baa-conductor

git clone 

commit
8936aa7
parent
25be868
author
jiaozhiwang
date
2026-03-27 08:14:29 +0800 CST
docs: add BUG-014, FIX-BUG-014, OPT-001 and update bugs README
4 files changed,  +139, -3
A bugs/BUG-014-ws-reconnect-premature-completed.md
+44, -0
 1@@ -0,0 +1,44 @@
 2+# BUG-014: ws_reconnect 报 completed=true 但实际还没重连
 3+
 4+## 现象
 5+
 6+当 conductor 通过 `POST /v1/browser/actions` 发送 `ws_reconnect` 动作时,插件立刻回传 `action_result` 报告 `completed: true, failed: false`,但实际的 WS 断开和重连在 80ms 后才发生。
 7+
 8+- 哪个模块:`plugins/baa-firefox/controller.js`,`runPluginManagementAction()` 中 `ws_reconnect` 分支
 9+- 返回了什么:`completed: true`
10+- 预期:`completed` 应反映实际执行状态;WS 重连是异步的,不应在执行前就报完成
11+- 复现条件:任何 `ws_reconnect` 调用
12+
13+## 触发路径
14+
15+```text
16+conductor POST /v1/browser/actions {action: "ws_reconnect"}
17+→ firefox-bridge dispatchWithActionResult
18+→ WS → controller.js
19+→ runPluginManagementAction("ws_reconnect")
20+→ setTimeout(() => { closeWsConnection(); connectWs(); }, 80)  ← 非阻塞
21+→ 函数立刻返回 → .then() 发 action_result completed=true
22+→ 80ms 后才真正断开和重连
23+```
24+
25+## 根因
26+
27+`ws_reconnect` 的实际执行被放在 `setTimeout(..., 80)` 里延迟执行,但 `runPluginManagementAction` 在 setTimeout 注册后立刻返回,调用方的 `.then()` 立刻发出 `action_result(completed=true)`。
28+
29+## 影响
30+
31+- 语义不准确:conductor 侧认为重连已完成,但此时 WS 可能还没断开
32+- 如果 conductor 在收到 completed=true 后立刻发送新命令,该命令可能在旧连接上被发出(80ms 窗口内)
33+- 后续自动化调度依赖 completed 语义做决策时可能产生误判
34+
35+## 严重度
36+
37+Low-Medium
38+
39+## 建议修复方向
40+
41+方案 A:让 `ws_reconnect` 返回 `completed: false`,表示动作已接受但异步完成。conductor 侧通过后续 hello 消息确认重连成功。
42+
43+方案 B:把 setTimeout 改为同步执行 closeWsConnection,然后异步 connectWs,在 connectWs 的 onopen 回调里才发 action_result。
44+
45+方案 A 更简单,方案 B 语义更准确。
A bugs/FIX-BUG-014.md
+49, -0
 1@@ -0,0 +1,49 @@
 2+# FIX-BUG-014: ws_reconnect 提前报 completed=true
 3+
 4+## 关联 Bug
 5+
 6+BUG-014-ws-reconnect-premature-completed.md
 7+
 8+## 目标
 9+
10+让 `ws_reconnect` 的 `action_result` 准确反映执行状态。
11+
12+## 修改文件
13+
14+`plugins/baa-firefox/controller.js`
15+
16+## 修改方案(推荐方案 A)
17+
18+在 `runPluginManagementAction` 的 ws_reconnect 分支中,让返回的 results 携带一个标记,使 `sendPluginActionResult` 生成 `completed: false`:
19+
20+```javascript
21+case "ws_reconnect":
22+  addLog("info", "正在重连本地 WS", false);
23+  setTimeout(() => {
24+    closeWsConnection();
25+    connectWs({ silentWhenDisabled: true });
26+  }, 80);
27+  break;
28+```
29+
30+在 `connectWs` 的 WS message handler 中,ws_reconnect 的 `.then()` 改为:
31+
32+```javascript
33+}).then((result) => {
34+  sendPluginActionResult(result, {
35+    action: pluginAction.action,
36+    commandType: pluginAction.commandType,
37+    completed: pluginAction.action === "ws_reconnect" ? false : true,
38+    platform: pluginAction.platform,
39+    requestId: pluginAction.requestId
40+  });
41+})
42+```
43+
44+这样 conductor 收到 `completed: false, accepted: true`,知道动作已被接受但需要等后续 hello 确认。
45+
46+## 验收标准
47+
48+1. `ws_reconnect` 返回的 action_result 中 `completed` 为 `false`
49+2. 重连后 conductor 通过 hello 消息确认连接恢复
50+3. 其他 action 不受影响,仍返回 `completed: true`
A bugs/OPT-001-action-result-code-quality.md
+36, -0
 1@@ -0,0 +1,36 @@
 2+# OPT-001: action_result 相关代码质量建议
 3+
 4+日期:2026-03-27
 5+来源:Claude 代码审查 782e4c7
 6+优先级:Low(均不影响功能)
 7+
 8+---
 9+
