260 lines
13 KiB
Markdown
260 lines
13 KiB
Markdown
# Chain Map — 跨仓库调用链
|
||
|
||
> 生成日期: 2026-06-05 | 文件级调用链,标注协议边界
|
||
|
||
---
|
||
|
||
## Chain 1: 用户发起 AI 对话 (主流程)
|
||
|
||
```
|
||
xworkmate-app xworkmate-bridge
|
||
───────────── ────────────────
|
||
lib/app/app_controller_desktop.dart
|
||
→ handleChatSend()
|
||
└─ lib/runtime/gateway_runtime_core.dart
|
||
GatewayRuntime.sendMessage()
|
||
│
|
||
├── (ACP WebSocket 路径)
|
||
│ └─ lib/runtime/gateway_acp_client.dart
|
||
│ GatewayAcpClient.request(method: "session.start", ...)
|
||
│ → WebSocket /acp ──────────────────► internal/acp/http_handler.go
|
||
│ HandleWebSocket()
|
||
│ └─ internal/acp/rpc_handler.go
|
||
│ handleRequest("session.start", ...)
|
||
│ └─ internal/router/
|
||
│ Resolve(provider)
|
||
│ └─ Provider handler
|
||
│
|
||
└── (ACP HTTP/SSE 路径)
|
||
└─ lib/runtime/gateway_acp_client.dart
|
||
GatewayAcpClient.request()
|
||
→ HTTP POST /acp/rpc ──────────────► internal/acp/http_handler.go
|
||
HandleRPC()
|
||
└─ internal/acp/rpc_handler.go
|
||
handleRequest(...)
|
||
```
|
||
|
||
### 涉及的 key files:
|
||
| 层 | 文件 | 作用 |
|
||
|----|------|------|
|
||
| app | `lib/app/app_controller_desktop.dart` | 用户输入入口 |
|
||
| app | `lib/runtime/gateway_runtime_core.dart` | Gateway runtime 核心 |
|
||
| app | `lib/runtime/gateway_acp_client.dart` | ACP 客户端 (JSON-RPC 封装) |
|
||
| app | `lib/runtime/acp_endpoint_paths.dart` | 端点路径解析 |
|
||
| bridge | `internal/acp/http_handler.go` | HTTP/WS 请求入口 |
|
||
| bridge | `internal/acp/rpc_handler.go` | JSON-RPC 方法分发 |
|
||
| bridge | `internal/router/` | 提供商路由 |
|
||
|
||
### 协议: ACP JSON-RPC 2.0 over WebSocket (主) / HTTP SSE (后备)
|
||
### 断点风险:
|
||
- ACP 客户端 120s 超时 → 长任务可能超时
|
||
- SSE 流中断后降级为轮询 (`xworkmate.tasks.get`)
|
||
- WebSocket 断线需重连 (30s ping/10s 超时)
|
||
|
||
---
|
||
|
||
## Chain 2: OpenClaw 网关任务执行
|
||
|
||
```
|
||
xworkmate-app xworkmate-bridge
|
||
───────────── ────────────────
|
||
lib/runtime/external_code_agent_acp_desktop_transport.dart
|
||
ExternalCodeAgentAcpTransport
|
||
→ session.start(routing: gateway/openclaw,
|
||
metadata.xworkmateTaskArtifactContract.expectedArtifactDirs)
|
||
└─ lib/runtime/gateway_acp_client.dart
|
||
→ WebSocket /acp or POST /acp/rpc ───────► internal/acp/http_handler.go
|
||
│ HandleWebSocket()/HandleRPC()
|
||
│ └─ internal/acp/rpc_handler.go
|
||
│ Orchestrator.Process()
|
||
│ │
|
||
│ ├─ 本地 gateway
|
||
│ │ └─ internal/gatewayruntime/runtime.go
|
||
│ │ GatewayRuntime.Connect()
|
||
│ │ → WebSocket ────► OpenClaw Gateway
|
||
│ │ ws://127.0.0.1:18789
|
||
│ │ │
|
||
│ │ ├─ chat.send
|
||
│ │ ├─ agent.wait
|
||
│ │ └─ xworkmate.artifacts.*
|
||
│ │ │
|
||
│ │ ▼
|
||
│ │ openclaw-multi-session-plugins
|
||
│ │ ─────────────────────────────
|
||
│ │ index.ts → register()
|
||
│ │ xworkmate.artifacts.prepare
|
||
│ │ xworkmate.artifacts.export
|
||
│ │ xworkmate.artifacts.read
|
||
│ │
|
||
│ └─ 分布式转发
|
||
│ └─ internal/acp/distributed_forwarder.go
|
||
│ ForwardToPeer()
|
||
│ → HTTP POST → 远端 bridge /acp/rpc
|
||
│
|
||
◄── SSE stream (token by token) ────────────
|
||
◄── xworkmate.gateway.push (chat events) ───
|
||
|
||
lib/app/app_controller_openclaw_task_queue.dart
|
||
OpenClawTaskQueue
|
||
→ 本地队列管理 (max 5 active, 20 queued)
|
||
→ 持久化 typed association
|
||
→ 恢复查询只发送 appThreadKey/openclawSessionKey/runId 到 native task-registry
|
||
```
|
||
|
||
Protocol boundary:
|
||
- `expectedArtifactDirs` is not a `chat.send` root parameter.
|
||
- App sends it only as `metadata.xworkmateTaskArtifactContract.expectedArtifactDirs` on `session.start`.
|
||
- Bridge maps it only into `xworkmate.artifacts.export` and `xworkmate.artifacts.collect-and-snapshot`.
|
||
- Bridge must reject old root/metadata compatibility paths instead of probing fallback keys.
|
||
|
||
### 涉及的 key files:
|
||
| 层 | 文件 | 作用 |
|
||
|----|------|------|
|
||
| app | `lib/runtime/external_code_agent_acp_desktop_transport.dart` | 任务传输层 |
|
||
| app | `lib/runtime/go_task_service_client.dart` | 任务接口定义 |
|
||
| app | `lib/runtime/go_task_service_desktop_service.dart` | 桌面任务服务 |
|
||
| app | `lib/app/app_controller_openclaw_task_queue.dart` | 客户端任务队列 |
|
||
| bridge | `internal/acp/gateway.go` | OpenClaw 集成 |
|
||
| bridge | `internal/acp/http_handler.go` | `/acp` / `/acp/rpc` 端点 |
|
||
| bridge | `internal/gatewayruntime/runtime.go` | 网关 WS 客户端 |
|
||
| bridge | `internal/acp/distributed_forwarder.go` | 分布式转发 |
|
||
| plugins | `index.ts` | 插件入口 |
|
||
| plugins | `src/exportArtifacts.ts` | 工件逻辑 |
|
||
|
||
### 协议: ACP JSON-RPC → Gateway RPC (WebSocket, Ed25519 握手)
|
||
### 断点风险:
|
||
- 网关 WebSocket 断连 → 任务丢失
|
||
- 分布式转发 hop=3 限制 → 深层拓扑不可达
|
||
- 任务轮询恢复依赖 `xworkmate.tasks.get` → Bridge 只转发 typed lookup,
|
||
terminal state 以 OpenClaw native task-registry 为准;缺少 native task
|
||
record 时返回 `no_native_task_record`,不从 artifactScope/runId 重建任务。
|
||
|
||
---
|
||
|
||
## Chain 3: 工件下载流
|
||
|
||
```
|
||
xworkmate-app xworkmate-bridge
|
||
───────────── ────────────────
|
||
lib/app/app_controller_desktop_thread_storage.dart
|
||
syncArtifactsFromBridge()
|
||
→ GET /artifacts/openclaw/download ───────────► internal/acp/http_handler.go
|
||
?ref=<signed>&t=<expiry> HandleArtifactDownload()
|
||
└─ internal/gatewayruntime/runtime.go
|
||
gateway.RequestByMode(
|
||
"openclaw",
|
||
"xworkmate.artifacts.read",
|
||
params
|
||
)
|
||
│
|
||
▼
|
||
openclaw-multi-session-plugins
|
||
─────────────────────────────
|
||
src/exportArtifacts.ts
|
||
xworkmate.artifacts.read()
|
||
→ 验证 HMAC 签名
|
||
→ 读取文件内容
|
||
→ 返回 artifact
|
||
```
|
||
|
||
### 涉及的 key files:
|
||
| 层 | 文件 | 作用 |
|
||
|----|------|------|
|
||
| app | `lib/app/app_controller_desktop_thread_storage.dart` | 工件同步 |
|
||
| bridge | `internal/acp/http_handler.go` | 下载端点 |
|
||
| bridge | `internal/gatewayruntime/runtime.go` | 网关调用 |
|
||
| plugins | `src/exportArtifacts.ts` | read 逻辑 |
|
||
|
||
### 安全: HMAC-SHA256 签名绑定 (workspaceRoot, session, run, path, size, hash)
|
||
### 断点风险:
|
||
- 签名过期 (24h) → 下载失败
|
||
- 签名密钥不一致 → 验证失败
|
||
|
||
---
|
||
|
||
## Chain 4: MCP 配置生成
|
||
|
||
```
|
||
xworkmate-app xworkmate-bridge
|
||
───────────── ────────────────
|
||
lib/runtime/codex_config_bridge.dart
|
||
CodexConfigBridge.generate()
|
||
→ 写入 ~/.codex/config.toml
|
||
[mcp_servers.xworkmate]
|
||
command = "openclaw-mcp"
|
||
args = ["--gateway", "https://xworkmate-bridge.svc.plus"]
|
||
# BEGIN XWORKMATE MANAGED MCP BLOCK
|
||
...
|
||
# END XWORKMATE MANAGED MCP BLOCK
|
||
|
||
lib/runtime/opencode_config_bridge.dart
|
||
OpencodeConfigBridge.generate()
|
||
→ 写入 ~/.opencode/config.toml
|
||
[mcp_servers.xworkmate]
|
||
url = "https://xworkmate-bridge.svc.plus/acp"
|
||
# 或 type="stdio" + command="openclaw-mcp" + args=["--gateway", url]
|
||
```
|
||
|
||
### 涉及的 key files:
|
||
| 层 | 文件 | 作用 |
|
||
|----|------|------|
|
||
| app | `lib/runtime/codex_config_bridge.dart` | Codex CLI 配置 |
|
||
| app | `lib/runtime/opencode_config_bridge.dart` | OpenCode CLI 配置 |
|
||
| bridge | `internal/mounts/reconcile.go` | MCP 配置管理 (服务端) |
|
||
|
||
### 断点风险:
|
||
- 配置 block 标记 (`# BEGIN XWORKMATE MANAGED MCP BLOCK`) 冲突 → 覆盖用户配置
|
||
- Gateway URL 变更 → 需重新生成配置
|
||
|
||
---
|
||
|
||
## Chain 5: 已移除的 Plugin → Bridge 反向调用
|
||
|
||
```
|
||
旧链路:
|
||
openclaw-multi-session-plugins/src/bridgeAgents.ts
|
||
→ HTTP POST xworkmate-bridge /acp/rpc
|
||
→ session.start(multiAgent=true)
|
||
|
||
当前链路:
|
||
xworkmate-bridge → OpenClaw Gateway → openclaw-multi-session-plugins
|
||
→ xworkmate.artifacts.*
|
||
```
|
||
|
||
### 涉及的 key files:
|
||
| 层 | 文件 | 作用 |
|
||
|----|------|------|
|
||
| plugins | `index.ts` / `src/exportArtifacts.ts` | artifact scope adapter |
|
||
| bridge | `internal/acp/orchestrator.go` | OpenClaw gateway orchestration |
|
||
|
||
### 协议: 无 Plugin→Bridge 运行时协议
|
||
### 断点风险:
|
||
- 旧版本插件若仍暴露 bridge agents 工具,会恢复循环依赖,应从 manifest 和 dist 中删除
|
||
|
||
---
|
||
|
||
## 跨仓库调用矩阵
|
||
|
||
```
|
||
调用方
|
||
app bridge plugins
|
||
┌───────┬───────┬───────┐
|
||
app │ - │ ACP │ - │
|
||
被调 bridge │ - │ - │ - │
|
||
方 plugins │ - │ GW │ - │
|
||
└───────┴───────┴───────┘
|
||
|
||
ACP = JSON-RPC 2.0 over WebSocket/HTTP SSE
|
||
GW = OpenClaw Gateway RPC over WebSocket (Ed25519)
|
||
```
|
||
|
||
## 调用链复杂度评分
|
||
|
||
| Chain | 跨仓库跳数 | 协议变换 | 风险等级 |
|
||
|-------|-----------|---------|---------|
|
||
| Chain 1 (AI 对话) | 2 (app→bridge→provider) | 1 (ACP) | **中** |
|
||
| Chain 2 (OpenClaw 任务) | 4 (app→bridge→gateway→plugins) | 2 (ACP + GW RPC) | **高** |
|
||
| Chain 3 (工件下载) | 3 (app→bridge→gateway→plugins) | 2 (HTTPS + GW RPC) | **中** |
|
||
| Chain 4 (MCP 配置) | 1 (app→本地文件) | 0 | **低** |
|
||
| Chain 5 (多 Agent) | 2 (plugins→bridge→provider) + 2 (bridge→gateway→plugins) | 2 (HTTP + GW RPC) | **高/循环** |
|