@theokit/sdk 4.63.3 → 5.0.0-next.1

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 (788) hide show
  1. package/CHANGELOG.md +729 -0
  2. package/dist/a2a/index.cjs +29 -13
  3. package/dist/a2a/index.cjs.map +1 -1
  4. package/dist/a2a/index.d.cts +1 -1
  5. package/dist/a2a/index.d.ts +1 -1
  6. package/dist/a2a/index.js +26 -11
  7. package/dist/a2a/index.js.map +1 -1
  8. package/dist/a2a/message-bus.d.cts +26 -3
  9. package/dist/a2a/message-bus.d.ts +26 -3
  10. package/dist/a2a/subagent.d.cts +8 -3
  11. package/dist/a2a/subagent.d.ts +8 -3
  12. package/dist/agent-2E7DI47Y.cjs +67 -0
  13. package/dist/{agent-PVINJTUR.cjs.map → agent-2E7DI47Y.cjs.map} +1 -1
  14. package/dist/{agent-BFno7Sfn.d.ts → agent-CdYJfKr6.d.ts} +205 -36
  15. package/dist/{agent-X0DKA943.d.cts → agent-CgNzshyV.d.cts} +205 -36
  16. package/dist/agent-XMKRP27S.js +58 -0
  17. package/dist/{agent-3JK7VXNN.js.map → agent-XMKRP27S.js.map} +1 -1
  18. package/dist/agent-session-store-AFML3AXC.js +6 -0
  19. package/dist/{agent-session-store-OPGRB4XM.js.map → agent-session-store-AFML3AXC.js.map} +1 -1
  20. package/dist/agent-session-store-MTSIY3MH.cjs +23 -0
  21. package/dist/{agent-session-store-6EL5NPA4.cjs.map → agent-session-store-MTSIY3MH.cjs.map} +1 -1
  22. package/dist/agent.d.ts +1 -1
  23. package/dist/auth/index.cjs +33 -34
  24. package/dist/auth/index.cjs.map +1 -1
  25. package/dist/auth/index.d.cts +1 -1
  26. package/dist/auth/index.d.ts +1 -1
  27. package/dist/auth/index.js +6 -7
  28. package/dist/auth/index.js.map +1 -1
  29. package/dist/{batch-BXYTW2DP.cjs → batch-I6T6MXZO.cjs} +58 -40
  30. package/dist/batch-I6T6MXZO.cjs.map +1 -0
  31. package/dist/{batch-L4ZXS46M.js → batch-US4F6WPK.js} +42 -24
  32. package/dist/batch-US4F6WPK.js.map +1 -0
  33. package/dist/chunk-24MGQDK3.js +31 -0
  34. package/dist/chunk-24MGQDK3.js.map +1 -0
  35. package/dist/{chunk-UGT7GK7I.cjs → chunk-24SYBZPL.cjs} +36 -18
  36. package/dist/chunk-24SYBZPL.cjs.map +1 -0
  37. package/dist/{chunk-KYAJINUI.cjs → chunk-2HPNT6HH.cjs} +581 -401
  38. package/dist/chunk-2HPNT6HH.cjs.map +1 -0
  39. package/dist/{chunk-VLVVJLDH.cjs → chunk-2NE7DTOK.cjs} +234 -193
  40. package/dist/chunk-2NE7DTOK.cjs.map +1 -0
  41. package/dist/{chunk-N2U4AZGB.js → chunk-2WXHA33T.js} +3 -3
  42. package/dist/chunk-2WXHA33T.js.map +1 -0
  43. package/dist/chunk-2XC6KDJM.js +22 -0
  44. package/dist/chunk-2XC6KDJM.js.map +1 -0
  45. package/dist/{chunk-L3MTL4NA.js → chunk-2ZLVT7H3.js} +223 -182
  46. package/dist/chunk-2ZLVT7H3.js.map +1 -0
  47. package/dist/{chunk-2GUYQR5P.js → chunk-3JHIFQ4I.js} +39 -13
  48. package/dist/chunk-3JHIFQ4I.js.map +1 -0
  49. package/dist/{chunk-BU4KFWXF.js → chunk-44I6UYVH.js} +8 -17
  50. package/dist/chunk-44I6UYVH.js.map +1 -0
  51. package/dist/{chunk-UNYXQ4M5.js → chunk-47TF32NQ.js} +10 -5
  52. package/dist/chunk-47TF32NQ.js.map +1 -0
  53. package/dist/{chunk-WNO3C3N2.cjs → chunk-4A3SKJ53.cjs} +56 -27
  54. package/dist/chunk-4A3SKJ53.cjs.map +1 -0
  55. package/dist/{chunk-YML4ME27.cjs → chunk-4HS6FFGL.cjs} +55 -46
  56. package/dist/chunk-4HS6FFGL.cjs.map +1 -0
  57. package/dist/{chunk-C72AZW7J.js → chunk-4MMWFSCD.js} +4 -4
  58. package/dist/chunk-4MMWFSCD.js.map +1 -0
  59. package/dist/{chunk-6HKGLTJI.cjs → chunk-4NLCWGH7.cjs} +15 -15
  60. package/dist/chunk-4NLCWGH7.cjs.map +1 -0
  61. package/dist/{chunk-UBDMVMBZ.js → chunk-55GB6JYQ.js} +33 -22
  62. package/dist/chunk-55GB6JYQ.js.map +1 -0
  63. package/dist/{chunk-U6IFHFWK.js → chunk-5WKQDIGO.js} +8 -17
  64. package/dist/chunk-5WKQDIGO.js.map +1 -0
  65. package/dist/{chunk-GPKAF7SG.js → chunk-6HIACV34.js} +91 -92
  66. package/dist/chunk-6HIACV34.js.map +1 -0
  67. package/dist/{chunk-XL7Q7HB2.cjs → chunk-6LHQPOMI.cjs} +39 -6
  68. package/dist/chunk-6LHQPOMI.cjs.map +1 -0
  69. package/dist/{chunk-A4JVILQU.js → chunk-6M2OIS4Y.js} +7 -7
  70. package/dist/chunk-6M2OIS4Y.js.map +1 -0
  71. package/dist/{chunk-LWGSI6M3.js → chunk-6PWOWXMC.js} +4 -4
  72. package/dist/{chunk-LWGSI6M3.js.map → chunk-6PWOWXMC.js.map} +1 -1
  73. package/dist/{chunk-RNB4APBZ.js → chunk-6WAKKTBO.js} +9 -5
  74. package/dist/chunk-6WAKKTBO.js.map +1 -0
  75. package/dist/{chunk-V2BOS4WF.cjs → chunk-7A6535RA.cjs} +11 -11
  76. package/dist/chunk-7A6535RA.cjs.map +1 -0
  77. package/dist/{chunk-ZLQSWSJ2.cjs → chunk-7FDKWDA2.cjs} +11 -11
  78. package/dist/{chunk-ZLQSWSJ2.cjs.map → chunk-7FDKWDA2.cjs.map} +1 -1
  79. package/dist/{chunk-4VPXM6UU.js → chunk-7I5Z3UBJ.js} +3 -3
  80. package/dist/{chunk-4VPXM6UU.js.map → chunk-7I5Z3UBJ.js.map} +1 -1
  81. package/dist/{chunk-B4EOJWOY.cjs → chunk-7JJ3A6AT.cjs} +13 -7
  82. package/dist/chunk-7JJ3A6AT.cjs.map +1 -0
  83. package/dist/{chunk-ZWRG4NWT.cjs → chunk-7ZK4DJD7.cjs} +108 -109
  84. package/dist/chunk-7ZK4DJD7.cjs.map +1 -0
  85. package/dist/{chunk-WJVHMTKB.cjs → chunk-AA27GEYS.cjs} +3 -3
  86. package/dist/{chunk-WJVHMTKB.cjs.map → chunk-AA27GEYS.cjs.map} +1 -1
  87. package/dist/{chunk-BP46RJ5X.js → chunk-AAEZSPTC.js} +5 -5
  88. package/dist/{chunk-BP46RJ5X.js.map → chunk-AAEZSPTC.js.map} +1 -1
  89. package/dist/chunk-AGACYRJ2.js +11 -0
  90. package/dist/chunk-AGACYRJ2.js.map +1 -0
  91. package/dist/{chunk-ZZMZWBR6.js → chunk-ALUN2B4W.js} +81 -58
  92. package/dist/chunk-ALUN2B4W.js.map +1 -0
  93. package/dist/chunk-ANMJJD6D.cjs +18 -0
  94. package/dist/chunk-ANMJJD6D.cjs.map +1 -0
  95. package/dist/{chunk-DXGZ2NUG.cjs → chunk-ATT276RD.cjs} +12 -11
  96. package/dist/chunk-ATT276RD.cjs.map +1 -0
  97. package/dist/{chunk-4FFBAUFS.js → chunk-AWINL3ZC.js} +6 -6
  98. package/dist/chunk-AWINL3ZC.js.map +1 -0
  99. package/dist/{chunk-UU36SHFY.cjs → chunk-BJUJT5ED.cjs} +9 -8
  100. package/dist/chunk-BJUJT5ED.cjs.map +1 -0
  101. package/dist/chunk-CEILSTWB.cjs +109 -0
  102. package/dist/chunk-CEILSTWB.cjs.map +1 -0
  103. package/dist/{chunk-D4CUGAKZ.js → chunk-CZJ6Q7CW.js} +36 -6
  104. package/dist/chunk-CZJ6Q7CW.js.map +1 -0
  105. package/dist/{chunk-KQ7TS7WW.cjs → chunk-D6POWE7E.cjs} +37 -26
  106. package/dist/chunk-D6POWE7E.cjs.map +1 -0
  107. package/dist/{chunk-AWO27VRZ.js → chunk-DMRT67Y6.js} +6 -5
  108. package/dist/chunk-DMRT67Y6.js.map +1 -0
  109. package/dist/{chunk-5VB22SYX.cjs → chunk-DQZU7JK6.cjs} +7 -7
  110. package/dist/{chunk-5VB22SYX.cjs.map → chunk-DQZU7JK6.cjs.map} +1 -1
  111. package/dist/{chunk-3NSS2OIZ.cjs → chunk-DRL7URI4.cjs} +6 -6
  112. package/dist/{chunk-3NSS2OIZ.cjs.map → chunk-DRL7URI4.cjs.map} +1 -1
  113. package/dist/{chunk-RFXWMRFC.js → chunk-EFMFILPG.js} +14 -6
  114. package/dist/chunk-EFMFILPG.js.map +1 -0
  115. package/dist/{chunk-HS7AVXTF.js → chunk-EH6XD3FY.js} +4 -4
  116. package/dist/chunk-EH6XD3FY.js.map +1 -0
  117. package/dist/{chunk-KQRW2GPZ.js → chunk-EIQFAOFD.js} +6 -6
  118. package/dist/chunk-EIQFAOFD.js.map +1 -0
  119. package/dist/{chunk-XJCXEKMD.cjs → chunk-EXTRW7GW.cjs} +4 -4
  120. package/dist/chunk-EXTRW7GW.cjs.map +1 -0
  121. package/dist/{chunk-U54XCYG3.js → chunk-FJWQP6EE.js} +12 -6
  122. package/dist/chunk-FJWQP6EE.js.map +1 -0
  123. package/dist/{chunk-O7DK5PBJ.cjs → chunk-FUSDYC2B.cjs} +26 -42
  124. package/dist/chunk-FUSDYC2B.cjs.map +1 -0
  125. package/dist/{chunk-CQBXOJ6U.cjs → chunk-G4ZGYKJG.cjs} +21 -21
  126. package/dist/chunk-G4ZGYKJG.cjs.map +1 -0
  127. package/dist/{chunk-4QZSA2HJ.js → chunk-G7BLGBRN.js} +4 -4
  128. package/dist/chunk-G7BLGBRN.js.map +1 -0
  129. package/dist/{chunk-BZRFXJHA.js → chunk-GBCVPKHE.js} +55 -26
  130. package/dist/chunk-GBCVPKHE.js.map +1 -0
  131. package/dist/{chunk-5HEG4CQH.cjs → chunk-GZV6AVRL.cjs} +8 -8
  132. package/dist/{chunk-5HEG4CQH.cjs.map → chunk-GZV6AVRL.cjs.map} +1 -1
  133. package/dist/{chunk-RFMBZPOW.cjs → chunk-HCT4HPCL.cjs} +10 -10
  134. package/dist/chunk-HCT4HPCL.cjs.map +1 -0
  135. package/dist/{chunk-OSEG74VJ.js → chunk-HFEJE7AC.js} +52 -43
  136. package/dist/chunk-HFEJE7AC.js.map +1 -0
  137. package/dist/{chunk-52NKC5HT.cjs → chunk-HUFSABUZ.cjs} +12 -8
  138. package/dist/chunk-HUFSABUZ.cjs.map +1 -0
  139. package/dist/{chunk-4CLOXP6H.cjs → chunk-HW7SEELD.cjs} +4 -4
  140. package/dist/{chunk-4CLOXP6H.cjs.map → chunk-HW7SEELD.cjs.map} +1 -1
  141. package/dist/{chunk-ZCIRZE37.cjs → chunk-HWSALKOR.cjs} +26 -17
  142. package/dist/chunk-HWSALKOR.cjs.map +1 -0
  143. package/dist/{chunk-ZSWPZ23K.cjs → chunk-I2PWY7VM.cjs} +5 -5
  144. package/dist/chunk-I2PWY7VM.cjs.map +1 -0
  145. package/dist/{chunk-VJ26EKGJ.cjs → chunk-IJ7M6GOG.cjs} +3 -3
  146. package/dist/chunk-IJ7M6GOG.cjs.map +1 -0
  147. package/dist/{chunk-K5OJUYSZ.js → chunk-IJM7UGS5.js} +19 -10
  148. package/dist/chunk-IJM7UGS5.js.map +1 -0
  149. package/dist/{chunk-SAVIWMZB.js → chunk-ILGZ2ZZV.js} +3 -3
  150. package/dist/chunk-ILGZ2ZZV.js.map +1 -0
  151. package/dist/{chunk-4ZHTIJNE.cjs → chunk-J7J7J2GN.cjs} +87 -63
  152. package/dist/chunk-J7J7J2GN.cjs.map +1 -0
  153. package/dist/{chunk-UALX2J2Q.cjs → chunk-JLRLCBJ4.cjs} +38 -11
  154. package/dist/chunk-JLRLCBJ4.cjs.map +1 -0
  155. package/dist/{chunk-2QDYBS2A.js → chunk-JMDDYA22.js} +4 -4
  156. package/dist/chunk-JMDDYA22.js.map +1 -0
  157. package/dist/{chunk-LXQ6HKPS.js → chunk-JNAA4G4H.js} +3 -3
  158. package/dist/{chunk-LXQ6HKPS.js.map → chunk-JNAA4G4H.js.map} +1 -1
  159. package/dist/{chunk-UMP6OJIM.js → chunk-JOFVLOFY.js} +4 -4
  160. package/dist/{chunk-UMP6OJIM.js.map → chunk-JOFVLOFY.js.map} +1 -1
  161. package/dist/chunk-JTZ74HFD.js +100 -0
  162. package/dist/chunk-JTZ74HFD.js.map +1 -0
  163. package/dist/{chunk-A46SWMIF.js → chunk-K2VMFZQ5.js} +7 -7
  164. package/dist/chunk-K2VMFZQ5.js.map +1 -0
  165. package/dist/{chunk-DN2PACRI.js → chunk-K3NH62DG.js} +461 -282
  166. package/dist/chunk-K3NH62DG.js.map +1 -0
  167. package/dist/{chunk-XWTLIGO3.cjs → chunk-KTTHHYEW.cjs} +5 -5
  168. package/dist/chunk-KTTHHYEW.cjs.map +1 -0
  169. package/dist/{chunk-3FFAEAUJ.cjs → chunk-KVSAY6NZ.cjs} +18 -18
  170. package/dist/chunk-KVSAY6NZ.cjs.map +1 -0
  171. package/dist/{chunk-IAHZCGBE.cjs → chunk-LHSWHYF3.cjs} +120 -146
  172. package/dist/chunk-LHSWHYF3.cjs.map +1 -0
  173. package/dist/{chunk-25BD2R5G.js → chunk-NCGWJ3HS.js} +1991 -1854
  174. package/dist/chunk-NCGWJ3HS.js.map +1 -0
  175. package/dist/{chunk-3OR54XG4.js → chunk-NJWYQWDL.js} +12 -8
  176. package/dist/chunk-NJWYQWDL.js.map +1 -0
  177. package/dist/chunk-NVXXWAU7.cjs +13 -0
  178. package/dist/chunk-NVXXWAU7.cjs.map +1 -0
  179. package/dist/{chunk-2D34UTDC.js → chunk-O6USDERH.js} +31 -11
  180. package/dist/chunk-O6USDERH.js.map +1 -0
  181. package/dist/{chunk-XO4SOZN6.js → chunk-OR6XIWLB.js} +4 -4
  182. package/dist/{chunk-XO4SOZN6.js.map → chunk-OR6XIWLB.js.map} +1 -1
  183. package/dist/{chunk-4PYZ5AX3.cjs → chunk-PRZ3BES7.cjs} +16 -8
  184. package/dist/chunk-PRZ3BES7.cjs.map +1 -0
  185. package/dist/{chunk-HCZD23VS.cjs → chunk-QC55H6RJ.cjs} +65 -39
  186. package/dist/chunk-QC55H6RJ.cjs.map +1 -0
  187. package/dist/{chunk-4O5TGQBW.cjs → chunk-QME6FDFG.cjs} +9 -5
  188. package/dist/chunk-QME6FDFG.cjs.map +1 -0
  189. package/dist/chunk-QOGNZMHD.cjs +34 -0
  190. package/dist/chunk-QOGNZMHD.cjs.map +1 -0
  191. package/dist/{chunk-B2J4ZMZL.cjs → chunk-QWD3CZWE.cjs} +6 -5
  192. package/dist/chunk-QWD3CZWE.cjs.map +1 -0
  193. package/dist/{chunk-SZVR77EJ.cjs → chunk-QWD4RDZ3.cjs} +15 -24
  194. package/dist/chunk-QWD4RDZ3.cjs.map +1 -0
  195. package/dist/{chunk-7BG5UH3T.cjs → chunk-RHZ6HP23.cjs} +4 -4
  196. package/dist/chunk-RHZ6HP23.cjs.map +1 -0
  197. package/dist/{chunk-2HVF2WJY.cjs → chunk-RQMCOFAI.cjs} +8 -8
  198. package/dist/{chunk-2HVF2WJY.cjs.map → chunk-RQMCOFAI.cjs.map} +1 -1
  199. package/dist/{chunk-VKJ7V7EB.cjs → chunk-SA6K24NB.cjs} +3 -3
  200. package/dist/chunk-SA6K24NB.cjs.map +1 -0
  201. package/dist/{chunk-7AD3ZTZL.js → chunk-SAGRF4IB.js} +3 -3
  202. package/dist/chunk-SAGRF4IB.js.map +1 -0
  203. package/dist/{chunk-PUAEFLYK.js → chunk-SVQIW5RJ.js} +4 -4
  204. package/dist/{chunk-PUAEFLYK.js.map → chunk-SVQIW5RJ.js.map} +1 -1
  205. package/dist/{chunk-3O42QOMJ.js → chunk-TA3K7SBK.js} +7 -6
  206. package/dist/chunk-TA3K7SBK.js.map +1 -0
  207. package/dist/{chunk-LYRDF5TQ.cjs → chunk-TFG5IBZS.cjs} +14 -23
  208. package/dist/chunk-TFG5IBZS.cjs.map +1 -0
  209. package/dist/{chunk-GKEFRLU7.cjs → chunk-TMKTSYDS.cjs} +6 -6
  210. package/dist/{chunk-GKEFRLU7.cjs.map → chunk-TMKTSYDS.cjs.map} +1 -1
  211. package/dist/{chunk-J24VJOH3.cjs → chunk-UADQJBHR.cjs} +31 -11
  212. package/dist/chunk-UADQJBHR.cjs.map +1 -0
  213. package/dist/{chunk-TAZVKYWJ.js → chunk-UBR5PWD7.js} +26 -40
  214. package/dist/chunk-UBR5PWD7.js.map +1 -0
  215. package/dist/{chunk-IPYYKCRC.js → chunk-UFPUHJWS.js} +5 -5
  216. package/dist/{chunk-IPYYKCRC.js.map → chunk-UFPUHJWS.js.map} +1 -1
  217. package/dist/{chunk-OHLDPWTA.cjs → chunk-UGRS7ZA7.cjs} +15 -15
  218. package/dist/{chunk-OHLDPWTA.cjs.map → chunk-UGRS7ZA7.cjs.map} +1 -1
  219. package/dist/{chunk-RIAM53CP.js → chunk-UKMBRMGT.js} +3 -3
  220. package/dist/chunk-UKMBRMGT.js.map +1 -0
  221. package/dist/{chunk-L4BDVXIM.js → chunk-UNK4HNJH.js} +97 -123
  222. package/dist/chunk-UNK4HNJH.js.map +1 -0
  223. package/dist/{chunk-C3NT3PVE.js → chunk-V22DZIXO.js} +3 -3
  224. package/dist/chunk-V22DZIXO.js.map +1 -0
  225. package/dist/{chunk-OFRFZRQ4.cjs → chunk-V6ZY4AX6.cjs} +24 -14
  226. package/dist/chunk-V6ZY4AX6.cjs.map +1 -0
  227. package/dist/{chunk-B3IMEBOA.js → chunk-VE6DFSKU.js} +3 -3
  228. package/dist/{chunk-B3IMEBOA.js.map → chunk-VE6DFSKU.js.map} +1 -1
  229. package/dist/{chunk-WLQNMXQE.js → chunk-VWUXIVEI.js} +53 -26
  230. package/dist/chunk-VWUXIVEI.js.map +1 -0
  231. package/dist/{chunk-ACDLHN3W.js → chunk-WJXOICRC.js} +16 -6
  232. package/dist/chunk-WJXOICRC.js.map +1 -0
  233. package/dist/{chunk-JJ3OVRUM.cjs → chunk-WMH2MSOP.cjs} +2250 -2113
  234. package/dist/chunk-WMH2MSOP.cjs.map +1 -0
  235. package/dist/{chunk-7YGCPMGB.js → chunk-XB4GI5RZ.js} +27 -12
  236. package/dist/chunk-XB4GI5RZ.js.map +1 -0
  237. package/dist/{chunk-LXI4XZEC.js → chunk-XCCGNU3D.js} +13 -13
  238. package/dist/chunk-XCCGNU3D.js.map +1 -0
  239. package/dist/{chunk-O73J46PV.js → chunk-XDANGA2C.js} +5 -5
  240. package/dist/{chunk-O73J46PV.js.map → chunk-XDANGA2C.js.map} +1 -1
  241. package/dist/{chunk-UTSRIDKZ.js → chunk-XYFGKVZ7.js} +3 -3
  242. package/dist/chunk-XYFGKVZ7.js.map +1 -0
  243. package/dist/{chunk-RMWTPV3M.cjs → chunk-Y2KYR2ED.cjs} +27 -27
  244. package/dist/chunk-Y2KYR2ED.cjs.map +1 -0
  245. package/dist/{chunk-O7LZFG6O.cjs → chunk-YIFFF23U.cjs} +5 -5
  246. package/dist/chunk-YIFFF23U.cjs.map +1 -0
  247. package/dist/{chunk-4OTIXDMU.cjs → chunk-YJNYDJ2T.cjs} +12 -4
  248. package/dist/chunk-YJNYDJ2T.cjs.map +1 -0
  249. package/dist/{chunk-6JSIEDKL.cjs → chunk-YSTXFWQE.cjs} +13 -7
  250. package/dist/chunk-YSTXFWQE.cjs.map +1 -0
  251. package/dist/{chunk-I6HGWHPU.cjs → chunk-Z3NTRKIC.cjs} +4 -4
  252. package/dist/{chunk-I6HGWHPU.cjs.map → chunk-Z3NTRKIC.cjs.map} +1 -1
  253. package/dist/compact-session-BHTPCIHA.cjs +61 -0
  254. package/dist/{compact-session-QV57KR66.cjs.map → compact-session-BHTPCIHA.cjs.map} +1 -1
  255. package/dist/compact-session-W4WLJTHA.js +24 -0
  256. package/dist/{compact-session-RIGOWC4Y.js.map → compact-session-W4WLJTHA.js.map} +1 -1
  257. package/dist/compaction.cjs +20 -17
  258. package/dist/compaction.d.cts +15 -1
  259. package/dist/compaction.d.ts +15 -1
  260. package/dist/compaction.js +3 -4
  261. package/dist/concurrency.cjs +6 -7
  262. package/dist/concurrency.cjs.map +1 -1
  263. package/dist/concurrency.d.cts +6 -3
  264. package/dist/concurrency.d.ts +6 -3
  265. package/dist/concurrency.js +4 -5
  266. package/dist/concurrency.js.map +1 -1
  267. package/dist/context/index.cjs +6 -6
  268. package/dist/context/index.js +3 -3
  269. package/dist/context-74SBFD27.cjs +23 -0
  270. package/dist/{context-AGQ3DIZU.cjs.map → context-74SBFD27.cjs.map} +1 -1
  271. package/dist/context-NZ2AC6S7.js +6 -0
  272. package/dist/{context-GQRFBCLP.js.map → context-NZ2AC6S7.js.map} +1 -1
  273. package/dist/create-skill.d.ts +4 -1
  274. package/dist/{cron-BuiRPrvt.d.cts → cron-Bw6mSgD4.d.cts} +8 -2
  275. package/dist/{cron-C2SIi31n.d.ts → cron-DJv9oXSZ.d.ts} +8 -2
  276. package/dist/cron.cjs +46 -45
  277. package/dist/cron.d.cts +5 -4
  278. package/dist/cron.d.ts +5 -4
  279. package/dist/cron.js +45 -44
  280. package/dist/{errors-BgJH9PHi.d.cts → errors-CLOAyuiv.d.ts} +133 -95
  281. package/dist/{errors-C5fJUqLk.d.ts → errors-DrDEgyz1.d.cts} +133 -95
  282. package/dist/errors-base-B5g01neU.d.cts +75 -0
  283. package/dist/errors-base-B5g01neU.d.ts +75 -0
  284. package/dist/errors-base.d.ts +73 -0
  285. package/dist/errors.cjs +25 -22
  286. package/dist/errors.d.cts +3 -2
  287. package/dist/errors.d.ts +3 -2
  288. package/dist/errors.js +2 -3
  289. package/dist/eval.cjs +74 -78
  290. package/dist/eval.cjs.map +1 -1
  291. package/dist/eval.js +64 -68
  292. package/dist/eval.js.map +1 -1
  293. package/dist/{executor-6CYCA7MI.cjs → executor-XQAOQOHD.cjs} +60 -54
  294. package/dist/executor-XQAOQOHD.cjs.map +1 -0
  295. package/dist/{executor-QSEC3MRH.js → executor-ZNDQDX6Q.js} +43 -37
  296. package/dist/executor-ZNDQDX6Q.js.map +1 -0
  297. package/dist/filesystem/index.cjs +24 -26
  298. package/dist/filesystem/index.cjs.map +1 -1
  299. package/dist/filesystem/index.js +20 -22
  300. package/dist/filesystem/index.js.map +1 -1
  301. package/dist/filesystem/types.d.cts +11 -5
  302. package/dist/filesystem/types.d.ts +11 -5
  303. package/dist/{fork-agent-RSV4E3EA.js → fork-agent-S2EPIML7.js} +3 -3
  304. package/dist/fork-agent-S2EPIML7.js.map +1 -0
  305. package/dist/{fork-agent-Y2IK2RYU.cjs → fork-agent-WAEQI2DL.cjs} +4 -4
  306. package/dist/fork-agent-WAEQI2DL.cjs.map +1 -0
  307. package/dist/fs-session-store-77JU46UZ.js +10 -0
  308. package/dist/{fs-session-store-NM6YSTE2.js.map → fs-session-store-77JU46UZ.js.map} +1 -1
  309. package/dist/fs-session-store-E4U3P56L.cjs +19 -0
  310. package/dist/{fs-session-store-4PIHT5UX.cjs.map → fs-session-store-E4U3P56L.cjs.map} +1 -1
  311. package/dist/generate-object-BXV7BZRP.js +7 -0
  312. package/dist/{generate-object-GUNAUVBX.js.map → generate-object-BXV7BZRP.js.map} +1 -1
  313. package/dist/generate-object-YBI2TDJ3.cjs +20 -0
  314. package/dist/{generate-object-R7HTMW7F.cjs.map → generate-object-YBI2TDJ3.cjs.map} +1 -1
  315. package/dist/generate-object.d.ts +2 -4
  316. package/dist/index-manager-DXR2RSFI.cjs +26 -0
  317. package/dist/{index-manager-2SRX45WJ.cjs.map → index-manager-DXR2RSFI.cjs.map} +1 -1
  318. package/dist/index-manager-QH6OXEV5.js +17 -0
  319. package/dist/{index-manager-SP4ISSDX.js.map → index-manager-QH6OXEV5.js.map} +1 -1
  320. package/dist/index.cjs +234 -194
  321. package/dist/index.cjs.map +1 -1
  322. package/dist/index.d.cts +243 -41
  323. package/dist/index.d.ts +243 -41
  324. package/dist/index.js +140 -102
  325. package/dist/index.js.map +1 -1
  326. package/dist/{inject-session-DAR7OUCW.js → inject-session-SUM6TDJF.js} +9 -9
  327. package/dist/{inject-session-DAR7OUCW.js.map → inject-session-SUM6TDJF.js.map} +1 -1
  328. package/dist/inject-session-W6A46J3E.cjs +29 -0
  329. package/dist/{inject-session-WQKMC3GR.cjs.map → inject-session-W6A46J3E.cjs.map} +1 -1
  330. package/dist/interactive/index.cjs +12 -6
  331. package/dist/interactive/index.cjs.map +1 -1
  332. package/dist/interactive/index.js +12 -6
  333. package/dist/interactive/index.js.map +1 -1
  334. package/dist/interactive/types.d.cts +14 -4
  335. package/dist/interactive/types.d.ts +14 -4
  336. package/dist/internal/agent-loop/loop-context-init.d.ts +1 -1
  337. package/dist/internal/agent-loop/loop-finalize.d.ts +25 -0
  338. package/dist/internal/agent-loop/loop.d.ts +1 -1
  339. package/dist/internal/agent-loop/message-builders.d.ts +1 -1
  340. package/dist/internal/agent-loop/replay-messages.d.ts +41 -0
  341. package/dist/internal/agent-loop/tool-dispatch.d.ts +2 -2
  342. package/dist/internal/agent-loop/usage-and-cost.d.ts +1 -1
  343. package/dist/internal/auth/credential-availability.d.ts +61 -0
  344. package/dist/internal/auth/credential-store.d.ts +1 -1
  345. package/dist/internal/auth/oauth-device.d.ts +1 -1
  346. package/dist/internal/auth/oauth-engine.d.ts +1 -1
  347. package/dist/internal/auth/resolve-credential.d.ts +1 -1
  348. package/dist/internal/base-url.d.ts +14 -0
  349. package/dist/internal/cloud-agent/cloud-config-serializer.d.ts +1 -1
  350. package/dist/internal/{runtime/concurrency → concurrency}/subagent-credentials.d.ts +2 -2
  351. package/dist/internal/emit-run-event.d.ts +16 -0
  352. package/dist/internal/error-mappers/shared.d.ts +14 -1
  353. package/dist/internal/eval/assert.d.ts +2 -1
  354. package/dist/internal/eval/single-flight.d.ts +2 -1
  355. package/dist/internal/global-singleton.d.ts +6 -3
  356. package/dist/internal/llm/responses.d.ts +10 -0
  357. package/dist/internal/local-agent/local-agent-bootstrap.d.ts +5 -3
  358. package/dist/internal/local-agent/local-agent-capabilities.d.ts +38 -0
  359. package/dist/internal/local-agent/local-agent-dispatch.d.ts +2 -2
  360. package/dist/internal/local-agent/local-agent-memory-provider.d.ts +1 -1
  361. package/dist/internal/local-agent/local-agent-personality-extensions.d.ts +25 -1
  362. package/dist/internal/local-agent/local-agent-send.d.ts +42 -1
  363. package/dist/internal/local-agent/local-option-keys.d.ts +2 -0
  364. package/dist/internal/local-agent/real-local-run-mcp.d.ts +26 -0
  365. package/dist/internal/local-agent/real-local-run-options.d.ts +26 -0
  366. package/dist/internal/local-agent/real-local-run-tools.d.ts +21 -4
  367. package/dist/internal/local-agent/real-local-run.d.ts +2 -2
  368. package/dist/internal/mcp/handshake-timeout.d.ts +53 -0
  369. package/dist/internal/memory/active-memory.d.ts +1 -1
  370. package/dist/internal/memory/adapters/index.cjs +10 -10
  371. package/dist/internal/memory/adapters/index.js +9 -9
  372. package/dist/internal/memory/adapters/openai-embedding.d.cts +10 -0
  373. package/dist/internal/memory/adapters/openai-embedding.d.ts +10 -0
  374. package/dist/internal/memory/corpus-sync.d.ts +23 -0
  375. package/dist/internal/memory/index-db.d.ts +15 -1
  376. package/dist/internal/memory/index-manager-contract.d.ts +12 -0
  377. package/dist/internal/memory/index-manager.d.ts +4 -10
  378. package/dist/internal/memory/index-repository.d.ts +58 -0
  379. package/dist/internal/memory/lance-memory-adapter.d.ts +16 -14
  380. package/dist/internal/memory/memory-index.d.ts +15 -0
  381. package/dist/internal/memory/sdk-memory-peer-loader.d.ts +54 -1
  382. package/dist/internal/memory/storage/index.cjs +39 -40
  383. package/dist/internal/memory/storage/index.js +10 -11
  384. package/dist/internal/memory/storage/memory-root.d.cts +2 -3
  385. package/dist/internal/memory/storage/memory-root.d.ts +2 -3
  386. package/dist/internal/persistence/atomic-write.d.cts +4 -4
  387. package/dist/internal/persistence/atomic-write.d.ts +4 -4
  388. package/dist/internal/persistence/index.cjs +24 -25
  389. package/dist/internal/persistence/index.cjs.map +1 -1
  390. package/dist/internal/persistence/index.js +7 -8
  391. package/dist/internal/persistence/index.js.map +1 -1
  392. package/dist/internal/persistence/jsonl.d.cts +3 -1
  393. package/dist/internal/persistence/jsonl.d.ts +3 -1
  394. package/dist/internal/persistence/paths.d.cts +2 -2
  395. package/dist/internal/persistence/paths.d.ts +2 -2
  396. package/dist/internal/persistence/transcript-ops.d.cts +11 -2
  397. package/dist/internal/persistence/transcript-ops.d.ts +11 -2
  398. package/dist/internal/plugins/context.d.cts +0 -10
  399. package/dist/internal/plugins/context.d.ts +0 -10
  400. package/dist/internal/plugins/types.d.cts +1 -1
  401. package/dist/internal/plugins/types.d.ts +1 -1
  402. package/dist/internal/providers/catalog-schema.d.ts +94 -0
  403. package/dist/internal/providers/catalog-source-models-dev.d.ts +11 -0
  404. package/dist/internal/runtime/compat/foreign-config-sources.d.ts +86 -0
  405. package/dist/internal/runtime/compression/compression-model-registry.d.ts +1 -1
  406. package/dist/internal/runtime/compression/compression-summarizer.d.ts +5 -1
  407. package/dist/internal/runtime/fixtures/fixture-events.d.ts +1 -1
  408. package/dist/internal/runtime/fixtures/fixture-mode.d.ts +8 -14
  409. package/dist/internal/runtime/fixtures/fixture-run-base.d.ts +1 -1
  410. package/dist/internal/runtime/fixtures/fixture-scripts.d.ts +2 -2
  411. package/dist/internal/runtime/hooks/hooks-executor.d.ts +14 -1
  412. package/dist/internal/runtime/hooks/hooks-source.d.ts +9 -0
  413. package/dist/internal/runtime/lifecycle/wrap-completion-check-run.d.ts +1 -1
  414. package/dist/internal/runtime/{memory → memory-glue}/memory-provider.d.ts +1 -1
  415. package/dist/internal/runtime/{plugins → plugin-loader}/plugin-bundles.d.ts +3 -1
  416. package/dist/internal/runtime/processors/wrap-output-run.d.ts +1 -1
  417. package/dist/internal/runtime/registry/live-agent-registry.d.ts +9 -1
  418. package/dist/internal/runtime/system-prompt/local-assembly.d.ts +2 -1
  419. package/dist/internal/scorers/llm-judge.d.ts +12 -0
  420. package/dist/internal/security/index.cjs +14 -15
  421. package/dist/internal/security/index.d.cts +6 -1
  422. package/dist/internal/security/index.d.ts +6 -1
  423. package/dist/internal/security/index.js +4 -5
  424. package/dist/internal/security/path-containment.d.ts +24 -0
  425. package/dist/internal/session/agent-session-store.d.ts +1 -1
  426. package/dist/internal/session/agent-session.d.ts +1 -1
  427. package/dist/internal/session/index.d.ts +1 -1
  428. package/dist/internal/session/session-cache.d.ts +9 -3
  429. package/dist/internal/task/registry.d.ts +1 -1
  430. package/dist/internal/task/store.d.ts +1 -1
  431. package/dist/internal/task/subscribe.d.ts +1 -1
  432. package/dist/internal/task/task-id.d.ts +22 -0
  433. package/dist/internal/telemetry/adapter-registry.d.ts +12 -2
  434. package/dist/internal/telemetry/adapters/braintrust.d.ts +6 -1
  435. package/dist/internal/telemetry/adapters/langsmith.d.ts +6 -1
  436. package/dist/internal/workflow/executor.d.ts +2 -1
  437. package/dist/internal/workflow/snapshot-store.d.ts +1 -1
  438. package/dist/internal/workflow/step-branch.d.ts +2 -2
  439. package/dist/internal/workflow/step-dowhile.d.ts +2 -2
  440. package/dist/internal/workflow/step-execution.d.ts +25 -0
  441. package/dist/internal/workflow/step-foreach.d.ts +2 -2
  442. package/dist/internal/workflow/step-parallel.d.ts +2 -2
  443. package/dist/judge-call-6MVARKU2.js +5 -0
  444. package/dist/{judge-call-LVXABPS3.js.map → judge-call-6MVARKU2.js.map} +1 -1
  445. package/dist/judge-call-I3P4D5QR.cjs +22 -0
  446. package/dist/{judge-call-LAHMBJ57.cjs.map → judge-call-I3P4D5QR.cjs.map} +1 -1
  447. package/dist/mcp-auth.cjs +14 -15
  448. package/dist/mcp-auth.cjs.map +1 -1
  449. package/dist/mcp-auth.d.cts +2 -0
  450. package/dist/mcp-auth.d.ts +2 -0
  451. package/dist/mcp-auth.js +4 -5
  452. package/dist/mcp-auth.js.map +1 -1
  453. package/dist/models.cjs +52 -42
  454. package/dist/models.cjs.map +1 -1
  455. package/dist/models.js +39 -29
  456. package/dist/models.js.map +1 -1
  457. package/dist/oauth-transaction-store-5RIR6D5C.js +5 -0
  458. package/dist/{oauth-transaction-store-W52KVHQ4.js.map → oauth-transaction-store-5RIR6D5C.js.map} +1 -1
  459. package/dist/oauth-transaction-store-SXIE57OD.cjs +38 -0
  460. package/dist/{oauth-transaction-store-BT4GLTLK.cjs.map → oauth-transaction-store-SXIE57OD.cjs.map} +1 -1
  461. package/dist/path-safety.cjs +11 -12
  462. package/dist/path-safety.d.cts +2 -0
  463. package/dist/path-safety.d.ts +2 -0
  464. package/dist/path-safety.js +4 -5
  465. package/dist/permission-engine.d.ts +10 -17
  466. package/dist/persistence.cjs +31 -31
  467. package/dist/persistence.cjs.map +1 -1
  468. package/dist/persistence.d.cts +9 -1
  469. package/dist/persistence.d.ts +9 -1
  470. package/dist/persistence.js +12 -13
  471. package/dist/persistence.js.map +1 -1
  472. package/dist/project.cjs +5 -6
  473. package/dist/project.cjs.map +1 -1
  474. package/dist/project.js +3 -4
  475. package/dist/project.js.map +1 -1
  476. package/dist/providers.cjs +10 -10
  477. package/dist/providers.d.cts +2 -0
  478. package/dist/providers.d.ts +2 -0
  479. package/dist/providers.js +8 -8
  480. package/dist/registry-BZQFYRTL.cjs +46 -0
  481. package/dist/{registry-V7BDQ6QB.cjs.map → registry-BZQFYRTL.cjs.map} +1 -1
  482. package/dist/registry-DMWCJKRF.js +9 -0
  483. package/dist/{registry-75W33OGL.js.map → registry-DMWCJKRF.js.map} +1 -1
  484. package/dist/retry.cjs +4 -5
  485. package/dist/retry.d.cts +20 -5
  486. package/dist/retry.d.ts +20 -5
  487. package/dist/retry.js +3 -4
  488. package/dist/{run-BYSHf58D.d.cts → run-CTAdRU3U.d.cts} +120 -152
  489. package/dist/{run-BYSHf58D.d.ts → run-CTAdRU3U.d.ts} +120 -152
  490. package/dist/{run-until-HEQOUVU6.js → run-until-6D6TQ4JN.js} +27 -59
  491. package/dist/run-until-6D6TQ4JN.js.map +1 -0
  492. package/dist/{run-until-U2B5FJJI.cjs → run-until-DG2KXWB2.cjs} +27 -59
  493. package/dist/run-until-DG2KXWB2.cjs.map +1 -0
  494. package/dist/sandbox/bwrap.d.cts +11 -1
  495. package/dist/sandbox/bwrap.d.ts +11 -1
  496. package/dist/sandbox/index.cjs +26 -30
  497. package/dist/sandbox/index.cjs.map +1 -1
  498. package/dist/sandbox/index.d.cts +8 -1
  499. package/dist/sandbox/index.d.ts +8 -1
  500. package/dist/sandbox/index.js +10 -14
  501. package/dist/sandbox/index.js.map +1 -1
  502. package/dist/sandbox/linux-sandbox.d.cts +20 -4
  503. package/dist/sandbox/linux-sandbox.d.ts +20 -4
  504. package/dist/sandbox/types.d.cts +18 -2
  505. package/dist/sandbox/types.d.ts +18 -2
  506. package/dist/sanitize/index.cjs +2 -2
  507. package/dist/sanitize/index.js +1 -1
  508. package/dist/sanitize/types.d.cts +15 -2
  509. package/dist/sanitize/types.d.ts +15 -2
  510. package/dist/{sdk-agent-D8qJVkuV.d.ts → sdk-agent-Dxjb0IfM.d.cts} +169 -116
  511. package/dist/{sdk-agent-DEoKhA8a.d.cts → sdk-agent-ldzpyAaF.d.ts} +169 -116
  512. package/dist/server/auth/errors.d.cts +4 -3
  513. package/dist/server/auth/errors.d.ts +4 -3
  514. package/dist/server/auth/index.cjs +28 -28
  515. package/dist/server/auth/index.cjs.map +1 -1
  516. package/dist/server/auth/index.d.cts +28 -5
  517. package/dist/server/auth/index.d.ts +28 -5
  518. package/dist/server/auth/index.js +13 -13
  519. package/dist/server/auth/index.js.map +1 -1
  520. package/dist/server/auth/oauth-transaction-store.d.cts +2 -1
  521. package/dist/server/auth/oauth-transaction-store.d.ts +2 -1
  522. package/dist/server/auth/orchestrator.d.cts +4 -1
  523. package/dist/server/auth/orchestrator.d.ts +4 -1
  524. package/dist/server/auth/types.d.cts +18 -0
  525. package/dist/server/auth/types.d.ts +18 -0
  526. package/dist/server/errors-envelope.cjs +14 -15
  527. package/dist/server/errors-envelope.cjs.map +1 -1
  528. package/dist/server/errors-envelope.d.cts +3 -3
  529. package/dist/server/errors-envelope.d.ts +3 -3
  530. package/dist/server/errors-envelope.js +3 -4
  531. package/dist/server/errors-envelope.js.map +1 -1
  532. package/dist/session-transcript-LGHSNVY5.cjs +62 -0
  533. package/dist/{session-transcript-6WNITKRE.cjs.map → session-transcript-LGHSNVY5.cjs.map} +1 -1
  534. package/dist/session-transcript-VTBTCGQX.js +5 -0
  535. package/dist/{session-transcript-XAEKW6P7.js.map → session-transcript-VTBTCGQX.js.map} +1 -1
  536. package/dist/skills.cjs +8 -9
  537. package/dist/skills.js +6 -7
  538. package/dist/stream-object-HBFMIZLD.js +7 -0
  539. package/dist/{stream-object-UF4QRQRU.js.map → stream-object-HBFMIZLD.js.map} +1 -1
  540. package/dist/stream-object-QSKHISDJ.cjs +20 -0
  541. package/dist/{stream-object-ZJTQNKY3.cjs.map → stream-object-QSKHISDJ.cjs.map} +1 -1
  542. package/dist/stream-object.d.ts +2 -4
  543. package/dist/subagents-loader-LSKM2UIK.js +7 -0
  544. package/dist/{subagents-loader-CRT5LLL3.js.map → subagents-loader-LSKM2UIK.js.map} +1 -1
  545. package/dist/subagents-loader-YWFE7KYE.cjs +16 -0
  546. package/dist/{subagents-loader-YEUFFPAL.cjs.map → subagents-loader-YWFE7KYE.cjs.map} +1 -1
  547. package/dist/subagents-loader.cjs +7 -8
  548. package/dist/subagents-loader.cjs.map +1 -1
  549. package/dist/subagents-loader.d.cts +5 -3
  550. package/dist/subagents-loader.d.ts +5 -3
  551. package/dist/subagents-loader.js +5 -6
  552. package/dist/subagents-loader.js.map +1 -1
  553. package/dist/subagents.cjs +2 -2
  554. package/dist/subagents.cjs.map +1 -1
  555. package/dist/subagents.js +1 -1
  556. package/dist/subagents.js.map +1 -1
  557. package/dist/subscription/define-subscription.d.cts +4 -1
  558. package/dist/subscription/define-subscription.d.ts +4 -1
  559. package/dist/subscription/index.cjs +4 -5
  560. package/dist/subscription/index.cjs.map +1 -1
  561. package/dist/subscription/index.d.cts +2 -0
  562. package/dist/subscription/index.d.ts +2 -0
  563. package/dist/subscription/index.js +3 -4
  564. package/dist/subscription/index.js.map +1 -1
  565. package/dist/subscription/internal/server-integration.d.cts +5 -0
  566. package/dist/subscription/internal/server-integration.d.ts +5 -0
  567. package/dist/subscription/internal/subscription-runtime.d.cts +13 -1
  568. package/dist/subscription/internal/subscription-runtime.d.ts +13 -1
  569. package/dist/task-errors.d.ts +58 -0
  570. package/dist/task-store.cjs +7 -8
  571. package/dist/task-store.d.cts +2 -0
  572. package/dist/task-store.d.ts +2 -0
  573. package/dist/task-store.js +4 -5
  574. package/dist/types/agent-prims.d.ts +21 -0
  575. package/dist/types/agent.d.ts +63 -15
  576. package/dist/types/batch.d.ts +3 -0
  577. package/dist/types/budget-tracker.d.ts +3 -0
  578. package/dist/types/budget.d.ts +12 -3
  579. package/dist/types/content-blocks.d.ts +3 -0
  580. package/dist/types/context.d.ts +3 -0
  581. package/dist/types/conversation.d.ts +5 -0
  582. package/dist/types/cron.d.ts +5 -0
  583. package/dist/types/env-policy.d.ts +3 -0
  584. package/dist/types/eval.d.ts +3 -0
  585. package/dist/types/fork.d.ts +3 -0
  586. package/dist/types/goal-events.d.ts +3 -0
  587. package/dist/types/mcp.d.ts +5 -0
  588. package/dist/types/memory-adapter.d.ts +3 -0
  589. package/dist/types/memory-provider.d.ts +44 -5
  590. package/dist/types/messages-base.d.ts +4 -0
  591. package/dist/types/messages.d.ts +5 -0
  592. package/dist/types/plugin.d.ts +32 -4
  593. package/dist/types/processors.d.ts +3 -0
  594. package/dist/types/provider-profile.d.ts +3 -0
  595. package/dist/types/providers.d.ts +3 -0
  596. package/dist/types/run-events.d.ts +36 -9
  597. package/dist/types/run.d.ts +29 -2
  598. package/dist/types/sdk-agent.d.ts +43 -0
  599. package/dist/types/session-message.d.ts +3 -0
  600. package/dist/types/session-record.d.ts +3 -0
  601. package/dist/types/session-store.d.ts +45 -0
  602. package/dist/types/task.d.ts +3 -11
  603. package/dist/types/theokit.d.ts +3 -0
  604. package/dist/types/trajectory.d.ts +3 -0
  605. package/dist/types/updates.d.ts +5 -0
  606. package/dist/types/usage.d.ts +4 -1
  607. package/dist/types/workflow.d.ts +13 -135
  608. package/dist/workflow-as-tool.d.ts +66 -0
  609. package/dist/workflow-errors.d.ts +164 -0
  610. package/dist/workflow.cjs +29 -30
  611. package/dist/workflow.d.cts +135 -74
  612. package/dist/workflow.d.ts +135 -74
  613. package/dist/workflow.js +8 -9
  614. package/docs/adr/README.md +2604 -0
  615. package/docs/error-codes.md +137 -103
  616. package/docs/harness-capability-map.md +30 -20
  617. package/docs/memory-decisions.md +1 -1
  618. package/package.json +3 -7
  619. package/bin/theokit-migrate-config.mjs +0 -278
  620. package/bin/theokit-migrate-memory.mjs +0 -116
  621. package/dist/agent-3JK7VXNN.js +0 -57
  622. package/dist/agent-PVINJTUR.cjs +0 -66
  623. package/dist/agent-session-store-6EL5NPA4.cjs +0 -24
  624. package/dist/agent-session-store-OPGRB4XM.js +0 -7
  625. package/dist/batch-BXYTW2DP.cjs.map +0 -1
  626. package/dist/batch-L4ZXS46M.js.map +0 -1
  627. package/dist/chunk-25BD2R5G.js.map +0 -1
  628. package/dist/chunk-2D34UTDC.js.map +0 -1
  629. package/dist/chunk-2GUYQR5P.js.map +0 -1
  630. package/dist/chunk-2QDYBS2A.js.map +0 -1
  631. package/dist/chunk-3FFAEAUJ.cjs.map +0 -1
  632. package/dist/chunk-3O42QOMJ.js.map +0 -1
  633. package/dist/chunk-3OR54XG4.js.map +0 -1
  634. package/dist/chunk-4FFBAUFS.js.map +0 -1
  635. package/dist/chunk-4O5TGQBW.cjs.map +0 -1
  636. package/dist/chunk-4OTIXDMU.cjs.map +0 -1
  637. package/dist/chunk-4PYZ5AX3.cjs.map +0 -1
  638. package/dist/chunk-4QZSA2HJ.js.map +0 -1
  639. package/dist/chunk-4ZHTIJNE.cjs.map +0 -1
  640. package/dist/chunk-52NKC5HT.cjs.map +0 -1
  641. package/dist/chunk-6HKGLTJI.cjs.map +0 -1
  642. package/dist/chunk-6JSIEDKL.cjs.map +0 -1
  643. package/dist/chunk-7AD3ZTZL.js.map +0 -1
  644. package/dist/chunk-7BG5UH3T.cjs.map +0 -1
  645. package/dist/chunk-7YGCPMGB.js.map +0 -1
  646. package/dist/chunk-A46SWMIF.js.map +0 -1
  647. package/dist/chunk-A4JVILQU.js.map +0 -1
  648. package/dist/chunk-ACDLHN3W.js.map +0 -1
  649. package/dist/chunk-AQO3NSRG.cjs +0 -41
  650. package/dist/chunk-AQO3NSRG.cjs.map +0 -1
  651. package/dist/chunk-AWO27VRZ.js.map +0 -1
  652. package/dist/chunk-B2J4ZMZL.cjs.map +0 -1
  653. package/dist/chunk-B4EOJWOY.cjs.map +0 -1
  654. package/dist/chunk-BU4KFWXF.js.map +0 -1
  655. package/dist/chunk-BZRFXJHA.js.map +0 -1
  656. package/dist/chunk-C3NT3PVE.js.map +0 -1
  657. package/dist/chunk-C72AZW7J.js.map +0 -1
  658. package/dist/chunk-CQBXOJ6U.cjs.map +0 -1
  659. package/dist/chunk-D4CUGAKZ.js.map +0 -1
  660. package/dist/chunk-DN2PACRI.js.map +0 -1
  661. package/dist/chunk-DXGZ2NUG.cjs.map +0 -1
  662. package/dist/chunk-EG4QM7ZJ.cjs +0 -39
  663. package/dist/chunk-EG4QM7ZJ.cjs.map +0 -1
  664. package/dist/chunk-GPKAF7SG.js.map +0 -1
  665. package/dist/chunk-HCZD23VS.cjs.map +0 -1
  666. package/dist/chunk-HS7AVXTF.js.map +0 -1
  667. package/dist/chunk-IAHZCGBE.cjs.map +0 -1
  668. package/dist/chunk-J24VJOH3.cjs.map +0 -1
  669. package/dist/chunk-JJ3OVRUM.cjs.map +0 -1
  670. package/dist/chunk-JPBKYL3B.cjs +0 -18
  671. package/dist/chunk-JPBKYL3B.cjs.map +0 -1
  672. package/dist/chunk-K5OJUYSZ.js.map +0 -1
  673. package/dist/chunk-KQ7TS7WW.cjs.map +0 -1
  674. package/dist/chunk-KQRW2GPZ.js.map +0 -1
  675. package/dist/chunk-KYAJINUI.cjs.map +0 -1
  676. package/dist/chunk-L3MTL4NA.js.map +0 -1
  677. package/dist/chunk-L4BDVXIM.js.map +0 -1
  678. package/dist/chunk-LXI4XZEC.js.map +0 -1
  679. package/dist/chunk-LYRDF5TQ.cjs.map +0 -1
  680. package/dist/chunk-N2U4AZGB.js.map +0 -1
  681. package/dist/chunk-O7DK5PBJ.cjs.map +0 -1
  682. package/dist/chunk-O7LZFG6O.cjs.map +0 -1
  683. package/dist/chunk-OFRFZRQ4.cjs.map +0 -1
  684. package/dist/chunk-OSEG74VJ.js.map +0 -1
  685. package/dist/chunk-RFMBZPOW.cjs.map +0 -1
  686. package/dist/chunk-RFXWMRFC.js.map +0 -1
  687. package/dist/chunk-RIAM53CP.js.map +0 -1
  688. package/dist/chunk-RMWTPV3M.cjs.map +0 -1
  689. package/dist/chunk-RNB4APBZ.js.map +0 -1
  690. package/dist/chunk-SAVIWMZB.js.map +0 -1
  691. package/dist/chunk-SZVR77EJ.cjs.map +0 -1
  692. package/dist/chunk-TAZVKYWJ.js.map +0 -1
  693. package/dist/chunk-U54XCYG3.js.map +0 -1
  694. package/dist/chunk-U6IFHFWK.js.map +0 -1
  695. package/dist/chunk-UALX2J2Q.cjs.map +0 -1
  696. package/dist/chunk-UBDMVMBZ.js.map +0 -1
  697. package/dist/chunk-UFLD2HEV.js +0 -35
  698. package/dist/chunk-UFLD2HEV.js.map +0 -1
  699. package/dist/chunk-UGT7GK7I.cjs.map +0 -1
  700. package/dist/chunk-UNYXQ4M5.js.map +0 -1
  701. package/dist/chunk-UTSRIDKZ.js.map +0 -1
  702. package/dist/chunk-UU36SHFY.cjs.map +0 -1
  703. package/dist/chunk-V2BOS4WF.cjs.map +0 -1
  704. package/dist/chunk-VJ26EKGJ.cjs.map +0 -1
  705. package/dist/chunk-VKJ7V7EB.cjs.map +0 -1
  706. package/dist/chunk-VLVVJLDH.cjs.map +0 -1
  707. package/dist/chunk-WLQNMXQE.js.map +0 -1
  708. package/dist/chunk-WNO3C3N2.cjs.map +0 -1
  709. package/dist/chunk-WTMU7J4U.js +0 -14
  710. package/dist/chunk-WTMU7J4U.js.map +0 -1
  711. package/dist/chunk-XEQ3TM66.js +0 -35
  712. package/dist/chunk-XEQ3TM66.js.map +0 -1
  713. package/dist/chunk-XJCXEKMD.cjs.map +0 -1
  714. package/dist/chunk-XL7Q7HB2.cjs.map +0 -1
  715. package/dist/chunk-XWTLIGO3.cjs.map +0 -1
  716. package/dist/chunk-YML4ME27.cjs.map +0 -1
  717. package/dist/chunk-ZCIRZE37.cjs.map +0 -1
  718. package/dist/chunk-ZSWPZ23K.cjs.map +0 -1
  719. package/dist/chunk-ZWRG4NWT.cjs.map +0 -1
  720. package/dist/chunk-ZZMZWBR6.js.map +0 -1
  721. package/dist/compact-session-QV57KR66.cjs +0 -59
  722. package/dist/compact-session-RIGOWC4Y.js +0 -22
  723. package/dist/context-AGQ3DIZU.cjs +0 -24
  724. package/dist/context-GQRFBCLP.js +0 -7
  725. package/dist/executor-6CYCA7MI.cjs.map +0 -1
  726. package/dist/executor-QSEC3MRH.js.map +0 -1
  727. package/dist/fork-agent-RSV4E3EA.js.map +0 -1
  728. package/dist/fork-agent-Y2IK2RYU.cjs.map +0 -1
  729. package/dist/fs-session-store-4PIHT5UX.cjs +0 -20
  730. package/dist/fs-session-store-NM6YSTE2.js +0 -11
  731. package/dist/generate-object-GUNAUVBX.js +0 -8
  732. package/dist/generate-object-R7HTMW7F.cjs +0 -21
  733. package/dist/index-manager-2SRX45WJ.cjs +0 -27
  734. package/dist/index-manager-SP4ISSDX.js +0 -18
  735. package/dist/inject-session-WQKMC3GR.cjs +0 -29
  736. package/dist/internal/persistence/credential-pool-store.d.cts +0 -32
  737. package/dist/internal/persistence/credential-pool-store.d.ts +0 -32
  738. package/dist/internal/runtime/memory/memory-path-selector.d.ts +0 -73
  739. package/dist/judge-call-LAHMBJ57.cjs +0 -23
  740. package/dist/judge-call-LVXABPS3.js +0 -6
  741. package/dist/oauth-transaction-store-BT4GLTLK.cjs +0 -36
  742. package/dist/oauth-transaction-store-W52KVHQ4.js +0 -3
  743. package/dist/registry-75W33OGL.js +0 -10
  744. package/dist/registry-V7BDQ6QB.cjs +0 -47
  745. package/dist/run-until-HEQOUVU6.js.map +0 -1
  746. package/dist/run-until-U2B5FJJI.cjs.map +0 -1
  747. package/dist/server/adapter/express.d.cts +0 -9
  748. package/dist/server/adapter/express.d.ts +0 -9
  749. package/dist/server/adapter/fastify.d.cts +0 -9
  750. package/dist/server/adapter/fastify.d.ts +0 -9
  751. package/dist/server/adapter/hono.d.cts +0 -9
  752. package/dist/server/adapter/hono.d.ts +0 -9
  753. package/dist/server/adapter/shared-handler.d.cts +0 -9
  754. package/dist/server/adapter/shared-handler.d.ts +0 -9
  755. package/dist/server/adapter/types.d.cts +0 -33
  756. package/dist/server/adapter/types.d.ts +0 -33
  757. package/dist/session-transcript-6WNITKRE.cjs +0 -63
  758. package/dist/session-transcript-XAEKW6P7.js +0 -6
  759. package/dist/stream-object-UF4QRQRU.js +0 -8
  760. package/dist/stream-object-ZJTQNKY3.cjs +0 -21
  761. package/dist/subagents-loader-CRT5LLL3.js +0 -8
  762. package/dist/subagents-loader-YEUFFPAL.cjs +0 -17
  763. /package/dist/{batch.d.ts → internal/agent/batch.d.ts} +0 -0
  764. /package/dist/{agent-helpers.d.ts → internal/agent/helpers.d.ts} +0 -0
  765. /package/dist/internal/agent-loop/{loop-types.d.ts → types.d.ts} +0 -0
  766. /package/dist/internal/auth/{auth-types.d.ts → types.d.ts} +0 -0
  767. /package/dist/internal/cloud-agent/{cloud-payload-types.d.ts → types.d.ts} +0 -0
  768. /package/dist/internal/{runtime/concurrency → concurrency}/abort-utils.d.ts +0 -0
  769. /package/dist/internal/{runtime/concurrency → concurrency}/async-local-storage.d.ts +0 -0
  770. /package/dist/internal/{runtime/concurrency → concurrency}/async-semaphore.d.ts +0 -0
  771. /package/dist/internal/{runtime/concurrency → concurrency}/delegation-depth.d.ts +0 -0
  772. /package/dist/internal/{runtime/concurrency → concurrency}/map-with-concurrency.d.ts +0 -0
  773. /package/dist/internal/{runtime/retry → error-mappers}/default-retriable.d.ts +0 -0
  774. /package/dist/internal/{runtime/fixtures/fixture-types.d.ts → memory/storage/list-markdown.d.cts} +0 -0
  775. /package/dist/internal/{runtime/plugins/plugins-manager.d.ts → memory/storage/list-markdown.d.ts} +0 -0
  776. /package/dist/internal/{resilience → retry}/circuit-breaker.d.ts +0 -0
  777. /package/dist/internal/{runtime/retry → retry}/with-retry.d.ts +0 -0
  778. /package/dist/internal/{security/secret-redactor.d.cts → runtime/fixtures/types.d.ts} +0 -0
  779. /package/dist/internal/runtime/{memory → memory-glue}/memory-store.d.ts +0 -0
  780. /package/dist/internal/runtime/{memory → memory-glue}/select-facts.d.ts +0 -0
  781. /package/dist/internal/runtime/{plugins → plugin-loader}/plugin-frontmatter.d.ts +0 -0
  782. /package/dist/internal/{security/secret-redactor.d.ts → runtime/plugin-loader/plugins-manager.d.ts} +0 -0
  783. /package/dist/internal/runtime/{reasoning → system-prompt}/native-reasoning.d.ts +0 -0
  784. /package/dist/internal/{runtime/context/path-containment.d.ts → security/path-containment.d.cts} +0 -0
  785. /package/dist/internal/session/{session-types.d.ts → types.d.ts} +0 -0
  786. /package/dist/internal/{zod/to-json-schema.d.ts → zod-to-json-schema.d.ts} +0 -0
  787. /package/dist/subscription/internal/{adapter-types.d.cts → types.d.cts} +0 -0
  788. /package/dist/subscription/internal/{adapter-types.d.ts → types.d.ts} +0 -0
