dsh-job-watch:把长跑任务挂到会话侧栏,用颜色告诉你还在跑还是已经跑完

前言

在 DSH 里让智能体提交集群作业、SSH 到裸机、或在远端 tmux 里起长任务,会话往往很快安静下来。任务状态却留在另一套程序里——squeue、bjobs、tmux list-sessions——要确认进度,只能自己开终端轮询、单独开一个监控页,或者几小时后才想起来去看一眼。

GUI 已经知道你在哪个会话里工作。dsh-job-watch 把任务 id 绑到当前会话,按你配置的 provider 去查状态,并在侧栏该行上色:跑着是粉色、跑完是绿色、查不到 id 是琥珀色。你扫一眼侧栏就能回答「哪个会话还有东西在跑、哪个趁你不在已经结束了」。

本文介绍社区插件 yanggaihao5-sys/dsh-job-watch(维护者 yanggaihao5-sys,分类为客户端)。插件与 DeepSeek 无隶属关系,仅声明与 DeepSeek Harness(DSH)兼容。DSH 生态里能力以插件形式扩展;目录站点 skillhub.cn 为独立社区目录,并非 DeepSeek 或幻方官方应用商店。

这是什么

一句话:dsh-job-watch 在 DSH Web GUI 里,把并非由当前会话启动、但你关心的长跑任务 id 登记到当前对话,由侧栏该行携带状态——运行中粉色、已完成绿色、provider 找不到 id 时琥珀色。

插件不实现调度器或 tmux 的业务逻辑。每个 provider 只是一条 shell 命令加「按行匹配」的正则;Slurm、裸机上的 tmux、或你自己的状态 CLI,对插件来说都是同一种抽象。

侧栏状态怎么读

README 用示意说明四种情况:

□ conv A  ·  (no mark)                       nothing to do
▌ conv B  ·  ●  pink, pulsing                a tracked job is running
▌ conv C  ·  ●  green                        finished — come back and analyse
▌ conv D  ·  ●  amber                        the id cannot be found by its provider

绿色是刻意保持的:不会自动过期,目的是提醒你再回来分析结果。只有你在该会话里真正发话时才会清掉;工作区说明、技能目录、运行时快照等注入上下文不算发话,避免静默清掉标记。

运行中的左侧条颜色为 #ec4899(README 截图说明中与实机一致)。

架构:host 与 browser 各做一半

