Files
zclaw_openfang/wiki/routing.md
iven c10e50d58e docs(wiki): Phase D完成 — 6模块页重构(routing/chat/butler/hands-skills/pipeline/data-model)
- routing.md: 移除Store/lib列表+5节模板 (330→131行)
- chat.md: 添加集成契约+不变量 (180→134行)
- butler.md: 移除重复→引用memory/hands-skills (215→150行)
- hands-skills.md: 5节模板+契约+不变量 (281→170行)
- pipeline.md: 添加契约+重组 (157→154行)
- data-model.md: 添加契约+双库架构图 (181→153行)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 21:53:17 +08:00

5.1 KiB
Raw Blame History

title, updated, status, tags
title updated status tags
客户端路由 2026-04-22 active
module
routing
connection

客户端路由

index 导航。关联模块: chat saas

1. 设计决策

核心: Tauri 桌面端通过 SaaS Token Pool 中转访问 LLM不直连。

决策 原因
5 分支路由 覆盖全部部署形态: Admin本地 / Tauri+SaaS / Browser+SaaS / Tauri本地 / 外部Gateway
SaaS Relay 中转 集中密钥管理 — 用户无需自备 API Key用量追踪计费 — 每次调用经 SaaS模型白名单 — Admin 控制可用模型
自动降级到本地 Kernel SaaS 不可达时桌面端不变砖,无感切换,不需要用户干预
Kernel 不直连 LLM 直连是降级后备。主路径经 SaaS Token Pool 做 RPM/TPM 轮换 + 故障转移
getClient() 全局单例 所有 Store 通过 initializeStores() 获取共享 client避免重复连接

2. 关键文件 + 数据流

核心文件

文件 职责
desktop/src/store/connectionStore.ts 路由决策核心: 5 分支 + 降级 + 模型路由
desktop/src/lib/kernel-chat.ts KernelClient ChatStream (Tauri Event)
desktop/src/lib/kernel-client.ts Kernel 客户端配置 (setConfig/boot)
desktop/src/lib/saas-relay-client.ts SaaS Relay ChatStream (SSE)
desktop/src/lib/gateway-client.ts External Gateway ChatStream (WebSocket)
desktop/src/store/index.ts Store 协调器 + client 注入

5 分支决策树

connect()
  ├─ [1] Admin强制本地: adminRouting=local && isTauri → Kernel 直连
  ├─ [2] SaaS+Tauri: savedMode=saas && isTauri → KernelClient + baseUrl=SaaS relay
  │     └─ SaaS不可达 → 降级 [4]
  ├─ [3] SaaS+Browser: savedMode=saas && !isTauri → SaaSRelayClient (SSE)
  │     └─ SaaS不可达 → 降级 [4]
  ├─ [4] 本地Kernel: isTauriRuntime && 非SaaS → KernelClient + 用户自配 Key
  └─ [5] 外部Gateway: !isTauri → GatewayClient (WebSocket)

集成契约

方向 模块 接口 说明
Calls -> saas relay URL + JWT Chat relay, model list, 用量上报
Calls -> kernel Tauri invoke Kernel boot, chat, config
Called by <- all stores getClient() 每个 API 调用都经过路由决策
Provides -> UI Connection status, model list 所有聊天依赖组件消费

3. 代码逻辑

模型路由链 (SaaS Relay 主路径)

前端选择模型 → preferredModel || fallbackId
  → kernelClient.setConfig({ model, apiKey: JWT, baseUrl: saasUrl/api/v1/relay })
    → Tauri invoke kernel_init → Kernel::boot(config)
      → loop_runner → POST {base_url}/chat/completions
        → SaaS Relay → cache 精确匹配 model_id → Key Pool 轮换 → 真实 LLM
          → SSE 流式返回

SaaS 降级流程

listModels() 失败
  → 401 → session 过期 → logout
  → 其他 → saasDegraded=true → 降级本地 Kernel

客户端类型

客户端 传输 用途
GatewayClient WebSocket + REST 外部 Gateway 进程
KernelClient Tauri invoke() 内置 Kernel (桌面端)
SaaSRelayGatewayClient HTTP SSE 浏览器端 SaaS 中继

不变量

  • getClient() 是全局单例,所有 Store 通过 initializeStores() 获取共享 client
  • SaaS 不可达时自动降级到本地 Kernel不需要用户干预
  • SaaS Relay 按 model_id 精确匹配,不解析别名 (config.toml [llm.aliases] 仅本地 Kernel)
  • Provider Key 解密失败时 warn+skip不 500 (key_pool.rs)

Tauri 命令

命令 说明
kernel_init 初始化 Kernel 配置 (model, apiKey, baseUrl)
zclaw_start / zclaw_stop / zclaw_restart Kernel 生命周期管理
zclaw_health_check / zclaw_ping 健康检查 + 端口检测
zclaw_doctor 完整诊断报告

SaaS Relay 路由

路径 说明
POST /api/v1/relay/chat/completions 主聊天中转 (认证+配额)
GET /api/v1/relay/models 可用模型列表

4. 活跃问题 + 注意事项

问题 状态 说明
Tauri invoke 参数名 snake_case 已修复 (f6c5dd2) Tauri 2.x 默认 rename_all="camelCase"invoke 必须用 camelCase
Provider Key 解密致 relay 500 已修复 (b69dc61) decrypt 失败 warn+skip启动时 heal_provider_keys() 自动重新加密
Tauri 命令孤儿 ~0 (差异来自内部调用) 190 定义 / 104 invoke / 97 @reserved

注意事项:

  • summarizer_adapter.rsextraction_adapter.rskernel_init 时配置,使用与聊天相同的 model+base_url。未配置时明确报错不静默 fallback
  • Browser 模式 getModel() 未获取到模型时 onError 报错,不发请求

5. 变更日志

日期 变更
04-22 Wiki 重写: 5 节模板,移除 Store/lib 全量列表
04-21 上一轮更新
04-19 TRUTH.md 数字校准: 190 命令 / 104 invoke / 97 @reserved
04-16 Provider Key 解密修复 (b69dc61)
04-16 Tauri invoke 参数名修复 (f6c5dd2)