@remnic/core 9.3.563 → 9.3.564

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 (156) hide show
  1. package/dist/access-cli.js +40 -39
  2. package/dist/access-cli.js.map +1 -1
  3. package/dist/access-http.js +16 -16
  4. package/dist/access-mcp.js +13 -13
  5. package/dist/access-schema.js +3 -3
  6. package/dist/access-service.js +11 -11
  7. package/dist/active-recall.js +1 -1
  8. package/dist/adapters/index.js +4 -4
  9. package/dist/adapters/registry.js +2 -2
  10. package/dist/briefing.js +4 -4
  11. package/dist/causal-consolidation.js +5 -5
  12. package/dist/{chunk-I2K6KCVC.js → chunk-2FHLI4U6.js} +49 -49
  13. package/dist/chunk-3ONXXHQO.js +57 -0
  14. package/dist/chunk-3ONXXHQO.js.map +1 -0
  15. package/dist/{chunk-5GX5MUQ2.js → chunk-574MU2Y3.js} +3 -3
  16. package/dist/{chunk-65OLPXBU.js → chunk-5WB4C7KM.js} +6 -6
  17. package/dist/chunk-6PTSXBPE.js +483 -0
  18. package/dist/chunk-6PTSXBPE.js.map +1 -0
  19. package/dist/{chunk-Z56KAZQL.js → chunk-74VA26CT.js} +2 -2
  20. package/dist/{chunk-CC2ESOOG.js → chunk-7X7TBJRX.js} +2 -2
  21. package/dist/{chunk-O4M4WH6V.js → chunk-ARY5OOLG.js} +2 -2
  22. package/dist/{chunk-JBPKEARU.js → chunk-AU7Q3LSC.js} +4 -4
  23. package/dist/{chunk-PM3QHTFT.js → chunk-CF3ZF2YU.js} +3 -3
  24. package/dist/{chunk-SI3QCHWF.js → chunk-DARLGSFX.js} +5 -5
  25. package/dist/chunk-EWLQPEO6.js +308 -0
  26. package/dist/chunk-EWLQPEO6.js.map +1 -0
  27. package/dist/{chunk-FVCZINOF.js → chunk-FHBEL473.js} +2 -2
  28. package/dist/{chunk-7Q3RCKAQ.js → chunk-FXKPZ3H6.js} +2 -2
  29. package/dist/{chunk-5WLYNZPC.js → chunk-GBXGCFRH.js} +2 -2
  30. package/dist/{chunk-ILJXM3FV.js → chunk-HQO5EBUC.js} +10 -10
  31. package/dist/{chunk-FK556DDH.js → chunk-I4UNL747.js} +4 -4
  32. package/dist/{chunk-RLPIT4YI.js → chunk-IOTTZLFF.js} +38 -38
  33. package/dist/{chunk-TVZ6LKKS.js → chunk-IRFF6LSF.js} +8 -8
  34. package/dist/{chunk-M5T4Q2ZU.js → chunk-KGK2QKWL.js} +1 -1
  35. package/dist/chunk-KGK2QKWL.js.map +1 -0
  36. package/dist/{chunk-IPLYGWQF.js → chunk-KQAFEZQX.js} +5 -5
  37. package/dist/chunk-M46RYSMW.js +597 -0
  38. package/dist/chunk-M46RYSMW.js.map +1 -0
  39. package/dist/{chunk-KXULCVOC.js → chunk-M6I5Z4SR.js} +4 -2
  40. package/dist/chunk-M6I5Z4SR.js.map +1 -0
  41. package/dist/{chunk-JFN6K74Q.js → chunk-MQEIWDYW.js} +2 -2
  42. package/dist/{chunk-7H6CFEBJ.js → chunk-NZPF2SYV.js} +8 -1
  43. package/dist/{chunk-7H6CFEBJ.js.map → chunk-NZPF2SYV.js.map} +1 -1
  44. package/dist/{chunk-SML26KED.js → chunk-OB6353F7.js} +16 -12
  45. package/dist/chunk-OB6353F7.js.map +1 -0
  46. package/dist/{chunk-SOTR74FK.js → chunk-OPYFD6PD.js} +2 -2
  47. package/dist/{chunk-3C5RPJAX.js → chunk-OXJBNGBK.js} +2 -2
  48. package/dist/{chunk-BD5LHQWD.js → chunk-PPPZY2EU.js} +2 -2
  49. package/dist/{chunk-25BY3HHZ.js → chunk-SUTSSOYU.js} +2 -2
  50. package/dist/{chunk-KS7WO6EQ.js → chunk-VFB2G5YL.js} +20 -20
  51. package/dist/{chunk-BUUYY2H2.js → chunk-WP5OWVLZ.js} +4 -4
  52. package/dist/{chunk-6URPAY2D.js → chunk-XCAZF7KQ.js} +207 -53
  53. package/dist/chunk-XCAZF7KQ.js.map +1 -0
  54. package/dist/{chunk-S53PAX2V.js → chunk-XM7BYXT7.js} +2 -2
  55. package/dist/{chunk-FADZBOR4.js → chunk-XRWTAEZM.js} +2 -2
  56. package/dist/{chunk-E5OECWZ5.js → chunk-XT7XVA53.js} +2 -2
  57. package/dist/{chunk-R3PS27B4.js → chunk-Z4R6RI2N.js} +2 -2
  58. package/dist/cli.js +44 -43
  59. package/dist/compounding/engine.js +4 -4
  60. package/dist/config.js +1 -1
  61. package/dist/connectors/codex-materialize-runner.js +4 -4
  62. package/dist/connectors/index.js +4 -4
  63. package/dist/embedding-fallback.d.ts +12 -1
  64. package/dist/embedding-fallback.js +4 -1
  65. package/dist/entity-retrieval.js +4 -4
  66. package/dist/host-embedding-provider.d.ts +21 -0
  67. package/dist/host-embedding-provider.js +14 -0
  68. package/dist/host-embedding-provider.js.map +1 -0
  69. package/dist/index.d.ts +1 -0
  70. package/dist/index.js +71 -63
  71. package/dist/index.js.map +1 -1
  72. package/dist/lcm/index.js +3 -3
  73. package/dist/maintenance/memory-governance.js +4 -4
  74. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +4 -4
  75. package/dist/maintenance/rebuild-memory-projection.js +5 -5
  76. package/dist/namespaces/migrate.js +14 -13
  77. package/dist/namespaces/search.js +9 -8
  78. package/dist/namespaces/storage.js +4 -4
  79. package/dist/operator-toolkit.js +17 -16
  80. package/dist/orchestrator.js +32 -31
  81. package/dist/recall-explain-renderer.js +3 -3
  82. package/dist/recall-xray-cli.js +4 -4
  83. package/dist/recall-xray-renderer.js +3 -3
  84. package/dist/recall-xray.js +2 -2
  85. package/dist/resume-bundles.js +2 -2
  86. package/dist/search/embed-helper.d.ts +48 -4
  87. package/dist/search/embed-helper.js +2 -1
  88. package/dist/search/factory.js +8 -7
  89. package/dist/search/index.d.ts +1 -0
  90. package/dist/search/index.js +12 -11
  91. package/dist/search/lancedb-backend.d.ts +11 -0
  92. package/dist/search/lancedb-backend.js +2 -2
  93. package/dist/search/meilisearch-backend.js +2 -2
  94. package/dist/search/orama-backend.d.ts +16 -0
  95. package/dist/search/orama-backend.js +2 -2
  96. package/dist/semantic-consolidation.js +5 -5
  97. package/dist/semantic-rule-promotion.js +4 -4
  98. package/dist/semantic-rule-verifier.js +4 -4
  99. package/dist/storage.js +3 -3
  100. package/dist/transfer/autodetect.js +1 -1
  101. package/dist/transfer/backup.js +1 -1
  102. package/dist/transfer/capsule-export.js +2 -2
  103. package/dist/transfer/types.d.ts +6 -6
  104. package/dist/types.d.ts +17 -0
  105. package/dist/types.js +1 -1
  106. package/dist/verified-recall.js +4 -4
  107. package/package.json +11 -1
  108. package/src/config.ts +18 -0
  109. package/src/embedding-fallback.ts +293 -61
  110. package/src/host-embedding-provider.ts +84 -0
  111. package/src/index.ts +7 -0
  112. package/src/namespaces/search.ts +9 -1
  113. package/src/qmd.test.ts +28 -0
  114. package/src/search/embed-helper.ts +319 -51
  115. package/src/search/factory.ts +6 -2
  116. package/src/search/lancedb-backend.ts +297 -41
  117. package/src/search/orama-backend.ts +418 -47
  118. package/src/types.ts +17 -0
  119. package/dist/chunk-6URPAY2D.js.map +0 -1
  120. package/dist/chunk-FUC4LZMD.js +0 -301
  121. package/dist/chunk-FUC4LZMD.js.map +0 -1
  122. package/dist/chunk-KXULCVOC.js.map +0 -1
  123. package/dist/chunk-M5T4Q2ZU.js.map +0 -1
  124. package/dist/chunk-ONPLNAPX.js +0 -133
  125. package/dist/chunk-ONPLNAPX.js.map +0 -1
  126. package/dist/chunk-QVJ4NWL2.js +0 -335
  127. package/dist/chunk-QVJ4NWL2.js.map +0 -1
  128. package/dist/chunk-SML26KED.js.map +0 -1
  129. /package/dist/{chunk-I2K6KCVC.js.map → chunk-2FHLI4U6.js.map} +0 -0
  130. /package/dist/{chunk-5GX5MUQ2.js.map → chunk-574MU2Y3.js.map} +0 -0
  131. /package/dist/{chunk-65OLPXBU.js.map → chunk-5WB4C7KM.js.map} +0 -0
  132. /package/dist/{chunk-Z56KAZQL.js.map → chunk-74VA26CT.js.map} +0 -0
  133. /package/dist/{chunk-CC2ESOOG.js.map → chunk-7X7TBJRX.js.map} +0 -0
  134. /package/dist/{chunk-O4M4WH6V.js.map → chunk-ARY5OOLG.js.map} +0 -0
  135. /package/dist/{chunk-JBPKEARU.js.map → chunk-AU7Q3LSC.js.map} +0 -0
  136. /package/dist/{chunk-PM3QHTFT.js.map → chunk-CF3ZF2YU.js.map} +0 -0
  137. /package/dist/{chunk-SI3QCHWF.js.map → chunk-DARLGSFX.js.map} +0 -0
  138. /package/dist/{chunk-FVCZINOF.js.map → chunk-FHBEL473.js.map} +0 -0
  139. /package/dist/{chunk-7Q3RCKAQ.js.map → chunk-FXKPZ3H6.js.map} +0 -0
  140. /package/dist/{chunk-5WLYNZPC.js.map → chunk-GBXGCFRH.js.map} +0 -0
  141. /package/dist/{chunk-ILJXM3FV.js.map → chunk-HQO5EBUC.js.map} +0 -0
  142. /package/dist/{chunk-FK556DDH.js.map → chunk-I4UNL747.js.map} +0 -0
  143. /package/dist/{chunk-RLPIT4YI.js.map → chunk-IOTTZLFF.js.map} +0 -0
  144. /package/dist/{chunk-TVZ6LKKS.js.map → chunk-IRFF6LSF.js.map} +0 -0
  145. /package/dist/{chunk-IPLYGWQF.js.map → chunk-KQAFEZQX.js.map} +0 -0
  146. /package/dist/{chunk-JFN6K74Q.js.map → chunk-MQEIWDYW.js.map} +0 -0
  147. /package/dist/{chunk-SOTR74FK.js.map → chunk-OPYFD6PD.js.map} +0 -0
  148. /package/dist/{chunk-3C5RPJAX.js.map → chunk-OXJBNGBK.js.map} +0 -0
  149. /package/dist/{chunk-BD5LHQWD.js.map → chunk-PPPZY2EU.js.map} +0 -0
  150. /package/dist/{chunk-25BY3HHZ.js.map → chunk-SUTSSOYU.js.map} +0 -0
  151. /package/dist/{chunk-KS7WO6EQ.js.map → chunk-VFB2G5YL.js.map} +0 -0
  152. /package/dist/{chunk-BUUYY2H2.js.map → chunk-WP5OWVLZ.js.map} +0 -0
  153. /package/dist/{chunk-S53PAX2V.js.map → chunk-XM7BYXT7.js.map} +0 -0
  154. /package/dist/{chunk-FADZBOR4.js.map → chunk-XRWTAEZM.js.map} +0 -0
  155. /package/dist/{chunk-E5OECWZ5.js.map → chunk-XT7XVA53.js.map} +0 -0
  156. /package/dist/{chunk-R3PS27B4.js.map → chunk-Z4R6RI2N.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 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(this.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
  createSearchBackend
3
- } from "./chunk-SML26KED.js";
3
+ } from "./chunk-OB6353F7.js";
4
4
  import {
5
5
  namespaceIdentityToken,
6
6
  normalizeNamespaceIdentity
@@ -129,9 +129,11 @@ var NamespaceSearchRouter = class {
129
129
  const pending = (async () => {
130
130
  const storage = await this.storageRouter.storageFor(key);
131
131
  const useLegacyDefaultCollection = key === this.config.defaultNamespace && storage.dir === this.config.memoryDir;
132
+ const rootHostEmbeddingScope = this.config.hostEmbeddingProviderScope ?? this.config.memoryDir;
132
133
  const scopedConfig = {
133
134
  ...this.config,
134
135
  memoryDir: storage.dir,
136
+ hostEmbeddingProviderScope: rootHostEmbeddingScope,
135
137
  qmdCollection: namespaceCollectionName(this.config.qmdCollection, key, {
136
138
  defaultNamespace: this.config.defaultNamespace,
137
139
  useLegacyDefaultCollection
@@ -177,4 +179,4 @@ export {
177
179
  namespaceCollectionName,
178
180
  NamespaceSearchRouter
179
181
  };
180
- //# sourceMappingURL=chunk-KXULCVOC.js.map
182
+ //# sourceMappingURL=chunk-M6I5Z4SR.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/namespaces/search.ts"],"sourcesContent":["import type { PluginConfig, QmdSearchResult } from \"../types.js\";\nimport type { SearchBackend, SearchExecutionOptions, SearchQueryOptions } from \"../search/port.js\";\nimport { createSearchBackend } from \"../search/factory.js\";\nimport { namespaceIdentityToken, normalizeNamespaceIdentity } from \"./identity.js\";\n\nexport function namespaceCollectionName(\n baseCollection: string,\n namespace: string,\n options?: {\n defaultNamespace?: string;\n useLegacyDefaultCollection?: boolean;\n },\n): string {\n const trimmed = normalizeNamespaceIdentity(namespace);\n const defaultNamespace = normalizeNamespaceIdentity(options?.defaultNamespace ?? \"\") || \"default\";\n if (\n options?.useLegacyDefaultCollection === true &&\n trimmed === defaultNamespace\n ) {\n return baseCollection;\n }\n\n return `${baseCollection}--${namespaceIdentityToken(trimmed || defaultNamespace)}`;\n}\n\ntype StorageRouterLike = {\n storageFor(namespace: string): Promise<{ dir: string }>;\n};\n\ntype NamespaceBackendRecord = {\n backend: SearchBackend;\n collection: string;\n memoryDir: string;\n available: boolean;\n collectionState: \"present\" | \"missing\" | \"unknown\" | \"skipped\";\n};\n\ntype NamespaceScopedSearchConfig = PluginConfig & {\n hostEmbeddingProviderScope?: string;\n};\n\nexport class NamespaceSearchRouter {\n private readonly cache = new Map<string, Promise<NamespaceBackendRecord>>();\n\n constructor(\n private readonly config: PluginConfig,\n private readonly storageRouter: StorageRouterLike,\n private readonly createBackend: (config: PluginConfig) => SearchBackend = createSearchBackend,\n ) {}\n\n async collectionForNamespace(namespace: string): Promise<string> {\n return (await this.backendRecordFor(namespace)).collection;\n }\n\n async searchAcrossNamespaces(options: {\n query: string;\n namespaces: string[];\n maxResults?: number;\n mode?: \"search\" | \"hybrid\" | \"bm25\" | \"vector\";\n searchOptions?: SearchQueryOptions;\n execution?: SearchExecutionOptions;\n }): Promise<QmdSearchResult[]> {\n const query = options.query.trim();\n if (!query) return [];\n const maxResults = Math.max(0, Math.floor(options.maxResults ?? this.config.qmdMaxResults));\n if (maxResults === 0) return [];\n\n const method = options.mode ?? \"search\";\n const namespaces = Array.from(new Set(options.namespaces.map((value) => value.trim()).filter(Boolean)));\n if (namespaces.length === 0) return [];\n\n const resultsByNamespace = await Promise.all(\n namespaces.map(async (namespace) => {\n const record = await this.backendRecordFor(namespace);\n if (!record.available || record.collectionState === \"missing\") {\n return { namespace, results: [] as QmdSearchResult[] };\n }\n let results: QmdSearchResult[];\n switch (method) {\n case \"hybrid\":\n results = await record.backend.hybridSearch(query, record.collection, maxResults, options.execution);\n break;\n case \"bm25\":\n results = await record.backend.bm25Search(query, record.collection, maxResults, options.execution);\n break;\n case \"vector\":\n results = await record.backend.vectorSearch(query, record.collection, maxResults, options.execution);\n break;\n default:\n results = await record.backend.search(\n query,\n record.collection,\n maxResults,\n options.searchOptions,\n options.execution,\n );\n break;\n }\n return { namespace, results };\n }),\n );\n\n return mergeNamespaceSearchResults(resultsByNamespace, maxResults);\n }\n\n /**\n * Update all namespace backends.\n * Returns the number of backends for which an update was attempted\n * (i.e., available and collection present). Callers can treat 0 as a\n * signal that no backend was eligible — useful for success-verification in\n * startup-sync when namespacesEnabled is true.\n */\n async updateNamespaces(\n namespaces: string[],\n execution?: SearchExecutionOptions,\n ): Promise<number> {\n const unique = Array.from(new Set(namespaces.map((value) => value.trim()).filter(Boolean)));\n const eligible = (await Promise.all(\n unique.map(async (namespace) => {\n const record = await this.backendRecordFor(namespace);\n return record.available && record.collectionState !== \"missing\"\n ? record\n : null;\n }),\n )).filter((record): record is NamespaceBackendRecord => record !== null);\n\n const globalRecord = eligible.find((record) => record.backend.updatesAllCollections?.() === true);\n const scopedRecords = globalRecord\n ? eligible.filter((record) => record.backend.updatesAllCollections?.() !== true)\n : eligible;\n\n await Promise.all([\n globalRecord ? globalRecord.backend.update(execution) : Promise.resolve(),\n ...scopedRecords.map((record) => record.backend.update(execution)),\n ]);\n\n return (globalRecord ? 1 : 0) + scopedRecords.length;\n }\n\n async embedNamespaces(namespaces: string[]): Promise<void> {\n const unique = Array.from(new Set(namespaces.map((value) => value.trim()).filter(Boolean)));\n await Promise.all(\n unique.map(async (namespace) => {\n const record = await this.backendRecordFor(namespace);\n if (!record.available || record.collectionState === \"missing\") return;\n await record.backend.embed();\n }),\n );\n }\n\n async ensureNamespaceCollection(\n namespace: string,\n execution?: SearchExecutionOptions,\n ): Promise<\"present\" | \"missing\" | \"unknown\" | \"skipped\"> {\n const record = await this.backendRecordFor(namespace, execution);\n return record.collectionState;\n }\n\n /** Clear cached backend records so the next access re-probes availability. */\n clearCache(): void {\n this.cache.clear();\n }\n\n /** Release any per-namespace backend handles held by cached records. */\n async dispose(): Promise<void> {\n const pendingRecords = Array.from(this.cache.values());\n this.cache.clear();\n const settled = await Promise.allSettled(pendingRecords);\n await Promise.allSettled(\n settled.flatMap((entry) => {\n if (entry.status !== \"fulfilled\") return [];\n const dispose = (entry.value.backend as { dispose?: () => void | Promise<void> }).dispose;\n return dispose ? [dispose.call(entry.value.backend)] : [];\n }),\n );\n }\n\n private async backendRecordFor(\n namespace: string,\n execution?: SearchExecutionOptions,\n ): Promise<NamespaceBackendRecord> {\n const key = namespace.trim() || this.config.defaultNamespace;\n const existing = this.cache.get(key);\n if (existing) return await existing;\n\n const pending = (async (): Promise<NamespaceBackendRecord> => {\n const storage = await this.storageRouter.storageFor(key);\n const useLegacyDefaultCollection =\n key === this.config.defaultNamespace && storage.dir === this.config.memoryDir;\n const rootHostEmbeddingScope =\n (this.config as NamespaceScopedSearchConfig).hostEmbeddingProviderScope ??\n this.config.memoryDir;\n const scopedConfig: NamespaceScopedSearchConfig = {\n ...this.config,\n memoryDir: storage.dir,\n hostEmbeddingProviderScope: rootHostEmbeddingScope,\n qmdCollection: namespaceCollectionName(this.config.qmdCollection, key, {\n defaultNamespace: this.config.defaultNamespace,\n useLegacyDefaultCollection,\n }),\n };\n\n const backend = this.createBackend(scopedConfig);\n const available = await backend.probe().catch(() => false);\n const collectionState = available\n ? await backend.ensureCollection(storage.dir, execution).catch(() => \"unknown\" as const)\n : \"unknown\";\n return {\n backend,\n collection: scopedConfig.qmdCollection,\n memoryDir: storage.dir,\n available,\n collectionState,\n };\n })();\n\n this.cache.set(key, pending);\n return await pending;\n }\n}\n\nfunction mergeNamespaceSearchResults(\n lists: Array<{ namespace: string; results: QmdSearchResult[] }>,\n maxResults: number,\n): QmdSearchResult[] {\n const merged = new Map<string, QmdSearchResult>();\n\n for (const { namespace, results } of lists) {\n for (const result of results) {\n const key = `${namespace}\\0${result.path || result.docid}`;\n const existing = merged.get(key);\n if (!existing) {\n merged.set(key, result);\n continue;\n }\n if (result.score > existing.score) {\n merged.set(key, {\n ...result,\n snippet: existing.snippet || result.snippet || \"\",\n });\n }\n }\n }\n\n return [...merged.values()]\n .sort((a, b) => b.score - a.score)\n .slice(0, maxResults);\n}\n"],"mappings":";;;;;;;;;AAKO,SAAS,wBACd,gBACA,WACA,SAIQ;AACR,QAAM,UAAU,2BAA2B,SAAS;AACpD,QAAM,mBAAmB,2BAA2B,SAAS,oBAAoB,EAAE,KAAK;AACxF,MACE,SAAS,+BAA+B,QACxC,YAAY,kBACZ;AACA,WAAO;AAAA,EACT;AAEA,SAAO,GAAG,cAAc,KAAK,uBAAuB,WAAW,gBAAgB,CAAC;AAClF;AAkBO,IAAM,wBAAN,MAA4B;AAAA,EAGjC,YACmB,QACA,eACA,gBAAyD,qBAC1E;AAHiB;AACA;AACA;AAAA,EAChB;AAAA,EAHgB;AAAA,EACA;AAAA,EACA;AAAA,EALF,QAAQ,oBAAI,IAA6C;AAAA,EAQ1E,MAAM,uBAAuB,WAAoC;AAC/D,YAAQ,MAAM,KAAK,iBAAiB,SAAS,GAAG;AAAA,EAClD;AAAA,EAEA,MAAM,uBAAuB,SAOE;AAC7B,UAAM,QAAQ,QAAQ,MAAM,KAAK;AACjC,QAAI,CAAC,MAAO,QAAO,CAAC;AACpB,UAAM,aAAa,KAAK,IAAI,GAAG,KAAK,MAAM,QAAQ,cAAc,KAAK,OAAO,aAAa,CAAC;AAC1F,QAAI,eAAe,EAAG,QAAO,CAAC;AAE9B,UAAM,SAAS,QAAQ,QAAQ;AAC/B,UAAM,aAAa,MAAM,KAAK,IAAI,IAAI,QAAQ,WAAW,IAAI,CAAC,UAAU,MAAM,KAAK,CAAC,EAAE,OAAO,OAAO,CAAC,CAAC;AACtG,QAAI,WAAW,WAAW,EAAG,QAAO,CAAC;AAErC,UAAM,qBAAqB,MAAM,QAAQ;AAAA,MACvC,WAAW,IAAI,OAAO,cAAc;AAClC,cAAM,SAAS,MAAM,KAAK,iBAAiB,SAAS;AACpD,YAAI,CAAC,OAAO,aAAa,OAAO,oBAAoB,WAAW;AAC7D,iBAAO,EAAE,WAAW,SAAS,CAAC,EAAuB;AAAA,QACvD;AACA,YAAI;AACJ,gBAAQ,QAAQ;AAAA,UACd,KAAK;AACH,sBAAU,MAAM,OAAO,QAAQ,aAAa,OAAO,OAAO,YAAY,YAAY,QAAQ,SAAS;AACnG;AAAA,UACF,KAAK;AACH,sBAAU,MAAM,OAAO,QAAQ,WAAW,OAAO,OAAO,YAAY,YAAY,QAAQ,SAAS;AACjG;AAAA,UACF,KAAK;AACH,sBAAU,MAAM,OAAO,QAAQ,aAAa,OAAO,OAAO,YAAY,YAAY,QAAQ,SAAS;AACnG;AAAA,UACF;AACE,sBAAU,MAAM,OAAO,QAAQ;AAAA,cAC7B;AAAA,cACA,OAAO;AAAA,cACP;AAAA,cACA,QAAQ;AAAA,cACR,QAAQ;AAAA,YACV;AACA;AAAA,QACJ;AACA,eAAO,EAAE,WAAW,QAAQ;AAAA,MAC9B,CAAC;AAAA,IACH;AAEA,WAAO,4BAA4B,oBAAoB,UAAU;AAAA,EACnE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,MAAM,iBACJ,YACA,WACiB;AACjB,UAAM,SAAS,MAAM,KAAK,IAAI,IAAI,WAAW,IAAI,CAAC,UAAU,MAAM,KAAK,CAAC,EAAE,OAAO,OAAO,CAAC,CAAC;AAC1F,UAAM,YAAY,MAAM,QAAQ;AAAA,MAC9B,OAAO,IAAI,OAAO,cAAc;AAC9B,cAAM,SAAS,MAAM,KAAK,iBAAiB,SAAS;AACpD,eAAO,OAAO,aAAa,OAAO,oBAAoB,YAClD,SACA;AAAA,MACN,CAAC;AAAA,IACH,GAAG,OAAO,CAAC,WAA6C,WAAW,IAAI;AAEvE,UAAM,eAAe,SAAS,KAAK,CAAC,WAAW,OAAO,QAAQ,wBAAwB,MAAM,IAAI;AAChG,UAAM,gBAAgB,eAClB,SAAS,OAAO,CAAC,WAAW,OAAO,QAAQ,wBAAwB,MAAM,IAAI,IAC7E;AAEJ,UAAM,QAAQ,IAAI;AAAA,MAChB,eAAe,aAAa,QAAQ,OAAO,SAAS,IAAI,QAAQ,QAAQ;AAAA,MACxE,GAAG,cAAc,IAAI,CAAC,WAAW,OAAO,QAAQ,OAAO,SAAS,CAAC;AAAA,IACnE,CAAC;AAED,YAAQ,eAAe,IAAI,KAAK,cAAc;AAAA,EAChD;AAAA,EAEA,MAAM,gBAAgB,YAAqC;AACzD,UAAM,SAAS,MAAM,KAAK,IAAI,IAAI,WAAW,IAAI,CAAC,UAAU,MAAM,KAAK,CAAC,EAAE,OAAO,OAAO,CAAC,CAAC;AAC1F,UAAM,QAAQ;AAAA,MACZ,OAAO,IAAI,OAAO,cAAc;AAC9B,cAAM,SAAS,MAAM,KAAK,iBAAiB,SAAS;AACpD,YAAI,CAAC,OAAO,aAAa,OAAO,oBAAoB,UAAW;AAC/D,cAAM,OAAO,QAAQ,MAAM;AAAA,MAC7B,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,MAAM,0BACJ,WACA,WACwD;AACxD,UAAM,SAAS,MAAM,KAAK,iBAAiB,WAAW,SAAS;AAC/D,WAAO,OAAO;AAAA,EAChB;AAAA;AAAA,EAGA,aAAmB;AACjB,SAAK,MAAM,MAAM;AAAA,EACnB;AAAA;AAAA,EAGA,MAAM,UAAyB;AAC7B,UAAM,iBAAiB,MAAM,KAAK,KAAK,MAAM,OAAO,CAAC;AACrD,SAAK,MAAM,MAAM;AACjB,UAAM,UAAU,MAAM,QAAQ,WAAW,cAAc;AACvD,UAAM,QAAQ;AAAA,MACZ,QAAQ,QAAQ,CAAC,UAAU;AACzB,YAAI,MAAM,WAAW,YAAa,QAAO,CAAC;AAC1C,cAAM,UAAW,MAAM,MAAM,QAAqD;AAClF,eAAO,UAAU,CAAC,QAAQ,KAAK,MAAM,MAAM,OAAO,CAAC,IAAI,CAAC;AAAA,MAC1D,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,MAAc,iBACZ,WACA,WACiC;AACjC,UAAM,MAAM,UAAU,KAAK,KAAK,KAAK,OAAO;AAC5C,UAAM,WAAW,KAAK,MAAM,IAAI,GAAG;AACnC,QAAI,SAAU,QAAO,MAAM;AAE3B,UAAM,WAAW,YAA6C;AAC5D,YAAM,UAAU,MAAM,KAAK,cAAc,WAAW,GAAG;AACvD,YAAM,6BACJ,QAAQ,KAAK,OAAO,oBAAoB,QAAQ,QAAQ,KAAK,OAAO;AACtE,YAAM,yBACH,KAAK,OAAuC,8BAC7C,KAAK,OAAO;AACd,YAAM,eAA4C;AAAA,QAChD,GAAG,KAAK;AAAA,QACR,WAAW,QAAQ;AAAA,QACnB,4BAA4B;AAAA,QAC5B,eAAe,wBAAwB,KAAK,OAAO,eAAe,KAAK;AAAA,UACrE,kBAAkB,KAAK,OAAO;AAAA,UAC9B;AAAA,QACF,CAAC;AAAA,MACH;AAEA,YAAM,UAAU,KAAK,cAAc,YAAY;AAC/C,YAAM,YAAY,MAAM,QAAQ,MAAM,EAAE,MAAM,MAAM,KAAK;AACzD,YAAM,kBAAkB,YACpB,MAAM,QAAQ,iBAAiB,QAAQ,KAAK,SAAS,EAAE,MAAM,MAAM,SAAkB,IACrF;AACJ,aAAO;AAAA,QACL;AAAA,QACA,YAAY,aAAa;AAAA,QACzB,WAAW,QAAQ;AAAA,QACnB;AAAA,QACA;AAAA,MACF;AAAA,IACF,GAAG;AAEH,SAAK,MAAM,IAAI,KAAK,OAAO;AAC3B,WAAO,MAAM;AAAA,EACf;AACF;AAEA,SAAS,4BACP,OACA,YACmB;AACnB,QAAM,SAAS,oBAAI,IAA6B;AAEhD,aAAW,EAAE,WAAW,QAAQ,KAAK,OAAO;AAC1C,eAAW,UAAU,SAAS;AAC5B,YAAM,MAAM,GAAG,SAAS,KAAK,OAAO,QAAQ,OAAO,KAAK;AACxD,YAAM,WAAW,OAAO,IAAI,GAAG;AAC/B,UAAI,CAAC,UAAU;AACb,eAAO,IAAI,KAAK,MAAM;AACtB;AAAA,MACF;AACA,UAAI,OAAO,QAAQ,SAAS,OAAO;AACjC,eAAO,IAAI,KAAK;AAAA,UACd,GAAG;AAAA,UACH,SAAS,SAAS,WAAW,OAAO,WAAW;AAAA,QACjD,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAEA,SAAO,CAAC,GAAG,OAAO,OAAO,CAAC,EACvB,KAAK,CAAC,GAAG,MAAM,EAAE,QAAQ,EAAE,KAAK,EAChC,MAAM,GAAG,UAAU;AACxB;","names":[]}
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  StorageManager,
3
3
  normalizeEntityName
4
- } from "./chunk-TVZ6LKKS.js";
4
+ } from "./chunk-IRFF6LSF.js";
5
5
  import {
6
6
  readEnvVar,
7
7
  resolveHomeDir
@@ -824,4 +824,4 @@ export {
824
824
  resolveBriefingSaveDir,
825
825
  briefingFilename
826
826
  };
827
- //# sourceMappingURL=chunk-JFN6K74Q.js.map
827
+ //# sourceMappingURL=chunk-MQEIWDYW.js.map
@@ -769,6 +769,9 @@ function parseConfig(raw) {
769
769
  qmdGenerateModel: parseOptionalNonEmptyString(cfg.qmdGenerateModel),
770
770
  embeddingFallbackEnabled: cfg.embeddingFallbackEnabled !== false,
771
771
  embeddingFallbackProvider: cfg.embeddingFallbackProvider === "openai" ? "openai" : cfg.embeddingFallbackProvider === "local" ? "local" : "auto",
772
+ hostEmbeddingProviderEnabled: coerceBooleanLike(cfg.hostEmbeddingProviderEnabled) ?? coerceBooleanLike(cfg.openclawHostEmbeddingProviderEnabled) ?? true,
773
+ hostEmbeddingProviderId: parseOptionalNonEmptyString(cfg.hostEmbeddingProviderId) ?? parseOptionalNonEmptyString(cfg.openclawHostEmbeddingProviderId),
774
+ hostEmbeddingProviderModel: parseOptionalNonEmptyString(cfg.hostEmbeddingProviderModel) ?? parseOptionalNonEmptyString(cfg.openclawHostEmbeddingProviderModel),
772
775
  embeddingFallbackModel: typeof cfg.embeddingFallbackModel === "string" && cfg.embeddingFallbackModel.length > 0 ? cfg.embeddingFallbackModel : "",
773
776
  qmdPath: typeof cfg.qmdPath === "string" && cfg.qmdPath.length > 0 ? cfg.qmdPath : void 0,
774
777
  memoryDir,
@@ -1029,6 +1032,10 @@ function parseConfig(raw) {
1029
1032
  commandsListEnabled: cfg.commandsListEnabled !== false,
1030
1033
  openclawToolsEnabled: cfg.openclawToolsEnabled !== false,
1031
1034
  openclawToolSnippetMaxChars: typeof cfg.openclawToolSnippetMaxChars === "number" ? Math.min(4e3, Math.max(80, Math.floor(cfg.openclawToolSnippetMaxChars))) : 600,
1035
+ openclawMessageReceivedCaptureEnabled: coerceBooleanLike(cfg.openclawMessageReceivedCaptureEnabled) ?? true,
1036
+ openclawReplyMetadataCaptureEnabled: coerceBooleanLike(cfg.openclawReplyMetadataCaptureEnabled) ?? true,
1037
+ openclawReplyMetadataExtractionHintsEnabled: coerceBooleanLike(cfg.openclawReplyMetadataExtractionHintsEnabled) ?? false,
1038
+ openclawChannelEnvelopeCleaningEnabled: coerceBooleanLike(cfg.openclawChannelEnvelopeCleaningEnabled) ?? true,
1032
1039
  sessionTogglesEnabled: cfg.sessionTogglesEnabled !== false,
1033
1040
  verboseRecallVisibility: cfg.verboseRecallVisibility !== false,
1034
1041
  recallTranscriptsEnabled: cfg.recallTranscriptsEnabled === true,
@@ -2296,4 +2303,4 @@ export {
2296
2303
  VALID_MEMORY_CATEGORIES,
2297
2304
  parseConfig
2298
2305
  };
2299
- //# sourceMappingURL=chunk-7H6CFEBJ.js.map
2306
+ //# sourceMappingURL=chunk-NZPF2SYV.js.map