Key changes: - Extend existing stores instead of creating new automationStore - Use type adapter pattern instead of new type hierarchy - Add explicit HandParamsForm parameter passing fix - Add category mapping for 7 existing Hands Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
20 KiB
20 KiB
ZCLAW 自动化系统重设计方案
状态: 待审核 作者: Claude 日期: 2026-03-18 版本: 1.0
一、背景与目标
1.1 当前问题
| 问题 | 影响 | 严重程度 |
|---|---|---|
| HandsPanel 使用 gatewayStore 而非 handStore | 状态管理混乱,新 store 未被使用 | 高 |
| HandParamsForm 参数未传递给 triggerHand | 用户填写的参数被丢弃 | 致命 |
| 缺少 WebSocket 实时状态更新 | 无法看到执行进度 | 高 |
| 无执行结果展示 | 用户不知道 Hand 执行结果 | 高 |
| 无执行历史查看 | 无法追溯过去的执行 | 中 |
| Hands 与 Workflows 分离 | 用户体验割裂 | 中 |
1.2 设计目标
基于用户需求确认:
- 专业版功能 - 完整重构 + 工作流集成 + 批量操作 + 调度管理
- 可视化调度器 - 图形化界面选择时间/频率,无需了解 cron 语法
- 结果流展示 - Hand 输出作为对话消息显示在聊天区域
- 批量操作 - 支持批量触发、批量审批、批量配置
- 统一视图 - Hands 和 Workflows 合并到一个"自动化"视图,按任务类型分类
二、架构设计
2.1 整体架构
┌─────────────────────────────────────────────────────────────┐
│ UI Layer │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │AutomationPanel│ │ScheduleEditor│ │ExecutionResultStream│ │
│ └─────────────┘ └─────────────┘ └─────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ State Management │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ automationStore.ts │ │
│ │ - hands: Hand[] │ │
│ │ - workflows: Workflow[] │ │
│ │ - runs: Run[] │ │
│ │ - schedules: Schedule[] │ │
│ │ - approvals: Approval[] │ │
│ │ - selectedIds: Set<string> │ │
│ └───────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Data Layer │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ gateway-client.ts │ │
│ │ - listHands() / listWorkflows() │ │
│ │ - triggerHand() / executeWorkflow() │ │
│ │ - createSchedule() / updateSchedule() │ │
│ │ - WebSocket 事件监听 │ │
│ └───────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
2.2 数据流
用户操作 → AutomationPanel → automationStore → gateway-client → OpenFang API
│
├── 更新 UI 状态
├── WebSocket 事件 → 更新执行状态
└── 执行完成 → 注入结果到 chatStore
2.3 文件结构
desktop/src/
├── components/
│ ├── Automation/ # 新建目录
│ │ ├── AutomationPanel.tsx # 统一入口(组合层)
│ │ ├── AutomationCard.tsx # Hand/Workflow 卡片
│ │ ├── AutomationFilters.tsx # 分类筛选
│ │ ├── ScheduleEditor.tsx # 可视化调度器
│ │ ├── ExecutionResult.tsx # 结果展示组件
│ │ ├── BatchActionBar.tsx # 批量操作栏
│ │ └── ApprovalQueue.tsx # 审批队列
│ └── HandsPanel.tsx # 重构为 AutomationPanel 入口
├── store/
│ ├── handStore.ts # 扩展:添加批量操作方法
│ ├── workflowStore.ts # 保留:工作流状态
│ └── automationCoordinator.ts # 新建:跨 store 协调层
├── types/
│ ├── hands.ts # 扩展:添加 CategoryType
│ └── automation.ts # 新建:类型适配器
└── hooks/
└── useAutomationEvents.ts # 新建:WebSocket 事件 Hook
设计决策: 不创建新的
automationStore.ts,而是扩展现有的handStore.ts和workflowStore.ts, 通过轻量级的automationCoordinator.ts进行跨 store 协调。这遵循了现有代码库的模式。
三、核心组件设计
3.1 AutomationPanel(统一入口)
interface AutomationPanelProps {
initialCategory?: CategoryType;
onSelect?: (item: AutomationItem) => void;
}
interface AutomationPanelState {
items: AutomationItem[]; // Hands + Workflows 合并
categories: CategoryStats; // 各分类统计
filters: FilterState; // 当前筛选条件
selectedIds: string[]; // 批量选择
viewMode: 'grid' | 'list'; // 视图模式
}
type CategoryType = 'all' | 'research' | 'data' | 'automation' | 'communication';
UI 布局:
┌─────────────────────────────────────────────────────────────┐
│ 自动化 [新建] [调度] │
├─────────────────────────────────────────────────────────────┤
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ 全部 │ │ 研究 │ │ 数据 │ │ 自动化 │ ... │
│ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │
├─────────────────────────────────────────────────────────────┤
│ [AutomationCard] [AutomationCard] [AutomationCard] │
│ [AutomationCard] [AutomationCard] [AutomationCard] │
└─────────────────────────────────────────────────────────────┘
3.2 AutomationCard(统一卡片)
interface AutomationCardProps {
item: AutomationItem;
status: ExecutionStatus;
result?: ExecutionResult;
onSelect: (selected: boolean) => void;
onExecute: (params?: Record<string, unknown>) => void;
onSchedule: () => void;
}
interface AutomationItem {
id: string;
name: string;
description: string;
type: 'hand' | 'workflow';
category: CategoryType;
status: ItemStatus;
parameters: Parameter[];
lastRun?: RunInfo;
schedule?: ScheduleInfo;
requiresApproval: boolean;
}
3.3 ScheduleEditor(可视化调度器)
interface ScheduleEditorProps {
schedule?: ScheduleInfo;
onSave: (schedule: ScheduleInfo) => void;
onCancel: () => void;
}
interface ScheduleInfo {
enabled: boolean;
frequency: 'once' | 'daily' | 'weekly' | 'monthly' | 'custom';
time: { hour: number; minute: number };
daysOfWeek?: number[]; // 0-6 for weekly
dayOfMonth?: number; // 1-31 for monthly
customCron?: string; // 高级模式可选
timezone: string;
endDate?: Date;
}
UI 设计:
┌─────────────────────────────────────────────────────────────┐
│ 调度设置 [保存] │
├─────────────────────────────────────────────────────────────┤
│ 频率: ○ 一次 ● 每天 ○ 每周 ○ 每月 ○ 自定义 │
│ 时间: [09] : [00] 时区: [Asia/Shanghai ▼] │
│ ┌─ 每周重复 (选中"每周"时显示) ───────────────────────┐ │
│ │ [一] [二] [三] [四] [五] [六] [日] │ │
│ └───────────────────────────────────────────────────────┘ │
│ 结束日期: [无结束日期 ▼] 或 选择日期: [____-__-__] │
│ 预览: "每天 09:00 (Asia/Shanghai),无结束日期" │
└─────────────────────────────────────────────────────────────┘
四、结果流设计
4.1 消息类型扩展
interface ChatMessage {
id: string;
role: 'user' | 'assistant' | 'system' | 'hand' | 'workflow'; // 新增
content: string;
timestamp: number;
executionInfo?: {
type: 'hand' | 'workflow';
name: string;
runId: string;
status: 'running' | 'completed' | 'failed' | 'needs_approval';
duration?: number;
output?: unknown;
error?: string;
};
}
4.2 结果消息渲染
┌─────────────────────────────────────────────────────────────┐
│ 🔍 Researcher │
│ ─────────────────────────────────────────────────────── │
│ 状态: ✅ 完成 耗时: 2m 34s │
│ │
│ ## 研究结果摘要 │
│ ... │
│ │
│ [查看完整报告] [下载 PDF] [重新执行] │
└─────────────────────────────────────────────────────────────┘
五、批量操作设计
5.1 批量操作接口
interface BatchOperations {
selectedIds: Set<string>;
executeSelected: (params?: Record<string, unknown>) => Promise<void>;
approveSelected: () => Promise<void>;
rejectSelected: (reason: string) => Promise<void>;
updateConfigSelected: (config: Partial<Config>) => Promise<void>;
scheduleSelected: (schedule: ScheduleInfo) => Promise<void>;
}
5.2 批量操作栏 UI
┌─────────────────────────────────────────────────────────────┐
│ 已选择 3 项 [取消选择] │
├─────────────────────────────────────────────────────────────┤
│ [▶ 执行选中] [✓ 批量审批] [✗ 批量拒绝] [⏰ 批量调度] │
└─────────────────────────────────────────────────────────────┘
5.3 批量审批队列
┌─────────────────────────────────────────────────────────────┐
│ 审批队列 (5 待处理) [全部批准] [全部拒绝] │
├─────────────────────────────────────────────────────────────┤
│ ☐ Browser - 访问 github.com/search │
│ 请求者: Agent-1 | 请求时间: 2分钟前 │
│ ☐ Lead - 搜索 LinkedIn 销售线索 │
│ 请求者: Agent-2 | 请求时间: 5分钟前 │
└─────────────────────────────────────────────────────────────┘
六、实时状态与错误处理
6.1 状态流转
┌─────────┐ trigger ┌─────────┐ execute ┌───────────┐
│ idle │ ──────────► │ pending │ ──────────► │ running │
└─────────┘ └─────────┘ └───────────┘
▲ │
│ ┌──────────────┐ │
└──────────────│ completed │◄───────────────────┘
└──────────────┘
│
┌──────────────┐
│ failed │
└──────────────┘
│
┌──────────────┐
│needs_approval│ ──approve──► running
└──────────────┘
6.2 WebSocket 事件处理
interface AutomationWebSocketHandlers {
onHandStatus: (data: { name: string; status: string; runId?: string }) => void;
onHandResult: (data: { name: string; runId: string; result: unknown }) => void;
onWorkflowStep: (data: { id: string; step: number; status: string }) => void;
onWorkflowComplete: (data: { id: string; result: unknown }) => void;
onApprovalRequest: (data: ApprovalRequest) => void;
onApprovalResolved: (data: { id: string; approved: boolean }) => void;
}
6.3 错误处理
type ErrorCode =
| 'CONNECTION_LOST'
| 'HAND_UNAVAILABLE'
| 'PARAM_INVALID'
| 'PERMISSION_DENIED'
| 'RATE_LIMITED'
| 'TIMEOUT'
| 'APPROVAL_REQUIRED'
| 'APPROVAL_REJECTED'
| 'EXECUTION_FAILED';
interface AutomationError {
code: ErrorCode;
message: string;
recoverable: boolean;
suggestedAction?: string;
}
6.4 离线队列
interface ConnectionState {
status: 'connected' | 'disconnected' | 'reconnecting';
pendingActions: PendingAction[];
}
// 离线时缓存操作,重连后批量执行
七、实现计划
7.1 分阶段实施
| 阶段 | 任务 | 交付物 | 预计时间 |
|---|---|---|---|
| Phase 1 | 基础修复 | 可用的 Hands 系统 | 1-2 天 |
| Phase 2 | UI 重构 | 统一自动化面板 | 2-3 天 |
| Phase 3 | 高级功能 | 调度与批量操作 | 2-3 天 |
| Phase 4 | 工作流集成 | 完整自动化系统 | 2-3 天 |
7.2 文件变更清单
新建文件:
desktop/src/components/Automation/目录(7 个组件)desktop/src/store/automationStore.tsdesktop/src/types/automation.tsdesktop/src/hooks/useAutomationEvents.tstests/desktop/automation/测试目录
修改文件:
desktop/src/components/HandsPanel.tsx- 重构为入口desktop/src/store/handStore.ts- 合并到 automationStoredesktop/src/lib/gateway-client.ts- 增强 WebSocket 事件desktop/src/store/chatStore.ts- 支持 hand/workflow 消息类型desktop/src/components/ChatArea.tsx- 渲染结果流消息desktop/src/components/Sidebar.tsx- 导航更新
八、测试策略
8.1 测试覆盖
| 测试类型 | 覆盖范围 | 工具 |
|---|---|---|
| 单元测试 | Store 逻辑、工具函数、组件 | Vitest |
| 集成测试 | API 调用、WebSocket 事件 | Vitest + MSW |
| E2E 测试 | 完整用户流程 | Playwright |
8.2 关键测试用例
- 参数从表单正确传递到 API
- WebSocket 事件正确更新 UI 状态
- 批量选择和操作功能
- 调度器生成正确的 cron 表达式
- 结果流消息正确注入聊天
- 离线队列在重连后执行
- 错误状态正确显示和恢复
九、验收标准
| 功能 | 验收标准 |
|---|---|
| Hand 执行 | 填写参数 → 执行 → 看到实时进度 → 结果显示在聊天流 |
| 批量操作 | 选择 3 个 Hand → 批量执行 → 全部成功 |
| 调度 | 设置"每天 9:00" → 保存 → 在调度列表看到正确预览 |
| 审批 | Hand 需要审批 → 弹出审批请求 → 批准 → 继续执行 |
| 离线 | 断网 → 触发 Hand → 重连 → 自动执行 |
十、风险评估
| 风险 | 可能性 | 影响 | 缓解措施 |
|---|---|---|---|
| 后端 API 不完整 | 中 | 高 | 使用 fallback 数据,明确标注未实现 |
| WebSocket 不稳定 | 低 | 高 | 心跳机制 + 自动重连 + 离线队列 |
| 迁移影响现有功能 | 中 | 中 | 分阶段迁移,保留旧组件作为 fallback |
| 调度器复杂度 | 低 | 中 | 先实现基础频率,高级功能后续迭代 |
附录 A:API 端点参考
| 端点 | 方法 | 用途 |
|---|---|---|
/api/hands |
GET | 列出所有 Hands |
/api/hands/{name} |
GET | 获取 Hand 详情 |
/api/hands/{name}/activate |
POST | 触发 Hand 执行 |
/api/hands/{name}/runs/{runId} |
GET | 获取执行状态 |
/api/hands/{name}/runs/{runId}/approve |
POST | 批准执行 |
/api/hands/{name}/runs/{runId}/cancel |
POST | 取消执行 |
/api/hands/{name}/runs |
GET | 列出执行历史 |
/api/workflows |
GET/POST | 工作流管理 |
/api/triggers |
GET/POST/PUT/DELETE | 触发器管理 |
附录 B:WebSocket 事件参考
| 事件类型 | 字段 | 说明 |
|---|---|---|
hand |
hand_name, hand_status, hand_result | Hand 状态变更 |
workflow |
workflow_id, step, status | Workflow 步骤变更 |
approval |
approval_id, type, status | 审批请求/响应 |