跳转到内容

WebSocket RPC

认证完成后,前端通过一条 WebSocket 持久连接 完成所有业务操作。RPC 共定义 17 个方法,分为 Action(操作类) 和 Query(查询类) 两种类型。

对比Action RPCQuery RPC
操作类型创建 / 修改 / 删除只读查询
响应包含 updates✅ 是❌ 否
幂等支持✅ client_id—
典型场景发消息、关闭会话加载消息列表

17 个方法按 4 个业务域 组织:

域ActionQuery
Sessionv1.session.open · v1.session.close · v1.session.update · v1.session.fork · v1.session.compactv1.session.list · v1.session.get
Messagev1.message.sendv1.message.list · v1.message.get
Turnv1.turn.stopv1.turn.list · v1.turn.get
RTCv1.rtc.update_status · v1.rtc.submit_resultv1.rtc.list · v1.rtc.get

会话是用户与 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

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 的典型场景:用户想从历史对话的某个分叉点开始新的方向。指定旧消息位置,系统复制之前的上下文,用新消息替换指定位置之后的内容,并触发新的 AI 推理。

Fork 响应:返回 {session_id, turn_id, message_ids[]}。注意 turn_id 为空字符串——Turn 由后台 turn-agent 异步创建。


消息是会话中的基本通信单元,支持多种内容类型。

方法类型功能关键参数
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

💡 自动创建:调用 v1.message.send 时,如果 server_session_id 为空,服务端会自动创建新会话。这意味着”新建对话”和”发送消息”可以合并为一次调用。

💡 异步 Turn:v1.message.send 和 v1.session.fork 响应中的 turn_id 为空字符串——Turn 由后台 turn-agent 异步创建,不随请求同步返回。

类型说明Data 结构
markdownMarkdown 文本字符串
text纯文本字符串
thinkingAI 推理过程字符串
summary上下文摘要SummaryItem[]
toolcall_input工具调用请求ToolCall 对象
toolcall_output工具调用结果ToolCall 对象
user_message用户消息(含场景注入)UserMessageContent 对象
error结构化错误消息ErrorContent 对象
prompt系统提示词(持久化系统级指令)PromptContent 对象

user_message 类型的 content_data 支持 files 字段,用于随消息附带文件附件(图片、文本等)。files 为 FileAttachment 数组:

字段类型说明
fileidstring文件唯一标识(引用已上传的文件)
mimetypestringMIME 类型(如 image/png、text/plain)
extraobject?可选扩展字段(如文件名、大小等)

目前支持的文件类型:image/*(图片,通过视觉通道注入 LLM)和 text/*(文本,XML 包裹后追加到消息内容)。

当 Turn 失败时,服务端会插入一条 error 类型的消息,前端可渲染为带重试按钮的错误提示。

{
"type": "error",
"data": {
"category": "network",
"title": "连接超时",
"message": "与 AI 模型的连接超时,请检查网络后重试",
"retryable": true,
"raw_error": "context deadline exceeded"
}
}
字段类型说明
categoryErrorCategory错误分类,前端据此选择图标和样式
titlestring简短错误标题
messagestring详细描述(可包含建议操作)
retryablebool是否可重试,前端据此决定是否显示重试按钮
raw_errorstring?原始错误信息(仅当服务端 debug.show_raw_errors 为 true 时包含)

ErrorCategory 枚举:

分类说明典型场景
apiAPI 调用错误模型返回错误、速率限制
context上下文相关上下文超长、压缩失败
network网络错误连接超时、DNS 失败
permission权限错误认证失败、会话不属于当前用户
stream流式处理错误SSE 中断、stream 解析失败
system系统错误内部异常、数据库错误
timeout超时错误推理超时、工具执行超时
tool工具调用错误工具不存在、参数校验失败

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获取单个 Turnturn_id
状态说明
pending等待开始
runningAI 正在推理
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获取单个 RTCrtc_id
状态说明前端操作
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 在不同方法中承担不同职责——有时是幂等键,有时是所有权标识,有时仅做记录。集成时应参考各方法的具体行为,不要假设统一的幂等语义。


大部分 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 错误使用与 HTTP 不同的结构化格式:

{
"code": "session.not_found",
"message": "session xxx not found",
"details": "optional additional info"
}
字段类型说明
codestring机器可读错误码,如 session.not_found、client_id_conflict、method_not_found
messagestring人类可读描述
detailsany可选附加信息(仅部分错误包含)

消息模型包含两个排序字段:

字段类型说明
global_offsetuint32Session 内全局消息顺序,单调递增,用作 v1.message.list 的分页 cursor(以字符串形式传输)
turn_offsetuint32Turn 内消息顺序