dsh-scheduler:在 DSH 里做可持久化的 cron / interval / once 定时任务

前言

在 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 与治理(重试、熔断、台账)。

注意:

  1. 权限:插件随当前 dsh web 进程权限运行;安装前请阅读源码与 MIT 许可证,确认 workspace 与命令范围可接受。
  2. 执行模型:v1 仅 headless 一条路径,没有「纯 shell 直跑」类型;每次运行有约数秒启动成本,可见性主要靠台账与 deliverTo。
  3. 推送型任务:README 指出 workspace=/tmp 可能导致沙箱拒绝访问 ~/.dsh/scripts/ 下 push 脚本;推送类作业宜使用如 ~/.dsh/scheduler-reports 等与既有作业一致的工作区。
  4. 生态:DSH 强调「一切皆插件」;SkillHub 目录页 为社区站点,与 DeepSeek / 幻方无官方从属关系。

结尾

dsh-scheduler 把 DSH 从「会话内定时提醒」扩展到「持久化定时任务 + headless 执行 + 运行台账 + 会话内管理 UI」,并在近版本补上 assertCmd、台账归档、派发延迟可见性,以及面向飞书等渠道的交付幂等与三态门禁。若要安装或查变更细节,可看目录页 skillhub.cn/plugins/LosEcher/dsh-scheduler 与源码 github.com/LosEcher/dsh-scheduler。

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

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

小夜