rag-lite-ts 2.1.1 → 2.3.0

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 (328) hide show
  1. package/README.md +88 -5
  2. package/dist/{cli → cjs/cli}/indexer.js +73 -15
  3. package/dist/cjs/cli/ui-server.d.ts +5 -0
  4. package/dist/cjs/cli/ui-server.js +152 -0
  5. package/dist/{cli.js → cjs/cli.js} +25 -6
  6. package/dist/{core → cjs/core}/binary-index-format.js +6 -3
  7. package/dist/{core → cjs/core}/db.d.ts +56 -0
  8. package/dist/{core → cjs/core}/db.js +105 -0
  9. package/dist/{core → cjs/core}/ingestion.js +3 -0
  10. package/dist/cjs/core/knowledge-base-manager.d.ts +109 -0
  11. package/dist/cjs/core/knowledge-base-manager.js +256 -0
  12. package/dist/{core → cjs/core}/model-validator.js +1 -1
  13. package/dist/{core → cjs/core}/search-pipeline.js +1 -1
  14. package/dist/{core → cjs/core}/search.js +1 -1
  15. package/dist/cjs/core/vector-index-messages.d.ts +52 -0
  16. package/dist/cjs/core/vector-index-messages.js +5 -0
  17. package/dist/cjs/core/vector-index-worker.d.ts +6 -0
  18. package/dist/cjs/core/vector-index-worker.js +304 -0
  19. package/dist/cjs/core/vector-index.d.ts +107 -0
  20. package/dist/cjs/core/vector-index.js +344 -0
  21. package/dist/{factories → cjs/factories}/ingestion-factory.js +3 -7
  22. package/dist/{factories → cjs/factories}/search-factory.js +11 -0
  23. package/dist/{index-manager.d.ts → cjs/index-manager.d.ts} +23 -3
  24. package/dist/{index-manager.js → cjs/index-manager.js} +84 -15
  25. package/dist/{index.d.ts → cjs/index.d.ts} +2 -1
  26. package/dist/{index.js → cjs/index.js} +3 -1
  27. package/dist/esm/api-errors.d.ts +90 -0
  28. package/dist/esm/api-errors.js +320 -0
  29. package/dist/esm/cli/indexer.d.ts +11 -0
  30. package/dist/esm/cli/indexer.js +529 -0
  31. package/dist/esm/cli/search.d.ts +7 -0
  32. package/dist/esm/cli/search.js +332 -0
  33. package/dist/esm/cli/ui-server.d.ts +5 -0
  34. package/dist/esm/cli/ui-server.js +152 -0
  35. package/dist/esm/cli.d.ts +3 -0
  36. package/dist/esm/cli.js +548 -0
  37. package/dist/esm/config.d.ts +51 -0
  38. package/dist/esm/config.js +79 -0
  39. package/dist/esm/core/abstract-embedder.d.ts +125 -0
  40. package/dist/esm/core/abstract-embedder.js +264 -0
  41. package/dist/esm/core/actionable-error-messages.d.ts +60 -0
  42. package/dist/esm/core/actionable-error-messages.js +397 -0
  43. package/dist/esm/core/adapters.d.ts +93 -0
  44. package/dist/esm/core/adapters.js +139 -0
  45. package/dist/esm/core/batch-processing-optimizer.d.ts +155 -0
  46. package/dist/esm/core/batch-processing-optimizer.js +536 -0
  47. package/dist/esm/core/binary-index-format.d.ts +78 -0
  48. package/dist/esm/core/binary-index-format.js +294 -0
  49. package/dist/esm/core/chunker.d.ts +119 -0
  50. package/dist/esm/core/chunker.js +73 -0
  51. package/dist/esm/core/cli-database-utils.d.ts +53 -0
  52. package/dist/esm/core/cli-database-utils.js +239 -0
  53. package/dist/esm/core/config.d.ts +102 -0
  54. package/dist/esm/core/config.js +247 -0
  55. package/dist/esm/core/content-errors.d.ts +111 -0
  56. package/dist/esm/core/content-errors.js +362 -0
  57. package/dist/esm/core/content-manager.d.ts +335 -0
  58. package/dist/esm/core/content-manager.js +1476 -0
  59. package/dist/esm/core/content-performance-optimizer.d.ts +150 -0
  60. package/dist/esm/core/content-performance-optimizer.js +516 -0
  61. package/dist/esm/core/content-resolver.d.ts +104 -0
  62. package/dist/esm/core/content-resolver.js +285 -0
  63. package/dist/esm/core/cross-modal-search.d.ts +164 -0
  64. package/dist/esm/core/cross-modal-search.js +342 -0
  65. package/dist/esm/core/database-connection-manager.d.ts +109 -0
  66. package/dist/esm/core/database-connection-manager.js +310 -0
  67. package/dist/esm/core/db.d.ts +269 -0
  68. package/dist/esm/core/db.js +1000 -0
  69. package/dist/esm/core/embedder-factory.d.ts +154 -0
  70. package/dist/esm/core/embedder-factory.js +311 -0
  71. package/dist/esm/core/error-handler.d.ts +112 -0
  72. package/dist/esm/core/error-handler.js +239 -0
  73. package/dist/esm/core/index.d.ts +59 -0
  74. package/dist/esm/core/index.js +69 -0
  75. package/dist/esm/core/ingestion.d.ts +202 -0
  76. package/dist/esm/core/ingestion.js +904 -0
  77. package/dist/esm/core/interfaces.d.ts +408 -0
  78. package/dist/esm/core/interfaces.js +106 -0
  79. package/dist/esm/core/knowledge-base-manager.d.ts +109 -0
  80. package/dist/esm/core/knowledge-base-manager.js +256 -0
  81. package/dist/esm/core/lazy-dependency-loader.d.ts +147 -0
  82. package/dist/esm/core/lazy-dependency-loader.js +435 -0
  83. package/dist/esm/core/mode-detection-service.d.ts +150 -0
  84. package/dist/esm/core/mode-detection-service.js +565 -0
  85. package/dist/esm/core/mode-model-validator.d.ts +92 -0
  86. package/dist/esm/core/mode-model-validator.js +203 -0
  87. package/dist/esm/core/model-registry.d.ts +116 -0
  88. package/dist/esm/core/model-registry.js +411 -0
  89. package/dist/esm/core/model-validator.d.ts +217 -0
  90. package/dist/esm/core/model-validator.js +782 -0
  91. package/dist/esm/core/path-manager.d.ts +47 -0
  92. package/dist/esm/core/path-manager.js +71 -0
  93. package/dist/esm/core/raglite-paths.d.ts +121 -0
  94. package/dist/esm/core/raglite-paths.js +145 -0
  95. package/dist/esm/core/reranking-config.d.ts +42 -0
  96. package/dist/esm/core/reranking-config.js +147 -0
  97. package/dist/esm/core/reranking-factory.d.ts +92 -0
  98. package/dist/esm/core/reranking-factory.js +410 -0
  99. package/dist/esm/core/reranking-strategies.d.ts +310 -0
  100. package/dist/esm/core/reranking-strategies.js +650 -0
  101. package/dist/esm/core/resource-cleanup.d.ts +163 -0
  102. package/dist/esm/core/resource-cleanup.js +371 -0
  103. package/dist/esm/core/resource-manager.d.ts +212 -0
  104. package/dist/esm/core/resource-manager.js +564 -0
  105. package/dist/esm/core/search-pipeline.d.ts +111 -0
  106. package/dist/esm/core/search-pipeline.js +287 -0
  107. package/dist/esm/core/search.d.ts +141 -0
  108. package/dist/esm/core/search.js +320 -0
  109. package/dist/esm/core/streaming-operations.d.ts +145 -0
  110. package/dist/esm/core/streaming-operations.js +409 -0
  111. package/dist/esm/core/types.d.ts +66 -0
  112. package/dist/esm/core/types.js +6 -0
  113. package/dist/esm/core/universal-embedder.d.ts +177 -0
  114. package/dist/esm/core/universal-embedder.js +139 -0
  115. package/dist/esm/core/validation-messages.d.ts +99 -0
  116. package/dist/esm/core/validation-messages.js +334 -0
  117. package/dist/esm/core/vector-index-messages.d.ts +52 -0
  118. package/dist/esm/core/vector-index-messages.js +5 -0
  119. package/dist/esm/core/vector-index-worker.d.ts +6 -0
  120. package/dist/esm/core/vector-index-worker.js +304 -0
  121. package/dist/esm/core/vector-index.d.ts +107 -0
  122. package/dist/esm/core/vector-index.js +344 -0
  123. package/dist/esm/dom-polyfills.d.ts +6 -0
  124. package/dist/esm/dom-polyfills.js +37 -0
  125. package/dist/esm/factories/index.d.ts +27 -0
  126. package/dist/esm/factories/index.js +29 -0
  127. package/dist/esm/factories/ingestion-factory.d.ts +200 -0
  128. package/dist/esm/factories/ingestion-factory.js +473 -0
  129. package/dist/esm/factories/search-factory.d.ts +154 -0
  130. package/dist/esm/factories/search-factory.js +355 -0
  131. package/dist/esm/file-processor.d.ts +147 -0
  132. package/dist/esm/file-processor.js +963 -0
  133. package/dist/esm/index-manager.d.ts +136 -0
  134. package/dist/esm/index-manager.js +667 -0
  135. package/dist/esm/index.d.ts +76 -0
  136. package/dist/esm/index.js +112 -0
  137. package/dist/esm/indexer.d.ts +7 -0
  138. package/dist/esm/indexer.js +54 -0
  139. package/dist/esm/ingestion.d.ts +63 -0
  140. package/dist/esm/ingestion.js +124 -0
  141. package/dist/esm/mcp-server.d.ts +46 -0
  142. package/dist/esm/mcp-server.js +1820 -0
  143. package/dist/esm/multimodal/clip-embedder.d.ts +327 -0
  144. package/dist/esm/multimodal/clip-embedder.js +996 -0
  145. package/dist/esm/multimodal/index.d.ts +6 -0
  146. package/dist/esm/multimodal/index.js +6 -0
  147. package/dist/esm/preprocess.d.ts +19 -0
  148. package/dist/esm/preprocess.js +203 -0
  149. package/dist/esm/preprocessors/index.d.ts +17 -0
  150. package/dist/esm/preprocessors/index.js +38 -0
  151. package/dist/esm/preprocessors/mdx.d.ts +25 -0
  152. package/dist/esm/preprocessors/mdx.js +101 -0
  153. package/dist/esm/preprocessors/mermaid.d.ts +68 -0
  154. package/dist/esm/preprocessors/mermaid.js +329 -0
  155. package/dist/esm/preprocessors/registry.d.ts +56 -0
  156. package/dist/esm/preprocessors/registry.js +179 -0
  157. package/dist/esm/run-error-recovery-tests.d.ts +7 -0
  158. package/dist/esm/run-error-recovery-tests.js +101 -0
  159. package/dist/esm/search-standalone.d.ts +7 -0
  160. package/dist/esm/search-standalone.js +117 -0
  161. package/dist/esm/search.d.ts +99 -0
  162. package/dist/esm/search.js +177 -0
  163. package/dist/esm/test-utils.d.ts +18 -0
  164. package/dist/esm/test-utils.js +27 -0
  165. package/dist/esm/text/chunker.d.ts +33 -0
  166. package/dist/esm/text/chunker.js +279 -0
  167. package/dist/esm/text/embedder.d.ts +111 -0
  168. package/dist/esm/text/embedder.js +386 -0
  169. package/dist/esm/text/index.d.ts +8 -0
  170. package/dist/esm/text/index.js +9 -0
  171. package/dist/esm/text/preprocessors/index.d.ts +17 -0
  172. package/dist/esm/text/preprocessors/index.js +38 -0
  173. package/dist/esm/text/preprocessors/mdx.d.ts +25 -0
  174. package/dist/esm/text/preprocessors/mdx.js +101 -0
  175. package/dist/esm/text/preprocessors/mermaid.d.ts +68 -0
  176. package/dist/esm/text/preprocessors/mermaid.js +330 -0
  177. package/dist/esm/text/preprocessors/registry.d.ts +56 -0
  178. package/dist/esm/text/preprocessors/registry.js +180 -0
  179. package/dist/esm/text/reranker.d.ts +49 -0
  180. package/dist/esm/text/reranker.js +274 -0
  181. package/dist/esm/text/sentence-transformer-embedder.d.ts +96 -0
  182. package/dist/esm/text/sentence-transformer-embedder.js +340 -0
  183. package/dist/esm/text/tokenizer.d.ts +22 -0
  184. package/dist/esm/text/tokenizer.js +64 -0
  185. package/dist/esm/types.d.ts +83 -0
  186. package/dist/esm/types.js +3 -0
  187. package/dist/esm/utils/vector-math.d.ts +31 -0
  188. package/dist/esm/utils/vector-math.js +70 -0
  189. package/package.json +39 -14
  190. package/dist/core/vector-index.d.ts +0 -72
  191. package/dist/core/vector-index.js +0 -331
  192. /package/dist/{api-errors.d.ts → cjs/api-errors.d.ts} +0 -0
  193. /package/dist/{api-errors.js → cjs/api-errors.js} +0 -0
  194. /package/dist/{cli → cjs/cli}/indexer.d.ts +0 -0
  195. /package/dist/{cli → cjs/cli}/search.d.ts +0 -0
  196. /package/dist/{cli → cjs/cli}/search.js +0 -0
  197. /package/dist/{cli.d.ts → cjs/cli.d.ts} +0 -0
  198. /package/dist/{config.d.ts → cjs/config.d.ts} +0 -0
  199. /package/dist/{config.js → cjs/config.js} +0 -0
  200. /package/dist/{core → cjs/core}/abstract-embedder.d.ts +0 -0
  201. /package/dist/{core → cjs/core}/abstract-embedder.js +0 -0
  202. /package/dist/{core → cjs/core}/actionable-error-messages.d.ts +0 -0
  203. /package/dist/{core → cjs/core}/actionable-error-messages.js +0 -0
  204. /package/dist/{core → cjs/core}/adapters.d.ts +0 -0
  205. /package/dist/{core → cjs/core}/adapters.js +0 -0
  206. /package/dist/{core → cjs/core}/batch-processing-optimizer.d.ts +0 -0
  207. /package/dist/{core → cjs/core}/batch-processing-optimizer.js +0 -0
  208. /package/dist/{core → cjs/core}/binary-index-format.d.ts +0 -0
  209. /package/dist/{core → cjs/core}/chunker.d.ts +0 -0
  210. /package/dist/{core → cjs/core}/chunker.js +0 -0
  211. /package/dist/{core → cjs/core}/cli-database-utils.d.ts +0 -0
  212. /package/dist/{core → cjs/core}/cli-database-utils.js +0 -0
  213. /package/dist/{core → cjs/core}/config.d.ts +0 -0
  214. /package/dist/{core → cjs/core}/config.js +0 -0
  215. /package/dist/{core → cjs/core}/content-errors.d.ts +0 -0
  216. /package/dist/{core → cjs/core}/content-errors.js +0 -0
  217. /package/dist/{core → cjs/core}/content-manager.d.ts +0 -0
  218. /package/dist/{core → cjs/core}/content-manager.js +0 -0
  219. /package/dist/{core → cjs/core}/content-performance-optimizer.d.ts +0 -0
  220. /package/dist/{core → cjs/core}/content-performance-optimizer.js +0 -0
  221. /package/dist/{core → cjs/core}/content-resolver.d.ts +0 -0
  222. /package/dist/{core → cjs/core}/content-resolver.js +0 -0
  223. /package/dist/{core → cjs/core}/cross-modal-search.d.ts +0 -0
  224. /package/dist/{core → cjs/core}/cross-modal-search.js +0 -0
  225. /package/dist/{core → cjs/core}/database-connection-manager.d.ts +0 -0
  226. /package/dist/{core → cjs/core}/database-connection-manager.js +0 -0
  227. /package/dist/{core → cjs/core}/embedder-factory.d.ts +0 -0
  228. /package/dist/{core → cjs/core}/embedder-factory.js +0 -0
  229. /package/dist/{core → cjs/core}/error-handler.d.ts +0 -0
  230. /package/dist/{core → cjs/core}/error-handler.js +0 -0
  231. /package/dist/{core → cjs/core}/index.d.ts +0 -0
  232. /package/dist/{core → cjs/core}/index.js +0 -0
  233. /package/dist/{core → cjs/core}/ingestion.d.ts +0 -0
  234. /package/dist/{core → cjs/core}/interfaces.d.ts +0 -0
  235. /package/dist/{core → cjs/core}/interfaces.js +0 -0
  236. /package/dist/{core → cjs/core}/lazy-dependency-loader.d.ts +0 -0
  237. /package/dist/{core → cjs/core}/lazy-dependency-loader.js +0 -0
  238. /package/dist/{core → cjs/core}/mode-detection-service.d.ts +0 -0
  239. /package/dist/{core → cjs/core}/mode-detection-service.js +0 -0
  240. /package/dist/{core → cjs/core}/mode-model-validator.d.ts +0 -0
  241. /package/dist/{core → cjs/core}/mode-model-validator.js +0 -0
  242. /package/dist/{core → cjs/core}/model-registry.d.ts +0 -0
  243. /package/dist/{core → cjs/core}/model-registry.js +0 -0
  244. /package/dist/{core → cjs/core}/model-validator.d.ts +0 -0
  245. /package/dist/{core → cjs/core}/path-manager.d.ts +0 -0
  246. /package/dist/{core → cjs/core}/path-manager.js +0 -0
  247. /package/dist/{core → cjs/core}/raglite-paths.d.ts +0 -0
  248. /package/dist/{core → cjs/core}/raglite-paths.js +0 -0
  249. /package/dist/{core → cjs/core}/reranking-config.d.ts +0 -0
  250. /package/dist/{core → cjs/core}/reranking-config.js +0 -0
  251. /package/dist/{core → cjs/core}/reranking-factory.d.ts +0 -0
  252. /package/dist/{core → cjs/core}/reranking-factory.js +0 -0
  253. /package/dist/{core → cjs/core}/reranking-strategies.d.ts +0 -0
  254. /package/dist/{core → cjs/core}/reranking-strategies.js +0 -0
  255. /package/dist/{core → cjs/core}/resource-cleanup.d.ts +0 -0
  256. /package/dist/{core → cjs/core}/resource-cleanup.js +0 -0
  257. /package/dist/{core → cjs/core}/resource-manager.d.ts +0 -0
  258. /package/dist/{core → cjs/core}/resource-manager.js +0 -0
  259. /package/dist/{core → cjs/core}/search-pipeline.d.ts +0 -0
  260. /package/dist/{core → cjs/core}/search.d.ts +0 -0
  261. /package/dist/{core → cjs/core}/streaming-operations.d.ts +0 -0
  262. /package/dist/{core → cjs/core}/streaming-operations.js +0 -0
  263. /package/dist/{core → cjs/core}/types.d.ts +0 -0
  264. /package/dist/{core → cjs/core}/types.js +0 -0
  265. /package/dist/{core → cjs/core}/universal-embedder.d.ts +0 -0
  266. /package/dist/{core → cjs/core}/universal-embedder.js +0 -0
  267. /package/dist/{core → cjs/core}/validation-messages.d.ts +0 -0
  268. /package/dist/{core → cjs/core}/validation-messages.js +0 -0
  269. /package/dist/{dom-polyfills.d.ts → cjs/dom-polyfills.d.ts} +0 -0
  270. /package/dist/{dom-polyfills.js → cjs/dom-polyfills.js} +0 -0
  271. /package/dist/{factories → cjs/factories}/index.d.ts +0 -0
  272. /package/dist/{factories → cjs/factories}/index.js +0 -0
  273. /package/dist/{factories → cjs/factories}/ingestion-factory.d.ts +0 -0
  274. /package/dist/{factories → cjs/factories}/search-factory.d.ts +0 -0
  275. /package/dist/{file-processor.d.ts → cjs/file-processor.d.ts} +0 -0
  276. /package/dist/{file-processor.js → cjs/file-processor.js} +0 -0
  277. /package/dist/{indexer.d.ts → cjs/indexer.d.ts} +0 -0
  278. /package/dist/{indexer.js → cjs/indexer.js} +0 -0
  279. /package/dist/{ingestion.d.ts → cjs/ingestion.d.ts} +0 -0
  280. /package/dist/{ingestion.js → cjs/ingestion.js} +0 -0
  281. /package/dist/{mcp-server.d.ts → cjs/mcp-server.d.ts} +0 -0
  282. /package/dist/{mcp-server.js → cjs/mcp-server.js} +0 -0
  283. /package/dist/{multimodal → cjs/multimodal}/clip-embedder.d.ts +0 -0
  284. /package/dist/{multimodal → cjs/multimodal}/clip-embedder.js +0 -0
  285. /package/dist/{multimodal → cjs/multimodal}/index.d.ts +0 -0
  286. /package/dist/{multimodal → cjs/multimodal}/index.js +0 -0
  287. /package/dist/{preprocess.d.ts → cjs/preprocess.d.ts} +0 -0
  288. /package/dist/{preprocess.js → cjs/preprocess.js} +0 -0
  289. /package/dist/{preprocessors → cjs/preprocessors}/index.d.ts +0 -0
  290. /package/dist/{preprocessors → cjs/preprocessors}/index.js +0 -0
  291. /package/dist/{preprocessors → cjs/preprocessors}/mdx.d.ts +0 -0
  292. /package/dist/{preprocessors → cjs/preprocessors}/mdx.js +0 -0
  293. /package/dist/{preprocessors → cjs/preprocessors}/mermaid.d.ts +0 -0
  294. /package/dist/{preprocessors → cjs/preprocessors}/mermaid.js +0 -0
  295. /package/dist/{preprocessors → cjs/preprocessors}/registry.d.ts +0 -0
  296. /package/dist/{preprocessors → cjs/preprocessors}/registry.js +0 -0
  297. /package/dist/{run-error-recovery-tests.d.ts → cjs/run-error-recovery-tests.d.ts} +0 -0
  298. /package/dist/{run-error-recovery-tests.js → cjs/run-error-recovery-tests.js} +0 -0
  299. /package/dist/{search-standalone.d.ts → cjs/search-standalone.d.ts} +0 -0
  300. /package/dist/{search-standalone.js → cjs/search-standalone.js} +0 -0
  301. /package/dist/{search.d.ts → cjs/search.d.ts} +0 -0
  302. /package/dist/{search.js → cjs/search.js} +0 -0
  303. /package/dist/{test-utils.d.ts → cjs/test-utils.d.ts} +0 -0
  304. /package/dist/{test-utils.js → cjs/test-utils.js} +0 -0
  305. /package/dist/{text → cjs/text}/chunker.d.ts +0 -0
  306. /package/dist/{text → cjs/text}/chunker.js +0 -0
  307. /package/dist/{text → cjs/text}/embedder.d.ts +0 -0
  308. /package/dist/{text → cjs/text}/embedder.js +0 -0
  309. /package/dist/{text → cjs/text}/index.d.ts +0 -0
  310. /package/dist/{text → cjs/text}/index.js +0 -0
  311. /package/dist/{text → cjs/text}/preprocessors/index.d.ts +0 -0
  312. /package/dist/{text → cjs/text}/preprocessors/index.js +0 -0
  313. /package/dist/{text → cjs/text}/preprocessors/mdx.d.ts +0 -0
  314. /package/dist/{text → cjs/text}/preprocessors/mdx.js +0 -0
  315. /package/dist/{text → cjs/text}/preprocessors/mermaid.d.ts +0 -0
  316. /package/dist/{text → cjs/text}/preprocessors/mermaid.js +0 -0
  317. /package/dist/{text → cjs/text}/preprocessors/registry.d.ts +0 -0
  318. /package/dist/{text → cjs/text}/preprocessors/registry.js +0 -0
  319. /package/dist/{text → cjs/text}/reranker.d.ts +0 -0
  320. /package/dist/{text → cjs/text}/reranker.js +0 -0
  321. /package/dist/{text → cjs/text}/sentence-transformer-embedder.d.ts +0 -0
  322. /package/dist/{text → cjs/text}/sentence-transformer-embedder.js +0 -0
  323. /package/dist/{text → cjs/text}/tokenizer.d.ts +0 -0
  324. /package/dist/{text → cjs/text}/tokenizer.js +0 -0
  325. /package/dist/{types.d.ts → cjs/types.d.ts} +0 -0
  326. /package/dist/{types.js → cjs/types.js} +0 -0
  327. /package/dist/{utils → cjs/utils}/vector-math.d.ts +0 -0
  328. /package/dist/{utils → cjs/utils}/vector-math.js +0 -0
