DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

Amer-CN /

Amer-CN/dsh-retry-panel

Verified

DeepSeek Harness (DSH) 插件:设置里的「断线重试」卡片,429 限流/断流时自动重试,四档耐心一键切换

★ 2 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHub
READMESource: main@2ac68325

dsh-auto-retry

DeepSeek Harness(DSH)插件:设置里一张 「断线重试」 卡片。 请求级重试 + 回合级自动继续 + 同轮截断续写 + 压缩吞轮恢复 + 卡住看门狗。

An auto-retry / auto-continue settings card for DeepSeek Harness: transient 429 / stream failures are retried inside the same turn where possible, and a failed turn can continue itself — with a circuit breaker, permanent-error classification and an idempotency guard.

设置页:断线重试


它解决什么问题

长任务跑到一半,模型服务返回:

429: {"code":"capacity_exceeded","message":"model capacity exceeded: tpm_exceeded"}

DSH 自带的 dsh-llm-retry 默认只重试 5 次、总共约 16 秒(500ms → 10s 退避)。 tpm_exceeded 要等分钟级窗口恢复,16 秒不够;重试耗尽后整轮失败,你回来只看到 「本轮运行失败」,还得自己发「继续」。

还有几种更隐蔽的断档:

  • 输出被 max-tokens 截断,UI 提示「发送继续」;
  • 流挂起,没有报错,界面一直转圈;
  • 上下文压缩把整整一轮吞掉,turn/end 却是 completed,什么都没干就停了;
  • 网关把瞬时 429 写成 insufficient_quota,被 DSH 归类成 QUOTA,内置重试直接放弃。

本插件把这几种情况都接住,并且尽量在同一个回合内恢复,而不是无脑新开一轮。

恢复顺序

1. 请求级重试(沿用 DSH 自带引擎)

把「耐心」写进每个 provider 的 retryPolicy,并显式补上容易漏掉的错误码。 覆盖两个写入点:llm-pi-ai 的每个 provider,以及 DeepSeek 官方 llm-deepseek 命名空间的顶层 retryPolicy。

retryableCodes: EMPTY_RESPONSE, RATE_LIMIT, QUOTA, SERVER,
                TIMEOUT, TRANSPORT, PI_AI_ERROR, UNKNOWN
backoff:        1s 起、60s 封顶、±20% 抖动
选项 行为 适合
普通 最多重试 10 次,约 5 分钟 日常断流
长任务 最多重试 40 次,约 35 分钟 出门前挂任务
死磕 mode: always,一直重试到成功 整晚挂机
关闭 maxRetries: 0 想自己控制

为什么要显式写 QUOTA:很多网关把瞬时 429 capacity/tpm 写成 insufficient_quota,DSH 会归到 QUOTA;而内置默认集合里没有它,会一次都不重试。

2. 同轮截断续写(v0.3 新增)

max-tokens 截断时,在 agent/turn-stopping 阶段用 agent.steer() 注入一条 「继续写,从截断处接着输出」,让同一个回合继续,而不是结束后再开新回合。

  • 单轮最多续写 3 次,避免模型无限复读;
  • 达到上限就放行 turn/end,再由第 3 层跨轮兜底;
  • 只有 continueOnMaxTokens 打开时才生效。

3. 回合级自动继续

一轮彻底失败后:

  • 等 N 秒(默认 5 秒;连续失败按 2 倍逐步拉长,封顶 10 分钟)
  • 以用户身份发送一条「继续」,开新回合,保留全部上下文
  • 最多连续 N 次(默认 5 次),成功一轮清零
  • 你手动发消息或点停止 → 立刻让位
  • 只对主智能体生效;子智能体是一次性任务,不自动继续
  • 自己发的「继续」会被识别成回显,不误触发人工接管
  • 跨重启计数:从持久会话历史倒推连续失败次数,与内存计数取较大值; 插件重载 / 宿主重启后上限依然成立,不会靠重启把熔断清零

永久性错误不继续:AUTH / INVALID_CREDENTIAL / QUOTA / CONTEXT_WINDOW_EXCEEDED / INVALID_REQUEST / UNKNOWN_MODEL 等, 重试也救不回来,直接停下并记日志,避免拿额度空转。

