UNPKG

vibe-coder-mcp

Version:

Production-ready MCP server with complete agent integration, multi-transport support, and comprehensive development automation tools for AI-assisted workflows.

796 lines (795 loc) 37.8 kB
import { EventEmitter } from 'events'; import { promises as fs } from 'fs'; import { join } from 'path'; import crypto from 'crypto'; import { ErrorFactory, createErrorContext } from '../utils/enhanced-errors.js'; import { createSuccess, createFailure } from './unified-lifecycle-manager.js'; import { getVibeTaskManagerOutputDir } from '../utils/config-loader.js'; import logger from '../../../logger.js'; export function createOrchestrationId(id) { if (!id || id.trim().length === 0) { throw new Error('Orchestration ID cannot be empty'); } return id; } export function createWorkflowId(id) { if (!id || id.trim().length === 0) { throw new Error('Workflow ID cannot be empty'); } return id; } export function createAgentId(id) { if (!id || id.trim().length === 0) { throw new Error('Agent ID cannot be empty'); } return id; } export function createExecutionId(id) { if (!id || id.trim().length === 0) { throw new Error('Execution ID cannot be empty'); } return id; } export function createScheduleId(id) { if (!id || id.trim().length === 0) { throw new Error('Schedule ID cannot be empty'); } return id; } export class UnifiedOrchestrationEngine extends EventEmitter { static instance = null; config; dataDirectory; initialized = false; agents = new Map(); workflows = new Map(); assignments = new Map(); executions = new Map(); schedule = new Map(); orchestrationCount = 0; workflowCount = 0; taskExecutionCount = 0; totalExecutionTime = 0; errorCount = 0; heartbeatTimer = null; schedulerTimer = null; watchdogTimer = null; cleanupTimer = null; metricsTimer = null; constructor(config) { super(); this.config = config; this.dataDirectory = getVibeTaskManagerOutputDir(); logger.info('Unified Orchestration Engine initialized'); } static getInstance(config) { if (!UnifiedOrchestrationEngine.instance) { if (!config) { throw new Error('Configuration required for first initialization'); } UnifiedOrchestrationEngine.instance = new UnifiedOrchestrationEngine(config); } return UnifiedOrchestrationEngine.instance; } static resetInstance() { if (UnifiedOrchestrationEngine.instance) { UnifiedOrchestrationEngine.instance.dispose(); UnifiedOrchestrationEngine.instance = null; } } async initialize() { if (this.initialized) { return createSuccess(undefined); } try { await this.createDataDirectories(); await this.loadPersistedState(); this.startBackgroundProcesses(); this.initialized = true; this.emit('initialized'); logger.info('Orchestration engine initialized successfully'); return createSuccess(undefined); } catch (error) { return createFailure(ErrorFactory.createError('system', `Failed to initialize orchestration engine: ${error instanceof Error ? error.message : 'Unknown error'}`, createErrorContext('UnifiedOrchestrationEngine', 'initialize').build(), { cause: error instanceof Error ? error : undefined })); } } async createDataDirectories() { const directories = [ join(this.dataDirectory, 'orchestration'), join(this.dataDirectory, 'orchestration', 'agents'), join(this.dataDirectory, 'orchestration', 'workflows'), join(this.dataDirectory, 'orchestration', 'executions'), join(this.dataDirectory, 'orchestration', 'schedules'), join(this.dataDirectory, 'orchestration', 'logs') ]; for (const dir of directories) { await fs.mkdir(dir, { recursive: true }); } } async loadPersistedState() { if (!this.config.workflowManagement.persistState) { return; } try { const workflowsPath = join(this.dataDirectory, 'orchestration', 'workflows.json'); if (await this.fileExists(workflowsPath)) { const workflowsData = await fs.readFile(workflowsPath, 'utf-8'); const workflows = JSON.parse(workflowsData); for (const workflow of workflows) { this.workflows.set(workflow.id, workflow); } } const agentsPath = join(this.dataDirectory, 'orchestration', 'agents.json'); if (await this.fileExists(agentsPath)) { const agentsData = await fs.readFile(agentsPath, 'utf-8'); const agents = JSON.parse(agentsData); for (const agent of agents) { this.agents.set(agent.id, agent); } } logger.info('Persisted orchestration state loaded successfully'); } catch (error) { logger.warn('Failed to load persisted state, starting fresh:', error); } } startBackgroundProcesses() { if (this.config.agentManagement.heartbeatTimeout > 0) { this.heartbeatTimer = setInterval(() => { this.checkAgentHeartbeats().catch(error => { logger.error('Agent heartbeat check failed:', error); }); }, this.config.heartbeatInterval); } if (this.config.taskScheduling.schedulingInterval > 0) { this.schedulerTimer = setInterval(() => { this.processScheduledTasks().catch(error => { logger.error('Task scheduling failed:', error); }); }, this.config.taskScheduling.schedulingInterval); } if (this.config.executionMonitoring.watchdogEnabled) { this.watchdogTimer = setInterval(() => { this.runExecutionWatchdog().catch(error => { logger.error('Execution watchdog failed:', error); }); }, this.config.executionMonitoring.watchdogInterval); } if (this.config.workflowManagement.autoCleanup) { this.cleanupTimer = setInterval(() => { this.cleanupCompletedWorkflows().catch(error => { logger.error('Workflow cleanup failed:', error); }); }, this.config.workflowManagement.cleanupInterval); } this.metricsTimer = setInterval(() => { this.collectMetrics(); }, 60 * 1000); logger.info('Orchestration background processes started'); } async registerAgent(agentInfo) { try { const agentId = createAgentId(crypto.randomUUID()); const agent = { id: agentId, ...agentInfo, metadata: { version: '1.0.0', heartbeatInterval: this.config.heartbeatInterval, lastHeartbeat: new Date(), registeredAt: new Date() } }; this.agents.set(agentId, agent); this.emit('agentRegistered', agent); logger.info(`Agent registered: ${agentId} (${agent.name})`); return createSuccess(agentId); } catch (error) { return createFailure(ErrorFactory.createError('system', `Failed to register agent: ${error instanceof Error ? error.message : 'Unknown error'}`, createErrorContext('UnifiedOrchestrationEngine', 'registerAgent').build(), { cause: error instanceof Error ? error : undefined })); } } async updateAgentStatus(agentId, status) { try { const agent = this.agents.get(agentId); if (!agent) { return createFailure(ErrorFactory.createError('validation', `Agent not found: ${agentId}`, createErrorContext('UnifiedOrchestrationEngine', 'updateAgentStatus').build())); } const oldStatus = agent.status; agent.status = status; agent.metadata.lastHeartbeat = new Date(); this.emit('agentStatusChanged', { agentId, oldStatus, newStatus: status }); logger.debug(`Agent status updated: ${agentId} ${oldStatus} -> ${status}`); return createSuccess(undefined); } catch (error) { return createFailure(ErrorFactory.createError('system', `Failed to update agent status: ${error instanceof Error ? error.message : 'Unknown error'}`, createErrorContext('UnifiedOrchestrationEngine', 'updateAgentStatus').build(), { cause: error instanceof Error ? error : undefined })); } } async getAvailableAgents(requiredCapabilities) { try { const availableAgents = Array.from(this.agents.values()).filter(agent => { if (agent.status !== 'online' && agent.status !== 'idle') { return false; } if (agent.currentTasks.length >= agent.maxConcurrentTasks) { return false; } if (requiredCapabilities && requiredCapabilities.length > 0) { const hasRequiredCapabilities = requiredCapabilities.every(cap => agent.capabilities.includes(cap)); if (!hasRequiredCapabilities) { return false; } } return true; }); availableAgents.sort((a, b) => { const loadDiff = a.currentLoad - b.currentLoad; if (Math.abs(loadDiff) > 0.1) { return loadDiff; } return b.performance.successRate - a.performance.successRate; }); return createSuccess(availableAgents); } catch (error) { return createFailure(ErrorFactory.createError('system', `Failed to get available agents: ${error instanceof Error ? error.message : 'Unknown error'}`, createErrorContext('UnifiedOrchestrationEngine', 'getAvailableAgents').build(), { cause: error instanceof Error ? error : undefined })); } } async createWorkflow(projectId, sessionId, tasks, priority = 'medium') { try { const workflowId = createWorkflowId(crypto.randomUUID()); const workflow = { id: workflowId, phase: 'initialization', status: 'pending', projectId, sessionId, tasks, assignedAgents: [], startTime: new Date(), progress: { totalTasks: tasks.length, completedTasks: 0, failedTasks: 0, percentage: 0 }, metadata: { initiator: sessionId, priority, estimatedDuration: tasks.length * 300000, } }; this.workflows.set(workflowId, workflow); this.workflowCount++; this.emit('workflowCreated', workflow); logger.info(`Workflow created: ${workflowId} with ${tasks.length} tasks`); return createSuccess(workflowId); } catch (error) { return createFailure(ErrorFactory.createError('system', `Failed to create workflow: ${error instanceof Error ? error.message : 'Unknown error'}`, createErrorContext('UnifiedOrchestrationEngine', 'createWorkflow').build(), { cause: error instanceof Error ? error : undefined })); } } async updateWorkflowPhase(workflowId, phase) { try { const workflow = this.workflows.get(workflowId); if (!workflow) { return createFailure(ErrorFactory.createError('validation', `Workflow not found: ${workflowId}`, createErrorContext('UnifiedOrchestrationEngine', 'updateWorkflowPhase').build())); } const oldPhase = workflow.phase; workflow.phase = phase; if (phase === 'execution') { workflow.status = 'running'; } else if (phase === 'completion') { workflow.status = 'completed'; workflow.endTime = new Date(); workflow.metadata.actualDuration = workflow.endTime.getTime() - workflow.startTime.getTime(); } else if (phase === 'error_recovery') { workflow.status = 'error'; } this.emit('workflowPhaseChanged', { workflowId, oldPhase, newPhase: phase }); logger.debug(`Workflow phase updated: ${workflowId} ${oldPhase} -> ${phase}`); return createSuccess(undefined); } catch (error) { return createFailure(ErrorFactory.createError('system', `Failed to update workflow phase: ${error instanceof Error ? error.message : 'Unknown error'}`, createErrorContext('UnifiedOrchestrationEngine', 'updateWorkflowPhase').build(), { cause: error instanceof Error ? error : undefined })); } } async scheduleTask(task, workflowId, constraints) { try { const scheduleId = createScheduleId(crypto.randomUUID()); const scheduleEntry = { id: scheduleId, taskId: task.id, workflowId, scheduledAt: new Date(), priority: task.priority, dependencies: task.dependencies, constraints: { requiredCapabilities: ['task_execution'], preferredAgents: [], excludedAgents: [], maxRetries: this.config.recovery.maxRetries, timeoutMs: this.config.defaultTimeout, ...constraints }, status: 'pending', createdAt: new Date(), updatedAt: new Date() }; this.schedule.set(scheduleId, scheduleEntry); this.emit('taskScheduled', scheduleEntry); logger.debug(`Task scheduled: ${task.id} in workflow ${workflowId}`); return createSuccess(scheduleId); } catch (error) { return createFailure(ErrorFactory.createError('system', `Failed to schedule task: ${error instanceof Error ? error.message : 'Unknown error'}`, createErrorContext('UnifiedOrchestrationEngine', 'scheduleTask').build(), { cause: error instanceof Error ? error : undefined })); } } async assignTask(scheduleId, agentId) { try { const scheduleEntry = this.schedule.get(scheduleId); if (!scheduleEntry) { return createFailure(ErrorFactory.createError('validation', `Schedule entry not found: ${scheduleId}`, createErrorContext('UnifiedOrchestrationEngine', 'assignTask').build())); } const agent = this.agents.get(agentId); if (!agent) { return createFailure(ErrorFactory.createError('validation', `Agent not found: ${agentId}`, createErrorContext('UnifiedOrchestrationEngine', 'assignTask').build())); } if (agent.currentTasks.length >= agent.maxConcurrentTasks) { return createFailure(ErrorFactory.createError('resource', `Agent at capacity: ${agentId}`, createErrorContext('UnifiedOrchestrationEngine', 'assignTask').build())); } const assignment = { id: crypto.randomUUID(), taskId: scheduleEntry.taskId, agentId, workflowId: scheduleEntry.workflowId, assignedAt: new Date(), status: 'scheduled', priority: scheduleEntry.priority, estimatedDuration: 300000, retryCount: 0, maxRetries: scheduleEntry.constraints.maxRetries, metadata: {} }; this.assignments.set(assignment.id, assignment); scheduleEntry.status = 'assigned'; scheduleEntry.assignedAgent = agentId; scheduleEntry.updatedAt = new Date(); agent.currentTasks.push(scheduleEntry.taskId); agent.currentLoad = agent.currentTasks.length / agent.maxConcurrentTasks; agent.status = agent.currentTasks.length > 0 ? 'busy' : 'idle'; this.emit('taskAssigned', assignment); logger.info(`Task assigned: ${scheduleEntry.taskId} -> ${agentId}`); return createSuccess(assignment); } catch (error) { return createFailure(ErrorFactory.createError('system', `Failed to assign task: ${error instanceof Error ? error.message : 'Unknown error'}`, createErrorContext('UnifiedOrchestrationEngine', 'assignTask').build(), { cause: error instanceof Error ? error : undefined })); } } async startExecution(assignmentId) { try { const assignment = this.assignments.get(assignmentId); if (!assignment) { return createFailure(ErrorFactory.createError('validation', `Assignment not found: ${assignmentId}`, createErrorContext('UnifiedOrchestrationEngine', 'startExecution').build())); } const executionId = createExecutionId(crypto.randomUUID()); const execution = { id: executionId, workflowId: assignment.workflowId, taskId: assignment.taskId, agentId: assignment.agentId, status: 'running', startTime: new Date(), progress: 0, logs: [], errors: [], metrics: { memoryUsage: 0, cpuUsage: 0, responseTime: 0 }, watchdog: { enabled: this.config.executionMonitoring.watchdogEnabled, timeoutMs: this.config.defaultTimeout, lastCheck: new Date(), violations: 0 } }; this.executions.set(executionId, execution); assignment.status = 'running'; assignment.startedAt = new Date(); this.taskExecutionCount++; this.emit('executionStarted', execution); logger.info(`Execution started: ${executionId} for task ${assignment.taskId}`); return createSuccess(executionId); } catch (error) { return createFailure(ErrorFactory.createError('system', `Failed to start execution: ${error instanceof Error ? error.message : 'Unknown error'}`, createErrorContext('UnifiedOrchestrationEngine', 'startExecution').build(), { cause: error instanceof Error ? error : undefined })); } } async updateExecutionProgress(executionId, progress, logs) { try { const execution = this.executions.get(executionId); if (!execution) { return createFailure(ErrorFactory.createError('validation', `Execution not found: ${executionId}`, createErrorContext('UnifiedOrchestrationEngine', 'updateExecutionProgress').build())); } execution.progress = Math.max(0, Math.min(100, progress)); execution.watchdog.lastCheck = new Date(); if (logs) { execution.logs.push(...logs); } this.emit('executionProgress', { executionId, progress }); return createSuccess(undefined); } catch (error) { return createFailure(ErrorFactory.createError('system', `Failed to update execution progress: ${error instanceof Error ? error.message : 'Unknown error'}`, createErrorContext('UnifiedOrchestrationEngine', 'updateExecutionProgress').build(), { cause: error instanceof Error ? error : undefined })); } } async completeExecution(executionId, success, result) { try { const execution = this.executions.get(executionId); if (!execution) { return createFailure(ErrorFactory.createError('validation', `Execution not found: ${executionId}`, createErrorContext('UnifiedOrchestrationEngine', 'completeExecution').build())); } execution.status = success ? 'completed' : 'failed'; execution.endTime = new Date(); execution.progress = success ? 100 : execution.progress; const assignment = Array.from(this.assignments.values()).find(a => a.taskId === execution.taskId && a.agentId === execution.agentId); if (assignment) { assignment.status = success ? 'completed' : 'failed'; assignment.completedAt = new Date(); assignment.actualDuration = execution.endTime.getTime() - execution.startTime.getTime(); } const agent = this.agents.get(execution.agentId); if (agent) { agent.currentTasks = agent.currentTasks.filter(taskId => taskId !== execution.taskId); agent.currentLoad = agent.currentTasks.length / agent.maxConcurrentTasks; agent.status = agent.currentTasks.length > 0 ? 'busy' : 'idle'; const executionTime = execution.endTime.getTime() - execution.startTime.getTime(); agent.performance.averageTaskTime = (agent.performance.averageTaskTime + executionTime) / 2; if (success) { agent.performance.successRate = Math.min(1, agent.performance.successRate + 0.01); } else { agent.performance.errorRate = Math.min(1, agent.performance.errorRate + 0.01); this.errorCount++; } agent.performance.lastActivity = new Date(); } const workflow = this.workflows.get(execution.workflowId); if (workflow) { if (success) { workflow.progress.completedTasks++; } else { workflow.progress.failedTasks++; } workflow.progress.percentage = (workflow.progress.completedTasks / workflow.progress.totalTasks) * 100; } this.totalExecutionTime += execution.endTime.getTime() - execution.startTime.getTime(); this.emit('executionCompleted', { execution, success, result }); logger.info(`Execution completed: ${executionId} (${success ? 'success' : 'failed'})`); return createSuccess(undefined); } catch (error) { return createFailure(ErrorFactory.createError('system', `Failed to complete execution: ${error instanceof Error ? error.message : 'Unknown error'}`, createErrorContext('UnifiedOrchestrationEngine', 'completeExecution').build(), { cause: error instanceof Error ? error : undefined })); } } async checkAgentHeartbeats() { const now = new Date(); const timeout = this.config.agentManagement.heartbeatTimeout; for (const [agentId, agent] of this.agents.entries()) { const timeSinceHeartbeat = now.getTime() - agent.metadata.lastHeartbeat.getTime(); if (timeSinceHeartbeat > timeout && agent.status !== 'offline') { agent.status = 'offline'; this.emit('agentTimeout', { agentId, timeSinceHeartbeat }); logger.warn(`Agent timeout: ${agentId} (${timeSinceHeartbeat}ms)`); if (this.config.agentManagement.autoRecovery) { await this.handleAgentRecovery(agentId); } } } } async processScheduledTasks() { const pendingTasks = Array.from(this.schedule.values()) .filter(entry => entry.status === 'pending') .sort((a, b) => { const priorityWeights = this.config.taskScheduling.priorityWeights; const priorityDiff = priorityWeights[b.priority] - priorityWeights[a.priority]; if (priorityDiff !== 0) return priorityDiff; return a.scheduledAt.getTime() - b.scheduledAt.getTime(); }); const batchSize = Math.min(pendingTasks.length, this.config.taskScheduling.batchSize); for (let i = 0; i < batchSize; i++) { const task = pendingTasks[i]; const agentsResult = await this.getAvailableAgents(task.constraints.requiredCapabilities); if (!agentsResult.success || agentsResult.data.length === 0) { continue; } const selectedAgent = this.selectAgentByStrategy(agentsResult.data, task); if (selectedAgent) { await this.assignTask(task.id, selectedAgent.id); } } } async runExecutionWatchdog() { const now = new Date(); for (const [executionId, execution] of this.executions.entries()) { if (execution.status !== 'running') continue; const timeSinceLastCheck = now.getTime() - execution.watchdog.lastCheck.getTime(); if (timeSinceLastCheck > execution.watchdog.timeoutMs) { execution.watchdog.violations++; if (execution.watchdog.violations >= 3) { execution.status = 'timeout'; execution.endTime = new Date(); this.emit('executionTimeout', execution); logger.warn(`Execution timeout: ${executionId}`); if (this.config.recovery.autoRetry) { await this.handleExecutionTimeout(executionId); } } } } } async cleanupCompletedWorkflows() { const cutoffTime = new Date(Date.now() - 24 * 60 * 60 * 1000); const completedWorkflows = []; for (const [workflowId, workflow] of this.workflows.entries()) { if ((workflow.status === 'completed' || workflow.status === 'failed') && workflow.endTime && workflow.endTime < cutoffTime) { completedWorkflows.push(workflowId); } } for (const workflowId of completedWorkflows) { this.workflows.delete(workflowId); for (const [assignmentId, assignment] of this.assignments.entries()) { if (assignment.workflowId === workflowId) { this.assignments.delete(assignmentId); } } for (const [executionId, execution] of this.executions.entries()) { if (execution.workflowId === workflowId) { this.executions.delete(executionId); } } } if (completedWorkflows.length > 0) { logger.debug(`Cleaned up ${completedWorkflows.length} completed workflows`); } } collectMetrics() { const stats = { agents: { total: this.agents.size, online: Array.from(this.agents.values()).filter(a => a.status === 'online').length, busy: Array.from(this.agents.values()).filter(a => a.status === 'busy').length, idle: Array.from(this.agents.values()).filter(a => a.status === 'idle').length, offline: Array.from(this.agents.values()).filter(a => a.status === 'offline').length, averageLoad: this.agents.size > 0 ? Array.from(this.agents.values()).reduce((sum, a) => sum + a.currentLoad, 0) / this.agents.size : 0 }, workflows: { active: Array.from(this.workflows.values()).filter(w => w.status === 'running').length, completed: Array.from(this.workflows.values()).filter(w => w.status === 'completed').length, failed: Array.from(this.workflows.values()).filter(w => w.status === 'failed').length, averageDuration: this.workflowCount > 0 ? this.totalExecutionTime / this.workflowCount : 0 }, tasks: { scheduled: Array.from(this.schedule.values()).filter(s => s.status === 'pending').length, running: Array.from(this.executions.values()).filter(e => e.status === 'running').length, completed: Array.from(this.assignments.values()).filter(a => a.status === 'completed').length, failed: Array.from(this.assignments.values()).filter(a => a.status === 'failed').length, averageExecutionTime: this.taskExecutionCount > 0 ? this.totalExecutionTime / this.taskExecutionCount : 0 }, performance: { throughput: this.taskExecutionCount / Math.max(1, (Date.now() - this.orchestrationCount) / 60000), successRate: this.taskExecutionCount > 0 ? (this.taskExecutionCount - this.errorCount) / this.taskExecutionCount : 1, errorRate: this.taskExecutionCount > 0 ? this.errorCount / this.taskExecutionCount : 0, averageResponseTime: this.taskExecutionCount > 0 ? this.totalExecutionTime / this.taskExecutionCount : 0 } }; this.emit('metricsCollected', stats); } selectAgentByStrategy(agents, task) { if (agents.length === 0) return null; switch (this.config.taskScheduling.strategy) { case 'round_robin': return agents[this.orchestrationCount % agents.length]; case 'least_loaded': return agents.reduce((best, current) => current.currentLoad < best.currentLoad ? current : best); case 'capability_first': { const exactMatch = agents.find(agent => task.constraints.requiredCapabilities.every(cap => agent.capabilities.includes(cap))); return exactMatch || agents[0]; } case 'performance_based': return agents.reduce((best, current) => current.performance.successRate > best.performance.successRate ? current : best); case 'intelligent_hybrid': default: return agents.reduce((best, current) => { const currentScore = this.calculateAgentScore(current, task); const bestScore = this.calculateAgentScore(best, task); return currentScore > bestScore ? current : best; }); } } calculateAgentScore(agent, task) { let score = 0; score += (1 - agent.currentLoad) * 0.3; score += agent.performance.successRate * 0.4; const capabilityMatch = task.constraints.requiredCapabilities.every(cap => agent.capabilities.includes(cap)) ? 1 : 0.5; score += capabilityMatch * 0.3; return score; } async handleAgentRecovery(agentId) { const agent = this.agents.get(agentId); if (!agent) return; for (const taskId of agent.currentTasks) { const assignment = Array.from(this.assignments.values()).find(a => a.taskId === taskId && a.agentId === agentId); if (assignment && assignment.retryCount < assignment.maxRetries) { assignment.retryCount++; assignment.status = 'pending'; const agentsResult = await this.getAvailableAgents(); if (agentsResult.success && agentsResult.data.length > 0) { const newAgent = agentsResult.data[0]; assignment.agentId = newAgent.id; logger.info(`Task reassigned from offline agent: ${taskId} ${agentId} -> ${newAgent.id}`); } } } agent.currentTasks = []; agent.currentLoad = 0; } async handleExecutionTimeout(executionId) { const execution = this.executions.get(executionId); if (!execution) return; const assignment = Array.from(this.assignments.values()).find(a => a.taskId === execution.taskId && a.agentId === execution.agentId); if (assignment && assignment.retryCount < assignment.maxRetries) { assignment.retryCount++; assignment.status = 'pending'; setTimeout(async () => { const agentsResult = await this.getAvailableAgents(); if (agentsResult.success && agentsResult.data.length > 0) { const newAgent = agentsResult.data[0]; assignment.agentId = newAgent.id; logger.info(`Task retry scheduled after timeout: ${assignment.taskId}`); } }, this.config.recovery.retryDelay); } } async fileExists(path) { try { await fs.access(path); return true; } catch { return false; } } getStatistics() { return { agents: { total: this.agents.size, online: Array.from(this.agents.values()).filter(a => a.status === 'online').length, busy: Array.from(this.agents.values()).filter(a => a.status === 'busy').length, idle: Array.from(this.agents.values()).filter(a => a.status === 'idle').length, offline: Array.from(this.agents.values()).filter(a => a.status === 'offline').length, averageLoad: this.agents.size > 0 ? Array.from(this.agents.values()).reduce((sum, a) => sum + a.currentLoad, 0) / this.agents.size : 0 }, workflows: { active: Array.from(this.workflows.values()).filter(w => w.status === 'running').length, completed: Array.from(this.workflows.values()).filter(w => w.status === 'completed').length, failed: Array.from(this.workflows.values()).filter(w => w.status === 'failed').length, averageDuration: this.workflowCount > 0 ? this.totalExecutionTime / this.workflowCount : 0 }, tasks: { scheduled: Array.from(this.schedule.values()).filter(s => s.status === 'pending').length, running: Array.from(this.executions.values()).filter(e => e.status === 'running').length, completed: Array.from(this.assignments.values()).filter(a => a.status === 'completed').length, failed: Array.from(this.assignments.values()).filter(a => a.status === 'failed').length, averageExecutionTime: this.taskExecutionCount > 0 ? this.totalExecutionTime / this.taskExecutionCount : 0 }, performance: { throughput: this.taskExecutionCount / Math.max(1, (Date.now() - this.orchestrationCount) / 60000), successRate: this.taskExecutionCount > 0 ? (this.taskExecutionCount - this.errorCount) / this.taskExecutionCount : 1, errorRate: this.taskExecutionCount > 0 ? this.errorCount / this.taskExecutionCount : 0, averageResponseTime: this.taskExecutionCount > 0 ? this.totalExecutionTime / this.taskExecutionCount : 0 } }; } dispose() { if (this.heartbeatTimer) { clearInterval(this.heartbeatTimer); this.heartbeatTimer = null; } if (this.schedulerTimer) { clearInterval(this.schedulerTimer); this.schedulerTimer = null; } if (this.watchdogTimer) { clearInterval(this.watchdogTimer); this.watchdogTimer = null; } if (this.cleanupTimer) { clearInterval(this.cleanupTimer); this.cleanupTimer = null; } if (this.metricsTimer) { clearInterval(this.metricsTimer); this.metricsTimer = null; } this.agents.clear(); this.workflows.clear(); this.assignments.clear(); this.executions.clear(); this.schedule.clear(); this.removeAllListeners(); this.initialized = false; logger.info('Unified Orchestration Engine disposed'); } } export function createDefaultOrchestrationConfig() { return { enabled: true, maxConcurrentWorkflows: 10, maxConcurrentExecutions: 50, defaultTimeout: 300000, heartbeatInterval: 30000, agentManagement: { maxAgents: 20, heartbeatTimeout: 90000, offlineThreshold: 180000, autoRecovery: true, loadBalancing: true }, workflowManagement: { persistState: true, stateBackupInterval: 60000, maxWorkflowDuration: 3600000, autoCleanup: true, cleanupInterval: 3600000 }, taskScheduling: { strategy: 'intelligent_hybrid', batchSize: 10, schedulingInterval: 5000, priorityWeights: { low: 1, medium: 2, high: 3, critical: 5 }, dependencyResolution: true }, executionMonitoring: { watchdogEnabled: true, watchdogInterval: 10000, performanceTracking: true, metricsCollection: true, alertThresholds: { errorRate: 0.1, responseTime: 300000, memoryUsage: 0.8 } }, recovery: { autoRetry: true, maxRetries: 3, retryDelay: 5000, failureEscalation: true, deadlockDetection: true } }; }