Skip to main content
Glama
cbunting99

MCP Code Analysis & Quality Server

by cbunting99
ProgressiveDisclosureService.ts49.6 kB
// Copyright 2025 Chris Bunting // Brief: Progressive disclosure service for MCP Code Analysis & Quality Server // Scope: Manages context-aware information filtering and progressive detail revelation import { EventEmitter } from 'events'; import { AnalysisContext, UnifiedAnalysisResult, LoggerInterface, CacheInterface, PriorityLevel, SeverityLevel } from '@mcp-code-analysis/shared-types'; export interface ProgressiveDisclosureConfig { enableAdaptation: boolean; enablePersonalization: boolean; maxInformationDepth: number; defaultDetailLevel: DetailLevel; adaptationThreshold: number; learningRate: number; enableContextAwareness: boolean; enableInteractiveExploration: boolean; } export interface DisclosureRequest { userId: string; projectId: string; information: InformationItem[]; context: DisclosureContext; options: DisclosureOptions; } export interface DisclosureResponse { success: boolean; disclosedItems: DisclosedItem[]; hiddenItems: HiddenItem[]; reasoning: DisclosureReasoning[]; recommendations: DisclosureRecommendation[]; metadata: DisclosureMetadata; } export interface InformationItem { id: string; type: InformationType; title: string; content: string; complexity: number; importance: number; sensitivity: number; relevance: number; dependencies: string[]; metadata: InformationMetadata; } export interface DisclosedItem { id: string; information: InformationItem; detailLevel: DetailLevel; adaptation: AdaptationInfo; reasoning: string[]; confidence: number; interactions: Interaction[]; } export interface HiddenItem { id: string; reason: HidingReason; detailLevel: DetailLevel; prerequisites: string[]; estimatedRevealTime: Date; confidence: number; } export interface DisclosureContext { userContext: UserContext; projectContext: ProjectContext; temporalContext: TemporalContext; spatialContext: SpatialContext; domainContext: DomainContext; } export interface DisclosureOptions { maxDepth: number; includeReasoning: boolean; includeRecommendations: boolean; adaptationStrategy: AdaptationStrategy; interactionMode: InteractionMode; } export interface DisclosureReasoning { id: string; type: ReasoningType; premise: string; conclusion: string; confidence: number; evidence: string[]; } export interface DisclosureRecommendation { id: string; type: RecommendationType; description: string; priority: PriorityLevel; effort: number; expectedOutcome: string; confidence: number; } export interface DisclosureMetadata { totalItems: number; disclosedItems: number; hiddenItems: number; averageComplexity: number; averageImportance: number; processingTime: number; adaptationApplied: boolean; } export interface UserContext { expertise: ExpertiseLevel; preferences: UserPreferences; history: DisclosureHistory[]; currentFocus: FocusArea; cognitiveLoad: CognitiveLoad; } export interface ProjectContext { phase: ProjectPhase; complexity: number; domain: string; technologies: string[]; teamContext: TeamContext; } export interface TemporalContext { timeframe: Timeframe; urgency: UrgencyLevel; deadline: Date | null; availableTime: number; } export interface SpatialContext { files: string[]; modules: string[]; components: string[]; currentLocation: string; } export interface DomainContext { businessDomain: string; technicalDomain: string; industry: string; regulations: string[]; } export interface InformationMetadata { language: string; technologies: string[]; patterns: string[]; bestPractices: string[]; createdAt: Date; updatedAt: Date; accessCount: number; } export interface AdaptationInfo { originalComplexity: number; adaptedComplexity: number; adaptationType: AdaptationType; factors: AdaptationFactor[]; effectiveness: number; } export interface Interaction { id: string; type: InteractionType; timestamp: Date; userAction: string; systemResponse: string; satisfaction: number; } export interface UserPreferences { preferredLanguages: string[]; preferredTechnologies: string[]; detailLevel: DetailLevel; visualizationPreference: VisualizationType; learningStyle: LearningStyle; cognitiveStyle: CognitiveStyle; } export interface DisclosureHistory { timestamp: Date; informationId: string; action: DisclosureAction; detailLevel: DetailLevel; satisfaction: number; effectiveness: number; } export interface FocusArea { type: FocusType; target: string; priority: number; duration: number; } export interface CognitiveLoad { current: number; capacity: number; factors: CognitiveFactor[]; } export interface TeamContext { size: number; experience: ExperienceLevel; collaborationStyle: CollaborationStyle; communication: CommunicationLevel; } export interface AdaptationFactor { type: FactorType; name: string; value: number; weight: number; description: string; } export interface CognitiveFactor { type: CognitiveFactorType; name: string; value: number; impact: number; description: string; } export enum InformationType { CODE_ANALYSIS = 'code-analysis', ARCHITECTURE = 'architecture', BUSINESS_LOGIC = 'business-logic', DATA_MODEL = 'data-model', API_CONTRACT = 'api-contract', CONFIGURATION = 'configuration', DEPENDENCY = 'dependency', TEST_PATTERN = 'test-pattern', DOCUMENTATION = 'documentation', PERFORMANCE = 'performance', SECURITY = 'security', BEST_PRACTICE = 'best-practice', ANTI_PATTERN = 'anti-pattern', DESIGN_PATTERN = 'design-pattern', REQUIREMENT = 'requirement', CONSTRAINT = 'constraint' } export enum DetailLevel { OVERVIEW = 'overview', BASIC = 'basic', DETAILED = 'detailed', COMPREHENSIVE = 'comprehensive', EXPERT = 'expert' } export enum HidingReason { COMPLEXITY = 'complexity', EXPERTISE = 'expertise', CONTEXT = 'context', DEPENDENCY = 'dependency', SENSITIVITY = 'sensitivity', RELEVANCE = 'relevance', COGNITIVE_LOAD = 'cognitive-load', PRIORITY = 'priority' } export enum ReasoningType { COMPLEXITY_BASED = 'complexity-based', EXPERTISE_BASED = 'expertise-based', CONTEXT_AWARE = 'context-aware', DEPENDENCY_BASED = 'dependency-based', COGNITIVE_LOAD_BASED = 'cognitive-load-based', PRIORITY_BASED = 'priority-based' } export enum RecommendationType { LEARN_MORE = 'learn-more', SIMPLIFY = 'simplify', POSTPONE = 'postpone', DELEGATE = 'delegate', AUTOMATE = 'automate', COLLABORATE = 'collaborate' } export enum AdaptationStrategy { COMPLEXITY_REDUCTION = 'complexity-reduction', ABSTRACTION = 'abstraction', PROGRESSION = 'progression', PERSONALIZATION = 'personalization', CONTEXT_AWARE = 'context-aware' } export enum InteractionMode { PASSIVE = 'passive', INTERACTIVE = 'interactive', GUIDED = 'guided', EXPLORATORY = 'exploratory' } export enum ExpertiseLevel { BEGINNER = 'beginner', INTERMEDIATE = 'intermediate', ADVANCED = 'advanced', EXPERT = 'expert' } export enum LearningStyle { VISUAL = 'visual', AUDITORY = 'auditory', KINESTHETIC = 'kinesthetic', READING = 'reading', MIXED = 'mixed' } export enum CognitiveStyle { ANALYTICAL = 'analytical', INTUITIVE = 'intuitive', SEQUENTIAL = 'sequential', GLOBAL = 'global' } export enum DisclosureAction { REVEAL = 'reveal', HIDE = 'hide', EXPAND = 'expand', COLLAPSE = 'collapse', NAVIGATE = 'navigate' } export enum FocusType { CODE = 'code', ARCHITECTURE = 'architecture', BUSINESS_LOGIC = 'business-logic', DATA = 'data', API = 'api', CONFIGURATION = 'configuration', TESTING = 'testing', DOCUMENTATION = 'documentation' } export enum ProjectPhase { PLANNING = 'planning', DEVELOPMENT = 'development', TESTING = 'testing', DEPLOYMENT = 'deployment', MAINTENANCE = 'maintenance' } export enum Timeframe { IMMEDIATE = 'immediate', SHORT_TERM = 'short-term', MEDIUM_TERM = 'medium-term', LONG_TERM = 'long-term' } export enum UrgencyLevel { LOW = 'low', MEDIUM = 'medium', HIGH = 'high', CRITICAL = 'critical' } export enum ExperienceLevel { JUNIOR = 'junior', MID = 'mid', SENIOR = 'senior', EXPERT = 'expert' } export enum CollaborationStyle { INDEPENDENT = 'independent', COLLABORATIVE = 'collaborative', PAIR_PROGRAMMING = 'pair-programming', MOB_PROGRAMMING = 'mob-programming' } export enum CommunicationLevel { MINIMAL = 'minimal', MODERATE = 'moderate', FREQUENT = 'frequent', CONTINUOUS = 'continuous' } export enum AdaptationType { SIMPLIFICATION = 'simplification', ABSTRACTION = 'abstraction', CHUNKING = 'chunking', VISUALIZATION = 'visualization', ANNOTATION = 'annotation' } export enum FactorType { USER_EXPERTISE = 'user-expertise', INFORMATION_COMPLEXITY = 'information-complexity', CONTEXT_RELEVANCE = 'context-relevance', COGNITIVE_LOAD = 'cognitive-load', TIME_PRESSURE = 'time-pressure', PRIORITY = 'priority' } export enum CognitiveFactorType { WORKING_MEMORY = 'working-memory', ATTENTION_SPAN = 'attention-span', PROCESSING_SPEED = 'processing-speed', COMPREHENSION = 'comprehension' } export enum InteractionType { CLICK = 'click', HOVER = 'hover', EXPAND = 'expand', COLLAPSE = 'collapse', NAVIGATE = 'navigate', SEARCH = 'search', FILTER = 'filter' } export enum VisualizationType { TEXT = 'text', GRAPH = 'graph', TREE = 'tree', TABLE = 'table', DIAGRAM = 'diagram' } export class ProgressiveDisclosureService extends EventEmitter { private config: ProgressiveDisclosureConfig; private cache: CacheInterface; private logger: LoggerInterface; private userProfiles: Map<string, UserProfile> = new Map(); private disclosureAlgorithms: Map<DisclosureAlgorithmType, DisclosureAlgorithm> = new Map(); private adaptationAlgorithms: Map<AdaptationAlgorithmType, AdaptationAlgorithm> = new Map(); constructor(config: ProgressiveDisclosureConfig, cache: CacheInterface, logger: LoggerInterface) { super(); this.config = config; this.cache = cache; this.logger = logger; this.setupEventHandlers(); this.initializeAlgorithms(); } private setupEventHandlers(): void { this.on('information-disclosed', this.handleInformationDisclosed.bind(this)); this.on('information-hidden', this.handleInformationHidden.bind(this)); this.on('adaptation-applied', this.handleAdaptationApplied.bind(this)); this.on('interaction-recorded', this.handleInteractionRecorded.bind(this)); } private initializeAlgorithms(): void { // Initialize disclosure algorithms this.disclosureAlgorithms.set(DisclosureAlgorithmType.COMPLEXITY_BASED, new ComplexityBasedDisclosureAlgorithm()); this.disclosureAlgorithms.set(DisclosureAlgorithmType.EXPERTISE_BASED, new ExpertiseBasedDisclosureAlgorithm()); this.disclosureAlgorithms.set(DisclosureAlgorithmType.CONTEXT_AWARE, new ContextAwareDisclosureAlgorithm()); this.disclosureAlgorithms.set(DisclosureAlgorithmType.COGNITIVE_LOAD_BASED, new CognitiveLoadBasedDisclosureAlgorithm()); this.disclosureAlgorithms.set(DisclosureAlgorithmType.PRIORITY_BASED, new PriorityBasedDisclosureAlgorithm()); // Initialize adaptation algorithms this.adaptationAlgorithms.set(AdaptationAlgorithmType.SIMPLIFICATION, new SimplificationAdaptationAlgorithm()); this.adaptationAlgorithms.set(AdaptationAlgorithmType.ABSTRACTION, new AbstractionAdaptationAlgorithm()); this.adaptationAlgorithms.set(AdaptationAlgorithmType.CHUNKING, new ChunkingAdaptationAlgorithm()); this.adaptationAlgorithms.set(AdaptationAlgorithmType.VISUALIZATION, new VisualizationAdaptationAlgorithm()); this.adaptationAlgorithms.set(AdaptationAlgorithmType.PERSONALIZATION, new PersonalizationAdaptationAlgorithm()); } async initialize(): Promise<void> { this.logger.info('Initializing Progressive Disclosure Service'); // Load existing user profiles from cache await this.loadUserProfiles(); this.logger.info('Progressive Disclosure Service initialized successfully'); } async discloseInformation(request: DisclosureRequest): Promise<DisclosureResponse> { try { this.logger.info(`Processing disclosure request for user: ${request.userId}`); const startTime = Date.now(); // Get or create user profile let userProfile = this.userProfiles.get(request.userId); if (!userProfile) { userProfile = await this.createUserProfile(request.userId, request.context.userContext); } // Analyze information and determine disclosure strategy const analysis = await this.analyzeInformation(request, userProfile); // Apply disclosure algorithms const disclosureResult = await this.applyDisclosureAlgorithms(request, analysis, userProfile); // Apply adaptation if enabled let adaptationApplied = false; if (this.config.enableAdaptation) { const adaptationResult = await this.applyAdaptation(disclosureResult.disclosedItems, request, userProfile); disclosureResult.disclosedItems = adaptationResult.adaptedItems; adaptationApplied = adaptationResult.adaptationApplied; } // Generate reasoning and recommendations const reasoning = await this.generateReasoning(disclosureResult, request, userProfile); const recommendations = await this.generateRecommendations(disclosureResult, request, userProfile); // Create response const response: DisclosureResponse = { success: true, disclosedItems: disclosureResult.disclosedItems, hiddenItems: disclosureResult.hiddenItems, reasoning, recommendations, metadata: { totalItems: request.information.length, disclosedItems: disclosureResult.disclosedItems.length, hiddenItems: disclosureResult.hiddenItems.length, averageComplexity: this.calculateAverageComplexity(disclosureResult.disclosedItems), averageImportance: this.calculateAverageImportance(disclosureResult.disclosedItems), processingTime: Date.now() - startTime, adaptationApplied } }; // Update user profile with interaction history await this.updateUserProfile(userProfile, request, response); // Save updated profile await this.saveUserProfile(userProfile.id); this.emit('information-disclosed', { userId: request.userId, projectId: request.projectId, disclosedCount: response.disclosedItems.length, hiddenCount: response.hiddenItems.length }); this.logger.info(`Successfully processed disclosure request for user: ${request.userId}`); return response; } catch (error) { this.logger.error('Failed to disclose information:', error); return { success: false, disclosedItems: [], hiddenItems: [], reasoning: [], recommendations: [], metadata: { totalItems: 0, disclosedItems: 0, hiddenItems: 0, averageComplexity: 0, averageImportance: 0, processingTime: 0, adaptationApplied: false } }; } } async recordInteraction(interaction: InteractionRecord): Promise<boolean> { try { this.logger.info(`Recording interaction for user: ${interaction.userId}`); const userProfile = this.userProfiles.get(interaction.userId); if (!userProfile) { throw new Error(`User profile not found: ${interaction.userId}`); } // Update user history const historyEntry: DisclosureHistory = { timestamp: interaction.timestamp, informationId: interaction.informationId, action: interaction.action, detailLevel: interaction.detailLevel, satisfaction: interaction.satisfaction, effectiveness: interaction.effectiveness }; userProfile.context.history.push(historyEntry); // Update user preferences based on interaction if (this.config.enablePersonalization) { await this.updateUserPreferences(userProfile, interaction); } // Update cognitive load await this.updateCognitiveLoad(userProfile, interaction); // Save updated profile await this.saveUserProfile(userProfile.id); this.emit('interaction-recorded', { userId: interaction.userId, action: interaction.action, satisfaction: interaction.satisfaction }); this.logger.info(`Successfully recorded interaction for user: ${interaction.userId}`); return true; } catch (error) { this.logger.error('Failed to record interaction:', error); return false; } } async getUserProfile(userId: string): Promise<UserProfile | null> { return this.userProfiles.get(userId) || null; } async updateUserPreferences(userId: string, preferences: Partial<UserPreferences>): Promise<boolean> { try { const userProfile = this.userProfiles.get(userId); if (!userProfile) { throw new Error(`User profile not found: ${userId}`); } userProfile.context.preferences = { ...userProfile.context.preferences, ...preferences }; userProfile.updatedAt = new Date(); await this.saveUserProfile(userId); this.logger.info(`Successfully updated preferences for user: ${userId}`); return true; } catch (error) { this.logger.error('Failed to update user preferences:', error); return false; } } private async createUserProfile(userId: string, userContext: UserContext): Promise<UserProfile> { const profile: UserProfile = { id: userId, context: userContext, createdAt: new Date(), updatedAt: new Date() }; this.userProfiles.set(userId, profile); await this.saveUserProfile(userId); this.emit('user-profile-created', profile); this.logger.info(`User profile created for user: ${userId}`); return profile; } private async analyzeInformation(request: DisclosureRequest, userProfile: UserProfile): Promise<InformationAnalysis> { const analysis: InformationAnalysis = { complexityScore: 0, relevanceScore: 0, cognitiveLoadEstimate: 0, dependencies: new Map<string, string[]>(), shouldAdapt: false, adaptationFactors: [] }; // Calculate complexity score analysis.complexityScore = request.information.reduce((sum, item) => sum + item.complexity, 0) / request.information.length; // Calculate relevance score analysis.relevanceScore = request.information.reduce((sum, item) => sum + item.relevance, 0) / request.information.length; // Estimate cognitive load analysis.cognitiveLoadEstimate = await this.estimateCognitiveLoad(request, userProfile); // Analyze dependencies for (const item of request.information) { analysis.dependencies.set(item.id, item.dependencies); } // Determine if adaptation is needed analysis.shouldAdapt = analysis.complexityScore > 7 || analysis.cognitiveLoadEstimate > userProfile.context.cognitiveLoad.capacity * 0.8; // Identify adaptation factors if (analysis.shouldAdapt) { analysis.adaptationFactors = await this.identifyAdaptationFactors(request, userProfile, analysis); } return analysis; } private async applyDisclosureAlgorithms( request: DisclosureRequest, analysis: InformationAnalysis, userProfile: UserProfile ): Promise<DisclosureResult> { const disclosedItems: DisclosedItem[] = []; const hiddenItems: HiddenItem[] = []; for (const item of request.information) { const disclosureDecision = await this.makeDisclosureDecision(item, request, analysis, userProfile); if (disclosureDecision.shouldDisclose) { const disclosedItem: DisclosedItem = { id: item.id, information: item, detailLevel: disclosureDecision.detailLevel, adaptation: disclosureDecision.adaptation || { originalComplexity: item.complexity, adaptedComplexity: item.complexity, adaptationType: AdaptationType.SIMPLIFICATION, factors: [], effectiveness: 1.0 }, reasoning: disclosureDecision.reasoning, confidence: disclosureDecision.confidence, interactions: [] }; disclosedItems.push(disclosedItem); } else { const hiddenItem: HiddenItem = { id: item.id, reason: disclosureDecision.hidingReason, detailLevel: disclosureDecision.detailLevel, prerequisites: disclosureDecision.prerequisites, estimatedRevealTime: disclosureDecision.estimatedRevealTime, confidence: disclosureDecision.confidence }; hiddenItems.push(hiddenItem); } } return { disclosedItems, hiddenItems }; } private async makeDisclosureDecision( item: InformationItem, request: DisclosureRequest, analysis: InformationAnalysis, userProfile: UserProfile ): Promise<DisclosureDecision> { let shouldDisclose = true; let hidingReason: HidingReason | null = null; let detailLevel = this.config.defaultDetailLevel; let confidence = 0.5; let reasoning: string[] = []; let prerequisites: string[] = []; let estimatedRevealTime = new Date(); let adaptation: AdaptationInfo | null = null; // Apply disclosure algorithms for (const [type, algorithm] of this.disclosureAlgorithms) { try { const result = await algorithm.shouldDisclose(item, request, analysis, userProfile); if (!result.shouldDisclose) { shouldDisclose = false; hidingReason = result.reason; detailLevel = result.detailLevel; prerequisites = result.prerequisites; estimatedRevealTime = result.estimatedRevealTime; } confidence = Math.max(confidence, result.confidence); reasoning.push(...result.reasoning); if (result.adaptation) { adaptation = result.adaptation; } } catch (error) { this.logger.warn(`Failed to apply disclosure algorithm ${type}:`, error); } } // Apply depth limit if (request.options.maxDepth > 0) { const currentDepth = this.detailLevelToDepth(detailLevel); if (currentDepth > request.options.maxDepth) { shouldDisclose = false; hidingReason = HidingReason.COMPLEXITY; detailLevel = this.depthToDetailLevel(request.options.maxDepth); reasoning.push('Depth limit exceeded'); } } return { shouldDisclose, hidingReason, detailLevel, confidence, reasoning, prerequisites, estimatedRevealTime, adaptation }; } private async applyAdaptation( disclosedItems: DisclosedItem[], request: DisclosureRequest, userProfile: UserProfile ): Promise<AdaptationResult> { let adaptationApplied = false; const adaptedItems: DisclosedItem[] = []; for (const item of disclosedItems) { let shouldAdapt = false; let bestAdaptation: AdaptationInfo | null = null; let bestEffectiveness = 0; // Try each adaptation algorithm for (const [type, algorithm] of this.adaptationAlgorithms) { try { const result = await algorithm.shouldAdapt(item, request, userProfile); if (result.shouldAdapt && result.effectiveness > bestEffectiveness) { shouldAdapt = true; bestAdaptation = result.adaptation; bestEffectiveness = result.effectiveness; } } catch (error) { this.logger.warn(`Failed to apply adaptation algorithm ${type}:`, error); } } if (shouldAdapt && bestAdaptation) { item.adaptation = bestAdaptation; adaptationApplied = true; } adaptedItems.push(item); } return { adaptedItems, adaptationApplied }; } private async generateReasoning( result: DisclosureResult, request: DisclosureRequest, userProfile: UserProfile ): Promise<DisclosureReasoning[]> { const reasoning: DisclosureReasoning[] = []; // Generate reasoning for disclosed items for (const item of result.disclosedItems) { const reasoningEntry: DisclosureReasoning = { id: this.generateReasoningId(), type: ReasoningType.COMPLEXITY_BASED, premise: `Item complexity: ${item.information.complexity}, User expertise: ${userProfile.context.expertise}`, conclusion: `Item disclosed at ${item.detailLevel} level`, confidence: item.confidence, evidence: item.reasoning }; reasoning.push(reasoningEntry); } // Generate reasoning for hidden items for (const item of result.hiddenItems) { const reasoningEntry: DisclosureReasoning = { id: this.generateReasoningId(), type: ReasoningType.EXPERTISE_BASED, premise: `Item hidden due to ${item.reason}`, conclusion: `Item will be revealed when prerequisites are met`, confidence: item.confidence, evidence: [`Prerequisites: ${item.prerequisites.join(', ')}`] }; reasoning.push(reasoningEntry); } return reasoning; } private async generateRecommendations( result: DisclosureResult, request: DisclosureRequest, userProfile: UserProfile ): Promise<DisclosureRecommendation[]> { const recommendations: DisclosureRecommendation[] = []; // Generate recommendations based on hidden items for (const item of result.hiddenItems) { switch (item.reason) { case HidingReason.COMPLEXITY: recommendations.push({ id: this.generateRecommendationId(), type: RecommendationType.SIMPLIFY, description: `Consider simplifying the information for better understanding`, priority: PriorityLevel.MEDIUM, effort: 3, expectedOutcome: 'Improved comprehension and reduced cognitive load', confidence: 0.8 }); break; case HidingReason.EXPERTISE: recommendations.push({ id: this.generateRecommendationId(), type: RecommendationType.LEARN_MORE, description: `Consider learning prerequisites to access this information`, priority: PriorityLevel.LOW, effort: 5, expectedOutcome: 'Access to more detailed information', confidence: 0.7 }); break; case HidingReason.COGNITIVE_LOAD: recommendations.push({ id: this.generateRecommendationId(), type: RecommendationType.POSTPONE, description: `Consider reviewing this information when cognitive load is lower`, priority: PriorityLevel.MEDIUM, effort: 1, expectedOutcome: 'Better information retention and understanding', confidence: 0.9 }); break; } } // Generate recommendations based on adaptation effectiveness if (result.disclosedItems.some(item => item.adaptation.effectiveness < 0.7)) { recommendations.push({ id: this.generateRecommendationId(), type: RecommendationType.AUTOMATE, description: 'Consider automating information adaptation for better effectiveness', priority: PriorityLevel.HIGH, effort: 7, expectedOutcome: 'Improved adaptation effectiveness and user experience', confidence: 0.8 }); } return recommendations; } private async updateUserPreferences(userProfile: UserProfile, interaction: InteractionRecord): Promise<void> { // Update preferences based on interaction patterns if (interaction.satisfaction > 0.8) { // User is satisfied with current detail level userProfile.context.preferences.detailLevel = interaction.detailLevel; } // Update visualization preference based on interaction type if (interaction.action === DisclosureAction.NAVIGATE) { userProfile.context.preferences.visualizationPreference = VisualizationType.GRAPH; } } private async updateCognitiveLoad(userProfile: UserProfile, interaction: InteractionRecord): Promise<void> { // Update cognitive load based on interaction effectiveness const loadChange = (1 - interaction.effectiveness) * 0.2; userProfile.context.cognitiveLoad.current = Math.min( userProfile.context.cognitiveLoad.capacity, userProfile.context.cognitiveLoad.current + loadChange ); // Gradually reduce cognitive load over time setTimeout(() => { userProfile.context.cognitiveLoad.current = Math.max( 0, userProfile.context.cognitiveLoad.current - 0.1 ); }, 5000); } private async updateUserProfile(userProfile: UserProfile, request: DisclosureRequest, response: DisclosureResponse): Promise<void> { // Update user profile with disclosure history for (const item of response.disclosedItems) { const historyEntry: DisclosureHistory = { timestamp: new Date(), informationId: item.id, action: DisclosureAction.REVEAL, detailLevel: item.detailLevel, satisfaction: 0.8, // Default satisfaction effectiveness: item.confidence }; userProfile.context.history.push(historyEntry); } userProfile.updatedAt = new Date(); } private async estimateCognitiveLoad(request: DisclosureRequest, userProfile: UserProfile): Promise<number> { let estimatedLoad = 0; // Base load from information complexity const complexityLoad = request.information.reduce((sum, item) => sum + item.complexity, 0) / request.information.length; // Adjust based on user expertise const expertiseMultiplier = { [ExpertiseLevel.BEGINNER]: 1.5, [ExpertiseLevel.INTERMEDIATE]: 1.2, [ExpertiseLevel.ADVANCED]: 1.0, [ExpertiseLevel.EXPERT]: 0.8 }; estimatedLoad = complexityLoad * expertiseMultiplier[userProfile.context.expertise]; // Adjust based on time pressure if (request.context.temporalContext.urgency === UrgencyLevel.HIGH) { estimatedLoad *= 1.3; } // Adjust based on current cognitive load const currentLoadRatio = userProfile.context.cognitiveLoad.current / userProfile.context.cognitiveLoad.capacity; if (currentLoadRatio > 0.8) { estimatedLoad *= 1.5; } return Math.min(10, estimatedLoad); } private async identifyAdaptationFactors( request: DisclosureRequest, userProfile: UserProfile, analysis: InformationAnalysis ): Promise<AdaptationFactor[]> { const factors: AdaptationFactor[] = []; // User expertise factor factors.push({ type: FactorType.USER_EXPERTISE, name: 'User Expertise', value: this.expertiseToValue(userProfile.context.expertise), weight: 0.3, description: 'User\'s level of expertise affects information complexity tolerance' }); // Information complexity factor factors.push({ type: FactorType.INFORMATION_COMPLEXITY, name: 'Information Complexity', value: analysis.complexityScore, weight: 0.4, description: 'Complexity of the information being disclosed' }); // Cognitive load factor factors.push({ type: FactorType.COGNITIVE_LOAD, name: 'Cognitive Load', value: analysis.cognitiveLoadEstimate, weight: 0.3, description: 'Current cognitive load of the user' }); return factors; } private expertiseToValue(expertise: ExpertiseLevel): number { const valueMap = { [ExpertiseLevel.BEGINNER]: 0.2, [ExpertiseLevel.INTERMEDIATE]: 0.5, [ExpertiseLevel.ADVANCED]: 0.8, [ExpertiseLevel.EXPERT]: 1.0 }; return valueMap[expertise]; } private detailLevelToDepth(detailLevel: DetailLevel): number { const depthMap = { [DetailLevel.OVERVIEW]: 1, [DetailLevel.BASIC]: 2, [DetailLevel.DETAILED]: 3, [DetailLevel.COMPREHENSIVE]: 4, [DetailLevel.EXPERT]: 5 }; return depthMap[detailLevel]; } private depthToDetailLevel(depth: number): DetailLevel { const levelMap = { 1: DetailLevel.OVERVIEW, 2: DetailLevel.BASIC, 3: DetailLevel.DETAILED, 4: DetailLevel.COMPREHENSIVE, 5: DetailLevel.EXPERT }; return levelMap[Math.min(5, Math.max(1, depth))]; } private calculateAverageComplexity(items: DisclosedItem[]): number { if (items.length === 0) return 0; const totalComplexity = items.reduce((sum, item) => sum + item.information.complexity, 0); return totalComplexity / items.length; } private calculateAverageImportance(items: DisclosedItem[]): number { if (items.length === 0) return 0; const totalImportance = items.reduce((sum, item) => sum + item.information.importance, 0); return totalImportance / items.length; } private async loadUserProfiles(): Promise<void> { try { const cachedProfiles = await this.cache.get<Map<string, any>>('user-profiles-disclosure'); if (cachedProfiles) { for (const [userId, profileData] of Object.entries(cachedProfiles)) { this.userProfiles.set(userId, profileData); } } this.logger.info(`Loaded ${this.userProfiles.size} user profiles`); } catch (error) { this.logger.warn('Failed to load user profiles:', error); } } private async saveUserProfile(userId: string): Promise<void> { try { const profile = this.userProfiles.get(userId); if (profile) { await this.cache.set(`user-profile-disclosure-${userId}`, profile, 3600); // Also save to global profiles index const profilesIndex: Record<string, any> = {}; for (const [uid, p] of this.userProfiles.entries()) { profilesIndex[uid] = p; } await this.cache.set('user-profiles-disclosure', profilesIndex, 3600); } } catch (error) { this.logger.warn(`Failed to save user profile for user ${userId}:`, error); } } // ID generation methods private generateReasoningId(): string { return `reasoning_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`; } private generateRecommendationId(): string { return `recommendation_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`; } // Event handlers private handleInformationDisclosed(data: any): void { this.logger.debug(`Information disclosed event handled for user: ${data.userId}`); } private handleInformationHidden(data: any): void { this.logger.debug(`Information hidden event handled`); } private handleAdaptationApplied(data: any): void { this.logger.debug(`Adaptation applied event handled`); } private handleInteractionRecorded(data: any): void { this.logger.debug(`Interaction recorded event handled for user: ${data.userId}`); } // Public API methods async updateConfig(config: Partial<ProgressiveDisclosureConfig>): Promise<void> { this.config = { ...this.config, ...config }; this.logger.info('Progressive disclosure configuration updated'); } async getDisclosureStats(): Promise<any> { const totalUsers = this.userProfiles.size; const totalInteractions = Array.from(this.userProfiles.values()) .reduce((sum, profile) => sum + profile.context.history.length, 0); const averageSatisfaction = Array.from(this.userProfiles.values()) .reduce((sum, profile) => { const userSatisfaction = profile.context.history.reduce((userSum, history) => userSum + history.satisfaction, 0 ); return sum + (userSatisfaction / Math.max(1, profile.context.history.length)); }, 0) / Math.max(1, this.userProfiles.size); return { totalUsers, totalInteractions, averageSatisfaction, adaptationEnabled: this.config.enableAdaptation, personalizationEnabled: this.config.enablePersonalization, disclosureAlgorithms: this.disclosureAlgorithms.size, adaptationAlgorithms: this.adaptationAlgorithms.size }; } async shutdown(): Promise<void> { this.logger.info('Shutting down Progressive Disclosure Service'); // Save all user profiles for (const userId of this.userProfiles.keys()) { await this.saveUserProfile(userId); } // Clear event listeners this.removeAllListeners(); this.logger.info('Progressive Disclosure Service shutdown complete'); } } // Type definitions for intermediate results interface InformationAnalysis { complexityScore: number; relevanceScore: number; cognitiveLoadEstimate: number; dependencies: Map<string, string[]>; shouldAdapt: boolean; adaptationFactors: AdaptationFactor[]; } interface DisclosureResult { disclosedItems: DisclosedItem[]; hiddenItems: HiddenItem[]; } interface DisclosureDecision { shouldDisclose: boolean; hidingReason: HidingReason | null; detailLevel: DetailLevel; confidence: number; reasoning: string[]; prerequisites: string[]; estimatedRevealTime: Date; adaptation: AdaptationInfo | null; } interface AdaptationResult { adaptedItems: DisclosedItem[]; adaptationApplied: boolean; } interface UserProfile { id: string; context: UserContext; createdAt: Date; updatedAt: Date; } interface InteractionRecord { userId: string; informationId: string; timestamp: Date; action: DisclosureAction; detailLevel: DetailLevel; satisfaction: number; effectiveness: number; } // Algorithm type definitions enum DisclosureAlgorithmType { COMPLEXITY_BASED = 'complexity-based', EXPERTISE_BASED = 'expertise-based', CONTEXT_AWARE = 'context-aware', COGNITIVE_LOAD_BASED = 'cognitive-load-based', PRIORITY_BASED = 'priority-based' } enum AdaptationAlgorithmType { SIMPLIFICATION = 'simplification', ABSTRACTION = 'abstraction', CHUNKING = 'chunking', VISUALIZATION = 'visualization', PERSONALIZATION = 'personalization' } // Abstract base classes for algorithms abstract class DisclosureAlgorithm { abstract shouldDisclose( item: InformationItem, request: DisclosureRequest, analysis: InformationAnalysis, userProfile: UserProfile ): Promise<DisclosureAlgorithmResult>; } abstract class AdaptationAlgorithm { abstract shouldAdapt( item: DisclosedItem, request: DisclosureRequest, userProfile: UserProfile ): Promise<AdaptationAlgorithmResult>; } // Result type definitions interface DisclosureAlgorithmResult { shouldDisclose: boolean; reason: HidingReason; detailLevel: DetailLevel; confidence: number; reasoning: string[]; prerequisites: string[]; estimatedRevealTime: Date; adaptation: AdaptationInfo | null; } interface AdaptationAlgorithmResult { shouldAdapt: boolean; adaptation: AdaptationInfo; effectiveness: number; } // Concrete algorithm implementations (simplified) class ComplexityBasedDisclosureAlgorithm extends DisclosureAlgorithm { async shouldDisclose( item: InformationItem, request: DisclosureRequest, analysis: InformationAnalysis, userProfile: UserProfile ): Promise<DisclosureAlgorithmResult> { const complexityThreshold = this.getComplexityThreshold(userProfile.context.expertise); if (item.complexity > complexityThreshold) { return { shouldDisclose: false, reason: HidingReason.COMPLEXITY, detailLevel: DetailLevel.OVERVIEW, confidence: 0.8, reasoning: ['Information complexity exceeds user expertise threshold'], prerequisites: [], estimatedRevealTime: new Date(Date.now() + 24 * 60 * 60 * 1000), // 24 hours adaptation: null }; } return { shouldDisclose: true, reason: HidingReason.COMPLEXITY, detailLevel: this.getDetailLevelForComplexity(item.complexity), confidence: 0.9, reasoning: ['Information complexity within acceptable range'], prerequisites: [], estimatedRevealTime: new Date(), adaptation: null }; } private getComplexityThreshold(expertise: ExpertiseLevel): number { const thresholds = { [ExpertiseLevel.BEGINNER]: 3, [ExpertiseLevel.INTERMEDIATE]: 5, [ExpertiseLevel.ADVANCED]: 7, [ExpertiseLevel.EXPERT]: 9 }; return thresholds[expertise]; } private getDetailLevelForComplexity(complexity: number): DetailLevel { if (complexity <= 2) return DetailLevel.OVERVIEW; if (complexity <= 4) return DetailLevel.BASIC; if (complexity <= 6) return DetailLevel.DETAILED; if (complexity <= 8) return DetailLevel.COMPREHENSIVE; return DetailLevel.EXPERT; } } class ExpertiseBasedDisclosureAlgorithm extends DisclosureAlgorithm { async shouldDisclose( item: InformationItem, request: DisclosureRequest, analysis: InformationAnalysis, userProfile: UserProfile ): Promise<DisclosureAlgorithmResult> { const expertiseMatch = this.calculateExpertiseMatch(item, userProfile); if (expertiseMatch < 0.5) { return { shouldDisclose: false, reason: HidingReason.EXPERTISE, detailLevel: DetailLevel.OVERVIEW, confidence: 0.7, reasoning: ['Information requires higher expertise level'], prerequisites: this.getPrerequisitesForExpertise(item, userProfile), estimatedRevealTime: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000), // 7 days adaptation: null }; } return { shouldDisclose: true, reason: HidingReason.EXPERTISE, detailLevel: this.getDetailLevelForExpertise(expertiseMatch), confidence: 0.8, reasoning: ['Information matches user expertise level'], prerequisites: [], estimatedRevealTime: new Date(), adaptation: null }; } private calculateExpertiseMatch(item: InformationItem, userProfile: UserProfile): number { // Simplified expertise matching logic const userExpertiseValue = this.expertiseToValue(userProfile.context.expertise); const requiredExpertise = item.complexity / 10; return Math.min(1, userExpertiseValue / requiredExpertise); } private getPrerequisitesForExpertise(item: InformationItem, userProfile: UserProfile): string[] { // Generate prerequisites based on expertise gap const gap = item.complexity - this.expertiseToValue(userProfile.context.expertise) * 10; if (gap > 5) { return ['Complete basic training', 'Gain intermediate experience']; } else if (gap > 2) { return ['Review related concepts', 'Practice with examples']; } return []; } private getDetailLevelForExpertise(expertiseMatch: number): DetailLevel { if (expertiseMatch >= 0.9) return DetailLevel.EXPERT; if (expertiseMatch >= 0.7) return DetailLevel.COMPREHENSIVE; if (expertiseMatch >= 0.5) return DetailLevel.DETAILED; if (expertiseMatch >= 0.3) return DetailLevel.BASIC; return DetailLevel.OVERVIEW; } private expertiseToValue(expertise: ExpertiseLevel): number { const valueMap = { [ExpertiseLevel.BEGINNER]: 0.2, [ExpertiseLevel.INTERMEDIATE]: 0.5, [ExpertiseLevel.ADVANCED]: 0.8, [ExpertiseLevel.EXPERT]: 1.0 }; return valueMap[expertise]; } } // Additional algorithm implementations would follow similar patterns... class ContextAwareDisclosureAlgorithm extends DisclosureAlgorithm { async shouldDisclose( item: InformationItem, request: DisclosureRequest, analysis: InformationAnalysis, userProfile: UserProfile ): Promise<DisclosureAlgorithmResult> { // Implement context-aware disclosure logic return { shouldDisclose: true, reason: HidingReason.COMPLEXITY, detailLevel: DetailLevel.BASIC, confidence: 0.7, reasoning: ['Context-aware disclosure applied'], prerequisites: [], estimatedRevealTime: new Date(), adaptation: null }; } } class CognitiveLoadBasedDisclosureAlgorithm extends DisclosureAlgorithm { async shouldDisclose( item: InformationItem, request: DisclosureRequest, analysis: InformationAnalysis, userProfile: UserProfile ): Promise<DisclosureAlgorithmResult> { // Implement cognitive load-based disclosure logic return { shouldDisclose: true, reason: HidingReason.COMPLEXITY, detailLevel: DetailLevel.BASIC, confidence: 0.8, reasoning: ['Cognitive load-based disclosure applied'], prerequisites: [], estimatedRevealTime: new Date(), adaptation: null }; } } class PriorityBasedDisclosureAlgorithm extends DisclosureAlgorithm { async shouldDisclose( item: InformationItem, request: DisclosureRequest, analysis: InformationAnalysis, userProfile: UserProfile ): Promise<DisclosureAlgorithmResult> { // Implement priority-based disclosure logic return { shouldDisclose: true, reason: HidingReason.COMPLEXITY, detailLevel: DetailLevel.BASIC, confidence: 0.9, reasoning: ['Priority-based disclosure applied'], prerequisites: [], estimatedRevealTime: new Date(), adaptation: null }; } } class SimplificationAdaptationAlgorithm extends AdaptationAlgorithm { async shouldAdapt( item: DisclosedItem, request: DisclosureRequest, userProfile: UserProfile ): Promise<AdaptationAlgorithmResult> { // Implement simplification adaptation logic return { shouldAdapt: item.information.complexity > 7, adaptation: { originalComplexity: item.information.complexity, adaptedComplexity: Math.max(1, item.information.complexity - 3), adaptationType: AdaptationType.SIMPLIFICATION, factors: [{ type: FactorType.INFORMATION_COMPLEXITY, name: 'Complexity Reduction', value: 3, weight: 1.0, description: 'Reduced information complexity by 3 points' }], effectiveness: 0.8 }, effectiveness: 0.8 }; } } class AbstractionAdaptationAlgorithm extends AdaptationAlgorithm { async shouldAdapt( item: DisclosedItem, request: DisclosureRequest, userProfile: UserProfile ): Promise<AdaptationAlgorithmResult> { // Implement abstraction adaptation logic return { shouldAdapt: false, adaptation: { originalComplexity: item.information.complexity, adaptedComplexity: item.information.complexity, adaptationType: AdaptationType.ABSTRACTION, factors: [], effectiveness: 1.0 }, effectiveness: 1.0 }; } } class ChunkingAdaptationAlgorithm extends AdaptationAlgorithm { async shouldAdapt( item: DisclosedItem, request: DisclosureRequest, userProfile: UserProfile ): Promise<AdaptationAlgorithmResult> { // Implement chunking adaptation logic return { shouldAdapt: item.information.complexity > 6, adaptation: { originalComplexity: item.information.complexity, adaptedComplexity: Math.max(1, item.information.complexity - 2), adaptationType: AdaptationType.CHUNKING, factors: [{ type: FactorType.INFORMATION_COMPLEXITY, name: 'Information Chunking', value: 2, weight: 1.0, description: 'Chunked information into manageable pieces' }], effectiveness: 0.7 }, effectiveness: 0.7 }; } } class VisualizationAdaptationAlgorithm extends AdaptationAlgorithm { async shouldAdapt( item: DisclosedItem, request: DisclosureRequest, userProfile: UserProfile ): Promise<AdaptationAlgorithmResult> { // Implement visualization adaptation logic return { shouldAdapt: userProfile.context.preferences.visualizationPreference === VisualizationType.GRAPH, adaptation: { originalComplexity: item.information.complexity, adaptedComplexity: Math.max(1, item.information.complexity - 1), adaptationType: AdaptationType.VISUALIZATION, factors: [{ type: FactorType.USER_EXPERTISE, name: 'Visual Learning', value: 1, weight: 1.0, description: 'Applied visual learning adaptation' }], effectiveness: 0.9 }, effectiveness: 0.9 }; } } class PersonalizationAdaptationAlgorithm extends AdaptationAlgorithm { async shouldAdapt( item: DisclosedItem, request: DisclosureRequest, userProfile: UserProfile ): Promise<AdaptationAlgorithmResult> { // Implement personalization adaptation logic return { shouldAdapt: true, adaptation: { originalComplexity: item.information.complexity, adaptedComplexity: item.information.complexity, adaptationType: AdaptationType.PERSONALIZATION, factors: [{ type: FactorType.USER_EXPERTISE, name: 'Personalization', value: 1, weight: 1.0, description: 'Applied personalization based on user preferences' }], effectiveness: 0.85 }, effectiveness: 0.85 }; } }

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