fix(agent): pin the user's task and prior summaries across compaction#4048
Merged
Conversation
Compaction folded the first user turn — the task brief and the user's stated facts and constraints — into a model-written summary, and a later fold then re-summarized that summary, degrading it to nothing and dropping the user's facts from context permanently. A real-provider run reproduced it: a token stated up front vanished from every request after the second fold, and the agent could no longer recall it. planCompaction now pins a small first user turn and any prior summaries in the verbatim prefix, so a fold never summarizes the task away and never re-folds an earlier summary. A large first turn (pasted content) stays foldable, capped by an absolute token ceiling and a window fraction, so pinning never starves the context.
esengine
added a commit
that referenced
this pull request
Jun 11, 2026
…digest (#4052) Builds on the first-turn pin (#4048): the deterministic floor now covers a fact the user states at ANY point, not just the opening turn. Compaction keeps every small user turn verbatim and folds only the assistant/tool work, so a mid-session "always deploy to eu-west-3" survives regardless of how the summarizer behaves. On top of that floor, the digest now leads with a structured "Standing facts & constraints" section consolidating what the user stated into one tidy view — redundant with the verbatim turns by design, so a weak summarizer dropping a fact there loses nothing. Co-authored-by: reasonix <reasonix@deepseek.com>
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 join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
The bug
A fact the user states up front gets dropped from context after repeated compaction, and the agent then "forgets" it. Reproduced end-to-end against the real provider:
<compaction-summary>[assistant calls read_file] {"path":"data/f01.txt"}</compaction-summary>— the## Goalwas empty; the user's task and token were gone.Root cause:
planCompactionpinned only the system message (head = 1). The first user turn (the task brief + the user's stated facts/constraints) was always inside the summarized region, so its survival depended on a weak summarizer model re-extracting it correctly on every fold. One degenerate summary — which the model produces especially when re-summarizing an already-summarized region — drops the fact for good.The fix
pinnedPrefixLennow keeps in the verbatim prefix:So a fold never summarizes the task away, and a later fold never re-folds an earlier summary into nothing. A large first turn (pasted content) stays foldable — gated by an absolute token ceiling and a window fraction — so pinning never starves the context.
Verification
Same scenario, same small window, identical work:
Post-fold request structure after the fix:
[system] [user: task verbatim, token present] [compaction-summary] [recent tail].Tests: new
TestPinnedPrefixLen(pins system+task+summaries; large/tiny-window turns stay foldable; a summary is not mistaken for the task turn); existing compaction/prune tests updated to the pinned-prefix behavior.go test ./internal/agent/..., control, and boot pass.