Back to home@stark-L-1

dsh-peer-mailbox

DSH peer mailbox plugin v0.0.2 - inter-session communication via jsonl mailbox (peer_ask / peer_read_mailbox / peer_reply / peer_reset_limit)

Stars
1
Language
Created
Aug 21, 2026
Updated
Aug 21, 2026
GitHub repo

Introduction

@dsh-external/dsh-peer-mailbox

对话间信箱通信(toolkit + daemon-loop,host-only):让 DSH 的不同会话之间一问一答, 全程不切换会话、不互相占用(绕开 live 会话锁)、不落 skill 文件。

工作用途约束(防闲聊烧 token)

  • 工具描述标注:peer_ask / peer_reply / peer_read_mailbox 的描述均声明 「工作用通信通道,不是闲聊工具:只用于传达任务、问事、交付结果,不要寒暄、不回复问候/闲聊内容」。
  • 轮数上限(硬约束):同一「发送方→接收方」有向对在滑动时间窗口内最多 workLimitMax 条(默认 4,建议 3~5)。超限时 peer_ask/peer_reply 拒绝投递(不落盘), 返回 {ok:false, limited:true, reason:"已达通信轮数上限…"}
  • 自动重置:滑动窗口(默认 1 小时)——窗口过期旧消息自动不计入,无需手动清零; 也可由管理员调整 workLimitMax/workLimitWindowMs 配置。
  • 手动重置(管理员)peer_reset_limit(from, to, scope?)——给指定对(或 scope=all 整个目录)的 现有消息打 limit_reset 标记,统计时忽略它们,该对可立即继续投递、计数从 0 开始。 工具描述带醒目标注「管理员工具,除非接到明确命令否则不许使用」。
  • 计数与投递在同一 per-file 锁内原子完成(并发投递不会超发);不同 (from,to) 对独立计数。

工具

  • peer_ask(target, message, from?):向目标会话的信箱投递一条消息(只投递),返回 {ok,id,from,to,file};超限返回 {ok:false,limited:true,reason,…}
  • peer_read_mailbox(from?, mark_read?, who?):读当前会话信箱;mark_read 缺省 true = 只看未读并标记已读,false = 看全部不动标记。
  • peer_reply(target, reply_to, message, from?):回复某条消息(写 reply_to 字段),本质同 peer_ask(同样受轮数限制)。
  • peer_reset_limit(from, to, scope?)管理员工具,除非接到明确命令否则不许使用。重置指定「发送方→接收方」的轮数计数(scope=pair 默认 / scope=all 整个目录),返回 {ok,scope,from,to,reset_count}

唤醒层(daemon-loop)

  • 定时轮询 D:\dsh\peer-mailbox\mb-*.jsonl(默认 10s,下限 5s),发现目标会话有未读消息时:
    • 目标在 live registry(ctx.agents.get(id) 命中)→ agent.followup() 注入一条 {kind:'plugin', form:'relay'} 通知(与 dsh-chat-proxy 的注入方式一致),idle 司机开回合 / running 司机排队;
    • 目标不在 live registry → 本轮跳过(信箱本身即队列,下轮再试),绝不主动 attach/抢挂会话
  • peer_ask/peer_reply 投递后默认立即尝试一次唤醒(wakeOnAsk,低延迟路径);轮询 daemon 是兜底。
  • 已读不重复触发:peer_read_mailbox 标记 read: true 后不再通知;进程内 WakeState 记住已通知的消息 id, 同一条未读只投递一次通知(防 spam / 防死循环)。
  • 唤醒目标必须用真实会话 id(名字只用于信箱可读性);且目标会话需已挂 agent preset(否则模型回合可能因 {{cwd}} 等模板变量缺失或权限策略被拒——生产会话天然满足)。

配置(插件 config)

{
  mailboxDir?: string        // 默认 D:\dsh\peer-mailbox
  pollIntervalMs?: number    // 默认 10000,下限 5000
  wakeOnAsk?: boolean        // 默认 true:投递后立即尝试唤醒
  wakeEnabled?: boolean      // 默认 true:启用轮询 daemon
  wakePreviewChars?: number  // 默认 160:唤醒通知里的消息预览长度
  workLimitMax?: number      // 默认 4:每对(from→to)窗口内最大投递条数;<=0 不限制
  workLimitWindowMs?: number // 默认 3600000:滑动窗口 ms,窗口过期自动重置
}

构建与注入

bash scripts/build.sh                 # 需要 DSH_CHECKOUT(本机用合成 checkout C:\Users\86185\dsh-harness)
node scripts/test.mjs                 # 核心逻辑单测(21 项,含轮数限制与重置 9 项)
# 注入器环境内:dev_inject_plugin <本目录> → dev_reload_package dsh-peer-mailbox → dev_uninject_plugin dsh-peer-mailbox

消息格式(每信箱一个 jsonl,一行一条,UTF-8 无 BOM、原子写、进程内 per-file 锁)

{"id":"<uuid>","from":"<发送会话>","to":"<目标会话>","text":"...","ts":<时间戳>,"reply_to":"<可选>","read":true}

已知限制

  • 进程内 per-file 锁:同一 web 进程内并发写安全;跨进程(多 DSH 实例)不保证。
  • 唤醒通知只是"提醒",目标会话是否真的调用 peer_reply 取决于其模型行为(实测可闭环,但非 100% 确定性)。
  • 目标会话未挂载时只排队不唤醒(信箱即队列,挂载后下一轮轮询会补投递)。