UNPKG

@alanhelmick/memorable

Version:

An AI memory system enabling personalized, context-aware interactions through advanced memory management and emotional intelligence

250 lines (213 loc) 6.52 kB
import { getRedisClient } from '../config/redis.js'; import { logger } from '../utils/logger.js'; export class AttentionSystem { constructor() { this.redis = null; this.windows = { short: parseInt(process.env.MEMORY_WINDOW_SHORT) || 1200000, // 20 min medium: parseInt(process.env.MEMORY_WINDOW_MEDIUM) || 3600000, // 1 hour long: parseInt(process.env.MEMORY_WINDOW_LONG) || 86400000 // 24 hours }; } async initialize() { try { this.redis = getRedisClient(); await this.initializeAttentionStructures(); logger.info('Attention System initialized'); } catch (error) { logger.error('Failed to initialize Attention System:', error); throw error; } } async initializeAttentionStructures() { try { // Initialize 4W framework structures await this.redis.hSet('attention:4w', { who: JSON.stringify([]), what: JSON.stringify([]), when: JSON.stringify([]), where: JSON.stringify([]) }); // Initialize rolling windows for (const window of Object.keys(this.windows)) { await this.redis.zAdd(`attention:window:${window}`, { score: Date.now(), value: 'initialized' }); } logger.info('Attention structures initialized'); } catch (error) { logger.error('Failed to initialize attention structures:', error); throw error; } } async processAttention(input) { try { // Extract 4W information const fourW = await this.extract4W(input); // Update attention windows await this.updateAttentionWindows(input, fourW); // Process patterns const patterns = await this.detectPatterns(fourW); // Consolidate memory if needed if (await this.shouldConsolidateMemory()) { await this.consolidateMemory(); } return { fourW, patterns, timestamp: Date.now() }; } catch (error) { logger.error('Failed to process attention:', error); throw error; } } async extract4W(input) { const fourW = { who: await this.extractWho(input), what: await this.extractWhat(input), when: await this.extractWhen(input), where: await this.extractWhere(input) }; // Update 4W framework in Redis await this.update4WFramework(fourW); return fourW; } async extractWho(input) { // Extract entities representing people, organizations, etc. return { entities: [], confidence: 0 }; } async extractWhat(input) { // Extract actions, events, or topics return { actions: [], topics: [], confidence: 0 }; } async extractWhen(input) { // Extract temporal information return { timestamp: Date.now(), temporal_expressions: [], confidence: 0 }; } async extractWhere(input) { // Extract location information return { locations: [], coordinates: null, confidence: 0 }; } async update4WFramework(fourW) { const current = await this.redis.hGetAll('attention:4w'); // Update each dimension while maintaining history for (const [dimension, value] of Object.entries(fourW)) { const history = JSON.parse(current[dimension] || '[]'); history.push({ ...value, timestamp: Date.now() }); // Keep only recent history const recentHistory = history.filter( item => Date.now() - item.timestamp < this.windows.medium ); await this.redis.hSet('attention:4w', dimension, JSON.stringify(recentHistory)); } } async updateAttentionWindows(input, fourW) { const timestamp = Date.now(); const entry = JSON.stringify({ input: input.processed, fourW, timestamp }); // Update each attention window for (const [window, duration] of Object.entries(this.windows)) { await this.redis.zAdd(`attention:window:${window}`, { score: timestamp, value: entry }); // Remove expired entries await this.redis.zRemRangeByScore( `attention:window:${window}`, 0, timestamp - duration ); } } async detectPatterns(fourW) { const patterns = { temporal: await this.detectTemporalPatterns(), spatial: await this.detectSpatialPatterns(), behavioral: await this.detectBehavioralPatterns(), contextual: await this.detectContextualPatterns() }; return patterns; } async detectTemporalPatterns() { // Analyze temporal patterns in attention windows return []; } async detectSpatialPatterns() { // Analyze spatial patterns in attention windows return []; } async detectBehavioralPatterns() { // Analyze behavioral patterns in attention windows return []; } async detectContextualPatterns() { // Analyze contextual patterns in attention windows return []; } async shouldConsolidateMemory() { // Check conditions for memory consolidation const shortTermCount = await this.redis.zCard('attention:window:short'); return shortTermCount > 100; // Arbitrary threshold } async consolidateMemory() { try { // Get all attention windows const windows = await Promise.all( Object.keys(this.windows).map(async window => ({ window, entries: await this.redis.zRange(`attention:window:${window}`, 0, -1) })) ); // Process each window for consolidation for (const { window, entries } of windows) { const consolidated = await this.consolidateWindow(entries); // Update window with consolidated entries await this.redis.del(`attention:window:${window}`); if (consolidated.length > 0) { await this.redis.zAdd( `attention:window:${window}`, ...consolidated.map(entry => ({ score: entry.timestamp, value: JSON.stringify(entry) })) ); } } logger.info('Memory consolidation completed'); } catch (error) { logger.error('Failed to consolidate memory:', error); throw error; } } async consolidateWindow(entries) { // Implement window-specific consolidation logic return entries.map(entry => JSON.parse(entry)); } async cleanup() { logger.info('Cleaning up Attention System...'); // Additional cleanup logic can be added here } }