@@ -1,39 +1,39 @@
1
- import { submit, emitRunEvent } from './chunk-A46SWMIF.js';
2
- import { enqueueSessionWrite, hydrateSession, persistTurnToTranscript, flushSessionWrites, appendSessionMessage, getSessionMessages, discardSession, clearSession } from './chunk-4FFBAUFS.js';
3
- import { IndexManager } from './chunk-L3MTL4NA.js';
4
- import { loadHookConfig, warnOnce, currentPersonalityContext, warnPersonalitySwitchInsideFork } from './chunk-K5OJUYSZ.js';
1
+ import { submit, emitRunEvent } from './chunk-K2VMFZQ5.js';
2
+ import { enqueueSessionWrite, hydrateSession, persistTurnToTranscript, flushSessionWrites, appendSessionMessage, getSessionMessages, discardSession, clearSession } from './chunk-AWINL3ZC.js';
3
+ import { IndexManager } from './chunk-2ZLVT7H3.js';
4
+ import { loadHookConfig, warnOnce, currentPersonalityContext, warnPersonalitySwitchInsideFork } from './chunk-IJM7UGS5.js';
5
5
  import { extractCodePlugins } from './chunk-2SFBB54R.js';
6
- import { createOpenAiCompatibleRuntime } from './chunk-UBDMVMBZ.js';
7
- import { persistActiveMemoryTranscript } from './chunk-XO4SOZN6.js';
8
- import { resolveMemoryRoot, writeSessionSummary, MEMORY_KINDS, appendFact, readFacts, legacyMemoryJsonPath, memoryMdPath, appendFactToMarkdown } from './chunk-L4BDVXIM.js';
9
- import { FsSessionStore } from './chunk-BP46RJ5X.js';
10
- import { discoverProviderPlugins, getConfiguredBaseUrl, httpRequest, isFixtureApiKey, presentProviderCredentialEnvVars, CircuitBreaker, buildDefaultSummarizer, shouldUseRealLocalRuntime, parseSseStream, resolveProviderChain, inferProviderFromApiKey, detectPrimaryProvider, warnProviderPrecedenceOnce, tryFirstEvent, relayStream, renderToolResultContentText } from './chunk-DN2PACRI.js';
6
+ import { createOpenAiCompatibleRuntime } from './chunk-55GB6JYQ.js';
7
+ import { persistActiveMemoryTranscript } from './chunk-OR6XIWLB.js';
8
+ import { writeSessionSummary, resolveMemoryRoot, MEMORY_KINDS, appendFact, readFacts, legacyMemoryJsonPath, memoryMdPath, appendFactToMarkdown } from './chunk-UNK4HNJH.js';
9
+ import { FsSessionStore } from './chunk-AAEZSPTC.js';
10
+ import { discoverProviderPlugins, validateApiKeyShape, getConfiguredBaseUrl, httpRequest, isFixtureApiKey, presentProviderCredentialEnvVars, buildDefaultSummarizer, shouldUseRealLocalRuntime, parseSseStream, CircuitBreaker, resolveRunProvider, mergeExplicitApiKey, resolveProviderChain, abortError, tryFirstEvent, relayStream, renderToolResultContentText } from './chunk-K3NH62DG.js';
11
11
  import { resolveChildEnv } from './chunk-HKCKOAIO.js';
12
- import { DEFAULT_MAX_BYTES_PER_FILE, runDiscovery, truncateWithMarker } from './chunk-SAVIWMZB.js';
13
- import { readVersionedJson, writeVersionedJson } from './chunk-PUAEFLYK.js';
14
- import { toJsonSchema } from './chunk-4VPXM6UU.js';
15
- import { sanitizeToolInput } from './chunk-U54XCYG3.js';
16
- import { withInheritedSubAgentCredentials, subAgentToolsFromDefinitions } from './chunk-RNB4APBZ.js';
12
+ import { DEFAULT_MAX_BYTES_PER_FILE, runDiscovery, truncateWithMarker } from './chunk-ILGZ2ZZV.js';
13
+ import { readVersionedJson, writeVersionedJson } from './chunk-SVQIW5RJ.js';
14
+ import { toJsonSchema } from './chunk-7I5Z3UBJ.js';
15
+ import { sanitizeToolInput } from './chunk-FJWQP6EE.js';
16
+ import { withInheritedSubAgentCredentials, subAgentToolsFromDefinitions } from './chunk-6WAKKTBO.js';
17
17
  import { setAgentFacade } from './chunk-6X6ID4MO.js';
18
- import { escapeBlockBody, buildSkillsBlock, discoverSkills, stripSkillFrontmatter } from './chunk-O73J46PV.js';
19
- import { withToolWhitelist, checkToolWhitelist } from './chunk-7AD3ZTZL.js';
20
- import { validateArtifactPath, PathTraversalError, safePathJoin } from './chunk-HS7AVXTF.js';
21
- import { insideRoot, atOrInsideRoot } from './chunk-RIAM53CP.js';
22
- import { mapWithConcurrency } from './chunk-C72AZW7J.js';
23
- import { expandTilde, defaultBaseDir } from './chunk-UMP6OJIM.js';
24
- import { withFileLock } from './chunk-3O42QOMJ.js';
18
+ import { escapeBlockBody, buildSkillsBlock, discoverSkills, stripSkillFrontmatter } from './chunk-XDANGA2C.js';
19
+ import { withToolWhitelist, checkToolWhitelist } from './chunk-SAGRF4IB.js';
20
+ import { validateArtifactPath, PathTraversalError, safePathJoin } from './chunk-EH6XD3FY.js';
21
+ import { insideRoot, atOrInsideRoot } from './chunk-UKMBRMGT.js';
22
+ import { mapWithConcurrency } from './chunk-4MMWFSCD.js';
23
+ import { expandTilde, defaultBaseDir } from './chunk-JOFVLOFY.js';
24
+ import { withFileLock } from './chunk-TA3K7SBK.js';
25
25
  import { withCwdMutex } from './chunk-Q5EWJPRY.js';
26
- import { atomicWriteJson } from './chunk-2GUYQR5P.js';
27
- import { loadSubagents, pluginBundleDirs } from './chunk-LXI4XZEC.js';
28
- import { getTheokitHome, projectConfigRoots, pluginBundleRoots } from './chunk-UFLD2HEV.js';
29
- import { readWorkspaceDir, parseSimpleYaml } from './chunk-LXQ6HKPS.js';
30
- import { resolveEffectiveContextWindow, CONTEXT_WINDOW_FLOOR, CONTEXT_WINDOW_MARGIN } from './chunk-A4JVILQU.js';
26
+ import { sweepStaleAtomicTemps, atomicWriteJson } from './chunk-3JHIFQ4I.js';
27
+ import { loadSubagents, pluginBundleDirs } from './chunk-XCCGNU3D.js';
28
+ import { reportUndeclaredSources, undefinedVariablesIn, getTheokitHome, adapterForConfigPath, projectConfigRoots, pluginBundleRoots } from './chunk-JTZ74HFD.js';
29
+ import { readWorkspaceDir, parseSimpleYaml } from './chunk-JNAA4G4H.js';
30
+ import { resolveEffectiveContextWindow, CONTEXT_WINDOW_FLOOR, CONTEXT_WINDOW_MARGIN } from './chunk-6M2OIS4Y.js';
31
31
  import { parseModelId } from './chunk-R7WIIPUR.js';
32
- import { getProviderProfile } from './chunk-UTSRIDKZ.js';
33
- import { getCatalogModelInfo, registerBuiltins, getProviderProfile as getProviderProfile$1, registerProvider, isPatchedModelKey } from './chunk-WLQNMXQE.js';
34
- import { AgentRunError, coerceToKnownAgentRunErrorCode, UnknownAgentError, ConfigurationError, AuthenticationError, AgentDisposedError, UnsupportedRunOperationError, NetworkError, TheokitAgentError } from './chunk-ZZMZWBR6.js';
35
- import { resolveApiKey, API_KEY_ENV_VAR, redactSecrets } from './chunk-D4CUGAKZ.js';
36
- import { diag, diagFailure } from './chunk-XEQ3TM66.js';
32
+ import { getProviderProfile } from './chunk-XYFGKVZ7.js';
33
+ import { getCatalogModelInfo, isPatchedModelKey } from './chunk-VWUXIVEI.js';
34
+ import { globalSingleton } from './chunk-AGACYRJ2.js';
35
+ import { AgentRunError, coerceToKnownAgentRunErrorCode, UnknownAgentError, ConfigurationError, AuthenticationError, AgentDisposedError, UnsupportedRunOperationError, NetworkError, TheokitAgentError } from './chunk-ALUN2B4W.js';
36
+ import { diag, resolveApiKey, API_KEY_ENV_VAR, redactSecrets, diagFailure } from './chunk-CZJ6Q7CW.js';
37
37
  import { stat, mkdir, readFile, readdir, access, unlink } from 'fs/promises';
38
38
  import { randomUUID, createHash } from 'crypto';
39
39
  import { join, dirname, resolve, isAbsolute } from 'path';
@@ -149,77 +149,6 @@ var AgentBuilder = class {
149
149
  }
150
150
  };
151
151
 
152
- // src/internal/auth/api-key-validator.ts
153
- var FIXTURE_KEY_PREFIX = "theo_test_";
154
- var LOCAL_RUNTIME_MOCK_KEY = "local";
155
- var MIN_KEY_LENGTH = 16;
156
- var KNOWN_PROVIDER_PREFIXES = [
157
- { provider: "openai", prefix: "sk-" },
158
- { provider: "anthropic", prefix: "sk-ant-" },
159
- { provider: "openrouter", prefix: "sk-or-" }
160
- ];
161
- function validateApiKeyShape(key, options = {}) {
162
- const opts = typeof options === "string" ? { provider: options } : options;
163
- const tier1 = checkTier1(key);
164
- if (tier1.malformed) return tier1;
165
- const validKey = key;
166
- if (validKey.startsWith(FIXTURE_KEY_PREFIX) || validKey === LOCAL_RUNTIME_MOCK_KEY) {
167
- return { malformed: false };
168
- }
169
- if (opts.strict === false) return { malformed: false };
170
- return checkTier2(validKey, opts.provider);
171
- }
172
- function checkTier1(key) {
173
- if (key === void 0 || key.length === 0) {
174
- return { malformed: true, reason: "empty", message: "API key is empty." };
175
- }
176
- if (key.trim().length === 0) {
177
- return {
178
- malformed: true,
179
- reason: "whitespace_only",
180
- message: "API key contains only whitespace."
181
- };
182
- }
183
- if (key.length < 4) {
184
- return {
185
- malformed: true,
186
- reason: "too_short",
187
- message: `API key must be at least 4 chars (got ${key.length}).`
188
- };
189
- }
190
- return { malformed: false };
191
- }
192
- function checkTier2(key, provider) {
193
- if (key.length < MIN_KEY_LENGTH) {
194
- return {
195
- malformed: true,
196
- reason: "too_short",
197
- message: `API key must be at least ${MIN_KEY_LENGTH} chars (got ${key.length}).`
198
- };
199
- }
200
- if (/\s/.test(key)) {
201
- return {
202
- malformed: true,
203
- reason: "embedded_whitespace",
204
- message: "API key contains embedded whitespace."
205
- };
206
- }
207
- return checkProviderPrefix(key, provider);
208
- }
209
- function checkProviderPrefix(key, provider) {
210
- if (provider === void 0) return { malformed: false };
211
- const hint = KNOWN_PROVIDER_PREFIXES.find((p) => p.provider === provider.toLowerCase());
212
- if (hint === void 0) return { malformed: false };
213
- if (!key.startsWith(hint.prefix)) {
214
- return {
215
- malformed: true,
216
- reason: "missing_known_prefix",
217
- message: `API key for provider "${hint.provider}" expected to start with "${hint.prefix}".`
218
- };
219
- }
220
- return { malformed: false };
221
- }
222
-
223
152
  // src/internal/runtime/config/default-model.ts
224
153
  var DEFAULT_AGENTIC_MODEL_ID = "google/gemini-2.0-flash-001";
225
154
 
