@remnic/core 1.0.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 (551) hide show
  1. package/dist/abstraction-nodes.d.ts +52 -0
  2. package/dist/abstraction-nodes.js +15 -0
  3. package/dist/abstraction-nodes.js.map +1 -0
  4. package/dist/access-cli.d.ts +5 -0
  5. package/dist/access-cli.js +308 -0
  6. package/dist/access-cli.js.map +1 -0
  7. package/dist/access-http.d.ts +158 -0
  8. package/dist/access-http.js +32 -0
  9. package/dist/access-http.js.map +1 -0
  10. package/dist/access-idempotency.d.ts +31 -0
  11. package/dist/access-idempotency.js +11 -0
  12. package/dist/access-idempotency.js.map +1 -0
  13. package/dist/access-mcp.d.ts +76 -0
  14. package/dist/access-mcp.js +8 -0
  15. package/dist/access-mcp.js.map +1 -0
  16. package/dist/access-schema.d.ts +266 -0
  17. package/dist/access-schema.js +29 -0
  18. package/dist/access-schema.js.map +1 -0
  19. package/dist/access-service.d.ts +614 -0
  20. package/dist/access-service.js +32 -0
  21. package/dist/access-service.js.map +1 -0
  22. package/dist/behavior-learner.d.ts +16 -0
  23. package/dist/behavior-learner.js +124 -0
  24. package/dist/behavior-learner.js.map +1 -0
  25. package/dist/behavior-signals.d.ts +15 -0
  26. package/dist/behavior-signals.js +11 -0
  27. package/dist/behavior-signals.js.map +1 -0
  28. package/dist/bootstrap.d.ts +46 -0
  29. package/dist/bootstrap.js +9 -0
  30. package/dist/bootstrap.js.map +1 -0
  31. package/dist/boxes.d.ts +93 -0
  32. package/dist/boxes.js +14 -0
  33. package/dist/boxes.js.map +1 -0
  34. package/dist/buffer.d.ts +22 -0
  35. package/dist/buffer.js +9 -0
  36. package/dist/buffer.js.map +1 -0
  37. package/dist/calibration.d.ts +81 -0
  38. package/dist/calibration.js +239 -0
  39. package/dist/calibration.js.map +1 -0
  40. package/dist/causal-behavior.d.ts +79 -0
  41. package/dist/causal-behavior.js +190 -0
  42. package/dist/causal-behavior.js.map +1 -0
  43. package/dist/causal-chain.d.ts +61 -0
  44. package/dist/causal-chain.js +24 -0
  45. package/dist/causal-chain.js.map +1 -0
  46. package/dist/causal-consolidation.d.ts +71 -0
  47. package/dist/causal-consolidation.js +211 -0
  48. package/dist/causal-consolidation.js.map +1 -0
  49. package/dist/causal-retrieval.d.ts +44 -0
  50. package/dist/causal-retrieval.js +184 -0
  51. package/dist/causal-retrieval.js.map +1 -0
  52. package/dist/causal-trajectory-graph.d.ts +13 -0
  53. package/dist/causal-trajectory-graph.js +59 -0
  54. package/dist/causal-trajectory-graph.js.map +1 -0
  55. package/dist/causal-trajectory.d.ts +68 -0
  56. package/dist/causal-trajectory.js +18 -0
  57. package/dist/causal-trajectory.js.map +1 -0
  58. package/dist/chunk-2CJCWDMR.js +87 -0
  59. package/dist/chunk-2CJCWDMR.js.map +1 -0
  60. package/dist/chunk-2NMMFZ5T.js +216 -0
  61. package/dist/chunk-2NMMFZ5T.js.map +1 -0
  62. package/dist/chunk-2PO5ZRKV.js +103 -0
  63. package/dist/chunk-2PO5ZRKV.js.map +1 -0
  64. package/dist/chunk-3QKK7QOS.js +154 -0
  65. package/dist/chunk-3QKK7QOS.js.map +1 -0
  66. package/dist/chunk-3SLRNYNG.js +26 -0
  67. package/dist/chunk-3SLRNYNG.js.map +1 -0
  68. package/dist/chunk-4A24LIM2.js +68 -0
  69. package/dist/chunk-4A24LIM2.js.map +1 -0
  70. package/dist/chunk-6HZ6AO2P.js +164 -0
  71. package/dist/chunk-6HZ6AO2P.js.map +1 -0
  72. package/dist/chunk-763GUIOU.js +302 -0
  73. package/dist/chunk-763GUIOU.js.map +1 -0
  74. package/dist/chunk-AAI7JARD.js +173 -0
  75. package/dist/chunk-AAI7JARD.js.map +1 -0
  76. package/dist/chunk-B7LOFDVE.js +112 -0
  77. package/dist/chunk-B7LOFDVE.js.map +1 -0
  78. package/dist/chunk-BDFZXRSO.js +318 -0
  79. package/dist/chunk-BDFZXRSO.js.map +1 -0
  80. package/dist/chunk-BOUYNNYD.js +707 -0
  81. package/dist/chunk-BOUYNNYD.js.map +1 -0
  82. package/dist/chunk-BRK4ODMI.js +60 -0
  83. package/dist/chunk-BRK4ODMI.js.map +1 -0
  84. package/dist/chunk-C6QPK5GG.js +111 -0
  85. package/dist/chunk-C6QPK5GG.js.map +1 -0
  86. package/dist/chunk-C7VW7C3F.js +117 -0
  87. package/dist/chunk-C7VW7C3F.js.map +1 -0
  88. package/dist/chunk-CDW777AI.js +621 -0
  89. package/dist/chunk-CDW777AI.js.map +1 -0
  90. package/dist/chunk-CULXMQJH.js +185 -0
  91. package/dist/chunk-CULXMQJH.js.map +1 -0
  92. package/dist/chunk-CXWFUJR2.js +1203 -0
  93. package/dist/chunk-CXWFUJR2.js.map +1 -0
  94. package/dist/chunk-DGXUHMOV.js +61 -0
  95. package/dist/chunk-DGXUHMOV.js.map +1 -0
  96. package/dist/chunk-DM2T26WE.js +61 -0
  97. package/dist/chunk-DM2T26WE.js.map +1 -0
  98. package/dist/chunk-DORBM6OB.js +81 -0
  99. package/dist/chunk-DORBM6OB.js.map +1 -0
  100. package/dist/chunk-DT5TVLJE.js +32 -0
  101. package/dist/chunk-DT5TVLJE.js.map +1 -0
  102. package/dist/chunk-EEQLFRUM.js +89 -0
  103. package/dist/chunk-EEQLFRUM.js.map +1 -0
  104. package/dist/chunk-EQINRHYR.js +672 -0
  105. package/dist/chunk-EQINRHYR.js.map +1 -0
  106. package/dist/chunk-ESSMF2FR.js +146 -0
  107. package/dist/chunk-ESSMF2FR.js.map +1 -0
  108. package/dist/chunk-ETOW6ACV.js +158 -0
  109. package/dist/chunk-ETOW6ACV.js.map +1 -0
  110. package/dist/chunk-FYIYMQ5N.js +221 -0
  111. package/dist/chunk-FYIYMQ5N.js.map +1 -0
  112. package/dist/chunk-G3AG3KZN.js +78 -0
  113. package/dist/chunk-G3AG3KZN.js.map +1 -0
  114. package/dist/chunk-GJR6D6KC.js +61 -0
  115. package/dist/chunk-GJR6D6KC.js.map +1 -0
  116. package/dist/chunk-GPGBSNKM.js +380 -0
  117. package/dist/chunk-GPGBSNKM.js.map +1 -0
  118. package/dist/chunk-H63EDPFJ.js +57 -0
  119. package/dist/chunk-H63EDPFJ.js.map +1 -0
  120. package/dist/chunk-HG2NKWR2.js +185 -0
  121. package/dist/chunk-HG2NKWR2.js.map +1 -0
  122. package/dist/chunk-HL4DB7TO.js +13 -0
  123. package/dist/chunk-HL4DB7TO.js.map +1 -0
  124. package/dist/chunk-HLBYLYRD.js +346 -0
  125. package/dist/chunk-HLBYLYRD.js.map +1 -0
  126. package/dist/chunk-HLXVTBF3.js +109 -0
  127. package/dist/chunk-HLXVTBF3.js.map +1 -0
  128. package/dist/chunk-IFFFR3MR.js +68 -0
  129. package/dist/chunk-IFFFR3MR.js.map +1 -0
  130. package/dist/chunk-ISY75RLM.js +1027 -0
  131. package/dist/chunk-ISY75RLM.js.map +1 -0
  132. package/dist/chunk-IZME7KW2.js +1886 -0
  133. package/dist/chunk-IZME7KW2.js.map +1 -0
  134. package/dist/chunk-J3BT33K7.js +720 -0
  135. package/dist/chunk-J3BT33K7.js.map +1 -0
  136. package/dist/chunk-J47FNDR7.js +113 -0
  137. package/dist/chunk-J47FNDR7.js.map +1 -0
  138. package/dist/chunk-JWPLJLDU.js +63 -0
  139. package/dist/chunk-JWPLJLDU.js.map +1 -0
  140. package/dist/chunk-K6WK37A6.js +865 -0
  141. package/dist/chunk-K6WK37A6.js.map +1 -0
  142. package/dist/chunk-KL4CP4SB.js +130 -0
  143. package/dist/chunk-KL4CP4SB.js.map +1 -0
  144. package/dist/chunk-KT4NEUNF.js +315 -0
  145. package/dist/chunk-KT4NEUNF.js.map +1 -0
  146. package/dist/chunk-KWBU5S5U.js +42 -0
  147. package/dist/chunk-KWBU5S5U.js.map +1 -0
  148. package/dist/chunk-L5RPWGFK.js +59 -0
  149. package/dist/chunk-L5RPWGFK.js.map +1 -0
  150. package/dist/chunk-L7WO3MZ4.js +128 -0
  151. package/dist/chunk-L7WO3MZ4.js.map +1 -0
  152. package/dist/chunk-LIRZNNUP.js +74 -0
  153. package/dist/chunk-LIRZNNUP.js.map +1 -0
  154. package/dist/chunk-LK6SGL53.js +22 -0
  155. package/dist/chunk-LK6SGL53.js.map +1 -0
  156. package/dist/chunk-LOBRX7VD.js +200 -0
  157. package/dist/chunk-LOBRX7VD.js.map +1 -0
  158. package/dist/chunk-LPSF4OQH.js +47 -0
  159. package/dist/chunk-LPSF4OQH.js.map +1 -0
  160. package/dist/chunk-LU3GQNDQ.js +152 -0
  161. package/dist/chunk-LU3GQNDQ.js.map +1 -0
  162. package/dist/chunk-M5KEYE5E.js +350 -0
  163. package/dist/chunk-M5KEYE5E.js.map +1 -0
  164. package/dist/chunk-M62O4P4T.js +41 -0
  165. package/dist/chunk-M62O4P4T.js.map +1 -0
  166. package/dist/chunk-MARWOCVP.js +48 -0
  167. package/dist/chunk-MARWOCVP.js.map +1 -0
  168. package/dist/chunk-MDDAA2AO.js +925 -0
  169. package/dist/chunk-MDDAA2AO.js.map +1 -0
  170. package/dist/chunk-MWGVGUIS.js +198 -0
  171. package/dist/chunk-MWGVGUIS.js.map +1 -0
  172. package/dist/chunk-N5AKDXAI.js +74 -0
  173. package/dist/chunk-N5AKDXAI.js.map +1 -0
  174. package/dist/chunk-NGAVDO7E.js +115 -0
  175. package/dist/chunk-NGAVDO7E.js.map +1 -0
  176. package/dist/chunk-NTTLPF7F.js +283 -0
  177. package/dist/chunk-NTTLPF7F.js.map +1 -0
  178. package/dist/chunk-ONRU4L2N.js +240 -0
  179. package/dist/chunk-ONRU4L2N.js.map +1 -0
  180. package/dist/chunk-ORZMT74A.js +209 -0
  181. package/dist/chunk-ORZMT74A.js.map +1 -0
  182. package/dist/chunk-OTAVQCSF.js +268 -0
  183. package/dist/chunk-OTAVQCSF.js.map +1 -0
  184. package/dist/chunk-PGK3VUHN.js +160 -0
  185. package/dist/chunk-PGK3VUHN.js.map +1 -0
  186. package/dist/chunk-Q6FETXJA.js +1362 -0
  187. package/dist/chunk-Q6FETXJA.js.map +1 -0
  188. package/dist/chunk-QANCTXQF.js +271 -0
  189. package/dist/chunk-QANCTXQF.js.map +1 -0
  190. package/dist/chunk-QCCCQT3O.js +189 -0
  191. package/dist/chunk-QCCCQT3O.js.map +1 -0
  192. package/dist/chunk-QDOSNLB4.js +1048 -0
  193. package/dist/chunk-QDOSNLB4.js.map +1 -0
  194. package/dist/chunk-QFQVZOGA.js +2168 -0
  195. package/dist/chunk-QFQVZOGA.js.map +1 -0
  196. package/dist/chunk-QPKFPHOO.js +178 -0
  197. package/dist/chunk-QPKFPHOO.js.map +1 -0
  198. package/dist/chunk-QSVPYQPG.js +268 -0
  199. package/dist/chunk-QSVPYQPG.js.map +1 -0
  200. package/dist/chunk-QWUUMMIK.js +3045 -0
  201. package/dist/chunk-QWUUMMIK.js.map +1 -0
  202. package/dist/chunk-QY2BHY5O.js +2378 -0
  203. package/dist/chunk-QY2BHY5O.js.map +1 -0
  204. package/dist/chunk-SCHEKPYH.js +349 -0
  205. package/dist/chunk-SCHEKPYH.js.map +1 -0
  206. package/dist/chunk-SCU65EZI.js +15 -0
  207. package/dist/chunk-SCU65EZI.js.map +1 -0
  208. package/dist/chunk-T4WRIV2C.js +170 -0
  209. package/dist/chunk-T4WRIV2C.js.map +1 -0
  210. package/dist/chunk-TKO4HZCK.js +1852 -0
  211. package/dist/chunk-TKO4HZCK.js.map +1 -0
  212. package/dist/chunk-TP4FZJIZ.js +93 -0
  213. package/dist/chunk-TP4FZJIZ.js.map +1 -0
  214. package/dist/chunk-TPB3I2AC.js +403 -0
  215. package/dist/chunk-TPB3I2AC.js.map +1 -0
  216. package/dist/chunk-TVVVQQAK.js +1431 -0
  217. package/dist/chunk-TVVVQQAK.js.map +1 -0
  218. package/dist/chunk-U4PV25RD.js +14 -0
  219. package/dist/chunk-U4PV25RD.js.map +1 -0
  220. package/dist/chunk-UCYSTFZR.js +284 -0
  221. package/dist/chunk-UCYSTFZR.js.map +1 -0
  222. package/dist/chunk-UHGBNIOS.js +205 -0
  223. package/dist/chunk-UHGBNIOS.js.map +1 -0
  224. package/dist/chunk-UIYZ5T3I.js +108 -0
  225. package/dist/chunk-UIYZ5T3I.js.map +1 -0
  226. package/dist/chunk-UV2FO7J4.js +747 -0
  227. package/dist/chunk-UV2FO7J4.js.map +1 -0
  228. package/dist/chunk-UZB5KHKX.js +63 -0
  229. package/dist/chunk-UZB5KHKX.js.map +1 -0
  230. package/dist/chunk-V3RXWQIE.js +626 -0
  231. package/dist/chunk-V3RXWQIE.js.map +1 -0
  232. package/dist/chunk-V4YC4LUK.js +444 -0
  233. package/dist/chunk-V4YC4LUK.js.map +1 -0
  234. package/dist/chunk-VEWZZM3H.js +133 -0
  235. package/dist/chunk-VEWZZM3H.js.map +1 -0
  236. package/dist/chunk-WWIQTB2Y.js +98 -0
  237. package/dist/chunk-WWIQTB2Y.js.map +1 -0
  238. package/dist/chunk-X7XN6YU4.js +24 -0
  239. package/dist/chunk-X7XN6YU4.js.map +1 -0
  240. package/dist/chunk-XKECPATV.js +202 -0
  241. package/dist/chunk-XKECPATV.js.map +1 -0
  242. package/dist/chunk-XYIK4LF6.js +75 -0
  243. package/dist/chunk-XYIK4LF6.js.map +1 -0
  244. package/dist/chunk-Y27UJK6V.js +39 -0
  245. package/dist/chunk-Y27UJK6V.js.map +1 -0
  246. package/dist/chunk-Y4Z4I6WK.js +9 -0
  247. package/dist/chunk-Y4Z4I6WK.js.map +1 -0
  248. package/dist/chunk-YAPUAHAY.js +10761 -0
  249. package/dist/chunk-YAPUAHAY.js.map +1 -0
  250. package/dist/chunk-YAZNBMNF.js +92 -0
  251. package/dist/chunk-YAZNBMNF.js.map +1 -0
  252. package/dist/chunk-YCN4BVDK.js +66 -0
  253. package/dist/chunk-YCN4BVDK.js.map +1 -0
  254. package/dist/chunk-YNCQ7E4M.js +388 -0
  255. package/dist/chunk-YNCQ7E4M.js.map +1 -0
  256. package/dist/chunk-YNI4S5WT.js +143 -0
  257. package/dist/chunk-YNI4S5WT.js.map +1 -0
  258. package/dist/chunk-YRMVARQP.js +406 -0
  259. package/dist/chunk-YRMVARQP.js.map +1 -0
  260. package/dist/chunk-Z5AAYHUC.js +79 -0
  261. package/dist/chunk-Z5AAYHUC.js.map +1 -0
  262. package/dist/chunk-Z5LAYHGJ.js +15 -0
  263. package/dist/chunk-Z5LAYHGJ.js.map +1 -0
  264. package/dist/chunk-ZJLY4QSU.js +823 -0
  265. package/dist/chunk-ZJLY4QSU.js.map +1 -0
  266. package/dist/chunk-ZKYI7UVO.js +276 -0
  267. package/dist/chunk-ZKYI7UVO.js.map +1 -0
  268. package/dist/chunk-ZPKBYX2F.js +297 -0
  269. package/dist/chunk-ZPKBYX2F.js.map +1 -0
  270. package/dist/chunking.d.ts +48 -0
  271. package/dist/chunking.js +11 -0
  272. package/dist/chunking.js.map +1 -0
  273. package/dist/cli.d.ts +1162 -0
  274. package/dist/cli.js +7187 -0
  275. package/dist/cli.js.map +1 -0
  276. package/dist/commitment-ledger.d.ts +83 -0
  277. package/dist/commitment-ledger.js +19 -0
  278. package/dist/commitment-ledger.js.map +1 -0
  279. package/dist/compression-optimizer.d.ts +37 -0
  280. package/dist/compression-optimizer.js +13 -0
  281. package/dist/compression-optimizer.js.map +1 -0
  282. package/dist/config.d.ts +6 -0
  283. package/dist/config.js +12 -0
  284. package/dist/config.js.map +1 -0
  285. package/dist/cue-anchors.d.ts +50 -0
  286. package/dist/cue-anchors.js +15 -0
  287. package/dist/cue-anchors.js.map +1 -0
  288. package/dist/dashboard-runtime.d.ts +46 -0
  289. package/dist/dashboard-runtime.js +10 -0
  290. package/dist/dashboard-runtime.js.map +1 -0
  291. package/dist/day-summary.d.ts +6 -0
  292. package/dist/day-summary.js +10 -0
  293. package/dist/day-summary.js.map +1 -0
  294. package/dist/delinearize.d.ts +34 -0
  295. package/dist/delinearize.js +11 -0
  296. package/dist/delinearize.js.map +1 -0
  297. package/dist/embedding-fallback.d.ts +22 -0
  298. package/dist/embedding-fallback.js +8 -0
  299. package/dist/embedding-fallback.js.map +1 -0
  300. package/dist/engine-P26JFSVY.js +19 -0
  301. package/dist/engine-P26JFSVY.js.map +1 -0
  302. package/dist/entity-retrieval.d.ts +23 -0
  303. package/dist/entity-retrieval.js +24 -0
  304. package/dist/entity-retrieval.js.map +1 -0
  305. package/dist/evals.d.ts +282 -0
  306. package/dist/evals.js +32 -0
  307. package/dist/evals.js.map +1 -0
  308. package/dist/explicit-capture.d.ts +60 -0
  309. package/dist/explicit-capture.js +23 -0
  310. package/dist/explicit-capture.js.map +1 -0
  311. package/dist/extraction.d.ts +141 -0
  312. package/dist/extraction.js +22 -0
  313. package/dist/extraction.js.map +1 -0
  314. package/dist/fallback-llm.d.ts +95 -0
  315. package/dist/fallback-llm.js +12 -0
  316. package/dist/fallback-llm.js.map +1 -0
  317. package/dist/graph-dashboard-diff.d.ts +12 -0
  318. package/dist/graph-dashboard-diff.js +8 -0
  319. package/dist/graph-dashboard-diff.js.map +1 -0
  320. package/dist/graph-dashboard-key.d.ts +5 -0
  321. package/dist/graph-dashboard-key.js +7 -0
  322. package/dist/graph-dashboard-key.js.map +1 -0
  323. package/dist/graph-dashboard-parser.d.ts +20 -0
  324. package/dist/graph-dashboard-parser.js +8 -0
  325. package/dist/graph-dashboard-parser.js.map +1 -0
  326. package/dist/graph.d.ts +157 -0
  327. package/dist/graph.js +27 -0
  328. package/dist/graph.js.map +1 -0
  329. package/dist/harmonic-retrieval.d.ts +27 -0
  330. package/dist/harmonic-retrieval.js +12 -0
  331. package/dist/harmonic-retrieval.js.map +1 -0
  332. package/dist/himem.d.ts +23 -0
  333. package/dist/himem.js +7 -0
  334. package/dist/himem.js.map +1 -0
  335. package/dist/hygiene.d.ts +24 -0
  336. package/dist/hygiene.js +9 -0
  337. package/dist/hygiene.js.map +1 -0
  338. package/dist/identity-continuity.d.ts +17 -0
  339. package/dist/identity-continuity.js +19 -0
  340. package/dist/identity-continuity.js.map +1 -0
  341. package/dist/importance.d.ts +25 -0
  342. package/dist/importance.js +11 -0
  343. package/dist/importance.js.map +1 -0
  344. package/dist/index.d.ts +923 -0
  345. package/dist/index.js +2512 -0
  346. package/dist/index.js.map +1 -0
  347. package/dist/intent.d.ts +8 -0
  348. package/dist/intent.js +13 -0
  349. package/dist/intent.js.map +1 -0
  350. package/dist/json-extract.d.ts +14 -0
  351. package/dist/json-extract.js +9 -0
  352. package/dist/json-extract.js.map +1 -0
  353. package/dist/json-store.d.ts +5 -0
  354. package/dist/json-store.js +11 -0
  355. package/dist/json-store.js.map +1 -0
  356. package/dist/legacy-hook-compat.d.ts +3 -0
  357. package/dist/legacy-hook-compat.js +35 -0
  358. package/dist/legacy-hook-compat.js.map +1 -0
  359. package/dist/lifecycle.d.ts +52 -0
  360. package/dist/lifecycle.js +21 -0
  361. package/dist/lifecycle.js.map +1 -0
  362. package/dist/local-llm.d.ts +154 -0
  363. package/dist/local-llm.js +10 -0
  364. package/dist/local-llm.js.map +1 -0
  365. package/dist/logger.d.ts +15 -0
  366. package/dist/logger.js +9 -0
  367. package/dist/logger.js.map +1 -0
  368. package/dist/memory-action-policy.d.ts +13 -0
  369. package/dist/memory-action-policy.js +7 -0
  370. package/dist/memory-action-policy.js.map +1 -0
  371. package/dist/memory-cache.d.ts +35 -0
  372. package/dist/memory-cache.js +37 -0
  373. package/dist/memory-cache.js.map +1 -0
  374. package/dist/memory-lifecycle-ledger-utils.d.ts +13 -0
  375. package/dist/memory-lifecycle-ledger-utils.js +23 -0
  376. package/dist/memory-lifecycle-ledger-utils.js.map +1 -0
  377. package/dist/memory-projection-format.d.ts +4 -0
  378. package/dist/memory-projection-format.js +9 -0
  379. package/dist/memory-projection-format.js.map +1 -0
  380. package/dist/memory-projection-store-NxMkbocT.d.ts +221 -0
  381. package/dist/memory-projection-store.d.ts +3 -0
  382. package/dist/memory-projection-store.js +31 -0
  383. package/dist/memory-projection-store.js.map +1 -0
  384. package/dist/model-registry.d.ts +60 -0
  385. package/dist/model-registry.js +8 -0
  386. package/dist/model-registry.js.map +1 -0
  387. package/dist/native-knowledge.d.ts +94 -0
  388. package/dist/native-knowledge.js +26 -0
  389. package/dist/native-knowledge.js.map +1 -0
  390. package/dist/negative.d.ts +26 -0
  391. package/dist/negative.js +8 -0
  392. package/dist/negative.js.map +1 -0
  393. package/dist/objective-state-writers.d.ts +22 -0
  394. package/dist/objective-state-writers.js +313 -0
  395. package/dist/objective-state-writers.js.map +1 -0
  396. package/dist/objective-state.d.ts +75 -0
  397. package/dist/objective-state.js +17 -0
  398. package/dist/objective-state.js.map +1 -0
  399. package/dist/openai-chat-compat.d.ts +13 -0
  400. package/dist/openai-chat-compat.js +11 -0
  401. package/dist/openai-chat-compat.js.map +1 -0
  402. package/dist/operator-toolkit.d.ts +304 -0
  403. package/dist/operator-toolkit.js +41 -0
  404. package/dist/operator-toolkit.js.map +1 -0
  405. package/dist/opik-exporter.d.ts +72 -0
  406. package/dist/opik-exporter.js +361 -0
  407. package/dist/opik-exporter.js.map +1 -0
  408. package/dist/orchestrator-zTa-Qo-1.d.ts +1104 -0
  409. package/dist/orchestrator.d.ts +21 -0
  410. package/dist/orchestrator.js +145 -0
  411. package/dist/orchestrator.js.map +1 -0
  412. package/dist/policy-runtime.d.ts +37 -0
  413. package/dist/policy-runtime.js +13 -0
  414. package/dist/policy-runtime.js.map +1 -0
  415. package/dist/port-C1GZFv8h.d.ts +41 -0
  416. package/dist/profiling.d.ts +80 -0
  417. package/dist/profiling.js +10 -0
  418. package/dist/profiling.js.map +1 -0
  419. package/dist/qmd-recall-cache.d.ts +29 -0
  420. package/dist/qmd-recall-cache.js +13 -0
  421. package/dist/qmd-recall-cache.js.map +1 -0
  422. package/dist/qmd.d.ts +105 -0
  423. package/dist/qmd.js +13 -0
  424. package/dist/qmd.js.map +1 -0
  425. package/dist/recall-qos.d.ts +33 -0
  426. package/dist/recall-qos.js +10 -0
  427. package/dist/recall-qos.js.map +1 -0
  428. package/dist/recall-query-policy.d.ts +20 -0
  429. package/dist/recall-query-policy.js +11 -0
  430. package/dist/recall-query-policy.js.map +1 -0
  431. package/dist/recall-state.d.ts +113 -0
  432. package/dist/recall-state.js +12 -0
  433. package/dist/recall-state.js.map +1 -0
  434. package/dist/recall-tokenization.d.ts +4 -0
  435. package/dist/recall-tokenization.js +9 -0
  436. package/dist/recall-tokenization.js.map +1 -0
  437. package/dist/reconstruct.d.ts +16 -0
  438. package/dist/reconstruct.js +7 -0
  439. package/dist/reconstruct.js.map +1 -0
  440. package/dist/release-changelog.d.ts +7 -0
  441. package/dist/release-changelog.js +30 -0
  442. package/dist/release-changelog.js.map +1 -0
  443. package/dist/relevance.d.ts +18 -0
  444. package/dist/relevance.js +8 -0
  445. package/dist/relevance.js.map +1 -0
  446. package/dist/rerank.d.ts +57 -0
  447. package/dist/rerank.js +11 -0
  448. package/dist/rerank.js.map +1 -0
  449. package/dist/resolve-provider-secret.d.ts +16 -0
  450. package/dist/resolve-provider-secret.js +11 -0
  451. package/dist/resolve-provider-secret.js.map +1 -0
  452. package/dist/resume-bundles.d.ts +66 -0
  453. package/dist/resume-bundles.js +27 -0
  454. package/dist/resume-bundles.js.map +1 -0
  455. package/dist/retrieval-agents.d.ts +129 -0
  456. package/dist/retrieval-agents.js +23 -0
  457. package/dist/retrieval-agents.js.map +1 -0
  458. package/dist/retrieval.d.ts +19 -0
  459. package/dist/retrieval.js +10 -0
  460. package/dist/retrieval.js.map +1 -0
  461. package/dist/sanitize.d.ts +9 -0
  462. package/dist/sanitize.js +9 -0
  463. package/dist/sanitize.js.map +1 -0
  464. package/dist/schemas.d.ts +688 -0
  465. package/dist/schemas.js +51 -0
  466. package/dist/schemas.js.map +1 -0
  467. package/dist/sdk-compat.d.ts +21 -0
  468. package/dist/sdk-compat.js +28 -0
  469. package/dist/sdk-compat.js.map +1 -0
  470. package/dist/semantic-consolidation.d.ts +42 -0
  471. package/dist/semantic-consolidation.js +12 -0
  472. package/dist/semantic-consolidation.js.map +1 -0
  473. package/dist/semantic-rule-promotion.d.ts +28 -0
  474. package/dist/semantic-rule-promotion.js +17 -0
  475. package/dist/semantic-rule-promotion.js.map +1 -0
  476. package/dist/semantic-rule-verifier.d.ts +19 -0
  477. package/dist/semantic-rule-verifier.js +18 -0
  478. package/dist/semantic-rule-verifier.js.map +1 -0
  479. package/dist/session-integrity.d.ts +67 -0
  480. package/dist/session-integrity.js +11 -0
  481. package/dist/session-integrity.js.map +1 -0
  482. package/dist/session-observer-bands.d.ts +6 -0
  483. package/dist/session-observer-bands.js +9 -0
  484. package/dist/session-observer-bands.js.map +1 -0
  485. package/dist/session-observer-state.d.ts +40 -0
  486. package/dist/session-observer-state.js +11 -0
  487. package/dist/session-observer-state.js.map +1 -0
  488. package/dist/signal.d.ts +6 -0
  489. package/dist/signal.js +9 -0
  490. package/dist/signal.js.map +1 -0
  491. package/dist/storage.d.ts +453 -0
  492. package/dist/storage.js +24 -0
  493. package/dist/storage.js.map +1 -0
  494. package/dist/store-contract.d.ts +10 -0
  495. package/dist/store-contract.js +21 -0
  496. package/dist/store-contract.js.map +1 -0
  497. package/dist/summarizer.d.ts +35 -0
  498. package/dist/summarizer.js +17 -0
  499. package/dist/summarizer.js.map +1 -0
  500. package/dist/summary-snapshot.d.ts +8 -0
  501. package/dist/summary-snapshot.js +13 -0
  502. package/dist/summary-snapshot.js.map +1 -0
  503. package/dist/temporal-index.d.ts +139 -0
  504. package/dist/temporal-index.js +29 -0
  505. package/dist/temporal-index.js.map +1 -0
  506. package/dist/threading.d.ts +62 -0
  507. package/dist/threading.js +8 -0
  508. package/dist/threading.js.map +1 -0
  509. package/dist/tier-migration.d.ts +44 -0
  510. package/dist/tier-migration.js +7 -0
  511. package/dist/tier-migration.js.map +1 -0
  512. package/dist/tier-routing.d.ts +21 -0
  513. package/dist/tier-routing.js +10 -0
  514. package/dist/tier-routing.js.map +1 -0
  515. package/dist/tmt.d.ts +79 -0
  516. package/dist/tmt.js +29 -0
  517. package/dist/tmt.js.map +1 -0
  518. package/dist/tokens.d.ts +24 -0
  519. package/dist/tokens.js +21 -0
  520. package/dist/tokens.js.map +1 -0
  521. package/dist/topics.d.ts +29 -0
  522. package/dist/topics.js +9 -0
  523. package/dist/topics.js.map +1 -0
  524. package/dist/transcript.d.ts +171 -0
  525. package/dist/transcript.js +9 -0
  526. package/dist/transcript.js.map +1 -0
  527. package/dist/trust-zones.d.ts +170 -0
  528. package/dist/trust-zones.js +32 -0
  529. package/dist/trust-zones.js.map +1 -0
  530. package/dist/types.d.ts +1243 -0
  531. package/dist/types.js +9 -0
  532. package/dist/types.js.map +1 -0
  533. package/dist/utility-learner.d.ts +59 -0
  534. package/dist/utility-learner.js +17 -0
  535. package/dist/utility-learner.js.map +1 -0
  536. package/dist/utility-runtime.d.ts +21 -0
  537. package/dist/utility-runtime.js +16 -0
  538. package/dist/utility-runtime.js.map +1 -0
  539. package/dist/utility-telemetry.d.ts +68 -0
  540. package/dist/utility-telemetry.js +17 -0
  541. package/dist/utility-telemetry.js.map +1 -0
  542. package/dist/verified-recall.d.ts +17 -0
  543. package/dist/verified-recall.js +19 -0
  544. package/dist/verified-recall.js.map +1 -0
  545. package/dist/version-utils.d.ts +4 -0
  546. package/dist/version-utils.js +7 -0
  547. package/dist/version-utils.js.map +1 -0
  548. package/dist/work-product-ledger.d.ts +65 -0
  549. package/dist/work-product-ledger.js +18 -0
  550. package/dist/work-product-ledger.js.map +1 -0
  551. package/package.json +58 -0
