Skip to content

[Harness Epic] 让任务在断线或重启后还能接着做,并且不会重复执行 #92

Open

Description

@rojim666

这条 Issue 要解决什么

现在,SztuCode 的任务主要靠 daemon 进程里的内存状态运行。任务记录虽然会分别写入几个文件,但没有一个统一的“进度存档”。

这意味着客户端断线通常还能重新看日志,但 daemon 一旦在关键时刻退出,系统就不一定知道任务究竟执行到了哪里,更不知道某个工具是否已经产生了效果。

用一个实际场景说明

假设 Agent 正在执行下面的步骤:

  1. 模型决定修改 config.py;
  2. 文件已经成功写入;
  3. daemon 还没来得及保存“文件修改成功”的工具结果;
  4. daemon 崩溃并重启。

重启后,系统只能看到“模型准备修改文件”,却看不到结果。此时有两个危险选择:

  • 再执行一次:可能重复修改、重复安装或重复发布;
  • 当作没事发生:会留下已经变化、但没有记录来源的工作区。

当前代码还存在几个类似问题:

  • 任务状态保存在 CoreApp 的内存字典中,重启后 run.get 可能得到 unknown;
  • 用户消息、session 状态、运行事件和最终回复分别写入不同文件,不是一起保存;
  • daemon 重启时,遗留的 active session 会直接变成“等待输入”,未说明之前的任务是完成、失败还是做到一半;
  • session 正在运行时,新消息只得到 session busy,不能选择“排在后面”“立即改变方向”或“先停止再继续”。

主要入口:

  • src/sztu_code/core/app.py
  • src/sztu_code/core/session/manager.py
  • src/sztu_code/core/session/store.py
  • src/sztu_code/core/runner.py
  • src/sztu_code/core/loop.py

修改后应该是什么样

1. 每个任务有一份统一、可靠的进度记录

任务的输入、当前步骤、模型回复、准备调用的工具、工具结果和最终状态都按顺序保存。内存中的 asyncio Task 只是执行者,不再是唯一事实来源。

客户端看到“任务已接收”之前,这条任务必须已经保存成功。客户端重复发送同一个请求,也只能创建一个任务。

2. 每个关键步骤都有明确的恢复点

至少在以下位置保存:

  • 收到用户消息后;
  • 收到完整模型回复后;
  • 工具开始前;
  • 工具结束后;
  • 权限等待时;
  • 子 Agent 交接时;
  • 任务正式结束时。

这里不是要求保存每一个流式 token,而是保存足够恢复的完整步骤。

3. 重启后根据真实情况处理

重启扫描未完成任务,并区分:

  • 尚未开始,可以直接继续;
  • 只读操作中断,可以安全重做;
  • 文件操作结果不确定,需要先检查文件;
  • 外部命令结果不确定,需要用户确认;
  • 任务已经完成,只是界面状态没有及时写好,此时只修复状态,不重新执行。

不能再把所有情况统一改成“等待输入”。

4. 支持运行中追加和改变要求

用户应能选择:

  • 排队:当前任务结束后再处理新消息;
  • 转向:在当前安全步骤结束后采用新要求;
  • 中断:停止当前任务并清理子任务和进程;
  • 恢复:从最近一次安全记录继续。

界面需要显示“消息已收到”“等待生效”“已经生效”或“无法应用”,不能只返回一个模糊的成功响应。

5. 主 Agent、子 Agent 和后台任务统一管理

所有子 Agent、压缩任务和工具进程都要知道自己属于哪个父任务。父任务取消或 daemon 关闭时,它们必须一起停止并完成清理。

必须保证的规则

  • 同一个用户请求无论重发多少次,只产生一个 run。
  • 一个 run 只能有一个最终结果。
  • 已经产生副作用但结果不确定的工具,不能自动再执行。
  • 重启后显示的状态必须和磁盘上的任务记录一致。
  • 不允许出现模型历史里有工具请求,却完全没有对应工具结果的情况。
  • 父任务结束后,不能还有子 Agent 在后台继续修改文件。
  • 任务事件必须带顺序号,客户端断线后可以从上次位置继续接收。

