/ src / lib / server / memory / memory-tiers.ts
memory-tiers.ts
 1  import type { MemoryEntry } from '@/types'
 2  
 3  export type MemoryTier = 'working' | 'durable' | 'archive'
 4  
 5  const WORKING_CATEGORIES = new Set(['execution', 'working', 'scratch', 'breadcrumb'])
 6  const ARCHIVE_CATEGORIES = new Set(['session_archive'])
 7  
 8  export function getMemoryTierForCategory(category: unknown): MemoryTier {
 9    const normalized = typeof category === 'string' ? category.trim().toLowerCase() : ''
10    if (ARCHIVE_CATEGORIES.has(normalized)) return 'archive'
11    if (normalized.startsWith('session_archive/')) return 'archive'
12    if (normalized === 'operations/execution' || normalized.startsWith('operations/execution/')) return 'working'
13    if (normalized === 'working/scratch' || normalized.startsWith('working/')) return 'working'
14    if (normalized === 'execution' || normalized.startsWith('execution/')) return 'working'
15    if (WORKING_CATEGORIES.has(normalized)) return 'working'
16    return 'durable'
17  }
18  
19  export function getMemoryTier(entry: Pick<MemoryEntry, 'category' | 'metadata'>): MemoryTier {
20    const metadataTier = typeof entry.metadata?.tier === 'string' ? entry.metadata.tier.trim().toLowerCase() : ''
21    if (metadataTier === 'archive' || metadataTier === 'session_archive') return 'archive'
22    if (metadataTier === 'working') return 'working'
23    if (metadataTier === 'durable') return 'durable'
24    return getMemoryTierForCategory(entry.category)
25  }
26  
27  export function partitionMemoriesByTier<T extends Pick<MemoryEntry, 'category' | 'metadata'>>(entries: T[]) {
28    const working: T[] = []
29    const durable: T[] = []
30    const archive: T[] = []
31  
32    for (const entry of entries) {
33      const tier = getMemoryTier(entry)
34      if (tier === 'working') working.push(entry)
35      else if (tier === 'archive') archive.push(entry)
36      else durable.push(entry)
37    }
38  
39    return { working, durable, archive }
40  }
41  
42  export function isWorkingMemoryCategory(category: unknown): boolean {
43    return getMemoryTierForCategory(category) === 'working'
44  }
45  
46  export function shouldHideFromDurableRecall(
47    entry: Pick<MemoryEntry, 'title' | 'metadata'>,
48  ): boolean {
49    const metadata = entry.metadata || {}
50    const origin = typeof metadata.origin === 'string' ? metadata.origin.trim().toLowerCase() : ''
51    if (origin === 'auto-consolidated') return true
52    if (typeof metadata.supersededBy === 'string' && metadata.supersededBy.trim()) return true
53    if (typeof metadata.supersededAt === 'number' && Number.isFinite(metadata.supersededAt)) return true
54    const title = typeof entry.title === 'string' ? entry.title.trim().toLowerCase() : ''
55    return title.startsWith('[auto-consolidated]')
56  }