refactor: 0.1.0-beta

This commit is contained in:
leokun
2026-08-13 22:01:11 +08:00
parent a3ec2a0dfc
commit 3e7a15017d
401 changed files with 8696 additions and 182189 deletions
+654
View File
@@ -0,0 +1,654 @@
# Agent Bidi / RunSSE 协议消息参考
本文描述 Agent Bidi / RunSSE 链路中的消息功能、字段语义和消息之间的关联关系。
本文是协议参考,不描述服务端或客户端的内部实现。字段定义以当前 `internal/backend/cursor/proto/agent_v1.proto``internal/backend/cursor/proto/aiserver_v1.proto` 为准。
范围包括 BidiAppend / RunSSE 传输封装、`AgentClientMessage` 的全部顶层分支、`AgentServerMessage` 的全部顶层分支,以及这些分支直接关联的主要请求、响应和控制消息。工具专属的 Args / Result 类型按功能归类,不展开为具体执行流程。
## 1. 协议概览
该协议将一次 Agent 通信拆成两条方向相反的通道:
- `BidiAppend`:客户端向服务端追加消息。
- `RunSSE`:服务端持续向客户端返回消息。
两条通道通过同一个 `request_id` 关联。
```text
客户端 服务端
| |
| BidiAppend(request_id, append_seqno, data)|
|------------------------------------------>|
| |
| RunSSE(request_id) |
|------------------------------------------>|
| |
| stream AgentServerMessage |
|<------------------------------------------|
```
### 1.1 主要关联标识
| 标识 | 范围 | 功能 |
| --- | --- | --- |
| `conversation_id` | 会话 | 标识一个可持续多轮的 Agent 会话。 |
| `request_id` | 请求流 | 关联 BidiAppend、RunSSE 和一次活跃请求。 |
| `run_id` | 运行 | 独立标识一次 Agent Run;不得假定它与 `request_id` 等值。 |
| `message_id` | 用户消息 | 标识一条用户输入。 |
| `model_call_id` | 模型调用 | 标识一次具体的模型调用或 provider pass。 |
| `call_id` / `tool_call_id` | 工具调用 | 标识模型发起的一次工具调用。 |
| `id` | 桥接消息 | 关联 Exec、Interaction 或 KV 的请求和响应。 |
| `exec_id` | 客户端执行 | 标识一次客户端执行任务,可跨多个流式消息。 |
| `append_seqno` | Bidi 请求流 | 表示同一 `request_id` 下客户端上行消息的顺序。 |
### 1.2 Connect 流式帧封装
RunSSE 中的每条消息都位于 Connect 流式帧中。帧由固定 5 字节帧头和消息载荷组成:
| 部分 | 长度 | 功能 |
| --- | --- | --- |
| `flags` | 1 字节 | 描述压缩和流结束状态。 |
| `length` | 4 字节 | 使用大端序表示后续载荷的字节数,不包含 5 字节帧头。 |
| `payload` | `length` 字节 | 普通帧中是 protobuf 消息;流结束帧中是结束状态。 |
`flags` 属于 Connect 传输层,不是 `AgentServerMessage` 或其他 protobuf 消息的字段。当前使用的标志位为:
| 标志 | 含义 |
| --- | --- |
| `0x00` | 普通、未压缩的数据帧。 |
| `0x01` | 压缩的数据帧,载荷需要按照流声明的压缩算法解压后再解析。 |
| `0x02` | 流结束帧,载荷表示 EndStream 状态,不应按业务 protobuf 消息解析。 |
这些值按 bit 表达:最低位 `0x01` 表示压缩,次低位 `0x02` 表示流结束,其余 bit 为保留位。因此,判断帧类型时应读取标志位,而不是把 `flags` 当作 protobuf 枚举。
例如下面的 RunSSE 帧:
```json
{
"kind": "interaction_update",
"messageType": "agent.v1.AgentServerMessage",
"flags": "0x00",
"length": 4,
"compressed": false,
"endStream": false,
"message": {
"interaction_update": {
"heartbeat": {}
}
}
}
```
它表示载荷是一个长度为 4 字节、未压缩且尚未结束流的 `AgentServerMessage``heartbeat` 消息很小,使用 `0x00` 是正常情况;较大的业务消息可能使用 `0x01`
## 2. BidiAppend 传输消息
### 2.1 `BidiAppendRequest`
功能:向指定请求流追加一条客户端消息。
| 字段 | 类型 | 功能 |
| --- | --- | --- |
| `data` | `string` | 十六进制编码的 `AgentClientMessage` protobuf 数据。 |
| `request_id` | `BidiRequestId` | 指定消息所属的请求流。 |
| `append_seqno` | `int64` | 指定消息在当前请求流中的追加顺序。 |
| `data_binary` | `bytes` | 二进制形式的消息载荷。 |
约束:
- `data``data_binary` 表达的是消息载荷,不应同时承载语义不同的消息。
- `append_seqno` 只在同一个 `request_id` 内比较。
- 解码后的根消息必须是 `AgentClientMessage`
### 2.2 `BidiAppendResponse`
功能:确认本次 append 请求已经被接收。
该消息没有业务字段。它只确认 unary 请求本身,不代表 Agent Run 已经完成。
### 2.3 `BidiRequestId`
| 字段 | 类型 | 功能 |
| --- | --- | --- |
| `request_id` | `string` | 标识 BidiAppend 与 RunSSE 共享的请求流。 |
## 3. 客户端上行根消息
### 3.1 `AgentClientMessage`
功能:封装一条客户端到服务端的 Agent 消息。
`message``oneof`,一条消息只能选择以下一个分支:
| 分支 | 消息类型 | 功能 |
| --- | --- | --- |
| `run_request` | `AgentRunRequest` | 启动或恢复一次 Agent Run。 |
| `exec_client_message` | `ExecClientMessage` | 返回客户端工具执行的数据或结果。 |
| `kv_client_message` | `KvClientMessage` | 返回 blob 读取或写入结果。 |
| `conversation_action` | `ConversationAction` | 追加会话动作,例如继续、取消或执行计划。 |
| `exec_client_control_message` | `ExecClientControlMessage` | 返回客户端执行通道的控制事件。 |
| `interaction_response` | `InteractionResponse` | 回答服务端发起的用户交互请求。 |
| `client_heartbeat` | `ClientHeartbeat` | 表示客户端连接仍然活跃。 |
| `prewarm_request` | `PrewarmRequest` | 提前准备会话、模型和上下文。 |
## 4. `AgentRunRequest`
功能:携带启动或恢复 Agent Run 所需的会话状态、动作、模型与能力信息。
### 4.1 核心字段
| 字段 | 类型 | 功能 |
| --- | --- | --- |
| `conversation_state` | `ConversationStateStructure` | 客户端掌握的会话 checkpoint。 |
| `action` | `ConversationAction` | 本次 Run 要执行的会话动作。 |
| `model_details` | `ModelDetails` | 旧式或展示用途的模型信息。 |
| `requested_model` | `RequestedModel` | 本次实际请求的模型、参数和凭据。 |
| `conversation_id` | `string?` | 本次 Run 所属会话。 |
| `run_id` | `string?` | 客户端分配的 Run 标识。 |
### 4.2 工具和上下文字段
| 字段 | 类型 | 功能 |
| --- | --- | --- |
| `mcp_tools` | `McpTools` | 本次 Run 可用的 MCP 工具定义。 |
| `mcp_file_system_options` | `McpFileSystemOptions?` | MCP 文件系统能力和描述符。 |
| `skill_options` | `SkillOptions?` | 可用技能及技能加载选项。 |
| `custom_system_prompt` | `string?` | 调用方提供的自定义系统提示。 |
| `exclude_workspace_context` | `bool?` | 是否排除工作区上下文。 |
| `pre_fetched_blobs` | `PreFetchedBlob[]` | 调用前已经取得的 blob 内容。 |
### 4.3 模式和子 Agent 字段
| 字段 | 类型 | 功能 |
| --- | --- | --- |
| `subagent_type_name` | `string?` | 当前 Run 使用的子 Agent 类型。 |
| `selected_subagent_models` | `RequestedModel[]` | 为子 Agent 选择的模型。 |
| `selected_subagent_model_details` | `ModelDetails[]` | 子 Agent 模型的展示信息。 |
| `subagent_model_overrides` | `SubagentModelOverride[]` | 按子 Agent 类型覆盖模型选择。 |
| `can_create_cloud_subagents` | `bool?` | 客户端是否允许创建云端子 Agent。 |
| `suppress_subagent_progress_update_tool` | `bool?` | 是否隐藏子 Agent 进度更新工具。 |
| `conversation_group_id` | `string?` | 将多个相关会话归入同一组。 |
### 4.4 客户端能力字段
| 字段 | 类型 | 功能 |
| --- | --- | --- |
| `suggest_next_prompt` | `bool?` | 是否请求生成下一条提示建议。 |
| `harness` | `string?` | 标识调用方所使用的 Agent harness。 |
| `dev_raw_model_slug` | `string?` | 开发模式下使用的原始模型标识。 |
| `client_supports_inline_images` | `bool?` | 客户端是否支持内联图片。 |
| `client_supports_send_to_user` | `bool?` | 客户端是否支持 send-to-user 能力。 |
| `computer_use_coordinate_mode` | `string?` | Computer Use 坐标系模式。 |
## 5. `PrewarmRequest`
功能:提前提供模型、会话状态和能力声明,使后续正式 Run 可以复用已经准备好的上下文。
其主要字段与 `AgentRunRequest` 相同,但没有直接携带 `ConversationAction`
| 字段组 | 字段 |
| --- | --- |
| 模型 | `model_details``requested_model` |
| 会话 | `conversation_id``conversation_state``conversation_group_id` |
| 工具 | `mcp_tools``mcp_file_system_options` |
| Prompt | `custom_system_prompt``exclude_workspace_context` |
| 子 Agent | `subagent_type_name``selected_subagent_models``selected_subagent_model_details``subagent_model_overrides` |
| 客户端能力 | `suggest_next_prompt``client_supports_inline_images``client_supports_send_to_user``computer_use_coordinate_mode` |
| 预取 | `pre_fetched_blobs` |
| 候选选择 | `best_of_n_group_id``try_use_best_of_n_promotion` |
## 6. 模型选择消息
### 6.1 `RequestedModel`
功能:描述调用方实际希望使用的模型和运行参数。
| 字段 | 类型 | 功能 |
| --- | --- | --- |
| `model_id` | `string` | Provider 模型标识。 |
| `max_mode` | `bool` | 是否启用该模型的 max 模式。 |
| `parameters` | `ModelParameterValue[]` | 额外模型参数,每项包含字符串 `id``value`。 |
| `built_in_model` | `bool` | 是否为内建模型。 |
| `is_variant_string_representation` | `bool` | `model_id` 是否表示模型变体字符串。 |
| `credentials` | `oneof` | `api_key_credentials``azure_credentials``bedrock_credentials`。 |
### 6.2 `ModelDetails`
功能:提供模型展示信息、别名、思考能力和凭据。
| 字段 | 类型 | 功能 |
| --- | --- | --- |
| `model_id` | `string` | 模型标识。 |
| `display_model_id` | `string` | 面向 UI 的模型标识。 |
| `display_name` | `string` | 完整展示名称。 |
| `display_name_short` | `string` | 短展示名称。 |
| `aliases` | `string[]` | 可识别的模型别名。 |
| `thinking_details` | `ThinkingDetails?` | 模型思考能力声明。 |
| `max_mode` | `bool?` | 是否启用 max 模式。 |
| `credentials` | `oneof` | API Key、Azure 或 Bedrock 凭据。 |
凭据字段属于敏感信息,不应写入普通日志、错误消息或会话记录。
## 7. `ConversationAction`
功能:描述一次会话级动作。`action``oneof`
### 7.1 公共字段
| 字段 | 类型 | 功能 |
| --- | --- | --- |
| `triggering_auth_id` | `string?` | 触发动作的认证主体。 |
| `triggering_user_info` | `TriggeringUserInfo?` | 触发用户的信息。 |
| `request_context_parts` | `RequestContextPartReferences?` | 通过 blob 引用传递的大型上下文部分。 |
### 7.2 动作分支
| 分支 | 主要参数 | 功能 |
| --- | --- | --- |
| `user_message_action` | `user_message``request_context``prepend_user_messages``conversation_history` | 提交新用户消息并开始或继续会话。 |
| `resume_action` | `request_context` | 从已有 checkpoint 或等待点继续会话。 |
| `cancel_action` | `reason``interrupted_pending_tool_call_resolutions` | 取消当前 Run,并可携带未完成工具的解决结果。 |
| `summarize_action` | 无字段 | 请求生成或刷新会话摘要。 |
| `shell_command_action` | `shell_command``exec_id` | 将一次显式 Shell 命令写入会话。 |
| `start_plan_action` | `user_message``request_context``is_spec` | 进入计划编制流程。 |
| `execute_plan_action` | `request_context``plan`、计划文件字段、`execution_mode``plan_id` | 执行已有计划。 |
| `async_ask_question_completion_action` | `original_tool_call_id``original_args``result` | 回填异步 AskQuestion 的结果。 |
| `cancel_subagent_action` | `subagent_id` | 取消指定子 Agent。 |
| `background_task_completion_action` | `completions[]` | 上报后台 Shell 或子 Agent 的进度和终态。 |
| `background_shell_action` | `tool_call_id` | 将指定 Shell 工具调用切换到后台语义。 |
| `background_subagent_action` | `tool_call_id` | 将指定子 Agent 工具调用切换到后台语义。 |
| `subscription_notification_action` | `notifications[]``request_context` | 将订阅系统产生的消息注入会话。 |
| `goal_continuation_action` | 无字段 | 继续当前长期目标。 |
| `inject_context_action` | `injection_id``expected_run_id``user_context/system_context` | 向仍在运行的 Run 注入上下文。 |
## 8. `UserMessage`
功能:描述用户输入及其选择的上下文和运行模式。
| 字段组 | 字段 | 功能 |
| --- | --- | --- |
| 内容 | `text``rich_text``text_blob_id``rich_text_blob_id` | 用户输入的纯文本、富文本或 blob 引用。 |
| 身份 | `message_id``thread_id``prompt_reference_id` | 消息、线程和提示引用标识。 |
| 上下文 | `selected_context``conversation_state_blob_id` | 用户选择的文件、代码或会话状态。 |
| 模式 | `mode``custom_mode_intent` | Agent、Ask、Plan、Debug、Multitask 或自定义模式。 |
| 计划 | `execute_plan_info` | 当前消息关联的计划。 |
| 子 Agent | `subagent_system_reminder``project_details` | 子 Agent 或项目相关信息。 |
| 模拟消息 | `is_simulated_msg``simulated_msg_reason``simulated_message_metadata` | 标记系统代用户生成的输入。 |
| Hook | `hook_additional_contexts` | Hook 产生的附加上下文。 |
## 9. `RequestContext`
功能:描述本次请求可见的工作区、规则、工具和运行环境。
字段较多,按语义分组如下:
| 字段组 | 代表字段 | 功能 |
| --- | --- | --- |
| 环境 | `env` | OS、Shell、工作区路径、时区、终端目录、sandbox 与 Computer Use 能力。 |
| 规则 | `rules``non_file_rules``cloud_rule``disabled_team_rules` | 本次请求适用的规则集合。 |
| 仓库 | `repository_info``git_repos``project_layouts`、完整性标记 | 仓库索引、Git 和项目布局。 |
| MCP | `tools``mcp_instructions``mcp_file_system_options``mcp_meta_tool_options` | MCP 工具与文件系统能力。 |
| 技能 | `skill_options``agent_skills` | 可用技能和技能内容。 |
| 子 Agent | `custom_subagents` | 自定义子 Agent 声明。 |
| 文件 | `file_contents` | 已预取的路径到文件内容映射。 |
| Web | `web_search_enabled``web_fetch_enabled` | Web Search 和 Web Fetch 能力开关。 |
| Hook | `hooks_additional_context``hooks_config` | Hook 配置和附加上下文。 |
| 权限 | `user_permissions_auto_run``project_permissions_auto_run``admin_permissions_auto_run``admin_command_denylist` | 自动执行许可和禁止命令。 |
| 功能能力 | `supports_mcp_auth``read_lints_enabled``search_conversations_enabled``send_message_enabled` | 客户端可提供的附加能力。 |
大型上下文也可以通过 `RequestContextPartReferences` 传递。该结构为 rules、skills、subagents 和 MCP 分别携带 `blob_id` 与字节长度,并用 `dynamic_context` 继续携带小型动态字段。
## 10. `ExecClientMessage`
功能:返回 `ExecServerMessage` 所请求的客户端执行数据或结果。
### 10.1 公共字段
| 字段 | 类型 | 功能 |
| --- | --- | --- |
| `id` | `uint32` | 与对应 `ExecServerMessage.id` 相同。 |
| `exec_id` | `string` | 与对应 `ExecServerMessage.exec_id` 相同。 |
| `local_execution_time_ms` | `int32?` | 客户端本地执行耗时。 |
| `hook_additional_contexts` | `HookAdditionalContext[]` | 执行 Hook 返回的附加上下文。 |
| `message` | `oneof` | 工具特定的结果或流式事件。 |
### 10.2 主要结果分支
| 分类 | 分支 | 功能 |
| --- | --- | --- |
| 文件 | `read_result``redacted_read_result` | 返回文件读取结果。 |
| 文件 | `write_result``delete_result` | 返回文件写入或删除结果。 |
| 搜索 | `grep_result``ls_result` | 返回文本搜索、Glob 或目录列表结果。 |
| 诊断 | `diagnostics_result``canvas_diagnostics_result` | 返回代码或 Canvas 诊断结果。 |
| Shell | `shell_result``shell_stream` | 返回一次性 Shell 结果或流式 Shell 事件。 |
| Shell | `background_shell_spawn_result``write_shell_stdin_result``force_background_shell_result` | 返回后台 Shell 创建、输入和后台切换结果。 |
| 上下文 | `request_context_result` | 返回动态构建的 RequestContext。 |
| MCP | `mcp_result``list_mcp_resources_exec_result``read_mcp_resource_exec_result``mcp_state_exec_result` | 返回 MCP 调用和资源操作结果。 |
| Hook | `execute_hook_result` | 返回 Hook 执行结果。 |
| 子 Agent | `subagent_result``force_background_subagent_result``subagent_await_result` | 返回子 Agent 运行、后台切换和等待结果。 |
| Web/Computer | `fetch_result``record_screen_result``computer_use_result` | 返回网页、录屏或 Computer Use 结果。 |
| 权限预检 | `shell_allowlist_precheck_result``mcp_allowlist_precheck_result``web_fetch_allowlist_precheck_result` | 返回 allowlist 检查结果。 |
| Git | `git_diff_response` | 返回 Git diff。 |
| Pi 工具 | `pi_read_result``pi_bash_result``pi_edit_result``pi_write_result``pi_grep_result``pi_find_result``pi_ls_result` | 返回 Pi 工具族的执行结果。 |
| 其他 | `smart_mode_classifier_result``conversation_search_result``agent_store_conflict_result` | 返回模式分类、会话搜索或 Agent Store 冲突处理结果。 |
对于 `shell_stream`,其内部 `event` 也是 `oneof`,常见事件包括:
- `start`:进程已经启动。
- `stdout`:标准输出增量。
- `stderr`:标准错误增量。
- `exit`:进程已经退出。
- `rejected`:执行请求被拒绝。
- `permission_denied`:缺少执行权限。
- `backgrounded`:进程已经转入后台。
## 11. `ExecClientControlMessage`
功能:描述客户端执行通道本身的状态,不承载正常工具结果。
`message``oneof`
| 分支 | 参数 | 功能 |
| --- | --- | --- |
| `stream_close` | `id` | 表示指定 Exec 数据流已经关闭。 |
| `throw` | `id``error``stack_trace?``error_code?` | 表示客户端执行通道异常终止。 |
| `heartbeat` | `id` | 表示指定 Exec 仍然存活。 |
## 12. `InteractionResponse`
功能:返回客户端或用户对 `InteractionQuery` 的响应。
| 字段 | 类型 | 功能 |
| --- | --- | --- |
| `id` | `uint32` | 与对应 `InteractionQuery.id` 相同。 |
| `result` | `oneof` | 交互类型对应的响应。 |
当前主要响应分支:
| 分支 | 主要内容 | 功能 |
| --- | --- | --- |
| `ask_question_interaction_response` | `AskQuestionResult` | 返回问题答案、拒绝、错误或异步状态。 |
| `create_plan_request_response` | `CreatePlanResult` | 返回计划 URI以及成功或错误。 |
| `web_search_request_response` | `approved/rejected` | 批准或拒绝 Web Search。 |
| `web_fetch_request_response` | `approved/rejected` | 批准或拒绝 Web Fetch。 |
| `switch_mode_request_response` | `approved/rejected` | 批准或拒绝模式切换。 |
协议还定义 VM 环境、PR 管理、MCP Auth、图片生成、环境替换和 SCM 连接等响应分支。
## 13. `KvClientMessage`
功能:返回 `KvServerMessage` 发起的 blob 操作结果。
| 字段 | 类型 | 功能 |
| --- | --- | --- |
| `id` | `uint32` | 与对应 `KvServerMessage.id` 相同。 |
| `get_blob_result` | `GetBlobResult` | 返回 `blob_data``error`。 |
| `set_blob_result` | `SetBlobResult` | 返回可选的写入错误;无错误表示写入成功。 |
## 14. `ClientHeartbeat`
功能:表示客户端 Agent 通道仍然存活。
该消息没有业务字段,也不与 `ExecClientHeartbeat` 混用:
- `ClientHeartbeat` 面向整个 Agent 请求通道。
- `ExecClientHeartbeat` 面向某个具体 `ExecServerMessage.id`
## 15. RunSSE 请求与服务端根消息
### 15.1 RunSSE 请求
RunSSE 请求体是 `BidiRequestId`,只包含:
| 字段 | 类型 | 功能 |
| --- | --- | --- |
| `request_id` | `string` | 订阅指定请求流的服务端消息。 |
### 15.2 `AgentServerMessage`
功能:封装一条服务端到客户端的 Agent 消息。
| 字段 | 类型 | 功能 |
| --- | --- | --- |
| `ttft_breakdown` | `TtftBreakdown` | 可选的首 token 延迟分解。 |
| `message` | `oneof` | 本条消息的业务载荷。 |
`message` 可以选择以下一个分支:
| 分支 | 消息类型 | 功能 |
| --- | --- | --- |
| `interaction_update` | `InteractionUpdate` | 返回文本、思考、工具和 turn 生命周期更新。 |
| `exec_server_message` | `ExecServerMessage` | 请求客户端执行本地工具。 |
| `exec_server_control_message` | `ExecServerControlMessage` | 控制已经发出的客户端执行。 |
| `conversation_checkpoint_update` | `ConversationStateStructure` | 更新客户端持有的会话 checkpoint。 |
| `kv_server_message` | `KvServerMessage` | 请求客户端读取或写入 blob。 |
| `interaction_query` | `InteractionQuery` | 请求用户或客户端作出交互决策。 |
## 16. `InteractionUpdate`
功能:承载模型输出和一次 turn 中的增量状态。
`message``oneof`。当前主要消息如下。
### 16.1 文本和思考
| 分支 | 参数 | 功能 |
| --- | --- | --- |
| `text_delta` | `text``is_server_notice` | 返回可展示文本增量。 |
| `thinking_delta` | `text``thinking_style?` | 返回思考文本增量及展示样式。 |
| `thinking_completed` | `thinking_duration_ms` | 表示思考阶段结束。 |
### 16.2 工具调用
| 分支 | 参数 | 功能 |
| --- | --- | --- |
| `tool_call_started` | `call_id``tool_call``model_call_id` | 宣布工具调用已经建立。 |
| `partial_tool_call` | `call_id``tool_call``args_text_delta``model_call_id` | 在参数尚未完整时返回部分 ToolCall。 |
| `tool_call_delta` | `call_id``tool_call_delta``model_call_id` | 返回 Shell、Task、Edit 或环境替换的增量。 |
| `tool_call_completed` | `call_id``tool_call``model_call_id` | 表示工具调用已经得到终态结果。 |
| `shell_output_delta` | `stdout/stderr/start/exit` | 返回 Shell 进程输出和生命周期增量。 |
同一次工具调用的这些消息必须使用相同的 `call_id`;同一次模型调用产生的工具事件应使用相同的 `model_call_id`
### 16.3 摘要和结束
| 分支 | 参数 | 功能 |
| --- | --- | --- |
| `summary_started` | 无字段 | 表示摘要阶段开始。 |
| `summary` | `summary` | 返回摘要文本。 |
| `summary_completed` | `hook_message?` | 表示摘要阶段完成,并可携带后续 Hook 信息。 |
| `turn_ended` | token 统计字段 | 表示当前 turn 正常结束。 |
`turn_ended` 的 token 字段包括:
- `input_tokens`
- `output_tokens`
- `cache_read_tokens`
- `cache_write_tokens`
- `reasoning_tokens`
### 16.4 保活
| 分支 | 参数 | 功能 |
| --- | --- | --- |
| `heartbeat` | 无字段 | 保持 RunSSE 活跃,不表示业务状态变化。 |
协议还定义 `user_message_appended``token_delta`、step 生命周期、prompt suggestion、branch change、feedback、response comparison 和 context injection state 等更新。
## 17. `ExecServerMessage`
功能:要求客户端执行一项本地能力。
### 17.1 公共字段
| 字段 | 类型 | 功能 |
| --- | --- | --- |
| `id` | `uint32` | 执行桥消息编号,客户端回包必须原样携带。 |
| `exec_id` | `string` | 执行任务标识,流式消息应保持一致。 |
| `span_context` | `SpanContext?` | 可选的分布式追踪上下文。 |
| `accept_hook_additional_contexts` | `bool?` | 是否接受客户端在结果中返回 Hook 附加上下文。 |
| `message` | `oneof` | 工具特定的执行参数。 |
### 17.2 主要执行分支
| 分类 | 分支 | 功能 |
| --- | --- | --- |
| 文件 | `read_args``write_args``delete_args` | 读取、写入或删除文件。 |
| 搜索 | `grep_args``ls_args` | 搜索文本、匹配路径或列出目录。 |
| 诊断 | `diagnostics_args` | 获取编辑器或项目诊断。 |
| Shell | `shell_stream_args` | 启动流式 Shell 命令。 |
| Shell | `write_shell_stdin_args``force_background_shell_args` | 向 Shell 写入输入或切换后台执行。 |
| MCP | `mcp_args``list_mcp_resources_exec_args``read_mcp_resource_exec_args` | 调用 MCP 工具或读取 MCP 资源。 |
| Hook | `execute_hook_args` | 请求客户端执行 Agent Hook。 |
| 子 Agent | `subagent_args` | 请求客户端启动子 Agent。 |
协议还定义普通 Shell、后台 Shell 创建、RequestContext、Fetch、Computer Use、allowlist 预检、Git diff、Pi 工具、会话搜索和 Agent Store 冲突等执行分支。
### 17.3 回包规则
客户端返回 `ExecClientMessage``ExecClientControlMessage` 时:
- `id` 必须与请求一致。
- 如果存在 `exec_id`,应与请求一致。
- 流式执行可以返回多条数据消息。
- 最终结果、`throw` 或明确终态用于结束本次执行关联。
## 18. `ExecServerControlMessage`
功能:控制此前已经发出的 Exec 请求。
当前协议分支:
| 分支 | 参数 | 功能 |
| --- | --- | --- |
| `abort` | `id` | 请求客户端终止对应的 Exec。 |
`abort.id` 对应 `ExecServerMessage.id`,不是 `tool_call_id`
## 19. `InteractionQuery`
功能:请求用户或客户端完成不能由模型单独决定的交互。
### 19.1 公共字段
| 字段 | 类型 | 功能 |
| --- | --- | --- |
| `id` | `uint32` | 交互编号,响应必须原样携带。 |
| `query` | `oneof` | 具体交互内容。 |
### 19.2 主要查询分支
| 分支 | 主要参数 | 功能 |
| --- | --- | --- |
| `ask_question_interaction_query` | `args``tool_call_id` | 向用户展示一个或多个问题。 |
| `create_plan_request_query` | `args``tool_call_id` | 请求客户端创建或保存计划。 |
| `web_search_request_query` | `args` | 请求批准 Web Search。 |
| `web_fetch_request_query` | `args``skip_approval``smart_mode_approval` | 请求批准或执行 Web Fetch。 |
| `switch_mode_request_query` | `args.target_mode_id``explanation?``tool_call_id` | 请求切换 Agent 模式。 |
协议还定义 VM 环境、PR 管理、MCP Auth、图片生成、环境替换和 SCM 连接查询。
### 19.3 响应规则
客户端必须用 `InteractionResponse` 返回结果:
- `InteractionResponse.id` 与查询 `id` 相同。
- `result` 分支必须与原查询类型匹配。
- 批准/拒绝型响应应明确选择对应的 `oneof` 分支,不能用空消息代替拒绝。
## 20. `KvServerMessage`
功能:请求客户端提供或保存较大的二进制数据。
| 字段 | 类型 | 功能 |
| --- | --- | --- |
| `id` | `uint32` | KV 操作编号。 |
| `span_context` | `SpanContext?` | 可选追踪上下文。 |
| `get_blob_args` | `GetBlobArgs` | 按 `blob_id` 读取数据。 |
| `set_blob_args` | `SetBlobArgs` | 按 `blob_id` 保存 `blob_data`。 |
客户端使用相同 `id` 返回 `KvClientMessage`
Blob 字段是原始 bytes。协议使用 `blob_id` 引用它们,以避免在主要会话消息中重复传输大型上下文。
## 21. `ConversationStateStructure`
功能:表示可跨请求传递的会话 checkpoint。
该结构既可以由客户端随 `AgentRunRequest` 上传,也可以由服务端通过 `conversation_checkpoint_update` 返回。
| 字段组 | 代表字段 | 功能 |
| --- | --- | --- |
| Prompt | `root_prompt_messages_json` | 根 Prompt 消息,元素以 bytes 保存。 |
| Turn | `turns``turn_timings` | 历史 turn 和耗时。 |
| 工具 | `pending_tool_calls` | 尚未解决的工具调用。 |
| 状态 | `todos``plan``plans` | Todo 和计划状态。 |
| Token | `token_details` | 已用 token、最大 token 和上下文分解。 |
| 摘要 | `summary``summary_archive``summary_archives``self_summary_count` | 当前摘要和历史摘要。 |
| 文件 | `file_states``file_states_v2``read_paths` | 会话涉及的文件状态。 |
| 工作区 | `previous_workspace_uris``tracked_git_repo_branches``active_branch_name` | 工作区和 Git 状态。 |
| 模式 | `mode``agent_type` | 当前 Agent 模式和类型。 |
| 子 Agent | `subagent_states``subagent_threads``subagent_runs_by_parent_tool_call_id``subagent_state_refs` | 子 Agent checkpoint。 |
| 通信进度 | `communicate_update_*` | 长任务进度和最终摘要。 |
| 会话时间 | `conversation_started_timestamp_ms``conversation_started_time_zone` | 会话开始时间。 |
| Goal | `goal_state` | 长期目标状态。 |
注意:多个字段使用 `bytes`,其内部内容通常仍是另一种 protobuf 或 JSON 编码。消费者必须依据字段定义解码,不能把所有 bytes 都当作 UTF-8 文本。
## 22. 消息配对关系
### 22.1 Run
```text
AgentClientMessage.run_request
-> AgentServerMessage.interaction_update (...多条)
-> AgentServerMessage.conversation_checkpoint_update
-> AgentServerMessage.interaction_update.turn_ended
-> stream end
```
### 22.2 Exec
```text
AgentServerMessage.exec_server_message(id, exec_id)
-> AgentClientMessage.exec_client_message(id, exec_id) (...可多条)
-> AgentClientMessage.exec_client_control_message(id) (...可选)
```
### 22.3 Interaction
```text
AgentServerMessage.interaction_query(id, query)
-> AgentClientMessage.interaction_response(id, matching_result)
```
### 22.4 KV
```text
AgentServerMessage.kv_server_message(id, get/set)
-> AgentClientMessage.kv_client_message(id, matching_result)
```
## 23. `oneof` 与可选字段规则
- 同一个 `oneof` 在一条 protobuf 消息中只能设置一个分支。
- 未设置 `optional` 字段和设置为默认值在业务语义上可能不同,消费者需要保留 presence 信息。
- 未识别的 protobuf 字段应按 protobuf 兼容规则保留或忽略,不应导致整条消息无法解析。
- 请求与响应的类型必须匹配,不能只依赖相同的 `id`
- `request_id``conversation_id``model_call_id``tool_call_id``exec_id` 和桥接 `id` 属于不同命名空间,不应互相替代。
- 增量消息只表达追加内容;接收方不应把 delta 当作完整快照覆盖已有内容。
- checkpoint 表达完整状态视图;同类的新 checkpoint 可以替代旧 checkpoint。
## 24. 错误与终止语义
协议需要区分三类结束:
1. 正常业务结束
- 典型信号是 `InteractionUpdate.turn_ended`,随后流结束。
2. 用户或系统取消
- 可能先出现 Exec `abort`,随后 RunSSE 以 canceled 状态结束。
3. 协议、provider 或服务错误
- 可以通过 Connect end-stream error 返回,不一定存在对应的 `AgentServerMessage.oneof` 分支。
因此,客户端不能仅凭“流关闭”判断正常完成;还需要结合最后一条业务消息和流终止状态。