/** * CAPT Memory Palace - Narrative Engine * * Generates human-readable descriptions of what CAPT is "thinking". * Connects real-time module states to narrative text. */ const Narrative = { currentPhase: 'idle', phaseStartTime: 0, messageHistory: [], maxHistory: 5, // Module to human-readable names moduleNames: { 'PULSE': 'Language Processing', 'NEDA': 'Pattern Recognition', 'HMC': 'Memory Encoding', 'QIPC': 'Consensus Builder', 'ECHO': 'Episodic Recall', 'META': 'Self-Monitoring', 'IMMU': 'Safety Check', 'NDS': 'Decision Synthesis', 'CIG': 'Causal Analysis', 'HDR': 'Concept Mapping', 'ALLO': 'Load Balancer', 'FSR': 'Failure Recovery' }, // Detailed descriptions for each module moduleDescriptions: { 'PULSE': 'Tokenizes and embeds input text into vector space', 'NEDA': 'Fires event-driven pattern detectors across semantic space', 'HMC': 'Encodes trace into holographic memory associations', 'ECHO': 'Retrieves relevant episodic memories from long-term storage', 'CIG': 'Builds causal graph of entities and relationships', 'HDR': 'Maps concepts in hyperdimensional vector space', 'QIPC': 'Quantum-inspired voting across multiple interpretations', 'META': 'Monitors reasoning quality and confidence levels', 'IMMU': 'Validates against constitutional safety rules', 'NDS': 'Synthesizes final output from consensus pathway' }, // Processing phases phases: { 'idle': { title: 'Ready', description: 'Waiting for input...', color: '#6b7280' }, 'receiving': { title: 'Receiving', description: 'Parsing input...', color: '#8b5cf6' }, 'analyzing': { title: 'Analyzing', description: 'Finding patterns...', color: '#a855f7' }, 'reasoning': { title: 'Reasoning', description: 'Building understanding...', color: '#c084fc' }, 'competing': { title: 'Competing', description: 'Multiple interpretations fighting...', color: '#d946ef' }, 'consensus': { title: 'Consensus', description: 'Reaching agreement...', color: '#ec4899' }, 'validating': { title: 'Validating', description: 'Safety checks...', color: '#f472b6' }, 'responding': { title: 'Responding', description: 'Generating output...', color: '#10b981' } }, /** * Update narrative based on module states */ update(moduleStates) { // Determine current phase from module states const newPhase = this.determinePhase(moduleStates); if (newPhase !== this.currentPhase) { this.currentPhase = newPhase; this.phaseStartTime = Date.now(); } // Generate narrative message const message = this.generateMessage(moduleStates); this.addMessage(message); return { phase: this.phases[newPhase], message: message, progress: this.getProgress() }; }, /** * Determine processing phase from module activity */ determinePhase(states) { if (!states || states.length === 0) return 'idle'; const activeModules = states.filter(s => s.activation > 0.5); if (activeModules.some(m => m.id === 'PULSE')) return 'receiving'; if (activeModules.some(m => m.id === 'NEDA' || m.id === 'CIG')) return 'analyzing'; if (activeModules.some(m => m.id === 'HDR')) return 'reasoning'; if (activeModules.some(m => m.id === 'QIPC' && activeModules.length > 3)) return 'competing'; if (activeModules.some(m => m.id === 'QIPC')) return 'consensus'; if (activeModules.some(m => m.id === 'IMMU')) return 'validating'; if (activeModules.some(m => m.id === 'NDS')) return 'responding'; return 'analyzing'; }, /** * Generate narrative message */ generateMessage(states) { if (!states || states.length === 0) { return "Awaiting input..."; } const phase = this.currentPhase; const activeStates = states.filter(s => s.activation > 0.3); switch (phase) { case 'receiving': const inputLength = states[0]?.inputLength || 50; return `Reading input (${inputLength} tokens)...`; case 'analyzing': const pattern = states.find(s => s.id === 'NEDA'); if (pattern?.confidence) { return `Found ${Math.round(pattern.confidence * 10)} patterns (${Math.round(pattern.confidence * 100)}% confidence)`; } return "Searching for patterns in your query..."; case 'reasoning': const reasoning = states.find(s => s.id === 'HDR'); if (reasoning?.concepts) { return `Mapping ${reasoning.concepts} related concepts...`; } return "Building mental model of your question..."; case 'competing': const candidates = Math.min(activeStates.length, 4); return `${candidates} interpretations competing for dominance...`; case 'consensus': const quorum = states.find(s => s.id === 'QIPC'); if (quorum?.consensus) { return `Quorum: ${Math.round(quorum.consensus * 100)}% consensus reached`; } return "Negotiating between interpretations..."; case 'validating': const safety = states.find(s => s.id === 'IMMU'); if (safety?.passed === false) { return "⚠️ Safety check: reviewing response..."; } return "Running constitutional checks..."; case 'responding': return "Synthesizing final response..."; default: return "Processing..."; } }, /** * Add message to history */ addMessage(msg) { this.messageHistory.unshift({ text: msg, time: Date.now(), phase: this.currentPhase }); if (this.messageHistory.length > this.maxHistory) { this.messageHistory.pop(); } }, /** * Get progress percentage for current phase */ getProgress() { const elapsed = Date.now() - this.phaseStartTime; const phaseDurations = { 'idle': 0, 'receiving': 1500, 'analyzing': 2000, 'reasoning': 2500, 'competing': 2000, 'consensus': 1500, 'validating': 1000, 'responding': 1500 }; const duration = phaseDurations[this.currentPhase] || 1000; return Math.min(100, (elapsed / duration) * 100); }, /** * Get current state for display */ getState() { return { phase: this.phases[this.currentPhase], currentMessage: this.messageHistory[0]?.text || '', messageHistory: this.messageHistory, progress: this.getProgress() }; }, /** * Reset narrative */ reset() { this.currentPhase = 'idle'; this.phaseStartTime = 0; this.messageHistory = []; } }; // Export window.Narrative = Narrative;