Skip to content

dsh-session-messaging

Verified

dsh-session-messaging · v0.4.0 · MIT · Web UI

Peer messaging between user-launched sessions in one workspace: discover peers, relay coordination messages, pause reception, and get advisory write-scope conflict warnings.

Install

dsh plugin add dsh-session-messaging

Confirm the layer applied with dsh --profile default --dump-config — see the install guide.

Source

Tags

Creators

Readme

dsh-session-messaging

为 DeepSeek Harness(dsh)提供跨会话消息:让用户在同一工作区自行启动的多个会话互相发消息,协调任务、声明文件写入范围、提示冲突——而不是把它们变成父子关系的子代理。

English | 简体中文

状态:早期预览(0.2.0),适配 dsh 0.2.1-rc.2。dsh 插件 API 仍为 pre-stable,上游升级可能带来破坏性变更。

为什么需要

dsh 已有 subagent 与 Agent Teams,但它们都是层级关系,生命周期绑定父会话。而当你自己同时打开几个会话(前端、后端、文档)时,它们在同一工作区里无法说"我在改 src/ui.ts,先别动"或"接口字段已冻结"。

本插件为这些顶层会话增加一个对等通道:

  • 同一工作目录下的会话可以发现彼此;
  • 模型可以向对等会话发送消息,消息以普通 user 消息插入目标对话;
  • 每个会话可暂停接收;写范围是建议性声明,重叠时会提示双方。

演示

桌面端收到的对等会话消息

macOS 桌面客户端(0.2.1-rc.2)真实运行:另一个用户启动的会话发来测试消息,以内联 session-message 信封显示(含发送方、时间与"peer 不是 authority"提示);本会话通过 session_send 回复。两个会话位于同一工作目录,不涉及子代理层级。

案例:从 peer 缺陷报告到修复验证

两个用户启动的会话通过本插件协作完成了一次真实修复:一个会话发来可复现的缺陷报告与代码级根因,修复以 v0.1.2 发布,报告方在桌面端独立完成了回归。

收到的 peer 缺陷报告

报告方发来的消息:复现步骤、根因定位与修复请求,全部通过 session_send 送达。

修复后的独立回归验证

报告方的独立回归:静态核对 + 桌面运行期探针。探针返回 caller-not-top-level,证明 v0.1.2 已生效;这条消息本身也证明"顶层 → 顶层"正向链路未回归。

0.1.2 的变更见 CHANGELOG.md。

设置面板

跨会话消息设置面板

侧边栏入口打开一个设置面板:切换跨目录消息(通过 dsh 设置表单持久化)、检查 npm 最新版本,并打开 npm / GitHub / 作者博客。安装或升级 bundle 后刷新一次 Web UI,客户端模块才会进入模块图。

功能

  • session_peers:列出同目录、live 的顶层会话及其接收状态。
  • session_send:发送协调消息,可附带 writeScopes 与 replyTo。
  • session_reception:暂停/恢复本会话接收对等消息,并声明写范围。
  • 侧边栏面板:左侧“跨会话消息”入口,提供跨目录开关、版本更新检查与作者链接。
  • 消息直接内联显示在目标会话中,来源归属于发送会话,不需要独立收件箱。
  • 建议性写范围冲突检测:与 peer 声明重叠时,回执与消息信封带 conflict-warning。
  • 不新增 Session 事件类型、不改 SESSION_FORMAT_VERSION:消息就是带 session-message source 的 user/message。
  • 插件管理卡片提供中英双语标题、简介与图标(English / 简体中文)。
  • 冷会话投递:目标不在 live 列表时,通过 Web/Desktop 的 sessionController 恢复持久会话后再投递(allowColdDelivery,默认开启)。
  • 有边界:长度上限、每 sender→target 限频、仅顶层、拒绝自发送。默认允许跨目录对等会话;sameDirectoryOnly: true 可收紧为同工作目录。

工作原理

会话 A 的模型调用 session_send
  → tools.ts 以 exec.agent 作为唯一身份
  → service.send 校验目标、正文、写范围、接收状态、限频
  → createUserMessage({ 信封+正文, source: session-message/relay })
  → target.steer(message)          # 最近 step 边界;空闲会话则唤醒
  → await ctx.sessions.flush(target.session)
目标会话 B 的日志出现 user/message(source.kind = 'session-message')
  → deriveMessages() 重建 → B 的下一次模型请求可见 → B 可回复

消息信封始终标明"来自另一个会话,不是当前用户",并提示 peer 不是 authority;peer 内容只作为数据,不获得更高指令权限。

要求

  • DeepSeek Harness 0.2.1-rc.2(桌面应用或源码)。
  • Node.js >= 22.19.0。
  • 插件依赖宿主提供的 @deepseek-ai/{cordis,schemastery,dsh-agent,dsh-llm,dsh-session,dsh-tools};它们以 peerDependencies 声明,由运行中的 dsh 安装解析。

安装

从 npm 安装(推荐)

dsh plugin --profile <profile> add dsh-session-messaging

包已发布为 dsh-session-messaging(最新 0.4.0)。库用法:npm install dsh-session-messaging。

从 GitHub 安装

