Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
关键数字修正: - Rust 74.5K行(原66K), Tauri命令 183(原182), SaaS路由 121 - 前端组件 104, lib/ 85文件, Store 17+4子store - TODO/FIXME 仅 8 个(前端4+Rust4) 内容增强: - 中间件完整14层注册清单含注册条件和优先级分类 - Store完整目录结构, Pipeline完整目录树 - Hands测试分布, Memory 16个Tauri命令列表 - 管家模式: 关键词路由→语义路由(TF-IDF)修正 - 代码健康度指标新增
5.1 KiB
5.1 KiB
title, updated, status, tags
| title | updated | status | tags | |||
|---|---|---|---|---|---|---|
| 客户端路由 | 2026-04-11 | active |
|
客户端路由
设计思想
核心决策: Tauri 桌面端通过 SaaS Token Pool 中转访问 LLM,不直连。
为什么?
- 集中密钥管理 — 用户不需要自己的 API Key,SaaS 维护共享 Key 池
- 用量追踪 + 计费 — 每次调用经过 SaaS,
record_usageworker 记录 token 消耗 - 模型白名单 — Admin 配置哪些模型可用,
listModels()返回白名单 - 降级保障 — SaaS 挂了自动切本地 Kernel,桌面端不变砖
代码逻辑
4 分支决策树
入口: connectionStore.ts:349 → connect(url?, token?)
connect()
│
├── [1] Admin 强制路由: localStorage llm_routing
│ ├── "relay" → 强制 SaaS Relay 模式
│ └── "local" → 强制本地 Kernel (adminForceLocal=true)
│
├── [2] SaaS Relay 模式: localStorage('zclaw-connection-mode') === 'saas'
│ ├── Tauri: KernelClient + baseUrl = saasUrl/api/v1/relay
│ │ apiKey = SaaS JWT (不是 LLM Key!)
│ ├── Browser: SaaSRelayGatewayClient (SSE)
│ └── SaaS 不可达 → 降级到本地 Kernel
│
├── [3] 本地 Kernel: isTauriRuntime() === true
│ KernelClient + 用户自定义模型配置
│ 用户需要自己的 API Key
│
└── [4] External Gateway (fallback)
GatewayClient via WebSocket/REST
SaaS Relay 主路径 (Tauri 桌面端)
关键代码: connectionStore.ts:482-535
kernelClient.setConfig({
provider: 'custom',
model: modelToUse, // 从 SaaS listModels() 获取
apiKey: session.token, // SaaS JWT,不是 LLM Key
baseUrl: `${session.saasUrl}/api/v1/relay`, // 指向 SaaS relay
apiProtocol: 'openai',
});
注意: Kernel 仍然执行 LLM 调用逻辑,但请求发往 SaaS relay 而非直连 LLM。 SaaS relay 接到请求后,从 Token Pool 中取一个可用 Key,转发给真实 LLM。
SaaS 降级流程
关键代码: connectionStore.ts:446-468
listModels() 失败
→ 401 → session 过期 → logout → 要求重新登录
→ 其他错误 → saasDegraded = true
→ saasStore.saasReachable = false
→ 降级到本地 Kernel 模式
客户端类型
| 客户端 | 传输 | 文件 | 用途 |
|---|---|---|---|
| GatewayClient | WebSocket + REST | lib/gateway-client.ts |
外部 Gateway 进程 |
| KernelClient | Tauri invoke() | lib/kernel-chat.ts |
内置 Kernel (桌面端) |
| SaaSRelayGatewayClient | HTTP SSE | lib/saas-relay-client.ts |
浏览器端 SaaS 中继 |
getClient() 定义: connectionStore.ts:844
所有 Store 通过 initializeStores() (store/index.ts:94) 获取共享 client。
Store 层 (17 文件 + chat/4)
desktop/src/store/
├── index.ts Store 协调器 + client 注入
├── agentStore.ts Agent 分身管理
├── browserHandStore.ts 浏览器 Hand 状态
├── chatStore.ts 聊天通用状态
├── classroomStore.ts 课堂模式
├── configStore.ts 配置读写
├── connectionStore.ts 路由决策核心
├── handStore.ts Hand 状态管理
├── memoryGraphStore.ts 记忆图谱
├── offlineStore.ts 离线队列
├── saasStore.ts SaaS 认证
├── securityStore.ts 安全状态
├── sessionStore.ts 会话管理
├── uiModeStore.ts 双模式 UI
├── workflowBuilderStore.ts 工作流构建器
├── workflowStore.ts 工作流状态
└── chat/
├── artifactStore.ts 聊天产物
├── conversationStore.ts 会话管理
├── messageStore.ts 消息持久化
└── streamStore.ts 流式编排
lib/ 工具层 (85 个文件)
关键分类:
| 类别 | 文件 | 数量 |
|---|---|---|
| Kernel 通信 | kernel-chat/kernel-client/kernel-agent/... | 7 |
| SaaS 通信 | saas-client/saas-auth/saas-billing/... | 9 |
| Gateway | gateway-client/gateway-api/gateway-auth/... | 6 |
| Intelligence | intelligence-client/ + 5 fallback | 7 |
| 工具 | config-parser/crypto-utils/logger/utils | 10+ |
| Tauri 集成 | safe-tauri/tauri-gateway/secure-storage | 3 |
关联模块
- chat — 路由决定使用哪种 ChatStream
- saas — Token Pool、认证、模型管理
- middleware — 请求经过中间件链处理
- butler — 管家模式通过 ButlerRouter 中间件介入
关键文件
| 文件 | 职责 |
|---|---|
desktop/src/store/connectionStore.ts |
路由决策核心 |
desktop/src/lib/gateway-client.ts |
WebSocket 客户端 |
desktop/src/lib/kernel-chat.ts |
Tauri 内核聊天 |
desktop/src/lib/kernel-client.ts |
Kernel 客户端配置 |
desktop/src/lib/saas-relay-client.ts |
SaaS SSE 中继 |
desktop/src/lib/saas-client.ts |
SaaS API 客户端 |
desktop/src/store/index.ts |
Store 协调器 + client 注入 |