幂等护栏:如果失败前最后一次工具调用没有结果(可能崩在 git push、 写文件、发消息的中间),自动继续的文本会附加一句「先确认外部状态再继续, 不要重复执行可能产生副作用的操作」。

4. 模型故障转移(v0.4 新增,v0.6 改为下拉选择)

失败被判定为可继续后,如果开启了故障转移,会先通过 agent.model.select()(DSH ≥ 0.2.2;旧宿主回退 sessionController.agents.selectForNextRequest())把下一轮请求切到备用列表里的 下一个模型,再发「继续」:

  • 备用模型直接来自你 DSH 里真实的供应商 / 模型目录,下拉选择,不用手输
  • 每个备用可以单独选推理强度(模型支持时才出现)
  • 按顺序尝试;成功一轮后回到第一个备用
  • 列表用完就保持当前模型继续,不会无限换模型
  • 切换只影响本会话的下一轮请求,不改你的全局默认模型
  • 目录来自 sessionController.modelCatalog();万一宿主不提供,才退回手输 服务商/模型名#推理强度
  • 失败过的备用模型会进入冷却(默认 5 分钟,内存表,重启清空); 冷却期内不再切到它,可用高级配置 healthCooldownSec 调整

5. 冷会话恢复(v0.5 新增)

宿主被强杀 / 重启后,上一轮可能停在 error,或者根本没有 turn/end, 原来的实时监听已经错过了它。插件启动 2 秒后会:

  • 通过 sessionController.list() 枚举最近 10 分钟内活跃的持久会话
  • 跳过正在运行、子智能体、以及当前已加载的会话
  • 用 sessionQuery.readSession() 读日志(DSH ≥ 0.2.2;旧宿主回退 sessionController.inspect()),找最后一个 turn/end 或未收尾的 turn/start
  • 对可恢复的失败(或孤儿回合)调用 resolveAgent() 唤醒会话,再补一次继续
  • 单次启动最多检查 5 个会话;已被后续消息覆盖的会话不会动

6. 压缩吞轮恢复(v0.3 新增)

有些压缩事务会把一整轮吞掉:turn/start → 压缩检查点 → turn/end(completed), 中间零 assistant 输出、零工具调用。插件识别这个形状后补一条 「按最近的检查点继续动手」,把被吞掉的活接回来。

7. 额外:卡住看门狗(默认关闭)

打开后,如果一轮运行中超过 N 秒(默认 180 秒)没有任何流输出或事件:

  • 主动取消当前请求(标记为 hook 取消)
  • 交给回合级自动继续,保留上下文

超长工具调用 + 模型静默可能被误判;取消后会马上自动继续,不会丢上下文。

设置项

设置 默认 说明
重试耐心 普通 普通 / 长任务 / 死磕 / 关闭
回合失败后自动发送「继续」 开 回合级总开关
等待秒数 5 0~600;连续失败按 2 倍递增,封顶 10 分钟
最多连续 5 1~50 次,成功一轮清零
继续时发送 继续 支持 {code} {kind} {attempt} {tool}
主模型失败时切换备用模型 关 失败后把下一轮切到备用模型
备用模型 空 从 DSH 真实供应商 / 模型目录下拉选择,可单独选推理强度
重启后恢复被中断的任务 开 启动时扫描最近 10 分钟内的失败/孤儿会话
输出被截断时也继续 开 同轮续写 + 跨轮兜底
卡住不动时自动重来 关 看门狗总开关
卡住判定秒数 180 30~600

保存后立即生效,无需重启。

安装

按 DSH 的 bundle 方式安装(不要手写裸 - id:,那只覆盖已有条目,会报 entry not found 且整条被跳过)。

cd ~/.dsh/profiles/desktop        # 或 web
pnpm add github:Amer-CN/dsh-retry-panel

然后在同一个 package.json 的 dsh.profile.bundles 数组里加入包名:

{
  "dsh": {
    "profile": {
      "bundles": [
        "@deepseek-ai/dsh-base",
        "@deepseek-ai/dsh-web-app",
        "dsh-auto-retry"
      ]
    }
  }
}

或者用 DSH 自带插件命令(若你的版本支持从 GitHub 安装):

dsh plugin --profile desktop add github:Amer-CN/dsh-retry-panel

