docs(wiki): 重构为模块化知识库 — 按模块组织而非按文档类型
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

问题: 旧 wiki 按文档类型组织(architecture/data-flows/file-map),
修复 Butler Router 需要读 4 个文件才能拼凑全貌。
且 SaaS Relay 主路径 vs 本地降级的优先级描述不准确。

重构为模块化结构,每个模块页自包含:
- 设计思想: 为什么这样设计
- 代码逻辑: 数据流 + 关键代码
- 关联模块: 依赖关系

新增模块页:
- routing.md: 客户端路由 (明确 SaaS Relay 是主路径,不是本地模式)
- chat.md: 聊天系统 (3种实现 + Token Pool 中转机制)
- butler.md: 管家模式 (路由/冷启动/痛点/双模式UI)
- memory.md: 记忆管道 (提取→FTS5→检索→注入)
- saas.md: SaaS平台 (认证/Token池/计费/Admin)
- middleware.md: 中间件链 (14层 + 优先级)
- hands-skills.md: Hands(9) + Skills(75)
- pipeline.md: Pipeline DSL

删除旧文件: architecture.md, data-flows.md, module-status.md, file-map.md
(内容已分布到对应模块页中)

添加 .gitignore 排除 Obsidian 工作区状态文件
This commit is contained in:
iven
2026-04-11 00:36:26 +08:00
parent 9772d6ec94
commit 36a1c87d87
18 changed files with 839 additions and 627 deletions

4
wiki/.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
.obsidian/workspace.json
.obsidian/workspace-mobile.json
.obsidian/plugins/
.trash/

1
wiki/.obsidian/app.json vendored Normal file
View File

@@ -0,0 +1 @@
{}

1
wiki/.obsidian/appearance.json vendored Normal file
View File

@@ -0,0 +1 @@
{}

33
wiki/.obsidian/core-plugins.json vendored Normal file
View File

@@ -0,0 +1,33 @@
{
"file-explorer": true,
"global-search": true,
"switcher": true,
"graph": true,
"backlink": true,
"canvas": true,
"outgoing-link": true,
"tag-pane": true,
"footnotes": false,
"properties": true,
"page-preview": true,
"daily-notes": true,
"templates": true,
"note-composer": true,
"command-palette": true,
"slash-command": false,
"editor-status": true,
"bookmarks": true,
"markdown-importer": false,
"zk-prefixer": false,
"random-note": false,
"outline": true,
"word-count": true,
"slides": false,
"audio-recorder": false,
"workspaces": false,
"file-recovery": true,
"publish": false,
"sync": true,
"bases": true,
"webviewer": false
}

View File

@@ -1,147 +0,0 @@
---
title: 系统架构
updated: 2026-04-11
status: active
tags: [architecture, core]
---
# 系统架构
> 从 [[index]] 导航到此处。详细架构参考: `docs/ARCHITECTURE_BRIEF.md`
## Crate 依赖关系
```
zclaw-types (L1: 基础类型, 无依赖)
zclaw-memory (L2: SQLite, KV, 会话)
zclaw-runtime (L3: 4 Driver, 7 工具, 14 中间件)
zclaw-kernel (L4: 182 Tauri 命令, 核心协调)
zclaw-saas (独立: Axum + PostgreSQL, 端口 8080)
desktop/src-tauri (集成: kernel + skills + hands + protocols)
```
并行 crates (不依赖 runtime):
- `zclaw-skills` — 75 SKILL.md 解析 + 语义路由
- `zclaw-hands` — 9 自主能力
- `zclaw-protocols` — MCP 完整 + A2A feature-gated
- `zclaw-pipeline` — Pipeline DSL v1/v2 + DAG 执行器
- `zclaw-growth` — 记忆增长 (FTS5 + TF-IDF + Embedding trait)
## 客户端路由 (4 分支)
```
getClient()
├── [1] Admin 路由: localStorage llm_routing → relay/local
├── [2] SaaS Relay: SaaS不可达→降级到本地 Kernel
├── [3] Local Kernel: Tauri 内置 (桌面端默认)
└── [4] External Gateway: WebSocket/REST fallback
```
关键文件: `desktop/src/store/connectionStore.ts:844`
## 聊天流 (3 种实现)
| 实现 | 传输 | 场景 |
|------|------|------|
| GatewayClient | WebSocket | 外部 Gateway 进程 |
| KernelClient | Tauri Event | 内置 Kernel (默认) |
| SaaSRelay | HTTP SSE | 浏览器端 SaaS 中继 |
统一回调: `{ onDelta, onThinkingDelta, onTool, onHand, onComplete, onError }`
5 分钟超时守护: `desktop/src/lib/kernel-chat.ts:76`
## LLM 驱动 (4 + 3)
### Rust Driver
| Driver | 文件 | 协议 |
|--------|------|------|
| AnthropicDriver | `crates/zclaw-runtime/src/driver/anthropic.rs` | Anthropic Messages |
| OpenAiDriver | `crates/zclaw-runtime/src/driver/openai.rs` | OpenAI Chat |
| GeminiDriver | `crates/zclaw-runtime/src/driver/gemini.rs` | Google Gemini |
| LocalDriver | `crates/zclaw-runtime/src/driver/local.rs` | Ollama |
### 国内兼容 (通过 OpenAI 协议 + base_url)
| Provider | base_url |
|----------|----------|
| DeepSeek | `https://api.deepseek.com` |
| Qwen/GLM | `https://dashscope.aliyuncs.com/compatible-mode/v1` |
| Moonshot | `https://api.moonshot.cn/v1` |
API Key → OS keyring (`secure-storage.ts`)
## 管家模式 (默认激活)
```
用户消息 → ButlerRouter (4域关键词分类) → 增强 system prompt → LLM
PainAggregator → PainStorage (内存+SQLite)
SolutionGenerator (痛点→方案)
```
- 冷启动: idle → greeting_sent → waiting_response → completed
- UI 双模式: simple (纯聊天, 默认) / professional (完整功能)
- ButlerRouter 文件: `crates/zclaw-runtime/src/middleware/butler_router.rs`
## 记忆管道 (闭环)
```
对话 → extraction_adapter (LLM 提取)
→ FTS5 全文索引 + TF-IDF 权重
→ 检索 (查询时召回)
→ 注入 system prompt (token 预算控制)
```
- EmbeddingClient trait 已定义但未激活
- zclaw-saas 有 pgvector HNSW 索引就绪embedding 生成 deferred
## SaaS 认证
| 数据 | 存储 |
|------|------|
| JWT Token | OS Keyring |
| 账户信息 | localStorage |
| Cookie | HttpOnly + Secure + SameSite=Strict |
- JWT password_version: 改密码→所有旧 JWT 失效
- Token 池: RPM/TPM 限流轮换
- SaaS unreachable → 自动降级本地 Kernel
## 中间件链 (14 层)
关键中间件:
- DataMasking@90 — 请求前数据脱敏
- ButlerRouter — 4域关键词分类 + system prompt 增强
- TrajectoryRecorder@650 — 轨迹记录压缩
## 关键文件速查
### 前端
| 文件 | 职责 |
|------|------|
| `desktop/src/store/connectionStore.ts` | 客户端路由 |
| `desktop/src/store/chat/streamStore.ts` | 流式消息编排 |
| `desktop/src/store/chat/conversationStore.ts` | 会话管理 |
| `desktop/src/store/saasStore.ts` | SaaS 认证 |
| `desktop/src/store/uiModeStore.ts` | 简洁/专业模式 |
| `desktop/src/hooks/use-cold-start.ts` | 管家冷启动 |
### 后端
| 文件 | 职责 |
|------|------|
| `crates/zclaw-kernel/src/kernel/mod.rs` | Kernel 启动 |
| `crates/zclaw-runtime/src/loop_runner.rs` | 主聊天循环 |
| `crates/zclaw-saas/src/auth/handlers.rs` | SaaS 认证 |
| `desktop/src-tauri/src/lib.rs` | Tauri 命令注册 |
→ 数据流细节见 [[data-flows]]
→ 模块状态见 [[module-status]]

