im_wower
·
2026-04-02
control-interfaces.md
1# 控制类接口
2
3这份文档给网页版 AI、CLI AI 和人工运维使用。
4
5目标是:
6
7- 先完成能力感知
8- 再读取当前状态
9- 最后才执行控制动作
10
11业务类接口单独见:
12
13- [`business-interfaces.md`](./business-interfaces.md)
14
15## 当前推荐入口
16
17当前项目使用 `mini` 单节点模式。
18
19推荐优先级:
20
211. 内网真相源:`http://100.71.210.78:4317`
222. 公网入口:`https://conductor.makefile.so`
23
24## 给 AI 的控制顺序
25
26建议严格按这个顺序:
27
281. 先读本文件
292. 调 `GET /describe/control`
303. 如有需要,再调 `GET /v1/capabilities`
314. 如果涉及 browser/plugin 管理,先调 `GET /v1/browser`
325. 调 `GET /v1/system/state`
336. 如果要做本机 shell / 文件操作,再看 `host_operations`
347. 确认当前模式和动作目标后,再执行 `POST /v1/browser/actions`、`pause` / `resume` / `drain` 或 host-ops
35
36如果目标是 Codex 会话而不是控制动作:
37
38- 改读 [`business-interfaces.md`](./business-interfaces.md)
39- 先看 `GET /describe/business`
40- 使用 `/v1/codex/*`
41- 这些路由固定代理到独立 `codexd`
42
43不要在未读状态前直接写入控制动作或本机 host-ops。
44
45## Host Ops 鉴权
46
47- `POST /v1/exec`
48- `POST /v1/files/read`
49- `POST /v1/files/write`
50
51这三条 host-ops 路由现在统一要求:
52
53- `Authorization: Bearer <BAA_SHARED_TOKEN>`
54- 缺少 token 或 token 错误时返回明确的 `401` JSON 错误
55- 即使通过 `https://conductor.makefile.so` 暴露,这三条路由也不再是匿名公网可用
56
57## 当前可用控制类接口
58
59### 发现与诊断
60
61| 方法 | 路径 | 作用 |
62| --- | --- | --- |
63| `GET` | `/describe/control` | 返回控制类自描述和推荐使用顺序 |
64| `GET` | `/health` | 返回服务健康摘要 |
65| `GET` | `/version` | 返回服务版本摘要 |
66| `GET` | `/v1/capabilities` | 返回当前启用能力、读写分类和注意事项 |
67
68### 当前状态
69
70| 方法 | 路径 | 作用 |
71| --- | --- | --- |
72| `GET` | `/v1/browser` | 返回 browser bridge 在线状态、插件摘要、最新 `shell_runtime` / `last_action_result`、浏览器登录态持久化记录,以及浮层同步所需的 `automation_conversations` |
73| `GET` | `/v1/system/state` | 返回当前 automation mode、leader、queue、active runs |
74
75### Browser / Plugin 管理
76
77| 方法 | 路径 | 作用 |
78| --- | --- | --- |
79| `POST` | `/v1/browser/actions` | 派发通用 browser/plugin 管理动作;当前正式支持 `request_credentials`、`tab_open`、`tab_focus`、`tab_reload`、`plugin_status`、`ws_reconnect`、`controller_reload`、`tab_restore` |
80| `POST` | `/v1/browser/claude/open` | legacy 包装:等价映射到 `POST /v1/browser/actions` |
81| `POST` | `/v1/browser/claude/reload` | legacy 包装:等价映射到 `POST /v1/browser/actions` |
82
83browser/plugin 管理约定:
84
85- `GET /v1/browser` 是 plugin 状态和登录态元数据的共享读面;不是单独的第三层 describe
86- `GET /v1/browser` 现在也会暴露 `automation_conversations`,把当前 active link 对应的 `automation_status`、`pause_reason` 和 `remote_conversation_id` 提供给 Firefox / Safari 浮层同步
87- `POST /v1/browser/actions` 当前正式支持:
88 - `request_credentials`
89 - `tab_open`
90 - `tab_focus`
91 - `tab_reload`
92 - `plugin_status`
93 - `ws_reconnect`
94 - `controller_reload`
95 - `tab_restore`
96- `ws_reconnect` 额外支持可选参数:
97 - `disconnectMs` / `disconnect_ms` / `delayMs` / `delay_ms`
98 - `repeatCount` / `repeat_count`
99 - `repeatIntervalMs` / `repeat_interval_ms` / `intervalMs` / `interval_ms`
100- 当前正式 shell / credential 管理平台仍覆盖 `claude` 和 `chatgpt`;Gemini raw relay 已转入 business 面,但 control 面的 shell 管理合同没有在这轮一起扩面
101- 如果没有活跃 browser bridge client,会返回 `503`
102- 如果指定了不存在的 `clientId`,会返回 `409`
103- `POST /v1/browser/actions` 会等待插件回传结构化 `action_result`,返回 `accepted` / `completed` / `failed` / `reason` / `target` / `result` / `shell_runtime`
104- 对 `browser.proxy_delivery` 一类动作,`action_result.results[*]` 现在可额外带 `delivery_ack`,用于表达下游确认层级;首版已稳定提供 Level 1 `status_code`
105- `GET /v1/browser` 会同步暴露当前 `shell_runtime` 和每个 client 最近一次结构化 `action_result`
106- `GET /v1/browser` 的 `policy` 视图也会带 `stale_lease` 默认阈值,以及 target 级别的 `last_activity_*`、`stale_sweep_count`、`last_stale_sweep_*` 诊断字段
107- browser request 的限流窗口、退避和熔断状态现在会持久化到 `artifact.db`;daemon 重启后 `GET /v1/browser` 会恢复上次的风险控制位置,`in_flight / waiting` 仍只代表当前进程内的运行态
108- browser 业务请求不在本节;请改读 [`business-interfaces.md`](./business-interfaces.md) 和 `POST /v1/browser/request`
109
110### 控制动作
111
112| 方法 | 路径 | 作用 |
113| --- | --- | --- |
114| `POST` | `/v1/system/pause` | 切到 `paused` |
115| `POST` | `/v1/system/resume` | 切到 `running` |
116| `POST` | `/v1/system/drain` | 切到 `draining` |
117
118system 控制约定:
119
120- `POST /v1/system/pause` 只切系统级 gate,不改各对话已有 `automation_status`、`pause_reason` 或 `last_non_paused_automation_status`
121- system mode 为 `paused` 时,普通 BAA 指令会在 live ingest 中记录为 `system_paused`,不会进入实际执行
122- system mode 为 `paused` 时,timed-jobs 整个 tick 会在调度层跳过,并写出 `skipped_system_paused`
123- `POST /v1/system/resume` 只恢复系统级 gate;已经是 `manual` 或 `paused` 的对话不会被自动改回 `auto`
124
125### 续命自动化控制
126
127| 方法 | 路径 | 作用 |
128| --- | --- | --- |
129| `POST` | `/v1/renewal/conversations/:local_conversation_id/manual` | 将指定本地对话切到 `manual`,停止自动生成和推进续命 |
130| `POST` | `/v1/renewal/conversations/:local_conversation_id/auto` | 将指定本地对话切到 `auto`,允许 projector / dispatcher 继续推进 |
131| `POST` | `/v1/renewal/conversations/:local_conversation_id/paused` | 将指定本地对话切到 `paused`,保留对话和任务,但暂停自动执行;可选 body `{"pause_reason":"user_pause"}` |
132
133续命控制约定:
134
135- 先通过业务读面查看当前状态:
136 - `GET /v1/renewal/conversations/:local_conversation_id`
137 - `GET /v1/renewal/jobs?local_conversation_id=...`
138- `paused` 不会删除任务,只会阻止 dispatcher 继续推进待执行 job
139- `manual` 和 `auto` / `paused` 共用同一份 `local_conversations` 后端状态,不存在插件侧单独影子开关
140- renewal REST 写接口修改状态后,browser bridge 的 `state_snapshot.browser.automation_conversations` 会在下一轮 WS 推送中同步更新,供浮层实时刷新
141- conductor 启动时会自动清理上次异常退出遗留的 `execution_state`,并把 `status=running` 的 renewal job 重新排回 `pending`
142- `GET /v1/renewal/conversations/:local_conversation_id` 现在会额外暴露:
143 - `pause_reason`
144 - `last_error`
145 - `execution_state`(`idle / instruction_running / renewal_running`)
146 - `consecutive_failure_count`
147 - `repeated_message_count`
148 - `repeated_renewal_count`
149- conductor 内部现在也支持最小显式控制指令入口:
150 - `@conductor::conversation/pause::{"scope":"current","reason":"rescue_wait"}`
151 - `@conductor::conversation/resume::{"scope":"current"}`
152 - `@conductor::conversation/mode::{"scope":"current","mode":"auto"}`
153 - `@conductor::system/pause`
154 - `@conductor::system/resume`
155- system paused 时仍允许显式 system 控制指令通过,以便后续 final-message 可发出 `@conductor::system/resume`
156
157### 本机 Host Ops
158
159| 方法 | 路径 | 作用 |
160| --- | --- | --- |
161| `POST` | `/v1/exec` | 在当前节点执行 shell 命令,返回结构化 stdout/stderr |
162| `POST` | `/v1/files/read` | 读取当前节点文本文件 |
163| `POST` | `/v1/files/write` | 写入当前节点文本文件,支持 `overwrite` / `createParents` |
164
165鉴权要求:
166
167- header:`Authorization: Bearer <BAA_SHARED_TOKEN>`
168- token 来源:daemon 启动时配置的 `BAA_SHARED_TOKEN`
169- 未授权请求会在进入 host-ops 前直接返回 `401`
170
171输入语义:
172
173- `cwd`:省略时使用 daemon 进程当前工作目录
174- `path`:可为绝对路径,也可相对 `cwd`
175- `timeoutMs`:仅 `/v1/exec` 使用,默认 `30000`
176- `overwrite`:仅 `/v1/files/write` 使用,默认 `true`
177- `POST /v1/exec` 在成功和失败时都返回稳定的 `data.result`;失败时 AI caller 也可以直接依赖 `stdout`、`stderr`、`exitCode`、`signal`、`durationMs`、`startedAt`、`finishedAt`、`timedOut`
178
179### 低层诊断
180
181| 方法 | 路径 | 作用 |
182| --- | --- | --- |
183| `GET` | `/healthz` | 最小健康探针 |
184| `GET` | `/readyz` | readiness 探针 |
185| `GET` | `/rolez` | 当前角色视图 |
186| `GET` | `/v1/runtime` | 本地运行时快照 |
187
188## 推荐给 AI 的调用顺序
189
190### 先看 describe
191
192```bash
193BASE_URL="http://100.71.210.78:4317"
194curl "${BASE_URL}/describe/control"
195```
196
197### 再看 capabilities
198
199```bash
200BASE_URL="http://100.71.210.78:4317"
201curl "${BASE_URL}/v1/capabilities"
202```
203
204### 再看当前 system state
205
206```bash
207BASE_URL="http://100.71.210.78:4317"
208curl "${BASE_URL}/v1/system/state"
209```
210
211### 需要时先看 browser/plugin 状态
212
213```bash
214BASE_URL="http://100.71.210.78:4317"
215curl "${BASE_URL}/v1/browser?platform=claude"
216```
217
218### 最后再执行控制动作
219
220```bash
221BASE_URL="http://100.71.210.78:4317"
222curl -X POST "${BASE_URL}/v1/browser/actions" \
223 -H 'Content-Type: application/json' \
224 -d '{"action":"tab_open","platform":"claude"}'
225```
226
227```bash
228BASE_URL="http://100.71.210.78:4317"
229curl -X POST "${BASE_URL}/v1/system/pause" \
230 -H 'Content-Type: application/json' \
231 -d '{"requested_by":"web_ai","reason":"manual_pause"}'
232```
233
234```bash
235BASE_URL="http://100.71.210.78:4317"
236curl -X POST "${BASE_URL}/v1/system/resume" \
237 -H 'Content-Type: application/json' \
238 -d '{"requested_by":"web_ai","reason":"manual_resume"}'
239```
240
241```bash
242BASE_URL="http://100.71.210.78:4317"
243curl -X POST "${BASE_URL}/v1/system/drain" \
244 -H 'Content-Type: application/json' \
245 -d '{"requested_by":"web_ai","reason":"manual_drain"}'
246```
247
248### 需要时再执行本机 host-ops
249
250```bash
251BASE_URL="http://100.71.210.78:4317"
252SHARED_TOKEN="${BAA_SHARED_TOKEN:?set BAA_SHARED_TOKEN}"
253curl -X POST "${BASE_URL}/v1/exec" \
254 -H "Authorization: Bearer ${SHARED_TOKEN}" \
255 -H 'Content-Type: application/json' \
256 -d '{"command":"printf '\''hello from conductor'\''","cwd":"/tmp","timeoutMs":2000}'
257```
258
259```bash
260BASE_URL="http://100.71.210.78:4317"
261SHARED_TOKEN="${BAA_SHARED_TOKEN:?set BAA_SHARED_TOKEN}"
262curl -X POST "${BASE_URL}/v1/files/write" \
263 -H "Authorization: Bearer ${SHARED_TOKEN}" \
264 -H 'Content-Type: application/json' \
265 -d '{"path":"tmp/demo.txt","cwd":"/Users/george/code/baa-conductor","content":"hello from conductor","overwrite":false,"createParents":true}'
266```
267
268## 给 CLI / 网页版 AI 的推荐提示
269
270```text
271先阅读控制类接口文档,再请求 /describe/control、/v1/capabilities,并在需要时查看 /v1/browser 和 /v1/system/state。
272只有在确认当前状态后,才执行 /v1/browser/actions、pause / resume / drain;如果要做本机 shell / 文件操作,也先看 host_operations,并带上 Authorization: Bearer <BAA_SHARED_TOKEN>。
273```
274
275## 当前边界
276
277- 当前控制面是单节点 `mini`
278- 控制动作默认作用于当前唯一活动节点
279- browser/plugin 管理动作已经纳入 control;当前正式支持 `request_credentials`、`tab_open`、`tab_focus`、`tab_reload`、`plugin_status`、`ws_reconnect`、`controller_reload`、`tab_restore`
280- 当前 `/v1/browser/actions` 返回结构化插件动作结果;`GET /v1/browser` 会继续提供最新 `shell_runtime` 和最近一次 `action_result` 读面
281- Codex 会话能力不在本文件主讨论范围;它通过 `/v1/codex/*` 代理到独立 `codexd`
282- 业务查询不在本文件讨论范围内
283- 业务类接口见 [`business-interfaces.md`](./business-interfaces.md)