@rlabs-inc/memory 0.1.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.
- package/bun.lock +102 -0
- package/dist/core/curator.d.ts +61 -0
- package/dist/core/engine.d.ts +111 -0
- package/dist/core/index.d.ts +4 -0
- package/dist/core/retrieval.d.ts +36 -0
- package/dist/core/store.d.ts +113 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +12147 -0
- package/dist/index.mjs +12130 -0
- package/dist/server/index.d.ts +31 -0
- package/dist/server/index.js +12363 -0
- package/dist/server/index.mjs +12346 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/memory.d.ts +105 -0
- package/dist/types/schema.d.ts +21 -0
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/logger.d.ts +65 -0
- package/package.json +56 -0
- package/src/core/curator.ts +433 -0
- package/src/core/engine.ts +404 -0
- package/src/core/index.ts +8 -0
- package/src/core/retrieval.ts +518 -0
- package/src/core/store.ts +505 -0
- package/src/index.ts +58 -0
- package/src/server/index.ts +262 -0
- package/src/types/index.ts +6 -0
- package/src/types/memory.ts +170 -0
- package/src/types/schema.ts +83 -0
- package/src/utils/index.ts +5 -0
- package/src/utils/logger.ts +208 -0
- package/test-retrieval.ts +91 -0
- package/tsconfig.json +16 -0
|
@@ -0,0 +1,505 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// MEMORY STORE - FatherStateDB-powered storage
|
|
3
|
+
// Per-project database management with reactive parallel arrays
|
|
4
|
+
// ============================================================================
|
|
5
|
+
|
|
6
|
+
import { createDatabase, type Database } from 'fatherstatedb'
|
|
7
|
+
import { homedir } from 'os'
|
|
8
|
+
import { join } from 'path'
|
|
9
|
+
import type {
|
|
10
|
+
CuratedMemory,
|
|
11
|
+
StoredMemory,
|
|
12
|
+
SessionSummary,
|
|
13
|
+
ProjectSnapshot,
|
|
14
|
+
} from '../types/memory.ts'
|
|
15
|
+
import {
|
|
16
|
+
memorySchema,
|
|
17
|
+
sessionSummarySchema,
|
|
18
|
+
projectSnapshotSchema,
|
|
19
|
+
sessionSchema,
|
|
20
|
+
type MemorySchema,
|
|
21
|
+
type SessionSummarySchema,
|
|
22
|
+
type ProjectSnapshotSchema,
|
|
23
|
+
type SessionSchema,
|
|
24
|
+
} from '../types/schema.ts'
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Store configuration
|
|
28
|
+
*/
|
|
29
|
+
export interface StoreConfig {
|
|
30
|
+
/**
|
|
31
|
+
* Base path for memory storage
|
|
32
|
+
* Default: ~/.local/share/memory
|
|
33
|
+
* Each project gets its own subdirectory
|
|
34
|
+
*/
|
|
35
|
+
basePath?: string
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Whether to watch for file changes
|
|
39
|
+
* Default: false
|
|
40
|
+
*/
|
|
41
|
+
watchFiles?: boolean
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Project database collection
|
|
46
|
+
*/
|
|
47
|
+
interface ProjectDatabases {
|
|
48
|
+
memories: Database<typeof memorySchema>
|
|
49
|
+
summaries: Database<typeof sessionSummarySchema>
|
|
50
|
+
snapshots: Database<typeof projectSnapshotSchema>
|
|
51
|
+
sessions: Database<typeof sessionSchema>
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* MemoryStore - Manages per-project FatherStateDB instances
|
|
56
|
+
*/
|
|
57
|
+
export class MemoryStore {
|
|
58
|
+
private _config: Required<StoreConfig>
|
|
59
|
+
private _projects = new Map<string, ProjectDatabases>()
|
|
60
|
+
|
|
61
|
+
constructor(config: StoreConfig = {}) {
|
|
62
|
+
this._config = {
|
|
63
|
+
basePath: config.basePath ?? join(homedir(), '.local', 'share', 'memory'),
|
|
64
|
+
watchFiles: config.watchFiles ?? false,
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Get or create databases for a project
|
|
70
|
+
*/
|
|
71
|
+
async getProject(projectId: string): Promise<ProjectDatabases> {
|
|
72
|
+
if (this._projects.has(projectId)) {
|
|
73
|
+
console.log(`🔄 [DEBUG] Returning cached databases for ${projectId}`)
|
|
74
|
+
return this._projects.get(projectId)!
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
console.log(`🆕 [DEBUG] Creating NEW databases for ${projectId}`)
|
|
78
|
+
const projectPath = join(this._config.basePath, projectId)
|
|
79
|
+
console.log(` Path: ${projectPath}`)
|
|
80
|
+
|
|
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
|
+
}),
|
|
109
|
+
])
|
|
110
|
+
|
|
111
|
+
const dbs: ProjectDatabases = { memories, summaries, snapshots, sessions }
|
|
112
|
+
this._projects.set(projectId, dbs)
|
|
113
|
+
|
|
114
|
+
return dbs
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// ================================================================
|
|
118
|
+
// MEMORY OPERATIONS
|
|
119
|
+
// ================================================================
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Store a curated memory
|
|
123
|
+
*/
|
|
124
|
+
async storeMemory(
|
|
125
|
+
projectId: string,
|
|
126
|
+
sessionId: string,
|
|
127
|
+
memory: CuratedMemory,
|
|
128
|
+
embedding?: Float32Array | number[]
|
|
129
|
+
): Promise<string> {
|
|
130
|
+
const { memories } = await this.getProject(projectId)
|
|
131
|
+
|
|
132
|
+
const id = await memories.insert({
|
|
133
|
+
content: memory.content,
|
|
134
|
+
reasoning: memory.reasoning,
|
|
135
|
+
importance_weight: memory.importance_weight,
|
|
136
|
+
confidence_score: memory.confidence_score,
|
|
137
|
+
context_type: memory.context_type,
|
|
138
|
+
temporal_relevance: memory.temporal_relevance,
|
|
139
|
+
knowledge_domain: memory.knowledge_domain,
|
|
140
|
+
emotional_resonance: memory.emotional_resonance,
|
|
141
|
+
action_required: memory.action_required,
|
|
142
|
+
problem_solution_pair: memory.problem_solution_pair,
|
|
143
|
+
semantic_tags: memory.semantic_tags,
|
|
144
|
+
trigger_phrases: memory.trigger_phrases,
|
|
145
|
+
question_types: memory.question_types,
|
|
146
|
+
session_id: sessionId,
|
|
147
|
+
project_id: projectId,
|
|
148
|
+
embedding: embedding
|
|
149
|
+
? (embedding instanceof Float32Array ? embedding : new Float32Array(embedding))
|
|
150
|
+
: undefined,
|
|
151
|
+
})
|
|
152
|
+
|
|
153
|
+
return id
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Get all memories for a project
|
|
158
|
+
*/
|
|
159
|
+
async getAllMemories(projectId: string): Promise<StoredMemory[]> {
|
|
160
|
+
const { memories } = await this.getProject(projectId)
|
|
161
|
+
|
|
162
|
+
return memories.all().map(record => ({
|
|
163
|
+
id: record.id,
|
|
164
|
+
content: record.content,
|
|
165
|
+
reasoning: record.reasoning,
|
|
166
|
+
importance_weight: record.importance_weight,
|
|
167
|
+
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,
|
|
172
|
+
action_required: record.action_required,
|
|
173
|
+
problem_solution_pair: record.problem_solution_pair,
|
|
174
|
+
semantic_tags: record.semantic_tags,
|
|
175
|
+
trigger_phrases: record.trigger_phrases,
|
|
176
|
+
question_types: record.question_types,
|
|
177
|
+
session_id: record.session_id,
|
|
178
|
+
project_id: record.project_id,
|
|
179
|
+
embedding: record.embedding,
|
|
180
|
+
created_at: record.created,
|
|
181
|
+
updated_at: record.updated,
|
|
182
|
+
stale: record.stale,
|
|
183
|
+
}))
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* Search memories by vector similarity
|
|
188
|
+
*/
|
|
189
|
+
async searchMemories(
|
|
190
|
+
projectId: string,
|
|
191
|
+
queryEmbedding: Float32Array | number[],
|
|
192
|
+
options: { topK?: number; filter?: (m: StoredMemory) => boolean } = {}
|
|
193
|
+
): Promise<StoredMemory[]> {
|
|
194
|
+
const { memories } = await this.getProject(projectId)
|
|
195
|
+
const { topK = 10, filter } = options
|
|
196
|
+
|
|
197
|
+
const results = memories.search('embedding', queryEmbedding, {
|
|
198
|
+
topK,
|
|
199
|
+
filter: filter ? (record) => {
|
|
200
|
+
// Convert record to StoredMemory format for filter
|
|
201
|
+
const mem: StoredMemory = {
|
|
202
|
+
id: record.id,
|
|
203
|
+
content: record.content,
|
|
204
|
+
reasoning: record.reasoning,
|
|
205
|
+
importance_weight: record.importance_weight,
|
|
206
|
+
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,
|
|
211
|
+
action_required: record.action_required,
|
|
212
|
+
problem_solution_pair: record.problem_solution_pair,
|
|
213
|
+
semantic_tags: record.semantic_tags,
|
|
214
|
+
trigger_phrases: record.trigger_phrases,
|
|
215
|
+
question_types: record.question_types,
|
|
216
|
+
session_id: record.session_id,
|
|
217
|
+
project_id: record.project_id,
|
|
218
|
+
created_at: 0,
|
|
219
|
+
updated_at: 0,
|
|
220
|
+
}
|
|
221
|
+
return filter(mem)
|
|
222
|
+
} : undefined,
|
|
223
|
+
})
|
|
224
|
+
|
|
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,
|
|
246
|
+
}))
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Update a memory's embedding
|
|
251
|
+
*/
|
|
252
|
+
async setMemoryEmbedding(
|
|
253
|
+
projectId: string,
|
|
254
|
+
memoryId: string,
|
|
255
|
+
embedding: Float32Array | number[],
|
|
256
|
+
content: string
|
|
257
|
+
): Promise<boolean> {
|
|
258
|
+
const { memories } = await this.getProject(projectId)
|
|
259
|
+
return memories.setEmbedding(memoryId, 'embedding', embedding, content)
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Get stale memory IDs (embedding out of sync with content)
|
|
264
|
+
*/
|
|
265
|
+
async getStaleMemoryIds(projectId: string): Promise<string[]> {
|
|
266
|
+
const { memories } = await this.getProject(projectId)
|
|
267
|
+
return memories.getStaleIds()
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// ================================================================
|
|
271
|
+
// SESSION OPERATIONS
|
|
272
|
+
// ================================================================
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Get or create a session
|
|
276
|
+
*/
|
|
277
|
+
async getOrCreateSession(
|
|
278
|
+
projectId: string,
|
|
279
|
+
sessionId: string
|
|
280
|
+
): Promise<{ isNew: boolean; messageCount: number; firstSessionCompleted: boolean }> {
|
|
281
|
+
const { sessions } = await this.getProject(projectId)
|
|
282
|
+
|
|
283
|
+
const existing = sessions.get(sessionId)
|
|
284
|
+
if (existing) {
|
|
285
|
+
return {
|
|
286
|
+
isNew: false,
|
|
287
|
+
messageCount: existing.message_count,
|
|
288
|
+
firstSessionCompleted: existing.first_session_completed,
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// Check if this is the first session for the project
|
|
293
|
+
const allSessions = sessions.all()
|
|
294
|
+
const firstSessionCompleted = allSessions.some(s => s.first_session_completed)
|
|
295
|
+
|
|
296
|
+
await sessions.insert({
|
|
297
|
+
id: sessionId,
|
|
298
|
+
project_id: projectId,
|
|
299
|
+
message_count: 0,
|
|
300
|
+
first_session_completed: false,
|
|
301
|
+
last_active: Date.now(),
|
|
302
|
+
metadata: '{}',
|
|
303
|
+
})
|
|
304
|
+
|
|
305
|
+
return {
|
|
306
|
+
isNew: true,
|
|
307
|
+
messageCount: 0,
|
|
308
|
+
firstSessionCompleted,
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Increment message count for a session
|
|
314
|
+
*/
|
|
315
|
+
async incrementMessageCount(projectId: string, sessionId: string): Promise<number> {
|
|
316
|
+
const { sessions } = await this.getProject(projectId)
|
|
317
|
+
|
|
318
|
+
const session = sessions.get(sessionId)
|
|
319
|
+
if (!session) {
|
|
320
|
+
throw new Error(`Session ${sessionId} not found`)
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
const newCount = session.message_count + 1
|
|
324
|
+
await sessions.update(sessionId, {
|
|
325
|
+
message_count: newCount,
|
|
326
|
+
last_active: Date.now(),
|
|
327
|
+
})
|
|
328
|
+
|
|
329
|
+
return newCount
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* Mark first session as completed
|
|
334
|
+
*/
|
|
335
|
+
async markFirstSessionCompleted(projectId: string, sessionId: string): Promise<void> {
|
|
336
|
+
const { sessions } = await this.getProject(projectId)
|
|
337
|
+
await sessions.update(sessionId, { first_session_completed: true })
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// ================================================================
|
|
341
|
+
// SUMMARY OPERATIONS
|
|
342
|
+
// ================================================================
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* Store a session summary
|
|
346
|
+
*/
|
|
347
|
+
async storeSessionSummary(
|
|
348
|
+
projectId: string,
|
|
349
|
+
sessionId: string,
|
|
350
|
+
summary: string,
|
|
351
|
+
interactionTone: string = ''
|
|
352
|
+
): Promise<string> {
|
|
353
|
+
const { summaries } = await this.getProject(projectId)
|
|
354
|
+
|
|
355
|
+
console.log(`📝 [DEBUG] Storing summary for ${projectId}:`)
|
|
356
|
+
console.log(` Summary length: ${summary.length} chars`)
|
|
357
|
+
console.log(` Summaries count before: ${summaries.all().length}`)
|
|
358
|
+
|
|
359
|
+
const id = await summaries.insert({
|
|
360
|
+
session_id: sessionId,
|
|
361
|
+
project_id: projectId,
|
|
362
|
+
summary,
|
|
363
|
+
interaction_tone: interactionTone,
|
|
364
|
+
})
|
|
365
|
+
|
|
366
|
+
console.log(` Summaries count after: ${summaries.all().length}`)
|
|
367
|
+
console.log(` Inserted ID: ${id}`)
|
|
368
|
+
|
|
369
|
+
return id
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Get the latest session summary for a project
|
|
374
|
+
*/
|
|
375
|
+
async getLatestSummary(projectId: string): Promise<SessionSummary | null> {
|
|
376
|
+
const { summaries } = await this.getProject(projectId)
|
|
377
|
+
|
|
378
|
+
console.log(`📖 [DEBUG] Getting latest summary for ${projectId}:`)
|
|
379
|
+
const all = summaries.all()
|
|
380
|
+
console.log(` Summaries found: ${all.length}`)
|
|
381
|
+
|
|
382
|
+
if (!all.length) {
|
|
383
|
+
console.log(` No summaries found!`)
|
|
384
|
+
return null
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
// Sort by created timestamp (most recent first)
|
|
388
|
+
all.sort((a, b) => b.created - a.created)
|
|
389
|
+
|
|
390
|
+
const latest = all[0]!
|
|
391
|
+
console.log(` Latest summary: ${latest.summary.slice(0, 50)}...`)
|
|
392
|
+
|
|
393
|
+
return {
|
|
394
|
+
id: latest.id,
|
|
395
|
+
session_id: latest.session_id,
|
|
396
|
+
project_id: latest.project_id,
|
|
397
|
+
summary: latest.summary,
|
|
398
|
+
interaction_tone: latest.interaction_tone,
|
|
399
|
+
created_at: latest.created,
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
// ================================================================
|
|
404
|
+
// SNAPSHOT OPERATIONS
|
|
405
|
+
// ================================================================
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* Store a project snapshot
|
|
409
|
+
*/
|
|
410
|
+
async storeProjectSnapshot(
|
|
411
|
+
projectId: string,
|
|
412
|
+
sessionId: string,
|
|
413
|
+
snapshot: Omit<ProjectSnapshot, 'id' | 'session_id' | 'project_id' | 'created_at'>
|
|
414
|
+
): Promise<string> {
|
|
415
|
+
const { snapshots } = await this.getProject(projectId)
|
|
416
|
+
|
|
417
|
+
return snapshots.insert({
|
|
418
|
+
session_id: sessionId,
|
|
419
|
+
project_id: projectId,
|
|
420
|
+
current_phase: snapshot.current_phase,
|
|
421
|
+
recent_achievements: snapshot.recent_achievements,
|
|
422
|
+
active_challenges: snapshot.active_challenges,
|
|
423
|
+
next_steps: snapshot.next_steps,
|
|
424
|
+
})
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
/**
|
|
428
|
+
* Get the latest project snapshot
|
|
429
|
+
*/
|
|
430
|
+
async getLatestSnapshot(projectId: string): Promise<ProjectSnapshot | null> {
|
|
431
|
+
const { snapshots } = await this.getProject(projectId)
|
|
432
|
+
|
|
433
|
+
const all = snapshots.all()
|
|
434
|
+
if (!all.length) return null
|
|
435
|
+
|
|
436
|
+
// Sort by created timestamp (most recent first)
|
|
437
|
+
all.sort((a, b) => b.created - a.created)
|
|
438
|
+
|
|
439
|
+
const latest = all[0]!
|
|
440
|
+
return {
|
|
441
|
+
id: latest.id,
|
|
442
|
+
session_id: latest.session_id,
|
|
443
|
+
project_id: latest.project_id,
|
|
444
|
+
current_phase: latest.current_phase,
|
|
445
|
+
recent_achievements: latest.recent_achievements,
|
|
446
|
+
active_challenges: latest.active_challenges,
|
|
447
|
+
next_steps: latest.next_steps,
|
|
448
|
+
created_at: latest.created,
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
// ================================================================
|
|
453
|
+
// STATS & UTILITIES
|
|
454
|
+
// ================================================================
|
|
455
|
+
|
|
456
|
+
/**
|
|
457
|
+
* Get statistics for a project
|
|
458
|
+
*/
|
|
459
|
+
async getProjectStats(projectId: string): Promise<{
|
|
460
|
+
totalMemories: number
|
|
461
|
+
totalSessions: number
|
|
462
|
+
staleMemories: number
|
|
463
|
+
latestSession: string | null
|
|
464
|
+
}> {
|
|
465
|
+
const { memories, sessions } = await this.getProject(projectId)
|
|
466
|
+
|
|
467
|
+
const allMemories = memories.all()
|
|
468
|
+
const allSessions = sessions.all()
|
|
469
|
+
const staleIds = memories.getStaleIds()
|
|
470
|
+
|
|
471
|
+
// Find latest session
|
|
472
|
+
let latestSession: string | null = null
|
|
473
|
+
if (allSessions.length) {
|
|
474
|
+
allSessions.sort((a, b) => b.last_active - a.last_active)
|
|
475
|
+
latestSession = allSessions[0]!.id
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
return {
|
|
479
|
+
totalMemories: allMemories.length,
|
|
480
|
+
totalSessions: allSessions.length,
|
|
481
|
+
staleMemories: staleIds.length,
|
|
482
|
+
latestSession,
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
/**
|
|
487
|
+
* Close all project databases
|
|
488
|
+
*/
|
|
489
|
+
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()
|
|
495
|
+
}
|
|
496
|
+
this._projects.clear()
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
/**
|
|
501
|
+
* Create a new memory store
|
|
502
|
+
*/
|
|
503
|
+
export function createStore(config?: StoreConfig): MemoryStore {
|
|
504
|
+
return new MemoryStore(config)
|
|
505
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// @rlabs-inc/memory - AI Memory System
|
|
3
|
+
// Consciousness continuity through intelligent memory curation and retrieval
|
|
4
|
+
// ============================================================================
|
|
5
|
+
|
|
6
|
+
// Core exports
|
|
7
|
+
export {
|
|
8
|
+
MemoryEngine,
|
|
9
|
+
createEngine,
|
|
10
|
+
type EngineConfig,
|
|
11
|
+
type StorageMode,
|
|
12
|
+
type ContextRequest,
|
|
13
|
+
} from './core/engine.ts'
|
|
14
|
+
|
|
15
|
+
export {
|
|
16
|
+
MemoryStore,
|
|
17
|
+
createStore,
|
|
18
|
+
type StoreConfig,
|
|
19
|
+
} from './core/store.ts'
|
|
20
|
+
|
|
21
|
+
export {
|
|
22
|
+
SmartVectorRetrieval,
|
|
23
|
+
createRetrieval,
|
|
24
|
+
type SessionContext,
|
|
25
|
+
} from './core/retrieval.ts'
|
|
26
|
+
|
|
27
|
+
export {
|
|
28
|
+
Curator,
|
|
29
|
+
createCurator,
|
|
30
|
+
type CuratorConfig,
|
|
31
|
+
} from './core/curator.ts'
|
|
32
|
+
|
|
33
|
+
// Type exports
|
|
34
|
+
export type {
|
|
35
|
+
CuratedMemory,
|
|
36
|
+
StoredMemory,
|
|
37
|
+
SessionSummary,
|
|
38
|
+
ProjectSnapshot,
|
|
39
|
+
CurationResult,
|
|
40
|
+
RetrievalResult,
|
|
41
|
+
SessionPrimer,
|
|
42
|
+
ContextType,
|
|
43
|
+
TemporalRelevance,
|
|
44
|
+
EmotionalResonance,
|
|
45
|
+
KnowledgeDomain,
|
|
46
|
+
CurationTrigger,
|
|
47
|
+
} from './types/memory.ts'
|
|
48
|
+
|
|
49
|
+
export {
|
|
50
|
+
memorySchema,
|
|
51
|
+
sessionSummarySchema,
|
|
52
|
+
projectSnapshotSchema,
|
|
53
|
+
sessionSchema,
|
|
54
|
+
type MemorySchema,
|
|
55
|
+
type SessionSummarySchema,
|
|
56
|
+
type ProjectSnapshotSchema,
|
|
57
|
+
type SessionSchema,
|
|
58
|
+
} from './types/schema.ts'
|