recoder-shared
Version:
Shared types, utilities, and configurations for Recoder
480 lines • 19.8 kB
JavaScript
"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