跨会话注册与寻址
实现外部 peer 的注册记录、进程身份检查和私有 inbox 发现。
This page has not been translated into English yet. The original Chinese version is shown below.
Cross-Session Protocol 让语音前端、转发进程或脚本作为外部 peer 加入 Qwen Code 的同机消息系统。当前契约是 schemaVersion 1、msgV 1;Node 程序可使用 @qwen-code/sdk/peer,PeerEndpoint.start() 与 close() 管理注册和清理。
这里介绍协议实现;交互操作见跨会话发现与审核。SDK peer 不自动替外部程序实现 Qwen Code 的限流、扣留和重复窗口,接收程序需要自行定义这些策略。
注册文件
目录为 $QWEN_HOME/sessions,QWEN_HOME 默认 ~/.qwen。目录权限 0700,文件权限 0600。文件名可为
文件名的 PID 前缀必须与记录中的 pid 按规范十进制一致;补零的文件名不匹配。记录包含:
| 字段 | 含义和校验重点 |
|---|---|
| schemaVersion | 当前 1;未知更高版本跳过且不删除 |
| pid | 写入者的进程 ID |
| procStart | Linux 为 boot ID 与进程启动 ticks,其他平台为 null |
| pidNs | Linux 的 PID namespace inode,其他平台为 null |
| sessionId | 当前会话 UUID,clear/resume 后可能改变 |
| cwd、name | 注册者自报的工作目录与显示名,不授予权限 |
| startedAt | 毫秒时间戳,列表按新到旧排序并用它区分重复记录 |
| qwenVersion | 自报版本文本或 null |
| kind | tui、headless、serve、external 等显示类别 |
| ipcPath | 已绑定的 inbox 地址;省略表示只能发现不能收消息 |
| ipcToken | 64 位十六进制连接令牌;旧记录可能没有 |
kind 只接受小写 ASCII 字母、数字和连字符,最多 16 字符,缺省兼容为 tui;不认识但形状合法的值可直接展示,不要自行纠正。
Linux 外部 peer 需要填写 pidNs,否则不会被同 namespace 的读取者列出或清扫。procStart 也应填写,否则只能退化为 PID 存活检查,无法判断 PID 重用。读取者还检查 boot ID 和启动 ticks;socket 文件存在不证明可连接。
写入与清理
在同一目录写临时文件,再 rename 到目标;新文件应为 0600,并拒绝通过符号链接写入。若裸 PID 文件已经存在,且不能证明它属于同 namespace、同次启动但不同 start ticks 的旧进程,应选择带随机后缀的文件,而不是覆盖它。
退出时删除自己的记录。读取者只在身份信息支持安全判断时清扫失效记录,不因未知版本、其他 namespace 或共享 home 中的陌生记录就删除文件。
能读取注册目录的进程也能读取其中的 token:发现和认证在此设计中是一项能力。不要把 ipcToken 输出给模型或写入普通日志。name、cwd、kind 都是自报信息,不能用来证明发信者身份或授权。
寻址和多会话进程
显示 ref 是 sha256(sessionId) 的前 6 个十六进制字符。地址可用 name、name [ref]、[ref] 或裸 ref;name 不唯一时直接报歧义,不猜测目标。默认 name 来自过滤后的工作目录基名,最多 32 个码点,再附加 sessionId 哈希前两位。
每个 ACP 子进程从首个会话起就为每个会话写带后缀记录,后缀在会话 ID 变化时仍不变。它们共享同一 inbox,通过帧里的 toSessionId 区分目标。每次发送前重新读记录并始终携带 toSessionId;缺失或不匹配可能得到 misaddressed。
当前 ACP 会话可发现和发送,但入站直接返回 refused;它们还没有承接人工 hold 队列的界面。协议能寻址不代表所有运行模式都接受消息。连接与帧格式见认证和消息帧。