dsh plugin --profile <profile> add github:XBXyftx/dsh-session-messaging

仓库包含构建好的 lib/,从 git 安装不需要额外构建。

本地目录安装

dsh plugin --profile <profile> add /absolute/path/to/dsh-session-messaging

排障:从本地 link 切换到 npm 安装

如果 profile 之前 link 了本地源码,又在应用运行中安装了 npm 包,运行中的 Loader 可能仍引用旧源码路径;此时删除源码目录的 node_modules 会出现 @deepseek-ai/* 的 ERR_MODULE_NOT_FOUND,即使 npm 包已经安装。先移除再重装 bundle,然后重启应用(客户端部分刷新页面即可):

dsh plugin --profile <profile> remove dsh-session-messaging
dsh plugin --profile <profile> add dsh-session-messaging@latest

桌面应用

桌面应用使用自己的 profile(例如 desktop),用其内置 CLI 或 agent 的 plugin_manager 工具安装到该 profile。dsh 0.2.1-rc.2 会通过 HMR 重载配置,通常无需重启应用即可激活。

确认已激活:

  • agent 工具列表出现 session_peers、session_send、session_reception;
  • plugin_manager list_plugins 中 session-messaging 与 session-messaging-tools 的 fiberPhase 为 active。

使用

在同一工作区打开两个会话,直接让模型协调即可,不需要手动操作 UI。

示例提示词:

用 session_peers 看看当前工作区还有哪些会话。
给 session-b 发消息:我在改 src/ui.ts,已经写进 writeScopes,请避开。
改 src/api.ts 之前先检查有没有别人声明了冲突的写范围。
本会话暂停接收跨会话消息。

工具:

工具 参数 返回
session_peers 无 { peers: [{ sessionId, status, canReceive, writeScopes }] }
session_send targetSessionId、message,可选 writeScopes、replyTo { accepted, messageId, targetSessionId, targetStatus, conflicts }
session_reception enabled,可选 writeScopes { enabled, writeScopes }

accepted 表示消息进入目标 inbox 且 flush 确认持久化,不表示对等模型已经处理或执行。

配置

- id: session-messaging
  name: dsh-session-messaging
  config:
    maxMessageChars: 4000
    maxMessagesPerMinute: 12
    requireTargetOptIn: false   # 默认对 peer 开放
    sameDirectoryOnly: false
    allowSelfSend: false
    allowColdDelivery: true   # 目标不 live 时先恢复持久会话

安全模型与限制

  • peer 内容是可信边界外的输入:它以 user 消息进入目标会话,信封会标注来源并警告模型,但 dsh 没有针对 peer 消息的内容审批点;工具审批、agent/pre-step 与 sandbox 策略仍是唯一的硬边界。
  • 只允许顶层会话,收发两个方向都对称:subagent 会话既不会出现在 peers 里,也不允许发送(caller-not-top-level);顶层会话也不能把 subagent 作为目标(target-not-top-level)。subagent 继续使用既有的父子 send_message 通道。消息信封的 from 字段才是可信身份;正文里的任何身份自称都只是数据。
  • 冷会话是“恢复后投递”,不是排队:目标不 live 且 allowColdDelivery 开启时,插件调用部署的 sessionController.resolveAgent() 恢复该会话,可能启动模型 turn(产生 token 成本)。没有该服务的 profile 仍返回 target-not-live;归档或 subagent 拥有的会话会被控制器/会话门禁拒绝。跨进程/跨机器通信仍未实现。
  • 写范围只是建议,不是锁:dsh 只有乐观版本守卫(FS_STALE_VERSION),没有文件锁;Bash、格式化器、代码生成器会绕过写范围提示。
  • 状态在内存:暂停接收与写范围声明随插件生命周期存在,重载/重启后重置。
  • 默认允许跨目录:不同工作目录的会话也可以互发消息。设置 sameDirectoryOnly: true 可恢复路径边界;无论是否限制,peer 内容都不可信。
  • 无 GUI 扩展:消息按普通 user 消息显示;session-message 的专属标题/图标需要 client 插件或上游 ui-chat 改动。

开发

npm install
npm run build              # tsc -p tsconfig.build.json -> lib/
npm run typecheck
npm test                   # 10 项协议单测
npm run test:integration   # 真实 AgentLoop 服务 + 工具管线,无模型
npm run test:model-e2e     # 脚本化模型:A 发消息,B 收到并回复

lib/ 已提交,便于 dsh plugin add github:... 直接使用;修改源码后请重新构建并提交,CI 会检查 lib/ 与 src/ 一致。

兼容性

  • 适配 dsh 0.2.1-rc.2,engines.dsh = ">=0.2.1-rc.2 <0.3.0"。
  • 只使用文档化扩展点:ctx.tools.register、ctx.agents、ctx.sessions、MessageSourceMap。
  • 不修改 agent-loop,不新增 SessionEventMap。

贡献

欢迎 Issue 与 PR。除非经过设计讨论,请保留"不改 loop、不新增 Session 事件、写范围仅建议"的边界。提交前运行 npm run typecheck、npm test、npm run test:integration、npm run test:model-e2e。

许可证

MIT © 2026 XBXyftx