mnemocyte 0.4.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +117 -136
- package/dist/embedders/index.mjs +1 -2
- package/dist/embedders/openai.d.mts +3 -8
- package/dist/embedders/openai.mjs +3 -4
- package/dist/embedders/openai.mjs.map +1 -1
- package/dist/{errors-B_7ZdjEO.mjs → errors-Dgt2nAs1.mjs} +2 -3
- package/dist/{errors-B_7ZdjEO.mjs.map → errors-Dgt2nAs1.mjs.map} +1 -1
- package/dist/index.d.mts +16 -20
- package/dist/index.mjs +180 -1302
- package/dist/index.mjs.map +1 -1
- package/dist/postgres-BDti0rrm.mjs +904 -0
- package/dist/postgres-BDti0rrm.mjs.map +1 -0
- package/dist/postgres-runtime-51fQVwqa.mjs +8 -0
- package/dist/postgres-runtime-51fQVwqa.mjs.map +1 -0
- package/dist/store-config-BZ4J1hrM.mjs +304 -0
- package/dist/store-config-BZ4J1hrM.mjs.map +1 -0
- package/dist/stores/drizzle.d.mts +13 -0
- package/dist/stores/drizzle.mjs +19 -0
- package/dist/stores/drizzle.mjs.map +1 -0
- package/dist/{types-DH0inEay.d.mts → types-DXYtLiOT.d.mts} +37 -16
- package/migrations/fresh-install.sql +43 -0
- package/package.json +24 -17
- package/dist/embedders/openai.d.mts.map +0 -1
- package/dist/index.d.mts.map +0 -1
- package/dist/types-DH0inEay.d.mts.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres-BDti0rrm.mjs","names":["timestampParam","insertMemoryRows","vectorSearchQuery","lexicalSearchQuery","getMemoryEmbeddingsQuery","deleteMemoryQuery","deleteMemoriesForEntityQuery","findDuplicatePairsQuery"],"sources":["../src/db/vector.ts","../src/db/schema.ts","../src/db/index.ts","../src/db/cancellation.ts","../src/db/queries/events.ts","../src/db/queries/memories.ts","../src/db/queries/meta.ts","../src/memory/postgres-records.ts","../src/memory/postgres.ts"],"sourcesContent":["export function formatVectorComponent(value: number): string {\n\tif (!Number.isFinite(value)) {\n\t\tthrow new Error(\"Vector values must be finite numbers.\");\n\t}\n\treturn Object.is(value, -0) ? \"0\" : value.toString();\n}\n","import { sql } from \"drizzle-orm\";\nimport {\n\ttype AnyPgColumn,\n\tcustomType,\n\tindex,\n\tinteger,\n\tjsonb,\n\tpgTable,\n\treal,\n\ttext,\n\ttimestamp,\n} from \"drizzle-orm/pg-core\";\nimport type { JsonObject } from \"../types.js\";\nimport { formatVectorComponent } from \"./vector.js\";\n\nconst vector = customType<{\n\tdata: number[];\n\tdriverData: string;\n\tconfig: { dimensions?: number };\n}>({\n\tdataType(config) {\n\t\tconst dimensions = config?.dimensions ?? 1536;\n\t\treturn `vector(${dimensions})`;\n\t},\n\ttoDriver(value) {\n\t\treturn `[${value.map(formatVectorComponent).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\").$type<JsonObject>().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\").references(\n\t\t\t(): AnyPgColumn => memoriesTable.id,\n\t\t),\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\tindex(\"mnemocyte_memories_embedding_hnsw_idx\").using(\n\t\t\t\"hnsw\",\n\t\t\ttable.embedding.op(\"vector_cosine_ops\"),\n\t\t),\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\").$type<JsonObject>().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 const metaTable = pgTable(\"mnemocyte_meta\", {\n\tkey: text(\"key\").primaryKey(),\n\tembeddingDimensions: integer(\"embedding_dimensions\").notNull(),\n\tembeddingModel: text(\"embedding_model\"),\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;\nexport type MetaRow = typeof metaTable.$inferSelect;\n","import { drizzle, type PostgresJsDatabase } from \"drizzle-orm/postgres-js\";\nimport postgres from \"postgres\";\nimport { parsePostgresDatabaseUrl } from \"../database-url.js\";\nimport * as schema from \"./schema.js\";\n\nexport type MnemocyteDatabase = PostgresJsDatabase<Record<string, unknown>>;\n\nexport interface DatabaseHandle {\n\tdb: MnemocyteDatabase;\n\tclose(): Promise<void>;\n}\n\nexport function createCallerOwnedDatabaseHandle<\n\tTSchema extends Record<string, unknown>,\n>(db: PostgresJsDatabase<TSchema>): DatabaseHandle {\n\treturn {\n\t\tdb,\n\t\tasync close() {},\n\t};\n}\n\ntype PostgresSslMode =\n\t| \"require\"\n\t| \"prefer\"\n\t| \"allow\"\n\t| \"verify-full\"\n\t| \"disable\";\n\ntype ValidPostgresSsl =\n\t| \"require\"\n\t| \"prefer\"\n\t| \"allow\"\n\t| \"verify-full\"\n\t| boolean\n\t| { rejectUnauthorized: false };\n\nfunction parseSslFromUrl(url: URL): ValidPostgresSsl | undefined {\n\tconst mode = url.searchParams.get(\"sslmode\") as PostgresSslMode | null;\n\tif (!mode || mode === \"disable\") return undefined;\n\n\tif (mode === \"require\" || mode === \"prefer\" || mode === \"allow\") {\n\t\treturn { rejectUnauthorized: false };\n\t}\n\n\tif (mode === \"verify-full\") return \"verify-full\";\n\n\treturn undefined;\n}\n\nexport function createDatabase(databaseUrl: string): DatabaseHandle {\n\tconst url = parsePostgresDatabaseUrl(databaseUrl);\n\tconst ssl = parseSslFromUrl(url);\n\n\tconst isPooler =\n\t\turl.port === \"6543\" || url.searchParams.get(\"pgbouncer\") === \"true\";\n\n\tconst client = postgres(databaseUrl, {\n\t\tmax: 10,\n\t\tidle_timeout: 20,\n\t\tconnect_timeout: 10,\n\t\t...(ssl ? { ssl } : {}),\n\t\t...(isPooler ? { prepare: false } : {}),\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","import type { SQL } from \"drizzle-orm\";\nimport { PgDialect } from \"drizzle-orm/pg-core\";\nimport type { Sql } from \"postgres\";\nimport { MnemocyteError } from \"../errors.js\";\nimport { throwIfAborted } from \"../resilience.js\";\nimport type { MnemocyteDatabase } from \"./index.js\";\n\nconst postgresDialect = new PgDialect();\n\ninterface CancelableQuery<T> extends PromiseLike<T> {\n\tcancel(): void;\n}\n\nasync function awaitCancelableQuery<T>(\n\tquery: CancelableQuery<T>,\n\tsignal: AbortSignal | undefined,\n): Promise<T> {\n\tthrowIfAborted(signal);\n\tif (!signal) {\n\t\treturn await query;\n\t}\n\tconst onAbort = (): void => {\n\t\tquery.cancel();\n\t};\n\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\ttry {\n\t\treturn await query;\n\t} catch (error) {\n\t\tif (signal.aborted) {\n\t\t\tthrow new MnemocyteError(\n\t\t\t\t\"Operation was aborted.\",\n\t\t\t\t\"ABORTED\",\n\t\t\t\tsignal.reason,\n\t\t\t);\n\t\t}\n\t\tthrow error;\n\t} finally {\n\t\tsignal.removeEventListener(\"abort\", onAbort);\n\t}\n}\n\nexport async function executeCancelableSql<T>(\n\tdb: MnemocyteDatabase,\n\tstatement: SQL,\n\tsignal: AbortSignal | undefined,\n): Promise<T> {\n\tconst query = postgresDialect.sqlToQuery(statement);\n\tconst client = (db as MnemocyteDatabase & { $client?: Sql }).$client;\n\tif (!client) {\n\t\tthrow new MnemocyteError(\n\t\t\t\"Cancelable Postgres query requires the postgres.js client.\",\n\t\t\t\"DB\",\n\t\t);\n\t}\n\treturn (await awaitCancelableQuery(\n\t\tclient.unsafe(query.sql, query.params as never[]),\n\t\tsignal,\n\t)) as T;\n}\n","import { sql } from \"drizzle-orm\";\nimport { MnemocyteError } from \"../../errors.js\";\nimport type { AuditLogCursor } from \"../../types.js\";\nimport { executeCancelableSql } from \"../cancellation.js\";\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\tbeforeCursor?: AuditLogCursor;\n\tafterCursor?: AuditLogCursor;\n}\n\nfunction timestampParam(value: Date) {\n\treturn sql`${value.toISOString()}::timestamptz`;\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 MnemocyteError(\"Event insert returned no rows.\", \"DB\");\n\t}\n\treturn inserted;\n}\n\nexport async function listEvents(\n\tdb: MnemocyteDatabase,\n\tfilter: EventFilter,\n\tsignal?: AbortSignal,\n): Promise<EventRow[]> {\n\treturn executeCancelableSql<EventRow[]>(\n\t\tdb,\n\t\tsql`\n\t\t\tSELECT\n\t\t\t\tid,\n\t\t\t\tentity_id AS \"entityId\",\n\t\t\t\tdescription,\n\t\t\t\tmetadata,\n\t\t\t\ttimestamp\n\t\t\tFROM mnemocyte_events\n\t\t\tWHERE entity_id = ${filter.entityId}\n\t\t\t\t${filter.before ? sql`AND timestamp < ${timestampParam(filter.before)}` : sql``}\n\t\t\t\t${filter.after ? sql`AND timestamp > ${timestampParam(filter.after)}` : sql``}\n\t\t\t\t${\n\t\t\t\t\tfilter.beforeCursor\n\t\t\t\t\t\t? sql`AND (timestamp, id) < (${timestampParam(filter.beforeCursor.timestamp)}, ${filter.beforeCursor.id})`\n\t\t\t\t\t\t: sql``\n\t\t\t\t}\n\t\t\t\t${\n\t\t\t\t\tfilter.afterCursor\n\t\t\t\t\t\t? sql`AND (timestamp, id) > (${timestampParam(filter.afterCursor.timestamp)}, ${filter.afterCursor.id})`\n\t\t\t\t\t\t: sql``\n\t\t\t\t}\n\t\t\tORDER BY timestamp DESC, id DESC\n\t\t\tLIMIT ${filter.limit ?? 50}\n\t\t`,\n\t\tsignal,\n\t);\n}\n","import {\n\tand,\n\tcount,\n\tcountDistinct,\n\teq,\n\tinArray,\n\tisNotNull,\n\tisNull,\n\tlt,\n\tor,\n\ttype SQL,\n\tsql,\n} from \"drizzle-orm\";\nimport type { ImportanceLevel, MemoryType } from \"../../types.js\";\nimport { executeCancelableSql } from \"../cancellation.js\";\nimport type { MnemocyteDatabase } from \"../index.js\";\nimport { type MemoryRow, memoriesTable, type NewMemoryRow } from \"../schema.js\";\nimport { formatVectorComponent } from \"../vector.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\tminVectorScore?: number;\n}\n\nexport interface LexicalSearchInput extends MemoryFilter {\n\tquery: string;\n\tlimit: number;\n}\n\nexport interface MemoryStatsCounts {\n\tmemoryCount: number;\n\tactiveMemoryCount: number;\n\texpiredMemoryCount: number;\n\tsupersededMemoryCount: number;\n}\n\nexport interface GuardedDeleteResult {\n\tmatchedCount: number;\n\tdeletedCount: number;\n\thasDependents: boolean;\n\tdeletedByEntity: Array<{ entityId: string; deletedCount: number }>;\n}\n\nexport interface GlobalMemoryStatsCounts extends MemoryStatsCounts {\n\tentityCount: number;\n}\n\nfunction vectorLiteral(embedding: readonly number[]): string {\n\treturn `[${embedding.map(formatVectorComponent).join(\",\")}]`;\n}\n\nfunction clampedVectorScore(embedding: string) {\n\tconst rawScore = sql`1 - (embedding <=> ${embedding}::vector)`;\n\treturn sql<number>`\n\t\tCASE\n\t\t\tWHEN ${rawScore} = 'NaN'::double precision\n\t\t\t\tOR ${rawScore} = 'Infinity'::double precision\n\t\t\t\tOR ${rawScore} = '-Infinity'::double precision\n\t\t\t\tTHEN 0::double precision\n\t\t\tELSE GREATEST(\n\t\t\t\t0::double precision,\n\t\t\t\tLEAST(1::double precision, ${rawScore})\n\t\t\t)\n\t\tEND\n\t`;\n}\n\ntype RawTimestamp = Date | string;\n\nexport type RecallMemoryRow = Omit<\n\tMemoryRow,\n\t| \"embedding\"\n\t| \"supersededAt\"\n\t| \"expiresAt\"\n\t| \"lastAccessedAt\"\n\t| \"createdAt\"\n\t| \"updatedAt\"\n> & {\n\tsupersededAt: RawTimestamp | null;\n\texpiresAt: RawTimestamp | null;\n\tlastAccessedAt: RawTimestamp | null;\n\tcreatedAt: RawTimestamp;\n\tupdatedAt: RawTimestamp;\n};\n\nexport type VectorSearchRow = RecallMemoryRow & { vectorScore: number };\n\nexport type LexicalSearchRow = RecallMemoryRow & { lexicalScore: number };\n\nfunction timestampParam(value: Date) {\n\treturn sql`${value.toISOString()}::timestamptz`;\n}\n\nfunction textArrayLiteral(values: readonly string[]) {\n\treturn sql`ARRAY[${sql.join(\n\t\tvalues.map((value) => sql`${value}`),\n\t\tsql`, `,\n\t)}]::text[]`;\n}\n\nfunction tagsContainAll(tags: readonly string[] | undefined) {\n\treturn tags && tags.length > 0\n\t\t? sql`${memoriesTable.tags} @> ${textArrayLiteral(tags)}`\n\t\t: undefined;\n}\n\nfunction rawTagsFilter(tags: readonly string[] | undefined) {\n\treturn tags && tags.length > 0\n\t\t? sql`AND tags @> ${textArrayLiteral(tags)}`\n\t\t: sql``;\n}\n\nfunction duplicateTagsFilter(tags: readonly string[] | undefined) {\n\treturn tags && tags.length > 0\n\t\t? sql`AND a.tags @> ${textArrayLiteral(tags)} AND b.tags @> ${textArrayLiteral(tags)}`\n\t\t: sql``;\n}\n\nfunction memoryStatsCountFields(now: Date) {\n\treturn {\n\t\tmemoryCount: count(),\n\t\tactiveMemoryCount: sql<number>`\n\t\t\t(count(*) FILTER (\n\t\t\t\tWHERE ${memoriesTable.supersededBy} IS NULL\n\t\t\t\t\tAND (${memoriesTable.expiresAt} IS NULL OR ${memoriesTable.expiresAt} > ${timestampParam(now)})\n\t\t\t))::int\n\t\t`.mapWith(Number),\n\t\texpiredMemoryCount: sql<number>`\n\t\t\t(count(*) FILTER (\n\t\t\t\tWHERE ${memoriesTable.expiresAt} IS NOT NULL\n\t\t\t\t\tAND ${memoriesTable.expiresAt} <= ${timestampParam(now)}\n\t\t\t))::int\n\t\t`.mapWith(Number),\n\t\tsupersededMemoryCount:\n\t\t\tsql<number>`(count(*) FILTER (WHERE ${memoriesTable.supersededBy} IS NOT NULL))::int`.mapWith(\n\t\t\t\tNumber,\n\t\t\t),\n\t};\n}\n\nfunction emptyMemoryStatsCounts(): MemoryStatsCounts {\n\treturn {\n\t\tmemoryCount: 0,\n\t\tactiveMemoryCount: 0,\n\t\texpiredMemoryCount: 0,\n\t\tsupersededMemoryCount: 0,\n\t};\n}\n\nexport async function insertMemories(\n\tdb: MnemocyteDatabase,\n\trows: NewMemoryRow[],\n): Promise<MemoryRow[]> {\n\tif (rows.length === 0) {\n\t\treturn [];\n\t}\n\treturn db.insert(memoriesTable).values(rows).returning();\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 getEntityMemoryStatsCounts(\n\tdb: MnemocyteDatabase,\n\tentityId: string,\n\tnow: Date,\n): Promise<MemoryStatsCounts> {\n\tconst rows = await db\n\t\t.select(memoryStatsCountFields(now))\n\t\t.from(memoriesTable)\n\t\t.where(eq(memoriesTable.entityId, entityId));\n\treturn rows[0] ?? emptyMemoryStatsCounts();\n}\n\nexport async function getGlobalMemoryStatsCounts(\n\tdb: MnemocyteDatabase,\n\tnow: Date,\n): Promise<GlobalMemoryStatsCounts> {\n\tconst rows = await db\n\t\t.select({\n\t\t\tentityCount: countDistinct(memoriesTable.entityId),\n\t\t\t...memoryStatsCountFields(now),\n\t\t})\n\t\t.from(memoriesTable);\n\treturn rows[0] ?? { entityCount: 0, ...emptyMemoryStatsCounts() };\n}\n\nexport async function deleteMemory(\n\tdb: MnemocyteDatabase,\n\tentityId: string,\n\tmemoryId: string,\n): Promise<GuardedDeleteResult> {\n\treturn deleteMemoriesWithDependentGuard(\n\t\tdb,\n\t\tand(eq(memoriesTable.entityId, entityId), eq(memoriesTable.id, memoryId)),\n\t);\n}\n\nexport async function deleteMemoriesForEntity(\n\tdb: MnemocyteDatabase,\n\tentityId: string,\n): Promise<GuardedDeleteResult> {\n\treturn deleteMemoriesWithDependentGuard(\n\t\tdb,\n\t\teq(memoriesTable.entityId, entityId),\n\t);\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\ttagsContainAll(filter.tags),\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\tsignal?: AbortSignal,\n): Promise<number> {\n\tconst conditions = pruneConditions(filter);\n\tconst rows = await executeCancelableSql<Array<{ count: number | string }>>(\n\t\tdb,\n\t\tsql`\n\t\t\tSELECT count(*)::int AS count\n\t\t\tFROM ${memoriesTable}\n\t\t\t${conditions ? sql`WHERE ${conditions}` : sql``}\n\t\t`,\n\t\tsignal,\n\t);\n\treturn Number(rows[0]?.count ?? 0);\n}\n\nexport async function pruneMemories(\n\tdb: MnemocyteDatabase,\n\tfilter: PruneFilter,\n\tsignal?: AbortSignal,\n): Promise<GuardedDeleteResult> {\n\tconst conditions = pruneConditions(filter);\n\treturn deleteMemoriesWithDependentGuard(db, conditions, signal);\n}\n\nasync function deleteMemoriesWithDependentGuard(\n\tdb: MnemocyteDatabase,\n\tconditions: SQL | undefined,\n\tsignal?: AbortSignal,\n): Promise<GuardedDeleteResult> {\n\tconst rows = await executeCancelableSql<\n\t\tArray<{\n\t\t\tmatchedCount: number | string;\n\t\t\tdeletedCount: number | string;\n\t\t\thasDependents: boolean;\n\t\t\tentityId: string | null;\n\t\t\tentityDeletedCount: number | string | null;\n\t\t}>\n\t>(\n\t\tdb,\n\t\tsql`\n\t\t\tWITH candidates AS MATERIALIZED (\n\t\t\t\tSELECT id, entity_id\n\t\t\t\tFROM ${memoriesTable}\n\t\t\t\t${conditions ? sql`WHERE ${conditions}` : sql``}\n\t\t\t),\n\t\t\tdependents AS MATERIALIZED (\n\t\t\t\tSELECT 1\n\t\t\t\tFROM ${memoriesTable} AS dependent\n\t\t\t\tINNER JOIN candidates AS target\n\t\t\t\t\tON dependent.superseded_by = target.id\n\t\t\t\tLIMIT 1\n\t\t\t),\n\t\t\tdeleted AS (\n\t\t\t\tDELETE FROM ${memoriesTable}\n\t\t\t\tWHERE ${memoriesTable.id} IN (SELECT id FROM candidates)\n\t\t\t\t\tAND NOT EXISTS (SELECT 1 FROM dependents)\n\t\t\t\tRETURNING id, entity_id\n\t\t\t),\n\t\t\tdeleted_counts AS (\n\t\t\t\tSELECT entity_id, count(*)::int AS deleted_count\n\t\t\t\tFROM deleted\n\t\t\t\tGROUP BY entity_id\n\t\t\t),\n\t\t\tsummary AS (\n\t\t\t\tSELECT\n\t\t\t\t\t(SELECT count(*)::int FROM candidates) AS matched_count,\n\t\t\t\t\t(SELECT count(*)::int FROM deleted) AS deleted_count,\n\t\t\t\t\tEXISTS (SELECT 1 FROM dependents) AS has_dependents\n\t\t\t)\n\t\t\tSELECT\n\t\t\t\tsummary.matched_count AS \"matchedCount\",\n\t\t\t\tsummary.deleted_count AS \"deletedCount\",\n\t\t\t\tsummary.has_dependents AS \"hasDependents\",\n\t\t\t\tdeleted_counts.entity_id AS \"entityId\",\n\t\t\t\tdeleted_counts.deleted_count AS \"entityDeletedCount\"\n\t\t\tFROM summary\n\t\t\tLEFT JOIN deleted_counts ON true\n\t\t\tORDER BY deleted_counts.entity_id\n\t\t`,\n\t\tsignal,\n\t);\n\tconst row = rows[0];\n\treturn {\n\t\tmatchedCount: Number(row?.matchedCount ?? 0),\n\t\tdeletedCount: Number(row?.deletedCount ?? 0),\n\t\thasDependents: row?.hasDependents === true,\n\t\tdeletedByEntity: rows.flatMap((detail) =>\n\t\t\tdetail.entityId === null\n\t\t\t\t? []\n\t\t\t\t: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tentityId: detail.entityId,\n\t\t\t\t\t\t\tdeletedCount: Number(detail.entityDeletedCount ?? 0),\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t),\n\t};\n}\n\nexport interface DuplicateSearchInput {\n\tentityId: string;\n\tthreshold: number;\n\tlimit: number;\n\ttypes?: readonly string[];\n\ttags?: readonly string[];\n\tincludeSuperseded?: boolean;\n\tincludeExpired?: boolean;\n}\n\nexport async function findDuplicatePairs(\n\tdb: MnemocyteDatabase,\n\tinput: DuplicateSearchInput,\n\tsignal?: AbortSignal,\n): Promise<Array<{ a: MemoryRow; b: MemoryRow; similarity: number }>> {\n\tconst rows = await executeCancelableSql<Array<Record<string, unknown>>>(\n\t\tdb,\n\t\tsql`\n\t\t\tSELECT\n\t\t\t\ta.id AS \"aId\",\n\t\t\t\ta.entity_id AS \"aEntityId\",\n\t\t\t\ta.content AS \"aContent\",\n\t\t\t\ta.type AS \"aType\",\n\t\t\t\ta.importance AS \"aImportance\",\n\t\t\t\ta.tags AS \"aTags\",\n\t\t\t\ta.source AS \"aSource\",\n\t\t\t\ta.metadata AS \"aMetadata\",\n\t\t\t\ta.confidence AS \"aConfidence\",\n\t\t\t\ta.embedding AS \"aEmbedding\",\n\t\t\t\ta.embedding_model AS \"aEmbeddingModel\",\n\t\t\t\ta.embedding_dimensions AS \"aEmbeddingDimensions\",\n\t\t\t\ta.superseded_by AS \"aSupersededBy\",\n\t\t\t\ta.superseded_at AS \"aSupersededAt\",\n\t\t\t\ta.expires_at AS \"aExpiresAt\",\n\t\t\t\ta.last_accessed_at AS \"aLastAccessedAt\",\n\t\t\t\ta.access_count AS \"aAccessCount\",\n\t\t\t\ta.created_at AS \"aCreatedAt\",\n\t\t\t\ta.updated_at AS \"aUpdatedAt\",\n\t\t\t\tb.id AS \"bId\",\n\t\t\t\tb.entity_id AS \"bEntityId\",\n\t\t\t\tb.content AS \"bContent\",\n\t\t\t\tb.type AS \"bType\",\n\t\t\t\tb.importance AS \"bImportance\",\n\t\t\t\tb.tags AS \"bTags\",\n\t\t\t\tb.source AS \"bSource\",\n\t\t\t\tb.metadata AS \"bMetadata\",\n\t\t\t\tb.confidence AS \"bConfidence\",\n\t\t\t\tb.embedding AS \"bEmbedding\",\n\t\t\t\tb.embedding_model AS \"bEmbeddingModel\",\n\t\t\t\tb.embedding_dimensions AS \"bEmbeddingDimensions\",\n\t\t\t\tb.superseded_by AS \"bSupersededBy\",\n\t\t\t\tb.superseded_at AS \"bSupersededAt\",\n\t\t\t\tb.expires_at AS \"bExpiresAt\",\n\t\t\t\tb.last_accessed_at AS \"bLastAccessedAt\",\n\t\t\t\tb.access_count AS \"bAccessCount\",\n\t\t\t\tb.created_at AS \"bCreatedAt\",\n\t\t\t\tb.updated_at AS \"bUpdatedAt\",\n\t\t\t\t1 - (a.embedding <=> b.embedding) AS \"similarity\"\n\t\t\tFROM mnemocyte_memories a\n\t\t\tJOIN mnemocyte_memories b\n\t\t\t\tON b.entity_id = a.entity_id\n\t\t\t\tAND a.id < b.id\n\t\t\t\tAND a.embedding IS NOT NULL\n\t\t\t\tAND b.embedding IS NOT NULL\n\t\t\tWHERE\n\t\t\t\ta.entity_id = ${input.entityId}\n\t\t\t\t${input.includeSuperseded ? sql`` : sql`AND a.superseded_by IS NULL AND b.superseded_by IS NULL`}\n\t\t\t\t${input.includeExpired ? sql`` : sql`AND (a.expires_at IS NULL OR a.expires_at > now()) AND (b.expires_at IS NULL OR b.expires_at > now())`}\n\t\t\t\t${\n\t\t\t\t\tinput.types && input.types.length > 0\n\t\t\t\t\t\t? sql`AND a.type IN (${sql.join(\n\t\t\t\t\t\t\t\tinput.types.map((type) => sql`${type}`),\n\t\t\t\t\t\t\t\tsql`, `,\n\t\t\t\t\t\t\t)}) AND b.type IN (${sql.join(\n\t\t\t\t\t\t\t\tinput.types.map((type) => sql`${type}`),\n\t\t\t\t\t\t\t\tsql`, `,\n\t\t\t\t\t\t\t)})`\n\t\t\t\t\t\t: sql``\n\t\t\t\t}\n\t\t\t\t${duplicateTagsFilter(input.tags)}\n\t\t\t\tAND 1 - (a.embedding <=> b.embedding) >= ${input.threshold}\n\t\t\tORDER BY \"similarity\" DESC\n\t\t\tLIMIT ${input.limit}\n\t\t`,\n\t\tsignal,\n\t);\n\treturn rows.map((row) => {\n\t\tconst a = {\n\t\t\tid: row.aId,\n\t\t\tentityId: row.aEntityId,\n\t\t\tcontent: row.aContent,\n\t\t\ttype: row.aType,\n\t\t\timportance: row.aImportance,\n\t\t\ttags: row.aTags,\n\t\t\tsource: row.aSource,\n\t\t\tmetadata: row.aMetadata,\n\t\t\tconfidence: row.aConfidence,\n\t\t\tembedding: row.aEmbedding,\n\t\t\tembeddingModel: row.aEmbeddingModel,\n\t\t\tembeddingDimensions: row.aEmbeddingDimensions,\n\t\t\tsupersededBy: row.aSupersededBy,\n\t\t\tsupersededAt: row.aSupersededAt,\n\t\t\texpiresAt: row.aExpiresAt,\n\t\t\tlastAccessedAt: row.aLastAccessedAt,\n\t\t\taccessCount: row.aAccessCount,\n\t\t\tcreatedAt: row.aCreatedAt,\n\t\t\tupdatedAt: row.aUpdatedAt,\n\t\t} as unknown as MemoryRow;\n\t\tconst b = {\n\t\t\tid: row.bId,\n\t\t\tentityId: row.bEntityId,\n\t\t\tcontent: row.bContent,\n\t\t\ttype: row.bType,\n\t\t\timportance: row.bImportance,\n\t\t\ttags: row.bTags,\n\t\t\tsource: row.bSource,\n\t\t\tmetadata: row.bMetadata,\n\t\t\tconfidence: row.bConfidence,\n\t\t\tembedding: row.bEmbedding,\n\t\t\tembeddingModel: row.bEmbeddingModel,\n\t\t\tembeddingDimensions: row.bEmbeddingDimensions,\n\t\t\tsupersededBy: row.bSupersededBy,\n\t\t\tsupersededAt: row.bSupersededAt,\n\t\t\texpiresAt: row.bExpiresAt,\n\t\t\tlastAccessedAt: row.bLastAccessedAt,\n\t\t\taccessCount: row.bAccessCount,\n\t\t\tcreatedAt: row.bCreatedAt,\n\t\t\tupdatedAt: row.bUpdatedAt,\n\t\t} as unknown as MemoryRow;\n\t\treturn {\n\t\t\ta,\n\t\t\tb,\n\t\t\tsimilarity: Number(row.similarity) || 0,\n\t\t};\n\t});\n}\n\nexport interface SupersedeRow {\n\tid: string;\n\ttags: string[];\n}\n\nexport async function loadConsolidationTargets(\n\tdb: MnemocyteDatabase,\n\tentityId: string,\n\tids: readonly string[],\n): Promise<Array<{ id: string; tags: string[]; supersededBy: string | null }>> {\n\tif (ids.length === 0) {\n\t\treturn [];\n\t}\n\tconst rows = await db\n\t\t.select({\n\t\t\tid: memoriesTable.id,\n\t\t\ttags: memoriesTable.tags,\n\t\t\tsupersededBy: memoriesTable.supersededBy,\n\t\t})\n\t\t.from(memoriesTable)\n\t\t.where(\n\t\t\tand(\n\t\t\t\teq(memoriesTable.entityId, entityId),\n\t\t\t\tinArray(memoriesTable.id, [...ids]),\n\t\t\t),\n\t\t);\n\treturn rows;\n}\n\nexport async function lockConsolidationMemories(\n\tdb: MnemocyteDatabase,\n\tentityId: string,\n\tsurvivorId: string,\n\tsupersededIds: readonly string[],\n): Promise<Array<{ id: string; tags: string[]; supersededBy: string | null }>> {\n\tconst ids = [...new Set([survivorId, ...supersededIds])].sort();\n\treturn db\n\t\t.select({\n\t\t\tid: memoriesTable.id,\n\t\t\ttags: memoriesTable.tags,\n\t\t\tsupersededBy: memoriesTable.supersededBy,\n\t\t})\n\t\t.from(memoriesTable)\n\t\t.where(\n\t\t\tand(eq(memoriesTable.entityId, entityId), inArray(memoriesTable.id, ids)),\n\t\t)\n\t\t.orderBy(memoriesTable.id)\n\t\t.for(\"update\");\n}\n\nexport async function markMemoriesSuperseded(\n\tdb: MnemocyteDatabase,\n\tparams: {\n\t\tsurvivorId: string;\n\t\tentityId: string;\n\t\tids: readonly string[];\n\t\tnow: Date;\n\t},\n): Promise<SupersedeRow[]> {\n\tif (params.ids.length === 0) {\n\t\treturn [];\n\t}\n\tconst result = await db\n\t\t.update(memoriesTable)\n\t\t.set({\n\t\t\tsupersededBy: params.survivorId,\n\t\t\tsupersededAt: params.now,\n\t\t\tupdatedAt: params.now,\n\t\t})\n\t\t.where(\n\t\t\tand(\n\t\t\t\teq(memoriesTable.entityId, params.entityId),\n\t\t\t\tinArray(memoriesTable.id, [...params.ids]),\n\t\t\t\tisNull(memoriesTable.supersededBy),\n\t\t\t),\n\t\t)\n\t\t.returning({ id: memoriesTable.id, tags: memoriesTable.tags });\n\treturn result;\n}\n\nexport async function setMemoryTags(\n\tdb: MnemocyteDatabase,\n\tparams: {\n\t\tentityId: string;\n\t\tmemoryId: string;\n\t\ttags: readonly string[];\n\t\tnow: Date;\n\t},\n): Promise<void> {\n\tawait db\n\t\t.update(memoriesTable)\n\t\t.set({ tags: [...params.tags], updatedAt: params.now })\n\t\t.where(\n\t\t\tand(\n\t\t\t\teq(memoriesTable.entityId, params.entityId),\n\t\t\t\teq(memoriesTable.id, params.memoryId),\n\t\t\t),\n\t\t);\n}\n\nexport async function markMemoriesAccessed(\n\tdb: MnemocyteDatabase,\n\tmemoryIds: readonly string[],\n): Promise<\n\tArray<{\n\t\tid: string;\n\t\tlastAccessedAt: Date | null;\n\t\taccessCount: number;\n\t\tupdatedAt: Date;\n\t}>\n> {\n\tconst now = new Date();\n\tif (memoryIds.length === 0) {\n\t\treturn [];\n\t}\n\treturn db\n\t\t.update(memoriesTable)\n\t\t.set({\n\t\t\tlastAccessedAt: now,\n\t\t\taccessCount: sql`${memoriesTable.accessCount} + 1`,\n\t\t\tupdatedAt: now,\n\t\t})\n\t\t.where(inArray(memoriesTable.id, [...memoryIds]))\n\t\t.returning({\n\t\t\tid: memoriesTable.id,\n\t\t\tlastAccessedAt: memoriesTable.lastAccessedAt,\n\t\t\taccessCount: memoriesTable.accessCount,\n\t\t\tupdatedAt: memoriesTable.updatedAt,\n\t\t});\n}\n\nexport async function getMemoryEmbeddings(\n\tdb: MnemocyteDatabase,\n\tmemoryIds: readonly string[],\n): Promise<Map<string, number[]>> {\n\tif (memoryIds.length === 0) {\n\t\treturn new Map();\n\t}\n\tconst rows = await db\n\t\t.select({\n\t\t\tid: memoriesTable.id,\n\t\t\tembedding: memoriesTable.embedding,\n\t\t})\n\t\t.from(memoriesTable)\n\t\t.where(inArray(memoriesTable.id, [...memoryIds]));\n\treturn new Map(\n\t\trows.flatMap((row) => (row.embedding ? [[row.id, row.embedding]] : [])),\n\t);\n}\n\nexport async function vectorSearch(\n\tdb: MnemocyteDatabase,\n\tinput: VectorSearchInput,\n): Promise<VectorSearchRow[]> {\n\tconst embedding = vectorLiteral(input.embedding);\n\tconst vectorScore = clampedVectorScore(embedding);\n\tconst minVectorScore = input.minVectorScore ?? 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_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\t${vectorScore} 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${rawTagsFilter(input.tags)}\n\t\t\t${input.before ? sql`AND created_at < ${timestampParam(input.before)}` : sql``}\n\t\t\t${input.after ? sql`AND created_at > ${timestampParam(input.after)}` : sql``}\n\t\t\tAND ${vectorScore} >= ${minVectorScore}\n\t\tORDER BY embedding <=> ${embedding}::vector\n\t\tLIMIT ${input.limit}\n\t`);\n\treturn rows as unknown as VectorSearchRow[];\n}\n\nexport async function lexicalSearch(\n\tdb: MnemocyteDatabase,\n\tinput: LexicalSearchInput,\n): Promise<LexicalSearchRow[]> {\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_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${rawTagsFilter(input.tags)}\n\t\t\t${input.before ? sql`AND created_at < ${timestampParam(input.before)}` : sql``}\n\t\t\t${input.after ? sql`AND created_at > ${timestampParam(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 LexicalSearchRow[];\n}\n","import { and, eq, isNull } from \"drizzle-orm\";\nimport type { MnemocyteDatabase } from \"../index.js\";\nimport { type MetaRow, memoriesTable, metaTable } from \"../schema.js\";\n\nexport const INSTALLATION_META_KEY = \"installation\";\n\nexport async function getInstallationMeta(\n\tdb: MnemocyteDatabase,\n): Promise<MetaRow | null> {\n\tconst rows = await db\n\t\t.select()\n\t\t.from(metaTable)\n\t\t.where(eq(metaTable.key, INSTALLATION_META_KEY))\n\t\t.limit(1);\n\treturn rows[0] ?? null;\n}\n\nexport async function getStoredEmbeddingModels(\n\tdb: MnemocyteDatabase,\n): Promise<string[]> {\n\tconst rows = await db\n\t\t.selectDistinct({ embeddingModel: memoriesTable.embeddingModel })\n\t\t.from(memoriesTable)\n\t\t.limit(2);\n\treturn rows.map((row) => row.embeddingModel);\n}\n\nexport async function recordInstallationEmbeddingModel(\n\tdb: MnemocyteDatabase,\n\tembeddingModel: string,\n): Promise<MetaRow | null> {\n\tconst rows = await db\n\t\t.update(metaTable)\n\t\t.set({ embeddingModel })\n\t\t.where(\n\t\t\tand(\n\t\t\t\teq(metaTable.key, INSTALLATION_META_KEY),\n\t\t\t\tisNull(metaTable.embeddingModel),\n\t\t\t),\n\t\t)\n\t\t.returning();\n\treturn rows[0] ?? null;\n}\n","import type { MemoryRow } from \"../db/schema.js\";\nimport type { ImportanceLevel, Memory, MemoryType } from \"../types.js\";\nimport { cloneJsonObject } from \"./json.js\";\n\ntype MemoryRowTimestamp = Date | string;\n\ntype MemoryLikeRow = Omit<\n\tMemoryRow,\n\t| \"embedding\"\n\t| \"supersededAt\"\n\t| \"expiresAt\"\n\t| \"lastAccessedAt\"\n\t| \"createdAt\"\n\t| \"updatedAt\"\n> & {\n\tsupersededAt: MemoryRowTimestamp | null;\n\texpiresAt: MemoryRowTimestamp | null;\n\tlastAccessedAt: MemoryRowTimestamp | null;\n\tcreatedAt: MemoryRowTimestamp;\n\tupdatedAt: MemoryRowTimestamp;\n};\n\nfunction toDate(value: MemoryRowTimestamp): Date {\n\treturn value instanceof Date ? value : new Date(value);\n}\n\nfunction toNullableDate(value: MemoryRowTimestamp | null): Date | null {\n\treturn value === null ? null : toDate(value);\n}\n\nexport function rowToMemory(row: MemoryLikeRow): 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: cloneJsonObject(row.metadata),\n\t\tconfidence: row.confidence,\n\t\tembeddingModel: row.embeddingModel,\n\t\tembeddingDimensions: row.embeddingDimensions,\n\t\tsupersededBy: row.supersededBy,\n\t\tsupersededAt: toNullableDate(row.supersededAt),\n\t\texpiresAt: toNullableDate(row.expiresAt),\n\t\tlastAccessedAt: toNullableDate(row.lastAccessedAt),\n\t\taccessCount: row.accessCount,\n\t\tcreatedAt: toDate(row.createdAt),\n\t\tupdatedAt: toDate(row.updatedAt),\n\t};\n}\n","import type { DatabaseHandle } from \"../db/index.js\";\nimport { insertEvent, listEvents } from \"../db/queries/events.js\";\nimport {\n\tcountPruneMatches,\n\tdeleteMemoriesForEntity as deleteMemoriesForEntityQuery,\n\tdeleteMemory as deleteMemoryQuery,\n\tfindDuplicatePairs as findDuplicatePairsQuery,\n\tgetEntityMemoryStatsCounts,\n\tgetGlobalMemoryStatsCounts,\n\tgetMemoryById,\n\tgetMemoryEmbeddings as getMemoryEmbeddingsQuery,\n\tinsertMemories as insertMemoryRows,\n\tlexicalSearch as lexicalSearchQuery,\n\tloadConsolidationTargets,\n\tlockConsolidationMemories,\n\tmarkMemoriesAccessed,\n\tmarkMemoriesSuperseded,\n\ttype PruneFilter,\n\tpruneMemories,\n\tsetMemoryTags,\n\tvectorSearch as vectorSearchQuery,\n} from \"../db/queries/memories.js\";\nimport {\n\tgetInstallationMeta,\n\tgetStoredEmbeddingModels,\n\trecordInstallationEmbeddingModel,\n} from \"../db/queries/meta.js\";\nimport type { EventRow, NewMemoryRow } from \"../db/schema.js\";\nimport { MnemocyteError } from \"../errors.js\";\nimport { throwIfAborted } from \"../resilience.js\";\nimport type {\n\tAuditEvent,\n\tEmbedder,\n\tEntityStats,\n\tGlobalStats,\n\tImportanceLevel,\n\tMnemocyteClient,\n\tMnemocyteConfig,\n} from \"../types.js\";\nimport { createMemoryClient } from \"./client-core.js\";\nimport {\n\tDEFAULT_AUDIT_LOG_LIMIT,\n\tDEFAULT_DUPLICATE_LIMIT,\n\tDEFAULT_DUPLICATE_THRESHOLD,\n\tIMPORTANCE_RANK,\n} from \"./defaults.js\";\nimport { memoryHasDependentsError } from \"./deletion.js\";\nimport { cloneJsonObject } from \"./json.js\";\nimport { rowToMemory } from \"./postgres-records.js\";\nimport { createEventId, type StoredMemory } from \"./records.js\";\nimport {\n\tassertPruneFilterHasSelector,\n\ttype MemoryStore,\n\ttype StoreConsolidateInput,\n\ttype StoreConsolidateResult,\n\ttype StoreDuplicatePair,\n\ttype StoreLexicalCandidate,\n\ttype StoreLexicalSearchInput,\n\ttype StoreVectorCandidate,\n\ttype StoreVectorSearchInput,\n\ttype ValidatedPruneFilter,\n} from \"./store.js\";\n\nconst IMPORTANCE_LEVELS: readonly ImportanceLevel[] = [\n\t\"low\",\n\t\"normal\",\n\t\"high\",\n\t\"critical\",\n];\n\nconst MIGRATION_ERROR_CODES = new Set([\"42P01\", \"42703\", \"42704\", \"42883\"]);\nconst CONSOLIDATION_SURVIVOR_FOREIGN_KEY =\n\t\"mnemocyte_memories_superseded_by_mnemocyte_memories_id_fk\";\n\nfunction rowToAuditEvent(row: EventRow): AuditEvent {\n\treturn {\n\t\tid: row.id,\n\t\tentityId: row.entityId,\n\t\tdescription: row.description,\n\t\tmetadata: cloneJsonObject(row.metadata),\n\t\ttimestamp: new Date(row.timestamp),\n\t};\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 hasPostgresErrorCode(error: unknown, code: string): boolean {\n\treturn (\n\t\ttypeof error === \"object\" &&\n\t\terror !== null &&\n\t\t\"code\" in error &&\n\t\terror.code === code\n\t);\n}\n\nfunction hasPostgresConstraintName(error: unknown, name: string): boolean {\n\treturn (\n\t\ttypeof error === \"object\" &&\n\t\terror !== null &&\n\t\t\"constraint_name\" in error &&\n\t\terror.constraint_name === name\n\t);\n}\n\nfunction getPostgresErrorCode(error: unknown): string | undefined {\n\treturn typeof error === \"object\" &&\n\t\terror !== null &&\n\t\t\"code\" in error &&\n\t\ttypeof (error as { code?: unknown }).code === \"string\"\n\t\t? (error as { code: string }).code\n\t\t: undefined;\n}\n\nfunction normalizePostgresError(error: unknown): MnemocyteError {\n\tif (error instanceof MnemocyteError) {\n\t\treturn error;\n\t}\n\tconst code = getPostgresErrorCode(error);\n\tif (code && MIGRATION_ERROR_CODES.has(code)) {\n\t\treturn new MnemocyteError(\n\t\t\t\"Postgres schema is missing or incompatible. Apply the bundled Mnemocyte migrations before using the Postgres backend.\",\n\t\t\t\"MIGRATION\",\n\t\t\terror,\n\t\t);\n\t}\n\treturn new MnemocyteError(\"Postgres operation failed.\", \"DB\", error);\n}\n\nasync function runPostgresOperation<T>(\n\toperation: () => Promise<T>,\n): Promise<T> {\n\ttry {\n\t\treturn await operation();\n\t} catch (error) {\n\t\tthrow normalizePostgresError(error);\n\t}\n}\n\nasync function runPostgresDeleteOperation<T>(\n\toperation: () => Promise<T>,\n): Promise<T> {\n\ttry {\n\t\treturn await operation();\n\t} catch (error) {\n\t\tif (error instanceof MnemocyteError) {\n\t\t\tthrow error;\n\t\t}\n\t\tif (\n\t\t\thasPostgresErrorCode(error, \"23503\") &&\n\t\t\thasPostgresConstraintName(error, CONSOLIDATION_SURVIVOR_FOREIGN_KEY)\n\t\t) {\n\t\t\tthrow memoryHasDependentsError(error);\n\t\t}\n\t\tthrow normalizePostgresError(error);\n\t}\n}\n\nfunction toPruneFilter(input: ValidatedPruneFilter): 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\nfunction toMemoryRow(memory: StoredMemory): NewMemoryRow {\n\treturn {\n\t\t...memory,\n\t\ttags: [...memory.tags],\n\t\tembedding: [...memory.embedding],\n\t};\n}\n\nexport function createPostgresStore(handle: DatabaseHandle): MemoryStore {\n\tlet schemaValidated = false;\n\tlet schemaValidationPromise: Promise<void> | undefined;\n\n\tasync function ensureEmbeddingCompatibility(\n\t\tembedder: Embedder,\n\t): Promise<void> {\n\t\tif (schemaValidated) {\n\t\t\treturn;\n\t\t}\n\t\tif (!schemaValidationPromise) {\n\t\t\tschemaValidationPromise = validateEmbeddingCompatibility(embedder).catch(\n\t\t\t\t(error: unknown) => {\n\t\t\t\t\tschemaValidationPromise = undefined;\n\t\t\t\t\tthrow error;\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\t\tawait schemaValidationPromise;\n\t}\n\n\tasync function validateEmbeddingCompatibility(\n\t\tembedder: Embedder,\n\t): Promise<void> {\n\t\tlet meta: Awaited<ReturnType<typeof getInstallationMeta>>;\n\t\ttry {\n\t\t\tmeta = await getInstallationMeta(handle.db);\n\t\t} catch (error) {\n\t\t\tif (\n\t\t\t\thasPostgresErrorCode(error, \"42P01\") ||\n\t\t\t\thasPostgresErrorCode(error, \"42703\")\n\t\t\t) {\n\t\t\t\tthrow new MnemocyteError(\n\t\t\t\t\t\"Postgres embedding metadata is missing or outdated. Apply the bundled migrations through 0002_add_embedding_model.sql, or render a fresh dimension-specific initial migration, before using embedding-dependent operations.\",\n\t\t\t\t\t\"MIGRATION\",\n\t\t\t\t\terror,\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow normalizePostgresError(error);\n\t\t}\n\t\tif (!meta) {\n\t\t\tthrow new MnemocyteError(\n\t\t\t\t'mnemocyte_meta is missing the \"installation\" row. Apply the bundled migrations, or render a fresh dimension-specific initial migration, before using embedding-dependent operations.',\n\t\t\t\t\"MIGRATION\",\n\t\t\t);\n\t\t}\n\t\tif (meta.embeddingDimensions !== embedder.dimensions) {\n\t\t\tthrow new MnemocyteError(\n\t\t\t\t`embedder.dimensions (${embedder.dimensions}) must match mnemocyte_meta.embedding_dimensions (${meta.embeddingDimensions}). Render and apply a migration for the selected embedding dimension, or configure an embedder that matches this installation.`,\n\t\t\t\t\"CONFIG\",\n\t\t\t);\n\t\t}\n\t\tlet installationModel = meta.embeddingModel;\n\t\tif (installationModel === null) {\n\t\t\ttry {\n\t\t\t\tconst storedModels = await getStoredEmbeddingModels(handle.db);\n\t\t\t\tif (storedModels.length > 1) {\n\t\t\t\t\tthrow new MnemocyteError(\n\t\t\t\t\t\t\"mnemocyte_meta.embedding_model is unset, but stored memories contain multiple embedding_model values. Re-embed or remove the mixed historical rows, then explicitly record the installation model before using embedding-dependent operations.\",\n\t\t\t\t\t\t\"MIGRATION\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tconst inferredModel = storedModels[0] ?? embedder.model;\n\t\t\t\tconst recorded = await recordInstallationEmbeddingModel(\n\t\t\t\t\thandle.db,\n\t\t\t\t\tinferredModel,\n\t\t\t\t);\n\t\t\t\tif (recorded) {\n\t\t\t\t\tinstallationModel = recorded.embeddingModel;\n\t\t\t\t} else {\n\t\t\t\t\tconst concurrentlyRecorded = await getInstallationMeta(handle.db);\n\t\t\t\t\tinstallationModel = concurrentlyRecorded?.embeddingModel ?? null;\n\t\t\t\t}\n\t\t\t} catch (error) {\n\t\t\t\tthrow normalizePostgresError(error);\n\t\t\t}\n\t\t\tif (installationModel === null) {\n\t\t\t\tthrow new MnemocyteError(\n\t\t\t\t\t\"mnemocyte_meta.embedding_model could not be recorded. Verify the installation metadata row and retry.\",\n\t\t\t\t\t\"MIGRATION\",\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t\tif (installationModel !== embedder.model) {\n\t\t\tthrow new MnemocyteError(\n\t\t\t\t`embedder.model (\"${embedder.model}\") must match mnemocyte_meta.embedding_model (\"${installationModel}\"). Configure the recorded model, or explicitly re-embed existing memories and update the installation metadata.`,\n\t\t\t\t\"CONFIG\",\n\t\t\t);\n\t\t}\n\t\tschemaValidated = true;\n\t}\n\n\treturn {\n\t\tbackend: \"postgres\",\n\t\tasync ensureSchema() {},\n\t\tensureEmbeddingCompatibility,\n\t\tasync insertMemories(memories) {\n\t\t\treturn runPostgresOperation(async () => {\n\t\t\t\tconst rows = await insertMemoryRows(\n\t\t\t\t\thandle.db,\n\t\t\t\t\tmemories.map(toMemoryRow),\n\t\t\t\t);\n\t\t\t\treturn rows.map(rowToMemory);\n\t\t\t});\n\t\t},\n\t\tasync vectorSearch(input: StoreVectorSearchInput) {\n\t\t\treturn runPostgresOperation(async () => {\n\t\t\t\tconst rows = await vectorSearchQuery(handle.db, input);\n\t\t\t\treturn rows.map(\n\t\t\t\t\t(row) =>\n\t\t\t\t\t\t({\n\t\t\t\t\t\t\tmemory: rowToMemory(row),\n\t\t\t\t\t\t\tvectorScore: row.vectorScore,\n\t\t\t\t\t\t}) satisfies StoreVectorCandidate,\n\t\t\t\t);\n\t\t\t});\n\t\t},\n\t\tasync lexicalSearch(input: StoreLexicalSearchInput) {\n\t\t\treturn runPostgresOperation(async () => {\n\t\t\t\tconst rows = await lexicalSearchQuery(handle.db, input);\n\t\t\t\treturn rows.map(\n\t\t\t\t\t(row) =>\n\t\t\t\t\t\t({\n\t\t\t\t\t\t\tmemory: rowToMemory(row),\n\t\t\t\t\t\t\tlexicalScore: row.lexicalScore,\n\t\t\t\t\t\t}) satisfies StoreLexicalCandidate,\n\t\t\t\t);\n\t\t\t});\n\t\t},\n\t\tasync getMemoryEmbeddings(memoryIds) {\n\t\t\treturn runPostgresOperation(() =>\n\t\t\t\tgetMemoryEmbeddingsQuery(handle.db, memoryIds),\n\t\t\t);\n\t\t},\n\t\tasync markMemoriesAccessed(memoryIds) {\n\t\t\treturn runPostgresOperation(async () => {\n\t\t\t\tconst rows = await markMemoriesAccessed(handle.db, memoryIds);\n\t\t\t\treturn rows.map((row) => {\n\t\t\t\t\tif (row.lastAccessedAt === null) {\n\t\t\t\t\t\tthrow new MnemocyteError(\n\t\t\t\t\t\t\t\"Postgres access update returned no timestamp.\",\n\t\t\t\t\t\t\t\"DB\",\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\t...row,\n\t\t\t\t\t\tlastAccessedAt: row.lastAccessedAt,\n\t\t\t\t\t};\n\t\t\t\t});\n\t\t\t});\n\t\t},\n\t\tasync deleteMemory(entityId, memoryId) {\n\t\t\treturn runPostgresDeleteOperation(async () => {\n\t\t\t\tconst result = await deleteMemoryQuery(handle.db, entityId, memoryId);\n\t\t\t\tif (result.hasDependents) {\n\t\t\t\t\tthrow memoryHasDependentsError();\n\t\t\t\t}\n\t\t\t\treturn result.deletedCount > 0;\n\t\t\t});\n\t\t},\n\t\tasync deleteMemoriesForEntity(entityId) {\n\t\t\treturn runPostgresDeleteOperation(async () => {\n\t\t\t\tconst result = await deleteMemoriesForEntityQuery(handle.db, entityId);\n\t\t\t\tif (result.hasDependents) {\n\t\t\t\t\tthrow memoryHasDependentsError();\n\t\t\t\t}\n\t\t\t\treturn result.deletedCount;\n\t\t\t});\n\t\t},\n\t\tasync prune(input, options) {\n\t\t\treturn runPostgresDeleteOperation(async () => {\n\t\t\t\tthrowIfAborted(options?.signal);\n\t\t\t\tassertPruneFilterHasSelector(input);\n\t\t\t\tconst filter = toPruneFilter(input);\n\t\t\t\tconst dryRun = input.dryRun === true;\n\t\t\t\tif (dryRun) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\tmatchedCount: await countPruneMatches(\n\t\t\t\t\t\t\thandle.db,\n\t\t\t\t\t\t\tfilter,\n\t\t\t\t\t\t\toptions?.signal,\n\t\t\t\t\t\t),\n\t\t\t\t\t\tdeletedCount: 0,\n\t\t\t\t\t\tdryRun: true,\n\t\t\t\t\t\tdeletedByEntity: [],\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t\tconst result = await pruneMemories(handle.db, filter, options?.signal);\n\t\t\t\tif (result.hasDependents) {\n\t\t\t\t\tthrow memoryHasDependentsError();\n\t\t\t\t}\n\t\t\t\treturn {\n\t\t\t\t\tmatchedCount: result.matchedCount,\n\t\t\t\t\tdeletedCount: result.deletedCount,\n\t\t\t\t\tdryRun: false,\n\t\t\t\t\tdeletedByEntity: result.deletedByEntity,\n\t\t\t\t};\n\t\t\t});\n\t\t},\n\t\tasync findDuplicatePairs(input, options) {\n\t\t\treturn runPostgresOperation(async () => {\n\t\t\t\tconst rows = await findDuplicatePairsQuery(\n\t\t\t\t\thandle.db,\n\t\t\t\t\t{\n\t\t\t\t\t\tentityId: input.entityId,\n\t\t\t\t\t\tthreshold: input.threshold ?? DEFAULT_DUPLICATE_THRESHOLD,\n\t\t\t\t\t\tlimit: input.limit ?? DEFAULT_DUPLICATE_LIMIT,\n\t\t\t\t\t\t...(input.types === undefined ? {} : { types: input.types }),\n\t\t\t\t\t\t...(input.tags === undefined ? {} : { tags: input.tags }),\n\t\t\t\t\t\t...(input.includeSuperseded === undefined\n\t\t\t\t\t\t\t? {}\n\t\t\t\t\t\t\t: { includeSuperseded: input.includeSuperseded }),\n\t\t\t\t\t\t...(input.includeExpired === undefined\n\t\t\t\t\t\t\t? {}\n\t\t\t\t\t\t\t: { includeExpired: input.includeExpired }),\n\t\t\t\t\t},\n\t\t\t\t\toptions?.signal,\n\t\t\t\t);\n\t\t\t\treturn rows.map(\n\t\t\t\t\t(row) =>\n\t\t\t\t\t\t({\n\t\t\t\t\t\t\ta: rowToMemory(row.a),\n\t\t\t\t\t\t\tb: rowToMemory(row.b),\n\t\t\t\t\t\t\tsimilarity: Math.max(0, Math.min(1, row.similarity)),\n\t\t\t\t\t\t}) satisfies StoreDuplicatePair,\n\t\t\t\t);\n\t\t\t});\n\t\t},\n\t\tasync addAuditEvents(events) {\n\t\t\treturn runPostgresOperation(async () => {\n\t\t\t\tfor (const event of events) {\n\t\t\t\t\tawait insertEvent(handle.db, {\n\t\t\t\t\t\tid: event.id,\n\t\t\t\t\t\tentityId: event.entityId,\n\t\t\t\t\t\tdescription: event.description,\n\t\t\t\t\t\tmetadata: cloneJsonObject(event.metadata),\n\t\t\t\t\t\ttimestamp: event.timestamp,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\t\tasync listAuditLog(input, options) {\n\t\t\treturn runPostgresOperation(async () => {\n\t\t\t\tconst rows = await listEvents(\n\t\t\t\t\thandle.db,\n\t\t\t\t\t{\n\t\t\t\t\t\tentityId: input.entityId,\n\t\t\t\t\t\tlimit: input.limit ?? DEFAULT_AUDIT_LOG_LIMIT,\n\t\t\t\t\t\t...(input.before === undefined ? {} : { before: input.before }),\n\t\t\t\t\t\t...(input.after === undefined ? {} : { after: input.after }),\n\t\t\t\t\t\t...(input.beforeCursor === undefined\n\t\t\t\t\t\t\t? {}\n\t\t\t\t\t\t\t: { beforeCursor: input.beforeCursor }),\n\t\t\t\t\t\t...(input.afterCursor === undefined\n\t\t\t\t\t\t\t? {}\n\t\t\t\t\t\t\t: { afterCursor: input.afterCursor }),\n\t\t\t\t\t},\n\t\t\t\t\toptions?.signal,\n\t\t\t\t);\n\t\t\t\treturn rows.map(rowToAuditEvent);\n\t\t\t});\n\t\t},\n\t\tasync getMemory(entityId, memoryId, options) {\n\t\t\treturn runPostgresOperation(async () => {\n\t\t\t\tthrowIfAborted(options?.signal);\n\t\t\t\tconst row = await getMemoryById(handle.db, entityId, memoryId);\n\t\t\t\tthrowIfAborted(options?.signal);\n\t\t\t\treturn row ? rowToMemory(row) : null;\n\t\t\t});\n\t\t},\n\t\tasync loadConsolidationTargets(entityId, ids, options) {\n\t\t\treturn runPostgresOperation(async () => {\n\t\t\t\tthrowIfAborted(options?.signal);\n\t\t\t\tconst targets = await loadConsolidationTargets(\n\t\t\t\t\thandle.db,\n\t\t\t\t\tentityId,\n\t\t\t\t\tids,\n\t\t\t\t);\n\t\t\t\tthrowIfAborted(options?.signal);\n\t\t\t\treturn targets;\n\t\t\t});\n\t\t},\n\t\tasync consolidate(\n\t\t\tinput: StoreConsolidateInput,\n\t\t\toptions,\n\t\t): Promise<StoreConsolidateResult> {\n\t\t\treturn runPostgresOperation(async () => {\n\t\t\t\tthrowIfAborted(options?.signal);\n\t\t\t\tconst newSupersededIds = await handle.db.transaction(async (tx) => {\n\t\t\t\t\tthrowIfAborted(options?.signal);\n\t\t\t\t\tconst lockedMemories = await lockConsolidationMemories(\n\t\t\t\t\t\ttx,\n\t\t\t\t\t\tinput.entityId,\n\t\t\t\t\t\tinput.survivorId,\n\t\t\t\t\t\tinput.supersededIds,\n\t\t\t\t\t);\n\t\t\t\t\tthrowIfAborted(options?.signal);\n\t\t\t\t\tconst survivor = lockedMemories.find(\n\t\t\t\t\t\t(memory) => memory.id === input.survivorId,\n\t\t\t\t\t);\n\t\t\t\t\tif (!survivor || survivor.supersededBy !== null) {\n\t\t\t\t\t\tthrow new MnemocyteError(\n\t\t\t\t\t\t\t\"Consolidation survivor changed before mutation.\",\n\t\t\t\t\t\t\t\"CONFLICT\",\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tconst targets = lockedMemories.filter(\n\t\t\t\t\t\t(memory) => memory.id !== input.survivorId,\n\t\t\t\t\t);\n\t\t\t\t\tif (\n\t\t\t\t\t\ttargets.some(\n\t\t\t\t\t\t\t(target) =>\n\t\t\t\t\t\t\t\ttarget.supersededBy !== null &&\n\t\t\t\t\t\t\t\ttarget.supersededBy !== input.survivorId,\n\t\t\t\t\t\t)\n\t\t\t\t\t) {\n\t\t\t\t\t\tthrow new MnemocyteError(\n\t\t\t\t\t\t\t\"Superseded memory already belongs to a different survivor.\",\n\t\t\t\t\t\t\t\"CONFLICT\",\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tconst activeIds = targets\n\t\t\t\t\t\t.filter((target) => target.supersededBy === null)\n\t\t\t\t\t\t.map((target) => target.id);\n\t\t\t\t\tconst updated = await markMemoriesSuperseded(tx, {\n\t\t\t\t\t\tsurvivorId: input.survivorId,\n\t\t\t\t\t\tentityId: input.entityId,\n\t\t\t\t\t\tids: activeIds,\n\t\t\t\t\t\tnow: input.now,\n\t\t\t\t\t});\n\t\t\t\t\tthrowIfAborted(options?.signal);\n\t\t\t\t\tconst ids = updated.map((row) => row.id);\n\t\t\t\t\tif (input.auditEnabled) {\n\t\t\t\t\t\tfor (const id of ids) {\n\t\t\t\t\t\t\tthrowIfAborted(options?.signal);\n\t\t\t\t\t\t\tawait insertEvent(tx, {\n\t\t\t\t\t\t\t\tid: createEventId(),\n\t\t\t\t\t\t\t\tentityId: input.entityId,\n\t\t\t\t\t\t\t\tdescription: \"memory.superseded\",\n\t\t\t\t\t\t\t\tmetadata: { memoryId: id, supersededBy: input.survivorId },\n\t\t\t\t\t\t\t\ttimestamp: input.now,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tthrowIfAborted(options?.signal);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (input.mergeTags && updated.length > 0) {\n\t\t\t\t\t\tconst mergedTags = new Set(survivor.tags);\n\t\t\t\t\t\tfor (const row of updated) {\n\t\t\t\t\t\t\tthrowIfAborted(options?.signal);\n\t\t\t\t\t\t\tfor (const tag of row.tags) {\n\t\t\t\t\t\t\t\tmergedTags.add(tag);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (mergedTags.size !== survivor.tags.length) {\n\t\t\t\t\t\t\tthrowIfAborted(options?.signal);\n\t\t\t\t\t\t\tawait setMemoryTags(tx, {\n\t\t\t\t\t\t\t\tentityId: input.entityId,\n\t\t\t\t\t\t\t\tmemoryId: input.survivorId,\n\t\t\t\t\t\t\t\ttags: [...mergedTags],\n\t\t\t\t\t\t\t\tnow: input.now,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tthrowIfAborted(options?.signal);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tthrowIfAborted(options?.signal);\n\t\t\t\t\treturn ids;\n\t\t\t\t});\n\t\t\t\treturn { supersededIds: newSupersededIds };\n\t\t\t});\n\t\t},\n\t\tasync stats(input, now) {\n\t\t\treturn runPostgresOperation(async () => {\n\t\t\t\tif (input?.entityId) {\n\t\t\t\t\tconst counts = await getEntityMemoryStatsCounts(\n\t\t\t\t\t\thandle.db,\n\t\t\t\t\t\tinput.entityId,\n\t\t\t\t\t\tnow,\n\t\t\t\t\t);\n\t\t\t\t\treturn {\n\t\t\t\t\t\tentityId: input.entityId,\n\t\t\t\t\t\t...counts,\n\t\t\t\t\t} satisfies EntityStats;\n\t\t\t\t}\n\t\t\t\treturn (await getGlobalMemoryStatsCounts(\n\t\t\t\t\thandle.db,\n\t\t\t\t\tnow,\n\t\t\t\t)) satisfies GlobalStats;\n\t\t\t});\n\t\t},\n\t\tasync close() {\n\t\t\treturn runPostgresOperation(() => handle.close());\n\t\t},\n\t};\n}\n\nexport function createPostgresClient(\n\tconfig: MnemocyteConfig,\n\thandle: DatabaseHandle,\n): MnemocyteClient {\n\treturn createMemoryClient(config, createPostgresStore(handle));\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { r as createDatabase, t as createPostgresStore } from "./postgres-BDti0rrm.mjs";
|
|
2
|
+
// src/memory/postgres-runtime.ts
|
|
3
|
+
function createPostgresStoreFromUrl(databaseUrl) {
|
|
4
|
+
return createPostgresStore(createDatabase(databaseUrl));
|
|
5
|
+
}
|
|
6
|
+
export { createPostgresStoreFromUrl };
|
|
7
|
+
|
|
8
|
+
//# sourceMappingURL=postgres-runtime-51fQVwqa.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres-runtime-51fQVwqa.mjs","names":[],"sources":["../src/memory/postgres-runtime.ts"],"sourcesContent":["import { createDatabase } from \"../db/index.js\";\nimport { createPostgresStore } from \"./postgres.js\";\nimport type { MemoryStore } from \"./store.js\";\n\nexport function createPostgresStoreFromUrl(databaseUrl: string): MemoryStore {\n\treturn createPostgresStore(createDatabase(databaseUrl));\n}\n"],"mappings":";;AAIA,SAAgB,2BAA2B,aAAkC;CAC5E,OAAO,oBAAoB,eAAe,WAAW,CAAC;AACvD"}
|
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
import { t as MnemocyteError } from "./errors-Dgt2nAs1.mjs";
|
|
2
|
+
// src/database-url.ts
|
|
3
|
+
function parsePostgresDatabaseUrl(databaseUrl) {
|
|
4
|
+
let url;
|
|
5
|
+
try {
|
|
6
|
+
url = new URL(databaseUrl);
|
|
7
|
+
} catch (error) {
|
|
8
|
+
throw new MnemocyteError("databaseUrl must be a valid Postgres connection URL.", "CONFIG", error);
|
|
9
|
+
}
|
|
10
|
+
if (url.protocol !== "postgres:" && url.protocol !== "postgresql:") throw new MnemocyteError("databaseUrl must use the postgres: or postgresql: protocol.", "CONFIG");
|
|
11
|
+
return url;
|
|
12
|
+
}
|
|
13
|
+
// src/resilience.ts
|
|
14
|
+
/**
|
|
15
|
+
* Default per-provider-call timeout. Disabled by default so that callers
|
|
16
|
+
* who do not configure {@link ProviderResilienceConfig.timeoutMs} are
|
|
17
|
+
* unaffected.
|
|
18
|
+
*/
|
|
19
|
+
const DEFAULT_TIMEOUT_MS = 0;
|
|
20
|
+
/** Default number of retry attempts on transient provider failures. */
|
|
21
|
+
const DEFAULT_RETRIES = 0;
|
|
22
|
+
/** Default base backoff delay used between retry attempts. */
|
|
23
|
+
const DEFAULT_BASE_DELAY_MS = 100;
|
|
24
|
+
/** Default ceiling for retry backoff delay. */
|
|
25
|
+
const DEFAULT_MAX_DELAY_MS = 2e3;
|
|
26
|
+
/**
|
|
27
|
+
* Throw a {@link MnemocyteError} with code `"ABORTED"` if `signal` is
|
|
28
|
+
* already aborted. Safe to call with `undefined`.
|
|
29
|
+
*/
|
|
30
|
+
function throwIfAborted(signal) {
|
|
31
|
+
if (signal?.aborted) throw new MnemocyteError("Operation was aborted.", "ABORTED", signal.reason);
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Heuristic default for whether an error should be retried.
|
|
35
|
+
*
|
|
36
|
+
* Conservative by design: only retries on common transient failure
|
|
37
|
+
* indicators (network errors, 5xx-ish messages, `ECONN*` etc.). Never
|
|
38
|
+
* retries on validation, configuration, or {@link MnemocyteError} of
|
|
39
|
+
* code `"VALIDATION"` / `"CONFIG"` / `"CONFLICT"` / `"ABORTED"`.
|
|
40
|
+
*/
|
|
41
|
+
function defaultShouldRetry(error) {
|
|
42
|
+
if (error instanceof MnemocyteError) {
|
|
43
|
+
if (error.code === "VALIDATION" || error.code === "CONFIG" || error.code === "CONFLICT" || error.code === "ABORTED") return false;
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
if (typeof error === "object" && error !== null && "status" in error && typeof error.status === "number" && [
|
|
47
|
+
429,
|
|
48
|
+
500,
|
|
49
|
+
502,
|
|
50
|
+
503,
|
|
51
|
+
504
|
|
52
|
+
].includes(error.status)) return true;
|
|
53
|
+
if (error instanceof Error) {
|
|
54
|
+
const message = error.message.toLowerCase();
|
|
55
|
+
if (message.includes("econn") || message.includes("etimedout") || message.includes("network") || message.includes("timeout") || message.includes("temporarily") || message.includes("rate limit") || message.includes("503") || message.includes("502") || message.includes("504") || message.includes("500")) return true;
|
|
56
|
+
}
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Compute the backoff delay for the given retry attempt, using exponential
|
|
61
|
+
* growth capped at {@link ProviderResilienceConfig.maxDelayMs}.
|
|
62
|
+
*
|
|
63
|
+
* `attempt` is 1-indexed: the delay before the first retry uses
|
|
64
|
+
* `attempt = 1`, before the second retry `attempt = 2`, etc.
|
|
65
|
+
*/
|
|
66
|
+
function computeDelayMs(attempt, baseDelayMs, maxDelayMs) {
|
|
67
|
+
const exponential = baseDelayMs * 2 ** (attempt - 1);
|
|
68
|
+
return Math.max(0, Math.min(maxDelayMs, exponential));
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Promise-based `setTimeout` that rejects with an `"ABORTED"`
|
|
72
|
+
* {@link MnemocyteError} if `signal` aborts while waiting.
|
|
73
|
+
*/
|
|
74
|
+
function delay(ms, signal) {
|
|
75
|
+
if (ms <= 0) {
|
|
76
|
+
throwIfAborted(signal);
|
|
77
|
+
return Promise.resolve();
|
|
78
|
+
}
|
|
79
|
+
return new Promise((resolve, reject) => {
|
|
80
|
+
const timer = setTimeout(() => {
|
|
81
|
+
signal?.removeEventListener("abort", onAbort);
|
|
82
|
+
resolve();
|
|
83
|
+
}, ms);
|
|
84
|
+
const onAbort = () => {
|
|
85
|
+
clearTimeout(timer);
|
|
86
|
+
reject(new MnemocyteError("Operation was aborted.", "ABORTED", signal?.reason));
|
|
87
|
+
};
|
|
88
|
+
if (signal) {
|
|
89
|
+
if (signal.aborted) {
|
|
90
|
+
clearTimeout(timer);
|
|
91
|
+
reject(new MnemocyteError("Operation was aborted.", "ABORTED", signal.reason));
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
function timeoutError(timeoutMs) {
|
|
99
|
+
return new MnemocyteError(`Provider call timed out after ${timeoutMs}ms.`, "TIMEOUT");
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Run one provider attempt with a signal linked to the caller's signal and
|
|
103
|
+
* Mnemocyte's configured timeout. Timeout aborts are actively propagated to
|
|
104
|
+
* providers that honor `AbortSignal`.
|
|
105
|
+
*/
|
|
106
|
+
function runAttempt(action, timeoutMs, signal) {
|
|
107
|
+
if (timeoutMs <= 0 && !signal) return action(void 0);
|
|
108
|
+
return new Promise((resolve, reject) => {
|
|
109
|
+
let settled = false;
|
|
110
|
+
const controller = new AbortController();
|
|
111
|
+
const timer = timeoutMs > 0 ? setTimeout(() => {
|
|
112
|
+
if (settled) return;
|
|
113
|
+
settled = true;
|
|
114
|
+
signal?.removeEventListener("abort", onAbort);
|
|
115
|
+
controller.abort(timeoutError(timeoutMs));
|
|
116
|
+
reject(timeoutError(timeoutMs));
|
|
117
|
+
}, timeoutMs) : void 0;
|
|
118
|
+
const onAbort = () => {
|
|
119
|
+
if (settled) return;
|
|
120
|
+
settled = true;
|
|
121
|
+
if (timer) clearTimeout(timer);
|
|
122
|
+
controller.abort(signal?.reason);
|
|
123
|
+
reject(new MnemocyteError("Operation was aborted.", "ABORTED", signal?.reason));
|
|
124
|
+
};
|
|
125
|
+
if (signal) {
|
|
126
|
+
if (signal.aborted) {
|
|
127
|
+
if (timer) clearTimeout(timer);
|
|
128
|
+
settled = true;
|
|
129
|
+
controller.abort(signal.reason);
|
|
130
|
+
reject(new MnemocyteError("Operation was aborted.", "ABORTED", signal.reason));
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
134
|
+
}
|
|
135
|
+
action(controller.signal).then((value) => {
|
|
136
|
+
if (settled) return;
|
|
137
|
+
settled = true;
|
|
138
|
+
if (timer) clearTimeout(timer);
|
|
139
|
+
signal?.removeEventListener("abort", onAbort);
|
|
140
|
+
resolve(value);
|
|
141
|
+
}, (error) => {
|
|
142
|
+
if (settled) return;
|
|
143
|
+
settled = true;
|
|
144
|
+
if (timer) clearTimeout(timer);
|
|
145
|
+
signal?.removeEventListener("abort", onAbort);
|
|
146
|
+
reject(error);
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Run `action` with timeout, retry, and abort handling derived from
|
|
152
|
+
* `options.resilience` and `options.signal`. Each retry attempt receives
|
|
153
|
+
* a fresh `AbortSignal` linked to the caller's signal — so callers may
|
|
154
|
+
* abort mid-retry and the in-flight attempt will cancel promptly if the
|
|
155
|
+
* underlying provider honours signals.
|
|
156
|
+
*
|
|
157
|
+
* Errors from {@link MnemocyteError} with code `"VALIDATION"` /
|
|
158
|
+
* `"CONFIG"` / `"CONFLICT"` / `"ABORTED"` are never retried.
|
|
159
|
+
*/
|
|
160
|
+
async function withResilience(action, options = {}) {
|
|
161
|
+
const config = options.resilience ?? {};
|
|
162
|
+
const timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
163
|
+
const retries = Math.max(0, config.retries ?? DEFAULT_RETRIES);
|
|
164
|
+
const baseDelayMs = Math.max(0, config.baseDelayMs ?? DEFAULT_BASE_DELAY_MS);
|
|
165
|
+
const maxDelayMs = Math.max(baseDelayMs, config.maxDelayMs ?? DEFAULT_MAX_DELAY_MS);
|
|
166
|
+
const shouldRetry = config.shouldRetry ?? defaultShouldRetry;
|
|
167
|
+
const externalSignal = options.signal;
|
|
168
|
+
throwIfAborted(externalSignal);
|
|
169
|
+
const maxAttempts = retries + 1;
|
|
170
|
+
let lastError;
|
|
171
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
|
|
172
|
+
throwIfAborted(externalSignal);
|
|
173
|
+
try {
|
|
174
|
+
return await runAttempt(action, timeoutMs, externalSignal);
|
|
175
|
+
} catch (error) {
|
|
176
|
+
lastError = error;
|
|
177
|
+
if (error instanceof MnemocyteError && error.code === "ABORTED") throw error;
|
|
178
|
+
if (attempt >= maxAttempts) throw error;
|
|
179
|
+
if (!shouldRetry(error, attempt)) throw error;
|
|
180
|
+
await delay(computeDelayMs(attempt, baseDelayMs, maxDelayMs), externalSignal);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
throw lastError;
|
|
184
|
+
}
|
|
185
|
+
// src/memory/json.ts
|
|
186
|
+
function invalidJsonValue(path, cause) {
|
|
187
|
+
return new MnemocyteError(`${path} must contain only JSON-compatible value data.`, "VALIDATION", cause);
|
|
188
|
+
}
|
|
189
|
+
function cloneJsonValue(value, path, ancestors) {
|
|
190
|
+
if (value === null || typeof value === "string" || typeof value === "boolean") return value;
|
|
191
|
+
if (typeof value === "number") {
|
|
192
|
+
if (!Number.isFinite(value)) throw invalidJsonValue(path);
|
|
193
|
+
return Object.is(value, -0) ? 0 : value;
|
|
194
|
+
}
|
|
195
|
+
if (typeof value !== "object") throw invalidJsonValue(path);
|
|
196
|
+
if (ancestors.has(value)) throw invalidJsonValue(path);
|
|
197
|
+
ancestors.add(value);
|
|
198
|
+
try {
|
|
199
|
+
if (Array.isArray(value)) {
|
|
200
|
+
if (Object.getOwnPropertySymbols(value).length > 0 || Object.keys(value).some((key) => !/^(0|[1-9]\d*)$/.test(key))) throw invalidJsonValue(path);
|
|
201
|
+
return Array.from({ length: value.length }, (_, index) => {
|
|
202
|
+
if (!Object.hasOwn(value, index)) throw invalidJsonValue(`${path}[${index}]`);
|
|
203
|
+
return cloneJsonValue(value[index], `${path}[${index}]`, ancestors);
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
const prototype = Object.getPrototypeOf(value);
|
|
207
|
+
if (prototype !== Object.prototype && prototype !== null) throw invalidJsonValue(path);
|
|
208
|
+
const descriptors = Object.getOwnPropertyDescriptors(value);
|
|
209
|
+
const entries = [];
|
|
210
|
+
for (const key of Reflect.ownKeys(descriptors)) {
|
|
211
|
+
if (typeof key !== "string") throw invalidJsonValue(path);
|
|
212
|
+
const descriptor = descriptors[key];
|
|
213
|
+
if (descriptor === void 0 || descriptor.enumerable !== true || !("value" in descriptor)) throw invalidJsonValue(`${path}.${key}`);
|
|
214
|
+
entries.push([key, cloneJsonValue(descriptor.value, `${path}.${key}`, ancestors)]);
|
|
215
|
+
}
|
|
216
|
+
return Object.fromEntries(entries);
|
|
217
|
+
} finally {
|
|
218
|
+
ancestors.delete(value);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
/** Validate and deep-clone a JSON-compatible object. */
|
|
222
|
+
function cloneJsonObject(value, path = "metadata") {
|
|
223
|
+
try {
|
|
224
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) throw invalidJsonValue(path);
|
|
225
|
+
return cloneJsonValue(value, path, /* @__PURE__ */ new Set());
|
|
226
|
+
} catch (error) {
|
|
227
|
+
if (error instanceof MnemocyteError) throw error;
|
|
228
|
+
throw invalidJsonValue(path, error);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
// src/memory/records.ts
|
|
232
|
+
function normalizeTags(tags) {
|
|
233
|
+
if (!tags) return [];
|
|
234
|
+
return [...new Set(tags.map((tag) => tag.trim()).filter(Boolean))];
|
|
235
|
+
}
|
|
236
|
+
function createId() {
|
|
237
|
+
return `mem_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;
|
|
238
|
+
}
|
|
239
|
+
/** Generate a unique audit-event id (`evt_*`). */
|
|
240
|
+
function createEventId() {
|
|
241
|
+
return `evt_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;
|
|
242
|
+
}
|
|
243
|
+
function cloneMemory(memory) {
|
|
244
|
+
return {
|
|
245
|
+
id: memory.id,
|
|
246
|
+
entityId: memory.entityId,
|
|
247
|
+
content: memory.content,
|
|
248
|
+
type: memory.type,
|
|
249
|
+
importance: memory.importance,
|
|
250
|
+
tags: [...memory.tags],
|
|
251
|
+
source: memory.source,
|
|
252
|
+
metadata: cloneJsonObject(memory.metadata),
|
|
253
|
+
confidence: memory.confidence,
|
|
254
|
+
embeddingModel: memory.embeddingModel,
|
|
255
|
+
embeddingDimensions: memory.embeddingDimensions,
|
|
256
|
+
supersededBy: memory.supersededBy,
|
|
257
|
+
supersededAt: memory.supersededAt ? new Date(memory.supersededAt) : null,
|
|
258
|
+
expiresAt: memory.expiresAt ? new Date(memory.expiresAt) : null,
|
|
259
|
+
lastAccessedAt: memory.lastAccessedAt ? new Date(memory.lastAccessedAt) : null,
|
|
260
|
+
accessCount: memory.accessCount,
|
|
261
|
+
createdAt: new Date(memory.createdAt),
|
|
262
|
+
updatedAt: new Date(memory.updatedAt)
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
// src/memory/defaults.ts
|
|
266
|
+
const DEFAULT_TYPE = "fact";
|
|
267
|
+
const DEFAULT_IMPORTANCE = "normal";
|
|
268
|
+
/**
|
|
269
|
+
* Ordering of {@link ImportanceLevel} from least to most important. Used
|
|
270
|
+
* by `prune({ maxImportance })` to compare a memory's importance against
|
|
271
|
+
* the caller-supplied ceiling.
|
|
272
|
+
*/
|
|
273
|
+
const IMPORTANCE_RANK = {
|
|
274
|
+
low: 0,
|
|
275
|
+
normal: 1,
|
|
276
|
+
high: 2,
|
|
277
|
+
critical: 3
|
|
278
|
+
};
|
|
279
|
+
/** Default cosine-similarity threshold for {@link FindDuplicatesInput}. */
|
|
280
|
+
const DEFAULT_DUPLICATE_THRESHOLD = .95;
|
|
281
|
+
// src/memory/store.ts
|
|
282
|
+
function hasPruneSelector(filter) {
|
|
283
|
+
return filter.entityId !== void 0 || filter.expired === true || filter.superseded === true || filter.createdBefore !== void 0 || filter.notAccessedSince !== void 0 || filter.types !== void 0 && filter.types.length > 0 || filter.tags !== void 0 && filter.tags.length > 0 || filter.maxImportance !== void 0;
|
|
284
|
+
}
|
|
285
|
+
function assertPruneFilterHasSelector(filter) {
|
|
286
|
+
if (!hasPruneSelector(filter)) throw new MnemocyteError("prune requires at least one selector (entityId, expired, superseded, createdBefore, notAccessedSince, types, tags, or maxImportance).", "VALIDATION");
|
|
287
|
+
}
|
|
288
|
+
// src/memory/deletion.ts
|
|
289
|
+
function memoryHasDependentsError(cause) {
|
|
290
|
+
return new MnemocyteError("Memory cannot be deleted while other memories reference it as their consolidation survivor.", "CONFLICT", cause);
|
|
291
|
+
}
|
|
292
|
+
// src/memory/store-config.ts
|
|
293
|
+
const MEMORY_STORE_CONFIG = Symbol.for("mnemocyte.memory-store-config");
|
|
294
|
+
function createMnemocyteStoreConfig(store) {
|
|
295
|
+
return Object.freeze({ [MEMORY_STORE_CONFIG]: store });
|
|
296
|
+
}
|
|
297
|
+
function unwrapMnemocyteStoreConfig(config) {
|
|
298
|
+
const candidate = config;
|
|
299
|
+
if (typeof candidate !== "object" || candidate === null || !(MEMORY_STORE_CONFIG in candidate)) throw new MnemocyteError("store must be created by a supported Mnemocyte store adapter.", "CONFIG");
|
|
300
|
+
return candidate[MEMORY_STORE_CONFIG];
|
|
301
|
+
}
|
|
302
|
+
export { DEFAULT_DUPLICATE_THRESHOLD as a, IMPORTANCE_RANK as c, createId as d, normalizeTags as f, parsePostgresDatabaseUrl as g, withResilience as h, assertPruneFilterHasSelector as i, cloneMemory as l, throwIfAborted as m, unwrapMnemocyteStoreConfig as n, DEFAULT_IMPORTANCE as o, cloneJsonObject as p, memoryHasDependentsError as r, DEFAULT_TYPE as s, createMnemocyteStoreConfig as t, createEventId as u };
|
|
303
|
+
|
|
304
|
+
//# sourceMappingURL=store-config-BZ4J1hrM.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store-config-BZ4J1hrM.mjs","names":[],"sources":["../src/database-url.ts","../src/resilience.ts","../src/memory/json.ts","../src/memory/records.ts","../src/memory/defaults.ts","../src/memory/store.ts","../src/memory/deletion.ts","../src/memory/store-config.ts"],"sourcesContent":["import { MnemocyteError } from \"./errors.js\";\n\nexport function parsePostgresDatabaseUrl(databaseUrl: string): URL {\n\tlet url: URL;\n\ttry {\n\t\turl = new URL(databaseUrl);\n\t} catch (error) {\n\t\tthrow new MnemocyteError(\n\t\t\t\"databaseUrl must be a valid Postgres connection URL.\",\n\t\t\t\"CONFIG\",\n\t\t\terror,\n\t\t);\n\t}\n\tif (url.protocol !== \"postgres:\" && url.protocol !== \"postgresql:\") {\n\t\tthrow new MnemocyteError(\n\t\t\t\"databaseUrl must use the postgres: or postgresql: protocol.\",\n\t\t\t\"CONFIG\",\n\t\t);\n\t}\n\treturn url;\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 * 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\"` / `\"CONFLICT\"` / `\"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 === \"CONFLICT\" ||\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 (\n\t\ttypeof error === \"object\" &&\n\t\terror !== null &&\n\t\t\"status\" in error &&\n\t\ttypeof (error as { status?: unknown }).status === \"number\" &&\n\t\t[429, 500, 502, 503, 504].includes((error as { status: number }).status)\n\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\nfunction timeoutError(timeoutMs: number): MnemocyteError {\n\treturn new MnemocyteError(\n\t\t`Provider call timed out after ${timeoutMs}ms.`,\n\t\t\"TIMEOUT\",\n\t);\n}\n\n/**\n * Run one provider attempt with a signal linked to the caller's signal and\n * Mnemocyte's configured timeout. Timeout aborts are actively propagated to\n * providers that honor `AbortSignal`.\n */\nfunction runAttempt<T>(\n\taction: (signal: AbortSignal | undefined) => Promise<T>,\n\ttimeoutMs: number,\n\tsignal: AbortSignal | undefined,\n): Promise<T> {\n\tif (timeoutMs <= 0 && !signal) {\n\t\treturn action(undefined);\n\t}\n\treturn new Promise<T>((resolve, reject) => {\n\t\tlet settled = false;\n\t\tconst controller = new AbortController();\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\tcontroller.abort(timeoutError(timeoutMs));\n\t\t\t\t\t\treject(timeoutError(timeoutMs));\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\tcontroller.abort(signal?.reason);\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\tcontroller.abort(signal.reason);\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\taction(controller.signal).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\"` / `\"CONFLICT\"` / `\"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 runAttempt(action, timeoutMs, externalSignal);\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 { MnemocyteError } from \"../errors.js\";\nimport type { JsonObject, JsonValue } from \"../types.js\";\n\ndeclare const ownedJsonObject: unique symbol;\n\n/** Internal marker for a JSON object that Mnemocyte has validated and cloned. */\nexport type OwnedJsonObject = JsonObject & {\n\treadonly [ownedJsonObject]: true;\n};\n\nfunction invalidJsonValue(path: string, cause?: unknown): MnemocyteError {\n\treturn new MnemocyteError(\n\t\t`${path} must contain only JSON-compatible value data.`,\n\t\t\"VALIDATION\",\n\t\tcause,\n\t);\n}\n\nfunction cloneJsonValue(\n\tvalue: unknown,\n\tpath: string,\n\tancestors: Set<object>,\n): JsonValue {\n\tif (\n\t\tvalue === null ||\n\t\ttypeof value === \"string\" ||\n\t\ttypeof value === \"boolean\"\n\t) {\n\t\treturn value;\n\t}\n\tif (typeof value === \"number\") {\n\t\tif (!Number.isFinite(value)) {\n\t\t\tthrow invalidJsonValue(path);\n\t\t}\n\t\treturn Object.is(value, -0) ? 0 : value;\n\t}\n\tif (typeof value !== \"object\") {\n\t\tthrow invalidJsonValue(path);\n\t}\n\tif (ancestors.has(value)) {\n\t\tthrow invalidJsonValue(path);\n\t}\n\n\tancestors.add(value);\n\ttry {\n\t\tif (Array.isArray(value)) {\n\t\t\tif (\n\t\t\t\tObject.getOwnPropertySymbols(value).length > 0 ||\n\t\t\t\tObject.keys(value).some((key) => !/^(0|[1-9]\\d*)$/.test(key))\n\t\t\t) {\n\t\t\t\tthrow invalidJsonValue(path);\n\t\t\t}\n\t\t\treturn Array.from({ length: value.length }, (_, index) => {\n\t\t\t\tif (!Object.hasOwn(value, index)) {\n\t\t\t\t\tthrow invalidJsonValue(`${path}[${index}]`);\n\t\t\t\t}\n\t\t\t\treturn cloneJsonValue(value[index], `${path}[${index}]`, ancestors);\n\t\t\t});\n\t\t}\n\n\t\tconst prototype = Object.getPrototypeOf(value);\n\t\tif (prototype !== Object.prototype && prototype !== null) {\n\t\t\tthrow invalidJsonValue(path);\n\t\t}\n\t\tconst descriptors = Object.getOwnPropertyDescriptors(value);\n\t\tconst entries: Array<[string, JsonValue]> = [];\n\t\tfor (const key of Reflect.ownKeys(descriptors)) {\n\t\t\tif (typeof key !== \"string\") {\n\t\t\t\tthrow invalidJsonValue(path);\n\t\t\t}\n\t\t\tconst descriptor = descriptors[key];\n\t\t\tif (\n\t\t\t\tdescriptor === undefined ||\n\t\t\t\tdescriptor.enumerable !== true ||\n\t\t\t\t!(\"value\" in descriptor)\n\t\t\t) {\n\t\t\t\tthrow invalidJsonValue(`${path}.${key}`);\n\t\t\t}\n\t\t\tentries.push([\n\t\t\t\tkey,\n\t\t\t\tcloneJsonValue(descriptor.value, `${path}.${key}`, ancestors),\n\t\t\t]);\n\t\t}\n\t\treturn Object.fromEntries(entries);\n\t} finally {\n\t\tancestors.delete(value);\n\t}\n}\n\n/** Validate and deep-clone a JSON-compatible object. */\nexport function cloneJsonObject(\n\tvalue: unknown,\n\tpath = \"metadata\",\n): OwnedJsonObject {\n\ttry {\n\t\tif (value === null || typeof value !== \"object\" || Array.isArray(value)) {\n\t\t\tthrow invalidJsonValue(path);\n\t\t}\n\t\treturn cloneJsonValue(value, path, new Set()) as OwnedJsonObject;\n\t} catch (error) {\n\t\tif (error instanceof MnemocyteError) {\n\t\t\tthrow error;\n\t\t}\n\t\tthrow invalidJsonValue(path, error);\n\t}\n}\n","import type { Memory } from \"../types.js\";\nimport { cloneJsonObject } from \"./json.js\";\n\nexport interface StoredMemory extends Memory {\n\tembedding: number[];\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\n/** Generate a unique audit-event id (`evt_*`). */\nexport function createEventId(): string {\n\treturn `evt_${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;\n}\n\nexport function cloneMemory(memory: Memory): Memory {\n\treturn {\n\t\tid: memory.id,\n\t\tentityId: memory.entityId,\n\t\tcontent: memory.content,\n\t\ttype: memory.type,\n\t\timportance: memory.importance,\n\t\ttags: [...memory.tags],\n\t\tsource: memory.source,\n\t\tmetadata: cloneJsonObject(memory.metadata),\n\t\tconfidence: memory.confidence,\n\t\tembeddingModel: memory.embeddingModel,\n\t\tembeddingDimensions: memory.embeddingDimensions,\n\t\tsupersededBy: memory.supersededBy,\n\t\tsupersededAt: memory.supersededAt ? new Date(memory.supersededAt) : null,\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\taccessCount: memory.accessCount,\n\t\tcreatedAt: new Date(memory.createdAt),\n\t\tupdatedAt: new Date(memory.updatedAt),\n\t};\n}\n","import type {\n\tFindDuplicatesInput,\n\tImportanceLevel,\n\tMemoryType,\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\n/** Default cosine-similarity threshold for {@link FindDuplicatesInput}. */\nexport const DEFAULT_DUPLICATE_THRESHOLD = 0.95;\n/** Default cap on the number of duplicate pairs returned. */\nexport const DEFAULT_DUPLICATE_LIMIT = 100;\n/** Default cap on audit-log entries returned per `listAuditLog`. */\nexport const DEFAULT_AUDIT_LOG_LIMIT = 50;\n","import { MnemocyteError } from \"../errors.js\";\nimport type {\n\tAuditEvent,\n\tEmbedder,\n\tEntityStats,\n\tFindDuplicatesInput,\n\tGlobalStats,\n\tImportanceLevel,\n\tListAuditLogInput,\n\tMemory,\n\tMemoryType,\n\tMnemocyteBackend,\n\tPruneResult,\n\tRecallInput,\n} from \"../types.js\";\nimport type { StoredMemory } from \"./records.js\";\n\nexport interface StoreVectorSearchInput extends Omit<RecallInput, \"minScore\"> {\n\tembedding: readonly number[];\n\tlimit: number;\n\tminVectorScore?: number;\n}\n\nexport interface StoreLexicalSearchInput extends RecallInput {\n\tlimit: number;\n}\n\nexport interface StoreVectorCandidate {\n\tmemory: Memory;\n\t/** Finite cosine component clamped to the inclusive range `[0, 1]`. */\n\tvectorScore: number;\n}\n\nexport interface StoreLexicalCandidate {\n\tmemory: Memory;\n\tlexicalScore: number;\n}\n\nexport interface StoreDuplicatePair {\n\ta: Memory;\n\tb: Memory;\n\tsimilarity: number;\n}\n\nexport interface StoreAccessUpdate {\n\tid: string;\n\tlastAccessedAt: Date;\n\taccessCount: number;\n\tupdatedAt: Date;\n}\n\nexport interface StorePruneEntityDeletion {\n\tentityId: string;\n\tdeletedCount: number;\n}\n\nexport interface StorePruneResult extends PruneResult {\n\tdeletedByEntity: readonly StorePruneEntityDeletion[];\n}\n\nexport interface StoreConsolidationTarget {\n\tid: string;\n\ttags: readonly string[];\n\tsupersededBy: string | null;\n}\n\nexport interface StoreConsolidateInput {\n\tentityId: string;\n\tsurvivorId: string;\n\tsupersededIds: readonly string[];\n\tmergeTags: boolean;\n\tnow: Date;\n\tauditEnabled: boolean;\n}\n\nexport interface StoreConsolidateResult {\n\tsupersededIds: readonly string[];\n}\n\nexport interface StoreOperationOptions {\n\tsignal?: AbortSignal;\n}\n\nexport interface ValidatedPruneFilter {\n\treadonly entityId?: string;\n\treadonly expired?: true;\n\treadonly superseded?: true;\n\treadonly createdBefore?: Date;\n\treadonly notAccessedSince?: Date;\n\treadonly types?: readonly MemoryType[];\n\treadonly tags?: readonly string[];\n\treadonly maxImportance?: ImportanceLevel;\n\treadonly dryRun: boolean;\n}\n\nexport function hasPruneSelector(filter: ValidatedPruneFilter): boolean {\n\treturn (\n\t\tfilter.entityId !== undefined ||\n\t\tfilter.expired === true ||\n\t\tfilter.superseded === true ||\n\t\tfilter.createdBefore !== undefined ||\n\t\tfilter.notAccessedSince !== undefined ||\n\t\t(filter.types !== undefined && filter.types.length > 0) ||\n\t\t(filter.tags !== undefined && filter.tags.length > 0) ||\n\t\tfilter.maxImportance !== undefined\n\t);\n}\n\nexport function assertPruneFilterHasSelector(\n\tfilter: ValidatedPruneFilter,\n): void {\n\tif (!hasPruneSelector(filter)) {\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 * Internal storage adapter boundary used by the shared client orchestration.\n *\n * This is intentionally not exported from the public package root in 0.3.x.\n * The public adapter surface is reserved for the later `drizzleStore(db)` line.\n *\n * Every method is unconditional. There is intentionally no capability-flag\n * surface, and adapters do not declare capabilities before shared orchestration\n * calls a method.\n *\n * Deleting a referenced consolidation survivor through `deleteMemory`,\n * `deleteMemoriesForEntity`, or a non-dry-run `prune` must reject with\n * `\"CONFLICT\"` before deleting anything. The dependency check and mutation must\n * be one atomic, non-interleavable operation; a check followed by a later write\n * with an interleaving gap does not satisfy the contract.\n *\n * Unless a method documents a stronger boundary, cancellation support and its\n * mechanism are implementation-defined. Adapters may use cooperative checks,\n * active statement cancellation, or no mid-operation cancellation while still\n * honoring the method's documented postconditions.\n */\nexport interface MemoryStore {\n\treadonly backend: MnemocyteBackend;\n\n\t/**\n\t * Completes the adapter's base-schema readiness hook.\n\t *\n\t * The built-in stores currently resolve without work and rely on explicit\n\t * schema management. An implementation may verify externally managed schema\n\t * state here, but this hook does not authorize hidden schema creation or\n\t * migration.\n\t */\n\tensureSchema(): Promise<void>;\n\t/**\n\t * Enforces the embedding compatibility check meaningful to this store's\n\t * persistence model before embedding-dependent work proceeds.\n\t *\n\t * The hook is unconditional and needs no capability flag. A store with no\n\t * persistent installation state may legitimately resolve without work. The\n\t * built-in Postgres store validates installation model and dimensions and may\n\t * reject with `\"MIGRATION\"` or `\"CONFIG\"`; the in-memory store is a no-op.\n\t */\n\tensureEmbeddingCompatibility(embedder: Embedder): Promise<void>;\n\n\t/**\n\t * Takes ownership of freshly prepared rows and returns exactly one detached\n\t * public record for every prepared input ID. Callers must not mutate or reuse\n\t * rows after passing them here.\n\t *\n\t * The store has no return-order obligation. Shared orchestration treats order\n\t * as untrusted, rejects missing or duplicate results and any returned ID\n\t * outside the prepared set, then restores prepared-input order.\n\t */\n\tinsertMemories(memories: readonly StoredMemory[]): Promise<Memory[]>;\n\t/**\n\t * Returns up to `input.limit` detached candidates that satisfy the shared\n\t * recall filters and `minVectorScore`, ordered by decreasing vector\n\t * similarity. Every `vectorScore` is finite and clamped to `[0, 1]`.\n\t *\n\t * An implementation may scan or use an index. When an approximate index is\n\t * available, candidate inclusion, ranking, and performance are index- and\n\t * planner-dependent and are not guaranteed to match an exhaustive scan.\n\t */\n\tvectorSearch(input: StoreVectorSearchInput): Promise<StoreVectorCandidate[]>;\n\t/**\n\t * Returns up to `input.limit` detached candidates that satisfy the shared\n\t * recall filters and have a positive implementation-defined lexical score,\n\t * ordered by decreasing score.\n\t *\n\t * Lexical parsing and relevance scoring are backend-defined. Implementations\n\t * may therefore differ in mechanism, returned candidates, and ranking, not\n\t * only in latency.\n\t */\n\tlexicalSearch(\n\t\tinput: StoreLexicalSearchInput,\n\t): Promise<StoreLexicalCandidate[]>;\n\t/**\n\t * Returns available embeddings for the requested IDs, keyed by memory ID.\n\t * Missing memories and memories without an embedding are omitted. Returned\n\t * vectors are detached from stored state, and input or map iteration order is\n\t * not part of the contract.\n\t */\n\tgetMemoryEmbeddings(\n\t\tmemoryIds: readonly string[],\n\t): Promise<Map<string, number[]>>;\n\t/**\n\t * Increments access state exactly once for each requested stored memory and\n\t * returns one record per ID containing its post-update `accessCount`,\n\t * `lastAccessedAt`, and `updatedAt`. Return order is untrusted and normalized\n\t * by shared orchestration.\n\t *\n\t * The input IDs must be distinct. Duplicate-ID behavior is backend-specific,\n\t * and callers must not rely on any particular deduplication or increment\n\t * behavior when this precondition is violated.\n\t */\n\tmarkMemoriesAccessed(\n\t\tmemoryIds: readonly string[],\n\t): Promise<StoreAccessUpdate[]>;\n\n\t/**\n\t * Deletes the memory only when both entity and memory ID match, returning\n\t * `false` when they do not and `true` after deletion.\n\t *\n\t * If any memory references the target through `supersededBy`, rejects with\n\t * `\"CONFLICT\"` without deleting it. Dependency detection and deletion must be\n\t * atomic and non-interleavable.\n\t */\n\tdeleteMemory(entityId: string, memoryId: string): Promise<boolean>;\n\t/**\n\t * Deletes every memory for the entity and returns the number deleted.\n\t *\n\t * If any memory references a selected target through `supersededBy`, rejects\n\t * the entire operation with `\"CONFLICT\"` before deleting anything, including\n\t * when the dependent is itself selected. Dependency detection and the batch\n\t * deletion must be atomic and non-interleavable.\n\t */\n\tdeleteMemoriesForEntity(entityId: string): Promise<number>;\n\tprune(\n\t\tinput: ValidatedPruneFilter,\n\t\toptions?: StoreOperationOptions,\n\t): Promise<StorePruneResult>;\n\t/**\n\t * Compares qualifying memories pairwise and returns up to the requested limit\n\t * of unordered pairs meeting the similarity threshold, ordered by decreasing\n\t * similarity. Similarities are clamped to `[0, 1]`; pair orientation and\n\t * equal-score order are not guaranteed.\n\t *\n\t * This contract neither implies nor requires indexed nearest-neighbor pair\n\t * generation. A database planner may still use ordinary indexes while\n\t * filtering or executing a pairwise join.\n\t */\n\tfindDuplicatePairs(\n\t\tinput: FindDuplicatesInput,\n\t\toptions?: StoreOperationOptions,\n\t): Promise<StoreDuplicatePair[]>;\n\n\t/**\n\t * Persists independent copies of audit events supplied by shared core.\n\t *\n\t * Ordinary audit writes are best-effort at the shared caller. Rejection does\n\t * not promise batch atomicity: failure behavior is implementation-defined,\n\t * and some stores may retain a partial batch after the promise rejects.\n\t */\n\taddAuditEvents(events: readonly AuditEvent[]): Promise<void>;\n\t/**\n\t * Returns detached events for the requested entity in strict descending\n\t * `(timestamp, id)` order, subject to the requested limit.\n\t *\n\t * Event IDs must be stable and timestamps comparable. Plain `before` and\n\t * `after` values are strict timestamp filters. Composite cursors use strict\n\t * tuple filtering on the same `(timestamp, id)` tuple used for ordering, so\n\t * equal-timestamp events can be paged without requiring a transaction.\n\t * Cancellation may be cooperative or active and is implementation-defined.\n\t */\n\tlistAuditLog(\n\t\tinput: ListAuditLogInput,\n\t\toptions?: StoreOperationOptions,\n\t): Promise<AuditEvent[]>;\n\n\t/**\n\t * Returns a detached memory only when both entity and memory ID match;\n\t * otherwise returns `null`.\n\t */\n\tgetMemory(\n\t\tentityId: string,\n\t\tmemoryId: string,\n\t\toptions?: StoreOperationOptions,\n\t): Promise<Memory | null>;\n\t/** Shared validation supplies distinct IDs before this preflight lookup. */\n\tloadConsolidationTargets(\n\t\tentityId: string,\n\t\tids: readonly string[],\n\t\toptions?: StoreOperationOptions,\n\t): Promise<StoreConsolidationTarget[]>;\n\t/**\n\t * Applies one atomic consolidation after re-reading and protecting the\n\t * survivor and requested losers. Throws `\"CONFLICT\"` before mutation when\n\t * the survivor is missing or superseded, or when any requested loser points\n\t * to a different survivor. Tag merging starts from the protected survivor's\n\t * mutation-time tags.\n\t */\n\tconsolidate(\n\t\tinput: StoreConsolidateInput,\n\t\toptions?: StoreOperationOptions,\n\t): Promise<StoreConsolidateResult>;\n\n\t/**\n\t * Returns entity-scoped or global counts evaluated against the supplied\n\t * `now`. `memoryCount` includes every selected memory; active memories are\n\t * neither expired nor superseded. Expired and superseded counts are\n\t * independent and may overlap. Global `entityCount` counts distinct entities\n\t * across all stored memories, and an empty scope returns zero counts.\n\t */\n\tstats(\n\t\tinput: { entityId?: string } | undefined,\n\t\tnow: Date,\n\t): Promise<EntityStats | GlobalStats>;\n\t/**\n\t * Releases only resources and transient state owned by this store instance.\n\t *\n\t * The in-memory store destroys its owned memory and audit state. The built-in\n\t * Postgres store closes the connection handle it created while leaving\n\t * persisted rows intact. An adapter wrapping a caller-supplied connection must\n\t * not close that connection or any other resource it does not own.\n\t */\n\tclose(): Promise<void>;\n}\n","import { MnemocyteError } from \"../errors.js\";\n\nexport function memoryHasDependentsError(cause?: unknown): MnemocyteError {\n\treturn new MnemocyteError(\n\t\t\"Memory cannot be deleted while other memories reference it as their consolidation survivor.\",\n\t\t\"CONFLICT\",\n\t\tcause,\n\t);\n}\n","import { MnemocyteError } from \"../errors.js\";\nimport type { MnemocyteStoreConfig } from \"../types.js\";\nimport type { MemoryStore } from \"./store.js\";\n\nconst MEMORY_STORE_CONFIG = Symbol.for(\"mnemocyte.memory-store-config\");\n\ninterface MemoryStoreConfigEnvelope {\n\treadonly [MEMORY_STORE_CONFIG]: MemoryStore;\n}\n\nexport function createMnemocyteStoreConfig(\n\tstore: MemoryStore,\n): MnemocyteStoreConfig {\n\treturn Object.freeze({\n\t\t[MEMORY_STORE_CONFIG]: store,\n\t}) as unknown as MnemocyteStoreConfig;\n}\n\nexport function unwrapMnemocyteStoreConfig(\n\tconfig: MnemocyteStoreConfig,\n): MemoryStore {\n\tconst candidate: unknown = config;\n\tif (\n\t\ttypeof candidate !== \"object\" ||\n\t\tcandidate === null ||\n\t\t!(MEMORY_STORE_CONFIG in candidate)\n\t) {\n\t\tthrow new MnemocyteError(\n\t\t\t\"store must be created by a supported Mnemocyte store adapter.\",\n\t\t\t\"CONFIG\",\n\t\t);\n\t}\n\n\treturn (candidate as MemoryStoreConfigEnvelope)[MEMORY_STORE_CONFIG];\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { D as MnemocyteStoreConfig } from "../types-DXYtLiOT.mjs";
|
|
2
|
+
import { PostgresJsDatabase } from "drizzle-orm/postgres-js";
|
|
3
|
+
/**
|
|
4
|
+
* Wrap a caller-owned postgres.js Drizzle instance for
|
|
5
|
+
* {@link MnemocyteConfig.store}.
|
|
6
|
+
*
|
|
7
|
+
* The Mnemocyte tables must already exist in the public schema through the
|
|
8
|
+
* bundled migrations. Closing the Mnemocyte client does not close the supplied
|
|
9
|
+
* Drizzle instance or its underlying postgres.js client.
|
|
10
|
+
*
|
|
11
|
+
* @param db - A Drizzle instance created with `drizzle-orm/postgres-js`.
|
|
12
|
+
*/
|
|
13
|
+
export declare function drizzleStore<TSchema extends Record<string, unknown>>(db: PostgresJsDatabase<TSchema>): MnemocyteStoreConfig;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { n as createCallerOwnedDatabaseHandle, t as createPostgresStore } from "../postgres-BDti0rrm.mjs";
|
|
2
|
+
import { t as createMnemocyteStoreConfig } from "../store-config-BZ4J1hrM.mjs";
|
|
3
|
+
// src/stores/drizzle.ts
|
|
4
|
+
/**
|
|
5
|
+
* Wrap a caller-owned postgres.js Drizzle instance for
|
|
6
|
+
* {@link MnemocyteConfig.store}.
|
|
7
|
+
*
|
|
8
|
+
* The Mnemocyte tables must already exist in the public schema through the
|
|
9
|
+
* bundled migrations. Closing the Mnemocyte client does not close the supplied
|
|
10
|
+
* Drizzle instance or its underlying postgres.js client.
|
|
11
|
+
*
|
|
12
|
+
* @param db - A Drizzle instance created with `drizzle-orm/postgres-js`.
|
|
13
|
+
*/
|
|
14
|
+
function drizzleStore(db) {
|
|
15
|
+
return createMnemocyteStoreConfig(createPostgresStore(createCallerOwnedDatabaseHandle(db)));
|
|
16
|
+
}
|
|
17
|
+
export { drizzleStore };
|
|
18
|
+
|
|
19
|
+
//# sourceMappingURL=drizzle.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drizzle.mjs","names":[],"sources":["../../src/stores/drizzle.ts"],"sourcesContent":["import type { PostgresJsDatabase } from \"drizzle-orm/postgres-js\";\nimport { createCallerOwnedDatabaseHandle } from \"../db/index.js\";\nimport { createPostgresStore } from \"../memory/postgres.js\";\nimport { createMnemocyteStoreConfig } from \"../memory/store-config.js\";\nimport type { MnemocyteStoreConfig } from \"../types.js\";\n\n/**\n * Wrap a caller-owned postgres.js Drizzle instance for\n * {@link MnemocyteConfig.store}.\n *\n * The Mnemocyte tables must already exist in the public schema through the\n * bundled migrations. Closing the Mnemocyte client does not close the supplied\n * Drizzle instance or its underlying postgres.js client.\n *\n * @param db - A Drizzle instance created with `drizzle-orm/postgres-js`.\n */\nexport function drizzleStore<TSchema extends Record<string, unknown>>(\n\tdb: PostgresJsDatabase<TSchema>,\n): MnemocyteStoreConfig {\n\treturn createMnemocyteStoreConfig(\n\t\tcreatePostgresStore(createCallerOwnedDatabaseHandle(db)),\n\t);\n}\n"],"mappings":";;;;;;;;;;;;;AAgBA,SAAgB,aACf,IACuB;CACvB,OAAO,2BACN,oBAAoB,gCAAgC,EAAE,CAAC,CACxD;AACD"}
|