主题
Chrome Extension API
本文引用的源码文件
本文引用的文件
目录
引言
本文面向 Chrome Extension(Manifest V3)扩展端与独立 Agent 端的通信契约,聚焦以下目标:
- 说明扩展端与 Agent 端的消息通信接口,包括
chrome.runtime.sendMessage、chrome.runtime.onMessage的使用方式。 - 解释 Service Worker 生命周期管理:保活机制、状态持久化、事件监听与自动续跑。
- 说明 Content Script 注入机制和页面工具调用接口。
- 解释权限管理系统:
manifest.json中的权限声明与运行时权限检查。 - 给出消息路由表结构、请求/响应格式规范与错误处理模式。
- 提供从 Content Script 调用 Background 功能的实际流程示例,并说明异步消息传递的处理方式。
本项目采用双进程架构:Chrome 扩展端(MV3,src/ 目录,版本 2.3.1)+ 独立本地代理端 Agent(Node.js,agent/src/server.js 入口,npm 包名 ai-helper-agent,版本 2.3.1)。两端版本号保持同步;Agent 源码修改后必须重启进程,新接口才生效。
项目结构
扩展端以 MV3 Service Worker 为后台进程,Content Script 注入到所有页面,Side Panel 作为用户交互面板,Options 页面用于配置 Agent 连接。Agent 端通过 HTTP/WebSocket 暴露文件系统、命令执行、MCP 工具、RAG 知识库等能力。
graph TB subgraph "浏览器扩展端" SW["Service Worker<br/>src/background/index.js"] CS["Content Script<br/>src/content/index.js"] SP["Side Panel<br/>side_panel.html"] OPT["Options 页面<br/>src/options/index.js"] MAN["清单 manifest.json"] end subgraph "Agent 端" AG_HTTP["HTTP API<br/>/api/*"] AG_WS["WebSocket<br/>/api/exec/stream"] end MAN --> SW CS --> |chrome.runtime.sendMessage/onMessage| SW SP --> |chrome.runtime.sendMessage/onMessage| SW OPT --> |chrome.runtime.sendMessage/onMessage| SW SW --> |fetch + Bearer Token| AG_HTTP SW --> |WebSocket + token| AG_WS
图表来源
- manifest.json#L1-L76
- src/background/index.js#L900-L1200
- src/content/index.js#L74-L247
- src/background/local-agent-client.js#L40-L93
章节来源
核心组件
- Service Worker 入口:统一注册消息路由、侧边栏行为、快捷键、保活心跳、自动续跑、Agent 健康检查。
- Content Script 路由:将页面读取、交互、提取、媒体输出等能力封装为消息处理器,供 Background 或 Side Panel 调用。
- Agent 客户端:封装与 Agent 的 HTTP/WebSocket 通信,负责配对、认证、文件操作、命令执行、MCP、RAG 等。
- 权限与注入:由
manifest.json声明权限与 content_scripts 匹配规则,Background 在需要时动态注入 Content Script。
章节来源
- src/background/index.js#L1-L2306
- src/content/index.js#L1-L391
- src/background/local-agent-client.js#L1-L800
- manifest.json#L1-L76
架构总览
扩展端与 Agent 端的核心通信路径如下:
- 扩展内部:Content Script / Side Panel / Options → Background(
chrome.runtime.sendMessage/chrome.runtime.onMessage)。 - 扩展到 Agent:Background → Agent HTTP
/api/*与 WebSocket/api/exec/stream,携带 Bearer Token。 - 页面工具:Background 通过
chrome.tabs.sendMessage向指定 tab 的 Content Script 发送指令,Content Script 返回 DOM 操作结果。
sequenceDiagram
participant CS as "Content Script"
participant BG as "Background (SW)"
participant SP as "Side Panel"
participant OPT as "Options"
participant AG as "Agent HTTP/WebSocket"
CS->>BG : sendMessage({type, payload})
BG-->>CS : sendResponse(...) 或 推送 API_ERROR/API_COMPLETE
SP->>BG : sendMessage({type, payload})
OPT->>BG : sendMessage({type, payload})
BG->>AG : fetch("/api/*", Authorization : Bearer)
BG->>AG : WebSocket(token)
AG-->>BG : JSON 结果 / 流式事件
BG-->>SP : runtime.sendMessage(状态/结果)
BG-->>OPT : runtime.sendMessage(状态/结果)
图表来源
- src/background/index.js#L900-L1200
- src/background/local-agent-client.js#L399-L443
- src/options/index.js#L2145-L2193
详细组件分析
1. 消息通信接口:chrome.runtime.sendMessage 与 chrome.runtime.onMessage
Background 使用 chrome.runtime?.onMessage?.addListener 统一接收来自 Content Script、Side Panel、Options 的消息,并通过 message.type 进行路由。部分处理器直接 sendResponse,部分处理器返回 true 表示异步响应,或通过 chrome.runtime.sendMessage 主动推送状态。
- Content Script 到 Background:Content Script 通过
chrome.runtime.sendMessage发起页面工具调用,Background 转发到具体 tab 的 Content Script,或直接执行业务逻辑。 - Side Panel 到 Background:Side Panel 发起会话控制、上下文压缩、RAG 查询、MCP 重载等操作。
- Options 到 Background:Options 通知 Background 打开/关闭配置页,触发全量 Agent 心跳,并订阅
AGENT_STATUS_CHANGE。
章节来源
2. Service Worker 生命周期管理:保活、持久化与事件监听
MV3 Service Worker 存在空闲被终止的硬约束。项目实现了两层保活:
- 任务级保活心跳:在 ReAct 循环执行期间周期性调用轻量扩展 API,重置闲置计时器,避免静默间隙导致 SW 被杀。
- 自动续跑闹钟:主任务执行期注册
chrome.alarms,SW 被系统回收后由闹钟唤醒,扫描残留 checkpoint 自动续跑,直到达到最大尝试次数。
此外,Background 还维护:
- keepalive port:Side Panel 通过长连接保活,防止 API 调用期间 SW 被判定空闲。
- checkpoint 持久化:ReAct 中间状态写入 IndexedDB,支持恢复、过期清理。
- 事件监听:tabs、windows、tabGroups、sidePanel、commands、storage 等事件驱动 UI 与状态同步。
flowchart TD
Start(["SW 启动"]) --> InitAlarms["重建定时任务闹钟"]
InitAlarms --> Keepalive["注册 keepalive port"]
Keepalive --> ReactLoop["进入 reactLoop"]
ReactLoop --> Heartbeat["任务级保活心跳"]
Heartbeat --> Checkpoint["保存 ReAct checkpoint"]
Checkpoint --> Alarm["注册自动续跑闹钟"]
Alarm --> SystemKill{"SW 被系统回收?"}
SystemKill --> |是| AlarmWake["闹钟唤醒 SW"]
AlarmWake --> ResumeScan["扫描残留 checkpoint"]
ResumeScan --> Decide{"是否可自动续跑?"}
Decide --> |是| ResumeTask["恢复执行"]
Decide --> |否| NotifyExhausted["通知人工介入"]
SystemKill --> |否| Continue["继续执行"]
ResumeTask --> End(["完成/失败"])
Continue --> End
NotifyExhausted --> End
图表来源
- src/background/index.js#L56-L81
- src/background/react-loop.js#L728-L746
- src/background/auto-resume.js#L1-L59
章节来源
- src/background/index.js#L56-L81
- src/background/react-loop.js#L728-L746
- src/background/auto-resume.js#L1-L59
- src/background/state.js#L278-L318
3. Content Script 注入机制与页面工具调用接口
Content Script 通过 manifest.json 的 content_scripts 声明全局注入,匹配 <all_urls>,在所有帧中运行。其内部维护一个 Map 路由表,按 message.type 分发到页面读取、交互、提取、媒体输出等处理器。
- 同步处理器:直接返回结果,Background 收到后立即
sendResponse。 - 异步处理器:返回 Promise 或在
ASYNC_HANDLERS集合中标记,Background 需保持通道开放,等待 Promise resolve 后回复。 - 顶层帧限制:部分工具只在顶层 frame 响应,避免 iframe 覆盖主页面内容。
flowchart TD
Enter(["Background 发送 chrome.tabs.sendMessage"]) --> Lookup["查找 HANDLERS[message.type]"]
Lookup --> HandlerFound{"找到处理器?"}
HandlerFound --> |否| Ignore["忽略消息"]
HandlerFound --> |是| RunHandler["执行 handler(message)"]
RunHandler --> AsyncCheck{"是否异步?"}
AsyncCheck --> |是| AwaitPromise["Promise.then(sendResponse)"]
AsyncCheck --> |否| SendSync["sendResponse(result)"]
AwaitPromise --> Exit(["结束"])
SendSync --> Exit
Ignore --> Exit
图表来源
章节来源
4. 权限管理系统:manifest.json 与运行时权限检查
manifest.json 声明了扩展所需权限与主机权限,包括 activeTab、storage、scripting、sidePanel、debugger、webNavigation 等。Content Security Policy 限制扩展页面的脚本来源。
- 权限声明:permissions 与 host_permissions 控制扩展对浏览器 API 与网页资源的访问范围。
- 运行时检查:Background 在调用可能失败的 API 时使用可选链与 try/catch 降级,避免 SW 终止竞态导致整体初始化中断。
- CSP 限制:extension_pages 仅允许
'self'脚本与对象资源,防止注入不可信代码。
章节来源
5. 消息路由表结构与请求/响应格式规范
Background 的消息路由以 message.type 为核心键,常见类型包括:
- 会话控制:
CALL_API、RESUME_REACT、CANCEL_REACT、TERMINATE_COMMAND、ABORT_CURRENT_TOOL - 配置与状态:
GET_SESSION、GET_CHAT_CONFIG、TRIGGER_AGENT_HEALTH_CHECK、AGENT_CONNECTION_CHANGED - 页面工具:
IFRAME_SELECTION、IFRAME_CLICK_DISMISS、IFRAME_SELECTION_CLEAR - RAG/MCP:
RELOAD_MCP_TOOLS、RELOAD_RAG_TOOLS、RAG_LIST_COLLECTIONS、RAG_SEARCH - 上下文压缩:
COMPACT_CONTEXT_SUMMARY - 原型文件:
OPEN_LOCAL_PROTOTYPE、DELETE_LOCAL_PROTOTYPE
请求/响应规范:
- 请求体:通常包含
type与业务字段(如sessionId、callId、params)。 - 响应体:同步处理器通过
sendResponse返回;异步处理器通过chrome.runtime.sendMessage推送API_COMPLETE、API_ERROR、EXECUTION_STATUS_UPDATE等。 - 错误体:统一包含
success、error、httpStatus(Agent 层)、executionLog(截断后)。
章节来源
6. 错误处理模式
- 网络错误映射:前端将
Failed to fetch、Load failed、NetworkError等映射为“网络错误”提示。 - 超时错误:Agent 客户端将
AbortError映射为“请求超时”,携带超时时长。 - 非网络错误:包装为“请求失败”,附带原始错误信息。
- SW 终止竞态:Background 对
chrome.*API 调用使用可选链保护,避免 SW 即将终止时抛错导致模块加载失败。 - Content Script 上下文失效:全局捕获
Extension context invalidated错误与未拒绝 Promise,防止控制台噪音。
章节来源
- test/unit/chat-manager-error-msg.unit.test.js#L63-L89
- src/background/local-agent-client.js#L436-L443
- src/content/index.js#L249-L262
7. 从 Content Script 调用 Background 功能的实际流程
以下流程展示如何从 Content Script 调用 Background 功能,并处理异步消息传递:
sequenceDiagram
participant CS as "Content Script"
participant BG as "Background (SW)"
participant TAB_CS as "目标 Tab 的 Content Script"
CS->>BG : sendMessage({type : 'QUERY_ELEMENTS', selector : '...'})
BG->>TAB_CS : tabs.sendMessage({type : 'QUERY_ELEMENTS', ...})
TAB_CS-->>BG : sendResponse({elements : [...]})
BG-->>CS : sendResponse({elements : [...]})
若目标 Tab 的 Content Script 尚未注入,Background 会先调用 chrome.scripting.executeScript 注入,再重试发送消息,最多三次指数退避。
图表来源
章节来源
依赖关系分析
- Background 依赖:state.js(keepalive 端口与身份)、react-loop.js(ReAct 循环与心跳)、auto-resume.js(自动续跑)、local-agent-client.js(Agent 通信)、notifier.js(通知)、scheduler.js(闹钟恢复)。
- Content Script 依赖:page-tools.js、page-interaction.js、page-extract.js、interaction-tools.js、advanced-tools.js、shadow-dom-utils.js、selection-toolbar.js。
- Options 依赖:background 消息广播(
AGENT_STATUS_CHANGE)、Agent 配对状态管理。
graph LR BG["Background"] --> STATE["state.js"] BG --> RL["react-loop.js"] BG --> AR["auto-resume.js"] BG --> LAC["local-agent-client.js"] BG --> NOT["notifier.js"] BG --> SCH["scheduler.js"] CS["Content Script"] --> PT["page-tools.js"] CS --> PI["page-interaction.js"] CS --> PE["page-extract.js"] CS --> IT["interaction-tools.js"] CS --> AT["advanced-tools.js"] OPT["Options"] --> BG
图表来源
章节来源
性能与保活特性
- 消息大小限制:Background 对日志条目进行截断,避免超过
chrome.runtime.sendMessage的 64MiB 限制。 - 工具预筛选:根据上下文预筛选 MCP/RAG 工具,减少无效调用。
- 缓存机制:MCP 工具列表、Skill Prompts 等缓存,避免重复网络请求。
- 保活心跳:任务执行期间每 20s 调用轻量 API,防止 SW 被杀。
- 自动续跑:闹钟唤醒后扫描 checkpoint,最多尝试 3 次,超限后通知人工介入。
章节来源
- src/background/index.js#L97-L113
- src/background/react-loop.js#L728-L746
- src/background/auto-resume.js#L1-L59
故障排查指南
- SW 被杀导致任务中断:检查是否处于 ReAct 循环执行期,确认 keepalive port 与自动续跑闹钟是否正常。
- Content Script 注入失败:检查
chrome.scripting.executeScript是否成功,查看重试逻辑与指数退避。 - Agent 连接失败:检查配对状态、Token 有效性、网络可达性,查看
AGENT_CONNECTION_CHANGED消息。 - 消息无响应:确认
message.type是否在路由表中,检查异步处理器是否正确返回true或 Promise。 - 权限不足:核对
manifest.json中 permissions 与 host_permissions,确认 CSP 未阻止脚本加载。
章节来源
- src/background/index.js#L136-L140
- src/background/tool-helpers.js#L424-L451
- src/options/index.js#L2145-L2193
结论
本项目的 Chrome Extension API 设计围绕 MV3 Service Worker 的生命周期约束展开,通过 keepalive port、任务级心跳与自动续跑闹钟保障长任务稳定性。Content Script 提供丰富的页面工具接口,Background 统一路由并转发到 Agent 端。权限声明与运行时检查确保扩展安全可控。消息路由表清晰,错误处理模式统一,便于扩展与维护。