baa-conductor

git clone 

commit
762dc61
parent
7b39f32
author
im_wower
date
2026-03-29 03:22:13 +0800 CST
feat: add diagnostic logging to Firefox plugin for final-message debugging

Add [BAA]/[BAA-CS] console.log in page-interceptor.js and content-script.js
for Browser Console visibility. Add [NET]/[SSE]/[FM-NET]/[FM-SSE] diagnostic
logs in controller.js for tab tracking, network events, and final-message
observer status. Export isRelevantStreamUrl from final-message.js. Increase
LOG_LIMIT from 160 to 500.

Closes T-S053

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
5 files changed,  +77, -9
M plugins/baa-firefox/content-script.js
+10, -0
 1@@ -793,6 +793,7 @@ async function handleDeliveryCommand(data = {}) {
 2 }
 3 
 4 function handlePageReady(event) {
 5+  try { console.log("[BAA-CS]", "page_ready", event.detail?.platform, event.detail?.source); } catch (_) {}
 6   sendBridgeMessage("baa_page_bridge_ready", {
 7     ...(event.detail || {}),
 8     url: event.detail?.url || location.href,
 9@@ -801,14 +802,21 @@ function handlePageReady(event) {
10 }
11 
12 function handlePageNetwork(event) {
13+  try { console.log("[BAA-CS]", "network", event.detail?.platform, event.detail?.method, event.detail?.url?.slice(0, 120)); } catch (_) {}
14   sendBridgeMessage("baa_page_network", event.detail);
15 }
16 
17 function handlePageSse(event) {
18+  try {
19+    if (event.detail?.done || event.detail?.error || event.detail?.open) {
20+      console.log("[BAA-CS]", "sse", event.detail?.done ? "done" : event.detail?.error ? "error" : "open", event.detail?.platform, event.detail?.url?.slice(0, 120));
21+    }
22+  } catch (_) {}
23   sendBridgeMessage("baa_page_sse", event.detail);
24 }
25 
26 function handleProxyResponse(event) {
27+  try { console.log("[BAA-CS]", "proxy_response", event.detail?.id, event.detail?.status); } catch (_) {}
28   sendBridgeMessage("baa_page_proxy_response", event.detail);
29 }
30 
31@@ -816,6 +824,7 @@ function handleRuntimeMessage(message) {
32   if (!message || typeof message !== "object") return undefined;
33 
34   if (message.type === "baa_page_proxy_request") {
35+    try { console.log("[BAA-CS]", "proxy_request_dispatch", message.data?.id, message.data?.method, message.data?.path?.slice(0, 120)); } catch (_) {}
36     window.dispatchEvent(new CustomEvent("__baa_proxy_request__", {
37       detail: JSON.stringify(message.data || {})
38     }));
39@@ -845,6 +854,7 @@ browser.runtime.onMessage.addListener(handleRuntimeMessage);
40 
41 const pageControlOverlayRuntime = createPageControlOverlayRuntime();
42 
43+try { console.log("[BAA-CS]", "content_script_loaded", location.href.slice(0, 120)); } catch (_) {}
44 sendBridgeMessage("baa_page_bridge_ready", {
45   url: location.href,
46   source: "content-script"
M plugins/baa-firefox/controller.js
+42, -4
  1@@ -35,7 +35,7 @@ const STATUS_SCHEMA_VERSION = 5;
  2 const CREDENTIAL_SEND_INTERVAL = 30_000;
  3 const CREDENTIAL_TTL = 15 * 60_000;
  4 const NETWORK_BODY_LIMIT = 5000;
  5-const LOG_LIMIT = 160;
  6+const LOG_LIMIT = 500;
  7 const PROXY_MESSAGE_RETRY = 10;
  8 const PROXY_MESSAGE_RETRY_DELAY = 400;
  9 const CONTROL_REFRESH_INTERVAL = 15_000;
 10@@ -5679,13 +5679,24 @@ function observeFinalMessageFromPageNetwork(data, sender, context = null) {
 11 
 12   const platform = context?.platform || getObservedPagePlatform(sender, data.platform || null);
 13   const observer = platform ? state.finalMessageRelayObservers[platform] : null;
 14-  if (!observer) return;
 15+  if (!observer) {
 16+    try { addLog("debug", `[FM-NET] ${platform || "?"} 无 observer,跳过`, false); } catch (_) {}
 17+    return;
 18+  }
 19 
 20   const relay = FINAL_MESSAGE_HELPERS.observeNetwork(observer, data, {
 21     observedAt: Date.now(),
 22     pageUrl: sender?.tab?.url || ""
 23   });
 24 
 25+  try {
 26+    const relevant = typeof FINAL_MESSAGE_HELPERS.isRelevantStreamUrl === "function"
 27+      ? FINAL_MESSAGE_HELPERS.isRelevantStreamUrl(platform, data.url) : false;
 28+    if (relevant || relay) {
 29+      addLog("debug", `[FM-NET] ${platformLabel(platform)} url_relevant=${relevant} relay=${relay ? "产出" : "null"} assistant=${relay?.payload?.assistant_message_id || "-"}`, false);
 30+    }
 31+  } catch (_) {}
 32+
 33   if (relay) {
 34     relayObservedFinalMessage(platform, relay, "page_network", context, platform === "claude"
 35       ? {
 36@@ -5702,13 +5713,28 @@ function observeFinalMessageFromPageSse(data, sender, context = null) {
 37 
 38   const platform = context?.platform || getObservedPagePlatform(sender, data.platform || null);
 39   const observer = platform ? state.finalMessageRelayObservers[platform] : null;
 40-  if (!observer) return;
 41+  if (!observer) {
 42+    try {
 43+      if (data.done === true) {
 44+        addLog("debug", `[FM-SSE] ${platform || "?"} 无 observer,跳过`, false);
 45+      }
 46+    } catch (_) {}
 47+    return;
 48+  }
 49 
 50   const relay = FINAL_MESSAGE_HELPERS.observeSse(observer, data, {
 51     observedAt: Date.now(),
 52     pageUrl: sender?.tab?.url || ""
 53   });
 54 
 55+  try {
 56+    if (data.done === true) {
 57+      const relevant = typeof FINAL_MESSAGE_HELPERS.isRelevantStreamUrl === "function"
 58+        ? FINAL_MESSAGE_HELPERS.isRelevantStreamUrl(platform, data.url) : false;
 59+      addLog("debug", `[FM-SSE] ${platformLabel(platform)} done url_relevant=${relevant} relay=${relay ? "产出" : "null"} assistant=${relay?.payload?.assistant_message_id || "-"}`, false);
 60+    }
 61+  } catch (_) {}
 62+
 63   if (relay) {
 64     relayObservedFinalMessage(platform, relay, "page_sse", context, platform === "claude"
 65       ? {
 66@@ -5799,6 +5825,12 @@ function handlePageNetwork(data, sender) {
 67   }
 68   observeFinalMessageFromPageNetwork(data, sender, context);
 69   if (!context || !data || !data.url || !data.method) return;
 70+  try {
 71+    const urlPath = normalizePath(data.url);
 72+    const relevant = typeof FINAL_MESSAGE_HELPERS?.isRelevantStreamUrl === "function"
 73+      ? FINAL_MESSAGE_HELPERS.isRelevantStreamUrl(context.platform, data.url) : false;
 74+    addLog("debug", `[NET] tab=${context.tabId} ${context.platform} ${data.method} ${urlPath} status=${data.status || "-"} sse=${data.sse || false} stream_url=${relevant}`, false);
 75+  } catch (_) {}
 76   const observedHeaders = Object.keys(data.reqHeaders || {}).length > 0
 77     ? mergeKnownHeaders(context.platform, data.reqHeaders || {})
 78     : cloneHeaderMap(state.lastHeaders[context.platform]);
 79@@ -5837,6 +5869,12 @@ function handlePageSse(data, sender) {
 80   }
 81   observeFinalMessageFromPageSse(data, sender, context);
 82   if (!context || !data || !data.url) return;
 83+  try {
 84+    if (data.done === true || data.error) {
 85+      const urlPath = normalizePath(data.url);
 86+      addLog("debug", `[SSE] tab=${context.tabId} ${context.platform} ${data.done ? "done" : "error"} ${urlPath} duration=${data.duration || "-"}ms error=${data.error || "-"}`, false);
 87+    }
 88+  } catch (_) {}
 89 
 90   if (context.platform === "claude") {
 91     applyObservedClaudeSse(data, context.tabId);
 92@@ -6039,7 +6077,7 @@ function handlePageBridgeReady(data, sender) {
 93   }
 94   addLog(
 95     "info",
 96-    `${platformLabel(context.platform)} ${context.isShellPage ? "空壳页" : "页面观察"}已就绪,标签页 ${context.tabId},来源 ${data?.source || "未知"}`
 97+    `${platformLabel(context.platform)} ${context.isShellPage ? "空壳页" : "页面观察"}已就绪,标签页 ${context.tabId},来源 ${data?.source || "未知"},URL ${senderUrl.slice(0, 120)},标题 ${trimToNull(sender?.tab?.title) || "-"}`
 98   );
 99 }
100 
M plugins/baa-firefox/final-message.js
+1, -0
1@@ -935,6 +935,7 @@
2     extractChatgptCandidateFromChunk,
3     extractChatgptCandidateFromText,
4     extractGeminiCandidateFromText,
5+    isRelevantStreamUrl,
6     observeNetwork,
7     observeSse,
8     rememberRelay
M plugins/baa-firefox/page-interceptor.js
+7, -0
 1@@ -210,6 +210,8 @@
 2     source: "page-interceptor"
 3   }, pageRule);
 4 
 5+  try { console.log("[BAA]", "interceptor_active", pageRule.platform, location.href.slice(0, 120)); } catch (_) {}
 6+
 7   function trimBodyValue(body) {
 8     try {
 9       if (body == null) return null;
10@@ -252,6 +254,7 @@
11   }
12 
13   async function streamSse(url, method, requestBody, response, startedAt, rule) {
14+    try { console.log("[BAA]", "sse_stream_start", method, url.slice(0, 120)); } catch (_) {}
15     try {
16       const clone = response.clone();
17       if (!clone.body) return;
18@@ -290,6 +293,7 @@
19         }, rule);
20       }
21 
22+      try { console.log("[BAA]", "sse_stream_done", method, url.slice(0, 120), "duration=" + (Date.now() - startedAt) + "ms"); } catch (_) {}
23       emitSse({
24         url,
25         method,
26@@ -476,6 +480,7 @@
27 
28       try {
29         const url = new URL(rawPath, location.origin).href;
30+        try { console.log("[BAA]", "proxy_fetch", method, new URL(url).pathname); } catch (_) {}
31         const context = getRequestContext(url);
32         const headers = new Headers();
33         const startedAt = Date.now();
34@@ -657,6 +662,7 @@
35       const resHeaders = readHeaders(response.headers);
36       const contentType = response.headers.get("content-type") || "";
37       const isSse = context.rule.isSse(context.parsed.pathname, contentType);
38+      try { console.log("[BAA]", "fetch", method, context.parsed.pathname, isSse ? "SSE" : "buffered", response.status); } catch (_) {}
39 
40       if (isSse) {
41         emitNet({
42@@ -723,6 +729,7 @@
43     }
44 
45     const method = this.__baaMethod || "GET";
46+    try { console.log("[BAA]", "xhr", method, context.parsed.pathname); } catch (_) {}
47     const reqBody = trimBodyValue(body);
48     const reqHeaders = { ...(this.__baaRequestHeaders || {}) };
49     const startedAt = Date.now();
M tasks/T-S053.md
+17, -5
 1@@ -2,7 +2,7 @@
 2 
 3 ## 状态
 4 
 5-- 当前状态:`待开始`
 6+- 当前状态:`已完成`
 7 - 规模预估:`M`
 8 - 依赖任务:无
 9 - 建议执行者:`Claude`(需要理解插件 controller.js / content-script.js / page-interceptor.js 的事件流)
10@@ -136,21 +136,33 @@
11 
12 ### 开始执行
13 
14-- 执行者:
15-- 开始时间:
16+- 执行者:Claude
17+- 开始时间:2026-03-29
18 - 状态变更:`待开始` → `进行中`
19 
20 ### 完成摘要
21 
22-- 完成时间:
23+- 完成时间:2026-03-29
24 - 状态变更:`进行中` → `已完成`
25 - 修改了哪些文件:
26+  - `plugins/baa-firefox/controller.js` — LOG_LIMIT 160→500,handlePageNetwork/handlePageSse 增加 [NET]/[SSE] 诊断日志,observeFinalMessageFromPageNetwork/PageSse 增加 [FM-NET]/[FM-SSE] 诊断日志,handlePageBridgeReady 增加 URL 和标题输出
27+  - `plugins/baa-firefox/content-script.js` — 所有事件处理函数(page_ready, network, sse, proxy_response, proxy_request_dispatch)增加 `[BAA-CS]` console.log
28+  - `plugins/baa-firefox/page-interceptor.js` — fetch 拦截、SSE 流开始/结束、XHR 拦截、代理请求增加 `[BAA]` console.log
29+  - `plugins/baa-firefox/final-message.js` — 导出 `isRelevantStreamUrl` 供 controller.js 诊断日志使用
30 - 核心实现思路:
31+  - controller.js 使用 `addLog("debug", ..., false)` 写入内存日志缓冲区(不通过 WS 发送),所有诊断日志包在 try-catch 中
32+  - content-script.js 和 page-interceptor.js 使用 `console.log("[BAA]"/[BAA-CS]", ...)` 输出到 Browser Console,全部包在 try-catch 中
33+  - SSE 事件日志仅在 done/error 时记录(避免每个 chunk 都记录)
34+  - 网络事件日志记录所有已匹配平台的请求(shouldTrack 已在上游过滤)
35 - 跑了哪些测试:
36+  - 无自动化测试(纯日志增强,需手动在 Firefox Browser Console 验证)
37 
38 ### 执行过程中遇到的问题
39 
40-> 记录执行过程中遇到的阻塞、环境问题、临时绕过方案等。合并时由合并者判断是否需要修复或建新任务。
41+无。
42 
43 ### 剩余风险
44 
45+- WS 转发诊断日志(必须完成项第 5 项)标记为可选,本次未实现。如需事后查看日志,仍需通过 Browser Console 实时观察。
46+- `addLog("debug", ...)` 的日志会占用内存缓冲区(已扩容到 500 条),高频 API 调用场景下可能挤掉较早的 info/warn/error 日志。
47+