@@ -228,7 +157,7 @@ async function agentGenerate(agent, agentModel, agentApiKey, agentLocal, input,
228
157
  const { output, maxRetries, errorStrategy, ...sendOptions } = options;
229
158
  const run = await agent.send(input, sendOptions);
230
159
  const result = await run.wait();
231
- const { generateObjectImpl, GenerateObjectError } = await import('./generate-object-GUNAUVBX.js');
160
+ const { generateObjectImpl, GenerateObjectError } = await import('./generate-object-BXV7BZRP.js');
232
161
  const answer = structurableAnswerOrThrow(result, GenerateObjectError);
233
162
  const { getAgentFacade } = await import('./agent-factory-registry-ZVTABLEY.js');
234
163
  const facade = getAgentFacade();
@@ -262,21 +191,21 @@ async function agentGenerate(agent, agentModel, agentApiKey, agentLocal, input,
262
191
  function structurableAnswerOrThrow(result, GenerateObjectError) {
263
192
  if (result.status === "error") {
264
193
  throw new GenerateObjectError(
265
- "no_tool_call",
194
+ "upstream_run_failed",
266
195
  `Agent run failed before an answer could be structured: ${result.error?.message ?? "unknown error"} [${result.error?.code ?? "?"}]`,
267
196
  result.error
268
197
  );
269
198
  }
270
199
  if (result.status === "cancelled") {
271
200
  throw new GenerateObjectError(
272
- "no_tool_call",
201
+ "run_cancelled",
273
202
  "Agent run was cancelled before an answer could be structured."
274
203
  );
275
204
  }
276
205
  const answer = result.result;
277
206
  if (answer === void 0 || answer.length === 0) {
278
207
  throw new GenerateObjectError(
279
- "no_tool_call",
208
+ "no_text_answer",
280
209
  "The tool loop finished with no text answer (tool-only completion) \u2014 there is nothing to structure."
281
210
  );
282
211
  }
@@ -453,6 +382,7 @@ function registryPath(cwd) {
453
382
  return join(cwd, REGISTRY_RELATIVE_PATH);
454
383
  }
455
384
  async function loadRegistry(cwd) {
385
+ void sweepStaleAtomicTemps(registryPath(cwd)).catch(() => void 0);
456
386
  return readVersionedJson({
457
387
  path: registryPath(cwd),
458
388
  currentVersion: SCHEMA_VERSION,
@@ -917,7 +847,7 @@ async function migrateLegacyJson(cwd, config) {
917
847
  return writeMigratedFacts(cwd, jsonPath, facts);
918
848
  }
919
849
 
920
- // src/internal/runtime/memory/memory-store.ts
850
+ // src/internal/runtime/memory-glue/memory-store.ts
921
851
  var REMEMBER_PATTERN = /^\s*Remember(?:\s+this\s+durable\s+preference)?\s*(?:\((user|feedback|project|reference)\))?\s*:\s*(.+)$/i;
922
852
  function isMemoryWritePrompt(message) {
923
853
  return REMEMBER_PATTERN.test(message) || message.includes("Remember this durable");
@@ -1813,7 +1743,28 @@ function safeParse(data2) {
1813
1743
  }
1814
1744
 
1815
1745
  // src/internal/cloud-agent/cloud-agent.ts
1816
- var CloudAgent = class {
1746
+ var CloudAgent = class _CloudAgent {
1747
+ /**
1748
+ * Operations this runtime does not perform. See {@link SDKAgent.supports} for why asking beats
1749
+ * catching: the members below are present on the type — some REQUIRED — and answering them by
1750
+ * throwing is what makes a caller unable to branch without a try/catch.
1751
+ *
1752
+ * The cloud runtime manages continuation, forking and personality server-side, so these throw `UnsupportedRunOperationError` — except `invalidateCache`, which is a documented no-op and is the more dangerous of the two shapes: it returns as if it worked.
1753
+ */
1754
+ static UNSUPPORTED_OPS = /* @__PURE__ */ new Set([
1755
+ "fork",
1756
+ "invalidateCache",
1757
+ "runToCompletion",
1758
+ "runUntil",
1759
+ "streamToCompletion",
1760
+ "usePersonality"
1761
+ ]);
1762
+ supports(operation) {
1763
+ return !_CloudAgent.UNSUPPORTED_OPS.has(operation);
1764
+ }
1765
+ unsupportedReason(operation) {
1766
+ return this.supports(operation) ? void 0 : `Operation "${operation}" is not available on a cloud agent.`;
1767
+ }
1817
1768
  agentId;
1818
1769
  model;
1819
1770
  /**
@@ -2256,6 +2207,18 @@ var PersonalityStore = class {
2256
2207
  };
2257
2208
 
2258
2209
  // src/internal/plugins/context.ts
2210
+ function makeHookDisposer(registrations, hook, handler) {
2211
+ let detached = false;
2212
+ return () => {
2213
+ if (detached) return;
2214
+ detached = true;
2215
+ const current = registrations.hooks.get(hook);
2216
+ if (current === void 0) return;
2217
+ const at = current.indexOf(handler);
2218
+ if (at !== -1) current.splice(at, 1);
2219
+ if (current.length === 0) registrations.hooks.delete(hook);
2220
+ };
2221
+ }
2259
2222
  function createPluginContext() {
2260
2223
  const registrations = {
2261
2224
  tools: [],
@@ -2276,11 +2239,12 @@ function createPluginContext() {
2276
2239
  if (typeof handler !== "function") {
2277
2240
  diag(`[theokit-sdk] ignoring non-function handler for hook "${hook}"
2278
2241
  `);
2279
- return;
2242
+ return () => void 0;
2280
2243
  }
2281
2244
  const existing = registrations.hooks.get(hook) ?? [];
2282
2245
  existing.push(handler);
2283
2246
  registrations.hooks.set(hook, existing);
2247
+ return makeHookDisposer(registrations, hook, handler);
2284
2248
  },
2285
2249
  injectMessage(content, role = "user") {
2286
2250
  registrations.injected.push({ content, role });
@@ -2595,6 +2559,8 @@ function spawnAndCollect(options) {
2595
2559
  settle({ stdout, stderr, exitCode: code, timedOut });
2596
2560
  });
2597
2561
  if (options.stdin !== void 0 && child.stdin !== null) {
2562
+ child.stdin.on("error", () => {
2563
+ });
2598
2564
  child.stdin.end(options.stdin);
2599
2565
  }
2600
2566
  });
@@ -2602,17 +2568,19 @@ function spawnAndCollect(options) {
2602
2568
 
2603
2569
  // src/internal/runtime/hooks/hooks-executor.ts
2604
2570
  var HooksExecutor = class {
2605
- constructor(cwd) {
2571
+ constructor(cwd, compatSources = []) {
2606
2572
  this.cwd = cwd;
2573
+ this.compatSources = compatSources;
2607
2574
  }
2608
2575
  cwd;
2576
+ compatSources;
2609
2577
  config = {};
2610
2578
  async initialize(settingSourcesIncludeProject) {
2611
2579
  if (!settingSourcesIncludeProject) {
2612
2580
  this.config = {};
2613
2581
  return;
2614
2582
  }
2615
- this.config = await loadHookConfig(this.cwd);
2583
+ this.config = await loadHookConfig(this.cwd, this.compatSources);
2616
2584
  }
2617
2585
  /** Fire every hook registered for `event` and aggregate the decisions. */
2618
2586
  async run(payload) {
@@ -2647,10 +2615,12 @@ var HooksExecutor = class {
2647
2615
  }
2648
2616
  async executeOne(command, payload) {
2649
2617
  const timeoutMs = command.timeoutMs ?? 3e4;
2618
+ const env = runtimeEnvFor(command.sourcePath, this.cwd);
2650
2619
  const result = await spawnAndCollect({
2651
2620
  command: "sh",
2652
2621
  args: ["-c", command.command],
2653
2622
  cwd: this.cwd,
2623
+ ...Object.keys(env).length > 0 ? { env } : {},
2654
2624
  timeoutMs,
2655
2625
  stdin: JSON.stringify(payload)
2656
2626
  });
@@ -2661,14 +2631,22 @@ var HooksExecutor = class {
2661
2631
  return { decision: "deny", reason: `Hook spawn failed: ${result.spawnError.message}` };
2662
2632
  }
2663
2633
  if (result.exitCode !== 0) {
2634
+ const stderr = result.stderr.trim();
2635
+ const base = stderr.length > 0 ? stderr : `Hook exited with code ${result.exitCode}`;
2636
+ const missing = undefinedVariablesIn(command.command, env);
2637
+ if (missing.length === 0) return { decision: "deny", reason: base };
2664
2638
  return {
2665
2639
  decision: "deny",
2666
- reason: result.stderr.trim().length > 0 ? result.stderr.trim() : `Hook exited with code ${result.exitCode}`
2640
+ reason: `${base} \u2014 this hook came from ${command.sourcePath ?? "an unrecorded source"} and uses ${missing.map((n) => `$${n}`).join(", ")}, which nothing defines here. A variable this runtime does not supply expands to the empty string, so the error above names a path rather than the cause.`
2667
2641
  };
2668
2642
  }
2669
2643
  return parseDecisionFromStdout(result.stdout);
2670
2644
  }
2671
2645
  };
2646
+ function runtimeEnvFor(sourcePath, cwd) {
2647
+ if (sourcePath === void 0) return {};
2648
+ return adapterForConfigPath(sourcePath)?.runtimeEnv(cwd) ?? {};
2649
+ }
2672
2650
  function parseDecisionFromStdout(stdout) {
2673
2651
  const trimmed = stdout.trim();
2674
2652
  if (trimmed.length === 0) return { decision: "allow" };
@@ -2687,28 +2665,6 @@ function parseDecisionFromStdout(stdout) {
2687
2665
  return { decision: "allow" };
2688
2666
  }
2689
2667
 
2690
- // src/internal/runtime/memory/memory-path-selector.ts
2691
- var PORT_MEMORY_PATH_ENV_VAR = "THEOKIT_PORT_MEMORY_PATH";
2692
- function shouldUsePortMemoryPath() {
2693
- const env = globalThis.process?.env;
2694
- if (env === void 0) return false;
2695
- const val = env[PORT_MEMORY_PATH_ENV_VAR];
2696
- return val === "1" || val === "true";
2697
- }
2698
- function resolveMemoryProviderForLoop(consumerSupplied, defaultAdapter, portPathEnabled) {
2699
- if (consumerSupplied !== void 0) return consumerSupplied;
2700
- if (portPathEnabled) return defaultAdapter;
2701
- return void 0;
2702
- }
2703
- function resolveMemoryToolsForLoop(legacyTools, portPathEnabled) {
2704
- if (portPathEnabled) return void 0;
2705
- return legacyTools;
2706
- }
2707
- function resolveActiveMemorySummaryForSend(legacySummary, portPathEnabled) {
2708
- if (portPathEnabled) return void 0;
2709
- return legacySummary;
2710
- }
2711
-
2712
2668
  // src/internal/runtime/lifecycle/context-budget-event.ts
2713
2669
  function buildContextBudgetEvent(model, resolved) {
2714
2670
  if (resolved.source !== "fallback") return void 0;
@@ -2739,7 +2695,6 @@ async function runPostRunLifecycle(inputs) {
2739
2695
  contextWindow,
2740
2696
  onRunEvent,
2741
2697
  hooksExecutor,
2742
- memoryGlue,
2743
2698
  memoryProvider
2744
2699
  } = inputs;
2745
2700
  let result;
@@ -2813,9 +2768,6 @@ async function runPostRunLifecycle(inputs) {
2813
2768
  } else {
2814
2769
  await writeSessionSummary(summaryArgs);
2815
2770
  }
2816
- if (!shouldUsePortMemoryPath()) {
2817
- void memoryGlue.syncIfReady();
2818
- }
2819
2771
  } catch (cause) {
2820
2772
  const message = cause instanceof Error ? cause.message : String(cause);
2821
2773
  diag(`[theokit-sdk] session summary write failed (${result.id}): ${message}
@@ -2836,10 +2788,83 @@ async function runPostRunLifecycle(inputs) {
2836
2788
  async function safeConversation(run) {
2837
2789
  try {
2838
2790
  return await run.conversation();
2839
- } catch {
2791
+ } catch (cause) {
2792
+ const msg = cause instanceof Error ? cause.message : String(cause);
2793
+ diag(`[theokit-sdk] conversation() failed; persisting the user turn only: ${msg}
2794
+ `);
2840
2795
  return [];
2841
2796
  }
2842
2797
  }
2798
+ var SkillsManager = class {
2799
+ constructor(cwd, _enabled, settingSourcesIncludeProject, skillsDir, inline, compatSources = []) {
2800
+ this.cwd = cwd;
2801
+ this.settingSourcesIncludeProject = settingSourcesIncludeProject;
2802
+ this.skillsDir = skillsDir;
2803
+ this.inline = inline;
2804
+ this.compatSources = compatSources;
2805
+ }
2806
+ cwd;
2807
+ settingSourcesIncludeProject;
2808
+ skillsDir;
2809
+ inline;
2810
+ compatSources;
2811
+ skills = [];
2812
+ async initialize() {
2813
+ if (!this.settingSourcesIncludeProject) {
2814
+ this.skills = this.mergeInline([]);
2815
+ return;
2816
+ }
2817
+ await this.refresh();
2818
+ }
2819
+ async refresh() {
2820
+ const roots = this.skillsDir === void 0 ? [
2821
+ ...projectConfigRoots(this.cwd, this.compatSources).map((root) => join(root, "skills")),
2822
+ ...(await pluginBundleDirs(this.cwd, this.compatSources)).map((b) => join(b, "skills"))
2823
+ ] : [this.skillsDir];
2824
+ const discovered = [];
2825
+ const seen = /* @__PURE__ */ new Set();
2826
+ for (const root of roots) {
2827
+ for (const skill of await discoverSkills(root, {
2828
+ onInvalidSkill: (info) => {
2829
+ diag(`[theokit-sdk] skill ${info.name} skipped (${info.code}): ${info.message}
2830
+ `);
2831
+ }
2832
+ })) {
2833
+ if (seen.has(skill.name)) continue;
2834
+ seen.add(skill.name);
2835
+ discovered.push(skill);
2836
+ }
2837
+ }
2838
+ this.skills = this.mergeInline(discovered);
2839
+ }
2840
+ /** M22 — merge inline skills over discovered ones; inline wins on a name conflict. */
2841
+ mergeInline(discovered) {
2842
+ if (this.inline === void 0 || this.inline.length === 0) return discovered;
2843
+ const inlineNames = new Set(this.inline.map((s) => s.name));
2844
+ return [...discovered.filter((s) => !inlineNames.has(s.name)), ...this.inline];
2845
+ }
2846
+ list() {
2847
+ return Promise.resolve(this.skills);
2848
+ }
2849
+ /**
2850
+ * SE20 — resolve a skill by name INCLUDING its body. Inline (`createSkill`)
2851
+ * skills carry `instructions` on the object; filesystem skills read the body
2852
+ * from their `source` SKILL.md (frontmatter stripped). `undefined` when no
2853
+ * enabled skill matches (malformed skills were already excluded at discovery).
2854
+ */
2855
+ async get(name) {
2856
+ const skill = this.skills.find((s) => s.name === name);
2857
+ if (skill === void 0) return void 0;
2858
+ const instructions = typeof skill.instructions === "string" ? skill.instructions : stripSkillFrontmatter(await readFile(skill.source, "utf8"));
2859
+ const references = skill.references;
2860
+ return {
2861
+ name: skill.name,
2862
+ description: skill.description,
2863
+ instructions,
2864
+ ...references !== void 0 ? { references } : {}
2865
+ };
2866
+ }
2867
+ };
2843
2868
 
2844
2869
  // src/define-tool.ts
2845
2870
  var TOOL_SPLIT_RESOLVER = /* @__PURE__ */ Symbol("theokit.toolSplitResolver");
@@ -2885,7 +2910,7 @@ function defineTool(spec) {
2885
2910
  return tool;
2886
2911
  }
2887
2912
 
2888
- // src/internal/runtime/reasoning/native-reasoning.ts
2913
+ // src/internal/runtime/system-prompt/native-reasoning.ts
2889
2914
  var NATIVE_REASONING_PARAM_IDS = /* @__PURE__ */ new Set(["thinking", "reasoning", "reasoning_effort"]);
2890
2915
  var REASONING_PREAMBLE = "Think step by step before answering: use the `think` tool to reason through each step, validate your work, then answer. Reason about magnitude before comparing numbers.";
2891
2916
  function createThinkTool() {
@@ -2918,74 +2943,6 @@ function reasoningActive(reasoning, model) {
2918
2943
  }
2919
2944
  return true;
2920
2945
  }
2921
- var SkillsManager = class {
2922
- constructor(cwd, _enabled, settingSourcesIncludeProject, skillsDir, inline) {
2923
- this.cwd = cwd;
2924
- this.settingSourcesIncludeProject = settingSourcesIncludeProject;
2925
- this.skillsDir = skillsDir;
2926
- this.inline = inline;
2927
- }
2928
- cwd;
2929
- settingSourcesIncludeProject;
2930
- skillsDir;
2931
- inline;
2932
- skills = [];
2933
- async initialize() {
2934
- if (!this.settingSourcesIncludeProject) {
2935
- this.skills = this.mergeInline([]);
2936
- return;
2937
- }
2938
- await this.refresh();
2939
- }
2940
- async refresh() {
2941
- const roots = this.skillsDir === void 0 ? [
2942
- ...projectConfigRoots(this.cwd).map((root) => join(root, "skills")),
2943
- ...(await pluginBundleDirs(this.cwd)).map((bundle) => join(bundle, "skills"))
2944
- ] : [this.skillsDir];
2945
- const discovered = [];
2946
- const seen = /* @__PURE__ */ new Set();
2947
- for (const root of roots) {
2948
- for (const skill of await discoverSkills(root, {
2949
- onInvalidSkill: (info) => {
2950
- diag(`[theokit-sdk] skill ${info.name} skipped (${info.code}): ${info.message}
2951
- `);
2952
- }
2953
- })) {
2954
- if (seen.has(skill.name)) continue;
2955
- seen.add(skill.name);
2956
- discovered.push(skill);
2957
- }
2958
- }
2959
- this.skills = this.mergeInline(discovered);
2960
- }
2961
- /** M22 — merge inline skills over discovered ones; inline wins on a name conflict. */
2962
- mergeInline(discovered) {
2963
- if (this.inline === void 0 || this.inline.length === 0) return discovered;
2964
- const inlineNames = new Set(this.inline.map((s) => s.name));
2965
- return [...discovered.filter((s) => !inlineNames.has(s.name)), ...this.inline];
2966
- }
2967
- list() {
2968
- return Promise.resolve(this.skills);
2969
- }
2970
- /**
2971
- * SE20 — resolve a skill by name INCLUDING its body. Inline (`createSkill`)
2972
- * skills carry `instructions` on the object; filesystem skills read the body
2973
- * from their `source` SKILL.md (frontmatter stripped). `undefined` when no
2974
- * enabled skill matches (malformed skills were already excluded at discovery).
2975
- */
2976
- async get(name) {
2977
- const skill = this.skills.find((s) => s.name === name);
2978
- if (skill === void 0) return void 0;
2979
- const instructions = typeof skill.instructions === "string" ? skill.instructions : stripSkillFrontmatter(await readFile(skill.source, "utf8"));
2980
- const references = skill.references;
2981
- return {
2982
- name: skill.name,
2983
- description: skill.description,
2984
- instructions,
2985
- ...references !== void 0 ? { references } : {}
2986
- };
2987
- }
2988
- };
2989
2946
 
2990
2947
  // src/internal/runtime/system-prompt/local-assembly.ts
2991
2948
  async function resolveSendSkills(inputs, userText, memoryFacts) {
@@ -3005,7 +2962,8 @@ async function resolveSendSkills(inputs, userText, memoryFacts) {
3005
2962
  settings.enabled,
3006
2963
  inputs.settingSourcesIncludeProject,
3007
2964
  settings.skillsDir,
3008
- settings.inline
2965
+ settings.inline,
2966
+ inputs.options.local?.compatSources ?? []
3009
2967
  );
3010
2968
  await manager.initialize();
3011
2969
  return { manager, autoInject: settings.autoInject ?? true };
@@ -3021,7 +2979,14 @@ async function buildSystemPromptContext(inputs, userText, memoryFacts, manager =
3021
2979
  memory: memoryFacts.map((fact) => ({ text: fact.text }))
3022
2980
  };
3023
2981
  }
3024
- async function buildAssemblyContext(inputs, userText, baseSystemPrompt, memoryFacts, activeMemorySummary, contextPaths) {
2982
+ async function buildAssemblyContext({
2983
+ inputs,
2984
+ userText,
2985
+ baseSystemPrompt,
2986
+ memoryFacts,
2987
+ activeMemorySummary,
2988
+ contextPaths
2989
+ }) {
3025
2990
  const resolved = await resolveSendSkills(inputs, userText, memoryFacts);
3026
2991
  const baseCtx = await buildSystemPromptContext(inputs, userText, memoryFacts, resolved.manager);
3027
2992
  const assemblyCtx = {
@@ -3044,16 +3009,9 @@ async function buildAssemblyContext(inputs, userText, baseSystemPrompt, memoryFa
3044
3009
  }
3045
3010
  return assemblyCtx;
3046
3011
  }
3047
- async function assembleSystemPromptForSend(inputs, userText, baseSystemPrompt, memoryFacts, activeMemorySummary, contextPaths) {
3048
- const ctx = await buildAssemblyContext(
3049
- inputs,
3050
- userText,
3051
- baseSystemPrompt,
3052
- memoryFacts,
3053
- activeMemorySummary,
3054
- contextPaths
3055
- );
3056
- return inputs.systemPromptPipeline.assemble(ctx);
3012
+ async function assembleSystemPromptForSend(request) {
3013
+ const ctx = await buildAssemblyContext(request);
3014
+ return request.inputs.systemPromptPipeline.assemble(ctx);
3057
3015
  }
3058
3016
 
3059
3017
  // src/internal/runtime/system-prompt/safe-call.ts
@@ -3459,15 +3417,16 @@ var arizeAdapter = {
3459
3417
  displayName: "Arize Phoenix",
3460
3418
  detect: () => safeRequire("arize-phoenix-otel") !== void 0,
3461
3419
  register: () => {
3462
- if (registeredHere) return;
3420
+ if (registeredHere) return "instrumented";
3463
3421
  const arize = safeRequire("arize-phoenix-otel");
3464
3422
  const otel = safeRequire("@opentelemetry/api");
3465
- if (arize === void 0 || otel === void 0) return;
3423
+ if (arize === void 0 || otel === void 0) return "not-wired";
3466
3424
  const provider = otel.trace.getTracerProvider();
3467
- if (provider.addSpanProcessor === void 0) return;
3425
+ if (provider.addSpanProcessor === void 0) return "not-wired";
3468
3426
  const processor = new arize.PhoenixSpanProcessor();
3469
3427
  provider.addSpanProcessor(processor);
3470
3428
  registeredHere = true;
3429
+ return "instrumented";
3471
3430
  }
3472
3431
  };
3473
3432
 
@@ -3478,10 +3437,11 @@ var braintrustAdapter = {
3478
3437
  displayName: "Braintrust",
3479
3438
  detect: () => safeRequire("braintrust") !== void 0,
3480
3439
  register: () => {
3481
- if (registeredHere2) return;
3482
- const bt = safeRequire("braintrust");
3483
- if (bt === void 0) return;
3440
+ if (registeredHere2) return "vendor-auto-instruments";
3441
+ const mod = safeRequire("braintrust");
3442
+ if (mod === void 0) return "not-wired";
3484
3443
  registeredHere2 = true;
3444
+ return "vendor-auto-instruments";
3485
3445
  }
3486
3446
  };
3487
3447
 
@@ -3492,11 +3452,12 @@ var datadogAdapter = {
3492
3452
  displayName: "Datadog",
3493
3453
  detect: () => safeRequire("dd-trace") !== void 0,
3494
3454
  register: () => {
3495
- if (registeredHere3) return;
3455
+ if (registeredHere3) return "instrumented";
3496
3456
  const dd = safeRequire("dd-trace");
3497
- if (dd === void 0) return;
3457
+ if (dd === void 0) return "not-wired";
3498
3458
  dd.init({ logInjection: true });
3499
3459
  registeredHere3 = true;
3460
+ return "instrumented";
3500
3461
  }
3501
3462
  };
3502
3463
 
@@ -3507,32 +3468,33 @@ var langfuseAdapter = {
3507
3468
  displayName: "Langfuse",
3508
3469
  detect: () => safeRequire("@langfuse/node") !== void 0,
3509
3470
  register: () => {
3510
- if (registeredHere4) return;
3471
+ if (registeredHere4) return "instrumented";
3511
3472
  const lf = safeRequire("@langfuse/node");
3512
3473
  const otel = safeRequire("@opentelemetry/api");
3513
- if (lf === void 0 || otel === void 0) return;
3474
+ if (lf === void 0 || otel === void 0) return "not-wired";
3514
3475
  const provider = otel.trace.getTracerProvider();
3515
3476
  if (provider.addSpanProcessor === void 0) {
3516
- return;
3477
+ return "not-wired";
3517
3478
  }
3518
3479
  const existing = provider.getActiveSpanProcessor?.();
3519
3480
  if (typeof existing === "object" && existing !== null) {
3520
3481
  const ctor = existing.constructor?.name ?? "";
3521
3482
  if (ctor.toLowerCase().includes("langfuse")) {
3522
3483
  registeredHere4 = true;
3523
- return;
3484
+ return "instrumented";
3524
3485
  }
3525
3486
  }
3526
3487
  if (lf.LangfuseSpanProcessor === void 0) {
3527
3488
  diag(
3528
3489
  "[theokit-sdk] @langfuse/node detected but LangfuseSpanProcessor not found (v2?). Use Langfuse v3+ for auto-instrumentation.\n"
3529
3490
  );
3530
- return;
3491
+ return "not-wired";
3531
3492
  }
3532
3493
  const client = new lf.Langfuse();
3533
3494
  const processor = new lf.LangfuseSpanProcessor({ langfuse: client });
3534
3495
  provider.addSpanProcessor(processor);
3535
3496
  registeredHere4 = true;
3497
+ return "instrumented";
3536
3498
  }
3537
3499
  };
3538
3500
 
@@ -3543,10 +3505,11 @@ var langsmithAdapter = {
3543
3505
  displayName: "LangSmith",
3544
3506
  detect: () => safeRequire("langsmith") !== void 0,
3545
3507
  register: () => {
3546
- if (registeredHere5) return;
3547
- const ls = safeRequire("langsmith");
3548
- if (ls === void 0) return;
3508
+ if (registeredHere5) return "vendor-auto-instruments";
3509
+ const mod = safeRequire("langsmith");
3510
+ if (mod === void 0) return "not-wired";
3549
3511
  registeredHere5 = true;
3512
+ return "vendor-auto-instruments";
3550
3513
  }
3551
3514
  };
3552
3515
 
@@ -3560,19 +3523,19 @@ var posthogAdapter = {
3560
3523
  displayName: "PostHog",
3561
3524
  detect: () => safeRequire("posthog-node") !== void 0,
3562
3525
  register: () => {
3563
- if (registeredHere6) return;
3526
+ if (registeredHere6) return "instrumented";
3564
3527
  const ph = safeRequire("posthog-node");
3565
3528
  const otel = safeRequire("@opentelemetry/api");
3566
- if (ph === void 0 || otel === void 0) return;
3529
+ if (ph === void 0 || otel === void 0) return "not-wired";
3567
3530
  const key = presentEnv(process.env.POSTHOG_API_KEY) ?? presentEnv(process.env.POSTHOG_PROJECT_API_KEY);
3568
3531
  if (typeof key !== "string" || key.length === 0) {
3569
- return;
3532
+ return "not-wired";
3570
3533
  }
3571
3534
  const client = new ph.PostHog(key, {
3572
3535
  host: presentEnv(process.env.POSTHOG_HOST) ?? "https://us.i.posthog.com"
3573
3536
  });
3574
3537
  const provider = otel.trace.getTracerProvider();
3575
- if (provider.addSpanProcessor === void 0) return;
3538
+ if (provider.addSpanProcessor === void 0) return "not-wired";
3576
3539
  const processor = {
3577
3540
  onStart: () => {
3578
3541
  },
@@ -3601,6 +3564,7 @@ var posthogAdapter = {
3601
3564
  };
3602
3565
  provider.addSpanProcessor(processor);
3603
3566
  registeredHere6 = true;
3567
+ return "instrumented";
3604
3568
  }
3605
3569
  };
3606
3570
 
@@ -3611,11 +3575,11 @@ var sentryAdapter = {
3611
3575
  displayName: "Sentry",
3612
3576
  detect: () => safeRequire("@sentry/node") !== void 0,
3613
3577
  register: () => {
3614
- if (registeredHere7) return;
3578
+ if (registeredHere7) return "instrumented";
3615
3579
  const sentry = safeRequire("@sentry/node");
3616
- if (sentry === void 0) return;
3580
+ if (sentry === void 0) return "not-wired";
3617
3581
  if (typeof sentry.addEventProcessor !== "function") {
3618
- return;
3582
+ return "not-wired";
3619
3583
  }
3620
3584
  sentry.addEventProcessor((event) => {
3621
3585
  const otel = safeRequire("@opentelemetry/api");
@@ -3631,10 +3595,16 @@ var sentryAdapter = {
3631
3595
  return event;
3632
3596
  });
3633
3597
  registeredHere7 = true;
3598
+ return "instrumented";
3634
3599
  }
3635
3600
  };
3636
3601
 
3637
3602
  // src/internal/telemetry/adapter-registry.ts
3603
+ var WIRING_PROSE = {
3604
+ instrumented: "auto-instrumented",
3605
+ "vendor-auto-instruments": "loaded; the vendor instruments itself from its env var",
3606
+ "not-wired": "detected but nothing was wired"
3607
+ };
3638
3608
  var ALL_ADAPTERS = [
3639
3609
  langfuseAdapter,
3640
3610
  sentryAdapter,
@@ -3644,7 +3614,7 @@ var ALL_ADAPTERS = [
3644
3614
  arizeAdapter,
3645
3615
  braintrustAdapter
3646
3616
  ];
3647
- var registered = /* @__PURE__ */ new Set();
3617
+ var registered = /* @__PURE__ */ new Map();
3648
3618
  function tryAutoRegisterAdapters(settings) {
3649
3619
  if (settings?.enabled !== true) return;
3650
3620
  if (settings.autoDetect === false) return;
@@ -3653,18 +3623,21 @@ function tryAutoRegisterAdapters(settings) {
3653
3623
  if (registered.has(adapter.moduleName)) continue;
3654
3624
  if (disabled.has(adapter.displayName.toLowerCase())) continue;
3655
3625
  if (!adapter.detect()) continue;
3656
- try {
3657
- adapter.register();
3658
- registered.add(adapter.moduleName);
3659
- diag(`[theokit-sdk] telemetry: ${adapter.displayName} auto-instrumented.
3626
+ registerOne(adapter);
3627
+ }
3628
+ }
3629
+ function registerOne(adapter) {
3630
+ try {
3631
+ const wiring = adapter.register();
3632
+ registered.set(adapter.moduleName, wiring);
3633
+ diag(`[theokit-sdk] telemetry: ${adapter.displayName} ${WIRING_PROSE[wiring]}.
3660
3634
  `);
3661
- } catch (cause) {
3662
- const message = cause instanceof Error ? cause.message : String(cause);
3663
- diag(
3664
- `[theokit-sdk] telemetry: ${adapter.displayName} detected but failed to register: ${message}
3635
+ } catch (cause) {
3636
+ const message = cause instanceof Error ? cause.message : String(cause);
3637
+ diag(
3638
+ `[theokit-sdk] telemetry: ${adapter.displayName} detected but failed to register: ${message}
3665
3639
  `
3666
- );
3667
- }
3640
+ );
3668
3641
  }
3669
3642
  }
3670
3643
 
@@ -4149,7 +4122,10 @@ async function loadContextConfig(cwd) {
4149
4122
  if (!existsSync(jsonPath)) return { sources: [] };
4150
4123
  warnOnce(
4151
4124
  "context-json-deprecated",
4152
- "[theokit-sdk] .theokit/context.json is deprecated; migrate to .theokit/context/<name>.md via theokit-migrate-config"
4125
+ // Names no command: `theokit-migrate-config` was unpublished with the `bin` entry, and a warning
4126
+ // that tells you to run something the package does not ship is worse than one that tells you
4127
+ // what the target looks like.
4128
+ "[theokit-sdk] .theokit/context.json is deprecated; move each entry to its own file under .theokit/context/<name>.md"
4153
4129
  );
4154
4130
  let raw;
4155
4131
  try {
@@ -4258,20 +4234,22 @@ var PluginFrontmatterSchema = z.object({
4258
4234
  entry: z.string().min(1).optional()
4259
4235
  });
4260
4236
 
4261
- // src/internal/runtime/plugins/plugins-manager.ts
4237
+ // src/internal/runtime/plugin-loader/plugins-manager.ts
4262
4238
  var PluginsManager = class {
4263
- constructor(cwd, enabled, settingSourcesIncludePlugins, cloud, localPaths) {
4239
+ constructor(cwd, enabled, settingSourcesIncludePlugins, cloud, localPaths, compatSources = []) {
4264
4240
  this.cwd = cwd;
4265
4241
  this.enabled = enabled;
4266
4242
  this.settingSourcesIncludePlugins = settingSourcesIncludePlugins;
4267
4243
  this.cloud = cloud;
4268
4244
  this.localPaths = localPaths;
4245
+ this.compatSources = compatSources;
4269
4246
  }
4270
4247
  cwd;
4271
4248
  enabled;
4272
4249
  settingSourcesIncludePlugins;
4273
4250
  cloud;
4274
4251
  localPaths;
4252
+ compatSources;
4275
4253
  plugins = [];
4276
4254
  async initialize() {
4277
4255
  this.assertCloudRules();
@@ -4283,7 +4261,7 @@ var PluginsManager = class {
4283
4261
  }
4284
4262
  async refresh() {
4285
4263
  this.plugins = [];
4286
- for (const pluginsRoot of pluginBundleRoots(this.cwd)) {
4264
+ for (const pluginsRoot of pluginBundleRoots(this.cwd, this.compatSources)) {
4287
4265
  await this.refreshRoot(pluginsRoot);
4288
4266
  }
4289
4267
  }
@@ -4313,7 +4291,8 @@ var PluginsManager = class {
4313
4291
  if (!existsSync(mdPath) && existsSync(jsonPath)) {
4314
4292
  warnOnce(
4315
4293
  "plugin-json-deprecated",
4316
- "[theokit-sdk] plugin.json manifests are deprecated; migrate to PLUGIN.md via theokit-migrate-config"
4294
+ // Same reason as the context.json warning: the CLI it used to name is no longer published.
4295
+ "[theokit-sdk] plugin.json manifests are deprecated; replace each with a PLUGIN.md"
4317
4296
  );
4318
4297
  }
4319
4298
  if (this.enabled === void 0 || this.enabled.includes(metadata.name)) {
@@ -4450,58 +4429,96 @@ function registerLocalAgent(args) {
4450
4429
  status: "finished"
4451
4430
  });
4452
4431
  }
4432
+ function buildContext(args, out) {
4433
+ if (args.options.context === void 0) return;
4434
+ out.context = new FileContextManager(
4435
+ args.workspaceCwd,
4436
+ args.options.context,
4437
+ args.settingSourcesIncludeProject
4438
+ );
4439
+ }
4440
+ function buildProviders(args, out) {
4441
+ const providerCount = (args.options.providers?.routes?.length ?? 0) + enabledPluginNames(args.options.plugins).length;
4442
+ if (providerCount === 0 && args.options.providers === void 0) return;
4443
+ out.providers = new ProvidersManagerImpl(
4444
+ normalizeModel(args.options.model),
4445
+ args.options.providers,
4446
+ args.options.plugins
4447
+ );
4448
+ }
4449
+ function buildSkills(args, out) {
4450
+ if (args.options.skills === void 0 && !args.settingSourcesIncludeProject) return;
4451
+ const staticSkills = typeof args.options.skills === "function" ? void 0 : args.options.skills;
4452
+ out.skillsManager = new SkillsManager(
4453
+ args.workspaceCwd,
4454
+ staticSkills?.enabled,
4455
+ args.settingSourcesIncludeProject,
4456
+ // M22 — custom skills directory + inline (code-defined) skills.
4457
+ staticSkills?.skillsDir,
4458
+ staticSkills?.inline,
4459
+ // #524 — the same declaration the per-send manager reads. Omitting it here would make
4460
+ // `agent.skills` disagree with the system prompt about which skills exist.
4461
+ args.options.local?.compatSources ?? []
4462
+ );
4463
+ const localSkills = out.skillsManager;
4464
+ out.skills = {
4465
+ // Project to the public shape (name + description only). Inline skills carry
4466
+ // their body + references on the object; `list()` must never leak them —
4467
+ // the body is reachable exclusively through `get()`.
4468
+ list: async () => (await localSkills.list()).map((s) => ({ name: s.name, description: s.description })),
4469
+ get: (name) => localSkills.get(name)
4470
+ };
4471
+ }
4472
+ function buildPlugins(args, out) {
4473
+ if (args.options.plugins === void 0 && !args.settingSourcesIncludePlugins) return;
4474
+ out.pluginsManager = new PluginsManager(
4475
+ args.workspaceCwd,
4476
+ // The array (code-`Plugin`) form has no named-enable list; `undefined`
4477
+ // here preserves "no filter / load all file-discovered plugins".
4478
+ asPluginsSettings(args.options.plugins)?.enabled,
4479
+ args.settingSourcesIncludePlugins,
4480
+ false,
4481
+ void 0,
4482
+ args.options.local?.compatSources ?? []
4483
+ );
4484
+ const localPlugins = out.pluginsManager;
4485
+ out.plugins = { list: () => localPlugins.list() };
4486
+ }
4453
4487
  function bootstrapSubmanagers(args) {
4454
4488
  const out = {};
4455
- if (args.options.context !== void 0) {
4456
- out.context = new FileContextManager(
4457
- args.workspaceCwd,
4458
- args.options.context,
4459
- args.settingSourcesIncludeProject
4460
- );
4461
- }
4462
- const providerCount = (args.options.providers?.routes?.length ?? 0) + enabledPluginNames(args.options.plugins).length;
4463
- if (providerCount > 0 || args.options.providers !== void 0) {
4464
- out.providers = new ProvidersManagerImpl(
4465
- normalizeModel(args.options.model),
4466
- args.options.providers,
4467
- args.options.plugins
4468
- );
4469
- }
4470
- if (args.options.skills !== void 0 || args.settingSourcesIncludeProject) {
4471
- const staticSkills = typeof args.options.skills === "function" ? void 0 : args.options.skills;
4472
- out.skillsManager = new SkillsManager(
4473
- args.workspaceCwd,
4474
- staticSkills?.enabled,
4475
- args.settingSourcesIncludeProject,
4476
- // M22 — custom skills directory + inline (code-defined) skills.
4477
- staticSkills?.skillsDir,
4478
- staticSkills?.inline
4479
- );
4480
- const localSkills = out.skillsManager;
4481
- out.skills = {
4482
- // Project to the public shape (name + description only). Inline skills carry
4483
- // their body + references on the object; `list()` must never leak them —
4484
- // the body is reachable exclusively through `get()`.
4485
- list: async () => (await localSkills.list()).map((s) => ({ name: s.name, description: s.description })),
4486
- get: (name) => localSkills.get(name)
4487
- };
4488
- }
4489
- if (args.options.plugins !== void 0 || args.settingSourcesIncludePlugins) {
4490
- out.pluginsManager = new PluginsManager(
4491
- args.workspaceCwd,
4492
- // The array (code-`Plugin`) form has no named-enable list; `undefined`
4493
- // here preserves "no filter / load all file-discovered plugins".
4494
- asPluginsSettings(args.options.plugins)?.enabled,
4495
- args.settingSourcesIncludePlugins,
4496
- false,
4497
- void 0
4498
- );
4499
- const localPlugins = out.pluginsManager;
4500
- out.plugins = { list: () => localPlugins.list() };
4501
- }
4489
+ buildContext(args, out);
4490
+ buildProviders(args, out);
4491
+ buildSkills(args, out);
4492
+ buildPlugins(args, out);
4502
4493
  return out;
4503
4494
  }
4504
4495
 
4496
+ // src/internal/local-agent/local-agent-capabilities.ts
4497
+ var UNSUPPORTED_OPS = /* @__PURE__ */ new Set(["downloadArtifact", "listArtifacts"]);
4498
+ function localAgentSupports(operation) {
4499
+ return !UNSUPPORTED_OPS.has(operation);
4500
+ }
4501
+ function localAgentUnsupportedReason(operation) {
4502
+ return localAgentSupports(operation) ? void 0 : `Operation "${operation}" is not available on a local agent.`;
4503
+ }
4504
+ function localAgentListArtifacts() {
4505
+ return Promise.resolve([]);
4506
+ }
4507
+ function localAgentDownloadArtifact() {
4508
+ return Promise.reject(
4509
+ new UnsupportedRunOperationError(
4510
+ "Artifacts are not supported for local agents",
4511
+ "downloadArtifact"
4512
+ )
4513
+ );
4514
+ }
4515
+ var localAgentCapabilities = {
4516
+ supports: localAgentSupports,
4517
+ unsupportedReason: localAgentUnsupportedReason,
4518
+ listArtifacts: localAgentListArtifacts,
4519
+ downloadArtifact: localAgentDownloadArtifact
4520
+ };
4521
+
4505
4522
  // src/internal/runtime/registry/run-registry.ts
4506
4523
  var runs = /* @__PURE__ */ new Map();
4507
4524
  var runsByAgent = /* @__PURE__ */ new Map();
@@ -4811,6 +4828,44 @@ var UsageAccumulator = class {
4811
4828
  }
4812
4829
  };
4813
4830
 
4831
+ // src/internal/agent-loop/replay-messages.ts
4832
+ function replayMessages(prior) {
4833
+ return prior.flatMap(replayTurn);
4834
+ }
4835
+ function replayTurn(msg) {
4836
+ if (msg.parts === void 0 || msg.parts.length === 0) {
4837
+ return [{ role: msg.role, content: [{ type: "text", text: msg.text }] }];
4838
+ }
4839
+ const { own, results } = splitParts(msg.parts);
4840
+ const out = [];
4841
+ if (own.length > 0) out.push({ role: msg.role, content: own });
4842
+ if (results.length > 0) out.push({ role: "user", content: results });
4843
+ return out;
4844
+ }
4845
+ function splitParts(parts) {
4846
+ const own = [];
4847
+ const results = [];
4848
+ for (const part of parts) {
4849
+ if (part.type === "tool_result") {
4850
+ results.push(toToolResult(part));
4851
+ continue;
4852
+ }
4853
+ if (part.type === "text" && part.text.length === 0) continue;
4854
+ own.push({ ...part });
4855
+ }
4856
+ return { own, results };
4857
+ }
4858
+ function toToolResult(part) {
4859
+ return {
4860
+ type: "tool_result",
4861
+ toolUseId: part.toolUseId,
4862
+ // `SessionMessagePart` holds the blocks readonly and `LlmToolResultPart` takes a mutable array:
4863
+ // same elements, different variance, so the copy is the whole conversion.
4864
+ content: typeof part.content === "string" ? part.content : [...part.content],
4865
+ ...part.isError === void 0 ? {} : { isError: part.isError }
4866
+ };
4867
+ }
4868
+
4814
4869
  // src/internal/agent-loop/live-events.ts
4815
4870
  var LiveEventLog = class extends Array {
4816
4871
  /**
@@ -4899,10 +4954,7 @@ function buildUserContent(text, images) {
4899
4954
  return content;
4900
4955
  }
4901
4956
  function buildAgentRef(inputs) {
4902
- return {
4903
- agentId: inputs.agentId,
4904
- model: inputs.model
4905
- };
4957
+ return { agentId: inputs.agentId, model: inputs.model };
4906
4958
  }
4907
4959
  async function initLoopContext(inputs) {
4908
4960
  let memoryProviderHandle;
@@ -4911,7 +4963,8 @@ async function initLoopContext(inputs) {
4911
4963
  memoryProviderHandle = await inputs.memoryProvider.init({
4912
4964
  cwd: process.cwd()
4913
4965
  });
4914
- } catch {
4966
+ } catch (cause) {
4967
+ reportMemoryDegraded("init", cause, inputs.runEventSink);
4915
4968
  memoryProviderHandle = void 0;
4916
4969
  }
4917
4970
  }
@@ -4940,7 +4993,8 @@ async function initLoopContext(inputs) {
4940
4993
  let providerTools = [];
4941
4994
  try {
4942
4995
  providerTools = inputs.memoryProvider.buildTools(memoryProviderHandle, buildAgentRef(inputs));
4943
- } catch {
4996
+ } catch (cause) {
4997
+ reportMemoryDegraded("buildTools", cause, inputs.runEventSink);
4944
4998
  providerTools = [];
4945
4999
  }
4946
5000
  for (const providerTool of providerTools) {
@@ -4962,10 +5016,7 @@ async function initLoopContext(inputs) {
4962
5016
  buildUserEvent(inputs)
4963
5017
  ]);
4964
5018
  if (inputs.onLoopEvent !== void 0) events.subscribe(inputs.onLoopEvent);
4965
- const priorMessages = (inputs.priorMessages ?? []).map((msg) => ({
4966
- role: msg.role,
4967
- content: [{ type: "text", text: msg.text }]
4968
- }));
5019
+ const priorMessages = replayMessages(inputs.priorMessages ?? []);
4969
5020
  let memorySystemPromptAdditions;
4970
5021
  if (inputs.memoryProvider !== void 0 && memoryProviderHandle !== void 0) {
4971
5022
  try {
@@ -4980,7 +5031,8 @@ async function initLoopContext(inputs) {
4980
5031
  if (passResult.systemPromptAdditions !== void 0 && passResult.systemPromptAdditions.length > 0) {
4981
5032
  memorySystemPromptAdditions = passResult.systemPromptAdditions;
4982
5033
  }
4983
- } catch {
5034
+ } catch (cause) {
5035
+ reportMemoryDegraded("activePass", cause, inputs.runEventSink);
4984
5036
  memorySystemPromptAdditions = void 0;
4985
5037
  }
4986
5038
  }
@@ -5002,6 +5054,12 @@ async function initLoopContext(inputs) {
5002
5054
  ...memorySystemPromptAdditions !== void 0 ? { memorySystemPromptAdditions } : {}
5003
5055
  };
5004
5056
  }
5057
+ function reportMemoryDegraded(stage, cause, sink) {
5058
+ const message = cause instanceof Error ? cause.message : String(cause);
5059
+ diag(`[theokit-sdk] memory ${stage} failed \u2014 continuing without it: ${message}
5060
+ `);
5061
+ emitRunEvent(sink, { type: "memory_degraded", stage, message });
5062
+ }
5005
5063
  async function safeListTools(client, serverName, sink) {
5006
5064
  try {
5007
5065
  const listed = await client.listTools();
@@ -5055,1215 +5113,1265 @@ async function collectTools(mcp, withheld, sink) {
5055
5113
  function sanitize(name) {
5056
5114
  return name.replace(/[^a-zA-Z0-9-]+/g, "_").replace(/^[_-]+|[_-]+$/g, "");
5057
5115
  }
5058
- var KEY_PREFIX = "theokit-";
5059
- var KEY_HEX_LENGTH = 32;
5060
- function derivePromptCacheKey(sessionId) {
5061
- if (sessionId === void 0 || sessionId.trim().length === 0) return void 0;
5062
- const digest = createHash("sha256").update(sessionId, "utf8").digest("hex");
5063
- return `${KEY_PREFIX}${digest.slice(0, KEY_HEX_LENGTH)}`;
5064
- }
5065
-
5066
- // src/internal/tool-dispatch/strip-think.ts
5067
- var THINK_PATTERN = /<think>[\s\S]*?<\/think>\s*/g;
5068
- function stripThinkBlocks(content) {
5069
- const matches = [...content.matchAll(THINK_PATTERN)];
5070
- const thinking = matches.length > 0 ? matches.map((m) => m[0]).join("\n").replace(/<\/?think>/g, "").trim() : null;
5071
- const visible = content.replace(THINK_PATTERN, "").trim();
5072
- return { visible, thinking };
5073
- }
5074
-
5075
- // src/internal/agent-loop/loop-llm-stream.ts
5076
- function resolveSystemPromptWithMemoryAdditions(systemPrompt, additions) {
5077
- if (additions === void 0 || additions.length === 0) return systemPrompt;
5078
- if (systemPrompt === void 0 || systemPrompt.length === 0) return additions;
5079
- return `${systemPrompt}
5080
-
5081
- ${additions}`;
5082
- }
5083
- function toLlmTool(tool) {
5084
- return { name: tool.name, description: tool.description, inputSchema: tool.inputSchema };
5085
- }
5086
- function reasoningEffortFromParams(params) {
5087
- const thinking = params?.find((p) => p.id === "thinking");
5088
- return thinking !== void 0 && thinking.value.length > 0 ? thinking.value : void 0;
5089
- }
5090
- function emitLlmMetrics(inputs, result, startAt) {
5091
- inputs.telemetry?.recordHistogram(HISTOGRAM_NAMES.LLM_CALL_DURATION_MS, Date.now() - startAt, {
5092
- provider: inputs.llm.name
5093
- });
5094
- if (result.inputTokens === void 0 && result.outputTokens === void 0) {
5095
- inputs.telemetry?.recordHistogram(HISTOGRAM_NAMES.LLM_USAGE_MISSING, 1, {
5096
- provider: inputs.llm.name
5097
- });
5098
- diag(
5099
- `[theokit-sdk] llm usage missing from ${inputs.llm.name} finish \u2014 budget may undercount
5100
- `
5101
- );
5102
- return;
5103
- }
5104
- inputs.telemetry?.recordHistogram(
5105
- HISTOGRAM_NAMES.LLM_TOKENS,
5106
- (result.inputTokens ?? 0) + (result.outputTokens ?? 0),
5107
- { provider: inputs.llm.name }
5108
- );
5109
- }
5110
- async function streamLlmTurn(inputs, ctx) {
5111
- const llmSpan = inputs.telemetry?.startChildSpan(ctx.sendSpan, "llm.call", {
5112
- "model.id": inputs.model.id ?? "auto",
5113
- provider: inputs.llm.name
5114
- });
5115
- const startAt = Date.now();
5116
- const signal = inputs.signal ?? new AbortController().signal;
5117
- const generator = inputs.llm.stream(
5118
- {
5119
- model: inputs.model.id ?? "auto",
5120
- ...(() => {
5121
- const effective = resolveSystemPromptWithMemoryAdditions(
5122
- inputs.systemPrompt,
5123
- ctx.memorySystemPromptAdditions
5124
- );
5125
- return effective !== void 0 ? { system: effective } : {};
5126
- })(),
5127
- // issue #47: forward the reasoning effort from ModelSelection.params (the `thinking` param)
5128
- // so the provider produces reasoning. Absent param ⇒ no `reasoning` field (bare request).
5129
- ...(() => {
5130
- const effort = reasoningEffortFromParams(inputs.model.params);
5131
- return effort !== void 0 ? { reasoning: { effort } } : {};
5132
- })(),
5133
- // Step-cap force-close: forward the per-run tool gate (`"none"` on a ceiling round forces a
5134
- // text close even though tools are advertised). Absent ⇒ provider default (auto).
5135
- ...inputs.toolChoice !== void 0 ? { toolChoice: inputs.toolChoice } : {},
5136
- // usetheokit/theokit-sdk#383 — the prompt-cache key, derived HERE and from `inputs.agentId`
5137
- // because this is the one place that sees the session identity on every round. `agentId` is
5138
- // the run's session identity (`Agent.getOrCreate(sessionId)`), so the derived key is identical
5139
- // on round 1 and round 12 of a turn, identical on turn 2 of the same session, and different
5140
- // for a different session. Deriving it per round from a stable input is what makes it a cache
5141
- // key; minting one anywhere that runs more than once per session would not be.
5142
- ...(() => {
5143
- const key = derivePromptCacheKey(inputs.agentId);
5144
- return key !== void 0 ? { promptCacheKey: key } : {};
5145
- })(),
5146
- messages: ctx.messages,
5147
- tools: ctx.tools.map(toLlmTool)
5148
- },
5149
- signal
5150
- );
5151
- const collected = await collectLlmEvents(generator, inputs, ctx);
5152
- if (collected.errored || collected.finishValue === void 0) {
5153
- llmSpan?.setAttribute("stopReason", "error");
5154
- llmSpan?.end();
5155
- return {
5156
- text: collected.accumulatedText,
5157
- toolCalls: [],
5158
- stopReason: "error",
5159
- errored: true
5160
- };
5161
- }
5162
- const result = collected.finishValue.value;
5163
- llmSpan?.setAttributes({
5164
- stopReason: result.stopReason,
5165
- inputTokens: result.inputTokens ?? 0,
5166
- outputTokens: result.outputTokens ?? 0
5167
- });
5168
- emitLlmMetrics(inputs, result, startAt);
5169
- llmSpan?.end();
5170
- const stripped = stripThinkBlocks(collected.accumulatedText);
5171
- const thinking = result.thinking ?? collected.thinking;
5172
- return {
5173
- text: stripped.visible,
5174
- toolCalls: result.toolCalls,
5175
- stopReason: result.stopReason,
5176
- errored: false,
5177
- inputTokens: result.inputTokens,
5178
- outputTokens: result.outputTokens,
5179
- cacheReadTokens: result.cacheReadTokens,
5180
- cacheWriteTokens: result.cacheWriteTokens,
5181
- reasoningTokens: result.reasoningTokens,
5182
- ...thinking !== void 0 ? { thinking } : {}
5183
- };
5184
- }
5185
- async function collectLlmEvents(generator, inputs, ctx) {
5186
- let errored = false;
5187
- let finishValue;
5188
- let thinking;
5189
- const partial = { text: "" };
5190
- try {
5191
- const result = await runCollectorLoop(generator, inputs, ctx, partial);
5192
- errored = result.errored;
5193
- finishValue = result.finishValue;
5194
- thinking = result.thinking;
5195
- } catch (cause) {
5196
- if (inputs.signal?.aborted === true) {
5197
- ctx.finalText = "[aborted]";
5198
- ctx.events.push(buildAssistantEvent(inputs, "[aborted]"));
5199
- } else {
5200
- registerLoopError(ctx, cause);
5201
- ctx.finalText = partial.text;
5202
- if (partial.text !== "") ctx.events.push(buildAssistantEvent(inputs, partial.text));
5203
- }
5204
- errored = true;
5205
- }
5206
- const accumulatedText = partial.text;
5207
- return {
5208
- accumulatedText,
5209
- errored,
5210
- finishValue,
5211
- ...thinking !== void 0 ? { thinking } : {}
5212
- };
5213
- }
5214
- function registerLoopError(ctx, cause) {
5215
- if (ctx.error !== void 0) return;
5216
- const rawMessage = cause?.message;
5217
- const message = typeof rawMessage === "string" ? rawMessage : cause instanceof Error ? cause.message : String(cause);
5218
- const metaCode = cause?.metadata?.code;
5219
- const rawCode = cause?.code;
5220
- const code = typeof metaCode === "string" ? metaCode : typeof rawCode === "string" ? rawCode : void 0;
5221
- ctx.error = code !== void 0 ? { message, code, cause } : { message, cause };
5222
- }
5223
- async function consumeStreamEvent(inputs, reasoning, event) {
5224
- if (event.type === "text_delta") {
5225
- const text = event.text ?? "";
5226
- await emitTextDeltaCallback(inputs, text);
5227
- return text;
5228
- }
5229
- if (event.type === "reasoning_delta") {
5230
- await consumeReasoningDelta(inputs, reasoning, {
5231
- text: event.text ?? "",
5232
- ...event.signature !== void 0 ? { signature: event.signature } : {}
5233
- });
5234
- }
5235
- return "";
5236
- }
5237
- async function runCollectorLoop(generator, inputs, ctx, partial) {
5238
- const reasoning = { text: "", startedAt: void 0, signature: void 0 };
5239
- let errored = false;
5240
- let finishValue;
5241
- let thinking;
5242
- try {
5243
- while (true) {
5244
- const next = await generator.next();
5245
- if (next.done === true) {
5246
- finishValue = next;
5247
- break;
5248
- }
5249
- if (next.value.type === "error") {
5250
- registerLoopError(ctx, next.value);
5251
- ctx.finalText = partial.text;
5252
- errored = true;
5253
- break;
5254
- }
5255
- partial.text += await consumeStreamEvent(inputs, reasoning, next.value);
5256
- }
5257
- } finally {
5258
- thinking = await finalizeReasoning(inputs, ctx, reasoning);
5259
- }
5260
- return { errored, finishValue, ...thinking !== void 0 ? { thinking } : {} };
5261
- }
5262
- async function consumeReasoningDelta(inputs, reasoning, delta) {
5263
- if (delta.signature !== void 0) reasoning.signature = delta.signature;
5264
- await accumulateReasoning(inputs, reasoning, delta.text);
5265
- }
5266
- async function accumulateReasoning(inputs, reasoning, text) {
5267
- if (reasoning.startedAt === void 0) reasoning.startedAt = Date.now();
5268
- reasoning.text += text;
5269
- await emitReasoningDeltaCallback(inputs, text);
5270
- }
5271
- async function finalizeReasoning(inputs, ctx, reasoning) {
5272
- if (reasoning.text.length === 0) return void 0;
5273
- const thinkingDurationMs = reasoning.startedAt === void 0 ? 0 : Date.now() - reasoning.startedAt;
5274
- ctx.events.push(
5275
- buildThinkingEvent(inputs, reasoning.text, thinkingDurationMs, reasoning.signature)
5276
- );
5277
- await emitThinkingCompletedCallback(inputs, thinkingDurationMs);
5278
- return {
5279
- type: "thinking",
5280
- text: reasoning.text,
5281
- ...reasoning.signature !== void 0 ? { signature: reasoning.signature } : {}
5282
- };
5283
- }
5284
- async function emitTextDeltaCallback(inputs, text) {
5285
- if (inputs.onDelta === void 0) return;
5286
- const cb = inputs.onDelta;
5287
- await safeCall(
5288
- () => cb({ update: { type: "text-delta", text } }),
5289
- void 0,
5290
- "SendOptions.onDelta"
5291
- );
5292
- }
5293
- async function emitReasoningDeltaCallback(inputs, text) {
5294
- if (inputs.onDelta === void 0) return;
5295
- const cb = inputs.onDelta;
5296
- await safeCall(
5297
- () => cb({ update: { type: "thinking-delta", text } }),
5298
- void 0,
5299
- "SendOptions.onDelta"
5300
- );
5301
- }
5302
- async function emitThinkingCompletedCallback(inputs, thinkingDurationMs) {
5303
- if (inputs.onDelta === void 0) return;
5304
- const cb = inputs.onDelta;
5305
- await safeCall(
5306
- () => cb({ update: { type: "thinking-completed", thinkingDurationMs } }),
5307
- void 0,
5308
- "SendOptions.onDelta"
5309
- );
5310
- }
5311
-
5312
- // src/internal/agent-loop/loop-thinking-steps.ts
5313
- function thinkingStep(thinking) {
5314
- return {
5315
- type: "thinkingMessage",
5316
- message: {
5317
- text: thinking.text,
5318
- ...thinking.signature !== void 0 ? { signature: thinking.signature } : {}
5319
- }
5320
- };
5321
- }
5322
- function recordThinkingOnSilentToolRound(ctx, text, thinking) {
5323
- if (text.length > 0 || thinking === void 0) return;
5324
- ctx.conversation.push({
5325
- type: "agentConversationTurn",
5326
- turn: { steps: [thinkingStep(thinking)] }
5327
- });
5328
- }
5329
-
5330
- // src/internal/tool-dispatch/repair-middleware.ts
5331
- var DECIMAL_RE = /^-?\d+(\.\d+)?$/;
5332
- function repairToolCall(raw, registry) {
5333
- const repairs = [];
5334
- let call = { ...raw };
5335
- if (!registry.has(call.name)) {
5336
- const lower = call.name.toLowerCase();
5337
- let match;
5338
- for (const key of registry.keys()) {
5339
- if (key.toLowerCase() === lower) {
5340
- match = key;
5341
- break;
5342
- }
5343
- }
5344
- if (match !== void 0) {
5345
- repairs.push(`name: "${call.name}" \u2192 "${match}"`);
5346
- call = { ...call, name: match };
5347
- }
5348
- }
5349
- if (typeof call.args === "string") {
5350
- try {
5351
- const parsed = JSON.parse(call.args);
5352
- call = { ...call, args: parsed };
5353
- repairs.push("args: parsed from string");
5354
- } catch {
5355
- }
5356
- }
5357
- const tool = registry.get(call.name);
5358
- if (tool !== void 0 && typeof call.args === "object" && call.args !== null && !Array.isArray(call.args)) {
5359
- const coerced = coerceArgsToSchema(call.args, tool.inputSchema);
5360
- if (coerced.changed.length > 0) {
5361
- call = { ...call, args: coerced.value };
5362
- repairs.push(...coerced.changed);
5363
- }
5364
- }
5365
- return { call, repairs };
5366
- }
5367
- function coerceArgsToSchema(args, schema) {
5368
- const changed = [];
5369
- const out = { ...args };
5370
- const properties = schema.properties;
5371
- if (properties === void 0) return { value: out, changed };
5372
- for (const [key, propDef] of Object.entries(properties)) {
5373
- const val = out[key];
5374
- if (typeof val !== "string") continue;
5375
- const propType = propDef.type;
5376
- if (typeof propType !== "string") continue;
5377
- if (propType === "number" && DECIMAL_RE.test(val.trim())) {
5378
- out[key] = Number(val);
5379
- changed.push(`${key}: string\u2192number`);
5380
- } else if (propType === "integer" && /^-?\d+$/.test(val.trim())) {
5381
- out[key] = Number(val);
5382
- changed.push(`${key}: string\u2192integer`);
5383
- } else if (propType === "boolean" && (val === "true" || val === "false")) {
5384
- out[key] = val === "true";
5385
- changed.push(`${key}: string\u2192boolean`);
5386
- } else if (propType === "array" || propType === "object") {
5387
- try {
5388
- const parsed = JSON.parse(val);
5389
- if (propType === "array" && Array.isArray(parsed)) {
5390
- out[key] = parsed;
5391
- changed.push(`${key}: string\u2192array`);
5392
- } else if (propType === "object" && typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
5393
- out[key] = parsed;
5394
- changed.push(`${key}: string\u2192object`);
5395
- }
5396
- } catch {
5397
- }
5398
- }
5399
- }
5400
- return { value: out, changed };
5401
- }
5402
5116
 
5403
- // src/tool-error.ts
5404
- var ToolError = class extends TheokitAgentError {
5405
- name = "ToolError";
5406
- /** The error content surfaced to the model: a string, or text/image blocks. */
5407
- content;
5408
- constructor(content, options = {}) {
5409
- super(renderToolErrorMessage(content), { ...options, isRetryable: false });
5410
- this.content = content;
5117
+ // src/internal/budget/pricing-data.json
5118
+ var pricing_data_default = {
5119
+ _meta: {
5120
+ pricingVersion: "litellm-2026-05-snapshot"},
5121
+ models: {
5122
+ "anthropic/claude-opus-4-7": {
5123
+ input: 5,
5124
+ output: 25,
5125
+ cacheRead: 0.5,
5126
+ cacheWrite: 6.25
5127
+ },
5128
+ "anthropic/claude-opus-4-6": {
5129
+ input: 5,
5130
+ output: 25,
5131
+ cacheRead: 0.5,
5132
+ cacheWrite: 6.25
5133
+ },
5134
+ "anthropic/claude-opus-4-5": {
5135
+ input: 5,
5136
+ output: 25,
5137
+ cacheRead: 0.5,
5138
+ cacheWrite: 6.25
5139
+ },
5140
+ "anthropic/claude-sonnet-4-6": {
5141
+ input: 3,
5142
+ output: 15,
5143
+ cacheRead: 0.3,
5144
+ cacheWrite: 3.75
5145
+ },
5146
+ "anthropic/claude-sonnet-4-5": {
5147
+ input: 3,
5148
+ output: 15,
5149
+ cacheRead: 0.3,
5150
+ cacheWrite: 3.75
5151
+ },
5152
+ "anthropic/claude-haiku-4-5": {
5153
+ input: 1,
5154
+ output: 5,
5155
+ cacheRead: 0.1,
5156
+ cacheWrite: 1.25
5157
+ },
5158
+ "anthropic/claude-3-5-sonnet": {
5159
+ input: 3,
5160
+ output: 15,
5161
+ cacheRead: 0.3,
5162
+ cacheWrite: 3.75
5163
+ },
5164
+ "anthropic/claude-3-5-haiku": {
5165
+ input: 0.8,
5166
+ output: 4,
5167
+ cacheRead: 0.08,
5168
+ cacheWrite: 1
5169
+ },
5170
+ "anthropic/claude-3-opus": {
5171
+ input: 15,
5172
+ output: 75,
5173
+ cacheRead: 1.5,
5174
+ cacheWrite: 18.75
5175
+ },
5176
+ "anthropic/claude-3-haiku": {
5177
+ input: 0.25,
5178
+ output: 1.25,
5179
+ cacheRead: 0.03,
5180
+ cacheWrite: 0.3
5181
+ },
5182
+ "openai/gpt-4o": {
5183
+ input: 2.5,
5184
+ output: 10,
5185
+ cacheRead: 1.25
5186
+ },
5187
+ "openai/gpt-4o-mini": {
5188
+ input: 0.15,
5189
+ output: 0.6,
5190
+ cacheRead: 0.075
5191
+ },
5192
+ "openai/gpt-4.1": {
5193
+ input: 2,
5194
+ output: 8,
5195
+ cacheRead: 0.5
5196
+ },
5197
+ "openai/gpt-4.1-mini": {
5198
+ input: 0.4,
5199
+ output: 1.6,
5200
+ cacheRead: 0.1
5201
+ },
5202
+ "openai/gpt-4.1-nano": {
5203
+ input: 0.1,
5204
+ output: 0.4,
5205
+ cacheRead: 0.025
5206
+ },
5207
+ "openai/o3": {
5208
+ input: 2,
5209
+ output: 8,
5210
+ cacheRead: 0.5
5211
+ },
5212
+ "openai/o3-mini": {
5213
+ input: 1.1,
5214
+ output: 4.4,
5215
+ cacheRead: 0.55
5216
+ },
5217
+ "openai/o4-mini": {
5218
+ input: 1.1,
5219
+ output: 4.4,
5220
+ cacheRead: 0.275
5221
+ },
5222
+ "deepseek/deepseek-chat": {
5223
+ input: 0.14,
5224
+ output: 0.28
5225
+ },
5226
+ "deepseek/deepseek-reasoner": {
5227
+ input: 0.55,
5228
+ output: 2.19
5229
+ },
5230
+ "google/gemini-2.5-pro": {
5231
+ input: 1.25,
5232
+ output: 10
5233
+ },
5234
+ "google/gemini-2.5-flash": {
5235
+ input: 0.15,
5236
+ output: 0.6
5237
+ },
5238
+ "google/gemini-2.0-flash": {
5239
+ input: 0.1,
5240
+ output: 0.4
5241
+ }
5411
5242
  }
5412
5243
  };
5413
- function renderToolErrorMessage(content) {
5414
- if (typeof content === "string") return content;
5415
- return content.map((block) => block.type === "text" ? block.text : `[${block.source.media_type} image]`).join("\n");
5416
- }
5417
5244
 
5418
- // src/internal/runtime/tools/shell-tool.ts
5419
- async function runShell(options) {
5420
- if (options.sandbox === true && isObviouslyUnsafe(options.command)) {
5421
- return {
5422
- stdout: "",
5423
- stderr: `Sandbox refused command: ${options.command}`,
5424
- exitCode: 126,
5425
- timedOut: false
5426
- };
5427
- }
5428
- const result = await spawnAndCollect({
5429
- command: "sh",
5430
- args: ["-c", options.command],
5431
- cwd: options.cwd,
5432
- ...options.env !== void 0 ? { env: options.env } : {},
5433
- ...options.timeoutMs !== void 0 ? { timeoutMs: options.timeoutMs } : {}
5434
- });
5435
- const stderr = result.spawnError !== void 0 ? result.stderr + result.spawnError.message : result.stderr;
5245
+ // src/internal/budget/pricing-registry.ts
5246
+ var data = pricing_data_default;
5247
+ function buildEntry(key, raw) {
5248
+ const [provider, ...modelParts] = key.split("/");
5436
5249
  return {
5437
- stdout: result.stdout,
5438
- stderr,
5439
- exitCode: result.exitCode,
5440
- timedOut: result.timedOut
5441
- };
5442
- }
5443
- function isObviouslyUnsafe(command) {
5444
- if (/(^|\s)(rm|mv|cp)\s+[^|;]*\s+\/(etc|var|root)\b/.test(command)) return true;
5445
- if (/sudo\s/.test(command)) return true;
5446
- return false;
5447
- }
5448
-
5449
- // src/internal/agent-loop/tool-executors.ts
5450
- async function executeTool(inputs, resolved, call) {
5451
- if (resolved === void 0) {
5452
- return { stdout: "", stderr: `Unknown tool ${call.name}`, exitCode: 127 };
5453
- }
5454
- if (resolved.origin === "shell") return runShellTool(inputs, call);
5455
- if (resolved.origin === "memory")
5456
- return runMemoryTool(resolved, call, inputs.context, inputs.agentId);
5457
- if (resolved.origin === "custom")
5458
- return runCustomTool(
5459
- resolved,
5460
- call,
5461
- inputs.signal,
5462
- inputs.context,
5463
- inputs.messages,
5464
- inputs.agentId
5465
- );
5466
- return runMcpTool(inputs, resolved, call);
5250
+ provider: provider ?? "unknown",
5251
+ model: modelParts.join("/"),
5252
+ inputCostPerMillion: raw.input,
5253
+ outputCostPerMillion: raw.output,
5254
+ ...raw.cacheRead !== void 0 ? { cacheReadCostPerMillion: raw.cacheRead } : {},
5255
+ ...raw.cacheWrite !== void 0 ? { cacheWriteCostPerMillion: raw.cacheWrite } : {},
5256
+ ...raw.reasoning !== void 0 ? { reasoningCostPerMillion: raw.reasoning } : {},
5257
+ pricingVersion: data._meta.pricingVersion
5258
+ };
5467
5259
  }
5468
- async function runMemoryTool(resolved, call, context, threadId) {
5469
- return runHandlerTool(
5470
- "memory",
5471
- resolved.memoryHandler,
5472
- call,
5473
- void 0,
5474
- context,
5475
- void 0,
5476
- threadId
5477
- );
5260
+ function stripDateSuffix(model) {
5261
+ return model.replace(/-\d{4}-?\d{2}-?\d{2}$/, "");
5478
5262
  }
5479
- async function runCustomTool(resolved, call, signal, context, messages, threadId) {
5480
- return runHandlerTool(
5481
- "custom",
5482
- resolved.customHandler,
5483
- call,
5484
- signal,
5485
- context,
5486
- messages,
5487
- threadId
5488
- );
5263
+ function normalizeAnthropicDots(model) {
5264
+ return model.replace(/(?<=\d)\.(?=\d)/g, "-");
5489
5265
  }
5490
- async function runHandlerTool(kind, handler, call, signal, context, messages, threadId) {
5491
- if (handler === void 0) {
5492
- return { stdout: "", stderr: `${kind} tool ${call.name} has no handler`, exitCode: 127 };
5266
+ function stripOpenRouterPrefix(modelId) {
5267
+ return modelId.startsWith("openrouter/") ? modelId.slice("openrouter/".length) : modelId;
5268
+ }
5269
+ function lookupRaw(key) {
5270
+ return data.models[key];
5271
+ }
5272
+ function getPricingEntry(opts) {
5273
+ const cleaned = stripOpenRouterPrefix(opts.model);
5274
+ const directKey = `${opts.provider}/${cleaned}`;
5275
+ const direct = lookupRaw(directKey);
5276
+ if (direct !== void 0) return buildEntry(directKey, direct);
5277
+ const noSuffix = stripDateSuffix(cleaned);
5278
+ if (noSuffix !== cleaned) {
5279
+ const noSuffixKey = `${opts.provider}/${noSuffix}`;
5280
+ const found = lookupRaw(noSuffixKey);
5281
+ if (found !== void 0) return buildEntry(noSuffixKey, found);
5493
5282
  }
5494
- try {
5495
- const split = handler[TOOL_SPLIT_RESOLVER];
5496
- if (split !== void 0) {
5497
- const { model, app } = await split(call.input, { signal, context, threadId });
5498
- const base = typeof model === "string" ? { stdout: model, stderr: "", exitCode: 0 } : { stdout: "", stderr: "", exitCode: 0, content: model };
5499
- return { ...base, appResult: app };
5500
- }
5501
- const out = await handler(call.input, { signal, context, messages, threadId });
5502
- if (typeof out !== "string") return { stdout: "", stderr: "", exitCode: 0, content: out };
5503
- return { stdout: out, stderr: "", exitCode: 0 };
5504
- } catch (cause) {
5505
- if (cause instanceof ToolError) {
5506
- return { stdout: "", stderr: cause.message, exitCode: 1, content: cause.content };
5283
+ if (opts.provider === "anthropic") {
5284
+ const normalized = normalizeAnthropicDots(stripDateSuffix(cleaned));
5285
+ const normKey = `${opts.provider}/${normalized}`;
5286
+ const found = lookupRaw(normKey);
5287
+ if (found !== void 0) return buildEntry(normKey, found);
5288
+ }
5289
+ if (cleaned.includes("/")) {
5290
+ const found = lookupRaw(cleaned);
5291
+ if (found !== void 0) return buildEntry(cleaned, found);
5292
+ const stripped = stripDateSuffix(cleaned);
5293
+ if (stripped !== cleaned) {
5294
+ const found2 = lookupRaw(stripped);
5295
+ if (found2 !== void 0) return buildEntry(stripped, found2);
5507
5296
  }
5508
- const message = cause instanceof Error ? cause.message : String(cause);
5509
- return { stdout: "", stderr: message, exitCode: 1 };
5510
5297
  }
5298
+ const catalogEntry = catalogCostFallback(opts.provider, cleaned);
5299
+ if (catalogEntry !== void 0) return catalogEntry;
5300
+ return void 0;
5511
5301
  }
5512
- async function runShellTool(inputs, call) {
5513
- const command = typeof call.input.command === "string" ? call.input.command : JSON.stringify(call.input);
5514
- const shellOptions = {
5515
- command,
5516
- cwd: inputs.shellCwd,
5517
- sandbox: inputs.shellSandbox
5518
- };
5519
- const result = await runShell(shellOptions);
5520
- const final = { stdout: result.stdout, stderr: result.stderr };
5521
- if (result.exitCode !== null && result.exitCode !== void 0) final.exitCode = result.exitCode;
5522
- return final;
5523
- }
5524
- async function runMcpTool(inputs, resolved, call) {
5525
- const client = inputs.mcp.get(resolved.mcpServerName ?? "");
5526
- if (client === void 0 || resolved.mcpToolName === void 0) {
5302
+ function catalogCostFallback(provider, cleanedModel) {
5303
+ const stripped = stripDateSuffix(cleanedModel);
5304
+ const candidates = [`${provider}/${cleanedModel}`, cleanedModel];
5305
+ if (stripped !== cleanedModel) candidates.push(`${provider}/${stripped}`, stripped);
5306
+ for (const key of candidates) {
5307
+ const info = getCatalogModelInfo(key);
5308
+ const cost = info?.cost;
5309
+ if (cost === void 0) continue;
5310
+ const [prov, ...modelParts] = key.split("/");
5527
5311
  return {
5528
- stdout: "",
5529
- stderr: `MCP server ${resolved.mcpServerName ?? "?"} not connected`,
5530
- exitCode: 127
5312
+ provider: prov ?? provider,
5313
+ model: modelParts.join("/") || cleanedModel,
5314
+ inputCostPerMillion: cost.input,
5315
+ outputCostPerMillion: cost.output,
5316
+ ...cost.cache_read !== void 0 ? { cacheReadCostPerMillion: cost.cache_read } : {},
5317
+ ...cost.cache_write !== void 0 ? { cacheWriteCostPerMillion: cost.cache_write } : {},
5318
+ // M44 M5 fix — honest provenance: a key patched by the LIVE models-dev source is not "vendored".
5319
+ pricingVersion: isPatchedModelKey(key) ? "catalog-models-dev" : "catalog-vendored"
5531
5320
  };
5532
5321
  }
5533
- try {
5534
- const response = await client.callTool(resolved.mcpToolName, call.input);
5535
- const text = response.content.filter((part) => part.type === "text").map((part) => part.text).join("\n");
5536
- return { stdout: text, stderr: "", exitCode: response.isError === true ? 1 : 0 };
5537
- } catch (cause) {
5538
- const message = cause instanceof Error ? cause.message : String(cause);
5539
- return { stdout: "", stderr: message, exitCode: 1 };
5540
- }
5541
- }
5542
- function renderToolResult(result) {
5543
- if (result.stderr.length > 0 && (result.exitCode ?? 0) !== 0) {
5544
- return `${result.stdout}
5545
- [stderr]
5546
- ${result.stderr}`.trim();
5547
- }
5548
- return result.stdout.trim();
5322
+ return void 0;
5549
5323
  }
5550
5324
 
5551
- // src/internal/agent-loop/tool-timeout.ts
5552
- var TOOL_ABORTED_EXIT = 124;
5553
- function abortedResult(signal) {
5554
- const reason = signal.reason;
5555
- const timedOut = reason?.name === "TimeoutError";
5556
- return {
5557
- stdout: "",
5558
- stderr: timedOut ? "tool execution timed out" : "tool execution aborted",
5559
- exitCode: TOOL_ABORTED_EXIT
5560
- };
5325
+ // src/internal/budget/compute-cost.ts
5326
+ var MICROCENT = 1e6;
5327
+ function isSubscriptionIncluded(provider) {
5328
+ return provider === "openai-codex" || provider === "codex";
5561
5329
  }
5562
- function raceToolExecution(exec, opts) {
5563
- const { signal, timeoutMs } = opts;
5564
- if (signal === void 0 && timeoutMs === void 0) return exec;
5565
- const signals = [];
5566
- if (signal !== void 0) signals.push(signal);
5567
- if (timeoutMs !== void 0) signals.push(AbortSignal.timeout(timeoutMs));
5568
- const merged = signals.length === 1 ? signals[0] : AbortSignal.any(signals);
5569
- if (merged.aborted) return Promise.resolve(abortedResult(merged));
5570
- return new Promise((resolve, reject) => {
5571
- let settled = false;
5572
- const onAbort = () => {
5573
- if (settled) return;
5574
- settled = true;
5575
- resolve(abortedResult(merged));
5576
- };
5577
- merged.addEventListener("abort", onAbort, { once: true });
5578
- exec.then(
5579
- (r) => {
5580
- if (settled) return;
5581
- settled = true;
5582
- merged.removeEventListener("abort", onAbort);
5583
- resolve(r);
5584
- },
5585
- (e) => {
5586
- if (settled) return;
5587
- settled = true;
5588
- merged.removeEventListener("abort", onAbort);
5589
- reject(e);
5590
- }
5591
- );
5592
- });
5330
+ function pricingHasValidRates(entry) {
5331
+ return entry.inputCostPerMillion >= 0 && entry.outputCostPerMillion >= 0 && (entry.cacheReadCostPerMillion === void 0 || entry.cacheReadCostPerMillion >= 0) && (entry.cacheWriteCostPerMillion === void 0 || entry.cacheWriteCostPerMillion >= 0) && (entry.reasoningCostPerMillion === void 0 || entry.reasoningCostPerMillion >= 0);
5593
5332
  }
5594
-
5595
- // src/internal/agent-loop/tool-dispatch.ts
5596
- async function dispatchTools(inputs, tools, toolCalls, events, parentSpan) {
5597
- const maxConcurrent = inputs.maxConcurrentTools ?? 4;
5598
- return mapWithConcurrency(
5599
- toolCalls,
5600
- maxConcurrent,
5601
- (call) => dispatchSingleCall(inputs, tools, call, events, parentSpan)
5602
- );
5333
+ function costForTokens(tokens, perMillion) {
5334
+ if (tokens === 0 || perMillion === 0) return 0;
5335
+ return Math.round(tokens * perMillion * MICROCENT / 1e6) / MICROCENT;
5603
5336
  }
5604
- async function dispatchSingleCall(inputs, tools, call, events, parentSpan) {
5605
- const { call: workingCall, repairs } = applyRepairAndExtractCall(tools, call);
5606
- const callId = generateCallId();
5607
- const forkVeto = vetoFromForkWhitelist(inputs, workingCall, callId, events);
5608
- if (forkVeto !== void 0) return forkVeto;
5609
- const resolved = tools.find((tool) => tool.name === workingCall.name);
5610
- const toolSpan = startToolCallSpan(inputs, workingCall, resolved, callId, repairs, parentSpan);
5611
- events.push(buildToolUseRunning(inputs, callId, workingCall));
5612
- const pluginVeto = await vetoFromPluginPreHook(inputs, workingCall, callId, events);
5613
- if (pluginVeto !== void 0) {
5614
- toolSpan?.setAttribute("tool.vetoed", true);
5615
- toolSpan?.setAttribute("tool.veto_source", "plugin");
5616
- toolSpan?.end();
5617
- return pluginVeto;
5337
+ function computeCost(args) {
5338
+ if (isSubscriptionIncluded(args.provider)) {
5339
+ return {
5340
+ amountUsd: 0,
5341
+ status: "included",
5342
+ currency: "USD",
5343
+ source: "subscription_included",
5344
+ pricingVersion: void 0
5345
+ };
5618
5346
  }
5619
- const fileVeto = await vetoFromFileHookPreDecision(inputs, workingCall, callId, events);
5620
- if (fileVeto !== void 0) {
5621
- toolSpan?.setAttribute("tool.vetoed", true);
5622
- toolSpan?.setAttribute("tool.veto_source", "file_hook");
5623
- toolSpan?.end();
5624
- return fileVeto;
5347
+ const entry = getPricingEntry({
5348
+ provider: args.provider,
5349
+ model: args.model,
5350
+ ...args.baseUrl !== void 0 ? { baseUrl: args.baseUrl } : {}
5351
+ });
5352
+ if (entry === void 0) {
5353
+ return {
5354
+ amountUsd: void 0,
5355
+ status: "unknown",
5356
+ currency: "USD",
5357
+ source: "unknown",
5358
+ pricingVersion: void 0
5359
+ };
5360
+ }
5361
+ if (!pricingHasValidRates(entry)) {
5362
+ return {
5363
+ amountUsd: void 0,
5364
+ status: "unknown",
5365
+ currency: "USD",
5366
+ source: "unknown",
5367
+ pricingVersion: entry.pricingVersion,
5368
+ notes: ["pricing entry has negative rates; treated as invalid"]
5369
+ };
5370
+ }
5371
+ const notes = [];
5372
+ const detail = {};
5373
+ const u = args.usage;
5374
+ const inputCost = costForTokens(u.inputTokens, entry.inputCostPerMillion);
5375
+ const outputCost = costForTokens(u.outputTokens, entry.outputCostPerMillion);
5376
+ detail.input = inputCost;
5377
+ detail.output = outputCost;
5378
+ let total = inputCost + outputCost;
5379
+ if (u.cacheReadTokens !== void 0 && u.cacheReadTokens > 0) {
5380
+ if (entry.cacheReadCostPerMillion === void 0) {
5381
+ return {
5382
+ amountUsd: void 0,
5383
+ status: "unknown",
5384
+ currency: "USD",
5385
+ source: "litellm_snapshot",
5386
+ pricingVersion: entry.pricingVersion,
5387
+ notes: ["cache-read tokens present but cacheReadCostPerMillion is undefined"]
5388
+ };
5389
+ }
5390
+ const c = costForTokens(u.cacheReadTokens, entry.cacheReadCostPerMillion);
5391
+ detail.cacheRead = c;
5392
+ total += c;
5393
+ }
5394
+ if (u.cacheWriteTokens !== void 0 && u.cacheWriteTokens > 0) {
5395
+ if (entry.cacheWriteCostPerMillion === void 0) {
5396
+ return {
5397
+ amountUsd: void 0,
5398
+ status: "unknown",
5399
+ currency: "USD",
5400
+ source: "litellm_snapshot",
5401
+ pricingVersion: entry.pricingVersion,
5402
+ notes: ["cache-write tokens present but cacheWriteCostPerMillion is undefined"]
5403
+ };
5404
+ }
5405
+ const c = costForTokens(u.cacheWriteTokens, entry.cacheWriteCostPerMillion);
5406
+ detail.cacheWrite = c;
5407
+ total += c;
5625
5408
  }
5626
- emitRunEvent(inputs.runEventSink, {
5627
- type: "tool_progress",
5628
- toolName: workingCall.name,
5629
- toolCallId: callId
5630
- });
5631
- const result = await runToolWithLifecycle(inputs, resolved, workingCall, callId);
5632
- await inputs.pluginManager?.runPostToolCallHooks({
5633
- name: workingCall.name,
5634
- args: workingCall.input,
5635
- result: { stdout: result.stdout, stderr: result.stderr, exitCode: result.exitCode },
5636
- agentId: inputs.agentId,
5637
- runId: inputs.runId
5638
- });
5639
- return finalizeSpanAndPostHook(inputs, workingCall, callId, result, events, toolSpan);
5640
- }
5641
- function applyRepairAndExtractCall(tools, call) {
5642
- const registryMap = buildRepairRegistry(tools);
5643
- const repaired = repairToolCall({ name: call.name, args: call.input, id: call.id }, registryMap);
5644
- if (repaired.repairs.length === 0) return { call, repairs: repaired.repairs };
5409
+ if (u.reasoningTokens !== void 0 && u.reasoningTokens > 0) {
5410
+ const rate = entry.reasoningCostPerMillion ?? entry.outputCostPerMillion;
5411
+ const c = costForTokens(u.reasoningTokens, rate);
5412
+ detail.reasoning = c;
5413
+ total += c;
5414
+ if (entry.reasoningCostPerMillion === void 0) {
5415
+ notes.push("reasoning tokens billed at output rate (no dedicated reasoning rate available)");
5416
+ }
5417
+ }
5418
+ const amountUsd = Math.round(total * MICROCENT) / MICROCENT;
5645
5419
  return {
5646
- call: {
5647
- ...call,
5648
- name: repaired.call.name,
5649
- input: repaired.call.args ?? {}
5650
- },
5651
- repairs: repaired.repairs
5420
+ amountUsd,
5421
+ status: "estimated",
5422
+ currency: "USD",
5423
+ source: "litellm_snapshot",
5424
+ pricingVersion: entry.pricingVersion,
5425
+ ...notes.length > 0 ? { notes } : {},
5426
+ detail
5652
5427
  };
5653
5428
  }
5654
- function vetoFromForkWhitelist(inputs, call, callId, events) {
5655
- const whitelistDecision = checkToolWhitelist(call.name);
5656
- if (whitelistDecision.allowed) return void 0;
5657
- emitRunEvent(inputs.runEventSink, {
5658
- type: "permission_denied",
5659
- toolName: call.name,
5660
- toolCallId: callId,
5661
- source: "fork_whitelist",
5662
- message: whitelistDecision.reason ?? "tool not available in fork"
5429
+
5430
+ // src/internal/agent-loop/usage-and-cost.ts
5431
+ function accumulateUsage(usage, turn) {
5432
+ const hasAnyToken = turn.inputTokens !== void 0 || turn.outputTokens !== void 0 || turn.cacheReadTokens !== void 0 || turn.cacheWriteTokens !== void 0 || turn.reasoningTokens !== void 0;
5433
+ if (!hasAnyToken) return;
5434
+ usage.add({
5435
+ inputTokens: turn.inputTokens,
5436
+ outputTokens: turn.outputTokens,
5437
+ cacheReadTokens: turn.cacheReadTokens,
5438
+ cacheWriteTokens: turn.cacheWriteTokens,
5439
+ reasoningTokens: turn.reasoningTokens
5663
5440
  });
5664
- events.push(buildToolUseRunning(inputs, callId, call));
5665
- events.push(
5666
- buildToolUseCompleted(inputs, callId, call, {
5667
- stdout: "",
5668
- stderr: whitelistDecision.reason ?? "tool not available in fork",
5669
- exitCode: 126
5670
- })
5671
- );
5672
- return {
5673
- type: "tool_result",
5674
- toolUseId: call.id,
5675
- content: `Tool blocked by fork whitelist: ${whitelistDecision.reason}`
5441
+ }
5442
+ function computeUsageCost(inputs, usage) {
5443
+ const modelId = inputs.model.id;
5444
+ if (modelId === void 0 || modelId === "auto") return void 0;
5445
+ const parsed = parseModelId(modelId);
5446
+ const provider = parsed.provider ?? inputs.llm.name;
5447
+ const model = parsed.provider !== void 0 ? parsed.name : modelId;
5448
+ return computeCost({ provider, model, usage });
5449
+ }
5450
+
5451
+ // src/internal/agent-loop/loop-finalize.ts
5452
+ function diagnoseTermination(ctx, budget, lastTurnDecision) {
5453
+ const exhausted = budget.shouldContinue() === false;
5454
+ if (lastTurnDecision === "continue" && exhausted) ctx.stoppedAtIterationLimit = true;
5455
+ if (!exhausted || ctx.finalStatus !== "finished" || ctx.finalText !== "") return;
5456
+ ctx.finalStatus = "error";
5457
+ if (ctx.error !== void 0) return;
5458
+ ctx.error = {
5459
+ message: `Run stopped after ${budget.total} iteration(s) without producing a reply \u2014 the model was still calling tools when the budget ran out. Raise \`SendOptions.maxIterations\` (default 8), or inspect \`RunResult.stoppedAtIterationLimit\` to continue the run.`,
5460
+ code: "iteration_limit_reached"
5676
5461
  };
5677
5462
  }
5678
- function startToolCallSpan(inputs, call, resolved, callId, repairs, parentSpan) {
5679
- const toolSpan = inputs.telemetry?.startChildSpan(parentSpan, "tool.call", {
5680
- "tool.name": call.name,
5681
- "tool.origin": resolved?.origin ?? "unknown",
5682
- callId
5463
+ function stampSendSpan(inputs, ctx, sendSpan, usage, cost) {
5464
+ sendSpan?.setAttribute("status", ctx.finalStatus);
5465
+ if (ctx.stoppedByDoomLoop === true) sendSpan?.setAttribute("stoppedByDoomLoop", true);
5466
+ if (inputs.telemetry?.includeContent === true && ctx.finalText.length > 0) {
5467
+ sendSpan?.addEvent("response", { content: ctx.finalText });
5468
+ }
5469
+ if (usage === void 0) return;
5470
+ sendSpan?.setAttributes({
5471
+ totalInputTokens: usage.inputTokens,
5472
+ totalOutputTokens: usage.outputTokens,
5473
+ ...cost?.amountUsd !== void 0 ? { totalCostUsd: cost.amountUsd } : {}
5683
5474
  });
5684
- if (repairs.length > 0 && toolSpan !== void 0) {
5685
- toolSpan.setAttribute("tool.repairs", repairs.join("; "));
5686
- }
5687
- if (toolSpan !== void 0 && inputs.telemetry?.includeContent === true) {
5688
- toolSpan.addEvent("args", { input: JSON.stringify(call.input) });
5475
+ }
5476
+ async function syncMemoryProvider(inputs, ctx, sendSpan) {
5477
+ if (ctx.finalStatus !== "finished") return;
5478
+ if (ctx.memoryProviderHandle === void 0 || inputs.memoryProvider?.sync === void 0) return;
5479
+ try {
5480
+ await inputs.memoryProvider.sync(ctx.memoryProviderHandle);
5481
+ } catch (cause) {
5482
+ sendSpan?.addEvent("memory.sync.failed", {
5483
+ message: cause instanceof Error ? cause.message : String(cause)
5484
+ });
5689
5485
  }
5690
- return toolSpan;
5691
5486
  }
5692
- async function vetoFromPluginPreHook(inputs, call, callId, events) {
5693
- const pluginVeto = await inputs.pluginManager?.runPreToolCallHooks({
5694
- name: call.name,
5695
- args: call.input,
5696
- agentId: inputs.agentId,
5697
- runId: inputs.runId,
5698
- // SE1 — thread the run's permission mode so a PermissionPlugin gates per-run.
5699
- ...inputs.permissionMode !== void 0 ? { permissionMode: inputs.permissionMode } : {}
5700
- });
5701
- if (pluginVeto === void 0) return void 0;
5702
- emitRunEvent(inputs.runEventSink, {
5703
- type: "permission_denied",
5704
- toolName: call.name,
5705
- toolCallId: callId,
5706
- source: "plugin",
5707
- message: pluginVeto.message
5708
- });
5709
- events.push(
5710
- buildToolUseCompleted(inputs, callId, call, {
5711
- stdout: "",
5712
- stderr: pluginVeto.message,
5713
- exitCode: 126
5714
- })
5715
- );
5487
+ async function finalizeLoopOutput(inputs, ctx, budget, sendSpan, lastTurnDecision) {
5488
+ diagnoseTermination(ctx, budget, lastTurnDecision);
5489
+ const usage = ctx.usage.hasAny() ? ctx.usage.toTokenUsage() : void 0;
5490
+ const cost = usage !== void 0 ? computeUsageCost(inputs, usage) : void 0;
5491
+ stampSendSpan(inputs, ctx, sendSpan, usage, cost);
5492
+ await syncMemoryProvider(inputs, ctx, sendSpan);
5716
5493
  return {
5717
- type: "tool_result",
5718
- toolUseId: call.id,
5719
- content: `Plugin blocked this tool call: ${pluginVeto.message}`
5494
+ events: ctx.events,
5495
+ finalStatus: ctx.finalStatus,
5496
+ result: ctx.finalText,
5497
+ conversation: ctx.conversation,
5498
+ ...usage !== void 0 ? { usage } : {},
5499
+ ...cost !== void 0 ? { cost } : {},
5500
+ ...ctx.error !== void 0 ? { error: ctx.error } : {},
5501
+ ...ctx.stoppedAtIterationLimit === true ? { stoppedAtIterationLimit: true } : {},
5502
+ ...ctx.stoppedByDoomLoop === true ? { stoppedByDoomLoop: true } : {}
5720
5503
  };
5721
5504
  }
5722
- async function vetoFromFileHookPreDecision(inputs, call, callId, events) {
5723
- const preDecision = await inputs.hooks.run({
5724
- event: "preToolUse",
5725
- tool: call.name,
5726
- input: call.input,
5727
- agentId: inputs.agentId,
5728
- runId: inputs.runId
5729
- });
5730
- if (!preDecision.blocked) return void 0;
5731
- emitRunEvent(inputs.runEventSink, {
5732
- type: "permission_denied",
5733
- toolName: call.name,
5734
- toolCallId: callId,
5735
- source: "file_hook",
5736
- message: preDecision.reason ?? "blocked by hook"
5737
- });
5738
- events.push(
5739
- buildToolUseCompleted(inputs, callId, call, {
5740
- stdout: "",
5741
- stderr: preDecision.reason ?? "blocked by hook",
5742
- exitCode: 126
5743
- })
5744
- );
5745
- return {
5746
- type: "tool_result",
5747
- toolUseId: call.id,
5748
- content: `Hook denied this tool call: ${preDecision.reason ?? "no reason given"}`
5749
- };
5505
+ var KEY_PREFIX = "theokit-";
5506
+ var KEY_HEX_LENGTH = 32;
5507
+ function derivePromptCacheKey(sessionId) {
5508
+ if (sessionId === void 0 || sessionId.trim().length === 0) return void 0;
5509
+ const digest = createHash("sha256").update(sessionId, "utf8").digest("hex");
5510
+ return `${KEY_PREFIX}${digest.slice(0, KEY_HEX_LENGTH)}`;
5750
5511
  }
5751
- async function runToolWithLifecycle(inputs, resolved, call, callId) {
5752
- const startAt = Date.now();
5753
- await safeEmitToolHook(inputs.onToolStart, {
5754
- toolName: call.name,
5755
- args: call.input,
5756
- conversationId: inputs.agentId,
5757
- callId
5758
- });
5759
- await emitToolLifecycleDelta(inputs, {
5760
- type: "tool-call-started",
5761
- callId,
5762
- toolCall: { callId, name: call.name, args: call.input },
5763
- modelCallId: callId
5764
- });
5765
- const result = await raceToolExecution(executeTool(inputs, resolved, call), {
5766
- signal: inputs.signal,
5767
- timeoutMs: inputs.perToolTimeoutMs
5768
- });
5769
- const durationMs = Date.now() - startAt;
5770
- await emitToolLifecycleDelta(inputs, {
5771
- type: "tool-call-completed",
5772
- callId,
5773
- toolCall: {
5774
- callId,
5775
- name: call.name,
5776
- args: call.input,
5777
- result: result.content !== void 0 ? result.content : renderToolResult(result)
5778
- },
5779
- modelCallId: callId
5780
- });
5781
- inputs.telemetry?.recordHistogram(HISTOGRAM_NAMES.TOOL_CALL_DURATION_MS, durationMs, {
5782
- "tool.name": call.name
5783
- });
5784
- if (result.exitCode !== void 0 && result.exitCode !== 0 && result.exitCode !== null) {
5785
- await safeEmitToolHook(inputs.onToolError, {
5786
- toolName: call.name,
5787
- args: call.input,
5788
- error: new Error(result.stderr || `tool exited with code ${result.exitCode}`),
5789
- conversationId: inputs.agentId,
5790
- callId,
5791
- durationMs,
5792
- attempt: 1
5793
- });
5794
- } else {
5795
- await safeEmitToolHook(inputs.onToolEnd, {
5796
- toolName: call.name,
5797
- args: call.input,
5798
- // SE17 — when a `toModelOutput` split is active, observability gets the FULL
5799
- // raw output (`appResult`), NOT the compact model-facing value. SE7 — a
5800
- // block-returning handler has empty `stdout`; surface its structured content
5801
- // to the hook instead of an empty string.
5802
- result: result.appResult !== void 0 ? result.appResult : result.content !== void 0 ? result.content : result.stdout,
5803
- conversationId: inputs.agentId,
5804
- callId,
5805
- durationMs
5806
- });
5807
- }
5808
- return result;
5512
+
5513
+ // src/internal/tool-dispatch/strip-think.ts
5514
+ var THINK_PATTERN = /<think>[\s\S]*?<\/think>\s*/g;
5515
+ function stripThinkBlocks(content) {
5516
+ const matches = [...content.matchAll(THINK_PATTERN)];
5517
+ const thinking = matches.length > 0 ? matches.map((m) => m[0]).join("\n").replace(/<\/?think>/g, "").trim() : null;
5518
+ const visible = content.replace(THINK_PATTERN, "").trim();
5519
+ return { visible, thinking };
5809
5520
  }
5810
- function finalizeSpanAndPostHook(inputs, call, callId, result, events, toolSpan) {
5811
- toolSpan?.setAttribute("exitCode", result.exitCode ?? 0);
5812
- if (toolSpan !== void 0 && inputs.telemetry?.includeContent === true) {
5813
- toolSpan.addEvent("result", { stdout: result.stdout.slice(0, 1e3) });
5814
- }
5815
- toolSpan?.end();
5816
- events.push(buildToolUseCompleted(inputs, callId, call, result));
5817
- inputs.hooks.run({
5818
- event: "postToolUse",
5819
- tool: call.name,
5820
- input: call.input,
5821
- output: {
5822
- stdout: result.stdout,
5823
- stderr: result.stderr,
5824
- exitCode: result.exitCode ?? 0,
5825
- // SE7 — structured content (text + image blocks) when the handler
5826
- // returned/threw blocks; absent for the string path.
5827
- ...result.content !== void 0 ? { content: result.content } : {}
5828
- },
5829
- agentId: inputs.agentId,
5830
- runId: inputs.runId
5831
- }).catch((err) => {
5521
+
5522
+ // src/internal/agent-loop/loop-llm-stream.ts
5523
+ function resolveSystemPromptWithMemoryAdditions(systemPrompt, additions) {
5524
+ if (additions === void 0 || additions.length === 0) return systemPrompt;
5525
+ const block = `<active-memory>
5526
+ ${escapeBlockBody(additions)}
5527
+ </active-memory>`;
5528
+ if (systemPrompt === void 0 || systemPrompt.length === 0) return block;
5529
+ return `${block}
5530
+
5531
+ ${systemPrompt}`;
5532
+ }
5533
+ function toLlmTool(tool) {
5534
+ return { name: tool.name, description: tool.description, inputSchema: tool.inputSchema };
5535
+ }
5536
+ function reasoningEffortFromParams(params) {
5537
+ const thinking = params?.find((p) => p.id === "thinking");
5538
+ return thinking !== void 0 && thinking.value.length > 0 ? thinking.value : void 0;
5539
+ }
5540
+ function emitLlmMetrics(inputs, result, startAt) {
5541
+ inputs.telemetry?.recordHistogram(HISTOGRAM_NAMES.LLM_CALL_DURATION_MS, Date.now() - startAt, {
5542
+ provider: inputs.llm.name
5543
+ });
5544
+ if (result.inputTokens === void 0 && result.outputTokens === void 0) {
5545
+ inputs.telemetry?.recordHistogram(HISTOGRAM_NAMES.LLM_USAGE_MISSING, 1, {
5546
+ provider: inputs.llm.name
5547
+ });
5832
5548
  diag(
5833
- `[theokit-sdk] postToolUse hook error (swallowed): ${err instanceof Error ? err.message : String(err)}
5549
+ `[theokit-sdk] llm usage missing from ${inputs.llm.name} finish \u2014 budget may undercount
5834
5550
  `
5835
5551
  );
5552
+ return;
5553
+ }
5554
+ inputs.telemetry?.recordHistogram(
5555
+ HISTOGRAM_NAMES.LLM_TOKENS,
5556
+ (result.inputTokens ?? 0) + (result.outputTokens ?? 0),
5557
+ { provider: inputs.llm.name }
5558
+ );
5559
+ }
5560
+ async function streamLlmTurn(inputs, ctx) {
5561
+ const llmSpan = inputs.telemetry?.startChildSpan(ctx.sendSpan, "llm.call", {
5562
+ "model.id": inputs.model.id ?? "auto",
5563
+ provider: inputs.llm.name
5564
+ });
5565
+ const startAt = Date.now();
5566
+ const signal = inputs.signal ?? new AbortController().signal;
5567
+ const generator = inputs.llm.stream(
5568
+ {
5569
+ model: inputs.model.id ?? "auto",
5570
+ ...(() => {
5571
+ const effective = resolveSystemPromptWithMemoryAdditions(
5572
+ inputs.systemPrompt,
5573
+ ctx.memorySystemPromptAdditions
5574
+ );
5575
+ return effective !== void 0 ? { system: effective } : {};
5576
+ })(),
5577
+ // issue #47: forward the reasoning effort from ModelSelection.params (the `thinking` param)
5578
+ // so the provider produces reasoning. Absent param ⇒ no `reasoning` field (bare request).
5579
+ ...(() => {
5580
+ const effort = reasoningEffortFromParams(inputs.model.params);
5581
+ return effort !== void 0 ? { reasoning: { effort } } : {};
5582
+ })(),
5583
+ // Step-cap force-close: forward the per-run tool gate (`"none"` on a ceiling round forces a
5584
+ // text close even though tools are advertised). Absent ⇒ provider default (auto).
5585
+ ...inputs.toolChoice !== void 0 ? { toolChoice: inputs.toolChoice } : {},
5586
+ // usetheokit/theokit-sdk#383 — the prompt-cache key, derived HERE and from `inputs.agentId`
5587
+ // because this is the one place that sees the session identity on every round. `agentId` is
5588
+ // the run's session identity (`Agent.getOrCreate(sessionId)`), so the derived key is identical
5589
+ // on round 1 and round 12 of a turn, identical on turn 2 of the same session, and different
5590
+ // for a different session. Deriving it per round from a stable input is what makes it a cache
5591
+ // key; minting one anywhere that runs more than once per session would not be.
5592
+ ...(() => {
5593
+ const key = derivePromptCacheKey(inputs.agentId);
5594
+ return key !== void 0 ? { promptCacheKey: key } : {};
5595
+ })(),
5596
+ messages: ctx.messages,
5597
+ tools: ctx.tools.map(toLlmTool)
5598
+ },
5599
+ signal
5600
+ );
5601
+ const collected = await collectLlmEvents(generator, inputs, ctx);
5602
+ if (collected.errored || collected.finishValue === void 0) {
5603
+ llmSpan?.setAttribute("stopReason", "error");
5604
+ llmSpan?.end();
5605
+ return {
5606
+ text: collected.accumulatedText,
5607
+ toolCalls: [],
5608
+ stopReason: "error",
5609
+ errored: true
5610
+ };
5611
+ }
5612
+ const result = collected.finishValue.value;
5613
+ llmSpan?.setAttributes({
5614
+ stopReason: result.stopReason,
5615
+ inputTokens: result.inputTokens ?? 0,
5616
+ outputTokens: result.outputTokens ?? 0
5836
5617
  });
5618
+ emitLlmMetrics(inputs, result, startAt);
5619
+ llmSpan?.end();
5620
+ const stripped = stripThinkBlocks(collected.accumulatedText);
5621
+ const thinking = result.thinking ?? collected.thinking;
5837
5622
  return {
5838
- type: "tool_result",
5839
- toolUseId: call.id,
5840
- // SE7 — structured content blocks (handler-returned or ToolError-carried)
5841
- // are authoritative; otherwise the legacy string rendering.
5842
- content: result.content !== void 0 ? result.content : renderToolResult(result),
5843
- ...result.exitCode !== 0 && result.exitCode !== void 0 ? { isError: true } : {}
5623
+ text: stripped.visible,
5624
+ toolCalls: result.toolCalls,
5625
+ stopReason: result.stopReason,
5626
+ errored: false,
5627
+ inputTokens: result.inputTokens,
5628
+ outputTokens: result.outputTokens,
5629
+ cacheReadTokens: result.cacheReadTokens,
5630
+ cacheWriteTokens: result.cacheWriteTokens,
5631
+ reasoningTokens: result.reasoningTokens,
5632
+ ...thinking !== void 0 ? { thinking } : {}
5844
5633
  };
5845
5634
  }
5846
- async function emitToolLifecycleDelta(inputs, update) {
5847
- if (inputs.onDelta === void 0) return;
5635
+ async function collectLlmEvents(generator, inputs, ctx) {
5636
+ let errored = false;
5637
+ let finishValue;
5638
+ let thinking;
5639
+ const partial = { text: "" };
5848
5640
  try {
5849
- await inputs.onDelta({ update });
5850
- } catch (err) {
5851
- diag(
5852
- `[theokit-sdk] onDelta tool-lifecycle emit error (swallowed): ${err instanceof Error ? err.message : String(err)}
5853
- `
5854
- );
5641
+ const result = await runCollectorLoop(generator, inputs, ctx, partial);
5642
+ errored = result.errored;
5643
+ finishValue = result.finishValue;
5644
+ thinking = result.thinking;
5645
+ } catch (cause) {
5646
+ if (inputs.signal?.aborted === true) {
5647
+ ctx.finalText = "[aborted]";
5648
+ ctx.events.push(buildAssistantEvent(inputs, "[aborted]"));
5649
+ } else {
5650
+ registerLoopError(ctx, cause);
5651
+ ctx.finalText = partial.text;
5652
+ if (partial.text !== "") ctx.events.push(buildAssistantEvent(inputs, partial.text));
5653
+ }
5654
+ errored = true;
5855
5655
  }
5656
+ const accumulatedText = partial.text;
5657
+ return {
5658
+ accumulatedText,
5659
+ errored,
5660
+ finishValue,
5661
+ ...thinking !== void 0 ? { thinking } : {}
5662
+ };
5856
5663
  }
5857
- async function safeEmitToolHook(callback, event) {
5858
- if (callback === void 0) return;
5664
+ function registerLoopError(ctx, cause) {
5665
+ if (ctx.error !== void 0) return;
5666
+ const rawMessage = cause?.message;
5667
+ const message = typeof rawMessage === "string" ? rawMessage : cause instanceof Error ? cause.message : String(cause);
5668
+ const metaCode = cause?.metadata?.code;
5669
+ const rawCode = cause?.code;
5670
+ const code = typeof metaCode === "string" ? metaCode : typeof rawCode === "string" ? rawCode : void 0;
5671
+ ctx.error = code !== void 0 ? { message, code, cause } : { message, cause };
5672
+ }
5673
+ async function consumeStreamEvent(inputs, reasoning, event) {
5674
+ if (event.type === "text_delta") {
5675
+ const text = event.text ?? "";
5676
+ await emitTextDeltaCallback(inputs, text);
5677
+ return text;
5678
+ }
5679
+ if (event.type === "reasoning_delta") {
5680
+ await consumeReasoningDelta(inputs, reasoning, {
5681
+ text: event.text ?? "",
5682
+ ...event.signature !== void 0 ? { signature: event.signature } : {}
5683
+ });
5684
+ }
5685
+ return "";
5686
+ }
5687
+ async function runCollectorLoop(generator, inputs, ctx, partial) {
5688
+ const reasoning = { text: "", startedAt: void 0, signature: void 0 };
5689
+ let errored = false;
5690
+ let finishValue;
5691
+ let thinking;
5859
5692
  try {
5860
- await callback(event);
5861
- } catch (cause) {
5862
- const msg = cause instanceof Error ? cause.message : String(cause);
5863
- diag(`[theokit-sdk] tool lifecycle hook threw: ${msg}
5864
- `);
5693
+ while (true) {
5694
+ const next = await generator.next();
5695
+ if (next.done === true) {
5696
+ finishValue = next;
5697
+ break;
5698
+ }
5699
+ if (next.value.type === "error") {
5700
+ registerLoopError(ctx, next.value);
5701
+ ctx.finalText = partial.text;
5702
+ errored = true;
5703
+ break;
5704
+ }
5705
+ partial.text += await consumeStreamEvent(inputs, reasoning, next.value);
5706
+ }
5707
+ } finally {
5708
+ thinking = await finalizeReasoning(inputs, ctx, reasoning);
5865
5709
  }
5710
+ return { errored, finishValue, ...thinking !== void 0 ? { thinking } : {} };
5711
+ }
5712
+ async function consumeReasoningDelta(inputs, reasoning, delta) {
5713
+ if (delta.signature !== void 0) reasoning.signature = delta.signature;
5714
+ await accumulateReasoning(inputs, reasoning, delta.text);
5715
+ }
5716
+ async function accumulateReasoning(inputs, reasoning, text) {
5717
+ if (reasoning.startedAt === void 0) reasoning.startedAt = Date.now();
5718
+ reasoning.text += text;
5719
+ await emitReasoningDeltaCallback(inputs, text);
5866
5720
  }
5867
- function buildToolUseRunning(inputs, callId, call) {
5721
+ async function finalizeReasoning(inputs, ctx, reasoning) {
5722
+ if (reasoning.text.length === 0) return void 0;
5723
+ const thinkingDurationMs = reasoning.startedAt === void 0 ? 0 : Date.now() - reasoning.startedAt;
5724
+ ctx.events.push(
5725
+ buildThinkingEvent(inputs, reasoning.text, thinkingDurationMs, reasoning.signature)
5726
+ );
5727
+ await emitThinkingCompletedCallback(inputs, thinkingDurationMs);
5868
5728
  return {
5869
- type: "tool_call",
5870
- agent_id: inputs.agentId,
5871
- run_id: inputs.runId,
5872
- call_id: callId,
5873
- name: call.name,
5874
- status: "running",
5875
- args: call.input
5729
+ type: "thinking",
5730
+ text: reasoning.text,
5731
+ ...reasoning.signature !== void 0 ? { signature: reasoning.signature } : {}
5876
5732
  };
5877
5733
  }
5878
- function buildRepairRegistry(tools) {
5879
- const out = /* @__PURE__ */ new Map();
5880
- for (const t of tools) {
5881
- out.set(t.name, { name: t.name, inputSchema: t.inputSchema });
5882
- }
5883
- return out;
5734
+ async function emitTextDeltaCallback(inputs, text) {
5735
+ if (inputs.onDelta === void 0) return;
5736
+ const cb = inputs.onDelta;
5737
+ await safeCall(
5738
+ () => cb({ update: { type: "text-delta", text } }),
5739
+ void 0,
5740
+ "SendOptions.onDelta"
5741
+ );
5742
+ }
5743
+ async function emitReasoningDeltaCallback(inputs, text) {
5744
+ if (inputs.onDelta === void 0) return;
5745
+ const cb = inputs.onDelta;
5746
+ await safeCall(
5747
+ () => cb({ update: { type: "thinking-delta", text } }),
5748
+ void 0,
5749
+ "SendOptions.onDelta"
5750
+ );
5751
+ }
5752
+ async function emitThinkingCompletedCallback(inputs, thinkingDurationMs) {
5753
+ if (inputs.onDelta === void 0) return;
5754
+ const cb = inputs.onDelta;
5755
+ await safeCall(
5756
+ () => cb({ update: { type: "thinking-completed", thinkingDurationMs } }),
5757
+ void 0,
5758
+ "SendOptions.onDelta"
5759
+ );
5884
5760
  }
5885
- function buildToolUseCompleted(inputs, callId, call, result) {
5761
+
5762
+ // src/internal/agent-loop/loop-thinking-steps.ts
5763
+ function thinkingStep(thinking) {
5886
5764
  return {
5887
- type: "tool_call",
5888
- agent_id: inputs.agentId,
5889
- run_id: inputs.runId,
5890
- call_id: callId,
5891
- name: call.name,
5892
- status: "completed",
5893
- args: call.input,
5894
- result: {
5895
- stdout: result.stdout,
5896
- stderr: result.stderr,
5897
- exitCode: result.exitCode ?? 0
5765
+ type: "thinkingMessage",
5766
+ message: {
5767
+ text: thinking.text,
5768
+ ...thinking.signature !== void 0 ? { signature: thinking.signature } : {}
5898
5769
  }
5899
5770
  };
5900
5771
  }
5772
+ function recordThinkingOnSilentToolRound(ctx, text, thinking) {
5773
+ if (text.length > 0 || thinking === void 0) return;
5774
+ ctx.conversation.push({
5775
+ type: "agentConversationTurn",
5776
+ turn: { steps: [thinkingStep(thinking)] }
5777
+ });
5778
+ }
5901
5779
 
5902
- // src/internal/agent-loop/tool-result-guard.ts
5903
- var OPEN = "<untrusted-tool-output>";
5904
- var CLOSE = "</untrusted-tool-output>";
5905
- var PII_PATTERNS = [
5906
- /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/g,
5907
- // email
5908
- /\b(?:\+?\d{1,3}[-.\s]?)?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}\b/g
5909
- // phone
5910
- ];
5911
- function guardText(content, opts) {
5912
- let out = content;
5913
- if (opts.redactPii === true) {
5914
- for (const re of PII_PATTERNS) out = out.replace(re, "[REDACTED]");
5780
+ // src/internal/tool-dispatch/repair-middleware.ts
5781
+ var DECIMAL_RE = /^-?\d+(\.\d+)?$/;
5782
+ function repairToolCall(raw, registry) {
5783
+ const repairs = [];
5784
+ let call = { ...raw };
5785
+ if (!registry.has(call.name)) {
5786
+ const lower = call.name.toLowerCase();
5787
+ let match;
5788
+ for (const key of registry.keys()) {
5789
+ if (key.toLowerCase() === lower) {
5790
+ match = key;
5791
+ break;
5792
+ }
5793
+ }
5794
+ if (match !== void 0) {
5795
+ repairs.push(`name: "${call.name}" \u2192 "${match}"`);
5796
+ call = { ...call, name: match };
5797
+ }
5915
5798
  }
5916
- if (opts.delimit === true) {
5917
- const safe2 = out.split(CLOSE).join("</ untrusted-tool-output>");
5918
- out = `${OPEN}
5919
- ${safe2}
5920
- ${CLOSE}`;
5799
+ if (typeof call.args === "string") {
5800
+ try {
5801
+ const parsed = JSON.parse(call.args);
5802
+ call = { ...call, args: parsed };
5803
+ repairs.push("args: parsed from string");
5804
+ } catch {
5805
+ }
5921
5806
  }
5922
- return out;
5807
+ const tool = registry.get(call.name);
5808
+ if (tool !== void 0 && typeof call.args === "object" && call.args !== null && !Array.isArray(call.args)) {
5809
+ const coerced = coerceArgsToSchema(call.args, tool.inputSchema);
5810
+ if (coerced.changed.length > 0) {
5811
+ call = { ...call, args: coerced.value };
5812
+ repairs.push(...coerced.changed);
5813
+ }
5814
+ }
5815
+ return { call, repairs };
5923
5816
  }
5924
- function applyToolResultGuard(parts, opts) {
5925
- if (opts.delimit !== true && opts.redactPii !== true) return parts;
5926
- return parts.map(
5927
- (p) => (
5928
- // SE7 guard the TEXT of a tool result (string or the text blocks of a
5929
- // structured content); image blocks pass through untouched.
5930
- p.type === "tool_result" ? { ...p, content: renderToolResultContentText(p.content, (t) => guardText(t, opts)) } : p
5931
- )
5932
- );
5817
+ function coerceArgsToSchema(args, schema) {
5818
+ const changed = [];
5819
+ const out = { ...args };
5820
+ const properties = schema.properties;
5821
+ if (properties === void 0) return { value: out, changed };
5822
+ for (const [key, propDef] of Object.entries(properties)) {
5823
+ const val = out[key];
5824
+ if (typeof val !== "string") continue;
5825
+ const propType = propDef.type;
5826
+ if (typeof propType !== "string") continue;
5827
+ if (propType === "number" && DECIMAL_RE.test(val.trim())) {
5828
+ out[key] = Number(val);
5829
+ changed.push(`${key}: string\u2192number`);
5830
+ } else if (propType === "integer" && /^-?\d+$/.test(val.trim())) {
5831
+ out[key] = Number(val);
5832
+ changed.push(`${key}: string\u2192integer`);
5833
+ } else if (propType === "boolean" && (val === "true" || val === "false")) {
5834
+ out[key] = val === "true";
5835
+ changed.push(`${key}: string\u2192boolean`);
5836
+ } else if (propType === "array" || propType === "object") {
5837
+ try {
5838
+ const parsed = JSON.parse(val);
5839
+ if (propType === "array" && Array.isArray(parsed)) {
5840
+ out[key] = parsed;
5841
+ changed.push(`${key}: string\u2192array`);
5842
+ } else if (propType === "object" && typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
5843
+ out[key] = parsed;
5844
+ changed.push(`${key}: string\u2192object`);
5845
+ }
5846
+ } catch {
5847
+ }
5848
+ }
5849
+ }
5850
+ return { value: out, changed };
5933
5851
  }
5934
5852
 
5935
- // src/internal/budget/pricing-data.json
5936
- var pricing_data_default = {
5937
- _meta: {
5938
- pricingVersion: "litellm-2026-05-snapshot"},
5939
- models: {
5940
- "anthropic/claude-opus-4-7": {
5941
- input: 5,
5942
- output: 25,
5943
- cacheRead: 0.5,
5944
- cacheWrite: 6.25
5945
- },
5946
- "anthropic/claude-opus-4-6": {
5947
- input: 5,
5948
- output: 25,
5949
- cacheRead: 0.5,
5950
- cacheWrite: 6.25
5951
- },
5952
- "anthropic/claude-opus-4-5": {
5953
- input: 5,
5954
- output: 25,
5955
- cacheRead: 0.5,
5956
- cacheWrite: 6.25
5957
- },
5958
- "anthropic/claude-sonnet-4-6": {
5959
- input: 3,
5960
- output: 15,
5961
- cacheRead: 0.3,
5962
- cacheWrite: 3.75
5963
- },
5964
- "anthropic/claude-sonnet-4-5": {
5965
- input: 3,
5966
- output: 15,
5967
- cacheRead: 0.3,
5968
- cacheWrite: 3.75
5969
- },
5970
- "anthropic/claude-haiku-4-5": {
5971
- input: 1,
5972
- output: 5,
5973
- cacheRead: 0.1,
5974
- cacheWrite: 1.25
5975
- },
5976
- "anthropic/claude-3-5-sonnet": {
5977
- input: 3,
5978
- output: 15,
5979
- cacheRead: 0.3,
5980
- cacheWrite: 3.75
5981
- },
5982
- "anthropic/claude-3-5-haiku": {
5983
- input: 0.8,
5984
- output: 4,
5985
- cacheRead: 0.08,
5986
- cacheWrite: 1
5987
- },
5988
- "anthropic/claude-3-opus": {
5989
- input: 15,
5990
- output: 75,
5991
- cacheRead: 1.5,
5992
- cacheWrite: 18.75
5993
- },
5994
- "anthropic/claude-3-haiku": {
5995
- input: 0.25,
5996
- output: 1.25,
5997
- cacheRead: 0.03,
5998
- cacheWrite: 0.3
5999
- },
6000
- "openai/gpt-4o": {
6001
- input: 2.5,
6002
- output: 10,
6003
- cacheRead: 1.25
6004
- },
6005
- "openai/gpt-4o-mini": {
6006
- input: 0.15,
6007
- output: 0.6,
6008
- cacheRead: 0.075
6009
- },
6010
- "openai/gpt-4.1": {
6011
- input: 2,
6012
- output: 8,
6013
- cacheRead: 0.5
6014
- },
6015
- "openai/gpt-4.1-mini": {
6016
- input: 0.4,
6017
- output: 1.6,
6018
- cacheRead: 0.1
6019
- },
6020
- "openai/gpt-4.1-nano": {
6021
- input: 0.1,
6022
- output: 0.4,
6023
- cacheRead: 0.025
6024
- },
6025
- "openai/o3": {
6026
- input: 2,
6027
- output: 8,
6028
- cacheRead: 0.5
6029
- },
6030
- "openai/o3-mini": {
6031
- input: 1.1,
6032
- output: 4.4,
6033
- cacheRead: 0.55
6034
- },
6035
- "openai/o4-mini": {
6036
- input: 1.1,
6037
- output: 4.4,
6038
- cacheRead: 0.275
6039
- },
6040
- "deepseek/deepseek-chat": {
6041
- input: 0.14,
6042
- output: 0.28
6043
- },
6044
- "deepseek/deepseek-reasoner": {
6045
- input: 0.55,
6046
- output: 2.19
6047
- },
6048
- "google/gemini-2.5-pro": {
6049
- input: 1.25,
6050
- output: 10
6051
- },
6052
- "google/gemini-2.5-flash": {
6053
- input: 0.15,
6054
- output: 0.6
6055
- },
6056
- "google/gemini-2.0-flash": {
6057
- input: 0.1,
6058
- output: 0.4
6059
- }
5853
+ // src/tool-error.ts
5854
+ var ToolError = class extends TheokitAgentError {
5855
+ name = "ToolError";
5856
+ /** The error content surfaced to the model: a string, or text/image blocks. */
5857
+ content;
5858
+ constructor(content, options = {}) {
5859
+ super(renderToolErrorMessage(content), { ...options, isRetryable: false });
5860
+ this.content = content;
6060
5861
  }
6061
5862
  };
5863
+ function renderToolErrorMessage(content) {
5864
+ if (typeof content === "string") return content;
5865
+ return content.map((block) => block.type === "text" ? block.text : `[${block.source.media_type} image]`).join("\n");
5866
+ }
6062
5867
 
6063
- // src/internal/budget/pricing-registry.ts
6064
- var data = pricing_data_default;
6065
- function buildEntry(key, raw) {
6066
- const [provider, ...modelParts] = key.split("/");
5868
+ // src/internal/runtime/tools/shell-tool.ts
5869
+ async function runShell(options) {
5870
+ if (options.sandbox === true && isObviouslyUnsafe(options.command)) {
5871
+ return {
5872
+ stdout: "",
5873
+ stderr: `Sandbox refused command: ${options.command}`,
5874
+ exitCode: 126,
5875
+ timedOut: false
5876
+ };
5877
+ }
5878
+ const result = await spawnAndCollect({
5879
+ command: "sh",
5880
+ args: ["-c", options.command],
5881
+ cwd: options.cwd,
5882
+ ...options.env !== void 0 ? { env: options.env } : {},
5883
+ ...options.timeoutMs !== void 0 ? { timeoutMs: options.timeoutMs } : {}
5884
+ });
5885
+ const stderr = result.spawnError !== void 0 ? result.stderr + result.spawnError.message : result.stderr;
6067
5886
  return {
6068
- provider: provider ?? "unknown",
6069
- model: modelParts.join("/"),
6070
- inputCostPerMillion: raw.input,
6071
- outputCostPerMillion: raw.output,
6072
- ...raw.cacheRead !== void 0 ? { cacheReadCostPerMillion: raw.cacheRead } : {},
6073
- ...raw.cacheWrite !== void 0 ? { cacheWriteCostPerMillion: raw.cacheWrite } : {},
6074
- ...raw.reasoning !== void 0 ? { reasoningCostPerMillion: raw.reasoning } : {},
6075
- pricingVersion: data._meta.pricingVersion
5887
+ stdout: result.stdout,
5888
+ stderr,
5889
+ exitCode: result.exitCode,
5890
+ timedOut: result.timedOut
6076
5891
  };
6077
5892
  }
6078
- function stripDateSuffix(model) {
6079
- return model.replace(/-\d{4}-?\d{2}-?\d{2}$/, "");
5893
+ function isObviouslyUnsafe(command) {
5894
+ if (/(^|\s)(rm|mv|cp)\s+[^|;]*\s+\/(etc|var|root)\b/.test(command)) return true;
5895
+ if (/sudo\s/.test(command)) return true;
5896
+ return false;
6080
5897
  }
6081
- function normalizeAnthropicDots(model) {
6082
- return model.replace(/(?<=\d)\.(?=\d)/g, "-");
5898
+
5899
+ // src/internal/agent-loop/tool-executors.ts
5900
+ async function executeTool(inputs, resolved, call) {
5901
+ if (resolved === void 0) {
5902
+ return { stdout: "", stderr: `Unknown tool ${call.name}`, exitCode: 127 };
5903
+ }
5904
+ if (resolved.origin === "shell") return runShellTool(inputs, call);
5905
+ if (resolved.origin === "memory")
5906
+ return runHandlerTool("memory", resolved.memoryHandler, call, {
5907
+ context: inputs.context,
5908
+ threadId: inputs.agentId
5909
+ });
5910
+ if (resolved.origin === "custom")
5911
+ return runHandlerTool("custom", resolved.customHandler, call, {
5912
+ signal: inputs.signal,
5913
+ context: inputs.context,
5914
+ messages: inputs.messages,
5915
+ threadId: inputs.agentId
5916
+ });
5917
+ return runMcpTool(inputs, resolved, call);
6083
5918
  }
6084
- function stripOpenRouterPrefix(modelId) {
6085
- return modelId.startsWith("openrouter/") ? modelId.slice("openrouter/".length) : modelId;
5919
+ async function runHandlerTool(kind, handler, call, ctx) {
5920
+ const { signal, context, messages, threadId } = ctx;
5921
+ if (handler === void 0) {
5922
+ return { stdout: "", stderr: `${kind} tool ${call.name} has no handler`, exitCode: 127 };
5923
+ }
5924
+ try {
5925
+ const split = handler[TOOL_SPLIT_RESOLVER];
5926
+ if (split !== void 0) {
5927
+ const { model, app } = await split(call.input, { signal, context, threadId });
5928
+ const base = typeof model === "string" ? { stdout: model, stderr: "", exitCode: 0 } : { stdout: "", stderr: "", exitCode: 0, content: model };
5929
+ return { ...base, appResult: app };
5930
+ }
5931
+ const out = await handler(call.input, { signal, context, messages, threadId });
5932
+ if (typeof out !== "string") return { stdout: "", stderr: "", exitCode: 0, content: out };
5933
+ return { stdout: out, stderr: "", exitCode: 0 };
5934
+ } catch (cause) {
5935
+ if (cause instanceof ToolError) {
5936
+ return { stdout: "", stderr: cause.message, exitCode: 1, content: cause.content };
5937
+ }
5938
+ const message = cause instanceof Error ? cause.message : String(cause);
5939
+ return { stdout: "", stderr: message, exitCode: 1 };
5940
+ }
6086
5941
  }
6087
- function lookupRaw(key) {
6088
- return data.models[key];
5942
+ async function runShellTool(inputs, call) {
5943
+ const command = typeof call.input.command === "string" ? call.input.command : JSON.stringify(call.input);
5944
+ const shellOptions = {
5945
+ command,
5946
+ cwd: inputs.shellCwd,
5947
+ sandbox: inputs.shellSandbox
5948
+ };
5949
+ const result = await runShell(shellOptions);
5950
+ const final = { stdout: result.stdout, stderr: result.stderr };
5951
+ if (result.exitCode !== null && result.exitCode !== void 0) final.exitCode = result.exitCode;
5952
+ return final;
6089
5953
  }
6090
- function getPricingEntry(opts) {
6091
- const cleaned = stripOpenRouterPrefix(opts.model);
6092
- const directKey = `${opts.provider}/${cleaned}`;
6093
- const direct = lookupRaw(directKey);
6094
- if (direct !== void 0) return buildEntry(directKey, direct);
6095
- const noSuffix = stripDateSuffix(cleaned);
6096
- if (noSuffix !== cleaned) {
6097
- const noSuffixKey = `${opts.provider}/${noSuffix}`;
6098
- const found = lookupRaw(noSuffixKey);
6099
- if (found !== void 0) return buildEntry(noSuffixKey, found);
5954
+ async function runMcpTool(inputs, resolved, call) {
5955
+ const client = inputs.mcp.get(resolved.mcpServerName ?? "");
5956
+ if (client === void 0 || resolved.mcpToolName === void 0) {
5957
+ return {
5958
+ stdout: "",
5959
+ stderr: `MCP server ${resolved.mcpServerName ?? "?"} not connected`,
5960
+ exitCode: 127
5961
+ };
6100
5962
  }
6101
- if (opts.provider === "anthropic") {
6102
- const normalized = normalizeAnthropicDots(stripDateSuffix(cleaned));
6103
- const normKey = `${opts.provider}/${normalized}`;
6104
- const found = lookupRaw(normKey);
6105
- if (found !== void 0) return buildEntry(normKey, found);
5963
+ try {
5964
+ const response = await client.callTool(resolved.mcpToolName, call.input);
5965
+ const text = response.content.filter((part) => part.type === "text").map((part) => part.text).join("\n");
5966
+ return { stdout: text, stderr: "", exitCode: response.isError === true ? 1 : 0 };
5967
+ } catch (cause) {
5968
+ const message = cause instanceof Error ? cause.message : String(cause);
5969
+ return { stdout: "", stderr: message, exitCode: 1 };
6106
5970
  }
6107
- if (cleaned.includes("/")) {
6108
- const found = lookupRaw(cleaned);
6109
- if (found !== void 0) return buildEntry(cleaned, found);
6110
- const stripped = stripDateSuffix(cleaned);
6111
- if (stripped !== cleaned) {
6112
- const found2 = lookupRaw(stripped);
6113
- if (found2 !== void 0) return buildEntry(stripped, found2);
6114
- }
5971
+ }
5972
+ function renderToolResult(result) {
5973
+ if (result.stderr.length > 0 && (result.exitCode ?? 0) !== 0) {
5974
+ return `${result.stdout}
5975
+ [stderr]
5976
+ ${result.stderr}`.trim();
6115
5977
  }
6116
- const catalogEntry = catalogCostFallback(opts.provider, cleaned);
6117
- if (catalogEntry !== void 0) return catalogEntry;
6118
- return void 0;
5978
+ return result.stdout.trim();
6119
5979
  }
6120
- function catalogCostFallback(provider, cleanedModel) {
6121
- const stripped = stripDateSuffix(cleanedModel);
6122
- const candidates = [`${provider}/${cleanedModel}`, cleanedModel];
6123
- if (stripped !== cleanedModel) candidates.push(`${provider}/${stripped}`, stripped);
6124
- for (const key of candidates) {
6125
- const info = getCatalogModelInfo(key);
6126
- const cost = info?.cost;
6127
- if (cost === void 0) continue;
6128
- const [prov, ...modelParts] = key.split("/");
6129
- return {
6130
- provider: prov ?? provider,
6131
- model: modelParts.join("/") || cleanedModel,
6132
- inputCostPerMillion: cost.input,
6133
- outputCostPerMillion: cost.output,
6134
- ...cost.cache_read !== void 0 ? { cacheReadCostPerMillion: cost.cache_read } : {},
6135
- ...cost.cache_write !== void 0 ? { cacheWriteCostPerMillion: cost.cache_write } : {},
6136
- // M44 M5 fix honest provenance: a key patched by the LIVE models-dev source is not "vendored".
6137
- pricingVersion: isPatchedModelKey(key) ? "catalog-models-dev" : "catalog-vendored"
5980
+
5981
+ // src/internal/agent-loop/tool-timeout.ts
5982
+ var TOOL_ABORTED_EXIT = 124;
5983
+ function abortedResult(signal) {
5984
+ const reason = signal.reason;
5985
+ const timedOut = reason?.name === "TimeoutError";
5986
+ return {
5987
+ stdout: "",
5988
+ stderr: timedOut ? "tool execution timed out" : "tool execution aborted",
5989
+ exitCode: TOOL_ABORTED_EXIT
5990
+ };
5991
+ }
5992
+ function raceToolExecution(exec, opts) {
5993
+ const { signal, timeoutMs } = opts;
5994
+ if (signal === void 0 && timeoutMs === void 0) return exec;
5995
+ const signals = [];
5996
+ if (signal !== void 0) signals.push(signal);
5997
+ if (timeoutMs !== void 0) signals.push(AbortSignal.timeout(timeoutMs));
5998
+ const merged = signals.length === 1 ? signals[0] : AbortSignal.any(signals);
5999
+ if (merged.aborted) return Promise.resolve(abortedResult(merged));
6000
+ return new Promise((resolve, reject) => {
6001
+ let settled = false;
6002
+ const onAbort = () => {
6003
+ if (settled) return;
6004
+ settled = true;
6005
+ resolve(abortedResult(merged));
6138
6006
  };
6007
+ merged.addEventListener("abort", onAbort, { once: true });
6008
+ exec.then(
6009
+ (r) => {
6010
+ if (settled) return;
6011
+ settled = true;
6012
+ merged.removeEventListener("abort", onAbort);
6013
+ resolve(r);
6014
+ },
6015
+ (e) => {
6016
+ if (settled) return;
6017
+ settled = true;
6018
+ merged.removeEventListener("abort", onAbort);
6019
+ reject(e);
6020
+ }
6021
+ );
6022
+ });
6023
+ }
6024
+
6025
+ // src/internal/agent-loop/tool-dispatch.ts
6026
+ async function dispatchTools(inputs, tools, toolCalls, events, parentSpan) {
6027
+ const maxConcurrent = inputs.maxConcurrentTools ?? 4;
6028
+ return mapWithConcurrency(
6029
+ toolCalls,
6030
+ maxConcurrent,
6031
+ (call) => dispatchSingleCall(inputs, tools, call, events, parentSpan)
6032
+ );
6033
+ }
6034
+ async function dispatchSingleCall(inputs, tools, call, events, parentSpan) {
6035
+ const { call: workingCall, repairs } = applyRepairAndExtractCall(tools, call);
6036
+ const dc = {
6037
+ inputs,
6038
+ call: workingCall,
6039
+ callId: generateCallId(),
6040
+ events,
6041
+ parentSpan
6042
+ };
6043
+ const forkVeto = vetoFromForkWhitelist(dc);
6044
+ if (forkVeto !== void 0) return forkVeto;
6045
+ const resolved = tools.find((tool) => tool.name === workingCall.name);
6046
+ const toolSpan = startToolCallSpan(dc, resolved, repairs);
6047
+ events.push(buildToolUseRunning(dc));
6048
+ const pluginVeto = await vetoFromPluginPreHook(dc);
6049
+ if (pluginVeto !== void 0) {
6050
+ toolSpan?.setAttribute("tool.vetoed", true);
6051
+ toolSpan?.setAttribute("tool.veto_source", "plugin");
6052
+ toolSpan?.end();
6053
+ return pluginVeto;
6054
+ }
6055
+ const fileVeto = await vetoFromFileHookPreDecision(dc);
6056
+ if (fileVeto !== void 0) {
6057
+ toolSpan?.setAttribute("tool.vetoed", true);
6058
+ toolSpan?.setAttribute("tool.veto_source", "file_hook");
6059
+ toolSpan?.end();
6060
+ return fileVeto;
6061
+ }
6062
+ emitRunEvent(inputs.runEventSink, {
6063
+ type: "tool_progress",
6064
+ toolName: workingCall.name,
6065
+ toolCallId: dc.callId
6066
+ });
6067
+ const result = await runToolWithLifecycle(dc, resolved);
6068
+ await inputs.pluginManager?.runPostToolCallHooks({
6069
+ name: workingCall.name,
6070
+ args: workingCall.input,
6071
+ result: { stdout: result.stdout, stderr: result.stderr, exitCode: result.exitCode },
6072
+ agentId: inputs.agentId,
6073
+ runId: inputs.runId
6074
+ });
6075
+ return finalizeSpanAndPostHook(dc, result, toolSpan);
6076
+ }
6077
+ function applyRepairAndExtractCall(tools, call) {
6078
+ const registryMap = buildRepairRegistry(tools);
6079
+ const repaired = repairToolCall({ name: call.name, args: call.input, id: call.id }, registryMap);
6080
+ if (repaired.repairs.length === 0) return { call, repairs: repaired.repairs };
6081
+ return {
6082
+ call: {
6083
+ ...call,
6084
+ name: repaired.call.name,
6085
+ input: repaired.call.args ?? {}
6086
+ },
6087
+ repairs: repaired.repairs
6088
+ };
6089
+ }
6090
+ function vetoFromForkWhitelist(dc) {
6091
+ const { inputs, call, callId, events } = dc;
6092
+ const whitelistDecision = checkToolWhitelist(call.name);
6093
+ if (whitelistDecision.allowed) return void 0;
6094
+ emitRunEvent(inputs.runEventSink, {
6095
+ type: "permission_denied",
6096
+ toolName: call.name,
6097
+ toolCallId: callId,
6098
+ source: "fork_whitelist",
6099
+ message: whitelistDecision.reason ?? "tool not available in fork"
6100
+ });
6101
+ events.push(buildToolUseRunning(dc));
6102
+ events.push(
6103
+ buildToolUseCompleted(dc, {
6104
+ stdout: "",
6105
+ stderr: whitelistDecision.reason ?? "tool not available in fork",
6106
+ exitCode: 126
6107
+ })
6108
+ );
6109
+ return {
6110
+ type: "tool_result",
6111
+ toolUseId: call.id,
6112
+ content: `Tool blocked by fork whitelist: ${whitelistDecision.reason}`
6113
+ };
6114
+ }
6115
+ function startToolCallSpan(dc, resolved, repairs) {
6116
+ const { inputs, call, callId, parentSpan } = dc;
6117
+ const toolSpan = inputs.telemetry?.startChildSpan(parentSpan, "tool.call", {
6118
+ "tool.name": call.name,
6119
+ "tool.origin": resolved?.origin ?? "unknown",
6120
+ callId
6121
+ });
6122
+ if (repairs.length > 0 && toolSpan !== void 0) {
6123
+ toolSpan.setAttribute("tool.repairs", repairs.join("; "));
6139
6124
  }
6140
- return void 0;
6141
- }
6142
-
6143
- // src/internal/budget/compute-cost.ts
6144
- var MICROCENT = 1e6;
6145
- function isSubscriptionIncluded(provider) {
6146
- return provider === "openai-codex" || provider === "codex";
6125
+ if (toolSpan !== void 0 && inputs.telemetry?.includeContent === true) {
6126
+ toolSpan.addEvent("args", { input: JSON.stringify(call.input) });
6127
+ }
6128
+ return toolSpan;
6147
6129
  }
6148
- function pricingHasValidRates(entry) {
6149
- return entry.inputCostPerMillion >= 0 && entry.outputCostPerMillion >= 0 && (entry.cacheReadCostPerMillion === void 0 || entry.cacheReadCostPerMillion >= 0) && (entry.cacheWriteCostPerMillion === void 0 || entry.cacheWriteCostPerMillion >= 0) && (entry.reasoningCostPerMillion === void 0 || entry.reasoningCostPerMillion >= 0);
6130
+ async function vetoFromPluginPreHook(dc) {
6131
+ const { inputs, call, callId, events } = dc;
6132
+ const pluginVeto = await inputs.pluginManager?.runPreToolCallHooks({
6133
+ name: call.name,
6134
+ args: call.input,
6135
+ agentId: inputs.agentId,
6136
+ runId: inputs.runId,
6137
+ // SE1 — thread the run's permission mode so a PermissionPlugin gates per-run.
6138
+ ...inputs.permissionMode !== void 0 ? { permissionMode: inputs.permissionMode } : {}
6139
+ });
6140
+ if (pluginVeto === void 0) return void 0;
6141
+ emitRunEvent(inputs.runEventSink, {
6142
+ type: "permission_denied",
6143
+ toolName: call.name,
6144
+ toolCallId: callId,
6145
+ source: "plugin",
6146
+ message: pluginVeto.message
6147
+ });
6148
+ events.push(
6149
+ buildToolUseCompleted(dc, {
6150
+ stdout: "",
6151
+ stderr: pluginVeto.message,
6152
+ exitCode: 126
6153
+ })
6154
+ );
6155
+ return {
6156
+ type: "tool_result",
6157
+ toolUseId: call.id,
6158
+ content: `Plugin blocked this tool call: ${pluginVeto.message}`
6159
+ };
6150
6160
  }
6151
- function costForTokens(tokens, perMillion) {
6152
- if (tokens === 0 || perMillion === 0) return 0;
6153
- return Math.round(tokens * perMillion * MICROCENT / 1e6) / MICROCENT;
6161
+ async function vetoFromFileHookPreDecision(dc) {
6162
+ const { inputs, call, callId, events } = dc;
6163
+ const preDecision = await inputs.hooks.run({
6164
+ event: "preToolUse",
6165
+ tool: call.name,
6166
+ input: call.input,
6167
+ agentId: inputs.agentId,
6168
+ runId: inputs.runId
6169
+ });
6170
+ if (!preDecision.blocked) return void 0;
6171
+ emitRunEvent(inputs.runEventSink, {
6172
+ type: "permission_denied",
6173
+ toolName: call.name,
6174
+ toolCallId: callId,
6175
+ source: "file_hook",
6176
+ message: preDecision.reason ?? "blocked by hook"
6177
+ });
6178
+ events.push(
6179
+ buildToolUseCompleted(dc, {
6180
+ stdout: "",
6181
+ stderr: preDecision.reason ?? "blocked by hook",
6182
+ exitCode: 126
6183
+ })
6184
+ );
6185
+ return {
6186
+ type: "tool_result",
6187
+ toolUseId: call.id,
6188
+ content: `Hook denied this tool call: ${preDecision.reason ?? "no reason given"}`
6189
+ };
6154
6190
  }
6155
- function computeCost(args) {
6156
- if (isSubscriptionIncluded(args.provider)) {
6157
- return {
6158
- amountUsd: 0,
6159
- status: "included",
6160
- currency: "USD",
6161
- source: "subscription_included",
6162
- pricingVersion: void 0
6163
- };
6164
- }
6165
- const entry = getPricingEntry({
6166
- provider: args.provider,
6167
- model: args.model,
6168
- ...args.baseUrl !== void 0 ? { baseUrl: args.baseUrl } : {}
6191
+ async function runToolWithLifecycle(dc, resolved) {
6192
+ const { inputs, call, callId } = dc;
6193
+ const startAt = Date.now();
6194
+ await safeEmitToolHook(inputs.onToolStart, {
6195
+ toolName: call.name,
6196
+ args: call.input,
6197
+ conversationId: inputs.agentId,
6198
+ callId
6169
6199
  });
6170
- if (entry === void 0) {
6171
- return {
6172
- amountUsd: void 0,
6173
- status: "unknown",
6174
- currency: "USD",
6175
- source: "unknown",
6176
- pricingVersion: void 0
6177
- };
6200
+ await emitToolLifecycleDelta(inputs, {
6201
+ type: "tool-call-started",
6202
+ callId,
6203
+ toolCall: { callId, name: call.name, args: call.input },
6204
+ modelCallId: callId
6205
+ });
6206
+ const result = await raceToolExecution(executeTool(inputs, resolved, call), {
6207
+ signal: inputs.signal,
6208
+ timeoutMs: inputs.perToolTimeoutMs
6209
+ });
6210
+ const durationMs = Date.now() - startAt;
6211
+ await emitToolLifecycleDelta(inputs, {
6212
+ type: "tool-call-completed",
6213
+ callId,
6214
+ toolCall: {
6215
+ callId,
6216
+ name: call.name,
6217
+ args: call.input,
6218
+ result: result.content !== void 0 ? result.content : renderToolResult(result)
6219
+ },
6220
+ modelCallId: callId
6221
+ });
6222
+ inputs.telemetry?.recordHistogram(HISTOGRAM_NAMES.TOOL_CALL_DURATION_MS, durationMs, {
6223
+ "tool.name": call.name
6224
+ });
6225
+ if (result.exitCode !== void 0 && result.exitCode !== 0 && result.exitCode !== null) {
6226
+ await safeEmitToolHook(inputs.onToolError, {
6227
+ toolName: call.name,
6228
+ args: call.input,
6229
+ error: new Error(result.stderr || `tool exited with code ${result.exitCode}`),
6230
+ conversationId: inputs.agentId,
6231
+ callId,
6232
+ durationMs,
6233
+ attempt: 1
6234
+ });
6235
+ } else {
6236
+ await safeEmitToolHook(inputs.onToolEnd, {
6237
+ toolName: call.name,
6238
+ args: call.input,
6239
+ // SE17 — when a `toModelOutput` split is active, observability gets the FULL
6240
+ // raw output (`appResult`), NOT the compact model-facing value. SE7 — a
6241
+ // block-returning handler has empty `stdout`; surface its structured content
6242
+ // to the hook instead of an empty string.
6243
+ result: result.appResult !== void 0 ? result.appResult : result.content !== void 0 ? result.content : result.stdout,
6244
+ conversationId: inputs.agentId,
6245
+ callId,
6246
+ durationMs
6247
+ });
6178
6248
  }
6179
- if (!pricingHasValidRates(entry)) {
6180
- return {
6181
- amountUsd: void 0,
6182
- status: "unknown",
6183
- currency: "USD",
6184
- source: "unknown",
6185
- pricingVersion: entry.pricingVersion,
6186
- notes: ["pricing entry has negative rates; treated as invalid"]
6187
- };
6249
+ return result;
6250
+ }
6251
+ function finalizeSpanAndPostHook(dc, result, toolSpan) {
6252
+ const { inputs, call, events } = dc;
6253
+ toolSpan?.setAttribute("exitCode", result.exitCode ?? 0);
6254
+ if (toolSpan !== void 0 && inputs.telemetry?.includeContent === true) {
6255
+ toolSpan.addEvent("result", { stdout: result.stdout.slice(0, 1e3) });
6188
6256
  }
6189
- const notes = [];
6190
- const detail = {};
6191
- const u = args.usage;
6192
- const inputCost = costForTokens(u.inputTokens, entry.inputCostPerMillion);
6193
- const outputCost = costForTokens(u.outputTokens, entry.outputCostPerMillion);
6194
- detail.input = inputCost;
6195
- detail.output = outputCost;
6196
- let total = inputCost + outputCost;
6197
- if (u.cacheReadTokens !== void 0 && u.cacheReadTokens > 0) {
6198
- if (entry.cacheReadCostPerMillion === void 0) {
6199
- return {
6200
- amountUsd: void 0,
6201
- status: "unknown",
6202
- currency: "USD",
6203
- source: "litellm_snapshot",
6204
- pricingVersion: entry.pricingVersion,
6205
- notes: ["cache-read tokens present but cacheReadCostPerMillion is undefined"]
6206
- };
6207
- }
6208
- const c = costForTokens(u.cacheReadTokens, entry.cacheReadCostPerMillion);
6209
- detail.cacheRead = c;
6210
- total += c;
6257
+ toolSpan?.end();
6258
+ events.push(buildToolUseCompleted(dc, result));
6259
+ inputs.hooks.run({
6260
+ event: "postToolUse",
6261
+ tool: call.name,
6262
+ input: call.input,
6263
+ output: {
6264
+ stdout: result.stdout,
6265
+ stderr: result.stderr,
6266
+ exitCode: result.exitCode ?? 0,
6267
+ // SE7 — structured content (text + image blocks) when the handler
6268
+ // returned/threw blocks; absent for the string path.
6269
+ ...result.content !== void 0 ? { content: result.content } : {}
6270
+ },
6271
+ agentId: inputs.agentId,
6272
+ runId: inputs.runId
6273
+ }).catch((err) => {
6274
+ diag(
6275
+ `[theokit-sdk] postToolUse hook error (swallowed): ${err instanceof Error ? err.message : String(err)}
6276
+ `
6277
+ );
6278
+ });
6279
+ return {
6280
+ type: "tool_result",
6281
+ toolUseId: call.id,
6282
+ // SE7 — structured content blocks (handler-returned or ToolError-carried)
6283
+ // are authoritative; otherwise the legacy string rendering.
6284
+ content: result.content !== void 0 ? result.content : renderToolResult(result),
6285
+ ...result.exitCode !== 0 && result.exitCode !== void 0 ? { isError: true } : {}
6286
+ };
6287
+ }
6288
+ async function emitToolLifecycleDelta(inputs, update) {
6289
+ if (inputs.onDelta === void 0) return;
6290
+ try {
6291
+ await inputs.onDelta({ update });
6292
+ } catch (err) {
6293
+ diag(
6294
+ `[theokit-sdk] onDelta tool-lifecycle emit error (swallowed): ${err instanceof Error ? err.message : String(err)}
6295
+ `
6296
+ );
6211
6297
  }
6212
- if (u.cacheWriteTokens !== void 0 && u.cacheWriteTokens > 0) {
6213
- if (entry.cacheWriteCostPerMillion === void 0) {
6214
- return {
6215
- amountUsd: void 0,
6216
- status: "unknown",
6217
- currency: "USD",
6218
- source: "litellm_snapshot",
6219
- pricingVersion: entry.pricingVersion,
6220
- notes: ["cache-write tokens present but cacheWriteCostPerMillion is undefined"]
6221
- };
6222
- }
6223
- const c = costForTokens(u.cacheWriteTokens, entry.cacheWriteCostPerMillion);
6224
- detail.cacheWrite = c;
6225
- total += c;
6298
+ }
6299
+ async function safeEmitToolHook(callback, event) {
6300
+ if (callback === void 0) return;
6301
+ try {
6302
+ await callback(event);
6303
+ } catch (cause) {
6304
+ const msg = cause instanceof Error ? cause.message : String(cause);
6305
+ diag(`[theokit-sdk] tool lifecycle hook threw: ${msg}
6306
+ `);
6226
6307
  }
6227
- if (u.reasoningTokens !== void 0 && u.reasoningTokens > 0) {
6228
- const rate = entry.reasoningCostPerMillion ?? entry.outputCostPerMillion;
6229
- const c = costForTokens(u.reasoningTokens, rate);
6230
- detail.reasoning = c;
6231
- total += c;
6232
- if (entry.reasoningCostPerMillion === void 0) {
6233
- notes.push("reasoning tokens billed at output rate (no dedicated reasoning rate available)");
6234
- }
6308
+ }
6309
+ function buildToolUseRunning({ inputs, callId, call }) {
6310
+ return {
6311
+ type: "tool_call",
6312
+ agent_id: inputs.agentId,
6313
+ run_id: inputs.runId,
6314
+ call_id: callId,
6315
+ name: call.name,
6316
+ status: "running",
6317
+ args: call.input
6318
+ };
6319
+ }
6320
+ function buildRepairRegistry(tools) {
6321
+ const out = /* @__PURE__ */ new Map();
6322
+ for (const t of tools) {
6323
+ out.set(t.name, { name: t.name, inputSchema: t.inputSchema });
6235
6324
  }
6236
- const amountUsd = Math.round(total * MICROCENT) / MICROCENT;
6325
+ return out;
6326
+ }
6327
+ function buildToolUseCompleted({ inputs, callId, call }, result) {
6237
6328
  return {
6238
- amountUsd,
6239
- status: "estimated",
6240
- currency: "USD",
6241
- source: "litellm_snapshot",
6242
- pricingVersion: entry.pricingVersion,
6243
- ...notes.length > 0 ? { notes } : {},
6244
- detail
6329
+ type: "tool_call",
6330
+ agent_id: inputs.agentId,
6331
+ run_id: inputs.runId,
6332
+ call_id: callId,
6333
+ name: call.name,
6334
+ status: "completed",
6335
+ args: call.input,
6336
+ result: {
6337
+ stdout: result.stdout,
6338
+ stderr: result.stderr,
6339
+ exitCode: result.exitCode ?? 0
6340
+ }
6245
6341
  };
6246
6342
  }
6247
6343
 
6248
- // src/internal/agent-loop/usage-and-cost.ts
6249
- function accumulateUsage(usage, turn) {
6250
- const hasAnyToken = turn.inputTokens !== void 0 || turn.outputTokens !== void 0 || turn.cacheReadTokens !== void 0 || turn.cacheWriteTokens !== void 0 || turn.reasoningTokens !== void 0;
6251
- if (!hasAnyToken) return;
6252
- usage.add({
6253
- inputTokens: turn.inputTokens,
6254
- outputTokens: turn.outputTokens,
6255
- cacheReadTokens: turn.cacheReadTokens,
6256
- cacheWriteTokens: turn.cacheWriteTokens,
6257
- reasoningTokens: turn.reasoningTokens
6258
- });
6344
+ // src/internal/agent-loop/tool-result-guard.ts
6345
+ var OPEN = "<untrusted-tool-output>";
6346
+ var CLOSE = "</untrusted-tool-output>";
6347
+ var PII_PATTERNS = [
6348
+ /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/g,
6349
+ // email
6350
+ /\b(?:\+?\d{1,3}[-.\s]?)?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}\b/g
6351
+ // phone
6352
+ ];
6353
+ function guardText(content, opts) {
6354
+ let out = content;
6355
+ if (opts.redactPii === true) {
6356
+ for (const re of PII_PATTERNS) out = out.replace(re, "[REDACTED]");
6357
+ }
6358
+ if (opts.delimit === true) {
6359
+ const safe2 = out.split(CLOSE).join("</ untrusted-tool-output>");
6360
+ out = `${OPEN}
6361
+ ${safe2}
6362
+ ${CLOSE}`;
6363
+ }
6364
+ return out;
6259
6365
  }
6260
- function computeUsageCost(inputs, usage) {
6261
- const modelId = inputs.model.id;
6262
- if (modelId === void 0 || modelId === "auto") return void 0;
6263
- const parsed = parseModelId(modelId);
6264
- const provider = parsed.provider ?? inputs.llm.name;
6265
- const model = parsed.provider !== void 0 ? parsed.name : modelId;
6266
- return computeCost({ provider, model, usage });
6366
+ function applyToolResultGuard(parts, opts) {
6367
+ if (opts.delimit !== true && opts.redactPii !== true) return parts;
6368
+ return parts.map(
6369
+ (p) => (
6370
+ // SE7 guard the TEXT of a tool result (string or the text blocks of a
6371
+ // structured content); image blocks pass through untouched.
6372
+ p.type === "tool_result" ? { ...p, content: renderToolResultContentText(p.content, (t) => guardText(t, opts)) } : p
6373
+ )
6374
+ );
6267
6375
  }
6268
6376
 
6269
6377
  // src/internal/agent-loop/loop.ts
@@ -6327,49 +6435,7 @@ async function runAgentLoop(inputs) {
6327
6435
  break;
6328
6436
  }
6329
6437
  }
6330
- if (lastTurnDecision === "continue" && budget.shouldContinue() === false) {
6331
- ctx.stoppedAtIterationLimit = true;
6332
- }
6333
- if (budget.shouldContinue() === false && ctx.finalStatus === "finished" && ctx.finalText === "") {
6334
- ctx.finalStatus = "error";
6335
- if (ctx.error === void 0) {
6336
- ctx.error = {
6337
- message: `Run stopped after ${budget.total} iteration(s) without producing a reply \u2014 the model was still calling tools when the budget ran out. Raise \`SendOptions.maxIterations\` (default 8), or inspect \`RunResult.stoppedAtIterationLimit\` to continue the run.`,
6338
- code: "iteration_limit_reached"
6339
- };
6340
- }
6341
- }
6342
- sendSpan?.setAttribute("status", ctx.finalStatus);
6343
- if (ctx.stoppedByDoomLoop === true) sendSpan?.setAttribute("stoppedByDoomLoop", true);
6344
- if (inputs.telemetry?.includeContent === true && ctx.finalText.length > 0) {
6345
- sendSpan?.addEvent("response", { content: ctx.finalText });
6346
- }
6347
- const usage = ctx.usage.hasAny() ? ctx.usage.toTokenUsage() : void 0;
6348
- const cost = usage !== void 0 ? computeUsageCost(inputs, usage) : void 0;
6349
- if (usage !== void 0) {
6350
- sendSpan?.setAttributes({
6351
- totalInputTokens: usage.inputTokens,
6352
- totalOutputTokens: usage.outputTokens,
6353
- ...cost?.amountUsd !== void 0 ? { totalCostUsd: cost.amountUsd } : {}
6354
- });
6355
- }
6356
- if (ctx.finalStatus === "finished" && ctx.memoryProviderHandle !== void 0 && inputs.memoryProvider?.sync !== void 0) {
6357
- try {
6358
- await inputs.memoryProvider.sync(ctx.memoryProviderHandle);
6359
- } catch {
6360
- }
6361
- }
6362
- return {
6363
- events: ctx.events,
6364
- finalStatus: ctx.finalStatus,
6365
- result: ctx.finalText,
6366
- conversation: ctx.conversation,
6367
- ...usage !== void 0 ? { usage } : {},
6368
- ...cost !== void 0 ? { cost } : {},
6369
- ...ctx.error !== void 0 ? { error: ctx.error } : {},
6370
- ...ctx.stoppedAtIterationLimit === true ? { stoppedAtIterationLimit: true } : {},
6371
- ...ctx.stoppedByDoomLoop === true ? { stoppedByDoomLoop: true } : {}
6372
- };
6438
+ return await finalizeLoopOutput(inputs, ctx, budget, sendSpan, lastTurnDecision);
6373
6439
  } finally {
6374
6440
  await inputs.pluginManager?.runOnSessionEndHooks({
6375
6441
  agentId: inputs.agentId,
@@ -6378,7 +6444,10 @@ async function runAgentLoop(inputs) {
6378
6444
  if (ctxRef !== void 0 && ctxRef.memoryProviderHandle !== void 0 && inputs.memoryProvider !== void 0) {
6379
6445
  try {
6380
6446
  await inputs.memoryProvider.dispose(ctxRef.memoryProviderHandle);
6381
- } catch {
6447
+ } catch (cause) {
6448
+ sendSpan?.addEvent("memory.dispose.failed", {
6449
+ message: cause instanceof Error ? cause.message : String(cause)
6450
+ });
6382
6451
  }
6383
6452
  }
6384
6453
  sendSpan?.end();
@@ -6606,15 +6675,20 @@ var FallbackLlmClient = class {
6606
6675
  });
6607
6676
  }
6608
6677
  };
6609
- function abortError(signal) {
6610
- if (signal.reason instanceof Error) return signal.reason;
6611
- return new Error(signal.reason !== void 0 ? String(signal.reason) : "aborted");
6678
+
6679
+ // src/internal/mcp/handshake-timeout.ts
6680
+ var DEFAULT_MCP_TIMEOUT_MS = 3e4;
6681
+ var HANDSHAKE_FLOOR_MS = 1e4;
6682
+ function handshakeAwareTimeout(input) {
6683
+ const isReconnectHandshake = input.method === "initialize" && input.reconnecting;
6684
+ return isReconnectHandshake ? Math.max(input.requestTimeoutMs, HANDSHAKE_FLOOR_MS) : input.requestTimeoutMs;
6612
6685
  }
6686
+
6687
+ // src/internal/mcp/client.ts
6613
6688
  function createMcpClient(name, config, fetchImpl = fetch) {
6614
6689
  if (isStdio(config)) return new StdioMcpClient(name, config);
6615
6690
  return new HttpMcpClient(name, config, fetchImpl);
6616
6691
  }
6617
- var DEFAULT_MCP_TIMEOUT_MS = 3e4;
6618
6692
  var MAX_STDIO_BUFFER_BYTES = 8 * 1024 * 1024;
6619
6693
  var RECONNECT_BASE_MS = 250;
6620
6694
  var MAX_RECONNECT_ATTEMPTS = 2;
@@ -6688,9 +6762,24 @@ var StdioMcpClient = class extends BaseMcpClient {
6688
6762
  // instead of racing (or spuriously failing with mcp_not_init).
6689
6763
  dropped = false;
6690
6764
  reconnectPromise;
6765
+ /** True only while `reconnect()`'s handshake is in flight — see `timeoutFor`. */
6766
+ reconnecting = false;
6691
6767
  get timeoutMs() {
6692
6768
  return this.config.requestTimeoutMs ?? DEFAULT_MCP_TIMEOUT_MS;
6693
6769
  }
6770
+ /**
6771
+ * The deadline for one RPC. The rule itself — and the reasoning behind it — lives in
6772
+ * `handshake-timeout.ts`, where it is a pure function of three values and can be interrogated
6773
+ * without spawning a process. It was private here, which is why the clause "a caller who sets a
6774
+ * LARGER timeout keeps it" went four months with no test.
6775
+ */
6776
+ timeoutFor(method) {
6777
+ return handshakeAwareTimeout({
6778
+ method,
6779
+ reconnecting: this.reconnecting,
6780
+ requestTimeoutMs: this.timeoutMs
6781
+ });
6782
+ }
6694
6783
  /** Spawn the server child and wire stdout/stderr/error/exit handlers.
6695
6784
  * Shared by `initialize()` and the M2 #59 reconnect path. */
6696
6785
  spawnChild() {
@@ -6756,12 +6845,15 @@ var StdioMcpClient = class extends BaseMcpClient {
6756
6845
  for (let attempt = 0; attempt < MAX_RECONNECT_ATTEMPTS; attempt += 1) {
6757
6846
  await reconnectDelay(attempt);
6758
6847
  this.spawnChild();
6848
+ this.reconnecting = true;
6759
6849
  try {
6760
6850
  await super.initialize();
6761
6851
  this.dropped = false;
6762
6852
  return;
6763
6853
  } catch (err) {
6764
6854
  lastErr = err;
6855
+ } finally {
6856
+ this.reconnecting = false;
6765
6857
  }
6766
6858
  }
6767
6859
  throw new NetworkError(`MCP ${this.name} reconnect exhausted`, {
@@ -6843,16 +6935,17 @@ var StdioMcpClient = class extends BaseMcpClient {
6843
6935
  child.stdin.write(`${JSON.stringify(payload)}
6844
6936
  `);
6845
6937
  return new Promise((resolve, reject) => {
6938
+ const budget = this.timeoutFor(method);
6846
6939
  const timer = setTimeout(() => {
6847
6940
  this.pending.delete(id);
6848
- reject(mcpTimeoutError(this.name, this.timeoutMs));
6941
+ reject(mcpTimeoutError(this.name, budget));
6849
6942
  this.child?.kill("SIGKILL");
6850
6943
  this.child = void 0;
6851
6944
  this.dropped = true;
6852
6945
  this.rejectAllPending(
6853
6946
  new NetworkError(`MCP ${this.name} disconnected`, { code: "mcp_disconnected" })
6854
6947
  );
6855
- }, this.timeoutMs);
6948
+ }, budget);
6856
6949
  this.pending.set(id, { resolve, reject, timer });
6857
6950
  });
6858
6951
  }
@@ -6975,16 +7068,6 @@ function resolveMcpCwd(configCwd) {
6975
7068
  return safePathJoin(process.cwd(), configCwd);
6976
7069
  }
6977
7070
 
6978
- // src/internal/providers/register-plugin-providers.ts
6979
- function registerPluginProviderProfiles(entries) {
6980
- let registered2 = 0;
6981
- for (const entry of entries) {
6982
- registerProvider(entry.profile);
6983
- registered2 += 1;
6984
- }
6985
- return registered2;
6986
- }
6987
-
6988
7071
  // src/internal/local-agent/mcp-pool.ts
6989
7072
  var DEFAULT_IDLE_TTL_MS = 6e5;
6990
7073
  function configKey(config) {
@@ -7048,6 +7131,31 @@ var McpClientPool = class {
7048
7131
  }
7049
7132
  };
7050
7133
 
7134
+ // src/internal/local-agent/real-local-run-mcp.ts
7135
+ var sessionMcpPool = new McpClientPool();
7136
+ function disposeSessionMcpClients(agentId) {
7137
+ sessionMcpPool.disposeSession(agentId, (client) => {
7138
+ void client.close();
7139
+ });
7140
+ }
7141
+ function runOwnsMcpClients(agentOptions) {
7142
+ return agentOptions.mcpLifecycle !== "session";
7143
+ }
7144
+ function buildMcpMap(options) {
7145
+ const map = /* @__PURE__ */ new Map();
7146
+ const inline = options.sendOptions.mcpServers ?? options.agentOptions.mcpServers;
7147
+ if (inline === void 0) return map;
7148
+ const pooled = !runOwnsMcpClients(options.agentOptions);
7149
+ if (pooled) sessionMcpPool.reapIdle((c) => void c.close());
7150
+ for (const [name, config] of Object.entries(inline)) {
7151
+ map.set(
7152
+ name,
7153
+ pooled ? sessionMcpPool.acquire(options.agentId, name, config, () => createMcpClient(name, config)) : createMcpClient(name, config)
7154
+ );
7155
+ }
7156
+ return map;
7157
+ }
7158
+
7051
7159
  // src/internal/tool-registry/personality-filter.ts
7052
7160
  function applyPersonalityFilter(exposedTools, whitelist, opts) {
7053
7161
  if (whitelist === void 0) return exposedTools;
@@ -7118,7 +7226,16 @@ function withheldBuiltinsInput(agentOptions) {
7118
7226
  if (withheld === void 0 || withheld.length === 0) return {};
7119
7227
  return { withheldBuiltinTools: withheld };
7120
7228
  }
7121
- function buildRunToolCatalogInput(agentOptions, sendOptions, pluginManager, personalityToolWhitelist, agentId, personalityName, subagents, effectiveModel) {
7229
+ function buildRunToolCatalogInput({
7230
+ agentOptions,
7231
+ sendOptions,
7232
+ pluginManager,
7233
+ personalityToolWhitelist,
7234
+ agentId,
7235
+ personalityName,
7236
+ subagents,
7237
+ effectiveModel
7238
+ }) {
7122
7239
  const builtins = withheldBuiltinsInput(agentOptions);
7123
7240
  const baseTools = sendOptions?.tools ?? agentOptions.tools ?? [];
7124
7241
  const agentsForTools = subagents !== void 0 && Object.keys(subagents).length > 0 ? subagents : agentOptions.agents;
@@ -7172,32 +7289,6 @@ function createRealLocalRun(options) {
7172
7289
  registerRun(handle);
7173
7290
  return handle;
7174
7291
  }
7175
- var pluginProvidersAnnounced = false;
7176
- function resolveRunProvider(options) {
7177
- registerBuiltins();
7178
- const profiles = options.pluginManager?.aggregated.providerProfiles ?? [];
7179
- const registered2 = registerPluginProviderProfiles(profiles);
7180
- if (registered2 > 0 && !pluginProvidersAnnounced) {
7181
- pluginProvidersAnnounced = true;
7182
- const names = profiles.map((e) => e.profile.name).join(", ");
7183
- diag(`[theokit-sdk] registered ${registered2} plugin provider profile(s): ${names}
7184
- `);
7185
- }
7186
- const parsedModel = parseModelId(options.model?.id);
7187
- const modelInferredProvider = parsedModel.provider !== void 0 && getProviderProfile$1(parsedModel.provider) !== void 0 ? parsedModel.provider : void 0;
7188
- const keyInferredProvider = inferProviderFromApiKey(options.agentOptions.apiKey);
7189
- const primary = options.agentOptions.providers?.routes?.[0]?.provider ?? keyInferredProvider ?? modelInferredProvider ?? detectPrimaryProvider();
7190
- warnProviderPrecedenceOnce(modelInferredProvider, primary);
7191
- const effectiveModelId = modelInferredProvider !== void 0 && modelInferredProvider === primary ? parsedModel.name : options.model?.id ?? "claude-sonnet-4-6";
7192
- return { primary, effectiveModelId };
7193
- }
7194
- function mergeExplicitApiKey(pools, primary, apiKey) {
7195
- if (apiKey === void 0 || apiKey.length === 0) return pools;
7196
- if (isFixtureApiKey(apiKey) || apiKey === LOCAL_RUNTIME_MOCK_KEY) return pools;
7197
- const existing = pools?.[primary];
7198
- if (existing !== void 0 && existing.length > 0) return pools;
7199
- return { ...pools ?? {}, [primary]: [apiKey] };
7200
- }
7201
7292
  function buildLoopInputs(options, runId, userText, userImages) {
7202
7293
  const maxIterations = options.sendOptions.maxIterations;
7203
7294
  if (maxIterations !== void 0 && (!Number.isInteger(maxIterations) || maxIterations < 1)) {
@@ -7256,16 +7347,16 @@ function buildLoopInputs(options, runId, userText, userImages) {
7256
7347
  } : {},
7257
7348
  ...options.priorMessages !== void 0 ? { priorMessages: options.priorMessages } : {},
7258
7349
  ...options.memoryTools !== void 0 && options.memoryTools.length > 0 ? { memoryTools: options.memoryTools } : {},
7259
- ...buildRunToolCatalogInput(
7260
- options.agentOptions,
7261
- options.sendOptions,
7262
- options.pluginManager,
7263
- options.personalityToolWhitelist,
7264
- options.agentId,
7265
- options.personalityName,
7266
- options.subagents,
7267
- options.model
7268
- ),
7350
+ ...buildRunToolCatalogInput({
7351
+ agentOptions: options.agentOptions,
7352
+ sendOptions: options.sendOptions,
7353
+ pluginManager: options.pluginManager,
7354
+ personalityToolWhitelist: options.personalityToolWhitelist,
7355
+ agentId: options.agentId,
7356
+ personalityName: options.personalityName,
7357
+ subagents: options.subagents,
7358
+ effectiveModel: options.model
7359
+ }),
7269
7360
  ...options.pluginManager !== void 0 ? { pluginManager: options.pluginManager } : {},
7270
7361
  // D318 — forward SendOptions.signal to the agent loop so streamLlmTurn
7271
7362
  // can attach it to the LLM `fetch({ signal })` call.
@@ -7302,29 +7393,6 @@ function buildLoopInputs(options, runId, userText, userImages) {
7302
7393
  ...options.agentOptions.memoryProvider !== void 0 ? { memoryProvider: options.agentOptions.memoryProvider } : {}
7303
7394
  };
7304
7395
  }
7305
- var sessionMcpPool = new McpClientPool();
7306
- function disposeSessionMcpClients(agentId) {
7307
- sessionMcpPool.disposeSession(agentId, (client) => {
7308
- void client.close();
7309
- });
7310
- }
7311
- function runOwnsMcpClients(agentOptions) {
7312
- return agentOptions.mcpLifecycle !== "session";
7313
- }
7314
- function buildMcpMap(options) {
7315
- const map = /* @__PURE__ */ new Map();
7316
- const inline = options.sendOptions.mcpServers ?? options.agentOptions.mcpServers;
7317
- if (inline === void 0) return map;
7318
- const pooled = !runOwnsMcpClients(options.agentOptions);
7319
- if (pooled) sessionMcpPool.reapIdle((c) => void c.close());
7320
- for (const [name, config] of Object.entries(inline)) {
7321
- map.set(
7322
- name,
7323
- pooled ? sessionMcpPool.acquire(options.agentId, name, config, () => createMcpClient(name, config)) : createMcpClient(name, config)
7324
- );
7325
- }
7326
- return map;
7327
- }
7328
7396
  var RealLocalRun = class extends FixtureRunBase {
7329
7397
  buildInputs;
7330
7398
  /** theokit#155 — whether this turn releases its MCP clients, or the session pool does. */
@@ -7746,14 +7814,16 @@ var LiveAgentRegistry = class {
7746
7814
  }
7747
7815
  }
7748
7816
  };
7749
- var liveAgentRegistry = new LiveAgentRegistry();
7817
+ var liveAgentRegistry = globalSingleton(
7818
+ "theokit-sdk.runtime.live-agents",
7819
+ () => new LiveAgentRegistry()
7820
+ );
7750
7821
 
7751
7822
  // src/internal/local-agent/local-agent-lifecycle.ts
7752
7823
  async function acquireLeaseIfPossible(store, agentId) {
7753
- const a = store.acquire;
7754
- if (typeof a !== "function") return;
7824
+ if (typeof store.acquire !== "function") return;
7755
7825
  try {
7756
- await a.call(store, agentId);
7826
+ await store.acquire(agentId);
7757
7827
  } catch (err) {
7758
7828
  if (err instanceof Error && err.name === "SessionBusyError") throw err;
7759
7829
  diag(
@@ -7763,12 +7833,10 @@ async function acquireLeaseIfPossible(store, agentId) {
7763
7833
  }
7764
7834
  }
7765
7835
  async function releaseLeaseIfPossible(store, agentId) {
7766
- const r = store.release;
7767
- if (typeof r === "function") await r.call(store, agentId);
7836
+ if (typeof store.release === "function") await store.release(agentId);
7768
7837
  }
7769
7838
  async function disposeSessionStore(store) {
7770
- const d = store.dispose;
7771
- if (typeof d === "function") await d.call(store);
7839
+ if (typeof store.dispose === "function") await store.dispose();
7772
7840
  }
7773
7841
  async function disposeLocalAgentSession(agent) {
7774
7842
  liveAgentRegistry.forget(agent.agentId);
@@ -7791,6 +7859,111 @@ async function reloadLocalAgent(agent) {
7791
7859
  );
7792
7860
  }
7793
7861
 
7862
+ // src/internal/local-agent/local-agent-memory-direct.ts
7863
+ async function createAvailableAdapters(entries, workspaceCwd) {
7864
+ const available = [];
7865
+ for (const entry of entries) {
7866
+ const instance = await entry.createProvider(workspaceCwd);
7867
+ if (instance.isAvailable() === false) {
7868
+ diag(
7869
+ `[theokit-sdk] memory adapter "${instance.id}" reports itself unavailable (plugin "${entry.pluginName}") \u2014 skipping it. Check its credentials.
7870
+ `
7871
+ );
7872
+ continue;
7873
+ }
7874
+ available.push(instance);
7875
+ }
7876
+ return available;
7877
+ }
7878
+ function buildAgentMemory(pluginManager, workspaceCwd, defaultContext) {
7879
+ let resolved;
7880
+ async function ensure() {
7881
+ if (resolved !== void 0) return resolved;
7882
+ const entries = pluginManager.aggregated.memoryProviders;
7883
+ const created = await createAvailableAdapters(entries, workspaceCwd);
7884
+ for (const adapter of created) {
7885
+ if (adapter.initialize !== void 0) {
7886
+ await adapter.initialize();
7887
+ }
7888
+ }
7889
+ resolved = { adapters: created, initialized: true, registered: entries.length };
7890
+ return resolved;
7891
+ }
7892
+ function mergeContext(partial) {
7893
+ const merged = {
7894
+ userId: partial?.userId ?? defaultContext?.userId ?? "",
7895
+ ...partial?.agentId !== void 0 ? { agentId: partial.agentId } : defaultContext?.agentId !== void 0 ? { agentId: defaultContext.agentId } : {},
7896
+ ...partial?.sessionId !== void 0 ? { sessionId: partial.sessionId } : defaultContext?.sessionId !== void 0 ? { sessionId: defaultContext.sessionId } : {},
7897
+ ...partial?.tenantId !== void 0 ? { tenantId: partial.tenantId } : defaultContext?.tenantId !== void 0 ? { tenantId: defaultContext.tenantId } : {},
7898
+ ...partial?.tags !== void 0 ? { tags: partial.tags } : defaultContext?.tags !== void 0 ? { tags: defaultContext.tags } : {},
7899
+ ...partial?.metadata !== void 0 ? { metadata: partial.metadata } : defaultContext?.metadata !== void 0 ? { metadata: defaultContext.metadata } : {}
7900
+ };
7901
+ if (merged.userId === "") {
7902
+ throw new ConfigurationError(
7903
+ "agent.memory requires a userId \u2014 either set AgentOptions.memoryContext.userId or pass ctx.userId at call time.",
7904
+ { code: "memory_context_missing_user_id" }
7905
+ );
7906
+ }
7907
+ return merged;
7908
+ }
7909
+ async function requireAdapters() {
7910
+ const r = await ensure();
7911
+ if (r.adapters.length === 0) {
7912
+ throw new ConfigurationError(
7913
+ r.registered === 0 ? "No memory adapter registered. Pass a memory plugin in AgentOptions.plugins (e.g. supermemoryMemory({...}))." : `All ${r.registered} registered memory adapter(s) reported themselves unavailable \u2014 see the warnings naming each one. Check their credentials.`,
7914
+ { code: "no_memory_adapter" }
7915
+ );
7916
+ }
7917
+ return r.adapters;
7918
+ }
7919
+ return {
7920
+ async write(content, ctx) {
7921
+ const adapters = await requireAdapters();
7922
+ const merged = mergeContext(ctx);
7923
+ const writes = await Promise.allSettled(adapters.map((a) => a.write(content, merged)));
7924
+ const firstFulfilled = writes.find((r) => r.status === "fulfilled");
7925
+ if (firstFulfilled === void 0) {
7926
+ const firstReason = writes[0];
7927
+ throw firstReason.reason;
7928
+ }
7929
+ return firstFulfilled.value;
7930
+ },
7931
+ // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: settled-promise iteration + content dedupe + graceful degrade are 3 inline concerns; helpers would obscure the merge invariant.
7932
+ async recall(query, ctx, k) {
7933
+ const adapters = await requireAdapters();
7934
+ const merged = mergeContext(ctx);
7935
+ const recalls = await Promise.allSettled(adapters.map((a) => a.recall(query, merged, k)));
7936
+ const out = [];
7937
+ const seen = /* @__PURE__ */ new Set();
7938
+ for (const r of recalls) {
7939
+ if (r.status !== "fulfilled") continue;
7940
+ for (const fact of r.value) {
7941
+ if (seen.has(fact.content)) continue;
7942
+ seen.add(fact.content);
7943
+ out.push(fact);
7944
+ }
7945
+ }
7946
+ return out;
7947
+ },
7948
+ async delete(id) {
7949
+ const adapters = await requireAdapters();
7950
+ const prefix = id.split(":", 1)[0] ?? "";
7951
+ const target = adapters.find((a) => a.id === prefix);
7952
+ if (target === void 0) {
7953
+ throw new ConfigurationError(
7954
+ `No adapter found for MemoryId prefix "${prefix}" (registered: ${adapters.map((a) => a.id).join(", ")}).`,
7955
+ { code: "no_memory_adapter" }
7956
+ );
7957
+ }
7958
+ await target.delete(id);
7959
+ },
7960
+ adapter() {
7961
+ if (resolved === void 0) return null;
7962
+ return resolved.adapters[0] ?? null;
7963
+ }
7964
+ };
7965
+ }
7966
+
7794
7967
  // src/internal/memory/active-memory.ts
7795
7968
  var DEFAULTS = {
7796
7969
  queryMode: "recent",
@@ -8014,13 +8187,36 @@ function cacheKey(userText, queryMode, ctx) {
8014
8187
  return createHash("sha256").update(parts.join("\0")).digest("hex");
8015
8188
  }
8016
8189
 
8017
- // src/internal/memory/adapters/azure-openai-embedding.ts
8018
- var DEFAULT_AZURE_OPENAI_EMBEDDING_MODEL = "text-embedding-3-small";
8019
- var DIMENSION_BY_MODEL = {
8190
+ // src/internal/memory/adapters/openai-embedding.ts
8191
+ var DEFAULT_OPENAI_EMBEDDING_MODEL = "text-embedding-3-small";
8192
+ var OPENAI_EMBEDDING_DIMENSIONS = {
8020
8193
  "text-embedding-3-small": 1536,
8021
8194
  "text-embedding-3-large": 3072,
8022
8195
  "text-embedding-ada-002": 1536
8023
8196
  };
8197
+ var DIMENSION_BY_MODEL = { ...OPENAI_EMBEDDING_DIMENSIONS };
8198
+ var openAiMemoryEmbeddingProviderAdapter = {
8199
+ id: "openai",
8200
+ defaultModel: DEFAULT_OPENAI_EMBEDDING_MODEL,
8201
+ transport: "remote",
8202
+ authProviderId: "openai",
8203
+ autoSelectPriority: 20,
8204
+ create: (options) => createOpenAiCompatibleRuntime(
8205
+ {
8206
+ id: "openai",
8207
+ defaultBaseUrl: "https://api.openai.com",
8208
+ apiKeyEnv: "OPENAI_API_KEY",
8209
+ baseUrlEnv: "OPENAI_API_BASE_URL",
8210
+ defaultModel: DEFAULT_OPENAI_EMBEDDING_MODEL,
8211
+ dimensionByModel: DIMENSION_BY_MODEL
8212
+ },
8213
+ options
8214
+ )
8215
+ };
8216
+
8217
+ // src/internal/memory/adapters/azure-openai-embedding.ts
8218
+ var DEFAULT_AZURE_OPENAI_EMBEDDING_MODEL = "text-embedding-3-small";
8219
+ var DIMENSION_BY_MODEL2 = { ...OPENAI_EMBEDDING_DIMENSIONS };
8024
8220
  var azureOpenAiMemoryEmbeddingProviderAdapter = {
8025
8221
  id: "azure-openai",
8026
8222
  defaultModel: DEFAULT_AZURE_OPENAI_EMBEDDING_MODEL,
@@ -8035,7 +8231,7 @@ var azureOpenAiMemoryEmbeddingProviderAdapter = {
8035
8231
  baseUrlEnv: "AZURE_OPENAI_ENDPOINT",
8036
8232
  defaultModel: DEFAULT_AZURE_OPENAI_EMBEDDING_MODEL,
8037
8233
  embeddingsPath: "/openai/deployments/{model}/embeddings?api-version=2024-02-01",
8038
- dimensionByModel: DIMENSION_BY_MODEL,
8234
+ dimensionByModel: DIMENSION_BY_MODEL2,
8039
8235
  // theokit#159 — Azure is NOT OpenAI on the wire, despite the name. It authenticates an API
8040
8236
  // key with the `api-key` header (`Authorization: Bearer` is for Entra ID tokens, not for
8041
8237
  // AZURE_OPENAI_API_KEY), and the deployment already rides in the path, so `model` has no
@@ -8051,7 +8247,7 @@ var azureOpenAiMemoryEmbeddingProviderAdapter = {
8051
8247
 
8052
8248
  // src/internal/memory/adapters/cohere-embedding.ts
8053
8249
  var DEFAULT_COHERE_EMBEDDING_MODEL = "embed-english-v3.0";
8054
- var DIMENSION_BY_MODEL2 = {
8250
+ var DIMENSION_BY_MODEL3 = {
8055
8251
  "embed-english-v3.0": 1024,
8056
8252
  "embed-multilingual-v3.0": 1024,
8057
8253
  "embed-english-light-v3.0": 384,
@@ -8070,7 +8266,7 @@ var cohereMemoryEmbeddingProviderAdapter = {
8070
8266
  apiKeyEnv: "COHERE_API_KEY",
8071
8267
  defaultModel: DEFAULT_COHERE_EMBEDDING_MODEL,
8072
8268
  embeddingsPath: "/v2/embed",
8073
- dimensionByModel: DIMENSION_BY_MODEL2,
8269
+ dimensionByModel: DIMENSION_BY_MODEL3,
8074
8270
  // theokit#159 — `/v2/embed` diverges in BOTH directions: it names the payload `texts`, requires
8075
8271
  // `input_type`, and answers `{embeddings:{float:[[...]]}}` rather than `{data:[{embedding}]}`.
8076
8272
  // `search_document` is the right default here because this runtime embeds material for
@@ -8091,7 +8287,7 @@ var cohereMemoryEmbeddingProviderAdapter = {
8091
8287
 
8092
8288
  // src/internal/memory/adapters/deepinfra-embedding.ts
8093
8289
  var DEFAULT_DEEPINFRA_EMBEDDING_MODEL = "BAAI/bge-large-en-v1.5";
8094
- var DIMENSION_BY_MODEL3 = {
8290
+ var DIMENSION_BY_MODEL4 = {
8095
8291
  "BAAI/bge-large-en-v1.5": 1024,
8096
8292
  "BAAI/bge-base-en-v1.5": 768,
8097
8293
  "BAAI/bge-small-en-v1.5": 384,
@@ -8116,7 +8312,7 @@ var deepinfraMemoryEmbeddingProviderAdapter = {
8116
8312
  apiKeyEnv: "DEEPINFRA_API_KEY",
8117
8313
  baseUrlEnv: "DEEPINFRA_API_BASE_URL",
8118
8314
  defaultModel: DEFAULT_DEEPINFRA_EMBEDDING_MODEL,
8119
- dimensionByModel: DIMENSION_BY_MODEL3,
8315
+ dimensionByModel: DIMENSION_BY_MODEL4,
8120
8316
  embeddingsPath: "/v1/openai/embeddings"
8121
8317
  },
8122
8318
  options
@@ -8125,7 +8321,7 @@ var deepinfraMemoryEmbeddingProviderAdapter = {
8125
8321
 
8126
8322
  // src/internal/memory/adapters/gemini-embedding.ts
8127
8323
  var DEFAULT_GEMINI_EMBEDDING_MODEL = "text-embedding-004";
8128
- var DIMENSION_BY_MODEL4 = {
8324
+ var DIMENSION_BY_MODEL5 = {
8129
8325
  "text-embedding-004": 768,
8130
8326
  "embedding-001": 768
8131
8327
  };
@@ -8144,7 +8340,7 @@ var geminiMemoryEmbeddingProviderAdapter = {
8144
8340
  // theokit#159 — the compat surface is under `/v1beta/openai/`, not the default
8145
8341
  // `/v1/embeddings`; the previous path 404'd on every call.
8146
8342
  embeddingsPath: "/v1beta/openai/embeddings",
8147
- dimensionByModel: DIMENSION_BY_MODEL4
8343
+ dimensionByModel: DIMENSION_BY_MODEL5
8148
8344
  },
8149
8345
  options
8150
8346
  )
@@ -8152,7 +8348,7 @@ var geminiMemoryEmbeddingProviderAdapter = {
8152
8348
 
8153
8349
  // src/internal/memory/adapters/jina-embedding.ts
8154
8350
  var DEFAULT_JINA_EMBEDDING_MODEL = "jina-embeddings-v3";
8155
- var DIMENSION_BY_MODEL5 = {
8351
+ var DIMENSION_BY_MODEL6 = {
8156
8352
  "jina-embeddings-v3": 1024,
8157
8353
  "jina-embeddings-v2-base-en": 768,
8158
8354
  "jina-embeddings-v2-small-en": 512
@@ -8169,7 +8365,7 @@ var jinaMemoryEmbeddingProviderAdapter = {
8169
8365
  defaultBaseUrl: "https://api.jina.ai",
8170
8366
  apiKeyEnv: "JINA_API_KEY",
8171
8367
  defaultModel: DEFAULT_JINA_EMBEDDING_MODEL,
8172
- dimensionByModel: DIMENSION_BY_MODEL5
8368
+ dimensionByModel: DIMENSION_BY_MODEL6
8173
8369
  },
8174
8370
  options
8175
8371
  )
@@ -8177,7 +8373,7 @@ var jinaMemoryEmbeddingProviderAdapter = {
8177
8373
 
8178
8374
  // src/internal/memory/adapters/mistral-embedding.ts
8179
8375
  var DEFAULT_MISTRAL_EMBEDDING_MODEL = "mistral-embed";
8180
- var DIMENSION_BY_MODEL6 = {
8376
+ var DIMENSION_BY_MODEL7 = {
8181
8377
  "mistral-embed": 1024
8182
8378
  };
8183
8379
  var mistralMemoryEmbeddingProviderAdapter = {
@@ -8193,7 +8389,7 @@ var mistralMemoryEmbeddingProviderAdapter = {
8193
8389
  apiKeyEnv: "MISTRAL_API_KEY",
8194
8390
  baseUrlEnv: "MISTRAL_API_BASE_URL",
8195
8391
  defaultModel: DEFAULT_MISTRAL_EMBEDDING_MODEL,
8196
- dimensionByModel: DIMENSION_BY_MODEL6
8392
+ dimensionByModel: DIMENSION_BY_MODEL7
8197
8393
  },
8198
8394
  options
8199
8395
  )
@@ -8202,7 +8398,7 @@ var mistralMemoryEmbeddingProviderAdapter = {
8202
8398
  // src/internal/memory/adapters/ollama-embedding.ts
8203
8399
  var DEFAULT_OLLAMA_EMBEDDING_MODEL = "nomic-embed-text";
8204
8400
  var OLLAMA_LOCAL_SENTINEL_KEY = "ollama-local";
8205
- var DIMENSION_BY_MODEL7 = {
8401
+ var DIMENSION_BY_MODEL8 = {
8206
8402
  // Nomic — local default, recommended quality/size balance.
8207
8403
  "nomic-embed-text": 768,
8208
8404
  "nomic-embed-text:latest": 768,
@@ -8235,39 +8431,13 @@ var ollamaMemoryEmbeddingProviderAdapter = {
8235
8431
  apiKeyEnv: "OLLAMA_API_KEY",
8236
8432
  baseUrlEnv: "OLLAMA_HOST",
8237
8433
  defaultModel: DEFAULT_OLLAMA_EMBEDDING_MODEL,
8238
- dimensionByModel: DIMENSION_BY_MODEL7
8434
+ dimensionByModel: DIMENSION_BY_MODEL8
8239
8435
  },
8240
8436
  { ...options, apiKey }
8241
8437
  );
8242
8438
  }
8243
8439
  };
8244
8440
 
8245
- // src/internal/memory/adapters/openai-embedding.ts
8246
- var DEFAULT_OPENAI_EMBEDDING_MODEL = "text-embedding-3-small";
8247
- var DIMENSION_BY_MODEL8 = {
8248
- "text-embedding-3-small": 1536,
8249
- "text-embedding-3-large": 3072,
8250
- "text-embedding-ada-002": 1536
8251
- };
8252
- var openAiMemoryEmbeddingProviderAdapter = {
8253
- id: "openai",
8254
- defaultModel: DEFAULT_OPENAI_EMBEDDING_MODEL,
8255
- transport: "remote",
8256
- authProviderId: "openai",
8257
- autoSelectPriority: 20,
8258
- create: (options) => createOpenAiCompatibleRuntime(
8259
- {
8260
- id: "openai",
8261
- defaultBaseUrl: "https://api.openai.com",
8262
- apiKeyEnv: "OPENAI_API_KEY",
8263
- baseUrlEnv: "OPENAI_API_BASE_URL",
8264
- defaultModel: DEFAULT_OPENAI_EMBEDDING_MODEL,
8265
- dimensionByModel: DIMENSION_BY_MODEL8
8266
- },
8267
- options
8268
- )
8269
- };
8270
-
8271
8441
  // src/internal/memory/adapters/openrouter-embedding.ts
8272
8442
  var DEFAULT_OPENROUTER_EMBEDDING_MODEL = "openai/text-embedding-3-small";
8273
8443
  var DIMENSION_BY_MODEL9 = {
@@ -8528,10 +8698,7 @@ var LocalAgentMemory = class {
8528
8698
  return this.toolsCache;
8529
8699
  } catch (cause) {
8530
8700
  const message = cause instanceof Error ? cause.message : String(cause);
8531
- const g = globalThis;
8532
- const sym = /* @__PURE__ */ Symbol.for("theokit-sdk.memory.warned");
8533
- g[sym] ??= /* @__PURE__ */ new Set();
8534
- const warned2 = g[sym];
8701
+ const warned2 = globalSingleton("theokit-sdk.memory.warned", () => /* @__PURE__ */ new Set());
8535
8702
  if (!warned2.has(message)) {
8536
8703
  warned2.add(message);
8537
8704
  diag(`[theokit-sdk] memory tools unavailable: ${message}
@@ -8622,111 +8789,6 @@ var LocalAgentMemory = class {
8622
8789
  }
8623
8790
  };
8624
8791
 
8625
- // src/internal/local-agent/local-agent-memory-direct.ts
8626
- async function createAvailableAdapters(entries, workspaceCwd) {
8627
- const available = [];
8628
- for (const entry of entries) {
8629
- const instance = await entry.createProvider(workspaceCwd);
8630
- if (instance.isAvailable() === false) {
8631
- diag(
8632
- `[theokit-sdk] memory adapter "${instance.id}" reports itself unavailable (plugin "${entry.pluginName}") \u2014 skipping it. Check its credentials.
8633
- `
8634
- );
8635
- continue;
8636
- }
8637
- available.push(instance);
8638
- }
8639
- return available;
8640
- }
8641
- function buildAgentMemory(pluginManager, workspaceCwd, defaultContext) {
8642
- let resolved;
8643
- async function ensure() {
8644
- if (resolved !== void 0) return resolved;
8645
- const entries = pluginManager.aggregated.memoryProviders;
8646
- const created = await createAvailableAdapters(entries, workspaceCwd);
8647
- for (const adapter of created) {
8648
- if (adapter.initialize !== void 0) {
8649
- await adapter.initialize();
8650
- }
8651
- }
8652
- resolved = { adapters: created, initialized: true, registered: entries.length };
8653
- return resolved;
8654
- }
8655
- function mergeContext(partial) {
8656
- const merged = {
8657
- userId: partial?.userId ?? defaultContext?.userId ?? "",
8658
- ...partial?.agentId !== void 0 ? { agentId: partial.agentId } : defaultContext?.agentId !== void 0 ? { agentId: defaultContext.agentId } : {},
8659
- ...partial?.sessionId !== void 0 ? { sessionId: partial.sessionId } : defaultContext?.sessionId !== void 0 ? { sessionId: defaultContext.sessionId } : {},
8660
- ...partial?.tenantId !== void 0 ? { tenantId: partial.tenantId } : defaultContext?.tenantId !== void 0 ? { tenantId: defaultContext.tenantId } : {},
8661
- ...partial?.tags !== void 0 ? { tags: partial.tags } : defaultContext?.tags !== void 0 ? { tags: defaultContext.tags } : {},
8662
- ...partial?.metadata !== void 0 ? { metadata: partial.metadata } : defaultContext?.metadata !== void 0 ? { metadata: defaultContext.metadata } : {}
8663
- };
8664
- if (merged.userId === "") {
8665
- throw new ConfigurationError(
8666
- "agent.memory requires a userId \u2014 either set AgentOptions.memoryContext.userId or pass ctx.userId at call time.",
8667
- { code: "memory_context_missing_user_id" }
8668
- );
8669
- }
8670
- return merged;
8671
- }
8672
- async function requireAdapters() {
8673
- const r = await ensure();
8674
- if (r.adapters.length === 0) {
8675
- throw new ConfigurationError(
8676
- r.registered === 0 ? "No memory adapter registered. Pass a memory plugin in AgentOptions.plugins (e.g. supermemoryMemory({...}))." : `All ${r.registered} registered memory adapter(s) reported themselves unavailable \u2014 see the warnings naming each one. Check their credentials.`,
8677
- { code: "no_memory_adapter" }
8678
- );
8679
- }
8680
- return r.adapters;
8681
- }
8682
- return {
8683
- async write(content, ctx) {
8684
- const adapters = await requireAdapters();
8685
- const merged = mergeContext(ctx);
8686
- const writes = await Promise.allSettled(adapters.map((a) => a.write(content, merged)));
8687
- const firstFulfilled = writes.find((r) => r.status === "fulfilled");
8688
- if (firstFulfilled === void 0) {
8689
- const firstReason = writes[0];
8690
- throw firstReason.reason;
8691
- }
8692
- return firstFulfilled.value;
8693
- },
8694
- // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: settled-promise iteration + content dedupe + graceful degrade are 3 inline concerns; helpers would obscure the merge invariant.
8695
- async recall(query, ctx, k) {
8696
- const adapters = await requireAdapters();
8697
- const merged = mergeContext(ctx);
8698
- const recalls = await Promise.allSettled(adapters.map((a) => a.recall(query, merged, k)));
8699
- const out = [];
8700
- const seen = /* @__PURE__ */ new Set();
8701
- for (const r of recalls) {
8702
- if (r.status !== "fulfilled") continue;
8703
- for (const fact of r.value) {
8704
- if (seen.has(fact.content)) continue;
8705
- seen.add(fact.content);
8706
- out.push(fact);
8707
- }
8708
- }
8709
- return out;
8710
- },
8711
- async delete(id) {
8712
- const adapters = await requireAdapters();
8713
- const prefix = id.split(":", 1)[0] ?? "";
8714
- const target = adapters.find((a) => a.id === prefix);
8715
- if (target === void 0) {
8716
- throw new ConfigurationError(
8717
- `No adapter found for MemoryId prefix "${prefix}" (registered: ${adapters.map((a) => a.id).join(", ")}).`,
8718
- { code: "no_memory_adapter" }
8719
- );
8720
- }
8721
- await target.delete(id);
8722
- },
8723
- adapter() {
8724
- if (resolved === void 0) return null;
8725
- return resolved.adapters[0] ?? null;
8726
- }
8727
- };
8728
- }
8729
-
8730
8792
  // src/internal/local-agent/local-agent-memory-provider.ts
8731
8793
  var INTERNAL_LAM_KEY = /* @__PURE__ */ Symbol("sdk-core.local-agent-memory-provider.glue");
8732
8794
  function createLocalAgentMemoryProvider(opts) {
@@ -8945,29 +9007,27 @@ function applyPersonalityOverlay(preset, base) {
8945
9007
 
8946
9008
  ${preset.systemPrompt}`;
8947
9009
  }
8948
- async function localAgentUsePersonality(args) {
8949
- if (args.disposed) throw new Error("Agent has been disposed");
9010
+ async function localAgentUsePersonality(agent, name, opts) {
8950
9011
  if (currentPersonalityContext() !== void 0) {
8951
- warnPersonalitySwitchInsideFork(args.agentId);
9012
+ warnPersonalitySwitchInsideFork(agent.agentId);
8952
9013
  return null;
8953
9014
  }
8954
- let registry = args.personalityRegistry;
8955
- if (registry === void 0) {
8956
- registry = await PersonalityRegistry.load(args.workspaceCwd);
8957
- args.onRegistryLoaded(registry);
9015
+ if (agent.personalityRegistry === void 0) {
9016
+ agent.personalityRegistry = await PersonalityRegistry.load(agent.workspaceCwd);
8958
9017
  }
9018
+ const registry = agent.personalityRegistry;
8959
9019
  return withCwdMutex(
8960
- `agent-send:${args.agentId}`,
9020
+ `agent-send:${agent.agentId}`,
8961
9021
  () => performPersonalitySwitch({
8962
- agentId: args.agentId,
8963
- prevSlug: args.personalityStore.active(args.agentId),
8964
- requestedName: args.name,
9022
+ agentId: agent.agentId,
9023
+ prevSlug: agent.personalityStore.active(agent.agentId),
9024
+ requestedName: name,
8965
9025
  registry,
8966
- store: args.personalityStore,
8967
- invalidateCache: (reason) => args.invalidateCache(reason),
8968
- appendSessionMessage: (msg) => appendSessionMessage(args.agentId, msg),
8969
- clearSession: () => clearSession(args.agentId),
8970
- opts: args.opts ?? {}
9026
+ store: agent.personalityStore,
9027
+ invalidateCache: (reason) => agent.invalidateCache(reason),
9028
+ appendSessionMessage: (msg) => appendSessionMessage(agent.agentId, msg),
9029
+ clearSession: () => clearSession(agent.agentId),
9030
+ opts: opts ?? {}
8971
9031
  })
8972
9032
  );
8973
9033
  }
@@ -8975,9 +9035,9 @@ async function localAgentUsePersonality(args) {
8975
9035
  // src/internal/local-agent/local-agent-runtime-extensions.ts
8976
9036
  function localAgentRunUntil(agent, goal, options) {
8977
9037
  async function* wrap() {
8978
- const { runUntilImpl } = await import('./run-until-HEQOUVU6.js');
9038
+ const { runUntilImpl } = await import('./run-until-6D6TQ4JN.js');
8979
9039
  const buildDeps = async () => {
8980
- const { judgeCallImpl } = await import('./judge-call-LVXABPS3.js');
9040
+ const { judgeCallImpl } = await import('./judge-call-6MVARKU2.js');
8981
9041
  const { getAgentFacade } = await import('./agent-factory-registry-ZVTABLEY.js');
8982
9042
  const create = getAgentFacade().create;
8983
9043
  return {
@@ -9008,9 +9068,9 @@ async function* localAgentStreamToCompletion(agent, message, options) {
9008
9068
  return yield* streamToCompletionImpl({ send: (m, o) => agent.send(m, o) }, message, options);
9009
9069
  }
9010
9070
  async function localAgentFork(parent, options) {
9011
- const { forkAgentImpl } = await import('./fork-agent-RSV4E3EA.js');
9071
+ const { forkAgentImpl } = await import('./fork-agent-S2EPIML7.js');
9012
9072
  const { getAgentFacade } = await import('./agent-factory-registry-ZVTABLEY.js');
9013
- const { withPersonalityContext } = await import('./context-GQRFBCLP.js');
9073
+ const { withPersonalityContext } = await import('./context-NZ2AC6S7.js');
9014
9074
  const create = getAgentFacade().create;
9015
9075
  return withPersonalityContext(
9016
9076
  { slug: parent.personalitySlugSnapshot, isFork: true },
@@ -9039,7 +9099,7 @@ async function persistMemoryFactIfWritePrompt(workspaceCwd, memoryConfig, userTe
9039
9099
  }
9040
9100
  }
9041
9101
 
9042
- // src/internal/runtime/concurrency/abort-utils.ts
9102
+ // src/internal/concurrency/abort-utils.ts
9043
9103
  function anySignal(signals) {
9044
9104
  const filtered = signals.filter((s) => s !== void 0);
9045
9105
  if (filtered.length === 0) {
@@ -9103,7 +9163,7 @@ function wrapRunWithCompletionCheck(args) {
9103
9163
  });
9104
9164
  }
9105
9165
 
9106
- // src/internal/runtime/memory/select-facts.ts
9166
+ // src/internal/runtime/memory-glue/select-facts.ts
9107
9167
  var DEFAULT_MAX_ENTRIES = 10;
9108
9168
  var CHARS_PER_TOKEN = 3.7;
9109
9169
  var DEFAULT_MAX_TOKENS = 15e3;
@@ -9505,7 +9565,12 @@ async function applyInputProcessors(inputs, message, rawUserText, options, sendM
9505
9565
  }
9506
9566
  async function executeSendLocked(inputs, message, options) {
9507
9567
  if (inputs.disposed) throw new AgentDisposedError(inputs.agentId);
9508
- await consumePending(inputs.agentId, inputs.invalidationPending, inputs.clearInvalidation, inputs.reload);
9568
+ await consumePending(
9569
+ inputs.agentId,
9570
+ inputs.invalidationPending,
9571
+ inputs.clearInvalidation,
9572
+ inputs.reload
9573
+ );
9509
9574
  const sendModel = normalizeModel(options.model);
9510
9575
  inputs.applyModelOverride(sendModel);
9511
9576
  const rawUserText = typeof message === "string" ? message : message.text;
@@ -9531,37 +9596,30 @@ async function executeSendLocked(inputs, message, options) {
9531
9596
  appendSessionMessage(inputs.agentId, { role: "user", text: userText });
9532
9597
  await persistMemoryFactIfWritePrompt(inputs.workspaceCwd, inputs.options.memory, userText);
9533
9598
  const memoryFacts = await readMemoryForSend(inputs.workspaceCwd, inputs.options.memory, userText);
9534
- const portPathActive = shouldUsePortMemoryPath();
9535
- const legacyTools = portPathActive ? void 0 : await inputs.memoryGlue.ensureTools();
9536
- const legacySummary = portPathActive ? void 0 : await inputs.memoryGlue.runActiveMemoryIfEnabled(userText, priorMessages, inputs.telemetry);
9537
- const memoryTools = resolveMemoryToolsForLoop(legacyTools, portPathActive);
9538
- const activeMemorySummary = resolveActiveMemorySummaryForSend(legacySummary, portPathActive);
9539
- const effectiveMemoryProvider = resolveMemoryProviderForLoop(
9540
- inputs.options.memoryProvider,
9541
- inputs.defaultMemoryProviderForLoop,
9542
- portPathActive
9543
- );
9599
+ const memoryTools = void 0;
9600
+ const activeMemorySummary = void 0;
9601
+ const effectiveMemoryProvider = inputs.options.memoryProvider ?? inputs.defaultMemoryProviderForLoop;
9544
9602
  const baseSystemPrompt = await inputs.resolveSystemPromptForSend(userText, options, memoryFacts);
9545
- const assembledSystemPrompt = await inputs.assembleSystemPromptForSend(
9603
+ const assembledSystemPrompt = await inputs.assembleSystemPromptForSend({
9546
9604
  userText,
9547
9605
  baseSystemPrompt,
9548
9606
  memoryFacts,
9549
9607
  activeMemorySummary,
9550
- options.contextPaths
9551
- );
9608
+ contextPaths: options.contextPaths
9609
+ });
9552
9610
  const composedOptions = {
9553
9611
  ...options,
9554
9612
  signal: anySignal([options.signal, inputs.lifecycleAbortController.signal])
9555
9613
  };
9556
- const run = await inputs.dispatchRun(
9557
- adaptedMessage,
9558
- composedOptions,
9559
- assembledSystemPrompt,
9614
+ const run = await inputs.dispatchRun({
9615
+ message: adaptedMessage,
9616
+ options: composedOptions,
9617
+ systemPrompt: assembledSystemPrompt,
9560
9618
  memoryFacts,
9561
9619
  priorMessages,
9562
9620
  memoryTools,
9563
- effectiveMemoryProvider
9564
- );
9621
+ memoryProviderOverride: effectiveMemoryProvider
9622
+ });
9565
9623
  const outputProcessors = inputs.options.outputProcessors;
9566
9624
  const processedRun = outputProcessors !== void 0 && outputProcessors.length > 0 ? wrapRunWithOutputProcessors({
9567
9625
  run,
@@ -9586,7 +9644,7 @@ async function executeSendLocked(inputs, message, options) {
9586
9644
  function buildCompletionCheckDeps() {
9587
9645
  return {
9588
9646
  judge: async (ctx, opts) => {
9589
- const { judgeCallImpl } = await import('./judge-call-LVXABPS3.js');
9647
+ const { judgeCallImpl } = await import('./judge-call-6MVARKU2.js');
9590
9648
  const { getAgentFacade } = await import('./agent-factory-registry-ZVTABLEY.js');
9591
9649
  return judgeCallImpl(ctx, opts, { create: getAgentFacade().create });
9592
9650
  }
@@ -9649,8 +9707,77 @@ function registerRunAsTask(run, agentId, taskOpt, userText) {
9649
9707
  });
9650
9708
  }
9651
9709
 
9710
+ // src/internal/local-agent/local-option-keys.ts
9711
+ var KNOWN_LOCAL_OPTION_KEYS = /* @__PURE__ */ new Set([
9712
+ "cwd",
9713
+ "settingSources",
9714
+ "compatSources",
9715
+ "sandboxOptions",
9716
+ "sessionDir",
9717
+ "baseDir",
9718
+ "sessionStore"
9719
+ ]);
9720
+ var reported = /* @__PURE__ */ new Set();
9721
+ function distance(a, b) {
9722
+ let previous = Array.from({ length: b.length + 1 }, (_, j) => j);
9723
+ for (let i = 1; i <= a.length; i++) {
9724
+ const current = [i, ...new Array(b.length).fill(0)];
9725
+ for (let j = 1; j <= b.length; j++) {
9726
+ const cost = a.charAt(i - 1) === b.charAt(j - 1) ? 0 : 1;
9727
+ current[j] = Math.min(
9728
+ (previous[j] ?? 0) + 1,
9729
+ (current[j - 1] ?? 0) + 1,
9730
+ (previous[j - 1] ?? 0) + cost
9731
+ );
9732
+ }
9733
+ previous = current;
9734
+ }
9735
+ return previous[b.length] ?? 0;
9736
+ }
9737
+ function nearest(key) {
9738
+ let best;
9739
+ let bestDistance = 4;
9740
+ for (const known of KNOWN_LOCAL_OPTION_KEYS) {
9741
+ const d = distance(key.toLowerCase(), known.toLowerCase());
9742
+ if (d < bestDistance) {
9743
+ bestDistance = d;
9744
+ best = known;
9745
+ }
9746
+ }
9747
+ return best;
9748
+ }
9749
+ function reportUnknownLocalOptions(local) {
9750
+ if (local === void 0) return;
9751
+ for (const key of Object.keys(local)) {
9752
+ if (KNOWN_LOCAL_OPTION_KEYS.has(key)) continue;
9753
+ if (reported.has(key)) continue;
9754
+ reported.add(key);
9755
+ const guess = nearest(key);
9756
+ const hint = guess === void 0 ? "" : ` Did you mean \`${guess}\`?`;
9757
+ diag(
9758
+ `[theokit] \`local.${key}\` is not an option this SDK version knows, so it was ignored.${hint}
9759
+ `
9760
+ );
9761
+ }
9762
+ }
9763
+
9652
9764
  // src/internal/local-agent/local-agent.ts
9653
9765
  var LocalAgent = class {
9766
+ /**
9767
+ * Operations this runtime does not perform. See {@link SDKAgent.supports} for why asking beats
9768
+ * catching: the members below are present on the type — `downloadArtifact` is REQUIRED — and
9769
+ * answering them by throwing is what leaves a caller unable to branch without a try/catch.
9770
+ *
9771
+ * Artifacts are a cloud concept: `downloadArtifact` rejects unconditionally here, and
9772
+ * `listArtifacts` returns `[]` for every state, so its empty array cannot be read as "this run
9773
+ * produced none".
9774
+ */
9775
+ supports(operation) {
9776
+ return localAgentCapabilities.supports(operation);
9777
+ }
9778
+ unsupportedReason(operation) {
9779
+ return localAgentCapabilities.unsupportedReason(operation);
9780
+ }
9654
9781
  agentId;
9655
9782
  model;
9656
9783
  context;
@@ -9687,14 +9814,14 @@ var LocalAgent = class {
9687
9814
  pluginsManager;
9688
9815
  hooksExecutor;
9689
9816
  systemPromptPipeline = SystemPromptPipeline.default();
9690
- memoryGlue;
9691
9817
  /**
9692
- * SDK 2.0 Phase 1 physical Stage 2biter 19+: pre-built adapter
9693
- * wrapping `memoryGlue` as a MemoryProvider impl. Constructed eagerly
9694
- * so future iters can flip `inputs.memoryProvider` to default to
9695
- * THIS adapter when consumer didn't supply one. NOT YET used by
9696
- * `send()` the kernel flip lands in Stage 2b proper after equivalence
9697
- * regression coverage.
9818
+ * The agent's memory, behind the `MemoryProvider` portthe only memory path since the kernel
9819
+ * flip (2026-09-02). A consumer-supplied `options.memoryProvider` takes precedence; this is what
9820
+ * runs otherwise.
9821
+ *
9822
+ * It used to be built ALONGSIDE a `LocalAgentMemory` this class held directly, "so future iters
9823
+ * can flip", while `send()` used the direct one. The adapter constructs its own `LocalAgentMemory`
9824
+ * inside `init()`, so that arrangement kept two of them per agent and the second was never read.
9698
9825
  *
9699
9826
  * Accessible to tests via `_defaultMemoryProviderForLoop()` helper.
9700
9827
  * @internal
@@ -9703,6 +9830,10 @@ var LocalAgent = class {
9703
9830
  /** T4.1 — PluginManager for code plugins (kind: general/model-provider/memory). @internal */
9704
9831
  pluginManagerCode = new PluginManager();
9705
9832
  /** Personality presets — lazy-loaded on first `usePersonality` call (ADRs D160-D164). @internal */
9833
+ // Not private: `local-agent-personality-extensions.ts` reads both through
9834
+ // `LocalAgentPersonalityTarget`, the same way `local-agent-lifecycle.ts` reads `sessionStore` and
9835
+ // `lifecycleAbortController` above. A field a sibling module needs is part of this class's
9836
+ // implementation surface, and saying so beats handing it over as a closure.
9706
9837
  personalityRegistry;
9707
9838
  personalityStore;
9708
9839
  /** T0.1 — telemetry handle shared with sendLocked + memory recall path. */
@@ -9729,8 +9860,10 @@ var LocalAgent = class {
9729
9860
  if (sub.skills !== void 0) this.skills = sub.skills;
9730
9861
  this.pluginsManager = sub.pluginsManager;
9731
9862
  if (sub.plugins !== void 0) this.plugins = sub.plugins;
9732
- this.hooksExecutor = new HooksExecutor(this.workspaceCwd);
9733
- this.memoryGlue = new LocalAgentMemory(options, this.workspaceCwd, this.agentId);
9863
+ reportUnknownLocalOptions(options.local);
9864
+ const compatSources = options.local?.compatSources ?? [];
9865
+ reportUndeclaredSources(this.workspaceCwd, compatSources);
9866
+ this.hooksExecutor = new HooksExecutor(this.workspaceCwd, compatSources);
9734
9867
  this.defaultMemoryProviderForLoop = createLocalAgentMemoryProvider({
9735
9868
  agentOptions: options,
9736
9869
  workspaceCwd: this.workspaceCwd,
@@ -9760,7 +9893,8 @@ var LocalAgent = class {
9760
9893
  this.resolvedSubagents = await loadSubagents(
9761
9894
  this.workspaceCwd,
9762
9895
  this.settingSourcesIncludeProject,
9763
- this.options.agents
9896
+ this.options.agents,
9897
+ this.options.local?.compatSources ?? []
9764
9898
  );
9765
9899
  await acquireLeaseIfPossible(this.sessionStore, this.agentId);
9766
9900
  try {
@@ -9826,11 +9960,6 @@ var LocalAgent = class {
9826
9960
  if (options.task !== void 0) registerRunAsTask(run, this.agentId, options.task, userText);
9827
9961
  resolve(run);
9828
9962
  try {
9829
- const postRunProvider = resolveMemoryProviderForLoop(
9830
- this.options.memoryProvider,
9831
- this.defaultMemoryProviderForLoop,
9832
- shouldUsePortMemoryPath()
9833
- );
9834
9963
  await runPostRunLifecycle({
9835
9964
  run,
9836
9965
  userText,
@@ -9843,10 +9972,13 @@ var LocalAgent = class {
9843
9972
  ...this.options.apiKey !== void 0 ? { apiKey: this.options.apiKey } : {},
9844
9973
  ...options.onRunEvent !== void 0 ? { onRunEvent: options.onRunEvent } : {},
9845
9974
  hooksExecutor: this.hooksExecutor,
9846
- memoryGlue: this.memoryGlue,
9847
9975
  // usetheokit/theokit-sdk#382 — the transcript write reads this and nothing else.
9848
9976
  memory: this.options.memory,
9849
- ...postRunProvider !== void 0 ? { memoryProvider: postRunProvider } : {}
9977
+ // A consumer-supplied provider wins; otherwise the auto-installed adapter over
9978
+ // `LocalAgentMemory`. Since the kernel flip there is no third case, so this is passed
9979
+ // unconditionally — the `!== undefined` spread that used to guard it could not be false,
9980
+ // and `recordSessionSummary` is now always reached through the port.
9981
+ memoryProvider: this.options.memoryProvider ?? this.defaultMemoryProviderForLoop
9850
9982
  });
9851
9983
  } finally {
9852
9984
  sendSpan.end();
@@ -9865,24 +9997,30 @@ var LocalAgent = class {
9865
9997
  applyModelOverride: (m) => this.applyModelOverride(m),
9866
9998
  options: this.options,
9867
9999
  pluginManagerCode: this.pluginManagerCode,
9868
- memoryGlue: this.memoryGlue,
9869
10000
  defaultMemoryProviderForLoop: this.defaultMemoryProviderForLoop,
9870
10001
  workspaceCwd: this.workspaceCwd,
9871
10002
  telemetry: this._telemetry,
9872
10003
  lifecycleAbortController: this.lifecycleAbortController,
9873
10004
  runPreHook: (ut) => this.runPreHook(ut),
9874
- // biome-ignore format: G8 budget — callbacks wire to private methods.
9875
10005
  resolveSystemPromptForSend: (ut, o, mf) => this.resolveSystemPrompt(ut, o, mf),
9876
- assembleSystemPromptForSend: (ut, bp, mf, ams, cp) => assembleSystemPromptForSend(this.assemblyInputs(), ut, bp, mf, ams, cp),
9877
- dispatchRun: (msg, o, sp, mf, pm, mt, mp) => this.dispatchRun(msg, o, sp, mf, pm, mt, mp)
10006
+ assembleSystemPromptForSend: (request) => assembleSystemPromptForSend({ ...request, inputs: this.assemblyInputs() }),
10007
+ dispatchRun: (args) => this.dispatchRun(args)
9878
10008
  },
9879
10009
  message,
9880
10010
  options
9881
10011
  );
9882
10012
  }
9883
- // biome-ignore format: G8 budget — thin accessor for the assembly inputs.
9884
10013
  assemblyInputs() {
9885
- return { agentId: this.agentId, workspaceCwd: this.workspaceCwd, model: this.model, options: this.options, context: this.context, skillsManager: this.skillsManager, settingSourcesIncludeProject: this.settingSourcesIncludeProject, systemPromptPipeline: this.systemPromptPipeline };
10014
+ return {
10015
+ agentId: this.agentId,
10016
+ workspaceCwd: this.workspaceCwd,
10017
+ model: this.model,
10018
+ options: this.options,
10019
+ context: this.context,
10020
+ skillsManager: this.skillsManager,
10021
+ settingSourcesIncludeProject: this.settingSourcesIncludeProject,
10022
+ systemPromptPipeline: this.systemPromptPipeline
10023
+ };
9886
10024
  }
9887
10025
  async resolveSystemPrompt(userText, options, memoryFacts) {
9888
10026
  const base = await resolveSystemPromptForSend(
@@ -9899,9 +10037,12 @@ var LocalAgent = class {
9899
10037
  return applyPersonalityOverlay(this.activePreset(), base);
9900
10038
  }
9901
10039
  /** @internal — read-only personality lookup (composes the helper, honors fork ALS). */
9902
- // biome-ignore format: keep one-liner so the personality lookup stays under G8.
9903
10040
  activePreset() {
9904
- return resolveActivePersonalityPreset({ agentId: this.agentId, personalityStore: this.personalityStore, personalityRegistry: this.personalityRegistry });
10041
+ return resolveActivePersonalityPreset({
10042
+ agentId: this.agentId,
10043
+ personalityStore: this.personalityStore,
10044
+ personalityRegistry: this.personalityRegistry
10045
+ });
9905
10046
  }
9906
10047
  applyModelOverride(overrideModel) {
9907
10048
  if (overrideModel === void 0) return;
@@ -9921,7 +10062,15 @@ var LocalAgent = class {
9921
10062
  );
9922
10063
  }
9923
10064
  }
9924
- dispatchRun(message, options, systemPrompt, memoryFacts, priorMessages, memoryTools, memoryProviderOverride) {
10065
+ dispatchRun({
10066
+ message,
10067
+ options,
10068
+ systemPrompt,
10069
+ memoryFacts,
10070
+ priorMessages,
10071
+ memoryTools,
10072
+ memoryProviderOverride
10073
+ }) {
9925
10074
  const effectiveAgentOptions = memoryProviderOverride !== void 0 && this.options.memoryProvider === void 0 ? { ...this.options, memoryProvider: memoryProviderOverride } : this.options;
9926
10075
  return dispatchLocalRun({
9927
10076
  inputs: {
@@ -9957,11 +10106,17 @@ var LocalAgent = class {
9957
10106
  [Symbol.asyncDispose]() {
9958
10107
  return this.dispose();
9959
10108
  }
9960
- // biome-ignore format: multi-line layout would push file past G8 LoC cap.
9961
10109
  /** T3.2 / ADR D94 — public `invalidateCache` API. @internal */
9962
- invalidateCache = (reason, opts = {}) => invalidateCacheImpl(this.agentId, reason, opts, this.disposed, () => this.dispose(), (p) => {
9963
- this.invalidationPending = p;
9964
- });
10110
+ invalidateCache = (reason, opts = {}) => invalidateCacheImpl(
10111
+ this.agentId,
10112
+ reason,
10113
+ opts,
10114
+ this.disposed,
10115
+ () => this.dispose(),
10116
+ (p) => {
10117
+ this.invalidationPending = p;
10118
+ }
10119
+ );
9965
10120
  /**
9966
10121
  * Activate a personality preset (Hermes #26, ADRs D160-D164).
9967
10122
  *
@@ -9976,41 +10131,33 @@ var LocalAgent = class {
9976
10131
  * @public
9977
10132
  */
9978
10133
  usePersonality(name, opts) {
9979
- return localAgentUsePersonality({
9980
- agentId: this.agentId,
9981
- workspaceCwd: this.workspaceCwd,
9982
- disposed: this.disposed,
9983
- personalityStore: this.personalityStore,
9984
- personalityRegistry: this.personalityRegistry,
9985
- invalidateCache: (reason) => this.invalidateCache(reason),
9986
- onRegistryLoaded: (reg) => {
9987
- this.personalityRegistry = reg;
9988
- },
9989
- name,
9990
- ...opts !== void 0 ? { opts } : {}
9991
- });
10134
+ if (this.disposed) throw new Error("Agent has been disposed");
10135
+ return localAgentUsePersonality(this, name, opts);
9992
10136
  }
9993
- // biome-ignore format: G8 budget artifact stubs (local agents have no artifacts); kept 1-line each.
10137
+ // The two operations `local-agent-capabilities.ts` is ABOUT: their runtime answers live beside the
10138
+ // static answer `supports()` gives, so a change to one cannot drift from the other.
9994
10139
  listArtifacts() {
9995
- return Promise.resolve([]);
10140
+ return localAgentCapabilities.listArtifacts();
9996
10141
  }
9997
- // biome-ignore format: G8 budget — see listArtifacts.
9998
10142
  downloadArtifact(_path) {
9999
- return Promise.reject(new UnsupportedRunOperationError("Artifacts are not supported for local agents", "downloadArtifact"));
10143
+ return localAgentCapabilities.downloadArtifact();
10000
10144
  }
10001
- // biome-ignore format: G8 budget — delegates to `local-agent-runtime-extensions.ts`; kept 1-line.
10002
10145
  runUntil(goal, options) {
10003
10146
  return localAgentRunUntil(this, goal, options);
10004
10147
  }
10005
- // biome-ignore format: G8 budget — see runUntil comment above.
10006
10148
  fork(options) {
10007
- return localAgentFork({ agentId: this.agentId, options: this.options, personalitySlugSnapshot: this.personalityStore.active(this.agentId) }, options);
10149
+ return localAgentFork(
10150
+ {
10151
+ agentId: this.agentId,
10152
+ options: this.options,
10153
+ personalitySlugSnapshot: this.personalityStore.active(this.agentId)
10154
+ },
10155
+ options
10156
+ );
10008
10157
  }
10009
- // biome-ignore format: G8 budget — see runUntil comment above.
10010
10158
  runToCompletion(message, options) {
10011
10159
  return localAgentRunToCompletion(this, message, options);
10012
10160
  }
10013
- // biome-ignore format: G8 budget — see runUntil comment above.
10014
10161
  streamToCompletion(message, options) {
10015
10162
  return localAgentStreamToCompletion(this, message, options);
10016
10163
  }
@@ -10023,7 +10170,7 @@ function includesSetting(options, source) {
10023
10170
  return sources !== void 0 && (sources.includes(source) || sources.includes("all"));
10024
10171
  }
10025
10172
 
10026
- // src/agent-helpers.ts
10173
+ // src/internal/agent/helpers.ts
10027
10174
  async function runCreateUnderSpan(options, span) {
10028
10175
  options = { ...options, model: normalizeModel(options.model) };
10029
10176
  validateAgentOptions(options);
@@ -10197,17 +10344,21 @@ async function validateRehydratedAgent(agentId, entry) {
10197
10344
  if (entry.runtime !== "local") return;
10198
10345
  const candidate = entry.options.local?.cwd ?? entry.cwd;
10199
10346
  if (typeof candidate !== "string") return;
10347
+ let info;
10200
10348
  try {
10201
- const info = await stat(candidate);
10202
- if (!info.isDirectory()) {
10203
- throw new Error(`Workspace path is not a directory: ${candidate}`);
10204
- }
10349
+ info = await stat(candidate);
10205
10350
  } catch (cause) {
10206
10351
  throw new UnknownAgentError(
10207
10352
  `Agent "${agentId}" cannot be rehydrated \u2014 workspace cwd "${candidate}" is missing or inaccessible.`,
10208
10353
  { code: "agent_rehydration_failed", cause }
10209
10354
  );
10210
10355
  }
10356
+ if (!info.isDirectory()) {
10357
+ throw new UnknownAgentError(
10358
+ `Agent "${agentId}" cannot be rehydrated \u2014 workspace cwd "${candidate}" exists but is not a directory.`,
10359
+ { code: "agent_rehydration_failed" }
10360
+ );
10361
+ }
10211
10362
  }
10212
10363
  function toAgentInfo(agent) {
10213
10364
  return isLocalAgentId(agent.agentId) ? toLocalAgentInfo(agent) : toCloudAgentInfo(agent);
@@ -10414,7 +10565,7 @@ var Agent = class _Agent {
10414
10565
  * @public
10415
10566
  */
10416
10567
  static async generateObject(options) {
10417
- const { generateObjectImpl } = await import('./generate-object-GUNAUVBX.js');
10568
+ const { generateObjectImpl } = await import('./generate-object-BXV7BZRP.js');
10418
10569
  return generateObjectImpl(options, {
10419
10570
  create: (opts) => _Agent.create(opts),
10420
10571
  delete: (agentId) => _Agent.delete(agentId)
@@ -10438,7 +10589,7 @@ var Agent = class _Agent {
10438
10589
  delete: (agentId) => _Agent.delete(agentId)
10439
10590
  };
10440
10591
  async function* wrapper() {
10441
- streamObjectImport ??= import('./stream-object-UF4QRQRU.js');
10592
+ streamObjectImport ??= import('./stream-object-HBFMIZLD.js');
10442
10593
  const { streamObjectImpl } = await streamObjectImport;
10443
10594
  yield* streamObjectImpl(options, deps);
10444
10595
  }
@@ -10462,7 +10613,7 @@ var Agent = class _Agent {
10462
10613
  * @public
10463
10614
  */
10464
10615
  static async batch(prompts, options) {
10465
- const { batchImpl } = await import('./batch-L4ZXS46M.js');
10616
+ const { batchImpl } = await import('./batch-US4F6WPK.js');
10466
10617
  return batchImpl(prompts, options, { create: (opts) => _Agent.create(opts) });
10467
10618
  }
10468
10619
  /**
@@ -10486,7 +10637,7 @@ var Agent = class _Agent {
10486
10637
  *
10487
10638
  * This bullet used to say the opposite ("Disposed agents are NOT auto-deleted...
10488
10639
  * call `Agent.delete(agentId)` first"). It was measured false in M91:
10489
- * `tests/m91-getorcreate-after-dispose.test.ts` builds an agent, disposes it, and
10640
+ * `tests/agent-getorcreate-after-dispose.test.ts` builds an agent, disposes it, and
10490
10641
  * gets a different instance back. The claim was about the PERSISTENT registry and
10491
10642
  * read as being about the live cache — and consumers built around the wrong half.
10492
10643
  * The agent-builder's M85 interrupt rotates the session id to work around a
@@ -10613,17 +10764,8 @@ var Agent = class _Agent {
10613
10764
  * @public
10614
10765
  */
10615
10766
  static async compact(agentId, options = {}) {
10616
- let reg = getRegisteredAgent(agentId);
10617
- if (reg === void 0) {
10618
- await hydrateRegistryFromDisk(process.cwd());
10619
- reg = getRegisteredAgent(agentId);
10620
- }
10621
- if (reg === void 0 || reg.runtime !== "local") {
10622
- throw new UnknownAgentError(
10623
- `No local agent "${agentId}" registered \u2014 compact targets local sessions.`
10624
- );
10625
- }
10626
- const { compactSessionTranscript, buildDefaultSummarizer: buildDefaultSummarizer2 } = await import('./compact-session-RIGOWC4Y.js');
10767
+ const reg = await requireLocalAgent(agentId, "compact");
10768
+ const { compactSessionTranscript, buildDefaultSummarizer: buildDefaultSummarizer2 } = await import('./compact-session-W4WLJTHA.js');
10627
10769
  const { cwd, model, store } = await openLocalStore(reg);
10628
10770
  return enqueueSessionWrite(
10629
10771
  cwd,
@@ -10649,17 +10791,8 @@ var Agent = class _Agent {
10649
10791
  * @public
10650
10792
  */
10651
10793
  static async injectSessionTurn(agentId, turn) {
10652
- let reg = getRegisteredAgent(agentId);
10653
- if (reg === void 0) {
10654
- await hydrateRegistryFromDisk(process.cwd());
10655
- reg = getRegisteredAgent(agentId);
10656
- }
10657
- if (reg === void 0 || reg.runtime !== "local") {
10658
- throw new UnknownAgentError(
10659
- `No local agent "${agentId}" registered \u2014 injectSessionTurn targets local sessions.`
10660
- );
10661
- }
10662
- const { injectSessionTurn } = await import('./inject-session-DAR7OUCW.js');
10794
+ const reg = await requireLocalAgent(agentId, "injectSessionTurn");
10795
+ const { injectSessionTurn } = await import('./inject-session-SUM6TDJF.js');
10663
10796
  const { cwd, model, store } = await openLocalStore(reg);
10664
10797
  await injectSessionTurn({
10665
10798
  store,
@@ -10688,17 +10821,8 @@ var Agent = class _Agent {
10688
10821
  * @public
10689
10822
  */
10690
10823
  static async transcript(agentId) {
10691
- let reg = getRegisteredAgent(agentId);
10692
- if (reg === void 0) {
10693
- await hydrateRegistryFromDisk(process.cwd());
10694
- reg = getRegisteredAgent(agentId);
10695
- }
10696
- if (reg === void 0 || reg.runtime !== "local") {
10697
- throw new UnknownAgentError(
10698
- `No local agent "${agentId}" registered \u2014 transcript targets local sessions.`
10699
- );
10700
- }
10701
- const { readSessionMessages } = await import('./agent-session-store-OPGRB4XM.js');
10824
+ const reg = await requireLocalAgent(agentId, "transcript");
10825
+ const { readSessionMessages } = await import('./agent-session-store-AFML3AXC.js');
10702
10826
  const { store } = await openLocalStore(reg);
10703
10827
  return readSessionMessages(store, agentId);
10704
10828
  }
@@ -10719,7 +10843,7 @@ var Agent = class _Agent {
10719
10843
  */
10720
10844
  static async describe(agentId) {
10721
10845
  const agent = await getRegisteredAgentOrThrow(agentId);
10722
- const { loadSubagents: loadSubagents2 } = await import('./subagents-loader-CRT5LLL3.js');
10846
+ const { loadSubagents: loadSubagents2 } = await import('./subagents-loader-LSKM2UIK.js');
10723
10847
  const settingSources = agent.options.local?.settingSources;
10724
10848
  const subagents = await loadSubagents2(
10725
10849
  agent.cwd ?? process.cwd(),
@@ -10782,17 +10906,30 @@ setAgentFacade({
10782
10906
  resume: (agentId, options) => Agent.resume(agentId, options),
10783
10907
  batch: (prompts, options) => Agent.batch(prompts, options)
10784
10908
  });
10909
+ async function requireLocalAgent(agentId, operation) {
10910
+ let reg = getRegisteredAgent(agentId);
10911
+ if (reg === void 0) {
10912
+ await hydrateRegistryFromDisk(process.cwd());
10913
+ reg = getRegisteredAgent(agentId);
10914
+ }
10915
+ if (reg === void 0 || reg.runtime !== "local") {
10916
+ throw new UnknownAgentError(
10917
+ `No local agent "${agentId}" registered \u2014 ${operation} targets local sessions.`
10918
+ );
10919
+ }
10920
+ return reg;
10921
+ }
10785
10922
  async function openLocalStore(reg) {
10786
10923
  const cwd = reg.cwd ?? process.cwd();
10787
10924
  const optModel = reg.options.model;
10788
10925
  const model = reg.model?.id ?? (typeof optModel === "string" ? optModel : optModel?.id) ?? "unknown";
10789
- const { FsSessionStore: FsSessionStore2 } = await import('./fs-session-store-NM6YSTE2.js');
10790
- const { defaultBaseDir: defaultBaseDir2, expandTilde: expandTilde2 } = await import('./session-transcript-XAEKW6P7.js');
10926
+ const { FsSessionStore: FsSessionStore2 } = await import('./fs-session-store-77JU46UZ.js');
10927
+ const { defaultBaseDir: defaultBaseDir2, expandTilde: expandTilde2 } = await import('./session-transcript-VTBTCGQX.js');
10791
10928
  const configuredSessionDir = reg.options.local?.sessionDir ?? reg.options.local?.baseDir;
10792
10929
  const baseDir = configuredSessionDir !== void 0 ? expandTilde2(configuredSessionDir) : defaultBaseDir2();
10793
10930
  return { cwd, model, store: new FsSessionStore2({ baseDir, cwd }) };
10794
10931
  }
10795
10932
 
10796
10933
  export { Agent, AgentBuilder, DEFAULT_AGENTIC_MODEL_ID, MEMORY_EMBEDDING_ADAPTERS, Tool, ToolError, UsageAccumulator, computeCost, generateCronId, getPricingEntry, openRouterMemoryEmbeddingProviderAdapter };
10797
- //# sourceMappingURL=chunk-25BD2R5G.js.map
10798
- //# sourceMappingURL=chunk-25BD2R5G.js.map
10934
+ //# sourceMappingURL=chunk-NCGWJ3HS.js.map
10935
+ //# sourceMappingURL=chunk-NCGWJ3HS.js.map