UNPKG

claude-flow

Version:

Enterprise-grade AI agent orchestration with ruv-swarm integration (Alpha Release)

603 lines (551 loc) 17.4 kB
import { getErrorMessage } from '../utils/error-handler.js'; /** * ruv-swarm MCP tools wrapper for Claude Code integration * * This module provides MCP tools that integrate with the external ruv-swarm * package to enable advanced swarm coordination and neural capabilities. */ import type { MCPTool, MCPContext } from '../utils/types.js'; import type { ILogger } from '../core/logger.js'; import { execAsync } from '../utils/helpers.js'; import { existsSync } from 'fs'; import { join } from 'path'; export interface RuvSwarmToolContext extends MCPContext { workingDirectory?: string; swarmId?: string; sessionId?: string; } /** * Interface for ruv-swarm command responses */ interface RuvSwarmResponse { success: boolean; data?: any; error?: string; metadata?: { timestamp: number; swarmId?: string; sessionId?: string; performance?: any; }; } /** * Execute ruv-swarm command with proper error handling */ async function executeRuvSwarmCommand( command: string, args: string[] = [], context?: RuvSwarmToolContext, logger?: ILogger ): Promise<RuvSwarmResponse> { try { const workDir = context?.workingDirectory || process.cwd(); const fullCommand = `npx ruv-swarm ${command} ${args.join(' ')}`; logger?.debug('Executing ruv-swarm command', { command: fullCommand, workDir }); const result = await execAsync(fullCommand, { cwd: workDir }); // Parse JSON response if possible let data; try { data = JSON.parse(result.stdout); } catch { data = { output: result.stdout, stderr: result.stderr }; } logger?.debug('ruv-swarm command completed', { command, success: true }); return { success: true, data, metadata: { timestamp: Date.now(), swarmId: context?.swarmId, sessionId: context?.sessionId } }; } catch (error) { logger?.error('ruv-swarm command failed', { command, error: (error instanceof Error ? error.message : String(error)) }); return { success: false, error: (error instanceof Error ? error.message : String(error)), metadata: { timestamp: Date.now(), swarmId: context?.swarmId, sessionId: context?.sessionId } }; } } /** * Create ruv-swarm MCP tools for Claude Code integration * * These tools provide access to the full ruv-swarm functionality including: * - Swarm initialization and management * - Neural agent coordination * - Memory and persistence * - Performance monitoring * - Task orchestration */ export function createRuvSwarmTools(logger: ILogger): MCPTool[] { return [ // === SWARM LIFECYCLE TOOLS === { name: 'mcp__ruv-swarm__swarm_init', description: 'Initialize a new ruv-swarm with specified topology and configuration', inputSchema: { type: 'object', properties: { topology: { type: 'string', enum: ['mesh', 'hierarchical', 'ring', 'star'], description: 'Swarm topology type' }, maxAgents: { type: 'number', minimum: 1, maximum: 100, default: 5, description: 'Maximum number of agents' }, strategy: { type: 'string', enum: ['balanced', 'specialized', 'adaptive'], default: 'balanced', description: 'Distribution strategy' } }, required: ['topology'] }, handler: async (input: any, context?: RuvSwarmToolContext) => { const args = [ '--topology', input.topology, '--max-agents', String(input.maxAgents || 5), '--strategy', input.strategy || 'balanced' ]; return await executeRuvSwarmCommand('swarm init', args, context, logger); } }, { name: 'mcp__ruv-swarm__swarm_status', description: 'Get current swarm status and agent information', inputSchema: { type: 'object', properties: { verbose: { type: 'boolean', default: false, description: 'Include detailed agent information' } } }, handler: async (input: any, context?: RuvSwarmToolContext) => { const args = input.verbose ? ['--verbose'] : []; return await executeRuvSwarmCommand('swarm status', args, context, logger); } }, { name: 'mcp__ruv-swarm__swarm_monitor', description: 'Monitor swarm activity in real-time', inputSchema: { type: 'object', properties: { duration: { type: 'number', default: 10, description: 'Monitoring duration in seconds' }, interval: { type: 'number', default: 1, description: 'Update interval in seconds' } } }, handler: async (input: any, context?: RuvSwarmToolContext) => { const args = [ '--duration', String(input.duration || 10), '--interval', String(input.interval || 1) ]; return await executeRuvSwarmCommand('swarm monitor', args, context, logger); } }, // === AGENT MANAGEMENT TOOLS === { name: 'mcp__ruv-swarm__agent_spawn', description: 'Spawn a new agent in the swarm', inputSchema: { type: 'object', properties: { type: { type: 'string', enum: ['coordinator', 'researcher', 'coder', 'analyst', 'architect', 'tester', 'reviewer', 'optimizer', 'documenter', 'monitor', 'specialist'], description: 'Agent type' }, name: { type: 'string', description: 'Custom agent name' }, capabilities: { type: 'array', items: { type: 'string' }, description: 'Agent capabilities' } }, required: ['type'] }, handler: async (input: any, context?: RuvSwarmToolContext) => { const args = ['--type', input.type]; if (input.name) { args.push('--name', input.name); } if (input.capabilities && input.capabilities.length > 0) { args.push('--capabilities', input.capabilities.join(',')); } return await executeRuvSwarmCommand('agent spawn', args, context, logger); } }, { name: 'mcp__ruv-swarm__agent_list', description: 'List all active agents in the swarm', inputSchema: { type: 'object', properties: { filter: { type: 'string', enum: ['all', 'active', 'idle', 'busy'], default: 'all', description: 'Filter agents by status' } } }, handler: async (input: any, context?: RuvSwarmToolContext) => { const args = ['--filter', input.filter || 'all']; return await executeRuvSwarmCommand('agent list', args, context, logger); } }, { name: 'mcp__ruv-swarm__agent_metrics', description: 'Get performance metrics for agents', inputSchema: { type: 'object', properties: { agentId: { type: 'string', description: 'Specific agent ID (optional)' }, metric: { type: 'string', enum: ['all', 'cpu', 'memory', 'tasks', 'performance'], default: 'all' } } }, handler: async (input: any, context?: RuvSwarmToolContext) => { const args = ['--metric', input.metric || 'all']; if (input.agentId) { args.push('--agent-id', input.agentId); } return await executeRuvSwarmCommand('agent metrics', args, context, logger); } }, // === TASK ORCHESTRATION TOOLS === { name: 'mcp__ruv-swarm__task_orchestrate', description: 'Orchestrate a task across the swarm', inputSchema: { type: 'object', properties: { task: { type: 'string', description: 'Task description or instructions' }, strategy: { type: 'string', enum: ['parallel', 'sequential', 'adaptive'], default: 'adaptive', description: 'Execution strategy' }, priority: { type: 'string', enum: ['low', 'medium', 'high', 'critical'], default: 'medium', description: 'Task priority' }, maxAgents: { type: 'number', minimum: 1, maximum: 10, description: 'Maximum agents to use' } }, required: ['task'] }, handler: async (input: any, context?: RuvSwarmToolContext) => { const args = [ '--task', JSON.stringify(input.task), '--strategy', input.strategy || 'adaptive', '--priority', input.priority || 'medium' ]; if (input.maxAgents) { args.push('--max-agents', String(input.maxAgents)); } return await executeRuvSwarmCommand('task orchestrate', args, context, logger); } }, { name: 'mcp__ruv-swarm__task_status', description: 'Check progress of running tasks', inputSchema: { type: 'object', properties: { taskId: { type: 'string', description: 'Specific task ID (optional)' }, detailed: { type: 'boolean', default: false, description: 'Include detailed progress' } } }, handler: async (input: any, context?: RuvSwarmToolContext) => { const args = []; if (input.taskId) { args.push('--task-id', input.taskId); } if (input.detailed) { args.push('--detailed'); } return await executeRuvSwarmCommand('task status', args, context, logger); } }, { name: 'mcp__ruv-swarm__task_results', description: 'Retrieve results from completed tasks', inputSchema: { type: 'object', properties: { taskId: { type: 'string', description: 'Task ID to retrieve results for' }, format: { type: 'string', enum: ['summary', 'detailed', 'raw'], default: 'summary', description: 'Result format' } }, required: ['taskId'] }, handler: async (input: any, context?: RuvSwarmToolContext) => { const args = [ '--task-id', input.taskId, '--format', input.format || 'summary' ]; return await executeRuvSwarmCommand('task results', args, context, logger); } }, // === MEMORY AND PERSISTENCE TOOLS === { name: 'mcp__ruv-swarm__memory_usage', description: 'Get current memory usage statistics', inputSchema: { type: 'object', properties: { detail: { type: 'string', enum: ['summary', 'detailed', 'by-agent'], default: 'summary', description: 'Detail level' } } }, handler: async (input: any, context?: RuvSwarmToolContext) => { const args = ['--detail', input.detail || 'summary']; return await executeRuvSwarmCommand('memory usage', args, context, logger); } }, // === NEURAL CAPABILITIES TOOLS === { name: 'mcp__ruv-swarm__neural_status', description: 'Get neural agent status and performance metrics', inputSchema: { type: 'object', properties: { agentId: { type: 'string', description: 'Specific agent ID (optional)' } } }, handler: async (input: any, context?: RuvSwarmToolContext) => { const args = []; if (input.agentId) { args.push('--agent-id', input.agentId); } return await executeRuvSwarmCommand('neural status', args, context, logger); } }, { name: 'mcp__ruv-swarm__neural_train', description: 'Train neural agents with sample tasks', inputSchema: { type: 'object', properties: { agentId: { type: 'string', description: 'Specific agent ID to train (optional)' }, iterations: { type: 'number', minimum: 1, maximum: 100, default: 10, description: 'Number of training iterations' } } }, handler: async (input: any, context?: RuvSwarmToolContext) => { const args = ['--iterations', String(input.iterations || 10)]; if (input.agentId) { args.push('--agent-id', input.agentId); } return await executeRuvSwarmCommand('neural train', args, context, logger); } }, { name: 'mcp__ruv-swarm__neural_patterns', description: 'Get cognitive pattern information', inputSchema: { type: 'object', properties: { pattern: { type: 'string', enum: ['all', 'convergent', 'divergent', 'lateral', 'systems', 'critical', 'abstract'], default: 'all', description: 'Cognitive pattern type' } } }, handler: async (input: any, context?: RuvSwarmToolContext) => { const args = ['--pattern', input.pattern || 'all']; return await executeRuvSwarmCommand('neural patterns', args, context, logger); } }, // === PERFORMANCE AND BENCHMARKING TOOLS === { name: 'mcp__ruv-swarm__benchmark_run', description: 'Execute performance benchmarks', inputSchema: { type: 'object', properties: { type: { type: 'string', enum: ['all', 'wasm', 'swarm', 'agent', 'task'], default: 'all', description: 'Benchmark type' }, iterations: { type: 'number', minimum: 1, maximum: 100, default: 10, description: 'Number of iterations' } } }, handler: async (input: any, context?: RuvSwarmToolContext) => { const args = [ '--type', input.type || 'all', '--iterations', String(input.iterations || 10) ]; return await executeRuvSwarmCommand('benchmark run', args, context, logger); } }, { name: 'mcp__ruv-swarm__features_detect', description: 'Detect runtime features and capabilities', inputSchema: { type: 'object', properties: { category: { type: 'string', enum: ['all', 'wasm', 'simd', 'memory', 'platform'], default: 'all', description: 'Feature category' } } }, handler: async (input: any, context?: RuvSwarmToolContext) => { const args = ['--category', input.category || 'all']; return await executeRuvSwarmCommand('features detect', args, context, logger); } } ]; } /** * Check if ruv-swarm is available in the current environment */ export async function isRuvSwarmAvailable(logger?: ILogger): Promise<boolean> { try { const result = await executeRuvSwarmCommand('--version', [], undefined, logger); return result.success; } catch (error) { logger?.warn('ruv-swarm not available', { error: error instanceof Error ? (error instanceof Error ? error.message : String(error)) : error }); return false; } } /** * Get ruv-swarm configuration and capabilities */ export async function getRuvSwarmCapabilities(logger?: ILogger): Promise<any> { try { const result = await executeRuvSwarmCommand('features detect', ['--category', 'all'], undefined, logger); return result.data; } catch (error) { logger?.error('Failed to get ruv-swarm capabilities', error); return null; } } /** * Initialize ruv-swarm with claude-code-flow integration */ export async function initializeRuvSwarmIntegration( workingDirectory: string, logger?: ILogger ): Promise<RuvSwarmResponse> { const context: RuvSwarmToolContext = { workingDirectory, sessionId: `claude-flow-${Date.now()}` }; logger?.info('Initializing ruv-swarm integration', { workingDirectory }); // Check if ruv-swarm is available const available = await isRuvSwarmAvailable(logger); if (!available) { return { success: false, error: 'ruv-swarm is not available. Please install it with: npm install -g ruv-swarm' }; } // Get capabilities const capabilities = await getRuvSwarmCapabilities(logger); logger?.info('ruv-swarm integration initialized', { capabilities }); return { success: true, data: { available: true, capabilities, integration: 'claude-code-flow', sessionId: context.sessionId }, metadata: { timestamp: Date.now(), sessionId: context.sessionId } }; } export default { createRuvSwarmTools, isRuvSwarmAvailable, getRuvSwarmCapabilities, initializeRuvSwarmIntegration };