3.5 KiB
3.5 KiB
Rust api-server SSE 基础设施设计(2026-04-22)
日期:2026-04-22
1. 文档目的
这份文档用于冻结 server-rs/crates/api-server 内部的 SSE 基础设施抽取口径。
本轮目标只有一个:
- 把当前散落在业务 handler 中的
text/event-stream响应头与事件文本编码逻辑,收口为api-server可复用的 Rust 基础设施。
本轮不做:
- 不改前端消费协议
- 不把 custom world message stream 改成真实逐段 token streaming
- 不引入跨 crate 的共享
shared-contractsSSE runtime helper - 不同时重构 story / runtime / txt mode 的未来流式接口
2. 当前问题
当前 Rust 侧 SSE 能力只在一个地方手写:
server-rs/crates/api-server/src/custom_world.rs
当前实现存在以下问题:
append_sse_event(...)与build_event_stream_response(...)直接写在业务文件里- SSE 响应头、事件编码规则没有统一入口
- 后续如果再新增第二条 Rust SSE 路由,极容易复制一份近似实现
- 业务层和传输层耦合在一起,不利于测试
3. 抽取边界
本轮只抽以下基础能力:
- 标准 SSE 响应头构造
- 单条事件编码
- 缓冲式 SSE body builder
- 一次性返回完整 SSE 文本的响应构造
本轮明确不抽:
reply_delta / session / done / error这些业务事件名- 事件发送顺序
- custom world session 的查询与回复文本推导
- 业务错误到 SSE
error事件的映射策略
原因固定如下:
- 这些内容属于业务协议,而不是通用传输设施
- 当前不同链路未来很可能有不同事件集合
- 先把传输层抽干净,后续真实流式能力才能稳定复用
4. 基础设施 API 口径
本轮在 server-rs/crates/api-server/src/sse.rs 提供:
SseEventBuffer- 面向当前最小兼容场景
- 内部持有
String - 提供
push_json(event, payload)与into_response()
build_sse_response(body)- 统一写入标准 SSE 响应头
encode_sse_event(body, event, payload)- 只负责把事件编码为:
event: xxx data: {...}
5. 标准响应头
所有通过本基础设施输出的 SSE 响应,统一包含:
Content-Type: text/event-stream; charset=utf-8Cache-Control: no-cacheX-Accel-Buffering: no
当前不默认加入:
Connection: keep-alive
原因:
- 当前 Rust
axum一次性 body 返回场景不依赖显式设置该头 - 保持最小必要头集合,避免提前固化未来长连接策略
6. 与 custom world message stream 的关系
POST /api/runtime/custom-world/agent/sessions/:sessionId/messages/stream 仍然保持 Stage 8 文档冻结的最小语义:
- 业务层先完成 deterministic 写表
- 读取最新 session snapshot
- 组装
reply_delta - 组装
session - 组装
done - 一次性返回完整 SSE 文本
本轮变化只在于:
- 事件编码和响应头不再手写在
custom_world.rs - 改由
sse.rs基础设施承接
7. 验收标准
当以下条件满足时,本轮视为完成:
api-server/src/sse.rs已提供可复用 SSE helpercustom_world.rs不再内联维护 SSE 编码与响应头细节cargo fmt -p api-server通过cargo check -p api-server通过npm run check:encoding通过
8. 一句话结论
本轮把 Rust api-server 里的 SSE 能力收口为“最小传输层基础设施”,统一事件编码与响应头,但不改业务事件协议和当前 custom world 的同步伪流式语义。