docs(architecture): add layered architecture overview

This commit is contained in:
Haitao Pan 2026-03-29 12:42:09 +08:00
parent 1f4b30cd47
commit c1c5a94a54

View File

@ -0,0 +1,439 @@
# XWorkmate 整体分层架构
Last Updated: 2026-03-29
## 目的
这份文档不是只画一张“UI 在上、服务在下”的静态框图,而是基于当前仓库代码,
重新规划 XWorkmate 的整体分层架构,回答四个问题:
- 本地用户、Web 用户、远程租户如何进入系统
- 任务线程如何成为 UI 与执行之间的控制面主对象
- Desktop / Mobile / Web 三个界面层如何共用同一套 agent core
- 本地 agent、OpenClaw Gateway、ACP endpoint、AI Gateway、Skills / MCP
等扩展能力应该落在哪一层
这份文档是整体总览。专题细节仍以以下文档为准:
- `docs/architecture/assistant-thread-target-model-20260328.md`
- `docs/architecture/xworkmate-internal-state-architecture.md`
- `docs/architecture/xworkmate-integrations.md`
## 为什么要重新规划
如果只用“用户 -> UI -> Agent-core -> 服务”四层表达,当前项目里最关键的
一个事实会被隐藏掉:
**XWorkmate 的运行主对象不是某个页面,也不是某个 gateway session而是
`TaskThread`。**
当前代码里,线程已经有清晰的 canonical schema
- `ownerScope`
- `workspaceBinding`
- `executionBinding`
- `contextState`
- `lifecycleState`
这意味着整体架构更适合规划成:
1. 访问与归属层
2. 多端 UI 层
3. 线程控制面
4. Agent-core 调度层
5. 对接服务与扩展层
6. 安全与持久化基座(横切,不单独作为主业务层)
推荐的关键判断是:
- UI 不是执行状态真值源
- `TaskThread` 才是线程级控制面真值源
- Agent-core 负责把线程状态翻译成可执行请求
- 真正的 provider / gateway / ACP / Skills / MCP 都应放在 Agent-core 之下
## 整体架构
```mermaid
flowchart TB
subgraph L1["① 访问与归属层"]
A1["本地用户 / 设备身份<br/>Desktop / Native host"]
A2["Web 用户 / Browser session"]
A3["远程租户 / owner realm"]
end
subgraph L2["② 多端 UI 层 (Flutter / Dart)"]
B1["AppShellDesktop / mobile_shell / AppShellWeb"]
B2["AssistantPage / SettingsPage / Tasks / Modules / Account"]
B3["WorkspacePageRegistry / destination routing / feature flags"]
end
subgraph L3["③ 线程控制面"]
C1["TaskThread"]
C2["ownerScope"]
C3["workspaceBinding"]
C4["executionBinding"]
C5["contextState"]
C6["lifecycleState"]
C7["线程持久化<br/>SettingsStore / WebSessionRepository"]
end
subgraph L4["④ Agent-core 调度层"]
D1["AppControllerDesktop / AppControllerWeb"]
D2["GoAgentCoreClient 抽象"]
D3["RuntimeCoordinator / GatewayRuntime / ModeSwitcher"]
D4["CodeAgentNodeOrchestrator"]
D5["SingleAgentRunner / DirectSingleAgentAppServerClient / CodexRuntime"]
D6["MultiAgentOrchestrator / MultiAgentMountManager"]
D7["CodexConfigBridge / OpencodeConfigBridge"]
D8["Desktop transport<br/>GoAgentCoreDesktopTransport / go_core / codex_ffi_bindings"]
D9["Web transport<br/>GoAgentCoreWebTransport / WebAcpClient / Relay"]
end
subgraph L5["⑤ 对接服务与扩展层"]
E1["本地 Agent / local app-server / Codex"]
E2["OpenClaw Gateway / Host"]
E3["Remote ACP endpoint / custom providers"]
E4["AI Gateway / Ollama / LLM endpoints"]
E5["Skills / MCP / workspace / attachments / adapters"]
end
F1[("安全与持久化基座<br/>SecretStore / SecureConfigStore / SettingsSnapshot")]
A1 --> B1
A2 --> B1
A3 --> B1
B1 --> B2
B1 --> B3
B2 --> C1
B3 --> C1
C1 --> C2
C1 --> C3
C1 --> C4
C1 --> C5
C1 --> C6
C1 --> D1
D1 --> D2
D1 --> D3
D1 --> D4
D1 --> D6
D1 --> D7
D2 --> D8
D2 --> D9
D3 --> E2
D4 --> E2
D5 --> E1
D6 --> E5
D7 --> E3
D7 --> E5
D8 --> E1
D8 --> E2
D8 --> E4
D9 --> E2
D9 --> E3
D9 --> E4
C7 -.-> C1
F1 -.-> B2
F1 -.-> C1
F1 -.-> D1
F1 -.-> D3
```
## 这五层分别是什么
### 1. 访问与归属层
这一层表达“谁在用系统、线程归谁所有”,不是具体页面。
在当前代码里,最接近这层的是:
- Desktop 本地设备身份:`DeviceIdentityStore`
- Web 会话身份与远程持久化身份:`WebSessionPersistenceConfig`
- 线程归属对象:`ThreadOwnerScope`
它的意义是把“用户入口”和“线程归属”从 UI 外观里抽离出来,让后续的
线程绑定、远端工作区路径、租户隔离都围绕 `ownerScope` 来展开。
### 2. 多端 UI 层
这一层只负责交互、展示和编辑,不拥有执行真值。
当前项目对应:
- Desktop shell`lib/app/app_shell_desktop.dart`
- Mobile shell`lib/features/mobile/`
- Web shell`lib/app/app_shell_web.dart`
- 统一页面入口:`WorkspacePageRegistry`
- 页面族:`AssistantPage`、`SettingsPage`、`TasksPage`、`ModulesPage`
重规划后的规则是:
- UI 负责选择线程、展示线程、编辑设置、发起动作
- UI 不直接决定真实工作目录、真实执行模式、真实 provider 绑定
- UI 必须通过 `TaskThread` + `AppController` 读写运行状态
### 3. 线程控制面
这是这次重规划里最重要的一层。
`TaskThread` 应被视为整个 App 的线程级控制面主对象,而不是聊天列表记录。
当前代码里它已经具备完整控制面字段:
- `ownerScope`
- `workspaceBinding`
- `executionBinding`
- `contextState`
- `lifecycleState`
它的职责是:
- 绑定线程归属
- 绑定工作区路径与展示路径
- 绑定执行模式与 provider
- 保存模型、技能、消息、权限、视图模式
- 保存线程的归档与最近执行状态
因此,推荐把所有“切换线程、发消息、切换目标、切换 provider、回写远端目录”
都看成对线程控制面的更新,而不是页面局部状态切换。
### 4. Agent-core 调度层
这是 XWorkmate 的核心中枢。
它不只是“某个 agent SDK”而是一整套把线程控制面翻译成执行请求的调度层。
当前代码里,这层最关键的组件是:
- `AppControllerDesktop`
- `AppControllerWeb`
- `RuntimeCoordinator`
- `GatewayRuntime`
- `CodeAgentNodeOrchestrator`
- `GoAgentCoreClient`
- `GoAgentCoreDesktopTransport`
- `GoAgentCoreWebTransport`
- `SingleAgentRunner`
- `MultiAgentOrchestrator`
- `MultiAgentMountManager`
- `CodexConfigBridge`
- `OpencodeConfigBridge`
重规划后的职责边界应当是:
- `AppController*` 负责从 `TaskThread` 解析出当前线程的执行上下文
- `GoAgentCoreClient` 负责统一 Desktop / Web 的 agent-core 会话调用抽象
- `RuntimeCoordinator` / `GatewayRuntime` 负责 runtime 与 gateway 连接能力
- `CodeAgentNodeOrchestrator` 负责 app-mediated cooperative node metadata
- `MultiAgentOrchestrator` / `MultiAgentMountManager` 负责协作执行与挂载
- Config bridge 只负责受管配置写入,不越权持有 UI 真值
### 5. 对接服务与扩展层
这一层是实际被调用的执行对象和扩展对象,不应与 controller 混层。
当前代码和文档中,对应的能力面包括:
- 本地单机 agent / local app-server / Codex runtime
- OpenClaw Gateway / Host
- Remote ACP endpoint / 自定义 provider endpoint
- AI Gateway / Ollama / LLM provider
- Skills / MCP / workspace / attachments
- Codex / Claude / Gemini / OpenCode / OpenClaw adapters
重规划后的原则是:
- 新 provider 进入这一层
- 新 gateway 进入这一层
- 新 Skills / MCP / 附件能力进入这一层
- UI 不因为新增 provider 而重新设计页面结构
- 新扩展优先通过 `executionBinding`、transport、adapter、mount manager
接入,而不是直接打穿到页面
### 6. 安全与持久化基座
它是横切基座,不应抢占主业务层。
当前代码里主要是:
- `SettingsStore`
- `SecretStore`
- `SecureConfigStore`
- `SettingsSnapshot`
- `WebStore`
职责是:
- 持久化线程记录和设置
- 安全保存 secret
- 提供 settings snapshot
- 为 Desktop / Web 各自提供持久化后端
## 线程执行主链路
下面这张图把你给出的“UI 选择线程 -> 读取线程 -> 构造请求 -> 执行 -> 回写”
链路,映射到当前代码里的真实对象。
```mermaid
flowchart LR
A["UI 选择 / 新建 / 切换线程"] --> B["currentSessionKey"]
B --> C["读取 TaskThread"]
C --> C1["ownerScope"]
C --> C2["workspaceBinding"]
C --> C3["executionBinding"]
C --> C4["contextState"]
C1 --> D["构造 GoAgentCoreSessionRequest<br/>或 Gateway 执行请求"]
C2 --> D
C3 --> D
C4 --> D
D --> E{"executionMode"}
E -->|localAgent| F["GoAgentCoreDesktopTransport / SingleAgentRunner"]
E -->|gatewayLocal| G["GatewayRuntime / OpenClaw local"]
E -->|gatewayRemote| H["GatewayAcpClient / WebAcpClient / Remote ACP"]
F --> I["执行结果 / delta / resolvedWorkingDirectory"]
G --> I
H --> I
I --> J["回写 contextState / lifecycleState"]
I --> K["必要时回写 workspaceBinding"]
J --> L["持久化 TaskThread"]
K --> L
L --> M["对话区 / 右栏 / 文件面板 / Tasks 刷新"]
```
这条链路里的关键点是:
- UI 先选线程,不是先选 provider
- 线程先绑定,再执行
- 执行模式由 `executionBinding` 决定
- 结果先回写线程,再刷新 UI
- 远端返回新的 working directory 时,应该回写 `workspaceBinding`
## 当前代码里的真实组件映射
| 层级 | 当前主组件 | 代表文件 | 当前职责 |
| --- | --- | --- | --- |
| 访问与归属层 | `ThreadOwnerScope`、`DeviceIdentityStore`、Web session identity | `lib/runtime/runtime_models_runtime_payloads.dart`, `lib/runtime/device_identity_store.dart`, `lib/web/web_session_repository.dart` | 定义线程归属、设备身份、远程会话身份 |
| 多端 UI 层 | `AppShellDesktop`、`mobile_shell_*`、`AppShellWeb`、`AssistantPage`、`SettingsPage` | `lib/app/`, `lib/features/assistant/`, `lib/features/mobile/`, `lib/features/settings/` | 接收用户操作、展示线程与设置 |
| 线程控制面 | `TaskThread` + thread records | `lib/runtime/runtime_models_runtime_payloads.dart`, `lib/runtime/settings_store.dart`, `lib/web/web_session_repository.dart` | 保存线程级真值状态 |
| Agent-core 调度层 | `AppControllerDesktop/Web`、`GoAgentCoreClient`、`RuntimeCoordinator`、`CodeAgentNodeOrchestrator`、`MultiAgentOrchestrator` | `lib/app/`, `lib/runtime/`, `lib/web/` | 把线程状态翻译为执行请求并协调 transport |
| 对接服务与扩展层 | local agent、OpenClaw Gateway、ACP endpoint、AI Gateway、Skills / MCP / adapters | `lib/runtime/go_agent_core_desktop_transport.dart`, `lib/web/go_agent_core_web_transport.dart`, `lib/runtime/multi_agent_mounts.dart` | 真实执行与扩展接入 |
| 安全与持久化基座 | `SettingsStore`、`SecretStore`、`SecureConfigStore`、`WebStore` | `lib/runtime/`, `lib/web/web_store.dart` | 提供持久化与 secret 保护 |
## 三端职责矩阵
| 平台 | UI 入口 | 线程控制面 | agent-core 重点 | 当前执行特点 |
| --- | --- | --- | --- | --- |
| Desktop | `AppShellDesktop` + workspace 页面 | `TaskThread` 持久化最完整 | `AppControllerDesktop` + `RuntimeCoordinator` + Desktop transport | 支持本地 single-agent、gateway local、gateway remote |
| Mobile | `mobile_shell_*` | 复用同一线程模型 | 仍走 native host/controller 体系 | 当前以 remote gateway 场景为主 |
| Web | `AppShellWeb` | 同 schema 的 thread records | `AppControllerWeb` + `GoAgentCoreWebTransport` + relay/acp client | 远程 ACP / relay / AI Gateway 路径 |
## 对你给出的旧图,按代码需要做的三个修正
### 修正 1`TaskThread` 必须上提成独立控制面
你给的第二张图其实已经接近真实代码主链路了。
真正需要正式化的是:
- `TaskThread` 不是“聊天线程 UI 对象”
- 它应该成为 UI 与调度层之间的唯一线程级真值对象
这也是为什么这次重规划把“线程控制面”单独从 UI 和 runtime 中抽出来。
### 修正 2`MultiAgentBrokerServer` 目前更适合作为概念 seam不是已落地的独立主类
现有仓库里没有真正的 `MultiAgentBrokerServer` 实现类。
从代码现实出发,当前更准确的 seam 是:
- `GoAgentCoreClient`
- `GoAgentCoreDesktopTransport`
- `GoAgentCoreWebTransport`
- `GatewayAcpClient`
- `WebAcpClient`
- `MultiAgentOrchestrator`
因此新的整体架构里应把“broker / ACP / transport”归到 Agent-core 调度层内部,
而不是单独挂成一个与 UI 并列的主系统。
### 修正 3`Assistant composer / Settings / Feature flags` 属于 UI 层,不属于运行时层
旧图里把 `Assistant composer / Settings / Feature flags` 和 runtime 节点并排。
按代码来看,它们更准确的定位是:
- UI 入口
- 运行时配置编辑器
- 线程动作触发点
它们不应该拥有执行调度职责,只应通过 controller 和线程控制面驱动 runtime。
## 未来扩展时的落点规则
### 新 UI surface
如果未来加新 surface例如专门的平板布局或独立工作台视图
- 放在多端 UI 层
- 复用 `TaskThread` 控制面
- 不直接接 provider SDK
### 新执行目标
如果未来新增新的执行目标或新的 gateway 类型:
- 先扩展 `executionBinding`
- 再扩展 `GoAgentCoreClient` transport 或 runtime coordinator
- 不要先改页面分支逻辑
### 新 provider / adapter / MCP / skill capability
如果未来新增 Codex / Claude / Gemini / OpenCode 之外的 provider
- 放在对接服务与扩展层
- 通过 mount manager、config bridge、ACP endpoint、adapter 接入
- UI 只展示能力,不成为 provider 真值层
### 新租户/归属模型
如果未来要支持团队、项目、组织、设备共享:
- 先扩展 `ThreadOwnerScope`
- 其次扩展远端 `workspaceBinding` 规则
- 不要把租户逻辑散落到页面和 provider 配置里
## 架构结论
结合当前代码和你给的两张图XWorkmate 最合适的整体定位不是:
- 一个 UI + 若干 provider 接口
而是:
- 一个以 `TaskThread` 为控制面核心的多端 agent workspace App
- UI 负责交互
- 线程控制面负责真值
- Agent-core 负责调度与 transport
- Gateway / ACP / local agent / Skills / MCP 负责实际执行与扩展
一句话概括:
**XWorkmate 应该被设计成“线程先行、界面多端、调度内聚、执行可插拔”的 agent workspace 平台。**
## 相关文档
- `docs/architecture/assistant-thread-target-model-20260328.md`
- `docs/architecture/xworkmate-internal-state-architecture.md`
- `docs/architecture/xworkmate-integrations.md`
- `docs/architecture/assistant-thread-information-architecture.md`