| import { MemoryConfig, DEFAULT_MEMORY_CONFIG, MemoryType, MemorySource } from './types'; |
| import { storeMemoryWithDeduplication } from './deduplication'; |
| import { evictLowHeatMemories, buildAccessUpdateQuery } from './memoryDecay'; |
| import { getPrimaryMemoryType } from './typedMemory'; |
| import { processAssistantForMemory } from './assistantMemory'; |
| import { shouldStoreUserMessage } from './smartFilter'; |
| import { computeRetrievalParams, buildDynamicRetrievalQuery, processRetrievedMemories } from './dynamicRetrieval'; |
|
|
| export class ImprovedMemoryService { |
| private db: any; |
| private config: MemoryConfig; |
| private embedFn: (t: string) => Promise<number[]>; |
| private insertCount = 0; |
|
|
| constructor(db: any, embedFn: (t: string) => Promise<number[]>, config = DEFAULT_MEMORY_CONFIG) { |
| this.db = db; |
| this.embedFn = embedFn; |
| this.config = config; |
| } |
|
|
| async retrieve(userMessage: string, embedding: number[]) { |
| const params = computeRetrievalParams(userMessage, this.config); |
| const { sql, queryParams } = buildDynamicRetrievalQuery(embedding, params); |
| const raw = await this.db.getAll(sql, queryParams); |
| const typed = raw.map((r: any) => ({ record: { id: r.id, text: r.text, embedding: [], type: r.type, source: r.source, createdAt: r.created_at, lastAccessedAt: r.last_accessed_at, accessCount: r.access_count, importance: r.importance }, cosineSimilarity: r.similarity })); |
| const { formattedContext, memoriesUsed } = processRetrievedMemories(typed, params, this.config); |
| if (memoriesUsed.length) { const { sql: s, params: p } = buildAccessUpdateQuery(memoriesUsed); await this.db.run(s, p); } |
| return { context: formattedContext, memoryIds: memoriesUsed }; |
| } |
|
|
| async storeUserMessage(text: string, embedding: number[]) { |
| const f = shouldStoreUserMessage(text, this.config); |
| if (!f.store) return { stored: false, reason: f.reason }; |
| const result = await storeMemoryWithDeduplication(this.db, f.textToStore, embedding, getPrimaryMemoryType(f.textToStore), 'user', this.config); |
| if (++this.insertCount % 50 === 0) await this.evict(); |
| return { stored: result.operation !== 'NOOP', operation: result.operation }; |
| } |
|
|
| async storeAssistantReply(reply: string) { |
| const c = await processAssistantForMemory(reply, this.embedFn); |
| if (!c) return { stored: false }; |
| const r = await storeMemoryWithDeduplication(this.db, c.text, c.embedding, c.type, c.source, this.config); |
| return { stored: r.operation !== 'NOOP', operation: r.operation }; |
| } |
|
|
| async evict() { return evictLowHeatMemories(this.db, this.config); } |
| } |
|
|
| export * from './types'; |
| export { cosineSimilarity } from './deduplication'; |
| export { computeDecayFactor, computeHeatScore } from './memoryDecay'; |
| export { routeToMemoryType, getPrimaryMemoryType, formatMemoriesByType } from './typedMemory'; |
| export { shouldStoreAssistantMessage, extractAssistantMemory } from './assistantMemory'; |
| export { scoreMessageForMemory, shouldStoreUserMessage, classifyMessageIntent } from './smartFilter'; |
| export { computeRetrievalParams, estimateQueryComplexity, inferRelevantMemoryTypes } from './dynamicRetrieval'; |
|
|