Skip to content

fix(agent-core): handle incomplete tool_calls on session resume (#660)#664

Open
LifeJiggy wants to merge 2 commits into
MoonshotAI:mainfrom
LifeJiggy:fix/session-resume-incomplete-tool-calls
Open

fix(agent-core): handle incomplete tool_calls on session resume (#660)#664
LifeJiggy wants to merge 2 commits into
MoonshotAI:mainfrom
LifeJiggy:fix/session-resume-incomplete-tool-calls

Conversation

@LifeJiggy

@LifeJiggy LifeJiggy commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Related Issue
Resolve #660

Problem
When a session is killed mid-tool-call (OOM, force kill) and later resumed, the history contains an assistant message with tool_calls but no matching tool result messages. This caused:

  1. A 400 API error (assistant message with 'tool_calls' must be followed by tool messages)
  2. New user messages silently deferred because pendingToolResultIds was never cleaned up

What changed

  • project() now applies trimTrailingOpenToolExchange() to strip trailing assistant messages with unanswered tool_calls before sending to the LLM
  • Added cleanupOrphanedToolCalls() to ContextMemory that clears stale pendingToolResultIds after resume, so new user messages are not silently deferred
  • Fixed trimTrailingOpenToolExchange edge case where history with no assistant message returned [] instead of the full history

Checklist

  • I have read the CONTRIBUTING document.
  • I have linked a related issue, or explained the problem above.
  • I have added tests that prove my feature works.
  • Ran gen-changesets skill.
  • Ran gen-docs skill, or this PR needs no doc update.

@changeset-bot

changeset-bot Bot commented Jun 11, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: c066cba

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@moonshot-ai/agent-core Patch
@moonshot-ai/kimi-code Patch

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

@LifeJiggy LifeJiggy force-pushed the fix/session-resume-incomplete-tool-calls branch from f9a4217 to 1d681f1 Compare June 11, 2026 16:12
When a session is killed mid-tool-call and later resumed, the history
contains an assistant message with tool_calls but no matching tool
results. This caused a 400 API error and silently deferred all new
user messages. Fixes MoonshotAI#660.

Changes:
- project() now applies trimTrailingOpenToolExchange() to strip
  trailing assistant messages with unanswered tool_calls before
  sending to the LLM
- Added cleanupOrphanedToolCalls() to ContextMemory that clears
  stale pendingToolResultIds after resume, so new user messages
  are not silently deferred
- Fixed trimTrailingOpenToolExchange edge case where history with
  no assistant message returned [] instead of the full history

Tests:
- project() trims trailing assistant with unanswered tool_calls
- project() keeps assistant when all tool_calls are answered
- cleanupOrphanedToolCalls clears stale pendingToolResultIds
- Add missing type: 'function' to ToolCall objects in test
- Fix LoopToolCallEvent shape (use stepUuid instead of parentUuid, add uuid/turnId/step/args)
- Add changeset for agent-core and kimi-code patch bumps
@LifeJiggy LifeJiggy force-pushed the fix/session-resume-incomplete-tool-calls branch from 1d681f1 to c066cba Compare June 11, 2026 16:48
@LifeJiggy LifeJiggy changed the title fix(agent-core): improve Edit tool backslash handling and error diagn… fix/session-resume-incomplete-tool-calls (#660 P1) Jun 11, 2026
@LifeJiggy LifeJiggy changed the title fix/session-resume-incomplete-tool-calls (#660 P1) fix(agent-core): handle incomplete tool_calls on session resume (#660) Jun 12, 2026
@LifeJiggy LifeJiggy marked this pull request as ready for review June 12, 2026 08:21
@pkg-pr-new

pkg-pr-new Bot commented Jun 12, 2026

Copy link
Copy Markdown
pnpm dlx https://pkg.pr.new/@moonshot-ai/kimi-code@c066cba
npx https://pkg.pr.new/@moonshot-ai/kimi-code@c066cba

commit: c066cba

@LifeJiggy

Copy link
Copy Markdown
Contributor Author

@codex

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c066cba25e

ℹ️ 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".

Comment on lines +316 to +319
for (const id of this.pendingToolResultIds) {
if (!answeredIds.has(id)) {
this.pendingToolResultIds.delete(id);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Drop orphaned assistant messages before accepting prompts

When resuming a session killed after a tool.call, this cleanup clears pendingToolResultIds but leaves the assistant message with unanswered toolCalls in _history; the next user prompt is then appended after that assistant, so project() no longer treats the open tool exchange as trailing and sends [assistant tool_calls, user] to the provider, reproducing the 400 this change is meant to avoid. In the resume-after-interrupt path, clear or trim the orphaned assistant/tool exchange from history before allowing new messages through.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Impossible to resume crashed sessions

1 participant