@remnic/core 1.1.12 → 1.1.14

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 (1324) hide show
  1. package/dist/access-cli.d.ts +2 -1
  2. package/dist/access-cli.js +263 -82
  3. package/dist/access-cli.js.map +1 -1
  4. package/dist/access-http.d.ts +26 -60
  5. package/dist/access-http.js +43 -29
  6. package/dist/access-mcp.d.ts +24 -6
  7. package/dist/access-mcp.js +35 -28
  8. package/dist/access-schema.d.ts +9 -6
  9. package/dist/access-schema.js +7 -5
  10. package/dist/access-service-DcCDmNYC.d.ts +1542 -0
  11. package/dist/access-service.d.ts +25 -7
  12. package/dist/access-service.js +33 -26
  13. package/dist/active-memory-bridge.js +2 -2
  14. package/dist/active-recall.js +11 -3
  15. package/dist/active-recall.js.map +1 -1
  16. package/dist/adapters/claude-code.d.ts +24 -0
  17. package/dist/adapters/claude-code.js +9 -0
  18. package/dist/adapters/codex.d.ts +25 -0
  19. package/dist/adapters/codex.js +9 -0
  20. package/dist/adapters/hermes.d.ts +35 -0
  21. package/dist/adapters/hermes.js +9 -0
  22. package/dist/adapters/index.d.ts +6 -0
  23. package/dist/adapters/index.js +26 -0
  24. package/dist/adapters/registry.d.ts +20 -0
  25. package/dist/adapters/registry.js +13 -0
  26. package/dist/adapters/replit.d.ts +28 -0
  27. package/dist/adapters/replit.js +9 -0
  28. package/dist/adapters/types.d.ts +43 -0
  29. package/dist/adapters/types.js +8 -0
  30. package/dist/bootstrap.d.ts +20 -5
  31. package/dist/boxes.d.ts +7 -0
  32. package/dist/boxes.js +1 -1
  33. package/dist/briefing.d.ts +5 -3
  34. package/dist/briefing.js +9 -6
  35. package/dist/buffer-surprise-report.js +1 -1
  36. package/dist/buffer.d.ts +18 -4
  37. package/dist/buffer.js +1 -1
  38. package/dist/calibration.js +4 -4
  39. package/dist/capsule-cli.d.ts +4 -4
  40. package/dist/capsule-cli.js +1 -1
  41. package/dist/capsule-crypto-5CYAGVC5.js +18 -0
  42. package/dist/capsule-merge-4MGKE7C5.js +189 -0
  43. package/dist/causal-behavior.d.ts +8 -28
  44. package/dist/causal-behavior.js +6 -3
  45. package/dist/causal-behavior.js.map +1 -1
  46. package/dist/causal-chain.js +3 -2
  47. package/dist/causal-consolidation.d.ts +1 -1
  48. package/dist/causal-consolidation.js +24 -13
  49. package/dist/causal-consolidation.js.map +1 -1
  50. package/dist/causal-retrieval.js +3 -3
  51. package/dist/causal-trajectory.js +1 -1
  52. package/dist/chunk-25MQ7IHJ.js +427 -0
  53. package/dist/chunk-25MQ7IHJ.js.map +1 -0
  54. package/dist/chunk-2F2W355T.js +256 -0
  55. package/dist/chunk-2F2W355T.js.map +1 -0
  56. package/dist/chunk-2KI4QFHU.js +228 -0
  57. package/dist/chunk-2KI4QFHU.js.map +1 -0
  58. package/dist/chunk-2PRQG7PV.js +86 -0
  59. package/dist/chunk-2PRQG7PV.js.map +1 -0
  60. package/dist/chunk-2QR3XXIC.js +2272 -0
  61. package/dist/chunk-2QR3XXIC.js.map +1 -0
  62. package/dist/chunk-2WWLHTZY.js +121 -0
  63. package/dist/chunk-326G7DJK.js +2185 -0
  64. package/dist/chunk-326G7DJK.js.map +1 -0
  65. package/dist/chunk-34DQE4KF.js +174 -0
  66. package/dist/chunk-34DQE4KF.js.map +1 -0
  67. package/dist/chunk-3APJ5EVB.js +601 -0
  68. package/dist/chunk-3APJ5EVB.js.map +1 -0
  69. package/dist/chunk-3HPAPHUK.js +51 -0
  70. package/dist/chunk-3HPAPHUK.js.map +1 -0
  71. package/dist/chunk-3JXBXXM2.js +69 -0
  72. package/dist/chunk-3JXBXXM2.js.map +1 -0
  73. package/dist/chunk-3KW65B36.js +681 -0
  74. package/dist/chunk-3KW65B36.js.map +1 -0
  75. package/dist/chunk-3UXOZBHV.js +20 -0
  76. package/dist/chunk-3UXOZBHV.js.map +1 -0
  77. package/dist/chunk-3VAL7ZL2.js +266 -0
  78. package/dist/chunk-3VAL7ZL2.js.map +1 -0
  79. package/dist/chunk-3Y4P7RXM.js +31 -0
  80. package/dist/chunk-3Y4P7RXM.js.map +1 -0
  81. package/dist/chunk-47VWKCAF.js +273 -0
  82. package/dist/chunk-47VWKCAF.js.map +1 -0
  83. package/dist/chunk-4CRG46BG.js +271 -0
  84. package/dist/chunk-5375UYTQ.js +914 -0
  85. package/dist/chunk-5375UYTQ.js.map +1 -0
  86. package/dist/chunk-56K5QLHX.js +506 -0
  87. package/dist/chunk-56K5QLHX.js.map +1 -0
  88. package/dist/chunk-5RGLBDQF.js +596 -0
  89. package/dist/chunk-5RGLBDQF.js.map +1 -0
  90. package/dist/chunk-5UZXUTVO.js +9 -0
  91. package/dist/chunk-5UZXUTVO.js.map +1 -0
  92. package/dist/chunk-65PG43EQ.js +105 -0
  93. package/dist/chunk-65PG43EQ.js.map +1 -0
  94. package/dist/chunk-66DHUKLO.js +57 -0
  95. package/dist/chunk-66DHUKLO.js.map +1 -0
  96. package/dist/chunk-6FC5EGNV.js +46 -0
  97. package/dist/chunk-6FC5EGNV.js.map +1 -0
  98. package/dist/chunk-6H2TESSP.js +62 -0
  99. package/dist/chunk-6H2TESSP.js.map +1 -0
  100. package/dist/chunk-6LVVDPJ4.js +32 -0
  101. package/dist/chunk-6LVVDPJ4.js.map +1 -0
  102. package/dist/chunk-6RVI47ZR.js +159 -0
  103. package/dist/chunk-6RVI47ZR.js.map +1 -0
  104. package/dist/chunk-7AAT6G4Q.js +5117 -0
  105. package/dist/chunk-7AAT6G4Q.js.map +1 -0
  106. package/dist/chunk-7DTASS5T.js +29 -0
  107. package/dist/chunk-7DTASS5T.js.map +1 -0
  108. package/dist/chunk-7IASACLB.js +596 -0
  109. package/dist/chunk-7MNMYOFP.js +32 -0
  110. package/dist/chunk-7MNMYOFP.js.map +1 -0
  111. package/dist/chunk-7N4KAIGN.js +133 -0
  112. package/dist/chunk-7N4KAIGN.js.map +1 -0
  113. package/dist/chunk-7OZ53EXP.js +101 -0
  114. package/dist/chunk-7OZ53EXP.js.map +1 -0
  115. package/dist/chunk-7XYTQGCC.js +134 -0
  116. package/dist/chunk-7XYTQGCC.js.map +1 -0
  117. package/dist/chunk-A2XUIMJ3.js +341 -0
  118. package/dist/chunk-A2XUIMJ3.js.map +1 -0
  119. package/dist/chunk-AGZQD76C.js +201 -0
  120. package/dist/chunk-AGZQD76C.js.map +1 -0
  121. package/dist/chunk-APO3DCMU.js +361 -0
  122. package/dist/chunk-APO3DCMU.js.map +1 -0
  123. package/dist/chunk-BFBF3XEF.js +283 -0
  124. package/dist/chunk-BFBF3XEF.js.map +1 -0
  125. package/dist/chunk-BJ3KMYTB.js +1974 -0
  126. package/dist/chunk-BJ3KMYTB.js.map +1 -0
  127. package/dist/chunk-CHEL3SKB.js +6758 -0
  128. package/dist/chunk-CHEL3SKB.js.map +1 -0
  129. package/dist/chunk-CQZRLNMV.js +1491 -0
  130. package/dist/chunk-CQZRLNMV.js.map +1 -0
  131. package/dist/chunk-D46YSIYX.js +892 -0
  132. package/dist/chunk-D46YSIYX.js.map +1 -0
  133. package/dist/chunk-DINWEURR.js +648 -0
  134. package/dist/chunk-DINWEURR.js.map +1 -0
  135. package/dist/chunk-DK5LDEQM.js +530 -0
  136. package/dist/chunk-DK5LDEQM.js.map +1 -0
  137. package/dist/chunk-DOM4GKSW.js +34 -0
  138. package/dist/chunk-DOM4GKSW.js.map +1 -0
  139. package/dist/chunk-EDTHC6UD.js +1075 -0
  140. package/dist/chunk-EFJ3MQ4V.js +721 -0
  141. package/dist/chunk-EHRTFRWW.js +89 -0
  142. package/dist/chunk-EHRTFRWW.js.map +1 -0
  143. package/dist/chunk-FAJ7FZYM.js +11 -0
  144. package/dist/chunk-FAJ7FZYM.js.map +1 -0
  145. package/dist/chunk-FBYESMQ2.js +570 -0
  146. package/dist/chunk-FDU6HUUL.js +147 -0
  147. package/dist/chunk-FF4KLI5W.js +99 -0
  148. package/dist/chunk-FF4KLI5W.js.map +1 -0
  149. package/dist/chunk-FIT6DMX6.js +310 -0
  150. package/dist/chunk-FIT6DMX6.js.map +1 -0
  151. package/dist/chunk-FJ43PRLT.js +272 -0
  152. package/dist/chunk-FJ43PRLT.js.map +1 -0
  153. package/dist/chunk-FKFMOY3N.js +32 -0
  154. package/dist/chunk-FKFMOY3N.js.map +1 -0
  155. package/dist/chunk-FLTNHQK6.js +262 -0
  156. package/dist/chunk-FLTNHQK6.js.map +1 -0
  157. package/dist/chunk-GA454ALV.js +12436 -0
  158. package/dist/chunk-GA454ALV.js.map +1 -0
  159. package/dist/chunk-GGKRUQOO.js +228 -0
  160. package/dist/chunk-GIF42EW3.js +63 -0
  161. package/dist/chunk-GIF42EW3.js.map +1 -0
  162. package/dist/chunk-GL6I6MEQ.js +647 -0
  163. package/dist/chunk-H3ME6L6D.js +709 -0
  164. package/dist/chunk-H3ME6L6D.js.map +1 -0
  165. package/dist/chunk-HHLLAQGZ.js +1 -0
  166. package/dist/chunk-HXXBL2KD.js +2040 -0
  167. package/dist/chunk-I5V2VDIW.js +219 -0
  168. package/dist/chunk-I5V2VDIW.js.map +1 -0
  169. package/dist/chunk-I6K5FBRQ.js +35 -0
  170. package/dist/chunk-I6K5FBRQ.js.map +1 -0
  171. package/dist/chunk-ICRIXAP2.js +121 -0
  172. package/dist/chunk-ICRIXAP2.js.map +1 -0
  173. package/dist/chunk-J4EB7DNW.js +11 -0
  174. package/dist/chunk-J4EB7DNW.js.map +1 -0
  175. package/dist/chunk-JLFA7DQG.js +62 -0
  176. package/dist/chunk-JLFA7DQG.js.map +1 -0
  177. package/dist/chunk-KJTKLXTH.js +9 -0
  178. package/dist/chunk-KJTKLXTH.js.map +1 -0
  179. package/dist/chunk-KLAO5DGL.js +917 -0
  180. package/dist/chunk-KLAO5DGL.js.map +1 -0
  181. package/dist/chunk-KNKUID7G.js +183 -0
  182. package/dist/chunk-KOSORCJG.js +624 -0
  183. package/dist/chunk-KOSORCJG.js.map +1 -0
  184. package/dist/chunk-KUJVMMZQ.js +1262 -0
  185. package/dist/chunk-KUJVMMZQ.js.map +1 -0
  186. package/dist/chunk-LCR46JY5.js +123 -0
  187. package/dist/chunk-LCR46JY5.js.map +1 -0
  188. package/dist/chunk-LLQ2LLWF.js +148 -0
  189. package/dist/chunk-LLQ2LLWF.js.map +1 -0
  190. package/dist/chunk-LPMVBPA3.js +236 -0
  191. package/dist/chunk-LT3NLYSI.js +50 -0
  192. package/dist/chunk-LT3NLYSI.js.map +1 -0
  193. package/dist/chunk-LUDTDZLK.js +287 -0
  194. package/dist/chunk-LUDTDZLK.js.map +1 -0
  195. package/dist/chunk-M23FSH32.js +3963 -0
  196. package/dist/chunk-M23FSH32.js.map +1 -0
  197. package/dist/chunk-MC26UJIM.js +118 -0
  198. package/dist/chunk-ME6ESPZU.js +119 -0
  199. package/dist/chunk-ME6ESPZU.js.map +1 -0
  200. package/dist/chunk-MGKYQQYF.js +272 -0
  201. package/dist/chunk-MJFNCJXV.js +66 -0
  202. package/dist/chunk-MJFNCJXV.js.map +1 -0
  203. package/dist/chunk-MSWG7JI6.js +237 -0
  204. package/dist/chunk-MSWG7JI6.js.map +1 -0
  205. package/dist/chunk-MT25YHYH.js +141 -0
  206. package/dist/chunk-MT25YHYH.js.map +1 -0
  207. package/dist/chunk-MT4HVDUZ.js +53 -0
  208. package/dist/chunk-MY6TPVXW.js +219 -0
  209. package/dist/chunk-N2D6GXBM.js +267 -0
  210. package/dist/chunk-N2D6GXBM.js.map +1 -0
  211. package/dist/chunk-NJ3MJQZX.js +46 -0
  212. package/dist/chunk-NJ3MJQZX.js.map +1 -0
  213. package/dist/chunk-NMZY542O.js +335 -0
  214. package/dist/chunk-NMZY542O.js.map +1 -0
  215. package/dist/chunk-NNVTUXEB.js +23 -0
  216. package/dist/chunk-NZL6GGQE.js +375 -0
  217. package/dist/chunk-NZL6GGQE.js.map +1 -0
  218. package/dist/chunk-P4NEIHUT.js +108 -0
  219. package/dist/chunk-P7FMDTKL.js +103 -0
  220. package/dist/chunk-P7FMDTKL.js.map +1 -0
  221. package/dist/chunk-PHK3HARR.js +32 -0
  222. package/dist/chunk-PHK3HARR.js.map +1 -0
  223. package/dist/chunk-PIRJPV5T.js +98 -0
  224. package/dist/chunk-PIRJPV5T.js.map +1 -0
  225. package/dist/chunk-PK7H5L6Y.js +159 -0
  226. package/dist/chunk-PK7H5L6Y.js.map +1 -0
  227. package/dist/chunk-PR5FBTFU.js +233 -0
  228. package/dist/chunk-PR5FBTFU.js.map +1 -0
  229. package/dist/chunk-PU63GXWS.js +174 -0
  230. package/dist/chunk-PU63GXWS.js.map +1 -0
  231. package/dist/chunk-PZIAX57I.js +124 -0
  232. package/dist/chunk-PZIAX57I.js.map +1 -0
  233. package/dist/chunk-Q7P4WJDP.js +26 -0
  234. package/dist/chunk-Q7P4WJDP.js.map +1 -0
  235. package/dist/chunk-QQUAB63I.js +63 -0
  236. package/dist/chunk-QQUAB63I.js.map +1 -0
  237. package/dist/chunk-QRNI5JBH.js +18 -0
  238. package/dist/chunk-RHY3HH7P.js +601 -0
  239. package/dist/chunk-RHY3HH7P.js.map +1 -0
  240. package/dist/chunk-RRF5UOBJ.js +91 -0
  241. package/dist/chunk-RXDLTSWT.js +124 -0
  242. package/dist/chunk-RXDLTSWT.js.map +1 -0
  243. package/dist/chunk-RYED3SPJ.js +42 -0
  244. package/dist/chunk-RYED3SPJ.js.map +1 -0
  245. package/dist/chunk-S7KDBTWT.js +106 -0
  246. package/dist/chunk-S7KDBTWT.js.map +1 -0
  247. package/dist/chunk-SEDEKFYQ.js +1 -0
  248. package/dist/chunk-TECVW3JP.js +36 -0
  249. package/dist/chunk-TECVW3JP.js.map +1 -0
  250. package/dist/chunk-TFO23QT4.js +88 -0
  251. package/dist/chunk-TFO23QT4.js.map +1 -0
  252. package/dist/chunk-TK4UEOSK.js +76 -0
  253. package/dist/chunk-TK4UEOSK.js.map +1 -0
  254. package/dist/chunk-TKWGAOLV.js +122 -0
  255. package/dist/chunk-TKWGAOLV.js.map +1 -0
  256. package/dist/chunk-TMM4S4IJ.js +597 -0
  257. package/dist/chunk-TMM4S4IJ.js.map +1 -0
  258. package/dist/chunk-TMQLARTH.js +188 -0
  259. package/dist/chunk-TMQLARTH.js.map +1 -0
  260. package/dist/chunk-TPDBFYEG.js +130 -0
  261. package/dist/chunk-TPDBFYEG.js.map +1 -0
  262. package/dist/chunk-TPMQ3G6Z.js +145 -0
  263. package/dist/chunk-TPMQ3G6Z.js.map +1 -0
  264. package/dist/chunk-TZOLIGIG.js +61 -0
  265. package/dist/chunk-TZOLIGIG.js.map +1 -0
  266. package/dist/chunk-U3PN77QT.js +113 -0
  267. package/dist/chunk-U3WSW6PZ.js +277 -0
  268. package/dist/chunk-U4SCL7B7.js +640 -0
  269. package/dist/chunk-U4SCL7B7.js.map +1 -0
  270. package/dist/chunk-UWK5OXUJ.js +156 -0
  271. package/dist/chunk-UWK5OXUJ.js.map +1 -0
  272. package/dist/chunk-UWVJF25J.js +74 -0
  273. package/dist/chunk-UXHQAFNA.js +1317 -0
  274. package/dist/chunk-UXHQAFNA.js.map +1 -0
  275. package/dist/chunk-V5OCT34X.js +1 -0
  276. package/dist/chunk-VLXA6PI2.js +304 -0
  277. package/dist/chunk-VLXA6PI2.js.map +1 -0
  278. package/dist/chunk-VNO6ZJ35.js +500 -0
  279. package/dist/chunk-VNO6ZJ35.js.map +1 -0
  280. package/dist/chunk-VW676BEI.js +827 -0
  281. package/dist/chunk-VW676BEI.js.map +1 -0
  282. package/dist/chunk-W3LR522O.js +2296 -0
  283. package/dist/chunk-W4L6CZKA.js +96 -0
  284. package/dist/chunk-W4L6CZKA.js.map +1 -0
  285. package/dist/chunk-W4RVMTHR.js +372 -0
  286. package/dist/chunk-W4RVMTHR.js.map +1 -0
  287. package/dist/chunk-WEHSQBFR.js +188 -0
  288. package/dist/chunk-WEHSQBFR.js.map +1 -0
  289. package/dist/chunk-WELDCG6C.js +380 -0
  290. package/dist/chunk-WELDCG6C.js.map +1 -0
  291. package/dist/chunk-WZYKANL3.js +2800 -0
  292. package/dist/chunk-WZYKANL3.js.map +1 -0
  293. package/dist/chunk-XIG5PDM7.js +48 -0
  294. package/dist/chunk-XJNBEDFE.js +193 -0
  295. package/dist/chunk-XJNBEDFE.js.map +1 -0
  296. package/dist/chunk-XVVIG67A.js +291 -0
  297. package/dist/chunk-XVVIG67A.js.map +1 -0
  298. package/dist/chunk-XVZ7B3HG.js +135 -0
  299. package/dist/chunk-YBPYIAA5.js +73 -0
  300. package/dist/chunk-YBPYIAA5.js.map +1 -0
  301. package/dist/chunk-Z734BLO3.js +21 -0
  302. package/dist/chunk-Z734BLO3.js.map +1 -0
  303. package/dist/chunk-ZKSK55RC.js +269 -0
  304. package/dist/chunk-ZKSK55RC.js.map +1 -0
  305. package/dist/chunk-ZTFCYYEZ.js +69 -0
  306. package/dist/chunk-ZTFCYYEZ.js.map +1 -0
  307. package/dist/chunk-ZY2MNJR6.js +329 -0
  308. package/dist/chunk-ZY2MNJR6.js.map +1 -0
  309. package/dist/cli-D3VpkVwB.d.ts +1136 -0
  310. package/dist/cli.d.ts +39 -10
  311. package/dist/cli.js +108 -49
  312. package/dist/commitment-ledger.js +1 -1
  313. package/dist/compat/checks.d.ts +5 -0
  314. package/dist/compat/checks.js +11 -0
  315. package/dist/compat/checks.js.map +1 -0
  316. package/dist/compat/types.d.ts +30 -0
  317. package/dist/compat/types.js +1 -0
  318. package/dist/compat/types.js.map +1 -0
  319. package/dist/compounding/engine.d.ts +221 -0
  320. package/dist/compounding/engine.js +32 -0
  321. package/dist/compounding/engine.js.map +1 -0
  322. package/dist/compounding/preference-consolidator.d.ts +92 -0
  323. package/dist/compounding/preference-consolidator.js +553 -0
  324. package/dist/compounding/preference-consolidator.js.map +1 -0
  325. package/dist/config.d.ts +4 -2
  326. package/dist/config.js +9 -4
  327. package/dist/conflict-policy-DyJ2wd-h.d.ts +4 -0
  328. package/dist/connectors/codex-materialize-runner.d.ts +64 -0
  329. package/dist/connectors/codex-materialize-runner.js +33 -0
  330. package/dist/connectors/codex-materialize-runner.js.map +1 -0
  331. package/dist/connectors/codex-materialize.d.ts +195 -0
  332. package/dist/connectors/codex-materialize.js +38 -0
  333. package/dist/connectors/codex-materialize.js.map +1 -0
  334. package/dist/connectors/index.d.ts +444 -0
  335. package/dist/connectors/index.js +115 -0
  336. package/dist/connectors/index.js.map +1 -0
  337. package/dist/connectors-cli-CwbyjGR7.d.ts +257 -0
  338. package/dist/connectors-cli.d.ts +1 -1
  339. package/dist/consolidation-provenance-check.d.ts +3 -1
  340. package/dist/consolidation-undo.d.ts +3 -1
  341. package/dist/contradiction/index.d.ts +258 -0
  342. package/dist/contradiction/index.js +43 -0
  343. package/dist/contradiction/index.js.map +1 -0
  344. package/dist/contradiction-review-ATP4S6IC.js +30 -0
  345. package/dist/contradiction-review-ATP4S6IC.js.map +1 -0
  346. package/dist/contradiction-scan-5A4IDZV5.js +13 -0
  347. package/dist/contradiction-scan-5A4IDZV5.js.map +1 -0
  348. package/dist/conversation-index/backend.d.ts +97 -0
  349. package/dist/conversation-index/backend.js +13 -0
  350. package/dist/conversation-index/backend.js.map +1 -0
  351. package/dist/conversation-index/chunker.d.ts +16 -0
  352. package/dist/conversation-index/chunker.js +8 -0
  353. package/dist/conversation-index/chunker.js.map +1 -0
  354. package/dist/conversation-index/cleanup.d.ts +11 -0
  355. package/dist/conversation-index/cleanup.js +9 -0
  356. package/dist/conversation-index/cleanup.js.map +1 -0
  357. package/dist/conversation-index/faiss-adapter.d.ts +6 -0
  358. package/dist/conversation-index/faiss-adapter.js +16 -0
  359. package/dist/conversation-index/faiss-adapter.js.map +1 -0
  360. package/dist/conversation-index/indexer.d.ts +23 -0
  361. package/dist/conversation-index/indexer.js +15 -0
  362. package/dist/conversation-index/indexer.js.map +1 -0
  363. package/dist/conversation-index/search.d.ts +6 -0
  364. package/dist/conversation-index/search.js +11 -0
  365. package/dist/conversation-index/search.js.map +1 -0
  366. package/dist/embedding-fallback.js +2 -2
  367. package/dist/enrichment/index.d.ts +163 -0
  368. package/dist/enrichment/index.js +18 -0
  369. package/dist/enrichment/index.js.map +1 -0
  370. package/dist/entity-retrieval.d.ts +4 -2
  371. package/dist/entity-retrieval.js +8 -5
  372. package/dist/evals.js +1 -1
  373. package/dist/explicit-capture.d.ts +20 -5
  374. package/dist/explicit-capture.js +2 -2
  375. package/dist/extraction-judge-training.js +1 -1
  376. package/dist/extraction.js +8 -8
  377. package/dist/faiss-adapter-CzPghc4C.d.ts +70 -0
  378. package/dist/fallback-llm.d.ts +2 -0
  379. package/dist/fallback-llm.js +4 -4
  380. package/dist/graph-edge-decay-5DI5GUNL.js +207 -0
  381. package/dist/index.d.ts +66 -711
  382. package/dist/index.js +556 -2680
  383. package/dist/index.js.map +1 -1
  384. package/dist/lcm/archive.d.ts +89 -0
  385. package/dist/lcm/archive.js +12 -0
  386. package/dist/lcm/archive.js.map +1 -0
  387. package/dist/lcm/dag.d.ts +48 -0
  388. package/dist/lcm/dag.js +8 -0
  389. package/dist/lcm/dag.js.map +1 -0
  390. package/dist/lcm/engine.d.ts +116 -0
  391. package/dist/lcm/engine.js +20 -0
  392. package/dist/lcm/engine.js.map +1 -0
  393. package/dist/lcm/index.d.ts +12 -0
  394. package/dist/lcm/index.js +44 -0
  395. package/dist/lcm/index.js.map +1 -0
  396. package/dist/lcm/queue.d.ts +62 -0
  397. package/dist/lcm/queue.js +8 -0
  398. package/dist/lcm/queue.js.map +1 -0
  399. package/dist/lcm/recall.d.ts +20 -0
  400. package/dist/lcm/recall.js +8 -0
  401. package/dist/lcm/recall.js.map +1 -0
  402. package/dist/lcm/schema.d.ts +16 -0
  403. package/dist/lcm/schema.js +14 -0
  404. package/dist/lcm/schema.js.map +1 -0
  405. package/dist/lcm/summarizer.d.ts +38 -0
  406. package/dist/lcm/summarizer.js +12 -0
  407. package/dist/lcm/summarizer.js.map +1 -0
  408. package/dist/lcm/tools.d.ts +29 -0
  409. package/dist/lcm/tools.js +8 -0
  410. package/dist/lcm/tools.js.map +1 -0
  411. package/dist/live-connectors-runner.js +5 -5
  412. package/dist/local-llm.js +3 -3
  413. package/dist/maintenance/archive-observations.d.ts +18 -0
  414. package/dist/maintenance/archive-observations.js +8 -0
  415. package/dist/maintenance/archive-observations.js.map +1 -0
  416. package/dist/maintenance/backup-stamp.d.ts +3 -0
  417. package/dist/maintenance/backup-stamp.js +8 -0
  418. package/dist/maintenance/backup-stamp.js.map +1 -0
  419. package/dist/maintenance/memory-governance-cron.d.ts +85 -0
  420. package/dist/maintenance/memory-governance-cron.js +22 -0
  421. package/dist/maintenance/memory-governance-cron.js.map +1 -0
  422. package/dist/maintenance/memory-governance.d.ts +137 -0
  423. package/dist/maintenance/memory-governance.js +40 -0
  424. package/dist/maintenance/memory-governance.js.map +1 -0
  425. package/dist/maintenance/migrate-observations.d.ts +18 -0
  426. package/dist/maintenance/migrate-observations.js +9 -0
  427. package/dist/maintenance/migrate-observations.js.map +1 -0
  428. package/dist/maintenance/observation-ledger-utils.d.ts +10 -0
  429. package/dist/maintenance/observation-ledger-utils.js +10 -0
  430. package/dist/maintenance/observation-ledger-utils.js.map +1 -0
  431. package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +15 -0
  432. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +28 -0
  433. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js.map +1 -0
  434. package/dist/maintenance/rebuild-memory-projection.d.ts +77 -0
  435. package/dist/maintenance/rebuild-memory-projection.js +35 -0
  436. package/dist/maintenance/rebuild-memory-projection.js.map +1 -0
  437. package/dist/maintenance/rebuild-observations.d.ts +17 -0
  438. package/dist/maintenance/rebuild-observations.js +9 -0
  439. package/dist/maintenance/rebuild-observations.js.map +1 -0
  440. package/dist/mcp-memory-inspector-app.d.ts +24 -6
  441. package/dist/memory-projection-store.d.ts +108 -3
  442. package/dist/memory-projection-store.js +2 -1
  443. package/dist/memory-worth-outcomes.d.ts +4 -2
  444. package/dist/migrate/from-engram.d.ts +24 -0
  445. package/dist/migrate/from-engram.js +12 -0
  446. package/dist/migrate/from-engram.js.map +1 -0
  447. package/dist/namespaces/migrate.d.ts +50 -0
  448. package/dist/namespaces/migrate.js +50 -0
  449. package/dist/namespaces/migrate.js.map +1 -0
  450. package/dist/namespaces/principal.d.ts +17 -0
  451. package/dist/namespaces/principal.js +16 -0
  452. package/dist/namespaces/principal.js.map +1 -0
  453. package/dist/namespaces/search.d.ts +46 -0
  454. package/dist/namespaces/search.js +28 -0
  455. package/dist/namespaces/search.js.map +1 -0
  456. package/dist/namespaces/storage.d.ts +32 -0
  457. package/dist/namespaces/storage.js +28 -0
  458. package/dist/namespaces/storage.js.map +1 -0
  459. package/dist/network/tailscale.d.ts +41 -0
  460. package/dist/network/tailscale.js +9 -0
  461. package/dist/network/tailscale.js.map +1 -0
  462. package/dist/network/webdav.d.ts +39 -0
  463. package/dist/network/webdav.js +10 -0
  464. package/dist/network/webdav.js.map +1 -0
  465. package/dist/objective-state-writers.js +2 -2
  466. package/dist/operator-toolkit.d.ts +4 -2
  467. package/dist/operator-toolkit.js +32 -14
  468. package/dist/opik-exporter.js +2 -2
  469. package/dist/opik-exporter.js.map +1 -1
  470. package/dist/orchestrator-DuWl9Hwx.d.ts +1244 -0
  471. package/dist/orchestrator.d.ts +22 -7
  472. package/dist/orchestrator.js +79 -44
  473. package/dist/path-MR5JPYOP.js +9 -0
  474. package/dist/path-MR5JPYOP.js.map +1 -0
  475. package/dist/qmd-recall-cache.d.ts +1 -1
  476. package/dist/qmd.d.ts +102 -3
  477. package/dist/qmd.js +23 -5
  478. package/dist/recall-explain-renderer.js +3 -3
  479. package/dist/recall-xray-cli.js +4 -4
  480. package/dist/recall-xray-renderer.js +3 -3
  481. package/dist/recall-xray.js +2 -2
  482. package/dist/replay/normalizers/chatgpt.d.ts +6 -0
  483. package/dist/replay/normalizers/chatgpt.js +11 -0
  484. package/dist/replay/normalizers/chatgpt.js.map +1 -0
  485. package/dist/replay/normalizers/claude.d.ts +6 -0
  486. package/dist/replay/normalizers/claude.js +11 -0
  487. package/dist/replay/normalizers/claude.js.map +1 -0
  488. package/dist/replay/normalizers/openclaw.d.ts +6 -0
  489. package/dist/replay/normalizers/openclaw.js +11 -0
  490. package/dist/replay/normalizers/openclaw.js.map +1 -0
  491. package/dist/replay/normalizers/shared.d.ts +16 -0
  492. package/dist/replay/normalizers/shared.js +14 -0
  493. package/dist/replay/normalizers/shared.js.map +1 -0
  494. package/dist/replay/runner.d.ts +35 -0
  495. package/dist/replay/runner.js +16 -0
  496. package/dist/replay/runner.js.map +1 -0
  497. package/dist/replay/types.d.ts +57 -0
  498. package/dist/replay/types.js +19 -0
  499. package/dist/replay/types.js.map +1 -0
  500. package/dist/resolution-B7FNQSSP.js +12 -0
  501. package/dist/resolution-B7FNQSSP.js.map +1 -0
  502. package/dist/resolve-provider-secret.js +2 -2
  503. package/dist/resume-bundles.js +8 -6
  504. package/dist/retrieval-agents.d.ts +1 -1
  505. package/dist/routing/engine.d.ts +35 -0
  506. package/dist/routing/engine.js +16 -0
  507. package/dist/routing/engine.js.map +1 -0
  508. package/dist/routing/store.d.ts +27 -0
  509. package/dist/routing/store.js +10 -0
  510. package/dist/routing/store.js.map +1 -0
  511. package/dist/runtime/better-sqlite.d.ts +8 -0
  512. package/dist/runtime/better-sqlite.js +10 -0
  513. package/dist/runtime/better-sqlite.js.map +1 -0
  514. package/dist/runtime/child-process.d.ts +32 -0
  515. package/dist/runtime/child-process.js +10 -0
  516. package/dist/runtime/child-process.js.map +1 -0
  517. package/dist/runtime/env.d.ts +5 -0
  518. package/dist/runtime/env.js +12 -0
  519. package/dist/runtime/env.js.map +1 -0
  520. package/dist/schemas.d.ts +22 -22
  521. package/dist/sdk-compat.js +1 -1
  522. package/dist/search/document-scanner.d.ts +22 -0
  523. package/dist/search/document-scanner.js +8 -0
  524. package/dist/search/document-scanner.js.map +1 -0
  525. package/dist/search/embed-helper.d.ts +35 -0
  526. package/dist/search/embed-helper.js +9 -0
  527. package/dist/search/embed-helper.js.map +1 -0
  528. package/dist/search/factory.d.ts +32 -0
  529. package/dist/search/factory.js +29 -0
  530. package/dist/search/factory.js.map +1 -0
  531. package/dist/search/index.d.ts +15 -0
  532. package/dist/search/index.js +50 -0
  533. package/dist/search/index.js.map +1 -0
  534. package/dist/search/lancedb-backend.d.ts +51 -0
  535. package/dist/search/lancedb-backend.js +10 -0
  536. package/dist/search/lancedb-backend.js.map +1 -0
  537. package/dist/search/meilisearch-backend.d.ts +48 -0
  538. package/dist/search/meilisearch-backend.js +10 -0
  539. package/dist/search/meilisearch-backend.js.map +1 -0
  540. package/dist/search/noop-backend.d.ts +26 -0
  541. package/dist/search/noop-backend.js +8 -0
  542. package/dist/search/noop-backend.js.map +1 -0
  543. package/dist/search/orama-backend.d.ts +53 -0
  544. package/dist/search/orama-backend.js +10 -0
  545. package/dist/search/orama-backend.js.map +1 -0
  546. package/dist/search/port.d.ts +61 -0
  547. package/dist/search/port.js +1 -0
  548. package/dist/search/port.js.map +1 -0
  549. package/dist/search/remote-backend.d.ts +39 -0
  550. package/dist/search/remote-backend.js +9 -0
  551. package/dist/search/remote-backend.js.map +1 -0
  552. package/dist/secure-store/index.d.ts +890 -0
  553. package/dist/secure-store/index.js +156 -0
  554. package/dist/secure-store/index.js.map +1 -0
  555. package/dist/semantic-VwGI14Ok.d.ts +69 -0
  556. package/dist/semantic-consolidation-4HkHWgeI.d.ts +180 -0
  557. package/dist/semantic-consolidation.d.ts +2 -2
  558. package/dist/semantic-consolidation.js +13 -6
  559. package/dist/semantic-rule-promotion.js +8 -5
  560. package/dist/semantic-rule-verifier.js +8 -5
  561. package/dist/shared-context/manager.d.ts +131 -0
  562. package/dist/shared-context/manager.js +15 -0
  563. package/dist/shared-context/manager.js.map +1 -0
  564. package/dist/skills-registry.js +13 -1
  565. package/dist/skills-registry.js.map +1 -1
  566. package/dist/state-store-VZU2IA53.js +16 -0
  567. package/dist/state-store-VZU2IA53.js.map +1 -0
  568. package/dist/storage-paths.d.ts +9 -0
  569. package/dist/storage-paths.js +20 -0
  570. package/dist/storage-paths.js.map +1 -0
  571. package/dist/storage.d.ts +3 -1
  572. package/dist/storage.js +7 -4
  573. package/dist/summarizer.d.ts +5 -0
  574. package/dist/summarizer.js +9 -8
  575. package/dist/summary-snapshot.js +2 -1
  576. package/dist/surfaces/dreams.d.ts +16 -0
  577. package/dist/surfaces/dreams.js +282 -0
  578. package/dist/surfaces/dreams.js.map +1 -0
  579. package/dist/surfaces/heartbeat.d.ts +17 -0
  580. package/dist/surfaces/heartbeat.js +265 -0
  581. package/dist/surfaces/heartbeat.js.map +1 -0
  582. package/dist/temporal-supersession.d.ts +3 -1
  583. package/dist/threading.d.ts +5 -0
  584. package/dist/threading.js +2 -1
  585. package/dist/tier-migration.d.ts +4 -2
  586. package/dist/tokens.js +2 -2
  587. package/dist/transcript.d.ts +15 -1
  588. package/dist/transcript.js +2 -1
  589. package/dist/transfer/autodetect.d.ts +4 -0
  590. package/dist/transfer/autodetect.js +15 -0
  591. package/dist/transfer/autodetect.js.map +1 -0
  592. package/dist/transfer/backup.d.ts +21 -0
  593. package/dist/transfer/backup.js +17 -0
  594. package/dist/transfer/backup.js.map +1 -0
  595. package/dist/transfer/capsule-export.d.ts +113 -0
  596. package/dist/transfer/capsule-export.js +19 -0
  597. package/dist/transfer/capsule-export.js.map +1 -0
  598. package/dist/transfer/capsule-import.d.ts +124 -0
  599. package/dist/transfer/capsule-import.js +16 -0
  600. package/dist/transfer/capsule-import.js.map +1 -0
  601. package/dist/transfer/constants.d.ts +13 -0
  602. package/dist/transfer/constants.js +12 -0
  603. package/dist/transfer/constants.js.map +1 -0
  604. package/dist/transfer/export-json.d.ts +11 -0
  605. package/dist/transfer/export-json.js +11 -0
  606. package/dist/transfer/export-json.js.map +1 -0
  607. package/dist/transfer/export-md.d.ts +10 -0
  608. package/dist/transfer/export-md.js +13 -0
  609. package/dist/transfer/export-md.js.map +1 -0
  610. package/dist/transfer/export-sqlite.d.ts +9 -0
  611. package/dist/transfer/export-sqlite.js +12 -0
  612. package/dist/transfer/export-sqlite.js.map +1 -0
  613. package/dist/transfer/fs-utils.d.ts +61 -0
  614. package/dist/transfer/fs-utils.js +40 -0
  615. package/dist/transfer/fs-utils.js.map +1 -0
  616. package/dist/transfer/import-json.d.ts +16 -0
  617. package/dist/transfer/import-json.js +13 -0
  618. package/dist/transfer/import-json.js.map +1 -0
  619. package/dist/transfer/import-md.d.ts +14 -0
  620. package/dist/transfer/import-md.js +11 -0
  621. package/dist/transfer/import-md.js.map +1 -0
  622. package/dist/transfer/import-sqlite.d.ts +14 -0
  623. package/dist/transfer/import-sqlite.js +12 -0
  624. package/dist/transfer/import-sqlite.js.map +1 -0
  625. package/dist/transfer/sqlite-schema.d.ts +4 -0
  626. package/dist/transfer/sqlite-schema.js +10 -0
  627. package/dist/transfer/sqlite-schema.js.map +1 -0
  628. package/dist/transfer/types.d.ts +916 -0
  629. package/dist/transfer/types.js +30 -0
  630. package/dist/transfer/types.js.map +1 -0
  631. package/dist/types.d.ts +28 -1
  632. package/dist/types.js +1 -1
  633. package/dist/verified-recall.js +9 -6
  634. package/dist/work/board.d.ts +43 -0
  635. package/dist/work/board.js +14 -0
  636. package/dist/work/board.js.map +1 -0
  637. package/dist/work/boundary.d.ts +8 -0
  638. package/dist/work/boundary.js +14 -0
  639. package/dist/work/boundary.js.map +1 -0
  640. package/dist/work/storage.d.ts +39 -0
  641. package/dist/work/storage.js +11 -0
  642. package/dist/work/storage.js.map +1 -0
  643. package/dist/work/types.d.ts +75 -0
  644. package/dist/work/types.js +1 -0
  645. package/dist/work/types.js.map +1 -0
  646. package/package.json +2767 -6
  647. package/scripts/faiss_index.py +816 -0
  648. package/scripts/faiss_requirements.txt +3 -0
  649. package/skills/remnic-entities/SKILL.md +51 -0
  650. package/skills/remnic-memory-workflow/SKILL.md +61 -0
  651. package/skills/remnic-recall/SKILL.md +51 -0
  652. package/skills/remnic-remember/SKILL.md +56 -0
  653. package/skills/remnic-search/SKILL.md +51 -0
  654. package/skills/remnic-status/SKILL.md +51 -0
  655. package/src/abort-error.test.ts +49 -0
  656. package/src/abort-error.ts +46 -0
  657. package/src/abstraction-nodes.ts +162 -0
  658. package/src/access-audit.test.ts +178 -0
  659. package/src/access-audit.ts +125 -0
  660. package/src/access-cli.test.ts +439 -0
  661. package/src/access-cli.ts +438 -0
  662. package/src/access-http.test.ts +225 -0
  663. package/src/access-http.ts +1899 -0
  664. package/src/access-idempotency.ts +232 -0
  665. package/src/access-mcp.test.ts +568 -0
  666. package/src/access-mcp.ts +3056 -0
  667. package/src/access-schema-pi.test.ts +60 -0
  668. package/src/access-schema.ts +522 -0
  669. package/src/access-service-namespace.test.ts +123 -0
  670. package/src/access-service.ts +5629 -0
  671. package/src/action-confidence.test.ts +206 -0
  672. package/src/action-confidence.ts +466 -0
  673. package/src/active-memory-bridge.test.ts +285 -0
  674. package/src/active-memory-bridge.ts +217 -0
  675. package/src/active-recall.test.ts +484 -0
  676. package/src/active-recall.ts +459 -0
  677. package/src/adapters/claude-code.ts +56 -0
  678. package/src/adapters/codex.ts +57 -0
  679. package/src/adapters/hermes.ts +64 -0
  680. package/src/adapters/index.ts +6 -0
  681. package/src/adapters/registry.ts +41 -0
  682. package/src/adapters/replit.ts +55 -0
  683. package/src/adapters/types.ts +51 -0
  684. package/src/behavior-learner.ts +144 -0
  685. package/src/behavior-signals.ts +73 -0
  686. package/src/binary-lifecycle/backend.ts +117 -0
  687. package/src/binary-lifecycle/index.ts +35 -0
  688. package/src/binary-lifecycle/manifest.ts +79 -0
  689. package/src/binary-lifecycle/pipeline.ts +352 -0
  690. package/src/binary-lifecycle/scanner.ts +89 -0
  691. package/src/binary-lifecycle/types.ts +89 -0
  692. package/src/bootstrap.ts +178 -0
  693. package/src/boxes.ts +521 -0
  694. package/src/briefing.test.ts +1535 -0
  695. package/src/briefing.ts +1382 -0
  696. package/src/buffer-session.test.ts +443 -0
  697. package/src/buffer-surprise-report.ts +176 -0
  698. package/src/buffer-surprise-telemetry.test.ts +606 -0
  699. package/src/buffer-surprise-trigger.test.ts +766 -0
  700. package/src/buffer-surprise.test.ts +339 -0
  701. package/src/buffer-surprise.ts +203 -0
  702. package/src/buffer.ts +900 -0
  703. package/src/bulk-import/cli-command.test.ts +204 -0
  704. package/src/bulk-import/index.ts +34 -0
  705. package/src/bulk-import/pipeline.test.ts +445 -0
  706. package/src/bulk-import/pipeline.ts +178 -0
  707. package/src/bulk-import/registry.test.ts +151 -0
  708. package/src/bulk-import/registry.ts +72 -0
  709. package/src/bulk-import/types.test.ts +272 -0
  710. package/src/bulk-import/types.ts +145 -0
  711. package/src/calibration.ts +394 -0
  712. package/src/capsule-cli.test.ts +398 -0
  713. package/src/capsule-cli.ts +565 -0
  714. package/src/causal-behavior.ts +308 -0
  715. package/src/causal-chain.ts +419 -0
  716. package/src/causal-consolidation.ts +370 -0
  717. package/src/causal-retrieval.ts +286 -0
  718. package/src/causal-trajectory-graph.ts +60 -0
  719. package/src/causal-trajectory.ts +303 -0
  720. package/src/chunking.ts +220 -0
  721. package/src/citations.ts +232 -0
  722. package/src/cli.ts +9403 -0
  723. package/src/codex-cli-fallback.ts +162 -0
  724. package/src/codex-thread-key.ts +1 -0
  725. package/src/coding/access-coding-context.test.ts +197 -0
  726. package/src/coding/coding-branch-scope.test.ts +281 -0
  727. package/src/coding/coding-namespace.test.ts +360 -0
  728. package/src/coding/coding-namespace.ts +412 -0
  729. package/src/coding/coding-orchestrator.test.ts +249 -0
  730. package/src/coding/git-context.test.ts +507 -0
  731. package/src/coding/git-context.ts +336 -0
  732. package/src/coding/mcp-set-coding-context.test.ts +174 -0
  733. package/src/coding/review-context.test.ts +316 -0
  734. package/src/coding/review-context.ts +349 -0
  735. package/src/coding/wire-coding-context.test.ts +468 -0
  736. package/src/commitment-ledger.test.ts +78 -0
  737. package/src/commitment-ledger.ts +337 -0
  738. package/src/compat/checks.test.ts +206 -0
  739. package/src/compat/checks.ts +716 -0
  740. package/src/compat/types.ts +33 -0
  741. package/src/compounding/engine.ts +1686 -0
  742. package/src/compounding/preference-consolidator.ts +778 -0
  743. package/src/compression-optimizer.ts +312 -0
  744. package/src/config.test.ts +930 -0
  745. package/src/config.ts +3807 -0
  746. package/src/connectors/codex/instructions.md +160 -0
  747. package/src/connectors/codex/resources/namespace-cheatsheet.md +48 -0
  748. package/src/connectors/codex-marketplace.ts +500 -0
  749. package/src/connectors/codex-materialize-runner.ts +212 -0
  750. package/src/connectors/codex-materialize.ts +983 -0
  751. package/src/connectors/coerce.ts +62 -0
  752. package/src/connectors/index.test.ts +1570 -0
  753. package/src/connectors/index.ts +3222 -0
  754. package/src/connectors/live/framework.ts +164 -0
  755. package/src/connectors/live/github.test.ts +1218 -0
  756. package/src/connectors/live/github.ts +1068 -0
  757. package/src/connectors/live/gmail.test.ts +1706 -0
  758. package/src/connectors/live/gmail.ts +1293 -0
  759. package/src/connectors/live/google-drive.test.ts +696 -0
  760. package/src/connectors/live/google-drive.ts +724 -0
  761. package/src/connectors/live/index.ts +101 -0
  762. package/src/connectors/live/live-connectors.test.ts +689 -0
  763. package/src/connectors/live/notion.test.ts +1109 -0
  764. package/src/connectors/live/notion.ts +978 -0
  765. package/src/connectors/live/registry.ts +103 -0
  766. package/src/connectors/live/state-store.ts +399 -0
  767. package/src/connectors/live/transient-errors.ts +150 -0
  768. package/src/connectors/weclone-installer.test.ts +850 -0
  769. package/src/connectors-cli.ts +513 -0
  770. package/src/console/state.test.ts +224 -0
  771. package/src/console/state.ts +514 -0
  772. package/src/console/trace.test.ts +813 -0
  773. package/src/console/trace.ts +603 -0
  774. package/src/console/tui.test.ts +582 -0
  775. package/src/console/tui.ts +508 -0
  776. package/src/consolidation-operator.ts +182 -0
  777. package/src/consolidation-provenance-check.ts +551 -0
  778. package/src/consolidation-undo.ts +718 -0
  779. package/src/contradiction/contradiction-judge.test.ts +189 -0
  780. package/src/contradiction/contradiction-judge.ts +333 -0
  781. package/src/contradiction/contradiction-review.ts +574 -0
  782. package/src/contradiction/contradiction-scan.ts +504 -0
  783. package/src/contradiction/contradiction.test.ts +2230 -0
  784. package/src/contradiction/index.ts +37 -0
  785. package/src/contradiction/resolution.ts +383 -0
  786. package/src/conversation-index/backend.ts +323 -0
  787. package/src/conversation-index/chunker.ts +47 -0
  788. package/src/conversation-index/cleanup.ts +53 -0
  789. package/src/conversation-index/faiss-adapter.ts +384 -0
  790. package/src/conversation-index/indexer.test.ts +164 -0
  791. package/src/conversation-index/indexer.ts +192 -0
  792. package/src/conversation-index/search.ts +37 -0
  793. package/src/cross-namespace-budget.test.ts +275 -0
  794. package/src/cross-namespace-budget.ts +365 -0
  795. package/src/cue-anchors.ts +163 -0
  796. package/src/curation/index.ts +544 -0
  797. package/src/dashboard-runtime.ts +337 -0
  798. package/src/day-summary.ts +122 -0
  799. package/src/dedup/index.ts +330 -0
  800. package/src/dedup/semantic.test.ts +1577 -0
  801. package/src/dedup/semantic.ts +148 -0
  802. package/src/delinearize.ts +193 -0
  803. package/src/direct-answer-wiring.test.ts +473 -0
  804. package/src/direct-answer-wiring.ts +180 -0
  805. package/src/direct-answer.test.ts +484 -0
  806. package/src/direct-answer.ts +273 -0
  807. package/src/embedding-fallback.ts +565 -0
  808. package/src/enrichment/audit.ts +89 -0
  809. package/src/enrichment/index.ts +27 -0
  810. package/src/enrichment/pipeline.ts +197 -0
  811. package/src/enrichment/provider-registry.ts +85 -0
  812. package/src/enrichment/types.ts +100 -0
  813. package/src/enrichment/web-search-provider.ts +63 -0
  814. package/src/entity-retrieval.ts +774 -0
  815. package/src/entity-schema.ts +239 -0
  816. package/src/evals.ts +1312 -0
  817. package/src/event-order-recall.test.ts +4164 -0
  818. package/src/event-order-recall.ts +2802 -0
  819. package/src/evidence-pack.test.ts +89 -0
  820. package/src/evidence-pack.ts +388 -0
  821. package/src/explicit-capture.ts +530 -0
  822. package/src/explicit-cue-recall.test.ts +3019 -0
  823. package/src/explicit-cue-recall.ts +5545 -0
  824. package/src/extraction-judge-telemetry.ts +234 -0
  825. package/src/extraction-judge-training.ts +221 -0
  826. package/src/extraction-judge.ts +846 -0
  827. package/src/extraction-timeout.test.ts +265 -0
  828. package/src/extraction.ts +2719 -0
  829. package/src/fallback-llm.test.ts +1060 -0
  830. package/src/fallback-llm.ts +918 -0
  831. package/src/focused-list-recall.test.ts +734 -0
  832. package/src/focused-list-recall.ts +1160 -0
  833. package/src/graph-dashboard-diff.ts +35 -0
  834. package/src/graph-dashboard-key.ts +5 -0
  835. package/src/graph-dashboard-parser.ts +104 -0
  836. package/src/graph-edge-reinforcement.ts +192 -0
  837. package/src/graph-events.ts +151 -0
  838. package/src/graph-recall.test.ts +164 -0
  839. package/src/graph-recall.ts +189 -0
  840. package/src/graph-retrieval.test.ts +809 -0
  841. package/src/graph-retrieval.ts +823 -0
  842. package/src/graph-snapshot.ts +329 -0
  843. package/src/graph.ts +813 -0
  844. package/src/harmonic-retrieval.ts +223 -0
  845. package/src/himem.ts +154 -0
  846. package/src/hygiene.ts +87 -0
  847. package/src/identity-continuity.ts +333 -0
  848. package/src/importance.ts +328 -0
  849. package/src/importers/base.test.ts +294 -0
  850. package/src/importers/base.ts +436 -0
  851. package/src/importers/index.ts +21 -0
  852. package/src/index.ts +1204 -0
  853. package/src/intent.ts +154 -0
  854. package/src/json-extract.ts +85 -0
  855. package/src/json-store.ts +42 -0
  856. package/src/lcm/archive.ts +617 -0
  857. package/src/lcm/dag.ts +199 -0
  858. package/src/lcm/engine.ts +645 -0
  859. package/src/lcm/index.ts +7 -0
  860. package/src/lcm/queue.test.ts +178 -0
  861. package/src/lcm/queue.ts +200 -0
  862. package/src/lcm/recall.ts +117 -0
  863. package/src/lcm/schema.ts +154 -0
  864. package/src/lcm/summarizer.ts +235 -0
  865. package/src/lcm/tools.ts +191 -0
  866. package/src/lcm-engine.test.ts +660 -0
  867. package/src/legacy-hook-compat.test.ts +20 -0
  868. package/src/legacy-hook-compat.ts +45 -0
  869. package/src/lifecycle.ts +289 -0
  870. package/src/live-connectors-runner.ts +385 -0
  871. package/src/local-llm-qos.test.ts +303 -0
  872. package/src/local-llm-thinking.test.ts +292 -0
  873. package/src/local-llm.ts +1464 -0
  874. package/src/logger.ts +49 -0
  875. package/src/maintenance/archive-observations.ts +147 -0
  876. package/src/maintenance/backup-stamp.ts +3 -0
  877. package/src/maintenance/dreams-ledger.ts +516 -0
  878. package/src/maintenance/first-start-migration.ts +362 -0
  879. package/src/maintenance/forget.test.ts +206 -0
  880. package/src/maintenance/forget.ts +126 -0
  881. package/src/maintenance/graph-edge-decay.test.ts +409 -0
  882. package/src/maintenance/graph-edge-decay.ts +394 -0
  883. package/src/maintenance/memory-governance-cron.ts +447 -0
  884. package/src/maintenance/memory-governance.ts +1039 -0
  885. package/src/maintenance/migrate-observations.ts +216 -0
  886. package/src/maintenance/observation-ledger-utils.ts +54 -0
  887. package/src/maintenance/pattern-reinforcement.test.ts +875 -0
  888. package/src/maintenance/pattern-reinforcement.ts +369 -0
  889. package/src/maintenance/purge.ts +334 -0
  890. package/src/maintenance/rebuild-memory-lifecycle-ledger.ts +78 -0
  891. package/src/maintenance/rebuild-memory-projection.ts +1234 -0
  892. package/src/maintenance/rebuild-observations.ts +178 -0
  893. package/src/maintenance/tier-stats.test.ts +378 -0
  894. package/src/maintenance/tier-stats.ts +222 -0
  895. package/src/mcp-memory-inspector-app.ts +421 -0
  896. package/src/memory-action-policy.ts +80 -0
  897. package/src/memory-cache.ts +208 -0
  898. package/src/memory-extension/claude-code-publisher.ts +51 -0
  899. package/src/memory-extension/codex-publisher.ts +149 -0
  900. package/src/memory-extension/hermes-publisher.ts +51 -0
  901. package/src/memory-extension/index.ts +100 -0
  902. package/src/memory-extension/shared-instructions.ts +133 -0
  903. package/src/memory-extension/types.ts +86 -0
  904. package/src/memory-extension-host/host-discovery.ts +276 -0
  905. package/src/memory-extension-host/index.ts +14 -0
  906. package/src/memory-extension-host/render-extensions-block.ts +73 -0
  907. package/src/memory-extension-host/types.ts +21 -0
  908. package/src/memory-lifecycle-ledger-utils.ts +116 -0
  909. package/src/memory-projection-format.ts +11 -0
  910. package/src/memory-projection-store.ts +951 -0
  911. package/src/memory-provenance.test.ts +196 -0
  912. package/src/memory-provenance.ts +484 -0
  913. package/src/memory-worth-bench.test.ts +71 -0
  914. package/src/memory-worth-bench.ts +265 -0
  915. package/src/memory-worth-filter.test.ts +209 -0
  916. package/src/memory-worth-filter.ts +204 -0
  917. package/src/memory-worth-frontmatter.test.ts +311 -0
  918. package/src/memory-worth-outcomes.test.ts +316 -0
  919. package/src/memory-worth-outcomes.ts +286 -0
  920. package/src/memory-worth.test.ts +317 -0
  921. package/src/memory-worth.ts +215 -0
  922. package/src/message-parts/index.ts +806 -0
  923. package/src/message-parts/message-parts.test.ts +421 -0
  924. package/src/migrate/from-engram.ts +789 -0
  925. package/src/model-registry.ts +313 -0
  926. package/src/models-json.ts +76 -0
  927. package/src/namespaces/migrate.ts +187 -0
  928. package/src/namespaces/path.ts +25 -0
  929. package/src/namespaces/principal.test.ts +195 -0
  930. package/src/namespaces/principal.ts +86 -0
  931. package/src/namespaces/search.test.ts +105 -0
  932. package/src/namespaces/search.ts +233 -0
  933. package/src/namespaces/storage.ts +74 -0
  934. package/src/native-knowledge.ts +1823 -0
  935. package/src/negative.ts +72 -0
  936. package/src/network/tailscale.ts +179 -0
  937. package/src/network/webdav.ts +385 -0
  938. package/src/objective-state-writers.ts +951 -0
  939. package/src/objective-state.ts +320 -0
  940. package/src/onboarding/index.ts +529 -0
  941. package/src/openai-chat-compat.ts +56 -0
  942. package/src/operator-toolkit.ts +2132 -0
  943. package/src/opik-exporter.test.ts +72 -0
  944. package/src/opik-exporter.ts +587 -0
  945. package/src/orchestrator-extraction-queue.test.ts +197 -0
  946. package/src/orchestrator-flush.test.ts +1171 -0
  947. package/src/orchestrator-pattern-reinforcement.test.ts +128 -0
  948. package/src/orchestrator-source-attribution.test.ts +701 -0
  949. package/src/orchestrator.ts +16368 -0
  950. package/src/page-versioning.ts +450 -0
  951. package/src/patterns-cli.ts +574 -0
  952. package/src/peers/index.ts +54 -0
  953. package/src/peers/migrate-from-identity-anchor.test.ts +291 -0
  954. package/src/peers/migrate-from-identity-anchor.ts +350 -0
  955. package/src/peers/peers.test.ts +419 -0
  956. package/src/peers/profile-reasoner.ts +694 -0
  957. package/src/peers/storage.ts +1350 -0
  958. package/src/peers/types.ts +138 -0
  959. package/src/plugin-id.ts +84 -0
  960. package/src/policy-runtime.ts +209 -0
  961. package/src/procedural/procedure-miner.ts +150 -0
  962. package/src/procedural/procedure-recall.ts +93 -0
  963. package/src/procedural/procedure-stats.ts +213 -0
  964. package/src/procedural/procedure-types.ts +132 -0
  965. package/src/procedural/reinforcement-core.test.ts +132 -0
  966. package/src/procedural/reinforcement-core.ts +73 -0
  967. package/src/profiling.test.ts +263 -0
  968. package/src/profiling.ts +435 -0
  969. package/src/projection/index.ts +398 -0
  970. package/src/qmd-recall-cache.test.ts +138 -0
  971. package/src/qmd-recall-cache.ts +111 -0
  972. package/src/qmd.test.ts +258 -0
  973. package/src/qmd.ts +2614 -0
  974. package/src/reasoning-trace-recall.ts +201 -0
  975. package/src/reasoning-trace-types.ts +235 -0
  976. package/src/recall-audit-anomaly.test.ts +246 -0
  977. package/src/recall-audit-anomaly.ts +297 -0
  978. package/src/recall-audit.test.ts +51 -0
  979. package/src/recall-audit.ts +72 -0
  980. package/src/recall-budget-config.test.ts +87 -0
  981. package/src/recall-disclosure-escalation.test.ts +196 -0
  982. package/src/recall-disclosure-escalation.ts +158 -0
  983. package/src/recall-disclosure-shaping.test.ts +146 -0
  984. package/src/recall-disclosure.test.ts +214 -0
  985. package/src/recall-explain-renderer.test.ts +140 -0
  986. package/src/recall-explain-renderer.ts +356 -0
  987. package/src/recall-mmr.test.ts +808 -0
  988. package/src/recall-mmr.ts +607 -0
  989. package/src/recall-qos.test.ts +85 -0
  990. package/src/recall-qos.ts +82 -0
  991. package/src/recall-query-policy.ts +221 -0
  992. package/src/recall-state.test.ts +233 -0
  993. package/src/recall-state.ts +456 -0
  994. package/src/recall-tag-filter.ts +143 -0
  995. package/src/recall-tokenization.ts +35 -0
  996. package/src/recall-xray-cli.test.ts +118 -0
  997. package/src/recall-xray-cli.ts +100 -0
  998. package/src/recall-xray-disclosure-telemetry.test.ts +183 -0
  999. package/src/recall-xray-renderer.test.ts +539 -0
  1000. package/src/recall-xray-renderer.ts +487 -0
  1001. package/src/recall-xray.test.ts +503 -0
  1002. package/src/recall-xray.ts +621 -0
  1003. package/src/reconstruct.ts +41 -0
  1004. package/src/release-changelog.ts +35 -0
  1005. package/src/relevance.ts +67 -0
  1006. package/src/replay/normalizers/chatgpt.ts +133 -0
  1007. package/src/replay/normalizers/claude.ts +102 -0
  1008. package/src/replay/normalizers/openclaw.ts +119 -0
  1009. package/src/replay/normalizers/shared.ts +69 -0
  1010. package/src/replay/runner.ts +197 -0
  1011. package/src/replay/types.ts +143 -0
  1012. package/src/rerank.test.ts +48 -0
  1013. package/src/rerank.ts +176 -0
  1014. package/src/resolve-auth-token.test.ts +226 -0
  1015. package/src/resolve-auth-token.ts +151 -0
  1016. package/src/resolve-provider-secret.test.ts +187 -0
  1017. package/src/resolve-provider-secret.ts +410 -0
  1018. package/src/response-guidance-recall.test.ts +3952 -0
  1019. package/src/response-guidance-recall.ts +4431 -0
  1020. package/src/resume-bundles.ts +415 -0
  1021. package/src/retrieval-agents.ts +623 -0
  1022. package/src/retrieval-tiers.ts +25 -0
  1023. package/src/retrieval.ts +104 -0
  1024. package/src/review/index.test.ts +201 -0
  1025. package/src/review/index.ts +536 -0
  1026. package/src/routing/engine.ts +162 -0
  1027. package/src/routing/store.ts +321 -0
  1028. package/src/runtime/better-sqlite.test.ts +32 -0
  1029. package/src/runtime/better-sqlite.ts +76 -0
  1030. package/src/runtime/child-process.ts +67 -0
  1031. package/src/runtime/env.ts +48 -0
  1032. package/src/sanitize.ts +58 -0
  1033. package/src/schemas.ts +449 -0
  1034. package/src/sdk-compat.ts +87 -0
  1035. package/src/search/document-scanner.ts +96 -0
  1036. package/src/search/embed-helper.ts +142 -0
  1037. package/src/search/factory.ts +189 -0
  1038. package/src/search/index.ts +10 -0
  1039. package/src/search/lancedb-backend.ts +342 -0
  1040. package/src/search/meilisearch-backend.ts +232 -0
  1041. package/src/search/noop-backend.ts +57 -0
  1042. package/src/search/orama-backend.ts +358 -0
  1043. package/src/search/port.ts +86 -0
  1044. package/src/search/remote-backend.ts +124 -0
  1045. package/src/secure-store/cipher.ts +271 -0
  1046. package/src/secure-store/cli-handlers.ts +355 -0
  1047. package/src/secure-store/cli-renderer.ts +131 -0
  1048. package/src/secure-store/header.ts +373 -0
  1049. package/src/secure-store/index.ts +137 -0
  1050. package/src/secure-store/kdf.ts +263 -0
  1051. package/src/secure-store/keyring.ts +106 -0
  1052. package/src/secure-store/metadata.ts +394 -0
  1053. package/src/secure-store/passphrase-reader.ts +252 -0
  1054. package/src/secure-store/secure-fs.ts +571 -0
  1055. package/src/secure-store/secure-store.test.ts +755 -0
  1056. package/src/semantic-chunking.ts +545 -0
  1057. package/src/semantic-consolidation.test.ts +182 -0
  1058. package/src/semantic-consolidation.ts +432 -0
  1059. package/src/semantic-rule-promotion.ts +183 -0
  1060. package/src/semantic-rule-verifier.ts +160 -0
  1061. package/src/session-integrity.ts +569 -0
  1062. package/src/session-observer-bands.ts +11 -0
  1063. package/src/session-observer-state.ts +346 -0
  1064. package/src/session-toggles.test.ts +96 -0
  1065. package/src/session-toggles.ts +159 -0
  1066. package/src/shared-context/manager.ts +810 -0
  1067. package/src/signal.ts +84 -0
  1068. package/src/skills-registry.test.ts +277 -0
  1069. package/src/skills-registry.ts +120 -0
  1070. package/src/source-attribution-roundtrip.test.ts +215 -0
  1071. package/src/source-attribution.test.ts +1425 -0
  1072. package/src/source-attribution.ts +639 -0
  1073. package/src/spaces/index.ts +627 -0
  1074. package/src/storage-paths.ts +117 -0
  1075. package/src/storage.ts +6657 -0
  1076. package/src/store-contract.ts +55 -0
  1077. package/src/summarizer.ts +844 -0
  1078. package/src/summary-snapshot.test.ts +681 -0
  1079. package/src/summary-snapshot.ts +238 -0
  1080. package/src/surfaces/dreams.test.ts +394 -0
  1081. package/src/surfaces/dreams.ts +346 -0
  1082. package/src/surfaces/heartbeat.test.ts +415 -0
  1083. package/src/surfaces/heartbeat.ts +325 -0
  1084. package/src/sync/index.ts +308 -0
  1085. package/src/targeted-fact-recall.test.ts +1694 -0
  1086. package/src/targeted-fact-recall.ts +2905 -0
  1087. package/src/taxonomy/default-taxonomy.ts +87 -0
  1088. package/src/taxonomy/index.ts +26 -0
  1089. package/src/taxonomy/resolver-doc-generator.ts +57 -0
  1090. package/src/taxonomy/resolver.ts +184 -0
  1091. package/src/taxonomy/taxonomy-loader.ts +186 -0
  1092. package/src/taxonomy/types.ts +48 -0
  1093. package/src/telemetry-transcript.ts +70 -0
  1094. package/src/temporal-index.ts +890 -0
  1095. package/src/temporal-supersession.test.ts +2703 -0
  1096. package/src/temporal-supersession.ts +493 -0
  1097. package/src/temporal-validity.test.ts +448 -0
  1098. package/src/temporal-validity.ts +123 -0
  1099. package/src/threading.ts +395 -0
  1100. package/src/tier-migration.ts +124 -0
  1101. package/src/tier-routing.ts +102 -0
  1102. package/src/tmt.ts +462 -0
  1103. package/src/tokens.test.ts +178 -0
  1104. package/src/tokens.ts +279 -0
  1105. package/src/topics.ts +147 -0
  1106. package/src/training-export/cli-date-validation.test.ts +258 -0
  1107. package/src/training-export/converter.test.ts +452 -0
  1108. package/src/training-export/converter.ts +319 -0
  1109. package/src/training-export/date-parse.ts +117 -0
  1110. package/src/training-export/index.ts +26 -0
  1111. package/src/training-export/registry.test.ts +85 -0
  1112. package/src/training-export/registry.ts +57 -0
  1113. package/src/training-export/types.ts +31 -0
  1114. package/src/transcript.ts +1179 -0
  1115. package/src/transfer/autodetect.ts +30 -0
  1116. package/src/transfer/backup.ts +138 -0
  1117. package/src/transfer/capsule-crypto.ts +485 -0
  1118. package/src/transfer/capsule-encrypt.test.ts +690 -0
  1119. package/src/transfer/capsule-export.ts +543 -0
  1120. package/src/transfer/capsule-fork.ts +375 -0
  1121. package/src/transfer/capsule-import.ts +564 -0
  1122. package/src/transfer/capsule-merge.ts +433 -0
  1123. package/src/transfer/conflict-policy.ts +16 -0
  1124. package/src/transfer/constants.ts +13 -0
  1125. package/src/transfer/exclusions.ts +37 -0
  1126. package/src/transfer/export-json.ts +65 -0
  1127. package/src/transfer/export-md.ts +59 -0
  1128. package/src/transfer/export-sqlite.ts +52 -0
  1129. package/src/transfer/fs-utils.ts +269 -0
  1130. package/src/transfer/import-json.ts +108 -0
  1131. package/src/transfer/import-md.ts +84 -0
  1132. package/src/transfer/import-sqlite.ts +100 -0
  1133. package/src/transfer/integrity.ts +71 -0
  1134. package/src/transfer/sqlite-schema.ts +16 -0
  1135. package/src/transfer/types.ts +297 -0
  1136. package/src/trust-zones.ts +1186 -0
  1137. package/src/types.ts +3074 -0
  1138. package/src/user-model.test.ts +124 -0
  1139. package/src/user-model.ts +162 -0
  1140. package/src/utility-learner.ts +353 -0
  1141. package/src/utility-runtime.ts +88 -0
  1142. package/src/utility-telemetry.ts +215 -0
  1143. package/src/utils/category-dir.ts +44 -0
  1144. package/src/utils/errno.ts +6 -0
  1145. package/src/utils/iso-timestamp.test.ts +37 -0
  1146. package/src/utils/iso-timestamp.ts +164 -0
  1147. package/src/utils/path.ts +26 -0
  1148. package/src/verified-recall.ts +138 -0
  1149. package/src/version-utils.test.ts +10 -0
  1150. package/src/version-utils.ts +9 -0
  1151. package/src/whitespace.ts +10 -0
  1152. package/src/work/board.ts +359 -0
  1153. package/src/work/boundary.ts +107 -0
  1154. package/src/work/storage.ts +436 -0
  1155. package/src/work/types.ts +82 -0
  1156. package/src/work-product-ledger.ts +265 -0
  1157. package/dist/access-service-DDjzFALq.d.ts +0 -2088
  1158. package/dist/capsule-crypto-SJS5VVAP.js +0 -18
  1159. package/dist/capsule-export-7QNCBZOQ.js +0 -17
  1160. package/dist/capsule-import-EPBHD2EN.js +0 -16
  1161. package/dist/capsule-merge-DI7PNQ2H.js +0 -189
  1162. package/dist/chunk-23ZZK64Y.js +0 -26
  1163. package/dist/chunk-23ZZK64Y.js.map +0 -1
  1164. package/dist/chunk-242S3I2A.js +0 -647
  1165. package/dist/chunk-2LGMW3DJ.js +0 -111
  1166. package/dist/chunk-3B6KIRBH.js +0 -5213
  1167. package/dist/chunk-3B6KIRBH.js.map +0 -1
  1168. package/dist/chunk-457A4P3L.js +0 -119
  1169. package/dist/chunk-457A4P3L.js.map +0 -1
  1170. package/dist/chunk-4IS4SXIQ.js +0 -2040
  1171. package/dist/chunk-4YM32CRU.js +0 -721
  1172. package/dist/chunk-6TBWYBJ3.js +0 -236
  1173. package/dist/chunk-74EMIVE4.js +0 -329
  1174. package/dist/chunk-74EMIVE4.js.map +0 -1
  1175. package/dist/chunk-767ODGE6.js +0 -183
  1176. package/dist/chunk-7V22HTMD.js +0 -623
  1177. package/dist/chunk-7V22HTMD.js.map +0 -1
  1178. package/dist/chunk-7ZM3BFKK.js +0 -9705
  1179. package/dist/chunk-7ZM3BFKK.js.map +0 -1
  1180. package/dist/chunk-AQJNPMOA.js +0 -643
  1181. package/dist/chunk-AQJNPMOA.js.map +0 -1
  1182. package/dist/chunk-ASAITVLA.js +0 -64
  1183. package/dist/chunk-ASAITVLA.js.map +0 -1
  1184. package/dist/chunk-BBE34QBJ.js +0 -275
  1185. package/dist/chunk-BBE34QBJ.js.map +0 -1
  1186. package/dist/chunk-BZSQEPRW.js +0 -14710
  1187. package/dist/chunk-BZSQEPRW.js.map +0 -1
  1188. package/dist/chunk-CPKTBRS2.js +0 -891
  1189. package/dist/chunk-CPKTBRS2.js.map +0 -1
  1190. package/dist/chunk-D4GAOFF6.js +0 -562
  1191. package/dist/chunk-D4GAOFF6.js.map +0 -1
  1192. package/dist/chunk-D54LZC5L.js +0 -147
  1193. package/dist/chunk-DF3RVK3X.js +0 -119
  1194. package/dist/chunk-DF3RVK3X.js.map +0 -1
  1195. package/dist/chunk-DZZPC36E.js +0 -1451
  1196. package/dist/chunk-DZZPC36E.js.map +0 -1
  1197. package/dist/chunk-E2UCDP5S.js +0 -570
  1198. package/dist/chunk-E6K4NIEU.js +0 -747
  1199. package/dist/chunk-E6K4NIEU.js.map +0 -1
  1200. package/dist/chunk-EEQLFRUM.js +0 -89
  1201. package/dist/chunk-ETOW6ACV.js +0 -158
  1202. package/dist/chunk-ETOW6ACV.js.map +0 -1
  1203. package/dist/chunk-FMEBPEAO.js +0 -347
  1204. package/dist/chunk-FMEBPEAO.js.map +0 -1
  1205. package/dist/chunk-FQDPCE3I.js +0 -1837
  1206. package/dist/chunk-FQDPCE3I.js.map +0 -1
  1207. package/dist/chunk-FYIYMQ5N.js +0 -221
  1208. package/dist/chunk-FYIYMQ5N.js.map +0 -1
  1209. package/dist/chunk-G2WADRQ3.js +0 -219
  1210. package/dist/chunk-G4SK7DSQ.js +0 -121
  1211. package/dist/chunk-GVPWB7EY.js +0 -390
  1212. package/dist/chunk-GVPWB7EY.js.map +0 -1
  1213. package/dist/chunk-HELQZFZO.js +0 -1075
  1214. package/dist/chunk-HL5LRPNA.js +0 -1914
  1215. package/dist/chunk-HL5LRPNA.js.map +0 -1
  1216. package/dist/chunk-HQZVVSVB.js +0 -147
  1217. package/dist/chunk-HQZVVSVB.js.map +0 -1
  1218. package/dist/chunk-HY3L4WKC.js +0 -2195
  1219. package/dist/chunk-HY3L4WKC.js.map +0 -1
  1220. package/dist/chunk-IB3BFHGN.js +0 -228
  1221. package/dist/chunk-IXEJRKCZ.js +0 -18
  1222. package/dist/chunk-JBMSGZEQ.js +0 -441
  1223. package/dist/chunk-JBMSGZEQ.js.map +0 -1
  1224. package/dist/chunk-JESOB2HO.js +0 -108
  1225. package/dist/chunk-JKDVIE52.js +0 -272
  1226. package/dist/chunk-JRNQ3RNA.js +0 -284
  1227. package/dist/chunk-JRNQ3RNA.js.map +0 -1
  1228. package/dist/chunk-K6WK37A6.js +0 -865
  1229. package/dist/chunk-K6WK37A6.js.map +0 -1
  1230. package/dist/chunk-MARWOCVP.js +0 -48
  1231. package/dist/chunk-MNU6ZBWT.js +0 -4454
  1232. package/dist/chunk-MNU6ZBWT.js.map +0 -1
  1233. package/dist/chunk-N5AKDXAI.js +0 -74
  1234. package/dist/chunk-OA3L7BFR.js +0 -183
  1235. package/dist/chunk-OA3L7BFR.js.map +0 -1
  1236. package/dist/chunk-OR64ZGRZ.js +0 -23
  1237. package/dist/chunk-P77UEOU2.js +0 -1521
  1238. package/dist/chunk-P77UEOU2.js.map +0 -1
  1239. package/dist/chunk-PH4C2U43.js +0 -239
  1240. package/dist/chunk-PH4C2U43.js.map +0 -1
  1241. package/dist/chunk-RVPLBATS.js +0 -1586
  1242. package/dist/chunk-RVPLBATS.js.map +0 -1
  1243. package/dist/chunk-U5JMRGKX.js +0 -340
  1244. package/dist/chunk-U5JMRGKX.js.map +0 -1
  1245. package/dist/chunk-URB2WSKZ.js +0 -350
  1246. package/dist/chunk-URB2WSKZ.js.map +0 -1
  1247. package/dist/chunk-UVMUAWVT.js +0 -596
  1248. package/dist/chunk-WEJG4TB5.js +0 -118
  1249. package/dist/chunk-X7HPGUVG.js +0 -271
  1250. package/dist/chunk-XAMBKFQS.js +0 -2777
  1251. package/dist/chunk-XAMBKFQS.js.map +0 -1
  1252. package/dist/chunk-XJKFSSDW.js +0 -726
  1253. package/dist/chunk-XJKFSSDW.js.map +0 -1
  1254. package/dist/chunk-XMHBH5H6.js +0 -283
  1255. package/dist/chunk-XMHBH5H6.js.map +0 -1
  1256. package/dist/chunk-XMVFHBHT.js +0 -277
  1257. package/dist/chunk-Y3VMVTYX.js +0 -53
  1258. package/dist/chunk-YNB73F22.js +0 -137
  1259. package/dist/chunk-YNB73F22.js.map +0 -1
  1260. package/dist/chunk-Z2E7VW55.js +0 -335
  1261. package/dist/chunk-Z2E7VW55.js.map +0 -1
  1262. package/dist/chunk-ZG7PTKBK.js +0 -2296
  1263. package/dist/chunk-ZNQN6ZTA.js +0 -135
  1264. package/dist/chunk-ZVTKDVVM.js +0 -827
  1265. package/dist/chunk-ZVTKDVVM.js.map +0 -1
  1266. package/dist/cli-BR8KpIU0.d.ts +0 -1259
  1267. package/dist/codex-materialize-CQlLTzke.d.ts +0 -139
  1268. package/dist/connectors-cli-DFGtY2DB.d.ts +0 -257
  1269. package/dist/contradiction-review-5LTTVDQV.js +0 -22
  1270. package/dist/contradiction-scan-QTXAMBUA.js +0 -414
  1271. package/dist/contradiction-scan-QTXAMBUA.js.map +0 -1
  1272. package/dist/engine-35M5BKQ7.js +0 -28
  1273. package/dist/fs-utils-IRVUFB6G.js +0 -30
  1274. package/dist/graph-edge-decay-PWB63GRE.js +0 -207
  1275. package/dist/memory-governance-IMPQZXFC.js +0 -37
  1276. package/dist/memory-projection-store-CY8TU40w.d.ts +0 -222
  1277. package/dist/orchestrator-DDMPqU6R.d.ts +0 -1792
  1278. package/dist/path-RMTY5Y5A.js +0 -9
  1279. package/dist/port-B6VEDIkC.d.ts +0 -53
  1280. package/dist/resolution-YGIBORXI.js +0 -101
  1281. package/dist/resolution-YGIBORXI.js.map +0 -1
  1282. package/dist/secure-store-4R2GSO7S.js +0 -156
  1283. package/dist/semantic-consolidation-ByBXb-sf.d.ts +0 -180
  1284. package/dist/state-store-3EH7HYIN.js +0 -16
  1285. package/dist/types-V3FJ26TF.js +0 -30
  1286. /package/dist/{capsule-crypto-SJS5VVAP.js.map → adapters/claude-code.js.map} +0 -0
  1287. /package/dist/{capsule-export-7QNCBZOQ.js.map → adapters/codex.js.map} +0 -0
  1288. /package/dist/{capsule-import-EPBHD2EN.js.map → adapters/hermes.js.map} +0 -0
  1289. /package/dist/{contradiction-review-5LTTVDQV.js.map → adapters/index.js.map} +0 -0
  1290. /package/dist/{engine-35M5BKQ7.js.map → adapters/registry.js.map} +0 -0
  1291. /package/dist/{fs-utils-IRVUFB6G.js.map → adapters/replit.js.map} +0 -0
  1292. /package/dist/{memory-governance-IMPQZXFC.js.map → adapters/types.js.map} +0 -0
  1293. /package/dist/{path-RMTY5Y5A.js.map → capsule-crypto-5CYAGVC5.js.map} +0 -0
  1294. /package/dist/{capsule-merge-DI7PNQ2H.js.map → capsule-merge-4MGKE7C5.js.map} +0 -0
  1295. /package/dist/{chunk-G4SK7DSQ.js.map → chunk-2WWLHTZY.js.map} +0 -0
  1296. /package/dist/{chunk-X7HPGUVG.js.map → chunk-4CRG46BG.js.map} +0 -0
  1297. /package/dist/{chunk-UVMUAWVT.js.map → chunk-7IASACLB.js.map} +0 -0
  1298. /package/dist/{chunk-HELQZFZO.js.map → chunk-EDTHC6UD.js.map} +0 -0
  1299. /package/dist/{chunk-4YM32CRU.js.map → chunk-EFJ3MQ4V.js.map} +0 -0
  1300. /package/dist/{chunk-E2UCDP5S.js.map → chunk-FBYESMQ2.js.map} +0 -0
  1301. /package/dist/{chunk-D54LZC5L.js.map → chunk-FDU6HUUL.js.map} +0 -0
  1302. /package/dist/{chunk-IB3BFHGN.js.map → chunk-GGKRUQOO.js.map} +0 -0
  1303. /package/dist/{chunk-242S3I2A.js.map → chunk-GL6I6MEQ.js.map} +0 -0
  1304. /package/dist/{secure-store-4R2GSO7S.js.map → chunk-HHLLAQGZ.js.map} +0 -0
  1305. /package/dist/{chunk-4IS4SXIQ.js.map → chunk-HXXBL2KD.js.map} +0 -0
  1306. /package/dist/{chunk-767ODGE6.js.map → chunk-KNKUID7G.js.map} +0 -0
  1307. /package/dist/{chunk-6TBWYBJ3.js.map → chunk-LPMVBPA3.js.map} +0 -0
  1308. /package/dist/{chunk-WEJG4TB5.js.map → chunk-MC26UJIM.js.map} +0 -0
  1309. /package/dist/{chunk-JKDVIE52.js.map → chunk-MGKYQQYF.js.map} +0 -0
  1310. /package/dist/{chunk-Y3VMVTYX.js.map → chunk-MT4HVDUZ.js.map} +0 -0
  1311. /package/dist/{chunk-G2WADRQ3.js.map → chunk-MY6TPVXW.js.map} +0 -0
  1312. /package/dist/{chunk-OR64ZGRZ.js.map → chunk-NNVTUXEB.js.map} +0 -0
  1313. /package/dist/{chunk-JESOB2HO.js.map → chunk-P4NEIHUT.js.map} +0 -0
  1314. /package/dist/{chunk-IXEJRKCZ.js.map → chunk-QRNI5JBH.js.map} +0 -0
  1315. /package/dist/{chunk-EEQLFRUM.js.map → chunk-RRF5UOBJ.js.map} +0 -0
  1316. /package/dist/{state-store-3EH7HYIN.js.map → chunk-SEDEKFYQ.js.map} +0 -0
  1317. /package/dist/{chunk-2LGMW3DJ.js.map → chunk-U3PN77QT.js.map} +0 -0
  1318. /package/dist/{chunk-XMVFHBHT.js.map → chunk-U3WSW6PZ.js.map} +0 -0
  1319. /package/dist/{chunk-N5AKDXAI.js.map → chunk-UWVJF25J.js.map} +0 -0
  1320. /package/dist/{types-V3FJ26TF.js.map → chunk-V5OCT34X.js.map} +0 -0
  1321. /package/dist/{chunk-ZG7PTKBK.js.map → chunk-W3LR522O.js.map} +0 -0
  1322. /package/dist/{chunk-MARWOCVP.js.map → chunk-XIG5PDM7.js.map} +0 -0
  1323. /package/dist/{chunk-ZNQN6ZTA.js.map → chunk-XVZ7B3HG.js.map} +0 -0
  1324. /package/dist/{graph-edge-decay-PWB63GRE.js.map → graph-edge-decay-5DI5GUNL.js.map} +0 -0
