Skip to content
dsh.fish
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

  • This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.
Source