22
33## 职责边界
44
5- Gateway 是远程访问中继,不是 Agent 执行环境。它同时面对桌面 Agent 和浏览器 WebUI:
5+ Gateway 是远程访问中继,不是 Agent 执行环境。它同时面对桌面 Agent 和浏览器 WebUI,
6+ v2 起两端统一走 WebSocket+Protobuf(v1 gRPC 与 JSON WebSocket 已弃用、仅为旧客户端保留):
67
78| 方向 | 协议 | 作用 |
89| ---| ---| ---|
9- | Desktop Agent -> Gateway | gRPC ` AgentGateway.AgentConnect ` 双向流 | 桌面端注册在线 session,接收 WebUI 请求,返回 chat/history/settings/memory/skills 等响应与事件。 |
10- | Desktop Agent -> Gateway | gRPC ` AgentGateway.AgentTerminalConnect ` 双向流 | 专用终端字节流,承载 attach snapshot、input、resize、output,不与普通控制面共享队列。 |
11- | WebUI -> Gateway | WebSocket ` /ws ` | 浏览器端发起 chat(command/subscribe)、history、settings、skills、memory、cron 等 request,并订阅 ` chat.event ` 与同步广播。 |
12- | WebUI -> Gateway | WebSocket ` /ws/terminal ` | 专用二进制终端流;输入 fire-and-forget,输出按 session interest 推送轻量 bytes frame。 |
10+ | Desktop Agent -> Gateway | WebSocket ` /ws/v2/agent ` (Protobuf 帧) | 桌面端注册在线 session,接收 WebUI 请求(` GatewayEnvelope ` ),返回 chat/history/settings/memory/skills 等响应与事件(` AgentEnvelope ` )。 |
11+ | Desktop/Browser -> Gateway | WebSocket ` /ws/v2/terminal ` (Protobuf 帧) | 专用终端字节流(角色由 hello 区分),承载 attach snapshot、input、resize、output,不与普通控制面共享队列。 |
12+ | WebUI -> Gateway | WebSocket ` /ws/v2 ` (Protobuf 帧) | 浏览器端发起 chat(command/subscribe)、直通 history/settings/skills/memory/cron 等请求,并订阅 ` chat_event ` 与同步广播。 |
1313| WebUI -> Gateway | HTTP ` /api/* ` | 状态检查、文件上传、公网分享页、图片代理、静态资源。 |
14+ | ~~ Desktop -> Gateway~~ | gRPC ` AgentGateway.* ` | ** 已弃用** ,服务旧版桌面端。 |
15+ | ~~ WebUI -> Gateway~~ | WebSocket ` /ws ` 、` /ws/terminal ` | ** 已弃用** ,服务未刷新的旧标签页。 |
1416
1517## 入口与服务启动
1618
1719| 文件 | 作用 |
1820| ---| ---|
19- | ` cmd/gateway/main.go ` | 读取 config,创建 ` session.Manager ` ,启动 gRPC server 与 HTTP server,处理 shutdown。 |
21+ | ` cmd/gateway/main.go ` | 读取 config,创建 ` session.Manager ` ,启动 gRPC server(弃用,兼容旧桌面端) 与 HTTP server,处理 shutdown。 |
2022| ` cmd/gateway/shutdown.go ` | gRPC graceful stop 超时后强制 stop。 |
2123| ` internal/config/config.go ` | 地址、token、TLS、静态资源、请求大小、超时等配置。 |
22- | ` internal/auth/grpc_interceptor.go ` | gRPC token 校验。 |
23- | ` internal/auth/http_middleware.go ` | HTTP API token 校验。 |
24- | ` internal/server/grpc.go ` | ` AgentGateway ` gRPC 服务实现。 |
25- | ` internal/server/http.go ` | HTTP mux、WebSocket、API、静态 WebUI 与 public share route。 |
26- | ` internal/server/websocket_chat_handlers.go ` 、` websocket_chat_queue_handlers.go ` 、` chat_commands.go ` | WS ` chat.prepare ` /` chat.command ` /` chat.subscribe ` /` chat.cancel ` /chat queue handler、原生 Runtime 往返探测、订阅 replay 与实时 forward、Gateway -> Desktop ` ChatCommandRequest ` 下发与事件 payload 映射。 |
27- | ` internal/server/websocket.go ` | WebUI WebSocket 连接生命周期、鉴权、订阅 forwarder。 |
28- | ` internal/server/websocket_routes.go ` | WebSocket request type 到 domain handler 的路由表。 |
29- | ` internal/server/websocket_*_handlers.go ` | fs/history/settings/terminal/git/skills/memory/cron/provider 等非 Chat domain handler。 |
30- | ` internal/server/websocket_payloads.go ` | WebSocket 响应 payload 组装与 JSON helper。 |
31- | ` internal/server/websocket_roundtrip.go ` | payload 严格解码、Agent unary round-trip 和错误文案归一。 |
32- | ` internal/server/websocket_writer.go ` | WebSocket 并发写锁、write deadline 与 envelope 发送。 |
33- | ` internal/server/websocket_connection_state.go ` | 单条 WebSocket 连接内的 terminal interest 状态。 |
34- | ` internal/session/manager.go ` | ` session.Manager ` façade 和核心公开类型。 |
24+ | ` internal/observability/ ` | slog 初始化与 v1/v2 协议使用计数(` /api/status ` 的 ` protocol_usage ` )。 |
25+ | ` internal/transport/wscore/ ` | v1/v2 共用的 WebSocket 连接运行时:控制优先双队列写泵、拥塞掉帧、有限重试、心跳与空闲驱逐。 |
26+ | ` internal/protocol/pbws/ ` | ** v2 协议层** :三链路握手/编解码、直通白名单(` guard.go ` )、关联 id 命名空间化、事件扇出与快照回放。 |
27+ | ` internal/protocol/shared/ ` | 两代协议共用的域逻辑:Origin 校验、终端权限门控与响应后处理、终端兴趣跟踪。 |
28+ | ` internal/chatcmd/ ` | chat 命令编排(归一化、探活、投递、启动看门狗),v1/v2 共用。 |
29+ | ` internal/auth/ ` | HTTP/WS token 校验;gRPC 拦截器(弃用)。 |
30+ | ` internal/server/grpc.go ` | v1 ` AgentGateway ` gRPC 服务实现(弃用)。 |
31+ | ` internal/server/http.go ` | HTTP mux、v1/v2 WebSocket 路由、API、静态 WebUI 与 public share route。 |
32+ | ` internal/server/websocket*.go ` | v1 JSON 协议实现(弃用):连接生命周期、字符串路由表、约 90 个 domain handler 与 payload 塑形。 |
33+ | ` internal/session/manager.go ` | ` session.Manager ` façade 和核心公开类型(transport 无关,两代协议共用)。 |
3534| ` internal/session/manager_state.go ` | session registry、sync hub、chat run store 的内部状态定义。 |
3635| ` internal/session/manager_registry.go ` | 当前 Agent session、认证快照、per-request stream 注册。 |
3736| ` internal/session/manager_*_sync.go ` 、` manager_terminal.go ` 、` conversation_stream.go ` 、` conversation_ingress.go ` | history/settings/terminal sync、进程内 Chat 事件窗口、实时 fan-out、replay 与 command dedupe。 |
@@ -40,25 +39,30 @@ Gateway 是远程访问中继,不是 Agent 执行环境。它同时面对桌
4039
4140| 路由 | 认证 | 说明 |
4241| ---| ---| ---|
43- | ` GET /ws ` | token | WebUI 主 WebSocket 协议。 |
44- | ` GET /ws/terminal ` | token | WebUI 终端专用 WebSocket;首帧 JSON auth,后续使用 ` version + kind + headerLength + JSON header + bytes ` 的二进制 frame。 |
45- | ` GET /api/status ` | token | Gateway 当前 Agent 在线状态。 |
42+ | ` GET /ws/v2 ` | hello token | ** v2** WebUI 主链路(Protobuf 帧,子协议 ` liveagent.v2.pb ` )。 |
43+ | ` GET /ws/v2/agent ` | hello token | ** v2** 桌面端信封流(取代 gRPC)。 |
44+ | ` GET /ws/v2/terminal ` | hello token | ** v2** 终端数据面(两端共用,角色在 hello)。 |
45+ | ` GET /ws ` | token | v1 WebUI JSON 协议(弃用)。 |
46+ | ` GET /ws/terminal ` | token | v1 终端二进制流(弃用);首帧 JSON auth,后续 ` version + kind + headerLength + JSON header + bytes ` 。 |
47+ | ` GET /api/status ` | token | Agent 在线状态 + ` protocol_usage ` 协议使用计数。 |
4648| ` POST /api/files/import ` | token | WebUI 上传可读文件,Gateway 转发给桌面端导入 workspace uploads。 |
4749| ` GET /api/public/history-shares/{token} ` | public token | 公开只读历史分享数据。 |
4850| ` GET /image-proxy ` | 视配置/实现而定 | 图片代理,带 URL 安全校验。 |
4951| ` / ` | 无或按静态资源策略 | 嵌入/构建后的 WebUI 静态资源与 SPA fallback。 |
5052
51- Chat 走 ` /ws ` 且是严格新协议:` chat.prepare ` 用关联 Ping/Pong 探测并唤醒桌面 Chat Runtime;` chat.command ` 必须是 ` { type, payload } ` envelope, ` chat.subscribe ` 按 ` conversation_id ` 订阅,不接受旧 ` command ` 字段、顶层裸 payload 或 ` request_id ` 别名 。旧 HTTP SSE 路由 ` GET /api/chat/events ` 已下线。
53+ Chat 走 ` /ws/v2 ` 且是严格新协议:` chat_prepare ` 用关联 Ping/Pong 探测并唤醒桌面 Chat Runtime;` chat_command ` 携带 proto ` ChatCommandRequest ` , ` chat_subscribe ` 按 ` conversation_id ` 订阅。旧 HTTP SSE 路由 ` GET /api/chat/events ` 已下线。
5254
53- ## gRPC 服务
55+ ## gRPC 服务(已弃用)
56+
57+ 仅为旧版桌面端保留;新桌面端走 ` /ws/v2/agent ` ,握手失败时自动回退到本服务。
5458
5559| RPC | 类型 | 用途 |
5660| ---| ---| ---|
57- | ` Authenticate(AuthRequest) -> AuthResponse ` | unary | 桌面端认证探活,返回 session 信息。 |
58- | ` AgentConnect(stream AgentEnvelope) -> stream GatewayEnvelope ` | bidirectional stream | 桌面端常驻连接,WebUI request 下发为 ` GatewayEnvelope ` ,桌面端 response/event 回传为 ` AgentEnvelope ` 。 |
59- | ` AgentTerminalConnect(stream TerminalStreamFrame) -> stream TerminalStreamFrame ` | bidirectional stream | 终端专用字节流;attach 返回 snapshot,input/resize 不返回 session metadata,output 只携带 session、offset 与 bytes 。 |
61+ | ` Authenticate(AuthRequest) -> AuthResponse ` | unary | 桌面端认证探活,返回 session 信息(v2 由 hello 承担) 。 |
62+ | ` AgentConnect(stream AgentEnvelope) -> stream GatewayEnvelope ` | bidirectional stream | 桌面端常驻连接(v2 由 ` /ws/v2/agent ` 承担,信封同构) 。 |
63+ | ` AgentTerminalConnect(stream TerminalStreamFrame) -> stream TerminalStreamFrame ` | bidirectional stream | 终端专用字节流(v2 由 ` /ws/v2/terminal ` 承担) 。 |
6064
61- ` proto/v1/gateway.proto ` 是 Desktop 与 Gateway 的权威协议定义; Go 侧生成文件位于 ` internal/proto/v1 /* ` 。
65+ ` proto/v1/gateway.proto ` 是三端共享的权威业务消息定义(Go 生成于 ` internal/proto/v1/* ` );v2 帧壳定义于 ` proto/v2/gateway_ws.proto ` ( Go 生成于 ` internal/proto/v2 /* ` )。代码生成统一由 ` buf ` 驱动( ` make proto ` ),CI 有生成物漂移与 breaking 检查门禁 。
6266
6367## Session Manager
6468
@@ -91,7 +95,7 @@ Chat 走 `/ws` 且是严格新协议:`chat.prepare` 用关联 Ping/Pong 探测
9195| chat command | 提交/编辑/取消走 WS ` chat.command ` ;新 command 在 accepted 前必须有原生往返 probe,紧随成功 prepare 的 command 可复用同一 session 2 秒内的新鲜结果,旧客户端或过期结果仍现场探测。accepted ACK 走控制优先队列,避免被 token 数据积压阻塞。流式事件走按 conversation 持久订阅 ` chat.subscribe ` ,经 ` chat.event ` 推送(订阅缓冲溢出时发 ` chat.subscription_reset ` 提示客户端按游标重订阅)。 |
9296| terminal stream | 不走普通 ` /ws ` request;attach/input/resize/detach 走 ` /ws/terminal ` 二进制 frame,页面侧 ` BrowserGatewayTerminalStreamClient ` 为同一 token 复用一条 terminal stream 并按 session fan-out。 |
9397
94- WebSocket server 的实现按三层组织: ` websocket.go ` 管连接生命周期和订阅 forwarder; ` websocket_routes.go ` 管 request 路由; ` websocket_*_handlers .go` 管 domain handler。handler 只做 payload 校验、调用 Gateway/Desktop service、组装 WebUI 响应。连接内的可变状态不再直接铺在 ` websocketConnection ` 上,而是通过 terminal tracker 管理 。
98+ WebSocket server 的实现分层: ` internal/transport/wscore ` 管写泵/背压/心跳(两代共用);v2 在 ` internal/protocol/pbws ` (帧编解码、直通白名单、事件扇出);v1 在 ` internal/server/websocket* .go` (弃用:连接生命周期 + 字符串路由 + domain handler)。域逻辑(终端门控/响应后处理、chat 编排)在 ` internal/protocol/shared ` 与 ` internal/chatcmd ` ,两代协议调用同一份实现 。
9599
96100Terminal metadata 事件仍通过普通 ` /ws ` 广播,用于同步 ` created ` 、` exit ` 、` closed ` 、` renamed ` 、SSH prompt 和 SSH tab 状态;terminal output 不再进入 React session state,也不再附带完整 session。输出 bytes 只通过 ` /ws/terminal ` 和 ` AgentTerminalConnect ` 推送,慢客户端只阻塞自己的 terminal stream。
97101
0 commit comments