@skillkit/memory 1.8.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/dist/index.js ADDED
@@ -0,0 +1,976 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropNames = Object.getOwnPropertyNames;
3
+ var __esm = (fn, res) => function __init() {
4
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
5
+ };
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+
11
+ // src/types.ts
12
+ var DEFAULT_TIER_PROMOTION_CONFIG, DEFAULT_EMBEDDING_DIMENSION;
13
+ var init_types = __esm({
14
+ "src/types.ts"() {
15
+ "use strict";
16
+ DEFAULT_TIER_PROMOTION_CONFIG = {
17
+ accessCountThreshold: 5,
18
+ reinforcementScoreThreshold: 0.7,
19
+ ageThresholdDays: 7
20
+ };
21
+ DEFAULT_EMBEDDING_DIMENSION = 384;
22
+ }
23
+ });
24
+
25
+ // src/database/schema.ts
26
+ async function initializeSchema(db) {
27
+ const tables = ["memories", "memory_vec", "memory_links"];
28
+ for (const table of tables) {
29
+ try {
30
+ await db.run(`?[id] := *${table}{id} :limit 1`);
31
+ } catch {
32
+ switch (table) {
33
+ case "memories":
34
+ await db.run(CREATE_MEMORIES_TABLE);
35
+ break;
36
+ case "memory_vec":
37
+ await db.run(CREATE_MEMORY_VEC_TABLE);
38
+ break;
39
+ case "memory_links":
40
+ await db.run(CREATE_MEMORY_LINKS_TABLE);
41
+ break;
42
+ }
43
+ }
44
+ }
45
+ try {
46
+ await db.run(CREATE_HNSW_INDEX);
47
+ } catch {
48
+ }
49
+ }
50
+ async function dropSchema(db) {
51
+ try {
52
+ await db.run("::hnsw drop memory_vec:embedding_idx");
53
+ } catch {
54
+ }
55
+ const tables = ["memory_links", "memory_vec", "memories"];
56
+ for (const table of tables) {
57
+ try {
58
+ await db.run(`::remove ${table}`);
59
+ } catch {
60
+ }
61
+ }
62
+ }
63
+ var CREATE_MEMORIES_TABLE, CREATE_MEMORY_VEC_TABLE, CREATE_MEMORY_LINKS_TABLE, CREATE_HNSW_INDEX;
64
+ var init_schema = __esm({
65
+ "src/database/schema.ts"() {
66
+ "use strict";
67
+ CREATE_MEMORIES_TABLE = `
68
+ :create memories {
69
+ id: String
70
+ =>
71
+ agent_id: String,
72
+ category: String,
73
+ tier: String,
74
+ content: String,
75
+ reinforcement_score: Float,
76
+ created_at: String,
77
+ updated_at: String,
78
+ access_count: Int,
79
+ last_accessed_at: String,
80
+ tags: [String],
81
+ metadata: String
82
+ }
83
+ `;
84
+ CREATE_MEMORY_VEC_TABLE = `
85
+ :create memory_vec {
86
+ id: String
87
+ =>
88
+ embedding: <F32; 384>
89
+ }
90
+ `;
91
+ CREATE_MEMORY_LINKS_TABLE = `
92
+ :create memory_links {
93
+ id: String
94
+ =>
95
+ source_id: String,
96
+ target_id: String,
97
+ relationship_type: String,
98
+ strength: Float,
99
+ created_at: String
100
+ }
101
+ `;
102
+ CREATE_HNSW_INDEX = `
103
+ ::hnsw create memory_vec:embedding_idx {
104
+ dim: 384,
105
+ m: 16,
106
+ ef_construction: 100,
107
+ dtype: F32,
108
+ fields: [embedding],
109
+ distance: Cosine,
110
+ filter: null
111
+ }
112
+ `;
113
+ }
114
+ });
115
+
116
+ // src/database/cozo-adapter.ts
117
+ import { CozoDb } from "cozo-node";
118
+ import { mkdir } from "fs/promises";
119
+ import { dirname, join } from "path";
120
+ import { homedir } from "os";
121
+ var CozoAdapter;
122
+ var init_cozo_adapter = __esm({
123
+ "src/database/cozo-adapter.ts"() {
124
+ "use strict";
125
+ init_schema();
126
+ CozoAdapter = class {
127
+ db = null;
128
+ dbPath;
129
+ initialized = false;
130
+ constructor(options) {
131
+ this.dbPath = options.dbPath ?? this.getDefaultDbPath(options.agentId);
132
+ }
133
+ getDefaultDbPath(agentId) {
134
+ return join(homedir(), ".skillkit", "agents", agentId, "memory.db");
135
+ }
136
+ async initialize() {
137
+ if (this.initialized) return;
138
+ await mkdir(dirname(this.dbPath), { recursive: true });
139
+ this.db = new CozoDb("rocksdb", this.dbPath);
140
+ await initializeSchema(this.db);
141
+ this.initialized = true;
142
+ }
143
+ async close() {
144
+ if (this.db) {
145
+ this.db.close();
146
+ this.db = null;
147
+ this.initialized = false;
148
+ }
149
+ }
150
+ async reset() {
151
+ if (!this.db) throw new Error("Database not initialized");
152
+ await dropSchema(this.db);
153
+ await initializeSchema(this.db);
154
+ }
155
+ async run(query, params) {
156
+ if (!this.db) throw new Error("Database not initialized");
157
+ const result = await this.db.run(query, params);
158
+ return {
159
+ headers: result.headers,
160
+ rows: result.rows,
161
+ ok: result.ok
162
+ };
163
+ }
164
+ async insertMemory(id, agentId, category, tier, content, reinforcementScore, createdAt, updatedAt, accessCount, lastAccessedAt, tags, metadata) {
165
+ const query = `
166
+ ?[id, agent_id, category, tier, content, reinforcement_score, created_at, updated_at, access_count, last_accessed_at, tags, metadata] <- [[
167
+ $id, $agent_id, $category, $tier, $content, $reinforcement_score, $created_at, $updated_at, $access_count, $last_accessed_at, $tags, $metadata
168
+ ]]
169
+ :put memories {
170
+ id, agent_id, category, tier, content, reinforcement_score, created_at, updated_at, access_count, last_accessed_at, tags, metadata
171
+ }
172
+ `;
173
+ await this.run(query, {
174
+ id,
175
+ agent_id: agentId,
176
+ category,
177
+ tier,
178
+ content,
179
+ reinforcement_score: reinforcementScore,
180
+ created_at: createdAt,
181
+ updated_at: updatedAt,
182
+ access_count: accessCount,
183
+ last_accessed_at: lastAccessedAt,
184
+ tags,
185
+ metadata: JSON.stringify(metadata)
186
+ });
187
+ }
188
+ async insertEmbedding(id, embedding) {
189
+ const query = `
190
+ ?[id, embedding] <- [[$id, $embedding]]
191
+ :put memory_vec { id, embedding }
192
+ `;
193
+ await this.run(query, { id, embedding });
194
+ }
195
+ async getMemory(id) {
196
+ const query = `
197
+ ?[id, agent_id, category, tier, content, reinforcement_score, created_at, updated_at, access_count, last_accessed_at, tags, metadata] :=
198
+ *memories[id, agent_id, category, tier, content, reinforcement_score, created_at, updated_at, access_count, last_accessed_at, tags, metadata],
199
+ id == $id
200
+ `;
201
+ const result = await this.run(query, { id });
202
+ if (result.rows.length === 0) return null;
203
+ return this.rowToMemory(result.rows[0]);
204
+ }
205
+ async getMemoriesByAgent(agentId, limit = 100) {
206
+ const query = `
207
+ ?[id, agent_id, category, tier, content, reinforcement_score, created_at, updated_at, access_count, last_accessed_at, tags, metadata] :=
208
+ *memories[id, agent_id, category, tier, content, reinforcement_score, created_at, updated_at, access_count, last_accessed_at, tags, metadata],
209
+ agent_id == $agent_id
210
+ :limit $limit
211
+ `;
212
+ const result = await this.run(query, { agent_id: agentId, limit });
213
+ return result.rows.map((row) => this.rowToMemory(row));
214
+ }
215
+ async updateMemory(id, updates) {
216
+ const existing = await this.getMemory(id);
217
+ if (!existing) throw new Error(`Memory ${id} not found`);
218
+ const query = `
219
+ ?[id, agent_id, category, tier, content, reinforcement_score, created_at, updated_at, access_count, last_accessed_at, tags, metadata] <- [[
220
+ $id, $agent_id, $category, $tier, $content, $reinforcement_score, $created_at, $updated_at, $access_count, $last_accessed_at, $tags, $metadata
221
+ ]]
222
+ :put memories {
223
+ id, agent_id, category, tier, content, reinforcement_score, created_at, updated_at, access_count, last_accessed_at, tags, metadata
224
+ }
225
+ `;
226
+ await this.run(query, {
227
+ id,
228
+ agent_id: existing.agentId,
229
+ category: updates.category ?? existing.category,
230
+ tier: updates.tier ?? existing.tier,
231
+ content: updates.content ?? existing.content,
232
+ reinforcement_score: updates.reinforcementScore ?? existing.reinforcementScore,
233
+ created_at: existing.createdAt,
234
+ updated_at: updates.updatedAt ?? (/* @__PURE__ */ new Date()).toISOString(),
235
+ access_count: updates.accessCount ?? existing.accessCount,
236
+ last_accessed_at: updates.lastAccessedAt ?? existing.lastAccessedAt,
237
+ tags: updates.tags ?? existing.tags,
238
+ metadata: JSON.stringify(updates.metadata ?? existing.metadata)
239
+ });
240
+ }
241
+ async deleteMemory(id) {
242
+ const deleteMemory = `
243
+ ?[id] <- [[$id]]
244
+ :rm memories { id }
245
+ `;
246
+ const deleteEmbedding = `
247
+ ?[id] <- [[$id]]
248
+ :rm memory_vec { id }
249
+ `;
250
+ await this.run(deleteMemory, { id });
251
+ await this.run(deleteEmbedding, { id });
252
+ }
253
+ async semanticSearch(embedding, limit = 10, _agentId, _category, _tier) {
254
+ const params = { embedding, limit };
255
+ const query = `
256
+ ?[id, score] := ~memory_vec:embedding_idx{ id, embedding |
257
+ query: $embedding,
258
+ k: $limit,
259
+ ef: 50
260
+ }, score = cos_dist(embedding, $embedding)
261
+ :order score
262
+ :limit $limit
263
+ `;
264
+ const result = await this.run(query, params);
265
+ return result.rows.map((row) => ({
266
+ id: row[0],
267
+ score: 1 - row[1]
268
+ }));
269
+ }
270
+ async insertLink(id, sourceId, targetId, relationshipType, strength, createdAt) {
271
+ const query = `
272
+ ?[id, source_id, target_id, relationship_type, strength, created_at] <- [[
273
+ $id, $source_id, $target_id, $relationship_type, $strength, $created_at
274
+ ]]
275
+ :put memory_links { id, source_id, target_id, relationship_type, strength, created_at }
276
+ `;
277
+ await this.run(query, {
278
+ id,
279
+ source_id: sourceId,
280
+ target_id: targetId,
281
+ relationship_type: relationshipType,
282
+ strength,
283
+ created_at: createdAt
284
+ });
285
+ }
286
+ async getLinks(memoryId) {
287
+ const query = `
288
+ ?[id, source_id, target_id, relationship_type, strength, created_at] :=
289
+ *memory_links[id, source_id, target_id, relationship_type, strength, created_at],
290
+ or(source_id == $memory_id, target_id == $memory_id)
291
+ `;
292
+ const result = await this.run(query, { memory_id: memoryId });
293
+ return result.rows.map((row) => ({
294
+ id: row[0],
295
+ sourceId: row[1],
296
+ targetId: row[2],
297
+ relationshipType: row[3],
298
+ strength: row[4],
299
+ createdAt: row[5]
300
+ }));
301
+ }
302
+ async getStats(agentId) {
303
+ let condition = "";
304
+ const params = {};
305
+ if (agentId) {
306
+ condition = ", agent_id == $agent_id";
307
+ params.agent_id = agentId;
308
+ }
309
+ const countQuery = `
310
+ ?[count(id)] := *memories[id, agent_id, _, _, _, _, _, _, _, _, _, _]${condition}
311
+ `;
312
+ const countResult = await this.run(countQuery, params);
313
+ const total = countResult.rows[0]?.[0] ?? 0;
314
+ const categoryQuery = `
315
+ ?[category, count(id)] := *memories[id, agent_id, category, _, _, _, _, _, _, _, _, _]${condition}
316
+ `;
317
+ const categoryResult = await this.run(categoryQuery, params);
318
+ const byCategory = {};
319
+ for (const row of categoryResult.rows) {
320
+ byCategory[row[0]] = row[1];
321
+ }
322
+ const tierQuery = `
323
+ ?[tier, count(id)] := *memories[id, agent_id, _, tier, _, _, _, _, _, _, _, _]${condition}
324
+ `;
325
+ const tierResult = await this.run(tierQuery, params);
326
+ const byTier = {};
327
+ for (const row of tierResult.rows) {
328
+ byTier[row[0]] = row[1];
329
+ }
330
+ return {
331
+ total,
332
+ byCategory,
333
+ byTier
334
+ };
335
+ }
336
+ rowToMemory(row) {
337
+ return {
338
+ id: row[0],
339
+ agentId: row[1],
340
+ category: row[2],
341
+ tier: row[3],
342
+ content: row[4],
343
+ reinforcementScore: row[5],
344
+ createdAt: row[6],
345
+ updatedAt: row[7],
346
+ accessCount: row[8],
347
+ lastAccessedAt: row[9],
348
+ tags: row[10],
349
+ metadata: JSON.parse(row[11])
350
+ };
351
+ }
352
+ get isInitialized() {
353
+ return this.initialized;
354
+ }
355
+ get path() {
356
+ return this.dbPath;
357
+ }
358
+ };
359
+ }
360
+ });
361
+
362
+ // src/embeddings/encoder.ts
363
+ import { pipeline, env } from "@xenova/transformers";
364
+ async function initializeEncoder(options = {}) {
365
+ if (embeddingPipeline) return;
366
+ if (initPromise) {
367
+ await initPromise;
368
+ return;
369
+ }
370
+ initPromise = (async () => {
371
+ if (options.cacheDir) {
372
+ env.cacheDir = options.cacheDir;
373
+ }
374
+ const modelName = options.model ?? DEFAULT_MODEL;
375
+ embeddingPipeline = await pipeline("feature-extraction", modelName, {
376
+ quantized: true
377
+ });
378
+ })();
379
+ try {
380
+ await initPromise;
381
+ } catch (error) {
382
+ initPromise = null;
383
+ throw error;
384
+ }
385
+ }
386
+ async function encode(text) {
387
+ if (!embeddingPipeline) {
388
+ await initializeEncoder();
389
+ }
390
+ if (!embeddingPipeline) {
391
+ throw new Error("Failed to initialize embedding pipeline");
392
+ }
393
+ const output = await embeddingPipeline(text, {
394
+ pooling: "mean",
395
+ normalize: true
396
+ });
397
+ const embedding = Array.from(output.data);
398
+ if (embedding.length !== DEFAULT_EMBEDDING_DIMENSION) {
399
+ throw new Error(
400
+ `Embedding dimension mismatch: expected ${DEFAULT_EMBEDDING_DIMENSION}, got ${embedding.length}`
401
+ );
402
+ }
403
+ return embedding;
404
+ }
405
+ async function encodeBatch(texts) {
406
+ if (texts.length === 0) return [];
407
+ if (!embeddingPipeline) {
408
+ await initializeEncoder();
409
+ }
410
+ if (!embeddingPipeline) {
411
+ throw new Error("Failed to initialize embedding pipeline");
412
+ }
413
+ const embeddings = [];
414
+ for (const text of texts) {
415
+ const output = await embeddingPipeline(text, {
416
+ pooling: "mean",
417
+ normalize: true
418
+ });
419
+ embeddings.push(Array.from(output.data));
420
+ }
421
+ return embeddings;
422
+ }
423
+ function cosineSimilarity(a, b) {
424
+ if (a.length !== b.length) {
425
+ throw new Error("Vectors must have the same dimension");
426
+ }
427
+ let dotProduct = 0;
428
+ let normA = 0;
429
+ let normB = 0;
430
+ for (let i = 0; i < a.length; i++) {
431
+ dotProduct += a[i] * b[i];
432
+ normA += a[i] * a[i];
433
+ normB += b[i] * b[i];
434
+ }
435
+ const denominator = Math.sqrt(normA) * Math.sqrt(normB);
436
+ if (denominator === 0) return 0;
437
+ return dotProduct / denominator;
438
+ }
439
+ function euclideanDistance(a, b) {
440
+ if (a.length !== b.length) {
441
+ throw new Error("Vectors must have the same dimension");
442
+ }
443
+ let sum = 0;
444
+ for (let i = 0; i < a.length; i++) {
445
+ const diff = a[i] - b[i];
446
+ sum += diff * diff;
447
+ }
448
+ return Math.sqrt(sum);
449
+ }
450
+ function isEncoderReady() {
451
+ return embeddingPipeline !== null;
452
+ }
453
+ async function disposeEncoder() {
454
+ if (embeddingPipeline) {
455
+ try {
456
+ await embeddingPipeline.dispose();
457
+ } catch {
458
+ }
459
+ }
460
+ embeddingPipeline = null;
461
+ initPromise = null;
462
+ }
463
+ var embeddingPipeline, initPromise, DEFAULT_MODEL;
464
+ var init_encoder = __esm({
465
+ "src/embeddings/encoder.ts"() {
466
+ "use strict";
467
+ init_types();
468
+ env.cacheDir = "./.cache/transformers";
469
+ embeddingPipeline = null;
470
+ initPromise = null;
471
+ DEFAULT_MODEL = "Xenova/all-MiniLM-L6-v2";
472
+ }
473
+ });
474
+
475
+ // src/embeddings/search.ts
476
+ async function quickSearch(adapter, query, options = {}) {
477
+ const search = new SemanticSearch(adapter);
478
+ return search.search(query, options);
479
+ }
480
+ var SemanticSearch;
481
+ var init_search = __esm({
482
+ "src/embeddings/search.ts"() {
483
+ "use strict";
484
+ init_encoder();
485
+ SemanticSearch = class {
486
+ constructor(adapter) {
487
+ this.adapter = adapter;
488
+ }
489
+ async search(query, options = {}) {
490
+ const {
491
+ agentId,
492
+ category,
493
+ tier,
494
+ limit = 10,
495
+ threshold = 0.5,
496
+ minScore = 0
497
+ } = options;
498
+ const queryEmbedding = await encode(query);
499
+ const results = await this.adapter.semanticSearch(
500
+ queryEmbedding,
501
+ limit * 5,
502
+ agentId,
503
+ category,
504
+ tier
505
+ );
506
+ const searchResults = [];
507
+ for (const { id, score } of results) {
508
+ if (score < Math.max(threshold, minScore)) continue;
509
+ if (searchResults.length >= limit) break;
510
+ const memory = await this.adapter.getMemory(id);
511
+ if (!memory) continue;
512
+ if (agentId && memory.agentId !== agentId) continue;
513
+ if (category && memory.category !== category) continue;
514
+ if (tier && memory.tier !== tier) continue;
515
+ searchResults.push({
516
+ memory: this.rowToMemory(memory),
517
+ score
518
+ });
519
+ }
520
+ return searchResults;
521
+ }
522
+ async findSimilar(memoryId, limit = 5, excludeSelf = true) {
523
+ const memory = await this.adapter.getMemory(memoryId);
524
+ if (!memory) {
525
+ throw new Error(`Memory ${memoryId} not found`);
526
+ }
527
+ const embedding = await encode(memory.content);
528
+ const results = await this.adapter.semanticSearch(
529
+ embedding,
530
+ limit + (excludeSelf ? 1 : 0),
531
+ memory.agentId
532
+ );
533
+ const searchResults = [];
534
+ for (const { id, score } of results) {
535
+ if (excludeSelf && id === memoryId) continue;
536
+ if (searchResults.length >= limit) break;
537
+ const similarMemory = await this.adapter.getMemory(id);
538
+ if (!similarMemory) continue;
539
+ searchResults.push({
540
+ memory: this.rowToMemory(similarMemory),
541
+ score
542
+ });
543
+ }
544
+ return searchResults;
545
+ }
546
+ async searchByCategory(query, category, limit = 10) {
547
+ return this.search(query, { category, limit });
548
+ }
549
+ async searchByTier(query, tier, limit = 10) {
550
+ return this.search(query, { tier, limit });
551
+ }
552
+ async hybridSearch(query, keywords, options = {}) {
553
+ const semanticResults = await this.search(query, {
554
+ ...options,
555
+ limit: (options.limit ?? 10) * 2
556
+ });
557
+ const scoredResults = semanticResults.map((result) => {
558
+ let keywordBoost = 0;
559
+ const contentLower = result.memory.content.toLowerCase();
560
+ for (const keyword of keywords) {
561
+ if (contentLower.includes(keyword.toLowerCase())) {
562
+ keywordBoost += 0.1;
563
+ }
564
+ }
565
+ return {
566
+ ...result,
567
+ score: Math.min(1, result.score + keywordBoost)
568
+ };
569
+ });
570
+ scoredResults.sort((a, b) => b.score - a.score);
571
+ return scoredResults.slice(0, options.limit ?? 10);
572
+ }
573
+ rowToMemory(row) {
574
+ return {
575
+ id: row.id,
576
+ agentId: row.agentId,
577
+ category: row.category,
578
+ tier: row.tier,
579
+ content: row.content,
580
+ embedding: row.embedding || [],
581
+ reinforcementScore: row.reinforcementScore,
582
+ createdAt: row.createdAt,
583
+ updatedAt: row.updatedAt,
584
+ accessCount: row.accessCount,
585
+ lastAccessedAt: row.lastAccessedAt,
586
+ tags: row.tags,
587
+ metadata: row.metadata
588
+ };
589
+ }
590
+ };
591
+ }
592
+ });
593
+
594
+ // src/stores/memory-store.ts
595
+ var memory_store_exports = {};
596
+ __export(memory_store_exports, {
597
+ MemoryStore: () => MemoryStore
598
+ });
599
+ import { randomUUID } from "crypto";
600
+ var MemoryStore;
601
+ var init_memory_store = __esm({
602
+ "src/stores/memory-store.ts"() {
603
+ "use strict";
604
+ init_cozo_adapter();
605
+ init_encoder();
606
+ init_search();
607
+ MemoryStore = class {
608
+ adapter;
609
+ search;
610
+ constructor(agentId, dbPath) {
611
+ this.adapter = new CozoAdapter({ agentId, dbPath });
612
+ this.search = new SemanticSearch(this.adapter);
613
+ }
614
+ async initialize() {
615
+ await this.adapter.initialize();
616
+ }
617
+ async close() {
618
+ await this.adapter.close();
619
+ }
620
+ async create(input) {
621
+ const id = randomUUID();
622
+ const now = (/* @__PURE__ */ new Date()).toISOString();
623
+ const embedding = await encode(input.content);
624
+ await this.adapter.insertMemory(
625
+ id,
626
+ input.agentId,
627
+ input.category,
628
+ input.tier ?? "warm",
629
+ input.content,
630
+ 1,
631
+ now,
632
+ now,
633
+ 0,
634
+ now,
635
+ input.tags ?? [],
636
+ input.metadata ?? {}
637
+ );
638
+ await this.adapter.insertEmbedding(id, embedding);
639
+ return {
640
+ id,
641
+ agentId: input.agentId,
642
+ category: input.category,
643
+ tier: input.tier ?? "warm",
644
+ content: input.content,
645
+ embedding,
646
+ reinforcementScore: 1,
647
+ createdAt: now,
648
+ updatedAt: now,
649
+ accessCount: 0,
650
+ lastAccessedAt: now,
651
+ tags: input.tags ?? [],
652
+ metadata: input.metadata ?? {}
653
+ };
654
+ }
655
+ async get(id) {
656
+ const row = await this.adapter.getMemory(id);
657
+ if (!row) return null;
658
+ await this.adapter.updateMemory(id, {
659
+ accessCount: row.accessCount + 1,
660
+ lastAccessedAt: (/* @__PURE__ */ new Date()).toISOString()
661
+ });
662
+ return {
663
+ id: row.id,
664
+ agentId: row.agentId,
665
+ category: row.category,
666
+ tier: row.tier,
667
+ content: row.content,
668
+ embedding: [],
669
+ reinforcementScore: row.reinforcementScore,
670
+ createdAt: row.createdAt,
671
+ updatedAt: row.updatedAt,
672
+ accessCount: row.accessCount + 1,
673
+ lastAccessedAt: (/* @__PURE__ */ new Date()).toISOString(),
674
+ tags: row.tags,
675
+ metadata: row.metadata
676
+ };
677
+ }
678
+ async update(id, input) {
679
+ const existing = await this.adapter.getMemory(id);
680
+ if (!existing) {
681
+ throw new Error(`Memory ${id} not found`);
682
+ }
683
+ const updates = {
684
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
685
+ };
686
+ if (input.category) updates.category = input.category;
687
+ if (input.tier) updates.tier = input.tier;
688
+ if (input.tags) updates.tags = input.tags;
689
+ if (input.metadata) updates.metadata = input.metadata;
690
+ if (input.content && input.content !== existing.content) {
691
+ updates.content = input.content;
692
+ const embedding = await encode(input.content);
693
+ await this.adapter.insertEmbedding(id, embedding);
694
+ }
695
+ await this.adapter.updateMemory(id, updates);
696
+ const updated = await this.adapter.getMemory(id);
697
+ if (!updated) {
698
+ throw new Error(`Failed to update memory ${id}`);
699
+ }
700
+ return {
701
+ id: updated.id,
702
+ agentId: updated.agentId,
703
+ category: updated.category,
704
+ tier: updated.tier,
705
+ content: updated.content,
706
+ embedding: [],
707
+ reinforcementScore: updated.reinforcementScore,
708
+ createdAt: updated.createdAt,
709
+ updatedAt: updated.updatedAt,
710
+ accessCount: updated.accessCount,
711
+ lastAccessedAt: updated.lastAccessedAt,
712
+ tags: updated.tags,
713
+ metadata: updated.metadata
714
+ };
715
+ }
716
+ async delete(id) {
717
+ await this.adapter.deleteMemory(id);
718
+ }
719
+ async list(agentId, limit = 100) {
720
+ const rows = await this.adapter.getMemoriesByAgent(agentId, limit);
721
+ return rows.map((row) => ({
722
+ id: row.id,
723
+ agentId: row.agentId,
724
+ category: row.category,
725
+ tier: row.tier,
726
+ content: row.content,
727
+ embedding: [],
728
+ reinforcementScore: row.reinforcementScore,
729
+ createdAt: row.createdAt,
730
+ updatedAt: row.updatedAt,
731
+ accessCount: row.accessCount,
732
+ lastAccessedAt: row.lastAccessedAt,
733
+ tags: row.tags,
734
+ metadata: row.metadata
735
+ }));
736
+ }
737
+ async semanticSearch(query, options = {}) {
738
+ return this.search.search(query, options);
739
+ }
740
+ async findSimilar(memoryId, limit = 5) {
741
+ return this.search.findSimilar(memoryId, limit);
742
+ }
743
+ async reinforce(id, amount = 0.1) {
744
+ const existing = await this.adapter.getMemory(id);
745
+ if (!existing) {
746
+ throw new Error(`Memory ${id} not found`);
747
+ }
748
+ const newScore = Math.min(1, existing.reinforcementScore + amount);
749
+ await this.adapter.updateMemory(id, {
750
+ reinforcementScore: newScore,
751
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
752
+ });
753
+ return this.get(id);
754
+ }
755
+ async weaken(id, amount = 0.1) {
756
+ const existing = await this.adapter.getMemory(id);
757
+ if (!existing) {
758
+ throw new Error(`Memory ${id} not found`);
759
+ }
760
+ const newScore = Math.max(0, existing.reinforcementScore - amount);
761
+ await this.adapter.updateMemory(id, {
762
+ reinforcementScore: newScore,
763
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString()
764
+ });
765
+ return this.get(id);
766
+ }
767
+ async link(sourceId, targetId, relationshipType, strength = 1) {
768
+ const id = randomUUID();
769
+ const now = (/* @__PURE__ */ new Date()).toISOString();
770
+ await this.adapter.insertLink(id, sourceId, targetId, relationshipType, strength, now);
771
+ return {
772
+ id,
773
+ sourceId,
774
+ targetId,
775
+ relationshipType,
776
+ strength,
777
+ createdAt: now
778
+ };
779
+ }
780
+ async getLinks(memoryId) {
781
+ const rows = await this.adapter.getLinks(memoryId);
782
+ return rows.map((row) => ({
783
+ id: row.id,
784
+ sourceId: row.sourceId,
785
+ targetId: row.targetId,
786
+ relationshipType: row.relationshipType,
787
+ strength: row.strength,
788
+ createdAt: row.createdAt
789
+ }));
790
+ }
791
+ async getStats(agentId) {
792
+ const stats = await this.adapter.getStats(agentId);
793
+ const byCategory = {
794
+ fact: stats.byCategory.fact ?? 0,
795
+ decision: stats.byCategory.decision ?? 0,
796
+ preference: stats.byCategory.preference ?? 0,
797
+ pattern: stats.byCategory.pattern ?? 0,
798
+ insight: stats.byCategory.insight ?? 0,
799
+ reasoning: stats.byCategory.reasoning ?? 0
800
+ };
801
+ const byTier = {
802
+ warm: stats.byTier.warm ?? 0,
803
+ long: stats.byTier.long ?? 0
804
+ };
805
+ return {
806
+ totalMemories: stats.total,
807
+ byCategory,
808
+ byTier,
809
+ avgReinforcementScore: 0,
810
+ oldestMemory: null,
811
+ newestMemory: null
812
+ };
813
+ }
814
+ async promoteToLongTerm(id) {
815
+ return this.update(id, { tier: "long" });
816
+ }
817
+ async demoteToWarm(id) {
818
+ return this.update(id, { tier: "warm" });
819
+ }
820
+ get isInitialized() {
821
+ return this.adapter.isInitialized;
822
+ }
823
+ get dbPath() {
824
+ return this.adapter.path;
825
+ }
826
+ };
827
+ }
828
+ });
829
+
830
+ // src/index.ts
831
+ init_types();
832
+
833
+ // src/database/index.ts
834
+ init_cozo_adapter();
835
+ init_schema();
836
+
837
+ // src/embeddings/index.ts
838
+ init_encoder();
839
+ init_search();
840
+
841
+ // src/stores/index.ts
842
+ init_memory_store();
843
+
844
+ // src/tiers/tier-manager.ts
845
+ init_types();
846
+ var TierManager = class {
847
+ config;
848
+ constructor(config = {}) {
849
+ this.config = { ...DEFAULT_TIER_PROMOTION_CONFIG, ...config };
850
+ }
851
+ evaluateForPromotion(memory) {
852
+ const score = this.calculatePromotionScore(memory);
853
+ const threshold = 0.7;
854
+ const shouldPromote = memory.tier === "warm" && score >= threshold;
855
+ const shouldDemote = memory.tier === "long" && score < 0.3;
856
+ let suggestedTier = memory.tier;
857
+ let reason = "Memory is appropriately tiered";
858
+ if (shouldPromote) {
859
+ suggestedTier = "long";
860
+ reason = this.getPromotionReason(memory);
861
+ } else if (shouldDemote) {
862
+ suggestedTier = "warm";
863
+ reason = this.getDemotionReason(memory);
864
+ }
865
+ return {
866
+ memoryId: memory.id,
867
+ currentTier: memory.tier,
868
+ suggestedTier,
869
+ reason,
870
+ score
871
+ };
872
+ }
873
+ calculatePromotionScore(memory) {
874
+ const accessScore = Math.min(1, memory.accessCount / this.config.accessCountThreshold);
875
+ const reinforcementScore = memory.reinforcementScore / this.config.reinforcementScoreThreshold;
876
+ const ageMs = Date.now() - new Date(memory.createdAt).getTime();
877
+ const ageDays = ageMs / (1e3 * 60 * 60 * 24);
878
+ const ageScore = Math.min(1, ageDays / this.config.ageThresholdDays);
879
+ const recencyMs = Date.now() - new Date(memory.lastAccessedAt).getTime();
880
+ const recencyDays = recencyMs / (1e3 * 60 * 60 * 24);
881
+ const recencyScore = Math.max(0, 1 - recencyDays / 30);
882
+ const weights = {
883
+ access: 0.3,
884
+ reinforcement: 0.35,
885
+ age: 0.15,
886
+ recency: 0.2
887
+ };
888
+ return accessScore * weights.access + Math.min(1, reinforcementScore) * weights.reinforcement + ageScore * weights.age + recencyScore * weights.recency;
889
+ }
890
+ async evaluateAll(store, agentId) {
891
+ const memories = await store.list(agentId);
892
+ return memories.map((memory) => this.evaluateForPromotion(memory));
893
+ }
894
+ async applyRecommendations(store, evaluations) {
895
+ const promoted = [];
896
+ const demoted = [];
897
+ for (const evaluation of evaluations) {
898
+ if (evaluation.currentTier === evaluation.suggestedTier) continue;
899
+ if (evaluation.suggestedTier === "long") {
900
+ await store.promoteToLongTerm(evaluation.memoryId);
901
+ promoted.push(evaluation.memoryId);
902
+ } else {
903
+ await store.demoteToWarm(evaluation.memoryId);
904
+ demoted.push(evaluation.memoryId);
905
+ }
906
+ }
907
+ return { promoted, demoted };
908
+ }
909
+ async autoPromote(store, agentId) {
910
+ const evaluations = await this.evaluateAll(store, agentId);
911
+ return this.applyRecommendations(store, evaluations);
912
+ }
913
+ getConfig() {
914
+ return { ...this.config };
915
+ }
916
+ updateConfig(updates) {
917
+ this.config = { ...this.config, ...updates };
918
+ }
919
+ getPromotionReason(memory) {
920
+ const reasons = [];
921
+ if (memory.accessCount >= this.config.accessCountThreshold) {
922
+ reasons.push(`accessed ${memory.accessCount} times`);
923
+ }
924
+ if (memory.reinforcementScore >= this.config.reinforcementScoreThreshold) {
925
+ reasons.push(`high reinforcement (${memory.reinforcementScore.toFixed(2)})`);
926
+ }
927
+ const ageDays = (Date.now() - new Date(memory.createdAt).getTime()) / (1e3 * 60 * 60 * 24);
928
+ if (ageDays >= this.config.ageThresholdDays) {
929
+ reasons.push(`${Math.floor(ageDays)} days old`);
930
+ }
931
+ return reasons.length > 0 ? `Promote to long-term: ${reasons.join(", ")}` : "Memory qualifies for long-term storage";
932
+ }
933
+ getDemotionReason(memory) {
934
+ const reasons = [];
935
+ if (memory.reinforcementScore < 0.3) {
936
+ reasons.push(`low reinforcement (${memory.reinforcementScore.toFixed(2)})`);
937
+ }
938
+ const recencyDays = (Date.now() - new Date(memory.lastAccessedAt).getTime()) / (1e3 * 60 * 60 * 24);
939
+ if (recencyDays > 30) {
940
+ reasons.push(`not accessed in ${Math.floor(recencyDays)} days`);
941
+ }
942
+ return reasons.length > 0 ? `Demote to warm: ${reasons.join(", ")}` : "Memory no longer qualifies for long-term storage";
943
+ }
944
+ };
945
+ function createTierManager(config) {
946
+ return new TierManager(config);
947
+ }
948
+
949
+ // src/index.ts
950
+ async function createMemoryStore(agentId, dbPath) {
951
+ const { MemoryStore: MemoryStore2 } = await Promise.resolve().then(() => (init_memory_store(), memory_store_exports));
952
+ const store = new MemoryStore2(agentId, dbPath);
953
+ await store.initialize();
954
+ return store;
955
+ }
956
+ export {
957
+ CozoAdapter,
958
+ DEFAULT_EMBEDDING_DIMENSION,
959
+ DEFAULT_TIER_PROMOTION_CONFIG,
960
+ MemoryStore,
961
+ SemanticSearch,
962
+ TierManager,
963
+ cosineSimilarity,
964
+ createMemoryStore,
965
+ createTierManager,
966
+ disposeEncoder,
967
+ dropSchema,
968
+ encode,
969
+ encodeBatch,
970
+ euclideanDistance,
971
+ initializeEncoder,
972
+ initializeSchema,
973
+ isEncoderReady,
974
+ quickSearch
975
+ };
976
+ //# sourceMappingURL=index.js.map