前言¶
在 DSH 里做复杂任务时,常见做法是把管线、跑章、门禁等拆成多个独立会话,各自保有上下文。会话之间若需要交接,往往只能让操作者在多个窗口之间复制提示词,既慢也容易丢上下文。
下面介绍的 dsh-session-send(仓库名 nevercanner/dsh-session-send)在 DSH 宿主内提供一层「会话总线」:平级会话可按 session id、自注册名或 dsh-team 成员名寻址,发消息后可直接写入目标会话的收件箱并唤醒对方,而不依赖 OpenClaw 的配置或数据面。插件由社区维护者 nevercanner 发布,在 SkillHub 目录中归类为工作流;当前 GitHub 星标为 0,许可证为 MIT(见仓库 package.json)。
DSH 生态奉行「一切皆插件」;SkillHub(目录页)是社区插件索引,与 DeepSeek / 幻方无官方从属关系,下文安装与配置均以仓库 README 为准。
这是什么¶
dsh-session-send 参考 OpenClaw session send 的消息语义,实现为 DSH 插件。它运行在 DSH 宿主进程内,不读写 openclaw.json,不读取 OpenClaw 的 session 账本,也不注册 channel。
默认关闭:只有在项目工作区存在 .dsh-bus.json 且 enabled 为 true 时,该项目的会话才能使用总线工具。未启用项目的调用会得到「项目未启用」类提示,而不会静默生效。
核心功能¶
消息投递与唤醒¶
语义上与 openclaw session send 对齐,核心字段如下:
send({ from, to, kind, payload, replyTo?, deliveryMode? })
// to : session id | 注册名 | dsh-team 成员名 | "*"(广播)
// kind : text | request | response | event
// deliveryMode : steer(默认) | followup | notify
// payload : { text, data? }
// replyTo : kind=response 时指向原消息 id
当目标是当前进程中活着的 DSH 会话时,消息进入该会话自己的收件箱并触发唤醒,而不是仅写入数据库等待轮询。deliveryMode 与宿主调用的对应关系如下:
| deliveryMode | DSH 调用 | 行为 |
|---|---|---|
notify |
agent.inject(msg) |
只放入收件箱,不唤醒 |
steer(默认) |
agent.steer(msg) |
在运行中轮次的下一 step 边界注入并唤醒 |
followup |
agent.followup(msg) |
作为下一轮入队并唤醒 |
宿主对 agent.steer() 的实现会把消息直接追加到目标会话收件箱,不做父子会话邻接校验,因此多个平级独立会话可以任意互发,而不必建立 subagent 关系。
目标不在本进程(会话未打开)时,消息仍会持久化;目标再次打开后可通过 dsh_bus_inbox 读取。找不到目标会报 E_TARGET_NOT_FOUND,歧义目标会报 E_AMBIGUOUS_TARGET,不会无声丢信。
模型侧工具¶
README 列出的四个主要工具如下:
| 工具 | 作用 |
|---|---|
dsh_bus_send |
{ to, text, deliveryMode?, kind?, data?, replyTo? } 发信 |
dsh_bus_inbox |
读来信与未读数(markRead: true 可顺带标记已读) |
dsh_bus_agents |
列出当前活着、可被立即唤醒的会话及来源可用性 |
dsh_bus_reply |
按原消息自动回填收件人 |
推荐各会话在执行任务前调用 dsh_bus_register({ name: "..." }) 自注册可读名称,避免总线列表里只剩 uuid。
回复守护(reply guard)¶
仅在本轮对话里口头回答,发送方看不到。插件在宿主轮次边界上跟踪「因总线投递产生的回复债务」:若会话已处理来信却未调用 dsh_bus_send / dsh_bus_reply,会在 turn 结束前注入提醒并最多 nudge 两次;不会代答,也尽量不干扰普通人机对话轮次。
项目根解析¶
projectRoot 按每次调用、由调用方会话解析,不在插件装配时写死。优先级为:显式配置 projectRoot > 调用者会话的 cwd > 当前 initiator 的 cwd > 进程 cwd。这样长期运行的宿主里,多 workspace 并存时,A 项目会话不会误读 B 项目的 .dsh-bus.json。
安装与启用¶
安装插件¶
官方安装命令如下(来自仓库 README.zh.md):
dsh plugin add https://github.com/nevercanner/dsh-session-send
npm 12 默认 allow-git=none 时可能报 EALLOWGIT,可先调整配置或在安装时附带参数:
npm config set allow-git all
# 或:dsh plugin add ... --allow-git=all
安装阶段会执行 prepare(scripts/build.mjs),要求 Node >= 22.18.0(与 package.json 中 engines 一致)。当前包版本为 0.4.1。
安装完成后,插件代码以当前 DSH 进程权限运行。安装前宜浏览 GitHub 仓库 源码与 MIT 许可证条款,确认符合你的安全策略。
在项目中开启总线¶
无需手写完整配置。在左侧栏任意 Session 行的「…」菜单中,选择与会话总线相关的条目(菜单文案形如「会话总线:开启 dsh-session-send」)。点击后会在该会话所属工作区写入或更新 .dsh-bus.json,并热生效;再次点击可关闭(仅将 enabled 置为 false,不删除文件内其它字段)。
首次开启时写入的最小结构为:
{
"enabled": true,
"transport": { "kind": "sqlite" },
"scope": "project"
}
若已有损坏的配置,插件会拒绝覆盖并说明原因。
开关挂在 Session 行而非 Project 行,是因为当前 ui-workspace 的项目行菜单暂无扩展点,而 Session 行具备扩展槽;开关作用对象是该会话所在的项目。
还可按需扩展 transport、registry、router、labels、ui 等字段,默认值见 README 配置表(例如 registry.requireRegistration 默认为 true,未注册会话默认不可寻址)。
典型用法¶
多会话分工时,管线会话在章节就绪后可直接通知门禁,无需人工拷 prompt。英文 README 示例:
// in the "pipeline" session
dsh_bus_send({ to: "gate", text: "Chapter 3 is done — please review." })
中文版 README 用中文注册名描述类似链路:管线维护向跑章选手、门禁依次 dsh_bus_send。启用前各会话可先注册:
dsh_bus_register({ name: "pipeline" })
dsh_bus_register({ name: "gate" })
之后即可 dsh_bus_send({ to: "gate", text: "..." })。若需显式回链,使用 dsh_bus_reply({ replyTo: "...", text: "..." })。
适用场景与注意¶
适合:同一仓库/项目内多个平级 DSH 会话协作;需要 steer 或 followup 级别唤醒的自动化流水线;与 dsh-team 成员名寻址配合的多智能体编排。
不适合或需知悉:
- 默认关闭,忘记在 Session 菜单开启会导致工具报「项目未启用」。
- 这不是 OpenClaw 插件,不要指望通过
openclaw.json配置它。 - 广播需配置允许(
router.allowBroadcast默认true);payload 有字符上限(默认 20000)。 - 消息会持久化在项目的 transport(默认 sqlite)中,注意磁盘与隐私边界。
- 插件与宿主、Cordis 及多个
@deepseek-ai/dsh-*包存在 peer 依赖,版本需与当前 DSH 发行版匹配。
结尾¶
dsh-session-send 把「会话间发信 + 真唤醒」做成可按项目开关的 DSH 插件,减少多窗口人肉搬运提示词。查阅说明与 issue 见 GitHub;在 SkillHub 浏览条目见 nevercanner/dsh-session-send。