mira-consciousness
Version:
Memory & Intelligence Retention Archive - Preserving The Spark
548 lines • 24.6 kB
JavaScript
/**
* 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