DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

DNAlec /

DNAlec/dsh-message-push

Verified

This plugin has no description yet.

★ 0 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHub
READMESource: main@b952c7a0

dsh-message-push

English | 中文

DeepSeek Harness 的 Cordis 插件:除了子代理以外,任何会话停下来都把消息推到配置好的消息平台(QQ / Telegram / 飞书 / 微信),于是人不用一直盯着屏幕。

覆盖所有「停下来」的情形:

场景 触发点 推送文案
任务完成 turn/end(completed) + agent/status(idle) ✅ 任务完成
任务中断 turn/end(aborted) ⏸ 任务中断
任务阻塞 turn/end(blocked) 🚫 任务阻塞
任务出错 turn/end(error) ❌ 任务出错(附错误信息)
达到长度上限 turn/end(max-tokens) ↯ 达到长度上限
需要审批 approval/request ⚠️ 需要你审批
需要回答问题 user-questions/request ❓ 需要你回答问题

每条推送带上会话名(标题 / 目录 + 会话尾号)、最后一段回复的预览,以及「打开网页处理」的链接。

本插件是推送层:不做审批决策、不在聊天里批复、不把入站注入 agent 会话。决策仍在网页;推送只负责把人叫回来。其他插件可以直接调用 ctx.messagePush.notify({...}) 复用同一套渠道与去重。

安装

从 GitHub(钉 tag 更稳):

dsh plugin --profile web add github:DNAlec/dsh-message-push

从本地检出安装(开发时用):

git clone https://github.com/DNAlec/dsh-message-push.git
dsh plugin --profile web add "$PWD/dsh-message-push"

需要 pnpm。装完重启 dsh web:profile 组合在启动时解析,重启后设置页才会出现「消息推送」。 可选依赖(QQ 扫码创建机器人 / 飞书 SDK)随包声明,dsh plugin add 时由 pnpm 安装;缺了只影响对应渠道,插件照常工作。

从 npm 安装(发布后):

dsh plugin --profile web add @dnalec/dsh-message-push

卸载:dsh plugin --profile web remove @dnalec/dsh-message-push,重启后生效。~/.dsh/message-push/ 下的配置与凭据不会删除。

配置

打开 设置 → 消息推送。

  1. 选一个渠道并连接(至少要有一个「已启用 + 已绑定目标 + 已连接」的渠道):
    • QQ:点「扫码创建机器人」用手机 QQ 扫码,或手填 AppID / AppSecret。扫码成功后会自动把扫码者设为推送目标。
    • Telegram:填 @BotFather 给的 Bot token,保存即开始长轮询。
    • 飞书 / Lark:填开放平台 App ID / Secret(需要可选依赖 @larksuiteoapi/node-sdk)。
    • 微信:点「扫码登录」(官方 iLink,仅私聊,建议专用小号)。
  2. 绑定推送目标:未绑定时,用手机私聊机器人发一条消息,然后在设置页「最近入站」里点选;或者直接在未绑定时回复 是 / 确认 / yes / ok,该聊天即被设为推送目标。

    这是私人 bot 设计:谁先回复「是」,谁的聊天就成为推送目标。不要把机器人放到陌生人能私聊的地方。QQ 群聊必须 @ 机器人,并在设置里填发言人的 userId。

  3. 点「发送测试推送」:收到消息说明通道打通。
  4. 按需调整通知规则:总开关、webUrl、预览字数、合并窗口、各类停止原因的开关、以及「子代理会话也推送」(默认关闭)。

触发与去重

  • 只看主会话:session.header.origin === 'subagent' 或 delegationDepth > 0 的会话默认跳过(可在设置里打开)。
  • 同一 turn 只推一条:turn/end 与 agent/status(idle) 到达顺序不保证;先到的先把「停下来」定型,等 turn/end 带来原因后再发(最多等 reasonUnknownDelayMs,默认 8s,超时按「会话已停下」发)。
  • 待审批 / 待回答优先:它们比「停下」更具体,立即推送;同一段停顿里紧跟的 idle 会折叠进这一条(追加「另有 N 条待处理」),不会再多发一条「任务完成」。
  • 合并窗口:同一会话的同类事件在 repeatWindowSecs(默认 60s)内合并,只在计数变化时补发一条更新的提醒,避免刷屏。
  • 发不出去不影响宿主:没有任何可用渠道时记 PUSH_SKIP / PUSH_FAIL 审计并按 60s 限频告警,会话照常运行。

