fix(agent-core): trim orphan tool calls from projected context after resume#723
fix(agent-core): trim orphan tool calls from projected context after resume#723meymchen wants to merge 1 commit into
Conversation
🦋 Changeset detectedLatest commit: 5b78bcd The changes in this PR will be included in the next version bump. This PR includes changesets to release 2 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5b78bcda7e
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| return trimTrailingOpenToolExchange( | ||
| project(this.agent.microCompaction.compact(messages)), | ||
| ); |
There was a problem hiding this comment.
Clear pending tool state when compacting it away
When a full/manual compaction runs while the tail contains an unresolved or partially resolved tool exchange, this projection now removes that exchange from the compaction prompt, so applyCompaction can replace the whole prefix with a summary. However applyCompaction only clears openSteps and leaves pendingToolResultIds set; after this live compaction completes, any later appendUserMessage still sees an open tool exchange and goes into deferredMessages, so the next model request is built without the user's new prompt until a restart happens to run resume cleanup. Please clear the pending tool state when the open exchange is compacted away.
Useful? React with 👍 / 👎.
Related Issue
Resolve #705
Resolve #701
Resolve #660
Resolve #269
Related #520
Problem
When a session crashes or is killed while a tool call is still in flight, the wire records contain an assistant message with
tool_callsbut no matchingtoolresult. Afterkimi resume,ContextMemory.messagesprojected that malformed tail unchanged, so the next LLM request failed with:Manual compaction hit the same error because it also projected the open tool exchange into the compaction prompt.
What changed
ContextMemory.project()now appliestrimTrailingOpenToolExchange()after micro-compaction, so every consumer of the projected history (regular turns, compaction, debug/export views) receives a provider-safe message list.ContextMemory.cleanupOrphanedToolCalls()which truncates the trailing open exchange from_history, clearspendingToolResultIds/openSteps, and flushes any deferred messages once the exchange is closed.Agent.resume()callscleanupOrphanedToolCalls()immediately afterrecords.replay()and beforebackground.reconcile(), so background notifications and new user input are no longer deferred forever.context.cleanup_orphan_tool_callswire record type so replay remains self-consistent.trimTrailingOpenToolExchange()to leave histories that end in orphantoolmessages (no preceding assistant) unchanged instead of returning[].Checklist
gen-changesetsskill, or this PR needs no changeset.gen-docsskill, or this PR needs no doc update.