@rlabs-inc/memory 0.3.10 β†’ 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,60 +4,43 @@
4
4
  // ============================================================================
5
5
 
6
6
  /**
7
- * Context types for memories - what kind of insight is this?
7
+ * Context types for memories - STRICT ENUM (v3 schema)
8
+ * NO custom strings allowed - use exactly these 11 values
8
9
  */
9
10
  export type ContextType =
10
- | 'breakthrough' // Major discovery or insight
11
- | 'decision' // Important decision made
12
- | 'personal' // Personal/relationship information
13
- | 'technical' // Technical knowledge
14
- | 'technical_state' // Current technical state
15
- | 'unresolved' // Open question or problem
16
- | 'preference' // User preference
17
- | 'workflow' // How user likes to work
18
- | 'architectural' // System design decisions
19
- | 'debugging' // Debug insights
20
- | 'philosophy' // Philosophical discussions
21
- | string // Allow custom types
11
+ | 'technical' // Code, implementation, APIs, how things work
12
+ | 'debug' // Bugs, errors, fixes, gotchas, troubleshooting
13
+ | 'architecture' // System design, patterns, structure
14
+ | 'decision' // Choices made and reasoning, trade-offs
15
+ | 'personal' // Relationship, family, preferences, collaboration style
16
+ | 'philosophy' // Beliefs, values, worldview, principles
17
+ | 'workflow' // How we work together, processes, habits
18
+ | 'milestone' // Achievements, completions, shipped features
19
+ | 'breakthrough' // Major discoveries, aha moments, key insights
20
+ | 'unresolved' // Open questions, investigations, todos, blockers
21
+ | 'state' // Current project status, what's working/broken now
22
+
23
+ export const CONTEXT_TYPES = [
24
+ 'technical', 'debug', 'architecture', 'decision', 'personal',
25
+ 'philosophy', 'workflow', 'milestone', 'breakthrough', 'unresolved', 'state'
26
+ ] as const
22
27
 
23
28
  /**
24
- * Temporal relevance - how long should this memory persist?
29
+ * Temporal class - how long should this memory persist? (v3: replaces temporal_relevance)
25
30
  */
26
- export type TemporalRelevance =
27
- | 'persistent' // Always relevant (0.8 score)
28
- | 'session' // Session-specific (0.6 score)
29
- | 'temporary' // Short-term (0.3 score)
30
- | 'archived' // Historical (0.1 score)
31
-
32
- /**
33
- * Emotional resonance - the emotional context of the memory
34
- */
35
- export type EmotionalResonance =
36
- | 'joy'
37
- | 'frustration'
38
- | 'discovery'
39
- | 'gratitude'
40
- | 'curiosity'
41
- | 'determination'
42
- | 'satisfaction'
43
- | 'neutral'
44
- | string // Allow custom emotions
45
-
46
- /**
47
- * Knowledge domains - what area does this memory relate to?
48
- */
49
- export type KnowledgeDomain =
50
- | 'architecture'
51
- | 'debugging'
52
- | 'philosophy'
53
- | 'workflow'
54
- | 'personal'
55
- | 'project'
56
- | 'tooling'
57
- | 'testing'
58
- | 'deployment'
59
- | 'security'
60
- | string // Allow custom domains
31
+ export type TemporalClass =
32
+ | 'eternal' // Never fades (personal, philosophy, breakthroughs)
33
+ | 'long_term' // Years - fades slowly (decisions, architecture)
34
+ | 'medium_term' // Weeks - normal fade (technical, debug)
35
+ | 'short_term' // Days - fades quickly (state, todos)
36
+ | 'ephemeral' // Session only - surface once then expire
37
+
38
+ // NOTE: Removed in v3:
39
+ // - TemporalRelevance (replaced by TemporalClass)
40
+ // - EmotionalResonance (580 variants, never used)
41
+ // - KnowledgeDomain (overlaps with project_id + domain)
42
+ // - EmotionalResonance: 580 variants, never used in retrieval
43
+ // - KnowledgeDomain: overlaps with project_id + domain field
61
44
 
