@lpb-work/pi-seatalk-listener
v1.1.3
Published
SeaTalk listener for durable pi sessions
Readme
@lpb-work/pi-seatalk-listener
SeaTalk Gateway 到持久化 pi session 的本机监听器:
SeaTalk Gateway SSE/search → pi-seatalk-listener → pi-session-server → AgentSession → SeaTalk MCP监听器默认通过 Unix socket 连接同机的 pi-session-server。如果 Gateway 在本机、Pi 服务在 AIS,使用 SSH transport:
本机 SeaTalk Gateway → 本机 pi-seatalk-listener
↓ SSH Unix-socket forwarding
AIS pi-session-server → AgentSession → 模型/工具SSH 模式只在本机运行 Gateway 和监听器;AIS 只运行 pi-session-server。监听器不会在远端重新启动 Pi 进程,也不会暴露 TCP 端口。
前置服务
先启动 pi-session-server,它负责模型、工具、AgentSession 和 JSONL 会话文件:
PI_SESSION_SERVER_TOKEN='replace-with-a-long-random-token' \
npx pi-session-server \
--socket "$HOME/.pi/agent/session-server.sock" \
--cwd /absolute/path/to/project \
--builtin-tools再确认 SeaTalk Gateway 已登录并监听 6767,复制配置并修改白名单、token 和工作目录:
cp config.example.json config.json
npx pi-seatalk-listener --config config.json --dry-run
npx pi-seatalk-listener --config config.json只有以 /codex 开头且通过白名单的消息会触发 pi。普通消息按 SeaTalk 对话和发送者绑定一个持久化 session;监听器重启后会从绑定文件恢复。
支持的命令:
/codex session list
/codex session use <session_id>
/codex session new
/codex session current远端 AIS 部署
本方案要求本机和 AIS 使用同一份 pi-fork 代码版本。可以都在 main,也可以都在同一个包含本功能的提交;不要让本机 client 和 AIS server 跨越不兼容的协议版本。
1. AIS 启动 Pi server
先在 AIS 上确认 SSH 登录用户能运行 Node.js、能访问目标项目和模型认证文件。进入 AIS 上的 pi-fork 根目录构建:
cd /path/to/pi-fork
npm install --ignore-scripts
npm run build然后保持这个进程长期运行。--cwd、--agent-dir 和 --session-dir 都是 AIS 上的路径:
PI_SESSION_SERVER_TOKEN='replace-with-a-long-random-token' \
node packages/server/dist/coding-agent-cli.js \
--socket "$HOME/.pi/agent/session-server.sock" \
--cwd /path/on/ais/to/project \
--agent-dir "$HOME/.pi/agent" \
--session-dir "$HOME/.pi/agent/server-sessions" \
--builtin-tools建议使用 AIS 上的 systemd、supervisord 或其他进程管理器托管它。token 只需和本机监听器配置完全一致,不要写入仓库。
2. 验证 SSH 和远端 socket
在本机执行,ais 是 ~/.ssh/config 中的 Host 别名:
ssh -T -o BatchMode=yes -o ConnectTimeout=20 -o ClearAllForwardings=yes ais \
'test -S "$HOME/.pi/agent/session-server.sock" && echo PI_SESSION_SOCKET_OK'如果远端 socket 使用了具体路径,把命令中的路径替换成该路径。看到 PI_SESSION_SOCKET_OK 后再启动本机监听器。SSH 登录必须对监听器所在的进程账户免交互认证;需要跳板机时,把 ProxyJump 等配置写入本机 SSH 配置的 ais Host 中。
3. 配置本机 listener
在本机 packages/seatalk-listener/config.json 中设置以下字段;Gateway URL、白名单和 MCP 路径保持本机配置:
{
"piTransport": "ssh",
"piSshHost": "ais",
"piSshRemoteSocketPath": "/home/ais-user/.pi/agent/session-server.sock",
"piSshConnectTimeoutSec": 15,
"piSshServerAliveIntervalSec": 15,
"piSshServerAliveCountMax": 3,
"piToken": "replace-with-the-same-token",
"workingDirectory": "/path/on/ais/to/project"
}SSH 模式下,workingDirectory 是 AIS 上的绝对路径,piSshRemoteSocketPath 也是 AIS 上的绝对路径;piSocketPath 不参与连接。监听器自己的 sessionBindingsPath 和 messageSearchStatePath 仍然保存在本机。
在本机仓库根目录先构建,再验证配置:
cd /path/to/pi-fork
npm run build
node packages/seatalk-listener/dist/cli.js --config packages/seatalk-listener/config.json --dry-rundry-run 只校验并打印连接设置,不会发送消息。确认输出中的 piTransport 为 ssh、Host 和远端 socket 正确后,前台启动监听器:
node packages/seatalk-listener/dist/cli.js --config packages/seatalk-listener/config.json看到 listener started、piTransport 为 ssh、SeaTalk SSE connected 后,在 SeaTalk 中发送:
/codex session current
/codex 请只读列出当前项目的主要文件第一次普通消息会在 AIS 的 sessionDir 创建 JSONL session;本机绑定文件只保存 SeaTalk 对话到 session ID 的映射。
4. 长期运行
本机只托管 pi-seatalk-listener,AIS 只托管 pi-session-server。两边都应由进程管理器自动重启;SSH 连接断开时 listener 会退出,让进程管理器重新建立 SSH 转发。不要手动长期保留一个后台 ssh -L 进程,也不要让 listener 和 server 同时操作同一个 socket 的服务端进程。
常见故障:
| 现象 | 检查 |
| --- | --- |
| did not create the control socket | 在同一用户下执行 ssh ais,检查 SSH key、ProxyJump 和 host key。 |
| did not create the local socket | 检查 piSshRemoteSocketPath、远端 socket 权限和 pi-session-server 是否运行。 |
| token 或 handshake 失败 | 本机 piToken 与 AIS 启动 server 的 PI_SESSION_SERVER_TOKEN 必须逐字一致。 |
| session 创建失败 | workingDirectory 必须是 AIS 上存在且 server 账户可访问的目录;模型认证必须配置在 AIS 的 agentDir。 |
SSE 用于实时消息,/messages/search 每秒补读启动后的消息并和 SSE 通过 message_id 去重。群聊回复使用入站消息的 root_message_id 或顶层 message_id 作为 thread_id,私聊不发送 thread_id。
长期运行建议由 macOS launchd 或 Linux systemd 同时托管两个进程;监听器或 Pi 服务退出后由进程管理器重启,不在监听器内另起隐藏的 Agent 进程。
