Skip to content

附录 C · ACP 消息字段参考

Agentao 的 ACP 服务器/客户端发出的每种消息的字段级速查。端到端叙事(握手 → 提示 → 流式 → 取消)见 Part 3。本附录是你在调试畸形消息时打开的那一页。

约定

  • 请求; 响应; 服务器到客户端通知
  • 所有消息都是 stdio 上的 NDJSON JSON-RPC 2.0
  • {…} = 对象;[…] = 数组;T|U = 联合;? = 可选

C.1 initialize

握手,MUST 是第一个调用。

→ 请求

字段类型必填说明
protocolVersionintAgentao 讲 1bool 被显式拒绝
clientCapabilitiesobject客户端能力标志(如 fs: {readFile, writeFile}
clientInfoobject{name, version, title} —— 纯信息性

← 响应

字段类型说明
protocolVersionint协商后——通常回显请求值;版本不匹配也不报错
agentCapabilitiesobject见下
authMethods[]v1 为空——Agentao 不做 ACP 级认证
agentInfoobject{name: "agentao", title: "Agentao", version}
_meta["_agentao.cn/extensions"][{method, description}]扩展方法,放在 _meta 下(ACP 标准的扩展通道);含 _agentao.cn/ask_user

agentCapabilities 字段(v0.2.x)

字段含义
loadSessiontrue支持 session/load——见 7.2
promptCapabilities.imagefalsev1 基线仅文本
promptCapabilities.audiofalse
promptCapabilities.embeddedContextfalse
mcpCapabilities.ssetrue可用 SSE 传输
mcpCapabilities.httpfalse支持 HTTP 传输

C.2 session/new

新建会话。

→ 请求

字段类型必填说明
cwdstring绝对路径,必须存在且是目录
mcpServers[object]是([] 可接受)每会话的 MCP 服务器

mcpServers[i] 形状

字段类型说明
namestring非空
type"stdio" / "http" / "sse"有的客户端会声明 http,但 agent 按 mcpCapabilities
commandstring仅 stdio
args[string]仅 stdio
env[{name, value}]仅 stdio——注意是键值对对象数组,不是 map
urlstring仅 sse / http
headers[{name, value}]仅 sse / http

← 响应

字段类型说明
sessionIdstringUUID。收好——后续每个调用都要用
configOptions[object]模型/提供方选择项(configId: "model");通过 session/set_config_option 触发切换。无法枚举目录时为空数组

常见失败

JSON-RPC code原因
-32002initialize 之前调(SERVER_NOT_INITIALIZED)
-32602cwd 不是绝对/不存在,或 mcpServers 格式错

启动时恢复。 当 server 以 agentao --acp --resume [SESSION_ID] 启动时,第一个 session/new 会恢复持久化会话而非新建空会话:把历史作为 session/update 通知重放,并返回持久化的 sessionId。未命中(空存储 / 未知 id / 文件损坏 / id 已存活)会静默降级为普通的全新会话。见 3.2 → 启动时恢复会话

C.3 session/prompt

跑一轮用户交互,返回时 agent 已停。

→ 请求

字段类型必填说明
sessionIdstringsession/newsession/load
prompt[ContentBlock]见下

ContentBlock 形状

字段类型说明
type"text"v1 基线仅 text
textstring用户消息

← 响应

字段类型说明
stopReasonstring"end_turn""max_tokens""cancelled"

C.4 session/update ⇠ 通知

服务器到客户端在一轮内的流式更新。

Params

字段类型说明
sessionIdstring活跃会话
updateobjectsessionUpdate 分支

变体(update.sessionUpdate

Agentao 事件额外字段
user_message_chunk(回放)content: {type:"text", text}
agent_message_chunkLLM_TEXTcontent: {type:"text", text}
agent_thought_chunkTHINKING / ERRORcontent: {type:"text", text}
tool_callTOOL_STARTtoolCallIdtitlekindstatus:"pending"rawInput
tool_call_updateTOOL_OUTPUT / TOOL_COMPLETEtoolCallIdstatus,可选 content[] 追加

tool_call.kind(封闭枚举)

readeditdeletemovesearchexecutethinkfetchswitch_modeother。Agentao 会把内部工具名映射到这枚举——见 agentao/acp/transport.py

tool_call_update.status

时机
in_progress输出流式片段
completed工具成功
failed工具抛错或返回错误

C.5 session/request_permission ⇠ 通知

服务器请客户端确认工具调用。

Params

字段类型说明
sessionIdstring
toolCallobject形状同 session/update.tool_call
options[{optionId, name, kind}]通常 ["allow", "allow_always", "reject"]

期望响应(客户端 → 服务器)

字段类型说明
outcome.outcome"selected""cancelled"
outcome.optionIdstringselected 时必填

取消规则:如果客户端一直不回,而整轮被取消,agent 会把所有挂起的权限请求以 cancelled 解决。见 7.2 陷阱

C.6 session/cancel

中止当前轮与所有挂起的权限请求。

→ 请求

字段类型说明
sessionIdstring

← 响应

空对象 {}。进行中的 session/prompt 最终以 stopReason: "cancelled" 解决。

C.7 session/load

按 id 恢复会话。仅当 agent 在能力里声明 loadSession: true 时可用。

→ 请求

字段类型说明
sessionIdstring必须是之前创建过的
cwdstring绝对路径;要与会话原 cwd 匹配
mcpServers[object]重声明——指纹要与 session/new 时一致

← 响应

{configOptions: [...]}——与 session/new 相同的模型/提供方选择项(无目录时为空数组)。Agent 还会通过 session/update 通知回放历史轮次(从持久化历史重建),之后才进入可接受下一轮 session/prompt 的状态。

指纹规则

session/newmcpServers 会被哈希。如果 session/load 传了不同的集合(增/删/重排),Agentao 可能拒绝或静默重建——取决于实现阶段。拿不准就传原样列表

C.8 session/set_config_option

用 ACP 标准的 config-option 机制切换模型(以及可选地切换提供方)。凭证绝不上线——Agentao 在服务端用宿主注入的 provider_resolver 解析凭证(默认走环境变量)。

→ 请求

字段类型必填说明
sessionIdstring活跃会话
configIdstring必须是 "model";其它值 → -32600 Invalid Request
valuestringprovider/model(如 openai/gpt-4o)或裸 model(保持当前提供方)。按第一个 / 切分;provider 转小写,model 原样保留

apiKeybaseUrl_meta 以及任何其它字段都会被拒绝-32602extra="forbid" + handler 白名单)——"凭证在服务端解析,绝不上线"

← 响应

字段类型说明
configOptions[object]刷新后的选择项(与 session/new 同形),反映新的 currentValue

解析与错误

  • provider/model:Agentao 调 provider_resolver(provider_id){api_key, base_url?},然后整套切换 provider + model。默认 resolver 只接受配置的 LLM_PROVIDER(大小写不敏感),读 {PREFIX}_API_KEY / {PREFIX}_BASE_URL;其它 provider → -32600 cannot resolve provider '<id>'。要支持更多提供方,注入更丰富的 resolver。
  • model:只换模型(provider 不变),与 _agentao.cn/set_model 走同一条核心路径。
  • resolver 失败时,服务端只记录 provider id + 异常类型,绝不记录消息(可能夹带密钥)。

ConfigOption 结构(configOptions 里的条目)

字段类型说明
idstring"model"
namestring"Model"
category"mode" | "model" | "thought_level""model"
type"select"v1 只有 select
currentValuestring?当前模型的 provider/model
options[{value, name?, description?}]候选项;valueprovider/model。默认目录 = 当前环境的单一模型;更丰富的目录由宿主注入

C.9 _agentao.cn/set_model(扩展)

Agentao 独有的自由文本换模型——session/set_config_option 裸值路径的厂商版兄弟。无密钥;与其共享同一条核心路径。

→ 请求

字段类型必填说明
sessionIdstring活跃会话
modelstring当前提供方接受的任意模型 id(会 strip)。自由文本——不按目录校验

apiKeybaseUrl_meta 会被拒绝-32602)。