装完重启 / 重载 DSH。Web 端刷新页面,桌面端重新打开应用(或 F12 → Ctrl+R)。

它是怎么工作的

  • 重试策略:面板保存时先写本插件配置,再 POST /api/auto-retry/apply; Host 在独立 HTTP 任务里调用 settings.mutate,给 llm-pi-ai 的 provider 和 llm-deepseek 顶层写入 retryPolicy。走独立路由是因为在 settings/document-updated 里再写另一个条目会撞 HMR transactions cannot be nested。
  • 自动继续:监听 session/event 的 turn/end:
    • error 且非永久 → 排定继续
    • max-tokens → 跨轮兜底(同轮阶段优先)
    • aborted 且原因是 hook(看门狗自己取消)→ 开关打开时排定继续
    • 用户手动停止(reason.kind === 'user')→ 永不自动继续 到期后通过 agent.followup() 注入一条 user 消息,开新回合。
  • 同轮续写:记录 agent/assistant-stream 最后一个 finish 分片的 reason.kind;agent/turn-stopping 时若还是 max-tokens,就 agent.steer()。
  • 压缩吞轮:按回合记录「是否有压缩检查点 / assistant 输出 / 工具调用」, completed 但只有检查点时判定为吞轮。
  • 看门狗:agent/status、agent/assistant-stream、session/event 都是活动 信号;超时用 agent.cancel({ kind: 'hook' }) 取消,再交给自动继续层。
  • 熔断:连续继续次数按会话记录,成功回合清零;人工输入会取消待发并暂停到 下一次成功回合。

首次安装时,如果所有 provider 都还没有 retryPolicy,Host 会自动应用一次当前 档位;只要有一个 provider 已有自定义 retryPolicy,插件就不会覆盖。

界面

v0.5.1 按 DSH Design System 的官方几何重做了一遍设置卡,不再是一个个裸控件堆起来:

  • 开关:36×20,轨道用 --dsw-alias-brand-primary / --dsw-alias-border-l3,滑块 16px
  • 输入框:32px 高、8px 圆角、--dsw-alias-border-l4 描边、--dsw-alias-bg-layer-1 底色
  • 间距 8 / 12 / 16,卡片 / 分组 / 行三级层次,选中态用品牌色描边
  • 全部颜色走 --dsw-alias-* 语义 token,自动适配明暗主题
  • 仍然是零依赖、纯内联样式,不往页面注入全局 CSS
  • v0.6.4 起带两处图标:插件面板读 package.json 的 icon,设置导航注册 settings.section.icon;两处图形不同,但都是「循环重试箭头」这一家族

生态里确实有专门做界面的项目,值得知道:

  • Physicolor/dsh-design-resources —— DSH Design System:规范、token、官方图标、26 个组件源码与在线画廊
  • Physicolor/dsh-ui-harmonizer —— 规范化官方 UI、审计已装插件的界面冲突
  • Physicolor/dsh-widgets —— 可复用 widget 系统
  • seed-forge/dsh-plugin-ui-components —— 面向插件作者的 host-aware React 组件(构建期依赖)
  • Ssshake1996/dsh-plugin-ui-skill —— 插件 UI 契约与静态检查
  • dshworks/awesome-dsh-themes —— 724 个 DSH 主题 / token 皮肤索引

但官方没有强制所有插件使用的组件库:主题项目主要改全局 token,设置卡布局仍然是各插件自己写。所以这里选择「对齐官方几何 + 零依赖」这条路线。

