@graphrefly/graphrefly 0.40.0 → 0.42.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (296) hide show
  1. package/dist/{cascading-Cxs1eztH.d.cts → cascading-CH-_VwG9.d.cts} +2 -2
  2. package/dist/{cascading-BNfxffgc.d.ts → cascading-OgKQZjsa.d.ts} +2 -2
  3. package/dist/{chunk-CKFQS2CJ.js → chunk-2K5RXLAH.js} +1 -1
  4. package/dist/chunk-3ERTUW2J.js +45 -0
  5. package/dist/chunk-3K7HA4Y6.js +1 -0
  6. package/dist/chunk-3ZZX7M25.js +1 -0
  7. package/dist/chunk-4QH6VJF4.js +1 -0
  8. package/dist/{chunk-I2DEVPMU.js → chunk-5QRRKBUT.js} +1 -1
  9. package/dist/chunk-5ST42ESJ.js +1 -0
  10. package/dist/{chunk-FHRBBHJN.js → chunk-6YFZMUMR.js} +1 -1
  11. package/dist/{chunk-MNZIKXK4.js → chunk-7ARY3Y3T.js} +1 -1
  12. package/dist/chunk-7B7ELAT2.js +1 -0
  13. package/dist/{chunk-Z4F3DOWS.js → chunk-7VKFXLZQ.js} +1 -1
  14. package/dist/chunk-ACMJ2ZPS.js +3 -0
  15. package/dist/{chunk-32N3JALT.js → chunk-AGNM6RS6.js} +1 -1
  16. package/dist/chunk-AS3TV2TV.js +1 -0
  17. package/dist/{chunk-B7LCDQEV.js → chunk-CISGGAIF.js} +1 -1
  18. package/dist/{chunk-N43XM7BM.js → chunk-DEJTNNQC.js} +1 -1
  19. package/dist/{chunk-2QXRYP7Q.js → chunk-FDZAZNRO.js} +1 -1
  20. package/dist/{chunk-QSK3RRII.js → chunk-FUZ6S2DY.js} +1 -1
  21. package/dist/{chunk-LYM4PBMV.js → chunk-G5VBJ5K6.js} +1 -1
  22. package/dist/{chunk-6I726LZU.js → chunk-HZKW2AAB.js} +1 -1
  23. package/dist/{chunk-LCGAVGGV.js → chunk-IZM3UEH3.js} +3 -3
  24. package/dist/{chunk-2DMKW2AD.js → chunk-KCACBSJH.js} +1 -1
  25. package/dist/{chunk-SSCGRYJ2.js → chunk-KT5DTRBP.js} +1 -1
  26. package/dist/{chunk-WL6LFPJB.js → chunk-KY2LMAXU.js} +1 -1
  27. package/dist/{chunk-YXDRGKXP.js → chunk-LDQ3IUIP.js} +1 -1
  28. package/dist/chunk-LPRWATHB.js +61 -0
  29. package/dist/{chunk-6VWBPSSY.js → chunk-NWXQIOIB.js} +3 -3
  30. package/dist/{chunk-XW4YDF6G.js → chunk-Q7QQQA3I.js} +1 -1
  31. package/dist/chunk-VE5SIZEM.js +1 -0
  32. package/dist/chunk-VRALOYRD.js +1 -0
  33. package/dist/{chunk-XJLYLLIJ.js → chunk-WHMUB5QB.js} +1 -1
  34. package/dist/chunk-XLQPNNIC.js +1 -0
  35. package/dist/{chunk-JKBOIJ22.js → chunk-YGL7FPVQ.js} +1 -1
  36. package/dist/compat/index.cjs +5 -5
  37. package/dist/compat/index.d.cts +16 -16
  38. package/dist/compat/index.d.ts +16 -16
  39. package/dist/compat/index.js +1 -1
  40. package/dist/compat/jotai/index.d.cts +2 -2
  41. package/dist/compat/jotai/index.d.ts +2 -2
  42. package/dist/compat/nanostores/index.d.cts +2 -2
  43. package/dist/compat/nanostores/index.d.ts +2 -2
  44. package/dist/compat/nestjs/index.cjs +5 -5
  45. package/dist/compat/nestjs/index.d.cts +8 -8
  46. package/dist/compat/nestjs/index.d.ts +8 -8
  47. package/dist/compat/nestjs/index.js +1 -1
  48. package/dist/compat/react/index.d.cts +2 -2
  49. package/dist/compat/react/index.d.ts +2 -2
  50. package/dist/compat/solid/index.d.cts +2 -2
  51. package/dist/compat/solid/index.d.ts +2 -2
  52. package/dist/compat/svelte/index.d.cts +2 -2
  53. package/dist/compat/svelte/index.d.ts +2 -2
  54. package/dist/compat/vue/index.d.cts +2 -2
  55. package/dist/compat/vue/index.d.ts +2 -2
  56. package/dist/compat/zustand/index.cjs +3 -3
  57. package/dist/compat/zustand/index.d.cts +4 -4
  58. package/dist/compat/zustand/index.d.ts +4 -4
  59. package/dist/compat/zustand/index.js +1 -1
  60. package/dist/core/index.d.cts +4 -4
  61. package/dist/core/index.d.ts +4 -4
  62. package/dist/{decay-C25AyNAj.d.cts → decay-2ZukgQ4o.d.cts} +2 -2
  63. package/dist/{decay-BnrlbxSv.d.ts → decay-CdEBmDIs.d.ts} +2 -2
  64. package/dist/extra/browser.d.cts +1 -1
  65. package/dist/extra/browser.d.ts +1 -1
  66. package/dist/extra/index.cjs +14 -14
  67. package/dist/extra/index.d.cts +10 -11
  68. package/dist/extra/index.d.ts +10 -11
  69. package/dist/extra/index.js +1 -1
  70. package/dist/extra/node.cjs +2 -2
  71. package/dist/extra/node.d.cts +1 -1
  72. package/dist/extra/node.d.ts +1 -1
  73. package/dist/extra/node.js +1 -1
  74. package/dist/extra/operators.cjs +1 -1
  75. package/dist/extra/operators.d.cts +1 -1
  76. package/dist/extra/operators.d.ts +1 -1
  77. package/dist/extra/operators.js +1 -1
  78. package/dist/extra/reactive.d.cts +3 -3
  79. package/dist/extra/reactive.d.ts +3 -3
  80. package/dist/extra/reactive.js +1 -1
  81. package/dist/extra/render/index.d.cts +3 -3
  82. package/dist/extra/render/index.d.ts +3 -3
  83. package/dist/extra/sources.cjs +3 -1
  84. package/dist/extra/sources.d.cts +1 -1
  85. package/dist/extra/sources.d.ts +1 -1
  86. package/dist/extra/sources.js +1 -1
  87. package/dist/extra/storage-browser.d.cts +1 -1
  88. package/dist/extra/storage-browser.d.ts +1 -1
  89. package/dist/{fallback-CMZl39L5.d.ts → fallback-CqYVLL6X.d.ts} +1 -1
  90. package/dist/{fallback-8JYU8tlT.d.cts → fallback-Ctlj2tMY.d.cts} +1 -1
  91. package/dist/graph/index.cjs +7 -7
  92. package/dist/graph/index.d.cts +5 -5
  93. package/dist/graph/index.d.ts +5 -5
  94. package/dist/graph/index.js +1 -1
  95. package/dist/{graph-BkIkog4h.d.ts → graph-7VguS7a4.d.ts} +3 -3
  96. package/dist/{graph-E6likq7w.d.cts → graph-C4SHb3Ly.d.cts} +3 -3
  97. package/dist/{index-DktLSZOc.d.cts → index-2B7u2pVn.d.cts} +4 -4
  98. package/dist/{index-BTHOTC0Q.d.cts → index-3NmAfcH0.d.cts} +25 -7
  99. package/dist/{index-D1IEZUsj.d.ts → index-4Uz-e_fL.d.ts} +573 -213
  100. package/dist/{index-BAQrjuZF.d.ts → index-B-i4_g3k.d.ts} +2 -2
  101. package/dist/{index-DpiGqtrs.d.cts → index-B11anra4.d.cts} +441 -381
  102. package/dist/{index-WSlcjhQF.d.ts → index-B3OTH1dV.d.ts} +124 -13
  103. package/dist/{index-2n8Eai6M.d.ts → index-BG0BN3PB.d.ts} +1 -1
  104. package/dist/{index-z8WFPVI8.d.cts → index-BJX94aud.d.cts} +1 -1
  105. package/dist/{index-DhLyOHYZ.d.ts → index-BP8a88zx.d.ts} +11 -4
  106. package/dist/{index-Cnr1WrlX.d.cts → index-BTQtTb_H.d.cts} +14 -3
  107. package/dist/{index-BaA-xpSw.d.ts → index-BUYXac2c.d.ts} +3 -3
  108. package/dist/{index-DOBLxOti.d.cts → index-BVpm6noz.d.cts} +1 -1
  109. package/dist/{index-DhnsQfa3.d.ts → index-Bbkgpt5t.d.ts} +441 -381
  110. package/dist/{index-Cczxgd2D.d.ts → index-Bc41FuHp.d.cts} +3 -3
  111. package/dist/{index-BiHUBEKq.d.cts → index-BdGtBX-X.d.cts} +3 -3
  112. package/dist/index-BeT2r7sk.d.ts +760 -0
  113. package/dist/{index-da2V5vPy.d.ts → index-Bf7eqeSF.d.ts} +2 -2
  114. package/dist/{index-bXXLSvor.d.ts → index-Bn4zHYLj.d.ts} +4 -4
  115. package/dist/{index-DGTo1yka.d.cts → index-BoLv_OfD.d.cts} +2 -2
  116. package/dist/{index-B72TQQHd.d.cts → index-BsT7F2et.d.ts} +3 -3
  117. package/dist/{index-Bd91Nmf4.d.cts → index-BtAsBp8K.d.cts} +4 -4
  118. package/dist/{index-DgJc8Zgc.d.cts → index-C0-Jv1kP.d.cts} +81 -5
  119. package/dist/{index-C6ZUaos7.d.ts → index-C7O6r5fV.d.ts} +1 -1
  120. package/dist/{index-CL7oilfm.d.cts → index-C9kSENB4.d.cts} +1 -1
  121. package/dist/{index-yLt-aPMp.d.ts → index-CCq87F7t.d.ts} +1 -1
  122. package/dist/{index-DQQCOIt8.d.cts → index-CEMx8n40.d.cts} +10 -5
  123. package/dist/{index-BilOa6AE.d.cts → index-CJIuLu2f.d.cts} +124 -13
  124. package/dist/{index-B2RUoIUz.d.ts → index-CJK1JkYy.d.ts} +1 -1
  125. package/dist/{index-IUCY0OFN.d.ts → index-CJQm0g38.d.ts} +25 -7
  126. package/dist/index-CPNSy-U0.d.cts +760 -0
  127. package/dist/{index-A3U3CSve.d.cts → index-CZjOhcBy.d.cts} +2 -2
  128. package/dist/{index-CAP3UGsq.d.ts → index-CZmcDtFn.d.ts} +1 -1
  129. package/dist/{index-DYTBbF8T.d.cts → index-ChOyVLKm.d.cts} +1 -1
  130. package/dist/{index-eaQuGJnv.d.ts → index-CpyNFqkB.d.ts} +3 -3
  131. package/dist/{index-BJSZxSFX.d.ts → index-CvrqGfNS.d.ts} +1 -1
  132. package/dist/{index-DJ_MPOJ5.d.cts → index-D-Xs74HZ.d.cts} +573 -213
  133. package/dist/{index-C5cQ7Gfx.d.ts → index-D6egPFAL.d.ts} +4 -4
  134. package/dist/{index-CD2dBMet.d.ts → index-D8l8hNXn.d.ts} +10 -5
  135. package/dist/{index-40ZT4MHj.d.ts → index-DBHK8O6H.d.ts} +14 -3
  136. package/dist/{index-DVDapw2k.d.cts → index-DBIqYS43.d.cts} +35 -21
  137. package/dist/{index-3k4Gg6-n.d.ts → index-DBevwHj_.d.ts} +3 -3
  138. package/dist/{index-Ctb7_2sG.d.ts → index-DIOoAZUX.d.ts} +1 -1
  139. package/dist/{index-BQ1fR4li.d.ts → index-DO9XxMzS.d.ts} +35 -21
  140. package/dist/{index-CQtWm7jS.d.ts → index-DQo8xBgd.d.ts} +9 -9
  141. package/dist/{index-DH4fm2Ck.d.ts → index-Dgs8zcj7.d.ts} +2 -2
  142. package/dist/{index-CtFNGe-m.d.cts → index-Dhc7a7Xo.d.cts} +2 -2
  143. package/dist/{index-MxYuWOrf.d.cts → index-DmAgG5CI.d.cts} +3 -3
  144. package/dist/{index-CoM4rzyB.d.ts → index-Dmqp7KjD.d.ts} +1 -1
  145. package/dist/{index-B6iTqKtJ.d.ts → index-Dn-wI9g4.d.ts} +2 -2
  146. package/dist/{index-C-dkXOpB.d.cts → index-Du7u1lSf.d.cts} +11 -4
  147. package/dist/{index-DVAlsmEU.d.cts → index-HoU88d5U.d.cts} +3 -3
  148. package/dist/{index-CRm0YIzC.d.cts → index-LIpQQE9f.d.cts} +9 -9
  149. package/dist/{index-CgnCFhr2.d.cts → index-f5IivDUX.d.cts} +1 -1
  150. package/dist/{index-PgwvGWa1.d.cts → index-hHcaFlJX.d.cts} +1 -1
  151. package/dist/{index-I1cCY3ZI.d.ts → index-pT8sCpOJ.d.ts} +81 -5
  152. package/dist/{index-D4uimgee.d.cts → index-sl4NyzQx.d.cts} +1 -1
  153. package/dist/{index-tV3AA9hI.d.cts → index-tJoTcnHh.d.cts} +2 -2
  154. package/dist/{index-D3ayz3hy.d.cts → index-z96luz5O.d.cts} +1 -1
  155. package/dist/index.cjs +48 -48
  156. package/dist/index.d.cts +45 -50
  157. package/dist/index.d.ts +45 -50
  158. package/dist/index.js +1 -1
  159. package/dist/{meta-D8OyedKp.d.ts → meta-BgVAsg9j.d.ts} +1 -1
  160. package/dist/{meta-Ct9nqQS5.d.cts → meta-vE8bxW1E.d.cts} +1 -1
  161. package/dist/{node-BYInONRr.d.cts → node-ClS5yC-B.d.cts} +1 -1
  162. package/dist/{node-BYInONRr.d.ts → node-ClS5yC-B.d.ts} +1 -1
  163. package/dist/{observable-DO8DDEzv.d.ts → observable-BsBzUrcI.d.ts} +1 -1
  164. package/dist/{observable-DMIlYJV1.d.cts → observable-DLGPPtb8.d.cts} +1 -1
  165. package/dist/patterns/ai/browser.d.cts +4 -4
  166. package/dist/patterns/ai/browser.d.ts +4 -4
  167. package/dist/patterns/ai/browser.js +1 -1
  168. package/dist/patterns/ai/index.cjs +17 -17
  169. package/dist/patterns/ai/index.d.cts +17 -17
  170. package/dist/patterns/ai/index.d.ts +17 -17
  171. package/dist/patterns/ai/index.js +1 -1
  172. package/dist/patterns/ai/node.d.cts +4 -4
  173. package/dist/patterns/ai/node.d.ts +4 -4
  174. package/dist/patterns/ai/node.js +1 -1
  175. package/dist/patterns/cqrs/index.cjs +3 -3
  176. package/dist/patterns/cqrs/index.d.cts +6 -6
  177. package/dist/patterns/cqrs/index.d.ts +6 -6
  178. package/dist/patterns/cqrs/index.js +1 -1
  179. package/dist/patterns/demo-shell/index.cjs +5 -5
  180. package/dist/patterns/demo-shell/index.d.cts +5 -5
  181. package/dist/patterns/demo-shell/index.d.ts +5 -5
  182. package/dist/patterns/demo-shell/index.js +1 -1
  183. package/dist/patterns/domain-templates/index.cjs +3 -3
  184. package/dist/patterns/domain-templates/index.d.cts +4 -4
  185. package/dist/patterns/domain-templates/index.d.ts +4 -4
  186. package/dist/patterns/domain-templates/index.js +1 -1
  187. package/dist/patterns/graphspec/index.cjs +12 -12
  188. package/dist/patterns/graphspec/index.d.cts +5 -5
  189. package/dist/patterns/graphspec/index.d.ts +5 -5
  190. package/dist/patterns/graphspec/index.js +1 -1
  191. package/dist/patterns/harness/index.cjs +10 -8
  192. package/dist/patterns/harness/index.d.cts +11 -12
  193. package/dist/patterns/harness/index.d.ts +11 -12
  194. package/dist/patterns/harness/index.js +1 -1
  195. package/dist/patterns/inspect/index.cjs +3 -0
  196. package/dist/patterns/inspect/index.d.cts +9 -0
  197. package/dist/patterns/inspect/index.d.ts +9 -0
  198. package/dist/patterns/inspect/index.js +1 -0
  199. package/dist/patterns/job-queue/index.cjs +3 -3
  200. package/dist/patterns/job-queue/index.d.cts +6 -6
  201. package/dist/patterns/job-queue/index.d.ts +6 -6
  202. package/dist/patterns/job-queue/index.js +1 -1
  203. package/dist/patterns/memory/index.cjs +3 -3
  204. package/dist/patterns/memory/index.d.cts +6 -6
  205. package/dist/patterns/memory/index.d.ts +6 -6
  206. package/dist/patterns/memory/index.js +1 -1
  207. package/dist/patterns/messaging/index.cjs +3 -3
  208. package/dist/patterns/messaging/index.d.cts +5 -5
  209. package/dist/patterns/messaging/index.d.ts +5 -5
  210. package/dist/patterns/messaging/index.js +1 -1
  211. package/dist/patterns/orchestration/index.cjs +3 -3
  212. package/dist/patterns/orchestration/index.d.cts +7 -7
  213. package/dist/patterns/orchestration/index.d.ts +7 -7
  214. package/dist/patterns/orchestration/index.js +1 -1
  215. package/dist/patterns/process/index.cjs +1 -1
  216. package/dist/patterns/process/index.d.cts +7 -7
  217. package/dist/patterns/process/index.d.ts +7 -7
  218. package/dist/patterns/process/index.js +1 -1
  219. package/dist/patterns/reactive-layout/index.cjs +4 -4
  220. package/dist/patterns/reactive-layout/index.d.cts +5 -5
  221. package/dist/patterns/reactive-layout/index.d.ts +5 -5
  222. package/dist/patterns/reactive-layout/index.js +1 -1
  223. package/dist/patterns/reduction/index.cjs +3 -3
  224. package/dist/patterns/reduction/index.d.cts +4 -4
  225. package/dist/patterns/reduction/index.d.ts +4 -4
  226. package/dist/patterns/reduction/index.js +1 -1
  227. package/dist/patterns/surface/index.cjs +8 -8
  228. package/dist/patterns/surface/index.d.cts +6 -6
  229. package/dist/patterns/surface/index.d.ts +6 -6
  230. package/dist/patterns/surface/index.js +1 -1
  231. package/dist/{pipeline-graph-MWrQZXCq.d.cts → pipeline-graph-WBlobVhU.d.cts} +5 -5
  232. package/dist/{pipeline-graph-CB4La-UW.d.ts → pipeline-graph-v8fMvqNk.d.ts} +5 -5
  233. package/dist/{reactive-layout-BtZfUKuL.d.cts → reactive-layout-Dsvob4zD.d.cts} +2 -2
  234. package/dist/{reactive-layout-KJj4E2dT.d.ts → reactive-layout-v7KPvxoc.d.ts} +2 -2
  235. package/dist/{reactive-log-_zeEnB9H.d.cts → reactive-log-B00laMSQ.d.cts} +1 -1
  236. package/dist/{reactive-log-BlAsPLl2.d.ts → reactive-log-BezYsbA_.d.ts} +1 -1
  237. package/dist/{reactive-map-6P_k3AQM.d.cts → reactive-map-48mnZ-nu.d.cts} +1 -1
  238. package/dist/{reactive-map-CjXByDV-.d.ts → reactive-map-BVVPdvmi.d.ts} +1 -1
  239. package/dist/resilience-445VFFXQ.js +1 -0
  240. package/dist/{sugar-BhfjgetH.d.ts → sugar-CH-2ZY90.d.ts} +1 -1
  241. package/dist/{sugar-DzePN5-g.d.cts → sugar-DStZfUEK.d.cts} +1 -1
  242. package/dist/{topology-tree-mF7Emqzm.d.ts → topology-tree-BNGvuG82.d.ts} +1 -1
  243. package/dist/{topology-tree-3LBKFsUo.d.cts → topology-tree-BSdfSwMi.d.cts} +1 -1
  244. package/dist/{types-1Dhoi7HM.d.cts → types-B1jDWVsM.d.cts} +1 -1
  245. package/dist/{types-39jk0kaV.d.ts → types-DkzUUs0H.d.ts} +1 -1
  246. package/package.json +11 -51
  247. package/dist/budget-gate-CmmVtasH.d.ts +0 -115
  248. package/dist/budget-gate-DiP_nK0n.d.cts +0 -115
  249. package/dist/chunk-2BX4NB34.js +0 -3
  250. package/dist/chunk-6XVD5TZV.js +0 -1
  251. package/dist/chunk-756D5TFD.js +0 -1
  252. package/dist/chunk-7Q4ZD3YW.js +0 -1
  253. package/dist/chunk-ECQRP2UT.js +0 -1
  254. package/dist/chunk-INQFTVZA.js +0 -61
  255. package/dist/chunk-J63M5U46.js +0 -1
  256. package/dist/chunk-K2Z7UENB.js +0 -1
  257. package/dist/chunk-OSZ22J7O.js +0 -1
  258. package/dist/chunk-PPUYQ66A.js +0 -1
  259. package/dist/chunk-RZJDIV2G.js +0 -1
  260. package/dist/chunk-SGS4OJGS.js +0 -1
  261. package/dist/chunk-SVFKHUCW.js +0 -1
  262. package/dist/chunk-UWA6D7UF.js +0 -3
  263. package/dist/chunk-VMF23LGB.js +0 -1
  264. package/dist/chunk-WUT362QV.js +0 -1
  265. package/dist/chunk-YKD7WUYJ.js +0 -43
  266. package/dist/index-8s-Qm-gz.d.ts +0 -218
  267. package/dist/index-BgjS2b8N.d.ts +0 -366
  268. package/dist/index-BmSQLAZo.d.cts +0 -244
  269. package/dist/index-CGhMJNHb.d.cts +0 -128
  270. package/dist/index-CUIkE1l9.d.cts +0 -230
  271. package/dist/index-Ck35nA-T.d.ts +0 -244
  272. package/dist/index-CuPUehFa.d.cts +0 -218
  273. package/dist/index-D1Gc7wV5.d.ts +0 -230
  274. package/dist/index-N2MAxt7_.d.ts +0 -128
  275. package/dist/index-t6L2qpHh.d.cts +0 -366
  276. package/dist/patterns/audit/index.cjs +0 -3
  277. package/dist/patterns/audit/index.d.cts +0 -8
  278. package/dist/patterns/audit/index.d.ts +0 -8
  279. package/dist/patterns/audit/index.js +0 -1
  280. package/dist/patterns/guarded-execution/index.cjs +0 -3
  281. package/dist/patterns/guarded-execution/index.d.cts +0 -9
  282. package/dist/patterns/guarded-execution/index.d.ts +0 -9
  283. package/dist/patterns/guarded-execution/index.js +0 -1
  284. package/dist/patterns/lens/index.cjs +0 -3
  285. package/dist/patterns/lens/index.d.cts +0 -7
  286. package/dist/patterns/lens/index.d.ts +0 -7
  287. package/dist/patterns/lens/index.js +0 -1
  288. package/dist/patterns/refine-loop/index.cjs +0 -5
  289. package/dist/patterns/refine-loop/index.d.cts +0 -9
  290. package/dist/patterns/refine-loop/index.d.ts +0 -9
  291. package/dist/patterns/refine-loop/index.js +0 -1
  292. package/dist/patterns/resilient-pipeline/index.cjs +0 -3
  293. package/dist/patterns/resilient-pipeline/index.d.cts +0 -8
  294. package/dist/patterns/resilient-pipeline/index.d.ts +0 -8
  295. package/dist/patterns/resilient-pipeline/index.js +0 -1
  296. package/dist/resilience-S33JV6XC.js +0 -1
