Run 中断与恢复
wesgine Run 的中断触发、孤儿 Run 处理与可恢复 Run 支持。
中断触发源
| 触发源 | 机制 | 说明 |
|---|---|---|
| 用户主动 | POST /sessions/{sid}/interrupt | 唯一的用户中断入口 |
| CycleDetector | 自愈失败后 HITL 超时 | 真循环检测 |
| ErrorStreak | HITL 超时 | 伪进展检测(INV-STREAK-01) |
| BudgetCheckFn | 返回 Exhausted | 商业限制(外部预算检查) |
| Cell Stop | 生命周期 | Cell 停止时排空 Run |
引擎不主动终止的场景
INV-TERM-01:引擎不因 counter 阈值主动终止。
以下 不会 自动终止 Run:
- 轮次数达到上限
- Token 消耗达到上限
- 时间达到上限
- 工具调用次数达到上限
这些只触发 EventBudgetWarning 通知 UI,不终止执行。
中断时的 Run 行为
正常中断
- 设置
ctx取消 - 当前 LLM 调用完成或中断
- 发出
EventInterrupted - 执行 CognitiveSettlement(如果可能)
- 写入 RunEnd 摘要消息
panic_stop
- 跳过 CognitiveSettlement
- 发出
EventError - 尝试保存已有状态
孤儿 Run 处理(INV-CKPT-04)
Cell boot 时自动执行:
Cell.Start()
→ MarkInterruptedSessions() // 标记未完成会话
→ ListOrphanedRuns() // 找到孤儿 Run
→ MarkRunTerminated() // 标记为终止
消费方不必在 PostBoot 调用 MarkInterrupted——引擎层已覆盖。
POST /cells/{id}/sessions/mark-interrupted 保留给运维手动触发。
可恢复 Run(Resumable)
孤儿 Run 可标记为 status=resumable:
GET /observe/runs?status=resumable
查询后可通过重新发起 Run 来恢复:
- 恢复上一个 Run 的 SessionState
- 继续未完成的任务
- 保留之前的记忆和上下文
批量中断
Cell 内所有 Run
POST /cells/{id}/sessions/interrupt-all
需要 cell:admin 权限。
崩溃后批量标记
POST /cells/{id}/sessions/mark-interrupted
需要 cell:admin 权限。
SSE 断连 ≠ 中断
INV-RUN-DETACH:SSE 断开不取消 Run。
Run 生命周期始终与传输层解耦:
| 事件 | Run 行为 |
|---|---|
| SSE 连接断开 | Run 继续执行 |
| 浏览器关闭 | Run 继续执行 |
| 网络超时 | Run 继续执行 |
SSE 重连后可通过 from_seq 续播事件。
相关不变量
- INV-TERM-01:引擎不因 counter 终止
- INV-RUN-DETACH:Run 与传输解耦
- INV-CKPT-04:Cell boot 自动清理孤儿
相关文档
- Run 终止哲学 →
run-termination.md - Run 终端事件 →
run-terminal-events.md - CycleDetector →
cycle-detection.md - ErrorStreak →
error-streak.md - Run 事件重放 →
run-event-replay.md