@@ -0,0 +1,667 @@
1
+ import { VectorIndex } from './core/vector-index.js';
2
+ import { BinaryIndexFormat } from './core/binary-index-format.js';
3
+ import { openDatabase, getSystemInfo, setSystemInfo } from './core/db.js';
4
+ import { config, getModelDefaults } from './core/config.js';
5
+ export class IndexManager {
6
+ modelName;
7
+ vectorIndex;
8
+ textIndex;
9
+ imageIndex;
10
+ db = null;
11
+ indexPath;
12
+ dbPath;
13
+ isInitialized = false;
14
+ hashToEmbeddingId = new Map();
15
+ embeddingIdToHash = new Map();
16
+ groupedEmbeddings;
17
+ vectorIndexOptions;
18
+ constructor(indexPath, dbPath, dimensions, modelName) {
19
+ this.modelName = modelName;
20
+ this.indexPath = indexPath;
21
+ this.dbPath = dbPath;
22
+ // Store options for creating specialized indexes
23
+ this.vectorIndexOptions = {
24
+ dimensions: dimensions,
25
+ maxElements: 100000, // Start with 100k capacity
26
+ efConstruction: 200,
27
+ M: 16
28
+ };
29
+ // Initialize with provided dimensions from config
30
+ this.vectorIndex = new VectorIndex(indexPath, this.vectorIndexOptions);
31
+ }
32
+ /**
33
+ * Initialize the index manager and load existing index if available
34
+ * @param skipModelCheck - Skip model compatibility check (used for rebuilds)
35
+ * @param forceRecreate - Force recreation of index (used for model changes)
36
+ */
37
+ async initialize(skipModelCheck = false, forceRecreate = false) {
38
+ if (this.isInitialized) {
39
+ return;
40
+ }
41
+ try {
42
+ // Open database connection
43
+ this.db = await openDatabase(this.dbPath);
44
+ // Check model compatibility BEFORE trying to load the vector index
45
+ // This prevents WebAssembly exceptions when dimensions don't match
46
+ if (!skipModelCheck && !forceRecreate) {
47
+ await this.checkModelCompatibility();
48
+ }
49
+ if (forceRecreate || !this.vectorIndex.indexExists()) {
50
+ console.log('Creating new vector index...');
51
+ await this.vectorIndex.initialize();
52
+ }
53
+ else {
54
+ // Only try to load existing index if not forcing recreation
55
+ console.log('Loading existing vector index...');
56
+ await this.vectorIndex.loadIndex();
57
+ // Check if the loaded index has grouped data and create specialized indexes
58
+ await this.createSpecializedIndexes();
59
+ }
60
+ // Always populate the embedding ID mapping from existing database entries
61
+ // This is needed both for new and existing indexes
62
+ const existingChunks = await this.db.all('SELECT embedding_id FROM chunks ORDER BY id');
63
+ for (const chunk of existingChunks) {
64
+ this.hashEmbeddingId(chunk.embedding_id); // This will populate the mapping
65
+ }
66
+ this.isInitialized = true;
67
+ const vectorCount = await this.vectorIndex.getCurrentCount();
68
+ console.log(`Index manager initialized with ${vectorCount} vectors${this.textIndex && this.imageIndex ? ' (multi-graph mode)' : ''}`);
69
+ }
70
+ catch (error) {
71
+ throw new Error(`Failed to initialize index manager: ${error}`);
72
+ }
73
+ }
74
+ /**
75
+ * Check model compatibility between stored and current configuration
76
+ * Requirements: 2.1, 2.2, 2.4, 5.1, 5.2, 5.3, 5.4
77
+ */
78
+ async checkModelCompatibility() {
79
+ if (!this.db) {
80
+ throw new Error('Database not initialized');
81
+ }
82
+ try {
83
+ // Get stored model information
84
+ const systemInfo = await getSystemInfo(this.db);
85
+ const currentModel = this.modelName || config.embedding_model;
86
+ const currentDefaults = getModelDefaults(currentModel);
87
+ if (systemInfo && systemInfo.modelName && systemInfo.modelDimensions) {
88
+ // Check if models match
89
+ if (systemInfo.modelName !== currentModel) {
90
+ throw new Error(`Model mismatch detected!\n` +
91
+ `Current model: ${currentModel} (${currentDefaults.dimensions} dimensions)\n` +
92
+ `Index model: ${systemInfo.modelName} (${systemInfo.modelDimensions} dimensions)\n` +
93
+ `\n` +
94
+ `The embedding model has changed since the index was created.\n` +
95
+ `This requires a full index rebuild to maintain consistency.\n` +
96
+ `\n` +
97
+ `To fix this issue:\n` +
98
+ `1. Run: npm run rebuild\n` +
99
+ `2. Or run: node dist/cli.js rebuild\n` +
100
+ `\n` +
101
+ `This will regenerate all embeddings with the new model.`);
102
+ }
103
+ // Check if dimensions match (additional safety check)
104
+ if (systemInfo.modelDimensions !== currentDefaults.dimensions) {
105
+ throw new Error(`Model dimension mismatch detected!\n` +
106
+ `Current model dimensions: ${currentDefaults.dimensions}\n` +
107
+ `Index model dimensions: ${systemInfo.modelDimensions}\n` +
108
+ `\n` +
109
+ `This indicates a configuration inconsistency.\n` +
110
+ `Please run: npm run rebuild`);
111
+ }
112
+ console.log(`Model compatibility verified: ${currentModel} (${currentDefaults.dimensions} dimensions)`);
113
+ }
114
+ else {
115
+ // First run - store the model info
116
+ console.log(`No model info stored yet - storing current model info: ${currentModel}`);
117
+ await setSystemInfo(this.db, {
118
+ modelName: currentModel,
119
+ modelDimensions: currentDefaults.dimensions
120
+ });
121
+ }
122
+ }
123
+ catch (error) {
124
+ if (error instanceof Error) {
125
+ throw error; // Re-throw our formatted errors
126
+ }
127
+ throw new Error(`Failed to check model compatibility: ${error}`);
128
+ }
129
+ }
130
+ /**
131
+ * Add vectors to the index with corresponding metadata (incremental addition)
132
+ * Requirements: 5.3 - When new documents are added THEN system SHALL append new chunks and vectors without rebuilding existing index
133
+ */
134
+ async addVectors(embeddings) {
135
+ if (!this.isInitialized) {
136
+ throw new Error('Index manager not initialized');
137
+ }
138
+ if (embeddings.length === 0) {
139
+ return;
140
+ }
141
+ try {
142
+ // Convert embedding IDs to numeric IDs for hnswlib
143
+ const vectors = embeddings.map((embedding) => ({
144
+ id: this.hashEmbeddingId(embedding.embedding_id),
145
+ vector: embedding.vector
146
+ }));
147
+ // Check if we need to resize the index before adding
148
+ const initialCount = await this.vectorIndex.getCurrentCount();
149
+ const newCount = initialCount + vectors.length;
150
+ const currentCapacity = 100000; // This should match the initial capacity
151
+ if (newCount > currentCapacity * 0.9) {
152
+ const newCapacity = Math.ceil(newCount * 1.5);
153
+ console.log(`Resizing index from ${currentCapacity} to ${newCapacity} to accommodate new vectors`);
154
+ await this.vectorIndex.resizeIndex(newCapacity);
155
+ }
156
+ // Add vectors incrementally (this is the key requirement - no rebuild needed)
157
+ await this.vectorIndex.addVectors(vectors);
158
+ const finalCount = await this.vectorIndex.getCurrentCount();
159
+ console.log(`Incrementally added ${embeddings.length} vectors to index (total: ${finalCount})`);
160
+ // Save the updated index
161
+ await this.saveIndex();
162
+ }
163
+ catch (error) {
164
+ throw new Error(`Failed to add vectors to index: ${error instanceof Error ? error.message : 'Unknown error'}`);
165
+ }
166
+ }
167
+ /**
168
+ * Add grouped embeddings by content type (for new grouped format)
169
+ */
170
+ async addGroupedEmbeddings(textEmbeddings, imageEmbeddings) {
171
+ if (!this.isInitialized) {
172
+ throw new Error('Index manager not initialized');
173
+ }
174
+ console.log(`addGroupedEmbeddings: text=${textEmbeddings.length}, image=${imageEmbeddings.length}`);
175
+ const allEmbeddings = [...textEmbeddings, ...imageEmbeddings];
176
+ if (allEmbeddings.length === 0) {
177
+ return;
178
+ }
179
+ try {
180
+ // Store grouped information for later saving
181
+ this.groupedEmbeddings = { text: textEmbeddings, image: imageEmbeddings };
182
+ console.log('addGroupedEmbeddings: stored grouped embeddings');
183
+ // Add all embeddings to the index (maintains current behavior)
184
+ await this.addVectors(allEmbeddings);
185
+ console.log('addGroupedEmbeddings: addVectors completed');
186
+ // The saveIndex method will now use grouped format if groupedEmbeddings exists
187
+ }
188
+ catch (error) {
189
+ throw new Error(`Failed to add grouped embeddings to index: ${error instanceof Error ? error.message : 'Unknown error'}`);
190
+ }
191
+ }
192
+ /**
193
+ * Rebuild the entire index from scratch
194
+ * Requirements: 5.2, 5.4 - Create full index rebuild functionality for model changes or document deletions
195
+ */
196
+ async rebuildIndex(newModelVersion) {
197
+ if (!this.db) {
198
+ throw new Error('Database not initialized');
199
+ }
200
+ console.log('Starting full index rebuild...');
201
+ try {
202
+ // Initialize new empty index (this will overwrite existing index)
203
+ await this.vectorIndex.initialize();
204
+ // Get all chunk embedding IDs from database (we'll need to regenerate embeddings)
205
+ const chunkData = await this.getAllChunksFromDB();
206
+ if (chunkData.length === 0) {
207
+ console.log('No chunks found in database - index rebuild complete with 0 vectors');
208
+ // Update model version if provided
209
+ if (newModelVersion) {
210
+ await this.updateModelVersion(newModelVersion);
211
+ }
212
+ await this.saveIndex();
213
+ return;
214
+ }
215
+ console.log(`Found ${chunkData.length} chunks in database that need re-embedding`);
216
+ // Note: In a complete implementation, we would need to:
217
+ // 1. Re-generate embeddings for all chunks using the new model
218
+ // 2. Add the new vectors to the index
219
+ // For now, we'll create a placeholder implementation that shows the structure
220
+ console.warn('WARNING: Full rebuild requires re-generating embeddings for all chunks.');
221
+ console.warn('This implementation requires integration with the EmbeddingEngine.');
222
+ console.warn('The index has been reset but vectors need to be regenerated.');
223
+ // Check if we need to resize index based on chunk count
224
+ const currentCapacity = 100000; // Default capacity
225
+ if (chunkData.length > currentCapacity * 0.8) {
226
+ const newCapacity = Math.ceil(chunkData.length * 1.5);
227
+ await this.vectorIndex.resizeIndex(newCapacity);
228
+ console.log(`Resized index capacity to ${newCapacity} for ${chunkData.length} chunks`);
229
+ }
230
+ // Update model version if provided
231
+ if (newModelVersion) {
232
+ await this.updateModelVersion(newModelVersion);
233
+ }
234
+ // Save the (empty) rebuilt index structure
235
+ await this.saveIndex();
236
+ console.log(`Index rebuild structure complete. ${chunkData.length} chunks need re-embedding.`);
237
+ }
238
+ catch (error) {
239
+ throw new Error(`Failed to rebuild index: ${error instanceof Error ? error.message : 'Unknown error'}`);
240
+ }
241
+ }
242
+ /**
243
+ * Trigger a full rebuild when documents are modified or deleted
244
+ * Requirements: 5.4 - When documents are modified or deleted THEN system SHALL trigger full index rebuild
245
+ */
246
+ async triggerRebuildForDocumentChanges(reason) {
247
+ console.log(`Triggering index rebuild due to: ${reason}`);
248
+ await this.rebuildIndex();
249
+ }
250
+ /**
251
+ * Complete rebuild workflow with embedding regeneration
252
+ * This method should be called by higher-level components that have access to the EmbeddingEngine
253
+ * Requirements: 5.2, 5.4 - Full index rebuild functionality
254
+ */
255
+ async rebuildWithEmbeddings(embeddingEngine) {
256
+ if (!this.db) {
257
+ throw new Error('Database not initialized');
258
+ }
259
+ console.log('Starting complete index rebuild with embedding regeneration...');
260
+ try {
261
+ // Get all chunks that need re-embedding
262
+ const chunkData = await this.getAllChunksFromDB();
263
+ if (chunkData.length === 0) {
264
+ console.log('No chunks found - initializing empty index');
265
+ await this.vectorIndex.initialize();
266
+ await this.updateModelVersion(embeddingEngine.getModelVersion());
267
+ // Store model info for the new model
268
+ const currentModel = this.modelName || config.embedding_model;
269
+ const currentDefaults = getModelDefaults(currentModel);
270
+ await setSystemInfo(this.db, {
271
+ modelName: currentModel,
272
+ modelDimensions: currentDefaults.dimensions
273
+ });
274
+ await this.saveIndex();
275
+ return;
276
+ }
277
+ // Initialize new empty index
278
+ await this.vectorIndex.initialize();
279
+ // Check if we need to resize index
280
+ const currentCapacity = 100000;
281
+ if (chunkData.length > currentCapacity * 0.8) {
282
+ const newCapacity = Math.ceil(chunkData.length * 1.5);
283
+ await this.vectorIndex.resizeIndex(newCapacity);
284
+ console.log(`Resized index capacity to ${newCapacity}`);
285
+ }
286
+ // Re-generate embeddings for all chunks
287
+ console.log(`Re-generating embeddings for ${chunkData.length} chunks...`);
288
+ const texts = chunkData.map(chunk => chunk.text);
289
+ const newEmbeddings = await embeddingEngine.embedDocumentBatch(texts);
290
+ if (newEmbeddings.length === 0) {
291
+ throw new Error('Failed to generate any embeddings during rebuild');
292
+ }
293
+ // Add all vectors to the new index
294
+ const vectors = newEmbeddings.map((embedding) => ({
295
+ id: this.hashEmbeddingId(embedding.embedding_id),
296
+ vector: embedding.vector
297
+ }));
298
+ await this.vectorIndex.addVectors(vectors);
299
+ console.log(`Added ${vectors.length} vectors to rebuilt index`);
300
+ // Update model version
301
+ await this.updateModelVersion(embeddingEngine.getModelVersion());
302
+ // Store model info for the new model
303
+ const currentModel = this.modelName || config.embedding_model;
304
+ const currentDefaults = getModelDefaults(currentModel);
305
+ await setSystemInfo(this.db, {
306
+ modelName: currentModel,
307
+ modelDimensions: currentDefaults.dimensions
308
+ });
309
+ // Save the rebuilt index
310
+ await this.saveIndex();
311
+ console.log(`Index rebuild complete: ${vectors.length} vectors with new model version`);
312
+ }
313
+ catch (error) {
314
+ throw new Error(`Failed to rebuild index with embeddings: ${error instanceof Error ? error.message : 'Unknown error'}`);
315
+ }
316
+ }
317
+ /**
318
+ * Check if the current model version matches stored version
319
+ * Requirements: 5.1, 5.2 - Compare current embedding model version with stored version
320
+ */
321
+ async checkModelVersion(currentVersion) {
322
+ if (!this.db) {
323
+ throw new Error('Database not initialized');
324
+ }
325
+ try {
326
+ const systemInfo = await getSystemInfo(this.db);
327
+ const storedVersion = systemInfo?.modelVersion;
328
+ if (!storedVersion || storedVersion === "") {
329
+ // No version stored yet, this is first run - store current version
330
+ await setSystemInfo(this.db, { modelVersion: currentVersion });
331
+ console.log(`Stored initial model version: ${currentVersion}`);
332
+ return true;
333
+ }
334
+ const matches = storedVersion === currentVersion;
335
+ if (!matches) {
336
+ console.error(`Model version mismatch detected!`);
337
+ console.error(`Stored version: ${storedVersion}`);
338
+ console.error(`Current version: ${currentVersion}`);
339
+ console.error(`A full index rebuild is required before the system can continue.`);
340
+ }
341
+ return matches;
342
+ }
343
+ catch (error) {
344
+ throw new Error(`Failed to check model version: ${error instanceof Error ? error.message : 'Unknown error'}`);
345
+ }
346
+ }
347
+ /**
348
+ * Update the stored model version after successful rebuild
349
+ * Requirements: 5.5 - Save model name and hash in SQLite for version tracking
350
+ */
351
+ async updateModelVersion(version) {
352
+ if (!this.db) {
353
+ throw new Error('Database not initialized');
354
+ }
355
+ try {
356
+ await setSystemInfo(this.db, { modelVersion: version });
357
+ console.log(`Updated model version to: ${version}`);
358
+ }
359
+ catch (error) {
360
+ throw new Error(`Failed to update model version: ${error instanceof Error ? error.message : 'Unknown error'}`);
361
+ }
362
+ }
363
+ /**
364
+ * Validate model version and exit if mismatch detected
365
+ * Requirements: 5.2 - System SHALL exit with error message until full index rebuild is completed
366
+ */
367
+ async validateModelVersionOrExit(currentVersion) {
368
+ const isValid = await this.checkModelVersion(currentVersion);
369
+ if (!isValid) {
370
+ console.error('\n=== MODEL VERSION MISMATCH ===');
371
+ console.error('The embedding model version has changed since the last index build.');
372
+ console.error('This requires a full index rebuild to maintain consistency.');
373
+ console.error('\nTo rebuild the index, run:');
374
+ console.error(' npm run rebuild-index');
375
+ console.error(' # or');
376
+ console.error(' node dist/cli.js rebuild');
377
+ console.error('\nThe system will now exit.');
378
+ process.exit(1);
379
+ }
380
+ }
381
+ /**
382
+ * Save the vector index to disk
383
+ */
384
+ async saveIndex() {
385
+ if (!this.isInitialized) {
386
+ throw new Error('Index manager not initialized');
387
+ }
388
+ // If we have grouped embeddings, save in grouped format
389
+ if (this.groupedEmbeddings) {
390
+ console.log('IndexManager: Saving in grouped format');
391
+ await this.saveGroupedIndex(this.groupedEmbeddings.text, this.groupedEmbeddings.image);
392
+ // Clear grouped data after saving
393
+ this.groupedEmbeddings = undefined;
394
+ }
395
+ else {
396
+ console.log('IndexManager: Saving in standard format');
397
+ await this.vectorIndex.saveIndex();
398
+ }
399
+ }
400
+ /**
401
+ * Create specialized indexes for text and image content when grouped data is available
402
+ */
403
+ async createSpecializedIndexes() {
404
+ try {
405
+ // Load the index data to check if it has grouped information
406
+ const indexData = await BinaryIndexFormat.load(this.indexPath);
407
+ if (indexData.hasContentTypeGroups && indexData.textVectors && indexData.imageVectors) {
408
+ // Only create specialized indexes if we have both text and image vectors
409
+ // In text-only mode, textVectors would be populated but imageVectors empty
410
+ // In multimodal mode, both would be populated
411
+ const hasTextVectors = indexData.textVectors.length > 0;
412
+ const hasImageVectors = indexData.imageVectors.length > 0;
413
+ if (hasTextVectors && hasImageVectors) {
414
+ console.log('Creating specialized indexes for content type filtering...');
415
+ // Create text-only index
416
+ this.textIndex = new VectorIndex(`${this.indexPath}.text`, this.vectorIndexOptions);
417
+ await this.textIndex.initialize();
418
+ await this.textIndex.addVectors(indexData.textVectors);
419
+ console.log(`✓ Text index created with ${indexData.textVectors.length} vectors`);
420
+ // Create image-only index
421
+ this.imageIndex = new VectorIndex(`${this.indexPath}.image`, this.vectorIndexOptions);
422
+ await this.imageIndex.initialize();
423
+ await this.imageIndex.addVectors(indexData.imageVectors);
424
+ console.log(`✓ Image index created with ${indexData.imageVectors.length} vectors`);
425
+ console.log('✓ Specialized indexes ready for content type filtering');
426
+ }
427
+ else if (hasTextVectors) {
428
+ console.log('Text-only index detected - using combined index for all searches');
429
+ // In text-only mode, we don't need specialized indexes
430
+ // The combined index (vectorIndex) already contains all text vectors
431
+ }
432
+ }
433
+ }
434
+ catch (error) {
435
+ console.warn('Failed to create specialized indexes, falling back to combined index:', error);
436
+ // Continue without specialized indexes - search will still work with combined index
437
+ }
438
+ }
439
+ /**
440
+ * Save index with content type grouping (for new grouped format)
441
+ */
442
+ async saveGroupedIndex(textEmbeddings, imageEmbeddings) {
443
+ if (!this.isInitialized) {
444
+ throw new Error('Index manager not initialized');
445
+ }
446
+ console.log(`saveGroupedIndex: text=${textEmbeddings.length}, image=${imageEmbeddings.length}`);
447
+ // Group vectors by content type
448
+ const textVectors = textEmbeddings.map((embedding) => ({
449
+ id: this.hashEmbeddingId(embedding.embedding_id),
450
+ vector: embedding.vector
451
+ }));
452
+ const imageVectors = imageEmbeddings.map((embedding) => ({
453
+ id: this.hashEmbeddingId(embedding.embedding_id),
454
+ vector: embedding.vector
455
+ }));
456
+ // Get index parameters
457
+ const options = this.vectorIndex.getOptions();
458
+ const allVectors = [...textVectors, ...imageVectors];
459
+ console.log(`saveGroupedIndex: dimensions=${options.dimensions}, totalVectors=${allVectors.length}`);
460
+ const indexData = {
461
+ dimensions: options.dimensions,
462
+ maxElements: options.maxElements,
463
+ M: options.M || 16,
464
+ efConstruction: options.efConstruction || 200,
465
+ seed: options.seed || 100,
466
+ currentSize: textVectors.length + imageVectors.length,
467
+ vectors: allVectors, // Required for backward compatibility
468
+ hasContentTypeGroups: true,
469
+ textVectors,
470
+ imageVectors
471
+ };
472
+ console.log('saveGroupedIndex: Calling BinaryIndexFormat.saveGrouped');
473
+ // Save using grouped format
474
+ await BinaryIndexFormat.saveGrouped(this.indexPath, indexData);
475
+ console.log(`✓ Saved grouped index with ${textVectors.length} text and ${imageVectors.length} image vectors`);
476
+ }
477
+ /**
478
+ * Search for similar vectors
479
+ * Now async due to worker-based VectorIndex implementation
480
+ */
481
+ async search(queryVector, k = 5, contentType) {
482
+ if (!this.isInitialized) {
483
+ throw new Error('Index manager not initialized');
484
+ }
485
+ // Select the appropriate index based on content type
486
+ let targetIndex;
487
+ // If we have specialized indexes (multimodal mode), use them for filtering
488
+ if (this.textIndex && this.imageIndex) {
489
+ if (contentType === 'text') {
490
+ targetIndex = this.textIndex;
491
+ }
492
+ else if (contentType === 'image') {
493
+ targetIndex = this.imageIndex;
494
+ }
495
+ else {
496
+ // 'combined' or undefined
497
+ targetIndex = this.vectorIndex;
498
+ }
499
+ }
500
+ else {
501
+ // No specialized indexes (text-only mode) - ignore contentType and use combined index
502
+ targetIndex = this.vectorIndex;
503
+ }
504
+ const results = await targetIndex.search(queryVector, k);
505
+ // Convert numeric IDs back to embedding IDs
506
+ const embeddingIds = results.neighbors.map(id => this.unhashEmbeddingId(id));
507
+ return {
508
+ embeddingIds,
509
+ distances: results.distances
510
+ };
511
+ }
512
+ /**
513
+ * Get index statistics
514
+ */
515
+ async getStats() {
516
+ if (!this.db) {
517
+ throw new Error('Database not initialized');
518
+ }
519
+ const totalVectors = await this.vectorIndex.getCurrentCount();
520
+ try {
521
+ const systemInfo = await getSystemInfo(this.db);
522
+ const modelVersion = systemInfo?.modelVersion || null;
523
+ return {
524
+ totalVectors,
525
+ modelVersion: modelVersion || 'unknown',
526
+ lastUpdated: new Date() // Could be enhanced to track actual last update time
527
+ };
528
+ }
529
+ catch (error) {
530
+ throw new Error(`Failed to get stats: ${error instanceof Error ? error.message : 'Unknown error'}`);
531
+ }
532
+ }
533
+ /**
534
+ * Get all chunks from database for rebuild (returns chunk data, not embeddings)
535
+ * Note: Embeddings need to be regenerated during rebuild since we don't store vectors in DB
536
+ */
537
+ async getAllChunksFromDB() {
538
+ if (!this.db) {
539
+ throw new Error('Database not initialized');
540
+ }
541
+ try {
542
+ const rows = await this.db.all('SELECT embedding_id, content as text, document_id FROM chunks ORDER BY id');
543
+ return rows.map(row => ({
544
+ embedding_id: row.embedding_id,
545
+ text: row.text,
546
+ document_id: row.document_id
547
+ }));
548
+ }
549
+ catch (error) {
550
+ throw new Error(`Failed to get chunks from DB: ${error instanceof Error ? error.message : 'Unknown error'}`);
551
+ }
552
+ }
553
+ /**
554
+ * Convert embedding ID string to numeric ID for hnswlib with collision handling
555
+ */
556
+ hashEmbeddingId(embeddingId) {
557
+ // Check if we already have a mapping for this embedding ID
558
+ if (this.embeddingIdToHash.has(embeddingId)) {
559
+ return this.embeddingIdToHash.get(embeddingId);
560
+ }
561
+ let hash = 0;
562
+ for (let i = 0; i < embeddingId.length; i++) {
563
+ const char = embeddingId.charCodeAt(i);
564
+ hash = ((hash << 5) - hash) + char;
565
+ hash = hash & hash; // Convert to 32-bit integer
566
+ }
567
+ hash = Math.abs(hash);
568
+ // Handle hash collisions by incrementing until we find an unused hash
569
+ let finalHash = hash;
570
+ while (this.hashToEmbeddingId.has(finalHash) && this.hashToEmbeddingId.get(finalHash) !== embeddingId) {
571
+ finalHash = (finalHash + 1) & 0x7FFFFFFF; // Keep it positive
572
+ }
573
+ // Store the bidirectional mapping
574
+ this.embeddingIdToHash.set(embeddingId, finalHash);
575
+ this.hashToEmbeddingId.set(finalHash, embeddingId);
576
+ return finalHash;
577
+ }
578
+ /**
579
+ * Convert numeric ID back to embedding ID using the maintained mapping
580
+ */
581
+ unhashEmbeddingId(numericId) {
582
+ const embeddingId = this.hashToEmbeddingId.get(numericId);
583
+ if (!embeddingId) {
584
+ console.warn(`Warning: No embedding ID found for hash ${numericId}. This may indicate index/database synchronization issues.`);
585
+ console.warn('Consider running "raglite rebuild" to fix synchronization problems.');
586
+ throw new Error(`No embedding ID found for hash ${numericId}`);
587
+ }
588
+ return embeddingId;
589
+ }
590
+ /**
591
+ * Close database connection and cleanup vector index worker
592
+ */
593
+ async close() {
594
+ if (this.db) {
595
+ await this.db.close();
596
+ this.db = null;
597
+ }
598
+ // Clean up vector index worker to free WebAssembly memory
599
+ if (this.vectorIndex && typeof this.vectorIndex.cleanup === 'function') {
600
+ await this.vectorIndex.cleanup();
601
+ }
602
+ // Also clean up specialized indexes
603
+ if (this.textIndex && typeof this.textIndex.cleanup === 'function') {
604
+ await this.textIndex.cleanup();
605
+ }
606
+ if (this.imageIndex && typeof this.imageIndex.cleanup === 'function') {
607
+ await this.imageIndex.cleanup();
608
+ }
609
+ }
610
+ /**
611
+ * Reset the vector index by clearing all vectors while keeping the index structure.
612
+ * This is a safer alternative to file deletion that avoids file locking issues on Windows.
613
+ *
614
+ * The reset operation:
615
+ * 1. Clears in-memory HNSW index
616
+ * 2. Clears in-memory vector storage and ID mappings
617
+ * 3. Reinitializes an empty index with the same parameters
618
+ * 4. Saves the empty index to disk (overwrites existing file)
619
+ *
620
+ * @returns Promise that resolves when reset is complete
621
+ */
622
+ async reset() {
623
+ console.log('🔄 Starting index reset...');
624
+ const startTime = Date.now();
625
+ try {
626
+ // Clear in-memory mappings
627
+ const previousVectorCount = await this.vectorIndex.getCurrentCount();
628
+ this.hashToEmbeddingId.clear();
629
+ this.embeddingIdToHash.clear();
630
+ // Clear grouped embeddings if any
631
+ this.groupedEmbeddings = undefined;
632
+ // Clear specialized indexes if they exist
633
+ if (this.textIndex) {
634
+ this.textIndex = undefined;
635
+ }
636
+ if (this.imageIndex) {
637
+ this.imageIndex = undefined;
638
+ }
639
+ // Reset the vector index (clears all vectors and reinitializes empty HNSW graph)
640
+ console.log(' Resetting HNSW index...');
641
+ await this.vectorIndex.reset();
642
+ // Save the empty index to disk (this overwrites the existing file)
643
+ console.log(' Saving empty index to disk...');
644
+ await this.vectorIndex.saveIndex();
645
+ const resetTimeMs = Date.now() - startTime;
646
+ const currentCount = await this.vectorIndex.getCurrentCount();
647
+ console.log(`✓ Index reset complete in ${resetTimeMs}ms`);
648
+ console.log(` Vectors cleared: ${previousVectorCount}`);
649
+ console.log(` Current vector count: ${currentCount}`);
650
+ }
651
+ catch (error) {
652
+ const resetTimeMs = Date.now() - startTime;
653
+ console.error(`❌ Index reset failed after ${resetTimeMs}ms:`, error);
654
+ throw new Error(`Failed to reset index: ${error instanceof Error ? error.message : 'Unknown error'}`);
655
+ }
656
+ }
657
+ /**
658
+ * Check if the index has any vectors
659
+ * @returns true if the index contains vectors, false if empty
660
+ * Now async due to worker-based VectorIndex implementation
661
+ */
662
+ async hasVectors() {
663
+ const count = await this.vectorIndex.getCurrentCount();
664
+ return count > 0;
665
+ }
666
+ }
667
+ //# sourceMappingURL=index-manager.js.map