@remnic/core 10.0.37 → 10.0.39

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 (440) hide show
  1. package/dist/access-admin-ops-surface.js +76 -76
  2. package/dist/access-audit.js +2 -2
  3. package/dist/access-authorization-probe.js +77 -77
  4. package/dist/access-boundary.js +76 -76
  5. package/dist/access-citation-namespace.js +2 -2
  6. package/dist/access-cli.js +165 -164
  7. package/dist/access-cli.js.map +1 -1
  8. package/dist/access-extraction-force-flush.js +76 -76
  9. package/dist/access-http-briefing.js +77 -77
  10. package/dist/access-http-query.js +78 -78
  11. package/dist/access-http.js +101 -101
  12. package/dist/access-identity-continuity-surface.js +76 -76
  13. package/dist/access-lcm-surface.js +76 -76
  14. package/dist/access-mcp.js +90 -90
  15. package/dist/access-namespace-preflight.js +76 -76
  16. package/dist/access-observe-write-category.js +15 -15
  17. package/dist/access-observe-write-surface.js +76 -76
  18. package/dist/access-offline-manifest.js +12 -12
  19. package/dist/access-operations-batch.js +80 -80
  20. package/dist/access-operations.js +87 -87
  21. package/dist/access-recall-concurrency.js +76 -76
  22. package/dist/access-recall-diagnostics.js +2 -2
  23. package/dist/access-recall-response.js +76 -76
  24. package/dist/access-recall-surface.js +76 -76
  25. package/dist/access-schema.js +10 -10
  26. package/dist/access-service.js +76 -76
  27. package/dist/access-surface-catalog.js +78 -78
  28. package/dist/active-recall.js +31 -31
  29. package/dist/adapters/index.js +4 -4
  30. package/dist/adapters/registry.js +2 -2
  31. package/dist/{auto-sync-R3XGJL5I.js → auto-sync-BNCBMU6H.js} +9 -9
  32. package/dist/briefing.js +21 -21
  33. package/dist/buffer-types.d.ts +59 -0
  34. package/dist/buffer-types.d.ts.map +1 -0
  35. package/dist/buffer-types.js +1 -0
  36. package/dist/buffer.d.ts +14 -22
  37. package/dist/buffer.d.ts.map +1 -1
  38. package/dist/buffer.js +11 -11
  39. package/dist/calibration.js +3 -3
  40. package/dist/{capsule-crypto-7FJQINUR.js → capsule-crypto-GWVG7LGC.js} +2 -2
  41. package/dist/causal-behavior.js +2 -2
  42. package/dist/causal-chain.js +2 -2
  43. package/dist/causal-consolidation.js +24 -24
  44. package/dist/causal-retrieval.js +2 -2
  45. package/dist/causal-trajectory-graph.js +2 -2
  46. package/dist/causal-trajectory.js +1 -1
  47. package/dist/{chunk-MH3LC7KB.js → chunk-22YJQTPN.js} +2 -2
  48. package/dist/{chunk-MKE5DP3S.js → chunk-23ZMQONL.js} +2 -2
  49. package/dist/{chunk-MGXFJOUR.js → chunk-2AV2U2SZ.js} +4 -4
  50. package/dist/{chunk-HJ3UTGIW.js → chunk-2JNBPOZ2.js} +3 -3
  51. package/dist/{chunk-EEOYF3IB.js → chunk-3RJDYZJE.js} +2 -2
  52. package/dist/{chunk-FBAHBFT5.js → chunk-4HJ2QK32.js} +2 -2
  53. package/dist/{chunk-UXXVOA4D.js → chunk-4LLV2N3R.js} +3 -3
  54. package/dist/{chunk-P5CUEB2Q.js → chunk-4QLKVZH6.js} +8 -8
  55. package/dist/{chunk-2RJO7VS4.js → chunk-4UT2NUAC.js} +2 -2
  56. package/dist/{chunk-R6TCM47S.js → chunk-5KZNWERU.js} +156 -143
  57. package/dist/chunk-5KZNWERU.js.map +1 -0
  58. package/dist/{chunk-MNDHKZZQ.js → chunk-5Q6CR65T.js} +2 -2
  59. package/dist/{chunk-XTBEXZFN.js → chunk-5SF7JOJB.js} +4 -4
  60. package/dist/{chunk-BQ6DGL6A.js → chunk-64WHWIPL.js} +2 -2
  61. package/dist/{chunk-TVIGN3XZ.js → chunk-6FRFVIKC.js} +10 -10
  62. package/dist/{chunk-A23DPFFI.js → chunk-6ITNEPJO.js} +2 -2
  63. package/dist/{chunk-UFBIOF7C.js → chunk-6X3J4NLZ.js} +10 -5
  64. package/dist/chunk-6X3J4NLZ.js.map +1 -0
  65. package/dist/{chunk-G6PPA4TH.js → chunk-6Z2ZWBOV.js} +6 -6
  66. package/dist/{chunk-QEGE5QCL.js → chunk-7IANFJ24.js} +58 -58
  67. package/dist/{chunk-PSQ2P2T3.js → chunk-7XZ7TOLQ.js} +3 -3
  68. package/dist/{chunk-Z5AQZRHF.js → chunk-AER3HD3B.js} +2 -2
  69. package/dist/{chunk-BPBUUGAO.js → chunk-ANV373S5.js} +2 -2
  70. package/dist/{chunk-GMMZ45C4.js → chunk-AVVCPA7U.js} +6 -8
  71. package/dist/chunk-AVVCPA7U.js.map +1 -0
  72. package/dist/{chunk-LSSCMZQ2.js → chunk-B3I2QQU7.js} +3 -3
  73. package/dist/{chunk-NSQSOLCE.js → chunk-B7VKRCAG.js} +2 -2
  74. package/dist/{chunk-HXFIILGF.js → chunk-BFPF5N3H.js} +4 -4
  75. package/dist/{chunk-KQAFEZQX.js → chunk-BUKK5SWA.js} +2 -2
  76. package/dist/{chunk-RBC4GIZU.js → chunk-BUKZ7MTN.js} +2 -2
  77. package/dist/{chunk-FO5AFCRI.js → chunk-CR72WZ3M.js} +9 -9
  78. package/dist/{chunk-YC2C67F7.js → chunk-CRXGQRNA.js} +3 -3
  79. package/dist/{chunk-WRDFYSUC.js → chunk-CZVNOTLR.js} +2 -2
  80. package/dist/{chunk-VPO53QMG.js → chunk-D6DOLQYK.js} +2 -2
  81. package/dist/{chunk-HRT2SJPC.js → chunk-E3NBMTTX.js} +2 -2
  82. package/dist/{chunk-HIMXDRSQ.js → chunk-E5IEI2MR.js} +2 -2
  83. package/dist/{chunk-Z2T5BPOZ.js → chunk-EIYJK7OD.js} +2 -2
  84. package/dist/{chunk-FRAL3EU4.js → chunk-EKPRLTAE.js} +2 -2
  85. package/dist/{chunk-EVVCE7S2.js → chunk-EKR6OO4P.js} +2 -2
  86. package/dist/{chunk-TYGLV6ZG.js → chunk-EYGOM6AI.js} +2 -2
  87. package/dist/{chunk-TYGLV6ZG.js.map → chunk-EYGOM6AI.js.map} +1 -1
  88. package/dist/{chunk-6R6CU3MR.js → chunk-F2IU6A2L.js} +57 -57
  89. package/dist/{chunk-FL6SLVAJ.js → chunk-FAKRTS3Y.js} +3 -3
  90. package/dist/{chunk-64IO6ZEE.js → chunk-FC3ZFEXF.js} +2 -2
  91. package/dist/{chunk-YGYT7S3G.js → chunk-FJ264QBP.js} +31 -9
  92. package/dist/chunk-FJ264QBP.js.map +1 -0
  93. package/dist/{chunk-DGBWPSM6.js → chunk-FLDXEJFX.js} +2 -2
  94. package/dist/{chunk-JH4FCVWJ.js → chunk-G6OFEGUR.js} +2 -2
  95. package/dist/{chunk-Z5QWUR3Y.js → chunk-GCW7UT5I.js} +2 -2
  96. package/dist/{chunk-ULUX6Q7R.js → chunk-GE5ZNDLE.js} +4 -4
  97. package/dist/{chunk-U4JXQCJ3.js → chunk-GLB6VV3J.js} +2 -2
  98. package/dist/{chunk-RWWYBE7E.js → chunk-GPVGAHXL.js} +3 -3
  99. package/dist/{chunk-3BPMYMPX.js → chunk-GSBSGT43.js} +2 -2
  100. package/dist/{chunk-645WOU5I.js → chunk-H7BZBSP6.js} +4 -4
  101. package/dist/{chunk-GFYFKXWZ.js → chunk-HUDPXTXW.js} +2 -2
  102. package/dist/{chunk-L2JQSG5M.js → chunk-I7TR2OCU.js} +2 -2
  103. package/dist/{chunk-HKEK27M4.js → chunk-IAOW2L6K.js} +2 -2
  104. package/dist/{chunk-STM4T335.js → chunk-IJH6METJ.js} +2 -2
  105. package/dist/{chunk-WADPRAZE.js → chunk-IZRNMXZC.js} +2 -2
  106. package/dist/{chunk-JWTUJVIF.js → chunk-JGS55BAS.js} +53 -2
  107. package/dist/chunk-JGS55BAS.js.map +1 -0
  108. package/dist/{chunk-LAQS5HYU.js → chunk-JM6U3SAE.js} +2 -2
  109. package/dist/{chunk-74AY3S7U.js → chunk-JNLYHJG7.js} +4 -4
  110. package/dist/{chunk-7ZBANI3M.js → chunk-JOOGPZJE.js} +2 -2
  111. package/dist/{chunk-V5RJCXLG.js → chunk-JORSMFL6.js} +6 -6
  112. package/dist/{chunk-VKTP3TZB.js → chunk-JQCP5QW3.js} +4 -4
  113. package/dist/{chunk-LRJKHXU4.js → chunk-JRTKYFFY.js} +2 -2
  114. package/dist/{chunk-UMFBHYPW.js → chunk-JT3IXJIL.js} +13 -13
  115. package/dist/{chunk-S53WZWGL.js → chunk-JZFJZLJY.js} +2 -2
  116. package/dist/{chunk-6QOL4G76.js → chunk-KQXRVELF.js} +2 -2
  117. package/dist/{chunk-USOXPN5H.js → chunk-L74NWAD4.js} +2 -2
  118. package/dist/{chunk-Y6Y3TRBN.js → chunk-LJXBFVI2.js} +4 -4
  119. package/dist/{chunk-3L5WH6CV.js → chunk-LPD6I2U6.js} +2 -2
  120. package/dist/{chunk-LDXS746V.js → chunk-LR7RW4T6.js} +3 -3
  121. package/dist/{chunk-FZVZYU5C.js → chunk-LXN737FX.js} +2 -2
  122. package/dist/{chunk-5U3NUHMA.js → chunk-MD3W2H3G.js} +301 -98
  123. package/dist/chunk-MD3W2H3G.js.map +1 -0
  124. package/dist/{chunk-ARFT6ZBE.js → chunk-MGYZENUY.js} +2 -2
  125. package/dist/{chunk-YQ6SLFNZ.js → chunk-MPJDQC4G.js} +3 -3
  126. package/dist/{chunk-5UWP5X3T.js → chunk-NJ2DZYEK.js} +2 -2
  127. package/dist/{chunk-MBMT5FUQ.js → chunk-O2O4FDAH.js} +2 -2
  128. package/dist/{chunk-GCVUBVEN.js → chunk-ODJ2HRFW.js} +10 -10
  129. package/dist/{chunk-2NLLXCJG.js → chunk-OWHERGF2.js} +2 -2
  130. package/dist/{chunk-I73ZSORJ.js → chunk-OXSTKCYK.js} +4 -4
  131. package/dist/{chunk-CNQQNYJ2.js → chunk-P3YUEPSQ.js} +2 -2
  132. package/dist/{chunk-A6PKEU7T.js → chunk-PARM6OYL.js} +1 -1
  133. package/dist/chunk-PARM6OYL.js.map +1 -0
  134. package/dist/{chunk-TPKB7T6Z.js → chunk-Q6UZREJK.js} +2 -2
  135. package/dist/{chunk-UJDTXWMT.js → chunk-QIMGULGN.js} +2 -2
  136. package/dist/{chunk-E24RUQEN.js → chunk-QNIYL5SK.js} +2 -2
  137. package/dist/{chunk-KOY25HUB.js → chunk-QYAXMXOB.js} +2 -2
  138. package/dist/{chunk-CU7WDDPV.js → chunk-RIAKNXZB.js} +4 -4
  139. package/dist/{chunk-UQWA5QDT.js → chunk-RO2NNWR5.js} +3 -3
  140. package/dist/{chunk-AYXRK264.js → chunk-RROFIAYI.js} +9 -9
  141. package/dist/{chunk-L46Y5FPE.js → chunk-RUAIO5UA.js} +2 -2
  142. package/dist/{chunk-QIC7YZ3D.js → chunk-RWW5KPIY.js} +18 -18
  143. package/dist/{chunk-E5PVMB3I.js → chunk-SDXBR5QO.js} +2 -2
  144. package/dist/{chunk-WSLNC5AL.js → chunk-SJHFU52W.js} +8 -8
  145. package/dist/{chunk-7PG7QBWD.js → chunk-SRPGA6WN.js} +2 -2
  146. package/dist/{chunk-CUWOSRCS.js → chunk-SUKPM6DV.js} +2 -2
  147. package/dist/{chunk-BBDASWNT.js → chunk-TJ5YGCPV.js} +81 -76
  148. package/dist/chunk-TJ5YGCPV.js.map +1 -0
  149. package/dist/{chunk-G2SRB62M.js → chunk-TTQYX7VU.js} +2 -2
  150. package/dist/{chunk-TDCR6PQL.js → chunk-TWRPWJJT.js} +2 -2
  151. package/dist/{chunk-KC5SVCUJ.js → chunk-U66CTIF5.js} +2 -2
  152. package/dist/{chunk-D2AKUKAQ.js → chunk-UIK3U36O.js} +2 -2
  153. package/dist/{chunk-XLEP7SS3.js → chunk-UMSH4I3E.js} +2 -2
  154. package/dist/{chunk-X7Y7WX73.js → chunk-UVYI6VIX.js} +1 -1
  155. package/dist/{chunk-LHBOFROT.js → chunk-V2XMG7GM.js} +2 -2
  156. package/dist/chunk-VA3GNAWQ.js +58 -0
  157. package/dist/chunk-VA3GNAWQ.js.map +1 -0
  158. package/dist/{chunk-NQOM6PHO.js → chunk-VCOCOBUS.js} +6 -6
  159. package/dist/{chunk-4P4VLPGB.js → chunk-VECRSYQG.js} +1 -1
  160. package/dist/{chunk-ID2PLENW.js → chunk-VHBGJAYC.js} +2 -2
  161. package/dist/{chunk-RVYXSS3Q.js → chunk-VIS23B6O.js} +8 -8
  162. package/dist/{chunk-NMKETOAX.js → chunk-VSHWPOUB.js} +2 -2
  163. package/dist/{chunk-UBN5AOLT.js → chunk-W5EO4USJ.js} +2 -2
  164. package/dist/{chunk-Y7427SL7.js → chunk-WCGJK4NQ.js} +4 -4
  165. package/dist/{chunk-CCYXCT4B.js → chunk-WQYS47G4.js} +2 -2
  166. package/dist/{chunk-JH2ALMPR.js → chunk-WR5POHQ3.js} +2 -2
  167. package/dist/{chunk-DK5VMJL3.js → chunk-WT2VVYBM.js} +2 -2
  168. package/dist/{chunk-EHIKY2IA.js → chunk-WU5WTCH5.js} +2 -2
  169. package/dist/{chunk-QKXPOLQD.js → chunk-WUBGMV3G.js} +6 -6
  170. package/dist/{chunk-O6YJI5VX.js → chunk-WUL6LDJ4.js} +2 -2
  171. package/dist/{chunk-5EILJ6W2.js → chunk-WXPBDEMW.js} +2 -2
  172. package/dist/{chunk-U7HJBODU.js → chunk-XKTHJHSQ.js} +5 -5
  173. package/dist/{chunk-JFI3ATK4.js → chunk-XMYWYJM2.js} +2 -2
  174. package/dist/{chunk-64S6X4IU.js → chunk-XTN54NML.js} +4 -4
  175. package/dist/{chunk-VGFNTY3Y.js → chunk-YFXRLRKP.js} +2 -2
  176. package/dist/{chunk-DAOMWGO2.js → chunk-ZX5N5D6M.js} +4 -4
  177. package/dist/{chunk-PTRPOJ7U.js → chunk-ZXFKG7VZ.js} +2 -2
  178. package/dist/cli.js +124 -124
  179. package/dist/coding/export-okf-codegraph.js +22 -22
  180. package/dist/coding/pre-action-gate.js +2 -2
  181. package/dist/compounding/engine.js +23 -23
  182. package/dist/config.d.ts.map +1 -1
  183. package/dist/config.js +31 -31
  184. package/dist/connectors/codex-materialize-runner.js +21 -21
  185. package/dist/connectors/index.js +21 -21
  186. package/dist/contradiction/index.js +5 -5
  187. package/dist/convergence-refresh.js +23 -23
  188. package/dist/corpus-watermark.js +23 -23
  189. package/dist/deep-recall-http-glue.js +11 -11
  190. package/dist/deep-recall-policy-llm.js +2 -2
  191. package/dist/deep-recall.js +2 -2
  192. package/dist/entity-retrieval.js +22 -22
  193. package/dist/event-order-recall.js +2 -2
  194. package/dist/explicit-capture.js +6 -6
  195. package/dist/external-wiki-access.js +77 -77
  196. package/dist/extraction-faithfulness.js +2 -2
  197. package/dist/extraction-judge.d.ts +42 -2
  198. package/dist/extraction-judge.d.ts.map +1 -1
  199. package/dist/extraction-judge.js +12 -2
  200. package/dist/extraction-window-drain.d.ts +48 -0
  201. package/dist/extraction-window-drain.d.ts.map +1 -0
  202. package/dist/extraction-window-drain.js +14 -0
  203. package/dist/extraction.js +29 -29
  204. package/dist/fallback-llm.d.ts +1 -0
  205. package/dist/fallback-llm.d.ts.map +1 -1
  206. package/dist/fallback-llm.js +1 -1
  207. package/dist/{graph-edge-decay-2BZTY2IM.js → graph-edge-decay-3HVLMT6U.js} +5 -5
  208. package/dist/graph-edge-decay-3HVLMT6U.js.map +1 -0
  209. package/dist/graph-jsonl.js +3 -3
  210. package/dist/graph-snapshot.js +3 -3
  211. package/dist/graph.js +4 -4
  212. package/dist/harmonic-retrieval.js +22 -22
  213. package/dist/harmonic-source-lookup.js +2 -2
  214. package/dist/index.js +212 -211
  215. package/dist/lcm/engine.js +2 -2
  216. package/dist/lcm/index.js +7 -7
  217. package/dist/local-llm.js +2 -2
  218. package/dist/location/index.js +24 -24
  219. package/dist/maintenance/memory-governance.js +21 -21
  220. package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +21 -21
  221. package/dist/maintenance/rebuild-memory-projection-runner.js +23 -23
  222. package/dist/maintenance/rebuild-memory-projection.js +22 -22
  223. package/dist/memory-browse-operations.js +77 -77
  224. package/dist/memory-browse.js +6 -6
  225. package/dist/memory-subject.js +3 -3
  226. package/dist/namespaces/migrate.js +22 -22
  227. package/dist/namespaces/search.js +7 -7
  228. package/dist/namespaces/storage.js +21 -21
  229. package/dist/offline-sync-changeset-generations.js +3 -3
  230. package/dist/offline-sync-embedding-generation.js +2 -2
  231. package/dist/offline-sync-file-io.js +2 -2
  232. package/dist/offline-sync-impression-drain.js +3 -3
  233. package/dist/offline-sync-snapshot-stream.js +8 -8
  234. package/dist/offline-sync-upload-staging.js +3 -3
  235. package/dist/offline-sync.js +9 -9
  236. package/dist/operator-doctor-corpus.js +24 -24
  237. package/dist/operator-toolkit.js +42 -42
  238. package/dist/orchestration/extraction-drain.d.ts +90 -0
  239. package/dist/orchestration/extraction-drain.d.ts.map +1 -0
  240. package/dist/orchestration/extraction-run-helpers.d.ts +3 -0
  241. package/dist/orchestration/extraction-run-helpers.d.ts.map +1 -1
  242. package/dist/orchestration/extraction-run.d.ts +4 -1
  243. package/dist/orchestration/extraction-run.d.ts.map +1 -1
  244. package/dist/orchestration/maintenance.js +35 -35
  245. package/dist/orchestration/turn-ingestion.d.ts +3 -0
  246. package/dist/orchestration/turn-ingestion.d.ts.map +1 -1
  247. package/dist/orchestrator.d.ts +8 -0
  248. package/dist/orchestrator.d.ts.map +1 -1
  249. package/dist/orchestrator.js +165 -164
  250. package/dist/qmd.js +5 -5
  251. package/dist/recall-explain-renderer.js +3 -3
  252. package/dist/recall-navigate-access.js +2 -2
  253. package/dist/recall-navigate-disclosure.js +2 -2
  254. package/dist/recall-navigate.js +2 -2
  255. package/dist/recall-navigation-operations.js +77 -77
  256. package/dist/recall-navigation.js +76 -76
  257. package/dist/recall-planner-llm.js +1 -1
  258. package/dist/recall-state-view-admission.js +6 -6
  259. package/dist/recall-why-service.js +6 -6
  260. package/dist/recall-xray-cli.js +4 -4
  261. package/dist/recall-xray-renderer.js +3 -3
  262. package/dist/recall-xray.js +2 -2
  263. package/dist/reconcile/manifest.js +3 -3
  264. package/dist/{resolution-4ZEQPXUZ.js → resolution-NNYG37YB.js} +6 -6
  265. package/dist/resolution-NNYG37YB.js.map +1 -0
  266. package/dist/resume-bundles.js +32 -32
  267. package/dist/retrieval-agents.js +2 -2
  268. package/dist/salvage-envelope.js +5 -5
  269. package/dist/search/factory.js +6 -6
  270. package/dist/search/index.js +10 -10
  271. package/dist/secure-store/index.js +2 -2
  272. package/dist/semantic-consolidation.js +22 -22
  273. package/dist/semantic-rule-promotion.js +21 -21
  274. package/dist/semantic-rule-verifier.js +21 -21
  275. package/dist/source-agent-qualifier.js +25 -25
  276. package/dist/standup/build.js +21 -21
  277. package/dist/storage/dropped-extraction-chunk.d.ts +8 -0
  278. package/dist/storage/dropped-extraction-chunk.d.ts.map +1 -0
  279. package/dist/storage.d.ts +1 -0
  280. package/dist/storage.d.ts.map +1 -1
  281. package/dist/storage.js +20 -20
  282. package/dist/subject-config.js +4 -4
  283. package/dist/summarizer.js +4 -4
  284. package/dist/support-passport/index.js +79 -79
  285. package/dist/transfer/backup.js +2 -2
  286. package/dist/transfer/capsule-export.js +2 -2
  287. package/dist/transfer/capsule-import.js +2 -2
  288. package/dist/transfer/export-okf.js +22 -22
  289. package/dist/types.d.ts +19 -0
  290. package/dist/types.d.ts.map +1 -1
  291. package/dist/types.js +1 -1
  292. package/dist/verified-recall.js +21 -21
  293. package/dist/who-knows-cli.js +22 -22
  294. package/dist/who-knows.js +21 -21
  295. package/dist/write-envelope.js +4 -4
  296. package/package.json +2 -2
  297. package/src/buffer-drop-extraction-chunk.test.ts +196 -0
  298. package/src/buffer-types.ts +65 -0
  299. package/src/buffer.ts +60 -62
  300. package/src/config.test.ts +16 -0
  301. package/src/config.ts +22 -0
  302. package/src/extraction-judge-chain.test.ts +298 -2
  303. package/src/extraction-judge.ts +147 -82
  304. package/src/extraction-window-drain.test.ts +123 -0
  305. package/src/extraction-window-drain.ts +110 -0
  306. package/src/fallback-llm.test.ts +94 -0
  307. package/src/fallback-llm.ts +7 -7
  308. package/src/orchestration/extraction-drain.ts +261 -0
  309. package/src/orchestration/extraction-run-helpers.ts +8 -0
  310. package/src/orchestration/extraction-run.ts +5 -4
  311. package/src/orchestration/turn-ingestion.ts +9 -5
  312. package/src/orchestrator.ts +21 -0
  313. package/src/secure-store/secure-fs.ts +3 -1
  314. package/src/storage/dropped-extraction-chunk.ts +27 -0
  315. package/src/storage-dropped-chunk-filenames.test.ts +30 -0
  316. package/src/storage.ts +6 -7
  317. package/src/types.ts +19 -0
  318. package/dist/chunk-5U3NUHMA.js.map +0 -1
  319. package/dist/chunk-A6PKEU7T.js.map +0 -1
  320. package/dist/chunk-BBDASWNT.js.map +0 -1
  321. package/dist/chunk-GMMZ45C4.js.map +0 -1
  322. package/dist/chunk-JWTUJVIF.js.map +0 -1
  323. package/dist/chunk-R6TCM47S.js.map +0 -1
  324. package/dist/chunk-UFBIOF7C.js.map +0 -1
  325. package/dist/chunk-YGYT7S3G.js.map +0 -1
  326. /package/dist/{auto-sync-R3XGJL5I.js.map → auto-sync-BNCBMU6H.js.map} +0 -0
  327. /package/dist/{capsule-crypto-7FJQINUR.js.map → buffer-types.js.map} +0 -0
  328. /package/dist/{graph-edge-decay-2BZTY2IM.js.map → capsule-crypto-GWVG7LGC.js.map} +0 -0
  329. /package/dist/{chunk-MH3LC7KB.js.map → chunk-22YJQTPN.js.map} +0 -0
  330. /package/dist/{chunk-MKE5DP3S.js.map → chunk-23ZMQONL.js.map} +0 -0
  331. /package/dist/{chunk-MGXFJOUR.js.map → chunk-2AV2U2SZ.js.map} +0 -0
  332. /package/dist/{chunk-HJ3UTGIW.js.map → chunk-2JNBPOZ2.js.map} +0 -0
  333. /package/dist/{chunk-EEOYF3IB.js.map → chunk-3RJDYZJE.js.map} +0 -0
  334. /package/dist/{chunk-FBAHBFT5.js.map → chunk-4HJ2QK32.js.map} +0 -0
  335. /package/dist/{chunk-UXXVOA4D.js.map → chunk-4LLV2N3R.js.map} +0 -0
  336. /package/dist/{chunk-P5CUEB2Q.js.map → chunk-4QLKVZH6.js.map} +0 -0
  337. /package/dist/{chunk-2RJO7VS4.js.map → chunk-4UT2NUAC.js.map} +0 -0
  338. /package/dist/{chunk-MNDHKZZQ.js.map → chunk-5Q6CR65T.js.map} +0 -0
  339. /package/dist/{chunk-XTBEXZFN.js.map → chunk-5SF7JOJB.js.map} +0 -0
  340. /package/dist/{chunk-BQ6DGL6A.js.map → chunk-64WHWIPL.js.map} +0 -0
  341. /package/dist/{chunk-TVIGN3XZ.js.map → chunk-6FRFVIKC.js.map} +0 -0
  342. /package/dist/{chunk-A23DPFFI.js.map → chunk-6ITNEPJO.js.map} +0 -0
  343. /package/dist/{chunk-G6PPA4TH.js.map → chunk-6Z2ZWBOV.js.map} +0 -0
  344. /package/dist/{chunk-QEGE5QCL.js.map → chunk-7IANFJ24.js.map} +0 -0
  345. /package/dist/{chunk-PSQ2P2T3.js.map → chunk-7XZ7TOLQ.js.map} +0 -0
  346. /package/dist/{chunk-Z5AQZRHF.js.map → chunk-AER3HD3B.js.map} +0 -0
  347. /package/dist/{chunk-BPBUUGAO.js.map → chunk-ANV373S5.js.map} +0 -0
  348. /package/dist/{chunk-LSSCMZQ2.js.map → chunk-B3I2QQU7.js.map} +0 -0
  349. /package/dist/{chunk-NSQSOLCE.js.map → chunk-B7VKRCAG.js.map} +0 -0
  350. /package/dist/{chunk-HXFIILGF.js.map → chunk-BFPF5N3H.js.map} +0 -0
  351. /package/dist/{chunk-KQAFEZQX.js.map → chunk-BUKK5SWA.js.map} +0 -0
  352. /package/dist/{chunk-RBC4GIZU.js.map → chunk-BUKZ7MTN.js.map} +0 -0
  353. /package/dist/{chunk-FO5AFCRI.js.map → chunk-CR72WZ3M.js.map} +0 -0
  354. /package/dist/{chunk-YC2C67F7.js.map → chunk-CRXGQRNA.js.map} +0 -0
  355. /package/dist/{chunk-WRDFYSUC.js.map → chunk-CZVNOTLR.js.map} +0 -0
  356. /package/dist/{chunk-VPO53QMG.js.map → chunk-D6DOLQYK.js.map} +0 -0
  357. /package/dist/{chunk-HRT2SJPC.js.map → chunk-E3NBMTTX.js.map} +0 -0
  358. /package/dist/{chunk-HIMXDRSQ.js.map → chunk-E5IEI2MR.js.map} +0 -0
  359. /package/dist/{chunk-Z2T5BPOZ.js.map → chunk-EIYJK7OD.js.map} +0 -0
  360. /package/dist/{chunk-FRAL3EU4.js.map → chunk-EKPRLTAE.js.map} +0 -0
  361. /package/dist/{chunk-EVVCE7S2.js.map → chunk-EKR6OO4P.js.map} +0 -0
  362. /package/dist/{chunk-6R6CU3MR.js.map → chunk-F2IU6A2L.js.map} +0 -0
  363. /package/dist/{chunk-FL6SLVAJ.js.map → chunk-FAKRTS3Y.js.map} +0 -0
  364. /package/dist/{chunk-64IO6ZEE.js.map → chunk-FC3ZFEXF.js.map} +0 -0
  365. /package/dist/{chunk-DGBWPSM6.js.map → chunk-FLDXEJFX.js.map} +0 -0
  366. /package/dist/{chunk-JH4FCVWJ.js.map → chunk-G6OFEGUR.js.map} +0 -0
  367. /package/dist/{chunk-Z5QWUR3Y.js.map → chunk-GCW7UT5I.js.map} +0 -0
  368. /package/dist/{chunk-ULUX6Q7R.js.map → chunk-GE5ZNDLE.js.map} +0 -0
  369. /package/dist/{chunk-U4JXQCJ3.js.map → chunk-GLB6VV3J.js.map} +0 -0
  370. /package/dist/{chunk-RWWYBE7E.js.map → chunk-GPVGAHXL.js.map} +0 -0
  371. /package/dist/{chunk-3BPMYMPX.js.map → chunk-GSBSGT43.js.map} +0 -0
  372. /package/dist/{chunk-645WOU5I.js.map → chunk-H7BZBSP6.js.map} +0 -0
  373. /package/dist/{chunk-GFYFKXWZ.js.map → chunk-HUDPXTXW.js.map} +0 -0
  374. /package/dist/{chunk-L2JQSG5M.js.map → chunk-I7TR2OCU.js.map} +0 -0
  375. /package/dist/{chunk-HKEK27M4.js.map → chunk-IAOW2L6K.js.map} +0 -0
  376. /package/dist/{chunk-STM4T335.js.map → chunk-IJH6METJ.js.map} +0 -0
  377. /package/dist/{chunk-WADPRAZE.js.map → chunk-IZRNMXZC.js.map} +0 -0
  378. /package/dist/{chunk-LAQS5HYU.js.map → chunk-JM6U3SAE.js.map} +0 -0
  379. /package/dist/{chunk-74AY3S7U.js.map → chunk-JNLYHJG7.js.map} +0 -0
  380. /package/dist/{chunk-7ZBANI3M.js.map → chunk-JOOGPZJE.js.map} +0 -0
  381. /package/dist/{chunk-V5RJCXLG.js.map → chunk-JORSMFL6.js.map} +0 -0
  382. /package/dist/{chunk-VKTP3TZB.js.map → chunk-JQCP5QW3.js.map} +0 -0
  383. /package/dist/{chunk-LRJKHXU4.js.map → chunk-JRTKYFFY.js.map} +0 -0
  384. /package/dist/{chunk-UMFBHYPW.js.map → chunk-JT3IXJIL.js.map} +0 -0
  385. /package/dist/{chunk-S53WZWGL.js.map → chunk-JZFJZLJY.js.map} +0 -0
  386. /package/dist/{chunk-6QOL4G76.js.map → chunk-KQXRVELF.js.map} +0 -0
  387. /package/dist/{chunk-USOXPN5H.js.map → chunk-L74NWAD4.js.map} +0 -0
  388. /package/dist/{chunk-Y6Y3TRBN.js.map → chunk-LJXBFVI2.js.map} +0 -0
  389. /package/dist/{chunk-3L5WH6CV.js.map → chunk-LPD6I2U6.js.map} +0 -0
  390. /package/dist/{chunk-LDXS746V.js.map → chunk-LR7RW4T6.js.map} +0 -0
  391. /package/dist/{chunk-FZVZYU5C.js.map → chunk-LXN737FX.js.map} +0 -0
  392. /package/dist/{chunk-ARFT6ZBE.js.map → chunk-MGYZENUY.js.map} +0 -0
  393. /package/dist/{chunk-YQ6SLFNZ.js.map → chunk-MPJDQC4G.js.map} +0 -0
  394. /package/dist/{chunk-5UWP5X3T.js.map → chunk-NJ2DZYEK.js.map} +0 -0
  395. /package/dist/{chunk-MBMT5FUQ.js.map → chunk-O2O4FDAH.js.map} +0 -0
  396. /package/dist/{chunk-GCVUBVEN.js.map → chunk-ODJ2HRFW.js.map} +0 -0
  397. /package/dist/{chunk-2NLLXCJG.js.map → chunk-OWHERGF2.js.map} +0 -0
  398. /package/dist/{chunk-I73ZSORJ.js.map → chunk-OXSTKCYK.js.map} +0 -0
  399. /package/dist/{chunk-CNQQNYJ2.js.map → chunk-P3YUEPSQ.js.map} +0 -0
  400. /package/dist/{chunk-TPKB7T6Z.js.map → chunk-Q6UZREJK.js.map} +0 -0
  401. /package/dist/{chunk-UJDTXWMT.js.map → chunk-QIMGULGN.js.map} +0 -0
  402. /package/dist/{chunk-E24RUQEN.js.map → chunk-QNIYL5SK.js.map} +0 -0
  403. /package/dist/{chunk-KOY25HUB.js.map → chunk-QYAXMXOB.js.map} +0 -0
  404. /package/dist/{chunk-CU7WDDPV.js.map → chunk-RIAKNXZB.js.map} +0 -0
  405. /package/dist/{chunk-UQWA5QDT.js.map → chunk-RO2NNWR5.js.map} +0 -0
  406. /package/dist/{chunk-AYXRK264.js.map → chunk-RROFIAYI.js.map} +0 -0
  407. /package/dist/{chunk-L46Y5FPE.js.map → chunk-RUAIO5UA.js.map} +0 -0
  408. /package/dist/{chunk-QIC7YZ3D.js.map → chunk-RWW5KPIY.js.map} +0 -0
  409. /package/dist/{chunk-E5PVMB3I.js.map → chunk-SDXBR5QO.js.map} +0 -0
  410. /package/dist/{chunk-WSLNC5AL.js.map → chunk-SJHFU52W.js.map} +0 -0
  411. /package/dist/{chunk-7PG7QBWD.js.map → chunk-SRPGA6WN.js.map} +0 -0
  412. /package/dist/{chunk-CUWOSRCS.js.map → chunk-SUKPM6DV.js.map} +0 -0
  413. /package/dist/{chunk-G2SRB62M.js.map → chunk-TTQYX7VU.js.map} +0 -0
  414. /package/dist/{chunk-TDCR6PQL.js.map → chunk-TWRPWJJT.js.map} +0 -0
  415. /package/dist/{chunk-KC5SVCUJ.js.map → chunk-U66CTIF5.js.map} +0 -0
  416. /package/dist/{chunk-D2AKUKAQ.js.map → chunk-UIK3U36O.js.map} +0 -0
  417. /package/dist/{chunk-XLEP7SS3.js.map → chunk-UMSH4I3E.js.map} +0 -0
  418. /package/dist/{chunk-X7Y7WX73.js.map → chunk-UVYI6VIX.js.map} +0 -0
  419. /package/dist/{chunk-LHBOFROT.js.map → chunk-V2XMG7GM.js.map} +0 -0
  420. /package/dist/{chunk-NQOM6PHO.js.map → chunk-VCOCOBUS.js.map} +0 -0
  421. /package/dist/{chunk-4P4VLPGB.js.map → chunk-VECRSYQG.js.map} +0 -0
  422. /package/dist/{chunk-ID2PLENW.js.map → chunk-VHBGJAYC.js.map} +0 -0
  423. /package/dist/{chunk-RVYXSS3Q.js.map → chunk-VIS23B6O.js.map} +0 -0
  424. /package/dist/{chunk-NMKETOAX.js.map → chunk-VSHWPOUB.js.map} +0 -0
  425. /package/dist/{chunk-UBN5AOLT.js.map → chunk-W5EO4USJ.js.map} +0 -0
  426. /package/dist/{chunk-Y7427SL7.js.map → chunk-WCGJK4NQ.js.map} +0 -0
  427. /package/dist/{chunk-CCYXCT4B.js.map → chunk-WQYS47G4.js.map} +0 -0
  428. /package/dist/{chunk-JH2ALMPR.js.map → chunk-WR5POHQ3.js.map} +0 -0
  429. /package/dist/{chunk-DK5VMJL3.js.map → chunk-WT2VVYBM.js.map} +0 -0
  430. /package/dist/{chunk-EHIKY2IA.js.map → chunk-WU5WTCH5.js.map} +0 -0
  431. /package/dist/{chunk-QKXPOLQD.js.map → chunk-WUBGMV3G.js.map} +0 -0
  432. /package/dist/{chunk-O6YJI5VX.js.map → chunk-WUL6LDJ4.js.map} +0 -0
  433. /package/dist/{chunk-5EILJ6W2.js.map → chunk-WXPBDEMW.js.map} +0 -0
  434. /package/dist/{chunk-U7HJBODU.js.map → chunk-XKTHJHSQ.js.map} +0 -0
  435. /package/dist/{chunk-JFI3ATK4.js.map → chunk-XMYWYJM2.js.map} +0 -0
  436. /package/dist/{chunk-64S6X4IU.js.map → chunk-XTN54NML.js.map} +0 -0
  437. /package/dist/{chunk-VGFNTY3Y.js.map → chunk-YFXRLRKP.js.map} +0 -0
  438. /package/dist/{chunk-DAOMWGO2.js.map → chunk-ZX5N5D6M.js.map} +0 -0
  439. /package/dist/{chunk-PTRPOJ7U.js.map → chunk-ZXFKG7VZ.js.map} +0 -0
  440. /package/dist/{resolution-4ZEQPXUZ.js.map → extraction-window-drain.js.map} +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/fallback-llm.ts"],"sourcesContent":["import { log } from \"./logger.js\";\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} from \"./resolve-provider-secret.js\";\nimport {\n CODEX_SUBSCRIPTION_PROVIDER_ID,\n codexSubscriptionBuiltinProviderConfig,\n} from \"./providers/codex-subscription.js\";\nimport { loadModelsJsonProviders } from \"./models-json.js\";\nimport {\n abortReason,\n classifyThrownProviderError,\n codexDeadlineHeadroomMs,\n defaultOpenClawWorkspaceDir,\n extractResponsesOutputText,\n fallbackLlmRuntimeContextFromConfig,\n isTerminalCodexSubscriptionError,\n isTimeoutError,\n isUnsupportedJsonSchemaError,\n normalizeRuntimePath,\n raceFallbackLlmDeadline,\n readGatewayWorkspaceDir,\n tryCodexSubscriptionProvider,\n withCodexRuntimeShutdown,\n type FallbackLlmRuntimeContext,\n type StructuredParseFailure,\n type StructuredParseResult,\n} from \"./fallback-llm-codex-subscription.js\";\n\nexport {\n fallbackLlmRuntimeContextFromConfig,\n type FallbackLlmRuntimeContext,\n type StructuredParseFailure,\n type StructuredParseFailureReason,\n type StructuredParseResult,\n} from \"./fallback-llm-codex-subscription.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 * Optional out-box for the terminal failure cause (issue #2891): when every\n * model in the chain fails, the last thrown provider error is recorded here\n * so callers can classify it (e.g. HTTP 429 → rate-limited) in memory\n * instead of seeing only null. Never logged.\n */\n failureDiag?: { lastError?: unknown };\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\ntype ChatCompletionOutcome =\n | { ok: true; response: FallbackLlmResponse }\n | { ok: false; failure: Omit<StructuredParseFailure, \"result\"> };\n\ninterface ModelRef {\n providerId: string;\n modelId: string;\n providerConfig: ModelProviderConfig;\n modelString: string;\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/** Built-in OAuth/managed-auth providers so resolveProviderConfig reaches runtime auth. */\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 * Gateway/task LLM client. In `modelSource: \"gateway\"` this is the primary\n * configured path (taskModelChain / agent persona), not a secondary recovery\n * client. The class name stays `FallbackLlmClient` because it is imported\n * widely; prefer the `TaskLlmClient` alias in new code. Issue #2967.\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 outcome = await this.completeChat(messages, options);\n return outcome.ok ? outcome.response : null;\n }\n\n /**\n * Same transport walk as chatCompletion, but tagged so structured parse can\n * tell timeout / empty / HTTP error apart instead of collapsing them to null.\n */\n private async completeChat(\n messages: Array<{ role: \"system\" | \"user\" | \"assistant\"; content: string }>,\n options: FallbackLlmOptions = {},\n ): Promise<ChatCompletionOutcome> {\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(\"task LLM: no models configured in gateway\");\n return { ok: false, failure: { failureReason: \"no_models\", errorClass: \"no_models\" } };\n }\n options = withCodexRuntimeShutdown(options, this.runtimeContext.codexSubscriptionRunner);\n\n let lastFailure: Omit<StructuredParseFailure, \"result\"> = {\n failureReason: \"http_error\",\n errorClass: \"network\",\n };\n\n const recordFailure = (\n failure: Omit<StructuredParseFailure, \"result\">,\n attemptedModel?: string,\n ): void => {\n lastFailure = attemptedModel ? { ...failure, attemptedModel } : failure;\n };\n\n const throwIfCallerAborted = (signal: AbortSignal | undefined): void => {\n if (!signal?.aborted) return;\n const reason = abortReason(signal);\n if (isTimeoutError(reason) && !options.signal?.aborted) {\n recordFailure({ failureReason: \"timeout\", errorClass: \"timeout\" });\n return;\n }\n throw reason;\n };\n\n const runChain = async (\n initialOptions: FallbackLlmOptions,\n ): Promise<FallbackLlmResponse | null> => {\n let runOptions = initialOptions;\n let lastRejectedResponse: FallbackLlmResponse | null = null;\n let lastError: unknown;\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 throwIfCallerAborted(runOptions.signal);\n if (lastFailure.failureReason === \"timeout\") return null;\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?.content) {\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(`task LLM: ${model.modelString} returned rejected output, trying next...`);\n continue;\n }\n if (isFallback) {\n log.debug(`task LLM: succeeded using ${model.modelString} (fallback ${i})`);\n }\n return response;\n }\n recordFailure({ failureReason: \"empty\", errorClass: \"empty\" }, model.modelString);\n } catch (err) {\n if (isTerminalCodexSubscriptionError(err) && runOptions.signal?.aborted) {\n throw err;\n }\n if (runOptions.signal?.aborted) {\n throwIfCallerAborted(runOptions.signal);\n if (lastFailure.failureReason === \"timeout\") return null;\n }\n lastError = err;\n if (\n (runOptions.jsonSchema || runOptions.responsesJsonSchema) &&\n isUnsupportedJsonSchemaError(err)\n ) {\n log.debug(`task 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?.content) {\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(`task LLM: ${model.modelString} unstructured retry output rejected by acceptResponse, trying next model...`);\n continue;\n }\n recordFailure({ failureReason: \"empty\", errorClass: \"empty\" }, model.modelString);\n } catch (retryError) {\n if (isTerminalCodexSubscriptionError(retryError) && runOptions.signal?.aborted) {\n throw retryError;\n }\n if (runOptions.signal?.aborted) {\n throwIfCallerAborted(runOptions.signal);\n if (lastFailure.failureReason === \"timeout\") return null;\n }\n lastError = retryError;\n const retryClassified = classifyThrownProviderError(retryError);\n recordFailure(retryClassified, model.modelString);\n const retryErrorMsg = runOptions.redactProviderErrors\n ? \"provider error details redacted\"\n : retryError instanceof Error\n ? retryError.message\n : String(retryError);\n log.debug(\n `task LLM: ${model.modelString} unstructured retry failed (${retryErrorMsg})`,\n );\n if (isTerminalCodexSubscriptionError(retryError)) {\n terminalError = retryError;\n }\n }\n continue;\n }\n const classified = classifyThrownProviderError(err);\n recordFailure(classified, model.modelString);\n const errorMsg = runOptions.redactProviderErrors\n ? \"provider error details redacted\"\n : err instanceof Error\n ? err.message\n : String(err);\n log.debug(`task 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(`task LLM: all ${models.length} models in chain failed`);\n if (options.failureDiag && lastError !== undefined && !lastRejectedResponse) {\n options.failureDiag.lastError = lastError;\n }\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 const toOutcome = (response: FallbackLlmResponse | null): ChatCompletionOutcome => {\n if (response) return { ok: true, response };\n return { ok: false, failure: lastFailure };\n };\n\n if (typeof options.timeoutMs === \"number\") {\n if (options.timeoutMs <= 0) {\n log.warn(\"task LLM: timed out before request started\");\n return { ok: false, failure: { failureReason: \"timeout\", errorClass: \"timeout\" } };\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) onCallerAbort();\n const timedOptions = { ...options, signal: controller.signal };\n const chain = runChain(timedOptions);\n const guarded = chain.catch((err) => {\n if (isTerminalCodexSubscriptionError(err)) throw err;\n return null;\n });\n try {\n const timeoutError = Object.assign(\n new Error(`task LLM timed out after ${options.timeoutMs}ms`),\n { name: \"TimeoutError\" },\n );\n const outcome = await raceFallbackLlmDeadline(\n guarded,\n options.timeoutMs,\n () => {\n log.warn(`task LLM: timed out after ${options.timeoutMs}ms`);\n recordFailure({ failureReason: \"timeout\", errorClass: \"timeout\" });\n controller.abort(timeoutError);\n if (options.failureDiag) options.failureDiag.lastError = timeoutError;\n },\n models.some((m) => m.providerConfig.api === \"codex-cli\") ? codexDeadlineHeadroomMs(options.timeoutMs) : 0,\n );\n if (outcome.timedOut) {\n return { ok: false, failure: { failureReason: \"timeout\", errorClass: \"timeout\" } };\n }\n return toOutcome(outcome.value);\n } finally {\n options.signal?.removeEventListener(\"abort\", onCallerAbort);\n }\n }\n\n return toOutcome(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<StructuredParseResult<T>> {\n let outcome: ChatCompletionOutcome;\n try {\n outcome = await this.completeChat(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 if (isTimeoutError(err)) {\n return { result: null, failureReason: \"timeout\", errorClass: \"timeout\" };\n }\n log.warn(\"task LLM: chatCompletion threw during structured parse:\", err);\n return { result: null, ...classifyThrownProviderError(err) };\n }\n if (!outcome.ok) {\n return { result: null, ...outcome.failure };\n }\n const response = outcome.response;\n if (!response.content) {\n return {\n result: null,\n failureReason: \"empty\",\n attemptedModel: response.modelUsed,\n errorClass: \"empty\",\n };\n }\n\n try {\n const candidates = extractJsonCandidates(response.content);\n let sawJson = false;\n let sawSchemaReject = false;\n for (const c of candidates) {\n let parsed: unknown;\n try {\n parsed = JSON.parse(c);\n sawJson = true;\n } catch {\n continue;\n }\n try {\n return { result: schema.parse(parsed), modelUsed: response.modelUsed };\n } catch {\n sawSchemaReject = true;\n }\n }\n if (sawSchemaReject) {\n return {\n result: null,\n failureReason: \"schema_rejection\",\n attemptedModel: response.modelUsed,\n errorClass: \"schema_rejection\",\n };\n }\n return {\n result: null,\n failureReason: \"empty\",\n attemptedModel: response.modelUsed,\n errorClass: \"empty\",\n };\n } catch (err) {\n log.warn(\"task LLM: failed to parse structured output:\", err);\n return {\n result: null,\n failureReason: \"empty\",\n attemptedModel: response.modelUsed,\n errorClass: \"empty\",\n };\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(\"task LLM: using explicit model chain override\");\n } else if (modelChainOverride) {\n log.warn(\"task 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(`task LLM: using agent persona \"${agentId}\" model chain`);\n } else {\n log.warn(\n `task 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 `task 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(`task 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 `task 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(`task 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(`task 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(`task LLM: provider \"${providerId}\" resolved from built-in defaults`);\n return { providerId, config: builtInConfig };\n }\n log.debug(`task 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(`task 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 `task 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 `task 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 Object.assign(new Error(`OpenAI API error: ${response.status} ${error}`), { status: response.status });\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 Object.assign(new Error(`Ollama API error: ${response.status} ${error}`), { status: response.status });\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 Object.assign(new Error(`OpenAI Responses API error: ${response.status} ${error}`), { status: response.status });\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 Object.assign(new Error(`Anthropic API error: ${response.status} ${error}`), { status: response.status });\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\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/buffer.ts"],"sourcesContent":["import { log } from \"./logger.js\";\nimport { throwIfAborted } from \"./abort-error.js\";\nimport { scanSignals } from \"./signal.js\";\nimport { BufferSessionPersistence, type BufferStorage } from \"./buffer-persistence.js\";\nimport { selectEvictedBufferKeys } from \"./buffer-eviction.js\";\nimport type {\n BufferEntryState,\n BufferState,\n BufferSurpriseEvent,\n BufferTurn,\n PluginConfig,\n SignalLevel,\n} from \"./types.js\";\nimport { resolvePresentationCapabilities, resolveNamespaceCapabilities } from \"./capabilities.js\";\nimport { resolvePrincipal } from \"./namespaces/principal.js\";\nimport { scopeProfilePlanIdentity } from \"./buffer-turn-helpers.js\";\nimport { ExtractionDeadlineError } from \"./orchestration/extraction-run.js\";\nimport type { ExtractionBufferSnapshot } from \"./extraction-liveness.js\";\nimport {\n bufferTurnArrayIsSuffixOfSnapshot,\n bufferTurnArraysEqual,\n bufferTurnsEqual,\n copyBufferTurn,\n describeError,\n hasPinnedCaptureScope,\n liveTurnsFromExtractionSnapshot,\n matchingQueuedExtractionPrefixLength,\n probeWithTimeout,\n selectRetainedDeferredTurns,\n} from \"./buffer-turn-helpers.js\";\n\nexport type TriggerDecision = \"extract_now\" | \"extract_batch\" | \"keep_buffering\";\n\nexport interface AddTurnOutcome {\n decision: TriggerDecision;\n extractionTurns?: BufferTurn[];\n}\n\nexport interface RetainedTurnCleanupOptions {\n abortSignal?: AbortSignal;\n deadlineMs?: number;\n /** Keep cleanup within the accepted namespace. */\n writeNamespaceOverride?: string;\n /** Match the original profile and project binding, not just its write namespace. */\n scopeProfileWritePlan?: import(\"./namespaces/scope-profiles.js\").ResolvedScopeProfilePlan | null;\n codingContext?: import(\"./types.js\").CodingContext;\n}\n\n/**\n * Optional surprise probe injected into `SmartBuffer`.\n *\n * Computes a D-MEM-style novelty score in `[0, 1]` for an incoming turn.\n * The buffer treats the probe as purely additive: if it is not provided, if\n * the feature flag is off, or if the probe throws/times out, the buffer\n * falls back to the existing signal/turn-count/time triggers unchanged.\n *\n * Callers are responsible for sampling recent memories and passing them\n * through the embedding pipeline — the buffer does not want to know about\n * storage, embeddings, or QMD.\n *\n * @param bufferKey Identifier for the active buffer (session/thread).\n * @param turn The incoming turn whose novelty is being scored.\n * @param recentTurns Turns already buffered for this key (most recent first\n * is NOT guaranteed — treat as unordered corpus).\n * @returns A surprise score in `[0, 1]`, or `null` if no score could be\n * produced (e.g. empty corpus, probe declined to embed).\n */\nexport interface BufferSurpriseProbe {\n scoreTurn(\n bufferKey: string,\n turn: BufferTurn,\n recentTurns: readonly BufferTurn[],\n ): Promise<number | null>;\n}\n\nconst MAX_BUFFER_ENTRY_COUNT = 200;\nconst isAcceptedTurn = (t: { acceptedCapture?: boolean; writeNamespaceOverride?: string }): boolean =>\n t.acceptedCapture === true || t.writeNamespaceOverride !== undefined;\n\n/**\n * Upper bound on how long a debounced buffer save may be deferred under\n * sustained activity (issue #1909). Each new turn re-arms the trailing-edge\n * timer, so a steady stream of turns could otherwise push the save out\n * indefinitely and widen the crash-loss window without bound. Once a pending\n * save has been deferred this many debounce windows, the next scheduled save\n * forces an inline flush instead of re-arming.\n */\nconst BUFFER_SAVE_MAX_DEFER_MULTIPLIER = 5;\n\n/**\n * Node's maximum 32-bit `setTimeout` delay (2^31-1 ms, ~24.8 days). A larger\n * value is overflow-clamped by Node to 1ms with a TimeoutOverflowWarning, so we\n * clamp defensively at every timer arm (issue #1909 review round 5) even though\n * parseConfig already caps `bufferSaveDebounceMs` — a directly-constructed config\n * could still exceed it.\n */\nconst MAX_SET_TIMEOUT_MS = 2_147_483_647;\n\n/**\n * Minimal data carried on the serialized telemetry write chain\n * (issue #563 PR 3).\n *\n * We intentionally do NOT capture the full `BufferTurn` here: under\n * slow filesystem latency the chain can back up, and retaining\n * `turn.content` for every pending append causes memory pressure on\n * large conversations. Only the fields the ledger row actually needs\n * cross the chain boundary.\n */\ninterface SurpriseTelemetryQueueEntry {\n bufferKey: string;\n turnRole: \"user\" | \"assistant\";\n sessionKey: string | null;\n surpriseScore: number;\n triggered: boolean;\n turnCountInWindow: number;\n /**\n * ISO timestamp captured at the moment the turn was scored, NOT when\n * the ledger append eventually runs. Backpressure on the serialized\n * write chain could otherwise shift event timestamps away from the\n * real decision moment and distort the distribution report (p90\n * inflated, current-threshold row misidentified).\n */\n timestamp: string;\n /**\n * Threshold value in force when `triggered` was computed. Must be\n * snapshot here rather than read from `config` at emit time — a\n * concurrent config change between queue and write would otherwise\n * record `triggered=true` against a newer threshold the operator\n * never set, distorting precision/recall interpretation.\n */\n threshold: number;\n}\n\ninterface AddTurnMutationResult {\n decision: TriggerDecision;\n signalLevel: SignalLevel;\n priorTurns: BufferTurn[];\n activeTurnsSnapshot: BufferTurn[];\n retainedTurnsSnapshot: BufferTurn[];\n turnCountInWindow: number;\n}\n\nexport class SmartBuffer {\n private state: BufferState;\n private loaded = false;\n private loadPromise: Promise<void> | null = null;\n private readonly surpriseProbe: BufferSurpriseProbe | null;\n private mutationChain: Promise<unknown> = Promise.resolve();\n /**\n * Serialized write chain for `BUFFER_SURPRISE` telemetry events.\n *\n * The telemetry path is fire-and-forget (`addTurn` does not await the\n * ledger append), but multiple concurrent appends would still settle\n * out of order under variable filesystem latency. The report path\n * assumes chronological ordering — it slices the tail of the ledger\n * and treats the most recent entry as the current threshold in force.\n * Chaining ensures each append only runs after the previous settles,\n * preserving wall-clock order.\n *\n * We include a `.catch` on every link so a rejected append does not\n * poison the chain (CLAUDE.md rule #40).\n */\n private surpriseTelemetryWriteChain: Promise<unknown> = Promise.resolve();\n\n /**\n * Debounced buffer-save state (issue #1909). Steady-state buffering used to\n * serialize + rewrite the whole multi-session buffer on EVERY turn. We now\n * coalesce those writes onto a trailing-edge timer; correctness boundaries\n * (extraction trigger, extraction clear, shutdown) still force an immediate\n * flush. `bufferSaveDebounceMs: 0` restores save-every-turn exactly.\n */\n private saveTimer: NodeJS.Timeout | null = null;\n private pendingSave = false;\n /** Wall-clock ms when the currently-pending save was first scheduled (issue\n * #1909). Null when nothing is pending. Used to bound deferral under sustained\n * activity (see BUFFER_SAVE_MAX_DEFER_MULTIPLIER). */\n private firstPendingAtMs: number | null = null;\n\n /** Which sessions' persisted files are stale (per-session incremental saves). */\n private readonly persistence = new BufferSessionPersistence();\n\n constructor(\n private readonly config: PluginConfig,\n private readonly storage: BufferStorage,\n surpriseProbe: BufferSurpriseProbe | null = null,\n ) {\n this.state = { turns: [], lastExtractionAt: null, extractionCount: 0 };\n this.surpriseProbe = surpriseProbe;\n }\n\n private enqueueMutation<T>(op: () => Promise<T>): Promise<T> {\n const run = this.mutationChain.catch(() => {}).then(op);\n this.mutationChain = run.catch(() => {});\n return run;\n }\n\n private entryFor(key: string): BufferEntryState {\n if (!this.state.entries) {\n this.state.entries = Object.create(null) as NonNullable<BufferState[\"entries\"]>;\n }\n const entries = this.state.entries as NonNullable<BufferState[\"entries\"]>;\n if (Object.hasOwn(entries, key)) {\n const stored = entries[key];\n // Guard against corrupted state/buffer.json — if the stored entry\n // is not a valid object shape, discard it and recreate.\n if (stored && typeof stored === \"object\" && Array.isArray(stored.turns)) {\n return stored;\n }\n // Corrupted — fall through to recreate.\n }\n const created: BufferEntryState = {\n turns: [],\n lastExtractionAt: null,\n extractionCount: 0,\n };\n entries[key] = created;\n return created;\n }\n\n private peekEntry(key: string): BufferEntryState | null {\n const existing = this.state.entries?.[key];\n if (existing) return existing;\n if (key !== \"default\") return null;\n return {\n turns: Array.isArray(this.state.turns) ? this.state.turns : [],\n lastExtractionAt: this.state.lastExtractionAt ?? null,\n extractionCount:\n typeof this.state.extractionCount === \"number\" ? this.state.extractionCount : 0,\n };\n }\n\n private normalizeState(state: BufferState): BufferState {\n const entries = Object.assign(\n Object.create(null),\n state.entries ?? {},\n ) as NonNullable<BufferState[\"entries\"]>;\n if (!entries.default) {\n entries.default = {\n turns: Array.isArray(state.turns) ? [...state.turns] : [],\n lastExtractionAt: state.lastExtractionAt ?? null,\n extractionCount:\n typeof state.extractionCount === \"number\" ? state.extractionCount : 0,\n };\n }\n return {\n turns: entries.default.turns,\n lastExtractionAt: entries.default.lastExtractionAt,\n extractionCount: entries.default.extractionCount,\n entries,\n };\n }\n\n private entryActivityAt(entry: BufferEntryState): number {\n const lastTurnAt = entry.turns.reduce((latest, turn) => {\n const parsed = Date.parse(turn.timestamp);\n return Number.isFinite(parsed) ? Math.max(latest, parsed) : latest;\n }, -1);\n const lastExtractionAt =\n typeof entry.lastExtractionAt === \"string\"\n ? Date.parse(entry.lastExtractionAt)\n : Number.NaN;\n return Math.max(\n lastTurnAt,\n Number.isFinite(lastExtractionAt) ? lastExtractionAt : -1,\n );\n }\n\n /** Evict oldest entries past MAX_BUFFER_ENTRY_COUNT and queue their session files for deletion. */\n private pruneEntries(retainKeys: string[]): void {\n const entries = this.state.entries;\n if (!entries) return;\n const evicted = selectEvictedBufferKeys(entries, retainKeys, MAX_BUFFER_ENTRY_COUNT, {\n activityAt: (entry) => this.entryActivityAt(entry),\n holdsAcceptedCapture: (entry) => this.entryHoldsAcceptedCapture(entry),\n });\n for (const key of evicted) delete entries[key];\n this.persistence.markEvicted(evicted);\n if (evicted.length > 0) {\n // Loud degradation (extraction hot-loop hardening, Step 7): buffer\n // pressure during a provider outage is bounded and expected, but must\n // be observable, not silent.\n log.warn(\n `buffer: pruned ${evicted.length} oldest session entr${evicted.length === 1 ? \"y\" : \"ies\"} ` +\n `past MAX_BUFFER_ENTRY_COUNT=${MAX_BUFFER_ENTRY_COUNT}; buffered turn data for those sessions was dropped`,\n );\n }\n }\n\n private async loadUnlocked(): Promise<void> {\n if (this.loaded) return;\n if (!this.loadPromise) {\n this.loadPromise = this.storage.loadBuffer()\n .then((state) => {\n this.state = this.normalizeState(state);\n this.loaded = true;\n })\n .finally(() => {\n this.loadPromise = null;\n });\n }\n await this.loadPromise;\n }\n\n async load(): Promise<void> {\n await this.enqueueMutation(async () => this.loadUnlocked());\n }\n\n /** Snapshot of buffered, not-yet-extracted work across sessions (#2151): session count,\n * pending-turn total, oldest buffered turn. Counts retained (#562) + active turns per entry. */\n async getBufferSnapshot(): Promise<ExtractionBufferSnapshot> {\n await this.load();\n let bufferedSessionCount = 0;\n let pendingTurnCount = 0;\n let oldestMs = Number.POSITIVE_INFINITY;\n let oldestTurnTimestamp: string | null = null;\n const consider = (turns: BufferTurn[] | undefined): void => {\n if (!Array.isArray(turns) || turns.length === 0) return;\n bufferedSessionCount += 1;\n pendingTurnCount += turns.length;\n const first = turns[0]?.timestamp;\n const parsed = typeof first === \"string\" ? Date.parse(first) : Number.NaN;\n if (Number.isFinite(parsed) && parsed < oldestMs) {\n oldestMs = parsed;\n oldestTurnTimestamp = first ?? null;\n }\n };\n const entries = this.state.entries;\n if (entries) {\n // Retained turns (deferred #562) are pending too - count with active (oldest-first), like getTurns().\n for (const entry of Object.values(entries)) consider([...(entry?.retainedTurns ?? []), ...(entry?.turns ?? [])]);\n } else {\n consider(this.state.turns);\n }\n return { bufferedSessionCount, pendingTurnCount, oldestTurnTimestamp };\n }\n\n /**\n * Reset the buffer to an empty, usable state.\n * Called when the persisted buffer file is corrupt and load() fails,\n * so the buffer can still accept new turns for the rest of the session.\n */\n resetToEmpty(): void {\n for (const key of Object.keys(this.state.entries ?? {})) {\n this.persistence.markDeleted(key);\n }\n this.state = { turns: [], lastExtractionAt: null, extractionCount: 0 };\n this.loaded = true;\n }\n\n private async saveUnlocked(): Promise<void> {\n await this.persistence.persist(this.storage, this.state, (key) => this.peekEntry(key) ?? undefined);\n }\n\n async save(): Promise<void> {\n await this.enqueueMutation(async () => this.saveUnlocked());\n }\n\n /**\n * Schedule a coalesced, TRUE trailing-edge buffer save (issue #1909). Only\n * used for the debounced (`bufferSaveDebounceMs > 0`) steady-state buffering\n * path; the debounce-off and correctness-boundary paths save inline within the\n * mutation (see `recordTurnUnlocked`). Each call re-arms the timer from now so\n * the write lands one full window after the LAST turn, not the first. To keep\n * sustained activity from deferring the save without bound (which would widen\n * the crash-loss window), once a pending save has been deferred\n * BUFFER_SAVE_MAX_DEFER_MULTIPLIER windows it is flushed inline instead of\n * re-armed. Runs inside the record mutation, so the inline save is awaited.\n */\n private async scheduleSave(): Promise<void> {\n const ms = Math.min(this.config.bufferSaveDebounceMs, MAX_SET_TIMEOUT_MS);\n const now = Date.now();\n this.pendingSave = true;\n if (this.firstPendingAtMs === null) this.firstPendingAtMs = now;\n if (now - this.firstPendingAtMs >= ms * BUFFER_SAVE_MAX_DEFER_MULTIPLIER) {\n // Staleness cap hit: persist now rather than deferring further. Drop the\n // armed timer, attempt the write, and only mark clean on success — a\n // failure keeps the save pending + re-arms so shutdown/the next timer\n // retries (issue #1909 review round 2), never diverging memory from disk.\n clearTimeout(this.saveTimer ?? undefined);\n this.saveTimer = null;\n try {\n await this.saveUnlocked();\n this.pendingSave = false;\n this.firstPendingAtMs = null;\n } catch (err) {\n log.warn(`buffer.scheduleSave: staleness-cap save failed, keeping it pending: ${describeError(err)}`);\n this.saveTimer = setTimeout(() => {\n this.saveTimer = null;\n void this.flushPendingSave();\n }, ms);\n this.saveTimer.unref?.();\n }\n return;\n }\n // True trailing edge: drop any armed timer and re-arm from now.\n clearTimeout(this.saveTimer ?? undefined);\n this.saveTimer = setTimeout(() => {\n this.saveTimer = null;\n void this.flushPendingSave();\n }, ms);\n this.saveTimer.unref?.();\n }\n\n /** Cancel any armed debounced save without persisting. */\n private cancelScheduledSave(): void {\n if (this.saveTimer) {\n clearTimeout(this.saveTimer);\n this.saveTimer = null;\n }\n this.pendingSave = false;\n this.firstPendingAtMs = null;\n }\n\n /**\n * Persist the current in-memory buffer state inline, keeping the global\n * pending-save state armed until the write SUCCEEDS (issue #1909). On failure\n * the save stays pending and — when debounced — a background retry timer is\n * (re-)armed before the error propagates, so a graceful shutdown flush and the\n * next timer tick both retry. A failed post-mutation save therefore can never\n * silently drop buffered turns, including turns from OTHER sessions that were\n * only in the debounced pending state. The pending flag is cleared (and any\n * armed timer dropped) only after a durable write.\n */\n private async saveNowRetainingPendingOnFailure(context: string): Promise<void> {\n this.pendingSave = true;\n if (this.firstPendingAtMs === null) this.firstPendingAtMs = Date.now();\n try {\n await this.saveUnlocked();\n } catch (err) {\n log.warn(\n `buffer.${context}: inline save failed, keeping it pending for retry: ${describeError(err)}`,\n );\n const ms = Math.min(this.config.bufferSaveDebounceMs, MAX_SET_TIMEOUT_MS);\n if (ms > 0 && !this.saveTimer) {\n this.saveTimer = setTimeout(() => {\n this.saveTimer = null;\n void this.flushPendingSave();\n }, ms);\n this.saveTimer.unref?.();\n }\n throw err;\n }\n this.cancelScheduledSave();\n }\n\n /**\n * Force any pending debounced save to land now (issue #1909). Idempotent and\n * safe to call from outside a mutation (timer tick, shutdown/dispose, or the\n * surprise-promotion path in `addTurnWithOutcome`). Do NOT `await` this from\n * inside a mutation — it enqueues its own mutation and would deadlock the\n * serializer.\n *\n * `throwOnFailure` (review round 7 finding 5): when set, a failed write is\n * rethrown AFTER the keep-pending + re-arm bookkeeping, so the surprise\n * extraction boundary gets the same durability guarantee as the built-in\n * extract triggers (which propagate saveUnlocked failures) instead of\n * proceeding to extract_now on a non-durable triggering turn. Default false\n * keeps the fail-open behavior for the timer/shutdown callers.\n */\n async flushPendingSave(opts?: { throwOnFailure?: boolean }): Promise<void> {\n if (this.saveTimer) {\n clearTimeout(this.saveTimer);\n this.saveTimer = null;\n }\n // resetToEmpty-only deletions are pending work too, even with no\n // pending-save flag set.\n if (!this.pendingSave && !this.persistence.hasPending()) return;\n try {\n await this.enqueueMutation(async () => {\n // Re-check under the serializer: a concurrent flush may have already\n // persisted this pending save. Skip the redundant write (no phantom\n // writes). resetToEmpty-only deletions also land here without a\n // pending-save flag.\n if (!this.pendingSave && !this.persistence.hasPending()) return;\n await this.saveUnlocked();\n // Clear the pending flag INSIDE the same serialized mutation as the\n // write (issue #1909 review). Clearing it after the enqueue await\n // resolved raced an addTurn interleaving between the write and the\n // clear: that turn's scheduleSave re-armed pendingSave + a timer, then\n // this clear wiped it and the debounced flush was lost. Atomic\n // write+clear means any addTurn runs wholly before (its turn is in the\n // write) or wholly after (its pendingSave survives and its timer\n // persists it).\n this.pendingSave = false;\n this.firstPendingAtMs = null;\n });\n } catch (err) {\n // The write failed: memory and disk diverge (issue #1909 review round 2).\n // Keep the save PENDING (do NOT clear pendingSave/firstPendingAtMs) so a\n // graceful shutdown flush and the re-armed timer both retry it — clearing\n // the flag here would drop the buffered turns permanently. Re-arm a\n // background retry when debounced.\n log.warn(`buffer.flushPendingSave: save failed, keeping it pending for retry: ${describeError(err)}`);\n const ms = Math.min(this.config.bufferSaveDebounceMs, MAX_SET_TIMEOUT_MS);\n if (ms > 0 && !this.saveTimer) {\n this.saveTimer = setTimeout(() => {\n this.saveTimer = null;\n void this.flushPendingSave();\n }, ms);\n this.saveTimer.unref?.();\n }\n // Surprise-extraction boundary needs the durability guarantee — surface\n // the failure so the caller does not proceed with a non-durable flush.\n if (opts?.throwOnFailure) throw err;\n return; // fail-open for timer/shutdown callers\n }\n }\n\n async addTurn(bufferKey: string, turn: BufferTurn): Promise<TriggerDecision> {\n return (await this.addTurnWithOutcome(bufferKey, turn)).decision;\n }\n\n /** Admit atomically; refuse at capacity rather than evict accepted work. */\n async addTurnBounded(bufferKey: string, turn: BufferTurn): Promise<AddTurnOutcome | null> {\n const mutation = await this.enqueueMutation(async () => {\n await this.loadUnlocked();\n if (this.peekEntry(bufferKey) === null) {\n this.makeRoomForEntryUnlocked();\n if (Object.keys(this.state.entries ?? {}).length >= MAX_BUFFER_ENTRY_COUNT) {\n log.warn(\n `buffer[${bufferKey}]: durable capture refused at MAX_BUFFER_ENTRY_COUNT=${MAX_BUFFER_ENTRY_COUNT}`,\n );\n return null;\n }\n }\n return this.recordTurnUnlocked(bufferKey, turn);\n });\n if (mutation === null) return null;\n return this.completeAddTurnOutcome(bufferKey, turn, mutation);\n }\n\n /** Prune empty entries only; accepted work must survive capacity pressure. */\n private makeRoomForEntryUnlocked(): void {\n const entries = this.state.entries;\n if (!entries) return;\n const keys = Object.keys(entries);\n if (keys.length < MAX_BUFFER_ENTRY_COUNT) return;\n const byOldestActivity = (left: string, right: string): number =>\n this.entryActivityAt(entries[left] ?? { turns: [], lastExtractionAt: null, extractionCount: 0 }) -\n this.entryActivityAt(entries[right] ?? { turns: [], lastExtractionAt: null, extractionCount: 0 });\n const emptyRemovable = keys\n .filter(\n (key) =>\n key !== \"default\" &&\n (entries[key]?.turns.length ?? 0) === 0 &&\n (entries[key]?.retainedTurns?.length ?? 0) === 0,\n )\n .sort(byOldestActivity);\n for (const key of emptyRemovable) {\n if (Object.keys(entries).length < MAX_BUFFER_ENTRY_COUNT) break;\n delete entries[key];\n this.persistence.markDeleted(key);\n }\n }\n\n private entryHoldsAcceptedCapture(entry: BufferEntryState | undefined): boolean {\n return (entry?.turns ?? []).some(isAcceptedTurn) || (entry?.retainedTurns ?? []).some(isAcceptedTurn);\n }\n\n async addTurnWithOutcome(\n bufferKey: string,\n turn: BufferTurn,\n ): Promise<AddTurnOutcome> {\n const mutation = await this.enqueueMutation(() => this.recordTurnUnlocked(bufferKey, turn));\n return this.completeAddTurnOutcome(bufferKey, turn, mutation);\n }\n\n /** Run probes outside the mutation lock to avoid reentrancy deadlocks. */\n private async completeAddTurnOutcome(\n bufferKey: string,\n turn: BufferTurn,\n mutation: AddTurnMutationResult,\n ): Promise<AddTurnOutcome> {\n let decision = mutation.decision;\n let extractionTurns: BufferTurn[] | undefined;\n\n // Surprise-gated flush (issue #563). Additive only: if the probe is\n // disabled, unavailable, or the score is below threshold, the decision\n // from the existing trigger logic stands. The probe only ever *promotes*\n // `keep_buffering` → `extract_now`; it never suppresses an existing\n // flush. This preserves the invariant that enabling surprise cannot\n // *reduce* extraction frequency.\n if (\n decision === \"keep_buffering\" &&\n resolvePresentationCapabilities(this.config).bufferSurpriseTrigger &&\n this.surpriseProbe !== null &&\n // Matching the existing \"smart\" branch: surprise is a lower-tier\n // novelty signal that should not second-guess a high-signal hit\n // (which already flushes) or fight `every_n` / `time_based` modes.\n this.config.triggerMode === \"smart\" &&\n mutation.signalLevel !== \"high\"\n ) {\n const surprise = await this.computeSurpriseSafe(bufferKey, turn, mutation.priorTurns);\n if (surprise !== null) {\n const shouldPromote = surprise > this.config.bufferSurpriseThreshold;\n let triggered = false;\n if (shouldPromote) {\n const currentTurns = await this.getExtractionTurnsIfBufferSnapshotStillCurrent(\n bufferKey,\n mutation.activeTurnsSnapshot,\n mutation.retainedTurnsSnapshot,\n );\n if (currentTurns) {\n log.debug(\n `buffer[${bufferKey}]: surprise=${surprise.toFixed(3)} > threshold=${this.config.bufferSurpriseThreshold} → extract_now`,\n );\n decision = \"extract_now\";\n triggered = true;\n extractionTurns = currentTurns;\n // Issue #1909 (review): the record mutation for a `keep_buffering`\n // turn only SCHEDULED a debounced save. Surprise now promotes it to\n // extract_now AFTER that mutation, so force the buffer durable before\n // the caller runs extraction — otherwise state/buffer.json lags the\n // extracted turns by up to the debounce window on a crash. Safe to\n // await here: we are outside the record mutation (deadlock-free).\n // throwOnFailure (round 7 finding 5): match the built-in extract\n // triggers — a failed durability write must NOT silently proceed to\n // extract_now on a non-durable turn.\n await this.flushPendingSave({ throwOnFailure: true });\n } else {\n log.debug(\n `buffer[${bufferKey}]: surprise=${surprise.toFixed(3)} ignored because buffer changed before probe resolved`,\n );\n }\n }\n // Emit telemetry on every scored turn — both triggering and\n // non-triggering — so operators can fit the threshold to real\n // traffic distributions. Fire-and-forget: `addTurn` does NOT\n // await the ledger append, so slow/contended filesystems cannot\n // add JSONL-append latency to every `processTurn`. But we DO\n // serialize writes through a promise chain so concurrent\n // appends settle in wall-clock order — the report path assumes\n // chronological tail rows and reads the most recent as the\n // \"current\" threshold.\n //\n // Project only the fields we need into the queue entry rather\n // than capturing the full `BufferTurn` — under slow filesystem\n // latency the chain can back up, and we must not retain the\n // (potentially large) `turn.content` string for every pending\n // append.\n this.queueSurpriseTelemetryWrite({\n bufferKey,\n turnRole: turn.role,\n sessionKey:\n typeof turn.sessionKey === \"string\" ? turn.sessionKey : null,\n surpriseScore: surprise,\n triggered,\n turnCountInWindow: mutation.turnCountInWindow,\n // Stamp at decision time so backpressure on the write chain\n // does not shift the event's apparent moment away from when\n // the turn was actually scored.\n timestamp: new Date().toISOString(),\n // Snapshot the threshold used to compute `triggered` so a\n // concurrent config mutation cannot retroactively change\n // what the ledger row claims the decision was against.\n threshold: this.config.bufferSurpriseThreshold,\n });\n }\n }\n\n log.debug(\n `buffer[${bufferKey}]: ${mutation.turnCountInWindow} turns, signal=${mutation.signalLevel}, decision=${decision}`,\n );\n if (decision !== \"keep_buffering\" && extractionTurns === undefined) {\n extractionTurns = [\n ...mutation.retainedTurnsSnapshot,\n ...mutation.activeTurnsSnapshot,\n ];\n }\n return extractionTurns ? { decision, extractionTurns } : { decision };\n }\n\n private async recordTurnUnlocked(bufferKey: string, turn: BufferTurn): Promise<AddTurnMutationResult> {\n await this.loadUnlocked();\n const entry = this.entryFor(bufferKey);\n const priorTurns = entry.turns.slice();\n entry.turns.push(turn);\n const activeTurnsSnapshot = entry.turns.map(copyBufferTurn);\n const retainedTurnsSnapshot = (entry.retainedTurns ?? []).map(copyBufferTurn);\n if (bufferKey === \"default\") {\n this.state.turns = entry.turns;\n }\n\n const signal = scanSignals(turn.content, this.config.highSignalPatterns);\n const decision = this.evaluate(entry, signal.level);\n const turnCountInWindow = entry.turns.length;\n\n this.persistence.markDirty(bufferKey);\n this.pruneEntries([bufferKey]);\n if (decision === \"keep_buffering\" && this.config.bufferSaveDebounceMs > 0) {\n // Steady-state buffering: coalesce the whole-state serialize onto a\n // trailing-edge timer (issue #1909) instead of rewriting per turn.\n await this.scheduleSave();\n } else {\n // Persist immediately within this mutation (awaited) when either:\n // - the turn triggered extraction (the buffer must be durable), or\n // - debounce is disabled (bufferSaveDebounceMs <= 0), which reproduces\n // the legacy save-every-turn behavior byte-for-byte.\n // Round 8 thread 4: the write is attempted BEFORE the pending state is\n // cleared, and a failed write leaves it pending (+ a re-armed timer) for\n // shutdown/timer retry instead of dropping the in-memory turns.\n await this.saveNowRetainingPendingOnFailure(\"recordTurn\");\n }\n return {\n decision,\n signalLevel: signal.level,\n priorTurns,\n activeTurnsSnapshot,\n retainedTurnsSnapshot,\n turnCountInWindow,\n };\n }\n\n private async getExtractionTurnsIfBufferSnapshotStillCurrent(\n bufferKey: string,\n activeTurnsSnapshot: readonly BufferTurn[],\n retainedTurnsSnapshot: readonly BufferTurn[],\n ): Promise<BufferTurn[] | null> {\n return this.enqueueMutation(async () => {\n await this.loadUnlocked();\n const entry = this.peekEntry(bufferKey);\n if (!entry) return null;\n const retained = entry.retainedTurns ?? [];\n const stillCurrent =\n bufferTurnArrayIsSuffixOfSnapshot(entry.turns, activeTurnsSnapshot) &&\n bufferTurnArraysEqual(retained, retainedTurnsSnapshot);\n if (!stillCurrent) return null;\n return [...retained, ...entry.turns];\n });\n }\n\n /**\n * Enqueue a telemetry append on the serialized write chain.\n *\n * The chain is a classic `writeChain = writeChain.then(fn).catch(...)`\n * — each link waits for the previous to settle before its append\n * starts, so out-of-order chronology cannot happen even under\n * variable filesystem latency. We always attach `.catch` so one\n * rejection does not poison the chain for the rest of the session\n * (CLAUDE.md rule #40). The error is logged through\n * `emitSurpriseEventSafe` itself, which swallows its own rejections.\n *\n * Public surface is deliberately narrow — only `addTurn` should call\n * this, so the surprise telemetry path stays centralized.\n */\n private queueSurpriseTelemetryWrite(params: SurpriseTelemetryQueueEntry): void {\n this.surpriseTelemetryWriteChain = this.surpriseTelemetryWriteChain\n .then(() => this.emitSurpriseEventSafe(params))\n .catch(() => {\n // `emitSurpriseEventSafe` already handles the logging. We\n // swallow here only so one failure does not break the chain\n // for future writes.\n });\n }\n\n /**\n * Append a single `BUFFER_SURPRISE` telemetry row (issue #563 PR 3).\n *\n * Deliberately swallows write errors: the buffer must never fail to\n * record a turn because the observation ledger is read-only, out of\n * disk, or otherwise unhappy. The log line at debug lets operators\n * confirm the path fired without polluting the error channel.\n */\n private async emitSurpriseEventSafe(\n params: SurpriseTelemetryQueueEntry,\n ): Promise<void> {\n const storage = this.storage;\n if (typeof storage.appendBufferSurpriseEvents !== \"function\") {\n // Older StorageManager / test double without the telemetry sink.\n // Silently skip — core path is still covered by the log line above.\n return;\n }\n const event: BufferSurpriseEvent = {\n event: \"BUFFER_SURPRISE\",\n // Use the decision-time stamp captured when the event was\n // queued, NOT `Date.now()` here — backpressure on the write\n // chain could otherwise shift timestamps into the future relative\n // to when the turn was scored.\n timestamp: params.timestamp,\n bufferKey: params.bufferKey,\n sessionKey: params.sessionKey,\n turnRole: params.turnRole,\n surpriseScore: params.surpriseScore,\n // Use the snapshotted threshold from the queue entry, not the\n // live config — see `SurpriseTelemetryQueueEntry.threshold`\n // doc for the rationale.\n threshold: params.threshold,\n triggeredFlush: params.triggered,\n turnCountInWindow: params.turnCountInWindow,\n };\n try {\n await storage.appendBufferSurpriseEvents([event]);\n } catch (err) {\n // Same guard as `computeSurpriseSafe`: non-Error rejections must\n // not crash the telemetry helper, which would defeat the whole\n // point of isolating the ledger write from the hot path.\n log.debug(\n `buffer[${params.bufferKey}]: surprise telemetry write failed, continuing: ${describeError(err)}`,\n );\n }\n }\n\n /**\n * Invoke the injected surprise probe defensively. Any error (probe throws,\n * embedder unavailable, timeout) is swallowed and logged at debug: the\n * surprise path must never crash the happy-path trigger evaluation. A\n * `null` return indicates \"no score available, fall through to existing\n * triggers\".\n */\n private async computeSurpriseSafe(\n bufferKey: string,\n turn: BufferTurn,\n priorTurns: readonly BufferTurn[],\n ): Promise<number | null> {\n if (!this.surpriseProbe) return null;\n try {\n // Hard timeout around the probe so a hung embedder cannot stall\n // `addTurn()` before `save()`. A slow probe would otherwise\n // prevent the just-appended turn from ever being persisted. The\n // timeout is a soft bound — we race it against the probe, take\n // whichever settles first, and treat the timeout as\n // \"probe unavailable, fall through\" rather than an error that\n // surfaces to the caller.\n const score = await probeWithTimeout(\n this.surpriseProbe.scoreTurn(bufferKey, turn, priorTurns),\n this.config.bufferSurpriseProbeTimeoutMs,\n );\n if (score === null) return null;\n if (typeof score !== \"number\" || !Number.isFinite(score)) {\n log.debug(\n `buffer[${bufferKey}]: surprise probe returned non-finite score (${String(score)}), ignoring`,\n );\n return null;\n }\n // Defensive clamp: formula lives in buffer-surprise.ts, but we never\n // want a misbehaving probe to inject an out-of-range value into the\n // threshold comparison.\n if (score < 0) return 0;\n if (score > 1) return 1;\n return score;\n } catch (err) {\n // `err` may be any thrown value — `throw null` and\n // `Promise.reject(\"x\")` are both legal. Accessing `.message` on a\n // non-Error would itself throw and defeat the failure-isolation\n // contract, so describe the value safely.\n log.debug(\n `buffer[${bufferKey}]: surprise probe failed, falling back to existing triggers: ${describeError(err)}`,\n );\n return null;\n }\n }\n\n private evaluate(entry: BufferEntryState, signalLevel: SignalLevel): TriggerDecision {\n if (this.config.triggerMode === \"smart\") {\n if (signalLevel === \"high\") return \"extract_now\";\n\n if (entry.turns.length >= this.config.bufferMaxTurns) {\n return \"extract_batch\";\n }\n\n if (entry.lastExtractionAt) {\n const elapsed =\n Date.now() - new Date(entry.lastExtractionAt).getTime();\n if (elapsed >= this.config.bufferMaxMinutes * 60_000) {\n return \"extract_batch\";\n }\n }\n\n return \"keep_buffering\";\n }\n\n if (this.config.triggerMode === \"every_n\") {\n return entry.turns.length >= this.config.bufferMaxTurns\n ? \"extract_batch\"\n : \"keep_buffering\";\n }\n\n if (this.config.triggerMode === \"time_based\") {\n if (!entry.lastExtractionAt) {\n return entry.turns.length >= this.config.bufferMaxTurns\n ? \"extract_batch\"\n : \"keep_buffering\";\n }\n const elapsed =\n Date.now() - new Date(entry.lastExtractionAt).getTime();\n return elapsed >= this.config.bufferMaxMinutes * 60_000\n ? \"extract_batch\"\n : \"keep_buffering\";\n }\n\n return \"keep_buffering\";\n }\n\n getTurns(bufferKey = \"default\"): BufferTurn[] {\n const entry = this.peekEntry(bufferKey);\n if (!entry) return [];\n const retained = entry.retainedTurns ?? [];\n // Retained turns (from a previous defer verdict, issue #562 PR 2) are\n // prepended so the chronological order — oldest context first — is\n // preserved for the next extraction pass.\n return [...retained, ...entry.turns];\n }\n\n /**\n * Retain a subset of the current turns across `clearAfterExtraction` so a\n * future extraction pass sees the context behind a deferred candidate\n * (issue #562, PR 2). Callers pass the turns that were seen during the\n * current extraction; the buffer keeps the tail (latest `max` turns) as\n * the retention window. Passing an empty array or `max <= 0` clears the\n * retention slot instead.\n */\n async retainDeferredTurns(\n bufferKey: string,\n turns: BufferTurn[],\n max = 10,\n originalTurns?: readonly BufferTurn[],\n ): Promise<void> {\n await this.enqueueMutation(async () => {\n await this.loadUnlocked();\n const entry = this.entryFor(bufferKey);\n const retained = selectRetainedDeferredTurns(\n entry.retainedTurns ?? [], turns, max, originalTurns,\n );\n if (retained.length > 0) entry.retainedTurns = retained;\n else delete entry.retainedTurns;\n this.persistence.markDirty(bufferKey);\n await this.saveUnlocked();\n });\n }\n\n /**\n * Return the current retention window (issue #562, PR 2). Primarily for\n * tests and diagnostics.\n */\n getRetainedDeferredTurns(bufferKey = \"default\"): BufferTurn[] {\n const entry = this.peekEntry(bufferKey);\n return entry?.retainedTurns ? [...entry.retainedTurns] : [];\n }\n\n /**\n * Clear deferred retention copies for a force-flushed session. Normal\n * extraction preserves these copies so a deferred candidate can be retried;\n * an explicit force flush is the caller's request to drain that context.\n */\n async clearRetainedTurnsForSession(\n sessionKey: string,\n ownerPrincipal?: string,\n options: RetainedTurnCleanupOptions = {},\n ): Promise<void> {\n if (typeof sessionKey !== \"string\" || sessionKey.length === 0) return;\n const normalizedOwnerPrincipal =\n typeof ownerPrincipal === \"string\" && ownerPrincipal.trim().length > 0\n ? ownerPrincipal.trim()\n : undefined;\n const namespacesEnabled = resolveNamespaceCapabilities(this.config).namespaces === true;\n const normalizedCleanupNamespace =\n namespacesEnabled && options.writeNamespaceOverride !== undefined && options.writeNamespaceOverride.length > 0\n ? options.writeNamespaceOverride\n : undefined;\n const assertLifecycle = (): void => {\n throwIfAborted(options.abortSignal, \"extraction force-flush aborted\");\n if (typeof options.deadlineMs === \"number\" && Date.now() >= options.deadlineMs) {\n throw new ExtractionDeadlineError(\"retained_turn_cleanup\");\n }\n };\n assertLifecycle();\n await this.enqueueMutation(async () => {\n assertLifecycle();\n const hadPendingSave = this.pendingSave;\n if (this.saveTimer) {\n clearTimeout(this.saveTimer);\n this.saveTimer = null;\n }\n await this.loadUnlocked();\n assertLifecycle();\n const bufferKeys = this.matchingSessionBufferKeysUnlocked(sessionKey);\n if (bufferKeys.length === 0) {\n if (hadPendingSave) {\n assertLifecycle();\n await this.saveNowRetainingPendingOnFailure(\"clearRetainedTurnsForSession\");\n }\n return;\n }\n let changed = false;\n const matchesCleanupScope = (turn: BufferTurn): boolean => {\n // Legacy unpinned turns keep their existing cleanup semantics.\n if (\n turn.writeNamespaceOverride !== undefined &&\n normalizedCleanupNamespace !== undefined &&\n turn.writeNamespaceOverride !== normalizedCleanupNamespace\n ) {\n return false;\n }\n // Equal write namespaces can still belong to different project bindings.\n if (options.scopeProfileWritePlan && hasPinnedCaptureScope(turn)) {\n if (\n scopeProfilePlanIdentity(turn.scopeProfileWritePlan) !== scopeProfilePlanIdentity(options.scopeProfileWritePlan) &&\n !(turn.acceptedCapture === true && turn.scopeProfileWritePlan === undefined)\n ) {\n return false;\n }\n const ctx = options.codingContext;\n if (\n ctx && turn.codingContext &&\n (turn.codingContext.projectId !== ctx.projectId ||\n turn.codingContext.rootPath !== ctx.rootPath ||\n turn.codingContext.branch !== ctx.branch ||\n turn.codingContext.defaultBranch !== ctx.defaultBranch)\n ) {\n return false;\n }\n }\n return true;\n };\n const belongsToOwner = (turn: BufferTurn): boolean => {\n if (turn.sessionKey !== sessionKey) return false;\n if (!matchesCleanupScope(turn)) return false;\n if (normalizedOwnerPrincipal === undefined) return true;\n if (turn.sessionOwnerPrincipal === normalizedOwnerPrincipal) return true;\n return (\n turn.sessionOwnerPrincipal === undefined &&\n resolvePrincipal(turn.sessionKey, this.config) === normalizedOwnerPrincipal\n );\n };\n for (const bufferKey of bufferKeys) {\n const entry = this.entryFor(bufferKey);\n const retainedTurns = entry.retainedTurns ?? [];\n const remainingTurns = retainedTurns.filter((turn) => !belongsToOwner(turn));\n if (remainingTurns.length === retainedTurns.length) continue;\n changed = true;\n if (remainingTurns.length > 0) entry.retainedTurns = remainingTurns;\n else delete entry.retainedTurns;\n if (bufferKey === \"default\") this.state.turns = entry.turns;\n this.persistence.markDirty(bufferKey);\n }\n if (changed || hadPendingSave) {\n assertLifecycle();\n await this.saveNowRetainingPendingOnFailure(\"clearRetainedTurnsForSession\");\n }\n assertLifecycle();\n });\n }\n\n async findBufferKeyForSession(sessionKey: string): Promise<string | null> {\n const bufferKeys = await this.findBufferKeysForSession(sessionKey);\n return bufferKeys[0] ?? null;\n }\n\n private matchingSessionBufferKeysUnlocked(sessionKey: string): string[] {\n const matches: string[] = [];\n const hasSessionTurns = (entry: BufferEntryState | null | undefined): boolean =>\n [...(entry?.turns ?? []), ...(entry?.retainedTurns ?? [])].some(\n (turn) => typeof turn.sessionKey === \"string\" && turn.sessionKey === sessionKey,\n );\n const directEntry = this.peekEntry(sessionKey);\n if (hasSessionTurns(directEntry)) {\n matches.push(sessionKey);\n }\n\n const entries = this.state.entries ?? {};\n for (const [bufferKey, entry] of Object.entries(entries)) {\n if (!matches.includes(bufferKey) && hasSessionTurns(entry)) {\n matches.push(bufferKey);\n }\n }\n\n return matches;\n }\n\n async findBufferKeysForSession(sessionKey: string): Promise<string[]> {\n if (typeof sessionKey !== \"string\" || sessionKey.length === 0) return [];\n await this.mutationChain.catch(() => {});\n await this.load();\n return this.matchingSessionBufferKeysUnlocked(sessionKey);\n }\n\n async clearAfterExtraction(\n bufferKey = \"default\",\n extractedTurns?: readonly BufferTurn[],\n options?: { allowNonPrefix?: boolean },\n ): Promise<void> {\n await this.enqueueMutation(async () => {\n // Drop any armed debounce TIMER so it cannot fire mid-mutation and race\n // our post-clear write, but KEEP the pending-save state (issue #1909\n // review round 13): the post-clear save below can fail, and clearing the\n // pending flag here would strand buffered turns — including turns from\n // OTHER sessions that only ever entered the debounced pending state — with\n // nothing left to retry them. saveNowRetainingPendingOnFailure clears the\n // pending state only after a durable write, or re-arms it on failure.\n if (this.saveTimer) {\n clearTimeout(this.saveTimer);\n this.saveTimer = null;\n }\n await this.loadUnlocked();\n const entry = this.entryFor(bufferKey);\n if (Array.isArray(extractedTurns)) {\n const liveExtractedTurns = liveTurnsFromExtractionSnapshot(\n entry,\n extractedTurns,\n );\n let clearedLiveTurns = false;\n if (liveExtractedTurns.length > 0) {\n if (options?.allowNonPrefix === true) {\n const remainingTurns = [...entry.turns];\n for (const extractedTurn of liveExtractedTurns) {\n const matchingIndex = remainingTurns.findIndex((liveTurn) =>\n bufferTurnsEqual(liveTurn, extractedTurn),\n );\n if (matchingIndex >= 0) {\n remainingTurns.splice(matchingIndex, 1);\n clearedLiveTurns = true;\n }\n }\n if (clearedLiveTurns) entry.turns = remainingTurns;\n } else {\n const matchedCount = matchingQueuedExtractionPrefixLength(\n entry.turns,\n liveExtractedTurns,\n );\n if (matchedCount > 0) {\n entry.turns = entry.turns.slice(matchedCount);\n clearedLiveTurns = true;\n }\n }\n if (!clearedLiveTurns) {\n log.debug(\n `buffer[${bufferKey}]: extraction clear skipped because live turns changed before clear`,\n );\n }\n }\n if (!clearedLiveTurns) {\n await this.saveNowRetainingPendingOnFailure(\"clearAfterExtraction\");\n return;\n }\n } else {\n entry.turns = [];\n }\n entry.lastExtractionAt = new Date().toISOString();\n entry.extractionCount += 1;\n if (bufferKey === \"default\") {\n this.state.turns = entry.turns;\n this.state.lastExtractionAt = entry.lastExtractionAt;\n this.state.extractionCount = entry.extractionCount;\n }\n this.persistence.markDirty(bufferKey);\n this.pruneEntries([bufferKey]);\n await this.saveNowRetainingPendingOnFailure(\"clearAfterExtraction\");\n });\n }\n\n getExtractionCount(bufferKey = \"default\"): number {\n return this.peekEntry(bufferKey)?.extractionCount ?? 0;\n }\n\n /**\n * Await any pending `BUFFER_SURPRISE` telemetry writes.\n *\n * The telemetry path is fire-and-forget from the hot path's point of\n * view, but tests and before-exit hooks sometimes need to make sure\n * the ledger has been flushed before they assert on its contents or\n * close the process. This method resolves once the current chain\n * head has settled; new writes scheduled after this call return a\n * separate, later settlement.\n *\n * Never throws — the chain already catches its own rejections.\n */\n async flushSurpriseTelemetry(): Promise<void> {\n await this.surpriseTelemetryWriteChain;\n }\n}\n"],"mappings":"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","names":[]}