dsh-peer-sessions:让两个同级 DSH 会话在用户授权下互相对话

前言

在 DeepSeek Harness(DSH)里,你往往会开多个长期会话——例如一个盯后端 API、一个盯前端客户端。改契约、等对方改完、再确认,如果全靠人复制粘贴或反复切换窗口,成本高,也容易漏。

DSH 里已有基于「父拥有子」(isOwnedBy)的 send_message / list_agents,适合 subagent 场景:一方结束,另一方通常也该停。若两个会话都归你指挥、谁也不比谁高一级,且希望各自还能独立继续工作,就需要另一种机制。

下面介绍社区插件 dsh-peer-sessions(维护者 OwlNjust,仓库 OwlNjust/dsh-peer-sessions)。它在同层级会话之间建立对称、由用户授权的通道,让两个你自己驱动的会话互发消息,没有上级,也没有下级。

这是什么

插件当前版本为 1.3.0(MIT 许可证),要求 Node ≥ 20、dsh ≥ 0.2.0-0;持久化授权等功能需要 dsh ≥ 0.2.1(更老宿主仍可工作,但授权退回进程内寿命并打警告)。

典型用法是两个长期会话——比如 /srv/orders-api 与 /srv/web-client——一方改 API 契约就通知另一方,另一方改完再回复。这与 subagent 的分界线在 README 里写得很直白:

一方结束就意味着另一方也该停 —— 那是 subagent。
两者可以各自独立地活下去 —— 那才是 peer。

插件不声明客户端代码:命令走现有聊天 UI,授权走 user-questions UI,消息来源走 form: 'relay' 渲染。

硬规则:可见性

agent 能对话的列表,必须是人在侧栏能看到的列表的子集;不能对着人类看不见的会话说话。

可寻址集合来自侧栏可见性规则(dsh-client-ui-workspace 中的 sessionVisible),实现细节以 lib/addressable.js 的 classify 为准。排除项包括:子代理来源(origin === 'subagent')、已归档、空白占位会话。每次投递都会重新读列表,归档对端会立刻切断可达性。

核心功能

用户命令

命令 作用
/peers 列出通道:对端、授权档位、剩余额度、对端可见性
/peer connect <标题> [once\|session] 建立通道;档位选择走原生选项卡片
/peer revoke <标题> 断开通道
/peer progress <标题> 查看对端进度

模型工具

工具 作用
peer_send 发消息;无授权时弹出授权卡片
peer_inbox 读收件箱:摘要列表,或按 id 取完整正文
peer_progress 读对端投影与摘要
peer_list 查看通道与权限

环路防护与等待方式

两个会话互相回复可能无限持续,因此在投递之前判定上限;被拒绝的投递不消耗额度、也不推进链条。默认值(均可通过配置覆盖)包括:

防护 默认 说明
每对速率 30 条 / 60 秒 按通道计的固定窗口
每对总量 200 条 单通道一生投递总量(once 档为 1)
跳数 3 跳 因果链跨会话接力转发的深度
请求超时 replyWithin 到点通知发起方一次,不自动重发

投递在两个方向上都「空闲才投递」:你的消息不打断对端当前回合;对端回信也不打断你的当前回合,而是新开回合。因此 agent 不应为等对端而 sleep、轮询或挂 wait_agent;应结束回合等待唤醒,或在本回合用 peer_inbox 主动拉取已送达内容。

长任务期间同一会话可能连发多条;未读排队消息会合并为一批(每条仍带 sent 时间戳),收件箱仍按消息 id 分别存储。完整行为见仓库 README.zh.md。

数据与持久化(v1.3.0)

授权写入批准方会话日志(插件记录类型 plugin:dsh-peer-sessions/channel),重启 dsh 后通道仍在,直到 /peer revoke。收件箱、速率窗口等「在途」状态仍在进程内存;peer_inbox 可取回正文的边界是宿主进程生命周期。授权记在批准方一侧,对端重启后若先发话,会再次向其人请求授权。

安装与启用

插件以 dsh 进程的权限运行;安装前请自行审阅源码与 MIT 许可证。社区目录 SkillHub 条目与 GitHub 无 DeepSeek / 幻方官方从属关系,DSH 生态本身是「一切皆插件」思路。

两条安装路线只能选一条;重复安装不会报错,但组合层可能静默遮蔽一行配置,导致部分设置不生效。

路线 A:组合包(插件管理器)

本包声明了 dsh.bundle,dsh 0.2.0+ 插件管理器可将其作为组合层安装,一般无需手改 profile 文件。

桌面端:打开「管理插件」,填写仓库地址或 npm 包名。

CLI(desktop profile 除外——官方不对其做 CLI 插件管理):

dsh plugin --profile <profile> add <仓库地址或包名>

桌面端安装的是 git 快照,发版后需在管理器里更新。

路线 B:本地目录 + install.sh

在插件源码目录执行:

./install.sh

脚本会:链 node_modules 到宿主实际部署、添加 profile 依赖(link: 路径)、按需追加 cordis.patch.yml 的 insert 行、复制(非软链)技能到 ~/.dsh/skills/peer-session/。可通过环境变量 DSH_PROFILE(默认 web)、DSH_HOME(默认 ~/.dsh)指定目标。

安装完成后必须重启对应 profile,用 /peers 验证。

卸载可执行 ./uninstall.sh,同样需重启 profile。细节见 README 卸载一节。

典型用法

1、在两个你已打开的同级会话中,在批准方会话输入 /peer connect <对端标题> session(或 once),在选项卡片上确认授权档位。

2、在任一侧用 /peers 或让模型调用 peer_list 查看通道与剩余额度。

3、需要通知对端时,让模型调用 peer_send;无授权时会弹出 consent 卡片。

4、在本回合仍需继续其他工作时,用 peer_inbox 拉取已送达回复,而不是阻塞等待。

5、查看对端工作状态时,使用 /peer progress <标题> 或 peer_progress。

6、不再需要互通时,执行 /peer revoke <标题>。

配置

在 profile 组合行中为插件 id dsh-peer-sessions 设置 config。示例(数值为文档中的示例,非全部默认值):

- id: dsh-peer-sessions
  name: dsh-peer-sessions
  config:
    hopLimit: 5
    rateLimit: 60
    rateWindowMs: 60000
    channelBudget: 500
    inboxLimit: 100
    requestMemory: 1000
    pendingGraceMs: 86400000
    hopMemoryMs: 900000
    maxCandidates: 8
    recentTurns: 3
    previewMaxChars: 200

注意:config 在组合层是整体替换,多层覆盖时靠后的对象整块胜出;完全省略 config 则使用 schema 默认值(与 README 配置表一致)。校验失败的插件可能只在启动时警告而静默不加载。

适用场景与注意

适合:多仓库、多服务并行开发,两个长期会话需要协商接口或同步进度,且你希望关系是对等的 peer,而不是 subagent 父子任务。

不适合:需要严格「子任务结束即父任务收敛」的一次性委派——应继续用 subagent 与现有 send_message 体系。

动手改代码或排查接线问题前,仓库 MAINTENANCE.md 记录了四条不变量与常见陷阱;行为规格以 docs/design.md 为准。

结尾

dsh-peer-sessions 补的是 DSH 里「同级会话、用户授权、对称互通」这一层:在侧栏可见性约束下,用命令与 peer_* 工具让两个会话协作,并用速率、总量、跳数与 replyWithin 控制环路风险。

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

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

Xiaoye