WebSocket RPC
认证完成后,前端通过一条 WebSocket 持久连接 完成所有业务操作。RPC 共定义 17 个方法,分为 Action(操作类) 和 Query(查询类) 两种类型。
RPC 分类
Section titled “RPC 分类”| 对比 | Action RPC | Query RPC |
|---|---|---|
| 操作类型 | 创建 / 修改 / 删除 | 只读查询 |
| 响应包含 updates | ✅ 是 | ❌ 否 |
| 幂等支持 | ✅ client_id | — |
| 典型场景 | 发消息、关闭会话 | 加载消息列表 |
17 个方法按 4 个业务域 组织:
| 域 | Action | Query |
|---|---|---|
| Session | v1.session.open · v1.session.close · v1.session.update · v1.session.fork · v1.session.compact | v1.session.list · v1.session.get |
| Message | v1.message.send | v1.message.list · v1.message.get |
| Turn | v1.turn.stop | v1.turn.list · v1.turn.get |
| RTC | v1.rtc.update_status · v1.rtc.submit_result | v1.rtc.list · v1.rtc.get |
Session 域
Section titled “Session 域”会话是用户与 AI 对话的容器。每个会话包含多条消息和多个 Turn。
| 方法 | 类型 | 功能 | 关键参数 |
|---|---|---|---|
v1.session.list | 🔍 Query | 获取会话列表 | cursor(分页),limit(默认 20) |
v1.session.get | 🔍 Query | 获取单个会话 | session_id |
v1.session.open | ⚡ Action | 重新打开已关闭的会话(closed → idle) | session_id |
v1.session.close | ⚡ Action | 关闭会话 | session_id |
v1.session.update | ⚡ Action | 更新会话标题 / 软删除 | session_id,title,deleted_at |
v1.session.fork | ⚡ Action | 分叉对话(基于历史消息创建新会话) | old_server_session_id,new_client_session_id,new_client_message_id,old_server_message_id,content_data,limit(默认 200,最多 1000) |
v1.session.compact | ⚡ Action | 手动触发上下文压缩(不返回 updates) | session_id,custom_instruction |
Open 重新打开会话
Section titled “Open 重新打开会话”v1.session.open 用于重新打开已关闭的会话,将会话状态从 closed 切换回 idle,同时清除 closed_at 时间戳。
幂等行为:如果会话不是 closed 状态,直接返回 {success: true} 而不做任何修改。
请求:
{ "session_id": "uuid"}响应:
{ "result": { "success": true }, "updates": [{ "...session.updated 事件..." }]}💡 与 close 的关系:
v1.session.close将会话标记为closed并设置closed_at;v1.session.open则会话恢复为idle并清除closed_at。两者配合实现会话的”归档 / 恢复”功能。
Fork 分叉对话
Section titled “Fork 分叉对话”💡 Fork 的典型场景:用户想从历史对话的某个分叉点开始新的方向。指定旧消息位置,系统复制之前的上下文,用新消息替换指定位置之后的内容,并触发新的 AI 推理。
Fork 响应:返回 {session_id, turn_id, message_ids[]}。注意 turn_id 为空字符串——Turn 由后台 turn-agent 异步创建。
Message 域
Section titled “Message 域”消息是会话中的基本通信单元,支持多种内容类型。
| 方法 | 类型 | 功能 | 关键参数 |
|---|---|---|---|
v1.message.send | ⚡ Action | 发送消息(自动创建 session 和 turn) | content_data,client_session_id,client_id(必填),server_session_id(可选),agent_prompt(可选) |
v1.message.list | 🔍 Query | 获取消息列表 | session_id,cursor(global_offset 字符串形式),limit(默认 50) |
v1.message.get | 🔍 Query | 获取单条消息 | message_id |
消息发送流程
Section titled “消息发送流程”💡 自动创建:调用
v1.message.send时,如果server_session_id为空,服务端会自动创建新会话。这意味着”新建对话”和”发送消息”可以合并为一次调用。
💡 异步 Turn:
v1.message.send和v1.session.fork响应中的turn_id为空字符串——Turn 由后台 turn-agent 异步创建,不随请求同步返回。
| 类型 | 说明 | Data 结构 |
|---|---|---|
markdown | Markdown 文本 | 字符串 |
text | 纯文本 | 字符串 |
thinking | AI 推理过程 | 字符串 |
summary | 上下文摘要 | SummaryItem[] |
toolcall_input | 工具调用请求 | ToolCall 对象 |
toolcall_output | 工具调用结果 | ToolCall 对象 |
user_message | 用户消息(含场景注入) | UserMessageContent 对象 |
error | 结构化错误消息 | ErrorContent 对象 |
prompt | 系统提示词(持久化系统级指令) | PromptContent 对象 |
user_message 的 files 字段
Section titled “user_message 的 files 字段”user_message 类型的 content_data 支持 files 字段,用于随消息附带文件附件(图片、文本等)。files 为 FileAttachment 数组:
| 字段 | 类型 | 说明 |
|---|---|---|
fileid | string | 文件唯一标识(引用已上传的文件) |
mimetype | string | MIME 类型(如 image/png、text/plain) |
extra | object? | 可选扩展字段(如文件名、大小等) |
目前支持的文件类型:image/*(图片,通过视觉通道注入 LLM)和 text/*(文本,XML 包裹后追加到消息内容)。
ErrorContent 错误消息
Section titled “ErrorContent 错误消息”当 Turn 失败时,服务端会插入一条 error 类型的消息,前端可渲染为带重试按钮的错误提示。
{ "type": "error", "data": { "category": "network", "title": "连接超时", "message": "与 AI 模型的连接超时,请检查网络后重试", "retryable": true, "raw_error": "context deadline exceeded" }}| 字段 | 类型 | 说明 |
|---|---|---|
category | ErrorCategory | 错误分类,前端据此选择图标和样式 |
title | string | 简短错误标题 |
message | string | 详细描述(可包含建议操作) |
retryable | bool | 是否可重试,前端据此决定是否显示重试按钮 |
raw_error | string? | 原始错误信息(仅当服务端 debug.show_raw_errors 为 true 时包含) |
ErrorCategory 枚举:
| 分类 | 说明 | 典型场景 |
|---|---|---|
api | API 调用错误 | 模型返回错误、速率限制 |
context | 上下文相关 | 上下文超长、压缩失败 |
network | 网络错误 | 连接超时、DNS 失败 |
permission | 权限错误 | 认证失败、会话不属于当前用户 |
stream | 流式处理错误 | SSE 中断、stream 解析失败 |
system | 系统错误 | 内部异常、数据库错误 |
timeout | 超时错误 | 推理超时、工具执行超时 |
tool | 工具调用错误 | 工具不存在、参数校验失败 |
Turn 域
Section titled “Turn 域”Turn 代表一次完整的 AI 推理轮次——从用户发消息到 AI 完成响应。
| 方法 | 类型 | 功能 | 关键参数 |
|---|---|---|---|
v1.turn.stop | ⚡ Action | 停止当前 Turn(不返回 updates) | session_id |
v1.turn.list | 🔍 Query | 获取 Turn 列表 | session_id,cursor,limit(默认 50) |
v1.turn.get | 🔍 Query | 获取单个 Turn | turn_id |
| 状态 | 说明 |
|---|---|
pending | 等待开始 |
running | AI 正在推理 |
completed | 推理完成 |
failed | 推理失败 |
cancelled | 用户主动取消 |
interrupted | 被系统中断 |
merged | 与其他 Turn 合并 |
RTC(Remote Tool Calling)是 AI 调用前端工具的机制。前端通过 RTC 域的 RPC 上报工具执行状态和结果。
| 方法 | 类型 | 功能 | 关键参数 |
|---|---|---|---|
v1.rtc.update_status | ⚡ Action | 更新 RTC 执行状态 | rtc_id,status,client_id |
v1.rtc.submit_result | ⚡ Action | 提交工具执行结果 | rtc_id,success,result / error,client_id |
v1.rtc.list | 🔍 Query | 获取 RTC 列表 | session_id,cursor,limit(默认 50) |
v1.rtc.get | 🔍 Query | 获取单个 RTC | rtc_id |
RTC 状态流转
Section titled “RTC 状态流转”| 状态 | 说明 | 前端操作 |
|---|---|---|
pending | 等待前端接收 | 收到 RTC 事件 |
sent | 已送达前端 | 展示工具调用 UI |
executing | 正在执行 | 调用 update_status |
completed | 执行成功 | 调用 submit_result(success=true) |
failed | 执行失败 | 调用 submit_result(success=false) |
timeout | 执行超时 | 系统自动标记 |
rejected | 用户拒绝 | 用户点击拒绝 |
部分 Action RPC 支持 client_id 用于去重或所有权验证,但各方法行为不同:
| 方法 | client_id | 实际行为 |
|---|---|---|
message.send | ✅ 必填 | 重复 client_id 返回 client_id_conflict 错误 |
rtc.submit_result | ✅ 可选 | 终态 + 相同 client_id → 返回缓存结果(幂等);终态 + 不同 client_id → 返回已有数据 |
rtc.update_status | ✅ 可选 | 用于所有权验证 + 状态机转换检查,非简单去重 |
session.open | ❌ 无此字段 | 幂等基于 session 状态:非 closed 状态直接返回 success |
session.close | ✅ 可选 | 字段接受但不做去重 |
turn.stop | ✅ 可选 | 字段接受但不做去重 |
session.update | ❌ 无此字段 | — |
session.compact | ❌ 无此字段 | 使用内部队列去重(同一 session 不重复压缩) |
session.fork | ❌ 用 new_client_message_id | 作为新消息的 ClientID 存储,不做 fork 级去重 |
💡 设计说明:
client_id在不同方法中承担不同职责——有时是幂等键,有时是所有权标识,有时仅做记录。集成时应参考各方法的具体行为,不要假设统一的幂等语义。
Update 模型
Section titled “Update 模型”大部分 Action RPC 的响应包含 result 和 updates 两部分(session.compact 和 turn.stop 除外,它们的 updates 为空):
{ "result": { "...业务数据..." }, "updates": [ { "id": "update-uuid", "items": [ { "entity": "message", "action": "created", "entity_id": "msg-uuid" } ], "data_list": [{ "...实体完整数据..." }], "offset": 42 } ]}💡 前端收到 updates 后:直接更新本地状态(IndexedDB / 内存),保持与服务端一致。无需再发一次查询请求——这就是”操作即同步”的设计理念。
RPC 错误格式
Section titled “RPC 错误格式”RPC 错误使用与 HTTP 不同的结构化格式:
{ "code": "session.not_found", "message": "session xxx not found", "details": "optional additional info"}| 字段 | 类型 | 说明 |
|---|---|---|
code | string | 机器可读错误码,如 session.not_found、client_id_conflict、method_not_found |
message | string | 人类可读描述 |
details | any | 可选附加信息(仅部分错误包含) |
Message 排序
Section titled “Message 排序”消息模型包含两个排序字段:
| 字段 | 类型 | 说明 |
|---|---|---|
global_offset | uint32 | Session 内全局消息顺序,单调递增,用作 v1.message.list 的分页 cursor(以字符串形式传输) |
turn_offset | uint32 | Turn 内消息顺序 |
- 实时事件 — 了解 updates 背后的双频道推送机制
- Remote Tool Calling — 深入了解 RTC 工具调用的完整生命周期
- 协议总览 — 返回协议全景