Files
cc-web/.planning/2026-10-10-ended-turn-steer-retry/findings.md
shiyue 69b6db0f5b 修复完整会话历史与长气泡交互并更新 CentOS 7 发布包
提交当前工作区全部源码、回归脚本、任务记录及重新构建的 Bun baseline 发布包。发布单文件 MCP 初始化及前端资源一致性验证通过。
2026-10-10 23:40:16 +08:00

2.5 KiB
Raw Blame History

调研记录

用户现象

  • Codex App 的 ccweb 表单答案在点击发送时,上一轮实际上已经结束,但 UI 仍按运行中消息走插入。
  • 失败卡片显示“插入失败”;点击“重试”仍被当成原 turn 插入,无法把答案作为新一轮发送。

代码证据

  • handleCcwebPromptUserResponse 将答案交给 handleMessage;若 activeCodexAppTurns 仍有条目,handleMessage 无条件转入 handleCodexAppSteerMessage。
  • handleCodexAppSteerMessage 已能处理 app-server 返回 no active turn to steer 的部分竞态,但 waitForSteerReady 超时会直接失败。
  • 前端 retryCodexAppSteerMessage 在 !isGenerating || !currentSessionRunning 时直接报“当前对话已结束,无法在原 turn 中重试插入”,正好阻断用户要求的新 turn 降级。
  • 失败项保留 clientMessageId,服务端普通 handleMessage 可用该 ID 避免重复持久化;前端需要把临时卡片提升为普通用户消息并启动生成态。

设计决策

  • 运行中的 turn 继续使用 steer;只有本地运行态已结束或 steer 明确确认旧 turn 不存在时,才转普通 handleMessage 新开 turn。
  • 新 turn 重试沿用原 clientMessageId、正文和附件,避免重复消息;转为普通消息后移除失败操作区并提交消息序号。
  • 不把 expectedTurnId 不匹配、网络错误或附件失效等真实失败泛化成新 turn。

基线验证

  • node scripts/failed-insert-card-unit.js 当前通过,但现有断言明确要求 turn 结束后禁止重试,正是需要改掉的旧行为。
  • node scripts/regression.js --target codexapp-stale-running 当前通过,覆盖了 no active turn to steer 的旧 turn 替换;尚未覆盖 waitForSteerReady 超时和前端失败卡片转普通新 turn。
  • node --check server.js && node --check public/app.js 当前通过。

实现与回归发现

  • 本机 app-server 二进制包含带 expectedTurnId 的无活动 turn 文案,原先只匹配 no active turn to steer 的恢复条件不足。
  • turn/completed 可以先于 steer 错误到达;恢复需要允许本地 entry 已清除,并把旧轮助手消息放回新用户消息之前。
  • 已补充普通文字、完成先到、表单答案的端到端回归;截至本阶段均通过。
  • 前端仍需等待明确发送成功回执后提交临时消息,并通过稳定消息 ID 合并普通 session_message,才能同时避免永久 pending 和重复气泡。