/** * ComfyUI V2 API 服务层 * 基于新的后端 V2 API 的现代化前端服务接口 */ import { invoke } from '@tauri-apps/api/core'; import { listen, UnlistenFn } from '@tauri-apps/api/event'; // ==================== 基础类型定义 ==================== export interface ComfyUIV2Config { base_url: string; timeout?: number; retry_attempts?: number; enable_cache?: boolean; max_concurrency?: number; websocket_url?: string; } export interface ConnectionStatus { connected: boolean; last_connected_at?: string; last_disconnected_at?: string; reconnect_attempts: number; total_connections: number; error_message?: string; } export interface SystemInfo { version: string; python_version: string; platform: string; gpu_info?: string; memory_info?: string; disk_info?: string; } export interface QueueStatus { running_count: number; pending_count: number; history_count: number; } // ==================== 工作流类型 ==================== export interface WorkflowV2 { id: string; name: string; description?: string; category?: string; workflow_data: any; input_schema?: any; output_schema?: any; created_at: string; updated_at: string; version: number; is_active: boolean; tags: string[]; } export interface CreateWorkflowRequest { name: string; description?: string; category?: string; workflow_data: any; input_schema?: any; output_schema?: any; tags?: string[]; } export interface UpdateWorkflowRequest { name?: string; description?: string; category?: string; workflow_data?: any; input_schema?: any; output_schema?: any; tags?: string[]; is_active?: boolean; } // ==================== 模板类型 ==================== export interface TemplateV2 { id: string; name: string; description?: string; category?: string; workflow_id: string; parameter_definitions: any; default_values?: any; created_at: string; updated_at: string; version: number; is_active: boolean; tags: string[]; } export interface CreateTemplateRequest { name: string; description?: string; category?: string; workflow_id: string; parameter_definitions: any; default_values?: any; tags?: string[]; } // ==================== 执行类型 ==================== export interface ExecutionV2 { id: string; workflow_id?: string; template_id?: string; prompt_id: string; parameters: any; status: 'pending' | 'running' | 'completed' | 'failed' | 'cancelled'; progress?: number; results?: any; output_urls?: string[]; error_message?: string; execution_time?: number; created_at: string; updated_at: string; } export interface ExecuteWorkflowRequest { workflow_id: string; parameters?: any; } export interface ExecuteTemplateRequest { template_id: string; parameters: any; } // ==================== 实时事件类型 ==================== export interface RealtimeEvent { event_type: string; data: any; timestamp: string; } export interface ExecutionProgressEvent { prompt_id: string; execution_id?: string; node_id: string; progress: number; max_progress: number; percentage: number; timestamp: string; } export interface ExecutionCompletedEvent { prompt_id: string; execution_id?: string; outputs: Record; output_urls: string[]; execution_time: number; timestamp: string; } // ==================== ComfyUI V2 服务类 ==================== export class ComfyUIV2Service { private static eventListeners: Map = new Map(); // ==================== 连接管理 ==================== /** * 连接到 ComfyUI 服务 */ static async connect(config: ComfyUIV2Config): Promise { try { const result = await invoke<{connected: boolean, status: string, base_url: string}>('comfyui_v2_connect', { config }); return result.connected ? '连接成功' : '连接失败'; } catch (error) { console.error('Failed to connect to ComfyUI:', error); throw new Error(`连接 ComfyUI 失败: ${error}`); } } /** * 断开 ComfyUI 连接 */ static async disconnect(): Promise { try { return await invoke('comfyui_v2_disconnect'); } catch (error) { console.error('Failed to disconnect from ComfyUI:', error); throw new Error(`断开 ComfyUI 连接失败: ${error}`); } } /** * 获取连接状态 */ static async getConnectionStatus(): Promise { try { return await invoke('comfyui_v2_get_connection_status'); } catch (error) { console.error('Failed to get connection status:', error); throw new Error(`获取连接状态失败: ${error}`); } } /** * 健康检查 */ static async healthCheck(): Promise { try { const result = await invoke('comfyui_v2_health_check'); return result === 'healthy'; } catch (error) { console.error('Health check failed:', error); return false; } } /** * 获取系统信息 */ static async getSystemInfo(): Promise { try { return await invoke('comfyui_v2_get_system_info'); } catch (error) { console.error('Failed to get system info:', error); throw new Error(`获取系统信息失败: ${error}`); } } /** * 获取队列状态 */ static async getQueueStatus(): Promise { try { return await invoke('comfyui_v2_get_queue_status'); } catch (error) { console.error('Failed to get queue status:', error); throw new Error(`获取队列状态失败: ${error}`); } } // ==================== 配置管理 ==================== /** * 获取配置 */ static async getConfig(): Promise { try { return await invoke('comfyui_v2_get_config'); } catch (error) { console.error('Failed to get config:', error); throw new Error(`获取配置失败: ${error}`); } } /** * 更新配置 */ static async updateConfig(config: Partial): Promise { try { // 获取当前配置,然后合并新配置 let currentConfig: ComfyUIV2Config; try { currentConfig = await this.getConfig(); } catch { // 如果获取失败,使用默认配置 currentConfig = { base_url: 'http://192.168.0.193:8188', timeout: 30000, retry_attempts: 3, enable_cache: true, max_concurrency: 4, websocket_url: 'ws://192.168.0.193:8188/ws', }; } // 合并配置 const fullConfig: ComfyUIV2Config = { ...currentConfig, ...config, }; return await invoke('comfyui_v2_update_config', { configRequest: fullConfig }); } catch (error) { console.error('Failed to update config:', error); throw new Error(`更新配置失败: ${error}`); } } /** * 验证配置 */ static async validateConfig(config: ComfyUIV2Config): Promise { try { const result = await invoke('comfyui_v2_validate_config', { configRequest: config }); return result === 'valid'; } catch (error) { console.error('Failed to validate config:', error); return false; } } // ==================== 工作流管理 ==================== /** * 创建工作流 */ static async createWorkflow(request: CreateWorkflowRequest): Promise { try { return await invoke('comfyui_v2_create_workflow', { request }); } catch (error) { console.error('Failed to create workflow:', error); throw new Error(`创建工作流失败: ${error}`); } } /** * 获取工作流列表 */ static async listWorkflows(category?: string, tags?: string[]): Promise { try { return await invoke('comfyui_v2_list_workflows', { category, tags }); } catch (error) { console.error('Failed to list workflows:', error); throw new Error(`获取工作流列表失败: ${error}`); } } /** * 获取单个工作流 */ static async getWorkflow(id: string): Promise { try { return await invoke('comfyui_v2_get_workflow', { id }); } catch (error) { console.error('Failed to get workflow:', error); throw new Error(`获取工作流失败: ${error}`); } } /** * 更新工作流 */ static async updateWorkflow(id: string, request: UpdateWorkflowRequest): Promise { try { return await invoke('comfyui_v2_update_workflow', { id, request }); } catch (error) { console.error('Failed to update workflow:', error); throw new Error(`更新工作流失败: ${error}`); } } /** * 删除工作流 */ static async deleteWorkflow(id: string): Promise { try { return await invoke('comfyui_v2_delete_workflow', { id }); } catch (error) { console.error('Failed to delete workflow:', error); throw new Error(`删除工作流失败: ${error}`); } } /** * 搜索工作流 */ static async searchWorkflows(query: string, category?: string): Promise { try { return await invoke('comfyui_v2_search_workflows', { query, category }); } catch (error) { console.error('Failed to search workflows:', error); throw new Error(`搜索工作流失败: ${error}`); } } // ==================== 模板管理 ==================== /** * 创建模板 */ static async createTemplate(request: CreateTemplateRequest): Promise { try { return await invoke('comfyui_v2_create_template', { request }); } catch (error) { console.error('Failed to create template:', error); throw new Error(`创建模板失败: ${error}`); } } /** * 获取模板列表 */ static async listTemplates(category?: string, tags?: string[]): Promise { try { return await invoke('comfyui_v2_list_templates', { category, tags }); } catch (error) { console.error('Failed to list templates:', error); throw new Error(`获取模板列表失败: ${error}`); } } /** * 获取单个模板 */ static async getTemplate(id: string): Promise { try { return await invoke('comfyui_v2_get_template', { id }); } catch (error) { console.error('Failed to get template:', error); throw new Error(`获取模板失败: ${error}`); } } /** * 删除模板 */ static async deleteTemplate(id: string): Promise { try { return await invoke('comfyui_v2_delete_template', { id }); } catch (error) { console.error('Failed to delete template:', error); throw new Error(`删除模板失败: ${error}`); } } /** * 预览模板实例 */ static async previewTemplateInstance(templateId: string, parameters: any): Promise { try { return await invoke('comfyui_v2_preview_template_instance', { templateId, parameters }); } catch (error) { console.error('Failed to preview template instance:', error); throw new Error(`预览模板实例失败: ${error}`); } } /** * 验证模板参数 */ static async validateTemplateParameters(templateId: string, parameters: any): Promise { try { const result = await invoke('comfyui_v2_validate_template_parameters', { templateId, parameters }); return result === 'valid'; } catch (error) { console.error('Failed to validate template parameters:', error); return false; } } // ==================== 执行管理 ==================== /** * 执行工作流 */ static async executeWorkflow(request: ExecuteWorkflowRequest): Promise { try { return await invoke('comfyui_v2_execute_workflow', { request }); } catch (error) { console.error('Failed to execute workflow:', error); throw new Error(`执行工作流失败: ${error}`); } } /** * 执行模板 */ static async executeTemplate(request: ExecuteTemplateRequest): Promise { try { return await invoke('comfyui_v2_execute_template', { request }); } catch (error) { console.error('Failed to execute template:', error); throw new Error(`执行模板失败: ${error}`); } } /** * 取消执行 */ static async cancelExecution(executionId: string): Promise { try { return await invoke('comfyui_v2_cancel_execution', { executionId }); } catch (error) { console.error('Failed to cancel execution:', error); throw new Error(`取消执行失败: ${error}`); } } /** * 获取执行状态 */ static async getExecutionStatus(executionId: string): Promise { try { return await invoke('comfyui_v2_get_execution_status', { executionId }); } catch (error) { console.error('Failed to get execution status:', error); throw new Error(`获取执行状态失败: ${error}`); } } /** * 获取执行历史 */ static async getExecutionHistory(limit?: number, status?: string): Promise { try { return await invoke('comfyui_v2_get_execution_history', { limit, status }); } catch (error) { console.error('Failed to get execution history:', error); throw new Error(`获取执行历史失败: ${error}`); } } // ==================== 实时通信 ==================== /** * 启动实时监控 */ static async startRealtimeMonitor(config?: any): Promise { try { return await invoke('comfyui_v2_start_realtime_monitor_enhanced', { config }); } catch (error) { console.error('Failed to start realtime monitor:', error); throw new Error(`启动实时监控失败: ${error}`); } } /** * 停止实时监控 */ static async stopRealtimeMonitor(): Promise { try { return await invoke('comfyui_v2_stop_realtime_monitor_enhanced'); } catch (error) { console.error('Failed to stop realtime monitor:', error); throw new Error(`停止实时监控失败: ${error}`); } } /** * 订阅实时事件 */ static async subscribeRealtimeEvents( eventTypes?: string[], callback?: (event: RealtimeEvent) => void ): Promise { try { // 订阅后端事件 const subscriptionId = await invoke('comfyui_v2_subscribe_realtime_events_enhanced', { eventTypes }); // 如果提供了回调,设置事件监听 if (callback) { // 监听连接状态变化 const connectionUnlisten = await listen('comfyui://connection-changed', (event) => { callback({ event_type: 'connection_changed', data: event.payload, timestamp: new Date().toISOString(), }); }); // 监听执行进度 const progressUnlisten = await listen('comfyui://execution-progress', (event) => { callback({ event_type: 'execution_progress', data: event.payload, timestamp: new Date().toISOString(), }); }); // 监听执行完成 const completedUnlisten = await listen('comfyui://execution-completed', (event) => { callback({ event_type: 'execution_completed', data: event.payload, timestamp: new Date().toISOString(), }); }); // 监听执行失败 const failedUnlisten = await listen('comfyui://execution-failed', (event) => { callback({ event_type: 'execution_failed', data: event.payload, timestamp: new Date().toISOString(), }); }); // 保存监听器以便后续清理 this.eventListeners.set(`${subscriptionId}_connection`, connectionUnlisten); this.eventListeners.set(`${subscriptionId}_progress`, progressUnlisten); this.eventListeners.set(`${subscriptionId}_completed`, completedUnlisten); this.eventListeners.set(`${subscriptionId}_failed`, failedUnlisten); } return subscriptionId; } catch (error) { console.error('Failed to subscribe to realtime events:', error); throw new Error(`订阅实时事件失败: ${error}`); } } /** * 取消订阅实时事件 */ static async unsubscribeRealtimeEvents(subscriptionId: string): Promise { try { // 清理事件监听器 const listenersToRemove = Array.from(this.eventListeners.keys()) .filter(key => key.startsWith(subscriptionId)); for (const key of listenersToRemove) { const unlisten = this.eventListeners.get(key); if (unlisten) { unlisten(); this.eventListeners.delete(key); } } // 取消后端订阅 return await invoke('comfyui_v2_unsubscribe_realtime_events', { subscriptionId }); } catch (error) { console.error('Failed to unsubscribe from realtime events:', error); throw new Error(`取消订阅实时事件失败: ${error}`); } } /** * 注册执行映射 */ static async registerExecutionMapping(promptId: string, executionId: string): Promise { try { return await invoke('comfyui_v2_register_execution_mapping', { promptId, executionId }); } catch (error) { console.error('Failed to register execution mapping:', error); throw new Error(`注册执行映射失败: ${error}`); } } // ==================== 批量操作 ==================== /** * 批量执行工作流 */ static async batchExecuteWorkflows(requests: ExecuteWorkflowRequest[]): Promise { try { return await invoke('comfyui_v2_batch_execute_workflows', { requests }); } catch (error) { console.error('Failed to batch execute workflows:', error); throw new Error(`批量执行工作流失败: ${error}`); } } /** * 批量执行模板 */ static async batchExecuteTemplates(requests: ExecuteTemplateRequest[]): Promise { try { return await invoke('comfyui_v2_batch_execute_templates', { requests }); } catch (error) { console.error('Failed to batch execute templates:', error); throw new Error(`批量执行模板失败: ${error}`); } } /** * 批量取消执行 */ static async batchCancelExecutions(executionIds: string[]): Promise { try { return await invoke('comfyui_v2_batch_cancel_executions', { executionIds }); } catch (error) { console.error('Failed to batch cancel executions:', error); throw new Error(`批量取消执行失败: ${error}`); } } // ==================== 工具方法 ==================== /** * 清理所有事件监听器 */ static cleanup(): void { for (const [key, unlisten] of this.eventListeners) { unlisten(); } this.eventListeners.clear(); } }