Bundle
dsh-retry-plugin
Whitelist / blacklist / any-error retry policy for DeepSeek Harness, driving DSH's built-in LLM request retry mechanism.
- Source
- jedzqer
- installs
- 2 installs
- License
- MIT
- Updated
- Updated 6 days ago
Readme
[English](README.en.md) | 中文
# dsh-retry-plugin
AI 访问报错(网络抖动、限流、服务器 5xx、配额……)导致对话中断?这个插件让你**完全控制 DSH 内置重试机制的错误码策略**:选择「任何错误都重试」「仅白名单重试」或「除黑名单外都重试」,并调整重试次数与退避参数,让对话无缝继续。
> 这是为 **DeepSeek Harness(DSH)Web UI** 打造的插件。DSH 本身带有基于 `@deepseek-ai/dsh-llm-retry` 的内置重试:模型请求失败后在同一轮内自动重发,带指数退避、持久化事件与原生状态显示。但内置策略默认只重试 5 类临时错误(`EMPTY_RESPONSE` / `RATE_LIMIT` / `SERVER` / `TIMEOUT` / `TRANSPORT`),`QUOTA`、`CONTEXT_WINDOW_EXCEEDED` 等一律放弃。**本插件在 `agent/request-error` 瀑布上以你配置的策略改写 provider 的 `retryPolicy`,从而决定哪些错误码值得重试——调度、退避、事件与 UI 全部复用 DSH 原生能力。**
## 功能特性
- 🎛️ **三种策略模式**,作用于所有 provider:
- **any** —— 任何错误码都重试(有上限,可配次数);
- **白名单** —— 仅列表中的错误码重试(默认 `EMPTY_RESPONSE` / `RATE_LIMIT` / `SERVER` / `TIMEOUT` / `TRANSPORT`,与 DSH 默认一致);
- **黑名单** —— 除列表中的错误码外都重试(例如排除 `QUOTA` / `INVALID_CREDENTIAL` 以免浪费额度,其余全部重试)。
- 🔢 **有界预算** —— 每次失败最多重试 N 次(默认 5),绝不无限请求(区别于内置 `always` 模式的无上限)。
- ⏱️ **可调退避** —— 初始延迟 / 最大延迟 / 抖动比例,指数退避 + 对称 jitter,尊重 provider 返回的 `Retry-After`。
- ⚙️ **原生设置面板** —— Settings -> General 中可视化配置,改动立即生效(热重载,无需重启)。
- 🔁 **DSH 原生重试链路** —— 重试是同一轮内的模型请求重发(**不会**向会话历史注入「continue」回声消息);`llm/retry` 持久化事件、可取消的退避等待、对话流中的「正在重试模型请求(X/Y)· Ns」倒计时与失败原因展示全部由 DSH 内置完成。
## 安装
### 前置要求
- 已安装 [DeepSeek Harness](https://www.npmjs.com/package/@deepseek-ai/dsh)(`dsh` 命令可用)
- [pnpm](https://pnpm.io)
### 步骤
```sh
# 1. 把插件安装进 web profile
dsh plugin --profile web add dsh-retry-plugin
# 2. 安装插件依赖(host 半身需要 @deepseek-ai/dsh-settings 与 schemastery)
# npm 方式安装时通常已自动处理;本地目录开发请执行:
cd dsh-retry-plugin && pnpm install
# 3. 启动或重启 web UI
dsh web
```
本地开发时,也可以在插件源码目录下安装本地副本:
```sh
dsh plugin --profile web add ./dsh-retry-plugin
```
卸载:
```sh
dsh plugin --profile web remove dsh-retry-plugin
```
## 配置
打开 DSH Web 界面左下角的 **设置 (Settings)** -> **通用 (General)**,找到 **AI 失败自动重试 (Auto Retry)**:
- **启用**:开关插件的策略干预;关闭后回到 DSH 内置默认策略。
- **模式**:`任何错误都重试` / `仅白名单错误重试` / `除黑名单外都重试`。
- **错误码列表**:逗号、空格或换行分隔,自动转大写并去重(仅白名单/黑名单模式生效)。常见错误码:`EMPTY_RESPONSE`、`RATE_LIMIT`、`SERVER`、`TIMEOUT`、`TRANSPORT`、`QUOTA`、`CONTEXT_WINDOW_EXCEEDED`、`AUTH`、`MISSING_CREDENTIAL`、`INVALID_CREDENTIAL`、`UNKNOWN`。
- 注意认证错误跨 provider 命名不同:DeepSeek 401/403 报 `AUTH`,pi-ai 路由报 `INVALID_CREDENTIAL`/`MISSING_CREDENTIAL`。要"排除认证失败不重试",黑名单建议同时列入三者。
- **最大重试次数**:0 表示不重试,上限 50。
- **初始延迟 / 最大延迟 (ms)**:指数退避的下限与上限。
- **抖动比例 (0-1)**:退避的随机抖动幅度。
设置写入插件自有命名空间 `dsh-retry`(`$DSH_HOME/settings.yaml` 中的 `dsh-retry:` 段),宿主热重载,下一请求即生效。也可直接手改 `settings.yaml`:
```yaml
dsh-retry:
enabled: true
mode: blacklist
codes:
- QUOTA
- INVALID_CREDENTIAL
- CONTEXT_WINDOW_EXCEEDED
maxRetries: 5
initialDelayMs: 500
maxDelayMs: 10000
jitterRatio: 0.1
```
## 工作原理(简述)
1. 插件 host 半身(`index.js`)以 `prepend` 注册 `agent/request-error` 瀑布处理器——**先于** `@deepseek-ai/dsh-llm-retry` 执行。
2. 根据你的策略,处理器改写本次失败的 `retryPolicy`:
- 决定重试 → 交给 `{mode:'normal', maxRetries, retryableCodes:[失败码], 退避参数}`;
- 决定不重试 → 置空(内置机制直接放行)。
3. `dsh-llm-retry` 原样执行:追加 `llm/retry` 事件 → 退避等待(可取消)→ 追加 `llm/retry-started` → 同一轮内重发模型请求。
4. 重试次数按「轮次 + 步骤 + provider + 策略 key」累计,与你的预算严格对应;对话流中由 DSH 原生渲染重试状态。
## 已知边界
- **作用范围**:所有 provider 统一生效(deepseek-official 与全部 pi-ai 路由)。
- **黑名单模式的 `UNKNOWN`**:未分类错误码(非 DSH `HarnessError`)在黑名单模式下会被重试——这是「除黑名单外都重试」的语义。
- **取消重试**:内置 UI 的 model-retry 节点为展示型;中止整个回合(如新发消息)会取消退避等待。
- **`ABORTED` 与用户取消**不触发重试(由 DSH 在瀑布之前处理)。
## 搭配推荐
推荐搭配 [**dsh-sound-plugin**](https://github.com/jedzqer/dsh-sound-plugin) 使用 —— 一款用于 DeepSeek Harness(DSH)的插件,可以让 AI 在结束工作后或向你提问时播放声音提醒你。配合自动重试,即使你暂时离开窗口,也能第一时间听到 AI 已完成任务或需要你介入的消息。
## 许可证
[MIT](LICENSE)
Install
dsh plugin --profile web add github:jedzqer/dsh-retry-plugin
Profile: web
With the hub plugin installed, ask your agent to install it by name — it resolves the same plan shown here.
dsh plugin --profile web add github:stvlynn/dsh.fish#path:packages/dsh-plugin-hub
install dsh-retry-plugin from the hub
- This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.