Remote API 网关
审计基线 0.1.5-alpha.1 @ 5dda764ed3;见 源码 / npm 渠道。
一句话版:
Connection管传输与浏览器鉴权,typertGateway校验并分发 typed Remote 调用 / 流,领域 controller 管业务策略。源码已移除旧 API Proxy。
本页对应源码版;安装 npm 版前先看 渠道差异。
一、请求与流的路径
packages/client/connection持有唯一/apifetch handler 与精确 HTTP 路由注册表。POST 承载一元 RPC;下载等表面使用显式 GET/HEAD 路由。packages/api/gateway持有/api/remote.muxWebSocket carrier,将多个逻辑流复用在同一连接上;心跳间隔websocketHeartbeatIntervalMs默认 2 秒(0.1.2 的 30 秒已改),且该间隔同时是 Pong 截止时间——下一拍前没答 Pong 的对端会被 Host 断开。- 未认领端点返回 404,旧 API Proxy fallback 已退出。
- Session 历史 / 控制流与 Host 转发事件是不同契约;持久化
session/event日志不等于直接推到浏览器的 token 流。 packages/api/session-controller另在已鉴权的connection.fetch通道上挂GET|HEAD /api/file?path=<绝对路径>(SessionMediaReferences),读普通文件(含工作区外的临时路径),不设目录或 MIME 类别限制。
二、Host Remote 调用
ctx.typertGateway.invoke() 与 .stream() 消费生成的描述符:校验具名参数,解析 receiver / lookup 身份,验证服务绑定,并在边界应用 codec。取消信号是描述符元数据,Host 接收 AbortSignal,而非信任 wire 上传来的 signal。
| 层 | 所属源码 |
|---|---|
@Remote、@RemoteScope、TypertRemoteService | packages/typert/protocol |
| 描述符校验与调用 | packages/api/gateway/src/index.ts |
| Client 方法安装 | packages/api/gateway/src/client/index.ts |
| 业务错误与 Session ownership 策略 | 对应领域 controller |
插件应消费生成的 Remote 契约及 client-safe 类型,而非继续复制已删除的 API Proxy schema。@RemoteScope 通过注册的 Host context provider 选择作用域 receiver,本身不定义会话准入策略。
三、领域 controller 接替集中式代理
| 包 | 职责 |
|---|---|
api/session-controller | 会话列表 / 历史、模型选择、prompt / queue / cancel、实时 control 与 follow 流、文件引用与 /api/file 媒体读取 |
api/settings-controller | 设置操作及客户端安全类型 |
api/workspace-controller | 工作区操作与目录选择集成 |
api/workspace-files | 工作区内文件的分页读 / 字节窗口 / stat / 目录列举与 Agent 写变更流(0.1.5 新增) |
api/remotes | 应用选定的 Remote 贡献与转发事件装配 |
Agent 身份解析位于 packages/api/session-controller/src/agent.ts,负责 live 复用、冷恢复、并发 resume 去重与子 Agent ownership fence。只读冷历史和会恢复 Agent 的显式命令仍是不同路径:list 只读已存 header 与投影缓存行,不做 per-session stat、也不打开冷 Session 正文。
会话配置只余 nativeOpen(平台探测,是否把工作区路径交给原生桌面打开器);导出策略归 Session-log export owner,不再塞回万能网关配置。
四、Client 服务与贡献
ctx.remote 通过 $mount() 装配生成的贡献,$on() 订阅选定 Host 事件,$stream() 开逻辑流,$host 读固定 Host 事实;已解码帧由 carrier 内部投递,ctx.remote 上没有 $dispatch。贡献生命周期约束已装载方法与在途调用。
当前 packages/api/remotes/src/client/index.ts 显式挂载 14 个贡献:
agentPresetsRemote · commandsRemote · settingsControllerRemote
goalsRemote · llmRemote · dynamicRemote · pluginInventoryRemote
messageFeedbackRemote · fileUploadsRemote · sessionReferencesRemote
subagentsRemote · sessionRemote · workspaceRemote · workspaceFilesRemote
浏览器消费应用 facade 与 client-safe 类型,而非运行时发现任意 Host Service。转发事件选择仍集中在 packages/api/remotes/src/remote-events.ts;被转发不等于具有 Session 回放能力。
五、浏览器鉴权与 Host 信任分开
CLI 打印包含 ?token=... 的启动链接。只有 GET / 用它换取绑定 authority 的浏览器会话 cookie,再重定向到干净根路径。随后 RPC / WebSocket 都用 cookie 鉴权,loopback 也一样。
trustedHosts 只允许 Host authority,不是凭据。缺少 / 错误浏览器会话得到 401;Host / Origin 校验失败得到 403。静态资源公开不代表 API 开放。当前启动拒绝 --host 0.0.0.0;远程使用通过 SSH 隧道访问,并打开打印的启动链接。
验证
# 使用匹配的源码构建。
pnpm dsh web --dump-config | grep -iE "connection|api-gateway|api-remotes|controller"
浏览器开发者工具中检查已登录的 POST /api 与 /api/remote.mux 连接。不带 cookie 的 curl 返回 401 是鉴权预期,并非 RPC 故障的证据。