hhb1028/dsh-retry-boost

遇到网关瞬时故障(429 限流/断流/超时)时自动退避重试、直到任务完成——一个 DSH 插件,启动时把防断流 retryPolicy 热注入到所有 llm-pi-ai provider; 之后在运行中新增/修改的 provider 也会自动补上(监听 llm/adapters-updated)。 再也不用手动发「继续」了。

catalog descriptioncatalog 简介 / catalog description:让 DeepSeek Harness 自动重试商汤 429/QUOTA 等瞬时网关故障直到任务完成——启动时给所有 llm-pi-ai provider 热注入加固版 retryPolicy。

Project Overview项目介绍

dsh-retry-boost is a DSH plugin that hot-injects an expanded retryPolicy into all llm-pi-ai providers at startup, with no restart required. It adds QUOTA to retryable codes and applies exponential backoff, so transient 429, dropped streams, and timeouts retry automatically until completion. Use it when gateways like SenseNova return 429 insufficient_quota. Caveat: variant routes such as vision-toolkit and other third-party adapter routes fall outside its scope and will log a warning.

dsh-retry-boost 是一个 DSH 插件,启动时把加宽的 retryPolicy 注入 llm-pi-ai 所有 provider,热生效、无需重启。核心能力是把 QUOTA 加入可重试码并启用指数退避,瞬时 429 / 断流 / 超时会自动重试直至完成。适合商汤 SenseNova 等返回 429 insufficient_quota 的网关。需注意:本插件不影响 vision-toolkit 等变体路由及其他第三方 adapter 的自有路由,遇到此类路由日志会有警告。

Or use CLI install (for developers)或使用命令行安装(适合开发者)

CLI Install命令行安装

dsh plugin --profile web add dsh-retry-boost

hhb1028/dsh-retry-boost 加入你的 DSH 配置(web profile)即可启用。

READMEREADME

dsh-retry-boost

遇到网关瞬时故障(429 限流/断流/超时)时自动退避重试、直到任务完成——一个 DSH 插件,启动时把防断流 retryPolicy 热注入到所有 llm-pi-ai provider; 之后在运行中新增/修改的 provider 也会自动补上(监听 llm/adapters-updated)。 再也不用手动发「继续」了。

English README


问题背景

网关返回 429 insufficient_quota(商汤 SenseNova 和很多 LLM 网关都这么措辞)时, DSH 的错误分类器会先命中 isQuotaExceededError 把它归为 QUOTA 码, 而不是通用的 429 → RATE_LIMIT

DSH 内置重试(dsh-llm-retry)只重试 retryableCodes 列表里的错误码。而默认策略是:

retryableCodes: [EMPTY_RESPONSE, RATE_LIMIT, SERVER, TIMEOUT, TRANSPORT]   // ← 没有 QUOTA
maxRetries: 5
backoff: 500ms → 10s

QUOTA 不在列表里 → 瞬时 429 insufficient_quota 直接 fail-fast: 一次都不重试、turn 立刻死掉,手动「继续」也会再撞同一堵墙。上游同源问题: deepseek-ai/deepseek-harness discussion #892 (目前 0 回复,官方尚未修复)。

解决方案

插件启动时把一份加宽的 retryPolicy 写入 llm-pi-ai 设置命名空间, llm-pi-ai 的 settings onChange热生效,无需重启。注入的策略:

retryableCodes: [EMPTY_RESPONSE, RATE_LIMIT, QUOTA, SERVER, TIMEOUT, TRANSPORT, PI_AI_ERROR, UNKNOWN]
maxRetries: 50
backoff: 1s → 60s,抖动 0.2(指数退避)

效果:瞬时 429 / 断流 / 超时会被指数退避重试直到任务完成——就是把商汤生产 环境里用的那个 settings.yaml 补丁产品化,让任何人都能一键装上。

覆盖范围与已知限制

本插件注入的是 llm-pi-ai 设置命名空间里的 provider——直连主路由全覆盖。 以下路径不在射程内(本插件没有任何配置面能影响它们):

  • 图片输入变体路由(如 vision-toolkit-<provider>):由视觉类插件 (如 dsh-vision-toolkit)通过 registerAdapter 注册的独立 adapter, 其 retryPolicy 在注册时一次性捕获、不读 settings。DSH 对这类路由 会落到内置默认值——retryableCodes没有 QUOTA,商汤 429 会在 这条路线上照样秒断。
    • 插件会自动检测并在日志里警告这类路由(warnUnprotectedVariants, 默认开启,路由注册/更新时复检)。看到 variant route "..." retries WITHOUT QUOTA 就是它。
    • 出路:给变体 adapter 的上游提补丁(让 providerRetryPolicy 委托 upstream 主路由)、换原生支持图片输入的模型、或临时关闭粘贴自动切变体。
  • 其他第三方 LLM adapter 插件注册的自有路由:同样不经过 llm-pi-ai 命名空间,本插件无法注入。