@@ -1,18 +1,18 @@
1
- import { T as TokenUsage, L as LLMAdapter, P as PricingFn, C as ChatMessage, a as LLMInvokeOptions, d as ToolDefinition, b as LLMResponse, S as StreamDelta, c as ToolCall, e as CapabilitiesRegistry, M as ModelCapabilities, f as ModelFeatures, g as ModelLimits, h as ModelPricing, i as PriceBreakdown, j as PricingRegistry, R as Rate, k as TieredRate, l as composePricing, m as computePrice, n as createCapabilitiesRegistry, o as createPricingRegistry, p as pricingFor, r as registryPricing, z as zeroPrice } from './types-1Dhoi7HM.cjs';
2
- import { a as CascadeExhaustionReport, A as AdapterProvider, b as AdapterTier, d as AllTiersExhaustedError, C as CascadingLlmAdapterOptions, e as CreateAdapterOptions, O as OpenAICompatAdapterOptions, f as OpenAICompatPreset, g as OpenAISdkLike, h as cascadingLlmAdapter, c as createAdapter, o as openAICompatAdapter, t as tier } from './cascading-Cxs1eztH.cjs';
3
- import { N as Node, A as Actor } from './node-BYInONRr.cjs';
4
- import { a as ReactiveLogBundle } from './reactive-log-_zeEnB9H.cjs';
5
- import { b as CircuitBreakerOptions, f as CircuitBreaker, g as CircuitOpenError } from './index-DGTo1yka.cjs';
1
+ import { T as TokenUsage, L as LLMAdapter, P as PricingFn, C as ChatMessage, a as LLMInvokeOptions, d as ToolDefinition, b as LLMResponse, S as StreamDelta, c as ToolCall, e as CapabilitiesRegistry, M as ModelCapabilities, f as ModelFeatures, g as ModelLimits, h as ModelPricing, i as PriceBreakdown, j as PricingRegistry, R as Rate, k as TieredRate, l as composePricing, m as computePrice, n as createCapabilitiesRegistry, o as createPricingRegistry, p as pricingFor, r as registryPricing, z as zeroPrice } from './types-B1jDWVsM.cjs';
2
+ import { a as CascadeExhaustionReport, A as AdapterProvider, b as AdapterTier, d as AllTiersExhaustedError, C as CascadingLlmAdapterOptions, e as CreateAdapterOptions, O as OpenAICompatAdapterOptions, f as OpenAICompatPreset, g as OpenAISdkLike, h as cascadingLlmAdapter, c as createAdapter, o as openAICompatAdapter, t as tier } from './cascading-CH-_VwG9.cjs';
3
+ import { N as Node, A as Actor } from './node-ClS5yC-B.cjs';
4
+ import { a as ReactiveLogBundle } from './reactive-log-B00laMSQ.cjs';
5
+ import { b as CircuitBreakerOptions, C as CircuitBreaker, c as CircuitOpenError } from './index-BoLv_OfD.cjs';
6
6
  import { NodeInput } from './extra/sources.cjs';
