前言¶
在 DSH 里用 @deepseek-ai/dsh-schedule 只能做会话级提醒:after_seconds、at、every_seconds 到期后向当前根 agent 注入一条 followup,定义跟着会话日志走,没有 cron 表达式,也没有跨会话独立执行和运行台账。
如果你要的是「关掉浏览器仍会按表触发、能查历史、能暂停和手动补跑」的定时任务,需要单独的调度与存储层。下面介绍社区插件 dsh-scheduler(维护者 LosEcher,SkillHub 分类:工作流,当前包版本 0.5.4,MIT 许可证)。宿主半包负责持久化任务、调度、headless 执行与 runs.jsonl 台账;客户端半包在会话里提供「定时任务」管理页。
这是什么¶
dsh-scheduler 是 DSH 的定时任务插件:触发器支持 cron、interval、once;任务定义与状态落在 ~/.dsh/storages/dsh-scheduler/ 文件 store(原子写);每次触发用 dsh --profile headless 在任务 workspace 下起独立进程,prompt 需自包含(无会话上下文)。与会话内 reminder 相比,它补齐了 cron、持久化、台账、重试/熔断、以及可选的 deliverTo 把结果 followup 到指定会话。
与内置 schedule 的差异(简要)¶
| 维度 | 内置 @deepseek-ai/dsh-schedule |
dsh-scheduler |
|---|---|---|
| 触发 | 秒级延时 / 固定间隔 | cron / interval(最小 60s)/ once(ISO 时间) |
| 存储 | 会话事件溯源 | jobs.json 等文件 store |
| 执行 | 当前 live 根 agent followup | headless 新进程 |
| 运维面 | 工具 schedule_* |
REST /scheduler/* + 会话内「定时任务」tab |
核心功能¶
调度与执行¶
- 调度循环:约 60s
tick(),并对最早nextRunAt做精确setTimeout唤醒;.tick.lock(mkdir)防止 web 重启交叠时双触发。 - 追赶策略:
catchUpPolicy为run_once(默认,迟到仍补跑一次)或skip(超过maxLatenessMs则跳过并记台账skipped)。 - 并发与抖动:全局并发上限;可选
dispatchJitterMaxMs(默认 180s)错开整点触发;手动触发与失败重试不走抖动。 - 执行:子进程 cwd = 任务
workspace;timeoutMs超时 SIGTERM → SIGKILL;stdout/stderr 尾部约 8KB 写入台账outputHead。 - 重试:
maxAttempts(默认 3)、retryDelayMs;额度/认证类错误不重试;重试中不递增熔断计数。 - 熔断:连续失败达到
maxConsecutiveFailures(默认 5)自动暂停(pausedReason=max_consecutive_failures)。
验收与交付(0.4.x / 0.5.x)¶
assertCmd:headless 干净退出后,在 workspace 内再跑/bin/bash -lc <assertCmd>;失败则本次 run 记failed,且断言失败不重试(仍计入连续失败)。用于弥补「exit 0 ≠ 任务真正完成」。deliverTo:配置sessionId时,结束后把摘要 followup 进该会话(须在线);否则台账记delivery.skipped。notify+ 交付台账(如飞书):可选notify: { channel: 'feishu', require?: bool };与 push 脚本共用的.sent/.skipped状态;finish 行push三态:delivered/skipped/missing。notify.require=true时仅missing判失败且可重试。- 幂等键:prompt 中
{{DSH_SCHED_RUN_KEY}}(jobId|scheduledFor)在 spawn 前替换;可选deliveryKey模板(事件域,如按日期/小时)与{{DSH_SCHED_DELIVERY_KEY}},避免同事件多次触发重复推送。失败告警带独立 key,避免同链重复告警。
台账与观测¶
runs.jsonl:每次运行一行;含dispatchLatencyMs(派发相对计划时刻的延迟,>5min 打 warn)、assertExitCode、delivery、push等。- 轮转:超过
rotateBytes(默认 2 MiB)时保留最新maxRuns(默认 5000)行,其余归档到archive/runs-<YYYY-MM>.jsonl,不直接丢弃旧记录。 - 状态接口:
GET /scheduler/status;插件路径下/plugins/dsh-scheduler/status还可看notifyJobs、pushMissing等(读台账较重,适合按需查)。
管理界面与 API¶
会话内注册 conversation.view(label「定时任务」):列表、新建/编辑(含触发预览)、手动触发、暂停/恢复、运行历史。
REST 同源前缀 /scheduler,例如:
| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /scheduler/jobs |
任务列表 |
| POST | /scheduler/jobs |
创建 |
| POST | /scheduler/jobs/:id/trigger |
手动触发 |
| POST | /scheduler/jobs/:id/pause / resume |
暂停 / 恢复 |
| GET | /scheduler/jobs/:id/runs |
运行台账 |
| GET | /scheduler/preview |
未来 n 次触发时间 |
安装与启用¶
安装命令以仓库 README 为准:
# 1. 注册 bundle
dsh plugin --profile web add github:LosEcher/dsh-scheduler#main
# 2. 重启 dsh web(宿主插件代码 HMR 不覆盖,必须重启)
~/.dsh/scripts/dsh-web-restart.sh
# 3. 验证
curl -s http://127.0.0.1:3080/scheduler/status
本地改源码时可用 dsh plugin --profile web add link:/path/to/dsh-scheduler;改客户端需 node scripts/build.mjs 后刷新页面,改宿主必须重启 dsh web。0.5.x 交付与 runKey 相关行为在重载 dsh web 后生效。
典型用法¶
任务定义要点(jobs.json 模型)¶
创建任务时核心字段包括:prompt(自包含)、trigger、workspace、enabled,以及可选的 deliverTo、catchUpPolicy、maxAttempts、model 链、assertCmd、deliveryKey、notify 等。触发器示例:
"trigger": { "kind": "cron", "expression": "0 9 * * 1-5", "timezone": "Asia/Shanghai" }
// kind: cron | interval | once
// interval: expression 如 "30m" / "2h"(最小 60s)
// once: expression 为 ISO 8601 时间戳
需要事件域交付幂等时(README 0.5.3):
- id: my-digest-job
deliveryKey: 'feed-digest-{{jobId}}-{{date}}-{{hour}}'
notify: { channel: feishu, require: true }
prompt 里对飞书推送脚本使用 {{DSH_SCHED_DELIVERY_KEY}} 或 {{DSH_SCHED_RUN_KEY}};assertCmd 中可用环境变量 $DSH_SCHED_DELIVERY_KEY(由调度器注入)。
机械验收示例(要求当日报告存在、非空、新鲜):
"assertCmd": "f=\"$HOME/.dsh/scheduler-reports/los-governance-daily-$(date +%Y%m%d).md\"\n[ -s \"$f\" ] || { echo \"missing: $f\"; exit 1; }\n[ -n \"$(find \"$f\" -mmin -90)\" ] || { echo \"stale: $f\"; exit 1; }\necho ok: $f"
经过上面的步骤,可在管理页或 API 创建任务后,用 preview 核对下次触发时间,用 trigger 做一次手动试跑,再在运行台账里看状态、耗时、push / delivery 字段。
适用场景与注意¶
适合:需要在 DSH 上跑周期性 agent 作业(巡检、摘要、归档)、且希望定义与历史与 web 会话解耦的团队或个人;已有 headless 脚本或 prompt 工作流,只需挂上 cron 与治理(重试、熔断、台账)。
注意:
- 权限:插件随当前 dsh web 进程权限运行;安装前请阅读源码与 MIT 许可证,确认
workspace与命令范围可接受。 - 执行模型:v1 仅 headless 一条路径,没有「纯 shell 直跑」类型;每次运行有约数秒启动成本,可见性主要靠台账与
deliverTo。 - 推送型任务:README 指出
workspace=/tmp可能导致沙箱拒绝访问~/.dsh/scripts/下 push 脚本;推送类作业宜使用如~/.dsh/scheduler-reports等与既有作业一致的工作区。 - 生态:DSH 强调「一切皆插件」;SkillHub 目录页 为社区站点,与 DeepSeek / 幻方无官方从属关系。
结尾¶
dsh-scheduler 把 DSH 从「会话内定时提醒」扩展到「持久化定时任务 + headless 执行 + 运行台账 + 会话内管理 UI」,并在近版本补上 assertCmd、台账归档、派发延迟可见性,以及面向飞书等渠道的交付幂等与三态门禁。若要安装或查变更细节,可看目录页 skillhub.cn/plugins/LosEcher/dsh-scheduler 与源码 github.com/LosEcher/dsh-scheduler。