@theokit/sdk 4.63.4 → 5.0.0-next.2

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 (786) hide show
  1. package/CHANGELOG.md +847 -23
  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-X0DKA943.d.cts → agent-C3KO5LKm.d.cts} +251 -36
  13. package/dist/{agent-BFno7Sfn.d.ts → agent-CvmTR9uf.d.ts} +251 -36
  14. package/dist/agent-GPV2JWZG.cjs +67 -0
  15. package/dist/{agent-UX7WFI6B.cjs.map → agent-GPV2JWZG.cjs.map} +1 -1
  16. package/dist/agent-Y24I5JBM.js +58 -0
  17. package/dist/{agent-A5XMIVNP.js.map → agent-Y24I5JBM.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-LKBEROHN.js → chunk-4S5TWFIZ.js} +14 -14
  62. package/dist/chunk-4S5TWFIZ.js.map +1 -0
  63. package/dist/{chunk-UBDMVMBZ.js → chunk-55GB6JYQ.js} +33 -22
  64. package/dist/chunk-55GB6JYQ.js.map +1 -0
  65. package/dist/{chunk-U6IFHFWK.js → chunk-5WKQDIGO.js} +8 -17
  66. package/dist/chunk-5WKQDIGO.js.map +1 -0
  67. package/dist/chunk-67ADYSTW.js +120 -0
  68. package/dist/chunk-67ADYSTW.js.map +1 -0
  69. package/dist/{chunk-XL7Q7HB2.cjs → chunk-6LHQPOMI.cjs} +39 -6
  70. package/dist/chunk-6LHQPOMI.cjs.map +1 -0
  71. package/dist/{chunk-A4JVILQU.js → chunk-6M2OIS4Y.js} +7 -7
  72. package/dist/chunk-6M2OIS4Y.js.map +1 -0
  73. package/dist/{chunk-LWGSI6M3.js → chunk-6PWOWXMC.js} +4 -4
  74. package/dist/{chunk-LWGSI6M3.js.map → chunk-6PWOWXMC.js.map} +1 -1
  75. package/dist/{chunk-RNB4APBZ.js → chunk-6WAKKTBO.js} +9 -5
  76. package/dist/chunk-6WAKKTBO.js.map +1 -0
  77. package/dist/{chunk-V2BOS4WF.cjs → chunk-7A6535RA.cjs} +11 -11
  78. package/dist/chunk-7A6535RA.cjs.map +1 -0
  79. package/dist/{chunk-ZLQSWSJ2.cjs → chunk-7FDKWDA2.cjs} +11 -11
  80. package/dist/{chunk-ZLQSWSJ2.cjs.map → chunk-7FDKWDA2.cjs.map} +1 -1
  81. package/dist/{chunk-4VPXM6UU.js → chunk-7I5Z3UBJ.js} +3 -3
  82. package/dist/{chunk-4VPXM6UU.js.map → chunk-7I5Z3UBJ.js.map} +1 -1
  83. package/dist/{chunk-B4EOJWOY.cjs → chunk-7JJ3A6AT.cjs} +13 -7
  84. package/dist/chunk-7JJ3A6AT.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-D4CUGAKZ.js → chunk-CZJ6Q7CW.js} +36 -6
  102. package/dist/chunk-CZJ6Q7CW.js.map +1 -0
  103. package/dist/{chunk-KQ7TS7WW.cjs → chunk-D6POWE7E.cjs} +37 -26
  104. package/dist/chunk-D6POWE7E.cjs.map +1 -0
  105. package/dist/{chunk-AWO27VRZ.js → chunk-DMRT67Y6.js} +6 -5
  106. package/dist/chunk-DMRT67Y6.js.map +1 -0
  107. package/dist/{chunk-5VB22SYX.cjs → chunk-DQZU7JK6.cjs} +7 -7
  108. package/dist/{chunk-5VB22SYX.cjs.map → chunk-DQZU7JK6.cjs.map} +1 -1
  109. package/dist/{chunk-3NSS2OIZ.cjs → chunk-DRL7URI4.cjs} +6 -6
  110. package/dist/{chunk-3NSS2OIZ.cjs.map → chunk-DRL7URI4.cjs.map} +1 -1
  111. package/dist/{chunk-RFXWMRFC.js → chunk-EFMFILPG.js} +14 -6
  112. package/dist/chunk-EFMFILPG.js.map +1 -0
  113. package/dist/{chunk-HS7AVXTF.js → chunk-EH6XD3FY.js} +4 -4
  114. package/dist/chunk-EH6XD3FY.js.map +1 -0
  115. package/dist/{chunk-KQRW2GPZ.js → chunk-EIQFAOFD.js} +6 -6
  116. package/dist/chunk-EIQFAOFD.js.map +1 -0
  117. package/dist/{chunk-XJCXEKMD.cjs → chunk-EXTRW7GW.cjs} +4 -4
  118. package/dist/chunk-EXTRW7GW.cjs.map +1 -0
  119. package/dist/{chunk-U54XCYG3.js → chunk-FJWQP6EE.js} +12 -6
  120. package/dist/chunk-FJWQP6EE.js.map +1 -0
  121. package/dist/{chunk-O7DK5PBJ.cjs → chunk-FUSDYC2B.cjs} +26 -42
  122. package/dist/chunk-FUSDYC2B.cjs.map +1 -0
  123. package/dist/{chunk-4QZSA2HJ.js → chunk-G7BLGBRN.js} +4 -4
  124. package/dist/chunk-G7BLGBRN.js.map +1 -0
  125. package/dist/{chunk-BZRFXJHA.js → chunk-GBCVPKHE.js} +55 -26
  126. package/dist/chunk-GBCVPKHE.js.map +1 -0
  127. package/dist/chunk-GGZ5GPE3.cjs +130 -0
  128. package/dist/chunk-GGZ5GPE3.cjs.map +1 -0
  129. package/dist/{chunk-5HEG4CQH.cjs → chunk-GZV6AVRL.cjs} +8 -8
  130. package/dist/{chunk-5HEG4CQH.cjs.map → chunk-GZV6AVRL.cjs.map} +1 -1
  131. package/dist/{chunk-VCLBZAZU.cjs → chunk-H6YM3PV6.cjs} +17 -17
  132. package/dist/chunk-H6YM3PV6.cjs.map +1 -0
  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-ZSWPZ23K.cjs → chunk-I2PWY7VM.cjs} +5 -5
  142. package/dist/chunk-I2PWY7VM.cjs.map +1 -0
  143. package/dist/{chunk-VJ26EKGJ.cjs → chunk-IJ7M6GOG.cjs} +3 -3
  144. package/dist/chunk-IJ7M6GOG.cjs.map +1 -0
  145. package/dist/{chunk-SAVIWMZB.js → chunk-ILGZ2ZZV.js} +3 -3
  146. package/dist/chunk-ILGZ2ZZV.js.map +1 -0
  147. package/dist/{chunk-4ZHTIJNE.cjs → chunk-J7J7J2GN.cjs} +87 -63
  148. package/dist/chunk-J7J7J2GN.cjs.map +1 -0
  149. package/dist/{chunk-UALX2J2Q.cjs → chunk-JLRLCBJ4.cjs} +38 -11
  150. package/dist/chunk-JLRLCBJ4.cjs.map +1 -0
  151. package/dist/{chunk-2QDYBS2A.js → chunk-JMDDYA22.js} +4 -4
  152. package/dist/chunk-JMDDYA22.js.map +1 -0
  153. package/dist/{chunk-LXQ6HKPS.js → chunk-JNAA4G4H.js} +3 -3
  154. package/dist/{chunk-LXQ6HKPS.js.map → chunk-JNAA4G4H.js.map} +1 -1
  155. package/dist/{chunk-UMP6OJIM.js → chunk-JOFVLOFY.js} +4 -4
  156. package/dist/{chunk-UMP6OJIM.js.map → chunk-JOFVLOFY.js.map} +1 -1
  157. package/dist/{chunk-A46SWMIF.js → chunk-K2VMFZQ5.js} +7 -7
  158. package/dist/chunk-K2VMFZQ5.js.map +1 -0
  159. package/dist/{chunk-DN2PACRI.js → chunk-K3NH62DG.js} +461 -282
  160. package/dist/chunk-K3NH62DG.js.map +1 -0
  161. package/dist/{chunk-LYTOXSRH.js → chunk-KDR53EO7.js} +1939 -1864
  162. package/dist/chunk-KDR53EO7.js.map +1 -0
  163. package/dist/{chunk-XWTLIGO3.cjs → chunk-KTTHHYEW.cjs} +5 -5
  164. package/dist/chunk-KTTHHYEW.cjs.map +1 -0
  165. package/dist/{chunk-3FFAEAUJ.cjs → chunk-KVSAY6NZ.cjs} +18 -18
  166. package/dist/chunk-KVSAY6NZ.cjs.map +1 -0
  167. package/dist/{chunk-IAHZCGBE.cjs → chunk-LHSWHYF3.cjs} +120 -146
  168. package/dist/chunk-LHSWHYF3.cjs.map +1 -0
  169. package/dist/{chunk-3OR54XG4.js → chunk-NJWYQWDL.js} +12 -8
  170. package/dist/chunk-NJWYQWDL.js.map +1 -0
  171. package/dist/chunk-NVXXWAU7.cjs +13 -0
  172. package/dist/chunk-NVXXWAU7.cjs.map +1 -0
  173. package/dist/{chunk-2D34UTDC.js → chunk-O6USDERH.js} +31 -11
  174. package/dist/chunk-O6USDERH.js.map +1 -0
  175. package/dist/{chunk-XO4SOZN6.js → chunk-OR6XIWLB.js} +4 -4
  176. package/dist/{chunk-XO4SOZN6.js.map → chunk-OR6XIWLB.js.map} +1 -1
  177. package/dist/{chunk-4PYZ5AX3.cjs → chunk-PRZ3BES7.cjs} +16 -8
  178. package/dist/chunk-PRZ3BES7.cjs.map +1 -0
  179. package/dist/{chunk-HCZD23VS.cjs → chunk-QC55H6RJ.cjs} +65 -39
  180. package/dist/chunk-QC55H6RJ.cjs.map +1 -0
  181. package/dist/{chunk-4O5TGQBW.cjs → chunk-QME6FDFG.cjs} +9 -5
  182. package/dist/chunk-QME6FDFG.cjs.map +1 -0
  183. package/dist/chunk-QOGNZMHD.cjs +34 -0
  184. package/dist/chunk-QOGNZMHD.cjs.map +1 -0
  185. package/dist/{chunk-7VT4P3Z4.cjs → chunk-QUAEOKDW.cjs} +1642 -1567
  186. package/dist/chunk-QUAEOKDW.cjs.map +1 -0
  187. package/dist/{chunk-B2J4ZMZL.cjs → chunk-QWD3CZWE.cjs} +6 -5
  188. package/dist/chunk-QWD3CZWE.cjs.map +1 -0
  189. package/dist/{chunk-SZVR77EJ.cjs → chunk-QWD4RDZ3.cjs} +15 -24
  190. package/dist/chunk-QWD4RDZ3.cjs.map +1 -0
  191. package/dist/{chunk-7BG5UH3T.cjs → chunk-RHZ6HP23.cjs} +4 -4
  192. package/dist/chunk-RHZ6HP23.cjs.map +1 -0
  193. package/dist/{chunk-2HVF2WJY.cjs → chunk-RQMCOFAI.cjs} +8 -8
  194. package/dist/{chunk-2HVF2WJY.cjs.map → chunk-RQMCOFAI.cjs.map} +1 -1
  195. package/dist/{chunk-VKJ7V7EB.cjs → chunk-SA6K24NB.cjs} +3 -3
  196. package/dist/chunk-SA6K24NB.cjs.map +1 -0
  197. package/dist/{chunk-7AD3ZTZL.js → chunk-SAGRF4IB.js} +3 -3
  198. package/dist/chunk-SAGRF4IB.js.map +1 -0
  199. package/dist/{chunk-PUAEFLYK.js → chunk-SVQIW5RJ.js} +4 -4
  200. package/dist/{chunk-PUAEFLYK.js.map → chunk-SVQIW5RJ.js.map} +1 -1
  201. package/dist/{chunk-43ZQRWAP.cjs → chunk-SYVWE64W.cjs} +22 -22
  202. package/dist/chunk-SYVWE64W.cjs.map +1 -0
  203. package/dist/{chunk-3O42QOMJ.js → chunk-TA3K7SBK.js} +7 -6
  204. package/dist/chunk-TA3K7SBK.js.map +1 -0
  205. package/dist/{chunk-LYRDF5TQ.cjs → chunk-TFG5IBZS.cjs} +14 -23
  206. package/dist/chunk-TFG5IBZS.cjs.map +1 -0
  207. package/dist/{chunk-GKEFRLU7.cjs → chunk-TMKTSYDS.cjs} +6 -6
  208. package/dist/{chunk-GKEFRLU7.cjs.map → chunk-TMKTSYDS.cjs.map} +1 -1
  209. package/dist/{chunk-J24VJOH3.cjs → chunk-UADQJBHR.cjs} +31 -11
  210. package/dist/chunk-UADQJBHR.cjs.map +1 -0
  211. package/dist/{chunk-TAZVKYWJ.js → chunk-UBR5PWD7.js} +26 -40
  212. package/dist/chunk-UBR5PWD7.js.map +1 -0
  213. package/dist/{chunk-IPYYKCRC.js → chunk-UFPUHJWS.js} +5 -5
  214. package/dist/{chunk-IPYYKCRC.js.map → chunk-UFPUHJWS.js.map} +1 -1
  215. package/dist/{chunk-OHLDPWTA.cjs → chunk-UGRS7ZA7.cjs} +15 -15
  216. package/dist/{chunk-OHLDPWTA.cjs.map → chunk-UGRS7ZA7.cjs.map} +1 -1
  217. package/dist/{chunk-RIAM53CP.js → chunk-UKMBRMGT.js} +3 -3
  218. package/dist/chunk-UKMBRMGT.js.map +1 -0
  219. package/dist/{chunk-L4BDVXIM.js → chunk-UNK4HNJH.js} +97 -123
  220. package/dist/chunk-UNK4HNJH.js.map +1 -0
  221. package/dist/{chunk-C3NT3PVE.js → chunk-V22DZIXO.js} +3 -3
  222. package/dist/chunk-V22DZIXO.js.map +1 -0
  223. package/dist/{chunk-OFRFZRQ4.cjs → chunk-V6ZY4AX6.cjs} +24 -14
  224. package/dist/chunk-V6ZY4AX6.cjs.map +1 -0
  225. package/dist/{chunk-B3IMEBOA.js → chunk-VE6DFSKU.js} +3 -3
  226. package/dist/{chunk-B3IMEBOA.js.map → chunk-VE6DFSKU.js.map} +1 -1
  227. package/dist/{chunk-WLQNMXQE.js → chunk-VWUXIVEI.js} +53 -26
  228. package/dist/chunk-VWUXIVEI.js.map +1 -0
  229. package/dist/{chunk-GMLBYDW4.cjs → chunk-VXDEKILY.cjs} +108 -109
  230. package/dist/chunk-VXDEKILY.cjs.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-7YGCPMGB.js → chunk-XB4GI5RZ.js} +27 -12
  234. package/dist/chunk-XB4GI5RZ.js.map +1 -0
  235. package/dist/{chunk-O73J46PV.js → chunk-XDANGA2C.js} +5 -5
  236. package/dist/{chunk-O73J46PV.js.map → chunk-XDANGA2C.js.map} +1 -1
  237. package/dist/{chunk-NDGGJQTZ.js → chunk-XJZEBGXD.js} +10 -10
  238. package/dist/chunk-XJZEBGXD.js.map +1 -0
  239. package/dist/{chunk-UTSRIDKZ.js → chunk-XYFGKVZ7.js} +3 -3
  240. package/dist/chunk-XYFGKVZ7.js.map +1 -0
  241. package/dist/{chunk-RMWTPV3M.cjs → chunk-Y2KYR2ED.cjs} +27 -27
  242. package/dist/chunk-Y2KYR2ED.cjs.map +1 -0
  243. package/dist/{chunk-O7LZFG6O.cjs → chunk-YIFFF23U.cjs} +5 -5
  244. package/dist/chunk-YIFFF23U.cjs.map +1 -0
  245. package/dist/{chunk-4OTIXDMU.cjs → chunk-YJNYDJ2T.cjs} +12 -4
  246. package/dist/chunk-YJNYDJ2T.cjs.map +1 -0
  247. package/dist/{chunk-6JSIEDKL.cjs → chunk-YSTXFWQE.cjs} +13 -7
  248. package/dist/chunk-YSTXFWQE.cjs.map +1 -0
  249. package/dist/{chunk-I6HGWHPU.cjs → chunk-Z3NTRKIC.cjs} +4 -4
  250. package/dist/{chunk-I6HGWHPU.cjs.map → chunk-Z3NTRKIC.cjs.map} +1 -1
  251. package/dist/{chunk-32WTYBUH.js → chunk-ZH26RNQA.js} +91 -92
  252. package/dist/chunk-ZH26RNQA.js.map +1 -0
  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-NI33FS2R.cjs +23 -0
  270. package/dist/{context-WFLTTMK3.cjs.map → context-NI33FS2R.cjs.map} +1 -1
  271. package/dist/context-Y7B7SI5X.js +6 -0
  272. package/dist/{context-WI2DFG7V.js.map → context-Y7B7SI5X.js.map} +1 -1
  273. package/dist/create-skill.d.ts +4 -1
  274. package/dist/{cron-BuiRPrvt.d.cts → cron-C3PhZED0.d.cts} +8 -2
  275. package/dist/{cron-C2SIi31n.d.ts → cron-crfMMdAw.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/tool-dispatch.d.ts +2 -2
  341. package/dist/internal/agent-loop/usage-and-cost.d.ts +1 -1
  342. package/dist/internal/auth/credential-availability.d.ts +61 -0
  343. package/dist/internal/auth/credential-store.d.ts +1 -1
  344. package/dist/internal/auth/oauth-device.d.ts +1 -1
  345. package/dist/internal/auth/oauth-engine.d.ts +1 -1
  346. package/dist/internal/auth/resolve-credential.d.ts +1 -1
  347. package/dist/internal/base-url.d.ts +14 -0
  348. package/dist/internal/cloud-agent/cloud-config-serializer.d.ts +1 -1
  349. package/dist/internal/{runtime/concurrency → concurrency}/subagent-credentials.d.ts +2 -2
  350. package/dist/internal/emit-run-event.d.ts +16 -0
  351. package/dist/internal/error-mappers/shared.d.ts +14 -1
  352. package/dist/internal/eval/assert.d.ts +2 -1
  353. package/dist/internal/eval/single-flight.d.ts +2 -1
  354. package/dist/internal/global-singleton.d.ts +6 -3
  355. package/dist/internal/llm/responses.d.ts +10 -0
  356. package/dist/internal/local-agent/local-agent-bootstrap.d.ts +5 -3
  357. package/dist/internal/local-agent/local-agent-capabilities.d.ts +38 -0
  358. package/dist/internal/local-agent/local-agent-dispatch.d.ts +2 -2
  359. package/dist/internal/local-agent/local-agent-memory-provider.d.ts +1 -1
  360. package/dist/internal/local-agent/local-agent-personality-extensions.d.ts +25 -1
  361. package/dist/internal/local-agent/local-agent-send.d.ts +42 -1
  362. package/dist/internal/local-agent/real-local-run-mcp.d.ts +26 -0
  363. package/dist/internal/local-agent/real-local-run-options.d.ts +26 -0
  364. package/dist/internal/local-agent/real-local-run-tools.d.ts +21 -4
  365. package/dist/internal/local-agent/real-local-run.d.ts +2 -2
  366. package/dist/internal/mcp/handshake-timeout.d.ts +53 -0
  367. package/dist/internal/memory/active-memory.d.ts +1 -1
  368. package/dist/internal/memory/adapters/index.cjs +10 -10
  369. package/dist/internal/memory/adapters/index.js +9 -9
  370. package/dist/internal/memory/adapters/openai-embedding.d.cts +10 -0
  371. package/dist/internal/memory/adapters/openai-embedding.d.ts +10 -0
  372. package/dist/internal/memory/corpus-sync.d.ts +23 -0
  373. package/dist/internal/memory/index-db.d.ts +15 -1
  374. package/dist/internal/memory/index-manager-contract.d.ts +12 -0
  375. package/dist/internal/memory/index-manager.d.ts +4 -10
  376. package/dist/internal/memory/index-repository.d.ts +58 -0
  377. package/dist/internal/memory/lance-memory-adapter.d.ts +16 -14
  378. package/dist/internal/memory/memory-index.d.ts +15 -0
  379. package/dist/internal/memory/sdk-memory-peer-loader.d.ts +54 -1
  380. package/dist/internal/memory/storage/index.cjs +39 -40
  381. package/dist/internal/memory/storage/index.js +10 -11
  382. package/dist/internal/memory/storage/memory-root.d.cts +2 -3
  383. package/dist/internal/memory/storage/memory-root.d.ts +2 -3
  384. package/dist/internal/persistence/atomic-write.d.cts +4 -4
  385. package/dist/internal/persistence/atomic-write.d.ts +4 -4
  386. package/dist/internal/persistence/index.cjs +24 -25
  387. package/dist/internal/persistence/index.cjs.map +1 -1
  388. package/dist/internal/persistence/index.js +7 -8
  389. package/dist/internal/persistence/index.js.map +1 -1
  390. package/dist/internal/persistence/jsonl.d.cts +3 -1
  391. package/dist/internal/persistence/jsonl.d.ts +3 -1
  392. package/dist/internal/persistence/paths.d.cts +25 -12
  393. package/dist/internal/persistence/paths.d.ts +25 -12
  394. package/dist/internal/persistence/transcript-ops.d.cts +11 -2
  395. package/dist/internal/persistence/transcript-ops.d.ts +11 -2
  396. package/dist/internal/plugins/context.d.cts +0 -10
  397. package/dist/internal/plugins/context.d.ts +0 -10
  398. package/dist/internal/plugins/types.d.cts +1 -1
  399. package/dist/internal/plugins/types.d.ts +1 -1
  400. package/dist/internal/providers/catalog-schema.d.ts +94 -0
  401. package/dist/internal/providers/catalog-source-models-dev.d.ts +11 -0
  402. package/dist/internal/runtime/compat/compat-config-file.d.ts +31 -0
  403. package/dist/internal/runtime/compat/foreign-config-sources.d.ts +58 -34
  404. package/dist/internal/runtime/compression/compression-model-registry.d.ts +1 -1
  405. package/dist/internal/runtime/compression/compression-summarizer.d.ts +5 -1
  406. package/dist/internal/runtime/fixtures/fixture-events.d.ts +1 -1
  407. package/dist/internal/runtime/fixtures/fixture-mode.d.ts +8 -14
  408. package/dist/internal/runtime/fixtures/fixture-run-base.d.ts +1 -1
  409. package/dist/internal/runtime/fixtures/fixture-scripts.d.ts +2 -2
  410. package/dist/internal/runtime/hooks/hooks-executor.d.ts +6 -1
  411. package/dist/internal/runtime/lifecycle/wrap-completion-check-run.d.ts +1 -1
  412. package/dist/internal/runtime/{memory → memory-glue}/memory-provider.d.ts +1 -1
  413. package/dist/internal/runtime/{plugins → plugin-loader}/plugin-bundles.d.ts +4 -1
  414. package/dist/internal/runtime/processors/wrap-output-run.d.ts +1 -1
  415. package/dist/internal/runtime/registry/live-agent-registry.d.ts +9 -1
  416. package/dist/internal/runtime/system-prompt/local-assembly.d.ts +2 -1
  417. package/dist/internal/scorers/llm-judge.d.ts +12 -0
  418. package/dist/internal/security/index.cjs +14 -15
  419. package/dist/internal/security/index.d.cts +6 -1
  420. package/dist/internal/security/index.d.ts +6 -1
  421. package/dist/internal/security/index.js +4 -5
  422. package/dist/internal/security/path-containment.d.ts +24 -0
  423. package/dist/internal/session/agent-session-store.d.ts +1 -1
  424. package/dist/internal/session/agent-session.d.ts +1 -1
  425. package/dist/internal/session/index.d.ts +1 -1
  426. package/dist/internal/session/session-cache.d.ts +9 -3
  427. package/dist/internal/task/registry.d.ts +1 -1
  428. package/dist/internal/task/store.d.ts +1 -1
  429. package/dist/internal/task/subscribe.d.ts +1 -1
  430. package/dist/internal/task/task-id.d.ts +22 -0
  431. package/dist/internal/telemetry/adapter-registry.d.ts +12 -2
  432. package/dist/internal/telemetry/adapters/braintrust.d.ts +6 -1
  433. package/dist/internal/telemetry/adapters/langsmith.d.ts +6 -1
  434. package/dist/internal/workflow/executor.d.ts +2 -1
  435. package/dist/internal/workflow/snapshot-store.d.ts +1 -1
  436. package/dist/internal/workflow/step-branch.d.ts +2 -2
  437. package/dist/internal/workflow/step-dowhile.d.ts +2 -2
  438. package/dist/internal/workflow/step-execution.d.ts +25 -0
  439. package/dist/internal/workflow/step-foreach.d.ts +2 -2
  440. package/dist/internal/workflow/step-parallel.d.ts +2 -2
  441. package/dist/judge-call-6MVARKU2.js +5 -0
  442. package/dist/{judge-call-LVXABPS3.js.map → judge-call-6MVARKU2.js.map} +1 -1
  443. package/dist/judge-call-I3P4D5QR.cjs +22 -0
  444. package/dist/{judge-call-LAHMBJ57.cjs.map → judge-call-I3P4D5QR.cjs.map} +1 -1
  445. package/dist/mcp-auth.cjs +14 -15
  446. package/dist/mcp-auth.cjs.map +1 -1
  447. package/dist/mcp-auth.d.cts +2 -0
  448. package/dist/mcp-auth.d.ts +2 -0
  449. package/dist/mcp-auth.js +4 -5
  450. package/dist/mcp-auth.js.map +1 -1
  451. package/dist/models.cjs +52 -42
  452. package/dist/models.cjs.map +1 -1
  453. package/dist/models.js +39 -29
  454. package/dist/models.js.map +1 -1
  455. package/dist/oauth-transaction-store-5RIR6D5C.js +5 -0
  456. package/dist/{oauth-transaction-store-W52KVHQ4.js.map → oauth-transaction-store-5RIR6D5C.js.map} +1 -1
  457. package/dist/oauth-transaction-store-SXIE57OD.cjs +38 -0
  458. package/dist/{oauth-transaction-store-BT4GLTLK.cjs.map → oauth-transaction-store-SXIE57OD.cjs.map} +1 -1
  459. package/dist/path-safety.cjs +11 -12
  460. package/dist/path-safety.d.cts +2 -0
  461. package/dist/path-safety.d.ts +2 -0
  462. package/dist/path-safety.js +4 -5
  463. package/dist/permission-engine.d.ts +10 -17
  464. package/dist/persistence.cjs +31 -31
  465. package/dist/persistence.cjs.map +1 -1
  466. package/dist/persistence.d.cts +9 -1
  467. package/dist/persistence.d.ts +9 -1
  468. package/dist/persistence.js +12 -13
  469. package/dist/persistence.js.map +1 -1
  470. package/dist/project.cjs +5 -6
  471. package/dist/project.cjs.map +1 -1
  472. package/dist/project.js +3 -4
  473. package/dist/project.js.map +1 -1
  474. package/dist/providers.cjs +10 -10
  475. package/dist/providers.d.cts +2 -0
  476. package/dist/providers.d.ts +2 -0
  477. package/dist/providers.js +8 -8
  478. package/dist/registry-BZQFYRTL.cjs +46 -0
  479. package/dist/{registry-V7BDQ6QB.cjs.map → registry-BZQFYRTL.cjs.map} +1 -1
  480. package/dist/registry-DMWCJKRF.js +9 -0
  481. package/dist/{registry-75W33OGL.js.map → registry-DMWCJKRF.js.map} +1 -1
  482. package/dist/retry.cjs +4 -5
  483. package/dist/retry.d.cts +20 -5
  484. package/dist/retry.d.ts +20 -5
  485. package/dist/retry.js +3 -4
  486. package/dist/{run-BYSHf58D.d.ts → run-CTAdRU3U.d.cts} +120 -152
  487. package/dist/{run-BYSHf58D.d.cts → run-CTAdRU3U.d.ts} +120 -152
  488. package/dist/{run-until-HEQOUVU6.js → run-until-6D6TQ4JN.js} +27 -59
  489. package/dist/run-until-6D6TQ4JN.js.map +1 -0
  490. package/dist/{run-until-U2B5FJJI.cjs → run-until-DG2KXWB2.cjs} +27 -59
  491. package/dist/run-until-DG2KXWB2.cjs.map +1 -0
  492. package/dist/sandbox/bwrap.d.cts +11 -1
  493. package/dist/sandbox/bwrap.d.ts +11 -1
  494. package/dist/sandbox/index.cjs +26 -30
  495. package/dist/sandbox/index.cjs.map +1 -1
  496. package/dist/sandbox/index.d.cts +8 -1
  497. package/dist/sandbox/index.d.ts +8 -1
  498. package/dist/sandbox/index.js +10 -14
  499. package/dist/sandbox/index.js.map +1 -1
  500. package/dist/sandbox/linux-sandbox.d.cts +20 -4
  501. package/dist/sandbox/linux-sandbox.d.ts +20 -4
  502. package/dist/sandbox/types.d.cts +18 -2
  503. package/dist/sandbox/types.d.ts +18 -2
  504. package/dist/sanitize/index.cjs +2 -2
  505. package/dist/sanitize/index.js +1 -1
  506. package/dist/sanitize/types.d.cts +15 -2
  507. package/dist/sanitize/types.d.ts +15 -2
  508. package/dist/{sdk-agent-D8qJVkuV.d.ts → sdk-agent-BOiKqOgL.d.cts} +197 -117
  509. package/dist/{sdk-agent-DEoKhA8a.d.cts → sdk-agent-D4a_BR_6.d.ts} +197 -117
  510. package/dist/server/auth/errors.d.cts +4 -3
  511. package/dist/server/auth/errors.d.ts +4 -3
  512. package/dist/server/auth/index.cjs +28 -28
  513. package/dist/server/auth/index.cjs.map +1 -1
  514. package/dist/server/auth/index.d.cts +28 -5
  515. package/dist/server/auth/index.d.ts +28 -5
  516. package/dist/server/auth/index.js +13 -13
  517. package/dist/server/auth/index.js.map +1 -1
  518. package/dist/server/auth/oauth-transaction-store.d.cts +2 -1
  519. package/dist/server/auth/oauth-transaction-store.d.ts +2 -1
  520. package/dist/server/auth/orchestrator.d.cts +4 -1
  521. package/dist/server/auth/orchestrator.d.ts +4 -1
  522. package/dist/server/auth/types.d.cts +18 -0
  523. package/dist/server/auth/types.d.ts +18 -0
  524. package/dist/server/errors-envelope.cjs +14 -15
  525. package/dist/server/errors-envelope.cjs.map +1 -1
  526. package/dist/server/errors-envelope.d.cts +3 -3
  527. package/dist/server/errors-envelope.d.ts +3 -3
  528. package/dist/server/errors-envelope.js +3 -4
  529. package/dist/server/errors-envelope.js.map +1 -1
  530. package/dist/session-transcript-LGHSNVY5.cjs +62 -0
  531. package/dist/{session-transcript-6WNITKRE.cjs.map → session-transcript-LGHSNVY5.cjs.map} +1 -1
  532. package/dist/session-transcript-VTBTCGQX.js +5 -0
  533. package/dist/{session-transcript-XAEKW6P7.js.map → session-transcript-VTBTCGQX.js.map} +1 -1
  534. package/dist/skills.cjs +8 -9
  535. package/dist/skills.js +6 -7
  536. package/dist/stream-object-HBFMIZLD.js +7 -0
  537. package/dist/{stream-object-UF4QRQRU.js.map → stream-object-HBFMIZLD.js.map} +1 -1
  538. package/dist/stream-object-QSKHISDJ.cjs +20 -0
  539. package/dist/{stream-object-ZJTQNKY3.cjs.map → stream-object-QSKHISDJ.cjs.map} +1 -1
  540. package/dist/stream-object.d.ts +2 -4
  541. package/dist/subagents-loader-TPZLTXYZ.cjs +16 -0
  542. package/dist/{subagents-loader-UCNO7FUH.cjs.map → subagents-loader-TPZLTXYZ.cjs.map} +1 -1
  543. package/dist/subagents-loader-Y6JFYXAY.js +7 -0
  544. package/dist/{subagents-loader-XP5ERVDZ.js.map → subagents-loader-Y6JFYXAY.js.map} +1 -1
  545. package/dist/subagents-loader.cjs +7 -8
  546. package/dist/subagents-loader.cjs.map +1 -1
  547. package/dist/subagents-loader.d.cts +5 -3
  548. package/dist/subagents-loader.d.ts +5 -3
  549. package/dist/subagents-loader.js +5 -6
  550. package/dist/subagents-loader.js.map +1 -1
  551. package/dist/subagents.cjs +2 -2
  552. package/dist/subagents.cjs.map +1 -1
  553. package/dist/subagents.js +1 -1
  554. package/dist/subagents.js.map +1 -1
  555. package/dist/subscription/define-subscription.d.cts +4 -1
  556. package/dist/subscription/define-subscription.d.ts +4 -1
  557. package/dist/subscription/index.cjs +4 -5
  558. package/dist/subscription/index.cjs.map +1 -1
  559. package/dist/subscription/index.d.cts +2 -0
  560. package/dist/subscription/index.d.ts +2 -0
  561. package/dist/subscription/index.js +3 -4
  562. package/dist/subscription/index.js.map +1 -1
  563. package/dist/subscription/internal/server-integration.d.cts +5 -0
  564. package/dist/subscription/internal/server-integration.d.ts +5 -0
  565. package/dist/subscription/internal/subscription-runtime.d.cts +13 -1
  566. package/dist/subscription/internal/subscription-runtime.d.ts +13 -1
  567. package/dist/task-errors.d.ts +58 -0
  568. package/dist/task-store.cjs +7 -8
  569. package/dist/task-store.d.cts +2 -0
  570. package/dist/task-store.d.ts +2 -0
  571. package/dist/task-store.js +4 -5
  572. package/dist/types/agent-prims.d.ts +21 -0
  573. package/dist/types/agent.d.ts +109 -15
  574. package/dist/types/batch.d.ts +3 -0
  575. package/dist/types/budget-tracker.d.ts +3 -0
  576. package/dist/types/budget.d.ts +12 -3
  577. package/dist/types/content-blocks.d.ts +3 -0
  578. package/dist/types/context.d.ts +3 -0
  579. package/dist/types/conversation.d.ts +5 -0
  580. package/dist/types/cron.d.ts +5 -0
  581. package/dist/types/env-policy.d.ts +3 -0
  582. package/dist/types/eval.d.ts +3 -0
  583. package/dist/types/fork.d.ts +3 -0
  584. package/dist/types/goal-events.d.ts +3 -0
  585. package/dist/types/mcp.d.ts +5 -0
  586. package/dist/types/memory-adapter.d.ts +3 -0
  587. package/dist/types/memory-provider.d.ts +44 -5
  588. package/dist/types/messages-base.d.ts +4 -0
  589. package/dist/types/messages.d.ts +5 -0
  590. package/dist/types/plugin.d.ts +32 -4
  591. package/dist/types/processors.d.ts +3 -0
  592. package/dist/types/provider-profile.d.ts +3 -0
  593. package/dist/types/providers.d.ts +3 -0
  594. package/dist/types/run-events.d.ts +36 -9
  595. package/dist/types/run.d.ts +29 -2
  596. package/dist/types/sdk-agent.d.ts +71 -1
  597. package/dist/types/session-message.d.ts +3 -0
  598. package/dist/types/session-record.d.ts +3 -0
  599. package/dist/types/session-store.d.ts +45 -0
  600. package/dist/types/task.d.ts +3 -11
  601. package/dist/types/theokit.d.ts +3 -0
  602. package/dist/types/trajectory.d.ts +3 -0
  603. package/dist/types/updates.d.ts +5 -0
  604. package/dist/types/usage.d.ts +4 -1
  605. package/dist/types/workflow.d.ts +13 -135
  606. package/dist/workflow-as-tool.d.ts +66 -0
  607. package/dist/workflow-errors.d.ts +164 -0
  608. package/dist/workflow.cjs +29 -30
  609. package/dist/workflow.d.cts +135 -74
  610. package/dist/workflow.d.ts +135 -74
  611. package/dist/workflow.js +8 -9
  612. package/docs/adr/README.md +2604 -0
  613. package/docs/error-codes.md +139 -105
  614. package/docs/harness-capability-map.md +32 -20
  615. package/docs/memory-decisions.md +1 -1
  616. package/package.json +3 -7
  617. package/bin/theokit-migrate-config.mjs +0 -278
  618. package/bin/theokit-migrate-memory.mjs +0 -116
  619. package/dist/agent-A5XMIVNP.js +0 -57
  620. package/dist/agent-UX7WFI6B.cjs +0 -66
  621. package/dist/agent-session-store-6EL5NPA4.cjs +0 -24
  622. package/dist/agent-session-store-OPGRB4XM.js +0 -7
  623. package/dist/batch-BXYTW2DP.cjs.map +0 -1
  624. package/dist/batch-L4ZXS46M.js.map +0 -1
  625. package/dist/chunk-247ZTLNU.js +0 -73
  626. package/dist/chunk-247ZTLNU.js.map +0 -1
  627. package/dist/chunk-2D34UTDC.js.map +0 -1
  628. package/dist/chunk-2GUYQR5P.js.map +0 -1
  629. package/dist/chunk-2QDYBS2A.js.map +0 -1
  630. package/dist/chunk-32WTYBUH.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-43ZQRWAP.cjs.map +0 -1
  635. package/dist/chunk-4FFBAUFS.js.map +0 -1
  636. package/dist/chunk-4O5TGQBW.cjs.map +0 -1
  637. package/dist/chunk-4OTIXDMU.cjs.map +0 -1
  638. package/dist/chunk-4PYZ5AX3.cjs.map +0 -1
  639. package/dist/chunk-4QZSA2HJ.js.map +0 -1
  640. package/dist/chunk-4ZHTIJNE.cjs.map +0 -1
  641. package/dist/chunk-52NKC5HT.cjs.map +0 -1
  642. package/dist/chunk-6HKGLTJI.cjs.map +0 -1
  643. package/dist/chunk-6JSIEDKL.cjs.map +0 -1
  644. package/dist/chunk-7AD3ZTZL.js.map +0 -1
  645. package/dist/chunk-7BG5UH3T.cjs.map +0 -1
  646. package/dist/chunk-7VT4P3Z4.cjs.map +0 -1
  647. package/dist/chunk-7YGCPMGB.js.map +0 -1
  648. package/dist/chunk-A46SWMIF.js.map +0 -1
  649. package/dist/chunk-A4JVILQU.js.map +0 -1
  650. package/dist/chunk-ACDLHN3W.js.map +0 -1
  651. package/dist/chunk-AKJP2STZ.cjs +0 -81
  652. package/dist/chunk-AKJP2STZ.cjs.map +0 -1
  653. package/dist/chunk-AWO27VRZ.js.map +0 -1
  654. package/dist/chunk-B2J4ZMZL.cjs.map +0 -1
  655. package/dist/chunk-B4EOJWOY.cjs.map +0 -1
  656. package/dist/chunk-BU4KFWXF.js.map +0 -1
  657. package/dist/chunk-BZRFXJHA.js.map +0 -1
  658. package/dist/chunk-C3NT3PVE.js.map +0 -1
  659. package/dist/chunk-C72AZW7J.js.map +0 -1
  660. package/dist/chunk-D4CUGAKZ.js.map +0 -1
  661. package/dist/chunk-DN2PACRI.js.map +0 -1
  662. package/dist/chunk-DXGZ2NUG.cjs.map +0 -1
  663. package/dist/chunk-EG4QM7ZJ.cjs +0 -39
  664. package/dist/chunk-EG4QM7ZJ.cjs.map +0 -1
  665. package/dist/chunk-GMLBYDW4.cjs.map +0 -1
  666. package/dist/chunk-HCZD23VS.cjs.map +0 -1
  667. package/dist/chunk-HS7AVXTF.js.map +0 -1
  668. package/dist/chunk-IAHZCGBE.cjs.map +0 -1
  669. package/dist/chunk-J24VJOH3.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-KQ7TS7WW.cjs.map +0 -1
  673. package/dist/chunk-KQRW2GPZ.js.map +0 -1
  674. package/dist/chunk-KYAJINUI.cjs.map +0 -1
  675. package/dist/chunk-L3MTL4NA.js.map +0 -1
  676. package/dist/chunk-L4BDVXIM.js.map +0 -1
  677. package/dist/chunk-LKBEROHN.js.map +0 -1
  678. package/dist/chunk-LYRDF5TQ.cjs.map +0 -1
  679. package/dist/chunk-LYTOXSRH.js.map +0 -1
  680. package/dist/chunk-N2U4AZGB.js.map +0 -1
  681. package/dist/chunk-NDGGJQTZ.js.map +0 -1
  682. package/dist/chunk-O7DK5PBJ.cjs.map +0 -1
  683. package/dist/chunk-O7LZFG6O.cjs.map +0 -1
  684. package/dist/chunk-OFRFZRQ4.cjs.map +0 -1
  685. package/dist/chunk-OSEG74VJ.js.map +0 -1
  686. package/dist/chunk-RFMBZPOW.cjs.map +0 -1
  687. package/dist/chunk-RFXWMRFC.js.map +0 -1
  688. package/dist/chunk-RIAM53CP.js.map +0 -1
  689. package/dist/chunk-RMWTPV3M.cjs.map +0 -1
  690. package/dist/chunk-RNB4APBZ.js.map +0 -1
  691. package/dist/chunk-SAVIWMZB.js.map +0 -1
  692. package/dist/chunk-SZVR77EJ.cjs.map +0 -1
  693. package/dist/chunk-TAZVKYWJ.js.map +0 -1
  694. package/dist/chunk-U54XCYG3.js.map +0 -1
  695. package/dist/chunk-U6IFHFWK.js.map +0 -1
  696. package/dist/chunk-UALX2J2Q.cjs.map +0 -1
  697. package/dist/chunk-UBDMVMBZ.js.map +0 -1
  698. package/dist/chunk-UGT7GK7I.cjs.map +0 -1
  699. package/dist/chunk-UNYXQ4M5.js.map +0 -1
  700. package/dist/chunk-UTSRIDKZ.js.map +0 -1
  701. package/dist/chunk-UU36SHFY.cjs.map +0 -1
  702. package/dist/chunk-V2BOS4WF.cjs.map +0 -1
  703. package/dist/chunk-VCLBZAZU.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-ZSWPZ23K.cjs.map +0 -1
  718. package/dist/chunk-ZZMZWBR6.js.map +0 -1
  719. package/dist/compact-session-QV57KR66.cjs +0 -59
  720. package/dist/compact-session-RIGOWC4Y.js +0 -22
  721. package/dist/context-WFLTTMK3.cjs +0 -24
  722. package/dist/context-WI2DFG7V.js +0 -7
  723. package/dist/executor-6CYCA7MI.cjs.map +0 -1
  724. package/dist/executor-QSEC3MRH.js.map +0 -1
  725. package/dist/fork-agent-RSV4E3EA.js.map +0 -1
  726. package/dist/fork-agent-Y2IK2RYU.cjs.map +0 -1
  727. package/dist/fs-session-store-4PIHT5UX.cjs +0 -20
  728. package/dist/fs-session-store-NM6YSTE2.js +0 -11
  729. package/dist/generate-object-GUNAUVBX.js +0 -8
  730. package/dist/generate-object-R7HTMW7F.cjs +0 -21
  731. package/dist/index-manager-2SRX45WJ.cjs +0 -27
  732. package/dist/index-manager-SP4ISSDX.js +0 -18
  733. package/dist/inject-session-WQKMC3GR.cjs +0 -29
  734. package/dist/internal/persistence/credential-pool-store.d.cts +0 -32
  735. package/dist/internal/persistence/credential-pool-store.d.ts +0 -32
  736. package/dist/internal/runtime/memory/memory-path-selector.d.ts +0 -73
  737. package/dist/judge-call-LAHMBJ57.cjs +0 -23
  738. package/dist/judge-call-LVXABPS3.js +0 -6
  739. package/dist/oauth-transaction-store-BT4GLTLK.cjs +0 -36
  740. package/dist/oauth-transaction-store-W52KVHQ4.js +0 -3
  741. package/dist/registry-75W33OGL.js +0 -10
  742. package/dist/registry-V7BDQ6QB.cjs +0 -47
  743. package/dist/run-until-HEQOUVU6.js.map +0 -1
  744. package/dist/run-until-U2B5FJJI.cjs.map +0 -1
  745. package/dist/server/adapter/express.d.cts +0 -9
  746. package/dist/server/adapter/express.d.ts +0 -9
  747. package/dist/server/adapter/fastify.d.cts +0 -9
  748. package/dist/server/adapter/fastify.d.ts +0 -9
  749. package/dist/server/adapter/hono.d.cts +0 -9
  750. package/dist/server/adapter/hono.d.ts +0 -9
  751. package/dist/server/adapter/shared-handler.d.cts +0 -9
  752. package/dist/server/adapter/shared-handler.d.ts +0 -9
  753. package/dist/server/adapter/types.d.cts +0 -33
  754. package/dist/server/adapter/types.d.ts +0 -33
  755. package/dist/session-transcript-6WNITKRE.cjs +0 -63
  756. package/dist/session-transcript-XAEKW6P7.js +0 -6
  757. package/dist/stream-object-UF4QRQRU.js +0 -8
  758. package/dist/stream-object-ZJTQNKY3.cjs +0 -21
  759. package/dist/subagents-loader-UCNO7FUH.cjs +0 -17
  760. package/dist/subagents-loader-XP5ERVDZ.js +0 -8
  761. /package/dist/{batch.d.ts → internal/agent/batch.d.ts} +0 -0
  762. /package/dist/{agent-helpers.d.ts → internal/agent/helpers.d.ts} +0 -0
  763. /package/dist/internal/agent-loop/{loop-types.d.ts → types.d.ts} +0 -0
  764. /package/dist/internal/auth/{auth-types.d.ts → types.d.ts} +0 -0
  765. /package/dist/internal/cloud-agent/{cloud-payload-types.d.ts → types.d.ts} +0 -0
  766. /package/dist/internal/{runtime/concurrency → concurrency}/abort-utils.d.ts +0 -0
  767. /package/dist/internal/{runtime/concurrency → concurrency}/async-local-storage.d.ts +0 -0
  768. /package/dist/internal/{runtime/concurrency → concurrency}/async-semaphore.d.ts +0 -0
  769. /package/dist/internal/{runtime/concurrency → concurrency}/delegation-depth.d.ts +0 -0
  770. /package/dist/internal/{runtime/concurrency → concurrency}/map-with-concurrency.d.ts +0 -0
  771. /package/dist/internal/{runtime/retry → error-mappers}/default-retriable.d.ts +0 -0
  772. /package/dist/internal/{runtime/fixtures/fixture-types.d.ts → memory/storage/list-markdown.d.cts} +0 -0
  773. /package/dist/internal/{runtime/plugins/plugins-manager.d.ts → memory/storage/list-markdown.d.ts} +0 -0
  774. /package/dist/internal/{resilience → retry}/circuit-breaker.d.ts +0 -0
  775. /package/dist/internal/{runtime/retry → retry}/with-retry.d.ts +0 -0
  776. /package/dist/internal/{security/secret-redactor.d.cts → runtime/fixtures/types.d.ts} +0 -0
  777. /package/dist/internal/runtime/{memory → memory-glue}/memory-store.d.ts +0 -0
  778. /package/dist/internal/runtime/{memory → memory-glue}/select-facts.d.ts +0 -0
  779. /package/dist/internal/runtime/{plugins → plugin-loader}/plugin-frontmatter.d.ts +0 -0
  780. /package/dist/internal/{security/secret-redactor.d.ts → runtime/plugin-loader/plugins-manager.d.ts} +0 -0
  781. /package/dist/internal/runtime/{reasoning → system-prompt}/native-reasoning.d.ts +0 -0
  782. /package/dist/internal/{runtime/context/path-containment.d.ts → security/path-containment.d.cts} +0 -0
  783. /package/dist/internal/session/{session-types.d.ts → types.d.ts} +0 -0
  784. /package/dist/internal/{zod/to-json-schema.d.ts → zod-to-json-schema.d.ts} +0 -0
  785. /package/dist/subscription/internal/{adapter-types.d.cts → types.d.cts} +0 -0
  786. /package/dist/subscription/internal/{adapter-types.d.ts → types.d.ts} +0 -0
@@ -1,46 +1,46 @@
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-NDGGJQTZ.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-XJZEBGXD.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-LKBEROHN.js';
28
- import { undefinedVariablesIn, getTheokitHome, projectConfigRoots, pluginBundleRoots, adapterForConfigPath } from './chunk-247ZTLNU.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-4S5TWFIZ.js';
28
+ import { reportUndeclaredSources, theokitConfigRoot, undefinedVariablesIn, getTheokitHome, adapterForConfigPath, projectConfigRoots, pluginBundleRoots } from './chunk-67ADYSTW.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
- import { join, dirname, resolve, isAbsolute } from 'path';
39
+ import { join, dirname, resolve, relative, isAbsolute } from 'path';
40
+ import { existsSync, readFileSync } from 'fs';
40
41
  import { spawn } from 'child_process';
41
42
  import { z } from 'zod';
42
43
  import { createRequire } from 'module';
43
- import { existsSync } from 'fs';
44
44
  import { homedir } from 'os';
45
45
 
46
46
  // src/agent-builder.ts
@@ -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
  }
