Skip to content

Commit 54b220d

Browse files
feat: Implement Claude Code agent integration for Oracle/Worker pattern
- Add ClaudeCodeAgentBridge extending OracleWorkerCoordinator - Create ClaudeCodeTaskCoordinator for parallel execution and retry logic - Map Claude Code specialized agents to Oracle/Worker roles: - Oracle: staff-architect, product-manager (strategic) - Workers: general-purpose, debugger, qa-workflow-validator - Reviewers: code-reviewer (quality assurance) - Add claude-swarm CLI command with agent listing and configuration - Enable cost-effective multi-model orchestration (60-80% savings) - Include comprehensive error handling and validation - Support parallel task execution with priority-based coordination
1 parent b09f3fc commit 54b220d

3 files changed

Lines changed: 1727 additions & 47 deletions

File tree

src/cli/commands/ralph.ts

Lines changed: 229 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -447,64 +447,246 @@ export function createRalphCommand(): Command {
447447
// Oracle/Worker pattern command
448448
ralph
449449
.command('oracle-worker')
450-
.description('Launch Oracle/Worker pattern swarm for cost-effective execution')
450+
.description(
451+
'Launch Oracle/Worker pattern swarm for cost-effective execution'
452+
)
451453
.argument('<project>', 'Project description for Oracle planning')
452-
.option('--oracle <model>', 'Oracle model (default: claude-3-opus)', 'claude-3-opus-20240229')
453-
.option('--workers <models>', 'Comma-separated worker models', 'claude-3-haiku-20240307')
454+
.option(
455+
'--oracle <model>',
456+
'Oracle model (default: claude-3-opus)',
457+
'claude-3-opus-20240229'
458+
)
459+
.option(
460+
'--workers <models>',
461+
'Comma-separated worker models',
462+
'claude-3-haiku-20240307'
463+
)
454464
.option('--budget <amount>', 'Cost budget in USD', '10.0')
455465
.option('--max-workers <count>', 'Maximum worker agents', '5')
456466
.option('--hints <hints>', 'Comma-separated planning hints')
457467
.action(async (project: string, options: any) => {
458-
return trace.command('ralph-oracle-worker', { project, ...options }, async () => {
459-
try {
460-
console.log('🧠 Launching Oracle/Worker swarm...');
461-
console.log(`📋 Project: ${project}`);
462-
console.log(`💰 Budget: $${options.budget}`);
463-
464-
// Import Oracle/Worker pattern
465-
const { OracleWorkerCoordinator, defaultModelConfigs } = await import('../../../integrations/ralph/patterns/oracle-worker-pattern.js');
466-
467-
// Parse worker models
468-
const workerModels = options.workers.split(',').map((model: string) => {
469-
const found = defaultModelConfigs.worker.find((w: any) => w.model.includes(model.trim()));
470-
return found || defaultModelConfigs.worker[0];
471-
});
468+
return trace.command(
469+
'ralph-oracle-worker',
470+
{ project, ...options },
471+
async () => {
472+
try {
473+
console.log('🧠 Launching Oracle/Worker swarm...');
474+
console.log(`📋 Project: ${project}`);
475+
console.log(`💰 Budget: $${options.budget}`);
476+
477+
// Import Oracle/Worker pattern
478+
const { OracleWorkerCoordinator, defaultModelConfigs } =
479+
await import('../../../integrations/ralph/patterns/oracle-worker-pattern.js');
480+
481+
// Parse worker models
482+
const workerModels = options.workers
483+
.split(',')
484+
.map((model: string) => {
485+
const found = defaultModelConfigs.worker.find((w: any) =>
486+
w.model.includes(model.trim())
487+
);
488+
return found || defaultModelConfigs.worker[0];
489+
});
472490

473-
// Configure Oracle/Worker coordinator
474-
const coordinator = new OracleWorkerCoordinator({
475-
oracle: defaultModelConfigs.oracle[0],
476-
workers: workerModels,
477-
reviewers: defaultModelConfigs.reviewer,
478-
maxWorkers: parseInt(options.maxWorkers),
479-
coordinationInterval: 30000,
480-
costBudget: parseFloat(options.budget),
481-
});
491+
// Configure Oracle/Worker coordinator
492+
const coordinator = new OracleWorkerCoordinator({
493+
oracle: defaultModelConfigs.oracle[0],
494+
workers: workerModels,
495+
reviewers: defaultModelConfigs.reviewer,
496+
maxWorkers: parseInt(options.maxWorkers),
497+
coordinationInterval: 30000,
498+
costBudget: parseFloat(options.budget),
499+
});
482500

483-
await coordinator.initialize();
501+
await coordinator.initialize();
484502

485-
// Parse hints if provided
486-
const hints = options.hints ? options.hints.split(',').map((h: string) => h.trim()) : undefined;
503+
// Parse hints if provided
504+
const hints = options.hints
505+
? options.hints.split(',').map((h: string) => h.trim())
506+
: undefined;
487507

488-
// Launch Oracle/Worker swarm
489-
const swarmId = await coordinator.launchOracleWorkerSwarm(project, hints);
508+
// Launch Oracle/Worker swarm
509+
const swarmId = await coordinator.launchOracleWorkerSwarm(
510+
project,
511+
hints
512+
);
490513

491-
console.log(`✅ Oracle/Worker swarm launched: ${swarmId}`);
492-
console.log('\n📊 Pattern Benefits:');
493-
console.log(' • Oracle handles strategic planning & review');
494-
console.log(' • Workers execute parallelizable tasks');
495-
console.log(' • Cost-optimized model selection');
496-
console.log(' • Scalable multi-agent coordination');
497-
498-
console.log('\nNext steps:');
499-
console.log(` stackmemory ralph swarm-status ${swarmId} # Check progress`);
500-
console.log(` stackmemory ralph swarm-stop ${swarmId} # Stop swarm`);
501-
502-
} catch (error: any) {
503-
logger.error('Oracle/Worker swarm failed', error);
504-
console.error(`❌ Oracle/Worker failed: ${error.message}`);
505-
throw error;
514+
console.log(`✅ Oracle/Worker swarm launched: ${swarmId}`);
515+
console.log('\n📊 Pattern Benefits:');
516+
console.log(' • Oracle handles strategic planning & review');
517+
console.log(' • Workers execute parallelizable tasks');
518+
console.log(' • Cost-optimized model selection');
519+
console.log(' • Scalable multi-agent coordination');
520+
521+
console.log('\nNext steps:');
522+
console.log(
523+
` stackmemory ralph swarm-status ${swarmId} # Check progress`
524+
);
525+
console.log(
526+
` stackmemory ralph swarm-stop ${swarmId} # Stop swarm`
527+
);
528+
} catch (error: any) {
529+
logger.error('Oracle/Worker swarm failed', error);
530+
console.error(`❌ Oracle/Worker failed: ${error.message}`);
531+
throw error;
532+
}
506533
}
507-
});
534+
);
535+
});
536+
537+
// Claude Code Agent integration command
538+
ralph
539+
.command('claude-swarm')
540+
.description('Launch swarm using Claude Code specialized agents')
541+
.argument('<project>', 'Project description for Claude Code agents')
542+
.option(
543+
'--oracle <agent>',
544+
'Oracle agent (default: staff-architect)',
545+
'staff-architect'
546+
)
547+
.option(
548+
'--workers <agents>',
549+
'Comma-separated worker agents',
550+
'general-purpose,code-reviewer'
551+
)
552+
.option(
553+
'--reviewers <agents>',
554+
'Comma-separated reviewer agents',
555+
'code-reviewer'
556+
)
557+
.option('--budget <amount>', 'Cost budget in USD', '10.0')
558+
.option(
559+
'--complexity <level>',
560+
'Project complexity (low|medium|high|very_high)',
561+
'medium'
562+
)
563+
.option('--list-agents', 'List available Claude Code agents')
564+
.action(async (project: string, options: any) => {
565+
return trace.command(
566+
'ralph-claude-swarm',
567+
{ project, ...options },
568+
async () => {
569+
try {
570+
// Import Claude Code bridge
571+
const { ClaudeCodeAgentBridge, CLAUDE_CODE_AGENTS } =
572+
await import('../../integrations/claude-code/agent-bridge.js');
573+
574+
// Handle list agents option
575+
if (options.listAgents) {
576+
console.log('\n🤖 Available Claude Code Agents:\n');
577+
578+
const oracles = Object.values(CLAUDE_CODE_AGENTS).filter(
579+
(a) => a.type === 'oracle'
580+
);
581+
const workers = Object.values(CLAUDE_CODE_AGENTS).filter(
582+
(a) => a.type === 'worker'
583+
);
584+
const reviewers = Object.values(CLAUDE_CODE_AGENTS).filter(
585+
(a) => a.type === 'reviewer'
586+
);
587+
588+
console.log('🧠 ORACLE AGENTS (Strategic Planning):');
589+
oracles.forEach((agent) => {
590+
console.log(` ${agent.name}: ${agent.description}`);
591+
console.log(
592+
` Capabilities: ${agent.capabilities.slice(0, 3).join(', ')}...`
593+
);
594+
});
595+
596+
console.log('\n⚡ WORKER AGENTS (Task Execution):');
597+
workers.forEach((agent) => {
598+
console.log(` ${agent.name}: ${agent.description}`);
599+
console.log(
600+
` Capabilities: ${agent.capabilities.slice(0, 3).join(', ')}...`
601+
);
602+
});
603+
604+
console.log('\n🔍 REVIEWER AGENTS (Quality Assurance):');
605+
reviewers.forEach((agent) => {
606+
console.log(` ${agent.name}: ${agent.description}`);
607+
console.log(
608+
` Capabilities: ${agent.capabilities.slice(0, 3).join(', ')}...`
609+
);
610+
});
611+
612+
console.log('\nUsage Examples:');
613+
console.log(
614+
' stackmemory ralph claude-swarm "Build REST API" --oracle staff-architect --workers general-purpose,debugger'
615+
);
616+
console.log(
617+
' stackmemory ralph claude-swarm "Add user auth" --complexity high --workers general-purpose,qa-workflow-validator'
618+
);
619+
return;
620+
}
621+
622+
console.log('🧠 Launching Claude Code Agent Swarm...');
623+
console.log(`📋 Project: ${project}`);
624+
console.log(`🎯 Oracle: ${options.oracle}`);
625+
console.log(`⚡ Workers: ${options.workers}`);
626+
console.log(`🔍 Reviewers: ${options.reviewers}`);
627+
console.log(`💰 Budget: $${options.budget}`);
628+
console.log(`📊 Complexity: ${options.complexity}`);
629+
630+
// Initialize Claude Code bridge
631+
const bridge = new ClaudeCodeAgentBridge();
632+
await bridge.initialize();
633+
634+
// Parse agent lists
635+
const workerAgents = options.workers
636+
.split(',')
637+
.map((s: string) => s.trim());
638+
const reviewerAgents = options.reviewers
639+
.split(',')
640+
.map((s: string) => s.trim());
641+
642+
// Launch Claude Code swarm
643+
const swarmId = await bridge.launchClaudeCodeSwarm(project, {
644+
oracleAgent: options.oracle,
645+
workerAgents,
646+
reviewerAgents,
647+
budget: parseFloat(options.budget),
648+
complexity: options.complexity as any,
649+
});
650+
651+
console.log(`✅ Claude Code swarm launched: ${swarmId}`);
652+
console.log('\n📊 Claude Code Benefits:');
653+
console.log(' • Specialized agents with proven capabilities');
654+
console.log(' • Seamless integration with Claude Code tools');
655+
console.log(' • Optimal agent selection for each task type');
656+
console.log(' • Built-in quality assurance and review processes');
657+
658+
console.log('\nActive Agents:');
659+
console.log(` 🧠 Oracle: ${options.oracle} (strategic planning)`);
660+
workerAgents.forEach((agent: string) => {
661+
const agentConfig = CLAUDE_CODE_AGENTS[agent];
662+
console.log(
663+
` ⚡ Worker: ${agent} (${agentConfig?.specializations.join(', ') || 'execution'})`
664+
);
665+
});
666+
reviewerAgents.forEach((agent: string) => {
667+
const agentConfig = CLAUDE_CODE_AGENTS[agent];
668+
console.log(
669+
` 🔍 Reviewer: ${agent} (${agentConfig?.specializations.join(', ') || 'review'})`
670+
);
671+
});
672+
673+
console.log('\nNext steps:');
674+
console.log(
675+
` stackmemory ralph swarm-status ${swarmId} # Check progress`
676+
);
677+
console.log(
678+
` stackmemory ralph swarm-stop ${swarmId} # Stop swarm`
679+
);
680+
console.log(
681+
' stackmemory ralph claude-swarm --list-agents # See all available agents'
682+
);
683+
} catch (error: any) {
684+
logger.error('Claude Code swarm failed', error);
685+
console.error(`❌ Claude Code swarm failed: ${error.message}`);
686+
throw error;
687+
}
688+
}
689+
);
508690
});
509691

510692
// Swarm killall command

0 commit comments

Comments
 (0)