← 响应

字段类型说明
modelstring切换后的活跃模型 id(agent.llm.model

C.10 session/set_mode

设置会话的 ACP modeId。字段是 ACP 标准的 modeId(不是 mode),且是开放字符串——一个 UI/行为选择器,不一定映射到 Agentao 权限预设。

→ 请求

字段类型必填说明
sessionIdstring活跃会话
modeIdstring非空。精确命中权限预设(read-only / workspace-write / full-access / plan)时 Agentao 应用之;其它值(如 codeask)会被持久化并回显,但不改变权限姿态

← 响应

字段类型说明
modeIdstring回显持久化的值

说明

  • 命中预设要求会话有 PermissionEngine,否则 -32600 Invalid Request。未知 modeId 不需要引擎——纯 UI 状态。
  • 按会话隔离:每个会话拥有自己的引擎,会话 A 的预设变更绝不影响会话 B。

C.11 _agentao.cn/ask_user ⇠ 通知(扩展)

Agentao 独有,服务器向用户问一个自由文本问题。

Params

字段类型说明
sessionIdstring
questionstring自由文本

期望响应

字段类型说明
answerstring用户自由文本回答

用户不可达时,客户端可回返哨兵 "(user unavailable)"(常量 ASK_USER_UNAVAILABLE_SENTINEL)。

C.12 JSON-RPC 错误码速查

代码含义
-32700Parse error服务器收到非法 JSON
-32600Invalid RequestJSON 合法但不是 JSON-RPC Request
-32601Method not found方法不存在或不可用
-32602Invalid params方法参数非法
-32603Internal error内部 JSON-RPC 错
-32002Server not initializedinitialize 之前调了 session 方法

对照 AcpErrorCode附录 D.2


附录 D · 错误码 · 附录 E · 迁移