mnemocyte 0.0.7 → 0.0.8
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/README.md +63 -1
- package/dist/index.d.mts +500 -5
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +364 -10
- package/dist/index.mjs.map +1 -1
- package/package.json +11 -16
package/dist/index.mjs.map
CHANGED
|
@@ -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/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(\"&\", \"&\")\n\t\t.replaceAll(\"<\", \"<\")\n\t\t.replaceAll(\">\", \">\")\n\t\t.replaceAll('\"', \""\")\n\t\t.replaceAll(\"'\", \"'\");\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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"}
|
|
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/resilience.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(\"&\", \"&\")\n\t\t.replaceAll(\"<\", \"<\")\n\t\t.replaceAll(\">\", \">\")\n\t\t.replaceAll('\"', \""\")\n\t\t.replaceAll(\"'\", \"'\");\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","/**\n * Stable, machine-readable error code attached to every {@link MnemocyteError}.\n *\n * - `\"CONFIG\"` — invalid client configuration (e.g. missing or malformed embedder).\n * - `\"VALIDATION\"` — invalid argument passed to a client method.\n * - `\"DB\"` — Postgres or driver-level failure.\n * - `\"EMBEDDING\"` — embedder threw or returned an invalid vector.\n * - `\"NOT_FOUND\"` — referenced memory or entity does not exist.\n * - `\"MIGRATION\"` — schema/migration check failed against the target database.\n * - `\"TIMEOUT\"` — a provider call exceeded its configured timeout.\n * - `\"ABORTED\"` — the operation was cancelled via an `AbortSignal`.\n */\nexport type MnemocyteErrorCode =\n\t| \"CONFIG\"\n\t| \"VALIDATION\"\n\t| \"DB\"\n\t| \"EMBEDDING\"\n\t| \"NOT_FOUND\"\n\t| \"MIGRATION\"\n\t| \"TIMEOUT\"\n\t| \"ABORTED\";\n\n/**\n * Error type thrown by every public Mnemocyte API.\n *\n * Use the {@link MnemocyteError.code} property — not the message — to branch\n * on failure modes, or call {@link isMnemocyteError} as a type guard when\n * working with `unknown` errors.\n *\n * @example\n * ```ts\n * try {\n * await client.recall({ entityId: \"u1\", query: \"hi\" });\n * } catch (err) {\n * if (isMnemocyteError(err) && err.code === \"DB\") {\n * // handle database failure\n * }\n * throw err;\n * }\n * ```\n */\nexport class MnemocyteError extends Error {\n\t/** Stable, machine-readable failure code. See {@link MnemocyteErrorCode}. */\n\treadonly code: MnemocyteErrorCode;\n\t/** Underlying cause, if any (e.g. an original driver or embedder error). */\n\toverride readonly cause?: unknown;\n\n\t/**\n\t * @param message - Human-readable error message.\n\t * @param code - Stable failure code; see {@link MnemocyteErrorCode}.\n\t * @param cause - Optional underlying cause (driver error, network error, etc.).\n\t */\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\n/**\n * Type guard for {@link MnemocyteError}.\n *\n * Prefer this over `instanceof` when working across module boundaries or\n * bundlers where multiple copies of the class may exist.\n *\n * @param error - Value to test (typically a caught `unknown`).\n * @returns `true` if `error` is a {@link MnemocyteError}.\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 { MnemocyteError } from \"./errors.js\";\nimport type { ProviderResilienceConfig } from \"./types.js\";\n\n/**\n * Default per-provider-call timeout. Disabled by default so that callers\n * who do not configure {@link ProviderResilienceConfig.timeoutMs} are\n * unaffected.\n */\nconst DEFAULT_TIMEOUT_MS = 0;\n/** Default number of retry attempts on transient provider failures. */\nconst DEFAULT_RETRIES = 0;\n/** Default base backoff delay used between retry attempts. */\nconst DEFAULT_BASE_DELAY_MS = 100;\n/** Default ceiling for retry backoff delay. */\nconst DEFAULT_MAX_DELAY_MS = 2000;\n\n/**\n * Internal helper: returns the AbortSignal as a typed value if available,\n * otherwise `undefined`. Used so call sites can stay narrow.\n */\nexport function getSignal(\n\tsource: { signal?: AbortSignal } | undefined,\n): AbortSignal | undefined {\n\treturn source?.signal;\n}\n\n/**\n * Throw a {@link MnemocyteError} with code `\"ABORTED\"` if `signal` is\n * already aborted. Safe to call with `undefined`.\n */\nexport function throwIfAborted(signal: AbortSignal | undefined): void {\n\tif (signal?.aborted) {\n\t\tthrow new MnemocyteError(\n\t\t\t\"Operation was aborted.\",\n\t\t\t\"ABORTED\",\n\t\t\tsignal.reason,\n\t\t);\n\t}\n}\n\n/**\n * Heuristic default for whether an error should be retried.\n *\n * Conservative by design: only retries on common transient failure\n * indicators (network errors, 5xx-ish messages, `ECONN*` etc.). Never\n * retries on validation, configuration, or {@link MnemocyteError} of\n * code `\"VALIDATION\"` / `\"CONFIG\"` / `\"ABORTED\"`.\n */\nexport function defaultShouldRetry(error: unknown): boolean {\n\tif (error instanceof MnemocyteError) {\n\t\tif (\n\t\t\terror.code === \"VALIDATION\" ||\n\t\t\terror.code === \"CONFIG\" ||\n\t\t\terror.code === \"ABORTED\"\n\t\t) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\tif (error instanceof Error) {\n\t\tconst message = error.message.toLowerCase();\n\t\tif (\n\t\t\tmessage.includes(\"econn\") ||\n\t\t\tmessage.includes(\"etimedout\") ||\n\t\t\tmessage.includes(\"network\") ||\n\t\t\tmessage.includes(\"timeout\") ||\n\t\t\tmessage.includes(\"temporarily\") ||\n\t\t\tmessage.includes(\"rate limit\") ||\n\t\t\tmessage.includes(\"503\") ||\n\t\t\tmessage.includes(\"502\") ||\n\t\t\tmessage.includes(\"504\") ||\n\t\t\tmessage.includes(\"500\")\n\t\t) {\n\t\t\treturn true;\n\t\t}\n\t}\n\treturn false;\n}\n\n/**\n * Compute the backoff delay for the given retry attempt, using exponential\n * growth capped at {@link ProviderResilienceConfig.maxDelayMs}.\n *\n * `attempt` is 1-indexed: the delay before the first retry uses\n * `attempt = 1`, before the second retry `attempt = 2`, etc.\n */\nfunction computeDelayMs(\n\tattempt: number,\n\tbaseDelayMs: number,\n\tmaxDelayMs: number,\n): number {\n\tconst exponential = baseDelayMs * 2 ** (attempt - 1);\n\treturn Math.max(0, Math.min(maxDelayMs, exponential));\n}\n\n/**\n * Promise-based `setTimeout` that rejects with an `\"ABORTED\"`\n * {@link MnemocyteError} if `signal` aborts while waiting.\n */\nfunction delay(ms: number, signal: AbortSignal | undefined): Promise<void> {\n\tif (ms <= 0) {\n\t\tthrowIfAborted(signal);\n\t\treturn Promise.resolve();\n\t}\n\treturn new Promise<void>((resolve, reject) => {\n\t\tconst timer = setTimeout(() => {\n\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\tresolve();\n\t\t}, ms);\n\t\tconst onAbort = (): void => {\n\t\t\tclearTimeout(timer);\n\t\t\treject(\n\t\t\t\tnew MnemocyteError(\"Operation was aborted.\", \"ABORTED\", signal?.reason),\n\t\t\t);\n\t\t};\n\t\tif (signal) {\n\t\t\tif (signal.aborted) {\n\t\t\t\tclearTimeout(timer);\n\t\t\t\treject(\n\t\t\t\t\tnew MnemocyteError(\n\t\t\t\t\t\t\"Operation was aborted.\",\n\t\t\t\t\t\t\"ABORTED\",\n\t\t\t\t\t\tsignal.reason,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\t\t}\n\t});\n}\n\n/**\n * Race `promise` against the configured `timeoutMs` and the caller's\n * `signal`. Rejects with `\"TIMEOUT\"` or `\"ABORTED\"` respectively. Resolves\n * with the original promise value if it settles first.\n */\nfunction withTimeout<T>(\n\tpromise: Promise<T>,\n\ttimeoutMs: number,\n\tsignal: AbortSignal | undefined,\n): Promise<T> {\n\tif (timeoutMs <= 0 && !signal) {\n\t\treturn promise;\n\t}\n\treturn new Promise<T>((resolve, reject) => {\n\t\tlet settled = false;\n\t\tconst timer =\n\t\t\ttimeoutMs > 0\n\t\t\t\t? setTimeout(() => {\n\t\t\t\t\t\tif (settled) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsettled = true;\n\t\t\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\t\t\treject(\n\t\t\t\t\t\t\tnew MnemocyteError(\n\t\t\t\t\t\t\t\t`Provider call timed out after ${timeoutMs}ms.`,\n\t\t\t\t\t\t\t\t\"TIMEOUT\",\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t);\n\t\t\t\t\t}, timeoutMs)\n\t\t\t\t: undefined;\n\t\tconst onAbort = (): void => {\n\t\t\tif (settled) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tsettled = true;\n\t\t\tif (timer) {\n\t\t\t\tclearTimeout(timer);\n\t\t\t}\n\t\t\treject(\n\t\t\t\tnew MnemocyteError(\"Operation was aborted.\", \"ABORTED\", signal?.reason),\n\t\t\t);\n\t\t};\n\t\tif (signal) {\n\t\t\tif (signal.aborted) {\n\t\t\t\tif (timer) {\n\t\t\t\t\tclearTimeout(timer);\n\t\t\t\t}\n\t\t\t\tsettled = true;\n\t\t\t\treject(\n\t\t\t\t\tnew MnemocyteError(\n\t\t\t\t\t\t\"Operation was aborted.\",\n\t\t\t\t\t\t\"ABORTED\",\n\t\t\t\t\t\tsignal.reason,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\t\t}\n\t\tpromise.then(\n\t\t\t(value) => {\n\t\t\t\tif (settled) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tsettled = true;\n\t\t\t\tif (timer) {\n\t\t\t\t\tclearTimeout(timer);\n\t\t\t\t}\n\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\tresolve(value);\n\t\t\t},\n\t\t\t(error) => {\n\t\t\t\tif (settled) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tsettled = true;\n\t\t\t\tif (timer) {\n\t\t\t\t\tclearTimeout(timer);\n\t\t\t\t}\n\t\t\t\tsignal?.removeEventListener(\"abort\", onAbort);\n\t\t\t\treject(error);\n\t\t\t},\n\t\t);\n\t});\n}\n\n/**\n * Options accepted by {@link withResilience}.\n */\nexport interface ResilienceCallOptions {\n\t/** External cancellation signal forwarded to each attempt. */\n\tsignal?: AbortSignal;\n\t/** Provider-level retry/timeout configuration. */\n\tresilience?: ProviderResilienceConfig;\n}\n\n/**\n * Run `action` with timeout, retry, and abort handling derived from\n * `options.resilience` and `options.signal`. Each retry attempt receives\n * a fresh `AbortSignal` linked to the caller's signal — so callers may\n * abort mid-retry and the in-flight attempt will cancel promptly if the\n * underlying provider honours signals.\n *\n * Errors from {@link MnemocyteError} with code `\"VALIDATION\"` /\n * `\"CONFIG\"` / `\"ABORTED\"` are never retried.\n */\nexport async function withResilience<T>(\n\taction: (signal: AbortSignal | undefined) => Promise<T>,\n\toptions: ResilienceCallOptions = {},\n): Promise<T> {\n\tconst config = options.resilience ?? {};\n\tconst timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n\tconst retries = Math.max(0, config.retries ?? DEFAULT_RETRIES);\n\tconst baseDelayMs = Math.max(0, config.baseDelayMs ?? DEFAULT_BASE_DELAY_MS);\n\tconst maxDelayMs = Math.max(\n\t\tbaseDelayMs,\n\t\tconfig.maxDelayMs ?? DEFAULT_MAX_DELAY_MS,\n\t);\n\tconst shouldRetry = config.shouldRetry ?? defaultShouldRetry;\n\tconst externalSignal = options.signal;\n\n\tthrowIfAborted(externalSignal);\n\n\tconst maxAttempts = retries + 1;\n\tlet lastError: unknown;\n\tfor (let attempt = 1; attempt <= maxAttempts; attempt += 1) {\n\t\tthrowIfAborted(externalSignal);\n\t\ttry {\n\t\t\treturn await withTimeout(\n\t\t\t\taction(externalSignal),\n\t\t\t\ttimeoutMs,\n\t\t\t\texternalSignal,\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tlastError = error;\n\t\t\tif (error instanceof MnemocyteError && error.code === \"ABORTED\") {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tif (attempt >= maxAttempts) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tif (!shouldRetry(error, attempt)) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tconst waitMs = computeDelayMs(attempt, baseDelayMs, maxDelayMs);\n\t\t\tawait delay(waitMs, externalSignal);\n\t\t}\n\t}\n\tthrow lastError;\n}\n","import type { MemoryRow } from \"../db/schema.js\";\nimport { MnemocyteError } from \"../errors.js\";\nimport { withResilience } from \"../resilience.js\";\nimport type {\n\tBuildContextInput,\n\tEmbedder,\n\tImportanceLevel,\n\tMemory,\n\tMemoryType,\n\tProviderResilienceConfig,\n\tPruneInput,\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\n/**\n * Ordering of {@link ImportanceLevel} from least to most important. Used\n * by `prune({ maxImportance })` to compare a memory's importance against\n * the caller-supplied ceiling.\n */\nexport const IMPORTANCE_RANK: Record<ImportanceLevel, number> = {\n\tlow: 0,\n\tnormal: 1,\n\thigh: 2,\n\tcritical: 3,\n};\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\toptions: {\n\t\tsignal?: AbortSignal;\n\t\tresilience?: ProviderResilienceConfig;\n\t} = {},\n): Promise<number[]> {\n\tlet embeddings: number[][];\n\ttry {\n\t\tembeddings = await withResilience(\n\t\t\t(signal) =>\n\t\t\t\tsignal === undefined\n\t\t\t\t\t? embedder.embed([text])\n\t\t\t\t\t: embedder.embed([text], { signal }),\n\t\t\t{\n\t\t\t\t...(options.signal === undefined ? {} : { signal: options.signal }),\n\t\t\t\t...(options.resilience === undefined\n\t\t\t\t\t? {}\n\t\t\t\t\t: { resilience: options.resilience }),\n\t\t\t},\n\t\t);\n\t} catch (error) {\n\t\tif (\n\t\t\terror instanceof MnemocyteError &&\n\t\t\t(error.code === \"TIMEOUT\" || error.code === \"ABORTED\")\n\t\t) {\n\t\t\tthrow error;\n\t\t}\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\n/**\n * Validate a {@link PruneInput} and throw a `\"VALIDATION\"`\n * {@link MnemocyteError} when no selector is supplied. Mnemocyte\n * deliberately rejects `prune({})` to avoid surprise full-table deletes.\n */\nexport function validatePruneInput(input: PruneInput): void {\n\tif (input.entityId !== undefined) {\n\t\tassertNonEmptyString(input.entityId, \"entityId\");\n\t}\n\tconst hasSelector =\n\t\tinput.entityId !== undefined ||\n\t\tinput.expired === true ||\n\t\tinput.superseded === true ||\n\t\tinput.createdBefore !== undefined ||\n\t\tinput.notAccessedSince !== undefined ||\n\t\t(input.types !== undefined && input.types.length > 0) ||\n\t\t(input.tags !== undefined && input.tags.length > 0) ||\n\t\tinput.maxImportance !== undefined;\n\tif (!hasSelector) {\n\t\tthrow new MnemocyteError(\n\t\t\t\"prune requires at least one selector (entityId, expired, superseded, createdBefore, notAccessedSince, types, tags, or maxImportance).\",\n\t\t\t\"VALIDATION\",\n\t\t);\n\t}\n}\n\n/**\n * Test whether `memory` matches a {@link PruneInput}. All specified\n * selectors are AND-combined; unspecified selectors do not restrict.\n *\n * `now` is supplied by the caller so callers can share a consistent\n * timestamp across a batch.\n */\nexport function matchesPruneFilter(\n\tmemory: Memory,\n\tinput: PruneInput,\n\tnow: Date,\n): boolean {\n\tif (input.entityId !== undefined && memory.entityId !== input.entityId) {\n\t\treturn false;\n\t}\n\tif (input.expired === true && !isExpired(memory, now)) {\n\t\treturn false;\n\t}\n\tif (input.superseded === true && memory.supersededBy === null) {\n\t\treturn false;\n\t}\n\tif (\n\t\tinput.createdBefore !== undefined &&\n\t\tmemory.createdAt.getTime() >= input.createdBefore.getTime()\n\t) {\n\t\treturn false;\n\t}\n\tif (input.notAccessedSince !== undefined) {\n\t\tconst last = memory.lastAccessedAt;\n\t\tif (last !== null && last.getTime() >= input.notAccessedSince.getTime()) {\n\t\t\treturn false;\n\t\t}\n\t}\n\tif (input.types !== undefined && !input.types.includes(memory.type)) {\n\t\treturn false;\n\t}\n\tif (\n\t\tinput.tags !== undefined &&\n\t\tinput.tags.length > 0 &&\n\t\t!input.tags.every((tag) => memory.tags.includes(tag))\n\t) {\n\t\treturn false;\n\t}\n\tif (\n\t\tinput.maxImportance !== undefined &&\n\t\tIMPORTANCE_RANK[memory.importance] > IMPORTANCE_RANK[input.maxImportance]\n\t) {\n\t\treturn false;\n\t}\n\treturn true;\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\tPruneInput,\n\tPruneResult,\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\tmatchesPruneFilter,\n\tmatchesRecallFilter,\n\tnormalizeTags,\n\ttype StoredMemory,\n\tvalidatePruneInput,\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\t\t...(input.signal === undefined ? {} : { signal: input.signal }),\n\t\t\t\t\t...(config.provider === undefined\n\t\t\t\t\t\t? {}\n\t\t\t\t\t\t: { resilience: config.provider }),\n\t\t\t\t});\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\t\t...(input.signal === undefined ? {} : { signal: input.signal }),\n\t\t\t\t\t\t...(config.provider === undefined\n\t\t\t\t\t\t\t? {}\n\t\t\t\t\t\t\t: { resilience: config.provider }),\n\t\t\t\t\t});\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\tconst recallInput = contextInputToRecallInput(contextInput);\n\t\t\t\t\t\t\treturn this.recall(\n\t\t\t\t\t\t\t\tinput.signal === undefined\n\t\t\t\t\t\t\t\t\t? recallInput\n\t\t\t\t\t\t\t\t\t: { ...recallInput, signal: input.signal },\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t},\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 prune(input: PruneInput): Promise<PruneResult> {\n\t\t\treturn observe(\n\t\t\t\tconfig,\n\t\t\t\t\"in-memory\",\n\t\t\t\t\"prune\",\n\t\t\t\tinput.entityId === undefined ? {} : { entityId: input.entityId },\n\t\t\t\tasync () => {\n\t\t\t\t\tassertOpen();\n\t\t\t\t\tvalidatePruneInput(input);\n\t\t\t\t\tconst now = new Date();\n\t\t\t\t\tconst matched: string[] = [];\n\t\t\t\t\tfor (const memory of memories.values()) {\n\t\t\t\t\t\tif (matchesPruneFilter(memory, input, now)) {\n\t\t\t\t\t\t\tmatched.push(memory.id);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tconst dryRun = input.dryRun === true;\n\t\t\t\t\tif (!dryRun) {\n\t\t\t\t\t\tfor (const id of matched) {\n\t\t\t\t\t\t\tmemories.delete(id);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn {\n\t\t\t\t\t\tmatchedCount: matched.length,\n\t\t\t\t\t\tdeletedCount: dryRun ? 0 : matched.length,\n\t\t\t\t\t\tdryRun,\n\t\t\t\t\t};\n\t\t\t\t},\n\t\t\t\t(result) => ({ count: result.deletedCount }),\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\"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 {\n\tand,\n\teq,\n\tgt,\n\tinArray,\n\tisNotNull,\n\tisNull,\n\tlt,\n\tor,\n\tsql,\n} from \"drizzle-orm\";\nimport type { ImportanceLevel, 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 interface PruneFilter {\n\tentityId?: string;\n\texpired?: boolean;\n\tsuperseded?: boolean;\n\tcreatedBefore?: Date;\n\tnotAccessedSince?: Date;\n\ttypes?: readonly MemoryType[];\n\ttags?: readonly string[];\n\tmaxImportanceLevels?: readonly ImportanceLevel[];\n}\n\nfunction pruneConditions(filter: PruneFilter) {\n\treturn and(\n\t\tfilter.entityId !== undefined\n\t\t\t? eq(memoriesTable.entityId, filter.entityId)\n\t\t\t: undefined,\n\t\tfilter.expired\n\t\t\t? and(\n\t\t\t\t\tisNotNull(memoriesTable.expiresAt),\n\t\t\t\t\tsql`${memoriesTable.expiresAt} <= now()`,\n\t\t\t\t)\n\t\t\t: undefined,\n\t\tfilter.superseded ? isNotNull(memoriesTable.supersededBy) : undefined,\n\t\tfilter.createdBefore\n\t\t\t? lt(memoriesTable.createdAt, filter.createdBefore)\n\t\t\t: undefined,\n\t\tfilter.notAccessedSince\n\t\t\t? or(\n\t\t\t\t\tisNull(memoriesTable.lastAccessedAt),\n\t\t\t\t\tlt(memoriesTable.lastAccessedAt, filter.notAccessedSince),\n\t\t\t\t)\n\t\t\t: undefined,\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.maxImportanceLevels && filter.maxImportanceLevels.length > 0\n\t\t\t? inArray(memoriesTable.importance, [...filter.maxImportanceLevels])\n\t\t\t: undefined,\n\t);\n}\n\nexport async function countPruneMatches(\n\tdb: MnemocyteDatabase,\n\tfilter: PruneFilter,\n): Promise<number> {\n\tconst result = await db\n\t\t.select({ count: sql<number>`count(*)::int` })\n\t\t.from(memoriesTable)\n\t\t.where(pruneConditions(filter));\n\treturn result[0]?.count ?? 0;\n}\n\nexport async function pruneMemories(\n\tdb: MnemocyteDatabase,\n\tfilter: PruneFilter,\n): Promise<number> {\n\tconst result = await db\n\t\t.delete(memoriesTable)\n\t\t.where(pruneConditions(filter))\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\tProviderResilienceConfig,\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\tsignal?: AbortSignal;\n\tresilience?: ProviderResilienceConfig;\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\t\t...(input.signal === undefined ? {} : { signal: input.signal }),\n\t\t...(input.resilience === undefined ? {} : { resilience: input.resilience }),\n\t});\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\tcountPruneMatches,\n\tdeleteMemoriesForEntity,\n\tdeleteMemory,\n\tinsertMemory,\n\tlistMemories,\n\ttype PruneFilter,\n\tpruneMemories,\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\tImportanceLevel,\n\tMemory,\n\tMnemocyteClient,\n\tMnemocyteConfig,\n\tPruneInput,\n\tPruneResult,\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\tIMPORTANCE_RANK,\n\tisExpired,\n\tnormalizeTags,\n\trowToMemory,\n\tvalidatePruneInput,\n\tvalidateRecallInput,\n\tvalidateRememberInput,\n} from \"./shared.js\";\n\nconst IMPORTANCE_LEVELS: readonly ImportanceLevel[] = [\n\t\"low\",\n\t\"normal\",\n\t\"high\",\n\t\"critical\",\n];\n\nfunction importanceCeilingLevels(\n\tmax: ImportanceLevel,\n): readonly ImportanceLevel[] {\n\treturn IMPORTANCE_LEVELS.filter(\n\t\t(level) => IMPORTANCE_RANK[level] <= IMPORTANCE_RANK[max],\n\t);\n}\n\nfunction toPruneFilter(input: PruneInput): PruneFilter {\n\tconst filter: PruneFilter = {};\n\tif (input.entityId !== undefined) {\n\t\tfilter.entityId = input.entityId;\n\t}\n\tif (input.expired === true) {\n\t\tfilter.expired = true;\n\t}\n\tif (input.superseded === true) {\n\t\tfilter.superseded = true;\n\t}\n\tif (input.createdBefore !== undefined) {\n\t\tfilter.createdBefore = input.createdBefore;\n\t}\n\tif (input.notAccessedSince !== undefined) {\n\t\tfilter.notAccessedSince = input.notAccessedSince;\n\t}\n\tif (input.types !== undefined && input.types.length > 0) {\n\t\tfilter.types = input.types;\n\t}\n\tif (input.tags !== undefined && input.tags.length > 0) {\n\t\tfilter.tags = input.tags;\n\t}\n\tif (input.maxImportance !== undefined) {\n\t\tfilter.maxImportanceLevels = importanceCeilingLevels(input.maxImportance);\n\t}\n\treturn filter;\n}\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\t\t...(input.signal === undefined ? {} : { signal: input.signal }),\n\t\t\t\t\t...(config.provider === undefined\n\t\t\t\t\t\t? {}\n\t\t\t\t\t\t: { resilience: config.provider }),\n\t\t\t\t});\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\t...(input.signal === undefined ? {} : { signal: input.signal }),\n\t\t\t\t\t\t...(config.provider === undefined\n\t\t\t\t\t\t\t? {}\n\t\t\t\t\t\t\t: { resilience: config.provider }),\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\tconst recallInput = contextInputToRecallInput(contextInput);\n\t\t\t\t\t\t\treturn this.recall(\n\t\t\t\t\t\t\t\tinput.signal === undefined\n\t\t\t\t\t\t\t\t\t? recallInput\n\t\t\t\t\t\t\t\t\t: { ...recallInput, signal: input.signal },\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t},\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 prune(input: PruneInput): Promise<PruneResult> {\n\t\t\treturn observe(\n\t\t\t\tconfig,\n\t\t\t\t\"postgres\",\n\t\t\t\t\"prune\",\n\t\t\t\tinput.entityId === undefined ? {} : { entityId: input.entityId },\n\t\t\t\tasync () => {\n\t\t\t\t\tassertOpen();\n\t\t\t\t\tvalidatePruneInput(input);\n\t\t\t\t\tconst filter = toPruneFilter(input);\n\t\t\t\t\tconst dryRun = input.dryRun === true;\n\t\t\t\t\tif (dryRun) {\n\t\t\t\t\t\tconst matchedCount = await countPruneMatches(handle.db, filter);\n\t\t\t\t\t\treturn { matchedCount, deletedCount: 0, dryRun: true };\n\t\t\t\t\t}\n\t\t\t\t\tconst deletedCount = await pruneMemories(handle.db, filter);\n\t\t\t\t\treturn {\n\t\t\t\t\t\tmatchedCount: deletedCount,\n\t\t\t\t\t\tdeletedCount,\n\t\t\t\t\t\tdryRun: false,\n\t\t\t\t\t};\n\t\t\t\t},\n\t\t\t\t(result) => ({ count: result.deletedCount }),\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\n/**\n * Create a Mnemocyte client.\n *\n * When {@link MnemocyteConfig.databaseUrl} is provided, a Postgres-backed\n * client is returned (requires the `pgvector` extension and the bundled\n * migration applied). Otherwise an in-memory client is returned, intended\n * for tests, demos, and short-lived processes.\n *\n * The returned client owns any underlying resources (e.g. the Postgres\n * connection pool). Call {@link MnemocyteClient.close} when finished to\n * release them.\n *\n * @param config - Client configuration. {@link MnemocyteConfig.embedder} is required.\n * @returns A {@link MnemocyteClient} instance.\n * @throws {MnemocyteError} With code `\"CONFIG\"` if `embedder` is missing or invalid,\n * or `\"VALIDATION\"` if `databaseUrl` is provided but empty.\n *\n * @example Postgres-backed client\n * ```ts\n * const client = createMnemocyte({\n * databaseUrl: process.env.DATABASE_URL,\n * embedder,\n * });\n * ```\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.
|
|
3
|
+
"version": "0.0.8",
|
|
4
4
|
"description": "Persistent memory for TypeScript AI apps.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -40,14 +40,7 @@
|
|
|
40
40
|
"provenance": true
|
|
41
41
|
},
|
|
42
42
|
"engines": {
|
|
43
|
-
"node": ">=18"
|
|
44
|
-
},
|
|
45
|
-
"devEngines": {
|
|
46
|
-
"packageManager": {
|
|
47
|
-
"name": "pnpm",
|
|
48
|
-
"version": "^11.0.8",
|
|
49
|
-
"onFail": "download"
|
|
50
|
-
}
|
|
43
|
+
"node": ">=22.18"
|
|
51
44
|
},
|
|
52
45
|
"dependencies": {
|
|
53
46
|
"drizzle-orm": "^0.45.2",
|
|
@@ -64,16 +57,18 @@
|
|
|
64
57
|
"build": "tsdown src/index.ts",
|
|
65
58
|
"dev": "tsdown src/index.ts --watch",
|
|
66
59
|
"checktypes": "tsc --noEmit",
|
|
67
|
-
"test:exports": "
|
|
68
|
-
"test:observability": "
|
|
69
|
-
"test:
|
|
70
|
-
"test:
|
|
71
|
-
"test:
|
|
72
|
-
"
|
|
60
|
+
"test:exports": "tsdown src/index.ts && node test/package/exports.test.mjs && tsc -p test/package/tsconfig.json",
|
|
61
|
+
"test:observability": "tsdown src/index.ts && node test/observability/hooks.test.mjs",
|
|
62
|
+
"test:resilience": "tsdown src/index.ts && node test/resilience/resilience.test.mjs",
|
|
63
|
+
"test:prune": "tsdown src/index.ts && node test/prune/prune.test.mjs",
|
|
64
|
+
"test:retrieval": "tsdown src/index.ts && node test/retrieval/quality.test.mjs",
|
|
65
|
+
"test:context": "tsdown src/index.ts && node test/context/builder.test.mjs",
|
|
66
|
+
"test:integration": "tsdown src/index.ts && node test/integration/postgres.test.mjs",
|
|
67
|
+
"bench:retrieval": "tsdown src/index.ts && node test/benchmarks/retrieval.bench.mjs",
|
|
73
68
|
"lint": "biome lint --write",
|
|
74
69
|
"format": "biome format --write",
|
|
75
70
|
"db:generate": "drizzle-kit generate",
|
|
76
71
|
"db:migrate": "drizzle-kit migrate",
|
|
77
|
-
"pack:
|
|
72
|
+
"pack:check": "pnpm pack --pack-destination .pack-check"
|
|
78
73
|
}
|
|
79
74
|
}
|