dsh-restart-task:把被打断的 DSH 回合救回来

前言

在 DeepSeek Harness(DSH)里跑长任务时,常见三类中断:模型请求失败、回复撞上输出 token 上限被截断、回合以 error / aborted / interrupted 收场。产品自带重试预算往往偏紧,失败行和「已重试」记录还会留在对话里;输出截断后若只能手动复制粘贴续写,既费事也容易打乱轮次。社区插件 dsh-restart-task(维护者 zchuxi)面向 Web profile,用「可见重试 + 同轮续写 + 可选新开一轮继续」三层策略,并在输入框旁提供手动控制;设计原则是恢复过的请求尽量不在对话里留下多余痕迹。下面介绍它是什么、能做什么,以及如何安装与使用。

这是什么

dsh-restart-task 是 DSH 的 Web 客户端插件(platform: "web"),当前 npm 包版本 1.5.1,许可证 MIT。它不改变 agent 核心循环的语义,而是在 agent/request-error、agent/turn-stopping 等产品接缝上挂策略,并在 composer 输入区渲染圆形「继续 / 重发」控件与设置卡片。

适用 DSH 运行时(loader 按 peerDependencies["@deepseek-ai/dsh"] 校验):

>=0.1.7-rc.1 <0.1.8-0 || >=0.1.8-rc.1 <0.2.0-0 || >=0.2.0-rc.1 <0.3.0-0

另需 Node >= 24。版本不匹配时 bundle 会在启动时被跳过,并提示可用 dsh plugin allow-version 等豁免途径;更旧的 DSH 缺少本插件依赖的设置与消息格式接缝,不应强行安装。

核心功能

插件把恢复能力分成三层,并在设置里可逐项开关(默认值见后文设置表)。

第 1 层:调宽可见重试预算

当一步模型请求失败且路由到了 retry 策略时,插件在瀑布链里 prepend 到产品自带的 dsh-llm-retry 之前,就地替换 payload.retryPolicy:普通模式下放大 maxRetries(默认 30)、退避基数 retryBaseDelayMs(默认 2000 ms,上限 60 s),retryableCodes 仍沿用 provider 解析结果——401、配额耗尽等确定性错误不会变成死循环。重试由产品执行器完成,对话里显示带实时倒计时的重试行,用户可取消。

可选 retryForever(默认关)会切换到产品的 always 模式,对任意失败无限重试,适合无人值守长任务,但无终端错误守卫。

hideSettledRetry(默认开)在重试结束后隐藏「已重试模型请求(N/M)」/「模型请求重试已取消(N/M)」类已结算记录,进行中的倒计时仍保留。

第 2 层:同轮续写(keep-alive)

当某步因 max-tokens 结束、且该步收尾确实被截断时,插件在 agent/turn-stopping 边界调用 agent.steer(...),不新开回合,在同一 turn 内再跑一步。受 maxTurnContinues(默认每回合 5 次,0 为不限)约束。对 aborted / error 路径不适用。

steer 指令会落盘为 user/message,默认以折叠记录呈现(可通过 hideContinueRow 隐藏),不会变成用户发言气泡。

第 3 层:新开一轮继续

回合已以失败收场时,手动或自动(autoContinue,默认关)通过 agent.followup 发送插件来源消息,source.kind 为 dsh-restart-task。这会新开一个 turn,对话里多一条折叠/通知类记录(默认可隐藏)。因此第 3 层默认关闭,由输入框控件按需触发。

手动控制与发送键接管

上一轮以 error / aborted / interrupted、或输出上限未写完、或存在 lastAgentError 时,发送键左侧会出现圆形控件:继续从中断处接续;若仅最后一次发送失败(promptError)则显示重发上一条输入。智能体运行中、空白无事可做、或输入框已有草稿时不渲染控件。

sendBecomesContinue(默认开):输入框为空且「有继续可做」时,产品原本置灰的发送键会被插件接管为「继续上次任务」(aria-label 等由插件样式负责);一旦输入框有内容立即交还,避免误把发送变成继续。Enter 键未被劫持,仍走产品固定快捷键。

页面上检测到多于一张 [data-composer-card] 时,发送键接管会整体退让,圆形控件仍按 slot 作用域工作。

安装与启用

插件以当前 DSH 进程权限运行;安装前建议浏览 GitHub 仓库 源码与 MIT 许可证。社区目录 SkillHub 条目 与 GitHub 无 DeepSeek / 幻方官方从属关系,属于社区生态收录。

先从仓库安装(无需 npm registry),针对 web profile:

dsh plugin --profile web add github:zchuxi/dsh-restart-task

也可使用 HTTPS 或本地 link(路径勿含空格):

dsh plugin --profile web add https://github.com/zchuxi/dsh-restart-task
# dsh plugin --profile web add link:<路径不含空格>

安装后需重启 profile(宿主半边 lib/index.js 变更才生效);浏览器半边 lib/client.js 支持 HMR,保存后页面可热更新。

移除:

dsh plugin --profile web remove dsh-restart-task

desktop profile 名 CLI 会拒绝,Electron 侧请在插件管理器中用同一 git 地址安装。

典型用法

1. 依赖网络/API 的长任务

保持默认的 retryFailedRequests: true、maxRequestRetries: 30。请求失败时观察对话中的倒计时重试行,必要时在设置里调整 retryBaseDelayMs。不要在不理解风险时打开 retryForever。

2. 长回答被 max-tokens 截断

保持 keepAliveOnMaxTokens: true。截断后输入框会出现「继续」,或空输入时直接点被接管的发送键;同轮续写会在后台 steer,续写行默认隐藏。若单回合续写次数不够,在设置里提高 maxTurnContinues。

3. 回合已失败、需要显式开新 turn 继续

保持 autoContinue: false(默认),在输入框为空时点圆形控件或发送键「继续」。若希望失败后在 delayMs(默认 1500 ms)后自动 followup,可打开 autoContinue,并配置 onError / onInterrupted / onMaxTokens 等触发条件;用户主动停止永不自动继续。

4. 调整设置

打开插件管理器 → 插件页 → dsh-restart-task(plugins.bundle.config 席位)。主要字段默认值如下(完整说明见 README §8):

字段 默认 简要含义
retryFailedRequests true 失败时放大可见重试预算
maxRequestRetries 30 重试次数上限(0 不重试)
keepAliveOnMaxTokens true 输出上限时同轮续写
maxTurnContinues 5 每回合续写次数(0 不限)
autoContinue false 失败后自动新开 turn
sendBecomesContinue true 空输入时发送键即继续
hideContinueRow true 隐藏插件折叠行
hideSettledRetry true 隐藏已结束的重试记录

写入经 configForms.get('restart-task') 实时生效(字段为 .volatile()),无需重启;若浏览器客户端比宿主新,卡片会提示需重启 DSH 后部分项才生效。

适用场景与注意

适合:Web profile 下跑 agent、常遇 transient 请求错误、长输出易被截断、希望少手动复制续写、又希望对话里少堆「已重试」噪音的开发者。

注意:

  1. 插件读的是产品 DOM 与渲染约定(如 data-chat-flow-kind="model-retry");DSH 大版本若改 UI 结构,隐藏规则或发送键接管可能静默失效,圆形控件通常仍可用。
  2. 第 3 层必然新增 turn 与一条生产者来源记录;若追求「零额外轮次」,应优先用第 1、2 层与手动继续,并理解 autoContinue 的开销。
  3. 同轮续写与继续指令对模型可见(第 2、3 层各增加一条指令类消息);第 1 层重试对模型不可见,仍重建相同前缀以利 KV cache。
  4. 安装即信任插件代码在同一 DSH 进程内执行;生产环境请自行审计 源码。

结尾

dsh-restart-task 把「失败重试、截断续写、坏 turn 再开一轮」收成一套可配置策略,并尽量在恢复完成后收走 UI 噪音。目录与文档:

羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