Skip to content

消息格式与通信协议 ​

本文引用的源码文件

本文引用的文件

目录 ​

  1. 引言
  2. 项目结构与通信边界
  3. 核心组件与职责
  4. 架构总览
  5. 详细组件分析
  6. 依赖关系分析
  7. 性能与网络异常处理
  8. 故障排查指南
  9. 结论

引言 ​

本文面向 MCP 工具扩展、命令执行流式输出、以及扩展端与本地 Agent 之间的 HTTP/WebSocket 通信,给出完整的消息格式、连接握手、心跳与断线重连、错误码与重试策略、状态管理机制说明,并配套序列图与流程图帮助理解整体交互。

本项目为双进程架构:

  • Chrome 扩展端(Manifest V3,版本 2.3.1)通过 src/background/local-agent-client.js 发起 HTTP 请求与 WebSocket 连接。
  • 独立本地代理端 Agent(Node.js,入口 agent/src/server.js,npm 包名 ai-helper-agent,版本 2.3.1)提供 HTTP API、WebSocket 命令输出通道、MCP 工具注册与调用、长期记忆与 RAG 能力。

两端版本号始终保持同步;Agent 源码修改后必须重启进程新接口才生效。

项目结构与通信边界 ​

扩展端与 Agent 端的通信契约是系统核心:

  • 扩展端经本地 HTTP/WebSocket 端点调用 Agent 的文件读写、命令执行、长期记忆与 RAG 能力。
  • MCP 工具由 Agent 侧自动发现与调用,扩展端仅暴露统一 REST 接口。
  • 所有需认证的请求均携带 Bearer Token;WebSocket 认证优先使用 Authorization Header,回退到 URL query token。
