fix(codex): 回写结构化回合失败状态 - #688
Conversation
同步 Codex 持久化失败终态,避免飞书卡片长期停留在工作中。
deepcoldy
left a comment
There was a problem hiding this comment.
复审结论:REQUEST_CHANGES。普通飞书回合的 429 可见链路本身不会双发,但还有一个 durable 429 阻塞问题;同时确认 Grok 共享路径存在未声明的行为变化。
1. 阻塞:Codex 429 在 durable VC delivery 中会快速烧完重试预算
emitReadyCodexTurns() 会把 429 回合最终作为 turn_terminal(status='failed', errorCode='codex_rate_limited') 发出(src/worker.ts:3976-3982)。普通 IM 回合没有 dispatchAttempt,确实不会重派;但 VC meeting 的 durable delivery 会带 dispatchAttempt。
该终态进入 receiver 后,所有 failed 都被映射为 failed_retryable(src/services/vc-meeting-delivery-receiver.ts:648-669)。同一个 frozen envelope 在后续会议 tick 会再次 POST;receiver 对 failed_retryable 会重新 dispatch,最多 3 次后转成 poison(同文件 :518-543,默认 tick 约 30 秒)。因此持续 429 时会在约一分钟内连续撞三次并把投递流毒化,而不是等待限流卡的 retry countdown。managed/silent delivery 又会抑制辅助卡片,所以这条路径甚至看不到倒计时。
建议让 codex_rate_limited 在 durable contract 中进入 cooldown-aware / 不立即烧预算的语义,并补一条覆盖 dispatchAttempt 的 receiver 集成测试;至少不能按普通瞬时失败每 tick 重派。
2. 确认:共享失败兜底改变了 Grok 主动取消的可见行为
shouldEmitFailedBridgeFallback() 是所有 structured bridge CLI 的共用门,而调用点只排除了 codex_rate_limited。Grok 的 cancelled 会产出空正文、terminalStatus='failed'、terminalErrorCode='grok_turn_cancelled',因此非 adopt 的主动 Ctrl+C 现在会收到“执行失败 / 查看最后错误”提示。终态结算本身没问题,但这段措辞把用户主动取消说成错误,属于噪音且 PR 影响面未说明。
建议二选一:排除 grok_turn_cancelled 并加 worker/gate 回归;或提供取消专用文案,同时在 PR 影响面明确 Grok。真 error / 未知 stop reason 保留失败提示是合理改善。
429 双发核查
普通 Codex 回合中顺序是:先发 screen_update(limited),随后 ready turn 因 rate-limit carve-out 不发 final_output,但第二轮循环仍发 turn_terminal(failed)。daemon 的 turn_terminal 不操作卡片;没有 final_output 也不会触发 usage-limit 自愈清理。因此用户只看到一张限流卡,不会再多出失败提示,限流状态会保留,uuid 重读也有去重。
本地验证
pnpm build:通过(domain audit / tsc / dashboard bundle / dist audit)pnpm exec vitest run test/codex-transcript.test.ts test/codex-bridge-queue.test.ts test/bridge-fallback-gate.test.ts test/grok-transcript.test.ts test/traex-worker-bridge-wiring.test.ts test/cli-usage-limit.test.ts test/card-builder.test.ts test/bridge-final-output-retry.test.ts- 8 files,332 tests 全绿
git diff --check:通过
未合并,等待作者修正并继续遵守“申晗确认前不合码”。
|
本地 delta 复核(尚未 push,commit
非阻塞建议:再锁一条 worker wiring 断言,确认 原阻塞项仍未解决:VC durable 的 |
|
本地 delta |
背景
Codex 结构化回合可能以
event_msg/task_complete结束,同时携带错误且没有last_agent_message。旧逻辑只从response_item提取最终回复,因此限流或任务失败后不会形成终态,飞书卡片会一直停留在“工作中”。改动
task_complete解析为结构化失败终态影响面
botmux send路径不变验证
pnpm exec vitest run test/codex-transcript.test.ts test/codex-bridge-queue.test.ts test/bridge-fallback-gate.test.ts test/traex-worker-bridge-wiring.test.ts test/cli-usage-limit.test.ts test/card-builder.test.ts test/bridge-final-output-retry.test.tspnpm buildgit diff --check未主动制造新的上游 429,以免影响正在运行的会话。