Repository navigation
v1.3.101
v1.3.101
Critical fixes
Harness loop now learns from previous failures
The harness auto-run loop was repeating identical errors across retry attempts. Each retry started a fresh subprocess with zero conversation history, so the agent had no way to know what went wrong in the previous attempt.
Fix: BuildRunPrompt now injects the previous attempt's error, verification status, and log file path into the prompt when task.Attempt > 1. The agent sees exactly what failed and is explicitly instructed not to repeat the same approach.
Context compaction: rolling single-pass design
Redesigned the compaction system from a complex multi-pass dual-threshold approach to a clean rolling design:
- Single-pass summarize: All pre-compaction messages are compressed into one summary in a single LLM call. No more multi-pass loops with adaptive retention budgets.
- Fixed post-compaction target: ~30K tokens (or 25% of context window for smaller models), instead of a proportional ratio.
- Summary output cap: 5% of context window, capped at 12K tokens absolute (prevents 50K summaries on 1M context models).
- Threshold lowered to 0.99: Compaction triggers at 99% of usable budget (was 100%), leaving a small margin for the last turn.
Precompact anti-collision
Background precompact (async compression) was racing with the agent's regular LLM turn, causing API rate-limit collisions and snapshot invalidation:
- 6-second stagger delay: The compression LLM call now fires 6 seconds after the agent's turn starts, avoiding simultaneous API requests.
- Snapshot guard:
ensurePromptSendableandtryReactiveCompactnow skip local compaction (Microcompact/TruncateOldest) while a background precompact is running, preventing fingerprint changes that would invalidate the snapshot. - Lossy apply:
ApplyCompactResultnow applies the compaction result even if messages changed within the snapshot range (lossy summary is always better than no compaction).
Session-scoped todos
todo_write now stores todos per-session at ~/.ggcode/todos/<sessionID>.json instead of per-workspace. This prevents todo bleed between concurrent sessions in the same workspace. The session ID is propagated from TUI/daemon/pipe to the agent.
Cancel no longer shows stuck "Cancelling..." state
Double Ctrl+C during an agent run was leaving the TUI in a stuck "Cancelling..." state with the spinner still running. The context.Canceled error path now performs full cleanup: stops spinner, finishes running tools, clears status, restores pending input.
Pending image queue fix
Images pasted with a submission while the agent was busy were lost when the submission was consumed from the pending queue. The pending queue now carries Images alongside text through enqueueWithImages → consumeDetailed.
Features
-
debug_logtool: New tool that lets the LLM query the in-memory debug log ring buffer (500 entries). Useful for diagnosing provider errors, agent loop behavior, or harness failures. Category filterable (e.g.agent,provider,harness). -
Debug log noise cleanup: Removed ~2500 lines of noise per session from debug logs:
estimateTokensForMessagespolling (1400 lines/session)- OpenAI tools JSON dump (60+ large lines)
- TUI CATCHALL cursor blink + keypress logging
- Agent permission decision trio (check + decision + execute)
- QQ heartbeat spam (3 lines × 42 cycles)
- Permission check full-input JSON dump
- Stream frame ticks, byte counts, encoder selection
- Emitter tool_result spam
-
First-token timeout: Reduced from 5 minutes to 120 seconds. If the provider hasn't sent a response header in 2 minutes, it's effectively down.
-
Slash command descriptions: Added missing descriptions for
/mode,/allow,/export,/bug,/config,/reflect,/rulesin both English and Chinese. -
Lanchat history compact format:
lanchattool result history now shows one line per message with a 50-char preview, instead of multi-line body dumps.
History rendering alignment (TUI + GUI)
Historical tool rendering in both TUI session reload and GUI GetSessionHistory now mirrors the real-time streaming path exactly:
todo_write→TodoToolItem(was genericToolItem)spawn_agent→ usesDisplayName(was empty, showing raw JSON)exit_plan_mode→ rendered as assistant text message- Skipped tools (
read_command_output,wait_command,stop_command,write_command_input,list_commands,enter_plan_mode,lsp_*) → omitted entirely tool_resultformatting:suppressToolResultnow resolvesrawArgsfrom the matchingtool_useblock for proper formatting
Files changed
45 files changed since v1.3.100.