@rlabs-inc/memory 0.1.0 → 0.2.1

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.
@@ -69,6 +69,17 @@ export interface ContextRequest {
69
69
  projectPath?: string // Required for 'local' storage mode
70
70
  }
71
71
 
72
+ /**
73
+ * Session metadata for deduplication
74
+ * Tracks which memories have been injected in each session
75
+ */
76
+ interface SessionMetadata {
77
+ message_count: number
78
+ started_at: number
79
+ project_id: string
80
+ injected_memories: Set<string> // Memory IDs already shown in this session
81
+ }
82
+
72
83
  /**
73
84
  * Memory Engine - The main orchestrator
74
85
  */
@@ -76,6 +87,7 @@ export class MemoryEngine {
76
87
  private _config: Required<Omit<EngineConfig, 'embedder'>> & { embedder?: EngineConfig['embedder'] }
77
88
  private _stores = new Map<string, MemoryStore>() // projectPath -> store
78
89
  private _retrieval: SmartVectorRetrieval
90
+ private _sessionMetadata = new Map<string, SessionMetadata>() // sessionId -> metadata
79
91
 
80
92
  constructor(config: EngineConfig = {}) {
81
93
  this._config = {
@@ -89,6 +101,21 @@ export class MemoryEngine {
89
101
  this._retrieval = createRetrieval()
90
102
  }
91
103
 
104
+ /**
105
+ * Get or create session metadata for deduplication
106
+ */
107
+ private _getSessionMetadata(sessionId: string, projectId: string): SessionMetadata {
108
+ if (!this._sessionMetadata.has(sessionId)) {
109
+ this._sessionMetadata.set(sessionId, {
110
+ message_count: 0,
111
+ started_at: Date.now(),
112
+ project_id: projectId,
113
+ injected_memories: new Set(),
114
+ })
115
+ }
116
+ return this._sessionMetadata.get(sessionId)!
117
+ }
118
+
92
119
  /**
93
120
  * Get the appropriate store for a project
94
121
  */
@@ -97,13 +124,6 @@ export class MemoryEngine {
97
124
  ? projectPath
98
125
  : projectId
99
126
 
100
- console.log(`šŸŖ [DEBUG] _getStore called:`)
101
- console.log(` projectId: ${projectId}`)
102
- console.log(` projectPath: ${projectPath}`)
103
- console.log(` storageMode: ${this._config.storageMode}`)
104
- console.log(` cache key: ${key}`)
105
- console.log(` cached: ${this._stores.has(key)}`)
106
-
107
127
  if (this._stores.has(key)) {
108
128
  return this._stores.get(key)!
109
129
  }
@@ -166,6 +186,10 @@ export class MemoryEngine {
166
186
  return { memories: [], formatted: '' }
167
187
  }
168
188
 
189
+ // Get session metadata for deduplication
190
+ const sessionMeta = this._getSessionMetadata(sessionId, projectId)
191
+ const injectedIds = sessionMeta.injected_memories
192
+
169
193
  // Get all memories for this project
170
194
  const allMemories = await store.getAllMemories(projectId)
171
195
 
@@ -173,6 +197,13 @@ export class MemoryEngine {
173
197
  return { memories: [], formatted: '' }
174
198
  }
175
199
 
200
+ // Filter out already-injected memories (deduplication)
201
+ const candidateMemories = allMemories.filter(m => !injectedIds.has(m.id))
202
+
203
+ if (!candidateMemories.length) {
204
+ return { memories: [], formatted: '' }
205
+ }
206
+
176
207
  // Generate embedding for query if embedder is available
177
208
  let queryEmbedding: Float32Array | undefined
178
209
  if (this._config.embedder) {
@@ -187,14 +218,20 @@ export class MemoryEngine {
187
218
  }
188
219
 
189
220
  // Retrieve relevant memories using 10-dimensional scoring
221
+ // Use candidateMemories (already filtered for deduplication)
190
222
  const relevantMemories = this._retrieval.retrieveRelevantMemories(
191
- allMemories,
223
+ candidateMemories,
192
224
  currentMessage,
193
225
  queryEmbedding ?? new Float32Array(384), // Empty embedding if no embedder
194
226
  sessionContext,
195
227
  maxMemories
196
228
  )
197
229
 
230
+ // Update injected memories for deduplication
231
+ for (const memory of relevantMemories) {
232
+ injectedIds.add(memory.id)
233
+ }
234
+
198
235
  return {
199
236
  memories: relevantMemories,
200
237
  formatted: this._formatMemories(relevantMemories),
@@ -5,7 +5,7 @@
5
5
  // ============================================================================
6
6
 
7
7
  import type { StoredMemory, RetrievalResult } from '../types/memory.ts'
8
- import { cosineSimilarity } from 'fatherstatedb'
8
+ import { cosineSimilarity } from '@rlabs-inc/fsdb'
9
9
 
10
10
  /**
11
11
  * Session context for retrieval
package/src/core/store.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  // ============================================================================
2
- // MEMORY STORE - FatherStateDB-powered storage
2
+ // MEMORY STORE - fsDB-powered storage
3
3
  // Per-project database management with reactive parallel arrays
4
4
  // ============================================================================
5
5
 
6
- import { createDatabase, type Database } from 'fatherstatedb'
6
+ import { createDatabase, type Database, type PersistentCollection } from '@rlabs-inc/fsdb'
7
7
  import { homedir } from 'os'
8
8
  import { join } from 'path'
9
9
  import type {
@@ -42,21 +42,22 @@ export interface StoreConfig {
42
42
  }
43
43
 
44
44
  /**
45
- * Project database collection
45
+ * Project database with collections
46
46
  */
47
- interface ProjectDatabases {
48
- memories: Database<typeof memorySchema>
49
- summaries: Database<typeof sessionSummarySchema>
50
- snapshots: Database<typeof projectSnapshotSchema>
51
- sessions: Database<typeof sessionSchema>
47
+ interface ProjectDB {
48
+ db: Database
49
+ memories: PersistentCollection<typeof memorySchema>
50
+ summaries: PersistentCollection<typeof sessionSummarySchema>
51
+ snapshots: PersistentCollection<typeof projectSnapshotSchema>
52
+ sessions: PersistentCollection<typeof sessionSchema>
52
53
  }
53
54
 
54
55
  /**
55
- * MemoryStore - Manages per-project FatherStateDB instances
56
+ * MemoryStore - Manages per-project fsDB instances
56
57
  */
57
58
  export class MemoryStore {
58
59
  private _config: Required<StoreConfig>
59
- private _projects = new Map<string, ProjectDatabases>()
60
+ private _projects = new Map<string, ProjectDB>()
60
61
 
61
62
  constructor(config: StoreConfig = {}) {
62
63
  this._config = {
@@ -66,9 +67,9 @@ export class MemoryStore {
66
67
  }
67
68
 
68
69
  /**
69
- * Get or create databases for a project
70
+ * Get or create database for a project
70
71
  */
71
- async getProject(projectId: string): Promise<ProjectDatabases> {
72
+ async getProject(projectId: string): Promise<ProjectDB> {
72
73
  if (this._projects.has(projectId)) {
73
74
  console.log(`šŸ”„ [DEBUG] Returning cached databases for ${projectId}`)
74
75
  return this._projects.get(projectId)!
@@ -78,40 +79,51 @@ export class MemoryStore {
78
79
  const projectPath = join(this._config.basePath, projectId)
79
80
  console.log(` Path: ${projectPath}`)
80
81
 
81
- // Create all databases for this project
82
- const [memories, summaries, snapshots, sessions] = await Promise.all([
83
- createDatabase({
84
- path: join(projectPath, 'memories'),
85
- schema: memorySchema,
86
- contentColumn: 'content',
87
- autoSave: true,
88
- watchFiles: this._config.watchFiles,
89
- }),
90
- createDatabase({
91
- path: join(projectPath, 'summaries'),
92
- schema: sessionSummarySchema,
93
- contentColumn: 'summary',
94
- autoSave: true,
95
- watchFiles: this._config.watchFiles,
96
- }),
97
- createDatabase({
98
- path: join(projectPath, 'snapshots'),
99
- schema: projectSnapshotSchema,
100
- autoSave: true,
101
- watchFiles: this._config.watchFiles,
102
- }),
103
- createDatabase({
104
- path: join(projectPath, 'sessions'),
105
- schema: sessionSchema,
106
- autoSave: true,
107
- watchFiles: this._config.watchFiles,
108
- }),
82
+ // Create the database for this project
83
+ const db = createDatabase({
84
+ name: projectId,
85
+ basePath: projectPath,
86
+ })
87
+
88
+ // Create all collections for this project
89
+ const memories = db.collection('memories', {
90
+ schema: memorySchema,
91
+ contentColumn: 'content',
92
+ autoSave: true,
93
+ watchFiles: this._config.watchFiles,
94
+ })
95
+
96
+ const summaries = db.collection('summaries', {
97
+ schema: sessionSummarySchema,
98
+ contentColumn: 'summary',
99
+ autoSave: true,
100
+ watchFiles: this._config.watchFiles,
101
+ })
102
+
103
+ const snapshots = db.collection('snapshots', {
104
+ schema: projectSnapshotSchema,
105
+ autoSave: true,
106
+ watchFiles: this._config.watchFiles,
107
+ })
108
+
109
+ const sessions = db.collection('sessions', {
110
+ schema: sessionSchema,
111
+ autoSave: true,
112
+ watchFiles: this._config.watchFiles,
113
+ })
114
+
115
+ // Load existing data
116
+ await Promise.all([
117
+ memories.load(),
118
+ summaries.load(),
119
+ snapshots.load(),
120
+ sessions.load(),
109
121
  ])
110
122
 
111
- const dbs: ProjectDatabases = { memories, summaries, snapshots, sessions }
112
- this._projects.set(projectId, dbs)
123
+ const projectDB: ProjectDB = { db, memories, summaries, snapshots, sessions }
124
+ this._projects.set(projectId, projectDB)
113
125
 
114
- return dbs
126
+ return projectDB
115
127
  }
116
128
 
117
129
  // ================================================================
@@ -129,7 +141,7 @@ export class MemoryStore {
129
141
  ): Promise<string> {
130
142
  const { memories } = await this.getProject(projectId)
131
143
 
132
- const id = await memories.insert({
144
+ const id = memories.insert({
133
145
  content: memory.content,
134
146
  reasoning: memory.reasoning,
135
147
  importance_weight: memory.importance_weight,
@@ -147,7 +159,7 @@ export class MemoryStore {
147
159
  project_id: projectId,
148
160
  embedding: embedding
149
161
  ? (embedding instanceof Float32Array ? embedding : new Float32Array(embedding))
150
- : undefined,
162
+ : null,
151
163
  })
152
164
 
153
165
  return id
@@ -165,10 +177,10 @@ export class MemoryStore {
165
177
  reasoning: record.reasoning,
166
178
  importance_weight: record.importance_weight,
167
179
  confidence_score: record.confidence_score,
168
- context_type: record.context_type,
169
- temporal_relevance: record.temporal_relevance,
170
- knowledge_domain: record.knowledge_domain,
171
- emotional_resonance: record.emotional_resonance,
180
+ context_type: record.context_type as StoredMemory['context_type'],
181
+ temporal_relevance: record.temporal_relevance as StoredMemory['temporal_relevance'],
182
+ knowledge_domain: record.knowledge_domain as StoredMemory['knowledge_domain'],
183
+ emotional_resonance: record.emotional_resonance as StoredMemory['emotional_resonance'],
172
184
  action_required: record.action_required,
173
185
  problem_solution_pair: record.problem_solution_pair,
174
186
  semantic_tags: record.semantic_tags,
@@ -176,7 +188,7 @@ export class MemoryStore {
176
188
  question_types: record.question_types,
177
189
  session_id: record.session_id,
178
190
  project_id: record.project_id,
179
- embedding: record.embedding,
191
+ embedding: record.embedding ?? undefined,
180
192
  created_at: record.created,
181
193
  updated_at: record.updated,
182
194
  stale: record.stale,
@@ -196,18 +208,19 @@ export class MemoryStore {
196
208
 
197
209
  const results = memories.search('embedding', queryEmbedding, {
198
210
  topK,
199
- filter: filter ? (record) => {
200
- // Convert record to StoredMemory format for filter
211
+ filter: filter ? (record, _idx) => {
212
+ // Filter receives raw schema record - we need to adapt it
213
+ // Note: filter doesn't have access to id/created/updated (those are in RecordWithMeta)
201
214
  const mem: StoredMemory = {
202
- id: record.id,
215
+ id: '', // Not available in filter
203
216
  content: record.content,
204
217
  reasoning: record.reasoning,
205
218
  importance_weight: record.importance_weight,
206
219
  confidence_score: record.confidence_score,
207
- context_type: record.context_type,
208
- temporal_relevance: record.temporal_relevance,
209
- knowledge_domain: record.knowledge_domain,
210
- emotional_resonance: record.emotional_resonance,
220
+ context_type: record.context_type as StoredMemory['context_type'],
221
+ temporal_relevance: record.temporal_relevance as StoredMemory['temporal_relevance'],
222
+ knowledge_domain: record.knowledge_domain as StoredMemory['knowledge_domain'],
223
+ emotional_resonance: record.emotional_resonance as StoredMemory['emotional_resonance'],
211
224
  action_required: record.action_required,
212
225
  problem_solution_pair: record.problem_solution_pair,
213
226
  semantic_tags: record.semantic_tags,
@@ -222,27 +235,27 @@ export class MemoryStore {
222
235
  } : undefined,
223
236
  })
224
237
 
225
- return results.map(record => ({
226
- id: record.id,
227
- content: record.content,
228
- reasoning: record.reasoning,
229
- importance_weight: record.importance_weight,
230
- confidence_score: record.confidence_score,
231
- context_type: record.context_type,
232
- temporal_relevance: record.temporal_relevance,
233
- knowledge_domain: record.knowledge_domain,
234
- emotional_resonance: record.emotional_resonance,
235
- action_required: record.action_required,
236
- problem_solution_pair: record.problem_solution_pair,
237
- semantic_tags: record.semantic_tags,
238
- trigger_phrases: record.trigger_phrases,
239
- question_types: record.question_types,
240
- session_id: record.session_id,
241
- project_id: record.project_id,
242
- embedding: record.embedding,
243
- created_at: record.created,
244
- updated_at: record.updated,
245
- stale: record.stale,
238
+ return results.map(result => ({
239
+ id: result.record.id,
240
+ content: result.record.content,
241
+ reasoning: result.record.reasoning,
242
+ importance_weight: result.record.importance_weight,
243
+ confidence_score: result.record.confidence_score,
244
+ context_type: result.record.context_type as StoredMemory['context_type'],
245
+ temporal_relevance: result.record.temporal_relevance as StoredMemory['temporal_relevance'],
246
+ knowledge_domain: result.record.knowledge_domain as StoredMemory['knowledge_domain'],
247
+ emotional_resonance: result.record.emotional_resonance as StoredMemory['emotional_resonance'],
248
+ action_required: result.record.action_required,
249
+ problem_solution_pair: result.record.problem_solution_pair,
250
+ semantic_tags: result.record.semantic_tags,
251
+ trigger_phrases: result.record.trigger_phrases,
252
+ question_types: result.record.question_types,
253
+ session_id: result.record.session_id,
254
+ project_id: result.record.project_id,
255
+ embedding: result.record.embedding ?? undefined,
256
+ created_at: result.record.created,
257
+ updated_at: result.record.updated,
258
+ stale: result.stale,
246
259
  }))
247
260
  }
248
261
 
@@ -254,9 +267,10 @@ export class MemoryStore {
254
267
  memoryId: string,
255
268
  embedding: Float32Array | number[],
256
269
  content: string
257
- ): Promise<boolean> {
270
+ ): Promise<void> {
258
271
  const { memories } = await this.getProject(projectId)
259
- return memories.setEmbedding(memoryId, 'embedding', embedding, content)
272
+ const vec = embedding instanceof Float32Array ? embedding : new Float32Array(embedding)
273
+ memories.setEmbedding(memoryId, 'embedding', vec, content)
260
274
  }
261
275
 
262
276
  /**
@@ -264,7 +278,7 @@ export class MemoryStore {
264
278
  */
265
279
  async getStaleMemoryIds(projectId: string): Promise<string[]> {
266
280
  const { memories } = await this.getProject(projectId)
267
- return memories.getStaleIds()
281
+ return memories.all().filter(r => r.stale).map(r => r.id)
268
282
  }
269
283
 
270
284
  // ================================================================
@@ -293,7 +307,7 @@ export class MemoryStore {
293
307
  const allSessions = sessions.all()
294
308
  const firstSessionCompleted = allSessions.some(s => s.first_session_completed)
295
309
 
296
- await sessions.insert({
310
+ sessions.insert({
297
311
  id: sessionId,
298
312
  project_id: projectId,
299
313
  message_count: 0,
@@ -321,7 +335,7 @@ export class MemoryStore {
321
335
  }
322
336
 
323
337
  const newCount = session.message_count + 1
324
- await sessions.update(sessionId, {
338
+ sessions.update(sessionId, {
325
339
  message_count: newCount,
326
340
  last_active: Date.now(),
327
341
  })
@@ -334,7 +348,7 @@ export class MemoryStore {
334
348
  */
335
349
  async markFirstSessionCompleted(projectId: string, sessionId: string): Promise<void> {
336
350
  const { sessions } = await this.getProject(projectId)
337
- await sessions.update(sessionId, { first_session_completed: true })
351
+ sessions.update(sessionId, { first_session_completed: true })
338
352
  }
339
353
 
340
354
  // ================================================================
@@ -356,7 +370,7 @@ export class MemoryStore {
356
370
  console.log(` Summary length: ${summary.length} chars`)
357
371
  console.log(` Summaries count before: ${summaries.all().length}`)
358
372
 
359
- const id = await summaries.insert({
373
+ const id = summaries.insert({
360
374
  session_id: sessionId,
361
375
  project_id: projectId,
362
376
  summary,
@@ -385,9 +399,9 @@ export class MemoryStore {
385
399
  }
386
400
 
387
401
  // Sort by created timestamp (most recent first)
388
- all.sort((a, b) => b.created - a.created)
402
+ const sorted = [...all].sort((a, b) => b.created - a.created)
389
403
 
390
- const latest = all[0]!
404
+ const latest = sorted[0]!
391
405
  console.log(` Latest summary: ${latest.summary.slice(0, 50)}...`)
392
406
 
393
407
  return {
@@ -434,9 +448,9 @@ export class MemoryStore {
434
448
  if (!all.length) return null
435
449
 
436
450
  // Sort by created timestamp (most recent first)
437
- all.sort((a, b) => b.created - a.created)
451
+ const sorted = [...all].sort((a, b) => b.created - a.created)
438
452
 
439
- const latest = all[0]!
453
+ const latest = sorted[0]!
440
454
  return {
441
455
  id: latest.id,
442
456
  session_id: latest.session_id,
@@ -466,19 +480,19 @@ export class MemoryStore {
466
480
 
467
481
  const allMemories = memories.all()
468
482
  const allSessions = sessions.all()
469
- const staleIds = memories.getStaleIds()
483
+ const staleCount = allMemories.filter(r => r.stale).length
470
484
 
471
485
  // Find latest session
472
486
  let latestSession: string | null = null
473
487
  if (allSessions.length) {
474
- allSessions.sort((a, b) => b.last_active - a.last_active)
475
- latestSession = allSessions[0]!.id
488
+ const sorted = [...allSessions].sort((a, b) => b.last_active - a.last_active)
489
+ latestSession = sorted[0]!.id
476
490
  }
477
491
 
478
492
  return {
479
493
  totalMemories: allMemories.length,
480
494
  totalSessions: allSessions.length,
481
- staleMemories: staleIds.length,
495
+ staleMemories: staleCount,
482
496
  latestSession,
483
497
  }
484
498
  }
@@ -487,11 +501,8 @@ export class MemoryStore {
487
501
  * Close all project databases
488
502
  */
489
503
  close(): void {
490
- for (const dbs of this._projects.values()) {
491
- dbs.memories.close()
492
- dbs.summaries.close()
493
- dbs.snapshots.close()
494
- dbs.sessions.close()
504
+ for (const projectDB of this._projects.values()) {
505
+ projectDB.db.close()
495
506
  }
496
507
  this._projects.clear()
497
508
  }
@@ -12,21 +12,8 @@ import { logger } from '../utils/logger.ts'
12
12
  * Server configuration
13
13
  */
14
14
  export interface ServerConfig extends EngineConfig {
15
- /**
16
- * Port to listen on
17
- * Default: 8765 (same as Python)
18
- */
19
15
  port?: number
20
-
21
- /**
22
- * Host to bind to
23
- * Default: 'localhost'
24
- */
25
16
  host?: string
26
-
27
- /**
28
- * Curator configuration
29
- */
30
17
  curator?: CuratorConfig
31
18
  }
32
19
 
@@ -61,7 +48,6 @@ interface CheckpointRequest {
61
48
 
62
49
  /**
63
50
  * Create and start the memory server
64
- * Uses Bun.serve() for high performance
65
51
  */
66
52
  export function createServer(config: ServerConfig = {}) {
67
53
  const {
@@ -102,7 +88,9 @@ export function createServer(config: ServerConfig = {}) {
102
88
 
103
89
  // Get memory context for a message
104
90
  if (path === '/memory/context' && req.method === 'POST') {
105
- const body: ContextRequest = await req.json()
91
+ const body = await req.json() as ContextRequest
92
+
93
+ logger.request('POST', '/memory/context', body.project_id)
106
94
 
107
95
  const result = await engine.getContext({
108
96
  sessionId: body.session_id,
@@ -126,20 +114,13 @@ export function createServer(config: ServerConfig = {}) {
126
114
  )
127
115
  }
128
116
 
129
- // Debug: show what's actually being returned
130
- console.log(`\nšŸ“¤ [DEBUG] Response to hook:`)
131
- console.log(` memories_count: ${result.memories.length}`)
132
- console.log(` has_primer: ${!!result.primer}`)
133
- console.log(` formatted length: ${result.formatted.length} chars`)
134
- if (result.formatted) {
135
- console.log(` formatted preview:\n${result.formatted.slice(0, 300)}...`)
136
- } else {
137
- console.log(` āš ļø formatted is EMPTY!`)
138
- }
139
-
140
117
  return Response.json({
141
118
  success: true,
142
- context: result.formatted,
119
+ session_id: body.session_id,
120
+ message_count: 0,
121
+ context_text: result.formatted,
122
+ has_memories: result.memories.length > 0,
123
+ curator_enabled: true,
143
124
  memories_count: result.memories.length,
144
125
  has_primer: !!result.primer,
145
126
  }, { headers: corsHeaders })
@@ -147,7 +128,7 @@ export function createServer(config: ServerConfig = {}) {
147
128
 
148
129
  // Process/track a message exchange
149
130
  if (path === '/memory/process' && req.method === 'POST') {
150
- const body: ProcessRequest = await req.json()
131
+ const body = await req.json() as ProcessRequest
151
132
 
152
133
  const messageCount = await engine.trackMessage(
153
134
  body.project_id,
@@ -155,7 +136,7 @@ export function createServer(config: ServerConfig = {}) {
155
136
  body.project_path
156
137
  )
157
138
 
158
- logger.session(`Message #${messageCount} tracked for ${body.project_id}/${body.session_id.slice(0, 8)}...`)
139
+ logger.session(`Message #${messageCount} tracked [${body.project_id}]`)
159
140
 
160
141
  return Response.json({
161
142
  success: true,
@@ -165,15 +146,13 @@ export function createServer(config: ServerConfig = {}) {
165
146
 
166
147
  // Checkpoint - trigger curation
167
148
  if (path === '/memory/checkpoint' && req.method === 'POST') {
168
- const body: CheckpointRequest = await req.json()
149
+ const body = await req.json() as CheckpointRequest
169
150
 
170
- logger.memory(`Curation triggered for ${body.project_id} (${body.trigger})`)
151
+ logger.logCurationStart(body.claude_session_id, body.trigger)
171
152
 
172
153
  // Fire and forget - don't block the response
173
154
  setImmediate(async () => {
174
155
  try {
175
- logger.info(`Resuming session ${body.claude_session_id.slice(0, 8)}... for curation`)
176
-
177
156
  const result = await curator.curateWithCLI(
178
157
  body.claude_session_id,
179
158
  body.trigger,
@@ -188,14 +167,10 @@ export function createServer(config: ServerConfig = {}) {
188
167
  body.project_path
189
168
  )
190
169
 
170
+ logger.logCurationComplete(result.memories.length, result.session_summary)
191
171
  logger.logCuratedMemories(result.memories)
192
- logger.success(`Stored ${result.memories.length} memories for ${body.project_id}`)
193
-
194
- if (result.session_summary) {
195
- logger.info(`Summary: ${result.session_summary.slice(0, 100)}...`)
196
- }
197
172
  } else {
198
- logger.warn(`No memories extracted for ${body.project_id}`)
173
+ logger.logCurationComplete(0)
199
174
  }
200
175
  } catch (error) {
201
176
  logger.error(`Curation failed: ${error}`)
@@ -227,7 +202,7 @@ export function createServer(config: ServerConfig = {}) {
227
202
  { status: 404, headers: corsHeaders }
228
203
  )
229
204
  } catch (error) {
230
- console.error('Server error:', error)
205
+ logger.error(`Server error: ${error}`)
231
206
  return Response.json(
232
207
  { error: String(error) },
233
208
  { status: 500, headers: corsHeaders }
@@ -3,7 +3,7 @@
3
3
  // Maps CuratedMemory to reactive parallel arrays
4
4
  // ============================================================================
5
5
 
6
- import type { SchemaDefinition } from 'fatherstatedb'
6
+ import type { SchemaDefinition } from '@rlabs-inc/fsdb'
7
7
 
8
8
  /**
9
9
  * Memory storage schema