Appearance
Demo:远程会话(server ⇄ client)
工程化复现第四部分的远程会话:握手 → 建会话 → 命令 → 事件推送。源码在 pi-principles/src/transport/,入口在 pi-principles/play/transport.ts。
工程化结构
text
pi-principles/src/transport/
├── pipe.ts # 内存双工管道(真实场景是 TCP/Unix socket)
├── server.ts # 会话服务端:持有 MiniAgent,握手 + 路由命令 + 广播事件
└── client.ts # 会话客户端:握手 + 发命令 + 维护各会话转录依赖自底向上:transport 依赖 protocol/framing.ts(定帧)+ protocol/schema.ts(消息类型)—— 和真实 pi 的依赖方向一致。
关键实现
管道(pipe.ts)
ts
export interface Endpoint { send(bytes): void; onFrame(cb): void }
export function makePipe(): { a: Endpoint; b: Endpoint };
// a.send 的数据被 b.onFrame 收到,反之亦然服务端(server.ts)
createSessionServer({ streamFn, tools, systemPrompt }) 持有 MiniAgent 会话:
ts
const server = createSessionServer({ streamFn, tools: [calculatorTool] });
server.accept(pipeA); // 接受连接:握手 + 分发命令
// 内部核心:订阅 Agent 事件 → 每次变化都广播 session_snapshot(快照模式)
agent.subscribe(() => broadcastSession(...));命令路由(对应 schema.ts 的 ClientCommand):create 建会话、prompt 提问、steer 插话、list 列会话。
客户端(client.ts)
createSessionClient(conn) 连接后自动握手,维护各会话转录:
ts
const client = createSessionClient(pipeB);
await client.connect(); // 握手
const handle = await client.createSession(); // 建会话
await client.prompt(handle.id, "请计算 1 + 2");
handle.transcript; // 由服务端快照累积
client.subscribe((event) => { ... }); // 订阅事件入口与运行
play/transport.ts 把 server 挂在管道一侧、client 挂在另一侧,跑通完整协议流:
bash
cd pi-principles
bun play/transport.ts # 或 npm run transport输出(注意事件是主动推送的 session_snapshot):
—— 握手 ——
客户端:握手成功
—— 建会话 + 提问 ——
客户端:收到事件 → session_created
客户端:会话已创建 203edbd1
客户端:收到事件 → session_snapshot(1 条消息)
客户端:收到事件 → session_snapshot(2 条消息)
...(模型/工具每步都推一次快照)
—— 最终转录 ——
[user] "请计算 1 + 2"
[assistant] [{"type":"toolCall",...}]
[toolResult] [{"type":"text","text":"3"}]
[assistant] [{"type":"text","text":"答案:3"}]全打通:play/app.ts
进阶:play/app.ts 把 server ⇄ client ⇄ tui 全部打通 —— 服务端持有 Agent,客户端经协议接收转录,TUI 用差分渲染实时画出会话内容:
bash
bun play/app.ts "请计算 3 + 4" # 有 .env 走真实 OpenAI,否则离线假模型对应到真实源码
| 工程化 Demo | 真实 pi 源码 |
|---|---|
transport/server.ts | packages/server/src/server.ts + sessions.ts |
transport/client.ts | packages/client/src/client.ts |
transport/pipe.ts | packages/client/src/transports/(TCP/Unix) |
protocol/schema.ts | packages/protocol/src/schemas.ts |
理解要点
- 握手是强制第一帧:
hello→hello_ok(带快照)。 - 请求用
id配对,事件是主动推送(不等请求)。 - 快照模式:服务端每次 Agent 事件都推完整转录,客户端累积成
transcript(对应 pi 的"快照权威 + 增量优化")。 - 真实场景用 CBOR + typebox 校验,这里用 JSON 演示交互流程。
下一步:5.1 TUI 与差分渲染。