UNPKG

claude-flow

Version:

Ruflo - Enterprise AI agent orchestration for Claude Code. Deploy 60+ specialized agents in coordinated swarms with self-learning, fault-tolerant consensus, vector memory, and MCP integration

499 lines 15.8 kB
/** * V3 MCP Federation Tools * * MCP tools for federation hub and ephemeral agent management: * - federation/status - Get federation status * - federation/spawn-ephemeral - Spawn ephemeral agent * - federation/terminate-ephemeral - Terminate ephemeral agent * - federation/list-ephemeral - List ephemeral agents * - federation/register-swarm - Register swarm with federation * - federation/broadcast - Broadcast message to all swarms * - federation/propose - Propose federation-wide consensus * - federation/vote - Vote on consensus proposal * * Implements ADR-005: MCP-First API Design * Implements ADR-001: agentic-flow@alpha compatibility */ import { z } from 'zod'; import { getDefaultFederationHub, } from '../../@claude-flow/swarm/src/federation-hub.js'; // ============================================================================ // Input Schemas // ============================================================================ const spawnEphemeralSchema = z.object({ type: z.string() .describe('Agent type (e.g., "coder", "researcher", "tester")'), task: z.string() .describe('Task description for the ephemeral agent'), swarmId: z.string().optional() .describe('Target swarm ID (auto-select if not specified)'), ttl: z.number().optional() .describe('Time-to-live in milliseconds'), capabilities: z.array(z.string()).optional() .describe('Required capabilities'), priority: z.enum(['low', 'normal', 'high', 'critical']).default('normal') .describe('Priority for swarm selection'), waitForCompletion: z.boolean().default(false) .describe('Wait for agent to complete'), completionTimeout: z.number().optional() .describe('Timeout when waiting for completion (ms)'), }); const terminateEphemeralSchema = z.object({ agentId: z.string() .describe('Ephemeral agent ID to terminate'), reason: z.string().optional() .describe('Reason for termination'), }); const listEphemeralSchema = z.object({ swarmId: z.string().optional() .describe('Filter by swarm ID'), status: z.enum(['spawning', 'active', 'completing', 'terminated']).optional() .describe('Filter by status'), limit: z.number().default(50) .describe('Maximum results to return'), }); const registerSwarmSchema = z.object({ swarmId: z.string() .describe('Unique swarm identifier'), name: z.string() .describe('Human-readable swarm name'), capabilities: z.array(z.string()) .describe('Swarm capabilities'), maxAgents: z.number().default(100) .describe('Maximum agents this swarm can handle'), endpoint: z.string().optional() .describe('Swarm communication endpoint'), }); const broadcastSchema = z.object({ sourceSwarmId: z.string() .describe('Source swarm ID'), message: z.unknown() .describe('Message payload to broadcast'), }); const proposeSchema = z.object({ proposerId: z.string() .describe('Proposer swarm ID'), type: z.string() .describe('Proposal type'), value: z.unknown() .describe('Proposal value'), timeoutMs: z.number().default(30000) .describe('Proposal timeout in milliseconds'), }); const voteSchema = z.object({ swarmId: z.string() .describe('Voting swarm ID'), proposalId: z.string() .describe('Proposal ID to vote on'), approve: z.boolean() .describe('Whether to approve the proposal'), }); // ============================================================================ // Global Hub Instance // ============================================================================ let hubInstance = null; function getHub() { if (!hubInstance) { hubInstance = getDefaultFederationHub(); } return hubInstance; } // ============================================================================ // Tool Handlers // ============================================================================ /** * Get federation status */ async function handleFederationStatus(input, context) { const hub = getHub(); const stats = hub.getStats(); const swarms = hub.getSwarms(); return { stats, swarms: swarms.map(s => ({ swarmId: s.swarmId, name: s.name, status: s.status, agentCount: s.currentAgents, maxAgents: s.maxAgents, })), }; } /** * Spawn an ephemeral agent */ async function handleSpawnEphemeral(input, context) { const hub = getHub(); return hub.spawnEphemeralAgent({ type: input.type, task: input.task, swarmId: input.swarmId, ttl: input.ttl, capabilities: input.capabilities, priority: input.priority, waitForCompletion: input.waitForCompletion, completionTimeout: input.completionTimeout, }); } /** * Terminate an ephemeral agent */ async function handleTerminateEphemeral(input, context) { const hub = getHub(); const error = input.reason ? new Error(input.reason) : undefined; const terminated = await hub.terminateAgent(input.agentId, error); return { terminated, agentId: input.agentId, reason: input.reason, }; } /** * List ephemeral agents */ async function handleListEphemeral(input, context) { const hub = getHub(); let agents = hub.getAgents(input.swarmId); // Filter by status if (input.status) { agents = agents.filter(a => a.status === input.status); } // Limit results agents = agents.slice(0, input.limit); return { agents: agents.map(a => ({ id: a.id, swarmId: a.swarmId, type: a.type, task: a.task, status: a.status, ttl: a.ttl, createdAt: a.createdAt.toISOString(), expiresAt: a.expiresAt.toISOString(), })), total: agents.length, }; } /** * Register a swarm with the federation */ async function handleRegisterSwarm(input, context) { const hub = getHub(); hub.registerSwarm({ swarmId: input.swarmId, name: input.name, capabilities: input.capabilities, maxAgents: input.maxAgents, currentAgents: 0, status: 'active', endpoint: input.endpoint, }); return { registered: true, swarmId: input.swarmId, }; } /** * Broadcast message to all swarms */ async function handleBroadcast(input, context) { const hub = getHub(); const sent = await hub.broadcast(input.sourceSwarmId, input.message); return { sent, sourceSwarmId: input.sourceSwarmId, }; } /** * Propose federation-wide consensus */ async function handlePropose(input, context) { const hub = getHub(); const proposal = await hub.propose(input.proposerId, input.type, input.value, input.timeoutMs); return { proposalId: proposal.id, status: proposal.status, expiresAt: proposal.expiresAt.toISOString(), }; } /** * Vote on a consensus proposal */ async function handleVote(input, context) { const hub = getHub(); const voted = hub.vote(input.swarmId, input.proposalId, input.approve); return { voted, proposalId: input.proposalId, swarmId: input.swarmId, approve: input.approve, }; } // ============================================================================ // Tool Definitions // ============================================================================ export const federationStatusTool = { name: 'federation/status', description: 'Get federation hub status including swarms and ephemeral agents', inputSchema: { type: 'object', properties: {}, }, handler: async (input, context) => { return handleFederationStatus({}, context); }, category: 'federation', tags: ['federation', 'status', 'monitoring'], version: '1.0.0', cacheable: true, cacheTTL: 5000, }; export const spawnEphemeralTool = { name: 'federation/spawn-ephemeral', description: 'Spawn an ephemeral agent for a short-lived task', inputSchema: { type: 'object', properties: { type: { type: 'string', description: 'Agent type', }, task: { type: 'string', description: 'Task description', }, swarmId: { type: 'string', description: 'Target swarm ID (optional)', }, ttl: { type: 'number', description: 'Time-to-live in milliseconds', }, capabilities: { type: 'array', items: { type: 'string' }, description: 'Required capabilities', }, priority: { type: 'string', enum: ['low', 'normal', 'high', 'critical'], description: 'Priority for swarm selection', default: 'normal', }, waitForCompletion: { type: 'boolean', description: 'Wait for agent completion', default: false, }, completionTimeout: { type: 'number', description: 'Completion timeout (ms)', }, }, required: ['type', 'task'], }, handler: async (input, context) => { const validated = spawnEphemeralSchema.parse(input); return handleSpawnEphemeral(validated, context); }, category: 'federation', tags: ['federation', 'ephemeral', 'spawn', 'agent'], version: '1.0.0', }; export const terminateEphemeralTool = { name: 'federation/terminate-ephemeral', description: 'Terminate an ephemeral agent', inputSchema: { type: 'object', properties: { agentId: { type: 'string', description: 'Ephemeral agent ID', }, reason: { type: 'string', description: 'Termination reason', }, }, required: ['agentId'], }, handler: async (input, context) => { const validated = terminateEphemeralSchema.parse(input); return handleTerminateEphemeral(validated, context); }, category: 'federation', tags: ['federation', 'ephemeral', 'terminate', 'agent'], version: '1.0.0', }; export const listEphemeralTool = { name: 'federation/list-ephemeral', description: 'List ephemeral agents in the federation', inputSchema: { type: 'object', properties: { swarmId: { type: 'string', description: 'Filter by swarm ID', }, status: { type: 'string', enum: ['spawning', 'active', 'completing', 'terminated'], description: 'Filter by status', }, limit: { type: 'number', description: 'Maximum results', default: 50, }, }, }, handler: async (input, context) => { const validated = listEphemeralSchema.parse(input); return handleListEphemeral(validated, context); }, category: 'federation', tags: ['federation', 'ephemeral', 'list', 'agent'], version: '1.0.0', cacheable: true, cacheTTL: 2000, }; export const registerSwarmTool = { name: 'federation/register-swarm', description: 'Register a swarm with the federation hub', inputSchema: { type: 'object', properties: { swarmId: { type: 'string', description: 'Unique swarm identifier', }, name: { type: 'string', description: 'Human-readable swarm name', }, capabilities: { type: 'array', items: { type: 'string' }, description: 'Swarm capabilities', }, maxAgents: { type: 'number', description: 'Maximum agents', default: 100, }, endpoint: { type: 'string', description: 'Communication endpoint', }, }, required: ['swarmId', 'name', 'capabilities'], }, handler: async (input, context) => { const validated = registerSwarmSchema.parse(input); return handleRegisterSwarm(validated, context); }, category: 'federation', tags: ['federation', 'swarm', 'register'], version: '1.0.0', }; export const broadcastTool = { name: 'federation/broadcast', description: 'Broadcast a message to all swarms in the federation', inputSchema: { type: 'object', properties: { sourceSwarmId: { type: 'string', description: 'Source swarm ID', }, message: { description: 'Message payload', }, }, required: ['sourceSwarmId', 'message'], }, handler: async (input, context) => { const validated = broadcastSchema.parse(input); return handleBroadcast(validated, context); }, category: 'federation', tags: ['federation', 'broadcast', 'message'], version: '1.0.0', }; export const proposeTool = { name: 'federation/propose', description: 'Propose a value for federation-wide consensus', inputSchema: { type: 'object', properties: { proposerId: { type: 'string', description: 'Proposer swarm ID', }, type: { type: 'string', description: 'Proposal type', }, value: { description: 'Proposal value', }, timeoutMs: { type: 'number', description: 'Proposal timeout (ms)', default: 30000, }, }, required: ['proposerId', 'type', 'value'], }, handler: async (input, context) => { const validated = proposeSchema.parse(input); return handlePropose(validated, context); }, category: 'federation', tags: ['federation', 'consensus', 'propose'], version: '1.0.0', }; export const voteTool = { name: 'federation/vote', description: 'Vote on a federation consensus proposal', inputSchema: { type: 'object', properties: { swarmId: { type: 'string', description: 'Voting swarm ID', }, proposalId: { type: 'string', description: 'Proposal ID', }, approve: { type: 'boolean', description: 'Approve or reject', }, }, required: ['swarmId', 'proposalId', 'approve'], }, handler: async (input, context) => { const validated = voteSchema.parse(input); return handleVote(validated, context); }, category: 'federation', tags: ['federation', 'consensus', 'vote'], version: '1.0.0', }; // ============================================================================ // Exports // ============================================================================ export const federationTools = [ federationStatusTool, spawnEphemeralTool, terminateEphemeralTool, listEphemeralTool, registerSwarmTool, broadcastTool, proposeTool, voteTool, ]; export default federationTools; //# sourceMappingURL=federation-tools.js.map