jay-code
Version:
Streamlined AI CLI orchestration engine with mathematical rigor and enterprise-grade reliability
670 lines (598 loc) • 20.1 kB
text/typescript
/**
* 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;
}
}
}