import { MemoryConfig, DEFAULT_MEMORY_CONFIG } from './types'; type MessageIntent = 'declarative' | 'interrogative' | 'imperative' | 'exclamatory' | 'social'; export function classifyMessageIntent(text: string): MessageIntent { const t = text.trim(); if (t.endsWith('?')) return 'interrogative'; if (/^(what|who|where|when|why|how|which|can|could|would|should|is|are|do|does|did|will|have|has)\s/i.test(t)) return 'interrogative'; if (/^(tell|show|give|find|get|make|let|help|explain|describe|list|suggest|recommend)\s/i.test(t)) return 'imperative'; if (/^(hi|hey|hello|bye|goodbye|thanks|thank\s+you|please|sorry|wow|oh|hmm|haha|lol|nice|cool|great|awesome)\b/i.test(t)) return 'social'; if (t.endsWith('!') && /\b(love|hate|amazing|terrible|awful|great|best|worst)\b/i.test(t)) return 'exclamatory'; return 'declarative'; } export function scoreMessageForMemory(text: string, config: MemoryConfig = DEFAULT_MEMORY_CONFIG): { score: number; shouldStore: boolean; reason: string } { let score = 0; const reasons: string[] = []; const t = text.trim(); if (t.length < config.minMessageLength) return { score: 0, shouldStore: false, reason: 'too_short' }; if (config.skipPatterns.some(p => p.test(t))) return { score: 0, shouldStore: false, reason: 'skip_pattern' }; const intent = classifyMessageIntent(t); switch (intent) { case 'declarative': score += 0.4; reasons.push('declarative'); break; case 'exclamatory': score += 0.3; reasons.push('exclamatory'); break; case 'interrogative': score += 0.05; reasons.push('question'); break; case 'imperative': if (/\b(always|never|remember|don't\s+forget)\b/i.test(t)) { score += 0.45; reasons.push('procedural'); } else { score += 0.05; reasons.push('command'); } break; case 'social': reasons.push('social'); break; } if (/\b(i\s+am|i'm|i\s+have|i've|i\s+live|i\s+work|my\s+\w+\s+is)\b/i.test(t)) { score += 0.25; reasons.push('personal_fact'); } if (/\b(i\s+(like|love|enjoy|prefer|hate|dislike|always|never))\b/i.test(t)) { score += 0.2; reasons.push('preference'); } if (/\b(allergic|can't\s+eat|don't\s+eat|vegetarian|vegan|intolerant|avoid)\b/i.test(t)) { score += 0.3; reasons.push('constraint'); } if (/\b(always|never|remember\s+to|remind\s+me|don't\s+forget)\b/i.test(t)) { score += 0.2; reasons.push('procedural_keywords'); } if (t.length > 40) score += 0.05; if (t.length > 80) score += 0.05; score = Math.min(score, 1.0); return { score, shouldStore: score >= 0.5, reason: reasons.join(', ') }; } export function shouldStoreUserMessage(text: string, config: MemoryConfig = DEFAULT_MEMORY_CONFIG): { store: boolean; textToStore: string; reason: string } { const segments = text.split(/[.!?]+/).map(s => s.trim()).filter(s => s.length > 5); if (segments.length <= 1) { const result = scoreMessageForMemory(text, config); if (result.reason.includes('constraint') || result.reason.includes('preference')) return { store: true, textToStore: text, reason: result.reason }; return { store: result.shouldStore, textToStore: text, reason: result.reason }; } const storeable = segments.filter(s => scoreMessageForMemory(s, config).shouldStore); if (!storeable.length) return { store: false, textToStore: '', reason: 'no_storable_content' }; return { store: true, textToStore: storeable.join('. ') + '.', reason: 'compound' }; }