7
- import { W as WithReplayCacheOptions, F as FallbackAdapterOptions, a as FallbackFixture, b as FallbackMissError, c as FallbackMissPolicy, R as ReplayCacheKeyContext, d as ReplayCacheMissError, e as ReplayCacheMode, f as canonicalJson, g as fallbackAdapter, w as withReplayCache } from './fallback-8JYU8tlT.cjs';
8
- import { E as Extraction, D as DistillBundle, f as DEFAULT_DECAY_RATE } from './decay-C25AyNAj.cjs';
9
- import { G as Graph, a as GraphOptions, k as GraphCheckpointRecord, j as GraphAttachStorageOptions } from './graph-E6likq7w.cjs';
10
- import { T as TopicGraph } from './index-Cnr1WrlX.cjs';
11
- import { G as GateController, c as GateOptions } from './pipeline-graph-MWrQZXCq.cjs';
12
- import { V as VectorSearchResult, C as CollectionGraph, a as VectorIndexGraph, K as KnowledgeGraph } from './index-DktLSZOc.cjs';
7
+ import { W as WithReplayCacheOptions, F as FallbackAdapterOptions, a as FallbackFixture, b as FallbackMissError, c as FallbackMissPolicy, R as ReplayCacheKeyContext, d as ReplayCacheMissError, e as ReplayCacheMode, f as canonicalJson, g as fallbackAdapter, w as withReplayCache } from './fallback-Ctlj2tMY.cjs';
8
+ import { E as Extraction, D as DistillBundle, f as DEFAULT_DECAY_RATE } from './decay-2ZukgQ4o.cjs';
9
+ import { G as Graph, a as GraphOptions, i as GraphCheckpointRecord, h as GraphAttachStorageOptions } from './graph-C4SHb3Ly.cjs';
10
+ import { T as TopicGraph } from './index-BTQtTb_H.cjs';
11
+ import { G as GateController, c as GateOptions } from './pipeline-graph-WBlobVhU.cjs';
12
+ import { V as VectorSearchResult, C as CollectionGraph, a as VectorIndexGraph, K as KnowledgeGraph } from './index-2B7u2pVn.cjs';
13
13
  import { StorageHandle } from './extra/storage-core.cjs';
14
14
  import { SnapshotStorageTier } from './extra/storage-tiers.cjs';
15
- import { c as GraphSpecCatalog } from './index-C-dkXOpB.cjs';
15
+ import { c as GraphSpecCatalog } from './index-Du7u1lSf.cjs';
16
16
 
