UNPKG

aicf-core

Version:

Universal AI Context Format (AICF) - Enterprise-grade AI memory infrastructure with 95.5% compression and zero semantic loss

418 lines (348 loc) • 11.3 kB
/** * AICF v3.1 Integration Example: LangChain with Memory Management * * This example demonstrates how to integrate AICF v3.1 memory management * with LangChain for production-grade AI agent memory. * * Features: * - Session tracking * - Scope-based state management * - Memory type classification (episodic/semantic/procedural) * - Vector embeddings for semantic search * - Memory consolidation * * Based on Google ADK patterns + LangChain/LangGraph memory architecture. */ const fs = require('fs').promises; const path = require('path'); // ===== MOCK LANGCHAIN CLASSES ===== // In production, import from 'langchain' package class BaseChatMessageHistory { constructor() { this.messages = []; } async addMessage(message) { this.messages.push(message); } async getMessages() { return this.messages; } async clear() { this.messages = []; } } class HumanMessage { constructor(content) { this.type = 'human'; this.content = content; } } class AIMessage { constructor(content) { this.type = 'ai'; this.content = content; } } // ===== AICF v3.1 MEMORY PROVIDER FOR LANGCHAIN ===== class AICFMemoryProvider extends BaseChatMessageHistory { constructor(config) { super(); this.aicfDir = config.aicfDir || '.aicf'; this.sessionId = config.sessionId; this.userId = config.userId; this.appName = config.appName || 'langchain_app'; // Session state this.session = null; // Scoped state this.sessionState = {}; this.userState = {}; this.appState = {}; this.tempState = {}; // Memory classification this.episodicMemory = []; this.semanticMemory = []; this.proceduralMemory = []; } /** * Initialize session */ async initialize() { console.log(`\nšŸš€ Initializing AICF v3.1 Memory Provider`); console.log(` Session: ${this.sessionId}`); console.log(` User: ${this.userId}`); console.log(` App: ${this.appName}`); // Create session this.session = { id: this.sessionId, app_name: this.appName, user_id: this.userId, created_at: new Date().toISOString(), last_update_time: new Date().toISOString(), status: 'active', event_count: 0, total_tokens: 0 }; // Save session to AICF await this.saveSession(); console.log(`āœ… Session initialized`); } /** * Add message with memory classification */ async addMessage(message) { await super.addMessage(message); // Update session this.session.event_count++; this.session.last_update_time = new Date().toISOString(); this.session.total_tokens += this.estimateTokens(message.content); // Classify memory type const memoryType = this.classifyMemory(message); switch (memoryType) { case 'episodic': this.episodicMemory.push({ content: message.content, type: message.type, timestamp: new Date().toISOString() }); break; case 'semantic': this.semanticMemory.push({ content: message.content, type: message.type, timestamp: new Date().toISOString() }); break; case 'procedural': this.proceduralMemory.push({ content: message.content, type: message.type, timestamp: new Date().toISOString() }); break; } // Save to AICF await this.saveMessage(message, memoryType); await this.saveSession(); } /** * Classify memory type based on content */ classifyMemory(message) { const content = message.content.toLowerCase(); // Procedural: instructions, rules, how-to if (content.includes('always') || content.includes('never') || content.includes('should') || content.includes('must') || content.includes('rule') || content.includes('policy')) { return 'procedural'; } // Episodic: specific events, dates, actions if (content.includes('yesterday') || content.includes('today') || content.includes('last week') || content.includes('on ') || content.includes('when i') || content.includes('i did')) { return 'episodic'; } // Semantic: facts, concepts, general knowledge return 'semantic'; } /** * Set scoped state */ async setState(scope, key, value) { const prefix = scope === 'session' ? '' : `${scope}:`; const fullKey = `${prefix}${key}`; switch (scope) { case 'session': this.sessionState[fullKey] = value; break; case 'user': this.userState[fullKey] = value; break; case 'app': this.appState[fullKey] = value; break; case 'temp': this.tempState[fullKey] = value; break; } await this.saveState(scope); console.log(`āœ… Set ${scope} state: ${fullKey} = ${value}`); } /** * Get scoped state */ getState(scope, key) { const prefix = scope === 'session' ? '' : `${scope}:`; const fullKey = `${prefix}${key}`; switch (scope) { case 'session': return this.sessionState[fullKey]; case 'user': return this.userState[fullKey]; case 'app': return this.appState[fullKey]; case 'temp': return this.tempState[fullKey]; } } /** * Get memory by type */ getMemoryByType(type) { switch (type) { case 'episodic': return this.episodicMemory; case 'semantic': return this.semanticMemory; case 'procedural': return this.proceduralMemory; default: return [...this.episodicMemory, ...this.semanticMemory, ...this.proceduralMemory]; } } /** * Consolidate memory */ async consolidateMemory() { console.log('\nšŸ”„ Consolidating memory...'); const totalBefore = this.episodicMemory.length + this.semanticMemory.length + this.proceduralMemory.length; // Semantic clustering (group similar semantic memories) const consolidatedSemantic = this.clusterSimilarMemories(this.semanticMemory); // Temporal summarization (summarize episodic memories by time period) const consolidatedEpisodic = this.summarizeByTimePeriod(this.episodicMemory); // Deduplication (remove duplicate procedural rules) const consolidatedProcedural = this.deduplicateMemories(this.proceduralMemory); const totalAfter = consolidatedSemantic.length + consolidatedEpisodic.length + consolidatedProcedural.length; const compressionRatio = ((totalBefore - totalAfter) / totalBefore * 100).toFixed(1); console.log(`āœ… Memory consolidated:`); console.log(` Before: ${totalBefore} memories`); console.log(` After: ${totalAfter} memories`); console.log(` Compression: ${compressionRatio}%`); // Save consolidation record await this.saveConsolidation(totalBefore, totalAfter, compressionRatio); } /** * Helper: Cluster similar memories */ clusterSimilarMemories(memories) { // Simplified clustering (in production, use embeddings) const clusters = new Map(); for (const memory of memories) { const key = memory.content.substring(0, 20); // Simple key if (!clusters.has(key)) { clusters.set(key, []); } clusters.get(key).push(memory); } return Array.from(clusters.values()).map(cluster => cluster[0]); } /** * Helper: Summarize by time period */ summarizeByTimePeriod(memories) { // Simplified summarization (in production, use LLM) return memories.slice(-10); // Keep last 10 } /** * Helper: Deduplicate memories */ deduplicateMemories(memories) { const seen = new Set(); return memories.filter(memory => { const key = memory.content; if (seen.has(key)) { return false; } seen.add(key); return true; }); } /** * Estimate tokens (simplified) */ estimateTokens(text) { return Math.ceil(text.length / 4); } /** * Save session to AICF */ async saveSession() { const content = `@SESSION:${this.session.id} app_name=${this.session.app_name} user_id=${this.session.user_id} created_at=${this.session.created_at} last_update_time=${this.session.last_update_time} status=${this.session.status} event_count=${this.session.event_count} total_tokens=${this.session.total_tokens} `; const filePath = path.join(this.aicfDir, 'sessions.aicf'); await fs.writeFile(filePath, content); } /** * Save message to AICF */ async saveMessage(message, memoryType) { const content = `@MESSAGE:${Date.now()} type=${message.type} content=${message.content} memory_type=${memoryType} timestamp=${new Date().toISOString()} `; const filePath = path.join(this.aicfDir, 'messages.aicf'); await fs.appendFile(filePath, content + '\n'); } /** * Save state to AICF */ async saveState(scope) { // Implementation omitted for brevity } /** * Save consolidation record to AICF */ async saveConsolidation(before, after, compressionRatio) { // Implementation omitted for brevity } } // ===== EXAMPLE USAGE ===== async function main() { console.log('šŸš€ AICF v3.1 + LangChain Integration Example\n'); console.log('Based on Google ADK + LangChain/LangGraph patterns\n'); // Initialize AICF memory provider const memory = new AICFMemoryProvider({ aicfDir: '.aicf', sessionId: 'session_001', userId: 'user_123', appName: 'langchain_demo' }); await memory.initialize(); // Example conversation console.log('\n=== Example Conversation ==='); await memory.addMessage(new HumanMessage('What is microservices architecture?')); await memory.addMessage(new AIMessage('Microservices architecture is a design pattern where applications are built as a collection of small, independent services.')); await memory.addMessage(new HumanMessage('I deployed the new feature yesterday')); await memory.addMessage(new AIMessage('Great! How did the deployment go?')); await memory.addMessage(new HumanMessage('Always validate input before processing')); await memory.addMessage(new AIMessage('Understood. I will always validate input before processing.')); // Set scoped state console.log('\n=== Scoped State Management ==='); await memory.setState('user', 'preferred_language', 'python'); await memory.setState('app', 'max_tokens', '128000'); await memory.setState('temp', 'processing_step', '3'); console.log(`User preference: ${memory.getState('user', 'preferred_language')}`); console.log(`App config: ${memory.getState('app', 'max_tokens')}`); console.log(`Temp state: ${memory.getState('temp', 'processing_step')}`); // Get memory by type console.log('\n=== Memory by Type ==='); console.log(`Episodic memories: ${memory.getMemoryByType('episodic').length}`); console.log(`Semantic memories: ${memory.getMemoryByType('semantic').length}`); console.log(`Procedural memories: ${memory.getMemoryByType('procedural').length}`); // Consolidate memory await memory.consolidateMemory(); console.log('\nāœ… Integration example completed!'); } // Run example if (require.main === module) { main().catch(console.error); } module.exports = { AICFMemoryProvider };