@remnic/core 9.3.603 → 9.3.605

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.
Files changed (64) hide show
  1. package/dist/access-cli.js +9 -9
  2. package/dist/access-schema.d.ts +34 -34
  3. package/dist/{chunk-JTDRJQ3K.js → chunk-6JGNHWCI.js} +2 -2
  4. package/dist/{chunk-M6I5Z4SR.js → chunk-6ZZP4EJF.js} +2 -2
  5. package/dist/{chunk-75O6YQ63.js → chunk-G6R5UD3Q.js} +10 -3
  6. package/dist/chunk-G6R5UD3Q.js.map +1 -0
  7. package/dist/{chunk-I4UNL747.js → chunk-GMAG2HS4.js} +7 -3
  8. package/dist/chunk-GMAG2HS4.js.map +1 -0
  9. package/dist/{chunk-5SQ5CQJP.js → chunk-HSVJGWYS.js} +2 -2
  10. package/dist/{chunk-RUYYYLDT.js → chunk-IOTENEVL.js} +3 -3
  11. package/dist/{chunk-M46RYSMW.js → chunk-JHMFYY7L.js} +5 -2
  12. package/dist/chunk-JHMFYY7L.js.map +1 -0
  13. package/dist/{chunk-2ESBDLT5.js → chunk-VJXSUAO7.js} +2 -2
  14. package/dist/{chunk-Z5AAYHUC.js → chunk-VOUOLGIP.js} +13 -2
  15. package/dist/chunk-VOUOLGIP.js.map +1 -0
  16. package/dist/{chunk-OB6353F7.js → chunk-XPSVGJYA.js} +4 -4
  17. package/dist/{chunk-MTGOAU7A.js → chunk-YJ6QCQNE.js} +336 -300
  18. package/dist/chunk-YJ6QCQNE.js.map +1 -0
  19. package/dist/{chunk-6PTSXBPE.js → chunk-ZDTVJXIP.js} +5 -2
  20. package/dist/chunk-ZDTVJXIP.js.map +1 -0
  21. package/dist/cli.js +8 -8
  22. package/dist/{first-start-migration-CKTCTCQI.js → first-start-migration-GYJWIH36.js} +2 -2
  23. package/dist/index.js +12 -12
  24. package/dist/namespaces/migrate.js +6 -6
  25. package/dist/namespaces/search.js +5 -5
  26. package/dist/operator-toolkit.js +7 -7
  27. package/dist/orchestrator.js +9 -9
  28. package/dist/retrieval-agents.js +2 -2
  29. package/dist/schemas.d.ts +42 -42
  30. package/dist/search/factory.js +4 -4
  31. package/dist/search/index.js +4 -4
  32. package/dist/search/lancedb-backend.d.ts +1 -0
  33. package/dist/search/lancedb-backend.js +1 -1
  34. package/dist/search/meilisearch-backend.d.ts +1 -0
  35. package/dist/search/meilisearch-backend.js +1 -1
  36. package/dist/search/orama-backend.d.ts +1 -0
  37. package/dist/search/orama-backend.js +1 -1
  38. package/dist/search/port.d.ts +1 -0
  39. package/dist/shared-context/manager.d.ts +2 -2
  40. package/dist/temporal-index.js +1 -1
  41. package/dist/tier-migration.d.ts +1 -0
  42. package/dist/tier-migration.js +1 -1
  43. package/package.json +1 -1
  44. package/src/orchestrator.ts +51 -8
  45. package/src/search/lancedb-backend.ts +5 -1
  46. package/src/search/meilisearch-backend.ts +7 -2
  47. package/src/search/orama-backend.ts +5 -1
  48. package/src/search/port.ts +1 -0
  49. package/src/temporal-index.test.ts +30 -1
  50. package/src/temporal-index.ts +10 -3
  51. package/src/tier-migration.ts +13 -2
  52. package/dist/chunk-6PTSXBPE.js.map +0 -1
  53. package/dist/chunk-75O6YQ63.js.map +0 -1
  54. package/dist/chunk-I4UNL747.js.map +0 -1
  55. package/dist/chunk-M46RYSMW.js.map +0 -1
  56. package/dist/chunk-MTGOAU7A.js.map +0 -1
  57. package/dist/chunk-Z5AAYHUC.js.map +0 -1
  58. /package/dist/{chunk-JTDRJQ3K.js.map → chunk-6JGNHWCI.js.map} +0 -0
  59. /package/dist/{chunk-M6I5Z4SR.js.map → chunk-6ZZP4EJF.js.map} +0 -0
  60. /package/dist/{chunk-5SQ5CQJP.js.map → chunk-HSVJGWYS.js.map} +0 -0
  61. /package/dist/{chunk-RUYYYLDT.js.map → chunk-IOTENEVL.js.map} +0 -0
  62. /package/dist/{chunk-2ESBDLT5.js.map → chunk-VJXSUAO7.js.map} +0 -0
  63. /package/dist/{chunk-OB6353F7.js.map → chunk-XPSVGJYA.js.map} +0 -0
  64. /package/dist/{first-start-migration-CKTCTCQI.js.map → first-start-migration-GYJWIH36.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/search/orama-backend.ts"],"sourcesContent":["import path from \"node:path\";\nimport { mkdir, readdir, readFile, rename, rm, writeFile } from \"node:fs/promises\";\nimport { log } from \"../logger.js\";\nimport type { SearchBackend, SearchExecutionOptions, SearchQueryOptions, SearchResult } from \"./port.js\";\nimport type { EmbedHelper, EmbedProviderIdentity, EmbedWithProviderResult } from \"./embed-helper.js\";\nimport { scanMemoryDir } from \"./document-scanner.js\";\nimport { isSearchAborted, throwIfSearchAborted } from \"./abort.js\";\n\nexport interface OramaBackendOptions {\n dbPath: string;\n collection: string;\n embedHelper: EmbedHelper;\n memoryDir: string;\n embeddingDimension: number;\n}\n\nconst ORAMA_COLLECTION_FILENAME_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;\n\nfunction pathIsInside(parent: string, child: string): boolean {\n const relative = path.relative(parent, child);\n return relative === \"\" || (!relative.startsWith(\"..\") && !path.isAbsolute(relative));\n}\n\nexport function resolveOramaCollectionDbFilePath(dbPath: string, collection: string): string {\n if (!ORAMA_COLLECTION_FILENAME_PATTERN.test(collection)) {\n throw new Error(\n `Invalid Orama collection name ${JSON.stringify(collection)}. ` +\n \"Collection names must match [A-Za-z0-9][A-Za-z0-9._-]*.\",\n );\n }\n const resolvedDbPath = path.resolve(dbPath);\n const filePath = path.resolve(resolvedDbPath, `${collection}.msp`);\n if (!pathIsInside(resolvedDbPath, filePath)) {\n throw new Error(\n `Invalid Orama collection path for ${JSON.stringify(collection)}: resolved outside dbPath.`,\n );\n }\n return filePath;\n}\n\n/**\n * Orama search backend — embedded hybrid FTS+vector, pure JS.\n *\n * Uses @orama/orama for full-text search with optional vector support.\n * Persists data to JSON files via @orama/plugin-data-persistence.\n */\nexport class OramaBackend implements SearchBackend {\n private readonly dbPath: string;\n private readonly collection: string;\n private readonly embedHelper: EmbedHelper;\n private readonly memoryDir: string;\n private readonly embeddingDimension: number;\n private available = false;\n private db: any = null;\n private oramaModule: any = null;\n private persistModule: any = null;\n private readonly vectorProviderCompatibility = new WeakMap<\n object,\n { providerIdentity: EmbedProviderIdentity; compatible: boolean }\n >();\n\n constructor(opts: OramaBackendOptions) {\n this.dbPath = opts.dbPath;\n this.collection = opts.collection;\n this.embedHelper = opts.embedHelper;\n this.memoryDir = opts.memoryDir;\n this.embeddingDimension = opts.embeddingDimension;\n }\n\n async probe(): Promise<boolean> {\n try {\n await this.ensureModules();\n await this.ensureDb();\n this.available = true;\n return true;\n } catch (err) {\n log.debug(`OramaBackend probe failed: ${err}`);\n this.available = false;\n return false;\n }\n }\n\n isAvailable(): boolean {\n return this.available;\n }\n\n debugStatus(): string {\n return `backend=orama available=${this.available} dbPath=${this.dbPath}`;\n }\n\n async search(\n query: string,\n _collection?: string,\n maxResults?: number,\n _options?: SearchQueryOptions,\n execution?: SearchExecutionOptions,\n ): Promise<SearchResult[]> {\n return this.hybridSearch(query, _collection, maxResults, execution);\n }\n\n async searchGlobal(query: string, maxResults?: number, execution?: SearchExecutionOptions): Promise<SearchResult[]> {\n const limit = maxResults ?? 10;\n if (!this.available) return [];\n try {\n throwIfSearchAborted(execution, \"OramaBackend global search aborted\");\n const files = await this.listDbFiles();\n const allResults: SearchResult[] = [];\n for (const file of files) {\n throwIfSearchAborted(execution, \"OramaBackend global search aborted\");\n const db = await this.loadDbFromFile(file);\n if (!db) continue;\n const results = await this.searchDb(db, query, \"hybrid\", limit, execution);\n allResults.push(...results);\n }\n allResults.sort((a, b) => b.score - a.score);\n return allResults.slice(0, limit);\n } catch (err) {\n log.debug(`OramaBackend searchGlobal failed: ${err}`);\n return [];\n }\n }\n\n async bm25Search(query: string, collection?: string, maxResults?: number, execution?: SearchExecutionOptions): Promise<SearchResult[]> {\n if (isSearchAborted(execution)) return [];\n const db = await this.ensureDbForCollection(collection ?? this.collection);\n if (isSearchAborted(execution)) return [];\n if (!db) return [];\n return this.searchDb(db, query, \"fulltext\", maxResults ?? 10, execution);\n }\n\n async vectorSearch(query: string, collection?: string, maxResults?: number, execution?: SearchExecutionOptions): Promise<SearchResult[]> {\n if (isSearchAborted(execution)) return [];\n const db = await this.ensureDbForCollection(collection ?? this.collection);\n if (isSearchAborted(execution)) return [];\n if (!db) return [];\n return this.searchDb(db, query, \"vector\", maxResults ?? 10, execution);\n }\n\n async hybridSearch(query: string, collection?: string, maxResults?: number, execution?: SearchExecutionOptions): Promise<SearchResult[]> {\n if (isSearchAborted(execution)) return [];\n const db = await this.ensureDbForCollection(collection ?? this.collection);\n if (isSearchAborted(execution)) return [];\n if (!db) return [];\n return this.searchDb(db, query, \"hybrid\", maxResults ?? 10, execution);\n }\n\n async update(execution?: SearchExecutionOptions): Promise<void> {\n await this.updateCollection(this.collection, execution);\n }\n\n async updateCollection(collection: string, execution?: SearchExecutionOptions): Promise<void> {\n await this.updateCollectionFromDir(collection, this.memoryDir, execution);\n }\n\n async updateCollectionFromDir(collection: string, memoryDir: string, execution?: SearchExecutionOptions): Promise<void> {\n if (isSearchAborted(execution)) return;\n const db = await this.ensureDbForCollection(collection);\n if (isSearchAborted(execution)) return;\n if (!db) return;\n const { search: oramaSearch, insert, remove, count, getByID } = this.oramaModule;\n\n const docs = await scanMemoryDir(memoryDir);\n if (isSearchAborted(execution)) return;\n const docMap = new Map(docs.map((d) => [d.docid, d]));\n const { update: oramaUpdate } = this.oramaModule;\n\n const embeddingProviderIdentity = this.embedHelper.getProviderIdentity();\n let allRowsCompatible = !!embeddingProviderIdentity && docs.length > 0;\n // Get existing docs to diff — map user doc ID → { internalId, vector }\n const existingDocs = new Map<string, {\n internalId: string;\n vector?: number[];\n vectorProvider?: string;\n }>();\n const existingCount = await count(db);\n if (existingCount > 0) {\n const allHits = await oramaSearch(db, {\n term: \"\",\n limit: existingCount + 100,\n });\n for (const hit of allHits.hits) {\n if (isSearchAborted(execution)) return;\n const storedDocument =\n typeof getByID === \"function\"\n ? await getByID(db, hit.id)\n : hit.document;\n const document = storedDocument ?? hit.document ?? {};\n if (!docMap.has(document.id)) {\n await remove(db, hit.id);\n } else {\n existingDocs.set(document.id, {\n internalId: hit.id,\n vector: this.normalizeStoredVector(document.vector) ?? undefined,\n vectorProvider:\n typeof document.vectorProvider === \"string\"\n ? document.vectorProvider\n : undefined,\n });\n }\n }\n }\n\n // Insert new docs, update existing ones (preserving vectors since update is remove+insert)\n for (const doc of docs) {\n if (isSearchAborted(execution)) return;\n const existing = existingDocs.get(doc.docid);\n if (existing) {\n const payload: Record<string, unknown> = {\n id: doc.docid,\n path: doc.path,\n content: doc.content,\n snippet: doc.snippet,\n };\n const preservesCompatibleProvider =\n !!embeddingProviderIdentity &&\n existing.vectorProvider === embeddingProviderIdentity;\n if (preservesCompatibleProvider) {\n if (this.isCompatibleStoredVector(existing.vector)) {\n payload.vector = existing.vector;\n payload.vectorProvider = existing.vectorProvider ?? \"\";\n } else {\n payload.vector = this.zeroVector();\n payload.vectorProvider = \"\";\n allRowsCompatible = false;\n }\n } else if (!embeddingProviderIdentity && this.isCompatibleStoredVector(existing.vector)) {\n payload.vector = existing.vector;\n payload.vectorProvider = existing.vectorProvider ?? \"\";\n allRowsCompatible = false;\n } else {\n payload.vector = this.zeroVector();\n payload.vectorProvider = \"\";\n allRowsCompatible = false;\n }\n try {\n await oramaUpdate(db, existing.internalId, payload);\n } catch {\n allRowsCompatible = false;\n // Update failed — skip and continue with remaining docs\n }\n } else {\n allRowsCompatible = false;\n try {\n await insert(db, {\n id: doc.docid,\n path: doc.path,\n content: doc.content,\n snippet: doc.snippet,\n vector: this.zeroVector(),\n vectorProvider: \"\",\n });\n } catch {\n allRowsCompatible = false;\n // Duplicate id edge case — skip\n }\n }\n }\n\n if (isSearchAborted(execution)) return;\n await this.persistDbForCollection(db, collection);\n this.rememberVectorProviderCompatibility(\n db,\n embeddingProviderIdentity,\n allRowsCompatible,\n );\n }\n\n async embed(): Promise<void> {\n await this.embedCollection(this.collection);\n }\n\n async embedCollection(collection: string): Promise<void> {\n if (!this.embedHelper.isAvailable()) return;\n\n const db = await this.ensureDbForCollection(collection);\n if (!db) return;\n const { search: oramaSearch, update: oramaUpdate, count } = this.oramaModule;\n\n const existingCount = await count(db);\n if (existingCount === 0) return;\n\n const embeddingProviderIdentity = this.embedHelper.getProviderIdentity();\n // Find docs without vectors or with vectors from a different provider.\n const allHits = await oramaSearch(db, { term: \"\", limit: existingCount + 100 });\n const needsEmbed = allHits.hits.filter((h: any) => {\n const vector = this.normalizeStoredVector(h.document?.vector);\n return (\n (embeddingProviderIdentity &&\n h.document?.vectorProvider !== embeddingProviderIdentity) ||\n !this.isCompatibleStoredVector(vector)\n );\n });\n\n if (needsEmbed.length === 0) {\n this.rememberVectorProviderCompatibility(db, embeddingProviderIdentity, true);\n return;\n }\n\n let rowsToEmbed = needsEmbed;\n let embedResult = await this.embedHelper.embedBatchWithProvider(\n rowsToEmbed.map((h: any) => h.document.content as string),\n );\n if (!embedResult) return;\n if (\n embeddingProviderIdentity &&\n embedResult.providerIdentity !== embeddingProviderIdentity\n ) {\n const effectiveProviderIdentity = embedResult.providerIdentity;\n const originalIds = new Set(rowsToEmbed.map((h: any) => h.id));\n const effectiveNeedsEmbed = allHits.hits.filter((h: any) => {\n const vector = this.normalizeStoredVector(h.document?.vector);\n return (\n h.document?.vectorProvider !== effectiveProviderIdentity ||\n !this.isCompatibleStoredVector(vector)\n );\n });\n const sameRows =\n effectiveNeedsEmbed.length === rowsToEmbed.length &&\n effectiveNeedsEmbed.every((h: any) => originalIds.has(h.id));\n if (!sameRows) {\n const effectiveTexts = effectiveNeedsEmbed.map((h: any) => h.document.content as string);\n const effectiveEmbedResult = await this.embedHelper.embedBatchWithProvider(effectiveTexts);\n if (effectiveEmbedResult) {\n rowsToEmbed = effectiveNeedsEmbed;\n embedResult = effectiveEmbedResult;\n }\n }\n }\n const { vectors, providerIdentity } = embedResult;\n\n let allEmbedded = true;\n for (let i = 0; i < rowsToEmbed.length; i++) {\n const vec = vectors[i];\n if (!this.isExpectedDimensionVector(vec)) {\n allEmbedded = false;\n continue;\n }\n // Orama update is remove+insert — must include all fields to avoid data loss\n const doc = rowsToEmbed[i].document;\n await oramaUpdate(db, rowsToEmbed[i].id, {\n id: doc.id,\n path: doc.path,\n content: doc.content,\n snippet: doc.snippet,\n vector: vec,\n vectorProvider: providerIdentity,\n });\n }\n\n await this.persistDbForCollection(db, collection);\n if (allEmbedded) {\n this.rememberVectorProviderCompatibility(db, providerIdentity, true);\n } else {\n this.rememberVectorProviderCompatibility(db, providerIdentity, false);\n }\n }\n\n async ensureCollection(\n _memoryDir: string,\n _execution?: SearchExecutionOptions,\n ): Promise<\"present\" | \"missing\" | \"unknown\" | \"skipped\"> {\n try {\n await this.ensureModules();\n await this.ensureDb();\n return \"present\";\n } catch {\n return \"missing\";\n }\n }\n\n private async ensureModules(): Promise<void> {\n if (this.oramaModule && this.persistModule) return;\n this.oramaModule = await import(\"@orama/orama\");\n this.persistModule = await import(\"@orama/plugin-data-persistence\");\n }\n\n private async ensureDb(): Promise<any> {\n if (this.db) return this.db;\n await this.ensureModules();\n\n await mkdir(this.dbPath, { recursive: true });\n const filePath = this.dbFilePath(this.collection);\n\n let raw: string;\n try {\n raw = await readFile(filePath, \"utf-8\");\n } catch {\n // No existing DB — create fresh\n this.db = await this.createDb();\n return this.db;\n }\n\n this.db = await this.migrateLegacyVectorProviderSchema(\n await this.persistModule.restore(\"json\", raw),\n this.collection,\n );\n return this.db;\n }\n\n private async ensureDbForCollection(collection: string): Promise<any> {\n // For the default collection, use the cached instance\n if (collection === this.collection) return this.ensureDb();\n\n await this.ensureModules();\n await mkdir(this.dbPath, { recursive: true });\n const filePath = this.dbFilePath(collection);\n\n let raw: string;\n try {\n raw = await readFile(filePath, \"utf-8\");\n } catch {\n // No existing DB — create fresh\n return await this.createDb();\n }\n\n return await this.migrateLegacyVectorProviderSchema(\n await this.persistModule.restore(\"json\", raw),\n collection,\n );\n }\n\n private async createDb(): Promise<any> {\n const { create } = this.oramaModule;\n const schema: Record<string, string> = {\n id: \"string\",\n path: \"string\",\n content: \"string\",\n snippet: \"string\",\n vectorProvider: \"string\",\n vector: `vector[${this.embeddingDimension}]`,\n };\n return await create({ schema });\n }\n\n private async migrateLegacyVectorProviderSchema(db: any, collection: string): Promise<any> {\n const { search: oramaSearch, count, insert } = this.oramaModule;\n const existingCount = await count(db);\n if (existingCount === 0) {\n const migrated = await this.createDb();\n await this.persistDbForCollection(migrated, collection);\n return migrated;\n }\n\n const allHits = await oramaSearch(db, { term: \"\", limit: existingCount + 100 });\n const hits = allHits.hits ?? [];\n const needsMigration = hits.some((hit: any) =>\n typeof hit.document?.vectorProvider !== \"string\"\n );\n if (!needsMigration) return db;\n\n const migrated = await this.createDb();\n for (const hit of hits) {\n const doc = this.getStoredDocument(db, hit);\n const vector = this.getStoredVector(db, hit, doc);\n const payload: Record<string, unknown> = {\n id: typeof doc.id === \"string\" && doc.id.length > 0 ? doc.id : String(hit.id),\n path: typeof doc.path === \"string\" ? doc.path : \"\",\n content: typeof doc.content === \"string\" ? doc.content : \"\",\n snippet:\n typeof doc.snippet === \"string\"\n ? doc.snippet\n : typeof doc.content === \"string\"\n ? doc.content.slice(0, 200)\n : \"\",\n vectorProvider:\n typeof doc.vectorProvider === \"string\" ? doc.vectorProvider : \"\",\n };\n if (vector) {\n payload.vector = vector;\n } else {\n payload.vector = this.zeroVector();\n }\n await insert(migrated, payload);\n }\n await this.persistDbForCollection(migrated, collection);\n return migrated;\n }\n\n private async persistDbForCollection(db: any, collection: string): Promise<void> {\n const data = await this.persistModule.persist(db, \"json\");\n const filePath = this.dbFilePath(collection);\n await mkdir(path.dirname(filePath), { recursive: true });\n const tempPath = path.join(\n path.dirname(filePath),\n `.${path.basename(filePath)}.${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}.tmp`,\n );\n try {\n await writeFile(tempPath, data, \"utf-8\");\n await rename(tempPath, filePath);\n } catch (err) {\n await rm(tempPath, { force: true }).catch(() => undefined);\n throw err;\n }\n }\n\n private dbFilePath(collection: string): string {\n return resolveOramaCollectionDbFilePath(this.dbPath, collection);\n }\n\n private async listDbFiles(): Promise<string[]> {\n try {\n const entries = await readdir(this.dbPath);\n return entries\n .filter((e) => e.endsWith(\".msp\"))\n .map((e) => path.join(this.dbPath, e));\n } catch {\n return [];\n }\n }\n\n private async loadDbFromFile(filePath: string): Promise<any> {\n try {\n await this.ensureModules();\n const raw = await readFile(filePath, \"utf-8\");\n const collection = path.basename(filePath, \".msp\");\n return await this.migrateLegacyVectorProviderSchema(\n await this.persistModule.restore(\"json\", raw),\n collection,\n );\n } catch (err) {\n log.debug(`OramaBackend failed to load ${filePath}: ${err}`);\n return null;\n }\n }\n\n private async searchDb(\n db: any,\n query: string,\n mode: \"fulltext\" | \"vector\" | \"hybrid\",\n limit: number,\n execution?: SearchExecutionOptions,\n ): Promise<SearchResult[]> {\n const { search: oramaSearch } = this.oramaModule;\n\n try {\n throwIfSearchAborted(execution, `OramaBackend ${mode} search aborted`);\n let searchParams: any;\n\n if (mode === \"fulltext\") {\n searchParams = { term: query, limit };\n } else if (mode === \"vector\") {\n const embedResult = await this.resolveCompatibleQueryEmbedding(db, query, execution);\n throwIfSearchAborted(execution, `OramaBackend ${mode} search aborted`);\n if (!embedResult) {\n // Fall back to fulltext if no embeddings available\n searchParams = { term: query, limit };\n } else {\n searchParams = { mode: \"vector\", vector: { value: embedResult.vector, property: \"vector\" }, limit };\n }\n } else {\n // hybrid\n const embedResult = await this.resolveCompatibleQueryEmbedding(db, query, execution);\n throwIfSearchAborted(execution, `OramaBackend ${mode} search aborted`);\n if (!embedResult) {\n searchParams = { term: query, limit };\n } else {\n searchParams = { mode: \"hybrid\", term: query, vector: { value: embedResult.vector, property: \"vector\" }, limit };\n }\n }\n\n throwIfSearchAborted(execution, `OramaBackend ${mode} search aborted`);\n const result = await oramaSearch(db, searchParams);\n throwIfSearchAborted(execution, `OramaBackend ${mode} search aborted`);\n return (result.hits ?? []).map((hit: any) => ({\n docid: hit.document?.id ?? \"\",\n path: hit.document?.path ?? \"\",\n snippet: hit.document?.snippet ?? hit.document?.content?.slice(0, 200) ?? \"\",\n score: hit.score ?? 0,\n }));\n } catch (err) {\n log.debug(`OramaBackend search (${mode}) failed: ${err}`);\n return [];\n }\n }\n\n private async resolveCompatibleQueryEmbedding(\n db: any,\n query: string,\n execution?: SearchExecutionOptions,\n ): Promise<EmbedWithProviderResult | null> {\n const embedResult = await this.embedHelper.embedWithProvider(query, { signal: execution?.signal });\n throwIfSearchAborted(execution, \"OramaBackend query embedding aborted\");\n if (!embedResult || !this.isExpectedDimensionVector(embedResult.vector)) return null;\n\n const storedProviderIdentity = await this.findCompatibleStoredVectorProvider(db, execution);\n if (!storedProviderIdentity) {\n this.rememberVectorProviderCompatibility(db, embedResult.providerIdentity, false);\n return null;\n }\n if (storedProviderIdentity === embedResult.providerIdentity) return embedResult;\n\n const fallbackEmbed = await this.embedQueryWithStoredFallbackProvider(query, storedProviderIdentity, execution);\n throwIfSearchAborted(execution, \"OramaBackend fallback query embedding aborted\");\n if (\n fallbackEmbed &&\n fallbackEmbed.providerIdentity === storedProviderIdentity &&\n this.isExpectedDimensionVector(fallbackEmbed.vector)\n ) {\n return fallbackEmbed;\n }\n\n this.rememberVectorProviderCompatibility(db, embedResult.providerIdentity, false);\n return null;\n }\n\n private async embedQueryWithStoredFallbackProvider(\n query: string,\n providerIdentity: EmbedProviderIdentity,\n execution?: SearchExecutionOptions,\n ): Promise<EmbedWithProviderResult | null> {\n const embedWithIdentity = (this.embedHelper as unknown as {\n embedWithFallbackProviderIdentity?: (\n text: string,\n identity: EmbedProviderIdentity,\n options?: { signal?: AbortSignal },\n ) => Promise<EmbedWithProviderResult | null>;\n }).embedWithFallbackProviderIdentity;\n if (typeof embedWithIdentity !== \"function\") return null;\n return embedWithIdentity.call(this.embedHelper, query, providerIdentity, { signal: execution?.signal });\n }\n\n private async findCompatibleStoredVectorProvider(\n db: any,\n execution?: SearchExecutionOptions,\n ): Promise<EmbedProviderIdentity | null> {\n const { search: oramaSearch, count } = this.oramaModule;\n try {\n const cached = this.vectorProviderCompatibility.get(db);\n if (cached?.compatible) return cached.providerIdentity;\n const existingCount = await count(db);\n if (existingCount === 0) return null;\n const allHits = await oramaSearch(db, {\n term: \"\",\n limit: existingCount + 100,\n properties: [\"vectorProvider\"],\n });\n let providerIdentity: EmbedProviderIdentity | null = null;\n let compatible = (allHits.hits ?? []).length > 0;\n for (const hit of allHits.hits ?? []) {\n throwIfSearchAborted(execution, \"OramaBackend vector provider check aborted\");\n const doc = this.getStoredDocument(db, hit);\n if (\n typeof doc.vectorProvider !== \"string\" ||\n doc.vectorProvider.length === 0 ||\n !this.isCompatibleStoredVector(this.getStoredVector(db, hit, doc))\n ) {\n compatible = false;\n break;\n }\n if (providerIdentity && doc.vectorProvider !== providerIdentity) {\n compatible = false;\n break;\n }\n providerIdentity = doc.vectorProvider as EmbedProviderIdentity;\n }\n if (compatible && providerIdentity) {\n this.vectorProviderCompatibility.set(db, {\n providerIdentity,\n compatible: true,\n });\n return providerIdentity;\n }\n return null;\n } catch (err) {\n if (isSearchAborted(execution)) throw err;\n log.debug(`OramaBackend stored vector provider check failed: ${err}`);\n return null;\n }\n }\n\n private async dbHasCompatibleVectors(\n db: any,\n providerIdentity: EmbedProviderIdentity,\n execution?: SearchExecutionOptions,\n ): Promise<boolean> {\n const { search: oramaSearch, count } = this.oramaModule;\n try {\n const cached = this.vectorProviderCompatibility.get(db);\n if (cached?.providerIdentity === providerIdentity) return cached.compatible;\n const existingCount = await count(db);\n if (existingCount === 0) return false;\n const allHits = await oramaSearch(db, {\n term: \"\",\n limit: existingCount + 100,\n properties: [\"vectorProvider\"],\n });\n let compatible = (allHits.hits ?? []).length > 0;\n for (const hit of allHits.hits ?? []) {\n throwIfSearchAborted(execution, \"OramaBackend vector provider check aborted\");\n const doc = this.getStoredDocument(db, hit);\n if (\n doc.vectorProvider !== providerIdentity ||\n !this.isCompatibleStoredVector(this.getStoredVector(db, hit, doc))\n ) {\n compatible = false;\n break;\n }\n }\n this.vectorProviderCompatibility.set(db, { providerIdentity, compatible });\n return compatible;\n } catch (err) {\n if (isSearchAborted(execution)) throw err;\n log.debug(`OramaBackend vector provider check failed: ${err}`);\n return false;\n }\n }\n\n private rememberVectorProviderCompatibility(\n db: unknown,\n providerIdentity: EmbedProviderIdentity | null,\n compatible: boolean,\n ): void {\n if (!db || typeof db !== \"object\") return;\n if (!providerIdentity) {\n this.vectorProviderCompatibility.delete(db);\n return;\n }\n this.vectorProviderCompatibility.set(db, { providerIdentity, compatible });\n }\n\n private getStoredDocument(db: any, hit: any): Record<string, unknown> {\n const internalId = this.getInternalDocumentId(db, hit);\n const internalDoc =\n internalId !== undefined && internalId !== null\n ? db?.data?.docs?.docs?.[String(internalId)]\n : undefined;\n if (internalDoc && typeof internalDoc === \"object\") {\n return internalDoc as Record<string, unknown>;\n }\n return hit?.document && typeof hit.document === \"object\"\n ? hit.document as Record<string, unknown>\n : {};\n }\n\n private getStoredVector(db: any, hit: any, doc: Record<string, unknown>): number[] | null {\n const documentVector = this.normalizeStoredVector(doc.vector);\n if (documentVector) return documentVector;\n const internalId = this.getInternalDocumentId(db, hit);\n if (internalId === undefined || internalId === null) return null;\n const vectorEntry = db?.data?.index?.vectorIndexes?.vector?.node?.vectors?.get?.(internalId);\n const vector = Array.isArray(vectorEntry) ? vectorEntry[1] : vectorEntry;\n return this.normalizeStoredVector(vector);\n }\n\n private getInternalDocumentId(db: any, hit: any): unknown {\n const publicId =\n typeof hit?.id === \"string\"\n ? hit.id\n : typeof hit?.document?.id === \"string\"\n ? hit.document.id\n : undefined;\n return publicId && typeof db?.internalDocumentIDStore?.idToInternalId?.get === \"function\"\n ? db.internalDocumentIDStore.idToInternalId.get(publicId)\n : undefined;\n }\n\n private isExpectedDimensionVector(vector: number[] | null | undefined): vector is number[] {\n return Array.isArray(vector) && vector.length === this.embeddingDimension;\n }\n\n private isCompatibleStoredVector(vector: unknown): vector is number[] {\n if (!vector || typeof vector !== \"object\") return false;\n const arr = Array.from(vector as ArrayLike<number>);\n return (\n arr.length === this.embeddingDimension &&\n arr.every((value) => Number.isFinite(value)) &&\n arr.some((value) => value !== 0)\n );\n }\n\n private zeroVector(): number[] {\n return Array.from({ length: this.embeddingDimension }, () => 0);\n }\n\n private normalizeStoredVector(vector: unknown): number[] | null {\n const values =\n Array.isArray(vector)\n ? vector\n : ArrayBuffer.isView(vector) && !(vector instanceof DataView)\n ? Array.from(vector as unknown as ArrayLike<unknown>)\n : null;\n if (!values || values.length !== this.embeddingDimension) return null;\n const normalized = values.map((value) => Number(value));\n return normalized.every((value) => Number.isFinite(value)) ? normalized : null;\n }\n}\n"],"mappings":"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","names":["migrated"]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  listNamespaces