83
wiki/butler.md Normal file
View File

@@ -0,0 +1,83 @@
---
title: 管家模式
updated: 2026-04-11
status: active
tags: [module, butler, interaction]
---
# 管家模式 (Butler Mode)
> 从 [[index]] 导航。关联模块: [[chat]] [[middleware]] [[memory]]
## 设计思想
**核心问题: 非技术用户(如医院行政)不会写 prompt需要 AI 主动引导。**
设计决策:
1. **默认激活** — 所有聊天都经过 ButlerRouter不需要用户手动开启
2. **4 域关键词分类** — healthcare / data_report / policy / meeting自动增强 system prompt
3. **痛点积累** — 从对话中提取用户痛点,积累后生成方案建议
4. **双模式 UI** — simple(纯聊天,默认) / professional(完整功能),渐进式解锁
## 代码逻辑
### 数据流
```
用户消息
→ ButlerRouter 中间件 (middleware/butler_router.rs)
→ SemanticSkillRouter TF-IDF 匹配 75 个技能
→ 4 域关键词分类
→ 增强 system prompt (领域专用指令)
→ LLM 响应
→ PainAggregator 提取痛点
→ PainStorage (内存 Vec 热缓存 + SQLite 持久层)
→ 全局 PAIN_STORAGE 单例
→ SolutionGenerator
→ 基于痛点生成解决方案提案
```
### 冷启动 (新用户引导)
入口: `desktop/src/hooks/use-cold-start.ts`
```
idle → (检测新用户) → greeting_sent → waiting_response → completed
```
4 个阶段,自动检测用户是否需要引导,发送欢迎消息,等待响应后完成。
### UI 双模式
| 模式 | Store | 特点 |
|------|-------|------|
| simple (默认) | `uiModeStore.ts` | 纯聊天界面,隐藏高级功能 |
| professional | `uiModeStore.ts` | 完整功能面板 |
切换文件: `desktop/src/store/uiModeStore.ts`
简洁侧边栏: `desktop/src/components/SimpleSidebar.tsx`
管家面板: `desktop/src/components/ButlerPanel.tsx` (3 区: 洞察/方案/记忆)
## 关联模块
- [[middleware]] — ButlerRouter 是中间件链中的一层
- [[chat]] — 消息流经过管家路由增强
- [[memory]] — 痛点存储在 memory 子系统
- [[hands-skills]] — 语义路由使用 75 个技能的 TF-IDF
## 关键文件
| 文件 | 职责 |
|------|------|
| `crates/zclaw-runtime/src/middleware/butler_router.rs` | 管家路由器 (4域分类) |
| `crates/zclaw-kernel/src/intelligence/pain_storage.rs` | 痛点双写 (内存+SQLite) |
| `crates/zclaw-kernel/src/intelligence/solution_generator.rs` | 方案生成 |
| `desktop/src/hooks/use-cold-start.ts` | 冷启动 4 阶段 |
| `desktop/src/store/uiModeStore.ts` | 双模式切换 |
| `desktop/src/components/SimpleSidebar.tsx` | 简洁模式侧边栏 |
| `desktop/src/components/ButlerPanel.tsx` | 管家面板 (洞察/方案/记忆) |
## Tauri 命令
6 个 butler 专属命令 (已标注 @reserved):
`butler_get_pain_points`, `butler_get_solutions`, `butler_delegate_task`, 等

92
wiki/chat.md Normal file
View File

@@ -0,0 +1,92 @@
---
title: 聊天系统
updated: 2026-04-11
status: active
tags: [module, chat, stream]
---
# 聊天系统
> 从 [[index]] 导航。关联模块: [[routing]] [[saas]] [[butler]]
## 设计思想
**核心问题: 3 种运行环境需要 3 种 ChatStream 实现。**
| 环境 | 实现 | 传输 | 为什么 |
|------|------|------|--------|
| 桌面端 (Tauri) | KernelClient | Tauri Event | 内置 Kernel但 baseUrl 可指向 SaaS relay |
| 桌面端 (Tauri + SaaS) | KernelClient + relay | Tauri Event → SaaS | 主路径: Token Pool 中转 |
| 浏览器端 | SaaSRelayGatewayClient | HTTP SSE | 无 Tauri 运行时 |
| 外部 Gateway | GatewayClient | WebSocket | 独立进程部署 |
**统一接口**: 3 种实现共享同一套回调:
```ts
{ onDelta, onThinkingDelta, onTool, onHand, onComplete, onError }
```
## 代码逻辑
### 发送消息流
入口: `streamStore.sendMessage(content)``streamStore.ts`
```
sendMessage(content)
→ effectiveSessionKey = conversationStore.sessionKey || uuid()
→ effectiveAgentId = resolveGatewayAgentId(currentAgent)
→ client.chatStream(content, callbacks, { sessionKey, agentId, chatMode })
→ KernelClient: Tauri invoke('kernel_chat', ...)
→ Kernel → loop_runner → LLM Driver
→ 如果 baseUrl 指向 SaaS relay → 请求发往 Token Pool → LLM
→ 如果 baseUrl 指向 LLM 直连 → 请求直接发往 LLM
→ Tauri Event emit('chat-response-delta', ...)
→ onDelta(text) → streamStore 追加 delta
→ onTool(tool) → toolStore 更新
→ onHand(hand) → handStore 更新
→ onComplete() → conversationStore 持久化
→ SaaSRelay: HTTP POST /api/v1/relay/chat/completions → SSE
→ GatewayClient: WebSocket send → onmessage
→ 5 分钟超时守护 (kernel-chat.ts:76) 防止流挂起
```
### Store 拆分 (4 Store)
原来 908 行的 ChatStore 已拆分为:
| Store | 文件 | 职责 |
|-------|------|------|
| streamStore | `store/chat/streamStore.ts` | 流式消息编排、发送、取消 |
| conversationStore | `store/chat/conversationStore.ts` | 会话管理、当前模型 |
| messageStore | `store/chat/messageStore.ts` | 消息持久化 |
| chatStore | `store/chat/chatStore.ts` | 聊天通用状态 |
### 模型切换
```
UI 选择模型 → conversationStore.currentModel = newModel
→ 下次 sendMessage 时connectionStore 读取 currentModel
→ SaaS 模式: relay 白名单验证 → 可用则切换
→ 本地模式: 直接使用用户配置的模型
```
## 关联模块
- [[routing]] — 路由决定使用哪种 client
- [[saas]] — Token Pool 提供模型和 API Key
- [[butler]] — ButlerRouter 中间件增强 system prompt
- [[middleware]] — 消息经过 14 层中间件处理
- [[memory]] — 对话内容可能触发记忆提取
## 关键文件
| 文件 | 职责 |
|------|------|
| `desktop/src/store/chat/streamStore.ts` | 流式消息编排 |
| `desktop/src/store/chat/conversationStore.ts` | 会话管理 |
| `desktop/src/lib/kernel-chat.ts` | Kernel ChatStream (Tauri) |
| `desktop/src/lib/saas-relay-client.ts` | SaaS Relay ChatStream |
| `desktop/src/lib/gateway-client.ts` | Gateway ChatStream (WS) |
| `desktop/src/components/ChatArea.tsx` | 聊天区域 UI |
| `crates/zclaw-runtime/src/loop_runner.rs` | Rust 主聊天循环 |

