Real model fallback retry (opt-in, at most once)
Worker previously only recorded a model_fallback event on a fallbackable failure and failed the task; ModelRouter.next_after was never used to actually run the task on another model. With --fallback-models (default empty = off, old behaviour unchanged), a fallbackable failure (404/429/5xx/timeout; 401/400 and cancellations never fall back) now re-runs the same task, same worktree/branch, on the first fallback model via host.py's top-level --model flag (no host.py signature change). The second attempt's result is final: actual_model is the fallback model, fallback_count=1, and a double failure keeps both reasons in error_text. LocalExecutor/DockerExecutor pass task model through to host.py; CloudExecutor includes model only when set.
This commit is contained in:
1 parent
f1d42d04f3
commit
7ce603b610
4 files changed
+473
-51
No files matched your search
+19
-3
@@ -530,11 +530,27 @@ interrupted 且终态任务 cancel 返回 400、心跳后 sweep 不扫刚心跳
|
||||
执行器自身的 timeout,这是诚实边界,不要假装同步路径也能中途杀掉。
|
||||
- 失败重试与退避:worker 的 `--max-retries`(默认 1 次重试,0 表示
|
||||
不重试)与 `--retry-backoff-seconds`(默认 5 秒,测试可注入 0);
|
||||
取消不重试,已记 fallback 事件的失败不做同模型重试(fallback 本身
|
||||
就是模型级的重试机制),其它失败(含 worker 超时)重试前按固定
|
||||
退避等待;重试次数记在审计(`worker_retry`)与最终 `error_text`
|
||||
取消不重试,其它失败(含 worker 超时)重试前按固定退避等待;
|
||||
重试次数记在审计(`worker_retry`)与最终 `error_text`
|
||||
的 `[retries=N]` 前缀里,不另起新表;重试耗尽后任务才最终 failed,
|
||||
成本记录与 usage_turns 只按最终结果记一次,不按尝试次数重复记。
|
||||
- 模型 fallback(显式配置时真换模型重试一次):worker 的
|
||||
`--fallback-models`(逗号分隔的模型列表,默认空 = 关闭)。
|
||||
未配时保持老行为:可 fallback 的失败只记 `model_fallback` 事件
|
||||
与 `worker_fallback` 审计、`fallback_count=1`,然后直接 failed,
|
||||
不换模型。显式配了时,一次尝试失败且错误可 fallback(404/429/
|
||||
5xx/timeout;401/400 绝不 fallback,取消绝不 fallback),就先记
|
||||
事件与审计,再用列表里的第一个模型在同一任务、同一 worktree/分支
|
||||
上再跑一次(dispatch 报“任务已存在”时走现有的 run 续跑路径,
|
||||
模型经 host.py 的顶层 `--model` 参数传过去,不改 host.py 签名);
|
||||
fallback 总次数最多 1 次,配两个模型也只试第一个,不会无限换下去
|
||||
烧额度,且与 `--max-retries` 无关(`--max-retries 0` 时 fallback
|
||||
照样跑)。第二次的结果就是最终结果:成功则任务 completed,
|
||||
`actual_model` 写成 fallback 后的模型,成本记录 `fallback_count=1`;
|
||||
第二次也失败则任务 failed,`error_text` 同时写清主模型失败原因与
|
||||
fallback 模型失败原因。边界:真实 token 成本仍是估算(host 协议
|
||||
不暴露真实 token 数),fallback 不改变成本来源,只改变实际跑的
|
||||
模型与 `actual_model`/`fallback_count` 的记录。
|
||||
- 容器清理兜底:`DockerExecutor.list_containers(prefix="codex-")`(
|
||||
`docker ps -a --format {{.Names}}`,失败返回 `[]`)与
|
||||
`cleanup_stale_containers()`(列出并逐个 kill+rm,单个失败只跳过,
|
||||
|
||||
Reference in new issue
Block a user