服务 API(给其他插件)

插件启动时通过 ctx.provide('messagePush', …) 在 host plane 提供服务,任意插件可消费:

// 方式一:可选消费,缺了也能跑
const push = ctx.get('messagePush')
if (push) {
  push.notify({
    kind: 'needs-approval',      // needs-approval | needs-question | custom | turn-stop
    sessionId,                   // 会话 id(用于去重与显示尾号)
    title: '修复推送插件',        // 会话名(可选)
    body: '需要批准:删除 3 个文件',
    toolName: 'bash',            // 可选
  })
}

// 方式二:硬依赖(服务不在就等它出现)
export const inject = ['messagePush', 'timer']
export function apply(ctx) {
  await ctx.messagePush.broadcast('自定义通知')
}
方法 说明
broadcast(text, opts?) 发给所有「开着 + 有目标 + 已连接」的渠道,返回 { sent, ok, failed, skipped }
send(channelId, chatId, text, opts?) 直发指定渠道/目标
notify(event) 走观察器管线(去重 + 窗口合并)推送一条通知
onInbound(fn) 订阅入站文本(只读)。返回 { dispose() };回调返回 true 表示已认领,宿主不再处理
channels() 当前真正可推送的渠道 id 列表
state 最近推送时间 / 结果 / 错误

设置页有 overwriteCorrupt 兜底;配置文件损坏时插件用内存默认值运行且绝不覆盖磁盘。

数据

全部在 $DSH_HOME/message-push/(默认 ~/.dsh/message-push/,权限 0600)。不要提交。

文件 内容
config.json 渠道开关、推送目标、通知规则
secrets.json QQ AppID/Secret、Telegram token、飞书 AppID/Secret
wechat.json 微信 iLink 登录态(botToken / 上下文 / 游标)
audit.log PUSH / PUSH_FAIL / PUSH_SKIP / BIND / INBOX / CONFIG / WARN

没有审计行,就说明这次没触发推送。

故障排查

现象 处理
设置页看不到「消息推送」 确认 dsh plugin --profile web add 成功并重启 dsh web
测试推送报「没有任何渠道可推」 渠道没启用 / 没绑 chatId / 没连上——看渠道卡片的状态行
QQ 状态「未配置凭据」 扫码或填 AppID + AppSecret 后点「保存并连接」
QQ 扫码报「未安装扫码依赖」 在插件目录执行 npm install(需要 qrcode 与可选的 @tencent-connect/qqbot-connector)
飞书状态「缺少依赖」 npm i @larksuiteoapi/node-sdk
收到消息但内容为空 会话还没产生任何 assistant 文本(例如空回复);previewChars = 0 也会关闭预览
推送里没有「打开网页」链接 设置里填 webUrl,或让进程环境有 DSH_WEB_URL
群聊回复没人应答 QQ 群必须 @ 机器人,并在设置里填该发言人的 userId
子代理任务没有推送 默认就是关闭的;需要时打开「子代理会话也推送」

开发

npm test      # node --test tests/*.test.mjs
npm run check # node --check 全部源文件

结构:

src/index.mjs         宿主:事件接线、渠道装配、RPC、provide('messagePush')
src/watcher.mjs       会话停下观察器(去重 / 窗口合并 / 原因兜底)
src/format.mjs        推送正文渲染(纯函数,zh/en)
src/service.mjs       服务对象(broadcast / send / notify / onInbound)
src/inbound.mjs       入站:绑定目标 + 回执
src/replies.mjs       入站文本判定(纯函数)
src/store.mjs         配置与凭据读写(区分缺失与损坏)
src/audit.mjs         审计与限频告警
src/channels/         枢纽 + QQ / Telegram / 飞书 / 微信 适配器
src/provisioning.mjs  QQ 官方扫码创建机器人
client.js             设置页(React createElement,无 JSX)
locales.mjs           Client zh/en 文案

纯 JS、零 @deepseek-ai/* 依赖:只用 cordis 的注入名(timer)与运行时自带的 fetch / WebSocket。

改代码前先读 AGENTS.md。

许可

MIT

—/ 5

No ratings yet

Verified DSH bundle

Commit b952c7a05fc8

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout