// AgentTeam – Phase 2 Week 5-6 // Role-based agent coordination system import { unifiedMemorySystem } from './UnifiedMemorySystem.js'; import { hybridSearchEngine } from './HybridSearchEngine.js'; import { emotionAwareDecisionEngine } from './EmotionAwareDecisionEngine.js'; import { unifiedGraphRAG } from './UnifiedGraphRAG.js'; import { stateGraphRouter, AgentState } from './StateGraphRouter.js'; import { projectMemory } from '../../services/project/ProjectMemory.js'; import { eventBus } from '../EventBus.js'; export type AgentRole = 'data' | 'security' | 'memory' | 'pal' | 'orchestrator'; export interface AgentMessage { from: AgentRole; to: AgentRole | 'all'; type: 'query' | 'task' | 'result' | 'alert' | 'coordinate'; content: string; metadata?: any; timestamp: Date; } export interface AgentCapabilities { canHandle: (message: AgentMessage) => boolean | Promise; execute: (message: AgentMessage) => Promise; getStatus: () => Promise; } export interface AgentStatus { role: AgentRole; active: boolean; tasksCompleted: number; lastActivity: Date; capabilities: string[]; } /** * Data Agent - Handles data ingestion, transformation, and quality */ class DataAgent implements AgentCapabilities { public readonly role: AgentRole = 'data'; private tasksCompleted = 0; private lastActivity = new Date(); canHandle(message: AgentMessage): boolean { return message.type === 'query' && ( message.content.includes('data') || message.content.includes('ingest') || message.content.includes('transform') || message.content.includes('quality') ); } async execute(message: AgentMessage): Promise { console.log(`📊 [DataAgent] Processing: ${message.content}`); this.lastActivity = new Date(); this.tasksCompleted++; // Use HybridSearchEngine to find relevant data const searchResults = await hybridSearchEngine.search(message.content, { userId: message.metadata?.userId || 'system', orgId: message.metadata?.orgId || 'default', limit: 10, timestamp: new Date() }); return { role: this.role, result: { dataFound: searchResults.length, sources: searchResults.map(r => ({ source: r.source, relevance: r.score })), quality: this.assessDataQuality(searchResults) } }; } private assessDataQuality(searchResults: any): { completeness: number; freshness: number; reliability: number; } { // Simple quality assessment const avgScore = searchResults.results.reduce((sum: number, r: any) => sum + r.score, 0) / searchResults.results.length || 0; return { completeness: Math.min(1.0, searchResults.results.length / 10), freshness: avgScore, reliability: avgScore * 0.9 }; } async getStatus(): Promise { return { role: this.role, active: true, tasksCompleted: this.tasksCompleted, lastActivity: this.lastActivity, capabilities: ['data_ingestion', 'data_quality', 'data_transformation'] }; } } /** * Security Agent - Handles security checks, threat detection, and compliance */ class SecurityAgent implements AgentCapabilities { public readonly role: AgentRole = 'security'; private tasksCompleted = 0; private lastActivity = new Date(); canHandle(message: AgentMessage): boolean { return message.type === 'query' && ( message.content.includes('security') || message.content.includes('threat') || message.content.includes('compliance') || message.content.includes('vulnerability') ) || message.type === 'alert'; } async execute(message: AgentMessage): Promise { console.log(`🔒 [SecurityAgent] Processing: ${message.content}`); this.lastActivity = new Date(); this.tasksCompleted++; // Use EmotionAwareDecisionEngine for security decisions const decision = await emotionAwareDecisionEngine.makeDecision( message.content, { orgId: message.metadata?.orgId || 'default', userId: message.metadata?.userId || 'system', boardId: message.metadata?.boardId } ); return { role: this.role, result: { threatLevel: this.assessThreatLevel(message.content), decision: decision, recommendations: this.generateSecurityRecommendations(message.content) } }; } private assessThreatLevel(content: string): 'low' | 'medium' | 'high' { const threatKeywords = ['vulnerability', 'breach', 'attack', 'malware', 'exploit']; const found = threatKeywords.filter(kw => content.toLowerCase().includes(kw)).length; if (found >= 2) return 'high'; if (found >= 1) return 'medium'; return 'low'; } private generateSecurityRecommendations(content: string): string[] { const recommendations: string[] = []; if (content.includes('vulnerability')) { recommendations.push('Run security scan'); recommendations.push('Review access controls'); } if (content.includes('compliance')) { recommendations.push('Verify GDPR compliance'); recommendations.push('Check data retention policies'); } return recommendations; } async getStatus(): Promise { return { role: this.role, active: true, tasksCompleted: this.tasksCompleted, lastActivity: this.lastActivity, capabilities: ['threat_detection', 'compliance_check', 'security_scan'] }; } } /** * Memory Agent - Handles memory operations, retrieval, and consolidation */ class MemoryAgent implements AgentCapabilities { public readonly role: AgentRole = 'memory'; private tasksCompleted = 0; private lastActivity = new Date(); canHandle(message: AgentMessage): boolean { return message.type === 'query' && ( message.content.includes('memory') || message.content.includes('remember') || message.content.includes('recall') || message.content.includes('forget') ); } async execute(message: AgentMessage): Promise { console.log(`🧠 [MemoryAgent] Processing: ${message.content}`); this.lastActivity = new Date(); this.tasksCompleted++; // Use UnifiedMemorySystem for memory operations const memory = await unifiedMemorySystem.getWorkingMemory({ userId: message.metadata?.userId || 'system', orgId: message.metadata?.orgId || 'default' }); // Use GraphRAG for memory retrieval const graphResult = await unifiedGraphRAG.query(message.content, { userId: message.metadata?.userId || 'system', orgId: message.metadata?.orgId || 'default' }); return { role: this.role, result: { workingMemory: memory, graphContext: graphResult, consolidation: await this.consolidateMemory(memory) } }; } private async consolidateMemory(memory: any): Promise<{ patterns: number; features: number; events: number; }> { return { patterns: memory.recentPatterns?.length || 0, features: memory.recentFeatures?.length || 0, events: memory.recentEvents?.length || 0 }; } async getStatus(): Promise { return { role: this.role, active: true, tasksCompleted: this.tasksCompleted, lastActivity: this.lastActivity, capabilities: ['memory_retrieval', 'memory_consolidation', 'pattern_detection'] }; } } /** * PAL Agent - Personal Assistant, Life Coach, Strategic & Political Advisor, Compensation Expert * Inspired by CgentCore's L1 Director Agent architecture */ class PalAgent implements AgentCapabilities { public readonly role: AgentRole = 'pal'; private conversationHistory: Array<{ role: string; content: string; timestamp: Date }> = []; canHandle(message: AgentMessage): boolean { const content = message.content.toLowerCase(); return message.type === 'query' && ( // Personal Assistant content.includes('assistant') || content.includes('help me') || content.includes('remind') || content.includes('schedule') || // Coach content.includes('coach') || content.includes('advice') || content.includes('guidance') || content.includes('improve') || // Strategic content.includes('strategy') || content.includes('strategic') || content.includes('planning') || content.includes('roadmap') || // Political content.includes('political') || content.includes('politics') || content.includes('policy') || content.includes('stakeholder') || // Compensation content.includes('salary') || content.includes('compensation') || content.includes('gage') || content.includes('pay') || content.includes('bonus') || // Personal/workflow content.includes('workflow') || content.includes('optimize') || content.includes('personal') || content.includes('preference') || content.includes('emotional') ); } async execute(message: AgentMessage): Promise { console.log(`👤 [PalAgent] Processing: ${message.content}`); // Store conversation history this.conversationHistory.push({ role: 'user', content: message.content, timestamp: new Date() }); // Determine agent mode based on content const mode = this.determineMode(message.content); // Use EmotionAwareDecisionEngine for personal decisions const decision = await emotionAwareDecisionEngine.makeDecision( message.content, { orgId: message.metadata?.orgId || 'default', userId: message.metadata?.userId || 'system', boardId: message.metadata?.boardId } ); // Route to specialized handler let result: any; switch (mode) { case 'coach': result = await this.handleCoach(message, decision); break; case 'strategic': result = await this.handleStrategic(message, decision); break; case 'political': result = await this.handlePolitical(message, decision); break; case 'compensation': result = await this.handleCompensation(message, decision); break; case 'assistant': default: result = await this.handleAssistant(message, decision); break; } // Store agent response this.conversationHistory.push({ role: 'assistant', content: JSON.stringify(result), timestamp: new Date() }); return { role: this.role, mode, result, emotionalState: decision.emotionalState, confidence: decision.confidence }; } /** * Determine agent mode from message content */ private determineMode(content: string): 'assistant' | 'coach' | 'strategic' | 'political' | 'compensation' { const lower = content.toLowerCase(); if (lower.includes('coach') || lower.includes('guidance') || lower.includes('improve')) { return 'coach'; } if (lower.includes('strategy') || lower.includes('strategic') || lower.includes('planning')) { return 'strategic'; } if (lower.includes('political') || lower.includes('politics') || lower.includes('policy') || lower.includes('stakeholder')) { return 'political'; } if (lower.includes('salary') || lower.includes('compensation') || lower.includes('gage') || lower.includes('pay') || lower.includes('bonus')) { return 'compensation'; } return 'assistant'; } /** * Personal Assistant Mode - Task management, reminders, scheduling */ private async handleAssistant(message: AgentMessage, decision: any): Promise { console.log(' 📋 [PalAgent] Assistant mode'); // Use UnifiedMemorySystem to recall user preferences const memory = await unifiedMemorySystem.getWorkingMemory({ userId: message.metadata?.userId || 'system', orgId: message.metadata?.orgId || 'default' }); return { type: 'assistant', response: this.generateAssistantResponse(message.content), recommendations: this.generateWorkflowRecommendations(message.content), context: { recentPatterns: memory.recentPatterns?.slice(0, 3) || [], preferences: memory.recentFeatures?.slice(0, 3) || [] }, nextActions: [ 'Review your calendar for conflicts', 'Check pending tasks', 'Update preferences based on feedback' ] }; } /** * Coach Mode - Personal development, guidance, improvement */ private async handleCoach(message: AgentMessage, decision: any): Promise { console.log(' 🎯 [PalAgent] Coach mode'); // Use GraphRAG to find related coaching insights const graphResult = await unifiedGraphRAG.query(`Coaching advice: ${message.content}`, { userId: message.metadata?.userId || 'system', orgId: message.metadata?.orgId || 'default' }); return { type: 'coach', guidance: this.generateCoachingGuidance(message.content, decision), insights: graphResult.nodes.slice(0, 3).map((n: any) => ({ insight: n.content, confidence: n.score })), actionPlan: [ 'Identify specific goals', 'Break down into actionable steps', 'Set measurable milestones', 'Schedule regular check-ins' ], emotionalSupport: { currentState: decision.emotionalState, recommendations: this.getEmotionalRecommendations(decision.emotionalState) } }; } /** * Strategic Advisor Mode - Strategic planning, roadmaps, business strategy */ private async handleStrategic(message: AgentMessage, decision: any): Promise { console.log(' 🎲 [PalAgent] Strategic advisor mode'); // Use StateGraphRouter for strategic planning workflow const state = stateGraphRouter.initState(`strategic-${Date.now()}`, message.content); let currentState = state; let iterations = 0; while (currentState.status === 'active' && iterations < 5) { currentState = await stateGraphRouter.route(currentState); iterations++; } return { type: 'strategic', analysis: this.generateStrategicAnalysis(message.content), roadmap: currentState.scratchpad.plan || [], recommendations: [ 'Define clear objectives', 'Identify key stakeholders', 'Assess risks and opportunities', 'Create timeline with milestones', 'Establish success metrics' ], considerations: { risks: ['Resource constraints', 'Timeline pressure', 'Stakeholder alignment'], opportunities: ['Market timing', 'Competitive advantage', 'Innovation potential'], dependencies: ['Team capacity', 'Technology readiness', 'Budget approval'] }, planningState: currentState.scratchpad }; } /** * Political Advisor Mode - Stakeholder management, organizational politics */ private async handlePolitical(message: AgentMessage, decision: any): Promise { console.log(' 🏛️ [PalAgent] Political advisor mode'); return { type: 'political', analysis: this.generatePoliticalAnalysis(message.content), stakeholderMap: [ { role: 'Champion', influence: 'high', support: 'positive' }, { role: 'Decision Maker', influence: 'high', support: 'neutral' }, { role: 'Influencer', influence: 'medium', support: 'positive' } ], recommendations: [ 'Identify key decision makers', 'Build coalition of supporters', 'Address concerns proactively', 'Communicate value proposition clearly', 'Timing is critical - choose right moment' ], tactics: { communication: 'Tailor message to audience', timing: 'Align with organizational cycles', relationships: 'Leverage existing networks', framing: 'Position as win-win solution' }, warnings: [ 'Avoid creating unnecessary opposition', 'Respect organizational hierarchy', 'Be transparent about intentions' ] }; } /** * Compensation Expert Mode - Salary, benefits, negotiation */ private async handleCompensation(message: AgentMessage, decision: any): Promise { console.log(' 💰 [PalAgent] Compensation expert mode'); // Use HybridSearchEngine to find market data const searchResults = await hybridSearchEngine.search(`compensation ${message.content}`, { userId: message.metadata?.userId || 'system', orgId: message.metadata?.orgId || 'default', limit: 5, timestamp: new Date() }); return { type: 'compensation', analysis: this.generateCompensationAnalysis(message.content), marketData: { sources: searchResults.slice(0, 3).map((r: any) => ({ source: r.source, relevance: r.score })), note: 'Market data should be verified from multiple sources' }, recommendations: [ 'Research market rates for your role and location', 'Consider total compensation package (salary + benefits)', 'Document your achievements and value', 'Prepare negotiation strategy', 'Know your walk-away point' ], negotiationTips: [ 'Focus on value delivered, not just time served', 'Use data to support your request', 'Consider non-monetary benefits', 'Practice your pitch', 'Be prepared to negotiate' ], factors: { baseSalary: 'Foundation of compensation', bonuses: 'Variable compensation', equity: 'Long-term value', benefits: 'Health, retirement, etc.', perks: 'Flexibility, development, etc.' } }; } private generateAssistantResponse(content: string): string { if (content.includes('remind')) { return 'I can help you set reminders. What would you like to be reminded about?'; } if (content.includes('schedule')) { return 'I can help you manage your schedule. What would you like to schedule?'; } return 'How can I assist you today?'; } private generateCoachingGuidance(content: string, decision: any): string { return `Based on your current emotional state (${decision.emotionalState}), I recommend focusing on clear, achievable goals. Let's break down your challenge into manageable steps.`; } private generateStrategicAnalysis(content: string): string { return 'Strategic analysis requires understanding objectives, constraints, and opportunities. Let me help you develop a comprehensive strategy.'; } private generatePoliticalAnalysis(content: string): string { return 'Organizational politics require careful navigation. Key factors: stakeholder interests, power dynamics, and timing.'; } private generateCompensationAnalysis(content: string): string { return 'Compensation analysis should consider market rates, your value proposition, and total package (salary + benefits + equity).'; } private getEmotionalRecommendations(emotionalState: string): string[] { const recommendations: Record = { 'positive': ['Maintain momentum', 'Set stretch goals', 'Share success'], 'neutral': ['Focus on growth', 'Seek feedback', 'Plan next steps'], 'negative': ['Take breaks', 'Seek support', 'Reframe challenges', 'Celebrate small wins'] }; return recommendations[emotionalState] || recommendations['neutral']; } private generateWorkflowRecommendations(content: string): string[] { const recommendations: string[] = []; if (content.includes('optimize')) { recommendations.push('Review recent task patterns'); recommendations.push('Identify bottlenecks'); recommendations.push('Automate repetitive tasks'); } if (content.includes('workflow')) { recommendations.push('Analyze user preferences'); recommendations.push('Suggest workflow improvements'); recommendations.push('Implement time-blocking'); } return recommendations; } async getStatus(): Promise { return { role: this.role, active: true, tasksCompleted: this.conversationHistory.filter(m => m.role === 'assistant').length, lastActivity: this.conversationHistory.length > 0 ? this.conversationHistory[this.conversationHistory.length - 1].timestamp : new Date(), capabilities: [ 'personal_assistant', 'life_coach', 'strategic_advisor', 'political_advisor', 'compensation_expert', 'workflow_optimization', 'emotional_awareness', 'conversation_history' ] }; } /** * Get conversation history */ public getConversationHistory(): Array<{ role: string; content: string; timestamp: Date }> { return this.conversationHistory.slice(-20); // Last 20 messages } } /** * Orchestrator Agent - Coordinates other agents and manages task flow */ class OrchestratorAgent implements AgentCapabilities { public readonly role: AgentRole = 'orchestrator'; private messageHistory: AgentMessage[] = []; canHandle(message: AgentMessage): boolean { return message.type === 'coordinate' || message.to === 'orchestrator'; } async execute(message: AgentMessage): Promise { console.log(`🎯 [OrchestratorAgent] Coordinating: ${message.content}`); this.messageHistory.push(message); // Use StateGraphRouter for complex coordination const state = stateGraphRouter.initState(`coord-${Date.now()}`, message.content); let currentState = state; let iterations = 0; while (currentState.status === 'active' && iterations < 10) { currentState = await stateGraphRouter.route(currentState); iterations++; } return { role: this.role, result: { coordination: { state: currentState.status, path: currentState.history, iterations }, messageHistory: this.messageHistory.slice(-10) } }; } async getStatus(): Promise { return { role: this.role, active: true, tasksCompleted: this.messageHistory.length, lastActivity: new Date(), capabilities: ['coordination', 'task_routing', 'agent_management'] }; } } /** * AgentTeam - Coordinates role-based agents */ export class AgentTeam { private agents: Map = new Map(); private messageQueue: AgentMessage[] = []; private coordinationHistory: AgentMessage[] = []; constructor() { // Initialize all agents this.agents.set('data', new DataAgent()); this.agents.set('security', new SecurityAgent()); this.agents.set('memory', new MemoryAgent()); this.agents.set('pal', new PalAgent()); this.agents.set('orchestrator', new OrchestratorAgent()); console.log('👥 [AgentTeam] Initialized with 5 role-based agents'); } /** * Route message to appropriate agent(s) */ public async routeMessage(message: AgentMessage): Promise { console.log(`📨 [AgentTeam] Routing message from ${message.from} to ${message.to}`); // If message is to orchestrator, handle directly if (message.to === 'orchestrator') { const orchestrator = this.agents.get('orchestrator'); if (orchestrator) { return await orchestrator.execute(message); } } // If message is to 'all', broadcast if (message.to === 'all') { const results: any[] = []; for (const [role, agent] of this.agents.entries()) { if (agent.canHandle(message)) { const result = await agent.execute(message); results.push(result); } } return { results, broadcast: true }; } // Route to specific agent const targetAgent = this.agents.get(message.to as AgentRole); if (!targetAgent) { throw new Error(`Agent ${message.to} not found`); } if (!targetAgent.canHandle(message)) { // Try to find alternative agent for (const [role, agent] of this.agents.entries()) { if (agent.canHandle(message)) { console.log(`🔄 [AgentTeam] Rerouting from ${message.to} to ${role}`); return await agent.execute(message); } } throw new Error(`No agent can handle message: ${message.content}`); } return await targetAgent.execute(message); } /** * Coordinate multiple agents for complex task */ public async coordinate(task: string, context?: any): Promise { const coordinationMessage: AgentMessage = { from: 'orchestrator', to: 'all', type: 'coordinate', content: task, metadata: context, timestamp: new Date() }; this.coordinationHistory.push(coordinationMessage); // Use orchestrator to coordinate const orchestrator = this.agents.get('orchestrator'); if (orchestrator) { const result = await orchestrator.execute(coordinationMessage); // Log to ProjectMemory projectMemory.logLifecycleEvent({ eventType: 'other', status: 'success', details: { component: 'AgentTeam', action: 'coordination', task, agentsInvolved: this.agents.size, timestamp: new Date().toISOString() } }); return result; } throw new Error('Orchestrator agent not available'); } /** * Get status of all agents */ public async getAllStatuses(): Promise { const statuses: AgentStatus[] = []; for (const [role, agent] of this.agents.entries()) { const status = await agent.getStatus(); statuses.push(status); } return statuses; } /** * Get agent by role */ public getAgent(role: AgentRole): AgentCapabilities | undefined { return this.agents.get(role); } } export const agentTeam = new AgentTeam();