Bug Description
When resuming a Kimi Code session where the last turn has open (unresponded) tool calls, the LLM provider fails with a 400 [provider.api_error] stating:
an assistant message with 'tool_calls' must be followed by tool messages responding to each 'tool_call_id'.
This happens because the new user prompt/steer is appended to the history after the open tool calls, preventing trimTrailingOpenToolExchange from cleaning them since they are no longer "trailing" at the very end of the history. Additionally, the new user prompt gets deferred if pendingToolResultIds is not cleared from the aborted turn.
Solution
We resolved this by:
- Clearing
pendingToolResultIds at the start and end of turn boundaries (TurnFlow.runOneTurn).
- Clearing
pendingToolResultIds after replaying session records during resume (Agent.resume).
- Reverting the
step.end cleanup to correctly preserve system reminder deferral during active tool execution.
The commit with the fix on the fork is:
thecannabisapp@0291e89
Bug Description
When resuming a Kimi Code session where the last turn has open (unresponded) tool calls, the LLM provider fails with a
400 [provider.api_error]stating:This happens because the new user prompt/steer is appended to the history after the open tool calls, preventing
trimTrailingOpenToolExchangefrom cleaning them since they are no longer "trailing" at the very end of the history. Additionally, the new user prompt gets deferred ifpendingToolResultIdsis not cleared from the aborted turn.Solution
We resolved this by:
pendingToolResultIdsat the start and end of turn boundaries (TurnFlow.runOneTurn).pendingToolResultIdsafter replaying session records during resume (Agent.resume).step.endcleanup to correctly preserve system reminder deferral during active tool execution.The commit with the fix on the fork is:
thecannabisapp@0291e89