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 指令主链路