feat(hands): restructure Hands UI with Chinese localization
Major changes: - Add HandList.tsx component for left sidebar - Add HandTaskPanel.tsx for middle content area - Restructure Sidebar tabs: 分身/HANDS/Workflow - Remove Hands tab from RightPanel - Localize all UI text to Chinese - Archive legacy OpenClaw documentation - Add Hands integration lessons document - Update feature checklist with new components UI improvements: - Left sidebar now shows Hands list with status icons - Middle area shows selected Hand's tasks and results - Consistent styling with Tailwind CSS - Chinese status labels and buttons Documentation: - Create docs/archive/openclaw-legacy/ for old docs - Add docs/knowledge-base/hands-integration-lessons.md - Update docs/knowledge-base/feature-checklist.md - Update docs/knowledge-base/README.md Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
467
plans/2026-03-12-zclaw-delivery-execution-plan.md
Normal file
467
plans/2026-03-12-zclaw-delivery-execution-plan.md
Normal file
@@ -0,0 +1,467 @@
|
||||
# ZCLAW 交付执行计划(2026-03-12)
|
||||
|
||||
## 1. 计划目标
|
||||
|
||||
本计划的目标不是继续做“功能堆叠”,而是把当前仓库推进到**可安装、可启动、可连接、可对话、可配置、可验证**的可交付状态。
|
||||
|
||||
当前对“完整可用 ZCLAW”的定义如下:
|
||||
|
||||
- 用户能够在本机启动 ZCLAW 桌面应用
|
||||
- 用户安装 ZCLAW 时,OpenClaw 运行时已经随包提供,而不是要求用户另行安装
|
||||
- 桌面应用能够引导并管理随 ZCLAW 一起分发的本地 OpenClaw Gateway
|
||||
- 前端能够稳定连接 Gateway,并完成基础握手与鉴权
|
||||
- 用户能够创建、编辑、切换 Agent(Clone)
|
||||
- 用户能够发起真实对话并收到流式回复
|
||||
- 关键设置页不再只是静态占位,而是尽量接到真实后端能力
|
||||
- 有一套清晰的验收与收尾流程,支持阶段性提交与后续发布
|
||||
|
||||
---
|
||||
|
||||
## 2. 当前基线
|
||||
|
||||
### 2.1 已完成的关键能力
|
||||
|
||||
- Gateway 握手参数已修正,能够兼容 OpenClaw 2026.3.11
|
||||
- Token 鉴权已接入前端连接流程
|
||||
- `zclaw-ui` 插件可被 Gateway 正常加载
|
||||
- Agent 的创建、编辑、保存链路已打通
|
||||
- `scripts/setup.ts` 已可在已有 `~/.openclaw/openclaw.json` 时非破坏性合并插件与 skills 路径
|
||||
- 自定义插件 manifest/package id 对齐问题已修复
|
||||
|
||||
### 2.2 当前仍阻塞交付的核心问题
|
||||
|
||||
按交付优先级排序,当前最关键的缺口为:
|
||||
|
||||
1. **桌面端尚未真正接管 Gateway 生命周期**
|
||||
- `src/gateway/manager.ts` 已存在,但未被 Tauri 壳使用
|
||||
- `desktop/src-tauri/src/lib.rs` 仍是默认模板
|
||||
- 当前产品更像“前端连接外部 Gateway”,还不是“完整桌面应用”
|
||||
|
||||
2. **当前仍默认依赖用户独立安装 OpenClaw**
|
||||
- 这与最终产品目标不一致
|
||||
- 最终必须做到:安装 ZCLAW 后即可直接使用 OpenClaw 能力
|
||||
- 因此现阶段的 CLI/PATH 依赖只能作为开发期和过渡期方案
|
||||
|
||||
3. **真实桌面链路缺少本地运行闭环验证**
|
||||
- 需要验证 Tauri 内从启动 Gateway 到连接、到拉数据、到发消息的完整过程
|
||||
|
||||
4. **设置体系中仍有若干页面/按钮处于占位状态**
|
||||
- 部分页面已有 UI 但尚未连接真实能力
|
||||
- 会影响“可用”判断,尤其是用户首次体验
|
||||
|
||||
5. **交付收尾缺少固定验收流程**
|
||||
- 需要统一 smoke test、安装前检查、文档更新、阶段提交点
|
||||
|
||||
---
|
||||
|
||||
## 3. 总体推进策略
|
||||
|
||||
### 3.1 核心原则
|
||||
|
||||
- **先打通闭环,再做扩展**:优先修复阻塞真实使用的能力缺口,而不是继续加功能
|
||||
- **优先最短交付路径**:优先复用 OpenClaw 现有 CLI/service 能力,而不是一开始就做完整 sidecar 架构
|
||||
- **最终必须内置 OpenClaw**:开发阶段允许复用系统已安装的 OpenClaw,但交付阶段必须改为随 ZCLAW 一起分发和托管
|
||||
- **浏览器模式不回退**:新增 Tauri 能力必须有运行时保护,不影响现有浏览器预览/开发体验
|
||||
- **阶段可提交**:每个阶段都有独立验收标准,达到后可形成 clean checkpoint
|
||||
|
||||
### 3.2 本轮优先级
|
||||
|
||||
- **P0**:Tauri 桌面壳接入本地 Gateway 生命周期管理
|
||||
- **P0**:完成真实桌面端基础闭环验证
|
||||
- **P0**:确定并落地“ZCLAW 安装即内置 OpenClaw”的分发方案
|
||||
- **P1**:补齐最影响可用性的设置页占位项
|
||||
- **P1**:形成交付前 smoke checklist 和文档更新
|
||||
- **P2**:补测试、清理遗留代码、准备打包发布
|
||||
|
||||
---
|
||||
|
||||
## 4. 分阶段执行计划
|
||||
|
||||
## Phase A:桌面端本地 Gateway 生命周期管理(当前最高优先级)
|
||||
|
||||
### A.1 目标
|
||||
|
||||
让 ZCLAW 桌面应用在 Tauri 环境下具备对本地 OpenClaw Gateway 的基础管理能力:
|
||||
|
||||
- 查询本地 Gateway 状态
|
||||
- 启动本地 Gateway
|
||||
- 停止本地 Gateway
|
||||
- 重启本地 Gateway
|
||||
- 在前端展示本地状态,并与现有 WebSocket 连接状态区分开
|
||||
|
||||
### A.2 实现策略
|
||||
|
||||
优先采用**Tauri Rust 命令封装 OpenClaw CLI** 的方式,而不是直接引入完整 sidecar:
|
||||
|
||||
- Rust 侧封装以下命令:
|
||||
- `openclaw gateway status --json`
|
||||
- `openclaw gateway start --json`
|
||||
- `openclaw gateway stop --json`
|
||||
- `openclaw gateway restart --json`
|
||||
- 前端通过 `invoke` 调用 Rust 命令
|
||||
- 通过运行时判断,仅在 Tauri 环境中启用这组能力
|
||||
- 浏览器模式继续保留“手工连接外部 Gateway”的现有逻辑
|
||||
|
||||
说明:
|
||||
|
||||
- 这一阶段是**开发期过渡方案**
|
||||
- 它的价值是先把桌面端产品闭环跑通
|
||||
- 但它**不是最终交付形态**
|
||||
- 最终交付必须把 OpenClaw 运行时随 ZCLAW 一起打包,而不是要求用户本机已有 `openclaw`
|
||||
|
||||
### 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”状态卡片
|
||||
- 用户可点击启动/停止/重启
|
||||
- 启动成功后,前端可继续连接并拉取基础数据
|
||||
- 浏览器模式不因该改动而报错或白屏
|
||||
- 开发环境下,即使仍依赖系统 `openclaw`,也已经明确与最终 bundling 方案解耦
|
||||
|
||||
### A.5 风险与应对
|
||||
|
||||
- **风险**:不同机器上 `openclaw` 不在 PATH
|
||||
- **应对**:前端明确提示“未安装 OpenClaw 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:OpenClaw 随包分发与运行时托管
|
||||
|
||||
### C.1 目标
|
||||
|
||||
把当前“依赖用户本机单独安装 OpenClaw”的开发态方案,推进到真正可交付的产品方案:
|
||||
|
||||
- 用户安装 ZCLAW 时,OpenClaw 运行时已经包含在安装包内
|
||||
- ZCLAW 启动后,能够直接找到并启动内置 OpenClaw
|
||||
- 用户不需要再单独安装一套 OpenClaw CLI / 环境
|
||||
|
||||
### C.2 目标形态
|
||||
|
||||
最终交付建议采用以下形态:
|
||||
|
||||
- 安装包内包含 OpenClaw 可执行运行时或受控分发产物
|
||||
- Tauri Rust 侧通过固定相对路径或 sidecar 机制调用该运行时
|
||||
- ZCLAW 负责:
|
||||
- 初始化 OpenClaw home / workspace
|
||||
- 写入或合并默认配置
|
||||
- 启动 / 停止 / 重启 Gateway
|
||||
- 读取日志与状态
|
||||
|
||||
### C.3 方案比较
|
||||
|
||||
#### 方案 1:继续依赖系统安装的 `openclaw`
|
||||
|
||||
优点:
|
||||
|
||||
- 当前开发改造最少
|
||||
|
||||
缺点:
|
||||
|
||||
- 不符合最终产品目标
|
||||
- 用户安装体验差
|
||||
- 环境差异和 PATH 问题会显著增加支持成本
|
||||
|
||||
结论:
|
||||
|
||||
- **仅适合开发期,不可作为最终交付方案**
|
||||
|
||||
#### 方案 2:把 OpenClaw 作为 sidecar / bundled runtime 随 ZCLAW 分发
|
||||
|
||||
优点:
|
||||
|
||||
- 符合 QClaw / AutoClaw 式的一体化交付体验
|
||||
- 可控性高
|
||||
- 便于做安装后自启动、版本锁定、升级兼容
|
||||
|
||||
缺点:
|
||||
|
||||
- 需要处理体积、签名、跨平台打包、路径定位
|
||||
|
||||
结论:
|
||||
|
||||
- **这是最终推荐方案**
|
||||
|
||||
### C.4 实施任务
|
||||
|
||||
- 确认 OpenClaw 可分发形态
|
||||
- npm 包直接落地
|
||||
- 预构建二进制
|
||||
- 内置 Node + OpenClaw 组合运行时
|
||||
- 确认 Tauri 2 下 sidecar / bundled binary 的最佳实现方式
|
||||
- 为 Windows 优先落地一版 bundling 方案
|
||||
- 调整 Rust 侧命令执行逻辑
|
||||
- 优先调用内置运行时
|
||||
- 开发模式可回退到系统 `openclaw`
|
||||
- 验证安装后首次启动流程
|
||||
- 不依赖用户额外安装
|
||||
- 可直接启动 Gateway
|
||||
- 可连接、可聊天、可配置
|
||||
|
||||
### C.5 验收标准
|
||||
|
||||
- 全新机器上,未单独安装 OpenClaw 的情况下,可直接安装并启动 ZCLAW
|
||||
- ZCLAW 可成功拉起内置 OpenClaw Gateway
|
||||
- Agent / 聊天 / 设置等核心功能可正常工作
|
||||
- 用户文档不再要求“先安装 OpenClaw 再使用 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 不应再把系统级 `openclaw --version` 作为前置要求
|
||||
- 应改为验证 ZCLAW 内置运行时是否可用
|
||||
|
||||
#### 桌面启动检查
|
||||
|
||||
- `pnpm --dir desktop tauri dev`
|
||||
- UI 能正常打开
|
||||
- 设置页不白屏
|
||||
|
||||
#### Gateway 闭环检查
|
||||
|
||||
- 本地 Gateway 状态可读
|
||||
- 能启动/停止/重启
|
||||
- 前端连接成功
|
||||
|
||||
#### 核心功能检查
|
||||
|
||||
- Clone 列表加载
|
||||
- 新建 Clone
|
||||
- 编辑 Clone
|
||||
- 发送首条消息
|
||||
- 收到流式回复
|
||||
|
||||
#### 配置检查
|
||||
|
||||
- quick config 可读写
|
||||
- workspace 信息可读取
|
||||
- 插件状态可显示
|
||||
|
||||
#### 安装闭环检查
|
||||
|
||||
- 全新环境中无需单独安装 OpenClaw
|
||||
- 安装 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:OpenClaw 随包分发打通
|
||||
|
||||
输出物:
|
||||
|
||||
- Windows 优先的一体化 bundling 方案
|
||||
- ZCLAW 优先调用内置 OpenClaw 运行时
|
||||
- 安装后无需用户额外安装 OpenClaw 的可运行链路
|
||||
|
||||
完成标志:
|
||||
|
||||
- 在未安装 OpenClaw 的机器/环境中,安装 ZCLAW 后即可直接使用
|
||||
|
||||
## Milestone 4:设置页与交付收尾
|
||||
|
||||
输出物:
|
||||
|
||||
- 最小可交付设置体验
|
||||
- smoke checklist
|
||||
- README / PROGRESS 更新
|
||||
|
||||
完成标志:
|
||||
|
||||
- 仓库进入“可给他人试用”的状态
|
||||
|
||||
---
|
||||
|
||||
## 6. 本轮立即执行项
|
||||
|
||||
按当前优先级,接下来立刻执行:
|
||||
|
||||
1. 在 Tauri Rust 侧实现 Gateway 管理命令
|
||||
2. 在前端新增 Tauri Gateway bridge
|
||||
3. 在 `gatewayStore` 中接入本地 Gateway 状态与动作
|
||||
4. 在 Settings > General 中增加本地 Gateway 管理卡片
|
||||
5. 明确 OpenClaw 随包分发方案,避免把系统安装依赖固化为最终设计
|
||||
6. 进行编译/运行级验证
|
||||
7. 若验证通过,记录到 `PROGRESS.md`
|
||||
|
||||
---
|
||||
|
||||
## 7. 阶段提交策略
|
||||
|
||||
本轮按以下 checkpoint 推进:
|
||||
|
||||
### Checkpoint A
|
||||
|
||||
- 完成计划文档
|
||||
- 完成 Tauri 命令桥与前端接线
|
||||
|
||||
### Checkpoint B
|
||||
|
||||
- 完成本地 Gateway 管理 UI
|
||||
- 完成基础验证
|
||||
|
||||
### Checkpoint C
|
||||
|
||||
- 完成 OpenClaw bundling / sidecar 方案设计
|
||||
- 明确 Windows 优先的交付路径
|
||||
|
||||
### Checkpoint D
|
||||
|
||||
- 完成设置页收尾 / 文档更新 / smoke checklist
|
||||
|
||||
说明:
|
||||
|
||||
- 代码会按干净阶段组织
|
||||
- 如需执行远端 `push`,仍单独确认
|
||||
|
||||
---
|
||||
|
||||
## 8. 结论
|
||||
|
||||
当前最短、最正确的交付路径,不是继续扩展更多功能,而是先把 ZCLAW 从“能连 Gateway 的前端”推进成“能在桌面端真正管理并使用内置 OpenClaw 的产品”。
|
||||
|
||||
因此,本轮执行的核心结论是:
|
||||
|
||||
- **先做 Tauri 本地 Gateway 生命周期管理**
|
||||
- **再完成 OpenClaw 随包分发方案**
|
||||
- **然后做真实桌面端闭环验证**
|
||||
- **最后收尾设置页与交付文档**
|
||||
|
||||
这条路线最符合当前仓库状态,也最接近“完整可用 ZCLAW”的真实交付目标。
|
||||
663
plans/fancy-sprouting-teacup.md
Normal file
663
plans/fancy-sprouting-teacup.md
Normal file
@@ -0,0 +1,663 @@
|
||||
# OpenFang Hands & Workflow 集成开发方案
|
||||
|
||||
## 上下文
|
||||
|
||||
**目标**: 将 OpenFang 的 Hands 和 Workflow 功能深度集成到 ZClaw 桌面客户端,提供与 OpenFang Web 界面对等的用户体验。
|
||||
|
||||
**当前状态**:
|
||||
- ZClaw 已有基础的 `HandsPanel.tsx` 和 `WorkflowList.tsx` 组件
|
||||
- 这些组件功能有限,缺少 OpenFang 的核心 UI 特性
|
||||
- OpenFang v0.4.0 提供了 8 个 Hands 和完整的 Workflow/Scheduler 系统
|
||||
|
||||
**参考界面**: http://127.0.0.1:50051 (OpenFang Dashboard)
|
||||
|
||||
---
|
||||
|
||||
## 一、OpenFang 界面分析总结
|
||||
|
||||
### 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 (优先级: 高)
|
||||
|
||||
**目标**: 提供与 OpenFang 对等的 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: 导航重构 (优先级: 中)
|
||||
|
||||
**目标**: 重构导航结构,匹配 OpenFang 布局
|
||||
|
||||
**文件修改**:
|
||||
- `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,连接 OpenFang (端口 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>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 七、风险与缓解
|
||||
|
||||
| 风险 | 影响 | 缓解措施 |
|
||||
|------|------|----------|
|
||||
| OpenFang API 变更 | 高 | 使用实际 API 测试验证,保持与 OpenFang v0.4.0 兼容 |
|
||||
| UI 复杂度 | 中 | 分阶段实现,先核心功能后高级功能 |
|
||||
| 性能问题 | 低 | 使用虚拟列表处理大量数据 |
|
||||
|
||||
---
|
||||
|
||||
*计划创建时间: 2026-03-14*
|
||||
*参考版本: OpenFang v0.4.0*
|
||||
386
plans/immutable-imagining-naur.md
Normal file
386
plans/immutable-imagining-naur.md
Normal file
@@ -0,0 +1,386 @@
|
||||
# ZClaw: 从 OpenClaw 迁移到 OpenFang 可行性方案
|
||||
|
||||
> **规划日期**: 2026-03-13
|
||||
> **目标**: 制定从 OpenClaw 到 OpenFang 的渐进式迁移策略,实现平稳过渡
|
||||
|
||||
---
|
||||
|
||||
## 一、背景与动机
|
||||
|
||||
### 1.1 当前架构 (OpenClaw)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ ZClaw Desktop (当前) │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ React 19 UI → Zustand Store → GatewayClient → OpenClaw │
|
||||
│ 技术栈: Tauri 2.0 + TypeScript + Node.js Gateway │
|
||||
│ 内存: >1GB | 启动: 2-5s | 安装: 500MB │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 1.2 目标架构 (OpenFang)
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ ZClaw Desktop (OpenFang) │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ React 19 UI → Zustand Store → OpenFangClient → OpenFang │
|
||||
│ 技术栈: Tauri 2.0 + TypeScript + Rust Gateway │
|
||||
│ 内存: ~40MB | 启动: 180ms | 安装: 32MB │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 1.3 迁移动机
|
||||
|
||||
| 维度 | OpenClaw | OpenFang | 提升 |
|
||||
|------|----------|----------|------|
|
||||
| **启动速度** | 5.98s | 180ms | **33x 更快** |
|
||||
| **内存占用** | 394MB | 40MB | **90% 更少** |
|
||||
| **安装大小** | 500MB | 32MB | **94% 更小** |
|
||||
| **安全防护** | 3 层 | 16 层 | **企业级安全** |
|
||||
| **通道支持** | 20+ | 40+ | **覆盖更广** |
|
||||
| **自主能力** | 无 | 7 Hands | **从被动到主动** |
|
||||
|
||||
---
|
||||
|
||||
## 二、核心差异分析
|
||||
|
||||
### 2.1 协议差异
|
||||
|
||||
| 方面 | OpenClaw | OpenFang |
|
||||
|------|----------|----------|
|
||||
| **WebSocket URL** | `ws://127.0.0.1:18789` | `ws://127.0.0.1:4200/ws` |
|
||||
| **协议格式** | 自定义 JSON 帧 | 标准 JSON + gRPC |
|
||||
| **认证方式** | Ed25519 设备签名 | Ed25519 + JWT |
|
||||
|
||||
### 2.2 配置差异
|
||||
|
||||
| 方面 | OpenClaw | OpenFang |
|
||||
|------|----------|----------|
|
||||
| **配置目录** | `~/.openclaw/` | `~/.openfang/` |
|
||||
| **配置格式** | YAML/JSON | TOML |
|
||||
| **插件系统** | TypeScript (`index.ts`) | SKILL.md + WASM |
|
||||
|
||||
### 2.3 API 差异
|
||||
|
||||
| 功能 | OpenClaw RPC | OpenFang 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. **双版本并行**: 保持 OpenClaw 可用,同时开发 OpenFang
|
||||
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. 创建 `OpenFangClient` 骨架
|
||||
3. 配置双后端切换机制
|
||||
4. 设置 OpenFang 开发环境
|
||||
|
||||
**交付物**:
|
||||
- `desktop/src/lib/types/gateway-backend.ts` - 接口定义
|
||||
- `desktop/src/lib/openfang-client.ts` - 客户端骨架
|
||||
- `desktop/src/lib/backend-factory.ts` - 后端工厂
|
||||
|
||||
### Phase 2: 客户端实现 (Week 3-4)
|
||||
|
||||
**目标**: 完整实现 OpenFang 客户端
|
||||
|
||||
**关键文件**: [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. OpenClaw 实现 (现有代码重构)
|
||||
class OpenClawBackend implements GatewayBackend { ... }
|
||||
|
||||
// 3. OpenFang 实现 (新建)
|
||||
class OpenFangBackend implements GatewayBackend {
|
||||
private ws: WebSocket;
|
||||
private url = 'ws://127.0.0.1:4200/ws';
|
||||
|
||||
async connect(): Promise<void> {
|
||||
// OpenFang 认证协议
|
||||
}
|
||||
|
||||
async chat(message: string, opts?: ChatOptions): Promise<{runId: string}> {
|
||||
// OpenFang chat 格式
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Phase 3: 状态迁移 (Week 5-6)
|
||||
|
||||
**目标**: 更新状态管理层支持双后端
|
||||
|
||||
**关键文件**: [gatewayStore.ts](desktop/src/store/gatewayStore.ts)
|
||||
|
||||
**修改内容**:
|
||||
```typescript
|
||||
interface GatewayStore {
|
||||
// 新增
|
||||
backendType: 'openclaw' | 'openfang';
|
||||
switchBackend(type: 'openclaw' | 'openfang'): void;
|
||||
|
||||
// 修改 connect 方法
|
||||
connect: async (url?, token?) => {
|
||||
const backend = getBackendFactory().create(get().backendType);
|
||||
await backend.connect(url, token);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Phase 4: 插件迁移 (Week 7-9)
|
||||
|
||||
**目标**: 迁移现有插件到 OpenFang 格式
|
||||
|
||||
| 插件 | 当前格式 | 目标格式 | 复杂度 |
|
||||
|------|----------|----------|--------|
|
||||
| `zclaw-chinese-models` | TypeScript | TOML 配置 | 中 |
|
||||
| `zclaw-feishu` | TypeScript | Rust/WASM | 高 |
|
||||
| `zclaw-ui` | TypeScript RPC | REST API | 高 |
|
||||
|
||||
**迁移方案**:
|
||||
```
|
||||
plugins/
|
||||
├── zclaw-chinese-models/
|
||||
│ ├── openclaw.plugin.json → 删除
|
||||
│ └── index.ts → 转换为 providers.toml
|
||||
│
|
||||
├── zclaw-feishu/
|
||||
│ └── index.ts → 迁移到 OpenFang channels
|
||||
│
|
||||
└── zclaw-ui/
|
||||
└── index.ts → 拆分为 REST 端点
|
||||
```
|
||||
|
||||
### Phase 5: Tauri 后端 (Week 10-11)
|
||||
|
||||
**目标**: 更新 Rust 后端支持 OpenFang
|
||||
|
||||
**关键文件**: [lib.rs](desktop/src-tauri/src/lib.rs)
|
||||
|
||||
**修改内容**:
|
||||
```rust
|
||||
// 新增 OpenFang 命令
|
||||
#[tauri::command]
|
||||
async fn openfang_status() -> Result<OpenFangStatus, String> { ... }
|
||||
|
||||
#[tauri::command]
|
||||
async fn openfang_start() -> Result<(), String> { ... }
|
||||
|
||||
#[tauri::command]
|
||||
async fn openfang_stop() -> Result<(), String> { ... }
|
||||
|
||||
// 新增配置迁移命令
|
||||
#[tauri::command]
|
||||
async fn migrate_to_openfang() -> Result<MigrationResult, String> { ... }
|
||||
```
|
||||
|
||||
### Phase 6: UI 增强 (Week 12-14)
|
||||
|
||||
**目标**: 添加 OpenFang 特有的 UI 功能
|
||||
|
||||
**新增组件**:
|
||||
1. `HandsPanel.tsx` - Hands 管理界面
|
||||
2. `WorkflowEditor.tsx` - 工作流编辑器
|
||||
3. `TriggerManager.tsx` - 触发器管理
|
||||
4. `AuditLogs.tsx` - 审计日志查看
|
||||
|
||||
**修改组件**:
|
||||
1. `SettingsLayout.tsx` - 添加后端切换选项
|
||||
2. `General.tsx` - 添加 OpenFang 配置项
|
||||
|
||||
### Phase 7: 测试验证 (Week 15-16)
|
||||
|
||||
**目标**: 全面测试和验证
|
||||
|
||||
**测试范围**:
|
||||
- 单元测试: 新客户端、适配层
|
||||
- 集成测试: 端到端消息流
|
||||
- 性能测试: 启动时间、内存占用
|
||||
- 迁移测试: 配置迁移正确性
|
||||
|
||||
---
|
||||
|
||||
## 五、风险评估与缓解
|
||||
|
||||
### 5.1 技术风险
|
||||
|
||||
| 风险 | 级别 | 缓解措施 |
|
||||
|------|------|----------|
|
||||
| 协议不兼容 | 高 | 创建适配层,保持双后端 |
|
||||
| 插件迁移复杂 | 高 | 分阶段迁移,保持 TypeScript 桥接 |
|
||||
| OpenFang 不成熟 | 中 | 持续关注上游,建立社区联系 |
|
||||
| 配置格式差异 | 中 | 构建自动迁移工具 |
|
||||
|
||||
### 5.2 运营风险
|
||||
|
||||
| 风险 | 级别 | 缓解措施 |
|
||||
|------|------|----------|
|
||||
| 用户困惑 | 中 | 清晰文档,渐进发布 |
|
||||
| 数据丢失 | 高 | 自动备份,非破坏性迁移 |
|
||||
| 支持负担 | 中 | FAQ,故障排除指南 |
|
||||
|
||||
### 5.3 回滚策略
|
||||
|
||||
```typescript
|
||||
// 环境变量切换
|
||||
const USE_OPENFANG = process.env.ZCLAW_USE_OPENFANG === 'true';
|
||||
|
||||
// localStorage 切换
|
||||
const backendType = localStorage.getItem('zclaw-backend') || 'openclaw';
|
||||
|
||||
// 一键回滚
|
||||
function rollbackToOpenClaw() {
|
||||
localStorage.setItem('zclaw-backend', 'openclaw');
|
||||
window.location.reload();
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 六、验证方案
|
||||
|
||||
### 6.1 功能验证清单
|
||||
|
||||
**核心功能**:
|
||||
- [ ] WebSocket 连接和认证
|
||||
- [ ] 消息发送和流式接收
|
||||
- [ ] Agent/Clone CRUD 操作
|
||||
- [ ] 频道管理 (飞书)
|
||||
- [ ] 技能加载和执行
|
||||
- [ ] 使用统计
|
||||
- [ ] 配置管理
|
||||
|
||||
**OpenFang 新特性**:
|
||||
- [ ] Hand 触发 (Clip, Lead, Researcher 等)
|
||||
- [ ] Workflow 执行
|
||||
- [ ] 16 层安全验证
|
||||
- [ ] 审计日志访问
|
||||
|
||||
### 6.2 性能基准
|
||||
|
||||
| 指标 | OpenClaw 基线 | OpenFang 目标 |
|
||||
|------|---------------|---------------|
|
||||
| 冷启动 | 5.98s | < 500ms |
|
||||
| 空闲内存 | 394MB | < 100MB |
|
||||
| 聊天延迟 | 100ms | < 50ms |
|
||||
| 安装大小 | 500MB | < 100MB |
|
||||
|
||||
---
|
||||
|
||||
## 七、关键文件清单
|
||||
|
||||
| 文件 | 修改类型 | 说明 |
|
||||
|------|----------|------|
|
||||
| [gateway-client.ts](desktop/src/lib/gateway-client.ts) | 重构 | 抽取接口,创建 OpenFang 实现 |
|
||||
| [gatewayStore.ts](desktop/src/store/gatewayStore.ts) | 修改 | 添加后端切换逻辑 |
|
||||
| [chatStore.ts](desktop/src/store/chatStore.ts) | 修改 | 适配新事件格式 |
|
||||
| [lib.rs](desktop/src-tauri/src/lib.rs) | 扩展 | 添加 OpenFang 管理命令 |
|
||||
| [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) | 迁移 | 使用 OpenFang channel |
|
||||
|
||||
---
|
||||
|
||||
## 八、时间线总结
|
||||
|
||||
| 阶段 | 周期 | 开始 | 结束 | 关键交付物 |
|
||||
|------|------|------|------|------------|
|
||||
| Phase 1 | 2周 | Week 1 | Week 2 | OpenFangClient 骨架 |
|
||||
| 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 OpenFang 支持 |
|
||||
| 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 决策建议
|
||||
|
||||
| 目标 | 建议 |
|
||||
|------|------|
|
||||
| 追求企业市场 | ✅ **强烈建议迁移** |
|
||||
| 追求差异化竞争 | ✅ **建议迁移** |
|
||||
| 目标是内容创作者/销售 | ✅ **强烈建议迁移** |
|
||||
| 资源有限 | ⚠️ 渐进评估 |
|
||||
| 追求快速迭代 | ⚠️ 保持 OpenClaw,关注 OpenFang |
|
||||
|
||||
### 9.3 下一步行动
|
||||
|
||||
1. **立即**: 确认迁移决策,分配资源
|
||||
2. **Week 1**: 创建 `GatewayBackend` 接口
|
||||
3. **Week 2**: 搭建 OpenFang 开发环境
|
||||
4. **Week 3-4**: 实现 `OpenFangClient`
|
||||
|
||||
---
|
||||
|
||||
*规划日期: 2026-03-13*
|
||||
*版本: v1.0*
|
||||
420
plans/new-session-prompt-roadmap.md
Normal file
420
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 面板编辑、保存回刷已验证通过
|
||||
- 快速配置应视为创建/更新 OpenClaw 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 / OpenClaw 演进升级为结构化原生协议。
|
||||
|
||||
---
|
||||
|
||||
## 五、目标能力定义
|
||||
|
||||
### 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 还未完全映射到 OpenClaw runtime agent
|
||||
|
||||
影响:
|
||||
|
||||
- 即使 Agent Profile 已切换,底层仍可能没有原生 agent routing
|
||||
|
||||
处理:
|
||||
|
||||
- 本轮先用“首轮消息注入”保证真实行为变化
|
||||
- 后续把 `agentId` 传输与 runtime routing 作为独立里程碑推进
|
||||
|
||||
### 风险 2:提示词注入格式可能影响回答质量
|
||||
|
||||
影响:
|
||||
|
||||
- 包装格式不佳时,可能让模型输出不稳定
|
||||
|
||||
处理:
|
||||
|
||||
- 采用清晰、边界明确的包裹格式
|
||||
- 在真实模型上做几组样例测试
|
||||
|
||||
### 风险 3:会话切换与持久化逻辑容易变脆
|
||||
|
||||
影响:
|
||||
|
||||
- 草稿、历史会话、当前会话三者状态可能串扰
|
||||
|
||||
处理:
|
||||
|
||||
- 优先把 store 状态边界设计清楚
|
||||
- 先覆盖核心状态迁移测试,再做 UI 微调
|
||||
|
||||
---
|
||||
|
||||
## 十、完成定义
|
||||
|
||||
当以下条件同时满足时,可视为“新会话提示词”能力第一阶段完成:
|
||||
|
||||
- Agent 默认新会话提示词可创建、编辑、保存、回刷
|
||||
- 新会话开始前用户可临时覆盖该提示词
|
||||
- 首轮真实发送到 Gateway 的消息中包含该提示词上下文
|
||||
- 同一会话后续消息不重复注入
|
||||
- 历史会话可以恢复其实际使用过的提示词信息
|
||||
- 快速配置、右侧 Agent 面板、聊天区三处语义一致
|
||||
|
||||
---
|
||||
|
||||
## 十一、下一步建议
|
||||
|
||||
在本计划落地后,建议立即开始:
|
||||
|
||||
- **P1:先补数据模型与插件透传**
|
||||
- **P2:再补 chatStore 的会话级状态模型**
|
||||
- **P3:最后接入首轮消息注入并做联调验证**
|
||||
|
||||
这会以最小改动建立一条真正可用的闭环,也是当前最符合 ZCLAW 产品化推进方向的高杠杆路径。
|
||||
231
plans/sequential-churning-wreath-agent-a730f837627aeb203.md
Normal file
231
plans/sequential-churning-wreath-agent-a730f837627aeb203.md
Normal file
@@ -0,0 +1,231 @@
|
||||
|
||||
# ZClaw 改进方案:从"前端 UI 演示"升级为"真正的 OpenClaw Runtime 控制界面"
|
||||
|
||||
**日期**: 2026-03-12
|
||||
**状态**: 规划中
|
||||
|
||||
---
|
||||
|
||||
## 背景分析
|
||||
|
||||
### 当前状态
|
||||
|
||||
经过对代码库的深入分析,发现以下关键差距:
|
||||
|
||||
#### 1. 分身与 Agent 断层
|
||||
- **现状**: 分身存储在 `zclaw-data.json` (ZCLAW 自定义格式)
|
||||
- **问题**: 不映射到 OpenClaw 原生 `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
|
||||
- **问题**: 没有调用 OpenClaw 的 `config.get/config.patch/config.apply`
|
||||
- **影响**: 用户改了设置而 OpenClaw 运行时行为不变
|
||||
|
||||
**关键代码位置**:
|
||||
- `desktop/src/components/Settings/*.tsx`: 所有设置页面
|
||||
- `desktop/src/store/chatStore.ts`: `currentModel` 只存前端状态
|
||||
- `desktop/src/lib/gateway-client.ts`: 缺少 `config.*` RPC 方法
|
||||
|
||||
#### 3. 右侧面板数据不真实
|
||||
- **现状**: 部分数据是硬编码默认值
|
||||
- **问题**: 没有显示真实 Agent 的运行时状态
|
||||
- **影响**: 用户看到的是演示数据,- **表现**: Bootstrap 文件生成了但可能未被 Agent 运行时使用
|
||||
|
||||
---
|
||||
|
||||
## P0: 最小可行改进 - 让分身真正工作
|
||||
|
||||
### 目标
|
||||
让分身系统真正映射到 OpenClaw 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`
|
||||
|
||||
### 技术挑战
|
||||
- **OpenClaw Agent 进程管理**: 隐式依赖 Gateway 的 Agent 启动机制
|
||||
- **会话隔离**: 需要验证 OpenClaw 是否支持 `agentId` 参数
|
||||
- **配置同步时机**: 何时同步分身配置到 OpenClaw
|
||||
|
||||
- **错误处理**: Agent 启动失败时的回退策略
|
||||
|
||||
### 验收标准
|
||||
- [ ] 创建分身后能在 OpenClaw 的 `agents.list` 中看到
|
||||
- [ ] 切换分身后聊天时传递正确的 `agentId`
|
||||
- [ ] 不同分身的会话完全隔离
|
||||
- [ ] Bootstrap 文件被 Agent 正确加载
|
||||
- [ ] 分身配置修改后 Agent 行为相应变化
|
||||
|
||||
---
|
||||
|
||||
## P1: 设置页 Runtime 化
|
||||
|
||||
### 目标
|
||||
让设置页真正修改 OpenClaw 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')`
|
||||
|
||||
### 技术挑战
|
||||
- **配置路径**: OpenClaw 配置是嵌套结构,需要正确处理路径
|
||||
- **配置验证**: 修改前验证配置有效性
|
||||
- **错误恢复**: 配置修改失败时的回滚
|
||||
- **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
plans/sequential-churning-wreath.md
Normal file
343
plans/sequential-churning-wreath.md
Normal file
@@ -0,0 +1,343 @@
|
||||
# ZClaw 项目深度分析与改进计划
|
||||
|
||||
## 一、现状分析
|
||||
|
||||
### 1.1 核心发现
|
||||
|
||||
基于 `docs/openclaw-deep-dive.md` 的目标与实际代码的对比:
|
||||
|
||||
| 模块 | 目标状态 | 实际状态 | 差距程度 |
|
||||
|------|----------|----------|----------|
|
||||
| **Gateway 连接** | 设备认证 + Challenge 签名 | ✅ 完整实现 | 无差距 |
|
||||
| **分身系统** | 映射到 OpenClaw `agents.list` | ⚠️ 独立存储在 `zclaw-data.json` | **严重** |
|
||||
| **设置页** | OpenClaw Runtime 配置面板 | ⚠️ 大部分是前端本地状态 | **严重** |
|
||||
| **右侧面板** | 真实 Agent 身份与状态 | ⚠️ 混合真实数据与硬编码值 | **中等** |
|
||||
|
||||
### 1.2 关键差距详解
|
||||
|
||||
#### 差距 1:分身与 Agent 断层(最严重)
|
||||
|
||||
```
|
||||
当前架构:
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ ZClaw 分身系统 (zclaw-data.json) │
|
||||
│ clone_1: { name: "程序员", workspaceDir: "...", ... } │
|
||||
│ clone_2: { name: "设计师", workspaceDir: "...", ... } │
|
||||
└────────────────────────┬────────────────────────────────────┘
|
||||
│ ❌ 无同步
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ OpenClaw agents.list (openclaw.json) │
|
||||
│ 只有: [{ id: "main", groupChat: {...} }] │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**后果**:
|
||||
- 所有分身实际共用同一个 `main` Agent
|
||||
- 聊天时不传递 `agentId`,OpenClaw 不知道当前是哪个分身
|
||||
- Bootstrap 文件(IDENTITY.md, SOUL.md 等)生成了但未被运行时使用
|
||||
|
||||
#### 差距 2:设置页是"假状态"
|
||||
|
||||
| 设置页 | 当前实现 | 应该实现 |
|
||||
|--------|----------|----------|
|
||||
| 模型选择 | 存在 `chatStore.currentModel`(前端状态) | 调用 `config.patch` 修改 OpenClaw 配置 |
|
||||
| MCP 服务 | 存 `quickConfig`,部分同步到 Gateway | 管理 `plugins.load.paths` |
|
||||
| 技能目录 | 存 `quickConfig` | 管理 `skills.load.extraDirs` |
|
||||
| IM 频道 | 存 `quickConfig`,只显示状态 | 管理 `channels.*` 配置 |
|
||||
| 工作区 | 存 `quickConfig` | 管理 `agents.defaults.workspace` |
|
||||
| 隐私 | 存 `quickConfig` | 管理 telemetry/优化计划 |
|
||||
|
||||
**缺失的 RPC 方法**:
|
||||
- `config.get` - 读取 OpenClaw 配置
|
||||
- `config.patch` - 修改配置
|
||||
- `config.apply` - 热更新配置
|
||||
|
||||
#### 差距 3:右侧面板数据不真实
|
||||
|
||||
```typescript
|
||||
// 硬编码的默认值(RightPanel.tsx)
|
||||
const credits = 2268; // 完全假数据
|
||||
const defaultUserName = '用户7141'; // 假用户名
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 二、根因分析
|
||||
|
||||
### 2.1 架构层面的偏差
|
||||
|
||||
**文档期望**:
|
||||
> ZClaw 应该是 OpenClaw Runtime 的控制界面
|
||||
|
||||
**实际实现**:
|
||||
> ZClaw 是一个有自己数据模型的前端应用,与 OpenClaw 是松耦合
|
||||
|
||||
### 2.2 数据模型的分裂
|
||||
|
||||
```
|
||||
OpenClaw 数据模型:
|
||||
openclaw.json → agents.list → Agent workspace → Bootstrap files
|
||||
|
||||
ZClaw 数据模型:
|
||||
zclaw-data.json → clones[] → (独立的) workspace 路径
|
||||
```
|
||||
|
||||
两套数据模型没有桥接,导致:
|
||||
1. 分身不能路由到正确的 Agent
|
||||
2. 设置不能影响 OpenClaw 行为
|
||||
3. Bootstrap 文件与运行时脱节
|
||||
|
||||
---
|
||||
|
||||
## 三、头脑风暴:改进方案
|
||||
|
||||
### 3.1 方案 A:完全对齐 OpenClaw(推荐)
|
||||
|
||||
**核心思路**:让 ZClaw 分身直接映射到 OpenClaw Agent
|
||||
|
||||
```
|
||||
改进后架构:
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ ZClaw 分身 = OpenClaw Agent │
|
||||
│ │
|
||||
│ clone_1 ↔ agents.list[0] (id: "programmer") │
|
||||
│ clone_2 ↔ agents.list[1] (id: "designer") │
|
||||
│ │
|
||||
│ 分身 CRUD → 同步修改 agents.list │
|
||||
│ 聊天时 → 传递 agentId 到 Gateway │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**优点**:
|
||||
- 符合 `openclaw-deep-dive.md` 的设计哲学
|
||||
- 分身真正有独立人格、记忆、工具权限
|
||||
- 设置页可以直接操作 OpenClaw 配置
|
||||
|
||||
**缺点**:
|
||||
- 改动较大,需要修改多个模块
|
||||
- 需要处理数据迁移
|
||||
|
||||
### 3.2 方案 B:保持独立,增强桥接
|
||||
|
||||
**核心思路**:保持 `zclaw-data.json`,但增加同步逻辑
|
||||
|
||||
```
|
||||
改进后架构:
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ ZClaw 分身系统 (主) │
|
||||
│ zclaw-data.json → clones[] │
|
||||
│ │ │
|
||||
│ ▼ (单向同步) │
|
||||
│ openclaw.json → agents.list (从分身生成) │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
**优点**:
|
||||
- 改动较小
|
||||
- 保持现有分身管理逻辑
|
||||
|
||||
**缺点**:
|
||||
- 数据冗余,需要维护同步
|
||||
- 不符合 OpenClaw 的设计哲学
|
||||
|
||||
### 3.3 方案 C:混合模式
|
||||
|
||||
**核心思路**:
|
||||
- 简单分身:共用 `main` Agent,通过 Bootstrap 文件区分
|
||||
- 高级分身:映射到独立 OpenClaw Agent
|
||||
|
||||
---
|
||||
|
||||
## 四、推荐实施路线(方案 A)
|
||||
|
||||
### P0:让分身真正工作(最小可行)
|
||||
|
||||
**目标**:创建分身时同步到 OpenClaw `agents.list`,聊天时传递 `agentId`
|
||||
|
||||
**关键修改**:
|
||||
|
||||
1. **`plugins/zclaw-ui/index.ts`**
|
||||
- `createClone` 时调用 OpenClaw 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` - 读取 OpenClaw 配置
|
||||
- `zclaw.config.patch` - 修改配置
|
||||
|
||||
**验收标准**:
|
||||
- [ ] 创建分身后,`openclaw.json` 的 `agents.list` 包含新 Agent
|
||||
- [ ] 切换分身后,聊天请求携带正确的 `agentId`
|
||||
- [ ] 每个分身有独立的对话上下文
|
||||
|
||||
### P1:设置页 Runtime 化
|
||||
|
||||
**目标**:设置修改直接影响 OpenClaw 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 反馈**
|
||||
- 显示配置保存状态
|
||||
- 配置变更后显示"需要重启"提示(如需要)
|
||||
|
||||
**验收标准**:
|
||||
- [ ] 模型选择后,`openclaw.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/openclaw.default.json` | 更新默认 Agent 模板 |
|
||||
|
||||
---
|
||||
|
||||
## 六、风险与缓解
|
||||
|
||||
| 风险 | 缓解措施 |
|
||||
|------|----------|
|
||||
| 数据迁移复杂 | 提供迁移脚本,保留 `zclaw-data.json` 作为备份 |
|
||||
| OpenClaw 版本兼容 | 检测 OpenClaw 版本,低版本降级到兼容模式 |
|
||||
| 破坏现有功能 | 灰度发布,支持回滚 |
|
||||
| 性能下降 | 懒加载 Agent 配置,缓存 RPC 结果 |
|
||||
|
||||
---
|
||||
|
||||
## 七、确认的方案
|
||||
|
||||
**选择:方案 A - 完全对齐 OpenClaw**
|
||||
|
||||
理由:
|
||||
1. 符合 `openclaw-deep-dive.md` 的设计哲学
|
||||
2. 分身真正有独立人格、记忆、工具权限
|
||||
3. 设置页可以直接操作 OpenClaw 配置
|
||||
4. 长期维护成本最低
|
||||
|
||||
---
|
||||
|
||||
## 八、下一步行动(P0 详细任务)
|
||||
|
||||
### Task 1: 修改 `zclaw-ui` 插件 - 分身同步到 agents.list
|
||||
|
||||
**文件**: `plugins/zclaw-ui/index.ts`
|
||||
|
||||
**修改点**:
|
||||
1. `createClone` 方法增加:
|
||||
- 调用 OpenClaw 内部 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` - 读取 OpenClaw 配置
|
||||
- `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 完成标准
|
||||
|
||||
- [ ] 创建分身后,`~/.openclaw/openclaw.json` 的 `agents.list` 包含新 Agent
|
||||
- [ ] 删除分身后,对应 Agent 从 `agents.list` 移除
|
||||
- [ ] 切换分身后,聊天请求携带正确的 `agentId`
|
||||
- [ ] 每个分身有独立的对话上下文(不串聊)
|
||||
- [ ] 现有分身数据成功迁移,无数据丢失
|
||||
- [ ] 单元测试覆盖新增逻辑 ≥ 80%
|
||||
Reference in New Issue
Block a user