部分 运行位置 职责
host(lib/index.js) dsh 进程 任务账本、provider 轮询、job_watch 智能体工具、/api/job-watch/*
browser(lib/client.js) Web GUI 读状态接口,给侧栏行上色

查询在四种时机触发,彼此可跳过、成本可控:

触发 作用
每 pollMinutes(默认 30) 常规节奏
约 60 s 心跳,对比墙钟与单调钟 机器休眠时定时器不可靠;时钟漂移 > 90 s 视为 sleep,立即补 poll
打开 / 重新聚焦 GUI 人在界面时状态应较新(host 仅在账本早于 requestStaleSeconds 时再查)
register 之后 颜色应立刻正确,而不是等 30 分钟

安装与启用

安装命令(须原样使用,--profile 必须写在 plugin 之后,否则会被拒绝):

dsh plugin --profile web add dsh-job-watch

安装后需要重启 dsh web。

package.json 要求 DSH 引擎 >=0.1.2-alpha.1,许可证为 MIT。插件以当前 dsh 进程权限运行 provider 里的 shell(含 SSH);安装前请自行查看源码与许可证。

配置 provider

在 profile 补丁里至少配置一个 provider,路径形如 ~/.dsh/profiles/<profile>/cordis.patch.yml:

- id: job-watch
  config:
    pollMinutes: 30
    providers:
      # 1) 调度器:一行一个作业(Slurm:id、state、name)
      - id: cluster
        label: Cluster
        command: 'ssh login01 "squeue -u $USER -h -o ''%i %T %j''"'
        linePattern: '^(?<id>\S+)\s+(?<stat>\S+)\s+(?<name>\S+)$'

      # 2) 裸机:把 tmux 会话名当作 job id
      - id: lab
        label: Lab box
        command: 'ssh lab "tmux list-sessions -F ''#{session_name}''"'
        linePattern: '^(?<id>[A-Za-z0-9_.-]+)$'

linePattern 逐行应用;必须有命名捕获组 id,可选 stat、name。不匹配的行忽略。会先剥掉 ANSI 颜色码。

Provider 字段

键 必填 含义
id ✅ job_watch(provider=…) 与 tooltip 用的名字
label 人类可读名称
command ✅ 经平台 shell 执行;SSH 等由你在命令里写
linePattern ✅ 每行正则,命名组 id 必填
runningStates 覆盖默认运行态列表(如 RUN、PEND、QUEUE、WAIT 等)
doneStates 覆盖默认结束态列表(如 DONE、EXIT、FAIL 等)

其它配置项包括:pollMinutes、heartbeatSeconds、commandTimeoutSeconds、minPollGapSeconds、requestStaleSeconds、unknownAfterSeconds、pruneDays(已完成且已确认的行在此天数后 prune)、missingMeans(done:从 listing 消失视为结束;unknown:涂琥珀色)、statePath(默认 $DSH_HOME/job-watch.json)。

provider 命令非零退出不致命(例如无 session 时 tmux list-sessions 退出 1);stdout 仍会解析,失败信息会与状态一并上报。

智能体:job_watch 工具

host 会向每个智能体的 system prompt 注入简短规则,并暴露工具:

job_watch(action='register', jobIds=['40217'], provider='cluster', etaMinutes=540, note='sweep A')
job_watch(action='list')
job_watch(action='refresh')
job_watch(action='clear')

要点如下。

  1. 登记不是可选的。 没人告诉插件的 job,账本里不会有记录,侧栏也不会猜。在 tmux 或集群上提交的任务不会自动出现;规则放在 system prompt 里是为了让智能体在长跑任务提交后调用 register。
  2. register 不传 jobIds 时会 auto-claim:把各 provider 当前列为运行中、且尚未被任何会话跟踪的 job 全部认领。适合事后补登记。
  3. 每次报告会在每个 job 末尾给出建议完成时间:注册时间加你登记的 ETA,或明确说明无法估计及如何测量;插件不会编造时间。ETA 已过而 provider 仍报运行中,会标为 overdue,不会假定已结束。
  4. SKILL.md 与上述约定一致,供加载技能的智能体使用。

典型用法步骤

  1. 按上文安装插件并重启 dsh web,在 cordis.patch.yml 里写好至少一个 provider(集群 squeue 或 lab 的 tmux list-sessions 等)。
  2. 在 DSH Web 中打开你要跟踪任务的那个会话;让智能体在提交长跑任务后调用 job_watch(action='register', jobIds=[...], provider='cluster', etaMinutes=..., note='...')。
  3. 侧栏该行:运行中为粉色脉动;结束后为绿色,直到你在该会话发话;id 在 provider listing 中找不到时为琥珀色。
  4. 需要时可 list、refresh;确认分析完后 clear,或依赖绿色在你发话后清除。

适用场景与限制

适合谁: 经常用 DSH Web 做多会话开发,同时在 Slurm 等调度器、SSH 裸机或 tmux 上跑小时级任务,希望侧栏代替手工轮询的人。

已知限制(README 写明):

  • 侧栏没有官方装饰 API。browser 半部分通过 React fiber 链从行 DOM 找 session id 再注入标记,与当前侧栏实现绑定;异常时控制台与 window.__dshJobWatch.stats() 会给出信息,而不是静默失败。
  • 非 DSH 发起的 job 必须手动 register。
  • 只有侧栏实际渲染到的会话行才会上色;未出现在侧栏列表里的会话没有颜色。

结尾

dsh-job-watch 把「长跑任务 id ↔ 当前对话」写进账本,用可配置的「命令 + 行正则」对接任意 listing,把状态折叠进你已经会看的 Web 侧栏。社区目录页:skillhub.cn/plugins/yanggaihao5-sys/dsh-job-watch。源码与完整说明:github.com/yanggaihao5-sys/dsh-job-watch。

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

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

Xiaoye