UNPKG

claude-flow-multilang

Version:

Revolutionary multilingual AI orchestration framework with cultural awareness and DDD architecture

1,046 lines (909 loc) 30 kB
// SPARC Coordinator // Integrates SPARC methodology with swarm system for enhanced coordination import { SparcPhase } from './phase-base.js'; export class SparcCoordinator { constructor(phases, options = {}) { this.phases = phases; this.options = options; this.swarmId = null; this.agents = []; this.phaseAgents = new Map(); this.coordination = { strategy: 'adaptive', topology: 'hierarchical', communication: 'event-driven', loadBalancing: 'capability-based', }; this.metrics = { phaseExecutions: 0, agentUtilization: {}, coordinationEfficiency: 0, qualityGates: [], learningData: [], }; this.neuralContext = null; this.swarmEnabled = options.swarmEnabled || false; } /** * Initialize swarm for SPARC execution */ async initializeSwarm() { if (!this.swarmEnabled) { console.log('🔄 SPARC running in standalone mode'); return; } console.log('🐝 Initializing SPARC Swarm Coordination'); try { // Initialize swarm using ruv-swarm hooks const swarmConfig = { topology: this.coordination.topology, maxAgents: this.calculateOptimalAgentCount(), strategy: 'sparc_methodology', communication: this.coordination.communication, loadBalancing: this.coordination.loadBalancing, }; this.swarmId = await this.executeSwarmHook('swarm_init', swarmConfig); console.log(`🆔 Swarm initialized: ${this.swarmId}`); // Spawn specialized SPARC agents await this.spawnSparcAgents(); // Setup inter-phase coordination await this.setupPhaseCoordination(); console.log('✅ SPARC Swarm coordination initialized'); } catch (error) { console.warn(`⚠️ Swarm initialization failed: ${error.message}`); console.log('🔄 Falling back to standalone mode'); this.swarmEnabled = false; } } /** * Calculate optimal agent count based on SPARC phases */ calculateOptimalAgentCount() { const baseAgents = Object.keys(this.phases).length; // One per phase const complexityMultiplier = this.assessTaskComplexity(); const parallelismFactor = this.options.parallelExecution ? 2 : 1; return Math.min(20, Math.max(5, baseAgents * complexityMultiplier * parallelismFactor)); } /** * Assess task complexity for agent allocation */ assessTaskComplexity() { const taskDescription = this.options.taskDescription || ''; const complexityKeywords = [ 'complex', 'enterprise', 'scalable', 'distributed', 'microservice', 'integration', ]; const matchedKeywords = complexityKeywords.filter((keyword) => taskDescription.toLowerCase().includes(keyword), ); if (matchedKeywords.length >= 3) return 3; // High complexity if (matchedKeywords.length >= 1) return 2; // Medium complexity return 1; // Low complexity } /** * Spawn specialized SPARC agents */ async spawnSparcAgents() { const agentTypes = [ { type: 'sparc_specification', role: 'Requirements Analyst', capabilities: ['analysis', 'documentation', 'validation'], }, { type: 'sparc_pseudocode', role: 'Logic Designer', capabilities: ['design', 'flowcharts', 'algorithms'], }, { type: 'sparc_architecture', role: 'System Architect', capabilities: ['architecture', 'design_patterns', 'scalability'], }, { type: 'sparc_refinement', role: 'TDD Engineer', capabilities: ['testing', 'refactoring', 'code_quality'], }, { type: 'sparc_completion', role: 'Integration Specialist', capabilities: ['integration', 'deployment', 'validation'], }, { type: 'sparc_coordinator', role: 'SPARC Orchestrator', capabilities: ['coordination', 'monitoring', 'optimization'], }, ]; for (const agentSpec of agentTypes) { try { const agentId = await this.executeSwarmHook('agent_spawn', { type: agentSpec.type, role: agentSpec.role, capabilities: agentSpec.capabilities, maxConcurrentTasks: this.getAgentConcurrency(agentSpec.type), specialization: 'sparc_methodology', }); const agent = { id: agentId, type: agentSpec.type, role: agentSpec.role, capabilities: agentSpec.capabilities, status: 'ready', currentPhase: null, assignedTasks: [], performance: { tasksCompleted: 0, averageTime: 0, qualityScore: 1.0, efficiency: 1.0, }, }; this.agents.push(agent); console.log(` 🤖 Spawned ${agentSpec.role} (${agentSpec.type})`); } catch (error) { console.warn(`⚠️ Failed to spawn ${agentSpec.role}: ${error.message}`); } } } /** * Get agent concurrency based on type */ getAgentConcurrency(agentType) { const concurrencyMap = { sparc_specification: 2, sparc_pseudocode: 1, sparc_architecture: 3, sparc_refinement: 4, sparc_completion: 2, sparc_coordinator: 1, }; return concurrencyMap[agentType] || 2; } /** * Setup phase coordination */ async setupPhaseCoordination() { // Map agents to phases for (const agent of this.agents) { const phaseName = agent.type.replace('sparc_', ''); if (this.phases[phaseName]) { if (!this.phaseAgents.has(phaseName)) { this.phaseAgents.set(phaseName, []); } this.phaseAgents.get(phaseName).push(agent); } } // Setup phase dependencies await this.executeSwarmHook('setup_dependencies', { phases: Object.keys(this.phases), dependencies: { pseudocode: ['specification'], architecture: ['specification', 'pseudocode'], refinement: ['specification', 'pseudocode', 'architecture'], completion: ['specification', 'pseudocode', 'architecture', 'refinement'], }, }); // Setup quality gates between phases await this.setupQualityGates(); } /** * Setup quality gates between phases */ async setupQualityGates() { const qualityGates = [ { phase: 'specification', criteria: ['requirements_complete', 'acceptance_criteria_defined'], threshold: 0.9, }, { phase: 'pseudocode', criteria: ['flow_diagram_complete', 'algorithms_defined'], threshold: 0.85, }, { phase: 'architecture', criteria: ['components_defined', 'patterns_selected'], threshold: 0.85, }, { phase: 'refinement', criteria: ['tests_passing', 'code_quality_acceptable'], threshold: 0.8, }, { phase: 'completion', criteria: ['validation_passed', 'deployment_successful'], threshold: 0.9, }, ]; for (const gate of qualityGates) { await this.executeSwarmHook('register_quality_gate', gate); } } /** * Pre-phase coordination */ async prePhase(phaseName) { if (!this.swarmEnabled) return; console.log(`🔄 Pre-phase coordination: ${phaseName}`); try { // Load neural context for the phase await this.loadNeuralContext(phaseName); // Assign agents to phase await this.assignAgentsToPhase(phaseName); // Prepare phase environment await this.preparePhaseEnvironment(phaseName); // Store phase initiation in memory await this.executeSwarmHook('memory_store', { key: `sparc_phase_${phaseName}_start`, value: { timestamp: Date.now(), agents: this.phaseAgents.get(phaseName)?.map((a) => a.id) || [], neuralContext: this.neuralContext, }, }); } catch (error) { console.warn(`⚠️ Pre-phase coordination failed for ${phaseName}: ${error.message}`); } } /** * Load neural context for phase */ async loadNeuralContext(phaseName) { try { const neuralData = await this.executeSwarmHook('neural_load_context', { phase: phaseName, methodology: 'sparc', taskType: this.classifyTaskType(), }); this.neuralContext = { phase: phaseName, patterns: neuralData.patterns || [], insights: neuralData.insights || [], recommendations: neuralData.recommendations || [], confidence: neuralData.confidence || 0.5, }; console.log( `🧠 Neural context loaded for ${phaseName} (confidence: ${this.neuralContext.confidence.toFixed(2)})`, ); } catch (error) { console.warn(`⚠️ Neural context loading failed: ${error.message}`); this.neuralContext = { phase: phaseName, patterns: [], insights: [], recommendations: [], confidence: 0.5, }; } } /** * Classify task type for neural learning */ classifyTaskType() { const taskDescription = this.options.taskDescription || ''; const taskLower = taskDescription.toLowerCase(); if (taskLower.includes('api') || taskLower.includes('service')) return 'api_development'; if (taskLower.includes('ui') || taskLower.includes('frontend')) return 'frontend_development'; if (taskLower.includes('data') || taskLower.includes('database')) return 'data_management'; if (taskLower.includes('test') || taskLower.includes('testing')) return 'testing'; if (taskLower.includes('deploy') || taskLower.includes('infrastructure')) return 'deployment'; return 'general_development'; } /** * Assign agents to phase */ async assignAgentsToPhase(phaseName) { const phaseAgents = this.phaseAgents.get(phaseName) || []; for (const agent of phaseAgents) { agent.currentPhase = phaseName; agent.status = 'assigned'; await this.executeSwarmHook('agent_assign', { agentId: agent.id, phase: phaseName, priority: this.getPhasePriority(phaseName), context: this.neuralContext, }); } // If no dedicated agents, assign general coordinator if (phaseAgents.length === 0) { const coordinator = this.agents.find((a) => a.type === 'sparc_coordinator'); if (coordinator) { coordinator.currentPhase = phaseName; coordinator.status = 'assigned'; await this.executeSwarmHook('agent_assign', { agentId: coordinator.id, phase: phaseName, priority: this.getPhasePriority(phaseName), context: this.neuralContext, }); } } } /** * Get phase priority for scheduling */ getPhasePriority(phaseName) { const priorities = { specification: 5, // Highest priority pseudocode: 4, architecture: 4, refinement: 3, completion: 2, }; return priorities[phaseName] || 1; } /** * Prepare phase environment */ async preparePhaseEnvironment(phaseName) { // Create phase-specific workspace await this.executeSwarmHook('create_workspace', { phase: phaseName, namespace: this.options.namespace || 'sparc', isolation: true, }); // Load previous phase artifacts const dependencies = this.getPhaseDependencies(phaseName); for (const dependency of dependencies) { await this.executeSwarmHook('load_artifacts', { fromPhase: dependency, toPhase: phaseName, artifactTypes: ['outputs', 'decisions', 'validations'], }); } } /** * Get phase dependencies */ getPhaseDependencies(phaseName) { const dependencies = { specification: [], pseudocode: ['specification'], architecture: ['specification', 'pseudocode'], refinement: ['specification', 'pseudocode', 'architecture'], completion: ['specification', 'pseudocode', 'architecture', 'refinement'], }; return dependencies[phaseName] || []; } /** * Post-phase coordination */ async postPhase(phaseName, result) { if (!this.swarmEnabled) return; console.log(`✅ Post-phase coordination: ${phaseName}`); try { // Validate phase results const validation = await this.validatePhaseResults(phaseName, result); // Update agent performance await this.updateAgentPerformance(phaseName, result, validation); // Store phase completion in memory await this.executeSwarmHook('memory_store', { key: `sparc_phase_${phaseName}_complete`, value: { timestamp: Date.now(), result: result, validation: validation, agents: this.phaseAgents.get(phaseName)?.map((a) => ({ id: a.id, performance: a.performance, })) || [], }, }); // Neural learning from phase execution if (this.options.neuralLearning) { await this.recordNeuralLearning(phaseName, result, validation); } // Prepare handoff to next phase await this.preparePhaseHandoff(phaseName, result); // Update metrics this.updateCoordinationMetrics(phaseName, result, validation); } catch (error) { console.warn(`⚠️ Post-phase coordination failed for ${phaseName}: ${error.message}`); } } /** * Validate phase results */ async validatePhaseResults(phaseName, result) { const validation = { phase: phaseName, passed: true, score: 0, issues: [], recommendations: [], }; try { // Execute swarm-based validation const swarmValidation = await this.executeSwarmHook('validate_phase', { phase: phaseName, result: result, criteria: this.getValidationCriteria(phaseName), }); validation.passed = swarmValidation.passed; validation.score = swarmValidation.score; validation.issues = swarmValidation.issues || []; validation.recommendations = swarmValidation.recommendations || []; } catch (error) { console.warn(`⚠️ Swarm validation failed: ${error.message}`); // Fallback to basic validation validation.passed = !!result; validation.score = result ? 85 : 0; } return validation; } /** * Get validation criteria for phase */ getValidationCriteria(phaseName) { const criteria = { specification: { requiredFields: ['requirements', 'acceptanceCriteria', 'userStories'], qualityThresholds: { completeness: 0.9, clarity: 0.8 }, }, pseudocode: { requiredFields: ['flowDiagram', 'pseudocode', 'algorithms'], qualityThresholds: { completeness: 0.85, complexity: 0.7 }, }, architecture: { requiredFields: ['systemDesign', 'components', 'designPatterns'], qualityThresholds: { modularity: 0.8, scalability: 0.75 }, }, refinement: { requiredFields: ['testResults', 'codeQuality', 'implementations'], qualityThresholds: { testCoverage: 0.8, codeQuality: 0.75 }, }, completion: { requiredFields: ['validation', 'deployment', 'documentation'], qualityThresholds: { completeness: 0.9, readiness: 0.85 }, }, }; return criteria[phaseName] || { requiredFields: [], qualityThresholds: {} }; } /** * Update agent performance metrics */ async updateAgentPerformance(phaseName, result, validation) { const phaseAgents = this.phaseAgents.get(phaseName) || []; for (const agent of phaseAgents) { agent.performance.tasksCompleted += 1; // Update quality score based on validation const qualityScore = validation.score / 100; agent.performance.qualityScore = (agent.performance.qualityScore + qualityScore) / 2; // Update efficiency based on execution time const executionTime = Date.now() - this.getPhaseStartTime(phaseName); const expectedTime = this.getExpectedPhaseTime(phaseName); const efficiency = Math.min(1, expectedTime / executionTime); agent.performance.efficiency = (agent.performance.efficiency + efficiency) / 2; // Update average time agent.performance.averageTime = (agent.performance.averageTime + executionTime) / 2; // Store performance update await this.executeSwarmHook('update_agent_performance', { agentId: agent.id, performance: agent.performance, phase: phaseName, }); } } /** * Get phase start time */ getPhaseStartTime(phaseName) { // This would typically be stored in memory or agent state return Date.now() - 5 * 60 * 1000; // Default to 5 minutes ago } /** * Get expected phase execution time */ getExpectedPhaseTime(phaseName) { const expectedTimes = { specification: 10 * 60 * 1000, // 10 minutes pseudocode: 5 * 60 * 1000, // 5 minutes architecture: 15 * 60 * 1000, // 15 minutes refinement: 20 * 60 * 1000, // 20 minutes completion: 10 * 60 * 1000, // 10 minutes }; return expectedTimes[phaseName] || 10 * 60 * 1000; } /** * Record neural learning from phase execution */ async recordNeuralLearning(phaseName, result, validation) { try { const learningData = { phase: phaseName, taskType: this.classifyTaskType(), methodology: 'sparc', execution: { result: result, validation: validation, timestamp: Date.now(), }, context: { taskDescription: this.options.taskDescription, neuralContext: this.neuralContext, agentPerformance: this.getAgentPerformanceData(phaseName), }, outcomes: { success: validation.passed, quality: validation.score, efficiency: this.calculatePhaseEfficiency(phaseName), learnings: this.extractLearnings(phaseName, result, validation), }, }; await this.executeSwarmHook('neural_record_learning', learningData); // Train neural patterns based on this execution await this.executeSwarmHook('neural_train', { data: learningData, updateWeights: true, savePattern: true, }); console.log(`🧠 Neural learning recorded for ${phaseName}`); } catch (error) { console.warn(`⚠️ Neural learning failed: ${error.message}`); } } /** * Get agent performance data for phase */ getAgentPerformanceData(phaseName) { const phaseAgents = this.phaseAgents.get(phaseName) || []; return phaseAgents.map((agent) => ({ id: agent.id, type: agent.type, performance: agent.performance, })); } /** * Calculate phase efficiency */ calculatePhaseEfficiency(phaseName) { const phaseAgents = this.phaseAgents.get(phaseName) || []; if (phaseAgents.length === 0) return 0.5; const avgEfficiency = phaseAgents.reduce((sum, agent) => sum + agent.performance.efficiency, 0) / phaseAgents.length; return avgEfficiency; } /** * Extract learnings from phase execution */ extractLearnings(phaseName, result, validation) { const learnings = []; if (validation.passed) { learnings.push(`${phaseName} phase executed successfully`); if (validation.score > 90) { learnings.push(`High quality output achieved in ${phaseName}`); } } else { learnings.push(`${phaseName} phase encountered issues: ${validation.issues.join(', ')}`); } if (validation.recommendations.length > 0) { learnings.push(`Recommendations for ${phaseName}: ${validation.recommendations.join(', ')}`); } return learnings; } /** * Prepare handoff to next phase */ async preparePhaseHandoff(phaseName, result) { const nextPhase = this.getNextPhase(phaseName); if (!nextPhase) return; // Prepare artifacts for next phase await this.executeSwarmHook('prepare_handoff', { fromPhase: phaseName, toPhase: nextPhase, artifacts: { outputs: result, decisions: this.extractDecisions(result), context: this.neuralContext, }, }); // Pre-warm next phase agents const nextPhaseAgents = this.phaseAgents.get(nextPhase) || []; for (const agent of nextPhaseAgents) { await this.executeSwarmHook('agent_prewarm', { agentId: agent.id, phase: nextPhase, context: result, }); } } /** * Get next phase in SPARC sequence */ getNextPhase(currentPhase) { const sequence = ['specification', 'pseudocode', 'architecture', 'refinement', 'completion']; const currentIndex = sequence.indexOf(currentPhase); return currentIndex >= 0 && currentIndex < sequence.length - 1 ? sequence[currentIndex + 1] : null; } /** * Extract decisions from phase result */ extractDecisions(result) { const decisions = []; if (result.architecturalDecisions) { decisions.push(...result.architecturalDecisions); } if (result.designDecisions) { decisions.push(...result.designDecisions); } if (result.qualityGates) { decisions.push( ...result.qualityGates.map((gate) => ({ decision: `Quality gate: ${gate.name}`, rationale: gate.rationale || 'Quality assurance', impact: gate.impact || 'process', })), ); } return decisions; } /** * Update coordination metrics */ updateCoordinationMetrics(phaseName, result, validation) { this.metrics.phaseExecutions += 1; // Update agent utilization const phaseAgents = this.phaseAgents.get(phaseName) || []; for (const agent of phaseAgents) { if (!this.metrics.agentUtilization[agent.id]) { this.metrics.agentUtilization[agent.id] = { phases: 0, totalTime: 0, quality: 0 }; } this.metrics.agentUtilization[agent.id].phases += 1; this.metrics.agentUtilization[agent.id].quality += validation.score; } // Update coordination efficiency const efficiency = this.calculatePhaseEfficiency(phaseName); this.metrics.coordinationEfficiency = (this.metrics.coordinationEfficiency + efficiency) / 2; // Record quality gate this.metrics.qualityGates.push({ phase: phaseName, passed: validation.passed, score: validation.score, timestamp: Date.now(), }); // Record learning data if (validation.passed) { this.metrics.learningData.push({ phase: phaseName, success: true, quality: validation.score, patterns: this.neuralContext?.patterns || [], }); } } /** * Finalize coordination */ async finalize() { if (!this.swarmEnabled) return; console.log('🏁 Finalizing SPARC coordination'); try { // Generate coordination report const report = await this.generateCoordinationReport(); // Store final metrics await this.executeSwarmHook('memory_store', { key: 'sparc_coordination_final', value: { metrics: this.metrics, report: report, timestamp: Date.now(), }, }); // Shutdown agents for (const agent of this.agents) { await this.executeSwarmHook('agent_shutdown', { agentId: agent.id, graceful: true, }); } // Shutdown swarm await this.executeSwarmHook('swarm_shutdown', { swarmId: this.swarmId, preserveData: true, }); console.log('✅ SPARC coordination finalized'); } catch (error) { console.warn(`⚠️ Coordination finalization failed: ${error.message}`); } } /** * Generate coordination report */ async generateCoordinationReport() { const report = { summary: { phasesExecuted: this.metrics.phaseExecutions, agentsUtilized: Object.keys(this.metrics.agentUtilization).length, coordinationEfficiency: this.metrics.coordinationEfficiency, qualityGatesPassed: this.metrics.qualityGates.filter((g) => g.passed).length, totalQualityGates: this.metrics.qualityGates.length, }, agentPerformance: this.calculateAgentPerformanceSummary(), phaseAnalysis: this.analyzePhasePerformance(), recommendations: this.generateRecommendations(), neuralInsights: this.extractNeuralInsights(), }; return report; } /** * Calculate agent performance summary */ calculateAgentPerformanceSummary() { const summary = {}; for (const agent of this.agents) { summary[agent.id] = { type: agent.type, role: agent.role, tasksCompleted: agent.performance.tasksCompleted, averageQuality: agent.performance.qualityScore, efficiency: agent.performance.efficiency, averageTime: agent.performance.averageTime, }; } return summary; } /** * Analyze phase performance */ analyzePhasePerformance() { const analysis = {}; for (const gate of this.metrics.qualityGates) { if (!analysis[gate.phase]) { analysis[gate.phase] = { executions: 0, passed: 0, averageScore: 0, totalScore: 0, }; } analysis[gate.phase].executions += 1; if (gate.passed) analysis[gate.phase].passed += 1; analysis[gate.phase].totalScore += gate.score; } // Calculate averages for (const phase of Object.keys(analysis)) { analysis[phase].averageScore = analysis[phase].totalScore / analysis[phase].executions; analysis[phase].successRate = analysis[phase].passed / analysis[phase].executions; } return analysis; } /** * Generate recommendations for improvement */ generateRecommendations() { const recommendations = []; // Analyze agent utilization const avgUtilization = Object.values(this.metrics.agentUtilization).reduce((sum, agent) => sum + agent.phases, 0) / Object.keys(this.metrics.agentUtilization).length; if (avgUtilization < 2) { recommendations.push('Consider reducing agent count for better utilization'); } else if (avgUtilization > 4) { recommendations.push('Consider increasing agent count to distribute load'); } // Analyze coordination efficiency if (this.metrics.coordinationEfficiency < 0.7) { recommendations.push('Improve coordination efficiency through better task decomposition'); } // Analyze quality gates const qualityGateSuccess = this.metrics.qualityGates.filter((g) => g.passed).length / this.metrics.qualityGates.length; if (qualityGateSuccess < 0.8) { recommendations.push('Review quality gate criteria and provide additional agent training'); } return recommendations; } /** * Extract neural insights */ extractNeuralInsights() { const insights = []; // Pattern analysis const successfulPatterns = this.metrics.learningData.filter((d) => d.success); if (successfulPatterns.length > 0) { insights.push(`${successfulPatterns.length} successful execution patterns identified`); } // Quality analysis const avgQuality = this.metrics.learningData.reduce((sum, d) => sum + d.quality, 0) / this.metrics.learningData.length; if (avgQuality > 85) { insights.push('High quality outcomes consistently achieved'); } else if (avgQuality < 70) { insights.push('Quality improvements needed in execution'); } return insights; } /** * Execute swarm hook with error handling */ async executeSwarmHook(hookName, data = {}) { if (!this.swarmEnabled) { throw new Error('Swarm not enabled'); } try { const { spawn } = await import('child_process'); return new Promise((resolve, reject) => { const args = ['ruv-swarm', 'hook', hookName]; // Add data as JSON argument if (Object.keys(data).length > 0) { args.push('--data', JSON.stringify(data)); } const process = spawn('npx', args, { stdio: 'pipe', }); let output = ''; let error = ''; process.stdout.on('data', (data) => { output += data.toString(); }); process.stderr.on('data', (data) => { error += data.toString(); }); process.on('close', (code) => { if (code === 0) { try { const result = JSON.parse(output); resolve(result); } catch (parseError) { resolve(output.trim()); } } else { reject(new Error(`Hook ${hookName} failed: ${error}`)); } }); process.on('error', (err) => { reject(err); }); }); } catch (error) { throw new Error(`Failed to execute swarm hook ${hookName}: ${error.message}`); } } /** * Record learning from SPARC execution */ async recordLearning(learningData) { if (!this.options.neuralLearning) return; try { await this.executeSwarmHook('neural_record_learning', { methodology: 'sparc', data: learningData, timestamp: Date.now(), }); } catch (error) { console.warn(`⚠️ Failed to record learning: ${error.message}`); } } /** * Get coordination status */ getStatus() { return { swarmEnabled: this.swarmEnabled, swarmId: this.swarmId, agentCount: this.agents.length, phaseAgents: Object.fromEntries( Array.from(this.phaseAgents.entries()).map(([phase, agents]) => [ phase, agents.map((a) => ({ id: a.id, type: a.type, status: a.status })), ]), ), metrics: this.metrics, coordination: this.coordination, }; } } export default SparcCoordinator;