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
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/抢挂会话。
- 目标在 live registry(
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% 确定性)。
- 目标会话未挂载时只排队不唤醒(信箱即队列,挂载后下一轮轮询会补投递)。