返回 DeepSeek-Reasonix
ACP.zh-CN.md
根目录 / docs / ACP.zh-CN.md
1 # ACP 编辑器接入
2
3 <a href="../README.zh-CN.md">README</a>
4 &nbsp;·&nbsp;
5 <a href="./ACP.md">English</a>
6 &nbsp;·&nbsp;
7 <a href="./GUIDE.zh-CN.md">使用指南</a>
8 &nbsp;·&nbsp;
9 <a href="https://agentclientprotocol.com/">ACP 规范</a>
10
11 Reasonix 实现了 Agent Client Protocol(ACP)v1,通过标准输入输出提供 NDJSON
12 JSON-RPC 2.0 agent。编辑器和其他 ACP host 负责启动进程、打开一个或多个工作区会话,
13 并接收流式消息、工具活动、计划、权限请求和配置更新。
14
15 ## 启动 agent
16
17 ACP host 应启动以下命令之一:
18
19 ```sh
20 reasonix acp
21 reasonix acp --model deepseek-pro
22 reasonix acp --profile delivery
23 ```
24
25 客户端未覆盖模型时,`--model` 用于选择启动模型;`--profile` 把启动工作模式设为
26 `economy`、`balanced` 或 `delivery`。初始化后,两者仍可按会话切换。
27
28 标准输出专用于 ACP 消息,Reasonix 会把诊断写入标准错误,因此 host 不应合并这两个
29 流。尚未配置 provider 时先运行 `reasonix setup`;initialize 响应也会声明一个启动
30 `reasonix setup` 的 terminal authentication method。
31
32 ## 初始化与能力协商
33
34 客户端应在打开会话前调用 `initialize`。Reasonix 会声明以下能力结构(省略无关字段):
35
36 ```json
37 {
38 "protocolVersion": 1,
39 "agentCapabilities": {
40 "loadSession": true,
41 "sessionCapabilities": {
42 "list": {},
43 "resume": {},
44 "close": {},
45 "delete": {}
46 },
47 "promptCapabilities": {
48 "image": false,
49 "audio": false,
50 "embeddedContext": true
51 },
52 "mcpCapabilities": {
53 "http": true,
54 "sse": false
55 },
56 "_meta": {
57 "reasonix.io": {
58 "sessionSteer": {
59 "method": "_reasonix.io/session/steer"
60 }
61 }
62 }
63 }
64 }
65 ```
66
67 客户端声明 `fs.readTextFile`、`fs.writeTextFile` 或 `terminal` 后,Reasonix 会让
68 适用的文件操作经过编辑器的未保存 buffer,并让适用的前台命令在客户端持有的 terminal
69 中运行。客户端没有声明这些能力时,常规工作区工具会在 Reasonix 进程内本地运行。
70
71 ## 会话生命周期
72
73 每个 ACP 会话都拥有独立的 Reasonix Controller、工作区根目录、模型、工作模式、协作
74 模式、审批模式、MCP 集合和持久化 transcript,会话之间不会泄漏状态。
75
76 | 方法 | 行为 |
77 | --- | --- |
78 | `session/new` | 为绝对路径 `cwd` 打开会话并返回配置状态。 |
79 | `session/load` | 打开持久化 ACP 会话,并通过 `session/update` 通知回放 transcript。 |
80 | `session/resume` | 打开持久化会话,但不回放 transcript。 |
81 | `session/prompt` | 执行一轮任务,流式发送更新,最后返回停止原因。 |
82 | `session/cancel` | 取消活动回合;它是一条 notification。 |
83 | `session/list` | 列出活动和持久化 ACP 会话,可按绝对路径 `cwd` 过滤。 |
84 | `session/close` | 停止活动会话并释放资源,但不删除历史。 |
85 | `session/delete` | 停止会话并删除其持久化 ACP 历史。 |
86
87 `session/new`、`session/load` 和 `session/resume` 可以携带 `mcpServers`。
88 Reasonix 支持 stdio、Streamable HTTP 和 legacy SSE server。
89 stdio `env` 和 HTTP `headers` 支持 ACP 官方的
90 `[{"name":"...","value":"..."}]` 结构,同时继续接受旧版 object-map 结构。
91
92 ## 会话控制
93
94 Reasonix 把互不相关的选择拆成独立控制轴,而不是混在一个 mode selector 中:
95
96 | 控制项 | 可选值 | 协议入口 |
97 | --- | --- | --- |
98 | 协作模式 | `normal`、`plan`、`goal` | `modes` 和 `session/set_mode` |
99 | 模型 | 已配置的 `provider/model` | id 为 `model` 的 `configOptions` |
100 | 推理强度 | provider 支持的等级或 `auto` | id 为 `effort` 的 `configOptions` |
101 | 工作模式 | `economy`、`balanced`、`delivery` | id 为 `work_mode` 的 `configOptions` |
102 | 工具审批 | `ask`、`auto`、`yolo` | id 为 `tool_approval` 的 `configOptions` |
103
104 模型、推理强度、工作模式和工具审批统一使用 `session/set_config_option`。它的参数是
105 `sessionId`、`configId` 和 `value`,其中 `configId` 取 `configOptions` 中该选项的
106 `id`:
107
108 ```json
109 {
110 "jsonrpc": "2.0",
111 "id": 3,
112 "method": "session/set_config_option",
113 "params": {
114 "sessionId": "session-id",
115 "configId": "tool_approval",
116 "value": "yolo"
117 }
118 }
119 ```
120
121 注意字段名是 `configId`,不是 `optionId`。返回值是刷新后的完整 `configOptions`
122 数组;id 未知时返回 `-32602 InvalidParams`。
123
124 切换模型、推理强度或工作模式时会重建会话 Controller,同时保留历史和其他控制轴;
125 切换工具审批只更新 gate,不重建 Controller。
126
127 旧客户端仍可使用 `session/set_model`。`session/set_mode` 也继续接受 legacy 值
128 `default` 和 `auto`,分别表示“常规 + 询问”和“常规 + Yolo”;新客户端应使用上面的
129 独立 selector。
130
131 ## Prompt、更新与审批
132
133 `session/prompt` 支持文本 block 和内嵌文本 resource,不声明图片或音频能力。执行回合
134 期间,Reasonix 可能发送:
135
136 - agent 消息和思考内容 chunk;
137 - pending 和 completed 工具调用更新;
138 - 从 `todo_write` 生成的完整计划更新;
139 - 可用的斜杠命令;
140 - 当前 mode 和配置项更新;
141 - 针对受权限控制工具及用户问题的 `session/request_permission` 请求。
142
143 Host 应让 `session/prompt` 请求保持打开,直到 Reasonix 返回停止原因;期间仍需同时处理
144 双向 request 和 notification。
145
146 ## 回合中引导扩展
147
148 Reasonix 通过 ACP v1 厂商扩展提供回合中引导。它不是 ACP 核心方法,也不是仍未发布的
149 ACP v2 `session/inject` 提案。
150
151 ### 发现能力
152
153 从以下位置读取方法名:
154
155 ```text
156 agentCapabilities._meta["reasonix.io"].sessionSteer.method
157 ```
158
159 不要假设该扩展一定存在,也不要调用无命名空间的 `session/steer`。ACP 为核心协议保留
160 所有不以下划线开头的方法名。
161
162 ### 发送引导
163
164 在 `session/prompt` 仍处于活动状态时调用声明的方法:
165
166 ```json
167 {
168 "jsonrpc": "2.0",
169 "id": 2,
170 "method": "_reasonix.io/session/steer",
171 "params": {
172 "sessionId": "session-id",
173 "prompt": [
174 {"type": "text", "text": "把用户名改成邮箱"}
175 ]
176 }
177 }
178 ```
179
180 成功返回 `{}` 表示活动回合已接受引导。Reasonix 会在下一个安全的模型调用边界前把它
181 作为 user message 加入上下文,不会取消回合,也不会额外消耗工具步骤预算。该消息会进入
182 正常历史;回放 transcript 时显示用户原文,不显示 Reasonix 内部 steer marker。
183
184 | 条件 | JSON-RPC 结果 |
185 | --- | --- |
186 | 活动 prompt 接受引导 | `{}` |
187 | session 不存在或 prompt 为空 | `-32602 InvalidParams` |
188 | session 没有活动 prompt | `-32600 InvalidRequest` |
189 | 客户端调用 `session/steer` | `-32601 MethodNotFound` |
190
191 收到 `InvalidRequest` 时,引导没有入队。客户端可以等待活动 prompt 结束,再让用户把该
192 文本作为普通新 prompt 提交,但不能把失败的 steer 静默显示为已接受。
193
194 ## 运行时重载与扩展表面
195
196 Reasonix 还在 `agentCapabilities._meta["reasonix.io"]` 中通告两个扩展点:
197
198 - `sessionReloadExtensions`——vendor method
199 `_reasonix.io/session/reloadExtensions`。调用后按与 CLI `/reload`
200 相同的失败原子语义重载该会话的 agent 运行时(扩展、工具、skills、
201 commands、hooks、providers):回合或重建进行中只排队一次
202 (`{"queued": true}`),空闲后执行;否则原子重建并交换,重建失败时
203 保留旧运行时。重载成功后 Reasonix 会推送新的
204 `available_commands_update`。
205 - `extensionSurface`——结构化扩展 UI 能力。在 initialize `_meta` 中
206 同样声明了 `reasonix.io.extensionSurface` 的客户端会收到结构化的
207 扩展表面载荷;未声明的客户端收到等价文本 fallback(card/status 退
208 化为 `agent_message_chunk`,扩展表单退化为权限请求),因此客户端
209 不做任何处理也能保持兼容。
210
211 已安装插件声明的扩展 action 以 `/<plugin>:<action>` 出现在
212 `available_commands_update` 中,可像普通斜杠命令一样调用。
213
214 ## 兼容性与缓存行为
215
216 | 表面 | 旧版或非 Reasonix 客户端的行为 | 结论 |
217 | --- | --- | --- |
218 | 现有 ACP v1 方法 | 方法名和响应结构不变。 | 兼容 |
219 | Capability `_meta` | 可以忽略未知 metadata。 | 兼容 |
220 | 持久化 transcript | 不需要新增持久化 schema。 | 兼容 |
221 | CLI、Desktop、Bot steer | 保留现有 idle fallback。 | 兼容 |
222
223 Steer 只会把用户请求的消息追加到正常会话历史,不改变 system prompt、工具 schema、工具
224 顺序或其他稳定的 provider prefix 字节。下一次 provider 请求必然包含这条新消息,和任何
225 普通新用户消息一样会改变新增后缀,但此前的稳定前缀仍可复用。
226
227 ## 客户端接入检查清单
228
229 1. 启动 `reasonix acp`,分离 stdin、stdout 和 stderr。
230 2. 调用 `initialize`,同时遵守标准 capability 和 `_meta` capability。
231 3. 使用绝对工作区路径打开会话,并隔离保存各 session id。
232 4. Prompt 运行期间继续处理 agent 发往客户端的文件、terminal 和权限请求。
233 5. 只有在 Reasonix 声明 capability 且 prompt 活动时才显示 steer UI。
234 6. 把成功的 steer 响应理解为“引导已入队”,而不是“模型已立即完成处理”。
235 7. 用 `session/close` 释放资源;只有用户明确要删除持久化历史时才调用
236 `session/delete`。
237
237 lines MARKDOWN