前言¶
在 DeepSeek Harness(DSH)里跑定时任务或远程触发会话时,模型往往只在终端或 Web UI 里给出答案,不会主动把同一段文字发到手机。若依赖模型自己调用发送工具,常见结果是:会话里已有回复却未外发、误发元评论,或把错误栈当成「报告」推出去。微信 iLink 侧还有硬性约束:每次发送必须携带来自入站消息的 context_token,插件不能凭空造 token,长时间无人发消息时,待发内容只能暂存而不能改走别的通道。
下面介绍社区插件 @ruqinhu/dsh-weixin-link(维护者 ruqinhu,分类:客户端)。它在 DSH 与微信 iLink API 之间做通道:收消息、在合适回合结束时自动投递结果,并记录投递回执与决策轨迹。
这是什么¶
@ruqinhu/dsh-weixin-link 是面向 DeepSeek Harness 的 Weixin(iLink)通道插件。简介原文为:bidirectional send/receive with delivery receipts——即双向收发,并对每次发送尝试留痕。
插件通过 Cordis patch 订阅 session/event,在 turn/end 时决定是否把本回合文本发到微信,而不是把「记得调用发送工具」交给模型。凭证经 DSH 的 credential store(ctx.credentials.resolve())读取,不直接读 process.env,以免覆盖 $DSH_HOME/.credentials.yaml 与项目 .env 的分层规则。
核心功能¶
iLink 发送约束与暂存¶
| 约束 | 后果 |
|---|---|
每次发送必须带 context_token |
token 只能来自入站消息 |
| 不能 mint token | 长时间无入站时,例如 07:00 定时报告会暂存,直到机主再发消息 |
| 不做 fallback 通道 | 失败不转路由;暂存文本在条件允许时重放 |
| 单条文本上限 2,200 字 | 在代码里截断,不交给模型自行控制 |
哪些回合会被自动投递¶
插件按 source.kind 过滤。只有部分来源会外发:
source.kind |
来源 | 是否投递 |
|---|---|---|
schedule |
cron 任务 | 是 |
weixin-link |
机主从微信发来消息触发的回合 | 是 |
user |
终端 / Web UI 输入 | 否(答案已在屏幕上) |
runtime-context / skill-catalog / time-context 等 |
注入上下文 | 否 |
compact-checkpoint / provider / fallback 等 |
压缩、标题等内部流程 | 否 |
README 说明:只有第一条用户消息标定来源;后续回合会注入上下文,若用「最后一条消息」判断,会把所有回合都当成上下文而不投递。
机制要点¶
- 谁负责发:通道在
turn/end自动发送;备选方案是让模型调用weixin_push,实测会出现已回答但未外发、乱推说明文字等问题。模型若不想说话,可使用[SILENT]。 - 去重:10 分钟内相同正文视为已投递;窗口外重复仍会发出。手动
weixin_push会压制同内容的自动投递。 - 空回合:发送
本次无产出(timestamp),避免「跑了但失败」与「没跑」无法区分。 - 失败回合:可发送
⚠️ 回合未完成(reason,timestamp):本次没有可投递的内容。;每个 session 每小时最多一条失败通知(内存计数,进程重启可能多一条)。 - 入站与重放:独立定时器重放 outbox,单线程 serial;长轮询 bootstrap 不阻塞重放,避免 30/60/120 秒退避叠加成数分钟 deaf。
- 存活检测:每轮更新
state/heartbeat.json,默认每 60 秒检查;若连续 3 个 budget(≥ 90 秒)没有任何发送尝试,则重启 poll 循环。
工具与本地文件¶
| 工具 | 用途 |
|---|---|
weixin_push |
立即发送;无法投递时自动暂存(park) |
weixin_status |
登录状态、token 年龄、最近投递、outbox 深度、poll 是否存活 |
路径(默认 dataDir 为 ~/.dsh/weixin-link) |
内容 |
|---|---|
receipts/YYYY-MM-DD.jsonl |
每次发送尝试一行,按东八区日期分文件 |
delivery-trace.log |
每个 turn 的投递决策,含 skip 及原因 |
outbox/ |
等待 token 的暂存消息 |
state/heartbeat.json |
最近尝试/成功、失败次数、入站计数、重启次数 |
delivery-trace.log 示例形态(README 摘录):
send session=... turn=12 kind=turn len=63
ok session=... turn=12 msgid=7521135910923441000
skip session=... turn=13 reason=source-not-deliverable
兼容性与体量¶
| 项 | 值 |
|---|---|
| DSH(peer) | 0.2.1-rc.5 |
| 插件版本(package.json) | 0.4.2 |
| Runtime | Node 22+,无 native 模块 |
| 依赖服务 | tools、credentials、sessionController;agents 可选 |
| 载荷 | 仅文本,≤ 2,200 字符 |
| 许可证 | MIT |
| 单元测试 | README 称 248 条、21 个文件,tsc --noEmit 通过 |
安装与配置¶
安装¶
官方安装命令如下:
dsh plugin add @ruqinhu/dsh-weixin-link
安装前请自行查看 GitHub 仓库 源码与 MIT 许可证。插件以当前 DSH 进程权限运行,凭证与 dataDir 会落在本机,部署前确认 token 与数据目录权限可接受。
凭证¶
在 credential store 中配置 bot token 与 account id。默认 credential 名称:
WEIXIN_BOT_TOKEN(配置项tokenEnv)WEIXIN_BOT_ACCOUNT_ID(配置项accountIdEnv)
主要配置项¶
| Key | 默认值 | 含义 |
|---|---|---|
baseUrl |
https://ilinkai.weixin.qq.com |
iLink 端点 |
dataDir |
~/.dsh/weixin-link |
token、outbox、receipts、trace |
poll |
true |
是否运行入站长轮询 |
pollTimeoutMs |
40000 |
客户端超时,须大于服务端 35 s hold |
defaultUserId |
"" |
收件人;空则用最 recent 入站发送者 |
echoOwnMessages |
false |
是否把机器人自己的消息当入站 |
sessionId |
"" |
入站路由到的 session,冷启动可恢复 |
replayIntervalMs |
300000 |
outbox 重试间隔 |
dedupeWindowMs |
600000 |
相同正文去重窗口 |
notifyTurnFailures |
true |
回合未完成时是否通知 |
watchdogIntervalMs |
60000 |
存活检查间隔;0 关闭 |
典型用法¶
- 安装插件并在 DSH credential store 中写入
WEIXIN_BOT_TOKEN与WEIXIN_BOT_ACCOUNT_ID。 - 保持
poll: true,从微信向机器人发一条消息,为后续发送换取context_token。 - 配置 cron(
source.kind为schedule)或继续通过微信触发会话;回合结束后查看手机是否收到自动投递,必要时读delivery-trace.log与receipts/。 - 需要主动推送或排查队列时,在会话中调用
weixin_status查看 token 年龄与 outbox 深度;无法立即发送时用weixin_push(会 park 到 outbox)。
README 记录的实测:入站 10:00:04 → 回合完成 10:00:24 → 同秒 ok msgid=...;14 小时运行 watchdog restarts: 0。配额耗尽(429 AccountQuotaExceeded)时,旧构建连续 skip not-completed,新构建在约四分钟沉默后发出一条说明回合未完成的短消息。
适用场景与注意¶
适合:希望 DSH 定时报告、微信触发的会话结果自动回到同一微信对话;需要 JSONL 回执与 trace 审计发送尝试的场景。
限制(README 开放问题摘要):
- Token 无法由插件刷新;约 12 小时无入站会 park 发送。
- 单 poll 循环、单收件人;多账号需额外路由层。
- Outbox 重放串行;富媒体 / 卡片未支持,仅文本。
- 调试器暂停或长 GC 可能被 watchdog 判为 stall 并重启(无害但会记入 heartbeat)。
DSH 生态强调「一切皆插件」;SkillHub 目录页 为社区站点,与 DeepSeek / 幻方无官方从属关系。
结尾¶
@ruqinhu/dsh-weixin-link 把微信 iLink 的 token 约束、回合来源过滤和 turn/end 自动投递合在一起,减少「模型忘了发微信」类问题,并用 outbox、trace 与 receipts 把失败与 skip 原因留在磁盘上。进一步细节见 GitHub README(含中文 README.zh-CN.md)与目录页 skillhub.cn/plugins/ruqinhu/dsh-weixin-link。