@remnic/core 9.69.39 → 9.69.41

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 (774) hide show
  1. package/dist/access-admin-ops-surface.d.ts +16 -14
  2. package/dist/access-admin-ops-surface.js +75 -74
  3. package/dist/access-audit.js +2 -2
  4. package/dist/access-authorization-probe.d.ts +16 -14
  5. package/dist/access-authorization-probe.js +76 -75
  6. package/dist/access-boundary.d.ts +16 -14
  7. package/dist/access-boundary.js +75 -74
  8. package/dist/access-cli.js +173 -170
  9. package/dist/access-cli.js.map +1 -1
  10. package/dist/access-coding-context-resolution.d.ts +1 -1
  11. package/dist/access-extraction-force-flush.d.ts +16 -14
  12. package/dist/access-extraction-force-flush.js +75 -74
  13. package/dist/access-health-types.d.ts +1 -1
  14. package/dist/access-http-briefing.d.ts +16 -14
  15. package/dist/access-http-briefing.js +76 -75
  16. package/dist/access-http-lcm-compaction.d.ts +16 -14
  17. package/dist/access-http-lifecycle-flush.d.ts +16 -14
  18. package/dist/access-http-offline-stream.d.ts +16 -14
  19. package/dist/access-http-query.d.ts +2 -2
  20. package/dist/access-http-query.js +77 -76
  21. package/dist/access-http.d.ts +17 -15
  22. package/dist/access-http.js +95 -92
  23. package/dist/access-identity-continuity-surface.d.ts +13 -12
  24. package/dist/access-identity-continuity-surface.js +75 -74
  25. package/dist/access-lcm-surface.d.ts +16 -14
  26. package/dist/access-lcm-surface.js +75 -74
  27. package/dist/access-mcp-shared-context-tools.d.ts +156 -0
  28. package/dist/access-mcp-shared-context-tools.js +8 -0
  29. package/dist/access-mcp.d.ts +16 -14
  30. package/dist/access-mcp.js +86 -83
  31. package/dist/access-memory-search-fanout.d.ts +2 -2
  32. package/dist/{access-namespace-preflight-DY4z6L5X.d.ts → access-namespace-preflight-DWsMc9Dh.d.ts} +1 -1
  33. package/dist/access-namespace-preflight.d.ts +3 -3
  34. package/dist/access-namespace-preflight.js +75 -74
  35. package/dist/access-observe-transcript.d.ts +13 -12
  36. package/dist/access-observe-write-category.d.ts +1 -1
  37. package/dist/access-observe-write-category.js +4 -4
  38. package/dist/access-observe-write-surface.d.ts +16 -14
  39. package/dist/access-observe-write-surface.js +75 -74
  40. package/dist/access-offline-manifest.d.ts +37 -13
  41. package/dist/access-offline-manifest.js +15 -11
  42. package/dist/access-operations-batch.js +79 -77
  43. package/dist/access-operations.d.ts +16 -14
  44. package/dist/access-operations.js +84 -82
  45. package/dist/access-recall-concurrency.d.ts +16 -14
  46. package/dist/access-recall-concurrency.js +75 -74
  47. package/dist/access-recall-response.d.ts +16 -14
  48. package/dist/access-recall-response.js +75 -74
  49. package/dist/access-recall-surface.d.ts +16 -14
  50. package/dist/access-recall-surface.js +75 -74
  51. package/dist/access-schema.d.ts +5 -3
  52. package/dist/access-schema.js +3 -3
  53. package/dist/{access-service-MY4bsr_Q.d.ts → access-service-Cisy5YDq.d.ts} +14 -9
  54. package/dist/access-service-helpers.d.ts +16 -14
  55. package/dist/access-service.d.ts +16 -14
  56. package/dist/access-service.js +75 -74
  57. package/dist/access-surface-catalog.d.ts +16 -14
  58. package/dist/access-surface-catalog.js +77 -76
  59. package/dist/access-surface-catalog.js.map +1 -1
  60. package/dist/access-wearables-meetings-surface.d.ts +6 -5
  61. package/dist/action-confidence.d.ts +1 -1
  62. package/dist/active-memory-bridge.d.ts +1 -1
  63. package/dist/active-memory-bridge.js +3 -3
  64. package/dist/active-recall.d.ts +1 -1
  65. package/dist/active-recall.js +10 -9
  66. package/dist/active-recall.js.map +1 -1
  67. package/dist/activity/digest.d.ts +1 -1
  68. package/dist/ambient-provenance.d.ts +1 -1
  69. package/dist/artifact-search.d.ts +1 -1
  70. package/dist/{auto-sync-RP4C6ZPF.js → auto-sync-7PGUFY7U.js} +7 -7
  71. package/dist/background-generation-config.d.ts +1 -1
  72. package/dist/background-generation-config.js +3 -1
  73. package/dist/background-generation.d.ts +1 -1
  74. package/dist/behavior-learner.d.ts +1 -1
  75. package/dist/behavior-signals.d.ts +1 -1
  76. package/dist/bootstrap.d.ts +13 -12
  77. package/dist/briefing-window.d.ts +2 -2
  78. package/dist/briefing.d.ts +2 -2
  79. package/dist/briefing.js +23 -23
  80. package/dist/buffer-surprise-report.d.ts +1 -1
  81. package/dist/buffer-turn-helpers.d.ts +1 -1
  82. package/dist/buffer.d.ts +2 -2
  83. package/dist/buffer.js +7 -7
  84. package/dist/bulk-import/index.d.ts +3 -3
  85. package/dist/calibration.d.ts +3 -2
  86. package/dist/calibration.js +2 -2
  87. package/dist/capabilities.d.ts +1 -1
  88. package/dist/{capsule-crypto-7FJQINUR.js → capsule-crypto-YO5QJ6L3.js} +2 -2
  89. package/dist/{capsule-merge-IPG4IOFP.js → capsule-merge-3MNURAQ3.js} +2 -2
  90. package/dist/{catalog-CW87xGx8.d.ts → catalog-wcX1QhtQ.d.ts} +1 -1
  91. package/dist/causal-behavior.d.ts +1 -1
  92. package/dist/causal-consolidation.d.ts +1 -1
  93. package/dist/causal-consolidation.js +29 -28
  94. package/dist/causal-consolidation.js.map +1 -1
  95. package/dist/causal-trajectory-graph.d.ts +1 -1
  96. package/dist/{chunk-YFTNZMGR.js → chunk-27NO2KVB.js} +31 -8
  97. package/dist/chunk-27NO2KVB.js.map +1 -0
  98. package/dist/{chunk-M6RORUO5.js → chunk-2EYZ32LH.js} +24 -2
  99. package/dist/{chunk-M6RORUO5.js.map → chunk-2EYZ32LH.js.map} +1 -1
  100. package/dist/{chunk-XH3HGI2N.js → chunk-2HQPE2NM.js} +2 -2
  101. package/dist/{chunk-3EKVN2OP.js → chunk-2ZG2LLZT.js} +2 -2
  102. package/dist/{chunk-6EHM2AV7.js → chunk-3BLHPQHT.js} +5 -5
  103. package/dist/{chunk-YKREX63Z.js → chunk-3D75XIYO.js} +5 -3
  104. package/dist/chunk-3D75XIYO.js.map +1 -0
  105. package/dist/{chunk-J272ODKJ.js → chunk-42DJ235G.js} +2 -2
  106. package/dist/{chunk-F4EHXVP7.js → chunk-46RII65S.js} +2 -2
  107. package/dist/{chunk-YUW66UAH.js → chunk-4AX5OYKC.js} +2 -2
  108. package/dist/{chunk-AECJY3GJ.js → chunk-4IGOLIWM.js} +2 -2
  109. package/dist/{chunk-2ZTDRNCS.js → chunk-54QPOE45.js} +2 -2
  110. package/dist/{chunk-O4M4BDIJ.js → chunk-563X6JJX.js} +2 -2
  111. package/dist/{chunk-IL6ODG6M.js → chunk-5EQT62HH.js} +2 -2
  112. package/dist/{chunk-JKKII6GX.js → chunk-6MQMYXSQ.js} +2 -2
  113. package/dist/{chunk-TVVEYCNW.js → chunk-7K5Q6COX.js} +4 -4
  114. package/dist/{chunk-BV4ZKIZH.js → chunk-7ZLC4DTZ.js} +5 -4
  115. package/dist/{chunk-WBM2MVBK.js → chunk-A4OIJYCV.js} +2 -2
  116. package/dist/{chunk-RLJHJQUY.js → chunk-AFJHNHAM.js} +8 -8
  117. package/dist/{chunk-6YAIN5XJ.js → chunk-AIVRD66I.js} +44 -6
  118. package/dist/chunk-AIVRD66I.js.map +1 -0
  119. package/dist/{chunk-OEDW4ER7.js → chunk-AJBWVDRV.js} +2 -1
  120. package/dist/chunk-AJBWVDRV.js.map +1 -0
  121. package/dist/{chunk-4RZLTZVM.js → chunk-AKABVXFS.js} +2 -2
  122. package/dist/{chunk-M6HBPLBA.js → chunk-AUSRUOMQ.js} +2 -2
  123. package/dist/{chunk-QHT7MOUF.js → chunk-BTPCP535.js} +25 -14
  124. package/dist/chunk-BTPCP535.js.map +1 -0
  125. package/dist/{chunk-2NLLXCJG.js → chunk-BXLOS5AJ.js} +2 -2
  126. package/dist/{chunk-Q7CLGFA7.js → chunk-C3G6MW4W.js} +3 -3
  127. package/dist/{chunk-O76F5QPP.js → chunk-D6PY63OM.js} +2 -2
  128. package/dist/{chunk-BD7JTBYP.js → chunk-D7MAYFQP.js} +2 -2
  129. package/dist/{chunk-LMLGBG6H.js → chunk-DBB5JPSL.js} +2 -2
  130. package/dist/{chunk-TSP5WH72.js → chunk-DIXZQTGY.js} +2 -2
  131. package/dist/{chunk-P4ZAEYKG.js → chunk-DM5CU5J7.js} +7 -4
  132. package/dist/chunk-DM5CU5J7.js.map +1 -0
  133. package/dist/{chunk-X7Y7WX73.js → chunk-DQEMWVMT.js} +1 -1
  134. package/dist/{chunk-UHRZ324M.js → chunk-E3I3NDUP.js} +4 -4
  135. package/dist/{chunk-AENM6GKU.js → chunk-E4LMQTST.js} +2 -2
  136. package/dist/{chunk-YDVAM7S4.js → chunk-EH3HNCAM.js} +13 -8
  137. package/dist/chunk-EH3HNCAM.js.map +1 -0
  138. package/dist/{chunk-MUTVRKKY.js → chunk-EMSYMYXO.js} +14 -14
  139. package/dist/{chunk-YNDLCWXS.js → chunk-EZ25VE3G.js} +4 -4
  140. package/dist/{chunk-FXHOZGSE.js → chunk-F5H6YG5P.js} +2 -2
  141. package/dist/{chunk-TRLOFIQC.js → chunk-FGFC2EFR.js} +14 -13
  142. package/dist/chunk-FGFC2EFR.js.map +1 -0
  143. package/dist/{chunk-TNSCIPBQ.js → chunk-G6NQ3L4T.js} +2 -2
  144. package/dist/{chunk-ZMWSYUUL.js → chunk-GCBIXUPT.js} +2 -2
  145. package/dist/{chunk-EYKIDK33.js → chunk-GMH5QPUU.js} +22 -22
  146. package/dist/chunk-GMH5QPUU.js.map +1 -0
  147. package/dist/{chunk-4BCHFSC7.js → chunk-GWNSKQDA.js} +3 -3
  148. package/dist/{chunk-JDX2OA4R.js → chunk-HNHIHXSD.js} +2 -2
  149. package/dist/{chunk-GG5FHZJJ.js → chunk-I33QYUAF.js} +6 -6
  150. package/dist/{chunk-LPYYY4AP.js → chunk-I46BYY7U.js} +653 -328
  151. package/dist/chunk-I46BYY7U.js.map +1 -0
  152. package/dist/{chunk-CZTPU65V.js → chunk-ICN37XHG.js} +74 -27
  153. package/dist/chunk-ICN37XHG.js.map +1 -0
  154. package/dist/chunk-IFBSZGW3.js +42 -0
  155. package/dist/chunk-IFBSZGW3.js.map +1 -0
  156. package/dist/{chunk-AAZEKXUP.js → chunk-IYIPXAIJ.js} +2 -2
  157. package/dist/{chunk-ACY4ZPF7.js → chunk-J2MGTGKC.js} +10 -5
  158. package/dist/chunk-J2MGTGKC.js.map +1 -0
  159. package/dist/chunk-JATHBCAV.js +94 -0
  160. package/dist/chunk-JATHBCAV.js.map +1 -0
  161. package/dist/{chunk-5U7K4W6K.js → chunk-JDOBQPJY.js} +3 -3
  162. package/dist/{chunk-TG3FAM2S.js → chunk-JL4TQYM5.js} +48 -1
  163. package/dist/{chunk-TG3FAM2S.js.map → chunk-JL4TQYM5.js.map} +1 -1
  164. package/dist/{chunk-UZZ7SQT3.js → chunk-JMWUPUE6.js} +2 -2
  165. package/dist/{chunk-ENBPQEVU.js → chunk-JSD7Q7LD.js} +2 -2
  166. package/dist/{chunk-QTQ6XKGT.js → chunk-K5D2XVNN.js} +4 -4
  167. package/dist/chunk-K5D2XVNN.js.map +1 -0
  168. package/dist/{chunk-3CBI2ZSA.js → chunk-KG2OOAFF.js} +20 -12
  169. package/dist/chunk-KG2OOAFF.js.map +1 -0
  170. package/dist/{chunk-Q432REND.js → chunk-KJLLPG26.js} +2 -2
  171. package/dist/{chunk-JTQR6L2N.js → chunk-KLUC2GSG.js} +6 -6
  172. package/dist/{chunk-OB3XMWX5.js → chunk-KVO2BTA4.js} +2 -2
  173. package/dist/{chunk-PCOVEDPK.js → chunk-KZJM7R4F.js} +3 -3
  174. package/dist/{chunk-X4TD4O2F.js → chunk-LE2KZ72G.js} +3 -3
  175. package/dist/{chunk-HIP6DKJJ.js → chunk-LQVXSRAJ.js} +2 -2
  176. package/dist/{chunk-A7GQBJP5.js → chunk-LVFI5LG7.js} +7 -7
  177. package/dist/{chunk-FWWWUPOE.js → chunk-MCMS4VUK.js} +25 -15
  178. package/dist/chunk-MCMS4VUK.js.map +1 -0
  179. package/dist/{chunk-5SPCMAUC.js → chunk-N6XTC56E.js} +13 -81
  180. package/dist/chunk-N6XTC56E.js.map +1 -0
  181. package/dist/{chunk-VBSNUH4J.js → chunk-ND7MAIJC.js} +2 -2
  182. package/dist/{chunk-TNZNSMVJ.js → chunk-NYWCFC3K.js} +301 -348
  183. package/dist/chunk-NYWCFC3K.js.map +1 -0
  184. package/dist/{chunk-54NX5EG4.js → chunk-P66QH6R6.js} +2 -2
  185. package/dist/{chunk-62D2PAAM.js → chunk-PAAJWQH5.js} +4 -4
  186. package/dist/{chunk-TA4C3XB7.js → chunk-PFKIOYJH.js} +2 -2
  187. package/dist/{chunk-WIWLX65T.js → chunk-PGGPRF6J.js} +2 -2
  188. package/dist/{chunk-V6EGNVUT.js → chunk-PIWFNPQT.js} +4 -4
  189. package/dist/{chunk-BLDBT6HZ.js → chunk-PJRKLB4Z.js} +18 -2
  190. package/dist/chunk-PJRKLB4Z.js.map +1 -0
  191. package/dist/{chunk-4JVQRFZD.js → chunk-PLJ2MQFT.js} +11 -11
  192. package/dist/{chunk-4RX5O34R.js → chunk-PQ42DJNG.js} +2 -2
  193. package/dist/{chunk-37CAEC7E.js → chunk-PWPIERBM.js} +4 -4
  194. package/dist/{chunk-ZEGL7YCC.js → chunk-Q62GA5U2.js} +2 -2
  195. package/dist/{chunk-CC37E3QM.js → chunk-QKCXRS5A.js} +16 -1
  196. package/dist/chunk-QKCXRS5A.js.map +1 -0
  197. package/dist/{chunk-WKDFJXW5.js → chunk-QM2SPLKQ.js} +1 -1
  198. package/dist/chunk-QM2SPLKQ.js.map +1 -0
  199. package/dist/{chunk-GAS7KYC7.js → chunk-RQQO3ORQ.js} +2 -2
  200. package/dist/{chunk-UZEHHXYC.js → chunk-S4MJTIPG.js} +85 -81
  201. package/dist/chunk-S4MJTIPG.js.map +1 -0
  202. package/dist/chunk-SK7D34OL.js +68 -0
  203. package/dist/chunk-SK7D34OL.js.map +1 -0
  204. package/dist/{chunk-LQNRVPTV.js → chunk-TRTLWUDD.js} +164 -130
  205. package/dist/chunk-TRTLWUDD.js.map +1 -0
  206. package/dist/{chunk-JXN77SGO.js → chunk-U2VDCFXW.js} +1 -1
  207. package/dist/chunk-U2VDCFXW.js.map +1 -0
  208. package/dist/{chunk-CWTCMZGE.js → chunk-UHSOPTNB.js} +132 -6
  209. package/dist/chunk-UHSOPTNB.js.map +1 -0
  210. package/dist/{chunk-3NPNBVFR.js → chunk-UZGHKD3T.js} +2 -2
  211. package/dist/{chunk-IQEJIOEU.js → chunk-V2EXYQEQ.js} +20 -12
  212. package/dist/chunk-V2EXYQEQ.js.map +1 -0
  213. package/dist/{chunk-OPBFP4TF.js → chunk-V2TOGJPM.js} +46 -13
  214. package/dist/chunk-V2TOGJPM.js.map +1 -0
  215. package/dist/{chunk-VJIE4D2I.js → chunk-V62YYBBY.js} +4 -4
  216. package/dist/{chunk-KQAFEZQX.js → chunk-VDX2J7OX.js} +2 -2
  217. package/dist/{chunk-6H2G7RFT.js → chunk-VNQRRUNS.js} +11 -10
  218. package/dist/chunk-VNQRRUNS.js.map +1 -0
  219. package/dist/{chunk-6AGWBKQU.js → chunk-VSN2DMQK.js} +2 -2
  220. package/dist/{chunk-ZHXSOMYH.js → chunk-VVX5PZFS.js} +2 -2
  221. package/dist/{chunk-GI4ZBWPQ.js → chunk-W7UV2ZCA.js} +3 -3
  222. package/dist/{chunk-GMIQV6DD.js → chunk-WBQ4ONQJ.js} +2 -2
  223. package/dist/{chunk-FNHLI2RE.js → chunk-WFMQN7JE.js} +3 -3
  224. package/dist/{chunk-MVAQ2WM3.js → chunk-WGZHSQDV.js} +9 -5
  225. package/dist/chunk-WGZHSQDV.js.map +1 -0
  226. package/dist/{chunk-IYKZJVL5.js → chunk-WN2OXGGH.js} +1 -1
  227. package/dist/chunk-WN2OXGGH.js.map +1 -0
  228. package/dist/{chunk-ZBW7A667.js → chunk-WPGA4RYI.js} +2 -2
  229. package/dist/{chunk-YQNNHLCG.js → chunk-WPGR3RW4.js} +2 -2
  230. package/dist/{chunk-SV4Z2S67.js → chunk-WUUGE7QC.js} +54 -21
  231. package/dist/chunk-WUUGE7QC.js.map +1 -0
  232. package/dist/{chunk-NXGSONWM.js → chunk-WZIO3TW6.js} +2 -2
  233. package/dist/{chunk-ZZUVBZL2.js → chunk-X2QPKLPL.js} +2 -2
  234. package/dist/{chunk-5HYUUFMQ.js → chunk-XCPNH2MG.js} +259 -10
  235. package/dist/chunk-XCPNH2MG.js.map +1 -0
  236. package/dist/{chunk-VSL63CFJ.js → chunk-XRS65T4O.js} +9 -9
  237. package/dist/{chunk-5N4MZLEH.js → chunk-YFXAWGMR.js} +2 -2
  238. package/dist/{chunk-KQW3YGEN.js → chunk-YR5QT4SR.js} +32 -9
  239. package/dist/chunk-YR5QT4SR.js.map +1 -0
  240. package/dist/{chunk-CARRTDKC.js → chunk-Z22M4JCY.js} +4 -3
  241. package/dist/chunk-Z22M4JCY.js.map +1 -0
  242. package/dist/{chunk-D545Z7UH.js → chunk-Z535ADTC.js} +3 -3
  243. package/dist/{chunk-B36GUU6T.js → chunk-Z7NBT6AK.js} +38 -5
  244. package/dist/chunk-Z7NBT6AK.js.map +1 -0
  245. package/dist/{chunk-5YCNDC3C.js → chunk-ZX6NNFSY.js} +3 -3
  246. package/dist/{chunk-3N3PBBEH.js → chunk-ZYSOT6HD.js} +2 -2
  247. package/dist/{chunk-MCRVQ5YQ.js → chunk-ZZEIL3MI.js} +2 -2
  248. package/dist/{cli-DGq0MNpO.d.ts → cli-CUlMlS2N.d.ts} +5 -5
  249. package/dist/cli.d.ts +18 -16
  250. package/dist/cli.js +129 -126
  251. package/dist/coding/export-okf-codegraph.d.ts +1 -1
  252. package/dist/coding/export-okf-codegraph.js +22 -22
  253. package/dist/coding/pre-action-gate.d.ts +1 -1
  254. package/dist/compounding/engine.d.ts +2 -2
  255. package/dist/compounding/engine.js +25 -25
  256. package/dist/compounding/preference-consolidator.d.ts +1 -1
  257. package/dist/compression-optimizer.d.ts +1 -1
  258. package/dist/config.d.ts +1 -1
  259. package/dist/config.js +10 -9
  260. package/dist/connectors/codex-materialize-runner.d.ts +1 -1
  261. package/dist/connectors/codex-materialize-runner.js +25 -25
  262. package/dist/connectors/codex-materialize.d.ts +1 -1
  263. package/dist/connectors/codex-materialize.js +2 -2
  264. package/dist/connectors/index.d.ts +1 -1
  265. package/dist/connectors/index.js +25 -25
  266. package/dist/consolidation-provenance-check.d.ts +2 -2
  267. package/dist/consolidation-undo.d.ts +2 -2
  268. package/dist/contradiction/index.d.ts +6 -5
  269. package/dist/contradiction/index.js +4 -4
  270. package/dist/{contradiction-scan-BSGKZHYJ.js → contradiction-scan-GVD4JJ7B.js} +4 -4
  271. package/dist/converge-config.d.ts +1 -1
  272. package/dist/convergence-refresh.d.ts +2 -2
  273. package/dist/convergence-refresh.js +26 -26
  274. package/dist/conversation-index/backend.d.ts +1 -1
  275. package/dist/conversation-index/chunker.d.ts +1 -1
  276. package/dist/conversation-index/faiss-adapter.d.ts +1 -1
  277. package/dist/conversation-index/indexer.d.ts +1 -1
  278. package/dist/conversation-index/search.d.ts +1 -1
  279. package/dist/corpus-watermark.d.ts +1 -1
  280. package/dist/corpus-watermark.js +25 -25
  281. package/dist/cross-lingual-recall.d.ts +1 -1
  282. package/dist/dashboard-runtime.js +2 -2
  283. package/dist/day-summary.d.ts +1 -1
  284. package/dist/deep-recall-config.d.ts +12 -1
  285. package/dist/deep-recall-config.js +5 -3
  286. package/dist/deep-recall-http-glue.d.ts +19 -15
  287. package/dist/deep-recall-http-glue.js +7 -4
  288. package/dist/deep-recall-mcp-tools.d.ts +16 -14
  289. package/dist/deep-recall-policy-llm.d.ts +14 -3
  290. package/dist/deep-recall-policy-llm.js +3 -3
  291. package/dist/deep-recall-seeds.d.ts +4 -1
  292. package/dist/deep-recall-seeds.js +1 -1
  293. package/dist/deep-recall.d.ts +12 -1
  294. package/dist/deep-recall.js +3 -2
  295. package/dist/delinearize.d.ts +1 -1
  296. package/dist/dependency-propagation-config.d.ts +1 -1
  297. package/dist/{dependency-propagation-delivery-Cq1ekOwV.d.ts → dependency-propagation-delivery-BDDjImQn.d.ts} +1 -1
  298. package/dist/direct-answer-wiring.d.ts +1 -1
  299. package/dist/direct-answer.d.ts +1 -1
  300. package/dist/embedding-fallback.d.ts +1 -1
  301. package/dist/enrichment/index.d.ts +1 -1
  302. package/dist/entity-origin-fields.d.ts +1 -1
  303. package/dist/entity-retrieval.d.ts +2 -2
  304. package/dist/entity-retrieval.js +24 -24
  305. package/dist/entity-schema.d.ts +1 -1
  306. package/dist/episodic-context.d.ts +1 -1
  307. package/dist/eval-trajectory-contracts.d.ts +1 -1
  308. package/dist/eval-trajectory-store.d.ts +1 -1
  309. package/dist/eval-trajectory.d.ts +1 -1
  310. package/dist/explicit-capture.d.ts +13 -12
  311. package/dist/explicit-capture.js +3 -3
  312. package/dist/external-wiki-access.d.ts +16 -14
  313. package/dist/external-wiki-access.js +76 -75
  314. package/dist/external-wiki-collection-registration.d.ts +1 -1
  315. package/dist/external-wiki-collection.d.ts +1 -1
  316. package/dist/external-wiki-mcp-tools.d.ts +16 -14
  317. package/dist/extraction-error-classification.d.ts +14 -3
  318. package/dist/extraction-error-classification.js +5 -3
  319. package/dist/extraction-faithfulness.d.ts +4 -3
  320. package/dist/extraction-faithfulness.js +3 -3
  321. package/dist/extraction-judge-telemetry.d.ts +4 -3
  322. package/dist/extraction-judge-training.d.ts +4 -3
  323. package/dist/extraction-judge.d.ts +4 -3
  324. package/dist/extraction-judge.js +3 -3
  325. package/dist/extraction-liveness.d.ts +1 -1
  326. package/dist/extraction-normalization.d.ts +1 -1
  327. package/dist/extraction-prompt.d.ts +1 -1
  328. package/dist/extraction-source-grounding-rules.d.ts +1 -1
  329. package/dist/extraction-source-grounding.d.ts +1 -1
  330. package/dist/extraction-span-config.d.ts +1 -1
  331. package/dist/extraction-span-materialize.d.ts +1 -1
  332. package/dist/extraction.d.ts +4 -4
  333. package/dist/extraction.js +40 -38
  334. package/dist/fallback-llm-codex-subscription.d.ts +65 -10
  335. package/dist/fallback-llm-codex-subscription.js +19 -1
  336. package/dist/fallback-llm.d.ts +25 -28
  337. package/dist/fallback-llm.js +4 -3
  338. package/dist/{first-start-migration-ZWMV5CX4.js → first-start-migration-L3UFX5CU.js} +4 -4
  339. package/dist/{generic-recall-paths-BcySh_f9.d.ts → generic-recall-paths-CpDzNO_I.d.ts} +1 -1
  340. package/dist/graph-append-error.d.ts +1 -1
  341. package/dist/graph-dashboard-diff.d.ts +1 -1
  342. package/dist/graph-dashboard-key.d.ts +1 -1
  343. package/dist/graph-dashboard-parser.d.ts +1 -1
  344. package/dist/graph-edge-reinforcement.d.ts +1 -1
  345. package/dist/graph-jsonl.d.ts +1 -1
  346. package/dist/graph-path-reconstruction.d.ts +1 -1
  347. package/dist/graph-path-scoring.d.ts +1 -1
  348. package/dist/graph-snapshot.d.ts +1 -1
  349. package/dist/graph.d.ts +1 -1
  350. package/dist/harmonic-retrieval.js +3 -3
  351. package/dist/importance.d.ts +1 -1
  352. package/dist/importers/index.d.ts +1 -1
  353. package/dist/importers/test-utils.d.ts +1 -1
  354. package/dist/in-flight-reads.d.ts +1 -1
  355. package/dist/{index-DWOb4wz9.d.ts → index-CtmmCJoo.d.ts} +3 -3
  356. package/dist/index.d.ts +80 -40
  357. package/dist/index.js +316 -296
  358. package/dist/intent.d.ts +1 -1
  359. package/dist/lcm/engine.d.ts +1 -1
  360. package/dist/lcm/engine.js +3 -3
  361. package/dist/lcm/index.d.ts +1 -1
  362. package/dist/lcm/index.js +11 -11
  363. package/dist/lcm/tools.d.ts +1 -1
  364. package/dist/lifecycle.d.ts +1 -1
  365. package/dist/live-connectors-runner.d.ts +1 -1
  366. package/dist/local-llm-DpXIvm6F.d.ts +247 -0
  367. package/dist/local-llm-config.d.ts +4 -1
  368. package/dist/local-llm-config.js +4 -2
  369. package/dist/local-llm-helpers.d.ts +18 -69
  370. package/dist/local-llm-helpers.js +1 -1
  371. package/dist/local-llm.d.ts +3 -170
  372. package/dist/local-llm.js +2 -2
  373. package/dist/local-model-endpoint.d.ts +1 -1
  374. package/dist/location/index.d.ts +3 -3
  375. package/dist/location/index.js +25 -25
  376. package/dist/maintenance/memory-governance.d.ts +1 -1
  377. package/dist/maintenance/memory-governance.js +24 -24
  378. package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -2
  379. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +23 -23
  380. package/dist/maintenance/rebuild-memory-projection.d.ts +2 -2
  381. package/dist/maintenance/rebuild-memory-projection.js +25 -25
  382. package/dist/{maintenance-CW9wCzMP.d.ts → maintenance-CNgoLsoM.d.ts} +13 -6
  383. package/dist/mcp-memory-inspector-app.d.ts +16 -14
  384. package/dist/memory-action-policy.d.ts +1 -1
  385. package/dist/memory-cache.d.ts +1 -1
  386. package/dist/memory-controller.d.ts +1 -1
  387. package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
  388. package/dist/memory-projection-store.d.ts +1 -1
  389. package/dist/memory-provenance.d.ts +1 -1
  390. package/dist/memory-snapshot.d.ts +1 -1
  391. package/dist/memory-subject-cli.d.ts +16 -14
  392. package/dist/memory-subject.d.ts +16 -14
  393. package/dist/memory-worth-outcomes.d.ts +2 -2
  394. package/dist/models-json.d.ts +1 -1
  395. package/dist/namespaces/migrate.d.ts +3 -3
  396. package/dist/namespaces/migrate.js +24 -24
  397. package/dist/namespaces/principal.d.ts +1 -1
  398. package/dist/namespaces/search.d.ts +12 -1
  399. package/dist/namespaces/search.js +9 -9
  400. package/dist/namespaces/storage.d.ts +3 -3
  401. package/dist/namespaces/storage.js +23 -23
  402. package/dist/native-knowledge.d.ts +1 -1
  403. package/dist/offline-sync-impression-drain.d.ts +1 -1
  404. package/dist/operator-doctor-corpus.d.ts +1 -1
  405. package/dist/operator-doctor-corpus.js +26 -26
  406. package/dist/operator-doctor-replica.d.ts +1 -1
  407. package/dist/operator-toolkit.d.ts +3 -3
  408. package/dist/operator-toolkit.js +45 -44
  409. package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -2
  410. package/dist/orchestration/maintenance.d.ts +4 -4
  411. package/dist/orchestration/maintenance.js +36 -36
  412. package/dist/{orchestrator-ComHLm49.d.ts → orchestrator-DT7ybIFz.d.ts} +32 -11
  413. package/dist/orchestrator.d.ts +13 -12
  414. package/dist/orchestrator.js +176 -171
  415. package/dist/patterns-cli.d.ts +1 -1
  416. package/dist/{pipeline-CiYcqqhl.d.ts → pipeline-CgBEmHcz.d.ts} +1 -1
  417. package/dist/policy-runtime.d.ts +1 -1
  418. package/dist/proactive-contention.d.ts +2 -2
  419. package/dist/provenance.d.ts +1 -1
  420. package/dist/{public-http-CuK4_Cb1.d.ts → public-http-C8P8fyiO.d.ts} +1 -1
  421. package/dist/{qmd-qXD4vatU.d.ts → qmd-BkY8KpCh.d.ts} +2 -2
  422. package/dist/qmd-preflight.d.ts +2 -2
  423. package/dist/qmd-recall-cache.d.ts +1 -1
  424. package/dist/qmd.d.ts +2 -2
  425. package/dist/qmd.js +2 -2
  426. package/dist/recall-concurrency-config.d.ts +1 -1
  427. package/dist/recall-disclosure-escalation.d.ts +1 -1
  428. package/dist/recall-explain-renderer.d.ts +1 -1
  429. package/dist/recall-explain-renderer.js +3 -3
  430. package/dist/recall-memory-map.d.ts +1 -1
  431. package/dist/recall-navigate-access.d.ts +1 -1
  432. package/dist/recall-navigate-access.js +2 -2
  433. package/dist/recall-navigate-disclosure.d.ts +1 -1
  434. package/dist/recall-navigate-disclosure.js +1 -1
  435. package/dist/recall-navigate.d.ts +1 -1
  436. package/dist/recall-navigate.js +2 -2
  437. package/dist/recall-planner-llm.d.ts +3 -2
  438. package/dist/recall-planner-llm.js +4 -3
  439. package/dist/recall-planner-llm.js.map +1 -1
  440. package/dist/recall-state-view-admission.d.ts +13 -3
  441. package/dist/recall-state-view-admission.js +9 -9
  442. package/dist/recall-state-view-anchors.d.ts +1 -1
  443. package/dist/recall-state-view-anchors.js +2 -2
  444. package/dist/recall-state-view-inject.js +2 -2
  445. package/dist/recall-state-view-render.js +2 -2
  446. package/dist/recall-state-view-widen.js +2 -2
  447. package/dist/recall-state-view-wire.js +3 -3
  448. package/dist/recall-state-view.d.ts +10 -1
  449. package/dist/recall-state-view.js +5 -3
  450. package/dist/recall-state.d.ts +1 -1
  451. package/dist/recall-tag-filter.d.ts +1 -1
  452. package/dist/recall-timings.d.ts +1 -1
  453. package/dist/recall-xray-cli.d.ts +1 -1
  454. package/dist/recall-xray-cli.js +4 -4
  455. package/dist/recall-xray-renderer.d.ts +1 -1
  456. package/dist/recall-xray-renderer.js +3 -3
  457. package/dist/recall-xray.d.ts +1 -1
  458. package/dist/recall-xray.js +2 -2
  459. package/dist/reconcile/cursor.d.ts +1 -1
  460. package/dist/reconcile/cursor.js +2 -2
  461. package/dist/reconcile/manifest.d.ts +1 -1
  462. package/dist/reconcile/manifest.js +4 -4
  463. package/dist/reconcile/plan.d.ts +1 -1
  464. package/dist/reconcile/plan.js +2 -2
  465. package/dist/replay/normalizers/chatgpt.d.ts +1 -1
  466. package/dist/replay/normalizers/claude.d.ts +1 -1
  467. package/dist/replay/normalizers/openclaw.d.ts +1 -1
  468. package/dist/replay/normalizers/shared.d.ts +1 -1
  469. package/dist/replay/runner.d.ts +1 -1
  470. package/dist/replay/types.d.ts +1 -1
  471. package/dist/replica-divergence.d.ts +1 -1
  472. package/dist/replica-peers-config.d.ts +1 -1
  473. package/dist/{resolution-4GG3QZRJ.js → resolution-LXFQQ4AE.js} +5 -5
  474. package/dist/resolution-LXFQQ4AE.js.map +1 -0
  475. package/dist/resolve-auth-token.d.ts +1 -1
  476. package/dist/resume-bundles.js +12 -11
  477. package/dist/retrieval-agents.d.ts +2 -2
  478. package/dist/retrieval-tiers.d.ts +1 -1
  479. package/dist/routing/engine.d.ts +1 -1
  480. package/dist/routing/store.d.ts +1 -1
  481. package/dist/salvage-envelope.d.ts +1 -1
  482. package/dist/{scope-profiles-BT9rqC3w.d.ts → scope-profiles-BBPjZ9jb.d.ts} +1 -1
  483. package/dist/search/embed-helper.d.ts +1 -1
  484. package/dist/search/factory.d.ts +1 -1
  485. package/dist/search/factory.js +8 -8
  486. package/dist/search/index.d.ts +1 -1
  487. package/dist/search/index.js +12 -12
  488. package/dist/search/lancedb-backend.d.ts +1 -1
  489. package/dist/search/lancedb-backend.js +2 -2
  490. package/dist/search/meilisearch-backend.d.ts +1 -1
  491. package/dist/search/meilisearch-backend.js +2 -2
  492. package/dist/search/noop-backend.d.ts +1 -1
  493. package/dist/search/orama-backend.d.ts +1 -1
  494. package/dist/search/orama-backend.js +2 -2
  495. package/dist/search/port.d.ts +2 -2
  496. package/dist/search/port.js +1 -1
  497. package/dist/search/remote-backend.d.ts +1 -1
  498. package/dist/search/remote-backend.js +2 -2
  499. package/dist/{semantic-consolidation-CmZi7thY.d.ts → semantic-consolidation-BPFFVO84.d.ts} +1 -1
  500. package/dist/semantic-consolidation.d.ts +2 -2
  501. package/dist/semantic-consolidation.js +26 -26
  502. package/dist/semantic-rule-promotion.js +23 -23
  503. package/dist/semantic-rule-verifier.d.ts +1 -1
  504. package/dist/semantic-rule-verifier.js +23 -23
  505. package/dist/{service-CLkA7AQB.d.ts → service-jKcr6Jvr.d.ts} +2 -2
  506. package/dist/session-observer-bands.d.ts +1 -1
  507. package/dist/session-observer-state.d.ts +1 -1
  508. package/dist/shared-context/manager.d.ts +1 -1
  509. package/dist/shared-context/manager.js +2 -2
  510. package/dist/shared-context/write-output-controls.d.ts +34 -0
  511. package/dist/shared-context/write-output-controls.js +10 -0
  512. package/dist/shared-context/write-output-controls.js.map +1 -0
  513. package/dist/signal.d.ts +1 -1
  514. package/dist/source-agent-qualifier.d.ts +1 -1
  515. package/dist/source-agent-qualifier.js +31 -31
  516. package/dist/source-attribution.d.ts +23 -1
  517. package/dist/source-attribution.js +13 -3
  518. package/dist/standup/build.js +23 -23
  519. package/dist/{storage-wvX01lht.d.ts → storage-C-0Ah5OY.d.ts} +2 -1
  520. package/dist/storage.d.ts +2 -2
  521. package/dist/storage.js +22 -22
  522. package/dist/subject-config.d.ts +1 -1
  523. package/dist/summarizer.d.ts +1 -1
  524. package/dist/summarizer.js +6 -6
  525. package/dist/summary-snapshot.d.ts +1 -1
  526. package/dist/support-passport/index.d.ts +18 -17
  527. package/dist/support-passport/index.js +78 -77
  528. package/dist/task-llm-config.d.ts +16 -0
  529. package/dist/task-llm-config.js +12 -0
  530. package/dist/task-llm-config.js.map +1 -0
  531. package/dist/temporal-supersession.d.ts +2 -2
  532. package/dist/temporal-timeline-recall.d.ts +1 -1
  533. package/dist/temporal-validity.d.ts +1 -1
  534. package/dist/threading.d.ts +1 -1
  535. package/dist/tier-migration.d.ts +2 -2
  536. package/dist/tier-routing.d.ts +1 -1
  537. package/dist/tier-routing.js +3 -3
  538. package/dist/{tier-stats-LUSUUNU6.js → tier-stats-VK5PCO2L.js} +4 -4
  539. package/dist/topics.d.ts +1 -1
  540. package/dist/transcript.d.ts +1 -1
  541. package/dist/transfer/backup.js +2 -2
  542. package/dist/transfer/capsule-export.js +2 -2
  543. package/dist/transfer/capsule-import.js +3 -3
  544. package/dist/transfer/export-okf.d.ts +1 -1
  545. package/dist/transfer/export-okf.js +23 -23
  546. package/dist/trust-score-stage.d.ts +1 -1
  547. package/dist/trust-score.d.ts +1 -1
  548. package/dist/{types-Cyr32ABj.d.ts → types-cK5LydjL.d.ts} +6 -1
  549. package/dist/types.d.ts +1 -1
  550. package/dist/types.js +1 -1
  551. package/dist/utility-runtime.d.ts +1 -1
  552. package/dist/verified-recall.js +23 -23
  553. package/dist/who-knows-cli.d.ts +16 -14
  554. package/dist/who-knows-cli.js +24 -24
  555. package/dist/who-knows.d.ts +16 -14
  556. package/dist/who-knows.js +23 -23
  557. package/dist/write-envelope.d.ts +1 -1
  558. package/package.json +12 -2
  559. package/src/access-category-alias.test.ts +93 -0
  560. package/src/access-http.ts +1 -1
  561. package/src/access-mcp-shared-context-tools.ts +103 -0
  562. package/src/access-mcp.ts +4 -74
  563. package/src/access-offline-manifest.ts +52 -2
  564. package/src/access-operations-batch.ts +45 -2
  565. package/src/access-schema.ts +9 -4
  566. package/src/access-service.ts +14 -7
  567. package/src/activity/config.test.ts +61 -0
  568. package/src/activity/config.ts +40 -1
  569. package/src/activity/timeline/analysis-provider.ts +8 -2
  570. package/src/activity/timeline/analysis-run.test.ts +82 -0
  571. package/src/activity/timeline/publish-cli.test.ts +30 -0
  572. package/src/activity/timeline/publish-cli.ts +7 -0
  573. package/src/activity/timeline/query.ts +8 -1
  574. package/src/activity/timeline/regenerate.test.ts +130 -2
  575. package/src/activity/timeline/regenerate.ts +14 -6
  576. package/src/activity/vault-frontmatter.test.ts +99 -1
  577. package/src/activity/vault-frontmatter.ts +131 -0
  578. package/src/activity/vault-publish.ts +6 -0
  579. package/src/activity/vault-publisher.test.ts +172 -0
  580. package/src/activity/vault-publisher.ts +69 -15
  581. package/src/activity/vault-region.test.ts +7 -2
  582. package/src/activity/vault-region.ts +7 -3
  583. package/src/background-generation-config.ts +32 -6
  584. package/src/background-generation.test.ts +10 -1
  585. package/src/cli/deep-recall-commands.ts +22 -10
  586. package/src/cli/timeline-publish-commands.ts +9 -0
  587. package/src/config.test.ts +170 -43
  588. package/src/config.ts +22 -5
  589. package/src/dedup/merge.test.ts +283 -0
  590. package/src/deep-recall-boundary.test.ts +66 -0
  591. package/src/deep-recall-cli.test.ts +82 -0
  592. package/src/deep-recall-config.test.ts +56 -0
  593. package/src/deep-recall-config.ts +32 -0
  594. package/src/deep-recall-http-glue.ts +10 -10
  595. package/src/deep-recall-policy-llm.test.ts +242 -0
  596. package/src/deep-recall-policy-llm.ts +37 -7
  597. package/src/deep-recall-seeds.test.ts +53 -0
  598. package/src/deep-recall-seeds.ts +7 -1
  599. package/src/deep-recall-surface.test.ts +93 -0
  600. package/src/deep-recall.test.ts +121 -0
  601. package/src/deep-recall.ts +88 -28
  602. package/src/extraction-error-classification.ts +36 -1
  603. package/src/extraction-timeout.test.ts +110 -1
  604. package/src/extraction.test.ts +19 -1
  605. package/src/extraction.ts +23 -21
  606. package/src/fallback-llm-codex-subscription.ts +220 -12
  607. package/src/fallback-llm-parse-failure.test.ts +156 -0
  608. package/src/fallback-llm.test.ts +178 -0
  609. package/src/fallback-llm.ts +200 -198
  610. package/src/index.ts +1 -0
  611. package/src/local-llm-config.ts +11 -10
  612. package/src/local-llm-headers-timeout.test.ts +30 -0
  613. package/src/local-llm-helpers.ts +28 -0
  614. package/src/local-llm.ts +8 -19
  615. package/src/meetings/config.test.ts +58 -0
  616. package/src/namespaces/search.test.ts +51 -1
  617. package/src/namespaces/search.ts +48 -3
  618. package/src/orchestration/extraction-persist-promotion.test.ts +228 -2
  619. package/src/orchestration/extraction-persist-promotion.ts +17 -14
  620. package/src/orchestration/extraction-persist.ts +1 -1
  621. package/src/orchestration/orchestrator-helpers.test.ts +104 -0
  622. package/src/orchestration/orchestrator-init.ts +366 -106
  623. package/src/orchestration/recall-entry.ts +15 -1
  624. package/src/orchestration/recall-internal.ts +6 -11
  625. package/src/orchestration/recall-section-coordinator.ts +65 -28
  626. package/src/orchestration/recall-state-view-pipeline.test.ts +8 -2
  627. package/src/orchestration/semantic-merge-commit-effects.ts +45 -16
  628. package/src/orchestration/semantic-merge-persist.ts +23 -36
  629. package/src/orchestration/semantic-merge-promotion-payload.ts +62 -6
  630. package/src/orchestration/startup-collection-checks.ts +85 -0
  631. package/src/orchestrator-flush.test.ts +7 -0
  632. package/src/orchestrator-init.test.ts +1539 -0
  633. package/src/orchestrator.ts +7 -0
  634. package/src/providers/codex-subscription.test.ts +127 -0
  635. package/src/providers/codex-subscription.ts +1 -1
  636. package/src/qmd.ts +21 -10
  637. package/src/recall-state-view-admission.ts +11 -1
  638. package/src/recall-state-view-budget.test.ts +424 -0
  639. package/src/recall-state-view-cron-intent.test.ts +268 -0
  640. package/src/recall-state-view-widen.test.ts +14 -5
  641. package/src/recall-state-view-widen.ts +8 -1
  642. package/src/recall-state-view.ts +35 -18
  643. package/src/reconcile-identity-cache.test.ts +82 -1
  644. package/src/search/port.ts +1 -1
  645. package/src/shared-context/envelope-io.ts +25 -0
  646. package/src/shared-context/envelope-wiring.test.ts +4 -2
  647. package/src/shared-context/manager.ts +1 -0
  648. package/src/shared-context/write-output-controls.test.ts +192 -0
  649. package/src/shared-context/write-output-controls.ts +72 -0
  650. package/src/source-attribution.test.ts +39 -0
  651. package/src/source-attribution.ts +72 -0
  652. package/src/storage/cas-revision-store.test.ts +4 -0
  653. package/src/storage/cas-revision-store.ts +104 -12
  654. package/src/storage-frontmatter-cas.test.ts +19 -17
  655. package/src/summarizer.ts +5 -1
  656. package/src/task-llm-config.test.ts +124 -0
  657. package/src/task-llm-config.ts +88 -0
  658. package/src/testing/subjects/startup-discovery-lifecycle.test.ts +273 -0
  659. package/src/types.ts +6 -0
  660. package/dist/chunk-3CBI2ZSA.js.map +0 -1
  661. package/dist/chunk-5HYUUFMQ.js.map +0 -1
  662. package/dist/chunk-5SPCMAUC.js.map +0 -1
  663. package/dist/chunk-6H2G7RFT.js.map +0 -1
  664. package/dist/chunk-6YAIN5XJ.js.map +0 -1
  665. package/dist/chunk-ACY4ZPF7.js.map +0 -1
  666. package/dist/chunk-B36GUU6T.js.map +0 -1
  667. package/dist/chunk-BLDBT6HZ.js.map +0 -1
  668. package/dist/chunk-CARRTDKC.js.map +0 -1
  669. package/dist/chunk-CC37E3QM.js.map +0 -1
  670. package/dist/chunk-CWTCMZGE.js.map +0 -1
  671. package/dist/chunk-CZTPU65V.js.map +0 -1
  672. package/dist/chunk-EYKIDK33.js.map +0 -1
  673. package/dist/chunk-FWWWUPOE.js.map +0 -1
  674. package/dist/chunk-IQEJIOEU.js.map +0 -1
  675. package/dist/chunk-IYKZJVL5.js.map +0 -1
  676. package/dist/chunk-JXN77SGO.js.map +0 -1
  677. package/dist/chunk-KQW3YGEN.js.map +0 -1
  678. package/dist/chunk-LPYYY4AP.js.map +0 -1
  679. package/dist/chunk-LQNRVPTV.js.map +0 -1
  680. package/dist/chunk-MVAQ2WM3.js.map +0 -1
  681. package/dist/chunk-OEDW4ER7.js.map +0 -1
  682. package/dist/chunk-OPBFP4TF.js.map +0 -1
  683. package/dist/chunk-P4ZAEYKG.js.map +0 -1
  684. package/dist/chunk-QHT7MOUF.js.map +0 -1
  685. package/dist/chunk-QTQ6XKGT.js.map +0 -1
  686. package/dist/chunk-SV4Z2S67.js.map +0 -1
  687. package/dist/chunk-TNZNSMVJ.js.map +0 -1
  688. package/dist/chunk-TRLOFIQC.js.map +0 -1
  689. package/dist/chunk-UZEHHXYC.js.map +0 -1
  690. package/dist/chunk-WKDFJXW5.js.map +0 -1
  691. package/dist/chunk-YDVAM7S4.js.map +0 -1
  692. package/dist/chunk-YFTNZMGR.js.map +0 -1
  693. package/dist/chunk-YKREX63Z.js.map +0 -1
  694. /package/dist/{capsule-crypto-7FJQINUR.js.map → access-mcp-shared-context-tools.js.map} +0 -0
  695. /package/dist/{auto-sync-RP4C6ZPF.js.map → auto-sync-7PGUFY7U.js.map} +0 -0
  696. /package/dist/{contradiction-scan-BSGKZHYJ.js.map → capsule-crypto-YO5QJ6L3.js.map} +0 -0
  697. /package/dist/{capsule-merge-IPG4IOFP.js.map → capsule-merge-3MNURAQ3.js.map} +0 -0
  698. /package/dist/{chunk-XH3HGI2N.js.map → chunk-2HQPE2NM.js.map} +0 -0
  699. /package/dist/{chunk-3EKVN2OP.js.map → chunk-2ZG2LLZT.js.map} +0 -0
  700. /package/dist/{chunk-6EHM2AV7.js.map → chunk-3BLHPQHT.js.map} +0 -0
  701. /package/dist/{chunk-J272ODKJ.js.map → chunk-42DJ235G.js.map} +0 -0
  702. /package/dist/{chunk-F4EHXVP7.js.map → chunk-46RII65S.js.map} +0 -0
  703. /package/dist/{chunk-YUW66UAH.js.map → chunk-4AX5OYKC.js.map} +0 -0
  704. /package/dist/{chunk-AECJY3GJ.js.map → chunk-4IGOLIWM.js.map} +0 -0
  705. /package/dist/{chunk-2ZTDRNCS.js.map → chunk-54QPOE45.js.map} +0 -0
  706. /package/dist/{chunk-O4M4BDIJ.js.map → chunk-563X6JJX.js.map} +0 -0
  707. /package/dist/{chunk-IL6ODG6M.js.map → chunk-5EQT62HH.js.map} +0 -0
  708. /package/dist/{chunk-JKKII6GX.js.map → chunk-6MQMYXSQ.js.map} +0 -0
  709. /package/dist/{chunk-TVVEYCNW.js.map → chunk-7K5Q6COX.js.map} +0 -0
  710. /package/dist/{chunk-BV4ZKIZH.js.map → chunk-7ZLC4DTZ.js.map} +0 -0
  711. /package/dist/{chunk-WBM2MVBK.js.map → chunk-A4OIJYCV.js.map} +0 -0
  712. /package/dist/{chunk-RLJHJQUY.js.map → chunk-AFJHNHAM.js.map} +0 -0
  713. /package/dist/{chunk-4RZLTZVM.js.map → chunk-AKABVXFS.js.map} +0 -0
  714. /package/dist/{chunk-M6HBPLBA.js.map → chunk-AUSRUOMQ.js.map} +0 -0
  715. /package/dist/{chunk-2NLLXCJG.js.map → chunk-BXLOS5AJ.js.map} +0 -0
  716. /package/dist/{chunk-Q7CLGFA7.js.map → chunk-C3G6MW4W.js.map} +0 -0
  717. /package/dist/{chunk-O76F5QPP.js.map → chunk-D6PY63OM.js.map} +0 -0
  718. /package/dist/{chunk-BD7JTBYP.js.map → chunk-D7MAYFQP.js.map} +0 -0
  719. /package/dist/{chunk-LMLGBG6H.js.map → chunk-DBB5JPSL.js.map} +0 -0
  720. /package/dist/{chunk-TSP5WH72.js.map → chunk-DIXZQTGY.js.map} +0 -0
  721. /package/dist/{chunk-X7Y7WX73.js.map → chunk-DQEMWVMT.js.map} +0 -0
  722. /package/dist/{chunk-UHRZ324M.js.map → chunk-E3I3NDUP.js.map} +0 -0
  723. /package/dist/{chunk-AENM6GKU.js.map → chunk-E4LMQTST.js.map} +0 -0
  724. /package/dist/{chunk-MUTVRKKY.js.map → chunk-EMSYMYXO.js.map} +0 -0
  725. /package/dist/{chunk-YNDLCWXS.js.map → chunk-EZ25VE3G.js.map} +0 -0
  726. /package/dist/{chunk-FXHOZGSE.js.map → chunk-F5H6YG5P.js.map} +0 -0
  727. /package/dist/{chunk-TNSCIPBQ.js.map → chunk-G6NQ3L4T.js.map} +0 -0
  728. /package/dist/{chunk-ZMWSYUUL.js.map → chunk-GCBIXUPT.js.map} +0 -0
  729. /package/dist/{chunk-4BCHFSC7.js.map → chunk-GWNSKQDA.js.map} +0 -0
  730. /package/dist/{chunk-JDX2OA4R.js.map → chunk-HNHIHXSD.js.map} +0 -0
  731. /package/dist/{chunk-GG5FHZJJ.js.map → chunk-I33QYUAF.js.map} +0 -0
  732. /package/dist/{chunk-AAZEKXUP.js.map → chunk-IYIPXAIJ.js.map} +0 -0
  733. /package/dist/{chunk-5U7K4W6K.js.map → chunk-JDOBQPJY.js.map} +0 -0
  734. /package/dist/{chunk-UZZ7SQT3.js.map → chunk-JMWUPUE6.js.map} +0 -0
  735. /package/dist/{chunk-ENBPQEVU.js.map → chunk-JSD7Q7LD.js.map} +0 -0
  736. /package/dist/{chunk-Q432REND.js.map → chunk-KJLLPG26.js.map} +0 -0
  737. /package/dist/{chunk-JTQR6L2N.js.map → chunk-KLUC2GSG.js.map} +0 -0
  738. /package/dist/{chunk-OB3XMWX5.js.map → chunk-KVO2BTA4.js.map} +0 -0
  739. /package/dist/{chunk-PCOVEDPK.js.map → chunk-KZJM7R4F.js.map} +0 -0
  740. /package/dist/{chunk-X4TD4O2F.js.map → chunk-LE2KZ72G.js.map} +0 -0
  741. /package/dist/{chunk-HIP6DKJJ.js.map → chunk-LQVXSRAJ.js.map} +0 -0
  742. /package/dist/{chunk-A7GQBJP5.js.map → chunk-LVFI5LG7.js.map} +0 -0
  743. /package/dist/{chunk-VBSNUH4J.js.map → chunk-ND7MAIJC.js.map} +0 -0
  744. /package/dist/{chunk-54NX5EG4.js.map → chunk-P66QH6R6.js.map} +0 -0
  745. /package/dist/{chunk-62D2PAAM.js.map → chunk-PAAJWQH5.js.map} +0 -0
  746. /package/dist/{chunk-TA4C3XB7.js.map → chunk-PFKIOYJH.js.map} +0 -0
  747. /package/dist/{chunk-WIWLX65T.js.map → chunk-PGGPRF6J.js.map} +0 -0
  748. /package/dist/{chunk-V6EGNVUT.js.map → chunk-PIWFNPQT.js.map} +0 -0
  749. /package/dist/{chunk-4JVQRFZD.js.map → chunk-PLJ2MQFT.js.map} +0 -0
  750. /package/dist/{chunk-4RX5O34R.js.map → chunk-PQ42DJNG.js.map} +0 -0
  751. /package/dist/{chunk-37CAEC7E.js.map → chunk-PWPIERBM.js.map} +0 -0
  752. /package/dist/{chunk-ZEGL7YCC.js.map → chunk-Q62GA5U2.js.map} +0 -0
  753. /package/dist/{chunk-GAS7KYC7.js.map → chunk-RQQO3ORQ.js.map} +0 -0
  754. /package/dist/{chunk-3NPNBVFR.js.map → chunk-UZGHKD3T.js.map} +0 -0
  755. /package/dist/{chunk-VJIE4D2I.js.map → chunk-V62YYBBY.js.map} +0 -0
  756. /package/dist/{chunk-KQAFEZQX.js.map → chunk-VDX2J7OX.js.map} +0 -0
  757. /package/dist/{chunk-6AGWBKQU.js.map → chunk-VSN2DMQK.js.map} +0 -0
  758. /package/dist/{chunk-ZHXSOMYH.js.map → chunk-VVX5PZFS.js.map} +0 -0
  759. /package/dist/{chunk-GI4ZBWPQ.js.map → chunk-W7UV2ZCA.js.map} +0 -0
  760. /package/dist/{chunk-GMIQV6DD.js.map → chunk-WBQ4ONQJ.js.map} +0 -0
  761. /package/dist/{chunk-FNHLI2RE.js.map → chunk-WFMQN7JE.js.map} +0 -0
  762. /package/dist/{chunk-ZBW7A667.js.map → chunk-WPGA4RYI.js.map} +0 -0
  763. /package/dist/{chunk-YQNNHLCG.js.map → chunk-WPGR3RW4.js.map} +0 -0
  764. /package/dist/{chunk-NXGSONWM.js.map → chunk-WZIO3TW6.js.map} +0 -0
  765. /package/dist/{chunk-ZZUVBZL2.js.map → chunk-X2QPKLPL.js.map} +0 -0
  766. /package/dist/{chunk-VSL63CFJ.js.map → chunk-XRS65T4O.js.map} +0 -0
  767. /package/dist/{chunk-5N4MZLEH.js.map → chunk-YFXAWGMR.js.map} +0 -0
  768. /package/dist/{chunk-D545Z7UH.js.map → chunk-Z535ADTC.js.map} +0 -0
  769. /package/dist/{chunk-5YCNDC3C.js.map → chunk-ZX6NNFSY.js.map} +0 -0
  770. /package/dist/{chunk-3N3PBBEH.js.map → chunk-ZYSOT6HD.js.map} +0 -0
  771. /package/dist/{chunk-MCRVQ5YQ.js.map → chunk-ZZEIL3MI.js.map} +0 -0
  772. /package/dist/{resolution-4GG3QZRJ.js.map → contradiction-scan-GVD4JJ7B.js.map} +0 -0
  773. /package/dist/{first-start-migration-ZWMV5CX4.js.map → first-start-migration-L3UFX5CU.js.map} +0 -0
  774. /package/dist/{tier-stats-LUSUUNU6.js.map → tier-stats-VK5PCO2L.js.map} +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/fallback-llm.ts"],"sourcesContent":["import { log } from \"./logger.js\";\nimport path from \"node:path\";\nimport type { AgentPersonaModelConfig, GatewayConfig, ModelProviderConfig, PluginConfig } from \"./types.js\";\nimport { extractJsonCandidates } from \"./json-extract.js\";\nimport {\n buildChatCompletionTemperature,\n buildChatCompletionTokenLimit,\n shouldAssumeOpenAiChatCompletions,\n} from \"./openai-chat-compat.js\";\nimport {\n resolveProviderApiKey,\n getGatewayRuntimeAuthForModel,\n type GetRuntimeAuthForModelFn,\n type ResolveApiKeyFn,\n} from \"./resolve-provider-secret.js\";\nimport {\n CODEX_SUBSCRIPTION_PROVIDER_ID,\n codexSubscriptionBuiltinProviderConfig,\n getCodexSubscriptionRunnerForOwner,\n} from \"./providers/codex-subscription.js\";\nimport { loadModelsJsonProviders } from \"./models-json.js\";\nimport {\n abortReason,\n isTerminalCodexSubscriptionError,\n raceFallbackLlmDeadline,\n tryCodexSubscriptionProvider,\n withCodexRuntimeShutdown,\n} from \"./fallback-llm-codex-subscription.js\";\nimport type { CodexCliFallbackRunner } from \"./cli-fallback.js\";\nimport { resolveHomeDir } from \"./runtime/env.js\";\nimport { expandTildePath } from \"./utils/path.js\";\n\nexport interface FallbackLlmOptions {\n temperature?: number;\n maxTokens?: number;\n timeoutMs?: number;\n signal?: AbortSignal;\n /** Set the Responses API storage policy. Other transports ignore this value. */\n store?: boolean;\n /** Request strict JSON output when a route uses the Responses API. */\n responsesJsonSchema?: { name: string; schema: Record<string, unknown> };\n /** Request provider-native structured output on supported JSON transports. */\n jsonSchema?: { name: string; schema: Record<string, unknown>; strict?: boolean };\n /** Hide provider error details that could echo private request content. */\n redactProviderErrors?: boolean;\n /** Explicit \"provider/model\" override to try before the configured chain. */\n model?: string;\n /** Explicit model chain override to use instead of the configured agent/default chain. */\n modelChain?: AgentPersonaModelConfig;\n /** Append the gateway default chain after an explicit model chain. */\n includeDefaultModelFallback?: boolean;\n /** Override which agent persona's model chain to use (by ID from agents.list[]). */\n agentId?: string;\n /** Reject a transport-successful response and continue through the configured model chain. */\n acceptResponse?: (response: FallbackLlmResponse) => boolean;\n}\n\nexport interface FallbackLlmAvailabilityOptions {\n agentId?: string;\n modelChain?: AgentPersonaModelConfig;\n}\n\n/**\n * Resolve the gateway routing options Remnic's background tasks should pass to\n * FallbackLlmClient — extraction, fact/profile/identity consolidation,\n * summarization, calibration, and causal/semantic consolidation. Single source\n * of truth so every task path stays consistent and can't diverge (gotcha #22):\n * in gateway mode an explicit `taskModelChain` wins over the gateway agent\n * persona; otherwise the persona (if any) is used. Returns `{}` in plugin mode\n * because the chain resolves through gateway providers only. Issue #1365.\n */\nexport function gatewayTaskChainOptions(\n config: Pick<PluginConfig, \"modelSource\" | \"taskModelChain\" | \"gatewayAgentId\">,\n): Pick<FallbackLlmOptions, \"modelChain\" | \"agentId\"> {\n if (config.modelSource !== \"gateway\") return {};\n if (config.taskModelChain) return { modelChain: config.taskModelChain };\n return config.gatewayAgentId ? { agentId: config.gatewayAgentId } : {};\n}\n\nexport interface FallbackLlmResponse {\n content: string;\n modelUsed: string;\n usage?: {\n inputTokens?: number;\n outputTokens?: number;\n totalTokens?: number;\n };\n}\n\nexport interface FallbackLlmRuntimeContext {\n agentDir?: string;\n getRuntimeAuthForModel?: GetRuntimeAuthForModelFn | null;\n resolveApiKeyForProvider?: ResolveApiKeyFn | null;\n workspaceDir?: string;\n /** Per-runtime Codex child owner. Shutdown must terminate only this runner. */\n codexSubscriptionRunner?: CodexCliFallbackRunner;\n}\n\nexport function fallbackLlmRuntimeContextFromConfig(\n config: Pick<\n GatewayBackedRuntimeConfig,\n \"providerApiKeyResolver\" | \"runtimeAuthForModelResolver\" | \"workspaceDir\"\n >,\n overrides: FallbackLlmRuntimeContext = {},\n): FallbackLlmRuntimeContext {\n return {\n workspaceDir: config.workspaceDir,\n resolveApiKeyForProvider: config.providerApiKeyResolver,\n getRuntimeAuthForModel: config.runtimeAuthForModelResolver,\n codexSubscriptionRunner: getCodexSubscriptionRunnerForOwner(config),\n ...overrides,\n };\n}\n\ntype GatewayBackedRuntimeConfig = {\n providerApiKeyResolver?: ResolveApiKeyFn | null;\n runtimeAuthForModelResolver?: GetRuntimeAuthForModelFn | null;\n workspaceDir?: string;\n};\n\ninterface ModelRef {\n providerId: string;\n modelId: string;\n providerConfig: ModelProviderConfig;\n modelString: string;\n}\n\nfunction isUnsupportedJsonSchemaError(error: unknown): boolean {\n const message = error instanceof Error ? error.message : String(error);\n // Require an HTTP status plus explicit schema/format context. A bare\n // \"unsupported\" (e.g. \"'temperature' is unsupported with this model\") must\n // NOT trigger the schema-stripping retry, or we pay a duplicate request\n // for unrelated provider errors.\n if (!/\\b(?:400|404|422)\\b/.test(message)) {\n return false;\n }\n if (/(?:response[_ ]?format|json[_ ]?schema|structured[_ ]?output)/i.test(message)) {\n return true;\n }\n // \"unsupported\" only counts when adjacent to schema/format terminology.\n return /\\bunsupported\\b[\\s\\S]{0,40}\\b(?:schema|format)\\b/i.test(message);\n}\n\nconst PROVIDER_ALIASES: Record<string, readonly string[]> = {\n \"openai-codex\": [\"codex\"],\n codex: [\"openai-codex\"],\n \"claude-cli\": [\"anthropic\"],\n};\n\nconst LEGACY_PROVIDER_IDS = new Set([\"openai-codex\", \"claude-cli\"]);\n\nconst MANAGED_SECRETREF_MARKER = [\"secretref\", \"managed\"].join(\"-\");\nconst PROVIDER_API_KEY_FIELD = [\"api\", \"Key\"].join(\"\") as keyof ModelProviderConfig;\n\n/**\n * Built-in provider fallbacks for providers that are commonly configured via\n * OAuth or gateway-managed auth rather than an explicit apiKey in\n * openclaw.json. These entries let resolveProviderConfig() succeed so the\n * chain proceeds to tryModel() → resolveRuntimeAuth(), which is where the\n * gateway's native OAuth token exchange happens.\n *\n * Without these, OAuth-only providers like `openai` are rejected with\n * \"provider not found\" before runtime auth is ever attempted.\n */\nconst BUILT_IN_PROVIDER_FALLBACKS: Record<string, ModelProviderConfig> = {\n anthropic: {\n baseUrl: \"https://api.anthropic.com/v1\",\n api: \"anthropic-messages\",\n models: [],\n [PROVIDER_API_KEY_FIELD]: MANAGED_SECRETREF_MARKER,\n },\n openai: {\n baseUrl: \"https://api.openai.com/v1\",\n api: \"openai-responses\",\n models: [],\n [PROVIDER_API_KEY_FIELD]: MANAGED_SECRETREF_MARKER,\n },\n // Subscription-OAuth extraction provider (issue #2784): no apiKey — the\n // codex CLI login authenticates, via the runner the codex-subscription\n // module registers on this same seam.\n [CODEX_SUBSCRIPTION_PROVIDER_ID]: codexSubscriptionBuiltinProviderConfig(),\n};\n\n/**\n * Generic fallback LLM client that uses the gateway's default AI configuration\n * and walks through the full fallback chain (primary + fallbacks).\n * Supports OpenAI and Anthropic API formats.\n */\nexport class FallbackLlmClient {\n private gatewayConfig: GatewayConfig | undefined;\n private runtimeContext: FallbackLlmRuntimeContext;\n\n constructor(\n gatewayConfig?: GatewayConfig,\n runtimeContext: FallbackLlmRuntimeContext = {},\n ) {\n this.gatewayConfig = gatewayConfig;\n this.runtimeContext = {\n ...runtimeContext,\n workspaceDir:\n normalizeRuntimePath(runtimeContext.workspaceDir) ??\n readGatewayWorkspaceDir(gatewayConfig) ??\n defaultOpenClawWorkspaceDir(),\n };\n }\n\n /**\n * Check if fallback is available (gateway config has at least one model).\n */\n isAvailable(agentIdOrOptions?: string | FallbackLlmAvailabilityOptions): boolean {\n const options = typeof agentIdOrOptions === \"string\"\n ? { agentId: agentIdOrOptions }\n : (agentIdOrOptions ?? {});\n const models = this.getModelChain(options.agentId, undefined, options.modelChain);\n return models.length > 0;\n }\n\n /**\n * Make a chat completion request using the gateway's default AI chain.\n * Tries primary first, then each fallback in order.\n * When agentId is provided, uses that agent persona's model chain instead of defaults.\n */\n async chatCompletion(\n messages: Array<{ role: \"system\" | \"user\" | \"assistant\"; content: string }>,\n options: FallbackLlmOptions = {},\n ): Promise<FallbackLlmResponse | null> {\n const models = this.getModelChain(\n options.agentId,\n options.model,\n options.modelChain,\n options.includeDefaultModelFallback,\n );\n if (models.length === 0) {\n log.warn(\"fallback LLM: no models configured in gateway\");\n return null;\n }\n options = withCodexRuntimeShutdown(options, this.runtimeContext.codexSubscriptionRunner);\n\n const runChain = async (\n initialOptions: FallbackLlmOptions,\n ): Promise<FallbackLlmResponse | null> => {\n let runOptions = initialOptions;\n let lastRejectedResponse: FallbackLlmResponse | null = null;\n let terminalError: unknown;\n // Try each model in the chain\n for (let i = 0; i < models.length; i++) {\n if (runOptions.signal?.aborted) {\n throw abortReason(runOptions.signal);\n }\n const model = models[i];\n const isFallback = i > 0;\n\n try {\n const result = await this.tryModel(model, messages, runOptions);\n if (result) {\n const response = {\n content: result.content,\n modelUsed: model.modelString,\n usage: result.usage,\n };\n if (runOptions.acceptResponse && !runOptions.acceptResponse(response)) {\n lastRejectedResponse = response;\n log.debug(`fallback LLM: ${model.modelString} returned rejected output, trying next...`);\n continue;\n }\n if (isFallback) {\n log.debug(`fallback LLM: succeeded using ${model.modelString} (fallback ${i})`);\n }\n return response;\n }\n } catch (err) {\n if (isTerminalCodexSubscriptionError(err) && runOptions.signal?.aborted) {\n throw err;\n }\n if (runOptions.signal?.aborted) {\n throw abortReason(runOptions.signal);\n }\n if (\n (runOptions.jsonSchema || runOptions.responsesJsonSchema) &&\n isUnsupportedJsonSchemaError(err)\n ) {\n log.debug(`fallback LLM: ${model.modelString} rejected native JSON schema; retrying without it`);\n // Degrade to prompt-only for the REST of the chain too, so an\n // N-model chain where every provider rejects structured output\n // costs N+1 requests instead of 2N.\n runOptions = {\n ...runOptions,\n jsonSchema: undefined,\n responsesJsonSchema: undefined,\n };\n try {\n const result = await this.tryModel(model, messages, runOptions);\n if (result) {\n const response = {\n content: result.content,\n modelUsed: model.modelString,\n usage: result.usage,\n };\n if (!runOptions.acceptResponse || runOptions.acceptResponse(response)) {\n return response;\n }\n lastRejectedResponse = response;\n log.debug(`fallback LLM: ${model.modelString} unstructured retry output rejected by acceptResponse, trying next model...`);\n continue;\n }\n } catch (retryError) {\n if (isTerminalCodexSubscriptionError(retryError) && runOptions.signal?.aborted) {\n throw retryError;\n }\n if (runOptions.signal?.aborted) throw abortReason(runOptions.signal);\n const retryErrorMsg = runOptions.redactProviderErrors\n ? \"provider error details redacted\"\n : retryError instanceof Error\n ? retryError.message\n : String(retryError);\n log.debug(\n `fallback LLM: ${model.modelString} unstructured retry failed (${retryErrorMsg})`,\n );\n if (isTerminalCodexSubscriptionError(retryError)) {\n terminalError = retryError;\n }\n }\n continue;\n }\n const errorMsg = runOptions.redactProviderErrors\n ? \"provider error details redacted\"\n : err instanceof Error\n ? err.message\n : String(err);\n log.debug(`fallback LLM: ${model.modelString} failed (${errorMsg}), trying next...`);\n if (isTerminalCodexSubscriptionError(err)) {\n terminalError = err;\n }\n // Continue to next model in chain\n }\n }\n\n log.warn(`fallback LLM: all ${models.length} models in chain failed`);\n // A terminal typed provider failure must reach the caller when the\n // chain is exhausted — the documented timeout/re-login guidance\n // depends on it (issue #2833).\n if (terminalError !== undefined) {\n throw terminalError;\n }\n return lastRejectedResponse;\n };\n\n if (typeof options.timeoutMs === \"number\") {\n if (options.timeoutMs <= 0) {\n log.warn(\"fallback LLM: timed out before request started\");\n return null;\n }\n const controller = new AbortController();\n const onCallerAbort = (): void => {\n controller.abort(abortReason(options.signal));\n };\n options.signal?.addEventListener(\"abort\", onCallerAbort, { once: true });\n if (options.signal?.aborted) {\n onCallerAbort();\n }\n const timedOptions = { ...options, signal: controller.signal };\n const chain = runChain(timedOptions);\n const guarded = chain.then(\n (value) => value,\n (err) => {\n if (isTerminalCodexSubscriptionError(err)) throw err;\n return null;\n },\n );\n try {\n const outcome = await raceFallbackLlmDeadline(guarded, options.timeoutMs, () => {\n log.warn(`fallback LLM: timed out after ${options.timeoutMs}ms`);\n controller.abort(\n new Error(`fallback LLM timed out after ${options.timeoutMs}ms`),\n );\n });\n return outcome.timedOut ? null : outcome.value;\n } finally {\n options.signal?.removeEventListener(\"abort\", onCallerAbort);\n }\n }\n\n return await runChain(options);\n }\n\n /**\n * Make a request with structured output (Zod schema).\n * Returns parsed JSON or null on failure.\n */\n async parseWithSchema<T>(\n messages: Array<{ role: \"system\" | \"user\" | \"assistant\"; content: string }>,\n schema: { parse: (data: unknown) => T },\n options: FallbackLlmOptions = {},\n ): Promise<T | null> {\n const detailed = await this.parseWithSchemaDetailed(messages, schema, options);\n return detailed?.result ?? null;\n }\n\n /**\n * Like parseWithSchema but also returns the model that was used,\n * so callers can emit accurate trace events.\n */\n async parseWithSchemaDetailed<T>(\n messages: Array<{ role: \"system\" | \"user\" | \"assistant\"; content: string }>,\n schema: { parse: (data: unknown) => T },\n options: FallbackLlmOptions = {},\n ): Promise<\n | { result: T; modelUsed: string }\n | { result: null; failureReason: \"no_models\" | \"empty\" | \"http_error\" }\n > {\n let response: FallbackLlmResponse | null;\n try {\n response = await this.chatCompletion(messages, options);\n } catch (err) {\n // Caller aborts must propagate (e.g. recall planner cancellation) — do\n // not swallow them as a provider failure, or abort-driven callers lose\n // cancellation and treat it as an extraction error (codex review).\n // Terminal codex-subscription failures propagate for the same reason:\n // their TimeoutError/auth guidance is the documented contract.\n if (options.signal?.aborted || isTerminalCodexSubscriptionError(err)) throw err;\n log.warn(\"fallback LLM: chatCompletion threw during structured parse:\", err);\n return { result: null, failureReason: \"http_error\" };\n }\n if (!response?.content) {\n // chatCompletion returns null both when no models are configured\n // (auth/config) and when every configured model errored (transient).\n // Disambiguate via the resolved model chain so the retry layer can pick\n // the right failure class.\n const hasModels =\n this.getModelChain(\n options.agentId,\n options.model,\n options.modelChain,\n options.includeDefaultModelFallback,\n ).length > 0;\n return { result: null, failureReason: hasModels ? \"http_error\" : \"no_models\" };\n }\n\n try {\n const candidates = extractJsonCandidates(response.content);\n for (const c of candidates) {\n try {\n const parsed = JSON.parse(c);\n return { result: schema.parse(parsed), modelUsed: response.modelUsed };\n } catch {\n // keep trying other candidates\n }\n }\n return { result: null, failureReason: \"empty\" };\n } catch (err) {\n log.warn(\"fallback LLM: failed to parse structured output:\", err);\n return { result: null, failureReason: \"empty\" };\n }\n }\n\n /**\n * Get the full model chain from gateway config.\n * Returns array of models in order: [primary, fallback1, fallback2, ...]\n *\n * When modelChainOverride is provided, uses it instead of any configured\n * agent/default chain. Otherwise, when agentId is provided, looks up the\n * matching entry in agents.list[] and uses that persona's model chain.\n * Falls back to agents.defaults.model if agentId is not found or not provided.\n */\n private getModelChain(\n agentId?: string,\n modelOverride?: string,\n modelChainOverride?: AgentPersonaModelConfig,\n includeDefaultModelFallback = true,\n ): ModelRef[] {\n const chain: ModelRef[] = [];\n const providers = this.gatewayConfig?.models?.providers ?? {};\n\n // Resolve the model config: explicit task chain, agent persona chain, or global defaults\n let modelConfig: AgentPersonaModelConfig | undefined;\n\n if (modelChainOverride?.primary) {\n modelConfig = modelChainOverride;\n log.debug(\"fallback LLM: using explicit model chain override\");\n } else if (modelChainOverride) {\n log.warn(\"fallback LLM: ignoring explicit model chain override without primary model\");\n }\n\n if (!modelConfig && agentId) {\n const persona = this.gatewayConfig?.agents?.list?.find(\n (a) => a.id === agentId,\n );\n if (persona?.model) {\n modelConfig = persona.model;\n log.debug(`fallback LLM: using agent persona \"${agentId}\" model chain`);\n } else {\n log.warn(\n `fallback LLM: agent persona \"${agentId}\" not found or has no model config, falling back to defaults`,\n );\n }\n }\n\n if (!modelConfig) {\n modelConfig = this.gatewayConfig?.agents?.defaults?.model;\n }\n\n // Build list of model strings: primary + fallbacks\n const modelStrings: string[] = [];\n\n const addModelString = (value: unknown): void => {\n if (typeof value !== \"string\") return;\n const trimmed = value.trim();\n if (trimmed.length > 0 && !modelStrings.includes(trimmed)) {\n modelStrings.push(trimmed);\n }\n };\n\n addModelString(modelOverride);\n addModelString(modelConfig?.primary);\n\n if (Array.isArray(modelConfig?.fallbacks)) {\n for (const fb of modelConfig.fallbacks) {\n addModelString(fb);\n }\n }\n\n // Parse each model string and look up provider config\n for (const modelString of modelStrings) {\n const modelRef = this.parseModelString(modelString, providers);\n if (modelRef) {\n chain.push(modelRef);\n }\n }\n\n // Implicit last-resort: when a task-specific modelChain override is active,\n // append the gateway default model so a stale or exhausted taskModelChain\n // never leaves the chain empty — Remnic should never be the reason a chat is\n // interrupted by a flush failure. Keyed on `modelChainOverride?.primary` —\n // the SAME activation condition chain resolution uses above — so a\n // primary-less override (e.g. {}) that falls through to a persona/default\n // chain does NOT get the default appended (gotcha #39). Issue #1365 / PR #1370.\n if (includeDefaultModelFallback && modelChainOverride?.primary && modelStrings.length > 0) {\n // Append the FULL gateway default chain (primary + fallbacks), not just\n // the primary — if the default primary is also unreachable, a listed\n // default fallback may still succeed (cursor review #1425).\n const defaults = this.gatewayConfig?.agents?.defaults?.model;\n const defaultStrings: string[] = [\n ...(typeof defaults?.primary === \"string\" ? [defaults.primary] : []),\n ...(Array.isArray(defaults?.fallbacks) ? defaults.fallbacks : []),\n ];\n for (const candidate of defaultStrings) {\n if (typeof candidate !== \"string\") continue;\n const trimmed = candidate.trim();\n if (trimmed.length === 0 || modelStrings.includes(trimmed)) continue;\n const defaultRef = this.parseModelString(trimmed, providers);\n if (defaultRef) {\n chain.push(defaultRef);\n modelStrings.push(trimmed); // keep dedupe correct for later default fallbacks\n log.debug(\n `fallback LLM: appended gateway default model \"${trimmed}\" as implicit last resort`,\n );\n }\n }\n }\n\n return chain;\n }\n\n /**\n * Parse a \"provider/model\" string and look up its config.\n */\n private parseModelString(\n modelString: string,\n providers: Record<string, ModelProviderConfig>,\n ): ModelRef | null {\n // Parse \"provider/model\" format (e.g., \"openai/gpt-5.5\", \"anthropic/claude-opus-4-6\")\n const parts = modelString.split(\"/\");\n if (parts.length < 2) {\n log.warn(`fallback LLM: invalid model format: ${modelString}`);\n return null;\n }\n\n const requestedProviderId = parts[0];\n const modelId = parts.slice(1).join(\"/\"); // Handle cases like \"openai/gpt-5.5\"\n\n // Respect the active gateway config first so profile-local overrides and\n // credentials win. Fall back to the materialized models.json only when\n // the provider is absent from the loaded config (for built-in providers\n // registered by the gateway at runtime).\n const resolvedProvider = this.resolveProviderConfig(requestedProviderId, providers);\n const providerConfig = resolvedProvider?.config;\n if (!providerConfig) {\n log.warn(\n `fallback LLM: provider not found: ${requestedProviderId} ` +\n `(tried: ${this.providerResolutionCandidates(requestedProviderId).join(\", \")})`,\n );\n return null;\n }\n\n return {\n providerId: resolvedProvider.providerId,\n modelId,\n providerConfig,\n modelString,\n };\n }\n\n private resolveProviderConfig(\n providerId: string,\n providers: Record<string, ModelProviderConfig>,\n ): { providerId: string; config: ModelProviderConfig } | null {\n const candidates = this.providerResolutionCandidates(providerId);\n const aliasCandidates = candidates.filter((candidate) => candidate !== providerId);\n const fallbackCandidates = LEGACY_PROVIDER_IDS.has(providerId)\n ? [...aliasCandidates, providerId]\n : [providerId, ...aliasCandidates];\n for (const candidate of candidates) {\n const config = providers[candidate];\n if (config) {\n if (candidate !== providerId) {\n log.debug(`fallback LLM: provider \"${providerId}\" resolved via alias \"${candidate}\"`);\n }\n return { providerId: candidate, config };\n }\n }\n for (const candidate of fallbackCandidates) {\n const config = this.resolveFromModelsJson(candidate);\n if (config) {\n if (candidate !== providerId) {\n log.debug(`fallback LLM: provider \"${providerId}\" resolved via models.json alias \"${candidate}\"`);\n }\n return { providerId: candidate, config };\n }\n const builtInConfig = BUILT_IN_PROVIDER_FALLBACKS[candidate];\n if (builtInConfig) {\n if (candidate === providerId) {\n log.debug(`fallback LLM: provider \"${providerId}\" resolved from built-in defaults`);\n return { providerId, config: builtInConfig };\n }\n log.debug(`fallback LLM: provider \"${providerId}\" resolved via built-in alias \"${candidate}\"`);\n return { providerId: candidate, config: builtInConfig };\n }\n }\n return null;\n }\n\n private providerResolutionCandidates(providerId: string): string[] {\n const candidates = [providerId, ...(PROVIDER_ALIASES[providerId] ?? [])];\n return [...new Set(candidates)];\n }\n\n /**\n * Look up a provider from the gateway's materialized models.json, which\n * contains all providers including built-in ones (openai-codex, google-vertex,\n * etc.) that aren't in the user's openclaw.json but are registered by\n * gateway plugins. Returns null if the provider isn't found there either.\n */\n private resolveFromModelsJson(providerId: string): ModelProviderConfig | null {\n const allProviders = loadModelsJsonProviders();\n const config = allProviders[providerId];\n if (config) {\n log.debug(`fallback LLM: resolved provider \"${providerId}\" from models.json (api: ${config.api ?? \"default\"})`);\n return config;\n }\n return null;\n }\n\n /**\n * Try to call a single model.\n *\n * Uses the gateway's native getRuntimeAuthForModel when available — this\n * handles all provider-specific auth transforms (OAuth token exchange,\n * base URL overrides for codex/copilot/etc.) through the same codepath\n * the gateway itself uses. Falls back to resolveProviderApiKey for\n * simpler providers or when the runtime module isn't loaded.\n */\n private async tryModel(\n model: ModelRef,\n messages: Array<{ role: \"system\" | \"user\" | \"assistant\"; content: string }>,\n options: FallbackLlmOptions,\n ): Promise<{ content: string; usage?: FallbackLlmResponse[\"usage\"] } | null> {\n const codexResult = await tryCodexSubscriptionProvider(\n model,\n messages,\n options,\n () => this.resolveFallbackApiKey(model),\n this.runtimeContext.codexSubscriptionRunner,\n );\n if (codexResult !== undefined) return codexResult;\n const runtimeAuth = await this.resolveRuntimeAuth(model);\n const effectiveBaseUrl = runtimeAuth?.baseUrl ?? model.providerConfig.baseUrl;\n const resolvedApiKey = runtimeAuth?.apiKey ?? await this.resolveFallbackApiKey(model);\n\n // If the raw key looks like an unresolved secret ref and resolution fails,\n // skip this provider entirely so the chain falls through to the next.\n const rawKey = model.providerConfig.apiKey;\n const needsResolution = rawKey === \"secretref-managed\" || (typeof rawKey === \"object\" && rawKey !== null);\n if (needsResolution && !resolvedApiKey) {\n throw new Error(`API key for provider \"${model.providerId}\" could not be resolved from secret ref`);\n }\n\n const effectiveConfig: ModelProviderConfig = {\n ...model.providerConfig,\n baseUrl: effectiveBaseUrl,\n ...(resolvedApiKey ? { apiKey: resolvedApiKey } : {}),\n };\n\n if (model.providerConfig.api === \"anthropic-messages\") {\n return await this.callAnthropic(effectiveConfig, model.modelId, messages, options);\n }\n\n if (model.providerConfig.api === \"ollama-chat\") {\n return await this.callOllamaChat(effectiveConfig, model.modelId, messages, options);\n }\n\n if (\n model.providerConfig.api === \"openai-responses\" ||\n model.providerConfig.api === \"openai-codex-responses\" ||\n model.providerConfig.api === \"azure-openai-responses\"\n ) {\n return await this.callOpenAIResponses(\n effectiveConfig,\n model.modelId,\n messages,\n options,\n );\n }\n\n // For OpenAI-compatible chat-completions APIs (openai-completions,\n // ollama, etc.) and unknown formats, use chat completions — the gateway's\n // runtime auth resolver returns request-ready base URL and credentials for\n // most providers.\n return await this.callOpenAI(\n effectiveConfig,\n model.modelId,\n messages,\n options,\n shouldAssumeOpenAiChatCompletions(effectiveConfig.baseUrl),\n );\n }\n\n /**\n * Resolve request-ready auth through the gateway's native runtime, which\n * handles provider-specific transforms (OAuth token exchange for codex/copilot,\n * base URL rewrite, etc.). Returns null if the runtime isn't available.\n */\n private async resolveRuntimeAuth(\n model: ModelRef,\n ): Promise<{ apiKey?: string; baseUrl?: string } | null> {\n try {\n const getRuntimeAuth = await getGatewayRuntimeAuthForModel({\n getRuntimeAuthForModel: this.runtimeContext.getRuntimeAuthForModel,\n });\n if (!getRuntimeAuth) return null;\n\n const result = await getRuntimeAuth({\n model: {\n provider: model.providerId,\n id: model.modelId,\n api: model.providerConfig.api,\n baseUrl: model.providerConfig.baseUrl,\n },\n cfg: this.gatewayConfig,\n workspaceDir: this.runtimeContext.workspaceDir,\n });\n\n if (result?.apiKey || result?.baseUrl) {\n log.debug(\n `fallback LLM: resolved runtime auth for \"${model.modelString}\" (source: ${result.source ?? \"unknown\"}, mode: ${result.mode ?? \"unknown\"})`,\n );\n return { apiKey: result.apiKey, baseUrl: result.baseUrl };\n }\n } catch (err) {\n log.debug(\n `fallback LLM: gateway runtime auth failed for \"${model.modelString}\": ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n return null;\n }\n\n /**\n * Resolve API key through the existing provider-level resolution (env vars,\n * secret refs, etc.). Used as fallback when gateway runtime auth isn't available.\n */\n private async resolveFallbackApiKey(model: ModelRef): Promise<string | undefined> {\n return resolveProviderApiKey(\n model.providerId,\n model.providerConfig.apiKey,\n this.gatewayConfig,\n this.runtimeContext.agentDir,\n {\n resolveApiKeyForProvider: this.runtimeContext.resolveApiKeyForProvider,\n },\n );\n }\n\n /**\n * Call OpenAI-compatible API.\n */\n private async callOpenAI(\n config: ModelProviderConfig,\n modelId: string,\n messages: Array<{ role: \"system\" | \"user\" | \"assistant\"; content: string }>,\n options: FallbackLlmOptions,\n assumeOpenAI: boolean,\n ): Promise<{ content: string; usage?: FallbackLlmResponse[\"usage\"] } | null> {\n const base = config.baseUrl.replace(/\\/$/, \"\");\n const url = base.endsWith(\"/v1\")\n ? `${base}/chat/completions`\n : `${base}/v1/chat/completions`;\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n ...config.headers,\n };\n\n // Handle auth — apiKey is already resolved to a string by tryModel()\n if (config.apiKey && typeof config.apiKey === \"string\") {\n if (config.authHeader !== false) {\n headers[\"Authorization\"] = `Bearer ${config.apiKey}`;\n }\n }\n\n const body = {\n model: modelId,\n messages,\n ...buildChatCompletionTemperature(modelId, options.temperature ?? 0.3, {\n assumeOpenAI,\n }),\n ...buildChatCompletionTokenLimit(modelId, options.maxTokens ?? 4096, {\n assumeOpenAI,\n }),\n ...(options.jsonSchema\n ? {\n response_format: {\n type: \"json_schema\",\n json_schema: {\n name: options.jsonSchema.name,\n strict: options.jsonSchema.strict ?? false,\n schema: options.jsonSchema.schema,\n },\n },\n }\n : {}),\n };\n\n const response = await fetch(url, {\n method: \"POST\",\n headers,\n signal: options.signal,\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const error = await response.text();\n throw new Error(`OpenAI API error: ${response.status} ${error}`);\n }\n\n const data = (await response.json()) as {\n choices: Array<{\n message: {\n content: string;\n };\n }>;\n usage?: {\n prompt_tokens?: number;\n completion_tokens?: number;\n total_tokens?: number;\n };\n };\n\n const content = data.choices?.[0]?.message?.content;\n if (!content) {\n throw new Error(\"Empty response from OpenAI API\");\n }\n\n return {\n content,\n usage: data.usage\n ? {\n inputTokens: data.usage.prompt_tokens,\n outputTokens: data.usage.completion_tokens,\n totalTokens: data.usage.total_tokens,\n }\n : undefined,\n };\n }\n\n /**\n * Call Ollama's native /api/chat transport. This lets benchmark-isolated\n * gateway configs route Remnic's own internal LLM calls to Ollama Cloud\n * without requiring an OpenAI-compatible shim.\n */\n private async callOllamaChat(\n config: ModelProviderConfig,\n modelId: string,\n messages: Array<{ role: \"system\" | \"user\" | \"assistant\"; content: string }>,\n options: FallbackLlmOptions,\n ): Promise<{ content: string; usage?: FallbackLlmResponse[\"usage\"] } | null> {\n const base = config.baseUrl.replace(/\\/$/, \"\");\n const url = base.endsWith(\"/api\") ? `${base}/chat` : `${base}/api/chat`;\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n ...config.headers,\n };\n if (config.apiKey && typeof config.apiKey === \"string\" && config.authHeader !== false) {\n headers.Authorization = `Bearer ${config.apiKey}`;\n }\n\n const response = await fetch(url, {\n method: \"POST\",\n headers,\n signal: options.signal,\n body: JSON.stringify({\n model: modelId,\n messages,\n stream: false,\n ...(config.disableThinking ? { think: false } : {}),\n options: {\n temperature: options.temperature ?? 0.3,\n num_predict: options.maxTokens ?? 4096,\n },\n }),\n });\n\n if (!response.ok) {\n const error = await response.text();\n throw new Error(`Ollama API error: ${response.status} ${error}`);\n }\n\n const data = (await response.json()) as {\n message?: { content?: string };\n response?: string;\n prompt_eval_count?: number;\n eval_count?: number;\n };\n const content = data.message?.content ?? data.response;\n if (!content) {\n throw new Error(\"Empty response from Ollama API\");\n }\n\n const inputTokens = data.prompt_eval_count ?? 0;\n const outputTokens = data.eval_count ?? 0;\n return {\n content,\n usage: {\n inputTokens,\n outputTokens,\n totalTokens: inputTokens + outputTokens,\n },\n };\n }\n\n /**\n * Call an OpenAI-compatible Responses API.\n */\n private async callOpenAIResponses(\n config: ModelProviderConfig,\n modelId: string,\n messages: Array<{ role: \"system\" | \"user\" | \"assistant\"; content: string }>,\n options: FallbackLlmOptions,\n ): Promise<{ content: string; usage?: FallbackLlmResponse[\"usage\"] } | null> {\n const base = config.baseUrl.replace(/\\/$/, \"\");\n const url = base.endsWith(\"/v1\")\n ? `${base}/responses`\n : `${base}/v1/responses`;\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n ...config.headers,\n };\n\n if (config.apiKey && typeof config.apiKey === \"string\" && config.authHeader !== false) {\n headers[\"Authorization\"] = `Bearer ${config.apiKey}`;\n }\n\n const instructions = messages\n .filter((message) => message.role === \"system\")\n .map((message) => message.content)\n .join(\"\\n\\n\")\n .trim();\n const input = messages\n .filter((message) => message.role !== \"system\")\n .map((message) => ({\n role: message.role,\n content: [{\n type: message.role === \"assistant\" ? \"output_text\" : \"input_text\",\n text: message.content,\n }],\n }));\n\n const body: Record<string, unknown> = {\n model: modelId,\n input,\n max_output_tokens: Math.max(0, Math.floor(options.maxTokens ?? 4096)),\n ...buildChatCompletionTemperature(modelId, options.temperature ?? 0.3, {\n assumeOpenAI: shouldAssumeOpenAiChatCompletions(config.baseUrl),\n }),\n ...(options.store === undefined ? {} : { store: options.store }),\n ...(options.jsonSchema || options.responsesJsonSchema\n ? {\n text: {\n format: {\n type: \"json_schema\",\n name: (options.jsonSchema ?? options.responsesJsonSchema)!.name,\n strict: (options.jsonSchema?.strict ?? (options.responsesJsonSchema ? true : false)),\n schema: (options.jsonSchema ?? options.responsesJsonSchema)!.schema,\n },\n },\n }\n : {}),\n };\n if (instructions.length > 0) {\n body.instructions = instructions;\n }\n\n const response = await fetch(url, {\n method: \"POST\",\n headers,\n signal: options.signal,\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const error = await response.text();\n throw new Error(`OpenAI Responses API error: ${response.status} ${error}`);\n }\n\n const data = (await response.json()) as {\n output_text?: string;\n output?: Array<{\n type?: string;\n text?: string;\n content?: Array<{\n type?: string;\n text?: string;\n }>;\n }>;\n usage?: {\n input_tokens?: number;\n output_tokens?: number;\n total_tokens?: number;\n };\n };\n\n const outputText = extractResponsesOutputText(data);\n if (!outputText) {\n throw new Error(\"Empty response from OpenAI Responses API\");\n }\n\n return {\n content: outputText,\n usage: data.usage\n ? {\n inputTokens: data.usage.input_tokens,\n outputTokens: data.usage.output_tokens,\n totalTokens: data.usage.total_tokens,\n }\n : undefined,\n };\n }\n\n /**\n * Call Anthropic Messages API.\n */\n private async callAnthropic(\n config: ModelProviderConfig,\n modelId: string,\n messages: Array<{ role: \"system\" | \"user\" | \"assistant\"; content: string }>,\n options: FallbackLlmOptions,\n ): Promise<{ content: string; usage?: FallbackLlmResponse[\"usage\"] } | null> {\n const base = config.baseUrl.replace(/\\/$/, \"\");\n const url = base.endsWith(\"/v1\")\n ? `${base}/messages`\n : `${base}/v1/messages`;\n\n const headers: Record<string, string> = {\n \"Content-Type\": \"application/json\",\n \"anthropic-version\": \"2023-06-01\",\n ...config.headers,\n };\n\n // Handle auth - Anthropic uses x-api-key header (apiKey resolved by tryModel)\n if (config.apiKey && typeof config.apiKey === \"string\") {\n headers[\"x-api-key\"] = config.apiKey;\n }\n\n // Extract system message (Anthropic handles it separately)\n const systemMessage = messages.find((m) => m.role === \"system\")?.content;\n const nonSystemMessages = messages.filter((m) => m.role !== \"system\");\n\n // Convert messages to Anthropic format\n const anthropicMessages = nonSystemMessages.map((m) => ({\n role: m.role,\n content: m.content,\n }));\n\n const body: Record<string, unknown> = {\n model: modelId,\n messages: anthropicMessages,\n max_tokens: options.maxTokens ?? 4096,\n temperature: options.temperature ?? 0.3,\n };\n\n if (systemMessage) {\n body.system = systemMessage;\n }\n\n const response = await fetch(url, {\n method: \"POST\",\n headers,\n signal: options.signal,\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n const error = await response.text();\n throw new Error(`Anthropic API error: ${response.status} ${error}`);\n }\n\n const data = (await response.json()) as {\n content: Array<{\n type: string;\n text: string;\n }>;\n usage?: {\n input_tokens?: number;\n output_tokens?: number;\n };\n };\n\n const content = data.content?.[0]?.text;\n if (!content) {\n throw new Error(\"Empty response from Anthropic API\");\n }\n\n return {\n content,\n usage: data.usage\n ? {\n inputTokens: data.usage.input_tokens,\n outputTokens: data.usage.output_tokens,\n totalTokens: (data.usage.input_tokens ?? 0) + (data.usage.output_tokens ?? 0),\n }\n : undefined,\n };\n }\n}\n\nfunction normalizeRuntimePath(value: unknown): string | undefined {\n if (typeof value !== \"string\") return undefined;\n const trimmed = value.trim();\n return trimmed.length > 0 ? expandTildePath(trimmed) : undefined;\n}\n\nfunction readGatewayWorkspaceDir(gatewayConfig: GatewayConfig | undefined): string | undefined {\n if (!gatewayConfig || typeof gatewayConfig !== \"object\") return undefined;\n const raw = gatewayConfig as Record<string, unknown>;\n return (\n normalizeRuntimePath(raw.workspaceDir) ??\n normalizeRuntimePath(raw.workspacePath) ??\n normalizeRuntimePath(raw.workspace)\n );\n}\n\nfunction defaultOpenClawWorkspaceDir(): string {\n return path.join(resolveHomeDir(), \".openclaw\", \"workspace\");\n}\n\nfunction extractResponsesOutputText(data: {\n output_text?: string;\n output?: Array<{\n type?: string;\n text?: string;\n content?: Array<{\n type?: string;\n text?: string;\n }>;\n }>;\n}): string | null {\n if (typeof data.output_text === \"string\" && data.output_text.trim().length > 0) {\n return data.output_text;\n }\n\n const chunks: string[] = [];\n for (const item of data.output ?? []) {\n if (typeof item.text === \"string\" && item.text.trim().length > 0) {\n chunks.push(item.text);\n }\n for (const part of item.content ?? []) {\n if (\n (part.type === \"output_text\" || part.type === \"text\") &&\n typeof part.text === \"string\" &&\n part.text.trim().length > 0\n ) {\n chunks.push(part.text);\n }\n }\n }\n\n const joined = chunks.join(\"\\n\").trim();\n return joined.length > 0 ? joined : null;\n}\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/local-llm.ts"],"sourcesContent":["import { log } from \"./logger.js\";\nimport { estimateTokenCount } from \"./token-estimate.js\";\nimport type { PluginConfig } from \"./types.js\";\nimport fs from \"node:fs\";\nimport os from \"node:os\";\nimport type { ModelRegistry } from \"./model-registry.js\";\nimport { launchProcessSync } from \"./runtime/child-process.js\";\nimport { mergeEnv, readEnvVar } from \"./runtime/env.js\";\nimport { resolveLocalLlmCapabilities } from \"./capabilities.js\";\nimport { resolvePipelineProcessingCapabilities } from \"./capabilities.js\";\nimport { ChatTransport } from \"./local-llm-transport.js\";\nimport {\n extractNonRecoverableBackendReason,\n extractNonRecoverableBackendReasonFromErrorText,\n isAbortError,\n probeFetch,\n resolveUnavailableVerdict,\n type ProbeFetchResult,\n normalizeBackendTripReason,\n waitForRetryBackoff,\n SingleFlightProbe,\n} from \"./local-llm-helpers.js\";\n\n/** Trim trailing slash characters without backtracking regex. */\nfunction trimTrailingSlashes(s: string): string {\n let end = s.length;\n while (end > 0 && s[end - 1] === \"/\") end--;\n return s.substring(0, end);\n}\n\nfunction stripTrailingV1Path(s: string): string {\n return s.endsWith(\"/v1\") ? s.slice(0, -3) : s;\n}\n\nfunction explicitPortFromUrl(s: string): number | null {\n try {\n const parsed = new URL(s);\n if (!parsed.port) return null;\n const port = Number(parsed.port);\n return Number.isInteger(port) ? port : null;\n } catch {\n return null;\n }\n}\n\nfunction isObjectRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n\nfunction isLlamaCppPropsResponse(value: unknown): boolean {\n return (\n isObjectRecord(value) &&\n isObjectRecord(value.default_generation_settings) &&\n typeof value.total_slots === \"number\" &&\n (\n typeof value.model_path === \"string\" ||\n typeof value.chat_template === \"string\" ||\n typeof value.build_info === \"string\"\n )\n );\n}\n\nfunction isLlamaCppModelsResponse(value: unknown): boolean {\n if (!isObjectRecord(value) || !Array.isArray(value.data)) {\n return false;\n }\n return value.data.some((entry) => {\n if (!isObjectRecord(entry)) return false;\n if (entry.owned_by === \"llamacpp\") return true;\n if (typeof entry.id === \"string\" && entry.id.endsWith(\".gguf\")) return true;\n const meta = entry.meta;\n return (\n isObjectRecord(meta) &&\n (\"n_ctx_train\" in meta || \"n_params\" in meta || \"vocab_type\" in meta)\n );\n });\n}\n\nfunction isLmStudioApiV1ModelsResponse(value: unknown): boolean {\n if (!isObjectRecord(value) || !Array.isArray(value.models)) {\n return false;\n }\n return value.models.some((entry) => {\n if (!isObjectRecord(entry)) return false;\n return (\n typeof entry.key === \"string\" &&\n typeof entry.display_name === \"string\" &&\n (\n typeof entry.format === \"string\" ||\n typeof entry.max_context_length === \"number\" ||\n Array.isArray(entry.loaded_instances)\n )\n );\n });\n}\n\nfunction isLmStudioApiV0ModelsResponse(value: unknown): boolean {\n if (!isObjectRecord(value) || !Array.isArray(value.data)) {\n return false;\n }\n return value.data.some((entry) => {\n if (!isObjectRecord(entry)) return false;\n return (\n typeof entry.id === \"string\" &&\n typeof entry.publisher === \"string\" &&\n (\n typeof entry.compatibility_type === \"string\" ||\n typeof entry.max_context_length === \"number\" ||\n typeof entry.state === \"string\"\n )\n );\n });\n}\n\nfunction isLmStudioNativeModelsResponse(value: unknown): boolean {\n return isLmStudioApiV1ModelsResponse(value) || isLmStudioApiV0ModelsResponse(value);\n}\n\n/**\n * Local LLM client for OpenAI-compatible endpoints (LM Studio, Ollama, MLX, etc.)\n *\n * Based on openclaw-tactician's provider detection patterns for consistency.\n * Provides privacy-preserving, cost-effective LLM operations with\n * graceful fallback to cloud providers when local LLM is unavailable.\n */\nexport type LocalLlmType = \"lmstudio\" | \"ollama\" | \"mlx\" | \"vllm\" | \"llamacpp\" | \"generic\";\n\n/**\n * Backends known to honor `chat_template_kwargs: { enable_thinking: false }`\n * on OpenAI-compatible `/v1/chat/completions`. LM Studio, vLLM, and\n * llama.cpp forward this field to the jinja chat template, where thinking-capable\n * models (Qwen 3.5, Gemma 4, DeepSeek) suppress reasoning tokens.\n *\n * Strict OpenAI-compatible backends (standard OpenAI, Azure OpenAI, some\n * proxies) reject unknown request fields with 400 — which trips the\n * `localLlm400*` cooldown path. `LocalLlmClient` therefore only injects\n * the kwarg when the detected backend is in this set; unknown / `generic`\n * / `ollama` / `mlx` fail open (no injection, no 400 risk). Issue #548.\n */\nconst THINKING_COMPATIBLE_BACKENDS: ReadonlySet<LocalLlmType> = new Set([\n \"lmstudio\",\n \"vllm\",\n \"llamacpp\",\n]);\n\nconst THINKING_SUPPRESSED_OPERATIONS: ReadonlySet<string> = new Set([\n \"extraction\",\n \"extraction-judge\",\n \"extraction-faithfulness\",\n \"contradiction-judge\",\n \"contradiction_verification\",\n \"link_suggestion\",\n \"memory_summarization\",\n \"proactive_extraction\",\n \"lcm-summarize\",\n \"day_summary\",\n \"hourly_summary\",\n \"hourly_summary_extended\",\n]);\n\ninterface LocalServerConfig {\n type: LocalLlmType;\n defaultPort: number;\n healthEndpoint: string;\n modelsEndpoint: string;\n detectFn: (response: unknown) => boolean;\n}\n\nconst LOCAL_SERVERS: LocalServerConfig[] = [\n {\n type: \"ollama\",\n defaultPort: 11434,\n healthEndpoint: \"/\",\n modelsEndpoint: \"/api/tags\",\n detectFn: (resp) => typeof resp === \"string\" && resp.includes(\"Ollama\"),\n },\n {\n type: \"llamacpp\",\n defaultPort: 8080,\n healthEndpoint: \"/health\",\n modelsEndpoint: \"/v1/models\",\n detectFn: (resp) => isObjectRecord(resp) && resp.status === \"ok\",\n },\n {\n type: \"mlx\",\n defaultPort: 8080,\n healthEndpoint: \"/v1/models\",\n modelsEndpoint: \"/v1/models\",\n detectFn: (resp) => isObjectRecord(resp) && Array.isArray(resp.data),\n },\n {\n type: \"lmstudio\",\n defaultPort: 1234,\n healthEndpoint: \"/v1/models\",\n modelsEndpoint: \"/v1/models\",\n detectFn: (resp) => isObjectRecord(resp) && Array.isArray(resp.data),\n },\n {\n type: \"vllm\",\n defaultPort: 8000,\n healthEndpoint: \"/health\",\n modelsEndpoint: \"/v1/models\",\n detectFn: (resp) => resp === \"\" || (isObjectRecord(resp) && !(\"status\" in resp)),\n },\n];\n\nfunction orderedLocalServers(configuredBaseUrl: string): LocalServerConfig[] {\n const configuredPort = explicitPortFromUrl(configuredBaseUrl);\n if (configuredPort === null) return LOCAL_SERVERS;\n const matching = LOCAL_SERVERS.filter(\n (serverConfig) => serverConfig.defaultPort === configuredPort,\n );\n if (matching.length === 0) return LOCAL_SERVERS;\n const matchingTypes = new Set(matching.map((serverConfig) => serverConfig.type));\n return [\n ...matching,\n ...LOCAL_SERVERS.filter((serverConfig) => !matchingTypes.has(serverConfig.type)),\n ];\n}\n\nexport interface LocalModelInfo {\n id: string;\n contextWindow?: number;\n maxTokens?: number;\n}\n\nexport type LocalLlmRequestPriority = \"recall-critical\" | \"background\";\n\ninterface LocalLlmChatCompletionOptions {\n temperature?: number;\n maxTokens?: number;\n responseFormat?: { type: string };\n timeoutMs?: number;\n operation?: string;\n forceDisableThinking?: boolean;\n disableThinking?: boolean;\n priority?: LocalLlmRequestPriority;\n signal?: AbortSignal;\n redactProviderErrors?: boolean;\n /** Per-request model; defaults to config.localLlmModel. */\n model?: string;\n}\ninterface LocalLlmQueuedRequest {\n messages: Array<{ role: string; content: string }>;\n options: LocalLlmChatCompletionOptions;\n priority: LocalLlmRequestPriority;\n enqueuedAtMs: number;\n resolve: (value: LocalLlmChatCompletionResult | null) => void;\n}\n\ninterface LocalLlmChatCompletionResult {\n content: string;\n usage?: { promptTokens: number; completionTokens: number; totalTokens: number };\n}\n\nconst LOCAL_LLM_GLOBAL_BACKEND_STATE = \"__openclawEngramLocalLlmBackendState\";\n\ntype LocalLlmBackendState = {\n untilMs: number;\n reason: string;\n};\nexport class LocalLlmClient {\n private config: PluginConfig;\n private isAvailable: boolean | null = null;\n private lastHealthCheck: number = 0;\n private readonly availabilityProbe = new SingleFlightProbe();\n private detectedType: LocalLlmType | null = null;\n private cachedModelInfo: LocalModelInfo | null = null;\n private cachedLmsContext: number | null = null;\n private lastLmsCheck: number = 0;\n private consecutive400s: number = 0;\n private cooldownUntilMs: number = 0;\n private modelRegistry?: ModelRegistry;\n private _disableThinking: boolean = false;\n private readonly requestQueues: Record<LocalLlmRequestPriority, LocalLlmQueuedRequest[]> = {\n \"recall-critical\": [],\n background: [],\n };\n private readonly queueProcessing = new Set<LocalLlmRequestPriority>();\n private queueDrainScheduled: boolean = false;\n private static readonly HEALTH_CHECK_INTERVAL_MS = 60000; // 1 minute\n private static readonly LMS_CACHE_INTERVAL_MS = 30000; // 30 seconds\n private readonly chatTransport = new ChatTransport();\n\n constructor(config: PluginConfig, modelRegistry?: ModelRegistry) {\n this.config = config;\n this.modelRegistry = modelRegistry;\n }\n\n /**\n * Request thinking/reasoning suppression on the next chat completion.\n *\n * When `true`, the client will inject\n * `chat_template_kwargs: { enable_thinking: false }` into the request\n * body — **but only when the detected backend is known to support it**\n * (LM Studio, vLLM; see `THINKING_COMPATIBLE_BACKENDS`). Strict\n * OpenAI-compat backends reject unknown fields with 400; on those the\n * client fails open (thinking runs normally). This is the safe\n * default for Remnic extraction-style operations: measurable latency\n * win on thinking-capable backends, zero risk on others. Consolidation\n * operations keep thinking enabled unless explicitly added to\n * `THINKING_SUPPRESSED_OPERATIONS`. Issues #548 and #979.\n */\n set disableThinking(value: boolean) {\n this._disableThinking = value;\n }\n\n private resolveHomeDir(): string {\n return this.config.localLlmHomeDir || readEnvVar(\"HOME\") || os.homedir();\n }\n\n private buildRequestHeaders(base: Record<string, string> = {}): Record<string, string> {\n const headers: Record<string, string> = {\n ...base,\n ...(this.config.localLlmHeaders ?? {}),\n };\n if (this.config.localLlmApiKey && this.config.localLlmAuthHeader !== false) {\n headers.Authorization = `Bearer ${this.config.localLlmApiKey}`;\n }\n return headers;\n }\n\n\n /**\n * Set the ModelRegistry for caching detected capabilities\n */\n setModelRegistry(registry: ModelRegistry): void {\n this.modelRegistry = registry;\n }\n\n /**\n * Get the detected server type (null if not detected)\n */\n getDetectedType(): LocalLlmType | null {\n return this.detectedType;\n }\n\n private getBackendKey(): string {\n return trimTrailingSlashes(\n this.config.localLlmUrl.replace(\"localhost\", \"127.0.0.1\"),\n ).replace(/\\/v1$/, \"\");\n }\n\n private getGlobalBackendState(): Map<string, LocalLlmBackendState> {\n const globalAny = globalThis as typeof globalThis & {\n [LOCAL_LLM_GLOBAL_BACKEND_STATE]?: Map<string, LocalLlmBackendState>;\n };\n if (!globalAny[LOCAL_LLM_GLOBAL_BACKEND_STATE]) {\n globalAny[LOCAL_LLM_GLOBAL_BACKEND_STATE] = new Map();\n }\n return globalAny[LOCAL_LLM_GLOBAL_BACKEND_STATE];\n }\n\n private getTrippedBackendState(now: number): LocalLlmBackendState | null {\n const state = this.getGlobalBackendState().get(this.getBackendKey()) ?? null;\n if (!state) return null;\n if (state.untilMs <= now) {\n this.getGlobalBackendState().delete(this.getBackendKey());\n this.lastHealthCheck = 0;\n return null;\n }\n return state;\n }\n\n private markBackendUnavailable(reason: string, durationMs: number): void {\n const normalizedReason = normalizeBackendTripReason(reason);\n if (durationMs > 0) {\n const untilMs = Date.now() + durationMs;\n this.getGlobalBackendState().set(this.getBackendKey(), { untilMs, reason: normalizedReason });\n } else {\n this.getGlobalBackendState().delete(this.getBackendKey());\n }\n this.isAvailable = false;\n this.lastHealthCheck = 0;\n log.warn(\n `local LLM backend unavailable for ${durationMs}ms: model=${this.config.localLlmModel} reason=${normalizedReason}`,\n );\n }\n\n\n /**\n * Fetch with timeout for health checks. Body lives in the sibling helper so\n * this file stays under its size ceiling (issue #1995).\n */\n private async fetchWithTimeout(\n url: string,\n timeoutMs: number = 2000,\n headers?: Record<string, string>,\n signal?: AbortSignal,\n ): Promise<ProbeFetchResult> {\n return await probeFetch(url, {\n timeoutMs,\n headers: this.buildRequestHeaders({ Accept: \"application/json\", ...(headers ?? {}) }),\n signal,\n });\n }\n\n private async probeLmStudioNativeModels(\n probeBaseUrl: string,\n signal?: AbortSignal,\n ): Promise<{ matched: boolean; unauthorized: boolean }> {\n let unauthorized = false;\n for (const endpoint of [\"/api/v1/models\", \"/api/v0/models\"]) {\n if (signal?.aborted) return { matched: false, unauthorized };\n const probe = await this.fetchWithTimeout(`${probeBaseUrl}${endpoint}`, 2000, undefined, signal);\n if (signal?.aborted) return { matched: false, unauthorized };\n if (probe.ok && isLmStudioNativeModelsResponse(probe.data)) {\n return { matched: true, unauthorized };\n }\n if (probe.status === 401 || probe.status === 403) {\n unauthorized = true;\n }\n }\n return { matched: false, unauthorized };\n }\n\n /**\n * Check if local LLM is available\n * Uses 127.0.0.1 instead of localhost to avoid DNS issues (consistent with tactician)\n */\n async checkAvailability(signal?: AbortSignal): Promise<boolean> {\n if (signal?.aborted) return false;\n // Cache health check results for 1 minute\n const now = Date.now();\n const trippedState = this.getTrippedBackendState(now);\n if (trippedState) {\n this.isAvailable = false;\n this.lastHealthCheck = 0;\n log.info(\n `local LLM availability: backend circuit open for ${Math.max(0, trippedState.untilMs - now)}ms (${trippedState.reason})`,\n );\n return false;\n }\n if (this.isAvailable !== null && now - this.lastHealthCheck < LocalLlmClient.HEALTH_CHECK_INTERVAL_MS) {\n return this.isAvailable;\n }\n return await this.availabilityProbe.run((probeSignal) => this.probeAvailability(probeSignal), signal);\n }\n\n private async probeAvailability(signal?: AbortSignal): Promise<boolean> {\n const now = Date.now();\n // Probe server-native endpoints from the server root even when users configure\n // the OpenAI-compatible `/v1` base URL for chat completions.\n const configuredBaseUrl = trimTrailingSlashes(\n this.config.localLlmUrl.replace(\"localhost\", \"127.0.0.1\"),\n );\n const probeBaseUrl = stripTrailingV1Path(configuredBaseUrl);\n let sawUnauthorizedProbe = false;\n // A probe that TIMED OUT says the event loop was busy, not that the backend\n // is down (issue #2210). Tracked separately so a loaded daemon cannot cache\n // itself into a blackout.\n let sawAbortedProbe = false;\n\n // Try to detect which server type is running\n if (signal?.aborted) return false;\n for (const serverConfig of orderedLocalServers(configuredBaseUrl)) {\n const healthUrl = `${probeBaseUrl}${serverConfig.healthEndpoint}`;\n log.debug(`checking ${serverConfig.type} at ${healthUrl}`);\n\n const result = await this.fetchWithTimeout(healthUrl, 2000, undefined, signal);\n if (result.aborted) sawAbortedProbe = true;\n if (signal?.aborted) return false;\n if (result.ok && serverConfig.detectFn(result.data)) {\n if (serverConfig.type === \"mlx\") {\n const lmStudioProbe = await this.probeLmStudioNativeModels(probeBaseUrl, signal);\n if (signal?.aborted) return false;\n if (lmStudioProbe.unauthorized) {\n sawUnauthorizedProbe = true;\n }\n if (lmStudioProbe.matched) {\n this.isAvailable = true;\n this.detectedType = \"lmstudio\";\n this.lastHealthCheck = now;\n log.info(`detected lmstudio at ${configuredBaseUrl}`);\n return true;\n }\n }\n if (serverConfig.type === \"llamacpp\") {\n let sawLlamaCppSignal = false;\n const propsProbe = await this.fetchWithTimeout(`${probeBaseUrl}/props`, 2000, undefined, signal);\n if (propsProbe.aborted) sawAbortedProbe = true;\n if (signal?.aborted) return false;\n if (propsProbe.ok && isLlamaCppPropsResponse(propsProbe.data)) {\n sawLlamaCppSignal = true;\n }\n if (propsProbe.status === 401 || propsProbe.status === 403) {\n sawUnauthorizedProbe = true;\n }\n\n const modelsUrl = `${probeBaseUrl}${serverConfig.modelsEndpoint}`;\n const modelsProbe = await this.fetchWithTimeout(modelsUrl, 2000, undefined, signal);\n if (modelsProbe.aborted) sawAbortedProbe = true;\n if (signal?.aborted) return false;\n if (modelsProbe.ok && isLlamaCppModelsResponse(modelsProbe.data)) {\n sawLlamaCppSignal = true;\n }\n if (modelsProbe.status === 401 || modelsProbe.status === 403) {\n sawUnauthorizedProbe = true;\n continue;\n }\n\n const authConfigured =\n Boolean(this.config.localLlmApiKey) &&\n this.config.localLlmAuthHeader !== false;\n if (!sawLlamaCppSignal || (authConfigured && !modelsProbe.ok)) {\n continue;\n }\n }\n this.isAvailable = true;\n this.detectedType = serverConfig.type;\n this.lastHealthCheck = now;\n log.info(`detected ${serverConfig.type} at ${configuredBaseUrl}`);\n return true;\n }\n if (result.status === 401 || result.status === 403) {\n sawUnauthorizedProbe = true;\n }\n }\n if (signal?.aborted) return false;\n\n // Generic check if specific detection failed\n try {\n const modelsUrl = `${probeBaseUrl}/v1/models`;\n const result = await this.fetchWithTimeout(modelsUrl, 2000, undefined, signal);\n if (result.aborted) sawAbortedProbe = true;\n if (signal?.aborted) return false;\n if (result.ok) {\n this.isAvailable = true;\n this.detectedType = \"generic\";\n this.lastHealthCheck = now;\n log.info(`detected generic OpenAI-compatible server at ${configuredBaseUrl}`);\n return true;\n }\n if (result.status === 401 || result.status === 403) {\n sawUnauthorizedProbe = true;\n }\n } catch {\n // Fall through to unavailable\n }\n\n const wasAvailable = this.isAvailable;\n this.detectedType = null;\n if (sawUnauthorizedProbe) {\n log.warn(\n `local LLM availability probe was unauthorized at ${configuredBaseUrl}; verify localLlmApiKey and localLlmAuthHeader settings`,\n );\n }\n const verdict = resolveUnavailableVerdict({\n baseUrl: configuredBaseUrl,\n sawAbortedProbe,\n wasAvailable,\n });\n this.isAvailable = verdict.cacheVerdict ? false : null;\n this.lastHealthCheck = verdict.cacheVerdict ? now : 0;\n if (verdict.warning) log.warn(verdict.warning);\n log.debug(\"local LLM not available at\", configuredBaseUrl);\n return false;\n }\n\n /**\n * Try to get context window from LM Studio settings.json as fallback.\n * This reads the defaultContextLength setting which is what LM Studio uses\n * when loading models without explicit context configuration.\n */\n private getContextFromLmStudioSettings(): number | null {\n try {\n const homeDir = this.resolveHomeDir();\n const settingsPath = `${homeDir}/.cache/lm-studio/settings.json`;\n\n if (!fs.existsSync(settingsPath)) {\n log.debug(`LM Studio settings: file not found at ${settingsPath}`);\n return null;\n }\n\n const content = fs.readFileSync(settingsPath, \"utf-8\");\n const settings = JSON.parse(content) as {\n defaultContextLength?: {\n type?: string;\n value?: number;\n };\n };\n\n if (settings.defaultContextLength?.value) {\n const contextWindow = settings.defaultContextLength.value;\n log.debug(`LM Studio settings: found default context length: ${contextWindow}`);\n return contextWindow;\n }\n\n return null;\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n log.debug(`LM Studio settings: failed to read - ${errorMsg}`);\n return null;\n }\n }\n\n /**\n * Try to get context window from LMS CLI (LM Studio specific).\n * Uses --json flag for reliable parsing.\n * Returns null if LMS CLI is not available or model not found.\n */\n private getContextFromLmsCli(modelId: string): number | null {\n try {\n // Check if lms CLI exists in common locations.\n // HOME may be absent in launchd environments, so prefer the resolved helper.\n const homeDir = this.resolveHomeDir();\n const lmsPaths = [\n this.config.localLmsCliPath || \"\",\n `${homeDir}/.cache/lm-studio/bin/lms`,\n \"/usr/local/bin/lms\",\n \"/opt/homebrew/bin/lms\",\n ];\n\n const lmsPath = lmsPaths.find((p) => p.length > 0 && fs.existsSync(p));\n if (!lmsPath) {\n log.debug(`LMS CLI: not found in standard locations (checked: ${lmsPaths.join(\", \")})`);\n return null;\n }\n\n // Run lms ps --json to get loaded models with context\n // Use spawnSync with shell and explicit PATH to ensure lms can find its dependencies\n log.debug(`LMS CLI: running: ${lmsPath} ps --json`);\n const existingPath = readEnvVar(\"PATH\") || \"\";\n const result = launchProcessSync(lmsPath, [\"ps\", \"--json\"], {\n encoding: \"utf-8\",\n timeout: 5000,\n shell: false, // Don't use shell for JSON output - more reliable\n env: mergeEnv({\n PATH: `${this.config.localLmsBinDir || `${homeDir}/.cache/lm-studio/bin`}:/usr/local/bin:/opt/homebrew/bin:/usr/bin:/bin:${existingPath}`,\n HOME: homeDir,\n }),\n });\n\n if (result.error) {\n log.debug(`LMS CLI: spawn error - ${result.error.message}`);\n return null;\n }\n\n if (result.stderr && result.stderr.trim()) {\n log.debug(`LMS CLI: stderr - ${result.stderr.slice(0, 200)}`);\n }\n\n const output = result.stdout || \"\";\n if (!output.trim()) {\n log.debug(\"LMS CLI: empty output - LM Studio may not be running or no models loaded\");\n return null;\n }\n\n // Parse JSON output\n let models: Array<{\n identifier?: string;\n modelKey?: string;\n contextLength?: number;\n maxContextLength?: number;\n }>;\n\n try {\n models = JSON.parse(output) as typeof models;\n } catch (parseErr) {\n log.debug(`LMS CLI: JSON parse error - ${parseErr}`);\n return null;\n }\n\n if (!Array.isArray(models) || models.length === 0) {\n log.debug(\"LMS CLI: no models loaded\");\n return null;\n }\n\n // Find the model matching our configured model ID\n const model = models.find((m) =>\n m.identifier === modelId ||\n m.modelKey === modelId ||\n (m.identifier?.includes(modelId.replace(/@\\d+bit$/, \"\")))\n );\n\n if (!model) {\n log.debug(`LMS CLI: model \"${modelId}\" not found in loaded models: ${models.map(m => m.identifier).join(\", \")}`);\n return null;\n }\n\n // Use contextLength (actual configured) or fall back to maxContextLength (model max)\n const contextWindow = model.contextLength || model.maxContextLength;\n\n if (contextWindow) {\n log.info(`LMS CLI detected context window: ${contextWindow} for ${modelId} (max: ${model.maxContextLength})`);\n return contextWindow;\n }\n\n return null;\n } catch (err) {\n // LMS CLI not available or failed\n const errorMsg = err instanceof Error ? err.message : String(err);\n log.debug(`LMS CLI: failed - ${errorMsg}`);\n return null;\n }\n }\n\n /**\n * Get full model info from LMS CLI including context length and max context length.\n * Returns null if LMS CLI is unavailable or model not found.\n */\n private getLmsModelInfo(modelId: string): { contextLength: number; maxContextLength: number; identifier: string } | null {\n try {\n const result = launchProcessSync(\"lms\", [\"ps\", \"--json\"], {\n encoding: \"utf-8\",\n timeout: 5000,\n shell: false,\n });\n\n if (result.error) {\n return null;\n }\n\n const output = result.stdout || \"\";\n if (!output.trim()) {\n return null;\n }\n\n let models: Array<{\n identifier?: string;\n modelKey?: string;\n contextLength?: number;\n maxContextLength?: number;\n }>;\n\n try {\n models = JSON.parse(output) as typeof models;\n } catch {\n return null;\n }\n\n if (!Array.isArray(models) || models.length === 0) {\n return null;\n }\n\n const model = models.find((m) =>\n m.identifier === modelId ||\n m.modelKey === modelId ||\n (m.identifier?.includes(modelId.replace(/@\\d+bit$/, \"\")))\n );\n\n if (!model || !model.contextLength) {\n return null;\n }\n\n return {\n contextLength: model.contextLength,\n maxContextLength: model.maxContextLength || model.contextLength,\n identifier: model.identifier || modelId,\n };\n } catch {\n return null;\n }\n }\n\n /**\n * Get context window for the configured model, using cache if available.\n * This method caches the result to avoid repeated LMS CLI calls.\n * Order: ModelRegistry (persistent) -> memory cache -> LMS CLI -> settings.json\n */\n getCachedContextWindow(modelId: string): number | null {\n const now = Date.now();\n\n // 1. Check ModelRegistry for persisted context window\n if (this.modelRegistry) {\n const caps = this.modelRegistry.getCapabilities(modelId);\n if (caps.source === \"lmstudio\" && caps.contextWindow) {\n log.debug(`ModelRegistry: using persisted LM Studio context: ${caps.contextWindow}`);\n // Also update memory cache\n this.cachedLmsContext = caps.contextWindow;\n this.lastLmsCheck = now;\n return caps.contextWindow;\n }\n }\n\n // 2. Return in-memory cached value if still valid\n if (this.cachedLmsContext && now - this.lastLmsCheck < LocalLlmClient.LMS_CACHE_INTERVAL_MS) {\n log.debug(`LMS CLI: returning in-memory cached context: ${this.cachedLmsContext}`);\n return this.cachedLmsContext;\n }\n\n // 3. Try LMS CLI (authoritative source)\n const lmsInfo = this.getLmsModelInfo(modelId);\n if (lmsInfo?.contextLength) {\n this.cachedLmsContext = lmsInfo.contextLength;\n this.lastLmsCheck = now;\n // Calculate appropriate output tokens based on context size\n // Use 12.5% of context window, capped at 16K (generous but safe)\n const calculatedOutputTokens = Math.min(Math.floor(lmsInfo.contextLength / 8), 16384);\n const outputTokens = Math.max(calculatedOutputTokens, 4096); // Minimum 4K\n // Persist to ModelRegistry with detected capabilities\n if (this.modelRegistry) {\n this.modelRegistry.setCapabilities(modelId, {\n maxPositionEmbeddings: lmsInfo.maxContextLength || lmsInfo.contextLength,\n contextWindow: lmsInfo.contextLength,\n supportsExtendedContext: (lmsInfo.maxContextLength || lmsInfo.contextLength) > 65536,\n typicalOutputTokens: outputTokens,\n source: \"lmstudio\",\n });\n log.info(`LMS CLI: Stored capabilities for ${modelId}: ${lmsInfo.contextLength} context, ${outputTokens} output tokens`);\n }\n return lmsInfo.contextLength;\n }\n\n // Legacy: Try LMS CLI context only (fallback)\n const legacyContext = this.getContextFromLmsCli(modelId);\n if (legacyContext) {\n this.cachedLmsContext = legacyContext;\n this.lastLmsCheck = now;\n // Persist to ModelRegistry with calculated output tokens\n if (this.modelRegistry) {\n const calculatedOutputTokens = Math.min(Math.floor(legacyContext / 8), 16384);\n const outputTokens = Math.max(calculatedOutputTokens, 4096);\n this.modelRegistry.setCapabilities(modelId, {\n maxPositionEmbeddings: legacyContext,\n contextWindow: legacyContext,\n supportsExtendedContext: false,\n typicalOutputTokens: outputTokens,\n source: \"lmstudio\",\n });\n }\n return legacyContext;\n }\n\n // 4. Fall back to LM Studio settings.json\n const settingsContext = this.getContextFromLmStudioSettings();\n if (settingsContext) {\n log.info(`LM Studio settings: using default context: ${settingsContext}`);\n this.cachedLmsContext = settingsContext;\n this.lastLmsCheck = now;\n return settingsContext;\n }\n\n return null;\n }\n\n /**\n * Clear the LMS context cache. Call this when the model changes.\n */\n clearContextCache(): void {\n this.cachedLmsContext = null;\n this.lastLmsCheck = 0;\n log.debug(\"LMS CLI: context cache cleared\");\n }\n\n private remainingCooldownMs(now: number = Date.now()): number {\n return Math.max(0, this.cooldownUntilMs - now);\n }\n\n private scheduleQueueDrain(): void {\n if (this.queueDrainScheduled) return;\n this.queueDrainScheduled = true;\n\n queueMicrotask(() => {\n this.queueDrainScheduled = false;\n this.startAvailableQueuedRequests();\n });\n }\n\n /** True when a background-priority request occupies or awaits this client's local lane (issue #2011). */\n isBackgroundLaneContended(): boolean {\n return this.queueProcessing.has(\"background\") || this.requestQueues.background.length > 0;\n }\n\n private dequeueQueuedRequest(priority: LocalLlmRequestPriority): LocalLlmQueuedRequest | null {\n const next = this.requestQueues[priority].shift();\n return next ?? null;\n }\n\n private failOpenQueuedRequestsForCooldown(): number {\n let dropped = 0;\n for (const priority of [\"recall-critical\", \"background\"] as const) {\n while (this.requestQueues[priority].length > 0) {\n const queued = this.requestQueues[priority].shift();\n queued?.resolve(null);\n dropped += 1;\n }\n }\n return dropped;\n }\n\n private startAvailableQueuedRequests(): void {\n if (!this.queueProcessing.has(\"recall-critical\")) {\n const nextCritical = this.dequeueQueuedRequest(\"recall-critical\");\n if (nextCritical) {\n this.queueProcessing.add(\"recall-critical\");\n void this.runQueuedRequest(nextCritical);\n }\n }\n\n if (!this.queueProcessing.has(\"background\")) {\n const nextBackground = this.dequeueQueuedRequest(\"background\");\n if (nextBackground) {\n this.queueProcessing.add(\"background\");\n void this.runQueuedRequest(nextBackground);\n }\n }\n }\n\n private async runQueuedRequest(next: LocalLlmQueuedRequest): Promise<void> {\n try {\n if (next.options.signal?.aborted) {\n next.resolve(null);\n return;\n }\n const remainingCooldownMs = this.remainingCooldownMs();\n if (remainingCooldownMs > 0) {\n const additionalDropped = this.failOpenQueuedRequestsForCooldown();\n log.warn(\n `local LLM: cooldown active (${remainingCooldownMs}ms remaining), dropping ${additionalDropped + 1} queued request(s) fail-open`,\n );\n next.resolve(null);\n return;\n }\n\n let result: LocalLlmChatCompletionResult | null = null;\n try {\n result = await this.runChatCompletionRequest(next.messages, next.options, {\n priority: next.priority,\n enqueuedAtMs: next.enqueuedAtMs,\n });\n } catch (err) {\n log.warn(`local LLM queue drain failed open: ${next.options.redactProviderErrors ? \"provider error details redacted\" : err instanceof Error ? err.message : String(err)}`);\n }\n next.resolve(result);\n } finally {\n this.queueProcessing.delete(next.priority);\n if (this.requestQueues[\"recall-critical\"].length > 0 || this.requestQueues.background.length > 0) {\n this.scheduleQueueDrain();\n }\n }\n }\n\n private async runChatCompletionRequest(\n messages: Array<{ role: string; content: string }>,\n options: LocalLlmChatCompletionOptions,\n queueMeta?: { priority: LocalLlmRequestPriority; enqueuedAtMs: number },\n ): Promise<LocalLlmChatCompletionResult | null> {\n log.debug(\n `local LLM chatCompletion: localLlmEnabled=${resolveLocalLlmCapabilities(this.config).localLlm}, model=${this.config.localLlmModel}`,\n );\n\n const operation = options.operation ?? \"unspecified\";\n const startedAtMs = Date.now();\n if (queueMeta) {\n log.debug(\n `local LLM queue start: priority=${queueMeta.priority} waitMs=${startedAtMs - queueMeta.enqueuedAtMs} op=${operation}`,\n );\n }\n\n try {\n if (options.signal?.aborted) return null;\n const isAvailable = await this.checkAvailability(options.signal);\n if (!isAvailable) {\n log.debug(\n `local LLM: checkAvailability returned false for ${this.config.localLlmUrl}`,\n );\n return null;\n }\n\n const promptChars = messages.reduce((sum, m) => sum + (m.content?.length ?? 0), 0);\n const requestBody: Record<string, unknown> = {\n model: options.model ?? this.config.localLlmModel,\n messages,\n temperature: options.temperature ?? 0.7,\n // Use max_tokens consistent with cloud models\n max_tokens: options.maxTokens ?? 4096,\n stream: false,\n };\n\n // Skip response_format for local LLMs - they don't support json_object type\n // The prompts already instruct the model to output JSON\n // Only send if it's json_schema type which some local LLMs support\n if (options.responseFormat?.type === \"json_schema\") {\n requestBody.response_format = options.responseFormat;\n }\n\n // Suppress thinking/reasoning for operations that benefit from terse,\n // structured output. Thinking-capable models (Qwen 3.5, Gemma 4,\n // DeepSeek) default to thinking-on via their chat template; sending\n // `chat_template_kwargs: { enable_thinking: false }` tells the template\n // to skip reasoning tokens. Consolidation operations on the main client\n // intentionally keep thinking enabled so entity resolution and\n // deduplication can use the model's reasoning path. Fast-tier callers can\n // still force suppression per request to preserve their low-latency\n // contract.\n //\n // Gate the injection on detected backend support (issue #548,\n // Codex P1 on PR #550): `chat_template_kwargs` is an LM Studio /\n // vLLM / llama.cpp extension, not part of standard OpenAI chat\n // completions. Strict OpenAI-compatible backends reject\n // unknown fields with 400, which trips the 400-cooldown path and\n // can effectively disable local extraction. Fail open when the\n // backend hasn't been positively identified as thinking-capable.\n const shouldSuppressThinking =\n options.forceDisableThinking === true ||\n ((options.disableThinking ?? this._disableThinking) &&\n THINKING_SUPPRESSED_OPERATIONS.has(operation));\n if (\n shouldSuppressThinking &&\n this.detectedType !== null &&\n THINKING_COMPATIBLE_BACKENDS.has(this.detectedType)\n ) {\n requestBody.chat_template_kwargs = { enable_thinking: false };\n } else if (shouldSuppressThinking && this.detectedType === \"ollama\") {\n // Ollama's /v1 endpoint silently drops `chat_template_kwargs` AND\n // `enable_thinking` — the ONLY field it maps to think-off is\n // `reasoning_effort` (\"none\" → ThinkValue{false} in openai.go;\n // verified against Ollama 0.32.0 source and live probes,\n // issue #1996). Without this, thinking-capable models (Gemma 4,\n // Qwen 3.5+) burn 1,700-2,000 reasoning tokens per extraction on\n // Ollama, exceed the client timeout, and retry forever. The effort\n // is configurable via `localLlmReasoningEffort` (default \"none\");\n // an empty value disables injection (pre-#1996 behavior).\n const effort = this.config.localLlmReasoningEffort;\n if (effort) {\n requestBody.reasoning_effort = effort;\n }\n }\n\n // Normalize URL (use 127.0.0.1 instead of localhost)\n const baseUrl = trimTrailingSlashes(\n this.config.localLlmUrl.replace(\"localhost\", \"127.0.0.1\"),\n );\n const chatUrl = baseUrl.endsWith(\"/v1\")\n ? `${baseUrl}/chat/completions`\n : `${baseUrl}/v1/chat/completions`;\n\n const requestBodyJson = JSON.stringify(requestBody);\n log.debug(\n `local LLM: sending request to ${chatUrl} with model ${this.config.localLlmModel}`,\n );\n // Avoid logging request bodies by default (can contain sensitive user content).\n log.debug(`local LLM: request body length=${requestBodyJson.length}`);\n\n const effectiveTimeoutMs =\n typeof options.timeoutMs === \"number\"\n ? Math.min(this.config.localLlmTimeoutMs, options.timeoutMs)\n : this.config.localLlmTimeoutMs;\n const maxAttempts = 1 + Math.max(0, this.config.localLlmRetry5xxCount);\n let response: Response | null = null, responseBody = \"\";\n let lastAbortError: Error | null = null;\n for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {\n response = null;\n responseBody = \"\";\n const attemptAbort = new AbortController();\n const onCallerAbort = (): void => {\n attemptAbort.abort(options.signal?.reason);\n };\n if (options.signal) {\n if (options.signal.aborted) {\n onCallerAbort();\n } else {\n options.signal.addEventListener(\"abort\", onCallerAbort, { once: true });\n }\n }\n const attemptTimeout = setTimeout(() => attemptAbort.abort(), effectiveTimeoutMs);\n try {\n response = await this.chatTransport.post({\n url: chatUrl,\n headers: this.buildRequestHeaders({\n \"Content-Type\": \"application/json\",\n }),\n body: requestBodyJson,\n signal: attemptAbort.signal,\n budgetMs: this.config.localLlmTimeoutMs,\n });\n responseBody = await response.text();\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n if (options.signal?.aborted) {\n response = null;\n lastAbortError = error;\n break;\n }\n if (response && !response.ok) {\n log.debug(`local LLM failed to read ${response.status} response body: ${options.redactProviderErrors ? \"details redacted\" : error.message}`);\n } else {\n response = null;\n if (!isAbortError(err)) throw err;\n lastAbortError = error;\n if (attempt >= maxAttempts) break;\n const backoffMs = this.config.localLlmRetryBackoffMs * attempt;\n log.warn(\n `local LLM request aborted: op=${operation} attempt=${attempt}/${maxAttempts} timeoutMs=${effectiveTimeoutMs} model=${this.config.localLlmModel}; retrying after ${backoffMs}ms`,\n );\n if (!(await waitForRetryBackoff(backoffMs, options.signal))) return null;\n continue;\n }\n } finally {\n clearTimeout(attemptTimeout);\n options.signal?.removeEventListener(\"abort\", onCallerAbort);\n }\n\n if (response.ok) break;\n if (response.status >= 500 && attempt < maxAttempts) {\n const nonRecoverableReason =\n extractNonRecoverableBackendReasonFromErrorText(responseBody);\n if (nonRecoverableReason) {\n this.markBackendUnavailable(\n nonRecoverableReason,\n this.config.localLlm400CooldownMs,\n );\n this.consecutive400s = 0;\n return null;\n }\n }\n if (response.status < 500 || attempt >= maxAttempts) break;\n\n const backoffMs = this.config.localLlmRetryBackoffMs * attempt;\n log.warn(\n `local LLM request got ${response.status}; retrying (attempt ${attempt + 1}/${maxAttempts}) after ${backoffMs}ms`,\n );\n if (!(await waitForRetryBackoff(backoffMs, options.signal))) return null;\n }\n log.debug(\n `local LLM: received response, status=${response?.status}, ok=${response?.ok}`,\n );\n if (!response) {\n if (lastAbortError) {\n log.warn(\n `local LLM request aborted after ${maxAttempts} attempt(s): op=${operation} timeoutMs=${effectiveTimeoutMs} model=${this.config.localLlmModel} promptChars=${promptChars} durationMs=${Date.now() - startedAtMs}`,\n );\n } else {\n log.warn(\n `local LLM request failed: no response object (op=${operation} model=${this.config.localLlmModel} durationMs=${Date.now() - startedAtMs})`,\n );\n }\n return null;\n }\n\n if (!response.ok) {\n let reason = \"\";\n try {\n const parsed = JSON.parse(responseBody) as { error?: { message?: string } };\n reason = parsed?.error?.message ? ` — ${parsed.error.message}` : \"\";\n } catch {\n if (!options.redactProviderErrors) log.debug(`local LLM error body: ${responseBody.slice(0, 500)}`);\n }\n log.warn(\n `local LLM request failed: ${response.status}${options.redactProviderErrors ? \"\" : ` ${response.statusText}${reason}`} ` +\n `(op=${operation}, model=${this.config.localLlmModel}, url=${chatUrl}, promptChars=${promptChars}, maxTokens=${requestBody.max_tokens as number})`,\n );\n const nonRecoverableReason =\n extractNonRecoverableBackendReason(reason) ??\n extractNonRecoverableBackendReasonFromErrorText(responseBody);\n if (nonRecoverableReason) {\n this.markBackendUnavailable(\n nonRecoverableReason,\n this.config.localLlm400CooldownMs,\n );\n this.consecutive400s = 0;\n return null;\n }\n if (response.status === 400) {\n this.consecutive400s += 1;\n if (this.consecutive400s >= this.config.localLlm400TripThreshold) {\n this.cooldownUntilMs = Date.now() + this.config.localLlm400CooldownMs;\n log.warn(\n `local LLM: entering cooldown for ${this.config.localLlm400CooldownMs}ms ` +\n `after ${this.consecutive400s} consecutive 400 responses`,\n );\n this.consecutive400s = 0;\n }\n } else {\n this.consecutive400s = 0;\n }\n return null;\n }\n this.consecutive400s = 0;\n\n const data = JSON.parse(responseBody) as {\n choices?: Array<{\n message?: { content?: string; reasoning_content?: string };\n }>;\n usage?: {\n prompt_tokens?: number;\n completion_tokens?: number;\n total_tokens?: number;\n };\n };\n\n log.debug(\n `local LLM response: choices=${data.choices?.length}, usage=${JSON.stringify(data.usage)}`,\n );\n\n // Thinking models (e.g. Qwen 3.5) may put their response in\n // `reasoning_content` and leave `content` empty. Fall back to\n // reasoning_content so engram still gets a usable result.\n const msg = data.choices?.[0]?.message;\n const content = msg?.content || msg?.reasoning_content || \"\";\n if (!content) {\n log.warn(`local LLM returned empty content.${options.redactProviderErrors ? \"\" : ` choices=${JSON.stringify(data.choices)?.slice(0, 200)}`}`);\n return null;\n }\n\n // Estimate tokens if not provided by local LLM\n const usage = data.usage\n ? {\n promptTokens: data.usage.prompt_tokens ?? 0,\n completionTokens: data.usage.completion_tokens ?? 0,\n totalTokens: data.usage.total_tokens ?? 0,\n }\n : this.estimateTokens(messages, content);\n\n const durationMs = Date.now() - startedAtMs;\n if (resolvePipelineProcessingCapabilities(this.config).slowLog && durationMs >= this.config.slowLogThresholdMs) {\n const promptChars = messages.reduce((sum, m) => sum + (m.content?.length ?? 0), 0);\n const op = options.operation ? ` op=${options.operation}` : \"\";\n log.warn(\n `SLOW local LLM:${op} durationMs=${durationMs} model=${this.config.localLlmModel} url=${chatUrl} promptChars=${promptChars} outputTokens=${usage.completionTokens} totalTokens=${usage.totalTokens}`,\n );\n }\n\n log.debug(\"local LLM: request succeeded, tokens:\", usage.totalTokens);\n return { content, usage };\n } catch (err) {\n const errMsg = err instanceof Error ? err.message : String(err);\n const durationMs = Date.now() - startedAtMs;\n if (isAbortError(err)) {\n log.warn(\n `local LLM request aborted: op=${operation} timeoutMs=${options.timeoutMs ?? this.config.localLlmTimeoutMs} model=${this.config.localLlmModel} durationMs=${durationMs} error=${options.redactProviderErrors ? \"provider error details redacted\" : errMsg}`,\n );\n return null;\n }\n log.warn(`local LLM request error: op=${operation} error=${options.redactProviderErrors ? \"provider error details redacted\" : errMsg}`);\n this.isAvailable = false; // Mark as unavailable on non-abort errors\n const nonRecoverableReason = extractNonRecoverableBackendReason(errMsg);\n if (nonRecoverableReason) {\n this.markBackendUnavailable(\n nonRecoverableReason,\n this.config.localLlm400CooldownMs,\n );\n }\n return null;\n } finally {\n if (queueMeta) {\n const finishedAtMs = Date.now();\n const waitMs = startedAtMs - queueMeta.enqueuedAtMs;\n log.debug(\n `local LLM queue finish: priority=${queueMeta.priority} waitMs=${waitMs} runMs=${finishedAtMs - startedAtMs} totalMs=${finishedAtMs - queueMeta.enqueuedAtMs} op=${operation}`,\n );\n }\n }\n }\n\n /**\n * Query the local LLM server for loaded model information.\n * Returns null if unavailable or if the model is not found.\n */\n async getLoadedModelInfo(): Promise<LocalModelInfo | null> {\n const baseUrl = trimTrailingSlashes(\n this.config.localLlmUrl.replace(\"localhost\", \"127.0.0.1\"),\n );\n\n // Handle URL construction - localLlmUrl may already include /v1\n const modelsUrl = baseUrl.endsWith(\"/v1\")\n ? `${baseUrl}/models`\n : `${baseUrl}/v1/models`;\n log.debug(`Fetching model info from ${modelsUrl}`);\n\n try {\n const result = await this.fetchWithTimeout(modelsUrl, 3000);\n if (!result.ok) {\n if (result.status === 401 || result.status === 403) {\n log.warn(\n `Local LLM: unauthorized while fetching models from ${modelsUrl}; verify localLlmApiKey and localLlmAuthHeader settings`,\n );\n }\n log.warn(`Local LLM: Failed to fetch models from ${modelsUrl} - server returned error`);\n return null;\n }\n if (!result.data) {\n log.warn(`Local LLM: No data returned from ${modelsUrl}`);\n return null;\n }\n\n const data = result.data as {\n data?: Array<{\n id?: string;\n object?: string;\n owned_by?: string;\n // LM Studio specific fields\n max_context_length?: number;\n max_tokens?: number;\n // Ollama specific\n name?: string;\n details?: {\n parameter_size?: string;\n family?: string;\n };\n }>;\n };\n\n if (!Array.isArray(data.data) || data.data.length === 0) {\n log.warn(\"Local LLM returned no models\");\n return null;\n }\n\n // Verbose model listings are noisy on every gateway restart. Keep it debug-only.\n const modelIds = data.data.map((m) => m.id).filter(Boolean);\n log.debug(\n `Local LLM: Found ${modelIds.length} model(s). First 10: ${modelIds.slice(0, 10).join(\", \")}`,\n );\n\n // Find the model matching our configured model ID\n const configuredModel = this.config.localLlmModel;\n let model = data.data.find((m) => m.id === configuredModel);\n\n // If not found by exact match, try partial match (handle suffixes like @4bit)\n if (!model) {\n model = data.data.find((m) =>\n configuredModel.includes(m.id || \"\") ||\n (m.id || \"\").includes(configuredModel.replace(/@\\d+bit$/, \"\"))\n );\n }\n\n // If still not found, use the first loaded model and warn\n if (!model) {\n model = data.data[0];\n const availablePreview = data.data\n .map((m) => m.id)\n .filter(Boolean)\n .slice(0, 10)\n .join(\", \");\n log.warn(\n `Configured model \"${configuredModel}\" not found in local LLM. ` +\n `Using \"${model.id}\" instead. Available (first 10): ${availablePreview}`\n );\n }\n\n // Extract context window - try multiple field names\n let contextWindow = model.max_context_length || model.max_tokens;\n\n // If API doesn't report context window, try LMS CLI (LM Studio specific)\n if (!contextWindow) {\n log.info(\"Local LLM: API did not report context window, trying LMS CLI...\");\n const lmsContext = this.getCachedContextWindow(model.id || \"\");\n if (lmsContext) {\n contextWindow = lmsContext;\n }\n }\n\n this.cachedModelInfo = {\n id: model.id || \"unknown\",\n contextWindow: contextWindow,\n maxTokens: model.max_tokens,\n };\n\n log.info(\n `Local LLM model detected: ${this.cachedModelInfo.id}, ` +\n `context window: ${contextWindow?.toLocaleString() || \"unknown (may use default)\"}`\n );\n\n return this.cachedModelInfo;\n } catch (err) {\n log.warn(`Failed to fetch model info: ${err}`);\n return null;\n }\n }\n\n /**\n * Check if the configured model is available and get its actual context window.\n * Warns if there's a mismatch between expected and actual context.\n */\n async validateModelConfig(expectedContextWindow?: number): Promise<{\n available: boolean;\n actualContextWindow?: number;\n warnings: string[];\n }> {\n const warnings: string[] = [];\n\n const modelInfo = await this.getLoadedModelInfo();\n if (!modelInfo) {\n return { available: false, warnings: [\"Could not query local LLM for model info\"] };\n }\n\n // If we have expected context and the server reports one, check for mismatch\n if (expectedContextWindow && modelInfo.contextWindow) {\n if (modelInfo.contextWindow < expectedContextWindow) {\n warnings.push(\n `Context window mismatch: Model ${modelInfo.id} supports ${modelInfo.contextWindow.toLocaleString()} tokens, ` +\n `but engram is configured for ${expectedContextWindow.toLocaleString()}. ` +\n `Set localLlmMaxContext: ${modelInfo.contextWindow} in config to avoid errors.`\n );\n }\n }\n\n // Warn if server doesn't report context window (common with some local LLM setups)\n if (!modelInfo.contextWindow) {\n warnings.push(\n `Local LLM server did not report context window for ${modelInfo.id}. ` +\n `If you get \"context length exceeded\" errors, set localLlmMaxContext in config.`\n );\n }\n\n return {\n available: true,\n actualContextWindow: modelInfo.contextWindow,\n warnings,\n };\n }\n\n /**\n * Make a chat completion request to local LLM\n */\n async chatCompletion(\n messages: Array<{ role: string; content: string }>,\n options: LocalLlmChatCompletionOptions = {},\n ): Promise<LocalLlmChatCompletionResult | null> {\n if (!resolveLocalLlmCapabilities(this.config).localLlm) {\n log.debug(\"local LLM: disabled, returning null\");\n return null;\n }\n\n const remainingMs = this.remainingCooldownMs();\n if (remainingMs > 0) {\n log.debug(`local LLM: cooldown active (${remainingMs}ms remaining), skipping request`);\n return null;\n }\n if (options.priority) {\n const priority = options.priority;\n return await new Promise<LocalLlmChatCompletionResult | null>((resolve) => {\n this.requestQueues[priority].push({\n messages,\n options,\n priority,\n enqueuedAtMs: Date.now(),\n resolve,\n });\n this.scheduleQueueDrain();\n });\n }\n\n return await this.runChatCompletionRequest(messages, options);\n }\n /**\n * Estimate tokens when local LLM does not return usage stats.\n */\n private estimateTokens(\n messages: Array<{ role: string; content: string }>,\n response: string\n ): { promptTokens: number; completionTokens: number; totalTokens: number } {\n const promptTokens = messages.reduce((sum, message) => sum + estimateTokenCount(message.content), 0);\n const completionTokens = estimateTokenCount(response);\n\n return {\n promptTokens,\n completionTokens,\n totalTokens: promptTokens + completionTokens,\n };\n }\n\n /**\n * Try local LLM first, fallback to cloud provider if configured\n */\n async withFallback<T>(\n localOperation: () => Promise<T | null>,\n fallbackOperation: () => Promise<T>,\n operationName: string\n ): Promise<T> {\n // Try local LLM first if enabled\n if (resolveLocalLlmCapabilities(this.config).localLlm) {\n const localResult = await localOperation();\n if (localResult !== null) {\n log.debug(`${operationName}: used local LLM`);\n return localResult;\n }\n\n // Local failed or unavailable\n if (this.config.localLlmFallback) {\n log.info(`${operationName}: local LLM unavailable, falling back to cloud`);\n } else {\n throw new Error(`${operationName}: local LLM unavailable and fallback disabled`);\n }\n }\n\n // Use fallback (cloud provider)\n return fallbackOperation();\n }\n}\n"],"mappings":"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","names":["backoffMs","promptChars"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/deep-recall-seeds.ts"],"sourcesContent":["/**\n * Deep-recall seed retrieval (issue #2332 review).\n *\n * Seeds route through the SAME namespace search router the rest of the read\n * path uses, so a non-default caller searches its own suffixed collection\n * instead of the base (default-namespace) collection — read and write resolve\n * through one resolver, never two (§30).\n *\n * Each hit is resolved to a real memory id through the shared QMD result\n * resolver (`QmdResultResolver.readQmdResultMemory`), per hit and bounded by\n * the requested limit, instead of pre-scanning the whole namespace corpus to\n * build a path index. With namespaces disabled the fanout queries the QMD\n * backend directly, so hits keep the indexer's raw path forms; the resolver\n * decodes `qmd://<collection>/` URIs and `<collection>/`-prefixed relatives,\n * and the two forms it cannot decode (`qmd:///`, a leading `/`) are stripped\n * for one retry. A hit with no path is dropped: its namespace membership\n * cannot be verified, and a bare docid from a foreign collection must never\n * enter the working set as a resolved memory.\n *\n * An unavailable namespace backend (or a missing collection) contributes an\n * empty result set and reports itself only through `execution.onDegradation`,\n * so the observer is REQUIRED here: without it a dead index is indistinguishable\n * from a healthy empty one and deep recall would answer `ok: true` with zero\n * entries instead of the advertised `backend_unavailable` failure.\n */\n\nimport type { DeepRecallSeedHit } from \"./deep-recall.js\";\nimport type { SearchDegradation } from \"./search/port.js\";\n\n/** Namespace-scoped search entrypoint (satisfied by `Orchestrator.searchAcrossNamespaces`). */\nexport interface DeepRecallSeedRouter {\n searchAcrossNamespaces(options: {\n query: string;\n namespaces: string[];\n maxResults?: number;\n execution?: { onDegradation?: (degradation: SearchDegradation) => void };\n }): Promise<ReadonlyArray<{ path?: string; docid?: string; score?: number }>>;\n}\n\n/** Namespace-scoped storage read (satisfied by `StorageManager`). */\nexport interface DeepRecallSeedStorage {\n readonly dir: string;\n readMemoryByPath(filePath: string): Promise<{ frontmatter: { id?: string } } | null>;\n}\n\n/** Full QMD hit -> memory resolver (satisfied by `QmdResultResolver#readQmdResultMemory`). */\nexport interface DeepRecallSeedResultResolver {\n readQmdResultMemory(\n resultPath: string,\n fallbackStorage: DeepRecallSeedStorage,\n recallNamespaces?: readonly string[],\n preferredNamespace?: string,\n ): Promise<{ frontmatter: { id?: string } } | null>;\n}\n\n/**\n * Strip the collection-qualified forms the indexer can emit but\n * `readQmdResultMemory` cannot decode: the empty-hostname `qmd:///` URI and\n * the root-relative `/` path both reach its fallback probe still prefixed and\n * miss. Returns `null` when the path carries no such prefix — including a\n * decodable `qmd://<collection>/` or `<collection>/` form, which the resolver\n * owns, and a foreign collection prefix, which must stay a miss.\n */\nfunction collectionPrefixStrippedPath(resultPath: string): string | null {\n const trimmed = resultPath.trim();\n if (trimmed.startsWith(\"qmd:///\")) {\n const relative = trimmed.slice(\"qmd:///\".length).replace(/^\\/+/, \"\");\n return relative.length > 0 ? relative : null;\n }\n if (trimmed.startsWith(\"/\")) {\n const relative = trimmed.replace(/^\\/+/, \"\");\n return relative.length > 0 ? relative : null;\n }\n return null;\n}\n\nasync function resolveSeedMemoryId(\n resolver: DeepRecallSeedResultResolver,\n storage: DeepRecallSeedStorage,\n namespace: string,\n resultPath: string | undefined,\n): Promise<string | null> {\n if (typeof resultPath !== \"string\" || resultPath.length === 0) return null;\n const attempts = [resultPath];\n const stripped = collectionPrefixStrippedPath(resultPath);\n if (stripped !== null) attempts.push(stripped);\n for (const attempt of attempts) {\n const memory = await resolver.readQmdResultMemory(attempt, storage, [namespace]);\n const id = memory?.frontmatter?.id;\n if (typeof id === \"string\" && id.length > 0) return id;\n }\n return null;\n}\n\nexport function createDeepRecallSeedSearch(deps: {\n namespace: string;\n storage: DeepRecallSeedStorage;\n router: DeepRecallSeedRouter;\n resolver: DeepRecallSeedResultResolver;\n}): (query: string, limit: number) => Promise<DeepRecallSeedHit[]> {\n return async (query, limit) => {\n if (limit <= 0) return [];\n const unavailable: SearchDegradation[] = [];\n const hits = await deps.router.searchAcrossNamespaces({\n query,\n namespaces: [deps.namespace],\n maxResults: limit,\n execution: {\n onDegradation: (degradation) => {\n if (degradation.code === \"backend_unavailable\") unavailable.push(degradation);\n },\n },\n });\n // The requested namespace has no usable index: a seed-search failure, which\n // is the one condition deep recall reports as `backend_unavailable`.\n if (unavailable.length > 0) {\n throw new Error(\n `deep recall seed search unavailable: ${unavailable.map((d) => d.detail ?? d.code).join(\"; \")}`,\n );\n }\n const seeds: DeepRecallSeedHit[] = [];\n for (const hit of hits) {\n if (typeof hit.path !== \"string\" || hit.path.length === 0) continue;\n const memoryId =\n (await resolveSeedMemoryId(deps.resolver, deps.storage, deps.namespace, hit.path)) ?? hit.docid;\n if (typeof memoryId !== \"string\" || memoryId.length === 0) continue;\n seeds.push({\n memoryId,\n score: typeof hit.score === \"number\" && Number.isFinite(hit.score) ? hit.score : 0,\n });\n }\n return seeds;\n };\n}\n"],"mappings":";AA+DA,SAAS,6BAA6B,YAAmC;AACvE,QAAM,UAAU,WAAW,KAAK;AAChC,MAAI,QAAQ,WAAW,SAAS,GAAG;AACjC,UAAM,WAAW,QAAQ,MAAM,UAAU,MAAM,EAAE,QAAQ,QAAQ,EAAE;AACnE,WAAO,SAAS,SAAS,IAAI,WAAW;AAAA,EAC1C;AACA,MAAI,QAAQ,WAAW,GAAG,GAAG;AAC3B,UAAM,WAAW,QAAQ,QAAQ,QAAQ,EAAE;AAC3C,WAAO,SAAS,SAAS,IAAI,WAAW;AAAA,EAC1C;AACA,SAAO;AACT;AAEA,eAAe,oBACb,UACA,SACA,WACA,YACwB;AACxB,MAAI,OAAO,eAAe,YAAY,WAAW,WAAW,EAAG,QAAO;AACtE,QAAM,WAAW,CAAC,UAAU;AAC5B,QAAM,WAAW,6BAA6B,UAAU;AACxD,MAAI,aAAa,KAAM,UAAS,KAAK,QAAQ;AAC7C,aAAW,WAAW,UAAU;AAC9B,UAAM,SAAS,MAAM,SAAS,oBAAoB,SAAS,SAAS,CAAC,SAAS,CAAC;AAC/E,UAAM,KAAK,QAAQ,aAAa;AAChC,QAAI,OAAO,OAAO,YAAY,GAAG,SAAS,EAAG,QAAO;AAAA,EACtD;AACA,SAAO;AACT;AAEO,SAAS,2BAA2B,MAKwB;AACjE,SAAO,OAAO,OAAO,UAAU;AAC7B,QAAI,SAAS,EAAG,QAAO,CAAC;AACxB,UAAM,cAAmC,CAAC;AAC1C,UAAM,OAAO,MAAM,KAAK,OAAO,uBAAuB;AAAA,MACpD;AAAA,MACA,YAAY,CAAC,KAAK,SAAS;AAAA,MAC3B,YAAY;AAAA,MACZ,WAAW;AAAA,QACT,eAAe,CAAC,gBAAgB;AAC9B,cAAI,YAAY,SAAS,sBAAuB,aAAY,KAAK,WAAW;AAAA,QAC9E;AAAA,MACF;AAAA,IACF,CAAC;AAGD,QAAI,YAAY,SAAS,GAAG;AAC1B,YAAM,IAAI;AAAA,QACR,wCAAwC,YAAY,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,KAAK,IAAI,CAAC;AAAA,MAC/F;AAAA,IACF;AACA,UAAM,QAA6B,CAAC;AACpC,eAAW,OAAO,MAAM;AACtB,UAAI,OAAO,IAAI,SAAS,YAAY,IAAI,KAAK,WAAW,EAAG;AAC3D,YAAM,WACH,MAAM,oBAAoB,KAAK,UAAU,KAAK,SAAS,KAAK,WAAW,IAAI,IAAI,KAAM,IAAI;AAC5F,UAAI,OAAO,aAAa,YAAY,SAAS,WAAW,EAAG;AAC3D,YAAM,KAAK;AAAA,QACT;AAAA,QACA,OAAO,OAAO,IAAI,UAAU,YAAY,OAAO,SAAS,IAAI,KAAK,IAAI,IAAI,QAAQ;AAAA,MACnF,CAAC;AAAA,IACH;AACA,WAAO;AAAA,EACT;AACF;","names":[]}