前言¶
用 DSH 跑长任务是常态:发起一个任务,切去干别的,回来才发现 agent 五分钟前就跑完了——或者更糟,它一直卡在一个等待你批准的提示上,什么都没干。问题不在于 agent 慢,而在于你没有被及时叫回来。
dsh-notification 解决的就是这件事。它监听 harness 自身的生命周期事件,在需要你注意的那一刻发出提醒。下面介绍它的功能、安装与配置。
这是什么¶
dsh-notification 是一个 DeepSeek Harness(DSH)插件,由 nishit130 维护,当前版本 0.1.1,MIT 许可证。一句话定位:当 agent 完成一轮、报错或等待你的批准时,通过桌面、浏览器或 webhook 通知你,无需盯着标签页。
DSH 的理念是「一切皆插件」,通知这类外围能力正适合以插件形式挂载,而不需要改动 harness 本身。
它监听哪三类事件¶
1、Agent finished:agent/status 由 running 变为 idle,且该轮时长 ≥ minTurnDurationMs 时触发。默认开启。
2、Agent error:监听 agent/error,某一步或某一轮出错时触发。默认开启。
3、Approval needed:监听 approval/request 瀑布。插件只观察(observe-only),始终以 next() 委托,不会替你做批准或拒绝的决定。默认开启。
minTurnDurationMs 的作用是过滤:几秒就结束的快速轮次不值得打扰,只有达到阈值的一轮才通知。
三个通知渠道,分别在哪里触发¶
先说清楚每个渠道在哪台机器上触发,这决定你该开哪个:
- 桌面通知(
desktop):零依赖。macOS 用osascript,Linux 用notify-send,Windows 用 PowerShell toast。在运行 dsh server 的机器上触发,适合dsh web跑在自己机器上的情况。 - 浏览器通知(
browser):使用标准 Notification API,在查看 Web UI 的机器上触发。默认仅在标签页隐藏时弹出——标签页可见说明你正在看。把browserOnlyWhenHidden设为false可改变这一行为。 - Webhook(
webhookUrl):向配置的 URL POST JSON,text字段兼容 Slack,因此 Slack、Discord 或通用 incoming-webhook URL 开箱即用。适合发到手机、Slack 频道或无人值守场景。
三个渠道可以独立开关,比如 desktop: false 或 browser: false。
一个需要注意的组合:单机运行且标签页隐藏时,同一事件可能同时弹桌面和浏览器通知。嫌重复的话,关掉其中一个渠道即可。
安装¶
dsh plugin --profile web add dsh-notification
# or straight from git:
dsh plugin --profile web add github:nishit130/dsh-notification
两条命令任选其一。插件是纯 ESM JavaScript,没有构建步骤,因此从 git 安装也不需要在 allowBuilds 里加条目。
配置¶
在 profile 的 cordis.patch.yml 中覆盖插件配置(或在 Settings UI 里改):
- insert:
- id: notify
name: dsh-notification
config:
minTurnDurationMs: 10000 # 只通知 ≥ 10 秒的轮次
webhookUrl: 'https://hooks.slack.com/services/XXX/YYY/ZZZ'
notifyOnApproval: true
desktop: true
title: 'DSH'
这段配置做的事:把单轮通知的时长阈值调到 10 秒,接一个 Slack webhook,保留桌面通知,并把通知标题改成 DSH。
全部配置项及默认值:
| 配置项 | 类型 | 默认值 | 含义 |
|---|---|---|---|
notifyOnIdle |
boolean | true |
一轮结束时通知 |
notifyOnError |
boolean | true |
agent/error 时通知 |
notifyOnApproval |
boolean | true |
工具调用等待批准时通知 |
minTurnDurationMs |
number | 5000 |
低于该时长的轮次不通知 |
desktop |
boolean | true |
在 server 宿主机发原生桌面通知 |
browser |
boolean | true |
在 Web UI 弹浏览器通知 |
browserOnlyWhenHidden |
boolean | true |
标签页可见时抑制浏览器通知 |
webhookUrl |
string | '' |
可选的 POST 目标(Slack 兼容 payload) |
title |
string | 'DeepSeek Harness' |
桌面通知标题 |
Webhook 的 payload 长这样:
{
"text": "Agent finished — done in 2m 14s",
"summary": "Agent finished",
"body": "done in 2m 14s",
"level": "info",
"ts": "2026-08-21T12:34:56.000Z"
}
text 是 Slack 兼容字段,summary 与 body 便于自定义消费方拆分展示,level 和 ts 提供级别与时间戳。
设计上的三个决策¶
经过上面的步骤,插件已经能正常工作。它的实现有几处设计值得了解:
1、经 ctx 注册的一切都是 effect。卸载或热重载时监听器自动移除,没有手动清理路径(Cordis revertible effects)。
2、approval/request 是瀑布。插件只观察,监听器始终调用 next()——不调用就会抢占决策权、吞掉真正的回答方。
3、永不打断 agent 循环。桌面通知以 detached fire-and-forget 方式 spawn,webhook 失败被吞掉,通知器绝不向 agent 回合抛错。
本地开发¶
想改代码的话,先复制 dev.patch.example.yml 为 dev.patch.yml(已被 gitignore),把它指向你 checkout 的绝对路径,再在 harness 源码 checkout 中运行:
pnpm dsh web --patch ./path/to/dsh-notification/dev.patch.yml
对 index.js 的修改可以热重载,无需重启。测试用 npm test 跑。
适用场景与注意事项¶
按部署方式选渠道:
- harness 跑在自己机器上:开桌面通知即可。
- harness 跑在远程服务器、Web UI 在本地看:开浏览器通知。
- 无人值守或长任务:配 webhook,把消息送进 Slack、Discord 或任何能收 POST 的服务。
两点提醒:
1、插件以当前 dsh 进程的权限运行,安装前建议先读一遍源码和许可证(本项目为 MIT)。从 package.json 的 files 字段看,插件只包含 index.js、client.js、cordis.patch.yml 三个文件,检查成本不高。
2、浏览器通知需要 Web UI 在你首次点击或按键时请求权限,装好后先和页面交互一次。
结尾¶
dsh-notification 解决的问题很具体:agent 跑长任务时,你不必再定时回来刷新标签页。三类事件、三个渠道、一个时长阈值,配置面不大,默认值基本开箱可用。
- 插件目录页:https://www.skillhub.cn/plugins/nishit130/dsh-notification
- GitHub:https://github.com/nishit130/dsh-notification
收录该插件的 skillhub.cn 是社区维护的插件目录,与 DeepSeek 官方无从属关系。