dsh-retry-policy
DSH(DeepSeek Harness)模型请求重试策略统一覆盖插件。
不修改 DSH 客户端任何文件,在插件 apply 阶段包装 ctx.llm.prepareCall,把每一次模型调用
携带的 retryPolicy 换成本插件配置的那一套 —— 于是所有 provider 通道(官方 deepseek、
workbuddy、our-free-model、pi-ai、qodercn……)共用同一份重试规则。
为什么需要它
DSH 的重试策略不是全局配置,而是由各 adapter 插件自己返回、固化在注册表里的:
adapter.providerRetryPolicy(provider) // 插件内部写死
-> registration.retryPolicy // dsh-llm 注册时求值
-> preparedCall.retryPolicy // llm.prepareCall 时取出
-> dsh-llm-retry // 监听 agent/request-error 决定重试与退避
profile 的 cordis.patch.yml 只能改插件的 config,改不动插件内部写死的返回值
(官方 deepseek adapter 默认甚至给 maxRetries: 0,也就是失败直接不重试)。
本插件走旁路:在 llm 服务的 prepareCall 外面再套一层,拿到返回对象后替换 retryPolicy。
原对象是 Object.freeze 的,所以浅拷贝出一个新对象返回;用 llm.__retryPolicyPatched
保证同一进程只包装一次。
安装
// ~/.dsh/profiles/<profile>/package.json
{
"dependencies": {
"dsh-retry-policy": "github:User-Clb/dsh-retry-policy"
},
"dsh": {
"profile": {
"bundles": [
// ...
"dsh-retry-policy" // ← 加进 bundles 才会被加载
]
}
}
}
然后在 profile 目录执行 pnpm install(或 DSH 插件面板里安装),重启 DSH 生效。
顺序无关:补丁作用在
llm服务实例上,与 adapter 插件的加载先后没有耦合。
配置
改本包 cordis.patch.yml 里的 config 块即可,不需要动代码:
- insert:
- id: dsh-retry-policy
name: dsh-retry-policy
inject: [llm]
config:
maxRetries: 20 # 单次请求失败后最多再试几次
initialDelayMs: 10000 # 退避基数
maxDelayMs: 10000 # 退避上限;与基数相等 => 指数退避被夹平,等效固定间隔
jitterRatio: 0 # 抖动比例 0..1
retryableCodes: # 只有这些错误码才重试
- EMPTY_RESPONSE
- RATE_LIMIT
- SERVER
- TIMEOUT
- TRANSPORT
| 参数 | 默认 | 取值范围(越界自动夹取) | 说明 |
|---|---|---|---|
maxRetries |
20 |
0..100 |
达到上限后把错误交给上层(配合 dsh-model-rotation 就是"扛不过就轮换") |
initialDelayMs |
10000 |
1..600000 |
退避基数,delay = min(initial × 2^n, max) × jitter |
maxDelayMs |
10000 |
1..600000 |
退避上限 |
jitterRatio |
0 |
0..1 |
0 = 每次整间隔;越大越分散,避免多通道同步重试 |
retryableCodes |
上面 5 项 | 非空字符串数组 | 全非法值时回落到默认列表 |
默认配置的净效果:失败后固定每 10 秒一跳、最多 20 跳(约 200 秒)。
一个需要知道的取舍
dsh-llm-retry 里有一条规则:如果服务端返回了 Retry-After 且大于 maxDelayMs,
normal 模式会直接放弃重试(不打算等那么久)。所以在当前默认值(maxDelayMs = 10000)下,
遇到"429 请等 60 秒"这类响应,本插件会选择不再等、把错误抛给上层。
想让插件尊重服务端的等待时长,把 maxDelayMs 调大即可,例如 60000 或 120000。
API
import { apply, resolveConfig, name, inject } from 'dsh-retry-policy';
resolveConfig(raw) // 纯函数:夹取与规整配置,返回 frozen 对象(可单独测试)
apply(ctx, config) // 安装补丁;llm.prepareCall 不可用时只打 warn、不抛错
apply(ctx) 不带 config 时全部走 DEFAULT_CONFIG,与 cordis.patch.yml 里的值一致。
文件
index.js 97 行,全部逻辑
cordis.patch.yml bundle 组合层 + 默认 config
验证
启动 DSH 后在日志里搜这一行,确认补丁生效并打印了实际参数:
[dsh-retry-policy] 已覆盖模型重试策略: maxRetries=20 initialDelayMs=10000 maxDelayMs=10000 jitterRatio=0 retryableCodes=[EMPTY_RESPONSE,RATE_LIMIT,SERVER,TIMEOUT,TRANSPORT]
node --check index.js
License
MIT
No comments yet. Be the first to write one.