-
Notifications
You must be signed in to change notification settings - Fork 1.2k
feat(agent-core-v2): anchor compaction resumption on the latest user message #3537
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
9bb7136
915d462
2e35106
8d4968c
07c4d35
7fa0088
9cf8c75
2f05ff8
badcb1c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| "@moonshot-ai/kimi-code": patch | ||
| --- | ||
|
|
||
| Fix the agent resuming the wrong request after automatic context compaction in long sessions. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1 @@ | ||
| The conversation so far has been compacted to free up context. What follows is your own working summary of this task — use it to continue your train of thought rather than starting over. Treat it as notes, not proof: where it says a step was done, tests passed, or a fix worked, verify that yourself before relying on it. Any user messages earlier in this context are preserved verbatim from the compacted conversation; where a system-reminder note among them marks an omitted middle section, the user messages it replaced are covered by this summary. | ||
| The conversation so far has been compacted to free up context. What follows is your own working summary of this task — use it to continue your train of thought rather than starting over. Treat it as notes, not proof: where it says a step was done, tests passed, or a fix worked, verify that yourself before relying on it. Any user messages earlier in this context are preserved verbatim from the compacted conversation; where a system-reminder note among them marks an omitted middle section, the user messages it replaced are covered by this summary. The summary records which earlier requests were already addressed. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,6 +8,7 @@ export const COMPACTION_SUMMARY_PREFIX = summaryPrefixTemplate.trimEnd(); | |
| export const COMPACT_USER_MESSAGE_MAX_TOKENS = 20_000; | ||
| export const COMPACT_USER_MESSAGE_HEAD_TOKENS = 2_000; | ||
| export const COMPACTION_ELISION_VARIANT = 'compaction_elision'; | ||
| export const COMPACTION_CONTINUATION_VARIANT = 'compaction_continuation'; | ||
|
|
||
| type MessageLike = ContextMessage; | ||
|
|
||
|
|
@@ -94,11 +95,12 @@ export function buildContextCompactionShape( | |
| ? [...selection.head, ...selection.tail] | ||
| : [...selection.head, elisionMessage, ...selection.tail]; | ||
| const contextSummary = input.contextSummary ?? input.summary; | ||
| const continuationMessage = createCompactionContinuationMessage(); | ||
| const tokensAfter = | ||
| input.tokensAfter ?? | ||
| (input.requestOverheadTokens ?? 0) + | ||
| (input.summaryOutputTokens ?? estimate.text(contextSummary)) + | ||
| estimate.messages(keptMessages); | ||
| estimate.messages([...keptMessages, continuationMessage]); | ||
| const keptUserMessageCount = | ||
| input.keptUserMessageCount ?? selection.head.length + selection.tail.length; | ||
| const keptHeadUserMessageCount = | ||
|
|
@@ -113,7 +115,11 @@ export function buildContextCompactionShape( | |
| keptUserMessageCount, | ||
| keptHeadUserMessageCount, | ||
| droppedCount: input.droppedCount, | ||
| messages: [...keptMessages, createCompactionSummaryMessage(contextSummary)], | ||
| messages: [ | ||
| ...keptMessages, | ||
| createCompactionSummaryMessage(contextSummary), | ||
| continuationMessage, | ||
| ], | ||
| }; | ||
| } | ||
|
|
||
|
|
@@ -146,6 +152,21 @@ export function buildCompactionElisionText(omittedTokens: number): string { | |
| ); | ||
| } | ||
|
|
||
| export function createCompactionContinuationMessage(): ContextMessage { | ||
| return { | ||
| role: 'user', | ||
| content: [{ type: 'text', text: buildCompactionContinuationText() }], | ||
| toolCalls: [], | ||
| origin: { kind: 'injection', variant: COMPACTION_CONTINUATION_VARIANT }, | ||
| }; | ||
| } | ||
|
|
||
| export function buildCompactionContinuationText(): string { | ||
| return wrapSystemReminder( | ||
| 'Context compaction is complete — continue the work that was in progress when it began.', | ||
| ); | ||
|
Comment on lines
+164
to
+167
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
When automatic compaction runs during a Useful? React with 👍 / 👎.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed in 8d4968c — the continuation no longer unconditionally selects the latest user message; it now says to continue the work that was in progress when compaction began, which covers non-user turns (cron/system_trigger/task) whose prompts are dropped from the rebuilt context. |
||
| } | ||
|
|
||
| export function collectCompactableUserMessages<T extends MessageLike>(messages: readonly T[]): T[] { | ||
| return messages.filter( | ||
| (message) => isRealUserInput(message) && !isCompactionSummaryMessage(message), | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When a user steers the session after compaction starts,
historySafeToCompactaccepts the appended user message andbuildContextCompactionShaperetains it, but the summarizer never saw that message; thekeeps messages appended while compacting an unchanged prefixtest confirms it is then placed before this newer reminder. Consequently, the final model-visible instruction says to continue the older work that existed when compaction began, potentially overriding or obscuring the user's newly appended request. Place post-start user messages after the handoff or make the reminder explicitly prioritize them.Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Confirmed against the existing
keeps messages appended while compacting an unchanged prefixtest — the race is real and the anchor does sharpen the pre-existing positioning gap into a misdirection here. Accepting as a known limitation for this PR (window is narrow and the fresh message survives verbatim); tracked in #3604 with both fix directions (positional anchor text vs. repositioning post-begin appends past the handoff).