@code-rag/core 0.1.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 (347) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +19 -0
  3. package/dist/auth/audit-log.d.ts +35 -0
  4. package/dist/auth/audit-log.js +110 -0
  5. package/dist/auth/audit-log.js.map +1 -0
  6. package/dist/auth/audit-log.test.d.ts +1 -0
  7. package/dist/auth/audit-log.test.js +261 -0
  8. package/dist/auth/audit-log.test.js.map +1 -0
  9. package/dist/auth/index.d.ts +6 -0
  10. package/dist/auth/index.js +5 -0
  11. package/dist/auth/index.js.map +1 -0
  12. package/dist/auth/oidc-provider.d.ts +49 -0
  13. package/dist/auth/oidc-provider.js +358 -0
  14. package/dist/auth/oidc-provider.js.map +1 -0
  15. package/dist/auth/oidc-provider.test.d.ts +1 -0
  16. package/dist/auth/oidc-provider.test.js +520 -0
  17. package/dist/auth/oidc-provider.test.js.map +1 -0
  18. package/dist/auth/rbac.d.ts +29 -0
  19. package/dist/auth/rbac.js +75 -0
  20. package/dist/auth/rbac.js.map +1 -0
  21. package/dist/auth/rbac.test.d.ts +1 -0
  22. package/dist/auth/rbac.test.js +224 -0
  23. package/dist/auth/rbac.test.js.map +1 -0
  24. package/dist/auth/saml-provider.d.ts +51 -0
  25. package/dist/auth/saml-provider.js +355 -0
  26. package/dist/auth/saml-provider.js.map +1 -0
  27. package/dist/auth/saml-provider.test.d.ts +1 -0
  28. package/dist/auth/saml-provider.test.js +422 -0
  29. package/dist/auth/saml-provider.test.js.map +1 -0
  30. package/dist/auth/types.d.ts +81 -0
  31. package/dist/auth/types.js +11 -0
  32. package/dist/auth/types.js.map +1 -0
  33. package/dist/auth/types.test.d.ts +1 -0
  34. package/dist/auth/types.test.js +147 -0
  35. package/dist/auth/types.test.js.map +1 -0
  36. package/dist/backlog/ab-reference-scanner.d.ts +10 -0
  37. package/dist/backlog/ab-reference-scanner.js +22 -0
  38. package/dist/backlog/ab-reference-scanner.js.map +1 -0
  39. package/dist/backlog/ab-reference-scanner.test.d.ts +1 -0
  40. package/dist/backlog/ab-reference-scanner.test.js +83 -0
  41. package/dist/backlog/ab-reference-scanner.test.js.map +1 -0
  42. package/dist/backlog/azure-devops-provider.d.ts +59 -0
  43. package/dist/backlog/azure-devops-provider.js +283 -0
  44. package/dist/backlog/azure-devops-provider.js.map +1 -0
  45. package/dist/backlog/backlog-provider.d.ts +13 -0
  46. package/dist/backlog/backlog-provider.js +6 -0
  47. package/dist/backlog/backlog-provider.js.map +1 -0
  48. package/dist/backlog/backlog-provider.test.d.ts +1 -0
  49. package/dist/backlog/backlog-provider.test.js +426 -0
  50. package/dist/backlog/backlog-provider.test.js.map +1 -0
  51. package/dist/backlog/clickup-provider.d.ts +55 -0
  52. package/dist/backlog/clickup-provider.js +301 -0
  53. package/dist/backlog/clickup-provider.js.map +1 -0
  54. package/dist/backlog/clickup-provider.test.d.ts +1 -0
  55. package/dist/backlog/clickup-provider.test.js +426 -0
  56. package/dist/backlog/clickup-provider.test.js.map +1 -0
  57. package/dist/backlog/clickup-reference-scanner.d.ts +10 -0
  58. package/dist/backlog/clickup-reference-scanner.js +32 -0
  59. package/dist/backlog/clickup-reference-scanner.js.map +1 -0
  60. package/dist/backlog/clickup-reference-scanner.test.d.ts +1 -0
  61. package/dist/backlog/clickup-reference-scanner.test.js +92 -0
  62. package/dist/backlog/clickup-reference-scanner.test.js.map +1 -0
  63. package/dist/backlog/code-linker.d.ts +63 -0
  64. package/dist/backlog/code-linker.js +90 -0
  65. package/dist/backlog/code-linker.js.map +1 -0
  66. package/dist/backlog/code-linker.test.d.ts +1 -0
  67. package/dist/backlog/code-linker.test.js +325 -0
  68. package/dist/backlog/code-linker.test.js.map +1 -0
  69. package/dist/backlog/index.d.ts +14 -0
  70. package/dist/backlog/index.js +8 -0
  71. package/dist/backlog/index.js.map +1 -0
  72. package/dist/backlog/jira-provider.d.ts +60 -0
  73. package/dist/backlog/jira-provider.js +272 -0
  74. package/dist/backlog/jira-provider.js.map +1 -0
  75. package/dist/backlog/jira-provider.test.d.ts +1 -0
  76. package/dist/backlog/jira-provider.test.js +449 -0
  77. package/dist/backlog/jira-provider.test.js.map +1 -0
  78. package/dist/backlog/jira-reference-scanner.d.ts +11 -0
  79. package/dist/backlog/jira-reference-scanner.js +26 -0
  80. package/dist/backlog/jira-reference-scanner.js.map +1 -0
  81. package/dist/backlog/jira-reference-scanner.test.d.ts +1 -0
  82. package/dist/backlog/jira-reference-scanner.test.js +127 -0
  83. package/dist/backlog/jira-reference-scanner.test.js.map +1 -0
  84. package/dist/backlog/types.d.ts +22 -0
  85. package/dist/backlog/types.js +1 -0
  86. package/dist/backlog/types.js.map +1 -0
  87. package/dist/chunker/ast-chunker.d.ts +45 -0
  88. package/dist/chunker/ast-chunker.js +292 -0
  89. package/dist/chunker/ast-chunker.js.map +1 -0
  90. package/dist/chunker/ast-chunker.test.d.ts +1 -0
  91. package/dist/chunker/ast-chunker.test.js +391 -0
  92. package/dist/chunker/ast-chunker.test.js.map +1 -0
  93. package/dist/chunker/chunker.d.ts +8 -0
  94. package/dist/chunker/chunker.js +1 -0
  95. package/dist/chunker/chunker.js.map +1 -0
  96. package/dist/chunker/index.d.ts +3 -0
  97. package/dist/chunker/index.js +2 -0
  98. package/dist/chunker/index.js.map +1 -0
  99. package/dist/config/config-parser.d.ts +15 -0
  100. package/dist/config/config-parser.js +283 -0
  101. package/dist/config/config-parser.js.map +1 -0
  102. package/dist/config/config-parser.test.d.ts +1 -0
  103. package/dist/config/config-parser.test.js +699 -0
  104. package/dist/config/config-parser.test.js.map +1 -0
  105. package/dist/docs/confluence-provider.d.ts +121 -0
  106. package/dist/docs/confluence-provider.js +459 -0
  107. package/dist/docs/confluence-provider.js.map +1 -0
  108. package/dist/docs/confluence-provider.test.d.ts +1 -0
  109. package/dist/docs/confluence-provider.test.js +765 -0
  110. package/dist/docs/confluence-provider.test.js.map +1 -0
  111. package/dist/docs/index.d.ts +4 -0
  112. package/dist/docs/index.js +2 -0
  113. package/dist/docs/index.js.map +1 -0
  114. package/dist/docs/sharepoint-provider.d.ts +150 -0
  115. package/dist/docs/sharepoint-provider.js +637 -0
  116. package/dist/docs/sharepoint-provider.js.map +1 -0
  117. package/dist/docs/sharepoint-provider.test.d.ts +1 -0
  118. package/dist/docs/sharepoint-provider.test.js +873 -0
  119. package/dist/docs/sharepoint-provider.test.js.map +1 -0
  120. package/dist/embedding/bm25-index.d.ts +12 -0
  121. package/dist/embedding/bm25-index.js +89 -0
  122. package/dist/embedding/bm25-index.js.map +1 -0
  123. package/dist/embedding/bm25-index.test.d.ts +1 -0
  124. package/dist/embedding/bm25-index.test.js +289 -0
  125. package/dist/embedding/bm25-index.test.js.map +1 -0
  126. package/dist/embedding/hybrid-search.d.ts +13 -0
  127. package/dist/embedding/hybrid-search.js +124 -0
  128. package/dist/embedding/hybrid-search.js.map +1 -0
  129. package/dist/embedding/hybrid-search.test.d.ts +1 -0
  130. package/dist/embedding/hybrid-search.test.js +266 -0
  131. package/dist/embedding/hybrid-search.test.js.map +1 -0
  132. package/dist/embedding/index.d.ts +11 -0
  133. package/dist/embedding/index.js +7 -0
  134. package/dist/embedding/index.js.map +1 -0
  135. package/dist/embedding/lancedb-store.d.ts +21 -0
  136. package/dist/embedding/lancedb-store.js +172 -0
  137. package/dist/embedding/lancedb-store.js.map +1 -0
  138. package/dist/embedding/lancedb-store.test.d.ts +1 -0
  139. package/dist/embedding/lancedb-store.test.js +268 -0
  140. package/dist/embedding/lancedb-store.test.js.map +1 -0
  141. package/dist/embedding/model-lifecycle-manager.d.ts +83 -0
  142. package/dist/embedding/model-lifecycle-manager.js +419 -0
  143. package/dist/embedding/model-lifecycle-manager.js.map +1 -0
  144. package/dist/embedding/model-lifecycle-manager.test.d.ts +1 -0
  145. package/dist/embedding/model-lifecycle-manager.test.js +642 -0
  146. package/dist/embedding/model-lifecycle-manager.test.js.map +1 -0
  147. package/dist/embedding/ollama-embedding-provider.d.ts +16 -0
  148. package/dist/embedding/ollama-embedding-provider.js +74 -0
  149. package/dist/embedding/ollama-embedding-provider.js.map +1 -0
  150. package/dist/embedding/ollama-embedding-provider.test.d.ts +1 -0
  151. package/dist/embedding/ollama-embedding-provider.test.js +198 -0
  152. package/dist/embedding/ollama-embedding-provider.test.js.map +1 -0
  153. package/dist/embedding/openai-compatible-embedding-provider.d.ts +19 -0
  154. package/dist/embedding/openai-compatible-embedding-provider.js +108 -0
  155. package/dist/embedding/openai-compatible-embedding-provider.js.map +1 -0
  156. package/dist/embedding/openai-compatible-embedding-provider.test.d.ts +1 -0
  157. package/dist/embedding/openai-compatible-embedding-provider.test.js +456 -0
  158. package/dist/embedding/openai-compatible-embedding-provider.test.js.map +1 -0
  159. package/dist/embedding/qdrant-store.d.ts +28 -0
  160. package/dist/embedding/qdrant-store.js +174 -0
  161. package/dist/embedding/qdrant-store.js.map +1 -0
  162. package/dist/embedding/qdrant-store.test.d.ts +1 -0
  163. package/dist/embedding/qdrant-store.test.js +359 -0
  164. package/dist/embedding/qdrant-store.test.js.map +1 -0
  165. package/dist/enrichment/index.d.ts +4 -0
  166. package/dist/enrichment/index.js +2 -0
  167. package/dist/enrichment/index.js.map +1 -0
  168. package/dist/enrichment/nl-enricher.d.ts +16 -0
  169. package/dist/enrichment/nl-enricher.js +47 -0
  170. package/dist/enrichment/nl-enricher.js.map +1 -0
  171. package/dist/enrichment/nl-enricher.test.d.ts +1 -0
  172. package/dist/enrichment/nl-enricher.test.js +154 -0
  173. package/dist/enrichment/nl-enricher.test.js.map +1 -0
  174. package/dist/enrichment/ollama-client.d.ts +18 -0
  175. package/dist/enrichment/ollama-client.js +55 -0
  176. package/dist/enrichment/ollama-client.js.map +1 -0
  177. package/dist/enrichment/ollama-client.test.d.ts +1 -0
  178. package/dist/enrichment/ollama-client.test.js +129 -0
  179. package/dist/enrichment/ollama-client.test.js.map +1 -0
  180. package/dist/git/git-client.d.ts +22 -0
  181. package/dist/git/git-client.js +6 -0
  182. package/dist/git/git-client.js.map +1 -0
  183. package/dist/git/git-client.test.d.ts +1 -0
  184. package/dist/git/git-client.test.js +200 -0
  185. package/dist/git/git-client.test.js.map +1 -0
  186. package/dist/git/ignore-filter.d.ts +2 -0
  187. package/dist/git/ignore-filter.js +31 -0
  188. package/dist/git/ignore-filter.js.map +1 -0
  189. package/dist/git/ignore-filter.test.d.ts +1 -0
  190. package/dist/git/ignore-filter.test.js +87 -0
  191. package/dist/git/ignore-filter.test.js.map +1 -0
  192. package/dist/git/index.d.ts +4 -0
  193. package/dist/git/index.js +3 -0
  194. package/dist/git/index.js.map +1 -0
  195. package/dist/git/simple-git-client.d.ts +12 -0
  196. package/dist/git/simple-git-client.js +138 -0
  197. package/dist/git/simple-git-client.js.map +1 -0
  198. package/dist/graph/cross-repo-resolver.d.ts +50 -0
  199. package/dist/graph/cross-repo-resolver.js +315 -0
  200. package/dist/graph/cross-repo-resolver.js.map +1 -0
  201. package/dist/graph/cross-repo-resolver.test.d.ts +1 -0
  202. package/dist/graph/cross-repo-resolver.test.js +548 -0
  203. package/dist/graph/cross-repo-resolver.test.js.map +1 -0
  204. package/dist/graph/dependency-graph.d.ts +44 -0
  205. package/dist/graph/dependency-graph.js +108 -0
  206. package/dist/graph/dependency-graph.js.map +1 -0
  207. package/dist/graph/dependency-graph.test.d.ts +1 -0
  208. package/dist/graph/dependency-graph.test.js +276 -0
  209. package/dist/graph/dependency-graph.test.js.map +1 -0
  210. package/dist/graph/graph-builder.d.ts +11 -0
  211. package/dist/graph/graph-builder.js +113 -0
  212. package/dist/graph/graph-builder.js.map +1 -0
  213. package/dist/graph/graph-builder.test.d.ts +1 -0
  214. package/dist/graph/graph-builder.test.js +178 -0
  215. package/dist/graph/graph-builder.test.js.map +1 -0
  216. package/dist/graph/import-resolver.d.ts +11 -0
  217. package/dist/graph/import-resolver.js +199 -0
  218. package/dist/graph/import-resolver.js.map +1 -0
  219. package/dist/graph/import-resolver.test.d.ts +1 -0
  220. package/dist/graph/import-resolver.test.js +282 -0
  221. package/dist/graph/import-resolver.test.js.map +1 -0
  222. package/dist/graph/index.d.ts +7 -0
  223. package/dist/graph/index.js +4 -0
  224. package/dist/graph/index.js.map +1 -0
  225. package/dist/index.d.ts +31 -0
  226. package/dist/index.js +15 -0
  227. package/dist/index.js.map +1 -0
  228. package/dist/indexer/file-scanner.d.ts +34 -0
  229. package/dist/indexer/file-scanner.js +69 -0
  230. package/dist/indexer/file-scanner.js.map +1 -0
  231. package/dist/indexer/file-scanner.test.d.ts +1 -0
  232. package/dist/indexer/file-scanner.test.js +110 -0
  233. package/dist/indexer/file-scanner.test.js.map +1 -0
  234. package/dist/indexer/file-watcher.d.ts +79 -0
  235. package/dist/indexer/file-watcher.js +148 -0
  236. package/dist/indexer/incremental-indexer.d.ts +67 -0
  237. package/dist/indexer/incremental-indexer.js +142 -0
  238. package/dist/indexer/incremental-indexer.js.map +1 -0
  239. package/dist/indexer/incremental-indexer.test.d.ts +1 -0
  240. package/dist/indexer/incremental-indexer.test.js +266 -0
  241. package/dist/indexer/incremental-indexer.test.js.map +1 -0
  242. package/dist/indexer/index-check.d.ts +22 -0
  243. package/dist/indexer/index-check.js +74 -0
  244. package/dist/indexer/index-check.js.map +1 -0
  245. package/dist/indexer/index-check.test.d.ts +1 -0
  246. package/dist/indexer/index-check.test.js +100 -0
  247. package/dist/indexer/index-check.test.js.map +1 -0
  248. package/dist/indexer/index-state.d.ts +61 -0
  249. package/dist/indexer/index-state.js +82 -0
  250. package/dist/indexer/index-state.js.map +1 -0
  251. package/dist/indexer/index-state.test.d.ts +1 -0
  252. package/dist/indexer/index-state.test.js +140 -0
  253. package/dist/indexer/index-state.test.js.map +1 -0
  254. package/dist/indexer/index.d.ts +12 -0
  255. package/dist/indexer/index.js +6 -0
  256. package/dist/indexer/index.js.map +1 -0
  257. package/dist/indexer/multi-repo-indexer.d.ts +63 -0
  258. package/dist/indexer/multi-repo-indexer.js +144 -0
  259. package/dist/indexer/multi-repo-indexer.js.map +1 -0
  260. package/dist/indexer/multi-repo-indexer.test.d.ts +1 -0
  261. package/dist/indexer/multi-repo-indexer.test.js +238 -0
  262. package/dist/indexer/multi-repo-indexer.test.js.map +1 -0
  263. package/dist/parser/index.d.ts +4 -0
  264. package/dist/parser/index.js +3 -0
  265. package/dist/parser/index.js.map +1 -0
  266. package/dist/parser/language-registry.d.ts +46 -0
  267. package/dist/parser/language-registry.js +219 -0
  268. package/dist/parser/language-registry.js.map +1 -0
  269. package/dist/parser/language-registry.test.d.ts +1 -0
  270. package/dist/parser/language-registry.test.js +225 -0
  271. package/dist/parser/language-registry.test.js.map +1 -0
  272. package/dist/parser/markdown-parser.d.ts +124 -0
  273. package/dist/parser/markdown-parser.js +487 -0
  274. package/dist/parser/markdown-parser.js.map +1 -0
  275. package/dist/parser/markdown-parser.test.d.ts +1 -0
  276. package/dist/parser/markdown-parser.test.js +600 -0
  277. package/dist/parser/markdown-parser.test.js.map +1 -0
  278. package/dist/parser/tree-sitter-parser.d.ts +32 -0
  279. package/dist/parser/tree-sitter-parser.js +146 -0
  280. package/dist/parser/tree-sitter-parser.js.map +1 -0
  281. package/dist/retrieval/context-expander.d.ts +51 -0
  282. package/dist/retrieval/context-expander.js +218 -0
  283. package/dist/retrieval/context-expander.js.map +1 -0
  284. package/dist/retrieval/context-expander.test.d.ts +1 -0
  285. package/dist/retrieval/context-expander.test.js +339 -0
  286. package/dist/retrieval/context-expander.test.js.map +1 -0
  287. package/dist/retrieval/cross-encoder-reranker.d.ts +16 -0
  288. package/dist/retrieval/cross-encoder-reranker.js +90 -0
  289. package/dist/retrieval/cross-encoder-reranker.js.map +1 -0
  290. package/dist/retrieval/cross-encoder-reranker.test.d.ts +1 -0
  291. package/dist/retrieval/cross-encoder-reranker.test.js +305 -0
  292. package/dist/retrieval/cross-encoder-reranker.test.js.map +1 -0
  293. package/dist/retrieval/index.d.ts +8 -0
  294. package/dist/retrieval/index.js +4 -0
  295. package/dist/retrieval/index.js.map +1 -0
  296. package/dist/retrieval/query-analyzer.d.ts +29 -0
  297. package/dist/retrieval/query-analyzer.js +238 -0
  298. package/dist/retrieval/query-analyzer.js.map +1 -0
  299. package/dist/retrieval/query-analyzer.test.d.ts +1 -0
  300. package/dist/retrieval/query-analyzer.test.js +236 -0
  301. package/dist/retrieval/query-analyzer.test.js.map +1 -0
  302. package/dist/retrieval/token-budget.d.ts +51 -0
  303. package/dist/retrieval/token-budget.js +141 -0
  304. package/dist/retrieval/token-budget.js.map +1 -0
  305. package/dist/retrieval/token-budget.test.d.ts +1 -0
  306. package/dist/retrieval/token-budget.test.js +404 -0
  307. package/dist/retrieval/token-budget.test.js.map +1 -0
  308. package/dist/storage/azure-blob-provider.d.ts +19 -0
  309. package/dist/storage/azure-blob-provider.js +199 -0
  310. package/dist/storage/azure-blob-provider.js.map +1 -0
  311. package/dist/storage/azure-blob-provider.test.d.ts +1 -0
  312. package/dist/storage/azure-blob-provider.test.js +250 -0
  313. package/dist/storage/azure-blob-provider.test.js.map +1 -0
  314. package/dist/storage/gcs-provider.d.ts +22 -0
  315. package/dist/storage/gcs-provider.js +241 -0
  316. package/dist/storage/gcs-provider.js.map +1 -0
  317. package/dist/storage/gcs-provider.test.d.ts +1 -0
  318. package/dist/storage/gcs-provider.test.js +299 -0
  319. package/dist/storage/gcs-provider.test.js.map +1 -0
  320. package/dist/storage/index.d.ts +5 -0
  321. package/dist/storage/index.js +4 -0
  322. package/dist/storage/index.js.map +1 -0
  323. package/dist/storage/s3-provider.d.ts +21 -0
  324. package/dist/storage/s3-provider.js +220 -0
  325. package/dist/storage/s3-provider.js.map +1 -0
  326. package/dist/storage/s3-provider.test.d.ts +1 -0
  327. package/dist/storage/s3-provider.test.js +329 -0
  328. package/dist/storage/s3-provider.test.js.map +1 -0
  329. package/dist/storage/types.d.ts +65 -0
  330. package/dist/storage/types.js +12 -0
  331. package/dist/storage/types.js.map +1 -0
  332. package/dist/types/chunk.d.ts +32 -0
  333. package/dist/types/chunk.js +1 -0
  334. package/dist/types/chunk.js.map +1 -0
  335. package/dist/types/config.d.ts +71 -0
  336. package/dist/types/config.js +1 -0
  337. package/dist/types/config.js.map +1 -0
  338. package/dist/types/index.d.ts +5 -0
  339. package/dist/types/index.js +1 -0
  340. package/dist/types/index.js.map +1 -0
  341. package/dist/types/provider.d.ts +54 -0
  342. package/dist/types/provider.js +36 -0
  343. package/dist/types/provider.js.map +1 -0
  344. package/dist/types/search.d.ts +27 -0
  345. package/dist/types/search.js +1 -0
  346. package/dist/types/search.js.map +1 -0
  347. package/package.json +70 -0
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,266 @@
1
+ import { describe, it, expect, vi, beforeEach } from 'vitest';
2
+ import { ok, err } from 'neverthrow';
3
+ import { HybridSearch } from './hybrid-search.js';
4
+ import { BM25Index } from './bm25-index.js';
5
+ import { EmbedError, StoreError } from '../types/provider.js';
6
+ function createMockEmbeddingProvider(embeddings = [[0.1, 0.2, 0.3]]) {
7
+ return {
8
+ embed: vi.fn().mockResolvedValue(ok(embeddings)),
9
+ dimensions: 3,
10
+ };
11
+ }
12
+ function createMockVectorStore(results = []) {
13
+ return {
14
+ upsert: vi.fn().mockResolvedValue(ok(undefined)),
15
+ query: vi.fn().mockResolvedValue(ok(results)),
16
+ delete: vi.fn().mockResolvedValue(ok(undefined)),
17
+ count: vi.fn().mockResolvedValue(ok(0)),
18
+ close: vi.fn(),
19
+ };
20
+ }
21
+ function createMockBM25Index(results = []) {
22
+ const index = new BM25Index();
23
+ vi.spyOn(index, 'search').mockReturnValue(results);
24
+ return index;
25
+ }
26
+ function makeSearchResult(overrides) {
27
+ const metadata = {
28
+ chunkType: 'function',
29
+ name: overrides.chunkId,
30
+ declarations: [],
31
+ imports: [],
32
+ exports: [],
33
+ };
34
+ return {
35
+ content: `content of ${overrides.chunkId}`,
36
+ nlSummary: `summary of ${overrides.chunkId}`,
37
+ score: 1.0,
38
+ method: 'bm25',
39
+ metadata,
40
+ ...overrides,
41
+ };
42
+ }
43
+ const DEFAULT_CONFIG = {
44
+ topK: 10,
45
+ vectorWeight: 0.7,
46
+ bm25Weight: 0.3,
47
+ };
48
+ describe('HybridSearch', () => {
49
+ let embeddingProvider;
50
+ let vectorStore;
51
+ let bm25Index;
52
+ let hybridSearch;
53
+ beforeEach(() => {
54
+ embeddingProvider = createMockEmbeddingProvider();
55
+ vectorStore = createMockVectorStore([
56
+ { id: 'chunk-1', score: 0.95, metadata: { content: 'vector content 1', nl_summary: 'vector summary 1', chunk_type: 'function', file_path: 'src/a.ts', language: 'typescript', name: 'chunk-1' } },
57
+ { id: 'chunk-2', score: 0.80, metadata: { content: 'vector content 2', nl_summary: 'vector summary 2', chunk_type: 'class', file_path: 'src/b.ts', language: 'typescript', name: 'chunk-2' } },
58
+ { id: 'chunk-3', score: 0.70, metadata: { content: 'vector content 3', nl_summary: 'vector summary 3', chunk_type: 'function', file_path: 'src/c.ts', language: 'typescript', name: 'chunk-3' } },
59
+ ]);
60
+ bm25Index = createMockBM25Index([
61
+ makeSearchResult({ chunkId: 'chunk-2', score: 5.0 }),
62
+ makeSearchResult({ chunkId: 'chunk-4', score: 3.0 }),
63
+ makeSearchResult({ chunkId: 'chunk-1', score: 1.0 }),
64
+ ]);
65
+ hybridSearch = new HybridSearch(vectorStore, bm25Index, embeddingProvider, DEFAULT_CONFIG);
66
+ });
67
+ describe('search', () => {
68
+ it('should combine vector and BM25 results using RRF', async () => {
69
+ const result = await hybridSearch.search('add numbers');
70
+ expect(result.isOk()).toBe(true);
71
+ if (result.isOk()) {
72
+ expect(result.value.length).toBeGreaterThan(0);
73
+ // All results should have method 'hybrid'
74
+ for (const r of result.value) {
75
+ expect(r.method).toBe('hybrid');
76
+ }
77
+ }
78
+ });
79
+ it('should deduplicate results that appear in both searches', async () => {
80
+ const result = await hybridSearch.search('add numbers');
81
+ expect(result.isOk()).toBe(true);
82
+ if (result.isOk()) {
83
+ const chunkIds = result.value.map((r) => r.chunkId);
84
+ const uniqueIds = new Set(chunkIds);
85
+ expect(chunkIds.length).toBe(uniqueIds.size);
86
+ }
87
+ });
88
+ it('should embed the query text', async () => {
89
+ await hybridSearch.search('test query');
90
+ expect(embeddingProvider.embed).toHaveBeenCalledWith(['test query']);
91
+ });
92
+ it('should query vector store with embedded query', async () => {
93
+ await hybridSearch.search('test query');
94
+ expect(vectorStore.query).toHaveBeenCalledWith([0.1, 0.2, 0.3], expect.any(Number));
95
+ });
96
+ it('should query BM25 index with original query', async () => {
97
+ await hybridSearch.search('test query');
98
+ expect(bm25Index.search).toHaveBeenCalledWith('test query', expect.any(Number));
99
+ });
100
+ it('should fetch 2*topK from each source', async () => {
101
+ await hybridSearch.search('test query');
102
+ // Default topK is 10, so fetchK should be 20
103
+ expect(vectorStore.query).toHaveBeenCalledWith(expect.any(Array), 20);
104
+ expect(bm25Index.search).toHaveBeenCalledWith('test query', 20);
105
+ });
106
+ it('should respect custom topK option', async () => {
107
+ await hybridSearch.search('test query', { topK: 5 });
108
+ expect(vectorStore.query).toHaveBeenCalledWith(expect.any(Array), 10);
109
+ expect(bm25Index.search).toHaveBeenCalledWith('test query', 10);
110
+ });
111
+ it('should return at most topK results', async () => {
112
+ const result = await hybridSearch.search('test query', { topK: 2 });
113
+ expect(result.isOk()).toBe(true);
114
+ if (result.isOk()) {
115
+ expect(result.value.length).toBeLessThanOrEqual(2);
116
+ }
117
+ });
118
+ it('should sort results by fused score descending', async () => {
119
+ const result = await hybridSearch.search('test query');
120
+ expect(result.isOk()).toBe(true);
121
+ if (result.isOk()) {
122
+ for (let i = 1; i < result.value.length; i++) {
123
+ expect(result.value[i - 1].score).toBeGreaterThanOrEqual(result.value[i].score);
124
+ }
125
+ }
126
+ });
127
+ it('should apply vectorWeight and bm25Weight to RRF scores', async () => {
128
+ // chunk-1 is rank 0 in vector (rrfScore = 1/61), rank 2 in BM25 (rrfScore = 1/63)
129
+ // chunk-2 is rank 1 in vector (rrfScore = 1/62), rank 0 in BM25 (rrfScore = 1/61)
130
+ const result = await hybridSearch.search('test query');
131
+ expect(result.isOk()).toBe(true);
132
+ if (result.isOk()) {
133
+ const chunk1 = result.value.find((r) => r.chunkId === 'chunk-1');
134
+ const chunk2 = result.value.find((r) => r.chunkId === 'chunk-2');
135
+ expect(chunk1).toBeDefined();
136
+ expect(chunk2).toBeDefined();
137
+ // chunk-1: vectorWeight * (1/61) + bm25Weight * (1/63)
138
+ const expectedChunk1Score = 0.7 * (1 / 61) + 0.3 * (1 / 63);
139
+ // chunk-2: vectorWeight * (1/62) + bm25Weight * (1/61)
140
+ const expectedChunk2Score = 0.7 * (1 / 62) + 0.3 * (1 / 61);
141
+ expect(chunk1.score).toBeCloseTo(expectedChunk1Score, 6);
142
+ expect(chunk2.score).toBeCloseTo(expectedChunk2Score, 6);
143
+ }
144
+ });
145
+ it('should use custom weights from options', async () => {
146
+ const result = await hybridSearch.search('test query', {
147
+ vectorWeight: 0.5,
148
+ bm25Weight: 0.5,
149
+ });
150
+ expect(result.isOk()).toBe(true);
151
+ if (result.isOk()) {
152
+ const chunk1 = result.value.find((r) => r.chunkId === 'chunk-1');
153
+ expect(chunk1).toBeDefined();
154
+ const expectedScore = 0.5 * (1 / 61) + 0.5 * (1 / 63);
155
+ expect(chunk1.score).toBeCloseTo(expectedScore, 6);
156
+ }
157
+ });
158
+ it('should handle results only in vector store', async () => {
159
+ // chunk-3 only appears in vector results
160
+ const result = await hybridSearch.search('test query');
161
+ expect(result.isOk()).toBe(true);
162
+ if (result.isOk()) {
163
+ const chunk3 = result.value.find((r) => r.chunkId === 'chunk-3');
164
+ expect(chunk3).toBeDefined();
165
+ // Only vector RRF score, no BM25 contribution
166
+ const expectedScore = 0.7 * (1 / 63);
167
+ expect(chunk3.score).toBeCloseTo(expectedScore, 6);
168
+ }
169
+ });
170
+ it('should hydrate vector-only results with metadata from vector store', async () => {
171
+ // chunk-3 only appears in vector results (not in BM25)
172
+ const result = await hybridSearch.search('test query');
173
+ expect(result.isOk()).toBe(true);
174
+ if (result.isOk()) {
175
+ const chunk3 = result.value.find((r) => r.chunkId === 'chunk-3');
176
+ expect(chunk3).toBeDefined();
177
+ expect(chunk3.content).toBe('vector content 3');
178
+ expect(chunk3.nlSummary).toBe('vector summary 3');
179
+ expect(chunk3.metadata.name).toBe('chunk-3');
180
+ expect(chunk3.metadata.chunkType).toBe('function');
181
+ expect(chunk3.chunk).toBeDefined();
182
+ expect(chunk3.chunk.filePath).toBe('src/c.ts');
183
+ expect(chunk3.chunk.language).toBe('typescript');
184
+ }
185
+ });
186
+ it('should handle results only in BM25 index', async () => {
187
+ // chunk-4 only appears in BM25 results
188
+ const result = await hybridSearch.search('test query');
189
+ expect(result.isOk()).toBe(true);
190
+ if (result.isOk()) {
191
+ const chunk4 = result.value.find((r) => r.chunkId === 'chunk-4');
192
+ expect(chunk4).toBeDefined();
193
+ // Only BM25 RRF score, no vector contribution
194
+ const expectedScore = 0.3 * (1 / 62);
195
+ expect(chunk4.score).toBeCloseTo(expectedScore, 6);
196
+ }
197
+ });
198
+ it('should return error when embedding fails', async () => {
199
+ const failingProvider = {
200
+ embed: vi
201
+ .fn()
202
+ .mockResolvedValue(err(new EmbedError('Embed failed'))),
203
+ dimensions: 3,
204
+ };
205
+ const search = new HybridSearch(vectorStore, bm25Index, failingProvider, DEFAULT_CONFIG);
206
+ const result = await search.search('test');
207
+ expect(result.isErr()).toBe(true);
208
+ if (result.isErr()) {
209
+ expect(result.error).toBeInstanceOf(EmbedError);
210
+ expect(result.error.message).toContain('Embed failed');
211
+ }
212
+ });
213
+ it('should return error when vector store query fails', async () => {
214
+ const failingStore = {
215
+ upsert: vi.fn().mockResolvedValue(ok(undefined)),
216
+ query: vi
217
+ .fn()
218
+ .mockResolvedValue(err(new StoreError('Query failed'))),
219
+ delete: vi.fn().mockResolvedValue(ok(undefined)),
220
+ count: vi.fn().mockResolvedValue(ok(0)),
221
+ close: vi.fn(),
222
+ };
223
+ const search = new HybridSearch(failingStore, bm25Index, embeddingProvider, DEFAULT_CONFIG);
224
+ const result = await search.search('test');
225
+ expect(result.isErr()).toBe(true);
226
+ if (result.isErr()) {
227
+ expect(result.error).toBeInstanceOf(EmbedError);
228
+ expect(result.error.message).toContain('Query failed');
229
+ }
230
+ });
231
+ it('should return error when embedding returns empty result', async () => {
232
+ const emptyProvider = {
233
+ embed: vi.fn().mockResolvedValue(ok([])),
234
+ dimensions: 3,
235
+ };
236
+ const search = new HybridSearch(vectorStore, bm25Index, emptyProvider, DEFAULT_CONFIG);
237
+ const result = await search.search('test');
238
+ expect(result.isErr()).toBe(true);
239
+ if (result.isErr()) {
240
+ expect(result.error).toBeInstanceOf(EmbedError);
241
+ expect(result.error.message).toContain('Failed to generate query embedding');
242
+ }
243
+ });
244
+ it('should handle empty results from both sources', async () => {
245
+ const emptyVectorStore = createMockVectorStore([]);
246
+ const emptyBM25 = createMockBM25Index([]);
247
+ const search = new HybridSearch(emptyVectorStore, emptyBM25, embeddingProvider, DEFAULT_CONFIG);
248
+ const result = await search.search('test');
249
+ expect(result.isOk()).toBe(true);
250
+ if (result.isOk()) {
251
+ expect(result.value).toEqual([]);
252
+ }
253
+ });
254
+ it('should include BM25 result content in final output', async () => {
255
+ const result = await hybridSearch.search('test');
256
+ expect(result.isOk()).toBe(true);
257
+ if (result.isOk()) {
258
+ const chunk2 = result.value.find((r) => r.chunkId === 'chunk-2');
259
+ expect(chunk2).toBeDefined();
260
+ expect(chunk2.content).toBe('content of chunk-2');
261
+ expect(chunk2.nlSummary).toBe('summary of chunk-2');
262
+ }
263
+ });
264
+ });
265
+ });
266
+ //# sourceMappingURL=hybrid-search.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hybrid-search.test.js","sourceRoot":"","sources":["../../src/embedding/hybrid-search.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ export { OllamaEmbeddingProvider } from './ollama-embedding-provider.js';
2
+ export type { OllamaEmbeddingConfig } from './ollama-embedding-provider.js';
3
+ export { OpenAICompatibleEmbeddingProvider } from './openai-compatible-embedding-provider.js';
4
+ export type { OpenAICompatibleEmbeddingConfig } from './openai-compatible-embedding-provider.js';
5
+ export { ModelLifecycleManager, ModelLifecycleError } from './model-lifecycle-manager.js';
6
+ export type { ModelLifecycleConfig, BackendInfo, BackendType, GpuMode, DockerConfig, ProgressCallback, ProcessExecutor, FetchFn, } from './model-lifecycle-manager.js';
7
+ export { LanceDBStore } from './lancedb-store.js';
8
+ export { QdrantVectorStore } from './qdrant-store.js';
9
+ export type { QdrantConfig } from './qdrant-store.js';
10
+ export { BM25Index } from './bm25-index.js';
11
+ export { HybridSearch } from './hybrid-search.js';
@@ -0,0 +1,7 @@
1
+ export { OllamaEmbeddingProvider } from './ollama-embedding-provider.js';
2
+ export { OpenAICompatibleEmbeddingProvider } from './openai-compatible-embedding-provider.js';
3
+ export { ModelLifecycleManager, ModelLifecycleError } from './model-lifecycle-manager.js';
4
+ export { LanceDBStore } from './lancedb-store.js';
5
+ export { QdrantVectorStore } from './qdrant-store.js';
6
+ export { BM25Index } from './bm25-index.js';
7
+ export { HybridSearch } from './hybrid-search.js';
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/embedding/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AAEzE,OAAO,EAAE,iCAAiC,EAAE,MAAM,2CAA2C,CAAC;AAE9F,OAAO,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAW1F,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEtD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,21 @@
1
+ import { type Result } from 'neverthrow';
2
+ import { StoreError, type VectorStore } from '../types/provider.js';
3
+ export declare class LanceDBStore implements VectorStore {
4
+ private readonly storagePath;
5
+ private readonly _dimensions;
6
+ private db;
7
+ private table;
8
+ constructor(storagePath: string, dimensions: number);
9
+ get dimensions(): number;
10
+ connect(): Promise<void>;
11
+ private ensureConnected;
12
+ upsert(ids: string[], embeddings: number[][], metadata: Record<string, unknown>[]): Promise<Result<void, StoreError>>;
13
+ query(embedding: number[], topK: number): Promise<Result<{
14
+ id: string;
15
+ score: number;
16
+ metadata?: Record<string, unknown>;
17
+ }[], StoreError>>;
18
+ delete(ids: string[]): Promise<Result<void, StoreError>>;
19
+ count(): Promise<Result<number, StoreError>>;
20
+ close(): void;
21
+ }
@@ -0,0 +1,172 @@
1
+ import { ok, err } from 'neverthrow';
2
+ import { StoreError } from '../types/provider.js';
3
+ import * as lancedb from '@lancedb/lancedb';
4
+ const TABLE_NAME = 'chunks';
5
+ const SAFE_ID_PATTERN = /^[a-zA-Z0-9_\-:.]+$/;
6
+ function safeParseJSON(json) {
7
+ try {
8
+ const parsed = JSON.parse(json);
9
+ if (parsed !== null && typeof parsed === 'object' && !Array.isArray(parsed)) {
10
+ return parsed;
11
+ }
12
+ return {};
13
+ }
14
+ catch {
15
+ return {};
16
+ }
17
+ }
18
+ function validateId(id) {
19
+ return SAFE_ID_PATTERN.test(id) && id.length > 0 && id.length <= 256;
20
+ }
21
+ export class LanceDBStore {
22
+ storagePath;
23
+ _dimensions;
24
+ db = null;
25
+ table = null;
26
+ constructor(storagePath, dimensions) {
27
+ this.storagePath = storagePath;
28
+ this._dimensions = dimensions;
29
+ }
30
+ get dimensions() {
31
+ return this._dimensions;
32
+ }
33
+ async connect() {
34
+ const dbPath = `${this.storagePath}/lancedb`;
35
+ this.db = await lancedb.connect(dbPath);
36
+ try {
37
+ const tableNames = await this.db.tableNames();
38
+ if (tableNames.includes(TABLE_NAME)) {
39
+ this.table = await this.db.openTable(TABLE_NAME);
40
+ }
41
+ }
42
+ catch {
43
+ // Table does not exist yet, will be created on first upsert
44
+ this.table = null;
45
+ }
46
+ }
47
+ async ensureConnected() {
48
+ if (!this.db) {
49
+ await this.connect();
50
+ }
51
+ }
52
+ async upsert(ids, embeddings, metadata) {
53
+ try {
54
+ for (const id of ids) {
55
+ if (!validateId(id)) {
56
+ return err(new StoreError(`Invalid chunk ID: ${id}`));
57
+ }
58
+ }
59
+ await this.ensureConnected();
60
+ const rows = ids.map((id, i) => {
61
+ const meta = metadata[i] ?? {};
62
+ return {
63
+ id,
64
+ vector: embeddings[i] ?? [],
65
+ content: meta['content'] ?? '',
66
+ nl_summary: meta['nl_summary'] ?? '',
67
+ chunk_type: meta['chunk_type'] ?? '',
68
+ file_path: meta['file_path'] ?? '',
69
+ language: meta['language'] ?? '',
70
+ metadata: JSON.stringify(meta),
71
+ };
72
+ });
73
+ const data = rows;
74
+ if (!this.table) {
75
+ this.table = await this.db.createTable(TABLE_NAME, data);
76
+ }
77
+ else {
78
+ // Batch delete existing rows, then add new ones
79
+ if (ids.length > 0) {
80
+ const filterParts = ids.map((id) => `'${id}'`);
81
+ const filter = `id IN (${filterParts.join(', ')})`;
82
+ try {
83
+ await this.table.delete(filter);
84
+ }
85
+ catch {
86
+ // Rows may not exist, that's fine
87
+ }
88
+ }
89
+ await this.table.add(data);
90
+ }
91
+ return ok(undefined);
92
+ }
93
+ catch (error) {
94
+ const message = error instanceof Error ? error.message : 'Unknown error';
95
+ return err(new StoreError(`LanceDB upsert failed: ${message}`));
96
+ }
97
+ }
98
+ async query(embedding, topK) {
99
+ try {
100
+ await this.ensureConnected();
101
+ if (!this.table) {
102
+ return ok([]);
103
+ }
104
+ const results = (await this.table
105
+ .search(embedding)
106
+ .limit(topK)
107
+ .toArray());
108
+ const mapped = results.map((row) => ({
109
+ id: row.id,
110
+ score: 1 / (1 + (row._distance ?? 0)),
111
+ metadata: {
112
+ content: row.content,
113
+ nl_summary: row.nl_summary,
114
+ chunk_type: row.chunk_type,
115
+ file_path: row.file_path,
116
+ language: row.language,
117
+ ...(row.metadata ? safeParseJSON(row.metadata) : {}),
118
+ },
119
+ }));
120
+ return ok(mapped);
121
+ }
122
+ catch (error) {
123
+ const message = error instanceof Error ? error.message : 'Unknown error';
124
+ return err(new StoreError(`LanceDB query failed: ${message}`));
125
+ }
126
+ }
127
+ async delete(ids) {
128
+ try {
129
+ for (const id of ids) {
130
+ if (!validateId(id)) {
131
+ return err(new StoreError(`Invalid chunk ID: ${id}`));
132
+ }
133
+ }
134
+ await this.ensureConnected();
135
+ if (!this.table || ids.length === 0) {
136
+ return ok(undefined);
137
+ }
138
+ const filterParts = ids.map((id) => `'${id}'`);
139
+ const filter = `id IN (${filterParts.join(', ')})`;
140
+ await this.table.delete(filter);
141
+ return ok(undefined);
142
+ }
143
+ catch (error) {
144
+ const message = error instanceof Error ? error.message : 'Unknown error';
145
+ return err(new StoreError(`LanceDB delete failed: ${message}`));
146
+ }
147
+ }
148
+ async count() {
149
+ try {
150
+ await this.ensureConnected();
151
+ if (!this.table) {
152
+ return ok(0);
153
+ }
154
+ const rows = await this.table.countRows();
155
+ return ok(rows);
156
+ }
157
+ catch (error) {
158
+ const message = error instanceof Error ? error.message : 'Unknown error';
159
+ return err(new StoreError(`LanceDB count failed: ${message}`));
160
+ }
161
+ }
162
+ close() {
163
+ if (this.table) {
164
+ this.table.close();
165
+ this.table = null;
166
+ }
167
+ if (this.db) {
168
+ this.db.close();
169
+ this.db = null;
170
+ }
171
+ }
172
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lancedb-store.js","sourceRoot":"","sources":["../../src/embedding/lancedb-store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};