What version of Kimi Code is running?
0.6.0
Which open platform/subscription were you using?
Kimi
Which model were you using?
kimi-for-coding
What platform is your computer?
Linux x64 (WSL2 Ubuntu-22.04), Node.js v24.15.0, WarpTerminal
What issue are you seeing?
在一次会话中,AI 正在等待一个后台 Agent 任务的结果(调用了 TaskOutput(block=true)),我在这个过程中强制中断了程序(直接关闭终端)。
重新进入同一会话后,无论发送什么消息(例如"继续"),都会持续报错:
400 an assistant message with 'tool_calls' must be followed by tool messages responding to each 'tool_call_id'.
The following tool_call_ids did not have response messages: TaskOutput:79
手动触发 Compaction 也会失败,切换 provider(kimi / deepseek)后错误相同:
APIStatusError: 400 an assistant message with 'tool_calls' must be followed by tool messages responding to each 'tool_call_id'. The following tool_call_ids did not have response messages: TaskOutput:79
What steps can reproduce the bug?
- 启动一个会话,让 AI 调用一个需要阻塞等待的工具(例如
TaskOutput(block=true) 或后台 Agent)
- 在工具执行过程中强制中断(如直接关闭终端窗口)
- 重新进入同一会话(自动恢复)
- 发送任意新消息,例如"继续"
- 观察到 LLM 请求返回 400,会话无法继续
Session ID: session_62a574ff-660e-4fa5-ac1a-a9d6efed9e21
What is the expected behavior?
用户强制中断是一个完全合理的操作,软件应该能优雅恢复:
- 恢复时检测到未完成的 tool exchange,自动补全缺失的
tool.result(标记为中断/错误)和 step.end
- 或者
project() 在构建 LLM 消息时过滤掉不完整的工具调用序列
- 恢复后能够正常继续对话
Additional information
我导出了该会话的 debug zip 并检查了其中的 wire log,发现以下关键证据:
1. wire.jsonl 中存在未配对的 tool.call
在 agents/main/wire.jsonl 中,turn 4 step 32 的记录如下:
- entry 472:
step.begin(uuid=8f932678-57bd-4cbc-845d-75a9944f1bb9)
- entry 473-474:
content.part(思考 + 文本)
- entry 475:
tool.call — TaskOutput,toolCallId=tool_iq3KtmRW2h0g5fZpAxmE76r2
- entry 476: 后台 Agent 丢失的通知消息(被 defer)
- entry 477-478: 用户输入"继续"(被 defer)
但是该 tool.call 之后没有任何 tool.result 记录,也没有对应的 step.end。
2. ContextMemory 恢复后处于脏状态
根据源码逻辑(packages/agent-core/src/agent/context/index.ts):
tool.call 会把 toolCallId 加入 pendingToolResultIds
tool.result 会将其移除
step.end 会关闭 openSteps
由于强制中断,tool.result 和 step.end 都未能写入 wire log。恢复重播后:
pendingToolResultIds 永远卡着该 id
openSteps 永远有一个未关闭的 step
hasOpenToolExchange() 永远返回 true
这导致两个连锁问题:
-
后续所有新消息被无限 defer:appendUserMessage() → appendMessage() 发现 hasOpenToolExchange() 为 true → 消息被塞进 deferredMessages,永远不进入 _history。所以发"继续"后 LLM 根本看不到这条消息。
-
project() 把不完整的 assistant 消息发给了 LLM API:packages/agent-core/src/agent/context/projector.ts 的过滤逻辑只排除了"空 assistant 消息",但没有检查 assistant 的 toolCalls 是否在后面都有对应的 tool 消息。于是带着 toolCalls 但缺少 tool 结果的非法消息序列直接发给了 API,触发 400。
What version of Kimi Code is running?
0.6.0
Which open platform/subscription were you using?
Kimi
Which model were you using?
kimi-for-coding
What platform is your computer?
Linux x64 (WSL2 Ubuntu-22.04), Node.js v24.15.0, WarpTerminal
What issue are you seeing?
在一次会话中,AI 正在等待一个后台 Agent 任务的结果(调用了
TaskOutput(block=true)),我在这个过程中强制中断了程序(直接关闭终端)。重新进入同一会话后,无论发送什么消息(例如"继续"),都会持续报错:
手动触发 Compaction 也会失败,切换 provider(kimi / deepseek)后错误相同:
What steps can reproduce the bug?
TaskOutput(block=true)或后台 Agent)Session ID:
session_62a574ff-660e-4fa5-ac1a-a9d6efed9e21What is the expected behavior?
用户强制中断是一个完全合理的操作,软件应该能优雅恢复:
tool.result(标记为中断/错误)和step.endproject()在构建 LLM 消息时过滤掉不完整的工具调用序列Additional information
我导出了该会话的 debug zip 并检查了其中的 wire log,发现以下关键证据:
1. wire.jsonl 中存在未配对的 tool.call
在
agents/main/wire.jsonl中,turn 4 step 32 的记录如下:step.begin(uuid=8f932678-57bd-4cbc-845d-75a9944f1bb9)content.part(思考 + 文本)tool.call—TaskOutput,toolCallId=tool_iq3KtmRW2h0g5fZpAxmE76r2但是该 tool.call 之后没有任何
tool.result记录,也没有对应的step.end。2. ContextMemory 恢复后处于脏状态
根据源码逻辑(
packages/agent-core/src/agent/context/index.ts):tool.call会把 toolCallId 加入pendingToolResultIdstool.result会将其移除step.end会关闭openSteps由于强制中断,
tool.result和step.end都未能写入 wire log。恢复重播后:pendingToolResultIds永远卡着该 idopenSteps永远有一个未关闭的 stephasOpenToolExchange()永远返回true这导致两个连锁问题:
后续所有新消息被无限 defer:
appendUserMessage()→appendMessage()发现hasOpenToolExchange()为 true → 消息被塞进deferredMessages,永远不进入_history。所以发"继续"后 LLM 根本看不到这条消息。project()把不完整的 assistant 消息发给了 LLM API:packages/agent-core/src/agent/context/projector.ts的过滤逻辑只排除了"空 assistant 消息",但没有检查 assistant 的toolCalls是否在后面都有对应的tool消息。于是带着toolCalls但缺少tool结果的非法消息序列直接发给了 API,触发 400。