Skip to main content
Glama

documcp

by tosin2013
enhanced-manager.ts18.1 kB
/** * Enhanced Memory Manager with Learning and Knowledge Graph Integration * Combines Issues #47 and #48 for intelligent memory management */ import { MemoryManager } from './manager.js'; import { MemoryEntry } from './storage.js'; import IncrementalLearningSystem, { ProjectFeatures, LearningInsight } from './learning.js'; import KnowledgeGraph, { RecommendationPath } from './knowledge-graph.js'; export interface EnhancedRecommendation { baseRecommendation: any; learningEnhanced: any; graphBased: RecommendationPath[]; insights: LearningInsight[]; confidence: number; reasoning: string[]; metadata: { usedLearning: boolean; usedKnowledgeGraph: boolean; patternsFound: number; similarProjects: number; }; } export interface IntelligentAnalysis { analysis: any; patterns: string[]; predictions: Array<{ type: 'success_rate' | 'optimal_ssg' | 'potential_issues'; prediction: string; confidence: number; }>; recommendations: string[]; learningData: { similarProjects: number; confidenceLevel: number; dataQuality: 'low' | 'medium' | 'high'; }; } export class EnhancedMemoryManager extends MemoryManager { private learningSystem: IncrementalLearningSystem; private knowledgeGraph: KnowledgeGraph; private initialized: boolean = false; constructor(storageDir?: string) { super(storageDir); this.learningSystem = new IncrementalLearningSystem(this); this.knowledgeGraph = new KnowledgeGraph(this); } async initialize(): Promise<void> { await super.initialize(); if (!this.initialized) { await this.learningSystem.initialize(); await this.knowledgeGraph.initialize(); this.initialized = true; // Set up automatic learning from new memories this.on('memory-created', this.handleNewMemory.bind(this)); } } /** * Enhanced recommendation that combines base analysis with learning and graph intelligence */ async getEnhancedRecommendation( projectPath: string, baseRecommendation: any, projectFeatures: ProjectFeatures, ): Promise<EnhancedRecommendation> { await this.initialize(); // Get learning-enhanced recommendation const learningResult = await this.learningSystem.getImprovedRecommendation( projectFeatures, baseRecommendation, ); // Get knowledge graph-based recommendations const candidateSSGs = this.extractCandidateSSGs(baseRecommendation); const graphRecommendations = await this.knowledgeGraph.getGraphBasedRecommendation( projectFeatures, candidateSSGs, ); // Combine insights and reasoning const allInsights = [...learningResult.insights]; const reasoning: string[] = []; // Add graph-based reasoning if (graphRecommendations.length > 0) { const topRecommendation = graphRecommendations[0]; reasoning.push(...topRecommendation.reasoning); allInsights.push({ type: 'recommendation', message: `Knowledge graph analysis suggests ${topRecommendation.to.label} based on similar successful projects`, confidence: topRecommendation.confidence, actionable: true, data: { graphPath: topRecommendation.path }, }); } // Calculate combined confidence const combinedConfidence = this.calculateCombinedConfidence( baseRecommendation.confidence, learningResult.confidence, graphRecommendations[0]?.confidence || 0, ); // Determine final recommendation const finalRecommendation = learningResult.recommendation; if (graphRecommendations.length > 0 && graphRecommendations[0].confidence > 0.8) { const graphChoice = graphRecommendations[0].to.label; if (graphChoice !== finalRecommendation.recommended) { finalRecommendation.graphSuggestion = graphChoice; finalRecommendation.conflictDetected = true; reasoning.push( `Knowledge graph suggests ${graphChoice} while learning system suggests ${finalRecommendation.recommended}`, ); } } return { baseRecommendation, learningEnhanced: learningResult.recommendation, graphBased: graphRecommendations, insights: allInsights, confidence: combinedConfidence, reasoning, metadata: { usedLearning: learningResult.insights.length > 0, usedKnowledgeGraph: graphRecommendations.length > 0, patternsFound: await this.countRelevantPatterns(projectFeatures), similarProjects: graphRecommendations.length, }, }; } /** * Enhanced analysis that provides intelligent insights */ async getIntelligentAnalysis( projectPath: string, baseAnalysis: any, ): Promise<IntelligentAnalysis> { await this.initialize(); const projectFeatures = this.extractProjectFeatures(baseAnalysis); // Find patterns from similar projects const patterns = await this.findProjectPatterns(projectFeatures); // Generate predictions const predictions = await this.generatePredictions(projectFeatures, patterns); // Generate recommendations const recommendations = await this.generateIntelligentRecommendations( projectFeatures, patterns, predictions, ); // Assess learning data quality const learningData = await this.assessLearningData(projectFeatures); return { analysis: baseAnalysis, patterns: patterns.map((p) => p.description), predictions, recommendations, learningData, }; } /** * Learn from new memory entries automatically */ private async handleNewMemory(memory: MemoryEntry): Promise<void> { try { // Determine outcome for learning const outcome = this.inferOutcome(memory); if (outcome) { await this.learningSystem.learn(memory, outcome); } // Update knowledge graph await this.knowledgeGraph.buildFromMemories(); // Periodically save graph to persistent storage if (Math.random() < 0.1) { // 10% chance to save await this.knowledgeGraph.saveToMemory(); } } catch (error) { console.error('Error in automatic learning:', error); } } /** * Extract project features from analysis data */ private extractProjectFeatures(analysis: any): ProjectFeatures { return { language: analysis.language?.primary || 'unknown', framework: analysis.framework?.name, size: this.categorizeProjectSize(analysis.stats?.files || 0), complexity: this.categorizeProjectComplexity(analysis), hasTests: Boolean(analysis.testing?.hasTests), hasCI: Boolean(analysis.ci?.hasCI), hasDocs: Boolean(analysis.documentation?.exists), teamSize: analysis.team?.size, isOpenSource: Boolean(analysis.repository?.isPublic), }; } private categorizeProjectSize(fileCount: number): 'small' | 'medium' | 'large' { if (fileCount < 50) return 'small'; if (fileCount < 200) return 'medium'; return 'large'; } private categorizeProjectComplexity(analysis: any): 'simple' | 'moderate' | 'complex' { let complexity = 0; if (analysis.dependencies?.count > 20) complexity++; if (analysis.framework?.name) complexity++; if (analysis.testing?.frameworks?.length > 1) complexity++; if (analysis.ci?.workflows?.length > 2) complexity++; if (analysis.architecture?.patterns?.length > 3) complexity++; if (complexity <= 1) return 'simple'; if (complexity <= 3) return 'moderate'; return 'complex'; } /** * Extract candidate SSGs from base recommendation */ private extractCandidateSSGs(baseRecommendation: any): string[] { const candidates = [baseRecommendation.recommended]; if (baseRecommendation.alternatives) { candidates.push(...baseRecommendation.alternatives.map((alt: any) => alt.name || alt)); } return [...new Set(candidates)].filter(Boolean); } /** * Calculate combined confidence from multiple sources */ private calculateCombinedConfidence( baseConfidence: number, learningConfidence: number, graphConfidence: number, ): number { // Weighted average with emphasis on learning and graph data when available const weights = { base: 0.4, learning: learningConfidence > 0 ? 0.4 : 0, graph: graphConfidence > 0 ? 0.2 : 0, }; // Redistribute weights if some sources are unavailable const totalWeight = weights.base + weights.learning + weights.graph; const normalizedWeights = { base: weights.base / totalWeight, learning: weights.learning / totalWeight, graph: weights.graph / totalWeight, }; return ( baseConfidence * normalizedWeights.base + learningConfidence * normalizedWeights.learning + graphConfidence * normalizedWeights.graph ); } /** * Count patterns relevant to project features */ private async countRelevantPatterns(features: ProjectFeatures): Promise<number> { const tags = [features.language, features.framework, features.size].filter( (tag): tag is string => Boolean(tag), ); const memories = await this.search({ tags, }); return memories.length; } /** * Find patterns from similar projects */ private async findProjectPatterns(features: ProjectFeatures): Promise< Array<{ type: string; description: string; confidence: number; frequency: number; }> > { const patterns: Array<{ type: string; description: string; confidence: number; frequency: number; }> = []; // Find similar projects based on features const similarMemories = await this.search({ tags: [features.language], }); if (similarMemories.length >= 3) { // Pattern: Most common SSG for this language const ssgCounts = new Map<string, number>(); for (const memory of similarMemories) { if (memory.metadata.ssg) { ssgCounts.set(memory.metadata.ssg, (ssgCounts.get(memory.metadata.ssg) || 0) + 1); } } if (ssgCounts.size > 0) { const topSSG = Array.from(ssgCounts.entries()).sort(([, a], [, b]) => b - a)[0]; patterns.push({ type: 'ssg_preference', description: `${topSSG[0]} is commonly used with ${features.language} (${topSSG[1]}/${similarMemories.length} projects)`, confidence: topSSG[1] / similarMemories.length, frequency: topSSG[1], }); } // Pattern: Success rate analysis const deploymentMemories = similarMemories.filter((m) => m.type === 'deployment'); if (deploymentMemories.length >= 2) { const successRate = deploymentMemories.filter((m) => m.data.status === 'success').length / deploymentMemories.length; patterns.push({ type: 'success_rate', description: `Similar ${features.language} projects have ${(successRate * 100).toFixed( 0, )}% deployment success rate`, confidence: Math.min(deploymentMemories.length / 10, 1.0), frequency: deploymentMemories.length, }); } } return patterns; } /** * Generate predictions based on patterns and features */ private async generatePredictions( features: ProjectFeatures, patterns: Array<{ type: string; description: string; confidence: number }>, ): Promise< Array<{ type: 'success_rate' | 'optimal_ssg' | 'potential_issues'; prediction: string; confidence: number; }> > { const predictions: Array<{ type: 'success_rate' | 'optimal_ssg' | 'potential_issues'; prediction: string; confidence: number; }> = []; // Predict success rate const successPattern = patterns.find((p) => p.type === 'success_rate'); if (successPattern) { predictions.push({ type: 'success_rate', prediction: `Expected deployment success rate: ${ successPattern.description.match(/(\d+)%/)?.[1] || 'unknown' }%`, confidence: successPattern.confidence, }); } // Predict optimal SSG const ssgPattern = patterns.find((p) => p.type === 'ssg_preference'); if (ssgPattern) { const ssg = ssgPattern.description.split(' ')[0]; predictions.push({ type: 'optimal_ssg', prediction: `${ssg} is likely the optimal choice based on similar projects`, confidence: ssgPattern.confidence, }); } // Predict potential issues if (!features.hasTests && features.size !== 'small') { predictions.push({ type: 'potential_issues', prediction: 'Deployment issues likely due to lack of tests in medium/large project', confidence: 0.7, }); } if (!features.hasCI && features.complexity === 'complex') { predictions.push({ type: 'potential_issues', prediction: 'Complex project without CI/CD may face integration challenges', confidence: 0.6, }); } return predictions; } /** * Generate intelligent recommendations */ private async generateIntelligentRecommendations( features: ProjectFeatures, patterns: Array<{ type: string; description: string; confidence: number }>, predictions: Array<{ type: string; prediction: string; confidence: number }>, ): Promise<string[]> { const recommendations: string[] = []; // Recommendations based on patterns const ssgPattern = patterns.find((p) => p.type === 'ssg_preference'); if (ssgPattern && ssgPattern.confidence > 0.7) { const ssg = ssgPattern.description.split(' ')[0]; recommendations.push( `Consider ${ssg} - it's proven successful for similar ${features.language} projects`, ); } // Recommendations based on predictions const issuesPrediction = predictions.find((p) => p.type === 'potential_issues'); if (issuesPrediction && issuesPrediction.confidence > 0.6) { if (issuesPrediction.prediction.includes('tests')) { recommendations.push('Set up automated testing before deployment to improve success rate'); } if (issuesPrediction.prediction.includes('CI/CD')) { recommendations.push('Implement CI/CD pipeline to handle project complexity'); } } // Recommendations based on features if (features.complexity === 'complex' && !features.hasDocs) { recommendations.push('Invest in comprehensive documentation for this complex project'); } if (features.isOpenSource && features.size === 'large') { recommendations.push( 'Consider community-friendly documentation tools for large open-source project', ); } return recommendations; } /** * Assess quality of learning data */ private async assessLearningData(features: ProjectFeatures): Promise<{ similarProjects: number; confidenceLevel: number; dataQuality: 'low' | 'medium' | 'high'; }> { const tags = [features.language, features.framework].filter((tag): tag is string => Boolean(tag), ); const similarMemories = await this.search({ tags, }); const similarProjects = similarMemories.length; let confidenceLevel = 0; if (similarProjects >= 10) { confidenceLevel = 0.9; } else if (similarProjects >= 5) { confidenceLevel = 0.7; } else if (similarProjects >= 2) { confidenceLevel = 0.5; } else { confidenceLevel = 0.2; } let dataQuality: 'low' | 'medium' | 'high'; if (similarProjects >= 8 && confidenceLevel >= 0.8) { dataQuality = 'high'; } else if (similarProjects >= 3 && confidenceLevel >= 0.5) { dataQuality = 'medium'; } else { dataQuality = 'low'; } return { similarProjects, confidenceLevel, dataQuality, }; } /** * Infer outcome from memory entry */ private inferOutcome(memory: MemoryEntry): 'success' | 'failure' | 'neutral' | null { if (memory.type === 'deployment') { if (memory.data.status === 'success') return 'success'; if (memory.data.status === 'failed') return 'failure'; } if (memory.type === 'recommendation' && memory.data.feedback) { const rating = memory.data.feedback.rating || memory.data.feedback.score; if (rating > 3) return 'success'; if (rating < 3) return 'failure'; } return 'neutral'; } /** * Get comprehensive learning statistics */ async getLearningStatistics(): Promise<{ learning: any; knowledgeGraph: any; combined: { totalMemories: number; enhancedRecommendations: number; accuracyImprovement: number; systemMaturity: 'nascent' | 'developing' | 'mature'; }; }> { const learningStats = await this.learningSystem.getStatistics(); const graphStats = this.knowledgeGraph.getStatistics(); const totalMemories = (await this.search('')).length; const graphStatsResult = await graphStats; const enhancedRecommendations = learningStats.totalPatterns + graphStatsResult.nodeCount; // Estimate accuracy improvement based on data volume let accuracyImprovement = 0; if (totalMemories >= 50) { accuracyImprovement = Math.min(0.3, totalMemories / 200); } // Determine system maturity let systemMaturity: 'nascent' | 'developing' | 'mature'; if (totalMemories >= 100 && learningStats.totalPatterns >= 20) { systemMaturity = 'mature'; } else if (totalMemories >= 20 && learningStats.totalPatterns >= 5) { systemMaturity = 'developing'; } else { systemMaturity = 'nascent'; } return { learning: learningStats, knowledgeGraph: graphStats, combined: { totalMemories, enhancedRecommendations, accuracyImprovement, systemMaturity, }, }; } /** * Close and cleanup */ async close(): Promise<void> { await this.knowledgeGraph.saveToMemory(); await super.close(); } } export default EnhancedMemoryManager;

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/tosin2013/documcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server