Skip to main content
Glama
cbunting99

MCP Code Analysis & Quality Server

by cbunting99
KnowledgeBaseService.ts44.9 kB
// Copyright 2025 Chris Bunting // Brief: Project-specific knowledge base service for MCP Code Analysis & Quality Server // Scope: Manages project-specific knowledge extraction, storage, and retrieval import { EventEmitter } from 'events'; import { AnalysisContext, AnalysisResult, UnifiedAnalysisResult, LoggerInterface, CacheInterface } from '@mcp-code-analysis/shared-types'; export interface KnowledgeBaseConfig { enableLearning: boolean; enableKnowledgeSharing: boolean; maxKnowledgeNodes: number; confidenceThreshold: number; learningRate: number; knowledgeRetention: number; enableInference: boolean; enableValidation: boolean; } export interface KnowledgeNode { id: string; type: NodeType; title: string; description: string; content: string; confidence: number; source: KnowledgeSource; metadata: NodeMetadata; relationships: Relationship[]; tags: string[]; createdAt: Date; updatedAt: Date; accessCount: number; lastAccessed: Date; } export interface Relationship { id: string; type: RelationshipType; sourceNodeId: string; targetNodeId: string; strength: number; description: string; metadata: RelationshipMetadata; createdAt: Date; } export interface KnowledgeGraph { id: string; projectId: string; name: string; description: string; nodes: Map<string, KnowledgeNode>; relationships: Map<string, Relationship>; metadata: GraphMetadata; createdAt: Date; updatedAt: Date; } export interface KnowledgeQuery { query: string; type: QueryType; filters: QueryFilter[]; limit: number; includeRelationships: boolean; context: QueryContext; } export interface KnowledgeExtractionRequest { projectId: string; analysisResults: UnifiedAnalysisResult[]; context: AnalysisContext; extractionType: ExtractionType; options: ExtractionOptions; } export interface KnowledgeInferenceRequest { projectId: string; context: AnalysisContext; inferenceType: InferenceType; premises: string[]; options: InferenceOptions; } export interface KnowledgeValidationRequest { knowledgeNodes: KnowledgeNode[]; validationType: ValidationType; options: ValidationOptions; } export interface NodeMetadata { language: string; technologies: string[]; complexity: number; importance: number; businessImpact: number; technicalImpact: number; userImpact: number; verificationStatus: VerificationStatus; reviewStatus: ReviewStatus; } export interface RelationshipMetadata { correlationStrength: number; causalRelationship: boolean; temporal: boolean; spatial: boolean; logical: boolean; evidence: string[]; } export interface GraphMetadata { totalNodes: number; totalRelationships: number; averageConfidence: number; lastExtraction: Date; lastInference: Date; lastValidation: Date; knowledgeDomains: string[]; completeness: number; } export interface QueryContext { projectId: string; userContext: UserContext; temporalContext: TemporalContext; spatialContext: SpatialContext; domainContext: DomainContext; } export interface UserContext { expertise: ExpertiseLevel; preferences: UserPreferences; history: QueryHistory[]; } export interface TemporalContext { timeframe: Timeframe; timeRange: { start: Date; end: Date; }; } export interface SpatialContext { files: string[]; modules: string[]; components: string[]; } export interface DomainContext { businessDomain: string; technicalDomain: string; industry: string; } export interface QueryFilter { field: string; operator: FilterOperator; value: any; } export interface ExtractionOptions { includeCodeAnalysis: boolean; includeDocumentation: boolean; includeComments: boolean; includeTests: boolean; includeConfiguration: boolean; maxNodesPerExtraction: number; confidenceThreshold: number; } export interface InferenceOptions { maxDepth: number; confidenceThreshold: number; includeExplanations: boolean; includeAlternatives: boolean; reasoningStrategy: ReasoningStrategy; } export interface ValidationOptions { validationLevel: ValidationLevel; crossReference: boolean; consistencyCheck: boolean; completenessCheck: boolean; expertReview: boolean; } export interface QueryHistory { query: string; timestamp: Date; results: number; satisfaction: number; } export interface UserPreferences { preferredLanguages: string[]; preferredTechnologies: string[]; detailLevel: DetailLevel; visualizationPreference: VisualizationType; } export interface KnowledgeExtractionResult { success: boolean; extractedNodes: KnowledgeNode[]; extractedRelationships: Relationship[]; statistics: ExtractionStatistics; errors: string[]; } export interface KnowledgeInferenceResult { success: boolean; inferredNodes: KnowledgeNode[]; inferredRelationships: Relationship[]; reasoning: ReasoningChain[]; confidence: number; alternatives: Alternative[]; errors: string[]; } export interface KnowledgeValidationResult { success: boolean; validatedNodes: ValidatedNode[]; validationReport: ValidationReport; recommendations: ValidationRecommendation[]; errors: string[]; } export interface ExtractionStatistics { totalNodes: number; totalRelationships: number; averageConfidence: number; processingTime: number; sources: ExtractionSource[]; } export interface ExtractionSource { type: SourceType; count: number; confidence: number; } export interface ReasoningChain { id: string; steps: ReasoningStep[]; conclusion: string; confidence: number; } export interface ReasoningStep { step: number; premise: string; inference: string; confidence: number; evidence: string[]; } export interface Alternative { id: string; description: string; confidence: number; reasoning: string; pros: string[]; cons: string[]; } export interface ValidatedNode { nodeId: string; validationStatus: ValidationStatus; confidence: number; issues: ValidationIssue[]; recommendations: string[]; } export interface ValidationReport { totalNodes: number; validNodes: number; invalidNodes: number; questionableNodes: number; averageConfidence: number; mainIssues: string[]; } export interface ValidationRecommendation { type: RecommendationType; description: string; priority: PriorityLevel; effort: number; expectedOutcome: string; } export interface ValidationIssue { type: IssueType; severity: SeverityLevel; description: string; location: string; suggestion: string; } export enum NodeType { CODE_PATTERN = 'code-pattern', ARCHITECTURAL_PATTERN = 'architectural-pattern', DESIGN_PRINCIPLE = 'design-principle', BUSINESS_RULE = 'business-rule', TECHNICAL_DECISION = 'technical-decision', REQUIREMENT = 'requirement', CONSTRAINT = 'constraint', BEST_PRACTICE = 'best-practice', ANTI_PATTERN = 'anti-pattern', DOMAIN_CONCEPT = 'domain-concept', TECHNOLOGY = 'technology', FRAMEWORK = 'framework', LIBRARY = 'library', API = 'api', DATA_MODEL = 'data-model', ALGORITHM = 'algorithm', PROCESS = 'process', WORKFLOW = 'workflow' } export enum RelationshipType { DEPENDS_ON = 'depends-on', IMPLEMENTS = 'implements', EXTENDS = 'extends', USES = 'uses', CONTAINS = 'contains', REFERENCES = 'references', VALIDATES = 'validates', CONTRADICTS = 'contradicts', SIMILAR_TO = 'similar-to', RELATED_TO = 'related-to', CAUSES = 'causes', PREVENTS = 'prevents', ENHANCES = 'enhances', REDUCES = 'reduces', ALTERNATIVE_TO = 'alternative-to' } export enum KnowledgeSource { CODE_ANALYSIS = 'code-analysis', DOCUMENTATION = 'documentation', COMMENTS = 'comments', TESTS = 'tests', CONFIGURATION = 'configuration', EXTERNAL_KNOWLEDGE = 'external-knowledge', USER_INPUT = 'user-input', INFERENCE = 'inference', VALIDATION = 'validation' } export enum QueryType { SEARCH = 'search', EXPLORE = 'explore', RECOMMEND = 'recommend', VALIDATE = 'validate', INFER = 'infer', EXPLAIN = 'explain', COMPARE = 'compare', ANALYZE = 'analyze' } export enum ExtractionType { CODE_PATTERNS = 'code-patterns', ARCHITECTURE = 'architecture', BUSINESS_LOGIC = 'business-logic', DATA_MODELS = 'data-models', API_CONTRACTS = 'api-contracts', CONFIGURATION = 'configuration', DEPENDENCIES = 'dependencies', TEST_PATTERNS = 'test-patterns', DOCUMENTATION = 'documentation' } export enum InferenceType { DEDUCTIVE = 'deductive', INDUCTIVE = 'inductive', ABDUCTIVE = 'abductive', ANALOGICAL = 'analogical', CAUSAL = 'causal', CORRELATIONAL = 'correlational' } export enum ValidationType { CONSISTENCY = 'consistency', COMPLETENESS = 'completeness', ACCURACY = 'accuracy', RELEVANCE = 'relevance', TIMELINESS = 'timeliness', CROSS_REFERENCE = 'cross-reference' } export enum VerificationStatus { UNVERIFIED = 'unverified', VERIFIED = 'verified', DISPUTED = 'disputed', OUTDATED = 'outdated' } export enum ReviewStatus { UNREVIEWED = 'unreviewed', REVIEWED = 'reviewed', APPROVED = 'approved', REJECTED = 'rejected' } export enum ExpertiseLevel { BEGINNER = 'beginner', INTERMEDIATE = 'intermediate', ADVANCED = 'advanced', EXPERT = 'expert' } export enum Timeframe { HOUR = 'hour', DAY = 'day', WEEK = 'week', MONTH = 'month', QUARTER = 'quarter', YEAR = 'year' } export enum FilterOperator { EQUALS = 'equals', NOT_EQUALS = 'not-equals', CONTAINS = 'contains', STARTS_WITH = 'starts-with', ENDS_WITH = 'ends-with', GREATER_THAN = 'greater-than', LESS_THAN = 'less-than', IN = 'in', NOT_IN = 'not-in' } export enum DetailLevel { BASIC = 'basic', DETAILED = 'detailed', COMPREHENSIVE = 'comprehensive' } export enum VisualizationType { GRAPH = 'graph', TREE = 'tree', TABLE = 'table', LIST = 'list' } export enum SourceType { CODE_FILE = 'code-file', DOCUMENTATION_FILE = 'documentation-file', TEST_FILE = 'test-file', CONFIGURATION_FILE = 'configuration-file', COMMENT = 'comment', EXTERNAL_API = 'external-api', USER_INPUT = 'user-input' } export enum ReasoningStrategy { FORWARD_CHAINING = 'forward-chaining', BACKWARD_CHAINING = 'backward-chaining', MIXED_CHAINING = 'mixed-chaining', ANALOGICAL_REASONING = 'analogical-reasoning', CASE_BASED = 'case-based' } export enum ValidationLevel { BASIC = 'basic', STANDARD = 'standard', THOROUGH = 'thorough', COMPREHENSIVE = 'comprehensive' } export enum ValidationStatus { VALID = 'valid', INVALID = 'invalid', QUESTIONABLE = 'questionable', PARTIAL = 'partial' } export enum RecommendationType { ADD_EVIDENCE = 'add-evidence', IMPROVE_CONFIDENCE = 'improve-confidence', UPDATE_CONTENT = 'update-content', REMOVE_NODE = 'remove-node', ADD_RELATIONSHIP = 'add-relationship', VERIFY_SOURCE = 'verify-source' } export enum IssueType { INCONSISTENCY = 'inconsistency', CONTRADICTION = 'contradiction', INCOMPLETENESS = 'incompleteness', INACCURACY = 'inaccuracy', IRRELEVANCE = 'irrelevance', OUTDATED = 'outdated' } export class KnowledgeBaseService extends EventEmitter { private config: KnowledgeBaseConfig; private cache: CacheInterface; private logger: LoggerInterface; private knowledgeGraphs: Map<string, KnowledgeGraph> = new Map(); private extractionEngines: Map<ExtractionType, ExtractionEngine> = new Map(); private inferenceEngines: Map<InferenceType, InferenceEngine> = new Map(); private validationEngines: Map<ValidationType, ValidationEngine> = new Map(); constructor(config: KnowledgeBaseConfig, cache: CacheInterface, logger: LoggerInterface) { super(); this.config = config; this.cache = cache; this.logger = logger; this.setupEventHandlers(); this.initializeEngines(); } private setupEventHandlers(): void { this.on('knowledge-extracted', this.handleKnowledgeExtracted.bind(this)); this.on('knowledge-inferred', this.handleKnowledgeInferred.bind(this)); this.on('knowledge-validated', this.handleKnowledgeValidated.bind(this)); this.on('knowledge-query', this.handleKnowledgeQuery.bind(this)); } private initializeEngines(): void { // Initialize extraction engines this.extractionEngines.set(ExtractionType.CODE_PATTERNS, new CodePatternExtractionEngine()); this.extractionEngines.set(ExtractionType.ARCHITECTURE, new ArchitectureExtractionEngine()); this.extractionEngines.set(ExtractionType.BUSINESS_LOGIC, new BusinessLogicExtractionEngine()); this.extractionEngines.set(ExtractionType.DATA_MODELS, new DataModelExtractionEngine()); this.extractionEngines.set(ExtractionType.API_CONTRACTS, new ApiContractExtractionEngine()); this.extractionEngines.set(ExtractionType.CONFIGURATION, new ConfigurationExtractionEngine()); this.extractionEngines.set(ExtractionType.DEPENDENCIES, new DependencyExtractionEngine()); this.extractionEngines.set(ExtractionType.TEST_PATTERNS, new TestPatternExtractionEngine()); this.extractionEngines.set(ExtractionType.DOCUMENTATION, new DocumentationExtractionEngine()); // Initialize inference engines this.inferenceEngines.set(InferenceType.DEDUCTIVE, new DeductiveInferenceEngine()); this.inferenceEngines.set(InferenceType.INDUCTIVE, new InductiveInferenceEngine()); this.inferenceEngines.set(InferenceType.ABDUCTIVE, new AbductiveInferenceEngine()); this.inferenceEngines.set(InferenceType.ANALOGICAL, new AnalogicalInferenceEngine()); this.inferenceEngines.set(InferenceType.CAUSAL, new CausalInferenceEngine()); this.inferenceEngines.set(InferenceType.CORRELATIONAL, new CorrelationalInferenceEngine()); // Initialize validation engines this.validationEngines.set(ValidationType.CONSISTENCY, new ConsistencyValidationEngine()); this.validationEngines.set(ValidationType.COMPLETENESS, new CompletenessValidationEngine()); this.validationEngines.set(ValidationType.ACCURACY, new AccuracyValidationEngine()); this.validationEngines.set(ValidationType.RELEVANCE, new RelevanceValidationEngine()); this.validationEngines.set(ValidationType.TIMELINESS, new TimelinessValidationEngine()); this.validationEngines.set(ValidationType.CROSS_REFERENCE, new CrossReferenceValidationEngine()); } async initialize(): Promise<void> { this.logger.info('Initializing Knowledge Base Service'); // Load existing knowledge graphs from cache await this.loadKnowledgeGraphs(); this.logger.info('Knowledge Base Service initialized successfully'); } async createKnowledgeGraph(projectId: string, name: string, description: string): Promise<KnowledgeGraph> { const graph: KnowledgeGraph = { id: this.generateGraphId(), projectId, name, description, nodes: new Map(), relationships: new Map(), metadata: { totalNodes: 0, totalRelationships: 0, averageConfidence: 0, lastExtraction: new Date(), lastInference: new Date(), lastValidation: new Date(), knowledgeDomains: [], completeness: 0 }, createdAt: new Date(), updatedAt: new Date() }; this.knowledgeGraphs.set(projectId, graph); await this.saveKnowledgeGraph(projectId); this.emit('graph-created', graph); this.logger.info(`Knowledge graph created for project: ${projectId}`); return graph; } async extractKnowledge(request: KnowledgeExtractionRequest): Promise<KnowledgeExtractionResult> { try { this.logger.info(`Extracting knowledge for project: ${request.projectId}`); const startTime = Date.now(); const graph = this.getOrCreateKnowledgeGraph(request.projectId); const engine = this.extractionEngines.get(request.extractionType); if (!engine) { throw new Error(`No extraction engine found for type: ${request.extractionType}`); } const result = await engine.extract(request, graph); if (result.success) { // Add extracted nodes and relationships to graph for (const node of result.extractedNodes) { graph.nodes.set(node.id, node); } for (const relationship of result.extractedRelationships) { graph.relationships.set(relationship.id, relationship); } // Update graph metadata this.updateGraphMetadata(graph); // Save updated graph await this.saveKnowledgeGraph(request.projectId); this.emit('knowledge-extracted', { projectId: request.projectId, extractionType: request.extractionType, nodesCount: result.extractedNodes.length, relationshipsCount: result.extractedRelationships.length }); } result.statistics.processingTime = Date.now() - startTime; this.logger.info(`Knowledge extraction completed in ${result.statistics.processingTime}ms`); return result; } catch (error) { this.logger.error('Failed to extract knowledge:', error); return { success: false, extractedNodes: [], extractedRelationships: [], statistics: { totalNodes: 0, totalRelationships: 0, averageConfidence: 0, processingTime: 0, sources: [] }, errors: [error.message] }; } } async inferKnowledge(request: KnowledgeInferenceRequest): Promise<KnowledgeInferenceResult> { try { this.logger.info(`Inferring knowledge for project: ${request.projectId}`); const startTime = Date.now(); const graph = this.getKnowledgeGraph(request.projectId); const engine = this.inferenceEngines.get(request.inferenceType); if (!engine) { throw new Error(`No inference engine found for type: ${request.inferenceType}`); } const result = await engine.infer(request, graph); if (result.success) { // Add inferred nodes and relationships to graph for (const node of result.inferredNodes) { if (node.confidence >= this.config.confidenceThreshold) { graph.nodes.set(node.id, node); } } for (const relationship of result.inferredRelationships) { if (relationship.strength >= this.config.confidenceThreshold) { graph.relationships.set(relationship.id, relationship); } } // Update graph metadata this.updateGraphMetadata(graph); // Save updated graph await this.saveKnowledgeGraph(request.projectId); this.emit('knowledge-inferred', { projectId: request.projectId, inferenceType: request.inferenceType, confidence: result.confidence, nodesCount: result.inferredNodes.length, relationshipsCount: result.inferredRelationships.length }); } this.logger.info(`Knowledge inference completed in ${Date.now() - startTime}ms`); return result; } catch (error) { this.logger.error('Failed to infer knowledge:', error); return { success: false, inferredNodes: [], inferredRelationships: [], reasoning: [], confidence: 0, alternatives: [], errors: [error.message] }; } } async validateKnowledge(request: KnowledgeValidationRequest): Promise<KnowledgeValidationResult> { try { this.logger.info('Validating knowledge'); const startTime = Date.now(); const engine = this.validationEngines.get(request.validationType); if (!engine) { throw new Error(`No validation engine found for type: ${request.validationType}`); } const result = await engine.validate(request); if (result.success) { // Update validation status of nodes for (const validatedNode of result.validatedNodes) { // Find and update the node in all graphs for (const graph of this.knowledgeGraphs.values()) { const node = graph.nodes.get(validatedNode.nodeId); if (node) { node.metadata.verificationStatus = this.mapValidationStatus(validatedNode.validationStatus); node.confidence = Math.max(node.confidence, validatedNode.confidence); node.updatedAt = new Date(); } } } // Save all updated graphs for (const projectId of this.knowledgeGraphs.keys()) { await this.saveKnowledgeGraph(projectId); } this.emit('knowledge-validated', { validationType: request.validationType, totalNodes: request.knowledgeNodes.length, validNodes: result.validationReport.validNodes, invalidNodes: result.validationReport.invalidNodes }); } this.logger.info(`Knowledge validation completed in ${Date.now() - startTime}ms`); return result; } catch (error) { this.logger.error('Failed to validate knowledge:', error); return { success: false, validatedNodes: [], validationReport: { totalNodes: 0, validNodes: 0, invalidNodes: 0, questionableNodes: 0, averageConfidence: 0, mainIssues: [] }, recommendations: [], errors: [error.message] }; } } async queryKnowledge(query: KnowledgeQuery): Promise<KnowledgeNode[]> { try { this.logger.info(`Querying knowledge: ${query.query}`); const graph = this.getKnowledgeGraph(query.context.projectId); const results: KnowledgeNode[] = []; // Apply filters and search for (const node of graph.nodes.values()) { if (this.matchesQuery(node, query)) { results.push(node); // Update access statistics node.accessCount++; node.lastAccessed = new Date(); } } // Sort by relevance and confidence results.sort((a, b) => { const relevanceScore = this.calculateRelevanceScore(a, query); const bRelevanceScore = this.calculateRelevanceScore(b, query); return (bRelevanceScore + b.confidence) - (relevanceScore + a.confidence); }); // Apply limit const limitedResults = results.slice(0, query.limit); // Include relationships if requested if (query.includeRelationships) { for (const node of limitedResults) { node.relationships = this.getNodeRelationships(node.id, graph); } } // Save updated graph await this.saveKnowledgeGraph(query.context.projectId); this.emit('knowledge-query', { query: query.query, results: limitedResults.length, projectId: query.context.projectId }); this.logger.info(`Knowledge query returned ${limitedResults.length} results`); return limitedResults; } catch (error) { this.logger.error('Failed to query knowledge:', error); return []; } } async getKnowledgeGraph(projectId: string): Promise<KnowledgeGraph | null> { return this.knowledgeGraphs.get(projectId) || null; } async getAllKnowledgeGraphs(): Promise<KnowledgeGraph[]> { return Array.from(this.knowledgeGraphs.values()); } async deleteKnowledgeGraph(projectId: string): Promise<boolean> { try { const deleted = this.knowledgeGraphs.delete(projectId); if (deleted) { await this.cache.delete(`knowledge-graph-${projectId}`); this.emit('graph-deleted', { projectId }); this.logger.info(`Knowledge graph deleted for project: ${projectId}`); } return deleted; } catch (error) { this.logger.error('Failed to delete knowledge graph:', error); return false; } } async shareKnowledge(sourceProjectId: string, targetProjectId: string, nodeIds: string[]): Promise<boolean> { try { const sourceGraph = this.getKnowledgeGraph(sourceProjectId); const targetGraph = this.getOrCreateKnowledgeGraph(targetProjectId); if (!sourceGraph) { throw new Error(`Source knowledge graph not found: ${sourceProjectId}`); } let sharedCount = 0; for (const nodeId of nodeIds) { const node = sourceGraph.nodes.get(nodeId); if (node) { // Create a copy of the node for the target graph const sharedNode: KnowledgeNode = { ...node, id: this.generateNodeId(), source: KnowledgeSource.EXTERNAL_KNOWLEDGE, createdAt: new Date(), updatedAt: new Date(), accessCount: 0, lastAccessed: new Date() }; targetGraph.nodes.set(sharedNode.id, sharedNode); sharedCount++; } } if (sharedCount > 0) { this.updateGraphMetadata(targetGraph); await this.saveKnowledgeGraph(targetProjectId); this.emit('knowledge-shared', { sourceProjectId, targetProjectId, sharedCount }); this.logger.info(`Shared ${sharedCount} knowledge nodes from ${sourceProjectId} to ${targetProjectId}`); } return sharedCount > 0; } catch (error) { this.logger.error('Failed to share knowledge:', error); return false; } } private getOrCreateKnowledgeGraph(projectId: string): KnowledgeGraph { let graph = this.knowledgeGraphs.get(projectId); if (!graph) { graph = { id: this.generateGraphId(), projectId, name: `${projectId} Knowledge Graph`, description: `Automatically generated knowledge graph for ${projectId}`, nodes: new Map(), relationships: new Map(), metadata: { totalNodes: 0, totalRelationships: 0, averageConfidence: 0, lastExtraction: new Date(), lastInference: new Date(), lastValidation: new Date(), knowledgeDomains: [], completeness: 0 }, createdAt: new Date(), updatedAt: new Date() }; this.knowledgeGraphs.set(projectId, graph); } return graph; } private updateGraphMetadata(graph: KnowledgeGraph): void { graph.metadata.totalNodes = graph.nodes.size; graph.metadata.totalRelationships = graph.relationships.size; // Calculate average confidence const totalConfidence = Array.from(graph.nodes.values()) .reduce((sum, node) => sum + node.confidence, 0); graph.metadata.averageConfidence = graph.nodes.size > 0 ? totalConfidence / graph.nodes.size : 0; // Update knowledge domains const domains = new Set<string>(); for (const node of graph.nodes.values()) { domains.add(node.metadata.technicalImpact > 5 ? 'technical' : 'business'); } graph.metadata.knowledgeDomains = Array.from(domains); // Calculate completeness (simplified) graph.metadata.completeness = Math.min(100, (graph.nodes.size / 100) * 100); graph.updatedAt = new Date(); } private matchesQuery(node: KnowledgeNode, query: KnowledgeQuery): boolean { // Check if node matches query filters for (const filter of query.filters) { if (!this.matchesFilter(node, filter)) { return false; } } // Check if node content matches query string if (query.query) { const queryLower = query.query.toLowerCase(); const contentMatch = node.title.toLowerCase().includes(queryLower) || node.description.toLowerCase().includes(queryLower) || node.content.toLowerCase().includes(queryLower) || node.tags.some(tag => tag.toLowerCase().includes(queryLower)); if (!contentMatch) { return false; } } return true; } private matchesFilter(node: KnowledgeNode, filter: QueryFilter): boolean { const value = this.getNodeFieldValue(node, filter.field); if (value === undefined) { return false; } switch (filter.operator) { case FilterOperator.EQUALS: return value === filter.value; case FilterOperator.NOT_EQUALS: return value !== filter.value; case FilterOperator.CONTAINS: return String(value).toLowerCase().includes(String(filter.value).toLowerCase()); case FilterOperator.STARTS_WITH: return String(value).toLowerCase().startsWith(String(filter.value).toLowerCase()); case FilterOperator.ENDS_WITH: return String(value).toLowerCase().endsWith(String(filter.value).toLowerCase()); case FilterOperator.GREATER_THAN: return Number(value) > Number(filter.value); case FilterOperator.LESS_THAN: return Number(value) < Number(filter.value); case FilterOperator.IN: return Array.isArray(filter.value) && filter.value.includes(value); case FilterOperator.NOT_IN: return Array.isArray(filter.value) && !filter.value.includes(value); default: return false; } } private getNodeFieldValue(node: KnowledgeNode, field: string): any { const fieldPath = field.split('.'); let value: any = node; for (const part of fieldPath) { if (value && typeof value === 'object') { value = value[part]; } else { return undefined; } } return value; } private calculateRelevanceScore(node: KnowledgeNode, query: KnowledgeQuery): number { let score = 0; // Boost score based on user expertise const expertiseMultiplier = { [ExpertiseLevel.BEGINNER]: 1.2, [ExpertiseLevel.INTERMEDIATE]: 1.0, [ExpertiseLevel.ADVANCED]: 0.8, [ExpertiseLevel.EXPERT]: 0.6 }; score *= expertiseMultiplier[query.context.userContext.expertise] || 1.0; // Boost score based on recency const daysSinceAccess = (Date.now() - node.lastAccessed.getTime()) / (1000 * 60 * 60 * 24); if (daysSinceAccess < 7) { score *= 1.2; } // Boost score based on access frequency if (node.accessCount > 10) { score *= 1.1; } return score; } private getNodeRelationships(nodeId: string, graph: KnowledgeGraph): Relationship[] { return Array.from(graph.relationships.values()).filter(rel => rel.sourceNodeId === nodeId || rel.targetNodeId === nodeId ); } private mapValidationStatus(status: ValidationStatus): VerificationStatus { const statusMap = { [ValidationStatus.VALID]: VerificationStatus.VERIFIED, [ValidationStatus.INVALID]: VerificationStatus.DISPUTED, [ValidationStatus.QUESTIONABLE]: VerificationStatus.UNVERIFIED, [ValidationStatus.PARTIAL]: VerificationStatus.UNVERIFIED }; return statusMap[status] || VerificationStatus.UNVERIFIED; } private async loadKnowledgeGraphs(): Promise<void> { try { // Load knowledge graphs from cache const cachedGraphs = await this.cache.get<Map<string, any>>('knowledge-graphs'); if (cachedGraphs) { for (const [projectId, graphData] of Object.entries(cachedGraphs)) { const graph: KnowledgeGraph = { ...graphData, nodes: new Map(Object.entries(graphData.nodes)), relationships: new Map(Object.entries(graphData.relationships)) }; this.knowledgeGraphs.set(projectId, graph); } this.logger.info(`Loaded ${this.knowledgeGraphs.size} knowledge graphs from cache`); } } catch (error) { this.logger.warn('Failed to load knowledge graphs:', error); } } private async saveKnowledgeGraph(projectId: string): Promise<void> { try { const graph = this.knowledgeGraphs.get(projectId); if (graph) { const graphData = { ...graph, nodes: Object.fromEntries(graph.nodes), relationships: Object.fromEntries(graph.relationships) }; await this.cache.set(`knowledge-graph-${projectId}`, graphData, 3600); // Also save to global graphs index const graphsIndex: Record<string, any> = {}; for (const [pid, g] of this.knowledgeGraphs.entries()) { graphsIndex[pid] = { ...g, nodes: Object.fromEntries(g.nodes), relationships: Object.fromEntries(g.relationships) }; } await this.cache.set('knowledge-graphs', graphsIndex, 3600); } } catch (error) { this.logger.warn(`Failed to save knowledge graph for project ${projectId}:`, error); } } // ID generation methods private generateGraphId(): string { return `graph_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`; } private generateNodeId(): string { return `node_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`; } // Event handlers private handleKnowledgeExtracted(data: any): void { this.logger.debug(`Knowledge extracted event handled for project: ${data.projectId}`); } private handleKnowledgeInferred(data: any): void { this.logger.debug(`Knowledge inferred event handled for project: ${data.projectId}`); } private handleKnowledgeValidated(data: any): void { this.logger.debug(`Knowledge validated event handled`); } private handleKnowledgeQuery(data: any): void { this.logger.debug(`Knowledge query event handled for project: ${data.projectId}`); } // Public API methods async updateConfig(config: Partial<KnowledgeBaseConfig>): Promise<void> { this.config = { ...this.config, ...config }; this.logger.info('Knowledge base configuration updated'); } async getKnowledgeStats(): Promise<any> { const totalNodes = Array.from(this.knowledgeGraphs.values()) .reduce((sum, graph) => sum + graph.metadata.totalNodes, 0); const totalRelationships = Array.from(this.knowledgeGraphs.values()) .reduce((sum, graph) => sum + graph.metadata.totalRelationships, 0); const averageConfidence = Array.from(this.knowledgeGraphs.values()) .reduce((sum, graph) => sum + graph.metadata.averageConfidence, 0) / this.knowledgeGraphs.size || 0; return { totalGraphs: this.knowledgeGraphs.size, totalNodes, totalRelationships, averageConfidence, learningEnabled: this.config.enableLearning, knowledgeSharingEnabled: this.config.enableKnowledgeSharing, extractionEngines: this.extractionEngines.size, inferenceEngines: this.inferenceEngines.size, validationEngines: this.validationEngines.size }; } async shutdown(): Promise<void> { this.logger.info('Shutting down Knowledge Base Service'); // Save all knowledge graphs for (const projectId of this.knowledgeGraphs.keys()) { await this.saveKnowledgeGraph(projectId); } // Clear event listeners this.removeAllListeners(); this.logger.info('Knowledge Base Service shutdown complete'); } } // Abstract base classes for engines abstract class ExtractionEngine { abstract extract(request: KnowledgeExtractionRequest, graph: KnowledgeGraph): Promise<KnowledgeExtractionResult>; } abstract class InferenceEngine { abstract infer(request: KnowledgeInferenceRequest, graph: KnowledgeGraph): Promise<KnowledgeInferenceResult>; } abstract class ValidationEngine { abstract validate(request: KnowledgeValidationRequest): Promise<KnowledgeValidationResult>; } // Concrete engine implementations (simplified for brevity) class CodePatternExtractionEngine extends ExtractionEngine { async extract(request: KnowledgeExtractionRequest, graph: KnowledgeGraph): Promise<KnowledgeExtractionResult> { // Implementation for code pattern extraction return { success: true, extractedNodes: [], extractedRelationships: [], statistics: { totalNodes: 0, totalRelationships: 0, averageConfidence: 0, processingTime: 0, sources: [] }, errors: [] }; } } class ArchitectureExtractionEngine extends ExtractionEngine { async extract(request: KnowledgeExtractionRequest, graph: KnowledgeGraph): Promise<KnowledgeExtractionResult> { // Implementation for architecture extraction return { success: true, extractedNodes: [], extractedRelationships: [], statistics: { totalNodes: 0, totalRelationships: 0, averageConfidence: 0, processingTime: 0, sources: [] }, errors: [] }; } } // Additional engine implementations would follow the same pattern... class BusinessLogicExtractionEngine extends ExtractionEngine { async extract(request: KnowledgeExtractionRequest, graph: KnowledgeGraph): Promise<KnowledgeExtractionResult> { return { success: true, extractedNodes: [], extractedRelationships: [], statistics: { totalNodes: 0, totalRelationships: 0, averageConfidence: 0, processingTime: 0, sources: [] }, errors: [] }; } } class DataModelExtractionEngine extends ExtractionEngine { async extract(request: KnowledgeExtractionRequest, graph: KnowledgeGraph): Promise<KnowledgeExtractionResult> { return { success: true, extractedNodes: [], extractedRelationships: [], statistics: { totalNodes: 0, totalRelationships: 0, averageConfidence: 0, processingTime: 0, sources: [] }, errors: [] }; } } class ApiContractExtractionEngine extends ExtractionEngine { async extract(request: KnowledgeExtractionRequest, graph: KnowledgeGraph): Promise<KnowledgeExtractionResult> { return { success: true, extractedNodes: [], extractedRelationships: [], statistics: { totalNodes: 0, totalRelationships: 0, averageConfidence: 0, processingTime: 0, sources: [] }, errors: [] }; } } class ConfigurationExtractionEngine extends ExtractionEngine { async extract(request: KnowledgeExtractionRequest, graph: KnowledgeGraph): Promise<KnowledgeExtractionResult> { return { success: true, extractedNodes: [], extractedRelationships: [], statistics: { totalNodes: 0, totalRelationships: 0, averageConfidence: 0, processingTime: 0, sources: [] }, errors: [] }; } } class DependencyExtractionEngine extends ExtractionEngine { async extract(request: KnowledgeExtractionRequest, graph: KnowledgeGraph): Promise<KnowledgeExtractionResult> { return { success: true, extractedNodes: [], extractedRelationships: [], statistics: { totalNodes: 0, totalRelationships: 0, averageConfidence: 0, processingTime: 0, sources: [] }, errors: [] }; } } class TestPatternExtractionEngine extends ExtractionEngine { async extract(request: KnowledgeExtractionRequest, graph: KnowledgeGraph): Promise<KnowledgeExtractionResult> { return { success: true, extractedNodes: [], extractedRelationships: [], statistics: { totalNodes: 0, totalRelationships: 0, averageConfidence: 0, processingTime: 0, sources: [] }, errors: [] }; } } class DocumentationExtractionEngine extends ExtractionEngine { async extract(request: KnowledgeExtractionRequest, graph: KnowledgeGraph): Promise<KnowledgeExtractionResult> { return { success: true, extractedNodes: [], extractedRelationships: [], statistics: { totalNodes: 0, totalRelationships: 0, averageConfidence: 0, processingTime: 0, sources: [] }, errors: [] }; } } class DeductiveInferenceEngine extends InferenceEngine { async infer(request: KnowledgeInferenceRequest, graph: KnowledgeGraph): Promise<KnowledgeInferenceResult> { return { success: true, inferredNodes: [], inferredRelationships: [], reasoning: [], confidence: 0, alternatives: [], errors: [] }; } } class InductiveInferenceEngine extends InferenceEngine { async infer(request: KnowledgeInferenceRequest, graph: KnowledgeGraph): Promise<KnowledgeInferenceResult> { return { success: true, inferredNodes: [], inferredRelationships: [], reasoning: [], confidence: 0, alternatives: [], errors: [] }; } } class AbductiveInferenceEngine extends InferenceEngine { async infer(request: KnowledgeInferenceRequest, graph: KnowledgeGraph): Promise<KnowledgeInferenceResult> { return { success: true, inferredNodes: [], inferredRelationships: [], reasoning: [], confidence: 0, alternatives: [], errors: [] }; } } class AnalogicalInferenceEngine extends InferenceEngine { async infer(request: KnowledgeInferenceRequest, graph: KnowledgeGraph): Promise<KnowledgeInferenceResult> { return { success: true, inferredNodes: [], inferredRelationships: [], reasoning: [], confidence: 0, alternatives: [], errors: [] }; } } class CausalInferenceEngine extends InferenceEngine { async infer(request: KnowledgeInferenceRequest, graph: KnowledgeGraph): Promise<KnowledgeInferenceResult> { return { success: true, inferredNodes: [], inferredRelationships: [], reasoning: [], confidence: 0, alternatives: [], errors: [] }; } } class CorrelationalInferenceEngine extends InferenceEngine { async infer(request: KnowledgeInferenceRequest, graph: KnowledgeGraph): Promise<KnowledgeInferenceResult> { return { success: true, inferredNodes: [], inferredRelationships: [], reasoning: [], confidence: 0, alternatives: [], errors: [] }; } } class ConsistencyValidationEngine extends ValidationEngine { async validate(request: KnowledgeValidationRequest): Promise<KnowledgeValidationResult> { return { success: true, validatedNodes: [], validationReport: { totalNodes: 0, validNodes: 0, invalidNodes: 0, questionableNodes: 0, averageConfidence: 0, mainIssues: [] }, recommendations: [], errors: [] }; } } class CompletenessValidationEngine extends ValidationEngine { async validate(request: KnowledgeValidationRequest): Promise<KnowledgeValidationResult> { return { success: true, validatedNodes: [], validationReport: { totalNodes: 0, validNodes: 0, invalidNodes: 0, questionableNodes: 0, averageConfidence: 0, mainIssues: [] }, recommendations: [], errors: [] }; } } class AccuracyValidationEngine extends ValidationEngine { async validate(request: KnowledgeValidationRequest): Promise<KnowledgeValidationResult> { return { success: true, validatedNodes: [], validationReport: { totalNodes: 0, validNodes: 0, invalidNodes: 0, questionableNodes: 0, averageConfidence: 0, mainIssues: [] }, recommendations: [], errors: [] }; } } class RelevanceValidationEngine extends ValidationEngine { async validate(request: KnowledgeValidationRequest): Promise<KnowledgeValidationResult> { return { success: true, validatedNodes: [], validationReport: { totalNodes: 0, validNodes: 0, invalidNodes: 0, questionableNodes: 0, averageConfidence: 0, mainIssues: [] }, recommendations: [], errors: [] }; } } class TimelinessValidationEngine extends ValidationEngine { async validate(request: KnowledgeValidationRequest): Promise<KnowledgeValidationResult> { return { success: true, validatedNodes: [], validationReport: { totalNodes: 0, validNodes: 0, invalidNodes: 0, questionableNodes: 0, averageConfidence: 0, mainIssues: [] }, recommendations: [], errors: [] }; } } class CrossReferenceValidationEngine extends ValidationEngine { async validate(request: KnowledgeValidationRequest): Promise<KnowledgeValidationResult> { return { success: true, validatedNodes: [], validationReport: { totalNodes: 0, validNodes: 0, invalidNodes: 0, questionableNodes: 0, averageConfidence: 0, mainIssues: [] }, recommendations: [], errors: [] }; } }

Latest Blog Posts

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/cbunting99/mcp-code-analysis-server'

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