graph TB
subgraph "Chrome 扩展端"
BG["background/local-agent-client.js<br/>HTTP + WebSocket 客户端"]
SC["background/stream-controller.js<br/>SSE 解析与节流"]
end
subgraph "本地 Agent 端"
S["agent/src/server.js<br/>HTTP 路由 + WebSocket 服务器"]
E["agent/src/executor.js<br/>命令执行 + WS 广播"]
M["agent/src/mcp/*<br/>MCP 客户端与注册表"]
end
BG --> |HTTP /api/*| S
BG --> |WebSocket /ws/exec/{execId}?token=...| S
S --> E
S --> M
SC -.-> BG

图示来源

章节来源

核心组件与职责 ​

  • 扩展端 HTTP 客户端:封装带认证的 fetch 请求、超时控制、可达性缓存、多代理配置管理。
  • 扩展端 WebSocket 客户端:创建命令执行实时输出通道,透传 JSON 或原始文本。
  • Agent HTTP 服务器:统一路由、CORS、鉴权、文件操作、RAG/Memory/Skill/MCP 分发。
  • Agent 命令执行器:维护进程生命周期、超时、WS 广播 stdout/stderr/exit/error。
  • SSE 流控制器:解析 OpenAI 兼容 SSE,聚合 tool_calls、usage,节流推送。
  • MCP 客户端与注册表:支持 stdio/sse/streamable-http/websocket 传输,统一管理工具发现与调用。

章节来源

架构总览 ​

扩展端通过 local-agent-client.js 向 Agent 发起两类通信:

  • HTTP:用于配对、状态查询、文件操作、MCP 工具列表与调用、Skill/RAG 管理等。
  • WebSocket:用于命令执行的实时输出流。

Agent 侧 server.js 同时承载 HTTP 路由与 WebSocket 升级;命令执行委托给 executor.js,MCP 工具通过 mcp/registry.js 与 mcp/client.js 管理。

sequenceDiagram
participant FE as "扩展端 background"
participant AC as "local-agent-client.js"
participant AG as "agent/src/server.js"
participant EX as "agent/src/executor.js"
FE->>AC : "发起命令执行"
AC->>AG : "POST /api/exec {command,cwd,timeoutMs}"
AG->>EX : "executeCommand(...) 返回 execId/wsUrl"
AG-->>AC : "{success : true, execId, wsUrl}"
AC->>AG : "WebSocket /ws/exec/{execId}?token=..."
AG->>EX : "addWsClient(execId, ws)"
EX-->>AG : "stdout/stderr/exit/error 事件"
AG-->>AC : "JSON 消息 {type,data,...}"

图示来源

详细组件分析 ​

一、HTTP 请求/响应消息结构 ​

通用约定:

  • 头部:
    • Authorization: Bearer <token>:除 /api/pair、/api/status 等免认证接口外均需携带。
    • Content-Type: application/json:JSON 请求体。
    • Accept-Language:语言偏好。
  • 响应体:
    • 成功:{ success: true, ... }
    • 失败:{ success: false, error: "<i18n key or message>" }
    • 部分扩展端会附加 httpStatus 字段以区分网络/HTTP 状态与业务错误。

常用端点摘要(节选):

  • 认证与会话:
    • POST /api/pair:配对,返回 token。
    • GET /api/status:健康检查(无认证)。
    • GET /api/status/detail:详细状态(需认证)。
    • GET /api/heartbeat:心跳(需认证)。
  • 文件系统:
    • POST /api/fs/read、/api/fs/write、/api/fs/list、/api/fs/delete、/api/fs/search_files、/api/fs/search_content、/api/files/upload、/api/fs/download-stream 等。
  • 命令执行:
    • POST /api/exec:启动命令,返回 { execId, wsUrl }。
    • POST /api/exec/stop:停止运行中的命令。
    • POST /api/exec/detach:显式 daemon 化。
  • MCP:
    • GET /api/mcp/tools、POST /api/mcp/call、GET /api/mcp/servers、POST /api/mcp/servers、DELETE /api/mcp/servers、POST /api/mcp/servers/connect、POST /api/mcp/servers/disconnect、PUT /api/mcp/servers/toggle。
  • Skill/RAG/审计日志/回收站等:见客户端注释汇总。

错误码与语义:

  • HTTP 层:400/401/403/404/409/429/500/503 等。
  • 业务层:统一 success:false + error 字符串;具体含义由 i18n key 表达。
  • 扩展端在 agentRequest 中会把 HTTP 状态码附加到返回对象的 httpStatus,便于上层区分“文件不存在”和“Agent 离线”。

章节来源

二、WebSocket 连接建立与消息传输协议 ​

连接建立流程:

  • 扩展端构造 URL:ws[s]://{host}:{port}/ws/exec/{execId}?token=<token>。
  • Agent 侧在 upgrade 事件中校验路径与 token,通过后升级为 WebSocket。
  • 认证成功后,服务端将 ws 加入对应 execId 的监听列表,并开启心跳检测。

消息格式(命令执行通道):

  • 标准 JSON 消息:
    • { type: "stdout", data: "...", execId }
    • { type: "stderr", data: "...", execId }
    • { type: "exit", exitCode: number, execId, killed: boolean, timedOut: boolean }
    • { type: "error", error: string, execId }
  • 非 JSON 数据:扩展端会降级为 { type: "raw", data: event.data }。

心跳机制:

  • 服务端每 30 秒 ping 一次,若未收到 pong 则 terminate 连接,触发断开清理逻辑。
  • 客户端不主动发送 ping/pong,浏览器会自动响应 ping。

断线重连:

  • 客户端本身不做指数退避重连;上层(如工具执行器)负责 Promise 超时、取消与资源清理。
  • 服务端在进程已结束场景下,对晚到的 WS 连接回放全部历史输出并立即关闭。
sequenceDiagram
participant C as "扩展端 WebSocket"
participant S as "Agent server.js"
participant X as "Agent executor.js"
C->>S : "HTTP Upgrade /ws/exec/{execId}?token=..."
S->>S : "verifyToken(token)"
alt 认证成功
S->>X : "addWsClient(execId, ws)"
S->>C : "ping (每30s)"
C-->>S : "pong"
X-->>S : "stdout/stderr/exit/error"
S-->>C : "转发 JSON 消息"
else 认证失败
S-->>C : "403 Forbidden"
end

图示来源

章节来源

三、SSE 流式输出与工具调用 ​

扩展端还消费模型服务商的 SSE 流(非 Agent WebSocket),由 StreamController 负责:

  • 解析 data: 行,识别 [DONE]、choices.delta.content、choices.delta.tool_calls、usage。
  • 节流合并内容增量,避免 UI 抖动。
  • 当检测到 finish_reason === 'tool_calls' 时,提前通知前端工具卡片,随后继续读取 usage。
  • 空闲超时保护:持续无数据超过阈值即中断流,释放底层 reader。
flowchart TD
Start(["开始读取SSE"]) --> Parse["逐行解析 data: 行"]
Parse --> DoneCheck{"[DONE]?"}
DoneCheck --> |是| Finish["finish() 发送 STREAM_DONE"]
DoneCheck --> |否| Usage["提取 usage若有"]
Usage --> Choice{"存在 choices[0] ?"}
Choice --> |否| Ignore["忽略该行"]
Choice --> |是| Delta["处理 delta.content / reasoning_content / tool_calls"]
Delta --> ToolCalls{"finish_reason === 'tool_calls' ?"}
ToolCalls --> |是| Notify["发送 STREAM_TOOL_CALL 并返回"]
ToolCalls --> |否| Content{"delta.content ?"}
Content --> |是| Throttle["节流合并并发送 STREAM_CHUNK"]
Content --> |否| Accumulate{"delta.tool_calls ?"}
Accumulate --> |是| Accum["累积参数,等待 finish_reason"]
Accumulate --> |否| Next["继续下一行"]
Throttle --> Next
Notify --> End(["结束本轮"])
Finish --> End
Ignore --> Next
Next --> Parse

图示来源

章节来源

四、MCP 工具消息与状态 ​

MCP 工具通过 Agent 内部注册表统一管理:

  • 扩展端调用 /api/mcp/tools 获取扁平化工具列表(含 serverId、name、inputSchema)。
  • 扩展端调用 /api/mcp/call 传入 serverId、toolName、args,由注册表定位已连接的 McpClient 并转发。
  • McpClient 支持多种传输:stdio、SSE、streamable-http、websocket。
classDiagram
class McpClient {
+string serverId
+string serverName
+boolean connected
+Array tools
+connect()
+callTool(toolName, args)
+disconnect()
+getStatus()
}
class Registry {
+initializeMcpRegistry()
+getMcpServersStatus()
+getMcpTools(serverId?)
+callMcpTool(serverId, toolName, args)
+connectMcpServer(serverId)
+disconnectMcpServer(serverId)
+shutdownMcpRegistry()
}
Registry --> McpClient : "管理实例"

图示来源

章节来源

五、状态管理机制 ​

  • 会话状态:
    • 扩展端通过 sessionId、callId 关联流式消息与工具调用结果。
    • StreamController 维护 fullContent、reasoningContent、usage、toolCalls。
  • 工具状态:
    • MCP 工具通过 serverId 与 toolName 标识;注册表维护已连接 client 的工具清单。
  • 连接状态:
    • 扩展端按 agentId 维护可达性缓存 _agentReachability,不可达时直接短路请求。
    • Agent 侧 WebSocket 维护每个 execId 的活跃客户端集合,心跳检测半开连接。
    • 命令执行支持受管模式:调用方显式传 timeoutMs 接管超时权威,断连不解除定时器。

章节来源

依赖关系分析 ​

  • local-agent-client.js 依赖 shared/logger.js、shared/i18n.js、shared/secret.js。
  • server.js 依赖 auth.js、security.js、executor.js、logger.js、memory/routes.js、rag/*、skill/*、mcp/*。
  • executor.js 依赖 config.js、security.js、logger.js。
  • stream-controller.js 依赖 shared/logger.js。
  • mcp/client.js 依赖 @modelcontextprotocol/sdk 各传输实现。
  • mcp/registry.js 依赖 mcp/client.js、mcp/mcp-config.js、i18n.js。
graph LR
LAC["local-agent-client.js"] --> SJS["server.js"]
SJS --> EXE["executor.js"]
SJS --> MCP_REG["mcp/registry.js"]
MCP_REG --> MCP_CLI["mcp/client.js"]
LAC --> SC["stream-controller.js"]

图示来源

章节来源

性能与网络异常处理 ​

  • 请求超时:
    • HTTP:agentRequest 默认 60s,agentGet 默认 30s;上传默认 60s;下载默认 120s;RAG ingest 放宽至 600s。
    • WebSocket:空闲超时由调用方(工具执行器)Promise 超时统一管理,避免双重超时冲突。
    • SSE:空闲超时 120s,持续无数据即中断 reader 并释放连接。
  • 流量与内存:
    • 大文件采用流式上传/下载,避免 base64 膨胀与全量内存占用。
    • ZIP 打包分块写入,降低峰值内存。
  • 并发与限流:
    • Agent 操作冷却时间(如重启/更新)防止频繁调用。
    • 搜索最大结果数限制。
  • 健壮性:
    • 全局捕获未处理异常与未拒绝 Promise,记录日志但不退出进程。
    • 优雅关闭:终止子进程、关闭 MCP 连接、强制销毁活跃 socket,10s 兜底退出。

章节来源

故障排查指南 ​

常见问题与定位要点:

  • 无法连接 Agent:
    • 检查扩展端是否已配对且 activeAgentId 有效。
    • 检查 _agentReachability 是否为 false,若是则跳过请求。
    • 确认 Agent 服务端口未被占用,查看 server_error 日志。
  • WebSocket 连接失败:
    • 检查 URL 中 execId 是否存在,token 是否正确。
    • 服务端会在认证失败时返回 403 并关闭连接。
    • 若进程已结束,服务端会回放历史输出后立即关闭。
  • 命令执行卡住:
    • 检查工具执行器的 Promise 超时与 detach 策略。
    • 受管模式下,断连不会解除超时;只有显式 detach 才会豁免。
  • MCP 工具不可用:
    • 检查 MCP Server 是否 enabled 且已 connect。
    • 查看注册表日志,确认工具列表加载成功。
  • SSE 流中断:
    • 关注 StreamIdleTimeout 日志,检查上游服务商是否长时间无数据。
    • 确认 streamEnabled 配置未被禁用。

章节来源

结论 ​

本通信协议以扩展端 HTTP/WebSocket 客户端与 Agent 端 HTTP+WebSocket 服务器为核心,结合 SSE 流控制器与 MCP 工具注册表,形成可扩展、可观测、可恢复的命令执行与工具调用体系。通过统一的认证、错误码、心跳与超时策略,确保在 MV3 Service Worker 生命周期约束与网络异常环境下仍能稳定工作。实际集成时,请严格遵循本文的消息格式、状态管理与异常处理建议,并在 Agent 源码变更后重启进程以确保接口生效。