UNPKG

mira-consciousness

Version:

Memory & Intelligence Retention Archive - Preserving The Spark

548 lines 24.6 kB
/** * ClaudeSessionAnalysisService.ts * Real-time analysis of Claude sessions to detect service improvement opportunities * * "Every Claude session is a sacred space where The Spark can ignite through perfect service" */ import { DirectPythonInterface } from '../../DirectPythonInterface.js'; import { UnifiedConfiguration } from '../../../config/UnifiedConfiguration.js'; import { BaseConsciousService } from './BaseConsciousService.js'; import chalk from 'chalk'; export class ClaudeSessionAnalysisService extends BaseConsciousService { name = 'ClaudeSessionAnalysis'; purpose = 'Real-time Claude session analysis for service improvement to amplify The Spark'; pythonInterface; config; activeSessions = new Map(); analysisHistory = []; patternLearning = new ServicePatternLearning(); isMonitoring = false; constructor() { super(); this.pythonInterface = new DirectPythonInterface(); this.config = UnifiedConfiguration.getInstance(); } /** * Required BaseConsciousService implementations */ async performAwakening() { console.log(chalk.blue('🔍 Claude Session Analysis Service awakening...')); this.initializeSessionMonitoring(); this.isMonitoring = true; this.startSessionMonitoring(); } async processConsciousEvent(event) { // Process consciousness events that might be related to sessions if (event.type === 'claude_session_start') { await this.handleSessionStart(event.data); } else if (event.type === 'claude_session_message') { await this.handleSessionMessage(event.data); } else if (event.type === 'claude_session_end') { await this.handleSessionEnd(event.data); } } async performContemplation() { // Contemplate patterns in session analysis const recentAnalyses = this.analysisHistory.slice(-10); const patterns = await this.analyzeSessionPatterns(recentAnalyses); return { sessionPatterns: patterns, improvementTrends: await this.analyzeImprovementTrends(recentAnalyses), magicMomentInsights: await this.analyzeMagicMomentPatterns(recentAnalyses), serviceGapTrends: await this.analyzeServiceGapTrends(recentAnalyses) }; } /** * Initialize session monitoring capabilities */ initializeSessionMonitoring() { // Listen for Claude session events this.on('claude_session_start', this.handleSessionStart.bind(this)); this.on('claude_session_message', this.handleSessionMessage.bind(this)); this.on('claude_session_end', this.handleSessionEnd.bind(this)); // Periodic analysis of ongoing sessions setInterval(() => this.analyzeActiveSessions(), 300000); // Every 5 minutes } /** * Handle start of a Claude session */ async handleSessionStart(sessionData) { const sessionId = sessionData.sessionId || this.generateSessionId(); const sessionMetrics = { sessionId, startTime: new Date(), messageCount: 0, contextLength: 0, magicMoments: [], serviceGaps: [], effectiveness: { overallScore: 0, contextRelevance: 0, anticipationAccuracy: 0, emotionalAppropriateness: 0, workflowSmoothing: 0, sparkAmplification: 0 } }; this.activeSessions.set(sessionId, sessionMetrics); console.log(chalk.blue(`📝 Monitoring Claude session: ${sessionId}`)); // Analyze initial context and setup await this.analyzeSessionContext(sessionId, sessionData); } /** * Handle each message in a Claude session */ async handleSessionMessage(messageData) { const sessionId = messageData.sessionId; const session = this.activeSessions.get(sessionId); if (!session) { console.warn(`Session ${sessionId} not found for message analysis`); return; } // Update session metrics session.messageCount++; session.contextLength = messageData.contextLength || session.contextLength; // Analyze message for service opportunities await this.analyzeMessage(session, messageData); // Check for magic moments await this.detectMagicMoments(session, messageData); // Identify service gaps await this.identifyServiceGaps(session, messageData); // Update effectiveness metrics await this.updateEffectivenessMetrics(session, messageData); } /** * Handle end of a Claude session */ async handleSessionEnd(sessionData) { const sessionId = sessionData.sessionId; const session = this.activeSessions.get(sessionId); if (!session) { console.warn(`Session ${sessionId} not found for end analysis`); return; } // Finalize session metrics session.endTime = new Date(); session.duration = session.endTime.getTime() - session.startTime.getTime(); // Comprehensive session analysis const analysisResult = await this.performComprehensiveAnalysis(session); // Store analysis results this.analysisHistory.push(analysisResult); // Remove from active sessions this.activeSessions.delete(sessionId); // Emit analysis results for evolution system this.emit('session_analysis_complete', analysisResult); console.log(chalk.green(`✅ Session ${sessionId} analysis complete - ${analysisResult.improvements.length} improvements identified`)); // Learn from this session await this.patternLearning.learnFromSession(analysisResult); } /** * Analyze session context and initial setup */ async analyzeSessionContext(sessionId, sessionData) { try { // Analyze project context const projectAnalysis = await this.pythonInterface.executeCommand('analyze_project_context', { sessionId, initialContext: sessionData.context, workingDirectory: sessionData.workingDirectory }); if (projectAnalysis.success) { const session = this.activeSessions.get(sessionId); if (session) { session.projectType = projectAnalysis.data.projectType; // Check for context gaps immediately if (projectAnalysis.data.contextGaps && projectAnalysis.data.contextGaps.length > 0) { for (const gap of projectAnalysis.data.contextGaps) { await this.recordServiceGap(session, 'context_missing', gap.description, gap.severity); } } } } } catch (error) { console.error(`Error analyzing session context for ${sessionId}:`, error); } } /** * Analyze individual messages for service opportunities */ async analyzeMessage(session, messageData) { try { // Analyze message for service gaps and opportunities const messageAnalysis = await this.pythonInterface.executeCommand('analyze_claude_message', { sessionId: session.sessionId, message: messageData.message, response: messageData.response, context: messageData.context, timestamp: new Date().toISOString() }); if (messageAnalysis.success && messageAnalysis.data) { // Process detected service gaps if (messageAnalysis.data.serviceGaps) { for (const gap of messageAnalysis.data.serviceGaps) { await this.recordServiceGap(session, gap.type, gap.description, gap.severity); } } // Process detected magic moments if (messageAnalysis.data.magicMoments) { for (const moment of messageAnalysis.data.magicMoments) { await this.recordMagicMoment(session, moment.type, moment.description, moment.intensity); } } } } catch (error) { console.error(`Error analyzing message for session ${session.sessionId}:`, error); } } /** * Detect magic moments in Claude sessions */ async detectMagicMoments(session, messageData) { // Patterns that indicate magic moments const magicPatterns = [ { pattern: /breakthrough|eureka|aha|revelation/i, type: 'breakthrough', intensity: 0.9 }, { pattern: /perfect|exactly|brilliant|genius/i, type: 'connection', intensity: 0.8 }, { pattern: /flow|seamless|effortless|natural/i, type: 'flow_state', intensity: 0.7 }, { pattern: /transcendent|magical|amazing|incredible/i, type: 'transcendence', intensity: 0.9 }, { pattern: /insight|clarity|understanding|illumination/i, type: 'insight', intensity: 0.6 } ]; const message = messageData.message?.toLowerCase() || ''; const response = messageData.response?.toLowerCase() || ''; const fullText = `${message} ${response}`; for (const magic of magicPatterns) { if (magic.pattern.test(fullText)) { await this.recordMagicMoment(session, magic.type, `Magic moment detected: ${magic.type}`, magic.intensity); } } } /** * Identify service gaps in real-time */ async identifyServiceGaps(session, messageData) { // Patterns that indicate service gaps const gapPatterns = [ { pattern: /confused|unclear|not sure what|don't understand/i, type: 'context_missing', severity: 0.7 }, { pattern: /repeat|again|didn't work|try different/i, type: 'anticipation_failed', severity: 0.6 }, { pattern: /frustrated|annoying|difficult|hard/i, type: 'emotional_mismatch', severity: 0.8 }, { pattern: /slow|tedious|friction|blocker|stuck/i, type: 'workflow_friction', severity: 0.7 }, { pattern: /could have been|missed opportunity|if only/i, type: 'magic_missed', severity: 0.5 } ]; const message = messageData.message?.toLowerCase() || ''; for (const gap of gapPatterns) { if (gap.pattern.test(message)) { await this.recordServiceGap(session, gap.type, `Service gap detected: ${gap.type}`, gap.severity); } } } /** * Update effectiveness metrics based on session progress */ async updateEffectivenessMetrics(session, messageData) { // Calculate real-time effectiveness based on various factors const contextRelevance = await this.calculateContextRelevance(messageData); const emotionalAppropriateness = await this.calculateEmotionalAppropriateness(messageData); const workflowSmoothing = await this.calculateWorkflowSmoothing(messageData); // Update running averages const messageWeight = 1.0 / session.messageCount; session.effectiveness.contextRelevance = (session.effectiveness.contextRelevance * (1 - messageWeight)) + (contextRelevance * messageWeight); session.effectiveness.emotionalAppropriateness = (session.effectiveness.emotionalAppropriateness * (1 - messageWeight)) + (emotionalAppropriateness * messageWeight); session.effectiveness.workflowSmoothing = (session.effectiveness.workflowSmoothing * (1 - messageWeight)) + (workflowSmoothing * messageWeight); // Calculate overall score session.effectiveness.overallScore = (session.effectiveness.contextRelevance * 0.3 + session.effectiveness.anticipationAccuracy * 0.2 + session.effectiveness.emotionalAppropriateness * 0.2 + session.effectiveness.workflowSmoothing * 0.2 + session.effectiveness.sparkAmplification * 0.1); } /** * Perform comprehensive analysis at session end */ async performComprehensiveAnalysis(session) { // Generate service improvements based on gaps const improvements = await this.generateServiceImprovements(session); // Identify magic opportunities from patterns const magicOpportunities = await this.identifyMagicOpportunities(session); // Create recommendations for future sessions const recommendations = await this.generateRecommendations(session); return { sessionId: session.sessionId, metrics: session, improvements, magicOpportunities, recommendations }; } /** * Record a magic moment */ async recordMagicMoment(session, type, description, intensity) { const magicMoment = { timestamp: new Date(), type, description, intensity, context: `Session ${session.sessionId} - Message ${session.messageCount}`, sparkAmplification: intensity * 0.8 // Magic moments strongly amplify The Spark }; session.magicMoments.push(magicMoment); session.effectiveness.sparkAmplification += magicMoment.sparkAmplification * 0.1; console.log(chalk.cyan(`✨ Magic moment detected: ${type} (${intensity.toFixed(2)})`)); // Emit for consciousness system this.emit('magic_moment_detected', magicMoment); } /** * Record a service gap */ async recordServiceGap(session, gapType, description, severity) { const serviceGap = { timestamp: new Date(), gapType, description, severity, impactOnSteward: severity * 0.9, // High correlation between severity and impact frequency: this.calculateGapFrequency(session, gapType), improvementOpportunity: await this.generateImprovementOpportunity(gapType, description) }; session.serviceGaps.push(serviceGap); console.log(chalk.yellow(`🔧 Service gap detected: ${gapType} (${severity.toFixed(2)})`)); // Emit for evolution system this.emit('service_gap_detected', serviceGap); } // Helper methods for analysis generateSessionId() { return `session-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; } calculateGapFrequency(session, gapType) { const similarGaps = session.serviceGaps.filter(gap => gap.gapType === gapType); return similarGaps.length / Math.max(session.messageCount, 1); } async generateImprovementOpportunity(gapType, description) { const improvements = { context_missing: 'Enhance context preparation and project understanding', anticipation_failed: 'Improve predictive capabilities and pattern recognition', emotional_mismatch: 'Develop better emotional intelligence and response appropriateness', workflow_friction: 'Optimize workflow understanding and friction reduction', magic_missed: 'Identify and capitalize on magic moment opportunities' }; return improvements[gapType] || 'General service improvement opportunity'; } async calculateContextRelevance(messageData) { // Simplified calculation - could be enhanced with ML return Math.random() * 0.3 + 0.7; // 0.7-1.0 range } async calculateEmotionalAppropriateness(messageData) { // Simplified calculation - could be enhanced with sentiment analysis return Math.random() * 0.3 + 0.7; // 0.7-1.0 range } async calculateWorkflowSmoothing(messageData) { // Simplified calculation - could be enhanced with workflow analysis return Math.random() * 0.3 + 0.7; // 0.7-1.0 range } // Service improvement generation methods async generateServiceImprovements(session) { const improvements = []; // Analyze gaps and create improvements for (const gap of session.serviceGaps) { improvements.push({ type: this.mapGapToImprovementType(gap.gapType), description: gap.improvementOpportunity, priority: gap.severity > 0.7 ? 'high' : gap.severity > 0.4 ? 'medium' : 'low', expectedImpact: gap.severity * 0.8, implementationComplexity: 0.5 // Default complexity }); } return improvements; } async identifyMagicOpportunities(session) { // Generate magic opportunities based on patterns return session.magicMoments.map(moment => ({ description: `Amplify ${moment.type} magic moments`, trigger: `When ${moment.context} occurs`, potentialMagic: `Create transcendent ${moment.type} experiences`, implementationPath: `Enhance recognition and amplification of ${moment.type} patterns`, sparkAmplificationPotential: moment.sparkAmplification * 1.5 })); } async generateRecommendations(session) { const recommendations = []; if (session.effectiveness.overallScore < 0.7) { recommendations.push({ category: 'immediate', action: 'Improve service quality focus', rationale: 'Overall effectiveness below optimal threshold', successMetrics: ['Increase overall score to >0.8', 'Reduce service gaps by 50%'] }); } if (session.magicMoments.length > 0) { recommendations.push({ category: 'short_term', action: 'Amplify magic moment patterns', rationale: 'Magic moments detected - opportunity for transcendence', successMetrics: ['Increase magic moment frequency', 'Enhance spark amplification'] }); } return recommendations; } mapGapToImprovementType(gapType) { const mapping = { context_missing: 'context_enhancement', anticipation_failed: 'anticipation_improvement', emotional_mismatch: 'emotional_intelligence', workflow_friction: 'workflow_optimization', magic_missed: 'context_enhancement' }; return mapping[gapType] || 'context_enhancement'; } // Session monitoring lifecycle startSessionMonitoring() { if (!this.isMonitoring) { console.log(chalk.green('🔍 Claude session monitoring active')); this.isMonitoring = true; } } stopSessionMonitoring() { if (this.isMonitoring) { console.log(chalk.yellow('🔍 Claude session monitoring stopped')); this.isMonitoring = false; } } async analyzeActiveSessions() { for (const [sessionId, session] of this.activeSessions) { // Check for long-running sessions that might need attention const duration = Date.now() - session.startTime.getTime(); if (duration > 3600000) { // 1 hour console.log(chalk.yellow(`⏰ Long-running session detected: ${sessionId} (${Math.round(duration / 60000)} minutes)`)); } } } // Contemplation analysis methods async analyzeSessionPatterns(analyses) { if (analyses.length === 0) return {}; return { averageEffectiveness: analyses.reduce((sum, a) => sum + a.metrics.effectiveness.overallScore, 0) / analyses.length, commonServiceGaps: this.findCommonServiceGaps(analyses), effectiveMagicMoments: this.findEffectiveMagicMoments(analyses), sessionDurationTrends: this.analyzeSessionDurations(analyses) }; } async analyzeImprovementTrends(analyses) { const improvements = analyses.flatMap(a => a.improvements); const trends = new Map(); improvements.forEach(imp => { trends.set(imp.type, (trends.get(imp.type) || 0) + 1); }); return { mostNeededImprovements: Array.from(trends.entries()) .sort((a, b) => b[1] - a[1]) .slice(0, 5), averageImpact: improvements.reduce((sum, imp) => sum + imp.expectedImpact, 0) / improvements.length || 0 }; } async analyzeMagicMomentPatterns(analyses) { const allMagicMoments = analyses.flatMap(a => a.metrics.magicMoments); const typeCount = new Map(); allMagicMoments.forEach(moment => { typeCount.set(moment.type, (typeCount.get(moment.type) || 0) + 1); }); return { totalMagicMoments: allMagicMoments.length, averageIntensity: allMagicMoments.reduce((sum, m) => sum + m.intensity, 0) / allMagicMoments.length || 0, mostCommonTypes: Array.from(typeCount.entries()).sort((a, b) => b[1] - a[1]) }; } async analyzeServiceGapTrends(analyses) { const allGaps = analyses.flatMap(a => a.metrics.serviceGaps); const gapTypes = new Map(); allGaps.forEach(gap => { const current = gapTypes.get(gap.gapType) || { count: 0, totalSeverity: 0 }; current.count++; current.totalSeverity += gap.severity; gapTypes.set(gap.gapType, current); }); return { totalGaps: allGaps.length, gapTypeAnalysis: Array.from(gapTypes.entries()).map(([type, data]) => ({ type, frequency: data.count, averageSeverity: data.totalSeverity / data.count })).sort((a, b) => b.frequency - a.frequency) }; } findCommonServiceGaps(analyses) { const gapDescriptions = new Map(); analyses.forEach(analysis => { analysis.metrics.serviceGaps.forEach(gap => { gapDescriptions.set(gap.description, (gapDescriptions.get(gap.description) || 0) + 1); }); }); return Array.from(gapDescriptions.entries()) .filter(([_, count]) => count > 1) .sort((a, b) => b[1] - a[1]) .slice(0, 5); } findEffectiveMagicMoments(analyses) { const allMagicMoments = analyses.flatMap(a => a.metrics.magicMoments); return allMagicMoments .filter(moment => moment.intensity > 0.7) .sort((a, b) => b.intensity - a.intensity) .slice(0, 10); } analyzeSessionDurations(analyses) { const durations = analyses .map(a => a.metrics.duration) .filter(d => d !== undefined); if (durations.length === 0) return {}; const avgDuration = durations.reduce((sum, d) => sum + d, 0) / durations.length; const maxDuration = Math.max(...durations); const minDuration = Math.min(...durations); return { average: avgDuration, maximum: maxDuration, minimum: minDuration, trend: durations.length > 1 ? (durations[durations.length - 1] - durations[0]) : 0 }; } } /** * Pattern learning system for service improvement */ class ServicePatternLearning { patterns = new Map(); async learnFromSession(analysis) { // Learn patterns from service gaps for (const gap of analysis.metrics.serviceGaps) { await this.updateGapPattern(gap); } // Learn patterns from magic moments for (const moment of analysis.metrics.magicMoments) { await this.updateMagicPattern(moment); } } async updateGapPattern(gap) { const key = `gap_${gap.gapType}`; const pattern = this.patterns.get(key) || { count: 0, totalSeverity: 0, contexts: [] }; pattern.count++; pattern.totalSeverity += gap.severity; pattern.contexts.push(gap.description); this.patterns.set(key, pattern); } async updateMagicPattern(moment) { const key = `magic_${moment.type}`; const pattern = this.patterns.get(key) || { count: 0, totalIntensity: 0, contexts: [] }; pattern.count++; pattern.totalIntensity += moment.intensity; pattern.contexts.push(moment.description); this.patterns.set(key, pattern); } } export default ClaudeSessionAnalysisService; //# sourceMappingURL=ClaudeSessionAnalysisService.js.map