mnemocyte 0.0.5 → 0.0.7

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.d.mts CHANGED
@@ -2,6 +2,23 @@
2
2
  type MemoryType = "fact" | "preference" | "instruction" | "backstory" | "episode" | "session";
3
3
  type ImportanceLevel = "low" | "normal" | "high" | "critical";
4
4
  type ContextFormat = "markdown" | "plain" | "xml";
5
+ type MnemocyteBackend = "in-memory" | "postgres";
6
+ type MnemocyteOperation = "remember" | "rememberMany" | "recall" | "buildContext" | "forget" | "forgetAll" | "stats" | "close";
7
+ type MnemocyteObservationPhase = "start" | "success" | "error";
8
+ interface MnemocyteObservation {
9
+ operation: MnemocyteOperation;
10
+ phase: MnemocyteObservationPhase;
11
+ backend: MnemocyteBackend;
12
+ timestamp: Date;
13
+ durationMs?: number;
14
+ entityId?: string;
15
+ memoryId?: string;
16
+ count?: number;
17
+ error?: unknown;
18
+ }
19
+ interface ObservabilityConfig {
20
+ onEvent?: (event: MnemocyteObservation) => void | Promise<void>;
21
+ }
5
22
  interface MnemocyteConfig {
6
23
  databaseUrl?: string;
7
24
  embedder: Embedder;
@@ -10,6 +27,7 @@ interface MnemocyteConfig {
10
27
  minScore?: number;
11
28
  };
12
29
  retrieval?: RetrievalConfig;
30
+ observability?: ObservabilityConfig;
13
31
  }
14
32
  interface Embedder {
15
33
  readonly model: string;
@@ -155,6 +173,7 @@ declare class MnemocyteError extends Error {
155
173
  readonly cause?: unknown;
156
174
  constructor(message: string, code: MnemocyteErrorCode, cause?: unknown);
157
175
  }
176
+ declare function isMnemocyteError(error: unknown): error is MnemocyteError;
158
177
  //#endregion
159
- export { type ContextFormat, type Embedder, type EntityStats, type GlobalStats, type ImportanceLevel, type Memory, type MemoryType, type MemoryWithScore, type MnemocyteClient, type MnemocyteConfig, MnemocyteError, type MnemocyteErrorCode, type RecallInput, type RememberInput, type RetrievalExplanation, type RetrievalScores, createMnemocyte };
178
+ export { type BuildContextInput, type ContextFormat, type Embedder, type EntityStats, type GlobalStats, type ImportanceLevel, type Memory, type MemoryType, type MemoryWithScore, type MnemocyteBackend, type MnemocyteClient, type MnemocyteConfig, MnemocyteError, type MnemocyteErrorCode, type MnemocyteObservation, type MnemocyteObservationPhase, type MnemocyteOperation, type ObservabilityConfig, type RecallInput, type RememberInput, type RetrievalConfig, type RetrievalExplanation, type RetrievalScoreWeights, type RetrievalScores, type TokenCounter, createMnemocyte, isMnemocyteError };
160
179
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/client.ts","../src/errors.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/client.ts","../src/errors.ts"],"mappings":"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"}
package/dist/index.mjs CHANGED
@@ -163,6 +163,59 @@ var MnemocyteError = class extends Error {
163
163
  this.cause = cause;
164
164
  }
165
165
  };
166
+ function isMnemocyteError(error) {
167
+ return error instanceof MnemocyteError;
168
+ }
169
+ //#endregion
170
+ //#region src/observability.ts
171
+ function withMetadata(event, metadata) {
172
+ return {
173
+ ...event,
174
+ ...metadata.entityId === void 0 ? {} : { entityId: metadata.entityId },
175
+ ...metadata.memoryId === void 0 ? {} : { memoryId: metadata.memoryId },
176
+ ...metadata.count === void 0 ? {} : { count: metadata.count }
177
+ };
178
+ }
179
+ async function emitObservation(config, event) {
180
+ try {
181
+ await config.observability?.onEvent?.(event);
182
+ } catch {
183
+ return;
184
+ }
185
+ }
186
+ async function observe(config, backend, operation, metadata, action, successMetadata) {
187
+ const startedAt = Date.now();
188
+ await emitObservation(config, withMetadata({
189
+ operation,
190
+ phase: "start",
191
+ backend,
192
+ timestamp: new Date(startedAt)
193
+ }, metadata));
194
+ try {
195
+ const result = await action();
196
+ await emitObservation(config, withMetadata({
197
+ operation,
198
+ phase: "success",
199
+ backend,
200
+ timestamp: /* @__PURE__ */ new Date(),
201
+ durationMs: Date.now() - startedAt
202
+ }, {
203
+ ...metadata,
204
+ ...successMetadata?.(result)
205
+ }));
206
+ return result;
207
+ } catch (error) {
208
+ await emitObservation(config, withMetadata({
209
+ operation,
210
+ phase: "error",
211
+ backend,
212
+ timestamp: /* @__PURE__ */ new Date(),
213
+ durationMs: Date.now() - startedAt,
214
+ error
215
+ }, metadata));
216
+ throw error;
217
+ }
218
+ }
166
219
  function assertNonEmptyString(value, field) {
167
220
  if (value.trim().length === 0) throw new MnemocyteError(`${field} must be a non-empty string.`, "VALIDATION");
168
221
  }
@@ -371,107 +424,134 @@ function createInMemoryClient(config) {
371
424
  if (closed) throw new MnemocyteError("Mnemocyte client is closed.", "DB");
372
425
  }
373
426
  async function remember(input) {
374
- assertOpen();
375
- validateRememberInput(input);
376
- const embedding = await embedOne(config.embedder, input.content);
377
- const now = /* @__PURE__ */ new Date();
378
- const memory = {
379
- id: createId(),
380
- entityId: input.entityId,
381
- content: input.content,
382
- type: input.type ?? "fact",
383
- importance: input.importance ?? "normal",
384
- tags: normalizeTags(input.tags),
385
- source: input.source ?? null,
386
- metadata: input.metadata ?? {},
387
- confidence: input.confidence ?? 1,
388
- embeddingModel: config.embedder.model,
389
- embeddingDimensions: config.embedder.dimensions,
390
- supersededBy: null,
391
- expiresAt: input.expiresAt ?? null,
392
- lastAccessedAt: null,
393
- accessCount: 0,
394
- createdAt: now,
395
- updatedAt: now,
396
- embedding
397
- };
398
- memories.set(memory.id, memory);
399
- return cloneMemory(memory);
427
+ return observe(config, "in-memory", "remember", { entityId: input.entityId }, async () => {
428
+ assertOpen();
429
+ validateRememberInput(input);
430
+ const embedding = await embedOne(config.embedder, input.content);
431
+ const now = /* @__PURE__ */ new Date();
432
+ const memory = {
433
+ id: createId(),
434
+ entityId: input.entityId,
435
+ content: input.content,
436
+ type: input.type ?? "fact",
437
+ importance: input.importance ?? "normal",
438
+ tags: normalizeTags(input.tags),
439
+ source: input.source ?? null,
440
+ metadata: input.metadata ?? {},
441
+ confidence: input.confidence ?? 1,
442
+ embeddingModel: config.embedder.model,
443
+ embeddingDimensions: config.embedder.dimensions,
444
+ supersededBy: null,
445
+ expiresAt: input.expiresAt ?? null,
446
+ lastAccessedAt: null,
447
+ accessCount: 0,
448
+ createdAt: now,
449
+ updatedAt: now,
450
+ embedding
451
+ };
452
+ memories.set(memory.id, memory);
453
+ return cloneMemory(memory);
454
+ }, (memory) => ({
455
+ memoryId: memory.id,
456
+ count: 1
457
+ }));
400
458
  }
