xworkmate-app/docs/architecture/task-control-plane-unification.md
2026-04-11 13:50:11 +08:00

165 lines
5.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 任务执行链路统一收敛
Last Updated: 2026-04-08
## 背景
当前仓库里已经存在 `GoTaskService`、Go ACP `Router.Resolve`、`Skills.Resolve`、
`Memory``buildResolvedExecutionParams`,说明统一控制面已经具备核心骨架。
但旧设计文档长期把不同实现通道写成并列主链,导致:
- Desktop / Web / Mobile 的现状与目标混在一起
- controller 层的历史分流被误认为长期规范
- `gateway` 与显式 `multi-agent` 被描述成 UI 规范入口
本文件把官方口径统一为:
- UI 不变
- `GoTaskService.executeTask` 是唯一公开入口
- ACP 是统一控制面
- `bridge` 是 app 客户端的发现 / 配置 / 连接 / 对话枢纽
- 账户同步只同步 bridge 相关配置属性与安全引用,不做自动连接
## 目标态
```mermaid
flowchart TD
A["Desktop / Web / Mobile UI"] --> B["sendMessage<br/>统一 Task Envelope"]
B --> C["GoTaskService.executeTask<br/>唯一公开入口"]
C --> D["ACP.session.start / session.message"]
D --> E["Router.Resolve"]
E --> F["Skills.Resolve"]
F --> G["Memory.Inject"]
G --> H["buildResolvedExecutionParams"]
H --> I{"resolvedExecutionTarget"}
I -->|"single-agent"| J["single-agent ACP request"]
I -->|"multi-agent"| K["multi-agent ACP request"]
J --> M["bridge hub"]
K --> M
M --> N["Gateway / Provider adapters"]
N --> O["stream events / result"]
O --> P["Memory.Record"]
P --> Q["Update Thread State"]
Q --> R["UI stream render"]
```
## Provider 真源
Single-agent provider catalog and availability are owned by
`xworkmate-bridge`, not by local endpoint presets inside the app.
```mermaid
flowchart TD
A["Settings UI
仅管理 Bridge 连接参数
与账号同步元数据"] --> G["acp.capabilities"]
G --> H["providerCatalog[]
singleAgent / multiAgent"]
H --> I["refreshSingleAgentCapabilitiesRuntimeInternal()"]
I --> J["bridgeAdvertisedProvidersInternal
App 内唯一 provider 名单源"]
I --> K["singleAgentCapabilitiesByProviderInternal
App 内唯一 provider 可用性源"]
G --> L["refreshAcpCapabilitiesRuntimeInternal()"]
L --> M["GatewayAcpCapabilities
providerCatalog / singleAgent / multiAgent"]
M --> N["mergeAcpCapabilitiesIntoMountTargetsRuntimeInternal()"]
N --> O["ManagedMountTargetState
codex / opencode / claude / gemini / aris / openclaw
available / discoveryState"]
J --> P["configuredSingleAgentProviders
= bridgeAdvertisedProvidersInternal"]
P --> Q["singleAgentProviderOptions
Composer / Thread Picker 唯一数据源"]
K --> R["availableSingleAgentProviders
= bridge 当前可用 provider"]
R --> S["visibleAssistantExecutionTargets(...)
single-agent 是否显示
只看 runtime available providers"]
O --> T["visible gateway / multi-agent execution affordances
openclaw / aris discovery 只看 bridge capabilities"]
Q --> U["setSingleAgentProvider(providerId)
仅写入 thread executionBinding.providerId"]
U --> V["singleAgentProviderForSession()
恢复线程已选 providerId"]
V --> W["sendSingleAgentMessageDesktopGoTaskFlowInternal()"]
W --> X["xworkmate.routing.resolve"]
X --> Y["resolvedProviderId /
unavailableCode /
unavailableMessage"]
Y --> Z{"unavailable?"}
Z -->|"no"| AA["executeTask(... resolved routing ...)"]
Z -->|"yes"| AB["provider unavailable UX
直接使用 bridge unavailable message"]
```
## 端侧桥接规则
### Desktop App
- Desktop App 直接桥接 Go 代码
- Desktop 正常执行链路不以“先启动一个本地 HTTP server再由 Desktop 自己回连”作为目标架构
- Desktop 的 `sendMessage -> GoTaskService.executeTask -> ACP` 应理解为进程内或直接桥接语义
- Production cloud mode does not call `xworkmate.providers.sync`
- Production provider upstreams are bridge-owned, not app-owned
- 对 app 来说bridge 是 discovery / config / connect / dialogue 的统一枢纽
### Web / Mobile
- Web / Mobile UI 连接的是 Go 代码启动出来的 server
- Web / Mobile 通过标准 ACP contract 与该 server 通信
- 对 Web / Mobile 来说,`/acp` 与 `/acp/rpc` 是稳定的网络协议入口
## 协议约束
### 传输协议
- local / loopback 允许 `ws://``http://`
- remote 必须使用 `wss://``https://`
- remote 模式禁止静默降级到非 TLS
### ACP contract
- websocket endpoint 规范路径:`/acp`
- RPC endpoint 规范路径:`/acp/rpc`
- base URL 派生时必须避免重复拼接 `/acp`
- 以上 endpoint contract 主要适用于 Web / Mobile 与外部 ACP server 的通信语义
- Desktop 目标态不要求为自身 UI 再额外启动一层本地 HTTP ACP server
## 收敛原则
### Current implementation note
- 当前实现可能仍残留历史分流代码
- 这些实现痕迹不再代表规范
### Target architecture rule
- 所有正常发送请求都先进入 `GoTaskService.executeTask`
- 所有任务都先进入 ACP 控制面,再解析到 executor
- Desktop 采用直接桥接 Go 代码的控制面接入方式
- Web / Mobile 采用连接 Go server 的控制面接入方式
### Compatibility route (removed from target)
- `openClawTask` 不再属于目标架构
- `GatewayRuntime`、`Web relay`、`GatewayAcpClient` 只作为 adapter/executor 能力存在
## 分阶段方向
1. 文档口径收敛
2. Dart 请求模型统一
3. route 决策内收到 `GoTaskService` / ACP
4. app 侧 bridge 枢纽与 provider / gateway 适配关系收敛
5. `multi-agent` 成为统一请求语义