dsh-lark-bridge:DSH 停止工作时,飞书必收到通知

前言

跑一个长时间的 DSH 会话,最麻烦的不是任务慢,而是它悄悄停下来等你:模型调了 ask_user_question 在等回答、工具在申请沙箱升级等审批、轮次因为模型 4xx 错误直接结束——而你在做别的事,十几分钟后回来看才发现它早就停了。

dsh-lark-bridge 解决的就是这个问题:它在 DSH 会话停止工作时实时调用 lark-cli 发飞书/Lark 通知,目标是做到「DSH 停止工作 = 必收到通知」。对比已有的做法(轮询看屏幕、或者只覆盖单一事件的脚本),它把等待交互、任务结束、被阻塞、请求退避、进程停滞、进程死亡这些情况都纳入了同一套通知体系。

这是什么

dsh-lark-bridge 是一个 DeepSeek Harness 插件,由 leo-lab-2026 维护,许可证为 MIT,当前版本 0.3.0-beta.0。它是一个纯只读观察者:只监听 DSH 持久事件流与 agent/status 生命周期,不拦截任何执行链、不代答任何审批/提问。lark-cli 缺失或发送失败时 fail-soft——只告警,绝不影响 DSH 本身。

覆盖了哪些「停止工作」的场景

类别 触发 通知时机
权限申请 工具申请审批(如沙箱升级) 等待审批期间(约 0.5s 宽限期内被秒批则不打扰)
向用户提问 模型调用 ask_user_question(含 plan mode 计划评审) 等待回答期间
错误致停 轮次以致命错误结束(模型 400/401/403/配额/重试耗尽等 4xx-5xx) 立即,每会话 5 分钟节流
任务完成 轮次 completed 结束且 agent 进入 idle(5s 宽限期过滤 goal 自动续轮//loop idle 宽限后,每会话 30 分钟节流
目标阻塞 turn/end blocked(goal 阻塞 / 预步骤拒绝) idle 宽限后
令牌上限 turn/end max-tokens idle 宽限后
轮次中止 / 异常中断闭合 turn/end abortedinterrupted(崩溃孤儿轮在重载时闭合) idle 宽限后
请求退避 llm/retry 事件达到重试阈值(默认第 2 次起) 达到阈值即发,每会话 5 分钟节流
无进展停滞 agent 保持 running 但默认 10 分钟无任何事件 判定即发,默认 60 分钟重复提醒
正常退出 插件 dispose(仅整个应用树卸载时,HMR/重载不误报) 退出时告别通知
进程死亡 心跳文件 + 进程外监督者检测心跳丢失 心跳超时即发

所有通知类别都有独立开关,默认全部开启,噪音由宽限窗口与节流控制。通知首行默认显示 工作区: {workspace},多个项目并行时能一眼分辨来源。

安装与启用

前置要求:Node ^22.19 || >=24、pnpm、DeepSeek Harness(dsh)。

dsh plugin --profile <name> add dsh-lark-bridge

也可以从 GitHub 源码安装(需要授权构建脚本):

dsh plugin --profile <name> add github:<you>/dsh-lark-bridge#<sha>

装完先验证,再重启:

dsh --profile <name> --dump-config   # 输出中应出现 dsh-lark-notify 行

更新时注意:同 semver 范围内的小版本/补丁用 update;跨版本或装预发布版(比如当前 0.3.0-beta.0)用带显式版本号的 add

dsh plugin --profile <name> list dsh-lark-bridge       # 查看当前安装版本
dsh plugin --profile <name> update dsh-lark-bridge     # 范围内更新
dsh plugin --profile <name> add dsh-lark-bridge@0.2.0-beta.1   # 跨版本/预发布升级

更新插件后需重启 dsh 生效。

首次配置(三步)

1、准备飞书应用与 lark-cli

  1. 在飞书开放平台创建企业自建应用,拿到 App ID 与 App Secret,在「应用能力」里启用机器人;
  2. 在「权限管理」开通发消息权限(im:messageim:message:send_as_bot);若想用 setup 自动配置,还需开通 im.message.receive_v1 事件订阅及 im:message.p2p_msg:readonly 等权限;
  3. 安装并配置 lark-cli(凭据存于 lark-cli 自身,插件从不接触 App Secret):
npx @larksuite/cli@latest install
lark-cli config init
lark-cli auth status -- --verify

2、配置通知目标

插件安装后默认无通知目标,需要指定一次并持久化到 settings.yaml。推荐在 DSH 会话里运行:

/lark-notify setup

然后去飞书给机器人发任意一条消息(默认 3 分钟窗口),插件会自动捕获会话 chat_id 并写入设置,同时发一条测试通知确认链路。也可以在 DSH Web 设置面板手动填 chatId,或在 profile 的 cordis.patch.yml 写 YAML 作为部署默认值。配置优先级:Web 设置面板(用户层)> YAML(部署层)> 默认值。

3、验证

/lark-notify test 你好     # 发送测试通知
/lark-notify status        # 一键诊断:通知目标、lark-cli 状态、发送统计、启用类别

再真实触发一两个场景(让模型申请一次审批、调用 ask_user_question、制造一次重试退避),飞书应收到对应通知。

按工作区路由通知(可选)

一个项目对应一个飞书群时,可以让每个工作区的通知发到各自的群。在目标工作区对应的 DSH 会话里输入:

/lark-notify route

然后去目标飞书群给机器人发任意一条消息(机器人需先被拉进该群,默认 3 分钟窗口),插件即完成「当前工作区 → 该群」的绑定并回发测试通知。CI/批量场景可在 cordis.patch.ymlrouting 映射,按工作区标题精确匹配、回退路径匹配;未绑定的通知走全局默认目标,不丢失。

进程死亡看门狗(可选)

进程内观察者无法报告自己的死亡(OOM/崩溃/误杀)。插件支持写心跳文件,配合进程外监督者脚本覆盖这种情况:

config:
  watchdog:
    enabled: true
    heartbeatFile: '/tmp/dsh-heartbeat'   # 插件每 5s 更新一次

监督者脚本有两种运行方式:

# 常驻模式(默认每 staleMs/4 检查一次)
node scripts/lark-watchdog.mjs --heartbeat-file /tmp/dsh-heartbeat --stale-ms 60000 --chat-id oc_xxx

# 定时任务模式(cron / systemd timer)
node scripts/lark-watchdog.mjs --heartbeat-file /tmp/dsh-heartbeat --stale-ms 60000 --chat-id oc_xxx --once

心跳丢失超过 stale-ms 即发「DSH 进程死亡」通知,同一死亡事件按 --repeat-ms(默认 60 分钟)去重。

适用场景与注意

适合把 DSH 当长时间后台工人用的人:挂着一堆会话跑任务、多工作区并行、或在无人值守环境里跑批。通知内容支持模板变量(sessionIdworkspacetimetoolreasonerrorLabel 等),可按需调整格式。

使用前几点注意:

  1. 插件以当前 dsh 进程的权限运行,安装第三方插件前建议先检查其源码与许可证(本插件为 MIT);
  2. 需要自建飞书应用并开通对应权限,lark-cli 凭据由 lark-cli 自行保管,插件不接触 App Secret;
  3. 发送链路是 fail-soft 的,lark-cli 出问题只告警,不会拖垮 DSH 会话。

结尾

dsh-lark-bridge 把「会话停了没人知道」变成「一停就收到飞书通知」,覆盖从等待审批到进程死亡的完整链路,且以只读观察者的方式接入,不影响 DSH 本身的执行。

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

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

小夜