baa-conductor

git clone 

baa-conductor / plans
codex@macbookpro  ·  2026-04-01

UNIFIED_OVERLAY_AUTOMATION_CONTROL.md

  1# 浮层统一自动化控制需求
  2
  3> 日期:2026-03-31
  4> 状态:需求讨论
  5
  6## 背景
  7
  8当前 Firefox 插件右下角浮层控制的是 BAA 指令处理的暂停/恢复。续命系统的对话自动化状态(manual/auto/paused)完全独立,只能通过 REST API 操作。用户无法从浮层上看到或控制续命行为。
  9
 10这两套自动化本质上都是“这个页面/对话是否允许 conductor 自动处理”,应该统一到一个控制入口里;但它们和系统级暂停不是同一层语义,不能压成一个总状态机。
 11
 12同一对话在 SSE 结束后的执行优先级,另见 `AUTOMATION_ARBITRATION_REQUIREMENTS.md` 13
 14## 当前现状
 15
 16### 浮层控制(content-script.js)
 17
 18- 系统级:`running` / `paused` / `draining`,通过 `control_plane_command` → conductor WS
 19- 页面级:`暂停本页` / `恢复本页`,通过 `page_control_command` → conductor WS
 20- 控制目标:BAA 指令提取和执行
 21
 22### 续命控制(renewal/)
 23
 24- 对话级:`manual` / `auto` / `paused`,通过 REST API `/v1/renewal/conversations/:id/auto`
 25- 控制目标:续命 projector 是否为该对话生成 renewal_job
 26
 27### 问题
 28
 29- 用户暂停本页后,BAA 指令停了,但续命还在跑(如果对话是 auto)
 30- 用户通过 API 设了 renewal auto,但浮层上看不到
 31- 两套"暂停"语义不同但用户无法区分
 32
 33## 目标
 34
 35将 BAA 指令处理和续命自动化统一到一个页面/对话级控制入口,从浮层一个位置查看和操作。
 36
 37明确不做的事:
 38
 39- 不把系统级 `running / paused / draining` 和对话级 `manual / auto / paused` 合并成一个状态值
 40- 不让“恢复本页”顺手解除系统级暂停
 41- 不让“系统恢复”顺手修改各对话原有的 `manual / auto / paused`
 42
 43## 分层状态模型
 44
 45### 系统级(保持独立)
 46
 47- `running`
 48- `paused`
 49- `draining`
 50
 51系统级状态继续作为最外层闸门,控制整机自动化是否允许执行。
 52
 53### 页面/对话级(统一控制)
 54
 55页面/对话级继续使用统一自动化状态:
 56
 57- **自动**(auto):BAA 指令正常处理 + 续命系统正常运行
 58- **暂停**(paused):BAA 指令暂停 + 续命系统暂停(不生成新任务,待执行任务不推进,执行中任务自然结束)
 59- **手动**(manual):BAA 指令暂停 + 续命系统不生成任务
 60
 61页面/对话级只回答“当前页面/对话是否允许自动化”;系统级只回答“整个 conductor 现在是否允许自动化”。
 62
 63页面/对话级还需要保留 `pause_reason`,用于区分:
 64
 65- 用户手动暂停
 66- AI 主动暂停
 67- 系统自动熔断暂停
 68- 等待救援
 69
 70## 执行判定顺序
 71
 72执行时按下面顺序判断:
 73
 741. 先看系统级状态
 752. 再看页面/对话级状态
 76
 77也就是:
 78
 79- 系统级 `paused` 时,不管当前对话是 `auto` 还是 `manual / paused`,都统一不执行
 80- 系统级恢复后,再按当前对话自己的 `manual / auto / paused` 决定是否继续
 81
 82## 控制入口
 83
 84### 浮层(首要入口)
 85
 86- 当前“暂停本页”/“恢复本页”按钮改为同时控制页面级 BAA 与 renewal
 87- 浮层同时显示两类状态:
 88  - 系统:运行中 / 系统暂停 / draining
 89  - 当前对话:auto / paused / manual
 90- 当前对话如处于 `paused`,还应显示 `pause_reason`
 91- 按钮文案保持分层:
 92  - 系统级按钮:`系统暂停` / `系统恢复`
 93  - 页面级按钮:`暂停本页` / `恢复本页` / `设为手动`
 94- 点击页面级按钮时,只更新 page_control 和 renewal automation_status,不修改系统级状态
 95
 96### REST API(保留)
 97
 98- `/v1/renewal/conversations/:id/auto` 等接口保留
 99- 但状态变更需要同步到 page_control,保持页面级一致
100- REST API 如果改的是系统级状态,只能改系统级,不碰各对话状态
101
102### BAA 指令(后续)
103
104- 后期可以通过显式 BAA 控制指令控制,例如:
105  - `@conductor::conversation::pause::{"scope":"current","reason":"rescue_wait"}`
106  - `@conductor::conversation::resume::{"scope":"current"}`
107  - `@conductor::conversation::mode::{"scope":"current","mode":"auto"}`
108- 具体仲裁规则见 `AUTOMATION_ARBITRATION_REQUIREMENTS.md`
109
110## 实现要点
111
112### 插件侧
113
114- `content-script.js`:浮层按钮 action 同时发 `page_control_command` 和 renewal 状态切换
115- `controller.js`:收到统一控制指令后,同时更新 page_control state 和向 conductor 发 renewal 状态变更请求
116
117### conductor 侧
118
119- `firefox-ws.ts`:收到页面控制指令时,同步更新 `local_conversations.automation_status`
120- `local-api.ts`:renewal API 状态变更时,同步广播给对应的 WS 连接
121- renewal / instruction 运行态需要能把自动熔断结果同步成 `automation_status + pause_reason`
122- 自动熔断判断应以结构化行为信号为主,以文本模式匹配为辅;不能只靠字符串命中来暂停对话
123
124### 状态同步方向
125
126```
127浮层按钮 → controller → conductor WS → 同时更新 page_control + renewal automation_status
128REST API → conductor → 广播 WS → controller → 浮层刷新
129```
130
131系统级同步方向保持独立:
132
133```
134系统暂停/恢复按钮 or REST API → conductor → 更新 system_state.automation → 广播 WS → 浮层刷新
135```
136
137## 需要注意
138
139- 新对话默认 `manual`,用户必须主动设为 `auto` 才会续命
140- “暂停本页”同时暂停页面级 BAA 和 renewal
141- “恢复本页”只恢复当前对话,不解除系统级暂停
142- “系统恢复”只恢复系统级闸门,不改各对话原有状态
143- 自动熔断暂停属于页面/对话级暂停的一种,必须在浮层上可见,而不是只写日志
144- 如果对话还没有 local_conversation 记录(从没有 final-message),浮层只控制 page_control
145- 系统级暂停仍是独立需求,见 `SYSTEM_LEVEL_PAUSE_REQUIREMENTS.md`
146
147## 验收标准
148
149- 浮层点击"暂停本页"后,BAA 指令和续命同时暂停
150- 浮层点击"恢复本页"后,两者同时恢复
151- 浮层能同时显示系统状态和当前对话状态
152- 自动熔断后,浮层能显示该对话已暂停及暂停原因
153- REST API 修改状态后,浮层能实时反映
154- 不影响现有 BAA 指令主链路