主题
内部通信协议
本文引用的源码文件
本文引用的文件
目录
引言
本文档定义 Chrome 扩展端(Manifest V3,src/)与独立本地 Agent 端(Node.js,agent/src/server.js)之间的内部通信协议。版本以仓库当前双端同步的 2.3.1 为准。
Agent 端提供 HTTP 路由与 WebSocket 服务,暴露文件读写、命令执行、MCP 工具调用、Skill 管理、RAG 知识库、长期记忆、审计日志等能力;扩展端通过 src/background/local-agent-client.js 统一封装配对、认证、HTTP 请求、WebSocket 连接和可达性缓存。
重要运行时约束:
- Agent 端源码修改后必须重启进程,新接口才生效。
- 扩展端 Service Worker 存在空闲被终止的生命周期约束,需配合心跳与健康检查保活。
- 所有需要写操作或敏感能力的接口均要求 Bearer Token 认证,仅健康检查和配对接口可免认证访问。
章节来源
项目结构与通信边界
graph TB subgraph "Chrome 扩展端" BG["background/local-agent-client.js<br/>HTTP/WebSocket 客户端"] REACT["background/react-loop.js<br/>ReAct 循环"] TOOL["background/tool-executor.js<br/>工具执行器"] DISPATCH["background/agent-dispatcher.js<br/>子代理调度"] PANEL["side_panel/chat-manager.js<br/>会话与 API 入口"] STREAM["side_panel/chat-streaming.js<br/>流式结果渲染"] INDEX["background/index.js<br/>健康检查/心跳"] end subgraph "Agent 端" SERVER["agent/src/server.js<br/>HTTP + WebSocket 服务器"] EXEC["executor.js<br/>命令执行"] MCP["mcp/registry.js<br/>MCP 工具注册"] MEMORY["memory/routes.js<br/>长期记忆路由"] RAG["rag/routes.js<br/>RAG 路由"] SKILL["skill/registry.js<br/>Skill 管理"] end BG --> SERVER REACT --> BG TOOL --> BG DISPATCH --> REACT PANEL --> REACT STREAM --> PANEL INDEX --> BG SERVER --> EXEC SERVER --> MCP SERVER --> MEMORY SERVER --> RAG SERVER --> SKILL
图表来源
- src/background/local-agent-client.js#L40-L93
- agent/src/server.js#L416-L425
- agent/src/server.js#L2086-L2153
章节来源
- src/background/local-agent-client.js#L40-L93
- agent/src/server.js#L416-L425
- agent/src/server.js#L2086-L2153
核心通信契约总览
扩展端与 Agent 端的通信契约围绕三类通道展开:
| 通道 | 用途 | 关键端点或路径 | 认证方式 |
|---|---|---|---|
| HTTP JSON | 文件、命令、MCP、Skill、RAG、配置、日志、回收站、Agent 管理 | /api/* | 多数接口要求 Authorization: Bearer <token> |
| WebSocket | 命令执行实时输出、半开连接心跳检测 | /ws/exec/<execId>?token=<token> | URL query token 或 Authorization Header |
| 健康与配对 | 插件发现、Agent 在线状态、一次性配对码 | /api/status、/api/pair、/api/heartbeat | 部分免认证,部分需 Bearer Token |
Agent 端统一响应结构为 { success, ... },失败时附带 error;扩展端在 HTTP 层附加 httpStatus,便于区分“Agent 离线”“网络错误”“业务拒绝”。
章节来源
- src/background/local-agent-client.js#L40-L93
- agent/src/server.js#L250-L266
- agent/src/server.js#L471-L548
HTTP 客户端封装与认证
多代理配置与活跃代理
扩展端维护 pairedAgents 数组和 activeAgentId,支持多个已配对 Agent,并通过 getAgentConfig() 获取当前活跃代理的 url、token、agentId。配对成功后,Token 会经过加密存储,读取时再解密。
认证流程
- 扩展端调用
/api/pair,携带code和extensionId。 - Agent 端校验配对码并返回
token。 - 后续所有受保护接口通过
Authorization: Bearer <token>发送。 - Agent 端通过
verifyToken(token)校验扩展 ID,未认证返回401,无效 Token 返回403。
WebSocket 认证
命令执行的 WebSocket 连接优先使用 Authorization Header;由于浏览器原生 new WebSocket() 不支持自定义 Header,扩展端回退到 URL query 参数 ?token=。Agent 端对 WebSocket 同样执行 verifyToken,失败直接关闭连接。
sequenceDiagram
participant Ext as "扩展端"
participant Client as "local-agent-client.js"
participant Server as "agent/src/server.js"
Ext->>Client : "pairWithAgent(agentUrl, pairCode)"
Client->>Server : "POST /api/pair { code, extensionId }"
Server-->>Client : "{ success, token }"
Client->>Client : "保存 pairedAgents + activeAgentId"
Ext->>Client : "agentRequest('/api/fs/read', { path })"
Client->>Server : "GET/POST /api/fs/read<br/>Authorization : Bearer <token>"
Server-->>Client : "{ success, content, httpStatus }"
图表来源
- src/background/local-agent-client.js#L275-L330
- src/background/local-agent-client.js#L399-L443
- agent/src/server.js#L471-L485
- agent/src/server.js#L537-L548
章节来源
- src/background/local-agent-client.js#L185-L212
- src/background/local-agent-client.js#L275-L330
- src/background/local-agent-client.js#L399-L443
- agent/src/server.js#L471-L548
请求、重试与错误处理
基础请求模型
agentRequest(path, body, method, timeoutMs) 是扩展端统一 HTTP 封装:
- 自动注入
Authorization和Accept-Language。 - GET/HEAD 不携带 body。
- 超时使用
AbortController,默认 60 秒,上传和下载有更长超时。 - 成功响应附加
httpStatus,用于区分业务失败和网络失败。 - 捕获
AbortError返回“请求超时”,其他异常返回“Agent 请求失败”。
可达性缓存与快速失败
扩展端维护 _agentReachability Map,按 agentId 缓存可达性:
null:尚未检测。true:可达。false:不可达。
当已知不可达时,agentRequest 和 agentGet 直接返回“代理服务未连接”,避免阻塞等待超时。
重试机制现状
当前代码中未发现通用指数退避重试实现。重试语义主要由上层调用方决定:
- 健康检查由
background/index.js周期性轮询。 - 长耗时接口(如 RAG ingest、download)通过增大
timeoutMs容忍延迟。 - 更新 Agent 的
/api/agent/update由 Agent 端自身控制 npm 安装和两阶段重启。
错误分类
| 类别 | 表现 | 典型原因 |
|---|---|---|
| 未配对 | success: false, error: "Agent 未配对" | 无活跃代理或配置缺失 |
| 未认证 | HTTP 401 | 缺少 Bearer Token |
| 无效 Token | HTTP 403 | Token 过期或伪造 |
| 业务拒绝 | HTTP 403/409/400 | 路径不允许、目标已存在、参数缺失 |
| 文件不存在 | HTTP 404 | 文件/目录不存在 |
| 网络/离线 | AbortError 或 fetch 异常 | Agent 未启动、端口占用、Service Worker 被终止 |
| 超时 | requestTimeout | 请求超过 timeoutMs |
章节来源
- src/background/local-agent-client.js#L100-L140
- src/background/local-agent-client.js#L399-L482
- agent/src/server.js#L537-L548
- agent/src/server.js#L2155-L2163
数据交换格式
通用响应结构
Agent 端大多数接口返回:
json
{
"success": true,
"data": "...",
"error": null
}扩展端在解析后追加 httpStatus,形成:
json
{
"success": true,
"data": "...",
"error": null,
"httpStatus": 200
}会话状态同步
会话状态主要发生在扩展端内部:
sessionId标识一次对话。- 子代理使用派生
subSessionId = sessionId + "_sub_" + agentId,隔离流式消息和执行日志。 - ReAct 循环和工具执行器通过
sessionId过滤消息,避免主/子任务互相干扰。
Agent 端本身不维护扩展端会话状态;它负责命令执行、文件、MCP、Skill、RAG、记忆等具体能力。
工具调用参数与结果
工具调用链如下:
- 侧边栏
chat-manager.js发起 API 调用。 react-loop.js构建 ReAct 循环,并行或串行执行工具。tool-executor.js解析toolCall,提取name、arguments、id。- 工具调用可能走本地工具或 Agent 端 MCP/Skill/文件系统。
- 工具结果通过
tool_call_id关联到 UI 卡片。
flowchart TD
Start["收到助手消息"] --> Parse["解析 tool_calls"]
Parse --> Group["分组:并行工具 vs 独占工具"]
Group --> Exec["执行工具"]
Exec --> Local{"是否本地工具?"}
Local --> |是| LocalResult["本地执行结果"]
Local --> |否| AgentCall["调用 Agent 端 MCP/Skill/FS"]
AgentCall --> AgentResult["Agent 返回 { success, content/error }"]
LocalResult --> Merge["合并结果并按 tool_calls 顺序重排"]
AgentResult --> Merge
Merge --> Stream["写入流式消息"]
Stream --> Done["完成本轮 ReAct"]
图表来源
- src/background/react-loop.js#L2224-L2251
- src/background/tool-executor.js#L2130-L2156
- src/side_panel/chat-streaming.js#L1136-L1152
章节来源
- src/side_panel/chat-manager.js#L3185-L3204
- src/background/react-loop.js#L2224-L2251
- src/background/tool-executor.js#L2130-L2156
- src/side_panel/chat-streaming.js#L1136-L1152
命令执行数据流
命令执行采用 HTTP + WebSocket 组合:
- HTTP
/api/exec返回execId和wsUrl。 - 扩展端通过
createExecWebSocket建立 WebSocket 连接。 - Agent 端将命令输出推送到对应
execId的 WebSocket。 - 支持
wait模式同步等待结果,也支持异步流式输出。
sequenceDiagram
participant Ext as "扩展端"
participant Client as "local-agent-client.js"
participant Server as "agent/src/server.js"
participant WS as "WebSocket"
Ext->>Client : "execCommand(command, cwd, force, timeoutMs)"
Client->>Server : "POST /api/exec { command, cwd, wait?, timeoutMs }"
Server-->>Client : "{ success, level, execId, wsUrl }"
Client->>WS : "new WebSocket(wsUrl + '?token=...')"
WS-->>Client : "JSON 输出片段"
Client-->>Ext : "onMessage(data)"
图表来源
- src/background/local-agent-client.js#L593-L626
- src/background/local-agent-client.js#L662-L728
- agent/src/server.js#L1603-L1674
- agent/src/server.js#L2086-L2153
章节来源
- src/background/local-agent-client.js#L593-L626
- src/background/local-agent-client.js#L662-L728
- agent/src/server.js#L1603-L1674
- agent/src/server.js#L2086-L2153
状态管理与一致性
本地缓存
扩展端维护以下本地状态:
pairedAgents:已配对的 Agent 列表,包含id、name、url、加密后的token、pairedAt。activeAgentId:当前活跃 Agent ID。_agentReachability:内存中的可达性缓存,按agentId区分。skillsCache:Agent Skill 名称集合缓存,60 秒有效,切换代理时清空。
Agent 端维护:
- 运行中的命令进程。
- MCP Server 连接状态。
- Skill 注册表。
- RAG 可用性检测结果。
- 回收站条目。
- 审计日志。
离线支持
当前协议并非完全离线设计:
- 若 Agent 离线,扩展端可通过可达性缓存快速返回错误。
- 文件内容、命令输出、MCP/Skill/RAG 结果依赖 Agent 端实时计算。
- 会话状态保存在扩展端,但工具执行结果通常来自 Agent。
数据一致性
- 工作目录切换会重新加载配置,并追加到
allowedPaths,只增不减。 - 删除文件进入回收站,支持恢复和定期清理。
- Skill 目录变更触发自动重载,无需手动 reload。
- MCP Server 禁用时会先断开连接,确保工具可用状态一致。
章节来源
- src/background/local-agent-client.js#L100-L140
- src/background/local-agent-client.js#L863-L907
- agent/src/server.js#L872-L930
- agent/src/server.js#L1144-L1161
- agent/src/server.js#L1901-L1913
- agent/src/server.js#L2207-L2237
性能优化策略
请求合并
- ReAct 循环中对连续可并行工具进行分组并发执行,非并行工具单独按序执行。
- Agent Skill Prompt 获取支持并发
Promise.all,并过滤掉 Workflow 技能减少无效请求。 - 配对成功后并行拉取
/api/status和/api/status/detail生成 Agent 名称。
连接池管理
- 扩展端未实现 HTTP 连接池,依赖浏览器底层连接复用。
- Agent 端使用 Node.js 原生
http模块和wsWebSocketServer。 - WebSocket 连接按
execId管理,每个命令一个连接。 - Agent 端维护活跃 socket 集合,优雅关闭时强制销毁。
资源清理
- Agent 端 shutdown 流程终止运行进程、关闭 MCP 连接、断开 WebSocket、销毁 HTTP socket、清理 PID 文件和回收站定时任务。
- 命令执行支持
stop和detach,前者停止进程,后者显式豁免超时。 - Skill 目录 watcher 防抖 800ms,避免频繁 reload。
大文件传输优化
- 普通上传使用
multipart/form-data,限制 200MB。 - 流式上传
/api/fs/upload-stream直接接收二进制,避免 base64 膨胀。 - 下载支持 base64 返回和流式下载两种模式,目录自动打包为 zip。
章节来源
- src/background/react-loop.js#L2224-L2251
- src/background/local-agent-client.js#L922-L944
- src/background/local-agent-client.js#L291-L300
- agent/src/server.js#L751-L862
- agent/src/server.js#L1163-L1385
- agent/src/server.js#L2239-L2288
使用示例
初始化配置
- 在设置中配置 Agent 地址。
- 调用
pairWithAgent(agentUrl, pairCode)完成配对。 - 成功后
activeAgentId指向新 Agent,后续 API 自动携带 Token。
推荐调用位置:
- 设置页或选项页中触发配对。
- 首次启动时检测是否有已配对 Agent。
章节来源
API 调用模式
文件读取
js
const result = await readFile('/absolute/path/to/file.txt');
if (result.success) {
// 使用 result.content
} else {
// 处理 error 和 httpStatus
}命令执行
js
// 异步模式
const execResult = await execCommand('npm install', process.cwd(), false);
if (execResult.success && execResult.wsUrl) {
const ws = await createExecWebSocket(execResult.wsUrl, onMessage, onClose, onError);
}
// 同步等待模式
const waitResult = await execCommandWait('echo hello');
if (waitResult.success) {
// 使用 stdout/stderr
}MCP 工具调用
js
const tools = await getMcpTools();
const callResult = await callMcpTool(serverId, toolName, args);章节来源
- src/background/local-agent-client.js#L484-L509
- src/background/local-agent-client.js#L593-L626
- src/background/local-agent-client.js#L730-L788
异常处理
建议统一处理以下情况:
success === false:读取error字段。httpStatus === 401:提示重新配对。httpStatus === 403:权限不足或路径不允许。httpStatus === 404:文件不存在。httpStatus === 503:RAG 功能不可用。AbortError:请求超时,建议提示用户延长超时或检查 Agent 是否在线。
章节来源
调试与排障指南
常见问题定位
| 现象 | 排查步骤 | 可能原因 |
|---|---|---|
| 无法连接 Agent | 检查 /api/status 是否返回 200 | Agent 未启动、端口错误、CORS 拦截 |
| 配对失败 | 检查 /api/pair 返回体 | 配对码过期、extensionId 不匹配 |
| 文件读取失败 | 检查 httpStatus 和 error | 路径不在允许范围、文件不存在、大小超限 |
| 命令执行无输出 | 检查 WebSocket 是否建立 | execId 无效、Token 不匹配、进程已退出 |
| MCP 工具不可用 | 检查 /api/mcp/servers 和 /api/mcp/tools | Server 未连接、工具被排除 |
| RAG 搜索失败 | 检查 /api/rag/detect | 依赖未安装、Node 版本不兼容 |
调试工具
- 使用
getAgentStatus()和getAgentDetail()查看 Agent 版本、平台、工作目录、资源使用情况。 - 使用
queryAuditLogs()查询最近 7 天的审计日志,支持按分类筛选。 - 使用
restartAgent()、updateAgent()、stopAgent()管理 Agent 生命周期。 - 使用
getTrashList()和restoreTrash(trashId)管理回收站。
WebSocket 调试要点
- 确认
wsUrl来自/api/exec响应。 - 确认 URL 中包含
token。 - 注意浏览器 WebSocket 不支持自定义 Header,必须使用 query token。
- Agent 端每 30 秒 ping 一次,两次 pong 未收到则判定连接死亡。
章节来源
- src/background/local-agent-client.js#L629-L649
- src/background/local-agent-client.js#L1029-L1056
- src/background/local-agent-client.js#L991-L1027
- agent/src/server.js#L2133-L2143
结论
本内部通信协议以 HTTP JSON 为主、WebSocket 为辅,覆盖文件、命令、MCP、Skill、RAG、记忆、日志等核心能力。扩展端通过统一的 local-agent-client.js 封装认证、请求、可达性缓存和错误处理;Agent 端通过 server.js 提供安全可控的路由、权限校验和资源管理。
实际使用中应重点关注:
- 配对与 Token 生命周期。
- 路径与命令的安全校验。
- 长耗时接口的超时配置。
- WebSocket 连接的建立与心跳。
- Agent 源码修改后必须重启进程。
- Service Worker 生命周期导致的连接中断。