@@ -340,7 +269,7 @@ function enabledPluginNames(plugins) {
340
269
  // src/internal/runtime/registry/agent-registry-store.ts
341
270
  var SCHEMA_VERSION = 1;
342
271
  var LEGACY_SCHEMA_VERSION_STRING = "1.0";
343
- var REGISTRY_RELATIVE_PATH = join(".theokit", "agents", "registry.json");
272
+ var REGISTRY_RELATIVE_SUFFIX = join("agents", "registry.json");
344
273
  function stripSecretsFromOptions(options) {
345
274
  return assignDefined({
346
275
  name: options.name,
@@ -450,9 +379,10 @@ function serializeAgents(agents2) {
450
379
  return out;
451
380
  }
452
381
  function registryPath(cwd) {
453
- return join(cwd, REGISTRY_RELATIVE_PATH);
382
+ return join(theokitConfigRoot(cwd), REGISTRY_RELATIVE_SUFFIX);
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 });
@@ -2554,6 +2518,37 @@ function removeAll(arr, toRemove) {
2554
2518
  if (idx !== -1) arr.splice(idx, 1);
2555
2519
  }
2556
2520
  }
2521
+ function readCompatConfigFile(cwd) {
2522
+ const path = join(theokitConfigRoot(cwd), "config.json");
2523
+ if (!existsSync(path)) return [];
2524
+ let raw;
2525
+ try {
2526
+ raw = readFileSync(path, "utf8");
2527
+ } catch {
2528
+ return [];
2529
+ }
2530
+ let parsed;
2531
+ try {
2532
+ parsed = JSON.parse(raw);
2533
+ } catch (cause) {
2534
+ diag(
2535
+ `[theokit] ${path} is not valid JSON \u2014 ignoring its "compat.adapters" (${cause.message}).
2536
+ `
2537
+ );
2538
+ return [];
2539
+ }
2540
+ const adapters = parsed.compat?.adapters;
2541
+ if (adapters === void 0) return [];
2542
+ if (!Array.isArray(adapters)) {
2543
+ diag(`[theokit] ${path}: "compat.adapters" must be an array \u2014 ignoring it.
2544
+ `);
2545
+ return [];
2546
+ }
2547
+ return adapters;
2548
+ }
2549
+ function resolveCompatSources(options, cwd) {
2550
+ return options.local?.compatSources ?? readCompatConfigFile(cwd);
2551
+ }
2557
2552
  function spawnAndCollect(options) {
2558
2553
  return new Promise((resolve) => {
2559
2554
  const timeoutMs = options.timeoutMs ?? 3e4;
@@ -2604,17 +2599,19 @@ function spawnAndCollect(options) {
2604
2599
 
2605
2600
  // src/internal/runtime/hooks/hooks-executor.ts
2606
2601
  var HooksExecutor = class {
2607
- constructor(cwd) {
2602
+ constructor(cwd, compatSources = []) {
2608
2603
  this.cwd = cwd;
2604
+ this.compatSources = compatSources;
2609
2605
  }
2610
2606
  cwd;
2607
+ compatSources;
2611
2608
  config = {};
2612
2609
  async initialize(settingSourcesIncludeProject) {
2613
2610
  if (!settingSourcesIncludeProject) {
2614
2611
  this.config = {};
2615
2612
  return;
2616
2613
  }
2617
- this.config = await loadHookConfig(this.cwd);
2614
+ this.config = await loadHookConfig(this.cwd, this.compatSources);
2618
2615
  }
2619
2616
  /** Fire every hook registered for `event` and aggregate the decisions. */
2620
2617
  async run(payload) {
@@ -2699,28 +2696,6 @@ function parseDecisionFromStdout(stdout) {
2699
2696
  return { decision: "allow" };
2700
2697
  }
2701
2698
 
2702
- // src/internal/runtime/memory/memory-path-selector.ts
2703
- var PORT_MEMORY_PATH_ENV_VAR = "THEOKIT_PORT_MEMORY_PATH";
2704
- function shouldUsePortMemoryPath() {
2705
- const env = globalThis.process?.env;
2706
- if (env === void 0) return false;
2707
- const val = env[PORT_MEMORY_PATH_ENV_VAR];
2708
- return val === "1" || val === "true";
2709
- }
2710
- function resolveMemoryProviderForLoop(consumerSupplied, defaultAdapter, portPathEnabled) {
2711
- if (consumerSupplied !== void 0) return consumerSupplied;
2712
- if (portPathEnabled) return defaultAdapter;
2713
- return void 0;
2714
- }
2715
- function resolveMemoryToolsForLoop(legacyTools, portPathEnabled) {
2716
- if (portPathEnabled) return void 0;
2717
- return legacyTools;
2718
- }
2719
- function resolveActiveMemorySummaryForSend(legacySummary, portPathEnabled) {
2720
- if (portPathEnabled) return void 0;
2721
- return legacySummary;
2722
- }
2723
-
2724
2699
  // src/internal/runtime/lifecycle/context-budget-event.ts
2725
2700
  function buildContextBudgetEvent(model, resolved) {
2726
2701
  if (resolved.source !== "fallback") return void 0;
@@ -2751,7 +2726,6 @@ async function runPostRunLifecycle(inputs) {
2751
2726
  contextWindow,
2752
2727
  onRunEvent,
2753
2728
  hooksExecutor,
2754
- memoryGlue,
2755
2729
  memoryProvider
2756
2730
  } = inputs;
2757
2731
  let result;
@@ -2825,9 +2799,6 @@ async function runPostRunLifecycle(inputs) {
2825
2799
  } else {
2826
2800
  await writeSessionSummary(summaryArgs);
2827
2801
  }
2828
- if (!shouldUsePortMemoryPath()) {
2829
- void memoryGlue.syncIfReady();
2830
- }
2831
2802
  } catch (cause) {
2832
2803
  const message = cause instanceof Error ? cause.message : String(cause);
2833
2804
  diag(`[theokit-sdk] session summary write failed (${result.id}): ${message}
@@ -2848,10 +2819,85 @@ async function runPostRunLifecycle(inputs) {
2848
2819
  async function safeConversation(run) {
2849
2820
  try {
2850
2821
  return await run.conversation();
2851
- } catch {
2822
+ } catch (cause) {
2823
+ const msg = cause instanceof Error ? cause.message : String(cause);
2824
+ diag(`[theokit-sdk] conversation() failed; persisting the user turn only: ${msg}
2825
+ `);
2852
2826
  return [];
2853
2827
  }
2854
2828
  }
2829
+ var SkillsManager = class {
2830
+ constructor(cwd, _enabled, settingSourcesIncludeProject, skillsDir, inline, compatSources = []) {
2831
+ this.cwd = cwd;
2832
+ this.settingSourcesIncludeProject = settingSourcesIncludeProject;
2833
+ this.skillsDir = skillsDir;
2834
+ this.inline = inline;
2835
+ this.compatSources = compatSources;
2836
+ }
2837
+ cwd;
2838
+ settingSourcesIncludeProject;
2839
+ skillsDir;
2840
+ inline;
2841
+ compatSources;
2842
+ skills = [];
2843
+ async initialize() {
2844
+ if (!this.settingSourcesIncludeProject) {
2845
+ this.skills = this.mergeInline([]);
2846
+ return;
2847
+ }
2848
+ await this.refresh();
2849
+ }
2850
+ async refresh() {
2851
+ const roots = this.skillsDir === void 0 ? [
2852
+ ...projectConfigRoots(this.cwd, this.compatSources, "skills").map(
2853
+ (root) => join(root, "skills")
2854
+ ),
2855
+ ...(await pluginBundleDirs(this.cwd, this.compatSources)).map((b) => join(b, "skills"))
2856
+ ] : [this.skillsDir];
2857
+ const discovered = [];
2858
+ const seen = /* @__PURE__ */ new Set();
2859
+ for (const root of roots) {
2860
+ for (const skill of await discoverSkills(root, {
2861
+ onInvalidSkill: (info) => {
2862
+ diag(`[theokit-sdk] skill ${info.name} skipped (${info.code}): ${info.message}
2863
+ `);
2864
+ }
2865
+ })) {
2866
+ if (seen.has(skill.name)) continue;
2867
+ seen.add(skill.name);
2868
+ discovered.push(skill);
2869
+ }
2870
+ }
2871
+ this.skills = this.mergeInline(discovered);
2872
+ }
2873
+ /** M22 — merge inline skills over discovered ones; inline wins on a name conflict. */
2874
+ mergeInline(discovered) {
2875
+ if (this.inline === void 0 || this.inline.length === 0) return discovered;
2876
+ const inlineNames = new Set(this.inline.map((s) => s.name));
2877
+ return [...discovered.filter((s) => !inlineNames.has(s.name)), ...this.inline];
2878
+ }
2879
+ list() {
2880
+ return Promise.resolve(this.skills);
2881
+ }
2882
+ /**
2883
+ * SE20 — resolve a skill by name INCLUDING its body. Inline (`createSkill`)
2884
+ * skills carry `instructions` on the object; filesystem skills read the body
2885
+ * from their `source` SKILL.md (frontmatter stripped). `undefined` when no
2886
+ * enabled skill matches (malformed skills were already excluded at discovery).
2887
+ */
2888
+ async get(name) {
2889
+ const skill = this.skills.find((s) => s.name === name);
2890
+ if (skill === void 0) return void 0;
2891
+ const instructions = typeof skill.instructions === "string" ? skill.instructions : stripSkillFrontmatter(await readFile(skill.source, "utf8"));
2892
+ const references = skill.references;
2893
+ return {
2894
+ name: skill.name,
2895
+ description: skill.description,
2896
+ instructions,
2897
+ ...references !== void 0 ? { references } : {}
2898
+ };
2899
+ }
2900
+ };
2855
2901
 
2856
2902
  // src/define-tool.ts
2857
2903
  var TOOL_SPLIT_RESOLVER = /* @__PURE__ */ Symbol("theokit.toolSplitResolver");
@@ -2897,7 +2943,7 @@ function defineTool(spec) {
2897
2943
  return tool;
2898
2944
  }
2899
2945
 
2900
- // src/internal/runtime/reasoning/native-reasoning.ts
2946
+ // src/internal/runtime/system-prompt/native-reasoning.ts
2901
2947
  var NATIVE_REASONING_PARAM_IDS = /* @__PURE__ */ new Set(["thinking", "reasoning", "reasoning_effort"]);
2902
2948
  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.";
2903
2949
  function createThinkTool() {
@@ -2930,74 +2976,6 @@ function reasoningActive(reasoning, model) {
2930
2976
  }
2931
2977
  return true;
2932
2978
  }
2933
- var SkillsManager = class {
2934
- constructor(cwd, _enabled, settingSourcesIncludeProject, skillsDir, inline) {
2935
- this.cwd = cwd;
2936
- this.settingSourcesIncludeProject = settingSourcesIncludeProject;
2937
- this.skillsDir = skillsDir;
2938
- this.inline = inline;
2939
- }
2940
- cwd;
2941
- settingSourcesIncludeProject;
2942
- skillsDir;
2943
- inline;
2944
- skills = [];
2945
- async initialize() {
2946
- if (!this.settingSourcesIncludeProject) {
2947
- this.skills = this.mergeInline([]);
2948
- return;
2949
- }
2950
- await this.refresh();
2951
- }
2952
- async refresh() {
2953
- const roots = this.skillsDir === void 0 ? [
2954
- ...projectConfigRoots(this.cwd).map((root) => join(root, "skills")),
2955
- ...(await pluginBundleDirs(this.cwd)).map((bundle) => join(bundle, "skills"))
2956
- ] : [this.skillsDir];
2957
- const discovered = [];
2958
- const seen = /* @__PURE__ */ new Set();
2959
- for (const root of roots) {
2960
- for (const skill of await discoverSkills(root, {
2961
- onInvalidSkill: (info) => {
2962
- diag(`[theokit-sdk] skill ${info.name} skipped (${info.code}): ${info.message}
2963
- `);
2964
- }
2965
- })) {
2966
- if (seen.has(skill.name)) continue;
2967
- seen.add(skill.name);
2968
- discovered.push(skill);
2969
- }
2970
- }
2971
- this.skills = this.mergeInline(discovered);
2972
- }
2973
- /** M22 — merge inline skills over discovered ones; inline wins on a name conflict. */
2974
- mergeInline(discovered) {
2975
- if (this.inline === void 0 || this.inline.length === 0) return discovered;
2976
- const inlineNames = new Set(this.inline.map((s) => s.name));
2977
- return [...discovered.filter((s) => !inlineNames.has(s.name)), ...this.inline];
2978
- }
2979
- list() {
2980
- return Promise.resolve(this.skills);
2981
- }
2982
- /**
2983
- * SE20 — resolve a skill by name INCLUDING its body. Inline (`createSkill`)
2984
- * skills carry `instructions` on the object; filesystem skills read the body
2985
- * from their `source` SKILL.md (frontmatter stripped). `undefined` when no
2986
- * enabled skill matches (malformed skills were already excluded at discovery).
2987
- */
2988
- async get(name) {
2989
- const skill = this.skills.find((s) => s.name === name);
2990
- if (skill === void 0) return void 0;
2991
- const instructions = typeof skill.instructions === "string" ? skill.instructions : stripSkillFrontmatter(await readFile(skill.source, "utf8"));
2992
- const references = skill.references;
2993
- return {
2994
- name: skill.name,
2995
- description: skill.description,
2996
- instructions,
2997
- ...references !== void 0 ? { references } : {}
2998
- };
2999
- }
3000
- };
3001
2979
 
3002
2980
  // src/internal/runtime/system-prompt/local-assembly.ts
3003
2981
  async function resolveSendSkills(inputs, userText, memoryFacts) {
@@ -3017,7 +2995,8 @@ async function resolveSendSkills(inputs, userText, memoryFacts) {
3017
2995
  settings.enabled,
3018
2996
  inputs.settingSourcesIncludeProject,
3019
2997
  settings.skillsDir,
3020
- settings.inline
2998
+ settings.inline,
2999
+ resolveCompatSources(inputs.options, inputs.workspaceCwd)
3021
3000
  );
3022
3001
  await manager.initialize();
3023
3002
  return { manager, autoInject: settings.autoInject ?? true };
@@ -3033,7 +3012,14 @@ async function buildSystemPromptContext(inputs, userText, memoryFacts, manager =
3033
3012
  memory: memoryFacts.map((fact) => ({ text: fact.text }))
3034
3013
  };
3035
3014
  }
3036
- async function buildAssemblyContext(inputs, userText, baseSystemPrompt, memoryFacts, activeMemorySummary, contextPaths) {
3015
+ async function buildAssemblyContext({
3016
+ inputs,
3017
+ userText,
3018
+ baseSystemPrompt,
3019
+ memoryFacts,
3020
+ activeMemorySummary,
3021
+ contextPaths
3022
+ }) {
3037
3023
  const resolved = await resolveSendSkills(inputs, userText, memoryFacts);
3038
3024
  const baseCtx = await buildSystemPromptContext(inputs, userText, memoryFacts, resolved.manager);
3039
3025
  const assemblyCtx = {
@@ -3056,16 +3042,9 @@ async function buildAssemblyContext(inputs, userText, baseSystemPrompt, memoryFa
3056
3042
  }
3057
3043
  return assemblyCtx;
3058
3044
  }
3059
- async function assembleSystemPromptForSend(inputs, userText, baseSystemPrompt, memoryFacts, activeMemorySummary, contextPaths) {
3060
- const ctx = await buildAssemblyContext(
3061
- inputs,
3062
- userText,
3063
- baseSystemPrompt,
3064
- memoryFacts,
3065
- activeMemorySummary,
3066
- contextPaths
3067
- );
3068
- return inputs.systemPromptPipeline.assemble(ctx);
3045
+ async function assembleSystemPromptForSend(request) {
3046
+ const ctx = await buildAssemblyContext(request);
3047
+ return request.inputs.systemPromptPipeline.assemble(ctx);
3069
3048
  }
3070
3049
 
3071
3050
  // src/internal/runtime/system-prompt/safe-call.ts
@@ -3471,15 +3450,16 @@ var arizeAdapter = {
3471
3450
  displayName: "Arize Phoenix",
3472
3451
  detect: () => safeRequire("arize-phoenix-otel") !== void 0,
3473
3452
  register: () => {
3474
- if (registeredHere) return;
3453
+ if (registeredHere) return "instrumented";
3475
3454
  const arize = safeRequire("arize-phoenix-otel");
3476
3455
  const otel = safeRequire("@opentelemetry/api");
3477
- if (arize === void 0 || otel === void 0) return;
3456
+ if (arize === void 0 || otel === void 0) return "not-wired";
3478
3457
  const provider = otel.trace.getTracerProvider();
3479
- if (provider.addSpanProcessor === void 0) return;
3458
+ if (provider.addSpanProcessor === void 0) return "not-wired";
3480
3459
  const processor = new arize.PhoenixSpanProcessor();
3481
3460
  provider.addSpanProcessor(processor);
3482
3461
  registeredHere = true;
3462
+ return "instrumented";
3483
3463
  }
3484
3464
  };
3485
3465
 
@@ -3490,10 +3470,11 @@ var braintrustAdapter = {
3490
3470
  displayName: "Braintrust",
3491
3471
  detect: () => safeRequire("braintrust") !== void 0,
3492
3472
  register: () => {
3493
- if (registeredHere2) return;
3494
- const bt = safeRequire("braintrust");
3495
- if (bt === void 0) return;
3473
+ if (registeredHere2) return "vendor-auto-instruments";
3474
+ const mod = safeRequire("braintrust");
3475
+ if (mod === void 0) return "not-wired";
3496
3476
  registeredHere2 = true;
3477
+ return "vendor-auto-instruments";
3497
3478
  }
3498
3479
  };
3499
3480
 
@@ -3504,11 +3485,12 @@ var datadogAdapter = {
3504
3485
  displayName: "Datadog",
3505
3486
  detect: () => safeRequire("dd-trace") !== void 0,
3506
3487
  register: () => {
3507
- if (registeredHere3) return;
3488
+ if (registeredHere3) return "instrumented";
3508
3489
  const dd = safeRequire("dd-trace");
3509
- if (dd === void 0) return;
3490
+ if (dd === void 0) return "not-wired";
3510
3491
  dd.init({ logInjection: true });
3511
3492
  registeredHere3 = true;
3493
+ return "instrumented";
3512
3494
  }
3513
3495
  };
3514
3496
 
@@ -3519,32 +3501,33 @@ var langfuseAdapter = {
3519
3501
  displayName: "Langfuse",
3520
3502
  detect: () => safeRequire("@langfuse/node") !== void 0,
3521
3503
  register: () => {
3522
- if (registeredHere4) return;
3504
+ if (registeredHere4) return "instrumented";
3523
3505
  const lf = safeRequire("@langfuse/node");
3524
3506
  const otel = safeRequire("@opentelemetry/api");
3525
- if (lf === void 0 || otel === void 0) return;
3507
+ if (lf === void 0 || otel === void 0) return "not-wired";
3526
3508
  const provider = otel.trace.getTracerProvider();
3527
3509
  if (provider.addSpanProcessor === void 0) {
3528
- return;
3510
+ return "not-wired";
3529
3511
  }
3530
3512
  const existing = provider.getActiveSpanProcessor?.();
3531
3513
  if (typeof existing === "object" && existing !== null) {
3532
3514
  const ctor = existing.constructor?.name ?? "";
3533
3515
  if (ctor.toLowerCase().includes("langfuse")) {
3534
3516
  registeredHere4 = true;
3535
- return;
3517
+ return "instrumented";
3536
3518
  }
3537
3519
  }
3538
3520
  if (lf.LangfuseSpanProcessor === void 0) {
3539
3521
  diag(
3540
3522
  "[theokit-sdk] @langfuse/node detected but LangfuseSpanProcessor not found (v2?). Use Langfuse v3+ for auto-instrumentation.\n"
3541
3523
  );
3542
- return;
3524
+ return "not-wired";
3543
3525
  }
3544
3526
  const client = new lf.Langfuse();
3545
3527
  const processor = new lf.LangfuseSpanProcessor({ langfuse: client });
3546
3528
  provider.addSpanProcessor(processor);
3547
3529
  registeredHere4 = true;
3530
+ return "instrumented";
3548
3531
  }
3549
3532
  };
3550
3533
 
@@ -3555,10 +3538,11 @@ var langsmithAdapter = {
3555
3538
  displayName: "LangSmith",
3556
3539
  detect: () => safeRequire("langsmith") !== void 0,
3557
3540
  register: () => {
3558
- if (registeredHere5) return;
3559
- const ls = safeRequire("langsmith");
3560
- if (ls === void 0) return;
3541
+ if (registeredHere5) return "vendor-auto-instruments";
3542
+ const mod = safeRequire("langsmith");
3543
+ if (mod === void 0) return "not-wired";
3561
3544
  registeredHere5 = true;
3545
+ return "vendor-auto-instruments";
3562
3546
  }
3563
3547
  };
3564
3548
 
@@ -3572,19 +3556,19 @@ var posthogAdapter = {
3572
3556
  displayName: "PostHog",
3573
3557
  detect: () => safeRequire("posthog-node") !== void 0,
3574
3558
  register: () => {
3575
- if (registeredHere6) return;
3559
+ if (registeredHere6) return "instrumented";
3576
3560
  const ph = safeRequire("posthog-node");
3577
3561
  const otel = safeRequire("@opentelemetry/api");
3578
- if (ph === void 0 || otel === void 0) return;
3562
+ if (ph === void 0 || otel === void 0) return "not-wired";
3579
3563
  const key = presentEnv(process.env.POSTHOG_API_KEY) ?? presentEnv(process.env.POSTHOG_PROJECT_API_KEY);
3580
3564
  if (typeof key !== "string" || key.length === 0) {
3581
- return;
3565
+ return "not-wired";
3582
3566
  }
3583
3567
  const client = new ph.PostHog(key, {
3584
3568
  host: presentEnv(process.env.POSTHOG_HOST) ?? "https://us.i.posthog.com"
3585
3569
  });
3586
3570
  const provider = otel.trace.getTracerProvider();
3587
- if (provider.addSpanProcessor === void 0) return;
3571
+ if (provider.addSpanProcessor === void 0) return "not-wired";
3588
3572
  const processor = {
3589
3573
  onStart: () => {
3590
3574
  },
@@ -3613,6 +3597,7 @@ var posthogAdapter = {
3613
3597
  };
3614
3598
  provider.addSpanProcessor(processor);
3615
3599
  registeredHere6 = true;
3600
+ return "instrumented";
3616
3601
  }
3617
3602
  };
3618
3603
 
@@ -3623,11 +3608,11 @@ var sentryAdapter = {
3623
3608
  displayName: "Sentry",
3624
3609
  detect: () => safeRequire("@sentry/node") !== void 0,
3625
3610
  register: () => {
3626
- if (registeredHere7) return;
3611
+ if (registeredHere7) return "instrumented";
3627
3612
  const sentry = safeRequire("@sentry/node");
3628
- if (sentry === void 0) return;
3613
+ if (sentry === void 0) return "not-wired";
3629
3614
  if (typeof sentry.addEventProcessor !== "function") {
3630
- return;
3615
+ return "not-wired";
3631
3616
  }
3632
3617
  sentry.addEventProcessor((event) => {
3633
3618
  const otel = safeRequire("@opentelemetry/api");
@@ -3643,10 +3628,16 @@ var sentryAdapter = {
3643
3628
  return event;
3644
3629
  });
3645
3630
  registeredHere7 = true;
3631
+ return "instrumented";
3646
3632
  }
3647
3633
  };
3648
3634
 
3649
3635
  // src/internal/telemetry/adapter-registry.ts
3636
+ var WIRING_PROSE = {
3637
+ instrumented: "auto-instrumented",
3638
+ "vendor-auto-instruments": "loaded; the vendor instruments itself from its env var",
3639
+ "not-wired": "detected but nothing was wired"
3640
+ };
3650
3641
  var ALL_ADAPTERS = [
3651
3642
  langfuseAdapter,
3652
3643
  sentryAdapter,
@@ -3656,7 +3647,7 @@ var ALL_ADAPTERS = [
3656
3647
  arizeAdapter,
3657
3648
  braintrustAdapter
3658
3649
  ];
3659
- var registered = /* @__PURE__ */ new Set();
3650
+ var registered = /* @__PURE__ */ new Map();
3660
3651
  function tryAutoRegisterAdapters(settings) {
3661
3652
  if (settings?.enabled !== true) return;
3662
3653
  if (settings.autoDetect === false) return;
@@ -3665,18 +3656,21 @@ function tryAutoRegisterAdapters(settings) {
3665
3656
  if (registered.has(adapter.moduleName)) continue;
3666
3657
  if (disabled.has(adapter.displayName.toLowerCase())) continue;
3667
3658
  if (!adapter.detect()) continue;
3668
- try {
3669
- adapter.register();
3670
- registered.add(adapter.moduleName);
3671
- diag(`[theokit-sdk] telemetry: ${adapter.displayName} auto-instrumented.
3659
+ registerOne(adapter);
3660
+ }
3661
+ }
3662
+ function registerOne(adapter) {
3663
+ try {
3664
+ const wiring = adapter.register();
3665
+ registered.set(adapter.moduleName, wiring);
3666
+ diag(`[theokit-sdk] telemetry: ${adapter.displayName} ${WIRING_PROSE[wiring]}.
3672
3667
  `);
3673
- } catch (cause) {
3674
- const message = cause instanceof Error ? cause.message : String(cause);
3675
- diag(
3676
- `[theokit-sdk] telemetry: ${adapter.displayName} detected but failed to register: ${message}
3668
+ } catch (cause) {
3669
+ const message = cause instanceof Error ? cause.message : String(cause);
3670
+ diag(
3671
+ `[theokit-sdk] telemetry: ${adapter.displayName} detected but failed to register: ${message}
3677
3672
  `
3678
- );
3679
- }
3673
+ );
3680
3674
  }
3681
3675
  }
3682
3676
 
@@ -4139,8 +4133,8 @@ var FileContextManager = class {
4139
4133
  }
4140
4134
  };
4141
4135
  async function loadContextConfig(cwd) {
4142
- const mdDir = join(cwd, ".theokit", "context");
4143
- const jsonPath = join(cwd, ".theokit", "context.json");
4136
+ const mdDir = join(theokitConfigRoot(cwd), "context");
4137
+ const jsonPath = join(theokitConfigRoot(cwd), "context.json");
4144
4138
  const mdEntities = await loadMarkdownEntities({
4145
4139
  dir: mdDir,
4146
4140
  schema: ContextSourceFrontmatterSchema,
@@ -4161,7 +4155,10 @@ async function loadContextConfig(cwd) {
4161
4155
  if (!existsSync(jsonPath)) return { sources: [] };
4162
4156
  warnOnce(
4163
4157
  "context-json-deprecated",
4164
- "[theokit-sdk] .theokit/context.json is deprecated; migrate to .theokit/context/<name>.md via theokit-migrate-config"
4158
+ // Names no command: `theokit-migrate-config` was unpublished with the `bin` entry, and a warning
4159
+ // that tells you to run something the package does not ship is worse than one that tells you
4160
+ // what the target looks like.
4161
+ "[theokit-sdk] .theokit/context.json is deprecated; move each entry to its own file under .theokit/context/<name>.md"
4165
4162
  );
4166
4163
  let raw;
4167
4164
  try {
@@ -4270,20 +4267,22 @@ var PluginFrontmatterSchema = z.object({
4270
4267
  entry: z.string().min(1).optional()
4271
4268
  });
4272
4269
 
4273
- // src/internal/runtime/plugins/plugins-manager.ts
4270
+ // src/internal/runtime/plugin-loader/plugins-manager.ts
4274
4271
  var PluginsManager = class {
4275
- constructor(cwd, enabled, settingSourcesIncludePlugins, cloud, localPaths) {
4272
+ constructor(cwd, enabled, settingSourcesIncludePlugins, cloud, localPaths, compatSources = []) {
4276
4273
  this.cwd = cwd;
4277
4274
  this.enabled = enabled;
4278
4275
  this.settingSourcesIncludePlugins = settingSourcesIncludePlugins;
4279
4276
  this.cloud = cloud;
4280
4277
  this.localPaths = localPaths;
4278
+ this.compatSources = compatSources;
4281
4279
  }
4282
4280
  cwd;
4283
4281
  enabled;
4284
4282
  settingSourcesIncludePlugins;
4285
4283
  cloud;
4286
4284
  localPaths;
4285
+ compatSources;
4287
4286
  plugins = [];
4288
4287
  async initialize() {
4289
4288
  this.assertCloudRules();
@@ -4295,7 +4294,7 @@ var PluginsManager = class {
4295
4294
  }
4296
4295
  async refresh() {
4297
4296
  this.plugins = [];
4298
- for (const pluginsRoot of pluginBundleRoots(this.cwd)) {
4297
+ for (const pluginsRoot of pluginBundleRoots(this.cwd, this.compatSources)) {
4299
4298
  await this.refreshRoot(pluginsRoot);
4300
4299
  }
4301
4300
  }
@@ -4307,7 +4306,7 @@ var PluginsManager = class {
4307
4306
  const folderName = entry.name;
4308
4307
  const cliPath = join(pluginsRoot, folderName, ".claude-plugin", "plugin.json");
4309
4308
  if (existsSync(cliPath)) {
4310
- const cliMetadata = await loadPluginManifestFromJson(cliPath, folderName);
4309
+ const cliMetadata = await loadPluginManifestFromJson(this.cwd, cliPath, folderName);
4311
4310
  if (this.enabled === void 0 || this.enabled.includes(cliMetadata.name)) {
4312
4311
  this.plugins.push(cliMetadata);
4313
4312
  }
@@ -4315,7 +4314,7 @@ var PluginsManager = class {
4315
4314
  }
4316
4315
  const mdPath = join(pluginsRoot, folderName, "PLUGIN.md");
4317
4316
  const jsonPath = join(pluginsRoot, folderName, "plugin.json");
4318
- const metadata = existsSync(mdPath) ? await loadPluginManifestFromMarkdown(pluginsRoot, folderName) : await loadPluginManifestFromJson(jsonPath, folderName);
4317
+ const metadata = existsSync(mdPath) ? await loadPluginManifestFromMarkdown(this.cwd, pluginsRoot, folderName) : await loadPluginManifestFromJson(this.cwd, jsonPath, folderName);
4319
4318
  if (existsSync(mdPath) && existsSync(jsonPath)) {
4320
4319
  warnOnce(
4321
4320
  `plugin-${folderName}-both`,
@@ -4325,11 +4324,12 @@ var PluginsManager = class {
4325
4324
  if (!existsSync(mdPath) && existsSync(jsonPath)) {
4326
4325
  warnOnce(
4327
4326
  "plugin-json-deprecated",
4328
- "[theokit-sdk] plugin.json manifests are deprecated; migrate to PLUGIN.md via theokit-migrate-config"
4327
+ // Same reason as the context.json warning: the CLI it used to name is no longer published.
4328
+ "[theokit-sdk] plugin.json manifests are deprecated; replace each with a PLUGIN.md"
4329
4329
  );
4330
4330
  }
4331
4331
  if (this.enabled === void 0 || this.enabled.includes(metadata.name)) {
4332
- await this.assertEntryFileExists(metadata, folderName);
4332
+ await this.assertEntryFileExists(metadata, folderName, pluginsRoot);
4333
4333
  this.plugins.push(metadata);
4334
4334
  }
4335
4335
  }
@@ -4337,10 +4337,10 @@ var PluginsManager = class {
4337
4337
  list() {
4338
4338
  return Promise.resolve(this.plugins);
4339
4339
  }
4340
- async assertEntryFileExists(metadata, folderName) {
4340
+ async assertEntryFileExists(metadata, folderName, pluginsRoot) {
4341
4341
  const entry = metadata.entry;
4342
4342
  if (entry === void 0) return;
4343
- const pluginRoot = join(this.cwd, ".theokit", "plugins", folderName);
4343
+ const pluginRoot = join(pluginsRoot, folderName);
4344
4344
  const entryPath = safePathJoin(pluginRoot, entry);
4345
4345
  try {
4346
4346
  await readFile(entryPath, "utf8");
@@ -4376,7 +4376,7 @@ var PluginsManager = class {
4376
4376
  }
4377
4377
  }
4378
4378
  };
4379
- async function loadPluginManifestFromJson(manifestPath, folderName) {
4379
+ async function loadPluginManifestFromJson(cwd, manifestPath, folderName) {
4380
4380
  let raw;
4381
4381
  try {
4382
4382
  raw = await readFile(manifestPath, "utf8");
@@ -4404,12 +4404,12 @@ async function loadPluginManifestFromJson(manifestPath, folderName) {
4404
4404
  const name = typeof record.name === "string" ? record.name : folderName;
4405
4405
  const version = typeof record.version === "string" ? record.version : "0.0.0";
4406
4406
  const capabilities = Array.isArray(record.capabilities) ? record.capabilities.filter((cap) => typeof cap === "string") : [];
4407
- const source = manifestPath.slice(manifestPath.indexOf(".theokit/"));
4407
+ const source = relative(cwd, manifestPath);
4408
4408
  const metadata = { name, version, capabilities, source };
4409
4409
  if (typeof record.entry === "string") metadata.entry = record.entry;
4410
4410
  return metadata;
4411
4411
  }
4412
- async function loadPluginManifestFromMarkdown(pluginsRoot, folderName) {
4412
+ async function loadPluginManifestFromMarkdown(cwd, pluginsRoot, folderName) {
4413
4413
  const mdPath = join(pluginsRoot, folderName, "PLUGIN.md");
4414
4414
  let raw;
4415
4415
  try {
@@ -4435,7 +4435,7 @@ async function loadPluginManifestFromMarkdown(pluginsRoot, folderName) {
4435
4435
  });
4436
4436
  }
4437
4437
  const fm = entity.frontmatter;
4438
- const source = mdPath.slice(mdPath.indexOf(".theokit/"));
4438
+ const source = relative(cwd, mdPath);
4439
4439
  const metadata = {
4440
4440
  name: fm.name ?? folderName,
4441
4441
  version: fm.version ?? "0.0.0",
@@ -4462,58 +4462,102 @@ function registerLocalAgent(args) {
4462
4462
  status: "finished"
4463
4463
  });
4464
4464
  }
4465
+ function buildContext(args, out) {
4466
+ if (args.options.context === void 0) return;
4467
+ out.context = new FileContextManager(
4468
+ args.workspaceCwd,
4469
+ args.options.context,
4470
+ args.settingSourcesIncludeProject
4471
+ );
4472
+ }
4473
+ function buildProviders(args, out) {
4474
+ const providerCount = (args.options.providers?.routes?.length ?? 0) + enabledPluginNames(args.options.plugins).length;
4475
+ if (providerCount === 0 && args.options.providers === void 0) return;
4476
+ out.providers = new ProvidersManagerImpl(
4477
+ normalizeModel(args.options.model),
4478
+ args.options.providers,
4479
+ args.options.plugins
4480
+ );
4481
+ }
4482
+ function buildSkills(args, out) {
4483
+ if (args.options.skills === void 0 && !args.settingSourcesIncludeProject) return;
4484
+ const staticSkills = typeof args.options.skills === "function" ? void 0 : args.options.skills;
4485
+ out.skillsManager = new SkillsManager(
4486
+ args.workspaceCwd,
4487
+ staticSkills?.enabled,
4488
+ args.settingSourcesIncludeProject,
4489
+ // M22 — custom skills directory + inline (code-defined) skills.
4490
+ staticSkills?.skillsDir,
4491
+ staticSkills?.inline,
4492
+ // #524 — the same declaration the per-send manager reads. Omitting it here would make
4493
+ // `agent.skills` disagree with the system prompt about which skills exist.
4494
+ resolveCompatSources(args.options, args.workspaceCwd)
4495
+ );
4496
+ const localSkills = out.skillsManager;
4497
+ out.skills = {
4498
+ // Project to the public shape (name + description only). Inline skills carry
4499
+ // their body + references on the object; `list()` must never leak them —
4500
+ // the body is reachable exclusively through `get()`.
4501
+ list: async () => (await localSkills.list()).map((s) => ({
4502
+ name: s.name,
4503
+ description: s.description,
4504
+ // The PATH, never the body. Dropping it with the body answered a question nobody asked and
4505
+ // silenced the one #524 is about: which root did this skill come from.
4506
+ ...s.source === void 0 ? {} : { source: s.source }
4507
+ })),
4508
+ get: (name) => localSkills.get(name)
4509
+ };
4510
+ }
4511
+ function buildPlugins(args, out) {
4512
+ if (args.options.plugins === void 0 && !args.settingSourcesIncludePlugins) return;
4513
+ out.pluginsManager = new PluginsManager(
4514
+ args.workspaceCwd,
4515
+ // The array (code-`Plugin`) form has no named-enable list; `undefined`
4516
+ // here preserves "no filter / load all file-discovered plugins".
4517
+ asPluginsSettings(args.options.plugins)?.enabled,
4518
+ args.settingSourcesIncludePlugins,
4519
+ false,
4520
+ void 0,
4521
+ resolveCompatSources(args.options, args.workspaceCwd)
4522
+ );
4523
+ const localPlugins = out.pluginsManager;
4524
+ out.plugins = { list: () => localPlugins.list() };
4525
+ }
4465
4526
  function bootstrapSubmanagers(args) {
4466
4527
  const out = {};
4467
- if (args.options.context !== void 0) {
4468
- out.context = new FileContextManager(
4469
- args.workspaceCwd,
4470
- args.options.context,
4471
- args.settingSourcesIncludeProject
4472
- );
4473
- }
4474
- const providerCount = (args.options.providers?.routes?.length ?? 0) + enabledPluginNames(args.options.plugins).length;
4475
- if (providerCount > 0 || args.options.providers !== void 0) {
4476
- out.providers = new ProvidersManagerImpl(
4477
- normalizeModel(args.options.model),
4478
- args.options.providers,
4479
- args.options.plugins
4480
- );
4481
- }
4482
- if (args.options.skills !== void 0 || args.settingSourcesIncludeProject) {
4483
- const staticSkills = typeof args.options.skills === "function" ? void 0 : args.options.skills;
4484
- out.skillsManager = new SkillsManager(
4485
- args.workspaceCwd,
4486
- staticSkills?.enabled,
4487
- args.settingSourcesIncludeProject,
4488
- // M22 — custom skills directory + inline (code-defined) skills.
4489
- staticSkills?.skillsDir,
4490
- staticSkills?.inline
4491
- );
4492
- const localSkills = out.skillsManager;
4493
- out.skills = {
4494
- // Project to the public shape (name + description only). Inline skills carry
4495
- // their body + references on the object; `list()` must never leak them —
4496
- // the body is reachable exclusively through `get()`.
4497
- list: async () => (await localSkills.list()).map((s) => ({ name: s.name, description: s.description })),
4498
- get: (name) => localSkills.get(name)
4499
- };
4500
- }
4501
- if (args.options.plugins !== void 0 || args.settingSourcesIncludePlugins) {
4502
- out.pluginsManager = new PluginsManager(
4503
- args.workspaceCwd,
4504
- // The array (code-`Plugin`) form has no named-enable list; `undefined`
4505
- // here preserves "no filter / load all file-discovered plugins".
4506
- asPluginsSettings(args.options.plugins)?.enabled,
4507
- args.settingSourcesIncludePlugins,
4508
- false,
4509
- void 0
4510
- );
4511
- const localPlugins = out.pluginsManager;
4512
- out.plugins = { list: () => localPlugins.list() };
4513
- }
4528
+ buildContext(args, out);
4529
+ buildProviders(args, out);
4530
+ buildSkills(args, out);
4531
+ buildPlugins(args, out);
4514
4532
  return out;
4515
4533
  }
4516
4534
 
4535
+ // src/internal/local-agent/local-agent-capabilities.ts
4536
+ var UNSUPPORTED_OPS = /* @__PURE__ */ new Set(["downloadArtifact", "listArtifacts"]);
4537
+ function localAgentSupports(operation) {
4538
+ return !UNSUPPORTED_OPS.has(operation);
4539
+ }
4540
+ function localAgentUnsupportedReason(operation) {
4541
+ return localAgentSupports(operation) ? void 0 : `Operation "${operation}" is not available on a local agent.`;
4542
+ }
4543
+ function localAgentListArtifacts() {
4544
+ return Promise.resolve([]);
4545
+ }
4546
+ function localAgentDownloadArtifact() {
4547
+ return Promise.reject(
4548
+ new UnsupportedRunOperationError(
4549
+ "Artifacts are not supported for local agents",
4550
+ "downloadArtifact"
4551
+ )
4552
+ );
4553
+ }
4554
+ var localAgentCapabilities = {
4555
+ supports: localAgentSupports,
4556
+ unsupportedReason: localAgentUnsupportedReason,
4557
+ listArtifacts: localAgentListArtifacts,
4558
+ downloadArtifact: localAgentDownloadArtifact
4559
+ };
4560
+
4517
4561
  // src/internal/runtime/registry/run-registry.ts
4518
4562
  var runs = /* @__PURE__ */ new Map();
4519
4563
  var runsByAgent = /* @__PURE__ */ new Map();
@@ -4949,10 +4993,7 @@ function buildUserContent(text, images) {
4949
4993
  return content;
4950
4994
  }
4951
4995
  function buildAgentRef(inputs) {
4952
- return {
4953
- agentId: inputs.agentId,
4954
- model: inputs.model
4955
- };
4996
+ return { agentId: inputs.agentId, model: inputs.model };
4956
4997
  }
4957
4998
  async function initLoopContext(inputs) {
4958
4999
  let memoryProviderHandle;
@@ -4961,7 +5002,8 @@ async function initLoopContext(inputs) {
4961
5002
  memoryProviderHandle = await inputs.memoryProvider.init({
4962
5003
  cwd: process.cwd()
4963
5004
  });
4964
- } catch {
5005
+ } catch (cause) {
5006
+ reportMemoryDegraded("init", cause, inputs.runEventSink);
4965
5007
  memoryProviderHandle = void 0;
4966
5008
  }
4967
5009
  }
@@ -4990,7 +5032,8 @@ async function initLoopContext(inputs) {
4990
5032
  let providerTools = [];
4991
5033
  try {
4992
5034
  providerTools = inputs.memoryProvider.buildTools(memoryProviderHandle, buildAgentRef(inputs));
4993
- } catch {
5035
+ } catch (cause) {
5036
+ reportMemoryDegraded("buildTools", cause, inputs.runEventSink);
4994
5037
  providerTools = [];
4995
5038
  }
4996
5039
  for (const providerTool of providerTools) {
@@ -5027,7 +5070,8 @@ async function initLoopContext(inputs) {
5027
5070
  if (passResult.systemPromptAdditions !== void 0 && passResult.systemPromptAdditions.length > 0) {
5028
5071
  memorySystemPromptAdditions = passResult.systemPromptAdditions;
5029
5072
  }
5030
- } catch {
5073
+ } catch (cause) {
5074
+ reportMemoryDegraded("activePass", cause, inputs.runEventSink);
5031
5075
  memorySystemPromptAdditions = void 0;
5032
5076
  }
5033
5077
  }
@@ -5049,6 +5093,12 @@ async function initLoopContext(inputs) {
5049
5093
  ...memorySystemPromptAdditions !== void 0 ? { memorySystemPromptAdditions } : {}
5050
5094
  };
5051
5095
  }
5096
+ function reportMemoryDegraded(stage, cause, sink) {
5097
+ const message = cause instanceof Error ? cause.message : String(cause);
5098
+ diag(`[theokit-sdk] memory ${stage} failed \u2014 continuing without it: ${message}
5099
+ `);
5100
+ emitRunEvent(sink, { type: "memory_degraded", stage, message });
5101
+ }
5052
5102
  async function safeListTools(client, serverName, sink) {
5053
5103
  try {
5054
5104
  const listed = await client.listTools();
@@ -5102,1215 +5152,1265 @@ async function collectTools(mcp, withheld, sink) {
5102
5152
  function sanitize(name) {
5103
5153
  return name.replace(/[^a-zA-Z0-9-]+/g, "_").replace(/^[_-]+|[_-]+$/g, "");
5104
5154
  }
5105
- var KEY_PREFIX = "theokit-";
5106
- var KEY_HEX_LENGTH = 32;
5107
- function derivePromptCacheKey(sessionId) {
5108
- if (sessionId === void 0 || sessionId.trim().length === 0) return void 0;
5109
- const digest = createHash("sha256").update(sessionId, "utf8").digest("hex");
5110
- return `${KEY_PREFIX}${digest.slice(0, KEY_HEX_LENGTH)}`;
5111
- }
5112
-
5113
- // src/internal/tool-dispatch/strip-think.ts
5114
- var THINK_PATTERN = /<think>[\s\S]*?<\/think>\s*/g;
5115
- function stripThinkBlocks(content) {
5116
- const matches = [...content.matchAll(THINK_PATTERN)];
5117
- const thinking = matches.length > 0 ? matches.map((m) => m[0]).join("\n").replace(/<\/?think>/g, "").trim() : null;
5118
- const visible = content.replace(THINK_PATTERN, "").trim();
5119
- return { visible, thinking };
5120
- }
5121
-
5122
- // src/internal/agent-loop/loop-llm-stream.ts
5123
- function resolveSystemPromptWithMemoryAdditions(systemPrompt, additions) {
5124
- if (additions === void 0 || additions.length === 0) return systemPrompt;
5125
- if (systemPrompt === void 0 || systemPrompt.length === 0) return additions;
5126
- return `${systemPrompt}
5127
5155
 
5128
- ${additions}`;
5129
- }
5130
- function toLlmTool(tool) {
5131
- return { name: tool.name, description: tool.description, inputSchema: tool.inputSchema };
5132
- }
5133
- function reasoningEffortFromParams(params) {
5134
- const thinking = params?.find((p) => p.id === "thinking");
5135
- return thinking !== void 0 && thinking.value.length > 0 ? thinking.value : void 0;
5136
- }
5137
- function emitLlmMetrics(inputs, result, startAt) {
5138
- inputs.telemetry?.recordHistogram(HISTOGRAM_NAMES.LLM_CALL_DURATION_MS, Date.now() - startAt, {
5139
- provider: inputs.llm.name
5140
- });
5141
- if (result.inputTokens === void 0 && result.outputTokens === void 0) {
5142
- inputs.telemetry?.recordHistogram(HISTOGRAM_NAMES.LLM_USAGE_MISSING, 1, {
5143
- provider: inputs.llm.name
5144
- });
5145
- diag(
5146
- `[theokit-sdk] llm usage missing from ${inputs.llm.name} finish \u2014 budget may undercount
5147
- `
5148
- );
5149
- return;
5150
- }
5151
- inputs.telemetry?.recordHistogram(
5152
- HISTOGRAM_NAMES.LLM_TOKENS,
5153
- (result.inputTokens ?? 0) + (result.outputTokens ?? 0),
5154
- { provider: inputs.llm.name }
5155
- );
5156
- }
5157
- async function streamLlmTurn(inputs, ctx) {
5158
- const llmSpan = inputs.telemetry?.startChildSpan(ctx.sendSpan, "llm.call", {
5159
- "model.id": inputs.model.id ?? "auto",
5160
- provider: inputs.llm.name
5161
- });
5162
- const startAt = Date.now();
5163
- const signal = inputs.signal ?? new AbortController().signal;
5164
- const generator = inputs.llm.stream(
5165
- {
5166
- model: inputs.model.id ?? "auto",
5167
- ...(() => {
5168
- const effective = resolveSystemPromptWithMemoryAdditions(
5169
- inputs.systemPrompt,
5170
- ctx.memorySystemPromptAdditions
5171
- );
5172
- return effective !== void 0 ? { system: effective } : {};
5173
- })(),
5174
- // issue #47: forward the reasoning effort from ModelSelection.params (the `thinking` param)
5175
- // so the provider produces reasoning. Absent param ⇒ no `reasoning` field (bare request).
5176
- ...(() => {
5177
- const effort = reasoningEffortFromParams(inputs.model.params);
5178
- return effort !== void 0 ? { reasoning: { effort } } : {};
5179
- })(),
5180
- // Step-cap force-close: forward the per-run tool gate (`"none"` on a ceiling round forces a
5181
- // text close even though tools are advertised). Absent ⇒ provider default (auto).
5182
- ...inputs.toolChoice !== void 0 ? { toolChoice: inputs.toolChoice } : {},
5183
- // usetheokit/theokit-sdk#383 — the prompt-cache key, derived HERE and from `inputs.agentId`
5184
- // because this is the one place that sees the session identity on every round. `agentId` is
5185
- // the run's session identity (`Agent.getOrCreate(sessionId)`), so the derived key is identical
5186
- // on round 1 and round 12 of a turn, identical on turn 2 of the same session, and different
5187
- // for a different session. Deriving it per round from a stable input is what makes it a cache
5188
- // key; minting one anywhere that runs more than once per session would not be.
5189
- ...(() => {
5190
- const key = derivePromptCacheKey(inputs.agentId);
5191
- return key !== void 0 ? { promptCacheKey: key } : {};
5192
- })(),
5193
- messages: ctx.messages,
5194
- tools: ctx.tools.map(toLlmTool)
5156
+ // src/internal/budget/pricing-data.json
5157
+ var pricing_data_default = {
5158
+ _meta: {
5159
+ pricingVersion: "litellm-2026-05-snapshot"},
5160
+ models: {
5161
+ "anthropic/claude-opus-4-7": {
5162
+ input: 5,
5163
+ output: 25,
5164
+ cacheRead: 0.5,
5165
+ cacheWrite: 6.25
5195
5166
  },
5196
- signal
5197
- );
5198
- const collected = await collectLlmEvents(generator, inputs, ctx);
5199
- if (collected.errored || collected.finishValue === void 0) {
5200
- llmSpan?.setAttribute("stopReason", "error");
5201
- llmSpan?.end();
5202
- return {
5203
- text: collected.accumulatedText,
5204
- toolCalls: [],
5205
- stopReason: "error",
5206
- errored: true
5207
- };
5208
- }
5209
- const result = collected.finishValue.value;
5210
- llmSpan?.setAttributes({
5211
- stopReason: result.stopReason,
5212
- inputTokens: result.inputTokens ?? 0,
5213
- outputTokens: result.outputTokens ?? 0
5214
- });
5215
- emitLlmMetrics(inputs, result, startAt);
5216
- llmSpan?.end();
5217
- const stripped = stripThinkBlocks(collected.accumulatedText);
5218
- const thinking = result.thinking ?? collected.thinking;
5219
- return {
5220
- text: stripped.visible,
5221
- toolCalls: result.toolCalls,
5222
- stopReason: result.stopReason,
5223
- errored: false,
5224
- inputTokens: result.inputTokens,
5225
- outputTokens: result.outputTokens,
5226
- cacheReadTokens: result.cacheReadTokens,
5227
- cacheWriteTokens: result.cacheWriteTokens,
5228
- reasoningTokens: result.reasoningTokens,
5229
- ...thinking !== void 0 ? { thinking } : {}
5230
- };
5231
- }
5232
- async function collectLlmEvents(generator, inputs, ctx) {
5233
- let errored = false;
5234
- let finishValue;
5235
- let thinking;
5236
- const partial = { text: "" };
5237
- try {
5238
- const result = await runCollectorLoop(generator, inputs, ctx, partial);
5239
- errored = result.errored;
5240
- finishValue = result.finishValue;
5241
- thinking = result.thinking;
5242
- } catch (cause) {
5243
- if (inputs.signal?.aborted === true) {
5244
- ctx.finalText = "[aborted]";
5245
- ctx.events.push(buildAssistantEvent(inputs, "[aborted]"));
5246
- } else {
5247
- registerLoopError(ctx, cause);
5248
- ctx.finalText = partial.text;
5249
- if (partial.text !== "") ctx.events.push(buildAssistantEvent(inputs, partial.text));
5250
- }
5251
- errored = true;
5252
- }
5253
- const accumulatedText = partial.text;
5254
- return {
5255
- accumulatedText,
5256
- errored,
5257
- finishValue,
5258
- ...thinking !== void 0 ? { thinking } : {}
5259
- };
5260
- }
5261
- function registerLoopError(ctx, cause) {
5262
- if (ctx.error !== void 0) return;
5263
- const rawMessage = cause?.message;
5264
- const message = typeof rawMessage === "string" ? rawMessage : cause instanceof Error ? cause.message : String(cause);
5265
- const metaCode = cause?.metadata?.code;
5266
- const rawCode = cause?.code;
5267
- const code = typeof metaCode === "string" ? metaCode : typeof rawCode === "string" ? rawCode : void 0;
5268
- ctx.error = code !== void 0 ? { message, code, cause } : { message, cause };
5269
- }
5270
- async function consumeStreamEvent(inputs, reasoning, event) {
5271
- if (event.type === "text_delta") {
5272
- const text = event.text ?? "";
5273
- await emitTextDeltaCallback(inputs, text);
5274
- return text;
5275
- }
5276
- if (event.type === "reasoning_delta") {
5277
- await consumeReasoningDelta(inputs, reasoning, {
5278
- text: event.text ?? "",
5279
- ...event.signature !== void 0 ? { signature: event.signature } : {}
5280
- });
5281
- }
5282
- return "";
5283
- }
5284
- async function runCollectorLoop(generator, inputs, ctx, partial) {
5285
- const reasoning = { text: "", startedAt: void 0, signature: void 0 };
5286
- let errored = false;
5287
- let finishValue;
5288
- let thinking;
5289
- try {
5290
- while (true) {
5291
- const next = await generator.next();
5292
- if (next.done === true) {
5293
- finishValue = next;
5294
- break;
5295
- }
5296
- if (next.value.type === "error") {
5297
- registerLoopError(ctx, next.value);
5298
- ctx.finalText = partial.text;
5299
- errored = true;
5300
- break;
5301
- }
5302
- partial.text += await consumeStreamEvent(inputs, reasoning, next.value);
5303
- }
5304
- } finally {
5305
- thinking = await finalizeReasoning(inputs, ctx, reasoning);
5306
- }
5307
- return { errored, finishValue, ...thinking !== void 0 ? { thinking } : {} };
5308
- }
5309
- async function consumeReasoningDelta(inputs, reasoning, delta) {
5310
- if (delta.signature !== void 0) reasoning.signature = delta.signature;
5311
- await accumulateReasoning(inputs, reasoning, delta.text);
5312
- }
5313
- async function accumulateReasoning(inputs, reasoning, text) {
5314
- if (reasoning.startedAt === void 0) reasoning.startedAt = Date.now();
5315
- reasoning.text += text;
5316
- await emitReasoningDeltaCallback(inputs, text);
5317
- }
5318
- async function finalizeReasoning(inputs, ctx, reasoning) {
5319
- if (reasoning.text.length === 0) return void 0;
5320
- const thinkingDurationMs = reasoning.startedAt === void 0 ? 0 : Date.now() - reasoning.startedAt;
5321
- ctx.events.push(
5322
- buildThinkingEvent(inputs, reasoning.text, thinkingDurationMs, reasoning.signature)
5323
- );
5324
- await emitThinkingCompletedCallback(inputs, thinkingDurationMs);
5325
- return {
5326
- type: "thinking",
5327
- text: reasoning.text,
5328
- ...reasoning.signature !== void 0 ? { signature: reasoning.signature } : {}
5329
- };
5330
- }
5331
- async function emitTextDeltaCallback(inputs, text) {
5332
- if (inputs.onDelta === void 0) return;
5333
- const cb = inputs.onDelta;
5334
- await safeCall(
5335
- () => cb({ update: { type: "text-delta", text } }),
5336
- void 0,
5337
- "SendOptions.onDelta"
5338
- );
5339
- }
5340
- async function emitReasoningDeltaCallback(inputs, text) {
5341
- if (inputs.onDelta === void 0) return;
5342
- const cb = inputs.onDelta;
5343
- await safeCall(
5344
- () => cb({ update: { type: "thinking-delta", text } }),
5345
- void 0,
5346
- "SendOptions.onDelta"
5347
- );
5348
- }
5349
- async function emitThinkingCompletedCallback(inputs, thinkingDurationMs) {
5350
- if (inputs.onDelta === void 0) return;
5351
- const cb = inputs.onDelta;
5352
- await safeCall(
5353
- () => cb({ update: { type: "thinking-completed", thinkingDurationMs } }),
5354
- void 0,
5355
- "SendOptions.onDelta"
5356
- );
5357
- }
5358
-
5359
- // src/internal/agent-loop/loop-thinking-steps.ts
5360
- function thinkingStep(thinking) {
5361
- return {
5362
- type: "thinkingMessage",
5363
- message: {
5364
- text: thinking.text,
5365
- ...thinking.signature !== void 0 ? { signature: thinking.signature } : {}
5366
- }
5367
- };
5368
- }
5369
- function recordThinkingOnSilentToolRound(ctx, text, thinking) {
5370
- if (text.length > 0 || thinking === void 0) return;
5371
- ctx.conversation.push({
5372
- type: "agentConversationTurn",
5373
- turn: { steps: [thinkingStep(thinking)] }
5374
- });
5375
- }
5376
-
5377
- // src/internal/tool-dispatch/repair-middleware.ts
5378
- var DECIMAL_RE = /^-?\d+(\.\d+)?$/;
5379
- function repairToolCall(raw, registry) {
5380
- const repairs = [];
5381
- let call = { ...raw };
5382
- if (!registry.has(call.name)) {
5383
- const lower = call.name.toLowerCase();
5384
- let match;
5385
- for (const key of registry.keys()) {
5386
- if (key.toLowerCase() === lower) {
5387
- match = key;
5388
- break;
5389
- }
5390
- }
5391
- if (match !== void 0) {
5392
- repairs.push(`name: "${call.name}" \u2192 "${match}"`);
5393
- call = { ...call, name: match };
5394
- }
5395
- }
5396
- if (typeof call.args === "string") {
5397
- try {
5398
- const parsed = JSON.parse(call.args);
5399
- call = { ...call, args: parsed };
5400
- repairs.push("args: parsed from string");
5401
- } catch {
5402
- }
5403
- }
5404
- const tool = registry.get(call.name);
5405
- if (tool !== void 0 && typeof call.args === "object" && call.args !== null && !Array.isArray(call.args)) {
5406
- const coerced = coerceArgsToSchema(call.args, tool.inputSchema);
5407
- if (coerced.changed.length > 0) {
5408
- call = { ...call, args: coerced.value };
5409
- repairs.push(...coerced.changed);
5410
- }
5411
- }
5412
- return { call, repairs };
5413
- }
5414
- function coerceArgsToSchema(args, schema) {
5415
- const changed = [];
5416
- const out = { ...args };
5417
- const properties = schema.properties;
5418
- if (properties === void 0) return { value: out, changed };
5419
- for (const [key, propDef] of Object.entries(properties)) {
5420
- const val = out[key];
5421
- if (typeof val !== "string") continue;
5422
- const propType = propDef.type;
5423
- if (typeof propType !== "string") continue;
5424
- if (propType === "number" && DECIMAL_RE.test(val.trim())) {
5425
- out[key] = Number(val);
5426
- changed.push(`${key}: string\u2192number`);
5427
- } else if (propType === "integer" && /^-?\d+$/.test(val.trim())) {
5428
- out[key] = Number(val);
5429
- changed.push(`${key}: string\u2192integer`);
5430
- } else if (propType === "boolean" && (val === "true" || val === "false")) {
5431
- out[key] = val === "true";
5432
- changed.push(`${key}: string\u2192boolean`);
5433
- } else if (propType === "array" || propType === "object") {
5434
- try {
5435
- const parsed = JSON.parse(val);
5436
- if (propType === "array" && Array.isArray(parsed)) {
5437
- out[key] = parsed;
5438
- changed.push(`${key}: string\u2192array`);
5439
- } else if (propType === "object" && typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
5440
- out[key] = parsed;
5441
- changed.push(`${key}: string\u2192object`);
5442
- }
5443
- } catch {
5444
- }
5167
+ "anthropic/claude-opus-4-6": {
5168
+ input: 5,
5169
+ output: 25,
5170
+ cacheRead: 0.5,
5171
+ cacheWrite: 6.25
5172
+ },
5173
+ "anthropic/claude-opus-4-5": {
5174
+ input: 5,
5175
+ output: 25,
5176
+ cacheRead: 0.5,
5177
+ cacheWrite: 6.25
5178
+ },
5179
+ "anthropic/claude-sonnet-4-6": {
5180
+ input: 3,
5181
+ output: 15,
5182
+ cacheRead: 0.3,
5183
+ cacheWrite: 3.75
5184
+ },
5185
+ "anthropic/claude-sonnet-4-5": {
5186
+ input: 3,
5187
+ output: 15,
5188
+ cacheRead: 0.3,
5189
+ cacheWrite: 3.75
5190
+ },
5191
+ "anthropic/claude-haiku-4-5": {
5192
+ input: 1,
5193
+ output: 5,
5194
+ cacheRead: 0.1,
5195
+ cacheWrite: 1.25
5196
+ },
5197
+ "anthropic/claude-3-5-sonnet": {
5198
+ input: 3,
5199
+ output: 15,
5200
+ cacheRead: 0.3,
5201
+ cacheWrite: 3.75
5202
+ },
5203
+ "anthropic/claude-3-5-haiku": {
5204
+ input: 0.8,
5205
+ output: 4,
5206
+ cacheRead: 0.08,
5207
+ cacheWrite: 1
5208
+ },
5209
+ "anthropic/claude-3-opus": {
5210
+ input: 15,
5211
+ output: 75,
5212
+ cacheRead: 1.5,
5213
+ cacheWrite: 18.75
5214
+ },
5215
+ "anthropic/claude-3-haiku": {
5216
+ input: 0.25,
5217
+ output: 1.25,
5218
+ cacheRead: 0.03,
5219
+ cacheWrite: 0.3
5220
+ },
5221
+ "openai/gpt-4o": {
5222
+ input: 2.5,
5223
+ output: 10,
5224
+ cacheRead: 1.25
5225
+ },
5226
+ "openai/gpt-4o-mini": {
5227
+ input: 0.15,
5228
+ output: 0.6,
5229
+ cacheRead: 0.075
5230
+ },
5231
+ "openai/gpt-4.1": {
5232
+ input: 2,
5233
+ output: 8,
5234
+ cacheRead: 0.5
5235
+ },
5236
+ "openai/gpt-4.1-mini": {
5237
+ input: 0.4,
5238
+ output: 1.6,
5239
+ cacheRead: 0.1
5240
+ },
5241
+ "openai/gpt-4.1-nano": {
5242
+ input: 0.1,
5243
+ output: 0.4,
5244
+ cacheRead: 0.025
5245
+ },
5246
+ "openai/o3": {
5247
+ input: 2,
5248
+ output: 8,
5249
+ cacheRead: 0.5
5250
+ },
5251
+ "openai/o3-mini": {
5252
+ input: 1.1,
5253
+ output: 4.4,
5254
+ cacheRead: 0.55
5255
+ },
5256
+ "openai/o4-mini": {
5257
+ input: 1.1,
5258
+ output: 4.4,
5259
+ cacheRead: 0.275
5260
+ },
5261
+ "deepseek/deepseek-chat": {
5262
+ input: 0.14,
5263
+ output: 0.28
5264
+ },
5265
+ "deepseek/deepseek-reasoner": {
5266
+ input: 0.55,
5267
+ output: 2.19
5268
+ },
5269
+ "google/gemini-2.5-pro": {
5270
+ input: 1.25,
5271
+ output: 10
5272
+ },
5273
+ "google/gemini-2.5-flash": {
5274
+ input: 0.15,
5275
+ output: 0.6
5276
+ },
5277
+ "google/gemini-2.0-flash": {
5278
+ input: 0.1,
5279
+ output: 0.4
5445
5280
  }
5446
5281
  }
5447
- return { value: out, changed };
5448
- }
5449
-
5450
- // src/tool-error.ts
5451
- var ToolError = class extends TheokitAgentError {
5452
- name = "ToolError";
5453
- /** The error content surfaced to the model: a string, or text/image blocks. */
5454
- content;
5455
- constructor(content, options = {}) {
5456
- super(renderToolErrorMessage(content), { ...options, isRetryable: false });
5457
- this.content = content;
5458
- }
5459
5282
  };
5460
- function renderToolErrorMessage(content) {
5461
- if (typeof content === "string") return content;
5462
- return content.map((block) => block.type === "text" ? block.text : `[${block.source.media_type} image]`).join("\n");
5463
- }
5464
5283
 
5465
- // src/internal/runtime/tools/shell-tool.ts
5466
- async function runShell(options) {
5467
- if (options.sandbox === true && isObviouslyUnsafe(options.command)) {
5468
- return {
5469
- stdout: "",
5470
- stderr: `Sandbox refused command: ${options.command}`,
5471
- exitCode: 126,
5472
- timedOut: false
5473
- };
5474
- }
5475
- const result = await spawnAndCollect({
5476
- command: "sh",
5477
- args: ["-c", options.command],
5478
- cwd: options.cwd,
5479
- ...options.env !== void 0 ? { env: options.env } : {},
5480
- ...options.timeoutMs !== void 0 ? { timeoutMs: options.timeoutMs } : {}
5481
- });
5482
- const stderr = result.spawnError !== void 0 ? result.stderr + result.spawnError.message : result.stderr;
5284
+ // src/internal/budget/pricing-registry.ts
5285
+ var data = pricing_data_default;
5286
+ function buildEntry(key, raw) {
5287
+ const [provider, ...modelParts] = key.split("/");
5483
5288
  return {
5484
- stdout: result.stdout,
5485
- stderr,
5486
- exitCode: result.exitCode,
5487
- timedOut: result.timedOut
5289
+ provider: provider ?? "unknown",
5290
+ model: modelParts.join("/"),
5291
+ inputCostPerMillion: raw.input,
5292
+ outputCostPerMillion: raw.output,
5293
+ ...raw.cacheRead !== void 0 ? { cacheReadCostPerMillion: raw.cacheRead } : {},
5294
+ ...raw.cacheWrite !== void 0 ? { cacheWriteCostPerMillion: raw.cacheWrite } : {},
5295
+ ...raw.reasoning !== void 0 ? { reasoningCostPerMillion: raw.reasoning } : {},
5296
+ pricingVersion: data._meta.pricingVersion
5488
5297
  };
5489
5298
  }
5490
- function isObviouslyUnsafe(command) {
5491
- if (/(^|\s)(rm|mv|cp)\s+[^|;]*\s+\/(etc|var|root)\b/.test(command)) return true;
5492
- if (/sudo\s/.test(command)) return true;
5493
- return false;
5299
+ function stripDateSuffix(model) {
5300
+ return model.replace(/-\d{4}-?\d{2}-?\d{2}$/, "");
5494
5301
  }
5495
-
5496
- // src/internal/agent-loop/tool-executors.ts
5497
- async function executeTool(inputs, resolved, call) {
5498
- if (resolved === void 0) {
5499
- return { stdout: "", stderr: `Unknown tool ${call.name}`, exitCode: 127 };
5500
- }
5501
- if (resolved.origin === "shell") return runShellTool(inputs, call);
5502
- if (resolved.origin === "memory")
5503
- return runMemoryTool(resolved, call, inputs.context, inputs.agentId);
5504
- if (resolved.origin === "custom")
5505
- return runCustomTool(
5506
- resolved,
5507
- call,
5508
- inputs.signal,
5509
- inputs.context,
5510
- inputs.messages,
5511
- inputs.agentId
5512
- );
5513
- return runMcpTool(inputs, resolved, call);
5302
+ function normalizeAnthropicDots(model) {
5303
+ return model.replace(/(?<=\d)\.(?=\d)/g, "-");
5514
5304
  }
5515
- async function runMemoryTool(resolved, call, context, threadId) {
5516
- return runHandlerTool(
5517
- "memory",
5518
- resolved.memoryHandler,
5519
- call,
5520
- void 0,
5521
- context,
5522
- void 0,
5523
- threadId
5524
- );
5305
+ function stripOpenRouterPrefix(modelId) {
5306
+ return modelId.startsWith("openrouter/") ? modelId.slice("openrouter/".length) : modelId;
5525
5307
  }
5526
- async function runCustomTool(resolved, call, signal, context, messages, threadId) {
5527
- return runHandlerTool(
5528
- "custom",
5529
- resolved.customHandler,
5530
- call,
5531
- signal,
5532
- context,
5533
- messages,
5534
- threadId
5535
- );
5308
+ function lookupRaw(key) {
5309
+ return data.models[key];
5536
5310
  }
5537
- async function runHandlerTool(kind, handler, call, signal, context, messages, threadId) {
5538
- if (handler === void 0) {
5539
- return { stdout: "", stderr: `${kind} tool ${call.name} has no handler`, exitCode: 127 };
5311
+ function getPricingEntry(opts) {
5312
+ const cleaned = stripOpenRouterPrefix(opts.model);
5313
+ const directKey = `${opts.provider}/${cleaned}`;
5314
+ const direct = lookupRaw(directKey);
5315
+ if (direct !== void 0) return buildEntry(directKey, direct);
5316
+ const noSuffix = stripDateSuffix(cleaned);
5317
+ if (noSuffix !== cleaned) {
5318
+ const noSuffixKey = `${opts.provider}/${noSuffix}`;
5319
+ const found = lookupRaw(noSuffixKey);
5320
+ if (found !== void 0) return buildEntry(noSuffixKey, found);
5540
5321
  }
5541
- try {
5542
- const split = handler[TOOL_SPLIT_RESOLVER];
5543
- if (split !== void 0) {
5544
- const { model, app } = await split(call.input, { signal, context, threadId });
5545
- const base = typeof model === "string" ? { stdout: model, stderr: "", exitCode: 0 } : { stdout: "", stderr: "", exitCode: 0, content: model };
5546
- return { ...base, appResult: app };
5547
- }
5548
- const out = await handler(call.input, { signal, context, messages, threadId });
5549
- if (typeof out !== "string") return { stdout: "", stderr: "", exitCode: 0, content: out };
5550
- return { stdout: out, stderr: "", exitCode: 0 };
5551
- } catch (cause) {
5552
- if (cause instanceof ToolError) {
5553
- return { stdout: "", stderr: cause.message, exitCode: 1, content: cause.content };
5322
+ if (opts.provider === "anthropic") {
5323
+ const normalized = normalizeAnthropicDots(stripDateSuffix(cleaned));
5324
+ const normKey = `${opts.provider}/${normalized}`;
5325
+ const found = lookupRaw(normKey);
5326
+ if (found !== void 0) return buildEntry(normKey, found);
5327
+ }
5328
+ if (cleaned.includes("/")) {
5329
+ const found = lookupRaw(cleaned);
5330
+ if (found !== void 0) return buildEntry(cleaned, found);
5331
+ const stripped = stripDateSuffix(cleaned);
5332
+ if (stripped !== cleaned) {
5333
+ const found2 = lookupRaw(stripped);
5334
+ if (found2 !== void 0) return buildEntry(stripped, found2);
5554
5335
  }
5555
- const message = cause instanceof Error ? cause.message : String(cause);
5556
- return { stdout: "", stderr: message, exitCode: 1 };
5557
5336
  }
5337
+ const catalogEntry = catalogCostFallback(opts.provider, cleaned);
5338
+ if (catalogEntry !== void 0) return catalogEntry;
5339
+ return void 0;
5558
5340
  }
5559
- async function runShellTool(inputs, call) {
5560
- const command = typeof call.input.command === "string" ? call.input.command : JSON.stringify(call.input);
5561
- const shellOptions = {
5562
- command,
5563
- cwd: inputs.shellCwd,
5564
- sandbox: inputs.shellSandbox
5565
- };
5566
- const result = await runShell(shellOptions);
5567
- const final = { stdout: result.stdout, stderr: result.stderr };
5568
- if (result.exitCode !== null && result.exitCode !== void 0) final.exitCode = result.exitCode;
5569
- return final;
5570
- }
5571
- async function runMcpTool(inputs, resolved, call) {
5572
- const client = inputs.mcp.get(resolved.mcpServerName ?? "");
5573
- if (client === void 0 || resolved.mcpToolName === void 0) {
5341
+ function catalogCostFallback(provider, cleanedModel) {
5342
+ const stripped = stripDateSuffix(cleanedModel);
5343
+ const candidates = [`${provider}/${cleanedModel}`, cleanedModel];
5344
+ if (stripped !== cleanedModel) candidates.push(`${provider}/${stripped}`, stripped);
5345
+ for (const key of candidates) {
5346
+ const info = getCatalogModelInfo(key);
5347
+ const cost = info?.cost;
5348
+ if (cost === void 0) continue;
5349
+ const [prov, ...modelParts] = key.split("/");
5574
5350
  return {
5575
- stdout: "",
5576
- stderr: `MCP server ${resolved.mcpServerName ?? "?"} not connected`,
5577
- exitCode: 127
5351
+ provider: prov ?? provider,
5352
+ model: modelParts.join("/") || cleanedModel,
5353
+ inputCostPerMillion: cost.input,
5354
+ outputCostPerMillion: cost.output,
5355
+ ...cost.cache_read !== void 0 ? { cacheReadCostPerMillion: cost.cache_read } : {},
5356
+ ...cost.cache_write !== void 0 ? { cacheWriteCostPerMillion: cost.cache_write } : {},
5357
+ // M44 M5 fix — honest provenance: a key patched by the LIVE models-dev source is not "vendored".
5358
+ pricingVersion: isPatchedModelKey(key) ? "catalog-models-dev" : "catalog-vendored"
5578
5359
  };
5579
5360
  }
5580
- try {
5581
- const response = await client.callTool(resolved.mcpToolName, call.input);
5582
- const text = response.content.filter((part) => part.type === "text").map((part) => part.text).join("\n");
5583
- return { stdout: text, stderr: "", exitCode: response.isError === true ? 1 : 0 };
5584
- } catch (cause) {
5585
- const message = cause instanceof Error ? cause.message : String(cause);
5586
- return { stdout: "", stderr: message, exitCode: 1 };
5587
- }
5588
- }
5589
- function renderToolResult(result) {
5590
- if (result.stderr.length > 0 && (result.exitCode ?? 0) !== 0) {
5591
- return `${result.stdout}
5592
- [stderr]
5593
- ${result.stderr}`.trim();
5594
- }
5595
- return result.stdout.trim();
5361
+ return void 0;
5596
5362
  }
5597
5363
 
5598
- // src/internal/agent-loop/tool-timeout.ts
5599
- var TOOL_ABORTED_EXIT = 124;
5600
- function abortedResult(signal) {
5601
- const reason = signal.reason;
5602
- const timedOut = reason?.name === "TimeoutError";
5603
- return {
5604
- stdout: "",
5605
- stderr: timedOut ? "tool execution timed out" : "tool execution aborted",
5606
- exitCode: TOOL_ABORTED_EXIT
5607
- };
5364
+ // src/internal/budget/compute-cost.ts
5365
+ var MICROCENT = 1e6;
5366
+ function isSubscriptionIncluded(provider) {
5367
+ return provider === "openai-codex" || provider === "codex";
5608
5368
  }
5609
- function raceToolExecution(exec, opts) {
5610
- const { signal, timeoutMs } = opts;
5611
- if (signal === void 0 && timeoutMs === void 0) return exec;
5612
- const signals = [];
5613
- if (signal !== void 0) signals.push(signal);
5614
- if (timeoutMs !== void 0) signals.push(AbortSignal.timeout(timeoutMs));
5615
- const merged = signals.length === 1 ? signals[0] : AbortSignal.any(signals);
5616
- if (merged.aborted) return Promise.resolve(abortedResult(merged));
5617
- return new Promise((resolve, reject) => {
5618
- let settled = false;
5619
- const onAbort = () => {
5620
- if (settled) return;
5621
- settled = true;
5622
- resolve(abortedResult(merged));
5623
- };
5624
- merged.addEventListener("abort", onAbort, { once: true });
5625
- exec.then(
5626
- (r) => {
5627
- if (settled) return;
5628
- settled = true;
5629
- merged.removeEventListener("abort", onAbort);
5630
- resolve(r);
5631
- },
5632
- (e) => {
5633
- if (settled) return;
5634
- settled = true;
5635
- merged.removeEventListener("abort", onAbort);
5636
- reject(e);
5637
- }
5638
- );
5639
- });
5369
+ function pricingHasValidRates(entry) {
5370
+ 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);
5640
5371
  }
5641
-
5642
- // src/internal/agent-loop/tool-dispatch.ts
5643
- async function dispatchTools(inputs, tools, toolCalls, events, parentSpan) {
5644
- const maxConcurrent = inputs.maxConcurrentTools ?? 4;
5645
- return mapWithConcurrency(
5646
- toolCalls,
5647
- maxConcurrent,
5648
- (call) => dispatchSingleCall(inputs, tools, call, events, parentSpan)
5649
- );
5372
+ function costForTokens(tokens, perMillion) {
5373
+ if (tokens === 0 || perMillion === 0) return 0;
5374
+ return Math.round(tokens * perMillion * MICROCENT / 1e6) / MICROCENT;
5650
5375
  }
5651
- async function dispatchSingleCall(inputs, tools, call, events, parentSpan) {
5652
- const { call: workingCall, repairs } = applyRepairAndExtractCall(tools, call);
5653
- const callId = generateCallId();
5654
- const forkVeto = vetoFromForkWhitelist(inputs, workingCall, callId, events);
5655
- if (forkVeto !== void 0) return forkVeto;
5656
- const resolved = tools.find((tool) => tool.name === workingCall.name);
5657
- const toolSpan = startToolCallSpan(inputs, workingCall, resolved, callId, repairs, parentSpan);
5658
- events.push(buildToolUseRunning(inputs, callId, workingCall));
5659
- const pluginVeto = await vetoFromPluginPreHook(inputs, workingCall, callId, events);
5660
- if (pluginVeto !== void 0) {
5661
- toolSpan?.setAttribute("tool.vetoed", true);
5662
- toolSpan?.setAttribute("tool.veto_source", "plugin");
5663
- toolSpan?.end();
5664
- return pluginVeto;
5376
+ function computeCost(args) {
5377
+ if (isSubscriptionIncluded(args.provider)) {
5378
+ return {
5379
+ amountUsd: 0,
5380
+ status: "included",
5381
+ currency: "USD",
5382
+ source: "subscription_included",
5383
+ pricingVersion: void 0
5384
+ };
5385
+ }
5386
+ const entry = getPricingEntry({
5387
+ provider: args.provider,
5388
+ model: args.model,
5389
+ ...args.baseUrl !== void 0 ? { baseUrl: args.baseUrl } : {}
5390
+ });
5391
+ if (entry === void 0) {
5392
+ return {
5393
+ amountUsd: void 0,
5394
+ status: "unknown",
5395
+ currency: "USD",
5396
+ source: "unknown",
5397
+ pricingVersion: void 0
5398
+ };
5399
+ }
5400
+ if (!pricingHasValidRates(entry)) {
5401
+ return {
5402
+ amountUsd: void 0,
5403
+ status: "unknown",
5404
+ currency: "USD",
5405
+ source: "unknown",
5406
+ pricingVersion: entry.pricingVersion,
5407
+ notes: ["pricing entry has negative rates; treated as invalid"]
5408
+ };
5409
+ }
5410
+ const notes = [];
5411
+ const detail = {};
5412
+ const u = args.usage;
5413
+ const inputCost = costForTokens(u.inputTokens, entry.inputCostPerMillion);
5414
+ const outputCost = costForTokens(u.outputTokens, entry.outputCostPerMillion);
5415
+ detail.input = inputCost;
5416
+ detail.output = outputCost;
5417
+ let total = inputCost + outputCost;
5418
+ if (u.cacheReadTokens !== void 0 && u.cacheReadTokens > 0) {
5419
+ if (entry.cacheReadCostPerMillion === void 0) {
5420
+ return {
5421
+ amountUsd: void 0,
5422
+ status: "unknown",
5423
+ currency: "USD",
5424
+ source: "litellm_snapshot",
5425
+ pricingVersion: entry.pricingVersion,
5426
+ notes: ["cache-read tokens present but cacheReadCostPerMillion is undefined"]
5427
+ };
5428
+ }
5429
+ const c = costForTokens(u.cacheReadTokens, entry.cacheReadCostPerMillion);
5430
+ detail.cacheRead = c;
5431
+ total += c;
5432
+ }
5433
+ if (u.cacheWriteTokens !== void 0 && u.cacheWriteTokens > 0) {
5434
+ if (entry.cacheWriteCostPerMillion === void 0) {
5435
+ return {
5436
+ amountUsd: void 0,
5437
+ status: "unknown",
5438
+ currency: "USD",
5439
+ source: "litellm_snapshot",
5440
+ pricingVersion: entry.pricingVersion,
5441
+ notes: ["cache-write tokens present but cacheWriteCostPerMillion is undefined"]
5442
+ };
5443
+ }
5444
+ const c = costForTokens(u.cacheWriteTokens, entry.cacheWriteCostPerMillion);
5445
+ detail.cacheWrite = c;
5446
+ total += c;
5665
5447
  }
5666
- const fileVeto = await vetoFromFileHookPreDecision(inputs, workingCall, callId, events);
5667
- if (fileVeto !== void 0) {
5668
- toolSpan?.setAttribute("tool.vetoed", true);
5669
- toolSpan?.setAttribute("tool.veto_source", "file_hook");
5670
- toolSpan?.end();
5671
- return fileVeto;
5448
+ if (u.reasoningTokens !== void 0 && u.reasoningTokens > 0) {
5449
+ const rate = entry.reasoningCostPerMillion ?? entry.outputCostPerMillion;
5450
+ const c = costForTokens(u.reasoningTokens, rate);
5451
+ detail.reasoning = c;
5452
+ total += c;
5453
+ if (entry.reasoningCostPerMillion === void 0) {
5454
+ notes.push("reasoning tokens billed at output rate (no dedicated reasoning rate available)");
5455
+ }
5672
5456
  }
5673
- emitRunEvent(inputs.runEventSink, {
5674
- type: "tool_progress",
5675
- toolName: workingCall.name,
5676
- toolCallId: callId
5677
- });
5678
- const result = await runToolWithLifecycle(inputs, resolved, workingCall, callId);
5679
- await inputs.pluginManager?.runPostToolCallHooks({
5680
- name: workingCall.name,
5681
- args: workingCall.input,
5682
- result: { stdout: result.stdout, stderr: result.stderr, exitCode: result.exitCode },
5683
- agentId: inputs.agentId,
5684
- runId: inputs.runId
5685
- });
5686
- return finalizeSpanAndPostHook(inputs, workingCall, callId, result, events, toolSpan);
5687
- }
5688
- function applyRepairAndExtractCall(tools, call) {
5689
- const registryMap = buildRepairRegistry(tools);
5690
- const repaired = repairToolCall({ name: call.name, args: call.input, id: call.id }, registryMap);
5691
- if (repaired.repairs.length === 0) return { call, repairs: repaired.repairs };
5457
+ const amountUsd = Math.round(total * MICROCENT) / MICROCENT;
5692
5458
  return {
5693
- call: {
5694
- ...call,
5695
- name: repaired.call.name,
5696
- input: repaired.call.args ?? {}
5697
- },
5698
- repairs: repaired.repairs
5459
+ amountUsd,
5460
+ status: "estimated",
5461
+ currency: "USD",
5462
+ source: "litellm_snapshot",
5463
+ pricingVersion: entry.pricingVersion,
5464
+ ...notes.length > 0 ? { notes } : {},
5465
+ detail
5699
5466
  };
5700
5467
  }
5701
- function vetoFromForkWhitelist(inputs, call, callId, events) {
5702
- const whitelistDecision = checkToolWhitelist(call.name);
5703
- if (whitelistDecision.allowed) return void 0;
5704
- emitRunEvent(inputs.runEventSink, {
5705
- type: "permission_denied",
5706
- toolName: call.name,
5707
- toolCallId: callId,
5708
- source: "fork_whitelist",
5709
- message: whitelistDecision.reason ?? "tool not available in fork"
5468
+
5469
+ // src/internal/agent-loop/usage-and-cost.ts
5470
+ function accumulateUsage(usage, turn) {
5471
+ const hasAnyToken = turn.inputTokens !== void 0 || turn.outputTokens !== void 0 || turn.cacheReadTokens !== void 0 || turn.cacheWriteTokens !== void 0 || turn.reasoningTokens !== void 0;
5472
+ if (!hasAnyToken) return;
5473
+ usage.add({
5474
+ inputTokens: turn.inputTokens,
5475
+ outputTokens: turn.outputTokens,
5476
+ cacheReadTokens: turn.cacheReadTokens,
5477
+ cacheWriteTokens: turn.cacheWriteTokens,
5478
+ reasoningTokens: turn.reasoningTokens
5710
5479
  });
5711
- events.push(buildToolUseRunning(inputs, callId, call));
5712
- events.push(
5713
- buildToolUseCompleted(inputs, callId, call, {
5714
- stdout: "",
5715
- stderr: whitelistDecision.reason ?? "tool not available in fork",
5716
- exitCode: 126
5717
- })
5718
- );
5719
- return {
5720
- type: "tool_result",
5721
- toolUseId: call.id,
5722
- content: `Tool blocked by fork whitelist: ${whitelistDecision.reason}`
5480
+ }
5481
+ function computeUsageCost(inputs, usage) {
5482
+ const modelId = inputs.model.id;
5483
+ if (modelId === void 0 || modelId === "auto") return void 0;
5484
+ const parsed = parseModelId(modelId);
5485
+ const provider = parsed.provider ?? inputs.llm.name;
5486
+ const model = parsed.provider !== void 0 ? parsed.name : modelId;
5487
+ return computeCost({ provider, model, usage });
5488
+ }
5489
+
5490
+ // src/internal/agent-loop/loop-finalize.ts
5491
+ function diagnoseTermination(ctx, budget, lastTurnDecision) {
5492
+ const exhausted = budget.shouldContinue() === false;
5493
+ if (lastTurnDecision === "continue" && exhausted) ctx.stoppedAtIterationLimit = true;
5494
+ if (!exhausted || ctx.finalStatus !== "finished" || ctx.finalText !== "") return;
5495
+ ctx.finalStatus = "error";
5496
+ if (ctx.error !== void 0) return;
5497
+ ctx.error = {
5498
+ 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.`,
5499
+ code: "iteration_limit_reached"
5723
5500
  };
5724
5501
  }
5725
- function startToolCallSpan(inputs, call, resolved, callId, repairs, parentSpan) {
5726
- const toolSpan = inputs.telemetry?.startChildSpan(parentSpan, "tool.call", {
5727
- "tool.name": call.name,
5728
- "tool.origin": resolved?.origin ?? "unknown",
5729
- callId
5502
+ function stampSendSpan(inputs, ctx, sendSpan, usage, cost) {
5503
+ sendSpan?.setAttribute("status", ctx.finalStatus);
5504
+ if (ctx.stoppedByDoomLoop === true) sendSpan?.setAttribute("stoppedByDoomLoop", true);
5505
+ if (inputs.telemetry?.includeContent === true && ctx.finalText.length > 0) {
5506
+ sendSpan?.addEvent("response", { content: ctx.finalText });
5507
+ }
5508
+ if (usage === void 0) return;
5509
+ sendSpan?.setAttributes({
5510
+ totalInputTokens: usage.inputTokens,
5511
+ totalOutputTokens: usage.outputTokens,
5512
+ ...cost?.amountUsd !== void 0 ? { totalCostUsd: cost.amountUsd } : {}
5730
5513
  });
5731
- if (repairs.length > 0 && toolSpan !== void 0) {
5732
- toolSpan.setAttribute("tool.repairs", repairs.join("; "));
5733
- }
5734
- if (toolSpan !== void 0 && inputs.telemetry?.includeContent === true) {
5735
- toolSpan.addEvent("args", { input: JSON.stringify(call.input) });
5514
+ }
5515
+ async function syncMemoryProvider(inputs, ctx, sendSpan) {
5516
+ if (ctx.finalStatus !== "finished") return;
5517
+ if (ctx.memoryProviderHandle === void 0 || inputs.memoryProvider?.sync === void 0) return;
5518
+ try {
5519
+ await inputs.memoryProvider.sync(ctx.memoryProviderHandle);
5520
+ } catch (cause) {
5521
+ sendSpan?.addEvent("memory.sync.failed", {
5522
+ message: cause instanceof Error ? cause.message : String(cause)
5523
+ });
5736
5524
  }
5737
- return toolSpan;
5738
5525
  }
5739
- async function vetoFromPluginPreHook(inputs, call, callId, events) {
5740
- const pluginVeto = await inputs.pluginManager?.runPreToolCallHooks({
5741
- name: call.name,
5742
- args: call.input,
5743
- agentId: inputs.agentId,
5744
- runId: inputs.runId,
5745
- // SE1 — thread the run's permission mode so a PermissionPlugin gates per-run.
5746
- ...inputs.permissionMode !== void 0 ? { permissionMode: inputs.permissionMode } : {}
5747
- });
5748
- if (pluginVeto === void 0) return void 0;
5749
- emitRunEvent(inputs.runEventSink, {
5750
- type: "permission_denied",
5751
- toolName: call.name,
5752
- toolCallId: callId,
5753
- source: "plugin",
5754
- message: pluginVeto.message
5755
- });
5756
- events.push(
5757
- buildToolUseCompleted(inputs, callId, call, {
5758
- stdout: "",
5759
- stderr: pluginVeto.message,
5760
- exitCode: 126
5761
- })
5762
- );
5526
+ async function finalizeLoopOutput(inputs, ctx, budget, sendSpan, lastTurnDecision) {
5527
+ diagnoseTermination(ctx, budget, lastTurnDecision);
5528
+ const usage = ctx.usage.hasAny() ? ctx.usage.toTokenUsage() : void 0;
5529
+ const cost = usage !== void 0 ? computeUsageCost(inputs, usage) : void 0;
5530
+ stampSendSpan(inputs, ctx, sendSpan, usage, cost);
5531
+ await syncMemoryProvider(inputs, ctx, sendSpan);
5763
5532
  return {
5764
- type: "tool_result",
5765
- toolUseId: call.id,
5766
- content: `Plugin blocked this tool call: ${pluginVeto.message}`
5533
+ events: ctx.events,
5534
+ finalStatus: ctx.finalStatus,
5535
+ result: ctx.finalText,
5536
+ conversation: ctx.conversation,
5537
+ ...usage !== void 0 ? { usage } : {},
5538
+ ...cost !== void 0 ? { cost } : {},
5539
+ ...ctx.error !== void 0 ? { error: ctx.error } : {},
5540
+ ...ctx.stoppedAtIterationLimit === true ? { stoppedAtIterationLimit: true } : {},
5541
+ ...ctx.stoppedByDoomLoop === true ? { stoppedByDoomLoop: true } : {}
5767
5542
  };
5768
5543
  }
5769
- async function vetoFromFileHookPreDecision(inputs, call, callId, events) {
5770
- const preDecision = await inputs.hooks.run({
5771
- event: "preToolUse",
5772
- tool: call.name,
5773
- input: call.input,
5774
- agentId: inputs.agentId,
5775
- runId: inputs.runId
5776
- });
5777
- if (!preDecision.blocked) return void 0;
5778
- emitRunEvent(inputs.runEventSink, {
5779
- type: "permission_denied",
5780
- toolName: call.name,
5781
- toolCallId: callId,
5782
- source: "file_hook",
5783
- message: preDecision.reason ?? "blocked by hook"
5784
- });
5785
- events.push(
5786
- buildToolUseCompleted(inputs, callId, call, {
5787
- stdout: "",
5788
- stderr: preDecision.reason ?? "blocked by hook",
5789
- exitCode: 126
5790
- })
5791
- );
5792
- return {
5793
- type: "tool_result",
5794
- toolUseId: call.id,
5795
- content: `Hook denied this tool call: ${preDecision.reason ?? "no reason given"}`
5796
- };
5544
+ var KEY_PREFIX = "theokit-";
5545
+ var KEY_HEX_LENGTH = 32;
5546
+ function derivePromptCacheKey(sessionId) {
5547
+ if (sessionId === void 0 || sessionId.trim().length === 0) return void 0;
5548
+ const digest = createHash("sha256").update(sessionId, "utf8").digest("hex");
5549
+ return `${KEY_PREFIX}${digest.slice(0, KEY_HEX_LENGTH)}`;
5797
5550
  }
5798
- async function runToolWithLifecycle(inputs, resolved, call, callId) {
5799
- const startAt = Date.now();
5800
- await safeEmitToolHook(inputs.onToolStart, {
5801
- toolName: call.name,
5802
- args: call.input,
5803
- conversationId: inputs.agentId,
5804
- callId
5805
- });
5806
- await emitToolLifecycleDelta(inputs, {
5807
- type: "tool-call-started",
5808
- callId,
5809
- toolCall: { callId, name: call.name, args: call.input },
5810
- modelCallId: callId
5811
- });
5812
- const result = await raceToolExecution(executeTool(inputs, resolved, call), {
5813
- signal: inputs.signal,
5814
- timeoutMs: inputs.perToolTimeoutMs
5815
- });
5816
- const durationMs = Date.now() - startAt;
5817
- await emitToolLifecycleDelta(inputs, {
5818
- type: "tool-call-completed",
5819
- callId,
5820
- toolCall: {
5821
- callId,
5822
- name: call.name,
5823
- args: call.input,
5824
- result: result.content !== void 0 ? result.content : renderToolResult(result)
5825
- },
5826
- modelCallId: callId
5827
- });
5828
- inputs.telemetry?.recordHistogram(HISTOGRAM_NAMES.TOOL_CALL_DURATION_MS, durationMs, {
5829
- "tool.name": call.name
5830
- });
5831
- if (result.exitCode !== void 0 && result.exitCode !== 0 && result.exitCode !== null) {
5832
- await safeEmitToolHook(inputs.onToolError, {
5833
- toolName: call.name,
5834
- args: call.input,
5835
- error: new Error(result.stderr || `tool exited with code ${result.exitCode}`),
5836
- conversationId: inputs.agentId,
5837
- callId,
5838
- durationMs,
5839
- attempt: 1
5840
- });
5841
- } else {
5842
- await safeEmitToolHook(inputs.onToolEnd, {
5843
- toolName: call.name,
5844
- args: call.input,
5845
- // SE17 — when a `toModelOutput` split is active, observability gets the FULL
5846
- // raw output (`appResult`), NOT the compact model-facing value. SE7 — a
5847
- // block-returning handler has empty `stdout`; surface its structured content
5848
- // to the hook instead of an empty string.
5849
- result: result.appResult !== void 0 ? result.appResult : result.content !== void 0 ? result.content : result.stdout,
5850
- conversationId: inputs.agentId,
5851
- callId,
5852
- durationMs
5853
- });
5854
- }
5855
- return result;
5551
+
5552
+ // src/internal/tool-dispatch/strip-think.ts
5553
+ var THINK_PATTERN = /<think>[\s\S]*?<\/think>\s*/g;
5554
+ function stripThinkBlocks(content) {
5555
+ const matches = [...content.matchAll(THINK_PATTERN)];
5556
+ const thinking = matches.length > 0 ? matches.map((m) => m[0]).join("\n").replace(/<\/?think>/g, "").trim() : null;
5557
+ const visible = content.replace(THINK_PATTERN, "").trim();
5558
+ return { visible, thinking };
5856
5559
  }
5857
- function finalizeSpanAndPostHook(inputs, call, callId, result, events, toolSpan) {
5858
- toolSpan?.setAttribute("exitCode", result.exitCode ?? 0);
5859
- if (toolSpan !== void 0 && inputs.telemetry?.includeContent === true) {
5860
- toolSpan.addEvent("result", { stdout: result.stdout.slice(0, 1e3) });
5861
- }
5862
- toolSpan?.end();
5863
- events.push(buildToolUseCompleted(inputs, callId, call, result));
5864
- inputs.hooks.run({
5865
- event: "postToolUse",
5866
- tool: call.name,
5867
- input: call.input,
5868
- output: {
5869
- stdout: result.stdout,
5870
- stderr: result.stderr,
5871
- exitCode: result.exitCode ?? 0,
5872
- // SE7 — structured content (text + image blocks) when the handler
5873
- // returned/threw blocks; absent for the string path.
5874
- ...result.content !== void 0 ? { content: result.content } : {}
5875
- },
5876
- agentId: inputs.agentId,
5877
- runId: inputs.runId
5878
- }).catch((err) => {
5560
+
5561
+ // src/internal/agent-loop/loop-llm-stream.ts
5562
+ function resolveSystemPromptWithMemoryAdditions(systemPrompt, additions) {
5563
+ if (additions === void 0 || additions.length === 0) return systemPrompt;
5564
+ const block = `<active-memory>
5565
+ ${escapeBlockBody(additions)}
5566
+ </active-memory>`;
5567
+ if (systemPrompt === void 0 || systemPrompt.length === 0) return block;
5568
+ return `${block}
5569
+
5570
+ ${systemPrompt}`;
5571
+ }
5572
+ function toLlmTool(tool) {
5573
+ return { name: tool.name, description: tool.description, inputSchema: tool.inputSchema };
5574
+ }
5575
+ function reasoningEffortFromParams(params) {
5576
+ const thinking = params?.find((p) => p.id === "thinking");
5577
+ return thinking !== void 0 && thinking.value.length > 0 ? thinking.value : void 0;
5578
+ }
5579
+ function emitLlmMetrics(inputs, result, startAt) {
5580
+ inputs.telemetry?.recordHistogram(HISTOGRAM_NAMES.LLM_CALL_DURATION_MS, Date.now() - startAt, {
5581
+ provider: inputs.llm.name
5582
+ });
5583
+ if (result.inputTokens === void 0 && result.outputTokens === void 0) {
5584
+ inputs.telemetry?.recordHistogram(HISTOGRAM_NAMES.LLM_USAGE_MISSING, 1, {
5585
+ provider: inputs.llm.name
5586
+ });
5879
5587
  diag(
5880
- `[theokit-sdk] postToolUse hook error (swallowed): ${err instanceof Error ? err.message : String(err)}
5588
+ `[theokit-sdk] llm usage missing from ${inputs.llm.name} finish \u2014 budget may undercount
5881
5589
  `
5882
5590
  );
5591
+ return;
5592
+ }
5593
+ inputs.telemetry?.recordHistogram(
5594
+ HISTOGRAM_NAMES.LLM_TOKENS,
5595
+ (result.inputTokens ?? 0) + (result.outputTokens ?? 0),
5596
+ { provider: inputs.llm.name }
5597
+ );
5598
+ }
5599
+ async function streamLlmTurn(inputs, ctx) {
5600
+ const llmSpan = inputs.telemetry?.startChildSpan(ctx.sendSpan, "llm.call", {
5601
+ "model.id": inputs.model.id ?? "auto",
5602
+ provider: inputs.llm.name
5603
+ });
5604
+ const startAt = Date.now();
5605
+ const signal = inputs.signal ?? new AbortController().signal;
5606
+ const generator = inputs.llm.stream(
5607
+ {
5608
+ model: inputs.model.id ?? "auto",
5609
+ ...(() => {
5610
+ const effective = resolveSystemPromptWithMemoryAdditions(
5611
+ inputs.systemPrompt,
5612
+ ctx.memorySystemPromptAdditions
5613
+ );
5614
+ return effective !== void 0 ? { system: effective } : {};
5615
+ })(),
5616
+ // issue #47: forward the reasoning effort from ModelSelection.params (the `thinking` param)
5617
+ // so the provider produces reasoning. Absent param ⇒ no `reasoning` field (bare request).
5618
+ ...(() => {
5619
+ const effort = reasoningEffortFromParams(inputs.model.params);
5620
+ return effort !== void 0 ? { reasoning: { effort } } : {};
5621
+ })(),
5622
+ // Step-cap force-close: forward the per-run tool gate (`"none"` on a ceiling round forces a
5623
+ // text close even though tools are advertised). Absent ⇒ provider default (auto).
5624
+ ...inputs.toolChoice !== void 0 ? { toolChoice: inputs.toolChoice } : {},
5625
+ // usetheokit/theokit-sdk#383 — the prompt-cache key, derived HERE and from `inputs.agentId`
5626
+ // because this is the one place that sees the session identity on every round. `agentId` is
5627
+ // the run's session identity (`Agent.getOrCreate(sessionId)`), so the derived key is identical
5628
+ // on round 1 and round 12 of a turn, identical on turn 2 of the same session, and different
5629
+ // for a different session. Deriving it per round from a stable input is what makes it a cache
5630
+ // key; minting one anywhere that runs more than once per session would not be.
5631
+ ...(() => {
5632
+ const key = derivePromptCacheKey(inputs.agentId);
5633
+ return key !== void 0 ? { promptCacheKey: key } : {};
5634
+ })(),
5635
+ messages: ctx.messages,
5636
+ tools: ctx.tools.map(toLlmTool)
5637
+ },
5638
+ signal
5639
+ );
5640
+ const collected = await collectLlmEvents(generator, inputs, ctx);
5641
+ if (collected.errored || collected.finishValue === void 0) {
5642
+ llmSpan?.setAttribute("stopReason", "error");
5643
+ llmSpan?.end();
5644
+ return {
5645
+ text: collected.accumulatedText,
5646
+ toolCalls: [],
5647
+ stopReason: "error",
5648
+ errored: true
5649
+ };
5650
+ }
5651
+ const result = collected.finishValue.value;
5652
+ llmSpan?.setAttributes({
5653
+ stopReason: result.stopReason,
5654
+ inputTokens: result.inputTokens ?? 0,
5655
+ outputTokens: result.outputTokens ?? 0
5883
5656
  });
5657
+ emitLlmMetrics(inputs, result, startAt);
5658
+ llmSpan?.end();
5659
+ const stripped = stripThinkBlocks(collected.accumulatedText);
5660
+ const thinking = result.thinking ?? collected.thinking;
5884
5661
  return {
5885
- type: "tool_result",
5886
- toolUseId: call.id,
5887
- // SE7 — structured content blocks (handler-returned or ToolError-carried)
5888
- // are authoritative; otherwise the legacy string rendering.
5889
- content: result.content !== void 0 ? result.content : renderToolResult(result),
5890
- ...result.exitCode !== 0 && result.exitCode !== void 0 ? { isError: true } : {}
5662
+ text: stripped.visible,
5663
+ toolCalls: result.toolCalls,
5664
+ stopReason: result.stopReason,
5665
+ errored: false,
5666
+ inputTokens: result.inputTokens,
5667
+ outputTokens: result.outputTokens,
5668
+ cacheReadTokens: result.cacheReadTokens,
5669
+ cacheWriteTokens: result.cacheWriteTokens,
5670
+ reasoningTokens: result.reasoningTokens,
5671
+ ...thinking !== void 0 ? { thinking } : {}
5891
5672
  };
5892
5673
  }
5893
- async function emitToolLifecycleDelta(inputs, update) {
5894
- if (inputs.onDelta === void 0) return;
5674
+ async function collectLlmEvents(generator, inputs, ctx) {
5675
+ let errored = false;
5676
+ let finishValue;
5677
+ let thinking;
5678
+ const partial = { text: "" };
5895
5679
  try {
5896
- await inputs.onDelta({ update });
5897
- } catch (err) {
5898
- diag(
5899
- `[theokit-sdk] onDelta tool-lifecycle emit error (swallowed): ${err instanceof Error ? err.message : String(err)}
5900
- `
5901
- );
5680
+ const result = await runCollectorLoop(generator, inputs, ctx, partial);
5681
+ errored = result.errored;
5682
+ finishValue = result.finishValue;
5683
+ thinking = result.thinking;
5684
+ } catch (cause) {
5685
+ if (inputs.signal?.aborted === true) {
5686
+ ctx.finalText = "[aborted]";
5687
+ ctx.events.push(buildAssistantEvent(inputs, "[aborted]"));
5688
+ } else {
5689
+ registerLoopError(ctx, cause);
5690
+ ctx.finalText = partial.text;
5691
+ if (partial.text !== "") ctx.events.push(buildAssistantEvent(inputs, partial.text));
5692
+ }
5693
+ errored = true;
5694
+ }
5695
+ const accumulatedText = partial.text;
5696
+ return {
5697
+ accumulatedText,
5698
+ errored,
5699
+ finishValue,
5700
+ ...thinking !== void 0 ? { thinking } : {}
5701
+ };
5702
+ }
5703
+ function registerLoopError(ctx, cause) {
5704
+ if (ctx.error !== void 0) return;
5705
+ const rawMessage = cause?.message;
5706
+ const message = typeof rawMessage === "string" ? rawMessage : cause instanceof Error ? cause.message : String(cause);
5707
+ const metaCode = cause?.metadata?.code;
5708
+ const rawCode = cause?.code;
5709
+ const code = typeof metaCode === "string" ? metaCode : typeof rawCode === "string" ? rawCode : void 0;
5710
+ ctx.error = code !== void 0 ? { message, code, cause } : { message, cause };
5711
+ }
5712
+ async function consumeStreamEvent(inputs, reasoning, event) {
5713
+ if (event.type === "text_delta") {
5714
+ const text = event.text ?? "";
5715
+ await emitTextDeltaCallback(inputs, text);
5716
+ return text;
5717
+ }
5718
+ if (event.type === "reasoning_delta") {
5719
+ await consumeReasoningDelta(inputs, reasoning, {
5720
+ text: event.text ?? "",
5721
+ ...event.signature !== void 0 ? { signature: event.signature } : {}
5722
+ });
5902
5723
  }
5724
+ return "";
5903
5725
  }
5904
- async function safeEmitToolHook(callback, event) {
5905
- if (callback === void 0) return;
5726
+ async function runCollectorLoop(generator, inputs, ctx, partial) {
5727
+ const reasoning = { text: "", startedAt: void 0, signature: void 0 };
5728
+ let errored = false;
5729
+ let finishValue;
5730
+ let thinking;
5906
5731
  try {
5907
- await callback(event);
5908
- } catch (cause) {
5909
- const msg = cause instanceof Error ? cause.message : String(cause);
5910
- diag(`[theokit-sdk] tool lifecycle hook threw: ${msg}
5911
- `);
5732
+ while (true) {
5733
+ const next = await generator.next();
5734
+ if (next.done === true) {
5735
+ finishValue = next;
5736
+ break;
5737
+ }
5738
+ if (next.value.type === "error") {
5739
+ registerLoopError(ctx, next.value);
5740
+ ctx.finalText = partial.text;
5741
+ errored = true;
5742
+ break;
5743
+ }
5744
+ partial.text += await consumeStreamEvent(inputs, reasoning, next.value);
5745
+ }
5746
+ } finally {
5747
+ thinking = await finalizeReasoning(inputs, ctx, reasoning);
5912
5748
  }
5749
+ return { errored, finishValue, ...thinking !== void 0 ? { thinking } : {} };
5750
+ }
5751
+ async function consumeReasoningDelta(inputs, reasoning, delta) {
5752
+ if (delta.signature !== void 0) reasoning.signature = delta.signature;
5753
+ await accumulateReasoning(inputs, reasoning, delta.text);
5754
+ }
5755
+ async function accumulateReasoning(inputs, reasoning, text) {
5756
+ if (reasoning.startedAt === void 0) reasoning.startedAt = Date.now();
5757
+ reasoning.text += text;
5758
+ await emitReasoningDeltaCallback(inputs, text);
5913
5759
  }
5914
- function buildToolUseRunning(inputs, callId, call) {
5760
+ async function finalizeReasoning(inputs, ctx, reasoning) {
5761
+ if (reasoning.text.length === 0) return void 0;
5762
+ const thinkingDurationMs = reasoning.startedAt === void 0 ? 0 : Date.now() - reasoning.startedAt;
5763
+ ctx.events.push(
5764
+ buildThinkingEvent(inputs, reasoning.text, thinkingDurationMs, reasoning.signature)
5765
+ );
5766
+ await emitThinkingCompletedCallback(inputs, thinkingDurationMs);
5915
5767
  return {
5916
- type: "tool_call",
5917
- agent_id: inputs.agentId,
5918
- run_id: inputs.runId,
5919
- call_id: callId,
5920
- name: call.name,
5921
- status: "running",
5922
- args: call.input
5768
+ type: "thinking",
5769
+ text: reasoning.text,
5770
+ ...reasoning.signature !== void 0 ? { signature: reasoning.signature } : {}
5923
5771
  };
5924
5772
  }
5925
- function buildRepairRegistry(tools) {
5926
- const out = /* @__PURE__ */ new Map();
5927
- for (const t of tools) {
5928
- out.set(t.name, { name: t.name, inputSchema: t.inputSchema });
5929
- }
5930
- return out;
5773
+ async function emitTextDeltaCallback(inputs, text) {
5774
+ if (inputs.onDelta === void 0) return;
5775
+ const cb = inputs.onDelta;
5776
+ await safeCall(
5777
+ () => cb({ update: { type: "text-delta", text } }),
5778
+ void 0,
5779
+ "SendOptions.onDelta"
5780
+ );
5931
5781
  }
5932
- function buildToolUseCompleted(inputs, callId, call, result) {
5933
- return {
5934
- type: "tool_call",
5935
- agent_id: inputs.agentId,
5936
- run_id: inputs.runId,
5937
- call_id: callId,
5938
- name: call.name,
5939
- status: "completed",
5940
- args: call.input,
5941
- result: {
5942
- stdout: result.stdout,
5943
- stderr: result.stderr,
5944
- exitCode: result.exitCode ?? 0
5782
+ async function emitReasoningDeltaCallback(inputs, text) {
5783
+ if (inputs.onDelta === void 0) return;
5784
+ const cb = inputs.onDelta;
5785
+ await safeCall(
5786
+ () => cb({ update: { type: "thinking-delta", text } }),
5787
+ void 0,
5788
+ "SendOptions.onDelta"
5789
+ );
5790
+ }
5791
+ async function emitThinkingCompletedCallback(inputs, thinkingDurationMs) {
5792
+ if (inputs.onDelta === void 0) return;
5793
+ const cb = inputs.onDelta;
5794
+ await safeCall(
5795
+ () => cb({ update: { type: "thinking-completed", thinkingDurationMs } }),
5796
+ void 0,
5797
+ "SendOptions.onDelta"
5798
+ );
5799
+ }
5800
+
5801
+ // src/internal/agent-loop/loop-thinking-steps.ts
5802
+ function thinkingStep(thinking) {
5803
+ return {
5804
+ type: "thinkingMessage",
5805
+ message: {
5806
+ text: thinking.text,
5807
+ ...thinking.signature !== void 0 ? { signature: thinking.signature } : {}
5945
5808
  }
5946
5809
  };
5947
5810
  }
5811
+ function recordThinkingOnSilentToolRound(ctx, text, thinking) {
5812
+ if (text.length > 0 || thinking === void 0) return;
5813
+ ctx.conversation.push({
5814
+ type: "agentConversationTurn",
5815
+ turn: { steps: [thinkingStep(thinking)] }
5816
+ });
5817
+ }
5948
5818
 
5949
- // src/internal/agent-loop/tool-result-guard.ts
5950
- var OPEN = "<untrusted-tool-output>";
5951
- var CLOSE = "</untrusted-tool-output>";
5952
- var PII_PATTERNS = [
5953
- /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/g,
5954
- // email
5955
- /\b(?:\+?\d{1,3}[-.\s]?)?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}\b/g
5956
- // phone
5957
- ];
5958
- function guardText(content, opts) {
5959
- let out = content;
5960
- if (opts.redactPii === true) {
5961
- for (const re of PII_PATTERNS) out = out.replace(re, "[REDACTED]");
5819
+ // src/internal/tool-dispatch/repair-middleware.ts
5820
+ var DECIMAL_RE = /^-?\d+(\.\d+)?$/;
5821
+ function repairToolCall(raw, registry) {
5822
+ const repairs = [];
5823
+ let call = { ...raw };
5824
+ if (!registry.has(call.name)) {
5825
+ const lower = call.name.toLowerCase();
5826
+ let match;
5827
+ for (const key of registry.keys()) {
5828
+ if (key.toLowerCase() === lower) {
5829
+ match = key;
5830
+ break;
5831
+ }
5832
+ }
5833
+ if (match !== void 0) {
5834
+ repairs.push(`name: "${call.name}" \u2192 "${match}"`);
5835
+ call = { ...call, name: match };
5836
+ }
5962
5837
  }
5963
- if (opts.delimit === true) {
5964
- const safe2 = out.split(CLOSE).join("</ untrusted-tool-output>");
5965
- out = `${OPEN}
5966
- ${safe2}
5967
- ${CLOSE}`;
5838
+ if (typeof call.args === "string") {
5839
+ try {
5840
+ const parsed = JSON.parse(call.args);
5841
+ call = { ...call, args: parsed };
5842
+ repairs.push("args: parsed from string");
5843
+ } catch {
5844
+ }
5968
5845
  }
5969
- return out;
5846
+ const tool = registry.get(call.name);
5847
+ if (tool !== void 0 && typeof call.args === "object" && call.args !== null && !Array.isArray(call.args)) {
5848
+ const coerced = coerceArgsToSchema(call.args, tool.inputSchema);
5849
+ if (coerced.changed.length > 0) {
5850
+ call = { ...call, args: coerced.value };
5851
+ repairs.push(...coerced.changed);
5852
+ }
5853
+ }
5854
+ return { call, repairs };
5970
5855
  }
5971
- function applyToolResultGuard(parts, opts) {
5972
- if (opts.delimit !== true && opts.redactPii !== true) return parts;
5973
- return parts.map(
5974
- (p) => (
5975
- // SE7 guard the TEXT of a tool result (string or the text blocks of a
5976
- // structured content); image blocks pass through untouched.
5977
- p.type === "tool_result" ? { ...p, content: renderToolResultContentText(p.content, (t) => guardText(t, opts)) } : p
5978
- )
5979
- );
5856
+ function coerceArgsToSchema(args, schema) {
5857
+ const changed = [];
5858
+ const out = { ...args };
5859
+ const properties = schema.properties;
5860
+ if (properties === void 0) return { value: out, changed };
5861
+ for (const [key, propDef] of Object.entries(properties)) {
5862
+ const val = out[key];
5863
+ if (typeof val !== "string") continue;
5864
+ const propType = propDef.type;
5865
+ if (typeof propType !== "string") continue;
5866
+ if (propType === "number" && DECIMAL_RE.test(val.trim())) {
5867
+ out[key] = Number(val);
5868
+ changed.push(`${key}: string\u2192number`);
5869
+ } else if (propType === "integer" && /^-?\d+$/.test(val.trim())) {
5870
+ out[key] = Number(val);
5871
+ changed.push(`${key}: string\u2192integer`);
5872
+ } else if (propType === "boolean" && (val === "true" || val === "false")) {
5873
+ out[key] = val === "true";
5874
+ changed.push(`${key}: string\u2192boolean`);
5875
+ } else if (propType === "array" || propType === "object") {
5876
+ try {
5877
+ const parsed = JSON.parse(val);
5878
+ if (propType === "array" && Array.isArray(parsed)) {
5879
+ out[key] = parsed;
5880
+ changed.push(`${key}: string\u2192array`);
5881
+ } else if (propType === "object" && typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)) {
5882
+ out[key] = parsed;
5883
+ changed.push(`${key}: string\u2192object`);
5884
+ }
5885
+ } catch {
5886
+ }
5887
+ }
5888
+ }
5889
+ return { value: out, changed };
5980
5890
  }
5981
5891
 
5982
- // src/internal/budget/pricing-data.json
5983
- var pricing_data_default = {
5984
- _meta: {
5985
- pricingVersion: "litellm-2026-05-snapshot"},
5986
- models: {
5987
- "anthropic/claude-opus-4-7": {
5988
- input: 5,
5989
- output: 25,
5990
- cacheRead: 0.5,
5991
- cacheWrite: 6.25
5992
- },
5993
- "anthropic/claude-opus-4-6": {
5994
- input: 5,
5995
- output: 25,
5996
- cacheRead: 0.5,
5997
- cacheWrite: 6.25
5998
- },
5999
- "anthropic/claude-opus-4-5": {
6000
- input: 5,
6001
- output: 25,
6002
- cacheRead: 0.5,
6003
- cacheWrite: 6.25
6004
- },
6005
- "anthropic/claude-sonnet-4-6": {
6006
- input: 3,
6007
- output: 15,
6008
- cacheRead: 0.3,
6009
- cacheWrite: 3.75
6010
- },
6011
- "anthropic/claude-sonnet-4-5": {
6012
- input: 3,
6013
- output: 15,
6014
- cacheRead: 0.3,
6015
- cacheWrite: 3.75
6016
- },
6017
- "anthropic/claude-haiku-4-5": {
6018
- input: 1,
6019
- output: 5,
6020
- cacheRead: 0.1,
6021
- cacheWrite: 1.25
6022
- },
6023
- "anthropic/claude-3-5-sonnet": {
6024
- input: 3,
6025
- output: 15,
6026
- cacheRead: 0.3,
6027
- cacheWrite: 3.75
6028
- },
6029
- "anthropic/claude-3-5-haiku": {
6030
- input: 0.8,
6031
- output: 4,
6032
- cacheRead: 0.08,
6033
- cacheWrite: 1
6034
- },
6035
- "anthropic/claude-3-opus": {
6036
- input: 15,
6037
- output: 75,
6038
- cacheRead: 1.5,
6039
- cacheWrite: 18.75
6040
- },
6041
- "anthropic/claude-3-haiku": {
6042
- input: 0.25,
6043
- output: 1.25,
6044
- cacheRead: 0.03,
6045
- cacheWrite: 0.3
6046
- },
6047
- "openai/gpt-4o": {
6048
- input: 2.5,
6049
- output: 10,
6050
- cacheRead: 1.25
6051
- },
6052
- "openai/gpt-4o-mini": {
6053
- input: 0.15,
6054
- output: 0.6,
6055
- cacheRead: 0.075
6056
- },
6057
- "openai/gpt-4.1": {
6058
- input: 2,
6059
- output: 8,
6060
- cacheRead: 0.5
6061
- },
6062
- "openai/gpt-4.1-mini": {
6063
- input: 0.4,
6064
- output: 1.6,
6065
- cacheRead: 0.1
6066
- },
6067
- "openai/gpt-4.1-nano": {
6068
- input: 0.1,
6069
- output: 0.4,
6070
- cacheRead: 0.025
6071
- },
6072
- "openai/o3": {
6073
- input: 2,
6074
- output: 8,
6075
- cacheRead: 0.5
6076
- },
6077
- "openai/o3-mini": {
6078
- input: 1.1,
6079
- output: 4.4,
6080
- cacheRead: 0.55
6081
- },
6082
- "openai/o4-mini": {
6083
- input: 1.1,
6084
- output: 4.4,
6085
- cacheRead: 0.275
6086
- },
6087
- "deepseek/deepseek-chat": {
6088
- input: 0.14,
6089
- output: 0.28
6090
- },
6091
- "deepseek/deepseek-reasoner": {
6092
- input: 0.55,
6093
- output: 2.19
6094
- },
6095
- "google/gemini-2.5-pro": {
6096
- input: 1.25,
6097
- output: 10
6098
- },
6099
- "google/gemini-2.5-flash": {
6100
- input: 0.15,
6101
- output: 0.6
6102
- },
6103
- "google/gemini-2.0-flash": {
6104
- input: 0.1,
6105
- output: 0.4
6106
- }
5892
+ // src/tool-error.ts
5893
+ var ToolError = class extends TheokitAgentError {
5894
+ name = "ToolError";
5895
+ /** The error content surfaced to the model: a string, or text/image blocks. */
5896
+ content;
5897
+ constructor(content, options = {}) {
5898
+ super(renderToolErrorMessage(content), { ...options, isRetryable: false });
5899
+ this.content = content;
5900
+ }
5901
+ };
5902
+ function renderToolErrorMessage(content) {
5903
+ if (typeof content === "string") return content;
5904
+ return content.map((block) => block.type === "text" ? block.text : `[${block.source.media_type} image]`).join("\n");
5905
+ }
5906
+
5907
+ // src/internal/runtime/tools/shell-tool.ts
5908
+ async function runShell(options) {
5909
+ if (options.sandbox === true && isObviouslyUnsafe(options.command)) {
5910
+ return {
5911
+ stdout: "",
5912
+ stderr: `Sandbox refused command: ${options.command}`,
5913
+ exitCode: 126,
5914
+ timedOut: false
5915
+ };
6107
5916
  }
6108
- };
6109
-
6110
- // src/internal/budget/pricing-registry.ts
6111
- var data = pricing_data_default;
6112
- function buildEntry(key, raw) {
6113
- const [provider, ...modelParts] = key.split("/");
5917
+ const result = await spawnAndCollect({
5918
+ command: "sh",
5919
+ args: ["-c", options.command],
5920
+ cwd: options.cwd,
5921
+ ...options.env !== void 0 ? { env: options.env } : {},
5922
+ ...options.timeoutMs !== void 0 ? { timeoutMs: options.timeoutMs } : {}
5923
+ });
5924
+ const stderr = result.spawnError !== void 0 ? result.stderr + result.spawnError.message : result.stderr;
6114
5925
  return {
6115
- provider: provider ?? "unknown",
6116
- model: modelParts.join("/"),
6117
- inputCostPerMillion: raw.input,
6118
- outputCostPerMillion: raw.output,
6119
- ...raw.cacheRead !== void 0 ? { cacheReadCostPerMillion: raw.cacheRead } : {},
6120
- ...raw.cacheWrite !== void 0 ? { cacheWriteCostPerMillion: raw.cacheWrite } : {},
6121
- ...raw.reasoning !== void 0 ? { reasoningCostPerMillion: raw.reasoning } : {},
6122
- pricingVersion: data._meta.pricingVersion
5926
+ stdout: result.stdout,
5927
+ stderr,
5928
+ exitCode: result.exitCode,
5929
+ timedOut: result.timedOut
6123
5930
  };
6124
5931
  }
6125
- function stripDateSuffix(model) {
6126
- return model.replace(/-\d{4}-?\d{2}-?\d{2}$/, "");
5932
+ function isObviouslyUnsafe(command) {
5933
+ if (/(^|\s)(rm|mv|cp)\s+[^|;]*\s+\/(etc|var|root)\b/.test(command)) return true;
5934
+ if (/sudo\s/.test(command)) return true;
5935
+ return false;
6127
5936
  }
6128
- function normalizeAnthropicDots(model) {
6129
- return model.replace(/(?<=\d)\.(?=\d)/g, "-");
5937
+
5938
+ // src/internal/agent-loop/tool-executors.ts
5939
+ async function executeTool(inputs, resolved, call) {
5940
+ if (resolved === void 0) {
5941
+ return { stdout: "", stderr: `Unknown tool ${call.name}`, exitCode: 127 };
5942
+ }
5943
+ if (resolved.origin === "shell") return runShellTool(inputs, call);
5944
+ if (resolved.origin === "memory")
5945
+ return runHandlerTool("memory", resolved.memoryHandler, call, {
5946
+ context: inputs.context,
5947
+ threadId: inputs.agentId
5948
+ });
5949
+ if (resolved.origin === "custom")
5950
+ return runHandlerTool("custom", resolved.customHandler, call, {
5951
+ signal: inputs.signal,
5952
+ context: inputs.context,
5953
+ messages: inputs.messages,
5954
+ threadId: inputs.agentId
5955
+ });
5956
+ return runMcpTool(inputs, resolved, call);
6130
5957
  }
6131
- function stripOpenRouterPrefix(modelId) {
6132
- return modelId.startsWith("openrouter/") ? modelId.slice("openrouter/".length) : modelId;
5958
+ async function runHandlerTool(kind, handler, call, ctx) {
5959
+ const { signal, context, messages, threadId } = ctx;
5960
+ if (handler === void 0) {
5961
+ return { stdout: "", stderr: `${kind} tool ${call.name} has no handler`, exitCode: 127 };
5962
+ }
5963
+ try {
5964
+ const split = handler[TOOL_SPLIT_RESOLVER];
5965
+ if (split !== void 0) {
5966
+ const { model, app } = await split(call.input, { signal, context, threadId });
5967
+ const base = typeof model === "string" ? { stdout: model, stderr: "", exitCode: 0 } : { stdout: "", stderr: "", exitCode: 0, content: model };
5968
+ return { ...base, appResult: app };
5969
+ }
5970
+ const out = await handler(call.input, { signal, context, messages, threadId });
5971
+ if (typeof out !== "string") return { stdout: "", stderr: "", exitCode: 0, content: out };
5972
+ return { stdout: out, stderr: "", exitCode: 0 };
5973
+ } catch (cause) {
5974
+ if (cause instanceof ToolError) {
5975
+ return { stdout: "", stderr: cause.message, exitCode: 1, content: cause.content };
5976
+ }
5977
+ const message = cause instanceof Error ? cause.message : String(cause);
5978
+ return { stdout: "", stderr: message, exitCode: 1 };
5979
+ }
6133
5980
  }
6134
- function lookupRaw(key) {
6135
- return data.models[key];
5981
+ async function runShellTool(inputs, call) {
5982
+ const command = typeof call.input.command === "string" ? call.input.command : JSON.stringify(call.input);
5983
+ const shellOptions = {
5984
+ command,
5985
+ cwd: inputs.shellCwd,
5986
+ sandbox: inputs.shellSandbox
5987
+ };
5988
+ const result = await runShell(shellOptions);
5989
+ const final = { stdout: result.stdout, stderr: result.stderr };
5990
+ if (result.exitCode !== null && result.exitCode !== void 0) final.exitCode = result.exitCode;
5991
+ return final;
6136
5992
  }
6137
- function getPricingEntry(opts) {
6138
- const cleaned = stripOpenRouterPrefix(opts.model);
6139
- const directKey = `${opts.provider}/${cleaned}`;
6140
- const direct = lookupRaw(directKey);
6141
- if (direct !== void 0) return buildEntry(directKey, direct);
6142
- const noSuffix = stripDateSuffix(cleaned);
6143
- if (noSuffix !== cleaned) {
6144
- const noSuffixKey = `${opts.provider}/${noSuffix}`;
6145
- const found = lookupRaw(noSuffixKey);
6146
- if (found !== void 0) return buildEntry(noSuffixKey, found);
5993
+ async function runMcpTool(inputs, resolved, call) {
5994
+ const client = inputs.mcp.get(resolved.mcpServerName ?? "");
5995
+ if (client === void 0 || resolved.mcpToolName === void 0) {
5996
+ return {
5997
+ stdout: "",
5998
+ stderr: `MCP server ${resolved.mcpServerName ?? "?"} not connected`,
5999
+ exitCode: 127
6000
+ };
6147
6001
  }
6148
- if (opts.provider === "anthropic") {
6149
- const normalized = normalizeAnthropicDots(stripDateSuffix(cleaned));
6150
- const normKey = `${opts.provider}/${normalized}`;
6151
- const found = lookupRaw(normKey);
6152
- if (found !== void 0) return buildEntry(normKey, found);
6002
+ try {
6003
+ const response = await client.callTool(resolved.mcpToolName, call.input);
6004
+ const text = response.content.filter((part) => part.type === "text").map((part) => part.text).join("\n");
6005
+ return { stdout: text, stderr: "", exitCode: response.isError === true ? 1 : 0 };
6006
+ } catch (cause) {
6007
+ const message = cause instanceof Error ? cause.message : String(cause);
6008
+ return { stdout: "", stderr: message, exitCode: 1 };
6153
6009
  }
6154
- if (cleaned.includes("/")) {
6155
- const found = lookupRaw(cleaned);
6156
- if (found !== void 0) return buildEntry(cleaned, found);
6157
- const stripped = stripDateSuffix(cleaned);
6158
- if (stripped !== cleaned) {
6159
- const found2 = lookupRaw(stripped);
6160
- if (found2 !== void 0) return buildEntry(stripped, found2);
6161
- }
6010
+ }
6011
+ function renderToolResult(result) {
6012
+ if (result.stderr.length > 0 && (result.exitCode ?? 0) !== 0) {
6013
+ return `${result.stdout}
6014
+ [stderr]
6015
+ ${result.stderr}`.trim();
6162
6016
  }
6163
- const catalogEntry = catalogCostFallback(opts.provider, cleaned);
6164
- if (catalogEntry !== void 0) return catalogEntry;
6165
- return void 0;
6017
+ return result.stdout.trim();
6166
6018
  }
6167
- function catalogCostFallback(provider, cleanedModel) {
6168
- const stripped = stripDateSuffix(cleanedModel);
6169
- const candidates = [`${provider}/${cleanedModel}`, cleanedModel];
6170
- if (stripped !== cleanedModel) candidates.push(`${provider}/${stripped}`, stripped);
6171
- for (const key of candidates) {
6172
- const info = getCatalogModelInfo(key);
6173
- const cost = info?.cost;
6174
- if (cost === void 0) continue;
6175
- const [prov, ...modelParts] = key.split("/");
6176
- return {
6177
- provider: prov ?? provider,
6178
- model: modelParts.join("/") || cleanedModel,
6179
- inputCostPerMillion: cost.input,
6180
- outputCostPerMillion: cost.output,
6181
- ...cost.cache_read !== void 0 ? { cacheReadCostPerMillion: cost.cache_read } : {},
6182
- ...cost.cache_write !== void 0 ? { cacheWriteCostPerMillion: cost.cache_write } : {},
6183
- // M44 M5 fix honest provenance: a key patched by the LIVE models-dev source is not "vendored".
6184
- pricingVersion: isPatchedModelKey(key) ? "catalog-models-dev" : "catalog-vendored"
6019
+
6020
+ // src/internal/agent-loop/tool-timeout.ts
6021
+ var TOOL_ABORTED_EXIT = 124;
6022
+ function abortedResult(signal) {
6023
+ const reason = signal.reason;
6024
+ const timedOut = reason?.name === "TimeoutError";
6025
+ return {
6026
+ stdout: "",
6027
+ stderr: timedOut ? "tool execution timed out" : "tool execution aborted",
6028
+ exitCode: TOOL_ABORTED_EXIT
6029
+ };
6030
+ }
6031
+ function raceToolExecution(exec, opts) {
6032
+ const { signal, timeoutMs } = opts;
6033
+ if (signal === void 0 && timeoutMs === void 0) return exec;
6034
+ const signals = [];
6035
+ if (signal !== void 0) signals.push(signal);
6036
+ if (timeoutMs !== void 0) signals.push(AbortSignal.timeout(timeoutMs));
6037
+ const merged = signals.length === 1 ? signals[0] : AbortSignal.any(signals);
6038
+ if (merged.aborted) return Promise.resolve(abortedResult(merged));
6039
+ return new Promise((resolve, reject) => {
6040
+ let settled = false;
6041
+ const onAbort = () => {
6042
+ if (settled) return;
6043
+ settled = true;
6044
+ resolve(abortedResult(merged));
6185
6045
  };
6046
+ merged.addEventListener("abort", onAbort, { once: true });
6047
+ exec.then(
6048
+ (r) => {
6049
+ if (settled) return;
6050
+ settled = true;
6051
+ merged.removeEventListener("abort", onAbort);
6052
+ resolve(r);
6053
+ },
6054
+ (e) => {
6055
+ if (settled) return;
6056
+ settled = true;
6057
+ merged.removeEventListener("abort", onAbort);
6058
+ reject(e);
6059
+ }
6060
+ );
6061
+ });
6062
+ }
6063
+
6064
+ // src/internal/agent-loop/tool-dispatch.ts
6065
+ async function dispatchTools(inputs, tools, toolCalls, events, parentSpan) {
6066
+ const maxConcurrent = inputs.maxConcurrentTools ?? 4;
6067
+ return mapWithConcurrency(
6068
+ toolCalls,
6069
+ maxConcurrent,
6070
+ (call) => dispatchSingleCall(inputs, tools, call, events, parentSpan)
6071
+ );
6072
+ }
6073
+ async function dispatchSingleCall(inputs, tools, call, events, parentSpan) {
6074
+ const { call: workingCall, repairs } = applyRepairAndExtractCall(tools, call);
6075
+ const dc = {
6076
+ inputs,
6077
+ call: workingCall,
6078
+ callId: generateCallId(),
6079
+ events,
6080
+ parentSpan
6081
+ };
6082
+ const forkVeto = vetoFromForkWhitelist(dc);
6083
+ if (forkVeto !== void 0) return forkVeto;
6084
+ const resolved = tools.find((tool) => tool.name === workingCall.name);
6085
+ const toolSpan = startToolCallSpan(dc, resolved, repairs);
6086
+ events.push(buildToolUseRunning(dc));
6087
+ const pluginVeto = await vetoFromPluginPreHook(dc);
6088
+ if (pluginVeto !== void 0) {
6089
+ toolSpan?.setAttribute("tool.vetoed", true);
6090
+ toolSpan?.setAttribute("tool.veto_source", "plugin");
6091
+ toolSpan?.end();
6092
+ return pluginVeto;
6186
6093
  }
6187
- return void 0;
6094
+ const fileVeto = await vetoFromFileHookPreDecision(dc);
6095
+ if (fileVeto !== void 0) {
6096
+ toolSpan?.setAttribute("tool.vetoed", true);
6097
+ toolSpan?.setAttribute("tool.veto_source", "file_hook");
6098
+ toolSpan?.end();
6099
+ return fileVeto;
6100
+ }
6101
+ emitRunEvent(inputs.runEventSink, {
6102
+ type: "tool_progress",
6103
+ toolName: workingCall.name,
6104
+ toolCallId: dc.callId
6105
+ });
6106
+ const result = await runToolWithLifecycle(dc, resolved);
6107
+ await inputs.pluginManager?.runPostToolCallHooks({
6108
+ name: workingCall.name,
6109
+ args: workingCall.input,
6110
+ result: { stdout: result.stdout, stderr: result.stderr, exitCode: result.exitCode },
6111
+ agentId: inputs.agentId,
6112
+ runId: inputs.runId
6113
+ });
6114
+ return finalizeSpanAndPostHook(dc, result, toolSpan);
6115
+ }
6116
+ function applyRepairAndExtractCall(tools, call) {
6117
+ const registryMap = buildRepairRegistry(tools);
6118
+ const repaired = repairToolCall({ name: call.name, args: call.input, id: call.id }, registryMap);
6119
+ if (repaired.repairs.length === 0) return { call, repairs: repaired.repairs };
6120
+ return {
6121
+ call: {
6122
+ ...call,
6123
+ name: repaired.call.name,
6124
+ input: repaired.call.args ?? {}
6125
+ },
6126
+ repairs: repaired.repairs
6127
+ };
6128
+ }
6129
+ function vetoFromForkWhitelist(dc) {
6130
+ const { inputs, call, callId, events } = dc;
6131
+ const whitelistDecision = checkToolWhitelist(call.name);
6132
+ if (whitelistDecision.allowed) return void 0;
6133
+ emitRunEvent(inputs.runEventSink, {
6134
+ type: "permission_denied",
6135
+ toolName: call.name,
6136
+ toolCallId: callId,
6137
+ source: "fork_whitelist",
6138
+ message: whitelistDecision.reason ?? "tool not available in fork"
6139
+ });
6140
+ events.push(buildToolUseRunning(dc));
6141
+ events.push(
6142
+ buildToolUseCompleted(dc, {
6143
+ stdout: "",
6144
+ stderr: whitelistDecision.reason ?? "tool not available in fork",
6145
+ exitCode: 126
6146
+ })
6147
+ );
6148
+ return {
6149
+ type: "tool_result",
6150
+ toolUseId: call.id,
6151
+ content: `Tool blocked by fork whitelist: ${whitelistDecision.reason}`
6152
+ };
6188
6153
  }
6189
-
6190
- // src/internal/budget/compute-cost.ts
6191
- var MICROCENT = 1e6;
6192
- function isSubscriptionIncluded(provider) {
6193
- return provider === "openai-codex" || provider === "codex";
6154
+ function startToolCallSpan(dc, resolved, repairs) {
6155
+ const { inputs, call, callId, parentSpan } = dc;
6156
+ const toolSpan = inputs.telemetry?.startChildSpan(parentSpan, "tool.call", {
6157
+ "tool.name": call.name,
6158
+ "tool.origin": resolved?.origin ?? "unknown",
6159
+ callId
6160
+ });
6161
+ if (repairs.length > 0 && toolSpan !== void 0) {
6162
+ toolSpan.setAttribute("tool.repairs", repairs.join("; "));
6163
+ }
6164
+ if (toolSpan !== void 0 && inputs.telemetry?.includeContent === true) {
6165
+ toolSpan.addEvent("args", { input: JSON.stringify(call.input) });
6166
+ }
6167
+ return toolSpan;
6194
6168
  }
6195
- function pricingHasValidRates(entry) {
6196
- 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);
6169
+ async function vetoFromPluginPreHook(dc) {
6170
+ const { inputs, call, callId, events } = dc;
6171
+ const pluginVeto = await inputs.pluginManager?.runPreToolCallHooks({
6172
+ name: call.name,
6173
+ args: call.input,
6174
+ agentId: inputs.agentId,
6175
+ runId: inputs.runId,
6176
+ // SE1 — thread the run's permission mode so a PermissionPlugin gates per-run.
6177
+ ...inputs.permissionMode !== void 0 ? { permissionMode: inputs.permissionMode } : {}
6178
+ });
6179
+ if (pluginVeto === void 0) return void 0;
6180
+ emitRunEvent(inputs.runEventSink, {
6181
+ type: "permission_denied",
6182
+ toolName: call.name,
6183
+ toolCallId: callId,
6184
+ source: "plugin",
6185
+ message: pluginVeto.message
6186
+ });
6187
+ events.push(
6188
+ buildToolUseCompleted(dc, {
6189
+ stdout: "",
6190
+ stderr: pluginVeto.message,
6191
+ exitCode: 126
6192
+ })
6193
+ );
6194
+ return {
6195
+ type: "tool_result",
6196
+ toolUseId: call.id,
6197
+ content: `Plugin blocked this tool call: ${pluginVeto.message}`
6198
+ };
6197
6199
  }
6198
- function costForTokens(tokens, perMillion) {
6199
- if (tokens === 0 || perMillion === 0) return 0;
6200
- return Math.round(tokens * perMillion * MICROCENT / 1e6) / MICROCENT;
6200
+ async function vetoFromFileHookPreDecision(dc) {
6201
+ const { inputs, call, callId, events } = dc;
6202
+ const preDecision = await inputs.hooks.run({
6203
+ event: "preToolUse",
6204
+ tool: call.name,
6205
+ input: call.input,
6206
+ agentId: inputs.agentId,
6207
+ runId: inputs.runId
6208
+ });
6209
+ if (!preDecision.blocked) return void 0;
6210
+ emitRunEvent(inputs.runEventSink, {
6211
+ type: "permission_denied",
6212
+ toolName: call.name,
6213
+ toolCallId: callId,
6214
+ source: "file_hook",
6215
+ message: preDecision.reason ?? "blocked by hook"
6216
+ });
6217
+ events.push(
6218
+ buildToolUseCompleted(dc, {
6219
+ stdout: "",
6220
+ stderr: preDecision.reason ?? "blocked by hook",
6221
+ exitCode: 126
6222
+ })
6223
+ );
6224
+ return {
6225
+ type: "tool_result",
6226
+ toolUseId: call.id,
6227
+ content: `Hook denied this tool call: ${preDecision.reason ?? "no reason given"}`
6228
+ };
6201
6229
  }
6202
- function computeCost(args) {
6203
- if (isSubscriptionIncluded(args.provider)) {
6204
- return {
6205
- amountUsd: 0,
6206
- status: "included",
6207
- currency: "USD",
6208
- source: "subscription_included",
6209
- pricingVersion: void 0
6210
- };
6211
- }
6212
- const entry = getPricingEntry({
6213
- provider: args.provider,
6214
- model: args.model,
6215
- ...args.baseUrl !== void 0 ? { baseUrl: args.baseUrl } : {}
6230
+ async function runToolWithLifecycle(dc, resolved) {
6231
+ const { inputs, call, callId } = dc;
6232
+ const startAt = Date.now();
6233
+ await safeEmitToolHook(inputs.onToolStart, {
6234
+ toolName: call.name,
6235
+ args: call.input,
6236
+ conversationId: inputs.agentId,
6237
+ callId
6216
6238
  });
6217
- if (entry === void 0) {
6218
- return {
6219
- amountUsd: void 0,
6220
- status: "unknown",
6221
- currency: "USD",
6222
- source: "unknown",
6223
- pricingVersion: void 0
6224
- };
6239
+ await emitToolLifecycleDelta(inputs, {
6240
+ type: "tool-call-started",
6241
+ callId,
6242
+ toolCall: { callId, name: call.name, args: call.input },
6243
+ modelCallId: callId
6244
+ });
6245
+ const result = await raceToolExecution(executeTool(inputs, resolved, call), {
6246
+ signal: inputs.signal,
6247
+ timeoutMs: inputs.perToolTimeoutMs
6248
+ });
6249
+ const durationMs = Date.now() - startAt;
6250
+ await emitToolLifecycleDelta(inputs, {
6251
+ type: "tool-call-completed",
6252
+ callId,
6253
+ toolCall: {
6254
+ callId,
6255
+ name: call.name,
6256
+ args: call.input,
6257
+ result: result.content !== void 0 ? result.content : renderToolResult(result)
6258
+ },
6259
+ modelCallId: callId
6260
+ });
6261
+ inputs.telemetry?.recordHistogram(HISTOGRAM_NAMES.TOOL_CALL_DURATION_MS, durationMs, {
6262
+ "tool.name": call.name
6263
+ });
6264
+ if (result.exitCode !== void 0 && result.exitCode !== 0 && result.exitCode !== null) {
6265
+ await safeEmitToolHook(inputs.onToolError, {
6266
+ toolName: call.name,
6267
+ args: call.input,
6268
+ error: new Error(result.stderr || `tool exited with code ${result.exitCode}`),
6269
+ conversationId: inputs.agentId,
6270
+ callId,
6271
+ durationMs,
6272
+ attempt: 1
6273
+ });
6274
+ } else {
6275
+ await safeEmitToolHook(inputs.onToolEnd, {
6276
+ toolName: call.name,
6277
+ args: call.input,
6278
+ // SE17 — when a `toModelOutput` split is active, observability gets the FULL
6279
+ // raw output (`appResult`), NOT the compact model-facing value. SE7 — a
6280
+ // block-returning handler has empty `stdout`; surface its structured content
6281
+ // to the hook instead of an empty string.
6282
+ result: result.appResult !== void 0 ? result.appResult : result.content !== void 0 ? result.content : result.stdout,
6283
+ conversationId: inputs.agentId,
6284
+ callId,
6285
+ durationMs
6286
+ });
6225
6287
  }
6226
- if (!pricingHasValidRates(entry)) {
6227
- return {
6228
- amountUsd: void 0,
6229
- status: "unknown",
6230
- currency: "USD",
6231
- source: "unknown",
6232
- pricingVersion: entry.pricingVersion,
6233
- notes: ["pricing entry has negative rates; treated as invalid"]
6234
- };
6288
+ return result;
6289
+ }
6290
+ function finalizeSpanAndPostHook(dc, result, toolSpan) {
6291
+ const { inputs, call, events } = dc;
6292
+ toolSpan?.setAttribute("exitCode", result.exitCode ?? 0);
6293
+ if (toolSpan !== void 0 && inputs.telemetry?.includeContent === true) {
6294
+ toolSpan.addEvent("result", { stdout: result.stdout.slice(0, 1e3) });
6235
6295
  }
6236
- const notes = [];
6237
- const detail = {};
6238
- const u = args.usage;
6239
- const inputCost = costForTokens(u.inputTokens, entry.inputCostPerMillion);
6240
- const outputCost = costForTokens(u.outputTokens, entry.outputCostPerMillion);
6241
- detail.input = inputCost;
6242
- detail.output = outputCost;
6243
- let total = inputCost + outputCost;
6244
- if (u.cacheReadTokens !== void 0 && u.cacheReadTokens > 0) {
6245
- if (entry.cacheReadCostPerMillion === void 0) {
6246
- return {
6247
- amountUsd: void 0,
6248
- status: "unknown",
6249
- currency: "USD",
6250
- source: "litellm_snapshot",
6251
- pricingVersion: entry.pricingVersion,
6252
- notes: ["cache-read tokens present but cacheReadCostPerMillion is undefined"]
6253
- };
6254
- }
6255
- const c = costForTokens(u.cacheReadTokens, entry.cacheReadCostPerMillion);
6256
- detail.cacheRead = c;
6257
- total += c;
6296
+ toolSpan?.end();
6297
+ events.push(buildToolUseCompleted(dc, result));
6298
+ inputs.hooks.run({
6299
+ event: "postToolUse",
6300
+ tool: call.name,
6301
+ input: call.input,
6302
+ output: {
6303
+ stdout: result.stdout,
6304
+ stderr: result.stderr,
6305
+ exitCode: result.exitCode ?? 0,
6306
+ // SE7 — structured content (text + image blocks) when the handler
6307
+ // returned/threw blocks; absent for the string path.
6308
+ ...result.content !== void 0 ? { content: result.content } : {}
6309
+ },
6310
+ agentId: inputs.agentId,
6311
+ runId: inputs.runId
6312
+ }).catch((err) => {
6313
+ diag(
6314
+ `[theokit-sdk] postToolUse hook error (swallowed): ${err instanceof Error ? err.message : String(err)}
6315
+ `
6316
+ );
6317
+ });
6318
+ return {
6319
+ type: "tool_result",
6320
+ toolUseId: call.id,
6321
+ // SE7 — structured content blocks (handler-returned or ToolError-carried)
6322
+ // are authoritative; otherwise the legacy string rendering.
6323
+ content: result.content !== void 0 ? result.content : renderToolResult(result),
6324
+ ...result.exitCode !== 0 && result.exitCode !== void 0 ? { isError: true } : {}
6325
+ };
6326
+ }
6327
+ async function emitToolLifecycleDelta(inputs, update) {
6328
+ if (inputs.onDelta === void 0) return;
6329
+ try {
6330
+ await inputs.onDelta({ update });
6331
+ } catch (err) {
6332
+ diag(
6333
+ `[theokit-sdk] onDelta tool-lifecycle emit error (swallowed): ${err instanceof Error ? err.message : String(err)}
6334
+ `
6335
+ );
6258
6336
  }
6259
- if (u.cacheWriteTokens !== void 0 && u.cacheWriteTokens > 0) {
6260
- if (entry.cacheWriteCostPerMillion === void 0) {
6261
- return {
6262
- amountUsd: void 0,
6263
- status: "unknown",
6264
- currency: "USD",
6265
- source: "litellm_snapshot",
6266
- pricingVersion: entry.pricingVersion,
6267
- notes: ["cache-write tokens present but cacheWriteCostPerMillion is undefined"]
6268
- };
6269
- }
6270
- const c = costForTokens(u.cacheWriteTokens, entry.cacheWriteCostPerMillion);
6271
- detail.cacheWrite = c;
6272
- total += c;
6337
+ }
6338
+ async function safeEmitToolHook(callback, event) {
6339
+ if (callback === void 0) return;
6340
+ try {
6341
+ await callback(event);
6342
+ } catch (cause) {
6343
+ const msg = cause instanceof Error ? cause.message : String(cause);
6344
+ diag(`[theokit-sdk] tool lifecycle hook threw: ${msg}
6345
+ `);
6273
6346
  }
6274
- if (u.reasoningTokens !== void 0 && u.reasoningTokens > 0) {
6275
- const rate = entry.reasoningCostPerMillion ?? entry.outputCostPerMillion;
6276
- const c = costForTokens(u.reasoningTokens, rate);
6277
- detail.reasoning = c;
6278
- total += c;
6279
- if (entry.reasoningCostPerMillion === void 0) {
6280
- notes.push("reasoning tokens billed at output rate (no dedicated reasoning rate available)");
6281
- }
6347
+ }
6348
+ function buildToolUseRunning({ inputs, callId, call }) {
6349
+ return {
6350
+ type: "tool_call",
6351
+ agent_id: inputs.agentId,
6352
+ run_id: inputs.runId,
6353
+ call_id: callId,
6354
+ name: call.name,
6355
+ status: "running",
6356
+ args: call.input
6357
+ };
6358
+ }
6359
+ function buildRepairRegistry(tools) {
6360
+ const out = /* @__PURE__ */ new Map();
6361
+ for (const t of tools) {
6362
+ out.set(t.name, { name: t.name, inputSchema: t.inputSchema });
6282
6363
  }
6283
- const amountUsd = Math.round(total * MICROCENT) / MICROCENT;
6364
+ return out;
6365
+ }
6366
+ function buildToolUseCompleted({ inputs, callId, call }, result) {
6284
6367
  return {
6285
- amountUsd,
6286
- status: "estimated",
6287
- currency: "USD",
6288
- source: "litellm_snapshot",
6289
- pricingVersion: entry.pricingVersion,
6290
- ...notes.length > 0 ? { notes } : {},
6291
- detail
6368
+ type: "tool_call",
6369
+ agent_id: inputs.agentId,
6370
+ run_id: inputs.runId,
6371
+ call_id: callId,
6372
+ name: call.name,
6373
+ status: "completed",
6374
+ args: call.input,
6375
+ result: {
6376
+ stdout: result.stdout,
6377
+ stderr: result.stderr,
6378
+ exitCode: result.exitCode ?? 0
6379
+ }
6292
6380
  };
6293
6381
  }
6294
6382
 
6295
- // src/internal/agent-loop/usage-and-cost.ts
6296
- function accumulateUsage(usage, turn) {
6297
- const hasAnyToken = turn.inputTokens !== void 0 || turn.outputTokens !== void 0 || turn.cacheReadTokens !== void 0 || turn.cacheWriteTokens !== void 0 || turn.reasoningTokens !== void 0;
6298
- if (!hasAnyToken) return;
6299
- usage.add({
6300
- inputTokens: turn.inputTokens,
6301
- outputTokens: turn.outputTokens,
6302
- cacheReadTokens: turn.cacheReadTokens,
6303
- cacheWriteTokens: turn.cacheWriteTokens,
6304
- reasoningTokens: turn.reasoningTokens
6305
- });
6383
+ // src/internal/agent-loop/tool-result-guard.ts
6384
+ var OPEN = "<untrusted-tool-output>";
6385
+ var CLOSE = "</untrusted-tool-output>";
6386
+ var PII_PATTERNS = [
6387
+ /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/g,
6388
+ // email
6389
+ /\b(?:\+?\d{1,3}[-.\s]?)?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}\b/g
6390
+ // phone
6391
+ ];
6392
+ function guardText(content, opts) {
6393
+ let out = content;
6394
+ if (opts.redactPii === true) {
6395
+ for (const re of PII_PATTERNS) out = out.replace(re, "[REDACTED]");
6396
+ }
6397
+ if (opts.delimit === true) {
6398
+ const safe2 = out.split(CLOSE).join("</ untrusted-tool-output>");
6399
+ out = `${OPEN}
6400
+ ${safe2}
6401
+ ${CLOSE}`;
6402
+ }
6403
+ return out;
6306
6404
  }
6307
- function computeUsageCost(inputs, usage) {
6308
- const modelId = inputs.model.id;
6309
- if (modelId === void 0 || modelId === "auto") return void 0;
6310
- const parsed = parseModelId(modelId);
6311
- const provider = parsed.provider ?? inputs.llm.name;
6312
- const model = parsed.provider !== void 0 ? parsed.name : modelId;
6313
- return computeCost({ provider, model, usage });
6405
+ function applyToolResultGuard(parts, opts) {
6406
+ if (opts.delimit !== true && opts.redactPii !== true) return parts;
6407
+ return parts.map(
6408
+ (p) => (
6409
+ // SE7 guard the TEXT of a tool result (string or the text blocks of a
6410
+ // structured content); image blocks pass through untouched.
6411
+ p.type === "tool_result" ? { ...p, content: renderToolResultContentText(p.content, (t) => guardText(t, opts)) } : p
6412
+ )
6413
+ );
6314
6414
  }
6315
6415
 
6316
6416
  // src/internal/agent-loop/loop.ts
@@ -6374,49 +6474,7 @@ async function runAgentLoop(inputs) {
6374
6474
  break;
6375
6475
  }
6376
6476
  }
6377
- if (lastTurnDecision === "continue" && budget.shouldContinue() === false) {
6378
- ctx.stoppedAtIterationLimit = true;
6379
- }
6380
- if (budget.shouldContinue() === false && ctx.finalStatus === "finished" && ctx.finalText === "") {
6381
- ctx.finalStatus = "error";
6382
- if (ctx.error === void 0) {
6383
- ctx.error = {
6384
- 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.`,
6385
- code: "iteration_limit_reached"
6386
- };
6387
- }
6388
- }
6389
- sendSpan?.setAttribute("status", ctx.finalStatus);
6390
- if (ctx.stoppedByDoomLoop === true) sendSpan?.setAttribute("stoppedByDoomLoop", true);
6391
- if (inputs.telemetry?.includeContent === true && ctx.finalText.length > 0) {
6392
- sendSpan?.addEvent("response", { content: ctx.finalText });
6393
- }
6394
- const usage = ctx.usage.hasAny() ? ctx.usage.toTokenUsage() : void 0;
6395
- const cost = usage !== void 0 ? computeUsageCost(inputs, usage) : void 0;
6396
- if (usage !== void 0) {
6397
- sendSpan?.setAttributes({
6398
- totalInputTokens: usage.inputTokens,
6399
- totalOutputTokens: usage.outputTokens,
6400
- ...cost?.amountUsd !== void 0 ? { totalCostUsd: cost.amountUsd } : {}
6401
- });
6402
- }
6403
- if (ctx.finalStatus === "finished" && ctx.memoryProviderHandle !== void 0 && inputs.memoryProvider?.sync !== void 0) {
6404
- try {
6405
- await inputs.memoryProvider.sync(ctx.memoryProviderHandle);
6406
- } catch {
6407
- }
6408
- }
6409
- return {
6410
- events: ctx.events,
6411
- finalStatus: ctx.finalStatus,
6412
- result: ctx.finalText,
6413
- conversation: ctx.conversation,
6414
- ...usage !== void 0 ? { usage } : {},
6415
- ...cost !== void 0 ? { cost } : {},
6416
- ...ctx.error !== void 0 ? { error: ctx.error } : {},
6417
- ...ctx.stoppedAtIterationLimit === true ? { stoppedAtIterationLimit: true } : {},
6418
- ...ctx.stoppedByDoomLoop === true ? { stoppedByDoomLoop: true } : {}
6419
- };
6477
+ return await finalizeLoopOutput(inputs, ctx, budget, sendSpan, lastTurnDecision);
6420
6478
  } finally {
6421
6479
  await inputs.pluginManager?.runOnSessionEndHooks({
6422
6480
  agentId: inputs.agentId,
@@ -6425,7 +6483,10 @@ async function runAgentLoop(inputs) {
6425
6483
  if (ctxRef !== void 0 && ctxRef.memoryProviderHandle !== void 0 && inputs.memoryProvider !== void 0) {
6426
6484
  try {
6427
6485
  await inputs.memoryProvider.dispose(ctxRef.memoryProviderHandle);
6428
- } catch {
6486
+ } catch (cause) {
6487
+ sendSpan?.addEvent("memory.dispose.failed", {
6488
+ message: cause instanceof Error ? cause.message : String(cause)
6489
+ });
6429
6490
  }
6430
6491
  }
6431
6492
  sendSpan?.end();
@@ -6653,15 +6714,20 @@ var FallbackLlmClient = class {
6653
6714
  });
6654
6715
  }
6655
6716
  };
6656
- function abortError(signal) {
6657
- if (signal.reason instanceof Error) return signal.reason;
6658
- return new Error(signal.reason !== void 0 ? String(signal.reason) : "aborted");
6717
+
6718
+ // src/internal/mcp/handshake-timeout.ts
6719
+ var DEFAULT_MCP_TIMEOUT_MS = 3e4;
6720
+ var HANDSHAKE_FLOOR_MS = 1e4;
6721
+ function handshakeAwareTimeout(input) {
6722
+ const isReconnectHandshake = input.method === "initialize" && input.reconnecting;
6723
+ return isReconnectHandshake ? Math.max(input.requestTimeoutMs, HANDSHAKE_FLOOR_MS) : input.requestTimeoutMs;
6659
6724
  }
6725
+
6726
+ // src/internal/mcp/client.ts
6660
6727
  function createMcpClient(name, config, fetchImpl = fetch) {
6661
6728
  if (isStdio(config)) return new StdioMcpClient(name, config);
6662
6729
  return new HttpMcpClient(name, config, fetchImpl);
6663
6730
  }
6664
- var DEFAULT_MCP_TIMEOUT_MS = 3e4;
6665
6731
  var MAX_STDIO_BUFFER_BYTES = 8 * 1024 * 1024;
6666
6732
  var RECONNECT_BASE_MS = 250;
6667
6733
  var MAX_RECONNECT_ATTEMPTS = 2;
@@ -6735,9 +6801,24 @@ var StdioMcpClient = class extends BaseMcpClient {
6735
6801
  // instead of racing (or spuriously failing with mcp_not_init).
6736
6802
  dropped = false;
6737
6803
  reconnectPromise;
6804
+ /** True only while `reconnect()`'s handshake is in flight — see `timeoutFor`. */
6805
+ reconnecting = false;
6738
6806
  get timeoutMs() {
6739
6807
  return this.config.requestTimeoutMs ?? DEFAULT_MCP_TIMEOUT_MS;
6740
6808
  }
6809
+ /**
6810
+ * The deadline for one RPC. The rule itself — and the reasoning behind it — lives in
6811
+ * `handshake-timeout.ts`, where it is a pure function of three values and can be interrogated
6812
+ * without spawning a process. It was private here, which is why the clause "a caller who sets a
6813
+ * LARGER timeout keeps it" went four months with no test.
6814
+ */
6815
+ timeoutFor(method) {
6816
+ return handshakeAwareTimeout({
6817
+ method,
6818
+ reconnecting: this.reconnecting,
6819
+ requestTimeoutMs: this.timeoutMs
6820
+ });
6821
+ }
6741
6822
  /** Spawn the server child and wire stdout/stderr/error/exit handlers.
6742
6823
  * Shared by `initialize()` and the M2 #59 reconnect path. */
6743
6824
  spawnChild() {
@@ -6803,12 +6884,15 @@ var StdioMcpClient = class extends BaseMcpClient {
6803
6884
  for (let attempt = 0; attempt < MAX_RECONNECT_ATTEMPTS; attempt += 1) {
6804
6885
  await reconnectDelay(attempt);
6805
6886
  this.spawnChild();
6887
+ this.reconnecting = true;
6806
6888
  try {
6807
6889
  await super.initialize();
6808
6890
  this.dropped = false;
6809
6891
  return;
6810
6892
  } catch (err) {
6811
6893
  lastErr = err;
6894
+ } finally {
6895
+ this.reconnecting = false;
6812
6896
  }
6813
6897
  }
6814
6898
  throw new NetworkError(`MCP ${this.name} reconnect exhausted`, {
@@ -6890,16 +6974,17 @@ var StdioMcpClient = class extends BaseMcpClient {
6890
6974
  child.stdin.write(`${JSON.stringify(payload)}
6891
6975
  `);
6892
6976
  return new Promise((resolve, reject) => {
6977
+ const budget = this.timeoutFor(method);
6893
6978
  const timer = setTimeout(() => {
6894
6979
  this.pending.delete(id);
6895
- reject(mcpTimeoutError(this.name, this.timeoutMs));
6980
+ reject(mcpTimeoutError(this.name, budget));
6896
6981
  this.child?.kill("SIGKILL");
6897
6982
  this.child = void 0;
6898
6983
  this.dropped = true;
6899
6984
  this.rejectAllPending(
6900
6985
  new NetworkError(`MCP ${this.name} disconnected`, { code: "mcp_disconnected" })
6901
6986
  );
6902
- }, this.timeoutMs);
6987
+ }, budget);
6903
6988
  this.pending.set(id, { resolve, reject, timer });
6904
6989
  });
6905
6990
  }
@@ -7022,16 +7107,6 @@ function resolveMcpCwd(configCwd) {
7022
7107
  return safePathJoin(process.cwd(), configCwd);
7023
7108
  }
7024
7109
 
7025
- // src/internal/providers/register-plugin-providers.ts
7026
- function registerPluginProviderProfiles(entries) {
7027
- let registered2 = 0;
7028
- for (const entry of entries) {
7029
- registerProvider(entry.profile);
7030
- registered2 += 1;
7031
- }
7032
- return registered2;
7033
- }
7034
-
7035
7110
  // src/internal/local-agent/mcp-pool.ts
7036
7111
  var DEFAULT_IDLE_TTL_MS = 6e5;
7037
7112
  function configKey(config) {
@@ -7095,6 +7170,31 @@ var McpClientPool = class {
7095
7170
  }
7096
7171
  };
7097
7172
 
7173
+ // src/internal/local-agent/real-local-run-mcp.ts
7174
+ var sessionMcpPool = new McpClientPool();
7175
+ function disposeSessionMcpClients(agentId) {
7176
+ sessionMcpPool.disposeSession(agentId, (client) => {
7177
+ void client.close();
7178
+ });
7179
+ }
7180
+ function runOwnsMcpClients(agentOptions) {
7181
+ return agentOptions.mcpLifecycle !== "session";
7182
+ }
7183
+ function buildMcpMap(options) {
7184
+ const map = /* @__PURE__ */ new Map();
7185
+ const inline = options.sendOptions.mcpServers ?? options.agentOptions.mcpServers;
7186
+ if (inline === void 0) return map;
7187
+ const pooled = !runOwnsMcpClients(options.agentOptions);
7188
+ if (pooled) sessionMcpPool.reapIdle((c) => void c.close());
7189
+ for (const [name, config] of Object.entries(inline)) {
7190
+ map.set(
7191
+ name,
7192
+ pooled ? sessionMcpPool.acquire(options.agentId, name, config, () => createMcpClient(name, config)) : createMcpClient(name, config)
7193
+ );
7194
+ }
7195
+ return map;
7196
+ }
7197
+
7098
7198
  // src/internal/tool-registry/personality-filter.ts
7099
7199
  function applyPersonalityFilter(exposedTools, whitelist, opts) {
7100
7200
  if (whitelist === void 0) return exposedTools;
@@ -7165,7 +7265,16 @@ function withheldBuiltinsInput(agentOptions) {
7165
7265
  if (withheld === void 0 || withheld.length === 0) return {};
7166
7266
  return { withheldBuiltinTools: withheld };
7167
7267
  }
7168
- function buildRunToolCatalogInput(agentOptions, sendOptions, pluginManager, personalityToolWhitelist, agentId, personalityName, subagents, effectiveModel) {
7268
+ function buildRunToolCatalogInput({
7269
+ agentOptions,
7270
+ sendOptions,
7271
+ pluginManager,
7272
+ personalityToolWhitelist,
7273
+ agentId,
7274
+ personalityName,
7275
+ subagents,
7276
+ effectiveModel
7277
+ }) {
7169
7278
  const builtins = withheldBuiltinsInput(agentOptions);
7170
7279
  const baseTools = sendOptions?.tools ?? agentOptions.tools ?? [];
7171
7280
  const agentsForTools = subagents !== void 0 && Object.keys(subagents).length > 0 ? subagents : agentOptions.agents;
@@ -7219,32 +7328,6 @@ function createRealLocalRun(options) {
7219
7328
  registerRun(handle);
7220
7329
  return handle;
7221
7330
  }
7222
- var pluginProvidersAnnounced = false;
7223
- function resolveRunProvider(options) {
7224
- registerBuiltins();
7225
- const profiles = options.pluginManager?.aggregated.providerProfiles ?? [];
7226
- const registered2 = registerPluginProviderProfiles(profiles);
7227
- if (registered2 > 0 && !pluginProvidersAnnounced) {
7228
- pluginProvidersAnnounced = true;
7229
- const names = profiles.map((e) => e.profile.name).join(", ");
7230
- diag(`[theokit-sdk] registered ${registered2} plugin provider profile(s): ${names}
7231
- `);
7232
- }
7233
- const parsedModel = parseModelId(options.model?.id);
7234
- const modelInferredProvider = parsedModel.provider !== void 0 && getProviderProfile$1(parsedModel.provider) !== void 0 ? parsedModel.provider : void 0;
7235
- const keyInferredProvider = inferProviderFromApiKey(options.agentOptions.apiKey);
7236
- const primary = options.agentOptions.providers?.routes?.[0]?.provider ?? keyInferredProvider ?? modelInferredProvider ?? detectPrimaryProvider();
7237
- warnProviderPrecedenceOnce(modelInferredProvider, primary);
7238
- const effectiveModelId = modelInferredProvider !== void 0 && modelInferredProvider === primary ? parsedModel.name : options.model?.id ?? "claude-sonnet-4-6";
7239
- return { primary, effectiveModelId };
7240
- }
7241
- function mergeExplicitApiKey(pools, primary, apiKey) {
7242
- if (apiKey === void 0 || apiKey.length === 0) return pools;
7243
- if (isFixtureApiKey(apiKey) || apiKey === LOCAL_RUNTIME_MOCK_KEY) return pools;
7244
- const existing = pools?.[primary];
7245
- if (existing !== void 0 && existing.length > 0) return pools;
7246
- return { ...pools ?? {}, [primary]: [apiKey] };
7247
- }
7248
7331
  function buildLoopInputs(options, runId, userText, userImages) {
7249
7332
  const maxIterations = options.sendOptions.maxIterations;
7250
7333
  if (maxIterations !== void 0 && (!Number.isInteger(maxIterations) || maxIterations < 1)) {
@@ -7303,16 +7386,16 @@ function buildLoopInputs(options, runId, userText, userImages) {
7303
7386
  } : {},
7304
7387
  ...options.priorMessages !== void 0 ? { priorMessages: options.priorMessages } : {},
7305
7388
  ...options.memoryTools !== void 0 && options.memoryTools.length > 0 ? { memoryTools: options.memoryTools } : {},
7306
- ...buildRunToolCatalogInput(
7307
- options.agentOptions,
7308
- options.sendOptions,
7309
- options.pluginManager,
7310
- options.personalityToolWhitelist,
7311
- options.agentId,
7312
- options.personalityName,
7313
- options.subagents,
7314
- options.model
7315
- ),
7389
+ ...buildRunToolCatalogInput({
7390
+ agentOptions: options.agentOptions,
7391
+ sendOptions: options.sendOptions,
7392
+ pluginManager: options.pluginManager,
7393
+ personalityToolWhitelist: options.personalityToolWhitelist,
7394
+ agentId: options.agentId,
7395
+ personalityName: options.personalityName,
7396
+ subagents: options.subagents,
7397
+ effectiveModel: options.model
7398
+ }),
7316
7399
  ...options.pluginManager !== void 0 ? { pluginManager: options.pluginManager } : {},
7317
7400
  // D318 — forward SendOptions.signal to the agent loop so streamLlmTurn
7318
7401
  // can attach it to the LLM `fetch({ signal })` call.
@@ -7349,29 +7432,6 @@ function buildLoopInputs(options, runId, userText, userImages) {
7349
7432
  ...options.agentOptions.memoryProvider !== void 0 ? { memoryProvider: options.agentOptions.memoryProvider } : {}
7350
7433
  };
7351
7434
  }
7352
- var sessionMcpPool = new McpClientPool();
7353
- function disposeSessionMcpClients(agentId) {
7354
- sessionMcpPool.disposeSession(agentId, (client) => {
7355
- void client.close();
7356
- });
7357
- }
7358
- function runOwnsMcpClients(agentOptions) {
7359
- return agentOptions.mcpLifecycle !== "session";
7360
- }
7361
- function buildMcpMap(options) {
7362
- const map = /* @__PURE__ */ new Map();
7363
- const inline = options.sendOptions.mcpServers ?? options.agentOptions.mcpServers;
7364
- if (inline === void 0) return map;
7365
- const pooled = !runOwnsMcpClients(options.agentOptions);
7366
- if (pooled) sessionMcpPool.reapIdle((c) => void c.close());
7367
- for (const [name, config] of Object.entries(inline)) {
7368
- map.set(
7369
- name,
7370
- pooled ? sessionMcpPool.acquire(options.agentId, name, config, () => createMcpClient(name, config)) : createMcpClient(name, config)
7371
- );
7372
- }
7373
- return map;
7374
- }
7375
7435
  var RealLocalRun = class extends FixtureRunBase {
7376
7436
  buildInputs;
7377
7437
  /** theokit#155 — whether this turn releases its MCP clients, or the session pool does. */
@@ -7589,7 +7649,7 @@ async function dispatchLocalRun(args) {
7589
7649
  });
7590
7650
  }
7591
7651
  async function readProjectMcpServers(cwd) {
7592
- const path = join(cwd, ".theokit", "mcp.json");
7652
+ const path = join(theokitConfigRoot(cwd), "mcp.json");
7593
7653
  try {
7594
7654
  const raw = await readFile(path, "utf8");
7595
7655
  const parsed = JSON.parse(raw);
@@ -7793,14 +7853,16 @@ var LiveAgentRegistry = class {
7793
7853
  }
7794
7854
  }
7795
7855
  };
7796
- var liveAgentRegistry = new LiveAgentRegistry();
7856
+ var liveAgentRegistry = globalSingleton(
7857
+ "theokit-sdk.runtime.live-agents",
7858
+ () => new LiveAgentRegistry()
7859
+ );
7797
7860
 
7798
7861
  // src/internal/local-agent/local-agent-lifecycle.ts
7799
7862
  async function acquireLeaseIfPossible(store, agentId) {
7800
- const a = store.acquire;
7801
- if (typeof a !== "function") return;
7863
+ if (typeof store.acquire !== "function") return;
7802
7864
  try {
7803
- await a.call(store, agentId);
7865
+ await store.acquire(agentId);
7804
7866
  } catch (err) {
7805
7867
  if (err instanceof Error && err.name === "SessionBusyError") throw err;
7806
7868
  diag(
@@ -7810,12 +7872,10 @@ async function acquireLeaseIfPossible(store, agentId) {
7810
7872
  }
7811
7873
  }
7812
7874
  async function releaseLeaseIfPossible(store, agentId) {
7813
- const r = store.release;
7814
- if (typeof r === "function") await r.call(store, agentId);
7875
+ if (typeof store.release === "function") await store.release(agentId);
7815
7876
  }
7816
7877
  async function disposeSessionStore(store) {
7817
- const d = store.dispose;
7818
- if (typeof d === "function") await d.call(store);
7878
+ if (typeof store.dispose === "function") await store.dispose();
7819
7879
  }
7820
7880
  async function disposeLocalAgentSession(agent) {
7821
7881
  liveAgentRegistry.forget(agent.agentId);
@@ -7838,6 +7898,111 @@ async function reloadLocalAgent(agent) {
7838
7898
  );
7839
7899
  }
7840
7900
 
7901
+ // src/internal/local-agent/local-agent-memory-direct.ts
7902
+ async function createAvailableAdapters(entries, workspaceCwd) {
7903
+ const available = [];
7904
+ for (const entry of entries) {
7905
+ const instance = await entry.createProvider(workspaceCwd);
7906
+ if (instance.isAvailable() === false) {
7907
+ diag(
7908
+ `[theokit-sdk] memory adapter "${instance.id}" reports itself unavailable (plugin "${entry.pluginName}") \u2014 skipping it. Check its credentials.
7909
+ `
7910
+ );
7911
+ continue;
7912
+ }
7913
+ available.push(instance);
7914
+ }
7915
+ return available;
7916
+ }
7917
+ function buildAgentMemory(pluginManager, workspaceCwd, defaultContext) {
7918
+ let resolved;
7919
+ async function ensure() {
7920
+ if (resolved !== void 0) return resolved;
7921
+ const entries = pluginManager.aggregated.memoryProviders;
7922
+ const created = await createAvailableAdapters(entries, workspaceCwd);
7923
+ for (const adapter of created) {
7924
+ if (adapter.initialize !== void 0) {
7925
+ await adapter.initialize();
7926
+ }
7927
+ }
7928
+ resolved = { adapters: created, initialized: true, registered: entries.length };
7929
+ return resolved;
7930
+ }
7931
+ function mergeContext(partial) {
7932
+ const merged = {
7933
+ userId: partial?.userId ?? defaultContext?.userId ?? "",
7934
+ ...partial?.agentId !== void 0 ? { agentId: partial.agentId } : defaultContext?.agentId !== void 0 ? { agentId: defaultContext.agentId } : {},
7935
+ ...partial?.sessionId !== void 0 ? { sessionId: partial.sessionId } : defaultContext?.sessionId !== void 0 ? { sessionId: defaultContext.sessionId } : {},
7936
+ ...partial?.tenantId !== void 0 ? { tenantId: partial.tenantId } : defaultContext?.tenantId !== void 0 ? { tenantId: defaultContext.tenantId } : {},
7937
+ ...partial?.tags !== void 0 ? { tags: partial.tags } : defaultContext?.tags !== void 0 ? { tags: defaultContext.tags } : {},
7938
+ ...partial?.metadata !== void 0 ? { metadata: partial.metadata } : defaultContext?.metadata !== void 0 ? { metadata: defaultContext.metadata } : {}
7939
+ };
7940
+ if (merged.userId === "") {
7941
+ throw new ConfigurationError(
7942
+ "agent.memory requires a userId \u2014 either set AgentOptions.memoryContext.userId or pass ctx.userId at call time.",
7943
+ { code: "memory_context_missing_user_id" }
7944
+ );
7945
+ }
7946
+ return merged;
7947
+ }
7948
+ async function requireAdapters() {
7949
+ const r = await ensure();
7950
+ if (r.adapters.length === 0) {
7951
+ throw new ConfigurationError(
7952
+ 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.`,
7953
+ { code: "no_memory_adapter" }
7954
+ );
7955
+ }
7956
+ return r.adapters;
7957
+ }
7958
+ return {
7959
+ async write(content, ctx) {
7960
+ const adapters = await requireAdapters();
7961
+ const merged = mergeContext(ctx);
7962
+ const writes = await Promise.allSettled(adapters.map((a) => a.write(content, merged)));
7963
+ const firstFulfilled = writes.find((r) => r.status === "fulfilled");
7964
+ if (firstFulfilled === void 0) {
7965
+ const firstReason = writes[0];
7966
+ throw firstReason.reason;
7967
+ }
7968
+ return firstFulfilled.value;
7969
+ },
7970
+ // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: settled-promise iteration + content dedupe + graceful degrade are 3 inline concerns; helpers would obscure the merge invariant.
7971
+ async recall(query, ctx, k) {
7972
+ const adapters = await requireAdapters();
7973
+ const merged = mergeContext(ctx);
7974
+ const recalls = await Promise.allSettled(adapters.map((a) => a.recall(query, merged, k)));
7975
+ const out = [];
7976
+ const seen = /* @__PURE__ */ new Set();
7977
+ for (const r of recalls) {
7978
+ if (r.status !== "fulfilled") continue;
7979
+ for (const fact of r.value) {
7980
+ if (seen.has(fact.content)) continue;
7981
+ seen.add(fact.content);
7982
+ out.push(fact);
7983
+ }
7984
+ }
7985
+ return out;
7986
+ },
7987
+ async delete(id) {
7988
+ const adapters = await requireAdapters();
7989
+ const prefix = id.split(":", 1)[0] ?? "";
7990
+ const target = adapters.find((a) => a.id === prefix);
7991
+ if (target === void 0) {
7992
+ throw new ConfigurationError(
7993
+ `No adapter found for MemoryId prefix "${prefix}" (registered: ${adapters.map((a) => a.id).join(", ")}).`,
7994
+ { code: "no_memory_adapter" }
7995
+ );
7996
+ }
7997
+ await target.delete(id);
7998
+ },
7999
+ adapter() {
8000
+ if (resolved === void 0) return null;
8001
+ return resolved.adapters[0] ?? null;
8002
+ }
8003
+ };
8004
+ }
8005
+
7841
8006
  // src/internal/memory/active-memory.ts
7842
8007
  var DEFAULTS = {
7843
8008
  queryMode: "recent",
@@ -8061,13 +8226,36 @@ function cacheKey(userText, queryMode, ctx) {
8061
8226
  return createHash("sha256").update(parts.join("\0")).digest("hex");
8062
8227
  }
8063
8228
 
8064
- // src/internal/memory/adapters/azure-openai-embedding.ts
8065
- var DEFAULT_AZURE_OPENAI_EMBEDDING_MODEL = "text-embedding-3-small";
8066
- var DIMENSION_BY_MODEL = {
8229
+ // src/internal/memory/adapters/openai-embedding.ts
8230
+ var DEFAULT_OPENAI_EMBEDDING_MODEL = "text-embedding-3-small";
8231
+ var OPENAI_EMBEDDING_DIMENSIONS = {
8067
8232
  "text-embedding-3-small": 1536,
8068
8233
  "text-embedding-3-large": 3072,
8069
8234
  "text-embedding-ada-002": 1536
8070
8235
  };
8236
+ var DIMENSION_BY_MODEL = { ...OPENAI_EMBEDDING_DIMENSIONS };
8237
+ var openAiMemoryEmbeddingProviderAdapter = {
8238
+ id: "openai",
8239
+ defaultModel: DEFAULT_OPENAI_EMBEDDING_MODEL,
8240
+ transport: "remote",
8241
+ authProviderId: "openai",
8242
+ autoSelectPriority: 20,
8243
+ create: (options) => createOpenAiCompatibleRuntime(
8244
+ {
8245
+ id: "openai",
8246
+ defaultBaseUrl: "https://api.openai.com",
8247
+ apiKeyEnv: "OPENAI_API_KEY",
8248
+ baseUrlEnv: "OPENAI_API_BASE_URL",
8249
+ defaultModel: DEFAULT_OPENAI_EMBEDDING_MODEL,
8250
+ dimensionByModel: DIMENSION_BY_MODEL
8251
+ },
8252
+ options
8253
+ )
8254
+ };
8255
+
8256
+ // src/internal/memory/adapters/azure-openai-embedding.ts
8257
+ var DEFAULT_AZURE_OPENAI_EMBEDDING_MODEL = "text-embedding-3-small";
8258
+ var DIMENSION_BY_MODEL2 = { ...OPENAI_EMBEDDING_DIMENSIONS };
8071
8259
  var azureOpenAiMemoryEmbeddingProviderAdapter = {
8072
8260
  id: "azure-openai",
8073
8261
  defaultModel: DEFAULT_AZURE_OPENAI_EMBEDDING_MODEL,
@@ -8082,7 +8270,7 @@ var azureOpenAiMemoryEmbeddingProviderAdapter = {
8082
8270
  baseUrlEnv: "AZURE_OPENAI_ENDPOINT",
8083
8271
  defaultModel: DEFAULT_AZURE_OPENAI_EMBEDDING_MODEL,
8084
8272
  embeddingsPath: "/openai/deployments/{model}/embeddings?api-version=2024-02-01",
8085
- dimensionByModel: DIMENSION_BY_MODEL,
8273
+ dimensionByModel: DIMENSION_BY_MODEL2,
8086
8274
  // theokit#159 — Azure is NOT OpenAI on the wire, despite the name. It authenticates an API
8087
8275
  // key with the `api-key` header (`Authorization: Bearer` is for Entra ID tokens, not for
8088
8276
  // AZURE_OPENAI_API_KEY), and the deployment already rides in the path, so `model` has no
@@ -8098,7 +8286,7 @@ var azureOpenAiMemoryEmbeddingProviderAdapter = {
8098
8286
 
8099
8287
  // src/internal/memory/adapters/cohere-embedding.ts
8100
8288
  var DEFAULT_COHERE_EMBEDDING_MODEL = "embed-english-v3.0";
8101
- var DIMENSION_BY_MODEL2 = {
8289
+ var DIMENSION_BY_MODEL3 = {
8102
8290
  "embed-english-v3.0": 1024,
8103
8291
  "embed-multilingual-v3.0": 1024,
8104
8292
  "embed-english-light-v3.0": 384,
@@ -8117,7 +8305,7 @@ var cohereMemoryEmbeddingProviderAdapter = {
8117
8305
  apiKeyEnv: "COHERE_API_KEY",
8118
8306
  defaultModel: DEFAULT_COHERE_EMBEDDING_MODEL,
8119
8307
  embeddingsPath: "/v2/embed",
8120
- dimensionByModel: DIMENSION_BY_MODEL2,
8308
+ dimensionByModel: DIMENSION_BY_MODEL3,
8121
8309
  // theokit#159 — `/v2/embed` diverges in BOTH directions: it names the payload `texts`, requires
8122
8310
  // `input_type`, and answers `{embeddings:{float:[[...]]}}` rather than `{data:[{embedding}]}`.
8123
8311
  // `search_document` is the right default here because this runtime embeds material for
@@ -8138,7 +8326,7 @@ var cohereMemoryEmbeddingProviderAdapter = {
8138
8326
 
8139
8327
  // src/internal/memory/adapters/deepinfra-embedding.ts
8140
8328
  var DEFAULT_DEEPINFRA_EMBEDDING_MODEL = "BAAI/bge-large-en-v1.5";
8141
- var DIMENSION_BY_MODEL3 = {
8329
+ var DIMENSION_BY_MODEL4 = {
8142
8330
  "BAAI/bge-large-en-v1.5": 1024,
8143
8331
  "BAAI/bge-base-en-v1.5": 768,
8144
8332
  "BAAI/bge-small-en-v1.5": 384,
@@ -8163,7 +8351,7 @@ var deepinfraMemoryEmbeddingProviderAdapter = {
8163
8351
  apiKeyEnv: "DEEPINFRA_API_KEY",
8164
8352
  baseUrlEnv: "DEEPINFRA_API_BASE_URL",
8165
8353
  defaultModel: DEFAULT_DEEPINFRA_EMBEDDING_MODEL,
8166
- dimensionByModel: DIMENSION_BY_MODEL3,
8354
+ dimensionByModel: DIMENSION_BY_MODEL4,
8167
8355
  embeddingsPath: "/v1/openai/embeddings"
8168
8356
  },
8169
8357
  options
@@ -8172,7 +8360,7 @@ var deepinfraMemoryEmbeddingProviderAdapter = {
8172
8360
 
8173
8361
  // src/internal/memory/adapters/gemini-embedding.ts
8174
8362
  var DEFAULT_GEMINI_EMBEDDING_MODEL = "text-embedding-004";
8175
- var DIMENSION_BY_MODEL4 = {
8363
+ var DIMENSION_BY_MODEL5 = {
8176
8364
  "text-embedding-004": 768,
8177
8365
  "embedding-001": 768
8178
8366
  };
@@ -8191,7 +8379,7 @@ var geminiMemoryEmbeddingProviderAdapter = {
8191
8379
  // theokit#159 — the compat surface is under `/v1beta/openai/`, not the default
8192
8380
  // `/v1/embeddings`; the previous path 404'd on every call.
8193
8381
  embeddingsPath: "/v1beta/openai/embeddings",
8194
- dimensionByModel: DIMENSION_BY_MODEL4
8382
+ dimensionByModel: DIMENSION_BY_MODEL5
8195
8383
  },
8196
8384
  options
8197
8385
  )
@@ -8199,7 +8387,7 @@ var geminiMemoryEmbeddingProviderAdapter = {
8199
8387
 
8200
8388
  // src/internal/memory/adapters/jina-embedding.ts
8201
8389
  var DEFAULT_JINA_EMBEDDING_MODEL = "jina-embeddings-v3";
8202
- var DIMENSION_BY_MODEL5 = {
8390
+ var DIMENSION_BY_MODEL6 = {
8203
8391
  "jina-embeddings-v3": 1024,
8204
8392
  "jina-embeddings-v2-base-en": 768,
8205
8393
  "jina-embeddings-v2-small-en": 512
@@ -8216,7 +8404,7 @@ var jinaMemoryEmbeddingProviderAdapter = {
8216
8404
  defaultBaseUrl: "https://api.jina.ai",
8217
8405
  apiKeyEnv: "JINA_API_KEY",
8218
8406
  defaultModel: DEFAULT_JINA_EMBEDDING_MODEL,
8219
- dimensionByModel: DIMENSION_BY_MODEL5
8407
+ dimensionByModel: DIMENSION_BY_MODEL6
8220
8408
  },
8221
8409
  options
8222
8410
  )
@@ -8224,7 +8412,7 @@ var jinaMemoryEmbeddingProviderAdapter = {
8224
8412
 
8225
8413
  // src/internal/memory/adapters/mistral-embedding.ts
8226
8414
  var DEFAULT_MISTRAL_EMBEDDING_MODEL = "mistral-embed";
8227
- var DIMENSION_BY_MODEL6 = {
8415
+ var DIMENSION_BY_MODEL7 = {
8228
8416
  "mistral-embed": 1024
8229
8417
  };
8230
8418
  var mistralMemoryEmbeddingProviderAdapter = {
@@ -8240,7 +8428,7 @@ var mistralMemoryEmbeddingProviderAdapter = {
8240
8428
  apiKeyEnv: "MISTRAL_API_KEY",
8241
8429
  baseUrlEnv: "MISTRAL_API_BASE_URL",
8242
8430
  defaultModel: DEFAULT_MISTRAL_EMBEDDING_MODEL,
8243
- dimensionByModel: DIMENSION_BY_MODEL6
8431
+ dimensionByModel: DIMENSION_BY_MODEL7
8244
8432
  },
8245
8433
  options
8246
8434
  )
@@ -8249,7 +8437,7 @@ var mistralMemoryEmbeddingProviderAdapter = {
8249
8437
  // src/internal/memory/adapters/ollama-embedding.ts
8250
8438
  var DEFAULT_OLLAMA_EMBEDDING_MODEL = "nomic-embed-text";
8251
8439
  var OLLAMA_LOCAL_SENTINEL_KEY = "ollama-local";
8252
- var DIMENSION_BY_MODEL7 = {
8440
+ var DIMENSION_BY_MODEL8 = {
8253
8441
  // Nomic — local default, recommended quality/size balance.
8254
8442
  "nomic-embed-text": 768,
8255
8443
  "nomic-embed-text:latest": 768,
@@ -8282,39 +8470,13 @@ var ollamaMemoryEmbeddingProviderAdapter = {
8282
8470
  apiKeyEnv: "OLLAMA_API_KEY",
8283
8471
  baseUrlEnv: "OLLAMA_HOST",
8284
8472
  defaultModel: DEFAULT_OLLAMA_EMBEDDING_MODEL,
8285
- dimensionByModel: DIMENSION_BY_MODEL7
8473
+ dimensionByModel: DIMENSION_BY_MODEL8
8286
8474
  },
8287
8475
  { ...options, apiKey }
8288
8476
  );
8289
8477
  }
8290
8478
  };
8291
8479
 
8292
- // src/internal/memory/adapters/openai-embedding.ts
8293
- var DEFAULT_OPENAI_EMBEDDING_MODEL = "text-embedding-3-small";
8294
- var DIMENSION_BY_MODEL8 = {
8295
- "text-embedding-3-small": 1536,
8296
- "text-embedding-3-large": 3072,
8297
- "text-embedding-ada-002": 1536
8298
- };
8299
- var openAiMemoryEmbeddingProviderAdapter = {
8300
- id: "openai",
8301
- defaultModel: DEFAULT_OPENAI_EMBEDDING_MODEL,
8302
- transport: "remote",
8303
- authProviderId: "openai",
8304
- autoSelectPriority: 20,
8305
- create: (options) => createOpenAiCompatibleRuntime(
8306
- {
8307
- id: "openai",
8308
- defaultBaseUrl: "https://api.openai.com",
8309
- apiKeyEnv: "OPENAI_API_KEY",
8310
- baseUrlEnv: "OPENAI_API_BASE_URL",
8311
- defaultModel: DEFAULT_OPENAI_EMBEDDING_MODEL,
8312
- dimensionByModel: DIMENSION_BY_MODEL8
8313
- },
8314
- options
8315
- )
8316
- };
8317
-
8318
8480
  // src/internal/memory/adapters/openrouter-embedding.ts
8319
8481
  var DEFAULT_OPENROUTER_EMBEDDING_MODEL = "openai/text-embedding-3-small";
8320
8482
  var DIMENSION_BY_MODEL9 = {
@@ -8575,10 +8737,7 @@ var LocalAgentMemory = class {
8575
8737
  return this.toolsCache;
8576
8738
  } catch (cause) {
8577
8739
  const message = cause instanceof Error ? cause.message : String(cause);
8578
- const g = globalThis;
8579
- const sym = /* @__PURE__ */ Symbol.for("theokit-sdk.memory.warned");
8580
- g[sym] ??= /* @__PURE__ */ new Set();
8581
- const warned2 = g[sym];
8740
+ const warned2 = globalSingleton("theokit-sdk.memory.warned", () => /* @__PURE__ */ new Set());
8582
8741
  if (!warned2.has(message)) {
8583
8742
  warned2.add(message);
8584
8743
  diag(`[theokit-sdk] memory tools unavailable: ${message}
@@ -8669,111 +8828,6 @@ var LocalAgentMemory = class {
8669
8828
  }
8670
8829
  };
8671
8830
 
8672
- // src/internal/local-agent/local-agent-memory-direct.ts
8673
- async function createAvailableAdapters(entries, workspaceCwd) {
8674
- const available = [];
8675
- for (const entry of entries) {
8676
- const instance = await entry.createProvider(workspaceCwd);
8677
- if (instance.isAvailable() === false) {
8678
- diag(
8679
- `[theokit-sdk] memory adapter "${instance.id}" reports itself unavailable (plugin "${entry.pluginName}") \u2014 skipping it. Check its credentials.
8680
- `
8681
- );
8682
- continue;
8683
- }
8684
- available.push(instance);
8685
- }
8686
- return available;
8687
- }
8688
- function buildAgentMemory(pluginManager, workspaceCwd, defaultContext) {
8689
- let resolved;
8690
- async function ensure() {
8691
- if (resolved !== void 0) return resolved;
8692
- const entries = pluginManager.aggregated.memoryProviders;
8693
- const created = await createAvailableAdapters(entries, workspaceCwd);
8694
- for (const adapter of created) {
8695
- if (adapter.initialize !== void 0) {
8696
- await adapter.initialize();
8697
- }
8698
- }
8699
- resolved = { adapters: created, initialized: true, registered: entries.length };
8700
- return resolved;
8701
- }
8702
- function mergeContext(partial) {
8703
- const merged = {
8704
- userId: partial?.userId ?? defaultContext?.userId ?? "",
8705
- ...partial?.agentId !== void 0 ? { agentId: partial.agentId } : defaultContext?.agentId !== void 0 ? { agentId: defaultContext.agentId } : {},
8706
- ...partial?.sessionId !== void 0 ? { sessionId: partial.sessionId } : defaultContext?.sessionId !== void 0 ? { sessionId: defaultContext.sessionId } : {},
8707
- ...partial?.tenantId !== void 0 ? { tenantId: partial.tenantId } : defaultContext?.tenantId !== void 0 ? { tenantId: defaultContext.tenantId } : {},
8708
- ...partial?.tags !== void 0 ? { tags: partial.tags } : defaultContext?.tags !== void 0 ? { tags: defaultContext.tags } : {},
8709
- ...partial?.metadata !== void 0 ? { metadata: partial.metadata } : defaultContext?.metadata !== void 0 ? { metadata: defaultContext.metadata } : {}
8710
- };
8711
- if (merged.userId === "") {
8712
- throw new ConfigurationError(
8713
- "agent.memory requires a userId \u2014 either set AgentOptions.memoryContext.userId or pass ctx.userId at call time.",
8714
- { code: "memory_context_missing_user_id" }
8715
- );
8716
- }
8717
- return merged;
8718
- }
8719
- async function requireAdapters() {
8720
- const r = await ensure();
8721
- if (r.adapters.length === 0) {
8722
- throw new ConfigurationError(
8723
- 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.`,
8724
- { code: "no_memory_adapter" }
8725
- );
8726
- }
8727
- return r.adapters;
8728
- }
8729
- return {
8730
- async write(content, ctx) {
8731
- const adapters = await requireAdapters();
8732
- const merged = mergeContext(ctx);
8733
- const writes = await Promise.allSettled(adapters.map((a) => a.write(content, merged)));
8734
- const firstFulfilled = writes.find((r) => r.status === "fulfilled");
8735
- if (firstFulfilled === void 0) {
8736
- const firstReason = writes[0];
8737
- throw firstReason.reason;
8738
- }
8739
- return firstFulfilled.value;
8740
- },
8741
- // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: settled-promise iteration + content dedupe + graceful degrade are 3 inline concerns; helpers would obscure the merge invariant.
8742
- async recall(query, ctx, k) {
8743
- const adapters = await requireAdapters();
8744
- const merged = mergeContext(ctx);
8745
- const recalls = await Promise.allSettled(adapters.map((a) => a.recall(query, merged, k)));
8746
- const out = [];
8747
- const seen = /* @__PURE__ */ new Set();
8748
- for (const r of recalls) {
8749
- if (r.status !== "fulfilled") continue;
8750
- for (const fact of r.value) {
8751
- if (seen.has(fact.content)) continue;
8752
- seen.add(fact.content);
8753
- out.push(fact);
8754
- }
8755
- }
8756
- return out;
8757
- },
8758
- async delete(id) {
8759
- const adapters = await requireAdapters();
8760
- const prefix = id.split(":", 1)[0] ?? "";
8761
- const target = adapters.find((a) => a.id === prefix);
8762
- if (target === void 0) {
8763
- throw new ConfigurationError(
8764
- `No adapter found for MemoryId prefix "${prefix}" (registered: ${adapters.map((a) => a.id).join(", ")}).`,
8765
- { code: "no_memory_adapter" }
8766
- );
8767
- }
8768
- await target.delete(id);
8769
- },
8770
- adapter() {
8771
- if (resolved === void 0) return null;
8772
- return resolved.adapters[0] ?? null;
8773
- }
8774
- };
8775
- }
8776
-
8777
8831
  // src/internal/local-agent/local-agent-memory-provider.ts
8778
8832
  var INTERNAL_LAM_KEY = /* @__PURE__ */ Symbol("sdk-core.local-agent-memory-provider.glue");
8779
8833
  function createLocalAgentMemoryProvider(opts) {
@@ -8856,7 +8910,7 @@ var PersonalityFrontmatterSchema = z.object({
8856
8910
  var RESERVED_CLEAR_SLUGS = ["none", "default", "neutral"];
8857
8911
 
8858
8912
  // src/internal/personality/registry.ts
8859
- var PROJECT_SUBDIR = ".theokit/personalities";
8913
+ var PERSONALITIES_SUFFIX = "personalities";
8860
8914
  var USER_SUBDIR = ".theokit/personalities";
8861
8915
  var PersonalityRegistry = class _PersonalityRegistry {
8862
8916
  #byName;
@@ -8871,7 +8925,7 @@ var PersonalityRegistry = class _PersonalityRegistry {
8871
8925
  * @internal
8872
8926
  */
8873
8927
  static async load(cwd) {
8874
- const projectDir = join(cwd, PROJECT_SUBDIR);
8928
+ const projectDir = join(theokitConfigRoot(cwd), PERSONALITIES_SUFFIX);
8875
8929
  const userDir = join(homedir(), USER_SUBDIR);
8876
8930
  const [userEntities, projectEntities] = await Promise.all([
8877
8931
  loadMarkdownEntities({
@@ -8992,29 +9046,27 @@ function applyPersonalityOverlay(preset, base) {
8992
9046
 
8993
9047
  ${preset.systemPrompt}`;
8994
9048
  }
8995
- async function localAgentUsePersonality(args) {
8996
- if (args.disposed) throw new Error("Agent has been disposed");
9049
+ async function localAgentUsePersonality(agent, name, opts) {
8997
9050
  if (currentPersonalityContext() !== void 0) {
8998
- warnPersonalitySwitchInsideFork(args.agentId);
9051
+ warnPersonalitySwitchInsideFork(agent.agentId);
8999
9052
  return null;
9000
9053
  }
9001
- let registry = args.personalityRegistry;
9002
- if (registry === void 0) {
9003
- registry = await PersonalityRegistry.load(args.workspaceCwd);
9004
- args.onRegistryLoaded(registry);
9054
+ if (agent.personalityRegistry === void 0) {
9055
+ agent.personalityRegistry = await PersonalityRegistry.load(agent.workspaceCwd);
9005
9056
  }
9057
+ const registry = agent.personalityRegistry;
9006
9058
  return withCwdMutex(
9007
- `agent-send:${args.agentId}`,
9059
+ `agent-send:${agent.agentId}`,
9008
9060
  () => performPersonalitySwitch({
9009
- agentId: args.agentId,
9010
- prevSlug: args.personalityStore.active(args.agentId),
9011
- requestedName: args.name,
9061
+ agentId: agent.agentId,
9062
+ prevSlug: agent.personalityStore.active(agent.agentId),
9063
+ requestedName: name,
9012
9064
  registry,
9013
- store: args.personalityStore,
9014
- invalidateCache: (reason) => args.invalidateCache(reason),
9015
- appendSessionMessage: (msg) => appendSessionMessage(args.agentId, msg),
9016
- clearSession: () => clearSession(args.agentId),
9017
- opts: args.opts ?? {}
9065
+ store: agent.personalityStore,
9066
+ invalidateCache: (reason) => agent.invalidateCache(reason),
9067
+ appendSessionMessage: (msg) => appendSessionMessage(agent.agentId, msg),
9068
+ clearSession: () => clearSession(agent.agentId),
9069
+ opts: opts ?? {}
9018
9070
  })
9019
9071
  );
9020
9072
  }
@@ -9022,9 +9074,9 @@ async function localAgentUsePersonality(args) {
9022
9074
  // src/internal/local-agent/local-agent-runtime-extensions.ts
9023
9075
  function localAgentRunUntil(agent, goal, options) {
9024
9076
  async function* wrap() {
9025
- const { runUntilImpl } = await import('./run-until-HEQOUVU6.js');
9077
+ const { runUntilImpl } = await import('./run-until-6D6TQ4JN.js');
9026
9078
  const buildDeps = async () => {
9027
- const { judgeCallImpl } = await import('./judge-call-LVXABPS3.js');
9079
+ const { judgeCallImpl } = await import('./judge-call-6MVARKU2.js');
9028
9080
  const { getAgentFacade } = await import('./agent-factory-registry-ZVTABLEY.js');
9029
9081
  const create = getAgentFacade().create;
9030
9082
  return {
@@ -9055,9 +9107,9 @@ async function* localAgentStreamToCompletion(agent, message, options) {
9055
9107
  return yield* streamToCompletionImpl({ send: (m, o) => agent.send(m, o) }, message, options);
9056
9108
  }
9057
9109
  async function localAgentFork(parent, options) {
9058
- const { forkAgentImpl } = await import('./fork-agent-RSV4E3EA.js');
9110
+ const { forkAgentImpl } = await import('./fork-agent-S2EPIML7.js');
9059
9111
  const { getAgentFacade } = await import('./agent-factory-registry-ZVTABLEY.js');
9060
- const { withPersonalityContext } = await import('./context-WI2DFG7V.js');
9112
+ const { withPersonalityContext } = await import('./context-Y7B7SI5X.js');
9061
9113
  const create = getAgentFacade().create;
9062
9114
  return withPersonalityContext(
9063
9115
  { slug: parent.personalitySlugSnapshot, isFork: true },
@@ -9086,7 +9138,7 @@ async function persistMemoryFactIfWritePrompt(workspaceCwd, memoryConfig, userTe
9086
9138
  }
9087
9139
  }
9088
9140
 
9089
- // src/internal/runtime/concurrency/abort-utils.ts
9141
+ // src/internal/concurrency/abort-utils.ts
9090
9142
  function anySignal(signals) {
9091
9143
  const filtered = signals.filter((s) => s !== void 0);
9092
9144
  if (filtered.length === 0) {
@@ -9150,7 +9202,7 @@ function wrapRunWithCompletionCheck(args) {
9150
9202
  });
9151
9203
  }
9152
9204
 
9153
- // src/internal/runtime/memory/select-facts.ts
9205
+ // src/internal/runtime/memory-glue/select-facts.ts
9154
9206
  var DEFAULT_MAX_ENTRIES = 10;
9155
9207
  var CHARS_PER_TOKEN = 3.7;
9156
9208
  var DEFAULT_MAX_TOKENS = 15e3;
@@ -9552,7 +9604,12 @@ async function applyInputProcessors(inputs, message, rawUserText, options, sendM
9552
9604
  }
9553
9605
  async function executeSendLocked(inputs, message, options) {
9554
9606
  if (inputs.disposed) throw new AgentDisposedError(inputs.agentId);
9555
- await consumePending(inputs.agentId, inputs.invalidationPending, inputs.clearInvalidation, inputs.reload);
9607
+ await consumePending(
9608
+ inputs.agentId,
9609
+ inputs.invalidationPending,
9610
+ inputs.clearInvalidation,
9611
+ inputs.reload
9612
+ );
9556
9613
  const sendModel = normalizeModel(options.model);
9557
9614
  inputs.applyModelOverride(sendModel);
9558
9615
  const rawUserText = typeof message === "string" ? message : message.text;
@@ -9578,37 +9635,30 @@ async function executeSendLocked(inputs, message, options) {
9578
9635
  appendSessionMessage(inputs.agentId, { role: "user", text: userText });
9579
9636
  await persistMemoryFactIfWritePrompt(inputs.workspaceCwd, inputs.options.memory, userText);
9580
9637
  const memoryFacts = await readMemoryForSend(inputs.workspaceCwd, inputs.options.memory, userText);
9581
- const portPathActive = shouldUsePortMemoryPath();
9582
- const legacyTools = portPathActive ? void 0 : await inputs.memoryGlue.ensureTools();
9583
- const legacySummary = portPathActive ? void 0 : await inputs.memoryGlue.runActiveMemoryIfEnabled(userText, priorMessages, inputs.telemetry);
9584
- const memoryTools = resolveMemoryToolsForLoop(legacyTools, portPathActive);
9585
- const activeMemorySummary = resolveActiveMemorySummaryForSend(legacySummary, portPathActive);
9586
- const effectiveMemoryProvider = resolveMemoryProviderForLoop(
9587
- inputs.options.memoryProvider,
9588
- inputs.defaultMemoryProviderForLoop,
9589
- portPathActive
9590
- );
9638
+ const memoryTools = void 0;
9639
+ const activeMemorySummary = void 0;
9640
+ const effectiveMemoryProvider = inputs.options.memoryProvider ?? inputs.defaultMemoryProviderForLoop;
9591
9641
  const baseSystemPrompt = await inputs.resolveSystemPromptForSend(userText, options, memoryFacts);
9592
- const assembledSystemPrompt = await inputs.assembleSystemPromptForSend(
9642
+ const assembledSystemPrompt = await inputs.assembleSystemPromptForSend({
9593
9643
  userText,
9594
9644
  baseSystemPrompt,
9595
9645
  memoryFacts,
9596
9646
  activeMemorySummary,
9597
- options.contextPaths
9598
- );
9647
+ contextPaths: options.contextPaths
9648
+ });
9599
9649
  const composedOptions = {
9600
9650
  ...options,
9601
9651
  signal: anySignal([options.signal, inputs.lifecycleAbortController.signal])
9602
9652
  };
9603
- const run = await inputs.dispatchRun(
9604
- adaptedMessage,
9605
- composedOptions,
9606
- assembledSystemPrompt,
9653
+ const run = await inputs.dispatchRun({
9654
+ message: adaptedMessage,
9655
+ options: composedOptions,
9656
+ systemPrompt: assembledSystemPrompt,
9607
9657
  memoryFacts,
9608
9658
  priorMessages,
9609
9659
  memoryTools,
9610
- effectiveMemoryProvider
9611
- );
9660
+ memoryProviderOverride: effectiveMemoryProvider
9661
+ });
9612
9662
  const outputProcessors = inputs.options.outputProcessors;
9613
9663
  const processedRun = outputProcessors !== void 0 && outputProcessors.length > 0 ? wrapRunWithOutputProcessors({
9614
9664
  run,
@@ -9633,7 +9683,7 @@ async function executeSendLocked(inputs, message, options) {
9633
9683
  function buildCompletionCheckDeps() {
9634
9684
  return {
9635
9685
  judge: async (ctx, opts) => {
9636
- const { judgeCallImpl } = await import('./judge-call-LVXABPS3.js');
9686
+ const { judgeCallImpl } = await import('./judge-call-6MVARKU2.js');
9637
9687
  const { getAgentFacade } = await import('./agent-factory-registry-ZVTABLEY.js');
9638
9688
  return judgeCallImpl(ctx, opts, { create: getAgentFacade().create });
9639
9689
  }
@@ -9700,6 +9750,7 @@ function registerRunAsTask(run, agentId, taskOpt, userText) {
9700
9750
  var KNOWN_LOCAL_OPTION_KEYS = /* @__PURE__ */ new Set([
9701
9751
  "cwd",
9702
9752
  "settingSources",
9753
+ "compatSources",
9703
9754
  "sandboxOptions",
9704
9755
  "sessionDir",
9705
9756
  "baseDir",
@@ -9751,6 +9802,21 @@ function reportUnknownLocalOptions(local) {
9751
9802
 
9752
9803
  // src/internal/local-agent/local-agent.ts
9753
9804
  var LocalAgent = class {
9805
+ /**
9806
+ * Operations this runtime does not perform. See {@link SDKAgent.supports} for why asking beats
9807
+ * catching: the members below are present on the type — `downloadArtifact` is REQUIRED — and
9808
+ * answering them by throwing is what leaves a caller unable to branch without a try/catch.
9809
+ *
9810
+ * Artifacts are a cloud concept: `downloadArtifact` rejects unconditionally here, and
9811
+ * `listArtifacts` returns `[]` for every state, so its empty array cannot be read as "this run
9812
+ * produced none".
9813
+ */
9814
+ supports(operation) {
9815
+ return localAgentCapabilities.supports(operation);
9816
+ }
9817
+ unsupportedReason(operation) {
9818
+ return localAgentCapabilities.unsupportedReason(operation);
9819
+ }
9754
9820
  agentId;
9755
9821
  model;
9756
9822
  context;
@@ -9787,14 +9853,14 @@ var LocalAgent = class {
9787
9853
  pluginsManager;
9788
9854
  hooksExecutor;
9789
9855
  systemPromptPipeline = SystemPromptPipeline.default();
9790
- memoryGlue;
9791
9856
  /**
9792
- * SDK 2.0 Phase 1 physical Stage 2biter 19+: pre-built adapter
9793
- * wrapping `memoryGlue` as a MemoryProvider impl. Constructed eagerly
9794
- * so future iters can flip `inputs.memoryProvider` to default to
9795
- * THIS adapter when consumer didn't supply one. NOT YET used by
9796
- * `send()` the kernel flip lands in Stage 2b proper after equivalence
9797
- * regression coverage.
9857
+ * The agent's memory, behind the `MemoryProvider` portthe only memory path since the kernel
9858
+ * flip (2026-09-02). A consumer-supplied `options.memoryProvider` takes precedence; this is what
9859
+ * runs otherwise.
9860
+ *
9861
+ * It used to be built ALONGSIDE a `LocalAgentMemory` this class held directly, "so future iters
9862
+ * can flip", while `send()` used the direct one. The adapter constructs its own `LocalAgentMemory`
9863
+ * inside `init()`, so that arrangement kept two of them per agent and the second was never read.
9798
9864
  *
9799
9865
  * Accessible to tests via `_defaultMemoryProviderForLoop()` helper.
9800
9866
  * @internal
@@ -9803,6 +9869,10 @@ var LocalAgent = class {
9803
9869
  /** T4.1 — PluginManager for code plugins (kind: general/model-provider/memory). @internal */
9804
9870
  pluginManagerCode = new PluginManager();
9805
9871
  /** Personality presets — lazy-loaded on first `usePersonality` call (ADRs D160-D164). @internal */
9872
+ // Not private: `local-agent-personality-extensions.ts` reads both through
9873
+ // `LocalAgentPersonalityTarget`, the same way `local-agent-lifecycle.ts` reads `sessionStore` and
9874
+ // `lifecycleAbortController` above. A field a sibling module needs is part of this class's
9875
+ // implementation surface, and saying so beats handing it over as a closure.
9806
9876
  personalityRegistry;
9807
9877
  personalityStore;
9808
9878
  /** T0.1 — telemetry handle shared with sendLocked + memory recall path. */
@@ -9830,8 +9900,9 @@ var LocalAgent = class {
9830
9900
  this.pluginsManager = sub.pluginsManager;
9831
9901
  if (sub.plugins !== void 0) this.plugins = sub.plugins;
9832
9902
  reportUnknownLocalOptions(options.local);
9833
- this.hooksExecutor = new HooksExecutor(this.workspaceCwd);
9834
- this.memoryGlue = new LocalAgentMemory(options, this.workspaceCwd, this.agentId);
9903
+ const compatSources = resolveCompatSources(options, this.workspaceCwd);
9904
+ reportUndeclaredSources(this.workspaceCwd, compatSources);
9905
+ this.hooksExecutor = new HooksExecutor(this.workspaceCwd, compatSources);
9835
9906
  this.defaultMemoryProviderForLoop = createLocalAgentMemoryProvider({
9836
9907
  agentOptions: options,
9837
9908
  workspaceCwd: this.workspaceCwd,
@@ -9861,7 +9932,8 @@ var LocalAgent = class {
9861
9932
  this.resolvedSubagents = await loadSubagents(
9862
9933
  this.workspaceCwd,
9863
9934
  this.settingSourcesIncludeProject,
9864
- this.options.agents
9935
+ this.options.agents,
9936
+ resolveCompatSources(this.options, this.workspaceCwd)
9865
9937
  );
9866
9938
  await acquireLeaseIfPossible(this.sessionStore, this.agentId);
9867
9939
  try {
@@ -9927,11 +9999,6 @@ var LocalAgent = class {
9927
9999
  if (options.task !== void 0) registerRunAsTask(run, this.agentId, options.task, userText);
9928
10000
  resolve(run);
9929
10001
  try {
9930
- const postRunProvider = resolveMemoryProviderForLoop(
9931
- this.options.memoryProvider,
9932
- this.defaultMemoryProviderForLoop,
9933
- shouldUsePortMemoryPath()
9934
- );
9935
10002
  await runPostRunLifecycle({
9936
10003
  run,
9937
10004
  userText,
@@ -9944,10 +10011,13 @@ var LocalAgent = class {
9944
10011
  ...this.options.apiKey !== void 0 ? { apiKey: this.options.apiKey } : {},
9945
10012
  ...options.onRunEvent !== void 0 ? { onRunEvent: options.onRunEvent } : {},
9946
10013
  hooksExecutor: this.hooksExecutor,
9947
- memoryGlue: this.memoryGlue,
9948
10014
  // usetheokit/theokit-sdk#382 — the transcript write reads this and nothing else.
9949
10015
  memory: this.options.memory,
9950
- ...postRunProvider !== void 0 ? { memoryProvider: postRunProvider } : {}
10016
+ // A consumer-supplied provider wins; otherwise the auto-installed adapter over
10017
+ // `LocalAgentMemory`. Since the kernel flip there is no third case, so this is passed
10018
+ // unconditionally — the `!== undefined` spread that used to guard it could not be false,
10019
+ // and `recordSessionSummary` is now always reached through the port.
10020
+ memoryProvider: this.options.memoryProvider ?? this.defaultMemoryProviderForLoop
9951
10021
  });
9952
10022
  } finally {
9953
10023
  sendSpan.end();
@@ -9966,24 +10036,30 @@ var LocalAgent = class {
9966
10036
  applyModelOverride: (m) => this.applyModelOverride(m),
9967
10037
  options: this.options,
9968
10038
  pluginManagerCode: this.pluginManagerCode,
9969
- memoryGlue: this.memoryGlue,
9970
10039
  defaultMemoryProviderForLoop: this.defaultMemoryProviderForLoop,
9971
10040
  workspaceCwd: this.workspaceCwd,
9972
10041
  telemetry: this._telemetry,
9973
10042
  lifecycleAbortController: this.lifecycleAbortController,
9974
10043
  runPreHook: (ut) => this.runPreHook(ut),
9975
- // biome-ignore format: G8 budget — callbacks wire to private methods.
9976
10044
  resolveSystemPromptForSend: (ut, o, mf) => this.resolveSystemPrompt(ut, o, mf),
9977
- assembleSystemPromptForSend: (ut, bp, mf, ams, cp) => assembleSystemPromptForSend(this.assemblyInputs(), ut, bp, mf, ams, cp),
9978
- dispatchRun: (msg, o, sp, mf, pm, mt, mp) => this.dispatchRun(msg, o, sp, mf, pm, mt, mp)
10045
+ assembleSystemPromptForSend: (request) => assembleSystemPromptForSend({ ...request, inputs: this.assemblyInputs() }),
10046
+ dispatchRun: (args) => this.dispatchRun(args)
9979
10047
  },
9980
10048
  message,
9981
10049
  options
9982
10050
  );
9983
10051
  }
9984
- // biome-ignore format: G8 budget — thin accessor for the assembly inputs.
9985
10052
  assemblyInputs() {
9986
- 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 };
10053
+ return {
10054
+ agentId: this.agentId,
10055
+ workspaceCwd: this.workspaceCwd,
10056
+ model: this.model,
10057
+ options: this.options,
10058
+ context: this.context,
10059
+ skillsManager: this.skillsManager,
10060
+ settingSourcesIncludeProject: this.settingSourcesIncludeProject,
10061
+ systemPromptPipeline: this.systemPromptPipeline
10062
+ };
9987
10063
  }
9988
10064
  async resolveSystemPrompt(userText, options, memoryFacts) {
9989
10065
  const base = await resolveSystemPromptForSend(
@@ -10000,9 +10076,12 @@ var LocalAgent = class {
10000
10076
  return applyPersonalityOverlay(this.activePreset(), base);
10001
10077
  }
10002
10078
  /** @internal — read-only personality lookup (composes the helper, honors fork ALS). */
10003
- // biome-ignore format: keep one-liner so the personality lookup stays under G8.
10004
10079
  activePreset() {
10005
- return resolveActivePersonalityPreset({ agentId: this.agentId, personalityStore: this.personalityStore, personalityRegistry: this.personalityRegistry });
10080
+ return resolveActivePersonalityPreset({
10081
+ agentId: this.agentId,
10082
+ personalityStore: this.personalityStore,
10083
+ personalityRegistry: this.personalityRegistry
10084
+ });
10006
10085
  }
10007
10086
  applyModelOverride(overrideModel) {
10008
10087
  if (overrideModel === void 0) return;
@@ -10022,7 +10101,15 @@ var LocalAgent = class {
10022
10101
  );
10023
10102
  }
10024
10103
  }
10025
- dispatchRun(message, options, systemPrompt, memoryFacts, priorMessages, memoryTools, memoryProviderOverride) {
10104
+ dispatchRun({
10105
+ message,
10106
+ options,
10107
+ systemPrompt,
10108
+ memoryFacts,
10109
+ priorMessages,
10110
+ memoryTools,
10111
+ memoryProviderOverride
10112
+ }) {
10026
10113
  const effectiveAgentOptions = memoryProviderOverride !== void 0 && this.options.memoryProvider === void 0 ? { ...this.options, memoryProvider: memoryProviderOverride } : this.options;
10027
10114
  return dispatchLocalRun({
10028
10115
  inputs: {
@@ -10058,11 +10145,17 @@ var LocalAgent = class {
10058
10145
  [Symbol.asyncDispose]() {
10059
10146
  return this.dispose();
10060
10147
  }
10061
- // biome-ignore format: multi-line layout would push file past G8 LoC cap.
10062
10148
  /** T3.2 / ADR D94 — public `invalidateCache` API. @internal */
10063
- invalidateCache = (reason, opts = {}) => invalidateCacheImpl(this.agentId, reason, opts, this.disposed, () => this.dispose(), (p) => {
10064
- this.invalidationPending = p;
10065
- });
10149
+ invalidateCache = (reason, opts = {}) => invalidateCacheImpl(
10150
+ this.agentId,
10151
+ reason,
10152
+ opts,
10153
+ this.disposed,
10154
+ () => this.dispose(),
10155
+ (p) => {
10156
+ this.invalidationPending = p;
10157
+ }
10158
+ );
10066
10159
  /**
10067
10160
  * Activate a personality preset (Hermes #26, ADRs D160-D164).
10068
10161
  *
@@ -10077,41 +10170,33 @@ var LocalAgent = class {
10077
10170
  * @public
10078
10171
  */
10079
10172
  usePersonality(name, opts) {
10080
- return localAgentUsePersonality({
10081
- agentId: this.agentId,
10082
- workspaceCwd: this.workspaceCwd,
10083
- disposed: this.disposed,
10084
- personalityStore: this.personalityStore,
10085
- personalityRegistry: this.personalityRegistry,
10086
- invalidateCache: (reason) => this.invalidateCache(reason),
10087
- onRegistryLoaded: (reg) => {
10088
- this.personalityRegistry = reg;
10089
- },
10090
- name,
10091
- ...opts !== void 0 ? { opts } : {}
10092
- });
10173
+ if (this.disposed) throw new Error("Agent has been disposed");
10174
+ return localAgentUsePersonality(this, name, opts);
10093
10175
  }
10094
- // biome-ignore format: G8 budget artifact stubs (local agents have no artifacts); kept 1-line each.
10176
+ // The two operations `local-agent-capabilities.ts` is ABOUT: their runtime answers live beside the
10177
+ // static answer `supports()` gives, so a change to one cannot drift from the other.
10095
10178
  listArtifacts() {
10096
- return Promise.resolve([]);
10179
+ return localAgentCapabilities.listArtifacts();
10097
10180
  }
10098
- // biome-ignore format: G8 budget — see listArtifacts.
10099
10181
  downloadArtifact(_path) {
10100
- return Promise.reject(new UnsupportedRunOperationError("Artifacts are not supported for local agents", "downloadArtifact"));
10182
+ return localAgentCapabilities.downloadArtifact();
10101
10183
  }
10102
- // biome-ignore format: G8 budget — delegates to `local-agent-runtime-extensions.ts`; kept 1-line.
10103
10184
  runUntil(goal, options) {
10104
10185
  return localAgentRunUntil(this, goal, options);
10105
10186
  }
10106
- // biome-ignore format: G8 budget — see runUntil comment above.
10107
10187
  fork(options) {
10108
- return localAgentFork({ agentId: this.agentId, options: this.options, personalitySlugSnapshot: this.personalityStore.active(this.agentId) }, options);
10188
+ return localAgentFork(
10189
+ {
10190
+ agentId: this.agentId,
10191
+ options: this.options,
10192
+ personalitySlugSnapshot: this.personalityStore.active(this.agentId)
10193
+ },
10194
+ options
10195
+ );
10109
10196
  }
10110
- // biome-ignore format: G8 budget — see runUntil comment above.
10111
10197
  runToCompletion(message, options) {
10112
10198
  return localAgentRunToCompletion(this, message, options);
10113
10199
  }
10114
- // biome-ignore format: G8 budget — see runUntil comment above.
10115
10200
  streamToCompletion(message, options) {
10116
10201
  return localAgentStreamToCompletion(this, message, options);
10117
10202
  }
@@ -10124,7 +10209,7 @@ function includesSetting(options, source) {
10124
10209
  return sources !== void 0 && (sources.includes(source) || sources.includes("all"));
10125
10210
  }
10126
10211
 
10127
- // src/agent-helpers.ts
10212
+ // src/internal/agent/helpers.ts
10128
10213
  async function runCreateUnderSpan(options, span) {
10129
10214
  options = { ...options, model: normalizeModel(options.model) };
10130
10215
  validateAgentOptions(options);
@@ -10298,17 +10383,21 @@ async function validateRehydratedAgent(agentId, entry) {
10298
10383
  if (entry.runtime !== "local") return;
10299
10384
  const candidate = entry.options.local?.cwd ?? entry.cwd;
10300
10385
  if (typeof candidate !== "string") return;
10386
+ let info;
10301
10387
  try {
10302
- const info = await stat(candidate);
10303
- if (!info.isDirectory()) {
10304
- throw new Error(`Workspace path is not a directory: ${candidate}`);
10305
- }
10388
+ info = await stat(candidate);
10306
10389
  } catch (cause) {
10307
10390
  throw new UnknownAgentError(
10308
10391
  `Agent "${agentId}" cannot be rehydrated \u2014 workspace cwd "${candidate}" is missing or inaccessible.`,
10309
10392
  { code: "agent_rehydration_failed", cause }
10310
10393
  );
10311
10394
  }
10395
+ if (!info.isDirectory()) {
10396
+ throw new UnknownAgentError(
10397
+ `Agent "${agentId}" cannot be rehydrated \u2014 workspace cwd "${candidate}" exists but is not a directory.`,
10398
+ { code: "agent_rehydration_failed" }
10399
+ );
10400
+ }
10312
10401
  }
10313
10402
  function toAgentInfo(agent) {
10314
10403
  return isLocalAgentId(agent.agentId) ? toLocalAgentInfo(agent) : toCloudAgentInfo(agent);
@@ -10515,7 +10604,7 @@ var Agent = class _Agent {
10515
10604
  * @public
10516
10605
  */
10517
10606
  static async generateObject(options) {
10518
- const { generateObjectImpl } = await import('./generate-object-GUNAUVBX.js');
10607
+ const { generateObjectImpl } = await import('./generate-object-BXV7BZRP.js');
10519
10608
  return generateObjectImpl(options, {
10520
10609
  create: (opts) => _Agent.create(opts),
10521
10610
  delete: (agentId) => _Agent.delete(agentId)
@@ -10539,7 +10628,7 @@ var Agent = class _Agent {
10539
10628
  delete: (agentId) => _Agent.delete(agentId)
10540
10629
  };
10541
10630
  async function* wrapper() {
10542
- streamObjectImport ??= import('./stream-object-UF4QRQRU.js');
10631
+ streamObjectImport ??= import('./stream-object-HBFMIZLD.js');
10543
10632
  const { streamObjectImpl } = await streamObjectImport;
10544
10633
  yield* streamObjectImpl(options, deps);
10545
10634
  }
@@ -10563,7 +10652,7 @@ var Agent = class _Agent {
10563
10652
  * @public
10564
10653
  */
10565
10654
  static async batch(prompts, options) {
10566
- const { batchImpl } = await import('./batch-L4ZXS46M.js');
10655
+ const { batchImpl } = await import('./batch-US4F6WPK.js');
10567
10656
  return batchImpl(prompts, options, { create: (opts) => _Agent.create(opts) });
10568
10657
  }
10569
10658
  /**
@@ -10587,7 +10676,7 @@ var Agent = class _Agent {
10587
10676
  *
10588
10677
  * This bullet used to say the opposite ("Disposed agents are NOT auto-deleted...
10589
10678
  * call `Agent.delete(agentId)` first"). It was measured false in M91:
10590
- * `tests/m91-getorcreate-after-dispose.test.ts` builds an agent, disposes it, and
10679
+ * `tests/agent-getorcreate-after-dispose.test.ts` builds an agent, disposes it, and
10591
10680
  * gets a different instance back. The claim was about the PERSISTENT registry and
10592
10681
  * read as being about the live cache — and consumers built around the wrong half.
10593
10682
  * The agent-builder's M85 interrupt rotates the session id to work around a
@@ -10714,17 +10803,8 @@ var Agent = class _Agent {
10714
10803
  * @public
10715
10804
  */
10716
10805
  static async compact(agentId, options = {}) {
10717
- let reg = getRegisteredAgent(agentId);
10718
- if (reg === void 0) {
10719
- await hydrateRegistryFromDisk(process.cwd());
10720
- reg = getRegisteredAgent(agentId);
10721
- }
10722
- if (reg === void 0 || reg.runtime !== "local") {
10723
- throw new UnknownAgentError(
10724
- `No local agent "${agentId}" registered \u2014 compact targets local sessions.`
10725
- );
10726
- }
10727
- const { compactSessionTranscript, buildDefaultSummarizer: buildDefaultSummarizer2 } = await import('./compact-session-RIGOWC4Y.js');
10806
+ const reg = await requireLocalAgent(agentId, "compact");
10807
+ const { compactSessionTranscript, buildDefaultSummarizer: buildDefaultSummarizer2 } = await import('./compact-session-W4WLJTHA.js');
10728
10808
  const { cwd, model, store } = await openLocalStore(reg);
10729
10809
  return enqueueSessionWrite(
10730
10810
  cwd,
@@ -10750,17 +10830,8 @@ var Agent = class _Agent {
10750
10830
  * @public
10751
10831
  */
10752
10832
  static async injectSessionTurn(agentId, turn) {
10753
- let reg = getRegisteredAgent(agentId);
10754
- if (reg === void 0) {
10755
- await hydrateRegistryFromDisk(process.cwd());
10756
- reg = getRegisteredAgent(agentId);
10757
- }
10758
- if (reg === void 0 || reg.runtime !== "local") {
10759
- throw new UnknownAgentError(
10760
- `No local agent "${agentId}" registered \u2014 injectSessionTurn targets local sessions.`
10761
- );
10762
- }
10763
- const { injectSessionTurn } = await import('./inject-session-DAR7OUCW.js');
10833
+ const reg = await requireLocalAgent(agentId, "injectSessionTurn");
10834
+ const { injectSessionTurn } = await import('./inject-session-SUM6TDJF.js');
10764
10835
  const { cwd, model, store } = await openLocalStore(reg);
10765
10836
  await injectSessionTurn({
10766
10837
  store,
@@ -10789,17 +10860,8 @@ var Agent = class _Agent {
10789
10860
  * @public
10790
10861
  */
10791
10862
  static async transcript(agentId) {
10792
- let reg = getRegisteredAgent(agentId);
10793
- if (reg === void 0) {
10794
- await hydrateRegistryFromDisk(process.cwd());
10795
- reg = getRegisteredAgent(agentId);
10796
- }
10797
- if (reg === void 0 || reg.runtime !== "local") {
10798
- throw new UnknownAgentError(
10799
- `No local agent "${agentId}" registered \u2014 transcript targets local sessions.`
10800
- );
10801
- }
10802
- const { readSessionMessages } = await import('./agent-session-store-OPGRB4XM.js');
10863
+ const reg = await requireLocalAgent(agentId, "transcript");
10864
+ const { readSessionMessages } = await import('./agent-session-store-AFML3AXC.js');
10803
10865
  const { store } = await openLocalStore(reg);
10804
10866
  return readSessionMessages(store, agentId);
10805
10867
  }
@@ -10820,7 +10882,7 @@ var Agent = class _Agent {
10820
10882
  */
10821
10883
  static async describe(agentId) {
10822
10884
  const agent = await getRegisteredAgentOrThrow(agentId);
10823
- const { loadSubagents: loadSubagents2 } = await import('./subagents-loader-XP5ERVDZ.js');
10885
+ const { loadSubagents: loadSubagents2 } = await import('./subagents-loader-Y6JFYXAY.js');
10824
10886
  const settingSources = agent.options.local?.settingSources;
10825
10887
  const subagents = await loadSubagents2(
10826
10888
  agent.cwd ?? process.cwd(),
@@ -10883,17 +10945,30 @@ setAgentFacade({
10883
10945
  resume: (agentId, options) => Agent.resume(agentId, options),
10884
10946
  batch: (prompts, options) => Agent.batch(prompts, options)
10885
10947
  });
10948
+ async function requireLocalAgent(agentId, operation) {
10949
+ let reg = getRegisteredAgent(agentId);
10950
+ if (reg === void 0) {
10951
+ await hydrateRegistryFromDisk(process.cwd());
10952
+ reg = getRegisteredAgent(agentId);
10953
+ }
10954
+ if (reg === void 0 || reg.runtime !== "local") {
10955
+ throw new UnknownAgentError(
10956
+ `No local agent "${agentId}" registered \u2014 ${operation} targets local sessions.`
10957
+ );
10958
+ }
10959
+ return reg;
10960
+ }
10886
10961
  async function openLocalStore(reg) {
10887
10962
  const cwd = reg.cwd ?? process.cwd();
10888
10963
  const optModel = reg.options.model;
10889
10964
  const model = reg.model?.id ?? (typeof optModel === "string" ? optModel : optModel?.id) ?? "unknown";
10890
- const { FsSessionStore: FsSessionStore2 } = await import('./fs-session-store-NM6YSTE2.js');
10891
- const { defaultBaseDir: defaultBaseDir2, expandTilde: expandTilde2 } = await import('./session-transcript-XAEKW6P7.js');
10965
+ const { FsSessionStore: FsSessionStore2 } = await import('./fs-session-store-77JU46UZ.js');
10966
+ const { defaultBaseDir: defaultBaseDir2, expandTilde: expandTilde2 } = await import('./session-transcript-VTBTCGQX.js');
10892
10967
  const configuredSessionDir = reg.options.local?.sessionDir ?? reg.options.local?.baseDir;
10893
10968
  const baseDir = configuredSessionDir !== void 0 ? expandTilde2(configuredSessionDir) : defaultBaseDir2();
10894
10969
  return { cwd, model, store: new FsSessionStore2({ baseDir, cwd }) };
10895
10970
  }
10896
10971
 
10897
10972
  export { Agent, AgentBuilder, DEFAULT_AGENTIC_MODEL_ID, MEMORY_EMBEDDING_ADAPTERS, Tool, ToolError, UsageAccumulator, computeCost, generateCronId, getPricingEntry, openRouterMemoryEmbeddingProviderAdapter };
10898
- //# sourceMappingURL=chunk-LYTOXSRH.js.map
10899
- //# sourceMappingURL=chunk-LYTOXSRH.js.map
10973
+ //# sourceMappingURL=chunk-KDR53EO7.js.map
10974
+ //# sourceMappingURL=chunk-KDR53EO7.js.map