View File

@@ -1,148 +0,0 @@
---
title: 核心数据流
updated: 2026-04-11
status: active
tags: [data-flow, architecture]
---
# 核心数据流
> 从 [[index]] 导航到此处。架构细节见 [[architecture]]
## 主数据流
```
用户操作 → React UI → Zustand Store → Tauri invoke() → zclaw-kernel → LLM/Tools/Skills/Hands
```
这是 ZCLAW 最核心的一条数据通路。所有用户交互都经过这条链路。
## 聊天消息流
```
用户输入
→ streamStore.sendMessage(content)
→ effectiveSessionKey = conversationStore.sessionKey || uuid()
→ effectiveAgentId = resolveGatewayAgentId(currentAgent)
→ client.chatStream(content, callbacks, options)
→ [KernelClient] Tauri invoke('kernel_chat', ...)
→ Kernel → loop_runner → LLM Driver
→ Tauri Event emit('chat-response-delta', ...)
→ onDelta(text) → streamStore 追加 delta
→ onTool(tool) → toolStore 更新
→ onHand(hand) → handStore 更新
→ onComplete() → conversationStore 持久化
→ [SaaSRelay] HTTP POST /api/v1/relay/chat → SSE stream
→ [GatewayClient] WebSocket send → onmessage 回调
→ 5 分钟超时守护 (kernel-chat.ts:76)
```
## 客户端路由决策流
```
connectionStore.connect(url?, token?)
├── Admin 模式? → localStorage('zclaw-saas-account').llm_routing
│ ├── "relay" → SaaS Relay
│ └── "local" → Kernel (adminForcedLocal=true)
├── SaaS 模式? → localStorage('zclaw-connection-mode') === 'saas'
│ → health check SaaS
│ ├── 可达 → Tauri: KernelClient + SaaS baseUrl
│ │ Browser: SaaSRelayGatewayClient (SSE)
│ └── 不可达 → 降级到本地 Kernel
├── Tauri 桌面? → isTauriRuntime() === true
│ → KernelClient + 自定义模型配置
└── Fallback → GatewayClient via WebSocket/REST
```
## 记忆管道流
```
对话发生
→ extraction_adapter (LLM 提取: 偏好/知识/经验)
→ MemoryEntry { agent_id, memory_type, content, keywords }
→ SqliteStorage.store()
→ FTS5 全文索引 + TF-IDF 权重计算
→ (可选) EmbeddingClient.embed() → 向量存储 [未激活]
查询时:
→ MemoryRetriever.retrieve(query, agent_id)
→ QueryAnalyzer: 意图分类 + 关键词提取 + 同义词扩展 (CJK)
→ SemanticScorer: TF-IDF 匹配 + (可选) embedding 相似度
→ 返回 top-k 相关记忆
注入时:
→ PromptInjector.inject(system_prompt, memories)
→ token 预算控制
→ 格式化为结构化上下文块
→ 插入到 system prompt 中
```
## SaaS 认证流
```
用户登录
→ POST /api/v1/auth/login { email, password }
→ 验证 (Argon2id + OsRng 盐)
→ 签发 JWT (Claims: user_id, role, pwv)
→ set_auth_cookies():
zclaw_access_token (path:/api, 2h TTL, HttpOnly)
zclaw_refresh_token (path:/api/v1/auth, 7d TTL, HttpOnly)
→ 前端: saasStore 存储 → OS keyring 存 JWT
Token 刷新:
→ POST /api/v1/auth/refresh
→ 验证 refresh_token (单次使用,旧 token 撤销到 DB)
→ 签发新 access + refresh token
密码修改:
→ 更新 password_version (pwv)
→ 所有旧 JWT 自动失效 (Claims.pwv != DB.pwv)
```
## 管家模式流
```
用户消息
→ ButlerRouter 中间件
→ 关键词 4 域分类: healthcare / data_report / policy / meeting
→ 增强 system prompt (领域专用指令)
→ LLM 响应
→ PainAggregator 提取痛点
→ PainStorage (内存 Vec 热缓存 + SQLite 持久)
→ SolutionGenerator
→ 基于痛点生成解决方案提案
冷启动:
idle → (检测新用户) → greeting_sent → waiting_response → completed
```
## Pipeline 执行流
```
YAML Pipeline 定义
→ PipelineExecutor.load(yaml)
→ 构建 DAG (按依赖排序)
→ 逐步执行:
→ ActionRegistry.resolve(action_type)
→ 执行 action → PipelineRun.step_results
→ 全部完成 → PipelineRun.status = Completed
→ 17 个行业模板在 pipelines/ 目录
```
## Hands 触发流
```
UI 触发 → handStore.trigger(handName, params)
→ Tauri invoke('hand_trigger', { handName, params })
→ Kernel → Hand 执行
→ needs_approval? → 等待 approvalStore 确认
→ 执行结果 → Tauri Event emit
→ handStore 更新状态 + 记录日志
```
→ 架构组件见 [[architecture]]
→ 模块状态见 [[module-status]]

View File

