Run 终止哲学
wesgine 的 Run 终止策略:无限制,有韧性(INV-TERM-01 / INV-TERM-04)。
核心原则
引擎不因 counter 阈值主动终止正常运行的任务。
Run 的终止只有以下合法来源:
| 来源 | 说明 |
|---|---|
end_turn | 模型主动结束 |
| 用户中断 | POST /sessions/{sid}/interrupt |
| CycleDetector 自愈失败 | 真循环,HITL 超时 |
| ErrorStreak HITL 超时 | 伪进展检测 |
BudgetCheckFn 返回 Exhausted | 外部商业限制 |
| Cell Stop | 生命周期 |
INV-TERM-01
引擎不因 counter 阈值(轮次 / token / 时间)主动终止。
这些指标是观测值,不是终止条件。
INV-TERM-04:终端事件完整性
runLoop 的每个 return 路径必须在返回前发出终端事件:
| 事件 | 含义 |
|---|---|
EventDone | 正常完成 |
EventError | 错误终止 |
EventInterrupted | 用户中断 |
context 取消场景
callLLM 和 execute 返回 phaseReturn 时,若 ctx.Err() != nil:
- 必须发出
EventDone("context_cancelled") - 不得依赖 for 循环顶部的
ctx.Err()检查(因为phaseReturn直接return)
缺失终端事件的后果
terminal guard 合成虚假 EventError(missing_terminal_event):
- 消费方显示误导性错误
- 无效重试按钮
终止路径清单
Run 可通过 11 种非 end_turn 路径终止:
budget_exhaustedcycle_detectedquality_revision_limitcontext_cancelledcognitive_errorexecute_errorpanic_stoperror_streakinterruptedguardrail_blockedcontent_filter_blocked
每种终止路径都必须执行 CognitiveSettlement(唯一例外:panic_stop)。
错误重试分类
| 类别 | 行为 | 示例 |
|---|---|---|
| 可重试 | 显示重试按钮 | Provider 503/429、cognitive_internal |
| 不可重试 | 柔和提示,无按钮 | guardrail_blocked、budget_exhausted |
| 静默 | 不渲染 | thinking_only_retrying、empty_response_recovered |
| 用户中断 | 压制 | context_cancelled、interrupted |
分类由 engine-errors.ts 的 severity 字段控制。
一次性宽限调用
_budget_grace_call 机制:
- 预算用尽后给 AI 最后一次机会保存进度
- 只有一次
- 不重置预算计数
RunEnd 摘要
Run 终止时引擎写入 role=system 摘要消息到 wes_messages:
- 使用
evt.TurnNum作为MessageRow.TurnNum(INV-PERSIST-03) - 调用
IncrementMessageCount