fix(chatd): enable compaction between steps and re-enter after summarization#22640
Merged
fix(chatd): enable compaction between steps and re-enter after summarization#22640
Conversation
…ization Three bugs with chat summarization are fixed: 1. Compaction never fired between steps because ReloadMessages was not wired up in the chatloop.Run() call in chatd.go. The inline compaction guard requires both Compaction and ReloadMessages to be non-nil, but ReloadMessages was only set in tests. 2. Compaction only occurred at the end of an agent turn because the post-run safety net was the only compaction path that worked in production (it doesn't check ReloadMessages). The inline path was dead code. 3. After post-run compaction, the agent stopped instead of continuing with its fresh summarized context. Run() returned nil unconditionally, and processChat set the status to waiting. Changes: - Wire up ReloadMessages in chatd.go to reload persisted messages from the database and re-apply system prompts after compaction. - Wrap the step loop in an outer compaction loop that re-enters when compaction fires on the model's final step (compactedOnFinalStep), giving the agent a chance to continue with summarized context. - Add maxCompactionRetries (3) to prevent infinite compaction loops. - Track stoppedByModel and compactedOnFinalStep to only re-enter when the agent hasn't already consumed the compacted context. - Add PostRunCompactionReEntersStepLoop test.
5f765db to
c4c20bf
Compare
ibetitsmike
approved these changes
Mar 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Three bugs with chat summarization (compaction) share a single root cause:
ReloadMessageswas never wired up in the productionchatloop.Run()call.Bug 1: Compaction never fires between steps
The inline compaction guard in
chatloop.gorequires bothCompactionandReloadMessagesto be non-nil:Since
ReloadMessageswas only set in tests, inline compaction was dead code in production. Long multi-step turns could blow through the context window.Bug 2: Compaction only occurs at end of turn
The post-run safety net doesn't check
ReloadMessages, so it was the only compaction path that fired:This meant compaction only happened once, after the entire agent turn finished.
Bug 3: Agent stops after summarization
After post-run compaction,
Run()unconditionally returnednil.processChatthen set the chat status towaiting(done). The agent never had a chance to continue with its fresh summarized context.Fix
Wire up
ReloadMessagesinchatd.go: reloads persisted messages from the database and re-applies system prompts (subagent instruction, workspace AGENTS.md).Wrap the step loop in an outer compaction loop: when compaction fires on the model's final step (
compactedOnFinalStep), reload messages andcontinuethe outer loop so the agent re-enters with summarized context.Track
compactedOnFinalStepto distinguish inline compaction on the last step (needs re-entry) from inline compaction mid-loop followed by more tool-call steps (agent already consumed the compacted context, no re-entry needed).Add
maxCompactionRetries = 3to prevent infinite compaction loops.Testing
PostRunCompactionReEntersStepLooptest: verifies that when a text-only response triggers compaction, the outer loop re-enters and the agent makes a second stream call with fresh context.