docs: add layered bridge engineering reference

This commit is contained in:
Haitao Pan 2026-04-14 16:24:12 +08:00
parent 9505c34dc4
commit f93a8dda0a
4 changed files with 1513 additions and 477 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,241 @@
# Bridge Runtime Design
本文档回答一个核心问题:`xworkmate-bridge` 作为独立仓库,如何把 APP-facing bridge、独立 upstream ACP provider、gateway runtime 和本地支撑能力组织成一个统一运行时。
## 1. 运行模式
二进制入口在 [main.go](../../main.go) 中定义,当前支持四种运行模式:
| 模式 | 入口 | 作用 |
| --- | --- | --- |
| `serve` | `acp.Serve` | 启动 bridge HTTP / WebSocket 服务,对外暴露 `/acp/rpc``/acp`,并附带健康检查路由。 |
| `acp-stdio` | `acp.RunStdio` | 启动 stdio ACP bridge适合被宿主进程以 stdin/stdout 驱动。 |
| `gemini-acp-adapter` | `geminiadapter.Serve` | 启动 Gemini 专用 ACP adapter把 Gemini CLI 包装成 ACP HTTP / WebSocket 服务。 |
| 默认模式 | `toolbridge.Run` | 启动 MCP 风格的本地工具桥,暴露 `chat`、`claude_review`、`vault_kv` 等工具。 |
设计含义:
- `main.go` 不承载业务决策,只做模式分发。
- APP-facing canonical bridge 只由 `serve` 模式提供。
- `gemini-acp-adapter` 是独立 adapter而不是 bridge 主入口的一部分。
- 默认工具桥是本地工具执行面,不参与 APP-facing canonical path。
## 2. 系统边界
### 2.1 Bridge 自身职责
`internal/acp` 是主控面,负责:
- 挂载 HTTP / WebSocket 路由
- 验证 bridge auth 与 origin
- 维护 session / thread 队列
- 做 routing resolve
- 将任务分发到 single-agent、multi-agent 或 gateway 路径
- 向外部 provider 做 ACP forwarding
- 暴露 bridge-owned metadata例如 provider catalog、gateway provider catalog、resolved routing metadata
### 2.2 Upstream ACP Provider
single-agent provider 目录由 [internal/acp/provider_catalog.go](../../internal/acp/provider_catalog.go) 内建:
- `codex`
- `opencode`
- `gemini`
这些 provider 的 endpoint 和 auth 归 bridge 所有。APP 只通过 `/acp/rpc``/acp` 与 bridge 交互,不直接依赖 provider-specific public URL。
### 2.3 Gateway Runtime
`internal/gatewayruntime` 负责 gateway 连接与请求生命周期,当前 bridge 内建的 gateway provider 是:
- `openclaw`
gateway access 不是单独的 public URL family而是通过 JSON-RPC 方法:
- `xworkmate.gateway.connect`
- `xworkmate.gateway.request`
- `xworkmate.gateway.disconnect`
### 2.4 本地支撑能力
bridge 在 routing 与执行过程中会调用若干支撑包:
- `internal/router`:根据 prompt、memory、available providers、gateway 偏好做执行目标解析
- `internal/skills`:解析显式技能、本地技能匹配与 fallback skill 安装请求
- `internal/memory`:加载本地 / 项目 memory记录 auto routing 成功经验
- `internal/mounts`:汇总 Codex / OpenCode / OpenClaw / ARIS 等 mount 状态
- `internal/shared`RPC envelope、provider command、Vault KV、OpenAI-compatible 请求等公共能力
## 3. 核心主链路
### 3.1 `session.start` / `session.message`
APP-facing 主链路从 `internal/acp.Server.handleRequest` 开始:
1. 校验 `sessionId`
2. 通过 `enqueue` 把任务按 `threadId` 串行排队
3. 在 `executeSessionTask` 中强制要求 `routing`
4. 用 `resolveRoutingMetadataWithProviders` 得到 `router.Result`
5. 将 routing 结果写回执行参数:
- `resolvedExecutionTarget`
- `resolvedProviderId`
- `resolvedGatewayProviderId`
- `resolvedModel`
- `resolvedSkills`
6. 根据 `mode` 分流:
- gateway: `runGateway`
- multi-agent: `runMultiAgent`
- single-agent: `runSingleAgent`
bridge 在开始与结束阶段通过 `session.update` notification 回传运行状态。
### 3.2 Routing Resolve
`internal/router.Resolver.Resolve` 的输入包括:
- prompt
- working directory
- routing mode
- explicit execution target / provider / model / skills
- available skills
- available providers
- AI gateway base URL / API key
- memory preferences
输出包括:
- `ResolvedExecutionTarget`
- `ResolvedProviderID`
- `ResolvedGatewayProviderID`
- `ResolvedModel`
- `ResolvedSkills`
- `SkillResolutionSource`
- `NeedsSkillInstall`
- `Unavailable*`
核心规则:
- 显式 routing 优先于自动 routing。
- 本地任务倾向 `single-agent`
- 在线任务倾向 `gateway`
- 复杂任务可升级到 `multi-agent`
- memory 中的 preferred route / model / skills / provider 会参与默认值补全。
### 3.3 External ACP Forwarding
single-agent 主链路优先走 bridge 内建 provider catalog。`runSingleAgentViaExternalProvider` 会:
1. 根据 provider 解析 endpoint
2. 用 `sanitizeExternalACPParams` 去掉内部字段
3. 优先使用 bridge-owned upstream auth如未配置则复用入站 bearer
4. 根据 endpoint scheme 选择 HTTP 或 WebSocket ACP forwarding
5. 收集 upstream notification并把结果补全为 bridge 统一返回格式
这里的设计重点是:
- bridge 对外保持统一 contract
- provider-specific endpoint 与 auth 不泄漏给 APP
- nested provider forwarding 仍能沿用 bridge bearer
### 3.4 Gateway Connect / Request / Disconnect
`internal/acp/gateway_runtime.go` 负责把 JSON-RPC 参数转为 `gatewayruntime.ConnectRequest``RequestResult`
当前 `openclaw` 路径带有 bridge-owned production routing
- endpoint 固定到 `openclaw.svc.plus:443`
- auth 优先使用 bridge upstream token
- `connectAuthMode` / `connectAuthFields` / `connectAuthSources` 会被 bridge 统一填充
`internal/gatewayruntime.Manager` 维护 runtime session map并负责
- 建连
- 重连
- request / response 配对
- push event 转换
- snapshot / log notification 发射
## 4. 横切关注点
### 4.1 Auth
bridge 主入口使用 `ACP_AUTH_TOKEN` 驱动的 bearer auth
- 如果配置了 token则必须完全匹配该 token 或 `Bearer <token>`
- 如果未配置 token则只要求存在非空 bearer header
Gemini adapter 的 auth 更宽松:
- `GEMINI_ADAPTER_AUTH_TOKEN` 未配置时默认放行
- 配置后才启用 bearer 校验
### 4.2 CORS / WebSocket
bridge 与 Gemini adapter 都维护独立的 allowed origins
- bridge: `ACP_ALLOWED_ORIGINS`
- Gemini adapter: `GEMINI_ADAPTER_ALLOWED_ORIGINS`
规则是:
- 空 `Origin` 默认允许
- `http://localhost:*` / `http://127.0.0.1:*` 这类前缀匹配通过 `:*` 语法支持
- `/acp/rpc` 支持 `OPTIONS` 预检
- WebSocket upgrade 也复用 origin + auth 校验
### 4.3 Provider Catalog
provider catalog 是 bridge-owned runtime truth而不是配置中心 UI 真相:
- `newProductionProviderCatalog()` 直接定义生产 provider
- `availableProviderCatalog()` 产出 APP-facing metadata
- `availableGatewayProviderCatalog()` 产出 gateway-facing metadata
这符合仓库 ADR 的约束APP 只认 bridge canonical entrypoint不认 provider-specific public URL。
### 4.4 Session Queue / Thread Queue
bridge 把任务串到 `threadId` 级别队列:
- `ensureQueue` 为每个 thread 创建一个缓冲队列
- `runQueue` 顺序执行同一 thread 的任务
- `session.start` 会 reset 同名 session
- `session.cancel` / `session.close` 只操作 session 级状态,不拆分 canonical contract
这样可以保证多轮对话在同一 thread 内顺序执行,避免状态竞争。
### 4.5 Memory / Mounts / Skills 介入点
- routing 前会加载 `memory.Service.Load`
- auto routing 成功后会调用 `RecordSuccess`
- skill 解析在 `router.Resolve` 内完成
- mount 状态通过 `xworkmate.mounts.reconcile` 暴露给上层
这些能力都是 bridge 的支撑层,而不是 APP shell 顶层 surface。
## 5. 设计约束
本仓库的设计约束必须始终保持一致:
- app-facing canonical path 只有 bridge
- `POST /acp/rpc`
- `GET /acp`
- provider 与 gateway 只是 bridge-owned routing metadata不是 APP 顶层模块
- runtime truth source 尽量 singular
- provider catalog 以内建 bridge contract 为准
- gateway provider 以内建 production routing 为准
- config-center UI 不是 runtime readiness 的前置真相;当 bridge/runtime contract 已能自解析时,不应引入第二套入口或第二套依赖来源
## 6. 代码定位
建议结合以下文件阅读本设计:
- [main.go](../../main.go)
- [internal/acp/server.go](../../internal/acp/server.go)
- [internal/acp/routing.go](../../internal/acp/routing.go)
- [internal/acp/execution.go](../../internal/acp/execution.go)
- [internal/acp/gateway_runtime.go](../../internal/acp/gateway_runtime.go)
- [internal/acp/provider_catalog.go](../../internal/acp/provider_catalog.go)
- [internal/gatewayruntime/runtime.go](../../internal/gatewayruntime/runtime.go)
- [internal/router/router.go](../../internal/router/router.go)
- [internal/toolbridge/runner.go](../../internal/toolbridge/runner.go)

