diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..3272927 --- /dev/null +++ b/readme.md @@ -0,0 +1,50 @@ +# oc-retry-guard + +模型严重错误自动重试插件(OpenCode TUI)。 + +## 功能 + +当模型在流式返回中出现**严重解析层错误**(HTTP 层返回 200 但响应体含特征错误串,例如 `content after the finish reason`),插件不会让会话停下,而是: + +- **自动补发一次请求**:在原请求 body 的 `messages` 末尾追加一条 nudge 提示(「上一次回复因流式解析层严重错误被截断……请重新完整作答」),重新 POST 同一端点; +- **替换原 response**:把重发成功的 response 回传给 OC,会话流式解析继续,用户侧体验为模型"接着答"而不是报错; +- **事不过三**:同一个 session 在 **2 分钟周期内最多自动重发 3 次**(count ≥ 3 记 STOP 停手);超过 2 分钟窗口计数器自动归零,进入新周期。 + +## 技术链路 + +| 环节 | 机制 | +|---|---| +| 错误识别 | `http.response` 钩子读 `response.clone().text()`,对 body 做 `ERR_SIGS` 特征匹配 | +| 计数 | `Map`,firstAt + 120000ms 内有效,超时归零 | +| 重发 | `http.request` 钩子缓存上一条请求 body(`lastReqBody`),命中错误时 `fetch` 重发 + 追加 nudge | +| 替换 | 钩子 return 改后的 response,OC 用 `Sy(we, ot.response)` 消费 | + +## 日志 + +`~/.config/opencode/oc-retry-guard.log`(append 模式) + +关键行: + +- `RETRY [sessionID前8位] 第N/3次 错误串=...` +- `STOP [sessionID前8位] 3次均失败,停手` +- `重发成功已替换 response` +- `计数器归零(超过2分钟窗口)` + +## 部署 + +| 端 | 路径 | +|---|---| +| Windows 本机 | `~/.config/opencode/plugins/oc-retry-guard.ts` | +| WSL | `/root/.config/opencode/plugins/oc-retry-guard.ts` | + +由 `tools/sync_wsl.py` 的 ITEMS 清单管理,`python D:/桌面/源码/oc_session/tools/sync_wsl.py` 一次性同步(自动算 sha256,diff 时写盘 + `mcpctl reload`)。 + +## 已知取舍 + +1. **路线B 成本**:出错时额外打一次上游(最多 3 次 / 2 分钟),有重复 token 费用;换来的是会话不停、体验连续。 +2. **nudge 非真隐藏**:nudge 文本会进 `messages` 数组,模型可见;不是 system 层注入。实测(A/B 实验)模型只认 messages 末尾的指令,这是最稳妥的位置。 +3. **只对严重解析层错误生效**:普通 4xx/5xx 由 OC 自身重试逻辑处理,本插件不介入。 + +## 文件 + +- `oc-retry-guard.ts` — 插件主文件(TypeScript,OC 的 `tsx` 运行时直接执行)