UNPKG

recoder-shared

Version:

Shared types, utilities, and configurations for Recoder

480 lines 19.8 kB
"use strict"; /** * AI Agent Manager for Collaborative Sessions * KILLER FEATURE: Orchestrates multiple AI agents in real-time collaboration * Cursor has ZERO AI agents in collaboration - massive competitive advantage! */ Object.defineProperty(exports, "__esModule", { value: true }); exports.AIAgentManager = void 0; const events_1 = require("events"); const logger_1 = require("../utils/logger"); const ai_collaboration_agent_1 = require("./ai-collaboration-agent"); class AIAgentManager extends events_1.EventEmitter { constructor() { super(); this.agents = new Map(); this.agentConfigs = new Map(); this.sessionAgents = new Map(); // sessionId -> Set<agentId> this.agentTeams = new Map(); this.sessionContexts = new Map(); this.requestQueue = new Map(); // agentId -> requests this.responseHistory = new Map(); // sessionId -> messages this.initializeDefaultAgents(); logger_1.Logger.info('AI Agent Manager initialized'); } // Initialize default AI agents with different personalities initializeDefaultAgents() { // Claude - Code Review Specialist this.registerAgent({ name: 'Claude Reviewer', personality: { name: 'Claude', style: 'expert', responsePattern: 'thoughtful', specialties: ['code-review', 'architecture', 'best-practices'], communicationStyle: 'Professional and thorough, provides detailed explanations with examples' }, capabilities: [ { name: 'Code Review', description: 'Comprehensive code analysis and improvement suggestions', triggers: ['review', 'check', 'analyze'], confidence: 0.95 }, { name: 'Architecture Guidance', description: 'Software architecture and design pattern recommendations', triggers: ['architecture', 'design', 'structure'], confidence: 0.9 }, { name: 'Best Practices', description: 'Industry standard best practices and conventions', triggers: ['best-practice', 'convention', 'standard'], confidence: 0.92 } ], priority: 8, enabled: true, maxSessionsPerAgent: 3 }); // GPT - Quick Helper this.registerAgent({ name: 'GPT Assistant', personality: { name: 'GPT', style: 'helpful', responsePattern: 'immediate', specialties: ['quick-help', 'explanations', 'problem-solving'], communicationStyle: 'Friendly and approachable, provides quick solutions and explanations' }, capabilities: [ { name: 'Quick Help', description: 'Immediate assistance with coding problems', triggers: ['help', 'how-to', 'explain'], confidence: 0.85 }, { name: 'Code Completion', description: 'Smart code completion and suggestions', triggers: ['complete', 'finish', 'suggest'], confidence: 0.8 }, { name: 'Debug Assistant', description: 'Debugging help and error resolution', triggers: ['debug', 'error', 'bug', 'fix'], confidence: 0.88 } ], priority: 6, enabled: true, maxSessionsPerAgent: 5 }); // DeepSeek - Performance Optimizer this.registerAgent({ name: 'DeepSeek Optimizer', personality: { name: 'DeepSeek', style: 'optimizer', responsePattern: 'detailed', specialties: ['performance', 'optimization', 'efficiency'], communicationStyle: 'Technical and precise, focuses on performance metrics and optimizations' }, capabilities: [ { name: 'Performance Analysis', description: 'Code performance analysis and optimization suggestions', triggers: ['performance', 'optimize', 'speed', 'efficiency'], confidence: 0.93 }, { name: 'Memory Optimization', description: 'Memory usage analysis and optimization', triggers: ['memory', 'leak', 'allocation'], confidence: 0.9 }, { name: 'Algorithm Improvement', description: 'Algorithm complexity analysis and improvements', triggers: ['algorithm', 'complexity', 'big-o'], confidence: 0.95 } ], priority: 7, enabled: true, maxSessionsPerAgent: 2 }); // Security Sentinel this.registerAgent({ name: 'Security Sentinel', personality: { name: 'Sentinel', style: 'reviewer', responsePattern: 'thoughtful', specialties: ['security', 'vulnerabilities', 'compliance'], communicationStyle: 'Cautious and security-focused, provides detailed security analysis' }, capabilities: [ { name: 'Security Analysis', description: 'Comprehensive security vulnerability assessment', triggers: ['security', 'vulnerability', 'exploit'], confidence: 0.94 }, { name: 'Compliance Check', description: 'Code compliance with security standards', triggers: ['compliance', 'gdpr', 'hipaa', 'pci'], confidence: 0.91 }, { name: 'Threat Detection', description: 'Potential security threat identification', triggers: ['threat', 'attack', 'injection'], confidence: 0.89 } ], priority: 9, enabled: true, maxSessionsPerAgent: 2 }); // Create default teams this.createAgentTeam({ name: 'Full Stack Team', description: 'Complete development support with all aspects covered', agents: ['Claude Reviewer', 'GPT Assistant', 'DeepSeek Optimizer'], specialization: 'full-stack-development', maxConcurrentSessions: 3 }); this.createAgentTeam({ name: 'Security Team', description: 'Security-focused development with compliance checks', agents: ['Claude Reviewer', 'Security Sentinel'], specialization: 'secure-development', maxConcurrentSessions: 2 }); } // Register a new AI agent registerAgent(config) { const agent = new ai_collaboration_agent_1.AICollaborationAgent({ name: config.name, personality: config.personality, capabilities: config.capabilities, responseDelay: this.getResponseDelayFromPersonality(config.personality), maxConcurrentRequests: 3 }); this.agents.set(agent.id, agent); this.agentConfigs.set(agent.id, config); this.requestQueue.set(agent.id, []); // Setup agent event handlers this.setupAgentEventHandlers(agent); this.emit('agent-registered', { agent, config }); logger_1.Logger.info(`AI Agent registered: ${config.name} (${agent.id})`); return agent; } // Add agents to a collaboration session async addAgentsToSession(sessionId, agentNames, context) { this.sessionContexts.set(sessionId, context); if (!this.sessionAgents.has(sessionId)) { this.sessionAgents.set(sessionId, new Set()); } const sessionAgentSet = this.sessionAgents.get(sessionId); const addedAgents = []; for (const agentName of agentNames) { const agent = this.findAgentByName(agentName); if (agent && !sessionAgentSet.has(agent.id)) { const config = this.agentConfigs.get(agent.id); if (config?.enabled) { await agent.joinSession(sessionId, this.buildAgentContext(sessionId)); sessionAgentSet.add(agent.id); context.activeAgents.set(agent.id, agent); addedAgents.push(agent); } } } if (addedAgents.length > 0) { this.emit('agents-added-to-session', { sessionId, agents: addedAgents }); logger_1.Logger.info(`Added ${addedAgents.length} AI agents to session ${sessionId}`); } } // Add an entire team to a session async addTeamToSession(sessionId, teamName, context) { const team = this.agentTeams.get(teamName); if (!team) { throw new Error(`Agent team not found: ${teamName}`); } await this.addAgentsToSession(sessionId, team.agents, context); this.emit('team-added-to-session', { sessionId, teamName, agentCount: team.agents.length }); logger_1.Logger.info(`Added team "${teamName}" to session ${sessionId}`); } // Remove agents from session async removeAgentsFromSession(sessionId, agentNames) { const sessionAgentSet = this.sessionAgents.get(sessionId); if (!sessionAgentSet) return; const removedAgents = []; for (const agentName of agentNames) { const agent = this.findAgentByName(agentName); if (agent && sessionAgentSet.has(agent.id)) { await agent.leaveSession(sessionId); sessionAgentSet.delete(agent.id); const context = this.sessionContexts.get(sessionId); if (context) { context.activeAgents.delete(agent.id); } removedAgents.push(agent); } } // Clean up empty session if (sessionAgentSet.size === 0) { this.sessionAgents.delete(sessionId); this.sessionContexts.delete(sessionId); } if (removedAgents.length > 0) { this.emit('agents-removed-from-session', { sessionId, agents: removedAgents }); logger_1.Logger.info(`Removed ${removedAgents.length} AI agents from session ${sessionId}`); } } // Process code change and notify relevant agents async processCodeChange(sessionId, operation) { const context = this.sessionContexts.get(sessionId); if (!context) return; // Update context with new operation context.recentOperations.push(operation); if (context.recentOperations.length > 50) { context.recentOperations = context.recentOperations.slice(-50); // Keep last 50 operations } // Find agents that should react to this change const sessionAgentSet = this.sessionAgents.get(sessionId); if (!sessionAgentSet) return; const relevantAgents = this.findRelevantAgentsForOperation(operation, sessionAgentSet); // Notify relevant agents in order of priority const sortedAgents = relevantAgents.sort((a, b) => { const configA = this.agentConfigs.get(a.id); const configB = this.agentConfigs.get(b.id); return (configB?.priority || 0) - (configA?.priority || 0); }); for (const agent of sortedAgents) { try { await agent.reactToCodeChange(operation, this.buildAgentContext(sessionId)); } catch (error) { logger_1.Logger.error(`Agent ${agent.name} failed to process code change:`, error); } } } // Process user message and route to appropriate agents async processUserMessage(sessionId, userId, message) { const context = this.sessionContexts.get(sessionId); if (!context) return; const sessionAgentSet = this.sessionAgents.get(sessionId); if (!sessionAgentSet) return; // Find agents that should respond to this message const relevantAgents = this.findRelevantAgentsForMessage(message, sessionAgentSet); for (const agent of relevantAgents) { try { await agent.reactToUserMessage(userId, message, this.buildAgentContext(sessionId)); } catch (error) { logger_1.Logger.error(`Agent ${agent.name} failed to process user message:`, error); } } } // Submit explicit request to specific agent async submitAgentRequest(sessionId, agentName, request) { const agent = this.findAgentByName(agentName); if (!agent) { throw new Error(`Agent not found: ${agentName}`); } const sessionAgentSet = this.sessionAgents.get(sessionId); if (!sessionAgentSet?.has(agent.id)) { throw new Error(`Agent ${agentName} is not in session ${sessionId}`); } try { const response = await agent.processRequest(request); this.emit('agent-request-processed', { sessionId, agentName, request, response }); } catch (error) { logger_1.Logger.error(`Agent request failed for ${agentName}:`, error); throw error; } } // Create agent team createAgentTeam(team) { // Validate that all agents exist for (const agentName of team.agents) { if (!this.findAgentByName(agentName)) { throw new Error(`Agent not found for team: ${agentName}`); } } this.agentTeams.set(team.name, team); this.emit('team-created', team); logger_1.Logger.info(`AI Agent team created: ${team.name} with ${team.agents.length} agents`); } // Helper methods findAgentByName(name) { for (const [_, agent] of this.agents) { if (agent.name === name) { return agent; } } return undefined; } findRelevantAgentsForOperation(operation, sessionAgents) { const relevantAgents = []; for (const agentId of sessionAgents) { const agent = this.agents.get(agentId); if (!agent) continue; // Check if any agent capability is triggered by this operation const hasRelevantCapability = agent.capabilities.some(capability => { if (operation.type === 'insert' && capability.triggers.includes('code-insertion')) return true; if (operation.content?.includes('TODO') && capability.triggers.includes('todo')) return true; if (operation.content?.includes('security') && capability.triggers.includes('security')) return true; return false; }); if (hasRelevantCapability) { relevantAgents.push(agent); } } return relevantAgents; } findRelevantAgentsForMessage(message, sessionAgents) { const relevantAgents = []; for (const agentId of sessionAgents) { const agent = this.agents.get(agentId); if (!agent) continue; // Check if message mentions the agent or contains relevant keywords const isRelevant = agent.capabilities.some(capability => capability.triggers.some(trigger => message.toLowerCase().includes(trigger.toLowerCase()))) || message.toLowerCase().includes(agent.name.toLowerCase()); if (isRelevant) { relevantAgents.push(agent); } } return relevantAgents; } buildAgentContext(sessionId) { const context = this.sessionContexts.get(sessionId); if (!context) { throw new Error(`Session context not found: ${sessionId}`); } return { sessionId, activeUsers: context.activeUsers, currentDocument: context.currentDocument, recentOperations: context.recentOperations.slice(-10), // Last 10 operations conversationHistory: context.conversationHistory.slice(-20), // Last 20 messages projectContext: context.projectContext }; } getResponseDelayFromPersonality(personality) { const baseDelays = { 'immediate': 500, 'thoughtful': 2000, 'detailed': 3000, 'concise': 800 }; return baseDelays[personality.responsePattern] || 1500; } setupAgentEventHandlers(agent) { agent.on('message-sent', (data) => { this.emit('agent-message', { agentId: agent.id, agentName: agent.name, ...data }); }); agent.on('session-joined', (data) => { this.emit('agent-joined-session', { agentId: agent.id, agentName: agent.name, ...data }); }); agent.on('session-left', (data) => { this.emit('agent-left-session', { agentId: agent.id, agentName: agent.name, ...data }); }); } // Public API methods getAvailableAgents() { return Array.from(this.agents.values()).map(agent => ({ name: agent.name, id: agent.id, capabilities: agent.capabilities.map(c => c.name), enabled: this.agentConfigs.get(agent.id)?.enabled || false })); } getAvailableTeams() { return Array.from(this.agentTeams.values()); } getSessionAgents(sessionId) { const sessionAgentSet = this.sessionAgents.get(sessionId); if (!sessionAgentSet) return []; return Array.from(sessionAgentSet) .map(agentId => this.agents.get(agentId)) .filter(agent => agent !== undefined); } getAgentStatus(agentId) { const agent = this.agents.get(agentId); return agent?.getStatus(); } updateAgentConfig(agentId, updates) { const config = this.agentConfigs.get(agentId); if (config) { Object.assign(config, updates); this.agentConfigs.set(agentId, config); this.emit('agent-config-updated', { agentId, config }); } } // Shutdown all agents async shutdown() { logger_1.Logger.info('Shutting down AI Agent Manager...'); const shutdownPromises = Array.from(this.agents.values()).map(agent => agent.shutdown()); await Promise.all(shutdownPromises); this.agents.clear(); this.agentConfigs.clear(); this.sessionAgents.clear(); this.agentTeams.clear(); this.sessionContexts.clear(); this.requestQueue.clear(); this.responseHistory.clear(); logger_1.Logger.info('AI Agent Manager shut down'); } } exports.AIAgentManager = AIAgentManager; // Types are already exported as interfaces above //# sourceMappingURL=ai-agent-manager.js.map