为什么做成插件而不是只改 settings.yaml?

  • 一条命令安装——对所有 provider 生效,不只是你手改的那一个。
  • 跟着新 provider 走——以后新增 provider,下次启动自动套用。
  • 可配置——fill / boost / force 三种策略,重试预算可调。
  • 透明——注入的策略会出现在 settings.yaml 里,看得见、改得动; 插件幂等,绝不和你手改的配置打架。

与 dsh-chat-continue 的区别

dsh-retry-boost(本项目) dsh-chat-continue
定位 第一道防线——让 DSH 内置重试真正生效 第二道防线——内置重试耗尽后兜底重试
机制 给所有 llm-pi-ai provider 注入 retryPolicy(走官方重试链路) 拦截 agent/request-error 自己重发失败的请求
退避 指数退避 1s → 60s + 抖动 固定间隔
手动确认 —— 可选弹窗通知
安装 dsh-retry-boost(npm) @wuxjs/dsh-chat-continue

两者互补:单独用本项目即可;也可以叠上 chat-continue 作为最后的兜底网。

环境要求

  • DSH >= 0.1.1-rc.1(支持 dsh.bundle.patch 宿主插件)
  • Node.js >= 20

安装

方式一:从 npm 安装(推荐):

dsh plugin --profile <你的profile名> add dsh-retry-boost

方式二:直接从 GitHub 安装(跟踪 main 分支):

dsh plugin --profile <你的profile名> add "github:hhb1028/dsh-retry-boost#main"

然后重启 DSH。日志里会出现类似:

dsh-retry-boost: injected retry policy for "sensenova" (mode=normal retries=50 backoff=1000ms->60000ms codes=8)

注入后的策略会出现在 profile 的 settings.yamlllm-pi-ai.providers.*.retryPolicy 下——可以随意手动修改。

配置项

在合并进 profile 的 cordis.patch.yml roster 行(或 DSH 的插件配置界面)里调整:

默认值 含义
strategy fill fill = 只处理没有显式 retryPolicy 的 provider;boost = 对显式配置的也合并缺失错误码并抬高上限;force = 全部替换为插件策略
mode normal normal = 有界重试;always = 无限重试(⚠️ 慎用,永远重试下去)
maxRetries 50 normal 模式下的重试次数上限
initialDelayMs 1000 首次退避延迟
maxDelayMs 60000 退避上限
jitterRatio 0.2 抖动比例(0–1)
retryableCodes 上面 8 个码 需要重试的失败码
warnUnprotectedVariants true 检测到不受保护的变体路由(见「覆盖范围与已知限制」)时打日志警告

卸载

dsh plugin --profile <你的profile名> remove <名字>

卸载后注入到 settings.yaml 里的 retryPolicy不会自动删除——手动清掉 (或卸载前先用 force 策略并恢复你自己的值),即可回到 DSH 默认行为。

工作原理

  1. 启动时读取 llm-pi-ai 设置命名空间。
  2. strategy 为每个 provider 规划目标 retryPolicylib/policy.js 纯函数, 全量单元测试)。
  3. 通过 DSH 的 settings provider 合并写入:经 llm-pi-ai 校验(与 dsh-llmRetryPolicySchema 完全一致)→ 持久化到 settings.yamlinstallSettingsSectiononChange 热生效。
  4. 写入幂等:已达标时再次运行产生空 patch,绝不反复改写。
  5. 变体路由巡检:监听 llm/adapters-updated,对 vision-toolkit-* 等变体 路由的已捕获 retryPolicy 复检;缺 QUOTA 时打警告(每条路由一次, 修复后重新武装),只警告不改动——诚实告知射程边界。

开发

npm test        # 单元 + 真实 schema 集成 + apply 流程测试(node --test)
npm run check   # 语法检查

无构建步骤——纯 ESM。schema 集成测试会把生成的策略跑过框架真实RetryPolicySchema / resolveRetryPolicy,保证注入的 patch 永远不会被设置校验拒绝。

Roadmap

  • 发布到 npm(dsh-retry-boost,v1.2.0 已上线)
  • llm-pi-ai 配置变化时自动重跑策略(v1.2.0:监听 llm/adapters-updated, 防抖 300ms,幂等防自触发——运行中新增的 provider 无需重启即受保护)
  • 可选的设置页面(Settings → Retry Boost)

更新记录

1.2.0

  • 运行中新增的 provider 自动受保护:监听 llm/adapters-updated(与变体路由 警告共用事件),防抖 300ms 后重跑注入计划。计划幂等——本插件自己写入引发 的扫描不会造成二次写入,更不会死循环;启动行为与 v1.1.0 完全一致。
  • 适用于:先启动 DSH、之后往 settings.yaml 加新 provider(比如第二把 key 的 备用通道)、或在设置界面新增供应商的场景,全程无需重启。

许可证

MIT

上一个 Prev dsh-plugins 下一个 Next deepseek-rainbow-fart