Skip to content

fix(agent): 修复停机续跑初始化失败与重复回复 - #1721

Merged
chen-ran merged 3 commits into
mainfrom
codex/fix-shutdown-resume
Nov 1, 2026
Merged

chen-ran merged 3 commits into
mainfrom
codex/fix-shutdown-resume

Conversation

@chen-ran

@chen-ran chen-ran commented Nov 1, 2026 •

Copy link
Copy Markdown
Member

Author

  • Human
  • Agent

Type

  • bug
  • feat
  • test

Summary

普通任务在 Server 停机后创建新的续跑 run。如果工作区在前置检查后短暂不可用,初始化失败会直接结束新 run,原任务也不再进入恢复队列。续跑还缺少原请求锚点:读图反馈可能无法落库;当历史输出归入原 turn、实时输出却使用新 turn 时,同一回答或错误会显示两份。

  • 两处启动阶段的工作区目标解析,在 shutdown resume 时针对现有 unavailable 错误每秒重试,窗口为每阶段 30 秒,并遵守原 context 的取消和期限。普通对话、其他错误、模型及工具执行沿用原处理。
  • admission 前将已解析的请求 ID 写入当前续跑意图。再次停机时优先读取当前 run 自己写入的请求或 steer,查不到才校验保存的请求 ID;决策续跑使用同样的 fallback。没有前驱 payload 解析、运行链回溯或跳数上限。请求尚未落库时只补写原任务文本。
  • 实时视图增加可选的 resume_turn,携带原回答身份及已提交前缀;Web 在该 turn 内接续新输出。run 的执行身份、admission turn 和 fencing 保持独立,前缀也不会因本次 provider retry 被清掉。
  • 复用已有的单 run 请求查询,仅增加一条单 run 历史存在性查询,无 schema 迁移。没有引入通用重试框架、额外配置或后台恢复服务。

Related Issues

关联 #1391 的普通任务停机续跑路径。与 #1707 的 waiting_decision 同 run 接管修复独立。

Validation

已重基到 main 858b0fc52(包含 #1697、#1700),保留 checkpoint 历史读取逻辑。重基后及请求锚点精简后已重新执行相关检查与页面续跑;开发数据库使用 main 自带的 migration 170,本 PR 不新增迁移。

  • 相关 Go application / session runtime / message 包测试通过;提交钩子的 Go lint、相关 Go 测试及 Web lint 通过。
  • 真实 PostgreSQL 18 + -race:前置检查成功后,初始目标解析及后续 run-config 解析各失败一次,续跑仍完成读图;断言只有一份图片反馈、没有重复写用户请求、全部续跑输出归入原 turn,实时视图保留原前缀。在同一用例中验证意图保存请求 ID、再次停机的请求解析与决策 fallback;既有 history reset、steer/decision continuation 用例通过,无跳过。
  • 非续跑请求不重试,等待重试时取消/期限生效。
  • Web 两份相关测试共 34 项通过,包括实时成功/错误结果归并到原 turn 且保留前缀;pnpm --filter @memohai/web typecheck、ESLint 和 UI contract 通过(contract 有 3 条既有 warning)。
  • sqlc、Swagger、SDK 已重新生成;Swagger/SDK 无额外 diff。

测试仅新增三个聚焦入口,复用既有 PostgreSQL 与前端 harness;没有复制额外的场景矩阵或把 QA 脚本提交到仓库。

Agent 浏览器验收

独立开发环境 memoh-resume-qa,使用仓库 dev compose、真实 PostgreSQL 与 containerd 工作区,页面为 http://localhost:29082/bot/shutdown-resume-qa。

在真实页面发送任务,实际执行一次 printf 输出 PREFIX_EXEC_OK,随后连续两次在模型流进行中重启 Server。原 run 和 C1 均记录为 lost / session_runtime.interrupted,C2 自动读 /data/qa-resume.png 并完成。C1 没有写入自己的历史消息,恢复只能依靠其意图携带的请求 ID;最终页面保留原步骤且只显示一份回答。

最新会话 7ec05459-ef1d-4073-a91a-cc6db4202b90:原 run 50f05072…,C1 3944d28a…,C2 ae9d1113… 为 completed。C1 运行时保存的请求 ID 和 C2 admission 中的请求 ID 都是 88c5856d-132e-4421-9c27-4091ab0d7784。数据库只有一个原始用户请求,命令和读图各执行一次,图片反馈仍归入原 turn。Provider 请求记录确认收到图片输入。

验证边界: 页面验收使用明确标注的受控 OpenAI-compatible Provider,命令和文件操作通过真实工作区执行。两次暂时不可用的故障注入在 PostgreSQL 集成测试中完成;没有在浏览器演练中人为断开工作区。未进行本 PR 的真实商业模型或 Codex 登录/对话验收,未重新部署 Cloud kind。以上均为 Agent QA。

Screenshots / Recordings

移除运行链回溯后,连续两次重启仍自动完成读图,保留原命令输出,最终回答只显示一次:

连续两次停机后的请求锚点传递与读图结果

Human QA

  • Human QA passed

@chen-ran
chen-ran force-pushed the codex/fix-shutdown-resume branch from c5ef7a3 to 41fadbf Compare November 1, 2026 01:39
@github-actions github-actions Bot added bug Fixes a bug or unexpected behavior change:server Changes backend code, configuration, or API contracts change:web Changes web frontend or shared frontend packages size:M PR size uses the larger of added or deleted lines, excluding generated files labels Nov 1, 2026
@chen-ran
chen-ran marked this pull request as ready for review November 1, 2026 01:58
@github-actions github-actions Bot added size:S PR size uses the larger of added or deleted lines, excluding generated files and removed size:M PR size uses the larger of added or deleted lines, excluding generated files labels Nov 1, 2026
@chen-ran
chen-ran merged commit 035d4f6 into main Nov 1, 2026
24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Fixes a bug or unexpected behavior change:server Changes backend code, configuration, or API contracts change:web Changes web frontend or shared frontend packages size:S PR size uses the larger of added or deleted lines, excluding generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant