Meowrium/dsh-auto-continue

dsh-auto-continue

dsh plugin: auto-continue after quota/rate-limit reset + peak/valley idle-task suspend/resume, with composer toggles and a status line.

待分类auto-continuedeepseek-harnessdsh

dsh-auto-continue

一个给 DeepSeek Harness(dsh) 用的双半插件(host + 浏览器),在对话输入栏加两个开关:

  1. 自动续跑 —— 请求因 RATE_LIMIT / QUOTA 中断时,额度/速率限制一重置就自动接着跑。
  2. 闲时任务 —— 峰价时段自动挂起正在跑的会话,进入谷价时段自动恢复。长任务不用守着,等便宜时段自己跑。

两个开关都在输入栏按钮上,下方状态行显示当前峰/谷价与距下次切换的时间。开关状态经 dsh settings 服务持久化,重启后仍在。

English README

安装

dsh plugin --profile web add github:Meowrium/dsh-auto-continue

然后重启 dsh web。本插件是 bundle,自带 patch 层,不需要手改 cordis.patch.yml。

需要 dsh ≥ 0.1.5-alpha.1(实测于 0.1.5-rc.1)。见下方兼容性。

用法

重启后打开会话,输入栏会出现两个胶囊按钮:

按钮作用
闲时任务峰价时段:挂起正在运行的会话;谷价时段:自动恢复
自动续跑命中 RATE_LIMIT / QUOTA 后,按重置时间自动重试

任一开启后,输入框下方会多出一行状态,例如 谷价 · 距峰价 23分 · 自动续跑。

工作原理

峰谷时段

全部为北京时间(UTC+8,无夏令时)。峰价为:

09:00 – 12:00   以及   14:00 – 18:00

其余时间为谷价。

  • 进入峰价 —— 每个正在运行的 agent 以 { keepInbox: true } 取消(消息不丢),并在 agent/pre-step 拦截新一轮:把已认领的消息塞回 agent 的 inbox,然后拒绝该 step。
  • 进入谷价 —— 给每个被挂起的 agent 发一次 followup,让它接着干。
  • 把闲时任务开关关掉会立刻恢复所有被挂起的会话。

时段边界是 lib/index.js 里的一个常量:

const BOUNDARIES_SEC = [9 * 3600, 12 * 3600, 14 * 3600, 18 * 3600];

按你自己的价格表改这四个值即可。

自动续跑

挂 agent/request-error。若失败码是 RATE_LIMIT 或 QUOTA,用 provider 给的 Retry-After(providerRetryAfterMs)安排定时恢复;缺失时兜底 60 秒,上限 24 小时。当前请求正常结束,之后会话自己继续。

设置项

持久化在 dsh settings 命名空间 auto-continue:

键类型默认
idleTaskEnabledbooleanfalse
autoContinueEnabledbooleanfalse

包结构

单包同时承载插件的两个半:

package.json        dsh.bundle.patch  → cordis.patch.yml(插入 host 半)
                    dsh.client        → lib/client.js   (浏览器半)
cordis.patch.yml    bundle patch:插入条目 { id: auto-continue, name: dsh-auto-continue }
lib/index.js        host 半 —— settings、定时器、agent 事件
lib/client.js       浏览器半 —— 输入栏开关 + 状态行

兼容性

  • 不 import @deepseek-ai/dsh-settings 的任何具名导出。settingsNamespace / installSettingsSection 在 dsh 0.1.2-alpha.1 已被删除,而缺具名导出会在模块链接期直接抛 SyntaxError,整个插件都活不了。改为经 ctx.inject(["settings"]) 拿服务、调用其 installSection(...) —— 与官方 dsh-agent-default-model 的做法一致。
  • 浏览器半用 slots.inject(...) 注册进 conversation.input.left 与 conversation.composer.dock;dsh 0.1.5 起这是必需写法(直接 register 会抛 "slot ... is not declared")。
  • 浏览器模块 id 与包名一致(dsh-auto-continue),因为 dsh-client-modules 以 loader entry 名作为客户端模块 id。

许可

MIT