17
17
  /**
18
18
  * Observable adapter wrapper — the "inverted statistics" surface.
@@ -939,6 +939,48 @@ declare function llmExtractor<TRaw, TMem>(systemPrompt: string, opts: LLMExtract
939
939
  */
940
940
  declare function llmConsolidator<TMem>(systemPrompt: string, opts: LLMConsolidatorOptions): (entries: ReadonlyMap<string, TMem>) => NodeInput<Extraction<TMem>>;
941
941
 
942
+ /**
943
+ * `promptNode` — universal LLM transform as a reactive derived node.
944
+ *
945
+ * The shape: `deps → messagesNode (derived) → switchMap → call (producer) → output`.
946
+ * Each upstream wave is one LLM call; superseding waves cancel the in-flight
947
+ * call via the abort signal threaded through `nodeSignal(opts.abort)`.
948
+ *
949
+ * The producer-shape on the inner is load-bearing: it emits exactly one DATA
950
+ * + COMPLETE per wave, so the outer switchMap sees one DATA per wave (matches
951
+ * the `HarnessExecutor` contract). A `derived([call], parse)` would have its
952
+ * own first-run / push-on-subscribe semantics that can leak a transient null
953
+ * before the real response arrives — observed and reverted in an earlier
954
+ * attempt; see SESSION-ai-harness-module-review.md line 3654 for context.
955
+ * Locked as path (b) producer-based by Session C (2026-04-27).
956
+ *
957
+ * **Retry / replay-cache.** Stack middleware on the adapter:
958
+ *
959
+ * ```ts
960
+ * import { withRetry, withReplayCache } from "@graphrefly/graphrefly/patterns/ai";
961
+ *
962
+ * const adapter = withRetry(
963
+ * withReplayCache(baseAdapter, { keyFn: (ctx) => ctx.messages[0].content }),
964
+ * { count: 3, backoff: 200 },
965
+ * );
966
+ * const result = promptNode(adapter, [input], (q) => q);
967
+ * ```
968
+ *
969
+ * `promptNode` no longer ships `retries` / `cache` options — they duplicated
970
+ * middleware already at the adapter layer.
971
+ *
972
+ * **Cross-wave cache (COMPOSITION-GUIDE §32).** The switchMap output cache
973
+ * survives across new outer DATAs — `promptNode`'s cached value persists
974
+ * until the next wave fully resolves. Consumers that need to distinguish
975
+ * "fresh value for THIS session" from "stale cache from a prior session"
976
+ * (e.g. `agentLoop` resetting on new `run()`) must add a `state()` mirror
977
+ * at their session boundary and depend on the mirror, not the `promptNode`
978
+ * output directly. `promptNode` itself stays primitive — it does not
979
+ * embed a state-mirror.
980
+ *
981
+ * @module
982
+ */
983
+
942
984
  type PromptNodeOptions = {
943
985
  name?: string;
944
986
  model?: string;
@@ -954,11 +996,26 @@ type PromptNodeOptions = {
954
996
  */
955
997
  format?: "text" | "json" | "raw";
956
998
  /**
957
- * Optional tool definitions forwarded to the adapter. Pair with
999
+ * Reactive tool definitions forwarded to the adapter. Pair with
958
1000
  * `format: "raw"` (or read `toolCalls` from a downstream parser) when
959
1001
  * tool-calling is in scope.
1002
+ *
1003
+ * **Reactive declared edge** (DF12, Tier 7): `tools` is a `Node` so the
1004
+ * tools list participates in `describe()` topology and `explain()` causal
1005
+ * chains. The tools Node is added to `messagesNode`'s declared deps —
1006
+ * tools changes re-invoke the LLM (treated as a new call envelope).
1007
+ * Wrap with `distinctUntilChanged` upstream if your tool selector emits
1008
+ * noisy duplicates that would otherwise spam the adapter. See
1009
+ * COMPOSITION-GUIDE §31 (Dynamic tool selection) for the canonical
1010
+ * `toolSelector` pattern that produces this Node.
1011
+ *
1012
+ * **Activation note:** since `tools` is a real declared dep, `messagesNode`
1013
+ * waits for the tools Node to DATA at least once before firing
1014
+ * (push-on-subscribe SENTINEL gate). Pass a `state<ToolDefinition[]>([])`
1015
+ * if you want immediate activation with no tools, or the latest published
1016
+ * `toolSelector.tools` Node.
960
1017
  */
961
- tools?: readonly ToolDefinition[];
1018
+ tools?: Node<readonly ToolDefinition[]>;
962
1019
  /**
963
1020
  * Optional system prompt. Forwarded via `opts.systemPrompt` to the adapter
964
1021
  * only — never pushed as a `{role:"system"}` message (avoiding the
@@ -982,10 +1039,13 @@ type PromptNodeOptions = {
982
1039
  *
983
1040
  * **Topology** (visible in `describe()`):
984
1041
  * ```
985
- * <deps...> → <name>::messages (derived, meta.ai = prompt_node)
986
- * <name>::messages → <name>::output (switchMap product, meta.ai = prompt_node::output)
987
- * per-wave inner: <name>::call (producer, meta.ai = prompt_node::call)
1042
+ * <deps...>, [tools?] → <name>::messages (derived, meta.ai = prompt_node)
1043
+ * <name>::messages → <name>::output (switchMap product, meta.ai = prompt_node::output)
1044
+ * per-wave inner: <name>::call (producer, meta.ai = prompt_node::call)
988
1045
  * ```
1046
+ * When `opts.tools` is supplied, the tools `Node` is appended to
1047
+ * `messagesNode`'s declared deps so it appears as a real edge in `describe()`
1048
+ * / `explain()` (DF12, Tier 7).
989
1049
  *
990
1050
  * **No-input semantics** (matches the codebase-wide SENTINEL convention):
991
1051
  * - **Initial no-input** (no real input has ever arrived) — emits nothing.
@@ -1390,6 +1450,77 @@ declare class ChatStreamGraph extends Graph {
1390
1450
  }
1391
1451
  declare function chatStream(name: string, opts?: ChatStreamOptions): ChatStreamGraph;
1392
1452
 
1453
+ /**
1454
+ * Options for {@link handoff}.
1455
+ */
1456
+ type HandoffOptions = {
1457
+ /**
1458
+ * Reactive gate: when this node's value is `true`, output flows from
1459
+ * `from` to the `to` specialist; when `false`, `from`'s output flows
1460
+ * through unchanged and `to` stays dormant. Omit to always hand off —
1461
+ * useful when `from` is itself a router whose output shape already
1462
+ * encodes routing intent.
1463
+ */
1464
+ condition?: NodeInput<boolean>;
1465
+ name?: string;
1466
+ };
1467
+ /**
1468
+ * Multi-agent handoff recipe — route `from`'s output into a specialist
1469
+ * agent `toFactory` when `condition` is open. Thin composition over
1470
+ * `switchMap` + gate; not a new primitive, just a named shape.
1471
+ *
1472
+ * The "handoff" pattern (popularized by the OpenAI Agents SDK) covers two
1473
+ * idioms:
1474
+ *
1475
+ * 1. **Full handoff** — a triage agent routes the conversation to a
1476
+ * specialist, and the specialist becomes the active agent for the rest
1477
+ * of the turn. Accumulated context (memory, tool definitions) can travel
1478
+ * along by threading the same `agentMemory` bundle into both.
1479
+ * 2. **Agents-as-tools** — the manager keeps control and calls the
1480
+ * specialist like a tool for a bounded subtask. Build this by registering
1481
+ * a `promptNode` instance as a `ToolDefinition` on the parent via
1482
+ * `toolRegistry`.
1483
+ *
1484
+ * This sugar covers (1) — a reactive route from one agent's output into a
1485
+ * specialist factory. For (2) wire a tool registry manually; the pattern is
1486
+ * additive with this one.
1487
+ *
1488
+ * @example Full handoff on a triage signal.
1489
+ * ```ts
1490
+ * import { handoff, promptNode } from "@graphrefly/graphrefly/patterns/ai";
1491
+ *
1492
+ * const triage = promptNode(adapter, [userMessage], (msg) =>
1493
+ * `Classify urgency of: ${msg}. Reply "high" or "normal".`);
1494
+ * const isUrgent = derived([triage], ([v]) => v === "high");
1495
+ *
1496
+ * const specialist = handoff(
1497
+ * userMessage,
1498
+ * (input) => promptNode(specialistAdapter, [input], (m) => `Respond urgently: ${m}`),
1499
+ * { condition: isUrgent },
1500
+ * );
1501
+ * ```
1502
+ *
1503
+ * @param from - Source node whose value is threaded into the specialist.
1504
+ * @param toFactory - Factory that takes `from` (as a reactive source) and
1505
+ * returns the specialist node. Called once, lazily, when the first
1506
+ * subscriber activates.
1507
+ * @param opts - Optional reactive `condition` gate + name.
1508
+ * @returns Node emitting the specialist's output when the gate is open, or
1509
+ * `from`'s value when the gate is closed. Null when `from` is null.
1510
+ *
1511
+ * **Performance caveat (Wave A Unit 5):** the specialist is mounted per
1512
+ * source emission — each `v != null` DATA on `from` allocates a fresh
1513
+ * `state<T>(v)` + invokes `toFactory`, and switchMap cancels the prior
1514
+ * branch. For per-turn routing (≤1 emit/sec) this is negligible. For
1515
+ * high-frequency sources (per-token routing, tight event loops), batch
1516
+ * upstream (e.g. via `audit`, `throttle`, or `distinctUntilChanged`) before
1517
+ * handing off — each mount/unmount cycle spins up full subgraphs
1518
+ * (`messagesNode` + adapter bridge + output for a `promptNode` specialist).
1519
+ *
1520
+ * @category patterns.ai
1521
+ */
1522
+ declare function handoff<T>(from: NodeInput<T | null>, toFactory: (input: Node<T>) => Node<T | null>, opts?: HandoffOptions): Node<T | null>;
1523
+
1393
1524
  type ToolRegistryOptions = {
1394
1525
  graph?: GraphOptions;
1395
1526
  };
@@ -1527,258 +1658,50 @@ type ToolExecutionOptions = {
1527
1658
  declare function toolExecution(opts: ToolExecutionOptions): Node<readonly ToolResult[]>;
1528
1659
 
1529
1660
  /**
1530
- * Reactive agent loop — autonomous multi-turn LLM agent with tool execution.
1661
+ * Options for {@link toolSelector}.
1531
1662
  */
1532
- type AgentLoopStatus = "idle" | "thinking" | "acting" | "done" | "error";
1533
-
1534
- type AgentLoopOptions = {
1535
- graph?: GraphOptions;
1536
- adapter: LLMAdapter;
1537
- tools?: readonly ToolDefinition[];
1538
- systemPrompt?: string;
1539
- maxTurns?: number;
1540
- stopWhen?: (response: LLMResponse) => boolean;
1541
- onToolCall?: (call: ToolCall) => void;
1542
- maxMessages?: number;
1543
- model?: string;
1544
- temperature?: number;
1545
- maxTokens?: number;
1546
- /**
1547
- * Reactive tool-call splice (COMPOSITION-GUIDE §31 "interception is security").
1548
- * When set, the raw `toolCalls` node is piped through this transform before
1549
- * reaching the executor. The transform is a pure reactive composition —
1550
- * `(calls: Node<readonly ToolCall[]>) => Node<readonly ToolCall[]>` — so the
1551
- * gate is visible in `describe()` / `explain()` as a real edge (no hidden
1552
- * imperative wraps; §24).
1553
- *
1554
- * Typical uses:
1555
- * - **Filter / block** — `derived([calls, policy], ([raw, p]) => raw.filter(p))`
1556
- * - **Throttle / debounce** — `throttle(calls, windowMs)`
1557
- * - **Human-in-the-loop approval** — pipe through a `gate` controller so
1558
- * calls wait for human approval before reaching the executor.
1559
- *
1560
- * The public `agent.toolCalls` node surfaces the POST-intercept stream, so
1561
- * audit / telemetry consumers see what the executor actually runs. The raw
1562
- * pre-intercept stream is not exposed — tests that need it should run
1563
- * without `interceptToolCalls` set (the identity case).
1564
- */
1565
- interceptToolCalls?: (calls: Node<readonly ToolCall[]>) => Node<readonly ToolCall[]>;
1566
- };
1663
+ interface ToolSelectorOptions {
1664
+ readonly name?: string;
1665
+ }
1567
1666
  /**
1568
- * Reactive agent loop.
1569
- *
1570
- * The loop is a reactive state machine wired entirely from graph primitives:
1571
- * `chat.messages` + `tools.schemas` + gating state feed a `promptInput`
1572
- * derived; `switchMap` turns non-null inputs into an LLM invocation via
1573
- * `fromAny(adapter.invoke(...))`. The LLM response drives chat writes and
1574
- * status transitions via effects. Tool calls flow through a reactive
1575
- * executor (`retrySource` + `rescue`) that retries once on error and
1576
- * surfaces terminal errors as JSON-shaped `ToolResult` payloads for the
1577
- * LLM to react to.
1667
+ * Reactive tool availability (COMPOSITION-GUIDE §31). Given a base tool set
1668
+ * (reactive or static) and one or more reactive predicates, emit the filtered
1669
+ * subset of tools currently allowed. Feeds into `promptNode({ tools: Node<...> })`
1670
+ * so the LLM sees a reactive menu instead of a frozen config.
1578
1671
  *
1579
- * **No imperative control flow inside the reactive layer** (spec §5.8-5.12):
1580
- * no `while` loops, no manual `await adapter.invoke`, no polling.
1581
- * `agent.run()` is a thin `awaitSettled` bridge so callers can still `await`
1582
- * the loop if they want a Promise.
1672
+ * Each predicate is a `NodeInput<(tool) => boolean>`. A tool is included iff
1673
+ * **every** predicate returns `true`. When any predicate value is `null` /
1674
+ * `undefined` (e.g. upstream not yet ready) that predicate is treated as a
1675
+ * pass-through — the tool isn't excluded on its basis. Predicate updates
1676
+ * recompute the selected set.
1583
1677
  *
1584
- * Public surface:
1585
- * - `chat` / `tools` — subgraphs (imperative `append` at boundary, reactive `executeReactive` for tool invocation)
1586
- * - `status` / `turn` / `aborted` state nodes with explicit initials
1587
- * - `lastResponse` / `toolCalls` / `toolResults` reactive outputs (SENTINEL until first emission; callers use `awaitSettled` / `subscribe`)
1588
- * - `run(userMessage?, signal?)` optional user append + Promise bridge
1589
- * - `abort()` — imperative abort shim; flips `aborted` state
1678
+ * Pairs with `toolInterceptor` (§D9 / §31): **selection** controls what's
1679
+ * offered to the LLM (pre-generation UX); **interception** gates what's
1680
+ * executed after the LLM chooses (post-generation security). Tool selection
1681
+ * is NOT a security boundaryan LLM can hallucinate tool calls outside
1682
+ * its offered set; always pair with `toolInterceptor` for enforcement.
1590
1683
  *
1591
- * **Lifecycle: single-mount.** `AgentLoopGraph` instances expect to be
1592
- * constructed once and used until `destroy()`. The internal closure mirrors
1593
- * (`latestTurn` / `latestAborted` / `latestStatus` / `latestMessages` /
1594
- * `latestSchemas`) are wired by subscribe-and-capture at construction time;
1595
- * their corresponding `addDisposer`-registered subscriptions are torn down
1596
- * on subgraph unmount or `destroy()`. After teardown the mirrors freeze at
1597
- * their last value, so re-using a destroyed instance — calling `run()`
1598
- * again, or remounting under a new parent — would silently feed stale
1599
- * mirror data into `promptInput`. If you need to "reset" an agent, build a
1600
- * fresh `AgentLoopGraph` instance instead of recycling.
1684
+ * @example
1685
+ * ```ts
1686
+ * const hasBudget = derived([costMeter], (c) => c.total < BUDGET);
1687
+ * const canDestroy = state(false, { name: "destructive-allowed" });
1688
+ * const tools = toolSelector(registry.schemas, [
1689
+ * derived([hasBudget], (b) => (t) => !t.meta?.expensive || b === true),
1690
+ * derived([canDestroy], (c) => (t) => !t.meta?.destructive || c === true),
1691
+ * ]);
1692
+ * const agent = promptNode(graph, "agent", { ..., tools });
1693
+ * ```
1601
1694
  */
1602
- declare class AgentLoopGraph extends Graph {
1603
- readonly chat: ChatStreamGraph;
1604
- readonly tools: ToolRegistryGraph;
1605
- /** Current agent status. `initial: "idle"` — always has a real value. */
1606
- readonly status: Node<AgentLoopStatus>;
1607
- /** Turn count (completed LLM invocations this run). `initial: 0`. */
1608
- readonly turn: Node<number>;
1609
- /** Aborted flag; flipped by `abort()` or external `AbortSignal`. `initial: false`. */
1610
- readonly aborted: Node<boolean>;
1611
- /**
1612
- * Most recent LLM response. State-backed mirror driven by the response
1613
- * effect. `initial: null` — subscribers can read the cache synchronously;
1614
- * `awaitSettled(lastResponse)` or `firstWhere(lastResponse, v => v != null)`
1615
- * bridges to the first non-null value as a Promise.
1616
- */
1617
- readonly lastResponse: Node<LLMResponse | null>;
1618
- /** Tool-call batch emitted by the most recent LLM response. SENTINEL. */
1619
- readonly toolCalls: Node<readonly ToolCall[]>;
1620
- /** Tool-result batch (one entry per call) after reactive execution. SENTINEL. */
1621
- readonly toolResults: Node<readonly ToolResult[]>;
1622
- private readonly _terminalResult;
1623
- private readonly _disposeRunWiring;
1624
- /** Guards against overlapping `run()` calls. */
1625
- private _running;
1626
- /**
1627
- * Abort controller for the currently-running `adapter.invoke`. Minted per
1628
- * switchMap project; aborted when the reactive `aborted` node flips true
1629
- * OR when the caller's external `AbortSignal` fires. Threaded into
1630
- * `adapter.invoke({ signal })` AND `fromAny(promise, { signal })`, so the
1631
- * reactive layer sees ERROR when the wire call is cancelled.
1632
- */
1633
- private _currentAbortController;
1634
- constructor(name: string, opts: AgentLoopOptions);
1635
- /**
1636
- * Bridge to `Promise<LLMResponse>` over the reactive pipeline.
1637
- *
1638
- * - If `userMessage` is provided, appends it as a user message and
1639
- * transitions status to `"thinking"` to kick the loop.
1640
- * - If `signal` is provided, binds it to the reactive `aborted` node
1641
- * AND threads into `adapter.invoke({ signal })` so the wire call can
1642
- * cancel mid-flight. The reactive `aborted` state + effect 3 guarantee
1643
- * that even an adapter that ignores `signal` will stop emitting into
1644
- * the agent graph.
1645
- * - Resolves when `status === "done"` with the final LLM response.
1646
- * Rejects with `AbortError` when the abort signal fires pre-response.
1647
- * Rejects with the stage error when `status === "error"`.
1648
- *
1649
- * **Concurrency:** `run()` refuses to overlap with a pending call on the
1650
- * same agent. Attempting to call `run()` while a previous `run()` is
1651
- * still in-flight throws a `RangeError` immediately. Stale-resolution
1652
- * safety is provided by `awaitSettled({skipCurrent: true})`, which
1653
- * ignores the cached initial DATA from any previous run and resolves
1654
- * only on a fresh post-subscribe emission of `_terminalResult`.
1655
- */
1656
- run(userMessage?: string, signal?: AbortSignal): Promise<LLMResponse | null>;
1657
- /**
1658
- * Flip the reactive `aborted` state. Equivalent to setting an external
1659
- * `AbortSignal` — the pipeline observes and transitions to `"done"`.
1660
- */
1661
- abort(): void;
1662
- destroy(): void;
1663
- }
1664
- declare function agentLoop(name: string, opts: AgentLoopOptions): AgentLoopGraph;
1695
+ declare function toolSelector(allTools: NodeInput<readonly ToolDefinition[]>, constraints: readonly NodeInput<(tool: ToolDefinition) => boolean>[], opts?: ToolSelectorOptions): Node<readonly ToolDefinition[]>;
1665
1696
 
1666
- /**
1667
- * Options for {@link handoff}.
1668
- */
1669
- type HandoffOptions = {
1670
- /**
1671
- * Reactive gate: when this node's value is `true`, output flows from
1672
- * `from` to the `to` specialist; when `false`, `from`'s output flows
1673
- * through unchanged and `to` stays dormant. Omit to always hand off —
1674
- * useful when `from` is itself a router whose output shape already
1675
- * encodes routing intent.
1676
- */
1677
- condition?: NodeInput<boolean>;
1678
- name?: string;
1679
- };
1680
- /**
1681
- * Multi-agent handoff recipe — route `from`'s output into a specialist
1682
- * agent `toFactory` when `condition` is open. Thin composition over
1683
- * `switchMap` + gate; not a new primitive, just a named shape.
1684
- *
1685
- * The "handoff" pattern (popularized by the OpenAI Agents SDK) covers two
1686
- * idioms:
1687
- *
1688
- * 1. **Full handoff** — a triage agent routes the conversation to a
1689
- * specialist, and the specialist becomes the active agent for the rest
1690
- * of the turn. Accumulated context (memory, tool definitions) can travel
1691
- * along by threading the same `agentMemory` bundle into both.
1692
- * 2. **Agents-as-tools** — the manager keeps control and calls the
1693
- * specialist like a tool for a bounded subtask. Build this by registering
1694
- * a `promptNode` instance as a `ToolDefinition` on the parent via
1695
- * `toolRegistry`.
1696
- *
1697
- * This sugar covers (1) — a reactive route from one agent's output into a
1698
- * specialist factory. For (2) wire a tool registry manually; the pattern is
1699
- * additive with this one.
1700
- *
1701
- * @example Full handoff on a triage signal.
1702
- * ```ts
1703
- * import { handoff, promptNode } from "@graphrefly/graphrefly/patterns/ai";
1704
- *
1705
- * const triage = promptNode(adapter, [userMessage], (msg) =>
1706
- * `Classify urgency of: ${msg}. Reply "high" or "normal".`);
1707
- * const isUrgent = derived([triage], ([v]) => v === "high");
1708
- *
1709
- * const specialist = handoff(
1710
- * userMessage,
1711
- * (input) => promptNode(specialistAdapter, [input], (m) => `Respond urgently: ${m}`),
1712
- * { condition: isUrgent },
1713
- * );
1714
- * ```
1715
- *
1716
- * @param from - Source node whose value is threaded into the specialist.
1717
- * @param toFactory - Factory that takes `from` (as a reactive source) and
1718
- * returns the specialist node. Called once, lazily, when the first
1719
- * subscriber activates.
1720
- * @param opts - Optional reactive `condition` gate + name.
1721
- * @returns Node emitting the specialist's output when the gate is open, or
1722
- * `from`'s value when the gate is closed. Null when `from` is null.
1723
- *
1724
- * **Performance caveat (Wave A Unit 5):** the specialist is mounted per
1725
- * source emission — each `v != null` DATA on `from` allocates a fresh
1726
- * `state<T>(v)` + invokes `toFactory`, and switchMap cancels the prior
1727
- * branch. For per-turn routing (≤1 emit/sec) this is negligible. For
1728
- * high-frequency sources (per-token routing, tight event loops), batch
1729
- * upstream (e.g. via `audit`, `throttle`, or `distinctUntilChanged`) before
1730
- * handing off — each mount/unmount cycle spins up full subgraphs
1731
- * (`messagesNode` + adapter bridge + output for a `promptNode` specialist).
1732
- *
1733
- * @category patterns.ai
1734
- */
1735
- declare function handoff<T>(from: NodeInput<T | null>, toFactory: (input: Node<T>) => Node<T | null>, opts?: HandoffOptions): Node<T | null>;
1736
-
1737
- /**
1738
- * Options for {@link toolSelector}.
1739
- */
1740
- interface ToolSelectorOptions {
1741
- readonly name?: string;
1742
- }
1743
- /**
1744
- * Reactive tool availability (COMPOSITION-GUIDE §31). Given a base tool set
1745
- * (reactive or static) and one or more reactive predicates, emit the filtered
1746
- * subset of tools currently allowed. Feeds into `promptNode({ tools: Node<...> })`
1747
- * so the LLM sees a reactive menu instead of a frozen config.
1748
- *
1749
- * Each predicate is a `NodeInput<(tool) => boolean>`. A tool is included iff
1750
- * **every** predicate returns `true`. When any predicate value is `null` /
1751
- * `undefined` (e.g. upstream not yet ready) that predicate is treated as a
1752
- * pass-through — the tool isn't excluded on its basis. Predicate updates
1753
- * recompute the selected set.
1754
- *
1755
- * Pairs with `toolInterceptor` (§D9 / §31): **selection** controls what's
1756
- * offered to the LLM (pre-generation UX); **interception** gates what's
1757
- * executed after the LLM chooses (post-generation security). Tool selection
1758
- * is NOT a security boundary — an LLM can hallucinate tool calls outside
1759
- * its offered set; always pair with `toolInterceptor` for enforcement.
1760
- *
1761
- * @example
1762
- * ```ts
1763
- * const hasBudget = derived([costMeter], (c) => c.total < BUDGET);
1764
- * const canDestroy = state(false, { name: "destructive-allowed" });
1765
- * const tools = toolSelector(registry.schemas, [
1766
- * derived([hasBudget], (b) => (t) => !t.meta?.expensive || b === true),
1767
- * derived([canDestroy], (c) => (t) => !t.meta?.destructive || c === true),
1768
- * ]);
1769
- * const agent = promptNode(graph, "agent", { ..., tools });
1770
- * ```
1771
- */
1772
- declare function toolSelector(allTools: NodeInput<readonly ToolDefinition[]>, constraints: readonly NodeInput<(tool: ToolDefinition) => boolean>[], opts?: ToolSelectorOptions): Node<readonly ToolDefinition[]>;
1773
-
1774
- /** Generic per-dimension thresholds. Any dim below its threshold → reject. */
1775
- type AdmissionThresholds<Dims extends string> = Partial<Record<Dims, number>>;
1776
- type AdmissionScoredOptions<Dims extends string, TRaw = unknown> = {
1777
- /** Score function — must return a finite number for every dimension named in `thresholds`. */
1778
- scoreFn: (raw: TRaw) => Readonly<Record<Dims, number>>;
1779
- /** Per-dim minimums. Dims absent here are scored but not gated. */
1780
- thresholds?: AdmissionThresholds<Dims>;
1781
- };
1697
+ /** Generic per-dimension thresholds. Any dim below its threshold → reject. */
1698
+ type AdmissionThresholds<Dims extends string> = Partial<Record<Dims, number>>;
1699
+ type AdmissionScoredOptions<Dims extends string, TRaw = unknown> = {
1700
+ /** Score function — must return a finite number for every dimension named in `thresholds`. */
1701
+ scoreFn: (raw: TRaw) => Readonly<Record<Dims, number>>;
1702
+ /** Per-dim minimums. Dims absent here are scored but not gated. */
1703
+ thresholds?: AdmissionThresholds<Dims>;
1704
+ };
1782
1705
  /**
1783
1706
  * Generic N-dimension admission filter. Rejects any input where one of the
1784
1707
  * configured threshold dimensions scores below its minimum. Missing scores
@@ -1919,6 +1842,262 @@ type MemoryTiersBundle<TMem> = {
1919
1842
  markPermanent: (key: string, value: TMem) => void;
1920
1843
  };
1921
1844
 
1845
+ type MemoryWithVectorsOptions<TMem> = {
1846
+ /** Embedding dimension. Must match the `embedFn` output length. */
1847
+ dimension: number;
1848
+ /** Extract an embedding vector for a memory entry. */
1849
+ embedFn: (mem: TMem) => readonly number[] | undefined;
1850
+ };
1851
+ /**
1852
+ * Attach a vector index to a `DistillBundle`. Indexes every entry in the
1853
+ * store as it changes. Returns the `VectorIndexGraph` so retrieval can read
1854
+ * its `entries` and call `search()`.
1855
+ *
1856
+ * The indexer's keepalive is registered with `graph.addDisposer` so it tears
1857
+ * down on `graph.destroy()`. The returned `dispose()` is also available for
1858
+ * early release without destroying the parent graph.
1859
+ */
1860
+ declare function memoryWithVectors<TMem>(graph: Graph, store: DistillBundle<TMem>, opts: MemoryWithVectorsOptions<TMem>): {
1861
+ vectors: VectorIndexGraph<TMem>;
1862
+ dispose: () => void;
1863
+ };
1864
+ type MemoryWithKGOptions<TMem> = {
1865
+ /**
1866
+ * Mount path for the KG subgraph on the parent graph. Defaults to `name`.
1867
+ * Pass a different value when the parent graph reserves a stable mount
1868
+ * path (e.g. `agentMemory` mounts at `"kg"` regardless of outer name).
1869
+ */
1870
+ mountPath?: string;
1871
+ /**
1872
+ * Extract entities + relations for a memory entry. Omit to mount an empty
1873
+ * KG without an indexer effect — caller upserts entities / relations
1874
+ * directly on the returned `kg` handle.
1875
+ */
1876
+ entityFn?: (key: string, mem: TMem) => {
1877
+ entities?: Array<{
1878
+ id: string;
1879
+ value: unknown;
1880
+ }>;
1881
+ relations?: Array<{
1882
+ from: string;
1883
+ to: string;
1884
+ relation: string;
1885
+ weight?: number;
1886
+ }>;
1887
+ } | undefined;
1888
+ };
1889
+ /**
1890
+ * Attach a knowledge graph alongside a `DistillBundle`. Inner graph is named
1891
+ * `${name}-kg`; mount path defaults to `name` but can be overridden via
1892
+ * `opts.mountPath` so a parent factory (e.g. `agentMemory`) can keep a stable
1893
+ * mount path independent of the inner graph's identity.
1894
+ *
1895
+ * If `opts.entityFn` is omitted, no indexer effect is wired — the empty KG is
1896
+ * mounted for manual `upsertEntity` / `link` use.
1897
+ *
1898
+ * Indexer keepalive (when present) is registered with `graph.addDisposer`;
1899
+ * explicit `dispose()` is also available.
1900
+ */
1901
+ declare function memoryWithKG<TMem>(graph: Graph, store: DistillBundle<TMem>, name: string, opts: MemoryWithKGOptions<TMem>): {
1902
+ kg: KnowledgeGraph<unknown, string>;
1903
+ dispose: () => void;
1904
+ };
1905
+ type MemoryWithTiersOptions<TMem> = MemoryTiersOptions<TMem> & {
1906
+ /** Score function — same signature as `agentMemory.score`. */
1907
+ score: (mem: TMem, context: unknown) => number;
1908
+ /** Optional reactive context node (passed to `score`). */
1909
+ context?: NodeInput<unknown>;
1910
+ };
1911
+ /**
1912
+ * Attach 3-tier storage (active / archived / permanent) to a `DistillBundle`.
1913
+ * Wires a `tierClassifier` effect that:
1914
+ * - Promotes entries matching `permanentFilter` into the permanent tier.
1915
+ * - Archives entries whose decayed score falls below `archiveThreshold`.
1916
+ * - Caps the active tier at `maxActive`, evicting lowest-scored on overflow.
1917
+ *
1918
+ * **Closure state caveat (Unit 7 Q3 deferred):** `permanentKeys` +
1919
+ * `entryCreatedAtNs` are still closure-held for now; promotion to reactive
1920
+ * nodes is tracked in `docs/optimizations.md`.
1921
+ */
1922
+ declare function memoryWithTiers<TMem>(graph: Graph, store: DistillBundle<TMem>, opts: MemoryWithTiersOptions<TMem>): {
1923
+ tiers: MemoryTiersBundle<TMem>;
1924
+ dispose: () => void;
1925
+ };
1926
+ type MemoryRetrievalOptions<TMem> = {
1927
+ /** Score function (same shape as `agentMemory.score`). */
1928
+ score: (mem: TMem, context: unknown) => number;
1929
+ /** Cost function for budget packing. */
1930
+ cost: (mem: TMem) => number;
1931
+ /** Token / cost budget. Default 2000. */
1932
+ budget?: number;
1933
+ /** Top-K vector candidates. Default 20. */
1934
+ topK?: number;
1935
+ /** KG expansion depth in hops. Default 1. */
1936
+ graphDepth?: number;
1937
+ /** Hierarchical-context boost weight. Default 0. */
1938
+ contextWeight?: number;
1939
+ /** Hierarchical-context accessor for entries. */
1940
+ contextOf?: (mem: TMem) => readonly string[] | undefined;
1941
+ /** Optional reactive context node (passed to `score`). */
1942
+ context?: NodeInput<unknown>;
1943
+ };
1944
+ type MemoryRetrievalBundle<TMem> = {
1945
+ /** State node mirroring the latest packed retrieval result. */
1946
+ readonly retrieval: Node<ReadonlyArray<RetrievalEntry<TMem>>>;
1947
+ /** State node mirroring the latest retrieval trace. */
1948
+ readonly retrievalTrace: Node<RetrievalTrace<TMem> | null>;
1949
+ /** Imperative consumer API — synchronous; reads cache at call time. */
1950
+ readonly retrieve: (query: RetrievalQuery) => ReadonlyArray<RetrievalEntry<TMem>>;
1951
+ /** Reactive sibling — chain into the graph. Mirrors observability state. */
1952
+ readonly retrieveReactive: (queryInput: NodeInput<RetrievalQuery | null>) => Node<ReadonlyArray<RetrievalEntry<TMem>>>;
1953
+ };
1954
+ /**
1955
+ * Build the retrieval pipeline (vector + KG + budget packing) over a
1956
+ * `DistillBundle` and optional `vectors` / `kg` bundles.
1957
+ *
1958
+ * Both consumer surfaces (`retrieve`, `retrieveReactive`) write to the same
1959
+ * `retrieval` + `retrievalTrace` state nodes — observers subscribed to those
1960
+ * see ALL queries regardless of which API issued them.
1961
+ */
1962
+ declare function memoryRetrieval<TMem>(graph: Graph, store: DistillBundle<TMem>, vectors: VectorIndexGraph<TMem> | null, kg: KnowledgeGraph<unknown, string> | null, opts: MemoryRetrievalOptions<TMem>): MemoryRetrievalBundle<TMem>;
1963
+
1964
+ /**
1965
+ * Reactive agent loop — autonomous multi-turn LLM agent with tool execution.
1966
+ */
1967
+ type AgentLoopStatus = "idle" | "thinking" | "acting" | "done" | "error";
1968
+
1969
+ type AgentLoopOptions = {
1970
+ graph?: GraphOptions;
1971
+ adapter: LLMAdapter;
1972
+ tools?: readonly ToolDefinition[];
1973
+ systemPrompt?: string;
1974
+ maxTurns?: number;
1975
+ stopWhen?: (response: LLMResponse) => boolean;
1976
+ onToolCall?: (call: ToolCall) => void;
1977
+ maxMessages?: number;
1978
+ model?: string;
1979
+ temperature?: number;
1980
+ maxTokens?: number;
1981
+ /**
1982
+ * Reactive tool-call splice (COMPOSITION-GUIDE §31 "interception is security").
1983
+ * When set, the raw `toolCalls` node is piped through this transform before
1984
+ * reaching the executor. The transform is a pure reactive composition —
1985
+ * `(calls: Node<readonly ToolCall[]>) => Node<readonly ToolCall[]>` — so the
1986
+ * gate is visible in `describe()` / `explain()` as a real edge (no hidden
1987
+ * imperative wraps; §24).
1988
+ *
1989
+ * Typical uses:
1990
+ * - **Filter / block** — `derived([calls, policy], ([raw, p]) => raw.filter(p))`
1991
+ * - **Throttle / debounce** — `throttle(calls, windowMs)`
1992
+ * - **Human-in-the-loop approval** — pipe through a `gate` controller so
1993
+ * calls wait for human approval before reaching the executor.
1994
+ *
1995
+ * The public `agent.toolCalls` node surfaces the POST-intercept stream, so
1996
+ * audit / telemetry consumers see what the executor actually runs. The raw
1997
+ * pre-intercept stream is not exposed — tests that need it should run
1998
+ * without `interceptToolCalls` set (the identity case).
1999
+ */
2000
+ interceptToolCalls?: (calls: Node<readonly ToolCall[]>) => Node<readonly ToolCall[]>;
2001
+ };
2002
+ /**
2003
+ * Reactive agent loop.
2004
+ *
2005
+ * The loop is a reactive state machine wired entirely from graph primitives:
2006
+ * `chat.messages` + `tools.schemas` + gating state feed a `promptInput`
2007
+ * derived; `switchMap` turns non-null inputs into an LLM invocation via
2008
+ * `fromAny(adapter.invoke(...))`. The LLM response drives chat writes and
2009
+ * status transitions via effects. Tool calls flow through a reactive
2010
+ * executor (`retrySource` + `rescue`) that retries once on error and
2011
+ * surfaces terminal errors as JSON-shaped `ToolResult` payloads for the
2012
+ * LLM to react to.
2013
+ *
2014
+ * **No imperative control flow inside the reactive layer** (spec §5.8-5.12):
2015
+ * no `while` loops, no manual `await adapter.invoke`, no polling.
2016
+ * `agent.run()` is a thin `awaitSettled` bridge so callers can still `await`
2017
+ * the loop if they want a Promise.
2018
+ *
2019
+ * Public surface:
2020
+ * - `chat` / `tools` — subgraphs (imperative `append` at boundary, reactive `executeReactive` for tool invocation)
2021
+ * - `status` / `turn` / `aborted` — state nodes with explicit initials
2022
+ * - `lastResponse` / `toolCalls` / `toolResults` — reactive outputs (SENTINEL until first emission; callers use `awaitSettled` / `subscribe`)
2023
+ * - `run(userMessage?, signal?)` — optional user append + Promise bridge
2024
+ * - `abort()` — imperative abort shim; flips `aborted` state
2025
+ *
2026
+ * **Lifecycle: single-mount.** `AgentLoopGraph` instances expect to be
2027
+ * constructed once and used until `destroy()`. The internal closure mirrors
2028
+ * (`latestTurn` / `latestAborted` / `latestStatus` / `latestMessages` /
2029
+ * `latestSchemas`) are wired by subscribe-and-capture at construction time;
2030
+ * their corresponding `addDisposer`-registered subscriptions are torn down
2031
+ * on subgraph unmount or `destroy()`. After teardown the mirrors freeze at
2032
+ * their last value, so re-using a destroyed instance — calling `run()`
2033
+ * again, or remounting under a new parent — would silently feed stale
2034
+ * mirror data into `promptInput`. If you need to "reset" an agent, build a
2035
+ * fresh `AgentLoopGraph` instance instead of recycling.
2036
+ */
2037
+ declare class AgentLoopGraph extends Graph {
2038
+ readonly chat: ChatStreamGraph;
2039
+ readonly tools: ToolRegistryGraph;
2040
+ /** Current agent status. `initial: "idle"` — always has a real value. */
2041
+ readonly status: Node<AgentLoopStatus>;
2042
+ /** Turn count (completed LLM invocations this run). `initial: 0`. */
2043
+ readonly turn: Node<number>;
2044
+ /** Aborted flag; flipped by `abort()` or external `AbortSignal`. `initial: false`. */
2045
+ readonly aborted: Node<boolean>;
2046
+ /**
2047
+ * Most recent LLM response. State-backed mirror driven by the response
2048
+ * effect. `initial: null` — subscribers can read the cache synchronously;
2049
+ * `awaitSettled(lastResponse)` or `firstWhere(lastResponse, v => v != null)`
2050
+ * bridges to the first non-null value as a Promise.
2051
+ */
2052
+ readonly lastResponse: Node<LLMResponse | null>;
2053
+ /** Tool-call batch emitted by the most recent LLM response. SENTINEL. */
2054
+ readonly toolCalls: Node<readonly ToolCall[]>;
2055
+ /** Tool-result batch (one entry per call) after reactive execution. SENTINEL. */
2056
+ readonly toolResults: Node<readonly ToolResult[]>;
2057
+ private readonly _terminalResult;
2058
+ private readonly _disposeRunWiring;
2059
+ /** Guards against overlapping `run()` calls. */
2060
+ private _running;
2061
+ /**
2062
+ * Abort controller for the currently-running `adapter.invoke`. Minted per
2063
+ * switchMap project; aborted when the reactive `aborted` node flips true
2064
+ * OR when the caller's external `AbortSignal` fires. Threaded into
2065
+ * `adapter.invoke({ signal })` AND `fromAny(promise, { signal })`, so the
2066
+ * reactive layer sees ERROR when the wire call is cancelled.
2067
+ */
2068
+ private _currentAbortController;
2069
+ constructor(name: string, opts: AgentLoopOptions);
2070
+ /**
2071
+ * Bridge to `Promise<LLMResponse>` over the reactive pipeline.
2072
+ *
2073
+ * - If `userMessage` is provided, appends it as a user message and
2074
+ * transitions status to `"thinking"` to kick the loop.
2075
+ * - If `signal` is provided, binds it to the reactive `aborted` node
2076
+ * AND threads into `adapter.invoke({ signal })` so the wire call can
2077
+ * cancel mid-flight. The reactive `aborted` state + effect 3 guarantee
2078
+ * that even an adapter that ignores `signal` will stop emitting into
2079
+ * the agent graph.
2080
+ * - Resolves when `status === "done"` with the final LLM response.
2081
+ * Rejects with `AbortError` when the abort signal fires pre-response.
2082
+ * Rejects with the stage error when `status === "error"`.
2083
+ *
2084
+ * **Concurrency:** `run()` refuses to overlap with a pending call on the
2085
+ * same agent. Attempting to call `run()` while a previous `run()` is
2086
+ * still in-flight throws a `RangeError` immediately. Stale-resolution
2087
+ * safety is provided by `awaitSettled({skipCurrent: true})`, which
2088
+ * ignores the cached initial DATA from any previous run and resolves
2089
+ * only on a fresh post-subscribe emission of `_terminalResult`.
2090
+ */
2091
+ run(userMessage?: string, signal?: AbortSignal): Promise<LLMResponse | null>;
2092
+ /**
2093
+ * Flip the reactive `aborted` state. Equivalent to setting an external
2094
+ * `AbortSignal` — the pipeline observes and transitions to `"done"`.
2095
+ */
2096
+ abort(): void;
2097
+ destroy(): void;
2098
+ }
2099
+ declare function agentLoop(name: string, opts: AgentLoopOptions): AgentLoopGraph;
2100
+
1922
2101
  type AgentMemoryOptions<TMem = unknown> = {
1923
2102
  graph?: GraphOptions;
1924
2103
  /** LLM adapter for extraction and consolidation. */
@@ -2046,125 +2225,6 @@ type AgentMemoryGraph<TMem = unknown> = Graph & {
2046
2225
  */
2047
2226
  declare function agentMemory<TMem = unknown>(name: string, source: NodeInput<unknown>, opts: AgentMemoryOptions<TMem>): AgentMemoryGraph<TMem>;
2048
2227
 
2049
- type MemoryWithVectorsOptions<TMem> = {
2050
- /** Embedding dimension. Must match the `embedFn` output length. */
2051
- dimension: number;
2052
- /** Extract an embedding vector for a memory entry. */
2053
- embedFn: (mem: TMem) => readonly number[] | undefined;
2054
- };
2055
- /**
2056
- * Attach a vector index to a `DistillBundle`. Indexes every entry in the
2057
- * store as it changes. Returns the `VectorIndexGraph` so retrieval can read
2058
- * its `entries` and call `search()`.
2059
- *
2060
- * The indexer's keepalive is registered with `graph.addDisposer` so it tears
2061
- * down on `graph.destroy()`. The returned `dispose()` is also available for
2062
- * early release without destroying the parent graph.
2063
- */
2064
- declare function memoryWithVectors<TMem>(graph: Graph, store: DistillBundle<TMem>, opts: MemoryWithVectorsOptions<TMem>): {
2065
- vectors: VectorIndexGraph<TMem>;
2066
- dispose: () => void;
2067
- };
2068
- type MemoryWithKGOptions<TMem> = {
2069
- /**
2070
- * Mount path for the KG subgraph on the parent graph. Defaults to `name`.
2071
- * Pass a different value when the parent graph reserves a stable mount
2072
- * path (e.g. `agentMemory` mounts at `"kg"` regardless of outer name).
2073
- */
2074
- mountPath?: string;
2075
- /**
2076
- * Extract entities + relations for a memory entry. Omit to mount an empty
2077
- * KG without an indexer effect — caller upserts entities / relations
2078
- * directly on the returned `kg` handle.
2079
- */
2080
- entityFn?: (key: string, mem: TMem) => {
2081
- entities?: Array<{
2082
- id: string;
2083
- value: unknown;
2084
- }>;
2085
- relations?: Array<{
2086
- from: string;
2087
- to: string;
2088
- relation: string;
2089
- weight?: number;
2090
- }>;
2091
- } | undefined;
2092
- };
2093
- /**
2094
- * Attach a knowledge graph alongside a `DistillBundle`. Inner graph is named
2095
- * `${name}-kg`; mount path defaults to `name` but can be overridden via
2096
- * `opts.mountPath` so a parent factory (e.g. `agentMemory`) can keep a stable
2097
- * mount path independent of the inner graph's identity.
2098
- *
2099
- * If `opts.entityFn` is omitted, no indexer effect is wired — the empty KG is
2100
- * mounted for manual `upsertEntity` / `link` use.
2101
- *
2102
- * Indexer keepalive (when present) is registered with `graph.addDisposer`;
2103
- * explicit `dispose()` is also available.
2104
- */
2105
- declare function memoryWithKG<TMem>(graph: Graph, store: DistillBundle<TMem>, name: string, opts: MemoryWithKGOptions<TMem>): {
2106
- kg: KnowledgeGraph<unknown, string>;
2107
- dispose: () => void;
2108
- };
2109
- type MemoryWithTiersOptions<TMem> = MemoryTiersOptions<TMem> & {
2110
- /** Score function — same signature as `agentMemory.score`. */
2111
- score: (mem: TMem, context: unknown) => number;
2112
- /** Optional reactive context node (passed to `score`). */
2113
- context?: NodeInput<unknown>;
2114
- };
2115
- /**
2116
- * Attach 3-tier storage (active / archived / permanent) to a `DistillBundle`.
2117
- * Wires a `tierClassifier` effect that:
2118
- * - Promotes entries matching `permanentFilter` into the permanent tier.
2119
- * - Archives entries whose decayed score falls below `archiveThreshold`.
2120
- * - Caps the active tier at `maxActive`, evicting lowest-scored on overflow.
2121
- *
2122
- * **Closure state caveat (Unit 7 Q3 deferred):** `permanentKeys` +
2123
- * `entryCreatedAtNs` are still closure-held for now; promotion to reactive
2124
- * nodes is tracked in `docs/optimizations.md`.
2125
- */
2126
- declare function memoryWithTiers<TMem>(graph: Graph, store: DistillBundle<TMem>, opts: MemoryWithTiersOptions<TMem>): {
2127
- tiers: MemoryTiersBundle<TMem>;
2128
- dispose: () => void;
2129
- };
2130
- type MemoryRetrievalOptions<TMem> = {
2131
- /** Score function (same shape as `agentMemory.score`). */
2132
- score: (mem: TMem, context: unknown) => number;
2133
- /** Cost function for budget packing. */
2134
- cost: (mem: TMem) => number;
2135
- /** Token / cost budget. Default 2000. */
2136
- budget?: number;
2137
- /** Top-K vector candidates. Default 20. */
2138
- topK?: number;
2139
- /** KG expansion depth in hops. Default 1. */
2140
- graphDepth?: number;
2141
- /** Hierarchical-context boost weight. Default 0. */
2142
- contextWeight?: number;
2143
- /** Hierarchical-context accessor for entries. */
2144
- contextOf?: (mem: TMem) => readonly string[] | undefined;
2145
- /** Optional reactive context node (passed to `score`). */
2146
- context?: NodeInput<unknown>;
2147
- };
2148
- type MemoryRetrievalBundle<TMem> = {
2149
- /** State node mirroring the latest packed retrieval result. */
2150
- readonly retrieval: Node<ReadonlyArray<RetrievalEntry<TMem>>>;
2151
- /** State node mirroring the latest retrieval trace. */
2152
- readonly retrievalTrace: Node<RetrievalTrace<TMem> | null>;
2153
- /** Imperative consumer API — synchronous; reads cache at call time. */
2154
- readonly retrieve: (query: RetrievalQuery) => ReadonlyArray<RetrievalEntry<TMem>>;
2155
- /** Reactive sibling — chain into the graph. Mirrors observability state. */
2156
- readonly retrieveReactive: (queryInput: NodeInput<RetrievalQuery | null>) => Node<ReadonlyArray<RetrievalEntry<TMem>>>;
2157
- };
2158
- /**
2159
- * Build the retrieval pipeline (vector + KG + budget packing) over a
2160
- * `DistillBundle` and optional `vectors` / `kg` bundles.
2161
- *
2162
- * Both consumer surfaces (`retrieve`, `retrieveReactive`) write to the same
2163
- * `retrieval` + `retrievalTrace` state nodes — observers subscribed to those
2164
- * see ALL queries regardless of which API issued them.
2165
- */
2166
- declare function memoryRetrieval<TMem>(graph: Graph, store: DistillBundle<TMem>, vectors: VectorIndexGraph<TMem> | null, kg: KnowledgeGraph<unknown, string> | null, opts: MemoryRetrievalOptions<TMem>): MemoryRetrievalBundle<TMem>;
2167
-
2168
2228
  type GaugesAsContextOptions = {
2169
2229
  /** Group gauges by `meta.tags` (default true). */
2170
2230
  groupByTags?: boolean;