Skip to content

fix(gateway): recover duplicate Responses tool outputs - #458

Merged
qxcnm merged 2 commits into
qxcnm:mainfrom
MDX-Tom:codex/fix-responses-duplicate-tool-output
Sep 5, 2026
Merged

fix(gateway): recover duplicate Responses tool outputs#458
qxcnm merged 2 commits into
qxcnm:mainfrom
MDX-Tom:codex/fix-responses-duplicate-tool-output

Conversation

@MDX-Tom

@MDX-Tom MDX-Tom commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

摘要

本 PR 加固 Responses WebSocket 请求链路:对重复工具输出进行归一化,并区分连接前导事件与实质输出,确保终止恢复逻辑按正确边界执行。

@MDX-Tom

MDX-Tom commented Sep 4, 2026

Copy link
Copy Markdown
Contributor Author

补充修复:对齐 Responses WebSocket 工具输出与终止恢复语义

现场证据

  • 目标 session 的 JSONL 将失败 call_id 与对应 custom_tool_call / custom_tool_call_output 逐条对齐后,前五个失败轮次均出现同一 call_id 的两个输出记录:结构化命令结果,以及由 host progress notification 产生的第二个字符串结果。
  • Manager request log 对应轮次均为上游 wss://.../responses 的 400,路由连续保持 conversation_bound,没有账号切换或本地模型崩溃证据。
  • 后续截图中的单输出错误发生在同一历史已污染之后;Codex core 日志同时记录 orphan custom tool output,属于前一个非法 continuation 触发的会话级联。当前任务在点击继续后,新请求已恢复为 HTTP/WS 200。

根因

  1. WebSocket response.create.input 允许每个 tool call 一个 output item;重复 output 使用相同 (kind, call_id) 会让上游找不到新的对应 tool call。
  2. Manager 已有 forwarded_non_preamble_event 状态,却用 forwarded_upstream_event 阻止终止恢复;response.created / queued / in_progress 等 preamble 不应消耗恢复机会。
  3. 已污染的客户端历史不能靠猜测补造未知 tool call;网关应在入口消除可确定的重复项,并对剩余上下文恢复保持有界。

本次改动

  • 在 WebSocket response.create 入口按 (kind, call_id) 去重 custom_tool_call_outputfunction_call_output,保留首个真实结果,保留不同 call_id/不同 kind 的输出。
  • 记录 responses_ws_duplicate_tool_outputs_dropped 结构化警告,便于后续从 gateway trace 识别同类事件。
  • 终止重试改用 forwarded_non_preamble_event 作为门禁,成功终态仍不重试。
  • 增加入口归一化和 preamble/实质输出边界回归测试。

验证

  • cargo test -p codexmanager-service --lib responses_websocket --no-fail-fast:70 passed / 0 failed。
  • 两个新增 focused tests 均 1 passed / 0 failed。
  • patch replay 与 rollback 均逐文件 byte-for-byte 通过。
  • pnpm -C apps run build:desktop 与 Tauri macOS arm64 app bundle 构建通过,bundle 已完成 ad-hoc signature verification。

兼容性

不改变数据库、账号路由、前端或普通消息顺序;只删除同一 (kind, call_id) 的后续重复 output item。已存在的污染历史建议从新的 response/session 起测,以避免旧 orphan item 继续参与客户端重放。

@MDX-Tom
MDX-Tom marked this pull request as draft September 4, 2026 02:52
@MDX-Tom
MDX-Tom marked this pull request as ready for review September 4, 2026 06:06
@MDX-Tom
MDX-Tom force-pushed the codex/fix-responses-duplicate-tool-output branch from 2a88bb5 to 15e447a Compare September 4, 2026 07:38
@MDX-Tom
MDX-Tom marked this pull request as draft September 4, 2026 07:39
@MDX-Tom
MDX-Tom marked this pull request as ready for review September 5, 2026 02:46
@qxcnm
qxcnm merged commit bc7bf81 into qxcnm:main Sep 5, 2026
3 checks passed
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.

2 participants