10+## A. request_id 字段命名风格不一致
11+
12+`BrowserBridgeActionResultSnapshot` 接口中使用 `request_id`(snake_case),但 Firefox 插件发送的 JSON 字段是 `requestId`(camelCase)。
13+
14+当前 `handlePluginActionResult`(firefox-ws.ts)做了归一化,功能正常。
15+
16+建议:接口层统一为 snake_case(与其他 snapshot 接口一致),或在 browser-types.ts 的注释里说明 wire format 是 camelCase、内部 snapshot 是 snake_case。
17+
18+## B. test 文件 buildShellRuntime 定义了两次
19+
20+`apps/conductor-daemon/src/index.test.js` 中:
21+- 模块级 `buildShellRuntime`(~第 498 行):tab_id=321
22+- `createBrowserBridgeStub` 内部 `buildShellRuntime`:tab_id=88
23+
24+两个函数功能基本相同,只是默认值不同。建议合并为一个,通过 overrides 参数区分。
25+
26+## C. dispatchBrowserAction async 错误路径分工
27+
28+`dispatchBrowserAction` 现在是 async,内部有两种错误路径:
29+1. bridge 同步抛出(如 no client)→ 被内部 catch 转为 LocalApiHttpError
30+2. `await dispatch.result` rejection(如 action_timeout)→ 传播到 handleBrowserActions 的 catch
31+
32+逻辑上没 bug,两层 catch 都能正确处理。建议在 `dispatchBrowserAction` 函数头部加一行注释说明:
33+
34+```typescript
35+// Synchronous bridge errors (no client, send failed) are caught below.
36+// Asynchronous result errors (action_timeout, client_disconnected) propagate to the caller.
37+```
M bugs/README.md
+10, -3
 1@@ -5,11 +5,10 @@
 2 - 当前仍需保留记录的 bug
 3 - 一个通用 `BUG-TEMPLATE.md`
 4 - 对应 bug 的修复任务卡
 5+- 优化建议(OPT-XXX)
 6 
 7 ## 已关闭
 8 
 9-按当前工作区状态,这 3 个 bug 都已完成修复,但仍保留文档作为根因与回归记录:
10-
11 1. `BUG-008` — 已随 `BUG-010` 一并修复
12 2. `BUG-009` — 已修复
13 3. `BUG-010` — 已修复
14@@ -21,11 +20,19 @@
15 | BUG-011 | `BUG-011-*.md` | writeHttpResponse drain handler 永久挂起 | Medium-High | FIX-BUG-011.md |
16 | BUG-012 | `BUG-012-*.md` | browser-request-policy waiter 死锁 | Medium | FIX-BUG-012.md |
17 | BUG-013 | `BUG-013-*.md` | stream session timer 未清除 | Low | FIX-BUG-013.md |
18+| BUG-014 | `BUG-014-*.md` | ws_reconnect 提前报 completed=true | Low-Medium | FIX-BUG-014.md |
19+
20+修复优先级:BUG-011 > BUG-012 > BUG-014 > BUG-013
21+
22+## 优化建议
23 
24-修复优先级:BUG-011 > BUG-012 > BUG-013
25+| # | 文件 | 内容 |
26+|---|---|---|
27+| OPT-001 | `OPT-001-*.md` | action_result 命名风格、test 重复定义、async 错误路径注释 |
28 
29 ## 编号规则
30 
31 - BUG-XXX:bug 报告
32 - FIX-BUG-XXX:对应修复任务卡(给 Codex 执行)
33+- OPT-XXX:优化建议(非紧急)
34 - 编号按发现顺序递增,不复用