dsh-phone-link:飞书私聊与 DSH 会话的直连桥

前言

用 DSH 做智能体会话时,常见需求是:不在电脑前也能往某个会话里丢一句话、看助手回复。飞书私聊是顺手渠道,但若每条消息都经模型中转,既烧 token,也不一定真能唤醒目标会话。DeepSeek Harness(DSH)支持以插件扩展宿主与客户端;社区目录里维护者 jieye666 提供的 dsh-phone-link(客户端类插件)做的是另一类事——在桌面 GUI 右侧栏「手机」tab 上点按钮接通后,入站走轮询与 HTTP,出站走会话事件镜像,不经过模型决策链路。

下面介绍它解决什么问题、怎么装、面板上怎么用,以及配置与限制。

这是什么

dsh-phone-link 把飞书私聊接到指定的 DSH 会话:右侧栏「手机」tab 一个按钮直连,不看模型脸色。

宿主半边负责轮询、/plugins/phone-link/* 路由与消息注入;浏览器半边注册侧栏 tab,可见时约 2 秒轮询状态,后台约 15 秒。传输层依赖本机 ~/.dsh/bin/lark-inbox.py(按 --chat-id 记账),配置写在 ~/.dsh/phone-link/config.json。

核心功能

入站:手机消息进会话

轮询子进程拉取飞书消息后,插件会:

  1. 用 ctx.agents.get(id) 取活着的 agent;没有则 ctx.agents.resume({ resumeSessionId }) 复活。
  2. 再 agent.followup(createUserMessage(...)) 投进收件箱(README 写明不用 agent.inject,因其只排队不唤醒)。
  3. 最后 ctx.sessions.flush(...) 确认写入。

注入内容带 📱 前缀,便于在 GUI 里区分来源。文本 / 富文本(post) / 图片 / 文件会处理;表情、卡片、系统消息不注入。

同 chat 的游标在 0.4.0 起按聊天拆开:~/.dsh/phone-link/cursor/<chatId>.json,避免多绑定互相覆盖导致丢消息。投递前有 delivered.json、内存 inflight 等去重;失败不记账,下次可补投。

出站:助手回复镜像回飞书

订阅 ctx.on('session/event', …):assistant/message 累积文本,turn/end 时整轮经 lark-inbox.py send --chat-id … --text 推到绑定聊天。只取 type === 'text' 块,跳过 reasoning / tool;超长按段落切成 ≤3500 字符分条。dsh-ui 表格在正文留「(表格见下图)」后另发 PNG(table-png.py)。config.json 里 mirrorReplies: false 可关闭镜像;mirrorScheduled 默认 false,避免定时任务轮次重复推送。

客户端:右侧栏「手机」tab

面板提供:

  • 「接通手机 / 断开手机」
  • 「把飞书私聊绑定到这个会话」/「重设绑定」
  • 发探针、立即拉一次
  • 收发时间、轮询间隔、绑定列表、最近注入摘要
  • 飞书内可用命令提示:/status /use /ping /help(本地处理,不进会话、不烧 token)

按钮侧直接 fetch('/plugins/phone-link/...');写操作路由过浏览器栅栏(ctx.connection.requestRejection),本机 GUI 以外 POST 会 403。只读 GET /plugins/phone-link/status 无栅栏,供探活脚本使用。

安装与启用

资料中的安装方式为本地 file: 路径(示例为 Windows 路径,Linux 用户需换成自己机器上的源码目录):

dsh plugin --profile desktop add file:C:/Users/LENOVO/.dsh/src/dsh-phone-link

修改源码后需先卸再装(pnpm 会把 file: 依赖拷进 node_modules,不会随源码自动更新):

dsh plugin --profile desktop remove dsh-phone-link
dsh plugin --profile desktop add file:C:/Users/LENOVO/.dsh/src/dsh-phone-link

装完必须重启 DSH(宿主注册路由 + 浏览器重拉 client bundle)。

插件以当前 DSH 进程权限运行;安装前请自行查看仓库源码与 MIT 许可证,确认 lark-inbox.py 与飞书凭据布局符合你的环境。

典型用法

面板上接通

  1. 打开目标 DSH 会话。
  2. 右侧栏切到「手机」tab。
  3. 点「接通手机」,必要时「把飞书私聊绑定到这个会话」。
  4. 可用「发探针到手机」验证链路;手机上新消息默认最多等 pollSeconds(默认 5 秒)轮询进会话。

手工只看状态(curl)

写路由需过栅栏,curl 会 403;唯一适合 curl 的是状态:

curl -s http://127.0.0.1:<GUI端口>/plugins/phone-link/status

改绑定可改 ~/.dsh/phone-link/config.json 后在面板点「断开 → 接通」,或直接用面板按钮。

飞书内命令(不进模型)

在飞书私聊里发送,例如:

  • /status:连接状态、投递目标、最近收发时间
  • /use <会话 id 前 8 位以上>:切换投递目标
  • /ping、/help

可调配置(节选)

~/.dsh/phone-link/config.json 示例结构(README):

{
  "enabled": true,
  "pollMinutes": 20,
  "bindings": [{ "id": "...", "chatId": "...", "chatName": "...", "sessionId": "..." }]
}

常用键:pollSeconds(默认 5)、pollMinutes(轮询进程寿命,默认 20)、mirrorReplies(默认 true)、mirrorScheduled(默认 false)、defaultChat(面板绑定默认飞书 chat)。改 pollSeconds 后点「断开→接通」即可,无需重启 DSH。

适用场景与注意

适合谁:已在 DSH Desktop 使用固定会话、并用飞书私聊做移动端触点的开发者;希望入站唤醒真实 agent、出站自动回手机,且接受 REST 轮询而非秒级推送。

务必注意:

  • 轮询默认 5 秒,不是实时 WebSocket;将来 README 提到可走 lark-cli event consume,当前未用。
  • 同一 chat 不要同时挂手工 lark-inbox.py wait,会抢游标。
  • 出站已镜像时,不要再用 lark-cli / lark-inbox.py send 手工回话,会重复。
  • 旧版依赖的 ctx.get('sessionController') 在当前 Host 不存在,0.3.x 入站不通的问题与此有关;请使用 0.4.x 线(README 描述 0.4.0 起模块拆分与游标修复)。
  • 社区目录(SkillHub)为独立生态站点,与 DeepSeek / 幻方无官方从属关系;星标与收录情况以目录页为准。

自检(来自 README):

cd ~/.dsh/src/dsh-phone-link && node --test
python ~/.dsh/bin/phone-link-selftest.py
python ~/.dsh/bin/phone-link-selftest.py --live

结尾

dsh-phone-link 的价值可以概括为:指定会话 ↔ 飞书私聊 的双向桥,侧栏一键接通,入站用 agent followup 唤醒会话,出站按轮次镜像回复,并针对飞书富文本做了表格 PNG 与文本降级。需要细节、Issue 或 PR 请走 GitHub;在目录中查找同名插件请用 SkillHub 插件页。

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

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

Xiaoye