Repository navigation
v1.5.2
SparkyBot v1.5.2 Release Notes
Bug Fixes
File Watcher Hang on Copied Files
Fixed a critical bug where the file watcher would hang indefinitely when processing copied .zevtc files on local folders. The stability check was using st_mtime which continues updating on Windows/NTFS after a file copy completes, causing an infinite loop. The fix uses size-only checking with 3 consecutive stable reads — faster and more reliable.
AI Commentary Meta-Text Leak
Fixed an issue where some AI providers would leak internal reasoning into the Discord output (e.g., "Character limit: 600 characters max, 2-4 sentences. Let me draft:"). The system prompt now explicitly instructs the AI to output only the commentary itself.
AI Squad/Enemy Confusion
Fixed an issue where the AI would misidentify top-performing squad members as enemies, especially in lost fights. The system prompt now explicitly states that all named players in the report are on the friendly squad, and enemies only appear as aggregated professions in the Enemy Breakdown section.
Self-Update False Positive
Fixed a bug where running an unreleased version (e.g., v1.5.2 dev) would incorrectly show "Update available" when GitHub has an older version. The version comparison was using string equality — now uses proper tuple-based comparison, and correctly shows "You are ahead of the latest release" when running a newer unreleased build.
Process Files Tab Path Matching
Fixed a bug where successful file checkmarks and auto-cleanup never worked because paths from the worker thread (Windows Path objects with backslashes) didn't match the stored strings (from QFileDialog or drag-drop URLs with forward slashes). Both sides are now normalized via resolve() before comparing.
About Tab Window Growth
Fixed a layout issue where the About tab would cause the settings window to grow unboundedly when resized. Wrapped the content in an inner fixed-size widget with outer stretches to absorb extra space, preventing the window from permanently expanding.
New Features
Configurable Network Polling Interval
New spinbox in Settings → Paths lets you set how often SparkyBot checks for new files when watching a network share (1-30 seconds, default 5). Faster intervals for local networks, slower for VPN connections. Does not affect local folder monitoring which uses instant OS events.
Show Strips Toggle
Added an independent "Show Strips" checkbox in the Display tab. Boon strip data was always being generated but had no toggle — now you can show or hide it independently.
Commander Name in AI Commentary
The squad commander's name is now passed to the AI analysis engine, enabling personalized commentary like "Bálls Of Steel had the tag and the numbers — the execution just wasn't there."
AI Token Limit
Default max_tokens increased from 350 to 1000 to prevent truncation, especially with models that use internal reasoning. The hard 600-character limit has been removed from the prompt — length is now controlled by the "2-4 sentences" instruction, which models follow more reliably than character counting. Truncation due to token limits is now logged as a warning.
Debug AI Prompt Flag
New --debug-ai-prompt command-line flag saves the full AI prompt (system prompt + fight data JSON) to a timestamped JSON file for debugging. Useful for inspecting exactly what data the AI receives. Run with python bootstrap.py --debug-ai-prompt and look for ai_prompt_*.json files in the current directory.
Manual File Processing Tab
New "Process Files" tab in the GUI lets you drag-and-drop or browse for .evtc/.zevtc files to process manually. Useful for reprocessing old fights, testing changes, or processing files from a different location. Supports multiple files at once with a queue, progress indicator, and per-file status. The browse dialog opens directly to the configured ArcDPS log folder. Successfully processed files are marked with "✓" and automatically cleared from the list when all files are done. Runs through the same pipeline as the automatic file watcher — GW2EI parse, fight report, Discord post, and AI analysis.
Dynamic Settings Window Width
The settings window now measures the actual rendered width of all tab labels and automatically sizes the window to fit them without scrolling. No more hardcoded pixel values to maintain — adding or renaming tabs requires no window size changes.
Auto-Update on Launch
SparkyBot now checks for updates automatically when it starts. If a newer version is available on GitHub, you will be prompted to update, skip, or suppress future prompts. Elite Insights updates are applied silently in the background without interrupting startup. A "Check for updates on launch" toggle in the Behavior tab controls this feature (enabled by default).
Display Tab Two-Column Layout
Display tab checkboxes are now arranged in a two-column grid, making better use of horizontal space and reducing scroll depth.
AI Context & Prompt Refactoring
The AI fight commentary pipeline has been significantly upgraded for more accurate and engaging analysis:
Data Pipeline (fight_report.py):
Added ally_dead and ally_damage metrics for better PUG performance context
Added individual stab_uptime and aegis_uptime tracking per player
Added outlier detection: players who beat the runner-up by 1.5x in support metrics (strips, cleanses, healing, stability, aegis, burst damage)
Outliers dictionary now includes contextual labels (unit or action) for clarity
Added top_cleanses, top_strips, top_healers, top_bursts, and top_cc arrays
Pruned enemy_breakdown and top_enemy_skills to top 5 entries only (saves tokens)
Filtered out unmapped ArcDPS skills (names starting with "Skill ")
Calculated is_outnumbered and squad_outdamaged_enemy as booleans in Python (prevents LLM hallucination)
Prompt Engineering (ai_analyst.py):
Removed hardcoded example outputs to enable dynamic, fresh commentary
Added "Narrative Focus" directive: AI chooses one of three angles (The Carry, The Enemy Failure, The Meatgrinder)
AI now prioritizes praising players in the outliers dictionary
Added strip terminology guidance: "strips" refers to boon removal, not a currency
Added even-fight threshold: fights within 15% of each other are treated as even, not disadvantaged
Removed flawed ally_damage comparison logic
Added guardrail: AI cannot claim enemy lacked certain professions (only sees top 5 threats)
Added retry loop with exponential backoff for HTTP 503 errors
Added SLANG SELECTION PROTOCOL with prioritized list of gaming terms (Skill Lag, Rallybot, Bags, Police the Rosters, Blob/Zerg) — strictly max 1 per response
Config Persistence (config.py):
Disabled configparser interpolation to prevent percent-sign issues in settings
Formatting Improvements
Wider Player Names
Player name column increased to 20 characters across all tables. Nearly all GW2 character names now display without truncation.
Boon Uptime Tables
Defensive boons: added spacing between columns for better readability
Offensive boons: full boon names (Might, Fury, Vigor, Swift, Alac, Quick) instead of 4-char abbreviations
Enemy Breakdown
Now sorted by count (most common profession first) instead of by damage
Full profession names (Dragonhunter, Chronomancer, etc.) instead of 4-char abbreviations
CC Table — Soft CC and Immob Now Working
Fixed the extraction of Soft CC (chill, cripple, slow, blind, daze, weakness) and Immobilize data. These columns previously always showed zero because the code was looking for the data in the wrong JSON fields. The fix properly reads condition application data from enemy target buffs arrays, matching MzFightReporter's approach. All four CC columns (Hard, Soft, Immob, Interrupts) now display real values.
Cleanup
Display Tab
Removed the dead "Show Spike Damage" checkbox which had no implementation. Burst Damage (which works) was already covering this functionality.
Full Changelog: v1.5.1...v1.5.2