401
459
  return {
402
460
  remember,
403
461
  async rememberMany(inputs) {
404
- assertOpen();
405
- const result = [];
406
- for (const input of inputs) result.push(await remember(input));
407
- return result;
462
+ return observe(config, "in-memory", "rememberMany", { count: inputs.length }, async () => {
463
+ assertOpen();
464
+ const result = [];
465
+ for (const input of inputs) result.push(await remember(input));
466
+ return result;
467
+ }, (result) => ({ count: result.length }));
408
468
  },
409
469
  async recall(input) {
410
- assertOpen();
411
- validateRecallInput(input);
412
- const limit = input.limit ?? config.defaults?.limit ?? 10;
413
- const minScore = input.minScore ?? config.defaults?.minScore ?? 0;
414
- assertLimit(limit);
415
- assertMinScore(minScore);
416
- const queryEmbedding = await embedOne(config.embedder, input.query);
417
- const now = /* @__PURE__ */ new Date();
418
- const scored = Array.from(memories.values()).filter((memory) => matchesRecallFilter(memory, input, now)).map((memory) => toScoredMemory(memory, Math.max(0, cosineSimilarity(memory.embedding, queryEmbedding)), lexicalScore(memory.content, input.query), input)).filter((memory) => memory.score >= minScore).sort((a, b) => b.score - a.score).slice(0, limit);
419
- for (const memory of scored) {
420
- const stored = memories.get(memory.id);
421
- if (stored) {
422
- stored.lastAccessedAt = now;
423
- stored.accessCount += 1;
424
- stored.updatedAt = now;
470
+ return observe(config, "in-memory", "recall", { entityId: input.entityId }, async () => {
471
+ assertOpen();
472
+ validateRecallInput(input);
473
+ const limit = input.limit ?? config.defaults?.limit ?? 10;
474
+ const minScore = input.minScore ?? config.defaults?.minScore ?? 0;
475
+ assertLimit(limit);
476
+ assertMinScore(minScore);
477
+ const queryEmbedding = await embedOne(config.embedder, input.query);
478
+ const now = /* @__PURE__ */ new Date();
479
+ const scored = Array.from(memories.values()).filter((memory) => matchesRecallFilter(memory, input, now)).map((memory) => toScoredMemory(memory, Math.max(0, cosineSimilarity(memory.embedding, queryEmbedding)), lexicalScore(memory.content, input.query), input, config.retrieval)).filter((memory) => memory.score >= minScore).sort((a, b) => b.score - a.score).slice(0, limit);
480
+ for (const memory of scored) {
481
+ const stored = memories.get(memory.id);
482
+ if (stored) {
483
+ stored.lastAccessedAt = now;
484
+ stored.accessCount += 1;
485
+ stored.updatedAt = now;
486
+ }
425
487
  }
426
- }
427
- return scored;
488
+ return scored;
489
+ }, (result) => ({ count: result.length }));
428
490
  },
429
491
  async buildContext(input) {
430
- assertOpen();
431
- return buildContext({
432
- input,
433
- recall: (contextInput) => this.recall(contextInputToRecallInput(contextInput))
492
+ return observe(config, "in-memory", "buildContext", { entityId: input.entityId }, async () => {
493
+ assertOpen();
494
+ return buildContext({
495
+ input,
496
+ recall: (contextInput) => this.recall(contextInputToRecallInput(contextInput))
497
+ });
434
498
  });
435
499
  },
436
500
  async forget(input) {
437
- assertOpen();
438
- assertNonEmptyString(input.entityId, "entityId");
439
- assertNonEmptyString(input.memoryId, "memoryId");
440
- const memory = memories.get(input.memoryId);
441
- if (!memory || memory.entityId !== input.entityId) throw new MnemocyteError("Memory was not found.", "NOT_FOUND");
442
- memories.delete(input.memoryId);
501
+ return observe(config, "in-memory", "forget", {
502
+ entityId: input.entityId,
503
+ memoryId: input.memoryId
504
+ }, async () => {
505
+ assertOpen();
506
+ assertNonEmptyString(input.entityId, "entityId");
507
+ assertNonEmptyString(input.memoryId, "memoryId");
508
+ const memory = memories.get(input.memoryId);
509
+ if (!memory || memory.entityId !== input.entityId) throw new MnemocyteError("Memory was not found.", "NOT_FOUND");
510
+ memories.delete(input.memoryId);
511
+ });
443
512
  },
444
513
  async forgetAll(input) {
445
- assertOpen();
446
- assertNonEmptyString(input.entityId, "entityId");
447
- for (const [id, memory] of memories) if (memory.entityId === input.entityId) memories.delete(id);
514
+ return observe(config, "in-memory", "forgetAll", { entityId: input.entityId }, async () => {
515
+ assertOpen();
516
+ assertNonEmptyString(input.entityId, "entityId");
517
+ let deleted = 0;
518
+ for (const [id, memory] of memories) if (memory.entityId === input.entityId) {
519
+ memories.delete(id);
520
+ deleted += 1;
521
+ }
522
+ return deleted;
523
+ }, (count) => ({ count })).then(() => void 0);
448
524
  },
449
525
  async stats(input) {
450
- assertOpen();
451
- const now = /* @__PURE__ */ new Date();
452
- const allMemories = Array.from(memories.values());
453
- const selected = input?.entityId ? allMemories.filter((memory) => memory.entityId === input.entityId) : allMemories;
454
- const activeMemoryCount = selected.filter((memory) => !isExpired(memory, now) && memory.supersededBy === null).length;
455
- const expiredMemoryCount = selected.filter((memory) => isExpired(memory, now)).length;
456
- const supersededMemoryCount = selected.filter((memory) => memory.supersededBy !== null).length;
457
- if (input?.entityId) return {
458
- entityId: input.entityId,
459
- memoryCount: selected.length,
460
- activeMemoryCount,
461
- expiredMemoryCount,
462
- supersededMemoryCount
463
- };
464
- return {
465
- entityCount: new Set(allMemories.map((memory) => memory.entityId)).size,
466
- memoryCount: selected.length,
467
- activeMemoryCount,
468
- expiredMemoryCount,
469
- supersededMemoryCount
470
- };
526
+ return observe(config, "in-memory", "stats", input?.entityId ? { entityId: input.entityId } : {}, async () => {
527
+ assertOpen();
528
+ const now = /* @__PURE__ */ new Date();
529
+ const allMemories = Array.from(memories.values());
530
+ const selected = input?.entityId ? allMemories.filter((memory) => memory.entityId === input.entityId) : allMemories;
531
+ const activeMemoryCount = selected.filter((memory) => !isExpired(memory, now) && memory.supersededBy === null).length;
532
+ const expiredMemoryCount = selected.filter((memory) => isExpired(memory, now)).length;
533
+ const supersededMemoryCount = selected.filter((memory) => memory.supersededBy !== null).length;
534
+ if (input?.entityId) return {
535
+ entityId: input.entityId,
536
+ memoryCount: selected.length,
537
+ activeMemoryCount,
538
+ expiredMemoryCount,
539
+ supersededMemoryCount
540
+ };
541
+ return {
542
+ entityCount: new Set(allMemories.map((memory) => memory.entityId)).size,
543
+ memoryCount: selected.length,
544
+ activeMemoryCount,
545
+ expiredMemoryCount,
546
+ supersededMemoryCount
547
+ };
548
+ });
471
549
  },
472
550
  async close() {
473
- closed = true;
474
- memories.clear();
551
+ return observe(config, "in-memory", "close", {}, async () => {
552
+ closed = true;
553
+ memories.clear();
554
+ });
475
555
  }
476
556
  };
477
557
  }
@@ -629,103 +709,125 @@ function createPostgresClient(config, handle) {
629
709
  if (closed) throw new MnemocyteError("Mnemocyte client is closed.", "DB");
630
710
  }
631
711
  async function remember(input) {
632
- assertOpen();
633
- validateRememberInput(input);
634
- const embedding = await embedOne(config.embedder, input.content);
635
- const now = /* @__PURE__ */ new Date();
636
- return rowToMemory(await insertMemory(handle.db, {
637
- id: createId(),
638
- entityId: input.entityId,
639
- content: input.content,
640
- type: input.type ?? "fact",
641
- importance: input.importance ?? "normal",
642
- tags: normalizeTags(input.tags),
643
- source: input.source ?? null,
644
- metadata: input.metadata ?? {},
645
- confidence: input.confidence ?? 1,
646
- embedding,
647
- embeddingModel: config.embedder.model,
648
- embeddingDimensions: config.embedder.dimensions,
649
- supersededBy: null,
650
- supersededAt: null,
651
- expiresAt: input.expiresAt ?? null,
652
- lastAccessedAt: null,
653
- accessCount: 0,
654
- createdAt: now,
655
- updatedAt: now
712
+ return observe(config, "postgres", "remember", { entityId: input.entityId }, async () => {
713
+ assertOpen();
714
+ validateRememberInput(input);
715
+ const embedding = await embedOne(config.embedder, input.content);
716
+ const now = /* @__PURE__ */ new Date();
717
+ return rowToMemory(await insertMemory(handle.db, {
718
+ id: createId(),
719
+ entityId: input.entityId,
720
+ content: input.content,
721
+ type: input.type ?? "fact",
722
+ importance: input.importance ?? "normal",
723
+ tags: normalizeTags(input.tags),
724
+ source: input.source ?? null,
725
+ metadata: input.metadata ?? {},
726
+ confidence: input.confidence ?? 1,
727
+ embedding,
728
+ embeddingModel: config.embedder.model,
729
+ embeddingDimensions: config.embedder.dimensions,
730
+ supersededBy: null,
731
+ supersededAt: null,
732
+ expiresAt: input.expiresAt ?? null,
733
+ lastAccessedAt: null,
734
+ accessCount: 0,
735
+ createdAt: now,
736
+ updatedAt: now
737
+ }));
738
+ }, (memory) => ({
739
+ memoryId: memory.id,
740
+ count: 1
656
741
  }));
657
742
  }
658
743
  return {
659
744
  remember,
660
745
  async rememberMany(inputs) {
661
- assertOpen();
662
- const result = [];
663
- for (const input of inputs) result.push(await remember(input));
664
- return result;
746
+ return observe(config, "postgres", "rememberMany", { count: inputs.length }, async () => {
747
+ assertOpen();
748
+ const result = [];
749
+ for (const input of inputs) result.push(await remember(input));
750
+ return result;
751
+ }, (result) => ({ count: result.length }));
665
752
  },
666
753
  async recall(input) {
667
- assertOpen();
668
- validateRecallInput(input);
669
- const limit = input.limit ?? config.defaults?.limit ?? 10;
670
- const minScore = input.minScore ?? config.defaults?.minScore ?? 0;
671
- assertLimit(limit);
672
- assertMinScore(minScore);
673
- return hybridRecall({
674
- db: handle.db,
675
- embedder: config.embedder,
676
- input,
677
- limit,
678
- minScore,
679
- retrieval: config.retrieval
680
- });
754
+ return observe(config, "postgres", "recall", { entityId: input.entityId }, async () => {
755
+ assertOpen();
756
+ validateRecallInput(input);
757
+ const limit = input.limit ?? config.defaults?.limit ?? 10;
758
+ const minScore = input.minScore ?? config.defaults?.minScore ?? 0;
759
+ assertLimit(limit);
760
+ assertMinScore(minScore);
761
+ return hybridRecall({
762
+ db: handle.db,
763
+ embedder: config.embedder,
764
+ input,
765
+ limit,
766
+ minScore,
767
+ retrieval: config.retrieval
768
+ });
769
+ }, (result) => ({ count: result.length }));
681
770
  },
682
771
  async buildContext(input) {
683
- assertOpen();
684
- return buildContext({
685
- input,
686
- recall: (contextInput) => this.recall(contextInputToRecallInput(contextInput))
772
+ return observe(config, "postgres", "buildContext", { entityId: input.entityId }, async () => {
773
+ assertOpen();
774
+ return buildContext({
775
+ input,
776
+ recall: (contextInput) => this.recall(contextInputToRecallInput(contextInput))
777
+ });
687
778
  });
688
779
  },
689
780
  async forget(input) {
690
- assertOpen();
691
- assertNonEmptyString(input.entityId, "entityId");
692
- assertNonEmptyString(input.memoryId, "memoryId");
693
- if (!await deleteMemory(handle.db, input.entityId, input.memoryId)) throw new MnemocyteError("Memory was not found.", "NOT_FOUND");
781
+ return observe(config, "postgres", "forget", {
782
+ entityId: input.entityId,
783
+ memoryId: input.memoryId
784
+ }, async () => {
785
+ assertOpen();
786
+ assertNonEmptyString(input.entityId, "entityId");
787
+ assertNonEmptyString(input.memoryId, "memoryId");
788
+ if (!await deleteMemory(handle.db, input.entityId, input.memoryId)) throw new MnemocyteError("Memory was not found.", "NOT_FOUND");
789
+ });
694
790
  },
695
791
  async forgetAll(input) {
696
- assertOpen();
697
- assertNonEmptyString(input.entityId, "entityId");
698
- await Promise.all([deleteMemoriesForEntity(handle.db, input.entityId), deleteEventsForEntity(handle.db, input.entityId)]);
792
+ return observe(config, "postgres", "forgetAll", { entityId: input.entityId }, async () => {
793
+ assertOpen();
794
+ assertNonEmptyString(input.entityId, "entityId");
795
+ await Promise.all([deleteMemoriesForEntity(handle.db, input.entityId), deleteEventsForEntity(handle.db, input.entityId)]);
796
+ });
699
797
  },
700
798
  async stats(input) {
701
- assertOpen();
702
- const now = /* @__PURE__ */ new Date();
703
- if (input?.entityId) {
704
- const selected = await listMemories(handle.db, {
705
- entityId: input.entityId,
706
- includeExpired: true,
707
- includeSuperseded: true
708
- });
799
+ return observe(config, "postgres", "stats", input?.entityId ? { entityId: input.entityId } : {}, async () => {
800
+ assertOpen();
801
+ const now = /* @__PURE__ */ new Date();
802
+ if (input?.entityId) {
803
+ const selected = await listMemories(handle.db, {
804
+ entityId: input.entityId,
805
+ includeExpired: true,
806
+ includeSuperseded: true
807
+ });
808
+ return {
809
+ entityId: input.entityId,
810
+ memoryCount: selected.length,
811
+ activeMemoryCount: selected.filter((memory) => !isExpired(rowToMemory(memory), now) && memory.supersededBy === null).length,
812
+ expiredMemoryCount: selected.filter((memory) => isExpired(rowToMemory(memory), now)).length,
813
+ supersededMemoryCount: selected.filter((memory) => memory.supersededBy !== null).length
814
+ };
815
+ }
816
+ const allMemories = await handle.db.select().from(memoriesTable);
709
817
  return {
710
- entityId: input.entityId,
711
- memoryCount: selected.length,
712
- activeMemoryCount: selected.filter((memory) => !isExpired(rowToMemory(memory), now) && memory.supersededBy === null).length,
713
- expiredMemoryCount: selected.filter((memory) => isExpired(rowToMemory(memory), now)).length,
714
- supersededMemoryCount: selected.filter((memory) => memory.supersededBy !== null).length
818
+ entityCount: new Set(allMemories.map((memory) => memory.entityId)).size,
819
+ memoryCount: allMemories.length,
820
+ activeMemoryCount: allMemories.filter((memory) => !isExpired(rowToMemory(memory), now) && memory.supersededBy === null).length,
821
+ expiredMemoryCount: allMemories.filter((memory) => isExpired(rowToMemory(memory), now)).length,
822
+ supersededMemoryCount: allMemories.filter((memory) => memory.supersededBy !== null).length
715
823
  };
716
- }
717
- const allMemories = await handle.db.select().from(memoriesTable);
718
- return {
719
- entityCount: new Set(allMemories.map((memory) => memory.entityId)).size,
720
- memoryCount: allMemories.length,
721
- activeMemoryCount: allMemories.filter((memory) => !isExpired(rowToMemory(memory), now) && memory.supersededBy === null).length,
722
- expiredMemoryCount: allMemories.filter((memory) => isExpired(rowToMemory(memory), now)).length,
723
- supersededMemoryCount: allMemories.filter((memory) => memory.supersededBy !== null).length
724
- };
824
+ });
725
825
  },
726
826
  async close() {
727
- closed = true;
728
- await handle.close();
827
+ return observe(config, "postgres", "close", {}, async () => {
828
+ closed = true;
829
+ await handle.close();
830
+ });
729
831
  }
730
832
  };
731
833
  }
@@ -740,6 +842,6 @@ function createMnemocyte(config) {
740
842
  return createInMemoryClient(config);
741
843
  }
742
844
  //#endregion
743
- export { MnemocyteError, createMnemocyte };
845
+ export { MnemocyteError, createMnemocyte, isMnemocyteError };
744
846
 
745
847
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/db/schema.ts","../src/db/index.ts","../src/context/formatter.ts","../src/context/tokens.ts","../src/context/builder.ts","../src/errors.ts","../src/memory/shared.ts","../src/retrieval/scorer.ts","../src/memory/in-memory.ts","../src/db/queries/events.ts","../src/db/queries/memories.ts","../src/retrieval/index.ts","../src/memory/postgres.ts","../src/client.ts"],"sourcesContent":["import { sql } from \"drizzle-orm\";\nimport {\n\tcustomType,\n\tindex,\n\tinteger,\n\tjsonb,\n\tpgTable,\n\treal,\n\ttext,\n\ttimestamp,\n} from \"drizzle-orm/pg-core\";\n\nconst vector = customType<{ data: number[]; driverData: string }>({\n\tdataType(config) {\n\t\tconst dimensions = typeof config === \"number\" ? config : 1536;\n\t\treturn `vector(${dimensions})`;\n\t},\n\ttoDriver(value) {\n\t\treturn `[${value.join(\",\")}]`;\n\t},\n\tfromDriver(value) {\n\t\treturn value.slice(1, -1).split(\",\").filter(Boolean).map(Number);\n\t},\n});\n\nexport const memoriesTable = pgTable(\n\t\"mnemocyte_memories\",\n\t{\n\t\tid: text(\"id\").primaryKey(),\n\t\tentityId: text(\"entity_id\").notNull(),\n\t\tcontent: text(\"content\").notNull(),\n\t\ttype: text(\"type\").notNull().default(\"fact\"),\n\t\timportance: text(\"importance\").notNull().default(\"normal\"),\n\t\ttags: text(\"tags\").array().notNull().default(sql`'{}'::text[]`),\n\t\tsource: text(\"source\"),\n\t\tmetadata: jsonb(\"metadata\").notNull().default({}),\n\t\tconfidence: real(\"confidence\").notNull().default(1),\n\t\tembedding: vector(\"embedding\", { dimensions: 1536 }),\n\t\tembeddingModel: text(\"embedding_model\").notNull(),\n\t\tembeddingDimensions: integer(\"embedding_dimensions\").notNull(),\n\t\tsupersededBy: text(\"superseded_by\"),\n\t\tsupersededAt: timestamp(\"superseded_at\", { withTimezone: true }),\n\t\texpiresAt: timestamp(\"expires_at\", { withTimezone: true }),\n\t\tlastAccessedAt: timestamp(\"last_accessed_at\", { withTimezone: true }),\n\t\taccessCount: integer(\"access_count\").notNull().default(0),\n\t\tcreatedAt: timestamp(\"created_at\", { withTimezone: true })\n\t\t\t.notNull()\n\t\t\t.defaultNow(),\n\t\tupdatedAt: timestamp(\"updated_at\", { withTimezone: true })\n\t\t\t.notNull()\n\t\t\t.defaultNow(),\n\t},\n\t(table) => [\n\t\tindex(\"mnemocyte_memories_entity_idx\").on(table.entityId),\n\t\tindex(\"mnemocyte_memories_entity_type_idx\").on(table.entityId, table.type),\n\t],\n);\n\nexport const eventsTable = pgTable(\n\t\"mnemocyte_events\",\n\t{\n\t\tid: text(\"id\").primaryKey(),\n\t\tentityId: text(\"entity_id\").notNull(),\n\t\tdescription: text(\"description\").notNull(),\n\t\tmetadata: jsonb(\"metadata\").notNull().default({}),\n\t\ttimestamp: timestamp(\"timestamp\", { withTimezone: true })\n\t\t\t.notNull()\n\t\t\t.defaultNow(),\n\t},\n\t(table) => [\n\t\tindex(\"mnemocyte_events_entity_time_idx\").on(\n\t\t\ttable.entityId,\n\t\t\ttable.timestamp,\n\t\t),\n\t],\n);\n\nexport type MemoryRow = typeof memoriesTable.$inferSelect;\nexport type NewMemoryRow = typeof memoriesTable.$inferInsert;\nexport type EventRow = typeof eventsTable.$inferSelect;\nexport type NewEventRow = typeof eventsTable.$inferInsert;\n","import { drizzle, type PostgresJsDatabase } from \"drizzle-orm/postgres-js\";\nimport postgres, { type Sql } from \"postgres\";\nimport * as schema from \"./schema.js\";\n\nexport type MnemocyteDatabase = PostgresJsDatabase<typeof schema>;\n\nexport interface DatabaseHandle {\n\tdb: MnemocyteDatabase;\n\tclose(): Promise<void>;\n}\n\nexport function createDatabase(databaseUrl: string): DatabaseHandle {\n\tconst client = postgres(databaseUrl, {\n\t\tmax: 10,\n\t\tidle_timeout: 20,\n\t\tconnect_timeout: 10,\n\t});\n\n\treturn {\n\t\tdb: drizzle(client, { schema }),\n\t\tasync close() {\n\t\t\tawait client.end();\n\t\t},\n\t};\n}\n\nexport function useDatabase(client: Sql): DatabaseHandle {\n\treturn {\n\t\tdb: drizzle(client, { schema }),\n\t\tasync close() {},\n\t};\n}\n\nexport { schema };\n","import type { ContextFormat, MemoryWithScore } from \"../types.js\";\n\nfunction escapeXml(value: string): string {\n\treturn value\n\t\t.replaceAll(\"&\", \"&amp;\")\n\t\t.replaceAll(\"<\", \"&lt;\")\n\t\t.replaceAll(\">\", \"&gt;\")\n\t\t.replaceAll('\"', \"&quot;\")\n\t\t.replaceAll(\"'\", \"&apos;\");\n}\n\nfunction formatMetadata(memory: MemoryWithScore): string {\n\tconst parts = [\n\t\t`type=${memory.type}`,\n\t\t`importance=${memory.importance}`,\n\t\t`score=${memory.score.toFixed(3)}`,\n\t];\n\tif (memory.source) {\n\t\tparts.push(`source=${memory.source}`);\n\t}\n\tif (memory.tags.length > 0) {\n\t\tparts.push(`tags=${memory.tags.join(\",\")}`);\n\t}\n\treturn parts.join(\"; \");\n}\n\nfunction formatMarkdown(\n\tmemories: readonly MemoryWithScore[],\n\tquery: string,\n): string {\n\tconst lines = [\n\t\t\"# Memory Context\",\n\t\t\"\",\n\t\t`Query: ${query}`,\n\t\t\"\",\n\t\t\"## Relevant Memories\",\n\t];\n\tfor (const memory of memories) {\n\t\tlines.push(\"\", `- ${memory.content}`, ` - ${formatMetadata(memory)}`);\n\t}\n\treturn lines.join(\"\\n\");\n}\n\nfunction formatPlain(\n\tmemories: readonly MemoryWithScore[],\n\tquery: string,\n): string {\n\tconst lines = [\n\t\t\"MEMORY CONTEXT\",\n\t\t\"\",\n\t\t`QUERY: ${query}`,\n\t\t\"\",\n\t\t\"RELEVANT MEMORIES\",\n\t];\n\tfor (const memory of memories) {\n\t\tlines.push(\"\", memory.content, formatMetadata(memory));\n\t}\n\treturn lines.join(\"\\n\");\n}\n\nfunction formatXml(\n\tmemories: readonly MemoryWithScore[],\n\tquery: string,\n): string {\n\tconst lines = [`<memory_context query=\"${escapeXml(query)}\">`];\n\tfor (const memory of memories) {\n\t\tlines.push(\n\t\t\t` <memory id=\"${escapeXml(memory.id)}\" type=\"${escapeXml(memory.type)}\" importance=\"${escapeXml(memory.importance)}\" score=\"${memory.score.toFixed(3)}\">`,\n\t\t\t` <content>${escapeXml(memory.content)}</content>`,\n\t\t\t` <metadata>${escapeXml(formatMetadata(memory))}</metadata>`,\n\t\t\t\" </memory>\",\n\t\t);\n\t}\n\tlines.push(\"</memory_context>\");\n\treturn lines.join(\"\\n\");\n}\n\nexport function formatContext(\n\tmemories: readonly MemoryWithScore[],\n\tquery: string,\n\tformat: ContextFormat,\n): string {\n\tswitch (format) {\n\t\tcase \"markdown\":\n\t\t\treturn formatMarkdown(memories, query);\n\t\tcase \"plain\":\n\t\t\treturn formatPlain(memories, query);\n\t\tcase \"xml\":\n\t\t\treturn formatXml(memories, query);\n\t}\n}\n","import type { TokenCounter } from \"../types.js\";\n\nexport const heuristicTokenCounter: TokenCounter = {\n\tcount(text) {\n\t\treturn Math.ceil(text.length / 4);\n\t},\n};\n\nexport function trimToTokenBudget(\n\ttext: string,\n\tmaxTokens: number,\n\ttokenCounter: TokenCounter,\n): string {\n\tif (maxTokens < 1 || tokenCounter.count(text) <= maxTokens) {\n\t\treturn text;\n\t}\n\tlet low = 0;\n\tlet high = text.length;\n\tlet best = \"\";\n\twhile (low <= high) {\n\t\tconst mid = Math.floor((low + high) / 2);\n\t\tconst candidate = text.slice(0, mid).trimEnd();\n\t\tconst output = `${candidate}\\n[truncated to fit token budget]`;\n\t\tif (tokenCounter.count(output) <= maxTokens) {\n\t\t\tbest = output;\n\t\t\tlow = mid + 1;\n\t\t} else {\n\t\t\thigh = mid - 1;\n\t\t}\n\t}\n\treturn best || \"[truncated to fit token budget]\";\n}\n","import type { BuildContextInput, MemoryWithScore } from \"../types.js\";\nimport { formatContext } from \"./formatter.js\";\nimport { heuristicTokenCounter, trimToTokenBudget } from \"./tokens.js\";\n\nexport interface BuildContextOptions {\n\tinput: BuildContextInput;\n\trecall(input: BuildContextInput): Promise<MemoryWithScore[]>;\n}\n\nexport async function buildContext(\n\toptions: BuildContextOptions,\n): Promise<string> {\n\tconst format = options.input.format ?? \"markdown\";\n\tconst maxTokens = options.input.maxTokens ?? 1200;\n\tconst tokenCounter = options.input.tokenCounter ?? heuristicTokenCounter;\n\tconst memories = await options.recall(options.input);\n\tconst context = formatContext(memories, options.input.query, format);\n\treturn trimToTokenBudget(context, maxTokens, tokenCounter);\n}\n","export type MnemocyteErrorCode =\n\t| \"CONFIG\"\n\t| \"VALIDATION\"\n\t| \"DB\"\n\t| \"EMBEDDING\"\n\t| \"NOT_FOUND\"\n\t| \"MIGRATION\";\n\nexport class MnemocyteError extends Error {\n\treadonly code: MnemocyteErrorCode;\n\toverride readonly cause?: unknown;\n\n\tconstructor(message: string, code: MnemocyteErrorCode, cause?: unknown) {\n\t\tsuper(message);\n\t\tthis.name = \"MnemocyteError\";\n\t\tthis.code = code;\n\t\tthis.cause = cause;\n\t}\n}\n","import type { MemoryRow } from \"../db/schema.js\";\nimport { MnemocyteError } from \"../errors.js\";\nimport type {\n\tBuildContextInput,\n\tEmbedder,\n\tImportanceLevel,\n\tMemory,\n\tMemoryType,\n\tRecallInput,\n\tRememberInput,\n} from \"../types.js\";\n\nexport const DEFAULT_LIMIT = 10;\nexport const DEFAULT_MIN_SCORE = 0;\nexport const DEFAULT_TYPE: MemoryType = \"fact\";\nexport const DEFAULT_IMPORTANCE: ImportanceLevel = \"normal\";\n\nexport interface StoredMemory extends Memory {\n\tembedding: number[];\n}\n\nexport function assertNonEmptyString(value: string, field: string): void {\n\tif (value.trim().length === 0) {\n\t\tthrow new MnemocyteError(\n\t\t\t`${field} must be a non-empty string.`,\n\t\t\t\"VALIDATION\",\n\t\t);\n\t}\n}\n\nexport function assertLimit(value: number): void {\n\tif (!Number.isInteger(value) || value < 1) {\n\t\tthrow new MnemocyteError(\"limit must be a positive integer.\", \"VALIDATION\");\n\t}\n}\n\nexport function assertMinScore(value: number): void {\n\tif (!Number.isFinite(value) || value < 0 || value > 1) {\n\t\tthrow new MnemocyteError(\n\t\t\t\"minScore must be a number between 0 and 1.\",\n\t\t\t\"VALIDATION\",\n\t\t);\n\t}\n}\n\nexport function assertEmbedder(embedder: Embedder): void {\n\tif (!embedder || typeof embedder.embed !== \"function\") {\n\t\tthrow new MnemocyteError(\n\t\t\t\"embedder with an embed function is required.\",\n\t\t\t\"CONFIG\",\n\t\t);\n\t}\n\tassertNonEmptyString(embedder.model, \"embedder.model\");\n\tif (!Number.isInteger(embedder.dimensions) || embedder.dimensions < 1) {\n\t\tthrow new MnemocyteError(\n\t\t\t\"embedder.dimensions must be a positive integer.\",\n\t\t\t\"CONFIG\",\n\t\t);\n\t}\n}\n\nexport function normalizeTags(tags: readonly string[] | undefined): string[] {\n\tif (!tags) {\n\t\treturn [];\n\t}\n\treturn [...new Set(tags.map((tag) => tag.trim()).filter(Boolean))];\n}\n\nexport function createId(): string {\n\treturn `mem_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;\n}\n\nexport function isExpired(memory: Memory, now: Date): boolean {\n\treturn (\n\t\tmemory.expiresAt !== null && memory.expiresAt.getTime() <= now.getTime()\n\t);\n}\n\nexport function cloneMemory(memory: Memory): Memory {\n\treturn {\n\t\t...memory,\n\t\ttags: [...memory.tags],\n\t\tmetadata: { ...memory.metadata },\n\t\texpiresAt: memory.expiresAt ? new Date(memory.expiresAt) : null,\n\t\tlastAccessedAt: memory.lastAccessedAt\n\t\t\t? new Date(memory.lastAccessedAt)\n\t\t\t: null,\n\t\tcreatedAt: new Date(memory.createdAt),\n\t\tupdatedAt: new Date(memory.updatedAt),\n\t};\n}\n\nexport function rowToMemory(row: MemoryRow): Memory {\n\treturn {\n\t\tid: row.id,\n\t\tentityId: row.entityId,\n\t\tcontent: row.content,\n\t\ttype: row.type as MemoryType,\n\t\timportance: row.importance as ImportanceLevel,\n\t\ttags: row.tags,\n\t\tsource: row.source,\n\t\tmetadata: row.metadata as Record<string, unknown>,\n\t\tconfidence: row.confidence,\n\t\tembeddingModel: row.embeddingModel,\n\t\tembeddingDimensions: row.embeddingDimensions,\n\t\tsupersededBy: row.supersededBy,\n\t\texpiresAt: row.expiresAt,\n\t\tlastAccessedAt: row.lastAccessedAt,\n\t\taccessCount: row.accessCount,\n\t\tcreatedAt: row.createdAt,\n\t\tupdatedAt: row.updatedAt,\n\t};\n}\n\nexport async function embedOne(\n\tembedder: Embedder,\n\ttext: string,\n): Promise<number[]> {\n\tlet embeddings: number[][];\n\ttry {\n\t\tembeddings = await embedder.embed([text]);\n\t} catch (error) {\n\t\tthrow new MnemocyteError(\"Failed to embed text.\", \"EMBEDDING\", error);\n\t}\n\tconst embedding = embeddings[0];\n\tif (!embedding) {\n\t\tthrow new MnemocyteError(\"Embedder returned no embedding.\", \"EMBEDDING\");\n\t}\n\tif (embedding.length !== embedder.dimensions) {\n\t\tthrow new MnemocyteError(\n\t\t\t\"Embedder returned an embedding with unexpected dimensions.\",\n\t\t\t\"EMBEDDING\",\n\t\t);\n\t}\n\treturn embedding;\n}\n\nexport function validateRememberInput(input: RememberInput): void {\n\tassertNonEmptyString(input.entityId, \"entityId\");\n\tassertNonEmptyString(input.content, \"content\");\n\tif (\n\t\tinput.confidence !== undefined &&\n\t\t(!Number.isFinite(input.confidence) ||\n\t\t\tinput.confidence < 0 ||\n\t\t\tinput.confidence > 1)\n\t) {\n\t\tthrow new MnemocyteError(\n\t\t\t\"confidence must be a number between 0 and 1.\",\n\t\t\t\"VALIDATION\",\n\t\t);\n\t}\n}\n\nexport function validateRecallInput(input: RecallInput): void {\n\tassertNonEmptyString(input.entityId, \"entityId\");\n\tassertNonEmptyString(input.query, \"query\");\n\tif (input.limit !== undefined) {\n\t\tassertLimit(input.limit);\n\t}\n\tif (input.minScore !== undefined) {\n\t\tassertMinScore(input.minScore);\n\t}\n}\n\nexport function contextInputToRecallInput(\n\tinput: BuildContextInput,\n): RecallInput {\n\treturn {\n\t\tentityId: input.entityId,\n\t\tquery: input.query,\n\t\t...(input.limit === undefined ? {} : { limit: input.limit }),\n\t\t...(input.minScore === undefined ? {} : { minScore: input.minScore }),\n\t\t...(input.types === undefined ? {} : { types: input.types }),\n\t\t...(input.tags === undefined ? {} : { tags: input.tags }),\n\t\t...(input.includeSuperseded === undefined\n\t\t\t? {}\n\t\t\t: { includeSuperseded: input.includeSuperseded }),\n\t\t...(input.includeExpired === undefined\n\t\t\t? {}\n\t\t\t: { includeExpired: input.includeExpired }),\n\t};\n}\n\nexport function matchesRecallFilter(\n\tmemory: Memory,\n\tinput: RecallInput,\n\tnow: Date,\n): boolean {\n\tif (memory.entityId !== input.entityId) {\n\t\treturn false;\n\t}\n\tif (!input.includeSuperseded && memory.supersededBy !== null) {\n\t\treturn false;\n\t}\n\tif (!input.includeExpired && isExpired(memory, now)) {\n\t\treturn false;\n\t}\n\tif (input.types && !input.types.includes(memory.type)) {\n\t\treturn false;\n\t}\n\tif (input.tags && !input.tags.every((tag) => memory.tags.includes(tag))) {\n\t\treturn false;\n\t}\n\tif (input.before && memory.createdAt >= input.before) {\n\t\treturn false;\n\t}\n\tif (input.after && memory.createdAt <= input.after) {\n\t\treturn false;\n\t}\n\treturn true;\n}\n","import { cloneMemory } from \"../memory/shared.js\";\nimport type {\n\tImportanceLevel,\n\tMemory,\n\tMemoryWithScore,\n\tRecallInput,\n\tRetrievalConfig,\n\tRetrievalScoreWeights,\n} from \"../types.js\";\n\nconst IMPORTANCE_SCORES: Record<ImportanceLevel, number> = {\n\tlow: 0,\n\tnormal: 0.5,\n\thigh: 0.8,\n\tcritical: 1,\n};\n\nconst DEFAULT_WEIGHTS: Required<RetrievalScoreWeights> = {\n\tvector: 0.55,\n\tlexical: 0.2,\n\trecency: 0.1,\n\tconfidence: 0.05,\n\taccess: 0.05,\n\timportance: 0.05,\n};\n\nconst DEFAULT_RECENCY_HALF_LIFE_DAYS = 90;\nconst DEFAULT_ACCESS_SATURATION = 10;\nexport const DEFAULT_CANDIDATE_MULTIPLIER = 3;\n\nexport function cosineSimilarity(\n\ta: readonly number[],\n\tb: readonly number[],\n): number {\n\tlet dot = 0;\n\tlet aMagnitude = 0;\n\tlet bMagnitude = 0;\n\tfor (let i = 0; i < a.length; i += 1) {\n\t\tconst av = a[i] ?? 0;\n\t\tconst bv = b[i] ?? 0;\n\t\tdot += av * bv;\n\t\taMagnitude += av * av;\n\t\tbMagnitude += bv * bv;\n\t}\n\tif (aMagnitude === 0 || bMagnitude === 0) {\n\t\treturn 0;\n\t}\n\treturn dot / (Math.sqrt(aMagnitude) * Math.sqrt(bMagnitude));\n}\n\nexport function lexicalScore(content: string, query: string): number {\n\tconst terms = query.toLowerCase().split(/\\s+/).filter(Boolean);\n\tif (terms.length === 0) {\n\t\treturn 0;\n\t}\n\tconst lowerContent = content.toLowerCase();\n\tconst matches = terms.filter((term) => lowerContent.includes(term)).length;\n\treturn matches / terms.length;\n}\n\nfunction clampScore(value: number): number {\n\tif (!Number.isFinite(value)) {\n\t\treturn 0;\n\t}\n\treturn Math.max(0, Math.min(1, value));\n}\n\nfunction normalizeWeights(\n\tweights: RetrievalScoreWeights | undefined,\n): Required<RetrievalScoreWeights> {\n\tconst merged = { ...DEFAULT_WEIGHTS, ...weights };\n\tconst total =\n\t\tmerged.vector +\n\t\tmerged.lexical +\n\t\tmerged.recency +\n\t\tmerged.confidence +\n\t\tmerged.access +\n\t\tmerged.importance;\n\tif (total <= 0) {\n\t\treturn DEFAULT_WEIGHTS;\n\t}\n\treturn {\n\t\tvector: merged.vector / total,\n\t\tlexical: merged.lexical / total,\n\t\trecency: merged.recency / total,\n\t\tconfidence: merged.confidence / total,\n\t\taccess: merged.access / total,\n\t\timportance: merged.importance / total,\n\t};\n}\n\nfunction recencyScore(createdAt: Date, halfLifeDays: number): number {\n\tconst ageMs = Date.now() - createdAt.getTime();\n\tconst ageDays = Math.max(0, ageMs / 86_400_000);\n\treturn Math.exp((-Math.LN2 * ageDays) / halfLifeDays);\n}\n\nfunction accessScore(accessCount: number, saturation: number): number {\n\tif (accessCount <= 0) {\n\t\treturn 0;\n\t}\n\treturn Math.min(1, Math.log1p(accessCount) / Math.log1p(saturation));\n}\n\nexport function toScoredMemory(\n\tmemory: Memory,\n\tvector: number,\n\tlexical: number,\n\tinput: RecallInput,\n\tconfig?: RetrievalConfig,\n): MemoryWithScore {\n\tconst weights = normalizeWeights(config?.weights);\n\tconst recency = recencyScore(\n\t\tmemory.createdAt,\n\t\tconfig?.recencyHalfLifeDays ?? DEFAULT_RECENCY_HALF_LIFE_DAYS,\n\t);\n\tconst confidence = clampScore(memory.confidence);\n\tconst access = accessScore(\n\t\tmemory.accessCount,\n\t\tconfig?.accessSaturation ?? DEFAULT_ACCESS_SATURATION,\n\t);\n\tconst importance = IMPORTANCE_SCORES[memory.importance];\n\tconst score = Math.max(\n\t\t0,\n\t\tMath.min(\n\t\t\t1,\n\t\t\tclampScore(vector) * weights.vector +\n\t\t\t\tclampScore(lexical) * weights.lexical +\n\t\t\t\trecency * weights.recency +\n\t\t\t\tconfidence * weights.confidence +\n\t\t\t\taccess * weights.access +\n\t\t\t\timportance * weights.importance,\n\t\t),\n\t);\n\treturn {\n\t\t...cloneMemory(memory),\n\t\tscore,\n\t\tscores: {\n\t\t\tvector: clampScore(vector),\n\t\t\tlexical: clampScore(lexical),\n\t\t\trecency,\n\t\t\tconfidence,\n\t\t\taccess,\n\t\t\timportance,\n\t\t},\n\t\texplanation: input.explain\n\t\t\t? {\n\t\t\t\t\tvectorScore: clampScore(vector),\n\t\t\t\t\tlexicalScore: clampScore(lexical),\n\t\t\t\t\trecencyScore: recency,\n\t\t\t\t\tconfidenceScore: confidence,\n\t\t\t\t\taccessScore: access,\n\t\t\t\t\timportanceScore: importance,\n\t\t\t\t\timportanceBoost: importance * weights.importance,\n\t\t\t\t\tweights,\n\t\t\t\t\tfinalScore: score,\n\t\t\t\t}\n\t\t\t: null,\n\t};\n}\n","import { buildContext } from \"../context/builder.js\";\nimport { MnemocyteError } from \"../errors.js\";\nimport {\n\tcosineSimilarity,\n\tlexicalScore,\n\ttoScoredMemory,\n} from \"../retrieval/scorer.js\";\nimport type {\n\tEntityStats,\n\tGlobalStats,\n\tMemory,\n\tMnemocyteClient,\n\tMnemocyteConfig,\n\tRememberInput,\n} from \"../types.js\";\nimport {\n\tassertLimit,\n\tassertMinScore,\n\tassertNonEmptyString,\n\tcloneMemory,\n\tcontextInputToRecallInput,\n\tcreateId,\n\tDEFAULT_IMPORTANCE,\n\tDEFAULT_LIMIT,\n\tDEFAULT_MIN_SCORE,\n\tDEFAULT_TYPE,\n\tembedOne,\n\tisExpired,\n\tmatchesRecallFilter,\n\tnormalizeTags,\n\ttype StoredMemory,\n\tvalidateRecallInput,\n\tvalidateRememberInput,\n} from \"./shared.js\";\n\nexport function createInMemoryClient(config: MnemocyteConfig): MnemocyteClient {\n\tconst memories = new Map<string, StoredMemory>();\n\tlet closed = false;\n\n\tfunction assertOpen(): void {\n\t\tif (closed) {\n\t\t\tthrow new MnemocyteError(\"Mnemocyte client is closed.\", \"DB\");\n\t\t}\n\t}\n\n\tasync function remember(input: RememberInput): Promise<Memory> {\n\t\tassertOpen();\n\t\tvalidateRememberInput(input);\n\t\tconst embedding = await embedOne(config.embedder, input.content);\n\t\tconst now = new Date();\n\t\tconst memory: StoredMemory = {\n\t\t\tid: createId(),\n\t\t\tentityId: input.entityId,\n\t\t\tcontent: input.content,\n\t\t\ttype: input.type ?? DEFAULT_TYPE,\n\t\t\timportance: input.importance ?? DEFAULT_IMPORTANCE,\n\t\t\ttags: normalizeTags(input.tags),\n\t\t\tsource: input.source ?? null,\n\t\t\tmetadata: input.metadata ?? {},\n\t\t\tconfidence: input.confidence ?? 1,\n\t\t\tembeddingModel: config.embedder.model,\n\t\t\tembeddingDimensions: config.embedder.dimensions,\n\t\t\tsupersededBy: null,\n\t\t\texpiresAt: input.expiresAt ?? null,\n\t\t\tlastAccessedAt: null,\n\t\t\taccessCount: 0,\n\t\t\tcreatedAt: now,\n\t\t\tupdatedAt: now,\n\t\t\tembedding,\n\t\t};\n\t\tmemories.set(memory.id, memory);\n\t\treturn cloneMemory(memory);\n\t}\n\n\treturn {\n\t\tremember,\n\t\tasync rememberMany(inputs) {\n\t\t\tassertOpen();\n\t\t\tconst result: Memory[] = [];\n\t\t\tfor (const input of inputs) {\n\t\t\t\tresult.push(await remember(input));\n\t\t\t}\n\t\t\treturn result;\n\t\t},\n\t\tasync recall(input) {\n\t\t\tassertOpen();\n\t\t\tvalidateRecallInput(input);\n\t\t\tconst limit = input.limit ?? config.defaults?.limit ?? DEFAULT_LIMIT;\n\t\t\tconst minScore =\n\t\t\t\tinput.minScore ?? config.defaults?.minScore ?? DEFAULT_MIN_SCORE;\n\t\t\tassertLimit(limit);\n\t\t\tassertMinScore(minScore);\n\t\t\tconst queryEmbedding = await embedOne(config.embedder, input.query);\n\t\t\tconst now = new Date();\n\t\t\tconst scored = Array.from(memories.values())\n\t\t\t\t.filter((memory) => matchesRecallFilter(memory, input, now))\n\t\t\t\t.map((memory) =>\n\t\t\t\t\ttoScoredMemory(\n\t\t\t\t\t\tmemory,\n\t\t\t\t\t\tMath.max(0, cosineSimilarity(memory.embedding, queryEmbedding)),\n\t\t\t\t\t\tlexicalScore(memory.content, input.query),\n\t\t\t\t\t\tinput,\n\t\t\t\t\t),\n\t\t\t\t)\n\t\t\t\t.filter((memory) => memory.score >= minScore)\n\t\t\t\t.sort((a, b) => b.score - a.score)\n\t\t\t\t.slice(0, limit);\n\t\t\tfor (const memory of scored) {\n\t\t\t\tconst stored = memories.get(memory.id);\n\t\t\t\tif (stored) {\n\t\t\t\t\tstored.lastAccessedAt = now;\n\t\t\t\t\tstored.accessCount += 1;\n\t\t\t\t\tstored.updatedAt = now;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn scored;\n\t\t},\n\t\tasync buildContext(input) {\n\t\t\tassertOpen();\n\t\t\treturn buildContext({\n\t\t\t\tinput,\n\t\t\t\trecall: (contextInput) =>\n\t\t\t\t\tthis.recall(contextInputToRecallInput(contextInput)),\n\t\t\t});\n\t\t},\n\t\tasync forget(input) {\n\t\t\tassertOpen();\n\t\t\tassertNonEmptyString(input.entityId, \"entityId\");\n\t\t\tassertNonEmptyString(input.memoryId, \"memoryId\");\n\t\t\tconst memory = memories.get(input.memoryId);\n\t\t\tif (!memory || memory.entityId !== input.entityId) {\n\t\t\t\tthrow new MnemocyteError(\"Memory was not found.\", \"NOT_FOUND\");\n\t\t\t}\n\t\t\tmemories.delete(input.memoryId);\n\t\t},\n\t\tasync forgetAll(input) {\n\t\t\tassertOpen();\n\t\t\tassertNonEmptyString(input.entityId, \"entityId\");\n\t\t\tfor (const [id, memory] of memories) {\n\t\t\t\tif (memory.entityId === input.entityId) {\n\t\t\t\t\tmemories.delete(id);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tasync stats(input) {\n\t\t\tassertOpen();\n\t\t\tconst now = new Date();\n\t\t\tconst allMemories = Array.from(memories.values());\n\t\t\tconst selected = input?.entityId\n\t\t\t\t? allMemories.filter((memory) => memory.entityId === input.entityId)\n\t\t\t\t: allMemories;\n\t\t\tconst activeMemoryCount = selected.filter(\n\t\t\t\t(memory) => !isExpired(memory, now) && memory.supersededBy === null,\n\t\t\t).length;\n\t\t\tconst expiredMemoryCount = selected.filter((memory) =>\n\t\t\t\tisExpired(memory, now),\n\t\t\t).length;\n\t\t\tconst supersededMemoryCount = selected.filter(\n\t\t\t\t(memory) => memory.supersededBy !== null,\n\t\t\t).length;\n\t\t\tif (input?.entityId) {\n\t\t\t\treturn {\n\t\t\t\t\tentityId: input.entityId,\n\t\t\t\t\tmemoryCount: selected.length,\n\t\t\t\t\tactiveMemoryCount,\n\t\t\t\t\texpiredMemoryCount,\n\t\t\t\t\tsupersededMemoryCount,\n\t\t\t\t} satisfies EntityStats;\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tentityCount: new Set(allMemories.map((memory) => memory.entityId)).size,\n\t\t\t\tmemoryCount: selected.length,\n\t\t\t\tactiveMemoryCount,\n\t\t\t\texpiredMemoryCount,\n\t\t\t\tsupersededMemoryCount,\n\t\t\t} satisfies GlobalStats;\n\t\t},\n\t\tasync close() {\n\t\t\tclosed = true;\n\t\t\tmemories.clear();\n\t\t},\n\t};\n}\n","import { and, desc, eq, gt, lt } from \"drizzle-orm\";\nimport type { MnemocyteDatabase } from \"../index.js\";\nimport { type EventRow, eventsTable, type NewEventRow } from \"../schema.js\";\n\nexport interface EventFilter {\n\tentityId: string;\n\tlimit?: number;\n\tbefore?: Date;\n\tafter?: Date;\n}\n\nexport async function insertEvent(\n\tdb: MnemocyteDatabase,\n\trow: NewEventRow,\n): Promise<EventRow> {\n\tconst result = await db.insert(eventsTable).values(row).returning();\n\tconst inserted = result[0];\n\tif (!inserted) {\n\t\tthrow new Error(\"Event insert returned no rows.\");\n\t}\n\treturn inserted;\n}\n\nexport async function listEvents(\n\tdb: MnemocyteDatabase,\n\tfilter: EventFilter,\n): Promise<EventRow[]> {\n\treturn db\n\t\t.select()\n\t\t.from(eventsTable)\n\t\t.where(\n\t\t\tand(\n\t\t\t\teq(eventsTable.entityId, filter.entityId),\n\t\t\t\tfilter.before ? lt(eventsTable.timestamp, filter.before) : undefined,\n\t\t\t\tfilter.after ? gt(eventsTable.timestamp, filter.after) : undefined,\n\t\t\t),\n\t\t)\n\t\t.orderBy(desc(eventsTable.timestamp))\n\t\t.limit(filter.limit ?? 50);\n}\n\nexport async function deleteEventsForEntity(\n\tdb: MnemocyteDatabase,\n\tentityId: string,\n): Promise<number> {\n\tconst result = await db\n\t\t.delete(eventsTable)\n\t\t.where(eq(eventsTable.entityId, entityId))\n\t\t.returning({ id: eventsTable.id });\n\treturn result.length;\n}\n","import { and, eq, gt, inArray, isNull, lt, sql } from \"drizzle-orm\";\nimport type { MemoryType } from \"../../types.js\";\nimport type { MnemocyteDatabase } from \"../index.js\";\nimport { type MemoryRow, memoriesTable, type NewMemoryRow } from \"../schema.js\";\n\nexport interface MemoryFilter {\n\tentityId: string;\n\ttypes?: readonly MemoryType[];\n\ttags?: readonly string[];\n\tbefore?: Date;\n\tafter?: Date;\n\tincludeSuperseded?: boolean;\n\tincludeExpired?: boolean;\n}\n\nexport interface VectorSearchInput extends MemoryFilter {\n\tembedding: readonly number[];\n\tlimit: number;\n\tminScore?: number;\n}\n\nexport interface LexicalSearchInput extends MemoryFilter {\n\tquery: string;\n\tlimit: number;\n}\n\nfunction vectorLiteral(embedding: readonly number[]): string {\n\treturn `[${embedding.join(\",\")}]`;\n}\n\nfunction filterConditions(filter: MemoryFilter) {\n\treturn and(\n\t\teq(memoriesTable.entityId, filter.entityId),\n\t\tfilter.includeSuperseded ? undefined : isNull(memoriesTable.supersededBy),\n\t\tfilter.includeExpired\n\t\t\t? undefined\n\t\t\t: sql`(${memoriesTable.expiresAt} IS NULL OR ${memoriesTable.expiresAt} > now())`,\n\t\tfilter.types && filter.types.length > 0\n\t\t\t? inArray(memoriesTable.type, [...filter.types])\n\t\t\t: undefined,\n\t\tfilter.tags && filter.tags.length > 0\n\t\t\t? sql`${memoriesTable.tags} && ${filter.tags}`\n\t\t\t: undefined,\n\t\tfilter.before ? lt(memoriesTable.createdAt, filter.before) : undefined,\n\t\tfilter.after ? gt(memoriesTable.createdAt, filter.after) : undefined,\n\t);\n}\n\nexport async function insertMemory(\n\tdb: MnemocyteDatabase,\n\trow: NewMemoryRow,\n): Promise<MemoryRow> {\n\tconst result = await db.insert(memoriesTable).values(row).returning();\n\tconst inserted = result[0];\n\tif (!inserted) {\n\t\tthrow new Error(\"Memory insert returned no rows.\");\n\t}\n\treturn inserted;\n}\n\nexport async function getMemoryById(\n\tdb: MnemocyteDatabase,\n\tentityId: string,\n\tmemoryId: string,\n): Promise<MemoryRow | null> {\n\tconst result = await db\n\t\t.select()\n\t\t.from(memoriesTable)\n\t\t.where(\n\t\t\tand(eq(memoriesTable.entityId, entityId), eq(memoriesTable.id, memoryId)),\n\t\t)\n\t\t.limit(1);\n\treturn result[0] ?? null;\n}\n\nexport async function listMemories(\n\tdb: MnemocyteDatabase,\n\tfilter: MemoryFilter,\n): Promise<MemoryRow[]> {\n\treturn db.select().from(memoriesTable).where(filterConditions(filter));\n}\n\nexport async function deleteMemory(\n\tdb: MnemocyteDatabase,\n\tentityId: string,\n\tmemoryId: string,\n): Promise<boolean> {\n\tconst result = await db\n\t\t.delete(memoriesTable)\n\t\t.where(\n\t\t\tand(eq(memoriesTable.entityId, entityId), eq(memoriesTable.id, memoryId)),\n\t\t)\n\t\t.returning({ id: memoriesTable.id });\n\treturn result.length > 0;\n}\n\nexport async function deleteMemoriesForEntity(\n\tdb: MnemocyteDatabase,\n\tentityId: string,\n): Promise<number> {\n\tconst result = await db\n\t\t.delete(memoriesTable)\n\t\t.where(eq(memoriesTable.entityId, entityId))\n\t\t.returning({ id: memoriesTable.id });\n\treturn result.length;\n}\n\nexport async function markMemoryAccessed(\n\tdb: MnemocyteDatabase,\n\tmemoryIds: readonly string[],\n): Promise<void> {\n\tif (memoryIds.length === 0) {\n\t\treturn;\n\t}\n\tawait db\n\t\t.update(memoriesTable)\n\t\t.set({\n\t\t\tlastAccessedAt: new Date(),\n\t\t\taccessCount: sql`${memoriesTable.accessCount} + 1`,\n\t\t\tupdatedAt: new Date(),\n\t\t})\n\t\t.where(inArray(memoriesTable.id, [...memoryIds]));\n}\n\nexport async function vectorSearch(\n\tdb: MnemocyteDatabase,\n\tinput: VectorSearchInput,\n): Promise<Array<MemoryRow & { vectorScore: number }>> {\n\tconst embedding = vectorLiteral(input.embedding);\n\tconst minScore = input.minScore ?? 0;\n\tconst rows = await db.execute(sql`\n\t\tSELECT\n\t\t\tid,\n\t\t\tentity_id AS \"entityId\",\n\t\t\tcontent,\n\t\t\ttype,\n\t\t\timportance,\n\t\t\ttags,\n\t\t\tsource,\n\t\t\tmetadata,\n\t\t\tconfidence,\n\t\t\tembedding,\n\t\t\tembedding_model AS \"embeddingModel\",\n\t\t\tembedding_dimensions AS \"embeddingDimensions\",\n\t\t\tsuperseded_by AS \"supersededBy\",\n\t\t\tsuperseded_at AS \"supersededAt\",\n\t\t\texpires_at AS \"expiresAt\",\n\t\t\tlast_accessed_at AS \"lastAccessedAt\",\n\t\t\taccess_count AS \"accessCount\",\n\t\t\tcreated_at AS \"createdAt\",\n\t\t\tupdated_at AS \"updatedAt\",\n\t\t\t1 - (embedding <=> ${embedding}::vector) AS \"vectorScore\"\n\t\tFROM mnemocyte_memories\n\t\tWHERE\n\t\t\tentity_id = ${input.entityId}\n\t\t\tAND embedding IS NOT NULL\n\t\t\t${input.includeSuperseded ? sql`` : sql`AND superseded_by IS NULL`}\n\t\t\t${input.includeExpired ? sql`` : sql`AND (expires_at IS NULL OR expires_at > now())`}\n\t\t\t${\n\t\t\t\tinput.types && input.types.length > 0\n\t\t\t\t\t? sql`AND type IN (${sql.join(\n\t\t\t\t\t\t\tinput.types.map((type) => sql`${type}`),\n\t\t\t\t\t\t\tsql`, `,\n\t\t\t\t\t\t)})`\n\t\t\t\t\t: sql``\n\t\t\t}\n\t\t\t${input.tags && input.tags.length > 0 ? sql`AND tags && ${input.tags}` : sql``}\n\t\t\t${input.before ? sql`AND created_at < ${input.before}` : sql``}\n\t\t\t${input.after ? sql`AND created_at > ${input.after}` : sql``}\n\t\t\tAND 1 - (embedding <=> ${embedding}::vector) >= ${minScore}\n\t\tORDER BY embedding <=> ${embedding}::vector\n\t\tLIMIT ${input.limit}\n\t`);\n\treturn rows as unknown as Array<MemoryRow & { vectorScore: number }>;\n}\n\nexport async function lexicalSearch(\n\tdb: MnemocyteDatabase,\n\tinput: LexicalSearchInput,\n): Promise<Array<MemoryRow & { lexicalScore: number }>> {\n\tconst rows = await db.execute(sql`\n\t\tSELECT\n\t\t\tid,\n\t\t\tentity_id AS \"entityId\",\n\t\t\tcontent,\n\t\t\ttype,\n\t\t\timportance,\n\t\t\ttags,\n\t\t\tsource,\n\t\t\tmetadata,\n\t\t\tconfidence,\n\t\t\tembedding,\n\t\t\tembedding_model AS \"embeddingModel\",\n\t\t\tembedding_dimensions AS \"embeddingDimensions\",\n\t\t\tsuperseded_by AS \"supersededBy\",\n\t\t\tsuperseded_at AS \"supersededAt\",\n\t\t\texpires_at AS \"expiresAt\",\n\t\t\tlast_accessed_at AS \"lastAccessedAt\",\n\t\t\taccess_count AS \"accessCount\",\n\t\t\tcreated_at AS \"createdAt\",\n\t\t\tupdated_at AS \"updatedAt\",\n\t\t\tts_rank(to_tsvector('english', content), websearch_to_tsquery('english', ${input.query})) AS \"lexicalScore\"\n\t\tFROM mnemocyte_memories\n\t\tWHERE\n\t\t\tentity_id = ${input.entityId}\n\t\t\t${input.includeSuperseded ? sql`` : sql`AND superseded_by IS NULL`}\n\t\t\t${input.includeExpired ? sql`` : sql`AND (expires_at IS NULL OR expires_at > now())`}\n\t\t\t${\n\t\t\t\tinput.types && input.types.length > 0\n\t\t\t\t\t? sql`AND type IN (${sql.join(\n\t\t\t\t\t\t\tinput.types.map((type) => sql`${type}`),\n\t\t\t\t\t\t\tsql`, `,\n\t\t\t\t\t\t)})`\n\t\t\t\t\t: sql``\n\t\t\t}\n\t\t\t${input.tags && input.tags.length > 0 ? sql`AND tags && ${input.tags}` : sql``}\n\t\t\t${input.before ? sql`AND created_at < ${input.before}` : sql``}\n\t\t\t${input.after ? sql`AND created_at > ${input.after}` : sql``}\n\t\t\tAND to_tsvector('english', content) @@ websearch_to_tsquery('english', ${input.query})\n\t\tORDER BY \"lexicalScore\" DESC\n\t\tLIMIT ${input.limit}\n\t`);\n\treturn rows as unknown as Array<MemoryRow & { lexicalScore: number }>;\n}\n","import type { MnemocyteDatabase } from \"../db/index.js\";\nimport {\n\tlexicalSearch,\n\tmarkMemoryAccessed,\n\tvectorSearch,\n} from \"../db/queries/memories.js\";\nimport type { MemoryRow } from \"../db/schema.js\";\nimport { embedOne, rowToMemory } from \"../memory/shared.js\";\nimport type {\n\tEmbedder,\n\tMemoryWithScore,\n\tRecallInput,\n\tRetrievalConfig,\n} from \"../types.js\";\nimport { DEFAULT_CANDIDATE_MULTIPLIER, toScoredMemory } from \"./scorer.js\";\n\ninterface HybridRecallInput {\n\tdb: MnemocyteDatabase;\n\tembedder: Embedder;\n\tinput: RecallInput;\n\tlimit: number;\n\tminScore: number;\n\tretrieval: RetrievalConfig | undefined;\n}\n\ninterface ScoredRow {\n\trow: MemoryRow;\n\tvectorScore: number;\n\tlexicalScore: number;\n}\n\nexport async function hybridRecall(\n\tinput: HybridRecallInput,\n): Promise<MemoryWithScore[]> {\n\tconst queryEmbedding = await embedOne(input.embedder, input.input.query);\n\tconst candidateMultiplier =\n\t\tinput.retrieval?.candidateMultiplier ?? DEFAULT_CANDIDATE_MULTIPLIER;\n\tconst candidateLimit = Math.max(\n\t\tinput.limit,\n\t\tinput.limit * candidateMultiplier,\n\t);\n\tconst [vectorRows, lexicalRows] = await Promise.all([\n\t\tvectorSearch(input.db, {\n\t\t\t...input.input,\n\t\t\tembedding: queryEmbedding,\n\t\t\tlimit: candidateLimit,\n\t\t\tminScore: 0,\n\t\t}),\n\t\tlexicalSearch(input.db, { ...input.input, limit: candidateLimit }),\n\t]);\n\tconst merged = new Map<string, ScoredRow>();\n\tfor (const row of vectorRows) {\n\t\tmerged.set(row.id, {\n\t\t\trow,\n\t\t\tvectorScore: row.vectorScore,\n\t\t\tlexicalScore: 0,\n\t\t});\n\t}\n\tfor (const row of lexicalRows) {\n\t\tconst existing = merged.get(row.id);\n\t\tif (existing) {\n\t\t\texisting.lexicalScore = row.lexicalScore;\n\t\t} else {\n\t\t\tmerged.set(row.id, {\n\t\t\t\trow,\n\t\t\t\tvectorScore: 0,\n\t\t\t\tlexicalScore: row.lexicalScore,\n\t\t\t});\n\t\t}\n\t}\n\tconst scored = Array.from(merged.values())\n\t\t.map((entry) =>\n\t\t\ttoScoredMemory(\n\t\t\t\trowToMemory(entry.row),\n\t\t\t\tMath.max(0, entry.vectorScore),\n\t\t\t\tMath.max(0, entry.lexicalScore),\n\t\t\t\tinput.input,\n\t\t\t\tinput.retrieval,\n\t\t\t),\n\t\t)\n\t\t.filter((memory) => memory.score >= input.minScore)\n\t\t.sort((a, b) => b.score - a.score)\n\t\t.slice(0, input.limit);\n\tawait markMemoryAccessed(\n\t\tinput.db,\n\t\tscored.map((memory) => memory.id),\n\t);\n\treturn scored;\n}\n","import { buildContext } from \"../context/builder.js\";\nimport type { DatabaseHandle } from \"../db/index.js\";\nimport { deleteEventsForEntity } from \"../db/queries/events.js\";\nimport {\n\tdeleteMemoriesForEntity,\n\tdeleteMemory,\n\tinsertMemory,\n\tlistMemories,\n} from \"../db/queries/memories.js\";\nimport { memoriesTable } from \"../db/schema.js\";\nimport { MnemocyteError } from \"../errors.js\";\nimport { hybridRecall } from \"../retrieval/index.js\";\nimport type {\n\tEntityStats,\n\tGlobalStats,\n\tMemory,\n\tMnemocyteClient,\n\tMnemocyteConfig,\n\tRememberInput,\n} from \"../types.js\";\nimport {\n\tassertLimit,\n\tassertMinScore,\n\tassertNonEmptyString,\n\tcontextInputToRecallInput,\n\tcreateId,\n\tDEFAULT_IMPORTANCE,\n\tDEFAULT_LIMIT,\n\tDEFAULT_MIN_SCORE,\n\tDEFAULT_TYPE,\n\tembedOne,\n\tisExpired,\n\tnormalizeTags,\n\trowToMemory,\n\tvalidateRecallInput,\n\tvalidateRememberInput,\n} from \"./shared.js\";\n\nexport function createPostgresClient(\n\tconfig: MnemocyteConfig,\n\thandle: DatabaseHandle,\n): MnemocyteClient {\n\tlet closed = false;\n\n\tfunction assertOpen(): void {\n\t\tif (closed) {\n\t\t\tthrow new MnemocyteError(\"Mnemocyte client is closed.\", \"DB\");\n\t\t}\n\t}\n\n\tasync function remember(input: RememberInput): Promise<Memory> {\n\t\tassertOpen();\n\t\tvalidateRememberInput(input);\n\t\tconst embedding = await embedOne(config.embedder, input.content);\n\t\tconst now = new Date();\n\t\tconst row = await insertMemory(handle.db, {\n\t\t\tid: createId(),\n\t\t\tentityId: input.entityId,\n\t\t\tcontent: input.content,\n\t\t\ttype: input.type ?? DEFAULT_TYPE,\n\t\t\timportance: input.importance ?? DEFAULT_IMPORTANCE,\n\t\t\ttags: normalizeTags(input.tags),\n\t\t\tsource: input.source ?? null,\n\t\t\tmetadata: input.metadata ?? {},\n\t\t\tconfidence: input.confidence ?? 1,\n\t\t\tembedding,\n\t\t\tembeddingModel: config.embedder.model,\n\t\t\tembeddingDimensions: config.embedder.dimensions,\n\t\t\tsupersededBy: null,\n\t\t\tsupersededAt: null,\n\t\t\texpiresAt: input.expiresAt ?? null,\n\t\t\tlastAccessedAt: null,\n\t\t\taccessCount: 0,\n\t\t\tcreatedAt: now,\n\t\t\tupdatedAt: now,\n\t\t});\n\t\treturn rowToMemory(row);\n\t}\n\n\treturn {\n\t\tremember,\n\t\tasync rememberMany(inputs) {\n\t\t\tassertOpen();\n\t\t\tconst result: Memory[] = [];\n\t\t\tfor (const input of inputs) {\n\t\t\t\tresult.push(await remember(input));\n\t\t\t}\n\t\t\treturn result;\n\t\t},\n\t\tasync recall(input) {\n\t\t\tassertOpen();\n\t\t\tvalidateRecallInput(input);\n\t\t\tconst limit = input.limit ?? config.defaults?.limit ?? DEFAULT_LIMIT;\n\t\t\tconst minScore =\n\t\t\t\tinput.minScore ?? config.defaults?.minScore ?? DEFAULT_MIN_SCORE;\n\t\t\tassertLimit(limit);\n\t\t\tassertMinScore(minScore);\n\t\t\treturn hybridRecall({\n\t\t\t\tdb: handle.db,\n\t\t\t\tembedder: config.embedder,\n\t\t\t\tinput,\n\t\t\t\tlimit,\n\t\t\t\tminScore,\n\t\t\t\tretrieval: config.retrieval,\n\t\t\t});\n\t\t},\n\t\tasync buildContext(input) {\n\t\t\tassertOpen();\n\t\t\treturn buildContext({\n\t\t\t\tinput,\n\t\t\t\trecall: (contextInput) =>\n\t\t\t\t\tthis.recall(contextInputToRecallInput(contextInput)),\n\t\t\t});\n\t\t},\n\t\tasync forget(input) {\n\t\t\tassertOpen();\n\t\t\tassertNonEmptyString(input.entityId, \"entityId\");\n\t\t\tassertNonEmptyString(input.memoryId, \"memoryId\");\n\t\t\tconst deleted = await deleteMemory(\n\t\t\t\thandle.db,\n\t\t\t\tinput.entityId,\n\t\t\t\tinput.memoryId,\n\t\t\t);\n\t\t\tif (!deleted) {\n\t\t\t\tthrow new MnemocyteError(\"Memory was not found.\", \"NOT_FOUND\");\n\t\t\t}\n\t\t},\n\t\tasync forgetAll(input) {\n\t\t\tassertOpen();\n\t\t\tassertNonEmptyString(input.entityId, \"entityId\");\n\t\t\tawait Promise.all([\n\t\t\t\tdeleteMemoriesForEntity(handle.db, input.entityId),\n\t\t\t\tdeleteEventsForEntity(handle.db, input.entityId),\n\t\t\t]);\n\t\t},\n\t\tasync stats(input) {\n\t\t\tassertOpen();\n\t\t\tconst now = new Date();\n\t\t\tif (input?.entityId) {\n\t\t\t\tconst selected = await listMemories(handle.db, {\n\t\t\t\t\tentityId: input.entityId,\n\t\t\t\t\tincludeExpired: true,\n\t\t\t\t\tincludeSuperseded: true,\n\t\t\t\t});\n\t\t\t\treturn {\n\t\t\t\t\tentityId: input.entityId,\n\t\t\t\t\tmemoryCount: selected.length,\n\t\t\t\t\tactiveMemoryCount: selected.filter(\n\t\t\t\t\t\t(memory) =>\n\t\t\t\t\t\t\t!isExpired(rowToMemory(memory), now) &&\n\t\t\t\t\t\t\tmemory.supersededBy === null,\n\t\t\t\t\t).length,\n\t\t\t\t\texpiredMemoryCount: selected.filter((memory) =>\n\t\t\t\t\t\tisExpired(rowToMemory(memory), now),\n\t\t\t\t\t).length,\n\t\t\t\t\tsupersededMemoryCount: selected.filter(\n\t\t\t\t\t\t(memory) => memory.supersededBy !== null,\n\t\t\t\t\t).length,\n\t\t\t\t} satisfies EntityStats;\n\t\t\t}\n\t\t\tconst allMemories = await handle.db.select().from(memoriesTable);\n\t\t\treturn {\n\t\t\t\tentityCount: new Set(allMemories.map((memory) => memory.entityId)).size,\n\t\t\t\tmemoryCount: allMemories.length,\n\t\t\t\tactiveMemoryCount: allMemories.filter(\n\t\t\t\t\t(memory) =>\n\t\t\t\t\t\t!isExpired(rowToMemory(memory), now) &&\n\t\t\t\t\t\tmemory.supersededBy === null,\n\t\t\t\t).length,\n\t\t\t\texpiredMemoryCount: allMemories.filter((memory) =>\n\t\t\t\t\tisExpired(rowToMemory(memory), now),\n\t\t\t\t).length,\n\t\t\t\tsupersededMemoryCount: allMemories.filter(\n\t\t\t\t\t(memory) => memory.supersededBy !== null,\n\t\t\t\t).length,\n\t\t\t} satisfies GlobalStats;\n\t\t},\n\t\tasync close() {\n\t\t\tclosed = true;\n\t\t\tawait handle.close();\n\t\t},\n\t};\n}\n","import { createDatabase } from \"./db/index.js\";\nimport { createInMemoryClient } from \"./memory/in-memory.js\";\nimport { createPostgresClient } from \"./memory/postgres.js\";\nimport { assertEmbedder, assertNonEmptyString } from \"./memory/shared.js\";\nimport type { MnemocyteClient, MnemocyteConfig } from \"./types.js\";\n\nexport function createMnemocyte(config: MnemocyteConfig): MnemocyteClient {\n\tassertEmbedder(config.embedder);\n\tif (config.databaseUrl) {\n\t\tassertNonEmptyString(config.databaseUrl, \"databaseUrl\");\n\t\treturn createPostgresClient(config, createDatabase(config.databaseUrl));\n\t}\n\treturn createInMemoryClient(config);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/db/schema.ts","../src/db/index.ts","../src/context/formatter.ts","../src/context/tokens.ts","../src/context/builder.ts","../src/errors.ts","../src/observability.ts","../src/memory/shared.ts","../src/retrieval/scorer.ts","../src/memory/in-memory.ts","../src/db/queries/events.ts","../src/db/queries/memories.ts","../src/retrieval/index.ts","../src/memory/postgres.ts","../src/client.ts"],"sourcesContent":["import { sql } from \"drizzle-orm\";\nimport {\n\tcustomType,\n\tindex,\n\tinteger,\n\tjsonb,\n\tpgTable,\n\treal,\n\ttext,\n\ttimestamp,\n} from \"drizzle-orm/pg-core\";\n\nconst vector = customType<{ data: number[]; driverData: string }>({\n\tdataType(config) {\n\t\tconst dimensions = typeof config === \"number\" ? config : 1536;\n\t\treturn `vector(${dimensions})`;\n\t},\n\ttoDriver(value) {\n\t\treturn `[${value.join(\",\")}]`;\n\t},\n\tfromDriver(value) {\n\t\treturn value.slice(1, -1).split(\",\").filter(Boolean).map(Number);\n\t},\n});\n\nexport const memoriesTable = pgTable(\n\t\"mnemocyte_memories\",\n\t{\n\t\tid: text(\"id\").primaryKey(),\n\t\tentityId: text(\"entity_id\").notNull(),\n\t\tcontent: text(\"content\").notNull(),\n\t\ttype: text(\"type\").notNull().default(\"fact\"),\n\t\timportance: text(\"importance\").notNull().default(\"normal\"),\n\t\ttags: text(\"tags\").array().notNull().default(sql`'{}'::text[]`),\n\t\tsource: text(\"source\"),\n\t\tmetadata: jsonb(\"metadata\").notNull().default({}),\n\t\tconfidence: real(\"confidence\").notNull().default(1),\n\t\tembedding: vector(\"embedding\", { dimensions: 1536 }),\n\t\tembeddingModel: text(\"embedding_model\").notNull(),\n\t\tembeddingDimensions: integer(\"embedding_dimensions\").notNull(),\n\t\tsupersededBy: text(\"superseded_by\"),\n\t\tsupersededAt: timestamp(\"superseded_at\", { withTimezone: true }),\n\t\texpiresAt: timestamp(\"expires_at\", { withTimezone: true }),\n\t\tlastAccessedAt: timestamp(\"last_accessed_at\", { withTimezone: true }),\n\t\taccessCount: integer(\"access_count\").notNull().default(0),\n\t\tcreatedAt: timestamp(\"created_at\", { withTimezone: true })\n\t\t\t.notNull()\n\t\t\t.defaultNow(),\n\t\tupdatedAt: timestamp(\"updated_at\", { withTimezone: true })\n\t\t\t.notNull()\n\t\t\t.defaultNow(),\n\t},\n\t(table) => [\n\t\tindex(\"mnemocyte_memories_entity_idx\").on(table.entityId),\n\t\tindex(\"mnemocyte_memories_entity_type_idx\").on(table.entityId, table.type),\n\t],\n);\n\nexport const eventsTable = pgTable(\n\t\"mnemocyte_events\",\n\t{\n\t\tid: text(\"id\").primaryKey(),\n\t\tentityId: text(\"entity_id\").notNull(),\n\t\tdescription: text(\"description\").notNull(),\n\t\tmetadata: jsonb(\"metadata\").notNull().default({}),\n\t\ttimestamp: timestamp(\"timestamp\", { withTimezone: true })\n\t\t\t.notNull()\n\t\t\t.defaultNow(),\n\t},\n\t(table) => [\n\t\tindex(\"mnemocyte_events_entity_time_idx\").on(\n\t\t\ttable.entityId,\n\t\t\ttable.timestamp,\n\t\t),\n\t],\n);\n\nexport type MemoryRow = typeof memoriesTable.$inferSelect;\nexport type NewMemoryRow = typeof memoriesTable.$inferInsert;\nexport type EventRow = typeof eventsTable.$inferSelect;\nexport type NewEventRow = typeof eventsTable.$inferInsert;\n","import { drizzle, type PostgresJsDatabase } from \"drizzle-orm/postgres-js\";\nimport postgres, { type Sql } from \"postgres\";\nimport * as schema from \"./schema.js\";\n\nexport type MnemocyteDatabase = PostgresJsDatabase<typeof schema>;\n\nexport interface DatabaseHandle {\n\tdb: MnemocyteDatabase;\n\tclose(): Promise<void>;\n}\n\nexport function createDatabase(databaseUrl: string): DatabaseHandle {\n\tconst client = postgres(databaseUrl, {\n\t\tmax: 10,\n\t\tidle_timeout: 20,\n\t\tconnect_timeout: 10,\n\t});\n\n\treturn {\n\t\tdb: drizzle(client, { schema }),\n\t\tasync close() {\n\t\t\tawait client.end();\n\t\t},\n\t};\n}\n\nexport function useDatabase(client: Sql): DatabaseHandle {\n\treturn {\n\t\tdb: drizzle(client, { schema }),\n\t\tasync close() {},\n\t};\n}\n\nexport { schema };\n","import type { ContextFormat, MemoryWithScore } from \"../types.js\";\n\nfunction escapeXml(value: string): string {\n\treturn value\n\t\t.replaceAll(\"&\", \"&amp;\")\n\t\t.replaceAll(\"<\", \"&lt;\")\n\t\t.replaceAll(\">\", \"&gt;\")\n\t\t.replaceAll('\"', \"&quot;\")\n\t\t.replaceAll(\"'\", \"&apos;\");\n}\n\nfunction formatMetadata(memory: MemoryWithScore): string {\n\tconst parts = [\n\t\t`type=${memory.type}`,\n\t\t`importance=${memory.importance}`,\n\t\t`score=${memory.score.toFixed(3)}`,\n\t];\n\tif (memory.source) {\n\t\tparts.push(`source=${memory.source}`);\n\t}\n\tif (memory.tags.length > 0) {\n\t\tparts.push(`tags=${memory.tags.join(\",\")}`);\n\t}\n\treturn parts.join(\"; \");\n}\n\nfunction formatMarkdown(\n\tmemories: readonly MemoryWithScore[],\n\tquery: string,\n): string {\n\tconst lines = [\n\t\t\"# Memory Context\",\n\t\t\"\",\n\t\t`Query: ${query}`,\n\t\t\"\",\n\t\t\"## Relevant Memories\",\n\t];\n\tfor (const memory of memories) {\n\t\tlines.push(\"\", `- ${memory.content}`, ` - ${formatMetadata(memory)}`);\n\t}\n\treturn lines.join(\"\\n\");\n}\n\nfunction formatPlain(\n\tmemories: readonly MemoryWithScore[],\n\tquery: string,\n): string {\n\tconst lines = [\n\t\t\"MEMORY CONTEXT\",\n\t\t\"\",\n\t\t`QUERY: ${query}`,\n\t\t\"\",\n\t\t\"RELEVANT MEMORIES\",\n\t];\n\tfor (const memory of memories) {\n\t\tlines.push(\"\", memory.content, formatMetadata(memory));\n\t}\n\treturn lines.join(\"\\n\");\n}\n\nfunction formatXml(\n\tmemories: readonly MemoryWithScore[],\n\tquery: string,\n): string {\n\tconst lines = [`<memory_context query=\"${escapeXml(query)}\">`];\n\tfor (const memory of memories) {\n\t\tlines.push(\n\t\t\t` <memory id=\"${escapeXml(memory.id)}\" type=\"${escapeXml(memory.type)}\" importance=\"${escapeXml(memory.importance)}\" score=\"${memory.score.toFixed(3)}\">`,\n\t\t\t` <content>${escapeXml(memory.content)}</content>`,\n\t\t\t` <metadata>${escapeXml(formatMetadata(memory))}</metadata>`,\n\t\t\t\" </memory>\",\n\t\t);\n\t}\n\tlines.push(\"</memory_context>\");\n\treturn lines.join(\"\\n\");\n}\n\nexport function formatContext(\n\tmemories: readonly MemoryWithScore[],\n\tquery: string,\n\tformat: ContextFormat,\n): string {\n\tswitch (format) {\n\t\tcase \"markdown\":\n\t\t\treturn formatMarkdown(memories, query);\n\t\tcase \"plain\":\n\t\t\treturn formatPlain(memories, query);\n\t\tcase \"xml\":\n\t\t\treturn formatXml(memories, query);\n\t}\n}\n","import type { TokenCounter } from \"../types.js\";\n\nexport const heuristicTokenCounter: TokenCounter = {\n\tcount(text) {\n\t\treturn Math.ceil(text.length / 4);\n\t},\n};\n\nexport function trimToTokenBudget(\n\ttext: string,\n\tmaxTokens: number,\n\ttokenCounter: TokenCounter,\n): string {\n\tif (maxTokens < 1 || tokenCounter.count(text) <= maxTokens) {\n\t\treturn text;\n\t}\n\tlet low = 0;\n\tlet high = text.length;\n\tlet best = \"\";\n\twhile (low <= high) {\n\t\tconst mid = Math.floor((low + high) / 2);\n\t\tconst candidate = text.slice(0, mid).trimEnd();\n\t\tconst output = `${candidate}\\n[truncated to fit token budget]`;\n\t\tif (tokenCounter.count(output) <= maxTokens) {\n\t\t\tbest = output;\n\t\t\tlow = mid + 1;\n\t\t} else {\n\t\t\thigh = mid - 1;\n\t\t}\n\t}\n\treturn best || \"[truncated to fit token budget]\";\n}\n","import type { BuildContextInput, MemoryWithScore } from \"../types.js\";\nimport { formatContext } from \"./formatter.js\";\nimport { heuristicTokenCounter, trimToTokenBudget } from \"./tokens.js\";\n\nexport interface BuildContextOptions {\n\tinput: BuildContextInput;\n\trecall(input: BuildContextInput): Promise<MemoryWithScore[]>;\n}\n\nexport async function buildContext(\n\toptions: BuildContextOptions,\n): Promise<string> {\n\tconst format = options.input.format ?? \"markdown\";\n\tconst maxTokens = options.input.maxTokens ?? 1200;\n\tconst tokenCounter = options.input.tokenCounter ?? heuristicTokenCounter;\n\tconst memories = await options.recall(options.input);\n\tconst context = formatContext(memories, options.input.query, format);\n\treturn trimToTokenBudget(context, maxTokens, tokenCounter);\n}\n","export type MnemocyteErrorCode =\n\t| \"CONFIG\"\n\t| \"VALIDATION\"\n\t| \"DB\"\n\t| \"EMBEDDING\"\n\t| \"NOT_FOUND\"\n\t| \"MIGRATION\";\n\nexport class MnemocyteError extends Error {\n\treadonly code: MnemocyteErrorCode;\n\toverride readonly cause?: unknown;\n\n\tconstructor(message: string, code: MnemocyteErrorCode, cause?: unknown) {\n\t\tsuper(message);\n\t\tthis.name = \"MnemocyteError\";\n\t\tthis.code = code;\n\t\tthis.cause = cause;\n\t}\n}\n\nexport function isMnemocyteError(error: unknown): error is MnemocyteError {\n\treturn error instanceof MnemocyteError;\n}\n","import type {\n\tMnemocyteBackend,\n\tMnemocyteConfig,\n\tMnemocyteObservation,\n\tMnemocyteOperation,\n} from \"./types.js\";\n\ninterface ObservationMetadata {\n\tentityId?: string;\n\tmemoryId?: string;\n\tcount?: number;\n}\n\nfunction withMetadata(\n\tevent: MnemocyteObservation,\n\tmetadata: ObservationMetadata,\n): MnemocyteObservation {\n\treturn {\n\t\t...event,\n\t\t...(metadata.entityId === undefined ? {} : { entityId: metadata.entityId }),\n\t\t...(metadata.memoryId === undefined ? {} : { memoryId: metadata.memoryId }),\n\t\t...(metadata.count === undefined ? {} : { count: metadata.count }),\n\t};\n}\n\nasync function emitObservation(\n\tconfig: MnemocyteConfig,\n\tevent: MnemocyteObservation,\n): Promise<void> {\n\ttry {\n\t\tawait config.observability?.onEvent?.(event);\n\t} catch {\n\t\treturn;\n\t}\n}\n\nexport async function observe<T>(\n\tconfig: MnemocyteConfig,\n\tbackend: MnemocyteBackend,\n\toperation: MnemocyteOperation,\n\tmetadata: ObservationMetadata,\n\taction: () => Promise<T>,\n\tsuccessMetadata?: (result: T) => ObservationMetadata,\n): Promise<T> {\n\tconst startedAt = Date.now();\n\tawait emitObservation(\n\t\tconfig,\n\t\twithMetadata(\n\t\t\t{\n\t\t\t\toperation,\n\t\t\t\tphase: \"start\",\n\t\t\t\tbackend,\n\t\t\t\ttimestamp: new Date(startedAt),\n\t\t\t},\n\t\t\tmetadata,\n\t\t),\n\t);\n\ttry {\n\t\tconst result = await action();\n\t\tawait emitObservation(\n\t\t\tconfig,\n\t\t\twithMetadata(\n\t\t\t\t{\n\t\t\t\t\toperation,\n\t\t\t\t\tphase: \"success\",\n\t\t\t\t\tbackend,\n\t\t\t\t\ttimestamp: new Date(),\n\t\t\t\t\tdurationMs: Date.now() - startedAt,\n\t\t\t\t},\n\t\t\t\t{ ...metadata, ...successMetadata?.(result) },\n\t\t\t),\n\t\t);\n\t\treturn result;\n\t} catch (error) {\n\t\tawait emitObservation(\n\t\t\tconfig,\n\t\t\twithMetadata(\n\t\t\t\t{\n\t\t\t\t\toperation,\n\t\t\t\t\tphase: \"error\",\n\t\t\t\t\tbackend,\n\t\t\t\t\ttimestamp: new Date(),\n\t\t\t\t\tdurationMs: Date.now() - startedAt,\n\t\t\t\t\terror,\n\t\t\t\t},\n\t\t\t\tmetadata,\n\t\t\t),\n\t\t);\n\t\tthrow error;\n\t}\n}\n","import type { MemoryRow } from \"../db/schema.js\";\nimport { MnemocyteError } from \"../errors.js\";\nimport type {\n\tBuildContextInput,\n\tEmbedder,\n\tImportanceLevel,\n\tMemory,\n\tMemoryType,\n\tRecallInput,\n\tRememberInput,\n} from \"../types.js\";\n\nexport const DEFAULT_LIMIT = 10;\nexport const DEFAULT_MIN_SCORE = 0;\nexport const DEFAULT_TYPE: MemoryType = \"fact\";\nexport const DEFAULT_IMPORTANCE: ImportanceLevel = \"normal\";\n\nexport interface StoredMemory extends Memory {\n\tembedding: number[];\n}\n\nexport function assertNonEmptyString(value: string, field: string): void {\n\tif (value.trim().length === 0) {\n\t\tthrow new MnemocyteError(\n\t\t\t`${field} must be a non-empty string.`,\n\t\t\t\"VALIDATION\",\n\t\t);\n\t}\n}\n\nexport function assertLimit(value: number): void {\n\tif (!Number.isInteger(value) || value < 1) {\n\t\tthrow new MnemocyteError(\"limit must be a positive integer.\", \"VALIDATION\");\n\t}\n}\n\nexport function assertMinScore(value: number): void {\n\tif (!Number.isFinite(value) || value < 0 || value > 1) {\n\t\tthrow new MnemocyteError(\n\t\t\t\"minScore must be a number between 0 and 1.\",\n\t\t\t\"VALIDATION\",\n\t\t);\n\t}\n}\n\nexport function assertEmbedder(embedder: Embedder): void {\n\tif (!embedder || typeof embedder.embed !== \"function\") {\n\t\tthrow new MnemocyteError(\n\t\t\t\"embedder with an embed function is required.\",\n\t\t\t\"CONFIG\",\n\t\t);\n\t}\n\tassertNonEmptyString(embedder.model, \"embedder.model\");\n\tif (!Number.isInteger(embedder.dimensions) || embedder.dimensions < 1) {\n\t\tthrow new MnemocyteError(\n\t\t\t\"embedder.dimensions must be a positive integer.\",\n\t\t\t\"CONFIG\",\n\t\t);\n\t}\n}\n\nexport function normalizeTags(tags: readonly string[] | undefined): string[] {\n\tif (!tags) {\n\t\treturn [];\n\t}\n\treturn [...new Set(tags.map((tag) => tag.trim()).filter(Boolean))];\n}\n\nexport function createId(): string {\n\treturn `mem_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;\n}\n\nexport function isExpired(memory: Memory, now: Date): boolean {\n\treturn (\n\t\tmemory.expiresAt !== null && memory.expiresAt.getTime() <= now.getTime()\n\t);\n}\n\nexport function cloneMemory(memory: Memory): Memory {\n\treturn {\n\t\t...memory,\n\t\ttags: [...memory.tags],\n\t\tmetadata: { ...memory.metadata },\n\t\texpiresAt: memory.expiresAt ? new Date(memory.expiresAt) : null,\n\t\tlastAccessedAt: memory.lastAccessedAt\n\t\t\t? new Date(memory.lastAccessedAt)\n\t\t\t: null,\n\t\tcreatedAt: new Date(memory.createdAt),\n\t\tupdatedAt: new Date(memory.updatedAt),\n\t};\n}\n\nexport function rowToMemory(row: MemoryRow): Memory {\n\treturn {\n\t\tid: row.id,\n\t\tentityId: row.entityId,\n\t\tcontent: row.content,\n\t\ttype: row.type as MemoryType,\n\t\timportance: row.importance as ImportanceLevel,\n\t\ttags: row.tags,\n\t\tsource: row.source,\n\t\tmetadata: row.metadata as Record<string, unknown>,\n\t\tconfidence: row.confidence,\n\t\tembeddingModel: row.embeddingModel,\n\t\tembeddingDimensions: row.embeddingDimensions,\n\t\tsupersededBy: row.supersededBy,\n\t\texpiresAt: row.expiresAt,\n\t\tlastAccessedAt: row.lastAccessedAt,\n\t\taccessCount: row.accessCount,\n\t\tcreatedAt: row.createdAt,\n\t\tupdatedAt: row.updatedAt,\n\t};\n}\n\nexport async function embedOne(\n\tembedder: Embedder,\n\ttext: string,\n): Promise<number[]> {\n\tlet embeddings: number[][];\n\ttry {\n\t\tembeddings = await embedder.embed([text]);\n\t} catch (error) {\n\t\tthrow new MnemocyteError(\"Failed to embed text.\", \"EMBEDDING\", error);\n\t}\n\tconst embedding = embeddings[0];\n\tif (!embedding) {\n\t\tthrow new MnemocyteError(\"Embedder returned no embedding.\", \"EMBEDDING\");\n\t}\n\tif (embedding.length !== embedder.dimensions) {\n\t\tthrow new MnemocyteError(\n\t\t\t\"Embedder returned an embedding with unexpected dimensions.\",\n\t\t\t\"EMBEDDING\",\n\t\t);\n\t}\n\treturn embedding;\n}\n\nexport function validateRememberInput(input: RememberInput): void {\n\tassertNonEmptyString(input.entityId, \"entityId\");\n\tassertNonEmptyString(input.content, \"content\");\n\tif (\n\t\tinput.confidence !== undefined &&\n\t\t(!Number.isFinite(input.confidence) ||\n\t\t\tinput.confidence < 0 ||\n\t\t\tinput.confidence > 1)\n\t) {\n\t\tthrow new MnemocyteError(\n\t\t\t\"confidence must be a number between 0 and 1.\",\n\t\t\t\"VALIDATION\",\n\t\t);\n\t}\n}\n\nexport function validateRecallInput(input: RecallInput): void {\n\tassertNonEmptyString(input.entityId, \"entityId\");\n\tassertNonEmptyString(input.query, \"query\");\n\tif (input.limit !== undefined) {\n\t\tassertLimit(input.limit);\n\t}\n\tif (input.minScore !== undefined) {\n\t\tassertMinScore(input.minScore);\n\t}\n}\n\nexport function contextInputToRecallInput(\n\tinput: BuildContextInput,\n): RecallInput {\n\treturn {\n\t\tentityId: input.entityId,\n\t\tquery: input.query,\n\t\t...(input.limit === undefined ? {} : { limit: input.limit }),\n\t\t...(input.minScore === undefined ? {} : { minScore: input.minScore }),\n\t\t...(input.types === undefined ? {} : { types: input.types }),\n\t\t...(input.tags === undefined ? {} : { tags: input.tags }),\n\t\t...(input.includeSuperseded === undefined\n\t\t\t? {}\n\t\t\t: { includeSuperseded: input.includeSuperseded }),\n\t\t...(input.includeExpired === undefined\n\t\t\t? {}\n\t\t\t: { includeExpired: input.includeExpired }),\n\t};\n}\n\nexport function matchesRecallFilter(\n\tmemory: Memory,\n\tinput: RecallInput,\n\tnow: Date,\n): boolean {\n\tif (memory.entityId !== input.entityId) {\n\t\treturn false;\n\t}\n\tif (!input.includeSuperseded && memory.supersededBy !== null) {\n\t\treturn false;\n\t}\n\tif (!input.includeExpired && isExpired(memory, now)) {\n\t\treturn false;\n\t}\n\tif (input.types && !input.types.includes(memory.type)) {\n\t\treturn false;\n\t}\n\tif (input.tags && !input.tags.every((tag) => memory.tags.includes(tag))) {\n\t\treturn false;\n\t}\n\tif (input.before && memory.createdAt >= input.before) {\n\t\treturn false;\n\t}\n\tif (input.after && memory.createdAt <= input.after) {\n\t\treturn false;\n\t}\n\treturn true;\n}\n","import { cloneMemory } from \"../memory/shared.js\";\nimport type {\n\tImportanceLevel,\n\tMemory,\n\tMemoryWithScore,\n\tRecallInput,\n\tRetrievalConfig,\n\tRetrievalScoreWeights,\n} from \"../types.js\";\n\nconst IMPORTANCE_SCORES: Record<ImportanceLevel, number> = {\n\tlow: 0,\n\tnormal: 0.5,\n\thigh: 0.8,\n\tcritical: 1,\n};\n\nconst DEFAULT_WEIGHTS: Required<RetrievalScoreWeights> = {\n\tvector: 0.55,\n\tlexical: 0.2,\n\trecency: 0.1,\n\tconfidence: 0.05,\n\taccess: 0.05,\n\timportance: 0.05,\n};\n\nconst DEFAULT_RECENCY_HALF_LIFE_DAYS = 90;\nconst DEFAULT_ACCESS_SATURATION = 10;\nexport const DEFAULT_CANDIDATE_MULTIPLIER = 3;\n\nexport function cosineSimilarity(\n\ta: readonly number[],\n\tb: readonly number[],\n): number {\n\tlet dot = 0;\n\tlet aMagnitude = 0;\n\tlet bMagnitude = 0;\n\tfor (let i = 0; i < a.length; i += 1) {\n\t\tconst av = a[i] ?? 0;\n\t\tconst bv = b[i] ?? 0;\n\t\tdot += av * bv;\n\t\taMagnitude += av * av;\n\t\tbMagnitude += bv * bv;\n\t}\n\tif (aMagnitude === 0 || bMagnitude === 0) {\n\t\treturn 0;\n\t}\n\treturn dot / (Math.sqrt(aMagnitude) * Math.sqrt(bMagnitude));\n}\n\nexport function lexicalScore(content: string, query: string): number {\n\tconst terms = query.toLowerCase().split(/\\s+/).filter(Boolean);\n\tif (terms.length === 0) {\n\t\treturn 0;\n\t}\n\tconst lowerContent = content.toLowerCase();\n\tconst matches = terms.filter((term) => lowerContent.includes(term)).length;\n\treturn matches / terms.length;\n}\n\nfunction clampScore(value: number): number {\n\tif (!Number.isFinite(value)) {\n\t\treturn 0;\n\t}\n\treturn Math.max(0, Math.min(1, value));\n}\n\nfunction normalizeWeights(\n\tweights: RetrievalScoreWeights | undefined,\n): Required<RetrievalScoreWeights> {\n\tconst merged = { ...DEFAULT_WEIGHTS, ...weights };\n\tconst total =\n\t\tmerged.vector +\n\t\tmerged.lexical +\n\t\tmerged.recency +\n\t\tmerged.confidence +\n\t\tmerged.access +\n\t\tmerged.importance;\n\tif (total <= 0) {\n\t\treturn DEFAULT_WEIGHTS;\n\t}\n\treturn {\n\t\tvector: merged.vector / total,\n\t\tlexical: merged.lexical / total,\n\t\trecency: merged.recency / total,\n\t\tconfidence: merged.confidence / total,\n\t\taccess: merged.access / total,\n\t\timportance: merged.importance / total,\n\t};\n}\n\nfunction recencyScore(createdAt: Date, halfLifeDays: number): number {\n\tconst ageMs = Date.now() - createdAt.getTime();\n\tconst ageDays = Math.max(0, ageMs / 86_400_000);\n\treturn Math.exp((-Math.LN2 * ageDays) / halfLifeDays);\n}\n\nfunction accessScore(accessCount: number, saturation: number): number {\n\tif (accessCount <= 0) {\n\t\treturn 0;\n\t}\n\treturn Math.min(1, Math.log1p(accessCount) / Math.log1p(saturation));\n}\n\nexport function toScoredMemory(\n\tmemory: Memory,\n\tvector: number,\n\tlexical: number,\n\tinput: RecallInput,\n\tconfig?: RetrievalConfig,\n): MemoryWithScore {\n\tconst weights = normalizeWeights(config?.weights);\n\tconst recency = recencyScore(\n\t\tmemory.createdAt,\n\t\tconfig?.recencyHalfLifeDays ?? DEFAULT_RECENCY_HALF_LIFE_DAYS,\n\t);\n\tconst confidence = clampScore(memory.confidence);\n\tconst access = accessScore(\n\t\tmemory.accessCount,\n\t\tconfig?.accessSaturation ?? DEFAULT_ACCESS_SATURATION,\n\t);\n\tconst importance = IMPORTANCE_SCORES[memory.importance];\n\tconst score = Math.max(\n\t\t0,\n\t\tMath.min(\n\t\t\t1,\n\t\t\tclampScore(vector) * weights.vector +\n\t\t\t\tclampScore(lexical) * weights.lexical +\n\t\t\t\trecency * weights.recency +\n\t\t\t\tconfidence * weights.confidence +\n\t\t\t\taccess * weights.access +\n\t\t\t\timportance * weights.importance,\n\t\t),\n\t);\n\treturn {\n\t\t...cloneMemory(memory),\n\t\tscore,\n\t\tscores: {\n\t\t\tvector: clampScore(vector),\n\t\t\tlexical: clampScore(lexical),\n\t\t\trecency,\n\t\t\tconfidence,\n\t\t\taccess,\n\t\t\timportance,\n\t\t},\n\t\texplanation: input.explain\n\t\t\t? {\n\t\t\t\t\tvectorScore: clampScore(vector),\n\t\t\t\t\tlexicalScore: clampScore(lexical),\n\t\t\t\t\trecencyScore: recency,\n\t\t\t\t\tconfidenceScore: confidence,\n\t\t\t\t\taccessScore: access,\n\t\t\t\t\timportanceScore: importance,\n\t\t\t\t\timportanceBoost: importance * weights.importance,\n\t\t\t\t\tweights,\n\t\t\t\t\tfinalScore: score,\n\t\t\t\t}\n\t\t\t: null,\n\t};\n}\n","import { buildContext } from \"../context/builder.js\";\nimport { MnemocyteError } from \"../errors.js\";\nimport { observe } from \"../observability.js\";\nimport {\n\tcosineSimilarity,\n\tlexicalScore,\n\ttoScoredMemory,\n} from \"../retrieval/scorer.js\";\nimport type {\n\tEntityStats,\n\tGlobalStats,\n\tMemory,\n\tMnemocyteClient,\n\tMnemocyteConfig,\n\tRememberInput,\n} from \"../types.js\";\nimport {\n\tassertLimit,\n\tassertMinScore,\n\tassertNonEmptyString,\n\tcloneMemory,\n\tcontextInputToRecallInput,\n\tcreateId,\n\tDEFAULT_IMPORTANCE,\n\tDEFAULT_LIMIT,\n\tDEFAULT_MIN_SCORE,\n\tDEFAULT_TYPE,\n\tembedOne,\n\tisExpired,\n\tmatchesRecallFilter,\n\tnormalizeTags,\n\ttype StoredMemory,\n\tvalidateRecallInput,\n\tvalidateRememberInput,\n} from \"./shared.js\";\n\nexport function createInMemoryClient(config: MnemocyteConfig): MnemocyteClient {\n\tconst memories = new Map<string, StoredMemory>();\n\tlet closed = false;\n\n\tfunction assertOpen(): void {\n\t\tif (closed) {\n\t\t\tthrow new MnemocyteError(\"Mnemocyte client is closed.\", \"DB\");\n\t\t}\n\t}\n\n\tasync function remember(input: RememberInput): Promise<Memory> {\n\t\treturn observe(\n\t\t\tconfig,\n\t\t\t\"in-memory\",\n\t\t\t\"remember\",\n\t\t\t{ entityId: input.entityId },\n\t\t\tasync () => {\n\t\t\t\tassertOpen();\n\t\t\t\tvalidateRememberInput(input);\n\t\t\t\tconst embedding = await embedOne(config.embedder, input.content);\n\t\t\t\tconst now = new Date();\n\t\t\t\tconst memory: StoredMemory = {\n\t\t\t\t\tid: createId(),\n\t\t\t\t\tentityId: input.entityId,\n\t\t\t\t\tcontent: input.content,\n\t\t\t\t\ttype: input.type ?? DEFAULT_TYPE,\n\t\t\t\t\timportance: input.importance ?? DEFAULT_IMPORTANCE,\n\t\t\t\t\ttags: normalizeTags(input.tags),\n\t\t\t\t\tsource: input.source ?? null,\n\t\t\t\t\tmetadata: input.metadata ?? {},\n\t\t\t\t\tconfidence: input.confidence ?? 1,\n\t\t\t\t\tembeddingModel: config.embedder.model,\n\t\t\t\t\tembeddingDimensions: config.embedder.dimensions,\n\t\t\t\t\tsupersededBy: null,\n\t\t\t\t\texpiresAt: input.expiresAt ?? null,\n\t\t\t\t\tlastAccessedAt: null,\n\t\t\t\t\taccessCount: 0,\n\t\t\t\t\tcreatedAt: now,\n\t\t\t\t\tupdatedAt: now,\n\t\t\t\t\tembedding,\n\t\t\t\t};\n\t\t\t\tmemories.set(memory.id, memory);\n\t\t\t\treturn cloneMemory(memory);\n\t\t\t},\n\t\t\t(memory) => ({ memoryId: memory.id, count: 1 }),\n\t\t);\n\t}\n\n\treturn {\n\t\tremember,\n\t\tasync rememberMany(inputs) {\n\t\t\treturn observe(\n\t\t\t\tconfig,\n\t\t\t\t\"in-memory\",\n\t\t\t\t\"rememberMany\",\n\t\t\t\t{ count: inputs.length },\n\t\t\t\tasync () => {\n\t\t\t\t\tassertOpen();\n\t\t\t\t\tconst result: Memory[] = [];\n\t\t\t\t\tfor (const input of inputs) {\n\t\t\t\t\t\tresult.push(await remember(input));\n\t\t\t\t\t}\n\t\t\t\t\treturn result;\n\t\t\t\t},\n\t\t\t\t(result) => ({ count: result.length }),\n\t\t\t);\n\t\t},\n\t\tasync recall(input) {\n\t\t\treturn observe(\n\t\t\t\tconfig,\n\t\t\t\t\"in-memory\",\n\t\t\t\t\"recall\",\n\t\t\t\t{ entityId: input.entityId },\n\t\t\t\tasync () => {\n\t\t\t\t\tassertOpen();\n\t\t\t\t\tvalidateRecallInput(input);\n\t\t\t\t\tconst limit = input.limit ?? config.defaults?.limit ?? DEFAULT_LIMIT;\n\t\t\t\t\tconst minScore =\n\t\t\t\t\t\tinput.minScore ?? config.defaults?.minScore ?? DEFAULT_MIN_SCORE;\n\t\t\t\t\tassertLimit(limit);\n\t\t\t\t\tassertMinScore(minScore);\n\t\t\t\t\tconst queryEmbedding = await embedOne(config.embedder, input.query);\n\t\t\t\t\tconst now = new Date();\n\t\t\t\t\tconst scored = Array.from(memories.values())\n\t\t\t\t\t\t.filter((memory) => matchesRecallFilter(memory, input, now))\n\t\t\t\t\t\t.map((memory) =>\n\t\t\t\t\t\t\ttoScoredMemory(\n\t\t\t\t\t\t\t\tmemory,\n\t\t\t\t\t\t\t\tMath.max(0, cosineSimilarity(memory.embedding, queryEmbedding)),\n\t\t\t\t\t\t\t\tlexicalScore(memory.content, input.query),\n\t\t\t\t\t\t\t\tinput,\n\t\t\t\t\t\t\t\tconfig.retrieval,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.filter((memory) => memory.score >= minScore)\n\t\t\t\t\t\t.sort((a, b) => b.score - a.score)\n\t\t\t\t\t\t.slice(0, limit);\n\t\t\t\t\tfor (const memory of scored) {\n\t\t\t\t\t\tconst stored = memories.get(memory.id);\n\t\t\t\t\t\tif (stored) {\n\t\t\t\t\t\t\tstored.lastAccessedAt = now;\n\t\t\t\t\t\t\tstored.accessCount += 1;\n\t\t\t\t\t\t\tstored.updatedAt = now;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn scored;\n\t\t\t\t},\n\t\t\t\t(result) => ({ count: result.length }),\n\t\t\t);\n\t\t},\n\t\tasync buildContext(input) {\n\t\t\treturn observe(\n\t\t\t\tconfig,\n\t\t\t\t\"in-memory\",\n\t\t\t\t\"buildContext\",\n\t\t\t\t{ entityId: input.entityId },\n\t\t\t\tasync () => {\n\t\t\t\t\tassertOpen();\n\t\t\t\t\treturn buildContext({\n\t\t\t\t\t\tinput,\n\t\t\t\t\t\trecall: (contextInput) =>\n\t\t\t\t\t\t\tthis.recall(contextInputToRecallInput(contextInput)),\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t);\n\t\t},\n\t\tasync forget(input) {\n\t\t\treturn observe(\n\t\t\t\tconfig,\n\t\t\t\t\"in-memory\",\n\t\t\t\t\"forget\",\n\t\t\t\t{ entityId: input.entityId, memoryId: input.memoryId },\n\t\t\t\tasync () => {\n\t\t\t\t\tassertOpen();\n\t\t\t\t\tassertNonEmptyString(input.entityId, \"entityId\");\n\t\t\t\t\tassertNonEmptyString(input.memoryId, \"memoryId\");\n\t\t\t\t\tconst memory = memories.get(input.memoryId);\n\t\t\t\t\tif (!memory || memory.entityId !== input.entityId) {\n\t\t\t\t\t\tthrow new MnemocyteError(\"Memory was not found.\", \"NOT_FOUND\");\n\t\t\t\t\t}\n\t\t\t\t\tmemories.delete(input.memoryId);\n\t\t\t\t},\n\t\t\t);\n\t\t},\n\t\tasync forgetAll(input) {\n\t\t\treturn observe(\n\t\t\t\tconfig,\n\t\t\t\t\"in-memory\",\n\t\t\t\t\"forgetAll\",\n\t\t\t\t{ entityId: input.entityId },\n\t\t\t\tasync () => {\n\t\t\t\t\tassertOpen();\n\t\t\t\t\tassertNonEmptyString(input.entityId, \"entityId\");\n\t\t\t\t\tlet deleted = 0;\n\t\t\t\t\tfor (const [id, memory] of memories) {\n\t\t\t\t\t\tif (memory.entityId === input.entityId) {\n\t\t\t\t\t\t\tmemories.delete(id);\n\t\t\t\t\t\t\tdeleted += 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn deleted;\n\t\t\t\t},\n\t\t\t\t(count) => ({ count }),\n\t\t\t).then(() => undefined);\n\t\t},\n\t\tasync stats(input) {\n\t\t\treturn observe(\n\t\t\t\tconfig,\n\t\t\t\t\"in-memory\",\n\t\t\t\t\"stats\",\n\t\t\t\tinput?.entityId ? { entityId: input.entityId } : {},\n\t\t\t\tasync () => {\n\t\t\t\t\tassertOpen();\n\t\t\t\t\tconst now = new Date();\n\t\t\t\t\tconst allMemories = Array.from(memories.values());\n\t\t\t\t\tconst selected = input?.entityId\n\t\t\t\t\t\t? allMemories.filter((memory) => memory.entityId === input.entityId)\n\t\t\t\t\t\t: allMemories;\n\t\t\t\t\tconst activeMemoryCount = selected.filter(\n\t\t\t\t\t\t(memory) => !isExpired(memory, now) && memory.supersededBy === null,\n\t\t\t\t\t).length;\n\t\t\t\t\tconst expiredMemoryCount = selected.filter((memory) =>\n\t\t\t\t\t\tisExpired(memory, now),\n\t\t\t\t\t).length;\n\t\t\t\t\tconst supersededMemoryCount = selected.filter(\n\t\t\t\t\t\t(memory) => memory.supersededBy !== null,\n\t\t\t\t\t).length;\n\t\t\t\t\tif (input?.entityId) {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tentityId: input.entityId,\n\t\t\t\t\t\t\tmemoryCount: selected.length,\n\t\t\t\t\t\t\tactiveMemoryCount,\n\t\t\t\t\t\t\texpiredMemoryCount,\n\t\t\t\t\t\t\tsupersededMemoryCount,\n\t\t\t\t\t\t} satisfies EntityStats;\n\t\t\t\t\t}\n\t\t\t\t\treturn {\n\t\t\t\t\t\tentityCount: new Set(allMemories.map((memory) => memory.entityId))\n\t\t\t\t\t\t\t.size,\n\t\t\t\t\t\tmemoryCount: selected.length,\n\t\t\t\t\t\tactiveMemoryCount,\n\t\t\t\t\t\texpiredMemoryCount,\n\t\t\t\t\t\tsupersededMemoryCount,\n\t\t\t\t\t} satisfies GlobalStats;\n\t\t\t\t},\n\t\t\t);\n\t\t},\n\t\tasync close() {\n\t\t\treturn observe(config, \"in-memory\", \"close\", {}, async () => {\n\t\t\t\tclosed = true;\n\t\t\t\tmemories.clear();\n\t\t\t});\n\t\t},\n\t};\n}\n","import { and, desc, eq, gt, lt } from \"drizzle-orm\";\nimport type { MnemocyteDatabase } from \"../index.js\";\nimport { type EventRow, eventsTable, type NewEventRow } from \"../schema.js\";\n\nexport interface EventFilter {\n\tentityId: string;\n\tlimit?: number;\n\tbefore?: Date;\n\tafter?: Date;\n}\n\nexport async function insertEvent(\n\tdb: MnemocyteDatabase,\n\trow: NewEventRow,\n): Promise<EventRow> {\n\tconst result = await db.insert(eventsTable).values(row).returning();\n\tconst inserted = result[0];\n\tif (!inserted) {\n\t\tthrow new Error(\"Event insert returned no rows.\");\n\t}\n\treturn inserted;\n}\n\nexport async function listEvents(\n\tdb: MnemocyteDatabase,\n\tfilter: EventFilter,\n): Promise<EventRow[]> {\n\treturn db\n\t\t.select()\n\t\t.from(eventsTable)\n\t\t.where(\n\t\t\tand(\n\t\t\t\teq(eventsTable.entityId, filter.entityId),\n\t\t\t\tfilter.before ? lt(eventsTable.timestamp, filter.before) : undefined,\n\t\t\t\tfilter.after ? gt(eventsTable.timestamp, filter.after) : undefined,\n\t\t\t),\n\t\t)\n\t\t.orderBy(desc(eventsTable.timestamp))\n\t\t.limit(filter.limit ?? 50);\n}\n\nexport async function deleteEventsForEntity(\n\tdb: MnemocyteDatabase,\n\tentityId: string,\n): Promise<number> {\n\tconst result = await db\n\t\t.delete(eventsTable)\n\t\t.where(eq(eventsTable.entityId, entityId))\n\t\t.returning({ id: eventsTable.id });\n\treturn result.length;\n}\n","import { and, eq, gt, inArray, isNull, lt, sql } from \"drizzle-orm\";\nimport type { MemoryType } from \"../../types.js\";\nimport type { MnemocyteDatabase } from \"../index.js\";\nimport { type MemoryRow, memoriesTable, type NewMemoryRow } from \"../schema.js\";\n\nexport interface MemoryFilter {\n\tentityId: string;\n\ttypes?: readonly MemoryType[];\n\ttags?: readonly string[];\n\tbefore?: Date;\n\tafter?: Date;\n\tincludeSuperseded?: boolean;\n\tincludeExpired?: boolean;\n}\n\nexport interface VectorSearchInput extends MemoryFilter {\n\tembedding: readonly number[];\n\tlimit: number;\n\tminScore?: number;\n}\n\nexport interface LexicalSearchInput extends MemoryFilter {\n\tquery: string;\n\tlimit: number;\n}\n\nfunction vectorLiteral(embedding: readonly number[]): string {\n\treturn `[${embedding.join(\",\")}]`;\n}\n\nfunction filterConditions(filter: MemoryFilter) {\n\treturn and(\n\t\teq(memoriesTable.entityId, filter.entityId),\n\t\tfilter.includeSuperseded ? undefined : isNull(memoriesTable.supersededBy),\n\t\tfilter.includeExpired\n\t\t\t? undefined\n\t\t\t: sql`(${memoriesTable.expiresAt} IS NULL OR ${memoriesTable.expiresAt} > now())`,\n\t\tfilter.types && filter.types.length > 0\n\t\t\t? inArray(memoriesTable.type, [...filter.types])\n\t\t\t: undefined,\n\t\tfilter.tags && filter.tags.length > 0\n\t\t\t? sql`${memoriesTable.tags} && ${filter.tags}`\n\t\t\t: undefined,\n\t\tfilter.before ? lt(memoriesTable.createdAt, filter.before) : undefined,\n\t\tfilter.after ? gt(memoriesTable.createdAt, filter.after) : undefined,\n\t);\n}\n\nexport async function insertMemory(\n\tdb: MnemocyteDatabase,\n\trow: NewMemoryRow,\n): Promise<MemoryRow> {\n\tconst result = await db.insert(memoriesTable).values(row).returning();\n\tconst inserted = result[0];\n\tif (!inserted) {\n\t\tthrow new Error(\"Memory insert returned no rows.\");\n\t}\n\treturn inserted;\n}\n\nexport async function getMemoryById(\n\tdb: MnemocyteDatabase,\n\tentityId: string,\n\tmemoryId: string,\n): Promise<MemoryRow | null> {\n\tconst result = await db\n\t\t.select()\n\t\t.from(memoriesTable)\n\t\t.where(\n\t\t\tand(eq(memoriesTable.entityId, entityId), eq(memoriesTable.id, memoryId)),\n\t\t)\n\t\t.limit(1);\n\treturn result[0] ?? null;\n}\n\nexport async function listMemories(\n\tdb: MnemocyteDatabase,\n\tfilter: MemoryFilter,\n): Promise<MemoryRow[]> {\n\treturn db.select().from(memoriesTable).where(filterConditions(filter));\n}\n\nexport async function deleteMemory(\n\tdb: MnemocyteDatabase,\n\tentityId: string,\n\tmemoryId: string,\n): Promise<boolean> {\n\tconst result = await db\n\t\t.delete(memoriesTable)\n\t\t.where(\n\t\t\tand(eq(memoriesTable.entityId, entityId), eq(memoriesTable.id, memoryId)),\n\t\t)\n\t\t.returning({ id: memoriesTable.id });\n\treturn result.length > 0;\n}\n\nexport async function deleteMemoriesForEntity(\n\tdb: MnemocyteDatabase,\n\tentityId: string,\n): Promise<number> {\n\tconst result = await db\n\t\t.delete(memoriesTable)\n\t\t.where(eq(memoriesTable.entityId, entityId))\n\t\t.returning({ id: memoriesTable.id });\n\treturn result.length;\n}\n\nexport async function markMemoryAccessed(\n\tdb: MnemocyteDatabase,\n\tmemoryIds: readonly string[],\n): Promise<void> {\n\tif (memoryIds.length === 0) {\n\t\treturn;\n\t}\n\tawait db\n\t\t.update(memoriesTable)\n\t\t.set({\n\t\t\tlastAccessedAt: new Date(),\n\t\t\taccessCount: sql`${memoriesTable.accessCount} + 1`,\n\t\t\tupdatedAt: new Date(),\n\t\t})\n\t\t.where(inArray(memoriesTable.id, [...memoryIds]));\n}\n\nexport async function vectorSearch(\n\tdb: MnemocyteDatabase,\n\tinput: VectorSearchInput,\n): Promise<Array<MemoryRow & { vectorScore: number }>> {\n\tconst embedding = vectorLiteral(input.embedding);\n\tconst minScore = input.minScore ?? 0;\n\tconst rows = await db.execute(sql`\n\t\tSELECT\n\t\t\tid,\n\t\t\tentity_id AS \"entityId\",\n\t\t\tcontent,\n\t\t\ttype,\n\t\t\timportance,\n\t\t\ttags,\n\t\t\tsource,\n\t\t\tmetadata,\n\t\t\tconfidence,\n\t\t\tembedding,\n\t\t\tembedding_model AS \"embeddingModel\",\n\t\t\tembedding_dimensions AS \"embeddingDimensions\",\n\t\t\tsuperseded_by AS \"supersededBy\",\n\t\t\tsuperseded_at AS \"supersededAt\",\n\t\t\texpires_at AS \"expiresAt\",\n\t\t\tlast_accessed_at AS \"lastAccessedAt\",\n\t\t\taccess_count AS \"accessCount\",\n\t\t\tcreated_at AS \"createdAt\",\n\t\t\tupdated_at AS \"updatedAt\",\n\t\t\t1 - (embedding <=> ${embedding}::vector) AS \"vectorScore\"\n\t\tFROM mnemocyte_memories\n\t\tWHERE\n\t\t\tentity_id = ${input.entityId}\n\t\t\tAND embedding IS NOT NULL\n\t\t\t${input.includeSuperseded ? sql`` : sql`AND superseded_by IS NULL`}\n\t\t\t${input.includeExpired ? sql`` : sql`AND (expires_at IS NULL OR expires_at > now())`}\n\t\t\t${\n\t\t\t\tinput.types && input.types.length > 0\n\t\t\t\t\t? sql`AND type IN (${sql.join(\n\t\t\t\t\t\t\tinput.types.map((type) => sql`${type}`),\n\t\t\t\t\t\t\tsql`, `,\n\t\t\t\t\t\t)})`\n\t\t\t\t\t: sql``\n\t\t\t}\n\t\t\t${input.tags && input.tags.length > 0 ? sql`AND tags && ${input.tags}` : sql``}\n\t\t\t${input.before ? sql`AND created_at < ${input.before}` : sql``}\n\t\t\t${input.after ? sql`AND created_at > ${input.after}` : sql``}\n\t\t\tAND 1 - (embedding <=> ${embedding}::vector) >= ${minScore}\n\t\tORDER BY embedding <=> ${embedding}::vector\n\t\tLIMIT ${input.limit}\n\t`);\n\treturn rows as unknown as Array<MemoryRow & { vectorScore: number }>;\n}\n\nexport async function lexicalSearch(\n\tdb: MnemocyteDatabase,\n\tinput: LexicalSearchInput,\n): Promise<Array<MemoryRow & { lexicalScore: number }>> {\n\tconst rows = await db.execute(sql`\n\t\tSELECT\n\t\t\tid,\n\t\t\tentity_id AS \"entityId\",\n\t\t\tcontent,\n\t\t\ttype,\n\t\t\timportance,\n\t\t\ttags,\n\t\t\tsource,\n\t\t\tmetadata,\n\t\t\tconfidence,\n\t\t\tembedding,\n\t\t\tembedding_model AS \"embeddingModel\",\n\t\t\tembedding_dimensions AS \"embeddingDimensions\",\n\t\t\tsuperseded_by AS \"supersededBy\",\n\t\t\tsuperseded_at AS \"supersededAt\",\n\t\t\texpires_at AS \"expiresAt\",\n\t\t\tlast_accessed_at AS \"lastAccessedAt\",\n\t\t\taccess_count AS \"accessCount\",\n\t\t\tcreated_at AS \"createdAt\",\n\t\t\tupdated_at AS \"updatedAt\",\n\t\t\tts_rank(to_tsvector('english', content), websearch_to_tsquery('english', ${input.query})) AS \"lexicalScore\"\n\t\tFROM mnemocyte_memories\n\t\tWHERE\n\t\t\tentity_id = ${input.entityId}\n\t\t\t${input.includeSuperseded ? sql`` : sql`AND superseded_by IS NULL`}\n\t\t\t${input.includeExpired ? sql`` : sql`AND (expires_at IS NULL OR expires_at > now())`}\n\t\t\t${\n\t\t\t\tinput.types && input.types.length > 0\n\t\t\t\t\t? sql`AND type IN (${sql.join(\n\t\t\t\t\t\t\tinput.types.map((type) => sql`${type}`),\n\t\t\t\t\t\t\tsql`, `,\n\t\t\t\t\t\t)})`\n\t\t\t\t\t: sql``\n\t\t\t}\n\t\t\t${input.tags && input.tags.length > 0 ? sql`AND tags && ${input.tags}` : sql``}\n\t\t\t${input.before ? sql`AND created_at < ${input.before}` : sql``}\n\t\t\t${input.after ? sql`AND created_at > ${input.after}` : sql``}\n\t\t\tAND to_tsvector('english', content) @@ websearch_to_tsquery('english', ${input.query})\n\t\tORDER BY \"lexicalScore\" DESC\n\t\tLIMIT ${input.limit}\n\t`);\n\treturn rows as unknown as Array<MemoryRow & { lexicalScore: number }>;\n}\n","import type { MnemocyteDatabase } from \"../db/index.js\";\nimport {\n\tlexicalSearch,\n\tmarkMemoryAccessed,\n\tvectorSearch,\n} from \"../db/queries/memories.js\";\nimport type { MemoryRow } from \"../db/schema.js\";\nimport { embedOne, rowToMemory } from \"../memory/shared.js\";\nimport type {\n\tEmbedder,\n\tMemoryWithScore,\n\tRecallInput,\n\tRetrievalConfig,\n} from \"../types.js\";\nimport { DEFAULT_CANDIDATE_MULTIPLIER, toScoredMemory } from \"./scorer.js\";\n\ninterface HybridRecallInput {\n\tdb: MnemocyteDatabase;\n\tembedder: Embedder;\n\tinput: RecallInput;\n\tlimit: number;\n\tminScore: number;\n\tretrieval: RetrievalConfig | undefined;\n}\n\ninterface ScoredRow {\n\trow: MemoryRow;\n\tvectorScore: number;\n\tlexicalScore: number;\n}\n\nexport async function hybridRecall(\n\tinput: HybridRecallInput,\n): Promise<MemoryWithScore[]> {\n\tconst queryEmbedding = await embedOne(input.embedder, input.input.query);\n\tconst candidateMultiplier =\n\t\tinput.retrieval?.candidateMultiplier ?? DEFAULT_CANDIDATE_MULTIPLIER;\n\tconst candidateLimit = Math.max(\n\t\tinput.limit,\n\t\tinput.limit * candidateMultiplier,\n\t);\n\tconst [vectorRows, lexicalRows] = await Promise.all([\n\t\tvectorSearch(input.db, {\n\t\t\t...input.input,\n\t\t\tembedding: queryEmbedding,\n\t\t\tlimit: candidateLimit,\n\t\t\tminScore: 0,\n\t\t}),\n\t\tlexicalSearch(input.db, { ...input.input, limit: candidateLimit }),\n\t]);\n\tconst merged = new Map<string, ScoredRow>();\n\tfor (const row of vectorRows) {\n\t\tmerged.set(row.id, {\n\t\t\trow,\n\t\t\tvectorScore: row.vectorScore,\n\t\t\tlexicalScore: 0,\n\t\t});\n\t}\n\tfor (const row of lexicalRows) {\n\t\tconst existing = merged.get(row.id);\n\t\tif (existing) {\n\t\t\texisting.lexicalScore = row.lexicalScore;\n\t\t} else {\n\t\t\tmerged.set(row.id, {\n\t\t\t\trow,\n\t\t\t\tvectorScore: 0,\n\t\t\t\tlexicalScore: row.lexicalScore,\n\t\t\t});\n\t\t}\n\t}\n\tconst scored = Array.from(merged.values())\n\t\t.map((entry) =>\n\t\t\ttoScoredMemory(\n\t\t\t\trowToMemory(entry.row),\n\t\t\t\tMath.max(0, entry.vectorScore),\n\t\t\t\tMath.max(0, entry.lexicalScore),\n\t\t\t\tinput.input,\n\t\t\t\tinput.retrieval,\n\t\t\t),\n\t\t)\n\t\t.filter((memory) => memory.score >= input.minScore)\n\t\t.sort((a, b) => b.score - a.score)\n\t\t.slice(0, input.limit);\n\tawait markMemoryAccessed(\n\t\tinput.db,\n\t\tscored.map((memory) => memory.id),\n\t);\n\treturn scored;\n}\n","import { buildContext } from \"../context/builder.js\";\nimport type { DatabaseHandle } from \"../db/index.js\";\nimport { deleteEventsForEntity } from \"../db/queries/events.js\";\nimport {\n\tdeleteMemoriesForEntity,\n\tdeleteMemory,\n\tinsertMemory,\n\tlistMemories,\n} from \"../db/queries/memories.js\";\nimport { memoriesTable } from \"../db/schema.js\";\nimport { MnemocyteError } from \"../errors.js\";\nimport { observe } from \"../observability.js\";\nimport { hybridRecall } from \"../retrieval/index.js\";\nimport type {\n\tEntityStats,\n\tGlobalStats,\n\tMemory,\n\tMnemocyteClient,\n\tMnemocyteConfig,\n\tRememberInput,\n} from \"../types.js\";\nimport {\n\tassertLimit,\n\tassertMinScore,\n\tassertNonEmptyString,\n\tcontextInputToRecallInput,\n\tcreateId,\n\tDEFAULT_IMPORTANCE,\n\tDEFAULT_LIMIT,\n\tDEFAULT_MIN_SCORE,\n\tDEFAULT_TYPE,\n\tembedOne,\n\tisExpired,\n\tnormalizeTags,\n\trowToMemory,\n\tvalidateRecallInput,\n\tvalidateRememberInput,\n} from \"./shared.js\";\n\nexport function createPostgresClient(\n\tconfig: MnemocyteConfig,\n\thandle: DatabaseHandle,\n): MnemocyteClient {\n\tlet closed = false;\n\n\tfunction assertOpen(): void {\n\t\tif (closed) {\n\t\t\tthrow new MnemocyteError(\"Mnemocyte client is closed.\", \"DB\");\n\t\t}\n\t}\n\n\tasync function remember(input: RememberInput): Promise<Memory> {\n\t\treturn observe(\n\t\t\tconfig,\n\t\t\t\"postgres\",\n\t\t\t\"remember\",\n\t\t\t{ entityId: input.entityId },\n\t\t\tasync () => {\n\t\t\t\tassertOpen();\n\t\t\t\tvalidateRememberInput(input);\n\t\t\t\tconst embedding = await embedOne(config.embedder, input.content);\n\t\t\t\tconst now = new Date();\n\t\t\t\tconst row = await insertMemory(handle.db, {\n\t\t\t\t\tid: createId(),\n\t\t\t\t\tentityId: input.entityId,\n\t\t\t\t\tcontent: input.content,\n\t\t\t\t\ttype: input.type ?? DEFAULT_TYPE,\n\t\t\t\t\timportance: input.importance ?? DEFAULT_IMPORTANCE,\n\t\t\t\t\ttags: normalizeTags(input.tags),\n\t\t\t\t\tsource: input.source ?? null,\n\t\t\t\t\tmetadata: input.metadata ?? {},\n\t\t\t\t\tconfidence: input.confidence ?? 1,\n\t\t\t\t\tembedding,\n\t\t\t\t\tembeddingModel: config.embedder.model,\n\t\t\t\t\tembeddingDimensions: config.embedder.dimensions,\n\t\t\t\t\tsupersededBy: null,\n\t\t\t\t\tsupersededAt: null,\n\t\t\t\t\texpiresAt: input.expiresAt ?? null,\n\t\t\t\t\tlastAccessedAt: null,\n\t\t\t\t\taccessCount: 0,\n\t\t\t\t\tcreatedAt: now,\n\t\t\t\t\tupdatedAt: now,\n\t\t\t\t});\n\t\t\t\treturn rowToMemory(row);\n\t\t\t},\n\t\t\t(memory) => ({ memoryId: memory.id, count: 1 }),\n\t\t);\n\t}\n\n\treturn {\n\t\tremember,\n\t\tasync rememberMany(inputs) {\n\t\t\treturn observe(\n\t\t\t\tconfig,\n\t\t\t\t\"postgres\",\n\t\t\t\t\"rememberMany\",\n\t\t\t\t{ count: inputs.length },\n\t\t\t\tasync () => {\n\t\t\t\t\tassertOpen();\n\t\t\t\t\tconst result: Memory[] = [];\n\t\t\t\t\tfor (const input of inputs) {\n\t\t\t\t\t\tresult.push(await remember(input));\n\t\t\t\t\t}\n\t\t\t\t\treturn result;\n\t\t\t\t},\n\t\t\t\t(result) => ({ count: result.length }),\n\t\t\t);\n\t\t},\n\t\tasync recall(input) {\n\t\t\treturn observe(\n\t\t\t\tconfig,\n\t\t\t\t\"postgres\",\n\t\t\t\t\"recall\",\n\t\t\t\t{ entityId: input.entityId },\n\t\t\t\tasync () => {\n\t\t\t\t\tassertOpen();\n\t\t\t\t\tvalidateRecallInput(input);\n\t\t\t\t\tconst limit = input.limit ?? config.defaults?.limit ?? DEFAULT_LIMIT;\n\t\t\t\t\tconst minScore =\n\t\t\t\t\t\tinput.minScore ?? config.defaults?.minScore ?? DEFAULT_MIN_SCORE;\n\t\t\t\t\tassertLimit(limit);\n\t\t\t\t\tassertMinScore(minScore);\n\t\t\t\t\treturn hybridRecall({\n\t\t\t\t\t\tdb: handle.db,\n\t\t\t\t\t\tembedder: config.embedder,\n\t\t\t\t\t\tinput,\n\t\t\t\t\t\tlimit,\n\t\t\t\t\t\tminScore,\n\t\t\t\t\t\tretrieval: config.retrieval,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t\t(result) => ({ count: result.length }),\n\t\t\t);\n\t\t},\n\t\tasync buildContext(input) {\n\t\t\treturn observe(\n\t\t\t\tconfig,\n\t\t\t\t\"postgres\",\n\t\t\t\t\"buildContext\",\n\t\t\t\t{ entityId: input.entityId },\n\t\t\t\tasync () => {\n\t\t\t\t\tassertOpen();\n\t\t\t\t\treturn buildContext({\n\t\t\t\t\t\tinput,\n\t\t\t\t\t\trecall: (contextInput) =>\n\t\t\t\t\t\t\tthis.recall(contextInputToRecallInput(contextInput)),\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t);\n\t\t},\n\t\tasync forget(input) {\n\t\t\treturn observe(\n\t\t\t\tconfig,\n\t\t\t\t\"postgres\",\n\t\t\t\t\"forget\",\n\t\t\t\t{ entityId: input.entityId, memoryId: input.memoryId },\n\t\t\t\tasync () => {\n\t\t\t\t\tassertOpen();\n\t\t\t\t\tassertNonEmptyString(input.entityId, \"entityId\");\n\t\t\t\t\tassertNonEmptyString(input.memoryId, \"memoryId\");\n\t\t\t\t\tconst deleted = await deleteMemory(\n\t\t\t\t\t\thandle.db,\n\t\t\t\t\t\tinput.entityId,\n\t\t\t\t\t\tinput.memoryId,\n\t\t\t\t\t);\n\t\t\t\t\tif (!deleted) {\n\t\t\t\t\t\tthrow new MnemocyteError(\"Memory was not found.\", \"NOT_FOUND\");\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t);\n\t\t},\n\t\tasync forgetAll(input) {\n\t\t\treturn observe(\n\t\t\t\tconfig,\n\t\t\t\t\"postgres\",\n\t\t\t\t\"forgetAll\",\n\t\t\t\t{ entityId: input.entityId },\n\t\t\t\tasync () => {\n\t\t\t\t\tassertOpen();\n\t\t\t\t\tassertNonEmptyString(input.entityId, \"entityId\");\n\t\t\t\t\tawait Promise.all([\n\t\t\t\t\t\tdeleteMemoriesForEntity(handle.db, input.entityId),\n\t\t\t\t\t\tdeleteEventsForEntity(handle.db, input.entityId),\n\t\t\t\t\t]);\n\t\t\t\t},\n\t\t\t);\n\t\t},\n\t\tasync stats(input) {\n\t\t\treturn observe(\n\t\t\t\tconfig,\n\t\t\t\t\"postgres\",\n\t\t\t\t\"stats\",\n\t\t\t\tinput?.entityId ? { entityId: input.entityId } : {},\n\t\t\t\tasync () => {\n\t\t\t\t\tassertOpen();\n\t\t\t\t\tconst now = new Date();\n\t\t\t\t\tif (input?.entityId) {\n\t\t\t\t\t\tconst selected = await listMemories(handle.db, {\n\t\t\t\t\t\t\tentityId: input.entityId,\n\t\t\t\t\t\t\tincludeExpired: true,\n\t\t\t\t\t\t\tincludeSuperseded: true,\n\t\t\t\t\t\t});\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tentityId: input.entityId,\n\t\t\t\t\t\t\tmemoryCount: selected.length,\n\t\t\t\t\t\t\tactiveMemoryCount: selected.filter(\n\t\t\t\t\t\t\t\t(memory) =>\n\t\t\t\t\t\t\t\t\t!isExpired(rowToMemory(memory), now) &&\n\t\t\t\t\t\t\t\t\tmemory.supersededBy === null,\n\t\t\t\t\t\t\t).length,\n\t\t\t\t\t\t\texpiredMemoryCount: selected.filter((memory) =>\n\t\t\t\t\t\t\t\tisExpired(rowToMemory(memory), now),\n\t\t\t\t\t\t\t).length,\n\t\t\t\t\t\t\tsupersededMemoryCount: selected.filter(\n\t\t\t\t\t\t\t\t(memory) => memory.supersededBy !== null,\n\t\t\t\t\t\t\t).length,\n\t\t\t\t\t\t} satisfies EntityStats;\n\t\t\t\t\t}\n\t\t\t\t\tconst allMemories = await handle.db.select().from(memoriesTable);\n\t\t\t\t\treturn {\n\t\t\t\t\t\tentityCount: new Set(allMemories.map((memory) => memory.entityId))\n\t\t\t\t\t\t\t.size,\n\t\t\t\t\t\tmemoryCount: allMemories.length,\n\t\t\t\t\t\tactiveMemoryCount: allMemories.filter(\n\t\t\t\t\t\t\t(memory) =>\n\t\t\t\t\t\t\t\t!isExpired(rowToMemory(memory), now) &&\n\t\t\t\t\t\t\t\tmemory.supersededBy === null,\n\t\t\t\t\t\t).length,\n\t\t\t\t\t\texpiredMemoryCount: allMemories.filter((memory) =>\n\t\t\t\t\t\t\tisExpired(rowToMemory(memory), now),\n\t\t\t\t\t\t).length,\n\t\t\t\t\t\tsupersededMemoryCount: allMemories.filter(\n\t\t\t\t\t\t\t(memory) => memory.supersededBy !== null,\n\t\t\t\t\t\t).length,\n\t\t\t\t\t} satisfies GlobalStats;\n\t\t\t\t},\n\t\t\t);\n\t\t},\n\t\tasync close() {\n\t\t\treturn observe(config, \"postgres\", \"close\", {}, async () => {\n\t\t\t\tclosed = true;\n\t\t\t\tawait handle.close();\n\t\t\t});\n\t\t},\n\t};\n}\n","import { createDatabase } from \"./db/index.js\";\nimport { createInMemoryClient } from \"./memory/in-memory.js\";\nimport { createPostgresClient } from \"./memory/postgres.js\";\nimport { assertEmbedder, assertNonEmptyString } from \"./memory/shared.js\";\nimport type { MnemocyteClient, MnemocyteConfig } from \"./types.js\";\n\nexport function createMnemocyte(config: MnemocyteConfig): MnemocyteClient {\n\tassertEmbedder(config.embedder);\n\tif (config.databaseUrl) {\n\t\tassertNonEmptyString(config.databaseUrl, \"databaseUrl\");\n\t\treturn createPostgresClient(config, createDatabase(config.databaseUrl));\n\t}\n\treturn createInMemoryClient(config);\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mnemocyte",
3
- "version": "0.0.5",
3
+ "version": "0.0.7",
4
4
  "description": "Persistent memory for TypeScript AI apps.",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -64,6 +64,8 @@
64
64
  "build": "tsdown src/index.ts",
65
65
  "dev": "tsdown src/index.ts --watch",
66
66
  "checktypes": "tsc --noEmit",
67
+ "test:exports": "pnpm build && node test/package/exports.test.mjs && tsc -p test/package/tsconfig.json",
68
+ "test:observability": "pnpm build && node test/observability/hooks.test.mjs",
67
69
  "test:retrieval": "pnpm build && node test/retrieval/quality.test.mjs",
68
70
  "test:context": "pnpm build && node test/context/builder.test.mjs",
69
71
  "test:integration": "pnpm build && node test/integration/postgres.test.mjs",