MoonshotAI / MoonshotAI/kimi-code

ACP/print 流式响应静默挂死:无空闲超时、被顶替轮 partial 不落 wire(0.31.1 只覆盖 Esc 场景)

Open
#2,762 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
TypeScript
Stars
7.5k
Forks
1.2k
Avg merge
11h 53m
Merged PRs (30d)
350

Description

现象

kimi CLI 0.34.0(ACP 模式,kimi acp)与 api.kimi.com 的流式对话中,偶发内容全部流式发完后连接挂死

  • 内容 delta 已全部到达(客户端能看到完整答复);
  • 但终端帧([DONE]/finish 帧)始终不来,无错误、无超时;
  • CLI 无流式空闲超时配置项(官方 config.toml 文档确认),session/prompt 无限等待;
  • 此时用户发送下一条消息,挂死轮被静默顶替;已流式的答复从未写入 wire.jsonl
    (无 content.part、无 usage.record、无 step.end);
  • 结果:下一轮的模型上下文里完全没有自己上一轮发过的答复——表现为"失忆",
    会把旧结论重发一遍、把已给的选项当作没列过。

证据(生产实机,2026-08-09)

  • kimi-code.log:最终总结的 LLM 请求发出后 12 分 21 秒零日志
    直到用户下一条消息到达才恢复(挂死轮被顶替);
  • 同会话两次命中:turn 1 挂死 12m21s,turn 0 末尾同形态(93 秒被顶替);
  • wire.jsonl 尾部:挂死轮只有 llm.request,无任何 response/part/usage/step.end 记录。

已知边界

  • 0.31.1「Esc 主动中断保留 partial 输出」修复覆盖不到本形态:静默挂死时
    轮永不 finalize,用户没有按 Esc,partial 保留逻辑没有触发机会;
  • 社区已知同类:Kimi K2 max_tokens+stream 时不发 [DONE](规避=收到
    finish_reason 主动 break);claude-code #61001「silently-dead stream 无限挂死」同型。

请求

  1. 流式空闲超时:config.toml 增加可配置的空闲看门狗(业界收敛在 4–5 分钟:
    Codex CLI 300s 硬编码、Claude Code 5min、Qwen Code 240s),超时按 interrupted
    收尾而不是无限等待;
  2. 被顶替/中止轮的 partial 落盘:复用 0.31.1 Esc 路径的 partial 保留逻辑,
    把已流式内容 + [Response interrupted] 标记写入 wire.jsonl 与模型历史
    (Cline/aider/OpenCode 均为同款打法),根治"失忆";
  3. ACP 侧:session/cancel 时先 flush 积压 update 再以 cancelled 收尾
    (协议规范要求),目前静默挂死场景下 cancel 是否 flush 未验证。

客户端临时规避(已实现)

ACP client 侧看门狗:记录最后 session/update 时间,空闲超阈值主动 session/cancel
宽限 20s 无响应杀进程;同时缓存本轮已流式文本,轮非正常结束时在下一条用户消息前
注入合成前缀「上一轮答复因传输中断未完整保存,已输出内容为:…」。

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Trace the ACP streaming path around session/prompt and session/cancel, then inspect config.toml, the 0.31.1 Esc partial-preservation path, and wire.jsonl/history writes. Done means idle streams time out as interrupted, displaced or cancelled turns preserve partial output and usage/history records, and cancellation flushes pending updates before finishing.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
api, cli
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.