依赖、权限与失败边界

  • 运行时依赖:仅 @deepseek-ai/schemastery@3.18.5(Config schema 用), pnpm-lock.yaml 固定版本与完整性;没有 install/prepare/build/postinstall 生命周期脚本, 没有原生制品或二进制。
  • 网络:浏览器端只请求 DSH 同源 的两个路由 POST /api/auto-retry/apply 与 GET /api/auto-retry/catalog; 不访问任何外部域名,也不直接请求模型供应商(模型请求仍由 DSH 自己发出)。
  • 存储 / 凭据:插件不读写文件、不持久化、不读取 API Key、Cookie 或系统凭据; 配置由 DSH settings 管理。
  • 外部服务:无。
  • 失败边界:路由失败只返回 503/500 并写 logger 告警,不阻断 DSH 启动; 某个 provider 配置非法时只跳过对应写入,其余功能继续。
  • Bundle Patch:只 insert 自己的 auto-retry 条目,不禁用、替换或遮蔽任何 @deepseek-ai/* 官方组件;权限元数据 network: true / storage: false。

安全报告方式见 SECURITY.md。

兼容

  • DSH 0.2.2-rc.1(2026-11-07 实测;选型改 agent.model.select()、冷读改 sessionQuery.readSession(),旧入口保留回退,见 AGENTS 的 0.6.3)
  • DSH 0.2.1-rc.5(2026-10-30 实测;设置、事件、路由与模型目录 API 全部未变, 无需改代码)
  • 0.2.1-rc.1 起可用(见 package.json 的 dsh.engines.dsh);设置导航图标 需要 DSH 0.2.2+,更老的宿主只显示默认齿轮
  • 需要 settings / configEditor 的 profile(desktop / web);headless 下静默跳过
  • 插件零外部运行时依赖(除 @deepseek-ai/schemastery)

边界

  • 第 1 层只对「临时性」错误重试;AUTH、QUOTA 等永久错误不会无限重试 (「死磕」档本身不限次数,请自行停止)
  • 自动继续是「重开一轮」,不是「续写半个回答」;已提交的工具结果和上下文都保留
  • 故障转移需要显式填写备用模型,不会自动枚举全部已配置模型; 路由健康表只在内存里(重启清空),也没有“请求前预判绕行”
  • 冷会话扫描只看最近 10 分钟、最多 5 个会话,不会翻很久以前的旧账
  • 没有做弹窗/看板、按错误码的自定义触发矩阵

我们参考了谁

v0.4 前系统扫了 GitHub 上 40+ 个 DSH retry / auto-continue / failover / watchdog 项目,重点精读了 20+ 个。落地时参考了这些思路(实现独立,未复制代码):

  • zxmqq1234/dsh-auto-retry —— 回合级继续、熔断、看门狗、通知与看板
  • HsiangNianian/dsh-auto-continue —— 错误分类、退避、静默回合、冷启动扫描、幂等护栏
  • Frog755/dsh-client-auto-retry —— 纯客户端自动「继续」、自身回显识别
  • hhb1028/dsh-retry-boost —— QUOTA 被漏掉的问题、启动注入 retryPolicy
  • zmy15/dsh-plugin-retry-backoff —— 自定义退避曲线、Retry-After
  • mengge237/dsh-auto-continue —— 压缩吞轮识别、max-tokens 续写
  • imcaibaicai/dsh-auto-continue-inturn —— agent/turn-stopping + agent.steer 同轮续写
  • shu0819-sjy/dsh-auto-continue —— 双链熔断、防竞争围栏
  • Captain-OP2008/dsh-auto-continue —— 历史计数、跨重启上限
  • elanski/dsh-failover-continue —— 自动继续 + 模型 failover、冷会话扫描
  • cglyvip/dsh-auto-continue —— sessionController.selectForNextRequest 切换路径
  • QGG4588/dsh-model-failover —— provider 池、预判绕行、熔断持久化

明确没做的:弹窗/看板、按错误码的自定义触发矩阵; 路由健康表还没有持久化,冷会话扫描也只覆盖最近 10 分钟。

开发

npm install
npm test
  • lib/index.js:Host 侧。Config(13 个 volatile 字段,其中 11 个在卡片上可编辑)、首次安装写入、 /api/auto-retry/apply 路由、自动继续 / 同轮续写 / 压缩恢复 / 看门狗状态机
  • lib/client.js:浏览器侧。lazy-CJS 模块壳,注册 settings.section 与 settings.section.icon,渲染设置卡片和导航图标
  • icon.svg:插件面板图标(包清单 icon 字段)
  • cordis.patch.yml:bundle patch,只插入 auto-retry 一行
  • tests/:不启动 DSH 的离线测试(服务端 44 项、客户端 13 项)

没有构建步骤;lib/*.js 就是发布产物。

License

MIT

—/ 5

No ratings yet

Verified DSH bundle

Commit 2ac68325ff4b

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout