fix: retry transient direct model failures

Direct model conversations previously stopped after the first transient network error or request timeout, including TLS setup ECONNRESET failures. Text requests now retry up to three times with cancellable backoff before visible output, while partial streamed responses are never replayed.

Release note: 直连模型遇到临时网络故障或请求超时时,会在尚未输出内容的情况下自动重试最多 3 次,并支持随时取消。
This commit is contained in:
mesalogo
2026-09-03 14:24:09 +08:00
parent f18e4abb3c
commit 74c3ec19b4
9 changed files with 718 additions and 194 deletions
@@ -5,8 +5,8 @@
| 项目 | 内容 |
| --- | --- |
| 状态 | 已实施 |
| 版本 | 0.2 |
| 日期 | 2026-09-01 |
| 版本 | 0.3 |
| 日期 | 2026-09-03 |
| 关联 PRD | [PRD](./prd.md) |
| 功能逻辑 | [功能逻辑设计](./logic-design.md) |
| 相关架构 | [助手工作栏与执行空间](../assistant-workbar/prd.md)、[本机工具环境](../local-tool-environment/technical-design.md) |
@@ -319,12 +319,19 @@ type SubagentActor =
| Shell 无法启动 | 工具失败 |
| cwd 无效或越界 | 工具调用前失败 |
| 超时/取消 | 终止进程树,返回已有输出和原因 |
| 直连模型瞬时网络错误/请求超时,尚无可见输出 | 500 ms、1 s、2 s 退避,最多自动重试 3 次 |
| 直连模型失败,已有文本或推理输出 | 保留部分输出并失败,不自动重放 |
| 子级模型失败 | 返回 `failed`、部分输出和错误 |
| 子级工具失败 | 由子模型处理;最终无法完成时返回子级失败 |
| 父请求已终止 | 拒绝新调用,丢弃迟到内容并清理 |
不要用宽泛 catch 抹掉取消、超时、Provider HTTP 状态或进程退出上下文。
模型请求重试由 `ModelAgentRuntime` 的统一流式请求边界处理,覆盖普通问答、工具轮次和复用
同一 Runtime 的上下文摘要。重试分类检查错误及有界 `cause` 链中的 Node/Undici 网络错误
码;每次尝试创建独立超时信号。退避等待监听父请求取消。只有完整模型轮次返回后才执行
工具,因此未产生可见文本或推理内容的重试不会重复执行工具。
## 11. 性能
- Shell 探测按执行服务实例缓存,不在每轮模型调用重复探测。
@@ -347,6 +354,8 @@ type SubagentActor =
- 深度 1 过滤、并发 3、队列 20、取消传播和部分输出。
- 编程 Subagent 不创建 Task/Conversation。
- DeepSeek Harness/OpenCode/Continue 不获得本功能工具。
- TLS 建连 `ECONNRESET`、Undici 连接超时、单次请求超时、三次重试上限和退避取消。
- 已产生文本或推理增量后发生网络错误时不自动重放。
### 12.2 本机集成测试