# Runtime Contracts ## Module Purpose `lib/runtime` 是当前仓库的最大公开接口面。这里承接的不是“视觉状态”,而是: - bridge ACP / gateway runtime 合同 - task request / routing request / provider catalog - settings 与 secret 持久化访问 - gateway session / agent / chat 控制器 - desktop 平台能力、skill 目录授权 - Codex CLI 与 config bridge ## `GatewayAcpException` - Source: `lib/runtime/gateway_acp_client.dart` - Type: `class` - Responsibility: 表示 ACP JSON-RPC 失败、能力缺失或协议错误。 ### Constructor Parameters | Param | Type | Required | Default | Meaning | | --- | --- | --- | --- | --- | | `message` | `String` | Yes | none | 错误摘要 | | `code` | `String?` | No | `null` | 协议级错误码 | | `details` | `Object?` | No | `null` | 原始错误负载 | ### Returns | API | Returns | Meaning | | --- | --- | --- | | `toString()` | `String` | 输出 `code: message` 或纯 message | ## `GatewayAcpCapabilities` - Source: `lib/runtime/gateway_acp_client.dart` - Type: `class` - Responsibility: 保存 `acp.capabilities` 的解析结果,是 app 侧 single-agent / execution-target / provider catalog 的只读快照。 ### Constructor Parameters | Param | Type | Required | Meaning | | --- | --- | --- | --- | | `singleAgent` | `bool` | Yes | 是否支持单 agent | | `multiAgent` | `bool` | Yes | 是否支持多 agent 协作 | | `availableExecutionTargets` | `List` | Yes | 当前 bridge 允许的执行目标 | | `providerCatalog` | `List` | Yes | agent 侧 provider catalog | | `gatewayProviderCatalog` | `List` | Yes | gateway 侧 provider catalog | | `raw` | `Map` | Yes | 原始 capability 负载 | | `diagnostics` | `Map` | No | 可选诊断信息 | ### Returns | API | Returns | Meaning | | --- | --- | --- | | `GatewayAcpCapabilities.empty()` | `GatewayAcpCapabilities` | 空 capability 占位 | ## `GatewayAcpClient` - Source: `lib/runtime/gateway_acp_client.dart` - Type: `class` - Responsibility: XWorkmate 对 ACP JSON-RPC 的 app-side client,负责 endpoint 解析、auth header 注入、capability 拉取、agent 事件流转发。 ### Constructor Parameters | Param | Type | Required | Meaning | | --- | --- | --- | --- | | `endpointResolver` | `Uri? Function()` | Yes | 当前 ACP endpoint 解析器 | | `authorizationResolver` | `Future Function(Uri endpoint)?` | No | endpoint 对应的授权头解析器 | ### Key Methods | Method | Parameters | Returns | Meaning | | --- | --- | --- | --- | | `loadCapabilities` | `{bool forceRefresh=false, Uri? endpointOverride, String authorizationOverride=''}` | `Future` | 拉取并缓存 15 秒 capability 快照 | ### Main Call Chain - `AppController.refreshAcpCapabilitiesRuntimeInternal` -> `loadCapabilities` - `GoRuntimeDispatchDesktopClient` -> `GatewayAcpClient` - `GatewayAcpClient` -> ACP JSON-RPC -> bridge ### Side Effects - 网络请求 - 本地 capability 缓存 ## `ExternalCodeAgentAcpCapabilities` - Source: `lib/runtime/go_task_service_client.dart` - Type: `class` - Responsibility: 表示 Go task service 视角下的外部 ACP 能力镜像,主要用于任务路由与执行目标可见性判断。 ### Constructor Parameters | Param | Type | Required | Meaning | | --- | --- | --- | --- | | `multiAgent` | `bool` | Yes | 是否支持多 agent 协作 | ## `ExternalCodeAgentAcpRoutingResolution` - Source: `lib/runtime/go_task_service_client.dart` - Type: `class` - Responsibility: 包装 bridge 返回的 routing resolution,给调用方提供 `resolvedExecutionTarget`、`resolvedProviderId`、`resolvedSkills`、`unavailable*` 等只读 getter。 ### Returns | Getter | Returns | Meaning | | --- | --- | --- | | `resolvedExecutionTarget` | `String` | 归一化后的执行目标 | | `resolvedProviderId` | `String` | 解析后的 provider | | `resolvedGatewayProviderId` | `String` | 解析后的 gateway provider | | `resolvedModel` | `String` | 解析后的模型 | | `resolvedSkills` | `List` | 解析后的技能列表 | | `unavailable` | `bool` | 路由是否不可用 | | `unavailableCode` / `unavailableMessage` | `String` | 不可用原因 | ## `ExternalCodeAgentAcpRoutingConfig` - Source: `lib/runtime/go_task_service_client.dart` - Type: `class` - Responsibility: 描述一次任务执行时 app 侧给 bridge 的 routing 约束,包括 auto/explicit 模式、执行目标、provider、模型、技能、自动安装许可。 ### Constructor Parameters | Param | Type | Required | Meaning | | --- | --- | --- | --- | | `mode` | `ExternalCodeAgentAcpRoutingMode` | Yes | `auto` or `explicit` | | `preferredGatewayTarget` | `String` | Yes | 自动模式下偏好的 gateway 目标 | | `explicitExecutionTarget` | `String` | Yes | 显式执行目标 | | `explicitProviderId` | `String` | Yes | 显式 provider | | `explicitModel` | `String` | Yes | 显式模型 | | `explicitSkills` | `List` | Yes | 显式技能列表 | | `allowSkillInstall` | `bool` | Yes | 是否允许安装缺失技能 | | `availableSkills` | `List` | Yes | 当前可见技能清单 | | `installApproval` | `ExternalCodeAgentAcpSkillInstallApproval?` | No | 安装批准信息 | ### Returns | API | Returns | Meaning | | --- | --- | --- | | `isAuto` | `bool` | 当前是否自动路由 | | `toJson()` | `Map` | 生成 bridge 请求负载 | ## `GoTaskServiceRequest` - Source: `lib/runtime/go_task_service_client.dart` - Type: `class` - Responsibility: 是 desktop task execution 的统一请求模型。无论最终落到 external ACP single、external ACP multi 还是 gateway mode,都由它统一描述。 ### Constructor Parameters | Param | Type | Required | Meaning | | --- | --- | --- | --- | | `sessionId` / `threadId` | `String` | Yes | 会话与线程标识 | | `target` | `AssistantExecutionTarget` | Yes | 目标执行面 | | `prompt` | `String` | Yes | 用户任务文本 | | `workingDirectory` | `String` | Yes | 本地工作目录 | | `model` / `thinking` | `String` | Yes | 模型与 thinking 档位 | | `selectedSkills` | `List` | Yes | 技能键 | | `inlineAttachments` | `List` | Yes | base64 内联附件 | | `localAttachments` | `List` | Yes | 本地文件附件 | | `agentId` | `String` | Yes | 目标 agent ID | | `metadata` | `Map` | Yes | 额外元数据 | | `routing` | `ExternalCodeAgentAcpRoutingConfig?` | No | 可选显式 routing | | `provider` | `SingleAgentProvider` | No | 当前 provider | | `remoteWorkingDirectoryHint` | `String` | No | 远端工作目录 hint | | `resumeSession` | `bool` | No | 是否续跑 | | `multiAgent` | `bool` | No | 是否多 agent 协作 | | `collaborationMode` | `GoTaskServiceCollaborationMode` | No | 协作模式 | | `routingHint` | `String` | No | 路由提示 | ### Returns | Getter / Method | Returns | Meaning | | --- | --- | --- | | `route` | `GoTaskServiceRoute` | 计算出的实际 route | | `acpMode` | `String` | ACP session mode | | `routingExecutionTarget` | `String` | 发送给 routing 的目标值 | | `effectiveRouting` | `ExternalCodeAgentAcpRoutingConfig` | 若未传入则自动合成 | | `toExternalAcpParams()` | `Map` | 生成 external ACP 请求参数 | ### Main Call Chain - `AppControllerDesktopWorkspaceExecution` -> `GoTaskServiceRequest` - `DesktopGoTaskService.execute*` -> `toExternalAcpParams()` - bridge 根据 routing 再决定 gateway / agent provider 落点 ## `SettingsController` - Source: `lib/runtime/runtime_controllers_settings.dart` - Type: `class` - Responsibility: 统一管理 `SettingsSnapshot`、secret refs、audit trail、account state、settings 文件监控和测试连接入口。 ### Constructor Parameters | Param | Type | Required | Meaning | | --- | --- | --- | --- | | `storeInternal` | `SecureConfigStore` | Yes | 底层持久化与 secret store | | `accountClientFactory` | `AccountRuntimeClient Function(String baseUrl)?` | No | 自定义 account client 构造器 | ### Key Methods | Method | Parameters | Returns | Meaning | | --- | --- | --- | --- | | `initialize` | none | `Future` | 读取 snapshot、启动 watcher、加载派生状态 | | `refreshDerivedState` | none | `Future` | 仅刷新派生状态 | | `saveSnapshot` | `SettingsSnapshot snapshot` | `Future` | 落盘 settings | | `saveGatewaySecrets` | `{int? profileIndex, required String token, required String password}` | `Future` | 保存 gateway secret | | `loadGatewayToken` / `loadGatewayPassword` | `{int? profileIndex}` | `Future` | 读取 gateway 凭据 | | `testOllamaConnection` | `{required bool cloud}` | `Future` | 测试 Ollama 连接 | | `testVaultConnectionDraft` | `VaultConfig profile, {String tokenOverride=''}` | `Future` | 使用草稿配置测试 vault | ### Side Effects - 文件系统 watcher - secure storage 与 settings JSON 文件 - account session / sync / MFA ## Gateway Runtime Controllers ### `GatewayAgentsController` - Source: `lib/runtime/runtime_controllers_gateway.dart` - Responsibility: 管理 gateway agent 列表、当前选中 agent 与 refresh 状态。 ### `GatewaySessionsController` - Source: `lib/runtime/runtime_controllers_gateway.dart` - Responsibility: 管理 session summary 列表、当前 session key、agent-base session 推导。 ### `GatewayChatController` - Source: `lib/runtime/runtime_controllers_gateway.dart` - Responsibility: 管理当前会话的消息历史、streaming 文本、pending run、chat/agent 事件消费。 ### Common API Shape | Controller | Key Parameters | Returns | | --- | --- | --- | | `refresh()` | none | `Future` | | `switchSession(String sessionKey)` | `String` | `Future` | | `loadSession(String sessionKey)` | `String` | `Future` | | `handleEvent(GatewayPushEvent event)` | `GatewayPushEvent` | `void` | ## `GatewayRuntime` - Source: `lib/runtime/gateway_runtime_core.dart` - Type: `class` - Responsibility: 对 websocket gateway 的连接、鉴权、请求、事件订阅、session client 更新、device identity 和日志做统一管理。 ### Constructor Parameters | Param | Type | Required | Meaning | | --- | --- | --- | --- | | `store` | `SecureConfigStore` | Yes | settings/secret/device token 存储 | | `identityStore` | `DeviceIdentityStore` | Yes | 设备身份持久化 | | `sessionClient` | `GatewayRuntimeSessionClient?` | No | 直接 session client | | `runtimeId` | `String` | No | runtime 实例 ID,空时自动生成 | ### Key Methods | Method | Parameters | Returns | Meaning | | --- | --- | --- | --- | | `initialize` | none | `Future` | 初始化 package/device/session updates | | `connectProfile` | `GatewayConnectionProfile profile, {int? profileIndex, String authTokenOverride='', String authPasswordOverride=''}` | `Future` | 按 profile 建立连接 | | `request` | RPC params | `Future>` | 发 websocket RPC | | `listAgents` | none | `Future>` | 取 agent 清单 | | `listSessions` | `{String? agentId, int limit=24}` | `Future>` | 取 session 清单 | | `loadHistory` | `String sessionKey, {int limit=120}` | `Future>` | 取会话历史 | | `sendChat` | named args | `Future` | 发消息并返回 runId | | `abortChat` | `{required String sessionKey, required String runId}` | `Future` | 终止 run | | `stop` | none | `Future` | 断连并清理资源 | ### Main Call Chain - `AppController` / `Gateway*Controller` -> `GatewayRuntime` - `GatewayRuntime` -> websocket RPC / `GatewayRuntimeSessionClient` - 返回 `GatewayPushEvent` 与 snapshot 更新给上层 controller ### Side Effects - 网络 websocket - device token / shared token / password 鉴权 - runtime logs 与 reconnect timer ## `GatewayRuntimeSessionClient` - Source: `lib/runtime/gateway_runtime_session_client.dart` - Type: `abstract class` - Responsibility: 描述 session connect/update 的外部实现边界,允许 runtime 接入不同 session 数据源。 ### Key Types | Type | Role | | --- | --- | | `GatewayRuntimeSessionConnectRequest` | 连接 session 的入参 | | `GatewayRuntimeSessionConnectResult` | 连接结果 | | `GatewayRuntimeSessionUpdate` | 增量更新负载 | ## `RuntimeBootstrapConfig` - Source: `lib/runtime/runtime_bootstrap.dart` - Type: `class` - Responsibility: 从 repo / `.env` / OpenClaw 邻接路径中解析启动期默认值,并把“仅用于预填”的 bootstrap 值合并到 `SettingsSnapshot`。 ### Key Methods | Method | Parameters | Returns | Meaning | | --- | --- | --- | --- | | `load` | `{String? workspacePathHint, String? cliPathHint}` | `Future` | 扫描 workspace/OpenClaw/.env 得到 bootstrap 配置 | | `mergeIntoSettings` | `SettingsSnapshot snapshot` | `SettingsSnapshot` | 只在默认/瞬时路径场景下注入预填值 | | `preferredGatewayFor` | `RuntimeConnectionMode mode` | `GatewayBootstrapTarget?` | 给连接模式选择 bootstrap gateway | ### Notes - 这里遵循仓库安全规则:`.env` 只做预填,不做自动连接真源 ## `GatewayBootstrapTarget` - Source: `lib/runtime/runtime_bootstrap.dart` - Type: `class` - Responsibility: 描述 bootstrap 阶段解析出来的远程 gateway 目标。 ### Constructor Parameters | Param | Type | Required | Meaning | | --- | --- | --- | --- | | `mode` | `RuntimeConnectionMode` | Yes | 当前只用于 remote | | `url` | `String` | Yes | 原始 URL | | `host` | `String` | Yes | 解析后的 host | | `port` | `int` | Yes | 解析后的端口 | | `tls` | `bool` | Yes | 是否 TLS | | `token` | `String` | Yes | 可选 bootstrap token | ## `AgentRegistry` - Source: `lib/runtime/agent_registry.dart` - Type: `class` - Responsibility: 聚合 gateway 暴露的 agent capability / registration / response,给 app 侧 provider 与 bridge 节点注册使用。 ## `SkillDirectoryAccessService` - Source: `lib/runtime/skill_directory_access.dart` - Type: `abstract class` - Responsibility: 抽象 skill 目录授权入口。平台实现包括文件选择器和 macOS bookmark 能力。 ### Main Implementations | Type | Meaning | | --- | --- | | `UnsupportedSkillDirectoryAccessService` | 平台不支持时的空实现 | | `FileSelectorSkillDirectoryAccessService` | 通用文件选择器实现 | | `MacOsSkillDirectoryAccessService` | macOS bookmark/持久授权实现 | ## `DesktopPlatformService` - Source: `lib/runtime/desktop_platform_service.dart` - Type: `abstract class` - Responsibility: 抽象 tunnel/proxy/VPN 模式、系统平台集成刷新与切换能力。 ### Main Implementations | Type | Meaning | | --- | --- | | `UnsupportedDesktopPlatformService` | 无平台支持时的降级实现 | | `MethodChannelDesktopPlatformService` | 通过 method channel 驱动平台能力 | ## `CodexRuntime` - Source: `lib/runtime/codex_runtime.dart` - Type: `class` - Responsibility: 管理本地 Codex CLI stdio 进程、线程/turn RPC、事件流和账户查询。 ### Key Methods | Method | Parameters | Returns | Meaning | | --- | --- | --- | --- | | `findCodexBinary` | none | `Future` | 解析 codex 二进制路径 | | `startStdio` | named args | `Future` | 以 stdio 模式启动 Codex CLI | | `request` | RPC request params | `Future>` | 发 Codex RPC 请求 | | `startThread` | `{required String cwd, bool ephemeral=false}` | `Future` | 新建 thread | | `resumeThread` | `{required String threadId}` | `Future` | 恢复 thread | | `sendMessage` | named args | `Stream` | 对 thread 发消息并返回事件流 | | `interrupt` | `{required String threadId}` | `Future` | 中断运行 | | `getAccount` | none | `Future` | 拉账户信息 | | `listModels` | named args | `Future>>` | 列模型 | | `listSkills` | `{required String cwd}` | `Future>>` | 列技能 | | `stop` | none | `Future` | 停止进程与清理 | ### Key Companion Types | Type | Role | | --- | --- | | `CodexThread` | thread 元数据 | | `CodexTurn` | turn 元数据 | | `CodexAccount` / `CodexRateLimit` | 账户与限额 | | `CodexUserInput` / `CodexAttachment` | 入参模型 | | `CodexRpcError` | RPC 错误 | | `CodexLaunchConfiguration` | 嵌入式启动配置 | ## `CodexConfigBridge` - Source: `lib/runtime/codex_config_bridge.dart` - Type: `class` - Responsibility: 负责把 app settings 与 Codex 配置文件 / MCP server 配置桥接起来,是 `CodexRuntime` 之外的“配置写入侧”。