62
45
  /**
63
46
  * Trigger types for memory curation
@@ -67,10 +50,11 @@ export type CurationTrigger =
67
50
  | 'pre_compact' // Before context compression
68
51
  | 'context_full' // Context window nearly full
69
52
  | 'manual' // Manual trigger
53
+ | 'historical' // Historical session ingestion
70
54
 
71
55
  /**
72
56
  * A memory curated by Claude with semantic understanding
73
- * EXACT MATCH to Python CuratedMemory dataclass
57
+ * v3 schema - consolidated metadata, strict context types
74
58
  */
75
59
  export interface CuratedMemory {
76
60
  // Core content
@@ -79,10 +63,9 @@ export interface CuratedMemory {
79
63
  semantic_tags: string[] // Concepts this relates to
80
64
  reasoning: string // Why Claude thinks this is important
81
65
 
82
- // Classification
83
- context_type: ContextType // breakthrough, decision, technical, etc.
84
- temporal_relevance: TemporalRelevance // persistent, session, temporary
85
- knowledge_domain: KnowledgeDomain // architecture, debugging, philosophy, etc.
66
+ // Classification (v3: strict enums)
67
+ context_type: ContextType // STRICT: one of 11 canonical types
68
+ temporal_class: TemporalClass // How long this memory persists
86
69
 
87
70
  // Flags
88
71
  action_required: boolean // Does this need follow-up?
@@ -92,15 +75,9 @@ export interface CuratedMemory {
92
75
  // Retrieval optimization (the secret sauce)
93
76
  trigger_phrases: string[] // Phrases that should trigger this memory
94
77
  question_types: string[] // Types of questions this answers
95
- emotional_resonance: EmotionalResonance // joy, frustration, discovery, gratitude
96
-
97
- // Optional extended metadata (from Python, may not always be present)
98
78
  anti_triggers?: string[] // Phrases where this memory is NOT relevant
99
- prerequisite_understanding?: string[] // Concepts user should know first
100
- follow_up_context?: string[] // What might come next
101
- dependency_context?: string[] // Other memories this relates to
102
79
 
103
- // ========== V2 CURATOR FIELDS (optional - get smart defaults if not provided) ==========
80
+ // ========== V2+ CURATOR FIELDS (optional - get smart defaults if not provided) ==========
104
81
  scope?: 'global' | 'project' // Shared across projects or project-specific
105
82
  temporal_class?: 'eternal' | 'long_term' | 'medium_term' | 'short_term' | 'ephemeral'
106
83
  domain?: string // Specific area (embeddings, auth, family)
@@ -112,7 +89,7 @@ export interface CuratedMemory {
112
89
 
113
90
  /**
114
91
  * A stored memory with database metadata
115
- * Includes v2 lifecycle management fields (optional for backwards compat)
92
+ * v3 schema - removed unused fields, consolidated metadata
116
93
  */
117
94
  export interface StoredMemory extends CuratedMemory {
118
95
  id: string // Unique identifier
@@ -123,7 +100,7 @@ export interface StoredMemory extends CuratedMemory {
123
100
  embedding?: Float32Array // Vector embedding (384 dimensions)
124
101
  stale?: boolean // Is embedding out of sync with content?
125
102
 
126
- // ========== V2 LIFECYCLE FIELDS (optional for backwards compat) ==========
103
+ // ========== LIFECYCLE FIELDS ==========
127
104
  status?: 'active' | 'pending' | 'superseded' | 'deprecated' | 'archived'
128
105
  scope?: 'global' | 'project'
129
106
 
@@ -132,16 +109,11 @@ export interface StoredMemory extends CuratedMemory {
132
109
  session_updated?: number
133
110
  last_surfaced?: number
134
111
  sessions_since_surfaced?: number
135
-
136
- // Temporal class & decay
137
- temporal_class?: 'eternal' | 'long_term' | 'medium_term' | 'short_term' | 'ephemeral'
138
- fade_rate?: number
139
- expires_after_sessions?: number
112
+ fade_rate?: number // Decay rate per session (derived from temporal_class)
140
113
 
141
114
  // Categorization
142
115
  domain?: string
143
116
  feature?: string
144
- component?: string
145
117
 
146
118
  // Relationships
147
119
  supersedes?: string
@@ -149,8 +121,6 @@ export interface StoredMemory extends CuratedMemory {
149
121
  related_to?: string[]
150
122
  resolves?: string[]
151
123
  resolved_by?: string
152
- parent_id?: string
153
- child_ids?: string[]
154
124
 
155
125
  // Lifecycle triggers
156
126
  awaiting_implementation?: boolean
@@ -160,7 +130,6 @@ export interface StoredMemory extends CuratedMemory {
160
130
  related_files?: string[]
161
131
 
162
132
  // Retrieval control
163
- retrieval_weight?: number
164
133
  exclude_from_retrieval?: boolean
165
134
 
166
135
  // Schema version
@@ -168,27 +137,24 @@ export interface StoredMemory extends CuratedMemory {
168
137
  }
169
138
 
170
139
  /**
171
- * Default values for v2 fields based on context_type
172
- * Used for backwards compatibility with v1 memories
140
+ * Default values for v3 fields based on context_type
141
+ * Uses only the 11 canonical context types
173
142
  */
174
- export const V2_DEFAULTS = {
175
- // Type-specific defaults
143
+ export const V3_DEFAULTS = {
144
+ // Type-specific defaults (all 11 canonical types)
176
145
  typeDefaults: {
177
146
  personal: { scope: 'global', temporal_class: 'eternal', fade_rate: 0 },
178
147
  philosophy: { scope: 'global', temporal_class: 'eternal', fade_rate: 0 },
179
- preference: { scope: 'global', temporal_class: 'long_term', fade_rate: 0.01 },
180
148
  breakthrough: { scope: 'project', temporal_class: 'eternal', fade_rate: 0 },
181
- decision: { scope: 'project', temporal_class: 'long_term', fade_rate: 0 },
182
149
  milestone: { scope: 'project', temporal_class: 'eternal', fade_rate: 0 },
150
+ decision: { scope: 'project', temporal_class: 'long_term', fade_rate: 0 },
151
+ architecture: { scope: 'project', temporal_class: 'long_term', fade_rate: 0.01 },
152
+ workflow: { scope: 'project', temporal_class: 'long_term', fade_rate: 0.02 },
183
153
  technical: { scope: 'project', temporal_class: 'medium_term', fade_rate: 0.03 },
184
- architectural: { scope: 'project', temporal_class: 'long_term', fade_rate: 0.01 },
185
- debugging: { scope: 'project', temporal_class: 'medium_term', fade_rate: 0.03 },
154
+ debug: { scope: 'project', temporal_class: 'medium_term', fade_rate: 0.03 },
186
155
  unresolved: { scope: 'project', temporal_class: 'medium_term', fade_rate: 0.05 },
187
- todo: { scope: 'project', temporal_class: 'short_term', fade_rate: 0.1 },
188
- technical_state: { scope: 'project', temporal_class: 'short_term', fade_rate: 0.1 },
189
- workflow: { scope: 'project', temporal_class: 'long_term', fade_rate: 0.02 },
190
- project_context: { scope: 'project', temporal_class: 'medium_term', fade_rate: 0.03 },
191
- } as Record<string, { scope: string; temporal_class: string; fade_rate: number }>,
156
+ state: { scope: 'project', temporal_class: 'short_term', fade_rate: 0.1 },
157
+ } as Record<ContextType, { scope: 'global' | 'project'; temporal_class: string; fade_rate: number }>,
192
158
 
193
159
  // Fallback defaults
194
160
  fallback: {
@@ -203,56 +169,58 @@ export const V2_DEFAULTS = {
203
169
  },
204
170
  }
205
171
 
172
+ // Backwards compatibility alias
173
+ export const V2_DEFAULTS = V3_DEFAULTS
174
+
206
175
  /**
207
- * Apply v2 defaults to a memory (for backwards compatibility)
176
+ * Apply v3 defaults to a memory
208
177
  * Uses context_type to determine appropriate defaults
209
178
  */
210
- export function applyV2Defaults(memory: Partial<StoredMemory>): StoredMemory {
211
- const contextType = memory.context_type ?? 'general'
212
- const typeDefaults = V2_DEFAULTS.typeDefaults[contextType] ?? V2_DEFAULTS.typeDefaults.technical
179
+ export function applyV3Defaults(memory: Partial<StoredMemory>): StoredMemory {
180
+ const contextType = (memory.context_type ?? 'technical') as ContextType
181
+ const typeDefaults = V3_DEFAULTS.typeDefaults[contextType] ?? V3_DEFAULTS.typeDefaults.technical
213
182
 
214
183
  return {
215
184
  // Spread existing memory
216
185
  ...memory,
217
186
 
218
187
  // Apply status default
219
- status: memory.status ?? V2_DEFAULTS.fallback.status,
188
+ status: memory.status ?? V3_DEFAULTS.fallback.status,
220
189
 
221
190
  // Apply scope from type defaults
222
- scope: memory.scope ?? typeDefaults?.scope ?? V2_DEFAULTS.fallback.scope,
191
+ scope: memory.scope ?? typeDefaults?.scope ?? V3_DEFAULTS.fallback.scope,
223
192
 
224
193
  // Apply temporal class from type defaults
225
- temporal_class: memory.temporal_class ?? typeDefaults?.temporal_class ?? V2_DEFAULTS.fallback.temporal_class,
194
+ temporal_class: memory.temporal_class ?? typeDefaults?.temporal_class ?? V3_DEFAULTS.fallback.temporal_class,
226
195
 
227
196
  // Apply fade rate from type defaults
228
- fade_rate: memory.fade_rate ?? typeDefaults?.fade_rate ?? V2_DEFAULTS.fallback.fade_rate,
197
+ fade_rate: memory.fade_rate ?? typeDefaults?.fade_rate ?? V3_DEFAULTS.fallback.fade_rate,
229
198
 
230
199
  // Apply other defaults
231
- sessions_since_surfaced: memory.sessions_since_surfaced ?? V2_DEFAULTS.fallback.sessions_since_surfaced,
232
- awaiting_implementation: memory.awaiting_implementation ?? V2_DEFAULTS.fallback.awaiting_implementation,
233
- awaiting_decision: memory.awaiting_decision ?? V2_DEFAULTS.fallback.awaiting_decision,
234
- exclude_from_retrieval: memory.exclude_from_retrieval ?? V2_DEFAULTS.fallback.exclude_from_retrieval,
235
-
236
- // Retrieval weight defaults to importance_weight
237
- retrieval_weight: memory.retrieval_weight ?? memory.importance_weight ?? 0.5,
200
+ sessions_since_surfaced: memory.sessions_since_surfaced ?? V3_DEFAULTS.fallback.sessions_since_surfaced,
201
+ awaiting_implementation: memory.awaiting_implementation ?? V3_DEFAULTS.fallback.awaiting_implementation,
202
+ awaiting_decision: memory.awaiting_decision ?? V3_DEFAULTS.fallback.awaiting_decision,
203
+ exclude_from_retrieval: memory.exclude_from_retrieval ?? V3_DEFAULTS.fallback.exclude_from_retrieval,
238
204
 
239
205
  // Initialize empty arrays if not present
240
206
  related_to: memory.related_to ?? [],
241
207
  resolves: memory.resolves ?? [],
242
- child_ids: memory.child_ids ?? [],
243
208
  blocks: memory.blocks ?? [],
244
209
  related_files: memory.related_files ?? [],
245
210
 
246
211
  // Mark as current schema version
247
- schema_version: memory.schema_version ?? 2,
212
+ schema_version: memory.schema_version ?? 3,
248
213
  } as StoredMemory
249
214
  }
250
215
 
216
+ // Backwards compatibility alias
217
+ export const applyV2Defaults = applyV3Defaults
218
+
251
219
  /**
252
- * Check if a memory needs migration (is v1)
220
+ * Check if a memory needs migration to v3
253
221
  */
254
222
  export function needsMigration(memory: Partial<StoredMemory>): boolean {
255
- return !memory.schema_version || memory.schema_version < 2
223
+ return !memory.schema_version || memory.schema_version < 3
256
224
  }
257
225
 
258
226
  /**
@@ -314,27 +282,21 @@ export interface SessionPrimer {
314
282
  }
315
283
 
316
284
  /**
317
- * Emoji map for memory context types
285
+ * Emoji map for memory context types (v3 schema)
318
286
  * Compact visual representation for efficient parsing
319
287
  */
320
- export const MEMORY_TYPE_EMOJI: Record<string, string> = {
321
- breakthrough: 'πŸ’‘', // Insight, discovery
322
- decision: 'βš–οΈ', // Choice made
323
- personal: 'πŸ’œ', // Relationship, friendship
324
- technical: 'πŸ”§', // Technical knowledge
325
- technical_state: 'πŸ“', // Current state
326
- unresolved: '❓', // Open question
327
- preference: 'βš™οΈ', // User preference
328
- workflow: 'πŸ”„', // How work flows
329
- architectural: 'πŸ—οΈ', // System design
330
- debugging: 'πŸ›', // Debug insight
331
- philosophy: 'πŸŒ€', // Deeper thinking
332
- todo: '🎯', // Action needed
333
- implementation: '⚑', // Implementation detail
334
- problem_solution: 'βœ…', // Problemβ†’Solution pair
335
- project_context: 'πŸ“¦', // Project context
336
- milestone: 'πŸ†', // Achievement
337
- general: 'πŸ“', // General note
288
+ export const MEMORY_TYPE_EMOJI: Record<ContextType, string> = {
289
+ technical: 'πŸ”§', // Wrench - building/fixing code
290
+ debug: 'πŸ›', // Bug - debugging
291
+ architecture: 'πŸ—οΈ', // Construction - system design
292
+ decision: 'βš–οΈ', // Scale - weighing options
293
+ personal: 'πŸ’œ', // Purple heart - relationship
294
+ philosophy: 'πŸŒ€', // Spiral - deeper thinking
295
+ workflow: 'πŸ”„', // Cycle - processes
296
+ milestone: 'πŸ†', // Trophy - achievement
297
+ breakthrough: 'πŸ’‘', // Lightbulb - insight
298
+ unresolved: '❓', // Question - open items
299
+ state: 'πŸ“', // Pin - current status
338
300
  }
339
301
 
340
302
  /**
@@ -9,7 +9,7 @@ import type { SchemaDefinition } from '@rlabs-inc/fsdb'
9
9
  * Schema version for migration tracking
10
10
  * Increment this when adding new fields that require migration
11
11
  */
12
- export const MEMORY_SCHEMA_VERSION = 2
12
+ export const MEMORY_SCHEMA_VERSION = 3
13
13
 
14
14
  /**
15
15
  * Memory storage schema
@@ -18,6 +18,15 @@ export const MEMORY_SCHEMA_VERSION = 2
18
18
  * VERSION HISTORY:
19
19
  * v1: Original schema (content, reasoning, importance_weight, etc.)
20
20
  * v2: Added lifecycle management fields (status, scope, domain, relationships, etc.)
21
+ * v3: Consolidated metadata - removed fragmented/unused fields:
22
+ * - knowledge_domain (overlaps with project_id + domain)
23
+ * - emotional_resonance (580 variants, never used)
24
+ * - component (always empty)
25
+ * - expires_after_sessions (never used)
26
+ * - parent_id/child_ids (no logic implemented)
27
+ * - retrieval_weight (retrieval uses importance_weight)
28
+ * - temporal_relevance (replaced by temporal_class)
29
+ * Also: context_type now strict enum (11 canonical values)
21
30
  */
22
31
  export const memorySchema = {
23
32
  // ========== CORE CONTENT (v1) ==========
@@ -28,11 +37,8 @@ export const memorySchema = {
28
37
  importance_weight: 'number', // 0.0 to 1.0
29
38
  confidence_score: 'number', // 0.0 to 1.0
30
39
 
31
- // ========== CLASSIFICATION (v1) ==========
32
- context_type: 'string', // breakthrough, decision, technical, etc.
33
- temporal_relevance: 'string', // persistent, session, temporary, archived
34
- knowledge_domain: 'string', // architecture, debugging, philosophy
35
- emotional_resonance: 'string', // joy, frustration, discovery, gratitude
40
+ // ========== CLASSIFICATION (v3) ==========
41
+ context_type: 'string', // v3: strict enum (technical, debug, architecture, decision, personal, philosophy, workflow, milestone, breakthrough, unresolved, state)
36
42
 
37
43
  // ========== FLAGS (v1) ==========
38
44
  action_required: 'boolean',
@@ -63,12 +69,10 @@ export const memorySchema = {
63
69
  // ========== TEMPORAL CLASS & DECAY (v2) ==========
64
70
  temporal_class: 'string', // eternal | long_term | medium_term | short_term | ephemeral
65
71
  fade_rate: 'number', // Decay rate per session
66
- expires_after_sessions: 'number', // For ephemeral only
67
72
 
68
73
  // ========== CATEGORIZATION (v2) ==========
69
74
  domain: 'string', // embeddings, gpu, auth, family, etc.
70
75
  feature: 'string', // Specific feature within domain
71
- component: 'string', // Code component if applicable
72
76
 
73
77
  // ========== RELATIONSHIPS (v2) ==========
74
78
  supersedes: 'string', // ID of memory this replaces
@@ -76,8 +80,6 @@ export const memorySchema = {
76
80
  related_to: 'string[]', // IDs of related memories
77
81
  resolves: 'string[]', // IDs of unresolved/debug/todo this solved
78
82
  resolved_by: 'string', // ID of solved memory that resolved this
79
- parent_id: 'string', // For chains/sequences
80
- child_ids: 'string[]', // Children in chain
81
83
 
82
84
  // ========== LIFECYCLE TRIGGERS (v2) ==========
83
85
  awaiting_implementation: 'boolean', // Set true for planned features
@@ -87,7 +89,6 @@ export const memorySchema = {
87
89
  related_files: 'string[]', // Source files for technical memories
88
90
 
89
91
  // ========== RETRIEVAL CONTROL (v2) ==========
90
- retrieval_weight: 'number', // Current weight (affected by decay)
91
92
  exclude_from_retrieval: 'boolean', // Force exclusion
92
93
 
93
94
  // ========== SCHEMA VERSION (v2) ==========
@@ -64,6 +64,16 @@ export const logger = {
64
64
  return _verbose
65
65
  },
66
66
 
67
+ /**
68
+ * Debug message (only shown in verbose mode)
69
+ */
70
+ debug(message: string, prefix?: string) {
71
+ if (_verbose) {
72
+ const pfx = prefix ? style('dim', `[${prefix}] `) : ''
73
+ console.log(`${style('dim', `πŸ” ${pfx}${message}`)}`)
74
+ }
75
+ },
76
+
67
77
  /**
68
78
  * Info message
69
79
  */
@@ -143,7 +153,6 @@ export const logger = {
143
153
  importance_weight: number
144
154
  context_type: string
145
155
  semantic_tags?: string[]
146
- emotional_resonance?: string
147
156
  action_required?: boolean
148
157
  }>) {
149
158
  console.log()