@@ -1,149 +0,0 @@
---
title: 文件地图
updated: 2026-04-11
status: active
tags: [files, reference]
---
# 文件地图
> 从 [[index]] 导航到此处。找什么去哪里。
## 项目顶层
```
ZCLAW/
├── CLAUDE.md → AI 协作规范(唯一入口)
├── wiki/ → 编译后知识库(新会话入口)
├── docs/ → 原始文档raw 层)
├── skills/ → 75 个 SKILL.md
├── hands/ → HAND.toml 配置
├── config/ → TOML 配置模板
├── pipelines/ → 17 个 YAML Pipeline 模板
├── saas-config.toml → SaaS 后端配置
├── docker-compose.yml → PostgreSQL 容器
```
## Rust Crates
```
crates/
├── zclaw-types/ → L1 基础类型 (AgentId, Message, Error)
│ └── src/types.rs
├── zclaw-memory/ → L2 存储层
│ └── src/sqlite.rs, session_manager.rs
├── zclaw-runtime/ → L3 运行时
│ ├── src/driver/ → 4 LLM Driver (anthropic/openai/gemini/local.rs)
│ ├── src/middleware/ → 14 层中间件
│ │ ├── butler_router.rs → 管家路由
│ │ ├── data_masking.rs → 数据脱敏
│ │ └── trajectory_recorder.rs → 轨迹记录
│ ├── src/loop_runner.rs → 主聊天循环
│ └── src/tools/ → 7 个工具
├── zclaw-kernel/ → L4 核心协调
│ ├── src/kernel/mod.rs → Kernel 启动序列
│ ├── src/config.rs → LLM 配置 + Driver 工厂
│ └── src/intelligence/ → 管家/痛点/方案/人格
│ ├── pain_storage.rs
│ ├── solution_generator.rs
│ └── personality_detector.rs
├── zclaw-skills/ → 技能系统
│ └── src/semantic_router.rs → TF-IDF 语义路由
├── zclaw-hands/ → 自主能力
│ └── src/ (Browser/Collector/Researcher/...)
├── zclaw-protocols/ → 协议 (MCP + A2A feature-gated)
├── zclaw-pipeline/ → Pipeline DSL
│ └── src/executor.rs → DAG 执行器
├── zclaw-growth/ → 记忆增长
│ ├── src/extractor.rs → LLM 记忆提取
│ ├── src/retriever.rs → 语义检索
│ ├── src/injector.rs → Prompt 注入
│ ├── src/experience_store.rs → 经验 CRUD
│ └── src/storage/sqlite.rs → FTS5 + TF-IDF
│ └── src/retrieval/semantic.rs → EmbeddingClient trait
└── zclaw-saas/ → SaaS 后端 (Axum + PostgreSQL)
├── src/auth/ → 认证 (JWT + Cookie + TOTP)
├── src/knowledge/ → 知识库 (23 API + pgvector)
├── src/billing/ → 计费 (Alipay/WeChat)
├── src/workers/ → 7 后台 Worker
└── migrations/ → SQL 迁移 (34 表)
```
## 前端 (desktop/src/)
```
desktop/src/
├── store/ → 18 Zustand Store
│ ├── connectionStore.ts → 客户端路由 (844行, 核心中枢)
│ ├── saasStore.ts → SaaS 认证
│ ├── uiModeStore.ts → 简洁/专业模式
│ └── chat/ → 4 Store (stream/conversation/message/chat)
│ ├── streamStore.ts
│ └── conversationStore.ts
├── components/ → ~135 React 组件
│ ├── ChatArea.tsx → 聊天区域
│ ├── SimpleSidebar.tsx → 简洁模式侧边栏
│ └── ButlerPanel.tsx → 管家面板
├── hooks/ → React Hooks
│ └── use-cold-start.ts → 管家冷启动
├── lib/ → 通信和工具
│ ├── gateway-client.ts → WebSocket 客户端
│ ├── kernel-chat.ts → Tauri 内核聊天
│ ├── saas-relay-client.ts → SaaS SSE 中继
│ ├── tauri-gateway.ts → Tauri 原生命令
│ ├── pipeline-client.ts → Pipeline 客户端
│ ├── secure-storage.ts → OS keyring 存储
│ └── webmcp-tools.ts → WebMCP 调试工具
└── store/index.ts → Store 协调器 + client 注入
```
## Admin V2 (admin-v2/)
```
admin-v2/src/
├── pages/ → 15 页面 (Dashboard/Agents/Knowledge/Billing/...)
├── services/ → SaaS API 调用封装
└── tests/ → 17 测试文件 (61 tests)
```
## 文档 (docs/)
```
docs/
├── TRUTH.md → 数字的唯一真相源
├── ARCHITECTURE_BRIEF.md → 架构参考
├── features/ → 功能文档
│ ├── README.md → 功能索引
│ ├── AUDIT_TRACKER.md → 审计进度
│ └── audit-v12/ → V12 模块化审计报告
├── knowledge-base/ → 技术知识库
├── superpowers/
│ ├── specs/ → 设计规格文档
│ ├── plans/ → 实施计划
│ └── reports/ → 测试报告
└── archive/ → 归档文档 (~70+ 文件)
```
## Memory (.claude/projects/)
```
.claude/projects/g--ZClaw-openfang/memory/
├── MEMORY.md → memory 索引
└── 47 个 .md 文件 → 会话间工作记录
```
→ 架构见 [[architecture]]
→ 开发规范见 [[development]]

90
wiki/hands-skills.md Normal file
View File

@@ -0,0 +1,90 @@
---
title: Hands + Skills
updated: 2026-04-11
status: active
tags: [module, hands, skills]
---
# Hands + Skills
> 从 [[index]] 导航。关联模块: [[chat]] [[middleware]]
## 设计思想
**Hands = 自主能力 (行动层), Skills = 知识技能 (认知层)**
- Hands: 浏览器自动化、数据收集、Twitter 操作等 — **执行动作**
- Skills: 75 个 SKILL.md 文件 — **语义路由匹配**,增强 LLM 的领域知识
- 触发: 用户请求 → LLM 判断需要执行 → 选择 Hand/Skill → 执行
## 代码逻辑
### Hands (9 启用 + 2 禁用)
| Hand | 功能 | 依赖 | 配置 |
|------|------|------|------|
| Browser | 浏览器自动化 | WebDriver | `hands/Browser/HAND.toml` |
| Collector | 数据收集聚合 | — | `hands/Collector/HAND.toml` |
| Researcher | 深度研究 | LLM | `hands/Researcher/HAND.toml` |
| Clip | 视频处理 | FFmpeg | `hands/Clip/HAND.toml` |
| Twitter | Twitter 自动化 | OAuth 1.0a | `hands/Twitter/HAND.toml` |
| Whiteboard | 白板演示 | — | `hands/Whiteboard/HAND.toml` |
| Slideshow | 幻灯片生成 | — | `hands/Slideshow/HAND.toml` |
| Speech | 语音合成 | Browser TTS | `hands/Speech/HAND.toml` |
| Quiz | 测验生成 | — | `hands/Quiz/HAND.toml` |
| Predictor | 预测分析 | **禁用** | 无 TOML/无 Rust 实现 |
| Lead | 销售线索 | **禁用** | 无 TOML/无 Rust 实现 |
### 触发流
```
UI 触发 → handStore.trigger(handName, params)
→ Tauri invoke('hand_trigger', { handName, params })
→ Kernel → Hand 执行
→ needs_approval? → 等待 approvalStore 确认
→ 执行结果 → Tauri Event emit
→ handStore 更新状态 + 记录日志
```
### Skills (75 个)
```
skills/
├── SKILL_001_数据分析.md
├── SKILL_002_报告生成.md
├── ... (75 个 SKILL.md 文件)
```
每个 SKILL.md 定义:
- 技能名称和描述
- 触发条件
- 执行步骤
- 输入/输出格式
### 语义路由
`crates/zclaw-skills/src/semantic_router.rs`
```
用户消息 → SemanticSkillRouter
→ TF-IDF 计算消息与 75 个技能的相似度
→ 返回最匹配的技能
→ ButlerRouter 使用此结果增强 system prompt
```
## 关联模块
- [[chat]] — 消息流中可能触发 Hand/Skill
- [[butler]] — ButlerRouter 使用语义路由匹配技能
- [[middleware]] — 技能注入通过中间件实现
## 关键文件
| 文件 | 职责 |
|------|------|
| `crates/zclaw-hands/src/` | 9 个 Hand 实现 |
| `crates/zclaw-skills/src/semantic_router.rs` | TF-IDF 语义路由 |
| `skills/*.md` | 75 个技能定义 |
| `hands/*/HAND.toml` | Hand 配置 |
| `desktop/src/store/handStore.ts` | 前端 Hand 状态 |
| `desktop/src/store/approvalStore.ts` | 审批状态 |

View File

@@ -7,90 +7,56 @@ status: active
# ZCLAW 项目知识库 # ZCLAW 项目知识库
> 面向中文用户的 AI Agent 桌面客户端。管家模式 + 多模型 + 9 自主能力 + 75 技能。 > 面向中文用户的 AI Agent 桌面客户端。管家模式 + 多模型 + 9 自主能力 + 75 技能。
> **使用方式**: 找到你要处理的模块,读对应页面,直接开始工作。
## 一句话画像 ## 项目画像
Rust 10 crates (~66K行) + React 19 + Tauri 2.x + PostgreSQL + Axum。发布前稳定化阶段功能冻结中。 | 维度 | 值 |
|------|-----|
| 定位 | AI Agent 桌面客户端 (Tauri 2.x) |
| 技术栈 | Rust 10 crates (~66K行) + React 19 + TypeScript + PostgreSQL |
| 阶段 | 发布前稳定化,功能冻结中 |
## 关键数字 ## 关键数字
| 维度 | 数量 | Rust Crates: 10 | 测试: 822 | Tauri 命令: 182 | SaaS API: 140 | Store: 18 | 中间件: 14 | Hands: 9 | Skills: 75 | Pipeline: 17
|------|------|
| Rust Crates | 10 |
| Rust 代码 | ~66,000 行 |
| Rust 测试 | 822 (684 workspace + 138 SaaS) |
| Tauri 命令 | 182 (92 有前端调用, 20 @reserved, 70 孤儿) |
| SaaS API | 140 端点 |
| SaaS 数据表 | 34 |
| Zustand Store | 18 |
| React 组件 | ~135 |
| 中间件层 | 14 |
| SKILL.md | 75 |
| Hands | 9 启用 + 2 禁用 |
| Pipeline 模板 | 17 YAML |
| LLM Provider | 8 |
## 核心架构 → [[architecture]] ## 模块导航树
- **客户端路由**: Admin / SaaS Relay / Local Kernel / External Gateway
- **聊天流**: GatewayClient(WS) / KernelClient(Tauri Event) / SaaSRelay(HTTP SSE)
- **LLM 驱动**: Anthropic / OpenAI / Gemini / Local + 国内 3 家(DeepSeek/Qwen/Moonshot)
- **管家模式**: ButlerRouter 4域分类 + 冷启动 4阶段 + 双模式UI
## 子系统状态 → [[module-status]]
| 子系统 | 状态 | 说明 |
|--------|------|------|
| 管家模式 (Butler) | 活跃 | ButlerRouter + 冷启动 + 简洁UI + 痛点持久化 |
| Hermes 管线 | 活跃 | ExperienceStore + UserProfiler + NlScheduleParser + TrajectoryRecorder |
| 聊天流 (ChatStream) | 稳定 | 3 种实现5min 超时守护 |
| 记忆管道 (Memory) | 稳定 | 对话→提取→FTS5+TF-IDF→检索→注入 |
| SaaS 认证 (Auth) | 稳定 | Token池 RPM/TPM 轮换 + JWT pwv 失效 |
| Pipeline DSL | 稳定 | 17 模板 + DAG 执行器 |
| Hands 系统 | 稳定 | 9 启用 |
| 技能系统 | 稳定 | 75 SKILL.md + 语义路由 |
| 中间件链 | 稳定 | 14 层 (含 DataMasking@90, ButlerRouter, TrajectoryRecorder@650) |
## 核心数据流 → [[data-flows]]
``` ```
用户操作 → React UI → Zustand Store → Tauri Commands → Kernel → LLM/Tools/Skills/Hands ZCLAW
├── [[routing]] 客户端路由 — 4分支决策SaaS Relay是主路径
│ └── [[chat]] 聊天系统 — 3种ChatStreamSaaS Token Pool是主路径
├── [[saas]] SaaS平台 — 认证/Token池/计费/AdminTauri的中枢
│ ├── 认证 JWT + Cookie + Token池 RPM/TPM轮换
│ ├── 计费 配额实时递增 + Alipay/WeChat
│ └── Admin V2 15页管理后台
├── [[butler]] 管家模式 — 默认交互范式4域路由+冷启动+痛点
├── [[middleware]] 中间件链 — 14层DataMasking→ButlerRouter→TrajectoryRecorder
├── [[memory]] 记忆管道 — 对话→提取→FTS5+TF-IDF→检索→注入
├── [[hands-skills]] Hands(9) + Skills(75) — 自主能力+语义技能路由
├── [[pipeline]] Pipeline DSL — YAML+DAG执行器+17行业模板
├── [[development]] 开发规范 — 闭环工作法/验证命令/提交规范
├── [[known-issues]] 已知问题 — P0/P1已修复P2待处理
└── [[log]] 变更日志 — append-only
``` ```
- 4 种 LLM Driver国内兼容通过 base_url ## 核心架构决策(为什么这样设计)
- SaaS unreachable 时自动降级到本地 Kernel
- 记忆闭环: 对话 → extraction → FTS5+TF-IDF → 检索 → 注入 system prompt
## 开发须知 → [[development]] **Q: 为什么 Tauri 不直连 LLM**
→ 因为 SaaS Token Pool 集中管理 API Key支持用量追踪、计费、模型白名单。直连是降级后备。
- **闭环工作法**: 定位→修复→验证→提交→文档,每步不可跳过 **Q: 为什么有3种 ChatStream**
- **功能冻结**: 禁止新增 SaaS API / SKILL.md / Tauri 命令 / 中间件 / admin 页面 → GatewayClient(WS) 用于外部进程KernelClient(Tauri Event) 用于桌面端SaaSRelay(SSE) 用于浏览器。Tauri 桌面端的 KernelClient 通过 `baseUrl` 指向 SaaS relay 实现间接中转。
- **验证命令**: `cargo check --workspace` / `pnpm tsc --noEmit` / `pnpm vitest run`
## 已知问题 → [[known-issues]] **Q: 为什么管家模式是默认?**
→ 面向医院行政等非技术用户4域关键词分类+痛点积累+方案生成,降低使用门槛。
- 所有 P0/P1 已修复
- 10 项 P2 代码质量问题待处理
- 70 个 Tauri 命令孤儿(无前端调用且无 @reserved
## 文件地图 → [[file-map]]
关键路径速查,按 `crates/` / `desktop/src/` / `admin-v2/` 组织。
## 变更日志 → [[log]]
Append-only 操作记录。
---
## 给新会话的快速引导
1. 先读本文件 (你正在读)
2. 需要了解架构 → 读 [[architecture]]
3. 需要了解某模块状态 → 读 [[module-status]]
4. 需要了解数据流 → 读 [[data-flows]]
5. 需要开发 → 读 [[development]]
6. 需要知道有哪些 bug → 读 [[known-issues]]
7. 需要找文件 → 读 [[file-map]]
> 数字真相源: `docs/TRUTH.md` — 如有冲突以 TRUTH.md 为准 > 数字真相源: `docs/TRUTH.md` — 如有冲突以 TRUTH.md 为准

View File

@@ -7,51 +7,24 @@ tags: [issues, bugs]
# 已知问题 # 已知问题
> 从 [[index]] 导航到此处。完整缺陷清单见 `docs/TRUTH.md §3` > 从 [[index]] 导航。完整清单见 `docs/TRUTH.md §3`
## P0 — 必然崩溃 ## 当前状态
| ID | 问题 | 状态 | | 级别 | 数量 | 状态 |
|----|------|------| |------|------|------|
| SEC2-P0-01 | skill_execute 反序列化崩溃 | 已修复 | | P0 (崩溃) | 2 | 全部已修复 |
| SEC2-P0-02 | TaskTool::default() panic | 已修复 | | P1 (功能失效) | 9 | 全部已修复 |
| P1.5 (代码质量) | 7 | 全部已修复 |
## P1 — 功能失效 | P2 (代码质量) | 10 | 待处理 |
| ID | 问题 | 状态 |
|----|------|------|
| SEC2-P1-01 | FactStore trait 零实现 | 已修复 |
| SEC2-P1-02 | agent-templates 路径错误 (缺 /api/v1) | 已修复 |
| SEC2-P1-03 | hand-execution-complete 无监听 | 已修复 |
| SEC2-P1-04 | InMemoryStorage RwLock unwrap 级联 | 已修复 |
| SEC2-P1-05~07 | HandRun 持久化静默忽略 (3处) | 已修复 |
| SEC2-P1-08 | FTS 索引更新静默失败 | 已修复 |
| SEC2-P1-09 | Worker dispatch 静默失败 | 已修复 |
## P1.5 — 代码质量
| ID | 问题 | 状态 |
|----|------|------|
| SEC2-P1.5-01 | Capability _ => false 通配符 | 已修复 |
| SEC2-P1.5-02 | billing let _ = ... 冗余 | 已修复 |
| SEC2-P1.5-03 | relay SSE 错误路径 send 失败未记录 | 已修复 |
| SEC2-P1.5-04 | WASM runner 缺少状态注解 | 已修复 |
| SEC2-P1.5-05 | Tauri 命令无连接状态标注 | 已修复 |
| SEC2-P1.5-06 | extract_token_usage 静默丢弃解析错误 | 已修复 |
| SEC2-P1.5-07 | relay current_key_id 防御性 unwrap | 已修复 |
## P2 — 代码质量(待处理)
10 项代码质量问题 (SEC2-P2-01~10),非阻塞性。详见 `docs/TRUTH.md §3.3`
## 长期观察项 ## 长期观察项
| 问题 | 说明 | 行动 | | 问题 | 说明 | 位置 |
|------|------|------| |------|------|------|
| Tauri 命令孤儿 70 个 | 无前端调用且无 @reserved | 逐步标注或清理 | | Tauri 命令孤儿 70 个 | 无前端调用且无 @reserved | `desktop/src-tauri/src/lib.rs` |
| Embedding 未激活 | EmbeddingClient trait 已写但未调用 | 发布后迭代 | | Embedding 未激活 | EmbeddingClient trait 已写但 NoOp | `zclaw-growth/src/retrieval/semantic.rs` |
| SaaS embedding deferred | pgvector 索引就绪,生成未实现 | 发布后迭代 | | SaaS embedding deferred | pgvector 索引就绪,生成未实现 | `zclaw-saas/src/workers/generate_embedding.rs` |
| webhook 死代码 | 5 路由定义但未挂载 | 待删除 | | webhook 死代码 | 5 路由定义但未挂载 | `zclaw-saas/src/webhook/` |
→ 模块状态见 [[module-status]] → 模块详情见各模块页面: [[routing]] [[chat]] [[saas]] [[memory]]
→ 开发规范见 [[development]]

106
wiki/memory.md Normal file
View File

@@ -0,0 +1,106 @@
---
title: 记忆管道
updated: 2026-04-11
status: active
tags: [module, memory, growth]
---
# 记忆管道 (Memory Pipeline)
> 从 [[index]] 导航。关联模块: [[chat]] [[middleware]]
## 设计思想
**核心问题: LLM 无状态,每次对话都从零开始。需要从历史对话中积累知识。**
设计决策:
1. **闭环架构** — 对话 → 提取 → 索引 → 检索 → 注入,形成正向循环
2. **FTS5 + TF-IDF** — 轻量级语义搜索,不依赖外部 embedding 服务
3. **Token 预算控制** — 注入 system prompt 时有 token 上限,防止溢出
4. **EmbeddingClient trait 已预留** — 接口已写,激活即可升级到向量搜索
## 代码逻辑
### 闭环数据流
```
[提取] 对话发生
→ MemoryExtractor (crates/zclaw-growth/src/extractor.rs)
→ LLM 提取: 偏好 (Preference) / 知识 (Knowledge) / 经验 (Experience)
→ MemoryEntry { agent_id, memory_type, content, keywords, importance }
[索引] 存储
→ SqliteStorage.store() (crates/zclaw-growth/src/storage/sqlite.rs)
→ SQLite + FTS5 全文索引
→ TF-IDF 权重计算
→ (可选) EmbeddingClient.embed() → 向量存储 [未激活]
[检索] 查询时
→ MemoryRetriever.retrieve(query, agent_id) (crates/zclaw-growth/src/retriever.rs)
→ QueryAnalyzer: 意图分类 (Preference/Knowledge/Experience/Code/General)
→ 中文+英文关键词提取 + CJK 支持 + 同义词扩展
→ SemanticScorer: TF-IDF 匹配 (70% embedding / 30% TF-IDF, embedding 未激活)
→ 返回 top-k 相关记忆
[注入] 给 LLM
→ PromptInjector.inject(system_prompt, memories) (crates/zclaw-growth/src/injector.rs)
→ token 预算控制
→ 格式化为结构化上下文块
→ 插入到 system prompt 中
```
### 经验存储 (ExperienceStore)
Hermes 管线 Chunk1 新增:
```
ExperienceStore (crates/zclaw-growth/src/experience_store.rs)
→ CRUD 封装: pain → solution → outcome 结构化经验
→ 底层使用 VikingAdapter
→ URI scheme: agent://{agent_id}/experience/...
```
### 查询意图分类
`QueryAnalyzer` 支持 5 种意图:
| 意图 | 说明 | 检索策略 |
|------|------|----------|
| Preference | 用户偏好 | 精确匹配 preference 类型记忆 |
| Knowledge | 知识查询 | 语义搜索 knowledge 类型 |
| Experience | 经验检索 | 时间+相关性排序 |
| Code | 代码相关 | 关键词优先 |
| General | 通用 | 混合策略 |
### Embedding 基础设施 (已写未激活)
```
EmbeddingClient trait (crates/zclaw-growth/src/retrieval/semantic.rs)
→ async embed(&str) -> Vec<f32>
→ is_available() -> bool
→ 当前实现: NoOpEmbeddingClient (始终返回空)
SaaS 侧:
→ pgvector HNSW 索引就绪 (knowledge_chunks 表, vector(1536))
→ generate_embedding Worker: 内容分块 + 中文关键词提取 (Phase 2 embedding deferred)
```
## 关联模块
- [[chat]] — 对话是记忆的输入源
- [[butler]] — 管家模式可能利用记忆提供个性化响应
- [[middleware]] — 记忆注入通过中间件或 hook 实现
## 关键文件
| 文件 | 职责 |
|------|------|
| `crates/zclaw-growth/src/extractor.rs` | LLM 记忆提取 |
| `crates/zclaw-growth/src/retriever.rs` | 语义检索 |
| `crates/zclaw-growth/src/injector.rs` | Prompt 注入 (token 预算) |
| `crates/zclaw-growth/src/experience_store.rs` | 经验 CRUD |
| `crates/zclaw-growth/src/storage/sqlite.rs` | FTS5 + TF-IDF 核心 |
| `crates/zclaw-growth/src/retrieval/semantic.rs` | EmbeddingClient trait |
| `crates/zclaw-growth/src/retrieval/query.rs` | 意图分类 + CJK 关键词 |
| `desktop/src/store/memoryStore.ts` | 前端记忆 UI |
| `desktop/src-tauri/src/memory/` | Tauri 记忆命令桥接 |

63
wiki/middleware.md Normal file
View File

@@ -0,0 +1,63 @@
---
title: 中间件链
updated: 2026-04-11
status: active
tags: [module, middleware, runtime]
---
# 中间件链
> 从 [[index]] 导航。关联模块: [[chat]] [[butler]] [[memory]]
## 设计思想
**中间件是请求处理的管道,按优先级顺序执行。**
- 优先级 0-100数值越大越先执行
- 每层中间件可以: 修改请求 / 拦截响应 / 记录日志 / 注入上下文
- 所有消息流(聊天、管家)都经过完整中间件链
## 代码逻辑
### 14 层中间件
关键中间件(按优先级排序):
| 优先级 | 中间件 | 文件 | 职责 |
|--------|--------|------|------|
| 90 | DataMasking | `middleware/data_masking.rs` | 请求发送前数据脱敏 (手机号/身份证) |
| ~500 | ButlerRouter | `middleware/butler_router.rs` | 4域关键词分类 + system prompt 增强 |
| 650 | TrajectoryRecorder | `middleware/trajectory_recorder.rs` | 轨迹记录 + 压缩 |
其他 11 层: 认证、速率限制、日志、技能注入、记忆注入等。
### 中间件执行流
```
用户消息
→ [优先级 90] DataMasking — 脱敏敏感数据
→ [优先级 ~500] ButlerRouter — 关键词分类 + prompt 增强
→ [优先级 650] TrajectoryRecorder — 记录请求轨迹
→ [其他层] 认证/限流/日志/技能/记忆
→ LLM 调用
→ 响应原路返回
```
### 注册位置
中间件在 `crates/zclaw-runtime/` 中注册Kernel 启动时加载。
## 关联模块
- [[butler]] — ButlerRouter 是管家模式的核心
- [[chat]] — 每条消息经过完整中间件链
- [[memory]] — 记忆注入层从 FTS5 检索并注入 system prompt
## 关键文件
| 文件 | 职责 |
|------|------|
| `crates/zclaw-runtime/src/middleware/` | 所有中间件实现 |
| `crates/zclaw-runtime/src/middleware/butler_router.rs` | 管家路由器 |
| `crates/zclaw-runtime/src/middleware/data_masking.rs` | 数据脱敏 |
| `crates/zclaw-runtime/src/middleware/trajectory_recorder.rs` | 轨迹记录 |

View File

@@ -1,70 +0,0 @@
---
title: 子系统状态
updated: 2026-04-11
status: active
tags: [status, modules]
---
# 子系统状态
> 从 [[index]] 导航到此处。数字真相源: `docs/TRUTH.md`
## 活跃子系统
| 子系统 | 状态 | 最新变更 | 关键文件 |
|--------|------|----------|----------|
| 管家模式 (Butler) | 活跃 | 04-09 ButlerRouter + 双模式UI + 痛点持久化 + 冷启动 | `middleware/butler_router.rs`, `pain_storage.rs` |
| Hermes 管线 | 活跃 | 04-09 4 Chunk: 自我改进+用户建模+NL Cron+轨迹压缩 | `experience_store.rs`, `user_profiler.rs`, `nl_schedule_parser.rs` |
| 聊天流 (ChatStream) | 稳定 | 04-02 ChatStore 拆分为 4 Store | `streamStore.ts`, `conversationStore.ts` |
| 记忆管道 (Memory) | 稳定 | 04-02 闭环: 对话→提取→FTS5+TF-IDF→检索→注入 | `crates/zclaw-growth/` |
| SaaS 认证 (Auth) | 稳定 | Token池 RPM/TPM 轮换 + JWT pwv 失效 | `saas/auth/handlers.rs` |
| Pipeline DSL | 稳定 | 04-01 17 YAML 模板 + DAG 执行器 | `crates/zclaw-pipeline/` |
| Hands 系统 | 稳定 | 9 启用 (详见下方) | `crates/zclaw-hands/` |
| 技能系统 (Skills) | 稳定 | 75 SKILL.md + 语义路由 | `crates/zclaw-skills/` |
| 中间件链 | 稳定 | 14 层 (含 DataMasking@90, ButlerRouter, TrajectoryRecorder@650) | `crates/zclaw-runtime/src/middleware/` |
## Hands 详细状态
| Hand | 功能 | 状态 | 依赖 |
|------|------|------|------|
| Browser | 浏览器自动化 | 可用 | WebDriver |
| Collector | 数据收集聚合 | 可用 | — |
| Researcher | 深度研究 | 可用 | LLM |
| Clip | 视频处理 | 需 FFmpeg | FFmpeg |
| Twitter | Twitter 自动化 | 可用 | OAuth 1.0a (写操作) |
| Whiteboard | 白板演示 | 可用 | 导出开发中 |
| Slideshow | 幻灯片生成 | 可用 | — |
| Speech | 语音合成 | 可用 | Browser TTS |
| Quiz | 测验生成 | 可用 | — |
| Predictor | 预测分析 | 禁用 | 无 Rust 实现 |
| Lead | 销售线索发现 | 禁用 | 无 Rust 实现 |
## Tauri 命令分布
| 类别 | 数量 | 说明 |
|------|------|------|
| 有前端调用 | 92 | 正常使用中 |
| @reserved | 20 | 已标注保留 |
| 孤儿 | 70 | 无前端调用且无标注 |
## 测试覆盖
| 层级 | 数量 | 状态 |
|------|------|------|
| Rust workspace | 684 | 全通过 |
| SaaS 集成 | 138 | 全通过 (需 PostgreSQL) |
| 前端 vitest | 330 | 330 passed + 1 skipped |
| Admin V2 | 61 | 17 文件 |
## SaaS API 分布
12 个路由模块: account / agent_template / auth / billing / knowledge / migration / model_config / prompt / relay / role / scheduled_task / telemetry
总计 140 端点 (138 标准 + 2 dev-only)
## 数据表 (34 个)
核心表: users, agents, conversations, messages, knowledge_*, billing_*, agent_templates, model_configs, roles, permissions, scheduled_tasks, telemetry
→ 架构细节见 [[architecture]]
→ 已知问题见 [[known-issues]]

70
wiki/pipeline.md Normal file
View File

@@ -0,0 +1,70 @@
---
title: Pipeline DSL
updated: 2026-04-11
status: active
tags: [module, pipeline, dsl]
---
# Pipeline DSL
> 从 [[index]] 导航。关联模块: [[hands-skills]]
## 设计思想
**Pipeline = 可编排的工作流,按 DAG 依赖顺序执行步骤。**
- YAML 定义 Pipeline 结构(步骤、依赖、输入/输出)
- DAG 执行器按依赖拓扑排序执行
- 17 个行业模板覆盖 10 大行业
- 前端已接通 8 个 Tauri invoke 调用
## 代码逻辑
### 架构
```
YAML Pipeline 定义
→ PipelineExecutor (crates/zclaw-pipeline/src/executor.rs)
→ 构建 DAG (按依赖排序)
→ 逐步执行:
→ ActionRegistry.resolve(action_type)
→ 执行 action → PipelineRun.step_results
→ 全部完成 → PipelineRun.status = Completed
```
### 运行状态
```rust
enum RunStatus { Pending, Running, Completed, Failed, Cancelled }
```
### 模板 (17 个 YAML)
位于 `pipelines/` 目录,覆盖:
- 汕头玩具行业、服装设计、医疗
- 数据分析、报告生成
- 教育、营销
- 等 10 大行业
### 前端集成
| 组件 | 文件 |
|------|------|
| PipelineClient | `desktop/src/lib/pipeline-client.ts` |
| Tauri 命令 | `desktop/src-tauri/src/pipeline_commands/` |
8 个前端 invoke 调用匹配 8 个 Rust 命令,完整可用。
## 关联模块
- [[hands-skills]] — Pipeline 步骤可能调用 Hand/Skill
## 关键文件
| 文件 | 职责 |
|------|------|
| `crates/zclaw-pipeline/src/executor.rs` | DAG 执行器 |
| `crates/zclaw-pipeline/src/` | Pipeline DSL 解析 |
| `pipelines/` | 17 个 YAML 模板 |
| `desktop/src/lib/pipeline-client.ts` | 前端 Pipeline 客户端 |
| `desktop/src-tauri/src/pipeline_commands/` | Tauri 命令桥接 |

105
wiki/routing.md Normal file
View File

@@ -0,0 +1,105 @@
---
title: 客户端路由
updated: 2026-04-11
status: active
tags: [module, routing, connection]
---
# 客户端路由
> 从 [[index]] 导航。关联模块: [[chat]] [[saas]]
## 设计思想
**核心决策: Tauri 桌面端通过 SaaS Token Pool 中转访问 LLM不直连。**
为什么?
1. **集中密钥管理** — 用户不需要自己的 API KeySaaS 维护共享 Key 池
2. **用量追踪 + 计费** — 每次调用经过 SaaS`record_usage` worker 记录 token 消耗
3. **模型白名单** — Admin 配置哪些模型可用,`listModels()` 返回白名单
4. **降级保障** — 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`
```ts
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。
## 关联模块
- [[chat]] — 路由决定使用哪种 ChatStream
- [[saas]] — Token Pool、认证、模型管理
- [[middleware]] — 请求经过中间件链处理
- [[butler]] — 管家模式通过 ButlerRouter 中间件介入
## 关键文件
| 文件 | 职责 |
|------|------|
| `desktop/src/store/connectionStore.ts` | 路由决策核心 (844行) |
| `desktop/src/lib/gateway-client.ts` | WebSocket 客户端 |
| `desktop/src/lib/kernel-chat.ts` | Tauri 内核聊天 |
| `desktop/src/lib/saas-relay-client.ts` | SaaS SSE 中继 |
| `desktop/src/lib/saas-client.ts` | SaaS API 客户端 |
| `desktop/src/store/index.ts` | Store 协调器 + client 注入 |

139
wiki/saas.md Normal file
View File

@@ -0,0 +1,139 @@
---
title: SaaS 平台
updated: 2026-04-11
status: active
tags: [module, saas, auth, billing]
---
# SaaS 平台
> 从 [[index]] 导航。关联模块: [[routing]] [[chat]]
## 设计思想
**核心定位: SaaS 是 Tauri 桌面端的中枢,不是独立 Web 应用。**
关键决策:
1. **Token Pool** — 桌面端不持有 LLM API KeySaaS 维护共享 Key 池RPM/TPM 轮换
2. **JWT + Cookie 双通道** — Tauri 用 OS keyring 存 JWT浏览器用 HttpOnly cookie
3. **计费闭环** — 配额实时递增 → 聚合器调度 → mock 支付路由
4. **Admin V2** — 15 页管理后台,管理模型/用户/计费/知识库
## 代码逻辑
### 认证流
```
用户登录 (POST /api/v1/auth/login)
→ Argon2id + OsRng 盐验证密码
→ 签发 JWT (Claims: user_id, role, pwv)
→ set_auth_cookies():
zclaw_access_token (path:/api, 2h TTL, HttpOnly)
zclaw_refresh_token (path:/api/v1/auth, 7d TTL, HttpOnly)
Secure: dev=false, prod=true | SameSite=Strict
前端存储:
→ Tauri: OS keyring → saasStore.token
→ 浏览器: HttpOnly Cookie (JS 不可读)
→ localStorage: saasUrl + account 信息 (非敏感)
```
### Token 池 + 限流
```
SaaS Relay 收到 LLM 请求 (POST /api/v1/relay/chat/completions)
→ 验证 JWT → 提取 user_id
→ 从 Token Pool 选择可用 Key (RPM/TPM 轮换)
→ 转发请求到真实 LLM API
→ 记录 usage (record_usage worker)
→ 返回响应
限流规则:
→ /api/auth/login: 5次/分钟/IP (防暴力) + 持久化到 PostgreSQL
→ /api/auth/register: 3次/小时/IP (防刷注册)
→ 公共端点: 20次/分钟/IP
```
### 密码安全
```
JWT password_version (pwv):
→ JWT Claims 含 pwv 字段
→ 每次验证 JWT 时比对 Claims.pwv vs DB.pwv
→ 修改密码 → DB.pwv 递增 → 所有旧 JWT 自动失效
密码存储: Argon2id + OsRng 随机盐
TOTP 加密: AES-256-GCM + 随机 Nonce
```
### Token 刷新
```
POST /api/v1/auth/refresh
→ 验证 refresh_token (单次使用)
→ 旧 refresh_token 撤销到 DB (rotation 校验)
→ 签发新 access + refresh token
```
### SaaS API 分布
12 个路由模块140 端点:
| 模块 | 端点数 | 说明 |
|------|--------|------|
| auth | ~10 | 登录/注册/刷新/2FA |
| relay | ~5 | 聊天中转/模型列表/任务 |
| billing | 10 | 配额/订阅/支付 |
| knowledge | 23 | 知识库 CRUD + pgvector |
| model_config | ~8 | Provider + 模型管理 |
| account | ~8 | 用户管理 |
| agent_template | ~8 | Agent 模板 |
| role | 11 | 角色 + 权限 |
| telemetry | ~5 | 用量统计 |
| prompt | ~5 | Prompt 模板 |
| scheduled_task | 5 | 定时任务 CRUD |
| migration | ~2 | Schema 迁移 |
### 数据表 (34 个)
核心: users, agents, conversations, messages, billing_*, knowledge_*, model_configs, roles, permissions, scheduled_tasks, telemetry, agent_templates, saas_schema_version
### Workers (7 个)
| Worker | 职责 |
|--------|------|
| log_operation | 操作日志 |
| cleanup_rate_limit | 限流记录清理 |
| cleanup_refresh_tokens | 刷新 token 清理 |
| record_usage | 用量记录 |
| update_last_used | 模型最后使用更新 |
| aggregate_usage | 用量聚合 |
| generate_embedding | 内容分块 (Phase 2 embedding deferred) |
## 关联模块
- [[routing]] — SaaS Relay 是 Tauri 的主路径
- [[chat]] — 聊天请求经过 SaaS relay 中转
- [[memory]] — knowledge_chunks 表有 pgvector 索引
## 关键文件
| 文件 | 职责 |
|------|------|
| `crates/zclaw-saas/src/auth/handlers.rs` | 认证端点 |
| `crates/zclaw-saas/src/relay/` | 聊天中转 |
| `crates/zclaw-saas/src/billing/` | 计费 |
| `crates/zclaw-saas/src/knowledge/` | 知识库 (23 API) |
| `crates/zclaw-saas/src/workers/` | 7 个后台 Worker |
| `crates/zclaw-saas/migrations/` | SQL 迁移 (34 表) |
| `admin-v2/src/pages/` | 15 页管理后台 |
| `desktop/src/lib/saas-client.ts` | 前端 SaaS API 客户端 |
| `desktop/src/store/saasStore.ts` | SaaS 认证状态 |
## 安全
完整审计: `docs/features/SECURITY_PENETRATION_TEST_V1.md`
- CORS 白名单 (生产缺失拒绝启动)
- Cookie Secure (dev=false, prod=true)
- JWT 签名密钥 >= 32 字符 (release fallback 拒绝启动)
- 独立 TOTP 加密密钥