建议分阶段实现

第一阶段:统一任务记录

  • 新建持久化 RunStore;
  • 把内存中的 run 状态和消息去重迁入 RunStore;
  • 让 run.get 和 session 状态从 RunStore 读取;
  • 给事件增加 run 内顺序号。

第二阶段:保存关键步骤并实现重启恢复

  • Agent Loop 在模型和工具边界保存进度;
  • daemon 启动时扫描未完成任务;
  • 文件工具、只读工具和外部命令采用不同恢复策略;
  • 加入真实杀进程测试。

第三阶段:运行中控制

  • 增加排队、转向、中断和恢复命令;
  • 统一管理主 Agent、子 Agent、压缩和工具进程;
  • TUI 与桌面端补齐对应状态。

验收标准

  • 在模型回复中、文件写入后、权限等待中和子 Agent 运行中强制结束 daemon,重启两次后状态仍一致。
  • 文件已经修改但结果未保存时,系统先检查文件,不会直接重复执行。
  • 同一个请求跨重启重复发送 100 次,始终返回同一个 run ID。
  • daemon 重启后,已存在的 run 不会错误显示为 unknown。
  • 任务最终事件只有一个,消息历史、运行状态和事件回放互相一致。
  • 父任务取消后,所有子 Agent 和工具进程在限定时间内停止。
  • Linux 和 Windows 都有重启恢复集成测试。

和现有 Issue 的关系

这些是本 Epic 的底层组成部分,但无法单独解决任务状态分散的问题。

维护者备注

底层可以考虑 SQLite WAL,或者带校验和的追加日志。关键不是具体数据库,而是用户消息、任务状态、工具执行记录和最终事件必须有统一提交顺序,不能继续依靠多个 JSON 文件碰巧保持一致。

Activity

  1. added
    area/agent-coreAgent Loop、Runner、预算、取消与运行时生命周期
    area/harness编码 Agent 的任务生命周期、工作区事务、验证反馈与评测闭环
    on Aug 13, 2026
  2. changed the title [-][Harness Epic] 建立可恢复、可转向、可审计的任务控制面[/-] [+][Harness Epic] 重构 Run Kernel:以持久化日志统一状态、恢复与运行中控制[/+] on Aug 13, 2026
  3. changed the title [-][Harness Epic] 重构 Run Kernel:以持久化日志统一状态、恢复与运行中控制[/-] [+][Harness Epic] 让任务在断线或重启后还能接着做,并且不会重复执行[/+] on Aug 13, 2026
  4. neutronstar238 commented on Aug 15, 2026

    @neutronstar238
    Collaborator

    已实现本 Issue 的第一阶段「统一任务记录」,见 PR #100。

    核心变化:

    • 新增 RunStore,把 run 的 run_id/session_id/status/goal/起止时间与最终结果持久化到 ~/.sztu/runs/<run_id>/run.json(可用 SZTU_RUNS_DIR 覆盖,便于测试隔离)。
    • agent.run 与 session.send_message 在返回 run_id 前先落盘 running 记录;run 终态(completed/cancelled)落盘且不可覆盖,保证一个 run 只有一个最终结果。
    • run.get 优先读内存活动状态,重启后回退到 RunStore,不再返回 unknown。
    • daemon 启动时对账:把崩溃遗留的 running 记录标记为 cancelled(reason=daemon_restarted),使显示状态与磁盘一致。

    验证:WSL(Ubuntu-24.04)下 tests/unit/test_run_store.py 9 通过、tests/integration/test_run_restart.py(含真实杀进程重启)3 通过;ruff check src tests scripts、mypy src、scripts/gen_protocol_doc.py --check 全部通过。

    后续阶段(保存关键步骤并恢复、运行中排队/转向/中断/恢复、事件顺序号、子 Agent 统一管理)按 Epic 拆分为后续子任务继续推进。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/agent-coreAgent Loop、Runner、预算、取消与运行时生命周期area/harness编码 Agent 的任务生命周期、工作区事务、验证反馈与评测闭环challenge/C4-collaboration人机及多智能体协作priority/P0必须优先解决type/epic大型课题

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions