devflow-ai
Version:
Enterprise-grade AI agent orchestration with swarm management UI dashboard
775 lines (675 loc) • 22.9 kB
text/typescript
/**
* Queen Coordinator Class
*
* The Queen manages high-level coordination, decision-making,
* and strategic planning for the Hive Mind swarm.
*/
import { EventEmitter } from 'events';
import { v4 as uuidv4 } from 'uuid';
import { Agent } from './Agent.js';
import { DatabaseManager } from './DatabaseManager.js';
import { MCPToolWrapper } from '../integration/MCPToolWrapper.js';
import {
SwarmTopology,
Task,
AgentType,
QueenMode,
ConsensusProposal,
QueenDecision,
CoordinationStrategy,
} from '../types.js';
interface QueenConfig {
swarmId: string;
mode: QueenMode;
topology: SwarmTopology;
}
export class Queen extends EventEmitter {
private id: string;
private config: QueenConfig;
private agents: Map<string, Agent>;
private taskQueue: Map<string, Task>;
private strategies: Map<string, CoordinationStrategy>;
private db: DatabaseManager;
private mcpWrapper: MCPToolWrapper;
private isActive: boolean = false;
constructor(config: QueenConfig) {
super();
this.id = uuidv4();
this.config = config;
this.agents = new Map();
this.taskQueue = new Map();
this.strategies = new Map();
this.initializeStrategies();
}
/**
* Initialize the Queen and her coordination capabilities
*/
async initialize(): Promise<void> {
this.db = await DatabaseManager.getInstance();
this.mcpWrapper = new MCPToolWrapper();
// Create Queen as a special coordinator agent
await this.db.createAgent({
id: this.id,
swarmId: this.config.swarmId,
name: 'Queen',
type: 'coordinator',
capabilities: JSON.stringify([
'strategic_planning',
'task_allocation',
'consensus_coordination',
'performance_optimization',
'swarm_governance',
]),
status: 'active',
metadata: JSON.stringify({ role: 'queen', mode: this.config.mode }),
});
this.isActive = true;
// Start coordination loops
this.startCoordinationLoop();
this.startOptimizationLoop();
this.emit('initialized');
}
/**
* Register a new agent with the Queen
*/
async registerAgent(agent: Agent): Promise<void> {
this.agents.set(agent.id, agent);
// Analyze agent capabilities and update strategies
await this.analyzeAgentCapabilities(agent);
// Notify other agents in distributed mode
if (this.config.mode === 'distributed') {
await this.broadcastAgentRegistration(agent);
}
this.emit('agentRegistered', { agent });
}
/**
* Handle task submission
*/
async onTaskSubmitted(task: Task): Promise<QueenDecision> {
this.taskQueue.set(task.id, task);
// Analyze task requirements
const analysis = await this.analyzeTask(task);
// Make strategic decision
const decision = await this.makeStrategicDecision(task, analysis);
// If consensus required, initiate consensus process
if (task.requireConsensus) {
await this.initiateConsensus(task, decision);
}
// Apply decision
await this.applyDecision(decision);
this.emit('taskDecision', { task, decision });
return decision;
}
/**
* Make a strategic decision about task execution
*/
private async makeStrategicDecision(task: Task, analysis: any): Promise<QueenDecision> {
// Use MCP neural capabilities for decision making
const neuralAnalysis = await this.mcpWrapper.analyzePattern({
action: 'analyze',
operation: 'task_strategy',
metadata: {
task: task.description,
priority: task.priority,
topology: this.config.topology,
availableAgents: this.getAvailableAgents().length,
},
});
// Select optimal strategy
const strategy = this.selectOptimalStrategy(task, analysis, neuralAnalysis);
// Identify best agents for the task
const selectedAgents = await this.selectAgentsForTask(task, strategy);
// Create execution plan
const executionPlan = this.createExecutionPlan(task, selectedAgents, strategy);
return {
id: uuidv4(),
taskId: task.id,
strategy,
selectedAgents: selectedAgents.map((a) => a.id),
executionPlan,
confidence: analysis.confidence || 0.85,
rationale: analysis.rationale || 'Strategic analysis completed',
timestamp: new Date(),
};
}
/**
* Select optimal coordination strategy
*/
private selectOptimalStrategy(
task: Task,
analysis: any,
neuralAnalysis: any,
): CoordinationStrategy {
// Strategy selection based on multiple factors
const factors = {
taskComplexity: analysis.complexity || 'medium',
agentAvailability: this.getAvailableAgents().length,
topology: this.config.topology,
priority: task.priority,
consensusRequired: task.requireConsensus,
};
// Use topology-specific strategies
if (this.config.topology === 'hierarchical' && factors.taskComplexity === 'high') {
return this.strategies.get('hierarchical-cascade')!;
}
if (this.config.topology === 'mesh' && factors.consensusRequired) {
return this.strategies.get('mesh-consensus')!;
}
if (factors.priority === 'critical') {
return this.strategies.get('priority-fast-track')!;
}
// Default adaptive strategy
return this.strategies.get('adaptive-default')!;
}
/**
* Select best agents for a task
*/
private async selectAgentsForTask(task: Task, strategy: CoordinationStrategy): Promise<Agent[]> {
const availableAgents = this.getAvailableAgents();
const requiredCapabilities = task.requiredCapabilities || [];
// Score agents based on capabilities and current load
const scoredAgents = await Promise.all(
availableAgents.map(async (agent) => {
const score = await this.scoreAgentForTask(agent, task, requiredCapabilities);
return { agent, score };
}),
);
// Sort by score and select top agents
scoredAgents.sort((a, b) => b.score - a.score);
const maxAgents = Math.min(task.maxAgents, strategy.maxAgents || 3);
return scoredAgents.slice(0, maxAgents).map((sa) => sa.agent);
}
/**
* Score an agent for a specific task
*/
private async scoreAgentForTask(
agent: Agent,
task: Task,
requiredCapabilities: string[],
): Promise<number> {
let score = 0;
// Capability match
const capabilityMatches = requiredCapabilities.filter((cap) =>
agent.capabilities.includes(cap),
).length;
score += capabilityMatches * 10;
// Agent type suitability
const typeSuitability = this.getTypeSuitabilityForTask(agent.type, task);
score += typeSuitability * 5;
// Current workload (prefer less busy agents)
if (agent.status === 'idle') score += 8;
else if (agent.status === 'active') score += 4;
// Historical performance (from database)
const performance = await this.db.getAgentPerformance(agent.id);
if (performance) {
score += performance.successRate * 10;
}
// Specialty bonus
if (agent.type === 'specialist' && requiredCapabilities.length > 0) {
score += 5;
}
return score;
}
/**
* Get type suitability score for a task
*/
private getTypeSuitabilityForTask(agentType: AgentType, task: Task): number {
const suitabilityMap: Record<string, Record<AgentType, number>> = {
research: {
researcher: 10,
analyst: 8,
specialist: 6,
coder: 4,
coordinator: 5,
architect: 5,
tester: 3,
reviewer: 4,
optimizer: 4,
documenter: 6,
monitor: 3,
},
development: {
coder: 10,
architect: 8,
tester: 7,
reviewer: 6,
coordinator: 5,
specialist: 6,
researcher: 4,
analyst: 4,
optimizer: 5,
documenter: 4,
monitor: 3,
},
analysis: {
analyst: 10,
researcher: 8,
specialist: 6,
reviewer: 5,
coordinator: 5,
architect: 4,
coder: 4,
tester: 3,
optimizer: 5,
documenter: 4,
monitor: 4,
},
testing: {
tester: 10,
reviewer: 8,
analyst: 6,
coder: 5,
coordinator: 4,
specialist: 5,
researcher: 3,
architect: 4,
optimizer: 4,
documenter: 3,
monitor: 4,
},
optimization: {
optimizer: 10,
analyst: 8,
coder: 7,
architect: 6,
coordinator: 5,
specialist: 6,
researcher: 4,
tester: 4,
reviewer: 5,
documenter: 3,
monitor: 4,
},
};
// Detect task type from description
const taskType = this.detectTaskType(task.description);
return suitabilityMap[taskType]?.[agentType] || 5;
}
/**
* Detect task type from description
*/
private detectTaskType(description: string): string {
const lower = description.toLowerCase();
if (lower.includes('research') || lower.includes('investigate') || lower.includes('explore')) {
return 'research';
}
if (
lower.includes('develop') ||
lower.includes('implement') ||
lower.includes('build') ||
lower.includes('create')
) {
return 'development';
}
if (lower.includes('analyze') || lower.includes('review') || lower.includes('assess')) {
return 'analysis';
}
if (lower.includes('test') || lower.includes('validate') || lower.includes('verify')) {
return 'testing';
}
if (lower.includes('optimize') || lower.includes('improve') || lower.includes('enhance')) {
return 'optimization';
}
return 'general';
}
/**
* Create execution plan for task
*/
private createExecutionPlan(task: Task, agents: Agent[], strategy: CoordinationStrategy): any {
return {
phases: strategy.phases || ['preparation', 'execution', 'validation'],
agentAssignments: agents.map((agent) => ({
agentId: agent.id,
role: this.determineAgentRole(agent, task),
responsibilities: this.getAgentResponsibilities(agent, task),
})),
coordinationPoints: strategy.coordinationPoints || ['start', 'midpoint', 'completion'],
checkpoints: this.createCheckpoints(task, strategy),
fallbackPlan: this.createFallbackPlan(task, agents),
};
}
/**
* Initiate consensus process
*/
private async initiateConsensus(task: Task, decision: QueenDecision): Promise<void> {
const proposal: ConsensusProposal = {
id: uuidv4(),
swarmId: this.config.swarmId,
taskId: task.id,
proposal: {
decision,
task: task.description,
rationale: decision.rationale,
},
requiredThreshold: 0.66,
deadline: new Date(Date.now() + 5 * 60 * 1000), // 5 minutes
};
await this.db.createConsensusProposal(proposal);
// Notify all agents to vote
await this.broadcastConsensusRequest(proposal);
}
/**
* Apply Queen's decision
*/
private async applyDecision(decision: QueenDecision): Promise<void> {
// Update task with assignments
await this.db.updateTask(decision.taskId, {
assigned_agents: JSON.stringify(decision.selectedAgents),
status: 'assigned',
assigned_at: new Date(),
});
// Notify selected agents
for (const agentId of decision.selectedAgents) {
const agent = this.agents.get(agentId);
if (agent) {
await agent.assignTask(decision.taskId, decision.executionPlan);
}
}
// Store decision in memory for learning
await this.mcpWrapper.storeMemory({
action: 'store',
key: `decision/${decision.taskId}`,
value: JSON.stringify(decision),
namespace: 'queen-decisions',
ttl: 86400 * 7, // 7 days
});
}
/**
* Start coordination loop
*/
private startCoordinationLoop(): void {
setInterval(async () => {
if (!this.isActive) return;
try {
// Monitor agent health
await this.monitorAgentHealth();
// Check task progress
await this.checkTaskProgress();
// Rebalance if needed
await this.checkRebalancing();
} catch (error) {
this.emit('error', error);
}
}, 5000); // Every 5 seconds
}
/**
* Start optimization loop
*/
private startOptimizationLoop(): void {
setInterval(async () => {
if (!this.isActive) return;
try {
// Analyze performance patterns
await this.analyzePerformancePatterns();
// Optimize strategies
await this.optimizeStrategies();
// Train neural patterns
await this.trainNeuralPatterns();
} catch (error) {
this.emit('error', error);
}
}, 60000); // Every minute
}
/**
* Initialize coordination strategies
*/
private initializeStrategies(): void {
// Hierarchical cascade strategy
this.strategies.set('hierarchical-cascade', {
name: 'Hierarchical Cascade',
description: 'Top-down task distribution with clear delegation',
phases: ['planning', 'delegation', 'execution', 'aggregation'],
maxAgents: 5,
coordinationPoints: ['phase-transition', 'milestone', 'completion'],
suitable_for: ['complex-tasks', 'multi-phase-projects'],
});
// Mesh consensus strategy
this.strategies.set('mesh-consensus', {
name: 'Mesh Consensus',
description: 'Peer-to-peer coordination with consensus requirements',
phases: ['proposal', 'discussion', 'consensus', 'execution'],
maxAgents: 7,
coordinationPoints: ['consensus-check', 'progress-sync', 'final-vote'],
suitable_for: ['critical-decisions', 'collaborative-tasks'],
});
// Priority fast-track strategy
this.strategies.set('priority-fast-track', {
name: 'Priority Fast Track',
description: 'Rapid execution for critical tasks',
phases: ['immediate-assignment', 'parallel-execution', 'quick-validation'],
maxAgents: 3,
coordinationPoints: ['start', 'critical-path', 'completion'],
suitable_for: ['urgent-tasks', 'critical-fixes'],
});
// Adaptive default strategy
this.strategies.set('adaptive-default', {
name: 'Adaptive Default',
description: 'Flexible strategy that adapts to task requirements',
phases: ['analysis', 'planning', 'execution', 'review'],
maxAgents: 4,
coordinationPoints: ['checkpoint', 'adaptation-point', 'completion'],
suitable_for: ['general-tasks', 'unknown-complexity'],
});
}
/**
* Helper methods
*/
private getAvailableAgents(): Agent[] {
return Array.from(this.agents.values()).filter(
(agent) => agent.status === 'idle' || agent.status === 'active',
);
}
private async analyzeTask(task: Task): Promise<any> {
// Use MCP tools to analyze task complexity and requirements
return this.mcpWrapper.analyzePattern({
action: 'analyze',
operation: 'task_analysis',
metadata: {
description: task.description,
priority: task.priority,
dependencies: task.dependencies,
},
});
}
private async analyzeAgentCapabilities(agent: Agent): Promise<void> {
// Analyze and store agent capability patterns
await this.mcpWrapper.storeMemory({
action: 'store',
key: `agent-capabilities/${agent.id}`,
value: JSON.stringify({
type: agent.type,
capabilities: agent.capabilities,
registeredAt: new Date(),
}),
namespace: 'agent-registry',
});
}
private async broadcastAgentRegistration(agent: Agent): Promise<void> {
// In distributed mode, notify other Queens/coordinators
await this.db.createCommunication({
from_agent_id: this.id,
to_agent_id: null, // broadcast
swarm_id: this.config.swarmId,
message_type: 'broadcast',
content: JSON.stringify({
type: 'agent_registered',
agent: {
id: agent.id,
type: agent.type,
capabilities: agent.capabilities,
},
}),
priority: 'high',
});
}
private async broadcastConsensusRequest(proposal: ConsensusProposal): Promise<void> {
await this.db.createCommunication({
from_agent_id: this.id,
to_agent_id: null, // broadcast
swarm_id: this.config.swarmId,
message_type: 'consensus',
content: JSON.stringify(proposal),
priority: 'urgent',
requires_response: true,
});
}
private determineAgentRole(agent: Agent, task: Task): string {
// Determine specific role based on agent type and task
const roleMap: Record<AgentType, string> = {
coordinator: 'lead',
researcher: 'investigator',
coder: 'implementer',
analyst: 'evaluator',
architect: 'designer',
tester: 'validator',
reviewer: 'auditor',
optimizer: 'enhancer',
documenter: 'recorder',
monitor: 'observer',
specialist: 'expert',
};
return roleMap[agent.type] || 'contributor';
}
private getAgentResponsibilities(agent: Agent, task: Task): string[] {
// Define specific responsibilities based on role
const responsibilityMap: Record<AgentType, string[]> = {
coordinator: ['coordinate team', 'track progress', 'resolve conflicts'],
researcher: ['gather information', 'identify patterns', 'provide insights'],
coder: ['implement solution', 'write tests', 'debug issues'],
analyst: ['analyze data', 'identify bottlenecks', 'suggest improvements'],
architect: ['design system', 'define interfaces', 'ensure scalability'],
tester: ['write tests', 'find bugs', 'validate functionality'],
reviewer: ['review code', 'ensure quality', 'suggest improvements'],
optimizer: ['improve performance', 'reduce complexity', 'optimize resources'],
documenter: ['create documentation', 'update guides', 'maintain clarity'],
monitor: ['track metrics', 'alert on issues', 'ensure health'],
specialist: ['provide expertise', 'solve complex problems', 'guide implementation'],
};
return responsibilityMap[agent.type] || ['contribute to task'];
}
private createCheckpoints(task: Task, strategy: CoordinationStrategy): any[] {
return strategy.coordinationPoints.map((point, index) => ({
name: point,
expectedProgress: Math.round(((index + 1) / strategy.coordinationPoints.length) * 100),
actions: ['status_check', 'sync_progress', 'adjust_strategy'],
}));
}
private createFallbackPlan(task: Task, agents: Agent[]): any {
return {
triggers: ['agent_failure', 'deadline_approaching', 'consensus_failure'],
actions: [
'reassign_to_available_agents',
'escalate_to_queen',
'activate_backup_agents',
'simplify_task_requirements',
],
escalation_path: ['team_lead', 'queen', 'human_operator'],
};
}
private async monitorAgentHealth(): Promise<void> {
for (const agent of this.agents.values()) {
if (agent.status === 'error' || !agent.isResponsive()) {
await this.handleAgentFailure(agent);
}
}
}
private async checkTaskProgress(): Promise<void> {
const activeTasks = await this.db.getActiveTasks(this.config.swarmId);
for (const task of activeTasks) {
if (this.isTaskStalled(task)) {
await this.handleStalledTask(task);
}
}
}
private async checkRebalancing(): Promise<void> {
const stats = await this.db.getSwarmStats(this.config.swarmId);
if (stats.agentUtilization > 0.9 || stats.taskBacklog > stats.agentCount * 2) {
this.emit('rebalanceNeeded', stats);
}
}
private async analyzePerformancePatterns(): Promise<void> {
const patterns = await this.mcpWrapper.analyzePattern({
action: 'analyze',
operation: 'performance_patterns',
metadata: {
swarmId: this.config.swarmId,
timeframe: '1h',
},
});
if (patterns.recommendations) {
await this.applyPerformanceRecommendations(patterns.recommendations);
}
}
private async optimizeStrategies(): Promise<void> {
// Analyze strategy effectiveness and adjust
const strategyPerformance = await this.db.getStrategyPerformance(this.config.swarmId);
for (const [strategyName, performance] of Object.entries(strategyPerformance)) {
if (performance.successRate < 0.7) {
await this.adjustStrategy(strategyName, performance);
}
}
}
private async trainNeuralPatterns(): Promise<void> {
// Train neural network on successful patterns
const successfulDecisions = await this.db.getSuccessfulDecisions(this.config.swarmId);
if (successfulDecisions.length > 10) {
await this.mcpWrapper.trainNeural({
pattern_type: 'coordination',
training_data: JSON.stringify(successfulDecisions),
epochs: 50,
});
}
}
private async handleAgentFailure(agent: Agent): Promise<void> {
// Reassign agent's tasks
if (agent.currentTask) {
await this.reassignTask(agent.currentTask, agent.id);
}
// Mark agent as offline
await this.db.updateAgentStatus(agent.id, 'offline');
this.emit('agentFailed', { agent });
}
private async handleStalledTask(task: any): Promise<void> {
// Implement stalled task recovery
this.emit('taskStalled', { task });
}
private isTaskStalled(task: any): boolean {
// Check if task hasn't progressed in reasonable time
const stalledThreshold = 10 * 60 * 1000; // 10 minutes
return (
task.last_progress_update &&
Date.now() - new Date(task.last_progress_update).getTime() > stalledThreshold
);
}
private async reassignTask(taskId: string, fromAgentId: string): Promise<void> {
const availableAgents = this.getAvailableAgents().filter((a) => a.id !== fromAgentId);
if (availableAgents.length > 0) {
const newAgent = availableAgents[0]; // Simple selection, could be more sophisticated
await this.db.reassignTask(taskId, newAgent.id);
await newAgent.assignTask(taskId, {});
}
}
private async applyPerformanceRecommendations(recommendations: any[]): Promise<void> {
// Apply recommended optimizations
for (const rec of recommendations) {
this.emit('performanceRecommendation', rec);
}
}
private async adjustStrategy(strategyName: string, performance: any): Promise<void> {
const strategy = this.strategies.get(strategyName);
if (strategy) {
// Adjust strategy parameters based on performance
if (performance.avgCompletionTime > performance.targetTime) {
strategy.maxAgents = Math.min(strategy.maxAgents + 1, 10);
}
this.emit('strategyAdjusted', { strategyName, performance });
}
}
/**
* Shutdown the Queen
*/
async shutdown(): Promise<void> {
this.isActive = false;
this.emit('shutdown');
}
}