前言¶
跑一个长时间的 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 aborted 与 interrupted(崩溃孤儿轮在重载时闭合) |
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¶
- 在飞书开放平台创建企业自建应用,拿到 App ID 与 App Secret,在「应用能力」里启用机器人;
- 在「权限管理」开通发消息权限(
im:message或im:message:send_as_bot);若想用setup自动配置,还需开通im.message.receive_v1事件订阅及im:message.p2p_msg:readonly等权限; - 安装并配置 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.yml 写 routing 映射,按工作区标题精确匹配、回退路径匹配;未绑定的通知走全局默认目标,不丢失。
进程死亡看门狗(可选)¶
进程内观察者无法报告自己的死亡(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 当长时间后台工人用的人:挂着一堆会话跑任务、多工作区并行、或在无人值守环境里跑批。通知内容支持模板变量(sessionId、workspace、time、tool、reason、errorLabel 等),可按需调整格式。
使用前几点注意:
- 插件以当前
dsh进程的权限运行,安装第三方插件前建议先检查其源码与许可证(本插件为 MIT); - 需要自建飞书应用并开通对应权限,lark-cli 凭据由 lark-cli 自行保管,插件不接触 App Secret;
- 发送链路是 fail-soft 的,lark-cli 出问题只告警,不会拖垮 DSH 会话。
结尾¶
dsh-lark-bridge 把「会话停了没人知道」变成「一停就收到飞书通知」,覆盖从等待审批到进程死亡的完整链路,且以只读观察者的方式接入,不影响 DSH 本身的执行。
- 插件目录页:https://www.skillhub.cn/plugins/leo-lab-2026/dsh-lark-bridge(社区维护的独立目录站点,与 DeepSeek / 幻方无官方从属关系)
- 源码仓库:https://github.com/leo-lab-2026/dsh-lark-bridge