40
docs/index.md Normal file
View File

@ -0,0 +1,40 @@
# XWorkmate Bridge 文档导航
本文档集面向 `xworkmate-bridge` 的内部工程协作,目标是把设计、入口、协议、内部实现和测试材料串成一条连续阅读链路。
约定口径:
- “设计” 指系统边界、运行模式、主链路和约束。
- “接口” 同时覆盖对外 HTTP / WebSocket / JSON-RPC 协议,以及 Go 代码中的 `interface` 类型。
- “类” 在本仓库按 Go 语义映射为 `struct``interface`
- “参数 / 返回” 既指协议参数 / 返回体,也指 Go 函数与方法的参数 / 返回值。
## 推荐阅读顺序
### 1. 架构与设计
- [架构拓扑ACP Forwarding Topology](./architecture/acp-forwarding-topology.md)
- [ADRUnified Bridge Entry Points](./architecture/adr-unified-bridge-entrypoints.md)
- [运行时设计Bridge Runtime Design](./architecture/bridge-runtime-design.md)
### 2. 运行入口与对外接口
- [API Interface Reference](./api-reference.md)
### 3. 内部包与实现参考
- [Internal Reference](./internal-reference.md)
### 4. 测试与验证材料
- [Core Functional Test Plan](./xworkmate-bridge-svc-plus-core-functional-test-plan-v1.md)
- [ACP Public Validation 2026-04-09](./acp-public-validation-2026-04-09.md)
- [Remote Agent Local Workspace Test Matrix](./testing/remote-agent-local-workspace-test-matrix.md)
- [Gemini ACP Adapter Notes](./gemini-acp-adapter.md)
## 文档组织原则
- `docs/api-reference.md` 是对外运行契约的唯一真相来源。
- `docs/architecture/*.md` 负责解释设计,不重复维护完整参数表。
- `docs/internal-reference.md` 负责解释内部包、类型、函数和关键主链路,不再复制大段协议示例。
- 当文档与代码冲突时,以当前仓库代码为准,并优先修正文档。

592
docs/internal-reference.md Normal file
View File

@ -0,0 +1,592 @@
# Internal Reference
本文档记录 `xworkmate-bridge` 的内部实现参考,覆盖 package、关键 `struct` / `interface`、导出函数,以及核心运行时中的关键未导出主链路函数。
术语约定:
- “类” 在本仓库映射为 Go 的 `struct``interface`
- “接口” 同时指外部协议接口与 Go `interface`
- “参数 / 返回” 同时包含 Go 签名与运行时语义
## internal/acp
### 包职责
APP-facing bridge 主控面。负责 HTTP / WebSocket 路由、JSON-RPC method dispatch、session / thread 队列、routing resolve、single-agent / multi-agent / gateway 执行分流,以及 provider / gateway runtime 桥接。
### 主要输入 / 输出
- 输入HTTP 请求、WebSocket RPC frame、stdio RPC 请求、bridge 环境变量
- 输出JSON-RPC result / error envelope、`session.update` notification、gateway 转发结果、provider 转发结果
### 关键类型
- `type Server struct`
- 作用bridge 运行时聚合根,持有 session map、thread queue、gateway manager、provider catalog、auth service。
- 主要副作用:维护内存态 session / queue并向下调用 gatewayruntime、router、mounts、dispatch、shared。
### 关键函数 / 方法
- `func Serve(args []string) error`
- 参数:`args` 为 `serve` 子命令参数。
- 返回:监听失败或 server 非正常退出时返回 error。
- 副作用:创建 `http.Server`,监听 `ACP_LISTEN_ADDR`
- 场景:`main.go` 中的 `serve` 模式入口。
- `func NewServer() *Server`
- 参数:无。
- 返回:初始化后的 `*Server`
- 副作用:装载内建 provider catalog、gateway manager、static token auth service。
- 场景:`Serve` 和测试中的 server 构造。
- `func (s *Server) Handler() http.Handler`
- 参数receiver `s *Server`
- 返回:统一的 HTTP handler。
- 副作用:按路径路由到 `/`、`/api/ping`、`/bridge/bootstrap/health`、`/acp/rpc`、`/acp`。
- 场景bridge HTTP 服务挂载。
- `func (s *Server) HandleRPC(w http.ResponseWriter, r *http.Request)`
- 参数:标准 HTTP writer/request。
- 返回:无显式返回;通过 HTTP body 输出 JSON-RPC envelope。
- 副作用:处理 CORS、auth、body decode、SSE streaming、RPC dispatch。
- 场景:`POST /acp/rpc`。
- `func (s *Server) HandleWebSocket(w http.ResponseWriter, r *http.Request)`
- 参数:标准 HTTP writer/request。
- 返回:无显式返回;通过 WebSocket 发回 JSON-RPC result / notification。
- 副作用:做 origin/auth 校验,升级连接,持续读取 RPC frame。
- 场景:`GET /acp`。
- `func (s *Server) HandleBridgeBootstrapHealth(w http.ResponseWriter, r *http.Request)`
- 参数:标准 HTTP writer/request。
- 返回:无显式返回;输出 bridge health JSON。
- 副作用:读取 `BRIDGE_PUBLIC_BASE_URL`
- 场景bootstrap 自检或部署健康检查。
- `func RunStdio(input io.Reader, output io.Writer)`
- 参数stdio 输入输出流。
- 返回:无。
- 副作用:运行 stdio ACP bridge。
- 场景:`acp-stdio` 模式。
### 核心未导出主链路
- `func (s *Server) handleRequest(request shared.RPCRequest, notify func(map[string]any)) (map[string]any, *shared.RPCError)`
- 参数:解码后的 RPC 请求、通知回调。
- 返回:成功 result map 或 RPCError。
- 副作用:分派所有 bridge JSON-RPC 方法。
- 场景HTTP 与 WebSocket 统一 RPC dispatch 核心。
- `func (s *Server) executeSessionTask(task task) (map[string]any, *shared.RPCError)`
- 参数:排队后的内部任务对象。
- 返回:执行结果或 RPCError。
- 副作用:强制 routing、创建 / 更新 session、按 resolved mode 分流。
- 场景thread queue 实际执行入口。
- `func resolveRoutingMetadataWithProviders(params map[string]any, availableProviders []string) (router.Result, bool)`
- 参数JSON-RPC params、当前 bridge 可用 provider 列表。
- 返回:`router.Result` 与 “是否提供 routing” 标记。
- 副作用:读取 routing、skill install approval、memory 偏好。
- 场景:`xworkmate.routing.resolve` 与 session 执行前置。
- `func (s *Server) runSingleAgent(ctx context.Context, method string, session *session, params map[string]any, turnID string, notify func(map[string]any)) taskResult`
- 参数上下文、RPC method、session、执行参数、turnId、通知回调。
- 返回:内部 `taskResult`
- 副作用:选择 provider、归一化 working directory、对外做 ACP forwarding。
- 场景single-agent 主路径。
- `func (s *Server) runMultiAgent(ctx context.Context, session *session, params map[string]any, turnID string, notify func(map[string]any)) taskResult`
- 参数上下文、session、执行参数、turnId、通知回调。
- 返回multi-agent 汇总结果。
- 副作用:调用 OpenAI-compatible chat completion产出多智能体总结。
- 场景:复杂任务升级到 multi-agent 时。
- `func (s *Server) runGateway(ctx context.Context, method string, session *session, params map[string]any, turnID string, notify func(map[string]any)) taskResult`
- 参数上下文、RPC method、session、执行参数、turnId、通知回调。
- 返回gateway 执行结果。
- 副作用:调用 `gatewayruntime.Manager.RequestByMode`
- 场景gateway-chat / gateway 模式。
- `func (s *Server) runSingleAgentViaExternalProvider(ctx context.Context, provider syncedProvider, method string, params map[string]any, notify func(map[string]any)) (map[string]any, error)`
- 参数上下文、bridge 内建 provider、RPC method、转发参数、通知回调。
- 返回upstream ACP result 或 error。
- 副作用HTTP / WebSocket forwarding、auth header 选择、结果补全。
- 场景:对 `codex` / `opencode` / `gemini` 做桥接转发。
- `func handleGatewayConnect(server *Server, params map[string]any, notify func(map[string]any)) map[string]any`
- 参数server、JSON-RPC params、通知回调。
- 返回gateway connect 结果。
- 副作用:把 JSON 参数映射为 `gatewayruntime.ConnectRequest`,应用 production routing。
- 场景:`xworkmate.gateway.connect`。
## internal/gatewayruntime
### 包职责
维护 gateway runtime 生命周期,包括建连、认证挑战、请求 / 响应配对、push 事件规范化、重连与快照通知。
### 关键类型
- `type Endpoint struct { Host string; Port int; TLS bool }`
- 作用:声明 gateway endpoint。
- `type PackageInfo struct { AppName string; PackageName string; Version string; BuildNumber string }`
- 作用:附带客户端包信息。
- `type DeviceInfo struct { Platform string; PlatformVersion string; DeviceFamily string; ModelIdentifier string }`
- 作用:附带设备平台信息。
- `func (d DeviceInfo) PlatformLabel() string`
- 参数receiver `DeviceInfo`
- 返回:`Platform` 与 `PlatformVersion` 拼出的展示文本。
- 场景:快照或日志展示。
- `type DeviceIdentity struct { DeviceID string; PublicKeyBase64URL string; PrivateKeyBase64URL string }`
- 作用:携带设备标识与签名密钥材料。
- `type AuthConfig struct { Token string; DeviceToken string; Password string }`
- 作用:承载 gateway connect 认证材料。
- `type ConnectRequest struct`
- 参数字段:`RuntimeID`、`Mode`、`ClientID`、`Locale`、`UserAgent`、`Endpoint`、`ReportedRemoteAddress`、`ConnectAuthMode`、`ConnectAuthFields`、`ConnectAuthSources`、`HasSharedAuth`、`HasDeviceToken`、`PackageInfo`、`DeviceInfo`、`Identity`、`Auth`。
- 作用gateway 建连请求的完整输入对象。
- `type ConnectResult struct { OK bool; Snapshot map[string]any; Auth map[string]any; ReturnedDeviceToken string; Error map[string]any }`
- 作用:建连返回体。
- `type RequestResult struct { OK bool; Payload any; Error map[string]any }`
- 作用gateway request 返回体。
- `type GatewayError struct { Message string; Code string; Details map[string]any }`
- 作用:规范化 gateway 错误。
- `func (e *GatewayError) Error() string`
- 返回:错误消息字符串。
- `func (e *GatewayError) DetailCode() string`
- 返回:`Details["code"]` 的规范化 detail code。
- `func (e *GatewayError) Map() map[string]any`
- 返回:适合写入 JSON / RPC 的错误对象。
- `type Manager struct`
- 导出字段:`ReconnectDelay`、`ConnectTimeout`、`ChallengeTimeout`
- 作用gateway runtime manager内部持有 runtime session map。
### 关键函数 / 方法
- `func NewManager() *Manager`
- 返回:带默认重连与超时参数的 manager。
- `func (m *Manager) Connect(request ConnectRequest, notify func(map[string]any)) ConnectResult`
- 参数connect request、通知回调。
- 返回connect 结果。
- 副作用:查找或创建 runtime session配置 session 并发起建连。
- 场景:`xworkmate.gateway.connect`。
- `func (m *Manager) Request(runtimeID string, method string, params map[string]any, timeout time.Duration, notify func(map[string]any)) RequestResult`
- 参数runtimeId、method、params、超时、通知回调。
- 返回request 结果。
- 副作用:把 gateway RPC 发到已连接 runtime。
- 场景:`xworkmate.gateway.request`。
- `func (m *Manager) RequestByMode(mode string, method string, params map[string]any, timeout time.Duration, notify func(map[string]any)) RequestResult`
- 参数gateway mode、method、params、超时、通知回调。
- 返回request 结果。
- 副作用:按 mode 选择当前已连接 session。
- 场景bridge gateway 执行路径。
- `func (m *Manager) Disconnect(runtimeID string, notify func(map[string]any))`
- 参数runtimeId、通知回调。
- 返回:无。
- 副作用:断开指定 runtime session。
- 场景:`xworkmate.gateway.disconnect`。
### 核心未导出主链路
- `func newSession(manager *Manager, runtimeID string) *session`
- `func (s *session) configure(request ConnectRequest, notify func(map[string]any))`
- `func (s *session) connect() ConnectResult`
- `func (s *session) connectAttempt() (ConnectResult, *GatewayError)`
- `func (s *session) request(method string, params map[string]any, timeout time.Duration) RequestResult`
- `func (s *session) requestRemote(method string, params map[string]any, timeout time.Duration, requireConnected bool) RequestResult`
- `func (s *session) disconnect()`
- `func (s *session) readLoop(conn *websocket.Conn, challengeCh chan string)`
- `func (s *session) scheduleReconnect()`
- `func (s *session) emitNotification(method string, params map[string]any)`
这些函数共同组成 gateway runtime 的状态机:配置、建连、读循环、请求发出、错误处理、重连调度以及 `xworkmate.gateway.snapshot` / `xworkmate.gateway.push` / `xworkmate.gateway.log` 通知发射。
## internal/router
### 包职责
根据 prompt、显式 routing、memory 偏好、provider 可用性与 skill 解析结果,决定任务应该走 `single-agent`、`multi-agent` 还是 `gateway`
### 常量
- `RoutingModeAuto = "auto"`
- `RoutingModeExplicit = "explicit"`
- `ExecutionTargetSingleAgent = "single-agent"`
- `ExecutionTargetMultiAgent = "multi-agent"`
- `ExecutionTargetGateway = "gateway"`
- `ExecutionTargetGatewayChat = "gateway-chat"`
- `GatewayProviderOpenClaw = "openclaw"`
### 关键类型
- `type Request struct`
- 关键字段:`Prompt`、`WorkingDirectory`、`RoutingMode`、`PreferredGatewayProviderID`、`ExplicitExecutionTarget`、`ExplicitProviderID`、`ExplicitModel`、`ExplicitSkills`、`AllowSkillInstall`、`InstallApproval`、`AvailableSkills`、`AvailableProviders`、`AIGatewayBaseURL`、`AIGatewayAPIKey`。
- 作用routing 计算输入。
- `type Result struct`
- 关键字段:`ResolvedExecutionTarget`、`ResolvedProviderID`、`ResolvedGatewayProviderID`、`ResolvedModel`、`ResolvedSkills`、`SkillResolutionSource`、`SkillCandidates`、`NeedsSkillInstall`、`SkillInstallRequestID`、`MemorySources`、`Unavailable`、`UnavailableCode`、`UnavailableMessage`。
- 作用routing 计算输出。
- `type Resolver struct`
- 字段:`SkillFinder`、`SkillInstaller`、`MemoryService`、`Classifier`
- 作用routing 聚合器。
- `type ClassificationRequest struct { Prompt string; AIGatewayBaseURL string; AIGatewayAPIKey string }`
- 作用:传给分类器的输入。
- `type Classifier interface { Classify(req ClassificationRequest) string }`
- 作用:抽象分类器接口。
- `type LLMClassifier struct{}`
- 作用:默认分类器实现。
### 关键函数 / 方法
- `func NewResolver() Resolver`
- 返回:绑定默认 skills finder / installer、memory service、classifier 的 resolver。
- `func (r Resolver) Resolve(req Request) Result`
- 参数routing request。
- 返回routing result。
- 副作用:读取 memory、解析技能、决定 execution target / provider / gateway provider。
- 场景bridge session 执行前置与 `xworkmate.routing.resolve`
- `func (LLMClassifier) Classify(req ClassificationRequest) string`
- 参数classification request。
- 返回execution target 候选字符串。
- 场景:启发式规则未命中时的分类补充。
### 核心未导出主链路
- `func (r Resolver) resolveExecution(req Request, prefs memory.Preferences) (string, string)`
- `func (r Resolver) classify(req Request) string`
- `func mapExplicitTarget(value string, preferredGatewayProviderID string) (string, string)`
- `func resolveGatewayProvider(preferredGatewayProviderID string) string`
- `func resolveProvider(req Request, prefs memory.Preferences, availableProviders []string, executionTarget string) (string, bool, string, string)`
这些函数共同实现了 execution target 与 provider 的两阶段决策。
## internal/dispatch
### 包职责
在 provider 列表、capability 要求和 node runtime state 之间做轻量级 dispatch 解析,并产出 bridge / provider / node metadata。
### 关键类型
- `type Provider struct { ID string; Name string; DefaultArgs []string; Capabilities []string }`
- `type NodeState struct { SelectedAgentID string; GatewayConnected bool; ExecutionTarget string; RuntimeMode string; BridgeEnabled bool; BridgeState string; ResolvedCodexCLIPath string; ConfiguredCodexCLIPath string }`
- `type NodeInfo struct { ID string; Name string; Version string }`
- `type Request struct { Providers []Provider; PreferredProviderID string; RequiredCapabilities []string; NodeState *NodeState; NodeInfo *NodeInfo }`
- `type Result struct { Provider *Provider; AgentID string; Metadata map[string]any }`
### 关键函数
- `func Resolve(request Request) Result`
- 参数provider、capability、node state / info。
- 返回dispatch result。
- 副作用:无外部 I/O纯粹做 provider 选择和 metadata 组装。
- 场景:`xworkmate.dispatch.resolve`。
- `func ResultMap(result Result) map[string]any`
- 参数dispatch result。
- 返回:适合写回 RPC 的 map。
- 场景bridge handler 层输出序列化。
### 核心未导出主链路
- `func selectProvider(providers []Provider, preferredProviderID string, requiredCapabilities []string) *Provider`
- 作用:优先选显式 provider否则按 capability 过滤并按 ID 稳定排序。
## internal/geminiadapter
### 包职责
把 Gemini CLI / Gemini ACP stdio 协议包装成独立 HTTP / WebSocket ACP adapter同时提供一条兼容本地 prompt runner 的 fallback 路径。
### 关键类型
- `type Server struct`
- 作用Gemini adapter 聚合根,持有 RPC client、auth service、provider 元数据、session map。
### 关键函数 / 方法
- `func Serve(args []string) error`
- 参数:`gemini-acp-adapter` 子命令参数。
- 返回:监听失败或 adapter 异常退出时返回 error。
- 副作用:读取 `GEMINI_ADAPTER_*` 环境变量,启动 HTTP 服务。
- `func NewServer(client rpcClient) *Server`
- 参数Gemini ACP RPC client。
- 返回adapter server。
- 副作用:绑定 auth token、provider label、allowed origins、session runner。
- `func (s *Server) HandleRPC(w http.ResponseWriter, r *http.Request)`
- 作用:处理 `/acp/rpc`
- `func (s *Server) HandleWebSocket(w http.ResponseWriter, r *http.Request)`
- 作用:处理 `/acp` WebSocket。
### 核心未导出主链路
- `func (s *Server) handleRequest(request shared.RPCRequest) map[string]any`
- `func (s *Server) handleCapabilities() map[string]any`
- `func (s *Server) handleSessionRequest(method string, params map[string]any) map[string]any`
- `func (s *Server) handleCompatSessionRequest(method string, params map[string]any) map[string]any`
这些函数负责区分真实 upstream ACP 能力与本地兼容路径,并维护 adapter local session history。
## internal/toolbridge
### 包职责
默认模式下的本地 MCP-style 工具桥。负责从 stdin 读取 JSON-RPC / Content-Length frame暴露 `chat`、`claude_review`、`vault_kv` 三个工具。
### 关键函数
- `func Run(input io.Reader, output io.Writer)`
- 参数:输入流、输出流。
- 返回:无。
- 副作用:持续读取消息、解析 RPC、写回结果。
- 场景:`main.go` 默认模式。
### 核心未导出主链路
- `func readMessage(reader *bufio.Reader) ([]byte, error)`
- `func writeMessage(output io.Writer, message map[string]any)`
- `func writeError(output io.Writer, id any, code int, message string)`
- `func handleRequest(request shared.RPCRequest) map[string]any`
## internal/service
### 包职责
认证服务层。一个分支做用户名 / 密码认证,另一个分支做 bearer token 认证。
### 关键类型与函数
- `var ErrInvalidCredentials = errors.New("invalid credentials")`
- `type AuthRepository interface { Verify(ctx context.Context, username, password string) (bool, error) }`
- 作用:用户名 / 密码认证仓储抽象。
- `type AuthService struct`
- `func NewAuthService(repo AuthRepository) *AuthService`
- 参数:认证仓储。
- 返回:认证服务。
- `func (s *AuthService) Authenticate(ctx context.Context, username, password string) error`
- 参数:上下文、用户名、密码。
- 返回:认证成功返回 `nil`,失败返回 `ErrInvalidCredentials` 或仓储错误。
- `type StaticTokenAuthService struct`
- `func NewStaticTokenAuthService(expectedToken string) *StaticTokenAuthService`
- 参数:期望 bearer token。
- 返回:静态 token 服务。
- `func (s *StaticTokenAuthService) ValidateToken(token string) bool`
- 参数token 或 auth header。
- 返回:是否通过校验。
- `func (s *StaticTokenAuthService) ValidateAuthorizationHeader(header string) bool`
- 参数HTTP `Authorization` header。
- 返回:是否通过校验。
- 规则:支持裸 token 和 `Bearer <token>`;若 expectedToken 为空,则接受任意非空 bearer。
## internal/handler
### 包职责
HTTP handler 适配层,把 `service` 层认证能力暴露为简单 HTTP endpoint。
### 关键类型与函数
- `type Authenticator interface { Authenticate(username, password string) error }`
- `type AuthHandler struct`
- `func NewAuthHandler(svc Authenticator) *AuthHandler`
- `func (h *AuthHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)`
- 参数HTTP writer/request。
- 返回:无显式返回。
- 副作用:读取 JSON body调用用户名 / 密码认证,返回 `200``401`
- `func NewServiceAdapter(svc *service.AuthService) Authenticator`
- 作用:把带 `context.Context``AuthService` 包装成 handler 所需接口。
- `type TokenAuthHandler struct`
- `func NewTokenAuthHandler(service *service.StaticTokenAuthService) *TokenAuthHandler`
- `func (h *TokenAuthHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)`
- 参数HTTP writer/request。
- 副作用:读取 `Authorization`,校验静态 token成功返回 `{"ok": true}`
## internal/memory
### 包职责
从全局 home memory、项目 home memory、项目本地 `.xworkmate/memory.md` 合并 memory并在 auto routing 成功后把偏好写回项目级 memory。
### 关键类型与函数
- `type Source struct { Path string; Scope string }`
- `type Preferences struct { PreferredRoute string; PreferredModel string; PreferredSkills []string; Provider string }`
- `type LoadResult struct { MergedText string; Sources []Source; Preferences Preferences; ProjectFiles []string }`
- `type SuccessEntry struct { ResolvedExecutionTarget string; ResolvedProviderID string; ResolvedModel string; ResolvedSkills []string; Summary string }`
- `type Service struct { HomeDir string }`
- `func NewService(homeDir string) Service`
- 参数home 目录。
- 返回memory service。
- `func (s Service) Load(workingDirectory string) LoadResult`
- 参数:工作目录。
- 返回:合并后的文本、来源、偏好、项目文件路径。
- 副作用:读文件;会过滤 token / password / secret 等敏感文本。
- `func (s Service) RecordSuccess(workingDirectory string, entry SuccessEntry) error`
- 参数:工作目录、成功条目。
- 返回:写入错误。
- 副作用:向 `.xworkmate/memory.md` 或 home project memory 追加 auto route block。
## internal/mounts
### 包职责
计算 Codex / Claude / Gemini / OpenCode / OpenClaw / ARIS 的 mount 与 MCP 就绪状态,并在可行时把 managed MCP block 写入配置文件。
### 关键类型与函数
- `type ManagedMCPServer struct { ID string; Name string; Transport string; Command string; URL string; Args []string; Enabled bool }`
- `type Config struct { AutoSync bool; UsesAris bool; ManagedMCPServers []ManagedMCPServer }`
- `type ArisInput struct { Available bool; BundleVersion string; LLMChatServerPath string; SkillCount int; BridgeAvailable bool; Error string }`
- `type Request struct { Config Config; AIGatewayURL string; ConfiguredCodexCLIPath string; CodexHome string; OpencodeHome string; OpenClawHome string; Aris ArisInput }`
- `type MountTargetState struct { TargetID string; Label string; Available bool; SupportsSkills bool; SupportsMCP bool; SupportsAIGatewayInjection bool; DiscoveryState string; SyncState string; DiscoveredSkillCount int; DiscoveredMCPCount int; ManagedMCPCount int; Detail string }`
- `type Result struct { MountTargets []MountTargetState; ArisBundleVersion string; ArisCompatStatus string }`
- `func Reconcile(request Request) Result`
- 参数mount reconcile request。
- 返回:所有目标的 reconcile 结果。
- 副作用:在 `AutoSync` 打开时可能更新 Codex / OpenCode / OpenClaw 配置文件中的 managed block。
- `func ResultMap(result Result) map[string]any`
- 作用:把 reconcile 结果序列化为 RPC 返回格式。
## internal/skills
### 包职责
解析显式技能、本地技能候选、fallback finder 和安装批准流,输出本轮应启用的技能集合及安装请求标记。
### 关键类型与函数
- `type Candidate struct { ID string; Label string; Description string; Installed bool }`
- `type Finder interface { Find(prompt string) []Candidate }`
- `type Installer interface { Install(candidates []Candidate) ([]Candidate, error) }`
- `type ResolveRequest struct { Prompt string; ExplicitSkills []string; AvailableSkills []Candidate; AllowSkillInstall bool; InstallApproval InstallApproval }`
- `type InstallApproval struct { RequestID string; ApprovedSkillKeys []string }`
- `type ResolveResult struct { ResolvedSkills []string; Candidates []Candidate; Source string; NeedsInstall bool; InstallRequestID string }`
- `type StaticFinder struct{}`
- `type ChainFinder struct { Primary Finder; Fallback Finder }`
- `type CommandFinder struct { Binary string }`
- `type CommandInstaller struct { Binary string }`
- `func Resolve(req ResolveRequest, finder Finder, installer Installer) ResolveResult`
- 参数:技能解析请求、候选查找器、安装器。
- 返回resolved skills、候选、来源、安装请求。
- 副作用:在批准条件满足时可能触发外部 installer 二进制。
- `func (StaticFinder) Find(prompt string) []Candidate`
- `func (f ChainFinder) Find(prompt string) []Candidate`
- `func (f CommandFinder) Find(prompt string) []Candidate`
- `func (i CommandInstaller) Install(candidates []Candidate) ([]Candidate, error)`
- `func NewDefaultFinder() Finder`
- `func NewDefaultInstaller() Installer`
## internal/shared
### 包职责
公共工具层RPC envelope、参数读取、provider command 执行、OpenAI-compatible HTTP 调用、Vault KV bridge、prompt 组装等。
### 关键类型
- `type RPCRequest struct { JSONRPC string; ID any; Method string; Params map[string]any }`
- `type RPCError struct { Code int; Message string }`
- `type ToolCallParams struct { Name string; Arguments map[string]any }`
- `type VaultKVResult struct { Operation string; Mount string; Path string; Data map[string]any; Keys []string; Metadata map[string]any }`
### 关键函数
- `func DecodeRPCRequest(payload []byte) (RPCRequest, error)`
- 参数:原始 JSON payload。
- 返回:解码后的 RPCRequest若 method 缺失则返回 error。
- `func WriteSSE(w http.ResponseWriter, payload map[string]any)`
- 参数writer、payload。
- 副作用:按 SSE `data: ...` 形式写出。
- `func ResultEnvelope(id any, result map[string]any) map[string]any`
- `func ErrorEnvelope(id any, code int, message string) map[string]any`
- `func NotificationEnvelope(method string, params map[string]any) map[string]any`
- `func ErrorResponse(id any, code int, message string) map[string]any`
- `func ToolTextResult(id any, content string) map[string]any`
- `func ToolErrorResult(id any, err error) map[string]any`
- `func EnvOrDefault(key, fallback string) string`
- `func StringArg(arguments map[string]any, key, fallback string) string`
- `func ListArg(arguments map[string]any, key string) []any`
- `func IntArg(raw string, fallback int) int`
- `func BoolArg(raw string, fallback bool) bool`
- `func NormalizeBaseURL(raw string) string`
- `func ResolveProviderCommand(provider, model, prompt, cwd string) (string, []string)`
- 参数provider、model、prompt、工作目录。
- 返回:二进制路径和参数列表。
- 场景Codex / OpenCode / Claude / Gemini 命令构造。
- `func RunProviderCommand(ctx context.Context, provider, model, prompt, workingDirectory string) (string, error)`
- 参数上下文、provider、model、prompt、工作目录。
- 返回CLI 输出文本或 error。
- 副作用:启动外部命令。
- `func NormalizeProviderWorkingDirectory(provider, requested string) (string, string)`
- 参数provider、请求目录。
- 返回:规范化目录与有效目录。
- 场景Codex / OpenCode 目录可访问性保护。
- `func AugmentPromptWithAttachments(prompt string, params map[string]any) string`
- `func ComposeHistoryPrompt(history []string) string`
- `func CallOpenAICompatibleCtx(ctx context.Context, baseURL, apiKey, model string, messages []map[string]string) (string, error)`
- `func CallOpenAICompatible(baseURL, apiKey, model string, messages []map[string]string) (string, error)`
- `func HandleChatTool(arguments map[string]any) (string, error)`
- `func HandleClaudeReviewTool(arguments map[string]any) (string, error)`
- `func RunClaudeReview(prompt, model, system, tools string, timeout time.Duration) (string, error)`
- `func ParseClaudeJSON(raw string) (map[string]any, error)`
- `func HandleVaultKVTool(arguments map[string]any) (string, error)`
### 调用关系
- `internal/acp` 同时依赖 shared 的 RPC、provider command、OpenAI-compatible、Vault / tool helpers。
- `internal/toolbridge` 直接把 shared 作为工具实现层。
- `internal/geminiadapter` 通过 shared 运行 provider command 和读取环境变量。