@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
JavaScript
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
}
}