3
- } from "./chunk-JTDRJQ3K.js";
3
+ } from "./chunk-6JGNHWCI.js";
4
4
  import {
5
5
  runConsolidationProvenanceCheck
6
6
  } from "./chunk-LZ3VEOU5.js";
@@ -1333,4 +1333,4 @@ export {
1333
1333
  runBenchmarkRecall,
1334
1334
  runOperatorRepair
1335
1335
  };
1336
- //# sourceMappingURL=chunk-2ESBDLT5.js.map
1336
+ //# sourceMappingURL=chunk-VJXSUAO7.js.map
@@ -44,7 +44,10 @@ var TierMigrationExecutor = class {
44
44
  if (result.changed) {
45
45
  const destinationCollection = this.collectionForTier(toTier);
46
46
  const sourceCollection = this.collectionForTier(fromTier);
47
- await this.qmd.updateCollection(destinationCollection);
47
+ await this.updateCollectionFromTierRoot(destinationCollection, toTier);
48
+ if (sourceCollection !== destinationCollection && this.qmd.updatesAllCollections?.() !== true) {
49
+ await this.updateCollectionFromTierRoot(sourceCollection, fromTier);
50
+ }
48
51
  if (this.autoEmbed) {
49
52
  await this.qmd.embedCollection(destinationCollection);
50
53
  if (sourceCollection !== destinationCollection) {
@@ -57,6 +60,14 @@ var TierMigrationExecutor = class {
57
60
  collectionForTier(tier) {
58
61
  return tier === "cold" ? this.coldCollection : this.hotCollection;
59
62
  }
63
+ async updateCollectionFromTierRoot(collection, tier) {
64
+ const memoryDir = tier === "cold" ? path.join(this.storage.dir, "cold") : this.storage.dir;
65
+ if (this.qmd.updatesAllCollections?.() !== true && this.qmd.updateCollectionFromDir) {
66
+ await this.qmd.updateCollectionFromDir(collection, memoryDir);
67
+ return;
68
+ }
69
+ await this.qmd.updateCollection(collection);
70
+ }
60
71
  async appendJournal(result) {
61
72
  const entry = {
62
73
  ts: (/* @__PURE__ */ new Date()).toISOString(),
@@ -76,4 +87,4 @@ var TierMigrationExecutor = class {
76
87
  export {
77
88
  TierMigrationExecutor
78
89
  };
79
- //# sourceMappingURL=chunk-Z5AAYHUC.js.map
90
+ //# sourceMappingURL=chunk-VOUOLGIP.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/tier-migration.ts"],"sourcesContent":["import { appendFile, mkdir } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport type { MemoryFile } from \"./types.js\";\nimport { StorageManager } from \"./storage.js\";\nimport type { MemoryTier } from \"./tier-routing.js\";\nimport type { SearchBackend } from \"./search/port.js\";\n\nexport type { MemoryTier } from \"./tier-routing.js\";\n\nexport interface TierMigrationRequest {\n memory: MemoryFile;\n fromTier: MemoryTier;\n toTier: MemoryTier;\n reason: string;\n}\n\nexport interface TierMigrationResult {\n memoryId: string;\n fromTier: MemoryTier;\n toTier: MemoryTier;\n changed: boolean;\n reason: string;\n targetPath: string;\n}\n\nexport interface TierMigrationExecutorOptions {\n storage: StorageManager;\n qmd: SearchBackend;\n hotCollection: string;\n coldCollection: string;\n autoEmbed?: boolean;\n journalPath?: string;\n}\n\ntype TierMigrationJournalEntry = {\n ts: string;\n memoryId: string;\n fromTier: MemoryTier;\n toTier: MemoryTier;\n changed: boolean;\n reason: string;\n targetPath: string;\n};\n\nexport class TierMigrationExecutor {\n private readonly storage: StorageManager;\n private readonly qmd: SearchBackend;\n private readonly hotCollection: string;\n private readonly coldCollection: string;\n private readonly autoEmbed: boolean;\n private readonly journalPath: string;\n\n constructor(options: TierMigrationExecutorOptions) {\n this.storage = options.storage;\n this.qmd = options.qmd;\n this.hotCollection = options.hotCollection;\n this.coldCollection = options.coldCollection;\n this.autoEmbed = options.autoEmbed === true;\n this.journalPath = options.journalPath ?? path.join(this.storage.dir, \"state\", \"tier-migration-journal.jsonl\");\n }\n\n async migrateMemory(request: TierMigrationRequest): Promise<TierMigrationResult> {\n const { memory, fromTier, toTier, reason } = request;\n const targetPath = this.storage.buildTierMemoryPath(memory, toTier);\n\n if (fromTier === toTier) {\n const noChange: TierMigrationResult = {\n memoryId: memory.frontmatter.id,\n fromTier,\n toTier,\n changed: false,\n reason,\n targetPath,\n };\n await this.appendJournal(noChange);\n return noChange;\n }\n\n const moved = await this.storage.migrateMemoryToTier(memory, toTier);\n const result: TierMigrationResult = {\n memoryId: memory.frontmatter.id,\n fromTier,\n toTier,\n changed: moved.changed,\n reason,\n targetPath: moved.targetPath,\n };\n\n await this.appendJournal(result);\n\n if (result.changed) {\n const destinationCollection = this.collectionForTier(toTier);\n const sourceCollection = this.collectionForTier(fromTier);\n await this.updateCollectionFromTierRoot(destinationCollection, toTier);\n if (sourceCollection !== destinationCollection && this.qmd.updatesAllCollections?.() !== true) {\n await this.updateCollectionFromTierRoot(sourceCollection, fromTier);\n }\n if (this.autoEmbed) {\n await this.qmd.embedCollection(destinationCollection);\n if (sourceCollection !== destinationCollection) {\n await this.qmd.embedCollection(sourceCollection);\n }\n }\n }\n\n return result;\n }\n\n private collectionForTier(tier: MemoryTier): string {\n return tier === \"cold\" ? this.coldCollection : this.hotCollection;\n }\n\n private async updateCollectionFromTierRoot(collection: string, tier: MemoryTier): Promise<void> {\n const memoryDir = tier === \"cold\" ? path.join(this.storage.dir, \"cold\") : this.storage.dir;\n if (this.qmd.updatesAllCollections?.() !== true && this.qmd.updateCollectionFromDir) {\n await this.qmd.updateCollectionFromDir(collection, memoryDir);\n return;\n }\n await this.qmd.updateCollection(collection);\n }\n\n private async appendJournal(result: TierMigrationResult): Promise<void> {\n const entry: TierMigrationJournalEntry = {\n ts: new Date().toISOString(),\n memoryId: result.memoryId,\n fromTier: result.fromTier,\n toTier: result.toTier,\n changed: result.changed,\n reason: result.reason,\n targetPath: result.targetPath,\n };\n await mkdir(path.dirname(this.journalPath), { recursive: true });\n await appendFile(this.journalPath, `${JSON.stringify(entry)}\\n`, \"utf-8\");\n }\n}\n"],"mappings":";AAAA,SAAS,YAAY,aAAa;AAClC,OAAO,UAAU;AA2CV,IAAM,wBAAN,MAA4B;AAAA,EAChB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEjB,YAAY,SAAuC;AACjD,SAAK,UAAU,QAAQ;AACvB,SAAK,MAAM,QAAQ;AACnB,SAAK,gBAAgB,QAAQ;AAC7B,SAAK,iBAAiB,QAAQ;AAC9B,SAAK,YAAY,QAAQ,cAAc;AACvC,SAAK,cAAc,QAAQ,eAAe,KAAK,KAAK,KAAK,QAAQ,KAAK,SAAS,8BAA8B;AAAA,EAC/G;AAAA,EAEA,MAAM,cAAc,SAA6D;AAC/E,UAAM,EAAE,QAAQ,UAAU,QAAQ,OAAO,IAAI;AAC7C,UAAM,aAAa,KAAK,QAAQ,oBAAoB,QAAQ,MAAM;AAElE,QAAI,aAAa,QAAQ;AACvB,YAAM,WAAgC;AAAA,QACpC,UAAU,OAAO,YAAY;AAAA,QAC7B;AAAA,QACA;AAAA,QACA,SAAS;AAAA,QACT;AAAA,QACA;AAAA,MACF;AACA,YAAM,KAAK,cAAc,QAAQ;AACjC,aAAO;AAAA,IACT;AAEA,UAAM,QAAQ,MAAM,KAAK,QAAQ,oBAAoB,QAAQ,MAAM;AACnE,UAAM,SAA8B;AAAA,MAClC,UAAU,OAAO,YAAY;AAAA,MAC7B;AAAA,MACA;AAAA,MACA,SAAS,MAAM;AAAA,MACf;AAAA,MACA,YAAY,MAAM;AAAA,IACpB;AAEA,UAAM,KAAK,cAAc,MAAM;AAE/B,QAAI,OAAO,SAAS;AAClB,YAAM,wBAAwB,KAAK,kBAAkB,MAAM;AAC3D,YAAM,mBAAmB,KAAK,kBAAkB,QAAQ;AACxD,YAAM,KAAK,6BAA6B,uBAAuB,MAAM;AACrE,UAAI,qBAAqB,yBAAyB,KAAK,IAAI,wBAAwB,MAAM,MAAM;AAC7F,cAAM,KAAK,6BAA6B,kBAAkB,QAAQ;AAAA,MACpE;AACA,UAAI,KAAK,WAAW;AAClB,cAAM,KAAK,IAAI,gBAAgB,qBAAqB;AACpD,YAAI,qBAAqB,uBAAuB;AAC9C,gBAAM,KAAK,IAAI,gBAAgB,gBAAgB;AAAA,QACjD;AAAA,MACF;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEQ,kBAAkB,MAA0B;AAClD,WAAO,SAAS,SAAS,KAAK,iBAAiB,KAAK;AAAA,EACtD;AAAA,EAEA,MAAc,6BAA6B,YAAoB,MAAiC;AAC9F,UAAM,YAAY,SAAS,SAAS,KAAK,KAAK,KAAK,QAAQ,KAAK,MAAM,IAAI,KAAK,QAAQ;AACvF,QAAI,KAAK,IAAI,wBAAwB,MAAM,QAAQ,KAAK,IAAI,yBAAyB;AACnF,YAAM,KAAK,IAAI,wBAAwB,YAAY,SAAS;AAC5D;AAAA,IACF;AACA,UAAM,KAAK,IAAI,iBAAiB,UAAU;AAAA,EAC5C;AAAA,EAEA,MAAc,cAAc,QAA4C;AACtE,UAAM,QAAmC;AAAA,MACvC,KAAI,oBAAI,KAAK,GAAE,YAAY;AAAA,MAC3B,UAAU,OAAO;AAAA,MACjB,UAAU,OAAO;AAAA,MACjB,QAAQ,OAAO;AAAA,MACf,SAAS,OAAO;AAAA,MAChB,QAAQ,OAAO;AAAA,MACf,YAAY,OAAO;AAAA,IACrB;AACA,UAAM,MAAM,KAAK,QAAQ,KAAK,WAAW,GAAG,EAAE,WAAW,KAAK,CAAC;AAC/D,UAAM,WAAW,KAAK,aAAa,GAAG,KAAK,UAAU,KAAK,CAAC;AAAA,GAAM,OAAO;AAAA,EAC1E;AACF;","names":[]}
@@ -6,16 +6,16 @@ import {
6
6
  } from "./chunk-EWLQPEO6.js";
7
7
  import {
8
8
  LanceDbBackend
9
- } from "./chunk-6PTSXBPE.js";
9
+ } from "./chunk-ZDTVJXIP.js";
10
10
  import {
11
11
  MeilisearchBackend
12
- } from "./chunk-I4UNL747.js";
12
+ } from "./chunk-GMAG2HS4.js";
13
13
  import {
14
14
  NoopSearchBackend
15
15
  } from "./chunk-2I5JGH3M.js";
16
16
  import {
17
17
  OramaBackend
18
- } from "./chunk-M46RYSMW.js";
18
+ } from "./chunk-JHMFYY7L.js";
19
19
  import {
20
20
  createConversationIndexBackend
21
21
  } from "./chunk-KIB7SDIJ.js";
@@ -167,4 +167,4 @@ export {
167
167
  createConversationSearchBackend,
168
168
  createConversationIndexRuntime
169
169
  };
170
- //# sourceMappingURL=chunk-OB6353F7.js.map
170
+ //# sourceMappingURL=chunk-XPSVGJYA.js.map