UNPKG

@versatil/sdlc-framework

Version:

🚀 AI-Native SDLC framework with 11-MCP ecosystem, RAG memory, OPERA orchestration, and 6 specialized agents achieving ZERO CONTEXT LOSS. Features complete CI/CD pipeline with 7 GitHub workflows (MCP testing, security scanning, performance benchmarking),

262 lines (228 loc) • 7.56 kB
/** * Cross-Agent Learning System * Enables agents to learn from each other's successes and failures */ import { EnhancedVectorMemoryStore } from './enhanced-vector-memory-store.js'; export interface AgentInteraction { sourceAgent: string; targetAgent: string; context: string; outcome: 'success' | 'failure' | 'initiated'; timestamp: number; metadata?: any; } export interface LearningInsight { pattern: string; confidence: number; applicability: string[]; description: string; } export class CrossAgentLearning { private vectorStore: EnhancedVectorMemoryStore; private interactionHistory: AgentInteraction[] = []; constructor(vectorStore: EnhancedVectorMemoryStore) { this.vectorStore = vectorStore; } /** * Learn from agent interaction */ async learnFromAgentInteraction( sourceAgent: string, targetAgent: string, context: string, outcome: 'success' | 'failure' | 'initiated', metadata?: any ): Promise<void> { const interaction: AgentInteraction = { sourceAgent, targetAgent, context, outcome, timestamp: Date.now(), metadata }; this.interactionHistory.push(interaction); // Store interaction pattern await this.vectorStore.storeMemory({ content: `${sourceAgent} → ${targetAgent}: ${outcome} (${context})`, contentType: 'text', metadata: { agentId: 'cross-agent-learning', timestamp: Date.now(), tags: ['cross-agent', sourceAgent, targetAgent, outcome], source_agent: sourceAgent, target_agent: targetAgent, context, outcome, ...metadata } }); // If successful, store as a reusable pattern if (outcome === 'success') { await this.storeSuccessPattern(sourceAgent, targetAgent, context, metadata); } } /** * Store successful pattern for future use */ private async storeSuccessPattern( sourceAgent: string, targetAgent: string, context: string, metadata?: any ): Promise<void> { await this.vectorStore.storeMemory({ content: `Successful handoff: ${sourceAgent} → ${targetAgent}`, contentType: 'text', metadata: { agentId: 'cross-agent-learning', timestamp: Date.now(), tags: ['cross-agent', 'success-pattern', sourceAgent, targetAgent], source_agent: sourceAgent, target_agent: targetAgent, pattern_type: 'handoff-success', context, reusable: true, ...metadata } }); } /** * Query for similar successful interactions */ async querySimilarSuccesses( sourceAgent: string, targetAgent: string, limit: number = 5 ): Promise<any[]> { const result = await this.vectorStore.queryMemories({ query: `${sourceAgent} ${targetAgent} success`, queryType: 'semantic', agentId: 'cross-agent-learning', topK: limit, filters: { tags: ['cross-agent', 'success'], contentTypes: ['text'] } }); return result.documents || []; } /** * Get recommended next agent based on history */ async getRecommendedNextAgent( currentAgent: string, context: string ): Promise<{ agentId: string; confidence: number } | null> { // Query for successful patterns from this agent const successfulHandoffs = await this.vectorStore.queryMemories({ query: `${currentAgent} successful handoff ${context}`, queryType: 'hybrid', agentId: 'cross-agent-learning', topK: 10, filters: { tags: ['cross-agent', 'success-pattern'], contentTypes: ['text'] } }); if (!successfulHandoffs.documents || successfulHandoffs.documents.length === 0) { return null; } // Count target agents and their success rates const targetAgentCounts: Map<string, { count: number; totalConfidence: number }> = new Map(); for (const doc of successfulHandoffs.documents) { const targetAgent = doc.metadata?.target_agent; if (targetAgent && doc.metadata?.source_agent === currentAgent) { const existing = targetAgentCounts.get(targetAgent) || { count: 0, totalConfidence: 0 }; targetAgentCounts.set(targetAgent, { count: existing.count + 1, totalConfidence: existing.totalConfidence + (doc.metadata?.relevanceScore || 0.5) }); } } // Find best candidate let bestAgent: string | null = null; let bestScore = 0; for (const [agentId, stats] of targetAgentCounts.entries()) { const score = stats.totalConfidence / stats.count; if (score > bestScore) { bestScore = score; bestAgent = agentId; } } if (bestAgent) { return { agentId: bestAgent, confidence: bestScore }; } return null; } /** * Extract learning insights from interaction history */ async extractLearningInsights(): Promise<LearningInsight[]> { const insights: LearningInsight[] = []; // Analyze interaction patterns const agentPairs: Map<string, { success: number; failure: number }> = new Map(); for (const interaction of this.interactionHistory) { const key = `${interaction.sourceAgent}->${interaction.targetAgent}`; const stats = agentPairs.get(key) || { success: 0, failure: 0 }; if (interaction.outcome === 'success') stats.success++; if (interaction.outcome === 'failure') stats.failure++; agentPairs.set(key, stats); } // Generate insights from patterns for (const [pair, stats] of agentPairs.entries()) { const total = stats.success + stats.failure; if (total >= 3) { // Minimum sample size const successRate = stats.success / total; const [source, target] = pair.split('->'); if (successRate > 0.7) { insights.push({ pattern: `High success rate for ${source} → ${target}`, confidence: successRate, applicability: [source, target], description: `${source} successfully hands off to ${target} in ${Math.round(successRate * 100)}% of cases` }); } else if (successRate < 0.3) { insights.push({ pattern: `Low success rate for ${source} → ${target}`, confidence: 1 - successRate, applicability: [source, target], description: `${source} → ${target} handoff may need review (${Math.round(successRate * 100)}% success)` }); } } } return insights; } /** * Get interaction statistics */ getStatistics(): any { const totalInteractions = this.interactionHistory.length; const successful = this.interactionHistory.filter(i => i.outcome === 'success').length; const failed = this.interactionHistory.filter(i => i.outcome === 'failure').length; return { totalInteractions, successful, failed, successRate: totalInteractions > 0 ? successful / totalInteractions : 0, agentPairs: this.getAgentPairStatistics() }; } /** * Get statistics by agent pair */ private getAgentPairStatistics(): any { const pairs: Map<string, any> = new Map(); for (const interaction of this.interactionHistory) { const key = `${interaction.sourceAgent}->${interaction.targetAgent}`; const stats = pairs.get(key) || { success: 0, failure: 0, initiated: 0 }; stats[interaction.outcome]++; pairs.set(key, stats); } return Object.fromEntries(pairs); } }