dsh-peer-mailbox
其他 活跃维护

dsh-peer-mailbox

stark-L-1/dsh-peer-mailbox

JSONL格式实现跨会话通信的轻量级插件,内置peer_ask、peer_read_mailbox、peer_reply、peer_reset_limit四类核心接口,无需额外依赖即可完成会话间消息收发、回复与额度重置操作,接入简单易用。

1
Stars 标星
0
Forks 分支
1
Watchers 关注
0
Open Issues
Other
主要语言
None
开源协议
19 KB
仓库大小
1 个月前
最后推送
一键安装扩展 / 插件指令
dsh plugin --profile web add github:stark-L-1/dsh-peer-mailbox
git clone https://github.com/stark-L-1/dsh-peer-mailbox.git
git clone git@github.com:stark-L-1/dsh-peer-mailbox.git
README.md master

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