@@ -0,0 +1,1464 @@
1
+ import { log } from "./logger.js";
2
+ import type { PluginConfig } from "./types.js";
3
+ import fs from "node:fs";
4
+ import os from "node:os";
5
+ import type { ModelRegistry } from "./model-registry.js";
6
+ import { launchProcessSync } from "./runtime/child-process.js";
7
+ import { mergeEnv, readEnvVar } from "./runtime/env.js";
8
+
9
+ /** Trim trailing slash characters without backtracking regex. */
10
+ function trimTrailingSlashes(s: string): string {
11
+ let end = s.length;
12
+ while (end > 0 && s[end - 1] === "/") end--;
13
+ return s.substring(0, end);
14
+ }
15
+
16
+ function stripTrailingV1Path(s: string): string {
17
+ return s.endsWith("/v1") ? s.slice(0, -3) : s;
18
+ }
19
+
20
+ function explicitPortFromUrl(s: string): number | null {
21
+ try {
22
+ const parsed = new URL(s);
23
+ if (!parsed.port) return null;
24
+ const port = Number(parsed.port);
25
+ return Number.isInteger(port) ? port : null;
26
+ } catch {
27
+ return null;
28
+ }
29
+ }
30
+
31
+ function isObjectRecord(value: unknown): value is Record<string, unknown> {
32
+ return typeof value === "object" && value !== null;
33
+ }
34
+
35
+ function isLlamaCppPropsResponse(value: unknown): boolean {
36
+ return (
37
+ isObjectRecord(value) &&
38
+ isObjectRecord(value.default_generation_settings) &&
39
+ typeof value.total_slots === "number" &&
40
+ (
41
+ typeof value.model_path === "string" ||
42
+ typeof value.chat_template === "string" ||
43
+ typeof value.build_info === "string"
44
+ )
45
+ );
46
+ }
47
+
48
+ function isLlamaCppModelsResponse(value: unknown): boolean {
49
+ if (!isObjectRecord(value) || !Array.isArray(value.data)) {
50
+ return false;
51
+ }
52
+ return value.data.some((entry) => {
53
+ if (!isObjectRecord(entry)) return false;
54
+ if (entry.owned_by === "llamacpp") return true;
55
+ if (typeof entry.id === "string" && entry.id.endsWith(".gguf")) return true;
56
+ const meta = entry.meta;
57
+ return (
58
+ isObjectRecord(meta) &&
59
+ ("n_ctx_train" in meta || "n_params" in meta || "vocab_type" in meta)
60
+ );
61
+ });
62
+ }
63
+
64
+ function isLmStudioApiV1ModelsResponse(value: unknown): boolean {
65
+ if (!isObjectRecord(value) || !Array.isArray(value.models)) {
66
+ return false;
67
+ }
68
+ return value.models.some((entry) => {
69
+ if (!isObjectRecord(entry)) return false;
70
+ return (
71
+ typeof entry.key === "string" &&
72
+ typeof entry.display_name === "string" &&
73
+ (
74
+ typeof entry.format === "string" ||
75
+ typeof entry.max_context_length === "number" ||
76
+ Array.isArray(entry.loaded_instances)
77
+ )
78
+ );
79
+ });
80
+ }
81
+
82
+ function isLmStudioApiV0ModelsResponse(value: unknown): boolean {
83
+ if (!isObjectRecord(value) || !Array.isArray(value.data)) {
84
+ return false;
85
+ }
86
+ return value.data.some((entry) => {
87
+ if (!isObjectRecord(entry)) return false;
88
+ return (
89
+ typeof entry.id === "string" &&
90
+ typeof entry.publisher === "string" &&
91
+ (
92
+ typeof entry.compatibility_type === "string" ||
93
+ typeof entry.max_context_length === "number" ||
94
+ typeof entry.state === "string"
95
+ )
96
+ );
97
+ });
98
+ }
99
+
100
+ function isLmStudioNativeModelsResponse(value: unknown): boolean {
101
+ return isLmStudioApiV1ModelsResponse(value) || isLmStudioApiV0ModelsResponse(value);
102
+ }
103
+
104
+ /**
105
+ * Local LLM client for OpenAI-compatible endpoints (LM Studio, Ollama, MLX, etc.)
106
+ *
107
+ * Based on openclaw-tactician's provider detection patterns for consistency.
108
+ * Provides privacy-preserving, cost-effective LLM operations with
109
+ * graceful fallback to cloud providers when local LLM is unavailable.
110
+ */
111
+ export type LocalLlmType = "lmstudio" | "ollama" | "mlx" | "vllm" | "llamacpp" | "generic";
112
+
113
+ /**
114
+ * Backends known to honor `chat_template_kwargs: { enable_thinking: false }`
115
+ * on OpenAI-compatible `/v1/chat/completions`. LM Studio, vLLM, and
116
+ * llama.cpp forward this field to the jinja chat template, where thinking-capable
117
+ * models (Qwen 3.5, Gemma 4, DeepSeek) suppress reasoning tokens.
118
+ *
119
+ * Strict OpenAI-compatible backends (standard OpenAI, Azure OpenAI, some
120
+ * proxies) reject unknown request fields with 400 — which trips the
121
+ * `localLlm400*` cooldown path. `LocalLlmClient` therefore only injects
122
+ * the kwarg when the detected backend is in this set; unknown / `generic`
123
+ * / `ollama` / `mlx` fail open (no injection, no 400 risk). Issue #548.
124
+ */
125
+ const THINKING_COMPATIBLE_BACKENDS: ReadonlySet<LocalLlmType> = new Set([
126
+ "lmstudio",
127
+ "vllm",
128
+ "llamacpp",
129
+ ]);
130
+
131
+ const THINKING_SUPPRESSED_OPERATIONS: ReadonlySet<string> = new Set([
132
+ "extraction",
133
+ "extraction-judge",
134
+ "contradiction-judge",
135
+ "contradiction_verification",
136
+ "link_suggestion",
137
+ "memory_summarization",
138
+ "proactive_extraction",
139
+ "lcm-summarize",
140
+ "day_summary",
141
+ "hourly_summary",
142
+ "hourly_summary_extended",
143
+ ]);
144
+
145
+ interface LocalServerConfig {
146
+ type: LocalLlmType;
147
+ defaultPort: number;
148
+ healthEndpoint: string;
149
+ modelsEndpoint: string;
150
+ detectFn: (response: unknown) => boolean;
151
+ }
152
+
153
+ const LOCAL_SERVERS: LocalServerConfig[] = [
154
+ {
155
+ type: "ollama",
156
+ defaultPort: 11434,
157
+ healthEndpoint: "/",
158
+ modelsEndpoint: "/api/tags",
159
+ detectFn: (resp) => typeof resp === "string" && resp.includes("Ollama"),
160
+ },
161
+ {
162
+ type: "llamacpp",
163
+ defaultPort: 8080,
164
+ healthEndpoint: "/health",
165
+ modelsEndpoint: "/v1/models",
166
+ detectFn: (resp) => isObjectRecord(resp) && resp.status === "ok",
167
+ },
168
+ {
169
+ type: "mlx",
170
+ defaultPort: 8080,
171
+ healthEndpoint: "/v1/models",
172
+ modelsEndpoint: "/v1/models",
173
+ detectFn: (resp) => isObjectRecord(resp) && Array.isArray(resp.data),
174
+ },
175
+ {
176
+ type: "lmstudio",
177
+ defaultPort: 1234,
178
+ healthEndpoint: "/v1/models",
179
+ modelsEndpoint: "/v1/models",
180
+ detectFn: (resp) => isObjectRecord(resp) && Array.isArray(resp.data),
181
+ },
182
+ {
183
+ type: "vllm",
184
+ defaultPort: 8000,
185
+ healthEndpoint: "/health",
186
+ modelsEndpoint: "/v1/models",
187
+ detectFn: (resp) => resp === "" || (isObjectRecord(resp) && !("status" in resp)),
188
+ },
189
+ ];
190
+
191
+ function orderedLocalServers(configuredBaseUrl: string): LocalServerConfig[] {
192
+ const configuredPort = explicitPortFromUrl(configuredBaseUrl);
193
+ if (configuredPort === null) return LOCAL_SERVERS;
194
+ const matching = LOCAL_SERVERS.filter(
195
+ (serverConfig) => serverConfig.defaultPort === configuredPort,
196
+ );
197
+ if (matching.length === 0) return LOCAL_SERVERS;
198
+ const matchingTypes = new Set(matching.map((serverConfig) => serverConfig.type));
199
+ return [
200
+ ...matching,
201
+ ...LOCAL_SERVERS.filter((serverConfig) => !matchingTypes.has(serverConfig.type)),
202
+ ];
203
+ }
204
+
205
+ export interface LocalModelInfo {
206
+ id: string;
207
+ contextWindow?: number;
208
+ maxTokens?: number;
209
+ }
210
+
211
+ export type LocalLlmRequestPriority = "recall-critical" | "background";
212
+
213
+ interface LocalLlmChatCompletionOptions {
214
+ temperature?: number;
215
+ maxTokens?: number;
216
+ responseFormat?: { type: string };
217
+ timeoutMs?: number;
218
+ operation?: string;
219
+ forceDisableThinking?: boolean;
220
+ priority?: LocalLlmRequestPriority;
221
+ }
222
+
223
+ interface LocalLlmQueuedRequest {
224
+ messages: Array<{ role: string; content: string }>;
225
+ options: LocalLlmChatCompletionOptions;
226
+ priority: LocalLlmRequestPriority;
227
+ enqueuedAtMs: number;
228
+ resolve: (value: LocalLlmChatCompletionResult | null) => void;
229
+ }
230
+
231
+ interface LocalLlmChatCompletionResult {
232
+ content: string;
233
+ usage?: { promptTokens: number; completionTokens: number; totalTokens: number };
234
+ }
235
+
236
+ const LOCAL_LLM_GLOBAL_BACKEND_STATE = "__openclawEngramLocalLlmBackendState";
237
+
238
+ type LocalLlmBackendState = {
239
+ untilMs: number;
240
+ reason: string;
241
+ };
242
+ export class LocalLlmClient {
243
+ private config: PluginConfig;
244
+ private isAvailable: boolean | null = null;
245
+ private lastHealthCheck: number = 0;
246
+ private detectedType: LocalLlmType | null = null;
247
+ private cachedModelInfo: LocalModelInfo | null = null;
248
+ private cachedLmsContext: number | null = null;
249
+ private lastLmsCheck: number = 0;
250
+ private consecutive400s: number = 0;
251
+ private cooldownUntilMs: number = 0;
252
+ private modelRegistry?: ModelRegistry;
253
+ private _disableThinking: boolean = false;
254
+ private readonly requestQueues: Record<LocalLlmRequestPriority, LocalLlmQueuedRequest[]> = {
255
+ "recall-critical": [],
256
+ background: [],
257
+ };
258
+ private readonly queueProcessing = new Set<LocalLlmRequestPriority>();
259
+ private queueDrainScheduled: boolean = false;
260
+ private static readonly HEALTH_CHECK_INTERVAL_MS = 60000; // 1 minute
261
+ private static readonly LMS_CACHE_INTERVAL_MS = 30000; // 30 seconds
262
+
263
+ constructor(config: PluginConfig, modelRegistry?: ModelRegistry) {
264
+ this.config = config;
265
+ this.modelRegistry = modelRegistry;
266
+ }
267
+
268
+ /**
269
+ * Request thinking/reasoning suppression on the next chat completion.
270
+ *
271
+ * When `true`, the client will inject
272
+ * `chat_template_kwargs: { enable_thinking: false }` into the request
273
+ * body — **but only when the detected backend is known to support it**
274
+ * (LM Studio, vLLM; see `THINKING_COMPATIBLE_BACKENDS`). Strict
275
+ * OpenAI-compat backends reject unknown fields with 400; on those the
276
+ * client fails open (thinking runs normally). This is the safe
277
+ * default for Remnic extraction-style operations: measurable latency
278
+ * win on thinking-capable backends, zero risk on others. Consolidation
279
+ * operations keep thinking enabled unless explicitly added to
280
+ * `THINKING_SUPPRESSED_OPERATIONS`. Issues #548 and #979.
281
+ */
282
+ set disableThinking(value: boolean) {
283
+ this._disableThinking = value;
284
+ }
285
+
286
+ private resolveHomeDir(): string {
287
+ return this.config.localLlmHomeDir || readEnvVar("HOME") || os.homedir();
288
+ }
289
+
290
+ private buildRequestHeaders(base: Record<string, string> = {}): Record<string, string> {
291
+ const headers: Record<string, string> = {
292
+ ...base,
293
+ ...(this.config.localLlmHeaders ?? {}),
294
+ };
295
+ if (this.config.localLlmApiKey && this.config.localLlmAuthHeader !== false) {
296
+ headers.Authorization = `Bearer ${this.config.localLlmApiKey}`;
297
+ }
298
+ return headers;
299
+ }
300
+
301
+ private isAbortError(err: unknown): boolean {
302
+ if (!err || typeof err !== "object") return false;
303
+ const maybe = err as { name?: string; message?: string };
304
+ return (
305
+ maybe.name === "AbortError" ||
306
+ maybe.message === "This operation was aborted" ||
307
+ maybe.message === "The operation was aborted"
308
+ );
309
+ }
310
+
311
+ /**
312
+ * Set the ModelRegistry for caching detected capabilities
313
+ */
314
+ setModelRegistry(registry: ModelRegistry): void {
315
+ this.modelRegistry = registry;
316
+ }
317
+
318
+ /**
319
+ * Get the detected server type (null if not detected)
320
+ */
321
+ getDetectedType(): LocalLlmType | null {
322
+ return this.detectedType;
323
+ }
324
+
325
+ private getBackendKey(): string {
326
+ return trimTrailingSlashes(
327
+ this.config.localLlmUrl.replace("localhost", "127.0.0.1"),
328
+ ).replace(/\/v1$/, "");
329
+ }
330
+
331
+ private getGlobalBackendState(): Map<string, LocalLlmBackendState> {
332
+ const globalAny = globalThis as typeof globalThis & {
333
+ [LOCAL_LLM_GLOBAL_BACKEND_STATE]?: Map<string, LocalLlmBackendState>;
334
+ };
335
+ if (!globalAny[LOCAL_LLM_GLOBAL_BACKEND_STATE]) {
336
+ globalAny[LOCAL_LLM_GLOBAL_BACKEND_STATE] = new Map();
337
+ }
338
+ return globalAny[LOCAL_LLM_GLOBAL_BACKEND_STATE];
339
+ }
340
+
341
+ private getTrippedBackendState(now: number): LocalLlmBackendState | null {
342
+ const state = this.getGlobalBackendState().get(this.getBackendKey()) ?? null;
343
+ if (!state) return null;
344
+ if (state.untilMs <= now) {
345
+ this.getGlobalBackendState().delete(this.getBackendKey());
346
+ this.lastHealthCheck = 0;
347
+ return null;
348
+ }
349
+ return state;
350
+ }
351
+
352
+ private markBackendUnavailable(reason: string, durationMs: number): void {
353
+ const normalizedReason = this.normalizeBackendTripReason(reason);
354
+ if (durationMs > 0) {
355
+ const untilMs = Date.now() + durationMs;
356
+ this.getGlobalBackendState().set(this.getBackendKey(), { untilMs, reason: normalizedReason });
357
+ } else {
358
+ this.getGlobalBackendState().delete(this.getBackendKey());
359
+ }
360
+ this.isAvailable = false;
361
+ this.lastHealthCheck = 0;
362
+ log.warn(
363
+ `local LLM backend unavailable for ${durationMs}ms: model=${this.config.localLlmModel} reason=${normalizedReason}`,
364
+ );
365
+ }
366
+
367
+ private extractNonRecoverableBackendReason(reason: string): string | null {
368
+ const match = reason.match(
369
+ /Failed to load model|Library not loaded|different Team IDs|code signature|llm_engine_mlx_amphibian/i,
370
+ );
371
+ return match?.[0] ?? null;
372
+ }
373
+
374
+ private extractNonRecoverableBackendReasonFromErrorText(errorText: string): string | null {
375
+ const directReason = this.extractNonRecoverableBackendReason(errorText);
376
+ if (directReason) return directReason;
377
+ try {
378
+ const parsed = JSON.parse(errorText) as { error?: { message?: string } };
379
+ return this.extractNonRecoverableBackendReason(parsed?.error?.message ?? "");
380
+ } catch {
381
+ return null;
382
+ }
383
+ }
384
+
385
+ private normalizeBackendTripReason(reason: string): string {
386
+ const cleaned = reason.replace(/\s+/g, " ").replace(/^[-:–—\s]+/, "").trim();
387
+ if (!cleaned) return "unknown local backend failure";
388
+ return cleaned.length > 160 ? `${cleaned.slice(0, 157)}...` : cleaned;
389
+ }
390
+
391
+ /**
392
+ * Fetch with timeout for health checks
393
+ */
394
+ private async fetchWithTimeout(
395
+ url: string,
396
+ timeoutMs: number = 2000,
397
+ headers?: Record<string, string>,
398
+ ): Promise<{ ok: boolean; data: unknown; status: number | null }> {
399
+ const controller = new AbortController();
400
+ const timeout = setTimeout(() => controller.abort(), timeoutMs);
401
+
402
+ try {
403
+ const response = await fetch(url, {
404
+ signal: controller.signal,
405
+ headers: this.buildRequestHeaders({ Accept: "application/json", ...(headers ?? {}) }),
406
+ });
407
+ clearTimeout(timeout);
408
+
409
+ if (!response.ok) {
410
+ return { ok: false, data: null, status: response.status };
411
+ }
412
+
413
+ const contentType = response.headers.get("content-type");
414
+ if (contentType?.includes("application/json")) {
415
+ return { ok: true, data: await response.json(), status: response.status };
416
+ } else {
417
+ return { ok: true, data: await response.text(), status: response.status };
418
+ }
419
+ } catch (err) {
420
+ clearTimeout(timeout);
421
+ return { ok: false, data: null, status: null };
422
+ }
423
+ }
424
+
425
+ private async probeLmStudioNativeModels(
426
+ probeBaseUrl: string,
427
+ ): Promise<{ matched: boolean; unauthorized: boolean }> {
428
+ let unauthorized = false;
429
+ for (const endpoint of ["/api/v1/models", "/api/v0/models"]) {
430
+ const probe = await this.fetchWithTimeout(`${probeBaseUrl}${endpoint}`);
431
+ if (probe.ok && isLmStudioNativeModelsResponse(probe.data)) {
432
+ return { matched: true, unauthorized };
433
+ }
434
+ if (probe.status === 401 || probe.status === 403) {
435
+ unauthorized = true;
436
+ }
437
+ }
438
+ return { matched: false, unauthorized };
439
+ }
440
+
441
+ /**
442
+ * Check if local LLM is available
443
+ * Uses 127.0.0.1 instead of localhost to avoid DNS issues (consistent with tactician)
444
+ */
445
+ async checkAvailability(): Promise<boolean> {
446
+ // Cache health check results for 1 minute
447
+ const now = Date.now();
448
+ const trippedState = this.getTrippedBackendState(now);
449
+ if (trippedState) {
450
+ this.isAvailable = false;
451
+ this.lastHealthCheck = 0;
452
+ log.info(
453
+ `local LLM availability: backend circuit open for ${Math.max(0, trippedState.untilMs - now)}ms (${trippedState.reason})`,
454
+ );
455
+ return false;
456
+ }
457
+ if (this.isAvailable !== null && now - this.lastHealthCheck < LocalLlmClient.HEALTH_CHECK_INTERVAL_MS) {
458
+ return this.isAvailable;
459
+ }
460
+
461
+ // Normalize URL - replace localhost with 127.0.0.1, remove trailing slashes.
462
+ // Probe server-native endpoints from the server root even when users configure
463
+ // the OpenAI-compatible `/v1` base URL for chat completions.
464
+ const configuredBaseUrl = trimTrailingSlashes(
465
+ this.config.localLlmUrl.replace("localhost", "127.0.0.1"),
466
+ );
467
+ const probeBaseUrl = stripTrailingV1Path(configuredBaseUrl);
468
+ let sawUnauthorizedProbe = false;
469
+
470
+ // Try to detect which server type is running
471
+ for (const serverConfig of orderedLocalServers(configuredBaseUrl)) {
472
+ const healthUrl = `${probeBaseUrl}${serverConfig.healthEndpoint}`;
473
+ log.debug(`checking ${serverConfig.type} at ${healthUrl}`);
474
+
475
+ const result = await this.fetchWithTimeout(healthUrl);
476
+ if (result.ok && serverConfig.detectFn(result.data)) {
477
+ if (serverConfig.type === "mlx") {
478
+ const lmStudioProbe = await this.probeLmStudioNativeModels(probeBaseUrl);
479
+ if (lmStudioProbe.unauthorized) {
480
+ sawUnauthorizedProbe = true;
481
+ }
482
+ if (lmStudioProbe.matched) {
483
+ this.isAvailable = true;
484
+ this.detectedType = "lmstudio";
485
+ this.lastHealthCheck = now;
486
+ log.info(`detected lmstudio at ${configuredBaseUrl}`);
487
+ return true;
488
+ }
489
+ }
490
+ if (serverConfig.type === "llamacpp") {
491
+ let sawLlamaCppSignal = false;
492
+ const propsProbe = await this.fetchWithTimeout(`${probeBaseUrl}/props`);
493
+ if (propsProbe.ok && isLlamaCppPropsResponse(propsProbe.data)) {
494
+ sawLlamaCppSignal = true;
495
+ }
496
+ if (propsProbe.status === 401 || propsProbe.status === 403) {
497
+ sawUnauthorizedProbe = true;
498
+ }
499
+
500
+ const modelsUrl = `${probeBaseUrl}${serverConfig.modelsEndpoint}`;
501
+ const modelsProbe = await this.fetchWithTimeout(modelsUrl);
502
+ if (modelsProbe.ok && isLlamaCppModelsResponse(modelsProbe.data)) {
503
+ sawLlamaCppSignal = true;
504
+ }
505
+ if (modelsProbe.status === 401 || modelsProbe.status === 403) {
506
+ sawUnauthorizedProbe = true;
507
+ continue;
508
+ }
509
+
510
+ const authConfigured =
511
+ Boolean(this.config.localLlmApiKey) &&
512
+ this.config.localLlmAuthHeader !== false;
513
+ if (!sawLlamaCppSignal || (authConfigured && !modelsProbe.ok)) {
514
+ continue;
515
+ }
516
+ }
517
+ this.isAvailable = true;
518
+ this.detectedType = serverConfig.type;
519
+ this.lastHealthCheck = now;
520
+ log.info(`detected ${serverConfig.type} at ${configuredBaseUrl}`);
521
+ return true;
522
+ }
523
+ if (result.status === 401 || result.status === 403) {
524
+ sawUnauthorizedProbe = true;
525
+ }
526
+ }
527
+
528
+ // Generic check if specific detection failed
529
+ try {
530
+ const modelsUrl = `${probeBaseUrl}/v1/models`;
531
+ const result = await this.fetchWithTimeout(modelsUrl);
532
+ if (result.ok) {
533
+ this.isAvailable = true;
534
+ this.detectedType = "generic";
535
+ this.lastHealthCheck = now;
536
+ log.info(`detected generic OpenAI-compatible server at ${configuredBaseUrl}`);
537
+ return true;
538
+ }
539
+ if (result.status === 401 || result.status === 403) {
540
+ sawUnauthorizedProbe = true;
541
+ }
542
+ } catch {
543
+ // Fall through to unavailable
544
+ }
545
+
546
+ this.isAvailable = false;
547
+ this.detectedType = null;
548
+ this.lastHealthCheck = now;
549
+ if (sawUnauthorizedProbe) {
550
+ log.warn(
551
+ `local LLM availability probe was unauthorized at ${configuredBaseUrl}; verify localLlmApiKey and localLlmAuthHeader settings`,
552
+ );
553
+ }
554
+ log.debug("local LLM not available at", configuredBaseUrl);
555
+ return false;
556
+ }
557
+
558
+ /**
559
+ * Try to get context window from LM Studio settings.json as fallback.
560
+ * This reads the defaultContextLength setting which is what LM Studio uses
561
+ * when loading models without explicit context configuration.
562
+ */
563
+ private getContextFromLmStudioSettings(): number | null {
564
+ try {
565
+ const homeDir = this.resolveHomeDir();
566
+ const settingsPath = `${homeDir}/.cache/lm-studio/settings.json`;
567
+
568
+ if (!fs.existsSync(settingsPath)) {
569
+ log.debug(`LM Studio settings: file not found at ${settingsPath}`);
570
+ return null;
571
+ }
572
+
573
+ const content = fs.readFileSync(settingsPath, "utf-8");
574
+ const settings = JSON.parse(content) as {
575
+ defaultContextLength?: {
576
+ type?: string;
577
+ value?: number;
578
+ };
579
+ };
580
+
581
+ if (settings.defaultContextLength?.value) {
582
+ const contextWindow = settings.defaultContextLength.value;
583
+ log.debug(`LM Studio settings: found default context length: ${contextWindow}`);
584
+ return contextWindow;
585
+ }
586
+
587
+ return null;
588
+ } catch (err) {
589
+ const errorMsg = err instanceof Error ? err.message : String(err);
590
+ log.debug(`LM Studio settings: failed to read - ${errorMsg}`);
591
+ return null;
592
+ }
593
+ }
594
+
595
+ /**
596
+ * Try to get context window from LMS CLI (LM Studio specific).
597
+ * Uses --json flag for reliable parsing.
598
+ * Returns null if LMS CLI is not available or model not found.
599
+ */
600
+ private getContextFromLmsCli(modelId: string): number | null {
601
+ try {
602
+ // Check if lms CLI exists in common locations.
603
+ // HOME may be absent in launchd environments, so prefer the resolved helper.
604
+ const homeDir = this.resolveHomeDir();
605
+ const lmsPaths = [
606
+ this.config.localLmsCliPath || "",
607
+ `${homeDir}/.cache/lm-studio/bin/lms`,
608
+ "/usr/local/bin/lms",
609
+ "/opt/homebrew/bin/lms",
610
+ ];
611
+
612
+ const lmsPath = lmsPaths.find((p) => p.length > 0 && fs.existsSync(p));
613
+ if (!lmsPath) {
614
+ log.debug(`LMS CLI: not found in standard locations (checked: ${lmsPaths.join(", ")})`);
615
+ return null;
616
+ }
617
+
618
+ // Run lms ps --json to get loaded models with context
619
+ // Use spawnSync with shell and explicit PATH to ensure lms can find its dependencies
620
+ log.debug(`LMS CLI: running: ${lmsPath} ps --json`);
621
+ const existingPath = readEnvVar("PATH") || "";
622
+ const result = launchProcessSync(lmsPath, ["ps", "--json"], {
623
+ encoding: "utf-8",
624
+ timeout: 5000,
625
+ shell: false, // Don't use shell for JSON output - more reliable
626
+ env: mergeEnv({
627
+ PATH: `${this.config.localLmsBinDir || `${homeDir}/.cache/lm-studio/bin`}:/usr/local/bin:/opt/homebrew/bin:/usr/bin:/bin:${existingPath}`,
628
+ HOME: homeDir,
629
+ }),
630
+ });
631
+
632
+ if (result.error) {
633
+ log.debug(`LMS CLI: spawn error - ${result.error.message}`);
634
+ return null;
635
+ }
636
+
637
+ if (result.stderr && result.stderr.trim()) {
638
+ log.debug(`LMS CLI: stderr - ${result.stderr.slice(0, 200)}`);
639
+ }
640
+
641
+ const output = result.stdout || "";
642
+ if (!output.trim()) {
643
+ log.debug("LMS CLI: empty output - LM Studio may not be running or no models loaded");
644
+ return null;
645
+ }
646
+
647
+ // Parse JSON output
648
+ let models: Array<{
649
+ identifier?: string;
650
+ modelKey?: string;
651
+ contextLength?: number;
652
+ maxContextLength?: number;
653
+ }>;
654
+
655
+ try {
656
+ models = JSON.parse(output) as typeof models;
657
+ } catch (parseErr) {
658
+ log.debug(`LMS CLI: JSON parse error - ${parseErr}`);
659
+ return null;
660
+ }
661
+
662
+ if (!Array.isArray(models) || models.length === 0) {
663
+ log.debug("LMS CLI: no models loaded");
664
+ return null;
665
+ }
666
+
667
+ // Find the model matching our configured model ID
668
+ const model = models.find((m) =>
669
+ m.identifier === modelId ||
670
+ m.modelKey === modelId ||
671
+ (m.identifier?.includes(modelId.replace(/@\d+bit$/, "")))
672
+ );
673
+
674
+ if (!model) {
675
+ log.debug(`LMS CLI: model "${modelId}" not found in loaded models: ${models.map(m => m.identifier).join(", ")}`);
676
+ return null;
677
+ }
678
+
679
+ // Use contextLength (actual configured) or fall back to maxContextLength (model max)
680
+ const contextWindow = model.contextLength || model.maxContextLength;
681
+
682
+ if (contextWindow) {
683
+ log.info(`LMS CLI detected context window: ${contextWindow} for ${modelId} (max: ${model.maxContextLength})`);
684
+ return contextWindow;
685
+ }
686
+
687
+ return null;
688
+ } catch (err) {
689
+ // LMS CLI not available or failed
690
+ const errorMsg = err instanceof Error ? err.message : String(err);
691
+ log.debug(`LMS CLI: failed - ${errorMsg}`);
692
+ return null;
693
+ }
694
+ }
695
+
696
+ /**
697
+ * Get full model info from LMS CLI including context length and max context length.
698
+ * Returns null if LMS CLI is unavailable or model not found.
699
+ */
700
+ private getLmsModelInfo(modelId: string): { contextLength: number; maxContextLength: number; identifier: string } | null {
701
+ try {
702
+ const result = launchProcessSync("lms", ["ps", "--json"], {
703
+ encoding: "utf-8",
704
+ timeout: 5000,
705
+ shell: false,
706
+ });
707
+
708
+ if (result.error) {
709
+ return null;
710
+ }
711
+
712
+ const output = result.stdout || "";
713
+ if (!output.trim()) {
714
+ return null;
715
+ }
716
+
717
+ let models: Array<{
718
+ identifier?: string;
719
+ modelKey?: string;
720
+ contextLength?: number;
721
+ maxContextLength?: number;
722
+ }>;
723
+
724
+ try {
725
+ models = JSON.parse(output) as typeof models;
726
+ } catch {
727
+ return null;
728
+ }
729
+
730
+ if (!Array.isArray(models) || models.length === 0) {
731
+ return null;
732
+ }
733
+
734
+ const model = models.find((m) =>
735
+ m.identifier === modelId ||
736
+ m.modelKey === modelId ||
737
+ (m.identifier?.includes(modelId.replace(/@\d+bit$/, "")))
738
+ );
739
+
740
+ if (!model || !model.contextLength) {
741
+ return null;
742
+ }
743
+
744
+ return {
745
+ contextLength: model.contextLength,
746
+ maxContextLength: model.maxContextLength || model.contextLength,
747
+ identifier: model.identifier || modelId,
748
+ };
749
+ } catch {
750
+ return null;
751
+ }
752
+ }
753
+
754
+ /**
755
+ * Get context window for the configured model, using cache if available.
756
+ * This method caches the result to avoid repeated LMS CLI calls.
757
+ * Order: ModelRegistry (persistent) -> memory cache -> LMS CLI -> settings.json
758
+ */
759
+ getCachedContextWindow(modelId: string): number | null {
760
+ const now = Date.now();
761
+
762
+ // 1. Check ModelRegistry for persisted context window
763
+ if (this.modelRegistry) {
764
+ const caps = this.modelRegistry.getCapabilities(modelId);
765
+ if (caps.source === "lmstudio" && caps.contextWindow) {
766
+ log.debug(`ModelRegistry: using persisted LM Studio context: ${caps.contextWindow}`);
767
+ // Also update memory cache
768
+ this.cachedLmsContext = caps.contextWindow;
769
+ this.lastLmsCheck = now;
770
+ return caps.contextWindow;
771
+ }
772
+ }
773
+
774
+ // 2. Return in-memory cached value if still valid
775
+ if (this.cachedLmsContext && now - this.lastLmsCheck < LocalLlmClient.LMS_CACHE_INTERVAL_MS) {
776
+ log.debug(`LMS CLI: returning in-memory cached context: ${this.cachedLmsContext}`);
777
+ return this.cachedLmsContext;
778
+ }
779
+
780
+ // 3. Try LMS CLI (authoritative source)
781
+ const lmsInfo = this.getLmsModelInfo(modelId);
782
+ if (lmsInfo?.contextLength) {
783
+ this.cachedLmsContext = lmsInfo.contextLength;
784
+ this.lastLmsCheck = now;
785
+ // Calculate appropriate output tokens based on context size
786
+ // Use 12.5% of context window, capped at 16K (generous but safe)
787
+ const calculatedOutputTokens = Math.min(Math.floor(lmsInfo.contextLength / 8), 16384);
788
+ const outputTokens = Math.max(calculatedOutputTokens, 4096); // Minimum 4K
789
+ // Persist to ModelRegistry with detected capabilities
790
+ if (this.modelRegistry) {
791
+ this.modelRegistry.setCapabilities(modelId, {
792
+ maxPositionEmbeddings: lmsInfo.maxContextLength || lmsInfo.contextLength,
793
+ contextWindow: lmsInfo.contextLength,
794
+ supportsExtendedContext: (lmsInfo.maxContextLength || lmsInfo.contextLength) > 65536,
795
+ typicalOutputTokens: outputTokens,
796
+ source: "lmstudio",
797
+ });
798
+ log.info(`LMS CLI: Stored capabilities for ${modelId}: ${lmsInfo.contextLength} context, ${outputTokens} output tokens`);
799
+ }
800
+ return lmsInfo.contextLength;
801
+ }
802
+
803
+ // Legacy: Try LMS CLI context only (fallback)
804
+ const legacyContext = this.getContextFromLmsCli(modelId);
805
+ if (legacyContext) {
806
+ this.cachedLmsContext = legacyContext;
807
+ this.lastLmsCheck = now;
808
+ // Persist to ModelRegistry with calculated output tokens
809
+ if (this.modelRegistry) {
810
+ const calculatedOutputTokens = Math.min(Math.floor(legacyContext / 8), 16384);
811
+ const outputTokens = Math.max(calculatedOutputTokens, 4096);
812
+ this.modelRegistry.setCapabilities(modelId, {
813
+ maxPositionEmbeddings: legacyContext,
814
+ contextWindow: legacyContext,
815
+ supportsExtendedContext: false,
816
+ typicalOutputTokens: outputTokens,
817
+ source: "lmstudio",
818
+ });
819
+ }
820
+ return legacyContext;
821
+ }
822
+
823
+ // 4. Fall back to LM Studio settings.json
824
+ const settingsContext = this.getContextFromLmStudioSettings();
825
+ if (settingsContext) {
826
+ log.info(`LM Studio settings: using default context: ${settingsContext}`);
827
+ this.cachedLmsContext = settingsContext;
828
+ this.lastLmsCheck = now;
829
+ return settingsContext;
830
+ }
831
+
832
+ return null;
833
+ }
834
+
835
+ /**
836
+ * Clear the LMS context cache. Call this when the model changes.
837
+ */
838
+ clearContextCache(): void {
839
+ this.cachedLmsContext = null;
840
+ this.lastLmsCheck = 0;
841
+ log.debug("LMS CLI: context cache cleared");
842
+ }
843
+
844
+ private remainingCooldownMs(now: number = Date.now()): number {
845
+ return Math.max(0, this.cooldownUntilMs - now);
846
+ }
847
+
848
+ private scheduleQueueDrain(): void {
849
+ if (this.queueDrainScheduled) return;
850
+ this.queueDrainScheduled = true;
851
+
852
+ queueMicrotask(() => {
853
+ this.queueDrainScheduled = false;
854
+ this.startAvailableQueuedRequests();
855
+ });
856
+ }
857
+
858
+ private hasQueuedRequests(): boolean {
859
+ return (
860
+ this.requestQueues["recall-critical"].length > 0 ||
861
+ this.requestQueues.background.length > 0
862
+ );
863
+ }
864
+
865
+ private dequeueQueuedRequest(priority: LocalLlmRequestPriority): LocalLlmQueuedRequest | null {
866
+ const next = this.requestQueues[priority].shift();
867
+ return next ?? null;
868
+ }
869
+
870
+ private failOpenQueuedRequestsForCooldown(): number {
871
+ let dropped = 0;
872
+ for (const priority of ["recall-critical", "background"] as const) {
873
+ while (this.requestQueues[priority].length > 0) {
874
+ const queued = this.requestQueues[priority].shift();
875
+ queued?.resolve(null);
876
+ dropped += 1;
877
+ }
878
+ }
879
+ return dropped;
880
+ }
881
+
882
+ private startAvailableQueuedRequests(): void {
883
+ if (!this.queueProcessing.has("recall-critical")) {
884
+ const nextCritical = this.dequeueQueuedRequest("recall-critical");
885
+ if (nextCritical) {
886
+ this.queueProcessing.add("recall-critical");
887
+ void this.runQueuedRequest(nextCritical);
888
+ }
889
+ }
890
+
891
+ if (!this.queueProcessing.has("background")) {
892
+ const nextBackground = this.dequeueQueuedRequest("background");
893
+ if (nextBackground) {
894
+ this.queueProcessing.add("background");
895
+ void this.runQueuedRequest(nextBackground);
896
+ }
897
+ }
898
+ }
899
+
900
+ private async runQueuedRequest(next: LocalLlmQueuedRequest): Promise<void> {
901
+ try {
902
+ const remainingCooldownMs = this.remainingCooldownMs();
903
+ if (remainingCooldownMs > 0) {
904
+ const additionalDropped = this.failOpenQueuedRequestsForCooldown();
905
+ log.warn(
906
+ `local LLM: cooldown active (${remainingCooldownMs}ms remaining), dropping ${additionalDropped + 1} queued request(s) fail-open`,
907
+ );
908
+ next.resolve(null);
909
+ return;
910
+ }
911
+
912
+ let result: LocalLlmChatCompletionResult | null = null;
913
+ try {
914
+ result = await this.runChatCompletionRequest(next.messages, next.options, {
915
+ priority: next.priority,
916
+ enqueuedAtMs: next.enqueuedAtMs,
917
+ });
918
+ } catch (err) {
919
+ log.warn(`local LLM queue drain failed open: ${err instanceof Error ? err.message : String(err)}`);
920
+ }
921
+ next.resolve(result);
922
+ } finally {
923
+ this.queueProcessing.delete(next.priority);
924
+ if (this.hasQueuedRequests()) {
925
+ this.scheduleQueueDrain();
926
+ }
927
+ }
928
+ }
929
+
930
+ private async runChatCompletionRequest(
931
+ messages: Array<{ role: string; content: string }>,
932
+ options: LocalLlmChatCompletionOptions,
933
+ queueMeta?: { priority: LocalLlmRequestPriority; enqueuedAtMs: number },
934
+ ): Promise<LocalLlmChatCompletionResult | null> {
935
+ log.debug(
936
+ `local LLM chatCompletion: localLlmEnabled=${this.config.localLlmEnabled}, model=${this.config.localLlmModel}`,
937
+ );
938
+
939
+ const operation = options.operation ?? "unspecified";
940
+ const startedAtMs = Date.now();
941
+ if (queueMeta) {
942
+ log.debug(
943
+ `local LLM queue start: priority=${queueMeta.priority} waitMs=${startedAtMs - queueMeta.enqueuedAtMs} op=${operation}`,
944
+ );
945
+ }
946
+
947
+ try {
948
+ const isAvailable = await this.checkAvailability();
949
+ if (!isAvailable) {
950
+ log.debug(
951
+ `local LLM: checkAvailability returned false for ${this.config.localLlmUrl}`,
952
+ );
953
+ return null;
954
+ }
955
+
956
+ const promptChars = messages.reduce((sum, m) => sum + (m.content?.length ?? 0), 0);
957
+ const requestBody: Record<string, unknown> = {
958
+ model: this.config.localLlmModel,
959
+ messages,
960
+ temperature: options.temperature ?? 0.7,
961
+ // Use max_tokens consistent with cloud models
962
+ max_tokens: options.maxTokens ?? 4096,
963
+ };
964
+
965
+ // Skip response_format for local LLMs - they don't support json_object type
966
+ // The prompts already instruct the model to output JSON
967
+ // Only send if it's json_schema type which some local LLMs support
968
+ if (options.responseFormat?.type === "json_schema") {
969
+ requestBody.response_format = options.responseFormat;
970
+ }
971
+
972
+ // Suppress thinking/reasoning for operations that benefit from terse,
973
+ // structured output. Thinking-capable models (Qwen 3.5, Gemma 4,
974
+ // DeepSeek) default to thinking-on via their chat template; sending
975
+ // `chat_template_kwargs: { enable_thinking: false }` tells the template
976
+ // to skip reasoning tokens. Consolidation operations on the main client
977
+ // intentionally keep thinking enabled so entity resolution and
978
+ // deduplication can use the model's reasoning path. Fast-tier callers can
979
+ // still force suppression per request to preserve their low-latency
980
+ // contract.
981
+ //
982
+ // Gate the injection on detected backend support (issue #548,
983
+ // Codex P1 on PR #550): `chat_template_kwargs` is an LM Studio /
984
+ // vLLM / llama.cpp extension, not part of standard OpenAI chat
985
+ // completions. Strict OpenAI-compatible backends reject
986
+ // unknown fields with 400, which trips the 400-cooldown path and
987
+ // can effectively disable local extraction. Fail open when the
988
+ // backend hasn't been positively identified as thinking-capable.
989
+ const shouldSuppressThinking =
990
+ options.forceDisableThinking === true ||
991
+ (this._disableThinking &&
992
+ THINKING_SUPPRESSED_OPERATIONS.has(operation));
993
+ if (
994
+ shouldSuppressThinking &&
995
+ this.detectedType !== null &&
996
+ THINKING_COMPATIBLE_BACKENDS.has(this.detectedType)
997
+ ) {
998
+ requestBody.chat_template_kwargs = { enable_thinking: false };
999
+ }
1000
+
1001
+ // Normalize URL (use 127.0.0.1 instead of localhost)
1002
+ const baseUrl = trimTrailingSlashes(
1003
+ this.config.localLlmUrl.replace("localhost", "127.0.0.1"),
1004
+ );
1005
+ const chatUrl = baseUrl.endsWith("/v1")
1006
+ ? `${baseUrl}/chat/completions`
1007
+ : `${baseUrl}/v1/chat/completions`;
1008
+
1009
+ const requestBodyJson = JSON.stringify(requestBody);
1010
+ log.debug(
1011
+ `local LLM: sending request to ${chatUrl} with model ${this.config.localLlmModel}`,
1012
+ );
1013
+ // Avoid logging request bodies by default (can contain sensitive user content).
1014
+ log.debug(`local LLM: request body length=${requestBodyJson.length}`);
1015
+
1016
+ // Write request body to file for debugging
1017
+ if (this.config.debug) {
1018
+ try {
1019
+ const { writeFileSync } = await import("node:fs");
1020
+ writeFileSync("/tmp/engram-last-request.json", requestBodyJson);
1021
+ } catch {
1022
+ /* ignore */
1023
+ }
1024
+ }
1025
+
1026
+ const effectiveTimeoutMs =
1027
+ typeof options.timeoutMs === "number"
1028
+ ? Math.min(this.config.localLlmTimeoutMs, options.timeoutMs)
1029
+ : this.config.localLlmTimeoutMs;
1030
+ const maxAttempts = 1 + Math.max(0, this.config.localLlmRetry5xxCount);
1031
+ let response: Response | null = null;
1032
+ let lastAbortError: Error | null = null;
1033
+ for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
1034
+ const attemptAbort = new AbortController();
1035
+ const attemptTimeout = setTimeout(() => attemptAbort.abort(), effectiveTimeoutMs);
1036
+ try {
1037
+ response = await fetch(chatUrl, {
1038
+ method: "POST",
1039
+ headers: this.buildRequestHeaders({
1040
+ "Content-Type": "application/json",
1041
+ }),
1042
+ body: JSON.stringify(requestBody),
1043
+ signal: attemptAbort.signal,
1044
+ });
1045
+ } catch (err) {
1046
+ if (!this.isAbortError(err)) throw err;
1047
+ lastAbortError = err instanceof Error ? err : new Error(String(err));
1048
+ if (attempt < maxAttempts) {
1049
+ const backoffMs = this.config.localLlmRetryBackoffMs * attempt;
1050
+ log.warn(
1051
+ `local LLM request aborted: op=${operation} attempt=${attempt}/${maxAttempts} timeoutMs=${effectiveTimeoutMs} model=${this.config.localLlmModel}; retrying after ${backoffMs}ms`,
1052
+ );
1053
+ await new Promise((resolve) => setTimeout(resolve, backoffMs));
1054
+ continue;
1055
+ }
1056
+ break;
1057
+ } finally {
1058
+ clearTimeout(attemptTimeout);
1059
+ }
1060
+
1061
+ if (response.ok) break;
1062
+ if (response.status >= 500 && attempt < maxAttempts) {
1063
+ try {
1064
+ const errorText = await response.clone().text();
1065
+ const nonRecoverableReason =
1066
+ this.extractNonRecoverableBackendReasonFromErrorText(errorText);
1067
+ if (nonRecoverableReason) {
1068
+ this.markBackendUnavailable(
1069
+ nonRecoverableReason,
1070
+ this.config.localLlm400CooldownMs,
1071
+ );
1072
+ this.consecutive400s = 0;
1073
+ return null;
1074
+ }
1075
+ } catch (e) {
1076
+ log.debug(`local LLM failed to inspect retryable error body: ${e}`);
1077
+ }
1078
+ }
1079
+ if (response.status < 500 || attempt >= maxAttempts) break;
1080
+
1081
+ const backoffMs = this.config.localLlmRetryBackoffMs * attempt;
1082
+ log.warn(
1083
+ `local LLM request got ${response.status}; retrying (attempt ${attempt + 1}/${maxAttempts}) after ${backoffMs}ms`,
1084
+ );
1085
+ await new Promise((resolve) => setTimeout(resolve, backoffMs));
1086
+ }
1087
+ log.debug(
1088
+ `local LLM: received response, status=${response?.status}, ok=${response?.ok}`,
1089
+ );
1090
+
1091
+ if (!response) {
1092
+ if (lastAbortError) {
1093
+ log.warn(
1094
+ `local LLM request aborted after ${maxAttempts} attempt(s): op=${operation} timeoutMs=${effectiveTimeoutMs} model=${this.config.localLlmModel} promptChars=${promptChars} durationMs=${Date.now() - startedAtMs}`,
1095
+ );
1096
+ } else {
1097
+ log.warn(
1098
+ `local LLM request failed: no response object (op=${operation} model=${this.config.localLlmModel} durationMs=${Date.now() - startedAtMs})`,
1099
+ );
1100
+ }
1101
+ return null;
1102
+ }
1103
+
1104
+ if (!response.ok) {
1105
+ let reason = "";
1106
+ let errorText = "";
1107
+ try {
1108
+ errorText = await response.text();
1109
+ // Try to extract a stable error message without logging content.
1110
+ try {
1111
+ const parsed = JSON.parse(errorText) as { error?: { message?: string } };
1112
+ reason = parsed?.error?.message ? ` — ${parsed.error.message}` : "";
1113
+ } catch {
1114
+ // Keep a short preview in debug only.
1115
+ log.debug(`local LLM error body: ${errorText.slice(0, 500)}`);
1116
+ }
1117
+ } catch (e) {
1118
+ log.debug(`local LLM failed to read error body: ${e}`);
1119
+ }
1120
+ log.warn(
1121
+ `local LLM request failed: ${response.status} ${response.statusText}${reason} ` +
1122
+ `(op=${operation}, model=${this.config.localLlmModel}, url=${chatUrl}, promptChars=${promptChars}, maxTokens=${requestBody.max_tokens as number})`,
1123
+ );
1124
+ const nonRecoverableReason =
1125
+ this.extractNonRecoverableBackendReason(reason) ??
1126
+ this.extractNonRecoverableBackendReasonFromErrorText(errorText);
1127
+ if (nonRecoverableReason) {
1128
+ this.markBackendUnavailable(
1129
+ nonRecoverableReason,
1130
+ this.config.localLlm400CooldownMs,
1131
+ );
1132
+ this.consecutive400s = 0;
1133
+ return null;
1134
+ }
1135
+ if (response.status === 400) {
1136
+ this.consecutive400s += 1;
1137
+ if (this.consecutive400s >= this.config.localLlm400TripThreshold) {
1138
+ this.cooldownUntilMs = Date.now() + this.config.localLlm400CooldownMs;
1139
+ log.warn(
1140
+ `local LLM: entering cooldown for ${this.config.localLlm400CooldownMs}ms ` +
1141
+ `after ${this.consecutive400s} consecutive 400 responses`,
1142
+ );
1143
+ this.consecutive400s = 0;
1144
+ }
1145
+ } else {
1146
+ this.consecutive400s = 0;
1147
+ }
1148
+ return null;
1149
+ }
1150
+ this.consecutive400s = 0;
1151
+
1152
+ const data = (await response.json()) as {
1153
+ choices?: Array<{
1154
+ message?: { content?: string; reasoning_content?: string };
1155
+ }>;
1156
+ usage?: {
1157
+ prompt_tokens?: number;
1158
+ completion_tokens?: number;
1159
+ total_tokens?: number;
1160
+ };
1161
+ };
1162
+
1163
+ log.debug(
1164
+ `local LLM response: choices=${data.choices?.length}, usage=${JSON.stringify(data.usage)}`,
1165
+ );
1166
+
1167
+ // Thinking models (e.g. Qwen 3.5) may put their response in
1168
+ // `reasoning_content` and leave `content` empty. Fall back to
1169
+ // reasoning_content so engram still gets a usable result.
1170
+ const msg = data.choices?.[0]?.message;
1171
+ const content = msg?.content || msg?.reasoning_content || "";
1172
+ if (!content) {
1173
+ log.warn(`local LLM returned empty content. choices=${JSON.stringify(data.choices)?.slice(0, 200)}`);
1174
+ return null;
1175
+ }
1176
+
1177
+ // Estimate tokens if not provided by local LLM
1178
+ const usage = data.usage
1179
+ ? {
1180
+ promptTokens: data.usage.prompt_tokens ?? 0,
1181
+ completionTokens: data.usage.completion_tokens ?? 0,
1182
+ totalTokens: data.usage.total_tokens ?? 0,
1183
+ }
1184
+ : this.estimateTokens(messages, content);
1185
+
1186
+ const durationMs = Date.now() - startedAtMs;
1187
+ if (this.config.slowLogEnabled && durationMs >= this.config.slowLogThresholdMs) {
1188
+ const promptChars = messages.reduce((sum, m) => sum + (m.content?.length ?? 0), 0);
1189
+ const op = options.operation ? ` op=${options.operation}` : "";
1190
+ log.warn(
1191
+ `SLOW local LLM:${op} durationMs=${durationMs} model=${this.config.localLlmModel} url=${chatUrl} promptChars=${promptChars} outputTokens=${usage.completionTokens} totalTokens=${usage.totalTokens}`,
1192
+ );
1193
+ }
1194
+
1195
+ log.debug("local LLM: request succeeded, tokens:", usage.totalTokens);
1196
+ return { content, usage };
1197
+ } catch (err) {
1198
+ const errMsg = err instanceof Error ? err.message : String(err);
1199
+ const durationMs = Date.now() - startedAtMs;
1200
+ if (this.isAbortError(err)) {
1201
+ log.warn(
1202
+ `local LLM request aborted: op=${operation} timeoutMs=${options.timeoutMs ?? this.config.localLlmTimeoutMs} model=${this.config.localLlmModel} durationMs=${durationMs} error=${errMsg}`,
1203
+ );
1204
+ return null;
1205
+ }
1206
+ log.warn(`local LLM request error: op=${operation} error=${errMsg}`);
1207
+ this.isAvailable = false; // Mark as unavailable on non-abort errors
1208
+ const nonRecoverableReason = this.extractNonRecoverableBackendReason(errMsg);
1209
+ if (nonRecoverableReason) {
1210
+ this.markBackendUnavailable(
1211
+ nonRecoverableReason,
1212
+ this.config.localLlm400CooldownMs,
1213
+ );
1214
+ }
1215
+ return null;
1216
+ } finally {
1217
+ if (queueMeta) {
1218
+ const finishedAtMs = Date.now();
1219
+ const waitMs = startedAtMs - queueMeta.enqueuedAtMs;
1220
+ log.debug(
1221
+ `local LLM queue finish: priority=${queueMeta.priority} waitMs=${waitMs} runMs=${finishedAtMs - startedAtMs} totalMs=${finishedAtMs - queueMeta.enqueuedAtMs} op=${operation}`,
1222
+ );
1223
+ }
1224
+ }
1225
+ }
1226
+
1227
+ /**
1228
+ * Query the local LLM server for loaded model information.
1229
+ * Returns null if unavailable or if the model is not found.
1230
+ */
1231
+ async getLoadedModelInfo(): Promise<LocalModelInfo | null> {
1232
+ const baseUrl = trimTrailingSlashes(
1233
+ this.config.localLlmUrl.replace("localhost", "127.0.0.1"),
1234
+ );
1235
+
1236
+ // Handle URL construction - localLlmUrl may already include /v1
1237
+ const modelsUrl = baseUrl.endsWith("/v1")
1238
+ ? `${baseUrl}/models`
1239
+ : `${baseUrl}/v1/models`;
1240
+ log.debug(`Fetching model info from ${modelsUrl}`);
1241
+
1242
+ try {
1243
+ const result = await this.fetchWithTimeout(modelsUrl, 3000);
1244
+ if (!result.ok) {
1245
+ if (result.status === 401 || result.status === 403) {
1246
+ log.warn(
1247
+ `Local LLM: unauthorized while fetching models from ${modelsUrl}; verify localLlmApiKey and localLlmAuthHeader settings`,
1248
+ );
1249
+ }
1250
+ log.warn(`Local LLM: Failed to fetch models from ${modelsUrl} - server returned error`);
1251
+ return null;
1252
+ }
1253
+ if (!result.data) {
1254
+ log.warn(`Local LLM: No data returned from ${modelsUrl}`);
1255
+ return null;
1256
+ }
1257
+
1258
+ const data = result.data as {
1259
+ data?: Array<{
1260
+ id?: string;
1261
+ object?: string;
1262
+ owned_by?: string;
1263
+ // LM Studio specific fields
1264
+ max_context_length?: number;
1265
+ max_tokens?: number;
1266
+ // Ollama specific
1267
+ name?: string;
1268
+ details?: {
1269
+ parameter_size?: string;
1270
+ family?: string;
1271
+ };
1272
+ }>;
1273
+ };
1274
+
1275
+ if (!Array.isArray(data.data) || data.data.length === 0) {
1276
+ log.warn("Local LLM returned no models");
1277
+ return null;
1278
+ }
1279
+
1280
+ // Verbose model listings are noisy on every gateway restart. Keep it debug-only.
1281
+ const modelIds = data.data.map((m) => m.id).filter(Boolean);
1282
+ log.debug(
1283
+ `Local LLM: Found ${modelIds.length} model(s). First 10: ${modelIds.slice(0, 10).join(", ")}`,
1284
+ );
1285
+
1286
+ // Find the model matching our configured model ID
1287
+ const configuredModel = this.config.localLlmModel;
1288
+ let model = data.data.find((m) => m.id === configuredModel);
1289
+
1290
+ // If not found by exact match, try partial match (handle suffixes like @4bit)
1291
+ if (!model) {
1292
+ model = data.data.find((m) =>
1293
+ configuredModel.includes(m.id || "") ||
1294
+ (m.id || "").includes(configuredModel.replace(/@\d+bit$/, ""))
1295
+ );
1296
+ }
1297
+
1298
+ // If still not found, use the first loaded model and warn
1299
+ if (!model) {
1300
+ model = data.data[0];
1301
+ const availablePreview = data.data
1302
+ .map((m) => m.id)
1303
+ .filter(Boolean)
1304
+ .slice(0, 10)
1305
+ .join(", ");
1306
+ log.warn(
1307
+ `Configured model "${configuredModel}" not found in local LLM. ` +
1308
+ `Using "${model.id}" instead. Available (first 10): ${availablePreview}`
1309
+ );
1310
+ }
1311
+
1312
+ // Extract context window - try multiple field names
1313
+ let contextWindow = model.max_context_length || model.max_tokens;
1314
+
1315
+ // If API doesn't report context window, try LMS CLI (LM Studio specific)
1316
+ if (!contextWindow) {
1317
+ log.info("Local LLM: API did not report context window, trying LMS CLI...");
1318
+ const lmsContext = this.getCachedContextWindow(model.id || "");
1319
+ if (lmsContext) {
1320
+ contextWindow = lmsContext;
1321
+ }
1322
+ }
1323
+
1324
+ this.cachedModelInfo = {
1325
+ id: model.id || "unknown",
1326
+ contextWindow: contextWindow,
1327
+ maxTokens: model.max_tokens,
1328
+ };
1329
+
1330
+ log.info(
1331
+ `Local LLM model detected: ${this.cachedModelInfo.id}, ` +
1332
+ `context window: ${contextWindow?.toLocaleString() || "unknown (may use default)"}`
1333
+ );
1334
+
1335
+ return this.cachedModelInfo;
1336
+ } catch (err) {
1337
+ log.warn(`Failed to fetch model info: ${err}`);
1338
+ return null;
1339
+ }
1340
+ }
1341
+
1342
+ /**
1343
+ * Check if the configured model is available and get its actual context window.
1344
+ * Warns if there's a mismatch between expected and actual context.
1345
+ */
1346
+ async validateModelConfig(expectedContextWindow?: number): Promise<{
1347
+ available: boolean;
1348
+ actualContextWindow?: number;
1349
+ warnings: string[];
1350
+ }> {
1351
+ const warnings: string[] = [];
1352
+
1353
+ const modelInfo = await this.getLoadedModelInfo();
1354
+ if (!modelInfo) {
1355
+ return { available: false, warnings: ["Could not query local LLM for model info"] };
1356
+ }
1357
+
1358
+ // If we have expected context and the server reports one, check for mismatch
1359
+ if (expectedContextWindow && modelInfo.contextWindow) {
1360
+ if (modelInfo.contextWindow < expectedContextWindow) {
1361
+ warnings.push(
1362
+ `Context window mismatch: Model ${modelInfo.id} supports ${modelInfo.contextWindow.toLocaleString()} tokens, ` +
1363
+ `but engram is configured for ${expectedContextWindow.toLocaleString()}. ` +
1364
+ `Set localLlmMaxContext: ${modelInfo.contextWindow} in config to avoid errors.`
1365
+ );
1366
+ }
1367
+ }
1368
+
1369
+ // Warn if server doesn't report context window (common with some local LLM setups)
1370
+ if (!modelInfo.contextWindow) {
1371
+ warnings.push(
1372
+ `Local LLM server did not report context window for ${modelInfo.id}. ` +
1373
+ `If you get "context length exceeded" errors, set localLlmMaxContext in config.`
1374
+ );
1375
+ }
1376
+
1377
+ return {
1378
+ available: true,
1379
+ actualContextWindow: modelInfo.contextWindow,
1380
+ warnings,
1381
+ };
1382
+ }
1383
+
1384
+ /**
1385
+ * Make a chat completion request to local LLM
1386
+ */
1387
+ async chatCompletion(
1388
+ messages: Array<{ role: string; content: string }>,
1389
+ options: LocalLlmChatCompletionOptions = {},
1390
+ ): Promise<LocalLlmChatCompletionResult | null> {
1391
+ if (!this.config.localLlmEnabled) {
1392
+ log.debug("local LLM: disabled, returning null");
1393
+ return null;
1394
+ }
1395
+
1396
+ const remainingMs = this.remainingCooldownMs();
1397
+ if (remainingMs > 0) {
1398
+ log.debug(`local LLM: cooldown active (${remainingMs}ms remaining), skipping request`);
1399
+ return null;
1400
+ }
1401
+ if (options.priority) {
1402
+ const priority = options.priority;
1403
+ return await new Promise<LocalLlmChatCompletionResult | null>((resolve) => {
1404
+ this.requestQueues[priority].push({
1405
+ messages,
1406
+ options,
1407
+ priority,
1408
+ enqueuedAtMs: Date.now(),
1409
+ resolve,
1410
+ });
1411
+ this.scheduleQueueDrain();
1412
+ });
1413
+ }
1414
+
1415
+ return await this.runChatCompletionRequest(messages, options);
1416
+ }
1417
+
1418
+ /**
1419
+ * Estimate tokens when local LLM doesn't return usage stats
1420
+ * Rough estimate: 1 token ≈ 4 characters
1421
+ */
1422
+ private estimateTokens(
1423
+ messages: Array<{ role: string; content: string }>,
1424
+ response: string
1425
+ ): { promptTokens: number; completionTokens: number; totalTokens: number } {
1426
+ const promptChars = messages.reduce((sum, m) => sum + m.content.length, 0);
1427
+ const promptTokens = Math.ceil(promptChars / 4);
1428
+ const completionTokens = Math.ceil(response.length / 4);
1429
+
1430
+ return {
1431
+ promptTokens,
1432
+ completionTokens,
1433
+ totalTokens: promptTokens + completionTokens,
1434
+ };
1435
+ }
1436
+
1437
+ /**
1438
+ * Try local LLM first, fallback to cloud provider if configured
1439
+ */
1440
+ async withFallback<T>(
1441
+ localOperation: () => Promise<T | null>,
1442
+ fallbackOperation: () => Promise<T>,
1443
+ operationName: string
1444
+ ): Promise<T> {
1445
+ // Try local LLM first if enabled
1446
+ if (this.config.localLlmEnabled) {
1447
+ const localResult = await localOperation();
1448
+ if (localResult !== null) {
1449
+ log.debug(`${operationName}: used local LLM`);
1450
+ return localResult;
1451
+ }
1452
+
1453
+ // Local failed or unavailable
1454
+ if (this.config.localLlmFallback) {
1455
+ log.info(`${operationName}: local LLM unavailable, falling back to cloud`);
1456
+ } else {
1457
+ throw new Error(`${operationName}: local LLM unavailable and fallback disabled`);
1458
+ }
1459
+ }
1460
+
1461
+ // Use fallback (cloud provider)
1462
+ return fallbackOperation();
1463
+ }
1464
+ }