@@ -0,0 +1,1886 @@
1
+ import {
2
+ QmdClient
3
+ } from "./chunk-TVVVQQAK.js";
4
+ import {
5
+ launchProcess
6
+ } from "./chunk-LK6SGL53.js";
7
+ import {
8
+ StorageManager
9
+ } from "./chunk-QWUUMMIK.js";
10
+ import {
11
+ isSafeRouteNamespace
12
+ } from "./chunk-HLXVTBF3.js";
13
+ import {
14
+ log
15
+ } from "./chunk-KWBU5S5U.js";
16
+
17
+ // src/search/noop-backend.ts
18
+ var NoopSearchBackend = class {
19
+ async probe() {
20
+ return false;
21
+ }
22
+ isAvailable() {
23
+ return false;
24
+ }
25
+ debugStatus() {
26
+ return "backend=noop";
27
+ }
28
+ async search(_query, _collection, _maxResults, _options, _execution) {
29
+ return [];
30
+ }
31
+ async searchGlobal(_query, _maxResults, _execution) {
32
+ return [];
33
+ }
34
+ async bm25Search(_query, _collection, _maxResults, _execution) {
35
+ return [];
36
+ }
37
+ async vectorSearch(_query, _collection, _maxResults, _execution) {
38
+ return [];
39
+ }
40
+ async hybridSearch(_query, _collection, _maxResults, _execution) {
41
+ return [];
42
+ }
43
+ async update() {
44
+ }
45
+ async updateCollection(_collection) {
46
+ }
47
+ async embed() {
48
+ }
49
+ async embedCollection(_collection) {
50
+ }
51
+ async ensureCollection(_memoryDir) {
52
+ return "skipped";
53
+ }
54
+ };
55
+
56
+ // src/search/document-scanner.ts
57
+ import path from "path";
58
+ import { readdir, readFile } from "fs/promises";
59
+ function parseFrontmatter(raw) {
60
+ const normalized = raw.replace(/\r\n/g, "\n");
61
+ const match = normalized.match(/^---\n([\s\S]*?)\n---\n?([\s\S]*)$/);
62
+ if (!match) return null;
63
+ const fmBlock = match[1];
64
+ const body = (match[2] ?? "").trim();
65
+ const data = {};
66
+ for (const line of fmBlock.split("\n")) {
67
+ const colonIdx = line.indexOf(":");
68
+ if (colonIdx === -1) continue;
69
+ const key = line.slice(0, colonIdx).trim();
70
+ const value = line.slice(colonIdx + 1).trim();
71
+ data[key] = value;
72
+ }
73
+ return { data, body };
74
+ }
75
+ async function scanDir(dir) {
76
+ const docs = [];
77
+ try {
78
+ const entries = await readdir(dir, { withFileTypes: true });
79
+ for (const entry of entries) {
80
+ const fullPath = path.join(dir, entry.name);
81
+ if (entry.isDirectory()) {
82
+ const sub = await scanDir(fullPath);
83
+ docs.push(...sub);
84
+ } else if (entry.name.endsWith(".md")) {
85
+ try {
86
+ const raw = await readFile(fullPath, "utf-8");
87
+ const parsed = parseFrontmatter(raw);
88
+ const body = parsed ? parsed.body : raw.trim();
89
+ const docid = parsed?.data.id || path.basename(entry.name, ".md");
90
+ docs.push({
91
+ docid,
92
+ path: fullPath,
93
+ content: body,
94
+ snippet: body.slice(0, 200)
95
+ });
96
+ } catch {
97
+ }
98
+ }
99
+ }
100
+ } catch {
101
+ }
102
+ return docs;
103
+ }
104
+ async function scanMemoryDir(memoryDir) {
105
+ const factsDir = path.join(memoryDir, "facts");
106
+ const correctionsDir = path.join(memoryDir, "corrections");
107
+ const [facts, corrections] = await Promise.all([scanDir(factsDir), scanDir(correctionsDir)]);
108
+ return [...facts, ...corrections];
109
+ }
110
+
111
+ // src/search/lancedb-backend.ts
112
+ var LanceDbBackend = class {
113
+ dbPath;
114
+ collection;
115
+ embedHelper;
116
+ memoryDir;
117
+ embeddingDimension;
118
+ available = false;
119
+ db = null;
120
+ lanceModule = null;
121
+ constructor(opts) {
122
+ this.dbPath = opts.dbPath;
123
+ this.collection = opts.collection;
124
+ this.embedHelper = opts.embedHelper;
125
+ this.memoryDir = opts.memoryDir;
126
+ this.embeddingDimension = opts.embeddingDimension;
127
+ }
128
+ async probe() {
129
+ try {
130
+ await this.ensureDb();
131
+ this.available = true;
132
+ return true;
133
+ } catch (err) {
134
+ log.debug(`LanceDbBackend probe failed: ${err}`);
135
+ this.available = false;
136
+ return false;
137
+ }
138
+ }
139
+ isAvailable() {
140
+ return this.available;
141
+ }
142
+ debugStatus() {
143
+ return `backend=lancedb available=${this.available} dbPath=${this.dbPath}`;
144
+ }
145
+ async search(query, _collection, maxResults, _options, _execution) {
146
+ return this.hybridSearch(query, _collection, maxResults);
147
+ }
148
+ async searchGlobal(query, maxResults, _execution) {
149
+ const limit = maxResults ?? 10;
150
+ if (!this.available) return [];
151
+ try {
152
+ const db = await this.ensureDb();
153
+ const tableNames = await db.tableNames();
154
+ const allResults = [];
155
+ for (const name of tableNames) {
156
+ try {
157
+ const table = await db.openTable(name);
158
+ const results = await this.searchTable(table, query, "hybrid", limit);
159
+ allResults.push(...results);
160
+ } catch {
161
+ }
162
+ }
163
+ allResults.sort((a, b) => b.score - a.score);
164
+ return allResults.slice(0, limit);
165
+ } catch (err) {
166
+ log.debug(`LanceDbBackend searchGlobal failed: ${err}`);
167
+ return [];
168
+ }
169
+ }
170
+ async bm25Search(query, collection, maxResults, _execution) {
171
+ const table = await this.ensureTableForCollection(collection ?? this.collection);
172
+ if (!table) return [];
173
+ return this.searchTable(table, query, "fts", maxResults ?? 10);
174
+ }
175
+ async vectorSearch(query, collection, maxResults, _execution) {
176
+ const table = await this.ensureTableForCollection(collection ?? this.collection);
177
+ if (!table) return [];
178
+ return this.searchTable(table, query, "vector", maxResults ?? 10);
179
+ }
180
+ async hybridSearch(query, collection, maxResults, _execution) {
181
+ const table = await this.ensureTableForCollection(collection ?? this.collection);
182
+ if (!table) return [];
183
+ return this.searchTable(table, query, "hybrid", maxResults ?? 10);
184
+ }
185
+ async update() {
186
+ await this.updateCollection(this.collection);
187
+ }
188
+ async updateCollection(collection) {
189
+ const table = await this.ensureTableForCollection(collection);
190
+ if (!table) return;
191
+ const docs = await scanMemoryDir(this.memoryDir);
192
+ if (docs.length === 0) {
193
+ try {
194
+ const db = await this.ensureDb();
195
+ await db.dropTable(collection).catch(() => {
196
+ });
197
+ if (collection === this.collection) this.table = null;
198
+ } catch {
199
+ }
200
+ return;
201
+ }
202
+ const rows = docs.map((d) => ({
203
+ docid: d.docid,
204
+ path: d.path,
205
+ content: d.content,
206
+ snippet: d.snippet,
207
+ vector: new Array(this.embeddingDimension).fill(0)
208
+ }));
209
+ try {
210
+ const db = await this.ensureDb();
211
+ await db.dropTable(collection).catch(() => {
212
+ });
213
+ if (collection === this.collection) this.table = null;
214
+ const newTable = await db.createTable(collection, rows);
215
+ try {
216
+ await newTable.createIndex("content", { config: this.lanceIndex.fts() });
217
+ } catch {
218
+ }
219
+ if (collection === this.collection) this.table = newTable;
220
+ } catch (err) {
221
+ log.debug(`LanceDbBackend update failed: ${err}`);
222
+ }
223
+ }
224
+ async embed() {
225
+ await this.embedCollection(this.collection);
226
+ }
227
+ async embedCollection(collection) {
228
+ if (!this.embedHelper.isAvailable()) return;
229
+ const table = await this.ensureTableForCollection(collection);
230
+ if (!table) return;
231
+ try {
232
+ const allRows = await table.query().select(["docid", "content", "vector"]).toArray();
233
+ const needsEmbed = allRows.filter((row) => {
234
+ const vec = row.vector;
235
+ if (!vec || typeof vec !== "object") return true;
236
+ const arr = Array.from(vec);
237
+ return arr.length === 0 || arr.every((v) => v === 0);
238
+ });
239
+ if (needsEmbed.length === 0) return;
240
+ const texts = needsEmbed.map((row) => row.content);
241
+ const vectors = await this.embedHelper.embedBatch(texts);
242
+ for (let i = 0; i < needsEmbed.length; i++) {
243
+ const vec = vectors[i];
244
+ if (!vec) continue;
245
+ const docid = needsEmbed[i].docid;
246
+ await table.update({ where: `docid = '${docid.replace(/'/g, "''")}'`, values: { vector: vec } });
247
+ }
248
+ } catch (err) {
249
+ log.debug(`LanceDbBackend embed failed: ${err}`);
250
+ }
251
+ }
252
+ async ensureCollection(_memoryDir) {
253
+ try {
254
+ await this.ensureTable();
255
+ return "present";
256
+ } catch {
257
+ return "missing";
258
+ }
259
+ }
260
+ table = null;
261
+ get lanceIndex() {
262
+ return this.lanceModule.Index ?? this.lanceModule.default?.Index;
263
+ }
264
+ async ensureDb() {
265
+ if (this.db) return this.db;
266
+ if (!this.lanceModule) {
267
+ this.lanceModule = await import("@lancedb/lancedb");
268
+ }
269
+ const connect = this.lanceModule.connect ?? this.lanceModule.default?.connect;
270
+ this.db = await connect(this.dbPath);
271
+ return this.db;
272
+ }
273
+ async ensureTableForCollection(collection) {
274
+ if (collection === this.collection) return this.ensureTable();
275
+ const db = await this.ensureDb();
276
+ const tables = await db.tableNames();
277
+ if (tables.includes(collection)) {
278
+ return await db.openTable(collection);
279
+ }
280
+ const emptyRow = {
281
+ docid: "__placeholder__",
282
+ path: "",
283
+ content: "",
284
+ snippet: "",
285
+ vector: new Array(this.embeddingDimension).fill(0)
286
+ };
287
+ const newTable = await db.createTable(collection, [emptyRow]);
288
+ try {
289
+ await newTable.createIndex("content", { config: this.lanceIndex.fts() });
290
+ } catch {
291
+ }
292
+ try {
293
+ await newTable.delete("docid = '__placeholder__'");
294
+ } catch {
295
+ }
296
+ return newTable;
297
+ }
298
+ async ensureTable() {
299
+ if (this.table) return this.table;
300
+ const db = await this.ensureDb();
301
+ const tables = await db.tableNames();
302
+ if (tables.includes(this.collection)) {
303
+ this.table = await db.openTable(this.collection);
304
+ return this.table;
305
+ }
306
+ const emptyRow = {
307
+ docid: "__placeholder__",
308
+ path: "",
309
+ content: "",
310
+ snippet: "",
311
+ vector: new Array(this.embeddingDimension).fill(0)
312
+ };
313
+ this.table = await db.createTable(this.collection, [emptyRow]);
314
+ try {
315
+ await this.table.createIndex("content", { config: this.lanceIndex.fts() });
316
+ } catch {
317
+ }
318
+ try {
319
+ await this.table.delete("docid = '__placeholder__'");
320
+ } catch {
321
+ }
322
+ return this.table;
323
+ }
324
+ async searchTable(table, query, mode, limit) {
325
+ try {
326
+ if (mode === "fts") {
327
+ const results = await table.search(query, "fts").limit(limit).toArray();
328
+ return this.mapRows(results);
329
+ }
330
+ if (mode === "vector") {
331
+ const vec2 = await this.embedHelper.embed(query);
332
+ if (!vec2) {
333
+ const results2 = await table.search(query, "fts").limit(limit).toArray();
334
+ return this.mapRows(results2);
335
+ }
336
+ const results = await table.search(vec2).limit(limit).toArray();
337
+ return this.mapRows(results);
338
+ }
339
+ const vec = await this.embedHelper.embed(query);
340
+ if (!vec) {
341
+ const results = await table.search(query, "fts").limit(limit).toArray();
342
+ return this.mapRows(results);
343
+ }
344
+ try {
345
+ const results = await table.search(query, "hybrid").vector(vec).limit(limit).toArray();
346
+ return this.mapRows(results);
347
+ } catch {
348
+ const results = await table.search(vec).limit(limit).toArray();
349
+ return this.mapRows(results);
350
+ }
351
+ } catch (err) {
352
+ log.debug(`LanceDbBackend search (${mode}) failed: ${err}`);
353
+ return [];
354
+ }
355
+ }
356
+ mapRows(rows) {
357
+ return (rows ?? []).filter((row) => row.docid && row.docid !== "__placeholder__").map((row) => ({
358
+ docid: row.docid ?? "",
359
+ path: row.path ?? "",
360
+ snippet: row.snippet ?? row.content?.slice(0, 200) ?? "",
361
+ score: row._relevance_score ?? (row._distance != null ? 1 / (1 + (row._distance ?? 0)) : 0.5)
362
+ }));
363
+ }
364
+ };
365
+
366
+ // src/search/meilisearch-backend.ts
367
+ var MeilisearchBackend = class {
368
+ host;
369
+ apiKey;
370
+ collection;
371
+ timeoutMs;
372
+ autoIndex;
373
+ memoryDir;
374
+ available = false;
375
+ client = null;
376
+ meiliModule = null;
377
+ constructor(opts) {
378
+ this.host = opts.host;
379
+ this.apiKey = opts.apiKey;
380
+ this.collection = opts.collection;
381
+ this.timeoutMs = opts.timeoutMs ?? 3e4;
382
+ this.autoIndex = opts.autoIndex ?? false;
383
+ this.memoryDir = opts.memoryDir;
384
+ }
385
+ async probe() {
386
+ try {
387
+ const client = await this.ensureClient();
388
+ await client.health();
389
+ this.available = true;
390
+ return true;
391
+ } catch (err) {
392
+ log.debug(`MeilisearchBackend probe failed: ${err}`);
393
+ this.available = false;
394
+ return false;
395
+ }
396
+ }
397
+ isAvailable() {
398
+ return this.available;
399
+ }
400
+ debugStatus() {
401
+ return `backend=meilisearch available=${this.available} host=${this.host}`;
402
+ }
403
+ async search(query, collection, maxResults, _options, _execution) {
404
+ try {
405
+ return await this.doSearch(query, maxResults ?? 10, { hybrid: { semanticRatio: 0.5, embedder: "default" } }, collection, true);
406
+ } catch {
407
+ return this.bm25Search(query, collection, maxResults);
408
+ }
409
+ }
410
+ async searchGlobal(query, maxResults, _execution) {
411
+ const limit = maxResults ?? 10;
412
+ if (!this.available) return [];
413
+ try {
414
+ const client = await this.ensureClient();
415
+ const indexes = await client.getIndexes();
416
+ const queries = (indexes.results ?? []).map((idx) => ({
417
+ indexUid: idx.uid,
418
+ q: query,
419
+ limit,
420
+ showRankingScore: true
421
+ }));
422
+ if (queries.length === 0) return [];
423
+ const multiResult = await client.multiSearch({ queries });
424
+ const allResults = [];
425
+ for (const result of multiResult.results ?? []) {
426
+ allResults.push(...this.mapHits(result.hits ?? []));
427
+ }
428
+ allResults.sort((a, b) => b.score - a.score);
429
+ return allResults.slice(0, limit);
430
+ } catch (err) {
431
+ log.debug(`MeilisearchBackend searchGlobal failed: ${err}`);
432
+ return [];
433
+ }
434
+ }
435
+ async bm25Search(query, collection, maxResults, _execution) {
436
+ return this.doSearch(query, maxResults ?? 10, void 0, collection);
437
+ }
438
+ async vectorSearch(query, collection, maxResults, _execution) {
439
+ return this.doSearch(query, maxResults ?? 10, { hybrid: { semanticRatio: 1, embedder: "default" } }, collection);
440
+ }
441
+ async hybridSearch(query, collection, maxResults, _execution) {
442
+ return this.doSearch(query, maxResults ?? 10, { hybrid: { semanticRatio: 0.5, embedder: "default" } }, collection);
443
+ }
444
+ async update() {
445
+ await this.updateCollection(this.collection);
446
+ }
447
+ async updateCollection(collection) {
448
+ if (!this.autoIndex || !this.memoryDir) return;
449
+ if (!this.available) return;
450
+ try {
451
+ const client = await this.ensureClient();
452
+ const docs = await scanMemoryDir(this.memoryDir);
453
+ const index = client.index(collection);
454
+ const meilDocs = docs.map((d) => ({
455
+ id: d.docid,
456
+ path: d.path,
457
+ content: d.content,
458
+ snippet: d.snippet
459
+ }));
460
+ const addTask = await index.addDocuments(meilDocs, { primaryKey: "id" });
461
+ await client.waitForTask(addTask.taskUid, { timeOutMs: this.timeoutMs });
462
+ const currentIds = new Set(docs.map((d) => d.docid));
463
+ try {
464
+ const PAGE_SIZE = 1e3;
465
+ let offset = 0;
466
+ let staleIds = [];
467
+ let hasMore = true;
468
+ while (hasMore) {
469
+ const page = await index.getDocuments({ limit: PAGE_SIZE, offset, fields: ["id"] });
470
+ const results = page.results ?? [];
471
+ for (const doc of results) {
472
+ const id = doc.id;
473
+ if (!currentIds.has(id)) staleIds.push(id);
474
+ }
475
+ offset += results.length;
476
+ hasMore = results.length === PAGE_SIZE;
477
+ }
478
+ if (staleIds.length > 0) {
479
+ const delTask = await index.deleteDocuments(staleIds);
480
+ await client.waitForTask(delTask.taskUid, { timeOutMs: this.timeoutMs });
481
+ }
482
+ } catch {
483
+ }
484
+ } catch (err) {
485
+ log.debug(`MeilisearchBackend update failed: ${err}`);
486
+ }
487
+ }
488
+ async embed() {
489
+ }
490
+ async embedCollection(collection) {
491
+ }
492
+ async ensureCollection(_memoryDir) {
493
+ if (!this.available) return "skipped";
494
+ try {
495
+ const client = await this.ensureClient();
496
+ try {
497
+ await client.getIndex(this.collection);
498
+ return "present";
499
+ } catch {
500
+ await client.createIndex(this.collection, { primaryKey: "id" });
501
+ return "present";
502
+ }
503
+ } catch {
504
+ return "skipped";
505
+ }
506
+ }
507
+ async ensureClient() {
508
+ if (this.client) return this.client;
509
+ if (!this.meiliModule) {
510
+ this.meiliModule = await import("meilisearch");
511
+ }
512
+ const MeiliSearch = this.meiliModule.MeiliSearch ?? this.meiliModule.default?.MeiliSearch;
513
+ this.client = new MeiliSearch({
514
+ host: this.host,
515
+ apiKey: this.apiKey,
516
+ timeout: this.timeoutMs
517
+ });
518
+ return this.client;
519
+ }
520
+ async doSearch(query, limit, extra, collection, rethrow = false) {
521
+ if (!this.available) return [];
522
+ try {
523
+ const client = await this.ensureClient();
524
+ const index = client.index(collection ?? this.collection);
525
+ const result = await index.search(query, { limit, showRankingScore: true, ...extra });
526
+ return this.mapHits(result.hits ?? []);
527
+ } catch (err) {
528
+ log.debug(`MeilisearchBackend search failed: ${err}`);
529
+ if (rethrow) throw err;
530
+ return [];
531
+ }
532
+ }
533
+ mapHits(hits) {
534
+ return hits.map((hit) => ({
535
+ docid: hit.id ?? "",
536
+ path: hit.path ?? "",
537
+ snippet: hit._formatted?.content ?? hit.snippet ?? hit.content?.slice(0, 200) ?? "",
538
+ score: hit._rankingScore ?? 0.5
539
+ }));
540
+ }
541
+ };
542
+
543
+ // src/search/orama-backend.ts
544
+ import path2 from "path";
545
+ import { mkdir, readdir as readdir2, readFile as readFile2, writeFile } from "fs/promises";
546
+ var OramaBackend = class {
547
+ dbPath;
548
+ collection;
549
+ embedHelper;
550
+ memoryDir;
551
+ embeddingDimension;
552
+ available = false;
553
+ db = null;
554
+ oramaModule = null;
555
+ persistModule = null;
556
+ constructor(opts) {
557
+ this.dbPath = opts.dbPath;
558
+ this.collection = opts.collection;
559
+ this.embedHelper = opts.embedHelper;
560
+ this.memoryDir = opts.memoryDir;
561
+ this.embeddingDimension = opts.embeddingDimension;
562
+ }
563
+ async probe() {
564
+ try {
565
+ await this.ensureModules();
566
+ await this.ensureDb();
567
+ this.available = true;
568
+ return true;
569
+ } catch (err) {
570
+ log.debug(`OramaBackend probe failed: ${err}`);
571
+ this.available = false;
572
+ return false;
573
+ }
574
+ }
575
+ isAvailable() {
576
+ return this.available;
577
+ }
578
+ debugStatus() {
579
+ return `backend=orama available=${this.available} dbPath=${this.dbPath}`;
580
+ }
581
+ async search(query, _collection, maxResults, _options, _execution) {
582
+ return this.hybridSearch(query, _collection, maxResults);
583
+ }
584
+ async searchGlobal(query, maxResults, _execution) {
585
+ const limit = maxResults ?? 10;
586
+ if (!this.available) return [];
587
+ try {
588
+ const files = await this.listDbFiles();
589
+ const allResults = [];
590
+ for (const file of files) {
591
+ const db = await this.loadDbFromFile(file);
592
+ if (!db) continue;
593
+ const results = await this.searchDb(db, query, "hybrid", limit);
594
+ allResults.push(...results);
595
+ }
596
+ allResults.sort((a, b) => b.score - a.score);
597
+ return allResults.slice(0, limit);
598
+ } catch (err) {
599
+ log.debug(`OramaBackend searchGlobal failed: ${err}`);
600
+ return [];
601
+ }
602
+ }
603
+ async bm25Search(query, collection, maxResults, _execution) {
604
+ const db = await this.ensureDbForCollection(collection ?? this.collection);
605
+ if (!db) return [];
606
+ return this.searchDb(db, query, "fulltext", maxResults ?? 10);
607
+ }
608
+ async vectorSearch(query, collection, maxResults, _execution) {
609
+ const db = await this.ensureDbForCollection(collection ?? this.collection);
610
+ if (!db) return [];
611
+ return this.searchDb(db, query, "vector", maxResults ?? 10);
612
+ }
613
+ async hybridSearch(query, collection, maxResults, _execution) {
614
+ const db = await this.ensureDbForCollection(collection ?? this.collection);
615
+ if (!db) return [];
616
+ return this.searchDb(db, query, "hybrid", maxResults ?? 10);
617
+ }
618
+ async update() {
619
+ await this.updateCollection(this.collection);
620
+ }
621
+ async updateCollection(collection) {
622
+ const db = await this.ensureDbForCollection(collection);
623
+ if (!db) return;
624
+ const { search: oramaSearch, insert, remove, count } = this.oramaModule;
625
+ const docs = await scanMemoryDir(this.memoryDir);
626
+ const docMap = new Map(docs.map((d) => [d.docid, d]));
627
+ const { update: oramaUpdate } = this.oramaModule;
628
+ const existingDocs = /* @__PURE__ */ new Map();
629
+ const existingCount = await count(db);
630
+ if (existingCount > 0) {
631
+ const allHits = await oramaSearch(db, { term: "", limit: existingCount + 100 });
632
+ for (const hit of allHits.hits) {
633
+ if (!docMap.has(hit.document.id)) {
634
+ await remove(db, hit.id);
635
+ } else {
636
+ existingDocs.set(hit.document.id, {
637
+ internalId: hit.id,
638
+ vector: hit.document.vector
639
+ });
640
+ }
641
+ }
642
+ }
643
+ for (const doc of docs) {
644
+ const existing = existingDocs.get(doc.docid);
645
+ if (existing) {
646
+ const payload = {
647
+ id: doc.docid,
648
+ path: doc.path,
649
+ content: doc.content,
650
+ snippet: doc.snippet
651
+ };
652
+ if (existing.vector && existing.vector.length > 0) {
653
+ payload.vector = existing.vector;
654
+ }
655
+ try {
656
+ await oramaUpdate(db, existing.internalId, payload);
657
+ } catch {
658
+ }
659
+ } else {
660
+ try {
661
+ await insert(db, {
662
+ id: doc.docid,
663
+ path: doc.path,
664
+ content: doc.content,
665
+ snippet: doc.snippet
666
+ });
667
+ } catch {
668
+ }
669
+ }
670
+ }
671
+ await this.persistDbForCollection(db, collection);
672
+ }
673
+ async embed() {
674
+ await this.embedCollection(this.collection);
675
+ }
676
+ async embedCollection(collection) {
677
+ if (!this.embedHelper.isAvailable()) return;
678
+ const db = await this.ensureDbForCollection(collection);
679
+ if (!db) return;
680
+ const { search: oramaSearch, update: oramaUpdate, count } = this.oramaModule;
681
+ const existingCount = await count(db);
682
+ if (existingCount === 0) return;
683
+ const allHits = await oramaSearch(db, { term: "", limit: existingCount + 100 });
684
+ const needsEmbed = allHits.hits.filter((h) => !h.document.vector || h.document.vector.length === 0);
685
+ if (needsEmbed.length === 0) return;
686
+ const texts = needsEmbed.map((h) => h.document.content);
687
+ const vectors = await this.embedHelper.embedBatch(texts);
688
+ for (let i = 0; i < needsEmbed.length; i++) {
689
+ const vec = vectors[i];
690
+ if (!vec) continue;
691
+ const doc = needsEmbed[i].document;
692
+ await oramaUpdate(db, needsEmbed[i].id, {
693
+ id: doc.id,
694
+ path: doc.path,
695
+ content: doc.content,
696
+ snippet: doc.snippet,
697
+ vector: vec
698
+ });
699
+ }
700
+ await this.persistDbForCollection(db, collection);
701
+ }
702
+ async ensureCollection(_memoryDir) {
703
+ try {
704
+ await this.ensureModules();
705
+ await this.ensureDb();
706
+ return "present";
707
+ } catch {
708
+ return "missing";
709
+ }
710
+ }
711
+ async ensureModules() {
712
+ if (this.oramaModule && this.persistModule) return;
713
+ this.oramaModule = await import("@orama/orama");
714
+ this.persistModule = await import("@orama/plugin-data-persistence");
715
+ }
716
+ async ensureDb() {
717
+ if (this.db) return this.db;
718
+ await this.ensureModules();
719
+ await mkdir(this.dbPath, { recursive: true });
720
+ const filePath = this.dbFilePath(this.collection);
721
+ try {
722
+ const raw = await readFile2(filePath, "utf-8");
723
+ this.db = await this.persistModule.restore("json", raw);
724
+ return this.db;
725
+ } catch {
726
+ }
727
+ const { create } = this.oramaModule;
728
+ const schema = {
729
+ id: "string",
730
+ path: "string",
731
+ content: "string",
732
+ snippet: "string"
733
+ };
734
+ if (this.embedHelper.isAvailable()) {
735
+ schema.vector = `vector[${this.embeddingDimension}]`;
736
+ }
737
+ this.db = await create({ schema });
738
+ return this.db;
739
+ }
740
+ async ensureDbForCollection(collection) {
741
+ if (collection === this.collection) return this.ensureDb();
742
+ await this.ensureModules();
743
+ await mkdir(this.dbPath, { recursive: true });
744
+ const filePath = this.dbFilePath(collection);
745
+ try {
746
+ const raw = await readFile2(filePath, "utf-8");
747
+ return await this.persistModule.restore("json", raw);
748
+ } catch {
749
+ }
750
+ const { create } = this.oramaModule;
751
+ const schema = {
752
+ id: "string",
753
+ path: "string",
754
+ content: "string",
755
+ snippet: "string"
756
+ };
757
+ if (this.embedHelper.isAvailable()) {
758
+ schema.vector = `vector[${this.embeddingDimension}]`;
759
+ }
760
+ return await create({ schema });
761
+ }
762
+ async persistDbForCollection(db, collection) {
763
+ const data = await this.persistModule.persist(db, "json");
764
+ const filePath = this.dbFilePath(collection);
765
+ await mkdir(path2.dirname(filePath), { recursive: true });
766
+ await writeFile(filePath, data, "utf-8");
767
+ }
768
+ dbFilePath(collection) {
769
+ return path2.join(this.dbPath, `${collection}.msp`);
770
+ }
771
+ async listDbFiles() {
772
+ try {
773
+ const entries = await readdir2(this.dbPath);
774
+ return entries.filter((e) => e.endsWith(".msp")).map((e) => path2.join(this.dbPath, e));
775
+ } catch {
776
+ return [];
777
+ }
778
+ }
779
+ async loadDbFromFile(filePath) {
780
+ try {
781
+ await this.ensureModules();
782
+ const raw = await readFile2(filePath, "utf-8");
783
+ return await this.persistModule.restore("json", raw);
784
+ } catch {
785
+ return null;
786
+ }
787
+ }
788
+ async searchDb(db, query, mode, limit) {
789
+ const { search: oramaSearch } = this.oramaModule;
790
+ try {
791
+ let searchParams;
792
+ if (mode === "fulltext") {
793
+ searchParams = { term: query, limit };
794
+ } else if (mode === "vector") {
795
+ const vec = await this.embedHelper.embed(query);
796
+ if (!vec) {
797
+ searchParams = { term: query, limit };
798
+ } else {
799
+ searchParams = { mode: "vector", vector: { value: vec, property: "vector" }, limit };
800
+ }
801
+ } else {
802
+ const vec = await this.embedHelper.embed(query);
803
+ if (!vec) {
804
+ searchParams = { term: query, limit };
805
+ } else {
806
+ searchParams = { mode: "hybrid", term: query, vector: { value: vec, property: "vector" }, limit };
807
+ }
808
+ }
809
+ const result = await oramaSearch(db, searchParams);
810
+ return (result.hits ?? []).map((hit) => ({
811
+ docid: hit.document?.id ?? "",
812
+ path: hit.document?.path ?? "",
813
+ snippet: hit.document?.snippet ?? hit.document?.content?.slice(0, 200) ?? "",
814
+ score: hit.score ?? 0
815
+ }));
816
+ } catch (err) {
817
+ log.debug(`OramaBackend search (${mode}) failed: ${err}`);
818
+ return [];
819
+ }
820
+ }
821
+ };
822
+
823
+ // src/conversation-index/indexer.ts
824
+ import { mkdir as mkdir2, writeFile as writeFile2 } from "fs/promises";
825
+ import path3 from "path";
826
+ function sanitizeSessionKey(sessionKey) {
827
+ const raw = typeof sessionKey === "string" && sessionKey.trim().length > 0 ? sessionKey : "unknown-session";
828
+ return raw.toLowerCase().replace(/[^a-z0-9._-]+/g, "_").slice(0, 200);
829
+ }
830
+ async function writeConversationChunks(rootDir, chunks) {
831
+ const written = [];
832
+ for (const c of chunks) {
833
+ const safe = sanitizeSessionKey(c.sessionKey);
834
+ const date = c.startTs.slice(0, 10);
835
+ const dir = path3.join(rootDir, safe, date);
836
+ await mkdir2(dir, { recursive: true });
837
+ const fp = path3.join(dir, `${c.id}.md`);
838
+ const content = `---
839
+ kind: conversation_chunk
840
+ sessionKey: ${c.sessionKey}
841
+ startTs: ${c.startTs}
842
+ endTs: ${c.endTs}
843
+ ---
844
+
845
+ ` + c.text + "\n";
846
+ await writeFile2(fp, content, "utf-8");
847
+ written.push(fp);
848
+ }
849
+ return written;
850
+ }
851
+ async function upsertConversationChunksFailOpen(adapter, chunks) {
852
+ if (!adapter) {
853
+ return { upserted: 0, skipped: true, reason: "adapter-unavailable" };
854
+ }
855
+ try {
856
+ const upserted = await adapter.upsertChunks(chunks);
857
+ return { upserted, skipped: false };
858
+ } catch (err) {
859
+ log.debug(`conversation index FAISS upsert failed (fail-open): ${err}`);
860
+ return { upserted: 0, skipped: true, reason: "adapter-error" };
861
+ }
862
+ }
863
+ async function rebuildConversationChunksFailOpen(adapter, chunks) {
864
+ if (!adapter) {
865
+ return { rebuilt: 0, skipped: true, reason: "adapter-unavailable" };
866
+ }
867
+ try {
868
+ const rebuilt = await adapter.rebuildChunks(chunks);
869
+ return { rebuilt, skipped: false };
870
+ } catch (err) {
871
+ log.debug(`conversation index FAISS rebuild failed (fail-open): ${err}`);
872
+ return { rebuilt: 0, skipped: true, reason: "adapter-error" };
873
+ }
874
+ }
875
+
876
+ // src/search/factory.ts
877
+ import path5 from "path";
878
+
879
+ // src/search/remote-backend.ts
880
+ var RemoteSearchBackend = class {
881
+ baseUrl;
882
+ apiKey;
883
+ timeoutMs;
884
+ available = false;
885
+ constructor(opts) {
886
+ let url = opts.baseUrl;
887
+ while (url.endsWith("/")) url = url.slice(0, -1);
888
+ this.baseUrl = url;
889
+ this.apiKey = opts.apiKey;
890
+ this.timeoutMs = opts.timeoutMs ?? 3e4;
891
+ }
892
+ async probe() {
893
+ try {
894
+ const res = await fetch(`${this.baseUrl}/health`, {
895
+ method: "GET",
896
+ headers: this.headers(),
897
+ signal: AbortSignal.timeout(this.timeoutMs)
898
+ });
899
+ this.available = res.ok;
900
+ return this.available;
901
+ } catch (err) {
902
+ log.debug(`RemoteSearchBackend probe failed: ${err}`);
903
+ this.available = false;
904
+ return false;
905
+ }
906
+ }
907
+ isAvailable() {
908
+ return this.available;
909
+ }
910
+ debugStatus() {
911
+ return `backend=remote available=${this.available} baseUrl=${this.baseUrl}`;
912
+ }
913
+ async search(query, collection, maxResults, _options, execution) {
914
+ return this.post("/search/deep", { query, collection, maxResults }, execution);
915
+ }
916
+ async searchGlobal(query, maxResults, execution) {
917
+ return this.post("/search/deep", { query, maxResults }, execution);
918
+ }
919
+ async bm25Search(query, collection, maxResults, execution) {
920
+ return this.post("/search/bm25", { query, collection, maxResults }, execution);
921
+ }
922
+ async vectorSearch(query, collection, maxResults, execution) {
923
+ return this.post("/search/vector", { query, collection, maxResults }, execution);
924
+ }
925
+ async hybridSearch(query, collection, maxResults, execution) {
926
+ return this.post("/search/hybrid", { query, collection, maxResults }, execution);
927
+ }
928
+ async update() {
929
+ }
930
+ async updateCollection(_collection) {
931
+ }
932
+ async embed() {
933
+ }
934
+ async embedCollection(_collection) {
935
+ }
936
+ async ensureCollection(_memoryDir) {
937
+ return "skipped";
938
+ }
939
+ headers() {
940
+ const h = { "Content-Type": "application/json" };
941
+ if (this.apiKey) {
942
+ h["Authorization"] = `Bearer ${this.apiKey}`;
943
+ }
944
+ return h;
945
+ }
946
+ async post(endpoint, body, execution) {
947
+ if (!this.available) return [];
948
+ try {
949
+ const res = await fetch(`${this.baseUrl}${endpoint}`, {
950
+ method: "POST",
951
+ headers: this.headers(),
952
+ body: JSON.stringify(body),
953
+ signal: execution?.signal ? AbortSignal.any([execution.signal, AbortSignal.timeout(this.timeoutMs)]) : AbortSignal.timeout(this.timeoutMs)
954
+ });
955
+ if (!res.ok) {
956
+ log.debug(`RemoteSearchBackend ${endpoint} returned ${res.status}`);
957
+ return [];
958
+ }
959
+ const data = await res.json();
960
+ if (!Array.isArray(data)) return [];
961
+ return data;
962
+ } catch (err) {
963
+ log.debug(`RemoteSearchBackend ${endpoint} failed: ${err}`);
964
+ return [];
965
+ }
966
+ }
967
+ };
968
+
969
+ // src/search/embed-helper.ts
970
+ var DEFAULT_OPENAI_MODEL = "text-embedding-3-small";
971
+ var EmbedHelper = class {
972
+ // undefined = not yet resolved
973
+ constructor(config) {
974
+ this.config = config;
975
+ }
976
+ config;
977
+ provider;
978
+ /**
979
+ * Whether an embedding provider is available.
980
+ * Resolves the provider on first call.
981
+ */
982
+ isAvailable() {
983
+ if (this.provider === void 0) {
984
+ this.provider = this.resolveProvider();
985
+ }
986
+ return this.provider !== null;
987
+ }
988
+ /**
989
+ * Embed a single text string. Returns null if no provider is available.
990
+ */
991
+ async embed(text) {
992
+ const provider = this.getProvider();
993
+ if (!provider) return null;
994
+ return this.callEmbed(text, provider);
995
+ }
996
+ /**
997
+ * Embed a batch of texts. Returns an array parallel to input; entries are null on failure.
998
+ */
999
+ async embedBatch(texts, batchSize = 32) {
1000
+ const provider = this.getProvider();
1001
+ if (!provider) return texts.map(() => null);
1002
+ const results = new Array(texts.length).fill(null);
1003
+ for (let i = 0; i < texts.length; i += batchSize) {
1004
+ const batch = texts.slice(i, i + batchSize);
1005
+ const batchResults = await Promise.all(batch.map((t) => this.callEmbed(t, provider)));
1006
+ for (let j = 0; j < batchResults.length; j++) {
1007
+ results[i + j] = batchResults[j];
1008
+ }
1009
+ }
1010
+ return results;
1011
+ }
1012
+ getProvider() {
1013
+ if (this.provider === void 0) {
1014
+ this.provider = this.resolveProvider();
1015
+ }
1016
+ return this.provider;
1017
+ }
1018
+ resolveProvider() {
1019
+ if (!this.config.embeddingFallbackEnabled) return null;
1020
+ const preferred = this.config.embeddingFallbackProvider;
1021
+ const providers = preferred === "auto" ? ["openai", "local"] : [preferred];
1022
+ for (const p of providers) {
1023
+ if (p === "openai" && this.config.openaiApiKey) {
1024
+ const baseUrl = this.config.openaiBaseUrl ?? "https://api.openai.com/v1";
1025
+ return {
1026
+ type: "openai",
1027
+ model: DEFAULT_OPENAI_MODEL,
1028
+ endpoint: `${baseUrl.replace(/\/$/, "")}/embeddings`,
1029
+ headers: {
1030
+ "Content-Type": "application/json",
1031
+ Authorization: `Bearer ${this.config.openaiApiKey}`
1032
+ }
1033
+ };
1034
+ }
1035
+ if (p === "local" && this.config.localLlmEnabled && this.config.localLlmUrl) {
1036
+ const base = this.config.localLlmUrl.replace(/\/$/, "");
1037
+ const endpoint = /\/v1$/i.test(base) ? `${base}/embeddings` : `${base}/v1/embeddings`;
1038
+ const headers = {
1039
+ "Content-Type": "application/json",
1040
+ ...this.config.localLlmHeaders ?? {}
1041
+ };
1042
+ if (this.config.localLlmApiKey && this.config.localLlmAuthHeader !== false) {
1043
+ headers.Authorization = `Bearer ${this.config.localLlmApiKey}`;
1044
+ }
1045
+ return {
1046
+ type: "local",
1047
+ model: this.config.localLlmModel || DEFAULT_OPENAI_MODEL,
1048
+ endpoint,
1049
+ headers
1050
+ };
1051
+ }
1052
+ }
1053
+ return null;
1054
+ }
1055
+ async callEmbed(input, provider) {
1056
+ try {
1057
+ const res = await fetch(provider.endpoint, {
1058
+ method: "POST",
1059
+ headers: provider.headers,
1060
+ body: JSON.stringify({
1061
+ model: provider.model,
1062
+ input: input.slice(0, 8e3),
1063
+ encoding_format: "float"
1064
+ }),
1065
+ signal: AbortSignal.timeout(3e4)
1066
+ });
1067
+ if (!res.ok) {
1068
+ log.debug(`EmbedHelper request failed: ${provider.type} ${res.status}`);
1069
+ return null;
1070
+ }
1071
+ const payload = await res.json();
1072
+ const vector = payload?.data?.[0]?.embedding;
1073
+ if (!Array.isArray(vector)) return null;
1074
+ return vector.map((n) => {
1075
+ const v = Number(n);
1076
+ return Number.isFinite(v) ? v : 0;
1077
+ });
1078
+ } catch (err) {
1079
+ log.debug(`EmbedHelper error: ${err}`);
1080
+ return null;
1081
+ }
1082
+ }
1083
+ };
1084
+
1085
+ // src/conversation-index/faiss-adapter.ts
1086
+ import { fileURLToPath } from "url";
1087
+ import path4 from "path";
1088
+ var FaissAdapterError = class extends Error {
1089
+ constructor(message, code) {
1090
+ super(message);
1091
+ this.code = code;
1092
+ this.name = "FaissAdapterError";
1093
+ }
1094
+ code;
1095
+ };
1096
+ function parseSidecarManifest(result) {
1097
+ const manifest = result.manifest;
1098
+ if (!manifest || typeof manifest.version !== "number" || typeof manifest.modelId !== "string" || typeof manifest.normalizedModelId !== "string" || typeof manifest.dimension !== "number" || typeof manifest.chunkCount !== "number" || typeof manifest.updatedAt !== "string" || typeof manifest.lastSuccessfulRebuildAt !== "string") {
1099
+ return void 0;
1100
+ }
1101
+ return {
1102
+ version: manifest.version,
1103
+ modelId: manifest.modelId,
1104
+ normalizedModelId: manifest.normalizedModelId,
1105
+ dimension: manifest.dimension,
1106
+ chunkCount: manifest.chunkCount,
1107
+ updatedAt: manifest.updatedAt,
1108
+ lastSuccessfulRebuildAt: manifest.lastSuccessfulRebuildAt
1109
+ };
1110
+ }
1111
+ function resolveDefaultFaissScriptPath(fromModuleUrl = import.meta.url) {
1112
+ const currentFile = fileURLToPath(fromModuleUrl);
1113
+ const moduleDir = path4.dirname(currentFile);
1114
+ if (moduleDir.endsWith(`${path4.sep}conversation-index`)) {
1115
+ return path4.resolve(moduleDir, "..", "..", "scripts", "faiss_index.py");
1116
+ }
1117
+ return path4.resolve(moduleDir, "..", "scripts", "faiss_index.py");
1118
+ }
1119
+ var FaissConversationIndexAdapter = class {
1120
+ constructor(config) {
1121
+ this.config = config;
1122
+ this.pythonBin = config.pythonBin && config.pythonBin.trim().length > 0 ? config.pythonBin.trim() : "python3";
1123
+ this.scriptPath = config.scriptPath && config.scriptPath.trim().length > 0 ? config.scriptPath.trim() : resolveDefaultFaissScriptPath();
1124
+ this.indexPath = path4.isAbsolute(config.indexDir) ? config.indexDir : path4.join(config.memoryDir, config.indexDir);
1125
+ this.spawnFn = config.spawnFn ?? launchProcess;
1126
+ }
1127
+ config;
1128
+ pythonBin;
1129
+ scriptPath;
1130
+ indexPath;
1131
+ spawnFn;
1132
+ async upsertChunks(chunks) {
1133
+ if (this.config.maxBatchSize <= 0) return 0;
1134
+ let totalUpserted = 0;
1135
+ for (let offset = 0; offset < chunks.length; offset += this.config.maxBatchSize) {
1136
+ const batch = chunks.slice(offset, offset + this.config.maxBatchSize);
1137
+ if (batch.length === 0) continue;
1138
+ const payload = {
1139
+ modelId: this.config.modelId,
1140
+ indexPath: this.indexPath,
1141
+ chunks: batch.map((chunk) => ({
1142
+ id: chunk.id,
1143
+ sessionKey: chunk.sessionKey,
1144
+ text: chunk.text,
1145
+ startTs: chunk.startTs,
1146
+ endTs: chunk.endTs
1147
+ }))
1148
+ };
1149
+ const result = await this.runCommand("upsert", payload, this.config.upsertTimeoutMs);
1150
+ const upserted = result.upserted;
1151
+ if (typeof upserted !== "number" || !Number.isFinite(upserted)) {
1152
+ throw new FaissAdapterError("FAISS sidecar produced malformed upsert response", "malformed_output");
1153
+ }
1154
+ totalUpserted += Math.max(0, Math.floor(upserted));
1155
+ }
1156
+ return totalUpserted;
1157
+ }
1158
+ async searchChunks(query, topK) {
1159
+ const requestedTopK = Number.isFinite(topK) ? Math.floor(topK) : 0;
1160
+ const boundedTopK = this.config.maxSearchK > 0 ? Math.max(0, Math.min(requestedTopK, this.config.maxSearchK)) : 0;
1161
+ if (boundedTopK <= 0 || query.trim().length === 0) return [];
1162
+ const payload = {
1163
+ modelId: this.config.modelId,
1164
+ indexPath: this.indexPath,
1165
+ query,
1166
+ topK: boundedTopK
1167
+ };
1168
+ const result = await this.runCommand("search", payload, this.config.searchTimeoutMs);
1169
+ if (!Array.isArray(result.results)) {
1170
+ throw new FaissAdapterError("FAISS sidecar produced malformed search response", "malformed_output");
1171
+ }
1172
+ const rows = result.results;
1173
+ return rows.filter(
1174
+ (row) => row && typeof row.path === "string" && typeof row.snippet === "string" && typeof row.score === "number"
1175
+ ).map((row) => ({ path: row.path, snippet: row.snippet, score: row.score }));
1176
+ }
1177
+ async health() {
1178
+ const payload = {
1179
+ modelId: this.config.modelId,
1180
+ indexPath: this.indexPath
1181
+ };
1182
+ const result = await this.runCommand("health", payload, this.config.healthTimeoutMs);
1183
+ if (result.status !== "ok" && result.status !== "degraded" && result.status !== "error") {
1184
+ throw new FaissAdapterError("FAISS sidecar produced malformed health response", "malformed_output");
1185
+ }
1186
+ return {
1187
+ ok: result.ok === true,
1188
+ status: result.status,
1189
+ indexPath: this.indexPath,
1190
+ message: typeof result.error === "string" && result.error.length > 0 ? result.error : void 0,
1191
+ manifest: parseSidecarManifest(result)
1192
+ };
1193
+ }
1194
+ async inspect() {
1195
+ const payload = {
1196
+ modelId: this.config.modelId,
1197
+ indexPath: this.indexPath
1198
+ };
1199
+ const result = await this.runCommand("inspect", payload, this.config.healthTimeoutMs);
1200
+ if (result.status !== "ok" && result.status !== "degraded" && result.status !== "error") {
1201
+ throw new FaissAdapterError("FAISS sidecar produced malformed inspect response", "malformed_output");
1202
+ }
1203
+ return {
1204
+ ok: result.ok === true,
1205
+ status: result.status,
1206
+ indexPath: this.indexPath,
1207
+ message: typeof result.error === "string" && result.error.length > 0 ? result.error : void 0,
1208
+ manifest: parseSidecarManifest(result),
1209
+ metadata: {
1210
+ chunkCount: result.metadata && typeof result.metadata.chunkCount === "number" ? result.metadata.chunkCount : 0,
1211
+ hasIndex: result.metadata?.hasIndex === true,
1212
+ hasMetadata: result.metadata?.hasMetadata === true,
1213
+ hasManifest: result.metadata?.hasManifest === true
1214
+ }
1215
+ };
1216
+ }
1217
+ async rebuildChunks(chunks) {
1218
+ if (this.config.maxBatchSize <= 0) return 0;
1219
+ const firstBatch = chunks.slice(0, this.config.maxBatchSize);
1220
+ const rebuildPayload = {
1221
+ modelId: this.config.modelId,
1222
+ indexPath: this.indexPath,
1223
+ chunks: firstBatch.map((chunk) => ({
1224
+ id: chunk.id,
1225
+ sessionKey: chunk.sessionKey,
1226
+ text: chunk.text,
1227
+ startTs: chunk.startTs,
1228
+ endTs: chunk.endTs
1229
+ }))
1230
+ };
1231
+ const result = await this.runCommand("rebuild", rebuildPayload, this.config.upsertTimeoutMs);
1232
+ const rebuilt = result.rebuilt;
1233
+ if (typeof rebuilt !== "number" || !Number.isFinite(rebuilt)) {
1234
+ throw new FaissAdapterError("FAISS sidecar produced malformed rebuild response", "malformed_output");
1235
+ }
1236
+ const rebuildCount = Math.max(0, Math.floor(rebuilt));
1237
+ const remaining = chunks.slice(firstBatch.length);
1238
+ if (remaining.length === 0) return rebuildCount;
1239
+ const upserted = await this.upsertChunks(remaining);
1240
+ return rebuildCount + upserted;
1241
+ }
1242
+ async runCommand(command, payload, timeoutMs) {
1243
+ const args = [this.scriptPath, command];
1244
+ const child = this.spawnFn(this.pythonBin, args, {
1245
+ stdio: ["pipe", "pipe", "pipe"]
1246
+ });
1247
+ if (!child.stdin || !child.stdout || !child.stderr) {
1248
+ throw new FaissAdapterError(
1249
+ `FAISS sidecar missing stdio pipes (${command})`,
1250
+ "non_zero_exit"
1251
+ );
1252
+ }
1253
+ const stdinPipe = child.stdin;
1254
+ const stdoutPipe = child.stdout;
1255
+ const stderrPipe = child.stderr;
1256
+ const stdoutChunks = [];
1257
+ const stderrChunks = [];
1258
+ let timedOut = false;
1259
+ const timer = timeoutMs > 0 ? setTimeout(() => {
1260
+ timedOut = true;
1261
+ child.kill("SIGKILL");
1262
+ }, timeoutMs) : void 0;
1263
+ stdoutPipe.on("data", (chunk) => {
1264
+ stdoutChunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
1265
+ });
1266
+ stderrPipe.on("data", (chunk) => {
1267
+ stderrChunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
1268
+ });
1269
+ let code;
1270
+ try {
1271
+ stdinPipe.write(JSON.stringify(payload));
1272
+ stdinPipe.end();
1273
+ code = await new Promise((resolve, reject) => {
1274
+ const rejectAsProcessError = (err) => {
1275
+ const msg = err instanceof Error ? err.message : String(err);
1276
+ reject(new FaissAdapterError(`FAISS sidecar stream/process error (${command}): ${msg}`, "non_zero_exit"));
1277
+ };
1278
+ child.once("error", rejectAsProcessError);
1279
+ stdinPipe.once("error", rejectAsProcessError);
1280
+ child.once("close", (exitCode) => resolve(exitCode));
1281
+ });
1282
+ } catch (err) {
1283
+ if (err instanceof FaissAdapterError) throw err;
1284
+ const msg = err instanceof Error ? err.message : String(err);
1285
+ throw new FaissAdapterError(`FAISS sidecar stream/process error (${command}): ${msg}`, "non_zero_exit");
1286
+ } finally {
1287
+ if (timer) clearTimeout(timer);
1288
+ }
1289
+ const stdout = Buffer.concat(stdoutChunks).toString("utf-8").trim();
1290
+ const stderr = Buffer.concat(stderrChunks).toString("utf-8").trim();
1291
+ if (timedOut) {
1292
+ throw new FaissAdapterError(
1293
+ `FAISS sidecar command timed out (${command}, ${timeoutMs}ms)`,
1294
+ "timeout"
1295
+ );
1296
+ }
1297
+ if (code !== 0) {
1298
+ throw new FaissAdapterError(
1299
+ `FAISS sidecar exited non-zero (${command}, code=${code ?? "null"})${stderr ? `: ${stderr}` : ""}`,
1300
+ "non_zero_exit"
1301
+ );
1302
+ }
1303
+ if (stdout.length === 0) {
1304
+ throw new FaissAdapterError(
1305
+ `FAISS sidecar produced empty output (${command})`,
1306
+ "malformed_output"
1307
+ );
1308
+ }
1309
+ let parsed;
1310
+ try {
1311
+ parsed = JSON.parse(stdout);
1312
+ } catch {
1313
+ throw new FaissAdapterError(
1314
+ `FAISS sidecar produced malformed JSON (${command})`,
1315
+ "malformed_output"
1316
+ );
1317
+ }
1318
+ if (parsed.ok === false) {
1319
+ const message = typeof parsed.error === "string" && parsed.error.length > 0 ? parsed.error : `FAISS sidecar command failed (${command})`;
1320
+ throw new FaissAdapterError(message, "non_zero_exit");
1321
+ }
1322
+ if (parsed.ok !== true) {
1323
+ throw new FaissAdapterError(
1324
+ `FAISS sidecar produced malformed success envelope (${command})`,
1325
+ "malformed_output"
1326
+ );
1327
+ }
1328
+ return parsed;
1329
+ }
1330
+ };
1331
+ async function failOpenFaissHealth(adapter) {
1332
+ if (!adapter) {
1333
+ return { ok: false, status: "error", indexPath: "", message: "adapter-unavailable" };
1334
+ }
1335
+ try {
1336
+ return await adapter.health();
1337
+ } catch (err) {
1338
+ log.debug(`faiss adapter health failed (fail-open): ${err}`);
1339
+ return { ok: false, status: "error", indexPath: "", message: "adapter-error" };
1340
+ }
1341
+ }
1342
+
1343
+ // src/conversation-index/search.ts
1344
+ async function searchConversationIndex(qmd, query, maxResults) {
1345
+ try {
1346
+ const results = await qmd.search(query, void 0, maxResults);
1347
+ return results.map((r) => ({ path: r.path, snippet: r.snippet, score: r.score }));
1348
+ } catch (err) {
1349
+ log.debug(`conversation index search failed: ${err}`);
1350
+ return [];
1351
+ }
1352
+ }
1353
+ async function searchConversationIndexFaissFailOpen(adapter, query, maxResults) {
1354
+ if (!adapter) return [];
1355
+ try {
1356
+ return await adapter.searchChunks(query, maxResults);
1357
+ } catch (err) {
1358
+ log.debug(`conversation index FAISS search failed (fail-open): ${err}`);
1359
+ return [];
1360
+ }
1361
+ }
1362
+
1363
+ // src/conversation-index/backend.ts
1364
+ function createConversationIndexBackend(options) {
1365
+ if (!options.enabled) return void 0;
1366
+ const getQmd = options.getQmd ?? (() => options.qmd);
1367
+ const getFaiss = options.getFaiss ?? (() => options.faiss);
1368
+ if (options.backend === "faiss") {
1369
+ return createFaissBackend(getFaiss);
1370
+ }
1371
+ return createQmdBackend(getQmd, options.collectionDir);
1372
+ }
1373
+ function createQmdBackend(getQmd, collectionDir) {
1374
+ return {
1375
+ kind: "qmd",
1376
+ async initialize() {
1377
+ const qmd = getQmd();
1378
+ if (!qmd) {
1379
+ return {
1380
+ enabled: true,
1381
+ logLevel: "warn",
1382
+ message: "Conversation index QMD: not available search backend disabled or unsupported"
1383
+ };
1384
+ }
1385
+ const available = await qmd.probe();
1386
+ if (!available) {
1387
+ return {
1388
+ enabled: true,
1389
+ logLevel: "warn",
1390
+ message: `Conversation index QMD: not available ${qmd.debugStatus()}`
1391
+ };
1392
+ }
1393
+ const collectionState = await qmd.ensureCollection(collectionDir);
1394
+ if (collectionState === "missing") {
1395
+ return {
1396
+ enabled: false,
1397
+ logLevel: "warn",
1398
+ message: "Conversation index collection missing; disabling conversation semantic recall for this runtime"
1399
+ };
1400
+ }
1401
+ if (collectionState === "unknown") {
1402
+ return {
1403
+ enabled: true,
1404
+ logLevel: "warn",
1405
+ message: "Conversation index collection check unavailable; keeping conversation semantic recall enabled for fail-open behavior"
1406
+ };
1407
+ }
1408
+ if (collectionState === "skipped") {
1409
+ return {
1410
+ enabled: true,
1411
+ logLevel: "debug",
1412
+ message: "Conversation index collection check skipped in daemon-only mode"
1413
+ };
1414
+ }
1415
+ return {
1416
+ enabled: true,
1417
+ logLevel: "info",
1418
+ message: `Conversation index QMD: available ${qmd.debugStatus()}`
1419
+ };
1420
+ },
1421
+ async search(query, maxResults) {
1422
+ const qmd = getQmd();
1423
+ if (!qmd || !qmd.isAvailable()) return [];
1424
+ return searchConversationIndex(qmd, query, maxResults);
1425
+ },
1426
+ async update(_chunks, options) {
1427
+ const qmd = getQmd();
1428
+ if (!qmd || !qmd.isAvailable()) return { embedded: false };
1429
+ await qmd.update();
1430
+ if (options.embed) {
1431
+ await qmd.embed();
1432
+ return { embedded: true };
1433
+ }
1434
+ return { embedded: false };
1435
+ },
1436
+ async rebuild(_chunks, options) {
1437
+ const qmd = getQmd();
1438
+ if (!qmd || !qmd.isAvailable()) return { embedded: false, rebuilt: false };
1439
+ await qmd.update();
1440
+ if (options.embed) {
1441
+ await qmd.embed();
1442
+ return { embedded: true, rebuilt: true };
1443
+ }
1444
+ return { embedded: false, rebuilt: true };
1445
+ },
1446
+ async health() {
1447
+ const qmd = getQmd();
1448
+ let qmdAvailable = !!qmd?.isAvailable();
1449
+ if (!qmdAvailable && qmd) {
1450
+ try {
1451
+ qmdAvailable = await qmd.probe();
1452
+ } catch {
1453
+ qmdAvailable = false;
1454
+ }
1455
+ }
1456
+ return {
1457
+ backend: "qmd",
1458
+ status: qmdAvailable ? "ok" : "degraded",
1459
+ qmdAvailable
1460
+ };
1461
+ },
1462
+ async inspect() {
1463
+ const qmd = getQmd();
1464
+ let qmdAvailable = !!qmd?.isAvailable();
1465
+ if (!qmdAvailable && qmd) {
1466
+ try {
1467
+ qmdAvailable = await qmd.probe();
1468
+ } catch {
1469
+ qmdAvailable = false;
1470
+ }
1471
+ }
1472
+ return {
1473
+ backend: "qmd",
1474
+ status: qmdAvailable ? "ok" : "degraded",
1475
+ available: qmdAvailable,
1476
+ indexPath: collectionDir,
1477
+ supportsIncrementalUpdate: true,
1478
+ message: qmd ? void 0 : "Conversation index QMD runtime unavailable",
1479
+ metadata: {
1480
+ chunkCount: null,
1481
+ qmdAvailable,
1482
+ debugStatus: qmd?.debugStatus()
1483
+ }
1484
+ };
1485
+ }
1486
+ };
1487
+ }
1488
+ function createFaissBackend(getFaiss) {
1489
+ return {
1490
+ kind: "faiss",
1491
+ async initialize() {
1492
+ const health = await failOpenFaissHealth(getFaiss());
1493
+ return health.status === "ok" ? {
1494
+ enabled: true,
1495
+ logLevel: "info",
1496
+ message: `Conversation index FAISS: available (status=${health.status})`
1497
+ } : {
1498
+ enabled: true,
1499
+ logLevel: "warn",
1500
+ message: `Conversation index FAISS: degraded (${health.message ?? health.status})`
1501
+ };
1502
+ },
1503
+ async search(query, maxResults) {
1504
+ return searchConversationIndexFaissFailOpen(getFaiss(), query, maxResults);
1505
+ },
1506
+ async update(chunks, _options) {
1507
+ await upsertConversationChunksFailOpen(getFaiss(), chunks);
1508
+ return { embedded: false };
1509
+ },
1510
+ async rebuild(chunks, _options) {
1511
+ const result = await rebuildConversationChunksFailOpen(getFaiss(), chunks);
1512
+ return { embedded: false, rebuilt: result.skipped !== true };
1513
+ },
1514
+ async health() {
1515
+ const faiss = await failOpenFaissHealth(getFaiss());
1516
+ return {
1517
+ backend: "faiss",
1518
+ status: faiss.status === "ok" ? "ok" : "degraded",
1519
+ message: faiss.message,
1520
+ faiss
1521
+ };
1522
+ },
1523
+ async inspect() {
1524
+ const adapter = getFaiss();
1525
+ if (!adapter) {
1526
+ return {
1527
+ backend: "faiss",
1528
+ status: "degraded",
1529
+ available: false,
1530
+ indexPath: "",
1531
+ supportsIncrementalUpdate: true,
1532
+ message: "Conversation index FAISS runtime unavailable",
1533
+ metadata: {
1534
+ chunkCount: 0,
1535
+ hasIndex: false,
1536
+ hasMetadata: false,
1537
+ hasManifest: false
1538
+ }
1539
+ };
1540
+ }
1541
+ try {
1542
+ const inspection = await adapter.inspect();
1543
+ return {
1544
+ backend: "faiss",
1545
+ status: inspection.status === "ok" ? "ok" : "degraded",
1546
+ available: inspection.status === "ok",
1547
+ indexPath: inspection.indexPath,
1548
+ supportsIncrementalUpdate: true,
1549
+ message: inspection.message,
1550
+ metadata: {
1551
+ chunkCount: inspection.metadata.chunkCount,
1552
+ hasIndex: inspection.metadata.hasIndex,
1553
+ hasMetadata: inspection.metadata.hasMetadata,
1554
+ hasManifest: inspection.metadata.hasManifest,
1555
+ manifest: inspection.manifest
1556
+ }
1557
+ };
1558
+ } catch (err) {
1559
+ const fallback = await failOpenFaissHealth(adapter);
1560
+ return {
1561
+ backend: "faiss",
1562
+ status: "degraded",
1563
+ available: false,
1564
+ indexPath: fallback.indexPath,
1565
+ supportsIncrementalUpdate: true,
1566
+ message: fallback.message ?? String(err),
1567
+ metadata: {
1568
+ chunkCount: fallback.manifest?.chunkCount ?? 0,
1569
+ hasIndex: false,
1570
+ hasMetadata: false,
1571
+ hasManifest: !!fallback.manifest,
1572
+ manifest: fallback.manifest
1573
+ }
1574
+ };
1575
+ }
1576
+ }
1577
+ };
1578
+ }
1579
+
1580
+ // src/search/factory.ts
1581
+ function resolveNonQmdBackend(config) {
1582
+ const backend = config.searchBackend ?? "qmd";
1583
+ const collection = config.qmdCollection;
1584
+ if (backend === "noop") {
1585
+ return new NoopSearchBackend();
1586
+ }
1587
+ if (backend === "remote") {
1588
+ const baseUrl = config.remoteSearchBaseUrl || "http://localhost:8181";
1589
+ if (!config.remoteSearchBaseUrl) {
1590
+ log.warn("searchBackend is 'remote' but remoteSearchBaseUrl is not configured; using default http://localhost:8181");
1591
+ }
1592
+ return new RemoteSearchBackend({
1593
+ baseUrl,
1594
+ apiKey: config.remoteSearchApiKey,
1595
+ timeoutMs: config.remoteSearchTimeoutMs
1596
+ });
1597
+ }
1598
+ if (backend === "lancedb") {
1599
+ const embedHelper = new EmbedHelper(config);
1600
+ return new LanceDbBackend({
1601
+ dbPath: config.lanceDbPath,
1602
+ collection,
1603
+ embedHelper,
1604
+ memoryDir: config.memoryDir,
1605
+ embeddingDimension: config.lanceEmbeddingDimension
1606
+ });
1607
+ }
1608
+ if (backend === "meilisearch") {
1609
+ return new MeilisearchBackend({
1610
+ host: config.meilisearchHost,
1611
+ apiKey: config.meilisearchApiKey,
1612
+ collection,
1613
+ timeoutMs: config.meilisearchTimeoutMs,
1614
+ autoIndex: config.meilisearchAutoIndex,
1615
+ memoryDir: config.memoryDir
1616
+ });
1617
+ }
1618
+ if (backend === "orama") {
1619
+ const embedHelper = new EmbedHelper(config);
1620
+ return new OramaBackend({
1621
+ dbPath: config.oramaDbPath,
1622
+ collection,
1623
+ embedHelper,
1624
+ memoryDir: config.memoryDir,
1625
+ embeddingDimension: config.oramaEmbeddingDimension
1626
+ });
1627
+ }
1628
+ return void 0;
1629
+ }
1630
+ function qmdOptions(config) {
1631
+ return {
1632
+ slowLog: {
1633
+ enabled: config.slowLogEnabled,
1634
+ thresholdMs: config.slowLogThresholdMs
1635
+ },
1636
+ updateTimeoutMs: config.qmdUpdateTimeoutMs,
1637
+ updateMinIntervalMs: config.qmdUpdateMinIntervalMs,
1638
+ qmdPath: config.qmdPath,
1639
+ daemonUrl: config.qmdDaemonEnabled ? config.qmdDaemonUrl : void 0,
1640
+ daemonRecheckIntervalMs: config.qmdDaemonRecheckIntervalMs
1641
+ };
1642
+ }
1643
+ function createSearchBackend(config) {
1644
+ const nonQmd = resolveNonQmdBackend(config);
1645
+ if (nonQmd) return nonQmd;
1646
+ if (!config.qmdEnabled) {
1647
+ return new NoopSearchBackend();
1648
+ }
1649
+ return new QmdClient(config.qmdCollection, config.qmdMaxResults, qmdOptions(config));
1650
+ }
1651
+ function createConversationSearchBackend(config) {
1652
+ if (!config.conversationIndexEnabled || config.conversationIndexBackend !== "qmd") {
1653
+ return void 0;
1654
+ }
1655
+ const backend = config.searchBackend ?? "qmd";
1656
+ if (backend === "noop") return void 0;
1657
+ if (!config.qmdEnabled) return void 0;
1658
+ return new QmdClient(
1659
+ config.conversationIndexQmdCollection,
1660
+ Math.max(6, config.conversationRecallTopK),
1661
+ qmdOptions(config)
1662
+ );
1663
+ }
1664
+ function createConversationIndexRuntime(config, overrides) {
1665
+ const qmd = createConversationSearchBackend(config);
1666
+ const faiss = config.conversationIndexEnabled && config.conversationIndexBackend === "faiss" ? new FaissConversationIndexAdapter({
1667
+ memoryDir: config.memoryDir,
1668
+ scriptPath: config.conversationIndexFaissScriptPath,
1669
+ pythonBin: config.conversationIndexFaissPythonBin,
1670
+ modelId: config.conversationIndexFaissModelId,
1671
+ indexDir: config.conversationIndexFaissIndexDir,
1672
+ upsertTimeoutMs: config.conversationIndexFaissUpsertTimeoutMs,
1673
+ searchTimeoutMs: config.conversationIndexFaissSearchTimeoutMs,
1674
+ healthTimeoutMs: config.conversationIndexFaissHealthTimeoutMs,
1675
+ maxBatchSize: config.conversationIndexFaissMaxBatchSize,
1676
+ maxSearchK: config.conversationIndexFaissMaxSearchK
1677
+ }) : void 0;
1678
+ const backend = createConversationIndexBackend({
1679
+ enabled: config.conversationIndexEnabled,
1680
+ backend: config.conversationIndexBackend,
1681
+ getQmd: () => overrides?.getQmd?.() ?? qmd,
1682
+ getFaiss: () => overrides?.getFaiss?.() ?? faiss,
1683
+ collectionDir: path5.join(config.memoryDir, "conversation-index")
1684
+ });
1685
+ return { qmd, faiss, backend };
1686
+ }
1687
+
1688
+ // src/namespaces/storage.ts
1689
+ import path6 from "path";
1690
+ import { access } from "fs/promises";
1691
+ async function exists(p) {
1692
+ try {
1693
+ await access(p);
1694
+ return true;
1695
+ } catch {
1696
+ return false;
1697
+ }
1698
+ }
1699
+ var NamespaceStorageRouter = class {
1700
+ constructor(config) {
1701
+ this.config = config;
1702
+ }
1703
+ config;
1704
+ cache = /* @__PURE__ */ new Map();
1705
+ defaultNsRootResolved = null;
1706
+ async defaultNamespaceRoot() {
1707
+ if (this.defaultNsRootResolved) return this.defaultNsRootResolved;
1708
+ if (!this.config.namespacesEnabled) {
1709
+ this.defaultNsRootResolved = this.config.memoryDir;
1710
+ return this.defaultNsRootResolved;
1711
+ }
1712
+ const nsDir = path6.join(this.config.memoryDir, "namespaces", this.config.defaultNamespace);
1713
+ this.defaultNsRootResolved = await exists(nsDir) ? nsDir : this.config.memoryDir;
1714
+ return this.defaultNsRootResolved;
1715
+ }
1716
+ namespaceRootSync(namespace) {
1717
+ if (!this.config.namespacesEnabled) return this.config.memoryDir;
1718
+ if (namespace === this.config.defaultNamespace) {
1719
+ return this.defaultNsRootResolved ?? this.config.memoryDir;
1720
+ }
1721
+ return path6.join(this.config.memoryDir, "namespaces", namespace);
1722
+ }
1723
+ async storageFor(namespace) {
1724
+ const ns = namespace || this.config.defaultNamespace;
1725
+ if (ns !== this.config.defaultNamespace && !isSafeRouteNamespace(ns)) {
1726
+ throw new Error(`unsafe namespace: ${ns}`);
1727
+ }
1728
+ if (this.cache.has(ns)) return this.cache.get(ns);
1729
+ if (ns === this.config.defaultNamespace) {
1730
+ await this.defaultNamespaceRoot();
1731
+ }
1732
+ const root = this.namespaceRootSync(ns);
1733
+ const sm = new StorageManager(root);
1734
+ this.cache.set(ns, sm);
1735
+ return sm;
1736
+ }
1737
+ };
1738
+
1739
+ // src/namespaces/search.ts
1740
+ function namespaceCollectionName(baseCollection, namespace, options) {
1741
+ const trimmed = namespace.trim();
1742
+ const defaultNamespace = options?.defaultNamespace?.trim() || "default";
1743
+ if (options?.useLegacyDefaultCollection === true && trimmed === defaultNamespace) {
1744
+ return baseCollection;
1745
+ }
1746
+ const normalized = trimmed.toLowerCase().replace(/[^a-z0-9._-]+/g, "-");
1747
+ let start = 0;
1748
+ let end = normalized.length;
1749
+ while (start < end && normalized[start] === "-") start += 1;
1750
+ while (end > start && normalized[end - 1] === "-") end -= 1;
1751
+ const token = normalized.slice(start, end) || defaultNamespace;
1752
+ return `${baseCollection}--ns--${token}`;
1753
+ }
1754
+ var NamespaceSearchRouter = class {
1755
+ constructor(config, storageRouter, createBackend = createSearchBackend) {
1756
+ this.config = config;
1757
+ this.storageRouter = storageRouter;
1758
+ this.createBackend = createBackend;
1759
+ }
1760
+ config;
1761
+ storageRouter;
1762
+ createBackend;
1763
+ cache = /* @__PURE__ */ new Map();
1764
+ async collectionForNamespace(namespace) {
1765
+ return (await this.backendRecordFor(namespace)).collection;
1766
+ }
1767
+ async searchAcrossNamespaces(options) {
1768
+ const query = options.query.trim();
1769
+ if (!query) return [];
1770
+ const maxResults = Math.max(0, Math.floor(options.maxResults ?? this.config.qmdMaxResults));
1771
+ if (maxResults === 0) return [];
1772
+ const method = options.mode ?? "search";
1773
+ const namespaces = Array.from(new Set(options.namespaces.map((value) => value.trim()).filter(Boolean)));
1774
+ if (namespaces.length === 0) return [];
1775
+ const resultsByNamespace = await Promise.all(
1776
+ namespaces.map(async (namespace) => {
1777
+ const record = await this.backendRecordFor(namespace);
1778
+ if (!record.available || record.collectionState === "missing") return [];
1779
+ switch (method) {
1780
+ case "hybrid":
1781
+ return await record.backend.hybridSearch(query, void 0, maxResults, options.execution);
1782
+ case "bm25":
1783
+ return await record.backend.bm25Search(query, void 0, maxResults, options.execution);
1784
+ case "vector":
1785
+ return await record.backend.vectorSearch(query, void 0, maxResults, options.execution);
1786
+ default:
1787
+ return await record.backend.search(
1788
+ query,
1789
+ void 0,
1790
+ maxResults,
1791
+ options.searchOptions,
1792
+ options.execution
1793
+ );
1794
+ }
1795
+ })
1796
+ );
1797
+ return mergeNamespaceSearchResults(resultsByNamespace, maxResults);
1798
+ }
1799
+ async updateNamespaces(namespaces) {
1800
+ const unique = Array.from(new Set(namespaces.map((value) => value.trim()).filter(Boolean)));
1801
+ await Promise.all(
1802
+ unique.map(async (namespace) => {
1803
+ const record = await this.backendRecordFor(namespace);
1804
+ if (!record.available || record.collectionState === "missing") return;
1805
+ await record.backend.update();
1806
+ })
1807
+ );
1808
+ }
1809
+ async embedNamespaces(namespaces) {
1810
+ const unique = Array.from(new Set(namespaces.map((value) => value.trim()).filter(Boolean)));
1811
+ await Promise.all(
1812
+ unique.map(async (namespace) => {
1813
+ const record = await this.backendRecordFor(namespace);
1814
+ if (!record.available || record.collectionState === "missing") return;
1815
+ await record.backend.embed();
1816
+ })
1817
+ );
1818
+ }
1819
+ async ensureNamespaceCollection(namespace) {
1820
+ const record = await this.backendRecordFor(namespace);
1821
+ return record.collectionState;
1822
+ }
1823
+ async backendRecordFor(namespace) {
1824
+ const key = namespace.trim() || this.config.defaultNamespace;
1825
+ const existing = this.cache.get(key);
1826
+ if (existing) return await existing;
1827
+ const pending = (async () => {
1828
+ const storage = await this.storageRouter.storageFor(key);
1829
+ const useLegacyDefaultCollection = key === this.config.defaultNamespace && storage.dir === this.config.memoryDir;
1830
+ const scopedConfig = {
1831
+ ...this.config,
1832
+ memoryDir: storage.dir,
1833
+ qmdCollection: namespaceCollectionName(this.config.qmdCollection, key, {
1834
+ defaultNamespace: this.config.defaultNamespace,
1835
+ useLegacyDefaultCollection
1836
+ })
1837
+ };
1838
+ const backend = this.createBackend(scopedConfig);
1839
+ const available = await backend.probe().catch(() => false);
1840
+ const collectionState = available ? await backend.ensureCollection(storage.dir).catch(() => "unknown") : "unknown";
1841
+ return {
1842
+ backend,
1843
+ collection: scopedConfig.qmdCollection,
1844
+ memoryDir: storage.dir,
1845
+ available,
1846
+ collectionState
1847
+ };
1848
+ })();
1849
+ this.cache.set(key, pending);
1850
+ return await pending;
1851
+ }
1852
+ };
1853
+ function mergeNamespaceSearchResults(lists, maxResults) {
1854
+ const merged = /* @__PURE__ */ new Map();
1855
+ for (const list of lists) {
1856
+ for (const result of list) {
1857
+ const key = result.path || result.docid;
1858
+ const existing = merged.get(key);
1859
+ if (!existing) {
1860
+ merged.set(key, result);
1861
+ continue;
1862
+ }
1863
+ if (result.score > existing.score) {
1864
+ merged.set(key, {
1865
+ ...result,
1866
+ snippet: existing.snippet || result.snippet || ""
1867
+ });
1868
+ }
1869
+ }
1870
+ }
1871
+ return [...merged.values()].sort((a, b) => b.score - a.score).slice(0, maxResults);
1872
+ }
1873
+
1874
+ export {
1875
+ NoopSearchBackend,
1876
+ LanceDbBackend,
1877
+ MeilisearchBackend,
1878
+ OramaBackend,
1879
+ writeConversationChunks,
1880
+ createSearchBackend,
1881
+ createConversationIndexRuntime,
1882
+ NamespaceStorageRouter,
1883
+ namespaceCollectionName,
1884
+ NamespaceSearchRouter
1885
+ };
1886
+ //# sourceMappingURL=chunk-IZME7KW2.js.map