UNPKG

jay-code

Version:

Streamlined AI CLI orchestration engine with mathematical rigor and enterprise-grade reliability

670 lines (598 loc) 20.1 kB
/** * Agent Capabilities System - Defines and manages agent skills and selection algorithms */ import type { AgentType, AgentCapabilities, TaskDefinition } from '../../swarm/types.js'; import type { AgentState } from './base-agent.js'; export interface CapabilityMatch { agent: AgentState; score: number; matchedCapabilities: string[]; missingCapabilities: string[]; confidence: number; reason: string; } export interface TaskRequirements { type: string; requiredCapabilities: string[]; preferredCapabilities: string[]; languages?: string[]; frameworks?: string[]; domains?: string[]; tools?: string[]; complexity: 'low' | 'medium' | 'high' | 'critical'; urgency: 'low' | 'medium' | 'high' | 'critical'; estimatedDuration: number; // minutes dependencies: string[]; } export interface CapabilityRegistry { [capability: string]: { description: string; category: 'technical' | 'domain' | 'soft' | 'system'; prerequisites: string[]; relatedCapabilities: string[]; complexity: number; // 1-10 importance: number; // 1-10 }; } /** * Agent Capability System */ export class AgentCapabilitySystem { private capabilityRegistry: CapabilityRegistry; private agentCapabilities: Map<string, AgentCapabilities>; private taskTypeRequirements: Map<string, TaskRequirements>; constructor() { this.capabilityRegistry = this.initializeCapabilityRegistry(); this.agentCapabilities = new Map(); this.taskTypeRequirements = this.initializeTaskRequirements(); } /** * Get agent capabilities by agent ID */ getAgentCapabilities(agentId: string): AgentCapabilities | undefined { return this.agentCapabilities.get(agentId); } /** * Register agent capabilities */ registerAgentCapabilities(agentId: string, capabilities: AgentCapabilities): void { this.agentCapabilities.set(agentId, capabilities); } /** * Find best matching agents for a task */ findBestAgents( task: TaskDefinition, availableAgents: AgentState[], maxResults: number = 5, ): CapabilityMatch[] { const requirements = this.getTaskRequirements(task); const matches: CapabilityMatch[] = []; for (const agent of availableAgents) { const match = this.evaluateAgentMatch(agent, requirements); if (match.score > 0) { matches.push(match); } } // Sort by score (highest first) and return top results return matches.sort((a, b) => b.score - a.score).slice(0, maxResults); } /** * Get capability requirements for a task type */ getTaskRequirements(task: TaskDefinition): TaskRequirements { const baseRequirements = this.taskTypeRequirements.get(task.type); if (!baseRequirements) { // Infer requirements from task parameters return this.inferTaskRequirements(task); } // Merge with task-specific parameters return { ...baseRequirements, languages: task.parameters?.languages || baseRequirements.languages, frameworks: task.parameters?.frameworks || baseRequirements.frameworks, complexity: task.parameters?.complexity || baseRequirements.complexity, urgency: task.parameters?.urgency || baseRequirements.urgency, estimatedDuration: task.parameters?.estimatedDuration || baseRequirements.estimatedDuration, }; } /** * Evaluate how well an agent matches task requirements */ private evaluateAgentMatch(agent: AgentState, requirements: TaskRequirements): CapabilityMatch { const capabilities = agent.capabilities; let score = 0; let maxScore = 0; const matchedCapabilities: string[] = []; const missingCapabilities: string[] = []; // Evaluate required capabilities for (const required of requirements.requiredCapabilities) { maxScore += 20; // Each required capability is worth 20 points if (this.agentHasCapability(capabilities, required)) { score += 20; matchedCapabilities.push(required); } else { missingCapabilities.push(required); score -= 5; // Penalty for missing required capability } } // Evaluate preferred capabilities for (const preferred of requirements.preferredCapabilities) { maxScore += 10; // Each preferred capability is worth 10 points if (this.agentHasCapability(capabilities, preferred)) { score += 10; matchedCapabilities.push(preferred); } } // Evaluate language compatibility if (requirements.languages) { maxScore += 15; const languageMatch = requirements.languages.some((lang) => capabilities.languages.includes(lang), ); if (languageMatch) { score += 15; } } // Evaluate framework compatibility if (requirements.frameworks) { maxScore += 15; const frameworkMatch = requirements.frameworks.some((framework) => capabilities.frameworks.includes(framework), ); if (frameworkMatch) { score += 15; } } // Evaluate domain expertise if (requirements.domains) { maxScore += 10; const domainMatch = requirements.domains.some((domain) => capabilities.domains.includes(domain), ); if (domainMatch) { score += 10; } } // Agent health and availability bonus maxScore += 20; score += agent.health * 10; // Health contributes up to 10 points score += (1 - agent.workload) * 10; // Low workload contributes up to 10 points // Agent reliability bonus maxScore += 10; score += capabilities.reliability * 10; // Complexity matching const complexityScore = this.evaluateComplexityMatch(capabilities, requirements.complexity); maxScore += 10; score += complexityScore; // Calculate final score as percentage const finalScore = maxScore > 0 ? (score / maxScore) * 100 : 0; const confidence = this.calculateConfidence( matchedCapabilities, missingCapabilities, requirements, ); const reason = this.generateMatchReason(matchedCapabilities, missingCapabilities, finalScore); return { agent, score: Math.max(0, Math.min(100, finalScore)), matchedCapabilities, missingCapabilities, confidence, reason, }; } /** * Check if agent has a specific capability */ private agentHasCapability(capabilities: AgentCapabilities, capability: string): boolean { // Check direct capabilities const capabilityFields = [ 'codeGeneration', 'codeReview', 'testing', 'documentation', 'research', 'analysis', 'webSearch', 'apiIntegration', 'fileSystem', 'terminalAccess', ] as const; for (const field of capabilityFields) { if (capability === field && capabilities[field]) { return true; } } // Check arrays const arrayFields = ['languages', 'frameworks', 'domains', 'tools'] as const; for (const field of arrayFields) { if (capabilities[field].includes(capability)) { return true; } } // Check for semantic matches return this.checkSemanticCapabilityMatch(capabilities, capability); } /** * Check for semantic capability matches */ private checkSemanticCapabilityMatch( capabilities: AgentCapabilities, capability: string, ): boolean { const semanticMappings: Record<string, string[]> = { 'web-development': ['react', 'vue', 'angular', 'javascript', 'typescript', 'html', 'css'], 'backend-development': ['node', 'express', 'fastify', 'python', 'django', 'flask'], database: ['sql', 'postgresql', 'mysql', 'mongodb', 'redis'], cloud: ['aws', 'azure', 'gcp', 'docker', 'kubernetes'], testing: ['jest', 'mocha', 'cypress', 'playwright', 'selenium'], 'data-science': ['python', 'r', 'pandas', 'numpy', 'sklearn'], mobile: ['react-native', 'flutter', 'swift', 'kotlin', 'ionic'], }; for (const [concept, related] of Object.entries(semanticMappings)) { if (capability.includes(concept)) { return related.some( (item) => capabilities.languages.includes(item) || capabilities.frameworks.includes(item) || capabilities.tools.includes(item), ); } } return false; } /** * Evaluate complexity matching */ private evaluateComplexityMatch(capabilities: AgentCapabilities, complexity: string): number { const complexityScores = { low: 1, medium: 2, high: 3, critical: 4, }; const agentComplexity = this.calculateAgentComplexityLevel(capabilities); const taskComplexity = complexityScores[complexity as keyof typeof complexityScores] || 2; // Perfect match gets full points, close matches get partial points const diff = Math.abs(agentComplexity - taskComplexity); if (diff === 0) return 10; if (diff === 1) return 7; if (diff === 2) return 4; return 1; } /** * Calculate agent's complexity handling level */ private calculateAgentComplexityLevel(capabilities: AgentCapabilities): number { let level = 1; // Advanced capabilities increase complexity level if (capabilities.codeGeneration) level += 0.5; if (capabilities.analysis) level += 0.5; if (capabilities.terminalAccess) level += 0.5; // Multiple languages/frameworks indicate higher complexity handling if (capabilities.languages.length > 3) level += 0.5; if (capabilities.frameworks.length > 3) level += 0.5; if (capabilities.domains.length > 5) level += 0.5; // Reliability indicates ability to handle complex tasks level += capabilities.reliability; return Math.min(4, Math.max(1, Math.round(level))); } /** * Calculate confidence in the match */ private calculateConfidence( matched: string[], missing: string[], requirements: TaskRequirements, ): number { const totalRequired = requirements.requiredCapabilities.length; if (totalRequired === 0) return 0.8; // Default confidence const matchRate = matched.length / (matched.length + missing.length); const criticalMissing = missing.filter((cap) => requirements.requiredCapabilities.includes(cap), ).length; let confidence = matchRate; // Reduce confidence for missing critical capabilities if (criticalMissing > 0) { confidence *= 1 - (criticalMissing / totalRequired) * 0.5; } return Math.max(0, Math.min(1, confidence)); } /** * Generate human-readable match reason */ private generateMatchReason(matched: string[], missing: string[], score: number): string { if (score >= 90) { return `Excellent match with ${matched.length} matching capabilities`; } else if (score >= 75) { return `Good match, minor gaps in ${missing.slice(0, 2).join(', ')}`; } else if (score >= 50) { return `Partial match, missing key capabilities: ${missing.slice(0, 3).join(', ')}`; } else { return `Poor match, significant capability gaps`; } } /** * Infer task requirements from task description and parameters */ private inferTaskRequirements(task: TaskDefinition): TaskRequirements { const description = task.description.toLowerCase(); const requiredCapabilities: string[] = []; const preferredCapabilities: string[] = []; const languages: string[] = []; const frameworks: string[] = []; const domains: string[] = []; // Analyze description for keywords if (description.includes('code') || description.includes('develop')) { requiredCapabilities.push('codeGeneration'); domains.push('development'); } if (description.includes('test')) { requiredCapabilities.push('testing'); domains.push('testing'); } if (description.includes('analyze') || description.includes('analysis')) { requiredCapabilities.push('analysis'); domains.push('analysis'); } if (description.includes('research')) { requiredCapabilities.push('research'); domains.push('research'); } // Check for language mentions const commonLanguages = ['javascript', 'typescript', 'python', 'java', 'go', 'rust']; for (const lang of commonLanguages) { if (description.includes(lang)) { languages.push(lang); } } return { type: task.type, requiredCapabilities, preferredCapabilities, languages, frameworks, domains, tools: [], complexity: 'medium', urgency: 'medium', estimatedDuration: 30, // Default 30 minutes dependencies: [], }; } /** * Initialize capability registry */ private initializeCapabilityRegistry(): CapabilityRegistry { return { codeGeneration: { description: 'Ability to generate code in various programming languages', category: 'technical', prerequisites: [], relatedCapabilities: ['codeReview', 'testing'], complexity: 8, importance: 9, }, codeReview: { description: 'Ability to review and analyze code for quality and security', category: 'technical', prerequisites: ['codeGeneration'], relatedCapabilities: ['testing', 'security'], complexity: 7, importance: 8, }, testing: { description: 'Ability to create and execute various types of tests', category: 'technical', prerequisites: [], relatedCapabilities: ['codeGeneration', 'analysis'], complexity: 6, importance: 9, }, documentation: { description: 'Ability to create comprehensive documentation', category: 'technical', prerequisites: [], relatedCapabilities: ['research', 'analysis'], complexity: 4, importance: 7, }, research: { description: 'Ability to gather and analyze information from various sources', category: 'domain', prerequisites: [], relatedCapabilities: ['analysis', 'webSearch'], complexity: 5, importance: 8, }, analysis: { description: 'Ability to analyze data, patterns, and systems', category: 'technical', prerequisites: [], relatedCapabilities: ['research', 'documentation'], complexity: 7, importance: 8, }, webSearch: { description: 'Ability to search and retrieve information from the web', category: 'system', prerequisites: [], relatedCapabilities: ['research'], complexity: 3, importance: 6, }, apiIntegration: { description: 'Ability to integrate with external APIs and services', category: 'technical', prerequisites: [], relatedCapabilities: ['codeGeneration', 'testing'], complexity: 6, importance: 7, }, fileSystem: { description: 'Ability to read, write, and manipulate files', category: 'system', prerequisites: [], relatedCapabilities: [], complexity: 3, importance: 6, }, terminalAccess: { description: 'Ability to execute commands in terminal/shell', category: 'system', prerequisites: [], relatedCapabilities: ['fileSystem'], complexity: 5, importance: 6, }, }; } /** * Initialize task type requirements */ private initializeTaskRequirements(): Map<string, TaskRequirements> { const requirements = new Map<string, TaskRequirements>(); requirements.set('code-generation', { type: 'code-generation', requiredCapabilities: ['codeGeneration'], preferredCapabilities: ['codeReview', 'testing'], complexity: 'medium', urgency: 'medium', estimatedDuration: 30, dependencies: [], }); requirements.set('testing', { type: 'testing', requiredCapabilities: ['testing'], preferredCapabilities: ['codeGeneration', 'codeReview'], complexity: 'medium', urgency: 'medium', estimatedDuration: 25, dependencies: [], }); requirements.set('research', { type: 'research', requiredCapabilities: ['research'], preferredCapabilities: ['webSearch', 'analysis', 'documentation'], complexity: 'low', urgency: 'low', estimatedDuration: 20, dependencies: [], }); requirements.set('analysis', { type: 'analysis', requiredCapabilities: ['analysis'], preferredCapabilities: ['research', 'documentation'], complexity: 'medium', urgency: 'medium', estimatedDuration: 35, dependencies: [], }); requirements.set('system-design', { type: 'system-design', requiredCapabilities: ['analysis', 'documentation'], preferredCapabilities: ['research', 'codeReview'], complexity: 'high', urgency: 'low', estimatedDuration: 60, dependencies: [], }); return requirements; } /** * Get agent type capabilities */ static getAgentTypeCapabilities(agentType: AgentType): AgentCapabilities { const baseCapabilities: AgentCapabilities = { codeGeneration: false, codeReview: false, testing: false, documentation: false, research: false, analysis: false, webSearch: false, apiIntegration: false, fileSystem: false, terminalAccess: false, languages: [], frameworks: [], domains: [], tools: [], maxConcurrentTasks: 3, maxMemoryUsage: 512 * 1024 * 1024, maxExecutionTime: 300000, reliability: 0.8, speed: 0.8, quality: 0.8, }; switch (agentType) { case 'researcher': return { ...baseCapabilities, research: true, analysis: true, webSearch: true, documentation: true, domains: ['research', 'analysis', 'information-gathering'], tools: ['web-search', 'document-analyzer', 'data-extractor'], }; case 'coder': return { ...baseCapabilities, codeGeneration: true, codeReview: true, testing: true, terminalAccess: true, fileSystem: true, languages: ['typescript', 'javascript', 'python'], frameworks: ['deno', 'node', 'react'], domains: ['web-development', 'backend-development'], tools: ['git', 'editor', 'debugger', 'linter'], }; case 'analyst': return { ...baseCapabilities, analysis: true, research: true, documentation: true, languages: ['python', 'r', 'sql'], frameworks: ['pandas', 'numpy', 'matplotlib'], domains: ['data-analysis', 'statistics', 'visualization'], tools: ['data-processor', 'chart-generator', 'statistical-analyzer'], }; case 'architect': return { ...baseCapabilities, analysis: true, research: true, documentation: true, codeReview: true, domains: ['system-architecture', 'software-architecture', 'cloud-architecture'], tools: ['architecture-diagrams', 'system-modeler', 'design-patterns'], }; case 'tester': return { ...baseCapabilities, testing: true, codeGeneration: true, codeReview: true, terminalAccess: true, frameworks: ['jest', 'cypress', 'playwright'], domains: ['testing', 'quality-assurance', 'automation'], tools: ['test-runner', 'coverage-analyzer', 'browser-automation'], }; case 'coordinator': return { ...baseCapabilities, analysis: true, documentation: true, research: true, domains: ['project-management', 'coordination', 'planning'], tools: ['task-manager', 'workflow-orchestrator', 'communication-hub'], }; default: return baseCapabilities; } } }