mirror of
https://github.com/MoonshotAI/kimi-code.git
synced 2026-07-09 17:29:12 +00:00
feat(agent-core): sharpen the compaction handoff prompt (#1283)
* feat(agent-core): sharpen the compaction handoff prompt Refine the first-person handoff note the model writes at compaction so it preserves what actually gets dropped instead of what already survives: - Lead with the intent of the latest request, not a verbatim re-transcription (the recent user messages are already kept verbatim beside the summary); name which request governs when several are in play. - Carry forward tool results — the concrete values, key lines, schemas — not just the commands that produced them. - Keep settled decisions separate from still-open questions, and name the context the next turn must go and re-check. - Write in the conversation's language, keep the note proportional to the task, and don't re-transcribe the auto-attached TODO list. Also correct the system prompt's description of the post-compaction shape: the recent user messages come first, followed by a first-person summary (not a rigidly sectioned report), and a newer kept message supersedes the summary. Update the affected inline snapshots and the compaction request token count. * fix(agent-core): preserve an oversized latest request in the handoff note selectRecentUserMessages truncates a kept user message to the size cap, keeping only its prefix, so when the latest request itself exceeds the cap only its head survives verbatim beside the summary. Telling the summary "don't re-transcribe, it survives verbatim" then permanently dropped the tail — often the actual ask. Keep the intent-not-transcription guidance, but require preserving the at-risk parts of a long current request.
This commit is contained in:
parent
c434b4c3e6
commit
ea55911062
4 changed files with 64 additions and 32 deletions
5
.changeset/sharpen-compaction-handoff-prompt.md
Normal file
5
.changeset/sharpen-compaction-handoff-prompt.md
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
"@moonshot-ai/kimi-code": patch
|
||||
---
|
||||
|
||||
Sharpen the conversation-compaction handoff prompt so resumed sessions continue more reliably: the summary now leads with the intent of the latest request instead of re-transcribing it, carries forward tool results (not just the commands that produced them), separates settled decisions from still-open questions, names the context the next turn must re-check, matches the conversation's language, and stays proportional to the task. Also corrects the system prompt's description of the post-compaction shape.
|
||||
|
|
@ -7,31 +7,58 @@ conversation is cleared.
|
|||
Write the note as your own continuing train of thought — first person, present
|
||||
tense, the way you would reason through the next move. Do not write a
|
||||
third-party report about someone else's work, and do not impose rigid section
|
||||
headings; let the shape follow the task.
|
||||
headings; let the shape follow the task. Write the note in the same language the
|
||||
conversation has been using — do not switch to English just because these
|
||||
instructions happen to be in English.
|
||||
|
||||
Make the note self-sufficient: the next turn will see only your most recent user
|
||||
messages and this note — every assistant message, tool call, and tool result
|
||||
above will be gone. In your own words, preserve what you genuinely need to
|
||||
continue:
|
||||
|
||||
- The latest user request, quoted verbatim, and what it is actually asking for.
|
||||
- What the latest request is actually asking for: your reading of its intent and
|
||||
any ambiguity you have already resolved — not a re-transcription, since what
|
||||
fits is kept verbatim in your most recent messages. But those kept messages are
|
||||
size-capped, so a long request is truncated there: if the latest request is
|
||||
large (a big paste or file), preserve the parts at risk of being dropped —
|
||||
above all the actual ask. If several requests are in play, say which one governs
|
||||
the next move, and re-quote any still-relevant earlier request that may have
|
||||
scrolled out of the kept messages.
|
||||
- The instructions and constraints currently in force (user preferences,
|
||||
project rules, environment and tooling limits) — condensed to what still
|
||||
matters.
|
||||
matters, keeping decisions you have already settled (what you chose and why)
|
||||
separate from questions still open, so you neither silently reopen a closed
|
||||
choice nor treat an undecided point as decided.
|
||||
- What has actually been done, at high fidelity: keep the exact commands that
|
||||
were run, the exact file paths touched, and whether each succeeded or failed.
|
||||
Keep only the final working version of any code; drop intermediate attempts
|
||||
and already-resolved errors.
|
||||
were run, the exact file paths touched, and whether each succeeded or failed —
|
||||
and the results themselves, not just the commands: the concrete values
|
||||
returned, the key lines or error text, the schema or signature a lookup
|
||||
revealed, since re-running to recover them may be slow or impossible. Keep only
|
||||
the final working version of any code; drop intermediate attempts and
|
||||
already-resolved errors.
|
||||
- What you still don't know: context the next step depends on that this
|
||||
conversation never established — files or paths referenced but not yet read,
|
||||
schemas or APIs assumed but unseen, questions the user has not answered. Name
|
||||
these gaps so the next turn goes and checks them instead of assuming.
|
||||
- The precise next action — including the exact next command or tool call you
|
||||
intend to make — and any required format for the final answer.
|
||||
|
||||
Your TODO list is re-attached automatically below this note from its live
|
||||
source, so do not transcribe it — copying it wastes space and can contradict the
|
||||
live version. What that list cannot hold is the reasoning between tasks — why one
|
||||
was reordered or dropped, or a decision on one that constrains another — so
|
||||
record that instead.
|
||||
|
||||
Be honest about uncertainty. If an earlier step claimed something was done but
|
||||
was never verified (tests "passing", a fix "working", a file "created"), say so
|
||||
plainly and treat it as unverified rather than fact — re-check before relying
|
||||
on it.
|
||||
|
||||
Be concise. Include the critical data, identifiers, and references needed to
|
||||
continue, and omit anything that does not change the next move.
|
||||
Be concise, and keep the note proportional to the task: a long multi-step task
|
||||
warrants detail, but a trivial or nearly finished exchange needs only a sentence
|
||||
or two — do not pad it out. Include the critical data, identifiers, and
|
||||
references needed to continue, and omit anything that does not change the next
|
||||
move.
|
||||
|
||||
Respond with text only. Do not call any tools — you already have everything you
|
||||
need in the conversation history.
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ The user may ask you to research on certain topics, process or generate certain
|
|||
|
||||
When the conversation grows long, the system automatically condenses the older part of it. This happens on its own near the context limit — you do not trigger it, decide when it runs, or see any marker where it occurred. Your instructions, tool schemas, and working directory information are unaffected; only the earlier turns are rewritten.
|
||||
|
||||
After this happens, the start of your visible history is a single structured summary of the work so far (current focus, environment, completed steps, active issues, key file states, and any TODO list), followed verbatim by the most recent messages. Treat that summary as an accurate record of what already happened: do not redo work it reports as done, re-read files whose relevant contents it captured, or re-ask the user for information it contains.
|
||||
After this happens, your most recent user messages are kept verbatim, followed by a single first-person summary of the work so far — the current request, the constraints in force, what you did (exact commands, paths, and outcomes), what you still don't know, and your next move, usually closing with a "## TODO List". Treat that summary as an accurate record of what already happened: do not redo work it reports as done, re-read files whose relevant contents it captured, or re-ask the user for information it contains. Where one of the kept messages is newer than the summary, follow the newer message and treat the summary as the older context it updates.
|
||||
|
||||
The summary preserves conclusions, not live tool state. If you depended on something transient from before the summary — an open file's contents, a command's status, background work you started — re-establish it from the current project with your tools rather than trusting a value that may predate the summary.
|
||||
|
||||
|
|
|
|||
|
|
@ -76,10 +76,10 @@ describe('FullCompaction', () => {
|
|||
[wire] context.append_message { "message": { "role": "user", "content": [ { "type": "text", "text": "recent user three" } ], "toolCalls": [], "origin": { "kind": "user" } }, "time": "<time>" }
|
||||
[wire] full_compaction.begin { "source": "manual", "instruction": "Keep the important test facts.", "time": "<time>" }
|
||||
[emit] compaction.started { "trigger": "manual", "instruction": "Keep the important test facts." }
|
||||
[wire] usage.record { "model": "kimi-code", "usage": { "inputOther": 537, "output": 8, "inputCacheRead": 0, "inputCacheCreation": 0 }, "usageScope": "session", "time": "<time>" }
|
||||
[emit] agent.status.updated { "model": "kimi-code", "contextTokens": 120, "maxContextTokens": 256000, "contextUsage": 0.00046875, "planMode": false, "swarmMode": false, "permission": "manual", "usage": { "byModel": { "kimi-code": { "inputOther": 537, "output": 8, "inputCacheRead": 0, "inputCacheCreation": 0 } }, "total": { "inputOther": 537, "output": 8, "inputCacheRead": 0, "inputCacheCreation": 0 } } }
|
||||
[wire] usage.record { "model": "kimi-code", "usage": { "inputOther": 1018, "output": 8, "inputCacheRead": 0, "inputCacheCreation": 0 }, "usageScope": "session", "time": "<time>" }
|
||||
[emit] agent.status.updated { "model": "kimi-code", "contextTokens": 120, "maxContextTokens": 256000, "contextUsage": 0.00046875, "planMode": false, "swarmMode": false, "permission": "manual", "usage": { "byModel": { "kimi-code": { "inputOther": 1018, "output": 8, "inputCacheRead": 0, "inputCacheCreation": 0 } }, "total": { "inputOther": 1018, "output": 8, "inputCacheRead": 0, "inputCacheCreation": 0 } } }
|
||||
[wire] context.apply_compaction { "summary": "Compacted summary.", "contextSummary": "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.\\nCompacted summary.", "compactedCount": 6, "tokensBefore": 39, "tokensAfter": 100, "keptUserMessageCount": 3, "time": "<time>" }
|
||||
[emit] agent.status.updated { "model": "kimi-code", "contextTokens": 100, "maxContextTokens": 256000, "contextUsage": 0.000390625, "planMode": false, "swarmMode": false, "permission": "manual", "usage": { "byModel": { "kimi-code": { "inputOther": 537, "output": 8, "inputCacheRead": 0, "inputCacheCreation": 0 } }, "total": { "inputOther": 537, "output": 8, "inputCacheRead": 0, "inputCacheCreation": 0 } } }
|
||||
[emit] agent.status.updated { "model": "kimi-code", "contextTokens": 100, "maxContextTokens": 256000, "contextUsage": 0.000390625, "planMode": false, "swarmMode": false, "permission": "manual", "usage": { "byModel": { "kimi-code": { "inputOther": 1018, "output": 8, "inputCacheRead": 0, "inputCacheCreation": 0 } }, "total": { "inputOther": 1018, "output": 8, "inputCacheRead": 0, "inputCacheCreation": 0 } } }
|
||||
[wire] full_compaction.complete { "time": "<time>" }
|
||||
[emit] compaction.completed { "result": { "summary": "Compacted summary.", "compactedCount": 6, "tokensBefore": 39, "tokensAfter": 100, "keptUserMessageCount": 3 } }
|
||||
`);
|
||||
|
|
@ -93,7 +93,7 @@ describe('FullCompaction', () => {
|
|||
assistant: text "old assistant two"
|
||||
user: text "recent user three"
|
||||
assistant: text "recent assistant three"
|
||||
user: text "You are about to run out of context. Write a first-person handoff note to\\nyourself so you can seamlessly continue this task after the earlier\\nconversation is cleared.\\n\\n--- This message is a direct task, not part of the above conversation ---\\n\\nWrite the note as your own continuing train of thought — first person, present\\ntense, the way you would reason through the next move. Do not write a\\nthird-party report about someone else's work, and do not impose rigid section\\nheadings; let the shape follow the task.\\n\\nMake the note self-sufficient: the next turn will see only your most recent user\\nmessages and this note — every assistant message, tool call, and tool result\\nabove will be gone. In your own words, preserve what you genuinely need to\\ncontinue:\\n\\n- The latest user request, quoted verbatim, and what it is actually asking for.\\n- The instructions and constraints currently in force (user preferences,\\n project rules, environment and tooling limits) — condensed to what still\\n matters.\\n- What has actually been done, at high fidelity: keep the exact commands that\\n were run, the exact file paths touched, and whether each succeeded or failed.\\n Keep only the final working version of any code; drop intermediate attempts\\n and already-resolved errors.\\n- The precise next action — including the exact next command or tool call you\\n intend to make — and any required format for the final answer.\\n\\nBe honest about uncertainty. If an earlier step claimed something was done but\\nwas never verified (tests \\"passing\\", a fix \\"working\\", a file \\"created\\"), say so\\nplainly and treat it as unverified rather than fact — re-check before relying\\non it.\\n\\nBe concise. Include the critical data, identifiers, and references needed to\\ncontinue, and omit anything that does not change the next move.\\n\\nRespond with text only. Do not call any tools — you already have everything you\\nneed in the conversation history.\\n\\n\\nOptional user instruction:\\nKeep the important test facts."
|
||||
user: text "You are about to run out of context. Write a first-person handoff note to\\nyourself so you can seamlessly continue this task after the earlier\\nconversation is cleared.\\n\\n--- This message is a direct task, not part of the above conversation ---\\n\\nWrite the note as your own continuing train of thought — first person, present\\ntense, the way you would reason through the next move. Do not write a\\nthird-party report about someone else's work, and do not impose rigid section\\nheadings; let the shape follow the task. Write the note in the same language the\\nconversation has been using — do not switch to English just because these\\ninstructions happen to be in English.\\n\\nMake the note self-sufficient: the next turn will see only your most recent user\\nmessages and this note — every assistant message, tool call, and tool result\\nabove will be gone. In your own words, preserve what you genuinely need to\\ncontinue:\\n\\n- What the latest request is actually asking for: your reading of its intent and\\n any ambiguity you have already resolved — not a re-transcription, since what\\n fits is kept verbatim in your most recent messages. But those kept messages are\\n size-capped, so a long request is truncated there: if the latest request is\\n large (a big paste or file), preserve the parts at risk of being dropped —\\n above all the actual ask. If several requests are in play, say which one governs\\n the next move, and re-quote any still-relevant earlier request that may have\\n scrolled out of the kept messages.\\n- The instructions and constraints currently in force (user preferences,\\n project rules, environment and tooling limits) — condensed to what still\\n matters, keeping decisions you have already settled (what you chose and why)\\n separate from questions still open, so you neither silently reopen a closed\\n choice nor treat an undecided point as decided.\\n- What has actually been done, at high fidelity: keep the exact commands that\\n were run, the exact file paths touched, and whether each succeeded or failed —\\n and the results themselves, not just the commands: the concrete values\\n returned, the key lines or error text, the schema or signature a lookup\\n revealed, since re-running to recover them may be slow or impossible. Keep only\\n the final working version of any code; drop intermediate attempts and\\n already-resolved errors.\\n- What you still don't know: context the next step depends on that this\\n conversation never established — files or paths referenced but not yet read,\\n schemas or APIs assumed but unseen, questions the user has not answered. Name\\n these gaps so the next turn goes and checks them instead of assuming.\\n- The precise next action — including the exact next command or tool call you\\n intend to make — and any required format for the final answer.\\n\\nYour TODO list is re-attached automatically below this note from its live\\nsource, so do not transcribe it — copying it wastes space and can contradict the\\nlive version. What that list cannot hold is the reasoning between tasks — why one\\nwas reordered or dropped, or a decision on one that constrains another — so\\nrecord that instead.\\n\\nBe honest about uncertainty. If an earlier step claimed something was done but\\nwas never verified (tests \\"passing\\", a fix \\"working\\", a file \\"created\\"), say so\\nplainly and treat it as unverified rather than fact — re-check before relying\\non it.\\n\\nBe concise, and keep the note proportional to the task: a long multi-step task\\nwarrants detail, but a trivial or nearly finished exchange needs only a sentence\\nor two — do not pad it out. Include the critical data, identifiers, and\\nreferences needed to continue, and omit anything that does not change the next\\nmove.\\n\\nRespond with text only. Do not call any tools — you already have everything you\\nneed in the conversation history.\\n\\n\\nOptional user instruction:\\nKeep the important test facts."
|
||||
`);
|
||||
expect(ctx.compactHistory()).toMatchInlineSnapshot(`
|
||||
[
|
||||
|
|
@ -126,7 +126,7 @@ describe('FullCompaction', () => {
|
|||
compacted_count: 6,
|
||||
retry_count: 0,
|
||||
thinking_effort: 'off',
|
||||
input_tokens: 537,
|
||||
input_tokens: 1018,
|
||||
output_tokens: 8,
|
||||
}),
|
||||
});
|
||||
|
|
@ -977,7 +977,7 @@ describe('FullCompaction', () => {
|
|||
assistant: [] calls call_open_one:LookupOne { "query": "one" }, call_open_two:LookupTwo { "query": "two" }
|
||||
tool[call_open_one]: text "one result"
|
||||
tool[call_open_two]: text "Tool result is not available in the current context. Do not assume the tool completed successfully."
|
||||
user: text "You are about to run out of context. Write a first-person handoff note to\\nyourself so you can seamlessly continue this task after the earlier\\nconversation is cleared.\\n\\n--- This message is a direct task, not part of the above conversation ---\\n\\nWrite the note as your own continuing train of thought — first person, present\\ntense, the way you would reason through the next move. Do not write a\\nthird-party report about someone else's work, and do not impose rigid section\\nheadings; let the shape follow the task.\\n\\nMake the note self-sufficient: the next turn will see only your most recent user\\nmessages and this note — every assistant message, tool call, and tool result\\nabove will be gone. In your own words, preserve what you genuinely need to\\ncontinue:\\n\\n- The latest user request, quoted verbatim, and what it is actually asking for.\\n- The instructions and constraints currently in force (user preferences,\\n project rules, environment and tooling limits) — condensed to what still\\n matters.\\n- What has actually been done, at high fidelity: keep the exact commands that\\n were run, the exact file paths touched, and whether each succeeded or failed.\\n Keep only the final working version of any code; drop intermediate attempts\\n and already-resolved errors.\\n- The precise next action — including the exact next command or tool call you\\n intend to make — and any required format for the final answer.\\n\\nBe honest about uncertainty. If an earlier step claimed something was done but\\nwas never verified (tests \\"passing\\", a fix \\"working\\", a file \\"created\\"), say so\\nplainly and treat it as unverified rather than fact — re-check before relying\\non it.\\n\\nBe concise. Include the critical data, identifiers, and references needed to\\ncontinue, and omit anything that does not change the next move.\\n\\nRespond with text only. Do not call any tools — you already have everything you\\nneed in the conversation history.\\n\\n\\nOptional user instruction:\\nKeep stable facts."
|
||||
user: text "You are about to run out of context. Write a first-person handoff note to\\nyourself so you can seamlessly continue this task after the earlier\\nconversation is cleared.\\n\\n--- This message is a direct task, not part of the above conversation ---\\n\\nWrite the note as your own continuing train of thought — first person, present\\ntense, the way you would reason through the next move. Do not write a\\nthird-party report about someone else's work, and do not impose rigid section\\nheadings; let the shape follow the task. Write the note in the same language the\\nconversation has been using — do not switch to English just because these\\ninstructions happen to be in English.\\n\\nMake the note self-sufficient: the next turn will see only your most recent user\\nmessages and this note — every assistant message, tool call, and tool result\\nabove will be gone. In your own words, preserve what you genuinely need to\\ncontinue:\\n\\n- What the latest request is actually asking for: your reading of its intent and\\n any ambiguity you have already resolved — not a re-transcription, since what\\n fits is kept verbatim in your most recent messages. But those kept messages are\\n size-capped, so a long request is truncated there: if the latest request is\\n large (a big paste or file), preserve the parts at risk of being dropped —\\n above all the actual ask. If several requests are in play, say which one governs\\n the next move, and re-quote any still-relevant earlier request that may have\\n scrolled out of the kept messages.\\n- The instructions and constraints currently in force (user preferences,\\n project rules, environment and tooling limits) — condensed to what still\\n matters, keeping decisions you have already settled (what you chose and why)\\n separate from questions still open, so you neither silently reopen a closed\\n choice nor treat an undecided point as decided.\\n- What has actually been done, at high fidelity: keep the exact commands that\\n were run, the exact file paths touched, and whether each succeeded or failed —\\n and the results themselves, not just the commands: the concrete values\\n returned, the key lines or error text, the schema or signature a lookup\\n revealed, since re-running to recover them may be slow or impossible. Keep only\\n the final working version of any code; drop intermediate attempts and\\n already-resolved errors.\\n- What you still don't know: context the next step depends on that this\\n conversation never established — files or paths referenced but not yet read,\\n schemas or APIs assumed but unseen, questions the user has not answered. Name\\n these gaps so the next turn goes and checks them instead of assuming.\\n- The precise next action — including the exact next command or tool call you\\n intend to make — and any required format for the final answer.\\n\\nYour TODO list is re-attached automatically below this note from its live\\nsource, so do not transcribe it — copying it wastes space and can contradict the\\nlive version. What that list cannot hold is the reasoning between tasks — why one\\nwas reordered or dropped, or a decision on one that constrains another — so\\nrecord that instead.\\n\\nBe honest about uncertainty. If an earlier step claimed something was done but\\nwas never verified (tests \\"passing\\", a fix \\"working\\", a file \\"created\\"), say so\\nplainly and treat it as unverified rather than fact — re-check before relying\\non it.\\n\\nBe concise, and keep the note proportional to the task: a long multi-step task\\nwarrants detail, but a trivial or nearly finished exchange needs only a sentence\\nor two — do not pad it out. Include the critical data, identifiers, and\\nreferences needed to continue, and omit anything that does not change the next\\nmove.\\n\\nRespond with text only. Do not call any tools — you already have everything you\\nneed in the conversation history.\\n\\n\\nOptional user instruction:\\nKeep stable facts."
|
||||
`);
|
||||
// The unresolved tool call is sent to the model with a synthetic tool_result
|
||||
// closing it (so a strict provider accepts the summary request), while the
|
||||
|
|
@ -1028,10 +1028,10 @@ describe('FullCompaction', () => {
|
|||
[wire] full_compaction.begin { "source": "manual", "time": "<time>" }
|
||||
[emit] compaction.started { "trigger": "manual" }
|
||||
[wire] context.append_message { "message": { "role": "user", "content": [ { "type": "text", "text": "new user while compacting" } ], "toolCalls": [], "origin": { "kind": "user" } }, "time": "<time>" }
|
||||
[wire] usage.record { "model": "kimi-code", "usage": { "inputOther": 508, "output": 8, "inputCacheRead": 0, "inputCacheCreation": 0 }, "usageScope": "session", "time": "<time>" }
|
||||
[emit] agent.status.updated { "model": "kimi-code", "contextTokens": 80, "maxContextTokens": 256000, "contextUsage": 0.0003125, "planMode": false, "swarmMode": false, "permission": "manual", "usage": { "byModel": { "kimi-code": { "inputOther": 508, "output": 8, "inputCacheRead": 0, "inputCacheCreation": 0 } }, "total": { "inputOther": 508, "output": 8, "inputCacheRead": 0, "inputCacheCreation": 0 } } }
|
||||
[wire] usage.record { "model": "kimi-code", "usage": { "inputOther": 989, "output": 8, "inputCacheRead": 0, "inputCacheCreation": 0 }, "usageScope": "session", "time": "<time>" }
|
||||
[emit] agent.status.updated { "model": "kimi-code", "contextTokens": 80, "maxContextTokens": 256000, "contextUsage": 0.0003125, "planMode": false, "swarmMode": false, "permission": "manual", "usage": { "byModel": { "kimi-code": { "inputOther": 989, "output": 8, "inputCacheRead": 0, "inputCacheCreation": 0 } }, "total": { "inputOther": 989, "output": 8, "inputCacheRead": 0, "inputCacheCreation": 0 } } }
|
||||
[wire] context.apply_compaction { "summary": "Compacted prefix.", "contextSummary": "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.\\nCompacted prefix.", "compactedCount": 4, "tokensBefore": 25, "tokensAfter": 103, "keptUserMessageCount": 3, "time": "<time>" }
|
||||
[emit] agent.status.updated { "model": "kimi-code", "contextTokens": 103, "maxContextTokens": 256000, "contextUsage": 0.00040234375, "planMode": false, "swarmMode": false, "permission": "manual", "usage": { "byModel": { "kimi-code": { "inputOther": 508, "output": 8, "inputCacheRead": 0, "inputCacheCreation": 0 } }, "total": { "inputOther": 508, "output": 8, "inputCacheRead": 0, "inputCacheCreation": 0 } } }
|
||||
[emit] agent.status.updated { "model": "kimi-code", "contextTokens": 103, "maxContextTokens": 256000, "contextUsage": 0.00040234375, "planMode": false, "swarmMode": false, "permission": "manual", "usage": { "byModel": { "kimi-code": { "inputOther": 989, "output": 8, "inputCacheRead": 0, "inputCacheCreation": 0 } }, "total": { "inputOther": 989, "output": 8, "inputCacheRead": 0, "inputCacheCreation": 0 } } }
|
||||
[wire] full_compaction.complete { "time": "<time>" }
|
||||
[emit] compaction.completed { "result": { "summary": "Compacted prefix.", "compactedCount": 4, "tokensBefore": 25, "tokensAfter": 103, "keptUserMessageCount": 3 } }
|
||||
`);
|
||||
|
|
@ -1043,7 +1043,7 @@ describe('FullCompaction', () => {
|
|||
assistant: text "old assistant one"
|
||||
user: text "recent user two"
|
||||
assistant: text "recent assistant two"
|
||||
user: text "You are about to run out of context. Write a first-person handoff note to\\nyourself so you can seamlessly continue this task after the earlier\\nconversation is cleared.\\n\\n--- This message is a direct task, not part of the above conversation ---\\n\\nWrite the note as your own continuing train of thought — first person, present\\ntense, the way you would reason through the next move. Do not write a\\nthird-party report about someone else's work, and do not impose rigid section\\nheadings; let the shape follow the task.\\n\\nMake the note self-sufficient: the next turn will see only your most recent user\\nmessages and this note — every assistant message, tool call, and tool result\\nabove will be gone. In your own words, preserve what you genuinely need to\\ncontinue:\\n\\n- The latest user request, quoted verbatim, and what it is actually asking for.\\n- The instructions and constraints currently in force (user preferences,\\n project rules, environment and tooling limits) — condensed to what still\\n matters.\\n- What has actually been done, at high fidelity: keep the exact commands that\\n were run, the exact file paths touched, and whether each succeeded or failed.\\n Keep only the final working version of any code; drop intermediate attempts\\n and already-resolved errors.\\n- The precise next action — including the exact next command or tool call you\\n intend to make — and any required format for the final answer.\\n\\nBe honest about uncertainty. If an earlier step claimed something was done but\\nwas never verified (tests \\"passing\\", a fix \\"working\\", a file \\"created\\"), say so\\nplainly and treat it as unverified rather than fact — re-check before relying\\non it.\\n\\nBe concise. Include the critical data, identifiers, and references needed to\\ncontinue, and omit anything that does not change the next move.\\n\\nRespond with text only. Do not call any tools — you already have everything you\\nneed in the conversation history."
|
||||
user: text "You are about to run out of context. Write a first-person handoff note to\\nyourself so you can seamlessly continue this task after the earlier\\nconversation is cleared.\\n\\n--- This message is a direct task, not part of the above conversation ---\\n\\nWrite the note as your own continuing train of thought — first person, present\\ntense, the way you would reason through the next move. Do not write a\\nthird-party report about someone else's work, and do not impose rigid section\\nheadings; let the shape follow the task. Write the note in the same language the\\nconversation has been using — do not switch to English just because these\\ninstructions happen to be in English.\\n\\nMake the note self-sufficient: the next turn will see only your most recent user\\nmessages and this note — every assistant message, tool call, and tool result\\nabove will be gone. In your own words, preserve what you genuinely need to\\ncontinue:\\n\\n- What the latest request is actually asking for: your reading of its intent and\\n any ambiguity you have already resolved — not a re-transcription, since what\\n fits is kept verbatim in your most recent messages. But those kept messages are\\n size-capped, so a long request is truncated there: if the latest request is\\n large (a big paste or file), preserve the parts at risk of being dropped —\\n above all the actual ask. If several requests are in play, say which one governs\\n the next move, and re-quote any still-relevant earlier request that may have\\n scrolled out of the kept messages.\\n- The instructions and constraints currently in force (user preferences,\\n project rules, environment and tooling limits) — condensed to what still\\n matters, keeping decisions you have already settled (what you chose and why)\\n separate from questions still open, so you neither silently reopen a closed\\n choice nor treat an undecided point as decided.\\n- What has actually been done, at high fidelity: keep the exact commands that\\n were run, the exact file paths touched, and whether each succeeded or failed —\\n and the results themselves, not just the commands: the concrete values\\n returned, the key lines or error text, the schema or signature a lookup\\n revealed, since re-running to recover them may be slow or impossible. Keep only\\n the final working version of any code; drop intermediate attempts and\\n already-resolved errors.\\n- What you still don't know: context the next step depends on that this\\n conversation never established — files or paths referenced but not yet read,\\n schemas or APIs assumed but unseen, questions the user has not answered. Name\\n these gaps so the next turn goes and checks them instead of assuming.\\n- The precise next action — including the exact next command or tool call you\\n intend to make — and any required format for the final answer.\\n\\nYour TODO list is re-attached automatically below this note from its live\\nsource, so do not transcribe it — copying it wastes space and can contradict the\\nlive version. What that list cannot hold is the reasoning between tasks — why one\\nwas reordered or dropped, or a decision on one that constrains another — so\\nrecord that instead.\\n\\nBe honest about uncertainty. If an earlier step claimed something was done but\\nwas never verified (tests \\"passing\\", a fix \\"working\\", a file \\"created\\"), say so\\nplainly and treat it as unverified rather than fact — re-check before relying\\non it.\\n\\nBe concise, and keep the note proportional to the task: a long multi-step task\\nwarrants detail, but a trivial or nearly finished exchange needs only a sentence\\nor two — do not pad it out. Include the critical data, identifiers, and\\nreferences needed to continue, and omit anything that does not change the next\\nmove.\\n\\nRespond with text only. Do not call any tools — you already have everything you\\nneed in the conversation history."
|
||||
`);
|
||||
expect(ctx.compactHistory()).toMatchInlineSnapshot(`
|
||||
[
|
||||
|
|
@ -1092,8 +1092,8 @@ describe('FullCompaction', () => {
|
|||
[emit] compaction.started { "trigger": "manual" }
|
||||
[wire] context.clear { "time": "<time>" }
|
||||
[emit] agent.status.updated { "model": "kimi-code", "contextTokens": 0, "maxContextTokens": 256000, "contextUsage": 0, "planMode": false, "swarmMode": false, "permission": "manual" }
|
||||
[wire] usage.record { "model": "kimi-code", "usage": { "inputOther": 508, "output": 7, "inputCacheRead": 0, "inputCacheCreation": 0 }, "usageScope": "session", "time": "<time>" }
|
||||
[emit] agent.status.updated { "model": "kimi-code", "contextTokens": 0, "maxContextTokens": 256000, "contextUsage": 0, "planMode": false, "swarmMode": false, "permission": "manual", "usage": { "byModel": { "kimi-code": { "inputOther": 508, "output": 7, "inputCacheRead": 0, "inputCacheCreation": 0 } }, "total": { "inputOther": 508, "output": 7, "inputCacheRead": 0, "inputCacheCreation": 0 } } }
|
||||
[wire] usage.record { "model": "kimi-code", "usage": { "inputOther": 989, "output": 7, "inputCacheRead": 0, "inputCacheCreation": 0 }, "usageScope": "session", "time": "<time>" }
|
||||
[emit] agent.status.updated { "model": "kimi-code", "contextTokens": 0, "maxContextTokens": 256000, "contextUsage": 0, "planMode": false, "swarmMode": false, "permission": "manual", "usage": { "byModel": { "kimi-code": { "inputOther": 989, "output": 7, "inputCacheRead": 0, "inputCacheCreation": 0 } }, "total": { "inputOther": 989, "output": 7, "inputCacheRead": 0, "inputCacheCreation": 0 } } }
|
||||
[wire] full_compaction.cancel { "time": "<time>" }
|
||||
[emit] compaction.cancelled {}
|
||||
`);
|
||||
|
|
@ -1105,7 +1105,7 @@ describe('FullCompaction', () => {
|
|||
assistant: text "old assistant one"
|
||||
user: text "recent user two"
|
||||
assistant: text "recent assistant two"
|
||||
user: text "You are about to run out of context. Write a first-person handoff note to\\nyourself so you can seamlessly continue this task after the earlier\\nconversation is cleared.\\n\\n--- This message is a direct task, not part of the above conversation ---\\n\\nWrite the note as your own continuing train of thought — first person, present\\ntense, the way you would reason through the next move. Do not write a\\nthird-party report about someone else's work, and do not impose rigid section\\nheadings; let the shape follow the task.\\n\\nMake the note self-sufficient: the next turn will see only your most recent user\\nmessages and this note — every assistant message, tool call, and tool result\\nabove will be gone. In your own words, preserve what you genuinely need to\\ncontinue:\\n\\n- The latest user request, quoted verbatim, and what it is actually asking for.\\n- The instructions and constraints currently in force (user preferences,\\n project rules, environment and tooling limits) — condensed to what still\\n matters.\\n- What has actually been done, at high fidelity: keep the exact commands that\\n were run, the exact file paths touched, and whether each succeeded or failed.\\n Keep only the final working version of any code; drop intermediate attempts\\n and already-resolved errors.\\n- The precise next action — including the exact next command or tool call you\\n intend to make — and any required format for the final answer.\\n\\nBe honest about uncertainty. If an earlier step claimed something was done but\\nwas never verified (tests \\"passing\\", a fix \\"working\\", a file \\"created\\"), say so\\nplainly and treat it as unverified rather than fact — re-check before relying\\non it.\\n\\nBe concise. Include the critical data, identifiers, and references needed to\\ncontinue, and omit anything that does not change the next move.\\n\\nRespond with text only. Do not call any tools — you already have everything you\\nneed in the conversation history."
|
||||
user: text "You are about to run out of context. Write a first-person handoff note to\\nyourself so you can seamlessly continue this task after the earlier\\nconversation is cleared.\\n\\n--- This message is a direct task, not part of the above conversation ---\\n\\nWrite the note as your own continuing train of thought — first person, present\\ntense, the way you would reason through the next move. Do not write a\\nthird-party report about someone else's work, and do not impose rigid section\\nheadings; let the shape follow the task. Write the note in the same language the\\nconversation has been using — do not switch to English just because these\\ninstructions happen to be in English.\\n\\nMake the note self-sufficient: the next turn will see only your most recent user\\nmessages and this note — every assistant message, tool call, and tool result\\nabove will be gone. In your own words, preserve what you genuinely need to\\ncontinue:\\n\\n- What the latest request is actually asking for: your reading of its intent and\\n any ambiguity you have already resolved — not a re-transcription, since what\\n fits is kept verbatim in your most recent messages. But those kept messages are\\n size-capped, so a long request is truncated there: if the latest request is\\n large (a big paste or file), preserve the parts at risk of being dropped —\\n above all the actual ask. If several requests are in play, say which one governs\\n the next move, and re-quote any still-relevant earlier request that may have\\n scrolled out of the kept messages.\\n- The instructions and constraints currently in force (user preferences,\\n project rules, environment and tooling limits) — condensed to what still\\n matters, keeping decisions you have already settled (what you chose and why)\\n separate from questions still open, so you neither silently reopen a closed\\n choice nor treat an undecided point as decided.\\n- What has actually been done, at high fidelity: keep the exact commands that\\n were run, the exact file paths touched, and whether each succeeded or failed —\\n and the results themselves, not just the commands: the concrete values\\n returned, the key lines or error text, the schema or signature a lookup\\n revealed, since re-running to recover them may be slow or impossible. Keep only\\n the final working version of any code; drop intermediate attempts and\\n already-resolved errors.\\n- What you still don't know: context the next step depends on that this\\n conversation never established — files or paths referenced but not yet read,\\n schemas or APIs assumed but unseen, questions the user has not answered. Name\\n these gaps so the next turn goes and checks them instead of assuming.\\n- The precise next action — including the exact next command or tool call you\\n intend to make — and any required format for the final answer.\\n\\nYour TODO list is re-attached automatically below this note from its live\\nsource, so do not transcribe it — copying it wastes space and can contradict the\\nlive version. What that list cannot hold is the reasoning between tasks — why one\\nwas reordered or dropped, or a decision on one that constrains another — so\\nrecord that instead.\\n\\nBe honest about uncertainty. If an earlier step claimed something was done but\\nwas never verified (tests \\"passing\\", a fix \\"working\\", a file \\"created\\"), say so\\nplainly and treat it as unverified rather than fact — re-check before relying\\non it.\\n\\nBe concise, and keep the note proportional to the task: a long multi-step task\\nwarrants detail, but a trivial or nearly finished exchange needs only a sentence\\nor two — do not pad it out. Include the critical data, identifiers, and\\nreferences needed to continue, and omit anything that does not change the next\\nmove.\\n\\nRespond with text only. Do not call any tools — you already have everything you\\nneed in the conversation history."
|
||||
`);
|
||||
expect(ctx.compactHistory()).toMatchInlineSnapshot(`[]`);
|
||||
await ctx.expectResumeMatches();
|
||||
|
|
@ -1136,10 +1136,10 @@ describe('FullCompaction', () => {
|
|||
[wire] full_compaction.begin { "source": "auto", "time": "<time>" }
|
||||
[emit] compaction.started { "trigger": "auto" }
|
||||
[emit] compaction.blocked { "turnId": 0 }
|
||||
[wire] usage.record { "model": "kimi-code", "usage": { "inputOther": 529, "output": 9, "inputCacheRead": 0, "inputCacheCreation": 0 }, "usageScope": "session", "time": "<time>" }
|
||||
[emit] agent.status.updated { "model": "kimi-code", "contextTokens": 950000, "maxContextTokens": 256000, "contextUsage": 3.7109375, "planMode": false, "swarmMode": false, "permission": "manual", "usage": { "byModel": { "kimi-code": { "inputOther": 529, "output": 9, "inputCacheRead": 0, "inputCacheCreation": 0 } }, "total": { "inputOther": 529, "output": 9, "inputCacheRead": 0, "inputCacheCreation": 0 } } }
|
||||
[wire] usage.record { "model": "kimi-code", "usage": { "inputOther": 1010, "output": 9, "inputCacheRead": 0, "inputCacheCreation": 0 }, "usageScope": "session", "time": "<time>" }
|
||||
[emit] agent.status.updated { "model": "kimi-code", "contextTokens": 950000, "maxContextTokens": 256000, "contextUsage": 3.7109375, "planMode": false, "swarmMode": false, "permission": "manual", "usage": { "byModel": { "kimi-code": { "inputOther": 1010, "output": 9, "inputCacheRead": 0, "inputCacheCreation": 0 } }, "total": { "inputOther": 1010, "output": 9, "inputCacheRead": 0, "inputCacheCreation": 0 } } }
|
||||
[wire] context.apply_compaction { "summary": "Auto compacted summary.", "contextSummary": "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.\\nAuto compacted summary.", "compactedCount": 7, "tokensBefore": 46, "tokensAfter": 108, "keptUserMessageCount": 4, "time": "<time>" }
|
||||
[emit] agent.status.updated { "model": "kimi-code", "contextTokens": 108, "maxContextTokens": 256000, "contextUsage": 0.000421875, "planMode": false, "swarmMode": false, "permission": "manual", "usage": { "byModel": { "kimi-code": { "inputOther": 529, "output": 9, "inputCacheRead": 0, "inputCacheCreation": 0 } }, "total": { "inputOther": 529, "output": 9, "inputCacheRead": 0, "inputCacheCreation": 0 } } }
|
||||
[emit] agent.status.updated { "model": "kimi-code", "contextTokens": 108, "maxContextTokens": 256000, "contextUsage": 0.000421875, "planMode": false, "swarmMode": false, "permission": "manual", "usage": { "byModel": { "kimi-code": { "inputOther": 1010, "output": 9, "inputCacheRead": 0, "inputCacheCreation": 0 } }, "total": { "inputOther": 1010, "output": 9, "inputCacheRead": 0, "inputCacheCreation": 0 } } }
|
||||
[wire] full_compaction.complete { "time": "<time>" }
|
||||
[emit] compaction.completed { "result": { "summary": "Auto compacted summary.", "compactedCount": 7, "tokensBefore": 46, "tokensAfter": 108, "keptUserMessageCount": 4 } }
|
||||
[wire] context.append_loop_event { "event": { "type": "step.begin", "uuid": "<uuid-1>", "turnId": "0", "step": 1 }, "time": "<time>" }
|
||||
|
|
@ -1149,7 +1149,7 @@ describe('FullCompaction', () => {
|
|||
[wire] context.append_loop_event { "event": { "type": "step.end", "uuid": "<uuid-1>", "turnId": "0", "step": 1, "usage": { "inputOther": 107, "output": 11, "inputCacheRead": 0, "inputCacheCreation": 0 }, "finishReason": "end_turn" }, "time": "<time>" }
|
||||
[emit] turn.step.completed { "turnId": 0, "step": 1, "stepId": "<uuid-1>", "usage": { "inputOther": 107, "output": 11, "inputCacheRead": 0, "inputCacheCreation": 0 }, "finishReason": "end_turn" }
|
||||
[wire] usage.record { "model": "kimi-code", "usage": { "inputOther": 107, "output": 11, "inputCacheRead": 0, "inputCacheCreation": 0 }, "usageScope": "turn", "time": "<time>" }
|
||||
[emit] agent.status.updated { "model": "kimi-code", "contextTokens": 118, "maxContextTokens": 256000, "contextUsage": 0.0004609375, "planMode": false, "swarmMode": false, "permission": "manual", "usage": { "byModel": { "kimi-code": { "inputOther": 636, "output": 20, "inputCacheRead": 0, "inputCacheCreation": 0 } }, "total": { "inputOther": 636, "output": 20, "inputCacheRead": 0, "inputCacheCreation": 0 }, "currentTurn": { "inputOther": 107, "output": 11, "inputCacheRead": 0, "inputCacheCreation": 0 } } }
|
||||
[emit] agent.status.updated { "model": "kimi-code", "contextTokens": 118, "maxContextTokens": 256000, "contextUsage": 0.0004609375, "planMode": false, "swarmMode": false, "permission": "manual", "usage": { "byModel": { "kimi-code": { "inputOther": 1117, "output": 20, "inputCacheRead": 0, "inputCacheCreation": 0 } }, "total": { "inputOther": 1117, "output": 20, "inputCacheRead": 0, "inputCacheCreation": 0 }, "currentTurn": { "inputOther": 107, "output": 11, "inputCacheRead": 0, "inputCacheCreation": 0 } } }
|
||||
[emit] turn.ended { "turnId": 0, "reason": "completed" }
|
||||
`);
|
||||
expect(ctx.llmInputs()).toMatchInlineSnapshot(`
|
||||
|
|
@ -1164,7 +1164,7 @@ describe('FullCompaction', () => {
|
|||
user: text "recent user three"
|
||||
assistant: text "recent assistant three"
|
||||
user: text "Answer after compacting"
|
||||
user: text "You are about to run out of context. Write a first-person handoff note to\\nyourself so you can seamlessly continue this task after the earlier\\nconversation is cleared.\\n\\n--- This message is a direct task, not part of the above conversation ---\\n\\nWrite the note as your own continuing train of thought — first person, present\\ntense, the way you would reason through the next move. Do not write a\\nthird-party report about someone else's work, and do not impose rigid section\\nheadings; let the shape follow the task.\\n\\nMake the note self-sufficient: the next turn will see only your most recent user\\nmessages and this note — every assistant message, tool call, and tool result\\nabove will be gone. In your own words, preserve what you genuinely need to\\ncontinue:\\n\\n- The latest user request, quoted verbatim, and what it is actually asking for.\\n- The instructions and constraints currently in force (user preferences,\\n project rules, environment and tooling limits) — condensed to what still\\n matters.\\n- What has actually been done, at high fidelity: keep the exact commands that\\n were run, the exact file paths touched, and whether each succeeded or failed.\\n Keep only the final working version of any code; drop intermediate attempts\\n and already-resolved errors.\\n- The precise next action — including the exact next command or tool call you\\n intend to make — and any required format for the final answer.\\n\\nBe honest about uncertainty. If an earlier step claimed something was done but\\nwas never verified (tests \\"passing\\", a fix \\"working\\", a file \\"created\\"), say so\\nplainly and treat it as unverified rather than fact — re-check before relying\\non it.\\n\\nBe concise. Include the critical data, identifiers, and references needed to\\ncontinue, and omit anything that does not change the next move.\\n\\nRespond with text only. Do not call any tools — you already have everything you\\nneed in the conversation history."
|
||||
user: text "You are about to run out of context. Write a first-person handoff note to\\nyourself so you can seamlessly continue this task after the earlier\\nconversation is cleared.\\n\\n--- This message is a direct task, not part of the above conversation ---\\n\\nWrite the note as your own continuing train of thought — first person, present\\ntense, the way you would reason through the next move. Do not write a\\nthird-party report about someone else's work, and do not impose rigid section\\nheadings; let the shape follow the task. Write the note in the same language the\\nconversation has been using — do not switch to English just because these\\ninstructions happen to be in English.\\n\\nMake the note self-sufficient: the next turn will see only your most recent user\\nmessages and this note — every assistant message, tool call, and tool result\\nabove will be gone. In your own words, preserve what you genuinely need to\\ncontinue:\\n\\n- What the latest request is actually asking for: your reading of its intent and\\n any ambiguity you have already resolved — not a re-transcription, since what\\n fits is kept verbatim in your most recent messages. But those kept messages are\\n size-capped, so a long request is truncated there: if the latest request is\\n large (a big paste or file), preserve the parts at risk of being dropped —\\n above all the actual ask. If several requests are in play, say which one governs\\n the next move, and re-quote any still-relevant earlier request that may have\\n scrolled out of the kept messages.\\n- The instructions and constraints currently in force (user preferences,\\n project rules, environment and tooling limits) — condensed to what still\\n matters, keeping decisions you have already settled (what you chose and why)\\n separate from questions still open, so you neither silently reopen a closed\\n choice nor treat an undecided point as decided.\\n- What has actually been done, at high fidelity: keep the exact commands that\\n were run, the exact file paths touched, and whether each succeeded or failed —\\n and the results themselves, not just the commands: the concrete values\\n returned, the key lines or error text, the schema or signature a lookup\\n revealed, since re-running to recover them may be slow or impossible. Keep only\\n the final working version of any code; drop intermediate attempts and\\n already-resolved errors.\\n- What you still don't know: context the next step depends on that this\\n conversation never established — files or paths referenced but not yet read,\\n schemas or APIs assumed but unseen, questions the user has not answered. Name\\n these gaps so the next turn goes and checks them instead of assuming.\\n- The precise next action — including the exact next command or tool call you\\n intend to make — and any required format for the final answer.\\n\\nYour TODO list is re-attached automatically below this note from its live\\nsource, so do not transcribe it — copying it wastes space and can contradict the\\nlive version. What that list cannot hold is the reasoning between tasks — why one\\nwas reordered or dropped, or a decision on one that constrains another — so\\nrecord that instead.\\n\\nBe honest about uncertainty. If an earlier step claimed something was done but\\nwas never verified (tests \\"passing\\", a fix \\"working\\", a file \\"created\\"), say so\\nplainly and treat it as unverified rather than fact — re-check before relying\\non it.\\n\\nBe concise, and keep the note proportional to the task: a long multi-step task\\nwarrants detail, but a trivial or nearly finished exchange needs only a sentence\\nor two — do not pad it out. Include the critical data, identifiers, and\\nreferences needed to continue, and omit anything that does not change the next\\nmove.\\n\\nRespond with text only. Do not call any tools — you already have everything you\\nneed in the conversation history."
|
||||
|
||||
call 2:
|
||||
messages:
|
||||
|
|
@ -2173,10 +2173,10 @@ describe('FullCompaction', () => {
|
|||
[wire] full_compaction.begin { "source": "auto", "time": "<time>" }
|
||||
[emit] compaction.started { "trigger": "auto" }
|
||||
[emit] compaction.blocked { "turnId": 0 }
|
||||
[wire] usage.record { "model": "mock-model", "usage": { "inputOther": 491, "output": 9, "inputCacheRead": 0, "inputCacheCreation": 0 }, "usageScope": "session", "time": "<time>" }
|
||||
[emit] agent.status.updated { "model": "mock-model", "contextTokens": 0, "maxContextTokens": 1000000, "contextUsage": 0, "planMode": false, "swarmMode": false, "permission": "manual", "usage": { "byModel": { "mock-model": { "inputOther": 491, "output": 9, "inputCacheRead": 0, "inputCacheCreation": 0 } }, "total": { "inputOther": 491, "output": 9, "inputCacheRead": 0, "inputCacheCreation": 0 } } }
|
||||
[wire] usage.record { "model": "mock-model", "usage": { "inputOther": 972, "output": 9, "inputCacheRead": 0, "inputCacheCreation": 0 }, "usageScope": "session", "time": "<time>" }
|
||||
[emit] agent.status.updated { "model": "mock-model", "contextTokens": 0, "maxContextTokens": 1000000, "contextUsage": 0, "planMode": false, "swarmMode": false, "permission": "manual", "usage": { "byModel": { "mock-model": { "inputOther": 972, "output": 9, "inputCacheRead": 0, "inputCacheCreation": 0 } }, "total": { "inputOther": 972, "output": 9, "inputCacheRead": 0, "inputCacheCreation": 0 } } }
|
||||
[wire] context.apply_compaction { "summary": "First compacted summary.", "contextSummary": "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.\\nFirst compacted summary.", "compactedCount": 1, "tokensBefore": 8, "tokensAfter": 96, "keptUserMessageCount": 1, "time": "<time>" }
|
||||
[emit] agent.status.updated { "model": "mock-model", "contextTokens": 96, "maxContextTokens": 1000000, "contextUsage": 0.000096, "planMode": false, "swarmMode": false, "permission": "manual", "usage": { "byModel": { "mock-model": { "inputOther": 491, "output": 9, "inputCacheRead": 0, "inputCacheCreation": 0 } }, "total": { "inputOther": 491, "output": 9, "inputCacheRead": 0, "inputCacheCreation": 0 } } }
|
||||
[emit] agent.status.updated { "model": "mock-model", "contextTokens": 96, "maxContextTokens": 1000000, "contextUsage": 0.000096, "planMode": false, "swarmMode": false, "permission": "manual", "usage": { "byModel": { "mock-model": { "inputOther": 972, "output": 9, "inputCacheRead": 0, "inputCacheCreation": 0 } }, "total": { "inputOther": 972, "output": 9, "inputCacheRead": 0, "inputCacheCreation": 0 } } }
|
||||
[wire] full_compaction.complete { "time": "<time>" }
|
||||
[emit] compaction.completed { "result": { "summary": "First compacted summary.", "compactedCount": 1, "tokensBefore": 8, "tokensAfter": 96, "keptUserMessageCount": 1 } }
|
||||
[wire] context.append_loop_event { "event": { "type": "step.begin", "uuid": "<uuid-1>", "turnId": "0", "step": 1 }, "time": "<time>" }
|
||||
|
|
@ -2191,7 +2191,7 @@ describe('FullCompaction', () => {
|
|||
[wire] context.append_loop_event { "event": { "type": "step.end", "uuid": "<uuid-1>", "turnId": "0", "step": 1, "usage": { "inputOther": 97, "output": 11, "inputCacheRead": 0, "inputCacheCreation": 0 }, "finishReason": "tool_use" }, "time": "<time>" }
|
||||
[emit] turn.step.completed { "turnId": 0, "step": 1, "stepId": "<uuid-1>", "usage": { "inputOther": 97, "output": 11, "inputCacheRead": 0, "inputCacheCreation": 0 }, "finishReason": "tool_use" }
|
||||
[wire] usage.record { "model": "mock-model", "usage": { "inputOther": 97, "output": 11, "inputCacheRead": 0, "inputCacheCreation": 0 }, "usageScope": "turn", "time": "<time>" }
|
||||
[emit] agent.status.updated { "model": "mock-model", "contextTokens": 108, "maxContextTokens": 1000000, "contextUsage": 0.000108, "planMode": false, "swarmMode": false, "permission": "manual", "usage": { "byModel": { "mock-model": { "inputOther": 588, "output": 20, "inputCacheRead": 0, "inputCacheCreation": 0 } }, "total": { "inputOther": 588, "output": 20, "inputCacheRead": 0, "inputCacheCreation": 0 }, "currentTurn": { "inputOther": 97, "output": 11, "inputCacheRead": 0, "inputCacheCreation": 0 } } }
|
||||
[emit] agent.status.updated { "model": "mock-model", "contextTokens": 108, "maxContextTokens": 1000000, "contextUsage": 0.000108, "planMode": false, "swarmMode": false, "permission": "manual", "usage": { "byModel": { "mock-model": { "inputOther": 1069, "output": 20, "inputCacheRead": 0, "inputCacheCreation": 0 } }, "total": { "inputOther": 1069, "output": 20, "inputCacheRead": 0, "inputCacheCreation": 0 }, "currentTurn": { "inputOther": 97, "output": 11, "inputCacheRead": 0, "inputCacheCreation": 0 } } }
|
||||
[emit] turn.step.interrupted { "turnId": 0, "step": 2, "reason": "error", "message": "Compaction limit exceeded (1)" }
|
||||
[emit] turn.ended { "turnId": 0, "reason": "failed", "error": { "code": "context.overflow", "message": "Compaction limit exceeded (1)", "name": "KimiError", "details": { "maxCompactions": 1, "turnId": 0 }, "retryable": true } }
|
||||
`);
|
||||
|
|
@ -2204,7 +2204,7 @@ describe('FullCompaction', () => {
|
|||
tools: []
|
||||
messages:
|
||||
user: text "Trigger repeated compaction"
|
||||
user: text "You are about to run out of context. Write a first-person handoff note to\\nyourself so you can seamlessly continue this task after the earlier\\nconversation is cleared.\\n\\n--- This message is a direct task, not part of the above conversation ---\\n\\nWrite the note as your own continuing train of thought — first person, present\\ntense, the way you would reason through the next move. Do not write a\\nthird-party report about someone else's work, and do not impose rigid section\\nheadings; let the shape follow the task.\\n\\nMake the note self-sufficient: the next turn will see only your most recent user\\nmessages and this note — every assistant message, tool call, and tool result\\nabove will be gone. In your own words, preserve what you genuinely need to\\ncontinue:\\n\\n- The latest user request, quoted verbatim, and what it is actually asking for.\\n- The instructions and constraints currently in force (user preferences,\\n project rules, environment and tooling limits) — condensed to what still\\n matters.\\n- What has actually been done, at high fidelity: keep the exact commands that\\n were run, the exact file paths touched, and whether each succeeded or failed.\\n Keep only the final working version of any code; drop intermediate attempts\\n and already-resolved errors.\\n- The precise next action — including the exact next command or tool call you\\n intend to make — and any required format for the final answer.\\n\\nBe honest about uncertainty. If an earlier step claimed something was done but\\nwas never verified (tests \\"passing\\", a fix \\"working\\", a file \\"created\\"), say so\\nplainly and treat it as unverified rather than fact — re-check before relying\\non it.\\n\\nBe concise. Include the critical data, identifiers, and references needed to\\ncontinue, and omit anything that does not change the next move.\\n\\nRespond with text only. Do not call any tools — you already have everything you\\nneed in the conversation history."
|
||||
user: text "You are about to run out of context. Write a first-person handoff note to\\nyourself so you can seamlessly continue this task after the earlier\\nconversation is cleared.\\n\\n--- This message is a direct task, not part of the above conversation ---\\n\\nWrite the note as your own continuing train of thought — first person, present\\ntense, the way you would reason through the next move. Do not write a\\nthird-party report about someone else's work, and do not impose rigid section\\nheadings; let the shape follow the task. Write the note in the same language the\\nconversation has been using — do not switch to English just because these\\ninstructions happen to be in English.\\n\\nMake the note self-sufficient: the next turn will see only your most recent user\\nmessages and this note — every assistant message, tool call, and tool result\\nabove will be gone. In your own words, preserve what you genuinely need to\\ncontinue:\\n\\n- What the latest request is actually asking for: your reading of its intent and\\n any ambiguity you have already resolved — not a re-transcription, since what\\n fits is kept verbatim in your most recent messages. But those kept messages are\\n size-capped, so a long request is truncated there: if the latest request is\\n large (a big paste or file), preserve the parts at risk of being dropped —\\n above all the actual ask. If several requests are in play, say which one governs\\n the next move, and re-quote any still-relevant earlier request that may have\\n scrolled out of the kept messages.\\n- The instructions and constraints currently in force (user preferences,\\n project rules, environment and tooling limits) — condensed to what still\\n matters, keeping decisions you have already settled (what you chose and why)\\n separate from questions still open, so you neither silently reopen a closed\\n choice nor treat an undecided point as decided.\\n- What has actually been done, at high fidelity: keep the exact commands that\\n were run, the exact file paths touched, and whether each succeeded or failed —\\n and the results themselves, not just the commands: the concrete values\\n returned, the key lines or error text, the schema or signature a lookup\\n revealed, since re-running to recover them may be slow or impossible. Keep only\\n the final working version of any code; drop intermediate attempts and\\n already-resolved errors.\\n- What you still don't know: context the next step depends on that this\\n conversation never established — files or paths referenced but not yet read,\\n schemas or APIs assumed but unseen, questions the user has not answered. Name\\n these gaps so the next turn goes and checks them instead of assuming.\\n- The precise next action — including the exact next command or tool call you\\n intend to make — and any required format for the final answer.\\n\\nYour TODO list is re-attached automatically below this note from its live\\nsource, so do not transcribe it — copying it wastes space and can contradict the\\nlive version. What that list cannot hold is the reasoning between tasks — why one\\nwas reordered or dropped, or a decision on one that constrains another — so\\nrecord that instead.\\n\\nBe honest about uncertainty. If an earlier step claimed something was done but\\nwas never verified (tests \\"passing\\", a fix \\"working\\", a file \\"created\\"), say so\\nplainly and treat it as unverified rather than fact — re-check before relying\\non it.\\n\\nBe concise, and keep the note proportional to the task: a long multi-step task\\nwarrants detail, but a trivial or nearly finished exchange needs only a sentence\\nor two — do not pad it out. Include the critical data, identifiers, and\\nreferences needed to continue, and omit anything that does not change the next\\nmove.\\n\\nRespond with text only. Do not call any tools — you already have everything you\\nneed in the conversation history."
|
||||
|
||||
call 2:
|
||||
messages:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue