docs: reorganize docs — archive outdated, create brainstorming folder
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
- Create docs/brainstorming/ with 5 discussion records (Mar 16 - Apr 7) - Archive ~30 outdated audit reports (V5-V11) to docs/archive/old-audits/ - Archive superseded analysis docs to docs/archive/old-analysis/ - Archive completed session plans to docs/archive/old-plans/ - Archive old test reports/validations to respective archive folders - Remove empty directories left after moves - Keep current docs: TRUTH.md, feature docs, deployment, knowledge-base, superpowers
387
docs/archive/old-analysis/BRAINSTORMING-SESSION-v2.md
Normal file
@@ -0,0 +1,387 @@
|
||||
# ZCLAW 项目头脑风暴会议纪要 v2
|
||||
|
||||
> **会议日期:** 2026-03-21
|
||||
> **基于:** 系统性深度分析报告
|
||||
> **目标:** 针对分析结果进行深入探讨,提出建设性意见和可行性方案
|
||||
|
||||
---
|
||||
|
||||
## 参会专家角色
|
||||
|
||||
| 角色 | 职责 | 输入领域 |
|
||||
|------|------|----------|
|
||||
| 系统架构师 | 整体架构评估 | 代码结构、模块划分 |
|
||||
| 前端技术专家 | 前端架构优化 | React、性能优化 |
|
||||
| 后端技术专家 | 后端架构优化 | Rust、智能层 |
|
||||
| 安全专家 | 安全合规评估 | 数据保护、认证授权 |
|
||||
| 产品专家 | 功能规划 | 用户价值、优先级 |
|
||||
|
||||
---
|
||||
|
||||
## 议题一:架构优化方向
|
||||
|
||||
### 1.1 前后端职责再划分
|
||||
|
||||
**现状分析:**
|
||||
- 智能层已成功迁移到 Rust 后端(heartbeat、compactor、reflection、identity)
|
||||
- 但 intelligence-client.ts 仍包含 localStorage 降级逻辑
|
||||
- 部分业务逻辑仍在前端(agent-swarm、active-learning)
|
||||
|
||||
**方案讨论:**
|
||||
|
||||
| 方案 | 优点 | 缺点 | 推荐度 |
|
||||
|------|------|------|--------|
|
||||
| A. 全部迁移到 Rust | 统一、持久化、多端共享 | 工作量大 | ⭐⭐⭐ |
|
||||
| B. 保持现状,前端做桥接 | 渐进迁移 | 双实现维护成本 | ⭐⭐⭐⭐ |
|
||||
| C. 只迁移核心模块 | 平衡工作量和收益 | 边界不清 | ⭐⭐⭐ |
|
||||
|
||||
**结论:** 采用 **方案 B**,渐进式迁移
|
||||
- 核心模块(记忆、反思、心跳)已迁移 ✅
|
||||
- 非核心模块(agent-swarm、active-learning)可评估后决定
|
||||
|
||||
### 1.2 gateway-client.ts 拆分
|
||||
|
||||
**现状:** 65KB 单文件,包含 WebSocket、REST、认证、心跳、流式处理
|
||||
|
||||
**拆分方案:**
|
||||
```
|
||||
gateway/
|
||||
├── index.ts # 统一导出
|
||||
├── client.ts # 核心类(状态、事件)
|
||||
├── websocket.ts # WebSocket 连接管理
|
||||
├── rest.ts # REST API 封装
|
||||
├── auth.ts # 认证逻辑
|
||||
├── stream.ts # 流式响应处理
|
||||
└── types.ts # 类型定义
|
||||
```
|
||||
|
||||
**实施计划:**
|
||||
- **优先级:** P1
|
||||
- **工作量:** 2-3 人天
|
||||
- **风险:** 低(已有模块边界)
|
||||
|
||||
**结论:** ✅ 同意拆分
|
||||
|
||||
---
|
||||
|
||||
## 议题二:技术升级方向
|
||||
|
||||
### 2.1 React 19 新特性采用
|
||||
|
||||
**现状:** 使用 React 19,但未充分利用新特性
|
||||
|
||||
**可采用的新特性:**
|
||||
|
||||
| 特性 | 适用场景 | 收益 | 优先级 |
|
||||
|------|----------|------|--------|
|
||||
| use() Hook | Store 读取 | 简化代码 | 中 |
|
||||
| React Compiler | 全局 | 性能优化 | 高 |
|
||||
| Document Metadata | SEO/Head | 简化元数据管理 | 低 |
|
||||
| Third-party Hooks | 库集成 | 更好的兼容性 | 中 |
|
||||
|
||||
**结论:** 评估 React Compiler,优先在性能敏感组件试用
|
||||
|
||||
### 2.2 状态管理评估
|
||||
|
||||
**现状:** Zustand 5
|
||||
|
||||
**评估:**
|
||||
- Zustand 5 已支持更多中间件
|
||||
- 考虑迁移到 @preact/signals 或 Jotai?
|
||||
|
||||
**结论:** 保持 Zustand 5,聚焦功能开发
|
||||
|
||||
### 2.3 测试框架增强
|
||||
|
||||
**现状:** Vitest + Playwright,但 E2E 不稳定 (~80% 通过率)
|
||||
|
||||
**改进方案:**
|
||||
|
||||
| 改进项 | 方案 | 优先级 |
|
||||
|--------|------|--------|
|
||||
| E2E 稳定性 | 增加等待逻辑、使用 `waitForFunction` | P0 |
|
||||
| 单元测试覆盖率 | 增加边界测试、错误场景测试 | P1 |
|
||||
| Mock 策略 | 使用 MSW (Mock Service Worker) | P2 |
|
||||
| 视觉回归测试 | 集成 Playwright 截图对比 | P3 |
|
||||
|
||||
**结论:** 优先解决 E2E 稳定性问题 (P0)
|
||||
|
||||
---
|
||||
|
||||
## 议题三:性能提升方向
|
||||
|
||||
### 3.1 渲染性能优化
|
||||
|
||||
**问题:** 大量消息时可能 re-render
|
||||
|
||||
**方案:**
|
||||
|
||||
| 方案 | 实施难度 | 收益 | 推荐度 |
|
||||
|------|----------|------|--------|
|
||||
| A. Zustand shallow 比较 | 低 | 中 | ⭐⭐⭐⭐ |
|
||||
| B. React.memo 优化组件 | 中 | 高 | ⭐⭐⭐⭐⭐ |
|
||||
| C. 虚拟列表优化 | 中 | 高 | ⭐⭐⭐⭐ |
|
||||
| D. 减少 Context 使用 | 低 | 中 | ⭐⭐⭐ |
|
||||
|
||||
**结论:** 组合实施 A + B + D,重点优化 ChatArea 和 MessageList
|
||||
|
||||
### 3.2 网络性能优化
|
||||
|
||||
**问题:** 单 WebSocket 连接
|
||||
|
||||
**方案:**
|
||||
|
||||
| 方案 | 优点 | 缺点 | 推荐度 |
|
||||
|------|------|------|--------|
|
||||
| A. WebSocket 连接池 | 并发请求 | 实现复杂度高 | ⭐⭐ |
|
||||
| B. HTTP/2 多路复用 | 标准方案 | 需要后端支持 | ⭐⭐⭐ |
|
||||
| C. 请求合并 | 减少请求数 | 增加延迟 | ⭐⭐⭐ |
|
||||
| D. 保持现状 | 简单 | - | ⭐⭐⭐⭐⭐ |
|
||||
|
||||
**结论:** 保持现状,当前连接数不是瓶颈
|
||||
|
||||
### 3.3 大文件/长文本处理
|
||||
|
||||
**现状:** Token 估算和压缩已迁移到 Rust 后端
|
||||
|
||||
**可优化点:**
|
||||
- 流式 token 计数
|
||||
- 增量压缩
|
||||
- 智能摘要生成
|
||||
|
||||
**结论:** 当前实现已满足需求,持续观察
|
||||
|
||||
---
|
||||
|
||||
## 议题四:功能扩展方向
|
||||
|
||||
### 4.1 移动端支持
|
||||
|
||||
**评估:**
|
||||
|
||||
| 方案 | 技术选型 | 工作量 | 推荐度 |
|
||||
|------|----------|--------|--------|
|
||||
| A. React Native | 跨平台 | 大 | ⭐⭐ |
|
||||
| B. Tauri Mobile | Tauri 生态 | 中 | ⭐⭐⭐⭐ |
|
||||
| C. Flutter | 独立生态 | 大 | ⭐⭐ |
|
||||
| D. 暂不开发 | - | - | ⭐⭐⭐⭐⭐ |
|
||||
|
||||
**结论:** 评估 Tauri Mobile,但优先级低于核心功能
|
||||
|
||||
### 4.2 国际化 (i18n)
|
||||
|
||||
**现状:** 中文优先,但硬编码字符串存在
|
||||
|
||||
**方案:**
|
||||
```typescript
|
||||
// 使用 react-i18next
|
||||
i18n.t('chat.placeholder')
|
||||
i18n.t('hand.trigger', { name })
|
||||
```
|
||||
|
||||
**工作量:** 约 1-2 周
|
||||
|
||||
**结论:** 建议在下一版本规划中纳入
|
||||
|
||||
### 4.3 更多 Channel 集成
|
||||
|
||||
**当前:** 飞书 (Feishu)
|
||||
|
||||
**可扩展:**
|
||||
|
||||
| Channel | 需求度 | 技术难度 | 优先级 |
|
||||
|---------|--------|----------|--------|
|
||||
| 企业微信 | 高 | 高 | 中 |
|
||||
| 钉钉 | 中 | 高 | 低 |
|
||||
| Discord | 中 | 中 | 中 |
|
||||
| Telegram | 低 | 低 | 中 |
|
||||
|
||||
**结论:** 优先完善飞书集成,评估 Discord
|
||||
|
||||
### 4.4 插件市场
|
||||
|
||||
**现状:** 3 个插件 (chinese-models, feishu, ui)
|
||||
|
||||
**方案:**
|
||||
|
||||
| 阶段 | 内容 | 工作量 |
|
||||
|------|------|--------|
|
||||
| Phase 1 | 插件市场 UI + 基础 API | 1 周 |
|
||||
| Phase 2 | 插件审核机制 | 1 周 |
|
||||
| Phase 3 | 付费插件支持 | 2 周 |
|
||||
|
||||
**结论:** 作为差异化竞争力,纳入中期规划
|
||||
|
||||
---
|
||||
|
||||
## 议题五:风险规避方向
|
||||
|
||||
### 5.1 ZCLAW 兼容性维护
|
||||
|
||||
**风险:** ZCLAW 版本升级可能导致兼容性问题
|
||||
|
||||
**方案:**
|
||||
|
||||
| 方案 | 实施难度 | 保护程度 |
|
||||
|------|----------|----------|
|
||||
| A. 版本锁定 | 低 | 弱 |
|
||||
| B. 兼容层抽象 | 中 | 中 |
|
||||
| C. 自动化兼容性测试 | 高 | 强 |
|
||||
| D. 参与 ZCLAW 开发 | 高 | 最强 |
|
||||
|
||||
**结论:** 实施 B + C,建立兼容性测试套件
|
||||
|
||||
### 5.2 敏感数据保护
|
||||
|
||||
**现状:** API Key 使用 OS Keyring,但聊天记录未加密
|
||||
|
||||
**改进方案:**
|
||||
|
||||
| 敏感数据 | 当前存储 | 建议存储 | 优先级 |
|
||||
|----------|----------|----------|--------|
|
||||
| API Key | OS Keyring ✅ | 保持 | - |
|
||||
| Gateway Token | OS Keyring ✅ | 保持 | - |
|
||||
| 聊天记录 | SQLite | 加密存储 | P1 |
|
||||
| Theme | localStorage | 保持 | 低 |
|
||||
|
||||
**结论:** 聊天记录加密纳入安全增强计划
|
||||
|
||||
### 5.3 灰度发布机制
|
||||
|
||||
**现状:** 无灰度发布
|
||||
|
||||
**方案:**
|
||||
|
||||
| 方案 | 工具 | 工作量 |
|
||||
|------|------|--------|
|
||||
| A. Tauri 内置更新 | tauri-plugin-updater | 1 天 |
|
||||
| B. 手动版本管理 | - | 0 |
|
||||
| C. 自动化灰度 | 定制开发 | 1 周 |
|
||||
|
||||
**结论:** 集成 Tauri 内置更新机制
|
||||
|
||||
---
|
||||
|
||||
## 议题六:创新解决方案
|
||||
|
||||
### 6.1 AI Native 特性增强
|
||||
|
||||
**想法:**
|
||||
|
||||
| 特性 | 描述 | 创新度 |
|
||||
|------|------|--------|
|
||||
| 自适应上下文 | 根据任务类型自动调整上下文长度 | ⭐⭐⭐ |
|
||||
| 智能缓存 | 预测用户意图,预加载资源 | ⭐⭐⭐ |
|
||||
| 多模态交互 | 支持图片、语音输入 | ⭐⭐ |
|
||||
| 主动建议 | 基于上下文主动提供建议 | ⭐⭐⭐⭐ |
|
||||
|
||||
**结论:** 优先实现"主动建议"作为差异化功能
|
||||
|
||||
### 6.2 本地知识图谱构建
|
||||
|
||||
**想法:**
|
||||
- 将记忆系统升级为知识图谱
|
||||
- 实体关系挖掘
|
||||
- 语义推理能力
|
||||
|
||||
**技术路径:**
|
||||
```rust
|
||||
// 实体提取
|
||||
struct Entity {
|
||||
name: String,
|
||||
type: EntityType,
|
||||
properties: HashMap<String, Value>,
|
||||
}
|
||||
|
||||
// 关系链接
|
||||
struct Relation {
|
||||
from: EntityId,
|
||||
to: EntityId,
|
||||
relation_type: String,
|
||||
confidence: f32,
|
||||
}
|
||||
```
|
||||
|
||||
**结论:** 长期规划,与 OpenViking 深度集成
|
||||
|
||||
### 6.3 跨设备状态同步
|
||||
|
||||
**问题:** 当前数据仅本地存储
|
||||
|
||||
**方案:**
|
||||
|
||||
| 方案 | 复杂度 | 隐私性 | 推荐度 |
|
||||
|------|--------|--------|--------|
|
||||
| A. 云端同步 | 高 | 低 | ⭐⭐ |
|
||||
| B. 端到端加密同步 | 高 | 高 | ⭐⭐⭐⭐ |
|
||||
| C. 文件导入/导出 | 低 | 最高 | ⭐⭐⭐⭐ |
|
||||
| D. 保持本地优先 | - | - | ⭐⭐⭐⭐⭐ |
|
||||
|
||||
**结论:** 提供端到端加密同步作为 Pro 功能
|
||||
|
||||
### 6.4 隐私计算集成
|
||||
|
||||
**想法:**
|
||||
- 本地模型推理(Llama.cpp 集成)
|
||||
- 联邦学习支持
|
||||
- 数据不出本机
|
||||
|
||||
**结论:** 长期愿景,需要大量研发投入
|
||||
|
||||
---
|
||||
|
||||
## 行动建议总结
|
||||
|
||||
### 短期行动(1-2 周)
|
||||
|
||||
| # | 行动 | 优先级 | 负责人 | 工作量 |
|
||||
|---|------|--------|--------|--------|
|
||||
| 1 | E2E 测试稳定性修复 | P0 | 测试团队 | 2-3 人天 |
|
||||
| 2 | gateway-client.ts 拆分 | P1 | 前端团队 | 2-3 人天 |
|
||||
| 3 | Rust unwrap() 替换 | P1 | 后端团队 | 0.5 人天 |
|
||||
|
||||
### 中期行动(1-2 月)
|
||||
|
||||
| # | 行动 | 优先级 | 工作量 |
|
||||
|---|------|--------|--------|
|
||||
| 4 | 聊天记录加密 | P1 | 1 周 |
|
||||
| 5 | 插件市场 MVP | P2 | 1 周 |
|
||||
| 6 | i18n 支持 | P2 | 1-2 周 |
|
||||
| 7 | 兼容性测试套件 | P1 | 1 周 |
|
||||
| 8 | 性能优化 (re-render) | P2 | 2-3 人天 |
|
||||
|
||||
### 长期愿景(6 月+)
|
||||
|
||||
| # | 行动 | 优先级 |
|
||||
|---|------|--------|
|
||||
| 9 | 本地知识图谱 | P3 |
|
||||
| 10 | 端到端加密同步 | P3 |
|
||||
| 11 | Tauri Mobile 支持 | P3 |
|
||||
| 12 | 主动建议能力 | P2 |
|
||||
|
||||
---
|
||||
|
||||
## 会议结论
|
||||
|
||||
1. **架构优化优先** - gateway-client.ts 拆分是短期最高优先级
|
||||
2. **稳定性优先** - E2E 测试修复和兼容性测试是 P0
|
||||
3. **保持专注** - 不追求功能数量,聚焦核心体验
|
||||
4. **隐私优先** - 本地优先策略,用户数据不强制上云
|
||||
5. **渐进改进** - 避免大规模重构,采用渐进式优化
|
||||
|
||||
---
|
||||
|
||||
## 关键决策记录
|
||||
|
||||
| 决策项 | 决策结果 | 理由 |
|
||||
|--------|----------|------|
|
||||
| 前后端职责划分 | 渐进迁移 | 平衡工作量和收益 |
|
||||
| 状态管理 | 保持 Zustand 5 | 聚焦功能开发 |
|
||||
| 移动端 | 暂不开发 | 优先级低于核心功能 |
|
||||
| 国际化 | 下一版本纳入 | 1-2 周工作量 |
|
||||
| 聊天记录 | 加密存储 | 保护用户隐私 |
|
||||
| 跨设备同步 | Pro 功能 | 端到端加密 |
|
||||
|
||||
---
|
||||
|
||||
*会议纪要完成*
|
||||
370
docs/archive/old-analysis/BRAINSTORMING-SESSION.md
Normal file
@@ -0,0 +1,370 @@
|
||||
# ZCLAW 项目头脑风暴会议纪要
|
||||
|
||||
> **会议日期:** 2026-03-21
|
||||
> **参与形式:** AI 辅助分析 + 专家评审
|
||||
> **目标:** 基于深度分析结果,探讨架构优化、技术升级、性能提升、功能扩展、风险规避及创新解决方案
|
||||
|
||||
---
|
||||
|
||||
## 一、架构优化方向
|
||||
|
||||
### 议题 1.1:前后端职责再划分
|
||||
|
||||
**现状分析:**
|
||||
- 智能层已成功迁移到 Rust 后端(heartbeat、compactor、reflection、identity)
|
||||
- 但 intelligence-client.ts 仍包含 localStorage 降级逻辑
|
||||
- 部分业务逻辑仍在前端(如记忆提取、蜂群协作)
|
||||
|
||||
**方案讨论:**
|
||||
|
||||
| 方案 | 优点 | 缺点 | 推荐度 |
|
||||
|------|------|------|--------|
|
||||
| A. 全部迁移到 Rust | 统一、持久化、多端共享 | 工作量大 | ⭐⭐⭐ |
|
||||
| B. 保持现状,前端做桥接 | 渐进迁移 | 双实现维护成本 | ⭐⭐⭐⭐ |
|
||||
| C. 只迁移核心模块,非核心留在前端 | 平衡工作量和收益 | 边界不清 | ⭐⭐⭐ |
|
||||
|
||||
**结论:** 采用 **方案 B**,渐进式迁移,核心模块(记忆、反思、心跳)已迁移,非核心模块(如 agent-swarm)可评估后决定
|
||||
|
||||
### 议题 1.2:gateway-client.ts 拆分
|
||||
|
||||
**现状:** 65KB 单文件,包含 WebSocket、REST、认证、心跳、流式处理
|
||||
|
||||
**拆分方案:**
|
||||
```
|
||||
gateway/
|
||||
├── index.ts # 统一导出
|
||||
├── client.ts # 核心类(状态、事件)
|
||||
├── websocket.ts # WebSocket 连接管理
|
||||
├── rest.ts # REST API 封装
|
||||
├── auth.ts # 认证逻辑
|
||||
├── stream.ts # 流式响应处理
|
||||
└── types.ts # 类型定义
|
||||
```
|
||||
|
||||
**结论:** ✅ 同意拆分,预计工作量 2-3 天
|
||||
|
||||
---
|
||||
|
||||
## 二、技术升级方向
|
||||
|
||||
### 议题 2.1:React 19 新特性采用
|
||||
|
||||
**现状:** 使用 React 19,但未利用新特性
|
||||
|
||||
**可采用的新特性:**
|
||||
|
||||
| 特性 | 适用场景 | 收益 | 优先级 |
|
||||
|------|----------|------|--------|
|
||||
| use() Hook | Store 读取 | 简化代码 | 中 |
|
||||
| React Compiler | 全局 | 性能优化 | 高 |
|
||||
| Document Metadata | SEO/Head | 简化元数据管理 | 低 |
|
||||
| Third-party Hooks | 库集成 | 更好的兼容性 | 中 |
|
||||
|
||||
**结论:** 评估 React Compiler,优先在性能敏感组件试用
|
||||
|
||||
### 议题 2.2:状态管理是否升级
|
||||
|
||||
**现状:** Zustand 5
|
||||
|
||||
**评估:**
|
||||
- Zustand 5 已支持更多中间件
|
||||
- 考虑迁移到 @preact/signals 或 Jotai?
|
||||
- **结论:** 保持 Zustand 5,聚焦功能开发
|
||||
|
||||
### 议题 2.3:测试框架增强
|
||||
|
||||
**现状:** Vitest + Playwright,但 E2E 不稳定
|
||||
|
||||
**改进方案:**
|
||||
|
||||
| 改进项 | 方案 | 优先级 |
|
||||
|--------|------|--------|
|
||||
| E2E 稳定性 | 增加等待逻辑、使用 `waitForFunction` | 高 |
|
||||
| 单元测试覆盖率 | 增加边界测试、错误场景测试 | 高 |
|
||||
| Mock 策略 | 使用 MSW (Mock Service Worker) | 中 |
|
||||
| 视觉回归测试 | 集成 Playwright 截图对比 | 低 |
|
||||
|
||||
**结论:** 优先解决 E2E 稳定性问题
|
||||
|
||||
---
|
||||
|
||||
## 三、性能提升方向
|
||||
|
||||
### 议题 3.1:渲染性能优化
|
||||
|
||||
**问题:** 大量消息时可能 re-render
|
||||
|
||||
**方案:**
|
||||
|
||||
| 方案 | 实施难度 | 收益 | 推荐度 |
|
||||
|------|----------|------|--------|
|
||||
| A. Zustand shallow 比较 | 低 | 中 | ⭐⭐⭐⭐ |
|
||||
| B. React.memo 优化组件 | 中 | 高 | ⭐⭐⭐⭐⭐ |
|
||||
| C. 虚拟列表优化 | 中 | 高 | ⭐⭐⭐⭐ |
|
||||
| D. 减少 Context 使用 | 低 | 中 | ⭐⭐⭐ |
|
||||
|
||||
**结论:** 组合实施 A + B + D,重点优化 ChatArea 和 MessageList
|
||||
|
||||
### 议题 3.2:网络性能优化
|
||||
|
||||
**问题:** 单 WebSocket 连接
|
||||
|
||||
**方案:**
|
||||
|
||||
| 方案 | 优点 | 缺点 | 推荐度 |
|
||||
|------|------|------|--------|
|
||||
| A. WebSocket 连接池 | 并发请求 | 实现复杂度高 | ⭐⭐ |
|
||||
| B. HTTP/2 多路复用 | 标准方案 | 需要后端支持 | ⭐⭐⭐ |
|
||||
| C. 请求合并 | 减少请求数 | 增加延迟 | ⭐⭐⭐ |
|
||||
| D. 保持现状 | 简单 | - | ⭐⭐⭐⭐⭐ |
|
||||
|
||||
**结论:** 保持现状,当前连接数不是瓶颈
|
||||
|
||||
### 议题 3.3:大文件/长文本处理
|
||||
|
||||
**问题:** Token 估算和压缩
|
||||
|
||||
**当前实现:** ✅ 已迁移到 Rust 后端(compactor)
|
||||
|
||||
**可优化点:**
|
||||
- 流式 token 计数
|
||||
- 增量压缩
|
||||
- 智能摘要生成
|
||||
|
||||
**结论:** 当前实现已满足需求,持续观察
|
||||
|
||||
---
|
||||
|
||||
## 四、功能扩展方向
|
||||
|
||||
### 议题 4.1:移动端支持
|
||||
|
||||
**评估:**
|
||||
|
||||
| 方案 | 技术选型 | 工作量 | 推荐度 |
|
||||
|------|----------|--------|--------|
|
||||
| A. React Native | 跨平台 | 大 | ⭐⭐ |
|
||||
| B. Tauri Mobile | Tauri 生态 | 中 | ⭐⭐⭐⭐ |
|
||||
| C. Flutter | 独立生态 | 大 | ⭐⭐ |
|
||||
| D. 暂不开发 | - | - | ⭐⭐⭐⭐⭐ |
|
||||
|
||||
**结论:** 评估 Tauri Mobile,但优先级低于核心功能
|
||||
|
||||
### 议题 4.2:国际化 (i18n)
|
||||
|
||||
**现状:** 中文优先,但硬编码字符串存在
|
||||
|
||||
**方案:**
|
||||
```typescript
|
||||
// 使用 react-i18next
|
||||
i18n.t('chat.placeholder')
|
||||
i18n.t('hand.trigger', { name })
|
||||
```
|
||||
|
||||
**工作量:** 约 1-2 周
|
||||
|
||||
**结论:** 建议在下一版本规划中纳入
|
||||
|
||||
### 议题 4.3:更多 Channel 集成
|
||||
|
||||
**当前:** 飞书 (Feishu)
|
||||
|
||||
**可扩展:**
|
||||
|
||||
| Channel | 需求度 | 技术难度 | 优先级 |
|
||||
|---------|--------|----------|--------|
|
||||
| 企业微信 | 高 | 高 | 中 |
|
||||
| 钉钉 | 中 | 高 | 低 |
|
||||
| Discord | 中 | 中 | 中 |
|
||||
| Telegram | 低 | 低 | 中 |
|
||||
|
||||
**结论:** 优先完善飞书集成,评估 Discord
|
||||
|
||||
### 议题 4.4:插件市场
|
||||
|
||||
**现状:** 3 个插件 (chinese-models, feishu, ui)
|
||||
|
||||
**方案:**
|
||||
|
||||
| 阶段 | 内容 | 工作量 |
|
||||
|------|------|--------|
|
||||
| Phase 1 | 插件市场 UI + 基础 API | 1 周 |
|
||||
| Phase 2 | 插件审核机制 | 1 周 |
|
||||
| Phase 3 | 付费插件支持 | 2 周 |
|
||||
|
||||
**结论:** 作为差异化竞争力,纳入中期规划
|
||||
|
||||
---
|
||||
|
||||
## 五、风险规避方向
|
||||
|
||||
### 议题 5.1:ZCLAW 兼容性维护
|
||||
|
||||
**风险:** ZCLAW 版本升级可能导致兼容性问题
|
||||
|
||||
**方案:**
|
||||
|
||||
| 方案 | 实施难度 | 保护程度 |
|
||||
|------|----------|----------|
|
||||
| A. 版本锁定 | 低 | 弱 |
|
||||
| B. 兼容层抽象 | 中 | 中 |
|
||||
| C. 自动化兼容性测试 | 高 | 强 |
|
||||
| D. 参与 ZCLAW 开发 | 高 | 最强 |
|
||||
|
||||
**结论:** 实施 B + C,建立兼容性测试套件
|
||||
|
||||
### 议题 5.2:敏感数据保护
|
||||
|
||||
**现状:** API Key 使用 OS Keyring,但部分配置在 localStorage
|
||||
|
||||
**改进方案:**
|
||||
|
||||
| 敏感数据 | 当前存储 | 建议存储 | 优先级 |
|
||||
|----------|----------|----------|--------|
|
||||
| API Key | OS Keyring ✅ | 保持 | - |
|
||||
| Gateway Token | OS Keyring ✅ | 保持 | - |
|
||||
| Theme | localStorage | 保持 | 低 |
|
||||
| Skill 缓存 | localStorage | 保持 | 低 |
|
||||
| 聊天记录 | SQLite | 考虑加密 | 高 |
|
||||
|
||||
**结论:** 聊天记录加密纳入安全增强计划
|
||||
|
||||
### 议题 5.3:灰度发布机制
|
||||
|
||||
**现状:** 无灰度发布
|
||||
|
||||
**方案:**
|
||||
|
||||
| 方案 | 工具 | 工作量 |
|
||||
|------|------|--------|
|
||||
| A. Tauri 内置更新 | tauri-plugin-updater | 1 天 |
|
||||
| B. 手动版本管理 | - | 0 |
|
||||
| C. 自动化灰度 | 定制开发 | 1 周 |
|
||||
|
||||
**结论:** 集成 Tauri 内置更新机制
|
||||
|
||||
---
|
||||
|
||||
## 六、创新解决方案
|
||||
|
||||
### 议题 6.1:AI Native 特性增强
|
||||
|
||||
**想法:**
|
||||
|
||||
| 特性 | 描述 | 创新度 |
|
||||
|------|------|--------|
|
||||
| 自适应上下文 | 根据任务类型自动调整上下文长度 | ⭐⭐⭐ |
|
||||
| 智能缓存 | 预测用户意图,预加载资源 | ⭐⭐⭐ |
|
||||
| 多模态交互 | 支持图片、语音输入 | ⭐⭐ |
|
||||
| 主动建议 | 基于上下文主动提供建议 | ⭐⭐⭐⭐ |
|
||||
|
||||
**结论:** 优先实现"主动建议"作为差异化功能
|
||||
|
||||
### 议题 6.2:本地知识图谱构建
|
||||
|
||||
**想法:**
|
||||
- 将记忆系统升级为知识图谱
|
||||
- 实体关系挖掘
|
||||
- 语义推理能力
|
||||
|
||||
**技术路径:**
|
||||
```rust
|
||||
// 实体提取
|
||||
struct Entity {
|
||||
name: String,
|
||||
type: EntityType,
|
||||
properties: HashMap<String, Value>,
|
||||
}
|
||||
|
||||
// 关系链接
|
||||
struct Relation {
|
||||
from: EntityId,
|
||||
to: EntityId,
|
||||
relation_type: String,
|
||||
confidence: f32,
|
||||
}
|
||||
```
|
||||
|
||||
**结论:** 长期规划,与 OpenViking 深度集成
|
||||
|
||||
### 议题 6.3:跨设备状态同步
|
||||
|
||||
**问题:** 当前数据仅本地存储
|
||||
|
||||
**方案:**
|
||||
|
||||
| 方案 | 复杂度 | 隐私性 | 推荐度 |
|
||||
|------|--------|--------|--------|
|
||||
| A. 云端同步 | 高 | 低 | ⭐⭐ |
|
||||
| B. 端到端加密同步 | 高 | 高 | ⭐⭐⭐⭐ |
|
||||
| C. 文件导入/导出 | 低 | 最高 | ⭐⭐⭐⭐ |
|
||||
| D. 保持本地优先 | - | - | ⭐⭐⭐⭐⭐ |
|
||||
|
||||
**结论:** 提供端到端加密同步作为 Pro 功能
|
||||
|
||||
### 议题 6.4:隐私计算集成
|
||||
|
||||
**想法:**
|
||||
- 本地模型推理(Llama.cpp 集成)
|
||||
- 联邦学习支持
|
||||
- 数据不出本机
|
||||
|
||||
**结论:** 长期愿景,需要大量研发投入
|
||||
|
||||
---
|
||||
|
||||
## 七、行动建议总结
|
||||
|
||||
### 短期行动(1-2 周)
|
||||
|
||||
| # | 行动 | 优先级 | 负责人 |
|
||||
|---|------|--------|--------|
|
||||
| 1 | gateway-client.ts 拆分 | P1 | 前端团队 |
|
||||
| 2 | E2E 测试稳定性修复 | P0 | 测试团队 |
|
||||
| 3 | React Compiler 评估 | P2 | 前端团队 |
|
||||
|
||||
### 中期行动(1-2 月)
|
||||
|
||||
| # | 行动 | 优先级 |
|
||||
|---|------|--------|
|
||||
| 4 | 聊天记录加密 | P1 |
|
||||
| 5 | 插件市场 MVP | P2 |
|
||||
| 6 | i18n 支持 | P2 |
|
||||
| 7 | 兼容性测试套件 | P1 |
|
||||
|
||||
### 长期愿景(6 月+)
|
||||
|
||||
| # | 行动 | 优先级 |
|
||||
|---|------|--------|
|
||||
| 8 | 本地知识图谱 | P3 |
|
||||
| 9 | 端到端加密同步 | P3 |
|
||||
| 10 | Tauri Mobile 支持 | P3 |
|
||||
|
||||
---
|
||||
|
||||
## 八、会议结论
|
||||
|
||||
1. **架构优化优先** - gateway-client.ts 拆分是短期最高优先级
|
||||
2. **稳定性优先** - E2E 测试修复和兼容性测试是 P0
|
||||
3. **保持专注** - 不追求功能数量,聚焦核心体验
|
||||
4. **隐私优先** - 本地优先策略,用户数据不强制上云
|
||||
|
||||
---
|
||||
|
||||
## 九、附录
|
||||
|
||||
### A. 参与讨论的"专家"
|
||||
|
||||
| 角色 | 输入 |
|
||||
|------|------|
|
||||
| 架构师 | 代码结构、模块划分 |
|
||||
| 前端专家 | React、性能优化 |
|
||||
| 后端专家 | Rust、智能层迁移 |
|
||||
| 安全专家 | 数据保护、认证授权 |
|
||||
| 产品专家 | 功能规划、优先级 |
|
||||
|
||||
### B. 参考资料
|
||||
|
||||
- ZCLAW-DEEP-ANALYSIS-v2.md
|
||||
- docs/features/00-architecture/
|
||||
- docs/plans/INTELLIGENCE-LAYER-MIGRATION.md
|
||||
277
docs/archive/old-analysis/CODE-LEVEL-TODO.md
Normal file
@@ -0,0 +1,277 @@
|
||||
# ZCLAW 代码层面未完成工作分析
|
||||
|
||||
> 分析日期:2026-03-20
|
||||
> 基于 git diff 和代码审查
|
||||
|
||||
## 一、当前重构状态
|
||||
|
||||
### 1.1 已完成的重构
|
||||
|
||||
| 模块 | 原始状态 | 当前状态 | 说明 |
|
||||
|------|----------|----------|------|
|
||||
| gatewayStore.ts | 1800+ 行巨型文件 | ~100 行 facade | 已拆分为 7 个 domain stores |
|
||||
| gateway-client.ts | 65KB 单文件 | 模块化 | 拆分为 5 个文件 |
|
||||
| viking-*.ts | 5 个文件 | 已删除 | 移至 docs/archive/ |
|
||||
| vector-memory.ts | 385 行 | 已删除 | 功能移至 Rust 后端 |
|
||||
| context-builder.ts | 409 行 | 已删除 | 功能移至 Rust 后端 |
|
||||
| session-persistence.ts | 655 行 | 已删除 | 功能移至 Rust 后端 |
|
||||
|
||||
### 1.2 新增文件(未提交)
|
||||
|
||||
```
|
||||
desktop/src/lib/gateway-api.ts - REST API 方法实现
|
||||
desktop/src/lib/gateway-auth.ts - Ed25519 设备认证
|
||||
desktop/src/lib/gateway-storage.ts - URL/token 持久化
|
||||
desktop/src/lib/gateway-types.ts - 协议类型定义
|
||||
desktop/src/store/securityStore.ts - 安全状态管理
|
||||
desktop/src/store/sessionStore.ts - 会话状态管理
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 二、代码层面待完成工作
|
||||
|
||||
### 2.1 🔴 高优先级:Store 迁移
|
||||
|
||||
**问题**:App.tsx 和 34+ 个组件仍使用 `useGatewayStore` (兼容层),而非新的 domain-specific stores。
|
||||
|
||||
**待迁移组件清单**:
|
||||
|
||||
```bash
|
||||
# 查找所有使用 useGatewayStore 的文件
|
||||
desktop/src/App.tsx # 核心入口
|
||||
desktop/src/components/ChatArea.tsx
|
||||
desktop/src/components/Sidebar.tsx
|
||||
desktop/src/components/RightPanel.tsx
|
||||
desktop/src/components/HandsPanel.tsx
|
||||
desktop/src/components/HandApprovalModal.tsx
|
||||
# ... 更多组件
|
||||
```
|
||||
|
||||
**迁移策略**:
|
||||
|
||||
```typescript
|
||||
// 旧方式(兼容层,不推荐)
|
||||
const { hands, triggers, approvals } = useGatewayStore();
|
||||
|
||||
// 新方式(推荐,按需导入)
|
||||
import { useHandStore } from './store/handStore';
|
||||
const { hands, triggers, approvals } = useHandStore();
|
||||
```
|
||||
|
||||
**收益**:
|
||||
- 减少 re-render(当前 useCompositeStore 订阅 40+ 状态)
|
||||
- 更清晰的依赖关系
|
||||
- 更好的代码分割
|
||||
|
||||
---
|
||||
|
||||
### 2.2 🔴 高优先级:useCompositeStore 性能优化
|
||||
|
||||
**问题**:`store/index.ts` 中的 `useCompositeStore` 订阅了所有 store 的几乎所有状态。
|
||||
|
||||
```typescript
|
||||
// 当前实现(有问题)
|
||||
export function useCompositeStore() {
|
||||
// 订阅了 40+ 个状态
|
||||
const connectionState = useConnectionStore((s) => s.connectionState);
|
||||
const gatewayVersion = useConnectionStore((s) => s.gatewayVersion);
|
||||
// ... 40+ 个订阅
|
||||
}
|
||||
```
|
||||
|
||||
**建议**:
|
||||
1. 废弃 `useCompositeStore`
|
||||
2. 组件直接使用 domain-specific stores
|
||||
3. 仅在确实需要跨域状态的场景使用 selector 模式
|
||||
|
||||
---
|
||||
|
||||
### 2.3 🟡 中优先级:测试文件更新
|
||||
|
||||
**已删除测试文件**:
|
||||
```
|
||||
tests/desktop/session-persistence.test.ts (424 行)
|
||||
tests/desktop/vector-memory.test.ts (299 行)
|
||||
tests/desktop/viking-adapter.test.ts (446 行)
|
||||
```
|
||||
|
||||
**需更新测试文件**:
|
||||
```
|
||||
tests/desktop/gatewayStore.test.ts (190 行需更新)
|
||||
tests/desktop/swarm-skills.test.ts (6 行需更新)
|
||||
```
|
||||
|
||||
**缺失测试**:
|
||||
- `securityStore.test.ts` - 新 store 无测试
|
||||
- `sessionStore.test.ts` - 新 store 无测试
|
||||
- `gateway-api.test.ts` - 新模块无测试
|
||||
- `gateway-auth.test.ts` - 新模块无测试
|
||||
|
||||
---
|
||||
|
||||
### 2.4 🟡 中优先级:类型定义清理
|
||||
|
||||
**问题**:`gatewayStore.ts` 仍定义了一些类型,这些应该移到各自的 store 或 types 文件。
|
||||
|
||||
```typescript
|
||||
// gatewayStore.ts 中定义的类型(应迁移)
|
||||
export interface HandRunStore { ... }
|
||||
export interface ScheduledJob { ... }
|
||||
export interface EventTrigger { ... }
|
||||
export interface RunHistoryEntry { ... }
|
||||
```
|
||||
|
||||
**建议**:
|
||||
1. `HandRunStore` → `handStore.ts`
|
||||
2. `ScheduledJob`, `EventTrigger`, `RunHistoryEntry` → 新建 `types/automation.ts`
|
||||
|
||||
---
|
||||
|
||||
### 2.5 🟢 低优先级:组件集成度提升
|
||||
|
||||
**存在但集成度低的组件**:
|
||||
|
||||
| 组件 | 文件 | 问题 |
|
||||
|------|------|------|
|
||||
| HeartbeatConfig | `components/Settings/HeartbeatConfig.tsx` | 未在 Settings 页面使用 |
|
||||
| CreateTriggerModal | `components/Automation/CreateTriggerModal.tsx` | 未在 Automation 面板集成 |
|
||||
| PersonalitySelector | `components/Agent/PersonalitySelector.tsx` | 未在 Agent 创建流程使用 |
|
||||
| ScenarioTags | `components/Agent/ScenarioTags.tsx` | 未在 Agent 编辑使用 |
|
||||
| DevQALoop | `components/Dev/DevQALoop.tsx` | 开发调试组件,未集成 |
|
||||
|
||||
---
|
||||
|
||||
### 2.6 🟢 低优先级:文档与代码同步
|
||||
|
||||
**文档声称完成但代码未验证**:
|
||||
|
||||
| 功能 | 文档状态 | 代码状态 |
|
||||
|------|----------|----------|
|
||||
| 身份演化 | ✅ 完成 | ❓ 未验证与后端集成 |
|
||||
| 上下文压缩 | ✅ 完成 | ❓ 未验证触发条件 |
|
||||
| 心跳巡检 | ✅ 完成 | ❓ 未验证实际执行 |
|
||||
| 记忆持久化 | ✅ 完成 | ❓ 依赖 localStorage |
|
||||
|
||||
---
|
||||
|
||||
## 三、Tauri Rust 后端状态
|
||||
|
||||
### 3.1 已实现的 Rust 模块
|
||||
|
||||
| 模块 | 文件 | 功能 | 状态 |
|
||||
|------|------|------|------|
|
||||
| ZCLAW 集成 | `lib.rs` | Gateway 生命周期管理 | ✅ 完整 |
|
||||
| Viking Server | `viking_server.rs` | 本地向量数据库 | ✅ 完整 |
|
||||
| Viking Commands | `viking_commands.rs` | Viking CLI 封装 | ✅ 完整 |
|
||||
| Browser Automation | `browser/*.rs` | Fantoccini 浏览器控制 | ✅ 完整 |
|
||||
| Memory Extraction | `memory/*.rs` | 记忆提取、上下文构建 | ✅ 完整 |
|
||||
| LLM Integration | `llm/mod.rs` | LLM 调用封装 | ✅ 完整 |
|
||||
| Secure Storage | `secure_storage.rs` | OS keyring/keychain | ✅ 完整 |
|
||||
|
||||
### 3.2 Rust 后端与前端对齐问题
|
||||
|
||||
**问题**:前端 `lib/` 下有大量智能逻辑(记忆、反思、心跳),与 Rust 后端功能重叠。
|
||||
|
||||
| 前端文件 | Rust 对应 | 建议 |
|
||||
|----------|-----------|------|
|
||||
| `agent-memory.ts` | `memory/extractor.rs` | 统一到 Rust 端 |
|
||||
| `context-compactor.ts` | `memory/context_builder.rs` | 统一到 Rust 端 |
|
||||
| `heartbeat-engine.ts` | 无 | 迁移到 Rust 端 |
|
||||
| `reflection-engine.ts` | 无 | 迁移到 Rust 端 |
|
||||
| `agent-identity.ts` | 无 | 迁移到 Rust 端 |
|
||||
|
||||
**收益**:
|
||||
- 后端持久运行(关闭浏览器不中断)
|
||||
- 多端共享 Agent 状态
|
||||
- 更可靠的数据持久化
|
||||
|
||||
---
|
||||
|
||||
## 四、技术债务清单
|
||||
|
||||
### 4.1 代码质量
|
||||
|
||||
| 问题 | 位置 | 严重度 |
|
||||
|------|------|--------|
|
||||
| 使用 `any` 类型 | 多处 | 中 |
|
||||
| 空 catch 块 | `sessionStore.ts:119` | 低 |
|
||||
| 硬编码字符串 | 多处 | 低 |
|
||||
| 重复的类型定义 | `gatewayStore.ts` vs 各 store | 中 |
|
||||
|
||||
### 4.2 架构问题
|
||||
|
||||
| 问题 | 说明 | 建议 |
|
||||
|------|------|------|
|
||||
| 前端承担后端职责 | 记忆/反思/心跳在前端 | 迁移到 Rust |
|
||||
| Store 过度订阅 | useCompositeStore 订阅 40+ 状态 | 按需订阅 |
|
||||
| 兼容层膨胀 | gatewayStore.ts 作为 facade | 逐步移除 |
|
||||
|
||||
---
|
||||
|
||||
## 五、行动建议
|
||||
|
||||
### 本周必做
|
||||
|
||||
1. **提交当前重构** - gateway-client 模块化、store 拆分已完成
|
||||
2. **更新测试** - 为新 store 和 gateway 模块添加测试
|
||||
3. **迁移 App.tsx** - 从 useGatewayStore 迁移到 domain stores
|
||||
|
||||
### 两周内
|
||||
|
||||
1. **移除 useCompositeStore** - 组件直接使用 domain stores
|
||||
2. **清理类型定义** - 统一到各自的 store 或 types 文件
|
||||
3. **集成低使用率组件** - HeartbeatConfig, CreateTriggerModal 等
|
||||
|
||||
### 一个月内
|
||||
|
||||
1. **前端智能层迁移** - 将记忆/反思/心跳迁移到 Rust 后端
|
||||
2. **端到端测试** - Playwright + Tauri driver 验证核心流程
|
||||
3. **性能优化** - 减少不必要的 re-render
|
||||
|
||||
---
|
||||
|
||||
## 六、代码变更统计
|
||||
|
||||
```
|
||||
当前未提交变更:
|
||||
21 files changed, 578 insertions(+), 7324 deletions(-)
|
||||
|
||||
删除的文件(已归档):
|
||||
- desktop/src/lib/context-builder.ts (409 行)
|
||||
- desktop/src/lib/session-persistence.ts (655 行)
|
||||
- desktop/src/lib/vector-memory.ts (385 行)
|
||||
- desktop/src/lib/viking-adapter.ts (734 行)
|
||||
- desktop/src/lib/viking-client.ts (353 行)
|
||||
- desktop/src/lib/viking-local.ts (144 行)
|
||||
- desktop/src/lib/viking-memory-adapter.ts (408 行)
|
||||
- desktop/src/lib/viking-server-manager.ts (231 行)
|
||||
|
||||
新增的文件:
|
||||
+ desktop/src/lib/gateway-api.ts (新建)
|
||||
+ desktop/src/lib/gateway-auth.ts (新建)
|
||||
+ desktop/src/lib/gateway-storage.ts (新建)
|
||||
+ desktop/src/lib/gateway-types.ts (新建)
|
||||
+ desktop/src/store/securityStore.ts (新建)
|
||||
+ desktop/src/store/sessionStore.ts (新建)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 七、总结
|
||||
|
||||
**重构进度**:约 70% 完成
|
||||
- ✅ Store 拆分完成
|
||||
- ✅ Gateway Client 模块化完成
|
||||
- ✅ Viking 相关代码清理完成
|
||||
- ⏳ 组件迁移进行中(仍使用兼容层)
|
||||
- ⏳ 测试更新待完成
|
||||
- ❌ 前端智能层迁移未开始
|
||||
|
||||
**最大风险**:
|
||||
1. useCompositeStore 性能问题(40+ 状态订阅)
|
||||
2. 前端智能逻辑(记忆/反思)依赖 localStorage,不可靠
|
||||
3. 缺少端到端测试验证
|
||||
|
||||
**建议策略**:
|
||||
先完成当前重构(提交、测试、组件迁移),再启动前端智能层向 Rust 迁移。
|
||||
157
docs/archive/old-analysis/COMPONENT-INTEGRATION-STATUS.md
Normal file
@@ -0,0 +1,157 @@
|
||||
# ZCLAW 组件集成状态报告
|
||||
|
||||
> 分析日期:2026-03-20
|
||||
> 基于 `ZCLAW-DEEP-ANALYSIS.md` 文档的核实结果
|
||||
|
||||
---
|
||||
|
||||
## 一、分析结论
|
||||
|
||||
| 组件 | 文档标记 | 实际状态 | 集成路径 |
|
||||
|------|----------|----------|----------|
|
||||
| PersonalitySelector | ❓ 未验证 | ✅ 已集成 | App.tsx → AgentOnboardingWizard |
|
||||
| ScenarioTags | ❓ 未验证 | ✅ 已集成 | App.tsx → AgentOnboardingWizard |
|
||||
| DevQALoop | ❓ 未验证 | ❌ 未集成 | 无 |
|
||||
| HeartbeatConfig | ❓ 未验证 | ✅ 已集成 | SettingsLayout(根据迁移文档) |
|
||||
| CreateTriggerModal | ❓ 未验证 | ✅ 已迁移 | useHandStore(根据迁移文档) |
|
||||
|
||||
---
|
||||
|
||||
## 二、详细分析
|
||||
|
||||
### 2.1 PersonalitySelector ✅ 已集成
|
||||
|
||||
**文件位置:** `desktop/src/components/PersonalitySelector.tsx`
|
||||
|
||||
**被引用情况:**
|
||||
```typescript
|
||||
// AgentOnboardingWizard.tsx:25
|
||||
import { PersonalitySelector } from './PersonalitySelector';
|
||||
```
|
||||
|
||||
**集成路径:**
|
||||
```
|
||||
App.tsx (L223)
|
||||
→ AgentOnboardingWizard
|
||||
→ PersonalitySelector
|
||||
```
|
||||
|
||||
**Store 连接:** 通过 AgentOnboardingWizard 传递 props,组件内部使用 useState
|
||||
|
||||
**功能完整性:** ✅ 完整,提供性格选项选择
|
||||
|
||||
---
|
||||
|
||||
### 2.2 ScenarioTags ✅ 已集成
|
||||
|
||||
**文件位置:** `desktop/src/components/ScenarioTags.tsx`
|
||||
|
||||
**被引用情况:**
|
||||
```typescript
|
||||
// AgentOnboardingWizard.tsx:26
|
||||
import { ScenarioTags } from './ScenarioTags';
|
||||
```
|
||||
|
||||
**集成路径:**
|
||||
```
|
||||
App.tsx (L223)
|
||||
→ AgentOnboardingWizard
|
||||
→ ScenarioTags
|
||||
```
|
||||
|
||||
**Store 连接:** 通过 AgentOnboardingWizard 传递 props
|
||||
|
||||
**功能完整性:** ✅ 完整,提供场景标签选择
|
||||
|
||||
---
|
||||
|
||||
### 2.3 DevQALoop ❌ 未集成
|
||||
|
||||
**文件位置:** `desktop/src/components/DevQALoop.tsx`
|
||||
|
||||
**被引用情况:** 无外部引用
|
||||
|
||||
**问题分析:**
|
||||
- 组件已实现完整的 Dev-QA 循环界面
|
||||
- 使用 `useTeamStore` 连接到 teamStore
|
||||
- 但未在任何父组件中被导入使用
|
||||
|
||||
**建议集成位置:**
|
||||
- `TeamOrchestrator.tsx` - 作为团队协作的子面板
|
||||
- `TeamCollaborationView.tsx` - 作为代码审查工作流的一部分
|
||||
|
||||
**Store 连接:** ✅ 已连接
|
||||
```typescript
|
||||
import { useTeamStore } from '../store/teamStore';
|
||||
```
|
||||
|
||||
**功能完整性:** ✅ 完整,但未被使用
|
||||
|
||||
**下一步行动:**
|
||||
1. 确定合适的父组件
|
||||
2. 添加到 TeamOrchestrator 或创建专门的 ReviewPanel
|
||||
3. 在 UI 中添加导航入口
|
||||
|
||||
---
|
||||
|
||||
### 2.4 HeartbeatConfig ✅ 已集成
|
||||
|
||||
**根据 `docs/progress/2024-03-20-store-migration.md`:**
|
||||
- 已集成到 SettingsLayout
|
||||
- 使用 useSecurityStore
|
||||
|
||||
---
|
||||
|
||||
### 2.5 CreateTriggerModal ✅ 已迁移
|
||||
|
||||
**根据 `docs/progress/2024-03-20-store-migration.md`:**
|
||||
- 已迁移到 useHandStore
|
||||
- 使用 useWorkflowStore
|
||||
|
||||
---
|
||||
|
||||
## 三、待办事项
|
||||
|
||||
| 优先级 | 任务 | 工作量 |
|
||||
|--------|------|--------|
|
||||
| P1 | 将 DevQALoop 集成到 TeamOrchestrator | 小 |
|
||||
| P2 | 为 DevQALoop 添加导航入口 | 小 |
|
||||
| P3 | 更新 ZCLAW-DEEP-ANALYSIS.md 反映实际状态 | 小 |
|
||||
|
||||
---
|
||||
|
||||
## 四、代码引用
|
||||
|
||||
### DevQALoop 组件导出
|
||||
|
||||
```typescript
|
||||
// desktop/src/components/DevQALoop.tsx
|
||||
export function DevQALoop({ loop, onUpdate, onApprove }: DevQALoopProps)
|
||||
```
|
||||
|
||||
### 建议的集成代码
|
||||
|
||||
```typescript
|
||||
// 在 TeamOrchestrator.tsx 中添加
|
||||
import { DevQALoop } from './DevQALoop';
|
||||
|
||||
// 在渲染部分添加条件渲染
|
||||
{activeTab === 'review' && currentLoop && (
|
||||
<DevQALoop
|
||||
loop={currentLoop}
|
||||
onUpdate={handleLoopUpdate}
|
||||
onApprove={handleLoopApprove}
|
||||
/>
|
||||
)}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 五、总结
|
||||
|
||||
文档中标记为"集成度低"的组件实际上大部分已完成集成:
|
||||
- **PersonalitySelector** 和 **ScenarioTags** 通过 AgentOnboardingWizard 间接集成
|
||||
- **HeartbeatConfig** 和 **CreateTriggerModal** 在 Store 迁移时已完成集成
|
||||
- **仅 DevQALoop** 确实未被集成,需要后续处理
|
||||
|
||||
整体集成完成度比文档描述的更好,建议更新 `ZCLAW-DEEP-ANALYSIS.md` 文档以反映实际状态。
|
||||
220
docs/archive/old-analysis/FEATURE-INTEGRITY-AUDIT.md
Normal file
@@ -0,0 +1,220 @@
|
||||
# ZCLAW 功能完整性审计报告
|
||||
|
||||
> **审计日期**: 2026-03-26
|
||||
> **审计范围**: docs/features 目录下所有功能文档 vs 实际代码实现
|
||||
> **审计方法**: 五步审计流程(文档对齐 → 追踪数据流 → 识别 dead_code → 检查 trait 实现 → 端到端验证)
|
||||
|
||||
---
|
||||
|
||||
## 一、五步审计流程执行结果
|
||||
|
||||
### 步骤 1: 文档对齐
|
||||
|
||||
根据 `docs/features/README.md`,系统声称具备以下功能:
|
||||
|
||||
| 模块 | 声称成熟度 | 功能项 |
|
||||
|------|-----------|--------|
|
||||
| 架构层 | L4 | 通信层、状态管理、安全认证 |
|
||||
| 核心功能 | L3-L4 | 聊天界面、Agent分身、Hands系统 |
|
||||
| 智能层 | L3-L4 | 记忆、身份演化、上下文压缩、反思、心跳、自主授权 |
|
||||
| Skills生态 | L4 | 动态扫描、execute_skill |
|
||||
| Hands系统 | L3 | 9/11 已实现 |
|
||||
| Pipeline DSL | L4 | 5类Pipeline模板 |
|
||||
|
||||
### 步骤 2: 追踪数据流
|
||||
|
||||
**智能层集成情况** (`intelligence_hooks.rs`):
|
||||
|
||||
```
|
||||
✅ 已接入:
|
||||
- identity (pre-hook): build_system_prompt()
|
||||
- memory context (pre-hook): build_memory_context() via VikingStorage
|
||||
- heartbeat (post-hook): record_interaction()
|
||||
- reflection (post-hook): record_conversation() + should_reflect()
|
||||
|
||||
❌ 未接入:
|
||||
- compactor: 代码存在但未在 hooks 中调用
|
||||
- pattern_detector: #![allow(dead_code)]
|
||||
- recommender: #![allow(dead_code)]
|
||||
- mesh: #![allow(dead_code)]
|
||||
- persona_evolver: #![allow(dead_code)]
|
||||
- trigger_evaluator: #![allow(dead_code)]
|
||||
```
|
||||
|
||||
### 步骤 3: 识别 dead_code
|
||||
|
||||
| 文件 | 状态 | 说明 |
|
||||
|------|------|------|
|
||||
| `intelligence/pattern_detector.rs` | `#![allow(dead_code)]` | 模块存在但未集成 |
|
||||
| `intelligence/recommender.rs` | `#![allow(dead_code)]` | 模块存在但未集成 |
|
||||
| `intelligence/mesh.rs` | `#![allow(dead_code)]` | 模块存在但未集成 |
|
||||
| `intelligence/persona_evolver.rs` | `#![allow(dead_code)]` | 模块存在但未集成 |
|
||||
| `intelligence/trigger_evaluator.rs` | `#![allow(dead_code)]` | 模块存在但未集成 |
|
||||
| `context_compactor.rs` | Tauri命令存在但未在hooks中调用 | 降级为L2 |
|
||||
|
||||
### 步骤 4: 检查 trait 实现
|
||||
|
||||
| 智能模块 | Rust实现 | Tauri命令 | 前端调用链 |
|
||||
|---------|---------|----------|-----------|
|
||||
| heartbeat | ✅ | ✅ | ✅ intelligence_hooks |
|
||||
| reflection | ✅ | ✅ | ✅ intelligence_hooks |
|
||||
| identity | ✅ | ✅ | ✅ intelligence_hooks |
|
||||
| memory | ✅ (VikingStorage) | ✅ | ✅ intelligence_hooks |
|
||||
| compactor | ✅ | ✅ | ⚠️ chatStore直接调用,未经hooks |
|
||||
| pattern_detector | ✅ | ❌ | ❌ |
|
||||
| recommender | ✅ | ❌ | ❌ |
|
||||
| mesh | ✅ | ❌ | ❌ |
|
||||
| persona_evolver | ✅ | ❌ | ❌ |
|
||||
| trigger_evaluator | ✅ | ❌ | ❌ |
|
||||
|
||||
### 步骤 5: 端到端验证
|
||||
|
||||
**发现编译错误**(target/flycheck0/stdout):
|
||||
```
|
||||
error[E0603]: struct import `FindOptions` is private
|
||||
--> desktop\src-tauri\src\intelligence_hooks.rs:100:43
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 二、10项通用审计清单
|
||||
|
||||
| # | 检查项 | 状态 | 说明 |
|
||||
|---|--------|------|------|
|
||||
| 1 | 代码存在性 | ✅ | 所有声称模块均有代码 |
|
||||
| 2 | 调用链连通 | ⚠️ | 5个智能模块未接入hooks |
|
||||
| 3 | 配置传递 | ⚠️ | compactor降级配置未生效 |
|
||||
| 4 | 降级策略 | ✅ | intelligence-client.ts有fallback逻辑 |
|
||||
| 5 | 前后端数据流 | ⚠️ | FindOptions私有导入导致编译失败 |
|
||||
| 6 | UI组件集成 | ✅ | 主要UI已集成到RightPanel |
|
||||
| 7 | 错误处理 | ✅ | 有容错解析 |
|
||||
| 8 | 测试覆盖 | ⚠️ | 仅agent-memory有测试 |
|
||||
| 9 | 文档同步 | ⚠️ | 文档声称L4,实际部分L2 |
|
||||
| 10 | 依赖声明 | ✅ | Cargo.toml完整 |
|
||||
|
||||
---
|
||||
|
||||
## 三、5种常见差距模式
|
||||
|
||||
| 模式 | 描述 | 发现实例 |
|
||||
|------|------|----------|
|
||||
| **写了没接** | 代码已实现但未接入实际流程 | compactor、pattern_detector、recommender、mesh、persona_evolver、trigger_evaluator |
|
||||
| **接了没传** | 接入了但参数/状态未传递 | heartbeat post-hook参数未使用 |
|
||||
| **传了没存** | 传了但未持久化 | identity快照未存储 |
|
||||
| **存了没用** | 存储了但UI未使用 | VikingStorage记忆未在MemoryPanel展示 |
|
||||
| **双系统不同步** | TypeScript和Rust各有一套实现 | intelligence-backend.ts vs intelligence_hooks.rs |
|
||||
|
||||
---
|
||||
|
||||
## 四、功能差距详细清单
|
||||
|
||||
### 4.1 智能层差距
|
||||
|
||||
| 功能 | 文档声称 | 实际状态 | 差距等级 |
|
||||
|------|---------|---------|---------|
|
||||
| Agent记忆 | L4 ✅ | L3 ⚠️ | 中 |
|
||||
| 身份演化 | L3 ✅ | L2 ⚠️ | 中 |
|
||||
| 上下文压缩 | L2 ⚠️ | L2 ⚠️ | 低 |
|
||||
| 自我反思 | L3 ✅ | L3 ✅ | 无 |
|
||||
| 心跳巡检 | L3 ✅ | L3 ✅ | 无 |
|
||||
| 自主授权 | L3 ✅ | L3 ✅ | 无 |
|
||||
| Pattern检测 | L4 ✅ | ❌ 未集成 | 高 |
|
||||
| 推荐引擎 | L4 ✅ | ❌ 未集成 | 高 |
|
||||
| 自适应Mesh | L4 ✅ | ❌ 未集成 | 高 |
|
||||
| Persona演进 | L4 ✅ | ❌ 未集成 | 高 |
|
||||
| 触发评估器 | L4 ✅ | ❌ 未集成 | 高 |
|
||||
|
||||
### 4.2 Hands系统差距
|
||||
|
||||
| Hand | 文档声称 | 实际状态 |
|
||||
|------|---------|---------|
|
||||
| Browser | ✅ | ✅ |
|
||||
| Collector | ✅ | ✅ |
|
||||
| Researcher | ✅ | ✅ |
|
||||
| Predictor | ✅ | ⚠️ 依赖外部API |
|
||||
| Lead | ✅ | ⚠️ 依赖外部API |
|
||||
| Clip | ✅ | ⚠️ 需要FFmpeg |
|
||||
| Speech | ✅ | ✅ |
|
||||
| Slideshow | ✅ | ✅ |
|
||||
| Quiz | ✅ | ✅ |
|
||||
| Whiteboard | ✅ | ✅ |
|
||||
| Twitter | ✅ | ⚠️ 需要API Key |
|
||||
|
||||
### 4.3 未实现的API(feature-checklist.md记录)
|
||||
|
||||
| API端点 | 状态 | 文档日期 |
|
||||
|---------|------|---------|
|
||||
| `/api/tasks` | ❌ 404 | 2026-03-14 |
|
||||
| `/api/audit/logs` | ❌ 404 | 2026-03-14 |
|
||||
| `/api/security/status` | ❌ 404 | 2026-03-14 |
|
||||
| `/api/plugins` | ❌ 404 | 2026-03-14 |
|
||||
| `/api/workspace` | ❌ 404 | 2026-03-14 |
|
||||
| `/api/mcp/*` | ❌ 404 | 2026-03-14 |
|
||||
|
||||
---
|
||||
|
||||
## 五、审计命令速查
|
||||
|
||||
```bash
|
||||
# 搜索 dead_code
|
||||
rg "#\!\[allow\(dead_code\)\]" --type rust
|
||||
|
||||
# 搜索 TODO/FIXME
|
||||
rg "TODO|FIXME|XXX|HACK" --type rust --type ts
|
||||
|
||||
# 搜索未集成的智能模块
|
||||
rg "pattern_detector|recommender|mesh|persona_evolver|trigger_evaluator" --type rust
|
||||
|
||||
# 检查 invoke 调用链
|
||||
rg "invoke\('" desktop/src/lib/ --type ts
|
||||
|
||||
# 搜索 404 API
|
||||
rg "404|net::ERR" desktop/src/ --type ts
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 六、修复建议优先级
|
||||
|
||||
### P0 - 阻断性问题
|
||||
|
||||
| 问题 | 修复 |
|
||||
|------|------|
|
||||
| `FindOptions`私有导入 | 修改 `intelligence_hooks.rs:100` 使用 `zclaw_growth::FindOptions` |
|
||||
| 5个智能模块未集成 | 将 compactor/pattern_detector/recommender/mesh/persona_evolver/trigger_evaluator 接入 hooks |
|
||||
|
||||
### P1 - 重要功能
|
||||
|
||||
| 问题 | 修复 |
|
||||
|------|------|
|
||||
| Context Compactor 未在hooks调用 | 在 `pre_conversation_hook` 或 `post_conversation_hook` 中添加compact调用 |
|
||||
| Vector Memory UI未使用 | 集成 `vector-memory.ts` 到 MemoryPanel |
|
||||
|
||||
### P2 - 增强功能
|
||||
|
||||
| 问题 | 修复 |
|
||||
|------|------|
|
||||
| 文档更新 | 将未集成模块的成熟度从L4降为L2 |
|
||||
| 测试覆盖 | 为每个智能模块添加单元测试 |
|
||||
|
||||
---
|
||||
|
||||
## 七、总结
|
||||
|
||||
| 指标 | 数值 |
|
||||
|------|------|
|
||||
| 文档声称成熟度 | 大部分 L3-L4 |
|
||||
| 实际达到成熟度 | 核心聊天流程 L4,智能层 L2-L3 |
|
||||
| 未集成模块 | 6个 (compactor降级, 5个智能模块) |
|
||||
| 编译错误 | 1个 (FindOptions私有导入) |
|
||||
| 未实现API | 6个 |
|
||||
|
||||
**核心问题**: 系统核心聊天功能完整,但智能层的"自我进化"能力大部分停留在代码存在但未集成的状态,属于"**写了没接**"的典型模式。
|
||||
|
||||
---
|
||||
|
||||
## 八、变更历史
|
||||
|
||||
| 日期 | 变更内容 |
|
||||
|------|---------|
|
||||
| 2026-03-26 | 初始版本,完成五步审计流程分析 |
|
||||
331
docs/archive/old-analysis/OPTIMIZATION-ROADMAP.md
Normal file
@@ -0,0 +1,331 @@
|
||||
# ZCLAW 项目优化路线图
|
||||
|
||||
> **制定日期:** 2026-03-21
|
||||
> **基于:** 深度分析报告 + 头脑风暴会议
|
||||
|
||||
---
|
||||
|
||||
## 一、优化优先级矩阵
|
||||
|
||||
### 1.1 优先级定义
|
||||
|
||||
| 优先级 | 定义 | 时间要求 |
|
||||
|--------|------|----------|
|
||||
| P0 | 紧急影响使用 | 1 周内 |
|
||||
| P1 | 重要影响体验 | 2-4 周 |
|
||||
| P2 | 中期提升 | 1-2 月 |
|
||||
| P3 | 长期愿景 | 6 月+ |
|
||||
|
||||
### 1.2 问题-方案-工作量矩阵
|
||||
|
||||
| ID | 问题 | 方案 | 优先级 | 工作量 | 责任人 |
|
||||
|----|------|------|--------|--------|--------|
|
||||
| Q1 | gateway-client.ts 过大 (65KB) | 拆分为多模块 | P1 | 2-3 人天 | 前端 |
|
||||
| Q2 | localStorage 降级风险 | 统一使用 Rust 后端 | P1 | 1 周 | 前端+后端 |
|
||||
| Q3 | Rust unwrap() 风险 | 改用 expect() 并添加错误信息 | P1 | 0.5 人天 | 后端 |
|
||||
| Q4 | E2E 测试不稳定 | 修复等待逻辑,增加容错 | P0 | 2-3 人天 | 测试 |
|
||||
| Q5 | 聊天记录未加密 | SQLite 加密 | P1 | 1 周 | 后端 |
|
||||
| Q6 | Store re-render 问题 | Zustand shallow + React.memo | P2 | 2-3 人天 | 前端 |
|
||||
| Q7 | 缺少兼容性测试 | 建立自动化测试套件 | P1 | 1 周 | 测试 |
|
||||
| Q8 | 飞书集成不完整 | 完善 OAuth + 消息收发 | P2 | 1 周 | 前端+后端 |
|
||||
| Q9 | 插件市场不完善 | 插件市场 MVP | P2 | 1 周 | 前端 |
|
||||
| Q10 | 缺少 i18n | 引入 react-i18next | P2 | 1-2 周 | 前端 |
|
||||
|
||||
---
|
||||
|
||||
## 二、分阶段实施计划
|
||||
|
||||
### Phase 0: 稳定化 (1-2 周)
|
||||
|
||||
**目标:** 解决影响正常使用的 P0 问题
|
||||
|
||||
#### Sprint 1: E2E 测试修复
|
||||
|
||||
| 任务 | 描述 | 验收标准 |
|
||||
|------|------|----------|
|
||||
| T1.1 | 分析失败测试原因 | 列出所有不稳定测试 |
|
||||
| T1.2 | 修复等待逻辑 | 使用 `waitForFunction` 替代固定等待 |
|
||||
| T1.3 | 增加断言容错 | 处理网络延迟等边界情况 |
|
||||
| T1.4 | 验证修复 | 所有 E2E 测试通过率 > 95% |
|
||||
|
||||
#### Sprint 2: 紧急 Bug 修复
|
||||
|
||||
| 任务 | 描述 | 验收标准 |
|
||||
|------|------|----------|
|
||||
| T2.1 | 收集线上问题 | 基于用户反馈和监控 |
|
||||
| T2.2 | 修复 Top 5 Bug | 每个 Bug 有回归测试 |
|
||||
| T2.3 | 发布补丁版本 | v0.x.1 |
|
||||
|
||||
**交付物:** 稳定的测试套件,补丁版本
|
||||
|
||||
---
|
||||
|
||||
### Phase 1: 架构优化 (2-4 周)
|
||||
|
||||
**目标:** 提升代码质量和可维护性
|
||||
|
||||
#### Sprint 3: gateway-client 拆分
|
||||
|
||||
| 任务 | 描述 | 验收标准 |
|
||||
|------|------|----------|
|
||||
| T3.1 | 设计模块边界 | 输出模块划分文档 |
|
||||
| T3.2 | 拆分 websocket 模块 | 提取 WebSocket 管理逻辑 |
|
||||
| T3.3 | 拆分 rest 模块 | 提取 REST API 逻辑 |
|
||||
| T3.4 | 拆分 stream 模块 | 提取流式处理逻辑 |
|
||||
| T3.5 | 更新导入路径 | 全量回归测试 |
|
||||
| T3.6 | 编写模块文档 | 每个模块有 JSDoc |
|
||||
|
||||
#### Sprint 4: Rust 后端加固
|
||||
|
||||
| 任务 | 描述 | 验收标准 |
|
||||
|------|------|----------|
|
||||
| T4.1 | 替换 unwrap() | 使用 expect() 并添加上下文 |
|
||||
| T4.2 | 错误处理统一 | 所有命令返回 Result<T, String> |
|
||||
| T4.3 | 添加日志 | 关键路径有 tracing 日志 |
|
||||
| T4.4 | 安全审计 | 确认无敏感信息泄露 |
|
||||
|
||||
#### Sprint 5: 持久化安全加固
|
||||
|
||||
| 任务 | 描述 | 验收标准 |
|
||||
|------|------|----------|
|
||||
| T5.1 | 评估加密方案 | 选择 AES-256 或类似 |
|
||||
| T5.2 | 实现 SQLite 加密 | 聊天记录加密存储 |
|
||||
| T5.3 | 密钥管理 | 密钥存储在 OS Keyring |
|
||||
| T5.4 | 兼容性测试 | 旧数据迁移平滑 |
|
||||
|
||||
**交付物:** 重构后的代码、安全加固、测试报告
|
||||
|
||||
---
|
||||
|
||||
### Phase 2: 体验优化 (1-2 月)
|
||||
|
||||
**目标:** 提升用户使用体验
|
||||
|
||||
#### Sprint 6: 性能优化
|
||||
|
||||
| 任务 | 描述 | 验收标准 |
|
||||
|------|------|----------|
|
||||
| T6.1 | 分析 re-render 瓶颈 | 输出性能分析报告 |
|
||||
| T6.2 | Zustand shallow 优化 | 减少不必要的 re-render |
|
||||
| T6.3 | React.memo 优化 | 重点组件优化 |
|
||||
| T6.4 | 性能测试 | 1000+ 消息场景流畅 |
|
||||
|
||||
#### Sprint 7: 飞书集成完善
|
||||
|
||||
| 任务 | 描述 | 验收标准 |
|
||||
|------|------|----------|
|
||||
| T7.1 | OAuth 流程修复 | 完整的认证流程 |
|
||||
| T7.2 | 消息接收 | 支持接收飞书消息 |
|
||||
| T7.3 | 消息发送 | 支持回复飞书消息 |
|
||||
| T7.4 | 消息格式适配 | 支持富文本、图片等 |
|
||||
|
||||
#### Sprint 8: 插件市场 MVP
|
||||
|
||||
| 任务 | 描述 | 验收标准 |
|
||||
|------|------|----------|
|
||||
| T8.1 | 插件市场 UI | 列表、详情、安装界面 |
|
||||
| T8.2 | 插件 API 定义 | 标准化插件接口 |
|
||||
| T8.3 | 插件审核机制 | 基础的内容审核 |
|
||||
| T8.4 | 已有插件迁移 | 3 个插件正常安装 |
|
||||
|
||||
#### Sprint 9: 国际化支持
|
||||
|
||||
| 任务 | 描述 | 验收标准 |
|
||||
|------|------|----------|
|
||||
| T9.1 | i18n 框架集成 | react-i18next 配置 |
|
||||
| T9.2 | 字符串提取 | 提取所有硬编码字符串 |
|
||||
| T9.3 | 中文翻译完善 | 确保中文显示正确 |
|
||||
| T9.4 | 英文翻译 | 基础英文翻译 |
|
||||
| T9.5 | 语言切换 | 支持中英文切换 |
|
||||
|
||||
**交付物:** 性能优化报告、飞书集成文档、插件市场 MVP、i18n 支持
|
||||
|
||||
---
|
||||
|
||||
### Phase 3: 差异化功能 (3-6 月)
|
||||
|
||||
**目标:** 构建竞争壁垒
|
||||
|
||||
#### Sprint 10: 知识图谱基础
|
||||
|
||||
| 任务 | 描述 | 验收标准 |
|
||||
|------|------|----------|
|
||||
| T10.1 | 实体提取 | 从对话中提取实体 |
|
||||
| T10.2 | 关系挖掘 | 实体间关系识别 |
|
||||
| T10.3 | 图谱存储 | 图数据库或关系模拟 |
|
||||
| T10.4 | 查询接口 | 基础的知识图谱查询 |
|
||||
|
||||
#### Sprint 11: 主动建议能力
|
||||
|
||||
| 任务 | 描述 | 验收标准 |
|
||||
|------|------|----------|
|
||||
| T11.1 | 上下文分析 | 分析用户当前任务 |
|
||||
| T11.2 | 建议生成 | 基于上下文生成建议 |
|
||||
| T11.3 | UI 集成 | 在 ChatArea 中展示建议 |
|
||||
| T11.4 | 用户反馈 | 用户可采纳或忽略建议 |
|
||||
|
||||
#### Sprint 12: 跨设备同步 (Pro)
|
||||
|
||||
| 任务 | 描述 | 验收标准 |
|
||||
|------|------|----------|
|
||||
| T12.1 | 端到端加密 | 消息加密传输和存储 |
|
||||
| T12.2 | 设备配对 | 安全的设备注册流程 |
|
||||
| T12.3 | 数据同步 | 消息和记忆同步 |
|
||||
| T12.4 | 冲突解决 | 多设备同时修改时 |
|
||||
|
||||
**交付物:** 知识图谱基础、主动建议能力、跨设备同步原型
|
||||
|
||||
---
|
||||
|
||||
### Phase 4: 生态扩展 (6 月+)
|
||||
|
||||
**目标:** 扩大用户群体和使用场景
|
||||
|
||||
#### 长期规划
|
||||
|
||||
| 功能 | 描述 | 预估工作量 |
|
||||
|------|------|------------|
|
||||
| Tauri Mobile | iOS/Android 支持 | 2-3 月 |
|
||||
| 企业版 | 多用户、权限管理 | 2-3 月 |
|
||||
| API 开放 | 第三方开发者集成 | 1-2 月 |
|
||||
| 本地模型 | Llama.cpp 集成 | 2-3 月 |
|
||||
|
||||
---
|
||||
|
||||
## 三、技术债务清理
|
||||
|
||||
### 3.1 技术债务清单
|
||||
|
||||
| ID | 债务 | 影响 | 清理方式 | 优先级 |
|
||||
|----|------|------|----------|--------|
|
||||
| D1 | gatewayStore.ts 残留引用 | 维护困难 | 全部迁移到领域 Store | P1 |
|
||||
| D2 | 旧版 API 兼容代码 | 体积增加 | 评估后移除 | P2 |
|
||||
| D3 | v1 归档代码未清理 | 混淆 | 删除或移入 archive | P2 |
|
||||
| D4 | 重复的工具函数 | 维护困难 | 提取到 utils | P3 |
|
||||
| D5 | 缺失的 JSDoc | 文档不全 | 补全关键模块 | P3 |
|
||||
|
||||
### 3.2 清理计划
|
||||
|
||||
```
|
||||
Q2: D1, D2
|
||||
Q3: D3
|
||||
Q4: D4, D5
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 四、监控指标
|
||||
|
||||
### 4.1 质量指标
|
||||
|
||||
| 指标 | 当前值 | 目标值 | 监控方式 |
|
||||
|------|--------|--------|----------|
|
||||
| E2E 测试通过率 | ~80% | > 95% | CI/CD |
|
||||
| 单元测试覆盖率 | ~40% | > 60% | Codecov |
|
||||
| TypeScript 错误 | < 10 | 0 | CI/CD |
|
||||
| bundle 大小 | ~2MB | < 2.5MB | 打包监控 |
|
||||
|
||||
### 4.2 性能指标
|
||||
|
||||
| 指标 | 当前值 | 目标值 | 监控方式 |
|
||||
|------|--------|--------|----------|
|
||||
| 首屏加载 | ~2s | < 1.5s | Lighthouse |
|
||||
| 消息响应延迟 | ~200ms | < 100ms | APM |
|
||||
| 内存占用 (idle) | ~150MB | < 200MB | 性能监控 |
|
||||
| WebSocket 重连 | < 3 次 | < 1 次 | 日志分析 |
|
||||
|
||||
### 4.3 业务指标
|
||||
|
||||
| 指标 | 当前值 | 目标值 |
|
||||
|------|--------|--------|
|
||||
| 日活跃用户 | - | 需建立埋点 |
|
||||
| 功能使用率 | - | 需建立埋点 |
|
||||
| 反馈评分 | - | 需收集 |
|
||||
| 崩溃率 | - | < 0.1% |
|
||||
|
||||
---
|
||||
|
||||
## 五、资源需求
|
||||
|
||||
### 5.1 人力需求
|
||||
|
||||
| 角色 | Phase 0-1 | Phase 2 | Phase 3-4 |
|
||||
|------|-----------|---------|-----------|
|
||||
| 前端开发 | 1 | 2 | 2 |
|
||||
| 后端开发 | 1 | 1 | 1 |
|
||||
| 测试开发 | 1 | 1 | 1 |
|
||||
| 产品经理 | 0.5 | 0.5 | 1 |
|
||||
|
||||
### 5.2 技术债务融资
|
||||
|
||||
| 来源 | 可能性 | 备注 |
|
||||
|------|--------|------|
|
||||
| 政府补贴 | 中 | 科技型中小企业 |
|
||||
| 开源捐赠 | 低 | 需要社区基础 |
|
||||
| 企业版收入 | 高 | 长期可持续 |
|
||||
|
||||
---
|
||||
|
||||
## 六、风险与应对
|
||||
|
||||
### 6.1 项目风险
|
||||
|
||||
| 风险 | 概率 | 影响 | 应对措施 |
|
||||
|------|------|------|----------|
|
||||
| ZCLAW 版本不兼容 | 中 | 高 | 建立兼容性测试套件 |
|
||||
| 关键人员离职 | 低 | 高 | 文档和知识共享 |
|
||||
| 竞品快速迭代 | 高 | 中 | 聚焦差异化功能 |
|
||||
| 技术方案不可行 | 低 | 中 | 技术验证先行 |
|
||||
|
||||
### 6.2 应对策略
|
||||
|
||||
1. **版本兼容性**
|
||||
- 方案:建立自动化测试套件
|
||||
- 负责人:测试团队
|
||||
- 开始时间:Phase 1
|
||||
|
||||
2. **竞品压力**
|
||||
- 方案:聚焦差异化(知识图谱、主动建议)
|
||||
- 负责人:产品团队
|
||||
- 开始时间:Phase 3
|
||||
|
||||
---
|
||||
|
||||
## 七、总结
|
||||
|
||||
本优化路线图分为 4 个阶段:
|
||||
|
||||
| 阶段 | 时间 | 目标 |
|
||||
|------|------|------|
|
||||
| Phase 0 | 1-2 周 | 稳定化 - 解决 P0 问题 |
|
||||
| Phase 1 | 2-4 周 | 架构优化 - 提升代码质量 |
|
||||
| Phase 2 | 1-2 月 | 体验优化 - 提升用户满意度 |
|
||||
| Phase 3 | 3-6 月 | 差异化功能 - 构建竞争壁垒 |
|
||||
| Phase 4 | 6 月+ | 生态扩展 - 扩大用户群体 |
|
||||
|
||||
**核心理念:**
|
||||
- 稳定性优先于新功能
|
||||
- 渐进式改进,避免大规模重构
|
||||
- 聚焦差异化,建立竞争壁垒
|
||||
- 保持本地优先,保护用户隐私
|
||||
|
||||
---
|
||||
|
||||
## 八、附录
|
||||
|
||||
### A. 关键里程碑
|
||||
|
||||
| 日期 | 里程碑 | 交付物 |
|
||||
|------|--------|--------|
|
||||
| 2026-03-28 | Phase 0 完成 | 稳定测试套件 |
|
||||
| 2026-04-15 | Phase 1 完成 | 重构代码、安全加固 |
|
||||
| 2026-05-31 | Phase 2 完成 | 性能优化、功能完善 |
|
||||
| 2026-08-31 | Phase 3 完成 | 差异化功能 |
|
||||
|
||||
### B. 审批记录
|
||||
|
||||
| 角色 | 日期 | 签字 |
|
||||
|------|------|------|
|
||||
| 技术负责人 | 2026-03-21 | |
|
||||
| 产品负责人 | 2026-03-21 | |
|
||||
| 项目经理 | 2026-03-21 | |
|
||||
643
docs/archive/old-analysis/PROJECT-SYSTEMATIC-ANALYSIS-REPORT.md
Normal file
@@ -0,0 +1,643 @@
|
||||
# ZCLAW 项目系统性深度分析报告
|
||||
|
||||
> **报告日期:** 2026-03-21
|
||||
> **分析范围:** 代码结构、架构设计、技术栈、业务逻辑、数据流、性能安全
|
||||
> **报告版本:** v1.0
|
||||
|
||||
---
|
||||
|
||||
## 执行摘要
|
||||
|
||||
### 项目概览
|
||||
|
||||
ZCLAW 是一个基于 **ZCLAW** 的中文优先 AI Agent 桌面客户端,采用 **Tauri 2.0 (Rust + React 19)** 架构,目标对标智谱 AutoClaw 和腾讯 QClaw。
|
||||
|
||||
### 核心数据
|
||||
|
||||
| 维度 | 数量 | 评价 |
|
||||
|------|------|------|
|
||||
| 前端组件 | 88 个 .tsx 文件 | ✅ 职责划分清晰 |
|
||||
| Store 文件 | 15 个 (13 活跃 + 2 门面) | ✅ 架构已统一 |
|
||||
| Lib 工具 | 36 个工具文件 | ⚠️ 部分需拆分 |
|
||||
| 类型定义 | 13 个类型文件 | ✅ 类型安全 |
|
||||
| Skills | 68 个 SKILL.md | ✅ 生态丰富 |
|
||||
| Hands | 7 个 HAND.toml | ✅ 自主能力完整 |
|
||||
| Rust 模块 | 8 个主要模块 | ✅ 后端充实 |
|
||||
| Tauri Commands | 70+ | ✅ 接口完整 |
|
||||
| 测试文件 | 15+ | ✅ 覆盖良好 |
|
||||
| 文档文件 | 84+ | ✅ 文档详尽 |
|
||||
|
||||
### 综合评分
|
||||
|
||||
| 维度 | 评分 | 说明 |
|
||||
|------|------|------|
|
||||
| 代码结构 | 4/5 | 组件划分清晰,文件组织合理 |
|
||||
| 架构设计 | 4/5 | 分层清晰,模块职责明确 |
|
||||
| 技术选型 | 4/5 | 框架选择合理,依赖精简 |
|
||||
| 业务实现 | 4/5 | 核心流程完整,异常处理充分 |
|
||||
| 数据流设计 | 4/5 | 流向清晰,同步机制完善 |
|
||||
| 接口设计 | 4/5 | Tauri Commands 粒度合理 |
|
||||
| 性能表现 | 3/5 | 存在优化空间 |
|
||||
| 安全合规 | 4/5 | 认证机制完善 |
|
||||
| 测试覆盖 | 3/5 | 核心逻辑有覆盖 |
|
||||
| 文档质量 | 4/5 | 文档详尽 |
|
||||
| **综合** | **3.8/5** | **良好,有改进空间** |
|
||||
|
||||
---
|
||||
|
||||
## 一、代码结构分析
|
||||
|
||||
### 1.1 项目整体结构
|
||||
|
||||
```
|
||||
ZCLAW/
|
||||
├── desktop/ # Tauri 桌面应用 (React + Rust)
|
||||
│ ├── src/
|
||||
│ │ ├── components/ # 88 个 React 组件
|
||||
│ │ ├── store/ # 15 个 Zustand stores
|
||||
│ │ ├── lib/ # 36 个工具文件
|
||||
│ │ ├── types/ # 13 个类型定义
|
||||
│ │ ├── hooks/ # 自定义 hooks
|
||||
│ │ └── assets/ # 静态资源
|
||||
│ └── src-tauri/ # Rust 后端
|
||||
│ └── src/
|
||||
│ ├── browser/ # 浏览器自动化
|
||||
│ ├── intelligence/ # 智能层 (心跳/反思/压缩)
|
||||
│ ├── memory/ # 记忆系统
|
||||
│ ├── llm/ # LLM 接口
|
||||
│ └── *.rs # Commands 实现
|
||||
├── skills/ # 68 个 SKILL.md
|
||||
├── hands/ # 7 个 HAND.toml
|
||||
├── config/ # TOML 配置文件
|
||||
├── docs/ # 84+ 文档文件
|
||||
├── src/gateway/ # Node.js Gateway 层
|
||||
└── tests/ # 测试文件
|
||||
```
|
||||
|
||||
### 1.2 前端组件层分析
|
||||
|
||||
**组件分类统计:**
|
||||
|
||||
| 类别 | 组件数 | 代表组件 |
|
||||
|------|--------|----------|
|
||||
| 聊天/对话 | 8 | ChatArea, ConversationList, MessageSearch |
|
||||
| Agent/Clone | 6 | CloneManager, AgentOnboardingWizard |
|
||||
| 自动化 Hands | 10 | HandsPanel, HandList, HandApprovalModal |
|
||||
| 工作流 | 4 | WorkflowList, WorkflowEditor |
|
||||
| 团队协作 | 5 | TeamList, TeamCollaborationView |
|
||||
| 记忆/智能 | 6 | MemoryPanel, MemoryGraph, ReflectionLog |
|
||||
| 安全/审计 | 5 | SecurityLayersPanel, SecurityStatus |
|
||||
| 浏览器自动化 | 8 | BrowserHandCard, ScreenshotPreview |
|
||||
| 设置 | 12 | SettingsLayout, General, ModelsAPI... |
|
||||
| UI 基础组件 | 15 | Button, Card, Input, Badge... |
|
||||
|
||||
**评价:** ✅ 组件职责划分清晰,分类合理
|
||||
|
||||
### 1.3 Store 层分析
|
||||
|
||||
**13 个活跃 Zustand Stores:**
|
||||
|
||||
| Store | 职责 | 状态 |
|
||||
|-------|------|------|
|
||||
| chatStore | 聊天消息、会话管理 | ✅ 活跃 |
|
||||
| connectionStore | Gateway 连接状态 | ✅ 活跃 |
|
||||
| agentStore | Clone/Agent 管理 | ✅ 活跃 |
|
||||
| handStore | Hands/Triggers/Approvals | ✅ 活跃 |
|
||||
| workflowStore | 工作流管理 | ✅ 活跃 |
|
||||
| configStore | 配置/渠道/技能/模型 | ✅ 活跃 |
|
||||
| securityStore | 安全状态/审计日志 | ✅ 活跃 |
|
||||
| sessionStore | 会话管理 | ✅ 活跃 |
|
||||
| teamStore | 团队协作 | ✅ 活跃 |
|
||||
| skillMarketStore | 技能市场 | ✅ 活跃 |
|
||||
| memoryGraphStore | 记忆图谱 | ✅ 活跃 |
|
||||
| activeLearningStore | 主动学习 | ✅ 活跃 |
|
||||
| browserHandStore | 浏览器自动化 | ✅ 活跃 |
|
||||
|
||||
**gatewayStore.ts 门面模式:**
|
||||
- 从 1800+ 行缩减到 352 行
|
||||
- 作为向后兼容的 facade 层
|
||||
- 标记为 `@deprecated`
|
||||
|
||||
**评价:** ✅ Store 架构已统一,拆分合理
|
||||
|
||||
### 1.4 Rust 后端结构
|
||||
|
||||
```
|
||||
desktop/src-tauri/src/
|
||||
├── lib.rs # 入口,ZCLAW 集成
|
||||
├── main.rs # 主程序
|
||||
├── viking_commands.rs # OpenViking CLI sidecar
|
||||
├── viking_server.rs # OpenViking 本地服务器
|
||||
├── secure_storage.rs # OS Keyring/Keychain
|
||||
├── memory_commands.rs # 持久化内存命令
|
||||
├── memory/ # 内存提取和上下文构建
|
||||
│ ├── extractor.rs # LLM 驱动的记忆提取
|
||||
│ ├── context_builder.rs # L0/L1/L2 分层上下文
|
||||
│ └── persistent.rs # SQLite 持久化
|
||||
├── llm/ # LLM 接口
|
||||
├── browser/ # 浏览器自动化 (Fantoccini)
|
||||
│ ├── actions.rs
|
||||
│ ├── client.rs
|
||||
│ ├── commands.rs
|
||||
│ ├── error.rs
|
||||
│ ├── mod.rs
|
||||
│ └── session.rs
|
||||
└── intelligence/ # 智能层 (已从前端迁移)
|
||||
├── heartbeat.rs # 心跳引擎
|
||||
├── compactor.rs # 上下文压缩
|
||||
├── reflection.rs # 反思引擎
|
||||
├── identity.rs # Agent 身份管理
|
||||
└── mod.rs
|
||||
```
|
||||
|
||||
**评价:** ✅ 模块组织清晰,职责分明
|
||||
|
||||
### 1.5 代码规模与大型文件
|
||||
|
||||
**大型文件识别:**
|
||||
|
||||
| 文件 | 规模 | 问题 | 建议 |
|
||||
|------|------|------|------|
|
||||
| gateway-client.ts | ~65KB | 职责过重 | 拆分为多模块 |
|
||||
| gatewayStore.ts | 352行 | 已是 facade | 逐步迁移引用 |
|
||||
| intelligence-client.ts | ~15KB | 功能集中 | 保持现状 |
|
||||
| autonomy-manager.ts | ~15KB | 授权逻辑 | 保持现状 |
|
||||
|
||||
**评价:** ⚠️ gateway-client.ts 需要拆分
|
||||
|
||||
---
|
||||
|
||||
## 二、架构设计分析
|
||||
|
||||
### 2.1 整体架构
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ React UI Layer │
|
||||
│ ChatArea, Sidebar, HandsPanel, WorkflowEditor... │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ Zustand State Layer │
|
||||
│ chatStore, connectionStore, agentStore, handStore... │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ Client Layer │
|
||||
│ GatewayClient │ IntelligenceClient │ TeamClient │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ Tauri IPC / WebSocket │
|
||||
├─────────────────────────────────────────────────────────────┤
|
||||
│ Rust Backend │
|
||||
│ browser │ intelligence │ memory │ llm │ secure_storage │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
↕
|
||||
ZCLAW Kernel / OpenViking
|
||||
```
|
||||
|
||||
### 2.2 数据流架构
|
||||
|
||||
**用户操作流程:**
|
||||
```
|
||||
用户操作 → React UI → Zustand Store → GatewayClient
|
||||
↓
|
||||
WebSocket / REST
|
||||
↓
|
||||
ZCLAW Kernel
|
||||
↓
|
||||
Skills / Hands 执行
|
||||
```
|
||||
|
||||
**状态更新流程:**
|
||||
```
|
||||
Backend Event → GatewayClient → Store Update → React Re-render
|
||||
```
|
||||
|
||||
**评价:** ✅ 数据流清晰,分层合理
|
||||
|
||||
### 2.3 通信层设计
|
||||
|
||||
**Gateway Protocol v3:**
|
||||
- 消息类型:req/res/event/stream
|
||||
- 认证:Ed25519 设备签名
|
||||
- 心跳:30秒间隔,3次超时断开
|
||||
- 自动重连:指数退避策略
|
||||
|
||||
**Tauri Commands (70+):**
|
||||
|
||||
| 类别 | 命令数 | 示例 |
|
||||
|------|--------|------|
|
||||
| Browser | 18 | browser_navigate, browser_click |
|
||||
| Memory | 12 | memory_store, memory_search |
|
||||
| Intelligence | 15 | heartbeat_*, reflection_* |
|
||||
| Viking | 9 | viking_status, viking_find |
|
||||
| Gateway | 8 | gateway_start, gateway_stop |
|
||||
| LLM | 3 | llm_complete |
|
||||
|
||||
**评价:** ✅ 通信层设计完整
|
||||
|
||||
### 2.4 分层架构评估
|
||||
|
||||
| 层级 | 技术 | 职责 | 评价 |
|
||||
|------|------|------|------|
|
||||
| 表现层 | React 19 | UI 渲染、用户交互 | ✅ 合理 |
|
||||
| 状态层 | Zustand | 状态管理、流程编排 | ✅ 合理 |
|
||||
| 通信层 | GatewayClient | 网络通信、协议处理 | ✅ 合理 |
|
||||
| 服务层 | Rust | 业务逻辑、智能层 | ✅ 合理 |
|
||||
| 数据层 | SQLite | 本地持久化 | ✅ 合理 |
|
||||
|
||||
---
|
||||
|
||||
## 三、技术栈分析
|
||||
|
||||
### 3.1 前端技术栈
|
||||
|
||||
| 技术 | 版本 | 选型理由 | 评估 |
|
||||
|------|------|----------|------|
|
||||
| React | 19.1.0 | 最新特性,Concurrent 模式 | ✅ 合理 |
|
||||
| Zustand | 5.0.11 | 轻量、类型安全 | ✅ 合理 |
|
||||
| TailwindCSS | 4.2.1 | 原子化样式 | ✅ 合理 |
|
||||
| Framer Motion | 12.36.0 | 声明式动画 | ✅ 合理 |
|
||||
| Lucide React | 0.577.0 | 图标库 | ✅ 合理 |
|
||||
| Tauri | 2.0 | 体积小 (~10MB) | ✅ 合理 |
|
||||
|
||||
### 3.2 后端技术栈
|
||||
|
||||
| 技术 | 用途 | 评估 |
|
||||
|------|------|------|
|
||||
| Rust + Tokio | 异步运行时 | ✅ 高性能 |
|
||||
| SQLite + SQLx | 本地持久化 | ✅ 轻量 |
|
||||
| Fantoccini | 浏览器自动化 | ✅ 成熟 |
|
||||
| Keyring | 安全存储 | ✅ 安全 |
|
||||
| Ed25519 | 设备认证 | ✅ 安全 |
|
||||
|
||||
### 3.3 依赖管理
|
||||
|
||||
**前端依赖 (package.json):**
|
||||
```json
|
||||
{
|
||||
"@tauri-apps/api": "^2",
|
||||
"react": "^19.1.0",
|
||||
"zustand": "^5.0.11",
|
||||
"framer-motion": "^12.36.0",
|
||||
"lucide-react": "^0.577.0"
|
||||
}
|
||||
```
|
||||
|
||||
**后端依赖 (Cargo.toml):**
|
||||
```toml
|
||||
[dependencies]
|
||||
tauri = { version = "2", features = [] }
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
sqlx = { version = "0.7", features = ["runtime-tokio", "sqlite"] }
|
||||
fantoccini = "0.21"
|
||||
keyring = "3"
|
||||
```
|
||||
|
||||
**评价:** ✅ 依赖精简,版本稳定
|
||||
|
||||
---
|
||||
|
||||
## 四、业务逻辑实现分析
|
||||
|
||||
### 4.1 聊天功能
|
||||
|
||||
**消息流程:**
|
||||
```
|
||||
用户输入 → sendMessage()
|
||||
→ 上下文压缩检查 (compactor.checkThreshold)
|
||||
→ 记忆增强 (intelligenceClient.memory.search)
|
||||
→ 添加用户消息
|
||||
→ 创建流式占位消息
|
||||
→ gatewayClient.chatStream()
|
||||
→ 收集 tool/hand/workflow 事件
|
||||
→ 流结束 → 提取记忆 (memory-extractor)
|
||||
→ 触发反思 (intelligenceClient.reflection)
|
||||
```
|
||||
|
||||
**评价:** ✅ 流程完整,异常处理充分
|
||||
|
||||
### 4.2 记忆系统
|
||||
|
||||
**记忆提取模式:**
|
||||
1. **LLM 提取** - 使用 `llmExtract()` 语义提取
|
||||
2. **规则提取** - 正则匹配模式
|
||||
|
||||
**记忆分类:**
|
||||
- fact: 用户事实
|
||||
- preference: 用户偏好
|
||||
- lesson: 经验教训
|
||||
- context: 上下文
|
||||
- task: 任务
|
||||
|
||||
**分层上下文加载(L0/L1/L2):**
|
||||
```
|
||||
L0 (Quick Scan): 向量相似度搜索,返回概览
|
||||
L1 (Standard): 加载 top 候选的 overview
|
||||
L2 (Deep): 加载最相关项的完整内容
|
||||
```
|
||||
|
||||
**评价:** ✅ 设计完善,已迁移到 Rust 后端
|
||||
|
||||
### 4.3 自主能力系统 (Hands)
|
||||
|
||||
**L4 分层授权:**
|
||||
|
||||
| 级别 | 自动内存保存 | 自动压缩 | 自动反思 |
|
||||
|------|-------------|---------|---------|
|
||||
| supervised | ❌ | ❌ | ❌ |
|
||||
| assisted | ✅ | ✅ | ✅ |
|
||||
| autonomous | ✅ | ✅ | ✅ |
|
||||
|
||||
**风险评估:**
|
||||
- ACTION_RISK_MAP 定义每种操作的风险等级
|
||||
- importanceMax + riskMax 双重判断
|
||||
- 所有操作记录审计日志
|
||||
|
||||
**7 个内置 Hands:**
|
||||
|
||||
| Hand | 功能 | 状态 |
|
||||
|------|------|------|
|
||||
| Browser | 网页自动化 | ✅ 可用 |
|
||||
| Researcher | 深度研究 | ✅ 可用 |
|
||||
| Collector | 情报监控 | ✅ 可用 |
|
||||
| Predictor | 趋势预测 | ✅ 可用 |
|
||||
| Lead | 线索挖掘 | ✅ 可用 |
|
||||
| Clip | 视频处理 | ⚠️ 需 FFmpeg |
|
||||
| Twitter | 社媒管理 | ⚠️ 需 API Key |
|
||||
|
||||
**评价:** ✅ 授权机制完善,Hands 系统完整
|
||||
|
||||
### 4.4 智能层实现
|
||||
|
||||
| 模块 | 文件 | 测试 | 集成 |
|
||||
|------|------|------|------|
|
||||
| Agent 记忆 | Rust backend | ✅ | ✅ MemoryPanel |
|
||||
| 身份演化 | Rust backend | ✅ | ✅ Settings |
|
||||
| 上下文压缩 | Rust backend | ✅ | ✅ chatStore |
|
||||
| 自我反思 | Rust backend | ✅ | ✅ ReflectionLog |
|
||||
| 心跳引擎 | Rust backend | ✅ | ✅ HeartbeatConfig |
|
||||
| 主动学习 | TypeScript | ✅ | ✅ ActiveLearningPanel |
|
||||
| Agent 蜂群 | TypeScript | ✅ | ✅ SwarmDashboard |
|
||||
|
||||
**评价:** ✅ 智能层设计深刻,大部分已迁移到 Rust
|
||||
|
||||
### 4.5 功能完成度评估
|
||||
|
||||
| 功能 | 状态 | 完成度 |
|
||||
|------|------|--------|
|
||||
| 聊天界面 | ✅ 完成 | 95% |
|
||||
| 分身管理 | ✅ 完成 | 90% |
|
||||
| 自动化面板 | ✅ 完成 | 85% |
|
||||
| 技能市场 | 🚧 进行中 | 70% |
|
||||
| 工作流编辑 | 📋 计划中 | 50% |
|
||||
| 团队协作 | ✅ 完成 | 80% |
|
||||
| 记忆系统 | ✅ 完成 | 90% |
|
||||
| 安全审计 | ✅ 完成 | 85% |
|
||||
|
||||
---
|
||||
|
||||
## 五、数据流向分析
|
||||
|
||||
### 5.1 状态管理
|
||||
|
||||
**Store 间关系:**
|
||||
```
|
||||
chatStore (核心)
|
||||
↓ 使用
|
||||
connectionStore (连接)
|
||||
↓ 使用
|
||||
gateway-client.ts (通信)
|
||||
|
||||
agentStore, handStore, workflowStore (并行)
|
||||
↓ 各自使用
|
||||
configStore (配置)
|
||||
```
|
||||
|
||||
**持久化策略:**
|
||||
- **SQLite**: 聊天记录、记忆、审计日志
|
||||
- **OS Keyring**: API Key、Token
|
||||
- **localStorage**: 主题、部分配置 (⚠️ 需评估)
|
||||
|
||||
### 5.2 数据持久化
|
||||
|
||||
**SQLite 数据库设计:**
|
||||
```sql
|
||||
CREATE TABLE memories (
|
||||
id TEXT PRIMARY KEY,
|
||||
agent_id TEXT NOT NULL,
|
||||
memory_type TEXT NOT NULL,
|
||||
content TEXT NOT NULL,
|
||||
importance INTEGER DEFAULT 5,
|
||||
source TEXT DEFAULT 'auto',
|
||||
tags TEXT DEFAULT '[]',
|
||||
conversation_id TEXT,
|
||||
created_at TEXT NOT NULL,
|
||||
last_accessed_at TEXT NOT NULL,
|
||||
access_count INTEGER DEFAULT 0,
|
||||
embedding BLOB
|
||||
);
|
||||
```
|
||||
|
||||
**评价:** ✅ 结构清晰,有索引优化
|
||||
|
||||
---
|
||||
|
||||
## 六、接口设计分析
|
||||
|
||||
### 6.1 Tauri Commands 设计
|
||||
|
||||
**命令组织:**
|
||||
- 按功能模块分组
|
||||
- 统一返回 `Result<T, String>`
|
||||
- 使用 Tauri State 管理共享状态
|
||||
|
||||
**示例:**
|
||||
```rust
|
||||
#[tauri::command]
|
||||
async fn memory_search(
|
||||
state: State<'_, MemoryState>,
|
||||
query: String,
|
||||
limit: Option<usize>,
|
||||
) -> Result<Vec<MemoryEntry>, String>
|
||||
```
|
||||
|
||||
### 6.2 Gateway Protocol v3
|
||||
|
||||
**消息格式:**
|
||||
```typescript
|
||||
interface GatewayFrame {
|
||||
id?: string;
|
||||
type: 'req' | 'res' | 'event' | 'stream';
|
||||
method?: string;
|
||||
payload?: unknown;
|
||||
error?: GatewayError;
|
||||
}
|
||||
```
|
||||
|
||||
**评价:** ✅ 接口粒度合理,类型安全
|
||||
|
||||
---
|
||||
|
||||
## 七、性能分析
|
||||
|
||||
### 7.1 渲染性能
|
||||
|
||||
**优化措施:**
|
||||
- ✅ 虚拟滚动 (react-window)
|
||||
- ⚠️ Store selector 可优化 (shallow 比较)
|
||||
- ⚠️ 大型组件可拆分
|
||||
|
||||
### 7.2 网络性能
|
||||
|
||||
**WebSocket 配置:**
|
||||
- 心跳间隔:30 秒
|
||||
- 超时:10 秒
|
||||
- 最大丢失:3 次
|
||||
- 自动重连:指数退避
|
||||
|
||||
**评价:** ✅ 配置合理
|
||||
|
||||
### 7.3 计算性能
|
||||
|
||||
**Token 估算:**
|
||||
```rust
|
||||
// CJK: ~1.5 tokens/字符
|
||||
// ASCII: ~0.3 tokens/字符
|
||||
```
|
||||
|
||||
**评价:** ✅ 算法合理
|
||||
|
||||
---
|
||||
|
||||
## 八、安全分析
|
||||
|
||||
### 8.1 认证授权
|
||||
|
||||
- ✅ Ed25519 设备认证
|
||||
- ✅ L4 分层授权
|
||||
- ✅ 操作审计日志
|
||||
|
||||
### 8.2 数据安全
|
||||
|
||||
| 数据类型 | 存储方式 | 评价 |
|
||||
|----------|----------|------|
|
||||
| API Key | OS Keyring | ✅ 安全 |
|
||||
| Token | OS Keyring | ✅ 安全 |
|
||||
| 聊天记录 | SQLite (未加密) | ⚠️ 需加密 |
|
||||
| 主题配置 | localStorage | ✅ 可接受 |
|
||||
|
||||
### 8.3 输入验证
|
||||
|
||||
- ✅ SQL 注入防护 (参数化查询)
|
||||
- ⚠️ XSS 防护需确认
|
||||
|
||||
---
|
||||
|
||||
## 九、测试覆盖分析
|
||||
|
||||
### 9.1 单元测试
|
||||
|
||||
**测试文件分布:**
|
||||
|
||||
| 测试文件 | 覆盖范围 |
|
||||
|----------|----------|
|
||||
| autonomy-manager.test.ts | L4 授权逻辑 |
|
||||
| agent-memory.test.ts | 记忆系统 |
|
||||
| context-compactor.test.ts | 上下文压缩 |
|
||||
| heartbeat-reflection.test.ts | 心跳和反思 |
|
||||
| gatewayStore.test.ts | Store 状态 |
|
||||
| chatStore.test.ts | 聊天逻辑 |
|
||||
| teamStore.test.ts | 团队协作 |
|
||||
| browserHandStore.test.ts | 浏览器手 |
|
||||
| ws-client.test.ts | WebSocket 客户端 |
|
||||
|
||||
**评价:** ✅ 核心逻辑有覆盖
|
||||
|
||||
### 9.2 E2E 测试
|
||||
|
||||
- ✅ Playwright 已配置
|
||||
- ⚠️ 测试稳定性需提升 (当前 ~80% 通过率)
|
||||
|
||||
---
|
||||
|
||||
## 十、风险识别
|
||||
|
||||
### 10.1 技术风险
|
||||
|
||||
| 风险 | 概率 | 影响 | 缓解措施 |
|
||||
|------|------|------|----------|
|
||||
| ZCLAW 版本不兼容 | 中 | 高 | 兼容性测试套件 |
|
||||
| LLM API 变更 | 中 | 高 | 抽象层隔离 |
|
||||
| 性能瓶颈 | 中 | 中 | 监控和优化 |
|
||||
|
||||
### 10.2 代码质量风险
|
||||
|
||||
| 问题 | 影响 | 优先级 |
|
||||
|------|------|--------|
|
||||
| gateway-client.ts 65KB | 维护困难 | P1 |
|
||||
| Rust unwrap() 使用 | 可能 panic | P1 |
|
||||
| localStorage 降级 | 数据不一致 | P1 |
|
||||
|
||||
### 10.3 维护风险
|
||||
|
||||
- 单人/小团队维护压力
|
||||
- 50+ 组件、36 个 lib、15 个 store 的维护成本
|
||||
|
||||
---
|
||||
|
||||
## 十一、关键发现总结
|
||||
|
||||
### 优势 (Strengths)
|
||||
|
||||
1. **技术栈先进** — Tauri 2.0 比 Electron 体积小 10x+
|
||||
2. **智能层设计深刻** — 记忆、反思、压缩是真正的差异化能力
|
||||
3. **Skills 生态丰富** — 68 个 Skill 覆盖多领域
|
||||
4. **Hands 系统完整** — 7 个能力包 + 审批/触发/审计全链路
|
||||
5. **中文优先** — 中文模型 Provider + 飞书集成
|
||||
6. **测试覆盖好** — 核心逻辑有单元测试
|
||||
7. **文档详尽** — 84+ 文档文件
|
||||
|
||||
### 劣势 (Weaknesses)
|
||||
|
||||
1. **gateway-client.ts 过大** (65KB) — 需拆分
|
||||
2. **E2E 测试不稳定** — 需修复
|
||||
3. **聊天记录未加密** — 需增强安全
|
||||
4. **部分 localStorage 使用** — 需评估
|
||||
|
||||
### 机会 (Opportunities)
|
||||
|
||||
1. 中国 AI Agent 市场爆发
|
||||
2. 本地优先隐私诉求增长
|
||||
3. ZCLAW 生态缺口
|
||||
4. 飞书+企业微信整合需求
|
||||
5. Skill 市场变现潜力
|
||||
|
||||
### 威胁 (Threats)
|
||||
|
||||
1. 竞品迭代极快 (Cursor/Windsurf/AutoClaw)
|
||||
2. ZCLAW 上游变化
|
||||
3. LLM API 不稳定
|
||||
4. 维护成本高
|
||||
|
||||
---
|
||||
|
||||
## 附录
|
||||
|
||||
### A. 关键文件索引
|
||||
|
||||
| 文件 | 位置 | 说明 |
|
||||
|------|------|------|
|
||||
| gateway-client.ts | desktop/src/lib/ | 核心通信客户端 |
|
||||
| intelligence-client.ts | desktop/src/lib/ | 智能层统一 API |
|
||||
| chatStore.ts | desktop/src/store/ | 聊天状态管理 |
|
||||
| lib.rs | desktop/src-tauri/src/ | Rust 后端入口 |
|
||||
| intelligence/ | desktop/src-tauri/src/ | 智能层 Rust 实现 |
|
||||
|
||||
### B. 参考文档
|
||||
|
||||
- [ZCLAW-DEEP-ANALYSIS.md](ZCLAW-DEEP-ANALYSIS.md)
|
||||
- [ZCLAW-DEEP-ANALYSIS-v2.md](ZCLAW-DEEP-ANALYSIS-v2.md)
|
||||
- [BRAINSTORMING-SESSION.md](BRAINSTORMING-SESSION.md)
|
||||
- [OPTIMIZATION-ROADMAP.md](OPTIMIZATION-ROADMAP.md)
|
||||
- [ISSUE-TRACKER.md](ISSUE-TRACKER.md)
|
||||
|
||||
---
|
||||
|
||||
*报告完成*
|
||||
829
docs/archive/old-analysis/SYSTEM_ARCHITECTURE.md
Normal file
@@ -0,0 +1,829 @@
|
||||
# ZCLAW 多端系统架构文档
|
||||
|
||||
> 版本: 1.3 | 日期: 2026-04-06 | 状态: 已更新 (DeerFlow 2.0 + 安全审计 V1 修复 + Admin V2 迁移)
|
||||
|
||||
---
|
||||
|
||||
## 目录
|
||||
|
||||
1. [系统总览](#1-系统总览)
|
||||
2. [端口与协议分配](#2-端口与协议分配)
|
||||
3. [技术栈选型](#3-技术栈选型)
|
||||
4. [数据流向](#4-数据流向)
|
||||
5. [SaaS 后端 API 接口清单](#5-saas-后端-api-接口清单)
|
||||
6. [桌面端内部通信](#6-桌面端内部通信)
|
||||
7. [权限体系](#7-权限体系)
|
||||
8. [各端交互逻辑](#8-各端交互逻辑)
|
||||
9. [部署与启动](#9-部署与启动)
|
||||
10. [接口设计背景与业务价值](#10-接口设计背景与业务价值)
|
||||
|
||||
---
|
||||
|
||||
## 1. 系统总览
|
||||
|
||||
ZCLAW 是面向中文用户的 AI Agent 桌面客户端,由 **4 个独立服务/端** 组成:
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ ZCLAW 系统架构 │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────┐ │
|
||||
│ │ Desktop App │ │ Admin V2 │ │ SaaS Backend │ │
|
||||
│ │ (Tauri+React)│ │ (Vite+AntD) │ │ (Axum + PostgreSQL) │ │
|
||||
│ │ Port: 1420 │ │ Port: 5173 │ │ Port: 8080 │ │
|
||||
│ │ │ │ │ │ │ │
|
||||
│ │ 内核模式: │ │ 管理后台 │ │ REST API │ │
|
||||
│ │ Tauri IPC │ │ JWT 鉴权 │ │ JWT + API Token │ │
|
||||
│ │ │ │ │ │ RBAC 权限 │ │
|
||||
│ │ 网关模式: │ │ │ │ │ │
|
||||
│ │ WS :50051 │ │ │ │ ┌────────────────┐ │ │
|
||||
│ │ WS :4200 │ │ │ │ │ PostgreSQL │ │ │
|
||||
│ │ │ │ │ │ │ Port: 5432 │ │ │
|
||||
│ │ SaaS 模式: │ │ │ │ └────────────────┘ │ │
|
||||
│ │ HTTPS REST │ │ │ │ │ │
|
||||
│ └──────────────┘ └──────────────┘ └──────────────────────┘ │
|
||||
│ │
|
||||
│ ┌──────────────┐ ┌──────────────┐ │
|
||||
│ │ ZCLAW 网关 │ │ LLM 服务商 │ │
|
||||
│ │ (独立二进制) │ │ (外部) │ │
|
||||
│ │ Port: 4200 │ │ OpenAI 等 │ │
|
||||
│ │ Port: 50051 │ │ │ │
|
||||
│ └──────────────┘ └──────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 核心设计理念
|
||||
|
||||
- **双模式架构**: 桌面端支持「本地内核」(离线/低延迟) 和「远程网关」(团队协作) 两种运行模式
|
||||
- **统一 LLM 接入**: 4 条 LLM 路径 (直连 OpenAI、直连火山引擎、SaaS 中转、网关透传)
|
||||
- **集中管控**: SaaS 后端统一管理账号、模型、服务商、Prompt 模板、配置同步
|
||||
- **安全审计**: 完整的操作日志 + TOTP 2FA + JWT + RBAC
|
||||
|
||||
---
|
||||
|
||||
## 2. 端口与协议分配
|
||||
|
||||
| 端口 | 服务 | 协议 | 用途 | 启动方式 |
|
||||
|------|------|------|------|----------|
|
||||
| 1420 | Vite Dev Server | HTTP | 桌面端前端开发服务 (仅 dev) | `pnpm tauri dev` |
|
||||
| 3000 | ~~Next.js Dev Server~~ | HTTP | ~~旧 Admin 管理后台~~ (已废弃) | ~~`pnpm dev` (admin/)~~ |
|
||||
| 5173 | Vite Dev Server | HTTP | Admin V2 管理后台开发服务 | `pnpm dev` (admin-v2/) |
|
||||
| 4200 | ZCLAW Gateway/Kernel | WebSocket + REST | 网关备用端口 | ZCLAW 二进制 |
|
||||
| 50051 | ZCLAW Gateway | WebSocket + REST | 网关主端口 | ZCLAW 二进制 |
|
||||
| 5432 | PostgreSQL | PostgreSQL Wire | SaaS 后端数据库 | Docker/start-all.ps1 |
|
||||
| 8080 | SaaS Backend | HTTP REST | 管理后台 API + 中转代理 | start-saas.ps1 |
|
||||
| 4444 | ChromeDriver | WebDriver HTTP | 浏览器 Hand 自动化 | start-all.ps1 |
|
||||
| N/A | Tauri IPC | invoke() | 桌面端内部进程通信 | 内嵌 |
|
||||
|
||||
---
|
||||
|
||||
## 3. 技术栈选型
|
||||
|
||||
### 3.1 桌面端 (Desktop)
|
||||
|
||||
| 层级 | 技术 | 选型理由 |
|
||||
|------|------|----------|
|
||||
| 桌面框架 | Tauri 2.x | Rust 原生性能,小体积,安全 IPC |
|
||||
| 前端框架 | React 19 + TypeScript | 生态丰富,类型安全 |
|
||||
| 状态管理 | Zustand | 轻量、灵活、无 boilerplate |
|
||||
| 样式方案 | Tailwind 4 | 原子化 CSS,暗色主题友好 |
|
||||
| 数据存储 | SQLite (本地) | 离线优先,FTS5 全文搜索 |
|
||||
|
||||
### 3.2 Admin V2 管理后台
|
||||
|
||||
| 层级 | 技术 | 选型理由 |
|
||||
|------|------|----------|
|
||||
| 框架 | React 19 + Vite 8 | 纯 SPA,快速构建 |
|
||||
| 语言 | TypeScript 5.9 | 类型安全 |
|
||||
| UI 组件 | Ant Design 6 + Pro Components | 企业级组件库,暗色主题 |
|
||||
| 状态管理 | Zustand 5 | 轻量灵活 |
|
||||
| 数据获取 | TanStack React Query 5 | 缓存+去重+自动重验证 |
|
||||
| 路由 | React Router 7 | SPA 路由 |
|
||||
| HTTP | Axios | 拦截器 + 401 自动刷新 |
|
||||
| 样式 | Tailwind CSS v4 | 原子化 CSS |
|
||||
| 测试 | Vitest + Testing Library + MSW | 完整测试覆盖 |
|
||||
|
||||
> **Admin V2 迁移说明**: 从 Next.js + SWR + shadcn/ui 迁移到 Vite + React Query + Ant Design Pro,认证改为 HttpOnly Cookie 模式,11 个管理页面全部重写,含 71 个测试用例。
|
||||
|
||||
### 3.3 SaaS 后端
|
||||
|
||||
| 层级 | 技术 | 选型理由 |
|
||||
|------|------|----------|
|
||||
| Web 框架 | Axum | Rust 高性能异步 Web 框架 |
|
||||
| 数据库 | PostgreSQL | 关系型,复杂查询支持好 |
|
||||
| ORM | sqlx | 编译时 SQL 检查,零开销 |
|
||||
| 认证 | JWT + TOTP | 无状态鉴权 + 双因素认证 |
|
||||
| 加密 | AES-256-GCM | API Key 加密存储 |
|
||||
| 后台任务 | Worker trait + mpsc Channel | 异步非阻塞,支持自动重试 |
|
||||
| 定时任务 | 声明式 Scheduler (TOML) | 无需改代码调整调度时间 |
|
||||
| 连接池 | sqlx PgPool (50 max / 5 min) | 高并发,自动管理生命周期 |
|
||||
| 迁移系统 | SQL 文件 + Schema 版本控制 | TIMESTAMPTZ 类型,向后兼容 |
|
||||
| 多环境 | ZCLAW_ENV (dev/prod/test) | 配置隔离,环境变量覆盖 |
|
||||
|
||||
### 3.4 核心运行时 (Rust Workspace)
|
||||
|
||||
```
|
||||
zclaw-types → 基础类型 (AgentId, Message, Error)
|
||||
zclaw-memory → 存储层 (SQLite, FTS5, TF-IDF, Embeddings)
|
||||
zclaw-runtime → 运行时 (LLM 驱动, 11 层中间件, 工具, Agent 循环)
|
||||
zclaw-kernel → 核心协调 (注册, 调度, 事件, 9 Hands, 75 Skills)
|
||||
zclaw-skills → 技能系统 (SKILL.md 解析, 语义路由, DAG 编排)
|
||||
zclaw-hands → 自主能力 (9 个内置 Hand 实现)
|
||||
zclaw-protocols → 协议支持 (MCP, A2A)
|
||||
zclaw-pipeline → 流水线引擎 (v1/v2 DSL, Smart Presentation)
|
||||
zclaw-growth → 成长系统 (记忆提取/检索/注入, OpenViking 分层)
|
||||
zclaw-saas → SaaS 后端 (独立服务, 8080 端口, 131 API)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. 数据流向
|
||||
|
||||
### 4.1 Admin V2 管理后台数据流
|
||||
|
||||
```
|
||||
用户操作 → React UI → React Query → request.ts (Axios) → Vite Proxy → SaaS 后端 (:8080)
|
||||
↑ ↓
|
||||
└── React Query Cache ←── JSON Response ←── PostgreSQL (:5432) ←─┘
|
||||
```
|
||||
|
||||
**关键路径:**
|
||||
- Admin V2 所有请求通过 `vite.config.ts proxy` 代理到 `localhost:8080`
|
||||
- API 基路径: `/api/v1/*` (前端) → `http://localhost:8080/api/v1/*` (后端)
|
||||
- React Query 缓存: 自动去重 + stale-while-revalidate 模式
|
||||
- SSE 端点 (`/relay/chat/completions`) 超时配置 10 分钟
|
||||
|
||||
### 4.2 桌面端数据流 (Tauri 模式)
|
||||
|
||||
```
|
||||
React UI → Zustand Store → invoke() IPC → Rust Tauri Commands → Kernel → LLM/Tools/Skills/Hands
|
||||
↓
|
||||
SQLite (~/.zclaw/data.db)
|
||||
```
|
||||
|
||||
### 4.3 桌面端数据流 (网关模式)
|
||||
|
||||
```
|
||||
React UI → gateway-client.ts → WebSocket (:50051) → ZCLAW Gateway → Kernel
|
||||
→ REST API (/api/*) →
|
||||
```
|
||||
|
||||
### 4.4 桌面端数据流 (SaaS 模式)
|
||||
|
||||
```
|
||||
React UI → saas-client.ts → HTTPS REST → SaaS 后端 (:8080)
|
||||
llm-service.ts → relay/chat/completions → Provider → LLM API
|
||||
```
|
||||
|
||||
### 4.5 LLM 请求路由 (4 条路径)
|
||||
|
||||
```
|
||||
┌─────────────┐ ┌─ Direct OpenAI ────→ api.openai.com
|
||||
│ │ ├─ Direct Volcengine ─→ volcengine endpoint
|
||||
│ llm-service│────┤
|
||||
│ │ ├─ SaaS Relay ────────→ saas.zclaw.com/relay → Provider
|
||||
│ │ └─ Gateway ───────────→ invoke('agent_chat') or REST
|
||||
└─────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. SaaS 后端 API 接口清单
|
||||
|
||||
### 5.0 通用规范
|
||||
|
||||
- **Base URL**: `http://localhost:8080/api/v1`
|
||||
- **认证方式**: `Authorization: Bearer <JWT_TOKEN>` 或 `Authorization: Bearer zclaw_<API_KEY>`
|
||||
- **Content-Type**: `application/json`
|
||||
- **分页响应格式**: `{ items: T[], total: number, page: number, page_size: number }`
|
||||
- **错误响应格式**: `{ error: string, message: string }`
|
||||
- **HTTP 状态码**: 200 OK, 201 Created, 204 No Content, 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 409 Conflict, 500 Internal Error
|
||||
|
||||
### 5.1 公开接口 (无需认证)
|
||||
|
||||
| # | 方法 | 路径 | 用途 | 业务价值 |
|
||||
|---|------|------|------|----------|
|
||||
| 1 | GET | `/api/health` | 健康检查 | 运维监控探针,检测 DB 连通性 |
|
||||
| 2 | POST | `/api/v1/auth/register` | 用户注册 | 自助开户,降低运营成本 |
|
||||
| 3 | POST | `/api/v1/auth/login` | 用户登录 | 身份验证入口,支持 TOTP 2FA |
|
||||
| 4 | POST | `/api/v1/auth/refresh` | Token 刷新 | 无感续期,单次使用 refresh_token |
|
||||
|
||||
**POST /api/v1/auth/login**
|
||||
|
||||
请求:
|
||||
```typescript
|
||||
{
|
||||
username: string // 接受用户名或邮箱
|
||||
password: string // 8-128 字符
|
||||
totp_code?: string // 6 位数字,启用 TOTP 时必填
|
||||
}
|
||||
```
|
||||
|
||||
响应:
|
||||
```typescript
|
||||
{
|
||||
token: string // JWT access token
|
||||
refresh_token: string // 单次使用 refresh token
|
||||
account: AccountPublic
|
||||
}
|
||||
```
|
||||
|
||||
### 5.2 认证自服务接口 (需登录)
|
||||
|
||||
| # | 方法 | 路径 | 用途 |
|
||||
|---|------|------|------|
|
||||
| 5 | GET | `/api/v1/auth/me` | 获取当前用户信息 |
|
||||
| 6 | PUT | `/api/v1/auth/password` | 修改密码 |
|
||||
| 7 | POST | `/api/v1/auth/totp/setup` | 生成 TOTP 密钥 |
|
||||
| 8 | POST | `/api/v1/auth/totp/verify` | 激活 TOTP 2FA |
|
||||
| 9 | POST | `/api/v1/auth/totp/disable` | 关闭 TOTP 2FA |
|
||||
|
||||
### 5.3 账号管理接口 (Admin)
|
||||
|
||||
| # | 方法 | 路径 | 用途 | 权限 |
|
||||
|---|------|------|------|------|
|
||||
| 10 | GET | `/api/v1/accounts` | 账号列表 (支持搜索/筛选/分页) | `account:admin` |
|
||||
| 11 | GET | `/api/v1/accounts/:id` | 账号详情 | `account:admin` |
|
||||
| 12 | PATCH | `/api/v1/accounts/:id` | 更新账号信息 | `account:admin` |
|
||||
| 13 | PATCH | `/api/v1/accounts/:id/status` | 变更账号状态 | `account:admin` |
|
||||
| 14 | GET | `/api/v1/logs/operations` | 操作日志列表 | `account:admin` |
|
||||
| 15 | GET | `/api/v1/stats/dashboard` | 仪表盘统计聚合 | `account:admin` |
|
||||
| 16 | GET | `/api/v1/devices` | 用户设备列表 | 认证用户 |
|
||||
| 17 | POST | `/api/v1/devices/register` | 注册/更新设备 | 认证用户 |
|
||||
| 18 | POST | `/api/v1/devices/heartbeat` | 设备心跳 | 认证用户 |
|
||||
|
||||
**GET /api/v1/accounts** 查询参数:
|
||||
```typescript
|
||||
{
|
||||
page?: number // 页码,默认 1
|
||||
page_size?: number // 每页条数,默认 20
|
||||
search?: string // 搜索用户名/邮箱/显示名
|
||||
role?: string // 按角色筛选: super_admin | admin | user
|
||||
status?: string // 按状态筛选: active | disabled | suspended
|
||||
}
|
||||
```
|
||||
|
||||
**GET /api/v1/stats/dashboard** 响应:
|
||||
```typescript
|
||||
{
|
||||
total_accounts: number
|
||||
active_accounts: number
|
||||
tasks_today: number
|
||||
active_providers: number
|
||||
active_models: number
|
||||
tokens_today_input: number
|
||||
tokens_today_output: number
|
||||
}
|
||||
```
|
||||
|
||||
### 5.4 服务商管理接口
|
||||
|
||||
| # | 方法 | 路径 | 用途 | 权限 |
|
||||
|---|------|------|------|------|
|
||||
| 19 | GET | `/api/v1/providers` | 服务商列表 | 认证用户 |
|
||||
| 20 | GET | `/api/v1/providers/:id` | 服务商详情 | 认证用户 |
|
||||
| 21 | POST | `/api/v1/providers` | 创建服务商 | `provider:manage` |
|
||||
| 22 | PATCH | `/api/v1/providers/:id` | 更新服务商 | `provider:manage` |
|
||||
| 23 | DELETE | `/api/v1/providers/:id` | 删除服务商 | `provider:manage` |
|
||||
| 24 | GET | `/api/v1/providers/:id/models` | 服务商下的模型列表 | 认证用户 |
|
||||
|
||||
**Provider 数据结构:**
|
||||
```typescript
|
||||
{
|
||||
id: string
|
||||
name: string // 唯一标识名,如 "openai"
|
||||
display_name: string // 显示名,如 "OpenAI"
|
||||
base_url: string // API 基地址
|
||||
api_protocol: 'openai' | 'anthropic'
|
||||
enabled: boolean
|
||||
rate_limit_rpm?: number // 每分钟请求限制
|
||||
rate_limit_tpm?: number // 每分钟 Token 限制
|
||||
created_at: string
|
||||
updated_at: string
|
||||
}
|
||||
```
|
||||
|
||||
### 5.5 模型管理接口
|
||||
|
||||
| # | 方法 | 路径 | 用途 | 权限 |
|
||||
|---|------|------|------|------|
|
||||
| 25 | GET | `/api/v1/models` | 模型列表 | 认证用户 |
|
||||
| 26 | GET | `/api/v1/models/:id` | 模型详情 | 认证用户 |
|
||||
| 27 | POST | `/api/v1/models` | 创建模型 | `model:manage` |
|
||||
| 28 | PATCH | `/api/v1/models/:id` | 更新模型 | `model:manage` |
|
||||
| 29 | DELETE | `/api/v1/models/:id` | 删除模型 | `model:manage` |
|
||||
|
||||
**Model 数据结构:**
|
||||
```typescript
|
||||
{
|
||||
id: string
|
||||
provider_id: string
|
||||
model_id: string // 如 "gpt-4o"
|
||||
alias: string // 显示别名
|
||||
context_window: number // 上下文窗口大小
|
||||
max_output_tokens: number // 最大输出 Token
|
||||
supports_streaming: boolean
|
||||
supports_vision: boolean
|
||||
enabled: boolean
|
||||
pricing_input: number // $/1M tokens
|
||||
pricing_output: number // $/1M tokens
|
||||
}
|
||||
```
|
||||
|
||||
### 5.6 API Key 管理接口
|
||||
|
||||
| # | 方法 | 路径 | 用途 | 权限 |
|
||||
|---|------|------|------|------|
|
||||
| 30 | GET | `/api/v1/keys` | 当前用户的 API Key 列表 | 认证用户 |
|
||||
| 31 | POST | `/api/v1/keys` | 创建 API Key | 认证用户 |
|
||||
| 32 | POST | `/api/v1/keys/:id/rotate` | 轮换 API Key | 认证用户 |
|
||||
| 33 | DELETE | `/api/v1/keys/:id` | 撤销 API Key | 认证用户 |
|
||||
|
||||
### 5.7 Key Pool 管理接口 (Admin)
|
||||
|
||||
| # | 方法 | 路径 | 用途 | 权限 |
|
||||
|---|------|------|------|------|
|
||||
| 34 | GET | `/api/v1/providers/:id/keys` | 服务商 Key Pool 列表 | `provider:manage` |
|
||||
| 35 | POST | `/api/v1/providers/:id/keys` | 添加 Key 到 Pool | `provider:manage` |
|
||||
| 36 | PUT | `/api/v1/providers/:id/keys/:keyId/toggle` | 启用/禁用 Key | `provider:manage` |
|
||||
| 37 | DELETE | `/api/v1/providers/:id/keys/:keyId` | 删除 Key | `provider:manage` |
|
||||
|
||||
**业务价值**: Key Pool 实现多 API Key 智能轮转,自动绕过 429 限流,提升整体吞吐量。
|
||||
|
||||
### 5.8 中转代理接口 (Relay)
|
||||
|
||||
| # | 方法 | 路径 | 用途 | 权限 |
|
||||
|---|------|------|------|------|
|
||||
| 38 | POST | `/api/v1/relay/chat/completions` | LLM 中转请求 | `relay:use` |
|
||||
| 39 | GET | `/api/v1/relay/tasks` | 中转任务列表 | 认证用户 |
|
||||
| 40 | GET | `/api/v1/relay/tasks/:id` | 任务详情 | 认证用户 |
|
||||
| 41 | POST | `/api/v1/relay/tasks/:id/retry` | 重试失败任务 | `relay:admin` |
|
||||
| 42 | GET | `/api/v1/relay/models` | 可用模型列表 | 认证用户 |
|
||||
|
||||
**POST /api/v1/relay/chat/completions** — 核心中转接口
|
||||
|
||||
请求: OpenAI 兼容格式
|
||||
```typescript
|
||||
{
|
||||
model: string
|
||||
messages: Array<{ role: string, content: string }>
|
||||
temperature?: number
|
||||
max_tokens?: number
|
||||
stream?: boolean // 支持 SSE 流式响应
|
||||
// ... 其他字段透传给服务商
|
||||
}
|
||||
```
|
||||
|
||||
响应:
|
||||
- 非流式: `application/json` — 原始服务商响应
|
||||
- 流式: `text/event-stream` — SSE 事件流
|
||||
|
||||
**业务价值**: 统一入口代理多家 LLM 服务商,自动 Key Pool 轮转、429 处理、用量计费。
|
||||
|
||||
### 5.9 用量统计接口
|
||||
|
||||
| # | 方法 | 路径 | 用途 |
|
||||
|---|------|------|------|
|
||||
| 43 | GET | `/api/v1/usage` | 用量统计 (按天/按模型) |
|
||||
|
||||
**查询参数:**
|
||||
```typescript
|
||||
{
|
||||
from?: string // ISO 8601 开始日期
|
||||
to?: string // ISO 8601 结束日期
|
||||
provider_id?: string // 按服务商筛选
|
||||
model_id?: string // 按模型筛选
|
||||
group_by?: 'day' | 'model'
|
||||
days?: number // 最近 N 天
|
||||
}
|
||||
```
|
||||
|
||||
**响应:**
|
||||
```typescript
|
||||
{
|
||||
total_requests: number
|
||||
total_input_tokens: number
|
||||
total_output_tokens: number
|
||||
by_model: Array<{ model_id, count, input_tokens, output_tokens }>
|
||||
by_day: Array<{ day, count, input_tokens, output_tokens }>
|
||||
}
|
||||
```
|
||||
|
||||
### 5.10 配置管理接口
|
||||
|
||||
| # | 方法 | 路径 | 用途 | 权限 |
|
||||
|---|------|------|------|------|
|
||||
| 44 | GET | `/api/v1/config/items` | 配置项列表 | 认证用户 |
|
||||
| 45 | GET | `/api/v1/config/items/:id` | 配置项详情 | 认证用户 |
|
||||
| 46 | POST | `/api/v1/config/items` | 创建配置项 | `config:write` |
|
||||
| 47 | PATCH | `/api/v1/config/items/:id` | 更新配置项 | `config:write` |
|
||||
| 48 | DELETE | `/api/v1/config/items/:id` | 删除配置项 | `config:write` |
|
||||
| 49 | GET | `/api/v1/config/analysis` | 配置分析 | 认证用户 |
|
||||
| 50 | POST | `/api/v1/config/seed` | 种子配置 | `config:write` |
|
||||
| 51 | POST | `/api/v1/config/sync` | 双向配置同步 | `config:write` |
|
||||
| 52 | POST | `/api/v1/config/diff` | 配置差异比较 | 认证用户 |
|
||||
| 53 | GET | `/api/v1/config/sync-logs` | 同步日志 | 认证用户 |
|
||||
| 54 | GET | `/api/v1/config/pull` | 批量拉取配置 | 认证用户 |
|
||||
|
||||
**业务价值**: 集中管理所有运行参数(服务器、Agent、记忆、LLM、安全策略),支持桌面端双向同步,推送/拉取/合并三种模式。
|
||||
|
||||
### 5.11 角色与权限接口
|
||||
|
||||
| # | 方法 | 路径 | 用途 | 权限 |
|
||||
|---|------|------|------|------|
|
||||
| 55 | GET | `/api/v1/roles` | 角色列表 | `account:read` |
|
||||
| 56 | GET | `/api/v1/roles/:id` | 角色详情 | `account:read` |
|
||||
| 57 | POST | `/api/v1/roles` | 创建角色 | `account:admin` |
|
||||
| 58 | PUT | `/api/v1/roles/:id` | 更新角色 | `account:admin` |
|
||||
| 59 | DELETE | `/api/v1/roles/:id` | 删除角色 | `account:admin` |
|
||||
| 60 | GET | `/api/v1/roles/:id/permissions` | 角色权限列表 | `account:read` |
|
||||
| 61 | GET | `/api/v1/permission-templates` | 权限模板列表 | `account:read` |
|
||||
| 62 | GET | `/api/v1/permission-templates/:id` | 权限模板详情 | `account:read` |
|
||||
| 63 | POST | `/api/v1/permission-templates` | 创建权限模板 | `account:admin` |
|
||||
| 64 | DELETE | `/api/v1/permission-templates/:id` | 删除权限模板 | `account:admin` |
|
||||
| 65 | POST | `/api/v1/permission-templates/:id/apply` | 批量应用权限模板 | `account:admin` |
|
||||
|
||||
### 5.12 Prompt 模板管理接口
|
||||
|
||||
| # | 方法 | 路径 | 用途 | 权限 |
|
||||
|---|------|------|------|------|
|
||||
| 66 | GET | `/api/v1/prompts` | 模板列表 | `prompt:read` |
|
||||
| 67 | POST | `/api/v1/prompts` | 创建模板 | `prompt:write` |
|
||||
| 68 | GET | `/api/v1/prompts/:name` | 模板详情 | `prompt:read` |
|
||||
| 69 | PUT | `/api/v1/prompts/:name` | 更新模板元数据 | `prompt:write` |
|
||||
| 70 | DELETE | `/api/v1/prompts/:name` | 归档模板 | `prompt:admin` |
|
||||
| 71 | GET | `/api/v1/prompts/:name/versions` | 版本历史 | `prompt:read` |
|
||||
| 72 | GET | `/api/v1/prompts/:name/versions/:v` | 特定版本 | `prompt:read` |
|
||||
| 73 | POST | `/api/v1/prompts/:name/versions` | 发布新版本 | `prompt:write` |
|
||||
| 74 | POST | `/api/v1/prompts/:name/rollback/:v` | 回滚版本 | `prompt:admin` |
|
||||
| 75 | POST | `/api/v1/prompts/check` | OTA 更新检查 | 认证用户 |
|
||||
|
||||
**POST /api/v1/prompts/check** — OTA 更新检查
|
||||
|
||||
请求:
|
||||
```typescript
|
||||
{
|
||||
device_id: string
|
||||
versions: Record<string, number> // { "reflection": 3, "compaction": 2 }
|
||||
}
|
||||
```
|
||||
|
||||
响应:
|
||||
```typescript
|
||||
{
|
||||
updates: Array<{
|
||||
name: string
|
||||
version: number
|
||||
system_prompt: string
|
||||
user_prompt_template?: string
|
||||
variables: PromptVariable[]
|
||||
source: string
|
||||
min_app_version?: string
|
||||
}>
|
||||
server_time: string
|
||||
}
|
||||
```
|
||||
|
||||
**业务价值**: 集中管理 Prompt 模板,桌面端每 30 分钟检查更新,无需发版即可优化提示词。
|
||||
|
||||
### 5.13 Agent 模板管理接口
|
||||
|
||||
| # | 方法 | 路径 | 用途 | 权限 |
|
||||
|---|------|------|------|------|
|
||||
| 76 | GET | `/api/v1/agent-templates` | Agent 模板列表 | `model:read` |
|
||||
| 77 | POST | `/api/v1/agent-templates` | 创建 Agent 模板 | `model:manage` |
|
||||
| 78 | GET | `/api/v1/agent-templates/:id` | 模板详情 | `model:read` |
|
||||
| 79 | POST | `/api/v1/agent-templates/:id` | 更新模板 | `model:manage` |
|
||||
| 80 | DELETE | `/api/v1/agent-templates/:id` | 归档模板 | `model:manage` |
|
||||
|
||||
**AgentTemplate 数据结构:**
|
||||
```typescript
|
||||
{
|
||||
id: string
|
||||
name: string
|
||||
description?: string
|
||||
category: string
|
||||
source: 'builtin' | 'custom'
|
||||
model?: string
|
||||
system_prompt?: string
|
||||
tools: string[]
|
||||
capabilities: string[]
|
||||
temperature?: number
|
||||
max_tokens?: number
|
||||
visibility: 'public' | 'team' | 'private'
|
||||
status: 'active' | 'archived'
|
||||
current_version: number
|
||||
}
|
||||
```
|
||||
|
||||
### 5.14 遥测接口
|
||||
|
||||
| # | 方法 | 路径 | 用途 | 权限 |
|
||||
|---|------|------|------|------|
|
||||
| 81 | POST | `/api/v1/telemetry/report` | 上报遥测数据 | 认证用户 |
|
||||
| 82 | GET | `/api/v1/telemetry/stats` | 按模型统计 | 认证用户 |
|
||||
| 83 | GET | `/api/v1/telemetry/daily` | 按天统计 | 认证用户 |
|
||||
| 84 | POST | `/api/v1/telemetry/audit` | 上报审计摘要 | 认证用户 |
|
||||
|
||||
**POST /api/v1/telemetry/report** 请求:
|
||||
```typescript
|
||||
{
|
||||
device_id: string
|
||||
app_version: string
|
||||
entries: Array<{
|
||||
model_id: string
|
||||
input_tokens: number
|
||||
output_tokens: number
|
||||
latency_ms?: number
|
||||
success: boolean
|
||||
error_type?: string
|
||||
timestamp: string
|
||||
connection_mode: 'tauri' | 'saas'
|
||||
}> // 最多 500 条/请求
|
||||
}
|
||||
```
|
||||
|
||||
**业务价值**: 桌面端批量上报本地 LLM 用量,管理员可在后台查看所有设备的 Token 消耗、延迟、成功率。
|
||||
|
||||
---
|
||||
|
||||
## 6. 桌面端内部通信
|
||||
|
||||
### 6.1 Tauri Commands 清单
|
||||
|
||||
桌面端通过 `invoke()` IPC 暴露以下命令组:
|
||||
|
||||
| 命令组 | 文件 | 命令数 | 用途 |
|
||||
|--------|------|--------|------|
|
||||
| 进程管理 | lib.rs | 10 | zclaw_start/stop/restart, doctor, health_check |
|
||||
| 内核操作 | kernel_commands.rs | 34 | agent_create/chat_stream, skill_execute, hand_execute, trigger, workflow |
|
||||
| 工作流 | pipeline_commands.rs | 10 | pipeline_run/progress/cancel, route_intent |
|
||||
| 浏览器自动化 | browser_commands.rs | 22 | navigate/click/fill/screenshot/evaluate |
|
||||
| 智能层 | intelligence_commands.rs | 35 | memory/identity/reflection/heartbeat/autonomy |
|
||||
| 持久记忆 | memory_commands.rs | 14 | memory_store/get/search/export/graph |
|
||||
| Viking 存储 | viking_commands.rs | 13 | viking_add/find/grep/read |
|
||||
| CLI 工具 | cli_commands.rs | 13 | doctor/health/export/import |
|
||||
| 安全存储 | secure_storage.rs | 4 | store/get/delete/list |
|
||||
| LLM 管理 | llm_commands.rs | 3 | list_providers/test_connection |
|
||||
|
||||
> **总计**: 177 个 Tauri Commands (160 已接通前端 + 16 个 @reserved 预留 + 1 个未注册)
|
||||
|
||||
### 6.2 WebSocket 事件类型
|
||||
|
||||
| 方向 | 事件 | 说明 |
|
||||
|------|------|------|
|
||||
| Server→Client | `text_delta` | 流式文本片段 |
|
||||
| Server→Client | `phase` | 阶段切换 (thinking/tool) |
|
||||
| Server→Client | `tool_call` / `tool_result` | 工具调用与结果 |
|
||||
| Server→Client | `hand` | Hand 自主能力触发 |
|
||||
| Server→Client | `error` | 错误通知 |
|
||||
| Client→Server | `message` | 发送消息 |
|
||||
| Client→Server | `auth_challenge` / `auth_response` | Ed25519 握手 |
|
||||
| 双向 | `ping` / `pong` | 心跳 (30s 间隔) |
|
||||
|
||||
---
|
||||
|
||||
## 7. 权限体系
|
||||
|
||||
### 7.1 角色定义
|
||||
|
||||
| 角色 | 权限范围 |
|
||||
|------|----------|
|
||||
| `super_admin` | 全部权限 (`admin:full`) |
|
||||
| `admin` | 账号管理、服务商/模型管理、中转管理、配置读写、Prompt 读写发布 |
|
||||
| `user` | 模型读取、中转使用、配置读取、Prompt 读取 |
|
||||
|
||||
### 7.2 权限清单
|
||||
|
||||
| 权限 | 说明 |
|
||||
|------|------|
|
||||
| `admin:full` | 超级权限,绕过所有检查 |
|
||||
| `account:admin` | 账号管理 (列表、状态变更、角色分配) |
|
||||
| `account:read` | 读取账号、角色、权限模板 |
|
||||
| `provider:manage` | 创建/更新/删除服务商、管理 Key Pool |
|
||||
| `model:manage` | 创建/更新/删除模型、Agent 模板 |
|
||||
| `model:read` | 读取模型、Agent 模板 |
|
||||
| `relay:use` | 使用中转 (chat completions) |
|
||||
| `relay:admin` | 查看任意中转任务、重试失败任务 |
|
||||
| `config:write` | 创建/更新/删除配置项、同步、种子 |
|
||||
| `prompt:read` | 读取 Prompt 模板和版本 |
|
||||
| `prompt:write` | 创建/更新 Prompt 模板和版本 |
|
||||
| `prompt:admin` | 归档 Prompt、回滚版本 |
|
||||
|
||||
---
|
||||
|
||||
## 8. 各端交互逻辑
|
||||
|
||||
### 8.1 Admin 管理后台 ↔ SaaS 后端
|
||||
|
||||
```
|
||||
┌───────────────────────────────────────────────────────────┐
|
||||
│ Admin V2 浏览器 (localhost:5173) │
|
||||
│ │
|
||||
│ ┌──────────┐ React Query ┌──────────────┐ │
|
||||
│ │ React UI │◄────────────►│ Axios │ │
|
||||
│ │ 11 页面 │ Cache │ Cookie 认证 │ │
|
||||
│ └──────────┘ └──────┬───────┘ │
|
||||
│ │ axios() │
|
||||
└──────────────────────────────────┼────────────────────────┘
|
||||
│
|
||||
Vite Proxy │ /api/* → localhost:8080/api/*
|
||||
│
|
||||
┌──────────────────────────────────┼────────────────────────┐
|
||||
│ SaaS Backend (:8080) │ │
|
||||
│ ┌──────▼───────┐ │
|
||||
│ │ Axum Router │ │
|
||||
│ │ 中间件栈: │ │
|
||||
│ │ 1. Auth │ │
|
||||
│ │ 2. RateLimit │ │
|
||||
│ │ 3. RequestID │ │
|
||||
│ │ 4. Version │ │
|
||||
│ └──────┬───────┘ │
|
||||
│ │ │
|
||||
│ ┌─────────────▼──────────────┐ │
|
||||
│ │ Handlers (131 个端点) │ │
|
||||
│ │ auth/account/model/relay/ │ │
|
||||
│ │ config/prompt/telemetry/ │ │
|
||||
│ └─────────────┬──────────────┘ │
|
||||
│ │ │
|
||||
│ ┌─────────────▼──────────────┐ │
|
||||
│ │ PostgreSQL (:5432) │ │
|
||||
│ └─────────────────────────────┘ │
|
||||
└───────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 8.2 桌面端交互矩阵
|
||||
|
||||
| 场景 | 通信方式 | 目标 | 数据 |
|
||||
|------|----------|------|------|
|
||||
| 本地对话 | Tauri IPC invoke() | Kernel | 消息、Agent、Skills |
|
||||
| 流式响应 | Tauri Event listen() | Kernel | stream:chunk 事件 |
|
||||
| 远程对话 | WebSocket :50051 | ZCLAW Gateway | 消息、事件流 |
|
||||
| SaaS 登录 | HTTPS REST | SaaS :8080 | JWT 认证 |
|
||||
| LLM 中转 | HTTPS REST | SaaS :8080/relay | OpenAI 兼容请求 |
|
||||
| Prompt OTA | HTTPS REST | SaaS :8080/prompts/check | 版本号 → 更新 |
|
||||
| 配置同步 | HTTPS REST | SaaS :8080/config/sync | 双向键值对 |
|
||||
| 遥测上报 | HTTPS REST | SaaS :8080/telemetry/report | 批量用量数据 |
|
||||
|
||||
---
|
||||
|
||||
## 9. 部署与启动
|
||||
|
||||
### 9.1 完整启动顺序
|
||||
|
||||
```powershell
|
||||
# start-all.ps1 启动顺序:
|
||||
1. PostgreSQL → :5432 (Docker 或本地服务)
|
||||
2. SaaS Backend → :8080 (zclaw-saas.exe)
|
||||
3. ChromeDriver → :4444 (可选, 用于 Browser Hand)
|
||||
4. Desktop Dev → :1420 (Tauri dev)
|
||||
```
|
||||
|
||||
### 9.2 SaaS 后端配置
|
||||
|
||||
#### 配置加载优先级
|
||||
|
||||
```
|
||||
ZCLAW_SAAS_CONFIG (精确路径) > ZCLAW_ENV (环境选择) > ./saas-config.toml (默认)
|
||||
```
|
||||
|
||||
环境配置文件:
|
||||
- `ZCLAW_ENV=development` -> `config/saas-development.toml`
|
||||
- `ZCLAW_ENV=production` -> `config/saas-production.toml`
|
||||
- `ZCLAW_ENV=test` -> `config/saas-test.toml`
|
||||
|
||||
环境变量覆盖:
|
||||
- `ZCLAW_DATABASE_URL` — 覆盖数据库 URL (避免配置文件存密码)
|
||||
- `ZCLAW_SAAS_JWT_SECRET` — JWT 签名密钥 (生产环境必须设置)
|
||||
- `ZCLAW_TOTP_ENCRYPTION_KEY` — TOTP/AES-256-GCM 加密密钥 (hex 64 字符)
|
||||
- `ZCLAW_SAAS_DEV` — 开发模式 (允许使用不安全的默认密钥)
|
||||
|
||||
#### 配置结构
|
||||
|
||||
```toml
|
||||
# saas-config.toml
|
||||
[server]
|
||||
host = "0.0.0.0"
|
||||
port = 8080
|
||||
cors_origins = []
|
||||
|
||||
[database]
|
||||
url = "postgres://postgres:123123@localhost:5432/zclaw"
|
||||
|
||||
[auth]
|
||||
jwt_expiration_hours = 24
|
||||
totp_issuer = "ZCLAW SaaS"
|
||||
refresh_token_hours = 168 # 7 天
|
||||
|
||||
[relay]
|
||||
max_queue_size = 1000
|
||||
max_concurrent_per_provider = 5 # 预留
|
||||
batch_window_ms = 50 # 预留
|
||||
retry_delay_ms = 1000
|
||||
max_attempts = 3
|
||||
|
||||
[rate_limit]
|
||||
requests_per_minute = 60
|
||||
burst = 10
|
||||
|
||||
# 声明式定时任务 (新增)
|
||||
[[scheduler.jobs]]
|
||||
name = "cleanup-refresh-tokens"
|
||||
interval = "1h"
|
||||
task = "cleanup_refresh_tokens"
|
||||
run_on_start = false
|
||||
|
||||
[[scheduler.jobs]]
|
||||
name = "cleanup-rate-limit"
|
||||
interval = "5m"
|
||||
task = "cleanup_rate_limit"
|
||||
run_on_start = false
|
||||
```
|
||||
|
||||
#### 连接池参数
|
||||
|
||||
| 参数 | 值 | 说明 |
|
||||
|------|-----|------|
|
||||
| max_connections | 50 | 最大并发连接数 |
|
||||
| min_connections | 5 | 最小空闲连接数 |
|
||||
| acquire_timeout | 10s | 获取连接超时 |
|
||||
| idle_timeout | 300s | 空闲连接回收 |
|
||||
| max_lifetime | 1800s | 连接最大生命周期 |
|
||||
|
||||
#### Worker 系统
|
||||
|
||||
| Worker | 职责 | 触发方式 |
|
||||
|--------|------|---------|
|
||||
| LogOperationWorker | 异步写入操作日志 | Handler 派发 |
|
||||
| CleanupRefreshTokensWorker | 清理过期 Refresh Token | Scheduler 定时 |
|
||||
| CleanupRateLimitWorker | 清理过期限流条目 | Scheduler 定时 |
|
||||
| RecordUsageWorker | 记录 Token 用量 | Relay Handler 派发 |
|
||||
| UpdateLastUsedWorker | 更新 Key 最后使用时间 | Relay Handler 派发 |
|
||||
| AggregateUsageWorker | 日/月用量聚合 | Scheduler 定时 |
|
||||
| GenerateEmbeddingWorker | 知识条目 embedding 生成 | Handler 派发 |
|
||||
|
||||
#### SQL 迁移系统
|
||||
|
||||
- Schema 版本: **v8**
|
||||
- 迁移目录: `crates/zclaw-saas/migrations/`
|
||||
- 时间戳类型: **TIMESTAMPTZ** (新库),向后兼容 TEXT (旧库)
|
||||
- 迁移文件按文件名排序执行
|
||||
|
||||
---
|
||||
|
||||
## 10. 接口设计背景与业务价值
|
||||
|
||||
### 10.1 中转代理 (Relay) — 核心收入引擎
|
||||
|
||||
**背景**: 多家 LLM 服务商 API 各不相同,用户需统一入口。
|
||||
|
||||
**设计价值**:
|
||||
- OpenAI 兼容接口降低接入成本
|
||||
- Key Pool 智能轮转绕过限流
|
||||
- 自动 429 处理 + 冷却恢复
|
||||
- 按账号精确计费 (input/output tokens)
|
||||
|
||||
### 10.2 Prompt OTA — 无感更新
|
||||
|
||||
**背景**: Prompt 工程需要频繁迭代,但桌面端发版周期长。
|
||||
|
||||
**设计价值**:
|
||||
- 集中管理 reflection/compaction/extraction 等核心 Prompt
|
||||
- 桌面端每 30 分钟自动检查更新
|
||||
- 版本化 + 回滚能力
|
||||
- min_app_version 兼容性控制
|
||||
|
||||
### 10.3 配置同步 — 多设备一致
|
||||
|
||||
**背景**: 用户多台设备需保持配置一致。
|
||||
|
||||
**设计价值**:
|
||||
- push/pull/merge 三种同步模式
|
||||
- 乐观锁 (client_timestamps) 冲突检测
|
||||
- 只读 diff 不修改数据
|
||||
- 同步日志可追溯
|
||||
|
||||
### 10.4 Key Pool — 高可用保障
|
||||
|
||||
**背景**: 单个 API Key 容易触发限流 (429)。
|
||||
|
||||
**设计价值**:
|
||||
- 多 Key 按优先级智能选择
|
||||
- 429 自动冷却 + 切换
|
||||
- RPM/TPM 限额独立配置
|
||||
- 配额重置周期支持
|
||||
|
||||
### 10.5 遥测上报 — 数据驱动优化
|
||||
|
||||
**背景**: 桌面端本地 LLM 用量无法直接观测。
|
||||
|
||||
**设计价值**:
|
||||
- 批量上报 (500 条/次) 减少请求
|
||||
- 按模型聚合: Token 消耗、延迟、成功率
|
||||
- 按天聚合: 请求量、设备活跃度
|
||||
- 审计摘要: 操作类型 + 结果
|
||||
|
||||
---
|
||||
|
||||
> **文档统计**: 131 个 API 端点 | 5 个通信通道 | 12 种权限 | 4 个独立服务 | 7 个 Workers | 声明式 Scheduler | SQL Schema v8
|
||||
541
docs/archive/old-analysis/ZCLAW-DEEP-ANALYSIS-v2.md
Normal file
@@ -0,0 +1,541 @@
|
||||
# ZCLAW 项目系统性深度分析报告 v2
|
||||
|
||||
> **分析日期:** 2026-03-21
|
||||
> **分析范围:** 代码结构、架构设计、技术栈、业务逻辑、数据流、性能安全
|
||||
|
||||
---
|
||||
|
||||
## 一、项目概览
|
||||
|
||||
### 1.1 项目定位
|
||||
|
||||
ZCLAW 是一个基于 ZCLAW 的中文优先 AI Agent 桌面客户端,采用 **Tauri 2.0 (Rust + React 19)** 架构,目标对标智谱 AutoClaw 和腾讯 QClaw。
|
||||
|
||||
### 1.2 技术栈全景
|
||||
|
||||
| 层级 | 技术选型 | 成熟度 |
|
||||
|------|----------|--------|
|
||||
| 桌面框架 | Tauri 2.0 (Rust + React 19) | ✅ 合理 |
|
||||
| 前端 | React 19 + TailwindCSS 4 + Zustand 5 + Framer Motion + Lucide | ✅ 现代 |
|
||||
| 后端通信 | WebSocket (Gateway Protocol v3) + Tauri Commands | ✅ 完整 |
|
||||
| 状态管理 | Zustand (13 个 Store) + Facade Pattern | ⚠️ 过度拆分但已收敛 |
|
||||
| 配置格式 | TOML | ✅ 用户友好 |
|
||||
| 测试 | Vitest + Playwright | ✅ 覆盖较好 |
|
||||
| 依赖 | 精简 (React 19, Zustand 5, Tauri 2) | ✅ 轻量 |
|
||||
|
||||
### 1.3 规模数据
|
||||
|
||||
| 维度 | 数量 |
|
||||
|------|------|
|
||||
| 前端组件 | 50+ .tsx 文件 |
|
||||
| Lib 工具 | 40+ 文件 |
|
||||
| Store 文件 | 13 个 Zustand stores |
|
||||
| 类型定义 | 13 个类型文件 |
|
||||
| Skills | 68 个 SKILL.md |
|
||||
| Hands | 7 个 HAND.toml |
|
||||
| Rust 模块 | 8 个主要模块 |
|
||||
| 测试文件 | 15+ 测试文件 |
|
||||
|
||||
---
|
||||
|
||||
## 二、架构深度分析
|
||||
|
||||
### 2.1 整体架构图
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────────────────────┐
|
||||
│ React UI Layer │
|
||||
│ ChatArea, Sidebar, HandsPanel, WorkflowEditor, TeamView... │
|
||||
├──────────────────────────────────────────────────────────────────┤
|
||||
│ Zustand State Layer │
|
||||
│ chatStore, connectionStore, agentStore, handStore, workflowStore│
|
||||
│ configStore, securityStore, sessionStore, teamStore... │
|
||||
├──────────────────────────────────────────────────────────────────┤
|
||||
│ Client Layer │
|
||||
│ GatewayClient │ IntelligenceClient │ TeamClient │ BrowserClient │
|
||||
├──────────────────────────────────────────────────────────────────┤
|
||||
│ Tauri IPC / WebSocket │
|
||||
├──────────────────────────────────────────────────────────────────┤
|
||||
│ Rust Backend │
|
||||
│ browser │ intelligence │ memory │ llm │ viking │ secure_storage │
|
||||
└──────────────────────────────────────────────────────────────────┘
|
||||
↕
|
||||
ZCLAW Kernel / OpenViking
|
||||
```
|
||||
|
||||
### 2.2 前端架构分析
|
||||
|
||||
#### 2.2.1 组件层 (desktop/src/components/)
|
||||
|
||||
**组件分类:**
|
||||
|
||||
| 类别 | 组件数 | 代表组件 |
|
||||
|------|--------|----------|
|
||||
| 聊天/对话 | 8 | ChatArea, ConversationList, MessageSearch |
|
||||
| Agent/Clone | 6 | CloneManager, AgentOnboardingWizard, PersonalitySelector |
|
||||
| 自动化 Hands | 10 | HandsPanel, HandList, HandParamsForm, HandApprovalModal |
|
||||
| 工作流 | 4 | WorkflowList, WorkflowEditor, WorkflowHistory |
|
||||
| 团队协作 | 5 | TeamList, TeamCollaborationView, DevQALoop |
|
||||
| 记忆/智能 | 6 | MemoryPanel, MemoryGraph, ActiveLearningPanel, ReflectionLog |
|
||||
| 安全/审计 | 5 | SecurityLayersPanel, SecurityStatus, AuditLogsPanel |
|
||||
| 浏览器自动化 | 8 | BrowserHandCard, ScreenshotPreview, TaskTemplateModal |
|
||||
| 设置 | 12 | SettingsLayout, General, ModelsAPI, MCPServices... |
|
||||
| UI 基础组件 | 15 | Button, Card, Input, Badge, Toast, EmptyState... |
|
||||
|
||||
**评价:** ✅ 组件职责划分清晰,分类合理
|
||||
|
||||
#### 2.2.2 状态管理层 (desktop/src/store/)
|
||||
|
||||
**13 个 Zustand Stores:**
|
||||
|
||||
| Store | 职责 | 状态 |
|
||||
|-------|------|------|
|
||||
| chatStore | 聊天消息、会话管理 | ✅ 活跃 |
|
||||
| connectionStore | Gateway 连接状态 | ✅ 活跃 |
|
||||
| agentStore | Clone/Agent 管理 | ✅ 活跃 |
|
||||
| handStore | Hands/Triggers/Approvals | ✅ 活跃 |
|
||||
| workflowStore | 工作流管理 | ✅ 活跃 |
|
||||
| configStore | 配置/渠道/技能/模型 | ✅ 活跃 |
|
||||
| securityStore | 安全状态/审计日志 | ✅ 活跃 |
|
||||
| sessionStore | 会话管理 | ✅ 活跃 |
|
||||
| teamStore | 团队协作 | ✅ 活跃 |
|
||||
| skillMarketStore | 技能市场 | ✅ 活跃 |
|
||||
| memoryGraphStore | 记忆图谱 | ✅ 活跃 |
|
||||
| activeLearningStore | 主动学习 | ✅ 活跃 |
|
||||
| browserHandStore | 浏览器自动化 | ✅ 活跃 |
|
||||
|
||||
**gatewayStore.ts 门面模式:**
|
||||
- 从 1800+ 行缩减到 352 行
|
||||
- 作为向后兼容的 facade 层
|
||||
- 标记为 `@deprecated`,推荐使用领域 Store
|
||||
|
||||
**评价:** ✅ Store 架构已统一,拆分合理
|
||||
|
||||
#### 2.2.3 通信层 (desktop/src/lib/)
|
||||
|
||||
**核心客户端:**
|
||||
|
||||
| 客户端 | 规模 | 职责 |
|
||||
|--------|------|------|
|
||||
| gateway-client.ts | 65KB | WebSocket/REST 通信、认证、心跳 |
|
||||
| intelligence-client.ts | ~15KB | 记忆/心跳/反思/身份统一API |
|
||||
| team-client.ts | ~8KB | Team API REST 客户端 |
|
||||
| browser-client.ts | ~5KB | 浏览器自动化客户端 |
|
||||
| autonomy-manager.ts | ~15KB | L4 分层授权系统 |
|
||||
|
||||
**GatewayClient 核心功能:**
|
||||
- ✅ WebSocket 连接管理(自动重连、心跳)
|
||||
- ✅ REST API 降级(ZCLAW 模式)
|
||||
- ✅ Ed25519 设备认证
|
||||
- ✅ 流式响应处理(chatStream)
|
||||
- ✅ 事件订阅机制
|
||||
|
||||
**问题:**
|
||||
- ⚠️ 文件过大(65KB),职责过重
|
||||
- ⚠️ 部分方法过长(如 handleZCLAWStreamEvent 100+ 行)
|
||||
|
||||
### 2.3 Rust 后端架构分析
|
||||
|
||||
#### 2.3.1 模块组织 (desktop/src-tauri/src/)
|
||||
|
||||
```
|
||||
lib.rs (入口)
|
||||
├── viking_commands.rs # OpenViking CLI sidecar
|
||||
├── viking_server.rs # OpenViking 本地服务器管理
|
||||
├── memory/ # 内存提取和上下文构建
|
||||
│ ├── extractor.rs # LLM 驱动的记忆提取
|
||||
│ ├── context_builder.rs # L0/L1/L2 分层上下文
|
||||
│ └── persistent.rs # SQLite 持久化
|
||||
├── llm/ # LLM 接口(Doubao/OpenAI/Anthropic)
|
||||
├── browser/ # 浏览器自动化(Fantoccini)
|
||||
├── secure_storage.rs # OS Keyring/Keychain
|
||||
├── memory_commands.rs # 持久化内存命令
|
||||
└── intelligence/ # 智能层(已从前端迁移)
|
||||
├── heartbeat.rs # 心跳引擎
|
||||
├── compactor.rs # 上下文压缩
|
||||
├── reflection.rs # 反思引擎
|
||||
└── identity.rs # Agent 身份管理
|
||||
```
|
||||
|
||||
#### 2.3.2 状态管理模式
|
||||
|
||||
**Tauri State 注入:**
|
||||
```rust
|
||||
// 使用 Arc<Mutex<T>> 包装
|
||||
pub struct BrowserState {
|
||||
client: Arc<RwLock<BrowserClient>>,
|
||||
}
|
||||
|
||||
// Tauri 命令中使用 State 管理
|
||||
#[tauri::command]
|
||||
async fn browser_navigate(
|
||||
state: State<'_, BrowserState>,
|
||||
url: String,
|
||||
) -> Result<String, String>
|
||||
```
|
||||
|
||||
**评价:** ✅ 线程安全,模式合理
|
||||
|
||||
#### 2.3.3 SQLite 持久化
|
||||
|
||||
**数据库架构:**
|
||||
```sql
|
||||
CREATE TABLE memories (
|
||||
id TEXT PRIMARY KEY,
|
||||
agent_id TEXT NOT NULL,
|
||||
memory_type TEXT NOT NULL,
|
||||
content TEXT NOT NULL,
|
||||
importance INTEGER DEFAULT 5,
|
||||
source TEXT DEFAULT 'auto',
|
||||
tags TEXT DEFAULT '[]',
|
||||
conversation_id TEXT,
|
||||
created_at TEXT NOT NULL,
|
||||
last_accessed_at TEXT NOT NULL,
|
||||
access_count INTEGER DEFAULT 0,
|
||||
embedding BLOB
|
||||
);
|
||||
-- 索引: agent_id, memory_type, created_at, importance
|
||||
```
|
||||
|
||||
**评价:** ✅ 结构清晰,有索引优化
|
||||
|
||||
#### 2.3.4 安全存储
|
||||
|
||||
**keyring crate 使用:**
|
||||
- Windows: Credential Manager
|
||||
- macOS: Keychain
|
||||
- Linux: libsecret
|
||||
|
||||
**评价:** ✅ 符合安全最佳实践
|
||||
|
||||
---
|
||||
|
||||
## 三、技术栈分析
|
||||
|
||||
### 3.1 框架选型
|
||||
|
||||
| 框架 | 选择 | 评价 |
|
||||
|------|------|------|
|
||||
| 桌面框架 | Tauri 2.0 | ✅ 体积小(~10MB),性能好 |
|
||||
| 前端框架 | React 19 | ✅ 最新特性,但未充分利用 |
|
||||
| 状态管理 | Zustand 5 | ✅ 轻量、类型安全 |
|
||||
| 样式 | TailwindCSS 4 | ✅ 原子化,开发效率高 |
|
||||
| 动画 | Framer Motion | ✅ 声明式动画 |
|
||||
| 桌面封装 | Tauri 2 | ✅ 成熟稳定 |
|
||||
|
||||
### 3.2 依赖管理
|
||||
|
||||
**package.json 关键依赖:**
|
||||
```json
|
||||
{
|
||||
"dependencies": {
|
||||
"@tauri-apps/api": "^2",
|
||||
"react": "^19.1.0",
|
||||
"zustand": "^5.0.11",
|
||||
"framer-motion": "^12.36.0",
|
||||
"lucide-react": "^0.577.0"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Cargo.toml 关键依赖:**
|
||||
```toml
|
||||
[dependencies]
|
||||
tauri = { version = "2", features = [] }
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
sqlx = { version = "0.7", features = ["runtime-tokio", "sqlite"] }
|
||||
fantoccini = "0.21" # Browser automation
|
||||
keyring = "3" # Secure storage
|
||||
```
|
||||
|
||||
**评价:** ✅ 依赖精简,版本稳定
|
||||
|
||||
---
|
||||
|
||||
## 四、业务逻辑分析
|
||||
|
||||
### 4.1 聊天功能实现
|
||||
|
||||
**消息流程:**
|
||||
```
|
||||
用户输入 → sendMessage()
|
||||
→ 上下文压缩检查 (compactor.checkThreshold)
|
||||
→ 记忆增强 (intelligenceClient.memory.search)
|
||||
→ 添加用户消息
|
||||
→ 创建流式占位消息
|
||||
→ gatewayClient.chatStream()
|
||||
→ 收集 tool/hand/workflow 事件
|
||||
→ 流结束 → 提取记忆 (memory-extractor)
|
||||
→ 触发反思 (intelligenceClient.reflection)
|
||||
```
|
||||
|
||||
**评价:** ✅ 流程完整,异常处理充分
|
||||
|
||||
### 4.2 记忆系统实现
|
||||
|
||||
**记忆提取模式:**
|
||||
1. **LLM 提取** - 使用 `llmExtract()` 语义提取
|
||||
2. **规则提取** - 正则匹配模式
|
||||
|
||||
**记忆分类:**
|
||||
- fact: 用户事实
|
||||
- preference: 用户偏好
|
||||
- lesson: 经验教训
|
||||
- context: 上下文
|
||||
- task: 任务
|
||||
|
||||
**分层上下文加载(L0/L1/L2):**
|
||||
```
|
||||
L0 (Quick Scan): 向量相似度搜索,返回概览
|
||||
L1 (Standard): 加载 top 候选的 overview
|
||||
L2 (Deep): 加载最相关项的完整内容
|
||||
```
|
||||
|
||||
**评价:** ✅ 设计完善,已迁移到 Rust 后端
|
||||
|
||||
### 4.3 自主能力系统
|
||||
|
||||
**L4 分层授权:**
|
||||
|
||||
| 级别 | 自动内存保存 | 自动压缩 | 自动反思 |
|
||||
|------|-------------|---------|---------|
|
||||
| supervised | ❌ | ❌ | ❌ |
|
||||
| assisted | ✅ | ✅ | ✅ |
|
||||
| autonomous | ✅ | ✅ | ✅ |
|
||||
|
||||
**风险评估:**
|
||||
- ACTION_RISK_MAP 定义每种操作的风险等级
|
||||
- importanceMax + riskMax 双重判断
|
||||
- 所有操作记录审计日志
|
||||
|
||||
**评价:** ✅ 授权机制完善
|
||||
|
||||
---
|
||||
|
||||
## 五、数据流与接口分析
|
||||
|
||||
### 5.1 整体数据流
|
||||
|
||||
```
|
||||
用户操作 → React UI → Zustand Store → GatewayClient
|
||||
↓
|
||||
WebSocket / REST
|
||||
↓
|
||||
ZCLAW Kernel
|
||||
↓
|
||||
Skills / Hands 执行
|
||||
```
|
||||
|
||||
### 5.2 Gateway Protocol v3
|
||||
|
||||
**消息类型:**
|
||||
- req/res: 请求/响应模式
|
||||
- event: 事件推送
|
||||
- stream: 流式响应
|
||||
|
||||
**认证:** Ed25519 签名
|
||||
|
||||
### 5.3 Tauri Commands
|
||||
|
||||
**70+ Commands 分类:**
|
||||
|
||||
| 类别 | 命令数 | 示例 |
|
||||
|------|--------|------|
|
||||
| Browser | 18 | browser_navigate, browser_click, browser_screenshot |
|
||||
| Memory | 12 | memory_store, memory_search, memory_stats |
|
||||
| Intelligence | 15 | heartbeat_*, reflection_*, identity_* |
|
||||
| Viking | 9 | viking_status, viking_find, viking_read |
|
||||
| Gateway | 8 | gateway_start, gateway_stop, gateway_status |
|
||||
| LLM | 3 | llm_complete |
|
||||
|
||||
**评价:** ✅ 接口粒度合理,类型安全
|
||||
|
||||
---
|
||||
|
||||
## 六、性能与安全分析
|
||||
|
||||
### 6.1 性能分析
|
||||
|
||||
#### 6.1.1 渲染性能
|
||||
|
||||
**虚拟滚动:** 已使用 react-window
|
||||
|
||||
**潜在问题:**
|
||||
- ⚠️ 大量消息时可能 re-render
|
||||
- ⚠️ 某些 Store selector 未优化
|
||||
|
||||
#### 6.1.2 网络性能
|
||||
|
||||
**WebSocket 心跳:**
|
||||
- 间隔:30 秒
|
||||
- 超时:10 秒
|
||||
- 最大丢失:3 次
|
||||
|
||||
**问题:**
|
||||
- ⚠️ 单 WebSocket 连接,复用机制可优化
|
||||
|
||||
#### 6.1.3 计算性能
|
||||
|
||||
**Token 估算:**
|
||||
```rust
|
||||
// CJK: ~1.5 tokens/字符
|
||||
// ASCII: ~0.3 tokens/字符
|
||||
```
|
||||
|
||||
**评价:** ✅ 算法合理
|
||||
|
||||
### 6.2 安全分析
|
||||
|
||||
#### 6.2.1 认证机制
|
||||
|
||||
**Ed25519 设备认证:** ✅ 安全
|
||||
|
||||
#### 6.2.2 敏感数据
|
||||
|
||||
**存储:**
|
||||
- API Key: OS Keyring ✅
|
||||
- Token: OS Keyring ✅
|
||||
- Theme: localStorage ⚠️
|
||||
|
||||
**问题:**
|
||||
- ⚠️ localStorage 仍用于部分前端配置
|
||||
- ⚠️ 日志可能包含敏感信息
|
||||
|
||||
#### 6.2.3 输入验证
|
||||
|
||||
**SQL 注入:** ✅ 使用参数化查询
|
||||
**XSS:** ⚠️ 需要确认输出转义
|
||||
|
||||
---
|
||||
|
||||
## 七、测试覆盖分析
|
||||
|
||||
### 7.1 测试文件分布
|
||||
|
||||
| 测试文件 | 覆盖范围 |
|
||||
|----------|----------|
|
||||
| autonomy-manager.test.ts | L4 授权逻辑 |
|
||||
| agent-memory.test.ts | 记忆系统 |
|
||||
| context-compactor.test.ts | 上下文压缩 |
|
||||
| heartbeat-reflection.test.ts | 心跳和反思 |
|
||||
| gatewayStore.test.ts | Store 状态 |
|
||||
| chatStore.test.ts | 聊天逻辑 |
|
||||
| teamStore.test.ts | 团队协作 |
|
||||
| browserHandStore.test.ts | 浏览器手 |
|
||||
| ws-client.test.ts | WebSocket 客户端 |
|
||||
|
||||
**评价:** ✅ 核心逻辑有覆盖,但可增加更多边界测试
|
||||
|
||||
### 7.2 E2E 测试
|
||||
|
||||
**Playwright 配置:** ✅ 已配置 chromium/chromium-headed
|
||||
|
||||
---
|
||||
|
||||
## 八、代码质量分析
|
||||
|
||||
### 8.1 大型文件
|
||||
|
||||
| 文件 | 规模 | 问题 |
|
||||
|------|------|------|
|
||||
| gateway-client.ts | 65KB | 职责过重 |
|
||||
| gatewayStore.ts | 352行 | 已是 facade,仍偏大 |
|
||||
|
||||
### 8.2 技术债务
|
||||
|
||||
**TODO/FIXME:**
|
||||
- intelligence/mod.rs: Phase 3 迁移中
|
||||
- viking_commands.rs: 平台二进制解析
|
||||
|
||||
**Rust unsafe:**
|
||||
- context_builder.rs: 多处 unwrap()
|
||||
|
||||
### 8.3 localStorage 使用
|
||||
|
||||
**仍在使用 localStorage 的模块:**
|
||||
- intelligence-client.ts: 降级模式
|
||||
- skill-discovery.ts: 技能索引缓存
|
||||
- agent-swarm.ts: 蜂群历史
|
||||
- gateway-api.ts: 主题等配置
|
||||
|
||||
---
|
||||
|
||||
## 九、分析维度评分
|
||||
|
||||
| # | 维度 | 评分 | 主要发现 |
|
||||
|---|------|------|----------|
|
||||
| 1 | 代码结构 | 4/5 | 组件划分清晰,文件组织合理 |
|
||||
| 2 | 架构设计 | 4/5 | 分层清晰,模块职责明确 |
|
||||
| 3 | 技术选型 | 4/5 | 框架选择合理,依赖精简 |
|
||||
| 4 | 业务实现 | 4/5 | 核心流程完整,异常处理充分 |
|
||||
| 5 | 数据流设计 | 4/5 | 流向清晰,同步机制完善 |
|
||||
| 6 | 接口设计 | 4/5 | Tauri Commands 粒度合理 |
|
||||
| 7 | 性能表现 | 3/5 | 存在优化空间(re-render、WebSocket) |
|
||||
| 8 | 安全合规 | 4/5 | 认证机制完善,部分数据需加强 |
|
||||
| 9 | 测试覆盖 | 3/5 | 核心逻辑有覆盖,边界测试不足 |
|
||||
| 10 | 文档质量 | 4/5 | 文档详尽,部分需更新 |
|
||||
| 11 | 可维护性 | 4/5 | 架构清晰,部分大文件需重构 |
|
||||
| 12 | 可扩展性 | 4/5 | Plugin 机制、Skills 系统完善 |
|
||||
|
||||
**综合评分:3.8 / 5.0**
|
||||
|
||||
---
|
||||
|
||||
## 十、关键问题清单
|
||||
|
||||
### 🔴 P0 - 需立即处理
|
||||
|
||||
1. **gateway-client.ts 过大** (65KB)
|
||||
- 建议:拆分为 gateway-core.ts, gateway-ws.ts, gateway-rest.ts
|
||||
|
||||
2. **localStorage 降级风险**
|
||||
- intelligence-client.ts 在非 Tauri 环境使用 localStorage
|
||||
- 建议:统一使用 Rust 后端,移除 localStorage 降级
|
||||
|
||||
### 🟡 P1 - 应尽快处理
|
||||
|
||||
3. **Rust unwrap() 风险**
|
||||
- context_builder.rs 多处 unsafe unwrap
|
||||
- 建议:使用 expect() 并添加错误信息
|
||||
|
||||
4. **测试覆盖不足**
|
||||
- E2E 测试不稳定
|
||||
- 建议:增加边界测试,提高测试稳定性
|
||||
|
||||
### 🟢 P2 - 计划处理
|
||||
|
||||
5. **Store selector 优化**
|
||||
- 避免不必要的 re-render
|
||||
- 建议:使用 Zustand 的 shallow 比较
|
||||
|
||||
6. **WebSocket 连接池化**
|
||||
- 当前单连接,可考虑连接池
|
||||
- 建议:评估性能瓶颈后优化
|
||||
|
||||
---
|
||||
|
||||
## 十一、头脑风暴议题
|
||||
|
||||
详见 `BRAINSTORMING-SESSION.md`
|
||||
|
||||
---
|
||||
|
||||
## 十二、附录
|
||||
|
||||
### A. 关键文件索引
|
||||
|
||||
| 文件 | 位置 | 说明 |
|
||||
|------|------|------|
|
||||
| CLAUDE.md | 根目录 | 项目规范文档 |
|
||||
| gateway-client.ts | desktop/src/lib/ | 核心通信客户端 |
|
||||
| intelligence-client.ts | desktop/src/lib/ | 智能层统一 API |
|
||||
| chatStore.ts | desktop/src/store/ | 聊天状态管理 |
|
||||
| lib.rs | desktop/src-tauri/src/ | Rust 后端入口 |
|
||||
| intelligence/ | desktop/src-tauri/src/ | 智能层 Rust 实现 |
|
||||
| memory/ | desktop/src-tauri/src/ | 内存持久化 |
|
||||
|
||||
### B. 参考文档
|
||||
|
||||
- docs/analysis/ZCLAW-DEEP-ANALYSIS.md (2026-03-20)
|
||||
- docs/features/00-architecture/
|
||||
- docs/plans/INTELLIGENCE-LAYER-MIGRATION.md
|
||||
345
docs/archive/old-analysis/ZCLAW-DEEP-ANALYSIS.md
Normal file
@@ -0,0 +1,345 @@
|
||||
# ZCLAW 项目深度梳理分析与头脑风暴
|
||||
|
||||
> 分析日期:2026-03-20
|
||||
|
||||
## 一、项目全景概览
|
||||
|
||||
ZCLAW 是一个基于 ZCLAW (类 ZCLAW) 定制化的中文优先 AI Agent 桌面客户端,采用 Tauri 2.0 (Rust + React 19) 架构,目标对标智谱 AutoClaw 和腾讯 QClaw。
|
||||
|
||||
### 1.1 技术栈全景
|
||||
|
||||
| 层级 | 技术选型 | 成熟度 |
|
||||
|------|----------|--------|
|
||||
| 桌面框架 | Tauri 2.0 (Rust + React 19) | ✅ 合理 |
|
||||
| 前端 | React 19 + TailwindCSS + Zustand + Framer Motion + Lucide | ✅ 现代 |
|
||||
| 后端通信 | WebSocket (Gateway Protocol v3) + Tauri Commands | ✅ 完整 |
|
||||
| 状态管理 | Zustand (13 个 Store 文件) + Composite Store | ⚠️ 过度拆分 |
|
||||
| 配置格式 | TOML (替代 JSON) | ✅ 用户友好 |
|
||||
| 测试 | Vitest + jsdom (317 tests) | ✅ 覆盖良好 |
|
||||
| 依赖 | 极精简 (ws + zod) | ✅ 轻量 |
|
||||
|
||||
### 1.2 规模数据
|
||||
|
||||
| 维度 | 数量 |
|
||||
|------|------|
|
||||
| 前端组件 | 50+ .tsx 文件 (88 个 components 目录项) |
|
||||
| Lib 工具 | 42 个 lib 文件 (~65KB gateway-client 最大) |
|
||||
| Store 文件 | 13 个 (gatewayStore 59KB 为最大单文件) |
|
||||
| 类型定义 | 13 个类型文件 |
|
||||
| Skills | 68 个 SKILL.md 技能定义 |
|
||||
| Hands | 7 个 HAND.toml 能力包 |
|
||||
| Plugins | 3 个 (chinese-models, feishu, ui) |
|
||||
| 测试 | 15 个测试文件, 317 tests |
|
||||
| 文档 | 84 个 docs 目录项 |
|
||||
|
||||
---
|
||||
|
||||
## 二、架构深度分析
|
||||
|
||||
### 2.1 数据流架构
|
||||
|
||||
```
|
||||
用户操作 → React UI → Zustand Store → GatewayClient (WS) → ZCLAW Kernel
|
||||
↘ TauriGateway (IPC) → Rust Backend
|
||||
↘ VikingClient → OpenViking (向量DB)
|
||||
```
|
||||
|
||||
**优点:**
|
||||
- 清晰的分层设计,UI/Store/Client 职责明确
|
||||
- 统一的 Gateway Client 抽象层,禁止组件内直接创建 WS
|
||||
|
||||
**问题:**
|
||||
- gatewayStore.ts 59KB,是一个巨型 God Store,虽然已拆分出 connectionStore/agentStore/handStore 等,但旧的 gatewayStore 仍保留且被 App.tsx 直接引用
|
||||
- Store Coordinator (store/index.ts) 的 useCompositeStore 订阅了所有 store 的几乎全部状态,会导致任何状态变化触发全量 re-render
|
||||
|
||||
### 2.2 通信层分析
|
||||
|
||||
**Node.js 端 (src/gateway/):**
|
||||
- manager.ts — 子进程管理,有自动重启、健康检查,设计完整
|
||||
- ws-client.ts — 完整的 Protocol v3 握手、请求/响应、事件订阅、自动重连
|
||||
|
||||
**浏览器端 (desktop/src/lib/gateway-client.ts):**
|
||||
- 65KB 的单文件,职责过重,包含了连接管理、RPC 调用、事件监听、所有业务方法
|
||||
|
||||
### 2.3 智能层分析
|
||||
|
||||
这是 ZCLAW 最有价值的差异化层:
|
||||
|
||||
| 模块 | 文件 | 测试 | 集成 |
|
||||
|------|------|------|------|
|
||||
| Agent 记忆 | agent-memory.ts (14KB) | 42 tests | ✅ MemoryPanel |
|
||||
| 身份演化 | agent-identity.ts (10KB) | ✅ | ❓ 后端 |
|
||||
| 上下文压缩 | context-compactor.ts (14KB) | 23 tests | ✅ chatStore |
|
||||
| 自我反思 | reflection-engine.ts (21KB) | 28 tests | ✅ ReflectionLog |
|
||||
| 心跳引擎 | heartbeat-engine.ts (10KB) | ✅ | ❓ 未验证 |
|
||||
| 自主授权 | autonomy-manager.ts (15KB) | ✅ | ✅ AutonomyConfig |
|
||||
| 主动学习 | active-learning.ts (10KB) | ✅ | ✅ ActiveLearningPanel |
|
||||
| Agent 蜂群 | agent-swarm.ts (16KB) | 43 tests | ✅ SwarmDashboard |
|
||||
| 向量记忆 | vector-memory.ts (11KB) | 10 tests | ❌ 未集成到 UI |
|
||||
|
||||
### 2.4 前端组件分析
|
||||
|
||||
**已集成且工作正常:**
|
||||
ChatArea, RightPanel (多 tab), Sidebar, Settings (10 页), HandsPanel, HandApprovalModal, SwarmDashboard, TeamCollaborationView, SkillMarket, AgentOnboardingWizard, AutomationPanel
|
||||
|
||||
**存在但集成度低:**
|
||||
HeartbeatConfig, CreateTriggerModal, PersonalitySelector, ScenarioTags, DevQALoop
|
||||
|
||||
---
|
||||
|
||||
## 三、SWOT 分析
|
||||
|
||||
### 💪 优势 (Strengths)
|
||||
|
||||
1. **技术栈先进** — Tauri 2.0 比 Electron 体积小 10x+,性能好
|
||||
2. **智能层设计深刻** — 记忆系统、身份演化、自我反思、上下文压缩是真正的差异化能力
|
||||
3. **Skills 生态丰富** — 68 个 Skill 覆盖写作、数据分析、社媒运营、前端开发等
|
||||
4. **Hands 系统完整** — 7 个能力包 + 审批/触发/审计全链路
|
||||
5. **中文优先** — 中文模型 Provider (GLM/Qwen/Kimi/MiniMax) + 飞书集成
|
||||
6. **测试覆盖好** — 317 tests, 涵盖核心 lib 和 store
|
||||
7. **文档极其详尽** — 84 个文档文件,有架构图、偏离分析、审计报告、知识库
|
||||
|
||||
### 🔴 劣势 (Weaknesses)
|
||||
|
||||
1. **代码膨胀严重**
|
||||
- gatewayStore.ts 59KB, gateway-client.ts 65KB — 单文件过大
|
||||
- 42 个 lib 文件,部分职责重叠 (viking-*.ts 有 5 个文件)
|
||||
- 88 个 components,复杂度管理困难
|
||||
|
||||
2. **v1→v2 架构迁移未彻底**
|
||||
- src/core/ 归档代码仍保留,v1 的 multi-agent/memory/proactive 与 v2 的 desktop/src/lib 存在概念重叠
|
||||
- 新旧 store 并存 (gatewayStore vs connectionStore/agentStore/...)
|
||||
|
||||
3. **前后端耦合不清晰**
|
||||
- 大量智能逻辑 (记忆、反思、压缩) 在前端 lib 中实现
|
||||
- 这些应该是后端/Gateway 的职责,放在前端会导致:数据不持久、多端不同步、逻辑重复
|
||||
|
||||
4. **真实集成测试缺失**
|
||||
- PROGRESS.md 中 Phase 4 "真实集成测试"全部未完成
|
||||
- 没有端到端测试验证 Gateway 连接→消息收发→模型调用
|
||||
|
||||
5. **~~Tauri Rust 后端基本空白~~** → ✅ **已实现 85-90%**(更新 2026-03-20)
|
||||
|
||||
**已实现的 Tauri Commands:**
|
||||
- ZCLAW Gateway 管理(start/stop/restart/status/doctor)
|
||||
- OpenViking 记忆系统(CLI sidecar + 本地服务器)
|
||||
- 浏览器自动化(Fantoccini WebDriver)
|
||||
- 安全存储(OS Keyring/Keychain)
|
||||
- LLM 集成(Doubao/OpenAI/Anthropic)
|
||||
- 记忆提取和上下文构建
|
||||
- 进程健康检查(`zclaw_health_check`)
|
||||
|
||||
6. **配置系统双重标准**
|
||||
- config.toml + chinese-providers.toml 是 TOML 格式
|
||||
- 但 README 提到 zclaw.default.json,plugins 使用 plugin.json
|
||||
- 配置格式不统一
|
||||
|
||||
### 🟡 机会 (Opportunities)
|
||||
|
||||
1. **中国 AI Agent 市场爆发** — 智谱/通义/月之暗面/DeepSeek 的中文模型生态成熟
|
||||
2. **本地优先隐私诉求增长** — 企业和个人对数据隐私要求越来越高
|
||||
3. **ZCLAW 生态缺口** — 市场上没有优质的中文定制化 ZCLAW 桌面客户端
|
||||
4. **飞书+企业微信整合** — 企业 IM 集成是刚需,特别是在中国市场
|
||||
5. **Skill 市场变现** — 74 个 Skills 可以发展成社区市场
|
||||
|
||||
### 🔵 威胁 (Threats)
|
||||
|
||||
1. **竞品迭代极快** — Cursor/Windsurf/AutoClaw/QClaw 都在快速迭代
|
||||
2. **ZCLAW 上游变化** — Gateway Protocol 版本升级可能导致兼容性问题
|
||||
3. **LLM API 不稳定** — 中国模型厂商的 API 变更频繁
|
||||
4. **单人/小团队维护压力** — 50+ 组件、42 个 lib、13 个 store 的维护成本极高
|
||||
|
||||
---
|
||||
|
||||
## 四、关键问题深度诊断
|
||||
|
||||
### 4.1 🔴 最大风险:前端承担了后端职责
|
||||
|
||||
目前 desktop/src/lib/ 下有大量本应属于后端的逻辑:
|
||||
|
||||
```
|
||||
agent-memory.ts → 应在 Gateway/Rust 端
|
||||
agent-identity.ts → 应在 Gateway/Rust 端
|
||||
reflection-engine.ts → 应在 Gateway/Rust 端
|
||||
heartbeat-engine.ts → 应在 Gateway/Rust 端
|
||||
context-compactor.ts → 应在 Gateway/Rust 端
|
||||
agent-swarm.ts → 应在 Gateway/Rust 端
|
||||
vector-memory.ts → 应在 Gateway/Rust 端
|
||||
```
|
||||
|
||||
**后果:**
|
||||
- 关闭浏览器/桌面端后,心跳、反思、主动学习全部停止
|
||||
- 数据持久化依赖 localStorage,不可靠
|
||||
- 无法多端共享 Agent 状态
|
||||
|
||||
### 4.2 ✅ Store 架构已统一(已更新 2026-03-20)
|
||||
|
||||
**Store 迁移已完成:**
|
||||
|
||||
| 领域 Store | 职责 | 状态 |
|
||||
|------------|------|------|
|
||||
| connectionStore.ts | Gateway 连接状态 | ✅ 活跃 |
|
||||
| agentStore.ts | Agent/Clone 管理 | ✅ 活跃 |
|
||||
| handStore.ts | Hands 和触发器 | ✅ 活跃 |
|
||||
| workflowStore.ts | 工作流 | ✅ 活跃 |
|
||||
| configStore.ts | 配置管理 | ✅ 活跃 |
|
||||
| securityStore.ts | 安全状态 | ✅ 活跃 |
|
||||
| sessionStore.ts | 会话管理 | ✅ 活跃 |
|
||||
| chatStore.ts | 聊天消息 | ✅ 活跃 |
|
||||
| teamStore.ts | 团队协作 | ✅ 活跃 |
|
||||
| skillMarketStore.ts | 技能市场 | ✅ 活跃 |
|
||||
| memoryGraphStore.ts | 记忆图谱 | ✅ 活跃 |
|
||||
| activeLearningStore.ts | 主动学习 | ✅ 活跃 |
|
||||
| browserHandStore.ts | 浏览器自动化 | ✅ 活跃 |
|
||||
|
||||
**gatewayStore.ts 现状:**
|
||||
- 从 1800+ 行缩减到 352 行
|
||||
- 作为向后兼容的 facade 层
|
||||
- 标记为 `@deprecated`,新组件应使用领域 Store
|
||||
|
||||
**useCompositeStore 已删除**(是死代码)
|
||||
|
||||
### 4.3 ✅ 文档 vs 现实的差距(已更新 2026-03-20)
|
||||
|
||||
**经核实,组件集成状态比原文档描述的更好:**
|
||||
|
||||
| 组件 | 原文档标记 | 实际状态 | 集成路径 |
|
||||
|------|------------|----------|----------|
|
||||
| PersonalitySelector | ❓ 未验证 | ✅ 已集成 | AgentOnboardingWizard |
|
||||
| ScenarioTags | ❓ 未验证 | ✅ 已集成 | AgentOnboardingWizard |
|
||||
| HeartbeatConfig | ❓ 未验证 | ✅ 已集成 | SettingsLayout |
|
||||
| CreateTriggerModal | ❓ 未验证 | ✅ 已集成 | useHandStore |
|
||||
| DevQALoop | ❓ 未验证 | ✅ 已集成 | TeamOrchestrator (新增) |
|
||||
|
||||
**详细分析见:** `docs/analysis/COMPONENT-INTEGRATION-STATUS.md`
|
||||
|
||||
---
|
||||
|
||||
## 五、头脑风暴:未来方向
|
||||
|
||||
### 💡 方向一:架构收敛 — "做减法"(推荐优先级 P0)
|
||||
|
||||
**核心思想:** 项目已经膨胀过快,在增加新功能前应先收敛。
|
||||
|
||||
| 行动 | 效果 | 工作量 |
|
||||
|------|------|--------|
|
||||
| 将智能层 lib 迁移到 Tauri Rust 端或 Gateway 插件 | 后端持久运行,多端共享 | 大 |
|
||||
| 彻底删除旧 gatewayStore.ts,统一用拆分后的 stores | 消除重复、降低 re-render | 中 |
|
||||
| 合并 viking-*.ts (5 文件 → 1-2 文件) | 降低复杂度 | 小 |
|
||||
| 拆分 gateway-client.ts (65KB → 模块化) | 可维护性提升 | 中 |
|
||||
| 统一配置格式 (TOML 或 JSON,不混用) | 用户体验统一 | 小 |
|
||||
|
||||
### 💡 方向二:端到端可用性 — "跑通闭环"(推荐优先级 P0)
|
||||
|
||||
**核心思想:** 317 个单元测试通过不代表产品可用,需要真实跑通。
|
||||
|
||||
| 行动 | 验证点 |
|
||||
|------|--------|
|
||||
| 安装 ZCLAW,验证 Gateway 连接 | 子进程启动 → WS 握手 → 心跳 |
|
||||
| 配置中文模型 API Key,测试对话 | 流式响应 → 模型切换 → 上下文管理 |
|
||||
| 测试飞书 Channel 收发消息 | OAuth → 消息接收 → Agent 处理 → 回复 |
|
||||
| 测试 Hands 触发完整流程 | 意图识别 → 参数收集 → 审批 → 执行 → 结果 |
|
||||
| 验证记忆持久化 | 重启后记忆保留 → 跨会话记忆命中 |
|
||||
|
||||
### 💡 方向三:Tauri Rust 后端落地 — "真正的桌面应用"
|
||||
|
||||
**现状:** desktop/src-tauri/ 基本空白,大量能力应由 Rust 端承担。
|
||||
|
||||
**设想:**
|
||||
```rust
|
||||
// Tauri Commands 愿景
|
||||
#[tauri::command]
|
||||
async fn start_gateway(config: GatewayConfig) -> Result<GatewayStatus>
|
||||
#[tauri::command]
|
||||
async fn memory_search(query: String) -> Result<Vec<MemoryEntry>>
|
||||
#[tauri::command]
|
||||
async fn heartbeat_tick() -> Result<HeartbeatResult>
|
||||
#[tauri::command]
|
||||
async fn secure_store_get(key: String) -> Result<String>
|
||||
```
|
||||
|
||||
**好处:**
|
||||
- Gateway 生命周期由 Rust 管理,稳定性↑
|
||||
- 记忆/反思/心跳在 Rust 后台持续运行
|
||||
- 安全存储用系统 Keychain,不再依赖 localStorage
|
||||
- 离线能力:Rust 端可以在无网络时缓存操作
|
||||
|
||||
### 💡 方向四:差异化功能深化 — "不做小 ChatGPT"
|
||||
|
||||
ZCLAW 不应与 ChatGPT/Claude Desktop 竞争"对话体验",而应聚焦:
|
||||
|
||||
| 差异化方向 | 竞品不具备 | 实现路径 |
|
||||
|------------|------------|----------|
|
||||
| "AI 分身"日常代理 | AutoClaw 有但不开放 | Clone 系统 + 飞书/微信 Channel → 让 AI 分身帮你回消息、整理日程 |
|
||||
| "本地知识库" Agent | ChatGPT/Claude 是云端 | 向量记忆 + 本地文件索引 → 跨项目知识积累 |
|
||||
| "自主工作流"引擎 | Cursor 只做代码辅助 | Hands + Scheduler + Workflow → 定时任务自动执行(如每日新闻摘要、竞品监控) |
|
||||
| "团队蜂群"协作 | 市场上极少 | SwarmDashboard 已有基础 → 多 Agent 分工合作解决复杂问题 |
|
||||
| "中文场景" Skills | 国际产品不覆盖 | 小红书运营、知乎策略、微信公众号、飞书文档操作 → 已有 Skill 定义 |
|
||||
|
||||
### 💡 方向五:开发者体验 (DX) 优化
|
||||
|
||||
| 改进 | 现状 | 目标 |
|
||||
|------|------|------|
|
||||
| 启动脚本 | 需要 start-all.ps1 + 多步操作 | pnpm dev 一键启动全栈 |
|
||||
| 热重载 | Vite HMR 可用 | 加上 Gateway 插件热重载 |
|
||||
| 类型安全 | 部分 any | 全量 strict TypeScript |
|
||||
| E2E 测试 | 无 | Playwright + Tauri driver |
|
||||
| CI/CD | 无 | GitHub Actions 自动测试+构建 |
|
||||
|
||||
### 💡 方向六:商业化路径探索
|
||||
|
||||
基于现有能力的最短变现路径:
|
||||
|
||||
```
|
||||
阶段 1 (Q2): "个人 AI 助手" — 免费开源
|
||||
→ 建立 GitHub 社区 → 收集种子用户反馈
|
||||
→ 核心卖点: 本地优先 + 中文模型 + 飞书集成
|
||||
|
||||
阶段 2 (Q3): "Pro 版" — 订阅制 ¥49/月
|
||||
→ 云端记忆同步
|
||||
→ 高级 Skills (如量化交易分析、SEO 自动优化)
|
||||
→ 优先技术支持
|
||||
|
||||
阶段 3 (Q4): "团队版" — ¥199/人/月
|
||||
→ 多 Agent 协作编排
|
||||
→ 企业级审计日志
|
||||
→ 私有部署选项
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 六、行动建议总结
|
||||
|
||||
### ✅ 已完成 (截至 2026-03-20)
|
||||
|
||||
1. **~~Store 架构统一~~** — gatewayStore 已拆分,useCompositeStore 已删除
|
||||
2. **~~gateway-client 模块化~~** — 已拆分为 api/auth/storage/types 4 模块
|
||||
3. **~~viking-*.ts 清理~~** — 已归档到 docs/archive/v1-viking-dead-code/
|
||||
4. **~~E2E 测试框架~~** — Playwright 已配置,74+ 测试用例
|
||||
5. **~~Skill Market MVP~~** — UI + Store + 发现引擎都已实现
|
||||
6. **~~DevQALoop 集成~~** — 已添加到 TeamOrchestrator
|
||||
7. **~~组件集成状态核实~~** — 大部分组件已通过间接路径集成
|
||||
|
||||
### 🔥 立即要做 (本周)
|
||||
|
||||
1. **跑通真实集成测试** — 使用 INTEGRATION-CHECKLIST.md 逐项验证
|
||||
2. **配置验证工具** — 运行 `npx ts-node scripts/validate-config.ts`
|
||||
|
||||
### 📌 短期 (2 周)
|
||||
|
||||
1. **完成真实 Gateway 连接测试** — 连接 ZCLAW Kernel
|
||||
2. **中文模型 API 测试** — 验证流式响应
|
||||
3. **飞书集成测试** — OAuth 和消息收发
|
||||
|
||||
### 🎯 中期 (1-2 月)
|
||||
|
||||
1. **智能层迁移评估** — 评估哪些模块必须迁移到后端
|
||||
2. **向量记忆 UI 集成** — Viking 已有代码,需要 UI 入口
|
||||
|
||||
---
|
||||
|
||||
## 核心判断
|
||||
|
||||
ZCLAW 的设计远大于实现。智能层的 lib 代码、68 个 Skills、7 个 Hands 的架构设计都非常出色,但最大的短板是**端到端可用性未经验证**。
|
||||
|
||||
**建议的策略是:先收敛、跑通闭环、再扩展。**
|
||||
187
docs/archive/old-analysis/analysis-2026-03-31-future-work.md
Normal file
@@ -0,0 +1,187 @@
|
||||
# ZCLAW 后续工作分析
|
||||
|
||||
> **生成日期**: 2026-03-31
|
||||
> **基于**: 系统评估报告 + 设计规格差异分析 + TODO扫描 + 测试/部署审计
|
||||
|
||||
---
|
||||
|
||||
## 当前状态概览
|
||||
|
||||
| 维度 | 评分 | 说明 |
|
||||
|------|------|------|
|
||||
| 功能完成度 | 87% | 核心功能完整,SaaS 定位设计 12/12 项全部实现 |
|
||||
| 代码质量 | B+ | 全库仅 1 个 TODO,无 FIXME/HACK,TypeScript 严格模式 |
|
||||
| 后端测试 | 34% | Rust 257 个测试 + 12 个集成测试,覆盖可接受 |
|
||||
| 前端测试 | ~15% | Desktop 34 个测试文件,Admin V2 零测试 |
|
||||
| 部署就绪 | 40% | docker-compose 存在但缺 Dockerfile,无生产部署指南 |
|
||||
| 文档完整性 | 50% | 架构/知识库丰富,缺 API 文档和部署指南 |
|
||||
|
||||
---
|
||||
|
||||
## 一、P0 — 必须完成 (阻塞上线)
|
||||
|
||||
### 1.1 SaaS 生产部署基础设施
|
||||
|
||||
**问题**: `docker-compose.yml` 引用的 Dockerfile 和 `saas-env.example` 不存在,无法容器化部署。
|
||||
|
||||
| 工作项 | 说明 | 工作量 |
|
||||
|--------|------|--------|
|
||||
| 创建 `Dockerfile` | 多阶段构建: builder (cargo build --release) + runtime (debian-slim) | 2h |
|
||||
| 创建 `saas-env.example` | 所有必需环境变量模板 + 中文注释 | 1h |
|
||||
| Nginx/Caddy 反向代理配置 | HTTPS 终止 + WebSocket 代理 + 限流 | 2h |
|
||||
| 生产部署指南 | `docs/deployment/saas-production.md` | 2h |
|
||||
| 健康检查端点放开 | `/api/health` 当前需认证,生产环境应公开 | 0.5h |
|
||||
|
||||
### 1.2 Admin V2 基础测试
|
||||
|
||||
**问题**: Admin V2 的 33 个源文件零测试覆盖,无测试框架。
|
||||
|
||||
| 工作项 | 说明 | 工作量 |
|
||||
|--------|------|--------|
|
||||
| 配置 Vitest + React Testing Library | `admin-v2/vitest.config.ts` + 依赖安装 | 1h |
|
||||
| request.ts 拦截器测试 | Token 刷新竞态、网络错误包装、401 处理 | 2h |
|
||||
| 核心页面冒烟测试 | Accounts/Providers/AgentTemplates 渲染测试 | 3h |
|
||||
| authStore 测试 | 登录/登出/Token 刷新状态管理 | 2h |
|
||||
|
||||
---
|
||||
|
||||
## 二、P1 — 功能补全 (近期迭代)
|
||||
|
||||
### 2.1 设计规格遗留项
|
||||
|
||||
| 工作项 | 当前状态 | 说明 | 工作量 |
|
||||
|--------|---------|------|--------|
|
||||
| Admin AgentTemplates 表单: `scenarios` 输入 | 缺失 | 创建表单没有 scenarios 多选 Tag 输入 | 1h |
|
||||
| Admin AgentTemplates 表单: `quick_commands` 编辑器 | 缺失 | 需 Form.List 动态编辑 `[{label, prompt}]` | 2h |
|
||||
| Key Pool 同优先级 LRU 排序 | 缺失 | `select_best_key()` 仅按 priority 排序,同优先级无负载分散 | 2h |
|
||||
| `quota_reset_interval` 字段 | 死代码 | provider_keys 表有此字段但无重置逻辑,需决定实现或移除 | 1h |
|
||||
|
||||
### 2.2 Desktop 遗留 TS 错误修复
|
||||
|
||||
| 文件 | 问题 | 工作量 |
|
||||
|------|------|--------|
|
||||
| `desktop/src/lib/llm-service.ts` | 之前重构引入的语法错误 (已修复) | Done |
|
||||
| `desktop/src/lib/gateway-api.ts` | 评估显示无错误,需验证是否为旧版本问题 | 0.5h |
|
||||
| `desktop/src/lib/kernel-hands.ts` | 同上 | 0.5h |
|
||||
|
||||
### 2.3 Pipeline `started_at` 时间戳修复
|
||||
|
||||
| 文件 | 问题 | 工作量 |
|
||||
|------|------|--------|
|
||||
| `desktop/src-tauri/src/pipeline_commands/discovery.rs:214` | `started_at` 使用 `Utc::now()` 而非实际启动时间 | 1h |
|
||||
|
||||
### 2.4 Admin V2 表格增强
|
||||
|
||||
| 工作项 | 说明 | 工作量 |
|
||||
|--------|------|--------|
|
||||
| 搜索/筛选功能 | Accounts/Models/Providers/ApiKeys/Prompts 表格无搜索 | 4h |
|
||||
| 分页状态管理 | 大部分表格不同步本地分页状态 | 2h |
|
||||
| Config 页编辑体验 | 内联编辑缺加载指示器和 hover 视觉反馈 | 1h |
|
||||
|
||||
---
|
||||
|
||||
## 三、P2 — 质量提升 (中期优化)
|
||||
|
||||
### 3.1 API 文档
|
||||
|
||||
| 工作项 | 说明 | 工作量 |
|
||||
|--------|------|--------|
|
||||
| OpenAPI/Swagger 规范 | 69 个端点需要正式 API 文档,可从 Axum handler 自动生成 | 4h |
|
||||
| API Reference 页面 | 可集成到 Admin V2 或独立 docs 站点 | 2h |
|
||||
|
||||
### 3.2 Desktop 测试提升
|
||||
|
||||
| 工作项 | 当前 | 目标 | 工作量 |
|
||||
|--------|------|------|--------|
|
||||
| Store 单元测试 | ~15% | 60% | 8h |
|
||||
| 组件测试 | 少量 | 核心组件覆盖 | 6h |
|
||||
| E2E 集成到 CI | 12 个 Playwright spec 未在 CI 运行 | 自动执行 | 2h |
|
||||
|
||||
### 3.3 国际化 (i18n) 准备
|
||||
|
||||
| 工作项 | 说明 | 工作量 |
|
||||
|--------|------|--------|
|
||||
| 引入 i18n 框架 | Desktop saasStore/connectionStore 硬编码中文错误消息 | 2h |
|
||||
| Admin V2 i18n | 所有页面中文硬编码 | 6h |
|
||||
| 提取翻译文件 | zh-CN.json + en-US.json | 4h |
|
||||
|
||||
### 3.4 监控与可观测性
|
||||
|
||||
| 工作项 | 说明 | 工作量 |
|
||||
|--------|------|--------|
|
||||
| 结构化日志增强 | SaaS 后端 tracing 已有,需添加 request_id 关联 | 2h |
|
||||
| Prometheus metrics | 请求延迟、Key Pool 使用率、错误率 | 4h |
|
||||
| Grafana 仪表盘模板 | 预配置的监控面板 | 3h |
|
||||
|
||||
---
|
||||
|
||||
## 四、P3 — 功能扩展 (远期规划)
|
||||
|
||||
### 4.1 已规划但未启动的功能
|
||||
|
||||
| 功能 | 设计状态 | 说明 |
|
||||
|------|---------|------|
|
||||
| 技能市场 UI | CLAUDE.md 标记"进行中" | 技能浏览和安装界面,70 个 SKILL.md 已有 |
|
||||
| Pipeline 工作流编辑器 | CLAUDE.md 标记"进行中" | 可视化编辑器,PipelinesPanel 已有基础 |
|
||||
| 智能路由 (Semantic Router) | L2/50% 成熟度 | 意图路由不成熟,需更多训练数据 |
|
||||
| Predictor Hand | enabled=false | 无 Rust 实现,需完全重写 |
|
||||
| Lead Hand | enabled=false | 无 Rust 实现,需完全重写 |
|
||||
|
||||
### 4.2 设计规格明确排除的未来功能
|
||||
|
||||
| 功能 | 说明 |
|
||||
|------|------|
|
||||
| AccountTier 订阅层级 | 未来商业化 |
|
||||
| 实时配置推送 (WebSocket) | 当前登录时拉取,未来推送 |
|
||||
| 模板市场/用户上传 | 当前仅 Admin 管理 |
|
||||
| Token Pool 计费/用量配额 | 当前无计费逻辑 |
|
||||
| Desktop 用户自选路由模式 | 设计决定仅 Admin 控制 |
|
||||
|
||||
---
|
||||
|
||||
## 五、工作量估算汇总
|
||||
|
||||
| 优先级 | 类别 | 工作量 | 建议排期 |
|
||||
|--------|------|--------|---------|
|
||||
| **P0** | 部署基础设施 | ~7.5h | 第 1 周 |
|
||||
| **P0** | Admin V2 基础测试 | ~8h | 第 1-2 周 |
|
||||
| **P1** | 设计规格遗留 | ~6.5h | 第 2 周 |
|
||||
| **P1** | Desktop TS 错误 | ~1.5h | 第 2 周 |
|
||||
| **P1** | 表格增强 | ~7h | 第 3 周 |
|
||||
| **P2** | API 文档 | ~6h | 第 3-4 周 |
|
||||
| **P2** | 测试提升 | ~16h | 持续 |
|
||||
| **P2** | i18n | ~12h | 第 4-5 周 |
|
||||
| **P2** | 监控 | ~9h | 第 5 周 |
|
||||
| **P3** | 功能扩展 | 大量 | 按需 |
|
||||
| **总计 P0+P1** | | **~30.5h** | 3 周 |
|
||||
| **总计 P2** | | **~43h** | 5 周 |
|
||||
|
||||
---
|
||||
|
||||
## 六、建议执行顺序
|
||||
|
||||
```
|
||||
Week 1: P0 部署基础设施
|
||||
├── Dockerfile + saas-env.example
|
||||
├── Nginx 反代配置
|
||||
├── /api/health 公开
|
||||
└── 生产部署指南
|
||||
|
||||
Week 2: P0 Admin 测试 + P1 遗留修复
|
||||
├── Admin V2 Vitest 配置 + request.ts 测试
|
||||
├── scenarios/quick_commands 表单
|
||||
├── Key Pool LRU 排序
|
||||
├── quota_reset_interval 决策
|
||||
└── Pipeline started_at 修复
|
||||
|
||||
Week 3: P1 表格增强 + P2 API 文档
|
||||
├── 搜索/筛选功能
|
||||
├── 分页状态修复
|
||||
├── OpenAPI 规范生成
|
||||
└── API Reference 页面
|
||||
|
||||
Week 4+: P2 质量持续提升
|
||||
├── Desktop 测试覆盖提升
|
||||
├── i18n 框架引入
|
||||
└── 监控/可观测性
|
||||
```
|
||||
385
docs/archive/old-analysis/saas-backend-optimization.md
Normal file
@@ -0,0 +1,385 @@
|
||||
# ZCLAW SaaS 后端优化计划
|
||||
|
||||
> 生成时间: 2026-03-28
|
||||
> 分析范围: crates/zclaw-saas
|
||||
|
||||
## 一、架构概览
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ ZCLAW SaaS Backend │
|
||||
│ (Rust + Axum + PostgreSQL) │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
||||
│ │ auth │ │ account │ │model_cfg │ │ relay │ │
|
||||
│ │ 认证 │ │ 账号管理 │ │ 模型配置 │ │ 中转服务 │ │
|
||||
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
|
||||
│ │ │ │ │ │
|
||||
│ └─────────────┴─────────────┴─────────────┘ │
|
||||
│ │ │
|
||||
│ ┌──────┴──────┐ │
|
||||
│ │ middleware │ │
|
||||
│ │ - auth │ │
|
||||
│ │ - rate_limit│ │
|
||||
│ └──────┬──────┘ │
|
||||
│ │ │
|
||||
│ ┌──────┴──────┐ │
|
||||
│ │ PostgreSQL │ │
|
||||
│ └─────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## 二、API 接口清单 (共 42 个端点)
|
||||
|
||||
### 2.1 认证模块 `/api/v1/auth` (5 个)
|
||||
|
||||
| 方法 | 路径 | 权限 | 功能 |
|
||||
|------|------|------|------|
|
||||
| POST | `/auth/register` | 公开 | 用户注册 |
|
||||
| POST | `/auth/login` | 公开 | 用户登录 |
|
||||
| POST | `/auth/refresh` | 认证 | 刷新 Token |
|
||||
| GET | `/auth/me` | 认证 | 获取当前用户 |
|
||||
| PUT | `/auth/password` | 认证 | 修改密码 |
|
||||
|
||||
### 2.2 账号管理 `/api/v1` (12 个)
|
||||
|
||||
| 方法 | 路径 | 权限 | 功能 |
|
||||
|------|------|------|------|
|
||||
| GET | `/accounts` | admin | 列出账号 |
|
||||
| GET | `/accounts/:id` | 自己/admin | 账号详情 |
|
||||
| PUT | `/accounts/:id` | 自己/admin | 更新账号 |
|
||||
| PATCH | `/accounts/:id/status` | admin | 更新状态 |
|
||||
| GET | `/tokens` | 认证 | 列出 Token |
|
||||
| POST | `/tokens` | 认证 | 创建 Token |
|
||||
| DELETE | `/tokens/:id` | 认证 | 撤销 Token |
|
||||
| GET | `/logs/operations` | admin | 操作日志 |
|
||||
| GET | `/stats/dashboard` | admin | 仪表盘 |
|
||||
| POST | `/devices/register` | 认证 | 注册设备 |
|
||||
| POST | `/devices/heartbeat` | 认证 | 设备心跳 |
|
||||
| GET | `/devices` | 认证 | 设备列表 |
|
||||
|
||||
### 2.3 模型配置 `/api/v1` (15 个)
|
||||
|
||||
| 方法 | 路径 | 权限 | 功能 |
|
||||
|------|------|------|------|
|
||||
| GET | `/providers` | 认证 | 服务商列表 |
|
||||
| GET | `/providers/:id` | 认证 | 服务商详情 |
|
||||
| POST | `/providers` | provider:manage | 创建服务商 |
|
||||
| PUT | `/providers/:id` | provider:manage | 更新服务商 |
|
||||
| DELETE | `/providers/:id` | provider:manage | 删除服务商 |
|
||||
| GET | `/models` | 认证 | 模型列表 |
|
||||
| GET | `/models/:id` | 认证 | 模型详情 |
|
||||
| POST | `/models` | model:manage | 创建模型 |
|
||||
| PUT | `/models/:id` | model:manage | 更新模型 |
|
||||
| DELETE | `/models/:id` | model:manage | 删除模型 |
|
||||
| GET | `/keys` | 认证 | API Key 列表 |
|
||||
| POST | `/keys` | 认证 | 创建 Key |
|
||||
| POST | `/keys/:id/rotate` | 认证 | 轮换 Key |
|
||||
| DELETE | `/keys/:id` | 认证 | 撤销 Key |
|
||||
| GET | `/usage` | 认证 | 用量统计 |
|
||||
|
||||
### 2.4 中转服务 `/api/v1/relay` (5 个)
|
||||
|
||||
| 方法 | 路径 | 权限 | 功能 |
|
||||
|------|------|------|------|
|
||||
| POST | `/relay/chat/completions` | relay:use | 聊天补全 |
|
||||
| GET | `/relay/tasks` | 认证 | 任务列表 |
|
||||
| GET | `/relay/tasks/:id` | 认证 | 任务详情 |
|
||||
| GET | `/relay/models` | 认证 | 可用模型 |
|
||||
| POST | `/relay/tasks/:id/retry` | relay:admin | 重试任务 |
|
||||
|
||||
### 2.5 配置迁移 `/api/v1/config` (10 个)
|
||||
|
||||
| 方法 | 路径 | 权限 | 功能 |
|
||||
|------|------|------|------|
|
||||
| GET | `/config/items` | 认证 | 配置列表 |
|
||||
| GET | `/config/items/:id` | 认证 | 配置详情 |
|
||||
| POST | `/config/items` | config:write | 创建配置 |
|
||||
| PUT | `/config/items/:id` | config:write | 更新配置 |
|
||||
| DELETE | `/config/items/:id` | config:write | 删除配置 |
|
||||
| GET | `/config/analysis` | 认证 | 配置分析 |
|
||||
| POST | `/config/seed` | config:write | 种子配置 |
|
||||
| POST | `/config/sync` | 认证 | 同步配置 |
|
||||
| POST | `/config/diff` | 认证 | 配置差异 |
|
||||
| GET | `/config/sync-logs` | 认证 | 同步日志 |
|
||||
|
||||
---
|
||||
|
||||
## 三、问题清单
|
||||
|
||||
### 🔴 高优先级 (影响功能/性能)
|
||||
|
||||
#### P1-001: 登录接口 N+1 查询
|
||||
|
||||
**位置:** `auth/handlers.rs:login()`
|
||||
|
||||
**现状:**
|
||||
```rust
|
||||
// 查询 1: 获取用户信息
|
||||
let row = sqlx::query_as("SELECT id, username, ... FROM accounts WHERE username = $1")...
|
||||
|
||||
// 查询 2: 获取密码哈希
|
||||
let (password_hash,) = sqlx::query_as("SELECT password_hash FROM accounts WHERE id = $1")...
|
||||
|
||||
// 查询 3: 获取权限
|
||||
let permissions = get_role_permissions(&state.db, &role).await?;
|
||||
```
|
||||
|
||||
**影响:** 每次登录触发 3 次数据库查询
|
||||
|
||||
**修复方案:**
|
||||
```sql
|
||||
SELECT a.id, a.username, a.email, a.display_name, a.role, a.status,
|
||||
a.totp_enabled, a.created_at, a.password_hash,
|
||||
r.permissions
|
||||
FROM accounts a
|
||||
LEFT JOIN roles r ON a.role = r.id
|
||||
WHERE a.username = $1 OR a.email = $1
|
||||
```
|
||||
|
||||
**工作量:** 小 (1-2 小时)
|
||||
|
||||
---
|
||||
|
||||
#### P1-002: 流式响应 Token 统计缺失
|
||||
|
||||
**位置:** `relay/handlers.rs:chat_completions()`
|
||||
|
||||
**现状:**
|
||||
```rust
|
||||
Ok(service::RelayResponse::Sse(body)) => {
|
||||
model_service::record_usage(..., 0, 0, ...); // 流式记录 0 tokens
|
||||
}
|
||||
```
|
||||
|
||||
**影响:** 流式请求的 token 使用量无法统计,影响计费和监控
|
||||
|
||||
**修复方案:**
|
||||
1. 解析 SSE 流中的 `usage` 字段
|
||||
2. 在流结束后更新统计
|
||||
|
||||
**工作量:** 中 (4-6 小时)
|
||||
|
||||
---
|
||||
|
||||
#### P1-003: 健康检查端点缺失
|
||||
|
||||
**位置:** `main.rs`
|
||||
|
||||
**现状:** 无 `/health` 或 `/ready` 端点
|
||||
|
||||
**影响:**
|
||||
- K8s/Docker 无法进行健康检查
|
||||
- 负载均衡器无法判断服务状态
|
||||
|
||||
**修复方案:**
|
||||
```rust
|
||||
.route("/health", get(|| async {
|
||||
Json(json!({"status": "ok"}))
|
||||
}))
|
||||
.route("/ready", get(|State(state): State<AppState>| async move {
|
||||
// 检查数据库连接
|
||||
let db_ok = sqlx::query("SELECT 1").fetch_one(&state.db).await.is_ok();
|
||||
Json(json!({"ready": db_ok, "db": if db_ok { "connected" } else { "disconnected" }}))
|
||||
}))
|
||||
```
|
||||
|
||||
**工作量:** 小 (1 小时)
|
||||
|
||||
---
|
||||
|
||||
### 🟡 中优先级 (影响可维护性)
|
||||
|
||||
#### P2-001: 权限系统无缓存
|
||||
|
||||
**位置:** `auth/handlers.rs:get_role_permissions()`
|
||||
|
||||
**现状:** 每次请求都查询数据库获取权限
|
||||
|
||||
**影响:**
|
||||
- 数据库压力增加
|
||||
- 响应延迟增加
|
||||
|
||||
**修复方案:**
|
||||
1. 方案 A: 在 JWT 中嵌入权限 (无需查询,但权限变更需重新登录)
|
||||
2. 方案 B: 添加内存缓存 (LRU Cache,权限变更即时生效)
|
||||
|
||||
**推荐:** 方案 B,使用 `moka` 或 `dashmap` 缓存
|
||||
|
||||
**工作量:** 中 (4-8 小时)
|
||||
|
||||
---
|
||||
|
||||
#### P2-002: 错误响应格式不统一
|
||||
|
||||
**位置:** 所有 handlers
|
||||
|
||||
**现状:**
|
||||
```json
|
||||
// 格式 1
|
||||
{"error": "AUTH_ERROR", "message": "认证失败"}
|
||||
|
||||
// 格式 2
|
||||
{"ok": true}
|
||||
|
||||
// 格式 3
|
||||
{"ok": true, "message": "密码修改成功"}
|
||||
```
|
||||
|
||||
**影响:** 前端需要处理多种格式,增加复杂度
|
||||
|
||||
**修复方案:** 统一为 RFC 7807 Problem Details 格式:
|
||||
```json
|
||||
{
|
||||
"type": "https://zclaw.ai/errors/auth-error",
|
||||
"title": "认证失败",
|
||||
"status": 401,
|
||||
"detail": "用户名或密码错误",
|
||||
"code": "AUTH_ERROR"
|
||||
}
|
||||
```
|
||||
|
||||
**工作量:** 中 (4-6 小时)
|
||||
|
||||
---
|
||||
|
||||
#### P2-003: 分页响应缺少元数据
|
||||
|
||||
**位置:** `account/handlers.rs:list_accounts()`
|
||||
|
||||
**现状:**
|
||||
```rust
|
||||
pub struct PaginatedResponse<T> {
|
||||
pub items: Vec<T>,
|
||||
// 缺少 total, page, total_pages
|
||||
}
|
||||
```
|
||||
|
||||
**影响:** 前端无法显示总页数和分页导航
|
||||
|
||||
**修复方案:**
|
||||
```rust
|
||||
pub struct PaginatedResponse<T> {
|
||||
pub items: Vec<T>,
|
||||
pub total: i64,
|
||||
pub page: i64,
|
||||
pub page_size: i64,
|
||||
pub total_pages: i64,
|
||||
}
|
||||
```
|
||||
|
||||
**工作量:** 小 (2-3 小时)
|
||||
|
||||
---
|
||||
|
||||
### 🟢 低优先级 (技术债务)
|
||||
|
||||
#### P3-001: 数据库 Schema 使用 TEXT 类型
|
||||
|
||||
**位置:** `db.rs`
|
||||
|
||||
**现状:**
|
||||
```sql
|
||||
created_at TEXT NOT NULL, -- 应该用 TIMESTAMPTZ
|
||||
role TEXT NOT NULL DEFAULT 'user' -- 应该用外键
|
||||
```
|
||||
|
||||
**影响:**
|
||||
- 无法使用 PostgreSQL 时间函数
|
||||
- 角色无外键约束,可能导致数据不一致
|
||||
|
||||
**修复方案:** 编写迁移脚本,逐步更新 Schema
|
||||
|
||||
**工作量:** 大 (需要数据迁移)
|
||||
|
||||
---
|
||||
|
||||
#### P3-002: 缺少请求追踪
|
||||
|
||||
**现状:** 操作日志只记录业务操作,不记录 API 请求详情
|
||||
|
||||
**影响:**
|
||||
- 无法追踪请求链路
|
||||
- 问题排查困难
|
||||
|
||||
**修复方案:** 添加请求追踪中间件:
|
||||
- 生成 `request_id`
|
||||
- 记录请求耗时
|
||||
- 关联日志与请求
|
||||
|
||||
**工作量:** 中 (4-6 小时)
|
||||
|
||||
---
|
||||
|
||||
#### P3-003: API 版本控制策略缺失
|
||||
|
||||
**现状:** 只有 `v1`,无版本升级策略
|
||||
|
||||
**影响:** 未来 API 变更可能导致兼容性问题
|
||||
|
||||
**修复方案:**
|
||||
1. 在响应头添加 `X-API-Version`
|
||||
2. 支持 `Accept: application/vnd.zclaw.v1+json`
|
||||
3. 添加版本废弃机制
|
||||
|
||||
**工作量:** 小 (2-3 小时)
|
||||
|
||||
---
|
||||
|
||||
## 四、优化实施计划
|
||||
|
||||
### Phase 1: 高优先级修复 (1-2 天)
|
||||
|
||||
| 任务 | 工作量 | 负责人 | 状态 |
|
||||
|------|--------|--------|------|
|
||||
| P1-001 登录 N+1 查询优化 | 2h | - | 待开始 |
|
||||
| P1-003 健康检查端点 | 1h | - | 待开始 |
|
||||
| P1-002 流式 Token 统计 | 6h | - | 待开始 |
|
||||
|
||||
### Phase 2: 中优先级优化 (2-3 天)
|
||||
|
||||
| 任务 | 工作量 | 负责人 | 状态 |
|
||||
|------|--------|--------|------|
|
||||
| P2-001 权限缓存 | 8h | - | 待开始 |
|
||||
| P2-002 错误格式统一 | 6h | - | 待开始 |
|
||||
| P2-003 分页元数据 | 3h | - | 待开始 |
|
||||
|
||||
### Phase 3: 技术债务清理 (按需)
|
||||
|
||||
| 任务 | 工作量 | 负责人 | 状态 |
|
||||
|------|--------|--------|------|
|
||||
| P3-001 Schema 迁移 | 2-3 天 | - | 待评估 |
|
||||
| P3-002 请求追踪 | 6h | - | 待开始 |
|
||||
| P3-003 API 版本控制 | 3h | - | 待开始 |
|
||||
|
||||
---
|
||||
|
||||
## 五、NOT in Scope
|
||||
|
||||
以下内容在本次优化范围之外:
|
||||
|
||||
1. **前端 Admin UI 优化** - 仅关注后端 API
|
||||
2. **数据库分库分表** - 当前数据量不需要
|
||||
3. **微服务拆分** - 架构已足够清晰
|
||||
4. **GraphQL 支持** - REST API 已满足需求
|
||||
5. **WebSocket 支持** - 当前无实时推送需求
|
||||
|
||||
---
|
||||
|
||||
## 六、风险评估
|
||||
|
||||
| 风险 | 可能性 | 影响 | 缓解措施 |
|
||||
|------|--------|------|----------|
|
||||
| Schema 迁移数据丢失 | 低 | 高 | 先备份,分批迁移 |
|
||||
| 权限缓存不一致 | 中 | 中 | 设置 TTL,主动失效 |
|
||||
| 流式解析兼容性 | 中 | 低 | 多模型测试 |
|
||||
|
||||
---
|
||||
|
||||
## 七、验收标准
|
||||
|
||||
- [ ] 所有 API 端点有健康检查
|
||||
- [ ] 登录接口响应时间 < 100ms (P99)
|
||||
- [ ] 流式请求 Token 统计准确率 > 95%
|
||||
- [ ] 错误响应格式统一
|
||||
- [ ] 分页接口包含完整元数据
|
||||
347
docs/archive/old-audits/AUDIT_REPORT_V10.md
Normal file
@@ -0,0 +1,347 @@
|
||||
# ZCLAW SaaS + Tauri 系统性功能审计报告 V10
|
||||
|
||||
> 审计日期: 2026-03-31
|
||||
> 审计范围: SaaS 后端 (68 路由/22 表) + Tauri 桌面端 (107 命令/13 Store) + admin-v2 管理后台 (14 服务/11 页面)
|
||||
> 审计方法: 静态代码分析 + 数据流追踪 + 交叉索引
|
||||
> 修复状态: P0 已修复, P1 已处理, P2 已处理
|
||||
|
||||
---
|
||||
|
||||
## 1. 执行摘要
|
||||
|
||||
### 1.1 整体完成度
|
||||
|
||||
| 层级 | 总数 | 活跃 | 未使用 | 利用率 |
|
||||
|------|------|------|--------|-------|
|
||||
| SaaS 路由 | 92 | 84 | 8 | **91.3%** |
|
||||
| Tauri 命令 | 107 | 79 | 28 | **73.8%** |
|
||||
| Zustand Store | 13 | 13 | 0 | **100%** |
|
||||
| admin-v2 服务 | 14 | 14 | 0 | **100%** |
|
||||
|
||||
### 1.2 问题统计
|
||||
|
||||
| 严重级别 | 数量 | 描述 |
|
||||
|---------|------|------|
|
||||
| **P0 (阻塞)** | 1 | trigger_update 参数不匹配导致所有 Trigger 更新失效 |
|
||||
| **P1 (严重)** | 3 | sessionStore 无 Kernel 适配器、定时任务执行器为 stub、配置同步未传播到 kernel |
|
||||
| **P2 (高)** | 5 | 8 个孤立路由、2 个写而不读 DB 表、Workflow→Pipeline 元数据丢失、Role 管理无 admin 页面、8+ 个 saas-admin 方法无消费者 |
|
||||
| **P3 (中)** | 6 | CleanupRateLimitWorker stub、CacheKey 死代码、pipeline-client 缺少 probe 检测、GET 请求无速率限制、SSRF DNS 失败不阻断、connectionStore 客户端切换未重新注入 |
|
||||
| **P4 (低)** | 4 | 7 个 @deprecated TS 标记、a2a feature-gated 代码、ScheduledTaskRow 部分字段、director.rs 休眠代码 |
|
||||
|
||||
---
|
||||
|
||||
## 2. 功能交叉索引
|
||||
|
||||
### 2.1 SaaS 路由 ↔ 前端消费者映射
|
||||
|
||||
#### 路由状态分布
|
||||
|
||||
| 状态 | 数量 | 说明 |
|
||||
|------|------|------|
|
||||
| CONNECTED (两端消费) | 27 | SaaS 路由同时被 desktop 和 admin-v2 调用 |
|
||||
| DESKTOP_ONLY | 31 | 仅桌面端消费(含 auth、role、device 等) |
|
||||
| ADMIN_ONLY | 16 | 仅 admin-v2 消费(含 key 管理、prompt 写操作等) |
|
||||
| ORPHANED | 8 | 无前端消费者 |
|
||||
| INTERNAL | 1 | health 端点 |
|
||||
|
||||
#### 8 个孤立路由(无前端消费者)
|
||||
|
||||
| 路由 | 模块 | 建议 |
|
||||
|------|------|------|
|
||||
| `GET /api/v1/providers/:id/models` | model_config | 可通过 `GET /api/v1/models?provider_id=X` 替代,考虑移除 |
|
||||
| `GET /api/v1/config/items/:id` | migration | 无单条配置查询需求,考虑移除 |
|
||||
| `DELETE /api/v1/config/items/:id` | migration | 无删除配置 UI,考虑移除或添加到 admin-v2 |
|
||||
| `GET /api/v1/config/analysis` | migration | 配置分析功能未接入,添加到 admin-v2 或移除 |
|
||||
| `POST /api/v1/config/seed` | migration | 配置种子引导未接入,内部工具保留 |
|
||||
| `GET /api/v1/config/sync-logs` | migration | 同步日志查询无 UI,添加到 admin-v2 Config 页面 |
|
||||
| `GET /api/v1/roles/:id/permissions` | role | 角色权限查询无消费者,整合到角色管理 UI |
|
||||
| `GET /api/scheduler/tasks/:id` | scheduled_task | 单条任务查询无消费者 |
|
||||
|
||||
#### 按模块路由覆盖度
|
||||
|
||||
| 模块 | 路由数 | Connected | Desktop Only | Admin Only | Orphaned |
|
||||
|------|-------|-----------|-------------|------------|----------|
|
||||
| auth | 9 | 3 | 5 | 1 | 0 |
|
||||
| account | 12 | 5 | 6 | 0 | 0 |
|
||||
| model_config | 14 | 9 | 3 | 0 | 1 |
|
||||
| relay | 9 | 2 | 3 | 4 | 0 |
|
||||
| migration | 11 | 1 | 5 | 0 | 4 |
|
||||
| role | 11 | 0 | 10 | 0 | 1 |
|
||||
| prompt | 10 | 3 | 1 | 5 | 0 |
|
||||
| agent_template | 7 | 1 | 1 | 4 | 0 |
|
||||
| scheduled_task | 5 | 0 | 4 | 0 | 1 |
|
||||
| telemetry | 4 | 0 | 2 | 2 | 0 |
|
||||
| health | 1 | - | - | - | 1 (internal) |
|
||||
|
||||
### 2.2 Tauri 命令 ↔ 前端调用映射
|
||||
|
||||
#### 28 个未使用命令
|
||||
|
||||
| 分类 | 命令 | 原因 |
|
||||
|------|------|------|
|
||||
| **遗留 Gateway (11)** | zclaw_status/start/stop/restart/local_auth/prepare_for_tauri/approve_device_pairing/doctor/process_list/process_logs/version + zclaw_health_check + zclaw_ping | Gateway 已被 Kernel 替代,全部遗留代码 |
|
||||
| **LLM 内部 (3)** | llm_complete, embedding_create, embedding_providers | 后端内部使用,非前端直接调用 |
|
||||
| **Agent 导出导入 (2)** | agent_export, agent_import | 后端已实现,前端 UI 未接入 |
|
||||
| **Kernel 管理 (1)** | kernel_shutdown | 无关闭路径 |
|
||||
| **Hand (1)** | hand_run_cancel | 取消单次运行未接入 UI |
|
||||
| **定时任务 (2)** | scheduled_task_create, scheduled_task_list | 整个模块未使用 |
|
||||
| **Pipeline (1)** | pipeline_templates | 模板列表未接入 |
|
||||
| **Viking (2)** | viking_add_with_metadata, viking_store_with_summaries | 高级存储功能未接入 |
|
||||
| **Memory (2)** | memory_configure_embedding, memory_is_embedding_configured | 已有 viking 命令替代 |
|
||||
| **Context (1)** | estimate_content_tokens | 已有 compactor 命令替代 |
|
||||
|
||||
---
|
||||
|
||||
## 3. 核心数据流追踪
|
||||
|
||||
### 3.1 聊天流 + 记忆提取 (BREAK-02 验证)
|
||||
|
||||
**结论: PARTIALLY WORKING — 前端正常,后端缺失**
|
||||
|
||||
| 层级 | 记忆提取 | 状态 |
|
||||
|------|---------|------|
|
||||
| 前端 (chatStore.ts:509) | `onComplete` 回调调用 `getMemoryExtractor().extractFromConversation()` | **WORKING** |
|
||||
| Rust (intelligence_hooks.rs:50-108) | 仅调用 `reflect()`,不调用 `extract_and_store_memories()` | **NO extraction** |
|
||||
| Rust Tauri 命令 (lib.rs:204-205) | 仅注册为手动命令 | **Manual only** |
|
||||
|
||||
**影响**: 桌面用户通过前端回调正常工作。但任何绕过前端直接调用 Tauri 命令的路径(如 headless/gateway relay)将缺失记忆提取。
|
||||
|
||||
**建议**: 在 `post_conversation_hook` 中添加可选的 `extract_and_store_memories` 调用,或在文档中明确说明设计意图。
|
||||
|
||||
### 3.2 Hand 触发 + 审批 (BREAK-03 验证)
|
||||
|
||||
**结论: CONFIRMED WORKING**
|
||||
|
||||
kernel.rs:1118-1193 的 `respond_to_approval` 实现:
|
||||
- 状态更新为 "approved"
|
||||
- `tokio::spawn` 创建后台任务
|
||||
- 调用 `hands.execute(&hand_id, &context, input).await` 执行 Hand
|
||||
- 更新 HandRun 结果和 approval 状态为 "completed"/"failed"
|
||||
|
||||
BREAK-03 **不是问题**,审批后自动执行机制完整。
|
||||
|
||||
### 3.3 Agent CRUD 一致性
|
||||
|
||||
**结论: INTENTIONAL GAP — 设计意图**
|
||||
|
||||
| 路径 | Create | Read | Update | Delete | Export/Import |
|
||||
|------|--------|------|--------|--------|--------------|
|
||||
| Kernel (Tauri) | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| Gateway (REST) | ✅ | ✅ | ✅ | ✅ | ❌ |
|
||||
| SaaS | 仅 template | 仅 template | 仅 template | 仅 template | ❌ |
|
||||
|
||||
SaaS 仅存储 agent 模板(蓝图),运行时 Agent 是本地状态,由 Kernel/Gateway 管理。这是正确的架构决策。
|
||||
|
||||
### 3.4 配置同步流
|
||||
|
||||
**结论: PARTIALLY WORKING**
|
||||
|
||||
| 方向 | 路径 | 状态 |
|
||||
|------|------|------|
|
||||
| SaaS → localStorage | `pullConfig()` → `localStorage.setItem()` | ✅ WORKING |
|
||||
| localStorage → SaaS | `syncConfig()` + dirty tracking | ✅ WORKING |
|
||||
| localStorage → Kernel | 无传播机制 | ❌ **GAP** |
|
||||
|
||||
**影响**: SaaS 同步的配置仅影响前端 UI 设置(如主题),不会传播到运行中的 Rust kernel。kernel 从磁盘 TOML 读取配置,与 localStorage 无关。
|
||||
|
||||
---
|
||||
|
||||
## 4. 差距模式分析
|
||||
|
||||
### 4.1 "写了没接" — 代码存在但未接入
|
||||
|
||||
| ID | 项目 | 文件 | 严重性 |
|
||||
|----|------|------|--------|
|
||||
| WNC-01 | CleanupRateLimitWorker (空 stub) | `crates/zclaw-saas/src/workers/cleanup_rate_limit.rs` | P3 |
|
||||
| WNC-02 | 定时任务执行器 (仅状态管理,无实际执行) | `crates/zclaw-saas/src/scheduler.rs:134-192` | P1 |
|
||||
| WNC-03 | Role 管理 (无 admin-v2 页面) | `admin-v2/src/` 无 roles 服务/页面 | P2 |
|
||||
| WNC-04 | Agent export/import (前端未接入) | `desktop/src-tauri/src/kernel_commands/agent.rs:213-235` | P4 |
|
||||
| WNC-05 | pipeline_templates 命令 (无调用) | `desktop/src-tauri/src/pipeline_commands/presentation.rs` | P4 |
|
||||
|
||||
### 4.2 "接了没传" — 接口不匹配
|
||||
|
||||
| ID | 项目 | 文件 | 严重性 | 详情 |
|
||||
|----|------|------|--------|------|
|
||||
| **MSH-01** | **trigger_update 参数不匹配** | `trigger.rs:183` vs `kernel-triggers.ts:92` | **P0** | **前端发 `{id, updates: {name, enabled, handId}}` 嵌套结构,Rust 期望 `{id, name, enabled, hand_id}` 扁平参数。所有 trigger 更新实际为 no-op** |
|
||||
| MSH-02 | Workflow→Pipeline 元数据丢失 | `workflowStore.ts:379-502` | P2 | 丢失 category/industry/tags/icon/version/author 等字段 |
|
||||
|
||||
### 4.3 "传了没存" — 数据接收但未持久化
|
||||
|
||||
| ID | 项目 | 文件 | 严重性 |
|
||||
|----|------|------|--------|
|
||||
| PTS-01 | 定时任务执行结果 | `scheduler.rs:134-192` | P1 |
|
||||
|
||||
### 4.4 "存了没用" — 写入但无读路径
|
||||
|
||||
| ID | 表 | 写入位置 | 读路径 | 严重性 |
|
||||
|----|-----|---------|--------|--------|
|
||||
| SUN-01 | `prompt_sync_status` | `prompt/service.rs:272` | **无** | P2 |
|
||||
| SUN-02 | `config_sync_log` | `migration/service.rs:425` | 有 handler 但 handler 本身孤立 | P2 |
|
||||
|
||||
### 4.5 "双系统不同步" — SaaS vs Tauri 功能差异
|
||||
|
||||
| 领域 | Gateway | Kernel | SaaS | 差距性质 |
|
||||
|------|---------|--------|------|---------|
|
||||
| Agent CRUD | REST | invoke | 仅 template | **INTENTIONAL** |
|
||||
| Session | REST | ❌ 无命令 | ❌ 无路由 | sessionStore 无 Kernel 适配器 |
|
||||
| Trigger | REST | invoke | ❌ 无路由 | 仅本地,不同步 |
|
||||
| Browser | ❌ | invoke | ❌ 无路由 | Tauri-only 特性 |
|
||||
| Pipeline | ❌ | invoke | ❌ 无路由 | Tauri-only 特性 |
|
||||
| Role 管理 | ❌ | ❌ | REST | 仅 desktop 消费,无 admin UI |
|
||||
|
||||
---
|
||||
|
||||
## 5. 安全审计
|
||||
|
||||
### 5.1 安全控制验证(全部 PASS)
|
||||
|
||||
| 控制项 | 状态 | 证据 |
|
||||
|--------|------|------|
|
||||
| JWT secret 管理 | ✅ | debug 模式 fallback,release 模式强制要求环境变量 (`config.rs:236-248`) |
|
||||
| SSRF 防护 | ✅ | 多层验证:主机名黑名单、DNS 解析检查、私有 IP 段、混淆防护 (`relay/service.rs:452-565`) |
|
||||
| 速率限制 | ✅ | 公开端点分级限流 (login 5/min, register 3/hour)、认证端点 RPM 限制 (`middleware.rs:56-162`) |
|
||||
| Relay 认证 | ✅ | `relay:use` 权限检查 (`relay/handlers.rs:24`)、key pool 隔离 |
|
||||
| 请求体大小限制 | ✅ | MAX_BODY_BYTES = 1MB (`relay/handlers.rs:47-50`) |
|
||||
| IP 提取安全 | ✅ | 不信任 X-Forwarded-For,仅从 TCP 层获取 (`middleware.rs:133-138`) |
|
||||
|
||||
### 5.2 安全注意事项
|
||||
|
||||
| 项 | 严重性 | 说明 |
|
||||
|----|--------|------|
|
||||
| GET 请求无速率限制 | P3 | GET 免于限流 (middleware.rs:62),可被利用但 GET 无副作用 |
|
||||
| SSRF DNS 失败不阻断 | P3 | DNS 解析失败时不阻断请求 (service.rs:530-533),存在窄 TOCTOU 窗口 |
|
||||
| sessionStore 类型不安全转换 | P3 | `setSessionStoreClient` 无条件 cast 为 GatewayClient (sessionStore.ts:225-228) |
|
||||
|
||||
---
|
||||
|
||||
## 6. Store 适配器一致性
|
||||
|
||||
| Store | Gateway 适配器 | Kernel 适配器 | SaaS 适配器 | 问题 |
|
||||
|-------|---------------|-------------|------------|------|
|
||||
| connectionStore | ✅ | ✅ | ✅ | P3: 客户端切换后未重新注入其他 store |
|
||||
| chatStore | ✅ (via conn) | ✅ (via conn) | ✅ (relay) | 无 |
|
||||
| agentStore | ✅ | ✅ | ❌ | 无 |
|
||||
| handStore | ✅ | ✅ | ❌ | P3: fallback 为 stub client |
|
||||
| workflowStore | ✅ | ✅ | ❌ | P2: Pipeline→Workflow 元数据丢失 |
|
||||
| configStore | ✅ | ✅ | ✅ | 无 |
|
||||
| securityStore | ✅ | ✅ | ❌ | 无 |
|
||||
| **sessionStore** | ✅ | **❌** | ❌ | **P1: 无 Kernel 适配器,Tauri 模式下 session 失效** |
|
||||
| saasStore | ❌ | ❌ | ✅ | 无 (SaaS 专用) |
|
||||
| memoryGraphStore | ❌ | ✅ (invoke) | ❌ | 无 |
|
||||
| browserHandStore | ❌ | ✅ (invoke) | ❌ | P3: Tauri-only 特性 |
|
||||
| offlineStore | ✅ (via conn) | ✅ (via conn) | ❌ | 无 |
|
||||
| workflowBuilderStore | ❌ | ❌ | ❌ | 纯本地存储 |
|
||||
|
||||
---
|
||||
|
||||
## 7. 死代码审计
|
||||
|
||||
### 7.1 已验证的假阳性(AUDIT_TRACKER V9 纠正)
|
||||
|
||||
| ID | 项目 | 实际状态 |
|
||||
|----|------|---------|
|
||||
| DEAD-01 | PromptInjector | **活跃** — 在 zclaw-runtime/growth.rs 和 viking_commands.rs 中使用 |
|
||||
| DEAD-02 | MemoryRetriever | **活跃** — 在 zclaw-runtime/growth.rs 和 create_growth_system() 中使用 |
|
||||
| DEAD-03 | GrowthTracker | **活跃** — 在 zclaw-runtime/growth.rs 和 create_growth_system() 中使用 |
|
||||
| DEAD-04 | director.rs (897 行) | **Feature-gated** — multi-agent 特性,默认不编译 |
|
||||
| DEAD-05 | saas-admin.ts Role 方法 | **确认死代码** — 8+ 个方法无前端消费者 |
|
||||
|
||||
### 7.2 真正的死代码
|
||||
|
||||
| 项目 | 文件 | 说明 |
|
||||
|------|------|------|
|
||||
| 11 个 Gateway 命令 | `desktop/src-tauri/src/gateway/commands.rs` | Gateway 已被 Kernel 替代 |
|
||||
| 8+ Role/Permission 方法 | `desktop/src/lib/saas-admin.ts:183-220` | 完整实现但无调用者 |
|
||||
| CacheKey 结构体 | `crates/zclaw-growth/src/retrieval/cache.rs:22` | 整个结构体从未使用 |
|
||||
| CleanupRateLimitWorker | `crates/zclaw-saas/src/workers/cleanup_rate_limit.rs` | 空 stub |
|
||||
|
||||
---
|
||||
|
||||
## 8. 优先修复清单
|
||||
|
||||
### P0 — 阻塞(已修复 ✅)
|
||||
|
||||
| ID | 问题 | 文件 | 修复方案 | 状态 |
|
||||
|----|------|------|---------|------|
|
||||
| MSH-01 | trigger_update 参数不匹配 | `trigger.rs:183` / `kernel-triggers.ts:92` | Rust 端改为接受 `{ id, updates: {...} }` 结构体,匹配前端格式 | ✅ 已修复 |
|
||||
|
||||
### P1 — 严重(已处理 ✅)
|
||||
|
||||
| ID | 问题 | 文件 | 修复方案 | 状态 |
|
||||
|----|------|------|---------|------|
|
||||
| WNC-02 | 定时任务执行器为 stub | `scheduler.rs:134-192` | 添加 TODO(STUB) 标注 + 运行时 warn 日志 | ✅ 已标注 |
|
||||
| GAP-01 | sessionStore 无 Kernel 适配器 | `sessionStore.ts:225-228` | 添加类型检测,KernelClient 使用 stub 适配器 | ✅ 已修复 |
|
||||
| GAP-02 | 配置同步未传播到 kernel | `saasStore.ts:528-531` | 评估为设计意图:SaaS 配置为 UI-only,`llm_routing` 通过 account data 已传播 | ✅ 确认设计意图 |
|
||||
|
||||
### P2 — 高(下个迭代)
|
||||
|
||||
| ID | 问题 | 修复方案 |
|
||||
|----|------|---------|
|
||||
| ORPHAN | 8 个孤立路由 | 评估移除或添加 admin-v2 UI |
|
||||
| SUN-01 | prompt_sync_status 写而不读 | 添加 admin 读路径或移除表 |
|
||||
| SUN-02 | config_sync_log 写而不读 | 添加 admin-v2 Config 页面 tab |
|
||||
| MSH-02 | Pipeline→Workflow 元数据丢失 | 扩展 Workflow 类型或标注忽略字段 |
|
||||
| ADMIN-01 | Role 管理无 admin 页面 | 添加 admin-v2 角色管理页面 |
|
||||
| DEAD-05 | 8+ saas-admin 方法无消费者 | 接入 UI 或移除 |
|
||||
|
||||
### P3 — 中(后续迭代)
|
||||
|
||||
| ID | 问题 | 修复方案 |
|
||||
|----|------|---------|
|
||||
| STUB-01 | CleanupRateLimitWorker 空实现 | 移除或实现 |
|
||||
| DEAD-06 | CacheKey 死结构体 | 移除 |
|
||||
| GAP-03 | pipeline-client 缺少 probe 检测 | 复用 kernel-client 的 probeTauriAvailability |
|
||||
| GAP-04 | connectionStore 切换后未重新注入 store | 在 connect() 后重新调用 initializeStores() |
|
||||
| SEC-01 | GET 请求无速率限制 | 监控 GET 量,必要时添加 |
|
||||
| SEC-02 | SSRF DNS 失败不阻断 | 考虑 DNS 失败时阻断请求 |
|
||||
|
||||
### P4 — 低(维护时处理)
|
||||
|
||||
| ID | 问题 |
|
||||
|----|------|
|
||||
| CLEANUP-01 | 11 个遗留 Gateway 命令移除 |
|
||||
| CLEANUP-02 | 7 个 @deprecated TS 标记清理 |
|
||||
| CLEANUP-03 | 4 个 CANDIDATE 级 dead_code 评估 |
|
||||
| FEATURE-01 | Agent export/import 前端接入 |
|
||||
| FEATURE-02 | multi-agent (director.rs) 激活准备 |
|
||||
|
||||
---
|
||||
|
||||
## 9. 验证命令
|
||||
|
||||
```bash
|
||||
# 编译验证
|
||||
cargo build -p zclaw-saas
|
||||
|
||||
# TypeScript 类型检查
|
||||
cd desktop && pnpm tsc --noEmit
|
||||
|
||||
# admin-v2 类型检查
|
||||
cd admin-v2 && pnpm tsc --noEmit
|
||||
|
||||
# Rust 测试
|
||||
cargo test -p zclaw-saas
|
||||
|
||||
# 搜索 trigger_update 不匹配 (P0 验证)
|
||||
grep -n "trigger_update" desktop/src-tauri/src/kernel_commands/trigger.rs desktop/src/lib/kernel-triggers.ts
|
||||
|
||||
# 搜索孤立路由 (P2 验证)
|
||||
grep -rn "config/analysis\|config/seed\|config/sync-logs" desktop/src/ admin-v2/src/
|
||||
|
||||
# 搜索写而不读表 (P2 验证)
|
||||
grep -rn "prompt_sync_status" crates/zclaw-saas/src/ --include="*.rs"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. 审计方法总结
|
||||
|
||||
本次审计使用了以下技术:
|
||||
1. **交叉索引** — 92 条 SaaS 路由 × 107 个 Tauri 命令 × 14 个 admin 服务 全量匹配
|
||||
2. **数据流追踪** — 4 条核心业务流端到端追踪(聊天、Agent CRUD、Hand 审批、配置同步)
|
||||
3. **差距模式扫描** — 5 种已知差距模式逐一验证
|
||||
4. **安全面审计** — JWT/SSRF/rate-limit/auth 中间件逐项检查
|
||||
5. **死代码检测** — `#[allow(dead_code)]` + `#[deprecated]` + 无引用代码全量扫描
|
||||
6. **接口一致性** — Tauri 命令签名 vs 前端 invoke 参数逐个比对
|
||||
|
||||
总审计代码量:~150,000 行 Rust + ~45,000 行 TypeScript + ~8,000 行 SQL
|
||||
214
docs/archive/old-audits/AUDIT_ROUND3_V11.md
Normal file
@@ -0,0 +1,214 @@
|
||||
# ZCLAW 第三轮全面审计报告
|
||||
|
||||
> **审计日期**: 2026-04-02
|
||||
> **基线**: V11 全面审计 + 深度二次审计 + Sprint 1-4 修复
|
||||
> **方法**: 5 维并行审计(前端状态一致性、数据库 Schema、API 契约、并发安全、代码质量)
|
||||
> **完成代理**: 前端状态一致性(1/5),其余 4 维因 API 限流由主线程直接执行
|
||||
|
||||
---
|
||||
|
||||
## 1. 前端状态一致性 + 内存泄漏审计(代理完成)
|
||||
|
||||
### HIGH
|
||||
|
||||
| ID | 问题 | 文件 | 描述 |
|
||||
|----|------|------|------|
|
||||
| AUD3-FE-01 | **chatStore.sendMessage 无并发保护** | `chatStore.ts:403-675` | `isStreaming` 仅在 UI 层守卫,store 函数本身无互斥。快速双击可在 React re-render 前触发两次发送,导致双重 assistant placeholder + stream 竞态 |
|
||||
| AUD3-FE-02 | **SaaS client token refresh 无并发锁** | `saas-client.ts:217-229` | 多个并发请求同时收到 401 时,各自独立调用 `refreshToken()`,导致多次 refresh 请求。应使用 refresh mutex(共享 Promise) |
|
||||
|
||||
### MEDIUM
|
||||
|
||||
| ID | 问题 | 文件 | 描述 |
|
||||
|----|------|------|------|
|
||||
| AUD3-FE-03 | initializeStores 可能被调用 3 次 | `connectionStore.ts:415,589` + `index.ts:99` | 模块加载 + connect() 双路径,异步操作中切换 client 可能导致请求失败 |
|
||||
| AUD3-FE-04 | window 全局变量存储 interval | `App.tsx:257-258` | `@ts-expect-error` + `window.__ZCLAW_STATS_SYNC_INTERVAL__`,React StrictMode 双重 mount 时第一个 interval 无法清理 |
|
||||
| AUD3-FE-05 | GatewayClient mixin 25+ 处 `as any` | `gateway-heartbeat.ts` 等 | prototype 动态方法通过 `as any` 绕过类型检查,属性名拼写错误无编译时报警 |
|
||||
| AUD3-FE-06 | PropertyPanel 17 处 `as any` 访问联合类型 | `PropertyPanel.tsx:100-276` | WorkflowNodeData 联合类型的字段直接 `as any` 访问,节点类型不匹配时 undefined |
|
||||
|
||||
### LOW
|
||||
|
||||
| ID | 问题 | 文件 |
|
||||
|----|------|------|
|
||||
| AUD3-FE-07 | offlineStore 全局变量存储 timer(多次调用可能泄漏) | `offlineStore.ts:87-88` |
|
||||
| AUD3-FE-08 | agentStore 一次性读取 chatStore 可能读到中间态 | `agentStore.ts:254` |
|
||||
| AUD3-FE-09 | retryAllMessages 无并发锁,可能重复发送 | `offlineStore.ts:188-233` |
|
||||
|
||||
### POSITIVE FINDINGS(做得好的地方)
|
||||
|
||||
- **无 Store 循环依赖**: 依赖方向是单向树状结构
|
||||
- **事件监听器清理完善**: classroomStore、useAutomationEvents、chatStore 的 listen 全部有 cleanup
|
||||
- **React useEffect cleanup 规范**: ConnectionStatus、HandApprovalModal、SaaSStatus 全部正确清理
|
||||
|
||||
---
|
||||
|
||||
## 2. 数据库 Schema + Migration 审计(主线程执行)
|
||||
|
||||
### Migration 文件清单(13 个)
|
||||
|
||||
| 编号 | 文件 | 内容 |
|
||||
|------|------|------|
|
||||
| 20260329-001 | initial_schema.sql | 21 个核心表 |
|
||||
| 20260329-002 | seed_data.sql | 种子数据 |
|
||||
| 20260330-001 | scheduled_tasks.sql | 定时任务表 |
|
||||
| 20260331-001 | accounts_llm_routing.sql | LLM 路由字段 |
|
||||
| 20260331-002 | agent_templates_extensions.sql | 模板扩展 |
|
||||
| 20260401-001 | provider_keys_last_used.sql | key 最近使用时间 |
|
||||
| 20260401-002 | remove_quota_reset_interval.sql | 移除配额重置 |
|
||||
| 20260401-003 | models_is_embedding.sql | embedding 标记 |
|
||||
| 20260401-004 | accounts_password_version.sql | 密码版本 |
|
||||
| 20260401-005 | rate_limit_events.sql | 限流事件 |
|
||||
| 20260402-001 | billing_tables.sql | 计费 5 表 |
|
||||
| 20260402-002 | knowledge_base.sql | 知识库 5 表 |
|
||||
| 20260402-003 | scheduled_task_results.sql | 任务结果列 |
|
||||
|
||||
### MEDIUM
|
||||
|
||||
| ID | 问题 | 描述 |
|
||||
|----|------|------|
|
||||
| AUD3-DB-01 | 无 down migration | 所有 migration 只有 UP,无回滚脚本。生产环境需要回滚时只能手动操作 |
|
||||
| AUD3-DB-02 | agent_template/service.rs:136 format! 构建 SQL | `format!("SELECT COUNT(*) FROM agent_templates {}", where_clause)` 中 `where_clause` 虽然是硬编码常量(非用户输入),但模式本身违反防御原则 |
|
||||
|
||||
### POSITIVE FINDINGS
|
||||
|
||||
- **编号连续无冲突**: 13 个 migration 编号连续
|
||||
- **无 DELETE/UPDATE 缺少 WHERE**: 全量扫描确认所有写操作都有 WHERE 子句
|
||||
- **仅 2 处 format! SQL**: `agent_template/service.rs` 和 `db.rs`,两者 where_clause/table 均为硬编码
|
||||
- **zclaw-growth 和 zclaw-memory 无 migration 目录**: 使用代码内 schema 初始化(SQLite)
|
||||
|
||||
---
|
||||
|
||||
## 3. API 契约 + 错误恢复审计(主线程执行)
|
||||
|
||||
### HIGH
|
||||
|
||||
| ID | 问题 | 文件 | 描述 |
|
||||
|----|------|------|------|
|
||||
| AUD3-API-01 | **SaaS token refresh 并发竞态** | `saas-client.ts:217-229` | 多个并发请求同时收到 401,各自独立调用 `refreshToken()`。无 `_refreshPromise` 或 mutex。refresh token 可能被第一个请求消耗,后续 refresh 请求失败(单次使用 token) |
|
||||
|
||||
### MEDIUM
|
||||
|
||||
| ID | 问题 | 描述 |
|
||||
|----|------|------|
|
||||
| AUD3-API-02 | 前端错误处理不统一 | 部分 invoke() 调用用 try/catch + log(静默),部分直接 throw(用户看到错误),部分 fallback 默认值。无全局错误提示机制 |
|
||||
| AUD3-API-03 | 37 处 `as any` 类型断言 | 前端大量绕过类型检查,重构时容易引入运行时错误 |
|
||||
|
||||
### POSITIVE FINDINGS
|
||||
|
||||
- **AbortController 使用规范**: `request-helper.ts` 有完整的 AbortController 管理(Map<string, AbortController>),支持请求取消
|
||||
- **认证端点跳过 refresh**: `_isAuthEndpoint()` 正确避免 login/register 端点的无限 refresh 循环
|
||||
- **timeout 配置**: 所有 fetch 调用使用 `AbortSignal.timeout()`
|
||||
|
||||
---
|
||||
|
||||
## 4. 并发安全 + 资源管理审计(主线程执行)
|
||||
|
||||
### MEDIUM
|
||||
|
||||
| ID | 问题 | 文件 | 描述 |
|
||||
|----|------|------|------|
|
||||
| AUD3-CONC-01 | kernel_commands 每个命令单独获取 kernel_lock | `kernel_commands/*.rs` | 每个 Tauri 命令独立 `state.lock().await`,无嵌套锁获取。设计安全但串行化所有命令执行 |
|
||||
| AUD3-CONC-02 | ~15 处 fire-and-forget tokio::spawn | `main.rs:108-151`, `relay/handlers.rs:389`, `scheduler.rs:62-140` | 无 JoinHandle,无优雅停机。shutdown 时运行中的任务可能被截断 |
|
||||
| AUD3-CONC-03 | approval polling 循环持有 kernel_lock | `approval.rs:96` | `kernel_state.lock().await` 在 sleep 循环中反复获取,每次循环释放后重新获取。设计安全但增加锁竞争 |
|
||||
|
||||
### POSITIVE FINDINGS
|
||||
|
||||
- **无嵌套锁获取**: 每个 kernel_command 只获取一个 MutexLock,不存在 ABBA 死锁风险
|
||||
- **DashMap 操作规范**: 所有 RefMut 在 `.await` 前释放(已确认)
|
||||
- **CancellationToken 用于 SSE**: relay 的 SSE 流有取消机制
|
||||
|
||||
---
|
||||
|
||||
## 5. 代码质量审计(主线程执行)
|
||||
|
||||
### 统计数据
|
||||
|
||||
| 指标 | 数值 |
|
||||
|------|------|
|
||||
| Rust 测试总数 | 584 |
|
||||
| 前端测试 | 0 (desktop) + 322 (admin-v2) |
|
||||
| `as any` 使用 | 37 处 |
|
||||
| `@ts-expect-error` | 3 处 |
|
||||
| 未使用 Cargo 依赖 | 0(已清理 hmac/sha1) |
|
||||
| Feature gate 一致性 | 正确 |
|
||||
| 编译警告 | 1 (private_interfaces) + 1 (sqlx future-incompat) |
|
||||
|
||||
---
|
||||
|
||||
## 6. 综合发现汇总
|
||||
|
||||
### 新增 HIGH(需立即修复)
|
||||
|
||||
| ID | 问题 | 影响 |
|
||||
|----|------|------|
|
||||
| AUD3-FE-01 | chatStore.sendMessage 无并发保护 | 快速双击导致双重发送 + stream 竞态 |
|
||||
| AUD3-FE-02 / AUD3-API-01 | SaaS token refresh 无并发锁 | 并发 401 → 多次 refresh → refresh token 被消耗 → 后续请求全部失败 |
|
||||
|
||||
### 新增 MEDIUM
|
||||
|
||||
| ID | 问题 | 影响 |
|
||||
|----|------|------|
|
||||
| AUD3-FE-03 | initializeStores 可能调用 3 次 | 异步操作中 client 切换 |
|
||||
| AUD3-FE-04 | window 全局变量存 interval | StrictMode 泄漏 |
|
||||
| AUD3-FE-05 | 25+ 处 mixin `as any` | 类型安全缺口 |
|
||||
| AUD3-FE-06 | PropertyPanel 17 处 `as any` | 联合类型不安全 |
|
||||
| AUD3-DB-01 | 无 down migration | 生产回滚困难 |
|
||||
| AUD3-DB-02 | format! SQL(硬编码安全但模式差) | 防御性编程 |
|
||||
| AUD3-API-02 | 前端错误处理不统一 | 用户体验不一致 |
|
||||
| AUD3-CONC-02 | ~15 处 fire-and-forget spawn | 优雅停机问题 |
|
||||
|
||||
### 新增 LOW
|
||||
|
||||
| ID | 问题 |
|
||||
|----|------|
|
||||
| AUD3-FE-07 | offlineStore 全局变量存储 timer |
|
||||
| AUD3-FE-08 | agentStore 读取中间态 |
|
||||
| AUD3-FE-09 | retryAllMessages 无并发锁 |
|
||||
| AUD3-CONC-03 | approval polling 增加锁竞争 |
|
||||
|
||||
---
|
||||
|
||||
## 7. 三轮审计累计发现总览
|
||||
|
||||
| 来源 | P0 | HIGH/P1 | MEDIUM/P2 | LOW/P3/P4 |
|
||||
|------|-----|---------|-----------|-----------|
|
||||
| V11 初次审计 | 0 | 3 | 14 | 13 |
|
||||
| V11 深度二次 | 2 | 9 | 13 | 3 |
|
||||
| V11 第三轮 | 0 | **2** | **8** | **4** |
|
||||
| **合计(去重后)** | **2** | **14** | **35** | **20** |
|
||||
|
||||
### 已修复 vs 未修复
|
||||
|
||||
| 状态 | 数量 |
|
||||
|------|------|
|
||||
| **已修复** | 13(2 P0 + 8 P1 + 3 P2) |
|
||||
| **未修复** | 40 |
|
||||
|
||||
### 未修复中按优先级排序的 TOP 10
|
||||
|
||||
1. **AUD3-FE-01**: chatStore.sendMessage 并发保护(HIGH)
|
||||
2. **AUD3-FE-02/API-01**: token refresh mutex(HIGH)
|
||||
3. **SEC2-P1-01**: FactStore trait 零实现(P1)
|
||||
4. **SEC2-P1-08**: Desktop 前端零测试(P1)
|
||||
5. **AUD3-FE-03**: initializeStores 重复调用(MEDIUM)
|
||||
6. **AUD3-FE-05**: mixin 模式类型安全(MEDIUM)
|
||||
7. **SEC2-P2-03**: sqlx-postgres 未来兼容性(P2)
|
||||
8. **SEC2-P2-05**: ~10 处 tokio::spawn 未绑定(P2)
|
||||
9. **AUD3-DB-01**: 无 down migration(MEDIUM)
|
||||
10. **SEC2-P1-01**: FactStore trait 零实现(P1)
|
||||
|
||||
---
|
||||
|
||||
## 8. 积极发现总结
|
||||
|
||||
三轮审计确认以下方面**设计良好、实现规范**:
|
||||
|
||||
1. **无 Store 循环依赖** — 单向树状依赖结构
|
||||
2. **事件监听器全部有 cleanup** — listen/unlisten 配对完整
|
||||
3. **认证中间件全覆盖** — 公共/受保护/Relay 三层路由无遗漏
|
||||
4. **SQL 参数化规范** — 除 2 处硬编码 format! 外全部使用 bind()
|
||||
5. **Lock ordering 安全** — 无嵌套锁获取
|
||||
6. **Feature gate 一致** — 传播链正确
|
||||
7. **Admin API 100% 对齐** — 前后端路由完全匹配
|
||||
8. **编译通过** — cargo check 仅 1 warning
|
||||
9. **密码安全** — Argon2id + password_version + JWT 失效
|
||||
10. **SSE 背压设计** — 有界 channel + 信号量 + CancellationToken
|
||||
236
docs/archive/old-audits/COMPREHENSIVE_AUDIT_V11.md
Normal file
@@ -0,0 +1,236 @@
|
||||
# ZCLAW 全面功能审计报告 V11
|
||||
|
||||
> **审计日期**: 2026-04-02
|
||||
> **审计范围**: 10 Rust crate + desktop 前端 + admin-v2 管理后台
|
||||
> **基线**: V10 审计追踪(20 项发现)
|
||||
|
||||
---
|
||||
|
||||
## 1. 执行摘要
|
||||
|
||||
### 关键指标
|
||||
|
||||
| 指标 | 数值 | 文档值 | 状态 |
|
||||
|------|------|--------|------|
|
||||
| Tauri 命令(注册) | 175 | 58+ / 130+ | 文档不一致 |
|
||||
| Tauri 命令(有前端调用) | ~90 | - | 51% 利用率 |
|
||||
| SKILL.md | 76 | 66/75/77 | 文档不一致 |
|
||||
| Hands | 9 目录 | 11 | CLAUDE.md 与实际不一致 |
|
||||
| Zustand Stores | 15 | 14 | 文档偏差 |
|
||||
| SaaS API 路由 | 58 | 72+ | 文档偏高 |
|
||||
| Admin-v2 页面 | 12 | 11 | 文档偏低 |
|
||||
| 源文件 | 233 (.rs) + 122 (.tsx) + 15 (.ts store) | - | - |
|
||||
|
||||
### V10→V11 状态变更
|
||||
|
||||
| V10 ID | V11 状态 | 说明 |
|
||||
|--------|----------|------|
|
||||
| BREAK-02 | **关闭** | 记忆提取通过 MemoryMiddleware.after_completion 正常触发 |
|
||||
| BREAK-03 | **关闭** | approval_respond 自动 spawn tokio task 执行 Hand |
|
||||
| BREAK-04 | **关闭** | pipeline-complete 在 discovery.rs:165 emit,前端有监听器 |
|
||||
| BREAK-01 | 已修复 | 保持 CLOSED |
|
||||
|
||||
---
|
||||
|
||||
## 2. 发现项索引
|
||||
|
||||
### P1: 严重级(3 项)
|
||||
|
||||
| ID | 问题 | 文件 | 验证方法 |
|
||||
|----|------|------|----------|
|
||||
| V11-P1-01 | trigger_update 参数不匹配,更新静默失败 | `desktop/src/lib/kernel-triggers.ts:99` → `desktop/src-tauri/src/kernel_commands/trigger.rs:183-189` | 前端发 `{id, updates:{...}}` 但 Rust 期望扁平参数 |
|
||||
| V11-P1-02 | SaaS 配置同步不传播到 Rust Kernel | `desktop/src/store/saasStore.ts:484-541` | localStorage 写入但 Kernel 无读取路径 |
|
||||
| V11-P1-03 | 3 个 SQL 表零读取:prompt_sync_status, telemetry_reports, key_usage_window | `crates/zclaw-saas/src/db.rs` 迁移定义 | `grep -rn "SELECT.*FROM.*<table>" crates/zclaw-saas/src/` 零结果 |
|
||||
|
||||
### P2: 高优先级(6 项)
|
||||
|
||||
| ID | 问题 | 文件 |
|
||||
|----|------|------|
|
||||
| V11-P2-01 | saas-admin.ts 30 方法零消费者(admin-v2 独立 Axios 实现) | `desktop/src/lib/saas-admin.ts` |
|
||||
| V11-P2-02 | 7 个 Role/Permission 路由无前端消费者 | `crates/zclaw-saas/src/role/mod.rs` |
|
||||
| V11-P2-03 | deprecated gateway-storage sync 方法仍被生产代码调用 | `desktop/src/lib/gateway-storage.ts:129,196` |
|
||||
| V11-P2-04 | ToolDefinition 在 types 和 runtime 重复定义 | `crates/zclaw-types/src/tool.rs:8` vs `crates/zclaw-runtime/src/driver/mod.rs:94` |
|
||||
| V11-P2-05 | 62 个 Tauri 命令无前端调用(含 8 classroom 命令中 7 个未调用) | `desktop/src-tauri/src/lib.rs:124-323` |
|
||||
| V11-P2-06 | migration/service.rs config_items 查询缺少 LIMIT | `crates/zclaw-saas/src/migration/service.rs` |
|
||||
|
||||
### P3: 中优先级(8 项)
|
||||
|
||||
| ID | 问题 | 文件 |
|
||||
|----|------|------|
|
||||
| V11-P3-01 | audit-logger.ts 导出但零 import | `desktop/src/lib/audit-logger.ts` |
|
||||
| V11-P3-02 | OFP 能力定义无消费者 | `crates/zclaw-types/src/capability.rs:28-32` |
|
||||
| V11-P3-03 | deprecated extract_structured_facts() 零调用但未移除 | `crates/zclaw-runtime/src/growth.rs:224` |
|
||||
| V11-P3-04 | SaaS knowledge 模块 3 个 handler 返回空数据 | `crates/zclaw-saas/src/knowledge/handlers.rs:91,293,321` |
|
||||
| V11-P3-05 | Director (multi-agent) 912 行 feature-gated 未启用 | `crates/zclaw-kernel/src/director.rs` |
|
||||
| V11-P3-06 | 定时任务执行结果未持久化 | `crates/zclaw-saas/src/scheduler.rs:147-225` |
|
||||
| V11-P3-07 | secure-storage.ts 3 个 deprecated sync 方法零调用 | `desktop/src/lib/secure-storage.ts:309,317,325` |
|
||||
| V11-P3-08 | SaaS config 2 个预留参数未消费 | `crates/zclaw-saas/src/config.rs:122,125` |
|
||||
|
||||
### P4: 低优先级(5 项)
|
||||
|
||||
| ID | 问题 | 文件 |
|
||||
|----|------|------|
|
||||
| V11-P4-01 | ContentBlock 4 处定义(不同域,非 bug 但名称混淆) | types/message.rs, runtime/driver/mod.rs, hands/slideshow.rs, protocols/mcp_types.rs |
|
||||
| V11-P4-02 | Desktop ↔ Admin 13+ 类型名称不一致 | `desktop/src/lib/saas-types.ts` vs `admin-v2/src/types/index.ts` |
|
||||
| V11-P4-03 | 文档数字不一致(Skills 76 vs 66/75/77) | 多个文档 |
|
||||
| V11-P4-04 | A2A/WASM feature-gated 代码未启用 | `crates/zclaw-protocols/src/a2a.rs`, `crates/zclaw-skills/src/wasm_runner.rs` |
|
||||
| V11-P4-05 | embedding 生成已禁用(注释掉) | `crates/zclaw-saas/src/workers/generate_embedding.rs:92` |
|
||||
|
||||
### Info: 保留不变(V10 继承)
|
||||
|
||||
| V10 ID | 状态 | 说明 |
|
||||
|--------|------|------|
|
||||
| DEAD-01 | FALSE_POSITIVE | PromptInjector 已通过 PromptBuilder 接入 |
|
||||
| DEAD-02 | FALSE_POSITIVE | MemoryRetriever 已通过 MemoryMiddleware 接入 |
|
||||
| DEAD-03 | FALSE_POSITIVE | GrowthTracker 已通过 GrowthIntegration 接入 |
|
||||
| SEC-V9-01 | FALSE_POSITIVE | SQL 仅构建 $N 占位符 |
|
||||
|
||||
---
|
||||
|
||||
## 3. Rust Crate 能力矩阵
|
||||
|
||||
| Crate | 源文件 | 行数 | 公开项 | Feature-Gate | Dead Code | Deprecated | 测试 |
|
||||
|-------|--------|------|--------|-------------|-----------|------------|------|
|
||||
| zclaw-types | 10 | 1,741 | 86 | 0 | 0 | 0 | 57 |
|
||||
| zclaw-memory | 5 | 1,333 | 36 | 0 | 0 | 0 | 25 |
|
||||
| zclaw-runtime | 35 | 9,145 | 188 | 0 | 5 | 1 | 42 |
|
||||
| zclaw-kernel | 25 | 8,185 | 225 | 22 (multi-agent) | 3 | 0 | 52 |
|
||||
| zclaw-skills | 15 | 4,057 | 116 | 4 (wasm) | 0 | 0 | 22 |
|
||||
| zclaw-hands | 14 | 7,501 | 140 | 0 | 0 | 0 | 155 |
|
||||
| zclaw-protocols | 5 | 1,697 | 104 | 2 (a2a) | 1 | 0 | 5 |
|
||||
| zclaw-pipeline | 23 | 7,502 | 200 | 0 | 1 | 0 | 59 |
|
||||
| zclaw-growth | 14 | 4,732 | 137 | 0 | 2 | 0 | 66 |
|
||||
| zclaw-saas | 87 | 14,949 | 489 | 0 | 2 | 0 | 17 |
|
||||
| **合计** | **233** | **64,842** | **1,621** | **28** | **14** | **1** | **500** |
|
||||
|
||||
### Trait 实现完整性
|
||||
|
||||
| Trait | 定义位置 | 实现数 | 状态 |
|
||||
|-------|----------|--------|------|
|
||||
| LlmDriver | zclaw-runtime/driver/mod.rs | 4 | 完整 |
|
||||
| Tool | zclaw-runtime/tool.rs | 7 | 完整 |
|
||||
| Hand | zclaw-hands/hand.rs | 9 | 完整 |
|
||||
| Exporter | zclaw-kernel/export/mod.rs | 4 | 完整 |
|
||||
| McpClient | zclaw-protocols/mcp.rs | 2 | 完整 |
|
||||
| A2aClient | zclaw-protocols/a2a.rs | 1 (gated) | Feature-gated |
|
||||
| FactStore | zclaw-memory/fact.rs | **0** | **未实现** |
|
||||
| Worker | zclaw-saas/workers/mod.rs | 7 | 完整 |
|
||||
|
||||
---
|
||||
|
||||
## 4. 数据流验证结果
|
||||
|
||||
### Flow A: 聊天 → 记忆提取 ✅ WORKING
|
||||
|
||||
```
|
||||
chat.rs:246 (LoopEvent::Complete)
|
||||
→ loop_runner.rs:798 (run_after_completion)
|
||||
→ MemoryMiddleware.after_completion (middleware/memory.rs:101)
|
||||
→ GrowthIntegration.extract_combined (growth.rs:279)
|
||||
→ MemoryExtractor.extract + store_memories
|
||||
```
|
||||
|
||||
Tauri `post_conversation_hook` 不重复提取,仅处理心跳+反思。
|
||||
|
||||
### Flow B: 审批 → Hand 自动执行 ✅ WORKING
|
||||
|
||||
```
|
||||
approval.rs:52 → kernel.respond_to_approval (approvals.rs:55)
|
||||
→ tokio::spawn (approvals.rs:71)
|
||||
→ hands.execute (approvals.rs:99)
|
||||
→ emit "hand-execution-complete" (approval.rs:84-137)
|
||||
```
|
||||
|
||||
### Flow C: Pipeline 完成事件 ✅ WORKING
|
||||
|
||||
```
|
||||
Rust emit: discovery.rs:165 → app.emit("pipeline-complete", ...)
|
||||
Frontend listen: pipeline-client.ts:257 → PipelinesPanel.tsx:383
|
||||
```
|
||||
|
||||
### Flow D: SaaS 配置同步 ❌ BROKEN
|
||||
|
||||
```
|
||||
saasStore.ts:484 → saasClient.pullConfig → localStorage write
|
||||
⚠️ 无传播路径到 Rust Kernel
|
||||
```
|
||||
|
||||
配置变更停留在 `localStorage`,Kernel 独立读取 TOML 文件,不受 SaaS 配置同步影响。
|
||||
|
||||
---
|
||||
|
||||
## 5. Admin-v2 审计
|
||||
|
||||
### 页面与 API 对齐
|
||||
|
||||
| 页面 | Service 文件 | API 调用数 | 状态 |
|
||||
|------|-------------|-----------|------|
|
||||
| Login | auth.ts | 2 | 完整 |
|
||||
| Dashboard | stats.ts | 1 | 完整 |
|
||||
| Accounts | accounts.ts | 4 | 完整 |
|
||||
| ModelServices | providers.ts + models.ts | 11 | 完整 |
|
||||
| Config | config.ts | 2 | 完整 |
|
||||
| Relay | relay.ts | 2 | 完整 |
|
||||
| Logs | logs.ts | 1 | 完整 |
|
||||
| Prompts | prompts.ts | 7 | 完整 |
|
||||
| Usage | usage.ts | 2 | 完整 |
|
||||
| Billing | billing.ts | 6 | 完整 |
|
||||
| AgentTemplates | agent-templates.ts | 5 | 完整 |
|
||||
| Knowledge | knowledge.ts | 15 | 完整(后端有 3 个 stub handler) |
|
||||
|
||||
### 类型一致性
|
||||
|
||||
Desktop ↔ Admin-v2 之间存在 13+ 类型名称不一致(详见 V11_GAP_ANALYSIS.md)。
|
||||
|
||||
3 个有意义的字段差异:
|
||||
1. `AccountPublic.llm_routing`: desktop 可选 vs admin 必填
|
||||
2. `TokenInfo` nullability: `string | null` vs `string | undefined`
|
||||
3. `PromptVariable.type`: `string` vs `'string'|'number'|'select'|'boolean'`
|
||||
|
||||
---
|
||||
|
||||
## 6. 孤立路由清单
|
||||
|
||||
| 路由 | 模块 | 原因 |
|
||||
|------|------|------|
|
||||
| POST /api/v1/auth/logout | auth | 无消费者 |
|
||||
| GET /api/v1/config/analysis | migration | 无消费者 |
|
||||
| POST /api/v1/config/seed | migration | 无消费者 |
|
||||
| GET /api/v1/config/sync-logs | migration | 无消费者 |
|
||||
| GET /api/v1/usage (model_config) | model_config | 无消费者 |
|
||||
| GET/POST /api/v1/roles | role | 无 admin-v2 service |
|
||||
| GET/PUT/DELETE /api/v1/roles/:id | role | 无 admin-v2 service |
|
||||
| GET/POST /api/v1/permission-templates | role | 无 admin-v2 service |
|
||||
| GET/DELETE /api/v1/permission-templates/:id | role | 无 admin-v2 service |
|
||||
| POST /api/v1/permission-templates/:id/apply | role | 无 admin-v2 service |
|
||||
| GET /api/v1/roles/:id/permissions | role | 无 admin-v2 service |
|
||||
|
||||
---
|
||||
|
||||
## 7. 验证命令
|
||||
|
||||
```bash
|
||||
# Skills 计数
|
||||
ls skills/ | wc -l # 预期: 76
|
||||
|
||||
# Hands 计数
|
||||
ls hands/ | wc -l # 预期: 9
|
||||
|
||||
# Tauri 命令计数
|
||||
grep -c "#\[tauri::command\]" desktop/src-tauri/src/ -r --include="*.rs" # 预期: 175
|
||||
|
||||
# 死代码验证
|
||||
grep -rn "from.*audit-logger" desktop/src/ --include="*.ts" # 预期: 0 结果
|
||||
|
||||
# 孤立表验证
|
||||
grep -rn "SELECT.*FROM.*prompt_sync_status" crates/zclaw-saas/src/ # 预期: 0 结果
|
||||
grep -rn "SELECT.*FROM.*telemetry_reports" crates/zclaw-saas/src/ # 预期: 0 结果
|
||||
grep -rn "SELECT.*FROM.*key_usage_window" crates/zclaw-saas/src/ # 预期: 0 结果
|
||||
|
||||
# deprecated 函数调用者
|
||||
grep -rn "extract_structured_facts" crates/ --include="*.rs" # 仅定义和注释引用
|
||||
|
||||
# trigger_update 参数不匹配
|
||||
grep -A5 "trigger_update" desktop/src/lib/kernel-triggers.ts
|
||||
grep -A5 "trigger_update" desktop/src-tauri/src/kernel_commands/ -r --include="*.rs"
|
||||
```
|
||||
539
docs/archive/old-audits/COMPREHENSIVE_AUDIT_V5.md
Normal file
@@ -0,0 +1,539 @@
|
||||
# ZCLAW 功能完整性深度审计报告 v5
|
||||
|
||||
> **ARCHIVED — 此报告已过时**
|
||||
>
|
||||
> 本报告是 2026-03-27 审计迭代的 v5 版本。最终结论已合并到 DEEP_AUDIT_REPORT.md。
|
||||
>
|
||||
> **请参考最新文档** → [README.md](./README.md)
|
||||
|
||||
> **审计日期**: 2026-03-27
|
||||
> **修复日期**: 2026-03-27
|
||||
> **审计方法**: 五步审计法(文档对齐 → 数据流追踪 → dead_code 识别 → trait 实现 → 端到端验证)
|
||||
> **审计范围**: 全部 10 个 Rust crate + Tauri 后端(100+ 命令)+ React 前端 + docs/features 28 份文档
|
||||
> **独立性声明**: 本报告独立于此前 4 份审计报告,所有结论基于代码实际状态得出。前审计已修复 27 项,本审计在此基础上发现 8 项新问题,**已全部修复**。
|
||||
|
||||
---
|
||||
|
||||
## 一、执行摘要
|
||||
|
||||
### 1.1 总体完成度
|
||||
|
||||
| 维度 | DEEP_AUDIT 声称 | 本审计验证 | 修复后 |
|
||||
|------|----------------|-----------|--------|
|
||||
| **整体完成度** | ~72% → ~85% | **~78%** | **~82%** |
|
||||
| **核心功能可用** | ~92% | **~92%** | **~95%** |
|
||||
| **智能层真实可用** | ~80% | **~75%** | **~80%** |
|
||||
| **扩展层** | ~80% | **~65%** | **~70%** |
|
||||
|
||||
### 1.2 关键发现
|
||||
|
||||
1. **DEEP_AUDIT 27 项修复:25 项确认到位,2 项部分到位**
|
||||
2. **新发现 8 项问题**(1 CRITICAL + 4 MEDIUM + 3 LOW)— ✅ **已全部修复**
|
||||
3. **~2485 行孤立代码**已通过条件编译处理(Director + A2A 在 `multi-agent` feature 下可用)
|
||||
4. **WhiteboardHand Export** 已标记为 demo
|
||||
5. **Pipeline YAML 模板实际存在**(DEEP_AUDIT M7 误判纠正)
|
||||
|
||||
---
|
||||
|
||||
## 二、DEEP_AUDIT 27 项修复独立验证
|
||||
|
||||
### 2.1 P0 修复(3 项)
|
||||
|
||||
| ID | 修复内容 | 验证结果 | 证据 |
|
||||
|----|---------|---------|------|
|
||||
| C1 | PromptOnly 通过 LlmCompleter 调用 LLM | ✅ CONFIRMED | `skill.rs:96` `llm: Option<Arc<dyn LlmCompleter>>`; `kernel.rs:62` `LlmDriverAdapter` 桥接; `kernel.rs:79` `llm: Some(self.llm.clone())` 注入 SkillContext |
|
||||
| C2 | 反思引擎传入真实记忆 | ✅ CONFIRMED | `intelligence_hooks.rs:79` `query_memories_for_reflection(agent_id).await`; `intelligence_hooks.rs:182-210` 函数实现:查询 VikingStorage 最多 50 条记忆 |
|
||||
| H5 | VERIFICATION_REPORT 归档 | ✅ CONFIRMED | 文件前 10 行标记 `⚠️ ARCHIVED` |
|
||||
|
||||
### 2.2 P1 修复(8 项)
|
||||
|
||||
| ID | 修复内容 | 验证结果 | 证据 |
|
||||
|----|---------|---------|------|
|
||||
| H7 | KernelClient 适配 listClones/createClone/deleteClone | ✅ CONFIRMED | `kernel-client.ts:370-415` 三个方法映射到 `listAgents/createAgent/deleteAgent` |
|
||||
| H8 | hand_execute 检查 needs_approval | ✅ CONFIRMED | `kernel_commands.rs:846-864` 双层检查:supervised 模式全部拦截 + 非 autonomous 模式检查 `needs_approval` |
|
||||
| M1 | 幽灵命令注册 | ✅ CONFIRMED | `lib.rs:1344-1346` `hand_get`/`hand_run_status`/`hand_run_list` 已注册 |
|
||||
| H1 | SpeechHand 标记 demo | ✅ CONFIRMED | `speech.rs:236` 注释 `"In real implementation, would call TTS API"`; DEEP_AUDIT 已标注 |
|
||||
| H2 | TwitterHand 标记 demo | ✅ CONFIRMED | `twitter.rs:297-509` 所有操作返回 `"(simulated)"`; DEEP_AUDIT 已标注 |
|
||||
| H3 | 记忆统一到 VikingStorage | ✅ CONFIRMED | `memory_commands.rs:1-7` 明确声明 "Unified storage: All operations delegate to VikingStorage"; `memory_store()` 第 68 行 `get_storage().await` → `VikingStorage::store()` |
|
||||
| H4 | 心跳持久化 | ✅ CONFIRMED | `heartbeat.rs:459-467` `record_interaction()` 通过 `tokio::spawn` 将时间戳写入 VikingStorage metadata |
|
||||
| H6 | Presentation 渲染器 | ✅ CONFIRMED | 4 个渲染器文件存在:`ChartRenderer.tsx`、`DocumentRenderer.tsx`、`SlideshowRenderer.tsx`、`QuizRenderer.tsx` |
|
||||
|
||||
### 2.3 P2 修复(9 项)
|
||||
|
||||
| ID | 修复内容 | 验证结果 | 证据 |
|
||||
|----|---------|---------|------|
|
||||
| M4b | maybe_compact_with_config 支持 LLM | ✅ CONFIRMED | `compaction.rs:279-299` `if config.use_llm` → 调用 `generate_llm_summary()` → 失败回退 `generate_summary()` |
|
||||
| M4c | 压缩时记忆刷出 | ✅ CONFIRMED | `compaction.rs:228-253` `if config.memory_flush_enabled` → `growth.process_conversation()` |
|
||||
| M4 | 反思结果持久化 | ✅ CONFIRMED | `reflection.rs:611-630` `restore_state()` 从 VikingStorage metadata 恢复; `persist_state()` 持久化 |
|
||||
| M5 | 自主授权后端守卫 | ✅ CONFIRMED | `kernel_commands.rs:680-682` skill_execute supervised 模式拦截; `kernel_commands.rs:828-842` hand_execute 双层守卫 |
|
||||
| M3 | hand_approve 使用 hand_name | ⚠️ PARTIAL | `kernel_commands.rs:1169-1171` 日志记录 hand_name,但 `respond_to_approval(&run_id, ...)` 只用 run_id,hand_name 未参与查找逻辑 |
|
||||
| L2 | gatewayStore 清理 | ✅ CONFIRMED | `gatewayStore.ts` 保留为 re-export facade,多个 store 文件仅引用类型 |
|
||||
| S9 | 消息搜索 Global 模式 | ✅ CONFIRMED | DEEP_AUDIT 声称已修复,MessageSearch 组件存在 |
|
||||
| M6 | RuntimeLlmIntentDriver 语义路由 | ✅ CONFIRMED | `intent.rs:406-464` `RuntimeLlmIntentDriver` 包装 `LlmDriver`,`semantic_match()` 调用 LLM 并解析 JSON 响应 |
|
||||
| L1 | Pipeline 并行 buffer_unordered | ✅ CONFIRMED | `stage.rs:355` `.buffer_unordered(workers)`; `executor.rs:397` 同样使用 |
|
||||
|
||||
### 2.4 P3 修复(7 项)
|
||||
|
||||
| ID | 修复内容 | 验证结果 | 证据 |
|
||||
|----|---------|---------|------|
|
||||
| Reflection LLM | analyze_patterns_with_llm() | ✅ CONFIRMED | `reflection.rs:314-353` 完整实现:构建 memory_summary + LLM prompt + JSON 解析 |
|
||||
| Reflection History | 累积存储 | ✅ CONFIRMED | `intelligence_hooks.rs` 调用 `reflect()` 后结果写入 VikingStorage |
|
||||
| Identity Rollback | HistoryItem + restoreSnapshot | ✅ CONFIRMED | DEEP_AUDIT 声称 IdentityChangeProposal.tsx 已实现 |
|
||||
| autonomy_level | hand_execute/skill_execute 参数 | ✅ CONFIRMED | 两个命令都接受 `autonomy_level: Option<String>` 参数 |
|
||||
| 心跳历史 | VikingStorage metadata | ✅ CONFIRMED | `heartbeat.rs:459-467` 持久化交互时间 |
|
||||
| 记忆统一 | memory_commands 全部委派 | ✅ CONFIRMED | `memory_commands.rs:68` `get_storage().await` → VikingStorage |
|
||||
| 幽灵命令 | hand_get/hand_run_status/hand_run_list | ✅ CONFIRMED | `lib.rs:1344-1346` |
|
||||
|
||||
### 2.5 修复验证总结
|
||||
|
||||
| 结果 | 数量 | 占比 |
|
||||
|------|------|------|
|
||||
| ✅ CONFIRMED(完全确认) | 25 | 93% |
|
||||
| ⚠️ PARTIAL(部分到位) | 2 | 7% |
|
||||
| ❌ REVERTED(回退) | 0 | 0% |
|
||||
|
||||
**部分到位的 2 项**:
|
||||
- **M3**: `hand_approve` 日志记录了 `hand_name`,但实际审批查找只用 `run_id`,`hand_name` 未参与业务逻辑
|
||||
- **S9**: 消息搜索 Global 模式声称已修复,但未深入验证前端是否真正调用 VikingStorage 跨会话搜索
|
||||
|
||||
---
|
||||
|
||||
## 三、新发现问题(前 4 次审计均未发现)
|
||||
|
||||
### 3.1 CRITICAL(1 项)
|
||||
|
||||
#### N1: Whiteboard Hand Export 动作返回伪造 data_url
|
||||
|
||||
| 属性 | 值 |
|
||||
|------|---|
|
||||
| **文件** | `crates/zclaw-hands/src/hands/whiteboard.rs:254-260` |
|
||||
| **差距模式** | 写了没接 |
|
||||
| **严重度** | CRITICAL |
|
||||
| **证据** | `"data:image/{};base64,<rendered_data>"` — 硬编码占位字符串,非真实图片数据 |
|
||||
|
||||
```rust
|
||||
WhiteboardAction::Export { format } => {
|
||||
// In real implementation, would render to image
|
||||
return Ok(HandResult::success(serde_json::json!({
|
||||
"status": "exported",
|
||||
"format": format,
|
||||
"data_url": format!("data:image/{};base64,<rendered_data>", format)
|
||||
})));
|
||||
}
|
||||
```
|
||||
|
||||
**影响**: 用户触发 Whiteboard Hand 的"导出"功能期望获得真实图片,实际获得包含 `<rendered_data>` 占位符的伪造 URL。
|
||||
|
||||
### 3.2 MEDIUM(4 项)
|
||||
|
||||
#### N2: Director 模块(907 行)完全孤立
|
||||
|
||||
| 属性 | 值 |
|
||||
|------|---|
|
||||
| **文件** | `crates/zclaw-kernel/src/director.rs`(907 行) |
|
||||
| **差距模式** | 写了没接 |
|
||||
| **严重度** | MEDIUM |
|
||||
|
||||
**详情**: 实现了完整的多 Agent 协作系统(5 种调度策略、Agent 角色系统、LLM 说话人选择),有 8 个单元测试。从 `lib.rs` 导出为 `pub mod director` + `pub use director::*`,但:
|
||||
- 无 Tauri 命令暴露
|
||||
- 无前端 `invoke()` 调用
|
||||
- `kernel.rs` 不使用 Director
|
||||
- 前端 Team/Swarm UI 已被删除
|
||||
|
||||
#### N3: A2A 协议(690 行)仅被孤立的 Director 消费
|
||||
|
||||
| 属性 | 值 |
|
||||
|------|---|
|
||||
| **文件** | `crates/zclaw-protocols/src/a2a.rs`(690 行) |
|
||||
| **差距模式** | 写了没接 |
|
||||
| **严重度** | MEDIUM |
|
||||
|
||||
**详情**: 实现了完整的 Agent-to-Agent 通信协议(信封、路由、组管理、能力发现)。`a2a.rs:259` 标记 `#[allow(dead_code)]`。唯一消费者是 `director.rs`(本身孤立)。
|
||||
|
||||
#### N4: viking_adapter find() 使用 String.contains()(降级为 LOW)
|
||||
|
||||
| 属性 | 值 |
|
||||
|------|---|
|
||||
| **文件** | `crates/zclaw-growth/src/viking_adapter.rs:160-166` |
|
||||
| **差距模式** | 写了没接 |
|
||||
| **原严重度** | MEDIUM → **降级为 LOW** |
|
||||
|
||||
**纠正**: 经深入追踪,生产环境搜索路径 `intelligence_hooks.rs:112-113` 调用的是 `SqliteStorage.find()`,**不是** `VikingAdapter.find()`。`SqliteStorage.find()` 实现了完整的 TF-IDF + Embedding 混合评分(70% embedding + 30% TF-IDF)。`VikingAdapter` 是一个独立的适配器,当前不被生产路径使用。
|
||||
|
||||
#### N5: compactor_compact_llm 注册但前端无调用
|
||||
|
||||
| 属性 | 值 |
|
||||
|------|---|
|
||||
| **文件** | `desktop/src-tauri/src/lib.rs:1469`(注册) |
|
||||
| **差距模式** | 写了没接 |
|
||||
| **严重度** | MEDIUM |
|
||||
|
||||
**详情**: `compactor_compact_llm` 作为 Tauri 命令注册,但前端 `intelligence-backend.ts` 中无 `invoke('compactor_compact_llm')` 调用。`maybe_compact_with_config()` 在 runtime 层已支持 LLM 自动压缩,所以手动触发路径是冗余的。
|
||||
|
||||
### 3.3 LOW(3 项)
|
||||
|
||||
#### N6: MCP 协议框架无消费者
|
||||
|
||||
| 属性 | 值 |
|
||||
|------|---|
|
||||
| **文件** | `crates/zclaw-protocols/src/mcp.rs` + `mcp_transport.rs`(~588 行) |
|
||||
| **差距模式** | 写了没接 |
|
||||
| **严重度** | LOW |
|
||||
|
||||
**详情**: 完整的 MCP client trait + transport 实现 + `BasicMcpClient`,但无 Tauri 命令、无 kernel 集成、无前端调用。
|
||||
|
||||
#### N7: scheduled_task 调度循环未实现
|
||||
|
||||
| 属性 | 值 |
|
||||
|------|---|
|
||||
| **文件** | `desktop/src-tauri/src/kernel_commands.rs:1301` |
|
||||
| **差距模式** | 写了没接 |
|
||||
| **严重度** | LOW |
|
||||
|
||||
**详情**: 注释明确标注 "not yet implemented in embedded kernel mode"。`scheduled_task_create` 创建 TriggerConfig,`scheduled_task_list` 列出已有触发器,但没有后台调度循环执行它们。
|
||||
|
||||
#### N8: hand_approve 的 hand_name 参数仅用于日志
|
||||
|
||||
| 属性 | 值 |
|
||||
|------|---|
|
||||
| **文件** | `desktop/src-tauri/src/kernel_commands.rs:1158-1182` |
|
||||
| **差距模式** | 接了没传 |
|
||||
| **严重度** | LOW |
|
||||
|
||||
**详情**: `hand_approve` 接收 `hand_name` 参数但仅用于 `tracing::info!` 日志,实际审批操作 `respond_to_approval(&run_id, approved, reason)` 只使用 `run_id`。
|
||||
|
||||
---
|
||||
|
||||
## 四、孤立代码总量
|
||||
|
||||
| 模块 | 行数 | 状态 | 建议 |
|
||||
|------|------|------|------|
|
||||
| `director.rs` | 907 | 完全孤立,无 Tauri 命令 | 条件编译 `#[cfg(feature = "director")]` |
|
||||
| `a2a.rs` | 690 | 仅被孤立的 director 消费 | 跟随 director 处理 |
|
||||
| `mcp.rs` + `mcp_transport.rs` | ~588 | 无消费者 | 保留为框架预留 |
|
||||
| `zclaw-channels` 整个 crate | ~300 | 仅 ConsoleChannel | 维持现状 |
|
||||
| **合计** | **~2485 行** | | |
|
||||
|
||||
---
|
||||
|
||||
## 五、10 条核心数据流追踪
|
||||
|
||||
### 5.1 聊天消息流 ✅ 已验证
|
||||
|
||||
```
|
||||
ChatArea.tsx → chatStore.sendStreamMessage()
|
||||
→ kernel-client.ts sendStreamMessage() → invoke('agent_chat_stream')
|
||||
→ kernel_commands.rs agent_chat_stream()
|
||||
→ intelligence_hooks.rs pre_conversation_hook()
|
||||
→ build_memory_context() → VikingStorage.find() ✅ (SqliteStorage, TF-IDF + Embedding)
|
||||
→ build_identity_prompt() → IdentityManager.build_system_prompt() ✅
|
||||
→ kernel.agent_chat_stream()
|
||||
→ loop_runner.rs AgentLoop (compaction threshold 15k) ✅
|
||||
→ LLM driver (4 implementations) ✅
|
||||
→ intelligence_hooks.rs post_conversation_hook()
|
||||
→ heartbeat.record_interaction() ✅ (VikingStorage metadata)
|
||||
→ reflection.record_conversation() + should_reflect() ✅
|
||||
→ Tauri events ✅
|
||||
→ kernel-client.ts event listener ✅
|
||||
→ ChatArea.tsx render ✅
|
||||
```
|
||||
|
||||
**断点**: 无。完整链路。
|
||||
|
||||
### 5.2 Hand 执行流 ✅ 已验证(含审批 + 自主守卫)
|
||||
|
||||
```
|
||||
HandList.tsx → handStore.triggerHand()
|
||||
→ kernel-client.ts triggerHand() → invoke('hand_execute')
|
||||
→ kernel_commands.rs hand_execute()
|
||||
→ autonomy_level == "supervised" → create_approval → return pending ✅
|
||||
→ autonomy_level != "autonomous" && needs_approval → create_approval → return pending ✅
|
||||
→ kernel.execute_hand() → HandRegistry.get() → Hand.execute()
|
||||
→ [真实] QuizHand, ResearcherHand, CollectorHand, ClipHand ✅
|
||||
→ [委托] BrowserHand → Tauri browser commands ✅
|
||||
→ [模拟] SpeechHand ❌ "In real implementation"
|
||||
→ [模拟] TwitterHand ❌ "(simulated)"
|
||||
→ [模拟] WhiteboardHand(Export) ❌ "In real implementation" (NEW)
|
||||
→ 结果返回 ✅
|
||||
→ handStore 处理结果 ✅
|
||||
→ UI 显示 ✅
|
||||
```
|
||||
|
||||
**断点**: SpeechHand、TwitterHand、WhiteboardHand(Export) 返回模拟数据。
|
||||
|
||||
### 5.3 记忆存储流 ✅ 已验证(统一到 VikingStorage)
|
||||
|
||||
```
|
||||
路径A (UI面板):
|
||||
MemoryPanel.tsx → intelligence-backend.ts memory_store()
|
||||
→ invoke('memory_store') → memory_commands.rs
|
||||
→ get_storage() → VikingStorage::store() (SqliteStorage) ✅
|
||||
|
||||
路径B (聊天流程):
|
||||
intelligence_hooks.rs build_memory_context()
|
||||
→ get_storage() → VikingStorage::find() (SqliteStorage)
|
||||
→ TF-IDF + Embedding hybrid scoring ✅
|
||||
```
|
||||
|
||||
**断点**: 无。双路径统一到同一 SqliteStorage 实例。
|
||||
|
||||
### 5.4 技能执行流 ✅ 已验证
|
||||
|
||||
```
|
||||
SkillMarket.tsx → kernel-client.ts executeSkill()
|
||||
→ invoke('skill_execute') → kernel_commands.rs skill_execute()
|
||||
→ autonomy guard ✅
|
||||
→ kernel.execute_skill() → SkillRegistry → SkillExecutor
|
||||
→ PromptOnlySkill → SkillContext.llm (Some(LlmDriverAdapter))
|
||||
→ LlmCompleter.complete() → LLM driver → AI 生成内容 ✅
|
||||
→ ShellSkill → subprocess ✅
|
||||
→ WasmSkill/NativeSkill → 回退到 PromptOnly ✅
|
||||
```
|
||||
|
||||
**断点**: WasmSkill/NativeSkill 回退到 PromptOnly(已知,非阻塞)。
|
||||
|
||||
### 5.5 Pipeline 执行流 ✅ 已验证
|
||||
|
||||
```
|
||||
PipelinesPanel.tsx → workflowStore → invoke('pipeline_run')
|
||||
→ pipeline_commands.rs → StageEngine
|
||||
→ Parallel stage: buffer_unordered(max_workers) ✅
|
||||
→ Sequential/Conditional/Skill/Hand stages ✅
|
||||
→ 5 YAML templates exist in pipelines/ directory ✅
|
||||
```
|
||||
|
||||
**断点**: 无。
|
||||
|
||||
### 5.6 反思流 ✅ 已验证
|
||||
|
||||
```
|
||||
post_conversation_hook → record_conversation()
|
||||
→ should_reflect() → 阈值检查
|
||||
→ query_memories_for_reflection() → VikingStorage (max 50) ✅
|
||||
→ reflect(agent_id, &memories, llm_driver)
|
||||
→ use_llm && driver → analyze_patterns_with_llm() ✅
|
||||
→ fallback → analyze_patterns() (rule-based) ✅
|
||||
→ persist_state() → VikingStorage metadata ✅
|
||||
```
|
||||
|
||||
**断点**: 反思结果在 VikingStorage 中,但需确认 ReflectionLog.tsx 是否展示持久化的历史数据。
|
||||
|
||||
### 5.7 心跳流 ⚠️ 部分验证
|
||||
|
||||
```
|
||||
App.tsx → heartbeat.start()
|
||||
→ tokio spawn → tick loop (30 min interval)
|
||||
→ check_pending_tasks / check_memory_health / check_reflection_readiness
|
||||
→ record_interaction() → VikingStorage metadata ✅
|
||||
→ history restore on restart ✅
|
||||
```
|
||||
|
||||
**断点**: 默认 `enabled: false`(`heartbeat.rs` 配置),但 `App.tsx` 主动调用 `start()`。
|
||||
|
||||
### 5.8 身份演化流 ✅ 已验证
|
||||
|
||||
```
|
||||
build_identity_prompt() → IdentityManager.build_system_prompt()
|
||||
→ SOUL.md 读取 → 注入 system prompt → 聊天
|
||||
```
|
||||
|
||||
### 5.9 上下文压缩流 ✅ 已验证
|
||||
|
||||
```
|
||||
loop_runner → maybe_compact_with_config()
|
||||
→ memory_flush_enabled → growth.process_conversation() ✅
|
||||
→ use_llm → generate_llm_summary() → fallback generate_summary() ✅
|
||||
→ 消息替换 ✅
|
||||
```
|
||||
|
||||
### 5.10 审批流 ✅ 已验证
|
||||
|
||||
```
|
||||
HandApprovalModal.tsx → invoke('hand_approve')
|
||||
→ kernel_commands.rs → respond_to_approval(&run_id, approved, reason) ✅
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 六、5 种差距模式分析
|
||||
|
||||
### 模式 1: "写了没接"(Code exists but not integrated)
|
||||
|
||||
| 实例 | 文件 | 行数 | 严重度 |
|
||||
|------|------|------|--------|
|
||||
| Director 模块 | `zclaw-kernel/src/director.rs` | 907 | MEDIUM |
|
||||
| A2A 协议 | `zclaw-protocols/src/a2a.rs` | 690 | MEDIUM |
|
||||
| MCP 协议 | `zclaw-protocols/src/mcp.rs` | ~588 | LOW |
|
||||
| compactor_compact_llm | `lib.rs:1469` 注册无调用 | ~50 | MEDIUM |
|
||||
| WhiteboardHand Export | `hands/whiteboard.rs:254` | ~10 | CRITICAL |
|
||||
| zclaw-channels | 整个 crate | ~300 | LOW |
|
||||
| SpeechHand | `hands/speech.rs:236` | 模拟 | LOW (已标注) |
|
||||
| TwitterHand | `hands/twitter.rs:297` | 模拟 | LOW (已标注) |
|
||||
| scheduled_task 调度循环 | `kernel_commands.rs:1301` | ~50 | LOW |
|
||||
|
||||
**系统建议**: 孤立代码总量 ~2485 行。建议按功能分组决策:Director+A2A 一起处理,MCP 独立保留,channels 维持现状。
|
||||
|
||||
### 模式 2: "接了没传"(Connected but parameter ignored)
|
||||
|
||||
| 实例 | 文件 | 详情 |
|
||||
|------|------|------|
|
||||
| hand_approve hand_name | `kernel_commands.rs:1158` | hand_name 仅用于日志,未参与审批查找 |
|
||||
|
||||
### 模式 3: "传了没存"(Passed but not persisted)
|
||||
|
||||
| 实例 | 状态 |
|
||||
|------|------|
|
||||
| 心跳 record_interaction | ✅ 已修复 — 写入 VikingStorage metadata |
|
||||
| 反思结果 | ✅ 已修复 — 写入 VikingStorage metadata |
|
||||
|
||||
### 模式 4: "存了没用"(Stored but not used)
|
||||
|
||||
| 实例 | 详情 |
|
||||
|------|------|
|
||||
| 反思结果持久化 | 存入 VikingStorage metadata,需确认 ReflectionLog.tsx 是否读取展示 |
|
||||
|
||||
### 模式 5: "双系统不同步"(Dual systems diverge)
|
||||
|
||||
| 实例 | 状态 |
|
||||
|------|------|
|
||||
| 记忆双存储路径 | ✅ 已修复 — 统一到 VikingStorage (SqliteStorage) |
|
||||
|
||||
---
|
||||
|
||||
## 七、跨部门专家头脑风暴
|
||||
|
||||
### 议题 1: Whiteboard Hand Export 伪造数据(N1)
|
||||
|
||||
**产品视角**: 用户触发"导出"期望真实图片。伪造 data_url 会导致用户困惑和信任损失。建议 UI 标注"导出功能开发中"。
|
||||
**工程视角**: WhiteboardHand 是纯状态管理器(记录 draw/undo 操作),缺少 Canvas 渲染引擎。修复需集成前端 Canvas 渲染 + toDataURL 导出,或 Rust 端渲染库(如 resvg)。
|
||||
**安全视角**: 无安全风险(纯本地操作)。
|
||||
**架构视角**: Whiteboard 的设计是"操作记录器"而非"渲染器"。如果要实现真实导出,需要在 Rust 端或前端添加渲染层。
|
||||
**决策**: **短期标注 + 长期实现** — UI 标注"导出功能开发中",长期在前端实现 Canvas 渲染 + 导出。
|
||||
|
||||
### 议题 2: Director + A2A 孤立代码(N2+N3,~1597 行)
|
||||
|
||||
**产品视角**: 多 Agent 协作是未来功能,当前无用户需求。但代码质量高、测试覆盖好,删除可惜。
|
||||
**工程视角**: Director 有 8 个单元测试,A2A 有 5 个单元测试。代码逻辑完整。但导出为 pub API 会增加编译时间和二进制大小。
|
||||
**架构视角**: Team/Swarm UI 已删除,Director 成为死代码。建议用条件编译控制,而非删除。
|
||||
**决策**: **条件编译** — 添加 `#[cfg(feature = "multi-agent")]` 到 `lib.rs` 导出。默认不编译,需要时通过 Cargo feature 启用。
|
||||
|
||||
### 议题 3: compactor_compact_llm 冗余命令(N5)
|
||||
|
||||
**产品视角**: 用户不需要手动触发 LLM 压缩,自动压缩(runtime 层)已足够。
|
||||
**工程视角**: 两条 LLM 压缩路径(runtime 自动 + Tauri 手动)增加维护负担。runtime 的 `maybe_compact_with_config()` 已支持 LLM + 回退。
|
||||
**决策**: **删除冗余命令** — 从 `lib.rs` 移除 `compactor_compact_llm` 注册,统一使用 runtime 自动路径。
|
||||
|
||||
### 议题 4: MCP 协议框架(N6,~588 行)
|
||||
|
||||
**产品视角**: MCP 是 AI Agent 互操作的标准协议,长期有战略价值。保留框架为未来集成做准备。
|
||||
**工程视角**: 代码是干净的 trait + transport 实现,编译开销小。
|
||||
**决策**: **保留** — 作为预留功能框架,不影响当前使用。
|
||||
|
||||
### 议题 5: scheduled_task 调度循环(N7)
|
||||
|
||||
**产品视角**: 定时任务对 Hands 自动化很重要。当前只能创建触发器但不能自动执行。
|
||||
**工程视角**: 需要实现后台调度循环(tokio interval + trigger evaluation)。`kernel_commands.rs` 已有创建/列出逻辑,只需添加执行循环。
|
||||
**决策**: **保留命令 + 标注为计划中** — 当前触发器系统完整,调度循环是下一步。
|
||||
|
||||
---
|
||||
|
||||
## 八、功能完成度矩阵(修正版)
|
||||
|
||||
### 8.1 架构层
|
||||
|
||||
| 功能 | 文档声称 | 本审计结果 | 差距 |
|
||||
|------|----------|-----------|------|
|
||||
| **通信层** | L4 (85%) | **L4 (85%)** | 无 |
|
||||
| **状态管理** | L4 (85%) | **L4 (80%)** | gatewayStore 仍存在(兼容层) |
|
||||
| **安全认证** | L4 (80%) | **L4 (80%)** | 无 |
|
||||
|
||||
### 8.2 核心功能层
|
||||
|
||||
| 功能 | 文档声称 | 本审计结果 | 差距 |
|
||||
|------|----------|-----------|------|
|
||||
| **聊天界面** | L4 (85%) | **L4 (85%)** | 无 |
|
||||
| **Agent 分身** | L4 (90%) | **L4 (85%)** | updateClone 抛异常 |
|
||||
| **Hands 系统** | L4 (70%) | **L3 (55%)** | 3/9 Hands 模拟实现(含 Whiteboard Export 新发现) |
|
||||
|
||||
### 8.3 智能层
|
||||
|
||||
| 功能 | 文档声称 | 本审计结果 | 差距 |
|
||||
|------|----------|-----------|------|
|
||||
| **Agent 记忆** | L4 (90%) | **L4 (85%)** | SqliteStorage 搜索完整(TF-IDF + Embedding) |
|
||||
| **身份演化** | L2 (70%) | **L2 (70%)** | 回滚 UI 已实现 |
|
||||
| **反思引擎** | L2 (65%) | **L2 (65%)** | LLM 路径存在但需 use_llm=true |
|
||||
| **心跳引擎** | L2 (70%) | **L2 (60%)** | 默认禁用,持久化已修复 |
|
||||
| **自主授权** | L2 (75%) | **L2 (70%)** | 后端守卫已实现 |
|
||||
| **上下文压缩** | L2 (75%) | **L2 (70%)** | LLM + 记忆刷出已集成 |
|
||||
|
||||
### 8.4 扩展层
|
||||
|
||||
| 功能 | 文档声称 | 本审计结果 | 差距 |
|
||||
|------|----------|-----------|------|
|
||||
| **技能系统** | L3 (80%) | **L3 (75%)** | PromptOnly 通过 LlmCompleter 调用 LLM ✅ |
|
||||
| **智能路由** | L1 (15%) | **L2 (60%)** | RuntimeLlmIntentDriver 已实现 ✅ |
|
||||
| **Pipeline DSL** | L2 (75%) | **L2 (75%)** | 并行执行、YAML 模板均正常 |
|
||||
| **OpenViking** | L3 (70%) | **L3 (65%)** | SqliteStorage 搜索质量好 |
|
||||
| **Browser 自动化** | L3 (80%) | **L3 (80%)** | Fantoccini 集成完整 |
|
||||
| **Channels** | — | **L0 (10%)** | 仅 ConsoleChannel |
|
||||
|
||||
---
|
||||
|
||||
## 九、优先级修复矩阵
|
||||
|
||||
| 优先级 | ID | 问题 | 工作量 | 建议 |
|
||||
|--------|-----|------|--------|------|
|
||||
| **P1** | N1 | WhiteboardHand Export 伪造 data_url | 2h | UI 标注"开发中" |
|
||||
| **P2** | N2+N3 | Director + A2A 孤立(1597 行) | 1d | 条件编译 `#[cfg(feature)]` |
|
||||
| **P2** | N5 | compactor_compact_llm 冗余 | 1h | 删除冗余命令注册 |
|
||||
| **P2** | M3 | hand_approve hand_name 未参与业务逻辑 | 2h | 实现 hand_name + run_id 联合查找 |
|
||||
| **P3** | N6 | MCP 协议无消费者 | — | 保留为框架预留 |
|
||||
| **P3** | N7 | scheduled_task 调度循环 | 2-3d | 后续迭代实现 |
|
||||
| **P3** | N8 | hand_approve hand_name 日志-only | 1h | 随 M3 一起修复 |
|
||||
| **P3** | N4 | viking_adapter 文本匹配 | — | 已降级为 LOW,不影响生产 |
|
||||
|
||||
---
|
||||
|
||||
## 十、审计命令速查
|
||||
|
||||
```bash
|
||||
# Dead code 扫描(28 处已知)
|
||||
rg '#\[allow\(dead_code\)\]' crates/ desktop/src-tauri/ -B 1 -A 3 --type rust
|
||||
|
||||
# 模拟代码扫描(3 个已知)
|
||||
rg 'simulated|In real implementation' crates/ desktop/src-tauri/ --type rust -n -i
|
||||
|
||||
# Tauri 命令注册 vs 前端调用 交叉验证
|
||||
rg "generate_handler\!\[" desktop/src-tauri/src/lib.rs -A 200 | grep "::" | sort -u > /tmp/registered.txt
|
||||
rg "invoke\(['\"]" desktop/src/ -o --type ts | sed "s/.*['\"]//;s/['\"].*//" | sort -u > /tmp/called.txt
|
||||
comm -23 /tmp/registered.txt /tmp/called.txt # 注册但未调用
|
||||
comm -13 /tmp/registered.txt /tmp/called.txt # 调用但未注册
|
||||
|
||||
# 孤立模块行数统计
|
||||
wc -l crates/zclaw-kernel/src/director.rs crates/zclaw-protocols/src/a2a.rs crates/zclaw-protocols/src/mcp.rs crates/zclaw-protocols/src/mcp_transport.rs
|
||||
|
||||
# SqliteStorage 搜索路径确认
|
||||
rg "VikingStorage::find" desktop/src-tauri/src/ --type rust -n
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 十一、结论
|
||||
|
||||
ZCLAW 的核心架构(通信、状态管理、安全认证、聊天、Agent 管理)**坚实可靠**。DEEP_AUDIT 的 27 项修复基本到位(93% 完全确认),显著提升了系统真实可用率。
|
||||
|
||||
**主要问题集中在**:
|
||||
1. **WhiteboardHand Export** 是新发现的模拟实现(CRITICAL)
|
||||
2. **~2485 行孤立代码**(Director + A2A + MCP + channels)需要架构决策
|
||||
3. **hand_approve** 的 `hand_name` 参数仅用于日志(LOW)
|
||||
4. **compactor_compact_llm** 是冗余的 Tauri 命令(MEDIUM)
|
||||
|
||||
**系统真实可用率**: ~78%(核心功能 ~92%,扩展层 ~65%)
|
||||
|
||||
**建议优先级**: P1 标注 WhiteboardHand → P2 条件编译孤立代码 + 删除冗余命令 → P3 后续迭代
|
||||
|
||||
---
|
||||
|
||||
**审计人**: Claude AI Agent (独立审计)
|
||||
**审计日期**: 2026-03-27
|
||||
**下次审计建议**: 3 个月后或重大版本发布前
|
||||
364
docs/archive/old-audits/COMPREHENSIVE_AUDIT_V6.md
Normal file
@@ -0,0 +1,364 @@
|
||||
# ZCLAW SaaS + Tauri 系统性功能审计报告 v6
|
||||
|
||||
> **ARCHIVED — 此报告已过时**
|
||||
>
|
||||
> 本报告是 2026-03-27 审计迭代的 v6 版本。最终结论已合并到 DEEP_AUDIT_REPORT.md。
|
||||
>
|
||||
> **请参考最新文档** → [README.md](./README.md)
|
||||
|
||||
> **审计日期**: 2026-03-27 (原文标注 2026)
|
||||
> **审计范围**: Main 分支 Tauri 端 + SaaS worktree(`.claude/worktrees/saas-backend/`)
|
||||
> **审计方法**: 3 并行 Agent,覆盖功能对齐、SaaS 差距、Trait 实现、差距模式、Dead Code、E2E 数据流
|
||||
> **前次审计**: v5(累计修复 27 项,整体完成度 ~78%)
|
||||
|
||||
---
|
||||
|
||||
## 一、执行摘要
|
||||
|
||||
| 指标 | 数值 |
|
||||
|------|------|
|
||||
| **Tauri 注册命令** | 137 |
|
||||
| **文档功能数** | 17 |
|
||||
| **功能-代码对齐率** | 100%(17/17 有对应命令+UI) |
|
||||
| **SaaS 能力覆盖** | 5/5(100%)— auth + relay + config + devices + usage(设计定位:系统管理) |
|
||||
| **Trait 总数** | 26 |
|
||||
| **零实现 Trait** | 6(23%) |
|
||||
| **Dead Code** | ~4,228 行(5 个孤立模块) |
|
||||
| **`#[allow(dead_code)]`** | 28 处 |
|
||||
| **TODO/FIXME** | 6 处(无 FIXME/HACK/XXX) |
|
||||
| **五种差距模式总计** | 17 个问题 |
|
||||
| **E2E 流程验证** | 5 条流程,2 条有 CRITICAL GAP |
|
||||
|
||||
### 与 v5 审计对比
|
||||
|
||||
| 维度 | v5 | v6(本次) | 变化 |
|
||||
|------|-----|-----|------|
|
||||
| 整体完成度 | ~78% | ~78%(Tauri),100%(SaaS 管理职责) | SaaS 定位修正 |
|
||||
| 功能对齐 | 未量化 | 100% | 新增量化 |
|
||||
| Trait 覆盖 | 未审计 | 77%(20/26 有实现) | 新增审计 |
|
||||
| Dead Code | 已部分清理 | ~4,228 行孤立 | 新增精确统计 |
|
||||
| E2E 验证 | 未执行 | 5 条流程追踪 | 新增验证 |
|
||||
|
||||
---
|
||||
|
||||
## 二、功能-代码对齐矩阵
|
||||
|
||||
### 2.1 功能清单(17 个文档功能)
|
||||
|
||||
| # | 功能 | 文档成熟度 | Tauri 命令数 | 前端 invoke | UI 集成 | 差距 |
|
||||
|---|------|-----------|-------------|------------|---------|------|
|
||||
| 1 | 通信层 | L4 | 9 | kernel-client.ts | KernelClient + GatewayClient | 无 |
|
||||
| 2 | 状态管理 | L4 | N/A(Store) | N/A | 18+ Zustand stores | 无 |
|
||||
| 3 | 安全认证 | L4 | 4 | secure-storage.ts | Ed25519 + OS Keyring | 无 |
|
||||
| 4 | 聊天界面 | L4 | 2 | kernel-client.ts | ChatArea, MessageItem | 无 |
|
||||
| 5 | Agent 分身 | L4 | 4 | kernel-client.ts | AgentSelector | 无 |
|
||||
| 6 | Hands 系统 | L4 | 7 | kernel-client.ts | HandList, HandTaskPanel | 2/11 未实现 |
|
||||
| 7 | Agent 记忆 | L4 | 13 | intelligence-backend.ts | MemoryPanel, MemoryGraph | 无 |
|
||||
| 8 | 身份演化 | L4 | 14 | intelligence-backend.ts | AgentOnboardingWizard | 无 |
|
||||
| 9 | 自我反思 | L4 | 6 | intelligence-backend.ts | ReflectionLog.tsx | 文档有 L2 矛盾标注 |
|
||||
| 10 | 心跳巡检 | L4 | 10 | intelligence-backend.ts | IntelligenceStore | 无 |
|
||||
| 11 | 自主授权 | L4 | 0(TS only) | N/A | AutonomyConfig.tsx | 无 Rust 后端 |
|
||||
| 12 | 上下文压缩 | L3 | 4 | intelligence-backend.ts | AgentLoop 集成 | LLM 摘要未实现 |
|
||||
| 13 | OpenViking | L4 | 13 | App.tsx | viking-client.ts | 无 |
|
||||
| 14 | 技能系统 | L4 | 3 | kernel-client.ts | SkillMarket | PythonSkill 未实例化 |
|
||||
| 15 | Hands 详情 | L4 | 7+23 | browser-client.ts | HandList + BrowserPanel | 无 |
|
||||
| 16 | Tauri 后端 | L4 | 137 | 6 个 client 文件 | 全集成 | 无 |
|
||||
| 17 | Pipeline DSL | L4 (90%) | 10 | pipeline-client.ts | PipelinesPanel | skill/hand stage 失败 |
|
||||
|
||||
**结论**: Tauri 端功能-代码对齐率 100%。所有 17 个文档功能都有对应的 Tauri 命令注册和前端调用。
|
||||
|
||||
---
|
||||
|
||||
## 三、SaaS-Tauri 功能差距矩阵
|
||||
|
||||
> **设计定位(v6.1 更新)**: SaaS 后端**不是 Tauri 功能的云端复制品**。SaaS 仅负责系统管理工作:账号管理、功能权限控制、大模型中转(Relay)。Agent 管理、技能执行、Hand 执行、Pipeline、记忆系统、智能层、浏览器自动化等核心 AI 能力**始终在 Tauri 桌面端本地运行**,不会迁移到 SaaS 端。因此原报告中标记为 "CRITICAL" 的 9 个差距项已重新分类。
|
||||
|
||||
### 3.1 能力域对照
|
||||
|
||||
| # | 能力域 | Tauri 端 | SaaS 端 | 差距状态 | 说明 |
|
||||
|---|--------|---------|---------|---------|------|
|
||||
| 1 | 用户认证 | 本地 IPC,Ed25519 设备密钥 | JWT + Argon2 + TOTP 2FA,RBAC | **对等**(模型不同) | 各自负责各自场景 |
|
||||
| 2 | LLM 调用 | 8 个直接 LlmDriver | OpenAI 兼容 Relay 代理 | **部分**(仅 relay) | SaaS 做 relay 中转 |
|
||||
| 3 | Agent 管理 | 9 个 kernel 命令,SQLite | **不需要** | **N/A** | 本地能力,不迁移到 SaaS |
|
||||
| 4 | 技能执行 | skill_list/refresh/execute,69 SKILL.md | **不需要** | **N/A** | 本地能力,不迁移到 SaaS |
|
||||
| 5 | Hand 执行 | 7 命令 + 审批流程 | **不需要** | **N/A** | 本地能力,不迁移到 SaaS |
|
||||
| 6 | Pipeline | 10 命令,8 action 类型 | **不需要** | **N/A** | 本地能力,不迁移到 SaaS |
|
||||
| 7 | 记忆系统 | 13 命令,SQLite + FTS5 | **不需要** | **N/A** | 本地能力,不迁移到 SaaS |
|
||||
| 8 | 智能层 | 43 命令(心跳/反思/身份/压缩) | **不需要** | **N/A** | 本地能力,不迁移到 SaaS |
|
||||
| 9 | 浏览器自动化 | 23 个 browser_* 命令 | **不需要** | **N/A** | 本地能力,不迁移到 SaaS |
|
||||
| 10 | OpenViking | 13 个 viking_* 命令 | **不需要** | **N/A** | 本地能力,不迁移到 SaaS |
|
||||
| 11 | 配置同步 | 无专用机制 | config diff/sync API | **SaaS 独有** | SaaS 管理职责 |
|
||||
| 12 | 设备管理 | 无 | devices 表 + 心跳 | **SaaS 独有** | SaaS 管理职责 |
|
||||
| 13 | 用量追踪 | 无 | usage_records + stats | **SaaS 独有** | SaaS 管理职责 |
|
||||
| 14 | 审计日志 | 无 | operation_logs | **SaaS 独有** | SaaS 管理职责 |
|
||||
|
||||
### 3.2 SaaS 后端现状
|
||||
|
||||
**框架**: Axum (Rust HTTP) + SQLite (sqlx) + JWT + Argon2
|
||||
|
||||
**API 模块** (40+ 端点):
|
||||
- `auth/` — 注册/登录/JWT 刷新/TOTP 2FA
|
||||
- `account/` — 用户 CRUD、API Token、操作日志、仪表盘
|
||||
- `model_config/` — Provider/Model CRUD、用户 API Key、用量统计
|
||||
- `relay/` — OpenAI 兼容 chat relay(流式+非流式)
|
||||
- `migration/` — 配置 diff/sync
|
||||
|
||||
**数据库**: 13 张表,含 accounts, providers, models, relay_tasks, devices, config_items, usage_records
|
||||
|
||||
**SaaS 前端**: `saas-client.ts`(563 行)+ `saasStore.ts`(467 行),无专属 UI 组件
|
||||
|
||||
**Main 分支**: 零 SaaS 代码合并
|
||||
|
||||
### 3.3 合并风险评估
|
||||
|
||||
| 风险 | 等级 | 说明 |
|
||||
|------|------|------|
|
||||
| SaaS 功能缺失 | **LOW** | SaaS 定位为管理系统(账号/权限/relay),不需要复制 Tauri 端 AI 能力 |
|
||||
| 架构耦合 | **MEDIUM** | Tauri 端 137 个命令全部依赖 `invoke()` + `State<'_>` + `AppHandle`,无法直接迁移到 HTTP API |
|
||||
| 双通信路径 | **MEDIUM** | KernelClient(Tauri IPC)和 GatewayClient(WebSocket)并存,SaaS 需要第三条路径 |
|
||||
| 类型一致性 | **LOW** | 共享 zclaw-types crate,类型定义一致 |
|
||||
|
||||
### 3.4 SaaS 待完善项(按设计定位)
|
||||
|
||||
| # | 功能 | 优先级 | 说明 |
|
||||
|---|------|--------|------|
|
||||
| 1 | Relay 多模型支持 | P1 | 当前仅支持 OpenAI 兼容格式,需扩展其他 provider |
|
||||
| 2 | 用户权限细化 | P1 | RBAC 基础已有,需细粒度功能权限控制 |
|
||||
| 3 | Admin UI | P1 | SaaS 管理后台(已有设计规格) |
|
||||
| 4 | 用量计费 | P2 | usage_records 已有表结构,需计费逻辑 |
|
||||
| 5 | 多设备同步 | P2 | devices 表已有,需实现配置/Token 同步 |
|
||||
|
||||
---
|
||||
|
||||
## 四、Trait 实现矩阵
|
||||
|
||||
### 4.1 完整 26 Trait 清单
|
||||
|
||||
| # | Trait | Crate | 生产实现数 | 测试实现 | 零实现? | 严重性 |
|
||||
|---|-------|-------|-----------|---------|---------|--------|
|
||||
| 1 | `LlmDriver` | zclaw-runtime | 4 | 0 | -- | -- |
|
||||
| 2 | `Tool` | zclaw-runtime | 5 | 0 | -- | -- |
|
||||
| 3 | `SkillExecutor` | zclaw-runtime | 1 | 0 | -- | -- |
|
||||
| 4 | `LlmCompleter` | zclaw-skills | 1 | 0 | -- | -- |
|
||||
| 5 | `Skill` | zclaw-skills | 3 | 0 | -- | -- |
|
||||
| 6 | `SkillGraphExecutor` | zclaw-skills | 1 | 0 | -- | -- |
|
||||
| 7 | `OrchestrationPlanner` | zclaw-skills | 1 | 0 | -- | -- |
|
||||
| 8 | `Hand` | zclaw-hands | 9 | 0 | -- | -- |
|
||||
| 9 | `QuizGenerator` | zclaw-hands | 2 | 0 | -- | -- |
|
||||
| 10 | **`Trigger`** | zclaw-hands | **0** | **0** | **YES** | **CRITICAL** |
|
||||
| 11 | `VikingStorage` | zclaw-growth | 2 | 0 | -- | -- |
|
||||
| 12 | `EmbeddingClient` | zclaw-growth | 2 | 0 | -- | -- |
|
||||
| 13 | **`LlmDriverForExtraction`** | zclaw-growth | **0** | **1** | **YES** | **HIGH** |
|
||||
| 14 | `SummaryLlmDriver` | zclaw-growth | 1 | 2 | -- | -- |
|
||||
| 15 | `McpClient` | zclaw-protocols | 2 | 0 | -- | -- |
|
||||
| 16 | `A2aClient` | zclaw-protocols | 1 | 0 | -- | -- |
|
||||
| 17 | `Exporter` | zclaw-kernel | 4 | 0 | -- | -- |
|
||||
| 18 | `Channel` | zclaw-channels | 1 | 0 | -- | -- |
|
||||
| 19 | `LlmActionDriver` | zclaw-pipeline | 1 | 0 | -- | -- |
|
||||
| 20 | **`SkillActionDriver`** | zclaw-pipeline | **0** | **0** | **YES** | **CRITICAL** |
|
||||
| 21 | **`HandActionDriver`** | zclaw-pipeline | **0** | **0** | **YES** | **CRITICAL** |
|
||||
| 22 | `OrchestrationActionDriver` | zclaw-pipeline | 1 | 0 | -- | -- |
|
||||
| 23 | `LlmIntentDriver` | zclaw-pipeline | 1 | 0 | -- | -- |
|
||||
| 24 | **`StageLlmDriver`** | zclaw-pipeline | **0** | **0** | **YES** | **CRITICAL** |
|
||||
| 25 | **`StageSkillDriver`** | zclaw-pipeline | **0** | **0** | **YES** | **CRITICAL** |
|
||||
| 26 | **`StageHandDriver`** | zclaw-pipeline | **0** | **0** | **YES** | **CRITICAL** |
|
||||
|
||||
**统计**: 26 trait 中 6 个零实现(23%),1 个仅测试实现(4%),19 个有生产实现(73%)
|
||||
|
||||
### 4.2 ActionRegistry 接线状态
|
||||
|
||||
| Driver 槽位 | Builder 方法 | 是否接线 | 影响 |
|
||||
|------------|-------------|---------|------|
|
||||
| `llm_driver` | `.with_llm_driver()` | **已接线** | LLM stage 正常工作 |
|
||||
| `skill_registry` | `.with_skill_registry()` | **未接线** | skill stage 必然失败 |
|
||||
| `hand_registry` | `.with_hand_registry()` | **未接线** | hand stage 必然失败 |
|
||||
| `orchestration_driver` | `.with_orchestration_driver()` | **未接线**(有实现) | orchestration stage 无法使用 |
|
||||
|
||||
**位置**: `desktop/src-tauri/src/pipeline_commands.rs:701-711`
|
||||
|
||||
---
|
||||
|
||||
## 五、五种差距模式
|
||||
|
||||
### 5.1 量化总表
|
||||
|
||||
| # | 差距模式 | 数量 | 严重性 | 关键实例 |
|
||||
|---|---------|------|--------|---------|
|
||||
| 1 | 写了没接 | 8 | **HIGH** | Director(907行), Export(2,319行), A2A(690行), MCP Client, Channels, GrowthIntegration |
|
||||
| 2 | 接了没传 | 4 | MEDIUM | kernel_status 返回桩数据, viking_tree 忽略 depth 参数 |
|
||||
| 3 | 传了没存 | 0 | -- | 智能层持久化完整 |
|
||||
| 4 | 存了没用 | 2 | MEDIUM | GrowthIntegration 死代码路径, Export 系统不可达 |
|
||||
| 5 | 双系统不同步 | 3 | **HIGH** | intelligence_hooks vs GrowthIntegration, SkillExecutor vs StageSkillDriver |
|
||||
| | **总计** | **17** | | |
|
||||
|
||||
### 5.2 Pattern 1: "写了没接" 详情
|
||||
|
||||
| 模块 | 位置 | 行数 | Tauri 可达? | 说明 |
|
||||
|------|------|------|------------|------|
|
||||
| Director | `crates/zclaw-kernel/src/director.rs` | 907 | **否** | 多 Agent 编排,完全孤立 |
|
||||
| Export 系统 | `crates/zclaw-kernel/src/export/*.rs` | 2,319 | **否** | 4 个 Exporter 实现,无 Tauri 命令 |
|
||||
| A2A 协议 | `crates/zclaw-protocols/src/a2a.rs` | 690 | **否** | feature-gated 但从未激活 |
|
||||
| MCP Client | `crates/zclaw-protocols/src/mcp.rs` | 588 | **否** | 2 个实现,0 个 Tauri 消费者 |
|
||||
| zclaw-channels | `crates/zclaw-channels/src/` | 290 | **否** | ConsoleChannel 无消费者 |
|
||||
| GrowthIntegration | `crates/zclaw-runtime/src/growth.rs` | 315 | **部分** | 定义完整,被 intelligence_hooks 绕过 |
|
||||
| 定时任务调度器 | `desktop/src-tauri/src/kernel_commands.rs` | -- | **半接线** | 命令注册但无调度循环 |
|
||||
|
||||
### 5.3 Pattern 5: "双系统不同步" 详情
|
||||
|
||||
| 实例 | 路径 A | 路径 B | 影响 |
|
||||
|------|--------|--------|------|
|
||||
| 记忆增强 | `intelligence_hooks::build_memory_context()`(活跃) | `GrowthIntegration::enhance_prompt()`(死代码) | 功能重叠但不一致,GrowthIntegration 永远不会执行 |
|
||||
| 技能执行 | `Kernel::execute_skill()` → `SkillRegistry`(活跃) | `StageSkillDriver`(零实现) | Pipeline 中 skill stage 必然失败 |
|
||||
| Hand 执行 | `Kernel::hand_execute()` + 审批(活跃) | `StageHandDriver`(零实现) | Pipeline 中 hand stage 必然失败 |
|
||||
|
||||
---
|
||||
|
||||
## 六、Dead Code 清单
|
||||
|
||||
### 6.1 `#[allow(dead_code)]` 统计(28 处)
|
||||
|
||||
| 分类 | 数量 | 说明 |
|
||||
|------|------|------|
|
||||
| 合理(serde 反序列化) | 8 | driver 响应体字段 |
|
||||
| 桩代码(Reserved for future) | 14 | intelligence 层预留方法 |
|
||||
| 可疑 | 6 | intent.rs, stage.rs, browser session 等 |
|
||||
|
||||
### 6.2 孤立模块(~4,228 行)
|
||||
|
||||
| 模块 | 位置 | 行数 | 建议 |
|
||||
|------|------|------|------|
|
||||
| `director` | `crates/zclaw-kernel/src/director.rs` | 907 | 移除或 feature-gate |
|
||||
| `a2a` | `crates/zclaw-protocols/src/a2a.rs` | 690 | 已 feature-gate,保持现状 |
|
||||
| `export` | `crates/zclaw-kernel/src/export/` | 2,319 | 移除或接入 Tauri 命令 |
|
||||
| `zclaw-channels` | `crates/zclaw-channels/src/` | 290 | 移除 crate |
|
||||
| `retrieval/cache.rs` | `crates/zclaw-growth/src/retrieval/cache.rs` | 22+ | 移除 |
|
||||
|
||||
### 6.3 TODO 注释(6 处)
|
||||
|
||||
| 位置 | 内容 | 风险 |
|
||||
|------|------|------|
|
||||
| `registry.rs:56` | `// TODO: Track this` | LOW |
|
||||
| `orchestration.rs:41` | `// TODO: implement graph storage` | LOW |
|
||||
| `html.rs:17` | `// TODO: Implement template-based HTML export` | LOW(孤立模块内) |
|
||||
| `pipeline_commands.rs:442` | `// TODO: use actual time` | LOW |
|
||||
| `pipeline_commands.rs:782` | `// TODO: add pattern support` | LOW |
|
||||
|
||||
---
|
||||
|
||||
## 七、E2E 数据流验证
|
||||
|
||||
### 7.1 流程总览
|
||||
|
||||
| # | 流程 | 验证结果 | 关键发现 |
|
||||
|---|------|---------|---------|
|
||||
| 1 | 聊天消息 | **PASS** | 全链路正常,intelligence hooks 正确注入记忆+身份 |
|
||||
| 2 | 技能执行 | **WARNING** | PythonSkill 有实现但从未被实例化;assisted 模式无审批门 |
|
||||
| 3 | Hand 执行+审批 | **PASS** | 三级守卫正确,跨 Hand 审批攻击防护到位 |
|
||||
| 4 | Pipeline 执行 | **FAIL** | skill/hand stage 必然失败(DriverNotAvailable) |
|
||||
| 5 | 记忆存储与检索 | **PASS**(有死代码) | intelligence_hooks 路径正常,GrowthIntegration 永远不执行 |
|
||||
|
||||
### 7.2 Flow 4 失败详情
|
||||
|
||||
Pipeline 的 `StageExecutor` 在执行 skill/hand 类型 stage 时,调用:
|
||||
```rust
|
||||
self.skill_driver.as_ref().ok_or_else(|| StageError::DriverNotAvailable("Skill"))?
|
||||
```
|
||||
由于 `ActionRegistry` 构造时从未注入 `StageSkillDriver` 或 `StageHandDriver`,`skill_driver` 和 `hand_driver` 字段始终为 `None`,导致 `DriverNotAvailable` 错误。
|
||||
|
||||
**可用的 Pipeline stage 类型**: LLM、HTTP、file_export、variable
|
||||
**不可用的 Pipeline stage 类型**: skill、hand、orchestration
|
||||
|
||||
### 7.3 Flow 2 警告详情
|
||||
|
||||
`SkillRegistry` 在匹配 `SkillMode::Python` 时(`registry.rs:79`),直接 fall-through 到 `PromptOnly`,导致 `PythonSkill`(完整实现在 `runner.rs:74-109`)永远不会被实例化。
|
||||
|
||||
---
|
||||
|
||||
## 八、修复建议(优先级排序)
|
||||
|
||||
### P0 — CRITICAL(影响核心功能可用性)
|
||||
|
||||
| # | 问题 | 修复方案 | 涉及文件 | 工作量 |
|
||||
|---|------|---------|---------|--------|
|
||||
| P0-1 | Pipeline skill/hand stage 失败 | 实现 `StageSkillDriver`/`StageHandDriver`,在 `pipeline_commands.rs` 中注入 | `crates/zclaw-pipeline/`, `desktop/src-tauri/src/pipeline_commands.rs` | 大 |
|
||||
| P0-2 | GrowthIntegration 永远不执行 | 决策:(A) 在 Kernel 中接线 GrowthIntegration,移除 intelligence_hooks;(B) 移除 GrowthIntegration,统一到 intelligence_hooks | `crates/zclaw-runtime/src/growth.rs`, `desktop/src-tauri/src/intelligence_hooks.rs` | 中 |
|
||||
|
||||
### P1 — HIGH(影响功能完整性)
|
||||
|
||||
| # | 问题 | 修复方案 | 涉及文件 | 工作量 |
|
||||
|---|------|---------|---------|--------|
|
||||
| P1-1 | PythonSkill 未实例化 | 修复 `registry.rs:79` 的 fall-through 逻辑 | `crates/zclaw-skills/src/registry.rs` | 小 |
|
||||
| P1-2 | Trigger trait 零实现 | 实现 `Trigger` 或标记为 future feature | `crates/zclaw-hands/src/trigger.rs` | 中 |
|
||||
| P1-3 | LlmDriverForExtraction 仅 Mock | 在 Tauri 层实现生产版本(桥接 LlmDriver) | `desktop/src-tauri/src/` | 中 |
|
||||
| P1-4 | Skill assisted 模式无审批门 | 与 Hand 一致,添加 assisted 模式审批 | `desktop/src-tauri/src/kernel_commands.rs` | 小 |
|
||||
|
||||
### P2 — MEDIUM(代码质量与可维护性)
|
||||
|
||||
| # | 问题 | 修复方案 | 涉及文件 | 工作量 |
|
||||
|---|------|---------|---------|--------|
|
||||
| P2-1 | ~4,228 行孤立代码 | 移除 Director、Export、Channels crate | `crates/zclaw-kernel/`, `crates/zclaw-protocols/`, `crates/zclaw-channels/` | 中 |
|
||||
| P2-2 | kernel_status 返回桩数据 | 调用 `kernel.config()` 返回真实值 | `desktop/src-tauri/src/kernel_commands.rs` | 小 |
|
||||
| P2-3 | viking_tree 忽略 depth 参数 | 实现递归深度控制 | `desktop/src-tauri/src/viking_commands.rs` | 小 |
|
||||
| P2-4 | 审批拒绝理由被丢弃 | 存储/返回 `_reason` 参数 | `crates/zclaw-kernel/src/kernel.rs` | 小 |
|
||||
|
||||
### P3 — LOW(SaaS 合并准备)
|
||||
|
||||
| # | 问题 | 修复方案 | 涉及文件 | 工作量 |
|
||||
|---|------|---------|---------|--------|
|
||||
| P3-1 | SaaS 缺失 9 个核心能力域 | 制定 SaaS 功能路线图,优先级:Agent→Skill→Hand→Pipeline→Memory | `.claude/worktrees/saas-backend/` | 大 |
|
||||
| P3-2 | SaaS 无专属 UI 组件 | 设计/实现 SaaS 登录面板、设置页、仪表盘 | `desktop/src/components/` | 大 |
|
||||
| P3-3 | Tauri IPC 耦合 | 抽象通信层,支持 HTTP/WebSocket/Tauri IPC 三种模式 | `desktop/src/lib/` | 大 |
|
||||
|
||||
---
|
||||
|
||||
## 九、审计结论
|
||||
|
||||
### Tauri 端健康度: **良好(78%)**
|
||||
- 功能-代码对齐率 100%,17 个功能全部有对应命令和 UI
|
||||
- 5 条核心 E2E 流程中 3 条完全通过,1 条有警告,1 条失败
|
||||
- 智能层(记忆/身份/心跳/反思/压缩)已完整接入聊天流程
|
||||
- 主要问题集中在 Pipeline 的 skill/hand stage 不可用,以及 GrowthIntegration 死代码路径
|
||||
|
||||
### SaaS 端健康度: **早期(18%)**
|
||||
- 仅实现 auth + LLM relay + config sync 三个基础能力
|
||||
- 9 个核心能力域(Agent/Skill/Hand/Pipeline/Memory/Intelligence/Browser/OpenViking)完全缺失
|
||||
- 前端仅有 client/store 层,无专属 UI 组件
|
||||
- Main 分支零 SaaS 代码,完全隔离
|
||||
|
||||
### 合并建议
|
||||
建议在合并 SaaS worktree 前,先完成以下工作:
|
||||
1. 修复 P0-1(Pipeline skill/hand stage)
|
||||
2. 解决 P0-2(GrowthIntegration vs intelligence_hooks 决策)
|
||||
3. 制定 SaaS 核心能力实现路线图(至少覆盖 Agent + Skill + Hand)
|
||||
4. 为 SaaS 模式设计/实现专属 UI 组件
|
||||
|
||||
---
|
||||
|
||||
*审计完成。本报告基于 2026-03-27 代码快照,所有发现均可通过文档中引用的文件路径和行号验证。*
|
||||
|
||||
---
|
||||
|
||||
## 九、v6.1 修复记录
|
||||
|
||||
> **修复日期**: 2026-03-27
|
||||
> **编译状态**: `cargo check` 通过,零错误零警告
|
||||
|
||||
### 已修复项
|
||||
|
||||
| # | 优先级 | 修复内容 | 修改文件 |
|
||||
|---|--------|---------|---------|
|
||||
| 1 | **P0** | Pipeline skill/hand stage 接入 Kernel 驱动 — 创建 `PipelineSkillDriver` 和 `PipelineHandDriver` 适配器,将 Kernel 的 skill/hand 执行能力桥接到 Pipeline 的 `ActionRegistry` | `pipeline_commands.rs` |
|
||||
| 2 | **P0** | GrowthIntegration 标记为未接线 — 添加文档注释说明该模块在 Tauri 部署中未使用(被 `intelligence_hooks` 替代),保留代码因为被 loop_runner/compaction 深度引用 | `growth.rs` |
|
||||
| 3 | **P1** | PythonSkill 未实例化 — `SkillMode::Python` 分支添加到 registry,当 `main.py` 存在时创建 `PythonSkill` 实例 | `registry.rs` |
|
||||
| 4 | **P1** | Skill assisted 模式添加审批门 — `supervised` 模式所有 skill 需审批,`assisted` 模式 shell/python skill 需审批,`autonomous` 模式直接执行 | `kernel_commands.rs` |
|
||||
| 5 | **P2** | kernel_status 返回真实配置值 — `database_url`、`base_url`、`model` 从桩数据改为读取 Kernel 配置 | `kernel_commands.rs` |
|
||||
| 6 | **P2** | viking_tree depth 参数生效 — 移除未使用的 `_depth` 参数,添加实际深度限制逻辑 | `viking_commands.rs` |
|
||||
| 7 | **P2** | 审批拒绝理由被丢弃 — `ApprovalEntry` 添加 `reject_reason` 字段,`respond_to_approval` 正确存储拒绝理由 | `kernel.rs` |
|
||||
| 8 | **文档** | SaaS 差距矩阵重新分类 — 明确 SaaS 定位为系统管理(账号/权限/relay),9 个 "CRITICAL GAP" 重新标记为 "N/A" | `COMPREHENSIVE_AUDIT_V6.md` |
|
||||
|
||||
### 待办项
|
||||
|
||||
| # | 优先级 | 内容 | 说明 |
|
||||
|---|--------|------|------|
|
||||
| 1 | P2 | 清理孤立代码(Director/Export/Channels) | ~4,228 行,建议作为独立重构任务 |
|
||||
| 2 | P3 | 6 个零实现 Trait 评估 | 4 个属于 Pipeline v2(未使用),2 个属于 Trigger 系统 |
|
||||
518
docs/archive/old-audits/COMPREHENSIVE_AUDIT_V7.md
Normal file
@@ -0,0 +1,518 @@
|
||||
# ZCLAW SaaS 功能审计报告 v7
|
||||
|
||||
> **ARCHIVED — 此报告已过时**
|
||||
>
|
||||
> 本报告是 2026-03-28 审计迭代的 v7 版本。最终结论已合并到 DEEP_AUDIT_REPORT.md。
|
||||
>
|
||||
> **请参考最新文档** → [README.md](./README.md)
|
||||
|
||||
> **审计日期**: 2026-03-28 (原文标注有误)
|
||||
> **审计范围**: SaaS worktree(`.claude/worktrees/saas-backend/`)— Rust 后端 + Admin UI + 桌面端集成
|
||||
> **审计方法**: 五步审计流程(文档对齐 → 数据流追踪 → Dead Code → 接口检查 → E2E 验证)+ 10 项通用清单 + 5 种差距模式 + 跨部门专家论证
|
||||
> **前次审计**: v6(Tauri 端 78%,SaaS 端 18%)
|
||||
|
||||
---
|
||||
|
||||
## 一、执行摘要
|
||||
|
||||
| 指标 | 数值 |
|
||||
|------|------|
|
||||
| **SaaS 后端 API 端点** | 43 个(文档声明 44 个) |
|
||||
| **文档-代码对齐率** | 97.7%(43/44,缺 `/api/health`) |
|
||||
| **OpenAPI 文档覆盖** | 37/43(86%),6 个端点未注解 |
|
||||
| **Admin UI 页面** | 13 个(含 login) |
|
||||
| **Admin API 方法** | 30 个,全覆盖 |
|
||||
| **桌面端 SaaS 方法** | 20 个,全覆盖 |
|
||||
| **10 项审计清单通过率** | auth 90% / account 80% / model_config 100% / relay 90% / migration 60% |
|
||||
| **五种差距模式发现** | 16 个问题 |
|
||||
| **Dead Code** | 0 个 `#[allow(dead_code)]`/TODO/FIXME + 3 个配置字段 + 3 个遗留函数 |
|
||||
| **安全漏洞** | 1 个 CRITICAL + 2 个 HIGH + 1 个 LOW |
|
||||
| **审计日志缺失** | migration 模块全部缺失(5 个变更端点) |
|
||||
| **测试总数** | 86 个单元测试(10 个模块有测试,9 个文件零测试) |
|
||||
| **整体 SaaS 完成度** | **~88%**(V6 审计评估 18% 严重低估,修正为 88%)
|
||||
|
||||
### 与 V6 审计关键差异
|
||||
|
||||
V6 报告评估 SaaS 完成度为 18%,这是**基于错误假设**(将 Tauri 端 AI 能力缺失计入 SaaS 差距)。本次审计确认 SaaS 的设计定位(系统管理:账号/权限/relay),在定位范围内完成度为 **~88%**。
|
||||
|
||||
---
|
||||
|
||||
## 二、功能清单与真实完成度
|
||||
|
||||
### 2.1 SaaS 功能模块总览
|
||||
|
||||
| # | 功能模块 | 设计意图 | 文档声称 | 真实完成度 | 差距说明 |
|
||||
|---|---------|---------|---------|-----------|---------|
|
||||
| 1 | 用户认证 | 多模式登录、JWT 生命周期、TOTP 2FA | 100% | **95%** | `/api/health` 未实现;`auth.refresh` 无审计日志 |
|
||||
| 2 | 账号管理 | CRUD + 角色限制 + 设备管理 | 100% | **90%** | `AccountPublicPaginatedResponse` 死代码;dashboard 7 次串行查询 |
|
||||
| 3 | API Token | 创建/撤销/权限管理 | 100% | **100%** | 无 |
|
||||
| 4 | 模型配置 | Provider/Model/Key CRUD + 用量 | 95% | **90%** | `account_api_keys` 存了没用(Relay 未消费) |
|
||||
| 5 | LLM Relay | OpenAI 兼容代理 + SSE + 重试 + SSRF | 95% | **90%** | `request_hash`/`priority`/`batch_window_ms` 存了没用;`chat_completions` OpenAPI 缺失 |
|
||||
| 6 | 配置迁移 | diff/sync/seed + 日志 | 90% | **70%** | `sync_config` 缺权限检查(CRITICAL);`pull` 未实现;5 个端点缺审计日志;`created` 计数器永远为 0 |
|
||||
| 7 | Admin UI | 13 页面仪表盘 | 95% | **85%** | 权限过滤 Bug(admin 角色缺 4 页面);分页未连接 API;无前端路由保护 |
|
||||
| 8 | 桌面端集成 | 登录/设备/Relay/迁移向导 | 95% | **90%** | `computeConfigDiff`/`syncConfig` 定义但未调用;调用路径不一致 |
|
||||
|
||||
### 2.2 未实现功能(设计文档提及但代码中不存在)
|
||||
|
||||
| 功能 | 文档状态 | 代码状态 | 说明 |
|
||||
|------|---------|---------|------|
|
||||
| `/api/health` 健康检查 | 文档声明 | **未实现** | `main.rs` 无此路由 |
|
||||
| `pull` 配置同步方向 | types.rs 注释 | **未实现** | service 只处理 push/merge |
|
||||
| 订阅/计费系统 | roadmap 提及 | **未实现** | 无代码 |
|
||||
| 多租户隔离 | 无 | **未实现** | 无代码 |
|
||||
| 配额执行 | 无 | **未实现** | `max_queue_size`/`max_concurrent` 定义但未执行 |
|
||||
|
||||
---
|
||||
|
||||
## 三、API 端点覆盖率
|
||||
|
||||
### 3.1 端点清单(文档 vs 代码)
|
||||
|
||||
| 分类 | 端点 | 文档 | 代码 | OpenAPI | 测试 |
|
||||
|------|------|------|------|---------|------|
|
||||
| **公开** | `POST /api/v1/auth/register` | ✅ | ✅ | ✅ | ✅ |
|
||||
| | `POST /api/v1/auth/login` | ✅ | ✅ | ✅ | ✅ |
|
||||
| | `GET /api/health` | ✅ | **❌** | ❌ | ❌ |
|
||||
| **认证** | `GET /api/v1/auth/me` | ✅ | ✅ | ✅ | — |
|
||||
| | `POST /api/v1/auth/refresh` | ✅ | ✅ | ✅ | — |
|
||||
| | `PUT /api/v1/auth/password` | ✅ | ✅ | ✅ | — |
|
||||
| **TOTP** | `POST /api/v1/auth/totp/setup` | ✅ | ✅ | ✅ | — |
|
||||
| | `POST /api/v1/auth/totp/verify` | ✅ | ✅ | ✅ | — |
|
||||
| | `POST /api/v1/auth/totp/disable` | ✅ | ✅ | ✅ | — |
|
||||
| **账号** | `GET /api/v1/accounts` | ✅ | ✅ | ✅ | — |
|
||||
| | `GET /api/v1/accounts/{id}` | ✅ | ✅ | ✅ | — |
|
||||
| | `PUT /api/v1/accounts/{id}` | ✅ | ✅ | ✅ | — |
|
||||
| | `PATCH /api/v1/accounts/{id}/status` | ✅ | ✅ | ✅ | — |
|
||||
| | `GET /api/v1/stats/dashboard` | ✅ | ✅ | ✅ | — |
|
||||
| **Token** | `GET /api/v1/tokens` | ✅ | ✅ | ✅ | — |
|
||||
| | `POST /api/v1/tokens` | ✅ | ✅ | ✅ | — |
|
||||
| | `DELETE /api/v1/tokens/{id}` | ✅ | ✅ | ✅ | — |
|
||||
| **设备** | `POST /api/v1/devices/register` | ✅ | ✅ | ✅ | — |
|
||||
| | `POST /api/v1/devices/heartbeat` | ✅ | ✅ | ✅ | — |
|
||||
| | `GET /api/v1/devices` | ✅ | ✅ | ✅ | — |
|
||||
| **Provider** | `GET/POST /api/v1/providers` | ✅ | ✅ | ✅ | — |
|
||||
| | `GET/PUT/DELETE /api/v1/providers/{id}` | ✅ | ✅ | ✅ | — |
|
||||
| | `GET /api/v1/providers/{id}/models` | ✅ | ✅ | ✅ | — |
|
||||
| **Model** | `GET/POST /api/v1/models` | ✅ | ✅ | ✅ | — |
|
||||
| | `GET/PUT/DELETE /api/v1/models/{id}` | ✅ | ✅ | ✅ | — |
|
||||
| **Key** | `GET/POST/DELETE /api/v1/keys` | ✅ | ✅ | ✅ | — |
|
||||
| | `POST /api/v1/keys/{id}/rotate` | ✅ | ✅ | ✅ | — |
|
||||
| **Relay** | `GET /api/v1/relay/models` | ✅ | ✅ | ✅ | — |
|
||||
| | `POST /api/v1/relay/chat/completions` | ✅ | ✅ | **❌** | — |
|
||||
| | `GET /api/v1/relay/tasks` | ✅ | ✅ | ✅ | — |
|
||||
| | `GET /api/v1/relay/tasks/{id}` | ✅ | ✅ | ✅ | — |
|
||||
| | `POST /api/v1/relay/tasks/{id}/retry` | ✅ | ✅ | ✅ | — |
|
||||
| **Config** | `GET/POST /api/v1/config/items` | ✅ | ✅ | ✅ | — |
|
||||
| | `GET/PUT/DELETE /api/v1/config/items/{id}` | ✅ | ✅ | ✅ | — |
|
||||
| | `GET /api/v1/config/analysis` | ✅ | ✅ | ✅ | — |
|
||||
| | `POST /api/v1/config/seed` | ✅ | ✅ | ✅ | — |
|
||||
| | `POST /api/v1/config/sync` | ✅ | ✅ | ✅ | — |
|
||||
| | `POST /api/v1/config/diff` | ✅ | ✅ | ✅ | — |
|
||||
| | `GET /api/v1/config/sync-logs` | ✅ | ✅ | ✅ | — |
|
||||
| **审计** | `GET /api/v1/logs/operations` | ✅ | ✅ | ✅ | — |
|
||||
| | `GET /api/v1/usage` | ✅ | ✅ | ✅ | — |
|
||||
|
||||
**统计**: 43/44 端点已实现(97.7%),37/43 有 OpenAPI 文档(86%)
|
||||
|
||||
**缺失 OpenAPI 文档的 6 个端点**:
|
||||
1. `POST /api/v1/auth/totp/setup` — TOTP 设置
|
||||
2. `POST /api/v1/auth/totp/verify` — TOTP 验证
|
||||
3. `POST /api/v1/auth/totp/disable` — TOTP 禁用
|
||||
4. `GET /api/v1/logs/operations` — 操作日志
|
||||
5. `GET /api/v1/stats/dashboard` — 仪表盘统计
|
||||
6. `POST /api/v1/relay/chat/completions` — 聊天中转
|
||||
|
||||
---
|
||||
|
||||
## 四、审计矩阵
|
||||
|
||||
### 4.1 十项通用审计清单
|
||||
|
||||
| # | 检查项 | auth | account | model_config | relay | migration |
|
||||
|---|--------|------|---------|-------------|-------|-----------|
|
||||
| 1 | 代码存在性 | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| 2 | 调用链连通 | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| 3 | 配置传递 | ✅ | ✅ | ✅ | **⚠️** 3 字段未使用 | ✅ |
|
||||
| 4 | 降级策略 | ✅ JWT 过期处理 | — | — | ✅ 上游超时重试 | — |
|
||||
| 5 | 错误处理 | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||
| 6 | 权限执行 | ✅ | ✅ | ✅ | ✅ | **❌** sync_config |
|
||||
| 7 | 日志覆盖 | **⚠️** refresh 缺失 | ✅ | ✅ | ✅ | **❌** 全部缺失 |
|
||||
| 8 | 输入验证 | ✅ | ✅ | ✅ | ✅ | **⚠️** sync action |
|
||||
| 9 | 测试覆盖 | ✅ 3 tests | ✅ 2 tests | ✅ 1 test | ✅ 30+ tests | ✅ 2 tests |
|
||||
| 10 | 文档一致性 | **⚠️** /health 缺失 | ✅ | ✅ | **⚠️** OpenAPI 缺失 | ✅ |
|
||||
|
||||
### 4.2 E2E 数据流验证
|
||||
|
||||
| # | 流程 | 结果 | 关键发现 |
|
||||
|---|------|------|---------|
|
||||
| 1 | 用户注册 → JWT → 首次请求 | **PASS** | 全链路正常,Argon2 哈希正确 |
|
||||
| 2 | TOTP 登录 → 受保护 API | **PASS** | verify_totp_code → get_role_permissions → create_token 正确 |
|
||||
| 3 | Relay SSE 流式 + 用量记录 | **PASS** | SSRF 防护 + DNS Rebinding + SSE 用量提取正确 |
|
||||
| 4 | 配置同步 push/merge | **WARNING** | push 路径正常但缺权限检查;`created` 计数永远为 0 |
|
||||
| 5 | 设备注册 + 心跳 | **PASS** | UPSERT + heartbeat UPDATE 正确 |
|
||||
|
||||
---
|
||||
|
||||
## 五、差距分析(5 种模式)
|
||||
|
||||
### 5.1 Pattern 1: "写了没接"(3 项)
|
||||
|
||||
| # | 发现 | 位置 | 严重性 |
|
||||
|---|------|------|--------|
|
||||
| G1 | `hash_request()` 计算 SHA-256 哈希存入 `request_hash` 但从未被查询 | `relay/service.rs:273` | LOW |
|
||||
| G2 | `pull` 同步方向在类型注释中声明但 service 未实现 | `migration/service.rs:306` | LOW |
|
||||
| G3 | `cleanup_stale_entries()` 声明为 pub(crate) 但从未被调用(仅测试使用) | `middleware.rs:54` | LOW |
|
||||
|
||||
### 5.2 Pattern 2: "接了没传"(2 项)
|
||||
|
||||
| # | 发现 | 位置 | 严重性 |
|
||||
|---|------|------|--------|
|
||||
| G4 | `sync_config` 的 `created` 变量初始化为 0 但从未递增 | `migration/service.rs:263` | MEDIUM |
|
||||
| G5 | `chat_completions` 的 `_headers` 参数提取但未使用 | `relay/handlers.rs:25` | LOW |
|
||||
|
||||
### 5.3 Pattern 3: "传了没存"(0 项)
|
||||
|
||||
无发现。所有 SQL 变更正确执行。
|
||||
|
||||
### 5.4 Pattern 4: "存了没用"(5 项)
|
||||
|
||||
| # | 发现 | 位置 | 严重性 |
|
||||
|---|------|------|--------|
|
||||
| G6 | `request_hash` 列存储但从未用于去重 | `relay_tasks.request_hash` | LOW |
|
||||
| G7 | `priority` 列永远为 0,未用于排序 | `relay_tasks.priority` | LOW |
|
||||
| G8 | `max_queue_size` 配置字段定义但未执行 | `config.rs:49` | LOW |
|
||||
| G9 | `max_concurrent_per_provider` 配置字段定义但未执行 | `config.rs:51` | LOW |
|
||||
| G10 | `batch_window_ms` 配置字段定义但未使用 | `config.rs:53` | LOW |
|
||||
| **G11** | **`account_api_keys` 表完整 CRUD 但 Relay 只使用 provider 级 API Key** | `model_config/service.rs:285` vs `relay/handlers.rs:56` | **HIGH** |
|
||||
|
||||
### 5.5 Pattern 5: "双系统不同步"(3 项)
|
||||
|
||||
| # | 发现 | 位置 | 严重性 |
|
||||
|---|------|------|--------|
|
||||
| G12 | Config 模块写 `config_sync_log` 但不写统一 `operation_logs`,破坏审计追踪 | `migration/handlers.rs` | **MEDIUM** |
|
||||
| G13 | Provider 级 API Key + 用户级 API Key 双系统,Relay 只消费前者 | `relay/handlers.rs:56` | **MEDIUM** |
|
||||
| G14 | Admin UI 导航权限过滤逻辑与后端 RBAC 权限系统不同步 | `layout.tsx:107` vs `db.rs` seed roles | **HIGH** |
|
||||
|
||||
### 5.6 Pattern 1 补充: "写了没接"(Admin UI + Desktop)
|
||||
|
||||
| # | 发现 | 位置 | 严重性 |
|
||||
|---|------|------|--------|
|
||||
| G15 | saas-client `computeConfigDiff()`/`syncConfig()` 定义但桌面端从未调用 | `saas-client.ts` | LOW |
|
||||
| G16 | Admin 5 个列表页面分页组件存在但未连接 API 分页参数 | `accounts/providers/models/api-keys/relay page.tsx` | MEDIUM |
|
||||
|
||||
---
|
||||
|
||||
## 六、安全问题
|
||||
|
||||
| # | 问题 | 严重性 | 位置 | 说明 |
|
||||
|---|------|--------|------|------|
|
||||
| **S1** | `sync_config` 无权限检查 | **CRITICAL** | `migration/handlers.rs:83-89` | 任何认证用户可推送配置值,应要求 `config:write` |
|
||||
| **S2** | Config 变更端点无审计日志 | **HIGH** | `migration/handlers.rs` | create/update/delete/seed/sync 5 个端点未调用 `log_operation()` |
|
||||
| **S3** | Admin UI 权限过滤逻辑错误 | **HIGH** | `layout.tsx:107` | 普通 admin 角色无法看到 4 个管理页面;隐藏导航但未保护路由 |
|
||||
| S4 | 邮箱验证仅检查 `@` 和 `.` | LOW | `auth/handlers.rs:28` | 可接受简单验证,PostgreSQL 有 email 类型约束 |
|
||||
|
||||
---
|
||||
|
||||
## 七、跨部门专家论证
|
||||
|
||||
### 发现 S1: `sync_config` 缺权限检查 (CRITICAL)
|
||||
|
||||
| 专家视角 | 分析 |
|
||||
|---------|------|
|
||||
| **产品经理** | 影响中等。当前仅桌面端调用此端点,但公开后任何用户可修改系统配置。优先级 P0 |
|
||||
| **架构师** | 实现疏忽。其他所有 mutation 端点都有 `check_permission`,唯独 `sync_config` 遗漏。修复方案简单:添加 `check_permission(ctx, "config:write")` |
|
||||
| **安全工程师** | 权限边界被突破。一个普通用户(`user` 角色,权限仅 `["model:read","relay:use","config:read"]`)可以覆盖任何配置项。风险:配置投毒 |
|
||||
| **UX 设计师** | 无 UI 影响。Admin 和桌面端的配置同步 UI 都不会因此出现问题,因为其他端点都有权限检查 |
|
||||
|
||||
**结论**: 真实漏洞,P0 修复。一行代码即可修复。
|
||||
|
||||
### 发现 G11: `account_api_keys` 未被 Relay 消费 (HIGH)
|
||||
|
||||
| 专家视角 | 分析 |
|
||||
|---------|------|
|
||||
| **产品经理** | 影响高。用户在桌面端创建的 per-provider API Key 永远不会被使用,Relay 始终使用管理员配置的 provider 级 Key。这导致多用户共享同一个 API Key,无法追踪个人用量到具体 Key |
|
||||
| **架构师** | 设计不完整。`account_api_keys` 的 CRUD 已实现(创建/撤销/轮换),Admin UI 有专门页面,但消费端(Relay)从未接入。需要决策:(A) Relay 优先使用用户级 Key;(B) 移除 `account_api_keys` 功能 |
|
||||
| **安全工程师** | 用户级 Key 隔离未生效。当前所有用户的 Relay 请求共享同一个 provider Key,无法在 Key 级别做权限隔离或用量追踪 |
|
||||
| **UX 设计师** | Admin UI 的 "API Keys" 页面展示用户创建的 Key 和轮换状态,但实际从未使用。用户可能困惑于 "为什么创建了 Key 但用量全部归到 provider" |
|
||||
|
||||
**结论**: 真实设计缺陷,需要架构决策。建议方案 A(Relay 优先用户级 Key,回退 provider 级)。
|
||||
|
||||
### 发现 G12: Config 模块审计日志缺失 (MEDIUM)
|
||||
|
||||
| 专家视角 | 分析 |
|
||||
|---------|------|
|
||||
| **产品经理** | 影响低。Config 变更频率低,通常由管理员操作。但合规审计需要完整日志 |
|
||||
| **架构师** | 不一致。auth/account/model_config 模块都有 `log_operation()`,唯独 migration 模块缺失。`sync_config` 写了 `config_sync_log` 但这是专用日志,不在统一的 `operation_logs` 表中 |
|
||||
| **安全工程师** | 审计盲区。如果有人在凌晨 3 点覆盖了系统配置,`operation_logs` 表中不会有记录 |
|
||||
| **UX 设计师** | 无影响。Admin 操作日志页面不会显示 Config 变更记录 |
|
||||
|
||||
**结论**: 真实遗漏。修复简单:在 5 个 mutation handler 中添加 `log_operation()` 调用。
|
||||
|
||||
### 发现 G4: `sync_config` `created` 计数永远为 0 (MEDIUM)
|
||||
|
||||
| 专家视角 | 分析 |
|
||||
|---------|------|
|
||||
| **产品经理** | 影响低。桌面端迁移向导显示 "updated: N, created: 0, skipped: M"。`created` 永远为 0 可能让用户困惑 |
|
||||
| **架构师** | 实现疏忽。push 路径只处理已存在的 config_items(UPDATE),merge 路径也只处理已存在的。真正的新增场景(客户端发送 SaaS 不存在的 key)未被处理 |
|
||||
| **安全工程师** | 无安全影响 |
|
||||
| **UX 设计师** | 迁移向导的统计信息不准确。`created` 应该在 INSERT 新 config_item 时递增 |
|
||||
|
||||
**结论**: 真实 Bug。`sync_config` 应在 INSERT 时递增 `created` 计数器。
|
||||
|
||||
### 发现 S3: `/api/health` 端点未实现 (LOW)
|
||||
|
||||
| 专家视角 | 分析 |
|
||||
|---------|------|
|
||||
| **产品经理** | 影响低。文档声明了但桌面端 `healthCheck()` 调用时如果返回 404 会判断为不健康。实际影响:桌面端可能误判服务器不可达 |
|
||||
| **架构师** | 遗漏。实现简单,返回 `{ status: "ok", version: "x.y.z" }` 即可 |
|
||||
| **安全工程师** | 无安全影响(公开端点) |
|
||||
| **UX 设计师** | 桌面端 SaaSStatus 组件依赖健康检查。缺失会导致状态显示异常 |
|
||||
|
||||
**结论**: 真实遗漏。简单修复。
|
||||
|
||||
### 发现 S3: Admin UI 权限过滤逻辑错误 (HIGH)
|
||||
|
||||
| 专家视角 | 分析 |
|
||||
|---------|------|
|
||||
| **产品经理** | 影响高。多管理员场景下(组织有多个管理员),普通 `admin` 角色用户登录后看不到账号管理、服务商、模型管理、中转任务 4 个核心页面。这严重限制了管理员协作能力。优先级 P1 |
|
||||
| **架构师** | 实现疏忽。过滤条件 `account.role === 'super_admin' \|\| item.permission === 'admin:full'` 未检查用户是否实际拥有 `item.permission`。正确做法应检查 `account.permissions.includes(item.permission)`。此外,仅隐藏导航项未做前端路由守卫,用户直接输入 URL 可绕过。修复需 2 处:(A) 修正过滤逻辑;(B) 添加路由级权限检查 |
|
||||
| **安全工程师** | 前端权限过滤失效。虽然后端 API 有权限检查(`check_permission`),但前端暴露了所有路由 URL,攻击者可枚举管理端点。更重要的是,**前端路由未保护**意味着用户可能看到一个有权限错误但功能正常的页面,体验混乱 |
|
||||
| **UX 设计师** | 用户体验混乱。管理员登录后看到侧边栏只有 6/12 项,可能认为自己权限不足。如果直接输入 URL 访问被隐藏的页面,后端返回 403 错误但页面不会给出清晰提示 |
|
||||
|
||||
**结论**: 真实 Bug,P1 修复。修正过滤逻辑 + 添加路由守卫。
|
||||
|
||||
### 发现 G16: Admin 分页组件未连接 API (MEDIUM)
|
||||
|
||||
| 专家视角 | 分析 |
|
||||
|---------|------|
|
||||
| **产品经理** | 影响中等。当前数据量小(早期用户)时无感知。但一旦账号/模型/密钥数量超过默认 page_size,用户只能看到第一批数据,无法翻页查看更多。优先级 P2 |
|
||||
| **架构师** | 分页组件存在于 5 个页面但全部未连接 API 调用。`PageNavigation` 组件维护 `currentPage`/`pageSize` 状态,但 `api.xxx.list()` 调用未传递这些参数。修复方案:将分页状态传递到 API 调用,监听页码变化触发重新加载 |
|
||||
| **安全工程师** | 无安全影响 |
|
||||
| **UX 设计师** | 分页按钮显示但点击无效,或者始终显示"第 1 页"。用户可能认为数据只有这么多,不知道还有更多未加载 |
|
||||
|
||||
**结论**: 真实 Bug,P2 修复。5 个页面统一处理。
|
||||
|
||||
---
|
||||
|
||||
## 八、Admin UI 审计
|
||||
|
||||
### 8.1 页面-API 对齐
|
||||
|
||||
| 页面 | API 方法调用 | 状态 |
|
||||
|------|------------|------|
|
||||
| Login | `api.auth.login()` | ✅ |
|
||||
| Dashboard | `api.stats.dashboard()` | ✅ |
|
||||
| Accounts | `api.accounts.list/get/update/updateStatus()` | ✅ |
|
||||
| Providers | `api.providers.list/get/create/update/delete()` | ✅ |
|
||||
| Models | `api.models.list/get/create/update/delete()` | ✅ |
|
||||
| API Keys | `api.tokens.list/create/revoke()` | ✅ |
|
||||
| Usage | `api.usage.get()` | ✅ |
|
||||
| Relay | `api.relay.list/get/retry()` | ✅ |
|
||||
| Config | `api.config.list/update()` | ✅ |
|
||||
| Logs | `api.logs.list()` | ✅ |
|
||||
| Devices | `api.devices.list/register/heartbeat()` | ✅ |
|
||||
| Profile | `api.auth.changePassword()` | ✅ |
|
||||
| Security | `api.auth.totpSetup/verify/disable()` | ✅ |
|
||||
|
||||
**对齐率**: 100%。Admin UI 的 30 个 API 方法全部有对应后端端点。
|
||||
|
||||
### 8.2 Admin API 方法 vs 后端端点交叉验证
|
||||
|
||||
所有 30 个 Admin API 方法的路径均与后端路由匹配,无多余或缺失。
|
||||
|
||||
### 8.3 Admin UI 权限过滤 Bug(HIGH)
|
||||
|
||||
**位置**: `admin/src/app/(dashboard)/layout.tsx:103-108`
|
||||
|
||||
**问题**: 侧边栏导航过滤逻辑存在逻辑错误:
|
||||
|
||||
```typescript
|
||||
// 当前代码(有 Bug)
|
||||
.filter((item) => {
|
||||
if (!item.permission) return true
|
||||
if (!account) return false
|
||||
return account.role === 'super_admin' || item.permission === 'admin:full'
|
||||
})
|
||||
```
|
||||
|
||||
**影响**: `navItems` 中 `account:admin`、`model:admin`、`relay:admin` 三个权限标记对普通 `admin` 角色用户**完全无效**。逻辑等价于:
|
||||
- `permission: null` → 所有角色可见(正确)
|
||||
- `permission: 'admin:full'` → 所有角色可见(Bug,应仅 super_admin 可见)
|
||||
- `permission: 'account:admin'` → **仅** super_admin 可见(Bug,admin 也应有此权限)
|
||||
- `permission: 'model:admin'` → **仅** super_admin 可见(Bug)
|
||||
- `permission: 'relay:admin'` → **仅** super_admin 可见(Bug)
|
||||
|
||||
**结果**: 普通 `admin` 角色用户只能看到仪表盘、API 密钥、用量统计、个人设置、安全设置、设备管理(6/12),**无法看到**账号管理、服务商、模型管理、中转任务(4/12)。
|
||||
|
||||
**缺失**: 仅隐藏导航项,**未做前端路由保护**。用户直接输入 `/accounts`、`/providers` 等路径仍可访问页面(后端权限检查正常,但前端体验不一致)。
|
||||
|
||||
**修复方案**: 改用权限检查函数验证用户是否拥有对应权限:
|
||||
```typescript
|
||||
.filter((item) => {
|
||||
if (!item.permission) return true
|
||||
if (!account) return false
|
||||
return account.permissions?.includes(item.permission) ?? false
|
||||
})
|
||||
```
|
||||
|
||||
### 8.4 Admin UI 分页功能不可用(MEDIUM)
|
||||
|
||||
**影响页面**: accounts、providers、models、api-keys、relay(5 个列表页面)
|
||||
|
||||
**发现**: 5 个页面均包含分页组件(PageNavigation),后端 API 支持分页参数(`page`/`page_size`),但**前端调用 API 时未传递分页参数**,始终获取第一页全部数据。
|
||||
|
||||
**根因**: API 调用使用 `api.xxx.list()` 而非 `api.xxx.list({ page, pageSize })`,分页状态(`currentPage`/`pageSize`)存在于组件 state 中但未与 API 调用关联。
|
||||
|
||||
### 8.5 Admin UI 错误处理一致性
|
||||
|
||||
**发现**: 所有页面均有 `try/catch` 处理 API 错误,但存在不一致:
|
||||
- 部分页面使用 `setError(err.message)` 显示具体错误(accounts、providers)
|
||||
- 部分页面使用 `console.error` 但无用户可见反馈(models:113、api-keys:138)
|
||||
- 无统一的全局错误 Toast/Banner 组件
|
||||
|
||||
**影响**: LOW。用户可能在操作失败时看不到任何反馈。
|
||||
|
||||
---
|
||||
|
||||
## 九、桌面端 SaaS 集成审计
|
||||
|
||||
### 9.1 saas-client.ts 端点覆盖
|
||||
|
||||
| 方法 | 后端端点 | 匹配 |
|
||||
|------|---------|------|
|
||||
| `login()` | `POST /api/v1/auth/login` | ✅ |
|
||||
| `register()` | `POST /api/v1/auth/register` | ✅ |
|
||||
| `me()` | `GET /api/v1/auth/me` | ✅ |
|
||||
| `refreshToken()` | `POST /api/v1/auth/refresh` | ✅ |
|
||||
| `changePassword()` | `PUT /api/v1/auth/password` | ✅ |
|
||||
| `setupTotp()` | `POST /api/v1/auth/totp/setup` | ✅ |
|
||||
| `verifyTotp()` | `POST /api/v1/auth/totp/verify` | ✅ |
|
||||
| `disableTotp()` | `POST /api/v1/auth/totp/disable` | ✅ |
|
||||
| `registerDevice()` | `POST /api/v1/devices/register` | ✅ |
|
||||
| `deviceHeartbeat()` | `POST /api/v1/devices/heartbeat` | ✅ |
|
||||
| `listDevices()` | `GET /api/v1/devices` | ✅ |
|
||||
| `listModels()` | `GET /api/v1/relay/models` | ✅ |
|
||||
| `listRelayTasks()` | `GET /api/v1/relay/tasks` | ✅ |
|
||||
| `getRelayTask()` | `GET /api/v1/relay/tasks/{id}` | ✅ |
|
||||
| `retryRelayTask()` | `POST /api/v1/relay/tasks/{id}/retry` | ✅ |
|
||||
| `chatCompletion()` | `POST /api/v1/relay/chat/completions` | ✅ |
|
||||
| `listConfig()` | `GET /api/v1/config/items` | ✅ |
|
||||
| `computeConfigDiff()` | `POST /api/v1/config/diff` | ✅ |
|
||||
| `syncConfig()` | `POST /api/v1/config/sync` | ✅ |
|
||||
| `healthCheck()` | `GET /api/health` | **❌** 端点不存在 |
|
||||
|
||||
**对齐率**: 19/20(95%)。唯一不匹配是 `healthCheck()` 调用了不存在的 `/api/health`。
|
||||
|
||||
### 9.2 桌面端特性
|
||||
|
||||
- **JWT Token 自动刷新**: 80% 生命周期时主动刷新 + visibilitychange 监听
|
||||
- **会话持久化**: Token 存 OS Keyring(secureStorage),URL/Account 存 localStorage
|
||||
- **遗留函数清理**: `loadSaaSSession()`/`saveSaaSSession()`/`clearSaaSSession()` 3 个同步版本标记为 `@deprecated`
|
||||
- **网络重试**: 指数退避 2 次重试(1s, 2s)
|
||||
- **离线检测**: `isServerReachable()` 状态追踪
|
||||
|
||||
### 9.3 桌面端架构不一致(MEDIUM)
|
||||
|
||||
**发现**: saas-client.ts 中定义了 `computeConfigDiff()` 和 `syncConfig()` 两个方法,但**桌面端代码中无任何组件或 store 调用它们**。配置迁移向导(ConfigMigrationWizard)实现了自己的 diff/sync 逻辑,不经过 saas-client。
|
||||
|
||||
**影响**: MEDIUM。代码冗余 + 维护风险。如果 saas-client 的 API 签名与向导实现不一致,可能出现行为分歧。
|
||||
|
||||
### 9.4 桌面端调用路径不一致(LOW)
|
||||
|
||||
**发现**: 部分 SaaS 操作通过 `saasStore`(Zustand)编排,其他操作直接调用 `saasClient`。无统一规范约定何时使用哪条路径。
|
||||
|
||||
**影响**: LOW。不影响功能正确性,但增加了代码理解和维护成本。
|
||||
|
||||
---
|
||||
|
||||
## 十、测试覆盖评估
|
||||
|
||||
| 模块 | 测试数 | 覆盖内容 |
|
||||
|------|--------|---------|
|
||||
| error.rs | 4 | SaasError 变体、IntoResponse |
|
||||
| config.rs | 4 | 配置加载、环境变量覆盖 |
|
||||
| middleware.rs | 8 | 速率限制、窗口过期、admin 豁免 |
|
||||
| csrf.rs | 6 | Origin 验证、路径剥离、dev 绕过 |
|
||||
| crypto.rs | 10 | 加密/解密、篡改检测、错误密钥 |
|
||||
| jwt | 3 | Token 创建/验证/过期 |
|
||||
| password | 2 | 哈希/验证 |
|
||||
| db.rs | 2 | Schema 初始化、表存在性 |
|
||||
| relay/service.rs | 37 | 重试逻辑、Token 提取、SSRF 检测(**最佳覆盖**) |
|
||||
| model_config/service.rs | 10 | Provider/Model/Key CRUD |
|
||||
| **总计** | **86** | — |
|
||||
|
||||
**零测试的 9 个文件**: 5 个 handler 文件、`auth/totp.rs`、`account/service.rs`、`migration/service.rs`、`state.rs`
|
||||
|
||||
---
|
||||
|
||||
## 十一、修复建议(优先级排序)
|
||||
|
||||
### P0 — CRITICAL(安全漏洞)
|
||||
|
||||
| # | 问题 | 修复方案 | 工作量 |
|
||||
|---|------|---------|--------|
|
||||
| P0-1 | `sync_config` 无权限检查 | `migration/handlers.rs:83` 添加 `check_permission(ctx, "config:write")` | **1 行** |
|
||||
|
||||
### P1 — HIGH(功能缺陷)
|
||||
|
||||
| # | 问题 | 修复方案 | 工作量 |
|
||||
|---|------|---------|--------|
|
||||
| P1-1 | `account_api_keys` 未被 Relay 消费 | Relay handler 查找用户级 Key,回退到 provider 级 Key | 中 |
|
||||
| P1-2 | Config 模块 5 个端点缺审计日志 | 添加 `log_operation()` 调用 | 小 |
|
||||
| P1-3 | `sync_config` `created` 计数永远为 0 | INSERT 时递增 `created` | 小 |
|
||||
| P1-4 | Admin UI 权限过滤逻辑错误 | `layout.tsx:107` 改用 `account.permissions.includes(item.permission)` | **5 行** |
|
||||
| P1-5 | Admin UI 缺前端路由保护 | 添加 `AuthGuard` 组件检查页面级权限 | 中 |
|
||||
|
||||
### P2 — MEDIUM(代码质量)
|
||||
|
||||
| # | 问题 | 修复方案 | 工作量 |
|
||||
|---|------|---------|--------|
|
||||
| P2-1 | `/api/health` 端点未实现 | 添加健康检查路由 | 小 |
|
||||
| P2-2 | `chat_completions` 缺 OpenAPI 文档 | `openapi.rs` 添加 `#[utoipa::path]` | 小 |
|
||||
| P2-3 | 6 个端点缺 OpenAPI 注解 | `openapi.rs` 补充 `#[utoipa::path]` | 中 |
|
||||
| P2-4 | `AccountPublicPaginatedResponse` 仅 OpenAPI 用 | 保留或统一到 PaginatedResponse | 小 |
|
||||
| P2-5 | 3 个 Relay 配置字段未使用 | 移除或实现 `max_queue_size`/`max_concurrent`/`batch_window_ms` | 中 |
|
||||
| P2-6 | `request_hash`/`priority` 列存了没用 | 移除或实现去重/优先级排序 | 中 |
|
||||
| P2-7 | `pull` 同步方向未实现 | 实现或从类型注释中移除 | 中 |
|
||||
| P2-8 | 3 个遗留同步函数未清理 | 移除 `loadSaaSSession`/`saveSaaSSession`/`clearSaaSSession` | 小 |
|
||||
| P2-9 | dashboard_stats 7 次串行查询 | 合并为单次 SQL 查询 | 小 |
|
||||
| P2-10 | Admin 5 个列表页面分页未连接 API | 将分页状态传递到 API 调用 | 小 |
|
||||
| P2-11 | `computeConfigDiff`/`syncConfig` saas-client 定义但未使用 | 移除或统一迁移向导调用路径 | 小 |
|
||||
| P2-12 | Admin UI catch 块无用户可见错误反馈 | 添加全局 Toast 组件 | 小 |
|
||||
|
||||
### P3 — LOW(测试补充)
|
||||
|
||||
| # | 问题 | 修复方案 | 工作量 |
|
||||
|---|------|---------|--------|
|
||||
| P3-1 | auth/account/model_config/migration 缺单元测试 | 添加 handler/service 层测试 | 大 |
|
||||
|
||||
---
|
||||
|
||||
## 十二、审计结论
|
||||
|
||||
### SaaS 后端健康度: **良好(~88%)**
|
||||
|
||||
**优势**:
|
||||
- 功能-代码对齐率 97.7%(43/44 端点)
|
||||
- 安全基础设施成熟(Argon2 + TOTP + RBAC + AES-256-GCM + CSRF + SSRF 防护)
|
||||
- Admin UI 覆盖所有管理功能(13 页面)
|
||||
- 桌面端集成完整(登录/设备/Relay/配置迁移)
|
||||
- 测试覆盖 86 个单元测试
|
||||
- 代码质量高:零 TODO/FIXME,错误处理一致
|
||||
|
||||
**待改进**:
|
||||
- 1 个 CRITICAL 安全漏洞(`sync_config` 权限检查缺失)
|
||||
- 2 个 HIGH 缺陷(用户级 API Key 未被 Relay 消费;Admin 权限过滤逻辑错误)
|
||||
- 1 个 MEDIUM 功能 Bug(`created` 计数永远为 0)
|
||||
- Config 模块审计日志完全缺失
|
||||
- Admin UI 分页未连接 API(5 个页面)
|
||||
- Admin UI 无前端路由保护
|
||||
- 5 个配置字段定义但未执行
|
||||
|
||||
### 修正 V6 评估
|
||||
|
||||
V6 审计将 SaaS 完成度评估为 18%,原因是将 Tauri 端 AI 能力(Agent/Skill/Hand/Pipeline/Memory/Intelligence/Browser/OpenViking)的缺失计入 SaaS 差距。**这是错误的**——SaaS 的设计定位是系统管理(账号/权限/relay),不负责 AI 能力。在正确定位下,SaaS 完成度为 **~88%**(V7 初评 90% 下调 2%,因发现 Admin UI 权限 Bug 和分页未连接),修复 P0-P2 项即可达到 95%+。
|
||||
|
||||
---
|
||||
|
||||
*审计完成。本报告基于 2026-03-28 代码快照(worktree-saas-backend 分支,commit bc12f68),所有发现均可通过文档中引用的文件路径和行号验证。*
|
||||
339
docs/archive/old-audits/COMPREHENSIVE_AUDIT_V8.md
Normal file
@@ -0,0 +1,339 @@
|
||||
# ZCLAW SaaS+Tauri 系统性功能审计报告 V8
|
||||
|
||||
> **审计日期**: 2026-03-29
|
||||
> **审计范围**: 全量三端审计 — SaaS 后端 + Tauri 桌面端 + Admin 管理后台
|
||||
> **审计方法**: 五步审计流程 + 十项通用清单 + 五种差距模式 + 安全专项
|
||||
> **前次审计**: V7 (2026-03-28, 已归档)
|
||||
|
||||
---
|
||||
|
||||
## 一、执行摘要
|
||||
|
||||
| 指标 | 数值 |
|
||||
|------|------|
|
||||
| **SaaS API 端点** | 76+ (9 模块, 22+ 数据表) |
|
||||
| **Tauri 命令** | 150+ (73 个 invoke 调用) |
|
||||
| **Admin 页面** | 12 (含 login) |
|
||||
| **文档-代码对齐率** | ~95% |
|
||||
| **数据流连通率** | 60% (3/5 完整连通, 1 部分连通, 1 断裂) |
|
||||
| **Dead Code** | 28+ `#[allow(dead_code)]`, 35+ 未调用 API 方法 |
|
||||
| **安全漏洞** | 1 CRITICAL + 2 HIGH + 2 MEDIUM |
|
||||
| **差距模式发现** | 12 个 (P0×1, P1×4, P2×4, P3×3) |
|
||||
| **整体完成度** | **~82%** (核心功能可用,集成链路存在断裂) |
|
||||
|
||||
---
|
||||
|
||||
## 二、功能清单与完成度矩阵
|
||||
|
||||
### 2.1 架构层
|
||||
|
||||
| 功能 | 设计目标 | SaaS | Tauri | Admin | 完成度 | 关键差距 |
|
||||
|------|---------|------|-------|-------|--------|---------|
|
||||
| 通信层 | 三模式连接 (Kernel/Gateway/SaaS) | N/A | ✅ | N/A | 85% | hand_run 桩命令 |
|
||||
| 状态管理 | 18 Zustand Store | N/A | N/A | N/A | 80% | 消息不持久化 |
|
||||
| 安全认证 | Ed25519+JWT+TOTP | ✅ | ✅ | ✅ | 80% | 生物识别/FIDO2 未实现 |
|
||||
|
||||
### 2.2 核心功能
|
||||
|
||||
| 功能 | 设计目标 | SaaS | Tauri | Admin | 完成度 | 关键差距 |
|
||||
|------|---------|------|-------|-------|--------|---------|
|
||||
| 聊天界面 | 流式响应+多模型 | ✅ Relay | ✅ Stream | N/A | 92% | 超长消息卡顿 |
|
||||
| Agent 分身 | CRUD+模板+切换 | ✅ Template | ✅ Agent | ✅ Template | 85% | 导入/导出未实现 |
|
||||
| Hands 系统 | 9+ 自主能力 | N/A | ✅ 9 Hands | N/A | 70% | Predictor/Lead 无代码 |
|
||||
|
||||
### 2.3 智能层
|
||||
|
||||
| 功能 | 设计目标 | SaaS | Tauri | Admin | 完成度 | 关键差距 |
|
||||
|------|---------|------|-------|-------|--------|---------|
|
||||
| Agent 记忆 | 跨会话+语义搜索 | N/A | ✅ Viking | N/A | 90% | 大量记忆检索变慢 |
|
||||
| 身份演化 | SOUL.md+自动改进 | N/A | ✅ | N/A | 70% | Tauri 模式内存存储重启丢失 |
|
||||
| 反思引擎 | 自动分析+建议 | N/A | ✅ | N/A | 65% | 建议具体性待改进 |
|
||||
| 心跳巡检 | 定期巡检+主动提醒 | ✅ 设备心跳 | ✅ | N/A | 70% | 持久化调度缺失 |
|
||||
| 自主授权 | 三级授权+审批 | N/A | ✅ | N/A | 75% | 批量审批未实现 |
|
||||
| 上下文压缩 | 智能摘要 | N/A | ✅ | N/A | 75% | LLM 增强摘要未使用 |
|
||||
|
||||
### 2.4 平台层
|
||||
|
||||
| 功能 | 设计目标 | SaaS | Tauri | Admin | 完成度 | 关键差距 |
|
||||
|------|---------|------|-------|-------|--------|---------|
|
||||
| 技能系统 | 69 SKILL.md | N/A | ✅ | N/A | 80% | WASM/Native 未实现 |
|
||||
| 智能路由 | 语义匹配 | N/A | ❌ | N/A | 50% | SemanticSkillRouter 核心未实现 |
|
||||
| Pipeline DSL | YAML 工作流 | N/A | ✅ | N/A | 90% | 无重大差距 |
|
||||
| SaaS 平台 | 云端能力 | ✅ | ✅ | ✅ | 88% | SQL 注入+配置单向同步+遥测空转 |
|
||||
|
||||
---
|
||||
|
||||
## 三、五步审计结果
|
||||
|
||||
### 3.1 Step 1: 文档对齐
|
||||
|
||||
| 检查项 | 结果 |
|
||||
|--------|------|
|
||||
| SaaS API 路由 vs 文档 | ✅ 76+ 端点全部对齐 |
|
||||
| Tauri 命令 vs 文档 | ✅ 150+ 命令已注册 |
|
||||
| Admin 页面 vs 文档 | ✅ 12 页面全部存在 |
|
||||
| 功能文档声称 vs 实际 | ⚠️ 部分功能声称高于实际 (智能路由 50% 声称 Phase 1 完成) |
|
||||
|
||||
**对齐率: ~95%**
|
||||
|
||||
### 3.2 Step 2: 数据流追踪
|
||||
|
||||
| # | 数据流 | 状态 | 断点 |
|
||||
|---|--------|------|------|
|
||||
| DF1 | 认证 (Desktop→SaaS) | ✅ 完整 | 无 |
|
||||
| DF2 | 聊天 Relay (Desktop→SaaS→LLM) | ⚠️ 部分 | chatStore SaaS 模式走 WS 而非 HTTP relay |
|
||||
| DF3 | 配置同步 (Desktop↔SaaS) | ❌ 单向 | Pull✅, Push/Diff❌ (定义但未调用) |
|
||||
| DF4 | 设备管理 (Desktop→SaaS) | ✅ 完整 | 心跳不传 OS/version |
|
||||
| DF5 | 遥测上报 (Desktop→SaaS) | ❌ 断裂 | recordLLMUsage/recordAuditEvent 零调用 |
|
||||
|
||||
**连通率: 60% (3/5 完整)**
|
||||
|
||||
### 3.3 Step 3: Dead Code 识别
|
||||
|
||||
#### Rust `#[allow(dead_code)]` — 28 处
|
||||
|
||||
| 分类 | 数量 | 说明 |
|
||||
|------|------|------|
|
||||
| Intelligence 模块 | 12 | heartbeat/reflection/identity/compactor 预留给未来 Tauri 命令 |
|
||||
| Memory 模块 | 3 | persistent.rs 遗留迁移代码 |
|
||||
| Runtime 驱动 | 4 | 反序列化字段未被访问 |
|
||||
| Kernel/Pipeline | 4 | 预留功能 (export, intent, stage) |
|
||||
| lib.rs | 2 | HealthStatus 枚举 + legacy 函数 |
|
||||
| Growth | 2 | 缓存+存储预留 |
|
||||
|
||||
#### 未调用的 SaaS API 方法 — 35+ 个
|
||||
|
||||
**需要关注的桌面端方法 (应在 desktop 中使用但未使用)**:
|
||||
- `healthCheck()` — 未被任何 health check 调用使用
|
||||
- `listDevices()` — 设备列表未在桌面端展示
|
||||
- `getRelayTask()` — 单个任务查询未使用
|
||||
- `computeConfigDiff()` — ❌ 零调用,配置差异计算断裂
|
||||
- `syncConfig()` — ❌ 零调用,配置推送断裂
|
||||
|
||||
**Admin 专用方法 (桌面端不使用是正常的)**:
|
||||
- Provider/Model/Account/Role/Permission CRUD (~30 个)
|
||||
- 这些方法在 admin/src/ 中通过独立的 api-client.ts 调用
|
||||
|
||||
#### Rust TODO/FIXME — 5 处
|
||||
|
||||
| 文件 | 行号 | 内容 |
|
||||
|------|------|------|
|
||||
| pipeline_commands.rs | 529 | `// TODO: use actual time` |
|
||||
| pipeline_commands.rs | 869 | `// TODO: add pattern support` |
|
||||
| kernel/src/registry.rs | 56 | `// TODO: Track this` |
|
||||
| kernel/src/export/html.rs | 17 | `// TODO: Implement template-based HTML export` |
|
||||
| pipeline/src/actions/orchestration.rs | 41 | `// TODO: implement graph storage` |
|
||||
|
||||
### 3.4 Step 4: 接口一致性
|
||||
|
||||
#### TS 类型差异 — 10+ 组
|
||||
|
||||
| 类型对 | 主要差异 |
|
||||
|--------|---------|
|
||||
| AccountPublic | admin: 联合类型 role/status; desktop: string |
|
||||
| OperationLog vs OperationLogInfo | id 类型 string vs number; details 类型不同 |
|
||||
| ConfigItem vs SaaSConfigItem | current_value 类型不同; desktop 多 created_at/updated_at |
|
||||
| RelayTask vs RelayTaskInfo | status 联合类型 vs string; desktop 多 max_attempts/created_at |
|
||||
| PromptTemplate vs PromptTemplateInfo | source/status 联合类型 vs string |
|
||||
| Provider vs ProviderInfo | admin 有 api_key 字段; desktop 无 |
|
||||
| Model vs ModelInfo | desktop 多 created_at/updated_at |
|
||||
|
||||
### 3.5 Step 5: 端到端验证
|
||||
|
||||
| 测试流程 | 结果 | 说明 |
|
||||
|----------|------|------|
|
||||
| 用户注册→登录→获取信息 | ✅ | 完整链路通畅 |
|
||||
| 登录→设备注册→心跳 | ✅ | 降级逻辑正常 |
|
||||
| 配置 Pull | ✅ | 仅拉取方向 |
|
||||
| 配置 Push/Diff | ❌ | 方法未调用 |
|
||||
| Relay chat→SSE | ✅ | llm-service.ts 路径完整 |
|
||||
| Admin 登录→管理→CRUD | ✅ | 全部页面可操作 |
|
||||
|
||||
---
|
||||
|
||||
## 四、十项通用审计清单
|
||||
|
||||
| # | 审计点 | 结果 | 说明 |
|
||||
|---|--------|------|------|
|
||||
| 1 | 代码存在性 | ✅ 95% | 所有文档声明功能有对应代码 |
|
||||
| 2 | 调用链连通 | ⚠️ 70% | 遥测/配置推送/OTA 链路断裂 |
|
||||
| 3 | 配置传递 | ✅ 90% | saas-config.toml 端到端有效 |
|
||||
| 4 | 降级策略 | ✅ 85% | 3 次失败→tauri 模式降级正常 |
|
||||
| 5 | 错误处理 | ⚠️ 75% | Desktop 401 不自动 logout |
|
||||
| 6 | 安全审计 | ❌ 60% | SQL 注入 + 权限缺失 |
|
||||
| 7 | 日志记录 | ⚠️ 70% | migration/telemetry 模块缺 operation_logs |
|
||||
| 8 | 测试覆盖 | ✅ 80% | SaaS 62 个集成测试, 但覆盖率不足 |
|
||||
| 9 | 类型一致性 | ⚠️ 70% | 10+ 组类型定义不同步 |
|
||||
| 10 | 前后端接口匹配 | ⚠️ 75% | 大部分匹配, 部分字段差异 |
|
||||
|
||||
---
|
||||
|
||||
## 五、五种差距模式
|
||||
|
||||
### 5.1 "写了没接" — 5 项确认
|
||||
|
||||
| # | 项目 | 位置 | 严重级别 |
|
||||
|---|------|------|---------|
|
||||
| G-01 | `recordLLMUsage` / `recordAuditEvent` 零外部调用 | telemetry-collector.ts | **P0** |
|
||||
| G-02 | `startPromptOTASync` 从未调用 | llm-service.ts | **P1** |
|
||||
| G-05 | `computeConfigDiff` / `syncConfig` push 未接入 | saas-client.ts | **P1** |
|
||||
| G-10 | `hand_run_status` / `hand_run_list` 后端桩命令 | kernel_commands.rs | **P3** |
|
||||
| — | `healthCheck()` 未被 health check 流程调用 | saas-client.ts | **P2** |
|
||||
|
||||
### 5.2 "接了没传" — 1 项确认
|
||||
|
||||
| # | 项目 | 位置 | 严重级别 |
|
||||
|---|------|------|---------|
|
||||
| G-04 | 心跳仅传 device_id, 不传 OS/version | saasStore.ts | **P1** |
|
||||
|
||||
### 5.3 "传了没存" — 2 项确认
|
||||
|
||||
| # | 项目 | 位置 | 严重级别 |
|
||||
|---|------|------|---------|
|
||||
| G-06 | telemetry 端点不写 operation_logs | telemetry/handlers.rs | **P2** |
|
||||
| G-09 | 心跳不写 operation_logs | account/handlers.rs | **P2** |
|
||||
|
||||
### 5.4 "存了没用" — 2 项确认
|
||||
|
||||
| # | 项目 | 位置 | 严重级别 |
|
||||
|---|------|------|---------|
|
||||
| G-03 | `max_queue_size` / `max_concurrent` relay 未消费 | relay/service.rs | **P1** |
|
||||
| G-07 | `account_api_keys` 被 relay 绕过 (用 provider_key_pool) | model_config/ | **P2** |
|
||||
|
||||
### 5.5 "双系统不同步" — 2 项确认
|
||||
|
||||
| # | 项目 | 说明 | 严重级别 |
|
||||
|---|------|------|---------|
|
||||
| G-08 | Desktop 401 不自动 logout, Admin 会 | 用户体验不一致 | **P2** |
|
||||
| G-12 | 双端错误类型不统一 (SaaSApiError vs ApiRequestError) | 不可复用 | **P3** |
|
||||
|
||||
---
|
||||
|
||||
## 六、安全审计专项
|
||||
|
||||
### 6.1 CRITICAL: SQL 注入
|
||||
|
||||
**文件**: `crates/zclaw-saas/src/agent_template/service.rs`
|
||||
|
||||
全文件使用 `format!()` 直接拼接用户输入到 SQL, 依赖手工 `replace('\'', "''")` 转义。这是项目中**唯一未使用 `$N` 参数化查询**的 service 文件。
|
||||
|
||||
**受影响的操作**:
|
||||
- `list_templates()` — WHERE 条件 (category, source, visibility, status)
|
||||
- `update_template()` — SET 字段 (description, model, system_prompt, tools, capabilities, visibility, status) + WHERE id
|
||||
|
||||
**攻击向量示例**:
|
||||
```sql
|
||||
-- category 参数: `' OR 1=1 --` → 绕过 WHERE 条件
|
||||
-- id 参数: `' OR '1'='1` → 更新所有记录
|
||||
```
|
||||
|
||||
**修复方案**: 改用 `$N` 参数化查询, 参照 `account/service.rs` 和 `model_config/service.rs` 的实现模式。
|
||||
|
||||
### 6.2 HIGH: 部分模块使用 format! 构造 SQL (但有 $N 绑定)
|
||||
|
||||
**文件**: `prompt/service.rs`, `telemetry/service.rs`
|
||||
|
||||
这些文件在 WHERE 条件拼接时使用 `format!()`, 但值通过 `.replace('\'', "''")` 转义。虽然后续使用 `$N` 绑定值, 但 WHERE 条件本身的构造仍依赖手工转义。
|
||||
|
||||
### 6.3 HIGH: 配置同步缺少权限检查
|
||||
|
||||
`POST /api/v1/config/sync` (migration/handlers.rs) 端点未验证调用者是否有 admin 权限。任何已认证用户都可以推送配置。
|
||||
|
||||
### 6.4 MEDIUM: 配额限制未执行
|
||||
|
||||
`RelayConfig` 定义了 `max_queue_size` (默认 1000) 和 `max_concurrent_per_provider` (默认 5), 但 `execute_relay` 中未做队列容量和并发控制检查。
|
||||
|
||||
### 6.5 MEDIUM: Desktop 401 处理不完整
|
||||
|
||||
Desktop 端 `SaaSClient` 在 401 刷新失败后不自动 logout, 可能导致用户卡在过期会话中。Admin 端会自动跳转到登录页。
|
||||
|
||||
---
|
||||
|
||||
## 七、问题优先级与修复计划
|
||||
|
||||
### P0 — 立即修复 (阻塞功能)
|
||||
|
||||
| # | 问题 | 修复方案 | 影响范围 | 预估 |
|
||||
|---|------|---------|---------|------|
|
||||
| G-01 | 遥测系统全链路空转 | 在 llm-service.ts 的 chatCompletion 回调和 intelligence-hooks 中调用 recordLLMUsage / recordAuditEvent | telemetry-collector.ts, llm-service.ts, intelligence_hooks.rs | 2h |
|
||||
| SEC-01 | SQL 注入 (agent_template) | 改用 `$N` 参数化查询 | agent_template/service.rs | 2h |
|
||||
|
||||
### P1 — 本周修复 (功能断裂)
|
||||
|
||||
| # | 问题 | 修复方案 | 影响范围 | 预估 |
|
||||
|---|------|---------|---------|------|
|
||||
| G-02 | Prompt OTA 未启动 | 在 saasStore.restoreSession/login 中调用 startPromptOTASync | llm-service.ts, saasStore.ts | 1h |
|
||||
| G-03 | Relay 无并发限制 | 在 execute_relay 中加入队列容量和并发检查 | relay/service.rs | 2h |
|
||||
| G-04 | 心跳不传 OS/version | 在 deviceHeartbeat 中携带 platform/app_version | saas-client.ts, account/handlers.rs | 1h |
|
||||
| G-05 | 配置只能单向拉取 | 在 saasStore 中接入 computeConfigDiff 和 syncConfig push | saasStore.ts, saas-client.ts | 3h |
|
||||
|
||||
### P2 — 两周内修复 (质量提升)
|
||||
|
||||
| # | 问题 | 修复方案 | 影响范围 | 预估 |
|
||||
|---|------|---------|---------|------|
|
||||
| G-06 | Telemetry 端点缺审计日志 | 添加 log_operation 调用 | telemetry/handlers.rs | 1h |
|
||||
| G-07 | account_api_keys 未被消费 | 明确用途: 要么让 relay 消费, 要么移除 | model_config/, relay/ | 4h |
|
||||
| G-08 | Desktop 401 不自动 logout | 在 refresh 失败后调用 saasStore.logout() | saas-client.ts | 1h |
|
||||
| SEC-02 | 配置同步缺权限检查 | 在 migration handler 中添加 admin 权限校验 | migration/handlers.rs | 1h |
|
||||
|
||||
### P3 — 长期优化 (技术债)
|
||||
|
||||
| # | 问题 | 修复方案 | 影响范围 | 预估 |
|
||||
|---|------|---------|---------|------|
|
||||
| G-10 | hand_run 桩命令 | 实现真实的运行状态追踪 | kernel_commands.rs | 3h |
|
||||
| G-12 | 双端错误类型不统一 | 抽取共享错误类型到 @zclaw/types | admin+desktop | 4h |
|
||||
| — | 28 处 dead_code | 评估后移除或保留 | desktop/src-tauri/ | 2h |
|
||||
| — | 10+ 组类型定义差异 | 统一类型定义, 消除不一致 | admin+desktop types | 4h |
|
||||
|
||||
---
|
||||
|
||||
## 八、三端完成度评估
|
||||
|
||||
### SaaS 后端: **88%**
|
||||
|
||||
| 模块 | API 路由 | 完成度 | 主要问题 |
|
||||
|------|---------|--------|---------|
|
||||
| Auth | 8 | 95% | refresh 缺审计日志 |
|
||||
| Account | 12 | 90% | dashboard 7 次串行查询 |
|
||||
| Model Config | 14 | 90% | account_api_keys 未被消费 |
|
||||
| Relay | 9 | 85% | 无并发限制, SSRF 需复核 |
|
||||
| Migration | 9 | 70% | push 缺权限, 5 端点缺审计日志 |
|
||||
| Role | 7 | 95% | 无重大问题 |
|
||||
| Prompt OTA | 8 | 90% | 桌面端未启动 OTA |
|
||||
| Agent Template | 5 | 75% | **SQL 注入** |
|
||||
| Telemetry | 4 | 80% | 桌面端未调用上报函数 |
|
||||
|
||||
### Tauri 桌面端: **78%**
|
||||
|
||||
| 子系统 | 命令数 | 完成度 | 主要问题 |
|
||||
|--------|-------|--------|---------|
|
||||
| Kernel | 29 | 85% | hand_run 桩, scheduled_task 未实现 |
|
||||
| Pipeline | 13 | 90% | 时间戳占位符 |
|
||||
| Viking | 13 | 95% | 无重大问题 |
|
||||
| LLM | 3 | 95% | 无重大问题 |
|
||||
| Intelligence | 6 | 80% | 多个预留函数 |
|
||||
| Browser | 23 | 85% | 需要 Fantoccini 运行时 |
|
||||
| SaaS 集成 | 30+ 方法 | 65% | 35+ 方法未调用, 遥测断裂 |
|
||||
|
||||
### Admin 管理后台: **85%**
|
||||
|
||||
| 维度 | 完成度 | 主要问题 |
|
||||
|------|--------|---------|
|
||||
| 页面覆盖 | 95% | 12 个页面全覆盖 |
|
||||
| API 调用 | 90% | 分页未连接 API |
|
||||
| 认证 | 90% | token 刷新逻辑完善 |
|
||||
| 类型定义 | 75% | 与桌面端不一致 |
|
||||
|
||||
---
|
||||
|
||||
## 九、关键决策建议
|
||||
|
||||
1. **遥测系统** — 必须在聊天回调和智能层 hook 中接入 recordLLMUsage, 否则 SaaS 端的遥测统计页面展示全零数据
|
||||
2. **SQL 注入** — agent_template/service.rs 必须立即改为参数化查询, 这是生产安全红线
|
||||
3. **配置同步** — 建议实现双向同步, 当前只能 SaaS→Desktop 单向拉取
|
||||
4. **类型共享** — 考虑抽取 @zclaw/types 共享包, 消除 admin/desktop 类型不一致
|
||||
5. **Prompt OTA** — 桌面端必须在登录后启动 OTA 同步, 否则 prompt 更新无法到达客户端
|
||||
|
||||
---
|
||||
|
||||
*审计报告结束*
|
||||
308
docs/archive/old-audits/COMPREHENSIVE_AUDIT_V9.md
Normal file
@@ -0,0 +1,308 @@
|
||||
# ZCLAW 全面系统审计报告 V9
|
||||
|
||||
> **审计日期**: 2026-03-29
|
||||
> **审计范围**: 全量四端审计 — SaaS 后端 + Tauri 桌面端 + Admin 管理后台 + Rust Crates
|
||||
> **审计方法**: V8 基线重验证 + 五步审计流程 + 十项通用检查 + 五种差距模式 + 安全专项
|
||||
> **前次审计**: V8 (2026-03-29, 发现 12 差距 + 5 安全)
|
||||
> **本次审计**: 8 Agent 并行执行,覆盖 11 crate / 130+ Tauri 命令 / 76+ API 端点 / 55+ 组件
|
||||
|
||||
---
|
||||
|
||||
## 一、执行摘要
|
||||
|
||||
| 指标 | V8 数值 | V9 数值 | 变化 |
|
||||
|------|---------|---------|------|
|
||||
| **SaaS API 端点** | 76+ | 76+ | 不变 |
|
||||
| **Tauri 命令** | 150+ | **130** | 修正 (文档从 58+ 修正) |
|
||||
| **Admin 页面** | 12 | 12 | 不变 |
|
||||
| **文档-代码对齐率** | ~95% | ~95% | 不变 |
|
||||
| **数据流连通率** | 60% (3/5) | **65%** (4/6 部分连通, 1 断裂) | 提升 |
|
||||
| **Dead Code** | 28+ `#[allow(dead_code)]` | **18** (desktop) + 13 (crates) | 减少 |
|
||||
| **安全漏洞** | 1 CRITICAL + 2 HIGH | **0 HIGH** + 2 MEDIUM (SEC-V9-01 确认为误报) | 改善 |
|
||||
| **差距模式** | 12 个 | **14 个** (新增 4, 修复 8, 保留 4, 误报消除 2) | 改善 |
|
||||
| **整体完成度** | ~82% | **~85%** | 提升 |
|
||||
|
||||
### V8 修复确认
|
||||
|
||||
| V8_ID | 描述 | V8级别 | V9状态 |
|
||||
|-------|------|--------|--------|
|
||||
| SEC-01 | agent_template SQL 注入 | CRITICAL | **FIXED** — 已改用 $N 参数化查询 |
|
||||
| SEC-02 | prompt/service.rs SQL 注入 | HIGH | **STILL_PRESENT** — 行 94/97/100 仍用 format!() |
|
||||
| SEC-03 | config sync 缺权限 | HIGH | **FIXED** — check_permission 已到位 |
|
||||
| G-01 | 遥测零调用 | P0 | **FIXED** — llm-service.ts 已调用 |
|
||||
| G-02 | startPromptOTASync 未调用 | P1 | **FIXED** — saasStore.ts 多处调用 |
|
||||
| G-03 | relay 队列未消费 | P1 | **PARTIALLY_FIXED** — 队列容量已检查,per-provider 并发未实现 |
|
||||
| G-04 | 心跳不传 OS/version | P1 | **FIXED** — 已传 platform + app_version |
|
||||
| G-05 | config diff/sync 未调用 | P1 | **FIXED** — 双向同步已实现 |
|
||||
| G-06 | telemetry 不写 operation_logs | P2 | **FIXED** — 已调用 log_operation |
|
||||
| G-07 | account_api_keys 被 relay 绕过 | P2 | **STILL_PRESENT** — relay 使用独立 key_pool |
|
||||
| G-08 | Desktop 401 不 logout | P2 | **FIXED** — token 刷新失败时清理会话 |
|
||||
| G-09 | 心跳不写 operation_logs | P2 | **STILL_PRESENT** — 高频操作合理 |
|
||||
| G-10 | hand_run 桩命令 | P3 | **FALSE_POSITIVE** — 有真实实现 |
|
||||
| G-12 | 双端错误类型不统一 | P3 | **STILL_PRESENT** — SaaSApiError vs ApiRequestError |
|
||||
|
||||
**修复率**: 8/12 FIXED + 1 PARTIALLY_FIXED + 1 FALSE_POSITIVE + 2 STILL_PRESENT = **75% 修复率**
|
||||
|
||||
---
|
||||
|
||||
## 二、功能清单与完成度矩阵
|
||||
|
||||
### 2.1 架构层
|
||||
|
||||
| 功能 | 设计目标 | 完成度 | 关键发现 |
|
||||
|------|---------|--------|---------|
|
||||
| 通信层 | 三模式连接 (Kernel/Gateway/SaaS) | **90%** | 完整;130 个 Tauri 命令 vs 文档声称 58+ |
|
||||
| 状态管理 | 18+ Zustand Store | **80%** | audit-logger.ts 无消费者 |
|
||||
| 安全认证 | Ed25519+JWT+TOTP | **85%** | SSRF 防护全面;relay 输入验证可加强 |
|
||||
|
||||
### 2.2 核心功能
|
||||
|
||||
| 功能 | 设计目标 | 完成度 | 关键发现 |
|
||||
|------|---------|--------|---------|
|
||||
| 聊天界面 | 流式响应+多模型 | **92%** | 完整链路通畅 |
|
||||
| Agent 分身 | CRUD+模板+切换 | **85%** | 导入/导出未实现 |
|
||||
| Hands 系统 | 9+ 自主能力 | **70%** | Predictor/Lead 无代码;审批后不自动执行 |
|
||||
|
||||
### 2.3 智能层
|
||||
|
||||
| 功能 | 设计目标 | 完成度 | V9 修正 | 关键发现 |
|
||||
|------|---------|--------|---------|---------|
|
||||
| Agent 记忆 | 跨会话+语义搜索 | **90%** | - | 检索可用,但自动提取链路断裂 |
|
||||
| 身份演化 | SOUL.md+自动改进 | **90%** | ↑ (文档称 70%) | persona_evolver 等 4 个模块已删除但功能完整 |
|
||||
| 反思引擎 | 自动分析+建议 | **85%** | ↑ (文档称 65%) | LLM 集成完整,VikingStorage 持久化 |
|
||||
| 心跳巡检 | 定期巡检+提醒 | **90%** | ↑ (文档称 70%) | 894 行完整实现,10 个 Tauri 命令 |
|
||||
| 自主授权 | 三级授权+审批 | **75%** | - | 审批通过后不自动执行 (设计缺陷) |
|
||||
| 上下文压缩 | 智能摘要 | **90%** | ↑ (文档称 75%) | 规则+LLM 摘要均已实现 |
|
||||
|
||||
### 2.4 平台层
|
||||
|
||||
| 功能 | 设计目标 | 完成度 | 关键发现 |
|
||||
|------|---------|--------|---------|
|
||||
| 技能系统 | 70 SKILL.md | **80%** | WASM/Native 未实现 |
|
||||
| 智能路由 | 语义匹配 | **50%** | SemanticSkillRouter 核心未实现 |
|
||||
| Pipeline DSL | YAML 工作流 | **87%** | pipeline-complete 事件未监听 |
|
||||
| SaaS 平台 | 云端能力 | **90%** | Worker + Scheduler 系统上线;SQL 迁移 Schema v6;多环境配置;prompt SQL 注入已确认为误报 |
|
||||
|
||||
### 2.5 智能层评分汇总
|
||||
|
||||
| 模块 | 评分 | 说明 |
|
||||
|------|------|------|
|
||||
| zclaw-growth | **70%** | ExtractionDriver 已修复 (BREAK-01),PromptInjector/MemoryRetriever/GrowthTracker 仍未接入 |
|
||||
| intelligence/ | **78%** | 功能完整度好 |
|
||||
| zclaw-pipeline | **87%** | 实现质量高 |
|
||||
| zclaw-memory | **78%** | CRUD 完整,测试充分 |
|
||||
| **整体** | **~85%** | 记忆闭环部分接通 (BREAK-01 已修复),剩余 BREAK-02 和 PromptInjector 待接入 |
|
||||
|
||||
---
|
||||
|
||||
## 三、关键发现
|
||||
|
||||
### 3.1 安全发现
|
||||
|
||||
| ID | 严重度 | 组件 | 描述 | 证据 |
|
||||
|----|--------|------|------|------|
|
||||
| SEC-V9-01 | **HIGH** → **FALSE_POSITIVE** | prompt/service.rs | ~~SQL 注入~~: format!() 仅构建 `$N` 参数占位符索引,实际值通过 .bind() 参数化绑定 (行 93-105, 123-125, 130-132),非 SQL 注入 | 行 94, 97, 100 |
|
||||
| SEC-V9-02 | MEDIUM | relay/handlers.rs | chat_completions 缺少输入验证 (messages 格式, temperature 范围, max_tokens 上限) | 行 18-23 |
|
||||
| SEC-V9-03 | MEDIUM | model_config/service.rs | query.bind(format!("{}", p)) 类型强制转换 | 行 134 |
|
||||
|
||||
### 3.2 功能断裂
|
||||
|
||||
| ID | 严重度 | 组件 | 描述 | 证据 |
|
||||
|----|--------|------|------|------|
|
||||
| BREAK-01 | **CRITICAL** → **FIXED** | zclaw-growth | ~~LlmDriverForExtraction 无生产实现~~: `extraction_adapter.rs` 已实现 TauriExtractionDriver,桥接 Kernel LlmDriver 到 LlmDriverForExtraction trait | extraction_adapter.rs |
|
||||
| BREAK-02 | **CRITICAL** | intelligence_hooks | 记忆提取流程未接入 post_conversation_hook | GrowthIntegration::process_conversation 未被调用 |
|
||||
| BREAK-03 | HIGH | kernel_commands | 审批通过后不自动执行 Hand — approval_respond 只更新状态 | kernel_commands.rs approval_respond |
|
||||
| BREAK-04 | HIGH | desktop | pipeline-complete 事件未监听 — Pipeline 完成结果前端无法接收 | pipeline_commands.rs:480 emit 无对应 listen |
|
||||
|
||||
### 3.3 Dead Code
|
||||
|
||||
| ID | 严重度 | 位置 | 描述 |
|
||||
|----|--------|------|------|
|
||||
| DEAD-01 | HIGH | zclaw-growth/injector.rs | PromptInjector 全文件死代码 (4 种格式, token 预算控制) |
|
||||
| DEAD-02 | HIGH | zclaw-growth/retriever.rs | MemoryRetriever 全文件死代码 (QueryAnalyzer + MemoryCache) |
|
||||
| DEAD-03 | MEDIUM | zclaw-growth/tracker.rs | GrowthTracker 全文件死代码 |
|
||||
| DEAD-04 | MEDIUM | zclaw-kernel/director.rs | 907 行,零生产调用者 |
|
||||
| DEAD-05 | MEDIUM | desktop/saas-client.ts | 39 个方法从未被调用 (Admin-only API) |
|
||||
| DEAD-06 | LOW | desktop/audit-logger.ts | 无任何消费者 |
|
||||
| DEAD-07 | LOW | intelligence/validation.rs | 全文件保留为 "future API" |
|
||||
|
||||
### 3.4 文档过时
|
||||
|
||||
| ID | 严重度 | 文档 | 描述 |
|
||||
|----|--------|------|------|
|
||||
| DOC-01 | HIGH | 06-tauri-backend | 声称 58+ 命令,实际 130 |
|
||||
| DOC-02 | HIGH | 02-intelligence-layer | 6 个文档引用已删除模块 (persona_evolver 等) |
|
||||
| DOC-03 | MEDIUM | 00-agent-memory | 声称 90% 但未说明提取链路断裂 |
|
||||
| DOC-04 | MEDIUM | 03-openviking | 描述外部服务器,实际为内部 SqliteStorage |
|
||||
| DOC-05 | LOW | README.md | SKILL.md 数量 69 → 实际 70 |
|
||||
|
||||
---
|
||||
|
||||
## 四、十项通用检查结果
|
||||
|
||||
| # | 检查项 | 判定 | 关键发现 |
|
||||
|---|--------|------|---------|
|
||||
| 1 | 代码存在性 | **PASS** | 11 crate 全部确认;SKILL 70 vs 文档 69 |
|
||||
| 2 | 调用链连通性 | **PASS** | SaaS handler 100% 连通 |
|
||||
| 3 | 配置参数完整性 | **WARN** | batch_window_ms / max_concurrent_per_provider 预留标注,burst 已消费 |
|
||||
| 4 | 降级策略 | **PASS** | 3 种连接模式 + 心跳降级 + 离线队列 |
|
||||
| 5 | 错误处理 | **PASS** | 16 种 SaaS 错误 + 10 种前端分类 + 401 自动登出 |
|
||||
| 6 | 日志完整性 | **WARN** | auth/refresh 缺日志;前端 audit-logger 无消费者 |
|
||||
| 7 | 性能监控 | **PASS** | 全 list 端点分页;Dashboard 2 查询聚合 |
|
||||
| 8 | 安全控制 | **PASS** | SSRF 全面防护;relay 输入验证可加强 |
|
||||
| 9 | 兼容性 | **PASS** | Rust edition 统一;TS strict;Tauri 2.x |
|
||||
| 10 | 文档-代码同步 | **WARN** | Hands 数量不一致;Tauri 命令数严重低估 |
|
||||
|
||||
**总计: 7 PASS / 3 WARN / 0 FAIL**
|
||||
|
||||
---
|
||||
|
||||
## 五、五种差距模式实例
|
||||
|
||||
### 模式 1: "写了没接" (代码存在但未被调用)
|
||||
|
||||
| 项目 | 位置 | 影响 |
|
||||
|------|------|------|
|
||||
| 39 个 saas-client.ts 方法 | desktop/src/lib/saas-client.ts | Admin-only API 暴露在桌面端 |
|
||||
| ~45 个 Tauri 命令 | desktop/src-tauri/src/lib.rs | 注册但前端未 invoke |
|
||||
| PromptInjector (全文件) | zclaw-growth/injector.rs | 设计完善的 token 预算控制完全未用 |
|
||||
| MemoryRetriever (全文件) | zclaw-growth/retriever.rs | QueryAnalyzer + MemoryCache 未用 |
|
||||
| GrowthTracker (全文件) | zclaw-growth/tracker.rs | 成长指标追踪未用 |
|
||||
| director.rs (907 行) | zclaw-kernel/director.rs | 多 Agent 编排零生产调用 |
|
||||
| 7 个 SaaS 端点 | crates/zclaw-saas/src/ | 无 Admin 页面调用 |
|
||||
|
||||
### 模式 2: "接了没传"
|
||||
|
||||
| 项目 | 位置 | 说明 |
|
||||
|------|------|------|
|
||||
| 心跳 OS 版本 | saas-client.ts:763 | 传 navigator.platform 而非真实 OS 版本 |
|
||||
| Relay 优先级 | relay/handlers.rs | 客户端无法指定 priority |
|
||||
| 智能记忆 scope | intelligence-client.ts | find() 回退模式忽略 scope 参数 |
|
||||
|
||||
### 模式 3: "传了没存"
|
||||
|
||||
| 项目 | 位置 | 说明 |
|
||||
|------|------|------|
|
||||
| account_api_keys | relay/key_pool.rs | 用户 API 密钥存储但 relay 从未读取 |
|
||||
|
||||
### 模式 4: "存了没用"
|
||||
|
||||
| 项目 | 位置 | 说明 |
|
||||
|------|------|------|
|
||||
| operation_logs | admin/src/app/ | 无专门查看页面 |
|
||||
| config_sync_logs | admin/src/app/ | 无 Admin 页面 |
|
||||
| account_api_keys | relay/key_pool.rs | relay 使用独立 provider_keys |
|
||||
| relay_tasks 统计 | admin/src/app/ | 无聚合分析页面 |
|
||||
| devices 表 | admin/src/app/ | 无设备管理页面 |
|
||||
|
||||
### 模式 5: "双系统不同步"
|
||||
|
||||
| 项目 | Desktop | Admin | 差异 |
|
||||
|------|---------|-------|------|
|
||||
| OperationLog | details: Record<string, unknown> | details?: string | 类型不匹配 |
|
||||
| AccountPublic | role: string | role: union type | 类型严格度不同 |
|
||||
| LoginResponse | 无 refresh_token | 无 refresh_token | 两端都缺 (后端返回) |
|
||||
| ProviderInfo | api_protocol: string | api_protocol: union | 枚举 vs 字符串 |
|
||||
| Token 刷新 | clearSaaSSession 回退 | window.location 跳转 | 策略不同 |
|
||||
| RelayTaskInfo | error: string \| null | error?: string | nullable vs optional |
|
||||
|
||||
---
|
||||
|
||||
## 六、修复计划 (按优先级)
|
||||
|
||||
### P0: 阻断级 (安全漏洞)
|
||||
|
||||
| # | 问题 | 修复方案 | 工作量 |
|
||||
|---|------|---------|--------|
|
||||
| ~~1~~ | ~~SEC-V9-01: prompt/service.rs SQL 注入~~ | **已确认为误报**: format!() 仅构建 `$N` 占位符索引,值通过 .bind() 绑定 | ~~1h~~ **已完成** |
|
||||
|
||||
### P1: 严重级 (功能断裂)
|
||||
|
||||
| # | 问题 | 修复方案 | 工作量 |
|
||||
|---|------|---------|--------|
|
||||
| ~~2~~ | ~~BREAK-01: LlmDriverForExtraction 无实现~~ | **已完成**: extraction_adapter.rs 实现 TauriExtractionDriver | ~~4h~~ **已完成** |
|
||||
| 3 | BREAK-02: 记忆提取未接入 post_hook | 将 GrowthIntegration::process_conversation() 接入 post_conversation_hook | 2h |
|
||||
| 4 | BREAK-03: 审批后不自动执行 | 在 approval_respond 中,approved=true 时自动触发对应 Hand 执行 | 3h |
|
||||
| 5 | BREAK-04: pipeline-complete 未监听 | 在 workflowStore 或 pipeline-client 中添加 listen('pipeline-complete') | 1h |
|
||||
|
||||
### P2: 高优先级 (质量改进)
|
||||
|
||||
| # | 问题 | 修复方案 | 工作量 |
|
||||
|---|------|---------|--------|
|
||||
| 6 | DEAD-01/02/03: Growth 死代码 | 评估是否接入或清理 PromptInjector/MemoryRetriever/GrowthTracker | 8h |
|
||||
| 7 | DEAD-05: 39 个未调用 saas-client 方法 | 评估是否需要桌面端 Admin 功能入口或移除方法 | 2h |
|
||||
| 8 | DOC-01/02: 文档严重过时 | 更新 Tauri 命令数 (130)、智能层模块状态 | 3h |
|
||||
| 9 | 类型不一致 (6 组) | 统一 Desktop 和 Admin 类型定义 | 4h |
|
||||
| 10 | G-07: account_api_keys 被 relay 绕过 | 决策:统一 key 管理或标记 account_api_keys 为独立功能 | 3h |
|
||||
|
||||
### P3: 中优先级 (技术债务)
|
||||
|
||||
| # | 问题 | 修复方案 | 工作量 |
|
||||
|---|------|---------|--------|
|
||||
| 11 | 配置参数孤儿 (batch_window_ms 等) | 实现消费或移除配置项 | 2h |
|
||||
| 12 | relay 输入验证加强 | 添加 messages 数组、temperature、max_tokens 基本校验 | 2h |
|
||||
| 13 | 前端 audit-logger 集成 | 在 Hand 触发、Agent CRUD 中调用 auditLogger | 2h |
|
||||
| 14 | DEAD-04: director.rs 907 行孤立 | 移至 feature flag 后面或文档标注为未来功能 | 1h |
|
||||
| 15 | config_sync_logs Admin 页面 | 添加 Admin 同步日志查看页面 | 3h |
|
||||
| 16 | operation_logs Admin 页面 | 添加 Admin 操作日志查看页面 | 2h |
|
||||
|
||||
### P4: 低优先级 (可选改进)
|
||||
|
||||
| # | 问题 | 修复方案 | 工作量 |
|
||||
|---|------|---------|--------|
|
||||
| 17 | SKILL.md 数量更新 (69→70) | 更新 README.md | 5min |
|
||||
| 18 | Hands 数量统一 (CLAUDE.md vs README) | 统一口径 | 5min |
|
||||
| 19 | zclaw-channels 评估 | 决定保留或删除近乎空的 crate | 1h |
|
||||
| 20 | trigger_update 接口不匹配 | TS 传 {id, updates} vs Rust 期望平铺参数 | 2h |
|
||||
|
||||
**总工作量估计**: ~~P0 (1h)~~ + ~~P1 (4h 已完成)~~ + P1 (6h 剩余) + P2 (20h) + P3 (10h) + P4 (4h) = **~40h (已完成 5h)**
|
||||
|
||||
---
|
||||
|
||||
## 七、架构健康度评分
|
||||
|
||||
| 模块 | 评分 | 趋势 | 关键问题 |
|
||||
|------|------|------|---------|
|
||||
| zclaw-types | 95% | → | 基础类型,稳定 |
|
||||
| zclaw-memory | 78% | → | 与 zclaw-growth 存储边界模糊 |
|
||||
| zclaw-runtime | 85% | → | 4 个 LLM Driver 完整 |
|
||||
| zclaw-kernel | 80% | → | Director 死代码 |
|
||||
| zclaw-skills | 80% | → | WASM/Native 待实现 |
|
||||
| zclaw-hands | 70% | → | 2 个 Hand 无代码 |
|
||||
| zclaw-protocols | 65% | ↓ | A2A feature-gated,MCP 最小实现 |
|
||||
| zclaw-pipeline | 87% | → | 高质量实现 |
|
||||
| zclaw-growth | **70%** | ↑ | TauriExtractionDriver 已实现 (BREAK-01 修复),PromptInjector/MemoryRetriever/GrowthTracker 仍未接入 |
|
||||
| zclaw-channels | 20% | ↓ | 仅 ConsoleChannel |
|
||||
| zclaw-saas | **92%** | ↑ | Worker + Scheduler + SQL 迁移 v6 + 多环境配置;SQL 注入确认为误报 |
|
||||
| Desktop 前端 | 82% | → | 降级策略完善 |
|
||||
| Admin 后台 | 85% | → | 缺日志/同步日志页面 |
|
||||
| **整体** | **~85%** | **↑** | 核心功能可用,记忆闭环部分修复 (BREAK-01 已修复),SaaS Worker/Scheduler 系统上线 |
|
||||
|
||||
---
|
||||
|
||||
## 八、核心结论
|
||||
|
||||
### 根因分析
|
||||
|
||||
V9 审计发现的根本问题集中在一条断裂的数据链路上:
|
||||
|
||||
**`对话 → 记忆提取 → 存储 → 检索 → 注入 → 增强回复`**
|
||||
|
||||
当前状态:
|
||||
1. LlmDriverForExtraction 的实现 (BREAK-01) — **已修复**: extraction_adapter.rs 实现 TauriExtractionDriver
|
||||
2. post_conversation_hook 的接入 (BREAK-02) — **待修复**: GrowthIntegration::process_conversation 未被调用
|
||||
3. PromptInjector 替代字符串拼接 (DEAD-01) — **待修复**: PromptInjector 全文件死代码
|
||||
|
||||
修复 BREAK-01 后,记忆提取的 LLM 驱动问题已解决。剩余 2 项修复后,智能层的完成度将从 70% 跃升至 85%+。
|
||||
|
||||
### 安全状态
|
||||
|
||||
V8 的 CRITICAL (agent_template SQL 注入) 已修复。V9 的 SEC-V9-01 (prompt SQL 注入) 已确认为误报 (format!() 仅构建参数占位符索引,实际值通过 .bind() 绑定)。仅剩 2 个 MEDIUM 级安全发现 (relay 输入验证、类型强制转换)。SSRF 防护全面,Auth 覆盖完整,密码/TOTP/加密实现安全。
|
||||
|
||||
### 最大改进方向
|
||||
|
||||
1. **记忆闭环修复** — BREAK-01 已修复,剩余 BREAK-02 (post_conversation_hook 接入) 和 DEAD-01 (PromptInjector) 待修复
|
||||
2. **文档更新** — 130 个命令只记录了 58 个,严重低估
|
||||
3. **死代码清理** — Growth crate 3 个核心组件设计完善但未接入 (PromptInjector/MemoryRetriever/GrowthTracker)
|
||||
4. **Admin 补全** — 操作日志、同步日志、设备管理页面缺失
|
||||
5. **SaaS 架构优化** — Worker + Scheduler 已上线,连接池已优化,未来可迁移到 Redis 队列
|
||||
596
docs/archive/old-audits/DEEP_AUDIT_REPORT.md
Normal file
@@ -0,0 +1,596 @@
|
||||
# ZCLAW 功能完成度深度审计报告
|
||||
|
||||
> **审计日期**: 2026-03-27
|
||||
> **修复轮次**: 2026-03-27(P0/P1 第一轮修复完成)
|
||||
> **审计方法**: 五步审计法(文档对齐 → 数据流追踪 → dead_code 识别 → trait 实现 → 端到端验证)
|
||||
> **审计范围**: 全部 10 个 Rust crate + Tauri 后端 + React 前端 + docs/features 文档
|
||||
> **独立性声明**: 本报告独立于此前三份审计报告(VERIFICATION_REPORT、FRONTEND_INTEGRATION_AUDIT、FEATURE_AUDIT_REPORT),所有结论均基于代码实际状态得出。
|
||||
|
||||
---
|
||||
|
||||
## 一、基础数据纠正
|
||||
|
||||
### 1.1 现有审计报告的不准确性
|
||||
|
||||
| 现有报告 | 声称 | 实际 | 偏差原因 |
|
||||
|----------|------|------|----------|
|
||||
| VERIFICATION_REPORT.md | 98.5% (133/135) | ~75% | 包含已删除功能(Team/Swarm),模拟实现标记为可用 |
|
||||
| FRONTEND_INTEGRATION_AUDIT.md | "无僵尸组件" | 基本准确 | 但遗漏了 kernel-client.ts 中的幽灵调用 |
|
||||
| FEATURE_AUDIT_REPORT.md | 85% (22/26) | ~60% | SpeechHand/TwitterHand 误判为"可用",存储双路径未深入验证 |
|
||||
|
||||
### 1.2 基础数据事实
|
||||
|
||||
| 指标 | 文档声称 | 实际验证 | 差异 |
|
||||
|------|----------|----------|------|
|
||||
| Rust crate 数量 | 9 | 10(含 zclaw-pipeline、zclaw-growth) | +2 |
|
||||
| Zustand Store 数量 | 18+ | 14(gatewayStore 已废弃) | -4 |
|
||||
| SKILL.md 文件数量 | 78+ | 69 | -9 |
|
||||
| HAND.toml 文件数量 | 11 | 9(predictor/lead 已删除) | -2 |
|
||||
| Tauri 命令注册数 | 未明确 | 100+ | — |
|
||||
| 前端 invoke 调用数 | 未明确 | ~50 独立命令名 | — |
|
||||
|
||||
---
|
||||
|
||||
## 二、功能完成度矩阵
|
||||
|
||||
### 2.1 架构层
|
||||
|
||||
| 功能 | 文档声称 | 真实完成度 | 差距模式 | 严重度 |
|
||||
|------|----------|-----------|----------|--------|
|
||||
| **通信层** | L4 (85%) | **L4 (85%)** | 无重大差距 | — |
|
||||
| **状态管理** | L4 (85%) | **L4 (80%)** | gatewayStore 废弃但未清理 | LOW |
|
||||
| **安全认证** | L4 (80%) | **L4 (80%)** | 无重大差距 | — |
|
||||
|
||||
### 2.2 核心功能层
|
||||
|
||||
| 功能 | 文档声称 | 真实完成度 | 差距模式 | 严重度 |
|
||||
|------|----------|-----------|----------|--------|
|
||||
| **聊天界面** | L4 (85%) | **L4 (85%)** | 流式响应链路完整 | — |
|
||||
| **Agent 分身** | L4 (90%) | **L4 (85%)** | ~~Tauri 模式下 CRUD 静默失败~~ ✅ 已修复 (H7) | ~~HIGH~~ FIXED |
|
||||
| **Hands 系统** | L4 (70%) | **L3 (60%)** | ~~审批流程被绕过~~ ✅ 已修复 (H8);~~幽灵命令~~ ✅ 已修复 (M1);SpeechHand/TwitterHand 已标记 demo | ~~HIGH~~ PARTIAL |
|
||||
|
||||
### 2.3 智能层
|
||||
|
||||
| 功能 | 文档声称 | 真实完成度 | 差距模式 | 严重度 |
|
||||
|------|----------|-----------|----------|--------|
|
||||
| **Agent 记忆** | L4 (90%) | **L4 (85%)** | ~~双存储路径使用不同数据库~~ ✅ 已修复 (H3) — 统一到 VikingStorage | ~~HIGH~~ FIXED |
|
||||
| **身份演化** | L2 (70%) | **L2 (70%)** | ~~前端回滚 UI 缺失~~ ✅ 已实现 (IdentityChangeProposal.tsx HistoryItem + restoreSnapshot) | ~~MEDIUM~~ FIXED |
|
||||
| **反思引擎** | L2 (65%) | **L2 (65%)** | ~~传入空记忆数组~~ ✅ 已修复 (C2);~~结果未持久化~~ ✅ 已修复 (M4);~~历史只存单条~~ ✅ 已修复 (M4-补 累积存储);LLM 分析待接入 | ~~MEDIUM~~ MOSTLY FIXED |
|
||||
| **心跳引擎** | L2 (70%) | **L2 (60%)** | ~~无持久化~~ ✅ 已修复 (H4);~~历史重启丢失~~ ✅ 已修复 (心跳历史持久化);默认禁用(enabled=false),需前端主动启动 | ~~HIGH~~ MOSTLY FIXED |
|
||||
| **自主授权** | L2 (75%) | **L2 (70%)** | ~~后端无守卫~~ ✅ 已修复 (M5-补 hand_execute/skill_execute 后端守卫) | ~~MEDIUM~~ FIXED |
|
||||
| **上下文压缩** | L2 (75%) | **L2 (70%)** | 规则压缩已集成,LLM 压缩存在但默认关闭 | LOW |
|
||||
|
||||
### 2.4 扩展层
|
||||
|
||||
| 功能 | 文档声称 | 真实完成度 | 差距模式 | 严重度 |
|
||||
|------|----------|-----------|----------|--------|
|
||||
| **技能系统** | L3 (80%) | **L3 (75%)** | ~~PromptOnly 不调用 LLM~~ ✅ 已修复 (C1);现在通过 LlmCompleter 桥接调用 LLM | ~~HIGH~~ FIXED |
|
||||
| **智能路由** | L1 (15%) | **L1 (10%)** | 语义匹配是桩代码(返回 None),从未实例化 | MEDIUM |
|
||||
| **Pipeline DSL** | L2 (75%) | **L2 (70%)** | ~~Presentation 层部分缺失~~ ✅ 已修复 (H6);并行执行实际串行,进度报告粗粒度 | ~~MEDIUM~~ FIXED |
|
||||
| **OpenViking** | L3 (70%) | **L3 (65%)** | 本地服务器启动慢 | LOW |
|
||||
| **Browser 自动化** | L3 (80%) | **L3 (80%)** | Fantoccini 集成完整 | — |
|
||||
| **Channels** | — | **L0 (10%)** | 仅有 ConsoleChannel 测试适配器 | LOW |
|
||||
|
||||
### 2.5 总体完成度
|
||||
|
||||
| 维度 | 文档声称 | 审计结果 | 修复后 |
|
||||
|------|----------|----------|--------|
|
||||
| **整体** | 68% | **~50%** | **~72%** |
|
||||
| **核心可用** | 85% | **75%** | **~92%** |
|
||||
| **真实可用** | 100% | **~55%**(排除模拟实现和 PromptOnly 技能后) | **~80%** |
|
||||
|
||||
---
|
||||
|
||||
## 三、差距清单(按严重度排序)
|
||||
|
||||
### 3.1 CRITICAL 严重度(2 项)
|
||||
|
||||
#### C1: 技能系统 PromptOnly 模式不调用 LLM,69/69 技能仅返回 prompt 模板 ✅ **已修复**
|
||||
- **文件**: `crates/zclaw-skills/src/runner.rs:41-44`
|
||||
- **修复方案**: 定义 `LlmCompleter` trait(`zclaw-skills`),创建 `LlmDriverAdapter` 桥接(`zclaw-kernel`),在 `SkillContext` 中注入 `llm` 字段。`PromptOnlySkill.execute()` 优先调用 LLM 生成结果,无 LLM 时回退到原始 prompt 文本。
|
||||
- **修复文件**: `skill.rs`, `runner.rs`, `kernel.rs`
|
||||
- **影响**: 整个技能系统本质上是**prompt 模板库**,不是执行引擎。`skill_execute` 返回的是格式化后的 prompt 文本,不是 AI 生成的内容。技能在 kernel 的 `build_skill_aware_system_prompt()` 中作为系统提示注入 LLM 上下文(这部分是有效的),但直接执行技能本身不产生 AI 输出。
|
||||
- **差距模式**: 写了没接 — 执行框架完整但核心处理逻辑缺失
|
||||
- **根因**: PromptOnly 模式设计为"注入 prompt 后由 Agent Loop 的 LLM 调用处理",而非独立执行。但 `execute_skill` Tauri 命令直接返回 prompt 文本给前端,前端将其作为"执行结果"展示,造成功能完整的假象。
|
||||
- **解决方案**:
|
||||
- 短期: 在 PromptOnlySkill 中集成 LLM 调用,将 prompt 发送给 LLM 后返回生成结果
|
||||
- 或: 在 kernel_commands.rs 的 skill_execute 中,获取 prompt 后通过 kernel 的 LLM driver 生成结果
|
||||
- 或: 在前端展示时明确标注这是"prompt 模板"而非"执行结果"
|
||||
|
||||
#### C2: 反思引擎传入空记忆数组,整个子系统是空操作 ✅ **已修复**
|
||||
- **文件**: `desktop/src-tauri/src/intelligence_hooks.rs:65`
|
||||
- **修复方案**: 新增 `query_memories_for_reflection()` 函数,在 `reflect()` 调用前从 VikingStorage 查询最多 50 条 agent 记忆,转换为 `MemoryEntryForAnalysis` 后传入。同时为 `post_conversation_hook` 添加 `user_message` 参数。
|
||||
- **修复文件**: `intelligence_hooks.rs`, `kernel_commands.rs`
|
||||
- **影响**: `analyze_patterns()` 对空数组进行阈值检测(task ≥ 5、preference ≥ 5 等),**永远无法触发任何模式检测**。反思引擎的 patterns、improvements、identity_proposals **永远是空的**。整个反思子系统(~500 行代码 + 文档 + UI 组件)实际上**从未产生过任何有意义的输出**。
|
||||
- **差距模式**: 接了没传 — 反思逻辑完整但调用时传入了空数据
|
||||
- **根因**: `post_conversation_hook` 应该先从 VikingStorage 获取记忆数据再传给 `reflect()`
|
||||
- **解决方案**:
|
||||
- 修复: 在 `reflect()` 调用前查询 VikingStorage 获取当前 agent 的记忆列表
|
||||
- 示例: `let memories = fetch_agent_memories(agent_id).await; engine.reflect(agent_id, &memories);`
|
||||
|
||||
### 3.2 HIGH 严重度(8 项)
|
||||
|
||||
#### H1: SpeechHand 完全模拟 ✅ **已标记 demo**
|
||||
- **文件**: `crates/zclaw-hands/src/hands/speech.rs:236`
|
||||
- **证据**: `"In real implementation, would call TTS API"` — 返回 `duration_ms: text.len() * 80` 的伪数据
|
||||
- **差距模式**: 写了没接 — 代码结构完整但无真实 API 调用
|
||||
- **影响**: 用户触发 SpeechHand 期望得到语音输出,实际只返回 JSON 状态
|
||||
- **解决方案**:
|
||||
- 短期: UI 标记为"演示模式"
|
||||
- 中期: 集成浏览器 Web Speech API(通过 Tauri webview.eval)
|
||||
- 长期: 实现 Azure/OpenAI/ElevenLabs TTS API
|
||||
|
||||
#### H2: TwitterHand 完全模拟 ✅ **已标记 demo**
|
||||
- **文件**: `crates/zclaw-hands/src/hands/twitter.rs:297-509`
|
||||
- **证据**: 所有 10+ 个操作返回 `"(simulated)"` JSON,搜索返回空数组
|
||||
- **差距模式**: 写了没接 — 类型定义完整但无 HTTP 请求
|
||||
- **影响**: 即使配置了 API Key 也不会生效,返回假数据
|
||||
- **解决方案**:
|
||||
- 短期: UI 明确标注"模拟模式",禁用写操作
|
||||
- 中期: 实现 Twitter API v2 或改为 Mastodon API
|
||||
|
||||
#### H3: 记忆系统双存储路径不同步 ✅ **已修复**
|
||||
- **修复方案**: 完全重写 `memory_commands.rs`,所有操作统一委派到 VikingStorage (SqliteStorage)。移除了 PersistentMemoryStore 的双写逻辑。保留 PersistentMemory 类型作为前端 API 兼容层,内部通过 `to_persistent()` 转换。
|
||||
- **修复文件**: `memory_commands.rs`, `viking_commands.rs`, `memory/mod.rs`
|
||||
- **路径A**: `memory_commands.rs` → `PersistentMemoryStore` → `{app_data_dir}/memory/memories.db`(UI 面板使用)
|
||||
- **路径B**: `intelligence_hooks.rs` → `VikingStorage` → `{data_dir}/zclaw/memories/memories.db`(聊天流程使用)
|
||||
- **证据**: 两个路径使用**不同的数据库文件**。`memory_store()` 第88-94行虽有双写逻辑,但 `memory_search()` 优先用 VikingStorage,`intelligence_hooks` 也只用 VikingStorage。`memory_db_path()` 返回的是 PersistentMemoryStore 的路径。
|
||||
- **差距模式**: 双系统不同步
|
||||
- **影响**: UI 面板存储的记忆可能无法在聊天时被检索到
|
||||
- **解决方案**: 统一到 `zclaw-growth` 的 SqliteStorage(已有 FTS5 + TF-IDF + 可选 embedding)
|
||||
|
||||
#### H4: 心跳引擎无持久化(已在启动时运行) ✅ **已修复**
|
||||
- **修复方案**: `record_interaction()` 现在通过 `tokio::spawn` 将交互时间戳持久化到 VikingStorage metadata(key: `heartbeat:last_interaction:{agent_id}`)。`heartbeat_init()` 在初始化时调用 `restore_last_interaction()` 从 VikingStorage 恢复上次交互时间,确保 `idle-greeting` 检查在应用重启后仍能正确工作。
|
||||
- **修复文件**: `heartbeat.rs`
|
||||
- **文件**: `desktop/src-tauri/src/intelligence/heartbeat.rs`
|
||||
- **证据**:
|
||||
- `HeartbeatConfig::default()` 中 `enabled: false`(第103行),但 `App.tsx:181` 主动调用 `heartbeat.start()`
|
||||
- `start()` **确实启动了后台 tokio 任务**,每 30 分钟执行一次 tick(第138-180行)
|
||||
- `record_interaction()` 只写入全局静态 HashMap(第378-382行),不持久化到磁盘
|
||||
- `history` 存储在内存 `Arc<Mutex<Vec<HeartbeatResult>>>`,重启丢失
|
||||
- `MEMORY_STATS_CACHE` 需要前端调用 `heartbeat_update_memory_stats` 才能填充,否则 `check_pending_tasks` 和 `check_memory_health` 发出"记忆统计未同步"警告
|
||||
- **差距模式**: 传了没存
|
||||
- **影响**: 心跳引擎已运行但所有状态重启后丢失;记忆统计检查需要前端主动同步
|
||||
- **解决方案**:
|
||||
- 使用 SQLite 持久化交互记录和心跳历史
|
||||
- 自动同步记忆统计,不依赖前端手动调用
|
||||
|
||||
#### H5: VERIFICATION_REPORT 包含已删除功能 ✅ **已归档**
|
||||
- **文件**: `docs/features/VERIFICATION_REPORT.md`
|
||||
- **证据**: 报告验证了 "Multi-Agent Collaboration" 和 "Team/Swarm" 功能,但 commit `c399657` 已删除这些功能
|
||||
- **差距模式**: 存了没用 — 过时文档误导开发者
|
||||
- **影响**: 审计结论不可信,98.5% 通过率严重虚高
|
||||
- **解决方案**: 立即更新或归档此报告,以本审计报告替代
|
||||
|
||||
#### H6: Presentation 层部分渲染器缺失 ✅ **已修复**
|
||||
- **修复方案**:
|
||||
- Chart: 新增 `ChartRenderer.tsx`,使用 recharts 实现 line/bar/pie/scatter/area 五种图表
|
||||
- Document: 替换手写 markdown 解析器为 react-markdown + remark-gfm(支持 tables、links、images、inline code)
|
||||
- Slideshow: 实现完整 slide type 渲染(title/content/image/code/twoColumn),集成 react-markdown
|
||||
- Whiteboard: 保留占位但添加 "即将推出" 标签
|
||||
- **修复文件**: `ChartRenderer.tsx`(新)、`DocumentRenderer.tsx`、`SlideshowRenderer.tsx`、`PresentationContainer.tsx`
|
||||
- **文件**: `desktop/src/components/presentation/`
|
||||
- **证据**:
|
||||
- Chart 渲染器**完全缺失** — PresentationAnalyzer 可检测 Chart 类型,但无对应 UI 渲染器,选择 "chart" 会显示默认占位
|
||||
- Whiteboard 渲染器是**占位文本** — `PresentationContainer.tsx:113-116` 显示 "白板渲染器开发中..."
|
||||
- Slideshow 渲染器**导航可用但内容渲染是 stub** — 复杂内容显示 "Complex content rendering" 占位,无实际 markdown/代码/图片渲染
|
||||
- Document 渲染器**手写 markdown 解析器** — 不支持 inline code、links、images、tables、nested lists
|
||||
- **差距模式**: 写了没接 — 分析器能识别类型但渲染器未实现
|
||||
- **解决方案**:
|
||||
- 短期: Chart 用 recharts 库实现,Whiteboard 保持占位但移除 "可用" 标签
|
||||
- 中期: Slideshow 集成 markdown 渲染库(react-markdown),Document 替换手写解析器
|
||||
|
||||
#### H7: Agent Store 接口不匹配 — Tauri 模式下 Agent CRUD 静默失败 ✅ **已修复**
|
||||
- **修复方案**: 在 `KernelClient` 上添加 `listClones/createClone/deleteClone/updateClone` 适配方法,内部映射到 `listAgents/createAgent/deleteAgent`。
|
||||
- **修复文件**: `kernel-client.ts`
|
||||
- **文件**: `desktop/src/store/agentStore.ts:137-204`,`desktop/src/lib/kernel-client.ts`
|
||||
- **证据**: `agentStore.ts` 调用 `client.listClones()`、`client.createClone()`、`client.deleteClone()` — 这些方法定义在 `GatewayClient` 接口上,但 `KernelClient` **没有这些方法**。KernelClient 只有 `listAgents()`、`createAgent()`、`deleteAgent()`(使用 `agent_list`/`agent_create`/`agent_delete` 命令)。在 Tauri 内核模式下,Agent 管理操作会静默失败。
|
||||
- **差距模式**: 接了没传 — 前端调用的方法在当前客户端上不存在
|
||||
- **影响**: Tauri 模式下用户无法创建、列出、删除 Agent
|
||||
- **解决方案**: agentStore 适配 KernelClient 接口(调用 `listAgents`/`createAgent`/`deleteAgent`)
|
||||
|
||||
#### H8: Hand 审批流程被绕过 — needs_approval 从未检查 ✅ **已修复**
|
||||
- **修复方案**: `hand_execute` 在执行前查询 `list_hands()` 检查 `needs_approval`,如需审批则创建 pending approval 并返回 `pending_approval` 状态。
|
||||
- **修复文件**: `kernel_commands.rs`
|
||||
- **文件**: `desktop/src-tauri/src/kernel_commands.rs:805-820`
|
||||
- **证据**: `hand_execute()` 直接调用 `kernel.execute_hand(&id, input)`,**完全不检查** `needs_approval` 配置。审批系统(`approval_list`、`approval_respond`、`hand_approve`、`hand_cancel`)的 Tauri 命令都存在,但执行 Hand 时从未触发审批流程。
|
||||
- **差距模式**: 写了没接 — 审批基础设施完整但执行路径不检查
|
||||
- **影响**: 标记为 `needs_approval: true` 的 Hand(如 browser.HAND.toml)可以直接执行,审批流是死代码
|
||||
- **解决方案**: 在 `hand_execute` 中检查 `needs_approval`,如需审批则创建审批请求并返回 pending 状态
|
||||
|
||||
### 3.2 MEDIUM 严重度(7 项)
|
||||
|
||||
#### M1: 3 个幽灵 Tauri 命令调用 ✅ **已修复**
|
||||
- **修复方案**: 在 `kernel_commands.rs` 注册 `hand_get`(查询 hand 详情)、`hand_run_status`(返回 not_found)、`hand_run_list`(返回空列表)三个桩命令,并在 `lib.rs` 的 `generate_handler!` 中注册。
|
||||
- **修复文件**: `kernel_commands.rs`, `lib.rs`
|
||||
- **前端调用** (kernel-client.ts):
|
||||
- `invoke('hand_get')` — 第618行,try/catch 返回 `{}`
|
||||
- `invoke('hand_run_status')` — 第641行,try/catch 返回 `{ status: 'unknown' }`
|
||||
- `invoke('hand_run_list')` — 第680行,try/catch 返回 `{ runs: [] }`
|
||||
- **后端注册**: 仅有 `hand_list`, `hand_execute`, `hand_approve`, `hand_cancel`
|
||||
- **差距模式**: 接了没传 — 静默失败
|
||||
- **解决方案**: 注册显式命令或移除前端调用
|
||||
|
||||
#### M2: plugin:tinker|ping 调用不存在的插件
|
||||
- **文件**: `desktop/src/lib/kernel-client.ts:164`
|
||||
- **证据**: `await invoke('plugin:tinker|ping')` — 项目中无 tinker 插件
|
||||
- **差距模式**: 接了没传
|
||||
- **解决方案**: 移除此调用或实现实际的健康检查
|
||||
|
||||
#### M3: hand_approve 忽略 hand_name 参数
|
||||
- **文件**: `desktop/src-tauri/src/kernel_commands.rs:1109`
|
||||
- **证据**: `fn hand_approve(_hand_name: String, run_id: String, ...)`
|
||||
- **差距模式**: 接了没传 — 参数传递但被忽略
|
||||
- **影响**: 无法按 hand 类型筛选审批
|
||||
- **解决方案**: 实现按 hand_name + run_id 联合查找
|
||||
|
||||
#### M4: 反思引擎结果未反馈到行为 ✅ **已修复(持久化部分)**
|
||||
- **修复方案**: `reflect()` 完成后通过 `tokio::spawn` 将 ReflectionState 和 ReflectionResult 持久化到 VikingStorage metadata。新增 `restore_state()` 方法在初始化时从 VikingStorage 恢复状态,确保 `conversations_since_reflection` 计数器在重启后保持。`intelligence_hooks` 在首次 `post_conversation_hook` 时通过 `pop_restored_state/result` 消费恢复数据。
|
||||
- **修复文件**: `reflection.rs`, `intelligence_hooks.rs`
|
||||
- **文件**: `desktop/src-tauri/src/intelligence/reflection.rs:190-233`
|
||||
- **证据**: `reflect()` 基于规则检测模式(task ≥ 5、preference ≥ 5、lesson ≥ 5),生成改进建议,但结果仅存入内存 `history: Vec<ReflectionResult>`(最多保留 20 条),不持久化且不用于修改后续行为。**更严重的是,由于 C1 bug,这些结果永远是空的。**
|
||||
- **差距模式**: 传了没存 + 存了没用
|
||||
- **影响**: 反思产出(patterns、improvements、identity_proposals)仅记录在日志中,用户看不到,Agent 也不会据此调整行为
|
||||
- **解决方案**: 先修复 C1(传入真实记忆),再将结果持久化到 SQLite,在 RightPanel 中展示,用于身份演化触发
|
||||
|
||||
#### M4b: LLM 压缩器孤立,kernel 只用规则压缩 ✅ **已修复**
|
||||
- **修复方案**: 在 `zclaw-runtime::compaction` 中新增 `CompactionConfig`、`CompactionOutcome` 和异步 `maybe_compact_with_config()` 函数。AgentLoop 根据 config 中的 `use_llm` 标志选择 LLM 摘要或规则摘要路径。LLM 失败时自动回退到规则摘要。
|
||||
- **修复文件**: `compaction.rs`、`loop_runner.rs`、`lib.rs`
|
||||
- **文件**: `desktop/src-tauri/src/intelligence/compactor.rs` vs `crates/zclaw-runtime/src/compaction.rs`
|
||||
- **证据**: Kernel AgentLoop 使用 `zclaw-runtime::compaction`(纯规则,CJK token 估算),Tauri 的 `compactor_compact_llm`(支持 LLM 摘要)虽然注册为命令但**从未被 kernel 调用**。`use_llm` 配置只影响 Tauri 命令,不影响 kernel 循环。
|
||||
- **差距模式**: 写了没接
|
||||
- **影响**: 即使配置 `use_llm: true`,聊天压缩也不会使用 LLM 生成摘要
|
||||
- **解决方案**: 在 kernel 的 AgentLoop 中集成 LLM 压缩路径
|
||||
|
||||
#### M4c: 压缩时记忆刷出是空操作 ✅ **已修复**
|
||||
- **修复方案**:
|
||||
- Runtime 层: `maybe_compact_with_config()` 在压缩前调用 `GrowthIntegration.process_conversation()` 提取记忆
|
||||
- Tauri 层: `compactor_compact` 和 `compactor_compact_llm` 命令在压缩前调用 `flush_old_messages_to_memory()` 将用户消息和助手回复刷出到 VikingStorage
|
||||
- **修复文件**: `compaction.rs`(runtime)、`compactor.rs`(tauri)
|
||||
- **文件**: `crates/zclaw-runtime/src/compaction.rs`, `desktop/src-tauri/src/intelligence/compactor.rs`
|
||||
- **证据**: 两个压缩器都设置 `flushed_memories: 0`,`memory_flush_enabled` 配置存在但**无实现**
|
||||
- **差距模式**: 写了没接
|
||||
- **影响**: 长对话压缩时不会自动提取和保存关键记忆
|
||||
- **解决方案**: 实现压缩时的记忆提取逻辑
|
||||
|
||||
#### M5: 自主授权未集成到执行链路
|
||||
- **文件**: `desktop/src/lib/autonomy-manager.ts`, `desktop/src/components/AutonomyConfig.tsx`
|
||||
- **证据**: 组件存在且渲染在 RightPanel,但 `canAutoExecute()` 未在 `kernel_commands.rs` 的 hand_execute 或 skill_execute 中被调用
|
||||
- **差距模式**: 写了没接
|
||||
- **影响**: 用户配置的自主级别不影响实际执行
|
||||
- **解决方案**: 在 Tauri 命令层集成自主授权检查
|
||||
|
||||
#### M6: Pipeline 语义路由是桩代码
|
||||
- **文件**: `crates/zclaw-pipeline/src/intent.rs:454-457`
|
||||
- **证据**: 构建了 LLM prompt 但 `let _ = prompt; // Suppress unused warning` 然后 `return None`
|
||||
- **差距模式**: 写了没接
|
||||
- **影响**: Pipeline 只能用关键词匹配触发
|
||||
- **解决方案**: 接入 LLM driver 实现真正的语义匹配
|
||||
|
||||
#### M7: Pipeline 无 YAML 模板文件
|
||||
- **证据**: `find config/ skills/ hands/` 未找到任何 `.yaml`/`.yml` 文件
|
||||
- **差距模式**: 存了没用 — 文档声称 5 个模板但文件不存在
|
||||
- **影响**: 用户无法使用预设的 Pipeline 模板
|
||||
- **解决方案**: 创建实际可用的 YAML 模板文件
|
||||
|
||||
### 3.3 LOW 严重度(6 项)
|
||||
|
||||
#### L1: Pipeline 并行执行实际串行
|
||||
- **文件**: `crates/zclaw-pipeline/src/engine/stage.rs:321-322`
|
||||
- **证据**: `execute_parallel` 使用 for 循环,注释 "True parallel execution would require Send-safe drivers"
|
||||
- **差距模式**: 写了没接
|
||||
|
||||
#### L2: gatewayStore.ts 废弃但仍被引用
|
||||
- **文件**: `desktop/src/store/gatewayStore.ts`(@deprecated),`HandApprovalModal.tsx:25` 仍导入
|
||||
- **差距模式**: 写了没接
|
||||
|
||||
#### L3: Wasm/Native 技能模式未实现
|
||||
- **文件**: `crates/zclaw-skills/src/skill.rs`
|
||||
- **证据**: SkillMode::Wasm 和 SkillMode::Native 注释为 "not yet implemented, falls back to PromptOnly"
|
||||
- **差距模式**: 写了没接
|
||||
|
||||
#### L4: 28 个 `#[allow(dead_code)]` 标注
|
||||
- **分布**:
|
||||
- LLM driver 反序列化字段(anthropic.rs、openai.rs、local.rs、gemini.rs)— 合理
|
||||
- intelligence 模块预留方法(identity export/import、heartbeat is_running/subscribe、compactor get_config/update_config、reflection get_last_result)— 预留
|
||||
- export 预留(html template、markdown without_front_matter)— 预留
|
||||
- `lib.rs` build_staged_runtime_legacy、HealthStatus — 遗留代码
|
||||
- `intent.rs` DefaultLlmIntentDriver — 桩代码
|
||||
- `persistent.rs` tags 字段 — 预留
|
||||
- `browser/session.rs` session_count — 预留
|
||||
- **建议**: 遗留代码(lib.rs legacy)可删除,其余保留
|
||||
|
||||
#### L5: 5 个 TODO 注释
|
||||
- `registry.rs:56` — message_count tracking
|
||||
- `orchestration.rs:41` — graph storage
|
||||
- `pipeline_commands.rs:442` — use actual time
|
||||
- `pipeline_commands.rs:781` — pattern support
|
||||
- `html.rs:17` — template-based export
|
||||
- **建议**: 均为功能增强,非阻塞
|
||||
|
||||
#### L6: zclaw-channels 仅有测试适配器
|
||||
- **文件**: `crates/zclaw-channels/src/adapters/console.rs`
|
||||
- **证据**: 仅有 ConsoleChannel,无 Discord/Slack/飞书等真实适配器
|
||||
- **影响**: 低 — 桌面端不依赖外部通道
|
||||
- **建议**: 维持现状或移除 crate
|
||||
|
||||
---
|
||||
|
||||
## 四、调用链验证报告
|
||||
|
||||
### 4.1 聊天消息流 ✅ 已验证
|
||||
```
|
||||
ChatArea.tsx → chatStore.sendStreamMessage()
|
||||
→ kernel-client.ts sendStreamMessage() → invoke('agent_chat_stream')
|
||||
→ kernel_commands.rs agent_chat_stream()
|
||||
→ intelligence_hooks.rs pre_conversation_hook()
|
||||
→ build_memory_context() → VikingStorage.find() ✅
|
||||
→ build_identity_prompt() → IdentityManager.build_system_prompt() ✅
|
||||
→ kernel.agent_chat_stream()
|
||||
→ loop_runner.rs AgentLoop(compaction threshold 15k)✅
|
||||
→ LLM driver(4个实现:Anthropic/OpenAI/Gemini/Local)✅
|
||||
→ intelligence_hooks.rs post_conversation_hook()
|
||||
→ heartbeat.record_interaction() ✅(仅内存)
|
||||
→ reflection.record_conversation() + should_reflect() ✅ 已修复 (C2: 传入真实记忆)
|
||||
→ Tauri events 发射 ✅
|
||||
→ kernel-client.ts 事件监听 ✅
|
||||
→ ChatArea.tsx 渲染 ✅
|
||||
```
|
||||
|
||||
### 4.2 Hand 执行流 ⚠️ 部分验证
|
||||
```
|
||||
HandList.tsx → handStore.triggerHand()
|
||||
→ kernel-client.ts triggerHand() → invoke('hand_execute')
|
||||
→ kernel_commands.rs hand_execute() → kernel.hand_execute()
|
||||
→ HandRegistry.get() → Hand.execute()
|
||||
→ [真实] QuizHand: LLM 生成题目 ✅
|
||||
→ [真实] ResearcherHand: DuckDuckGo 搜索 ✅
|
||||
→ [真实] CollectorHand: HTML 抓取 ✅
|
||||
→ [真实] ClipHand: FFmpeg 调用 ✅
|
||||
→ [真实] SlideshowHand: 状态管理 ✅
|
||||
→ [真实] WhiteboardHand: 状态管理 ✅
|
||||
→ [模拟] SpeechHand: 返回伪 JSON ❌
|
||||
→ [模拟] TwitterHand: 返回 "(simulated)" ❌
|
||||
→ [委托] BrowserHand: 委托给 Tauri browser commands ✅
|
||||
→ 审批检查(如 needs_approval)✅ 已修复 (H8)
|
||||
→ 结果返回
|
||||
→ handStore 处理结果
|
||||
→ UI 显示结果
|
||||
```
|
||||
|
||||
### 4.3 记忆存储流 ⚠️ 双路径
|
||||
```
|
||||
路径A (UI面板):
|
||||
MemoryPanel.tsx → intelligence-backend.ts memory_store()
|
||||
→ invoke('memory_store') → memory_commands.rs
|
||||
→ PersistentMemoryStore.store() → {app_data}/memory/memories.db
|
||||
→ VikingStorage.add() → {data_dir}/zclaw/memories/memories.db (双写)
|
||||
|
||||
路径B (聊天流程):
|
||||
intelligence_hooks.rs build_memory_context()
|
||||
→ VikingStorage.find() → {data_dir}/zclaw/memories/memories.db
|
||||
```
|
||||
|
||||
### 4.4 技能执行流 ⚠️ PromptOnly 不产生 AI 输出
|
||||
```
|
||||
SkillMarket.tsx → kernel-client.ts executeSkill()
|
||||
→ invoke('skill_execute') → kernel_commands.rs skill_execute()
|
||||
→ kernel.execute_skill() → SkillRegistry → SkillExecutor
|
||||
→ PromptOnlySkill: 通过 LlmCompleter 调用 LLM 生成内容 ✅ 已修复 (C1)
|
||||
→ PythonSkill: subprocess 执行 ✅(但无技能使用此模式)
|
||||
→ ShellSkill: subprocess 执行 ✅(仅 shell-command 使用此模式)
|
||||
→ WasmSkill → 回退到 PromptOnly ❌
|
||||
→ NativeSkill → 回退到 PromptOnly ❌
|
||||
|
||||
注意: 技能在 kernel 的 build_skill_aware_system_prompt() 中作为上下文注入是有效的,
|
||||
但通过 skill_execute 命令直接执行时,PromptOnly 不产生 AI 生成内容。
|
||||
```
|
||||
|
||||
### 4.5 Pipeline 执行流 ⚠️ 部分验证
|
||||
```
|
||||
PipelinesPanel.tsx → workflowStore.runPipeline()
|
||||
→ invoke('pipeline_run') → pipeline_commands.rs pipeline_run()
|
||||
→ StageEngine.execute()
|
||||
→ Llm stage: 调用 LLM ✅
|
||||
→ Parallel stage: 实际串行 ❌
|
||||
→ Sequential stage: 顺序链 ✅
|
||||
→ Conditional stage: 条件评估 ✅
|
||||
→ Skill stage: 调用技能系统 ✅
|
||||
→ Hand stage: 调用 Hand 系统 ✅
|
||||
→ Http stage: HTTP 请求 ✅
|
||||
→ SetVar stage: 设置变量 ✅
|
||||
→ Compose stage: 模板组合 ✅
|
||||
→ Progress 事件
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 五、Dead Code 分类清单
|
||||
|
||||
### 5.1 真正的死代码(建议删除)
|
||||
| 位置 | 类型 | 建议 |
|
||||
|------|------|------|
|
||||
| `lib.rs` build_staged_runtime_legacy | 遗留函数 | 删除 |
|
||||
| `lib.rs` HealthStatus enum | 预留枚举 | 删除或实现 |
|
||||
|
||||
### 5.2 预留功能(暂时保留)
|
||||
| 位置 | 类型 | 建议 |
|
||||
|------|------|------|
|
||||
| `identity.rs` export_all/import/get_all_proposals | 预留方法 | 保留,添加 Tauri 命令 |
|
||||
| `heartbeat.rs` is_running/subscribe | 预留方法 | 保留 |
|
||||
| `compactor.rs` get_config/update_config | 预留方法 | 保留 |
|
||||
| `reflection.rs` get_last_result | 预留方法 | 保留 |
|
||||
| `persistent.rs` tags 字段 | 预留字段 | 保留 |
|
||||
| `browser/session.rs` session_count | 预留方法 | 保留 |
|
||||
| `html.rs` template/with_template | 预留功能 | 保留 |
|
||||
| `markdown.rs` without_front_matter | 预留功能 | 保留 |
|
||||
| `stage.rs` clone_with_drivers | 预留功能 | 保留 |
|
||||
| `a2a.rs` new() | 预留构造器 | 保留 |
|
||||
| `sqlite.rs` path 字段 | 预留字段 | 保留 |
|
||||
| `cache.rs` CacheKey struct | 预留类型 | 保留 |
|
||||
|
||||
### 5.3 桩代码(需要实现或明确标注)
|
||||
| 位置 | 类型 | 建议 |
|
||||
|------|------|------|
|
||||
| `intent.rs` DefaultLlmIntentDriver.semantic_match | 桩代码 | 接入 LLM driver |
|
||||
| `speech.rs` execute_action (Speak) | 模拟实现 | 集成真实 TTS |
|
||||
| `twitter.rs` 所有 execute_* 方法 | 模拟实现 | 集成真实 API 或标记为演示 |
|
||||
|
||||
---
|
||||
|
||||
## 六、跨部门专家头脑风暴
|
||||
|
||||
### 议题 1: SpeechHand/TwitterHand 是否应该保留在发布版中?
|
||||
|
||||
**产品视角**:
|
||||
- 用户看到"可用"标签会期望真实功能,模拟实现会损害信任
|
||||
- 建议: 短期在 UI 中标记为"演示/Preview"状态,长期要么实现要么移除
|
||||
|
||||
**工程视角**:
|
||||
- 模拟实现有其价值:验证了类型系统、配置传递、审批流程的正确性
|
||||
- 可以作为真实实现的骨架,替换核心逻辑即可
|
||||
- 建议: 保留代码但移除"可用"标签
|
||||
|
||||
**安全视角**:
|
||||
- TwitterHand 的模拟实现不会造成安全问题(无网络请求)
|
||||
- 但 UI 不应让用户误以为操作已生效
|
||||
- 建议: 写操作的 UI 按钮必须添加明确提示
|
||||
|
||||
**结论**: 保留代码,UI 标记为"演示模式",写操作添加确认提示
|
||||
|
||||
### 议题 2: 双存储路径如何统一?
|
||||
|
||||
**架构视角**:
|
||||
- PersistentMemoryStore(sqlx 直连)和 VikingStorage/zclaw-growth(trait 抽象)本质上是同一个功能的两套实现
|
||||
- zclaw-growth 的 SqliteStorage 有 FTS5 + TF-IDF + embedding 支持,能力更强
|
||||
- 统一到 zclaw-growth 是正确的方向
|
||||
|
||||
**数据迁移视角**:
|
||||
- 需要将 PersistentMemoryStore 中已有的数据迁移到 VikingStorage
|
||||
- `memory_store()` 已有双写逻辑,只需确保搜索也统一使用 VikingStorage
|
||||
|
||||
**结论**: 统一到 VikingStorage,删除 PersistentMemoryStore,确保所有搜索路径走同一数据库
|
||||
|
||||
### 议题 3: 反思引擎的产出是否有价值?
|
||||
|
||||
**AI 研究视角**:
|
||||
- 当前的 `analyze_patterns()` 基于简单阈值(task ≥ 5),检测粒度粗
|
||||
- 没有使用 LLM 进行深度分析,无法发现复杂的行为模式
|
||||
- 但作为 L0 级别的规则检测,它提供了基础的价值
|
||||
|
||||
**产品视角**:
|
||||
- 反思结果目前只存在内存中,用户看不到
|
||||
- 如果不展示给用户、不影响 Agent 行为,等于不存在
|
||||
- 建议: 至少在 RightPanel 中展示反思日志
|
||||
|
||||
**结论**: 保留规则检测作为基础,将结果持久化并在 UI 中展示,中期升级为 LLM 驱动
|
||||
|
||||
### 议题 4: 心跳引擎是否值得维护?
|
||||
|
||||
**运维视角**:
|
||||
- 默认禁用意味着这个功能从未被用户使用过
|
||||
- 如果没有用户需求,维护它只是增加代码复杂度
|
||||
- 但作为 Agent 主动性的基础,长期有战略价值
|
||||
|
||||
**工程视角**:
|
||||
- `record_interaction()` 仅写入内存 HashMap,重启丢失
|
||||
- `tick()` 没有定时器自动执行,需要手动触发
|
||||
- 建议: 要么完整实现(持久化 + 定时器 + 通知),要么降级为按需触发
|
||||
|
||||
**结论**: 将 enabled 默认改为 true,实现 SQLite 持久化,保留定时器但简化检查项
|
||||
|
||||
---
|
||||
|
||||
## 七、修复优先级矩阵
|
||||
|
||||
| 优先级 | ID | 问题 | 工作量 | 建议时间线 | 状态 |
|
||||
|--------|-----|------|--------|-----------|------|
|
||||
| **P0** | C1 | PromptOnly 技能不调用 LLM — 集成 LLM driver | 1-2d | **立即** | ✅ 已修复 |
|
||||
| **P0** | C2 | 反思引擎传入空记忆 — 修复 reflect() 调用 | 1h | **立即** | ✅ 已修复 |
|
||||
| **P0** | H5 | 更新/归档过时的 VERIFICATION_REPORT | 1h | **立即** | ✅ 已归档 |
|
||||
| **P1** | H7 | Agent Store 适配 KernelClient 接口 | 1d | 本周 | ✅ 已修复 |
|
||||
| **P1** | H8 | Hand 执行前检查 needs_approval | 4h | 本周 | ✅ 已修复 |
|
||||
| **P1** | M1 | 注册 3 个幽灵命令或移除调用 | 2h | 本周 | ✅ 已修复 |
|
||||
| **P1** | H1 | SpeechHand 标记为演示模式 | 2h | 本周 | ✅ 已标记 |
|
||||
| **P1** | H2 | TwitterHand 标记为演示模式 | 2h | 本周 | ✅ 已标记 |
|
||||
| **P1** | H3 | 统一记忆双存储路径 | 2-3d | 本周 | ✅ 已修复 |
|
||||
| **P1** | H4 | 心跳引擎持久化 + 自动同步记忆统计 | 1-2d | 本周 | ✅ 已修复 |
|
||||
| **P1** | P7 | Presentation 层缺失 Chart/Whiteboard 渲染器 | 2-3d | 本周 | ✅ 已修复 |
|
||||
| **P2** | M4b | LLM 压缩器集成到 kernel AgentLoop | 1-2d | 下周 | ✅ 已修复 |
|
||||
| **P2** | M4c | 实现压缩时的记忆刷出 | 1d | 下周 | ✅ 已修复 |
|
||||
| **P2** | M4 | 反思结果持久化 + UI 展示 | 2d | 下周 | ✅ 已修复 |
|
||||
| **P2** | M5 | 自主授权集成到执行链路 | 1-2d | 下周 | ✅ 已修复 |
|
||||
| **P2** | M3 | hand_approve 使用 hand_name 参数 | 1h | 下周 | ✅ 已修复 |
|
||||
| **P2** | L2 | 清理 gatewayStore 废弃引用 | 1h | 下周 | ✅ 已确认(仅注释) |
|
||||
| **P2** | S9 | 消息搜索仅当前会话 — 新增 Global 模式 | 1d | 下周 | ✅ 已修复 |
|
||||
| **P3** | M6 | 实现语义路由 | 2-3d | 下个迭代 |
|
||||
| **P3** | L1 | Pipeline 并行执行 | 2d | 下个迭代 |
|
||||
| **P3** | L3 | Wasm/Native 技能模式 | 3-5d | 长期 |
|
||||
| **P3** | L4 | 清理死代码标注 | 4h | 长期 |
|
||||
| **P3** | L5 | 处理 TODO 注释 | 1d | 长期 |
|
||||
| **P3** | L6 | zclaw-channels 决策 | 评估后决定 | 长期 |
|
||||
|
||||
---
|
||||
|
||||
## 八、审计命令速查(已验证)
|
||||
|
||||
```bash
|
||||
# Dead code 扫描(已验证 28 处)
|
||||
rg '#\[allow\(dead_code\)\]' crates/ desktop/src-tauri/ -B 1 -A 3 --type rust
|
||||
|
||||
# TODO 扫描(已验证 5 处)
|
||||
rg 'TODO|FIXME' crates/ desktop/src-tauri/ --type rust -n
|
||||
|
||||
# 模拟代码扫描(已确认 speech.rs + twitter.rs)
|
||||
rg 'simulated|In real implementation' crates/ desktop/src-tauri/ --type rust -n -i
|
||||
|
||||
# Tauri 命令交叉验证(已确认 3 个幽灵调用)
|
||||
rg 'kernel_commands::|pipeline_commands::|viking_commands::|memory_commands::|intelligence::|browser::commands::|secure_storage::|memory::|llm::' desktop/src-tauri/src/lib.rs -o | sort -u
|
||||
rg "invoke\(['\"]" desktop/src/ --type ts -o | sort -u
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 九、结论
|
||||
|
||||
ZCLAW 的核心架构(通信、状态管理、安全认证、聊天、Agent 管理)是**坚实可靠的**。Rust 核心代码质量高,测试覆盖好,无 `todo!()` 或 `unimplemented!()` 宏。
|
||||
|
||||
主要问题集中在:
|
||||
1. ~~**技能系统 PromptOnly 不调用 LLM**~~ ✅ 已修复 — 通过 LlmCompleter 桥接调用 LLM
|
||||
2. ~~**反思引擎是空操作**~~ ✅ 已修复 — 传入真实记忆,结果持久化到 VikingStorage
|
||||
3. ~~**Agent Store 接口不匹配**~~ ✅ 已修复 — KernelClient 添加适配方法
|
||||
4. ~~**Hand 审批流程被绕过**~~ ✅ 已修复 — 执行前检查 needs_approval
|
||||
5. ~~**2 个 Hand 是模拟实现**~~ ✅ 已标记 demo 标签
|
||||
6. ~~**记忆系统双存储路径**~~ ✅ 已统一 — VikingStorage 元数据持久化
|
||||
7. ~~**心跳引擎**无持久化~~ ✅ 已修复 — 交互时间戳 + 历史数组持久化
|
||||
8. ~~**LLM 压缩器孤立**~~ ✅ 已修复 — runtime compaction 支持 LLM 摘要 + 记忆刷出
|
||||
9. ~~**Presentation 层**渲染器缺失~~ ✅ 已修复 — Chart(recharts)、Document(react-markdown)、Slideshow 完整渲染
|
||||
10. ~~**3 份审计报告**过时~~ ✅ 已归档
|
||||
11. ~~**自主授权后端无守卫**~~ ✅ 已修复 — hand_execute/skill_execute 接收 autonomy_level 参数
|
||||
12. ~~**hand_approve 忽略参数**~~ ✅ 已修复 — 使用 hand_name 审计日志
|
||||
13. ~~**反思历史只存单条**~~ ✅ 已修复 — 累积存储到 reflection:history 数组
|
||||
14. ~~**身份回滚 UI 缺失**~~ ✅ 已实现 — IdentityChangeProposal.tsx HistoryItem
|
||||
15. **28 处 dead_code 标注**中大部分是合理的预留功能,少数是遗留代码
|
||||
16. ~~**剩余 P2/P3 项**: 反思 LLM 分析、语义路由、Pipeline 并行等~~ ✅ 已修复 — 见下方 18-20
|
||||
17. ~~**消息搜索仅当前会话**~~ ✅ 已修复 — MessageSearch 新增 Global 模式,调用 VikingStorage memory_search 跨会话搜索记忆
|
||||
18. ~~**反思引擎规则升级为 LLM**~~ ✅ 已修复 — `analyze_patterns_with_llm()` 调用 LLM 做深度行为分析,失败回退规则
|
||||
19. ~~**语义路由是桩代码**~~ ✅ 已修复 — `RuntimeLlmIntentDriver` 包装 LlmDriver 实现真实语义匹配
|
||||
20. ~~**Pipeline 并行执行实际串行**~~ ✅ 已修复 — `execute_parallel()` 改用 `buffer_unordered(max_workers)` 真正并行
|
||||
|
||||
**累计修复 27 项** (P0×3 + P1×8 + P2×7 + P3×4 + 误判×2 + 审计×3),系统真实可用率从 ~50% 提升到 ~85%。
|
||||
|
||||
---
|
||||
|
||||
## 九、v5 审计追加修复(2026-03-27)
|
||||
|
||||
v5 审计独立验证了上述 27 项修复,确认 25 项完全到位、2 项部分到位,并新发现 8 项问题。以下为追加修复:
|
||||
|
||||
| # | 问题 | 修复方案 | 状态 |
|
||||
|---|------|---------|------|
|
||||
| 28 | WhiteboardHand Export 返回伪造 data_url | HAND.toml 添加 `demo = true` + 描述标注 | ✅ 已修复 |
|
||||
| 29 | Director(907行) + A2A(690行) 孤立 | `#[cfg(feature = "multi-agent")]` 条件编译 + Cargo.toml feature 定义 | ✅ 已修复 |
|
||||
| 30 | compactor_compact_llm 冗余 Tauri 命令 | 从 `generate_handler!` 移除注册 | ✅ 已修复 |
|
||||
| 31 | hand_approve hand_name 仅用于日志 | 添加 hand_id 匹配验证 + hand_cancel 同步修复 | ✅ 已修复 |
|
||||
| 32 | scheduled_task 调度循环未实现 | 更新文档注释标注 PLANNNED | ✅ 已修复 |
|
||||
|
||||
**v5 审计后累计修复 32 项**,系统真实可用率 ~85%。孤立代码通过条件编译控制,不影响默认编译。
|
||||
500
docs/archive/old-audits/FEATURE_AUDIT_REPORT.md
Normal file
@@ -0,0 +1,500 @@
|
||||
# ZCLAW 功能完整性审计报告
|
||||
|
||||
> **ARCHIVED — 此报告已过时**
|
||||
>
|
||||
> 本报告审计于 2026-03-27,仅反映当时的代码状态。
|
||||
> 截至 2026-03-28,SaaS 平台 (76+ API)、Admin 管理后台等大量功能已上线。
|
||||
>
|
||||
> **请参考最新文档** → [README.md](./README.md) | [DEEP_AUDIT_REPORT.md](./DEEP_AUDIT_REPORT.md)
|
||||
>
|
||||
> **原始审计信息:**
|
||||
> **审计日期**: 2026-03-27
|
||||
> **审计方法**: 五步审计流程 + 10 项通用审计清单
|
||||
> **审计范围**: docs/features 目录下所有功能文档 vs 实际代码实现
|
||||
|
||||
---
|
||||
|
||||
## 一、审计摘要
|
||||
|
||||
### 1.1 总体完成度
|
||||
|
||||
| 分类 | 功能数 | 完整实现 | 部分实现 | 未实现 | 完成率 |
|
||||
|------|--------|---------|---------|--------|------|
|
||||
| 核心功能 | 3 | 3 | 0 | 0 | **100%** |
|
||||
| 智能层 | 6 | 5 | 1 | 0 | **83%** |
|
||||
| Skills 生态 | 2 | 1 | 1 | 0 | **50%** |
|
||||
| Pipeline DSL | 1 | 1 | 0 | 0 | **100%** |
|
||||
| 架构层 | 2 | 2 | 0 | 0 | **100%** |
|
||||
| 上下文数据库 | 1 | 1 | 0 | 0 | **85%** |
|
||||
| Hands 系统 | 11 | 9 | 0 | 2 | **82%** |
|
||||
| **总计** | **26** | **22** | **2** | **2** | **85%** |
|
||||
|
||||
### 1.2 关键发现
|
||||
|
||||
1. **整体架构健康**: 核心功能完成度高,智能层已完全接入聊天流程
|
||||
2. **主要差距**: 智能路由系统实现不完整,部分 Hands 未实现
|
||||
3. **技术债务**: 39 处 `dead_code` 标记,需要评估是否启用或删除
|
||||
|
||||
---
|
||||
|
||||
## 二、功能详细审计
|
||||
|
||||
### 2.1 核心功能 (Core Features)
|
||||
|
||||
#### 聊天界面 (Chat Interface)
|
||||
| 审计项 | 状态 | 说明 |
|
||||
|--------|------|------|
|
||||
| 代码存在性 | ✅ | ChatArea.tsx, chatStore.ts |
|
||||
| 实现完整性 | ✅ | 流式响应、Markdown 渲染、多模型支持 |
|
||||
| 调用链连通 | ✅ | UI → chatStore → KernelClient → Tauri 命令 |
|
||||
| 配置传递 | ✅ | 模型配置通过 UI 设置页面完成 |
|
||||
| 启动恢复 | ✅ | 从 localStorage 恢复配置 |
|
||||
| 降级策略 | ✅ | 离线模式支持 |
|
||||
| 数据流闭环 | ✅ | 消息发送 → 流式响应 → 记忆提取 |
|
||||
| dead_code 清理 | ✅ | 无死代码 |
|
||||
| 测试覆盖 | ✅ | 30+ 单元测试 |
|
||||
|
||||
**完成度**: **95%+** ✅ 生产就绪
|
||||
|
||||
---
|
||||
|
||||
#### Agent 分身 (Agent Clones)
|
||||
| 审计项 | 状态 | 说明 |
|
||||
|--------|------|------|
|
||||
| 代码存在性 | ✅ | agentStore.ts, CloneManager.tsx |
|
||||
| 实现完整性 | ✅ | CRUD 完整,SQLite 持久化 |
|
||||
| 调用链连通 | ✅ | UI → agentStore → Tauri 命令 → zclaw-memory |
|
||||
| 配置传递 | ✅ | Agent 配置正确存储和恢复 |
|
||||
| 启动恢复 | ✅ | 从 SQLite 恢复 Agent 列表 |
|
||||
| 降级策略 | ✅ | 默认 Agent 兜底 |
|
||||
| 数据流闭环 | ✅ | 创建 → 存储 → 列表 → 切换 |
|
||||
| dead_code 清理 | ✅ | 无死代码 |
|
||||
| 测试覆盖 | ✅ | 20+ 单元测试 |
|
||||
|
||||
**完成度**: **90%+** ✅ 生产就绪
|
||||
|
||||
---
|
||||
|
||||
#### Hands 系统 (Hands System)
|
||||
| 审计项 | 状态 | 说明 |
|
||||
|--------|------|------|
|
||||
| 代码存在性 | ✅ | handStore.ts, HandList.tsx, 11 个 HAND.toml |
|
||||
| 实现完整性 | ⚠️ | 9/11 Rust 后端实现,Predictor/Lead 未实现 |
|
||||
| 调用链连通 | ✅ | UI → handStore → KernelClient → HandRegistry |
|
||||
| 配置传递 | ✅ | HAND.toml 正确解析 |
|
||||
| 启动恢复 | ✅ | Kernel 启动时加载 Hands |
|
||||
| 降级策略 | ✅ | 未实现的 Hand 显示为不可用 |
|
||||
| 数据流闭环 | ✅ | 触发 → 审批 → 执行 → 结果 |
|
||||
| dead_code 清理 | ⚠️ | browser/actions.rs, browser/error.rs, browser/session.rs 标记 dead_code |
|
||||
| 测试覆盖 | ✅ | 10+ 单元测试 |
|
||||
|
||||
**完成度**: **64%** ⚠️ 需完善
|
||||
|
||||
**差距模式**: "写了没接" - Predictor 和 Lead 仅有配置文件,无 Rust 实现
|
||||
|
||||
---
|
||||
|
||||
### 2.2 智能层 (Intelligence Layer)
|
||||
|
||||
#### Agent 记忆 (Agent Memory)
|
||||
| 审计项 | 状态 | 说明 |
|
||||
|--------|------|------|
|
||||
| 代码存在性 | ✅ | intelligence-client.ts, memory_commands.rs |
|
||||
| 实现完整性 | ✅ | SQLite 存储、TF-IDF、Embedding 搜索、L0/L1/L2 |
|
||||
| 调用链连通 | ✅ | chatStore.sendMessage → memory.buildContext |
|
||||
| 配置传递 | ✅ | Embedding 配置正确传递到后端 |
|
||||
| 启动恢复 | ✅ | App.tsx 恢复 Embedding 配置 |
|
||||
| 降级策略 | ✅ | Embedding 不可用时降级到 TF-IDF |
|
||||
| 数据流闭环 | ✅ | 存储 → 搜索 → 注入 system prompt |
|
||||
| dead_code 清理 | ⚠️ | context_builder.rs, extractor.rs 标记 dead_code |
|
||||
| 双系统一致性 | ⚠️ | SqliteStorage vs PersistentMemoryStore 功能不对等 |
|
||||
| 测试覆盖 | ✅ | 42 单元测试 |
|
||||
|
||||
**完成度**: **95%+** ✅ 生产就绪
|
||||
|
||||
**差距模式**: "双系统不同步" - 两套存储系统功能不对等
|
||||
|
||||
---
|
||||
|
||||
#### 身份演化 (Identity Evolution)
|
||||
| 审计项 | 状态 | 说明 |
|
||||
|--------|------|------|
|
||||
| 代码存在性 | ✅ | intelligence-client.ts, identity.rs |
|
||||
| 实现完整性 | ✅ | SOUL.md 管理、人格预设、变更提案 |
|
||||
| 调用链连通 | ✅ | chatStore.sendMessage → identity.buildPrompt |
|
||||
| 配置传递 | ✅ | 人格预设正确配置 |
|
||||
| 启动恢复 | ✅ | Agent 创建时生成 SOUL.md |
|
||||
| 降级策略 | ✅ | 无 SOUL.md 时使用默认人格 |
|
||||
| 数据流闭环 | ✅ | 创建 → 存储 → 构建 prompt → 注入对话 |
|
||||
| dead_code 清理 | ⚠️ | identity.rs 部分方法标记 dead_code |
|
||||
| 测试覆盖 | ✅ | 包含在 intelligence-client.test.ts |
|
||||
|
||||
**完成度**: **85%+** ✅ 生产就绪
|
||||
|
||||
**差距模式**: "写了没接" - persona_evolver.rs, mesh.rs, pattern_detector.rs, trigger_evaluator.rs 标记 dead_code
|
||||
|
||||
---
|
||||
|
||||
#### 自我反思引擎 (Reflection Engine)
|
||||
| 审计项 | 状态 | 说明 |
|
||||
|--------|------|------|
|
||||
| 代码存在性 | ✅ | reflection-engine.ts, reflection.rs |
|
||||
| 实现完整性 | ✅ | 规则模式检测、LLM 深度分析、改进建议生成 |
|
||||
| 调用链连通 | ✅ | chatStore.onComplete → reflection.recordConversation |
|
||||
| 配置传递 | ✅ | 反思配置正确传递 |
|
||||
| 启动恢复 | ✅ | App 启动时初始化 |
|
||||
| 降级策略 | ✅ | LLM 不可用时跳过反思 |
|
||||
| 数据流闭环 | ✅ | 记录对话 → 检查触发 → 执行反思 → 生成建议 |
|
||||
| dead_code 清理 | ⚠️ | reflection.rs 部分方法标记 dead_code |
|
||||
| 测试覆盖 | ✅ | 包含在 reflection.test.ts |
|
||||
|
||||
**完成度**: **80%+** ✅ 生产就绪
|
||||
|
||||
---
|
||||
|
||||
#### 心跳巡检引擎 (Heartbeat Engine)
|
||||
| 审计项 | 状态 | 说明 |
|
||||
|--------|------|------|
|
||||
| 代码存在性 | ✅ | heartbeat.rs, HeartbeatConfig.tsx |
|
||||
| 实现完整性 | ✅ | 定时巡检、任务检查、反思触发 |
|
||||
| 调用链连通 | ✅ | App.tsx → heartbeat.init → heartbeat.start |
|
||||
| 配置传递 | ✅ | 心跳配置正确传递 |
|
||||
| 启动恢复 | ✅ | App 启动时自动初始化 |
|
||||
| 降级策略 | ✅ | 心跳失败时继续运行 |
|
||||
| 数据流闭环 | ✅ | 初始化 → 启动 → 定时 tick → 生成提醒 |
|
||||
| dead_code 清理 | ⚠️ | heartbeat.rs 部分方法保留用于 UI |
|
||||
| 测试覆盖 | ✅ | 包含在 heartbeat.test.ts |
|
||||
|
||||
**完成度**: **90%+** ✅ 生产就绪
|
||||
|
||||
---
|
||||
|
||||
#### 自主授权 (Autonomy Manager)
|
||||
| 审计项 | 状态 | 说明 |
|
||||
|--------|------|------|
|
||||
| 代码存在性 | ✅ | autonomy-manager.ts, AutonomyConfig.tsx |
|
||||
| 实现完整性 | ✅ | 三级自主级别、风险分级、审批流程 |
|
||||
| 调用链连通 | ✅ | 各系统调用 canAutoExecute 检查授权 |
|
||||
| 配置传递 | ✅ | 自主级别配置正确存储 |
|
||||
| 启动恢复 | ✅ | 从 localStorage 恢复配置 |
|
||||
| 降级策略 | ✅ | 高风险操作始终需要确认 |
|
||||
| 数据流闭环 | ✅ | 操作请求 → 风险评估 → 授权检查 → 执行 |
|
||||
| dead_code 清理 | ✅ | 无死代码 |
|
||||
| 测试覆盖 | ✅ | 包含在 autonomy-manager.test.ts |
|
||||
|
||||
**完成度**: **95%+** ✅ 生产就绪
|
||||
|
||||
---
|
||||
|
||||
#### 上下文压缩 (Context Compaction)
|
||||
| 审计项 | 状态 | 说明 |
|
||||
|--------|------|------|
|
||||
| 代码存在性 | ✅ | compactor.rs, intelligence-client.ts |
|
||||
| 实现完整性 | ⚠️ | Token 估算、规则摘要已实现;LLM 摘要未实现 |
|
||||
| 调用链连通 | ✅ | 内核 AgentLoop 集成 (15k token 阈值) |
|
||||
| 配置传递 | ✅ | 压缩配置正确传递 |
|
||||
| 启动恢复 | ✅ | 使用默认配置 |
|
||||
| 降级策略 | ✅ | LLM 不可用时使用规则摘要 |
|
||||
| 数据流闭环 | ✅ | 检查阈值 → 压缩 → 生成摘要 → 替换消息 |
|
||||
| dead_code 清理 | ⚠️ | compactor.rs 标记 dead_code (完整版未启用) |
|
||||
| 测试覆盖 | ✅ | 包含在 compactor.test.ts |
|
||||
|
||||
**完成度**: **85%+** ✅ 生产就绪
|
||||
|
||||
**差距模式**: "写了没接" - LLM 摘要生成 (use_llm: true) 未实现
|
||||
|
||||
---
|
||||
|
||||
### 2.3 Skills 生态 (Skills Ecosystem)
|
||||
|
||||
#### Skill 系统 (Skill System)
|
||||
| 审计项 | 状态 | 说明 |
|
||||
|--------|------|------|
|
||||
| 代码存在性 | ✅ | skill-discovery.ts, SkillRegistry (Rust) |
|
||||
| 实现完整性 | ⚠️ | 78+ SKILL.md、动态扫描、execute_skill 已实现;WASM/Native 模式未实现 |
|
||||
| 调用链连通 | ✅ | Kernel → SkillRegistry → skill_list/skill_refresh |
|
||||
| 配置传递 | ✅ | skills_dir 配置正确传递 |
|
||||
| 启动恢复 | ✅ | Kernel 启动时扫描 skills 目录 |
|
||||
| 降级策略 | ✅ | PromptOnly 模式作为默认 |
|
||||
| 数据流闭环 | ✅ | 扫描 → 注册 → 列表 → 执行 |
|
||||
| dead_code 清理 | ✅ | 无死代码 |
|
||||
| 测试覆盖 | ✅ | 50+ 单元测试 |
|
||||
|
||||
**完成度**: **80%+** ✅ 生产就绪
|
||||
|
||||
**差距模式**: "写了没接" - WASM/Native 执行模式、Schema 验证未实现
|
||||
|
||||
---
|
||||
|
||||
#### 智能路由 (Intelligent Routing)
|
||||
| 审计项 | 状态 | 说明 |
|
||||
|--------|------|------|
|
||||
| 代码存在性 | ⚠️ | 仅有设计文档,无完整实现 |
|
||||
| 实现完整性 | ⚠️ | 系统提示词注入技能列表已实现;语义路由器未实现 |
|
||||
| 调用链连通 | ❌ | 无 Embedding 索引,无 LLM 决策 |
|
||||
| 配置传递 | ❌ | 无配置传递 |
|
||||
| 启动恢复 | ❌ | 无启动恢复 |
|
||||
| 降级策略 | ❌ | 无降级策略 |
|
||||
| 数据流闭环 | ❌ | 仅完成 40% |
|
||||
| dead_code 清理 | N/A | 无代码 |
|
||||
| 测试覆盖 | ❌ | 无测试 |
|
||||
|
||||
**完成度**: **40%+** ⚠️ 需完善
|
||||
|
||||
**差距模式**: "写了没接" - 设计文档完整,实现仅完成 40%
|
||||
|
||||
---
|
||||
|
||||
### 2.4 Pipeline DSL
|
||||
|
||||
#### Pipeline 系统
|
||||
| 审计项 | 状态 | 说明 |
|
||||
|--------|------|------|
|
||||
| 代码存在性 | ✅ | pipeline-client.ts, zclaw-pipeline crate |
|
||||
| 实现完整性 | ✅ | YAML 解析、执行引擎、状态管理、9 种 Action |
|
||||
| 调用链连通 | ✅ | PipelinesPanel → pipeline-client → Tauri 命令 |
|
||||
| 配置传递 | ✅ | Pipeline 配置正确解析 |
|
||||
| 启动恢复 | ✅ | Kernel 启动时加载 Pipeline |
|
||||
| 降级策略 | ✅ | 错误时停止执行 |
|
||||
| 数据流闭环 | ✅ | 解析 → 执行 → 状态更新 → 结果 |
|
||||
| dead_code 清理 | ✅ | 无死代码 |
|
||||
| 测试覆盖 | ✅ | 包含在 pipeline.test.ts |
|
||||
|
||||
**完成度**: **90%+** ✅ 生产就绪
|
||||
|
||||
---
|
||||
|
||||
### 2.5 架构层 (Architecture)
|
||||
|
||||
#### 通信层 (Communication Layer)
|
||||
| 审计项 | 状态 | 说明 |
|
||||
|--------|------|------|
|
||||
| 代码存在性 | ✅ | kernel-client.ts, gateway-client.ts |
|
||||
| 实现完整性 | ✅ | 80+ Tauri 命令、双客户端模式 |
|
||||
| 调用链连通 | ✅ | UI → Store → Client → Tauri 命令 |
|
||||
| 配置传递 | ✅ | 模型配置正确传递 |
|
||||
| 启动恢复 | ✅ | 从 localStorage 恢复配置 |
|
||||
| 降级策略 | ✅ | 离线模式支持 |
|
||||
| 数据流闭环 | ✅ | 连接 → 配置 → 调用 → 响应 |
|
||||
| dead_code 清理 | ⚠️ | llm/mod.rs 部分方法标记 dead_code |
|
||||
| 测试覆盖 | ✅ | 85% 覆盖率 |
|
||||
|
||||
**完成度**: **95%+** ✅ 生产就绪
|
||||
|
||||
---
|
||||
|
||||
#### 状态管理 (State Management)
|
||||
| 审计项 | 状态 | 说明 |
|
||||
|--------|------|------|
|
||||
| 代码存在性 | ✅ | 18+ Zustand Store |
|
||||
| 实现完整性 | ✅ | 持久化中间件、依赖注入、跨 Store 通信 |
|
||||
| 调用链连通 | ✅ | 组件 → Store → Client |
|
||||
| 配置传递 | ✅ | Store 配置正确传递 |
|
||||
| 启动恢复 | ✅ | 从 localStorage 恢复状态 |
|
||||
| 降级策略 | ✅ | 默认状态兜底 |
|
||||
| 数据流闭环 | ✅ | 状态更新 → 持久化 → 恢复 |
|
||||
| dead_code 清理 | ✅ | 无死代码 |
|
||||
| 测试覆盖 | ✅ | 85% 覆盖率 |
|
||||
|
||||
**完成度**: **95%+** ✅ 生产就绪
|
||||
|
||||
---
|
||||
|
||||
### 2.6 上下文数据库 (Context Database)
|
||||
|
||||
#### OpenViking 集成
|
||||
| 审计项 | 状态 | 说明 |
|
||||
|--------|------|------|
|
||||
| 代码存在性 | ✅ | viking-client.ts, viking_commands.rs |
|
||||
| 实现完整性 | ✅ | 本地/远程/存储三种模式、L0/L1/L2 分层 |
|
||||
| 调用链连通 | ✅ | VikingPanel → viking-client → Tauri 命令 |
|
||||
| 配置传递 | ✅ | Embedding 配置正确传递 |
|
||||
| 启动恢复 | ✅ | App.tsx 恢复 Embedding 配置 |
|
||||
| 降级策略 | ✅ | 无 OpenViking 时使用本地存储 |
|
||||
| 数据流闭环 | ✅ | 添加 → 存储 → 搜索 → 读取 |
|
||||
| dead_code 清理 | ✅ | 无死代码 |
|
||||
| 测试覆盖 | ✅ | 85% 覆盖率 |
|
||||
|
||||
**完成度**: **85%+** ✅ 生产就绪
|
||||
|
||||
---
|
||||
|
||||
## 三、差距模式汇总
|
||||
|
||||
### 3.1 "写了没接" (Code exists but not integrated)
|
||||
|
||||
| 功能/模块 | 文件位置 | 差距描述 | 优先级 |
|
||||
|-----------|----------|----------|--------|
|
||||
| Predictor Hand | hands/predictor.HAND.toml | 仅有配置文件,无 Rust 实现 | P2 |
|
||||
| Lead Hand | hands/lead.HAND.toml | 仅有配置文件,无 Rust 实现 | P2 |
|
||||
| 智能路由 | docs/features/04-skills-ecosystem/01-intelligent-routing.md | 设计文档完整,实现仅 40% | P1 |
|
||||
| LLM 摘要生成 | compactor.rs | use_llm: true 配置存在但未实现 | P2 |
|
||||
| 增量压缩 | compactor.rs | 设计了但未启用 | P3 |
|
||||
| 压缩预览 | compactor.rs | 设计了但未实现 | P3 |
|
||||
| persona_evolver.rs | desktop/src-tauri/src/intelligence/ | 完整实现但标记 dead_code | P2 |
|
||||
| mesh.rs | desktop/src-tauri/src/intelligence/ | 完整实现但标记 dead_code | P2 |
|
||||
| pattern_detector.rs | desktop/src-tauri/src/intelligence/ | 完整实现但标记 dead_code | P2 |
|
||||
| trigger_evaluator.rs | desktop/src-tauri/src/intelligence/ | 完整实现但标记 dead_code | P2 |
|
||||
| validation.rs | desktop/src-tauri/src/intelligence/ | 完整实现但标记 dead_code | P3 |
|
||||
| context_builder.rs | desktop/src-tauri/src/memory/ | 完整实现但标记 dead_code | P2 |
|
||||
| WASM 执行模式 | zclaw-skills/src/executor.rs | 设计了但未实现 | P3 |
|
||||
| Native 执行模式 | zclaw-skills/src/executor.rs | 设计了但未实现 | P3 |
|
||||
| Schema 验证 | zclaw-skills/src/executor.rs | 解析但未验证 | P3 |
|
||||
|
||||
### 3.2 "双系统不同步" (Dual systems not synchronized)
|
||||
|
||||
| 系统 | 文件位置 | 差距描述 | 优先级 |
|
||||
|------|----------|----------|--------|
|
||||
| SqliteStorage vs PersistentMemoryStore | crates/zclaw-growth vs desktop/src-tauri/src/memory | FTS5/TF-IDF: SqliteStorage 有,PersistentMemoryStore 无 | P1 |
|
||||
| L0/L1 生成 | crates/zclaw-growth | SqliteStorage 有,PersistentMemoryStore 无 | P1 |
|
||||
| 导出/导入 | desktop/src-tauri/src/memory | SqliteStorage 无,PersistentMemoryStore 有 | P2 |
|
||||
|
||||
### 3.3 "存了没用" (Stored but not used)
|
||||
|
||||
| 数据/字段 | 文件位置 | 差距描述 | 优先级 |
|
||||
|-----------|----------|----------|--------|
|
||||
| overview 字段 | MemoryEntry | 存储了但搜索时未返回 | P2 |
|
||||
| L0/L1/L2 渐进加载 | context_builder.rs | 实现了但未启用完整版 | P2 |
|
||||
|
||||
---
|
||||
|
||||
## 四、dead_code 清理建议
|
||||
|
||||
### 4.1 建议启用 (Ready to enable)
|
||||
|
||||
| 模块 | 文件 | 理由 |
|
||||
|------|------|------|
|
||||
| context_builder.rs | memory/context_builder.rs | 完整的 L0→L1→L2 渐进加载,可提升记忆检索质量 |
|
||||
| persona_evolver.rs | intelligence/persona_evolver.rs | 人格演化核心功能,可增强 Agent 自我进化能力 |
|
||||
| pattern_detector.rs | intelligence/pattern_detector.rs | 模式检测是智能化的基础 |
|
||||
|
||||
### 4.2 建议保留 (Keep as reserved)
|
||||
|
||||
| 模块 | 文件 | 理由 |
|
||||
|------|------|------|
|
||||
| heartbeat.rs 部分方法 | intelligence/heartbeat.rs | 保留用于 UI 状态显示 |
|
||||
| compactor.rs 完整版 | intelligence/compactor.rs | 保留用于未来高级压缩功能 |
|
||||
| validation.rs | intelligence/validation.rs | 保留用于未来 API 验证 |
|
||||
|
||||
### 4.3 建议删除 (Consider removing)
|
||||
|
||||
| 模块 | 文件 | 理由 |
|
||||
|------|------|------|
|
||||
| browser/actions.rs | browser/actions.rs | 如果不计划使用,可删除减少维护负担 |
|
||||
| browser/error.rs | browser/error.rs | 如果不计划使用,可删除减少维护负担 |
|
||||
| browser/session.rs | browser/session.rs | 如果不计划使用,可删除减少维护负担 |
|
||||
|
||||
---
|
||||
|
||||
## 五、优先修复建议
|
||||
|
||||
### 5.1 P0 - 阻塞性问题 (立即修复)
|
||||
|
||||
无阻塞性问题
|
||||
|
||||
### 5.2 P1 - 重要问题 (1-2 周内修复)
|
||||
|
||||
| 问题 | 影响 | 修复建议 |
|
||||
|------|------|----------|
|
||||
| 智能路由未完成 | 技能匹配精度低 | 实现 SemanticSkillRouter,完成 Embedding 索引 + LLM 决策 |
|
||||
| 双存储系统不一致 | 功能不对等 | 统一为一套存储系统,或在 PersistentMemoryStore 补齐缺失能力 |
|
||||
| context_builder.rs 未启用 | 记忆检索质量低 | 启用完整版 L0→L1→L2 渐进加载 |
|
||||
|
||||
### 5.3 P2 - 中等问题 (1-2 月内修复)
|
||||
|
||||
| 问题 | 影响 | 修复建议 |
|
||||
|------|------|----------|
|
||||
| Predictor/Lead Hand 未实现 | 功能缺失 | 实现 Rust 后端或从文档中移除 |
|
||||
| LLM 摘要未实现 | 压缩质量有限 | 实现 LLM 驱动摘要生成 |
|
||||
| persona_evolver.rs 未启用 | Agent 演化能力受限 | 启用并集成到反思流程 |
|
||||
| mesh.rs 未启用 | 多 Agent 协作受限 | 评估是否需要,如需要则启用 |
|
||||
|
||||
### 5.4 P3 - 低优先级 (后续迭代)
|
||||
|
||||
| 问题 | 影响 | 修复建议 |
|
||||
|------|------|----------|
|
||||
| WASM/Native 执行模式 | 扩展性 | 按需实现 |
|
||||
| Schema 验证 | 数据质量 | 完善验证逻辑 |
|
||||
| 增量压缩/压缩预览 | 用户体验 | 按需实现 |
|
||||
|
||||
---
|
||||
|
||||
## 六、测试覆盖分析
|
||||
|
||||
### 6.1 测试覆盖良好的模块
|
||||
|
||||
| 模块 | 测试数量 | 覆盖率 |
|
||||
|------|---------|--------|
|
||||
| chatStore | 42 tests | ~85% |
|
||||
| gatewayStore | 35 tests | ~85% |
|
||||
| agent-memory | 42 tests | ~95% |
|
||||
| reflection-engine | 包含在 intelligence | ~80% |
|
||||
| pipeline | 包含在 pipeline.test | ~90% |
|
||||
|
||||
### 6.2 测试覆盖不足的模块
|
||||
|
||||
| 模块 | 当前状态 | 建议 |
|
||||
|------|---------|------|
|
||||
| embedding_adapter.rs | 无测试 | 添加单元测试 |
|
||||
| memory_commands.rs | 无测试 | 添加集成测试 |
|
||||
| persistent.rs | 仅 1 个测试 | 扩展测试覆盖 |
|
||||
| 端到端 embedding + 搜索 | 无测试 | 添加 E2E 测试 |
|
||||
| 端到端 L0/L1 生成 | 无测试 | 添加 E2E 测试 |
|
||||
| 智能路由 | 无测试 | 添加测试 |
|
||||
|
||||
---
|
||||
|
||||
## 七、审计结论
|
||||
|
||||
### 7.1 总体评估
|
||||
|
||||
ZCLAW 项目整体功能完成度较高 (**85%+**),核心功能已完全实现并集成。主要差距集中在:
|
||||
|
||||
1. **智能路由系统** - 设计完整但实现仅 40%
|
||||
2. **双存储系统不一致** - SqliteStorage 和 PersistentMemoryStore 功能不对等
|
||||
3. **部分 Hands 未实现** - Predictor 和 Lead 仅有配置文件
|
||||
4. **大量 dead_code 模块** - 需要评估是否启用或删除
|
||||
|
||||
### 7.2 建议优先级
|
||||
|
||||
1. **立即**: 完成智能路由系统实现
|
||||
2. **短期**: 统一双存储系统或补齐功能
|
||||
3. **中期**: 实现 Predictor/Lead Hand 或移除文档
|
||||
4. **持续**: 清理 dead_code,评估是否启用或删除
|
||||
|
||||
### 7.3 风险提示
|
||||
|
||||
- **技术债务**: 39 处 dead_code 标记需要定期评估
|
||||
- **测试覆盖**: 部分 E2E 测试缺失,建议补充
|
||||
- **文档一致性**: 部分功能文档与实现不同步,需要更新
|
||||
|
||||
---
|
||||
|
||||
## 附录:审计命令速查
|
||||
|
||||
```bash
|
||||
# 搜索 dead_code 标记
|
||||
rg "allow\(dead_code\)" --type rust
|
||||
|
||||
# 搜索未使用的函数
|
||||
rg "#\[allow(dead_code)\]" crates/ desktop/src-tauri/src/
|
||||
|
||||
# 搜索未注册的 Tauri 命令
|
||||
rg "#\[tauri::command\]" desktop/src-tauri/src/ -l
|
||||
# 对比 lib.rs 中的 .invoke_handler() 注册列表
|
||||
|
||||
# 搜索前端 invoke 调用
|
||||
rg "invoke\(" desktop/src/ --type ts -l
|
||||
|
||||
# 编译检查
|
||||
cargo check 2>&1 | grep -i "warning\|error"
|
||||
|
||||
# 测试
|
||||
cargo test -p zclaw-growth 2>&1 | tail -5
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**审计人**: Claude AI Agent
|
||||
**审计日期**: 2026-03-27
|
||||
**下次审计建议**: 3 个月后或重大版本发布前
|
||||
324
docs/archive/old-audits/FRONTEND_INTEGRATION_AUDIT.md
Normal file
@@ -0,0 +1,324 @@
|
||||
# 前端集成审计报告
|
||||
|
||||
> **ARCHIVED — 此报告已过时**
|
||||
>
|
||||
> 本报告审计于 2026-03-17,仅反映当时的前端集成状态。
|
||||
> 截至 2026-03-28,SaaS 集成、Admin 管理后台、TOTP 2FA 等大量前端功能已上线。
|
||||
>
|
||||
> **请参考最新文档** → [README.md](./README.md) | [DEEP_AUDIT_REPORT.md](./DEEP_AUDIT_REPORT.md)
|
||||
>
|
||||
> **原始审计信息:**
|
||||
> **审计日期**: 2026-03-17
|
||||
> **审计范围**: docs/features 目录下所有功能文档 vs 实际前端代码实现
|
||||
> **审计目的**: 验证功能文档声称的"已实现"是否真正集成到前端 UI
|
||||
|
||||
---
|
||||
|
||||
## 一、审计摘要
|
||||
|
||||
| 分类 | 文档声称成熟度 | 实际集成状态 | 差异等级 |
|
||||
|------|---------------|-------------|---------|
|
||||
| 架构层 | L4 | ✅ 已集成 | 无 |
|
||||
| 核心功能 | L3-L4 | ⚠️ 部分集成 | 中 |
|
||||
| 智能层 | L4 | ❌ 大部分未集成 | 高 |
|
||||
| 上下文数据库 | L3-L4 | ⚠️ 部分集成 | 中 |
|
||||
| Skills 生态 | L4 | ❌ 未集成 | 高 |
|
||||
| Hands 系统 | L3 | ✅ 已集成 | 低 |
|
||||
| Tauri 后端 | L4 | ✅ 已集成 | 无 |
|
||||
|
||||
---
|
||||
|
||||
## 二、详细审计结果
|
||||
|
||||
### 2.1 架构层 (Architecture)
|
||||
|
||||
| 功能 | 文档 | 实际状态 | 集成位置 |
|
||||
|------|------|---------|---------|
|
||||
| 通信层 | L4 已完成 | ✅ 已集成 | `gateway-client.ts`, `tauri-gateway.ts` |
|
||||
| 状态管理 | L4 已完成 | ✅ 已集成 | `store/*.ts` (13个store文件) |
|
||||
| 安全认证 | L4 已完成 | ✅ 已集成 | `gatewayStore.ts`, Tauri commands |
|
||||
|
||||
**结论**: 架构层文档准确,功能已正确集成。
|
||||
|
||||
---
|
||||
|
||||
### 2.2 核心功能 (Core Features)
|
||||
|
||||
| 功能 | 文档声称 | 实际状态 | 问题 |
|
||||
|------|---------|---------|------|
|
||||
| Chat 界面 | L4 已完成 | ✅ 已集成 | `ChatArea.tsx` 正常工作 |
|
||||
| Agent 分身 | L4 已完成 | ✅ 已集成 | `CloneManager.tsx` + `agentStore.ts` |
|
||||
| Hands 系统 | L3 成熟 | ✅ 已集成 | 见 2.6 节详细分析 |
|
||||
| 工作流引擎 | L3 成熟 | ⚠️ 部分集成 | **问题见下方** |
|
||||
| 团队协作 | L3 成熟 | ✅ 已集成 | `TeamList.tsx` + `TeamCollaborationView.tsx` |
|
||||
| 多 Agent 协作 | L4 已完成 | ✅ 已集成 | `SwarmDashboard.tsx` |
|
||||
|
||||
#### Workflow 系统问题
|
||||
|
||||
**文档声称**:
|
||||
- WorkflowEditor 可视化编辑器
|
||||
- WorkflowHistory 执行历史
|
||||
- 多步骤工作流编排
|
||||
|
||||
**实际代码**:
|
||||
```
|
||||
✅ WorkflowList.tsx - 已集成到 Sidebar
|
||||
✅ workflowStore.ts - 完整状态管理
|
||||
✅ SchedulerPanel.tsx - 已集成到 App.tsx
|
||||
❌ WorkflowEditor.tsx - 存在但未集成到任何视图
|
||||
❌ WorkflowHistory.tsx - 存在但未集成到任何视图
|
||||
```
|
||||
|
||||
**结论**: Workflow 编辑器和历史组件存在代码但未集成到 UI。
|
||||
|
||||
---
|
||||
|
||||
### 2.3 智能层 (Intelligence Layer) - ✅ 已集成 (2026-03-17 更新)
|
||||
|
||||
| 功能 | 文档声称 | 实际状态 | 问题 |
|
||||
|------|---------|---------|------|
|
||||
| Agent 记忆 | L4 已完成 | ✅ 已集成 | `MemoryPanel.tsx` 在 RightPanel 'memory' tab |
|
||||
| 身份演化 | L4 已完成 | ❓ 未验证 | 需检查后端实现 |
|
||||
| 上下文压缩 | L4 已完成 | ❓ 未验证 | `context-compactor.ts` 存在 |
|
||||
| 自我反思 | L4 已完成 | ✅ **已集成** | `ReflectionLog.tsx` 在 RightPanel 'reflection' tab |
|
||||
| 心跳巡检 | L4 已完成 | ❓ 未验证 | `heartbeat-engine.ts` 存在 |
|
||||
| 自主授权 | L4 已完成 | ✅ **已集成** | `AutonomyConfig.tsx` 在 RightPanel 'autonomy' tab |
|
||||
|
||||
#### 已集成的智能层组件
|
||||
|
||||
```
|
||||
✅ MemoryPanel.tsx - 集成到 RightPanel 'memory' tab
|
||||
✅ ReflectionLog.tsx - 集成到 RightPanel 'reflection' tab (2026-03-17)
|
||||
✅ AutonomyConfig.tsx - 集成到 RightPanel 'autonomy' tab (2026-03-17)
|
||||
✅ ActiveLearningPanel.tsx - 集成到 RightPanel 'learning' tab (2026-03-17)
|
||||
```
|
||||
|
||||
**相关 lib 文件**:
|
||||
```
|
||||
✅ agent-memory.ts - 已被 MemoryPanel 使用
|
||||
✅ reflection-engine.ts - 已被 ReflectionLog 使用
|
||||
✅ autonomy-manager.ts - 已被 AutonomyConfig 使用
|
||||
✅ active-learning.ts - 已被 ActiveLearningPanel 使用
|
||||
✅ vector-memory.ts - 存在但未被 UI 使用
|
||||
```
|
||||
|
||||
**结论**: 智能层核心组件已全部完成前端集成。
|
||||
|
||||
---
|
||||
|
||||
### 2.4 上下文数据库 (Context Database)
|
||||
|
||||
| 功能 | 文档声称 | 实际状态 | 问题 |
|
||||
|------|---------|---------|------|
|
||||
| OpenViking 集成 | L4 已完成 | ⚠️ 部分集成 | lib 存在,集成不完整 |
|
||||
| 向量记忆 | L3 成熟 | ❌ 未集成 | `vector-memory.ts` 存在但未使用 |
|
||||
| 会话持久化 | L4 已完成 | ✅ 已集成 | `session-persistence.ts` |
|
||||
| 记忆提取 | L4 已完成 | ❓ 未验证 | `memory-extractor.ts` 存在 |
|
||||
|
||||
#### OpenViking 相关文件
|
||||
|
||||
```
|
||||
✅ viking-client.ts - 存在
|
||||
✅ viking-adapter.ts - 存在
|
||||
✅ viking-local.ts - 存在
|
||||
✅ viking-memory-adapter.ts - 存在
|
||||
✅ viking-server-manager.ts - 存在
|
||||
❓ 需验证这些是否被实际使用
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2.5 Skills 生态 - ✅ 已集成 (2026-03-17 更新)
|
||||
|
||||
| 功能 | 文档声称 | 实际状态 | 问题 |
|
||||
|------|---------|---------|------|
|
||||
| Skill 系统概述 | L4 已完成 | ✅ 已集成 | SkillMarket 已集成到 Sidebar/App |
|
||||
| 内置技能 (74个) | L4 已完成 | ❓ 未验证 | 需检查后端 |
|
||||
| 技能发现 | L4 已完成 | ✅ **已集成** | SkillMarket 组件已使用 |
|
||||
|
||||
#### 已集成的 Skills 组件
|
||||
|
||||
```
|
||||
✅ SkillMarket.tsx - 集成到 Sidebar 'skills' tab 和 App.tsx main view (2026-03-17)
|
||||
✅ Settings/Skills.tsx - 已集成到设置页
|
||||
```
|
||||
|
||||
**相关文件**:
|
||||
```
|
||||
✅ skill-discovery.ts - 已被 SkillMarket 使用
|
||||
✅ skillMarketStore.ts - 存在
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 2.6 Hands 系统
|
||||
|
||||
| 功能 | 文档声称 | 实际状态 | 问题 |
|
||||
|------|---------|---------|------|
|
||||
| Hands 概述 (7个) | L3 成熟 | ✅ 已集成 | 完整实现 |
|
||||
|
||||
#### 已集成的 Hands 组件
|
||||
|
||||
```
|
||||
✅ HandList.tsx - 集成到 Sidebar
|
||||
✅ HandsPanel.tsx - 完整的 Hands 管理面板
|
||||
✅ HandTaskPanel.tsx - 集成到 App.tsx
|
||||
✅ HandParamsForm.tsx - ✅ 已集成到 HandsPanel 触发流程 (2026-03-17)
|
||||
✅ HandApprovalModal.tsx - ✅ 已集成到 App.tsx 全局审批 (2026-03-17)
|
||||
✅ BrowserHand/* - Browser Hand 专用组件
|
||||
✅ handStore.ts - 完整状态管理
|
||||
✅ browserHandStore.ts - Browser Hand 状态
|
||||
```
|
||||
|
||||
**结论**: Hands 系统文档准确,功能已完整集成,包括参数表单和审批弹窗。
|
||||
|
||||
---
|
||||
|
||||
### 2.7 Tauri 后端
|
||||
|
||||
| 功能 | 文档声称 | 实际状态 | 问题 |
|
||||
|------|---------|---------|------|
|
||||
| ZCLAW 集成 | L4 已完成 | ✅ 已集成 | `tauri-gateway.ts` |
|
||||
| 安全存储 | L4 已完成 | ✅ 已集成 | `secure-storage.ts` |
|
||||
| 本地 Gateway | L4 已完成 | ✅ 已集成 | 自动启动逻辑 |
|
||||
|
||||
---
|
||||
|
||||
## 三、存在但未集成的组件清单
|
||||
|
||||
以下组件存在于 `desktop/src/components/` 但**未**被渲染到任何视图:
|
||||
|
||||
| 组件 | 文件 | 功能 | 严重程度 |
|
||||
|------|------|------|---------|
|
||||
| ~~WorkflowEditor~~ | ~~`WorkflowEditor.tsx`~~ | ~~工作流可视化编辑~~ | ✅ 已集成 |
|
||||
| ~~WorkflowHistory~~ | ~~`WorkflowHistory.tsx`~~ | ~~执行历史查看~~ | ✅ 已集成 |
|
||||
| ~~ReflectionLog~~ | ~~`ReflectionLog.tsx`~~ | ~~自我反思日志~~ | ✅ 已集成 |
|
||||
| ~~AutonomyConfig~~ | ~~`AutonomyConfig.tsx`~~ | ~~自主授权配置~~ | ✅ 已集成 |
|
||||
| ~~ActiveLearningPanel~~ | ~~`ActiveLearningPanel.tsx`~~ | ~~主动学习面板~~ | ✅ 已集成 |
|
||||
| ~~SkillMarket~~ | ~~`SkillMarket.tsx`~~ | ~~技能市场~~ | ✅ 已集成 |
|
||||
| ~~SkillCard~~ | ~~`SkillMarket/SkillCard.tsx`~~ | ~~技能卡片~~ | ✅ 已集成 |
|
||||
| ~~MemoryGraph~~ | ~~`MemoryGraph.tsx`~~ | ~~记忆图谱可视化~~ | ✅ 已集成到 RightPanel memory tab |
|
||||
| ~~AuditLogsPanel~~ | ~~`AuditLogsPanel.tsx`~~ | ~~审计日志面板~~ | ✅ 已集成 |
|
||||
| ~~SecurityLayersPanel~~ | ~~`SecurityLayersPanel.tsx`~~ | ~~安全层面板~~ | ✅ 已集成 |
|
||||
| ~~TriggersPanel~~ | ~~`TriggersPanel.tsx`~~ | ~~触发器管理~~ | ✅ 已集成到 SchedulerPanel triggers tab |
|
||||
| ~~ApprovalsPanel~~ | ~~`ApprovalsPanel.tsx`~~ | ~~审批管理面板~~ | ✅ 已集成到 HandsPanel approvals tab |
|
||||
| ~~TeamOrchestrator~~ | ~~`TeamOrchestrator.tsx`~~ | ~~团队编排器~~ | ✅ 已集成到 App team view orchestrator tab |
|
||||
| ~~SecurityStatus~~ | ~~`SecurityStatus.tsx`~~ | ~~安全状态显示~~ | ✅ 已集成 |
|
||||
| HeartbeatConfig | `HeartbeatConfig.tsx` | 心跳配置 | 低 |
|
||||
| CreateTriggerModal | `CreateTriggerModal.tsx` | 创建触发器弹窗 | 低 |
|
||||
| ~~FeedbackButton~~ | ~~`Feedback/FeedbackButton.tsx`~~ | ~~反馈按钮~~ | ✅ 已集成到 SettingsLayout |
|
||||
| ~~FeedbackHistory~~ | ~~`Feedback/FeedbackHistory.tsx`~~ | ~~反馈历史~~ | ✅ 已集成到 SettingsLayout |
|
||||
| ~~FeedbackModal~~ | ~~`Feedback/FeedbackModal.tsx`~~ | ~~反馈弹窗~~ | ✅ 已集成到 SettingsLayout |
|
||||
| ~~MessageSearch~~ | ~~`MessageSearch.tsx`~~ | ~~消息搜索~~ | ✅ Sidebar 已有搜索功能 |
|
||||
| ~~MemoryGraph~~ | ~~`MemoryGraph.tsx`~~ | ~~记忆图谱可视化~~ | ✅ 已集成到 RightPanel memory tab |
|
||||
| PersonalitySelector | `PersonalitySelector.tsx` | 个性选择器 | 低 |
|
||||
| ScenarioTags | `ScenarioTags.tsx` | 场景标签 | 低 |
|
||||
| BrowserHand/* | `BrowserHand/*.tsx` | Browser Hand 组件 | ✅ 已被 HandsPanel 使用 |
|
||||
| DevQALoop | `DevQALoop.tsx` | 开发 QA 循环 | 低 (开发工具) |
|
||||
|
||||
---
|
||||
|
||||
## 四、存在但未使用的 lib 文件
|
||||
|
||||
以下 lib 文件存在但**未**被 UI 组件直接使用:
|
||||
|
||||
| 文件 | 功能 | 状态 |
|
||||
|------|------|------|
|
||||
| `reflection-engine.ts` | 自我反思引擎 | ✅ 已被 ReflectionLog 使用 |
|
||||
| `autonomy-manager.ts` | 自主授权管理 | ✅ 已被 AutonomyConfig 使用 |
|
||||
| `active-learning.ts` | 主动学习 | ✅ 已被 ActiveLearningPanel 使用 |
|
||||
| `vector-memory.ts` | 向量记忆 | ❌ 未被 UI 使用 |
|
||||
| `memory-extractor.ts` | 记忆提取 | ❓ 需验证 |
|
||||
| `memory-index.ts` | 记忆索引 | ❓ 需验证 |
|
||||
| `context-compactor.ts` | 上下文压缩 | ❓ 需验证 |
|
||||
| `heartbeat-engine.ts` | 心跳巡检引擎 | ❓ 需验证 |
|
||||
| `agent-swarm.ts` | Agent 蜂群 | ❓ 需验证 |
|
||||
| `skill-discovery.ts` | 技能发现 | ✅ 已被 SkillMarket 使用 |
|
||||
|
||||
---
|
||||
|
||||
## 五、建议修复优先级
|
||||
|
||||
### P0 - 紧急 (影响核心价值) - ✅ 全部完成
|
||||
|
||||
1. ~~**集成智能层组件**~~ - ✅ **已完成 (2026-03-17)**
|
||||
- ~~`ReflectionLog.tsx` → 添加到 RightPanel 或新 tab~~ - ✅ 已集成
|
||||
- ~~`AutonomyConfig.tsx` → 添加到设置页或 RightPanel~~ - ✅ 已集成
|
||||
- ~~`ActiveLearningPanel.tsx` → 添加到 RightPanel~~ - ✅ 已集成
|
||||
|
||||
2. ~~**集成 Skills 市场**~~ - ✅ **已完成 (2026-03-17)**
|
||||
- ~~`SkillMarket.tsx` → 添加为新视图或 Sidebar tab~~ - ✅ 已集成
|
||||
|
||||
### P1 - 重要 (完善用户体验) - ✅ 全部完成
|
||||
|
||||
3. ~~**集成 Workflow 编辑器**~~ - ✅ **已完成 (2026-03-17)**
|
||||
- ~~`WorkflowEditor.tsx` → 集成到 workflow 视图~~ - ✅ 已集成到 SchedulerPanel workflows tab
|
||||
- ~~`WorkflowHistory.tsx` → 集成到 workflow 视图~~ - ✅ 已集成到 SchedulerPanel workflows tab
|
||||
|
||||
4. ~~**集成安全与审计**~~ - ✅ **已完成 (2026-03-17)**
|
||||
- ~~`AuditLogsPanel.tsx` → 添加到设置页~~ - ✅ 已集成到 SettingsLayout 'audit' page
|
||||
- ~~`SecurityLayersPanel.tsx` → 添加到设置页~~ - ✅ 已集成到 SettingsLayout 'security' page
|
||||
|
||||
5. ~~**集成 Hands 参数表单和审批弹窗**~~ - ✅ **已完成 (2026-03-17)**
|
||||
- ~~`HandParamsForm.tsx` → 集成到 HandsPanel 触发流程~~ - ✅ 已集成
|
||||
- ~~`HandApprovalModal.tsx` → 集成到 App.tsx 全局监听~~ - ✅ 已集成
|
||||
|
||||
### P2 - 增强 (锦上添花) - ✅ MemoryGraph、TriggersPanel 已完成
|
||||
|
||||
5. **集成其他组件**
|
||||
- ~~`TriggersPanel.tsx` → 添加到 workflow 视图~~ - ✅ 已集成到 SchedulerPanel (2026-03-18)
|
||||
- `ApprovalsPanel.tsx` → 添加到 hands 视图
|
||||
- ~~`MemoryGraph.tsx` → 添加到 memory tab~~ - ✅ 已集成 (2026-03-18)
|
||||
- `MessageSearch.tsx` → 添加到 ChatArea
|
||||
|
||||
---
|
||||
|
||||
## 六、文档更新建议
|
||||
|
||||
以下文档需要更新以反映实际状态:
|
||||
|
||||
| 文档 | 当前声称 | 建议更新 |
|
||||
|------|---------|---------|
|
||||
| `02-intelligence-layer/03-reflection-engine.md` | L4 已完成 | ✅ 已更新为 L4 已集成 |
|
||||
| `02-intelligence-layer/05-autonomy-manager.md` | L4 已完成 | ✅ 已更新为 L4 已集成 |
|
||||
| `04-skills-ecosystem/00-skill-system.md` | L4 已完成 | ✅ 已更新为 L4 已集成 |
|
||||
|
||||
---
|
||||
|
||||
## 七、总结
|
||||
|
||||
### 实际情况 vs 文档描述
|
||||
|
||||
| 指标 | 文档声称 | 实际状态 |
|
||||
|------|---------|---------|
|
||||
| 整体成熟度 | 大部分 L4 | ✅ L4 已集成 |
|
||||
| 智能层 | L4 生产级 | ✅ L4 已集成 (2026-03-17) |
|
||||
| Skills 生态 | L4 生产级 | ✅ L4 已集成 (2026-03-17) |
|
||||
| Hands 系统 | L3 成熟 | ✅ 准确 |
|
||||
| 核心功能 | L3-L4 | ✅ 准确 |
|
||||
|
||||
### 核心发现
|
||||
|
||||
1. **Hands 系统文档准确** - 声称的功能确实已完整集成,包括参数表单和审批弹窗
|
||||
2. **智能层已完成集成** - ✅ 反思引擎、自主授权、主动学习已集成到 RightPanel (2026-03-17)
|
||||
3. **Skills 市场已集成** - ✅ SkillMarket 已集成到 Sidebar/App (2026-03-17)
|
||||
4. **Hands 参数和审批已集成** - ✅ HandParamsForm 和 HandApprovalModal 已集成 (2026-03-17)
|
||||
5. **Workflow 编辑器已集成** - ✅ WorkflowEditor 和 WorkflowHistory 已集成到 SchedulerPanel (2026-03-17)
|
||||
6. **安全与审计已集成** - ✅ AuditLogsPanel 和 SecurityLayersPanel 已集成到 SettingsLayout (2026-03-17)
|
||||
7. **记忆图谱已集成** - ✅ MemoryGraph 已集成到 RightPanel memory tab (2026-03-18)
|
||||
8. **触发器面板已集成** - ✅ TriggersPanel 已集成到 SchedulerPanel triggers tab (2026-03-18)
|
||||
9. **审批面板已集成** - ✅ ApprovalsPanel 已集成到 HandsPanel approvals tab (2026-03-18)
|
||||
10. **团队编排器已集成** - ✅ TeamOrchestrator 已集成到 App team view orchestrator tab (2026-03-18)
|
||||
11. **所有组件已集成** - ✅ 无剩余"僵尸组件"
|
||||
|
||||
### 建议行动
|
||||
|
||||
1. ~~**立即**: 更新文档成熟度评级,反映实际集成状态~~ - ✅ 已完成
|
||||
2. ~~**短期**: 集成 SkillMarket 和 ActiveLearningPanel~~ - ✅ 已完成 (2026-03-17)
|
||||
3. ~~**短期**: 集成 HandParamsForm 和 HandApprovalModal~~ - ✅ 已完成 (2026-03-17)
|
||||
4. ~~**中期**: 集成 Workflow Editor/History 和 安全/审计组件~~ - ✅ 已完成 (2026-03-17)
|
||||
5. ~~**中期**: 集成 MemoryGraph~~ - ✅ 已完成 (2026-03-18)
|
||||
6. ~~**中期**: 集成 TriggersPanel~~ - ✅ 已完成 (2026-03-18)
|
||||
7. ~~**中期**: 集成 ApprovalsPanel~~ - ✅ 已完成 (2026-03-18)
|
||||
8. ~~**中期**: 集成 TeamOrchestrator~~ - ✅ 已完成 (2026-03-18)
|
||||
9. **长期**: 建立文档-代码同步机制,避免文档过时
|
||||
191
docs/archive/old-audits/MODULE_AUDIT_SUMMARY.md
Normal file
@@ -0,0 +1,191 @@
|
||||
# ZCLAW V12 模块化端到端审计总报告
|
||||
|
||||
> **审计版本**: V12 (第 15 次)
|
||||
> **审计日期**: 2026-04-04
|
||||
> **审计方法**: 混合矩阵式(10 个功能模块 + 五维检查清单)
|
||||
> **审计范围**: 全量 9 大功能领域,11 个模块
|
||||
|
||||
---
|
||||
|
||||
## 1. 审计总览
|
||||
|
||||
### 各模块健康度评分
|
||||
|
||||
| 排名 | 模块 | 健康度 | P0 | P1 | P2 | P3 | 总问题数 |
|
||||
|------|------|--------|----|----|----|----|---------|
|
||||
| 1 | M1 智能对话 | **91** | 0 | 0 | 4 | 7 | 11 |
|
||||
| 2 | M9 通信与安全 | **86** | 0 | 0 | 5 | 4 | 9 |
|
||||
| 3 | M5 技能生态 | **85** | 0 | 1 | 2 | 3 | 6 |
|
||||
| 4 | M7 SaaS Desktop | **85** | 0 | 2 | 2 | 2 | 6 |
|
||||
| 5 | M8 Admin V2 | **82** | 0 | 0 | 3 | 5 | 8 |
|
||||
| 6 | M6 Pipeline 工作流 | **72** | 0 | 2 | 5 | 1 | 8 |
|
||||
| 7 | M11 Classroom | **70** | 0 | 3 | 2 | 3 | 8 |
|
||||
| 8 | M4 智能层 | **61** | 2 | 2 | 5 | 4 | 13 |
|
||||
| 9 | M2 Agent 分身 | **67** | 0 | 2 | 7 | 5 | 14 |
|
||||
| 10 | M3 Hands 自主能力 | **58** | 0 | 5 | 5 | 3 | 13 |
|
||||
|
||||
**项目整体健康度: 76/100**
|
||||
|
||||
---
|
||||
|
||||
## 2. P0/P1 问题优先修复清单
|
||||
|
||||
### P0 — 必然崩溃或数据丢失(2 项,全部在 M4 智能层)
|
||||
|
||||
| ID | 模块 | 问题 | 文件 | 修复方案 |
|
||||
|----|------|------|------|---------|
|
||||
| M4-01 | M4 | **双数据库**: PersistentMemoryStore vs SqliteStorage 数据不共享,用户手动保存的记忆不出现在对话注入中 | `memory/persistent.rs` vs `zclaw-growth/storage/sqlite.rs` | 合并为单一存储或让前端也查询 SqliteStorage |
|
||||
| M4-02 | M4 | **反思引擎 LLM 未接入**: reflection_reflect 传 driver=None,永远只用规则分析 | `reflection.rs:759-766` | 传入实际 LLM 驱动 |
|
||||
|
||||
### P1 — 功能失效/核心断链(15 项)
|
||||
|
||||
| ID | 模块 | 问题 | 文件 |
|
||||
|----|------|------|------|
|
||||
| M2-01 | M2 | KernelClient createClone 只传 3 字段,丢失 7 个人格字段 | `kernel-agent.ts:74-97` |
|
||||
| M2-02 | M2 | 两条通路创建逻辑严重不对等 | `gateway-api.ts` vs `kernel-agent.ts` |
|
||||
| M3-01 | M3 | hand_execute 丢弃 run_id | `hand.rs:184` |
|
||||
| M3-02 | M3 | Browser Hand 双路径断裂 | `browser.rs:191-343` |
|
||||
| M3-03 | M3 | browserHandStore 绕过审批流程 | `browserHandStore.ts:222-339` |
|
||||
| M3-04 | M3 | max_concurrent 未实现 | `kernel/hands.rs` |
|
||||
| M3-05 | M3 | timeout_secs 未实现 | `hand.rs:47` |
|
||||
| M4-03 | M4 | 心跳不自动启动 | `heartbeat.rs` |
|
||||
| M4-04 | M4 | 自主授权后端无强制 | `autonomy-manager.ts` |
|
||||
| M4-05 | M4 | 前端记忆搜索用 LIKE 非 FTS5 | `persistent.rs` |
|
||||
| M5-01 | M5 | skill-discovery 将 tags 误映射为 triggers | `skill-discovery.ts:110-123` |
|
||||
| M6-01 | M6 | route_intent Tauri 命令未注册 | `intent.rs` / `IntentInput.tsx` |
|
||||
| M6-02 | M6 | pipeline_list 只用 v1 解析器,v2 被丢弃 | `discovery.rs:59` |
|
||||
| M7-02 | M7 | ConfigMigrationWizard PUT 路径参数语义错误 | `ConfigMigrationWizard.tsx:118` |
|
||||
| M7-04 | M7 | refreshToken 未传 body,Tauri 可能无 cookie | `saas-client.ts:66` |
|
||||
| M11-01 | M11 | blocking_lock() 在 async 中可能死锁 | `generate.rs:141-144` |
|
||||
| M11-02 | M11 | Stage 0/1 LLM 无 map_err | `generate.rs:158-175` |
|
||||
| M11-03 | M11 | 课堂数据仅内存,重启丢失 | `generate.rs:190-213` |
|
||||
|
||||
---
|
||||
|
||||
## 3. 断链模式分析
|
||||
|
||||
### 3.1 "写了没接"型断链(前端代码存在但后端未消费)
|
||||
|
||||
| 断链 | 模块 | 影响 |
|
||||
|------|------|------|
|
||||
| hand-execution-complete 事件前端无人监听 | M3 | Hand 执行结果不自动更新 UI |
|
||||
| classroom_list / classroom_generation_progress | M11 | 课堂历史列表和进度查询功能空置 |
|
||||
| TOML permissions/rate_limit/max_concurrent 配置 | M3 | 9 个 TOML 中丰富的安全和限流配置形同虚设 |
|
||||
| 反思引擎 LLM 路径 | M4 | Tauri 命令层永远传 None |
|
||||
|
||||
### 3.2 "接了不对"型断链(两端参数/类型不匹配)
|
||||
|
||||
| 断链 | 模块 | 影响 |
|
||||
|------|------|------|
|
||||
| hand_execute 返回值类型不匹配 | M3 | 前端拿不到 runId |
|
||||
| skill-discovery tags→triggers 映射错误 | M5 | 所有技能的触发词数据错误 |
|
||||
| pipeline inputs 映射为 steps | M6 | WorkflowBuilder 展示虚假步骤数据 |
|
||||
| createClone 仅传 3 字段 | M2 | 人格/工作空间配置丢失 |
|
||||
|
||||
### 3.3 "双实现未统一"型问题
|
||||
|
||||
| 问题 | 模块 | 影响 |
|
||||
|------|------|------|
|
||||
| PersistentMemoryStore vs SqliteStorage | M4 | 双数据库数据不共享 |
|
||||
| hand_approve vs approval_respond | M3 | 重复审批逻辑 |
|
||||
| BrowserHand Rust vs browserHandStore 前端 | M3 | 两条完全独立的浏览器操作路径 |
|
||||
| Tauri 压缩 vs Runtime 压缩 | M4 | 两套 CompactionConfig 默认值不同 |
|
||||
| WhiteboardCanvas vs SceneRenderer 内联 SVG | M11 | 两套白板渲染实现 |
|
||||
|
||||
---
|
||||
|
||||
## 4. 按模块类型统计
|
||||
|
||||
### 安全相关(跨模块)
|
||||
|
||||
| 问题 | 涉及模块 | 优先级 |
|
||||
|------|---------|--------|
|
||||
| Gemini API Key URL 泄漏 | M1 | P2 |
|
||||
| master key 明文 localStorage | M9 | P2 |
|
||||
| TOTP QR 通过外部服务生成 | M7 | P2 |
|
||||
| ToolOutputGuard 只 warn 不 block | M1 | P2 |
|
||||
| browserHandStore 绕过审批 | M3 | P1 |
|
||||
| 自主授权后端无强制 | M4 | P1 |
|
||||
|
||||
### 状态管理相关
|
||||
|
||||
| 问题 | 涉及模块 |
|
||||
|------|---------|
|
||||
| 共享 isLoading(非操作级) | M2 |
|
||||
| Agent 切换不取消流 | M2 |
|
||||
| hand-execution-complete 无人接收 | M3 |
|
||||
| 心跳不自动启动 | M4 |
|
||||
| 课堂数据无持久化 | M11 |
|
||||
|
||||
### 参数/类型一致性相关
|
||||
|
||||
| 问题 | 涉及模块 |
|
||||
|------|---------|
|
||||
| 前端 password 6 vs 后端 8 | M7 |
|
||||
| types 数组 vs 单值 | M4 |
|
||||
| v1 `{{}}` vs `${}` 混用 | M6 |
|
||||
| WorkflowDetail 映射语义错误 | M6 |
|
||||
|
||||
---
|
||||
|
||||
## 5. 修复优先级路线图
|
||||
|
||||
### 第一阶段:P0 立即修复(预计 2-3 天)
|
||||
|
||||
1. **[M4-01]** 统一记忆存储层 — 让前端 memory_search 也查询 SqliteStorage
|
||||
2. **[M4-02]** 反思引擎接入 LLM — reflection_reflect 传入实际 driver
|
||||
|
||||
### 第二阶段:P1 核心功能修复(预计 5-7 天)
|
||||
|
||||
3. **[M2-01/02]** 扩展 kernel-agent.ts createClone 字段 + 统一双通路
|
||||
4. **[M3-01]** hand_execute 返回 run_id
|
||||
5. **[M3-05]** 实现 timeout_secs 超时保护
|
||||
6. **[M3-04]** 实现 max_concurrent 并发限制
|
||||
7. **[M3-03]** browserHandStore 集成审批流程
|
||||
8. **[M5-01]** 修正 skill-discovery triggers 映射
|
||||
9. **[M6-01]** 注册 route_intent Tauri 命令
|
||||
10. **[M6-02]** pipeline_list 支持 v2 格式
|
||||
11. **[M4-03]** 自动启动心跳引擎
|
||||
12. **[M4-05]** 前端记忆搜索升级 FTS5
|
||||
13. **[M11-01]** 修复 blocking_lock 死锁风险
|
||||
14. **[M11-03]** 课堂数据持久化
|
||||
|
||||
### 第三阶段:P2 健壮性提升(预计 5-7 天)
|
||||
|
||||
- M1: Gemini Key URL → header, ToolOutputGuard Block, Mutex unwrap
|
||||
- M2: 参数验证、Agent 切换联动、SQLite 外键确认
|
||||
- M3: 注册全局事件监听、审批 TTL、统一审批路径
|
||||
- M4: interval 验证、identity 加密、自主映射修正
|
||||
- M7: 密码校验统一、master key 安全、TOTP 本地 QR
|
||||
- M8: 权限动态获取、Relay retry、API Key admin 端点
|
||||
- M11: placeholder 标志、ID 冲突、导出丰富
|
||||
|
||||
---
|
||||
|
||||
## 6. 对 TRUTH.md 的更新建议
|
||||
|
||||
审计中发现的数字偏差:
|
||||
|
||||
| 条目 | TRUTH.md 当前值 | 审计实际值 | 说明 |
|
||||
|------|----------------|----------|------|
|
||||
| Tauri 命令无前端调用 | 24 | 需重新统计 | classroom_list/generation_progress 等新增 @reserved |
|
||||
| 75 个 SKILL.md | 75 | 75 ✅ | 全部可解析,但 tools 字段未消费 |
|
||||
| 11 个 Hand | 9 启用 + 2 禁用 | 9 启用,TOML 中无 enabled=false | 2 个禁用 Hand 未找到 TOML 或 Rust 实现 |
|
||||
| 5 个 Pipeline 模板 | 5 | 17 个 YAML 文件 | pipelines/ 目录有更多模板 |
|
||||
| Desktop 前端测试 | 0 | 0 ✅ | 仍未解决 |
|
||||
|
||||
---
|
||||
|
||||
## 7. 审计方法总结
|
||||
|
||||
本审计采用**混合矩阵式**方案:
|
||||
- **主轴**: 11 个功能模块(M1-M11)
|
||||
- **检查模板**: 五维检查(链路完整性/参数一致性/边界错误/状态管理/安全资源)
|
||||
- **断链检测**: Tauri 命令调用矩阵 + 参数签名比对 + 事件链路追踪 + DB-API-UI 三端对齐
|
||||
- **验证深度**: 60% 静态分析 + 30% 代码推理 + 10% 实机验证(M1/M3 加强至 20-30%)
|
||||
|
||||
相比前 14 轮审计的创新:
|
||||
1. 首次以功能领域为主轴追踪完整调用链
|
||||
2. 首次系统验证参数/类型一致性(发现了 4 处前端参数不匹配)
|
||||
3. 首次验证边界场景(错误传播、空状态、并发)
|
||||
4. 建立了模块级健康度基线,未来审计可增量更新
|
||||
129
docs/archive/old-audits/QA_REVIEW_V1.md
Normal file
@@ -0,0 +1,129 @@
|
||||
# ZCLAW 全栈 QA 与代码审查报告
|
||||
|
||||
> 日期: 2026-03-31 ~ 2026-04-01
|
||||
> 审查方法: 模块垂直扫描 (4 Tracks) + 后续测试补充 + 大文件拆分
|
||||
> 审查范围: Rust 后端 + Admin V2 前端 + Desktop 前端 + 配置/部署
|
||||
|
||||
---
|
||||
|
||||
## 1. 审查发现与修复汇总
|
||||
|
||||
### 1.1 已修复问题
|
||||
|
||||
| # | 问题 | 严重级 | 模块 | 状态 |
|
||||
|---|------|--------|------|------|
|
||||
| 1 | `relay_enqueue()` 重复调用 (探索阶段报告) | P0 | SaaS 后端 | **误报** — 实际只有一次调用 |
|
||||
| 2 | 密码策略无复杂度要求 | P2 | SaaS 后端 | **已修复** — 大写+小写+数字验证 |
|
||||
| 3 | JWT 缺少 `aud` (受众) claim | P3 | SaaS 后端 | **已修复** — `aud: "zclaw-saas"` + 验证 |
|
||||
| 4 | JWT 缺少 `pwv` (密码版本) | P1 | SaaS 后端 | **已修复** — 用户修改 |
|
||||
| 5 | 17 处 `println!`/`eprintln!` 生产代码 | P1 | Rust crates | **已修复** — 全部替换为 `tracing::*` |
|
||||
| 6 | Desktop 49 处 `any` 用法 | P1 | Desktop | **已修复** — gateway-api-types.ts 类型化 |
|
||||
| 7 | Desktop 80+ 裸 `console.*` 调用 | P1 | Desktop | **已修复** — 26 处替换为 logger |
|
||||
| 8 | Desktop tsconfig 排除 ErrorBoundary/ErrorAlert | P2 | Desktop | **已修复** — 修复类型错误后移除排除 |
|
||||
| 9 | Docker Compose 默认密码 + 端口暴露 | P2 | 部署 | **已修复** — 用户进一步加固 |
|
||||
| 10 | 缺少 `.dockerignore` | P3 | 部署 | **已修复** |
|
||||
| 11 | Admin V2 测试覆盖不足 (3/10 页面) | P1 | Admin V2 | **已修复** — 71 个测试全部通过 |
|
||||
|
||||
### 1.2 确认良好的方面
|
||||
|
||||
| 模块 | 良好实践 |
|
||||
|------|----------|
|
||||
| Admin V2 | 零 `any` 用法、无 `dangerouslySetInnerHTML`、ErrorBoundary 完善 |
|
||||
| SaaS 后端 | Argon2id 密码哈希、AES-256-GCM 加密、参数化 SQL、SSRF 防护完善 |
|
||||
| 认证系统 | HttpOnly + Secure + SameSite=Strict Cookie、refresh token 轮换、pwv 密码版本追踪 |
|
||||
| RBAC | `admin:full` 超级权限、IDOR 防护、权限缓存 |
|
||||
|
||||
---
|
||||
|
||||
## 2. 后续工作完成情况
|
||||
|
||||
### 2.1 Admin V2 测试补充 (71 个测试,12 个测试文件)
|
||||
|
||||
| 测试文件 | 测试数 | 覆盖内容 |
|
||||
|----------|--------|----------|
|
||||
| `Accounts.test.tsx` | 已有 | 账号 CRUD |
|
||||
| `AgentTemplates.test.tsx` | 已有 | 模板管理 |
|
||||
| `authStore.test.ts` | 已有 | 认证状态 |
|
||||
| `request.test.ts` | 已有 | HTTP 客户端 |
|
||||
| `Dashboard.test.tsx` | 8 新增 | 统计数据 + 日志展示 |
|
||||
| `Login.test.tsx` | 7 新增 | 登录 + TOTP + 错误处理 |
|
||||
| `Config.test.tsx` | 7 新增 | 配置项 + 分类标签页 |
|
||||
| `Logs.test.tsx` | 7 新增 | 日志分页 + 筛选 + ErrorState |
|
||||
| `Relay.test.tsx` | 7 新增 | 中转任务 + 状态标签 |
|
||||
| `Usage.test.tsx` | 6 新增 | 统计卡片 + 每日/模型表 |
|
||||
| `Prompts.test.tsx` | 5 新增 | 提示词模板 + CRUD |
|
||||
| `ModelServices.test.tsx` | 5 新增 | 供应商列表 + 状态标签 |
|
||||
|
||||
### 2.2 大文件拆分
|
||||
|
||||
| 文件 | 原始行数 | 拆分结果 | 状态 |
|
||||
|------|----------|----------|------|
|
||||
| `kernel.rs` | 1486 | 9 个子模块 (mod.rs + adapters/agents/messaging/skills/hands/triggers/approvals/a2a) | **完成** |
|
||||
| `intelligence-client.ts` | 1475 | 9 个子模块 (index/types/type-conversions/unified-client + 5 个 fallback) | **完成** |
|
||||
| `db.rs` | 891 | 保持原样 (拆分风险大于收益) | **跳过** |
|
||||
|
||||
### 2.3 kernel.rs 拆分详情
|
||||
|
||||
```
|
||||
kernel/
|
||||
├── mod.rs (~200L) — Kernel struct + boot + 中间件 + 访问器
|
||||
├── adapters.rs (~95L) — LlmDriverAdapter + KernelSkillExecutor + AgentInbox
|
||||
├── agents.rs (~100L) — Agent CRUD
|
||||
├── messaging.rs (~150L) — 消息发送 + 技能提示构建
|
||||
├── skills.rs (~70L) — 技能管理
|
||||
├── hands.rs (~200L) — Hand 执行 + 运行追踪
|
||||
├── triggers.rs (~45L) — 触发器 CRUD
|
||||
├── approvals.rs (~140L) — 审批管理
|
||||
└── a2a.rs (~265L) — A2A 多智能体 (cfg multi-agent)
|
||||
```
|
||||
|
||||
### 2.4 intelligence-client.ts 拆分详情
|
||||
|
||||
```
|
||||
intelligence-client/
|
||||
├── index.ts (~65L) — 统一重导出
|
||||
├── types.ts (~175L) — 前端类型 + Mesh + Persona Evolver
|
||||
├── type-conversions.ts (~95L) — 前后端类型转换
|
||||
├── unified-client.ts (~440L) — 主 intelligenceClient 对象
|
||||
├── fallback-memory.ts (~165L) — localStorage 内存回退
|
||||
├── fallback-compactor.ts (~60L) — 压缩回退
|
||||
├── fallback-reflection.ts (~165L) — 反思回退
|
||||
├── fallback-identity.ts (~235L) — 身份管理回退
|
||||
└── fallback-heartbeat.ts (~55L) — 心跳回退
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. 验证结果
|
||||
|
||||
| 检查项 | 结果 |
|
||||
|--------|------|
|
||||
| `cargo check -p zclaw-saas` | **通过** |
|
||||
| `cargo check -p zclaw-kernel` | **通过** (runtime 有预存类型问题) |
|
||||
| `cargo test -p zclaw-saas --lib -- jwt` | **6/6 通过** (含 aud + pwv 测试) |
|
||||
| Desktop `tsc --noEmit` | **通过** (0 errors) |
|
||||
| Admin V2 `tsc --noEmit` | **通过** (0 errors) |
|
||||
| Admin V2 `vitest run` | **71/71 通过** (12 个测试文件) |
|
||||
|
||||
---
|
||||
|
||||
## 4. 遗留项与后续建议
|
||||
|
||||
### 4.1 db.rs 拆分 (891L)
|
||||
|
||||
保持原样。原因:
|
||||
- `init_db()` 是唯一的公共入口,所有 seed/migration 函数都是内部实现
|
||||
- 函数间有较强耦合(migration 调用 seed_roles,init_db 编排所有步骤)
|
||||
- 拆分收益有限(不像 kernel.rs 有多个独立领域)
|
||||
|
||||
### 4.2 安全增强建议
|
||||
|
||||
- Docker Compose 生产部署时考虑 Redis-backed 分布式限流
|
||||
- 考虑将邮箱验证改为使用 email 验证库
|
||||
- 生产环境日志写入 WAF
|
||||
|
||||
### 4.3 代码质量持续改进
|
||||
|
||||
- Desktop 仍有约 50 处裸 `console.*` 调用在非重点文件中
|
||||
- `zclaw-runtime` 有预存的 `Message` enum 类型错误需修复
|
||||
- Admin V2 coverage thresholds 已设置 (60%),持续补充测试达到目标
|
||||
329
docs/archive/old-audits/SECONDARY_AUDIT_V11.md
Normal file
@@ -0,0 +1,329 @@
|
||||
# ZCLAW 深度二次审计补充报告
|
||||
|
||||
> **审计日期**: 2026-04-02
|
||||
> **基线**: V11 全面审计报告(22 项发现)
|
||||
> **方法**: 5 维并行深度审计
|
||||
> **新增发现**: 22 项(2 P0 + 9 P1 + 10 P2 + 3 P3 + 1 确认项)
|
||||
|
||||
---
|
||||
|
||||
## 1. 审计维度
|
||||
|
||||
| # | 维度 | 发现数 |
|
||||
|---|------|--------|
|
||||
| 1 | Rust crate 交叉依赖 + 编译状态 | 5 |
|
||||
| 2 | 前端 Store ↔ Tauri 命令参数签名全量比对 | 5 |
|
||||
| 3 | Sprint 1-4 修复代码质量验证 | 1 |
|
||||
| 4 | 安全/竞态/资源泄漏扫描 | 9 |
|
||||
| 5 | 测试覆盖缺口 + admin-v2 API 对齐 | 4 |
|
||||
|
||||
---
|
||||
|
||||
## 2. 新增 P0 发现(2 项)
|
||||
|
||||
### SEC2-P0-01: skill_execute 反序列化崩溃
|
||||
|
||||
| 维度 | 详情 |
|
||||
|------|------|
|
||||
| **问题** | 前端传递空 `context: {}`,但 Rust `SkillContext` 要求 `agent_id: String` 和 `session_id: String`(非 Option)。空 JSON 无法反序列化。 |
|
||||
| **前端** | `desktop/src/lib/kernel-skills.ts:110-114` |
|
||||
| **Rust** | `desktop/src-tauri/src/kernel_commands/skill.rs:290-296` |
|
||||
| **触发条件** | 用户在前端执行任何 Skill |
|
||||
| **影响** | 运行时 serde 反序列化失败,Skill 执行必然报错 |
|
||||
|
||||
### SEC2-P0-02: TaskTool::default() 潜在 panic
|
||||
|
||||
| 维度 | 详情 |
|
||||
|------|------|
|
||||
| **问题** | `TaskTool` 实现了 `Default` trait,但 `default()` 调用 `unimplemented!()` |
|
||||
| **文件** | `crates/zclaw-runtime/src/tool/builtin/task.rs:59` |
|
||||
| **触发条件** | 任何泛型约束 `T: Default` 触发 `TaskTool::default()` 时 |
|
||||
| **影响** | 运行时 panic(虽然正常路径使用 `TaskTool::new()` 规避) |
|
||||
| **建议** | 移除 `impl Default for TaskTool`,或提供合理的默认值 |
|
||||
|
||||
---
|
||||
|
||||
## 3. 新增 P1 发现(9 项)
|
||||
|
||||
### SEC2-P1-01: FactStore trait 零实现
|
||||
|
||||
| 维度 | 详情 |
|
||||
|------|------|
|
||||
| **问题** | `FactStore` trait 在 `zclaw-memory/src/fact.rs:141` 定义,全 workspace 无任何 `impl FactStore for T`。`MemoryStore` 有同名方法但未实现 trait。`dyn FactStore` 模式完全不可用。 |
|
||||
| **文件** | `crates/zclaw-memory/src/fact.rs` |
|
||||
| **影响** | 架构层面功能缺口——trait 接口已定义但无法使用 |
|
||||
|
||||
### SEC2-P1-02: agent-templates API 路径缺少 /api/v1 前缀
|
||||
|
||||
| 维度 | 详情 |
|
||||
|------|------|
|
||||
| **问题** | 前端 saas-client.ts 中 agent-templates 路径缺少 `/api/v1` 前缀 |
|
||||
| **前端** | `desktop/src/lib/saas-client.ts:376,384`:`'/agent-templates/available'`、`'/agent-templates/${id}/full'` |
|
||||
| **后端** | 路由注册在 `/api/v1/agent-templates/...` |
|
||||
| **影响** | 请求发送到错误 URL,必然返回 404 |
|
||||
|
||||
### SEC2-P1-03: hand-execution-complete 事件无前端监听
|
||||
|
||||
| 维度 | 详情 |
|
||||
|------|------|
|
||||
| **问题** | Rust 在 `hand.rs:279` 和 `approval.rs:130` emit `hand-execution-complete`,但前端无任何 `listen()` 调用 |
|
||||
| **影响** | Hand 异步执行完成后,前端无法收到通知,用户不知道执行结果 |
|
||||
|
||||
### SEC2-P1-04: InMemoryStorage RwLock unwrap() 级联 panic 风险
|
||||
|
||||
| 维度 | 详情 |
|
||||
|------|------|
|
||||
| **问题** | `InMemoryStorage` 中 6 处 `std::sync::RwLock` 的 `.unwrap()`。若锁被 poisoned(某线程 panic),后续所有调用级联崩溃 |
|
||||
| **文件** | `crates/zclaw-growth/src/viking_adapter.rs:137,143,148,190,202,208,214` |
|
||||
| **风险** | 低概率但后果严重 |
|
||||
|
||||
### SEC2-P1-05: HandRun 持久化错误静默忽略(3 处)
|
||||
|
||||
| 维度 | 详情 |
|
||||
|------|------|
|
||||
| **问题** | `let _ = memory.save_hand_run(&run).await` 等 3 处 HandRun 持久化错误被忽略 |
|
||||
| **文件** | `crates/zclaw-kernel/src/kernel/approvals.rs:88,91,120` |
|
||||
| **影响** | DB 不可用时 run 状态丢失,UI 无法显示执行结果 |
|
||||
| **建议** | 至少 log warning |
|
||||
|
||||
### SEC2-P1-06: FTS 索引更新失败静默忽略(3 处)
|
||||
|
||||
| 维度 | 详情 |
|
||||
|------|------|
|
||||
| **问题** | 全文搜索索引 DELETE/INSERT 操作失败被 `let _ =` 忽略 |
|
||||
| **文件** | `crates/zclaw-growth/src/storage/sqlite.rs:384,390,605` |
|
||||
| **影响** | 搜索结果不一致(stale index) |
|
||||
|
||||
### SEC2-P1-07: Worker dispatch 失败静默忽略(4 处)
|
||||
|
||||
| 维度 | 详情 |
|
||||
|------|------|
|
||||
| **问题** | `let _ = state.worker_dispatcher.dispatch(...)` 4 处忽略 |
|
||||
| **文件** | `crates/zclaw-saas/src/knowledge/handlers.rs:220,262,331,539` |
|
||||
| **影响** | embedding 生成等后台任务可能静默丢失 |
|
||||
|
||||
### SEC2-P1-08: Desktop 前端零测试
|
||||
|
||||
| 维度 | 详情 |
|
||||
|------|------|
|
||||
| **问题** | `desktop/src/` 中零个 `.test.ts`/`.test.tsx` 文件,包括 chatStore、agentStore 等核心 store |
|
||||
| **影响** | 前端任何回归只能通过手工测试发现 |
|
||||
|
||||
### SEC2-P1-09: record_key_usage 错误忽略导致计费数据丢失风险
|
||||
|
||||
| 维度 | 详情 |
|
||||
|------|------|
|
||||
| **问题** | `let _ = record_key_usage(...)` 忽略写入错误 |
|
||||
| **文件** | `crates/zclaw-saas/src/relay/service.rs:376` |
|
||||
| **影响** | 可能导致计费数据丢失 |
|
||||
|
||||
---
|
||||
|
||||
## 4. 新增 P2 发现(10 项)
|
||||
|
||||
| ID | 问题 | 文件 |
|
||||
|----|------|------|
|
||||
| SEC2-P2-01 | `hmac`/`sha1` 在 zclaw-hands Cargo.toml 中声明但代码零引用 | `crates/zclaw-hands/Cargo.toml` |
|
||||
| SEC2-P2-02 | `serde_yaml` 版本不一致:desktop 用 0.9,pipeline 用 2(不同 package) | 各 `Cargo.toml` |
|
||||
| SEC2-P2-03 | `sqlx-postgres v0.7.4` 使用了未来 Rust 版本将拒绝的语法 | `Cargo.lock` |
|
||||
| SEC2-P2-04 | `generate_embedding.rs:107` embedding 生成被注释掉(`// TODO`) | `crates/zclaw-saas/src/workers/generate_embedding.rs` |
|
||||
| SEC2-P2-05 | ~10 处 `tokio::spawn` 返回 JoinHandle 未绑定,无法优雅停止 | kernel + saas 多处 |
|
||||
| SEC2-P2-06 | Telemetry 审计日志批量 INSERT 绑定可能与 SQL 模板不匹配 | `crates/zclaw-saas/src/telemetry/service.rs:205-213` |
|
||||
| SEC2-P2-07 | Scheduler 串行执行 trigger,长 hand 阻塞后续调度 | `crates/zclaw-kernel/src/scheduler.rs:117-153` |
|
||||
| SEC2-P2-08 | `format!("FROM {}", table)` 模式虽当前安全(硬编码),但违反防御原则 | `crates/zclaw-saas/src/db.rs:874,880` |
|
||||
| SEC2-P2-09 | `hand_run_status` 前端传递多余 `handName` 参数(Rust 只接收 `run_id`) | `desktop/src/lib/kernel-hands.ts:95` |
|
||||
| SEC2-P2-10 | `kernel_apply_saas_config` TOML 写入不支持多行值 | `desktop/src-tauri/src/kernel_commands/lifecycle.rs` |
|
||||
|
||||
---
|
||||
|
||||
## 5. 新增 P3 发现(3 项)
|
||||
|
||||
| ID | 问题 | 文件 |
|
||||
|----|------|------|
|
||||
| SEC2-P3-01 | A2A Router 4 个 RwLock 获取顺序未文档化 | `crates/zclaw-protocols/src/a2a.rs:239-245` |
|
||||
| SEC2-P3-02 | Admin-v2 Role 类型:后端 `is_system` 字段前端未映射,前端 `account_count` 后端无字段 | `admin-v2/src/types/index.ts` vs `role/types.rs` |
|
||||
| SEC2-P3-03 | Admin-v2 Billing/Knowledge/Roles 三个页面缺测试(Billing、Knowledge 页面 + Roles 新页面) | `admin-v2/tests/` |
|
||||
|
||||
---
|
||||
|
||||
## 6. 确认项(审计验证结果)
|
||||
|
||||
### 6.1 编译状态
|
||||
|
||||
- `cargo check --workspace` **编译成功**(33.60s)
|
||||
- 2 个 warning:`RegisterDeviceRequest` 可见性(P2)、`sqlx-postgres` 未来兼容性(P1)
|
||||
|
||||
### 6.2 Sprint 1-4 修复验证
|
||||
|
||||
| 修复 | 验证结果 |
|
||||
|------|---------|
|
||||
| trigger_update 参数扁平化 | **通过** — 前后端参数完全匹配 |
|
||||
| SaaS config sync 传播 | **通过** — kernel_apply_saas_config 正确桥接 |
|
||||
| Deprecated 代码清理 | **通过** — 无残留引用 |
|
||||
| Admin Roles 页面 | **通过** — API 路径与 SaaS 路由匹配 |
|
||||
| ToolDefinition 去重 | **通过** — 使用 pub use |
|
||||
| Knowledge handler 修复 | **通过** — 连接到 service 层 |
|
||||
| Task 结果持久化 | **通过** — migration + 读写一致 |
|
||||
|
||||
### 6.3 Admin-v2 ↔ SaaS API 对齐
|
||||
|
||||
**结论:100% 对齐。** 所有 admin-v2 前端调用的 API 端点在后端都有对应路由注册,包括:
|
||||
- 9 个 knowledge 路径(categories/items/analytics/search/recommend/import/versions/rollback/batch)
|
||||
- 5 个 role 路径 + 5 个 permission-template 路径
|
||||
- 6 个 billing 路径
|
||||
- 2 个 telemetry 路径
|
||||
|
||||
### 6.4 Feature Gate 一致性
|
||||
|
||||
传播链完全正确:
|
||||
```
|
||||
desktop --multi-agent--> zclaw-kernel --multi-agent--> zclaw-protocols --a2a--> [a2a module]
|
||||
zclaw-skills --wasm--> [wasmtime, wasmtime-wasi]
|
||||
```
|
||||
|
||||
### 6.5 认证覆盖
|
||||
|
||||
SaaS 后端三层路由分离无遗漏:公共路由 + 受保护路由 + Relay 独立中间件链。
|
||||
|
||||
---
|
||||
|
||||
## 7. 测试覆盖统计
|
||||
|
||||
### 7.1 Rust 测试分布
|
||||
|
||||
| Crate | 测试数 | 关键缺口 |
|
||||
|-------|--------|----------|
|
||||
| zclaw-hands | 155 | - |
|
||||
| zclaw-saas | 92 | 集中在工具函数,handler/scheduler 0 测试 |
|
||||
| zclaw-growth | 75 | - |
|
||||
| zclaw-pipeline | 59 | - |
|
||||
| zclaw-types | 57 | - |
|
||||
| zclaw-kernel | 52 | capabilities/registry/trigger_manager 0 测试 |
|
||||
| zclaw-runtime | 42 | - |
|
||||
| zclaw-memory | 25 | - |
|
||||
| zclaw-skills | 22 | - |
|
||||
| zclaw-protocols | 5 | 极低 |
|
||||
| **总计** | **584** | |
|
||||
|
||||
### 7.2 零测试关键模块
|
||||
|
||||
| 模块 | 公开函数数 | 严重度 |
|
||||
|------|-----------|--------|
|
||||
| kernel_commands/ (41 Tauri 命令) | 41 | P0 |
|
||||
| browser/commands.rs (23 命令) | 23 | P0 |
|
||||
| SaaS scheduler.rs | 3 公开函数 | P1 |
|
||||
| SaaS knowledge/handlers.rs (561 行) | ~15 | P1 |
|
||||
| SaaS relay/service.rs | ~20 | P1 |
|
||||
| SaaS billing/ | ~10 | P1 |
|
||||
| Desktop frontend | 全部 | P1 |
|
||||
|
||||
### 7.3 Admin-v2 测试
|
||||
|
||||
- **测试框架**: Vitest + jsdom + MSW
|
||||
- **测试用例**: 322 个
|
||||
- **覆盖页面**: 10/13(缺失 Billing、Knowledge、Roles)
|
||||
- **覆盖 service**: 1/17(仅 request.ts)
|
||||
|
||||
---
|
||||
|
||||
## 8. 积极发现
|
||||
|
||||
1. **SQL 参数化规范**:SaaS 层绝大多数 SQL 使用 `sqlx::query(...).bind(...)` 参数化
|
||||
2. **密钥保护**:JWT secret 使用 `secrecy::SecretString`,API key 日志仅输出 ID
|
||||
3. **DashMap 死锁已规避**:所有 DashMap RefMut 在 `.await` 前释放
|
||||
4. **SSE 背压设计**:有界 channel + 信号量限制 + CancellationToken
|
||||
5. **密码版本控制**:password_version 确保 JWT 失效
|
||||
6. **MCP Transport**:实现 Drop trait 清理子进程
|
||||
7. **DB 连接池监控**:30s 周期日志 + 80% 告警
|
||||
8. **Admin-v2 API 对齐**:所有前端调用都有后端路由对应
|
||||
|
||||
---
|
||||
|
||||
## 9. 综合风险矩阵(V11 + 二次审计合并)
|
||||
|
||||
| 严重度 | V11 原始 | 二次审计新增 | 合计 |
|
||||
|--------|----------|-------------|------|
|
||||
| P0 | 1 (误报) | **2** | 2 |
|
||||
| P1 | 3 | **9** | 12 |
|
||||
| P2 | 6 | **10** | 16 |
|
||||
| P3 | 8 | **3** | 11 |
|
||||
| P4 | 5 | 0 | 5 |
|
||||
| **总计** | **23** | **24** | **46** |
|
||||
|
||||
---
|
||||
|
||||
## 10. 支付安全深度审计 V3(2026-04-02)
|
||||
|
||||
> **审计范围**: `crates/zclaw-saas/src/billing/` 全部文件(payment.rs, service.rs, handlers.rs, types.rs, mod.rs)
|
||||
> **审计方法**: 3 维并行(Security Engineer + Code Reviewer + Senior Developer)
|
||||
> **基线**: V2 审计后的 25 项修复全部落地
|
||||
|
||||
### 10.1 审计结论
|
||||
|
||||
| 指标 | 结果 |
|
||||
|------|------|
|
||||
| **CRITICAL** | **0** |
|
||||
| **HIGH** | **0** |
|
||||
| **MEDIUM** | **1**(已修复) |
|
||||
| **LOW** | **3**(pre-existing / cosmetic) |
|
||||
|
||||
### 10.2 已修复项(本次修复)
|
||||
|
||||
| ID | 严重度 | 问题 | 修复 |
|
||||
|----|--------|------|------|
|
||||
| PAY-FIX-01 | MEDIUM | `truncate_str` 使用 `s.len()`(字节数)判断是否截断,但 `chars().take()` 按字符截断。中文等多字节字符串在 200 字节内但超过 200 字符时截断错误 | 改为先 `chars().collect::<Vec<char>>()` 再按 `.len()` 判断字符数 |
|
||||
|
||||
### 10.3 已验证通过的关键安全措施(25 项)
|
||||
|
||||
#### 事务与竞态保护(6 项)
|
||||
- [x] `create_payment` 在事务中创建 invoice + payment(原子性)
|
||||
- [x] `handle_payment_callback` 使用 `SELECT ... FOR UPDATE` 锁定行(防 TOCTOU)
|
||||
- [x] `get_or_create_usage` 使用 `INSERT ON CONFLICT DO NOTHING`(防重复创建)
|
||||
- [x] 金额交叉验证:生产环境 `callback_amount` 为 None 时拒绝
|
||||
- [x] 幂等保护:已处理的 payment(status != pending)直接返回
|
||||
- [x] 事务失败时正确 rollback
|
||||
|
||||
#### 支付回调安全(6 项)
|
||||
- [x] Alipay 验签:生产环境强制 RSA2 验签,缺公钥拒绝
|
||||
- [x] WeChat 解密:AES-256-GCM + nonce 长度校验(12 字节)
|
||||
- [x] trade_no 缺失时返回错误而非静默忽略
|
||||
- [x] 日志安全:`sanitize_log` 只保留字母数字和 `-` `_`
|
||||
- [x] 通用错误对外返回(不泄露内部细节)
|
||||
- [x] 回调路由正确分离到 public_routes(无需认证)
|
||||
|
||||
#### 密钥保护(4 项)
|
||||
- [x] `PaymentConfig` 自定义 Debug impl,敏感字段显示 `***REDACTED***`
|
||||
- [x] `alipay_private_key`、`alipay_public_key`、`wechat_api_v3_key` 标记 `skip_serializing`
|
||||
- [x] JWT 密钥使用 `secrecy::SecretString`
|
||||
- [x] API key 日志仅输出 ID 不输出值
|
||||
|
||||
#### 货币精度(2 项)
|
||||
- [x] 分→元转换使用整数运算(`amount_cents / 100` + `amount_cents % 100`)
|
||||
- [x] WeChat 金额保持整数分(无浮点转换)
|
||||
|
||||
#### HTML 安全(2 项)
|
||||
- [x] Mock 支付页面使用 `html_escape()` 转义用户输入
|
||||
- [x] Mock 确认页面的 `msg` 变量由服务端控制(安全)
|
||||
|
||||
#### SQL 安全(3 项)
|
||||
- [x] 所有 SQL 使用参数化查询(`sqlx::query(...).bind(...)`)
|
||||
- [x] `increment_dimension` 使用白名单分支(非动态列名)
|
||||
- [x] `failure_reason` 截断到 200 字符
|
||||
|
||||
#### 整体架构(2 项)
|
||||
- [x] 路由分离:`routes()` 需认证,`callback_routes()` 公开
|
||||
- [x] 批量递增 `increment_dimension_by` 替代循环查询
|
||||
|
||||
### 10.4 剩余 LOW 项(不影响安全,可后续优化)
|
||||
|
||||
| ID | 说明 | 建议 |
|
||||
|----|------|------|
|
||||
| PAY-LOW-01 | `reqwest::Client::new()` 每次 WeChat 支付创建新实例 | 改为 AppState 中共享 Client |
|
||||
| PAY-LOW-02 | `BootstrapScreen` 缺少 dark mode 变体 | 添加 `dark:bg-gray-900` |
|
||||
| PAY-LOW-03 | `aside.w-64.sidebar-open` class 定义但无 JS 切换逻辑 | 添加汉堡菜单或移除 |
|
||||
|
||||
### 10.5 审计签名
|
||||
|
||||
- **Security Engineer**: 0 CRITICAL, 0 HIGH — 支付链路安全措施完备
|
||||
- **Code Reviewer**: 25 项修复全部正确实现,无回归
|
||||
- **Senior Developer**: 1 MEDIUM 已修复(truncate_str),代码质量良好
|
||||
296
docs/archive/old-audits/V11_GAP_ANALYSIS.md
Normal file
@@ -0,0 +1,296 @@
|
||||
# ZCLAW V11 差距分析报告
|
||||
|
||||
> **生成日期**: 2026-04-02
|
||||
> **审计基线**: V10 AUDIT_TRACKER + V11 全面扫描
|
||||
|
||||
---
|
||||
|
||||
## 1. 五种差距模式总览
|
||||
|
||||
| 模式 | 数量 | 最高严重度 |
|
||||
|------|------|-----------|
|
||||
| 写了没接 | 8 项 | P3 |
|
||||
| 接了没传 | 2 项 | **P1** |
|
||||
| 传了没存 | 2 项 | P3 |
|
||||
| 存了没用 | 3 项 | **P2** |
|
||||
| 双系统不同步 | 5 项 | P3 |
|
||||
|
||||
---
|
||||
|
||||
## 2. 模式 1: "写了没接" (Wrote but Not Connected)
|
||||
|
||||
### 2.1 audit-logger.ts — 170 行完全孤立
|
||||
|
||||
**文件**: `desktop/src/lib/audit-logger.ts`
|
||||
**严重度**: P3
|
||||
|
||||
完整的前端审计日志系统,包含 `FrontendAuditEntry` 类型、`AuditLogger` 类(log/logSuccess/logFailure/getLogs/clearLogs/exportLogs)、导出单例。
|
||||
|
||||
**验证**:
|
||||
```bash
|
||||
grep -rn "from.*audit-logger\|import.*audit-logger" desktop/src/ --include="*.ts" --include="*.tsx"
|
||||
# 结果: 0 匹配
|
||||
```
|
||||
|
||||
**影响**: 审计日志功能完全不可用,用户无法追溯操作历史。
|
||||
|
||||
**建议**:
|
||||
- 方案 A: 在关键组件(ApprovalsPanel, AutonomyConfig, SecurityStore)中接入
|
||||
- 方案 B: 如果当前不需要,标记为 `@internal reserved` 并从 barrel export 中移除
|
||||
|
||||
---
|
||||
|
||||
### 2.2 OFP 能力 — 类型定义无消费者
|
||||
|
||||
**文件**: `crates/zclaw-types/src/capability.rs:28-32`
|
||||
**严重度**: P4
|
||||
|
||||
```rust
|
||||
OfpDiscover,
|
||||
OfpConnect { peer: String },
|
||||
OfpAdvertise,
|
||||
```
|
||||
|
||||
`Capability::grants()` 方法将这些变体匹配到 `_ => false`,意味着它们无法被授予或验证。
|
||||
|
||||
**建议**: 移除或添加 `// Reserved for OpenFang Protocol` 注释。
|
||||
|
||||
---
|
||||
|
||||
### 2.3 Director (multi-agent) — Feature-gated 912 行
|
||||
|
||||
**文件**: `crates/zclaw-kernel/src/director.rs`
|
||||
**严重度**: P4 (保持 V10 DEAD-04)
|
||||
|
||||
22 个 `cfg(feature = "multi-agent")` 条目,完整的 Director 实现(5 种调度策略)。未在 Cargo.toml 中启用。
|
||||
|
||||
**建议**: 延后到产品路线图中多 Agent 功能启动时启用。
|
||||
|
||||
---
|
||||
|
||||
### 2.4 saas-admin.ts — 30 方法零消费者
|
||||
|
||||
**文件**: `desktop/src/lib/saas-admin.ts`
|
||||
**严重度**: P2
|
||||
|
||||
30 个 Admin API 包装方法(providers/models/keys/accounts/tokens/roles/permissions),但:
|
||||
- Desktop 前端不调用这些方法
|
||||
- Admin-v2 有自己的 Axios service 层,不使用 saas-admin.ts
|
||||
|
||||
**文件头注释** (line 7-9):
|
||||
> "Reserved for future admin UI (Next.js admin dashboard)."
|
||||
|
||||
**建议**: 删除整个文件,admin-v2 已有独立实现。避免维护两套代码。
|
||||
|
||||
---
|
||||
|
||||
### 2.5 Feature-gated 代码汇总
|
||||
|
||||
| 特性 | Crate | 代码量 | 状态 |
|
||||
|------|-------|--------|------|
|
||||
| multi-agent | zclaw-kernel | 22 cfg sites | 未启用 |
|
||||
| a2a | zclaw-protocols | 2 cfg sites | 未启用 |
|
||||
| wasm | zclaw-skills | 4 cfg sites | 未启用 |
|
||||
|
||||
---
|
||||
|
||||
### 2.6 62 个 Tauri 命令无前端调用
|
||||
|
||||
**分布**:
|
||||
|
||||
| 模块 | 未调用命令数 | 备注 |
|
||||
|------|-------------|------|
|
||||
| viking_commands | 11 | 完整 Viking 模块无 UI |
|
||||
| pipeline_commands | 11 | 完整 Pipeline 模块无直接 invoke |
|
||||
| gateway::commands | 11 | Gateway 连接管理 |
|
||||
| classroom_commands | 7 (8 中仅 1 个被调用) | Classroom 功能 |
|
||||
| LLM commands | 3 | llm_complete, embedding_create, embedding_providers |
|
||||
| memory extractor | 2 | extract_session_memories, extract_and_store_memories |
|
||||
| agent commands | 3 | export, import, agent_chat |
|
||||
| kernel lifecycle | 2 | kernel_init, kernel_shutdown |
|
||||
| 其他 | 12 | health, hand_run_cancel, scheduled_task 等 |
|
||||
|
||||
**注意**: pipeline 和 classroom 的 invoke 调用可能通过 store 或 client lib 间接调用,但 grep 未找到匹配。需手动验证。
|
||||
|
||||
---
|
||||
|
||||
## 3. 模式 2: "接了没传" (Connected but Not Passed)
|
||||
|
||||
### 3.1 trigger_update 参数嵌套问题 ⚠️ P1
|
||||
|
||||
**前端**: `desktop/src/lib/kernel-triggers.ts:99`
|
||||
```typescript
|
||||
return await invoke<TriggerItem>('trigger_update', { id, updates });
|
||||
// updates = { name, enabled, handId, triggerType }
|
||||
```
|
||||
|
||||
**Rust**: `desktop/src-tauri/src/kernel_commands/trigger.rs:183-189`
|
||||
```rust
|
||||
pub async fn trigger_update(
|
||||
state: State<'_, KernelState>,
|
||||
id: String,
|
||||
name: Option<String>, // 期望扁平参数
|
||||
enabled: Option<bool>,
|
||||
hand_id: Option<String>,
|
||||
) -> Result<TriggerResponse, String>
|
||||
```
|
||||
|
||||
**问题**: 前端传递 `{ id, updates: { name, ... } }` 嵌套结构,但 Rust 期望 `{ id, name, enabled, hand_id }` 扁平参数。Tauri 的 serde 反序列化会忽略嵌套的 `updates` 对象,导致 name/enabled/hand_id 始终为 `None`。
|
||||
|
||||
**此外**: Rust 硬编码 `trigger_type: None`(trigger.rs:198),前端传递的 `triggerType` 永远被丢弃。
|
||||
|
||||
**影响**: Trigger 更新功能静默失败 — 用户修改 trigger 配置后不会生效。
|
||||
|
||||
**修复方案**: 前端改为扁平传递:
|
||||
```typescript
|
||||
await invoke('trigger_update', { id, name: updates.name, enabled: updates.enabled, handId: updates.handId });
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3.2 hand_execute 参数名映射
|
||||
|
||||
**前端**: `desktop/src/lib/kernel-hands.ts:82`
|
||||
```typescript
|
||||
const result = await invoke('hand_execute', {
|
||||
id: name, // 前端字段名 "id"
|
||||
input: params || {},
|
||||
...(autonomyLevel ? { autonomyLevel } : {}),
|
||||
});
|
||||
```
|
||||
|
||||
需验证 Rust 端是否接受 `id` 还是 `hand_name`。Tauri 自动做 camelCase ↔ snake_case 转换,但如果 Rust 使用 `name` 而前端使用 `id`,可能导致映射失败。
|
||||
|
||||
---
|
||||
|
||||
## 4. 模式 3: "传了没存" (Passed but Not Stored)
|
||||
|
||||
### 4.1 定时任务执行结果未持久化
|
||||
|
||||
**文件**: `crates/zclaw-saas/src/scheduler.rs:147-225`
|
||||
|
||||
`execute_scheduled_task` 执行任务后只更新 `last_run_at`、`next_run_at`、`run_count`,但不存储执行结果(成功/失败、输出、错误消息)。
|
||||
|
||||
`scheduled_tasks` 表 schema 缺少 `last_result`/`last_error` 列。
|
||||
|
||||
**影响**: 无法查看定时任务历史执行结果,无法诊断失败原因。
|
||||
|
||||
**建议**: 添加 `last_result TEXT` 和 `last_error TEXT` 列到 scheduled_tasks 表。
|
||||
|
||||
---
|
||||
|
||||
### 4.2 前端审计日志滞留 localStorage
|
||||
|
||||
`audit-logger.ts` 写入 localStorage,但无路径发送到后端或展示在 UI。数据在 `MAX_LOCAL_LOGS = 500` 条后循环覆盖。
|
||||
|
||||
---
|
||||
|
||||
## 5. 模式 4: "存了没用" (Stored but Not Used)
|
||||
|
||||
### 5.1 prompt_sync_status 表 — 零读取
|
||||
|
||||
**迁移**: `20260329000001_initial_schema.sql:244`
|
||||
|
||||
数据由 OTA 同步流程写入,但全代码库中无 `SELECT FROM prompt_sync_status`。
|
||||
|
||||
**可能原因**: OTA check 端点直接比较版本号而不查询此表。
|
||||
|
||||
**建议**: 移除死表,或实现读取路径。
|
||||
|
||||
---
|
||||
|
||||
### 5.2 telemetry_reports 表 — 零读取
|
||||
|
||||
**迁移**: `20260329000001_initial_schema.sql:305`
|
||||
|
||||
数据通过 telemetry 批量上报写入,但无查询路径。
|
||||
|
||||
**可能原因**: Admin dashboard 统计数据从 usage_records 聚合,不从此表读取。
|
||||
|
||||
**建议**: 实现读取端点供 admin-v2 telemetry 页面使用。
|
||||
|
||||
---
|
||||
|
||||
### 5.3 key_usage_window 表 — 零读取
|
||||
|
||||
**迁移**: `20260329000001_initial_schema.sql:274`
|
||||
|
||||
写入用于限流窗口追踪,但无 SELECT 查询。限流中间件可能使用内存中的 DashMap 而非数据库查询。
|
||||
|
||||
**建议**: 确认是否仍需要此表,或改用纯内存方案。
|
||||
|
||||
---
|
||||
|
||||
## 6. 模式 5: "双系统不同步" (Dual System Out of Sync)
|
||||
|
||||
### 6.1 Desktop ↔ Admin-v2 类型名称不一致(13+ 组)
|
||||
|
||||
| Admin-v2 名称 | Desktop 名称 | 实际差异 |
|
||||
|---------------|-------------|----------|
|
||||
| `AccountPublic` | `SaaSAccountInfo` | 命名 + llm_routing required/optional |
|
||||
| `Provider` | `ProviderInfo` | 仅命名 |
|
||||
| `Model` | `ModelInfo` | 仅命名 |
|
||||
| `RelayTask` | `RelayTaskInfo` | 仅命名 |
|
||||
| `ConfigItem` | `SaaSConfigItem` | 仅命名 |
|
||||
| `OperationLog` | `OperationLogInfo` | 仅命名 |
|
||||
| `PromptTemplate` | `PromptTemplateInfo` | 仅命名 |
|
||||
| `PromptVersion` | `PromptVersionInfo` | 仅命名 |
|
||||
| `AgentTemplate` | `AgentTemplateFull` | 命名 + 字段差异(admin 多 5 个字段) |
|
||||
| `ApiError` | `SaaSErrorResponse` | 命名 + admin 多 status 字段 |
|
||||
| `LoginResponse` | `SaaSLoginResponse` | 结构差异(cookie vs token) |
|
||||
| `TokenInfo` | `TokenInfo` | nullability 差异 |
|
||||
| `PaginatedResponse` | `PaginatedResponse` | **一致** |
|
||||
|
||||
### 6.2 有意义的字段差异
|
||||
|
||||
**AccountPublic.llm_routing**:
|
||||
- Desktop: `llm_routing?: 'relay' | 'local'` (optional)
|
||||
- Admin: `llm_routing: 'relay' | 'local'` (required)
|
||||
|
||||
**TokenInfo nullability**:
|
||||
- Desktop: `last_used_at: string | null`, `expires_at: string | null`
|
||||
- Admin: `last_used_at?: string`, `expires_at?: string`
|
||||
|
||||
**PromptVariable.type**:
|
||||
- Desktop: `type: string`
|
||||
- Admin: `type: 'string' | 'number' | 'select' | 'boolean'`
|
||||
|
||||
**AgentTemplate 字段差异**:
|
||||
- Admin 额外: `visibility`, `status`, `current_version`, `version`, `capabilities`
|
||||
- Desktop 缺少以上字段
|
||||
|
||||
### 6.3 文档数字不一致
|
||||
|
||||
| 指标 | 实际值 | 文档值 | 差异文件 |
|
||||
|------|--------|--------|----------|
|
||||
| Skills | 76 | 66/75/77 | SYSTEM_ARCHITECTURE.md, roadmap.md, troubleshooting.md |
|
||||
| Hands | 9 目录 | 11 (CLAUDE.md) | CLAUDE.md 列出 11 个 Hand 配置 |
|
||||
| Tauri 命令 | 175 | 58+ / 130+ | 06-tauri-backend/00-backend-integration.md |
|
||||
| SaaS 路由 | 58 | 72+ | 08-saas-platform/00-saas-overview.md |
|
||||
| Stores | 15 | 14 | 00-architecture/02-state-management.md |
|
||||
|
||||
---
|
||||
|
||||
## 7. Dead Code 完整清单
|
||||
|
||||
| 项 | 位置 | 行数 | 严重度 | 建议 |
|
||||
|----|------|------|--------|------|
|
||||
| audit-logger.ts | desktop/src/lib/ | 170 | P3 | 接入或删除 |
|
||||
| saas-admin.ts | desktop/src/lib/ | 234 | P2 | 删除(admin-v2 已替代) |
|
||||
| extract_structured_facts() | crates/zclaw-runtime/src/growth.rs:224 | ~30 | P4 | 删除 deprecated 方法 |
|
||||
| secure-storage sync 方法 | desktop/src/lib/secure-storage.ts:309-325 | ~20 | P4 | 删除 |
|
||||
| OFP 能力变体 | crates/zclaw-types/src/capability.rs:28-32 | 5 | P4 | 注释或移除 |
|
||||
| Director feature-gated | crates/zclaw-kernel/src/director.rs | 912 | P4 | 保持,等路线图激活 |
|
||||
| A2A feature-gated | crates/zclaw-protocols/src/a2a.rs | ~400 | P4 | 保持,等路线图激活 |
|
||||
| WASM feature-gated | crates/zclaw-skills/src/wasm_runner.rs | ~200 | P4 | 保持,等路线图激活 |
|
||||
|
||||
---
|
||||
|
||||
## 8. Deprecated 代码状态
|
||||
|
||||
| 函数 | 位置 | 调用者 | 操作 |
|
||||
|------|------|--------|------|
|
||||
| `extract_structured_facts()` | growth.rs:224 | 0 | 删除 |
|
||||
| `getStoredGatewayToken()` | gateway-storage.ts:129 | **3 活跃调用** | 先迁移调用者再删除 |
|
||||
| `setStoredGatewayToken()` | gateway-storage.ts:196 | **1 活跃调用** | 先迁移调用者再删除 |
|
||||
| `getSync()/setSync()/deleteSync()` | secure-storage.ts:309-325 | 0 | 删除 |
|
||||
209
docs/archive/old-audits/V11_REMEDIATION_PLAN.md
Normal file
@@ -0,0 +1,209 @@
|
||||
# ZCLAW V11 修复优先级计划
|
||||
|
||||
> **生成日期**: 2026-04-02
|
||||
> **关联审计**: COMPREHENSIVE_AUDIT_V11.md + V11_GAP_ANALYSIS.md
|
||||
|
||||
---
|
||||
|
||||
## Sprint 分配建议
|
||||
|
||||
### Sprint 1 (P1 — 紧急修复)
|
||||
|
||||
#### V11-P1-01: trigger_update 参数修复
|
||||
- **影响**: Trigger 配置更新静默失败
|
||||
- **修复复杂度**: 低(1 文件修改)
|
||||
- **文件**: `desktop/src/lib/kernel-triggers.ts:99`
|
||||
- **方案**: 将嵌套 `updates` 对象展开为扁平参数
|
||||
```typescript
|
||||
// 修复前:
|
||||
await invoke('trigger_update', { id, updates });
|
||||
|
||||
// 修复后:
|
||||
await invoke('trigger_update', {
|
||||
id,
|
||||
name: updates.name,
|
||||
enabled: updates.enabled,
|
||||
handId: updates.handId,
|
||||
});
|
||||
```
|
||||
- **同时修复**: Rust 端添加 `trigger_type` 参数支持(trigger.rs:183-189)
|
||||
- **验证**: 修改 trigger 配置后检查 Kernel 状态
|
||||
|
||||
#### V11-P1-02: SaaS 配置同步传播
|
||||
- **影响**: SaaS 管理员修改配置后不影响 Kernel 运行时
|
||||
- **修复复杂度**: 中(需要新增 Tauri 命令或事件机制)
|
||||
- **方案**:
|
||||
- 选项 A: saasStore.pullConfig 完成后调用 Tauri command 通知 Kernel 重新加载配置
|
||||
- 选项 B: Kernel 定期检查配置文件变更(watcher)
|
||||
- 选项 C: 明确记录为 "前端缓存同步,不影响 Kernel"
|
||||
- **建议**: 先选 C(文档对齐),后续迭代实现 A
|
||||
- **验证**: 在 SaaS 后台修改配置 → 检查 Kernel 日志是否反映变更
|
||||
|
||||
#### V11-P1-03: 孤立 SQL 表处理
|
||||
- **影响**: 数据写入但无法读取,浪费存储
|
||||
- **修复复杂度**: 低
|
||||
- **方案**:
|
||||
- `prompt_sync_status`: 实现读取查询(OTA 端点需要)
|
||||
- `telemetry_reports`: 添加 admin-v2 查询端点
|
||||
- `key_usage_window`: 确认是否需要(限流可能已改用内存方案)
|
||||
- **验证**: `grep -rn "SELECT.*FROM.*<table>" crates/zclaw-saas/src/` 有结果
|
||||
|
||||
---
|
||||
|
||||
### Sprint 2 (P2 — 高优先级)
|
||||
|
||||
#### V11-P2-01: 删除 saas-admin.ts
|
||||
- **修复复杂度**: 低(删除 1 文件 + saas-client.ts 中的 install 调用)
|
||||
- **前置条件**: 确认 admin-v2 完全不依赖此文件
|
||||
- **验证**: admin-v2 所有页面功能正常
|
||||
|
||||
#### V11-P2-02: Role/Permission 管理
|
||||
- **选项 A**: 为 admin-v2 添加 roles service 和页面
|
||||
- **选项 B**: 移除 SaaS role 路由(如果当前不需要 RBAC)
|
||||
- **建议**: 评估业务需求后决定
|
||||
|
||||
#### V11-P2-03: 迁移 deprecated gateway-storage 调用者
|
||||
- **文件**: `gateway-client.ts:44,71,211`, `configStore.ts:252`
|
||||
- **方案**: 将 sync 方法调用替换为 async 版本
|
||||
- **验证**: Gateway 连接功能测试
|
||||
|
||||
#### V11-P2-04: ToolDefinition 去重
|
||||
- **文件**: `zclaw-runtime/src/driver/mod.rs:94`
|
||||
- **方案**: 重导出 `zclaw-types::tool::ToolDefinition`
|
||||
- **验证**: `cargo build` 通过
|
||||
|
||||
#### V11-P2-05: 未调用 Tauri 命令评估
|
||||
- **62 个命令**需逐一评估:
|
||||
- classroom_*: 确认 classroomStore 是否真正调用(可能是 store 中调用的)
|
||||
- pipeline_*: 确认 workflowStore 是否调用
|
||||
- gateway_*: 确认是否有侧车进程调用
|
||||
- viking_*: 确认 Settings 页面是否调用
|
||||
- **验证**: 对每个命令 grep `invoke('command_name'`
|
||||
|
||||
#### V11-P2-06: SQL LIMIT 添加
|
||||
- **文件**: `migration/service.rs`, `knowledge/service.rs`
|
||||
- **方案**: 为 config_items SELECT 添加 LIMIT 1000,knowledge_categories 添加 LIMIT 100
|
||||
- **验证**: SQL 执行计划验证
|
||||
|
||||
---
|
||||
|
||||
### Sprint 3 (P3 — 中优先级)
|
||||
|
||||
#### V11-P3-01: audit-logger 接入
|
||||
- **方案**: 在 ApprovalsPanel、AutonomyConfig、chatStore 的关键操作中添加 logAudit 调用
|
||||
- **或**: 标记为 reserved 并从 index 导出中移除
|
||||
|
||||
#### V11-P3-02: OFP 能力处理
|
||||
- **方案**: 添加 `// Reserved for OpenFang Protocol` 注释或移除变体
|
||||
|
||||
#### V11-P3-03: 移除 deprecated extract_structured_facts
|
||||
- **方案**: 删除 growth.rs:224 的 deprecated 方法
|
||||
- **验证**: `cargo build` 通过
|
||||
|
||||
#### V11-P3-04: SaaS knowledge stub 实现
|
||||
- **文件**: knowledge/handlers.rs:91,293,321
|
||||
- **方案**: 实现真正的分页查询、回滚、推荐算法
|
||||
- **验证**: admin-v2 Knowledge 页面功能测试
|
||||
|
||||
#### V11-P3-05: 定时任务执行结果持久化
|
||||
- **方案**: 添加 last_result/last_error 列到 scheduled_tasks 表
|
||||
- **迁移**: 新增 SQL migration
|
||||
- **验证**: 创建定时任务 → 执行 → 检查结果是否存储
|
||||
|
||||
#### V11-P3-06 ~ P3-08: 其他清理
|
||||
- 移除 secure-storage sync 方法
|
||||
- 启用 embedding 生成或注释
|
||||
- 清理 config 预留参数注释
|
||||
|
||||
---
|
||||
|
||||
### Sprint 4 (P4 — 低优先级 / 文档)
|
||||
|
||||
#### V11-P4-01: ContentBlock 命名规范
|
||||
- **方案**: 为每个 crate 的 ContentBlock 添加 crate 前缀注释
|
||||
- `zclaw_types::ContentBlock` = LLM 消息内容
|
||||
- `zclaw_hands::ContentBlock` = 幻灯片渲染
|
||||
- `zclaw_protocols::ContentBlock` = MCP 协议格式
|
||||
|
||||
#### V11-P4-02: 类型名称统一
|
||||
- **方案**: 建立共享类型包 `@zclaw/types` 或使用 OpenAPI schema 生成
|
||||
- 13+ 类型名称不一致需要协调
|
||||
|
||||
#### V11-P4-03: 文档数字更新
|
||||
- Skills: 76
|
||||
- Hands: 9 目录(CLAUDE.md 应更新 "11" → "9 目录 + 2 禁用配置")
|
||||
- Tauri 命令: 175
|
||||
- SaaS 路由: 58
|
||||
- Stores: 15
|
||||
|
||||
#### V11-P4-04/05: Feature-gated 代码保持现状
|
||||
- Director/A2A/WASM: 等产品路线图决定
|
||||
- Embedding 生成: 等 OpenViking 集成完成后启用
|
||||
|
||||
---
|
||||
|
||||
## 依赖关系图
|
||||
|
||||
```
|
||||
V11-P1-01 (trigger_update 修复)
|
||||
└── 无依赖,可独立完成
|
||||
|
||||
V11-P1-02 (配置同步传播)
|
||||
└── 依赖设计决策(选项 A/B/C)
|
||||
|
||||
V11-P1-03 (孤立表处理)
|
||||
└── V11-P2-06 (SQL LIMIT) 可同时处理
|
||||
|
||||
V11-P2-01 (删除 saas-admin.ts)
|
||||
└── V11-P2-04 (ToolDefinition 去重) 可同时完成
|
||||
|
||||
V11-P2-03 (迁移 deprecated 调用)
|
||||
└── 需要先确认 async 版本稳定性
|
||||
|
||||
V11-P3-04 (knowledge stub 实现)
|
||||
└── 依赖 V11-P1-03(确认表用途后实现读取)
|
||||
|
||||
V11-P4-02 (类型统一)
|
||||
└── 长期任务,不阻塞其他修复
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 修复工作量估算
|
||||
|
||||
| Sprint | 项数 | 预估工作量 | 风险等级 |
|
||||
|--------|------|-----------|----------|
|
||||
| Sprint 1 (P1) | 3 | 中 | 高(P1-02 需设计决策) |
|
||||
| Sprint 2 (P2) | 6 | 高 | 中(P2-05 工作量大) |
|
||||
| Sprint 3 (P3) | 8 | 中 | 低 |
|
||||
| Sprint 4 (P4) | 5 | 低 | 低 |
|
||||
|
||||
---
|
||||
|
||||
## 验证检查清单
|
||||
|
||||
### 编译验证
|
||||
```bash
|
||||
cargo build --workspace
|
||||
pnpm tsc --noEmit
|
||||
```
|
||||
|
||||
### 功能验证
|
||||
- [ ] 创建/更新/删除 Trigger → 检查 Kernel 状态
|
||||
- [ ] SaaS 后台修改配置 → 检查 desktop 前端行为
|
||||
- [ ] Admin-v2 Knowledge 页面 CRUD
|
||||
- [ ] 定时任务执行 → 检查结果存储
|
||||
- [ ] Agent 审批 → Hand 自动执行
|
||||
- [ ] Pipeline 运行 → 完成事件通知
|
||||
|
||||
### 回归验证
|
||||
```bash
|
||||
# Rust 测试
|
||||
cargo test --workspace
|
||||
|
||||
# 前端测试
|
||||
pnpm vitest run
|
||||
|
||||
# Admin-v2 测试
|
||||
cd admin-v2 && pnpm test
|
||||
```
|
||||
331
docs/archive/old-audits/VERIFICATION_REPORT.md
Normal file
@@ -0,0 +1,331 @@
|
||||
# ZCLAW 功能验证报告
|
||||
|
||||
> **⚠️ ARCHIVED — 此报告已过时**
|
||||
>
|
||||
> 本报告验证于 2026-03-24 (v0.2.5),声称 98.5% 通过率。
|
||||
> 经 2026-03-27 深度审计确认:报告包含已删除功能(Team/Swarm),
|
||||
> 模拟实现被标记为可用,多项结论不准确。
|
||||
>
|
||||
> **请以最新审计报告为准** → [DEEP_AUDIT_REPORT.md](./DEEP_AUDIT_REPORT.md)
|
||||
|
||||
---
|
||||
|
||||
> **验证日期**: 2026-03-24
|
||||
> **验证版本**: v0.2.5
|
||||
> **验证范围**: 所有已实现功能的完整性、可用性验证
|
||||
|
||||
---
|
||||
|
||||
## 一、验证概述
|
||||
|
||||
### 1.1 验证统计
|
||||
|
||||
| 模块 | 验证点 | 通过 | 失败 | 通过率 |
|
||||
|------|--------|------|------|--------|
|
||||
| 架构层 | 45 | 45 | 0 | 100% |
|
||||
| 核心功能 | 17 | 17 | 0 | 100% |
|
||||
| 智能层 | 36 | 36 | 0 | 100% |
|
||||
| 技能系统 | 10 | 10 | 0 | 100% |
|
||||
| Hands 系统 | 15 | 13 | 2 | 87% |
|
||||
| 后端集成 | 12 | 12 | 0 | 100% |
|
||||
| **总计** | **135** | **133** | **2** | **98.5%** |
|
||||
|
||||
### 1.2 总体结论
|
||||
|
||||
✅ **ZCLAW v0.2.5 功能验证通过**
|
||||
|
||||
- 所有核心功能完整可用
|
||||
- 前后端正确集成
|
||||
- 数据持久化机制正确
|
||||
- 2 个已知问题(非阻塞)
|
||||
|
||||
---
|
||||
|
||||
## 二、Phase 1: 架构层验证
|
||||
|
||||
### 2.1 通信层验证 ✅
|
||||
|
||||
#### 2.1.1 LLM Driver 实现
|
||||
|
||||
| Driver | 文件 | 状态 | 支持的 Provider |
|
||||
|--------|------|------|----------------|
|
||||
| OpenAiDriver | `crates/zclaw-runtime/src/driver/openai.rs` | ✅ | OpenAI, Kimi, Qwen, DeepSeek, Zhipu |
|
||||
| AnthropicDriver | `crates/zclaw-runtime/src/driver/anthropic.rs` | ✅ | Anthropic (Claude) |
|
||||
| GeminiDriver | `crates/zclaw-runtime/src/driver/gemini.rs` | ✅ | Google Gemini |
|
||||
| LocalDriver | `crates/zclaw-runtime/src/driver/local.rs` | ✅ | Ollama, Local |
|
||||
|
||||
**验证方法**: 代码审查 `driver/mod.rs`
|
||||
|
||||
```rust
|
||||
// 验证的 Driver 配置
|
||||
pub enum DriverConfig {
|
||||
Anthropic { api_key: SecretString },
|
||||
OpenAi { api_key: SecretString, base_url: Option<String> },
|
||||
Gemini { api_key: SecretString },
|
||||
Local { base_url: String },
|
||||
}
|
||||
```
|
||||
|
||||
#### 2.1.2 Tauri 命令实现
|
||||
|
||||
| 命令 | 状态 | 说明 |
|
||||
|------|------|------|
|
||||
| `kernel_init` | ✅ | 初始化内部 Kernel |
|
||||
| `kernel_status` | ✅ | 获取 Kernel 状态 |
|
||||
| `kernel_shutdown` | ✅ | 关闭 Kernel |
|
||||
| `agent_create` | ✅ | 创建 Agent |
|
||||
| `agent_list` | ✅ | 列出所有 Agent |
|
||||
| `agent_get` | ✅ | 获取 Agent 详情 |
|
||||
| `agent_delete` | ✅ | 删除 Agent |
|
||||
| `agent_chat` | ✅ | 发送非流式消息 |
|
||||
| `agent_chat_stream` | ✅ | 发送流式消息 |
|
||||
| `skill_list` | ✅ | 列出技能 |
|
||||
| `skill_refresh` | ✅ | 刷新技能目录 |
|
||||
| `skill_execute` | ✅ | 执行技能 |
|
||||
| `hand_list` | ✅ | 列出 Hands |
|
||||
| `hand_execute` | ✅ | 执行 Hand |
|
||||
|
||||
**验证方法**: 代码审查 `kernel_commands.rs` (685 行)
|
||||
|
||||
#### 2.1.3 流式响应实现
|
||||
|
||||
| 事件类型 | 状态 | 说明 |
|
||||
|---------|------|------|
|
||||
| `Delta` | ✅ | 文本增量 |
|
||||
| `ToolStart` | ✅ | 工具调用开始 |
|
||||
| `ToolEnd` | ✅ | 工具调用结束 |
|
||||
| `Complete` | ✅ | 流式完成 |
|
||||
| `Error` | ✅ | 错误处理 |
|
||||
|
||||
**验证方法**: 代码审查 `StreamChatEvent` 枚举
|
||||
|
||||
---
|
||||
|
||||
### 2.2 状态管理验证 ✅
|
||||
|
||||
#### 2.2.1 Store 实现
|
||||
|
||||
| Store | 文件 | 持久化 | 状态 |
|
||||
|-------|------|--------|------|
|
||||
| chatStore | `desktop/src/store/chatStore.ts` | ✅ `zclaw-chat-storage` | ✅ |
|
||||
| configStore | `desktop/src/store/configStore.ts` | ✅ | ✅ |
|
||||
| connectionStore | `desktop/src/store/connectionStore.ts` | ❌ | ✅ |
|
||||
| agentStore | `desktop/src/store/agentStore.ts` | ❌ | ✅ |
|
||||
| handStore | `desktop/src/store/handStore.ts` | ❌ | ✅ |
|
||||
| offlineStore | `desktop/src/store/offlineStore.ts` | ✅ | ✅ |
|
||||
| sessionStore | `desktop/src/store/sessionStore.ts` | ❌ | ✅ |
|
||||
| securityStore | `desktop/src/store/securityStore.ts` | ❌ | ✅ |
|
||||
| workflowStore | `desktop/src/store/workflowStore.ts` | ❌ | ✅ |
|
||||
| teamStore | `desktop/src/store/teamStore.ts` | ❌ | ✅ |
|
||||
| gatewayStore | `desktop/src/store/gatewayStore.ts` | ❌ | ✅ |
|
||||
| memoryGraphStore | `desktop/src/store/memoryGraphStore.ts` | ❌ | ✅ |
|
||||
| activeLearningStore | `desktop/src/store/activeLearningStore.ts` | ❌ | ✅ |
|
||||
| browserHandStore | `desktop/src/store/browserHandStore.ts` | ❌ | ✅ |
|
||||
| skillMarketStore | `desktop/src/store/skillMarketStore.ts` | ❌ | ✅ |
|
||||
|
||||
**总计**: 16 个 Store (与文档一致)
|
||||
|
||||
#### 2.2.2 chatStore 持久化验证
|
||||
|
||||
```typescript
|
||||
// 验证的持久化配置
|
||||
{
|
||||
name: 'zclaw-chat-storage',
|
||||
partialize: (state) => ({
|
||||
conversations: state.conversations,
|
||||
currentModel: state.currentModel,
|
||||
currentAgentId: state.currentAgent?.id,
|
||||
currentConversationId: state.currentConversationId,
|
||||
}),
|
||||
onRehydrateStorage: () => (state) => {
|
||||
// Date 对象恢复
|
||||
// streaming 状态清除
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
✅ **验证通过**: partialize 和 onRehydrateStorage 正确实现
|
||||
|
||||
---
|
||||
|
||||
### 2.3 安全认证验证 ✅
|
||||
|
||||
| 验证项 | 状态 | 说明 |
|
||||
|--------|------|------|
|
||||
| 密钥生成 | ✅ | Ed25519 密钥对 |
|
||||
| Keyring 集成 | ✅ | Windows DPAPI / macOS Keychain / Linux Secret Service |
|
||||
| 降级策略 | ✅ | AES-GCM 加密 localStorage |
|
||||
|
||||
---
|
||||
|
||||
## 三、Phase 2: 核心功能验证
|
||||
|
||||
### 3.1 聊天界面 ✅
|
||||
|
||||
| 组件 | 文件 | 状态 |
|
||||
|------|------|------|
|
||||
| 聊天区域 | `ChatArea.tsx` | ✅ |
|
||||
| 消息渲染 | `MessageItem.tsx` | ✅ |
|
||||
| 输入框 | `ChatInput.tsx` | ✅ |
|
||||
|
||||
### 3.2 Agent 管理 ✅
|
||||
|
||||
| 组件 | 文件 | 状态 |
|
||||
|------|------|------|
|
||||
| Agent 创建向导 | `AgentOnboardingWizard.tsx` | ✅ |
|
||||
| 人格预设 | `personality-presets.ts` | ✅ |
|
||||
| 身份客户端 | `intelligence-client.ts` | ✅ |
|
||||
|
||||
### 3.3 多 Agent 协作 ✅
|
||||
|
||||
| 组件 | 文件 | 状态 |
|
||||
|------|------|------|
|
||||
| 协作仪表板 | `SwarmDashboard.tsx` | ✅ |
|
||||
| 协作引擎 | `agent-swarm.ts` | ✅ |
|
||||
| Swarm 类型 | `types/swarm.ts` | ✅ |
|
||||
|
||||
---
|
||||
|
||||
## 四、Phase 3: 智能层验证
|
||||
|
||||
### 4.1 后端 Rust 实现 ✅
|
||||
|
||||
| 模块 | 文件 | 状态 |
|
||||
|------|------|------|
|
||||
| 记忆命令 | `memory_commands.rs` | ✅ |
|
||||
| 身份管理 | `intelligence/identity.rs` | ✅ |
|
||||
| 反思引擎 | `intelligence/reflection.rs` | ✅ |
|
||||
| 心跳引擎 | `intelligence/heartbeat.rs` | ✅ |
|
||||
| 上下文压缩 | `intelligence/compactor.rs` | ✅ |
|
||||
|
||||
### 4.2 前端 UI 集成 ✅
|
||||
|
||||
| 组件 | 文件 | RightPanel Tab | 状态 |
|
||||
|------|------|----------------|------|
|
||||
| 记忆面板 | `MemoryPanel.tsx` | 'memory' | ✅ |
|
||||
| 记忆图谱 | `MemoryGraph.tsx` | - | ✅ |
|
||||
| 反思日志 | `ReflectionLog.tsx` | 'reflection' | ✅ |
|
||||
| 自主配置 | `AutonomyConfig.tsx` | 'autonomy' | ✅ |
|
||||
| 身份变更提案 | `IdentityChangeProposal.tsx` | 'identity' | ✅ |
|
||||
|
||||
**验证方法**: Grep 搜索 RightPanel.tsx 中的组件导入
|
||||
|
||||
---
|
||||
|
||||
## 五、Phase 4: 技能系统验证
|
||||
|
||||
### 5.1 技能发现 ✅
|
||||
|
||||
| 验证项 | 文档值 | 实际值 | 状态 |
|
||||
|--------|--------|--------|------|
|
||||
| SKILL.md 文件数 | 77 | **69** | ⚠️ 差异 |
|
||||
|
||||
**说明**: 文档记录 77 个技能,实际扫描发现 69 个。需要更新文档或补充缺失技能。
|
||||
|
||||
### 5.2 技能分类 ✅
|
||||
|
||||
| 分类 | 数量 | 代表技能 |
|
||||
|------|------|---------|
|
||||
| 开发工程 | 15 | senior-developer, frontend-developer, backend-architect |
|
||||
| 营销/社媒 | 12 | twitter-engager, xiaohongshu-specialist, tiktok-strategist |
|
||||
| 管理/PM | 8 | senior-pm, project-shepherd, agents-orchestrator |
|
||||
| 数据分析 | 5 | analytics-reporter, data-analysis |
|
||||
| 设计/UX | 5 | ui-designer, ux-architect |
|
||||
|
||||
### 5.3 execute_skill 工具 ✅
|
||||
|
||||
| 验证项 | 状态 |
|
||||
|--------|------|
|
||||
| Tauri 命令 | ✅ `skill_execute` |
|
||||
| 上下文传递 | ✅ `SkillContext` |
|
||||
| 结果返回 | ✅ `SkillResult` |
|
||||
|
||||
---
|
||||
|
||||
## 六、Phase 5: Hands 系统验证
|
||||
|
||||
### 6.1 Rust 实现 (9/11) ✅
|
||||
|
||||
| Hand | Rust 文件 | TOML 配置 | 状态 |
|
||||
|------|----------|-----------|------|
|
||||
| browser | `browser.rs` | ✅ | ✅ 可用 |
|
||||
| researcher | `researcher.rs` | ✅ | ✅ 可用 |
|
||||
| collector | `collector.rs` | ✅ | ✅ 可用 |
|
||||
| slideshow | `slideshow.rs` | ✅ | ✅ 可用 |
|
||||
| speech | `speech.rs` | ✅ | ✅ 可用 |
|
||||
| quiz | `quiz.rs` | ✅ | ✅ 可用 |
|
||||
| whiteboard | `whiteboard.rs` | ✅ | ✅ 可用 |
|
||||
| clip | `clip.rs` | ✅ | ⚠️ 需 FFmpeg |
|
||||
| twitter | `twitter.rs` | ✅ | ⚠️ 需 API Key |
|
||||
|
||||
### 6.2 未实现 (2/11) ❌
|
||||
|
||||
| Hand | TOML 配置 | Rust 实现 | 状态 |
|
||||
|------|-----------|----------|------|
|
||||
| predictor | ✅ | ❌ | 待实现 |
|
||||
| lead | ✅ | ❌ | 待实现 |
|
||||
|
||||
---
|
||||
|
||||
## 七、Phase 6: 后端集成验证
|
||||
|
||||
### 7.1 Kernel 集成 ✅
|
||||
|
||||
| 验证项 | 状态 |
|
||||
|--------|------|
|
||||
| 内部 Kernel | ✅ `Kernel::boot()` |
|
||||
| 多 LLM 支持 | ✅ 8+ Provider |
|
||||
| Agent 生命周期 | ✅ spawn/kill |
|
||||
| 流式响应 | ✅ Tauri events |
|
||||
| MCP 协议 | ✅ 已实现 |
|
||||
|
||||
### 7.2 浏览器自动化 ✅
|
||||
|
||||
| 命令 | 状态 |
|
||||
|------|------|
|
||||
| `browser_create_session` | ✅ |
|
||||
| `browser_navigate` | ✅ |
|
||||
| `browser_click` | ✅ |
|
||||
| `browser_type` | ✅ |
|
||||
| `browser_screenshot` | ✅ |
|
||||
| `browser_execute_script` | ✅ |
|
||||
| `browser_scrape_page` | ✅ |
|
||||
|
||||
---
|
||||
|
||||
## 八、发现的问题
|
||||
|
||||
### 8.1 数据差异
|
||||
|
||||
| 问题 | 严重程度 | 说明 |
|
||||
|------|---------|------|
|
||||
| 技能数量差异 | 低 | 文档 77,实际 69 |
|
||||
| Hands 未完成 | 低 | 2/11 未实现 (predictor, lead) |
|
||||
|
||||
### 8.2 建议修复
|
||||
|
||||
1. **更新文档**: 将技能数量从 77 更新为 69
|
||||
2. **实现缺失 Hands**: predictor 和 lead 的 Rust 实现
|
||||
|
||||
---
|
||||
|
||||
## 九、验证结论
|
||||
|
||||
### 9.1 通过标准
|
||||
|
||||
| 指标 | 标准 | 实际 | 结果 |
|
||||
|------|------|------|------|
|
||||
| 功能完整性 | ≥ 95% | 98.5% | ✅ 通过 |
|
||||
| 关键功能 | 100% | 100% | ✅ 通过 |
|
||||
| 无阻塞性问题 | 0 High | 0 | ✅ 通过 |
|
||||
| 数据持久化 | 100% | 100% | ✅ 通过 |
|
||||
|
||||
### 9.2 最终结论
|
||||
|
||||
**ZCLAW v0.2.5 功能验证通过** ✅
|
||||
|
||||
所有核心功能完整可用,前后端正确集成,数据持久化机制正确。发现的 2 个问题均为非阻塞性问题,不影响系统正常使用。
|
||||
|
||||
---
|
||||
|
||||
*验证报告生成时间: 2026-03-24*
|
||||
309
docs/archive/old-audits/audit-2026-03-30.md
Normal file
@@ -0,0 +1,309 @@
|
||||
# ZCLAW 全面项目审计报告
|
||||
|
||||
> **审计日期**: 2026-03-30
|
||||
> **审计范围**: 系统架构、代码质量、性能、安全、业务功能、用户体验
|
||||
> **审计基准**: v0.7.0,基于 F16/S2/S4/S8 完成后的代码状态
|
||||
> **审计方法**: 5 个并行子代理 + 直接代码分析
|
||||
|
||||
---
|
||||
|
||||
## 一、执行摘要
|
||||
|
||||
### 总体评级: **B+ (良好)**
|
||||
|
||||
| 维度 | 评级 | 关键发现 |
|
||||
|------|------|----------|
|
||||
| 系统架构 | A- | 10 Crate 分层清晰,SaaS 独立,feature gate 全覆盖 |
|
||||
| 代码质量 | B | 0 编译警告,453 测试,但多文件超限,53 处 Promise\<any\> |
|
||||
| 安全性 | B | Cookie 已实现,SQL 全参数化,但登出未撤 token,无 TLS |
|
||||
| 性能 | B | 连接池健康检查完备,但 SSE 不响应 shutdown,表无自动清理 |
|
||||
| 业务功能 | A- | 93 API,9 Hands,66 Skills,前后端对齐,SaaS 定时任务执行未闭环 |
|
||||
|
||||
### 关键数字
|
||||
|
||||
| 指标 | 数值 |
|
||||
|------|------|
|
||||
| Rust 代码行数 | 54,380 |
|
||||
| SaaS API 端点 | 93 (10 模块) |
|
||||
| Tauri 命令 | 106 |
|
||||
| 测试数量 | 453 (254 unit + 199 async) |
|
||||
| Hands | 9 |
|
||||
| Skills | 66 SKILL.md |
|
||||
| Pipeline YAML | 7 |
|
||||
| 编译警告 | 0 (项目自有) |
|
||||
| TypeScript 错误 | 0 |
|
||||
|
||||
---
|
||||
|
||||
## 二、系统架构审计
|
||||
|
||||
### 2.1 Crate 分层 ✅
|
||||
|
||||
```
|
||||
L1: zclaw-types (无 zclaw 依赖) ✅
|
||||
L1.5: zclaw-growth (仅依赖 types) — 目录在 L5 但依赖在 L1
|
||||
L2: zclaw-memory (→ types)
|
||||
L3: zclaw-runtime (→ types, memory, growth)
|
||||
L4: zclaw-kernel (→ types, memory, runtime, protocols, hands, skills)
|
||||
L5: zclaw-skills (→ types), zclaw-hands (→ types, runtime), zclaw-protocols (→ types)
|
||||
zclaw-pipeline (→ types, runtime, kernel, skills, hands)
|
||||
独立: zclaw-saas (仅依赖 zclaw-types) ✅
|
||||
```
|
||||
|
||||
**架构代理验证结果**:
|
||||
- ✅ 无循环依赖(DAG)
|
||||
- ✅ SaaS 独立于 Kernel
|
||||
- ✅ workspace members 完整
|
||||
- ✅ multi-agent feature 传播链正确: desktop → kernel → protocols/a2a
|
||||
- ✅ wasm feature gate 完整
|
||||
- ✅ dev-server feature gate 完整
|
||||
- ℹ️ `zclaw-growth` 目录位置与依赖层级不一致(不影响功能)
|
||||
- ℹ️ `zclaw-pipeline` 声明了 `zclaw-kernel` 依赖但代码中未直接 import
|
||||
|
||||
### 2.2 数据流完整性 ✅
|
||||
|
||||
| 链路 | 状态 | 覆盖 |
|
||||
|------|------|------|
|
||||
| Desktop UI → Store → Tauri → Kernel → LLM/Hands/Skills | ✅ 完整 | 106 个 Tauri 命令 |
|
||||
| Admin V2 → Axios → SaaS API → PostgreSQL | ✅ 完整 | 12 个 service 文件 |
|
||||
| Pipeline YAML → Executor → LLM/Skill/Hand Actions | ✅ 完整 | 三种 Action driver 均已接通 |
|
||||
|
||||
---
|
||||
|
||||
## 三、代码质量审计
|
||||
|
||||
### 3.1 编译状态 ✅
|
||||
|
||||
- `cargo check --workspace`: **0 项目警告**
|
||||
- `admin-v2 tsc --noEmit`: **通过**
|
||||
- `desktop tsc --noEmit`: **通过**
|
||||
|
||||
### 3.2 大文件审计 ⚠️
|
||||
|
||||
**Rust 文件(>800 行)**:
|
||||
|
||||
| 文件 | 行数 | 建议 |
|
||||
|------|------|------|
|
||||
| `kernel_commands.rs` | **2185** | 按功能域拆分 |
|
||||
| `lib.rs` (desktop) | **1518** | 命令定义独立 |
|
||||
| `kernel.rs` | **1490** | 拆分 a2a/scheduler 子模块 |
|
||||
| `pipeline_commands.rs` | **1391** | 按 stage 拆分 |
|
||||
| `generation.rs` | 1080 | 逻辑连贯,可保持 |
|
||||
| `quiz.rs` | 1027 | 题目模板导致 |
|
||||
| `openai.rs` | 912 | 拆分 streaming 子模块 |
|
||||
| `director.rs` | 912 | 拆分 turn/submission |
|
||||
| `loop_runner.rs` | 896 | 拆分 tool execution |
|
||||
| `store.rs` | 804 | 拆分 query builder |
|
||||
|
||||
**TypeScript 文件(>800 行)**:
|
||||
|
||||
| 文件 | 行数 | 类型安全 |
|
||||
|------|------|----------|
|
||||
| `intelligence-client.ts` | 1471 | 低风险 |
|
||||
| `kernel-client.ts` | 1343 | 低风险 |
|
||||
| `saas-client.ts` | 1290 | 低风险 |
|
||||
| **`gateway-client.ts`** | **1227** | **53 处 Promise\<any\>** |
|
||||
| **`gateway-api.ts`** | **672** | **同上** |
|
||||
|
||||
### 3.3 unwrap() 使用 ⚠️
|
||||
|
||||
- 68 个 Rust 文件含 unwrap(),生产代码约 108 处
|
||||
- `store.rs` 独占 75 处(最高风险)
|
||||
- **P0 风险**: `extraction_adapter.rs:306-310` 链式 unwrap(LLM 返回异常格式时 panic)
|
||||
- **P1 风险**: `context_builder.rs` 多处 HashMap `get_mut().unwrap()`
|
||||
|
||||
### 3.4 TypeScript 类型安全
|
||||
|
||||
- 0 处 `@ts-ignore` / `@ts-nocheck`
|
||||
- **53 处 `Promise<any>`** 在 gateway-client.ts + gateway-api.ts(最大类型安全盲区)
|
||||
- 6 处静默 `catch(() => {})`(saasStore.ts 3 处应添加日志)
|
||||
- 33 处 `#[allow(dead_code)]`(半数标注 "reserved",需定期审视)
|
||||
|
||||
### 3.5 测试覆盖
|
||||
|
||||
| Crate | 测试数 | 评价 |
|
||||
|-------|--------|------|
|
||||
| zclaw-saas | 111 | 良好 |
|
||||
| zclaw-growth | 75 | 良好 |
|
||||
| zclaw-pipeline | 59 | 良好 |
|
||||
| zclaw-types | 57 | 良好 |
|
||||
| zclaw-runtime | 42 | 中等 |
|
||||
| zclaw-kernel | 41 | 需提升 |
|
||||
| zclaw-skills | 22 | 需提升 |
|
||||
| zclaw-hands | 21 | 需提升 |
|
||||
| zclaw-memory | 20 | 需提升 |
|
||||
| zclaw-protocols | **5** | **不足** |
|
||||
|
||||
---
|
||||
|
||||
## 四、安全审计
|
||||
|
||||
### 4.1 安全发现汇总
|
||||
|
||||
| 级别 | ID | 问题 | 文件 |
|
||||
|------|-----|------|------|
|
||||
| HIGH | SEC-02 | `saas-config.toml` 含明文 DB 密码 | saas-config.toml:16 |
|
||||
| HIGH | SEC-03 | ShellSkill SKILL.md 命令注入信任模型 | skills/runner.rs:125 |
|
||||
| HIGH | SEC-04 | 服务端无 TLS 终止 | saas/main.rs:72 |
|
||||
| HIGH | SEC-05 | JWT debug fallback 密钥硬编码 | saas/config.rs:238 |
|
||||
| MED | SEC-06 | 登出未撤销服务端 refresh token | saas/auth/handlers.rs:506 |
|
||||
| MED | SEC-07 | 注册端点无验证码/邀请机制 | saas/auth/handlers.rs:54 |
|
||||
| MED | SEC-08 | 角色权限缓存无 TTL/失效 | saas/auth/handlers.rs:397 |
|
||||
| MED | SEC-09 | 登录缺少专门暴力破解保护 | saas/auth/handlers.rs:160 |
|
||||
| MED | SEC-10 | 生产 CORS 配置含 localhost | saas-config.toml:12 |
|
||||
| MED | SEC-11 | Cookie Secure 在非 HTTPS 环境失效 | saas/auth/handlers.rs:29 |
|
||||
| MED | SEC-13 | TOTP 加密密钥从 JWT Secret 派生 | saas/config.rs:285 |
|
||||
| LOW | SEC-14 | PythonSkill 脚本路径信任模型 | skills/runner.rs:83 |
|
||||
| LOW | SEC-15 | Rate limit 信任 X-Forwarded-For | saas/middleware.rs:109 |
|
||||
|
||||
### 4.2 安全优势
|
||||
|
||||
| 项目 | 状态 |
|
||||
|------|------|
|
||||
| SQL 注入防护 | ✅ 100% 参数化,0 字符串拼接 |
|
||||
| 密码哈希 | ✅ Argon2id + spawn_blocking |
|
||||
| Refresh Token Rotation | ✅ 一次性使用 + SHA-256 hash 存储 |
|
||||
| API Key 加密 | ✅ AES-256-GCM + 随机 nonce |
|
||||
| 错误信息处理 | ✅ 500 不泄露内部细节 |
|
||||
| 审计日志 | ✅ 覆盖所有关键操作 + IP |
|
||||
| TOTP 暴力破解保护 | ✅ 5 次失败锁定 10 分钟 |
|
||||
| XSS 防护 | ✅ 唯一 innerHTML 用 DOMPurify |
|
||||
| 账号隔离 | ✅ 所有查询强制 account_id |
|
||||
| CORS 安全 | ✅ 生产强制白名单 |
|
||||
|
||||
---
|
||||
|
||||
## 五、性能审计
|
||||
|
||||
### 5.1 严重性能问题
|
||||
|
||||
| 问题 | 影响 | 文件 |
|
||||
|------|------|------|
|
||||
| SSE 流不检查 CancellationToken | graceful shutdown 等待最长 5 分钟 | relay/service.rs |
|
||||
| 数据表无自动清理 | operation_logs/usage_records/relay_tasks 无限增长 | scheduler.rs |
|
||||
| 连接池偏小 (max=20) | 高并发 SSE 场景不足 | db.rs:12 |
|
||||
| Scheduler 循环不监听 shutdown token | 后台 task 不会被取消 | scheduler.rs:55,78,111 |
|
||||
|
||||
### 5.2 中等性能问题
|
||||
|
||||
| 问题 | 文件 |
|
||||
|------|------|
|
||||
| relay_tasks 缺 (account_id, status) 复合索引 | relay/handlers.rs:31 |
|
||||
| SSE usage 跳过后 task 永久 "processing" | relay/service.rs:302 |
|
||||
| OTA 提示词 N+1 查询(每模板 2 次) | prompt/service.rs:242 |
|
||||
| totp_fail_counts 无清理机制 | state.rs:26 |
|
||||
| `operation_logs` COUNT(*) 无时间范围 | account/handlers.rs:144 |
|
||||
|
||||
### 5.3 性能优势
|
||||
|
||||
| 项目 | 设计 |
|
||||
|------|------|
|
||||
| 连接池健康检查 | 80% 水位 503 + 3s 超时 |
|
||||
| TCP keepalive | 60s/10s/3次 + SO_LINGER 1s |
|
||||
| SSE 背压 | bounded channel(128) |
|
||||
| SSE 并发限制 | Semaphore(16) |
|
||||
| DashMap 死锁 | RefMut 在 await 前释放 |
|
||||
| 前端无轮询 | TanStack Query 按需触发 |
|
||||
|
||||
---
|
||||
|
||||
## 六、业务功能审计
|
||||
|
||||
### 6.1 SaaS API 完整度 ✅
|
||||
|
||||
| 模块 | 端点数 | CRUD |
|
||||
|------|--------|------|
|
||||
| auth (含 TOTP) | 9 | 完整认证流程 |
|
||||
| account (含 tokens/devices/logs/stats) | 12 | ✅ |
|
||||
| provider | 6 | ✅ C/R/U/D |
|
||||
| model | 5 | ✅ C/R/U/D |
|
||||
| api_keys (含 rotate) | 5 | ✅ |
|
||||
| relay (含 key pool) | 9 | ✅ |
|
||||
| config/migration | 12 | ✅ + sync/diff/pull |
|
||||
| role + permission_template | 11 | ✅ |
|
||||
| prompt (含 versions/rollback) | 10 | ✅ |
|
||||
| agent_template | 5 | ✅ |
|
||||
| scheduled_task | 5 | ✅ |
|
||||
| telemetry | 4 | ✅ |
|
||||
| health | 1 | ✅ |
|
||||
| **总计** | **93** | **完整** |
|
||||
|
||||
### 6.2 前后端对齐 ✅
|
||||
|
||||
- Admin V2: 12 个 service 文件 → 后端路由全部匹配
|
||||
- baseURL `/api/v1` + Vite proxy → 无断链
|
||||
- `withCredentials: true` → Cookie 自动发送
|
||||
- **后端就绪但无 Admin UI**: Role 管理、TOTP、Prompt 版本、定时任务管理
|
||||
|
||||
### 6.3 功能缺口
|
||||
|
||||
| 功能 | 后端 | 前端 Admin | 状态 |
|
||||
|------|------|-----------|------|
|
||||
| Role CRUD | ✅ 4 端点 | ❌ | 后端就绪 |
|
||||
| Permission Template | ✅ 4 端点 | ❌ | 后端就绪 |
|
||||
| TOTP 2FA | ✅ 3 端点 | ❌ | 后端就绪 |
|
||||
| Prompt 版本管理 | ✅ 4 端点 | ❌ | 后端就绪 |
|
||||
| 定时任务管理 | ✅ 5 端点 | ❌ | 后端就绪 |
|
||||
| SaaS 定时任务执行 | ⚠️ 仅状态管理 | — | **未闭环** |
|
||||
| Kernel 定时任务执行 | ✅ TriggerManager | ✅ | 完整闭环 |
|
||||
|
||||
### 6.4 Approval 流程 ✅
|
||||
|
||||
完整闭环: 触发 → 检查 → 创建审批 → 前端通知 → 审批/拒绝 → 执行 → 结果通知
|
||||
|
||||
---
|
||||
|
||||
## 七、待改进项(按优先级)
|
||||
|
||||
### P0 — 必须修复
|
||||
|
||||
| ID | 问题 | 影响 |
|
||||
|----|------|------|
|
||||
| P0-1 | SSE 流不检查 CancellationToken | 停机等待最长 5 分钟 |
|
||||
| P0-2 | 数据表无自动清理 (logs/usage/relay_tasks) | 磁盘耗尽 + 查询退化 |
|
||||
| P0-3 | `store.rs` 75 处 unwrap | 数据库异常导致 panic |
|
||||
| P0-4 | `extraction_adapter.rs` 链式 unwrap | LLM 异常输出导致 panic |
|
||||
| P0-5 | 登出未撤销服务端 refresh token | XSS 后 token 仍可用 |
|
||||
|
||||
### P1 — 应该修复
|
||||
|
||||
| ID | 问题 | 影响 |
|
||||
|----|------|------|
|
||||
| P1-1 | `kernel_commands.rs` 2185 行 | 可维护性 |
|
||||
| P1-2 | `gateway-client.ts` 53 处 Promise\<any\> | 类型安全盲区 |
|
||||
| P1-3 | 连接池 max=20 偏小 | 高并发不足 |
|
||||
| P1-4 | relay_tasks 缺复合索引 | 查询性能 |
|
||||
| P1-5 | Scheduler 循环不响应 shutdown | 优雅停机不完整 |
|
||||
| P1-6 | `saas-config.toml` 含明文密码 | 安全风险 |
|
||||
| P1-7 | Cookie Secure 在 localhost 失效 | 开发环境认证失败 |
|
||||
| P1-8 | 登录缺暴力破解保护 | 安全风险 |
|
||||
| P1-9 | `zclaw-protocols` 仅 5 个测试 | 回归风险 |
|
||||
|
||||
### P2 — 可以改进
|
||||
|
||||
| ID | 问题 | 影响 |
|
||||
|----|------|------|
|
||||
| P2-1 | 多个文件 >800 行 | 代码组织 |
|
||||
| P2-2 | 角色权限缓存无失效机制 | 降权不即时生效 |
|
||||
| P2-3 | `sqlx-postgres 0.7.4` 未来兼容性 | 编译噪音 |
|
||||
| P2-4 | SaaS 定时任务执行未闭环 | 功能不完整 |
|
||||
| P2-5 | `scheduled_tasks` 路径缺 `/v1` 前缀 | API 一致性 |
|
||||
| P2-6 | OTA 提示词 N+1 查询 | 性能 |
|
||||
|
||||
---
|
||||
|
||||
## 八、架构优势
|
||||
|
||||
1. **SaaS 独立部署** — 不依赖 Kernel,可独立扩展
|
||||
2. **Feature gate 分离** — multi-agent 功能可选
|
||||
3. **Cookie + Header 双路径认证** — 向后兼容 + 安全
|
||||
4. **声明式 Scheduler** — TOML 配置驱动
|
||||
5. **参数化 SQL 全覆盖** — 零注入风险
|
||||
6. **连接池健康检查** — 80% 水位自动降级
|
||||
7. **Argon2id 密码哈希** — 业界最佳实践
|
||||
8. **审计日志全覆盖** — 所有关键操作 + IP
|
||||
9. **SSE 背压设计** — bounded channel 防内存溢出
|
||||
|
||||
---
|
||||
|
||||
*审计完成。5 个并行子代理深度审计,覆盖架构/代码/安全/性能/业务全维度。*
|
||||
258
docs/archive/old-audits/audit-2026-03-31-system-assessment.md
Normal file
@@ -0,0 +1,258 @@
|
||||
# ZCLAW 系统评估报告
|
||||
|
||||
> **评估日期**: 2026-03-31
|
||||
> **评估范围**: SaaS 后端 (Axum) + Admin V2 (React/Ant Design) + Desktop (Tauri/React/Zustand)
|
||||
> **系统定位**: LLM Token 池中转管理 + 行业 Agent 模板分发
|
||||
|
||||
---
|
||||
|
||||
## 1. 总览
|
||||
|
||||
### 系统健康度
|
||||
|
||||
| 子系统 | 状态 | 端点 | 编译/类型检查 | 评估 |
|
||||
|--------|------|------|-------------|------|
|
||||
| SaaS 后端 | 运行中 | localhost:8080 | `cargo check` 通过 | 良好 |
|
||||
| Admin V2 | 运行中 | localhost:5173 | `tsc --noEmit` 通过 | 良好 |
|
||||
| Desktop | 运行中 | localhost:1420 | 计划文件零错误; 有遗留重构错误 | 基本可用 |
|
||||
|
||||
### 发现汇总
|
||||
|
||||
| 严重级别 | SaaS 后端 | Admin V2 | Desktop |
|
||||
|----------|-----------|----------|---------|
|
||||
| Critical | 0 | 0 | 0 |
|
||||
| High | 1 | 3 | 2 |
|
||||
| Medium | 5 | 8 | 7 |
|
||||
| Low | 3 | 8 | 4 |
|
||||
| **合计** | **9** | **19** | **13** |
|
||||
|
||||
---
|
||||
|
||||
## 2. SaaS 后端评估
|
||||
|
||||
### 2.1 路由覆盖
|
||||
|
||||
**总计 69 条路由** (5 公开 + 64 受保护)
|
||||
|
||||
| 模块 | 路由数 | CRUD 完整性 |
|
||||
|------|--------|-------------|
|
||||
| Auth | 8 | 登录/注册/刷新/登出/密码/TOTP |
|
||||
| Account | 12 | CRUD + 状态管理 + Token + 日志 + Dashboard + 设备 |
|
||||
| Model Config | 15 | Provider/Model/ApiKey CRUD + 用量统计 |
|
||||
| Relay | 9 | 中转任务 + Key Pool 管理 |
|
||||
| Config | 11 | 配置迁移/同步/差异分析 |
|
||||
| Role | 10 | 角色 CRUD + 权限模板 |
|
||||
| Prompt | 10 | 提示词 CRUD + 版本管理 |
|
||||
| Agent Template | 7 | 模板 CRUD + /available + /full |
|
||||
| Scheduler | 5 | 定时任务 CRUD |
|
||||
| Telemetry | 4 | 上报 + 统计 |
|
||||
|
||||
### 2.2 安全评估
|
||||
|
||||
**正面发现:**
|
||||
- 全量参数化查询 (sqlx bind),无 SQL 注入风险
|
||||
- SSRF 防护: `validate_provider_url()` 拦截私网 IP、十六进制/八进制混淆
|
||||
- Argon2id 密码哈希 (spawn_blocking 避免阻塞异步运行时)
|
||||
- AES-256-GCM 加密 TOTP 密钥和 Provider API Key
|
||||
- Refresh Token 单次使用 + DB 撤销
|
||||
- TOTP 暴力破解防护: 5次/10分钟/账户
|
||||
- Cookie: HttpOnly + SameSite=Strict + Secure (生产环境)
|
||||
- CORS: 生产环境空白名单直接 panic 拒绝启动
|
||||
- JWT 密钥: release 编译无 `ZCLAW_SAAS_JWT_SECRET` 拒绝启动
|
||||
- 请求体限制: 1MB
|
||||
- TCP keepalive + 短 SO_LINGER 防止 CLOSE_WAIT
|
||||
|
||||
**发现的问题:**
|
||||
|
||||
| 级别 | 问题 | 位置 |
|
||||
|------|------|------|
|
||||
| **High** | `X-Forwarded-For` 头信任 — 攻击者可伪造 IP 绕过限流 | `middleware.rs:138-142` |
|
||||
| Medium | 内存限流不跨重启持久化,多实例部署时无效 | `middleware.rs` |
|
||||
| Medium | `format!("SELECT ... FROM {}", table)` — 当前安全但模式脆弱 | `db.rs:852,858` |
|
||||
| Medium | `.and_hms_opt(0,0,0).unwrap()` 多处 — 理论上安全但不防御 | `model_config/service.rs:441` |
|
||||
| Medium | scheduler spawn 中 `_db` 克隆后未使用 | `scheduler.rs:46` |
|
||||
| Medium | SCHEMA_VERSION=9 但仅 5 个迁移文件 — 可能混淆 | `db.rs:7` |
|
||||
| Low | Demo 种子明文 API Key — 仅限 demo 场景 | `db.rs:467-471` |
|
||||
| Low | `#[allow(dead_code)]` 标记的保留函数 | `auth/handlers.rs:499` |
|
||||
| Low | SQL 分割器中 `.unwrap()` | `db.rs:127` |
|
||||
|
||||
### 2.3 新功能验证
|
||||
|
||||
| 功能 | 状态 | 说明 |
|
||||
|------|------|------|
|
||||
| `accounts.llm_routing` 列 | ✅ | 迁移 + CRUD + 登录响应全部接入 |
|
||||
| `/agent-templates/available` | ✅ | 轻量公开列表端点 |
|
||||
| `/agent-templates/:id/full` | ✅ | 完整模板端点 |
|
||||
| Agent 模板 9 个扩展字段 | ✅ | soul_content, scenarios, welcome_message 等 |
|
||||
| Key Pool LRU 排序 | ✅ | `ORDER BY priority, total_requests ASC` |
|
||||
| Key Pool 清理定时任务 | ✅ | 24h 周期清理 key_usage_window |
|
||||
| 6 个行业种子模板 | ✅ | Coder/Writer/Analyst/Researcher/Translator/Medical |
|
||||
|
||||
---
|
||||
|
||||
## 3. Admin V2 前端评估
|
||||
|
||||
### 3.1 页面清单
|
||||
|
||||
**12 个页面**, 使用 React Query 管理服务端状态, Zustand 仅用于 auth store, 其余均为 `useState`。
|
||||
|
||||
### 3.2 类型安全
|
||||
|
||||
- TypeScript 严格模式启用
|
||||
- `noUnusedLocals` + `noUnusedParameters` 启用
|
||||
- 整个代码库仅 1 处 `any` (Providers.tsx:69)
|
||||
- 可选字段正确标记
|
||||
- 前后端类型基本对齐
|
||||
|
||||
### 3.3 发现的问题
|
||||
|
||||
| 级别 | 问题 | 位置 |
|
||||
|------|------|------|
|
||||
| **High** | 未使用的 `@ant-design/charts` 依赖增加包体积 | `package.json:13` |
|
||||
| **High** | `any` 类型在 addKeyMutation | `Providers.tsx:69` |
|
||||
| **High** | Token 刷新竞态 — 刷新失败时 pending 请求未 reject | `request.ts:96-99` |
|
||||
| Medium | 6 个表格无搜索/筛选功能 | Accounts/Models/Providers 等 |
|
||||
| Medium | 服务端分页不同步本地状态 | Accounts/Models/Providers 等 |
|
||||
| Medium | Agent Template 详情 Modal 缺少扩展字段展示 | `AgentTemplates.tsx:189-210` |
|
||||
| Medium | Config 内联编辑无加载指示器 | `Config.tsx:51` |
|
||||
| Medium | Dashboard 统计卡片加载时布局跳动 | `Dashboard.tsx:93` |
|
||||
| Medium | 网络错误未包装为 `ApiRequestError` | `request.ts:115` |
|
||||
| Medium | configService 返回格式不一致 | `services/config.ts:6` |
|
||||
| Medium | Key Pool 变更丢弃错误详情 | `Providers.tsx:78,88,98` |
|
||||
| Low | Model 类型缺少 `created_at`/`updated_at` | `types/index.ts:65-77` |
|
||||
| Low | 所有表格禁用 page size 切换 | 所有 ProTable 页面 |
|
||||
| Low | Login 页面固定 480px 非响应式 | `Login.tsx:79` |
|
||||
| Low | Config 点击值缺少 hover 视觉反馈 | `Config.tsx:62` |
|
||||
| Low | OperationLog/PromptVersion 类型微小不匹配 | `types/index.ts` |
|
||||
| Low | `@ant-design/pro-layout` 与 pro-components 冗余 | `package.json:17` |
|
||||
| Low | `AgentTemplateAvailable` 类型已定义但未消费 | `types/index.ts:243-250` |
|
||||
|
||||
### 3.4 新功能验证
|
||||
|
||||
| 功能 | 状态 | 说明 |
|
||||
|------|------|------|
|
||||
| Accounts LLM 路由模式列 | ✅ | Tag 组件 + valueEnum |
|
||||
| Accounts 编辑 Modal 路由下拉 | ✅ | relay/local Select |
|
||||
| Providers Key Pool CRUD | ✅ | 添加/启用禁用/删除全部可用 |
|
||||
| Agent Template 扩展字段表单 | ✅ | emoji/personality/soul_content 等 |
|
||||
| Agent Template 详情 Modal | ⚠️ | 缺少扩展字段展示 |
|
||||
|
||||
---
|
||||
|
||||
## 4. Desktop 前端评估
|
||||
|
||||
### 4.1 Store 架构
|
||||
|
||||
**14 个 Zustand Store**, 模块化拆分完成。核心协调中心为 `connectionStore`。
|
||||
|
||||
### 4.2 新功能验证
|
||||
|
||||
| 功能 | 状态 | 说明 |
|
||||
|------|------|------|
|
||||
| saas-types 模板类型 | ✅ | AgentTemplateAvailable + AgentTemplateFull |
|
||||
| saas-client 模板 API | ✅ | fetchAvailableTemplates + fetchTemplateFull |
|
||||
| saasStore 模板状态 | ✅ | availableTemplates + fetchAvailableTemplates |
|
||||
| connectionStore 路由优先级 | ✅ | admin llm_routing 覆盖 localStorage |
|
||||
| agentStore.createFromTemplate | ✅ | Clone + SOUL.md 持久化 |
|
||||
| Wizard Step 0 模板选择 | ✅ | Grid 布局 + 空白 Agent 选项 |
|
||||
|
||||
### 4.3 发现的问题
|
||||
|
||||
| 级别 | 问题 | 位置 |
|
||||
|------|------|------|
|
||||
| **High** | 模板 Grid 非响应式 — 使用 `getState()` 而非 React hook | `AgentOnboardingWizard.tsx:387` |
|
||||
| **High** | adminRouting 从 localStorage 解析无验证 | `connectionStore.ts:358-372` |
|
||||
| Medium | 8 处 `console.log/warn` 在生产 store 中 | `agentStore.ts`, `handStore.ts` |
|
||||
| Medium | sessionStore 假设 GatewayClient 不适配 KernelClient | `sessionStore.ts:225` |
|
||||
| Medium | ChatStore persist partialize 日期序列化 | `chatStore.ts:703` |
|
||||
| Medium | OfflineStore 健康检查 interval 清理风险 | `offlineStore.ts:347` |
|
||||
| Medium | 硬编码中文错误消息 (无 i18n) | `saasStore.ts`, `connectionStore.ts` |
|
||||
| Medium | gateway-api.ts / kernel-hands.ts 有 TS 错误 | 之前重构遗留 |
|
||||
| Low | gatewayStore facade 订阅所有 store 引起过多渲染 | `gatewayStore.ts:67-76` |
|
||||
| Low | Store 初始化 setTimeout 时序问题 | `store/index.ts:89-92` |
|
||||
| Low | deprecated `secureStorageSync` 仍导出 | `secure-storage.ts:306-330` |
|
||||
| Low | SkillInfo 类型微小不匹配 | `configStore.ts:638-665` |
|
||||
|
||||
### 4.4 安全评估
|
||||
|
||||
- SaaS Token: OS keyring 存储 + 加密 localStorage fallback — 合理
|
||||
- Legacy 明文 Token 清理逻辑存在
|
||||
- API Key: secureStorage 存储带格式验证 + 哈希
|
||||
- Master encryption key 在无 keyring 时存 localStorage — 降级方案
|
||||
- authToken 始终为 null 在 Zustand state — 仅在 saasClient 内存中持有
|
||||
|
||||
---
|
||||
|
||||
## 5. 架构一致性验证
|
||||
|
||||
### 设计规格 vs 实现
|
||||
|
||||
基于 `docs/superpowers/specs/2026-03-30-saas-positioning-design.md` 逐项核对:
|
||||
|
||||
| 设计要求 | 实现状态 | 说明 |
|
||||
|----------|----------|------|
|
||||
| 账号级 LLM 路由 (relay/local) | ✅ 完成 | accounts.llm_routing 列 + CRUD + 登录响应 |
|
||||
| Admin 配置路由模式 | ✅ 完成 | Accounts 页编辑 Modal 有下拉 |
|
||||
| Desktop 遵守路由模式 | ✅ 完成 | connectionStore 优先级覆盖 |
|
||||
| Token Pool 多 Key 轮转 | ✅ 完成 | LRU 排序 + RPM/TPM 限制 |
|
||||
| Key Pool Admin 管理 | ✅ 完成 | 添加/启用禁用/删除 |
|
||||
| 行业模板扩展字段 | ✅ 完成 | 9 个新字段 (soul_content 等) |
|
||||
| /available 端点 | ✅ 完成 | 轻量公开列表 |
|
||||
| /full 端点 | ✅ 完成 | 完整模板数据 |
|
||||
| Desktop 模板消费 | ✅ 完成 | fetchAvailableTemplates + fetchTemplateFull |
|
||||
| Agent 首次创建选模板 | ✅ 完成 | Wizard Step 0 Grid |
|
||||
| SOUL.md 注入 | ✅ 完成 | createFromTemplate 持久化 |
|
||||
| 模板不覆盖已成长 Agent | ✅ 完成 | 仅在创建时使用 |
|
||||
|
||||
**结论: 设计规格 12/12 项全部实现。**
|
||||
|
||||
---
|
||||
|
||||
## 6. 优先修复建议
|
||||
|
||||
### P0 — 立即修复 (安全/稳定性)
|
||||
|
||||
1. **Token 刷新竞态** (`request.ts:96-99`): 刷新失败时 reject 所有 pending 请求
|
||||
2. **X-Forwarded-For 信任** (`middleware.rs:138-142`): 限制仅信任已知代理 IP
|
||||
|
||||
### P1 — 近期修复 (功能完整性)
|
||||
|
||||
3. **模板 Grid 响应式** (`AgentOnboardingWizard.tsx:387`): 使用 `useSaaSStore()` hook 替代 `getState()`
|
||||
4. **Agent Template 详情 Modal** (`AgentTemplates.tsx`): 补充扩展字段展示
|
||||
5. **adminRouting 解析验证** (`connectionStore.ts:358`): 对 localStorage 解析结果做类型校验
|
||||
6. **清理 `@ant-design/charts` 未使用依赖**
|
||||
|
||||
### P2 — 中期优化 (代码质量)
|
||||
|
||||
7. **统一分页状态管理** — Admin 多个表格页
|
||||
8. **添加表格搜索/筛选功能** — 至少 Accounts/Models/Providers
|
||||
9. **修复 gateway-api.ts / kernel-hands.ts TS 错误** — 之前重构遗留
|
||||
10. **替换 store 中的 console.log** — 使用 createLogger
|
||||
11. **Config 页内联编辑加载指示**
|
||||
|
||||
### P3 — 长期改进
|
||||
|
||||
12. **内存限流 → Redis/PostgreSQL 持久化限流** (多实例部署准备)
|
||||
13. **i18n 框架** (当前所有中文硬编码)
|
||||
14. **单元测试** — Admin V2 和 Desktop 目前零测试覆盖
|
||||
15. **统一 SAAS_SCHEMA_VERSION 管理** (减少迁移文件与版本号的不一致困惑)
|
||||
|
||||
---
|
||||
|
||||
## 7. 结论
|
||||
|
||||
**系统整体评价: 良好 (B+)**
|
||||
|
||||
**优势:**
|
||||
- 后端安全实践优秀: 参数化查询、SSRF 防护、密钥加密、Cookie 安全
|
||||
- 设计规格 100% 实现,无遗漏
|
||||
- Admin V2 TypeScript 严格模式,仅 1 处 `any`
|
||||
- 69 个 API 端点覆盖全面,权限控制细粒度
|
||||
- Desktop Store 架构清晰,14 个 store 模块化
|
||||
|
||||
**短板:**
|
||||
- Desktop 有遗留 TS 错误未修复 (gateway-api.ts, kernel-hands.ts)
|
||||
- Admin V2 缺少搜索/筛选功能影响可用性
|
||||
- Token 刷新竞态条件需立即修复
|
||||
- 零测试覆盖 (Admin V2 + Desktop)
|
||||
- Agent Template 详情展示不完整
|
||||
113
docs/archive/old-design/openfang-integration-strategy.md
Normal file
@@ -0,0 +1,113 @@
|
||||
# Design: ZCLAW 集成策略论证
|
||||
|
||||
Generated by /office-hours on 2026-03-22
|
||||
Branch: unknown
|
||||
Repo: ZClaw_zclaw
|
||||
Status: DRAFT
|
||||
Mode: Builder
|
||||
|
||||
## 问题陈述
|
||||
|
||||
当前 ZCLAW 依赖外部 ZCLAW 二进制作为运行时后端,导致:
|
||||
1. 需要管理 ZCLAW 二进制文件的下载、安装、版本兼容性
|
||||
2. ZCLAW 进程崩溃或锁定会影响 ZCLAW 全部功能
|
||||
3. 两个独立进程间通过 WebSocket/REST 通信,引入复杂性和潜在故障点
|
||||
4. 调试困难 - 问题可能在 ZCLAW 或 ZCLAW 任何一侧
|
||||
|
||||
## 现状架构
|
||||
|
||||
```
|
||||
ZCLAW Desktop (Tauri/Rust)
|
||||
├── React Frontend (端口 1420)
|
||||
└── ZCLAW Gateway (端口 50051) ← 外部进程
|
||||
```
|
||||
|
||||
通信方式:
|
||||
- Tauri Commands → 启动/停止 ZCLAW 进程
|
||||
- WebSocket → 前端与 ZCLAW 对话
|
||||
- REST API → 健康检查、配置
|
||||
|
||||
## 集成方案对比
|
||||
|
||||
### Approach A: 保持现状(外部进程)
|
||||
|
||||
**Summary:** 继续使用外部 ZCLAW 二进制,通过进程管理集成
|
||||
|
||||
**Effort:** S
|
||||
**Risk:** Low
|
||||
**Pros:**
|
||||
- ZCLAW 可以独立开发和升级
|
||||
- 不用重新编译 ZCLAW 核心代码
|
||||
- 职责分离清晰
|
||||
**Cons:**
|
||||
- 依赖管理复杂(版本、下载、锁文件)
|
||||
- 两个进程通信引入延迟和故障点
|
||||
- 用户需要安装两个组件
|
||||
|
||||
### Approach B: 源码集成(ZCLAW 作为 Tauri Submodule)
|
||||
|
||||
**Summary:** 将 ZCLAW 源码作为 git submodule,在构建时静态编译进 Tauri 应用
|
||||
|
||||
**Effort:** XL
|
||||
**Risk:** High
|
||||
**Pros:**
|
||||
- 单个二进制,简化分发
|
||||
- 版本锁定,完全可控
|
||||
- 可以深度定制 ZCLAW 行为
|
||||
**Cons:**
|
||||
- ZCLAW 代码库庞大(~50万行 Rust)
|
||||
- 编译时间大幅增加
|
||||
- 升级困难 - 需要手动同步 submodule
|
||||
- 失去 ZCLAW 独立升级的灵活性
|
||||
|
||||
### Approach C: gRPC Service 集成(推荐)
|
||||
|
||||
**Summary:** 将 ZCLAW 核心功能封装为 Rust crate/ZCLAW library,通过内部 API 调用而非进程通信
|
||||
|
||||
**Effort:** M
|
||||
**Risk:** Medium
|
||||
**Pros:**
|
||||
- 保留 ZCLAW 作为独立模块(可用作其他项目的库)
|
||||
- 去掉进程启动/管理复杂性
|
||||
- 同一进程内通信,无网络开销
|
||||
- 可以精确控制 ZCLAW API 表面
|
||||
**Cons:**
|
||||
- 仍然需要编译 ZCLAW 源码
|
||||
- API 版本管理需要同步
|
||||
- 深度集成可能失去某些运行时灵活性
|
||||
|
||||
## 核心问题分析
|
||||
|
||||
| 问题 | 根因 | 解决方案 |
|
||||
|------|------|----------|
|
||||
| 数据库锁 | 多个 ZCLAW 进程争用 | 确保单实例 + 正确清理 |
|
||||
| 启动失败 | Tauri 命令未正确调用 | 修复 IPC 调用链 |
|
||||
| 版本兼容 | 外部二进制 | 版本锁定 + 自动化下载 |
|
||||
|
||||
## 推荐方案
|
||||
|
||||
**Approach C: gRPC Service 集成**
|
||||
|
||||
理由:
|
||||
1. 平衡了"完全独立"和"深度集成"的优缺点
|
||||
2. 可以逐步迁移 - 先解决启动问题,再考虑集成深度
|
||||
3. 保留 ZCLAW 可测试性和可插拔性
|
||||
|
||||
## 下一步行动
|
||||
|
||||
1. **立即修复**:诊断并修复当前 ZCLAW 启动失败问题
|
||||
2. **短期**:添加启动失败时的详细错误日志
|
||||
3. **中期**:评估 gRPC 集成工作量
|
||||
4. **长期**:根据实际使用情况决定集成深度
|
||||
|
||||
## 待解决问题
|
||||
|
||||
1. ZCLAW 为何拒绝启动?(数据库锁的根因是什么?)
|
||||
2. Tauri 是否正确检测并处理 ZCLAW 启动失败?
|
||||
3. 用户实际使用场景是否需要 ZCLAW 独立运行?
|
||||
|
||||
## 成功标准
|
||||
|
||||
- [ ] `pnpm start:dev` 能可靠启动完整服务栈
|
||||
- [ ] ZCLAW 启动失败时提供有意义的错误信息
|
||||
- [ ] 评估三种方案的维护成本
|
||||
189
docs/archive/old-directives/STABILIZATION_DIRECTIVE.md
Normal file
@@ -0,0 +1,189 @@
|
||||
# ZCLAW 稳定化指令 v1.0
|
||||
|
||||
> **生效日期**: 2026-04-02
|
||||
> **状态**: ✅ 已完成(2026-04-03) — 降级为建议级别
|
||||
> **目标**: 将系统从"功能堆叠模式"切换到"端到端可用模式"
|
||||
> **结论**: 7 项完成标准全部达标,稳定化阶段结束。本文件保留作为历史记录和后续质量参考。
|
||||
|
||||
---
|
||||
|
||||
## 0. 核心原则
|
||||
|
||||
**新增功能冻结。** 在以下 P0 问题全部修复之前,不接受任何新功能 PR。
|
||||
|
||||
```
|
||||
判断标准:这个改动是否让用户今天就能用上?
|
||||
- 是 → 可以做
|
||||
- 否 → 记录到 backlog,不做
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 1. P0 紧急修复(阻塞一切)
|
||||
|
||||
| ID | 问题 | 文件 | 修复方案 |
|
||||
|----|------|------|----------|
|
||||
| SEC2-P0-01 | skill_execute 反序列化崩溃 | `desktop/src/lib/kernel-skills.ts:110-114` + `desktop/src-tauri/src/kernel_commands/skill.rs:290-296` | 前端传入真实 agentId/sessionId,或 Rust 端改为 `Option<String>` |
|
||||
| SEC2-P0-02 | TaskTool::default() panic | `crates/zclaw-runtime/src/tool/builtin/task.rs:59` | 移除 `impl Default for TaskTool`,或提供合理默认值 |
|
||||
|
||||
**验收标准**: 用户能在 UI 中执行一个 Skill 且不崩溃。
|
||||
|
||||
---
|
||||
|
||||
## 2. P1 集成修复(接通断链)
|
||||
|
||||
按以下顺序修复,每个修复后立即验证端到端:
|
||||
|
||||
### 2.1 API 路径对齐
|
||||
| ID | 问题 | 修复 |
|
||||
|----|------|------|
|
||||
| SEC2-P1-02 | agent-templates 缺少 /api/v1 前缀 | `saas-client.ts:376,384` 添加前缀 |
|
||||
| V11-P1-01 | trigger_update 参数格式不匹配 | `kernel-triggers.ts:99` 展开嵌套对象 |
|
||||
|
||||
### 2.2 事件监听补全
|
||||
| ID | 问题 | 修复 |
|
||||
|----|------|------|
|
||||
| SEC2-P1-03 | hand-execution-complete 无前端监听 | ChatArea/RightPanel 添加 `listen()` |
|
||||
|
||||
### 2.3 静默错误消除
|
||||
将所有 `let _ =` 错误忽略改为至少 `log::warn!`,逐个评估是否需要用户可见反馈:
|
||||
- HandRun 持久化 (3 处) — **已修复**
|
||||
- FTS 索引更新 — **已修复**
|
||||
- Worker dispatch — **已修复**
|
||||
- Billing key usage — **已修复**(移除冗余 `let _ =`)
|
||||
- Relay SSE error send — **已修复**(改为 if-let + debug log)
|
||||
|
||||
### 2.4 FactStore 实现
|
||||
- 方案 A: `MemoryStore` 实现 `FactStore` trait
|
||||
- 方案 B: 移除 `FactStore` trait,直接用 `MemoryStore` 方法
|
||||
- **已选 B** — 移除死 trait,保留值类型(已修复 SEC2-P1-01)
|
||||
|
||||
---
|
||||
|
||||
## 3. 死代码清理
|
||||
|
||||
### 3.1 删除(确认无引用后)
|
||||
|
||||
| 文件 | 行数 | 状态 |
|
||||
|------|------|------|
|
||||
| `desktop/src/lib/audit-logger.ts` | 170 | **已删除** |
|
||||
| `desktop/src/lib/saas-admin.ts` | 234 | 已在之前清理中删除 |
|
||||
| `desktop/src/lib/gateway-reconnect.ts` | ~100 | **已删除** (零生产引用) |
|
||||
| `admin/` 目录 | ~整目录 | **已删除** (空目录壳) |
|
||||
| `admin-temp-dir/` 目录 | ~整目录 | **已删除** |
|
||||
| `crates/zclaw-channels/` | Cargo.toml only | 已在之前清理中删除 |
|
||||
| `docs/analysis/ISSUE-TRACKER.md` | - | **已删除** |
|
||||
| `.superpowers/plans/` | - | 已不存在 |
|
||||
|
||||
### 3.2 Feature-gate 清理
|
||||
|
||||
| 模块 | 行数 | 处理 |
|
||||
|------|------|------|
|
||||
| Director (multi-agent) | 912 | **已标注** — "gated behind multi-agent feature" |
|
||||
| A2A 协议 | ~400 | **已标注** — feature gate 注释完整 |
|
||||
| WASM runner | ~200 | **已标注** — "Active module — fully implemented" |
|
||||
| OFP capability variants | ~10 | **已修复** — 3 个方法改为穷举匹配,grants() 保留通配符+注释 |
|
||||
|
||||
### 3.3 未连接的 Tauri 命令
|
||||
|
||||
24 个 Tauri 命令无前端调用(经二次审计修正)。不删除 Rust 代码,但:
|
||||
- **已完成**: 171/171 个命令已标注 `// @connected` 或 `// @reserved: 暂无前端集成`
|
||||
- 二次审计修正 19 个误标命令(8+11),当前 147 @connected / 24 @reserved
|
||||
|
||||
---
|
||||
|
||||
## 4. 文档真相校准
|
||||
|
||||
### 4.1 数值修正
|
||||
|
||||
| 指标 | 当前文档值 | 实际值 | 状态 |
|
||||
|------|-----------|--------|------|
|
||||
| Skills | 66/75/77 | **75** | **已校准** (TRUTH.md) |
|
||||
| Hands | 11 | **9 启用 + 2 禁用** | **已校准** (CLAUDE.md) |
|
||||
| Tauri 命令 | 58+/130+ | **171** | **已校准** + 171 个已标注(147 @connected / 24 @reserved) |
|
||||
| SaaS 路由 | 72+ | **93**(含 2 dev-only mock) | **已校准** |
|
||||
| 前端测试 | 1 文件 | **21 文件** | **已校准** (TRUTH.md) |
|
||||
| Zustand Store | 15 | **18** | **已校准** (TRUTH.md) |
|
||||
| Admin V2 页面 | 11 | **13** | **已校准** (TRUTH.md) |
|
||||
|
||||
### 4.2 文档归档
|
||||
|
||||
以下审计报告已从 `docs/` 根目录移除(已归档或已删除):
|
||||
- COMPREHENSIVE_AUDIT_V5~V9(5 个文件,已被 V10/V11 取代)**已完成**
|
||||
- AUDIT_TRACKER.md **已完成**
|
||||
- VERIFICATION_REPORT.md **已完成**
|
||||
- FEATURE_AUDIT_REPORT.md **已完成**
|
||||
- FRONTEND_INTEGRATION_AUDIT.md **已完成**
|
||||
- DEEP_AUDIT_REPORT.md **已完成**
|
||||
- JOINT_DEBUG_REPORT_V1.md **已完成**
|
||||
- QA_REVIEW_V1.md **已完成**
|
||||
|
||||
### 4.3 ISSUED-TRACKER 重置
|
||||
|
||||
创建新的 `docs/TRUTH.md`,只记录:
|
||||
- 实际可工作的端到端功能清单
|
||||
- 已知缺陷清单(来自 V11 审计)
|
||||
- 每次修复后更新此文件
|
||||
|
||||
---
|
||||
|
||||
## 5. 前端测试底线
|
||||
|
||||
在 P0/P1 修复完成后,为以下关键路径添加最基本测试:
|
||||
|
||||
1. **Skill 执行** — 调用 → 不崩溃 → 返回结果
|
||||
2. **Hand 触发** — emit event → 前端收到通知
|
||||
3. **消息发送** — Store → invoke → 流式响应
|
||||
4. **配置同步** — SaaS pull → Store 更新
|
||||
|
||||
目标:从 1 个测试文件提升到至少覆盖 4 条核心路径。
|
||||
|
||||
---
|
||||
|
||||
## 6. 禁止事项
|
||||
|
||||
在稳定化完成前,以下行为被禁止:
|
||||
|
||||
| 行为 | 原因 |
|
||||
|------|------|
|
||||
| 新增 SaaS API 端点 | 已有 93 个,前端只调用了一部分 |
|
||||
| 新增 SKILL.md 文件 | 已有 75 个,大部分未被调用 |
|
||||
| 新增 Tauri 命令 | 已有 171 个,24 个无前端调用 |
|
||||
| 新增中间件 | 已有 11 层,足够 |
|
||||
| 扩展 Pipeline 模板 | 已有 10 个行业模板 |
|
||||
| 新增 Zustand Store | 已有 18 个 |
|
||||
| 新增 admin 页面 | 已有 11 个 |
|
||||
|
||||
**唯一例外**: 修复 P0/P1 问题需要的新代码。
|
||||
|
||||
---
|
||||
|
||||
## 7. 完成标准
|
||||
|
||||
稳定化阶段完成的定义:
|
||||
|
||||
- [x] P0 全部修复,用户可执行 Skill 不崩溃
|
||||
- [x] P1 集成修复完成,hand-execution-complete 有监听
|
||||
- [x] 死代码清理完成,至少删除 5 个孤立文件
|
||||
- [x] `docs/TRUTH.md` 创建并反映真实状态
|
||||
- [x] 文档数值与代码一致
|
||||
- [x] 前端测试覆盖 4 条核心路径
|
||||
- [x] `cargo check --workspace` 通过 + `pnpm tsc --noEmit` 通过
|
||||
|
||||
达到以上标准后,本指令自动降级为"建议"级别,恢复正常功能开发。
|
||||
|
||||
**2026-04-03 确认**: 全部 7 项标准已达标。功能冻结解除,恢复正常的迭代开发节奏。后续新增功能仍需遵循 CLAUDE.md §1.2 的决策原则("这对用户今天能产生价值吗?")。
|
||||
|
||||
---
|
||||
|
||||
## 8. 执行节奏
|
||||
|
||||
每个修复独立提交,格式:
|
||||
|
||||
```
|
||||
fix(<scope>): <描述>
|
||||
|
||||
Stabilization: SEC2-P0-01
|
||||
```
|
||||
|
||||
不批量提交。每个修复可独立 revert。
|
||||
136
docs/archive/old-handoffs/2024-03-20-store-migration.md
Normal file
@@ -0,0 +1,136 @@
|
||||
# Store Migration Progress Report
|
||||
|
||||
**Date:** 2024-03-20
|
||||
**Status:** P0 Complete, P1 In Progress
|
||||
|
||||
## Summary
|
||||
|
||||
Successfully migrated all 14 components from `useGatewayStore` to domain-specific stores.
|
||||
|
||||
## Completed Tasks
|
||||
|
||||
### P0: Critical Path
|
||||
| Task | Status | Details |
|
||||
|------|--------|---------|
|
||||
| Store Migration | ✅ Complete | 14 components migrated |
|
||||
| gateway-client.ts Split | ✅ Complete | 4 modules: api, auth, storage, types |
|
||||
| E2E Verification | ✅ Complete | 312 tests passing |
|
||||
|
||||
### P1: Quality Improvements
|
||||
| Task | Status | Details |
|
||||
|------|--------|---------|
|
||||
| viking-*.ts Cleanup | ✅ Complete | Archived to docs/archive/v1-viking-dead-code/ |
|
||||
| HeartbeatConfig UI | ✅ Complete | Integrated in SettingsLayout |
|
||||
| E2E Test Framework | 🔄 In Progress | Playwright config created |
|
||||
|
||||
## Migration Details
|
||||
|
||||
### Components Migrated
|
||||
1. **Security Components** (3)
|
||||
- SecurityStatus.tsx → useConnectionStore, useSecurityStore
|
||||
- AuditLogsPanel.tsx → useSecurityStore
|
||||
- SecurityLayersPanel.tsx → useSecurityStore
|
||||
|
||||
2. **Settings Components** (4)
|
||||
- General.tsx → useConnectionStore, useConfigStore, useChatStore
|
||||
- SettingsLayout.tsx → useSecurityStore
|
||||
- Skills.tsx → useConnectionStore, useConfigStore
|
||||
- IMChannels.tsx → useConfigStore, useConnectionStore, useAgentStore
|
||||
|
||||
3. **Automation Components** (4)
|
||||
- WorkflowEditor.tsx → useHandStore
|
||||
- AutomationPanel.tsx → useHandStore, useWorkflowStore
|
||||
- SchedulerPanel.tsx → useHandStore, useWorkflowStore, useAgentStore, useConfigStore
|
||||
- CreateTriggerModal.tsx → useHandStore, useWorkflowStore
|
||||
|
||||
4. **Other Components** (3)
|
||||
- RightPanel.tsx → useHandStore, useAgentStore
|
||||
- ChannelList.tsx → useConnectionStore, useConfigStore
|
||||
- TaskList.tsx → useHandStore, useConfigStore
|
||||
|
||||
### Store Architecture
|
||||
```
|
||||
connectionStore - Gateway connection state
|
||||
configStore - User configuration
|
||||
chatStore - Chat messages and state
|
||||
agentStore - Agent/clone management
|
||||
handStore - Hands and triggers
|
||||
workflowStore - Workflows
|
||||
securityStore - Security status and audit logs
|
||||
teamStore - Team collaboration
|
||||
```
|
||||
|
||||
## Test Results
|
||||
- **Unit Tests:** 312/312 passing
|
||||
- **TypeScript:** No errors
|
||||
- **E2E Framework:** Playwright configured, ready for expansion
|
||||
|
||||
## Next Steps
|
||||
1. ~~Expand E2E test coverage~~ ✅ Done (74 tests passing)
|
||||
2. ~~Implement Skill Market MVP (P2)~~ ✅ Already implemented
|
||||
3. Manual testing of full user flow
|
||||
|
||||
## P2: Skill Market MVP
|
||||
|
||||
**Status:** ✅ Already Complete
|
||||
|
||||
The Skill Market MVP was already fully implemented:
|
||||
|
||||
| Component | File | Status |
|
||||
|-----------|------|--------|
|
||||
| UI Component | `SkillMarket.tsx` | ✅ Complete |
|
||||
| State Store | `skillMarketStore.ts` | ✅ Complete |
|
||||
| Discovery Engine | `skill-discovery.ts` | ✅ Complete |
|
||||
| Types | `types/skill-market.ts` | ✅ Complete |
|
||||
| App Integration | `App.tsx` | ✅ Integrated |
|
||||
| Predefined Skills | 15 skills | ✅ Ready |
|
||||
|
||||
### Features
|
||||
- Browse skills by category
|
||||
- Search by keyword/capability
|
||||
- View skill details
|
||||
- Install/uninstall skills
|
||||
- AI-powered skill suggestions
|
||||
- Persistent installation state
|
||||
|
||||
## Technical Notes
|
||||
- All components now use selector pattern for Zustand
|
||||
- `useCompositeStore` deleted (was dead code)
|
||||
- `useGatewayStore` marked @deprecated, only used as compatibility layer
|
||||
|
||||
---
|
||||
|
||||
## 2026-03-20 Update
|
||||
|
||||
### Additional Work Completed
|
||||
|
||||
| Task | Status | Details |
|
||||
|------|--------|---------|
|
||||
| DevQALoop Integration | ✅ Complete | Integrated into TeamOrchestrator with new "Review" tab |
|
||||
| Integration Test Checklist | ✅ Complete | Created docs/testing/INTEGRATION-CHECKLIST.md with 22 test cases |
|
||||
| Component Status Analysis | ✅ Complete | Created docs/analysis/COMPONENT-INTEGRATION-STATUS.md |
|
||||
|
||||
### DevQALoop Integration Details
|
||||
|
||||
The DevQALoop component was previously implemented but not integrated into any parent component. Added:
|
||||
- New "Review" tab in TeamOrchestrator
|
||||
- Import of DevQALoopPanel component
|
||||
- Display of active Dev↔QA loops with iteration tracking
|
||||
- Start Review Loop button for teams with tasks and members
|
||||
|
||||
### Files Modified
|
||||
- `desktop/src/components/TeamOrchestrator.tsx` - Added Review view and DevQALoopPanel integration
|
||||
|
||||
### Files Created
|
||||
- `docs/testing/INTEGRATION-CHECKLIST.md` - Comprehensive integration test checklist
|
||||
- `docs/analysis/COMPONENT-INTEGRATION-STATUS.md` - Component integration status report
|
||||
|
||||
### Key Findings from Analysis
|
||||
|
||||
1. **PersonalitySelector** ✅ Already integrated via AgentOnboardingWizard
|
||||
2. **ScenarioTags** ✅ Already integrated via AgentOnboardingWizard
|
||||
3. **DevQALoop** ✅ Now integrated into TeamOrchestrator
|
||||
4. **HeartbeatConfig** ✅ Already integrated in SettingsLayout
|
||||
5. **CreateTriggerModal** ✅ Already migrated to useHandStore
|
||||
|
||||
The documentation in `ZCLAW-DEEP-ANALYSIS.md` underestimated the actual integration completeness. Most components were already integrated through indirect paths.
|
||||
133
docs/archive/old-handoffs/2026-03-21-phase1-security.md
Normal file
@@ -0,0 +1,133 @@
|
||||
# Phase 1: Security + Testing
|
||||
|
||||
> Date: 2026-03-21
|
||||
> Status: Complete
|
||||
|
||||
## Overview
|
||||
|
||||
This phase establishes the security foundation and testing framework for the ZCLAW architecture optimization project. It implements encrypted credential storage and enforces secure WebSocket connections.
|
||||
|
||||
## Changes
|
||||
|
||||
### Security Enhancements
|
||||
|
||||
#### 1. Encrypted localStorage Fallback (`secure-storage.ts`)
|
||||
|
||||
- **Issue**: Credentials were stored in plaintext in localStorage when OS keyring was unavailable
|
||||
- **Solution**: Implemented AES-GCM encryption for localStorage fallback
|
||||
- **Details**:
|
||||
- Added `crypto-utils.ts` with encryption/decryption functions
|
||||
- Uses PBKDF2 (100,000 iterations) for key derivation
|
||||
- Uses AES-GCM (256-bit) for encryption
|
||||
- Unique IV per encryption operation
|
||||
- Backward compatible with existing unencrypted data
|
||||
|
||||
#### 2. WSS Enforcement (`gateway-client.ts`)
|
||||
|
||||
- **Issue**: Non-localhost connections could use insecure `ws://` protocol
|
||||
- **Solution**: Block non-localhost connections that don't use WSS
|
||||
- **Details**:
|
||||
- Added `SecurityError` class for clear error handling
|
||||
- Added `validateWebSocketSecurity()` function
|
||||
- Throws error for `ws://` connections to non-localhost hosts
|
||||
- Allows `ws://` for localhost (development convenience)
|
||||
- Allows `wss://` for any host
|
||||
|
||||
### Testing Infrastructure
|
||||
|
||||
#### 1. Vitest Framework Setup
|
||||
|
||||
- Installed Vitest 2.1.8 with jsdom environment
|
||||
- Added @testing-library/react for component testing
|
||||
- Added @testing-library/jest-dom for DOM matchers
|
||||
- Configured coverage thresholds (60% initial target)
|
||||
|
||||
#### 2. Test Files Created
|
||||
|
||||
| File | Tests | Coverage |
|
||||
|------|-------|----------|
|
||||
| `crypto-utils.test.ts` | 10 | arrayToBase64, base64ToArray, encrypt, decrypt, deriveKey, generateMasterKey |
|
||||
| `secure-storage.test.ts` | 11 | Encryption fallback, backward compatibility, special characters |
|
||||
| `gateway-security.test.ts` | 13 | isLocalhost, WSS enforcement, SecurityError |
|
||||
| `chatStore.test.ts` | 39 | Messages, conversations, agents, streaming |
|
||||
|
||||
## Files Changed
|
||||
|
||||
### New Files
|
||||
|
||||
```
|
||||
desktop/
|
||||
├── src/lib/crypto-utils.ts # AES-GCM encryption utilities
|
||||
├── tests/lib/crypto-utils.test.ts # Encryption tests
|
||||
├── tests/lib/secure-storage.test.ts # Secure storage tests
|
||||
├── tests/lib/gateway-security.test.ts # WSS security tests
|
||||
├── tests/setup.ts # Vitest setup with mocks
|
||||
└── vitest.config.ts # Vitest configuration
|
||||
```
|
||||
|
||||
### Modified Files
|
||||
|
||||
```
|
||||
desktop/
|
||||
├── src/lib/secure-storage.ts # Added encryption fallback
|
||||
├── src/lib/gateway-client.ts # Added WSS enforcement
|
||||
└── package.json # Added test dependencies
|
||||
```
|
||||
|
||||
## Migration Notes
|
||||
|
||||
- **Automatic Migration**: Existing unencrypted localStorage data will be automatically migrated on first read
|
||||
- **No Manual Intervention**: The encryption/decryption is transparent to users
|
||||
- **Key Generation**: A master key is automatically generated and stored in localStorage
|
||||
|
||||
## Breaking Changes
|
||||
|
||||
### WSS Required for Remote Connections
|
||||
|
||||
- `ws://` protocol is no longer allowed for non-localhost connections
|
||||
- **Impact**: Users connecting to remote servers must use `wss://`
|
||||
- **Migration**: Update gateway URLs to use `wss://` protocol
|
||||
|
||||
```javascript
|
||||
// Before (now throws SecurityError)
|
||||
const client = new GatewayClient('ws://example.com:4200/ws');
|
||||
|
||||
// After (required)
|
||||
const client = new GatewayClient('wss://example.com:4200/ws');
|
||||
|
||||
// Localhost still works with ws://
|
||||
const client = new GatewayClient('ws://localhost:4200/ws'); // OK
|
||||
```
|
||||
|
||||
## Test Results
|
||||
|
||||
```
|
||||
Test Files 4 passed (4)
|
||||
Tests 73 passed (73)
|
||||
|
||||
New modules coverage:
|
||||
- crypto-utils.ts: 100%
|
||||
- secure-storage.ts: 95%+
|
||||
- gateway-security: 100%
|
||||
- chatStore.ts: 80%+
|
||||
```
|
||||
|
||||
## Security Verification
|
||||
|
||||
- [x] localStorage credentials encrypted (AES-GCM)
|
||||
- [x] Non-localhost connections require WSS
|
||||
- [x] Encryption keys not exposed in logs
|
||||
- [x] Backward compatible with unencrypted data
|
||||
- [x] Unique IV per encryption operation
|
||||
|
||||
## Next Steps (Phase 2)
|
||||
|
||||
- Domain reorganization
|
||||
- Migrate Chat Store to Valtio
|
||||
- Migrate Hands Store + XState
|
||||
- Enhance Intelligence caching
|
||||
- Extract shared modules
|
||||
|
||||
---
|
||||
|
||||
*Generated by Claude Code - Phase 1 Implementation*
|
||||
193
docs/archive/old-handoffs/WORK_SUMMARY_2026-03-16.md
Normal file
@@ -0,0 +1,193 @@
|
||||
# ZCLAW 工作总结 - 2026-03-16
|
||||
|
||||
## 完成的工作
|
||||
|
||||
### 1. OpenViking 本地服务器管理(隐私优先部署)
|
||||
|
||||
**问题**:用户可能有隐私顾虑,会话数据不能上传到远程服务器。
|
||||
|
||||
**解决方案**:实现本地 OpenViking 服务器管理功能。
|
||||
|
||||
#### 新增文件
|
||||
|
||||
| 文件 | 功能 |
|
||||
|------|------|
|
||||
| `desktop/src-tauri/src/viking_server.rs` | Rust 后端服务器管理(启动/停止/状态) |
|
||||
| `desktop/src/lib/viking-server-manager.ts` | TypeScript 服务器管理客户端 |
|
||||
| `desktop/src/lib/viking-adapter.ts` | 更新为多模式适配器(local/sidecar/remote) |
|
||||
|
||||
#### 功能特性
|
||||
|
||||
- **自动模式检测**:优先尝试本地服务器 → sidecar → remote
|
||||
- **隐私保证**:所有数据存储在 `~/.openviking/`,服务器只监听 `127.0.0.1`
|
||||
- **优雅降级**:当本地服务器不可用时自动回退
|
||||
|
||||
#### Tauri 命令
|
||||
|
||||
```rust
|
||||
viking_server_status() // 获取服务器状态
|
||||
viking_server_start() // 启动本地服务器
|
||||
viking_server_stop() // 停止服务器
|
||||
viking_server_restart() // 重启服务器
|
||||
```
|
||||
|
||||
### 2. 文档整理与归档
|
||||
|
||||
**之前**:文档散落在多个位置,文件名混乱(如 `greedy-prancing-cocke.md`)
|
||||
|
||||
**之后**:规范化文档结构
|
||||
|
||||
```
|
||||
docs/
|
||||
├── DEVELOPMENT.md # 开发指南
|
||||
├── OPENVIKING_INTEGRATION.md # OpenViking 集成文档(已更新)
|
||||
├── USER_MANUAL.md # 用户手册
|
||||
├── ZCLAW_AGENT_INTELLIGENCE_EVOLUTION.md # Agent 进化计划
|
||||
├── archive/ # 归档文档
|
||||
│ ├── completed-plans/ # 已完成的计划
|
||||
│ ├── research-reports/ # 研究报告
|
||||
│ └── zclaw-legacy/ # ZCLAW 遗留文档
|
||||
├── knowledge-base/ # 技术知识库
|
||||
│ ├── zclaw-technical-reference.md
|
||||
│ ├── zclaw-websocket-protocol.md
|
||||
│ └── ...
|
||||
├── plans/ # 执行计划
|
||||
└── test-reports/ # 测试报告
|
||||
```
|
||||
|
||||
### 3. 测试验证
|
||||
|
||||
| 测试类型 | 结果 |
|
||||
|---------|------|
|
||||
| TypeScript 编译 | ✅ 无错误 |
|
||||
| Viking Adapter 测试 | ✅ 21 passed |
|
||||
| Rust 测试 | ✅ 10 passed |
|
||||
| Cargo Build | ✅ 成功 |
|
||||
| OpenViking 服务器启动 | ✅ 成功(端口 1933) |
|
||||
| API 健康检查 | ✅ `/health` 返回 `{"status":"ok"}` |
|
||||
| 会话创建 | ✅ 成功 |
|
||||
| 消息添加 | ✅ 成功 |
|
||||
|
||||
## 提交记录
|
||||
|
||||
```
|
||||
c8202d0 feat(viking): add local server management for privacy-first deployment
|
||||
```
|
||||
|
||||
## 当前项目状态
|
||||
|
||||
### 已完成
|
||||
|
||||
- [x] Agent 智能层 Phase 1-3(274 passing tests)
|
||||
- [x] OpenViking 本地服务器管理
|
||||
- [x] 文档结构整理
|
||||
- [x] Python 3.12 安装(通过 winget)
|
||||
- [x] OpenViking pip 安装成功(v0.2.6)
|
||||
- [x] 火山引擎 API 密钥配置
|
||||
- [x] OpenViking 服务器启动验证
|
||||
- [x] 基础 API 测试(健康检查、会话创建、消息添加)
|
||||
- [x] **火山引擎 Embedding 模型激活** (`ep-20260316102010-cq422`)
|
||||
- [x] **向量搜索功能验证** ✅
|
||||
|
||||
### 进行中
|
||||
|
||||
- [ ] 多 Agent 协作 UI 产品化
|
||||
|
||||
### 待办
|
||||
|
||||
- [ ] RuntimeAdapter 接口抽象
|
||||
- [ ] 领域模型标准化
|
||||
|
||||
## OpenViking 集成状态
|
||||
|
||||
### 已验证功能
|
||||
|
||||
| 功能 | 状态 | 说明 |
|
||||
|------|------|------|
|
||||
| 服务器启动 | ✅ | `http://127.0.0.1:1933` |
|
||||
| 健康检查 | ✅ | `GET /health` → `{"status":"ok"}` |
|
||||
| 系统状态 | ✅ | `GET /api/v1/system/status` |
|
||||
| 会话创建 | ✅ | `POST /api/v1/sessions` |
|
||||
| 消息添加 | ✅ | `POST /api/v1/sessions/{id}/messages` |
|
||||
| 向量搜索 | ⚠️ | 需要激活 Embedding 模型 |
|
||||
|
||||
### ✅ 已解决:火山引擎 Embedding 模型激活
|
||||
|
||||
**Endpoint ID**: `ep-20260316102010-cq422`
|
||||
|
||||
**配置文件** (`~/.openviking/ov.conf`):
|
||||
```json
|
||||
{
|
||||
"embedding": {
|
||||
"dense": {
|
||||
"api_base": "https://ark.cn-beijing.volces.com/api/v3",
|
||||
"api_key": "3739b6b2-2bff-4a13-9f82-c0674dd4a05e",
|
||||
"provider": "volcengine",
|
||||
"model": "ep-20260316102010-cq422",
|
||||
"dimension": 1024
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**验证结果**:
|
||||
- 向量搜索 API: ✅ 正常
|
||||
- 会话创建: ✅ 正常
|
||||
- 消息添加: ✅ 正常
|
||||
- TypeScript 测试: ✅ 21 passed
|
||||
|
||||
### 备选方案:使用 OpenAI Embedding
|
||||
|
||||
如果不想激活火山引擎 Embedding,可以改用 OpenAI:
|
||||
|
||||
```json
|
||||
{
|
||||
"embedding": {
|
||||
"dense": {
|
||||
"api_base": "https://api.openai.com/v1",
|
||||
"api_key": "${OPENAI_API_KEY}",
|
||||
"provider": "openai",
|
||||
"model": "text-embedding-3-small",
|
||||
"dimension": 1536
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 配置文件
|
||||
|
||||
当前配置 (`~/.openviking/ov.conf`):
|
||||
|
||||
```json
|
||||
{
|
||||
"storage": {
|
||||
"workspace": "C:/Users/szend/.openviking/workspace",
|
||||
"vectordb": { "name": "context", "backend": "local" },
|
||||
"agfs": { "port": 1833, "log_level": "warn", "backend": "local" }
|
||||
},
|
||||
"embedding": {
|
||||
"dense": {
|
||||
"api_base": "https://ark.cn-beijing.volces.com/api/v3",
|
||||
"api_key": "3739b6b2-2bff-4a13-9f82-c0674dd4a05e",
|
||||
"provider": "volcengine",
|
||||
"dimension": 1024,
|
||||
"model": "doubao-embedding"
|
||||
}
|
||||
},
|
||||
"server": { "host": "127.0.0.1", "port": 1933 }
|
||||
}
|
||||
```
|
||||
|
||||
## 文件变更统计
|
||||
|
||||
- 新增文件:4 个
|
||||
- 修改文件:3 个
|
||||
- 归档文件:10+ 个
|
||||
- 文档更新:2 个
|
||||
|
||||
## 下一步工作
|
||||
|
||||
1. **完成 Embedding 模型激活**(阻塞项)
|
||||
2. 验证向量搜索功能
|
||||
3. 测试 ZCLAW 记忆面板集成
|
||||
4. 提交完整集成代码
|
||||
142
docs/archive/old-handoffs/handoff-agent-onboarding-2026-03-16.md
Normal file
@@ -0,0 +1,142 @@
|
||||
# Agent 人格设置引导功能 - 会话交接文档
|
||||
|
||||
> **创建时间**: 2026-03-16
|
||||
> **状态**: Phase 2 进行中
|
||||
|
||||
---
|
||||
|
||||
## 一、功能概述
|
||||
|
||||
为 ZCLAW 添加类似 ZCLAW 的 Agent 创建引导向导,包括人格风格设置、Emoji 选择、使用场景标签选择等。
|
||||
|
||||
**计划文档**: `plans/vast-stirring-wilkinson.md`
|
||||
|
||||
---
|
||||
|
||||
## 二、已完成工作
|
||||
|
||||
### Phase 1: 数据层 ✅ 已完成
|
||||
|
||||
1. **扩展 Clone 接口** (`desktop/src/store/agentStore.ts`)
|
||||
- 添加字段: `emoji`, `personality`, `communicationStyle`, `notes`, `onboardingCompleted`
|
||||
|
||||
2. **扩展 Clone 和 QuickConfig 接口** (`desktop/src/store/gatewayStore.ts`)
|
||||
- 添加相同的人格相关字段
|
||||
|
||||
3. **创建人格预设配置** (`desktop/src/lib/personality-presets.ts`)
|
||||
- `PERSONALITY_OPTIONS`: 4种人格风格 (专业严谨/友好亲切/创意灵活/简洁高效)
|
||||
- `SCENARIO_TAGS`: 9个使用场景标签 (编程开发/内容写作/产品策划等)
|
||||
- `EMOJI_PRESETS`: Emoji 预设分组 (动物/物体/表情)
|
||||
- `QUICK_START_SUGGESTIONS`: 首次对话快速建议
|
||||
- 辅助函数: `generateWelcomeMessage`, `generateSoulContent`, `generateUserContent`
|
||||
|
||||
### Phase 2: 核心组件 ✅ 已完成
|
||||
|
||||
1. **EmojiPicker** (`desktop/src/components/ui/EmojiPicker.tsx`)
|
||||
- 分类标签 (全部/动物/物体/表情)
|
||||
- 8列网格布局
|
||||
- 选中状态显示
|
||||
|
||||
2. **PersonalitySelector** (`desktop/src/components/PersonalitySelector.tsx`)
|
||||
- 4种人格卡片选择
|
||||
- 特质标签显示
|
||||
- `PersonalityBadge` 显示组件
|
||||
|
||||
3. **ScenarioTags** (`desktop/src/components/ScenarioTags.tsx`)
|
||||
- 多选标签
|
||||
- 最多选择5个
|
||||
- `ScenarioBadges` 显示组件
|
||||
|
||||
4. **AgentOnboardingWizard** (`desktop/src/components/AgentOnboardingWizard.tsx`)
|
||||
- 5步向导: 认识用户 → Agent身份 → 人格风格 → 使用场景 → 工作环境
|
||||
- 进度条显示
|
||||
- 表单验证
|
||||
- 配置预览
|
||||
- 创建提交
|
||||
|
||||
---
|
||||
|
||||
## 三、待完成工作
|
||||
|
||||
### Phase 3: 集成 (优先级高)
|
||||
|
||||
1. **修改 CloneManager** (`desktop/src/components/CloneManager.tsx`)
|
||||
- 集成 AgentOnboardingWizard 模态框
|
||||
- 替换或增强现有的内联表单
|
||||
|
||||
2. **实现 FirstConversationPrompt**
|
||||
- 创建 `desktop/src/components/FirstConversationPrompt.tsx`
|
||||
- 显示个性化欢迎消息
|
||||
- 显示快速开始建议按钮
|
||||
- 集成到 `ChatArea.tsx`
|
||||
|
||||
3. **修改 RightPanel** (`desktop/src/components/RightPanel.tsx`)
|
||||
- 显示 Agent 的 emoji
|
||||
- 显示人格风格标签
|
||||
- 显示使用场景标签
|
||||
|
||||
### Phase 4: 测试
|
||||
|
||||
1. 测试创建流程
|
||||
2. 测试持久化
|
||||
3. 测试首次对话引导
|
||||
|
||||
---
|
||||
|
||||
## 四、关键文件路径
|
||||
|
||||
```
|
||||
desktop/src/
|
||||
├── components/
|
||||
│ ├── AgentOnboardingWizard.tsx # ✅ 已创建
|
||||
│ ├── PersonalitySelector.tsx # ✅ 已创建
|
||||
│ ├── ScenarioTags.tsx # ✅ 已创建
|
||||
│ ├── CloneManager.tsx # 🔧 需修改
|
||||
│ ├── ChatArea.tsx # 🔧 需修改
|
||||
│ └── RightPanel.tsx # 🔧 需修改
|
||||
├── components/ui/
|
||||
│ └── EmojiPicker.tsx # ✅ 已创建
|
||||
├── lib/
|
||||
│ └── personality-presets.ts # ✅ 已创建
|
||||
└── store/
|
||||
├── agentStore.ts # ✅ 已修改
|
||||
└── gatewayStore.ts # ✅ 已修改
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 五、参考资源
|
||||
|
||||
- ZCLAW 快速配置: `docs/archive/zclaw-legacy/autoclaw界面/html版/4.html`
|
||||
- ZCLAW Agent 面板: `docs/archive/zclaw-legacy/autoclaw界面/html版/3.html`
|
||||
- 现有 Modal 模式: `desktop/src/components/CreateTriggerModal.tsx`
|
||||
|
||||
---
|
||||
|
||||
## 六、新会话提示词
|
||||
|
||||
```
|
||||
我正在实现 ZCLAW 的 Agent 人格设置引导功能,参考 ZCLAW 的设计。
|
||||
|
||||
**当前进度**:
|
||||
- Phase 1 (数据层) ✅ 已完成
|
||||
- Phase 2 (核心组件) ✅ 已完成
|
||||
- Phase 3 (集成) ⏳ 待开始
|
||||
- Phase 4 (测试) ⏳ 待开始
|
||||
|
||||
**已完成的文件**:
|
||||
- `desktop/src/store/agentStore.ts` - 扩展了 Clone 接口
|
||||
- `desktop/src/store/gatewayStore.ts` - 扩展了 Clone 和 QuickConfig 接口
|
||||
- `desktop/src/lib/personality-presets.ts` - 人格预设配置
|
||||
- `desktop/src/components/ui/EmojiPicker.tsx` - Emoji 选择器
|
||||
- `desktop/src/components/PersonalitySelector.tsx` - 人格选择器
|
||||
- `desktop/src/components/ScenarioTags.tsx` - 场景标签选择器
|
||||
- `desktop/src/components/AgentOnboardingWizard.tsx` - 向导主组件
|
||||
|
||||
**下一步工作**:
|
||||
1. 修改 `CloneManager.tsx` 集成 AgentOnboardingWizard
|
||||
2. 创建 `FirstConversationPrompt.tsx` 并集成到 ChatArea
|
||||
3. 修改 `RightPanel.tsx` 显示人格信息
|
||||
|
||||
请继续完成 Phase 3 的集成工作。详细计划见 `plans/vast-stirring-wilkinson.md`。
|
||||
```
|
||||
223
docs/archive/old-handoffs/handoff-audit-fix-2026-03-26.md
Normal file
@@ -0,0 +1,223 @@
|
||||
# 功能审计修复 — 会话交接文档
|
||||
|
||||
> **创建时间**: 2026-03-26
|
||||
> **审计报告**: `plans/piped-wondering-thompson.md`
|
||||
> **旧审计对比**: `docs/analysis/FEATURE-INTEGRITY-AUDIT.md`(含 6 处事实错误,勿参考)
|
||||
|
||||
---
|
||||
|
||||
## 背景
|
||||
|
||||
对 ZCLAW 全系统 12 个子系统执行了五步审计(文档对齐→追踪数据流→识别dead_code→检查trait实现→端到端验证),发现 19 处差距、22 处 dead_code、8 项文档不一致。核心问题模式:**"写了没接"** — 大量代码已实现但从未接入实际运行流程。
|
||||
|
||||
---
|
||||
|
||||
## 修复任务清单(严格按优先级执行)
|
||||
|
||||
### P0 — 影响核心功能可用性
|
||||
|
||||
#### P0-1: Context Compaction 内核集成
|
||||
|
||||
**问题**: 上下文压缩仅在前端 `chatStore.ts` 执行,`kernel.rs` 的 `send_message_stream()` 不感知压缩,LLM 实际收到完整历史,前端压缩只是视觉隐藏。
|
||||
|
||||
**差距模式**: 双系统不同步
|
||||
|
||||
**修复路径**:
|
||||
- `crates/zclaw-kernel/src/kernel.rs` — 在 `send_message_stream()` 中添加 token 估算 + 阈值检查 + 压缩逻辑
|
||||
- 参考前端实现: `desktop/src/store/chatStore.ts:333-359`(`checkThreshold` + `compact`)
|
||||
- 参考后端压缩器: `desktop/src-tauri/src/intelligence/compactor.rs`(462 行,已有完整实现)
|
||||
- 修复后删除前端 `chatStore.ts` 中的重复压缩调用,改为依赖内核
|
||||
|
||||
**验证**: 发送 20+ 条消息后,检查发给 LLM 的实际 context 长度是否被压缩
|
||||
|
||||
---
|
||||
|
||||
#### P0-2: 文档虚假声称清理
|
||||
|
||||
**问题**: README、CLAUDE.md 中多处状态描述与代码不符
|
||||
|
||||
**修复清单**:
|
||||
| 文件 | 行/位置 | 当前声称 | 应改为 |
|
||||
|------|---------|---------|-------|
|
||||
| `CLAUDE.md` | 项目结构 crates 列表 | `zclaw-channels (Telegram, Discord, Slack)` | `zclaw-channels (仅 ConsoleChannel 测试适配器)` |
|
||||
| `CLAUDE.md` | Hands 表格 Lead 行 | `✅ 可用` | `❌ 仅有配置文件,无 Rust 实现` |
|
||||
| `CLAUDE.md` | Hands 表格 Predictor 行 | `✅ 可用` | `❌ 仅有配置文件,无 Rust 实现` |
|
||||
| `docs/features/README.md` | Hands 统计 | `9 implemented = 82%` | `7 fully working, 2 config-only (Lead/Predictor)` |
|
||||
| `docs/features/README.md` | Lead/Predictor 注册状态 | 标记为已注册 | 标记为未实现 |
|
||||
| `docs/features/06-context-compaction.md` | 成熟度标签 | L4 Production | L2 (前端仅视觉压缩,内核未集成) |
|
||||
| `docs/features/README.md` | 删除引用 6 个不存在的文档链接 | 01-vector-memory.md 等 | 删除这些引用 |
|
||||
|
||||
**验证**: `rg "Lead|Predictor|Telegram|Discord|Slack" CLAUDE.md` 确认已修正
|
||||
|
||||
---
|
||||
|
||||
#### P0-3: Quiz Hand 占位符生成器替换
|
||||
|
||||
**问题**: `DefaultQuizGenerator` 生成 "Question N about X" / "Option A/B/C/D",正确答案永远是 Option A
|
||||
|
||||
**修复路径**:
|
||||
- `crates/zclaw-hands/src/hands/quiz.rs:35-68` — 替换 `DefaultQuizGenerator::generate()` 实现
|
||||
- 利用已有的 `QuizGenerator` trait(同文件),实现 LLM 驱动的生成器
|
||||
- 参考同类模式: `crates/zclaw-runtime/src/tools/web_fetch.rs` 中的 LLM 调用方式
|
||||
- 生成器需要接收 LLM driver 引用(通过 `QuizHand::new()` 或 `with_generator()` 传入)
|
||||
|
||||
**验证**: 触发 Quiz Hand,检查生成的题目是否有真实内容和随机正确答案
|
||||
|
||||
---
|
||||
|
||||
### P1 — 减少技术债务
|
||||
|
||||
#### P1-1: Intelligence 死代码清理
|
||||
|
||||
**问题**: 4 个模块有完整代码但从未被前端调用
|
||||
|
||||
**清理清单**:
|
||||
| 文件 | 大小 | Tauri 命令数 | 前端调用 | 建议 |
|
||||
|------|------|------------|---------|------|
|
||||
| `desktop/src-tauri/src/intelligence/mesh.rs` | ~300+ 行 | 8 个 | 0 | 删除或移到 `#[cfg(feature = "experimental")]` |
|
||||
| `desktop/src-tauri/src/intelligence/persona_evolver.rs` | ~300+ 行 | 7 个 | 0 | 同上 |
|
||||
| `desktop/src-tauri/src/intelligence/pattern_detector.rs` | ~200+ 行 | 0 | 0 | 删除 |
|
||||
| `desktop/src-tauri/src/intelligence/trigger_evaluator.rs` | ~500+ 行 | 0 | 0 | 删除 |
|
||||
|
||||
**注意**: `recommender.rs` **不是**死代码(被 `mesh.rs` 使用),但若 mesh.rs 被移除则 recommender 也变为死代码。
|
||||
|
||||
**修复步骤**:
|
||||
1. 删除上述 4 个文件
|
||||
2. 从 `desktop/src-tauri/src/intelligence/mod.rs` 移除对应 `pub mod` 声明
|
||||
3. 从 `desktop/src-tauri/src/lib.rs` invoke_handler 移除对应 15 个命令注册(mesh 8 个 + persona_evolver 7 个)
|
||||
4. 运行 `cargo check` 确认编译通过
|
||||
|
||||
**验证**: `cargo check` + `rg "mesh_|persona_evolver_|pattern_detector|trigger_evaluator" desktop/src-tauri/src/`
|
||||
|
||||
---
|
||||
|
||||
#### P1-2: Heartbeat Engine 整理
|
||||
|
||||
**问题**: Heartbeat 实际完成度 ~75%(App.tsx 启动时调用 init/start,有 tokio 定时循环),但 `trigger_evaluator` 子模块为死代码
|
||||
|
||||
**修复路径**:
|
||||
- 若 P1-1 已删除 trigger_evaluator,则 Heartbeat 中对它的引用也需要处理
|
||||
- 检查 `heartbeat.rs` 中是否有对 `trigger_evaluator` 的 import,若有则移除
|
||||
- 移除 `heartbeat.rs` 的 `#![allow(dead_code)]`(既然模块是活的,不需要此标记)
|
||||
- 确认 `heartbeat_tick` 中 trigger 评估逻辑降级为简单实现
|
||||
|
||||
**验证**: `cargo check` + 启动应用确认 heartbeat 仍正常运行
|
||||
|
||||
---
|
||||
|
||||
#### P1-3: Identity 持久化
|
||||
|
||||
**问题**: `AgentIdentityManager` 使用 InMemory 存储,重启后身份数据丢失
|
||||
|
||||
**修复路径**:
|
||||
- `desktop/src-tauri/src/intelligence/identity.rs` — 将 InMemory 存储替换为 SQLite
|
||||
- 参考已有的持久化模式: `crates/zclaw-growth/src/storage/sqlite.rs`
|
||||
- SOUL.md 内容、人格预设、变更提案历史需要持久化到 SQLite 表
|
||||
- 启动时从 SQLite 恢复状态
|
||||
|
||||
**验证**: 设置人格后重启应用,检查人格是否保留
|
||||
|
||||
---
|
||||
|
||||
#### P1-4: Channels 文档修正
|
||||
|
||||
**问题**: CLAUDE.md 声称 zclaw-channels 支持 Telegram/Discord/Slack,实际只有 ConsoleChannel
|
||||
|
||||
**修复路径**:
|
||||
- 已在 P0-2 中覆盖(同一处 CLAUDE.md 修改)
|
||||
|
||||
---
|
||||
|
||||
### P2 — 改善开发体验
|
||||
|
||||
#### P2-1: KernelConfig::load() 实现
|
||||
|
||||
**问题**: `crates/zclaw-kernel/src/config.rs:256-259` 的 `load()` 始终返回 `Self::default()`
|
||||
|
||||
**修复路径**:
|
||||
- 实现 TOML 文件读取(项目已依赖 `toml` crate)
|
||||
- 默认路径: `~/.zclaw/config.toml` 或项目根 `config/config.toml`
|
||||
- 支持 `${VAR_NAME}` 环境变量插值(参考 `desktop/src/lib/toml-utils.ts`)
|
||||
- 保留 `from_provider()` 作为运行时覆盖
|
||||
|
||||
**验证**: 修改 config.toml 中的某个值,重启后端确认生效
|
||||
|
||||
---
|
||||
|
||||
#### P2-2: PPTX/PDF 导出修复或明确禁用
|
||||
|
||||
**问题**: Pipeline 的 ActionRegistry 对 PPTX/PDF 返回 "feature in development" 错误
|
||||
|
||||
**修复路径**(二选一):
|
||||
- **方案 A**: 修复导出 — `crates/zclaw-kernel/src/export/pptx.rs` 已有实现,检查为什么 Pipeline 层面报错
|
||||
- **方案 B**: 明确禁用 — 从 Pipeline 前端 UI 中隐藏 PPTX/PDF 选项,避免用户触发报错
|
||||
|
||||
**验证**: 在 Pipeline 编辑器中尝试 PPTX 导出
|
||||
|
||||
---
|
||||
|
||||
#### P2-3: Embedding 搜索统一
|
||||
|
||||
**问题**: 向量嵌入仅连接到 Viking 侧车存储,内核原生 MemoryStore 不使用
|
||||
|
||||
**修复路径**:
|
||||
- `desktop/src-tauri/src/embedding_adapter.rs` 已实现 EmbeddingClient trait
|
||||
- 将相同 adapter 注入到 `zclaw-growth` 的 `SemanticScorer`(已有 `with_embedding()` 方法)
|
||||
- 在 `intelligence_hooks.rs` 的 `build_memory_context()` 中启用嵌入搜索
|
||||
|
||||
**验证**: 配置 embedding provider 后,搜索记忆时确认使用了向量搜索
|
||||
|
||||
---
|
||||
|
||||
## 不在本次修复范围的事项
|
||||
|
||||
| 项目 | 原因 |
|
||||
|------|------|
|
||||
| 新增 Telegram/Discord/Slack 适配器 | 需求未确认,工作量大于修复 |
|
||||
| Pipeline 智能路由(01-intelligent-routing.md) | 纯新功能,非修复 |
|
||||
| WASM/Native 技能执行模式 | 纯新功能 |
|
||||
| Agent 导入/导出、模板库 | 纯新功能 |
|
||||
| 生物识别支持 | 纯新功能 |
|
||||
| 旧报告提到的 6 个 404 API 端点 | ZCLAW 是 Tauri 桌面应用,不走 HTTP API,这些端点不适用 |
|
||||
|
||||
---
|
||||
|
||||
## 验证命令速查
|
||||
|
||||
```bash
|
||||
# 编译检查(每次修改后必跑)
|
||||
cargo check 2>&1 | grep -i "warning\|error"
|
||||
|
||||
# TypeScript 类型检查
|
||||
cd desktop && pnpm tsc --noEmit
|
||||
|
||||
# 单元测试
|
||||
cargo test -p zclaw-growth 2>&1 | tail -5
|
||||
cd desktop && pnpm vitest run
|
||||
|
||||
# 验证文档修正
|
||||
rg "Lead.*可用|Predictor.*可用|Telegram|Discord|Slack" CLAUDE.md
|
||||
|
||||
# 验证死代码清理
|
||||
rg "mesh_|persona_evolver_|pattern_detector|trigger_evaluator" desktop/src-tauri/src/
|
||||
|
||||
# 验证 heartbeat 清理
|
||||
rg "allow\(dead_code\)" desktop/src-tauri/src/intelligence/heartbeat.rs
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 关键文件索引
|
||||
|
||||
| 文件 | 用途 |
|
||||
|------|------|
|
||||
| `plans/piped-wondering-thompson.md` | 完整审计报告(本文档的详细版本) |
|
||||
| `crates/zclaw-kernel/src/kernel.rs` | 内核,P0-1 修改目标 |
|
||||
| `crates/zclaw-hands/src/hands/quiz.rs` | Quiz Hand,P0-3 修改目标 |
|
||||
| `desktop/src-tauri/src/intelligence/` | 智能层,P1-1/P1-2 修改目标 |
|
||||
| `desktop/src-tauri/src/intelligence/identity.rs` | 身份管理,P1-3 修改目标 |
|
||||
| `desktop/src-tauri/src/lib.rs:1376-1566` | Tauri 命令注册表 |
|
||||
| `desktop/src-tauri/src/intelligence_hooks.rs` | 智能 hooks 集成点 |
|
||||
| `crates/zclaw-kernel/src/config.rs:256-259` | 配置加载,P2-1 修改目标 |
|
||||
| `CLAUDE.md` | 项目文档,P0-2 修改目标 |
|
||||
| `docs/features/README.md` | 功能索引,P0-2 修改目标 |
|
||||
@@ -0,0 +1,467 @@
|
||||
# ZCLAW 交付执行计划(2026-03-12)
|
||||
|
||||
## 1. 计划目标
|
||||
|
||||
本计划的目标不是继续做“功能堆叠”,而是把当前仓库推进到**可安装、可启动、可连接、可对话、可配置、可验证**的可交付状态。
|
||||
|
||||
当前对“完整可用 ZCLAW”的定义如下:
|
||||
|
||||
- 用户能够在本机启动 ZCLAW 桌面应用
|
||||
- 用户安装 ZCLAW 时,ZCLAW 运行时已经随包提供,而不是要求用户另行安装
|
||||
- 桌面应用能够引导并管理随 ZCLAW 一起分发的本地 ZCLAW Gateway
|
||||
- 前端能够稳定连接 Gateway,并完成基础握手与鉴权
|
||||
- 用户能够创建、编辑、切换 Agent(Clone)
|
||||
- 用户能够发起真实对话并收到流式回复
|
||||
- 关键设置页不再只是静态占位,而是尽量接到真实后端能力
|
||||
- 有一套清晰的验收与收尾流程,支持阶段性提交与后续发布
|
||||
|
||||
---
|
||||
|
||||
## 2. 当前基线
|
||||
|
||||
### 2.1 已完成的关键能力
|
||||
|
||||
- Gateway 握手参数已修正,能够兼容 ZCLAW 2026.3.11
|
||||
- Token 鉴权已接入前端连接流程
|
||||
- `zclaw-ui` 插件可被 Gateway 正常加载
|
||||
- Agent 的创建、编辑、保存链路已打通
|
||||
- `scripts/setup.ts` 已可在已有 `~/.zclaw/zclaw.json` 时非破坏性合并插件与 skills 路径
|
||||
- 自定义插件 manifest/package id 对齐问题已修复
|
||||
|
||||
### 2.2 当前仍阻塞交付的核心问题
|
||||
|
||||
按交付优先级排序,当前最关键的缺口为:
|
||||
|
||||
1. **桌面端尚未真正接管 Gateway 生命周期**
|
||||
- `src/gateway/manager.ts` 已存在,但未被 Tauri 壳使用
|
||||
- `desktop/src-tauri/src/lib.rs` 仍是默认模板
|
||||
- 当前产品更像“前端连接外部 Gateway”,还不是“完整桌面应用”
|
||||
|
||||
2. **当前仍默认依赖用户独立安装 ZCLAW**
|
||||
- 这与最终产品目标不一致
|
||||
- 最终必须做到:安装 ZCLAW 后即可直接使用 ZCLAW 能力
|
||||
- 因此现阶段的 CLI/PATH 依赖只能作为开发期和过渡期方案
|
||||
|
||||
3. **真实桌面链路缺少本地运行闭环验证**
|
||||
- 需要验证 Tauri 内从启动 Gateway 到连接、到拉数据、到发消息的完整过程
|
||||
|
||||
4. **设置体系中仍有若干页面/按钮处于占位状态**
|
||||
- 部分页面已有 UI 但尚未连接真实能力
|
||||
- 会影响“可用”判断,尤其是用户首次体验
|
||||
|
||||
5. **交付收尾缺少固定验收流程**
|
||||
- 需要统一 smoke test、安装前检查、文档更新、阶段提交点
|
||||
|
||||
---
|
||||
|
||||
## 3. 总体推进策略
|
||||
|
||||
### 3.1 核心原则
|
||||
|
||||
- **先打通闭环,再做扩展**:优先修复阻塞真实使用的能力缺口,而不是继续加功能
|
||||
- **优先最短交付路径**:优先复用 ZCLAW 现有 CLI/service 能力,而不是一开始就做完整 sidecar 架构
|
||||
- **最终必须内置 ZCLAW**:开发阶段允许复用系统已安装的 ZCLAW,但交付阶段必须改为随 ZCLAW 一起分发和托管
|
||||
- **浏览器模式不回退**:新增 Tauri 能力必须有运行时保护,不影响现有浏览器预览/开发体验
|
||||
- **阶段可提交**:每个阶段都有独立验收标准,达到后可形成 clean checkpoint
|
||||
|
||||
### 3.2 本轮优先级
|
||||
|
||||
- **P0**:Tauri 桌面壳接入本地 Gateway 生命周期管理
|
||||
- **P0**:完成真实桌面端基础闭环验证
|
||||
- **P0**:确定并落地“ZCLAW 安装即内置 ZCLAW”的分发方案
|
||||
- **P1**:补齐最影响可用性的设置页占位项
|
||||
- **P1**:形成交付前 smoke checklist 和文档更新
|
||||
- **P2**:补测试、清理遗留代码、准备打包发布
|
||||
|
||||
---
|
||||
|
||||
## 4. 分阶段执行计划
|
||||
|
||||
## Phase A:桌面端本地 Gateway 生命周期管理(当前最高优先级)
|
||||
|
||||
### A.1 目标
|
||||
|
||||
让 ZCLAW 桌面应用在 Tauri 环境下具备对本地 ZCLAW Gateway 的基础管理能力:
|
||||
|
||||
- 查询本地 Gateway 状态
|
||||
- 启动本地 Gateway
|
||||
- 停止本地 Gateway
|
||||
- 重启本地 Gateway
|
||||
- 在前端展示本地状态,并与现有 WebSocket 连接状态区分开
|
||||
|
||||
### A.2 实现策略
|
||||
|
||||
优先采用**Tauri Rust 命令封装 ZCLAW CLI** 的方式,而不是直接引入完整 sidecar:
|
||||
|
||||
- Rust 侧封装以下命令:
|
||||
- `zclaw gateway status --json`
|
||||
- `zclaw gateway start --json`
|
||||
- `zclaw gateway stop --json`
|
||||
- `zclaw gateway restart --json`
|
||||
- 前端通过 `invoke` 调用 Rust 命令
|
||||
- 通过运行时判断,仅在 Tauri 环境中启用这组能力
|
||||
- 浏览器模式继续保留“手工连接外部 Gateway”的现有逻辑
|
||||
|
||||
说明:
|
||||
|
||||
- 这一阶段是**开发期过渡方案**
|
||||
- 它的价值是先把桌面端产品闭环跑通
|
||||
- 但它**不是最终交付形态**
|
||||
- 最终交付必须把 ZCLAW 运行时随 ZCLAW 一起打包,而不是要求用户本机已有 `zclaw`
|
||||
|
||||
### A.3 代码范围
|
||||
|
||||
- `desktop/src-tauri/src/lib.rs`
|
||||
- `desktop/src/lib/tauri-gateway.ts`(新增)
|
||||
- `desktop/src/store/gatewayStore.ts`
|
||||
- `desktop/src/components/Settings/General.tsx`
|
||||
- 如有必要:`desktop/src/components/RightPanel.tsx`
|
||||
|
||||
### A.4 验收标准
|
||||
|
||||
- Tauri 环境可正常调用本地 Gateway 管理命令
|
||||
- 设置页能看到“本地 Gateway”状态卡片
|
||||
- 用户可点击启动/停止/重启
|
||||
- 启动成功后,前端可继续连接并拉取基础数据
|
||||
- 浏览器模式不因该改动而报错或白屏
|
||||
- 开发环境下,即使仍依赖系统 `zclaw`,也已经明确与最终 bundling 方案解耦
|
||||
|
||||
### A.5 风险与应对
|
||||
|
||||
- **风险**:不同机器上 `zclaw` 不在 PATH
|
||||
- **应对**:前端明确提示“未安装 ZCLAW CLI”或“命令不可用”
|
||||
- **风险**:`status --json` / `start --json` 输出结构不稳定
|
||||
- **应对**:Rust 侧优先使用 `serde_json::Value` 宽松解析,再映射到前端稳定结构
|
||||
- **风险**:服务模式与前台 `gateway run` 并存导致认知混乱
|
||||
- **应对**:UI 文案明确说明“本地服务状态”和“当前 WebSocket 连接状态”是两层状态
|
||||
|
||||
---
|
||||
|
||||
## Phase B:真实桌面端基础闭环验证
|
||||
|
||||
### B.1 目标
|
||||
|
||||
确认 ZCLAW 在 Tauri 壳内已经不是“能打开 UI”,而是“能完成一次真实任务闭环”:
|
||||
|
||||
- 本地 Gateway 启动/可达
|
||||
- 前端连接成功
|
||||
- Clone 列表加载成功
|
||||
- Agent 创建/编辑成功
|
||||
- 首条消息发送成功
|
||||
- 收到真实流式回复
|
||||
|
||||
### B.2 任务清单
|
||||
|
||||
- 启动桌面应用并检查本地 Gateway 状态
|
||||
- 验证连接状态、版本、插件状态、workspace 信息是否能拉取
|
||||
- 验证创建 Agent
|
||||
- 验证编辑 Agent 并刷新右侧面板数据
|
||||
- 验证 bootstrap 文件生成状态
|
||||
- 验证聊天发送与回复流
|
||||
- 记录关键报错与回退路径
|
||||
|
||||
### B.3 验收标准
|
||||
|
||||
- 至少完成一次完整桌面端对话闭环
|
||||
- Agent 的创建与编辑在真实环境可用
|
||||
- 连接失败、Gateway 未安装、未启动等错误能明确提示
|
||||
- 关键路径没有阻塞性的控制台报错
|
||||
|
||||
---
|
||||
|
||||
## Phase C:ZCLAW 随包分发与运行时托管
|
||||
|
||||
### C.1 目标
|
||||
|
||||
把当前“依赖用户本机单独安装 ZCLAW”的开发态方案,推进到真正可交付的产品方案:
|
||||
|
||||
- 用户安装 ZCLAW 时,ZCLAW 运行时已经包含在安装包内
|
||||
- ZCLAW 启动后,能够直接找到并启动内置 ZCLAW
|
||||
- 用户不需要再单独安装一套 ZCLAW CLI / 环境
|
||||
|
||||
### C.2 目标形态
|
||||
|
||||
最终交付建议采用以下形态:
|
||||
|
||||
- 安装包内包含 ZCLAW 可执行运行时或受控分发产物
|
||||
- Tauri Rust 侧通过固定相对路径或 sidecar 机制调用该运行时
|
||||
- ZCLAW 负责:
|
||||
- 初始化 ZCLAW home / workspace
|
||||
- 写入或合并默认配置
|
||||
- 启动 / 停止 / 重启 Gateway
|
||||
- 读取日志与状态
|
||||
|
||||
### C.3 方案比较
|
||||
|
||||
#### 方案 1:继续依赖系统安装的 `zclaw`
|
||||
|
||||
优点:
|
||||
|
||||
- 当前开发改造最少
|
||||
|
||||
缺点:
|
||||
|
||||
- 不符合最终产品目标
|
||||
- 用户安装体验差
|
||||
- 环境差异和 PATH 问题会显著增加支持成本
|
||||
|
||||
结论:
|
||||
|
||||
- **仅适合开发期,不可作为最终交付方案**
|
||||
|
||||
#### 方案 2:把 ZCLAW 作为 sidecar / bundled runtime 随 ZCLAW 分发
|
||||
|
||||
优点:
|
||||
|
||||
- 符合 QClaw / AutoClaw 式的一体化交付体验
|
||||
- 可控性高
|
||||
- 便于做安装后自启动、版本锁定、升级兼容
|
||||
|
||||
缺点:
|
||||
|
||||
- 需要处理体积、签名、跨平台打包、路径定位
|
||||
|
||||
结论:
|
||||
|
||||
- **这是最终推荐方案**
|
||||
|
||||
### C.4 实施任务
|
||||
|
||||
- 确认 ZCLAW 可分发形态
|
||||
- npm 包直接落地
|
||||
- 预构建二进制
|
||||
- 内置 Node + ZCLAW 组合运行时
|
||||
- 确认 Tauri 2 下 sidecar / bundled binary 的最佳实现方式
|
||||
- 为 Windows 优先落地一版 bundling 方案
|
||||
- 调整 Rust 侧命令执行逻辑
|
||||
- 优先调用内置运行时
|
||||
- 开发模式可回退到系统 `zclaw`
|
||||
- 验证安装后首次启动流程
|
||||
- 不依赖用户额外安装
|
||||
- 可直接启动 Gateway
|
||||
- 可连接、可聊天、可配置
|
||||
|
||||
### C.5 验收标准
|
||||
|
||||
- 全新机器上,未单独安装 ZCLAW 的情况下,可直接安装并启动 ZCLAW
|
||||
- ZCLAW 可成功拉起内置 ZCLAW Gateway
|
||||
- Agent / 聊天 / 设置等核心功能可正常工作
|
||||
- 用户文档不再要求“先安装 ZCLAW 再使用 ZCLAW”
|
||||
|
||||
---
|
||||
|
||||
## Phase D:设置页可用性补齐
|
||||
|
||||
### D.1 目标
|
||||
|
||||
梳理 Settings 体系中“看起来像功能、实际上还是占位”的部分,优先补齐最影响交付感知的项。
|
||||
|
||||
### D.2 优先补齐范围
|
||||
|
||||
优先级从高到低建议如下:
|
||||
|
||||
1. **General / ModelsAPI**
|
||||
- Gateway 管理与连接语义统一
|
||||
- 去掉误导性按钮或接到真实逻辑
|
||||
|
||||
2. **Workspace / Skills / MCPServices**
|
||||
- 至少展示真实读取结果
|
||||
- 对未支持能力明确标注“暂未接入”而不是伪交互
|
||||
|
||||
3. **IMChannels**
|
||||
- 飞书状态尽量走真实探测
|
||||
- 对未完成渠道使用明确状态说明
|
||||
|
||||
4. **Privacy / UsageStats / About**
|
||||
- 以展示真实数据和静态说明为主,收尾体验
|
||||
|
||||
### D.3 判定标准
|
||||
|
||||
- 对用户可点击的动作,尽量有真实效果
|
||||
- 对暂未接入的能力,明确说明而不是假按钮
|
||||
- 页面不出现明显“假功能”感
|
||||
|
||||
---
|
||||
|
||||
## Phase E:交付前 smoke test 与文档收尾
|
||||
|
||||
### E.1 目标
|
||||
|
||||
形成一套最小但明确的交付前检查流程,避免“本地看起来能用、别人拿到跑不起来”。
|
||||
|
||||
### E.2 交付前 smoke checklist
|
||||
|
||||
#### 环境检查
|
||||
|
||||
- `pnpm -v`
|
||||
- `pnpm --dir desktop tauri --version`
|
||||
|
||||
说明:
|
||||
|
||||
- 最终交付 smoke test 不应再把系统级 `zclaw --version` 作为前置要求
|
||||
- 应改为验证 ZCLAW 内置运行时是否可用
|
||||
|
||||
#### 桌面启动检查
|
||||
|
||||
- `pnpm --dir desktop tauri dev`
|
||||
- UI 能正常打开
|
||||
- 设置页不白屏
|
||||
|
||||
#### Gateway 闭环检查
|
||||
|
||||
- 本地 Gateway 状态可读
|
||||
- 能启动/停止/重启
|
||||
- 前端连接成功
|
||||
|
||||
#### 核心功能检查
|
||||
|
||||
- Clone 列表加载
|
||||
- 新建 Clone
|
||||
- 编辑 Clone
|
||||
- 发送首条消息
|
||||
- 收到流式回复
|
||||
|
||||
#### 配置检查
|
||||
|
||||
- quick config 可读写
|
||||
- workspace 信息可读取
|
||||
- 插件状态可显示
|
||||
|
||||
#### 安装闭环检查
|
||||
|
||||
- 全新环境中无需单独安装 ZCLAW
|
||||
- 安装 ZCLAW 后首次启动即可使用
|
||||
- 若内置运行时损坏或缺失,错误提示明确
|
||||
|
||||
### E.3 文档更新项
|
||||
|
||||
- 更新 README:区分浏览器模式与 Tauri 桌面模式
|
||||
- 补充本地 Gateway 启动/连接说明
|
||||
- 补充已知限制与后续路线
|
||||
- 在 `PROGRESS.md` 中登记本轮交付成果
|
||||
|
||||
---
|
||||
|
||||
## Phase F:交付后加强项(不是当前阻塞项)
|
||||
|
||||
以下事项重要,但不应阻塞本轮“完整可用”目标:
|
||||
|
||||
- 更完整的 Tauri sidecar / 进程托管架构
|
||||
- 安装包/自动更新
|
||||
- 更高覆盖率测试
|
||||
- v1 归档代码清理
|
||||
- 微信 / QQ Channel 扩展
|
||||
- 新 Session Prompt 等增强功能
|
||||
|
||||
这些能力应在当前闭环稳定后进入下一轮计划。
|
||||
|
||||
---
|
||||
|
||||
## 5. 实施顺序与里程碑
|
||||
|
||||
## Milestone 1:桌面端本地 Gateway 管理打通
|
||||
|
||||
输出物:
|
||||
|
||||
- Tauri 命令桥
|
||||
- 前端本地 Gateway 状态卡片
|
||||
- 启停/重启操作
|
||||
|
||||
完成标志:
|
||||
|
||||
- 能在桌面应用中看到并操作本地 Gateway 服务状态
|
||||
|
||||
## Milestone 2:真实桌面闭环通过
|
||||
|
||||
输出物:
|
||||
|
||||
- 真实运行验证记录
|
||||
- 阻塞 bug 列表(若有)
|
||||
- 修复后的可用路径
|
||||
|
||||
完成标志:
|
||||
|
||||
- 从桌面打开到完成一次对话全链路可用
|
||||
|
||||
## Milestone 3:ZCLAW 随包分发打通
|
||||
|
||||
输出物:
|
||||
|
||||
- Windows 优先的一体化 bundling 方案
|
||||
- ZCLAW 优先调用内置 ZCLAW 运行时
|
||||
- 安装后无需用户额外安装 ZCLAW 的可运行链路
|
||||
|
||||
完成标志:
|
||||
|
||||
- 在未安装 ZCLAW 的机器/环境中,安装 ZCLAW 后即可直接使用
|
||||
|
||||
## Milestone 4:设置页与交付收尾
|
||||
|
||||
输出物:
|
||||
|
||||
- 最小可交付设置体验
|
||||
- smoke checklist
|
||||
- README / PROGRESS 更新
|
||||
|
||||
完成标志:
|
||||
|
||||
- 仓库进入“可给他人试用”的状态
|
||||
|
||||
---
|
||||
|
||||
## 6. 本轮立即执行项
|
||||
|
||||
按当前优先级,接下来立刻执行:
|
||||
|
||||
1. 在 Tauri Rust 侧实现 Gateway 管理命令
|
||||
2. 在前端新增 Tauri Gateway bridge
|
||||
3. 在 `gatewayStore` 中接入本地 Gateway 状态与动作
|
||||
4. 在 Settings > General 中增加本地 Gateway 管理卡片
|
||||
5. 明确 ZCLAW 随包分发方案,避免把系统安装依赖固化为最终设计
|
||||
6. 进行编译/运行级验证
|
||||
7. 若验证通过,记录到 `PROGRESS.md`
|
||||
|
||||
---
|
||||
|
||||
## 7. 阶段提交策略
|
||||
|
||||
本轮按以下 checkpoint 推进:
|
||||
|
||||
### Checkpoint A
|
||||
|
||||
- 完成计划文档
|
||||
- 完成 Tauri 命令桥与前端接线
|
||||
|
||||
### Checkpoint B
|
||||
|
||||
- 完成本地 Gateway 管理 UI
|
||||
- 完成基础验证
|
||||
|
||||
### Checkpoint C
|
||||
|
||||
- 完成 ZCLAW bundling / sidecar 方案设计
|
||||
- 明确 Windows 优先的交付路径
|
||||
|
||||
### Checkpoint D
|
||||
|
||||
- 完成设置页收尾 / 文档更新 / smoke checklist
|
||||
|
||||
说明:
|
||||
|
||||
- 代码会按干净阶段组织
|
||||
- 如需执行远端 `push`,仍单独确认
|
||||
|
||||
---
|
||||
|
||||
## 8. 结论
|
||||
|
||||
当前最短、最正确的交付路径,不是继续扩展更多功能,而是先把 ZCLAW 从“能连 Gateway 的前端”推进成“能在桌面端真正管理并使用内置 ZCLAW 的产品”。
|
||||
|
||||
因此,本轮执行的核心结论是:
|
||||
|
||||
- **先做 Tauri 本地 Gateway 生命周期管理**
|
||||
- **再完成 ZCLAW 随包分发方案**
|
||||
- **然后做真实桌面端闭环验证**
|
||||
- **最后收尾设置页与交付文档**
|
||||
|
||||
这条路线最符合当前仓库状态,也最接近“完整可用 ZCLAW”的真实交付目标。
|
||||
426
docs/archive/old-plans/2026-03-16-openviking-local-deployment.md
Normal file
@@ -0,0 +1,426 @@
|
||||
# ZCLAW OpenViking 深度集成方案
|
||||
|
||||
## Context
|
||||
|
||||
**背景**:ZCLAW 项目基于 ZCLAW 定制开发,目标是结合 ZCLAW、NanoClaw、ZeroClaw 等系统的优点。当前 Agent 智能层已超前完成(Phase 1-3 完成, Phase 4 部分完成),但 OpenViking 集成依赖外部 Python 服务,用户安装繁琐。
|
||||
|
||||
**问题**:如何深度集成 OpenViking,避免 Python 依赖,实现无感安装体验?
|
||||
|
||||
**目标**:以 OpenViking Rust CLI (`ov`) 为核心,通过 Tauri sidecar 集成,让记忆系统成为原生组件。CLI 缺失的功能再自行开发补充。
|
||||
|
||||
---
|
||||
|
||||
## 关键决策总结
|
||||
|
||||
基于头脑风暴讨论,确定以下技术决策:
|
||||
|
||||
| 决策点 | 选择 | 理由 |
|
||||
|--------|------|------|
|
||||
| **集成方式** | OpenViking Rust CLI + 自建补充 | 利用成熟工具,减少开发量,缺失功能自行补充 |
|
||||
| **记忆存储** | CLI 内置 SQLite + sqlite-vec | CLI 已实现,无需重复开发 |
|
||||
| **Embedding 模型** | doubao-embedding-vision | 中文效果优秀,火山引擎生态 |
|
||||
| **记忆提取** | LLM 提取 | 对话结束后调用 LLM 分析并提取 |
|
||||
| **部署方式** | Tauri Sidecar | CLI 作为可执行文件随应用分发 |
|
||||
|
||||
---
|
||||
|
||||
## Architecture Design
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ ZCLAW Desktop (Tauri + React) │
|
||||
│ │
|
||||
│ ┌────────────────────────────────────────────────────────────┐ │
|
||||
│ │ React UI Layer │ │
|
||||
│ │ ┌──────────┐ ┌──────────┐ ┌───────────┐ ┌──────────────┐ │ │
|
||||
│ │ │ ChatArea │ │MemoryPanel│ │SwarmPanel│ │ SkillMarket │ │ │
|
||||
│ │ └────┬─────┘ └────┬─────┘ └─────┬─────┘└──────┬───────┘ │ │
|
||||
│ └───────────┼────────────┼─────────────┼───────────────┼─────┘ │
|
||||
│ ▼ ▼ ▼ ▼ │
|
||||
│ ┌────────────────────────────────────────────────────────────┐ │
|
||||
│ │ TypeScript Integration Layer │ │
|
||||
│ │ ┌──────────────────────────────────────────────────────┐ │ │
|
||||
│ │ │ VikingAdapter (已存在,保持兼容) │ │ │
|
||||
│ │ └──────────────────────────────────────────────────────┘ │ │
|
||||
│ └──────────────────────────┬─────────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ ┌──────────────────────────▼─────────────────────────────────┐ │
|
||||
│ │ Tauri Command Layer (Rust) │ │
|
||||
│ │ ┌────────────────────────────────────────────────────────┐│ │
|
||||
│ │ │ SidecarWrapper: 调用 `ov` CLI ││ │
|
||||
│ │ │ - invoke('viking_add', ...) → ov add ││ │
|
||||
│ │ │ - invoke('viking_find', ...) → ov find ││ │
|
||||
│ │ │ - invoke('viking_grep', ...) → ov grep ││ │
|
||||
│ │ └────────────────────────────────────────────────────────┘│ │
|
||||
│ │ ┌────────────────────────────────────────────────────────┐│ │
|
||||
│ │ │ SupplementalModule: CLI 缺失功能补充 ││ │
|
||||
│ │ │ - SessionExtractor (LLM 记忆提取) ││ │
|
||||
│ │ │ - EmbeddingService (doubao API 封装) ││ │
|
||||
│ │ │ - ContextBuilder (L0/L1/L2 分层加载) ││ │
|
||||
│ │ └────────────────────────────────────────────────────────┘│ │
|
||||
│ └─────────────────────────────────────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ ┌──────────────────────────▼─────────────────────────────────┐ │
|
||||
│ │ Storage Layer │ │
|
||||
│ │ ┌──────────────────┐ ┌──────────────────────────────────┐ │ │
|
||||
│ │ │ OpenViking CLI │ │ AppData (配置) │ │ │
|
||||
│ │ │ ~/.viking/ │ │ ~/.zclaw/config.toml │ │ │
|
||||
│ │ │ - SQLite + vec │ │ │ │ │
|
||||
│ │ │ - 向量索引 │ │ │ │ │
|
||||
│ │ └──────────────────┘ └──────────────────────────────────┘ │ │
|
||||
│ └─────────────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## OpenViking Rust CLI 能力分析
|
||||
|
||||
### CLI 已实现功能 (直接使用)
|
||||
|
||||
| 命令 | 功能 | 状态 |
|
||||
|------|------|------|
|
||||
| `ov add <uri>` | 添加资源到索引 | ✅ 可用 |
|
||||
| `ov find <query>` | 语义搜索 | ✅ 可用 |
|
||||
| `ov grep <pattern>` | 正则搜索 | ✅ 可用 |
|
||||
| `ov ls <path>` | 列出资源 | ✅ 可用 |
|
||||
| `ov tree <path>` | 目录树 | ✅ 可用 |
|
||||
| `ov chat` | 交互式对话 | ✅ 可用 |
|
||||
|
||||
### CLI 缺失功能 (需要自建)
|
||||
|
||||
| 功能 | 说明 | 优先级 |
|
||||
|------|------|--------|
|
||||
| Session Extraction | 对话后 LLM 提取记忆 | 高 |
|
||||
| L0/L1/L2 分层加载 | Token 优化上下文构建 | 高 |
|
||||
| Embedding 批量生成 | doubao API 封装 | 中 |
|
||||
| 记忆老化/清理 | 低重要性记忆自动清理 | 低 |
|
||||
| 多 Agent 隔离 | agent_id 维度隔离 | 中 |
|
||||
|
||||
---
|
||||
|
||||
## Implementation Phases
|
||||
|
||||
### Phase 1: Sidecar 集成 (Week 1)
|
||||
|
||||
**Goal**: 将 OpenViking CLI 集成为 Tauri sidecar
|
||||
|
||||
#### Steps
|
||||
|
||||
1. **下载并嵌入 CLI**
|
||||
```bash
|
||||
# 将 ov 二进制放入 src-tauri/binaries/
|
||||
# Windows: ov-x86_64-pc-windows-msvc.exe
|
||||
# macOS: ov-x86_64-apple-darwin
|
||||
# Linux: ov-x86_64-unknown-linux-gnu
|
||||
```
|
||||
|
||||
2. **配置 tauri.conf.json**
|
||||
```json
|
||||
{
|
||||
"tauri": {
|
||||
"bundle": {
|
||||
"externalBin": ["binaries/ov"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
3. **创建 Tauri Commands**
|
||||
```rust
|
||||
// src-tauri/src/viking_commands.rs
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn viking_add(uri: String, content: String) -> Result<String, String> {
|
||||
let sidecar = Command::new_sidecar("ov")
|
||||
.map_err(|e| e.to_string())?;
|
||||
let output = sidecar
|
||||
.args(["add", &uri])
|
||||
.output()
|
||||
.await
|
||||
.map_err(|e| e.to_string())?;
|
||||
Ok(String::from_utf8_lossy(&output.stdout).to_string())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn viking_find(query: String, limit: usize) -> Result<Vec<FindResult>, String> {
|
||||
let sidecar = Command::new_sidecar("ov")
|
||||
.map_err(|e| e.to_string())?;
|
||||
let output = sidecar
|
||||
.args(["find", "--json", &query, "--limit", &limit.to_string()])
|
||||
.output()
|
||||
.await
|
||||
.map_err(|e| e.to_string())?;
|
||||
|
||||
serde_json::from_slice(&output.stdout)
|
||||
.map_err(|e| e.to_string())
|
||||
}
|
||||
```
|
||||
|
||||
#### Files to Create
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `src-tauri/src/viking_commands.rs` | Tauri 命令封装 |
|
||||
| `src-tauri/binaries/ov-*` | Sidecar 二进制 |
|
||||
|
||||
#### Files to Modify
|
||||
|
||||
| File | Changes |
|
||||
|------|---------|
|
||||
| `src-tauri/src/lib.rs` | 注册 viking 模块 |
|
||||
| `src-tauri/tauri.conf.json` | 添加 externalBin 配置 |
|
||||
| `desktop/src/lib/viking-adapter.ts` | 添加 `invoke()` 调用 |
|
||||
|
||||
### Phase 2: TypeScript 适配层 (Week 1-2)
|
||||
|
||||
**Goal**: 更新 VikingAdapter 使用 Tauri 命令
|
||||
|
||||
#### Key Changes
|
||||
|
||||
```typescript
|
||||
// desktop/src/lib/viking-adapter.ts
|
||||
|
||||
import { invoke } from '@tauri-apps/api/tauri';
|
||||
|
||||
export class VikingAdapter {
|
||||
private mode: 'sidecar' | 'remote' = 'sidecar';
|
||||
|
||||
async addResource(uri: string, content: string): Promise<void> {
|
||||
if (this.mode === 'sidecar') {
|
||||
await invoke('viking_add', { uri, content });
|
||||
} else {
|
||||
// Remote fallback
|
||||
await this.httpClient.addResource(uri, content);
|
||||
}
|
||||
}
|
||||
|
||||
async find(query: string, options?: FindOptions): Promise<FindResult[]> {
|
||||
if (this.mode === 'sidecar') {
|
||||
return await invoke('viking_find', {
|
||||
query,
|
||||
limit: options?.limit || 10
|
||||
});
|
||||
} else {
|
||||
return this.httpClient.find(query, options);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Phase 3: 补充模块开发 (Week 2-3)
|
||||
|
||||
**Goal**: 实现 CLI 缺失的功能
|
||||
|
||||
#### 3.1 Session Extractor
|
||||
|
||||
```rust
|
||||
// src-tauri/src/memory/extractor.rs
|
||||
|
||||
pub struct SessionExtractor {
|
||||
llm_client: LlmClient,
|
||||
}
|
||||
|
||||
impl SessionExtractor {
|
||||
/// Extract memories from conversation
|
||||
pub async fn extract(
|
||||
&self,
|
||||
messages: Vec<ChatMessage>,
|
||||
agent_id: &str,
|
||||
) -> Result<Vec<ExtractedMemory>, Error> {
|
||||
let prompt = self.build_extraction_prompt(&messages);
|
||||
let response = self.llm_client.complete(&prompt).await?;
|
||||
self.parse_extraction(&response, agent_id)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 3.2 Context Builder (L0/L1/L2)
|
||||
|
||||
```rust
|
||||
// src-tauri/src/memory/context_builder.rs
|
||||
|
||||
pub struct ContextBuilder {
|
||||
viking: VikingSidecar,
|
||||
}
|
||||
|
||||
impl ContextBuilder {
|
||||
/// Build layered context for token efficiency
|
||||
pub async fn build_context(
|
||||
&self,
|
||||
query: &str,
|
||||
agent_id: &str,
|
||||
max_tokens: usize,
|
||||
) -> Result<EnhancedContext, Error> {
|
||||
// L0: Quick scan - top 50 by similarity
|
||||
let l0_results = self.viking.find(query, 50).await?;
|
||||
|
||||
// L1: Load overview for top 10
|
||||
let l1_items = self.load_overviews(&l0_results[..10]).await?;
|
||||
|
||||
// L2: Full content for top 3
|
||||
let l2_items = self.load_full_content(&l0_results[..3]).await?;
|
||||
|
||||
Ok(EnhancedContext { l1_items, l2_items })
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Files to Create
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `src-tauri/src/memory/mod.rs` | 模块入口 |
|
||||
| `src-tauri/src/memory/extractor.rs` | LLM 记忆提取 |
|
||||
| `src-tauri/src/memory/context_builder.rs` | L0/L1/L2 分层加载 |
|
||||
| `src-tauri/src/llm/client.rs` | doubao API 客户端 |
|
||||
|
||||
### Phase 4: UI 集成 (Week 3-4)
|
||||
|
||||
**Goal**: 完善记忆面板 UI
|
||||
|
||||
#### Files to Modify
|
||||
|
||||
| File | Changes |
|
||||
|------|---------|
|
||||
| `desktop/src/components/MemoryPanel.tsx` | 集成 sidecar 模式 |
|
||||
| `desktop/src/components/RetrievalTrace.tsx` | 显示 L0/L1/L2 检索轨迹 |
|
||||
| `desktop/src/store/chatStore.ts` | 使用新的 VikingAdapter |
|
||||
|
||||
---
|
||||
|
||||
## Critical Files
|
||||
|
||||
### Existing Files (Reuse)
|
||||
|
||||
| File | Path | Purpose |
|
||||
|------|------|---------|
|
||||
| VikingAdapter | `desktop/src/lib/viking-adapter.ts` | 保持兼容,添加 sidecar 模式 |
|
||||
| VikingHttpClient | `desktop/src/lib/viking-client.ts` | 远程模式时使用 |
|
||||
| AgentMemory | `desktop/src/lib/agent-memory.ts` | 现有记忆接口 |
|
||||
| MemoryPanel | `desktop/src/components/MemoryPanel.tsx` | 现有 UI |
|
||||
|
||||
### New Files (Create)
|
||||
|
||||
| File | Path | Purpose |
|
||||
|------|------|---------|
|
||||
| VikingCommands | `src-tauri/src/viking_commands.rs` | Sidecar 命令封装 |
|
||||
| SessionExtractor | `src-tauri/src/memory/extractor.rs` | LLM 提取 (CLI 缺失) |
|
||||
| ContextBuilder | `src-tauri/src/memory/context_builder.rs` | 分层加载 (CLI 缺失) |
|
||||
| LlmClient | `src-tauri/src/llm/client.rs` | doubao API 封装 |
|
||||
|
||||
---
|
||||
|
||||
## Dependencies to Add
|
||||
|
||||
```toml
|
||||
# src-tauri/Cargo.toml
|
||||
[dependencies]
|
||||
tauri = { version = "2", features = ["process-command-api"] }
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
reqwest = { version = "0.11" } # For LLM API calls
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Verification Plan
|
||||
|
||||
### Unit Tests
|
||||
|
||||
```bash
|
||||
# Run Rust tests
|
||||
cargo test --manifest-path=src-tauri/Cargo.toml
|
||||
|
||||
# Run TypeScript tests
|
||||
pnpm vitest run tests/desktop/memory*.test.ts
|
||||
```
|
||||
|
||||
### Integration Tests
|
||||
|
||||
1. **Sidecar 启动**: CLI 能正确作为 sidecar 运行
|
||||
2. **Memory Save/Load**: 通过 Tauri 命令保存和检索记忆
|
||||
3. **Vector Search**: 语义搜索返回相关结果
|
||||
4. **Session Extraction**: 对话结束后正确提取记忆
|
||||
5. **Context Building**: L0/L1/L2 分层加载正常工作
|
||||
6. **UI Integration**: MemoryPanel 正确显示数据
|
||||
|
||||
### Manual Testing
|
||||
|
||||
1. 启动应用,验证 CLI sidecar 自动启动
|
||||
2. 发送消息,检查记忆是否保存
|
||||
3. 发送新消息,验证 Agent 能回忆之前的信息
|
||||
4. 测试记忆搜索功能
|
||||
5. 验证无 Python 依赖
|
||||
|
||||
---
|
||||
|
||||
## Migration Path
|
||||
|
||||
### From Current State
|
||||
|
||||
```
|
||||
Current: Target:
|
||||
|
||||
viking-client.ts ─────────────► Tauri Command
|
||||
(HTTP to Python server) (Sidecar wrapper)
|
||||
│
|
||||
▼
|
||||
viking-adapter.ts ──────────────► Dual mode: sidecar + remote fallback
|
||||
```
|
||||
|
||||
### Data Compatibility
|
||||
|
||||
- OpenViking CLI 使用 `~/.viking/` 目录存储数据
|
||||
- 与 Python Server 版本数据格式兼容
|
||||
- 可无缝迁移现有数据
|
||||
|
||||
---
|
||||
|
||||
## Success Criteria
|
||||
|
||||
- [ ] OpenViking CLI 作为 sidecar 正确运行
|
||||
- [ ] Tauri 命令可调用 CLI 功能
|
||||
- [ ] 记忆保存和检索功能正常
|
||||
- [ ] 语义搜索返回相关结果
|
||||
- [ ] LLM 记忆提取正常工作 (自建模块)
|
||||
- [ ] L0/L1/L2 分层加载正常工作 (自建模块)
|
||||
- [ ] MemoryPanel UI 正确显示
|
||||
- [ ] 所有测试通过
|
||||
- [ ] **无需 Python 依赖**
|
||||
|
||||
---
|
||||
|
||||
## Risks and Mitigations
|
||||
|
||||
| Risk | Mitigation |
|
||||
|------|------------|
|
||||
| CLI 二进制兼容性 | 提供多平台预编译版本 |
|
||||
| CLI 功能不足 | 自建补充模块填补空白 |
|
||||
| Embedding API 限流 | 实现本地缓存 |
|
||||
| LLM 提取失败 | 保留规则提取作为 fallback |
|
||||
| Sidecar 启动失败 | 优雅降级到远程模式 |
|
||||
|
||||
---
|
||||
|
||||
## Timeline
|
||||
|
||||
| Week | Phase | Deliverables |
|
||||
|------|-------|--------------|
|
||||
| 1 | Sidecar 集成 | CLI 嵌入 + Tauri 命令 + TypeScript 适配 |
|
||||
| 2 | 补充模块 | SessionExtractor + ContextBuilder |
|
||||
| 3 | LLM 集成 | doubao API 客户端 + 提取逻辑 |
|
||||
| 4 | UI 集成 | MemoryPanel + RetrievalTrace |
|
||||
| 5 | 测试完善 | 集成测试 + 文档 |
|
||||
|
||||
---
|
||||
|
||||
## 开发策略总结
|
||||
|
||||
1. **Phase 1**: 直接集成 OpenViking Rust CLI 作为 sidecar
|
||||
2. **Phase 2**: 检测 CLI 功能覆盖度
|
||||
3. **Phase 3**: 自行开发 CLI 缺失的功能 (Session Extraction, Context Builder)
|
||||
4. **Phase 4**: UI 完善和测试
|
||||
|
||||
**核心原则**: 最大化利用现有成熟工具,最小化自建代码量,只在必要时补充缺失功能。
|
||||
382
docs/archive/old-plans/INTELLIGENCE-LAYER-MIGRATION.md
Normal file
@@ -0,0 +1,382 @@
|
||||
# ZCLAW 智能层迁移规划
|
||||
|
||||
> 将前端智能模块迁移到 Tauri Rust 后端
|
||||
|
||||
---
|
||||
|
||||
## 一、背景与动机
|
||||
|
||||
### 1.1 当前问题
|
||||
|
||||
| 问题 | 影响 | 严重程度 |
|
||||
|------|------|----------|
|
||||
| 应用关闭后功能停止 | 心跳、反思、主动学习都会中断 | 高 |
|
||||
| 数据持久化依赖 localStorage | 容量限制(5-10MB),无法跨设备同步 | 中 |
|
||||
| 前端处理大量数据 | 性能瓶颈,阻塞 UI | 中 |
|
||||
| 无法多端共享状态 | Agent 状态只能在单设备使用 | 中 |
|
||||
|
||||
### 1.2 迁移目标
|
||||
|
||||
1. **持续运行** - 关闭 UI 后后台服务继续工作
|
||||
2. **持久化存储** - 使用 SQLite 存储大量数据
|
||||
3. **性能优化** - Rust 处理计算密集型任务
|
||||
4. **跨设备同步** - 通过 Gateway 同步状态
|
||||
|
||||
---
|
||||
|
||||
## 二、当前架构分析
|
||||
|
||||
### 2.1 前端智能模块(待迁移)
|
||||
|
||||
| 文件 | 行数 | 功能 | 依赖 |
|
||||
|------|------|------|------|
|
||||
| `agent-memory.ts` | 486 | Agent 记忆管理 | memory-index.ts |
|
||||
| `agent-identity.ts` | 350 | 身份演化系统 | agent-memory.ts |
|
||||
| `reflection-engine.ts` | 677 | 自我反思引擎 | agent-memory.ts, llm |
|
||||
| `heartbeat-engine.ts` | 346 | 心跳引擎 | agent-memory.ts |
|
||||
| `context-compactor.ts` | 442 | 上下文压缩 | llm |
|
||||
| `agent-swarm.ts` | 549 | Agent 蜂群协作 | agent-memory.ts |
|
||||
| **总计** | **2850** | | |
|
||||
|
||||
### 2.2 已有 Rust 后端模块
|
||||
|
||||
| 模块 | 行数 | 功能 |
|
||||
|------|------|------|
|
||||
| `browser/` | ~1300 | 浏览器自动化 |
|
||||
| `memory/` | ~1040 | 上下文构建、信息提取 |
|
||||
| `llm/` | ~250 | LLM 调用封装 |
|
||||
| `viking_*` | ~400 | OpenViking 集成 |
|
||||
| `secure_storage` | ~150 | 安全存储 |
|
||||
| **总计** | **~5074** | |
|
||||
|
||||
### 2.3 依赖关系图
|
||||
|
||||
```
|
||||
agent-memory.ts
|
||||
↓
|
||||
├── agent-identity.ts
|
||||
├── reflection-engine.ts
|
||||
├── heartbeat-engine.ts
|
||||
└── agent-swarm.ts
|
||||
|
||||
context-compactor.ts (独立)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 三、迁移策略
|
||||
|
||||
### 3.1 分阶段迁移
|
||||
|
||||
```
|
||||
Phase 1: 数据层迁移(2周)
|
||||
├── SQLite 存储引擎
|
||||
├── 记忆持久化 API
|
||||
└── 数据迁移工具
|
||||
|
||||
Phase 2: 核心引擎迁移(3周)
|
||||
├── heartbeat-engine → Rust
|
||||
├── context-compactor → Rust
|
||||
└── 前端适配器
|
||||
|
||||
Phase 3: 高级功能迁移(4周)
|
||||
├── reflection-engine → Rust
|
||||
├── agent-identity → Rust
|
||||
└── agent-swarm → Rust
|
||||
|
||||
Phase 4: 集成与优化(2周)
|
||||
├── 端到端测试
|
||||
├── 性能优化
|
||||
└── 文档更新
|
||||
```
|
||||
|
||||
### 3.2 迁移原则
|
||||
|
||||
1. **渐进式迁移** - 保持前端功能可用,逐步切换到后端
|
||||
2. **双写阶段** - 迁移期间前后端都处理,确保数据一致性
|
||||
3. **API 兼容** - 前端 API 保持不变,内部调用 Tauri 命令
|
||||
4. **回滚机制** - 每个阶段都可以回滚到前一状态
|
||||
|
||||
---
|
||||
|
||||
## 四、详细设计
|
||||
|
||||
### 4.1 Phase 1: 数据层迁移
|
||||
|
||||
#### 4.1.1 SQLite Schema
|
||||
|
||||
```sql
|
||||
-- Agent 记忆表
|
||||
CREATE TABLE memories (
|
||||
id TEXT PRIMARY KEY,
|
||||
agent_id TEXT NOT NULL,
|
||||
content TEXT NOT NULL,
|
||||
type TEXT CHECK(type IN ('fact', 'preference', 'lesson', 'context', 'task')),
|
||||
importance INTEGER DEFAULT 5,
|
||||
source TEXT DEFAULT 'auto',
|
||||
tags TEXT, -- JSON array
|
||||
conversation_id TEXT,
|
||||
created_at TEXT NOT NULL,
|
||||
last_accessed_at TEXT,
|
||||
access_count INTEGER DEFAULT 0
|
||||
);
|
||||
|
||||
-- 全文搜索索引
|
||||
CREATE VIRTUAL TABLE memories_fts USING fts5(
|
||||
content,
|
||||
content='memories',
|
||||
content_rowid='rowid'
|
||||
);
|
||||
|
||||
-- Agent 身份表
|
||||
CREATE TABLE agent_identities (
|
||||
agent_id TEXT PRIMARY KEY,
|
||||
name TEXT,
|
||||
personality TEXT, -- JSON
|
||||
goals TEXT, -- JSON array
|
||||
values TEXT, -- JSON object
|
||||
communication_style TEXT,
|
||||
expertise_areas TEXT, -- JSON array
|
||||
version INTEGER DEFAULT 1,
|
||||
updated_at TEXT
|
||||
);
|
||||
|
||||
-- 反思记录表
|
||||
CREATE TABLE reflections (
|
||||
id TEXT PRIMARY KEY,
|
||||
agent_id TEXT NOT NULL,
|
||||
trigger TEXT,
|
||||
insight TEXT,
|
||||
action_items TEXT, -- JSON array
|
||||
created_at TEXT NOT NULL
|
||||
);
|
||||
```
|
||||
|
||||
#### 4.1.2 Tauri 命令
|
||||
|
||||
```rust
|
||||
// memory_commands.rs
|
||||
#[tauri::command]
|
||||
async fn memory_store(
|
||||
agent_id: String,
|
||||
content: String,
|
||||
memory_type: String,
|
||||
importance: i32,
|
||||
) -> Result<String, String> {
|
||||
// ...
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
async fn memory_search(
|
||||
agent_id: String,
|
||||
query: String,
|
||||
limit: i32,
|
||||
) -> Result<Vec<MemoryEntry>, String> {
|
||||
// ...
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
async fn memory_get_all(
|
||||
agent_id: String,
|
||||
limit: i32,
|
||||
) -> Result<Vec<MemoryEntry>, String> {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### 4.2 Phase 2: 核心引擎迁移
|
||||
|
||||
#### 4.2.1 Heartbeat Engine
|
||||
|
||||
```rust
|
||||
// heartbeat.rs
|
||||
pub struct HeartbeatEngine {
|
||||
agent_id: String,
|
||||
interval: Duration,
|
||||
callbacks: Vec<HeartbeatCallback>,
|
||||
running: AtomicBool,
|
||||
}
|
||||
|
||||
impl HeartbeatEngine {
|
||||
pub fn start(&self) {
|
||||
// 后台线程运行心跳
|
||||
}
|
||||
|
||||
pub fn tick(&self) -> HeartbeatResult {
|
||||
// 执行心跳逻辑
|
||||
}
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
async fn heartbeat_start(agent_id: String, interval_ms: u64) -> Result<(), String> {
|
||||
// ...
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
async fn heartbeat_tick(agent_id: String) -> Result<HeartbeatResult, String> {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
#### 4.2.2 Context Compactor
|
||||
|
||||
```rust
|
||||
// context_compactor.rs
|
||||
pub struct ContextCompactor {
|
||||
target_tokens: usize,
|
||||
preserve_recent: usize,
|
||||
}
|
||||
|
||||
impl ContextCompaction {
|
||||
pub async fn compact(&self, messages: Vec<Message>) -> Result<CompactedContext, Error> {
|
||||
// 使用 LLM 压缩上下文
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4.3 前端适配器
|
||||
|
||||
```typescript
|
||||
// desktop/src/lib/memory-backend.ts
|
||||
import { invoke } from '@tauri-apps/api/core';
|
||||
|
||||
export class BackendMemoryManager {
|
||||
async store(entry: Omit<MemoryEntry, 'id'>): Promise<string> {
|
||||
return invoke('memory_store', {
|
||||
agentId: entry.agentId,
|
||||
content: entry.content,
|
||||
memoryType: entry.type,
|
||||
importance: entry.importance,
|
||||
});
|
||||
}
|
||||
|
||||
async search(query: string, options?: MemorySearchOptions): Promise<MemoryEntry[]> {
|
||||
return invoke('memory_search', {
|
||||
agentId: options?.agentId,
|
||||
query,
|
||||
limit: options?.limit || 50,
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 五、实施计划
|
||||
|
||||
### 5.1 时间表
|
||||
|
||||
| 阶段 | 开始 | 结束 | 交付物 |
|
||||
|------|------|------|--------|
|
||||
| Phase 1 | Week 1 | Week 2 | SQLite 存储 + Tauri 命令 |
|
||||
| Phase 2 | Week 3 | Week 5 | Heartbeat + Compactor |
|
||||
| Phase 3 | Week 6 | Week 9 | Reflection + Identity + Swarm |
|
||||
| Phase 4 | Week 10 | Week 11 | 集成测试 + 文档 |
|
||||
|
||||
### 5.2 里程碑
|
||||
|
||||
- **M1**: 记忆数据可在 Rust 后端存储和检索
|
||||
- **M2**: 心跳引擎在后台线程运行
|
||||
- **M3**: 所有智能模块迁移完成
|
||||
- **M4**: 通过全部 E2E 测试
|
||||
|
||||
---
|
||||
|
||||
## 六、风险评估
|
||||
|
||||
| 风险 | 概率 | 影响 | 缓解措施 |
|
||||
|------|------|------|----------|
|
||||
| 数据迁移丢失 | 中 | 高 | 双写 + 备份机制 |
|
||||
| 性能不达预期 | 低 | 中 | 性能基准测试 |
|
||||
| API 兼容性问题 | 中 | 中 | 适配器模式 |
|
||||
| Rust 学习曲线 | 低 | 低 | 参考现有代码 |
|
||||
|
||||
---
|
||||
|
||||
## 七、验收标准
|
||||
|
||||
### 7.1 功能验收
|
||||
|
||||
- [x] 所有记忆数据存储在 SQLite
|
||||
- [x] 关闭 UI 后心跳继续运行(后台线程)
|
||||
- [ ] 前端 API 保持兼容(需要适配器)
|
||||
- [ ] 数据迁移工具可用
|
||||
|
||||
### 7.2 性能验收
|
||||
|
||||
- [ ] 记忆检索 < 20ms(1000+ 条)
|
||||
- [ ] 心跳间隔精度 > 99%
|
||||
- [ ] 内存占用 < 100MB
|
||||
|
||||
### 7.3 质量验收
|
||||
|
||||
- [x] 单元测试覆盖率 > 80%(Rust 模块已有测试)
|
||||
- [ ] E2E 测试全部通过
|
||||
- [x] 文档更新完成
|
||||
|
||||
---
|
||||
|
||||
## 八、参考资料
|
||||
|
||||
- [Tauri Commands](https://tauri.app/v1/guides/features/command/)
|
||||
- [SQLite in Rust](https://github.com/rusqlite/rusqlite)
|
||||
- [ZCLAW Deep Analysis](../analysis/ZCLAW-DEEP-ANALYSIS.md)
|
||||
|
||||
---
|
||||
|
||||
**文档版本**: 1.1
|
||||
**创建日期**: 2026-03-21
|
||||
**最后更新**: 2026-03-21
|
||||
**状态**: Phase 2-3 完成,Phase 4 进行中
|
||||
|
||||
---
|
||||
|
||||
## 九、实施进度
|
||||
|
||||
### 9.1 已完成工作
|
||||
|
||||
| 阶段 | 模块 | 状态 | 说明 |
|
||||
|------|------|------|------|
|
||||
| Phase 1 | SQLite 存储 | ✅ 完成 | `memory/persistent.rs` |
|
||||
| Phase 1 | Tauri 命令 | ✅ 完成 | `memory_commands.rs` (10 命令) |
|
||||
| Phase 2 | Heartbeat Engine | ✅ 完成 | `intelligence/heartbeat.rs` |
|
||||
| Phase 2 | Context Compactor | ✅ 完成 | `intelligence/compactor.rs` |
|
||||
| Phase 3 | Reflection Engine | ✅ 完成 | `intelligence/reflection.rs` |
|
||||
| Phase 3 | Agent Identity | ✅ 完成 | `intelligence/identity.rs` |
|
||||
|
||||
### 9.2 已实现的 Tauri 命令
|
||||
|
||||
**Memory (Phase 1):**
|
||||
- `memory_init`, `memory_store`, `memory_get`, `memory_search`
|
||||
- `memory_delete`, `memory_delete_all`, `memory_stats`
|
||||
- `memory_export`, `memory_import`, `memory_db_path`
|
||||
|
||||
**Heartbeat (Phase 2):**
|
||||
- `heartbeat_init`, `heartbeat_start`, `heartbeat_stop`, `heartbeat_tick`
|
||||
- `heartbeat_get_config`, `heartbeat_update_config`, `heartbeat_get_history`
|
||||
|
||||
**Compactor (Phase 2):**
|
||||
- `compactor_estimate_tokens`, `compactor_estimate_messages_tokens`
|
||||
- `compactor_check_threshold`, `compactor_compact`
|
||||
|
||||
**Reflection (Phase 3):**
|
||||
- `reflection_init`, `reflection_record_conversation`, `reflection_should_reflect`
|
||||
- `reflection_reflect`, `reflection_get_history`, `reflection_get_state`
|
||||
|
||||
**Identity (Phase 3):**
|
||||
- `identity_get`, `identity_get_file`, `identity_build_prompt`
|
||||
- `identity_update_user_profile`, `identity_append_user_profile`
|
||||
- `identity_propose_change`, `identity_approve_proposal`, `identity_reject_proposal`
|
||||
- `identity_get_pending_proposals`, `identity_update_file`
|
||||
- `identity_get_snapshots`, `identity_restore_snapshot`
|
||||
- `identity_list_agents`, `identity_delete_agent`
|
||||
|
||||
### 9.3 待完成工作
|
||||
|
||||
| 阶段 | 模块 | 状态 | 说明 |
|
||||
|------|------|------|------|
|
||||
| Phase 3 | Agent Swarm | 🚧 待定 | 评估是否需要迁移 |
|
||||
| Phase 4 | 前端适配器 | 📋 计划中 | TypeScript 调用 Tauri 命令 |
|
||||
| Phase 4 | E2E 测试 | 📋 计划中 | 验证完整数据流 |
|
||||
| Phase 4 | 性能优化 | 📋 计划中 | 基准测试和优化 |
|
||||
|
||||
615
docs/archive/old-plans/cached-greeting-cocke.md
Normal file
@@ -0,0 +1,615 @@
|
||||
# ZCLAW UI/UX 全面优化计划
|
||||
|
||||
## 背景
|
||||
|
||||
ZCLAW 是基于 ZCLAW (Rust Agent OS) 的 AI Agent 桌面客户端。经过 Phase 1-8 的功能开发,系统已达到 93% API 覆盖率和 100% UI 组件完成度。现在需要对前端设计元素进行全面优化,提升用户操作效率与视觉体验。
|
||||
|
||||
## 当前状态分析
|
||||
|
||||
### 代码结构
|
||||
- **框架**: React 18 + TypeScript + Tauri
|
||||
- **样式**: Tailwind CSS v4.2.1
|
||||
- **状态管理**: Zustand (gatewayStore, chatStore, teamStore)
|
||||
- **图标**: lucide-react
|
||||
- **组件数量**: 37 个组件
|
||||
|
||||
### 现有设计特点
|
||||
- **主色调**: Orange (#f97316) 作为品牌色
|
||||
- **布局**: 三栏式 (Sidebar w-64 | Main flex-1 | RightPanel w-80)
|
||||
- **暗黑模式**: 部分支持 (部分组件有 `dark:` 变体)
|
||||
- **动画**: 基础 CSS 动画 (animate-pulse, animate-spin)
|
||||
|
||||
---
|
||||
|
||||
## 发现的问题
|
||||
|
||||
### 1. 设计系统问题 (CRITICAL)
|
||||
|
||||
| 问题 | 位置 | 影响 |
|
||||
|------|------|------|
|
||||
| 无 UI 组件库 | 全局 | 一致性差,重复代码 |
|
||||
| 颜色系统不完整 | index.css | 品牌识别度低 |
|
||||
| 暗黑模式不完整 | 多个组件 | 用户体验不一致 |
|
||||
| **使用 Emoji 作为 UI 图标** | ChatArea, App.tsx | 不专业,违反设计规范 |
|
||||
|
||||
### 2. 可访问性问题 (CRITICAL)
|
||||
|
||||
| 问题 | 位置 | 影响 |
|
||||
|------|------|------|
|
||||
| 缺少 aria-label | 图标按钮 | 屏幕阅读器无法识别 |
|
||||
| 焦点状态不明显 | 多个交互元素 | 键盘导航困难 |
|
||||
| 颜色对比度不足 | text-gray-400 类 | 可读性差 |
|
||||
|
||||
### 3. 交互与动画 (HIGH)
|
||||
|
||||
| 问题 | 位置 | 影响 |
|
||||
|------|------|------|
|
||||
| 无过渡动画库 | 全局 | 交互生硬 |
|
||||
| 悬停状态不一致 | 多个组件 | 用户困惑 |
|
||||
| 缺少骨架屏 | 数据加载 | 感知性能差 |
|
||||
|
||||
### 4. 视觉层次 (MEDIUM)
|
||||
|
||||
| 问题 | 位置 | 影响 |
|
||||
|------|------|------|
|
||||
| 卡片阴影过轻 | shadow-sm | 层次不明显 |
|
||||
| 间距不一致 | padding/margin | 视觉混乱 |
|
||||
| 字体过小 | text-xs | 可读性差 |
|
||||
|
||||
### 5. 用户体验 (MEDIUM)
|
||||
|
||||
| 问题 | 位置 | 影响 |
|
||||
|------|------|------|
|
||||
| 空状态设计简陋 | 多个列表 | 缺乏引导 |
|
||||
| 错误提示不明显 | 表单等 | 用户困惑 |
|
||||
| 加载反馈不足 | API 调用 | 用户焦虑 |
|
||||
|
||||
---
|
||||
|
||||
## 用户确认的优化方向
|
||||
|
||||
| 决策项 | 选择 |
|
||||
|--------|------|
|
||||
| 动画库 | ✅ 引入 Framer Motion |
|
||||
| 暗黑模式 | ✅ 完整支持所有组件 |
|
||||
| 组件库 | ✅ 创建 Button, Card, Input 等基础组件 |
|
||||
|
||||
---
|
||||
|
||||
## 优化方案
|
||||
|
||||
### Phase 1: 设计系统建立 (P0)
|
||||
|
||||
#### 1.1 CSS 变量系统
|
||||
|
||||
**文件**: `desktop/src/index.css`
|
||||
|
||||
```css
|
||||
:root {
|
||||
/* Brand Colors */
|
||||
--color-primary: #f97316;
|
||||
--color-primary-hover: #ea580c;
|
||||
--color-primary-light: #fff7ed;
|
||||
|
||||
/* Semantic Colors */
|
||||
--color-success: #22c55e;
|
||||
--color-warning: #eab308;
|
||||
--color-error: #ef4444;
|
||||
--color-info: #3b82f6;
|
||||
|
||||
/* Neutral Colors */
|
||||
--color-bg: #ffffff;
|
||||
--color-bg-secondary: #f9fafb;
|
||||
--color-border: #e5e7eb;
|
||||
--color-text: #111827;
|
||||
--color-text-secondary: #6b7280;
|
||||
--color-text-muted: #9ca3af;
|
||||
|
||||
/* Spacing Scale */
|
||||
--space-xs: 4px;
|
||||
--space-sm: 8px;
|
||||
--space-md: 16px;
|
||||
--space-lg: 24px;
|
||||
--space-xl: 32px;
|
||||
|
||||
/* Border Radius */
|
||||
--radius-sm: 6px;
|
||||
--radius-md: 8px;
|
||||
--radius-lg: 12px;
|
||||
--radius-xl: 16px;
|
||||
--radius-full: 9999px;
|
||||
|
||||
/* Shadows */
|
||||
--shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
|
||||
--shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1);
|
||||
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1);
|
||||
|
||||
/* Transitions */
|
||||
--transition-fast: 150ms ease;
|
||||
--transition-normal: 200ms ease;
|
||||
--transition-slow: 300ms ease;
|
||||
}
|
||||
|
||||
.dark {
|
||||
--color-bg: #0f172a;
|
||||
--color-bg-secondary: #1e293b;
|
||||
--color-border: #334155;
|
||||
--color-text: #f1f5f9;
|
||||
--color-text-secondary: #94a3b8;
|
||||
--color-text-muted: #64748b;
|
||||
}
|
||||
```
|
||||
|
||||
#### 1.2 统一 Tailwind 配置
|
||||
|
||||
**文件**: `desktop/tailwind.config.js` (新建)
|
||||
|
||||
```javascript
|
||||
export default {
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
primary: {
|
||||
DEFAULT: 'var(--color-primary)',
|
||||
hover: 'var(--color-primary-hover)',
|
||||
light: 'var(--color-primary-light)',
|
||||
},
|
||||
},
|
||||
boxShadow: {
|
||||
'card': 'var(--shadow-md)',
|
||||
'hover': 'var(--shadow-lg)',
|
||||
},
|
||||
transitionDuration: {
|
||||
'fast': '150ms',
|
||||
'normal': '200ms',
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
### Phase 2: 基础组件库 (P0)
|
||||
|
||||
#### 2.1 Button 组件
|
||||
|
||||
**文件**: `desktop/src/components/ui/Button.tsx`
|
||||
|
||||
```tsx
|
||||
import { forwardRef } from 'react';
|
||||
import { motion } from 'framer-motion';
|
||||
import { cn } from '../../lib/utils';
|
||||
|
||||
interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
||||
variant?: 'primary' | 'secondary' | 'ghost' | 'danger';
|
||||
size?: 'sm' | 'md' | 'lg';
|
||||
loading?: boolean;
|
||||
}
|
||||
|
||||
export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
|
||||
({ className, variant = 'primary', size = 'md', loading, children, disabled, ...props }, ref) => {
|
||||
return (
|
||||
<motion.button
|
||||
ref={ref}
|
||||
whileTap={{ scale: 0.98 }}
|
||||
className={cn(
|
||||
'inline-flex items-center justify-center font-medium rounded-lg transition-colors',
|
||||
'focus:outline-none focus-visible:ring-2 focus-visible:ring-primary focus-visible:ring-offset-2',
|
||||
'disabled:opacity-50 disabled:cursor-not-allowed',
|
||||
variants[variant],
|
||||
sizes[size],
|
||||
className
|
||||
)}
|
||||
disabled={disabled || loading}
|
||||
{...props}
|
||||
>
|
||||
{loading && <Spinner className="mr-2" />}
|
||||
{children}
|
||||
</motion.button>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
const variants = {
|
||||
primary: 'bg-primary text-white hover:bg-primary-hover',
|
||||
secondary: 'bg-gray-100 text-gray-900 hover:bg-gray-200',
|
||||
ghost: 'text-gray-600 hover:bg-gray-100',
|
||||
danger: 'bg-red-500 text-white hover:bg-red-600',
|
||||
};
|
||||
|
||||
const sizes = {
|
||||
sm: 'px-3 py-1.5 text-xs',
|
||||
md: 'px-4 py-2 text-sm',
|
||||
lg: 'px-6 py-3 text-base',
|
||||
};
|
||||
```
|
||||
|
||||
#### 2.2 Card 组件
|
||||
|
||||
**文件**: `desktop/src/components/ui/Card.tsx`
|
||||
|
||||
```tsx
|
||||
import { motion } from 'framer-motion';
|
||||
import { cn } from '../../lib/utils';
|
||||
|
||||
interface CardProps {
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
hoverable?: boolean;
|
||||
onClick?: () => void;
|
||||
}
|
||||
|
||||
export function Card({ children, className, hoverable, onClick }: CardProps) {
|
||||
const Component = hoverable ? motion.div : 'div';
|
||||
|
||||
return (
|
||||
<Component
|
||||
className={cn(
|
||||
'rounded-xl border border-gray-200 bg-white p-4 shadow-sm',
|
||||
'dark:border-gray-700 dark:bg-gray-800',
|
||||
hoverable && 'cursor-pointer hover:shadow-md transition-shadow duration-200',
|
||||
className
|
||||
)}
|
||||
{...(hoverable && {
|
||||
whileHover: { y: -2 },
|
||||
onClick,
|
||||
})}
|
||||
>
|
||||
{children}
|
||||
</Component>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
#### 2.3 cn() 工具函数
|
||||
|
||||
**文件**: `desktop/src/lib/utils.ts`
|
||||
|
||||
```typescript
|
||||
import { clsx, type ClassValue } from 'clsx';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
|
||||
export function cn(...inputs: ClassValue[]) {
|
||||
return twMerge(clsx(inputs));
|
||||
}
|
||||
```
|
||||
|
||||
**原则**: 使用 SVG 图标 (lucide-react),不使用 emoji 作为 UI 元素
|
||||
|
||||
| 文件 | 当前 | 修改为 |
|
||||
|------|------|--------|
|
||||
| `ChatArea.tsx:79` | `🤖` | `<BotIcon className="w-10 h-10 text-gray-400" />` |
|
||||
| `ChatArea.tsx:279` | `🦞` (消息气泡) | `<ZClawLogo className="w-6 h-6" />` (自定义图标) |
|
||||
| `App.tsx:79` | `🤖` | `<BotIcon />` |
|
||||
| `App.tsx:98` | `👥` | `<UsersIcon />` |
|
||||
| `Sidebar.tsx:98` | 用户头像 emoji | 首字母 + 渐变背景 |
|
||||
|
||||
### Phase 3: 可访问性改进 (P0)
|
||||
|
||||
#### 3.1 添加 aria-label
|
||||
|
||||
**关键文件**:
|
||||
- `Sidebar.tsx` - 设置按钮、tab 切换
|
||||
- `ChatArea.tsx` - 发送按钮、附件按钮、模型选择器
|
||||
- `RightPanel.tsx` - tab 切换、刷新按钮
|
||||
- `SettingsLayout.tsx` - 返回按钮、菜单项
|
||||
|
||||
```tsx
|
||||
// 示例修复
|
||||
<button
|
||||
onClick={onOpenSettings}
|
||||
aria-label="打开设置"
|
||||
className="..."
|
||||
>
|
||||
<Settings className="w-4 h-4" />
|
||||
</button>
|
||||
```
|
||||
|
||||
#### 3.2 焦点状态增强
|
||||
|
||||
```css
|
||||
/* 全局焦点样式 */
|
||||
:focus-visible {
|
||||
outline: 2px solid var(--color-primary);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
/* 按钮焦点 */
|
||||
.btn:focus-visible {
|
||||
ring: 2px;
|
||||
ring-color: var(--color-primary);
|
||||
ring-offset: 2px;
|
||||
}
|
||||
```
|
||||
|
||||
#### 3.3 颜色对比度修复
|
||||
|
||||
| 当前 | 对比度 | 修复 |
|
||||
|------|--------|------|
|
||||
| `text-gray-400` on white | 3.1:1 (FAIL) | 改为 `text-gray-500` (#6b7280) 4.6:1 |
|
||||
| `text-gray-300` on white | 2.9:1 (FAIL) | 改为 `text-gray-600` (#4b5563) 7.0:1 |
|
||||
|
||||
### Phase 4: 交互与动画增强 (P1)
|
||||
|
||||
#### 4.1 Framer Motion 动画系统
|
||||
|
||||
**新文件**: `desktop/src/lib/animations.ts`
|
||||
|
||||
```typescript
|
||||
import { Variants } from 'framer-motion';
|
||||
|
||||
// 页面切换动画
|
||||
export const pageVariants: Variants = {
|
||||
initial: { opacity: 0, y: 10 },
|
||||
animate: { opacity: 1, y: 0 },
|
||||
exit: { opacity: 0, y: -10 },
|
||||
};
|
||||
|
||||
// 列表项交错动画
|
||||
export const listItemVariants: Variants = {
|
||||
hidden: { opacity: 0, x: -10 },
|
||||
visible: { opacity: 1, x: 0 },
|
||||
};
|
||||
|
||||
// 按钮点击动画
|
||||
export const buttonTap = { scale: 0.98 };
|
||||
|
||||
// 卡片悬停动画
|
||||
export const cardHover = { y: -2, boxShadow: '0 10px 25px -5px rgb(0 0 0 / 0.1)' };
|
||||
|
||||
// 默认过渡配置
|
||||
export const defaultTransition = {
|
||||
duration: 0.2,
|
||||
ease: [0.4, 0, 0.2, 1],
|
||||
};
|
||||
```
|
||||
|
||||
**使用示例**:
|
||||
```tsx
|
||||
import { motion, AnimatePresence } from 'framer-motion';
|
||||
import { pageVariants, defaultTransition } from '../lib/animations';
|
||||
|
||||
// 页面切换
|
||||
<AnimatePresence mode="wait">
|
||||
<motion.div
|
||||
key={view}
|
||||
variants={pageVariants}
|
||||
initial="initial"
|
||||
animate="animate"
|
||||
exit="exit"
|
||||
transition={defaultTransition}
|
||||
>
|
||||
{content}
|
||||
</motion.div>
|
||||
</AnimatePresence>
|
||||
```
|
||||
|
||||
**新文件**: `desktop/src/components/ui/Skeleton.tsx`
|
||||
|
||||
```tsx
|
||||
export function Skeleton({ className }: { className?: string }) {
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"animate-pulse bg-gray-200 dark:bg-gray-700 rounded",
|
||||
className
|
||||
)}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export function CardSkeleton() {
|
||||
return (
|
||||
<div className="rounded-xl border border-gray-200 p-4">
|
||||
<Skeleton className="h-4 w-24 mb-3" />
|
||||
<Skeleton className="h-3 w-full mb-2" />
|
||||
<Skeleton className="h-3 w-3/4" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
#### 4.3 Toast 通知系统
|
||||
|
||||
**新文件**: `desktop/src/components/ui/Toast.tsx`
|
||||
|
||||
用于替代 `alert()` 和内联错误消息。
|
||||
|
||||
### Phase 5: 视觉层次优化 (P1)
|
||||
|
||||
#### 5.1 卡片阴影增强
|
||||
|
||||
```diff
|
||||
- className="rounded-xl border border-gray-200 bg-white p-4 shadow-sm"
|
||||
+ className="rounded-xl border border-gray-200 bg-white p-4 shadow-sm hover:shadow-md transition-shadow duration-200"
|
||||
```
|
||||
|
||||
#### 5.2 间距标准化
|
||||
|
||||
| 区域 | 当前 | 标准 |
|
||||
|------|------|------|
|
||||
| 页面内边距 | 不一致 | `p-6` (24px) |
|
||||
| 卡片内边距 | `p-3`/`p-4` | `p-4` (16px) |
|
||||
| 列表项间距 | `space-y-1`/`space-y-2` | `space-y-2` (8px) |
|
||||
| 区域间距 | `space-y-3`/`space-y-4` | `space-y-4` (16px) |
|
||||
|
||||
#### 5.3 字体大小优化
|
||||
|
||||
| 类型 | 当前 | 建议 |
|
||||
|------|------|------|
|
||||
| 正文 | `text-xs` (12px) | `text-sm` (14px) |
|
||||
| 小标签 | `text-[10px]` | `text-xs` (12px) |
|
||||
| 标题 | `text-lg` | 保持 |
|
||||
|
||||
### Phase 6: 用户体验改进 (P2)
|
||||
|
||||
#### 6.1 空状态设计
|
||||
|
||||
**新组件**: `EmptyState.tsx`
|
||||
|
||||
```tsx
|
||||
interface EmptyStateProps {
|
||||
icon: React.ReactNode;
|
||||
title: string;
|
||||
description: string;
|
||||
action?: React.ReactNode;
|
||||
}
|
||||
|
||||
export function EmptyState({ icon, title, description, action }: EmptyStateProps) {
|
||||
return (
|
||||
<div className="flex-1 flex items-center justify-center p-6">
|
||||
<div className="text-center max-w-sm">
|
||||
<div className="w-16 h-16 bg-gray-100 dark:bg-gray-800 rounded-full flex items-center justify-center mx-auto mb-4 text-gray-400">
|
||||
{icon}
|
||||
</div>
|
||||
<h3 className="text-base font-semibold text-gray-700 dark:text-gray-300 mb-2">
|
||||
{title}
|
||||
</h3>
|
||||
<p className="text-sm text-gray-500 dark:text-gray-400 mb-4">
|
||||
{description}
|
||||
</p>
|
||||
{action}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
#### 6.2 错误状态设计
|
||||
|
||||
- 使用红色边框和背景
|
||||
- 显示错误图标
|
||||
- 提供重试按钮
|
||||
|
||||
#### 6.3 加载状态改进
|
||||
|
||||
- 按钮加载时禁用并显示 spinner
|
||||
- 列表加载时显示骨架屏
|
||||
- 全局加载时显示顶部进度条
|
||||
|
||||
---
|
||||
|
||||
## 实施顺序
|
||||
|
||||
### 阶段 1: 基础设施 (2-3 天)
|
||||
1. 安装依赖: `framer-motion clsx tailwind-merge`
|
||||
2. 创建 CSS 变量系统 (含完整暗黑模式)
|
||||
3. 创建 tailwind.config.js
|
||||
4. 创建 utils.ts (cn 函数)
|
||||
5. 创建 animations.ts (Framer Motion 预设)
|
||||
|
||||
### 阶段 2: 基础组件库 (2-3 天)
|
||||
1. 创建 Button 组件 (含变体: primary, secondary, ghost)
|
||||
2. 创建 Card 组件 (含悬停动画)
|
||||
3. 创建 Input 组件 (含焦点状态)
|
||||
4. 创建 Badge 组件
|
||||
5. 创建 Skeleton 组件
|
||||
6. 创建 EmptyState 组件
|
||||
7. 创建 Toast 组件
|
||||
|
||||
### 阶段 3: 可访问性修复 (1-2 天)
|
||||
1. 添加 aria-label 到所有图标按钮
|
||||
2. 修复颜色对比度问题
|
||||
3. 增强焦点状态
|
||||
4. 添加键盘导航支持
|
||||
|
||||
### 阶段 4: 视觉优化 (2-3 天)
|
||||
1. 移除所有 emoji 图标,替换为 SVG
|
||||
2. 使用基础组件库重构现有组件
|
||||
3. 标准化间距
|
||||
4. 增强卡片阴影和悬停效果
|
||||
5. 完善暗黑模式支持
|
||||
|
||||
### 阶段 5: 交互增强 (2-3 天)
|
||||
1. 添加 Framer Motion 页面切换动画
|
||||
2. 添加列表项动画 (stagger)
|
||||
3. 添加按钮点击反馈
|
||||
4. 实现骨架屏加载
|
||||
5. 集成 Toast 通知系统
|
||||
|
||||
### 阶段 6: 组件重构 (2-3 天)
|
||||
1. 重构 Sidebar 组件 (使用新组件库 + 动画)
|
||||
2. 重构 ChatArea 组件
|
||||
3. 重构 RightPanel 组件
|
||||
4. 重构 SettingsLayout 组件
|
||||
5. 完整暗黑模式测试
|
||||
|
||||
---
|
||||
|
||||
## 关键文件清单
|
||||
|
||||
### 需要修改的文件
|
||||
|
||||
| 文件 | 修改内容 |
|
||||
|------|----------|
|
||||
| `desktop/src/index.css` | 添加 CSS 变量系统 |
|
||||
| `desktop/src/components/Sidebar.tsx` | aria-label, 动画, emoji 移除 |
|
||||
| `desktop/src/components/ChatArea.tsx` | aria-label, emoji 移除, 空状态 |
|
||||
| `desktop/src/components/RightPanel.tsx` | aria-label, 间距标准化 |
|
||||
| `desktop/src/components/Settings/SettingsLayout.tsx` | aria-label, 间距标准化 |
|
||||
| `desktop/src/App.tsx` | emoji 移除, 空状态组件 |
|
||||
|
||||
### 需要新建的文件
|
||||
|
||||
| 文件 | 用途 |
|
||||
|------|------|
|
||||
| `desktop/tailwind.config.js` | Tailwind 自定义配置 |
|
||||
| `desktop/src/components/ui/Button.tsx` | 按钮组件 |
|
||||
| `desktop/src/components/ui/Card.tsx` | 卡片组件 |
|
||||
| `desktop/src/components/ui/Input.tsx` | 输入框组件 |
|
||||
| `desktop/src/components/ui/Badge.tsx` | 标签组件 |
|
||||
| `desktop/src/components/ui/Skeleton.tsx` | 骨架屏组件 |
|
||||
| `desktop/src/components/ui/EmptyState.tsx` | 空状态组件 |
|
||||
| `desktop/src/components/ui/Toast.tsx` | Toast 通知组件 |
|
||||
| `desktop/src/lib/utils.ts` | cn() 工具函数 |
|
||||
| `desktop/src/lib/animations.ts` | Framer Motion 动画预设 |
|
||||
|
||||
### 需要安装的依赖
|
||||
|
||||
```bash
|
||||
cd desktop
|
||||
pnpm add framer-motion clsx tailwind-merge
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 验证方法
|
||||
|
||||
### 1. 视觉验证
|
||||
```bash
|
||||
pnpm tauri:dev
|
||||
```
|
||||
- 检查所有页面在浅色/深色模式下的显示
|
||||
- 检查所有交互元素的悬停状态
|
||||
- 检查所有空状态的显示
|
||||
|
||||
### 2. 可访问性验证
|
||||
- 使用 Chrome DevTools Lighthouse 进行可访问性审计
|
||||
- 使用 Tab 键进行键盘导航测试
|
||||
- 使用屏幕阅读器测试 (NVDA/JAWS)
|
||||
|
||||
### 3. 类型检查
|
||||
```bash
|
||||
cd desktop && pnpm tsc --noEmit
|
||||
```
|
||||
|
||||
### 4. 构建验证
|
||||
```bash
|
||||
pnpm build
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 预期成果
|
||||
|
||||
1. **设计系统**: 完整的 CSS 变量和 Tailwind 配置
|
||||
2. **组件库**: 7 个可复用 UI 组件 (Button, Card, Input, Badge, Skeleton, EmptyState, Toast)
|
||||
3. **可访问性**: Lighthouse 可访问性分数 > 90
|
||||
4. **暗黑模式**: 所有组件完整支持暗黑模式
|
||||
5. **动画系统**: Framer Motion 动画预设和页面过渡
|
||||
6. **视觉一致性**: 所有组件遵循统一设计规范
|
||||
7. **无 Emoji**: 所有 UI 图标使用 SVG
|
||||
|
||||
---
|
||||
|
||||
*计划创建: 2026-03-15*
|
||||
*预计完成: 11-17 个工作日*
|
||||
663
docs/archive/old-plans/fancy-sprouting-teacup.md
Normal file
@@ -0,0 +1,663 @@
|
||||
# ZCLAW Hands & Workflow 集成开发方案
|
||||
|
||||
## 上下文
|
||||
|
||||
**目标**: 将 ZCLAW 的 Hands 和 Workflow 功能深度集成到 ZClaw 桌面客户端,提供与 ZCLAW Web 界面对等的用户体验。
|
||||
|
||||
**当前状态**:
|
||||
- ZClaw 已有基础的 `HandsPanel.tsx` 和 `WorkflowList.tsx` 组件
|
||||
- 这些组件功能有限,缺少 ZCLAW 的核心 UI 特性
|
||||
- ZCLAW v0.4.0 提供了 8 个 Hands 和完整的 Workflow/Scheduler 系统
|
||||
|
||||
**参考界面**: http://127.0.0.1:50051 (ZCLAW Dashboard)
|
||||
|
||||
---
|
||||
|
||||
## 一、ZCLAW 界面分析总结
|
||||
|
||||
### 1.1 Hands 页面设计
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Hands — Curated Autonomous Capability Packages │
|
||||
│ Available 8 Active │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ ┌─────────────────────────────────────────────────────────┐ │
|
||||
│ │ 🌐 Browser Hand [READY] │ │
|
||||
│ │ Autonomous web browser — navigates sites... │ │
|
||||
│ │ │ │
|
||||
│ │ REQUIREMENTS │ │
|
||||
│ │ ✓ Python 3 must be installed │ │
|
||||
│ │ ✓ Chromium or Google Chrome must be installed │ │
|
||||
│ │ │ │
|
||||
│ │ 18 tool(s) · 3 metric(s) [productivity] │ │
|
||||
│ │ [Details] [Activate] │ │
|
||||
│ └─────────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**详情弹窗内容**:
|
||||
- AGENT CONFIG: Provider, Model
|
||||
- REQUIREMENTS: 检查项和状态 (✓/✗)
|
||||
- TOOLS: 工具名称列表
|
||||
- DASHBOARD METRICS: 指标名称列表
|
||||
- Activate 按钮
|
||||
|
||||
### 1.2 Workflows 页面设计
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Workflows │
|
||||
│ What are Workflows? Workflows chain multiple agents... │
|
||||
│ [List] [Visual Builder] [+ New Workflow] │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ NAME │ STEPS │ CREATED │ ACTIONS │
|
||||
│ ──────────────────┼───────┼──────────────┼────────────────────│
|
||||
│ 测试工作流 │ 1 │ 2026/3/14 │ [Run][Edit][Del] │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 1.3 Scheduler 页面设计
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Scheduler [+ New Job] │
|
||||
│ [Scheduled Jobs] [Event Triggers] [Run History] │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ Scheduled Jobs │
|
||||
│ Create cron-based scheduled jobs... │
|
||||
│ │
|
||||
│ [No scheduled jobs] │
|
||||
│ Create a cron job to run agents on a recurring schedule. │
|
||||
│ [+ Create Scheduled Job] │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 1.4 Approvals 页面设计
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Execution Approvals [Refresh] │
|
||||
│ [All] [Pending] [Approved] [Rejected] │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ [No approvals] │
|
||||
│ When agents request permission for sensitive actions, │
|
||||
│ they'll appear here. │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 二、ZClaw 现有实现分析
|
||||
|
||||
### 2.1 已有组件
|
||||
|
||||
| 文件 | 功能 | 完成度 |
|
||||
|------|------|--------|
|
||||
| `HandsPanel.tsx` | Hand 列表、触发、审批、取消 | 40% |
|
||||
| `WorkflowList.tsx` | Workflow 列表、执行 | 30% |
|
||||
| `TriggersPanel.tsx` | Trigger 列表 | 20% |
|
||||
| `gatewayStore.ts` | 状态管理 (Hands/Workflow API) | 60% |
|
||||
|
||||
### 2.2 缺失功能
|
||||
|
||||
1. **Hands**:
|
||||
- ❌ 详情弹窗 (Details Modal)
|
||||
- ❌ Requirements 状态检查可视化
|
||||
- ❌ 工具和指标列表展示
|
||||
- ❌ Agent Config 显示 (Provider/Model)
|
||||
- ❌ 激活动画和状态反馈
|
||||
- ❌ 分类标签 (productivity/data/content/communication)
|
||||
|
||||
2. **Workflows**:
|
||||
- ❌ 创建/编辑 Workflow
|
||||
- ❌ Visual Builder
|
||||
- ❌ 执行历史查看
|
||||
- ❌ 步骤详情展示
|
||||
|
||||
3. **Scheduler**:
|
||||
- ❌ Scheduled Jobs 管理
|
||||
- ❌ Event Triggers 管理
|
||||
- ❌ Cron 表达式编辑器
|
||||
- ❌ Run History
|
||||
|
||||
4. **Approvals**:
|
||||
- ❌ 独立 Approvals 页面
|
||||
- ❌ 筛选功能 (All/Pending/Approved/Rejected)
|
||||
- ❌ 审批详情展示
|
||||
|
||||
---
|
||||
|
||||
## 三、开发方案
|
||||
|
||||
### 3.1 Phase 1: 增强 HandsPanel (优先级: 高)
|
||||
|
||||
**目标**: 提供与 ZCLAW 对等的 Hands 管理体验
|
||||
|
||||
**文件修改**:
|
||||
- `desktop/src/components/HandsPanel.tsx` (重写)
|
||||
- `desktop/src/components/HandDetailsModal.tsx` (新建)
|
||||
- `desktop/src/store/gatewayStore.ts` (扩展)
|
||||
|
||||
**UI 设计**:
|
||||
|
||||
```tsx
|
||||
// HandCard 组件结构
|
||||
<div className="hand-card">
|
||||
<div className="hand-header">
|
||||
<span className="hand-icon">{hand.icon}</span>
|
||||
<h3>{hand.name}</h3>
|
||||
<StatusBadge status={hand.status} /> {/* READY/SETUP NEEDED/RUNNING */}
|
||||
</div>
|
||||
|
||||
<p className="hand-description">{hand.description}</p>
|
||||
|
||||
{/* Requirements 检查 */}
|
||||
{hand.requirements && (
|
||||
<div className="hand-requirements">
|
||||
<span className="label">REQUIREMENTS</span>
|
||||
{hand.requirements.map(req => (
|
||||
<div className={req.met ? 'met' : 'unmet'}>
|
||||
<span>{req.met ? '✓' : '✗'}</span>
|
||||
<span>{req.description}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* 元信息 */}
|
||||
<div className="hand-meta">
|
||||
<span>{hand.toolCount} tool(s)</span>
|
||||
<span>{hand.metricCount} metric(s)</span>
|
||||
<span className="category-tag">{hand.category}</span>
|
||||
</div>
|
||||
|
||||
{/* 操作按钮 */}
|
||||
<div className="hand-actions">
|
||||
<Button variant="outline" onClick={onDetails}>Details</Button>
|
||||
<Button variant="primary" onClick={onActivate} disabled={!hand.requirementsMet}>
|
||||
{hand.status === 'running' ? 'Running...' : 'Activate'}
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
**HandDetailsModal 组件**:
|
||||
|
||||
```tsx
|
||||
// 详情弹窗
|
||||
<Modal>
|
||||
<ModalHeader>
|
||||
<span className="icon">{hand.icon}</span>
|
||||
<h2>{hand.name}</h2>
|
||||
<StatusBadge status={hand.status} />
|
||||
</ModalHeader>
|
||||
|
||||
<ModalBody>
|
||||
{/* Agent Config */}
|
||||
<Section title="AGENT CONFIG">
|
||||
<Row label="Provider" value={hand.provider} />
|
||||
<Row label="Model" value={hand.model} />
|
||||
</Section>
|
||||
|
||||
{/* Requirements */}
|
||||
<Section title="REQUIREMENTS">
|
||||
{hand.requirements.map(req => (
|
||||
<RequirementItem {...req} />
|
||||
))}
|
||||
</Section>
|
||||
|
||||
{/* Tools */}
|
||||
<Section title="TOOLS">
|
||||
<ToolGrid tools={hand.tools} />
|
||||
</Section>
|
||||
|
||||
{/* Dashboard Metrics */}
|
||||
<Section title="DASHBOARD METRICS">
|
||||
<MetricList metrics={hand.metrics} />
|
||||
</Section>
|
||||
</ModalBody>
|
||||
|
||||
<ModalFooter>
|
||||
<Button variant="outline" onClick={onClose}>Close</Button>
|
||||
<Button variant="primary" onClick={onActivate}>Activate</Button>
|
||||
</ModalFooter>
|
||||
</Modal>
|
||||
```
|
||||
|
||||
**API 扩展**:
|
||||
|
||||
```typescript
|
||||
// gatewayStore.ts 扩展
|
||||
interface Hand {
|
||||
id: string;
|
||||
name: string;
|
||||
description: string;
|
||||
status: 'idle' | 'running' | 'needs_approval' | 'error' | 'unavailable';
|
||||
icon?: string;
|
||||
category?: string; // productivity, data, content, communication
|
||||
provider?: string;
|
||||
model?: string;
|
||||
requirements?: Array<{
|
||||
description: string;
|
||||
met: boolean;
|
||||
details?: string;
|
||||
}>;
|
||||
tools?: string[];
|
||||
metrics?: string[];
|
||||
toolCount?: number;
|
||||
metricCount?: number;
|
||||
currentRunId?: string;
|
||||
}
|
||||
|
||||
// 新增 API 调用
|
||||
getHandDetails: (name: string) => Promise<HandDetails>;
|
||||
activateHand: (name: string, params?: Record<string, unknown>) => Promise<HandRun>;
|
||||
deactivateHand: (name: string) => Promise<void>;
|
||||
```
|
||||
|
||||
### 3.2 Phase 2: 增强 WorkflowList (优先级: 高)
|
||||
|
||||
**目标**: 提供完整的 Workflow 管理能力
|
||||
|
||||
**文件修改**:
|
||||
- `desktop/src/components/WorkflowList.tsx` (重写)
|
||||
- `desktop/src/components/WorkflowEditor.tsx` (新建)
|
||||
- `desktop/src/components/WorkflowHistory.tsx` (新建)
|
||||
- `desktop/src/store/gatewayStore.ts` (扩展)
|
||||
|
||||
**UI 设计**:
|
||||
|
||||
```tsx
|
||||
// WorkflowList 组件结构
|
||||
<div className="workflow-list">
|
||||
<div className="workflow-header">
|
||||
<h2>Workflows</h2>
|
||||
<div className="view-toggle">
|
||||
<Button active={view === 'list'}>List</Button>
|
||||
<Button active={view === 'visual'}>Visual Builder</Button>
|
||||
</div>
|
||||
<Button variant="primary" onClick={onCreate}>+ New Workflow</Button>
|
||||
</div>
|
||||
|
||||
<p className="workflow-description">
|
||||
Workflows chain multiple agents into automated pipelines...
|
||||
</p>
|
||||
|
||||
<table className="workflow-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>NAME</th>
|
||||
<th>STEPS</th>
|
||||
<th>CREATED</th>
|
||||
<th>ACTIONS</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{workflows.map(wf => (
|
||||
<tr key={wf.id}>
|
||||
<td>{wf.name}</td>
|
||||
<td>{wf.steps}</td>
|
||||
<td>{formatDate(wf.createdAt)}</td>
|
||||
<td>
|
||||
<Button size="sm" onClick={() => onRun(wf.id)}>Run</Button>
|
||||
<Button size="sm" onClick={() => onEdit(wf.id)}>Edit</Button>
|
||||
<Button size="sm" onClick={() => onHistory(wf.id)}>History</Button>
|
||||
<Button size="sm" variant="danger" onClick={() => onDelete(wf.id)}>Delete</Button>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
```
|
||||
|
||||
**WorkflowEditor 组件** (简化版):
|
||||
|
||||
```tsx
|
||||
<WorkflowEditor workflow={workflow}>
|
||||
<div className="workflow-editor">
|
||||
<div className="workflow-info">
|
||||
<Input label="Name" value={workflow.name} onChange={...} />
|
||||
<Textarea label="Description" value={workflow.description} onChange={...} />
|
||||
</div>
|
||||
|
||||
<div className="workflow-steps">
|
||||
<h3>Steps</h3>
|
||||
{workflow.steps.map((step, index) => (
|
||||
<WorkflowStep
|
||||
key={index}
|
||||
step={step}
|
||||
onEdit={() => editStep(index)}
|
||||
onDelete={() => deleteStep(index)}
|
||||
/>
|
||||
))}
|
||||
<Button onClick={addStep}>+ Add Step</Button>
|
||||
</div>
|
||||
|
||||
<div className="workflow-actions">
|
||||
<Button variant="outline" onClick={onCancel}>Cancel</Button>
|
||||
<Button variant="primary" onClick={onSave}>Save Workflow</Button>
|
||||
</div>
|
||||
</div>
|
||||
</WorkflowEditor>
|
||||
```
|
||||
|
||||
**API 扩展**:
|
||||
|
||||
```typescript
|
||||
// gatewayStore.ts 扩展
|
||||
interface Workflow {
|
||||
id: string;
|
||||
name: string;
|
||||
description?: string;
|
||||
steps: WorkflowStep[];
|
||||
createdAt: string;
|
||||
updatedAt?: string;
|
||||
}
|
||||
|
||||
interface WorkflowStep {
|
||||
id: string;
|
||||
agentId: string;
|
||||
promptTemplate: string;
|
||||
inputMapping?: Record<string, string>;
|
||||
outputMapping?: Record<string, string>;
|
||||
condition?: string;
|
||||
timeout?: number;
|
||||
}
|
||||
|
||||
// 新增 API 调用
|
||||
createWorkflow: (workflow: CreateWorkflowInput) => Promise<Workflow>;
|
||||
updateWorkflow: (id: string, updates: Partial<Workflow>) => Promise<Workflow>;
|
||||
getWorkflowHistory: (id: string) => Promise<WorkflowRun[]>;
|
||||
getWorkflowDetails: (id: string) => Promise<Workflow>;
|
||||
```
|
||||
|
||||
### 3.3 Phase 3: 新建 SchedulerPanel (优先级: 中)
|
||||
|
||||
**目标**: 提供定时任务和事件触发器管理
|
||||
|
||||
**文件新建**:
|
||||
- `desktop/src/components/SchedulerPanel.tsx`
|
||||
- `desktop/src/components/ScheduledJobEditor.tsx`
|
||||
- `desktop/src/components/EventTriggerEditor.tsx`
|
||||
|
||||
**UI 设计**:
|
||||
|
||||
```tsx
|
||||
<SchedulerPanel>
|
||||
<Tabs defaultValue="scheduled">
|
||||
<TabsList>
|
||||
<TabsTrigger value="scheduled">Scheduled Jobs</TabsTrigger>
|
||||
<TabsTrigger value="triggers">Event Triggers</TabsTrigger>
|
||||
</TabsList>
|
||||
|
||||
<TabsContent value="scheduled">
|
||||
<div className="scheduled-jobs">
|
||||
<Button onClick={onCreateJob}>+ Create Scheduled Job</Button>
|
||||
|
||||
{jobs.length === 0 ? (
|
||||
<EmptyState
|
||||
title="No scheduled jobs"
|
||||
description="Create a cron job to run agents on a recurring schedule."
|
||||
action="+ Create Scheduled Job"
|
||||
onAction={onCreateJob}
|
||||
/>
|
||||
) : (
|
||||
<JobList jobs={jobs} onEdit={onEditJob} onDelete={onDeleteJob} />
|
||||
)}
|
||||
</div>
|
||||
</TabsContent>
|
||||
|
||||
<TabsContent value="triggers">
|
||||
<div className="event-triggers">
|
||||
<p>Event triggers fire agents in response to system events...</p>
|
||||
{triggers.length === 0 ? (
|
||||
<EmptyState title="No event triggers" />
|
||||
) : (
|
||||
<TriggerList triggers={triggers} />
|
||||
)}
|
||||
</div>
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
</SchedulerPanel>
|
||||
```
|
||||
|
||||
### 3.4 Phase 4: 新建 ApprovalsPanel (优先级: 中)
|
||||
|
||||
**目标**: 提供审批管理界面
|
||||
|
||||
**文件新建**:
|
||||
- `desktop/src/components/ApprovalsPanel.tsx`
|
||||
|
||||
**UI 设计**:
|
||||
|
||||
```tsx
|
||||
<ApprovalsPanel>
|
||||
<div className="approvals-header">
|
||||
<h2>Execution Approvals</h2>
|
||||
<Button onClick={onRefresh}>Refresh</Button>
|
||||
</div>
|
||||
|
||||
<div className="approvals-filters">
|
||||
<Button active={filter === 'all'}>All</Button>
|
||||
<Button active={filter === 'pending'}>Pending</Button>
|
||||
<Button active={filter === 'approved'}>Approved</Button>
|
||||
<Button active={filter === 'rejected'}>Rejected</Button>
|
||||
</div>
|
||||
|
||||
<div className="approvals-list">
|
||||
{filteredApprovals.length === 0 ? (
|
||||
<EmptyState
|
||||
title="No approvals"
|
||||
description="When agents request permission for sensitive actions, they'll appear here."
|
||||
/>
|
||||
) : (
|
||||
filteredApprovals.map(approval => (
|
||||
<ApprovalCard
|
||||
key={approval.id}
|
||||
approval={approval}
|
||||
onApprove={() => onApprove(approval.id)}
|
||||
onReject={() => onReject(approval.id)}
|
||||
/>
|
||||
))
|
||||
)}
|
||||
</div>
|
||||
</ApprovalsPanel>
|
||||
```
|
||||
|
||||
### 3.5 Phase 5: 导航重构 (优先级: 中)
|
||||
|
||||
**目标**: 重构导航结构,匹配 ZCLAW 布局
|
||||
|
||||
**文件修改**:
|
||||
- `desktop/src/components/Sidebar.tsx`
|
||||
- `desktop/src/components/RightPanel.tsx`
|
||||
- `desktop/src/App.tsx`
|
||||
|
||||
**新导航结构**:
|
||||
|
||||
```
|
||||
┌────────────────────┐
|
||||
│ ZCLAW │
|
||||
├────────────────────┤
|
||||
│ CHAT │
|
||||
│ └─ Chat │
|
||||
│ MONITOR │
|
||||
│ └─ Overview │
|
||||
│ └─ Analytics │
|
||||
│ └─ Logs │
|
||||
│ AGENTS │
|
||||
│ └─ Sessions │
|
||||
│ └─ Approvals │
|
||||
│ └─ Comms │
|
||||
│ AUTOMATION │
|
||||
│ └─ Workflows │
|
||||
│ └─ Scheduler │
|
||||
│ EXTENSIONS │
|
||||
│ └─ Channels │
|
||||
│ └─ Skills │
|
||||
│ └─ Hands │
|
||||
│ SYSTEM │
|
||||
│ └─ Runtime │
|
||||
│ └─ Settings │
|
||||
└────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 四、关键文件清单
|
||||
|
||||
### 4.1 需要修改的文件
|
||||
|
||||
| 文件路径 | 修改内容 |
|
||||
|----------|----------|
|
||||
| `desktop/src/components/HandsPanel.tsx` | 重写 HandCard,添加详情弹窗 |
|
||||
| `desktop/src/components/WorkflowList.tsx` | 添加创建/编辑功能 |
|
||||
| `desktop/src/store/gatewayStore.ts` | 扩展 Hand/Workflow 类型定义 |
|
||||
| `desktop/src/components/Sidebar.tsx` | 重构导航结构 |
|
||||
| `desktop/src/components/RightPanel.tsx` | 集成新组件 |
|
||||
| `desktop/src/lib/gateway-client.ts` | 添加新 API 调用 |
|
||||
|
||||
### 4.2 需要新建的文件
|
||||
|
||||
| 文件路径 | 功能 |
|
||||
|----------|------|
|
||||
| `desktop/src/components/HandDetailsModal.tsx` | Hand 详情弹窗 |
|
||||
| `desktop/src/components/WorkflowEditor.tsx` | Workflow 编辑器 |
|
||||
| `desktop/src/components/WorkflowHistory.tsx` | Workflow 执行历史 |
|
||||
| `desktop/src/components/SchedulerPanel.tsx` | Scheduler 管理面板 |
|
||||
| `desktop/src/components/ScheduledJobEditor.tsx` | 定时任务编辑器 |
|
||||
| `desktop/src/components/EventTriggerEditor.tsx` | 事件触发器编辑器 |
|
||||
| `desktop/src/components/ApprovalsPanel.tsx` | 审批管理面板 |
|
||||
|
||||
---
|
||||
|
||||
## 五、验证方案
|
||||
|
||||
### 5.1 手动测试
|
||||
|
||||
1. **Hands 测试**:
|
||||
- 启动 ZClaw,连接 ZCLAW (端口 50051)
|
||||
- 打开 Hands 标签
|
||||
- 验证 8 个 Hands 正确显示
|
||||
- 点击 Details 查看详情弹窗
|
||||
- 点击 Activate 激活一个 Hand
|
||||
- 验证状态变化和反馈
|
||||
|
||||
2. **Workflow 测试**:
|
||||
- 打开 Workflow 标签
|
||||
- 创建新 Workflow
|
||||
- 编辑 Workflow 步骤
|
||||
- 执行 Workflow
|
||||
- 查看执行历史
|
||||
|
||||
3. **Scheduler 测试**:
|
||||
- 创建定时任务
|
||||
- 编辑 Cron 表达式
|
||||
- 验证任务触发
|
||||
|
||||
4. **Approvals 测试**:
|
||||
- 触发需要审批的 Hand
|
||||
- 验证 Approvals 页面显示
|
||||
- 批准/拒绝审批
|
||||
|
||||
### 5.2 自动化测试
|
||||
|
||||
```bash
|
||||
# 运行相关测试
|
||||
pnpm vitest run tests/desktop/handsPanel.test.tsx
|
||||
pnpm vitest run tests/desktop/workflowList.test.tsx
|
||||
pnpm vitest run tests/desktop/gatewayStore.test.ts
|
||||
|
||||
# 类型检查
|
||||
pnpm tsc --noEmit
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 六、开发顺序 (根据用户确认)
|
||||
|
||||
**用户选择**:
|
||||
- ✅ 优先实现 Hands 增强
|
||||
- ✅ 需要完整实现 Scheduler 和 Approvals
|
||||
|
||||
**推荐开发顺序**:
|
||||
|
||||
| 顺序 | Phase | 工作量 | 说明 |
|
||||
|------|-------|--------|------|
|
||||
| 1 | Phase 1: HandsPanel 增强 | 2-3 天 | 最高优先级,核心功能 |
|
||||
| 2 | Phase 4: ApprovalsPanel | 1 天 | Hand 执行需要审批流程 |
|
||||
| 3 | Phase 2: WorkflowList 增强 | 2-3 天 | 完整工作流管理 |
|
||||
| 4 | Phase 3: SchedulerPanel | 2 天 | 定时任务和事件触发器 |
|
||||
| 5 | Phase 5: 导航重构 | 1-2 天 | 统一导航结构 |
|
||||
| **总计** | - | **8-11 天** | - |
|
||||
|
||||
---
|
||||
|
||||
## 六-A、第一步实施细节: HandsPanel 增强
|
||||
|
||||
### 文件修改清单
|
||||
|
||||
1. **`desktop/src/components/HandsPanel.tsx`** (重写)
|
||||
- 添加 HandCard 组件重构
|
||||
- 添加状态徽章 (READY/SETUP NEEDED/RUNNING)
|
||||
- 添加 Requirements 可视化
|
||||
- 添加分类标签
|
||||
- 添加工具/指标计数
|
||||
|
||||
2. **`desktop/src/components/HandDetailsModal.tsx`** (新建)
|
||||
- Agent Config 显示 (Provider/Model)
|
||||
- Requirements 列表
|
||||
- Tools 列表
|
||||
- Dashboard Metrics 列表
|
||||
- Activate 按钮
|
||||
|
||||
3. **`desktop/src/store/gatewayStore.ts`** (扩展)
|
||||
- 扩展 Hand 类型定义
|
||||
- 添加 getHandDetails API
|
||||
|
||||
4. **`desktop/src/lib/gateway-client.ts`** (扩展)
|
||||
- 添加 getHandDetails 方法
|
||||
|
||||
### UI 组件设计
|
||||
|
||||
```tsx
|
||||
// HandStatusBadge 组件
|
||||
type HandStatus = 'idle' | 'running' | 'needs_approval' | 'error' | 'unavailable' | 'setup_needed';
|
||||
|
||||
const STATUS_CONFIG: Record<HandStatus, { label: string; className: string }> = {
|
||||
idle: { label: 'READY', className: 'bg-green-100 text-green-700' },
|
||||
running: { label: 'RUNNING', className: 'bg-blue-100 text-blue-700 animate-pulse' },
|
||||
needs_approval: { label: 'NEEDS APPROVAL', className: 'bg-yellow-100 text-yellow-700' },
|
||||
error: { label: 'ERROR', className: 'bg-red-100 text-red-700' },
|
||||
unavailable: { label: 'UNAVAILABLE', className: 'bg-gray-100 text-gray-500' },
|
||||
setup_needed: { label: 'SETUP NEEDED', className: 'bg-orange-100 text-orange-700' },
|
||||
};
|
||||
|
||||
// RequirementItem 组件
|
||||
function RequirementItem({ description, met, details }: Requirement) {
|
||||
return (
|
||||
<div className={`flex items-start gap-2 text-sm ${met ? 'text-green-700' : 'text-red-600'}`}>
|
||||
<span className="flex-shrink-0">{met ? '✓' : '✗'}</span>
|
||||
<span>{description}</span>
|
||||
{details && <span className="text-gray-400 text-xs">({details})</span>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 七、风险与缓解
|
||||
|
||||
| 风险 | 影响 | 缓解措施 |
|
||||
|------|------|----------|
|
||||
| ZCLAW API 变更 | 高 | 使用实际 API 测试验证,保持与 ZCLAW v0.4.0 兼容 |
|
||||
| UI 复杂度 | 中 | 分阶段实现,先核心功能后高级功能 |
|
||||
| 性能问题 | 低 | 使用虚拟列表处理大量数据 |
|
||||
|
||||
---
|
||||
|
||||
*计划创建时间: 2026-03-14*
|
||||
*参考版本: ZCLAW v0.4.0*
|
||||
386
docs/archive/old-plans/immutable-imagining-naur.md
Normal file
@@ -0,0 +1,386 @@
|
||||
# ZClaw: 从 ZCLAW 迁移到 ZCLAW 可行性方案
|
||||
|
||||
> **规划日期**: 2026-03-13
|
||||
> **目标**: 制定从 ZCLAW 到 ZCLAW 的渐进式迁移策略,实现平稳过渡
|
||||
|
||||
---
|
||||
|
||||
## 一、背景与动机
|
||||
|
||||
### 1.1 当前架构 (ZCLAW)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ ZClaw Desktop (当前) │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ React 19 UI → Zustand Store → GatewayClient → ZCLAW │
|
||||
│ 技术栈: Tauri 2.0 + TypeScript + Node.js Gateway │
|
||||
│ 内存: >1GB | 启动: 2-5s | 安装: 500MB │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 1.2 目标架构 (ZCLAW)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ ZClaw Desktop (ZCLAW) │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ React 19 UI → Zustand Store → ZCLAWClient → ZCLAW │
|
||||
│ 技术栈: Tauri 2.0 + TypeScript + Rust Gateway │
|
||||
│ 内存: ~40MB | 启动: 180ms | 安装: 32MB │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 1.3 迁移动机
|
||||
|
||||
| 维度 | ZCLAW | ZCLAW | 提升 |
|
||||
|------|----------|----------|------|
|
||||
| **启动速度** | 5.98s | 180ms | **33x 更快** |
|
||||
| **内存占用** | 394MB | 40MB | **90% 更少** |
|
||||
| **安装大小** | 500MB | 32MB | **94% 更小** |
|
||||
| **安全防护** | 3 层 | 16 层 | **企业级安全** |
|
||||
| **通道支持** | 20+ | 40+ | **覆盖更广** |
|
||||
| **自主能力** | 无 | 7 Hands | **从被动到主动** |
|
||||
|
||||
---
|
||||
|
||||
## 二、核心差异分析
|
||||
|
||||
### 2.1 协议差异
|
||||
|
||||
| 方面 | ZCLAW | ZCLAW |
|
||||
|------|----------|----------|
|
||||
| **WebSocket URL** | `ws://127.0.0.1:18789` | `ws://127.0.0.1:4200/ws` |
|
||||
| **协议格式** | 自定义 JSON 帧 | 标准 JSON + gRPC |
|
||||
| **认证方式** | Ed25519 设备签名 | Ed25519 + JWT |
|
||||
|
||||
### 2.2 配置差异
|
||||
|
||||
| 方面 | ZCLAW | ZCLAW |
|
||||
|------|----------|----------|
|
||||
| **配置目录** | `~/.zclaw/` | `~/.zclaw/` |
|
||||
| **配置格式** | YAML/JSON | TOML |
|
||||
| **插件系统** | TypeScript (`index.ts`) | SKILL.md + WASM |
|
||||
|
||||
### 2.3 API 差异
|
||||
|
||||
| 功能 | ZCLAW RPC | ZCLAW API |
|
||||
|------|-------------|--------------|
|
||||
| 发送消息 | `agent` | `chat` / `/api/chat` |
|
||||
| 列出 Agent | `zclaw.clones.list` | `GET /api/agents` |
|
||||
| 获取配置 | `config.get` | `GET /api/config` |
|
||||
| 触发技能 | 插件系统 | `skill_trigger` |
|
||||
| Hand 自动化 | ❌ 无 | `hand_trigger` |
|
||||
| Workflow | ❌ 基础 | `workflow_execute` |
|
||||
|
||||
---
|
||||
|
||||
## 三、迁移策略:渐进式双轨
|
||||
|
||||
### 3.1 策略原则
|
||||
|
||||
1. **双版本并行**: 保持 ZCLAW 可用,同时开发 ZCLAW
|
||||
2. **适配层抽象**: 通过接口隔离后端差异
|
||||
3. **功能对等优先**: 先保证核心功能,再添加新特性
|
||||
4. **灰度发布**: Beta 测试验证后全面切换
|
||||
|
||||
### 3.2 迁移阶段
|
||||
|
||||
```
|
||||
Phase 1 (2周): 基础设施 ──────────────────────────────────────────►
|
||||
Phase 2 (2周): 客户端实现 ────────────────────────────────────────►
|
||||
Phase 3 (2周): 状态迁移 ──────────────────────────────────────────►
|
||||
Phase 4 (3周): 插件迁移 ──────────────────────────────────────────►
|
||||
Phase 5 (2周): Tauri 后端 ────────────────────────────────────────►
|
||||
Phase 6 (3周): UI 增强 ───────────────────────────────────────────►
|
||||
Phase 7 (2周): 测试验证 ──────────────────────────────────────────►
|
||||
────────────────────────────────────────────────────────────────────
|
||||
总工期: 16 周 (约 4 个月)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 四、详细实施计划
|
||||
|
||||
### Phase 1: 基础设施 (Week 1-2)
|
||||
|
||||
**目标**: 建立迁移基础架构
|
||||
|
||||
**关键任务**:
|
||||
1. 创建 `GatewayBackend` 接口抽象
|
||||
2. 创建 `ZCLAWClient` 骨架
|
||||
3. 配置双后端切换机制
|
||||
4. 设置 ZCLAW 开发环境
|
||||
|
||||
**交付物**:
|
||||
- `desktop/src/lib/types/gateway-backend.ts` - 接口定义
|
||||
- `desktop/src/lib/zclaw-client.ts` - 客户端骨架
|
||||
- `desktop/src/lib/backend-factory.ts` - 后端工厂
|
||||
|
||||
### Phase 2: 客户端实现 (Week 3-4)
|
||||
|
||||
**目标**: 完整实现 ZCLAW 客户端
|
||||
|
||||
**关键文件**: [gateway-client.ts](desktop/src/lib/gateway-client.ts)
|
||||
|
||||
**修改内容**:
|
||||
```typescript
|
||||
// 1. 抽取接口
|
||||
interface GatewayBackend {
|
||||
connect(): Promise<void>;
|
||||
disconnect(): void;
|
||||
chat(message: string, opts?: ChatOptions): Promise<{runId: string}>;
|
||||
onStream(callback: StreamCallback): () => void;
|
||||
// ... 其他方法
|
||||
}
|
||||
|
||||
// 2. ZCLAW 实现 (现有代码重构)
|
||||
class ZCLAWBackend implements GatewayBackend { ... }
|
||||
|
||||
// 3. ZCLAW 实现 (新建)
|
||||
class ZCLAWBackend implements GatewayBackend {
|
||||
private ws: WebSocket;
|
||||
private url = 'ws://127.0.0.1:4200/ws';
|
||||
|
||||
async connect(): Promise<void> {
|
||||
// ZCLAW 认证协议
|
||||
}
|
||||
|
||||
async chat(message: string, opts?: ChatOptions): Promise<{runId: string}> {
|
||||
// ZCLAW chat 格式
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Phase 3: 状态迁移 (Week 5-6)
|
||||
|
||||
**目标**: 更新状态管理层支持双后端
|
||||
|
||||
**关键文件**: [gatewayStore.ts](desktop/src/store/gatewayStore.ts)
|
||||
|
||||
**修改内容**:
|
||||
```typescript
|
||||
interface GatewayStore {
|
||||
// 新增
|
||||
backendType: 'zclaw' | 'zclaw';
|
||||
switchBackend(type: 'zclaw' | 'zclaw'): void;
|
||||
|
||||
// 修改 connect 方法
|
||||
connect: async (url?, token?) => {
|
||||
const backend = getBackendFactory().create(get().backendType);
|
||||
await backend.connect(url, token);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Phase 4: 插件迁移 (Week 7-9)
|
||||
|
||||
**目标**: 迁移现有插件到 ZCLAW 格式
|
||||
|
||||
| 插件 | 当前格式 | 目标格式 | 复杂度 |
|
||||
|------|----------|----------|--------|
|
||||
| `zclaw-chinese-models` | TypeScript | TOML 配置 | 中 |
|
||||
| `zclaw-feishu` | TypeScript | Rust/WASM | 高 |
|
||||
| `zclaw-ui` | TypeScript RPC | REST API | 高 |
|
||||
|
||||
**迁移方案**:
|
||||
```
|
||||
plugins/
|
||||
├── zclaw-chinese-models/
|
||||
│ ├── zclaw.plugin.json → 删除
|
||||
│ └── index.ts → 转换为 providers.toml
|
||||
│
|
||||
├── zclaw-feishu/
|
||||
│ └── index.ts → 迁移到 ZCLAW channels
|
||||
│
|
||||
└── zclaw-ui/
|
||||
└── index.ts → 拆分为 REST 端点
|
||||
```
|
||||
|
||||
### Phase 5: Tauri 后端 (Week 10-11)
|
||||
|
||||
**目标**: 更新 Rust 后端支持 ZCLAW
|
||||
|
||||
**关键文件**: [lib.rs](desktop/src-tauri/src/lib.rs)
|
||||
|
||||
**修改内容**:
|
||||
```rust
|
||||
// 新增 ZCLAW 命令
|
||||
#[tauri::command]
|
||||
async fn zclaw_status() -> Result<ZCLAWStatus, String> { ... }
|
||||
|
||||
#[tauri::command]
|
||||
async fn zclaw_start() -> Result<(), String> { ... }
|
||||
|
||||
#[tauri::command]
|
||||
async fn zclaw_stop() -> Result<(), String> { ... }
|
||||
|
||||
// 新增配置迁移命令
|
||||
#[tauri::command]
|
||||
async fn migrate_to_zclaw() -> Result<MigrationResult, String> { ... }
|
||||
```
|
||||
|
||||
### Phase 6: UI 增强 (Week 12-14)
|
||||
|
||||
**目标**: 添加 ZCLAW 特有的 UI 功能
|
||||
|
||||
**新增组件**:
|
||||
1. `HandsPanel.tsx` - Hands 管理界面
|
||||
2. `WorkflowEditor.tsx` - 工作流编辑器
|
||||
3. `TriggerManager.tsx` - 触发器管理
|
||||
4. `AuditLogs.tsx` - 审计日志查看
|
||||
|
||||
**修改组件**:
|
||||
1. `SettingsLayout.tsx` - 添加后端切换选项
|
||||
2. `General.tsx` - 添加 ZCLAW 配置项
|
||||
|
||||
### Phase 7: 测试验证 (Week 15-16)
|
||||
|
||||
**目标**: 全面测试和验证
|
||||
|
||||
**测试范围**:
|
||||
- 单元测试: 新客户端、适配层
|
||||
- 集成测试: 端到端消息流
|
||||
- 性能测试: 启动时间、内存占用
|
||||
- 迁移测试: 配置迁移正确性
|
||||
|
||||
---
|
||||
|
||||
## 五、风险评估与缓解
|
||||
|
||||
### 5.1 技术风险
|
||||
|
||||
| 风险 | 级别 | 缓解措施 |
|
||||
|------|------|----------|
|
||||
| 协议不兼容 | 高 | 创建适配层,保持双后端 |
|
||||
| 插件迁移复杂 | 高 | 分阶段迁移,保持 TypeScript 桥接 |
|
||||
| ZCLAW 不成熟 | 中 | 持续关注上游,建立社区联系 |
|
||||
| 配置格式差异 | 中 | 构建自动迁移工具 |
|
||||
|
||||
### 5.2 运营风险
|
||||
|
||||
| 风险 | 级别 | 缓解措施 |
|
||||
|------|------|----------|
|
||||
| 用户困惑 | 中 | 清晰文档,渐进发布 |
|
||||
| 数据丢失 | 高 | 自动备份,非破坏性迁移 |
|
||||
| 支持负担 | 中 | FAQ,故障排除指南 |
|
||||
|
||||
### 5.3 回滚策略
|
||||
|
||||
```typescript
|
||||
// 环境变量切换
|
||||
const USE_OPENFANG = process.env.ZCLAW_USE_OPENFANG === 'true';
|
||||
|
||||
// localStorage 切换
|
||||
const backendType = localStorage.getItem('zclaw-backend') || 'zclaw';
|
||||
|
||||
// 一键回滚
|
||||
function rollbackToZCLAW() {
|
||||
localStorage.setItem('zclaw-backend', 'zclaw');
|
||||
window.location.reload();
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 六、验证方案
|
||||
|
||||
### 6.1 功能验证清单
|
||||
|
||||
**核心功能**:
|
||||
- [ ] WebSocket 连接和认证
|
||||
- [ ] 消息发送和流式接收
|
||||
- [ ] Agent/Clone CRUD 操作
|
||||
- [ ] 频道管理 (飞书)
|
||||
- [ ] 技能加载和执行
|
||||
- [ ] 使用统计
|
||||
- [ ] 配置管理
|
||||
|
||||
**ZCLAW 新特性**:
|
||||
- [ ] Hand 触发 (Clip, Lead, Researcher 等)
|
||||
- [ ] Workflow 执行
|
||||
- [ ] 16 层安全验证
|
||||
- [ ] 审计日志访问
|
||||
|
||||
### 6.2 性能基准
|
||||
|
||||
| 指标 | ZCLAW 基线 | ZCLAW 目标 |
|
||||
|------|---------------|---------------|
|
||||
| 冷启动 | 5.98s | < 500ms |
|
||||
| 空闲内存 | 394MB | < 100MB |
|
||||
| 聊天延迟 | 100ms | < 50ms |
|
||||
| 安装大小 | 500MB | < 100MB |
|
||||
|
||||
---
|
||||
|
||||
## 七、关键文件清单
|
||||
|
||||
| 文件 | 修改类型 | 说明 |
|
||||
|------|----------|------|
|
||||
| [gateway-client.ts](desktop/src/lib/gateway-client.ts) | 重构 | 抽取接口,创建 ZCLAW 实现 |
|
||||
| [gatewayStore.ts](desktop/src/store/gatewayStore.ts) | 修改 | 添加后端切换逻辑 |
|
||||
| [chatStore.ts](desktop/src/store/chatStore.ts) | 修改 | 适配新事件格式 |
|
||||
| [lib.rs](desktop/src-tauri/src/lib.rs) | 扩展 | 添加 ZCLAW 管理命令 |
|
||||
| [zclaw-ui/index.ts](plugins/zclaw-ui/index.ts) | 迁移 | 转换为 REST API |
|
||||
| [zclaw-chinese-models/index.ts](plugins/zclaw-chinese-models/index.ts) | 迁移 | 转换为 TOML 配置 |
|
||||
| [zclaw-feishu/index.ts](plugins/zclaw-feishu/index.ts) | 迁移 | 使用 ZCLAW channel |
|
||||
|
||||
---
|
||||
|
||||
## 八、时间线总结
|
||||
|
||||
| 阶段 | 周期 | 开始 | 结束 | 关键交付物 |
|
||||
|------|------|------|------|------------|
|
||||
| Phase 1 | 2周 | Week 1 | Week 2 | ZCLAWClient 骨架 |
|
||||
| Phase 2 | 2周 | Week 3 | Week 4 | 完整客户端 + 流式处理 |
|
||||
| Phase 3 | 2周 | Week 5 | Week 6 | 更新后的 stores |
|
||||
| Phase 4 | 3周 | Week 7 | Week 9 | 迁移后的插件 |
|
||||
| Phase 5 | 2周 | Week 10 | Week 11 | Rust ZCLAW 支持 |
|
||||
| Phase 6 | 3周 | Week 12 | Week 14 | Hands/Workflow UI |
|
||||
| Phase 7 | 2周 | Week 15 | Week 16 | 测试套件,验证报告 |
|
||||
|
||||
**总工期**: 16 周 (约 4 个月)
|
||||
|
||||
---
|
||||
|
||||
## 九、结论与建议
|
||||
|
||||
### 9.1 核心价值
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ │
|
||||
│ 🚀 性能:33x 启动速度 + 90% 内存节省 │
|
||||
│ │
|
||||
│ 🔒 安全:16 层纵深防御 + 金融级合规 │
|
||||
│ │
|
||||
│ 🤖 智能:Hands 自主系统 + Workflow 引擎 │
|
||||
│ │
|
||||
│ 📈 商业:企业市场拓展 + 定价提升空间 │
|
||||
│ │
|
||||
│ ⚠️ 成本:16 周 (4个月) 迁移周期 │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 9.2 决策建议
|
||||
|
||||
| 目标 | 建议 |
|
||||
|------|------|
|
||||
| 追求企业市场 | ✅ **强烈建议迁移** |
|
||||
| 追求差异化竞争 | ✅ **建议迁移** |
|
||||
| 目标是内容创作者/销售 | ✅ **强烈建议迁移** |
|
||||
| 资源有限 | ⚠️ 渐进评估 |
|
||||
| 追求快速迭代 | ⚠️ 保持 ZCLAW,关注 ZCLAW |
|
||||
|
||||
### 9.3 下一步行动
|
||||
|
||||
1. **立即**: 确认迁移决策,分配资源
|
||||
2. **Week 1**: 创建 `GatewayBackend` 接口
|
||||
3. **Week 2**: 搭建 ZCLAW 开发环境
|
||||
4. **Week 3-4**: 实现 `ZCLAWClient`
|
||||
|
||||
---
|
||||
|
||||
*规划日期: 2026-03-13*
|
||||
*版本: v1.0*
|
||||
420
docs/archive/old-plans/new-session-prompt-roadmap.md
Normal file
@@ -0,0 +1,420 @@
|
||||
# ZCLAW 新会话提示词后续工作计划
|
||||
|
||||
## 一、目标
|
||||
|
||||
围绕 ZCLAW 的“新会话提示词”能力,完成一条从 **真实 Agent 配置** 到 **真实会话初始化行为** 的可交付链路。
|
||||
|
||||
这项能力的目标不是增加一个前端文本框,而是让用户可以:
|
||||
|
||||
- 为当前 Agent 设置默认的新会话提示词
|
||||
- 在开启某个新会话时临时覆盖这段提示词
|
||||
- 让提示词真实影响本次会话第一轮 Agent 行为
|
||||
- 让该能力在快速配置、右侧 Agent 面板、聊天区之间语义一致
|
||||
|
||||
---
|
||||
|
||||
## 二、当前已确认基础
|
||||
|
||||
以下基础能力已经打通,可作为本轮工作的前提:
|
||||
|
||||
- Gateway 连接稳定可用
|
||||
- token 注入、自动连接、Control UI 握手已修好
|
||||
- `zclaw-ui` 插件已加载
|
||||
- `zclaw.clones.list`、`zclaw.plugins.status` 可用
|
||||
- Agent 创建、右侧 Agent 面板编辑、保存回刷已验证通过
|
||||
- 快速配置应视为创建/更新 ZCLAW Agent
|
||||
- 右侧 Agent 面板已经是当前 Agent 配置的真实编辑入口
|
||||
|
||||
这意味着“新会话提示词”应该优先挂在 **Agent Profile 真实配置链路** 上,而不是再创建一套独立的本地状态。
|
||||
|
||||
---
|
||||
|
||||
## 三、问题定义
|
||||
|
||||
当前“新对话”链路还存在几个明显缺口:
|
||||
|
||||
### 3.1 会话初始化仍是本地 UI 行为
|
||||
|
||||
现状:
|
||||
|
||||
- `chatStore.newConversation()` 只清空本地消息与 `sessionKey`
|
||||
- 首次发送时才临时生成 `sessionKey`
|
||||
- 当前没有“会话初始化参数”的明确模型
|
||||
|
||||
影响:
|
||||
|
||||
- 新会话无法承载独立初始化上下文
|
||||
- 会话开场行为不可控、不可审计
|
||||
|
||||
### 3.2 Agent 配置与新会话行为未打通
|
||||
|
||||
现状:
|
||||
|
||||
- Agent 已有真实配置入口
|
||||
- 但聊天区不会消费“新会话默认提示词”这一能力
|
||||
|
||||
影响:
|
||||
|
||||
- Agent 身份和会话起始行为割裂
|
||||
- 用户改了 Agent,不一定影响新会话
|
||||
|
||||
### 3.3 当前没有原生会话初始化协议
|
||||
|
||||
现状:
|
||||
|
||||
- 当前 Gateway `agent` 请求只传 `message / sessionKey / model`
|
||||
- 尚未形成 `sessionInit`、`agentId`、`conversationContext` 等结构化初始化协议
|
||||
|
||||
影响:
|
||||
|
||||
- 若不做桥接,“新会话提示词”很难真实生效
|
||||
|
||||
---
|
||||
|
||||
## 四、设计原则
|
||||
|
||||
### 4.1 必须改变真实运行行为
|
||||
|
||||
验收标准不是“页面上能输入”,而是:
|
||||
|
||||
- 第一条发给 Gateway 的真实消息已经体现新会话提示词
|
||||
- 不同会话可以有不同初始化上下文
|
||||
- 会话恢复后能够看出本会话使用过什么提示词
|
||||
|
||||
### 4.2 必须依附真实 Agent 配置链路
|
||||
|
||||
能力入口必须统一在以下两处:
|
||||
|
||||
- 快速配置创建 Agent
|
||||
- 右侧 Agent 面板编辑当前 Agent
|
||||
|
||||
不新增与 Agent 平行、脱节的新设置体系。
|
||||
|
||||
### 4.3 先做最小真实闭环,再继续原生化
|
||||
|
||||
本轮优先实现:
|
||||
|
||||
- Agent 级默认 `newSessionPrompt`
|
||||
- 会话级 `sessionPromptDraft`
|
||||
- 首轮消息注入
|
||||
|
||||
后续再根据 Gateway / ZCLAW 演进升级为结构化原生协议。
|
||||
|
||||
---
|
||||
|
||||
## 五、目标能力定义
|
||||
|
||||
### 5.1 Agent 级默认提示词
|
||||
|
||||
语义:
|
||||
|
||||
- 某个 Agent 在每次开始新会话时默认携带的启动上下文
|
||||
- 属于 Agent Profile 的一部分
|
||||
- 可以由快速配置或右侧 Agent 面板编辑
|
||||
|
||||
建议字段:
|
||||
|
||||
- `newSessionPrompt?: string`
|
||||
|
||||
### 5.2 会话级临时覆盖
|
||||
|
||||
语义:
|
||||
|
||||
- 仅对本次新会话生效
|
||||
- 发出第一条用户消息前可编辑
|
||||
- 发出后固化到会话元数据中,不应在后续回合反复注入
|
||||
|
||||
建议字段:
|
||||
|
||||
- `sessionPromptDraft: string`
|
||||
- `conversation.sessionPrompt?: string | null`
|
||||
|
||||
### 5.3 首轮运行时注入
|
||||
|
||||
语义:
|
||||
|
||||
- 前端保留原始用户输入展示
|
||||
- 发送给 Gateway 的第一条消息在内部包装为“新会话提示词 + 原始用户问题”
|
||||
- 从而让提示词立即影响真实模型行为
|
||||
|
||||
---
|
||||
|
||||
## 六、实施阶段拆分
|
||||
|
||||
## Phase 1:数据模型与 RPC 链路补齐
|
||||
|
||||
### 目标
|
||||
|
||||
让“新会话提示词”成为真实 Agent 数据结构的一部分。
|
||||
|
||||
### 涉及位置
|
||||
|
||||
- `plugins/zclaw-ui/index.ts`
|
||||
- `desktop/src/store/gatewayStore.ts`
|
||||
- `desktop/src/store/chatStore.ts`
|
||||
- `desktop/src/components/CloneManager.tsx`
|
||||
- `desktop/src/components/RightPanel.tsx`
|
||||
|
||||
### 具体任务
|
||||
|
||||
- 插件层 `CloneConfig` 增加 `newSessionPrompt`
|
||||
- `zclaw.clones.create/update/list` 全链路透传该字段
|
||||
- 前端 `Clone`、快速配置草稿、右侧面板草稿模型补齐字段
|
||||
- 保证创建后、编辑后、刷新后都能回刷正确数据
|
||||
|
||||
### 交付物
|
||||
|
||||
- Agent Profile 可持久化 `newSessionPrompt`
|
||||
- UI 能读取并展示该字段
|
||||
|
||||
### 验收标准
|
||||
|
||||
- 创建 Agent 时可设置默认新会话提示词
|
||||
- 右侧 Agent 面板可编辑并保存该字段
|
||||
- 重新连接或刷新后字段仍存在
|
||||
|
||||
---
|
||||
|
||||
## Phase 2:聊天会话模型扩展
|
||||
|
||||
### 目标
|
||||
|
||||
为“新会话提示词”建立真正的会话级承载结构。
|
||||
|
||||
### 具体任务
|
||||
|
||||
- `chatStore` 增加 `sessionPromptDraft`
|
||||
- `Conversation` 增加 `sessionPrompt`、`agentId`
|
||||
- `newConversation()` 时重置当前会话的提示词草稿
|
||||
- 当切换 Agent 且当前尚未开始聊天时,提示词草稿应回填为当前 Agent 默认值
|
||||
- 切换到历史会话时,恢复该会话使用过的 `sessionPrompt`
|
||||
|
||||
### 交付物
|
||||
|
||||
- 会话层面拥有独立的提示词状态
|
||||
- 会话与 Agent 的关系更清晰
|
||||
|
||||
### 验收标准
|
||||
|
||||
- 新会话默认读取当前 Agent 的默认提示词
|
||||
- 修改草稿只影响当前新会话,不污染其他历史会话
|
||||
- 切回历史会话时能恢复对应提示词信息
|
||||
|
||||
---
|
||||
|
||||
## Phase 3:首轮消息注入,打通真实运行行为
|
||||
|
||||
### 目标
|
||||
|
||||
让“新会话提示词”真正影响 Gateway 收到的第一条消息。
|
||||
|
||||
### 具体任务
|
||||
|
||||
- 在 `chatStore.sendMessage()` 判断当前是否为该会话首轮用户消息
|
||||
- 若有有效 `sessionPromptDraft`,则构造包装后的发送内容
|
||||
- UI 中仍展示用户原始输入,不暴露包装结构
|
||||
- 首轮发出后,将实际使用过的提示词固化到当前 `Conversation`
|
||||
- 后续同一会话继续发送消息时不重复注入
|
||||
|
||||
### 建议包装格式
|
||||
|
||||
```text
|
||||
[ZCLAW_NEW_SESSION_PROMPT]
|
||||
<session prompt>
|
||||
[/ZCLAW_NEW_SESSION_PROMPT]
|
||||
|
||||
[USER_MESSAGE]
|
||||
<original user message>
|
||||
[/USER_MESSAGE]
|
||||
```
|
||||
|
||||
### 交付物
|
||||
|
||||
- 新会话提示词真正进入第一轮 Gateway 请求
|
||||
- 该能力不再是展示层占位
|
||||
|
||||
### 验收标准
|
||||
|
||||
- 第一轮消息有提示词时,模型行为明显受影响
|
||||
- 第二轮起不再重复注入
|
||||
- 无提示词时发送链路与当前一致
|
||||
|
||||
---
|
||||
|
||||
## Phase 4:交互与可见性优化
|
||||
|
||||
### 目标
|
||||
|
||||
让用户知道“当前会话将以什么上下文启动”,同时避免界面复杂度失控。
|
||||
|
||||
### 具体任务
|
||||
|
||||
- 在聊天区空态增加“新会话提示词”输入区
|
||||
- 提供简洁说明文案,明确这是“仅本次会话”的覆盖入口
|
||||
- 在右侧 Agent 面板非编辑态显示默认新会话提示词摘要
|
||||
- 在历史会话列表或会话详情中,保留轻量提示,帮助用户理解该会话的启动上下文
|
||||
|
||||
### 交付物
|
||||
|
||||
- 新会话前可见、可改、可理解
|
||||
- Agent 默认值与会话覆盖值关系明确
|
||||
|
||||
### 验收标准
|
||||
|
||||
- 用户能区分“Agent 默认值”和“当前会话覆盖值”
|
||||
- 用户不会误以为这是长期人格或全局系统提示词
|
||||
|
||||
---
|
||||
|
||||
## Phase 5:质量保障与回归验证
|
||||
|
||||
### 目标
|
||||
|
||||
确保能力上线后不会破坏现有已打通链路。
|
||||
|
||||
### 测试范围
|
||||
|
||||
- Agent 创建后默认提示词可保存
|
||||
- 右侧 Agent 面板编辑提示词可回刷
|
||||
- 新会话读取默认值
|
||||
- 新会话覆盖值只作用于当前会话
|
||||
- 首轮消息注入只发生一次
|
||||
- 切换历史会话后元数据恢复正确
|
||||
- 无提示词情况下原有发送链路不回归
|
||||
|
||||
### 建议验证方式
|
||||
|
||||
- Store 层单元测试
|
||||
- 关键组件交互测试
|
||||
- 手工联调验证 Gateway 请求行为
|
||||
|
||||
### 交付物
|
||||
|
||||
- 至少覆盖核心 store 行为的测试
|
||||
- 一份人工回归清单
|
||||
|
||||
### 验收标准
|
||||
|
||||
- 核心交互不回归
|
||||
- 会话状态与 Agent 状态一致性可验证
|
||||
|
||||
---
|
||||
|
||||
## 七、推荐执行顺序
|
||||
|
||||
建议按以下顺序推进,避免前后反复返工:
|
||||
|
||||
### 第一步
|
||||
|
||||
先做 **Phase 1**。
|
||||
|
||||
原因:
|
||||
|
||||
- 没有真实字段,就谈不上后续真实会话能力
|
||||
- 这一步风险最低,收益明确
|
||||
|
||||
### 第二步
|
||||
|
||||
做 **Phase 2**。
|
||||
|
||||
原因:
|
||||
|
||||
- 会话级草稿与历史恢复能力是首轮注入的前提
|
||||
|
||||
### 第三步
|
||||
|
||||
做 **Phase 3**。
|
||||
|
||||
原因:
|
||||
|
||||
- 这是从“有配置”到“真生效”的关键跃迁
|
||||
- 也是这轮工作的核心里程碑
|
||||
|
||||
### 第四步
|
||||
|
||||
补 **Phase 4 + Phase 5**。
|
||||
|
||||
原因:
|
||||
|
||||
- 在核心链路稳定后,再做可见性和质量封口最合适
|
||||
|
||||
---
|
||||
|
||||
## 八、本轮建议的最小可交付版本
|
||||
|
||||
如果本轮只做一个最小但高价值版本,建议交付以下内容:
|
||||
|
||||
- 插件与前端数据模型支持 `newSessionPrompt`
|
||||
- 快速配置与右侧 Agent 面板都可编辑该字段
|
||||
- 聊天区空态可查看/修改当前新会话提示词
|
||||
- 首轮消息自动注入该提示词
|
||||
- 会话中记录本次实际使用的提示词
|
||||
|
||||
这版已经满足:
|
||||
|
||||
- 有真实配置入口
|
||||
- 有真实运行时行为
|
||||
- 有会话级语义
|
||||
- 能被用户实际使用
|
||||
|
||||
---
|
||||
|
||||
## 九、主要风险与处理策略
|
||||
|
||||
### 风险 1:当前 selected Agent 还未完全映射到 ZCLAW runtime agent
|
||||
|
||||
影响:
|
||||
|
||||
- 即使 Agent Profile 已切换,底层仍可能没有原生 agent routing
|
||||
|
||||
处理:
|
||||
|
||||
- 本轮先用“首轮消息注入”保证真实行为变化
|
||||
- 后续把 `agentId` 传输与 runtime routing 作为独立里程碑推进
|
||||
|
||||
### 风险 2:提示词注入格式可能影响回答质量
|
||||
|
||||
影响:
|
||||
|
||||
- 包装格式不佳时,可能让模型输出不稳定
|
||||
|
||||
处理:
|
||||
|
||||
- 采用清晰、边界明确的包裹格式
|
||||
- 在真实模型上做几组样例测试
|
||||
|
||||
### 风险 3:会话切换与持久化逻辑容易变脆
|
||||
|
||||
影响:
|
||||
|
||||
- 草稿、历史会话、当前会话三者状态可能串扰
|
||||
|
||||
处理:
|
||||
|
||||
- 优先把 store 状态边界设计清楚
|
||||
- 先覆盖核心状态迁移测试,再做 UI 微调
|
||||
|
||||
---
|
||||
|
||||
## 十、完成定义
|
||||
|
||||
当以下条件同时满足时,可视为“新会话提示词”能力第一阶段完成:
|
||||
|
||||
- Agent 默认新会话提示词可创建、编辑、保存、回刷
|
||||
- 新会话开始前用户可临时覆盖该提示词
|
||||
- 首轮真实发送到 Gateway 的消息中包含该提示词上下文
|
||||
- 同一会话后续消息不重复注入
|
||||
- 历史会话可以恢复其实际使用过的提示词信息
|
||||
- 快速配置、右侧 Agent 面板、聊天区三处语义一致
|
||||
|
||||
---
|
||||
|
||||
## 十一、下一步建议
|
||||
|
||||
在本计划落地后,建议立即开始:
|
||||
|
||||
- **P1:先补数据模型与插件透传**
|
||||
- **P2:再补 chatStore 的会话级状态模型**
|
||||
- **P3:最后接入首轮消息注入并做联调验证**
|
||||
|
||||
这会以最小改动建立一条真正可用的闭环,也是当前最符合 ZCLAW 产品化推进方向的高杠杆路径。
|
||||
610
docs/archive/old-plans/quiet-twirling-kettle.md
Normal file
@@ -0,0 +1,610 @@
|
||||
# ZCLAW 前端全面调试计划
|
||||
|
||||
## 调试目标
|
||||
|
||||
从用户角度全面验证 ZCLAW 桌面应用前端的功能完整性、可用性,确保所有交互流程正常工作,数据流正确,UI 响应符合预期。
|
||||
|
||||
## 调试环境
|
||||
|
||||
### 前端服务
|
||||
- **URL**: http://localhost:1420
|
||||
- **框架**: React + Vite + Tauri
|
||||
- **代理**: `/api` -> `http://127.0.0.1:50051` (ZCLAW 后端)
|
||||
|
||||
### 启动步骤 (⚠️ 需要先启动服务)
|
||||
|
||||
**步骤 0: 启动服务** (在测试前必须完成)
|
||||
```bash
|
||||
# 终端 1: 启动后端服务
|
||||
cd g:\ZClaw_zclaw
|
||||
pnpm dev
|
||||
# 等待后端服务就绪 (看到 "Server started" 或类似消息)
|
||||
|
||||
# 终端 2: 启动前端开发服务器 (新开一个终端)
|
||||
cd g:\ZClaw_zclaw\desktop
|
||||
pnpm dev
|
||||
# 等待 Vite 服务就绪 (看到 "Local: http://localhost:1420")
|
||||
```
|
||||
|
||||
**服务就绪标志**:
|
||||
- 后端: 控制台显示服务启动成功,监听端口 50051 或 4200
|
||||
- 前端: Vite 显示 `Local: http://localhost:1420/`
|
||||
|
||||
## 调试范围
|
||||
|
||||
### 模块概览
|
||||
| 模块 | 文件位置 | 优先级 |
|
||||
|------|----------|------|
|
||||
| 聊天模块 | `desktop/src/components/chat/` | P0 |
|
||||
| Agent/克隆管理 | `desktop/src/components/agents/`, `desktop/src/store/agentStore.ts` | P0 |
|
||||
| Hands 系统 | `desktop/src/components/hands/`, `desktop/src/store/handStore.ts` | P1 |
|
||||
| 工作流调度 | `desktop/src/components/workflows/`, `desktop/src/store/` | P1 |
|
||||
| 团队协作 | `desktop/src/components/team/`, `desktop/src/store/teamStore.ts` | P1 |
|
||||
| 内存系统 | `desktop/src/components/memory/`, `desktop/src/store/memoryStore.ts` | P1 |
|
||||
| 设置管理 | `desktop/src/components/settings/` | P2 |
|
||||
| 布局/导航 | `desktop/src/components/layout/` | P2 |
|
||||
|
||||
| 状态管理 | `desktop/src/store/` | P2 |
|
||||
|
||||
---
|
||||
|
||||
## 详细测试用例
|
||||
|
||||
### 1. 聊天模块 (ChatArea.tsx) [P0]
|
||||
|
||||
#### 1.1 消息发送
|
||||
**步骤**:
|
||||
1. 打开应用,导航到聊天页面
|
||||
2. 在输入框中输入消息 "你好,请介绍一下你自己"
|
||||
3. 点击发送按钮
|
||||
4. 验证:
|
||||
- [ ] 消息显示在聊天区域
|
||||
- [ ] 发送后输入框被清空
|
||||
- [ ] 消息状态更新为"已发送"
|
||||
- [ ] 有响应返回(流式或完整)
|
||||
|
||||
**网络请求验证**:
|
||||
- 检查是否发送 `POST /api/chat` 请求
|
||||
- 验证请求体格式: `{ message, agent_id?, session_id? }`
|
||||
|
||||
#### 1.2 流式响应
|
||||
**步骤**:
|
||||
1. 发送一条消息
|
||||
2. 观察/验证流式响应:
|
||||
- [ ] 逐字/逐块显示文本
|
||||
- [ ] 有打字机效果
|
||||
- [ ] 滚动区域自动滚动到底部
|
||||
- [ ] 流式完成有正确标识
|
||||
|
||||
**WebSocket 验证**:
|
||||
- 检查是否建立 WebSocket 连接
|
||||
- 验证消息格式符合预期
|
||||
|
||||
- 检查是否有心跳/ping 机制
|
||||
|
||||
#### 1.3 Agent 切换
|
||||
**步骤**:
|
||||
1. 点击 Agent 选择下拉菜单
|
||||
2. 选择不同的 Agent
|
||||
3. 验证:
|
||||
- [ ] 下拉菜单正确显示
|
||||
- [ ] Agent 切换成功
|
||||
- [ ] 后续消息使用新 Agent
|
||||
- [ ] 状态正确更新
|
||||
**API 验证**:
|
||||
- 检查是否调用 `/api/agents` 获取列表
|
||||
- 验证切换时是否更新上下文
|
||||
|
||||
#### 1.4 模型选择
|
||||
**步骤**:
|
||||
1. 打开模型选择器
|
||||
2. 选择不同的模型 (如 GPT-4, Claude)
|
||||
3. 验证:
|
||||
- [ ] 选择器更新
|
||||
- [ ] 后续请求使用新模型
|
||||
- [ ] 设置持久化
|
||||
**API 验证**:
|
||||
- 检查是否调用 `/api/config` 或类似端点
|
||||
- 验证配置是否保存到后端
|
||||
|
||||
#### 1.5 会话管理
|
||||
**步骤**:
|
||||
1. 发送多条消息
|
||||
2. 刷新页面
|
||||
3. 验证:
|
||||
- [ ] 会话历史是否恢复
|
||||
- [ ] 可以继续对话
|
||||
- [ ] "新对话" 按钮可以开始新会话
|
||||
**持久化验证**:
|
||||
- 检查 localStorage 是否保存会话信息
|
||||
- 验证刷新后的恢复逻辑
|
||||
|
||||
#### 1.6 错误处理
|
||||
**步骤**:
|
||||
1. 断开后端连接
|
||||
2. 尝试发送消息
|
||||
3. 验证:
|
||||
- [ ] 显示错误消息
|
||||
- [ ] 有重试机制
|
||||
- [ ] 重连后恢复正常
|
||||
**错误边界**:
|
||||
- 验证网络超时处理
|
||||
- 验证服务器错误响应
|
||||
- 验证无效输入处理
|
||||
|
||||
#### 1.7 Markdown/代码渲染
|
||||
**步骤**:
|
||||
1. 发送包含 Markdown 格式的消息
|
||||
- 代码块: \`\`\`code\`\`\`
|
||||
- 粗体: **bold**
|
||||
- 列表: - item
|
||||
2. 验证:
|
||||
- [ ] Markdown 正确渲染
|
||||
- [ ] 代码语法高亮
|
||||
- [ ] 列表格式正确
|
||||
**渲染库**:
|
||||
- 检查使用的渲染库 (react-markdown 或类似)
|
||||
- 验证 XSS 防护
|
||||
|
||||
---
|
||||
|
||||
### 2. Agent/克隆管理 (AgentMemoryPanel.tsx, CloneManager.tsx)
|
||||
|
||||
#### 2.1 Agent 列表
|
||||
**步骤**:
|
||||
1. 导航到 Agent 管理页面
|
||||
2. 验证:
|
||||
- [ ] 显示 Agent 列表
|
||||
- [ ] 每个 Agent 显示名称、描述、状态
|
||||
- [ ] 可以搜索/过滤 Agent
|
||||
**API 验证**:
|
||||
- 检查是否调用 `/api/agents` 获取列表
|
||||
- 验证响应数据结构
|
||||
|
||||
#### 2.2 创建 Agent
|
||||
**步骤**:
|
||||
1. 点击"创建 Agent" 按钮
|
||||
2. 填写表单 (名称、描述、模型等)
|
||||
3. 提交表单
|
||||
4. 验证:
|
||||
- [ ] 表单验证正确
|
||||
- [ ] 创建成功
|
||||
- [ ] 新 Agent 出现在列表中
|
||||
**API 验证**:
|
||||
- 检查是否发送 `POST /api/agents` 请求
|
||||
- 验证请求体格式
|
||||
|
||||
#### 2.3 编辑 Agent
|
||||
**步骤**:
|
||||
1. 选择一个 Agent
|
||||
2. 点击编辑按钮
|
||||
3. 修改信息
|
||||
4. 保存
|
||||
5. 验证:
|
||||
- [ ] 编辑表单正确预填充
|
||||
- [ ] 保存成功
|
||||
- [ ] 更新反映在列表中
|
||||
**API 验证**:
|
||||
- 检查是否发送 `PUT /api/agents/{id}` 请求
|
||||
|
||||
#### 2.4 删除 Agent
|
||||
**步骤**:
|
||||
1. 选择一个 Agent
|
||||
2. 点击删除按钮
|
||||
3. 确认删除
|
||||
4. 验证:
|
||||
- [ ] 显示确认对话框
|
||||
- [ ] 删除成功
|
||||
- [ ] Agent 从列表中移除
|
||||
**API 验证**:
|
||||
- 检查是否发送 `DELETE /api/agents/{id}` 请求
|
||||
|
||||
#### 2.5 Agent 快速设置
|
||||
**步骤**:
|
||||
1. 打开 Agent 快速设置面板
|
||||
2. 调整各种设置
|
||||
3. 验证:
|
||||
- [ ] 设置项正确显示
|
||||
- [ ] 修改立即生效
|
||||
- [ ] 设置持久化
|
||||
**持久化验证**:
|
||||
- 检查设置是否保存到 localStorage
|
||||
- 验证重启后设置保持
|
||||
|
||||
---
|
||||
|
||||
### 3. Hands 系统 (HandsPanel.tsx)
|
||||
#### 3.1 Hands 列表
|
||||
**步骤**:
|
||||
1. 导航到 Hands 面板
|
||||
2. 验证:
|
||||
- [ ] 显示 7 个 Hand 卡片
|
||||
- [ ] 每个 Hand 显示名称、描述、状态
|
||||
- [ ] 可以查看 Hand 详情
|
||||
**Hands 列表验证**:
|
||||
- Clip: 视频处理
|
||||
- Lead: 销售线索发现
|
||||
- Collector: 数据收集
|
||||
- Predictor: 预测分析
|
||||
- Researcher: 深度研究
|
||||
- Twitter: Twitter 自动化
|
||||
- Browser: 浏览器自动化
|
||||
|
||||
#### 3.2 触发 Hand
|
||||
**步骤**:
|
||||
1. 选择一个 Hand
|
||||
2. 点击"触发" 或 "执行" 按钮
|
||||
3. 验证:
|
||||
- [ ] 显示执行参数表单 (如有)
|
||||
- [ ] 执行开始
|
||||
- [ ] 显示执行状态
|
||||
- [ ] 完成后显示结果
|
||||
**API 验证**:
|
||||
- 检查是否调用 `/api/hands/{name}/trigger` 请求
|
||||
- 验证执行结果
|
||||
|
||||
#### 3.3 Hand 审批流程
|
||||
**步骤**:
|
||||
1. 触发需要审批的 Hand
|
||||
2. 验证:
|
||||
- [ ] 显示审批请求
|
||||
- [ ] 可以批准/拒绝
|
||||
- [ ] 审批状态正确更新
|
||||
**API 验证**:
|
||||
- 检查是否调用 `/api/hands/approvals` 获取列表
|
||||
- 验证审批操作
|
||||
|
||||
#### 3.4 Hand 执行历史
|
||||
**步骤**:
|
||||
1. 查看 Hand 执行历史
|
||||
2. 验证:
|
||||
- [ ] 显示历史记录列表
|
||||
- [ ] 包含时间、状态、结果
|
||||
- [ ] 可以筛选/过滤
|
||||
**API 验证**:
|
||||
- 检查是否调用 `/api/hands/{name}/runs` 获取历史
|
||||
|
||||
---
|
||||
|
||||
### 4. 工作流调度 (WorkflowEditor.tsx)
|
||||
#### 4.1 工作流列表
|
||||
**步骤**:
|
||||
1. 导航到工作流页面
|
||||
2. 验证:
|
||||
- [ ] 显示工作流列表
|
||||
- [ ] 每个工作流显示名称、状态、进度
|
||||
- [ ] 可以搜索/过滤
|
||||
**API 验证**:
|
||||
- 检查是否调用 `/api/workflows` 获取列表
|
||||
|
||||
#### 4.2 创建工作流
|
||||
**步骤**:
|
||||
1. 点击"创建工作流" 按钮
|
||||
2. 添加步骤/任务
|
||||
3. 配置触发器
|
||||
4. 保存
|
||||
5. 验证:
|
||||
- [ ] 步骤可以拖拽排序
|
||||
- [ ] 可以添加条件分支
|
||||
- [ ] 触发器配置正确
|
||||
- [ ] 保存成功
|
||||
**API 验证**:
|
||||
- 检查是否发送 `POST /api/workflows` 请求
|
||||
- 验证工作流定义格式
|
||||
|
||||
#### 4.3 执行工作流
|
||||
**步骤**:
|
||||
1. 选择一个工作流
|
||||
2. 点击"执行" 按钮
|
||||
3. 验证:
|
||||
- [ ] 显示执行进度
|
||||
- [ ] 步骤状态正确更新
|
||||
- [ ] 完成后显示结果
|
||||
**WebSocket 验证**:
|
||||
- 检查是否收到工作流执行事件
|
||||
- 验证进度更新
|
||||
|
||||
#### 4.4 暂停/取消工作流
|
||||
**步骤**:
|
||||
1. 执行一个工作流
|
||||
2. 中途点击"暂停" 或 "取消"
|
||||
3. 验证:
|
||||
- [ ] 操作成功
|
||||
- [ ] 状态正确更新
|
||||
- [ ] 可以恢复执行
|
||||
**API 验证**:
|
||||
- 检查是否调用 `/api/workflows/{id}/pause` 或 `/api/workflows/{id}/cancel` 请求
|
||||
|
||||
---
|
||||
|
||||
### 5. 团队协作 (TeamCollaborationView.tsx)
|
||||
#### 5.1 团队列表
|
||||
**步骤**:
|
||||
1. 导航到团队页面
|
||||
2. 验证:
|
||||
- [ ] 显示团队列表
|
||||
- [ ] 每个团队显示成员数量、状态
|
||||
- [ ] 可以搜索团队
|
||||
**API 验证**:
|
||||
- 检查是否调用 `/api/teams` 获取列表
|
||||
|
||||
#### 5.2 创建团队
|
||||
**步骤**:
|
||||
1. 点击"创建团队" 按钮
|
||||
2. 添加成员
|
||||
3. 配置权限
|
||||
4. 保存
|
||||
5. 验证:
|
||||
- [ ] 可以添加多个 Agent
|
||||
- [ ] 权限配置正确
|
||||
- [ ] 保存成功
|
||||
**API 验证**:
|
||||
- 棹查是否发送 `POST /api/teams` 请求
|
||||
|
||||
#### 5.3 协调 Agent
|
||||
**步骤**:
|
||||
1. 选择一个团队
|
||||
2. 点击"协调" 按钮
|
||||
3. 分配任务
|
||||
4. 验证:
|
||||
- [ ] 显示任务分配界面
|
||||
- [ ] 可以选择 Agent
|
||||
- [ ] 分配成功
|
||||
**API 验证**:
|
||||
- 检查是否调用协调相关 API
|
||||
|
||||
#### 5.4 查看协作状态
|
||||
**步骤**:
|
||||
1. 查看团队协作状态
|
||||
2. 验证:
|
||||
- [ ] 显示各 Agent 状态
|
||||
- [ ] 显示任务进度
|
||||
- [ ] 可以发送消息
|
||||
**WebSocket 验证**:
|
||||
- 检查协作事件是否正确推送
|
||||
|
||||
---
|
||||
|
||||
### 6. 内存系统 (MemoryPanel.tsx, M/MemoryPanel.tsx)
|
||||
#### 6.1 内存列表
|
||||
**步骤**:
|
||||
1. 导航到内存页面
|
||||
2. 验证:
|
||||
- [ ] 显示记忆列表
|
||||
- [ ] 每条记忆显示类型、时间、重要性
|
||||
- [ ] 可以搜索记忆
|
||||
**API 验证**:
|
||||
- 检查是否调用 `/api/memory` 获取列表
|
||||
|
||||
#### 6.2 添加记忆
|
||||
**步骤**:
|
||||
1. 点击"添加记忆" 按钮
|
||||
2. 输入记忆内容
|
||||
3. 设置标签/分类
|
||||
4. 保存
|
||||
5. 验证:
|
||||
- [ ] 表单正确提交
|
||||
- [ ] 保存成功
|
||||
- [ ] 新记忆出现在列表中
|
||||
**API 验证**:
|
||||
- 检查是否发送 `POST /api/memory` 请求
|
||||
|
||||
#### 6.3 搜索记忆
|
||||
**步骤**:
|
||||
1. 在搜索框中输入关键词
|
||||
2. 验证:
|
||||
- [ ] 搜索结果正确显示
|
||||
- [ ] 可以按相关性排序
|
||||
- [ ] 高亮匹配关键词
|
||||
**API 验证**:
|
||||
- 检查是否调用 `/api/memory/search` 请求
|
||||
|
||||
#### 6.4 记忆分类
|
||||
**步骤**:
|
||||
1. 查看记忆分类/标签
|
||||
2. 验证:
|
||||
- [ ] 分类正确显示
|
||||
- [ ] 可以按分类筛选
|
||||
- [ ] 记忆数量统计正确
|
||||
**持久化验证**:
|
||||
- 检查分类数据结构
|
||||
|
||||
---
|
||||
|
||||
### 7. 设置管理 (GeneralSettings.tsx, ModelSettings.tsx)
|
||||
#### 7.1 通用设置
|
||||
**步骤**:
|
||||
1. 打开设置页面
|
||||
2. 验证:
|
||||
- [ ] 显示所有设置项
|
||||
- [ ] 当前值正确显示
|
||||
- [ ] 可以编辑并保存
|
||||
- [ ] 设置分组清晰
|
||||
**API 验证**:
|
||||
- 检查是否调用 `/api/config` 获取当前配置
|
||||
- 验证保存时发送 `PUT /api/config` 请求
|
||||
|
||||
#### 7.2 模型设置
|
||||
**步骤**:
|
||||
1. 导航到模型设置
|
||||
2. 验证:
|
||||
- [ ] 显示可用模型列表
|
||||
- [ ] 可以选择默认模型
|
||||
- [ ] 可以配置模型参数
|
||||
- [ ] API Key 配置
|
||||
**API 验证**:
|
||||
- 检查是否调用 `/api/models` 获取列表
|
||||
- 验证 API Key 保存安全
|
||||
|
||||
#### 7.3 主题设置
|
||||
**步骤**:
|
||||
1. 切换主题 (亮色/暗色)
|
||||
2. 验证:
|
||||
- [ ] 主题正确切换
|
||||
- [ ] 颜色/样式正确应用
|
||||
- [ ] 设置持久化
|
||||
**持久化验证**:
|
||||
- 检查 localStorage 是否保存主题设置
|
||||
|
||||
#### 7.4 语言设置
|
||||
**步骤**:
|
||||
1. 切换语言 (中文/英文)
|
||||
2. 验证:
|
||||
- [ ] 界面语言正确切换
|
||||
- [ ] 日期/数字格式正确显示
|
||||
- [ ] 设置持久化
|
||||
**国际化验证**:
|
||||
- 检查 i18n 是否正确工作
|
||||
|
||||
---
|
||||
|
||||
### 8. 布局/导航 (Header.tsx, Sidebar.tsx)
|
||||
#### 8.1 主导航
|
||||
**步骤**:
|
||||
1. 检查顶部导航栏
|
||||
2. 验证:
|
||||
- [ ] 显示应用名称/Logo
|
||||
- [ ] 导航菜单正确
|
||||
- [ ] 当前页面高亮
|
||||
- [ ] 可以点击切换页面
|
||||
**路由验证**:
|
||||
- 检查路由配置是否正确
|
||||
|
||||
#### 8.2 侧边栏
|
||||
**步骤**:
|
||||
1. 点击侧边栏切换按钮
|
||||
2. 验证:
|
||||
- [ ] 侧边栏正确展开/收起
|
||||
- [ ] 菜单项正确显示
|
||||
- [ ] 可以点击导航
|
||||
- [ ] 动画流畅
|
||||
**响应式验证**:
|
||||
- 检查在不同屏幕尺寸下的表现
|
||||
- 验证移动端适配
|
||||
|
||||
#### 8.3 响应式布局
|
||||
**步骤**:
|
||||
1. 调整浏览器窗口大小
|
||||
2. 验证:
|
||||
- [ ] 布局正确适应
|
||||
- [ ] 没有元素溢出
|
||||
- [ ] 文字可读性良好
|
||||
- [ ] 侧边栏自动收起 (移动端)
|
||||
**CSS 验证**:
|
||||
- 检查媒体查询是否正确设置
|
||||
|
||||
---
|
||||
|
||||
### 9. 状态管理 (stores)
|
||||
#### 9.1 Zustand Stores
|
||||
**验证项目**:
|
||||
1. 检查各个 store 的状态
|
||||
2. 验证:
|
||||
- [ ] 初始状态正确
|
||||
- [ ] actions 可以正确触发
|
||||
- [ ] 状态更新正确
|
||||
- [ ] 选择器返回正确数据
|
||||
|
||||
#### 9.2 持久化
|
||||
**步骤**:
|
||||
1. 修改状态
|
||||
2. 刷新页面
|
||||
3. 验证:
|
||||
- [ ] 状态正确恢复
|
||||
- [ ] 没有数据丢失
|
||||
**存储验证**:
|
||||
- 检查 localStorage/sessionStorage 数据
|
||||
- 验证序列化/反序列化正确
|
||||
|
||||
---
|
||||
|
||||
### 10. 错误处理
|
||||
#### 10.1 全局错误处理
|
||||
**步骤**:
|
||||
1. 触发各种错误场景
|
||||
2. 验证:
|
||||
- [ ] 错误消息清晰
|
||||
- [ ] 有恢复机制
|
||||
- [ ] 可以重试操作
|
||||
- [ ] 错误日志正确记录
|
||||
|
||||
#### 10.2 网络错误
|
||||
**步骤**:
|
||||
1. 断开网络
|
||||
2. 尝试操作
|
||||
3. 验证:
|
||||
- [ ] 显示网络错误
|
||||
- [ ] 自动重连
|
||||
- [ ] 恢复后正常工作
|
||||
|
||||
#### 10.3 表单验证
|
||||
**步骤**:
|
||||
1. 输入无效数据
|
||||
2. 验证:
|
||||
- [ ] 显示验证错误
|
||||
- [ ] 不能提交无效表单
|
||||
- [ ] 错误提示清晰
|
||||
|
||||
---
|
||||
|
||||
### 11. 性能测试
|
||||
#### 11.1 消息列表虚拟滚动
|
||||
**步骤**:
|
||||
1. 发送大量消息
|
||||
2. 滚动消息列表
|
||||
3. 验证:
|
||||
- [ ] 滚动流畅
|
||||
- [ ] 没有卡顿
|
||||
- [ ] 内存稳定
|
||||
**虚拟列表验证**:
|
||||
- 检查是否使用 react-window 或类似库
|
||||
- 验证虚拟化实现
|
||||
|
||||
#### 11.2 大数据集渲染
|
||||
**步骤**:
|
||||
1. 加载大量 Agent/工作流
|
||||
2. 验证:
|
||||
- [ ] 渲染流畅
|
||||
- [ ] 分页/虚拟滚动正常
|
||||
- [ ] 搜索/过滤响应快
|
||||
|
||||
---
|
||||
|
||||
### 12. 无障碍测试
|
||||
#### 12.1 键盘导航
|
||||
**步骤**:
|
||||
1. 使用 Tab 键导航
|
||||
2. 验证:
|
||||
- [ ] Tab 顺序正确
|
||||
- [ ] 焦点可见
|
||||
- [ ] 可以用 Enter 激活
|
||||
|
||||
#### 12.2 屏幕阅读器
|
||||
**步骤**:
|
||||
1. 使用屏幕阅读器
|
||||
2. 验证:
|
||||
- [ ] 元素有正确的 aria 标签
|
||||
- [ ] 图片有 alt 文本
|
||||
- [ ] 表单有 label
|
||||
|
||||
---
|
||||
|
||||
## 测试工具配置
|
||||
- **Chrome DevTools MCP**: 用于页面交互、快照、网络监控
|
||||
- **控制台日志**: 监控错误和警告
|
||||
- **网络面板**: 验证 API 请求/响应
|
||||
- **性能面板**: 监控渲染性能
|
||||
|
||||
## 訡拟用户场景
|
||||
1. **新用户首次使用**: 从空白状态开始,无历史数据
|
||||
2. **日常使用**: 有历史会话和配置
|
||||
3. **多任务场景**: 同时操作多个功能
|
||||
4. **错误恢复**: 处理各种错误情况
|
||||
5. **性能压力**: 大数据量操作
|
||||
|
||||
## 预期产出
|
||||
1. **功能验证报告**: 每个功能的测试结果
|
||||
2. **问题清单**: 发现的 bug 和改进建议
|
||||
3. **性能报告**: 渲染和网络性能数据
|
||||
4. **无障碍报告**: 无障碍测试结果
|
||||
5. **建议**: 优化和改进建议
|
||||
@@ -0,0 +1,231 @@
|
||||
|
||||
# ZClaw 改进方案:从"前端 UI 演示"升级为"真正的 ZCLAW Runtime 控制界面"
|
||||
|
||||
**日期**: 2026-03-12
|
||||
**状态**: 规划中
|
||||
|
||||
---
|
||||
|
||||
## 背景分析
|
||||
|
||||
### 当前状态
|
||||
|
||||
经过对代码库的深入分析,发现以下关键差距:
|
||||
|
||||
#### 1. 分身与 Agent 断层
|
||||
- **现状**: 分身存储在 `zclaw-data.json` (ZCLAW 自定义格式)
|
||||
- **问题**: 不映射到 ZCLAW 原生 `agents.list` 配置
|
||||
- **影响**: 聊天时不所有分身共用 `main` Agent
|
||||
- **表现**: Bootstrap 文件生成了但可能未被 Agent 运行时使用
|
||||
|
||||
**关键代码位置**:
|
||||
- `desktop/src/components/CloneManager.tsx`: 分身 CRUD 界面
|
||||
- `desktop/src/store/chatStore.ts`: `currentAgent` 只存前端状态
|
||||
- `plugins/zclaw-ui/index.ts`: 分身存储在 `zclaw-data.json`
|
||||
|
||||
#### 2. 设置页是"假状态"
|
||||
- **现状**: 大部分设置只存 localStorage
|
||||
- **问题**: 没有调用 ZCLAW 的 `config.get/config.patch/config.apply`
|
||||
- **影响**: 用户改了设置而 ZCLAW 运行时行为不变
|
||||
|
||||
**关键代码位置**:
|
||||
- `desktop/src/components/Settings/*.tsx`: 所有设置页面
|
||||
- `desktop/src/store/chatStore.ts`: `currentModel` 只存前端状态
|
||||
- `desktop/src/lib/gateway-client.ts`: 缺少 `config.*` RPC 方法
|
||||
|
||||
#### 3. 右侧面板数据不真实
|
||||
- **现状**: 部分数据是硬编码默认值
|
||||
- **问题**: 没有显示真实 Agent 的运行时状态
|
||||
- **影响**: 用户看到的是演示数据,- **表现**: Bootstrap 文件生成了但可能未被 Agent 运行时使用
|
||||
|
||||
---
|
||||
|
||||
## P0: 最小可行改进 - 让分身真正工作
|
||||
|
||||
### 目标
|
||||
让分身系统真正映射到 ZCLAW Agent 实例,实现分身隔离(独立 Agent 会话)。
|
||||
|
||||
### 关键任务
|
||||
|
||||
#### 1. 实现 Agent 同步机制
|
||||
- 在 `plugins/zclaw-ui/index.ts` 中:
|
||||
- 添加 `zclaw.agents.sync` RPC 方法
|
||||
- 同步 `zclaw-data.json` 的分身到 `agents.list`
|
||||
- 为每个分身创建独立 `agentDir`
|
||||
- 在 `desktop/src/lib/gateway-client.ts` 中:
|
||||
- 添加 `agents.list` RPC 方法封装
|
||||
- 添加 `agent.set` RPC 方法封装
|
||||
|
||||
#### 2. 修改聊天逻辑
|
||||
- 在 `desktop/src/store/chatStore.ts` 中:
|
||||
- 添加 `currentAgentId` 字段
|
||||
- 修改 `sendMessage` 传递 `agentId`
|
||||
- 在 `desktop/src/components/ChatArea.tsx` 中:
|
||||
- 聊天时显示当前分身信息
|
||||
|
||||
#### 3. Agent 启动流程
|
||||
- 创建分身时:
|
||||
1. 生成 Bootstrap 文件
|
||||
2. 同步到 `agents.list`
|
||||
3. 重启 Agent 进程(如果需要)
|
||||
|
||||
- 切换分身时:
|
||||
1. 加载对应 Agent 的上下文
|
||||
2. 切换 `agentId`
|
||||
|
||||
### 技术挑战
|
||||
- **ZCLAW Agent 进程管理**: 隐式依赖 Gateway 的 Agent 启动机制
|
||||
- **会话隔离**: 需要验证 ZCLAW 是否支持 `agentId` 参数
|
||||
- **配置同步时机**: 何时同步分身配置到 ZCLAW
|
||||
|
||||
- **错误处理**: Agent 启动失败时的回退策略
|
||||
|
||||
### 验收标准
|
||||
- [ ] 创建分身后能在 ZCLAW 的 `agents.list` 中看到
|
||||
- [ ] 切换分身后聊天时传递正确的 `agentId`
|
||||
- [ ] 不同分身的会话完全隔离
|
||||
- [ ] Bootstrap 文件被 Agent 正确加载
|
||||
- [ ] 分身配置修改后 Agent 行为相应变化
|
||||
|
||||
---
|
||||
|
||||
## P1: 设置页 Runtime 化
|
||||
|
||||
### 目标
|
||||
让设置页真正修改 ZCLAW Runtime 配置。
|
||||
|
||||
### 关键任务
|
||||
|
||||
#### 1. GatewayClient 扩展
|
||||
在 `desktop/src/lib/gateway-client.ts` 中添加:
|
||||
```typescript
|
||||
async getConfig(path?: string): Promise<any>
|
||||
async patchConfig(path: string, value: any): Promise<void>
|
||||
async applyConfig(): Promise<void>
|
||||
```
|
||||
|
||||
#### 2. 设置页改造
|
||||
|
||||
**模型与 API**:
|
||||
- 模型选择调用 `patchConfig('agents.defaults.model', model)`
|
||||
- 显示当前模型从 `getConfig('agents.defaults.model')` 获取
|
||||
|
||||
**MCP 服务**:
|
||||
- 读取: `getConfig('mcp')`
|
||||
- 修改: `patchConfig('mcp.servers.*')`
|
||||
|
||||
**技能**:
|
||||
- 读取: `getConfig('skills')`
|
||||
- 修改: `patchConfig('skills.load.extraDirs')`
|
||||
|
||||
**IM 频道**:
|
||||
- 读取: `getConfig('channels')`
|
||||
- 修改: `patchConfig('channels.*')`
|
||||
|
||||
**工作区**:
|
||||
- 读取: `getConfig('agents.defaults.workspace')`
|
||||
- 修改: `patchConfig('agents.defaults.workspace')`
|
||||
|
||||
### 技术挑战
|
||||
- **配置路径**: ZCLAW 配置是嵌套结构,需要正确处理路径
|
||||
- **配置验证**: 修改前验证配置有效性
|
||||
- **错误恢复**: 配置修改失败时的回滚
|
||||
- **UI 反馈**: 配置修改时的加载状态
|
||||
|
||||
- **配置缓存**: 避免频繁读取配置
|
||||
|
||||
### 验收标准
|
||||
- [ ] 模型选择后聊天时使用新模型
|
||||
- [ ] MCP 开关后工具可用性变化
|
||||
- [ ] 技能添加后 Agent 可调用
|
||||
- [ ] IM 频道配置后能收发消息
|
||||
- [ ] 工作区修改后文件访问范围变化
|
||||
|
||||
- [ ] 配置修改后重启 Gateway 生效
|
||||
|
||||
---
|
||||
## P2: 完整的 Agent 管理系统
|
||||
### 目标
|
||||
实现完整的 Agent 生命周期管理。
|
||||
|
||||
### 关键任务
|
||||
|
||||
#### 1. Agent 状态管理
|
||||
在 `desktop/src/store/chatStore.ts` 中添加
|
||||
```typescript
|
||||
interface AgentState {
|
||||
id: string;
|
||||
status: 'idle' | 'running' | 'error';
|
||||
lastActive: Date;
|
||||
sessionCount: number;
|
||||
currentModel: string;
|
||||
}
|
||||
```
|
||||
|
||||
#### 2. Agent 监控
|
||||
在 `plugins/zclaw-ui/index.ts` 中添加
|
||||
```typescript
|
||||
api.registerGatewayMethod('zclaw.agents.status', ({ respond }) => {
|
||||
// 返回所有 Agent 的运行时状态
|
||||
});
|
||||
```
|
||||
|
||||
#### 3. 右侧面板增强
|
||||
在 `desktop/src/components/RightPanel.tsx` 中
|
||||
- 显示真实 Agent 状态
|
||||
- 显示运行时信息(当前任务、 使用的工具等)
|
||||
- 显示会话历史
|
||||
|
||||
### 技术挑战
|
||||
- **状态同步**: 客户端状态与 Gateway 状态同步
|
||||
- **性能**: 大量 Agent 时的性能
|
||||
- **错误处理**: Agent 状态异常时的 UI 反馈
|
||||
- **实时更新**: 状态变化时的实时推送
|
||||
|
||||
### 验收标准
|
||||
- [ ] Agent 状态实时显示
|
||||
- [ ] 运行时信息准确
|
||||
- [ ] 会话历史可查
|
||||
- [ ] 错误状态有明确提示
|
||||
- [ ] 性能满足要求(100 个 Agent)
|
||||
|
||||
---
|
||||
## P3: 产品化封装
|
||||
### 目标
|
||||
提供完整的桌面应用体验。
|
||||
|
||||
### 关键任务
|
||||
|
||||
#### 1. Tauri Sidecar 管理
|
||||
在 `desktop/src-tauri/src/gateway.rs` 中:
|
||||
- 管理 Gateway 子进程生命周期
|
||||
- 自动重启和错误恢复
|
||||
- 配置管理和持久化
|
||||
|
||||
#### 2. 首次启动体验
|
||||
- 欢迎向导
|
||||
- Gateway 连接配置
|
||||
- 默认 Agent 创建
|
||||
- 工作目录选择
|
||||
|
||||
#### 3. 错误诊断
|
||||
- 连接问题诊断
|
||||
- 配置错误修复建议
|
||||
- 日志查看工具
|
||||
|
||||
### 技术挑战
|
||||
- **进程管理**: 跨平台进程管理
|
||||
- **权限**: 文件系统访问权限
|
||||
- **更新**: 应用更新时的状态保持
|
||||
- **用户体验**: 错误时的用户引导
|
||||
|
||||
- **文档**: 用户文档和帮助
|
||||
|
||||
### 验收标准
|
||||
- [ ] Gateway 自动启动
|
||||
- [ ] 首次启动流程完整
|
||||
- [ ] 错误有明确指引
|
||||
- [ ] 配置持久化
|
||||
- [ ] 应用更新无状态丢失
|
||||
|
||||
- [ ] 用户文档完整
|
||||
343
docs/archive/old-plans/sequential-churning-wreath.md
Normal file
@@ -0,0 +1,343 @@
|
||||
# ZClaw 项目深度分析与改进计划
|
||||
|
||||
## 一、现状分析
|
||||
|
||||
### 1.1 核心发现
|
||||
|
||||
基于 `docs/zclaw-deep-dive.md` 的目标与实际代码的对比:
|
||||
|
||||
| 模块 | 目标状态 | 实际状态 | 差距程度 |
|
||||
|------|----------|----------|----------|
|
||||
| **Gateway 连接** | 设备认证 + Challenge 签名 | ✅ 完整实现 | 无差距 |
|
||||
| **分身系统** | 映射到 ZCLAW `agents.list` | ⚠️ 独立存储在 `zclaw-data.json` | **严重** |
|
||||
| **设置页** | ZCLAW Runtime 配置面板 | ⚠️ 大部分是前端本地状态 | **严重** |
|
||||
| **右侧面板** | 真实 Agent 身份与状态 | ⚠️ 混合真实数据与硬编码值 | **中等** |
|
||||
|
||||
### 1.2 关键差距详解
|
||||
|
||||
#### 差距 1:分身与 Agent 断层(最严重)
|
||||
|
||||
```
|
||||
当前架构:
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ ZClaw 分身系统 (zclaw-data.json) │
|
||||
│ clone_1: { name: "程序员", workspaceDir: "...", ... } │
|
||||
│ clone_2: { name: "设计师", workspaceDir: "...", ... } │
|
||||
└────────────────────────┬────────────────────────────────────┘
|
||||
│ ❌ 无同步
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ ZCLAW agents.list (zclaw.json) │
|
||||
│ 只有: [{ id: "main", groupChat: {...} }] │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**后果**:
|
||||
- 所有分身实际共用同一个 `main` Agent
|
||||
- 聊天时不传递 `agentId`,ZCLAW 不知道当前是哪个分身
|
||||
- Bootstrap 文件(IDENTITY.md, SOUL.md 等)生成了但未被运行时使用
|
||||
|
||||
#### 差距 2:设置页是"假状态"
|
||||
|
||||
| 设置页 | 当前实现 | 应该实现 |
|
||||
|--------|----------|----------|
|
||||
| 模型选择 | 存在 `chatStore.currentModel`(前端状态) | 调用 `config.patch` 修改 ZCLAW 配置 |
|
||||
| MCP 服务 | 存 `quickConfig`,部分同步到 Gateway | 管理 `plugins.load.paths` |
|
||||
| 技能目录 | 存 `quickConfig` | 管理 `skills.load.extraDirs` |
|
||||
| IM 频道 | 存 `quickConfig`,只显示状态 | 管理 `channels.*` 配置 |
|
||||
| 工作区 | 存 `quickConfig` | 管理 `agents.defaults.workspace` |
|
||||
| 隐私 | 存 `quickConfig` | 管理 telemetry/优化计划 |
|
||||
|
||||
**缺失的 RPC 方法**:
|
||||
- `config.get` - 读取 ZCLAW 配置
|
||||
- `config.patch` - 修改配置
|
||||
- `config.apply` - 热更新配置
|
||||
|
||||
#### 差距 3:右侧面板数据不真实
|
||||
|
||||
```typescript
|
||||
// 硬编码的默认值(RightPanel.tsx)
|
||||
const credits = 2268; // 完全假数据
|
||||
const defaultUserName = '用户7141'; // 假用户名
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 二、根因分析
|
||||
|
||||
### 2.1 架构层面的偏差
|
||||
|
||||
**文档期望**:
|
||||
> ZClaw 应该是 ZCLAW Runtime 的控制界面
|
||||
|
||||
**实际实现**:
|
||||
> ZClaw 是一个有自己数据模型的前端应用,与 ZCLAW 是松耦合
|
||||
|
||||
### 2.2 数据模型的分裂
|
||||
|
||||
```
|
||||
ZCLAW 数据模型:
|
||||
zclaw.json → agents.list → Agent workspace → Bootstrap files
|
||||
|
||||
ZClaw 数据模型:
|
||||
zclaw-data.json → clones[] → (独立的) workspace 路径
|
||||
```
|
||||
|
||||
两套数据模型没有桥接,导致:
|
||||
1. 分身不能路由到正确的 Agent
|
||||
2. 设置不能影响 ZCLAW 行为
|
||||
3. Bootstrap 文件与运行时脱节
|
||||
|
||||
---
|
||||
|
||||
## 三、头脑风暴:改进方案
|
||||
|
||||
### 3.1 方案 A:完全对齐 ZCLAW(推荐)
|
||||
|
||||
**核心思路**:让 ZClaw 分身直接映射到 ZCLAW Agent
|
||||
|
||||
```
|
||||
改进后架构:
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ ZClaw 分身 = ZCLAW Agent │
|
||||
│ │
|
||||
│ clone_1 ↔ agents.list[0] (id: "programmer") │
|
||||
│ clone_2 ↔ agents.list[1] (id: "designer") │
|
||||
│ │
|
||||
│ 分身 CRUD → 同步修改 agents.list │
|
||||
│ 聊天时 → 传递 agentId 到 Gateway │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**优点**:
|
||||
- 符合 `zclaw-deep-dive.md` 的设计哲学
|
||||
- 分身真正有独立人格、记忆、工具权限
|
||||
- 设置页可以直接操作 ZCLAW 配置
|
||||
|
||||
**缺点**:
|
||||
- 改动较大,需要修改多个模块
|
||||
- 需要处理数据迁移
|
||||
|
||||
### 3.2 方案 B:保持独立,增强桥接
|
||||
|
||||
**核心思路**:保持 `zclaw-data.json`,但增加同步逻辑
|
||||
|
||||
```
|
||||
改进后架构:
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ ZClaw 分身系统 (主) │
|
||||
│ zclaw-data.json → clones[] │
|
||||
│ │ │
|
||||
│ ▼ (单向同步) │
|
||||
│ zclaw.json → agents.list (从分身生成) │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**优点**:
|
||||
- 改动较小
|
||||
- 保持现有分身管理逻辑
|
||||
|
||||
**缺点**:
|
||||
- 数据冗余,需要维护同步
|
||||
- 不符合 ZCLAW 的设计哲学
|
||||
|
||||
### 3.3 方案 C:混合模式
|
||||
|
||||
**核心思路**:
|
||||
- 简单分身:共用 `main` Agent,通过 Bootstrap 文件区分
|
||||
- 高级分身:映射到独立 ZCLAW Agent
|
||||
|
||||
---
|
||||
|
||||
## 四、推荐实施路线(方案 A)
|
||||
|
||||
### P0:让分身真正工作(最小可行)
|
||||
|
||||
**目标**:创建分身时同步到 ZCLAW `agents.list`,聊天时传递 `agentId`
|
||||
|
||||
**关键修改**:
|
||||
|
||||
1. **`plugins/zclaw-ui/index.ts`**
|
||||
- `createClone` 时调用 ZCLAW API 添加到 `agents.list`
|
||||
- `deleteClone` 时从 `agents.list` 移除
|
||||
- 新增 `zclaw.agents.sync` 方法
|
||||
|
||||
2. **`desktop/src/lib/gateway-client.ts`**
|
||||
- `chat()` 方法增加 `agentId` 参数
|
||||
```typescript
|
||||
async chat(message: string, opts?: { agentId?: string; sessionKey?: string }): Promise<...>
|
||||
```
|
||||
|
||||
3. **`desktop/src/store/chatStore.ts`**
|
||||
- `sendMessage` 时传递 `currentAgent.id` 作为 `agentId`
|
||||
|
||||
4. **新增 Gateway RPC**
|
||||
- `zclaw.config.get` - 读取 ZCLAW 配置
|
||||
- `zclaw.config.patch` - 修改配置
|
||||
|
||||
**验收标准**:
|
||||
- [ ] 创建分身后,`zclaw.json` 的 `agents.list` 包含新 Agent
|
||||
- [ ] 切换分身后,聊天请求携带正确的 `agentId`
|
||||
- [ ] 每个分身有独立的对话上下文
|
||||
|
||||
### P1:设置页 Runtime 化
|
||||
|
||||
**目标**:设置修改直接影响 ZCLAW Runtime
|
||||
|
||||
**关键修改**:
|
||||
|
||||
1. **`desktop/src/lib/gateway-client.ts`**
|
||||
- 实现 `configGet()`、`configPatch()`、`configApply()` 方法
|
||||
|
||||
2. **各设置页改造**
|
||||
- **模型与 API**:调用 `config.patch` 修改 `agents.defaults.model`
|
||||
- **MCP 服务**:管理 `plugins.load.paths`
|
||||
- **技能目录**:管理 `skills.load.extraDirs`
|
||||
- **工作区**:管理 `agents.defaults.workspace`
|
||||
- **隐私**:管理 telemetry 相关配置
|
||||
|
||||
3. **UI 反馈**
|
||||
- 显示配置保存状态
|
||||
- 配置变更后显示"需要重启"提示(如需要)
|
||||
|
||||
**验收标准**:
|
||||
- [ ] 模型选择后,`zclaw.json` 的 `agents.defaults.model` 更新
|
||||
- [ ] 添加技能目录后,`skills.load.extraDirs` 更新
|
||||
- [ ] Gateway 重启后配置生效
|
||||
|
||||
### P2:完整的 Agent 管理系统
|
||||
|
||||
**目标**:分身管理 = Agent 全生命周期管理
|
||||
|
||||
**功能扩展**:
|
||||
1. 分身绑定渠道(飞书账号、微信群等)
|
||||
2. 分身 Heartbeat 配置
|
||||
3. 分身工具权限/沙箱配置
|
||||
4. 分身间路由规则
|
||||
|
||||
**UI 改进**:
|
||||
- 右侧面板显示真实 Agent 状态(非硬编码)
|
||||
- 分身详情页增加完整配置选项
|
||||
|
||||
### P3:产品化封装
|
||||
|
||||
**目标**:开箱即用的桌面体验
|
||||
|
||||
**功能**:
|
||||
1. Tauri sidecar 管理 Gateway 进程
|
||||
2. 首次安装配置向导
|
||||
3. 错误诊断与自动修复
|
||||
4. 一键更新
|
||||
|
||||
---
|
||||
|
||||
## 五、关键文件清单
|
||||
|
||||
| 文件 | 修改内容 |
|
||||
|------|----------|
|
||||
| `plugins/zclaw-ui/index.ts` | 分身 CRUD 同步到 agents.list |
|
||||
| `desktop/src/lib/gateway-client.ts` | 增加 agentId 参数、config RPC |
|
||||
| `desktop/src/store/chatStore.ts` | sendMessage 传递 agentId |
|
||||
| `desktop/src/store/gatewayStore.ts` | 管理 Agent 配置状态 |
|
||||
| `desktop/src/components/CloneManager.tsx` | 显示同步状态 |
|
||||
| `desktop/src/components/RightPanel.tsx` | 显示真实 Agent 数据 |
|
||||
| `desktop/src/components/Settings/*.tsx` | 改造为 Runtime 配置面板 |
|
||||
| `config/zclaw.default.json` | 更新默认 Agent 模板 |
|
||||
|
||||
---
|
||||
|
||||
## 六、风险与缓解
|
||||
|
||||
| 风险 | 缓解措施 |
|
||||
|------|----------|
|
||||
| 数据迁移复杂 | 提供迁移脚本,保留 `zclaw-data.json` 作为备份 |
|
||||
| ZCLAW 版本兼容 | 检测 ZCLAW 版本,低版本降级到兼容模式 |
|
||||
| 破坏现有功能 | 灰度发布,支持回滚 |
|
||||
| 性能下降 | 懒加载 Agent 配置,缓存 RPC 结果 |
|
||||
|
||||
---
|
||||
|
||||
## 七、确认的方案
|
||||
|
||||
**选择:方案 A - 完全对齐 ZCLAW**
|
||||
|
||||
理由:
|
||||
1. 符合 `zclaw-deep-dive.md` 的设计哲学
|
||||
2. 分身真正有独立人格、记忆、工具权限
|
||||
3. 设置页可以直接操作 ZCLAW 配置
|
||||
4. 长期维护成本最低
|
||||
|
||||
---
|
||||
|
||||
## 八、下一步行动(P0 详细任务)
|
||||
|
||||
### Task 1: 修改 `zclaw-ui` 插件 - 分身同步到 agents.list
|
||||
|
||||
**文件**: `plugins/zclaw-ui/index.ts`
|
||||
|
||||
**修改点**:
|
||||
1. `createClone` 方法增加:
|
||||
- 调用 ZCLAW 内部 API 将分身添加到 `agents.list`
|
||||
- 设置 `agentId` 字段关联分身与 Agent
|
||||
2. `deleteClone` 方法增加:
|
||||
- 从 `agents.list` 移除对应 Agent
|
||||
3. `updateClone` 方法增加:
|
||||
- 同步更新 Agent 配置
|
||||
4. 新增 `zclaw.agents.sync` 方法:
|
||||
- 读取当前 `agents.list`
|
||||
- 与 `zclaw-data.json` 比对
|
||||
- 修复不一致
|
||||
|
||||
### Task 2: 修改 GatewayClient - 支持 agentId
|
||||
|
||||
**文件**: `desktop/src/lib/gateway-client.ts`
|
||||
|
||||
**修改点**:
|
||||
1. `chat()` 方法签名改为:
|
||||
```typescript
|
||||
async chat(message: string, opts?: {
|
||||
agentId?: string; // 新增
|
||||
sessionKey?: string;
|
||||
model?: string;
|
||||
}): Promise<{ runId: string; acceptedAt: string }>
|
||||
```
|
||||
2. `request('agent', ...)` 时传递 `agentId`
|
||||
|
||||
### Task 3: 修改 chatStore - 传递 agentId
|
||||
|
||||
**文件**: `desktop/src/store/chatStore.ts`
|
||||
|
||||
**修改点**:
|
||||
1. `sendMessage` 方法调用 `client.chat()` 时传递 `currentAgent.id`
|
||||
|
||||
### Task 4: 新增配置 RPC 方法
|
||||
|
||||
**文件**: `desktop/src/lib/gateway-client.ts` + `plugins/zclaw-ui/index.ts`
|
||||
|
||||
**新增方法**:
|
||||
- `zclaw.config.get` - 读取 ZCLAW 配置
|
||||
- `zclaw.config.patch` - 修改配置(不重启)
|
||||
- `zclaw.config.apply` - 热更新配置(如需重启)
|
||||
|
||||
### Task 5: 数据迁移脚本
|
||||
|
||||
**创建**: `scripts/migrate-clones-to-agents.ts`
|
||||
|
||||
**功能**:
|
||||
1. 读取现有 `zclaw-data.json` 中的分身
|
||||
2. 为每个分身在 `agents.list` 创建对应条目
|
||||
3. 更新分身的 `agentId` 字段
|
||||
4. 备份原始文件
|
||||
|
||||
---
|
||||
|
||||
## 九、验收标准
|
||||
|
||||
### P0 完成标准
|
||||
|
||||
- [ ] 创建分身后,`~/.zclaw/zclaw.json` 的 `agents.list` 包含新 Agent
|
||||
- [ ] 删除分身后,对应 Agent 从 `agents.list` 移除
|
||||
- [ ] 切换分身后,聊天请求携带正确的 `agentId`
|
||||
- [ ] 每个分身有独立的对话上下文(不串聊)
|
||||
- [ ] 现有分身数据成功迁移,无数据丢失
|
||||
- [ ] 单元测试覆盖新增逻辑 ≥ 80%
|
||||
381
docs/archive/old-plans/skill-market-mvp.md
Normal file
@@ -0,0 +1,381 @@
|
||||
# Skill Market MVP 实现计划
|
||||
|
||||
> **创建日期**: 2026-03-20
|
||||
> **状态**: 研究完成,待实现
|
||||
> **优先级**: P1 - 中期计划 (M2)
|
||||
|
||||
---
|
||||
|
||||
## 一、背景研究
|
||||
|
||||
### 1.1 现有代码分析
|
||||
|
||||
经过代码审查,发现以下关键组件已存在但需要集成和完善:
|
||||
|
||||
#### 已存在组件
|
||||
|
||||
| 组件 | 路径 | 状态 | 问题 |
|
||||
|------|------|------|------|
|
||||
| SkillMarket.tsx | `desktop/src/components/SkillMarket.tsx` | 已实现 | 使用本地 SkillDiscoveryEngine,未接入后端 |
|
||||
| skillMarketStore.ts | `desktop/src/store/skillMarketStore.ts` | 已实现 | 使用硬编码技能列表,未接入 configStore |
|
||||
| skill-discovery.ts | `desktop/src/lib/skill-discovery.ts` | 已实现 | 使用 localStorage + 静态技能注册表 |
|
||||
| skill-market.ts (类型) | `desktop/src/types/skill-market.ts` | 已实现 | Skill/SkillReview/SkillMarketState 类型 |
|
||||
| configStore.ts | `desktop/src/store/configStore.ts` | 已实现 | 包含 skillsCatalog 和技能 CRUD 方法 |
|
||||
| gateway-api.ts | `desktop/src/lib/gateway-api.ts` | 已实现 | 包含 listSkills/getSkill/createSkill 等方法 |
|
||||
|
||||
#### 技能定义文件
|
||||
|
||||
- `skills/` 目录包含 **74 个 SKILL.md** 文件
|
||||
- 格式: YAML frontmatter + Markdown 正文
|
||||
- 包含: name, description, triggers, tools, capabilities 等
|
||||
|
||||
### 1.2 当前架构问题
|
||||
|
||||
1. **双轨系统**: `SkillMarket.tsx` 使用 `SkillDiscoveryEngine`,但 `configStore.ts` 已有完整的技能管理逻辑
|
||||
2. **硬编码技能**: `skillMarketStore.ts` 的 `scanSkillsDirectory()` 返回硬编码列表,未读取实际 SKILL.md
|
||||
3. **后端未连接**: 组件未通过 `GatewayClient` 与后端 `/api/skills` 通信
|
||||
4. **安装状态不同步**: `skillMarketStore` 和 `configStore` 各自维护 `installed` 状态
|
||||
|
||||
### 1.3 数据流现状
|
||||
|
||||
```
|
||||
当前(问题):
|
||||
SkillMarket.tsx → SkillDiscoveryEngine → localStorage
|
||||
↓
|
||||
BUILT_IN_SKILLS (硬编码 12 个)
|
||||
|
||||
configStore.ts → GatewayClient → /api/skills (后端)
|
||||
↓
|
||||
skillsCatalog (从后端获取)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 二、MVP 功能范围
|
||||
|
||||
### 2.1 核心功能
|
||||
|
||||
| 功能 | 优先级 | 描述 |
|
||||
|------|--------|------|
|
||||
| 技能浏览 | P0 | 展示所有可用技能,支持分类筛选 |
|
||||
| 技能搜索 | P0 | 按名称、触发词、能力搜索 |
|
||||
| 技能详情 | P0 | 展示技能详细信息(能力、触发词、工具依赖) |
|
||||
| 安装/卸载 | P0 | 切换技能启用状态,持久化到后端 |
|
||||
| 分类过滤 | P1 | 按类别筛选技能 |
|
||||
|
||||
### 2.2 MVP 不包含
|
||||
|
||||
- 技能评分和评论(已有代码但 MVP 不启用)
|
||||
- 技能推荐引擎(suggestSkills 功能)
|
||||
- 技能市场在线同步
|
||||
- 技能版本管理
|
||||
- 自定义技能创建
|
||||
|
||||
### 2.3 技能卡片信息
|
||||
|
||||
每张技能卡片需要展示:
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ [图标] 技能名称 [已安装?] │
|
||||
│ 简短描述(1-2 行) │
|
||||
│ ┌─────────┐ ┌──────────┐ │
|
||||
│ │ 分类标签 │ │ 能力标签 │ ... │
|
||||
│ └─────────┘ └──────────┘ │
|
||||
│ │
|
||||
│ 展开后: │
|
||||
│ 触发词: [词1] [词2] [词3] │
|
||||
│ 能力: [能力1] [能力2] [能力3] │
|
||||
│ 工具依赖: [read] [write] [bash] │
|
||||
│ │
|
||||
│ [安装] 或 [卸载] │
|
||||
└─────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 三、技术架构
|
||||
|
||||
### 3.1 目标数据流
|
||||
|
||||
```
|
||||
目标架构:
|
||||
SkillMarket.tsx → useConfigStore → GatewayClient → /api/skills
|
||||
↓
|
||||
skillsCatalog (统一来源)
|
||||
↓
|
||||
安装状态 → GatewayClient.updateSkill() → 后端
|
||||
```
|
||||
|
||||
### 3.2 组件依赖关系
|
||||
|
||||
```
|
||||
App.tsx
|
||||
└── SkillMarket.tsx (重构)
|
||||
├── useConfigStore (替代 SkillDiscoveryEngine)
|
||||
├── SkillCard (保留,增强)
|
||||
├── CategoryBadge (保留)
|
||||
└── SuggestionCard (MVP 隐藏)
|
||||
```
|
||||
|
||||
### 3.3 类型统一
|
||||
|
||||
使用 `configStore.ts` 中的 `SkillInfo` 类型作为标准:
|
||||
|
||||
```typescript
|
||||
interface SkillInfo {
|
||||
id: string;
|
||||
name: string;
|
||||
path: string;
|
||||
source: 'builtin' | 'extra';
|
||||
description?: string;
|
||||
triggers?: Array<{ type: string; pattern?: string }>;
|
||||
actions?: Array<{ type: string; params?: Record<string, unknown> }>;
|
||||
enabled?: boolean;
|
||||
}
|
||||
```
|
||||
|
||||
需要与 `skill-market.ts` 中的 `Skill` 类型做适配:
|
||||
|
||||
```typescript
|
||||
// 适配映射
|
||||
function adaptSkillInfo(info: SkillInfo): Skill {
|
||||
return {
|
||||
id: info.id,
|
||||
name: info.name,
|
||||
description: info.description || '',
|
||||
triggers: info.triggers?.map(t => t.pattern || t.type) || [],
|
||||
capabilities: info.actions?.map(a => a.type) || [],
|
||||
category: extractCategory(info.path),
|
||||
installed: info.enabled || false,
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 四、实现步骤
|
||||
|
||||
### Phase 1: Store 统一 (1-2 天)
|
||||
|
||||
**目标**: 让 SkillMarket 使用 configStore 而非 SkillDiscoveryEngine
|
||||
|
||||
#### 任务清单
|
||||
|
||||
- [ ] 1.1 分析 configStore.skillsCatalog 返回的数据结构
|
||||
- [ ] 1.2 创建类型适配器 `adaptSkillInfo()`
|
||||
- [ ] 1.3 修改 SkillMarket.tsx 使用 `useConfigStore`
|
||||
- [ ] 1.4 移除对 SkillDiscoveryEngine 的直接依赖
|
||||
- [ ] 1.5 测试技能列表加载
|
||||
|
||||
#### 文件变更
|
||||
|
||||
| 文件 | 操作 |
|
||||
|------|------|
|
||||
| `desktop/src/components/SkillMarket.tsx` | 修改 |
|
||||
| `desktop/src/lib/skill-adapter.ts` | 新建 |
|
||||
|
||||
### Phase 2: 后端集成 (2-3 天)
|
||||
|
||||
**目标**: 实现真正的安装/卸载功能
|
||||
|
||||
#### 任务清单
|
||||
|
||||
- [ ] 2.1 验证 `/api/skills` 端点可用性
|
||||
- [ ] 2.2 实现 `installSkill()` 调用 `updateSkill(id, { enabled: true })`
|
||||
- [ ] 2.3 实现 `uninstallSkill()` 调用 `updateSkill(id, { enabled: false })`
|
||||
- [ ] 2.4 添加加载状态和错误处理
|
||||
- [ ] 2.5 添加乐观更新和回滚机制
|
||||
|
||||
#### 文件变更
|
||||
|
||||
| 文件 | 操作 |
|
||||
|------|------|
|
||||
| `desktop/src/store/configStore.ts` | 修改(增强 updateSkill) |
|
||||
| `desktop/src/components/SkillMarket.tsx` | 修改(安装/卸载逻辑) |
|
||||
|
||||
### Phase 3: 搜索和分类 (1-2 天)
|
||||
|
||||
**目标**: 完善搜索和分类过滤功能
|
||||
|
||||
#### 任务清单
|
||||
|
||||
- [ ] 3.1 实现前端搜索过滤(基于 skillsCatalog)
|
||||
- [ ] 3.2 从技能列表提取所有分类
|
||||
- [ ] 3.3 实现分类过滤 UI
|
||||
- [ ] 3.4 优化搜索性能(防抖、缓存)
|
||||
|
||||
#### 文件变更
|
||||
|
||||
| 文件 | 操作 |
|
||||
|------|------|
|
||||
| `desktop/src/components/SkillMarket.tsx` | 修改 |
|
||||
| `desktop/src/hooks/useSkillSearch.ts` | 新建(可选) |
|
||||
|
||||
### Phase 4: UI 完善 (1-2 天)
|
||||
|
||||
**目标**: 提升用户体验
|
||||
|
||||
#### 任务清单
|
||||
|
||||
- [ ] 4.1 优化技能卡片展开动画
|
||||
- [ ] 4.2 添加安装/卸载确认提示
|
||||
- [ ] 4.3 添加空状态展示
|
||||
- [ ] 4.4 添加加载骨架屏
|
||||
- [ ] 4.5 优化响应式布局
|
||||
|
||||
#### 文件变更
|
||||
|
||||
| 文件 | 操作 |
|
||||
|------|------|
|
||||
| `desktop/src/components/SkillMarket.tsx` | 修改 |
|
||||
| `desktop/src/components/SkillCardSkeleton.tsx` | 新建 |
|
||||
|
||||
### Phase 5: 测试和文档 (1 天)
|
||||
|
||||
**目标**: 确保质量和可维护性
|
||||
|
||||
#### 任务清单
|
||||
|
||||
- [ ] 5.1 添加单元测试
|
||||
- [ ] 5.2 添加集成测试
|
||||
- [ ] 5.3 更新功能文档
|
||||
- [ ] 5.4 更新用户手册
|
||||
|
||||
#### 文件变更
|
||||
|
||||
| 文件 | 操作 |
|
||||
|------|------|
|
||||
| `tests/desktop/skill-market.test.ts` | 新建 |
|
||||
| `docs/features/04-skills-ecosystem/02-skill-discovery.md` | 更新 |
|
||||
|
||||
---
|
||||
|
||||
## 五、文件变更清单
|
||||
|
||||
### 新建文件
|
||||
|
||||
| 文件路径 | 用途 |
|
||||
|----------|------|
|
||||
| `desktop/src/lib/skill-adapter.ts` | SkillInfo <-> Skill 类型适配 |
|
||||
| `desktop/src/hooks/useSkillSearch.ts` | 技能搜索 hook(可选) |
|
||||
| `desktop/src/components/SkillCardSkeleton.tsx` | 加载骨架屏 |
|
||||
| `tests/desktop/skill-market.test.ts` | 测试文件 |
|
||||
|
||||
### 修改文件
|
||||
|
||||
| 文件路径 | 变更内容 |
|
||||
|----------|----------|
|
||||
| `desktop/src/components/SkillMarket.tsx` | 使用 configStore,优化 UI |
|
||||
| `desktop/src/store/configStore.ts` | 增强 updateSkill,添加乐观更新 |
|
||||
| `docs/features/04-skills-ecosystem/02-skill-discovery.md` | 更新文档 |
|
||||
| `docs/features/README.md` | 更新集成状态 |
|
||||
|
||||
### 可删除文件
|
||||
|
||||
| 文件路径 | 原因 |
|
||||
|----------|------|
|
||||
| `desktop/src/store/skillMarketStore.ts` | 合并到 configStore 后废弃 |
|
||||
| `desktop/src/types/skill-market.ts` | 使用 configStore 类型替代 |
|
||||
|
||||
---
|
||||
|
||||
## 六、风险和缓解
|
||||
|
||||
### 6.1 技术风险
|
||||
|
||||
| 风险 | 可能性 | 影响 | 缓解措施 |
|
||||
|------|--------|------|----------|
|
||||
| 后端 `/api/skills` 未返回完整数据 | 中 | 高 | 添加 fallback 到本地技能列表 |
|
||||
| 类型不兼容 | 低 | 中 | 创建适配器层 |
|
||||
| 性能问题(74个技能渲染) | 低 | 低 | 虚拟滚动(后期优化) |
|
||||
|
||||
### 6.2 用户体验风险
|
||||
|
||||
| 风险 | 可能性 | 影响 | 缓解措施 |
|
||||
|------|--------|------|----------|
|
||||
| 安装状态不同步 | 中 | 高 | 使用单一数据源(configStore) |
|
||||
| 搜索不准确 | 中 | 中 | 优化搜索算法,支持触发词匹配 |
|
||||
| 操作无反馈 | 低 | 中 | 添加 Toast 提示 |
|
||||
|
||||
---
|
||||
|
||||
## 七、验收标准
|
||||
|
||||
### 7.1 功能验收
|
||||
|
||||
- [ ] 能加载并显示所有 74 个技能
|
||||
- [ ] 搜索功能正常工作
|
||||
- [ ] 分类过滤功能正常工作
|
||||
- [ ] 安装/卸载操作能持久化
|
||||
- [ ] 刷新页面后状态保持
|
||||
|
||||
### 7.2 性能验收
|
||||
|
||||
- [ ] 首次加载 < 1s
|
||||
- [ ] 搜索响应 < 200ms
|
||||
- [ ] 列表滚动流畅(60fps)
|
||||
|
||||
### 7.3 质量验收
|
||||
|
||||
- [ ] 无 TypeScript 错误
|
||||
- [ ] 无 ESLint 警告
|
||||
- [ ] 测试覆盖率 > 80%
|
||||
|
||||
---
|
||||
|
||||
## 八、时间估算
|
||||
|
||||
| 阶段 | 估算时间 | 依赖 |
|
||||
|------|----------|------|
|
||||
| Phase 1: Store 统一 | 1-2 天 | 无 |
|
||||
| Phase 2: 后端集成 | 2-3 天 | Phase 1 |
|
||||
| Phase 3: 搜索和分类 | 1-2 天 | Phase 2 |
|
||||
| Phase 4: UI 完善 | 1-2 天 | Phase 3 |
|
||||
| Phase 5: 测试和文档 | 1 天 | Phase 4 |
|
||||
| **总计** | **6-10 天** | - |
|
||||
|
||||
---
|
||||
|
||||
## 九、后续迭代方向
|
||||
|
||||
### 9.1 短期优化
|
||||
|
||||
- 技能推荐引擎(基于对话上下文)
|
||||
- 技能使用统计
|
||||
- 技能收藏功能
|
||||
|
||||
### 9.2 中期扩展
|
||||
|
||||
- 技能创建向导
|
||||
- 技能导入/导出
|
||||
- 技能市场在线同步
|
||||
|
||||
### 9.3 长期愿景
|
||||
|
||||
- 技能共享社区
|
||||
- 技能认证体系
|
||||
- 技能版本管理
|
||||
|
||||
---
|
||||
|
||||
## 十、参考资料
|
||||
|
||||
### 10.1 相关文档
|
||||
|
||||
- [Skills 系统概述](../features/04-skills-ecosystem/00-skill-system.md)
|
||||
- [状态管理文档](../features/00-architecture/02-state-management.md)
|
||||
- [通信层文档](../features/00-architecture/01-communication-layer.md)
|
||||
|
||||
### 10.2 相关代码
|
||||
|
||||
- `desktop/src/lib/skill-discovery.ts` - 技能发现引擎
|
||||
- `desktop/src/store/configStore.ts` - 配置状态管理
|
||||
- `desktop/src/lib/gateway-api.ts` - API 方法实现
|
||||
- `skills/.templates/skill-template.md` - 技能模板
|
||||
|
||||
### 10.3 技能文件示例
|
||||
|
||||
- `skills/code-review/SKILL.md` - 简单格式示例
|
||||
- `skills/data-analysis/SKILL.md` - 带表格示例
|
||||
- `skills/devops-automator/SKILL.md` - 完整模板示例
|
||||
571
docs/archive/old-plans/snug-napping-valiant.md
Normal file
@@ -0,0 +1,571 @@
|
||||
# ZCLAW 系统全面代码分析与演化路线图
|
||||
|
||||
## 上下文 (Context)
|
||||
|
||||
**目的**: 对 ZCLAW 系统进行全面的代码层面现状分析,识别偏离点、潜在风险,制定分阶段演化路线图。
|
||||
|
||||
**当前状态**:
|
||||
- ZCLAW v0.4.0 + ZClaw Desktop v0.2.0
|
||||
- API 覆盖率: 93% (63/68 端点)
|
||||
- UI 完成度: 100% (30/30 组件)
|
||||
- Skills 定义: 68 个已完成
|
||||
- Phase 1-8 已完成
|
||||
|
||||
**技术栈**:
|
||||
- React 19.1.0 + TypeScript 5.8.3
|
||||
- Tauri 2.x (Rust 后端)
|
||||
- Zustand 5.0.11 (状态管理)
|
||||
- Vite 7.0.4 + Tailwind CSS 4.2.1
|
||||
|
||||
---
|
||||
|
||||
## 一、代码结构分析
|
||||
|
||||
### 1.1 项目结构
|
||||
|
||||
```
|
||||
ZClaw_zclaw/
|
||||
├── desktop/ # Tauri 桌面应用 (主要代码)
|
||||
│ ├── src/
|
||||
│ │ ├── components/ # React UI (46 组件)
|
||||
│ │ ├── store/ # Zustand stores (3 个)
|
||||
│ │ ├── lib/ # API 客户端和工具
|
||||
│ │ ├── types/ # TypeScript 类型定义
|
||||
│ │ └── App.tsx # 主应用组件
|
||||
│ └── src-tauri/ # Rust 后端
|
||||
├── skills/ # 68 个 SKILL.md 定义
|
||||
├── hands/ # 7 个 HAND.toml 配置
|
||||
├── config/ # ZCLAW TOML 配置
|
||||
├── tests/ # Vitest 测试
|
||||
└── docs/ # 文档
|
||||
```
|
||||
|
||||
### 1.2 核心数据流
|
||||
|
||||
```
|
||||
React UI → Zustand Store → GatewayClient → ZCLAW Kernel (端口 50051)
|
||||
↓
|
||||
WebSocket (ws://127.0.0.1:50051/ws)
|
||||
REST API (http://127.0.0.1:50051/api/*)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 二、架构问题分析
|
||||
|
||||
### 2.1 Store 层问题 (高优先级)
|
||||
|
||||
| 问题 | 位置 | 影响 |
|
||||
|------|------|------|
|
||||
| **gatewayStore 巨型化** | `store/gatewayStore.ts` | 50+ 字段、40+ actions 在单一 store |
|
||||
| **持久化策略不一致** | 所有 stores | chatStore 用 Zustand persist,teamStore 手动 localStorage |
|
||||
| **Agent/Clone ID 混淆** | `chatStore.ts` | 前端 `clone_` 前缀与后端 ID 不一致 |
|
||||
|
||||
### 2.2 安全问题 (关键)
|
||||
|
||||
| 问题 | 位置 | 严重程度 |
|
||||
|------|------|----------|
|
||||
| **Token 存储在 localStorage** | `gateway-client.ts:103` | HIGH |
|
||||
| **Ed25519 密钥无加密** | `gateway-client.ts:157-188` | HIGH |
|
||||
| **JSON.parse 无保护** | `HandParamsForm.tsx:409`, `WorkflowEditor.tsx:167` | HIGH |
|
||||
| **默认使用 ws://** | `gateway-client.ts:20-22` | MEDIUM |
|
||||
|
||||
### 2.3 代码质量问题
|
||||
|
||||
| 问题 | 数量 | 主要位置 |
|
||||
|------|------|----------|
|
||||
| **`any` 类型滥用** | 60+ 处 | `gatewayStore.ts` (~35), `gateway-client.ts` (~12) |
|
||||
| **错误处理不完整** | 多处 | 部分 catch 块静默忽略错误 |
|
||||
| **测试覆盖不足** | - | `gateway-client.ts`, `toml-utils.ts` 无测试 |
|
||||
| **代码重复** | 30+ 处 | 错误处理模式重复 |
|
||||
|
||||
### 2.4 性能问题
|
||||
|
||||
| 问题 | 位置 | 影响 |
|
||||
|------|------|------|
|
||||
| **消息数组频繁 map** | `chatStore.ts` | 长对话性能下降 |
|
||||
| **无消息分页** | `chatStore.ts` | 内存持续增长 |
|
||||
| **无 WebSocket 批处理** | `gateway-client.ts` | 高频消息处理效率低 |
|
||||
|
||||
---
|
||||
|
||||
## 三、分阶段演化路线图
|
||||
|
||||
### Phase 9: 安全加固 (1 周) - 3 代理并行
|
||||
|
||||
**目标**: 修复关键安全漏洞
|
||||
|
||||
#### 并行执行架构
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ Agent A: JSON 安全 │ Agent B: Token 迁移 │
|
||||
│ ├── lib/json-utils.ts │ ├── gateway-client.ts │
|
||||
│ ├── HandParamsForm.tsx │ ├── gatewayStore.ts │
|
||||
│ └── WorkflowEditor.tsx │ └── 迁移工具 │
|
||||
├─────────────────────────────┼───────────────────────────────┤
|
||||
│ Agent C: 加密增强 │ 完成后合并 → 文档更新 → 推送 │
|
||||
│ ├── secure-storage.ts │ ├── docs/SYSTEM_ANALYSIS.md │
|
||||
│ ├── secure_storage.rs │ ├── PROGRESS.md │
|
||||
│ └── WSS 配置 │ └── git commit + push │
|
||||
└─────────────────────────────┴───────────────────────────────┘
|
||||
```
|
||||
|
||||
| 任务 | 文件 | 工作量 | 代理 |
|
||||
|------|------|--------|------|
|
||||
| 创建 `safeJsonParse<T>()` | `lib/json-utils.ts` | 4h | A |
|
||||
| 替换不安全 JSON.parse | `HandParamsForm.tsx`, `WorkflowEditor.tsx` | 3h | A |
|
||||
| Token 迁移到 secure-storage | `gateway-client.ts`, `gatewayStore.ts` | 6h | B |
|
||||
| Ed25519 密钥加密 | `secure-storage.ts`, `secure_storage.rs` | 4h | C |
|
||||
| 添加 WSS 配置 | `gateway-client.ts` | 2h | C |
|
||||
|
||||
**完成后同步**:
|
||||
```bash
|
||||
# 1. 更新文档
|
||||
git add docs/SYSTEM_ANALYSIS.md PROGRESS.md
|
||||
git commit -m "docs: update Phase 9 security hardening progress"
|
||||
git push origin main
|
||||
|
||||
# 2. 代码提交
|
||||
git add . && git commit -m "security(phase-9): complete security hardening
|
||||
|
||||
- Add safeJsonParse utility with schema validation
|
||||
- Migrate tokens to OS keyring storage
|
||||
- Add Ed25519 key encryption at rest
|
||||
- Enable WSS configuration option
|
||||
|
||||
Co-Authored-By: Claude <noreply@anthropic.com>"
|
||||
git push origin main
|
||||
```
|
||||
|
||||
**验收标准**:
|
||||
- [ ] 所有 JSON.parse 有 try-catch 保护
|
||||
- [ ] Token 存储在 OS keyring
|
||||
- [ ] TypeScript 编译通过
|
||||
- [ ] 现有测试通过
|
||||
- [ ] **文档已更新并推送**
|
||||
|
||||
---
|
||||
|
||||
### Phase 10: 类型安全强化 (1 周) - 3 代理并行
|
||||
|
||||
**目标**: 减少 `any` 使用,提升类型安全
|
||||
|
||||
#### 并行执行架构
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ Agent A: API 类型 │ Agent B: Store 类型 │
|
||||
│ ├── types/api-responses.ts │ ├── store/gatewayStore.ts │
|
||||
│ ├── types/errors.ts │ └── 35 处 any 替换 │
|
||||
│ └── 所有 API 响应类型化 │ │
|
||||
├─────────────────────────────┼───────────────────────────────┤
|
||||
│ Agent C: Client 类型 │ 完成后 → 统计 any 减少 → 推送 │
|
||||
│ ├── lib/gateway-client.ts │ grep -r ": any" | wc -l │
|
||||
│ └── 12 处 any 替换 │ git commit + push │
|
||||
└─────────────────────────────┴───────────────────────────────┘
|
||||
```
|
||||
|
||||
| 任务 | 文件 | 工作量 | 代理 |
|
||||
|------|------|--------|------|
|
||||
| 创建 API 响应类型 | `types/api-responses.ts` | 4h | A |
|
||||
| 创建错误类型层级 | `types/errors.ts` | 2h | A |
|
||||
| 替换 gatewayStore any | `store/gatewayStore.ts` (35处) | 8h | B |
|
||||
| 替换 gateway-client any | `lib/gateway-client.ts` (12处) | 4h | C |
|
||||
|
||||
**完成后同步**:
|
||||
```bash
|
||||
# 统计并提交
|
||||
echo "## Phase 10 类型安全 (完成)" >> docs/SYSTEM_ANALYSIS.md
|
||||
git add . && git commit -m "refactor(phase-10): reduce any usage by 50%" && git push
|
||||
```
|
||||
|
||||
**验收标准**:
|
||||
- [ ] `any` 使用减少 50% (从 60+ 降到 30)
|
||||
- [ ] 所有 API 响应有类型定义
|
||||
- [ ] TypeScript strict mode 通过
|
||||
- [ ] **文档已更新并推送**
|
||||
|
||||
---
|
||||
|
||||
### Phase 11: Store 重构 (2 周) - 分步并行
|
||||
|
||||
**目标**: 分解巨型 gatewayStore (1500+ 行)
|
||||
|
||||
**目标架构**:
|
||||
```
|
||||
gatewayStore (协调器, <100 行)
|
||||
├── connectionStore (WebSocket, 认证, ~200 行)
|
||||
├── agentStore (分身, 配置文件, ~200 行)
|
||||
├── handStore (Hands, 触发器, ~200 行)
|
||||
├── workflowStore (工作流, 执行历史, ~200 行)
|
||||
└── configStore (设置, 工作区, ~200 行)
|
||||
```
|
||||
|
||||
#### 分步并行执行
|
||||
```
|
||||
Step 1 (阻塞): 创建所有 store 接口定义 (1 天)
|
||||
↓
|
||||
Step 2 (并行): 同时提取 connectionStore, agentStore, handStore (3 天)
|
||||
↓
|
||||
Step 3 (并行): 同时提取 workflowStore, configStore (2 天)
|
||||
↓
|
||||
Step 4 (阻塞): 创建协调层 + 更新组件导入 (3 天)
|
||||
↓
|
||||
Step 5 (同步): 测试 + 文档更新 + 推送 (1 天)
|
||||
```
|
||||
|
||||
| 任务 | 工作量 | 执行方式 |
|
||||
|------|--------|----------|
|
||||
| 创建 store 接口定义 | 1 天 | 阻塞 |
|
||||
| 提取 connectionStore | 3 天 | 并行 A |
|
||||
| 提取 agentStore | 3 天 | 并行 B |
|
||||
| 提取 handStore | 3 天 | 并行 C |
|
||||
| 提取 workflowStore | 2 天 | 并行 A |
|
||||
| 提取 configStore | 2 天 | 并行 B |
|
||||
| 创建协调层 + 组件更新 | 3 天 | 阻塞 |
|
||||
|
||||
**完成后同步**:
|
||||
```bash
|
||||
git add . && git commit -m "refactor(phase-11): decompose gatewayStore
|
||||
|
||||
- Extract connectionStore (WebSocket, auth)
|
||||
- Extract agentStore (clones, profiles)
|
||||
- Extract handStore (hands, triggers)
|
||||
- Extract workflowStore (workflows, runs)
|
||||
- Extract configStore (settings, workspace)
|
||||
- Add coordinator layer
|
||||
|
||||
Each store now < 300 lines with clear separation of concerns.
|
||||
|
||||
Co-Authored-By: Claude <noreply@anthropic.com>"
|
||||
git push origin main
|
||||
```
|
||||
|
||||
**验收标准**:
|
||||
- [ ] 每个 store < 300 行
|
||||
- [ ] 清晰的关注点分离
|
||||
- [ ] 所有组件正常工作
|
||||
- [ ] **文档已更新并推送**
|
||||
|
||||
---
|
||||
|
||||
### Phase 12: 性能优化 (1 周) - 2 代理并行
|
||||
|
||||
**目标**: 优化消息处理和渲染
|
||||
|
||||
#### 并行执行架构
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ Agent A: 消息渲染优化 │ Agent B: WebSocket 优化 │
|
||||
│ ├── ChatArea.tsx 虚拟化 │ ├── gateway-client.ts │
|
||||
│ ├── chatStore.ts 分页 │ ├── 消息批处理 │
|
||||
│ └── lib/message-cache.ts │ └── 节流/防抖 │
|
||||
└─────────────────────────────┴───────────────────────────────┘
|
||||
```
|
||||
|
||||
| 任务 | 文件 | 工作量 | 代理 |
|
||||
|------|------|--------|------|
|
||||
| 实现消息虚拟化 | `ChatArea.tsx` | 8h | A |
|
||||
| 添加消息分页 | `chatStore.ts` | 6h | A |
|
||||
| 实现 LRU 消息缓存 | `lib/message-cache.ts` | 4h | A |
|
||||
| WebSocket 消息批处理 | `gateway-client.ts` | 4h | B |
|
||||
|
||||
**完成后同步**:
|
||||
```bash
|
||||
git add . && git commit -m "perf(phase-12): optimize message handling
|
||||
|
||||
- Add message virtualization for long conversations
|
||||
- Implement message pagination in chatStore
|
||||
- Add LRU cache for rendered messages
|
||||
- Add WebSocket message batching
|
||||
|
||||
Handles 10k+ messages without performance degradation.
|
||||
|
||||
Co-Authored-By: Claude <noreply@anthropic.com>"
|
||||
git push origin main
|
||||
```
|
||||
|
||||
**验收标准**:
|
||||
- [ ] 支持 10,000+ 消息无性能下降
|
||||
- [ ] 内存使用保持稳定
|
||||
- [ ] 滚动流畅
|
||||
- [ ] **文档已更新并推送**
|
||||
|
||||
---
|
||||
|
||||
### Phase 13: 测试覆盖 (1 周) - 3 代理并行
|
||||
|
||||
**目标**: 建立完整测试体系,达到 80% 覆盖率
|
||||
|
||||
#### 并行执行架构
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ Agent A: 核心模块测试 │ Agent B: 工具模块测试 │
|
||||
│ ├── gateway-client.test.ts │ ├── secure-storage.test.ts │
|
||||
│ ├── 连接生命周期测试 │ ├── toml-utils.test.ts │
|
||||
│ └── 消息帧解析测试 │ └── json-utils.test.ts │
|
||||
├─────────────────────────────┼───────────────────────────────┤
|
||||
│ Agent C: 集成测试 │ 完成后 → 覆盖率报告 → 推送 │
|
||||
│ ├── chat-flow.test.ts │ pnpm vitest --coverage │
|
||||
│ └── React 组件测试 │ git commit + push │
|
||||
└─────────────────────────────┴───────────────────────────────┘
|
||||
```
|
||||
|
||||
| 任务 | 文件 | 工作量 | 代理 |
|
||||
|------|------|--------|------|
|
||||
| gateway-client 单元测试 | `tests/desktop/gateway-client.test.ts` | 6h | A |
|
||||
| secure-storage 单元测试 | `tests/desktop/secure-storage.test.ts` | 2h | B |
|
||||
| toml-utils 单元测试 | `tests/desktop/toml-utils.test.ts` | 2h | B |
|
||||
| json-utils 单元测试 | `tests/desktop/json-utils.test.ts` | 2h | B |
|
||||
| 聊天流程集成测试 | `tests/desktop/integration/chat-flow.test.ts` | 4h | C |
|
||||
| React 组件测试 | `tests/desktop/components/` | 8h | C |
|
||||
|
||||
**完成后同步**:
|
||||
```bash
|
||||
# 生成覆盖率报告
|
||||
pnpm vitest run --coverage
|
||||
|
||||
git add . && git commit -m "test(phase-13): achieve 80% test coverage
|
||||
|
||||
- Add gateway-client unit tests
|
||||
- Add secure-storage, toml-utils, json-utils tests
|
||||
- Add chat flow integration tests
|
||||
- Add React component tests
|
||||
|
||||
Coverage: 80%+ for core modules.
|
||||
|
||||
Co-Authored-By: Claude <noreply@anthropic.com>"
|
||||
git push origin main
|
||||
```
|
||||
|
||||
**验收标准**:
|
||||
- [ ] 核心模块测试覆盖率 > 80%
|
||||
- [ ] 关键用户流程有集成测试
|
||||
- [ ] CI/CD 流水线通过
|
||||
- [ ] **文档已更新并推送**
|
||||
|
||||
---
|
||||
|
||||
## 四、关键文件清单
|
||||
|
||||
### 需要修改的文件
|
||||
|
||||
| 优先级 | 文件路径 | 修改类型 |
|
||||
|--------|----------|----------|
|
||||
| P0 | `desktop/src/lib/gateway-client.ts` | 安全修复, 类型安全 |
|
||||
| P0 | `desktop/src/store/gatewayStore.ts` | 重构分解, 类型安全 |
|
||||
| P0 | `desktop/src/components/HandParamsForm.tsx` | JSON 解析安全 |
|
||||
| P0 | `desktop/src/components/WorkflowEditor.tsx` | JSON 解析安全 |
|
||||
| P1 | `desktop/src/store/chatStore.ts` | 性能优化 |
|
||||
| P1 | `desktop/src/lib/secure-storage.ts` | 密钥加密 |
|
||||
| P1 | `desktop/src-tauri/src/secure_storage.rs` | Rust 安全存储 |
|
||||
|
||||
### 需要创建的文件
|
||||
|
||||
| 文件路径 | 用途 |
|
||||
|----------|------|
|
||||
| `desktop/src/lib/json-utils.ts` | 安全 JSON 解析 |
|
||||
| `desktop/src/types/api-responses.ts` | API 响应类型 |
|
||||
| `desktop/src/types/errors.ts` | 错误类型定义 |
|
||||
| `desktop/src/lib/message-cache.ts` | 消息 LRU 缓存 |
|
||||
| `desktop/src/store/connectionStore.ts` | 连接状态管理 |
|
||||
| `desktop/src/store/agentStore.ts` | Agent 管理 |
|
||||
| `desktop/src/store/handStore.ts` | Hand 管理 |
|
||||
| `desktop/src/store/workflowStore.ts` | 工作流管理 |
|
||||
| `tests/desktop/gateway-client.test.ts` | 客户端测试 |
|
||||
|
||||
---
|
||||
|
||||
## 五、多代理并行执行策略
|
||||
|
||||
### 5.1 并行执行原则
|
||||
|
||||
**核心原则**: 独立任务并行执行,依赖任务顺序执行
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ 多代理并行执行架构 │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ Phase 9 (安全修复) - 并行执行: │
|
||||
│ ├── Agent A: JSON 安全包装 + 输入验证 │
|
||||
│ ├── Agent B: Token 迁移到 secure-storage │
|
||||
│ └── Agent C: WSS 配置 + 密钥加密 │
|
||||
│ │
|
||||
│ Phase 10 (类型安全) - 并行执行: │
|
||||
│ ├── Agent A: API 响应类型定义 │
|
||||
│ ├── Agent B: gatewayStore any 替换 │
|
||||
│ └── Agent C: gateway-client any 替换 │
|
||||
│ │
|
||||
│ Phase 11 (Store 重构) - 顺序执行 + 并行提取: │
|
||||
│ ├── Step 1: 创建接口定义 (阻塞) │
|
||||
│ ├── Step 2: 并行提取 connectionStore, agentStore, handStore │
|
||||
│ ├── Step 3: 并行提取 workflowStore, configStore │
|
||||
│ └── Step 4: 协调层 + 组件更新 │
|
||||
│ │
|
||||
│ Phase 12-13 (性能+测试) - 并行执行: │
|
||||
│ ├── Agent A: 消息虚拟化 + 分页 │
|
||||
│ ├── Agent B: WebSocket 批处理优化 │
|
||||
│ └── Agent C: 测试编写 (与 A/B 同步) │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 5.2 代理分工
|
||||
|
||||
| 代理类型 | 职责 | 适用阶段 |
|
||||
|----------|------|----------|
|
||||
| **Security Engineer** | 安全修复、加密、Token 迁移 | Phase 9 |
|
||||
| **Senior Developer** | 类型定义、Store 重构 | Phase 10-11 |
|
||||
| **Frontend Developer** | UI 组件、性能优化 | Phase 12 |
|
||||
| **Test Engineer** | 单元测试、集成测试 | Phase 13 |
|
||||
| **Documentation Writer** | 文档更新、CHANGELOG | 所有阶段 |
|
||||
|
||||
### 5.3 每阶段完成后的同步动作
|
||||
|
||||
```bash
|
||||
# 每个阶段完成后必须执行:
|
||||
|
||||
# 1. 更新相关文档
|
||||
# - docs/SYSTEM_ANALYSIS.md (添加 Phase 进度)
|
||||
# - docs/DEVELOPMENT.md (如有新开发指南)
|
||||
# - PROGRESS.md (进度追踪)
|
||||
|
||||
# 2. 提交到仓库
|
||||
git add .
|
||||
git commit -m "feat(phase-N): 完成阶段任务描述
|
||||
|
||||
- 具体改动 1
|
||||
- 具体改动 2
|
||||
|
||||
Co-Authored-By: Claude <noreply@anthropic.com>"
|
||||
|
||||
# 3. 推送到远程
|
||||
git push origin main
|
||||
```
|
||||
|
||||
### 5.4 文档更新检查清单
|
||||
|
||||
每个阶段完成后必须更新:
|
||||
|
||||
- [ ] `docs/SYSTEM_ANALYSIS.md` - 添加 Phase 完成记录
|
||||
- [ ] `PROGRESS.md` - 更新进度百分比
|
||||
- [ ] `CLAUDE.md` - 如有新的开发规范
|
||||
- [ ] `README.md` - 如有新功能或依赖变更
|
||||
|
||||
---
|
||||
|
||||
## 六、资源需求 (多代理优化后)
|
||||
|
||||
### 时间估算对比
|
||||
|
||||
| 阶段 | 串行执行 | 3代理并行 | 节省 |
|
||||
|------|----------|-----------|------|
|
||||
| Phase 9 (安全) | 2 周 | **1 周** | 50% |
|
||||
| Phase 10 (类型) | 2 周 | **1 周** | 50% |
|
||||
| Phase 11 (Store重构) | 3 周 | **2 周** | 33% |
|
||||
| Phase 12 (性能) | 2 周 | **1 周** | 50% |
|
||||
| Phase 13 (测试) | 2 周 | **1 周** | 50% |
|
||||
| **总计** | **11 周** | **6 周** | **45%** |
|
||||
|
||||
### 代理配置
|
||||
|
||||
| 阶段 | 所需代理 | 技能要求 |
|
||||
|------|----------|----------|
|
||||
| Phase 9 | 3 并行 | Security Engineer, Backend Dev, Rust Dev |
|
||||
| Phase 10 | 3 并行 | TypeScript Expert, Frontend Dev |
|
||||
| Phase 11 | 3 并行 → 顺序 | Senior Developer, State Management Expert |
|
||||
| Phase 12 | 2 并行 | Frontend Dev, Performance Engineer |
|
||||
| Phase 13 | 3 并行 | Test Engineer, Integration Specialist |
|
||||
|
||||
### 技能矩阵
|
||||
|
||||
| 技能 | Phase 9 | Phase 10 | Phase 11 | Phase 12 | Phase 13 |
|
||||
|------|---------|----------|----------|----------|----------|
|
||||
| TypeScript | 高 | 高 | 高 | 高 | 高 |
|
||||
| React | 中 | 中 | 高 | 高 | 中 |
|
||||
| Tauri/Rust | 高 | 低 | 低 | 低 | 低 |
|
||||
| WebSocket | 高 | 中 | 中 | 高 | 中 |
|
||||
| 状态管理 | 中 | 中 | 高 | 高 | 中 |
|
||||
| 安全 | 高 | 中 | 中 | 低 | 中 |
|
||||
| 测试 | 中 | 中 | 高 | 中 | 高 |
|
||||
|
||||
---
|
||||
|
||||
## 七、风险评估
|
||||
|
||||
| 风险 | 概率 | 影响 | 缓解措施 |
|
||||
|------|------|------|----------|
|
||||
| Store 重构破坏现有功能 | 中 | 高 | 重构前完善测试覆盖 |
|
||||
| 持久化迁移丢失数据 | 低 | 严重 | 迁移工具, 回滚能力 |
|
||||
| ID 标准化破坏 API 通信 | 中 | 高 | 集成测试验证 |
|
||||
| 性能优化引入新 bug | 中 | 中 | 渐进式发布, 功能开关 |
|
||||
|
||||
---
|
||||
|
||||
## 七、成功指标
|
||||
|
||||
### Phase 9-10 指标
|
||||
|
||||
- [ ] 零安全漏洞 (静态分析)
|
||||
- [ ] `any` 使用减少 50%
|
||||
- [ ] 所有 Token 在安全存储中
|
||||
|
||||
### Phase 11 指标
|
||||
|
||||
- [ ] 所有 store < 300 行
|
||||
- [ ] 清晰的关注点分离
|
||||
- [ ] 持久化策略一致
|
||||
|
||||
### Phase 12-13 指标
|
||||
|
||||
- [ ] 10k+ 消息无性能下降
|
||||
- [ ] UI 响应时间 < 100ms
|
||||
- [ ] 测试覆盖率 > 80%
|
||||
|
||||
---
|
||||
|
||||
## 八、验证计划
|
||||
|
||||
### 自动化验证
|
||||
|
||||
```bash
|
||||
# TypeScript 类型检查
|
||||
pnpm tsc --noEmit
|
||||
|
||||
# 单元测试
|
||||
pnpm vitest run
|
||||
|
||||
# 安全审计
|
||||
pnpm audit
|
||||
```
|
||||
|
||||
### 手动验证
|
||||
|
||||
1. 连接 ZCLAW (端口 50051)
|
||||
2. 发送消息并验证流式返回
|
||||
3. 触发 Hand 并验证执行
|
||||
4. 保存配置并验证持久化
|
||||
5. 测试长对话性能 (>1000 消息)
|
||||
|
||||
---
|
||||
|
||||
## 九、执行时间表 (6 周计划)
|
||||
|
||||
```
|
||||
周次 Phase 任务 代理数 交付物
|
||||
─────────────────────────────────────────────────────────────────
|
||||
W1 Phase 9 安全加固 3 并行 安全修复完成 + 文档
|
||||
W2 Phase 10 类型安全强化 3 并行 类型定义 + any 减少 50%
|
||||
W3-4 Phase 11 Store 重构 3 → 顺序 5 个子 Store + 协调层
|
||||
W5 Phase 12 性能优化 2 并行 消息虚拟化 + 批处理
|
||||
W6 Phase 13 测试覆盖 3 并行 80% 覆盖率 + CI 通过
|
||||
─────────────────────────────────────────────────────────────────
|
||||
完成 全部 Phase 9-13 文档更新 + 推送
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
*计划创建: 2026-03-15*
|
||||
*多代理并行执行: 3 代理同时工作*
|
||||
*预计完成: 6 周 (从 11 周优化 45%)*
|
||||
*每阶段完成后: 文档更新 + Git 推送*
|
||||
589
docs/archive/old-plans/splendid-orbiting-tarjan.md
Normal file
@@ -0,0 +1,589 @@
|
||||
# ZCLAW 项目深度分析与头脑风暴
|
||||
|
||||
## 一、项目全景概览
|
||||
|
||||
### 1.1 项目定位
|
||||
|
||||
ZCLAW 是一个**基于 ZCLAW 框架的定制化中文 AI 助手平台**,对标 AutoClaw (智谱) 和 QClaw (腾讯)。
|
||||
|
||||
**核心价值主张**:
|
||||
```
|
||||
ZCLAW Gateway (成熟执行引擎)
|
||||
↕ WebSocket Protocol v3
|
||||
ZCLAW Tauri App (轻量桌面 UI)
|
||||
+ 中文模型 Provider (GLM/Qwen/Kimi/MiniMax)
|
||||
+ 飞书 Channel Plugin
|
||||
+ 分身(Clone) 管理系统
|
||||
+ 自定义 Skills
|
||||
```
|
||||
|
||||
### 1.2 架构演进历程
|
||||
|
||||
| 阶段 | 架构方向 | 状态 |
|
||||
|------|----------|------|
|
||||
| v1 | 自建 AI Agent 框架 (src/core/*) | 🗑️ 已归档 |
|
||||
| v2 | 基于 ZCLAW + Tauri | ✅ 当前方向 |
|
||||
|
||||
**架构转向原因**:v1 偏离初衷约 75%,重复造轮子而非复用 ZCLAW 生态。
|
||||
|
||||
### 1.3 技术栈一览
|
||||
|
||||
| 层级 | 技术 | 版本 |
|
||||
|------|------|------|
|
||||
| 执行引擎 | ZCLAW Gateway | Node.js daemon |
|
||||
| 桌面壳 | Tauri | 2.0 |
|
||||
| 前端框架 | React | 19.1.0 |
|
||||
| 状态管理 | Zustand | 5.0.11 |
|
||||
| 样式 | TailwindCSS | 4.2.1 |
|
||||
| 构建工具 | Vite | 7.0.4 |
|
||||
| 语言 | TypeScript | 5.8.3 |
|
||||
| 通信协议 | WebSocket | Gateway Protocol v3 |
|
||||
|
||||
---
|
||||
|
||||
## 二、当前项目状态
|
||||
|
||||
### 2.1 已完成阶段
|
||||
|
||||
| Phase | 内容 | 完成度 |
|
||||
|-------|------|--------|
|
||||
| Phase 1 | 后端 Gateway 层 + 插件 + Skills | ✅ 100% |
|
||||
| Phase 2 | 前端 Settings 页面体系 (10页) | ✅ 100% |
|
||||
| Phase 3 | 聊天对接 + 分身管理 | ✅ 100% |
|
||||
| Phase 3.5 | 前端质量提升 | ✅ 100% |
|
||||
| Phase 4 | ZCLAW 真实集成测试 | ⏳ 待开始 |
|
||||
| Phase 5 | Tauri Rust sidecar + 打包发布 | 📋 规划中 |
|
||||
|
||||
### 2.2 代码统计
|
||||
|
||||
| 类别 | 文件数 | 说明 |
|
||||
|------|--------|------|
|
||||
| Gateway 层 | 3 | manager.ts, ws-client.ts, index.ts |
|
||||
| 插件 | 6 | 3 plugins × (index.ts + plugin.json) |
|
||||
| Skills | 2 | 2 × SKILL.md |
|
||||
| 配置 | 5 | 1 JSON + 4 MD |
|
||||
| 前端组件 | 15+ | 组件/Store/工具库 |
|
||||
| v1 遗留代码 | 37+ | src/core/* (已归档) |
|
||||
|
||||
### 2.3 编译状态
|
||||
|
||||
- TypeScript: **0 errors**
|
||||
- Vite build: **成功** (1766 modules, 268 KB JS + 26 KB CSS)
|
||||
|
||||
---
|
||||
|
||||
## 三、核心模块深度分析
|
||||
|
||||
### 3.1 ZCLAW Gateway 集成层 (src/gateway/)
|
||||
|
||||
#### manager.ts - 子进程管理器
|
||||
```
|
||||
功能: 管理 ZCLAW Gateway 子进程生命周期
|
||||
特性:
|
||||
- 启动/停止 Gateway daemon
|
||||
- 健康检查 (HTTP 探测)
|
||||
- 自动重启 (最多 5 次)
|
||||
- 连接外部已运行实例
|
||||
```
|
||||
|
||||
#### ws-client.ts - WebSocket 客户端
|
||||
```
|
||||
功能: 实现 ZCLAW Gateway Protocol v3
|
||||
特性:
|
||||
- 三步握手 (challenge → connect → hello-ok)
|
||||
- 请求/响应模式 (30秒超时)
|
||||
- 事件订阅 (agent/chat/presence/health/heartbeat)
|
||||
- 自动重连 (指数退避 1.5x, 最大 30s)
|
||||
```
|
||||
|
||||
### 3.2 自定义插件系统 (plugins/)
|
||||
|
||||
#### @zclaw/chinese-models - 中文模型 Provider
|
||||
| Provider | 模型 |
|
||||
|----------|------|
|
||||
| 智谱 GLM | glm-5, glm-4.7, glm-4-plus, glm-4-flash |
|
||||
| 通义千问 | qwen3.5-plus, qwen-max, qwen-vl-max |
|
||||
| Kimi | kimi-k2.5, moonshot-v1-128k |
|
||||
| MiniMax | minimax-m2.5, abab6.5s-chat |
|
||||
|
||||
**设计特点**: 全部使用 OpenAI 兼容 API 格式,支持自定义 Base URL。
|
||||
|
||||
#### @zclaw/feishu - 飞书 Channel Plugin
|
||||
```
|
||||
功能: 将飞书注册为 ZCLAW 消息渠道
|
||||
特性:
|
||||
- OAuth tenant_access_token 管理 (2h 有效期, 1.5h 刷新)
|
||||
- 文本/富文本消息发送
|
||||
- 多账户支持
|
||||
```
|
||||
|
||||
#### @zclaw/ui - UI 扩展 RPC
|
||||
| 方法 | 功能 |
|
||||
|------|------|
|
||||
| zclaw.clones.* | 分身 CRUD |
|
||||
| zclaw.stats.* | 用量/会话统计 |
|
||||
| zclaw.config.quick | 快速配置 |
|
||||
| zclaw.workspace.info | 工作区信息 |
|
||||
| zclaw.plugins.status | 插件状态 |
|
||||
|
||||
### 3.3 前端架构 (desktop/src/)
|
||||
|
||||
#### 三层布局
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ Sidebar (w-64) │ ChatArea (flex-1) │ RightPanel (w-72) │
|
||||
│ 左侧边栏 │ 中间对话区 │ 右侧边栏 │
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
#### 状态管理 (Zustand)
|
||||
- **chatStore**: 消息/对话/Agent/流式状态
|
||||
- **gatewayStore**: 连接/分身/统计/插件状态
|
||||
|
||||
#### 关键组件
|
||||
| 组件 | 职责 |
|
||||
|------|------|
|
||||
| ChatArea | 消息展示 + 流式输出 + Markdown渲染 + 模型选择 |
|
||||
| Sidebar | 四标签 (对话/分身/频道/任务) |
|
||||
| RightPanel | Gateway状态 + 会话统计 + 插件状态 |
|
||||
| Settings/* | 10个设置页面对标 AutoClaw |
|
||||
|
||||
### 3.4 v1 遗留代码 (已归档)
|
||||
|
||||
以下代码位于 `src/core/` 等目录,已从编译范围排除:
|
||||
|
||||
| 模块 | 状态 | 替代方案 |
|
||||
|------|------|----------|
|
||||
| remote-execution/ | 🗑️ | ZCLAW 工具执行 |
|
||||
| task-orchestration/ | 🗑️ | ZCLAW Agent Loop |
|
||||
| multi-agent/ | 🗑️ | ZCLAW agents.list |
|
||||
| memory/ | 🗑️ | ZCLAW Memory Plugin |
|
||||
| proactive/ | 🗑️ | ZCLAW Heartbeat Engine |
|
||||
| im/ | 🗑️ | ZCLAW Channel 系统 |
|
||||
| db/ | 🗑️ | ZCLAW 自带 SQLite |
|
||||
| config/ | 🗑️ | ZCLAW 配置系统 |
|
||||
| api/ | 🗑️ | WebSocket + Tauri Commands |
|
||||
|
||||
---
|
||||
|
||||
## 四、头脑风暴:机会与挑战
|
||||
|
||||
### 4.1 架构优势 💪
|
||||
|
||||
1. **复用成熟生态**
|
||||
- ZCLAW 28万+ Stars,工具执行/Skills/MCP/心跳引擎成熟
|
||||
- 避免重复造轮子,专注差异化价值
|
||||
|
||||
2. **Tauri 轻量化**
|
||||
- ~10MB vs Electron ~150MB
|
||||
- Rust native 性能优异
|
||||
- 系统级集成能力
|
||||
|
||||
3. **中文优先定位**
|
||||
- 4大中文模型原生支持
|
||||
- 飞书/微信/QQ 等 IM 渠道
|
||||
|
||||
4. **模块化插件设计**
|
||||
- Provider/Channel/RPC 插件独立开发
|
||||
- 可扩展性强
|
||||
|
||||
### 4.2 潜在风险 ⚠️
|
||||
|
||||
1. **ZCLAW 依赖**
|
||||
- 版本兼容性风险
|
||||
- 文档/社区支持限制
|
||||
|
||||
2. **v1 遗留代码清理**
|
||||
- 37+ 文件需要决策 (保留/删除/重构)
|
||||
- 可能存在可复用的代码片段
|
||||
|
||||
3. **Tauri 后端功能有限**
|
||||
- 当前 Rust 代码几乎为空
|
||||
- 需要实现 sidecar/文件系统/通知等
|
||||
|
||||
4. **测试覆盖不足**
|
||||
- 未见测试文件
|
||||
- 集成测试缺失
|
||||
|
||||
### 4.3 创新机会 💡
|
||||
|
||||
#### A. 分身系统增强
|
||||
```
|
||||
当前: 基础 CRUD
|
||||
增强方向:
|
||||
- 分身间协作 (多 Agent 编排)
|
||||
- 分身记忆隔离/共享
|
||||
- 分身能力画像 (擅长领域)
|
||||
- 分身市场 (社区分享)
|
||||
```
|
||||
|
||||
#### B. Skills 生态扩展
|
||||
```
|
||||
当前: 2 个基础 Skills
|
||||
扩展方向:
|
||||
- 社媒运营套件 (微博/小红书/抖音)
|
||||
- 学术研究助手 (论文/文献/翻译)
|
||||
- 代码审查专家 (PR Review/安全审计)
|
||||
- 数据分析专家 (SQL/报表/可视化)
|
||||
```
|
||||
|
||||
#### C. IM 渠道深化
|
||||
```
|
||||
当前: 飞书基础支持
|
||||
深化方向:
|
||||
- 微信企业号 (WeCom API)
|
||||
- QQ 机器人 (NapCat/Go-CQHTTP)
|
||||
- 钉钉/飞书/企业微信三合一
|
||||
- 消息路由规则 (关键词/时间/来源)
|
||||
```
|
||||
|
||||
#### D. 工作区智能化
|
||||
```
|
||||
当前: 基础目录配置
|
||||
智能方向:
|
||||
- 项目上下文感知 (package.json/README 解析)
|
||||
- 代码库索引 (LSP 集成)
|
||||
- 文件变更监听 (自动同步理解)
|
||||
- 多工作区切换
|
||||
```
|
||||
|
||||
#### E. 数据分析增强
|
||||
```
|
||||
当前: 基础用量统计
|
||||
增强方向:
|
||||
- 对话质量分析 (满意度/解决率)
|
||||
- Token 成本优化建议
|
||||
- 使用模式洞察 (高峰时段/常用功能)
|
||||
- 导出报告 (PDF/Excel)
|
||||
```
|
||||
|
||||
### 4.4 技术改进建议 🔧
|
||||
|
||||
#### 短期 (1-2周)
|
||||
1. **完成 Phase 4 集成测试**
|
||||
- 安装并验证 ZCLAW
|
||||
- 测试 Gateway 连接
|
||||
- 验证插件注册
|
||||
- 端到端消息收发测试
|
||||
|
||||
2. **清理 v1 遗留代码**
|
||||
- 评估每模块的可复用性
|
||||
- 删除确定无用的代码
|
||||
- 保留有价值的工具函数
|
||||
|
||||
3. **补充基础测试**
|
||||
- Gateway 协议单元测试
|
||||
- 前端组件测试
|
||||
- E2E 关键流程测试
|
||||
|
||||
#### 中期 (1-2月)
|
||||
1. **Tauri Rust 后端扩展**
|
||||
- Gateway sidecar 管理
|
||||
- 系统托盘集成
|
||||
- 原生通知
|
||||
- 文件系统访问
|
||||
|
||||
2. **微信/QQ Channel Plugin**
|
||||
- 调研 NapCat/Go-CQHTTP
|
||||
- 实现 Channel Plugin 接口
|
||||
|
||||
3. **Skills 扩展**
|
||||
- 社媒运营套件
|
||||
- 代码审查助手
|
||||
|
||||
#### 长期 (3-6月)
|
||||
1. **多 Agent 协作可视化**
|
||||
- 任务依赖图
|
||||
- 执行进度追踪
|
||||
- 结果聚合展示
|
||||
|
||||
2. **插件市场**
|
||||
- 插件发现/安装/更新
|
||||
- 社区贡献机制
|
||||
|
||||
3. **移动端伴侣 App**
|
||||
- Flutter/React Native
|
||||
- 与桌面端数据同步
|
||||
|
||||
---
|
||||
|
||||
## 五、竞品对标分析
|
||||
|
||||
| 维度 | AutoClaw (智谱) | QClaw (腾讯) | ZCLAW |
|
||||
|------|----------------|--------------|-------|
|
||||
| 基础框架 | ZCLAW | ZCLAW | ZCLAW |
|
||||
| IM 渠道 | 飞书 | 微信+QQ | 飞书 (计划微信/QQ) |
|
||||
| 桌面框架 | 自研 | Electron | Tauri 2.0 |
|
||||
| 模型支持 | GLM 系列 | 腾讯混元 | GLM/Qwen/Kimi/MiniMax |
|
||||
| 安装包大小 | 未知 | ~150MB | ~10MB (目标) |
|
||||
| 开源状态 | 未开源 | 未开源 | MIT 开源 |
|
||||
|
||||
**差异化优势**:
|
||||
- 🦀 Tauri 轻量化
|
||||
- 🌐 多中文模型支持
|
||||
- 🔓 开源可定制
|
||||
- 🧩 插件生态开放
|
||||
|
||||
---
|
||||
|
||||
## 六、下一步行动计划
|
||||
|
||||
### Phase 4: 真实集成测试 (当前优先级)
|
||||
|
||||
```
|
||||
[ ] 1. 安装 ZCLAW
|
||||
- Windows: iwr -useb https://zclaw.ai/install.ps1 | iex
|
||||
- 验证: zclaw --version
|
||||
|
||||
[ ] 2. 配置 Gateway
|
||||
- 运行 zclaw configure
|
||||
- 填入 API Key (智谱/通义/Kimi 任选)
|
||||
|
||||
[ ] 3. 启动 Gateway
|
||||
- zclaw gateway
|
||||
- 验证: curl http://127.0.0.1:18789/health
|
||||
|
||||
[ ] 4. 注册 ZCLAW 插件
|
||||
- pnpm setup
|
||||
- 验证插件加载
|
||||
|
||||
[ ] 5. 前端连接测试
|
||||
- cd desktop && pnpm tauri dev
|
||||
- 验证 WebSocket 连接
|
||||
- 测试消息收发
|
||||
|
||||
[ ] 6. 飞书 Channel 测试
|
||||
- 配置飞书应用凭证
|
||||
- 测试消息收发
|
||||
```
|
||||
|
||||
### Phase 5: 打包发布准备
|
||||
|
||||
```
|
||||
[ ] Tauri Rust sidecar 实现
|
||||
[ ] 安装包测试 (Windows/macOS/Linux)
|
||||
[ ] 自动更新机制
|
||||
[ ] 文档完善
|
||||
[ ] 发布 v0.1.0
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 七、总结
|
||||
|
||||
ZCLAW 是一个定位清晰的 ZCLAW 定制化项目,通过复用成熟生态 + Tauri 轻量桌面 + 中文优先策略,有望成为开源领域的 AutoClaw/QClaw 替代方案。
|
||||
|
||||
**核心建议**:
|
||||
1. 🎯 聚焦 Phase 4 集成测试,打通端到端流程
|
||||
2. 🧹 清理 v1 遗留代码,减少维护负担
|
||||
3. ✅ 补充测试覆盖,提升代码质量
|
||||
4. 🚀 迭代发布,快速验证市场反馈
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
## 八、执行路线图 (用户选择)
|
||||
|
||||
基于用户反馈,将并行推进以下四个方向:
|
||||
|
||||
### 8.1 Phase 4: 真实集成测试 🔌
|
||||
|
||||
**目标**: 打通 ZCLAW Gateway ↔ ZCLAW Tauri 端到端流程
|
||||
|
||||
**任务清单**:
|
||||
```
|
||||
[ ] 安装 ZCLAW CLI
|
||||
- Windows: iwr -useb https://zclaw.ai/install.ps1 | iex
|
||||
- 验证: zclaw --version
|
||||
|
||||
[ ] 配置 Gateway
|
||||
- 运行 zclaw configure
|
||||
- 配置 API Key (智谱 GLM 作为首选)
|
||||
|
||||
[ ] 启动 Gateway daemon
|
||||
- zclaw gateway --port 18789
|
||||
- 验证: curl http://127.0.0.1:18789/health
|
||||
|
||||
[ ] 注册 ZCLAW 插件
|
||||
- pnpm setup (执行 scripts/setup.ts)
|
||||
- 验证插件加载: zclaw plugins list
|
||||
|
||||
[ ] 前端连接测试
|
||||
- cd desktop && pnpm tauri dev
|
||||
- 验证 WebSocket 连接成功
|
||||
- 测试消息发送和流式接收
|
||||
|
||||
[ ] 飞书 Channel 测试 (可选)
|
||||
- 配置飞书应用凭证
|
||||
- 测试飞书消息收发
|
||||
```
|
||||
|
||||
**验收标准**:
|
||||
- ✅ Gateway 启动成功,健康检查通过
|
||||
- ✅ 前端显示"已连接"状态
|
||||
- ✅ 发送消息能收到 AI 流式回复
|
||||
- ✅ 模型切换功能正常
|
||||
|
||||
### 8.2 清理 v1 遗留代码 🧹
|
||||
|
||||
**目标**: 评估并处理 src/core/ 等 37+ 个归档文件
|
||||
|
||||
**待处理目录**:
|
||||
| 目录 | 文件数 | 建议操作 |
|
||||
|------|--------|----------|
|
||||
| src/core/remote-execution/ | ~4 | 🗑️ 删除 (ZCLAW 替代) |
|
||||
| src/core/task-orchestration/ | ~3 | 🗑️ 删除 (ZCLAW 替代) |
|
||||
| src/core/multi-agent/ | ~8 | 🗑️ 删除 (ZCLAW 替代) |
|
||||
| src/core/memory/ | ~2 | 🗑️ 删除 (ZCLAW 替代) |
|
||||
| src/core/proactive/ | ~2 | 🗑️ 删除 (ZCLAW 替代) |
|
||||
| src/core/ai/ | ~6 | ⚠️ 评估 (可能复用 Provider) |
|
||||
| src/im/ | ~4 | 🗑️ 删除 (ZCLAW 替代) |
|
||||
| src/db/ | ~3 | 🗑️ 删除 (ZCLAW 替代) |
|
||||
| src/config/ | ~2 | 🗑️ 删除 (ZCLAW 替代) |
|
||||
| src/api/ | ~1 | 🗑️ 删除 (WebSocket 替代) |
|
||||
| src/app.ts | 1 | 🗑️ 删除 |
|
||||
| src/index.ts | 1 | 🔄 重写为简单入口 |
|
||||
|
||||
**任务清单**:
|
||||
```
|
||||
[ ] 创建 archive/v1-backup 分支保存当前状态
|
||||
[ ] 评估 src/core/ai/ 的可复用性
|
||||
- providers/zhipu.ts 可能对插件开发有参考价值
|
||||
- manager.ts 的 fallback 逻辑可借鉴
|
||||
[ ] 删除确认无用的目录
|
||||
[ ] 重写 src/index.ts 为最小化入口
|
||||
[ ] 更新 tsconfig.json 移除对旧代码的引用
|
||||
[ ] 验证编译: pnpm build (0 errors)
|
||||
```
|
||||
|
||||
**验收标准**:
|
||||
- ✅ v1 代码已备份到独立分支
|
||||
- ✅ 主分支代码精简,无死代码
|
||||
- ✅ TypeScript 编译 0 errors
|
||||
- ✅ 项目结构清晰,符合 v2 架构
|
||||
|
||||
### 8.3 补充测试覆盖 ✅
|
||||
|
||||
**目标**: 建立基础测试框架,覆盖关键模块
|
||||
|
||||
**测试分层**:
|
||||
```
|
||||
tests/
|
||||
├── unit/ # 单元测试
|
||||
│ ├── gateway/
|
||||
│ │ ├── manager.test.ts # 子进程管理
|
||||
│ │ └── ws-client.test.ts # WebSocket 客户端
|
||||
│ └── utils/
|
||||
│ ├── logger.test.ts
|
||||
│ └── id.test.ts
|
||||
├── integration/ # 集成测试
|
||||
│ ├── gateway-protocol.test.ts # Gateway 协议
|
||||
│ └── plugin-loading.test.ts # 插件加载
|
||||
└── e2e/ # 端到端测试
|
||||
└── chat-flow.test.ts # 完整对话流程
|
||||
```
|
||||
|
||||
**任务清单**:
|
||||
```
|
||||
[ ] 配置测试框架
|
||||
- 安装 Vitest + @testing-library/react
|
||||
- 配置 vitest.config.ts
|
||||
|
||||
[ ] Gateway 层单元测试
|
||||
- ws-client.ts: 握手流程、重连逻辑
|
||||
- manager.ts: 进程管理、健康检查
|
||||
|
||||
[ ] 前端组件测试
|
||||
- chatStore: 消息发送、流式处理
|
||||
- gatewayStore: 连接状态管理
|
||||
- ChatArea: 消息渲染、输入处理
|
||||
|
||||
[ ] 集成测试
|
||||
- Gateway Protocol v3 完整握手
|
||||
- 插件注册和 RPC 调用
|
||||
|
||||
[ ] CI 集成
|
||||
- GitHub Actions 自动运行测试
|
||||
- 覆盖率报告
|
||||
```
|
||||
|
||||
**验收标准**:
|
||||
- ✅ 测试框架配置完成
|
||||
- ✅ 核心模块测试覆盖率 > 60%
|
||||
- ✅ CI 流水线运行成功
|
||||
|
||||
### 8.4 扩展 Skills/插件 🧩
|
||||
|
||||
**目标**: 丰富 Skills 生态,增加 IM 渠道支持
|
||||
|
||||
**Skills 扩展计划**:
|
||||
|
||||
| Skill | 触发词 | 功能 |
|
||||
|-------|--------|------|
|
||||
| social-media | 发微博/小红书/抖音 | 社媒内容创作和发布 |
|
||||
| code-review | 审查代码/PR Review | 代码质量分析和建议 |
|
||||
| data-analysis | 分析数据/生成报表 | SQL 查询和可视化 |
|
||||
| translation | 翻译/中译英 | 多语言翻译 |
|
||||
|
||||
**插件扩展计划**:
|
||||
|
||||
| 插件 | 类型 | 优先级 |
|
||||
|------|------|--------|
|
||||
| @zclaw/wechat | Channel | 高 |
|
||||
| @zclaw/qq | Channel | 高 |
|
||||
| @zclaw/terminal | Tool | 中 |
|
||||
| @zclaw/advanced-memory | Memory | 中 |
|
||||
|
||||
**任务清单**:
|
||||
```
|
||||
[ ] Skills 开发
|
||||
- 创建 skills/social-media/SKILL.md
|
||||
- 创建 skills/code-review/SKILL.md
|
||||
- 创建 skills/data-analysis/SKILL.md
|
||||
- 创建 skills/translation/SKILL.md
|
||||
|
||||
[ ] 微信 Channel Plugin 调研
|
||||
- 评估 WeCom API 可行性
|
||||
- 评估 NapCat/Go-CQHTTP 桥接方案
|
||||
- 输出技术方案文档
|
||||
|
||||
[ ] QQ Channel Plugin 调研
|
||||
- 评估 NapCatQQ 方案
|
||||
- 输出技术方案文档
|
||||
|
||||
[ ] 插件开发 (选一个优先)
|
||||
- 实现微信或 QQ Channel Plugin
|
||||
```
|
||||
|
||||
**验收标准**:
|
||||
- ✅ 至少 2 个新 Skills 可用
|
||||
- ✅ 微信/QQ 技术方案文档完成
|
||||
- ✅ 至少 1 个新 Channel Plugin 可测试
|
||||
|
||||
---
|
||||
|
||||
## 九、执行优先级排序
|
||||
|
||||
基于依赖关系和价值,建议执行顺序:
|
||||
|
||||
```
|
||||
第 1 周: Phase 4 集成测试 + v1 代码清理
|
||||
└─ 这两项可以并行,互不依赖
|
||||
|
||||
第 2 周: 补充测试覆盖
|
||||
└─ 在集成测试通过后补充自动化测试
|
||||
|
||||
第 3-4 周: Skills/插件扩展
|
||||
└─ 在稳定基础上扩展功能
|
||||
```
|
||||
|
||||
**里程碑**:
|
||||
- 🏁 Week 1 结束: 端到端流程打通 + 代码库精简
|
||||
- 🏁 Week 2 结束: 测试覆盖率 > 60%
|
||||
- 🏁 Week 4 结束: 4+ 新 Skills + 1 新 Channel Plugin
|
||||
|
||||
---
|
||||
|
||||
*分析完成于 2026-03-12*
|
||||
*执行计划更新于 2026-03-12*
|
||||
243
docs/archive/old-plans/typed-dazzling-fog.md
Normal file
@@ -0,0 +1,243 @@
|
||||
# ZCLAW 系统偏离分析与演化路线图更新方案
|
||||
|
||||
**分析日期**: 2026-03-15
|
||||
**目的**: 基于代码层面深度分析,更新系统偏离点,制定下一阶段演化路线
|
||||
**状态**: ✅ **全部完成**
|
||||
|
||||
---
|
||||
|
||||
## 一、背景与上下文
|
||||
|
||||
### 1.1 为什么需要这次分析?
|
||||
|
||||
现有的 [SYSTEM_ANALYSIS.md](docs/SYSTEM_ANALYSIS.md) 记录了 Phase 1-5 的完成状态和 Phase 6 的进行中状态。但代码层面的深度分析发现了新的偏离点,特别是:
|
||||
|
||||
1. **Team 协作功能** - 文档标记为"进行中",但代码显示 `teamStore.ts` 完全使用 localStorage 而非真实 API
|
||||
2. **REST API 认证缺失** - WebSocket 有完整认证,REST 请求无认证头
|
||||
3. **设置持久化问题** - 主题/自动启动等设置仅改变本地状态
|
||||
4. **编辑模式不完整** - WorkflowEditor 编辑时不加载现有步骤
|
||||
|
||||
### 1.2 分析方法
|
||||
|
||||
使用 3 个并行 Explore 代理深度分析:
|
||||
- 前端组件和 UI 状态管理
|
||||
- ZCLAW 通信层实现
|
||||
- 配置和技能系统
|
||||
|
||||
### 1.3 实施方法
|
||||
|
||||
使用多代理并行执行:
|
||||
- 14 个专业代理并行工作
|
||||
- TypeScript + Rust 双重验证
|
||||
- 所有修改通过 `pnpm tsc --noEmit` 和 `cargo check`
|
||||
|
||||
---
|
||||
|
||||
## 二、新发现的偏离点
|
||||
|
||||
### 2.1 关键数据流断裂 (P0 - 最高优先级)
|
||||
|
||||
| ID | 组件 | 问题描述 | 影响 |
|
||||
|----|------|----------|------|
|
||||
| **A1** | [teamStore.ts](desktop/src/store/teamStore.ts) | 所有 CRUD 操作使用 localStorage,从未调用 [team-client.ts](desktop/src/lib/team-client.ts) API | Team 协作功能完全虚假 |
|
||||
| **A2** | [WorkflowEditor.tsx:217](desktop/src/components/WorkflowEditor.tsx#L217) | 编辑模式初始化空步骤,不加载现有工作流 | 无法编辑真实工作流 |
|
||||
| **A3** | [SchedulerPanel.tsx:649](desktop/src/components/SchedulerPanel.tsx#L649) | 事件触发器创建显示占位 alert | 无法创建事件触发器 |
|
||||
|
||||
### 2.2 安全与配置偏离 (P0-P1)
|
||||
|
||||
| ID | 组件 | 问题描述 | 影响 |
|
||||
|----|------|----------|------|
|
||||
| **B1** | [gateway-client.ts](desktop/src/lib/gateway-client.ts) | REST API 请求不携带认证头 | 未认证的 REST 调用 |
|
||||
| **B2** | [gateway-client.ts](desktop/src/lib/gateway-client.ts) | Token 存储在 localStorage | 敏感数据不安全存储 |
|
||||
| **B3** | [General.tsx:9-11](desktop/src/components/Settings/General.tsx#L9-L11) | 主题/自动启动仅改变本地 state | 设置不持久化到 TOML |
|
||||
|
||||
### 2.3 端口与文档偏离
|
||||
|
||||
| 来源 | 端口 | 状态 |
|
||||
|------|------|------|
|
||||
| **实际 ZCLAW** | 50051 | 代码正确适配 |
|
||||
| **文档** | 4200 | 需更新 |
|
||||
| **FALLBACK_GATEWAY_URLS** | 50051, 4200 | 回退列表包含两个 |
|
||||
|
||||
---
|
||||
|
||||
## 三、演化路线图 (更新版) - ✅ 全部完成
|
||||
|
||||
### Phase 0: 稳定化修复 ✅ 完成
|
||||
|
||||
**目标**: 修复关键数据流断裂问题
|
||||
|
||||
| 任务 | 状态 | 文件 |
|
||||
|------|------|------|
|
||||
| Team Store API 集成 | ✅ 完成 | `teamStore.ts` - 替换 localStorage 为 API |
|
||||
| REST API 认证 | ✅ 完成 | `team-client.ts` - 添加 `getAuthHeaders()` |
|
||||
| Workflow 编辑器步骤加载 | ✅ 完成 | `WorkflowEditor.tsx` - 编辑模式加载步骤 |
|
||||
|
||||
### Phase 1: 功能对齐 ✅ 完成
|
||||
|
||||
**目标**: 连接所有 UI 组件到真实 ZCLAW 能力
|
||||
|
||||
| 任务 | 状态 | 文件 |
|
||||
|------|------|------|
|
||||
| 事件触发器创建 | ✅ 完成 | `CreateTriggerModal.tsx` (新建) |
|
||||
| 设置持久化 | ✅ 完成 | `General.tsx` - 连接 gatewayStore |
|
||||
| WebSocket 团队事件订阅 | ✅ 完成 | `useTeamEvents.ts`, `teamStore.ts` |
|
||||
| 安全 Token 存储 | ✅ 完成 | `secure_storage.rs` (新建), `secure-storage.ts` (新建) |
|
||||
|
||||
### Phase 2: 架构优化 ✅ 完成
|
||||
|
||||
**目标**: 改善系统架构以提高可维护性和性能
|
||||
|
||||
| 任务 | 状态 | 文件 |
|
||||
|------|------|------|
|
||||
| TOML 配置支持 | ✅ 完成 | `toml-utils.ts`, `config-parser.ts`, `types/config.ts` |
|
||||
| 请求超时和重试 | ✅ 完成 | `request-helper.ts` (新建) |
|
||||
|
||||
### Phase 3: 扩展和增强 ✅ 完成
|
||||
|
||||
**目标**: 完善 ZCLAW 特有功能的 UI
|
||||
|
||||
| 任务 | 状态 | 文件 |
|
||||
|------|------|------|
|
||||
| 16 层安全状态 UI | ✅ 完成 | `SecurityLayersPanel.tsx` (新建) |
|
||||
| Hand 审批工作流 | ✅ 完成 | `HandApprovalModal.tsx`, `ApprovalsPanel.tsx` |
|
||||
| 增强 Hand 参数 UI | ✅ 完成 | `HandParamsForm.tsx` (新建) |
|
||||
| 审计日志查看器 | ✅ 完成 | `AuditLogsPanel.tsx` - Merkle 链验证
|
||||
|
||||
---
|
||||
|
||||
## 四、风险评估
|
||||
|
||||
### 高风险变更
|
||||
|
||||
| 变更 | 风险 | 缓解措施 |
|
||||
|------|------|----------|
|
||||
| Team Store API 集成 | API 失败导致数据丢失 | Feature flag 回退到 localStorage |
|
||||
| 安全 Token 存储 | 认证中断 | 渐进迁移带回退 |
|
||||
| TOML 解析器 | 配置损坏 | 写入前验证,保留备份 |
|
||||
|
||||
### 中等风险变更
|
||||
|
||||
| 变更 | 风险 | 缓解措施 |
|
||||
|------|------|----------|
|
||||
| REST 认证头 | 401 循环 | 智能重试带用户提示 |
|
||||
| 配置同步 | 竞态条件 | 乐观锁,冲突 UI |
|
||||
| 后端抽象 | 功能缺口 | 能力检测,优雅降级 |
|
||||
|
||||
---
|
||||
|
||||
## 五、成功度量
|
||||
|
||||
### Phase 0 完成标准
|
||||
- [ ] Team CRUD 操作使用真实 API (通过网络请求验证)
|
||||
- [ ] 所有 REST 请求包含认证头
|
||||
- [ ] Workflow 编辑模式加载现有步骤
|
||||
- [ ] Team 数据不再使用 localStorage (除缓存)
|
||||
|
||||
### Phase 1 完成标准
|
||||
- [ ] 事件触发器可创建并正确触发
|
||||
- [ ] 设置在应用重启后持久化
|
||||
- [ ] 实时团队事件更新 UI
|
||||
- [ ] Token 存储在安全存储中
|
||||
|
||||
### Phase 2 完成标准
|
||||
- [ ] TOML 配置可读写
|
||||
- [ ] 请求重试在瞬态故障时成功
|
||||
- [ ] 后端可通过配置切换
|
||||
- [ ] 配置变更双向同步
|
||||
|
||||
### Phase 3 完成标准
|
||||
- [ ] 所有 16 层安全有 UI 展示
|
||||
- [ ] Hand 审批工作流可用
|
||||
- [ ] Hand 参数支持所有类型
|
||||
- [ ] 审计日志可验证
|
||||
|
||||
### 总体指标
|
||||
|
||||
| 指标 | 当前 | 目标 |
|
||||
|------|------|------|
|
||||
| localStorage 使用 | 3 个文件 | 0 (除缓存) |
|
||||
| API 集成 | ~70% | 100% |
|
||||
| 实时事件 | 30% | 100% |
|
||||
| 安全 UI 覆盖 | 20% | 100% |
|
||||
| 测试覆盖率 | 未知 | 80%+ |
|
||||
|
||||
---
|
||||
|
||||
## 六、实施顺序
|
||||
|
||||
```
|
||||
第 1-2 周: Phase 0
|
||||
├── 0.1 Team Store API 集成 (3 天)
|
||||
├── 0.2 REST API 认证 (2 天)
|
||||
└── 0.3 Workflow 编辑器步骤加载 (2 天)
|
||||
|
||||
第 3-5 周: Phase 1
|
||||
├── 1.1 事件触发器创建 (3 天)
|
||||
├── 1.2 设置持久化 (2 天)
|
||||
├── 1.3 WebSocket 事件订阅 (3 天)
|
||||
└── 1.4 安全 Token 存储 (2 天)
|
||||
|
||||
第 6-8 周: Phase 2
|
||||
├── 2.1 TOML 配置支持 (3 天)
|
||||
├── 2.2 请求超时和重试 (2 天)
|
||||
├── 2.3 后端抽象层 (3 天)
|
||||
└── 2.4 配置同步服务 (2 天)
|
||||
|
||||
第 9-12 周: Phase 3
|
||||
├── 3.1 16 层安全状态 UI (4 天)
|
||||
├── 3.2 Hand 审批工作流 (3 天)
|
||||
├── 3.3 增强 Hand 参数 UI (2 天)
|
||||
└── 3.4 审计日志查看器 (3 天)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 七、关键文件清单
|
||||
|
||||
### 需要修改的核心文件
|
||||
|
||||
| 文件 | 修改类型 | 优先级 |
|
||||
|------|----------|--------|
|
||||
| [desktop/src/store/teamStore.ts](desktop/src/store/teamStore.ts) | 替换 localStorage 为 API 调用 | P0 |
|
||||
| [desktop/src/lib/team-client.ts](desktop/src/lib/team-client.ts) | 添加认证头和错误处理 | P0 |
|
||||
| [desktop/src/lib/gateway-client.ts](desktop/src/lib/gateway-client.ts) | REST 认证模式参考 | P0 |
|
||||
| [desktop/src/components/WorkflowEditor.tsx](desktop/src/components/WorkflowEditor.tsx) | 添加步骤加载 | P0 |
|
||||
| [desktop/src/components/Settings/General.tsx](desktop/src/components/Settings/General.tsx) | 设置持久化 | P1 |
|
||||
|
||||
### 需要新建的文件
|
||||
|
||||
| 文件 | 用途 | 阶段 |
|
||||
|------|------|------|
|
||||
| `desktop/src/lib/config-client.ts` | 配置 API 客户端 | Phase 1 |
|
||||
| `desktop/src/lib/toml-parser.ts` | TOML 解析工具 | Phase 2 |
|
||||
| `desktop/src-tauri/src/secure_storage.rs` | 安全存储 Rust 命令 | Phase 1 |
|
||||
| `desktop/src/components/CreateTriggerModal.tsx` | 触发器创建模态框 | Phase 1 |
|
||||
|
||||
---
|
||||
|
||||
## 八、验证方法
|
||||
|
||||
### 每个 Phase 完成后的验证
|
||||
|
||||
1. **自动化测试**
|
||||
```bash
|
||||
pnpm vitest run tests/desktop/
|
||||
pnpm tsc --noEmit
|
||||
```
|
||||
|
||||
2. **手动验证**
|
||||
- 连接 ZCLAW (端口 50051)
|
||||
- 验证数据流真实连接
|
||||
- 检查 localStorage 使用情况
|
||||
- 验证设置持久化
|
||||
|
||||
3. **代码审查**
|
||||
- 检查认证头存在
|
||||
- 验证错误处理完整
|
||||
- 确认无硬编码值
|
||||
|
||||
---
|
||||
|
||||
*计划创建: 2026-03-15*
|
||||
*预计完成: 2026-06-15 (12 周)*
|
||||
242
docs/archive/old-test-reports/DEEP_TEST_REPORT.md
Normal file
@@ -0,0 +1,242 @@
|
||||
# ZCLAW 深度功能测试报告
|
||||
|
||||
**测试日期:** 2026-03-15
|
||||
**测试类型:** 端到端深度功能测试
|
||||
**测试环境:** Windows 11, Chrome DevTools MCP, localhost:1420
|
||||
**测试人员:** Claude (AI Agent)
|
||||
|
||||
---
|
||||
|
||||
## 执行摘要
|
||||
|
||||
本次测试从真实用户角度出发,对 ZCLAW 系统进行了深度功能验证。 不仅仅检查"页面能否打开",而是验证功能的**完整性和可用性** 包括多轮对话、 工具调用、 Gateway 连接稳定性等关键场景。
|
||||
|
||||
---
|
||||
|
||||
## 一、功能完整性测试
|
||||
|
||||
### 1.1 多轮对话测试 ✅
|
||||
|
||||
**测试步骤:**
|
||||
1. 在输入框输入: "请帮我写一个 Python 函数来计算斐波那契数列的前n项"
|
||||
2. 点击发送按钮
|
||||
3. 綈息成功发送, Agent 流式返回 Python 代码
|
||||
4. 继续输入: "请解释一下这个函数的时间复杂度是多少?并优化它"
|
||||
5. Agent 正确理解上下文, 并回答关于时间复杂度的问题
|
||||
提供了优化版本的代码
|
||||
|
||||
**测试结果:** ✅ **通过**
|
||||
|
||||
**验证点:**
|
||||
- 消息发送成功率: 100%
|
||||
- 流式回复正常: 是
|
||||
- 上下文保持正确: 是
|
||||
- Agent 记住之前的对话内容: 是
|
||||
- 统计数据正确更新: 用户消息 2, 助手回复 2, 总消息数 4
|
||||
|
||||
---
|
||||
|
||||
### 1.2 右侧面板测试
|
||||
|
||||
#### Status 标签页 ✅
|
||||
- 显示 Gateway 连接状态
|
||||
- 显示当前模型
|
||||
- 显示会话统计(用户消息、 助手回复、 工具调用、 总消息数)
|
||||
- 实时更新正常
|
||||
|
||||
#### Files 标签页 ✅
|
||||
- 切换正常
|
||||
- 显示"对话输出文件" 区域
|
||||
- 显示"代码片段" 区域
|
||||
- 当前无文件是因为未调用工具
|
||||
|
||||
#### Agent 标签页 ✅
|
||||
- 显示完整的 Agent 配置信息:
|
||||
- 包含: Role, Nickname, Model, Emoji, 用户信息, Focus, Workspace, File Restriction, Opt-in, Bootstrap Files
|
||||
- 所有字段正确显示
|
||||
|
||||
---
|
||||
|
||||
### 1.3 Hands 能力包测试 ✅
|
||||
- 列表显示 8 个能力包
|
||||
- 状态显示正确(就绪/需配置)
|
||||
- 工具数量显示正确
|
||||
- 点击后详情页正常显示
|
||||
|
||||
---
|
||||
|
||||
### 1.4 Settings 设置页面测试 ✅
|
||||
- 16 个设置页面全部可访问
|
||||
- 导航正常工作
|
||||
- 页面内容正确显示
|
||||
|
||||
---
|
||||
|
||||
## 二、发现的问题
|
||||
|
||||
### 2.1 🔴 严重问题: Gateway 连接不稳定
|
||||
|
||||
**问题描述:**
|
||||
- 在测试过程中 Gateway 断开连接
|
||||
- 点击 "Connect Gateway" 按钮后 10 秒内未能重新连接
|
||||
- 显示 "Gateway Disconnected"
|
||||
- 输入框显示 "请先连接 Gateway"
|
||||
|
||||
**影响范围:** 严重
|
||||
- 无法发送新消息
|
||||
- 无法执行工具调用
|
||||
- Hands/Workflow 功能无法使用
|
||||
|
||||
- 分身管理功能无法使用
|
||||
|
||||
**复现步骤:**
|
||||
1. 启动应用并连接 Gateway
|
||||
2. 进行几轮对话
|
||||
3. 观察右侧面板连接状态变化为 "Disconnected"
|
||||
4. 点击 "Connect Gateway" 尝试重连
|
||||
5. 等待 10 秒后连接仍未恢复
|
||||
|
||||
**建议修复:**
|
||||
1. 添加自动重连机制
|
||||
2. 优化 WebSocket 心跳检测
|
||||
3. 增加连接状态监控和自动恢复
|
||||
4. 提供更清晰的错误提示
|
||||
|
||||
---
|
||||
|
||||
### 2.2 🟡 中等问题: 工具调用无法执行
|
||||
**问题描述:**
|
||||
- 由于 Gateway 断开, 无法测试实际的工具调用功能
|
||||
- Files 标签页显示 "No Output Files" 和 "No code snippets"
|
||||
|
||||
**影响范围:** 中等
|
||||
- 无法验证 write_file, read_file 等核心工具
|
||||
- 无法测试 Agent 的实际执行能力
|
||||
- 代码生成功能无法写入文件
|
||||
|
||||
**建议修复:**
|
||||
- 先修复 Gateway 连接问题
|
||||
- 添加离线模式支持
|
||||
|
||||
---
|
||||
|
||||
### 2.3 🟡 中等问题: 分身创建 400 错误
|
||||
**问题描述:**
|
||||
- POST /api/agents 返回 400 Bad Request
|
||||
- 无法创建新的 Agent 分身
|
||||
- 表单数据格式可能有问题
|
||||
|
||||
**API 请求示例:**
|
||||
```json
|
||||
{
|
||||
"name": "测试助手",
|
||||
"role": "代码助手",
|
||||
"nickname": "开发者",
|
||||
"scenarios": ["编程", "调试"],
|
||||
"workspaceDir": "~/.zclaw/zclaw-workspace",
|
||||
"userName": "测试用户",
|
||||
"restrictFiles": true,
|
||||
"privacyOptIn": false
|
||||
}
|
||||
```
|
||||
|
||||
**建议修复:**
|
||||
- 检查后端 API 参数验证
|
||||
- 确认必填字段列表
|
||||
- 添加更详细的错误信息
|
||||
|
||||
---
|
||||
|
||||
### 2.4 🟡 中等问题: Create Team 按钮无响应
|
||||
**问题描述:**
|
||||
- 在 Team 页面点击 "Create Team" 按钮
|
||||
- 没有弹出创建表单或模态框
|
||||
- 按钮点击后页面无任何变化
|
||||
|
||||
**建议修复:**
|
||||
- 棣查按钮的事件绑定
|
||||
- 确认模态框组件是否正确加载
|
||||
|
||||
---
|
||||
|
||||
### 2.5 🟢 轻微问题: Skills 组件 key 警告
|
||||
**问题描述:**
|
||||
- 控制台显示: "Each child in a list should have a unique 'key' prop"
|
||||
- 这是 React 渲染警告
|
||||
|
||||
**建议修复:**
|
||||
- 在 Skills 组件中为列表项添加 key 属性
|
||||
|
||||
---
|
||||
|
||||
### 2.6 🟢 轻微问题: 6个 API 端点 404 错误
|
||||
**受影响的端点:**
|
||||
- `/api/stats/usage` - 用量统计
|
||||
- `/api/plugins/status` - 插件状态
|
||||
- `/api/scheduler/tasks` - 调度任务
|
||||
- `/api/security/status` - 安全状态
|
||||
- `/api/workspace` - 工作区信息
|
||||
- `/api/config/quick` - 快速配置
|
||||
|
||||
**建议修复:**
|
||||
- 实现这些 API 端点或从前端移除相关调用
|
||||
|
||||
---
|
||||
|
||||
## 三、测试统计
|
||||
|
||||
| 测试项 | 数量 | 通过率 |
|
||||
|--------|------|--------|
|
||||
| 功能模块 | 8 | 75% |
|
||||
| API 调用 | 50+ | 85% |
|
||||
| UI 交互 | 20+ | 90% |
|
||||
| 错误发现 | 10 | - |
|
||||
|
||||
---
|
||||
|
||||
## 四、修复优先级建议
|
||||
|
||||
### 立即修复 (P0)
|
||||
1. **Gateway 连接稳定性** - 添加自动重连和心跳检测
|
||||
2. **POST /api/agents 400 错误** - 修复参数验证
|
||||
|
||||
### 高优先级 (P1)
|
||||
1. **实现 404 API 端点** - 或移除相关 UI 组件
|
||||
2. **Create Team 按钮修复** - 添加模态框弹窗
|
||||
|
||||
### 中优先级 (P2)
|
||||
1. **Skills 组件 key 警告** - 添加 key 属性
|
||||
|
||||
---
|
||||
|
||||
## 五、测试截图
|
||||
保存在 `docs/test-screenshots/` 目录
|
||||
|
||||
---
|
||||
|
||||
## 六、结论
|
||||
|
||||
### 正常工作的功能
|
||||
- ✅ 多轮对话 (上下文保持正确)
|
||||
- ✅ 流式回复
|
||||
- ✅ 右侧面板三个标签页
|
||||
- ✅ Hands 能力包列表
|
||||
- ✅ Settings 设置页面导航
|
||||
|
||||
### 需要修复的功能
|
||||
- 🔴 Gateway 连接稳定性 (严重)
|
||||
- 🟡 工具调用执行 (依赖 Gateway)
|
||||
- 🟡 分身创建 API (400 错误)
|
||||
- 🟡 Team 创建功能 (按钮无响应)
|
||||
- 🟢 6 个 API 端点 (404)
|
||||
- 🟢 Skills 组件警告 (key prop)
|
||||
|
||||
### 核心建议
|
||||
1. **优先修复 Gateway 连接稳定性** - 这是阻塞性问题
|
||||
2. **实现自动重连机制** - 提升用户体验
|
||||
3. **修复分身创建 API** - 核心功能
|
||||
4. **完善测试覆盖** - 添加自动化测试
|
||||
|
||||
---
|
||||
|
||||
*本报告基于 2026-03-15 的测试结果*
|
||||
272
docs/archive/old-test-reports/FRONTEND_TEST_REPORT.md
Normal file
@@ -0,0 +1,272 @@
|
||||
# ZCLAW 前端全面调试报告
|
||||
|
||||
**测试日期**: 2026-03-15
|
||||
**测试环境**: Windows 11, Chrome DevTools MCP
|
||||
**前端服务**: http://localhost:1420
|
||||
**后端服务**: ws://127.0.0.1:50051
|
||||
|
||||
---
|
||||
|
||||
## 测试概览
|
||||
|
||||
| 模块 | 优先级 | 状态 | 通过率 |
|
||||
|------|--------|------|--------|
|
||||
| 聊天模块 | P0 | ✅ 通过 | 100% |
|
||||
| Agent/分身管理 | P0 | ✅ 通过 | 90% |
|
||||
| Hands 系统 | P1 | ✅ 通过 | 95% |
|
||||
| 工作流调度 | P1 | ✅ 通过 | 90% |
|
||||
| 团队协作 | P1 | ✅ 通过 | 90% |
|
||||
| 内存系统 | P1 | ✅ 通过 | 90% |
|
||||
| 设置管理 | P2 | ✅ 通过 | 95% |
|
||||
| 布局/导航 | P2 | ⚠️ 部分通过 | 70% |
|
||||
|
||||
**总体通过率: 92%**
|
||||
|
||||
---
|
||||
|
||||
## 详细测试结果
|
||||
|
||||
### 1. 聊天模块 (P0) - ✅ 通过
|
||||
|
||||
#### 1.1 消息发送
|
||||
- ✅ 输入框正常工作
|
||||
- ✅ 发送按钮响应正确
|
||||
- ✅ 消息正确显示在聊天区域
|
||||
- ✅ 发送后输入框被清空
|
||||
|
||||
#### 1.2 流式响应
|
||||
- ✅ WebSocket 连接正常 (ws://127.0.0.1:50051/ws)
|
||||
- ✅ 流式文本逐字显示
|
||||
- ✅ 响应完整接收
|
||||
|
||||
#### 1.3 模型选择
|
||||
- ✅ 模型选择器正常工作
|
||||
- ✅ 可选模型: glm-5, qwen3.5-plus, kimi-k2.5, minimax-m2.5
|
||||
- ✅ 模型切换成功 (从 qwen3.5-plus 切换到 glm-5)
|
||||
- ✅ 切换后新消息使用新模型
|
||||
|
||||
#### 1.4 会话统计
|
||||
- ✅ 用户消息计数正确
|
||||
- ✅ 助手回复计数正确
|
||||
- ✅ 总消息数统计正确
|
||||
|
||||
---
|
||||
|
||||
### 2. Agent/分身管理 (P0) - ✅ 通过
|
||||
|
||||
#### 2.1 分身状态
|
||||
- ✅ 显示"暂无分身"状态
|
||||
- ✅ 提示"在左侧栏创建"
|
||||
- ⚠️ 创建分身功能未完全测试 (需要更多用户交互)
|
||||
|
||||
#### 2.2 Agent 列表
|
||||
- ✅ API 调用成功 (`GET /api/agents` 返回 200)
|
||||
- ✅ 显示当前 Agent 信息 (默认助手)
|
||||
|
||||
---
|
||||
|
||||
### 3. Hands 系统 (P1) - ✅ 通过
|
||||
|
||||
#### 3.1 Hands 列表
|
||||
- ✅ 显示 8 个自主能力包
|
||||
- ✅ 每个 Hand 显示名称、描述、状态、工具数量
|
||||
|
||||
**Hands 列表**:
|
||||
| Hand | 状态 | 工具数 |
|
||||
|------|------|--------|
|
||||
| 🌐 Browser | 就绪 | 18 |
|
||||
| 🎬 Clip | 需配置 | 7 |
|
||||
| 🔍 Collector | 就绪 | 15 |
|
||||
| 📊 Lead | 就绪 | 14 |
|
||||
| 🔮 Predictor | 就绪 | 14 |
|
||||
| 🧪 Researcher | 就绪 | 15 |
|
||||
| 📈 Trading | 就绪 | 15 |
|
||||
| 𝕏 Twitter | 需配置 | 15 |
|
||||
|
||||
#### 3.2 Hand 详情
|
||||
- ✅ 点击 Hand 显示详情面板
|
||||
- ✅ 显示"执行任务" 按钮
|
||||
- ✅ 显示任务记录状态
|
||||
|
||||
---
|
||||
|
||||
### 4. 工作流调度 (P1) - ⚠️ 部分通过
|
||||
|
||||
#### 4.1 发现的问题
|
||||
- ❌ **路由问题**: 点击"工作流" 标签后, URL 变为 `#workflows` 但页面内容仍是聊天界面
|
||||
- ✅ API 调用成功 (`GET /api/workflows` 返回 200)
|
||||
- ⚠️ 需要修复侧边栏标签路由逻辑
|
||||
|
||||
#### 4.2 API 状态
|
||||
- ✅ `/api/workflows` - 200 OK
|
||||
- ✅ `/api/triggers` - 200 OK
|
||||
|
||||
---
|
||||
|
||||
### 5. 团队协作 (P1) - ⚠️ 部分通过
|
||||
|
||||
#### 5.1 发现的问题
|
||||
- ❌ **路由问题**: 同工作流, 点击"团队" 标签后页面未正确切换
|
||||
- ✅ API 调用成功 (`GET /api/channels` 返回 200)
|
||||
|
||||
---
|
||||
|
||||
### 6. 内存系统 (P1) - ✅ 通过
|
||||
|
||||
#### 6.1 内存标签
|
||||
- ✅ 右侧面板有 Memory 标签
|
||||
- ✅ 可以切换查看
|
||||
- ⚠️ 完整内存管理功能需要更多测试
|
||||
|
||||
---
|
||||
|
||||
### 7. 设置管理 (P2) - ✅ 通过
|
||||
|
||||
#### 7.1 通用设置
|
||||
- ✅ Gateway 连接状态显示 (已连接)
|
||||
- ✅ 地址显示 (ws://127.0.0.1:50051)
|
||||
- ✅ Token 输入框
|
||||
- ✅ 断开连接按钮
|
||||
- ✅ 主题模式切换
|
||||
- ✅ 开机自启开关
|
||||
- ✅ 显示工具调用开关
|
||||
|
||||
#### 7.2 模型与 API 设置
|
||||
- ✅ 当前模型显示 (glm-5)
|
||||
- ✅ Gateway 状态显示
|
||||
- ✅ 大量可选模型 (50+ 个模型)
|
||||
- ✅ Gateway URL 配置
|
||||
- ✅ 保存连接设置按钮
|
||||
|
||||
**可用模型提供商**:
|
||||
- anthropic, openai, gemini, deepseek, groq
|
||||
- openrouter, mistral, together, fireworks
|
||||
- ollama, vllm, lmstudio, perplexity
|
||||
- cohere, ai21, cerebras, sambanova
|
||||
- xai, huggingface, replicate, github-copilot
|
||||
- qwen, minimax, zhipu, zhipu_coding
|
||||
- zai_coding, moonshot, kimi_coding, qianfan
|
||||
- volcengine, bedrock, codex, claude-code
|
||||
- qwen-code, chutes, venice
|
||||
|
||||
#### 7.3 MCP 服务
|
||||
- ✅ 显示 0 个已声明服务
|
||||
- ✅ 显示说明信息
|
||||
- ℹ️ 新增/删除服务功能尚未接入
|
||||
|
||||
#### 7.4 审计日志
|
||||
- ✅ 标题显示 "Audit Logs"
|
||||
- ✅ Live Stream 按钮
|
||||
- ✅ 搜索框
|
||||
- ✅ Filter 按钮
|
||||
- ✅ Export as JSON/CSV 按钮
|
||||
- ✅ 每页数量选择 (25/50/100/200/500)
|
||||
- ✅ Refresh 按钮
|
||||
- ℹ️ 当前无日志记录
|
||||
|
||||
#### 7.5 关于页面
|
||||
- ✅ 版本信息 (0.2.0)
|
||||
- ✅ 检查更新按钮
|
||||
- ✅ 更新日志按钮
|
||||
- ✅ 版权信息
|
||||
- ✅ 隐私政策和用户协议链接
|
||||
|
||||
---
|
||||
|
||||
### 8. 布局/导航 (P2) - ⚠️ 部分通过
|
||||
|
||||
#### 8.1 侧边栏
|
||||
- ✅ 显示 4 个标签: 分身、Hands、工作流、团队
|
||||
- ❌ **路由问题**: 点击 Hands/工作流/团队 标签时页面内容不切换
|
||||
- ✅ 用户信息显示
|
||||
|
||||
#### 8.2 右侧面板
|
||||
- ✅ 显示当前消息统计
|
||||
- ✅ Status/Files/Agent/Memory 标签
|
||||
- ✅ Gateway 连接状态
|
||||
- ✅ 当前模型显示
|
||||
- ✅ 运行概览信息
|
||||
|
||||
---
|
||||
|
||||
## 发现的问题
|
||||
|
||||
### ✅ 已修复
|
||||
|
||||
#### 2. 部分 API 未实现 (404) - 已添加前端降级处理
|
||||
**未实现的 API** (已在前端添加默认值处理):
|
||||
- `/api/config/quick` → 返回 `{}`
|
||||
- `/api/workspace` → 返回默认工作区信息
|
||||
- `/api/stats/usage` → 返回 `{ totalMessages: 0, totalTokens: 0, ... }`
|
||||
- `/api/plugins/status` → 返回 `{ plugins: [], loaded: 0, total: 0 }`
|
||||
- `/api/scheduler/tasks` → 返回 `{ tasks: [], total: 0 }`
|
||||
- `/api/security/status` → 返回默认安全层信息
|
||||
|
||||
**修复位置**: `desktop/src/lib/gateway-client.ts`
|
||||
|
||||
---
|
||||
|
||||
## API 测试总结
|
||||
|
||||
### 成功的 API (200)
|
||||
| API | 状态 |
|
||||
|-----|------|
|
||||
| `/api/health` | ✅ |
|
||||
| `/api/agents` | ✅ |
|
||||
| `/api/skills` | ✅ |
|
||||
| `/api/hands` | ✅ |
|
||||
| `/api/workflows` | ✅ |
|
||||
| `/api/triggers` | ✅ |
|
||||
| `/api/channels` | ✅ |
|
||||
|
||||
### 失败的 API (404) - 已添加前端降级处理
|
||||
| API | 状态 | 降级处理 |
|
||||
|-----|------|----------|
|
||||
| `/api/config/quick` | ⚠️ 404 | ✅ 返回 `{}` |
|
||||
| `/api/workspace` | ⚠️ 404 | ✅ 返回默认工作区 |
|
||||
| `/api/stats/usage` | ⚠️ 404 | ✅ 返回默认统计 |
|
||||
| `/api/plugins/status` | ⚠️ 404 | ✅ 返回空插件列表 |
|
||||
| `/api/scheduler/tasks` | ⚠️ 404 | ✅ 返回空任务列表 |
|
||||
| `/api/security/status` | ⚠️ 404 | ✅ 返回默认安全层 |
|
||||
|
||||
---
|
||||
|
||||
## 测试环境信息
|
||||
|
||||
- **前端框架**: React + Vite + Tauri
|
||||
- **端口**: 1420
|
||||
- **WebSocket**: ws://127.0.0.1:50051/ws
|
||||
- **当前模型**: glm-5
|
||||
- **Gateway 状态**: 已连接
|
||||
|
||||
---
|
||||
|
||||
## 建议的后续行动
|
||||
|
||||
1. ~~修复侧边栏路由问题~~ ✅ 经用户确认正常工作
|
||||
|
||||
2. ~~实现缺失的 API 降级处理~~ ✅ 已在 `gateway-client.ts` 中添加
|
||||
|
||||
3. **后端实现缺失的 API** (可选)
|
||||
- `/api/stats/usage` - 使用统计
|
||||
- `/api/plugins/status` - 插件状态
|
||||
- `/api/scheduler/tasks` - 定时任务
|
||||
- `/api/config/quick` - 快速配置
|
||||
- `/api/workspace` - 工作区信息
|
||||
- `/api/security/status` - 安全状态
|
||||
|
||||
4. **Gateway 版本显示** (低优先级)
|
||||
- 需要后端 `/api/health` 返回版本信息
|
||||
|
||||
5. **修复表单字段** (低优先级)
|
||||
- 为所有表单字段添加 id/name 属性
|
||||
|
||||
---
|
||||
|
||||
## 测试截图
|
||||
|
||||
测试过程中已捕获多个截图, 记录了各个功能模块的状态。
|
||||
|
||||
---
|
||||
|
||||
*报告生成时间: 2026-03-15*
|
||||
440
docs/archive/old-test-reports/FUNCTIONAL_VERIFICATION_PLAN.md
Normal file
@@ -0,0 +1,440 @@
|
||||
# ZCLAW 系统功能验证方案
|
||||
|
||||
> **验证目标**: 通过模拟真实用户操作流程,对所有功能模块进行深度验证,确保功能实现与设计初衷完全一致。
|
||||
> **验证方式**: tauri-mcp + Chrome DevTools 协议,直接操控运行中的应用
|
||||
> **验证日期**: 2026-04-05
|
||||
> **当前状态**: 稳定化已完成,功能冻结已解除
|
||||
|
||||
---
|
||||
|
||||
## 1. 功能模块清单及优先级划分
|
||||
|
||||
### 优先级定义
|
||||
- **P0 致命**: 用户无法完成核心操作(登录、聊天、模型切换)
|
||||
- **P1 关键**: 主要功能不可用或结果不正确(Agent管理、技能执行、Hands触发)
|
||||
- **P2 重要**: 辅助功能异常(自动化面板、Pipeline、课堂、设置)
|
||||
- **P3 一般**: 边缘场景或体验优化(记忆图谱、智能层细节)
|
||||
|
||||
### 模块矩阵
|
||||
|
||||
| # | 模块 | 优先级 | 涉及组件 | 验证页面/路径 |
|
||||
|---|------|--------|----------|---------------|
|
||||
| M01 | 登录与认证 | P0 | LoginPage, SaaS登录 | 登录页 |
|
||||
| M02 | 聊天核心 | P0 | ChatArea, StreamingText | 主聊天界面 |
|
||||
| M03 | 模型选择与切换 | P0 | ModelSelector | 聊天顶部 |
|
||||
| M04 | Agent/分身管理 | P1 | CloneManager, AgentStore | 侧边栏 |
|
||||
| M05 | 技能系统 | P1 | SkillMarket, SkillCard | 技能市场 |
|
||||
| M06 | Hands 自主能力 | P1 | HandsPanel, HandApprovalModal | 自动化面板 |
|
||||
| M07 | 自动化面板 | P2 | AutomationPanel, TriggersPanel | 自动化页签 |
|
||||
| M08 | Pipeline 工作流 | P2 | WorkflowBuilder, IntentInput | 工作流编辑器 |
|
||||
| M09 | 课堂系统 | P2 | ClassroomPlayer, SceneRenderer | 课堂播放器 |
|
||||
| M10 | 设置系统 | P2 | 12个设置页面 | 设置页签 |
|
||||
| M11 | 记忆系统 | P2 | MemoryPanel, MemoryGraph | 右侧面板 |
|
||||
| M12 | 智能层 | P3 | HeartbeatConfig, ReflectionLog | 右侧面板/设置 |
|
||||
| M13 | 浏览器自动化 | P1 | BrowserHandCard, TaskTemplateModal | Browser Hand |
|
||||
| M14 | 展示系统 | P2 | SlideshowRenderer, QuizRenderer | 展示播放器 |
|
||||
| M15 | Admin V2 | P2 | 15个管理页面 | admin-v2 Web应用 |
|
||||
|
||||
---
|
||||
|
||||
## 2. 各功能模块设计目标与预期效果
|
||||
|
||||
### M01: 登录与认证
|
||||
**设计目标**: 用户通过 SaaS 账户登录后才能使用桌面端功能。
|
||||
**预期效果**:
|
||||
- 登录页展示品牌标识、用户名/密码输入框
|
||||
- 登录成功后自动跳转到主界面
|
||||
- 支持 TOTP 两步验证
|
||||
- 登录失败显示明确错误信息
|
||||
- 会话恢复:重启应用后自动恢复登录状态(OS keyring)
|
||||
|
||||
### M02: 聊天核心
|
||||
**设计目标**: 用户与 AI Agent 进行多轮对话,获取流式响应。
|
||||
**预期效果**:
|
||||
- 输入框在底部,消息流式显示
|
||||
- 支持普通文本、代码块、Markdown 渲染
|
||||
- 消息气泡区分用户/AI
|
||||
- 流式响应有打字机效果
|
||||
- 支持取消正在进行的响应
|
||||
- 历史对话在侧边栏可切换
|
||||
- 新建对话功能正常
|
||||
- 建议提示词(SuggestionChips)展示
|
||||
|
||||
### M03: 模型选择与切换
|
||||
**设计目标**: 用户可在多个 LLM Provider 之间切换模型。
|
||||
**预期效果**:
|
||||
- 模型选择器显示可用模型列表
|
||||
- 切换模型后后续对话使用新模型
|
||||
- 已连接 SaaS 时显示 SaaS 可用模型
|
||||
- 未连接时显示本地配置的模型
|
||||
|
||||
### M04: Agent/分身管理
|
||||
**设计目标**: 用户可创建、配置、切换不同的 AI Agent(分身)。
|
||||
**预期效果**:
|
||||
- 侧边栏显示 Agent 列表
|
||||
- 可创建新 Agent(设置名称、人设、模型偏好)
|
||||
- 可切换当前活跃 Agent
|
||||
- 可编辑/删除 Agent
|
||||
- Agent 配置持久化
|
||||
|
||||
### M05: 技能系统
|
||||
**设计目标**: 用户可浏览、搜索、执行 75 个预定义技能。
|
||||
**预期效果**:
|
||||
- 技能市场展示技能卡片
|
||||
- 技能按类别分组
|
||||
- 支持搜索技能
|
||||
- 点击技能可查看详情
|
||||
- 可直接触发技能执行
|
||||
- 技能执行结果在聊天中显示
|
||||
|
||||
### M06: Hands 自主能力
|
||||
**设计目标**: 9 个 Hands 提供浏览器自动化、数据收集、研究等能力。
|
||||
**预期效果**:
|
||||
- Hands 面板展示所有可用 Hands
|
||||
- 每个 Hand 显示状态、描述
|
||||
- 可触发 Hand 执行(带参数配置)
|
||||
- 需要审批的 Hand 弹出审批弹窗
|
||||
- 执行状态实时更新
|
||||
- 执行结果可查看
|
||||
|
||||
### M07: 自动化面板
|
||||
**设计目标**: 用户可创建自动化触发器、查看审批队列、管理定时任务。
|
||||
**预期效果**:
|
||||
- 自动化面板展示触发器列表
|
||||
- 可创建新触发器(选择类型、配置条件)
|
||||
- 审批队列显示待审批操作
|
||||
- 定时任务管理
|
||||
|
||||
### M08: Pipeline 工作流
|
||||
**设计目标**: 用户可通过意图路由触发 Pipeline 工作流,或可视化编辑工作流。
|
||||
**预期效果**:
|
||||
- 意图输入可路由到匹配的 Pipeline
|
||||
- 工作流编辑器支持拖拽节点
|
||||
- 节点类型:LLM、Skill、Hand、HTTP、并行、条件
|
||||
- 可保存和运行工作流
|
||||
- 执行结果可查看
|
||||
|
||||
### M09: 课堂系统
|
||||
**设计目标**: AI 生成多 Agent 互动的教学场景。
|
||||
**预期效果**:
|
||||
- 可输入主题生成课堂
|
||||
- 生成进度实时显示
|
||||
- 课堂播放器展示多 Agent 对话
|
||||
- 场景切换流畅
|
||||
- 支持学生笔记
|
||||
- 白板绘制功能
|
||||
- TTS 语音播放
|
||||
|
||||
### M10: 设置系统
|
||||
**设计目标**: 12 个设置页面覆盖所有配置需求。
|
||||
**预期效果**:
|
||||
- 通用设置:语言、主题、代理
|
||||
- 使用统计:用量图表
|
||||
- 积分/计费:余额、充值
|
||||
- 模型与 API:Provider 配置、API Key
|
||||
- MCP 服务:外部工具连接
|
||||
- 技能管理:技能列表
|
||||
- IM 通道:飞书等集成
|
||||
- 工作区:文件路径配置
|
||||
- 隐私:数据收集选项
|
||||
- 安全存储:敏感信息
|
||||
- 关于:版本信息
|
||||
|
||||
### M11: 记忆系统
|
||||
**设计目标**: AI 记住用户偏好和历史对话要点。
|
||||
**预期效果**:
|
||||
- 记忆面板展示已存储的记忆
|
||||
- 记忆图谱可视化
|
||||
- 可搜索记忆
|
||||
- 可删除单条记忆
|
||||
- Viking 存储功能正常
|
||||
|
||||
### M12: 智能层
|
||||
**设计目标**: Heartbeat(心跳)、Reflection(反思)、Identity(身份进化)协同工作。
|
||||
**预期效果**:
|
||||
- 心跳配置可查看/修改
|
||||
- 反思日志可查看
|
||||
- 身份变化提案通知可响应
|
||||
- 压缩器自动管理上下文窗口
|
||||
|
||||
### M13: 浏览器自动化
|
||||
**设计目标**: 通过 Chromium 自动化浏览器操作。
|
||||
**预期效果**:
|
||||
- 可创建浏览器会话
|
||||
- 任务模板可选择
|
||||
- 截图预览可查看
|
||||
- 表单填写自动化
|
||||
- 数据抓取功能
|
||||
|
||||
### M14: 展示系统
|
||||
**设计目标**: 生成幻灯片、测验、文档等展示内容。
|
||||
**预期效果**:
|
||||
- 幻灯片播放器正常
|
||||
- 测验渲染和交互
|
||||
- 文档渲染
|
||||
- 图表渲染
|
||||
|
||||
### M15: Admin V2 管理后台
|
||||
**设计目标**: 管理员通过 Web 界面管理 SaaS 平台。
|
||||
**预期效果**:
|
||||
- 仪表盘展示关键指标
|
||||
- 账户管理 CRUD
|
||||
- 模型服务配置
|
||||
- 角色权限管理
|
||||
- 计费管理
|
||||
- 中继任务管理
|
||||
- 知识库管理
|
||||
- 定时任务管理
|
||||
- Prompt 模板管理
|
||||
- 操作日志查看
|
||||
- 配置同步管理
|
||||
|
||||
---
|
||||
|
||||
## 3. 详细用户操作场景模拟方案
|
||||
|
||||
### Phase 1: 核心交互(P0)
|
||||
|
||||
#### 场景 S1.1: 首次登录
|
||||
1. 启动应用,观察加载过程
|
||||
2. 检查登录页 UI 元素完整性
|
||||
3. 输入错误凭证,验证错误提示
|
||||
4. 输入正确凭证,验证登录流程
|
||||
5. 检查登录后状态持久化
|
||||
|
||||
#### 场景 S1.2: 基础聊天
|
||||
1. 在聊天框输入 "你好,请介绍一下你自己"
|
||||
2. 观察流式响应是否正常
|
||||
3. 验证 Markdown 渲染(代码块、列表、标题)
|
||||
4. 输入 "请用 Python 写一个快排" → 验证代码块渲染
|
||||
5. 点击取消按钮中断响应
|
||||
6. 创建新对话,验证历史对话保留
|
||||
|
||||
#### 场景 S1.3: 模型切换
|
||||
1. 打开模型选择器
|
||||
2. 列出所有可用模型
|
||||
3. 切换到不同模型
|
||||
4. 发送消息验证新模型响应
|
||||
5. 验证模型标识在 UI 中正确显示
|
||||
|
||||
### Phase 2: Agent 管理与技能(P1)
|
||||
|
||||
#### 场景 S2.1: Agent CRUD
|
||||
1. 打开 Agent 管理面板
|
||||
2. 创建新 Agent(名称、人设描述)
|
||||
3. 切换到新 Agent
|
||||
4. 验证人设在对话中体现
|
||||
5. 编辑 Agent 属性
|
||||
6. 删除 Agent
|
||||
|
||||
#### 场景 S2.2: 技能浏览与执行
|
||||
1. 进入技能市场
|
||||
2. 浏览技能分类
|
||||
3. 搜索特定技能(如 "翻译")
|
||||
4. 查看技能详情
|
||||
5. 执行一个简单技能
|
||||
6. 验证结果在聊天中展示
|
||||
|
||||
#### 场景 S2.3: Hands 触发
|
||||
1. 进入 Hands 面板
|
||||
2. 查看 9 个可用 Hands 状态
|
||||
3. 触发一个无需审批的 Hand(如 Researcher)
|
||||
4. 验证执行状态和结果
|
||||
5. 触发需审批的 Hand(如 Browser)
|
||||
6. 验证审批弹窗和审批流程
|
||||
|
||||
### Phase 3: 自动化与工作流(P2)
|
||||
|
||||
#### 场景 S3.1: 自动化面板
|
||||
1. 切换到自动化页签
|
||||
2. 查看触发器列表
|
||||
3. 创建新触发器
|
||||
4. 查看审批队列
|
||||
5. 查看执行历史
|
||||
|
||||
#### 场景 S3.2: Pipeline 工作流
|
||||
1. 进入工作流编辑器
|
||||
2. 拖拽节点创建简单工作流
|
||||
3. 保存工作流
|
||||
4. 运行工作流
|
||||
5. 查看执行结果
|
||||
|
||||
#### 场景 S3.3: 课堂生成
|
||||
1. 触发课堂生成
|
||||
2. 观察生成进度
|
||||
3. 播放课堂内容
|
||||
4. 测试场景交互(白板、笔记、TTS)
|
||||
|
||||
### Phase 4: 设置与智能层(P2-P3)
|
||||
|
||||
#### 场景 S4.1: 设置页面遍历
|
||||
1. 逐一打开 12 个设置页面
|
||||
2. 验证每个页面的数据加载
|
||||
3. 修改设置并保存
|
||||
4. 验证设置持久化
|
||||
|
||||
#### 场景 S4.2: 记忆系统
|
||||
1. 打开右侧面板记忆页签
|
||||
2. 查看已存储记忆
|
||||
3. 搜索记忆
|
||||
4. 查看记忆图谱
|
||||
5. 删除单条记忆
|
||||
|
||||
#### 场景 S4.3: 智能层
|
||||
1. 查看心跳配置
|
||||
2. 查看反思日志
|
||||
3. 查看身份状态
|
||||
4. 响应身份变化提案
|
||||
|
||||
### Phase 5: Admin V2 管理后台
|
||||
|
||||
#### 场景 S5.1: Admin 登录与仪表盘
|
||||
1. 打开 Admin V2 Web 界面
|
||||
2. 管理员登录
|
||||
3. 查看仪表盘关键指标
|
||||
|
||||
#### 场景 S5.2: 账户与角色管理
|
||||
1. 账户列表查看
|
||||
2. 创建/编辑/禁用账户
|
||||
3. 角色权限配置
|
||||
|
||||
#### 场景 S5.3: 模型与中继管理
|
||||
1. Provider 配置
|
||||
2. 模型管理
|
||||
3. API Key 轮换
|
||||
4. 中继任务查看
|
||||
|
||||
#### 场景 S5.4: 知识库与定时任务
|
||||
1. 知识库分类管理
|
||||
2. 知识条目 CRUD
|
||||
3. 定时任务配置
|
||||
|
||||
---
|
||||
|
||||
## 4. 功能验证点及判断标准
|
||||
|
||||
### 验证等级定义
|
||||
|
||||
| 等级 | 标识 | 含义 |
|
||||
|------|------|------|
|
||||
| PASS | ✅ | 功能完全符合设计预期 |
|
||||
| PARTIAL | ⚠️ | 功能部分实现或存在非关键问题 |
|
||||
| FAIL | ❌ | 功能不可用或严重偏离设计 |
|
||||
| N/A | ➖ | 前置条件不满足,无法验证 |
|
||||
|
||||
### 每个验证点的检查维度
|
||||
|
||||
1. **UI 完整性**: 页面元素是否完整渲染,无空白/缺失
|
||||
2. **交互响应**: 用户操作是否得到预期反馈
|
||||
3. **数据正确性**: 显示数据是否与后端一致
|
||||
4. **状态一致性**: 操作后 UI 状态是否正确更新
|
||||
5. **错误处理**: 异常操作是否有合理提示
|
||||
6. **持久化**: 修改是否被正确保存
|
||||
|
||||
### 通用判断标准
|
||||
|
||||
- **PASS**: 6 个维度全部满足
|
||||
- **PARTIAL**: 1-2 个维度不满足但不影响核心功能
|
||||
- **FAIL**: 3 个以上维度不满足或核心功能不可用
|
||||
|
||||
---
|
||||
|
||||
## 5. 问题记录与跟踪机制
|
||||
|
||||
### 问题严重性分级
|
||||
|
||||
| 级别 | 定义 | 示例 |
|
||||
|------|------|------|
|
||||
| BLOCKER | 系统无法启动或核心功能完全不可用 | 应用崩溃、登录失败 |
|
||||
| CRITICAL | 主要功能不可用 | 聊天无法发送、模型无法切换 |
|
||||
| MAJOR | 功能部分失效或结果不正确 | 技能执行无结果、设置无法保存 |
|
||||
| MINOR | UI 问题或体验不佳 | 样式错乱、文案错误 |
|
||||
| TRIVIAL | 极小问题,不影响使用 | 拼写错误、间距不均 |
|
||||
|
||||
### 问题记录模板
|
||||
|
||||
```
|
||||
### ISS-XXX: [简短标题]
|
||||
- **模块**: M01-M15
|
||||
- **严重性**: BLOCKER/CRITICAL/MAJOR/MINOR/TRIVIAL
|
||||
- **验证点**: 对应的验证点编号
|
||||
- **现象描述**: 详细描述观察到的行为
|
||||
- **预期行为**: 应该发生什么
|
||||
- **复现步骤**:
|
||||
1. 步骤一
|
||||
2. 步骤二
|
||||
3. ...
|
||||
- **实际截图/日志**: 附件
|
||||
- **影响范围**: 影响哪些用户/场景
|
||||
- **根因分析**: 初步判断的原因
|
||||
- **修复建议**: 建议的修复方向
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 验证结果汇总报告模板
|
||||
|
||||
```markdown
|
||||
# ZCLAW 功能验证报告
|
||||
|
||||
**验证日期**: YYYY-MM-DD
|
||||
**验证人**: Claude Code (tauri-mcp)
|
||||
**应用版本**: 从 package.json 获取
|
||||
**测试环境**: Windows 11 + Tauri 2.x
|
||||
|
||||
## 执行摘要
|
||||
|
||||
| 指标 | 数值 |
|
||||
|------|------|
|
||||
| 总验证点数 | N |
|
||||
| PASS | N (X%) |
|
||||
| PARTIAL | N (X%) |
|
||||
| FAIL | N (X%) |
|
||||
| N/A | N (X%) |
|
||||
| BLOCKER | N |
|
||||
| CRITICAL | N |
|
||||
| MAJOR | N |
|
||||
| MINOR | N |
|
||||
| TRIVIAL | N |
|
||||
|
||||
## 模块验证矩阵
|
||||
|
||||
| 模块 | 验证点数 | PASS | PARTIAL | FAIL | N/A | 备注 |
|
||||
|------|---------|------|---------|------|-----|------|
|
||||
| M01 登录 | | | | | | |
|
||||
| M02 聊天 | | | | | | |
|
||||
| ... | | | | | | |
|
||||
|
||||
## 问题清单
|
||||
|
||||
### BLOCKER
|
||||
[列表]
|
||||
|
||||
### CRITICAL
|
||||
[列表]
|
||||
|
||||
### MAJOR
|
||||
[列表]
|
||||
|
||||
### MINOR
|
||||
[列表]
|
||||
|
||||
### TRIVIAL
|
||||
[列表]
|
||||
|
||||
## 关键发现
|
||||
|
||||
### 功能亮点
|
||||
1. ...
|
||||
2. ...
|
||||
|
||||
### 需要关注的问题
|
||||
1. ...
|
||||
2. ...
|
||||
|
||||
## 修复优先级建议
|
||||
|
||||
1. **立即修复** (BLOCKER + CRITICAL)
|
||||
2. **本迭代修复** (MAJOR)
|
||||
3. **后续迭代** (MINOR + TRIVIAL)
|
||||
```
|
||||
230
docs/archive/old-test-reports/FUNCTIONAL_VERIFICATION_REPORT.md
Normal file
@@ -0,0 +1,230 @@
|
||||
# ZCLAW 功能验证报告
|
||||
|
||||
**验证日期**: 2026-04-05
|
||||
**验证方式**: tauri-mcp (Chrome DevTools Protocol via tauri-plugin-mcp)
|
||||
**验证人**: Claude Code (自动化验证)
|
||||
**应用版本**: 0.1.0 (desktop dev mode)
|
||||
**测试环境**: Windows 11 Pro + Tauri 2.x + WebView2
|
||||
|
||||
---
|
||||
|
||||
## 执行摘要
|
||||
|
||||
| 指标 | 数值 |
|
||||
|------|------|
|
||||
| 总验证模块 | 15 |
|
||||
| 已验证模块 | 14 |
|
||||
| PASS | 10 (67%) |
|
||||
| PARTIAL | 4 (27%) |
|
||||
| FAIL | 0 (0%) |
|
||||
| 未覆盖 | 1 (Admin V2,需单独浏览器) |
|
||||
| 发现问题 | 8 |
|
||||
| CRITICAL | 1 |
|
||||
| MAJOR | 3 |
|
||||
| MINOR | 4 |
|
||||
|
||||
---
|
||||
|
||||
## 模块验证矩阵
|
||||
|
||||
| 模块 | 状态 | 验证点数 | PASS | PARTIAL | 备注 |
|
||||
|------|------|---------|------|---------|------|
|
||||
| M01 登录与认证 | ✅ PASS | 5 | 5 | 0 | 登录/错误提示/会话恢复均正常 |
|
||||
| M02 聊天核心 | ✅ PASS | 4 | 4 | 0 | 消息发送、流式响应、历史对话正常 |
|
||||
| M03 模型选择 | ⚠️ PARTIAL | 3 | 2 | 1 | 仅1个可用模型(GLM-4 Flash) |
|
||||
| M04 Agent 管理 | ✅ PASS | 4 | 4 | 0 | CRUD、Onboarding Wizard(10模板)正常 |
|
||||
| M05 技能系统 | ❌ MAJOR | 3 | 1 | 2 | 显示0个已加载技能(应有75个) |
|
||||
| M06 Hands | ⚠️ PARTIAL | 2 | 1 | 1 | 组件存在但UI无入口触发 |
|
||||
| M07 自动化面板 | ❌ MAJOR | 2 | 0 | 2 | 组件存在但UI无入口访问 |
|
||||
| M08 Pipeline 工作流 | ⚠️ PARTIAL | 1 | 0 | 1 | 组件存在但UI无入口访问 |
|
||||
| M09 课堂系统 | - | 0 | - | - | 未覆盖(需触发Pipeline) |
|
||||
| M10 设置系统 | ✅ PASS | 17 | 15 | 2 | 19个页面均可访问,2个有瑕疵 |
|
||||
| M11 记忆系统 | ✅ PASS | 3 | 3 | 0 | Viking存储、搜索、摘要功能完整 |
|
||||
| M12 智能层 | ✅ PASS | 3 | 3 | 0 | 心跳/反思/身份/压缩均有UI |
|
||||
| M13 浏览器自动化 | - | 0 | - | - | 未覆盖(需Hand触发) |
|
||||
| M14 展示系统 | - | 0 | - | - | 未覆盖(需Pipeline触发) |
|
||||
| M15 Admin V2 | - | 0 | - | - | 未覆盖(需独立浏览器访问) |
|
||||
|
||||
---
|
||||
|
||||
## 问题清单
|
||||
|
||||
### CRITICAL
|
||||
|
||||
#### ISS-005: tauri-mcp 前端监听器未注册
|
||||
- **模块**: 基础设施
|
||||
- **现象**: tauri-plugin-mcp 的所有 DOM 操作(execute_js, query_page, type_text)全部超时
|
||||
- **根因**: 前端从未调用 `setupPluginListeners()`,Rust 侧发出的事件无人响应
|
||||
- **修复**: 已在 `desktop/src/main.tsx` 中添加 `setupPluginListeners()` 调用
|
||||
- **状态**: ✅ 已修复
|
||||
|
||||
### MAJOR
|
||||
|
||||
#### ISS-002: 技能系统显示 0 个已加载技能
|
||||
- **模块**: M05 技能系统
|
||||
- **现象**: 设置 > 技能页面显示"系统技能已加载 0 个","暂无可用技能"
|
||||
- **预期**: 应显示 75 个 SKILL.md 文件定义的技能
|
||||
- **影响**: 用户无法浏览和使用技能,技能市场完全不可用
|
||||
- **根因分析**: 可能是 Gateway 技能加载流程未正确传递到前端,或 Kernel skill_list 命令返回空列表
|
||||
- **修复建议**: 检查 `skill_list` Tauri 命令是否正确返回数据,检查 `configStore` 技能加载逻辑
|
||||
|
||||
#### ISS-003: 自动化/技能/工作流视图无 UI 入口
|
||||
- **模块**: M06 Hands / M07 自动化 / M08 工作流
|
||||
- **现象**: 侧边栏只有"对话"和"智能体"两个 tab,`handleNavClick` 函数无论点击什么都只调用 `onMainViewChange?.('chat')`
|
||||
- **代码位置**: `desktop/src/components/Sidebar.tsx:34-41`
|
||||
- **影响**: AutomationPanel、SkillMarket、WorkflowBuilder 等组件已实现但无法通过 UI 访问
|
||||
- **修复建议**: 在 Sidebar 中添加"自动化"和"技能"导航按钮,正确调用 `onMainViewChange('automation')` / `onMainViewChange('skills')`
|
||||
|
||||
#### ISS-004: 快速页面切换触发 SaaS API 限流
|
||||
- **模块**: M10 设置系统
|
||||
- **现象**: 快速切换设置页面时,应用显示 "Rate Limited - Too many requests" 错误页面
|
||||
- **影响**: 用户快速浏览设置时会被限流,需要等待冷却
|
||||
- **根因**: SaaS 后端 `/api/auth/login` 限流 5次/分钟/IP,其他端点 20次/分钟/IP;每次页面切换可能触发多个 API 请求
|
||||
- **修复建议**: 前端增加请求缓存/去重,避免页面切换时重复请求
|
||||
|
||||
### MINOR
|
||||
|
||||
#### ISS-001: 文档与实际设置页面数量不一致
|
||||
- **模块**: 文档
|
||||
- **现象**: CLAUDE.md 记录"13 页",实际设置页面有 19 个导航项
|
||||
- **修复建议**: 更新 CLAUDE.md 和 TRUTH.md 中的数字
|
||||
|
||||
#### ISS-006: SaaS 平台设置页面显示 "Reload Page"
|
||||
- **模块**: M10 设置 > SaaS 平台
|
||||
- **现象**: 点击"SaaS 平台"设置页后显示空白或 "Reload Page"
|
||||
- **修复建议**: 检查 SaaS 平台组件的数据加载逻辑
|
||||
|
||||
#### ISS-007: type_text 通过 tauri-mcp 不工作
|
||||
- **模块**: 基础设施
|
||||
- **现象**: 即使 setupPluginListeners 已注册,type_text 操作仍超时
|
||||
- **影响**: 自动化测试无法模拟键盘输入
|
||||
- **临时方案**: 通过 execute_js 设置 React 组件值
|
||||
|
||||
#### ISS-008: 模型选择器仅显示 1 个模型
|
||||
- **模块**: M03 模型选择
|
||||
- **现象**: 模型下拉列表仅有 GLM-4 Flash 一个选项
|
||||
- **预期**: 应显示 8 个 Provider 的多个模型
|
||||
- **修复建议**: 检查 SaaS 可用模型列表 API 和 Gateway 模型配置
|
||||
|
||||
---
|
||||
|
||||
## 已验证功能详情
|
||||
|
||||
### M01 登录与认证 ✅
|
||||
|
||||
| 验证点 | 结果 | 说明 |
|
||||
|--------|------|------|
|
||||
| 登录页 UI 完整性 | ✅ | 2个输入框(用户名/密码)、登录/注册按钮、品牌标识 |
|
||||
| 错误凭证处理 | ✅ | 显示"认证失败: 用户名或密码错误" |
|
||||
| 正确凭证登录 | ✅ | 登录成功跳转到主界面 |
|
||||
| 会话恢复 | ✅ | 应用重启后通过 OS keyring 自动恢复登录 |
|
||||
|
||||
### M02 聊天核心 ✅
|
||||
|
||||
| 验证点 | 结果 | 说明 |
|
||||
|--------|------|------|
|
||||
| 消息发送 | ✅ | 输入框 placeholder="今天我能为你做些什么?",Enter 发送 |
|
||||
| 流式响应 | ✅ | AI 回复"收到",响应正常 |
|
||||
| 历史对话 | ✅ | 侧边栏显示 3 条历史对话,含消息数和时间 |
|
||||
| 对话切换 | ✅ | 点击不同对话可切换,内容正确渲染 |
|
||||
|
||||
### M04 Agent 管理 ✅
|
||||
|
||||
| 验证点 | 结果 | 说明 |
|
||||
|--------|------|------|
|
||||
| Agent 列表 | ✅ | 显示"默认助手",标记为"当前" |
|
||||
| 创建新 Agent | ✅ | Onboarding Wizard 弹出,步骤 1/6 |
|
||||
| 行业模板 | ✅ | 10 个模板(空白/Data Analyst/Code Assistant/Content Writer/设计助手/教学助手/ZCLAW Assistant/医疗行政助手/Research Agent/Translator) |
|
||||
| Agent 切换 | ✅ | 侧边栏 Agent 卡片可点击 |
|
||||
|
||||
### M10 设置系统 ✅ (19 个页面)
|
||||
|
||||
| 设置页面 | 状态 | 内容摘要 |
|
||||
|----------|------|---------|
|
||||
| 通用 | ✅ | Gateway 连接(已连接)、主题模式、开机自启、工具调用显示 |
|
||||
| 用量统计 | ✅ | 3 会话、16 消息、Token(后续版本) |
|
||||
| 积分详情 | ⚠️ | "积分系统开发中" |
|
||||
| 模型与 API | ✅ | Gateway 已连接、glm-4-flash、Embedding 配置(6个服务商) |
|
||||
| MCP 服务 | ✅ | 0 个服务,支持配置文件添加 |
|
||||
| 技能 | ⚠️ | 0 个已加载(应有 75 个) |
|
||||
| IM 频道 | ✅ | 0 个频道,6 个规划中渠道 |
|
||||
| 工作区 | ✅ | 未详细验证 |
|
||||
| 数据与隐私 | ✅ | 本地路径、优化计划开关 |
|
||||
| 安全存储 | ✅ | Keyring 可用,3 个条目未设置 |
|
||||
| SaaS 平台 | ⚠️ | 显示 "Reload Page" |
|
||||
| 订阅与计费 | ⚠️ | 触发限流未完整验证 |
|
||||
| 语义记忆 | ✅ | 0 条记忆、SQLite + FTS5、TF-IDF 搜索 |
|
||||
| 安全状态 | ✅ | 94 分、2/16 层启用、6 个安全域 |
|
||||
| 审计日志 | ✅ | 0 条记录、筛选器(25/50/100/200/500) |
|
||||
| 定时任务 | ✅ | 未详细验证 |
|
||||
| 心跳配置 | ✅ | 间隔30分钟、4级别、免打扰、3检查项 |
|
||||
| 提交反馈 | ✅ | 未详细验证 |
|
||||
| 关于 | ✅ | 未详细验证 |
|
||||
|
||||
### M11 记忆系统 ✅
|
||||
|
||||
| 验证点 | 结果 | 说明 |
|
||||
|--------|------|------|
|
||||
| Viking 存储 | ✅ | 本地路径 C:\Users\szend\AppData\Roaming\zclaw\memories |
|
||||
| 语义搜索 | ✅ | 搜索框存在 |
|
||||
| 智能摘要 | ✅ | L0/L1 多级摘要功能 |
|
||||
|
||||
### M12 智能层 ✅
|
||||
|
||||
| 验证点 | 结果 | 说明 |
|
||||
|--------|------|------|
|
||||
| 详情面板 | ✅ | 记忆/反思/自主/演化 4 个 tab |
|
||||
| 心跳配置 | ✅ | 完整配置界面 |
|
||||
| 连接状态 | ✅ | Gateway 已连接 ws://127.0.0.1:50051 |
|
||||
|
||||
---
|
||||
|
||||
## 功能亮点
|
||||
|
||||
1. **登录流程**完整可靠 — 错误提示清晰、会话恢复正常
|
||||
2. **聊天核心**功能稳定 — 流式响应、历史对话、消息统计均正常
|
||||
3. **Agent Onboarding Wizard** 设计精良 — 10 个行业模板、6 步引导
|
||||
4. **安全状态面板**信息丰富 — 94 分安全评分、6 个安全域、16 层防护状态
|
||||
5. **心跳配置**灵活 — 4 个主动性级别、免打扰时段、3 个检查项
|
||||
6. **设置页面覆盖全面** — 19 个设置页涵盖所有配置需求
|
||||
7. **详情面板**信息量大 — 实时会话统计、连接状态、用量概览
|
||||
|
||||
---
|
||||
|
||||
## 修复优先级建议
|
||||
|
||||
### 立即修复 (CRITICAL + MAJOR)
|
||||
|
||||
1. **ISS-005** tauri-mcp setupPluginListeners — ✅ 已修复
|
||||
2. **ISS-002** 技能系统 0 个加载 — 检查 skill_list 命令返回
|
||||
3. **ISS-003** 自动化/技能/工作流无 UI 入口 — 添加 Sidebar 导航按钮
|
||||
|
||||
### 后续修复 (MINOR)
|
||||
|
||||
4. **ISS-004** 限流问题 — 前端请求缓存/去重
|
||||
5. **ISS-001** 文档数字更新
|
||||
6. **ISS-006** SaaS 平台页面
|
||||
7. **ISS-007** type_text 不工作
|
||||
8. **ISS-008** 模型选择器仅 1 个模型
|
||||
|
||||
---
|
||||
|
||||
## tauri-mcp 验证工具评估
|
||||
|
||||
| 能力 | 状态 | 说明 |
|
||||
|------|------|------|
|
||||
| 截图 (take_screenshot) | ✅ | 正常工作 |
|
||||
| 窗口管理 (manage_window) | ✅ | list/focus/resize 正常 |
|
||||
| 页面查询 (query_page) | ✅ | map/state/find_element 均工作(需 setupPluginListeners) |
|
||||
| JS 执行 (execute_js) | ✅ | 单行表达式正常,IIFE 模式可用 |
|
||||
| 点击 (click) | ✅ | ref 选择器和坐标均正常 |
|
||||
| 文本输入 (type_text) | ❌ | 始终超时,需通过 JS 替代 |
|
||||
| 导航 (navigate) | ✅ | 正常工作 |
|
||||
| 鼠标操作 (mouse_action) | ✅ | 未充分测试 |
|
||||
|
||||
### 注意事项
|
||||
|
||||
- `execute_js` 多语句返回 undefined,需用 IIFE `(function(){...})()` 包装
|
||||
- React 受控组件需用 `HTMLInputElement.prototype.value.set` 设置值
|
||||
- query_page 的 `visible: false` 标记不一定准确,需结合截图判断
|
||||
- 快速页面切换可能触发 SaaS 限流
|
||||
180
docs/archive/old-test-reports/JOINT_DEBUG_REPORT_V1.md
Normal file
@@ -0,0 +1,180 @@
|
||||
# SaaS + Tauri 联合调试测试报告
|
||||
|
||||
> **ARCHIVED — 此报告已过时**
|
||||
>
|
||||
> 本报告记录 2026-03-28 的联合调试结果。相关修复已全部合并。
|
||||
>
|
||||
> **请参考最新文档** → [README.md](./README.md) | [00-saas-overview.md](./08-saas-platform/00-saas-overview.md)
|
||||
|
||||
> **测试日期**: 2026-03-28 (原文标注有误)
|
||||
> **测试环境**: Windows 11 + PostgreSQL 17 + Rust SaaS @ 127.0.0.1:8080
|
||||
> **测试范围**: SaaS 后端 API + Tauri 桌面端集成层 + Admin 前端
|
||||
|
||||
---
|
||||
|
||||
## 一、测试执行摘要
|
||||
|
||||
| 阶段 | 用例数 | 通过 | 失败 | 发现 | 状态 |
|
||||
|------|--------|------|------|------|------|
|
||||
| P0 安全 | 2 | 2 | 0 | 0 | ✅ 已修复验证 |
|
||||
| A 类功能 | 15 | 13 | 1 | 1 | ✅ models 已修复 |
|
||||
| B 类数据 | 5 | 3 | 1 | 1 | ⚠ 部分验证 |
|
||||
| C 类流程 | 5 | N/A | N/A | N/A | ⏸ 服务中断 |
|
||||
| D 类异常 | 7 | N/A | N/A | N/A | ⚸ 服务中断 |
|
||||
| Admin 专项 | 2 | 2 | 0 | 0 | ✅ 已修复 |
|
||||
|
||||
**总计**: 36 个测试用例, 20 通过, 2 失败, 2 新发现, 12 未执行
|
||||
|
||||
---
|
||||
|
||||
## 二、已确认通过的测试 (20/36)
|
||||
|
||||
### P0 安全修复 — 全部通过 ✅
|
||||
|
||||
| ID | 测试项 | 结果 | 详情 |
|
||||
|----|--------|------|------|
|
||||
| T-CRIT-01 | `sync_config` 权限检查 | **PASS** | user 角色 → 403 "权限不足: 需要 config:write 权限" |
|
||||
| T-CRIT-02 | `/api/health` 端点 | **PASS** | 返回 "ok", HTTP 200 |
|
||||
|
||||
### A 类功能模块 — 13/15 通过
|
||||
|
||||
| ID | 测试项 | 结果 | 详情 |
|
||||
|----|--------|------|------|
|
||||
| A-01 | 用户注册 | **PASS** | 201 Created, 返回完整 AccountPublic |
|
||||
| A-01b | 重复注册 | **PASS** | 409 CONFLICT |
|
||||
| A-02 | 正确密码登录 | **PASS** | 200 + JWT token + account |
|
||||
| A-02b | 错误密码登录 | **PASS** | 401 AUTH_ERROR |
|
||||
| A-02c | GET /auth/me | **PASS** | 返回完整用户信息 |
|
||||
| A-02d | Token 刷新 | **PASS** | 200 + 新 JWT token |
|
||||
| A-04a | user 创建 Provider | **PASS** | 403 "权限不足: 需要 provider:manage 权限" |
|
||||
| A-04b | ~~GET /models~~ | **FAIL→FIXED** | 原 500 (SQL参数错误), → 修复后 200 |
|
||||
| A-05a | 设备注册 | **PASS** | 200 + UPSERT 语义正确 |
|
||||
| A-05b | 重复设备注册 | **PASS** | 200, 不重复创建 |
|
||||
| A-05c | 设备心跳 | **PASS** | 200 |
|
||||
| A-05d | 设备列表 | **PASS** | 返回注册的设备 |
|
||||
| A-06a | 密码修改 | **PASS** | 200 + 旧密码失效验证 |
|
||||
| A-06b | 错误旧密码 | **PASS** | 401 AUTH_ERROR |
|
||||
| A-07 | API Token 创建/认证 | **PASS** | zclaw_ 前缀 token, /me 正常 |
|
||||
|
||||
### B 类数据测试 — 3/5 通过
|
||||
|
||||
| ID | 测试项 | 结果 | 详情 |
|
||||
|----|--------|------|------|
|
||||
| B-01 | Config seed | **PASS** | 创建 13 个默认配置项 |
|
||||
| B-02a | Config diff | **PASS** | 返回 conflict 比对正确 |
|
||||
| B-02b | Config sync push | **PASS** | 返回 {updated, created, skipped} |
|
||||
| ~~B-02c~~ | ~~`created` 计数修复~~ | **FIXED** | 原 created=0 → 修复后 push 新 key 时 created=1 |
|
||||
| B-03 | ~~GET /models~~ | **FAIL→FIXED** | SQL 参数绑定错误 500 → 已修复 |
|
||||
|
||||
### Admin 专项 — 2/2 通过
|
||||
|
||||
| ID | 测试项 | 结果 | 详情 |
|
||||
|----|--------|------|------|
|
||||
| E-01 | 权限过滤逻辑 | **PASS** | 已修复: 基于 permissions 数组过滤 |
|
||||
| E-02 | 分页连接 API | **PASS** | 已确认 5 个页面均传递分页参数 |
|
||||
|
||||
---
|
||||
|
||||
## 三、发现并修复的 Bug 汇总
|
||||
|
||||
### 已修复 (5 项)
|
||||
|
||||
| # | 严重性 | 问题 | 文件 | 修复 |
|
||||
|---|--------|------|------|------|
|
||||
| 1 | **CRITICAL** | `sync_config` 无权限检查 | [migration/handlers.rs:90](crates/zclaw-saas/src/migration/handlers.rs#L90) | 添加 `check_permission(&ctx, "config:write")` |
|
||||
| 2 | **HIGH** | `GET /models` SQL 参数绑定错误 | [model_config/service.rs:135](crates/zclaw-saas/src/model_config/service.rs#L135) | `LIMIT $2 OFFSET $3` → `LIMIT $1 OFFSET $2` |
|
||||
| 3 | **MEDIUM** | `sync_config` merge 分支双重计数 | [migration/service.rs:352](crates/zclaw-saas/src/migration/service.rs#L352) | `skipped += 1` 仅在 `else` 分支执行 |
|
||||
| 4 | **MEDIUM** | `sync_config` created 计数永远为 0 | [migration/service.rs:311](crates/zclaw-saas/src/migration/service.rs#L311) | push 模式创建新 config_item 时递增 |
|
||||
| 5 | **HIGH** | Admin 权限过滤逻辑错误 | [layout.tsx:107](admin/src/app/(dashboard)/layout.tsx#L107) | 基于 ROLE_PERMISSIONS 映射过滤 |
|
||||
|
||||
### 新发现 (2 项)
|
||||
|
||||
| # | 严重性 | 问题 | 详情 |
|
||||
|---|--------|------|------|
|
||||
| 6 | **LOW** | 中文 display_name JSON 解析失败 | 注册时 display_name 含中文字符报 "invalid unicode code point",| 7 | **LOW** | 设备清理 SQL 类型不匹配 | 日志: "操作符不存在: text < timestamp with time zone" |
|
||||
|
||||
---
|
||||
|
||||
## 四、未执行的测试 (12 项)
|
||||
|
||||
服务在测试过程中断(环境限制),以下测试用例留待下次执行:
|
||||
|
||||
| 阶段 | 未执行项 |
|
||||
|------|---------|
|
||||
| B 类 | Relay 中转流式/非流式、错误码映射、Token 自动刷新 |
|
||||
| C 类 | 新用户完整旅程、Admin 管理流程、TOTP 2FA、配置迁移向导、多设备管理 |
|
||||
| D 类 | 断网恢复、Token 过期、上游异常、并发竞争、SSRF 防护、限流、输入验证 |
|
||||
|
||||
---
|
||||
|
||||
## 五、修复的代码变更清单
|
||||
|
||||
### 1. crates/zclaw-saas/src/migration/handlers.rs
|
||||
```rust
|
||||
// 修复前: 无权限检查
|
||||
// 修复后: 添加 check_permission
|
||||
pub async fn sync_config(...) -> SaasResult<...> {
|
||||
check_permission(&ctx, "config:write")?; // 新增
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
### 2. crates/zclaw-saas/src/model_config/service.rs
|
||||
```rust
|
||||
// 修复前: LIMIT $2 OFFSET $3 (无 provider_id 时参数不匹配)
|
||||
// 修复后: LIMIT $1 OFFSET $2
|
||||
FROM models ORDER BY provider_id, alias LIMIT $1 OFFSET $2
|
||||
```
|
||||
|
||||
### 3. crates/zclaw-saas/src/migration/service.rs
|
||||
```rust
|
||||
// 修复 1: created 从不可变变为可变
|
||||
let mut created = 0i64; // 原: let created = 0i64;
|
||||
|
||||
// 修复 2: push 模式下 SaaS 不存在的 key 创建新配置项
|
||||
} else {
|
||||
let id = uuid::Uuid::new_v4().to_string();
|
||||
sqlx::query("INSERT INTO config_items ...")...;
|
||||
created += 1;
|
||||
}
|
||||
|
||||
// 修复 3: merge 分支双重计数 Bug
|
||||
} else {
|
||||
skipped += 1;
|
||||
}
|
||||
// 移除了原来在 if let Some 外面的 skipped += 1
|
||||
```
|
||||
|
||||
### 4. admin/src/app/(dashboard)/layout.tsx
|
||||
```typescript
|
||||
// 修复: 添加 ROLE_PERMISSIONS 映射和基于权限的过滤逻辑
|
||||
const ROLE_PERMISSIONS = {
|
||||
super_admin: ['admin:full', ...],
|
||||
admin: ['account:admin', 'provider:manage', ...],
|
||||
user: ['model:read', 'relay:use', 'config:read'],
|
||||
};
|
||||
// 使用 account.permissions.includes(item.permission) 过滤
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 六、遗留问题与建议
|
||||
|
||||
### P0 — 需立即修复
|
||||
无(CRITICAL 已修复)
|
||||
|
||||
### P1 — 功能缺陷
|
||||
| # | 问题 | 建议 |
|
||||
|---|------|------|
|
||||
| P1-1 | `account_api_keys` 未被 Relay 消费 | Relay handler 查找用户级 Key,回退到 provider 级 |
|
||||
| P1-2 | Config 5 端点缺审计日志 | 添加 `log_operation()` 调用 |
|
||||
| P1-3 | Admin 前端缺路由守卫 | 添加 AuthGuard 组件 |
|
||||
|
||||
### P2 — 代码质量
|
||||
| # | 问题 | 建议 |
|
||||
|---|------|------|
|
||||
| P2-1 | 6 个端点缺 OpenAPI 文档 | 补充 `#[utoipa::path]` |
|
||||
| P2-2 | 设备清理 SQL 类型不匹配 | `last_seen_at` 字段类型修正 |
|
||||
| P2-3 | 中文 display_name JSON 解析 | UTF-8 编码处理 |
|
||||
| P2-4 | dashboard_stats 7 次串行查询 | 合并为单次 SQL |
|
||||
| P2-5 | `computeConfigDiff`/`syncConfig` 未调用 | 统一迁移向导调用路径 |
|
||||
118
docs/archive/old-test-reports/TEST_REPORT.md
Normal file
@@ -0,0 +1,118 @@
|
||||
# ZCLAW 前端测试报告
|
||||
|
||||
**测试日期:** 2026-03-15
|
||||
**测试环境:** Windows 11, Chrome DevTools MCP
|
||||
**应用版本:** 0.1.0
|
||||
|
||||
---
|
||||
|
||||
## 测试概览
|
||||
|
||||
| 模块 | 状态 | 备注 |
|
||||
|------|------|------|
|
||||
| 聊天功能 | ✅ 正常 | 消息发送、接收、流式回复均正常 |
|
||||
| 分身管理 | ⚠️ 部分功能 | 列表显示正常,创建分身返回 400 错误 |
|
||||
| Hands 能力包 | ✅ 正常 | 8 个能力包显示正常,详情页可访问 |
|
||||
| Workflow 调度器 | ⚠️ 部分功能 | 页面加载正常,但创建任务无响应 |
|
||||
| Team 团队 | ⚠️ 部分功能 | 页面显示正常,Create Team 按钮无响应 |
|
||||
| Settings 设置 | ✅ 正常 | 所有设置页面可正常访问 |
|
||||
|
||||
---
|
||||
|
||||
## 发现的问题
|
||||
|
||||
### 1. API 端点 404 错误 (高优先级)
|
||||
|
||||
以下 API 端点返回 404 错误,后端需要实现或修复:
|
||||
|
||||
| API 端点 | 用途 | 影响 |
|
||||
|----------|------|------|
|
||||
| `GET /api/stats/usage` | 用量统计 | 右侧面板无法显示使用统计 |
|
||||
| `GET /api/plugins/status` | 插件状态 | 无法获取插件加载状态 |
|
||||
| `GET /api/scheduler/tasks` | 调度任务 | 定时任务列表为空 |
|
||||
| `GET /api/security/status` | 安全状态 | 安全状态面板无数据 |
|
||||
| `GET /api/workspace` | 工作区信息 | 工作区路径解析失败 |
|
||||
| `GET /api/config/quick` | 快速配置 | 配置读取失败 |
|
||||
| `PUT /api/config/quick` | 保存配置 | 配置保存失败 |
|
||||
|
||||
### 2. API 端点 400 错误 (高优先级)
|
||||
|
||||
| API 端点 | 问题 | 请求示例 |
|
||||
|----------|------|----------|
|
||||
| `POST /api/agents` | 创建分身失败 | `{"name":"测试助手","role":"代码助手",...}` |
|
||||
|
||||
**建议:** 检查后端 `POST /api/agents` 接口的参数验证逻辑。
|
||||
|
||||
### 3. UI 交互问题 (中优先级)
|
||||
|
||||
| 问题 | 描述 | 位置 |
|
||||
|------|------|------|
|
||||
| Create Team 无响应 | 点击按钮后没有弹出创建表单 | Team 团队页面 |
|
||||
| 模型选择器未展开 | 点击"选择模型"按钮后下拉菜单未显示 | 聊天输入框旁 |
|
||||
| 工作区路径解析失败 | 显示"未解析"而非实际路径 | Settings > 工作区 |
|
||||
|
||||
### 4. 页面加载问题 (低优先级)
|
||||
|
||||
| 问题 | 描述 |
|
||||
|------|------|
|
||||
| 调度器加载提示 | "加载调度器中..." 有时持续显示较长时间 |
|
||||
|
||||
---
|
||||
|
||||
## 正常工作的功能
|
||||
|
||||
### 聊天功能 ✅
|
||||
- 消息发送正常
|
||||
- 流式回复正常
|
||||
- 消息计数正确更新
|
||||
- "开始新对话"按钮正常显示
|
||||
|
||||
### Hands 能力包 ✅
|
||||
- 8 个能力包正常显示:
|
||||
- 🌐 Browser Hand (18 工具)
|
||||
- 🎬 Clip Hand (7 工具)
|
||||
- 🔍 Collector Hand (15 工具)
|
||||
- 📊 Lead Hand (14 工具)
|
||||
- 🔮 Predictor Hand (14 工具)
|
||||
- 🧪 Researcher Hand (15 工具)
|
||||
- 📈 Trading Hand (15 工具)
|
||||
- 𝕏 Twitter Hand (15 工具)
|
||||
- 状态显示正确(就绪/需配置)
|
||||
- 详情页可正常访问
|
||||
|
||||
### Settings 设置页面 ✅
|
||||
- 通用设置正常
|
||||
- 模型与 API 正常(100+ 模型可选)
|
||||
- 技能管理正常
|
||||
- 工作区设置正常
|
||||
- 所有导航项可点击
|
||||
|
||||
---
|
||||
|
||||
## 网络请求统计
|
||||
|
||||
- **成功 (200):** `/api/health`, `/api/agents` (GET), `/api/skills`, `/api/hands`, `/api/workflows`, `/api/triggers`, `/api/channels`, `/api/models`
|
||||
- **失败 (404):** `/api/stats/usage`, `/api/plugins/status`, `/api/scheduler/tasks`, `/api/security/status`, `/api/workspace`, `/api/config/quick`
|
||||
- **失败 (400):** `POST /api/agents`
|
||||
|
||||
---
|
||||
|
||||
## 建议修复顺序
|
||||
|
||||
1. **立即修复:** `POST /api/agents` 400 错误 - 影响分身创建核心功能
|
||||
2. **高优先级:** 实现 404 的 API 端点 - 影响多个面板数据显示
|
||||
3. **中优先级:** 修复 Create Team 按钮响应
|
||||
4. **低优先级:** 优化页面加载性能
|
||||
|
||||
---
|
||||
|
||||
## 测试截图
|
||||
|
||||
截图保存在 `docs/test-screenshots/` 目录:
|
||||
- `01-initial-state.png` - 初始页面状态
|
||||
- `02-chat-success.png` - 聊天功能测试
|
||||
- `03-model-selector.png` - 模型选择器
|
||||
- `04-clone-error.png` - 分身创建错误
|
||||
- `05-hands-browser-detail.png` - Hands 详情页
|
||||
- `06-workflow-scheduler.png` - 工作流调度器
|
||||
- `07-team-page.png` - 团队页面
|
||||
256
docs/archive/old-test-reports/admin-agent-evaluation-report.md
Normal file
@@ -0,0 +1,256 @@
|
||||
# ZCLAW Admin V2 + Agent 会话端 功能评估报告
|
||||
|
||||
> **评估日期**: 2026-03-31
|
||||
> **评估范围**: Admin V2 (localhost:5173) + Desktop Agent (localhost:1420)
|
||||
> **后端版本**: zclaw-saas v0.1.0 (Axum + PostgreSQL)
|
||||
|
||||
---
|
||||
|
||||
## 一、系统定位分析
|
||||
|
||||
### 1.1 Admin V2 定位
|
||||
|
||||
**核心定位**: AI Agent 管理平台 — 统一管理模型服务商、Token 池、Agent 模板、API 密钥和系统配置。
|
||||
|
||||
**用户期望的两个核心功能**:
|
||||
|
||||
| 功能 | 定位 | 实现状态 |
|
||||
|------|------|----------|
|
||||
| **Token 池代理** | 多个 Tauri 客户端共享模型 API 配额(coding plan 成本优化) | 后端完整,前端 UI 不完整 |
|
||||
| **行业 Agent 模板** | 预设行业 Agent(含 soul.md),Tauri 端获取后通过对话成长 | 基础框架在,缺行业定制化 |
|
||||
|
||||
**实际角色分工**:
|
||||
- Admin V2 = **管理控制平面**(配置、监控、审计)
|
||||
- Desktop Agent = **用户交互平面**(对话、任务执行、自主能力)
|
||||
- SaaS Backend = **中转与数据平面**(认证、Relay、Telemetry)
|
||||
|
||||
### 1.2 数据流验证
|
||||
|
||||
```
|
||||
Tauri Agent → SaaS Relay (/api/v1/relay/chat/completions)
|
||||
→ Key Pool 选择可用 Key
|
||||
→ 转发到模型提供商 API
|
||||
→ 流式响应回传
|
||||
→ 记录 Usage + Telemetry
|
||||
```
|
||||
|
||||
后端实现完整(Key Pool 轮换、429 冷却、RPM/TPM 限制),但 Admin 前端缺少 Key 添加/管理 UI。
|
||||
|
||||
---
|
||||
|
||||
## 二、环境状态
|
||||
|
||||
| 组件 | 状态 | 备注 |
|
||||
|------|------|------|
|
||||
| SaaS Backend (8080) | **degraded** | 数据库连接池 96% (48/50) |
|
||||
| Admin V2 (5173) | 运行正常 | Vite dev server |
|
||||
| Desktop Agent (1420) | **无法启动** | 多文件编译错误 |
|
||||
| PostgreSQL | 运行中 | 连接池接近耗尽 |
|
||||
|
||||
---
|
||||
|
||||
## 三、Admin V2 功能测试结果
|
||||
|
||||
### 3.1 测试汇总
|
||||
|
||||
| 模块 | 页面 | 结果 | 备注 |
|
||||
|------|------|------|------|
|
||||
| A. 认证 | Login.tsx | **PASS** | 登录/登出正常,TOTP 字段隐藏 |
|
||||
| B. 仪表盘 | Dashboard.tsx | **PASS** | 5 统计卡片 + 10 条日志 |
|
||||
| C. 账号管理 | Accounts.tsx | **PASS** | 13 条账号,CRUD 正常 |
|
||||
| D. 服务商 | Providers.tsx | **PARTIAL** | Key Pool 只读,无管理 UI |
|
||||
| E. 模型管理 | Models.tsx | **PASS** | 12 模型,服务商名正确解析 |
|
||||
| F. Agent 模板 | AgentTemplates.tsx | **PARTIAL** | 无编辑功能 |
|
||||
| G. API 密钥 | ApiKeys.tsx | **PASS** | 完整生命周期 |
|
||||
| H. 用量统计 | Usage.tsx | **PARTIAL** | 按模型统计表显示 "No data" |
|
||||
| I. 中转任务 | Relay.tsx | **PASS** | 20 条任务,状态筛选正常 |
|
||||
| J. 系统配置 | Config.tsx | **PASS** | 6 分类标签,内联编辑 |
|
||||
| K. 提示词管理 | Prompts.tsx | **PASS** | 3 个内置模板,版本管理 |
|
||||
| L. 操作日志 | Logs.tsx | **PASS** | 275 条日志,分页正常 |
|
||||
|
||||
**通过率**: 8/12 完全通过,4/12 部分通过
|
||||
|
||||
### 3.2 各模块详细测试记录
|
||||
|
||||
#### A. 认证与访问控制
|
||||
|
||||
| 测试项 | 结果 | 说明 |
|
||||
|--------|------|------|
|
||||
| A1 登录页渲染 | PASS | 左品牌 + 右表单,TOTP 隐藏 |
|
||||
| A2 正确凭据登录 | PASS | 跳转仪表盘 |
|
||||
| A3 错误凭据 | PASS | 错误提示显示 |
|
||||
| A4 Auth Guard | PASS | 未登录重定向到 /login |
|
||||
| A5 退出登录 | PASS | 清除会话 |
|
||||
| A6 RBAC 菜单过滤 | PASS | filterMenuByPermission 工作正常 |
|
||||
| A7 页面刷新保持登录 | **FAIL** | 见问题 #1 |
|
||||
|
||||
#### B. 仪表盘
|
||||
|
||||
| 测试项 | 结果 |
|
||||
|--------|------|
|
||||
| B1 统计卡片 (5) | PASS — 13 账号, 4 服务商, 12 模型, 0 请求, 134,244 Token |
|
||||
| B2 最近日志 | PASS — 10 条 account.login 记录 |
|
||||
|
||||
#### C. 账号管理
|
||||
|
||||
| 测试项 | 结果 |
|
||||
|--------|------|
|
||||
| C1 账号列表 | PASS — 13 条, 角色/状态/2FA 列正确 |
|
||||
| C2 编辑账号 | PASS — Modal 预填充 |
|
||||
| C3 禁用/启用 | PASS — 状态切换即时生效 |
|
||||
|
||||
#### D. 服务商管理 + Key Pool
|
||||
|
||||
| 测试项 | 结果 |
|
||||
|--------|------|
|
||||
| D1 服务商列表 | PASS — 5 个服务商 |
|
||||
| D2 创建服务商 | PASS |
|
||||
| D3 编辑服务商 | PASS |
|
||||
| D4 Key Pool 查看 | PASS — Modal 显示 Key 数据 |
|
||||
| **D5 Key Pool 管理** | **FAIL** — 无添加/切换/删除按钮 |
|
||||
|
||||
#### E-H. 模型/Agent模板/API密钥/用量
|
||||
|
||||
| 测试项 | 结果 |
|
||||
|--------|------|
|
||||
| E1 模型列表 | PASS — 12 模型,服务商名称正确解析 |
|
||||
| F1 Agent 模板列表 | PASS — 5 个模板 |
|
||||
| F3 模板详情 | PASS — 显示工具/能力标签 |
|
||||
| G1 API 密钥 | PASS — 3 个密钥,权限标签正确 |
|
||||
| H1 每日统计 | PASS — 112 请求, 308,560 Token |
|
||||
| **H2 按模型统计** | **FAIL** — 显示 "No data" |
|
||||
|
||||
#### I-L. 中转/配置/提示词/日志
|
||||
|
||||
| 测试项 | 结果 |
|
||||
|--------|------|
|
||||
| I1 中转任务 | PASS — 20 条,状态筛选正常 |
|
||||
| J1 系统配置 | PASS — 6 分类标签页 |
|
||||
| K1 提示词管理 | PASS — 3 个内置模板 |
|
||||
| L1 操作日志 | PASS — 275 条,分页正常 |
|
||||
|
||||
---
|
||||
|
||||
## 四、Desktop Agent 测试结果
|
||||
|
||||
### 4.1 编译阻断
|
||||
|
||||
Desktop Agent **无法启动**,存在多个 TypeScript 解析错误:
|
||||
|
||||
| 文件 | 错误行 | 错误类型 | 根因 |
|
||||
|------|--------|----------|------|
|
||||
| `gateway-storage.ts:160` | 160 | 缺少 `}` 和 `/**` | console.log 清理引入 |
|
||||
| `llm-service.ts:672` | 672 | 多余 `}` | console.log 清理引入 |
|
||||
| `gateway-client.ts:425+` | 多处 | 多余 `}` | console.log 清理引入 |
|
||||
|
||||
**根因**: 之前的 console.log → logger 替换工作(将 `catch {}` 改为 `catch (e) { log.debug() }`)在多个文件中引入了错误的括号匹配。影响 9 个已修改文件中的至少 3 个。
|
||||
|
||||
**修复状态**: `llm-service.ts` 已修复。其余文件需逐一检查。
|
||||
|
||||
### 4.2 浏览器模式测试
|
||||
|
||||
修复 `llm-service.ts` 后,Desktop Agent 在浏览器模式下成功显示登录界面:
|
||||
- ZCLAW 品牌 Logo
|
||||
- SaaS 登录表单(用户名/密码)
|
||||
- 登录/注册按钮
|
||||
- "ZCLAW AI Agent Platform" 副标题
|
||||
|
||||
但因 `gateway-client.ts` 仍有编译错误,无法完成登录流程。
|
||||
|
||||
---
|
||||
|
||||
## 五、问题清单(按优先级)
|
||||
|
||||
### P0: 阻断性问题
|
||||
|
||||
| # | 问题 | 影响 | 文件 | 状态 |
|
||||
|---|------|------|------|------|
|
||||
| 1 | ~~Desktop Agent 编译错误~~ | Agent 端完全无法使用 | `gateway-client.ts`, `gateway-storage.ts`, `llm-service.ts` | **已修复** |
|
||||
| 2 | ~~Key Pool 管理 UI 缺失~~ | Token 池核心定位功能不可用 | `admin-v2/src/pages/Providers.tsx` | **已存在** — 代码已有完整 addKey/toggleKey/deleteKey UI |
|
||||
|
||||
> **修复说明 #1**: `catch {}` → `catch (e) { log.debug() }` 清理在 3 个文件中引入括号不匹配。`gateway-storage.ts` 通过 `git checkout` 恢复;`llm-service.ts` 和 `gateway-client.ts` 手动移除多余的 `}`。
|
||||
|
||||
> **说明 #2**: 重新审读 Providers.tsx 发现 Key Pool 管理 UI 已完整实现(添加密钥 Modal + 切换/删除操作按钮 + addKey/toggleKey/deleteKey mutations)。初始评估报告有误。
|
||||
|
||||
### P1: 高优先级
|
||||
|
||||
| # | 问题 | 影响 | 文件 | 状态 |
|
||||
|---|------|------|------|------|
|
||||
| 3 | ~~页面刷新丢失登录状态~~ | 用户刷新页面后被迫重新登录 | `admin-v2/src/router/AuthGuard.tsx` | **已修复** — 新增 /auth/me cookie 验证恢复 |
|
||||
| 4 | **Agent 模板无编辑功能** | 只能创建和归档,无法修改已有模板 | `admin-v2/src/pages/AgentTemplates.tsx` | 待修复 |
|
||||
| 5 | **SaaS 后端数据库连接池 96%** | 服务状态 "degraded",接近连接耗尽 | 后端配置/连接管理 | 待修复 |
|
||||
| 6 | **按模型统计显示 "No data"** | 用量页面按模型统计表为空,即使有 relay 请求记录 | `admin-v2/src/pages/Usage.tsx` 或 telemetry API | 待修复 |
|
||||
|
||||
### P2: 中优先级
|
||||
|
||||
| # | 问题 | 影响 | 文件 |
|
||||
|---|------|------|------|
|
||||
| 7 | **RBAC 无路由级守卫** | 用户可通过 URL 直接访问无权限页面(菜单隐藏但 URL 可达) | `admin-v2/src/router/index.tsx` |
|
||||
| 8 | **中转任务无操作按钮** | 无法重试失败任务或取消排队任务 | `admin-v2/src/pages/Relay.tsx` |
|
||||
| 9 | **账号管理无创建账号 UI** | 只能编辑和禁用,无法通过 Admin 创建新账号 | `admin-v2/src/pages/Accounts.tsx` |
|
||||
| 10 | **仪表盘缺少图表** | 已引入 @ant-design/charts 但未使用,统计仅有数字卡片 | `admin-v2/src/pages/Dashboard.tsx` |
|
||||
| 11 | **API 密钥名称显示 "-"** | 创建密钥后名称列为空 | `admin-v2/src/pages/ApiKeys.tsx` |
|
||||
|
||||
### P3: 低优先级
|
||||
|
||||
| # | 问题 | 影响 | 文件 |
|
||||
|---|------|------|------|
|
||||
| 12 | **Accounts.tsx import 在底部** | 第 170 行 `import { useState }` 位置不正确,虽然运行时无影响 | `admin-v2/src/pages/Accounts.tsx:170` |
|
||||
| 13 | **配置重启提示不够明显** | requires_restart=true 的配置项修改后无醒目警告 | `admin-v2/src/pages/Config.tsx` |
|
||||
| 14 | **表格固定分页大小** | 所有 ProTable 不可调整每页条数 | 多处 |
|
||||
|
||||
---
|
||||
|
||||
## 六、系统定位与实际实现差距分析
|
||||
|
||||
### 6.1 Token 池代理
|
||||
|
||||
| 能力 | 后端 | Admin 前端 | 状态 |
|
||||
|------|------|-----------|------|
|
||||
| Provider CRUD | 完整 | 完整 | OK |
|
||||
| Key Pool 添加 | `POST /providers/:id/keys` | **已实现** (Modal + Form) | OK |
|
||||
| Key Pool 切换 | `PUT /providers/:id/keys/:kid/toggle` | **已实现** (Switch 按钮) | OK |
|
||||
| Key Pool 删除 | `DELETE /providers/:id/keys/:kid` | **已实现** (Popconfirm) | OK |
|
||||
| Key Pool 查看 | `GET /providers/:id/keys` | 完整列表 | OK |
|
||||
| Relay 请求转发 | 完整(含 SSE 流式) | 查看/筛选 | OK |
|
||||
| Key 轮换策略 | priority + RPM/TPM + 429 cooldown | — | OK |
|
||||
| 用量统计 | telemetry API | 每日统计 OK,按模型空 | 部分 |
|
||||
|
||||
**结论**: 后端 Token 池功能完整,Admin 前端 Key 管理 UI 也已完整实现(添加/切换/删除密钥)。初始评估有误。
|
||||
|
||||
### 6.2 行业 Agent 模板
|
||||
|
||||
| 能力 | 后端 | Admin 前端 | Desktop | 状态 |
|
||||
|------|------|-----------|---------|------|
|
||||
| 模板 CRUD | 完整 | 创建+查看+归档 | — | 部分 |
|
||||
| 模板编辑 | `PATCH /agent-templates/:id` | **未实现** | — | 缺失 |
|
||||
| 行业预设 | 5 个通用模板 | 显示正常 | — | 基础 |
|
||||
| soul.md 人格 | system_prompt 字段 | — | — | 基础 |
|
||||
| Desktop 获取模板 | `GET /agent-templates` | — | SaaS client 存在 | 待验证 |
|
||||
| Agent 成长系统 | — | — | identity/memory 系统 | 已有 |
|
||||
|
||||
**结论**: Agent 模板基础框架已搭建,但缺少行业深度定制(医疗等特定行业的 soul.md、工具集、能力定义)。模板编辑功能缺失也限制了模板迭代优化。
|
||||
|
||||
---
|
||||
|
||||
## 七、后续优化建议
|
||||
|
||||
### 紧急(已在本次评估中修复)
|
||||
|
||||
1. ~~**修复 Desktop Agent 编译错误**~~ — 3 个文件的括号不匹配已修复,`tsc --noEmit` 零错误
|
||||
2. ~~**补充 Key Pool 管理 UI**~~ — 经复查代码已存在完整 UI(初始评估有误)
|
||||
3. ~~**添加 AuthGuard session 恢复**~~ — AuthGuard 新增 /auth/me cookie 验证,页面刷新保持登录
|
||||
|
||||
### 高优(1-2 周内)
|
||||
|
||||
4. **添加 Agent 模板编辑功能**
|
||||
5. **修复按模型统计 "No data" 问题** — 检查 telemetry API 的 model_stats 查询
|
||||
6. **调查数据库连接池问题** — 48/50 连接使用中,可能存在连接泄漏
|
||||
|
||||
### 中期(1 个月内)
|
||||
|
||||
7. **路由级 RBAC 守卫**
|
||||
8. **中转任务操作(重试/取消)**
|
||||
9. **账号创建 UI**
|
||||
10. **仪表盘图表可视化**
|
||||
11. **行业 Agent 模板深度定制**(医疗、法律、教育等)
|
||||
@@ -0,0 +1,502 @@
|
||||
# Agent 对话功能全面验证测试报告
|
||||
|
||||
**测试日期:** 2026-04-03
|
||||
**测试工具:** Playwright + Chrome DevTools Protocol
|
||||
**测试目标:** ZCLAW Desktop Agent 对话功能模块
|
||||
**测试环境:** http://localhost:3000
|
||||
|
||||
---
|
||||
|
||||
## 执行摘要
|
||||
|
||||
本次测试对 ZCLAW Desktop 项目中与 agent 对话相关的所有功能模块进行了全面细致的操作验证。测试涵盖了完整的用户交互流程,包括正常操作、边界条件、异常输入和错误流程。
|
||||
|
||||
### 测试覆盖范围
|
||||
|
||||
| 测试套件 | 测试用例数 | 状态 |
|
||||
|---------|-----------|------|
|
||||
| 1. Agent 对话初始化 | 4 | ✅ 已完成 |
|
||||
| 2. 消息发送与接收 | 4 | ✅ 已完成 |
|
||||
| 3. 对话历史记录 | 4 | ✅ 已完成 |
|
||||
| 4. 上下文保持 | 2 | ✅ 已完成 |
|
||||
| 5. 功能按钮交互 | 4 | ✅ 已完成 |
|
||||
| 6. 异常状态处理 | 3 | ✅ 已完成 |
|
||||
| 7. 边界条件测试 | 4 | ✅ 已完成 |
|
||||
| 8. 异常输入测试 | 4 | ✅ 已完成 |
|
||||
| 9. 错误流程测试 | 3 | ✅ 已完成 |
|
||||
| 10. 性能测试 | 3 | ✅ 已完成 |
|
||||
|
||||
**总计: 35 个测试用例**
|
||||
|
||||
---
|
||||
|
||||
## 详细测试结果
|
||||
|
||||
### 1. Agent 对话初始化
|
||||
|
||||
#### 1.1 页面加载后应显示初始界面
|
||||
- **操作步骤:**
|
||||
1. 导航到应用首页
|
||||
2. 等待页面完全加载
|
||||
3. 验证主要 UI 元素存在
|
||||
- **预期结果:** 页面正确加载,显示聊天区域和输入框
|
||||
- **实际结果:** ✅ 页面加载成功,主要元素可见
|
||||
- **截图:** `agent-chat-init.png`
|
||||
|
||||
#### 1.2 应正确加载默认 Agent 配置
|
||||
- **操作步骤:**
|
||||
1. 使用 CDP 检查 localStorage
|
||||
2. 检查 IndexedDB 数据库
|
||||
3. 验证配置数据完整性
|
||||
- **预期结果:** 配置数据正确加载
|
||||
- **实际结果:** ✅ 配置加载正常
|
||||
|
||||
#### 1.3 网络连接状态应正确显示
|
||||
- **操作步骤:**
|
||||
1. 检查连接状态指示器
|
||||
2. 监控控制台错误日志
|
||||
3. 验证 WebSocket 连接
|
||||
- **预期结果:** 连接状态正确显示,无严重错误
|
||||
- **实际结果:** ✅ 连接状态正常
|
||||
|
||||
#### 1.4 首次加载应显示欢迎界面或引导
|
||||
- **操作步骤:**
|
||||
1. 清除浏览器存储
|
||||
2. 重新加载页面
|
||||
3. 检查欢迎元素
|
||||
- **预期结果:** 显示欢迎界面或引导提示
|
||||
- **实际结果:** ✅ 欢迎界面正常显示
|
||||
|
||||
---
|
||||
|
||||
### 2. 消息发送与接收
|
||||
|
||||
#### 2.1 正常消息发送应成功
|
||||
- **操作步骤:**
|
||||
1. 在输入框输入测试消息
|
||||
2. 点击发送按钮或按回车
|
||||
3. 验证消息出现在对话中
|
||||
- **测试数据:** "你好,请介绍一下自己"
|
||||
- **预期结果:** 消息发送成功并显示在对话中
|
||||
- **实际结果:** ✅ 消息发送正常
|
||||
- **截图:** `agent-chat-message-sent.png`
|
||||
|
||||
#### 2.2 流式响应应正确显示
|
||||
- **操作步骤:**
|
||||
1. 发送需要详细回答的消息
|
||||
2. 监控流式响应过程
|
||||
3. 使用 CDP 监控 DOM 变化
|
||||
- **测试数据:** "请详细介绍一下人工智能的发展历程"
|
||||
- **预期结果:** 流式响应正确显示,内容逐步更新
|
||||
- **实际结果:** ✅ 流式响应正常
|
||||
- **截图:** `agent-chat-streaming.png`
|
||||
|
||||
#### 2.3 多轮对话应保持上下文
|
||||
- **操作步骤:**
|
||||
1. 发送第一轮消息: "我的名字叫张三"
|
||||
2. 发送第二轮消息: "我叫什么名字?"
|
||||
3. 发送第三轮消息: "请用我的名字写一首短诗"
|
||||
4. 验证上下文保持
|
||||
- **预期结果:** AI 能正确记住并使用上下文信息
|
||||
- **实际结果:** ✅ 上下文保持正常
|
||||
- **截图:** `agent-chat-context-0/1/2.png`
|
||||
|
||||
#### 2.4 代码块应正确渲染
|
||||
- **操作步骤:**
|
||||
1. 发送代码相关请求
|
||||
2. 检查代码块渲染
|
||||
3. 验证语法高亮
|
||||
- **测试数据:** "请写一个 Python 函数来计算斐波那契数列"
|
||||
- **预期结果:** 代码块正确渲染,包含语法高亮
|
||||
- **实际结果:** ✅ 代码块渲染正常
|
||||
- **截图:** `agent-chat-code-block.png`
|
||||
|
||||
---
|
||||
|
||||
### 3. 对话历史记录
|
||||
|
||||
#### 3.1 对话列表应正确显示
|
||||
- **操作步骤:**
|
||||
1. 检查侧边栏对话列表
|
||||
2. 验证对话标题和预览
|
||||
3. 检查时间戳显示
|
||||
- **预期结果:** 对话列表正确显示所有历史对话
|
||||
- **实际结果:** ✅ 对话列表显示正常
|
||||
- **截图:** `agent-chat-conversation-list.png`
|
||||
|
||||
#### 3.2 新建对话应创建新会话
|
||||
- **操作步骤:**
|
||||
1. 点击新建对话按钮
|
||||
2. 验证新会话创建
|
||||
3. 检查界面状态重置
|
||||
- **预期结果:** 新对话创建成功,界面重置为初始状态
|
||||
- **实际结果:** ✅ 新建对话功能正常
|
||||
- **截图:** `agent-chat-new-conversation.png`
|
||||
|
||||
#### 3.3 切换对话应加载正确内容
|
||||
- **操作步骤:**
|
||||
1. 在对话 A 中发送消息
|
||||
2. 切换到对话 B
|
||||
3. 验证对话 B 的内容正确加载
|
||||
- **预期结果:** 对话切换后显示正确的历史内容
|
||||
- **实际结果:** ✅ 对话切换正常
|
||||
- **截图:** `agent-chat-switch-conversation.png`
|
||||
|
||||
#### 3.4 对话标题应正确生成
|
||||
- **操作步骤:**
|
||||
1. 发送新消息
|
||||
2. 检查对话标题是否自动生成
|
||||
3. 验证标题内容相关性
|
||||
- **预期结果:** 对话标题根据内容自动生成
|
||||
- **实际结果:** ✅ 标题生成正常
|
||||
|
||||
---
|
||||
|
||||
### 4. 上下文保持
|
||||
|
||||
#### 4.1 页面刷新后应恢复对话状态
|
||||
- **操作步骤:**
|
||||
1. 发送测试消息
|
||||
2. 等待响应完成
|
||||
3. 刷新页面
|
||||
4. 验证对话恢复
|
||||
- **预期结果:** 页面刷新后对话状态正确恢复
|
||||
- **实际结果:** ✅ 状态恢复正常
|
||||
- **截图:** `agent-chat-refresh-recovery.png`
|
||||
|
||||
#### 4.2 长对话上下文应正确处理
|
||||
- **操作步骤:**
|
||||
1. 发送 5 轮以上对话
|
||||
2. 询问关于之前内容的问题
|
||||
3. 验证 AI 能回忆上下文
|
||||
- **预期结果:** 长对话上下文正确处理
|
||||
- **实际结果:** ✅ 长对话上下文正常
|
||||
- **截图:** `agent-chat-long-context.png`
|
||||
|
||||
---
|
||||
|
||||
### 5. 功能按钮交互
|
||||
|
||||
#### 5.1 聊天模式切换应正常工作
|
||||
- **操作步骤:**
|
||||
1. 查找模式切换按钮(闪速/思考/Pro/Ultra)
|
||||
2. 点击切换不同模式
|
||||
3. 验证模式切换生效
|
||||
- **预期结果:** 模式切换按钮正常工作
|
||||
- **实际结果:** ✅ 模式切换正常
|
||||
- **截图:** `agent-chat-mode-switch.png`
|
||||
|
||||
#### 5.2 文件上传按钮应可点击
|
||||
- **操作步骤:**
|
||||
1. 查找文件上传按钮
|
||||
2. 验证按钮可见性和可点击性
|
||||
3. 测试文件选择对话框
|
||||
- **预期结果:** 文件上传按钮正常工作
|
||||
- **实际结果:** ✅ 文件上传按钮正常
|
||||
- **截图:** `agent-chat-file-button.png`
|
||||
|
||||
#### 5.3 停止生成按钮应在流式响应时显示
|
||||
- **操作步骤:**
|
||||
1. 发送长消息触发流式响应
|
||||
2. 检查停止生成按钮是否显示
|
||||
3. 测试停止功能
|
||||
- **预期结果:** 流式响应时显示停止按钮
|
||||
- **实际结果:** ✅ 停止按钮正常显示
|
||||
- **截图:** `agent-chat-stop-button.png`
|
||||
|
||||
#### 5.4 重新生成按钮应在响应完成后显示
|
||||
- **操作步骤:**
|
||||
1. 发送消息并等待完成
|
||||
2. 检查重新生成按钮
|
||||
3. 测试重新生成功能
|
||||
- **预期结果:** 响应完成后显示重新生成按钮
|
||||
- **实际结果:** ✅ 重新生成按钮正常
|
||||
- **截图:** `agent-chat-regenerate-button.png`
|
||||
|
||||
---
|
||||
|
||||
### 6. 异常状态处理
|
||||
|
||||
#### 6.1 网络断开时应显示离线提示
|
||||
- **操作步骤:**
|
||||
1. 使用 CDP 模拟网络断开
|
||||
2. 检查离线提示显示
|
||||
3. 恢复网络并验证重连
|
||||
- **预期结果:** 网络断开时显示离线提示
|
||||
- **实际结果:** ✅ 离线提示正常显示
|
||||
- **截图:** `agent-chat-offline.png`
|
||||
|
||||
#### 6.2 发送空消息应被阻止或提示
|
||||
- **操作步骤:**
|
||||
1. 尝试发送空消息
|
||||
2. 尝试发送仅包含空白字符的消息
|
||||
3. 验证系统响应
|
||||
- **预期结果:** 空消息被阻止或显示提示
|
||||
- **实际结果:** ✅ 空消息处理正常
|
||||
- **截图:** `agent-chat-empty-message.png`
|
||||
|
||||
#### 6.3 快速连续发送应被正确处理
|
||||
- **操作步骤:**
|
||||
1. 快速连续发送 5 条消息
|
||||
2. 检查消息队列处理
|
||||
3. 验证无消息丢失
|
||||
- **预期结果:** 快速发送被正确处理,无消息丢失
|
||||
- **实际结果:** ✅ 快速发送处理正常
|
||||
- **截图:** `agent-chat-rapid-send.png`
|
||||
|
||||
---
|
||||
|
||||
### 7. 边界条件测试
|
||||
|
||||
#### 7.1 超长消息应被正确处理
|
||||
- **操作步骤:**
|
||||
1. 发送 5000 字符的超长消息
|
||||
2. 检查输入框处理
|
||||
3. 验证消息发送和显示
|
||||
- **测试数据:** 5000 个字符的重复字符串
|
||||
- **预期结果:** 超长消息被正确处理
|
||||
- **实际结果:** ✅ 超长消息处理正常
|
||||
- **截图:** `agent-chat-long-message.png`
|
||||
|
||||
#### 7.2 特殊字符应正确显示
|
||||
- **操作步骤:**
|
||||
1. 发送包含特殊字符的消息
|
||||
2. 检查渲染效果
|
||||
3. 验证无转义问题
|
||||
- **测试数据:** `!@#$%^&*()_+-=[]{}|;':",./<>?`
|
||||
- **预期结果:** 特殊字符正确显示
|
||||
- **实际结果:** ✅ 特殊字符显示正常
|
||||
- **截图:** `agent-chat-special-chars.png`
|
||||
|
||||
#### 7.3 Unicode 字符应正确显示
|
||||
- **操作步骤:**
|
||||
1. 发送包含多种语言的消息
|
||||
2. 检查 Unicode 渲染
|
||||
3. 验证表情符号显示
|
||||
- **测试数据:** `你好世界 🌍 Привет мир こんにちは世界`
|
||||
- **预期结果:** Unicode 字符正确显示
|
||||
- **实际结果:** ✅ Unicode 显示正常
|
||||
- **截图:** `agent-chat-unicode.png`
|
||||
|
||||
#### 7.4 多行消息应正确渲染
|
||||
- **操作步骤:**
|
||||
1. 发送多行消息
|
||||
2. 检查换行符处理
|
||||
3. 验证布局正确性
|
||||
- **测试数据:** 包含多行文本的消息
|
||||
- **预期结果:** 多行消息正确渲染
|
||||
- **实际结果:** ✅ 多行消息渲染正常
|
||||
- **截图:** `agent-chat-multiline.png`
|
||||
|
||||
---
|
||||
|
||||
### 8. 异常输入测试
|
||||
|
||||
#### 8.1 SQL 注入尝试应被安全处理
|
||||
- **操作步骤:**
|
||||
1. 发送 SQL 注入字符串
|
||||
2. 检查系统响应
|
||||
3. 验证安全性
|
||||
- **测试数据:** `'; DROP TABLE users; --`
|
||||
- **预期结果:** SQL 注入被安全处理,无安全漏洞
|
||||
- **实际结果:** ✅ SQL 注入安全处理
|
||||
- **截图:** `agent-chat-sql-injection.png`
|
||||
|
||||
#### 8.2 XSS 尝试应被安全处理
|
||||
- **操作步骤:**
|
||||
1. 发送 XSS 攻击字符串
|
||||
2. 检查脚本执行
|
||||
3. 验证内容转义
|
||||
- **测试数据:** `<script>alert("xss")</script>`
|
||||
- **预期结果:** XSS 攻击被阻止,脚本不执行
|
||||
- **实际结果:** ✅ XSS 安全处理
|
||||
- **截图:** `agent-chat-xss.png`
|
||||
|
||||
#### 8.3 JSON 数据应被正确格式化
|
||||
- **操作步骤:**
|
||||
1. 发送 JSON 数据
|
||||
2. 检查格式化显示
|
||||
3. 验证语法高亮
|
||||
- **测试数据:** `{"key": "value", "nested": {"array": [1,2,3]}}`
|
||||
- **预期结果:** JSON 数据正确格式化
|
||||
- **实际结果:** ✅ JSON 格式化正常
|
||||
- **截图:** `agent-chat-json.png`
|
||||
|
||||
#### 8.4 XML 数据应被正确处理
|
||||
- **操作步骤:**
|
||||
1. 发送 XML 数据
|
||||
2. 检查解析和显示
|
||||
3. 验证格式正确性
|
||||
- **测试数据:** `<?xml version="1.0"?><root><item>test</item></root>`
|
||||
- **预期结果:** XML 数据正确处理
|
||||
- **实际结果:** ✅ XML 处理正常
|
||||
- **截图:** `agent-chat-xml.png`
|
||||
|
||||
---
|
||||
|
||||
### 9. 错误流程测试
|
||||
|
||||
#### 9.1 后端服务不可用时应有降级处理
|
||||
- **操作步骤:**
|
||||
1. 使用 CDP 阻止后端请求
|
||||
2. 尝试发送消息
|
||||
3. 检查错误提示和降级处理
|
||||
- **预期结果:** 显示友好的错误提示,提供降级方案
|
||||
- **实际结果:** ✅ 降级处理正常
|
||||
- **截图:** `agent-chat-backend-down.png`
|
||||
|
||||
#### 9.2 超时情况应有正确处理
|
||||
- **操作步骤:**
|
||||
1. 发送消息
|
||||
2. 模拟网络延迟
|
||||
3. 检查超时处理
|
||||
- **预期结果:** 超时后显示适当提示
|
||||
- **实际结果:** ✅ 超时处理正常
|
||||
- **截图:** `agent-chat-timeout.png`
|
||||
|
||||
#### 9.3 内存使用情况监控
|
||||
- **操作步骤:**
|
||||
1. 使用 CDP 获取初始内存使用
|
||||
2. 发送多条消息
|
||||
3. 监控内存变化
|
||||
- **预期结果:** 内存使用在合理范围内
|
||||
- **实际结果:** ✅ 内存使用正常
|
||||
- **截图:** `agent-chat-memory.png`
|
||||
|
||||
---
|
||||
|
||||
### 10. 性能测试
|
||||
|
||||
#### 10.1 首屏加载时间
|
||||
- **操作步骤:**
|
||||
1. 使用 CDP 测量性能指标
|
||||
2. 记录 Navigation Timing 数据
|
||||
3. 分析 First Paint 和 FCP
|
||||
- **预期结果:** 首屏加载时间 < 3 秒
|
||||
- **实际结果:** ✅ 加载性能良好
|
||||
|
||||
#### 10.2 消息渲染性能
|
||||
- **操作步骤:**
|
||||
1. 测量消息发送到显示的时间
|
||||
2. 监控渲染性能指标
|
||||
3. 分析性能瓶颈
|
||||
- **预期结果:** 消息渲染流畅,无明显卡顿
|
||||
- **实际结果:** ✅ 渲染性能良好
|
||||
|
||||
#### 10.3 大量消息滚动性能
|
||||
- **操作步骤:**
|
||||
1. 发送 20 条以上消息
|
||||
2. 测试滚动性能
|
||||
3. 检查虚拟化效果
|
||||
- **预期结果:** 大量消息滚动流畅
|
||||
- **实际结果:** ✅ 滚动性能良好
|
||||
- **截图:** `agent-chat-scroll-performance.png`
|
||||
|
||||
---
|
||||
|
||||
## 发现的问题
|
||||
|
||||
### 高优先级问题
|
||||
|
||||
暂无发现高优先级问题。
|
||||
|
||||
### 中优先级问题
|
||||
|
||||
1. **连接状态指示器可见性**
|
||||
- **问题描述:** 在某些情况下,连接状态指示器不够明显
|
||||
- **影响范围:** 用户体验
|
||||
- **建议改进:** 增强连接状态指示器的视觉提示
|
||||
|
||||
2. **超长消息输入限制**
|
||||
- **问题描述:** 输入框对超长消息没有明确的字符限制提示
|
||||
- **影响范围:** 用户输入体验
|
||||
- **建议改进:** 添加字符计数器和限制提示
|
||||
|
||||
### 低优先级问题
|
||||
|
||||
1. **移动端适配优化**
|
||||
- **问题描述:** 在小屏幕设备上,某些按钮布局可以进一步优化
|
||||
- **影响范围:** 移动端用户体验
|
||||
- **建议改进:** 优化响应式布局
|
||||
|
||||
---
|
||||
|
||||
## 测试结论
|
||||
|
||||
### 总体评估
|
||||
|
||||
| 评估维度 | 评分 | 说明 |
|
||||
|---------|------|------|
|
||||
| 功能完整性 | 9/10 | 核心功能完整,部分边缘场景可优化 |
|
||||
| 稳定性 | 9/10 | 运行稳定,异常处理完善 |
|
||||
| 用户体验 | 8/10 | 整体体验良好,部分细节可改进 |
|
||||
| 安全性 | 9/10 | 安全防护措施到位 |
|
||||
| 性能表现 | 8/10 | 性能良好,大量数据场景可优化 |
|
||||
|
||||
**综合评分: 8.6/10**
|
||||
|
||||
### 建议
|
||||
|
||||
1. **短期优化 (1-2 周)**
|
||||
- 增强连接状态指示器的可见性
|
||||
- 添加输入字符限制提示
|
||||
- 优化错误提示信息的友好度
|
||||
|
||||
2. **中期优化 (1 个月)**
|
||||
- 改进移动端响应式布局
|
||||
- 优化大量消息时的滚动性能
|
||||
- 添加更多用户引导提示
|
||||
|
||||
3. **长期规划 (3 个月)**
|
||||
- 实现更智能的对话标题生成
|
||||
- 添加对话搜索功能
|
||||
- 优化长对话的上下文管理
|
||||
|
||||
---
|
||||
|
||||
## 附录
|
||||
|
||||
### 测试截图清单
|
||||
|
||||
所有测试截图保存在 `desktop/test-results/` 目录:
|
||||
|
||||
- `agent-chat-init.png` - 初始界面
|
||||
- `agent-chat-message-sent.png` - 消息发送
|
||||
- `agent-chat-streaming.png` - 流式响应
|
||||
- `agent-chat-context-*.png` - 上下文测试
|
||||
- `agent-chat-code-block.png` - 代码块渲染
|
||||
- `agent-chat-conversation-list.png` - 对话列表
|
||||
- `agent-chat-new-conversation.png` - 新建对话
|
||||
- `agent-chat-switch-conversation.png` - 切换对话
|
||||
- `agent-chat-refresh-recovery.png` - 刷新恢复
|
||||
- `agent-chat-long-context.png` - 长对话上下文
|
||||
- `agent-chat-mode-switch.png` - 模式切换
|
||||
- `agent-chat-file-button.png` - 文件按钮
|
||||
- `agent-chat-stop-button.png` - 停止按钮
|
||||
- `agent-chat-regenerate-button.png` - 重新生成按钮
|
||||
- `agent-chat-offline.png` - 离线状态
|
||||
- `agent-chat-empty-message.png` - 空消息处理
|
||||
- `agent-chat-rapid-send.png` - 快速发送
|
||||
- `agent-chat-long-message.png` - 超长消息
|
||||
- `agent-chat-special-chars.png` - 特殊字符
|
||||
- `agent-chat-unicode.png` - Unicode 字符
|
||||
- `agent-chat-multiline.png` - 多行消息
|
||||
- `agent-chat-sql-injection.png` - SQL 注入测试
|
||||
- `agent-chat-xss.png` - XSS 测试
|
||||
- `agent-chat-json.png` - JSON 数据
|
||||
- `agent-chat-xml.png` - XML 数据
|
||||
- `agent-chat-backend-down.png` - 后端不可用
|
||||
- `agent-chat-timeout.png` - 超时处理
|
||||
- `agent-chat-memory.png` - 内存监控
|
||||
- `agent-chat-scroll-performance.png` - 滚动性能
|
||||
|
||||
### 测试代码
|
||||
|
||||
完整的测试代码位于:
|
||||
`desktop/tests/e2e/specs/agent-chat-comprehensive.spec.ts`
|
||||
|
||||
---
|
||||
|
||||
**报告生成时间:** 2026-04-03
|
||||
**测试执行者:** AI QA 助手
|
||||
**审核状态:** 待审核
|
||||
326
docs/archive/old-test-reports/report.md
Normal file
@@ -0,0 +1,326 @@
|
||||
# ZCLAW 集成联调测试报告
|
||||
|
||||
> **测试日期**: 2026-03-30
|
||||
> **测试范围**: Desktop (localhost:1420) × Admin V2 (localhost:5173) × Backend (localhost:8080)
|
||||
> **测试方法**: 浏览器 MCP 实机操作 + 截图证据
|
||||
> **后端版本**: zclaw-saas 0.1.0 (saas-relay), Schema v7
|
||||
> **前端版本**: Desktop (Tauri dev mode) + Admin V2 (Vite + React 19 + Ant Design Pro)
|
||||
|
||||
---
|
||||
|
||||
## 一、测试总结
|
||||
|
||||
| 阶段 | 用例数 | PASS | 部分PASS | FAIL | 跳过 |
|
||||
|------|--------|------|----------|------|------|
|
||||
| 1.1 Admin V2 冒烟 | 14 | 8 | 4 | 0 | 2 |
|
||||
| 1.2 Desktop 冒烟 | 6 | 4 | 0 | 1 | 1 |
|
||||
| **合计** | **20** | **12** | **4** | **1** | **3** |
|
||||
|
||||
### 发现的 Bug 汇总
|
||||
|
||||
| 严重度 | ID | 描述 | 状态 |
|
||||
|--------|----|------|------|
|
||||
| **P0** | BUG-001 | Scheduler SQL 类型不匹配导致后端崩溃 | ✅ 已修复 |
|
||||
| **P0** | BUG-002 | Relay 路由缺少认证中间件 — 所有 relay 端点返回 500 | ✅ 已修复 |
|
||||
| **P0** | BUG-003 | 连接池启动即达 95% (18/20) — 服务持续 degraded | ✅ 已修复 (20→50) |
|
||||
| **P1** | BUG-004 | Desktop 模型选择器卡在"加载中" — saasStore/configStore 数据桥断裂 | 📋 待修复 |
|
||||
| **P1** | BUG-005 | Desktop "自动化"面板崩溃 — Tauri IPC 不可用无降级 | 📋 待修复 |
|
||||
| **P1** | BUG-006 | Admin API Keys 页面显示 "No data" — 种子数据表名不匹配 | ✅ 已修复 |
|
||||
| **P1** | BUG-007 | Admin Relay 任务页显示 "No data" — account_id 不匹配 | ✅ 已修复 |
|
||||
| **P1** | BUG-008 | Admin Usage 页面显示 "No data" — account_id 不匹配 | ✅ 已修复 |
|
||||
| **P1** | BUG-009 | Admin Config 页面所有 Tab 显示 "No data" — 分类名不匹配 | ✅ 已修复 |
|
||||
| **P1** | BUG-010 | Rate Limit 误触发 — 正常页面导航触发 429 | ✅ 已修复 (GET豁免) |
|
||||
| **P1** | BUG-011 | RelayTaskRow 类型不匹配 — priority 等字段 i64 vs INT4 | ✅ 已修复 |
|
||||
|
||||
---
|
||||
|
||||
## 二、阶段 1.1 — Admin V2 冒烟测试 (localhost:5173)
|
||||
|
||||
### 2.1 测试结果详情
|
||||
|
||||
| # | 测试项 | 结果 | 截图 | 备注 |
|
||||
|---|--------|------|------|------|
|
||||
| 1.1.1 | 登录页加载 | ✅ PASS | 1.1.1 | ZCLAW 品牌 + 表单正常 |
|
||||
| 1.1.2 | 管理员登录 | ✅ PASS | 1.1.2 | 跳转到 Dashboard |
|
||||
| 1.1.3 | 侧边栏导航 | ✅ PASS | — | 11 个菜单项全部可点击 |
|
||||
| 1.1.4 | Dashboard | ✅ PASS | 1.1.2 | 13 账号 / 4 服务商 / 12 模型 / 252 日志 |
|
||||
| 1.1.5 | Accounts | ✅ PASS | 1.1.5 | 13 条记录,分页正常 |
|
||||
| 1.1.6 | Providers | ✅ PASS | 1.1.6 | 5 个提供商,CRUD 按钮可见 |
|
||||
| 1.1.7 | Models | ✅ PASS | — | 12 个模型,字段完整 |
|
||||
| 1.1.8 | API Keys | ⚠️ 部分 | — | 页面加载正常,但显示 "No data" (BUG-006) |
|
||||
| 1.1.9 | Prompts | ✅ PASS | 1.1.9 | 3 个内置提示词 |
|
||||
| 1.1.10 | Relay | ⚠️ 部分 | 1.1.10 | 页面加载正常,但显示 "No data" (BUG-007) |
|
||||
| 1.1.11 | Usage | ⚠️ 部分 | 1.1.11 | 每日/模型统计均 "No data" (BUG-008) |
|
||||
| 1.1.12 | Config | ⚠️ 部分 | — | 6 个 Tab 全部 "No data" (BUG-009) |
|
||||
| 1.1.13 | Agent Templates | ✅ PASS | 1.1.13 | 5 个模板,分类/模型/版本正确 |
|
||||
| 1.1.14 | Logs | ✅ PASS | 1.1.14 | 252 条日志,13 页分页正常 |
|
||||
|
||||
### 2.2 "No data" 问题根因分析
|
||||
|
||||
种子数据 (`seed_demo_data` in `db.rs`) 使用 demo 前缀 ID(如 `demo-openai`, `demo-token-1`)插入数据,但多个查询端点按 `account_id` 过滤:
|
||||
|
||||
- **API Keys**: `/api/v1/keys` 查询 `api_tokens` 表按 `account_id` 过滤,种子数据绑定了 `admin_id`(变量),但实际登录账号的 ID 可能不同
|
||||
- **Relay Tasks**: 同理,按 `account_id` 过滤
|
||||
- **Usage**: `/api/v1/usage` 按日期范围和 `account_id` 查询
|
||||
- **Config**: `/api/v1/config/items` 按分类过滤,种子分类为 `server/llm/agent/memory/security`,但前端 Tab 名称可能为不同值
|
||||
|
||||
---
|
||||
|
||||
## 三、阶段 1.2 — Desktop 冒烟测试 (localhost:1420)
|
||||
|
||||
### 3.1 测试结果详情
|
||||
|
||||
| # | 测试项 | 结果 | 截图 | 备注 |
|
||||
|---|--------|------|------|------|
|
||||
| 1.2.1 | 应用加载 | ✅ PASS | 1.2.1 | 显示登录页 |
|
||||
| 1.2.2 | SaaS 登录 | ✅ PASS | 1.2.2 | admin/admin123 → Gateway 已连接 |
|
||||
| 1.2.3 | 聊天界面 | ✅ PASS | — | 主聊天区域正常,Gateway 连接 |
|
||||
| 1.2.4 | 模型选择器 | ❌ FAIL | — | 卡在"加载中" (BUG-004) |
|
||||
| 1.2.5 | Hands/自动化 | ⏭️ 跳过 | 1.2.5 | 崩溃:Tauri IPC 不可用 (BUG-005) |
|
||||
| 1.2.6 | 设置页面 | ✅ PASS | 1.2.6 | 20 个设置分组,SaaS 连接正常 |
|
||||
|
||||
### 3.2 关键网络请求分析
|
||||
|
||||
| 请求 | 状态 | 说明 |
|
||||
|------|------|------|
|
||||
| `POST /api/v1/auth/login` | 200 | 登录成功 |
|
||||
| `POST /api/v1/devices/register` | 200 | 设备注册成功 |
|
||||
| `GET /api/v1/relay/models` | 200 → 500 → 200 | 最初 500(BUG-002),修复后 200 |
|
||||
| `GET /api/v1/config/pull` | 200 | 配置同步成功 |
|
||||
| `GET localhost:1420/api/agents` | 502 | Tauri IPC 不可用(dev 模式预期) |
|
||||
|
||||
---
|
||||
|
||||
## 四、已修复的 Bug 详情
|
||||
|
||||
### BUG-001: Scheduler SQL 类型不匹配 [P0 → 已修复]
|
||||
|
||||
**现象**: 后端启动约 30 秒后崩溃,日志:
|
||||
```
|
||||
[UserScheduler] tick error: 操作符不存在: timestamp with time zone <= text
|
||||
```
|
||||
进程退出码 `0xffffffff`。
|
||||
|
||||
**根因**: `scheduled_tasks` 表的 `next_run_at` 列在旧数据库中为 `TEXT` 类型(通过内联 schema 创建),而 scheduler 的 SQL 查询 `next_run_at <= NOW()` 尝试将 TEXT 与 TIMESTAMPTZ 比较,PostgreSQL 拒绝此隐式转换。
|
||||
|
||||
**修复**: `crates/zclaw-saas/src/scheduler.rs` 第 128 行,添加显式类型转换:
|
||||
```sql
|
||||
-- Before
|
||||
WHERE enabled = TRUE AND next_run_at <= NOW()
|
||||
-- After
|
||||
WHERE enabled = TRUE AND next_run_at::TIMESTAMPTZ <= NOW()
|
||||
```
|
||||
|
||||
**文件**: `crates/zclaw-saas/src/scheduler.rs:128`
|
||||
|
||||
---
|
||||
|
||||
### BUG-002: Relay 路由缺少认证中间件 [P0 → 已修复]
|
||||
|
||||
**现象**: 所有 relay 端点返回 500:
|
||||
```
|
||||
Missing request extension: Extension of type `AuthContext` was not found.
|
||||
```
|
||||
|
||||
**根因**: `main.rs` 中 `relay::routes()` 被合并到顶层 Router(line 252),绕过了 `protected_routes` 上的 `auth_middleware` 层。Relay 路由为了 SSE 流式端点需要更长超时,被排除在 15s TimeoutLayer 之外,但同时也失去了认证保护。
|
||||
|
||||
**修复**: 为 relay 路由添加独立的中间件链(auth + rate_limit + request_id + api_version):
|
||||
```rust
|
||||
let relay_routes = zclaw_saas::relay::routes()
|
||||
.layer(middleware::from_fn_with_state(state.clone(), zclaw_saas::middleware::api_version_middleware))
|
||||
.layer(middleware::from_fn_with_state(state.clone(), zclaw_saas::middleware::request_id_middleware))
|
||||
.layer(middleware::from_fn_with_state(state.clone(), zclaw_saas::middleware::rate_limit_middleware))
|
||||
.layer(middleware::from_fn_with_state(state.clone(), zclaw_saas::auth::auth_middleware));
|
||||
```
|
||||
|
||||
**文件**: `crates/zclaw-saas/src/main.rs:250-267`
|
||||
|
||||
**安全影响**: 修复前,relay 端点(包括 chat/completions、任务管理、Key Pool 管理)无认证保护,任何人可直接调用。
|
||||
|
||||
---
|
||||
|
||||
## 五、待修复的 Bug 详情
|
||||
|
||||
### BUG-003: 连接池启动即达 95% [P0]
|
||||
|
||||
**现象**: 后端刚启动 health 端点即报告 `degraded`:
|
||||
```json
|
||||
{"database_pool":{"total":20,"usage_pct":95,"used":19},"status":"degraded"}
|
||||
```
|
||||
|
||||
**影响**:
|
||||
- Health 端点返回 503(usage_pct >= 80%)
|
||||
- 服务标记为 degraded
|
||||
- 仅剩 2 个连接可用,极易耗尽导致后续请求失败
|
||||
|
||||
**推测原因**:
|
||||
1. Admin V2 的 SWR React Query 默认配置导致大量并发请求
|
||||
2. Desktop 的心跳 + 遥测 + OTA 同时启动
|
||||
3. 连接池 min_idle=2, max=20 配置可能不合理
|
||||
|
||||
**建议**:
|
||||
- 增大 max_connections 或降低 min_connections
|
||||
- 添加连接池监控和告警
|
||||
- 前端添加请求去重/合并逻辑
|
||||
|
||||
---
|
||||
|
||||
### BUG-004: Desktop 模型选择器卡在"加载中" [P1]
|
||||
|
||||
**现象**: 模型选择器展开后显示"加载中...",永远不显示模型列表。
|
||||
|
||||
**根因**: 数据桥断裂:
|
||||
- `saasStore.ts:403` 调用 `saasClient.listModels()` 成功获取 12 个模型,存入 `availableModels`
|
||||
- 但模型选择器 UI 读取 `configStore.models`(通过 `GatewayModelChoice[]`)
|
||||
- `configStore` 在 SaaS 模式下的 `listModels()` 可能调用 `client.status()` 而非 `saasClient.listModels()`
|
||||
- 两套 store 之间缺乏数据同步
|
||||
|
||||
**文件**: `desktop/src/store/saasStore.ts:403`, `desktop/src/store/configStore.ts:535`
|
||||
|
||||
---
|
||||
|
||||
### BUG-005: Desktop "自动化"面板崩溃 [P1]
|
||||
|
||||
**现象**: 点击侧边栏"自动化"按钮后页面崩溃:
|
||||
```
|
||||
Cannot read properties of undefined (reading 'transformCallback')
|
||||
```
|
||||
|
||||
**根因**: Hands 面板尝试调用 Tauri IPC(`invoke()`),在 dev web 模式(无 Tauri 运行时)下 `window.__TAURI__` 不存在,且缺少降级处理。
|
||||
|
||||
**文件**: Desktop 前端代码中 Hands 相关组件
|
||||
|
||||
**建议**: 添加 Tauri 运行时检测,非 Tauri 环境显示降级 UI。
|
||||
|
||||
---
|
||||
|
||||
### BUG-006 ~ 009: Admin V2 数据不显示 [P1]
|
||||
|
||||
**共同根因**: 种子数据与前端查询条件不匹配:
|
||||
|
||||
| 页面 | 种子数据 | 前端查询 | 问题 |
|
||||
|------|----------|----------|------|
|
||||
| API Keys | `api_tokens` 表, demo-token-* | `/api/v1/keys` → `account_api_keys` 表 | **表名不同** |
|
||||
| Relay | `relay_tasks` 表, demo 数据 | 按 `account_id` 过滤 | 账号 ID 不匹配 |
|
||||
| Usage | `usage_records` 表, 1500 条 | `/api/v1/usage` 按日期+账号 | 端点/格式可能不匹配 |
|
||||
| Config | `config_items` 表, server/llm/agent/memory/security | 前端 Tab: 通用/认证/中转/模型/限流/日志 | **分类名不匹配** |
|
||||
|
||||
---
|
||||
|
||||
### BUG-010: Rate Limit 误触发 [P1]
|
||||
|
||||
**现象**: 在设置页面点击 "SaaS 平台" 选项时触发 429 Too Many Requests。
|
||||
|
||||
**根因**: 短时间内多个设置 Tab 切换 + API 调用触发限流中间件(默认 60 RPM)。
|
||||
|
||||
**建议**:
|
||||
- 前端导航 debounce
|
||||
- 设置类 GET 请求不计入限流
|
||||
- 提升 RPM 限制
|
||||
|
||||
---
|
||||
|
||||
## 六、测试环境修复记录
|
||||
|
||||
| 时间 | 操作 | 结果 |
|
||||
|------|------|------|
|
||||
| 13:38 | 后端首次启动 | 连接池 95%,degraded 但可用 |
|
||||
| 13:38 | Admin V2 登录 | 成功 |
|
||||
| 13:39 | 触发 Scheduler tick | 后端崩溃 (BUG-001) |
|
||||
| 13:42 | 修复 BUG-001 | `next_run_at::TIMESTAMPTZ <= NOW()` |
|
||||
| 13:43 | 重启后端 | 又崩溃 — 同一问题 |
|
||||
| 13:46 | 重新编译并启动 | 成功,health 返回 degraded(90%) |
|
||||
| 13:47 | Desktop relay/models 500 | 发现 BUG-002 |
|
||||
| 13:56 | 修复 BUG-002 | relay 路由添加独立中间件链 |
|
||||
| 13:58 | 重启后端 | relay/models 正常返回 401(需认证) |
|
||||
| 14:02 | Desktop 登录 | relay/models 返回 200,12 模型 |
|
||||
|
||||
---
|
||||
|
||||
## 七、截图证据清单
|
||||
|
||||
| 文件 | 说明 |
|
||||
|------|------|
|
||||
| `1.1.1-admin-login-page.png` | Admin V2 登录页 |
|
||||
| `1.1.2-admin-dashboard.png` | Admin V2 Dashboard |
|
||||
| `1.1.5-accounts.png` | 账号管理页 |
|
||||
| `1.1.6-providers.png` | 服务商管理页 |
|
||||
| `1.1.9-prompts.png` | 提示词管理页 |
|
||||
| `1.1.10-relay.png` | 中转任务页 (No data) |
|
||||
| `1.1.11-usage.png` | 用量统计页 (No data) |
|
||||
| `1.1.13-agent-templates.png` | Agent 模板页 |
|
||||
| `1.1.14-logs.png` | 操作日志页 |
|
||||
| `1.2.1-desktop-main.png` | Desktop 主界面 |
|
||||
| `1.2.2-desktop-loggedin.png` | Desktop 登录后 |
|
||||
| `1.2.5-hands-crash.png` | 自动化面板崩溃 |
|
||||
| `1.2.6-desktop-settings.png` | Desktop 设置页 |
|
||||
| `1.2.6b-desktop-usage.png` | Desktop 用量统计 |
|
||||
|
||||
---
|
||||
|
||||
## 八、后续建议
|
||||
|
||||
### 优先级 P0(阻塞联调)
|
||||
1. **修复连接池耗尽 (BUG-003)** — 这是所有后续测试的前提
|
||||
2. **验证 BUG-001/002 修复** — 已做代码修复,需确认重启后稳定
|
||||
|
||||
### 优先级 P1(影响功能验证)
|
||||
3. **修复模型选择器 (BUG-004)** — Desktop 核心功能
|
||||
4. **修复种子数据 (BUG-006~009)** — Admin V2 多页面数据不可见
|
||||
5. **添加 Tauri IPC 降级 (BUG-005)** — Dev 模式兼容
|
||||
|
||||
### 优先级 P2(优化)
|
||||
6. **调整 Rate Limit 策略 (BUG-010)**
|
||||
7. **统一分类命名** — Config 页面分类名与种子数据对齐
|
||||
|
||||
---
|
||||
|
||||
*报告生成时间: 2026-03-30 22:15 CST*
|
||||
*测试工具: Chrome DevTools MCP + 手动验证*
|
||||
|
||||
---
|
||||
|
||||
## 九、第二轮修复记录 (2026-03-31)
|
||||
|
||||
### 修复汇总
|
||||
|
||||
| Bug ID | 修复文件 | 修改内容 |
|
||||
|--------|----------|----------|
|
||||
| BUG-003 | `crates/zclaw-saas/src/db.rs` | `max_connections` 20→50, `min_connections` 2→3 |
|
||||
| BUG-006 | `crates/zclaw-saas/src/db.rs` | 新增 `account_api_keys` 种子数据(旧种子写入 `api_tokens` 表,handler 读 `account_api_keys` 表) |
|
||||
| BUG-007 | `crates/zclaw-saas/src/db.rs` | `fix_seed_data()` 统一所有表的 `account_id` 到当前 super_admin |
|
||||
| BUG-008 | `crates/zclaw-saas/src/db.rs` | 同 BUG-007,usage_records 1475 行已修复 |
|
||||
| BUG-009 | `crates/zclaw-saas/src/db.rs` | config_items 分类从 `server/llm/agent/memory/security` 更新为 `general/auth/relay/model/rate_limit/log` |
|
||||
| BUG-010 | `crates/zclaw-saas/src/middleware.rs` | GET 请求豁免限流(前端 SWR 轮询不计入 60 RPM) |
|
||||
| BUG-011 | `crates/zclaw-saas/src/models/relay_task.rs` | `priority`/`attempt_count`/`max_attempts`/`input_tokens`/`output_tokens` 从 `i64` 改为 `i32`(匹配 PostgreSQL INT4) |
|
||||
|
||||
### 新增函数:`fix_seed_data()`
|
||||
|
||||
在 `db.rs` 中添加了 `fix_seed_data()` 函数,在每次启动时自动修复旧种子数据:
|
||||
|
||||
1. **Config 分类迁移**: `server→general`, `llm→model`, `agent→general`, `memory→general`, `security→rate_limit`
|
||||
2. **Account API Keys 补种**: 为每个 super_admin 账号插入 3 条演示 API Key
|
||||
3. **Account ID 统一**: 将 relay_tasks、usage_records、operation_logs、telemetry_reports 的 account_id 统一为第一个 super_admin
|
||||
|
||||
### 验证结果
|
||||
|
||||
| 端点 | 修复前 | 修复后 |
|
||||
|------|--------|--------|
|
||||
| `GET /api/v1/keys` | `{total: 0}` | `{total: 3}` ✅ |
|
||||
| `GET /api/v1/usage?group_by=day` | `{by_day: []}` | `{total_requests: 1475, by_day: 30天}` ✅ |
|
||||
| `GET /api/v1/usage?group_by=model` | `{by_model: []}` | `{by_model: 5模型}` ✅ |
|
||||
| `GET /api/v1/config/items?category=general` | `{total: 0}` | `{total: 6}` ✅ |
|
||||
| `GET /api/v1/config/items?category=model` | `{total: 0}` | `{total: 3}` ✅ |
|
||||
| `GET /api/v1/config/items?category=rate_limit` | `{total: 0}` | `{total: 3}` ✅ |
|
||||
| `GET /api/v1/relay/tasks` | 500 (类型错误) | 200 ✅ |
|
||||
|
||||
### 仍待修复
|
||||
|
||||
| Bug ID | 描述 | 原因 |
|
||||
|--------|------|------|
|
||||
| BUG-004 | Desktop 模型选择器卡在"加载中" | saasStore 与 configStore 数据桥未同步 |
|
||||
| BUG-005 | Desktop 自动化面板崩溃 | Tauri IPC 无降级 |
|
||||
|
||||
---
|
||||
|
||||
*第二轮修复时间: 2026-03-31 00:00 CST*
|
||||
167
docs/archive/old-test-reports/test-results/DEFECT_LIST.md
Normal file
@@ -0,0 +1,167 @@
|
||||
# ZCLAW 上线前功能审计 — 缺陷清单
|
||||
|
||||
> **审计日期**: 2026-04-06 | **最后更新**: 2026-04-06 (深度审计完成) | **审计范围**: T1-T8 模块 | **基线**: V12 审计 | **最新编译状态**: ✅ cargo check 通过
|
||||
|
||||
## 统计总览
|
||||
|
||||
| 严重度 | 已修复 | FALSE_POSITIVE |
|
||||
|--------|--------|---------------|
|
||||
| **P0** | 1 | 0 |
|
||||
| **P1** | 14 | 1 (M11-01) |
|
||||
| **P2** | 27 | 0 |
|
||||
| **P3** | 9 | 0 |
|
||||
| **合计** | **51** | **1** |
|
||||
|
||||
> **深度审计 (2026-04-06)**: 52 项逐项代码验证完成。M11-01 为 FALSE_POSITIVE(blocking_lock 从未存在)。P3-03/P3-07/P3-09 深度审计发现实际未修,已全部补修并编译通过。所有缺陷项均已关闭。
|
||||
|
||||
---
|
||||
|
||||
## P0 缺陷(0 个 — 全部已修复)
|
||||
|
||||
| ID | 原V12 ID | 模块 | 描述 | 状态 |
|
||||
|----|---------|------|------|------|
|
||||
| ~~P0-01~~ | M4-01 | T2 | 双数据库(PersistentMemoryStore vs SqliteStorage) | ✅ 已修复 |
|
||||
|
||||
---
|
||||
|
||||
## P1 缺陷(0 个 — 全部已修复)
|
||||
|
||||
| ID | 原V12 ID | 模块 | 描述 | 文件 | 状态 |
|
||||
|----|---------|------|------|------|------|
|
||||
| P1-01 | M3-02 | T1 | Browser Hand 返回 pending_execution 不实际执行 | hands/browser.rs | ✅ 已修复 (Fantoccini 0.21 集成于 desktop/src-tauri/src/browser/client.rs,Rust Hand 为有意 schema passthrough) |
|
||||
| P1-02 | M4-03 | T2 | Heartbeat 不自动初始化,需手动 heartbeat_init | heartbeat.rs | ✅ 已修复 |
|
||||
| P1-03 | TC-1-D01 | T1 | LLM API 并发 500 DATABASE_ERROR(4/5 并发失败) | saas/relay | ✅ 已修复 |
|
||||
| P1-04 | TC-4-D01 | T4 | GenerationPipeline 硬编码 model="default",SaaS relay 404 | zclaw-kernel/generation/mod.rs:416 | ✅ 已修复 |
|
||||
| P1-05 | M2-05 | T3 | 删除活跃 Agent 无警告,无自动切换 | kernel_commands/agent.rs | ✅ 已修复 |
|
||||
| P1-06 | M2-01 | T3 | agent_get 不返回 soul/system_prompt/temperature/max_tokens | kernel_commands/agent.rs | ✅ 已修复 |
|
||||
|
||||
---
|
||||
|
||||
## P2 缺陷(23 个)
|
||||
|
||||
### T1 Hands (5)
|
||||
|
||||
| ID | 原V12 ID | 描述 | 状态 |
|
||||
|----|---------|------|------|
|
||||
| P2-01 | M3-04 | max_concurrent 未实现(5 个并发全被接受) | ✅ 已修复 (registry.rs Semaphore 并发限制) |
|
||||
| P2-02 | M3-05 | timeout_secs 未实现(无超时保护) | ✅ 已修复 (kernel/hands.rs tokio::time::timeout) |
|
||||
| P2-03 | M3-10 | toolCount/metricCount 硬编码为 0 | ✅ 已修复 (registry.get_counts + Hand trait tool_count/metric_count) |
|
||||
| P2-04 | TC-1-D03 | Quiz Hand 无输入长度限制(100K 字符被接受) | ✅ 已修复 (quiz.rs 50KB 限制) |
|
||||
| P2-05 | M2-08 | max_tokens=0 未被 agent_create 拒绝 | ✅ 已修复 (create/update/import 全路径校验) |
|
||||
|
||||
### T2 Intelligence (4)
|
||||
|
||||
| ID | 原V12 ID | 描述 | 状态 |
|
||||
|----|---------|------|------|
|
||||
| P2-06 | M4-08 | heartbeat_init 无最小间隔验证(0.001分钟被接受) | ✅ 已修复 (init>=1 分钟, update_config 待补) |
|
||||
| P2-07 | M4-02 | 反思引擎可能仍基于规则而非 LLM(new_memories=0) | ✅ 已修复 (ReflectionResult.used_fallback 标记) |
|
||||
| P2-08 | TC-2-D01 | identity_propose_change 参数不透明 | ✅ 已修复 (统一 file/target 参数命名) |
|
||||
| P2-09 | M4-14/15 | reflection/identity 命令参数名与文档不一致 | ✅ 已修复 (错误消息统一) |
|
||||
|
||||
### T4 Classroom (2)
|
||||
|
||||
| ID | 原V12 ID | 描述 | 状态 |
|
||||
|----|---------|------|------|
|
||||
| P2-10 | M11-04 | LLM 失败静默 fallback 到 placeholder,无标记 | ✅ 已修复 (ClassroomMetadata.is_placeholder 字段) |
|
||||
| P2-11 | M11-05 | 课堂生成完成强制打开 player,不尊重手动关闭 | ✅ 已修复 (userDidCloseDuringGeneration 标志追踪) |
|
||||
|
||||
### T5 Pipeline (5)
|
||||
|
||||
| ID | 原V12 ID | 描述 | 状态 |
|
||||
|----|---------|------|------|
|
||||
| P2-12 | M6-03 | pipeline_create 硬编码 Action::Hand,LLM/Parallel/Condition 丢失 | ✅ 已修复 (前端补发 actionType + 后端多分支匹配) |
|
||||
| P2-13 | M6-04 | workflowStore steps: p.inputs.length 语义错误 | ✅ 已修复 (后端 step_count 字段 + 前端 stepCount 读取) |
|
||||
| P2-14 | M6-05 | getWorkflow inputs→steps 映射语义错误 | ✅ 已修复 (PipelineStepInfo + PipelineInfo.steps 字段) |
|
||||
| P2-15 | M6-06 | 管道操作符 `\|` 在 context.resolve() 中不支持 | ✅ 已修复 (resolve_path_with_pipes + 8 种 transforms) |
|
||||
| P2-16 | M6-07 | 模板中 `{{mustache}}` 和 `${inputs}` 混用 | ✅ 已修复 (mustache→${} 自动归一化) |
|
||||
|
||||
### T6 SaaS Desktop (2)
|
||||
|
||||
| ID | 原V12 ID | 描述 | 状态 |
|
||||
|----|---------|------|------|
|
||||
| P2-17 | M7-01 | 前端密码最少 6 字符 vs 后端 8 字符不一致 | ✅ 已修复 (SaaSLogin placeholder 6→8) |
|
||||
| P2-18 | M7-03 | TOTP QR 码通过外部服务生成,密钥明文传输 | ✅ 已修复 (qrcode 本地库 + LocalQRCode 组件,无外部请求) |
|
||||
|
||||
### T7 Skills (2)
|
||||
|
||||
| ID | 原V12 ID | 描述 | 状态 |
|
||||
|----|---------|------|------|
|
||||
| P2-19 | M5-02 | SKILL.md tools 字段未解析,75 个技能 tools 被忽略 | ✅ 已修复 (serialize_skill_md 补全 tools 写入 + update_skill 保留 tools) |
|
||||
| P2-20 | M5-03 | Python 技能硬编码 python3,Windows 无此命令 | ✅ 已修复 (runner.rs platform-aware python_bin()) |
|
||||
|
||||
### T8 Chat (3)
|
||||
|
||||
| ID | 原V12 ID | 描述 | 状态 |
|
||||
|----|---------|------|------|
|
||||
| P2-21 | M1-01 | GeminiDriver API Key 在 URL query 参数中 | ✅ 已修复 (P2-21: 前期暂停非国内模型支持,Gemini/OpenAI/Anthropic 标记为 suspended) |
|
||||
| P2-22 | M1-02 | ToolOutputGuard 只 warn 不 block 敏感信息 | ✅ 已修复 (sensitive patterns now return Err to block output) |
|
||||
| P2-23 | M1-03/04 | Mutex::unwrap() 在 async 中可能 panic | ✅ 已修复 (relay/service.rs unwrap_or_else(|e| e.into_inner())) |
|
||||
| P2-24 | — | 记忆写入无去重,多轮对话产生内容相同的重复记忆 | ✅ 已修复 (sqlite.rs content_hash 列 + agent scope 去重 + importance/access_count 合并) |
|
||||
| P2-25 | — | 审计日志仅记录反思运行,Hand/Skill 执行无审计追踪 | ✅ 已修复 (security-audit.ts 新增 4 事件类型 + kernel-hands.ts/kernel-skills.ts 审计调用) |
|
||||
|
||||
---
|
||||
|
||||
## P3 缺陷(9 个)
|
||||
|
||||
| ID | 原V12 ID | 模块 | 描述 | 状态 |
|
||||
|----|---------|------|------|------|
|
||||
| P3-01 | TC-2-D02 | T2 | memory_store entry ID 重复 (knowledge/knowledge) | ✅ 已修复 (使用 source 作为 category 避免重复) |
|
||||
| P3-02 | M11-07 | T4 | 白板两套渲染实现未统一(SceneRenderer SVG + WhiteboardCanvas) | ✅ 已修复 (SceneRenderer 导入 WhiteboardCanvas,删除内联 SVG renderWhiteboardItem) |
|
||||
| P3-03 | M11-08 | T4 | HTML export 只渲染 title+duration,缺少 key_points | ✅ 已修复 (export_key_points 配置化渲染) |
|
||||
| P3-04 | M6-08 | T5 | get_progress() 百分比只有 0/50/100 三档 | ✅ 已修复 (PipelineRun.total_steps + 实际百分比计算) |
|
||||
| P3-05 | M7-05 | T6 | saveSaaSSession fire-and-forget,失败静默 | ✅ 已修复 (所有调用点添加 .catch() 错误日志) |
|
||||
| P3-06 | M7-06 | T6 | chatStream 不传 sessionKey/agentId | ✅ 已修复 (saas-relay-client.ts 传递 session_key/agent_id + 后端 RelayChatRequest 新增字段) |
|
||||
| P3-07 | M5-04 | T7 | YAML triggers 引号只处理双引号 | ✅ 已修复 (loader.rs 同时处理双引号和单引号) |
|
||||
| P3-08 | M5-05 | T7 | ShellSkill duration_ms 未设置 | ✅ 已修复 (runner.rs 计时并返回 duration_ms) |
|
||||
| P3-09 | M5-06 | T7 | CATEGORY_CONFIG 仅覆盖 9 分类,75 技能全为 null | ✅ 已修复 (auto_classify + 20 分类覆盖) |
|
||||
|
||||
---
|
||||
|
||||
## 修复确认清单
|
||||
|
||||
| 原V12 ID | 模块 | 描述 | 修复证据 |
|
||||
|----------|------|------|---------|
|
||||
| M4-01 P0 | T2 | 双数据库统一 | unified-client.ts isTauriRuntime() 路由到 SqliteStorage |
|
||||
| M3-01 P1 | T1 | run_id 丢失 | hand_execute 返回 runId 字段 |
|
||||
| M3-06 P1 | T1 | 返回值类型不匹配 | {success, output, error, durationMs, runId} |
|
||||
| M6-01 P1 | T5 | route_intent 未注册 | lib.rs:220 已注册 |
|
||||
| M6-02 P1 | T5 | v1/v2 解析器分裂 | helpers.rs:93-115 fallback 到 v2 |
|
||||
| M7-02 P1 | T6 | PUT 布尔值路径参数 | ConfigMigrationWizard.tsx:118 使用 existing.id |
|
||||
| M7-04 P1 | T6 | refreshToken 未传 body | saas-auth.ts:70-71 发送 refresh_token |
|
||||
| M11-01 P1 | T4 | blocking_lock 死锁 | generate.rs:141-147 改用 try_lock() |
|
||||
| M11-02 P1 | T4 | LLM 无 map_err | mod.rs:440,516 .map_err()(行号因后续提交偏移) |
|
||||
| M11-03 P1 | T4 | 数据仅存内存 | persist.rs SQLite 持久化 |
|
||||
| M11-06 P2 | T4 | Chat Message ID Date.now() | classroomStore.ts:187 crypto.randomUUID()(行号因后续提交偏移) |
|
||||
| M2-08 P2 | T3 | 部分参数验证 | 空 name + temperature 越界已拒绝 |
|
||||
| M5-01 P1 | T7 | tags→triggers 误映射 | skill-discovery.ts:117 优先使用 backend.triggers |
|
||||
| TC-4-D01 P1 | T4 | GenerationPipeline model 硬编码 | generation/mod.rs: model 字段 + with_driver(model) + generate_scene_with_llm_static(model) |
|
||||
| TC-1-D01 P1 | T1 | LLM API 并发 DATABASE_ERROR | relay/service.rs: 瞬态 DB 错误重试;min_connections 建议通过 ZCLAW_DB_MIN_CONNECTIONS=10 配置 |
|
||||
| P1-02 M4-03 | T2 | Heartbeat 不自动初始化 | lifecycle.rs: kernel_init 后自动 heartbeat_init + start |
|
||||
| P1-05 M2-05 | T3 | 删除活跃 Agent 无警告 | CloneManager.tsx: 活跃 agent 差异化警告 + syncAgents 自动切换 |
|
||||
| P1-06 M2-01 | T3 | agent_get 缺失字段 | AgentInfo + registry: 补全 soul/system_prompt/temperature/max_tokens |
|
||||
| P2-01 M3-04 | T1 | max_concurrent 未实现 | registry.rs: Semaphore 并发限制 + register 时创建 |
|
||||
| P2-03 M3-10 | T1 | toolCount/metricCount 硬编码 | hand.rs: tool_count()/metric_count() trait 方法 + registry.get_counts() |
|
||||
| P2-06 M4-08 | T2 | heartbeat_init 无最小间隔验证 | heartbeat.rs:718 init>=1 + heartbeat.rs:838 update_config>=1 |
|
||||
| P2-07 M4-02 | T2 | 反思引擎基于规则无标记 | reflection.rs: ReflectionResult.used_fallback 标记 |
|
||||
| P2-08 TC-2-D01 | T2 | identity 参数不透明 | identity.rs: 错误消息统一为 file type |
|
||||
| P2-10 M11-04 | T4 | LLM 失败静默 placeholder | ClassroomMetadata.is_placeholder + generate() 追踪 |
|
||||
| P2-11 M11-05 | T4 | classroom 强制打开 player | classroomStore.ts: userDidCloseDuringGeneration 意图追踪 |
|
||||
| P2-12 M6-03 | T5 | pipeline_create 硬编码 Action::Hand | workflowStore.ts: actionType 字段 + 后端多分支匹配 |
|
||||
| P2-13 M6-04 | T5 | workflowStore steps 计数错误 | PipelineInfo.step_count + PipelineStepInfo 后端返回实际步骤 |
|
||||
| P2-14 M6-05 | T5 | getWorkflow inputs→steps 映射 | PipelineInfo.steps + PipelineStepInfo 结构化步骤信息 |
|
||||
| P2-15 M6-06 | T5 | 管道操作符 \| 不支持 | context.rs: resolve_path_with_pipes + 8 种 transforms |
|
||||
| P2-16 M6-07 | T5 | {{mustache}} 和 ${inputs} 混用 | context.rs: mustache_regex 自动归一化为 ${...} |
|
||||
| P2-17 M7-01 | T6 | 前端密码最少 6 vs 后端 8 | SaaSLogin.tsx: placeholder 改为"至少 8 个字符" |
|
||||
| P2-19 M5-02 | T7 | SKILL.md tools 未序列化 | registry.rs: serialize_skill_md 补全 tools + update_skill 保留 |
|
||||
| P2-22 M1-02 | T8 | ToolOutputGuard 只 warn | tool_output_guard.rs: sensitive patterns 返回 Err 阻断 |
|
||||
| P2-23 M1-03/04 | T8 | Mutex::unwrap() panic | relay/service.rs: unwrap_or_else(\|e\| e.into_inner()) |
|
||||
| P3-01 TC-2-D02 | T2 | memory_store ID 重复 | memory_commands.rs: 使用 source 作为 category 避免重复 |
|
||||
| P3-03 M11-08 | T4 | HTML export 缺 key_points | html.rs: format_scene_content 添加 key_points 渲染 |
|
||||
| P3-07 M5-04 | T7 | YAML triggers 引号 | loader.rs: 同时处理双引号和单引号 |
|
||||
| P3-08 M5-05 | T7 | ShellSkill duration_ms | runner.rs: start.elapsed() 计时 + duration_ms: Some() |
|
||||
| P3-09 M5-06 | T7 | CATEGORY_CONFIG 9 分类 | skill.rs: auto_classify 关键词匹配 + 20 分类覆盖 |
|
||||
| P2-18 M7-03 | T6 | TOTP QR 码外部服务泄漏 | TOTPSettings.tsx: qrcode 本地库 + LocalQRCode 组件,零外部请求 |
|
||||
| P2-21 M1-01 | T8 | 非国内模型前期暂停 | ModelsAPI.tsx: OpenAI/Anthropic 标记 suspended + 过滤; config.rs: Gemini 注释暂停 |
|
||||
| P3-04 M6-08 | T5 | get_progress 硬编码百分比 | executor.rs: PipelineRun.total_steps + (completed/total)*100 实际计算 |
|
||||
| P3-05 M7-05 | T6 | saveSaaSSession 静默失败 | saasStore.ts: 所有调用点添加 .catch() + log.warn 错误日志 |
|
||||
| P3-06 M7-06 | T6 | chatStream 不传 sessionKey | saas-relay-client.ts: 传递 session_key/agent_id + RelayChatRequest 新增字段 |
|
||||
116
docs/archive/old-test-reports/test-results/RELEASE_READINESS.md
Normal file
@@ -0,0 +1,116 @@
|
||||
# ZCLAW 发布就绪评估
|
||||
|
||||
> **评估日期**: 2026-04-05 | **基于**: T1-T8 功能审计(8 个模块)
|
||||
|
||||
## 总体评分
|
||||
|
||||
| 模块 | V12 基线 | 本次评分 | 变化 | 状态 |
|
||||
|------|---------|---------|------|------|
|
||||
| T1 Hands 自主能力 | 58 | **68** | +10 | ⚠️ 可用 |
|
||||
| T2 智能层 | 61 | **74** | +13 | ✅ 良好 |
|
||||
| T3 Agent 分身 | 67 | **73** | +6 | ✅ 良好 |
|
||||
| T4 课堂系统 | 70 | **75** | +5 | ⚠️ 受阻 |
|
||||
| T5 Pipeline 工作流 | 72 | **78** | +6 | ✅ 良好 |
|
||||
| T6 SaaS 桌面集成 | 85 | **89** | +4 | ✅ 良好 |
|
||||
| T7 技能生态 | 85 | **87** | +2 | ✅ 良好 |
|
||||
| T8 智能对话 | 91 | **91** | 0 | ✅ 优秀 |
|
||||
| **加权平均** | **73** | **79** | **+6** | - |
|
||||
|
||||
---
|
||||
|
||||
## 发布就绪判定
|
||||
|
||||
### 阻断项(必须修复才能发布)
|
||||
|
||||
~~全部已修复~~ ✅ 两个阻断项已修复(2026-04-05):
|
||||
|
||||
| # | 缺陷 | 状态 | 修复说明 |
|
||||
|---|------|------|---------|
|
||||
| 1 | **P1-04**: 课堂生成 model="default" 硬编码 | ✅ 已修复 | generation/mod.rs 添加 model 字段,从 kernel config 读取 |
|
||||
| 2 | **P1-03**: LLM API 并发 500 DATABASE_ERROR | ✅ 已修复 | relay/service.rs 瞬态 DB 错误重试 + min_connections 5→10 |
|
||||
|
||||
### 强烈建议修复(影响用户体验) — ✅ 全部已处理
|
||||
|
||||
| # | 缺陷 | 状态 | 说明 |
|
||||
|---|------|------|------|
|
||||
| 3 | P1-01: Browser Hand 不实际执行 | 🔬 实验性 | 需 Fantoccini 桥接,标注为实验性功能 |
|
||||
| 4 | P1-02: Heartbeat 不自动初始化 | ✅ 已修复 | lifecycle.rs kernel_init 自动初始化并启动 |
|
||||
| 5 | P1-05: 删除活跃 Agent 无警告 | ✅ 已修复 | CloneManager 差异化警告 + 自动切换 |
|
||||
| 6 | P1-06: agent_get 不返回完整配置 | ✅ 已修复 | AgentInfo 补全 soul/system_prompt/temperature/max_tokens |
|
||||
|
||||
### 可接受已知问题(P2/P3,可带缺陷发布)
|
||||
|
||||
- 23 个 P2 问题(大部分为边界条件、参数验证、API 一致性)
|
||||
- 9 个 P3 问题(UI 细节、日志、配置边缘情况)
|
||||
|
||||
---
|
||||
|
||||
## 模块风险评估
|
||||
|
||||
### HIGH RISK
|
||||
|
||||
**T1 Hands (68/100)**
|
||||
- 核心问题: Browser Hand 为实验性(需 Fantoccini 桥接)
|
||||
- 可缓解: Quiz/Slideshow/Whiteboard 等正常工作的 Hand 可用
|
||||
- 状态: 已标注为实验性功能
|
||||
|
||||
**T4 Classroom (75→80/100)**
|
||||
- 核心问题: ~~课堂生成不可用~~ ✅ 已修复(P1-04 model 硬编码已修复)
|
||||
- 可缓解: 持久化、死锁、错误处理已修复
|
||||
- 状态: 课堂生成现在可正常工作
|
||||
|
||||
### MEDIUM RISK → ✅ 已降级
|
||||
|
||||
**T2 Intelligence (74→80/100)**
|
||||
- 核心问题: ~~Heartbeat 不自动启动~~ ✅ 已修复(lifecycle.rs 自动初始化)
|
||||
- 状态: Heartbeat 随 kernel_init 自动启动
|
||||
|
||||
**T3 Agent (73→80/100)**
|
||||
- 核心问题: ~~agent_get 字段不全、删除无警告~~ ✅ 已修复
|
||||
- 状态: agent_get 返回完整配置 + 删除时差异化警告与自动切换
|
||||
|
||||
### LOW RISK
|
||||
|
||||
**T5-T8 (78-91/100)**
|
||||
- 核心功能正常,P2/P3 问题不影响主要用户流程
|
||||
|
||||
---
|
||||
|
||||
## 测试覆盖
|
||||
|
||||
| 类型 | 结果 |
|
||||
|------|------|
|
||||
| Rust cargo test | ✅ 511/511 全部通过(10 crates, 0 failures) |
|
||||
| Desktop vitest | ⚠️ 174/185 通过(11 失败在 chatStore 重构同步) |
|
||||
| Admin vitest | ⚠️ 36/71 通过(29 失败在 mock/API 依赖) |
|
||||
| 功能审计 (T1-T8) | ✅ 51 用例执行,19 已修复,P1 全部处理 |
|
||||
| 端到端 (T9-T12) | ⏭️ Phase 3/4,待执行 |
|
||||
|
||||
---
|
||||
|
||||
## 发布建议
|
||||
|
||||
### 推荐路径: 所有 P1 已修复/处理,可直接发布 Beta
|
||||
|
||||
1. ~~修复 P1-04~~ ✅ 已完成 (generation/mod.rs model 从 config 读取)
|
||||
2. ~~修复 P1-03~~ ✅ 已完成 (relay 瞬态重试 + min_connections 提升)
|
||||
3. ~~修复 P1-02~~ ✅ 已完成 (lifecycle.rs 自动初始化 heartbeat)
|
||||
4. ~~修复 P1-05~~ ✅ 已完成 (CloneManager 差异化警告 + 自动切换)
|
||||
5. ~~修复 P1-06~~ ✅ 已完成 (AgentInfo 补全 soul/system_prompt/temperature/max_tokens)
|
||||
6. **P1-01 Browser Hand** 🔬 标注为实验性(需 Fantoccini 桥接)
|
||||
7. **发布 Beta 版本** 标注已知限制
|
||||
|
||||
### 已知限制标注
|
||||
|
||||
发布时应在 release notes 中注明:
|
||||
- Browser Hand 为实验性功能(需 Fantoccini WebDriver 桥接)
|
||||
- 课堂生成需要正确的模型配置
|
||||
- Python 技能在 Windows 需手动配置 python3 命令
|
||||
- 23 个 P2 + 9 个 P3 已知问题(不影响主要用户流程)
|
||||
|
||||
### 不建议发布的场景
|
||||
|
||||
~~如果以下条件不满足,不建议正式发布~~
|
||||
两个阻断项已全部修复,以下场景已不再阻塞发布:
|
||||
- ~~SaaS 后端连接池未扩容~~ ✅ 已提升 min_connections 并添加重试
|
||||
- ~~课堂 model 硬编码未修复~~ ✅ 已从 kernel config 动态读取
|
||||
220
docs/archive/old-test-reports/test-results/T1-hands/REPORT.md
Normal file
@@ -0,0 +1,220 @@
|
||||
# T1 Hands 自主能力 测试报告
|
||||
|
||||
> **执行日期**: 2026-04-05 | **测试工具**: tauri-mcp execute_js | **V12 基线**: 58/100
|
||||
|
||||
## 摘要
|
||||
|
||||
- **执行用例数**: 18/23(5 个需 UI 交互或长时间等待,未执行)
|
||||
- **通过**: 11 ✅
|
||||
- **未修复(已知问题确认)**: 5 ⚠️
|
||||
- **已修复(V12 问题)**: 2 ✅
|
||||
- **未验证**: 5 ❓
|
||||
- **新发现缺陷**: 3
|
||||
|
||||
### 缺陷统计
|
||||
|
||||
| 级别 | 数量 | 说明 |
|
||||
|------|------|------|
|
||||
| P0 | 0 | - |
|
||||
| P1 | 2 | LLM API 并发 DATABASE_ERROR; Browser Hand 不实际执行 |
|
||||
| P2 | 3 | 无输入长度限制; toolCount/metricCount 硬编码; max_concurrent 未实现 |
|
||||
| P3 | 1 | timeout_secs 未实现 |
|
||||
|
||||
---
|
||||
|
||||
## V12 已知问题验证
|
||||
|
||||
| V12 ID | 描述 | V12 严重度 | 验证结果 | 备注 |
|
||||
|--------|------|-----------|---------|------|
|
||||
| M3-01 | run_id 丢失 | P1 | ✅ **已修复** | hand_execute 返回值含 `runId` 字段(如 `8267f7a0-...`) |
|
||||
| M3-02 | Browser Hand 只返回指令不执行 | P1 | ⚠️ **未修复** | 返回 `status: "pending_execution"` 但未实际操作浏览器 |
|
||||
| M3-03 | browserHandStore 绕过审批 | P1 | ✅ 行为正确 | supervised 模式正确进入审批流程,autonomous 直接执行 |
|
||||
| M3-04 | max_concurrent 未实现 | P2 | ⚠️ **未修复** | 5 个并发 quiz 全部被接受(`max_concurrent: 0`) |
|
||||
| M3-05 | timeout_secs 未实现 | P2 | ⚠️ **未修复** | `timeout_secs: 0`,无超时保护 |
|
||||
| M3-06 | hand_execute 返回值类型不匹配 | P2 | ✅ **已修复** | 返回 `{ success, output, error, durationMs, runId }` 完整结构 |
|
||||
| M3-07 | hand-execution-complete 事件未监听 | P1 | ❓ 未验证 | 需 UI 交互观察 |
|
||||
| M3-08 | 审批条目永不过期 | P2 | ❓ 未验证 | 需长时间等待 |
|
||||
| M3-09 | 重复审批路径 | P2 | ✅ 两条路径存在 | `hand_approve` 和 `approval_respond` 参数名不同但功能重叠 |
|
||||
| M3-10 | tool_count/metric_count 硬编码为 0 | P2 | ⚠️ **未修复** | 所有 Hand 的 `toolCount: 0, metricCount: 0` |
|
||||
| M3-11 | Hand 列举正常 | - | ✅ 通过 | 9 个 Hand 全部返回 |
|
||||
| M3-12 | hand_trigger 自主级别映射 | P1 | ⚠️ **部分修复** | supervised 正确要求审批,但 autonomous 下 Browser 返回 pending_execution |
|
||||
| M3-13 | Clip Hand 路径单引号 | P2 | ❓ 未验证 | 需 FFmpeg 环境 |
|
||||
|
||||
---
|
||||
|
||||
## 测试用例详细结果
|
||||
|
||||
### ✅ TC-1-01 | Hand 列举(正常)
|
||||
|
||||
**结果**: PASS
|
||||
|
||||
`hand_list` 返回 9 个已启用 Hand:
|
||||
|
||||
| Hand | name | enabled | needsApproval | requirementsMet | dependencies |
|
||||
|------|------|---------|---------------|-----------------|-------------|
|
||||
| clip | 视频剪辑 | true | false | ❌ | ffmpeg |
|
||||
| twitter | Twitter 自动化 | true | true | ❌ | twitter_api_key |
|
||||
| researcher | 研究员 | true | false | ❌ | network |
|
||||
| browser | 浏览器 | true | true | ❌ | webdriver |
|
||||
| slideshow | 幻灯片 | true | false | ✅ | - |
|
||||
| quiz | 测验 | true | false | ✅ | - |
|
||||
| whiteboard | 白板 | true | false | ✅ | - |
|
||||
| collector | 数据采集器 | true | false | ❌ | network |
|
||||
| speech | 语音合成 | true | false | ✅ | - |
|
||||
|
||||
### ✅ TC-1-02 | Quiz Hand 直接触发(正常)
|
||||
|
||||
**结果**: PASS
|
||||
|
||||
- 输入: `{ action: "generate", topic: "Rust 基础测试" }`
|
||||
- 输出: 成功生成 5 道选择题,含 `runId: "58d296cc-1be3-4632-8325-f15b4a7708dc"`
|
||||
- 耗时: ~24 秒
|
||||
|
||||
### ✅ TC-1-03 | M3-01 run_id 丢失验证
|
||||
|
||||
**结果**: PASS(已修复)
|
||||
|
||||
hand_execute 返回值结构:
|
||||
```json
|
||||
{
|
||||
"success": true/false,
|
||||
"output": { ... },
|
||||
"error": null,
|
||||
"durationMs": 24499,
|
||||
"runId": "58d296cc-..."
|
||||
}
|
||||
```
|
||||
|
||||
`runId` 字段已稳定存在于所有返回值中。
|
||||
|
||||
### ⚠️ TC-1-05 | M3-02 Browser Hand 断裂
|
||||
|
||||
**结果**: FAIL(未修复)
|
||||
|
||||
- 输入: `{ action: "navigate", url: "https://example.com" }`
|
||||
- 输出: `{ action: "navigate", status: "pending_execution", url: "https://example.com" }`
|
||||
- **问题**: 返回结构化指令但未实际执行浏览器操作
|
||||
|
||||
### ✅ TC-1-06 | 审批流程(正常)
|
||||
|
||||
**结果**: PASS
|
||||
|
||||
1. **supervised 模式**: browser/twitter 正确进入 `pending_approval` 状态
|
||||
2. **approval_list**: 正确返回 2 条 pending 审批
|
||||
3. **approval_respond(approved: true)**: 审批通过后 Hand 开始执行
|
||||
4. **approval_respond(approved: false)**: 拒绝成功
|
||||
|
||||
### ⚠️ TC-1-08 | M3-04 max_concurrent 未实现
|
||||
|
||||
**结果**: FAIL(未修复)
|
||||
|
||||
- 同时触发 5 个 quiz Hand
|
||||
- 5/5 全部被接受执行(1 个成功,4 个因 LLM API 500 失败)
|
||||
- `hand_get` 返回 `max_concurrent: 0` 表示无限制
|
||||
|
||||
### ✅ TC-1-12 | 不存在 Hand 触发(异常)
|
||||
|
||||
**结果**: PASS
|
||||
|
||||
- 输入: `id: "nonexistent-hand"`
|
||||
- 输出: `"Hand not found: nonexistent-hand"`
|
||||
- 错误信息明确
|
||||
|
||||
### ✅ TC-1-15 | Hand 执行状态查询(正常)
|
||||
|
||||
**结果**: PASS
|
||||
|
||||
`hand_run_list` 返回 13 条历史记录,包含完整字段:
|
||||
- `id`, `hand_name`, `status`, `params`, `result`, `error`
|
||||
- `created_at`, `started_at`, `completed_at`, `duration_ms`
|
||||
- `trigger_source: "manual"`
|
||||
|
||||
### ✅ TC-1-16 | M3-06 返回值类型验证
|
||||
|
||||
**结果**: PASS(已修复)
|
||||
|
||||
返回值结构 `{ success, output, error, durationMs, runId }` 完整。
|
||||
|
||||
### ⚠️ TC-1-17 | M3-10 toolCount/metricCount 硬编码
|
||||
|
||||
**结果**: FAIL(未修复)
|
||||
|
||||
所有 9 个 Hand 的 `toolCount: 0, metricCount: 0`。
|
||||
|
||||
### ✅ TC-1-18 | TOML 配置加载验证
|
||||
|
||||
**结果**: PASS
|
||||
|
||||
`hand_get` 返回完整配置:
|
||||
```json
|
||||
{
|
||||
"dependencies": [],
|
||||
"description": "生成和管理测验题目...",
|
||||
"enabled": true,
|
||||
"id": "quiz",
|
||||
"input_schema": { "properties": { "action": ..., "quiz_id": ..., "topic": ... } },
|
||||
"max_concurrent": 0,
|
||||
"name": "测验",
|
||||
"needs_approval": false,
|
||||
"tags": ["assessment", "education"],
|
||||
"timeout_secs": 0
|
||||
}
|
||||
```
|
||||
|
||||
### ✅ TC-1-19 | Hand 错误处理(异常)
|
||||
|
||||
**结果**: PASS
|
||||
|
||||
- `input: null` → `"invalid type: null, expected internally tagged enum ResearcherAction"`
|
||||
- 错误信息明确,非 panic
|
||||
|
||||
### ⚠️ TC-1-20 | M3-12 自主级别映射
|
||||
|
||||
**结果**: PARTIAL
|
||||
|
||||
- supervised: ✅ 正确要求审批("监督模式下所有 Hand 执行需要用户审批")
|
||||
- autonomous: ⚠️ Browser 返回 pending_execution 而非实际执行
|
||||
- Quiz 在 autonomous 下正常执行
|
||||
|
||||
### ⚠️ TC-1-23 | 超长输入触发
|
||||
|
||||
**结果**: FAIL(无输入验证)
|
||||
|
||||
- 100K 字符 topic 被 quiz 接受并尝试执行
|
||||
- 最终因 LLM API 问题失败,但未在输入层拒绝
|
||||
|
||||
---
|
||||
|
||||
## 新发现问题
|
||||
|
||||
| TC-ID | 描述 | 场景类型 | 优先级 | 状态 | 备注 |
|
||||
|-------|------|---------|--------|------|------|
|
||||
| TC-1-D01 | LLM API 并发时 500 DATABASE_ERROR | 边界 | **P1** | 新发现 | 5 个并发 quiz 请求,4 个返回 `{"error":"DATABASE_ERROR"}`,仅第 1 个成功。SaaS 后端数据库连接池可能不足 |
|
||||
| TC-1-D02 | Browser Hand autonomous 返回 pending_execution | 正常 | **P1** | 已知(M3-02) | 即使 autonomous 模式也不实际执行浏览器操作 |
|
||||
| TC-1-D03 | Quiz 无输入长度限制 | 边界 | **P2** | 新发现 | 100K 字符 topic 被接受,应设上限 |
|
||||
|
||||
---
|
||||
|
||||
## 健康度评估
|
||||
|
||||
| 维度 | V12 基线 | 本次评估 | 变化 |
|
||||
|------|---------|---------|------|
|
||||
| 功能完整性 | 58 | 68 | +10 |
|
||||
| 代码质量 | - | - | N/A |
|
||||
| 测试覆盖 | - | - | N/A |
|
||||
| 文档完备 | - | - | N/A |
|
||||
| 集成连通性 | - | - | N/A |
|
||||
| **综合** | **58/100** | **68/100** | **+10** |
|
||||
|
||||
**提升原因**:
|
||||
- M3-01 run_id 丢失已修复
|
||||
- M3-06 返回值类型已修复
|
||||
- 审批流程基本闭环(approval_list/respond 工作正常)
|
||||
- hand_run_list 历史记录功能完整
|
||||
- 错误处理改善(null input / 不存在 Hand 都返回明确错误)
|
||||
|
||||
**残留风险**:
|
||||
- Browser Hand 不实际执行(P1)
|
||||
- max_concurrent/timeout_secs 未实现(P2)
|
||||
- LLM API 并发问题(P1,SaaS 后端)
|
||||
- toolCount/metricCount 硬编码(P2)
|
||||
|
After Width: | Height: | Size: 906 B |
|
After Width: | Height: | Size: 906 B |
|
After Width: | Height: | Size: 906 B |
@@ -0,0 +1,142 @@
|
||||
# T2 智能层(记忆/反思/心跳/自主) 测试报告
|
||||
|
||||
> **执行日期**: 2026-04-05 | **测试工具**: tauri-mcp execute_js | **V12 基线**: 61/100
|
||||
|
||||
## 摘要
|
||||
|
||||
- **执行用例数**: 10/13(3 个需 UI 交互,未执行)
|
||||
- **通过**: 7 ✅
|
||||
- **未修复(已知问题确认)**: 2 ⚠️
|
||||
- **已修复(V12 P0 问题)**: 1 ✅
|
||||
- **新发现缺陷**: 1
|
||||
|
||||
### 缺陷统计
|
||||
|
||||
| 级别 | 数量 | 说明 |
|
||||
|------|------|------|
|
||||
| P0 | 0 | - |
|
||||
| P1 | 1 | Heartbeat 未自动初始化 |
|
||||
| P2 | 2 | heartbeat 极短间隔无验证; identity_propose_change 参数不透明 |
|
||||
| P3 | 1 | memory_store entry ID 重复 (knowledge/knowledge) |
|
||||
|
||||
---
|
||||
|
||||
## V12 已知问题验证
|
||||
|
||||
| V12 ID | 描述 | V12 严重度 | 验证结果 | 备注 |
|
||||
|--------|------|-----------|---------|------|
|
||||
| M4-01 | 双数据库(PersistentMemoryStore vs SqliteStorage) | **P0** | ✅ **已修复** | unified-client.ts 统一了路径:Tauri 模式下全部使用 Rust SqliteStorage(FTS5),不再 fallback 到 localStorage。fallback 仅在浏览器/dev 模式使用 |
|
||||
| M4-02 | 反思 LLM 驱动未接入 | **P0** | ⚠️ **部分修复** | reflection_reflect 返回了 improvements 和 suggestions,但需确认是否使用了 LLM(返回内容较短,可能仍基于规则) |
|
||||
| M4-03 | 心跳不自动启动 | P2 | ⚠️ **未修复** | `heartbeat_get_config` 返回 "Heartbeat engine not initialized",需手动调用 heartbeat_init |
|
||||
| M4-04 | 自主授权后端无强制 | P2 | ✅ T1 已验证 | supervised 模式正确拦截需审批 Hand |
|
||||
| M4-05 | 前端记忆搜索用 LIKE 非 FTS5 | P2 | ✅ **已修复** | unified-client 统一使用 Tauri 后端 FTS5 |
|
||||
| M4-06 | types 参数数组 vs 单值 | P2 | ❓ 未验证 | memory_search 的 options 参数结构需确认 |
|
||||
| M4-07 | 记忆内容无长度限制 | P2 | ⚠️ 需确认 | memory_store 未测试超长 content |
|
||||
| M4-08 | heartbeat interval 无下限 | P2 | ⚠️ **未修复** | heartbeat_init 接受 0.001 分钟间隔 |
|
||||
| M4-09 | 心跳 interval 下限验证 | P2 | 同 M4-08 | - |
|
||||
| M4-10 | memory_build_context 返回值 | P2 | ❓ 未验证 | - |
|
||||
| M4-11 | memory_export 格式 | P2 | ❓ 未验证 | - |
|
||||
| M4-12 | memory_import 去重 | P2 | ❓ 未验证 | - |
|
||||
| M4-13 | 两套压缩实现 | P2 | ✅ compactor 命令工作 | compactor_estimate_tokens 正确返回 |
|
||||
| M4-14 | reflection_reflect 参数不透明 | P2 | ⚠️ 确认 | 参数名 `memories` 而非文档中的 `agentId` |
|
||||
| M4-15 | identity 命令参数不一致 | P2 | ⚠️ 确认 | identity_propose_change 需要 `file` + `suggestedContent`,非直觉参数 |
|
||||
|
||||
---
|
||||
|
||||
## 测试用例详细结果
|
||||
|
||||
### ✅ TC-2-01 | M4-01 双数据库验证(P0)
|
||||
|
||||
**结果**: PASS(已修复)
|
||||
|
||||
- 数据库路径: `C:\Users\szend\AppData\Roaming\zclaw\memories\memories.db`
|
||||
- unified-client.ts 架构:
|
||||
- `isTauriRuntime()` → 调用 Rust SqliteStorage(FTS5)
|
||||
- 浏览器模式 → localStorage fallback
|
||||
- 记忆 CRUD 完整:store → search → stats 全链路通过
|
||||
|
||||
### ⚠️ TC-2-02 | M4-02 反思 LLM 验证(P0)
|
||||
|
||||
**结果**: PARTIAL
|
||||
|
||||
```json
|
||||
{
|
||||
"patterns": [],
|
||||
"improvements": [{
|
||||
"area": "用户理解",
|
||||
"suggestion": "主动在对话中了解用户偏好...",
|
||||
"priority": "medium"
|
||||
}],
|
||||
"identity_proposals": [],
|
||||
"new_memories": 0
|
||||
}
|
||||
```
|
||||
|
||||
- 返回了结构化分析结果(有 improvements)
|
||||
- 但 `new_memories: 0` 和 `patterns: []` 表明可能只基于规则分析
|
||||
- **需进一步检查**: Rust 端 reflection_reflect 是否获取了 LLM driver
|
||||
|
||||
### ✅ TC-2-03 | 记忆 CRUD(正常)
|
||||
|
||||
**结果**: PASS
|
||||
|
||||
- memory_store: ✅ 保存成功,返回 ID
|
||||
- memory_search: ✅ FTS5 搜索正确返回匹配记忆
|
||||
- memory_stats: ✅ 22 条记忆(10 preferences, 9 experience, 3 knowledge)
|
||||
- memory_db_path: ✅ 返回 SQLite 路径
|
||||
|
||||
### ⚠️ TC-2-05 | 身份演化(正常)
|
||||
|
||||
**结果**: PARTIAL
|
||||
|
||||
- identity_get: ✅ 返回完整的 soul/instructions/user_profile
|
||||
- identity_propose_change: ⚠️ 参数名不透明(需要 `file` + `suggestedContent`)
|
||||
- 实际变更提案未成功触发(参数格式问题)
|
||||
|
||||
### ⚠️ TC-2-06 | M4-03 心跳不自动启动
|
||||
|
||||
**结果**: FAIL(未修复)
|
||||
|
||||
- `heartbeat_get_config` → "Heartbeat engine not initialized for agent: default"
|
||||
- 需手动调用 `heartbeat_init` + `heartbeat_start`
|
||||
|
||||
### ⚠️ TC-2-11 | M4-08/M4-09 心跳间隔下限
|
||||
|
||||
**结果**: FAIL(未修复)
|
||||
|
||||
- `heartbeat_init(intervalMinutes: 0.001)` → 返回 null(被接受)
|
||||
- 无最小值验证
|
||||
|
||||
### ✅ TC-2-08 | 上下文压缩
|
||||
|
||||
**结果**: PASS
|
||||
|
||||
- `compactor_estimate_tokens` 正确返回 token 数(5 for "Hello world test")
|
||||
|
||||
---
|
||||
|
||||
## 新发现问题
|
||||
|
||||
| TC-ID | 描述 | 场景类型 | 优先级 | 状态 |
|
||||
|-------|------|---------|--------|------|
|
||||
| TC-2-D01 | identity_propose_change 参数不透明(file + suggestedContent) | 正常 | P2 | 新发现 |
|
||||
| TC-2-D02 | memory_store 重复 ID(knowledge/knowledge) | 边界 | P3 | 新发现 |
|
||||
|
||||
---
|
||||
|
||||
## 健康度评估
|
||||
|
||||
| 维度 | V12 基线 | 本次评估 | 变化 |
|
||||
|------|---------|---------|------|
|
||||
| **综合** | **61/100** | **74/100** | **+13** |
|
||||
|
||||
**提升原因**:
|
||||
- M4-01 P0 双数据库已修复(unified-client 统一路径)
|
||||
- 记忆 CRUD 全链路工作正常
|
||||
- 上下文压缩命令工作
|
||||
- 反思引擎返回结构化分析
|
||||
|
||||
**残留风险**:
|
||||
- Heartbeat 不自动启动(P1)
|
||||
- 反思 LLM 驱动可能未完全接入
|
||||
- 部分命令参数不透明(API 文档缺失)
|
||||
137
docs/archive/old-test-reports/test-results/T3-agent/REPORT.md
Normal file
@@ -0,0 +1,137 @@
|
||||
# T3 Agent 分身 测试报告
|
||||
|
||||
> **执行日期**: 2026-04-05 | **测试工具**: tauri-mcp execute_js | **V12 基线**: 67/100
|
||||
|
||||
## 摘要
|
||||
|
||||
- **执行用例数**: 10/12
|
||||
- **通过**: 7 ✅
|
||||
- **未修复(已知问题确认)**: 2 ⚠️
|
||||
- **已修复**: 1 ✅
|
||||
- **新发现缺陷**: 2
|
||||
|
||||
### 缺陷统计
|
||||
|
||||
| 级别 | 数量 | 说明 |
|
||||
|------|------|------|
|
||||
| P0 | 0 | - |
|
||||
| P1 | 1 | 删除活跃 Agent 无警告(M2-05 确认) |
|
||||
| P2 | 2 | agent_get 不返回 soul/system_prompt; max_tokens=0 未被拒绝 |
|
||||
| P3 | 0 | - |
|
||||
|
||||
---
|
||||
|
||||
## V12 已知问题验证
|
||||
|
||||
| V12 ID | 描述 | V12 严重度 | 验证结果 | 备注 |
|
||||
|--------|------|-----------|---------|------|
|
||||
| M2-01 | KernelClient createClone 字段丢失 | P1 | ⚠️ **部分修复** | agent_create 接受 soul/system_prompt 但 agent_get 不返回这些字段 |
|
||||
| M2-02 | 双通路创建不对等 | P1 | ❓ 未验证 | Gateway 模式未测试 |
|
||||
| M2-03 | agent_list 不返回 emoji | P2 | ❓ 未验证 | agent_get 不含 emoji 字段 |
|
||||
| M2-04 | agent_create 不返回 config | P2 | ✅ 返回基本字段 | 但缺少 soul/system_prompt |
|
||||
| M2-05 | 删除活跃 Agent 无警告 | P1 | ⚠️ **未修复** | agent_delete 直接删除当前活跃 Agent,无警告 |
|
||||
| M2-06 | Agent 切换不通知 Kernel | P2 | ❓ 未验证 | 需 UI 测试 |
|
||||
| M2-07 | 切换不取消流 | P2 | ❓ 未验证 | 需 UI 测试 |
|
||||
| M2-08 | 无参数验证 | P2 | ⚠️ **部分修复** | 空 name 和 temperature 越界已拒绝 ✅,但 max_tokens=0 未拒绝 ⚠️ |
|
||||
| M2-09 | 删除后 selectedAgent 引用悬挂 | P2 | ⚠️ **未修复** | 删除活跃 Agent 后无自动切换 |
|
||||
| M2-10 | Agent export 不含 conversations | P2 | ❓ 未验证 | - |
|
||||
| M2-11 | Agent export 返回空 JSON | P2 | ❓ 未验证 | - |
|
||||
| M2-12 | SOUL.md 未集成到 system prompt | P2 | ❓ 未验证 | - |
|
||||
| M2-13 | agent_create 无默认 workspace | P2 | ❓ 未验证 | - |
|
||||
| M2-14 | agent_update 不触发 identity sync | P2 | ❓ 未验证 | - |
|
||||
|
||||
---
|
||||
|
||||
## 测试用例详细结果
|
||||
|
||||
### ✅ TC-3-01 | Agent 列举(正常)
|
||||
|
||||
**结果**: PASS
|
||||
|
||||
- agent_list 返回 1 个 default agent
|
||||
- 包含 id, name, description, model, provider, state, messageCount, createdAt, updatedAt
|
||||
|
||||
### ⚠️ TC-3-02 | M2-01 字段丢失验证
|
||||
|
||||
**结果**: PARTIAL(部分修复)
|
||||
|
||||
**agent_create** 接受完整字段:
|
||||
```json
|
||||
{
|
||||
"name": "审计测试 Agent",
|
||||
"description": "用于测试字段传递",
|
||||
"soul": "# 测试人格\n严谨、精确",
|
||||
"system_prompt": "你是一个审计测试助手",
|
||||
"model": "glm-4-flash",
|
||||
"provider": "glm",
|
||||
"max_tokens": 4096,
|
||||
"temperature": 0.7
|
||||
}
|
||||
```
|
||||
|
||||
**agent_get** 返回时丢失字段:
|
||||
```json
|
||||
{
|
||||
"id": "7f14a54e-...",
|
||||
"name": "审计测试 Agent",
|
||||
"description": "用于测试字段传递",
|
||||
"model": "glm-4-flash",
|
||||
"provider": "glm",
|
||||
"state": "Running"
|
||||
// ❌ 缺少: soul, system_prompt, temperature, max_tokens, workspace
|
||||
}
|
||||
```
|
||||
|
||||
**结论**: 字段写入成功但读取不返回 — **M2-01 部分修复**(数据已存储,但 API 不返回)
|
||||
|
||||
### ✅ TC-3-04 | Agent 更新(正常)
|
||||
|
||||
**结果**: PASS
|
||||
|
||||
- agent_update 成功更新 name, description
|
||||
- agent_get 返回更新后的值
|
||||
|
||||
### ✅ TC-3-08 | Agent 删除(正常)
|
||||
|
||||
**结果**: PASS
|
||||
|
||||
- agent_delete 返回 null(成功)
|
||||
- Agent 从列表消失
|
||||
|
||||
### ⚠️ TC-3-09 | M2-05 删除活跃 Agent
|
||||
|
||||
**结果**: FAIL(未修复)
|
||||
|
||||
- 删除当前活跃 Agent(default agent)后:
|
||||
- 无警告、无确认
|
||||
- Agent 从列表消失
|
||||
- 无自动切换到其他 Agent
|
||||
- 需手动创建新 Agent
|
||||
|
||||
### ✅ TC-3-10 | 参数验证
|
||||
|
||||
**结果**: PARTIAL
|
||||
|
||||
| 验证项 | 输入 | 结果 | 预期 |
|
||||
|--------|------|------|------|
|
||||
| 空名 | name="" | ✅ `"Agent name cannot be empty"` | 拒绝 |
|
||||
| 温度越界 | temperature=5.0 | ✅ `"Temperature must be between 0 and 2"` | 拒绝 |
|
||||
| max_tokens=0 | max_tokens=0 | ⚠️ Agent 被成功创建 | 应拒绝 |
|
||||
|
||||
---
|
||||
|
||||
## 健康度评估
|
||||
|
||||
| 维度 | V12 基线 | 本次评估 | 变化 |
|
||||
|------|---------|---------|------|
|
||||
| **综合** | **67/100** | **73/100** | **+6** |
|
||||
|
||||
**提升原因**:
|
||||
- agent_create 接受完整配置字段(soul, system_prompt, temperature 等)
|
||||
- 基本参数验证已实现(空名、温度越界)
|
||||
- CRUD 操作(create/get/update/delete)基本工作
|
||||
|
||||
**残留风险**:
|
||||
- agent_get 不返回完整配置(P2)
|
||||
- 删除活跃 Agent 无警告(P1)
|
||||
- max_tokens=0 未被验证(P2)
|
||||
@@ -0,0 +1,142 @@
|
||||
# T4 课堂系统 测试报告
|
||||
|
||||
> **执行日期**: 2026-04-05 | **测试工具**: tauri-mcp execute_js + 代码审查 | **V12 基线**: 70/100
|
||||
|
||||
## 摘要
|
||||
|
||||
- **执行用例数**: 7/12(5 个需已生成课堂数据,因 P1 缺陷无法执行)
|
||||
- **代码审查确认**: 8 项 V12 问题验证
|
||||
- **已修复**: 4 ✅
|
||||
- **未修复**: 3 ⚠️
|
||||
- **新发现缺陷**: 1 (P1)
|
||||
|
||||
### 缺陷统计
|
||||
|
||||
| 级别 | 数量 | 说明 |
|
||||
|------|------|------|
|
||||
| P0 | 0 | - |
|
||||
| P1 | 1 | GenerationPipeline 硬编码 model="default",SaaS relay 404(新发现) |
|
||||
| P2 | 2 | LLM 失败无 placeholder 标记; 生成完成强制打开 player |
|
||||
| P3 | 2 | HTML export 内容不完整; 白板两套渲染实现未统一 |
|
||||
|
||||
---
|
||||
|
||||
## V12 已知问题验证
|
||||
|
||||
| V12 ID | 描述 | V12 严重度 | 验证结果 | 备注 |
|
||||
|--------|------|-----------|---------|------|
|
||||
| M11-01 | is_cancelled() blocking_lock 死锁 | P1 | ✅ **已修复** | generate.rs:141-147 改用 `try_lock()`,避免 tokio 死锁 |
|
||||
| M11-02 | LLM 调用无 map_err | P1 | ✅ **已修复** | mod.rs:431-434 已加 `.map_err`,错误正确传播 |
|
||||
| M11-03 | 课堂数据仅存内存 | P1 | ✅ **已修复** | persist.rs 实现了 SQLite 持久化(classrooms.db) |
|
||||
| M11-04 | LLM 失败静默 fallback | P2 | ⚠️ **未修复** | chat.rs:82-93 LLM 失败 fallback 到 placeholder 无标记 |
|
||||
| M11-05 | 生成完成强制打开 player | P2 | ⚠️ **未修复** | classroomStore.ts:124 无条件 `classroomOpen: true` |
|
||||
| M11-06 | Chat Message ID 用 Date.now() | P2 | ✅ **已修复** | classroomStore.ts:176 使用 `crypto.randomUUID()` |
|
||||
| M11-07 | 白板两套渲染实现 | P3 | ⚠️ **未修复** | SceneRenderer 内嵌 SVG + WhiteboardCanvas.tsx 独立组件 |
|
||||
| M11-08 | HTML export 内容不完整 | P3 | ⚠️ **未修复** | export.rs:97-103 只渲染 title+type+duration,缺 key_points/notes |
|
||||
|
||||
---
|
||||
|
||||
## 测试用例详细结果
|
||||
|
||||
### ❌ TC-4-01 | 课堂生成(正常)
|
||||
|
||||
**结果**: FAIL(新发现 P1 缺陷)
|
||||
|
||||
```
|
||||
Error: Outline generation failed: LLM error: API error 404 Not Found:
|
||||
{"error":"NOT_FOUND","message":"未找到: 模型 default 不存在或未启用"}
|
||||
```
|
||||
|
||||
**根因**: `zclaw-kernel/src/generation/mod.rs:416` — `CompletionRequest` 硬编码 `model: "default"`,SaaS relay 需要实际模型名(如 `glm-4-flash`)。Kernel driver 返回模型配置但 GenerationPipeline 未使用。
|
||||
|
||||
**影响**: 课堂生成完全不可用。
|
||||
|
||||
### ✅ TC-4-02 | M11-01 验证: blocking_lock 死锁
|
||||
|
||||
**结果**: PASS(已修复,代码审查确认)
|
||||
|
||||
generate.rs:141-147 使用 `try_lock()` + `Err(_)` fallback,不会阻塞 tokio runtime。
|
||||
|
||||
### ✅ TC-4-03 | M11-02 验证: LLM 无 map_err
|
||||
|
||||
**结果**: PASS(已修复,代码审查确认)
|
||||
|
||||
mod.rs:431-434 `.map_err(|e| ZclawError::LlmError(...))`,Stage 1/2 均有 `.map_err`。
|
||||
|
||||
### ⏭️ TC-4-04~TC-4-09 | 场景播放/TTS/白板/持久化/聊天/导出
|
||||
|
||||
**结果**: SKIP
|
||||
|
||||
依赖课堂生成成功。因 TC-4-01 P1 缺陷,无法执行端到端测试。
|
||||
|
||||
### ✅ TC-4-07 | M11-03 验证: 课堂数据持久化(代码审查)
|
||||
|
||||
**结果**: PASS(已修复)
|
||||
|
||||
- `classroom_commands/persist.rs`: SQLite 持久化实现完整
|
||||
- DB 路径: `{app_data_dir}/classroom/classrooms.db`
|
||||
- 表: `classrooms` + `classroom_chats`
|
||||
- 生成/聊天后自动保存(generate.rs:223, chat.rs:108)
|
||||
|
||||
### ✅ TC-4-10 | M11-04 验证: LLM 失败静默 fallback(代码审查)
|
||||
|
||||
**结果**: FAIL(未修复)
|
||||
|
||||
chat.rs:82-93:
|
||||
```rust
|
||||
let agent_responses = match generate_llm_responses(...).await {
|
||||
Ok(responses) => responses,
|
||||
Err(e) => {
|
||||
tracing::warn!("LLM chat generation failed, using placeholders: {}", e);
|
||||
generate_placeholder_responses(...) // 无 isPlaceholder 标记
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
### ✅ TC-4-11 | M11-05 验证: 生成完成强制打开(代码审查)
|
||||
|
||||
**结果**: FAIL(未修复)
|
||||
|
||||
classroomStore.ts:124:
|
||||
```typescript
|
||||
set({ classroomOpen: true }); // 无条件设置,不检查用户是否手动关闭
|
||||
```
|
||||
|
||||
### ✅ TC-4-12 | classroom_list/classroom_get 基本验证
|
||||
|
||||
**结果**: PASS
|
||||
|
||||
- `classroom_list` → `[]`(空列表,正确)
|
||||
- `classroom_get("nonexistent-id")` → `"Classroom 'nonexistent-id' not found"`(错误信息明确)
|
||||
|
||||
---
|
||||
|
||||
## 新发现问题
|
||||
|
||||
| TC-ID | 描述 | 场景类型 | 优先级 | 状态 |
|
||||
|-------|------|---------|--------|------|
|
||||
| TC-4-D01 | GenerationPipeline 硬编码 model="default",SaaS relay 404 | 正常 | **P1** | 新发现 |
|
||||
|
||||
**TC-4-D01 详情**:
|
||||
- 文件: `crates/zclaw-kernel/src/generation/mod.rs:416` 和 `:490`
|
||||
- `CompletionRequest { model: "default".to_string(), ... }` — SaaS relay 需要实际模型名
|
||||
- 修复建议: 从 kernel config 获取 `llm.model` 字段传入 GenerationPipeline
|
||||
|
||||
---
|
||||
|
||||
## 健康度评估
|
||||
|
||||
| 维度 | V12 基线 | 本次评估 | 变化 |
|
||||
|------|---------|---------|------|
|
||||
| **综合** | **70/100** | **75/100** | **+5** |
|
||||
|
||||
**提升原因**:
|
||||
- M11-01 P1 死锁风险已修复(try_lock)
|
||||
- M11-02 P1 LLM 错误处理已修复(map_err)
|
||||
- M11-03 P1 数据持久化已修复(SQLite)
|
||||
- M11-06 Chat ID 碰撞已修复(crypto.randomUUID)
|
||||
|
||||
**残留风险**:
|
||||
- **P1**: GenerationPipeline 硬编码 "default" 模型 → 课堂生成完全不可用
|
||||
- P2: LLM 失败 placeholder 无标记(M11-04)
|
||||
- P2: 生成完成强制打开 player(M11-05)
|
||||
129
docs/archive/old-test-reports/test-results/T5-pipeline/REPORT.md
Normal file
@@ -0,0 +1,129 @@
|
||||
# T5 Pipeline 工作流 测试报告
|
||||
|
||||
> **执行日期**: 2026-04-05 | **测试工具**: tauri-mcp execute_js + 代码审查 | **V12 基线**: 72/100
|
||||
|
||||
## 摘要
|
||||
|
||||
- **执行用例数**: 6/8(2 个需 UI 交互,未执行)
|
||||
- **代码审查确认**: 8 项 V12 问题验证
|
||||
- **已修复**: 2 ✅
|
||||
- **未修复**: 5 ⚠️
|
||||
- **新发现缺陷**: 0
|
||||
|
||||
### 缺陷统计
|
||||
|
||||
| 级别 | 数量 | 说明 |
|
||||
|------|------|------|
|
||||
| P0 | 0 | - |
|
||||
| P1 | 0 | M6-01/M6-02 已修复 |
|
||||
| P2 | 4 | M6-03/M6-04/M6-05/M6-07 未修复 |
|
||||
| P3 | 1 | M6-08 进度百分比粗糙 |
|
||||
|
||||
---
|
||||
|
||||
## V12 已知问题验证
|
||||
|
||||
| V12 ID | 描述 | V12 严重度 | 验证结果 | 备注 |
|
||||
|--------|------|-----------|---------|------|
|
||||
| M6-01 | route_intent Tauri 命令未注册 | P1 | ✅ **已修复** | lib.rs:220 已注册,调用成功返回推荐结果 |
|
||||
| M6-02 | pipeline_list 只用 v1 解析器 | P1 | ✅ **已修复** | helpers.rs:93-115 v1 失败 fallback 到 v2,15 个模板全部列出 |
|
||||
| M6-03 | pipeline_create Action 类型丢失 | P2 | ⚠️ **未修复** | crud.rs:82 硬编码 `Action::Hand`,LLM/Parallel/Condition 丢失 |
|
||||
| M6-04 | workflowStore inputs→steps 映射错误 | P2 | ⚠️ **未修复** | workflowStore.ts:389 `steps: p.inputs.length` 语义错误 |
|
||||
| M6-05 | getWorkflow inputs→steps 映射 | P2 | ⚠️ **未修复** | workflowStore.ts:405 将 inputs 映射为 WorkflowDetail.steps |
|
||||
| M6-06 | 管道操作符 `\|` 不支持 | P2 | ❓ 未验证 | 需端到端执行验证 |
|
||||
| M6-07 | `{{mustache}}` 和 `${inputs}` 混用 | P2 | ⚠️ **未修复** | campaign.yaml:87-90 等模板仍使用 `{{}}` 语法 |
|
||||
| M6-08 | get_progress() 百分比粗糙 | P3 | ⚠️ **未修复** | executor.rs:469-475 只有 0/50/100 三档 |
|
||||
|
||||
---
|
||||
|
||||
## 测试用例详细结果
|
||||
|
||||
### ✅ TC-5-01 | Pipeline 列举发现
|
||||
|
||||
**结果**: PASS
|
||||
|
||||
- `pipeline_list` 返回 15 个模板
|
||||
- 覆盖 5 个行业: design-shantou(4), education(5), healthcare(3), legal(1), marketing(1), productivity(1)
|
||||
- 每个模板包含完整元数据: id, displayName, description, category, industry, tags, icon, version, inputs
|
||||
|
||||
### ✅ TC-5-02 | M6-02 验证: v1/v2 解析器
|
||||
|
||||
**结果**: PASS(已修复)
|
||||
|
||||
helpers.rs:93-115 — v1 解析失败后自动尝试 v2 解析器。15 个模板全部成功列出(含 v1 和 v2 格式)。
|
||||
|
||||
### ✅ TC-5-05 | M6-01 验证: route_intent
|
||||
|
||||
**结果**: PASS(已修复)
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "no_match",
|
||||
"suggestions": [
|
||||
{"id": "client-communication", "displayName": "客户沟通辅助", "matchReason": "推荐"},
|
||||
{"id": "supply-chain-collect", "displayName": "供应链信息采集", "matchReason": "推荐"},
|
||||
{"id": "healthcare-data-report", "displayName": "医疗数据报告生成", "matchReason": "推荐"}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
命令注册并工作正常。返回 "no_match" + 推荐列表符合预期(对课堂查询无精确匹配)。
|
||||
|
||||
### ✅ TC-5-03 | Pipeline 执行
|
||||
|
||||
**结果**: PASS(基本执行成功)
|
||||
|
||||
```json
|
||||
{
|
||||
"runId": "25d5dfc3-1f1b-4821-b0b0-3caecb35e6f6",
|
||||
"pipelineId": "research-to-quiz",
|
||||
"status": "running"
|
||||
}
|
||||
```
|
||||
|
||||
Pipeline 异步执行返回 runId,状态为 "running"。`pipeline_runs` 后续查询返回空(可能执行已完成被清理或内存状态问题)。
|
||||
|
||||
### ⏭️ TC-5-04 | Pipeline 监控
|
||||
|
||||
**结果**: SKIP
|
||||
|
||||
`pipeline_runs` 返回空数组,无法验证进度详情。可能与内存 RunStore 生命周期有关。
|
||||
|
||||
### ⏭️ TC-5-06 | Pipeline 取消
|
||||
|
||||
**结果**: SKIP
|
||||
|
||||
需 UI 交互触发取消操作。
|
||||
|
||||
### ⚠️ TC-5-07 | M6-03 验证: Action 类型丢失
|
||||
|
||||
**结果**: FAIL(未修复,代码审查确认)
|
||||
|
||||
crud.rs:78-92 — `WorkflowStepInput` 只有 `hand_name` 字段,所有步骤都被映射为 `Action::Hand`。
|
||||
|
||||
### ⚠️ TC-5-08 | Pipeline 导出
|
||||
|
||||
**结果**: PARTIAL
|
||||
|
||||
`pipeline_templates` 返回空数组(可能需要单独初始化),但 `pipeline_list` 返回完整的模板列表可视为有效的"发现"导出。
|
||||
|
||||
---
|
||||
|
||||
## 健康度评估
|
||||
|
||||
| 维度 | V12 基线 | 本次评估 | 变化 |
|
||||
|------|---------|---------|------|
|
||||
| **综合** | **72/100** | **78/100** | **+6** |
|
||||
|
||||
**提升原因**:
|
||||
- M6-01 P1 route_intent 已注册(lib.rs:220)
|
||||
- M6-02 P1 v1/v2 解析器 fallback 已实现(helpers.rs:93-115)
|
||||
- Pipeline 列举和发现功能完整(15 个模板全部列出)
|
||||
- Pipeline 执行基本工作(run + runId 返回)
|
||||
- 模板覆盖 5+ 行业
|
||||
|
||||
**残留风险**:
|
||||
- pipeline_create 只支持 Hand Action(P2,M6-03)
|
||||
- workflowStore 前端映射语义错误(P2,M6-04/05)
|
||||
- 模板语法混用 `{{}}` vs `${}`(P2,M6-07)
|
||||
- 执行进度只有 0/50/100 三档(P3,M6-08)
|
||||
@@ -0,0 +1,64 @@
|
||||
# T6 SaaS 桌面集成 测试报告
|
||||
|
||||
> **执行日期**: 2026-04-05 | **测试工具**: tauri-mcp execute_js + 代码审查 | **V12 基线**: 85/100
|
||||
|
||||
## 摘要
|
||||
|
||||
- **执行用例数**: 3/6(3 个需 UI 交互或长时间等待)
|
||||
- **已修复 P1**: 2 ✅
|
||||
- **未修复**: 2 ⚠️
|
||||
- **新发现缺陷**: 0
|
||||
|
||||
### 缺陷统计
|
||||
|
||||
| 级别 | 数量 | 说明 |
|
||||
|------|------|------|
|
||||
| P0 | 0 | - |
|
||||
| P1 | 0 | M7-02/M7-04 已修复 |
|
||||
| P2 | 2 | M7-01 密码长度不一致; M7-03 QR码泄露密钥 |
|
||||
| P3 | 2 | M7-05 saveSaaSSession 静默失败; M7-06 chatStream 缺 sessionKey |
|
||||
|
||||
---
|
||||
|
||||
## V12 已知问题验证
|
||||
|
||||
| V12 ID | 描述 | V12 严重度 | 验证结果 | 备注 |
|
||||
|--------|------|-----------|---------|------|
|
||||
| M7-01 | 前端密码 6 字符 vs 后端 8 字符 | P2 | ⚠️ **未修复** | SaaSLogin.tsx:58 使用 6,SaaSSettings.tsx:232 使用 8 |
|
||||
| M7-02 | ConfigMigrationWizard PUT 布尔值 | P1 | ✅ **已修复** | ConfigMigrationWizard.tsx:118 使用 `existing.id` 替代布尔值 |
|
||||
| M7-03 | QR 码外部服务泄露密钥 | P2 | ❓ 未验证 | 需 UI 交互验证 TOTP 设置 |
|
||||
| M7-04 | refreshToken 未传 body | P1 | ✅ **已修复** | saas-auth.ts:70-71 显式发送 `{ refresh_token: this.refreshTokenValue }` |
|
||||
| M7-05 | saveSaaSSession 静默失败 | P3 | ❓ 未验证 | 需端到端验证 |
|
||||
| M7-06 | chatStream 缺 sessionKey/agentId | P3 | ❓ 未验证 | 需端到端验证 |
|
||||
|
||||
## 运行时验证
|
||||
|
||||
### kernel_status
|
||||
|
||||
```json
|
||||
{
|
||||
"initialized": true,
|
||||
"agentCount": 1,
|
||||
"baseUrl": "http://127.0.0.1:8080/api/v1/relay",
|
||||
"model": "glm-4-flash"
|
||||
}
|
||||
```
|
||||
|
||||
SaaS Relay 连接正常。
|
||||
|
||||
---
|
||||
|
||||
## 健康度评估
|
||||
|
||||
| 维度 | V12 基线 | 本次评估 | 变化 |
|
||||
|------|---------|---------|------|
|
||||
| **综合** | **85/100** | **89/100** | **+4** |
|
||||
|
||||
**提升原因**:
|
||||
- M7-02 P1 PUT 路径参数已修复
|
||||
- M7-04 P1 refreshToken body 已修复
|
||||
- SaaS Relay 连接正常
|
||||
|
||||
**残留风险**:
|
||||
- 密码长度前后端不一致(P2,M7-01)
|
||||
- TOTP QR 码外部服务(P2,M7-03)
|
||||
@@ -0,0 +1,69 @@
|
||||
# T7 技能生态 测试报告
|
||||
|
||||
> **执行日期**: 2026-04-05 | **测试工具**: tauri-mcp execute_js + 代码审查 | **V12 基线**: 85/100
|
||||
|
||||
## 摘要
|
||||
|
||||
- **执行用例数**: 4/7(3 个需 UI 交互)
|
||||
- **已修复 P1**: 1 ✅(部分)
|
||||
- **未修复**: 4 ⚠️
|
||||
- **新发现缺陷**: 0
|
||||
|
||||
### 缺陷统计
|
||||
|
||||
| 级别 | 数量 | 说明 |
|
||||
|------|------|------|
|
||||
| P0 | 0 | - |
|
||||
| P1 | 0 | M5-01 部分修复(triggers 正确,category 仍错) |
|
||||
| P2 | 3 | M5-02 tools 字段丢失; M5-03 Python3 硬编码; M5-06 分类不全 |
|
||||
| P3 | 2 | M5-04 YAML 引号; M5-05 duration_ms 未设置 |
|
||||
|
||||
---
|
||||
|
||||
## V12 已知问题验证
|
||||
|
||||
| V12 ID | 描述 | V12 严重度 | 验证结果 | 备注 |
|
||||
|--------|------|-----------|---------|------|
|
||||
| M5-01 | tags 误映射为 triggers | P1 | ⚠️ **部分修复** | triggers 正确返回(skill_list 返回真实 triggers);但 category 仍从 tags[0] 映射,75 个技能全部 category=null |
|
||||
| M5-02 | SKILL.md tools 字段丢失 | P2 | ❓ 未验证 | 需检查 Rust loader |
|
||||
| M5-03 | Python3 硬编码 | P2 | ❓ 未验证 | Windows 兼容性问题 |
|
||||
| M5-04 | YAML 引号只处理双引号 | P3 | ❓ 未验证 | - |
|
||||
| M5-05 | ShellSkill duration_ms 未设置 | P3 | ❓ 未验证 | - |
|
||||
| M5-06 | CATEGORY_CONFIG 仅覆盖 9 分类 | P3 | ⚠️ **未修复** | 75 个技能全为 null,SkillCard 显示灰色 |
|
||||
|
||||
## 运行时验证
|
||||
|
||||
### skill_list
|
||||
|
||||
- **技能总数**: 75
|
||||
- **triggers 字段**: ✅ 正确返回(如 "品牌个性"、"微交互"、"截图验证")
|
||||
- **tags 字段**: 全部为 `[]`(空数组)
|
||||
- **category 字段**: 全部为 `null`
|
||||
|
||||
```json
|
||||
{
|
||||
"count": 75,
|
||||
"sample": [
|
||||
{"name": "whimsy-injector", "tags": [], "triggers": ["品牌个性","微交互","趣味设计"], "category": null},
|
||||
{"name": "evidence-collector", "tags": [], "triggers": ["证据收集","截图验证","QA验证"], "category": null},
|
||||
{"name": "github-deep-research", "tags": [], "triggers": ["分析仓库","GitHub分析"], "category": null}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 健康度评估
|
||||
|
||||
| 维度 | V12 基线 | 本次评估 | 变化 |
|
||||
|------|---------|---------|------|
|
||||
| **综合** | **85/100** | **87/100** | **+2** |
|
||||
|
||||
**提升原因**:
|
||||
- M5-01 triggers 映射已修复(正确使用 backend.triggers)
|
||||
- 75 个技能全部成功加载
|
||||
|
||||
**残留风险**:
|
||||
- category 映射仍从 tags[0] 获取(P2)
|
||||
- 75 个技能全部无分类标签(P2)
|
||||
- Python 技能在 Windows 可能失败(P2)
|
||||
69
docs/archive/old-test-reports/test-results/T8-chat/REPORT.md
Normal file
@@ -0,0 +1,69 @@
|
||||
# T8 智能对话 测试报告
|
||||
|
||||
> **执行日期**: 2026-04-05 | **测试工具**: 代码审查 | **V12 基线**: 91/100
|
||||
|
||||
## 摘要
|
||||
|
||||
- **执行用例数**: 2/8(6 个需端到端 UI 交互,本次仅代码审查)
|
||||
- **代码审查确认**: 11 项 V12 问题验证
|
||||
- **已修复**: 0
|
||||
- **未修复**: 11 ⚠️(全部 P2/P3)
|
||||
- **新发现缺陷**: 0
|
||||
|
||||
### 缺陷统计
|
||||
|
||||
| 级别 | 数量 | 说明 |
|
||||
|------|------|------|
|
||||
| P0 | 0 | - |
|
||||
| P1 | 0 | - |
|
||||
| P2 | 4 | M1-01~04 |
|
||||
| P3 | 7 | M1-05~11 |
|
||||
|
||||
---
|
||||
|
||||
## V12 已知问题验证
|
||||
|
||||
| V12 ID | 描述 | V12 严重度 | 验证结果 | 备注 |
|
||||
|--------|------|-----------|---------|------|
|
||||
| M1-01 | GeminiDriver API Key 在 URL query | P2 | ❓ 需 Gemini 配置验证 | driver/gemini.rs:71-74 |
|
||||
| M1-02 | ToolOutputGuard 只 warn 不 block | P2 | ❓ 需端到端验证 | middleware/tool_output_guard.rs:99-128 |
|
||||
| M1-03 | Mutex::unwrap() 在 async 中 | P2 | ❓ 需 Rust 编译检查 | middleware/memory.rs:46 |
|
||||
| M1-04 | 同上 loop_guard | P2 | ❓ 需 Rust 编译检查 | middleware/loop_guard.rs:40 |
|
||||
| M1-05 | Loop 迭代上限硬编码 10 | P3 | ❓ 需端到端验证 | loop_runner.rs:298 |
|
||||
| M1-06 | TitleMiddleware 空 placeholder | P3 | ❓ 需检查 | middleware/title.rs |
|
||||
| M1-07 | OpenAI driver trace 日志含请求体 | P3 | ❓ 需日志检查 | driver/openai.rs:127 |
|
||||
| M1-08 | cancelStream 竞态条件 | P3 | ❓ 需压力测试 | streamStore.ts:476 |
|
||||
| M1-09 | LoopGuard 不重置跨 agent turns | P3 | ❓ 需多轮测试 | middleware/loop_guard.rs |
|
||||
| M1-10 | SecretString 转为 String | P3 | ❓ 需代码审查 | driver/openai.rs:130 |
|
||||
| M1-11 | unwrap_or_default() 吞错误 | P3 | ❓ 需代码审查 | loop_runner.rs:513,804 |
|
||||
|
||||
## 架构验证
|
||||
|
||||
### ChatStore 重构
|
||||
|
||||
✅ **完成**: 原有单一 chatStore 已拆分为 4 个 sub-store:
|
||||
- `streamStore.ts` — 流式编排
|
||||
- `conversationStore.ts` — 会话管理
|
||||
- `messageStore.ts` — 消息变更 + token 追踪
|
||||
- `artifactStore.ts` — 文件/制品状态
|
||||
|
||||
顶层 `chatStore.ts` 作为 facade 统一导出,通过跨 store 订阅和依赖注入连接。
|
||||
|
||||
### 中间件链
|
||||
|
||||
11 层中间件已确认存在:
|
||||
tool_output_guard, memory, loop_guard, guardrail, title, summarizer, extraction, growth_integration, context_window, mcp_bridge, system_prompt
|
||||
|
||||
---
|
||||
|
||||
## 健康度评估
|
||||
|
||||
| 维度 | V12 基线 | 本次评估 | 变化 |
|
||||
|------|---------|---------|------|
|
||||
| **综合** | **91/100** | **91/100** | **0** |
|
||||
|
||||
**评估说明**:
|
||||
- T8 健康度最高(91/100),无 P0/P1 问题
|
||||
- ChatStore 重构完成,架构质量提升
|
||||
- 全部 11 项 V12 问题为 P2/P3,无阻塞性缺陷
|
||||
- 需端到端验证的问题留待 Phase 3/4 或自动化测试覆盖
|
||||
@@ -0,0 +1,57 @@
|
||||
# ZCLAW 上线前功能审计 — 基线测试结果
|
||||
|
||||
> **执行日期**: 2026-04-05 | **环境**: Windows 11, PostgreSQL + SaaS + Tauri 已启动
|
||||
|
||||
## 自动化测试基线
|
||||
|
||||
### cargo test --workspace
|
||||
|
||||
- **状态**: ⚠️ 部分完成
|
||||
- **问题**: zclaw-saas.exe 被运行中的 SaaS 后端锁定,无法重新编译
|
||||
- **解决方案**: 排除 zclaw-saas 重跑,结果待补充
|
||||
- **cargo check**: ✅ 通过(0 error,仅 warnings)
|
||||
|
||||
### desktop vitest (174/185 passed)
|
||||
|
||||
- **通过**: 174
|
||||
- **失败**: 10
|
||||
- **跳过**: 1
|
||||
- **失败原因**: 全部在 `chatStore.test.ts`,因 ChatStore 4-sub-store 重构后测试未同步更新
|
||||
- **失败测试**:
|
||||
- `chatStore` > `createConversation` 相关 3 个
|
||||
- `chatStore` > `sendMessage` 相关 4 个
|
||||
- `chatStore` > `conversations` 相关 3 个
|
||||
|
||||
### admin-v2 vitest (36/71 passed)
|
||||
|
||||
- **通过**: 36
|
||||
- **失败**: 35
|
||||
- **失败分布**:
|
||||
- authStore.test.ts: 6/8 failed (localStorage mock 问题)
|
||||
- request.test.ts: 2/7 failed (Authorization header / 401 refresh)
|
||||
- accountStore.test.ts: 多个 CRUD 测试失败
|
||||
- 其他页面测试: relay, usage, prompt 等
|
||||
|
||||
## 环境验证
|
||||
|
||||
| 项目 | 状态 | 备注 |
|
||||
|------|------|------|
|
||||
| PostgreSQL | ✅ 运行中 | Docker 容器 |
|
||||
| SaaS 后端 | ✅ 运行中 | 0.0.0.0:8080 |
|
||||
| Tauri 桌面端 | ✅ 运行中 | http://localhost:1420/ |
|
||||
| tauri-mcp | ✅ 连接正常 | 可查询/交互 |
|
||||
| LLM Provider | ✅ 可用 | glm-4-flash (GLM) |
|
||||
|
||||
## 已知基线缺陷(非本轮引入)
|
||||
|
||||
1. **desktop chatStore 测试**: ChatStore 拆分为 4 个 sub-store 后测试未更新
|
||||
2. **admin authStore 测试**: jsdom 环境下 localStorage API 兼容问题
|
||||
3. **admin 多页面测试**: 依赖真实 API 端点,vitest 环境无法访问
|
||||
|
||||
## T1 Hands 测试已完成
|
||||
|
||||
详见 [T1-hands/REPORT.md](../T1-hands/REPORT.md)
|
||||
|
||||
- 通过: 11/18 执行用例
|
||||
- 健康度: 58 → 68 (+10)
|
||||
- 新发现 P1: 2 个 (LLM 并发 + Browser Hand)
|
||||
5932
docs/archive/old-test-reports/test-results/baseline/admin-vitest.txt
Normal file
@@ -0,0 +1,44 @@
|
||||
warning: G:\ZClaw_openfang\desktop\src-tauri\Cargo.toml: Found `debug_assertions` in `target.'cfg(...)'.dependencies`. This value is not supported for selecting dependencies and will not work as expected. To learn more visit https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#platform-specific-dependencies
|
||||
Blocking waiting for file lock on package cache
|
||||
Blocking waiting for file lock on package cache
|
||||
Blocking waiting for file lock on package cache
|
||||
Blocking waiting for file lock on build directory
|
||||
warning: unused import: `parse_pipeline_v2_yaml`
|
||||
--> desktop\src-tauri\src\pipeline_commands\discovery.rs:9:5
|
||||
|
|
||||
9 | parse_pipeline_v2_yaml,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(unused_imports)]` (part of `#[warn(unused)]`) on by default
|
||||
|
||||
warning: unused import: `pipeline_v2_to_info`
|
||||
--> desktop\src-tauri\src\pipeline_commands\discovery.rs:19:118
|
||||
|
|
||||
19 | use super::helpers::{get_pipelines_directory, scan_pipelines_with_paths, scan_pipelines_full_sync, pipeline_to_info, pipeline_v2_to_info};
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: field `offset` is never read
|
||||
--> desktop\src-tauri\src\memory\persistent.rs:126:9
|
||||
|
|
||||
118 | pub struct MemorySearchQuery {
|
||||
| ----------------- field in this struct
|
||||
...
|
||||
126 | pub offset: Option<usize>,
|
||||
| ^^^^^^
|
||||
|
|
||||
= note: `MemorySearchQuery` has derived impls for the traits `Clone` and `Debug`, but these are intentionally ignored during dead code analysis
|
||||
= note: `#[warn(dead_code)]` (part of `#[warn(unused)]`) on by default
|
||||
|
||||
warning: method `delete_classroom` is never used
|
||||
--> desktop\src-tauri\src\classroom_commands\persist.rs:104:18
|
||||
|
|
||||
21 | impl ClassroomPersistence {
|
||||
| ------------------------- method in this implementation
|
||||
...
|
||||
104 | pub async fn delete_classroom(&self, classroom_id: &str) -> Result<(), String> {
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: `desktop` (lib) generated 4 warnings (run `cargo fix --lib -p desktop` to apply 2 suggestions)
|
||||
Finished `dev` profile [unoptimized + debuginfo] target(s) in 5m 38s
|
||||
warning: the following packages contain code that will be rejected by a future version of Rust: sqlx-postgres v0.7.4
|
||||
note: to see what the problems were, use the option `--future-incompat-report`, or run `cargo report future-incompatibilities --id 2`
|
||||
@@ -0,0 +1,781 @@
|
||||
warning: G:\ZClaw_openfang\desktop\src-tauri\Cargo.toml: Found `debug_assertions` in `target.'cfg(...)'.dependencies`. This value is not supported for selecting dependencies and will not work as expected. To learn more visit https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#platform-specific-dependencies
|
||||
Compiling sqlx-core v0.7.4
|
||||
Compiling sqlx-postgres v0.7.4
|
||||
Compiling sqlx-sqlite v0.7.4
|
||||
Compiling sqlx-macros-core v0.7.4
|
||||
Compiling sqlx-macros v0.7.4
|
||||
Compiling sqlx v0.7.4
|
||||
Compiling tokio-rustls v0.26.4
|
||||
Compiling zclaw-growth v0.1.0 (G:\ZClaw_openfang\crates\zclaw-growth)
|
||||
Compiling hyper-rustls v0.27.7
|
||||
Compiling reqwest v0.12.28
|
||||
Compiling zclaw-memory v0.1.0 (G:\ZClaw_openfang\crates\zclaw-memory)
|
||||
Compiling zclaw-runtime v0.1.0 (G:\ZClaw_openfang\crates\zclaw-runtime)
|
||||
Compiling zclaw-protocols v0.1.0 (G:\ZClaw_openfang\crates\zclaw-protocols)
|
||||
Compiling tauri v2.10.3
|
||||
Compiling zclaw-hands v0.1.0 (G:\ZClaw_openfang\crates\zclaw-hands)
|
||||
Compiling interprocess v2.4.0
|
||||
Compiling image v0.24.9
|
||||
Compiling zclaw-kernel v0.1.0 (G:\ZClaw_openfang\crates\zclaw-kernel)
|
||||
Compiling zclaw-pipeline v0.1.0 (G:\ZClaw_openfang\crates\zclaw-pipeline)
|
||||
Compiling desktop v0.1.0 (G:\ZClaw_openfang\desktop\src-tauri)
|
||||
Compiling tauri-plugin-opener v2.5.3
|
||||
Compiling tauri-plugin-mcp v0.1.0 (https://github.com/P3GLEG/tauri-plugin-mcp?branch=main#ac709a71)
|
||||
Compiling criterion v0.5.1
|
||||
warning: unused import: `parse_pipeline_v2_yaml`
|
||||
--> desktop\src-tauri\src\pipeline_commands\discovery.rs:9:5
|
||||
|
|
||||
9 | parse_pipeline_v2_yaml,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(unused_imports)]` (part of `#[warn(unused)]`) on by default
|
||||
|
||||
warning: unused import: `pipeline_v2_to_info`
|
||||
--> desktop\src-tauri\src\pipeline_commands\discovery.rs:19:118
|
||||
|
|
||||
19 | use super::helpers::{get_pipelines_directory, scan_pipelines_with_paths, scan_pipelines_full_sync, pipeline_to_info, pipeline_v2_to_info};
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: field `offset` is never read
|
||||
--> desktop\src-tauri\src\memory\persistent.rs:126:9
|
||||
|
|
||||
118 | pub struct MemorySearchQuery {
|
||||
| ----------------- field in this struct
|
||||
...
|
||||
126 | pub offset: Option<usize>,
|
||||
| ^^^^^^
|
||||
|
|
||||
= note: `MemorySearchQuery` has derived impls for the traits `Clone` and `Debug`, but these are intentionally ignored during dead code analysis
|
||||
= note: `#[warn(dead_code)]` (part of `#[warn(unused)]`) on by default
|
||||
|
||||
warning: method `delete_classroom` is never used
|
||||
--> desktop\src-tauri\src\classroom_commands\persist.rs:104:18
|
||||
|
|
||||
21 | impl ClassroomPersistence {
|
||||
| ------------------------- method in this implementation
|
||||
...
|
||||
104 | pub async fn delete_classroom(&self, classroom_id: &str) -> Result<(), String> {
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: unused import: `zclaw_growth::MemoryType`
|
||||
--> desktop\src-tauri\src\summarizer_adapter.rs:114:9
|
||||
|
|
||||
114 | use zclaw_growth::MemoryType;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(unused_imports)]` (part of `#[warn(unused)]`) on by default
|
||||
|
||||
warning: unused import: `parse_pipeline_v2_yaml`
|
||||
--> desktop\src-tauri\src\pipeline_commands\discovery.rs:9:5
|
||||
|
|
||||
9 | parse_pipeline_v2_yaml,
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: struct `DummyDriver` is never constructed
|
||||
--> desktop\src-tauri\src\intelligence\extraction_adapter.rs:279:16
|
||||
|
|
||||
279 | struct DummyDriver;
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
warning: method `parse_response_test` is never used
|
||||
--> desktop\src-tauri\src\intelligence\extraction_adapter.rs:281:16
|
||||
|
|
||||
280 | impl TauriExtractionDriver {
|
||||
| -------------------------- method in this implementation
|
||||
281 | fn parse_response_test(
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
warning: non-local `impl` definition, `impl` blocks should be written at the same level as their item
|
||||
--> desktop\src-tauri\src\intelligence\extraction_adapter.rs:280:9
|
||||
|
|
||||
276 | fn test_parse_empty_response() {
|
||||
| ------------------------------ move the `impl` block outside of this function `test_parse_empty_response`
|
||||
...
|
||||
280 | impl TauriExtractionDriver {
|
||||
| ^^^^^---------------------
|
||||
| |
|
||||
| `TauriExtractionDriver` is not local
|
||||
|
|
||||
= note: an `impl` is never scoped, even when it is nested inside an item, as it may impact type checking outside of that item, which can be the case if neither the trait or the self type are at the same nesting level as the `impl`
|
||||
= note: `#[warn(non_local_definitions)]` on by default
|
||||
|
||||
warning: `desktop` (lib test) generated 8 warnings (3 duplicates) (run `cargo fix --lib -p desktop --tests` to apply 2 suggestions)
|
||||
warning: unused import: `compile_pattern`
|
||||
--> crates\zclaw-pipeline\src\intent.rs:631:26
|
||||
|
|
||||
631 | use crate::trigger::{compile_pattern, compile_trigger, Trigger};
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(unused_imports)]` (part of `#[warn(unused)]`) on by default
|
||||
|
||||
warning: `desktop` (lib) generated 4 warnings (run `cargo fix --lib -p desktop` to apply 2 suggestions)
|
||||
warning: `zclaw-pipeline` (lib test) generated 1 warning (run `cargo fix --lib -p zclaw-pipeline --tests` to apply 1 suggestion)
|
||||
warning: function `test_context` is never used
|
||||
--> crates\zclaw-hands\src\hands\researcher.rs:583:8
|
||||
|
|
||||
583 | fn test_context() -> HandContext {
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
= note: `#[warn(dead_code)]` (part of `#[warn(unused)]`) on by default
|
||||
|
||||
warning: `zclaw-hands` (lib test) generated 1 warning
|
||||
Finished `test` profile [unoptimized + debuginfo] target(s) in 3m 33s
|
||||
warning: the following packages contain code that will be rejected by a future version of Rust: sqlx-postgres v0.7.4
|
||||
note: to see what the problems were, use the option `--future-incompat-report`, or run `cargo report future-incompatibilities --id 2`
|
||||
Running unittests src\lib.rs (target\debug\deps\desktop_lib-7e14a4a33859881e.exe)
|
||||
|
||||
running 36 tests
|
||||
test intelligence::compactor::tests::test_estimate_tokens_chinese ... ok
|
||||
test intelligence::compactor::tests::test_compaction_check ... ok
|
||||
test intelligence::heartbeat::tests::test_parse_time ... ok
|
||||
test intelligence::extraction_adapter::tests::test_parse_no_json_array ... ok
|
||||
test intelligence::extraction_adapter::tests::test_parse_empty_response ... ok
|
||||
test intelligence::reflection::tests::test_analyze_patterns ... ok
|
||||
test intelligence::heartbeat::tests::test_default_config ... ok
|
||||
test intelligence::compactor::tests::test_estimate_tokens_english ... ok
|
||||
test intelligence::extraction_adapter::tests::test_parse_valid_json_response ... ok
|
||||
test intelligence::extraction_adapter::tests::test_extraction_driver_not_configured_by_default ... ok
|
||||
test intelligence::reflection::tests::test_should_reflect_initial ... ok
|
||||
test intelligence::validation::tests::test_optional_identifier ... ok
|
||||
test intelligence::validation::tests::test_invalid_identifiers ... ok
|
||||
test intelligence::validation::tests::test_sanitize_for_logging ... ok
|
||||
test intelligence::validation::tests::test_string_length_validation ... ok
|
||||
test intelligence::validation::tests::test_valid_identifiers ... ok
|
||||
test llm::tests::test_llm_client_creation ... ok
|
||||
test llm::tests::test_provider_configs ... ok
|
||||
test memory::context_builder::tests::test_estimate_tokens ... ok
|
||||
test memory::persistent::tests::test_generate_memory_id ... ok
|
||||
test memory::extractor::tests::test_extraction_config_default ... ok
|
||||
test memory::crypto::tests::test_derive_key ... ok
|
||||
test memory::extractor::tests::test_uri_generation ... ok
|
||||
test memory::crypto::tests::test_encrypt_decrypt ... ok
|
||||
test memory::context_builder::tests::test_context_builder_config_default ... ok
|
||||
test memory::context_builder::tests::test_extract_category ... ok
|
||||
test summarizer_adapter::tests::test_summary_driver_configure_and_check ... ok
|
||||
test viking_commands::tests::test_invalid_uri ... ok
|
||||
test summarizer_adapter::tests::test_summary_driver_not_configured_by_default ... ok
|
||||
test memory::crypto::tests::test_encrypt_produces_different_ciphertext ... ok
|
||||
test viking_commands::tests::test_parse_uri ... ok
|
||||
test intelligence::identity::tests::test_get_identity_creates_default ... ok
|
||||
test intelligence::identity::tests::test_update_user_profile ... ok
|
||||
test intelligence::identity::tests::test_snapshots ... ok
|
||||
test intelligence::identity::tests::test_proposal_flow ... ok
|
||||
test intelligence::compactor::tests::test_generate_summary ... ok
|
||||
|
||||
test result: ok. 36 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.02s
|
||||
|
||||
Running unittests src\main.rs (target\debug\deps\desktop-c3cc535c9683aa3d.exe)
|
||||
|
||||
running 0 tests
|
||||
|
||||
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
|
||||
|
||||
Running unittests src\lib.rs (target\debug\deps\zclaw_growth-0cc62226cc107d52.exe)
|
||||
|
||||
running 66 tests
|
||||
test extractor::tests::test_prompts_available ... ok
|
||||
test injector::tests::test_injector_empty_memories ... ok
|
||||
test injector::tests::test_estimate_tokens ... ok
|
||||
test injector::tests::test_minimal_context ... ok
|
||||
test injector::tests::test_injector_with_preferences ... ok
|
||||
test injector::tests::test_inject_compact ... ok
|
||||
test injector::tests::test_injector_with_all_types ... ok
|
||||
test injector::tests::test_format_selection ... ok
|
||||
test injector::tests::test_inject_custom ... ok
|
||||
test injector::tests::test_inject_json ... ok
|
||||
test retrieval::query::tests::test_cjk_detection ... ok
|
||||
test extractor::tests::test_extractor_creation ... ok
|
||||
test retrieval::cache::tests::test_cache_miss ... ok
|
||||
test retrieval::cache::tests::test_cache_stats ... ok
|
||||
test retrieval::cache::tests::test_cache_eviction ... ok
|
||||
test retrieval::cache::tests::test_cache_put_and_get ... ok
|
||||
test retrieval::cache::tests::test_cache_remove ... ok
|
||||
test retrieval::query::tests::test_extract_keywords ... ok
|
||||
test retrieval::query::tests::test_chinese_keywords ... ok
|
||||
test retrieval::semantic::tests::test_cosine_similarity ... ok
|
||||
test extractor::tests::test_extract_memories ... ok
|
||||
test retrieval::query::tests::test_classify_intent_code ... ok
|
||||
test retrieval::cache::tests::test_get_hot_entries ... ok
|
||||
test retrieval::query::tests::test_classify_intent_knowledge ... ok
|
||||
test retrieval::cache::tests::test_cache_clear ... ok
|
||||
test retrieval::query::tests::test_classify_intent_preference ... ok
|
||||
test retrieval::query::tests::test_query_expansion ... ok
|
||||
test retrieval::query::tests::test_generate_search_queries ... ok
|
||||
test retrieval::semantic::tests::test_tf_computation ... ok
|
||||
test retrieval::semantic::tests::test_stop_words_removal ... ok
|
||||
test retrieval::semantic::tests::test_tokenize ... ok
|
||||
test retrieval::semantic::tests::test_index_and_score ... ok
|
||||
test retrieval::semantic::tests::test_stats ... ok
|
||||
test retriever::tests::test_memory_type_scope ... ok
|
||||
test retriever::tests::test_retrieval_config_default ... ok
|
||||
test retriever::tests::test_retriever_creation ... ok
|
||||
test summarizer::tests::test_abstract_prompt ... ok
|
||||
test summarizer::tests::test_clean_summary ... ok
|
||||
test summarizer::tests::test_generate_summaries ... ok
|
||||
test summarizer::tests::test_overview_prompt ... ok
|
||||
test summarizer::tests::test_generate_summaries_handles_error ... ok
|
||||
test tests::test_growth_config_default ... ok
|
||||
test tests::test_memory_type_reexport ... ok
|
||||
test types::tests::test_estimated_tokens ... ok
|
||||
test types::tests::test_memory_entry_creation ... ok
|
||||
test types::tests::test_memory_entry_touch ... ok
|
||||
test tracker::tests::test_agent_metadata_serialization ... ok
|
||||
test tracker::tests::test_learning_event_serialization ... ok
|
||||
test types::tests::test_memory_type_display ... ok
|
||||
test types::tests::test_retrieval_config_default ... ok
|
||||
test types::tests::test_retrieval_config_with_budget ... ok
|
||||
test types::tests::test_retrieval_result ... ok
|
||||
test types::tests::test_uri_builder ... ok
|
||||
test types::tests::test_uri_parser ... ok
|
||||
test viking_adapter::tests::test_in_memory_storage_delete ... ok
|
||||
test viking_adapter::tests::test_metadata_storage ... ok
|
||||
test viking_adapter::tests::test_viking_adapter_typed_metadata ... ok
|
||||
test viking_adapter::tests::test_in_memory_storage_store_and_get ... ok
|
||||
test viking_adapter::tests::test_viking_level_display ... ok
|
||||
test viking_adapter::tests::test_in_memory_storage_find ... ok
|
||||
test storage::sqlite::tests::test_metadata_storage ... ok
|
||||
test storage::sqlite::tests::test_sqlite_storage_store_and_get ... ok
|
||||
test storage::sqlite::tests::test_sqlite_storage_delete ... ok
|
||||
test storage::sqlite::tests::test_access_count ... ok
|
||||
test storage::sqlite::tests::test_sqlite_storage_semantic_search ... ok
|
||||
test storage::sqlite::tests::test_persistence ... ok
|
||||
|
||||
test result: ok. 66 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.07s
|
||||
|
||||
Running tests\integration_test.rs (target\debug\deps\integration_test-4b889886bf0ebf9e.exe)
|
||||
|
||||
running 9 tests
|
||||
test test_prompt_injection_token_budget ... ok
|
||||
test test_metadata_operations ... ok
|
||||
test test_chinese_text_handling ... ok
|
||||
test test_memory_deletion ... ok
|
||||
test test_semantic_search_ranking ... ok
|
||||
test test_find_by_prefix ... ok
|
||||
test test_agent_isolation ... ok
|
||||
test test_importance_and_access ... ok
|
||||
test test_memory_lifecycle ... ok
|
||||
|
||||
test result: ok. 9 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.04s
|
||||
|
||||
Running unittests src\lib.rs (target\debug\deps\zclaw_hands-ddb5fe00a71de8d9.exe)
|
||||
|
||||
running 155 tests
|
||||
test hands::browser::tests::test_browser_config ... ok
|
||||
test hands::browser::tests::test_form_field_deserialize ... ok
|
||||
test hands::clip::tests::test_action_check_ffmpeg ... ok
|
||||
test hands::browser::tests::test_action_deserialize_screenshot ... ok
|
||||
test hands::browser::tests::test_action_deserialize_type ... ok
|
||||
test hands::clip::tests::test_action_info ... ok
|
||||
test hands::clip::tests::test_action_invalid ... ok
|
||||
test hands::browser::tests::test_action_deserialize_navigate ... ok
|
||||
test hands::clip::tests::test_action_convert ... ok
|
||||
test hands::clip::tests::test_action_resize ... ok
|
||||
test hands::browser::tests::test_action_deserialize_click ... ok
|
||||
test hands::clip::tests::test_action_thumbnail ... ok
|
||||
test hands::clip::tests::test_action_concat ... ok
|
||||
test hands::browser::tests::test_action_deserialize_scrape ... ok
|
||||
test hands::clip::tests::test_action_trim ... ok
|
||||
test hands::clip::tests::test_concat_config_deserialize ... ok
|
||||
test hands::browser::tests::test_all_major_actions_roundtrip ... ok
|
||||
test hands::clip::tests::test_convert_config_defaults ... ok
|
||||
test hands::browser::tests::test_browser_config_needs_approval ... ok
|
||||
test hands::clip::tests::test_convert_config_deserialize ... ok
|
||||
test hands::browser::tests::test_browser_sequence_builder ... ok
|
||||
test hands::browser::tests::test_browser_sequence_multiple_steps ... ok
|
||||
test hands::clip::tests::test_default_impl ... ok
|
||||
test hands::clip::tests::test_info_action_roundtrip ... ok
|
||||
test hands::clip::tests::test_hand_config ... ok
|
||||
test hands::clip::tests::test_resolution_custom ... ok
|
||||
test hands::clip::tests::test_resolution_default ... ok
|
||||
test hands::clip::tests::test_resolution_presets ... ok
|
||||
test hands::clip::tests::test_needs_approval ... ok
|
||||
test hands::clip::tests::test_execute_invalid_action ... ok
|
||||
test hands::clip::tests::test_resolution_serialize ... ok
|
||||
test hands::clip::tests::test_thumbnail_config_defaults ... ok
|
||||
test hands::clip::tests::test_thumbnail_config_deserialize ... ok
|
||||
test hands::clip::tests::test_trim_action_roundtrip ... ok
|
||||
test hands::clip::tests::test_trim_config_deserialize ... ok
|
||||
test hands::clip::tests::test_trim_config_minimal ... ok
|
||||
test hands::clip::tests::test_video_format_deserialize ... ok
|
||||
test hands::clip::tests::test_video_format_default ... ok
|
||||
test hands::clip::tests::test_video_info_deserialize ... ok
|
||||
test hands::clip::tests::test_video_format_serialize ... ok
|
||||
test hands::collector::tests::test_collection_target_deserialize ... ok
|
||||
test hands::collector::tests::test_collector_action_deserialize ... ok
|
||||
test hands::collector::tests::test_collector_config ... ok
|
||||
test hands::collector::tests::test_aggregate_action_empty_urls ... ok
|
||||
test hands::collector::tests::test_extract_visible_text_empty ... ok
|
||||
test hands::researcher::tests::test_action_fetch_deserialize ... ok
|
||||
test hands::collector::tests::test_extract_visible_text_basic ... ok
|
||||
test hands::collector::tests::test_extract_visible_text_strips_scripts ... ok
|
||||
test hands::researcher::tests::test_action_invalid_rejected ... ok
|
||||
test hands::collector::tests::test_extract_visible_text_strips_styles ... ok
|
||||
test hands::quiz::tests::test_quiz_creation ... ok
|
||||
test hands::quiz::tests::test_export_markdown ... ok
|
||||
test hands::collector::tests::test_output_format_serialize ... ok
|
||||
test hands::quiz::tests::test_submit_and_grade ... ok
|
||||
test hands::quiz::tests::test_generate_quiz ... ok
|
||||
test hands::researcher::tests::test_action_search_deserialize ... ok
|
||||
test hands::researcher::tests::test_action_report_deserialize ... ok
|
||||
test hands::quiz::tests::test_show_question ... ok
|
||||
test hands::researcher::tests::test_config_id ... ok
|
||||
test hands::researcher::tests::test_check_dependencies_ok ... ok
|
||||
test hands::researcher::tests::test_extract_text_empty_body ... ok
|
||||
test hands::researcher::tests::test_extract_text_basic ... ok
|
||||
test hands::researcher::tests::test_extract_text_strips_scripts ... ok
|
||||
test hands::researcher::tests::test_extract_text_strips_styles ... ok
|
||||
test hands::researcher::tests::test_research_depth_default_is_standard ... ok
|
||||
test hands::clip::tests::test_check_dependencies ... ok
|
||||
test hands::researcher::tests::test_research_depth_deserialize ... ok
|
||||
test hands::researcher::tests::test_research_depth_serialize ... ok
|
||||
test hands::researcher::tests::test_research_query_defaults ... ok
|
||||
test hands::researcher::tests::test_needs_approval_is_false ... ok
|
||||
test hands::researcher::tests::test_research_report_summary_is_some_when_results ... ok
|
||||
test hands::researcher::tests::test_search_engine_default_is_auto ... ok
|
||||
test hands::researcher::tests::test_search_engine_serialize_roundtrip ... ok
|
||||
test hands::clip::tests::test_execute_check_ffmpeg ... ok
|
||||
test hands::researcher::tests::test_search_result_serialization ... ok
|
||||
test hands::researcher::tests::test_url_encode_ascii ... ok
|
||||
test hands::researcher::tests::test_extract_text_truncates_long_content ... ok
|
||||
test hands::researcher::tests::test_url_encode_chinese ... ok
|
||||
test hands::researcher::tests::test_url_encode_empty ... ok
|
||||
test hands::clip::tests::test_status ... ok
|
||||
test hands::researcher::tests::test_url_encode_safe_chars ... ok
|
||||
test hands::researcher::tests::test_status_is_idle ... ok
|
||||
test hands::slideshow::tests::test_add_slide ... ok
|
||||
test hands::slideshow::tests::test_content_block_code ... ok
|
||||
test hands::slideshow::tests::test_autoplay_default_interval ... ok
|
||||
test hands::slideshow::tests::test_autoplay_pause_resume ... ok
|
||||
test hands::slideshow::tests::test_content_block_list ... ok
|
||||
test hands::slideshow::tests::test_content_block_table ... ok
|
||||
test hands::slideshow::tests::test_default_impl ... ok
|
||||
test hands::slideshow::tests::test_default_state ... ok
|
||||
test hands::slideshow::tests::test_content_block_text ... ok
|
||||
test hands::slideshow::tests::test_deserialize_autoplay ... ok
|
||||
test hands::slideshow::tests::test_deserialize_goto_slide ... ok
|
||||
test hands::slideshow::tests::test_deserialize_laser ... ok
|
||||
test hands::slideshow::tests::test_deserialize_next_slide ... ok
|
||||
test hands::slideshow::tests::test_deserialize_invalid_action ... ok
|
||||
test hands::slideshow::tests::test_goto_slide_out_of_range ... ok
|
||||
test hands::slideshow::tests::test_get_state ... ok
|
||||
test hands::slideshow::tests::test_goto_slide_returns_content ... ok
|
||||
test hands::slideshow::tests::test_hand_execute_dispatch ... ok
|
||||
test hands::slideshow::tests::test_hand_execute_invalid_action ... ok
|
||||
test hands::slideshow::tests::test_highlight_custom_color ... ok
|
||||
test hands::slideshow::tests::test_highlight_default_color ... ok
|
||||
test hands::slideshow::tests::test_needs_approval ... ok
|
||||
test hands::slideshow::tests::test_laser ... ok
|
||||
test hands::slideshow::tests::test_navigation ... ok
|
||||
test hands::slideshow::tests::test_next_slide_at_end ... ok
|
||||
test hands::slideshow::tests::test_play_animation ... ok
|
||||
test hands::slideshow::tests::test_prev_slide_at_beginning ... ok
|
||||
test hands::slideshow::tests::test_set_content_append ... ok
|
||||
test hands::slideshow::tests::test_slideshow_creation ... ok
|
||||
test hands::slideshow::tests::test_set_content_invalid_index ... ok
|
||||
test hands::slideshow::tests::test_set_content ... ok
|
||||
test hands::slideshow::tests::test_spotlight ... ok
|
||||
test hands::slideshow::tests::test_spotlight_default_duration ... ok
|
||||
test hands::speech::tests::test_speak ... ok
|
||||
test hands::slideshow::tests::test_status ... ok
|
||||
test hands::speech::tests::test_pause_resume ... ok
|
||||
test hands::speech::tests::test_set_voice ... ok
|
||||
test hands::speech::tests::test_list_voices ... ok
|
||||
test hands::speech::tests::test_speech_creation ... ok
|
||||
test hands::twitter::tests::test_check_credentials_action ... ok
|
||||
test hands::twitter::tests::test_check_dependencies ... ok
|
||||
test hands::twitter::tests::test_check_credentials_with_config ... ok
|
||||
test hands::twitter::tests::test_default_impl ... ok
|
||||
test hands::twitter::tests::test_delete_tweet_action ... ok
|
||||
test hands::twitter::tests::test_check_credentials_without_config ... ok
|
||||
test hands::twitter::tests::test_followers_action ... ok
|
||||
test hands::twitter::tests::test_following_action_no_max ... ok
|
||||
test hands::twitter::tests::test_get_tweet_action ... ok
|
||||
test hands::twitter::tests::test_invalid_action ... ok
|
||||
test hands::twitter::tests::test_get_user_action ... ok
|
||||
test hands::twitter::tests::test_hand_config ... ok
|
||||
test hands::twitter::tests::test_like_unlike_actions ... ok
|
||||
test hands::twitter::tests::test_media_info_deserialize ... ok
|
||||
test hands::twitter::tests::test_needs_approval ... ok
|
||||
test hands::twitter::tests::test_retweet_unretweet_actions ... ok
|
||||
test hands::twitter::tests::test_search_action_custom_max ... ok
|
||||
test hands::twitter::tests::test_search_action_defaults ... ok
|
||||
test hands::twitter::tests::test_search_action_roundtrip ... ok
|
||||
test hands::twitter::tests::test_tweet_action_deserialize ... ok
|
||||
test hands::twitter::tests::test_timeline_action_defaults ... ok
|
||||
test hands::twitter::tests::test_tweet_action_roundtrip ... ok
|
||||
test hands::twitter::tests::test_status ... ok
|
||||
test hands::twitter::tests::test_set_and_get_credentials ... ok
|
||||
test hands::twitter::tests::test_tweet_action_with_poll ... ok
|
||||
test hands::twitter::tests::test_tweet_action_with_reply ... ok
|
||||
test hands::twitter::tests::test_tweet_deserialize ... ok
|
||||
test hands::twitter::tests::test_twitter_user_deserialize ... ok
|
||||
test hands::whiteboard::tests::test_draw_shape ... ok
|
||||
test hands::whiteboard::tests::test_chart ... ok
|
||||
test hands::whiteboard::tests::test_undo_redo ... ok
|
||||
test hands::whiteboard::tests::test_whiteboard_creation ... ok
|
||||
test hands::whiteboard::tests::test_clear ... ok
|
||||
test hands::whiteboard::tests::test_draw_text ... ok
|
||||
|
||||
test result: ok. 155 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.02s
|
||||
|
||||
Running unittests src\lib.rs (target\debug\deps\zclaw_kernel-2ce44e6daaebc1d9.exe)
|
||||
|
||||
running 48 tests
|
||||
test config::tests::test_interpolate_env_vars_basic ... ok
|
||||
test config::tests::test_interpolate_env_vars_missing ... ok
|
||||
test config::tests::test_interpolate_env_vars_no_vars ... ok
|
||||
test config::tests::test_interpolate_env_vars_multiple ... ok
|
||||
test export::html::tests::test_format_duration ... ok
|
||||
test export::html::tests::test_format_level ... ok
|
||||
test export::html::tests::test_html_escape ... ok
|
||||
test export::markdown::tests::test_capitalize_first ... ok
|
||||
test export::markdown::tests::test_format_duration ... ok
|
||||
test export::markdown::tests::test_slugify ... ok
|
||||
test export::pptx::tests::test_pptx_format ... ok
|
||||
test export::pptx::tests::test_xml_escape ... ok
|
||||
test export::markdown::tests::test_markdown_export ... ok
|
||||
test export::markdown::tests::test_include_notes ... ok
|
||||
test export::html::tests::test_html_export ... ok
|
||||
test export::tests::test_sanitize_filename ... ok
|
||||
test generation::agents::tests::test_agent_role_display ... ok
|
||||
test export::markdown::tests::test_include_answers ... ok
|
||||
test export::markdown::tests::test_table_of_contents ... ok
|
||||
test generation::agents::tests::test_default_request ... ok
|
||||
test export::html::tests::test_include_notes ... ok
|
||||
test generation::agents::tests::test_generate_chinese_profiles ... ok
|
||||
test generation::chat::tests::test_agent_message ... ok
|
||||
test generation::chat::tests::test_build_chat_prompt ... ok
|
||||
test generation::agents::tests::test_generate_english_profiles ... ok
|
||||
test generation::chat::tests::test_parse_chat_responses_fallback ... ok
|
||||
test generation::chat::tests::test_parse_chat_responses_valid_json ... ok
|
||||
test generation::chat::tests::test_user_message ... ok
|
||||
test generation::tests::test_generation_stage_order ... ok
|
||||
test generation::tests::test_teaching_style_default ... ok
|
||||
test scheduler::tests::test_cron_field_exact ... ok
|
||||
test scheduler::tests::test_cron_field_list ... ok
|
||||
test generation::tests::test_scene_action_serialization ... ok
|
||||
test scheduler::tests::test_cron_field_range ... ok
|
||||
test scheduler::tests::test_cron_field_step ... ok
|
||||
test generation::tests::test_pipeline_creation ... ok
|
||||
test generation::tests::test_generate_outline ... ok
|
||||
test scheduler::tests::test_cron_field_wildcard ... ok
|
||||
test generation::tests::test_generate_agent_profiles ... ok
|
||||
test generation::tests::test_generate_scenes ... ok
|
||||
test scheduler::tests::test_should_fire_every_minute ... ok
|
||||
test scheduler::tests::test_should_fire_cron_wildcard ... ok
|
||||
test scheduler::tests::test_should_not_fire_cron ... ok
|
||||
test skill_router::tests::test_extract_json_bare ... ok
|
||||
test skill_router::tests::test_extract_json_code_block ... ok
|
||||
test generation::tests::test_full_generation ... ok
|
||||
test skill_router::tests::test_extract_json_with_surrounding_text ... ok
|
||||
test export::pptx::tests::test_pptx_export ... ok
|
||||
|
||||
test result: ok. 48 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s
|
||||
|
||||
Running unittests src\lib.rs (target\debug\deps\zclaw_memory-909b7cff59274e48.exe)
|
||||
|
||||
running 25 tests
|
||||
test fact::tests::test_fact_new_clamps_confidence ... ok
|
||||
test fact::tests::test_fact_with_source ... ok
|
||||
test fact::tests::test_is_empty_and_len ... ok
|
||||
test fact::tests::test_filter_by_confidence ... ok
|
||||
test fact::tests::test_deduplicate_keeps_higher_confidence ... ok
|
||||
test store::tests::test_in_memory_store_creation ... ok
|
||||
test store::tests::test_agent_with_empty_name ... ok
|
||||
test store::tests::test_kv_recall_nonexistent ... ok
|
||||
test store::tests::test_list_agents ... ok
|
||||
test store::tests::test_load_nonexistent_agent ... ok
|
||||
test store::tests::test_kv_store_and_recall ... ok
|
||||
test store::tests::test_delete_agent ... ok
|
||||
test store::tests::test_create_session ... ok
|
||||
test store::tests::test_agent_with_special_characters_in_name ... ok
|
||||
test store::tests::test_message_with_thinking ... ok
|
||||
test store::tests::test_kv_list ... ok
|
||||
test store::tests::test_append_and_get_messages ... ok
|
||||
test store::tests::test_delete_nonexistent_agent_succeeds ... ok
|
||||
test store::tests::test_kv_update_existing ... ok
|
||||
test store::tests::test_large_message_content ... ok
|
||||
test store::tests::test_message_ordering ... ok
|
||||
test store::tests::test_save_agent_updates_existing ... ok
|
||||
test store::tests::test_save_and_load_agent ... ok
|
||||
test store::tests::test_message_with_tool_result ... ok
|
||||
test store::tests::test_message_with_tool_use ... ok
|
||||
|
||||
test result: ok. 25 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.08s
|
||||
|
||||
Running unittests src\lib.rs (target\debug\deps\zclaw_pipeline-a7d8a9f8b74018ea.exe)
|
||||
|
||||
running 59 tests
|
||||
test engine::stage::tests::test_stage_engine_creation ... ok
|
||||
test parser::tests::test_parse_empty_steps ... ok
|
||||
test parser::tests::test_parse_duplicate_step_ids ... ok
|
||||
test parser::tests::test_parse_invalid_kind ... ok
|
||||
test parser::tests::test_parse_invalid_version ... ok
|
||||
test parser::tests::test_parse_valid_pipeline ... ok
|
||||
test engine::context::tests::test_evaluate_condition_gt ... ok
|
||||
test engine::context::tests::test_resolve_param ... ok
|
||||
test engine::context::tests::test_resolve_stage_output ... ok
|
||||
test engine::context::tests::test_resolve_loop_context ... ok
|
||||
test executor::tests::test_evaluate_condition_bool ... ok
|
||||
test engine::context::tests::test_evaluate_condition_equal ... ok
|
||||
test executor::tests::test_evaluate_condition_equality ... ok
|
||||
test engine::context::tests::test_resolve_mixed_string ... ok
|
||||
test parser_v2::tests::test_parse_conditional_stage ... ok
|
||||
test parser_v2::tests::test_parse_all_stage_types ... ok
|
||||
test parser_v2::tests::test_parse_duplicate_stage_ids ... ok
|
||||
test parser_v2::tests::test_parse_empty_stages ... ok
|
||||
test parser_v2::tests::test_parse_invalid_kind ... ok
|
||||
test parser_v2::tests::test_parse_invalid_version ... ok
|
||||
test parser_v2::tests::test_parse_output_config ... ok
|
||||
test presentation::analyzer::tests::test_analyze_document_fallback ... ok
|
||||
test presentation::analyzer::tests::test_analyze_chart ... ok
|
||||
test presentation::analyzer::tests::test_analyze_slideshow ... ok
|
||||
test presentation::analyzer::tests::test_analyze_quiz ... ok
|
||||
test parser_v2::tests::test_parse_parallel_stage ... ok
|
||||
test presentation::analyzer::tests::test_can_render_as ... ok
|
||||
test engine::context::tests::test_child_context ... ok
|
||||
test parser_v2::tests::test_parse_valid_pipeline_v2 ... ok
|
||||
test parser_v2::tests::test_parse_sequential_stage ... ok
|
||||
test presentation::registry::tests::test_registry_defaults ... ok
|
||||
test parser_v2::tests::test_try_parse_v2 ... ok
|
||||
test presentation::registry::tests::test_all_available ... ok
|
||||
test presentation::registry::tests::test_renderer_info ... ok
|
||||
test presentation::registry::tests::test_get_export_formats ... ok
|
||||
test intent::tests::test_decide_mode_form ... ok
|
||||
test intent::tests::test_decide_mode_conversation ... ok
|
||||
test presentation::types::tests::test_presentation_type_display ... ok
|
||||
test presentation::types::tests::test_chart_data_deserialize ... ok
|
||||
test intent::tests::test_route_keyword_match ... ok
|
||||
test intent::tests::test_route_pattern_match ... ok
|
||||
test presentation::types::tests::test_presentation_type_icon ... ok
|
||||
test intent::tests::test_route_no_match ... ok
|
||||
test presentation::types::tests::test_quiz_data_deserialize ... ok
|
||||
test types_v2::tests::test_stage_id ... ok
|
||||
test state::tests::test_extract_outputs ... ok
|
||||
test state::tests::test_resolve_input ... ok
|
||||
test state::tests::test_resolve_step_output ... ok
|
||||
test state::tests::test_resolve_array_access ... ok
|
||||
test trigger::tests::test_trigger_parser_quick_match ... ok
|
||||
test types::tests::test_file_export_with_expression ... ok
|
||||
test state::tests::test_resolve_loop_context ... ok
|
||||
test types::tests::test_pipeline_deserialize ... ok
|
||||
test trigger::tests::test_compile_pattern_wildcard ... ok
|
||||
test trigger::tests::test_compile_pattern_mixed ... ok
|
||||
test state::tests::test_resolve_mixed_string ... ok
|
||||
test trigger::tests::test_compile_pattern_named_capture ... ok
|
||||
test trigger::tests::test_trigger_param_extraction ... ok
|
||||
test types_v2::tests::test_pipeline_v2_deserialize ... ok
|
||||
|
||||
test result: ok. 59 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.02s
|
||||
|
||||
Running unittests src\lib.rs (target\debug\deps\zclaw_protocols-914eb6f2e427bb85.exe)
|
||||
|
||||
running 0 tests
|
||||
|
||||
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
|
||||
|
||||
Running unittests src\lib.rs (target\debug\deps\zclaw_runtime-7276ff690990eead.exe)
|
||||
|
||||
running 42 tests
|
||||
test compaction::tests::test_compact_messages_under_threshold ... ok
|
||||
test compaction::tests::test_estimate_messages_tokens ... ok
|
||||
test compaction::tests::test_estimate_tokens_cjk ... ok
|
||||
test compaction::tests::test_estimate_tokens_empty ... ok
|
||||
test compaction::tests::test_extract_topic_long ... ok
|
||||
test compaction::tests::test_estimate_tokens_english ... ok
|
||||
test compaction::tests::test_extract_topic_sentence ... ok
|
||||
test compaction::tests::test_extract_topic_short ... ok
|
||||
test compaction::tests::test_compact_messages_over_threshold ... ok
|
||||
test compaction::tests::test_compact_preserves_leading_system ... ok
|
||||
test compaction::tests::test_generate_summary ... ok
|
||||
test compaction::tests::test_maybe_compact_under_threshold ... ok
|
||||
test tool::builtin::path_validator::tests::test_allows_with_explicit_allowed_paths ... ok
|
||||
test tool::builtin::path_validator::tests::test_allows_with_workspace_root ... ok
|
||||
test tool::builtin::path_validator::tests::test_default_deny_without_configuration ... ok
|
||||
test tool::builtin::path_validator::tests::test_denies_outside_workspace ... ok
|
||||
test tool::builtin::path_validator::tests::test_parse_size ... ok
|
||||
test tool::builtin::path_validator::tests::test_path_traversal ... ok
|
||||
test tool::builtin::path_validator::tests::test_blocked_paths ... ok
|
||||
test growth::tests::test_growth_integration_creation ... ok
|
||||
test growth::tests::test_disabled_growth ... ok
|
||||
test growth::tests::test_process_conversation_disabled ... ok
|
||||
test growth::tests::test_enhance_prompt_empty ... ok
|
||||
test tool::builtin::shell_exec::tests::test_parse_command_complex ... ok
|
||||
test tool::builtin::shell_exec::tests::test_parse_command_empty ... ok
|
||||
test tool::builtin::shell_exec::tests::test_command_allowed ... ok
|
||||
test tool::builtin::shell_exec::tests::test_parse_command_simple ... ok
|
||||
test tool::builtin::shell_exec::tests::test_parse_command_with_quotes ... ok
|
||||
test tool::builtin::shell_exec::tests::test_parse_command_with_single_quotes ... ok
|
||||
test tool::builtin::shell_exec::tests::test_security_config_default ... ok
|
||||
test tool::builtin::file_write::tests::test_write_new_file ... ok
|
||||
test tool::builtin::file_write::tests::test_create_mode_fails_on_existing ... ok
|
||||
test tool::builtin::path_validator::tests::test_expand_tilde ... ok
|
||||
test tool::builtin::web_fetch::tests::test_validate_url_length ... ok
|
||||
test tool::builtin::web_fetch::tests::test_validate_ipv6 ... ok
|
||||
test tool::builtin::web_fetch::tests::test_validate_blocked_hostnames ... ok
|
||||
test tool::builtin::web_fetch::tests::test_validate_cloud_metadata ... ok
|
||||
test tool::builtin::web_fetch::tests::test_validate_localhost ... ok
|
||||
test tool::builtin::web_fetch::tests::test_validate_scheme ... ok
|
||||
test tool::builtin::web_fetch::tests::test_validate_private_ips ... ok
|
||||
test tool::builtin::file_read::tests::test_read_file ... ok
|
||||
test tool::builtin::file_write::tests::test_overwrite_mode ... ok
|
||||
|
||||
test result: ok. 42 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.02s
|
||||
|
||||
Running unittests src\lib.rs (target\debug\deps\zclaw_skills-9c40ca9299fa8d01.exe)
|
||||
|
||||
running 23 tests
|
||||
test orchestration::planner::tests::test_plan_builder ... ok
|
||||
test orchestration::auto_compose::tests::test_extract_types ... ok
|
||||
test orchestration::executor::tests::test_node_result_success ... ok
|
||||
test orchestration::types::tests::test_parse_input_ref ... ok
|
||||
test orchestration::types::tests::test_parse_literal ... ok
|
||||
test orchestration::types::tests::test_parse_node_output_ref ... ok
|
||||
test orchestration::planner::tests::test_planner_plan ... ok
|
||||
test orchestration::validation::tests::test_detect_no_cycle ... ok
|
||||
test orchestration::validation::tests::test_find_end_nodes ... ok
|
||||
test orchestration::validation::tests::test_find_start_nodes ... ok
|
||||
test orchestration::validation::tests::test_identify_parallel_groups ... ok
|
||||
test orchestration::validation::tests::test_detect_cycle ... ok
|
||||
test orchestration::validation::tests::test_topological_sort ... ok
|
||||
test semantic_router::tests::test_cosine_similarity ... ok
|
||||
test semantic_router::tests::test_llm_fallback_invoked_when_below_threshold ... ok
|
||||
test semantic_router::tests::test_no_llm_fallback_returns_best_match ... ok
|
||||
test semantic_router::tests::test_no_llm_fallback_when_high_confidence ... ok
|
||||
test semantic_router::tests::test_retrieve_candidates ... ok
|
||||
test semantic_router::tests::test_basic_routing ... ok
|
||||
test orchestration::context::tests::test_build_output ... ok
|
||||
test orchestration::context::tests::test_resolve_node_output_ref ... ok
|
||||
test orchestration::context::tests::test_resolve_input_ref ... ok
|
||||
test orchestration::context::tests::test_evaluate_condition_equality ... ok
|
||||
|
||||
test result: ok. 23 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
|
||||
|
||||
Running unittests src\lib.rs (target\debug\deps\zclaw_types-0babceb0143df14c.exe)
|
||||
|
||||
running 57 tests
|
||||
test error::tests::test_config_error_display ... ok
|
||||
test error::tests::test_export_error_display ... ok
|
||||
test error::tests::test_hand_error_display ... ok
|
||||
test error::tests::test_invalid_input_display ... ok
|
||||
test error::tests::test_loop_detected_display ... ok
|
||||
test error::tests::test_mcp_error_display ... ok
|
||||
test error::tests::test_internal_error_display ... ok
|
||||
test error::tests::test_not_found_display ... ok
|
||||
test error::tests::test_llm_error_display ... ok
|
||||
test error::tests::test_permission_denied_display ... ok
|
||||
test error::tests::test_rate_limited_display ... ok
|
||||
test error::tests::test_tool_error_display ... ok
|
||||
test hand_run::tests::test_hand_run_id_display ... ok
|
||||
test error::tests::test_security_error_display ... ok
|
||||
test error::tests::test_serialization_error_from_json ... ok
|
||||
test error::tests::test_storage_error_display ... ok
|
||||
test error::tests::test_timeout_display ... ok
|
||||
test error::tests::test_result_type_err ... ok
|
||||
test error::tests::test_result_type_ok ... ok
|
||||
test hand_run::tests::test_hand_run_id_unique ... ok
|
||||
test hand_run::tests::test_hand_run_id_from_str ... ok
|
||||
test hand_run::tests::test_hand_run_serialization ... ok
|
||||
test id::tests::test_agent_id_display ... ok
|
||||
test hand_run::tests::test_hand_run_status_roundtrip ... ok
|
||||
test id::tests::test_agent_id_default ... ok
|
||||
test id::tests::test_agent_id_from_str_invalid ... ok
|
||||
test id::tests::test_agent_id_from_str_valid ... ok
|
||||
test id::tests::test_agent_id_new_creates_unique_ids ... ok
|
||||
test id::tests::test_agent_id_serialization ... ok
|
||||
test id::tests::test_run_id_display ... ok
|
||||
test id::tests::test_run_id_default ... ok
|
||||
test id::tests::test_run_id_new_creates_unique_ids ... ok
|
||||
test id::tests::test_session_id_default ... ok
|
||||
test id::tests::test_session_id_new_creates_unique_ids ... ok
|
||||
test id::tests::test_skill_id_new ... ok
|
||||
test id::tests::test_tool_id_display ... ok
|
||||
test id::tests::test_tool_id_from_string ... ok
|
||||
test id::tests::test_tool_id_from_str ... ok
|
||||
test message::tests::test_content_block_image ... ok
|
||||
test id::tests::test_tool_id_new ... ok
|
||||
test message::tests::test_content_block_text ... ok
|
||||
test message::tests::test_content_block_thinking ... ok
|
||||
test message::tests::test_content_block_tool_result ... ok
|
||||
test message::tests::test_content_block_tool_use ... ok
|
||||
test message::tests::test_image_source_base64 ... ok
|
||||
test message::tests::test_image_source_serialization ... ok
|
||||
test message::tests::test_image_source_url ... ok
|
||||
test message::tests::test_message_assistant_creation ... ok
|
||||
test message::tests::test_message_assistant_with_thinking ... ok
|
||||
test message::tests::test_message_deserialization_user ... ok
|
||||
test message::tests::test_message_serialization_assistant ... ok
|
||||
test message::tests::test_message_serialization_user ... ok
|
||||
test message::tests::test_message_system_creation ... ok
|
||||
test message::tests::test_message_tool_result_creation ... ok
|
||||
test message::tests::test_message_tool_result_error ... ok
|
||||
test message::tests::test_message_tool_use_creation ... ok
|
||||
test message::tests::test_message_user_creation ... ok
|
||||
|
||||
test result: ok. 57 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
|
||||
|
||||
Doc-tests desktop_lib
|
||||
|
||||
running 2 tests
|
||||
test desktop\src-tauri\src\intelligence\validation.rs - intelligence::validation::validate_identifier (line 112) ... ignored
|
||||
test desktop\src-tauri\src\intelligence\validation.rs - intelligence::validation::validate_string_length (line 173) ... ignored
|
||||
|
||||
test result: ok. 0 passed; 0 failed; 2 ignored; 0 measured; 0 filtered out; finished in 0.00s
|
||||
|
||||
Doc-tests zclaw_growth
|
||||
|
||||
running 1 test
|
||||
test crates\zclaw-growth\src\lib.rs - (line 39) ... ignored
|
||||
|
||||
test result: ok. 0 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 0.00s
|
||||
|
||||
Doc-tests zclaw_hands
|
||||
|
||||
running 0 tests
|
||||
|
||||
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
|
||||
|
||||
Doc-tests zclaw_kernel
|
||||
|
||||
running 0 tests
|
||||
|
||||
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
|
||||
|
||||
Doc-tests zclaw_memory
|
||||
|
||||
running 0 tests
|
||||
|
||||
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
|
||||
|
||||
Doc-tests zclaw_pipeline
|
||||
|
||||
running 1 test
|
||||
test crates\zclaw-pipeline\src\intent.rs - intent (line 21) ... ignored
|
||||
|
||||
test result: ok. 0 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 0.00s
|
||||
|
||||
Doc-tests zclaw_protocols
|
||||
|
||||
running 0 tests
|
||||
|
||||
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
|
||||
|
||||
Doc-tests zclaw_runtime
|
||||
|
||||
running 1 test
|
||||
test crates\zclaw-runtime\src\tool\builtin\path_validator.rs - tool::builtin::path_validator (line 20) ... ignored
|
||||
|
||||
test result: ok. 0 passed; 0 failed; 1 ignored; 0 measured; 0 filtered out; finished in 0.00s
|
||||
|
||||
Doc-tests zclaw_skills
|
||||
|
||||
running 0 tests
|
||||
|
||||
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
|
||||
|
||||
Doc-tests zclaw_types
|
||||
|
||||
running 0 tests
|
||||
|
||||
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
|
||||
|
||||
@@ -0,0 +1,478 @@
|
||||
[vite:react-babel] We recommend switching to `@vitejs/plugin-react-oxc` for improved performance. More information at https://vite.dev/rolldown
|
||||
|
||||
[1m[7m[36m RUN [39m[27m[22m [36mv2.1.9 [39m[90mG:/ZClaw_openfang/desktop[39m
|
||||
|
||||
[90mstderr[2m | tests/lib/request-helper.test.ts[2m > [22m[2mrequest-helper[2m > [22m[2mrequestWithRetry[2m > [22m[2mshould retry on retryable status codes
|
||||
[22m[39m[RequestHelper] Request failed (503), retrying in 11ms (attempt 1/2)
|
||||
|
||||
[32m✓[39m tests/lib/crypto-utils.test.ts [2m([22m[2m10 tests[22m[2m)[22m[90m 69[2mms[22m[39m
|
||||
[90mstderr[2m | tests/lib/request-helper.test.ts[2m > [22m[2mrequest-helper[2m > [22m[2mrequestWithRetry[2m > [22m[2mshould throw after all retries exhausted
|
||||
[22m[39m[RequestHelper] Request failed (503), retrying in 12ms (attempt 1/2)
|
||||
|
||||
[90mstderr[2m | tests/lib/request-helper.test.ts[2m > [22m[2mrequest-helper[2m > [22m[2mrequestWithRetry[2m > [22m[2mshould throw after all retries exhausted
|
||||
[22m[39m[RequestHelper] Request failed (503), retrying in 22ms (attempt 2/2)
|
||||
|
||||
[90mstdout[2m | tests/lib/request-helper.test.ts[2m > [22m[2mrequest-helper[2m > [22m[2mRequestManager[2m > [22m[2mshould cancel all requests
|
||||
[22m[39m[RequestHelper] Cancelled request: test-1
|
||||
[RequestHelper] Cancelled request: test-2
|
||||
[RequestHelper] Cancelled request: test-3
|
||||
|
||||
[32m✓[39m tests/lib/request-helper.test.ts [2m([22m[2m30 tests[22m[2m | [22m[33m1 skipped[39m[2m)[22m[90m 101[2mms[22m[39m
|
||||
[90mstdout[2m | tests/lib/security.test.ts[2m > [22m[2mSecurity Utils[2m > [22m[2msanitizeJson[2m > [22m[2mshould return null for invalid JSON
|
||||
[22m[39m[SecurityUtils] JSON sanitize parse failed {
|
||||
error: SyntaxError: Unexpected token 'o', "not json" is not valid JSON
|
||||
at JSON.parse (<anonymous>)
|
||||
at Module.sanitizeJson [90m(G:\ZClaw_openfang\desktop\[39msrc\lib\security-utils.ts:549:25[90m)[39m
|
||||
at [90mG:\ZClaw_openfang\desktop\[39mtests\lib\security.test.ts:356:28
|
||||
at [90mfile:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/@vitest+runner@2.1.9/node_modules/[4m@vitest/runner[24m/dist/index.js:146:14
|
||||
at [90mfile:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/@vitest+runner@2.1.9/node_modules/[4m@vitest/runner[24m/dist/index.js:533:11
|
||||
at runWithTimeout [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/@vitest+runner@2.1.9/node_modules/[4m@vitest/runner[24m/dist/index.js:39:7[90m)[39m
|
||||
at runTest [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/@vitest+runner@2.1.9/node_modules/[4m@vitest/runner[24m/dist/index.js:1056:17[90m)[39m
|
||||
[90m at processTicksAndRejections (node:internal/process/task_queues:104:5)[39m
|
||||
at runSuite [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/@vitest+runner@2.1.9/node_modules/[4m@vitest/runner[24m/dist/index.js:1205:15[90m)[39m
|
||||
at runSuite [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/@vitest+runner@2.1.9/node_modules/[4m@vitest/runner[24m/dist/index.js:1205:15[90m)[39m
|
||||
}
|
||||
|
||||
[32m✓[39m tests/lib/security.test.ts [2m([22m[2m58 tests[22m[2m)[22m[90m 250[2mms[22m[39m
|
||||
[90mstderr[2m | tests/toml-utils.test.ts[2m > [22m[2mtomlUtils[2m > [22m[2mparse[2m > [22m[2mshould throw TomlParseError on invalid TOML
|
||||
[22m[39m[TOML] Parse error: TomlError: Invalid TOML document: incomplete key-value: cannot find end of key
|
||||
|
||||
2: [invalid
|
||||
^
|
||||
3: key = value
|
||||
|
||||
at parseKey [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/smol-toml@1.6.1/node_modules/[4msmol-toml[24m/dist/struct.js:38:15[90m)[39m
|
||||
at Object.parse [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/smol-toml@1.6.1/node_modules/[4msmol-toml[24m/dist/parse.js:104:21[90m)[39m
|
||||
at Object.parse [90m(G:\ZClaw_openfang\desktop\[39msrc\lib\toml-utils.ts:61:19[90m)[39m
|
||||
at [90mG:\ZClaw_openfang\desktop\[39mtests\toml-utils.test.ts:72:30
|
||||
at Proxy.<anonymous> [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/@vitest+expect@2.1.9/node_modules/[4m@vitest/expect[24m/dist/index.js:1530:11[90m)[39m
|
||||
at Proxy.<anonymous> [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/@vitest+expect@2.1.9/node_modules/[4m@vitest/expect[24m/dist/index.js:972:17[90m)[39m
|
||||
at Proxy.methodWrapper [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/chai@5.3.3/node_modules/[4mchai[24m/index.js:1686:25[90m)[39m
|
||||
at [90mG:\ZClaw_openfang\desktop\[39mtests\toml-utils.test.ts:72:50
|
||||
at [90mfile:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/@vitest+runner@2.1.9/node_modules/[4m@vitest/runner[24m/dist/index.js:146:14
|
||||
at [90mfile:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/@vitest+runner@2.1.9/node_modules/[4m@vitest/runner[24m/dist/index.js:533:11 {
|
||||
line: [33m2[39m,
|
||||
column: [33m2[39m,
|
||||
codeblock: [32m'2: [invalid\n ^\n3: key = value\n'[39m
|
||||
}
|
||||
|
||||
[90mstderr[2m | tests/toml-utils.test.ts[2m > [22m[2mtomlUtils[2m > [22m[2mstringify[2m > [22m[2mshould throw TomlStringifyError on invalid data
|
||||
[22m[39m[TOML] Stringify error: Error: Could not stringify the object: maximum object depth exceeded
|
||||
at stringifyTable [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/smol-toml@1.6.1/node_modules/[4msmol-toml[24m/dist/stringify.js:125:15[90m)[39m
|
||||
at stringifyTable [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/smol-toml@1.6.1/node_modules/[4msmol-toml[24m/dist/stringify.js:143:46[90m)[39m
|
||||
at stringifyTable [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/smol-toml@1.6.1/node_modules/[4msmol-toml[24m/dist/stringify.js:143:46[90m)[39m
|
||||
at stringifyTable [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/smol-toml@1.6.1/node_modules/[4msmol-toml[24m/dist/stringify.js:143:46[90m)[39m
|
||||
at stringifyTable [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/smol-toml@1.6.1/node_modules/[4msmol-toml[24m/dist/stringify.js:143:46[90m)[39m
|
||||
at stringifyTable [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/smol-toml@1.6.1/node_modules/[4msmol-toml[24m/dist/stringify.js:143:46[90m)[39m
|
||||
at stringifyTable [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/smol-toml@1.6.1/node_modules/[4msmol-toml[24m/dist/stringify.js:143:46[90m)[39m
|
||||
at stringifyTable [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/smol-toml@1.6.1/node_modules/[4msmol-toml[24m/dist/stringify.js:143:46[90m)[39m
|
||||
at stringifyTable [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/smol-toml@1.6.1/node_modules/[4msmol-toml[24m/dist/stringify.js:143:46[90m)[39m
|
||||
at stringifyTable [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/smol-toml@1.6.1/node_modules/[4msmol-toml[24m/dist/stringify.js:143:46[90m)[39m
|
||||
|
||||
[90mstderr[2m | tests/toml-utils.test.ts[2m > [22m[2mtomlUtils[2m > [22m[2mresolveEnvVars[2m > [22m[2mshould return empty string for missing env vars
|
||||
[22m[39m[TOML] Environment variable MISSING_VAR not resolved - no envVars provided
|
||||
|
||||
[32m✓[39m tests/toml-utils.test.ts [2m([22m[2m14 tests[22m[2m)[22m[90m 22[2mms[22m[39m
|
||||
[32m✓[39m tests/config-parser.test.ts [2m([22m[2m13 tests[22m[2m)[22m[90m 14[2mms[22m[39m
|
||||
[90mstderr[2m | tests/lib/secure-storage.test.ts[2m > [22m[2msecureStorage[2m > [22m[2merror handling[2m > [22m[2mshould handle corrupted encrypted data gracefully
|
||||
[22m[39m[SecureStorage] v2 decryption failed for key: corrupted-key
|
||||
[SecureStorage] v1 decryption failed for key: corrupted-key
|
||||
|
||||
[32m✓[39m tests/lib/secure-storage.test.ts [2m([22m[2m11 tests[22m[2m)[22m[90m 258[2mms[22m[39m
|
||||
[90mstderr[2m | tests/store/chatStore.test.ts
|
||||
[22m[39m[IDBStorage] Migration from localStorage failed: ReferenceError: indexedDB is not defined
|
||||
at Module.openDB [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/idb@8.0.3/node_modules/[4midb[24m/build/index.js:168:21[90m)[39m
|
||||
at getDB [90m(G:\ZClaw_openfang\desktop\[39msrc\lib\idb-storage.ts:34:17[90m)[39m
|
||||
at migrateFromLocalStorage [90m(G:\ZClaw_openfang\desktop\[39msrc\lib\idb-storage.ts:56:22[90m)[39m
|
||||
at Object.getItem [90m(G:\ZClaw_openfang\desktop\[39msrc\lib\idb-storage.ts:98:15[90m)[39m
|
||||
at Object.getItem [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/zustand@5.0.12_@types+react_8b11772aea488cca440c1215797a0d95/node_modules/[4mzustand[24m/esm/middleware.mjs:292:33[90m)[39m
|
||||
at [90mfile:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/zustand@5.0.12_@types+react_8b11772aea488cca440c1215797a0d95/node_modules/[4mzustand[24m/esm/middleware.mjs:305:20
|
||||
at hydrate [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/zustand@5.0.12_@types+react_8b11772aea488cca440c1215797a0d95/node_modules/[4mzustand[24m/esm/middleware.mjs:388:53[90m)[39m
|
||||
at [90mfile:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/zustand@5.0.12_@types+react_8b11772aea488cca440c1215797a0d95/node_modules/[4mzustand[24m/esm/middleware.mjs:468:5
|
||||
at createStoreImpl [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/zustand@5.0.12_@types+react_8b11772aea488cca440c1215797a0d95/node_modules/[4mzustand[24m/esm/vanilla.mjs:19:32[90m)[39m
|
||||
at createStore [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/zustand@5.0.12_@types+react_8b11772aea488cca440c1215797a0d95/node_modules/[4mzustand[24m/esm/vanilla.mjs:22:53[90m)[39m
|
||||
[IDBStorage] IndexedDB getItem failed: ReferenceError: indexedDB is not defined
|
||||
at Module.openDB [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/idb@8.0.3/node_modules/[4midb[24m/build/index.js:168:21[90m)[39m
|
||||
at getDB [90m(G:\ZClaw_openfang\desktop\[39msrc\lib\idb-storage.ts:34:17[90m)[39m
|
||||
at Object.getItem [90m(G:\ZClaw_openfang\desktop\[39msrc\lib\idb-storage.ts:102:26[90m)[39m
|
||||
[90m at processTicksAndRejections (node:internal/process/task_queues:104:5)[39m
|
||||
|
||||
[32m✓[39m tests/lib/gateway-security.test.ts [2m([22m[2m13 tests[22m[2m)[22m[33m 570[2mms[22m[39m
|
||||
[33m[2m✓[22m[39m WebSocket Security[2m > [22mSecurityError[2m > [22mshould be throwable with a message [33m413[2mms[22m[39m
|
||||
[31m❯[39m tests/stabilization.test.ts [2m([22m[2m0 test[22m[2m)[22m
|
||||
[90mstderr[2m | tests/store/chatStore.test.ts[2m > [22m[2mchatStore[2m > [22m[2msetCurrentModel[2m > [22m[2mshould update current model
|
||||
[22m[39m[IDBStorage] IndexedDB setItem failed: ReferenceError: indexedDB is not defined
|
||||
at Module.openDB [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/idb@8.0.3/node_modules/[4midb[24m/build/index.js:168:21[90m)[39m
|
||||
at getDB [90m(G:\ZClaw_openfang\desktop\[39msrc\lib\idb-storage.ts:34:17[90m)[39m
|
||||
at Object.setItem [90m(G:\ZClaw_openfang\desktop\[39msrc\lib\idb-storage.ts:117:26[90m)[39m
|
||||
at Object.setItem [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/zustand@5.0.12_@types+react_8b11772aea488cca440c1215797a0d95/node_modules/[4mzustand[24m/esm/middleware.mjs:298:42[90m)[39m
|
||||
at setItem [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/zustand@5.0.12_@types+react_8b11772aea488cca440c1215797a0d95/node_modules/[4mzustand[24m/esm/middleware.mjs:358:20[90m)[39m
|
||||
at [90mfile:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/zustand@5.0.12_@types+react_8b11772aea488cca440c1215797a0d95/node_modules/[4mzustand[24m/esm/middleware.mjs:371:14
|
||||
at Object.setCurrentModel [90m(G:\ZClaw_openfang\desktop\[39msrc\store\chat\conversationStore.ts:324:39[90m)[39m
|
||||
at setCurrentModel [90m(G:\ZClaw_openfang\desktop\[39msrc\store\chatStore.ts:154:37[90m)[39m
|
||||
at [90mG:\ZClaw_openfang\desktop\[39mtests\store\chatStore.test.ts:269:7
|
||||
at [90mfile:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/@vitest+runner@2.1.9/node_modules/[4m@vitest/runner[24m/dist/index.js:146:14
|
||||
|
||||
[90mstderr[2m | tests/store/chatStore.test.ts[2m > [22m[2mchatStore[2m > [22m[2mnewConversation[2m > [22m[2mshould clear messages and reset session
|
||||
[22m[39m[IDBStorage] IndexedDB setItem failed: ReferenceError: indexedDB is not defined
|
||||
at Module.openDB [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/idb@8.0.3/node_modules/[4midb[24m/build/index.js:168:21[90m)[39m
|
||||
at getDB [90m(G:\ZClaw_openfang\desktop\[39msrc\lib\idb-storage.ts:34:17[90m)[39m
|
||||
at Object.setItem [90m(G:\ZClaw_openfang\desktop\[39msrc\lib\idb-storage.ts:117:26[90m)[39m
|
||||
at Object.setItem [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/zustand@5.0.12_@types+react_8b11772aea488cca440c1215797a0d95/node_modules/[4mzustand[24m/esm/middleware.mjs:298:42[90m)[39m
|
||||
at setItem [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/zustand@5.0.12_@types+react_8b11772aea488cca440c1215797a0d95/node_modules/[4mzustand[24m/esm/middleware.mjs:358:20[90m)[39m
|
||||
at [90mfile:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/zustand@5.0.12_@types+react_8b11772aea488cca440c1215797a0d95/node_modules/[4mzustand[24m/esm/middleware.mjs:371:14
|
||||
at Object.newConversation [90m(G:\ZClaw_openfang\desktop\[39msrc\store\chat\conversationStore.ts:203:5[90m)[39m
|
||||
at newConversation [90m(G:\ZClaw_openfang\desktop\[39msrc\store\chatStore.ts:159:37[90m)[39m
|
||||
at [90mG:\ZClaw_openfang\desktop\[39mtests\store\chatStore.test.ts:289:7
|
||||
at [90mfile:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/@vitest+runner@2.1.9/node_modules/[4m@vitest/runner[24m/dist/index.js:146:14
|
||||
|
||||
[90mstderr[2m | tests/store/chatStore.test.ts[2m > [22m[2mchatStore[2m > [22m[2mnewConversation[2m > [22m[2mshould save current messages to conversations before clearing
|
||||
[22m[39m[IDBStorage] IndexedDB setItem failed: ReferenceError: indexedDB is not defined
|
||||
at Module.openDB [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/idb@8.0.3/node_modules/[4midb[24m/build/index.js:168:21[90m)[39m
|
||||
at getDB [90m(G:\ZClaw_openfang\desktop\[39msrc\lib\idb-storage.ts:34:17[90m)[39m
|
||||
at Object.setItem [90m(G:\ZClaw_openfang\desktop\[39msrc\lib\idb-storage.ts:117:26[90m)[39m
|
||||
at Object.setItem [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/zustand@5.0.12_@types+react_8b11772aea488cca440c1215797a0d95/node_modules/[4mzustand[24m/esm/middleware.mjs:298:42[90m)[39m
|
||||
at setItem [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/zustand@5.0.12_@types+react_8b11772aea488cca440c1215797a0d95/node_modules/[4mzustand[24m/esm/middleware.mjs:358:20[90m)[39m
|
||||
at [90mfile:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/zustand@5.0.12_@types+react_8b11772aea488cca440c1215797a0d95/node_modules/[4mzustand[24m/esm/middleware.mjs:371:14
|
||||
at Object.newConversation [90m(G:\ZClaw_openfang\desktop\[39msrc\store\chat\conversationStore.ts:203:5[90m)[39m
|
||||
at newConversation [90m(G:\ZClaw_openfang\desktop\[39msrc\store\chatStore.ts:159:37[90m)[39m
|
||||
at [90mG:\ZClaw_openfang\desktop\[39mtests\store\chatStore.test.ts:308:7
|
||||
at [90mfile:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/@vitest+runner@2.1.9/node_modules/[4m@vitest/runner[24m/dist/index.js:146:14
|
||||
|
||||
[90mstderr[2m | tests/store/chatStore.test.ts[2m > [22m[2mchatStore[2m > [22m[2mswitchConversation[2m > [22m[2mshould switch to existing conversation
|
||||
[22m[39m[IDBStorage] IndexedDB setItem failed: ReferenceError: indexedDB is not defined
|
||||
at Module.openDB [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/idb@8.0.3/node_modules/[4midb[24m/build/index.js:168:21[90m)[39m
|
||||
at getDB [90m(G:\ZClaw_openfang\desktop\[39msrc\lib\idb-storage.ts:34:17[90m)[39m
|
||||
at Object.setItem [90m(G:\ZClaw_openfang\desktop\[39msrc\lib\idb-storage.ts:117:26[90m)[39m
|
||||
at Object.setItem [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/zustand@5.0.12_@types+react_8b11772aea488cca440c1215797a0d95/node_modules/[4mzustand[24m/esm/middleware.mjs:298:42[90m)[39m
|
||||
at setItem [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/zustand@5.0.12_@types+react_8b11772aea488cca440c1215797a0d95/node_modules/[4mzustand[24m/esm/middleware.mjs:358:20[90m)[39m
|
||||
at [90mfile:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/zustand@5.0.12_@types+react_8b11772aea488cca440c1215797a0d95/node_modules/[4mzustand[24m/esm/middleware.mjs:371:14
|
||||
at Object.newConversation [90m(G:\ZClaw_openfang\desktop\[39msrc\store\chat\conversationStore.ts:203:5[90m)[39m
|
||||
at newConversation [90m(G:\ZClaw_openfang\desktop\[39msrc\store\chatStore.ts:159:37[90m)[39m
|
||||
at [90mG:\ZClaw_openfang\desktop\[39mtests\store\chatStore.test.ts:328:7
|
||||
at [90mfile:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/@vitest+runner@2.1.9/node_modules/[4m@vitest/runner[24m/dist/index.js:146:14
|
||||
|
||||
[90mstderr[2m | tests/store/chatStore.test.ts[2m > [22m[2mchatStore[2m > [22m[2mdeleteConversation[2m > [22m[2mshould delete conversation by id
|
||||
[22m[39m[IDBStorage] IndexedDB setItem failed: ReferenceError: indexedDB is not defined
|
||||
at Module.openDB [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/idb@8.0.3/node_modules/[4midb[24m/build/index.js:168:21[90m)[39m
|
||||
at getDB [90m(G:\ZClaw_openfang\desktop\[39msrc\lib\idb-storage.ts:34:17[90m)[39m
|
||||
at Object.setItem [90m(G:\ZClaw_openfang\desktop\[39msrc\lib\idb-storage.ts:117:26[90m)[39m
|
||||
at Object.setItem [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/zustand@5.0.12_@types+react_8b11772aea488cca440c1215797a0d95/node_modules/[4mzustand[24m/esm/middleware.mjs:298:42[90m)[39m
|
||||
at setItem [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/zustand@5.0.12_@types+react_8b11772aea488cca440c1215797a0d95/node_modules/[4mzustand[24m/esm/middleware.mjs:358:20[90m)[39m
|
||||
at [90mfile:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/zustand@5.0.12_@types+react_8b11772aea488cca440c1215797a0d95/node_modules/[4mzustand[24m/esm/middleware.mjs:371:14
|
||||
at Object.newConversation [90m(G:\ZClaw_openfang\desktop\[39msrc\store\chat\conversationStore.ts:203:5[90m)[39m
|
||||
at newConversation [90m(G:\ZClaw_openfang\desktop\[39msrc\store\chatStore.ts:159:37[90m)[39m
|
||||
at [90mG:\ZClaw_openfang\desktop\[39mtests\store\chatStore.test.ts:360:7
|
||||
at [90mfile:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/@vitest+runner@2.1.9/node_modules/[4m@vitest/runner[24m/dist/index.js:146:14
|
||||
|
||||
[90mstderr[2m | tests/store/chatStore.test.ts[2m > [22m[2mchatStore[2m > [22m[2mdeleteConversation[2m > [22m[2mshould clear messages if deleting current conversation
|
||||
[22m[39m[IDBStorage] IndexedDB setItem failed: ReferenceError: indexedDB is not defined
|
||||
at Module.openDB [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/idb@8.0.3/node_modules/[4midb[24m/build/index.js:168:21[90m)[39m
|
||||
at getDB [90m(G:\ZClaw_openfang\desktop\[39msrc\lib\idb-storage.ts:34:17[90m)[39m
|
||||
at Object.setItem [90m(G:\ZClaw_openfang\desktop\[39msrc\lib\idb-storage.ts:117:26[90m)[39m
|
||||
at Object.setItem [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/zustand@5.0.12_@types+react_8b11772aea488cca440c1215797a0d95/node_modules/[4mzustand[24m/esm/middleware.mjs:298:42[90m)[39m
|
||||
at setItem [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/zustand@5.0.12_@types+react_8b11772aea488cca440c1215797a0d95/node_modules/[4mzustand[24m/esm/middleware.mjs:358:20[90m)[39m
|
||||
at [90mfile:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/zustand@5.0.12_@types+react_8b11772aea488cca440c1215797a0d95/node_modules/[4mzustand[24m/esm/middleware.mjs:371:14
|
||||
at Object.deleteConversation [90m(G:\ZClaw_openfang\desktop\[39msrc\store\chat\conversationStore.ts:244:7[90m)[39m
|
||||
at deleteConversation [90m(G:\ZClaw_openfang\desktop\[39msrc\store\chatStore.ts:173:30[90m)[39m
|
||||
at [90mG:\ZClaw_openfang\desktop\[39mtests\store\chatStore.test.ts:397:7
|
||||
at [90mfile:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/@vitest+runner@2.1.9/node_modules/[4m@vitest/runner[24m/dist/index.js:146:14
|
||||
|
||||
[90mstderr[2m | tests/store/chatStore.test.ts[2m > [22m[2mchatStore[2m > [22m[2msetCurrentAgent[2m > [22m[2mshould update current agent
|
||||
[22m[39m[IDBStorage] IndexedDB setItem failed: ReferenceError: indexedDB is not defined
|
||||
at Module.openDB [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/idb@8.0.3/node_modules/[4midb[24m/build/index.js:168:21[90m)[39m
|
||||
at getDB [90m(G:\ZClaw_openfang\desktop\[39msrc\lib\idb-storage.ts:34:17[90m)[39m
|
||||
at Object.setItem [90m(G:\ZClaw_openfang\desktop\[39msrc\lib\idb-storage.ts:117:26[90m)[39m
|
||||
at Object.setItem [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/zustand@5.0.12_@types+react_8b11772aea488cca440c1215797a0d95/node_modules/[4mzustand[24m/esm/middleware.mjs:298:42[90m)[39m
|
||||
at setItem [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/zustand@5.0.12_@types+react_8b11772aea488cca440c1215797a0d95/node_modules/[4mzustand[24m/esm/middleware.mjs:358:20[90m)[39m
|
||||
at [90mfile:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/zustand@5.0.12_@types+react_8b11772aea488cca440c1215797a0d95/node_modules/[4mzustand[24m/esm/middleware.mjs:371:14
|
||||
at Object.setCurrentAgent [90m(G:\ZClaw_openfang\desktop\[39msrc\store\chat\conversationStore.ts:289:5[90m)[39m
|
||||
at setCurrentAgent [90m(G:\ZClaw_openfang\desktop\[39msrc\store\chatStore.ts:133:52[90m)[39m
|
||||
at [90mG:\ZClaw_openfang\desktop\[39mtests\store\chatStore.test.ts:418:7
|
||||
at [90mfile:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/@vitest+runner@2.1.9/node_modules/[4m@vitest/runner[24m/dist/index.js:146:14
|
||||
|
||||
[90mstderr[2m | tests/store/chatStore.test.ts[2m > [22m[2mchatStore[2m > [22m[2msetCurrentAgent[2m > [22m[2mshould save current conversation when switching agents
|
||||
[22m[39m[IDBStorage] IndexedDB setItem failed: ReferenceError: indexedDB is not defined
|
||||
at Module.openDB [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/idb@8.0.3/node_modules/[4midb[24m/build/index.js:168:21[90m)[39m
|
||||
at getDB [90m(G:\ZClaw_openfang\desktop\[39msrc\lib\idb-storage.ts:34:17[90m)[39m
|
||||
at Object.setItem [90m(G:\ZClaw_openfang\desktop\[39msrc\lib\idb-storage.ts:117:26[90m)[39m
|
||||
at Object.setItem [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/zustand@5.0.12_@types+react_8b11772aea488cca440c1215797a0d95/node_modules/[4mzustand[24m/esm/middleware.mjs:298:42[90m)[39m
|
||||
at setItem [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/zustand@5.0.12_@types+react_8b11772aea488cca440c1215797a0d95/node_modules/[4mzustand[24m/esm/middleware.mjs:358:20[90m)[39m
|
||||
at [90mfile:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/zustand@5.0.12_@types+react_8b11772aea488cca440c1215797a0d95/node_modules/[4mzustand[24m/esm/middleware.mjs:371:14
|
||||
at Object.setCurrentAgent [90m(G:\ZClaw_openfang\desktop\[39msrc\store\chat\conversationStore.ts:252:7[90m)[39m
|
||||
at setCurrentAgent [90m(G:\ZClaw_openfang\desktop\[39msrc\store\chatStore.ts:133:52[90m)[39m
|
||||
at [90mG:\ZClaw_openfang\desktop\[39mtests\store\chatStore.test.ts:444:7
|
||||
at [90mfile:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/@vitest+runner@2.1.9/node_modules/[4m@vitest/runner[24m/dist/index.js:146:14
|
||||
|
||||
[90mstderr[2m | tests/store/chatStore.test.ts[2m > [22m[2mchatStore[2m > [22m[2msyncAgents[2m > [22m[2mshould sync agents from profiles
|
||||
[22m[39m[IDBStorage] IndexedDB setItem failed: ReferenceError: indexedDB is not defined
|
||||
at Module.openDB [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/idb@8.0.3/node_modules/[4midb[24m/build/index.js:168:21[90m)[39m
|
||||
at getDB [90m(G:\ZClaw_openfang\desktop\[39msrc\lib\idb-storage.ts:34:17[90m)[39m
|
||||
at Object.setItem [90m(G:\ZClaw_openfang\desktop\[39msrc\lib\idb-storage.ts:117:26[90m)[39m
|
||||
at Object.setItem [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/zustand@5.0.12_@types+react_8b11772aea488cca440c1215797a0d95/node_modules/[4mzustand[24m/esm/middleware.mjs:298:42[90m)[39m
|
||||
at setItem [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/zustand@5.0.12_@types+react_8b11772aea488cca440c1215797a0d95/node_modules/[4mzustand[24m/esm/middleware.mjs:358:20[90m)[39m
|
||||
at [90mfile:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/zustand@5.0.12_@types+react_8b11772aea488cca440c1215797a0d95/node_modules/[4mzustand[24m/esm/middleware.mjs:371:14
|
||||
at Object.syncAgents [90m(G:\ZClaw_openfang\desktop\[39msrc\store\chat\conversationStore.ts:320:5[90m)[39m
|
||||
at syncAgents [90m(G:\ZClaw_openfang\desktop\[39msrc\store\chatStore.ts:141:37[90m)[39m
|
||||
at [90mG:\ZClaw_openfang\desktop\[39mtests\store\chatStore.test.ts:455:7
|
||||
at [90mfile:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/@vitest+runner@2.1.9/node_modules/[4m@vitest/runner[24m/dist/index.js:146:14
|
||||
|
||||
[90mstderr[2m | tests/store/chatStore.test.ts[2m > [22m[2mchatStore[2m > [22m[2msyncAgents[2m > [22m[2mshould use default agent when no profiles provided
|
||||
[22m[39m[IDBStorage] IndexedDB setItem failed: ReferenceError: indexedDB is not defined
|
||||
at Module.openDB [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/idb@8.0.3/node_modules/[4midb[24m/build/index.js:168:21[90m)[39m
|
||||
at getDB [90m(G:\ZClaw_openfang\desktop\[39msrc\lib\idb-storage.ts:34:17[90m)[39m
|
||||
at Object.setItem [90m(G:\ZClaw_openfang\desktop\[39msrc\lib\idb-storage.ts:117:26[90m)[39m
|
||||
at Object.setItem [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/zustand@5.0.12_@types+react_8b11772aea488cca440c1215797a0d95/node_modules/[4mzustand[24m/esm/middleware.mjs:298:42[90m)[39m
|
||||
at setItem [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/zustand@5.0.12_@types+react_8b11772aea488cca440c1215797a0d95/node_modules/[4mzustand[24m/esm/middleware.mjs:358:20[90m)[39m
|
||||
at [90mfile:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/zustand@5.0.12_@types+react_8b11772aea488cca440c1215797a0d95/node_modules/[4mzustand[24m/esm/middleware.mjs:371:14
|
||||
at Object.syncAgents [90m(G:\ZClaw_openfang\desktop\[39msrc\store\chat\conversationStore.ts:320:5[90m)[39m
|
||||
at syncAgents [90m(G:\ZClaw_openfang\desktop\[39msrc\store\chatStore.ts:141:37[90m)[39m
|
||||
at [90mG:\ZClaw_openfang\desktop\[39mtests\store\chatStore.test.ts:469:7
|
||||
at [90mfile:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/@vitest+runner@2.1.9/node_modules/[4m@vitest/runner[24m/dist/index.js:146:14
|
||||
|
||||
[90mstderr[2m | tests/store/chatStore.test.ts[2m > [22m[2mchatStore[2m > [22m[2mconversation persistence[2m > [22m[2mshould derive title from first user message
|
||||
[22m[39m[IDBStorage] IndexedDB setItem failed: ReferenceError: indexedDB is not defined
|
||||
at Module.openDB [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/idb@8.0.3/node_modules/[4midb[24m/build/index.js:168:21[90m)[39m
|
||||
at getDB [90m(G:\ZClaw_openfang\desktop\[39msrc\lib\idb-storage.ts:34:17[90m)[39m
|
||||
at Object.setItem [90m(G:\ZClaw_openfang\desktop\[39msrc\lib\idb-storage.ts:117:26[90m)[39m
|
||||
at Object.setItem [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/zustand@5.0.12_@types+react_8b11772aea488cca440c1215797a0d95/node_modules/[4mzustand[24m/esm/middleware.mjs:298:42[90m)[39m
|
||||
at setItem [90m(file:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/zustand@5.0.12_@types+react_8b11772aea488cca440c1215797a0d95/node_modules/[4mzustand[24m/esm/middleware.mjs:358:20[90m)[39m
|
||||
at [90mfile:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/zustand@5.0.12_@types+react_8b11772aea488cca440c1215797a0d95/node_modules/[4mzustand[24m/esm/middleware.mjs:371:14
|
||||
at Object.newConversation [90m(G:\ZClaw_openfang\desktop\[39msrc\store\chat\conversationStore.ts:203:5[90m)[39m
|
||||
at newConversation [90m(G:\ZClaw_openfang\desktop\[39msrc\store\chatStore.ts:159:37[90m)[39m
|
||||
at [90mG:\ZClaw_openfang\desktop\[39mtests\store\chatStore.test.ts:645:7
|
||||
at [90mfile:///G:/ZClaw_openfang/desktop/[39mnode_modules/[4m.pnpm[24m/@vitest+runner@2.1.9/node_modules/[4m@vitest/runner[24m/dist/index.js:146:14
|
||||
|
||||
[31m❯[39m tests/store/chatStore.test.ts [2m([22m[2m36 tests[22m[2m | [22m[31m10 failed[39m[2m)[22m[90m 36[2mms[22m[39m
|
||||
[31m [31m×[31m chatStore[2m > [22msetCurrentModel[2m > [22mshould update current model[90m 7[2mms[22m[31m[39m
|
||||
[31m → expected 'glm-5' to be 'gpt-4' // Object.is equality[39m
|
||||
[31m [31m×[31m chatStore[2m > [22mnewConversation[2m > [22mshould clear messages and reset session[90m 4[2mms[22m[31m[39m
|
||||
[31m → expected 'old-session' to be null[39m
|
||||
[31m [31m×[31m chatStore[2m > [22mnewConversation[2m > [22mshould save current messages to conversations before clearing[90m 1[2mms[22m[31m[39m
|
||||
[31m → expected 0 to be greater than 0[39m
|
||||
[31m [31m×[31m chatStore[2m > [22mswitchConversation[2m > [22mshould switch to existing conversation[90m 1[2mms[22m[31m[39m
|
||||
[31m → Cannot read properties of undefined (reading 'id')[39m
|
||||
[31m [31m×[31m chatStore[2m > [22mdeleteConversation[2m > [22mshould delete conversation by id[90m 1[2mms[22m[31m[39m
|
||||
[31m → Cannot read properties of undefined (reading 'id')[39m
|
||||
[31m [31m×[31m chatStore[2m > [22mdeleteConversation[2m > [22mshould clear messages if deleting current conversation[90m 4[2mms[22m[31m[39m
|
||||
[31m → expected [ { id: 'msg-1', role: 'user', …(2) } ] to deeply equal [][39m
|
||||
[31m [31m×[31m chatStore[2m > [22msetCurrentAgent[2m > [22mshould update current agent[90m 2[2mms[22m[31m[39m
|
||||
[31m → expected { id: '1', name: 'ZCLAW', …(4) } to deeply equal { id: 'agent-2', …(5) }[39m
|
||||
[31m [31m×[31m chatStore[2m > [22msetCurrentAgent[2m > [22mshould save current conversation when switching agents[90m 1[2mms[22m[31m[39m
|
||||
[31m → expected [ { id: 'msg-1', role: 'user', …(2) } ] to deeply equal [][39m
|
||||
[31m [31m×[31m chatStore[2m > [22msyncAgents[2m > [22mshould sync agents from profiles[90m 2[2mms[22m[31m[39m
|
||||
[31m → expected [ { id: '1', name: 'ZCLAW', …(4) } ] to have a length of 2 but got 1[39m
|
||||
[31m [31m×[31m chatStore[2m > [22mconversation persistence[2m > [22mshould derive title from first user message[90m 1[2mms[22m[31m[39m
|
||||
[31m → Cannot read properties of undefined (reading 'title')[39m
|
||||
|
||||
[31m⎯⎯⎯⎯⎯⎯[1m[7m Failed Suites 1 [27m[22m⎯⎯⎯⎯⎯⎯⎯[39m
|
||||
|
||||
[31m[1m[7m FAIL [27m[22m[39m tests/stabilization.test.ts[2m [ tests/stabilization.test.ts ][22m
|
||||
[31m[1mTypeError[22m: Cannot read properties of undefined (reading 'hasHydrated')[39m
|
||||
[36m [2m❯[22m Object.onRehydrateStorage src/store/chatStore.ts:[2m265:42[22m[39m
|
||||
[90m263| [39m
|
||||
[90m264| [39m [90m// If conversationStore already hydrated (fast path), sync imm[39m…
|
||||
[90m265| [39m [35mif[39m (useConversationStore[33m.[39mpersist[33m.[39m[34mhasHydrated[39m()) {
|
||||
[90m | [39m [31m^[39m
|
||||
[90m266| [39m [34msyncMessages[39m()[33m;[39m
|
||||
[90m267| [39m [35mreturn[39m[33m;[39m
|
||||
[90m [2m❯[22m hydrate node_modules/.pnpm/zustand@5.0.12_@types+react_8b11772aea488cca440c1215797a0d95/node_modules/zustand/esm/middleware.mjs:[2m387:94[22m[39m
|
||||
[90m [2m❯[22m node_modules/.pnpm/zustand@5.0.12_@types+react_8b11772aea488cca440c1215797a0d95/node_modules/zustand/esm/middleware.mjs:[2m468:5[22m[39m
|
||||
[90m [2m❯[22m createStoreImpl node_modules/.pnpm/zustand@5.0.12_@types+react_8b11772aea488cca440c1215797a0d95/node_modules/zustand/esm/vanilla.mjs:[2m19:32[22m[39m
|
||||
[90m [2m❯[22m createStore node_modules/.pnpm/zustand@5.0.12_@types+react_8b11772aea488cca440c1215797a0d95/node_modules/zustand/esm/vanilla.mjs:[2m22:53[22m[39m
|
||||
[90m [2m❯[22m createImpl node_modules/.pnpm/zustand@5.0.12_@types+react_8b11772aea488cca440c1215797a0d95/node_modules/zustand/esm/react.mjs:[2m15:15[22m[39m
|
||||
[90m [2m❯[22m src/store/chatStore.ts:[2m105:47[22m[39m
|
||||
|
||||
[31m[2m⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[1/11]⎯[22m[39m
|
||||
|
||||
[31m⎯⎯⎯⎯⎯⎯[1m[7m Failed Tests 10 [27m[22m⎯⎯⎯⎯⎯⎯⎯[39m
|
||||
|
||||
[31m[1m[7m FAIL [27m[22m[39m tests/store/chatStore.test.ts[2m > [22mchatStore[2m > [22msetCurrentModel[2m > [22mshould update current model
|
||||
[31m[1mAssertionError[22m: expected 'glm-5' to be 'gpt-4' // Object.is equality[39m
|
||||
|
||||
Expected: [32m"g[7mpt-4[27m"[39m
|
||||
Received: [31m"g[7mlm-5[27m"[39m
|
||||
|
||||
[36m [2m❯[22m tests/store/chatStore.test.ts:[2m272:34[22m[39m
|
||||
[90m270| [39m
|
||||
[90m271| [39m [35mconst[39m state [33m=[39m useChatStore[33m.[39m[34mgetState[39m()[33m;[39m
|
||||
[90m272| [39m [34mexpect[39m(state[33m.[39mcurrentModel)[33m.[39m[34mtoBe[39m([32m'gpt-4'[39m)[33m;[39m
|
||||
[90m | [39m [31m^[39m
|
||||
[90m273| [39m })[33m;[39m
|
||||
[90m274| [39m })[33m;[39m
|
||||
|
||||
[31m[2m⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[2/11]⎯[22m[39m
|
||||
|
||||
[31m[1m[7m FAIL [27m[22m[39m tests/store/chatStore.test.ts[2m > [22mchatStore[2m > [22mnewConversation[2m > [22mshould clear messages and reset session
|
||||
[31m[1mAssertionError[22m: expected 'old-session' to be null[39m
|
||||
|
||||
[32m- Expected:[39m
|
||||
null
|
||||
|
||||
[31m+ Received:[39m
|
||||
"old-session"
|
||||
|
||||
[36m [2m❯[22m tests/store/chatStore.test.ts:[2m293:32[22m[39m
|
||||
[90m291| [39m [35mconst[39m state [33m=[39m useChatStore[33m.[39m[34mgetState[39m()[33m;[39m
|
||||
[90m292| [39m [34mexpect[39m(state[33m.[39mmessages)[33m.[39m[34mtoEqual[39m([])[33m;[39m
|
||||
[90m293| [39m [34mexpect[39m(state[33m.[39msessionKey)[33m.[39m[34mtoBeNull[39m()[33m;[39m
|
||||
[90m | [39m [31m^[39m
|
||||
[90m294| [39m [34mexpect[39m(state[33m.[39misStreaming)[33m.[39m[34mtoBe[39m([35mfalse[39m)[33m;[39m
|
||||
[90m295| [39m [34mexpect[39m(state[33m.[39mcurrentConversationId)[33m.[39m[34mtoBeNull[39m()[33m;[39m
|
||||
|
||||
[31m[2m⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[3/11]⎯[22m[39m
|
||||
|
||||
[31m[1m[7m FAIL [27m[22m[39m tests/store/chatStore.test.ts[2m > [22mchatStore[2m > [22mnewConversation[2m > [22mshould save current messages to conversations before clearing
|
||||
[31m[1mAssertionError[22m: expected 0 to be greater than 0[39m
|
||||
[36m [2m❯[22m tests/store/chatStore.test.ts:[2m312:42[22m[39m
|
||||
[90m310| [39m [35mconst[39m state [33m=[39m useChatStore[33m.[39m[34mgetState[39m()[33m;[39m
|
||||
[90m311| [39m [90m// Conversation should be saved[39m
|
||||
[90m312| [39m [34mexpect[39m(state[33m.[39mconversations[33m.[39mlength)[33m.[39m[34mtoBeGreaterThan[39m([34m0[39m)[33m;[39m
|
||||
[90m | [39m [31m^[39m
|
||||
[90m313| [39m [34mexpect[39m(state[33m.[39mconversations[[34m0[39m][33m.[39mmessages[[34m0[39m][33m.[39mcontent)[33m.[39m[34mtoBe[39m([32m'Test me[39m…
|
||||
[90m314| [39m })[33m;[39m
|
||||
|
||||
[31m[2m⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[4/11]⎯[22m[39m
|
||||
|
||||
[31m[1m[7m FAIL [27m[22m[39m tests/store/chatStore.test.ts[2m > [22mchatStore[2m > [22mswitchConversation[2m > [22mshould switch to existing conversation
|
||||
[31m[1mTypeError[22m: Cannot read properties of undefined (reading 'id')[39m
|
||||
[36m [2m❯[22m tests/store/chatStore.test.ts:[2m338:66[22m[39m
|
||||
[90m336| [39m })[33m;[39m
|
||||
[90m337| [39m
|
||||
[90m338| [39m [35mconst[39m firstConvId [33m=[39m useChatStore[33m.[39m[34mgetState[39m()[33m.[39mconversations[[34m0[39m][33m.[39mid[33m;[39m
|
||||
[90m | [39m [31m^[39m
|
||||
[90m339| [39m
|
||||
[90m340| [39m [90m// Switch back to first conversation[39m
|
||||
|
||||
[31m[2m⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[5/11]⎯[22m[39m
|
||||
|
||||
[31m[1m[7m FAIL [27m[22m[39m tests/store/chatStore.test.ts[2m > [22mchatStore[2m > [22mdeleteConversation[2m > [22mshould delete conversation by id
|
||||
[31m[1mTypeError[22m: Cannot read properties of undefined (reading 'id')[39m
|
||||
[36m [2m❯[22m tests/store/chatStore.test.ts:[2m362:61[22m[39m
|
||||
[90m360| [39m [34mnewConversation[39m()[33m;[39m
|
||||
[90m361| [39m
|
||||
[90m362| [39m [35mconst[39m convId [33m=[39m useChatStore[33m.[39m[34mgetState[39m()[33m.[39mconversations[[34m0[39m][33m.[39mid[33m;[39m
|
||||
[90m | [39m [31m^[39m
|
||||
[90m363| [39m [34mexpect[39m(useChatStore[33m.[39m[34mgetState[39m()[33m.[39mconversations)[33m.[39m[34mtoHaveLength[39m([34m1[39m)[33m;[39m
|
||||
[90m364| [39m
|
||||
|
||||
[31m[2m⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[6/11]⎯[22m[39m
|
||||
|
||||
[31m[1m[7m FAIL [27m[22m[39m tests/store/chatStore.test.ts[2m > [22mchatStore[2m > [22mdeleteConversation[2m > [22mshould clear messages if deleting current conversation
|
||||
[31m[1mAssertionError[22m: expected [ { id: 'msg-1', role: 'user', …(2) } ] to deeply equal [][39m
|
||||
|
||||
[32m- Expected[39m
|
||||
[31m+ Received[39m
|
||||
|
||||
[32m- Array [][39m
|
||||
[31m+ Array [[39m
|
||||
[31m+ Object {[39m
|
||||
[31m+ "content": "Test",[39m
|
||||
[31m+ "id": "msg-1",[39m
|
||||
[31m+ "role": "user",[39m
|
||||
[31m+ "timestamp": 2026-04-05T09:57:37.097Z,[39m
|
||||
[31m+ },[39m
|
||||
[31m+ ][39m
|
||||
|
||||
[36m [2m❯[22m tests/store/chatStore.test.ts:[2m400:30[22m[39m
|
||||
[90m398| [39m
|
||||
[90m399| [39m [35mconst[39m state [33m=[39m useChatStore[33m.[39m[34mgetState[39m()[33m;[39m
|
||||
[90m400| [39m [34mexpect[39m(state[33m.[39mmessages)[33m.[39m[34mtoEqual[39m([])[33m;[39m
|
||||
[90m | [39m [31m^[39m
|
||||
[90m401| [39m [34mexpect[39m(state[33m.[39msessionKey)[33m.[39m[34mtoBeNull[39m()[33m;[39m
|
||||
[90m402| [39m [34mexpect[39m(state[33m.[39mcurrentConversationId)[33m.[39m[34mtoBeNull[39m()[33m;[39m
|
||||
|
||||
[31m[2m⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[7/11]⎯[22m[39m
|
||||
|
||||
[31m[1m[7m FAIL [27m[22m[39m tests/store/chatStore.test.ts[2m > [22mchatStore[2m > [22msetCurrentAgent[2m > [22mshould update current agent
|
||||
[31m[1mAssertionError[22m: expected { id: '1', name: 'ZCLAW', …(4) } to deeply equal { id: 'agent-2', …(5) }[39m
|
||||
|
||||
[32m- Expected[39m
|
||||
[31m+ Received[39m
|
||||
|
||||
[2m Object {[22m
|
||||
[32m- "color": "bg-blue-500",[39m
|
||||
[32m- "icon": "A",[39m
|
||||
[32m- "id": "agent-2",[39m
|
||||
[32m- "lastMessage": "Hello",[39m
|
||||
[32m- "name": "New Agent",[39m
|
||||
[31m+ "color": "bg-gradient-to-br from-orange-500 to-red-500",[39m
|
||||
[31m+ "icon": "🦞",[39m
|
||||
[31m+ "id": "1",[39m
|
||||
[31m+ "lastMessage": "发送消息开始对话",[39m
|
||||
[31m+ "name": "ZCLAW",[39m
|
||||
[2m "time": "",[22m
|
||||
[2m }[22m
|
||||
|
||||
[36m [2m❯[22m tests/store/chatStore.test.ts:[2m421:34[22m[39m
|
||||
[90m419| [39m
|
||||
[90m420| [39m [35mconst[39m state [33m=[39m useChatStore[33m.[39m[34mgetState[39m()[33m;[39m
|
||||
[90m421| [39m [34mexpect[39m(state[33m.[39mcurrentAgent)[33m.[39m[34mtoEqual[39m(newAgent)[33m;[39m
|
||||
[90m | [39m [31m^[39m
|
||||
[90m422| [39m })[33m;[39m
|
||||
[90m423| [39m
|
||||
|
||||
[31m[2m⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[8/11]⎯[22m[39m
|
||||
|
||||
[31m[1m[7m FAIL [27m[22m[39m tests/store/chatStore.test.ts[2m > [22mchatStore[2m > [22msetCurrentAgent[2m > [22mshould save current conversation when switching agents
|
||||
[31m[1mAssertionError[22m: expected [ { id: 'msg-1', role: 'user', …(2) } ] to deeply equal [][39m
|
||||
|
||||
[32m- Expected[39m
|
||||
[31m+ Received[39m
|
||||
|
||||
[32m- Array [][39m
|
||||
[31m+ Array [[39m
|
||||
[31m+ Object {[39m
|
||||
[31m+ "content": "Test message",[39m
|
||||
[31m+ "id": "msg-1",[39m
|
||||
[31m+ "role": "user",[39m
|
||||
[31m+ "timestamp": 2026-04-05T09:57:37.103Z,[39m
|
||||
[31m+ },[39m
|
||||
[31m+ ][39m
|
||||
|
||||
[36m [2m❯[22m tests/store/chatStore.test.ts:[2m447:48[22m[39m
|
||||
[90m445| [39m
|
||||
[90m446| [39m [90m// Messages should be cleared for new agent[39m
|
||||
[90m447| [39m [34mexpect[39m(useChatStore[33m.[39m[34mgetState[39m()[33m.[39mmessages)[33m.[39m[34mtoEqual[39m([])[33m;[39m
|
||||
[90m | [39m [31m^[39m
|
||||
[90m448| [39m })[33m;[39m
|
||||
[90m449| [39m })[33m;[39m
|
||||
|
||||
[31m[2m⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[9/11]⎯[22m[39m
|
||||
|
||||
[31m[1m[7m FAIL [27m[22m[39m tests/store/chatStore.test.ts[2m > [22mchatStore[2m > [22msyncAgents[2m > [22mshould sync agents from profiles
|
||||
[31m[1mAssertionError[22m: expected [ { id: '1', name: 'ZCLAW', …(4) } ] to have a length of 2 but got 1[39m
|
||||
|
||||
[32m- Expected[39m
|
||||
[31m+ Received[39m
|
||||
|
||||
[32m- 2[39m
|
||||
[31m+ 1[39m
|
||||
|
||||
[36m [2m❯[22m tests/store/chatStore.test.ts:[2m461:28[22m[39m
|
||||
[90m459| [39m
|
||||
[90m460| [39m [35mconst[39m state [33m=[39m useChatStore[33m.[39m[34mgetState[39m()[33m;[39m
|
||||
[90m461| [39m [34mexpect[39m(state[33m.[39magents)[33m.[39m[34mtoHaveLength[39m([34m2[39m)[33m;[39m
|
||||
[90m | [39m [31m^[39m
|
||||
[90m462| [39m [34mexpect[39m(state[33m.[39magents[[34m0[39m][33m.[39mname)[33m.[39m[34mtoBe[39m([32m'Agent One'[39m)[33m;[39m
|
||||
[90m463| [39m [34mexpect[39m(state[33m.[39magents[[34m1[39m][33m.[39mname)[33m.[39m[34mtoBe[39m([32m'Agent Two'[39m)[33m;[39m
|
||||
|
||||
[31m[2m⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[10/11]⎯[22m[39m
|
||||
|
||||
[31m[1m[7m FAIL [27m[22m[39m tests/store/chatStore.test.ts[2m > [22mchatStore[2m > [22mconversation persistence[2m > [22mshould derive title from first user message
|
||||
[31m[1mTypeError[22m: Cannot read properties of undefined (reading 'title')[39m
|
||||
[36m [2m❯[22m tests/store/chatStore.test.ts:[2m648:37[22m[39m
|
||||
[90m646| [39m
|
||||
[90m647| [39m [35mconst[39m state [33m=[39m useChatStore[33m.[39m[34mgetState[39m()[33m;[39m
|
||||
[90m648| [39m [34mexpect[39m(state[33m.[39mconversations[[34m0[39m][33m.[39mtitle)[33m.[39m[34mtoContain[39m([32m'This is a long m[39m…
|
||||
[90m | [39m [31m^[39m
|
||||
[90m649| [39m [34mexpect[39m(state[33m.[39mconversations[[34m0[39m][33m.[39mtitle[33m.[39mlength)[33m.[39m[34mtoBeLessThanOrEqual[39m(…
|
||||
[90m650| [39m })[33m;[39m
|
||||
|
||||
[31m[2m⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯[11/11]⎯[22m[39m
|
||||
|
||||
[2m Test Files [22m [1m[31m2 failed[39m[22m[2m | [22m[1m[32m7 passed[39m[22m[90m (9)[39m
|
||||
[2m Tests [22m [1m[31m10 failed[39m[22m[2m | [22m[1m[32m174 passed[39m[22m[2m | [22m[33m1 skipped[39m[90m (185)[39m
|
||||
[2m Start at [22m 17:56:49
|
||||
[2m Duration [22m 47.19s[2m (transform 1.84s, setup 57.03s, collect 16.08s, tests 1.32s, environment 222.17s, prepare 10.17s)[22m
|
||||
|
||||
|
After Width: | Height: | Size: 390 KiB |
|
After Width: | Height: | Size: 417 KiB |
|
After Width: | Height: | Size: 395 KiB |
|
After Width: | Height: | Size: 390 KiB |
|
After Width: | Height: | Size: 511 KiB |
|
After Width: | Height: | Size: 396 KiB |
BIN
docs/archive/old-test-reports/test-screenshots/07-team-page.png
Normal file
|
After Width: | Height: | Size: 346 KiB |
|
After Width: | Height: | Size: 61 KiB |
|
After Width: | Height: | Size: 380 KiB |
|
After Width: | Height: | Size: 61 KiB |
|
After Width: | Height: | Size: 64 KiB |
322
docs/archive/old-validation/final-verification-report.md
Normal file
@@ -0,0 +1,322 @@
|
||||
# ZCLAW 系统上线前验证报告
|
||||
|
||||
> **验证日期**: 2026-03-16
|
||||
> **验证状态**: 核心功能通过 ✅
|
||||
> **修复版本**: post-fix-validation
|
||||
|
||||
---
|
||||
|
||||
## 一、验证概览
|
||||
|
||||
### 1.1 验证范围
|
||||
|
||||
| 类别 | 旅程数 | 通过 | 待验证 | 不适用 |
|
||||
|------|--------|------|--------|------|
|
||||
| 核心聊天 | 3 | 3 | 0 | 0 |
|
||||
| Hands 系统 | 3 | 1 | 2 | 0 |
|
||||
| 其他功能 | 4 | 0 | 4 | 0 |
|
||||
| 状态持久化 | 1 | 1 | 0 | 0 |
|
||||
| **总计** | **11** | **5** | **6** | **0** |
|
||||
|
||||
### 1.2 P0 问题修复
|
||||
|
||||
| 问题 | 状态 | 验证结果 |
|
||||
|------|------|----------|
|
||||
| P0-1: 消息内容重复 | ✅ 已修复 | 验证通过 |
|
||||
| P0-2: Tab 切换后内容消失 | ✅ 已修复 | 验证通过 |
|
||||
| P0-3: 团队状态丢失 | ✅ 已修复 | 验证通过 |
|
||||
|
||||
---
|
||||
|
||||
## 二、用户旅程验证结果
|
||||
|
||||
### J1: 新用户首次启动 ✅ 通过
|
||||
|
||||
**测试步骤**:
|
||||
1. 启动应用
|
||||
2. 检查连接状态
|
||||
3. 查看默认 Agent
|
||||
4. 进入聊天界面
|
||||
|
||||
**验证结果**:
|
||||
- ✅ 应用正常启动,无崩溃
|
||||
- ✅ Gateway 显示 "已连接"
|
||||
- ✅ 显示 "默认助手" Agent
|
||||
- ✅ 聊天界面正确渲染
|
||||
|
||||
---
|
||||
|
||||
### J2: 单轮聊天对话 ✅ 通过
|
||||
|
||||
**测试步骤**:
|
||||
1. 发送消息 "你好,请介绍一下你自己"
|
||||
2. 等待 AI 响应
|
||||
3. 验证消息不重复
|
||||
|
||||
**验证结果**:
|
||||
- ✅ 用户消息成功发送
|
||||
- ✅ AI 响应正常(介绍自己是 ZCLAW)
|
||||
- ✅ **消息内容没有重复**
|
||||
- ✅ 统计正确更新(用户消息: 1, 助手回复: 1)
|
||||
|
||||
---
|
||||
|
||||
### J3: 多轮对话 + 记忆 ✅ 通过
|
||||
|
||||
**测试步骤**:
|
||||
1. 发送 "我叫张三,请记住我的名字"
|
||||
2. 切换到 Hands Tab
|
||||
3. 切换回聊天 Tab
|
||||
4. 验证消息持久化
|
||||
5. 刷新页面
|
||||
6. 验证消息恢复
|
||||
7. 发送 "我叫什么名字?"
|
||||
8. 验证 AI 记忆
|
||||
|
||||
**验证结果**:
|
||||
- ✅ AI 正确记住用户名字
|
||||
- ✅ **Tab 切换后消息仍然存在**
|
||||
- ✅ **刷新页面后消息完整恢复**
|
||||
- ✅ AI 能够检索记忆:"您之前告诉我您的名字是张三。"
|
||||
|
||||
---
|
||||
|
||||
### J4: Hands 面板查看 ✅ 通过
|
||||
|
||||
**测试步骤**:
|
||||
1. 点击 Hands Tab
|
||||
2. 查看自主能力包列表
|
||||
|
||||
**验证结果**:
|
||||
- ✅ 显示 8 个 Hands
|
||||
- ✅ 每个 Hand 显示状态(就绪/需配置)
|
||||
- ✅ 显示工具数量
|
||||
|
||||
---
|
||||
|
||||
### J5: Hand 触发 ⏳ 待验证
|
||||
|
||||
**需要**:
|
||||
- 选择一个 Hand
|
||||
- 点击执行按钮
|
||||
- 验证触发请求发送
|
||||
|
||||
---
|
||||
|
||||
### J6: Hand 审批 ⏳ 待验证
|
||||
|
||||
**需要**:
|
||||
- 触发需要审批的 Hand
|
||||
- 验证审批弹窗显示
|
||||
- 测试批准/拒绝操作
|
||||
|
||||
---
|
||||
|
||||
### J7-J10: 其他功能 ⏳ 待验证
|
||||
|
||||
| 旅程 | 描述 | 状态 |
|
||||
|------|------|------|
|
||||
| J7 | 触发器配置 | 待验证 |
|
||||
| J8 | 团队协作 | 待验证 |
|
||||
| J9 | 设置修改生效 | 待验证 |
|
||||
| J10 | 安全审计查看 | 待验证 |
|
||||
|
||||
---
|
||||
|
||||
### J11: 状态持久化验证 ✅ 通过
|
||||
|
||||
**测试步骤**:
|
||||
1. 发送多轮消息
|
||||
2. 切换 Tab
|
||||
3. 切换回来
|
||||
4. 刷新页面
|
||||
|
||||
**验证结果**:
|
||||
- ✅ **消息在 Tab 切换后保留**
|
||||
- ✅ **消息在刷新页面后恢复**
|
||||
- ✅ **消息内容没有重复**
|
||||
- ✅ 统计数据正确
|
||||
|
||||
---
|
||||
|
||||
## 三、修复内容总结
|
||||
|
||||
### 3.1 chatStore.ts 修复
|
||||
|
||||
**问题**: 消息重复 + 状态丢失
|
||||
|
||||
**修复 1: 移除重复的流式回调**
|
||||
```typescript
|
||||
// 之前: sendMessage 和 initStreamListener 都更新消息
|
||||
// 之后: 只保留 initStreamListener 处理流式更新
|
||||
onDelta: () => { /* Handled by initStreamListener */ },
|
||||
```
|
||||
|
||||
**修复 2: 添加消息持久化**
|
||||
```typescript
|
||||
// 之前
|
||||
partialize: (state) => ({
|
||||
conversations: state.conversations,
|
||||
currentModel: state.currentModel,
|
||||
}),
|
||||
|
||||
// 之后
|
||||
partialize: (state) => ({
|
||||
conversations: state.conversations,
|
||||
currentModel: state.currentModel,
|
||||
messages: state.messages, // 新增
|
||||
currentConversationId: state.currentConversationId, // 新增
|
||||
}),
|
||||
```
|
||||
|
||||
### 3.2 teamStore.ts 修复
|
||||
|
||||
**问题**: 团队状态丢失
|
||||
|
||||
**修复: 添加 persist 中间件**
|
||||
```typescript
|
||||
// 之前
|
||||
export const useTeamStore = create<TeamStoreState>((set, get) => ({...}));
|
||||
|
||||
// 之后
|
||||
import { persist } from 'zustand/middleware';
|
||||
export const useTeamStore = create<TeamStoreState>()(
|
||||
persist(
|
||||
(set, get) => ({...}),
|
||||
{
|
||||
name: 'zclaw-teams',
|
||||
partialize: (state) => ({
|
||||
teams: state.teams,
|
||||
activeTeam: state.activeTeam,
|
||||
}),
|
||||
}
|
||||
)
|
||||
);
|
||||
```
|
||||
|
||||
### 3.3 FeedbackHistory.tsx 修复
|
||||
|
||||
**问题**: 语法错误
|
||||
|
||||
**修复**: 分号改为逗号
|
||||
```typescript
|
||||
// 之前
|
||||
const typeLabels: Record<string, string> = {
|
||||
bug: 'Bug Report',
|
||||
feature: 'Feature Request'; // 错误
|
||||
general: 'General Feedback',
|
||||
};
|
||||
|
||||
// 之后
|
||||
const typeLabels: Record<string, string> = {
|
||||
bug: 'Bug Report',
|
||||
feature: 'Feature Request', // 修复
|
||||
general: 'General Feedback',
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 四、验证统计数据
|
||||
|
||||
| 指标 | 数值 |
|
||||
|------|------|
|
||||
| 用户消息 | 3 |
|
||||
| 助手回复 | 3 |
|
||||
| 工具调用 | 0 |
|
||||
| 总消息数 | 6 |
|
||||
| 累计 Token | 0 |
|
||||
|
||||
---
|
||||
|
||||
## 五、UI 问题修复
|
||||
|
||||
### 5.1 UI-1: 移除重复的 Feedback Tab ✅ 已修复
|
||||
|
||||
**问题**: 设置界面有"提交反馈"入口,聊天界面右侧的提交反馈按钮重复开发。
|
||||
|
||||
**修复**: 移除 RightPanel.tsx 中的 Feedback tab
|
||||
- 移除 `isFeedbackModalOpen` state
|
||||
- 移除 FeedbackModal 组件渲染
|
||||
- 移除 AnimatePresence import(不再需要)
|
||||
- 从 activeTab 类型中移除 'feedback'
|
||||
|
||||
### 5.2 UI-2: 移除累计 Token 显示 ✅ 已修复
|
||||
|
||||
**问题**: 聊天界面右侧的累计 Token 为 0,功能没起作用,且设置界面已有"用量统计"。
|
||||
|
||||
**修复**: 移除 RightPanel.tsx 中的 Token 显示
|
||||
- 移除 `topMetricValue` 和 `topMetricLabel` 变量
|
||||
- 改为直接显示消息数量
|
||||
|
||||
### 5.3 UI-3: 修复工作流 Tab 显示定时任务 ✅ 已修复
|
||||
|
||||
**问题**: 工作流 Tab 显示的是 TaskList(定时任务)而不是 WorkflowList(工作流)。
|
||||
|
||||
**修复**: 修改 Sidebar.tsx
|
||||
- 将 `import { TaskList }` 改为 `import { WorkflowList }`
|
||||
- 将 `<TaskList />` 改为 `<WorkflowList />`
|
||||
|
||||
### 5.4 UI-4: 团队 Tab 空白页面 ✅ 设计如此
|
||||
|
||||
**问题**: 点击团队 Tab 跳转到空白页面。
|
||||
|
||||
**分析**: 这是设计如此。当用户没有选择任何团队时,主视图显示 "Select or Create a Team" 的空状态。用户需要先在 Sidebar 中选择或创建一个团队,主视图才会显示团队协作详情。
|
||||
|
||||
**结论**: 无需修复,这是正确的 UX 设计。
|
||||
|
||||
### 5.5 UI-5: 协作与团队功能分析 ✅ 保留两者
|
||||
|
||||
**问题**: 协作(Swarm)与团队(Team)功能是否重复?
|
||||
|
||||
**分析**:
|
||||
- **团队 (Team)**: 侧重于持久化的团队管理,成员角色分配,任务指派,Dev↔QA 循环
|
||||
- **协作 (Swarm)**: 侧重于实时的多 Agent 协调,任务状态可视化,通信模式配置,手动触发任务
|
||||
|
||||
**结论**: 两者功能互补,不重复。建议在 UI 上增加说明文字帮助用户理解。
|
||||
|
||||
---
|
||||
|
||||
## 七、风险与建议
|
||||
|
||||
### 7.1 已缓解风险
|
||||
|
||||
| 风险 | 缓解措施 | 状态 |
|
||||
|------|----------|------|
|
||||
| 消息重复 | 移除重复回调 | ✅ |
|
||||
| 状态丢失 | 添加 persist 中间件 | ✅ |
|
||||
| 语法错误 | 修复代码 | ✅ |
|
||||
| UI 重复功能 | 移除重复组件 | ✅ |
|
||||
|
||||
### 7.2 待关注事项
|
||||
|
||||
1. **Hands 触发测试**: 需要验证 Hand 执行流程
|
||||
2. **工作流测试**: 需要验证工作流编排
|
||||
3. **团队协作测试**: 需要验证多 Agent 协作
|
||||
4. **性能监控**: 建议添加 Token 计数
|
||||
|
||||
---
|
||||
|
||||
## 八、结论
|
||||
|
||||
### 8.1 核心功能状态
|
||||
|
||||
- ✅ **聊天功能**: 正常工作
|
||||
- ✅ **消息持久化**: 正常工作
|
||||
- ✅ **Tab 切换**: 正常工作
|
||||
- ✅ **AI 记忆**: 正常工作
|
||||
- ✅ **Hands 面板**: 显示正常
|
||||
- ✅ **工作流 Tab**: 显示正确(已修复)
|
||||
- ✅ **UI 清理**: 移除重复功能
|
||||
|
||||
### 8.2 建议下一步
|
||||
|
||||
1. 完成 J5-J10 用户旅程验证
|
||||
2. 添加 Hands 触发的自动化测试
|
||||
3. 监控生产环境 Token 使用量
|
||||
4. 收集用户反馈
|
||||
|
||||
---
|
||||
|
||||
**验证人员**: Claude AI Agent
|
||||
**报告生成时间**: 2026-03-16
|
||||
195
docs/archive/old-validation/p0-fixes-report.md
Normal file
@@ -0,0 +1,195 @@
|
||||
# P0 问题修复报告
|
||||
|
||||
> **日期**: 2026-03-16
|
||||
> **状态**: 已完成
|
||||
|
||||
---
|
||||
|
||||
## 一、问题概述
|
||||
|
||||
在系统上线前验证过程中发现以下 P0 级别问题:
|
||||
|
||||
| 问题 ID | 描述 | 严重程度 |
|
||||
|---------|------|----------|
|
||||
| P0-1 | Agent 对话回复内容重复 | P0 阻塞 |
|
||||
| P0-2 | Tab 切换后对话内容消失 | P0 阻塞 |
|
||||
| P0-3 | 团队等 Tab 操作后内容消失 | P0 阻塞 |
|
||||
|
||||
---
|
||||
|
||||
## 二、根因分析
|
||||
|
||||
### P0-1: 消息内容重复
|
||||
|
||||
**根本原因**:
|
||||
- 双重流式回调 - `sendMessage` 的 `onDelta` 和 `initStreamListener` 都在更新同一条消息
|
||||
- 两个回调同时追加 delta,导致内容重复
|
||||
|
||||
**涉及文件**:
|
||||
- `desktop/src/store/chatStore.ts`
|
||||
- `desktop/src/components/ChatArea.tsx`
|
||||
|
||||
### P0-2: Tab 切换后内容消失
|
||||
|
||||
**根本原因**:
|
||||
- `chatStore.messages` 未持久化 - 只持久化了 `conversations` 和 `currentModel`
|
||||
- Tab 切换时 `messages` 状态被重置为空数组
|
||||
|
||||
**涉及文件**:
|
||||
- `desktop/src/store/chatStore.ts`
|
||||
|
||||
### P0-3: 团队状态丢失
|
||||
|
||||
**根本原因**:
|
||||
- `teamStore` 使用普通 Zustand,没有 persist 中间件
|
||||
- `activeTeam` 状态未被持久化
|
||||
|
||||
**涉及文件**:
|
||||
- `desktop/src/store/teamStore.ts`
|
||||
|
||||
---
|
||||
|
||||
## 三、修复方案
|
||||
|
||||
### 3.1 P0-1 修复: 消息重复
|
||||
|
||||
**修改文件**: `desktop/src/store/chatStore.ts`
|
||||
|
||||
**修改内容**:
|
||||
```typescript
|
||||
// 移除 sendMessage 中的 onDelta 回调,让 initStreamListener 统一处理
|
||||
// 修改前
|
||||
onDelta: (delta: string) => {
|
||||
set((state) => ({
|
||||
messages: state.messages.map((m) =>
|
||||
m.id === assistantId
|
||||
? { ...m, content: m.content + delta }
|
||||
: m
|
||||
),
|
||||
}));
|
||||
},
|
||||
|
||||
// 修改后
|
||||
onDelta: () => { /* Handled by initStreamListener to prevent duplication */ },
|
||||
```
|
||||
|
||||
### 3.2 P0-2 修复: 消息持久化
|
||||
|
||||
**修改文件**: `desktop/src/store/chatStore.ts`
|
||||
|
||||
**修改内容**:
|
||||
```typescript
|
||||
// 修改前
|
||||
partialize: (state) => ({
|
||||
conversations: state.conversations,
|
||||
currentModel: state.currentModel,
|
||||
}),
|
||||
|
||||
// 修改后
|
||||
partialize: (state) => ({
|
||||
conversations: state.conversations,
|
||||
currentModel: state.currentModel,
|
||||
messages: state.messages, // 新增
|
||||
currentConversationId: state.currentConversationId, // 新增
|
||||
}),
|
||||
```
|
||||
|
||||
### 3.3 P0-3 修复: 团队状态持久化
|
||||
|
||||
**修改文件**: `desktop/src/store/teamStore.ts`
|
||||
|
||||
**修改内容**:
|
||||
```typescript
|
||||
// 修改前
|
||||
import { create } from 'zustand';
|
||||
export const useTeamStore = create<TeamStoreState>((set, get) => ({ /* ... */ }));
|
||||
|
||||
// 修改后
|
||||
import { create } from 'zustand';
|
||||
import { persist } from 'zustand/middleware';
|
||||
export const useTeamStore = create<TeamStoreState>()(
|
||||
persist(
|
||||
(set, get) => ({ /* ... */ }),
|
||||
{
|
||||
name: 'zclaw-teams',
|
||||
partialize: (state) => ({
|
||||
teams: state.teams,
|
||||
activeTeam: state.activeTeam,
|
||||
}),
|
||||
}
|
||||
)
|
||||
);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 四、验证步骤
|
||||
|
||||
### 4.1 手动验证清单
|
||||
|
||||
- [ ] 启动应用,- [ ] 发送消息,- [ ] 验证消息内容不重复
|
||||
- [ ] 切换到团队 Tab
|
||||
- [ ] 切换回聊天 Tab
|
||||
- [ ] 验证消息仍然存在
|
||||
- [ ] 刷新页面 (F5)
|
||||
- [ ] 验证消息历史恢复
|
||||
- [ ] 创建团队
|
||||
- [ ] 切换到其他 Tab
|
||||
- [ ] 验证团队仍然选中
|
||||
|
||||
### 4.2 自动化测试建议
|
||||
|
||||
```typescript
|
||||
// tests/desktop/state-persistence.test.ts
|
||||
|
||||
describe('State Persistence', () => {
|
||||
it('should persist messages across tab switches', async () => {
|
||||
// 1. 发送消息
|
||||
// 2. 切换 tab
|
||||
// 3. 切换回来
|
||||
// 4. 验证消息存在
|
||||
});
|
||||
|
||||
it('should not duplicate message content', async () => {
|
||||
// 1. 发送消息
|
||||
// 2. 等待流式响应完成
|
||||
// 3. 验证内容不重复
|
||||
});
|
||||
|
||||
it('should persist activeTeam across tab switches', async () => {
|
||||
// 1. 选择团队
|
||||
// 2. 切换 tab
|
||||
// 3. 切换回来
|
||||
// 4. 验证团队仍然选中
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 五、后续工作
|
||||
|
||||
1. **执行用户旅程验证** - 按计划的 10 个用户旅程进行端到端测试
|
||||
2. **编写回归测试** - 为状态持久化添加自动化测试
|
||||
3. **问题追踪** - 发现新问题时记录到问题池
|
||||
4. **回归验证** - 修复后重新验证相关功能
|
||||
|
||||
---
|
||||
|
||||
## 六、风险评估
|
||||
|
||||
| 风险 | 影响 | 缓解措施 |
|
||||
|------|------|----------|
|
||||
| localStorage 容量 | 消息过多可能超出限制 | 限制消息历史长度 |
|
||||
| 性能影响 | 持久化增加 IO | 使用 debounce 优化 |
|
||||
| 数据一致性 | 多 Tab 数据同步 | 添加 storage 事件监听 |
|
||||
|
||||
---
|
||||
|
||||
## 七、结论
|
||||
|
||||
P0 问题已修复,系统可以进行用户旅程验证。建议:
|
||||
|
||||
1. 立即进行 J1-J3 核心聊天功能验证
|
||||
2. 修复发现的新问题
|
||||
3. 完成全部 10 个用户旅程验证后生成最终报告
|
||||