|
| 1 | +# Gateway 详细设计(EPIC-GW-06) |
| 2 | + |
| 3 | +## 1. 目标与边界 |
| 4 | + |
| 5 | +Gateway 是 NeoCode 的协议与路由中枢,职责是: |
| 6 | + |
| 7 | +- 生命周期管理(IPC + HTTP/WS/SSE 并行启动、优雅关闭) |
| 8 | +- 协议归一化(外层 JSON-RPC 2.0,内层 `gateway.MessageFrame`) |
| 9 | +- 鉴权与 ACL(`Auth -> ACL -> Dispatch`) |
| 10 | +- 会话流式中继(session/run/channel 精准投递) |
| 11 | + |
| 12 | +Gateway **不承载业务逻辑**,不会做模型推理、工具编排与 Provider 选择。业务执行仅由 Runtime 决定。 |
| 13 | + |
| 14 | +## 2. 架构图(含进程边界) |
| 15 | + |
| 16 | +```mermaid |
| 17 | +flowchart LR |
| 18 | + subgraph ClientProcess["客户端进程边界"] |
| 19 | + CLI["CLI / TUI"] |
| 20 | + WEB["Web / Desktop UI"] |
| 21 | + EXT["External Adapter\nURL Scheme / Clipboard"] |
| 22 | + end |
| 23 | +
|
| 24 | + subgraph GatewayProcess["Gateway 进程边界"] |
| 25 | + IPC["IPC Listener\nUDS / Named Pipe"] |
| 26 | + NET["HTTP/WS/SSE Listener"] |
| 27 | + AUTH["Auth + ACL"] |
| 28 | + NORM["JSON-RPC -> MessageFrame\nNormalize"] |
| 29 | + ROUTER["Dispatch + Stream Relay"] |
| 30 | + OPS["Health / Version / Metrics"] |
| 31 | + end |
| 32 | +
|
| 33 | + subgraph RuntimeProcess["Runtime 进程边界"] |
| 34 | + RT["RuntimePort\n编排与事件流"] |
| 35 | + TOOLS["Tools"] |
| 36 | + PROVIDER["Provider Adapter"] |
| 37 | + end |
| 38 | +
|
| 39 | + subgraph CloudBoundary["云端边界"] |
| 40 | + CLOUD["Cloud LLM API"] |
| 41 | + end |
| 42 | +
|
| 43 | + CLI --> IPC |
| 44 | + WEB --> NET |
| 45 | + EXT --> IPC |
| 46 | + EXT --> NET |
| 47 | +
|
| 48 | + IPC --> AUTH |
| 49 | + NET --> AUTH |
| 50 | + AUTH --> NORM |
| 51 | + NORM --> ROUTER |
| 52 | + ROUTER --> RT |
| 53 | + ROUTER --> OPS |
| 54 | +
|
| 55 | + RT --> TOOLS |
| 56 | + RT --> PROVIDER |
| 57 | + PROVIDER --> CLOUD |
| 58 | +``` |
| 59 | + |
| 60 | +## 3. 核心时序图 |
| 61 | + |
| 62 | +### 3.1 本地控制面链路(Client -> Gateway -> Runtime -> Client) |
| 63 | + |
| 64 | +```mermaid |
| 65 | +sequenceDiagram |
| 66 | + box rgb(238, 246, 255) 客户端进程 |
| 67 | + participant C as "Client (CLI/WS/SSE)" |
| 68 | + end |
| 69 | + box rgb(241, 255, 241) Gateway 进程 |
| 70 | + participant G as "Gateway Listener" |
| 71 | + participant A as "Auth + ACL" |
| 72 | + participant D as "Normalize + Dispatch" |
| 73 | + participant R as "Stream Relay" |
| 74 | + end |
| 75 | + box rgb(255, 249, 238) Runtime 进程 |
| 76 | + participant RT as "RuntimePort" |
| 77 | + end |
| 78 | +
|
| 79 | + C->>G: JSON-RPC request |
| 80 | + G->>A: 校验 Token / ACL |
| 81 | + A-->>G: allow |
| 82 | + G->>D: Normalize(JSON-RPC -> MessageFrame) |
| 83 | + D->>RT: RuntimePort 调用(无业务改写) |
| 84 | + RT-->>D: 结果 / 事件 |
| 85 | + D->>R: MessageFrame(event/ack/error) |
| 86 | + R-->>C: JSON-RPC response/notification |
| 87 | +``` |
| 88 | + |
| 89 | +### 3.2 云端调用链路(Runtime -> Provider -> Cloud API) |
| 90 | + |
| 91 | +```mermaid |
| 92 | +sequenceDiagram |
| 93 | + box rgb(238, 246, 255) 客户端进程 |
| 94 | + participant C as "Client" |
| 95 | + end |
| 96 | + box rgb(241, 255, 241) Gateway 进程 |
| 97 | + participant G as "Gateway" |
| 98 | + end |
| 99 | + box rgb(255, 249, 238) Runtime 进程 |
| 100 | + participant RT as "Runtime" |
| 101 | + participant P as "Provider Adapter" |
| 102 | + end |
| 103 | + box rgb(255, 240, 245) 云端边界 |
| 104 | + participant LLM as "Cloud LLM API" |
| 105 | + end |
| 106 | +
|
| 107 | + C->>G: gateway.run / wake.openUrl |
| 108 | + G->>RT: 透传规范化请求 |
| 109 | + RT->>P: 选择并调用 Provider |
| 110 | + P->>LLM: HTTP API |
| 111 | + LLM-->>P: streaming/result |
| 112 | + P-->>RT: 统一 Provider 结果 |
| 113 | + RT-->>G: runtime events |
| 114 | + G-->>C: gateway.event / result |
| 115 | +``` |
| 116 | + |
| 117 | +## 4. 数据流向(本地端与云端区别) |
| 118 | + |
| 119 | +- 本地控制面: |
| 120 | + - 客户端只与 Gateway 通信(IPC/HTTP/WS/SSE)。 |
| 121 | + - Gateway 负责协议、连接、鉴权、路由与中继。 |
| 122 | + - 本地控制面不直接触达云端。 |
| 123 | +- 云端调用: |
| 124 | + - 仅 Runtime 与 Provider 层触达 Cloud API。 |
| 125 | + - Gateway 不感知模型厂商细节,不拼接 Provider 私有字段。 |
| 126 | + |
| 127 | +## 5. 对外接口清单 |
| 128 | + |
| 129 | +### 5.1 面向客户端接口 |
| 130 | + |
| 131 | +| 接口 | 方向 | 认证 | 说明 | |
| 132 | +|---|---|---|---| |
| 133 | +| IPC (UDS / Named Pipe) | Client -> Gateway | `gateway.authenticate` 握手后复用 | 本地控制面主入口 | |
| 134 | +| `POST /rpc` | Client -> Gateway | `Authorization: Bearer <token>` | 单次 JSON-RPC 请求 | |
| 135 | +| `GET /ws` | Client <-> Gateway | `gateway.authenticate` 握手后复用 | 双向流式请求与通知 | |
| 136 | +| `GET /sse` | Client <- Gateway | `?token=<token>` | 单向流式通知与心跳 | |
| 137 | +| `GET /healthz` | Client -> Gateway | 无 | 健康检查 | |
| 138 | +| `GET /version` | Client -> Gateway | 无 | 版本信息 | |
| 139 | +| `GET /metrics` | Client -> Gateway | Bearer Token | Prometheus 指标 | |
| 140 | +| `GET /metrics.json` | Client -> Gateway | Bearer Token | JSON 指标快照 | |
| 141 | + |
| 142 | +### 5.2 JSON-RPC 方法 |
| 143 | + |
| 144 | +| Method | 方向 | 说明 | |
| 145 | +|---|---|---| |
| 146 | +| `gateway.authenticate` | request/response | 连接级鉴权,成功后复用认证态 | |
| 147 | +| `gateway.ping` | request/response | 健康探针 | |
| 148 | +| `gateway.bindStream` | request/response | 会话流绑定 | |
| 149 | +| `wake.openUrl` | request/response | URL Scheme 唤醒入口 | |
| 150 | +| `gateway.event` | notification | Gateway 推送运行时事件 | |
| 151 | + |
| 152 | +### 5.3 面向 Runtime 接口(`RuntimePort`) |
| 153 | + |
| 154 | +| 方法 | 说明 | |
| 155 | +|---|---| |
| 156 | +| `Run(ctx, input)` | 发起一次运行编排 | |
| 157 | +| `Compact(ctx, input)` | 执行会话压缩 | |
| 158 | +| `ResolvePermission(ctx, input)` | 回填权限审批结果 | |
| 159 | +| `CancelActiveRun()` | 取消活动运行 | |
| 160 | +| `Events()` | 订阅运行时事件流 | |
| 161 | +| `ListSessions(ctx)` | 获取会话摘要 | |
| 162 | +| `LoadSession(ctx, id)` | 加载会话详情 | |
| 163 | + |
| 164 | +## 6. 安全与治理基线 |
| 165 | + |
| 166 | +### 6.1 Silent Auth |
| 167 | + |
| 168 | +- Token 文件:`~/.neocode/auth.json` |
| 169 | +- 启动网关时自动加载;缺失或损坏自动重建 |
| 170 | +- 文件结构:`version`, `token`, `created_at`, `updated_at` |
| 171 | + |
| 172 | +### 6.2 ACL 与错误模型 |
| 173 | + |
| 174 | +- 执行顺序:`Auth -> ACL -> Dispatch` |
| 175 | +- 错误返回统一: |
| 176 | + - JSON-RPC:`error.code` |
| 177 | + - Gateway 稳定码:`error.data.gateway_code` |
| 178 | +- 关键稳定码:`unauthorized`, `access_denied`, `invalid_frame`, `unsupported_action` |
| 179 | + |
| 180 | +### 6.3 默认治理参数 |
| 181 | + |
| 182 | +| 配置项 | 默认值 | |
| 183 | +|---|---| |
| 184 | +| `gateway.limits.max_frame_bytes` | `1048576` | |
| 185 | +| `gateway.limits.ipc_max_connections` | `128` | |
| 186 | +| `gateway.limits.http_max_request_bytes` | `1048576` | |
| 187 | +| `gateway.limits.http_max_stream_connections` | `128` | |
| 188 | +| `gateway.timeouts.ipc_read_sec` | `30` | |
| 189 | +| `gateway.timeouts.ipc_write_sec` | `30` | |
| 190 | +| `gateway.timeouts.http_read_sec` | `15` | |
| 191 | +| `gateway.timeouts.http_write_sec` | `15` | |
| 192 | +| `gateway.timeouts.http_shutdown_sec` | `2` | |
| 193 | +| `gateway.observability.metrics_enabled` | `true` | |
| 194 | + |
| 195 | +## 7. 配置优先级 |
| 196 | + |
| 197 | +- `flags > config.yaml > default constants` |
| 198 | +- 当前支持通过 `~/.neocode/config.yaml` 的 `gateway.*` 段配置治理参数。 |
| 199 | + |
| 200 | +## 8. 非目标(本期) |
| 201 | + |
| 202 | +- 不新增 Provider/Tools 业务能力 |
| 203 | +- 不引入外网公开监听与 TLS |
| 204 | +- 不在 Gateway 内实现 Runtime 业务决策 |
0 commit comments