@theokit/sdk 5.13.0 → 5.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (241) hide show
  1. package/CHANGELOG.md +57 -0
  2. package/dist/{agent-DSMuwADp.d.ts → agent-B6C9i_qu.d.ts} +31 -213
  3. package/dist/{agent-iW5kPpfT.d.cts → agent-B6FQad6P.d.cts} +31 -213
  4. package/dist/{agent-5DSDDH7K.js → agent-DRDGUU6T.js} +21 -20
  5. package/dist/{agent-5DSDDH7K.js.map → agent-DRDGUU6T.js.map} +1 -1
  6. package/dist/{agent-WOMRT3KX.cjs → agent-VI2HITPT.cjs} +22 -21
  7. package/dist/{agent-WOMRT3KX.cjs.map → agent-VI2HITPT.cjs.map} +1 -1
  8. package/dist/agent.d.ts +2 -3
  9. package/dist/auth/index.cjs +17 -16
  10. package/dist/auth/index.cjs.map +1 -1
  11. package/dist/auth/index.js +5 -4
  12. package/dist/auth/index.js.map +1 -1
  13. package/dist/{batch-EP3FCL6D.js → batch-N2XDYZED.js} +4 -4
  14. package/dist/{batch-EP3FCL6D.js.map → batch-N2XDYZED.js.map} +1 -1
  15. package/dist/{batch-IZ5EDKJ5.cjs → batch-VFR2MAUE.cjs} +7 -7
  16. package/dist/{batch-IZ5EDKJ5.cjs.map → batch-VFR2MAUE.cjs.map} +1 -1
  17. package/dist/{chunk-XOYNB3YN.js → chunk-23SS4ID4.js} +3 -3
  18. package/dist/{chunk-XOYNB3YN.js.map → chunk-23SS4ID4.js.map} +1 -1
  19. package/dist/{chunk-NHOEXFZT.js → chunk-2HXTNVLM.js} +5 -2
  20. package/dist/chunk-2HXTNVLM.js.map +1 -0
  21. package/dist/{chunk-2C24NSNV.js → chunk-3BBTHFGJ.js} +3 -3
  22. package/dist/{chunk-2C24NSNV.js.map → chunk-3BBTHFGJ.js.map} +1 -1
  23. package/dist/{chunk-NP362THY.cjs → chunk-3F53FLQ7.cjs} +5 -7
  24. package/dist/chunk-3F53FLQ7.cjs.map +1 -0
  25. package/dist/{chunk-3FSBE4PS.js → chunk-3GTN4HOO.js} +10 -6
  26. package/dist/chunk-3GTN4HOO.js.map +1 -0
  27. package/dist/{chunk-7WARNHWW.cjs → chunk-3UMPP553.cjs} +5 -2
  28. package/dist/chunk-3UMPP553.cjs.map +1 -0
  29. package/dist/{chunk-SXH37C7X.cjs → chunk-55LLQFHW.cjs} +6 -6
  30. package/dist/{chunk-SXH37C7X.cjs.map → chunk-55LLQFHW.cjs.map} +1 -1
  31. package/dist/{chunk-QISSETTG.cjs → chunk-5645PMVU.cjs} +6 -4
  32. package/dist/chunk-5645PMVU.cjs.map +1 -0
  33. package/dist/{chunk-JX4LB6XO.js → chunk-5M5GQYBM.js} +617 -250
  34. package/dist/chunk-5M5GQYBM.js.map +1 -0
  35. package/dist/{chunk-KL7ZUMK3.cjs → chunk-64ECM3XM.cjs} +704 -337
  36. package/dist/chunk-64ECM3XM.cjs.map +1 -0
  37. package/dist/{chunk-ZJAYFSVI.js → chunk-7ACS6P5Z.js} +5 -7
  38. package/dist/chunk-7ACS6P5Z.js.map +1 -0
  39. package/dist/{chunk-5A4UFBHW.cjs → chunk-A77UMVMD.cjs} +15 -11
  40. package/dist/chunk-A77UMVMD.cjs.map +1 -0
  41. package/dist/{chunk-ZTP6ZACR.js → chunk-ARC2V7NY.js} +3 -3
  42. package/dist/{chunk-ZTP6ZACR.js.map → chunk-ARC2V7NY.js.map} +1 -1
  43. package/dist/{chunk-WDVG5R2Q.cjs → chunk-AUH2EVWY.cjs} +4 -3
  44. package/dist/chunk-AUH2EVWY.cjs.map +1 -0
  45. package/dist/chunk-BNEUB52I.cjs +55 -0
  46. package/dist/chunk-BNEUB52I.cjs.map +1 -0
  47. package/dist/chunk-BPL5CVZ5.js +53 -0
  48. package/dist/chunk-BPL5CVZ5.js.map +1 -0
  49. package/dist/{chunk-2SFLLOMN.js → chunk-CBBT42VX.js} +3 -3
  50. package/dist/{chunk-2SFLLOMN.js.map → chunk-CBBT42VX.js.map} +1 -1
  51. package/dist/chunk-CHKV2L2Y.cjs +416 -0
  52. package/dist/chunk-CHKV2L2Y.cjs.map +1 -0
  53. package/dist/{chunk-4UYHP6NF.cjs → chunk-DJKGDLYZ.cjs} +93 -63
  54. package/dist/chunk-DJKGDLYZ.cjs.map +1 -0
  55. package/dist/{chunk-354F3OF5.js → chunk-FGGVSHDW.js} +3 -3
  56. package/dist/{chunk-354F3OF5.js.map → chunk-FGGVSHDW.js.map} +1 -1
  57. package/dist/{chunk-6OCJWGVD.cjs → chunk-FTXY4D44.cjs} +4 -4
  58. package/dist/{chunk-6OCJWGVD.cjs.map → chunk-FTXY4D44.cjs.map} +1 -1
  59. package/dist/chunk-INVEGVGO.js +405 -0
  60. package/dist/chunk-INVEGVGO.js.map +1 -0
  61. package/dist/{chunk-2PRGRYEQ.js → chunk-IOBHFP2E.js} +50 -20
  62. package/dist/chunk-IOBHFP2E.js.map +1 -0
  63. package/dist/{chunk-47EACDOC.cjs → chunk-KMFBNKCT.cjs} +4 -4
  64. package/dist/{chunk-47EACDOC.cjs.map → chunk-KMFBNKCT.cjs.map} +1 -1
  65. package/dist/{chunk-DF77RBF4.js → chunk-LCCT5ZXJ.js} +6 -6
  66. package/dist/{chunk-DF77RBF4.js.map → chunk-LCCT5ZXJ.js.map} +1 -1
  67. package/dist/{chunk-G7XBVM3T.cjs → chunk-MHUOVS5I.cjs} +5 -5
  68. package/dist/{chunk-G7XBVM3T.cjs.map → chunk-MHUOVS5I.cjs.map} +1 -1
  69. package/dist/{chunk-CWQPQTUZ.cjs → chunk-NEH3BPFD.cjs} +15 -15
  70. package/dist/{chunk-CWQPQTUZ.cjs.map → chunk-NEH3BPFD.cjs.map} +1 -1
  71. package/dist/{chunk-5AR6O7GW.js → chunk-NK5EOTDY.js} +3 -3
  72. package/dist/{chunk-5AR6O7GW.js.map → chunk-NK5EOTDY.js.map} +1 -1
  73. package/dist/{chunk-S46WJTDL.cjs → chunk-P7QYG4RZ.cjs} +27 -19
  74. package/dist/chunk-P7QYG4RZ.cjs.map +1 -0
  75. package/dist/chunk-PPU2D4FZ.js +19 -0
  76. package/dist/chunk-PPU2D4FZ.js.map +1 -0
  77. package/dist/{chunk-MS3TQSXU.js → chunk-QD6B6W6I.js} +6 -4
  78. package/dist/chunk-QD6B6W6I.js.map +1 -0
  79. package/dist/{chunk-AB4OPJLD.js → chunk-RGVMJU57.js} +3 -3
  80. package/dist/{chunk-AB4OPJLD.js.map → chunk-RGVMJU57.js.map} +1 -1
  81. package/dist/{chunk-NWWTYBD3.cjs → chunk-RTDVSHJR.cjs} +5 -5
  82. package/dist/{chunk-NWWTYBD3.cjs.map → chunk-RTDVSHJR.cjs.map} +1 -1
  83. package/dist/{chunk-5HSMH2ZZ.js → chunk-RZL2W4C3.js} +25 -17
  84. package/dist/chunk-RZL2W4C3.js.map +1 -0
  85. package/dist/chunk-SPEN7RJU.cjs +18 -0
  86. package/dist/{chunk-LO6LIUZ6.cjs.map → chunk-SPEN7RJU.cjs.map} +1 -1
  87. package/dist/{chunk-ZF2LDKQQ.cjs → chunk-U3DW3WDE.cjs} +9 -8
  88. package/dist/chunk-U3DW3WDE.cjs.map +1 -0
  89. package/dist/{chunk-DVP3YMDA.cjs → chunk-U7PRI3XM.cjs} +3 -3
  90. package/dist/{chunk-DVP3YMDA.cjs.map → chunk-U7PRI3XM.cjs.map} +1 -1
  91. package/dist/{chunk-H7G65PNI.js → chunk-VCQ37TC5.js} +3 -3
  92. package/dist/{chunk-H7G65PNI.js.map → chunk-VCQ37TC5.js.map} +1 -1
  93. package/dist/{chunk-SDZ4XDWS.cjs → chunk-VWYFGE27.cjs} +9 -9
  94. package/dist/{chunk-SDZ4XDWS.cjs.map → chunk-VWYFGE27.cjs.map} +1 -1
  95. package/dist/{chunk-RN3XDZGS.js → chunk-WM646HEN.js} +4 -3
  96. package/dist/chunk-WM646HEN.js.map +1 -0
  97. package/dist/chunk-X7CE7Y5W.js +305 -0
  98. package/dist/chunk-X7CE7Y5W.js.map +1 -0
  99. package/dist/{chunk-CGH4BCIY.cjs → chunk-XE3CAY6Z.cjs} +5 -5
  100. package/dist/{chunk-CGH4BCIY.cjs.map → chunk-XE3CAY6Z.cjs.map} +1 -1
  101. package/dist/chunk-XOU3CL7S.cjs +312 -0
  102. package/dist/chunk-XOU3CL7S.cjs.map +1 -0
  103. package/dist/{chunk-NKQVLWDF.js → chunk-YKNBTHMD.js} +3 -3
  104. package/dist/{chunk-NKQVLWDF.js.map → chunk-YKNBTHMD.js.map} +1 -1
  105. package/dist/{compact-session-B7P6EU3Z.cjs → compact-session-NX7HUNTB.cjs} +18 -18
  106. package/dist/{compact-session-B7P6EU3Z.cjs.map → compact-session-NX7HUNTB.cjs.map} +1 -1
  107. package/dist/{compact-session-5HMX6KYT.js → compact-session-Q5IGNFPW.js} +9 -9
  108. package/dist/{compact-session-5HMX6KYT.js.map → compact-session-Q5IGNFPW.js.map} +1 -1
  109. package/dist/{cron-BvxrLW5J.d.cts → cron-Bh3aWgQ2.d.cts} +2 -2
  110. package/dist/{cron-DdKzwJqK.d.ts → cron-CCDxeeFZ.d.ts} +2 -2
  111. package/dist/cron.cjs +21 -20
  112. package/dist/cron.d.cts +4 -3
  113. package/dist/cron.d.ts +4 -3
  114. package/dist/cron.js +20 -19
  115. package/dist/eval.cjs +20 -19
  116. package/dist/eval.cjs.map +1 -1
  117. package/dist/eval.js +19 -18
  118. package/dist/eval.js.map +1 -1
  119. package/dist/fs-session-store-CYNTEPJZ.cjs +20 -0
  120. package/dist/{fs-session-store-S2AXVJIX.cjs.map → fs-session-store-CYNTEPJZ.cjs.map} +1 -1
  121. package/dist/fs-session-store-MYQEVUFL.js +11 -0
  122. package/dist/{fs-session-store-6ZCCJX3K.js.map → fs-session-store-MYQEVUFL.js.map} +1 -1
  123. package/dist/{index-manager-HO456AVW.cjs → index-manager-2KH75BRW.cjs} +7 -7
  124. package/dist/{index-manager-HO456AVW.cjs.map → index-manager-2KH75BRW.cjs.map} +1 -1
  125. package/dist/{index-manager-QDH56FER.js → index-manager-NF2WRLOU.js} +6 -6
  126. package/dist/{index-manager-QDH56FER.js.map → index-manager-NF2WRLOU.js.map} +1 -1
  127. package/dist/index.cjs +93 -273
  128. package/dist/index.cjs.map +1 -1
  129. package/dist/index.d.cts +13 -46
  130. package/dist/index.d.ts +13 -46
  131. package/dist/index.js +52 -236
  132. package/dist/index.js.map +1 -1
  133. package/dist/{inject-session-75L3NCNL.js → inject-session-4ROYLZHY.js} +3 -3
  134. package/dist/{inject-session-75L3NCNL.js.map → inject-session-4ROYLZHY.js.map} +1 -1
  135. package/dist/{inject-session-WOH7TPDX.cjs → inject-session-AWKDCGHV.cjs} +4 -4
  136. package/dist/{inject-session-WOH7TPDX.cjs.map → inject-session-AWKDCGHV.cjs.map} +1 -1
  137. package/dist/internal/agent-loop/doom-loop-tracker.d.ts +3 -0
  138. package/dist/internal/agent-loop/prune-tool-results.d.ts +37 -0
  139. package/dist/internal/agent-loop/types.d.ts +6 -0
  140. package/dist/internal/auth/credential-store.d.ts +1 -1
  141. package/dist/internal/auth/types.d.ts +4 -0
  142. package/dist/internal/error-mappers/anthropic.d.ts +3 -0
  143. package/dist/internal/error-mappers/openai-compatible.d.ts +2 -3
  144. package/dist/internal/local-agent/local-agent-dispatch.d.ts +3 -1
  145. package/dist/internal/local-agent/send-queue.d.ts +31 -0
  146. package/dist/internal/mcp/client.d.ts +2 -0
  147. package/dist/internal/mcp/oauth-bearer.d.ts +2 -0
  148. package/dist/internal/memory/adapters/index.cjs +3 -3
  149. package/dist/internal/memory/adapters/index.js +2 -2
  150. package/dist/internal/memory/dreaming/phases.d.ts +15 -0
  151. package/dist/internal/memory/dreaming/run.d.ts +29 -0
  152. package/dist/internal/memory/sdk-memory-peer-loader.d.ts +2 -0
  153. package/dist/internal/memory/storage/index.cjs +51 -35
  154. package/dist/internal/memory/storage/index.d.cts +2 -0
  155. package/dist/internal/memory/storage/index.d.ts +2 -0
  156. package/dist/internal/memory/storage/index.js +4 -4
  157. package/dist/internal/persistence/cwd-mutex.d.cts +4 -2
  158. package/dist/internal/persistence/cwd-mutex.d.ts +4 -2
  159. package/dist/internal/persistence/index.cjs +4 -4
  160. package/dist/internal/persistence/index.js +2 -2
  161. package/dist/internal/persistence/sqlite-session-store.d.cts +25 -0
  162. package/dist/internal/persistence/sqlite-session-store.d.ts +25 -0
  163. package/dist/internal/providers/registry.d.ts +5 -1
  164. package/dist/internal/runtime/skills/binary-on-path.d.ts +1 -0
  165. package/dist/internal/runtime/skills/discover-skills.d.ts +2 -0
  166. package/dist/mcp-auth.cjs +25 -307
  167. package/dist/mcp-auth.cjs.map +1 -1
  168. package/dist/mcp-auth.js +5 -305
  169. package/dist/mcp-auth.js.map +1 -1
  170. package/dist/models.cjs +11 -11
  171. package/dist/models.js +4 -4
  172. package/dist/persistence.cjs +9 -4
  173. package/dist/persistence.cjs.map +1 -1
  174. package/dist/persistence.d.cts +744 -40
  175. package/dist/persistence.d.ts +744 -40
  176. package/dist/persistence.js +3 -2
  177. package/dist/persistence.js.map +1 -1
  178. package/dist/providers.cjs +6 -6
  179. package/dist/providers.js +4 -4
  180. package/dist/sandbox/docker-sandbox.d.cts +58 -0
  181. package/dist/sandbox/docker-sandbox.d.ts +58 -0
  182. package/dist/sandbox/index.cjs +129 -1
  183. package/dist/sandbox/index.cjs.map +1 -1
  184. package/dist/sandbox/index.d.cts +1 -0
  185. package/dist/sandbox/index.d.ts +1 -0
  186. package/dist/sandbox/index.js +132 -5
  187. package/dist/sandbox/index.js.map +1 -1
  188. package/dist/{sdk-agent-4-dXI2GS.d.cts → sdk-agent-BA_6_wtc.d.cts} +57 -4
  189. package/dist/{sdk-agent-CTOJlWA_.d.ts → sdk-agent-CnwPODYH.d.ts} +57 -4
  190. package/dist/session-store-Dh07jr9N.d.cts +209 -0
  191. package/dist/session-store-Dh07jr9N.d.ts +209 -0
  192. package/dist/skills.cjs +4 -4
  193. package/dist/skills.js +1 -1
  194. package/dist/sqlite-session-store-BbcpKY1L.d.ts +64 -0
  195. package/dist/sqlite-session-store-TKXtT4ON.d.cts +64 -0
  196. package/dist/subagents-loader-KLWF4QPD.cjs +16 -0
  197. package/dist/{subagents-loader-TXOA5EJJ.cjs.map → subagents-loader-KLWF4QPD.cjs.map} +1 -1
  198. package/dist/subagents-loader-SXETS2F2.js +7 -0
  199. package/dist/{subagents-loader-Z744TAKD.js.map → subagents-loader-SXETS2F2.js.map} +1 -1
  200. package/dist/subagents-loader.cjs +2 -2
  201. package/dist/subagents-loader.d.cts +3 -2
  202. package/dist/subagents-loader.d.ts +3 -2
  203. package/dist/subagents-loader.js +1 -1
  204. package/dist/types/agent.d.ts +20 -1
  205. package/dist/types/budget-tracker.d.ts +6 -2
  206. package/dist/types/mcp.d.ts +14 -0
  207. package/dist/types/run.d.ts +42 -3
  208. package/dist/workflow.d.cts +1 -1
  209. package/dist/workflow.d.ts +1 -1
  210. package/docs/adr/mutation-testing-scope.md +66 -0
  211. package/docs/error-codes.md +48 -45
  212. package/docs/harness-capability-map.md +60 -6
  213. package/package.json +1 -1
  214. package/dist/chunk-2PRGRYEQ.js.map +0 -1
  215. package/dist/chunk-3FSBE4PS.js.map +0 -1
  216. package/dist/chunk-4UYHP6NF.cjs.map +0 -1
  217. package/dist/chunk-5A4UFBHW.cjs.map +0 -1
  218. package/dist/chunk-5HSMH2ZZ.js.map +0 -1
  219. package/dist/chunk-6CXRYPG7.cjs +0 -211
  220. package/dist/chunk-6CXRYPG7.cjs.map +0 -1
  221. package/dist/chunk-7WARNHWW.cjs.map +0 -1
  222. package/dist/chunk-JX4LB6XO.js.map +0 -1
  223. package/dist/chunk-KL7ZUMK3.cjs.map +0 -1
  224. package/dist/chunk-LO6LIUZ6.cjs +0 -18
  225. package/dist/chunk-MS3TQSXU.js.map +0 -1
  226. package/dist/chunk-MSEL5E5P.js +0 -204
  227. package/dist/chunk-MSEL5E5P.js.map +0 -1
  228. package/dist/chunk-NHOEXFZT.js.map +0 -1
  229. package/dist/chunk-NP362THY.cjs.map +0 -1
  230. package/dist/chunk-Q5EWJPRY.js +0 -18
  231. package/dist/chunk-Q5EWJPRY.js.map +0 -1
  232. package/dist/chunk-QISSETTG.cjs.map +0 -1
  233. package/dist/chunk-RN3XDZGS.js.map +0 -1
  234. package/dist/chunk-S46WJTDL.cjs.map +0 -1
  235. package/dist/chunk-WDVG5R2Q.cjs.map +0 -1
  236. package/dist/chunk-ZF2LDKQQ.cjs.map +0 -1
  237. package/dist/chunk-ZJAYFSVI.js.map +0 -1
  238. package/dist/fs-session-store-6ZCCJX3K.js +0 -11
  239. package/dist/fs-session-store-S2AXVJIX.cjs +0 -20
  240. package/dist/subagents-loader-TXOA5EJJ.cjs +0 -16
  241. package/dist/subagents-loader-Z744TAKD.js +0 -7
@@ -1,40 +1,41 @@
1
1
  'use strict';
2
2
 
3
3
  var chunkL7JPXZ2C_cjs = require('./chunk-L7JPXZ2C.cjs');
4
- var chunkDVP3YMDA_cjs = require('./chunk-DVP3YMDA.cjs');
5
- var chunkCWQPQTUZ_cjs = require('./chunk-CWQPQTUZ.cjs');
4
+ var chunkU7PRI3XM_cjs = require('./chunk-U7PRI3XM.cjs');
5
+ var chunkNEH3BPFD_cjs = require('./chunk-NEH3BPFD.cjs');
6
6
  var chunk7YUPSBDV_cjs = require('./chunk-7YUPSBDV.cjs');
7
7
  var chunkBV2MWEMV_cjs = require('./chunk-BV2MWEMV.cjs');
8
- var chunkCGH4BCIY_cjs = require('./chunk-CGH4BCIY.cjs');
8
+ var chunkXE3CAY6Z_cjs = require('./chunk-XE3CAY6Z.cjs');
9
9
  var chunkRS7YQR4X_cjs = require('./chunk-RS7YQR4X.cjs');
10
- var chunkSDZ4XDWS_cjs = require('./chunk-SDZ4XDWS.cjs');
11
- var chunk6OCJWGVD_cjs = require('./chunk-6OCJWGVD.cjs');
12
- var chunk4UYHP6NF_cjs = require('./chunk-4UYHP6NF.cjs');
10
+ var chunkVWYFGE27_cjs = require('./chunk-VWYFGE27.cjs');
11
+ var chunkFTXY4D44_cjs = require('./chunk-FTXY4D44.cjs');
12
+ var chunkDJKGDLYZ_cjs = require('./chunk-DJKGDLYZ.cjs');
13
13
  var chunk2ZPEDVLM_cjs = require('./chunk-2ZPEDVLM.cjs');
14
14
  var chunkQG4SXZ2A_cjs = require('./chunk-QG4SXZ2A.cjs');
15
15
  var chunkUDAKAE4Z_cjs = require('./chunk-UDAKAE4Z.cjs');
16
+ var chunkXOU3CL7S_cjs = require('./chunk-XOU3CL7S.cjs');
16
17
  var chunk3HA7N2BB_cjs = require('./chunk-3HA7N2BB.cjs');
17
18
  var chunkAA27GEYS_cjs = require('./chunk-AA27GEYS.cjs');
18
19
  var chunkYSTXFWQE_cjs = require('./chunk-YSTXFWQE.cjs');
19
20
  var chunkH7HD6RXO_cjs = require('./chunk-H7HD6RXO.cjs');
20
21
  var chunkNINIJCHU_cjs = require('./chunk-NINIJCHU.cjs');
21
- var chunk7WARNHWW_cjs = require('./chunk-7WARNHWW.cjs');
22
+ var chunk3UMPP553_cjs = require('./chunk-3UMPP553.cjs');
22
23
  var chunkIJ7M6GOG_cjs = require('./chunk-IJ7M6GOG.cjs');
23
24
  var chunk3KIUY67P_cjs = require('./chunk-3KIUY67P.cjs');
24
25
  var chunkSA6K24NB_cjs = require('./chunk-SA6K24NB.cjs');
25
26
  var chunk27V5I2WW_cjs = require('./chunk-27V5I2WW.cjs');
26
27
  var chunk3WKWBYPO_cjs = require('./chunk-3WKWBYPO.cjs');
27
- var chunkG7XBVM3T_cjs = require('./chunk-G7XBVM3T.cjs');
28
- var chunkZF2LDKQQ_cjs = require('./chunk-ZF2LDKQQ.cjs');
28
+ var chunkMHUOVS5I_cjs = require('./chunk-MHUOVS5I.cjs');
29
+ var chunkU3DW3WDE_cjs = require('./chunk-U3DW3WDE.cjs');
29
30
  var chunkZOFRNNZD_cjs = require('./chunk-ZOFRNNZD.cjs');
30
- var chunkWDVG5R2Q_cjs = require('./chunk-WDVG5R2Q.cjs');
31
+ var chunkAUH2EVWY_cjs = require('./chunk-AUH2EVWY.cjs');
31
32
  var chunkYQ3XC6C2_cjs = require('./chunk-YQ3XC6C2.cjs');
32
33
  var chunk6XQLTQB6_cjs = require('./chunk-6XQLTQB6.cjs');
33
34
  var chunkKX5QXLBS_cjs = require('./chunk-KX5QXLBS.cjs');
34
- var chunkNWWTYBD3_cjs = require('./chunk-NWWTYBD3.cjs');
35
+ var chunkRTDVSHJR_cjs = require('./chunk-RTDVSHJR.cjs');
35
36
  var chunk3EE6LVWT_cjs = require('./chunk-3EE6LVWT.cjs');
36
- var chunkLO6LIUZ6_cjs = require('./chunk-LO6LIUZ6.cjs');
37
- var chunkS46WJTDL_cjs = require('./chunk-S46WJTDL.cjs');
37
+ var chunkSPEN7RJU_cjs = require('./chunk-SPEN7RJU.cjs');
38
+ var chunkP7QYG4RZ_cjs = require('./chunk-P7QYG4RZ.cjs');
38
39
  var chunkNVXXWAU7_cjs = require('./chunk-NVXXWAU7.cjs');
39
40
  var chunkEHD25JBZ_cjs = require('./chunk-EHD25JBZ.cjs');
40
41
  var chunkCEGU5AVD_cjs = require('./chunk-CEGU5AVD.cjs');
@@ -458,7 +459,7 @@ async function saveRegistry(cwd, agents2) {
458
459
  serialized[id] = toSerialized(agent);
459
460
  }
460
461
  const path = registryPath(cwd);
461
- await chunkZF2LDKQQ_cjs.withCwdMutex(`registry:${cwd}`, async () => {
462
+ await chunkU3DW3WDE_cjs.withCwdMutex(`registry:${cwd}`, async () => {
462
463
  await chunk3HA7N2BB_cjs.writeVersionedJson(path, serialized, SCHEMA_VERSION);
463
464
  });
464
465
  }
@@ -866,7 +867,7 @@ async function readLegacyFacts(jsonPath) {
866
867
  }
867
868
  async function writeMigratedFacts(cwd, jsonPath, facts) {
868
869
  try {
869
- for (const fact of facts) await chunkSDZ4XDWS_cjs.appendFactToMarkdown(cwd, fact);
870
+ for (const fact of facts) await chunkVWYFGE27_cjs.appendFactToMarkdown(cwd, fact);
870
871
  await promises.unlink(jsonPath).catch(() => void 0);
871
872
  chunkRNXXYF22_cjs.diag(`[theokit-sdk] migrated ${facts.length} fact(s) from ${jsonPath} to MEMORY.md
872
873
  `);
@@ -883,11 +884,11 @@ async function migrateLegacyJson(cwd, config) {
883
884
  const key = `${cwd}::${config.namespace ?? "default"}::${config.scope ?? "agent"}::${config.userId ?? "default"}`;
884
885
  if (migrationRun.has(key)) return { migrated: false, factCount: 0, reason: "already-migrated" };
885
886
  migrationRun.add(key);
886
- const jsonPath = chunkSDZ4XDWS_cjs.legacyMemoryJsonPath(cwd, config);
887
+ const jsonPath = chunkVWYFGE27_cjs.legacyMemoryJsonPath(cwd, config);
887
888
  if (!await fileExists(jsonPath)) {
888
889
  return { migrated: false, factCount: 0, reason: "no-legacy-json" };
889
890
  }
890
- if (await fileExists(chunkSDZ4XDWS_cjs.memoryMdPath(chunkSDZ4XDWS_cjs.resolveMemoryRoot(cwd, config)))) {
891
+ if (await fileExists(chunkVWYFGE27_cjs.memoryMdPath(chunkVWYFGE27_cjs.resolveMemoryRoot(cwd, config)))) {
891
892
  chunkRNXXYF22_cjs.diag(
892
893
  `[theokit-sdk] memory migration skipped: both MEMORY.md and legacy JSON exist at ${jsonPath}; leaving both intact
893
894
  `
@@ -916,29 +917,29 @@ function unstoredRememberWarning(message) {
916
917
  if (isMemoryWritePrompt(message) && extractMemoryFact(message).length > 0) return void 0;
917
918
  const trimmed = message.trim();
918
919
  const quoted = trimmed.length > QUOTED_MESSAGE_MAX ? `${trimmed.slice(0, QUOTED_MESSAGE_MAX)}\u2026` : trimmed;
919
- return `[theokit-sdk] NOTHING WAS STORED \u2014 this message does not match the memory capture pattern: ${JSON.stringify(quoted)}. Supported: "Remember: <fact>" or "Remember (${chunkSDZ4XDWS_cjs.MEMORY_KINDS.join("|")}): <fact>". It still reaches the session transcript, so a follow-up may answer from it \u2014 that is search over transcripts, not a durable memory.`;
920
+ return `[theokit-sdk] NOTHING WAS STORED \u2014 this message does not match the memory capture pattern: ${JSON.stringify(quoted)}. Supported: "Remember: <fact>" or "Remember (${chunkVWYFGE27_cjs.MEMORY_KINDS.join("|")}): <fact>". It still reaches the session transcript, so a follow-up may answer from it \u2014 that is search over transcripts, not a durable memory.`;
920
921
  }
921
922
  function extractMemoryKind(message) {
922
923
  const match = REMEMBER_PATTERN.exec(message);
923
924
  const declared = match?.[1];
924
925
  if (declared === void 0) return void 0;
925
926
  const lowered = declared.toLowerCase();
926
- return chunkSDZ4XDWS_cjs.MEMORY_KINDS.includes(lowered) ? lowered : void 0;
927
+ return chunkVWYFGE27_cjs.MEMORY_KINDS.includes(lowered) ? lowered : void 0;
927
928
  }
928
929
  async function readMemoryFacts(cwd, config) {
929
930
  if (!config.enabled) return [];
930
931
  await migrateLegacyJson(cwd, config);
931
- return chunkSDZ4XDWS_cjs.readFacts(cwd, config);
932
+ return chunkVWYFGE27_cjs.readFacts(cwd, config);
932
933
  }
933
934
  async function appendMemoryFact(cwd, config, fact) {
934
935
  if (!config.enabled) return;
935
- chunkSDZ4XDWS_cjs.resolveMaxFacts(config.maxFacts);
936
+ chunkVWYFGE27_cjs.resolveMaxFacts(config.maxFacts);
936
937
  await migrateLegacyJson(cwd, config);
937
938
  const sanitized = {
938
939
  text: chunkRNXXYF22_cjs.redactSecrets(fact.text),
939
940
  ...fact.kind === void 0 ? {} : { kind: fact.kind }
940
941
  };
941
- await chunkSDZ4XDWS_cjs.appendFact(cwd, config, sanitized);
942
+ await chunkVWYFGE27_cjs.appendFact(cwd, config, sanitized);
942
943
  }
943
944
 
944
945
  // src/internal/runtime/fixtures/fixture-scripts.ts
@@ -1624,7 +1625,7 @@ function createRealCloudRun(options) {
1624
1625
  conversation: []
1625
1626
  };
1626
1627
  const apiKey = chunkRNXXYF22_cjs.resolveApiKey(options.agentOptions.apiKey);
1627
- const baseUrl = chunk4UYHP6NF_cjs.getConfiguredBaseUrl();
1628
+ const baseUrl = chunkDJKGDLYZ_cjs.getConfiguredBaseUrl();
1628
1629
  const handle = new RealCloudRun(
1629
1630
  {
1630
1631
  id,
@@ -1676,7 +1677,10 @@ var RealCloudRun = class extends FixtureRunBase {
1676
1677
  await this.consumeStream(response);
1677
1678
  } catch (cause) {
1678
1679
  if (this.terminated) return;
1679
- this.fail(cause instanceof Error ? cause.message : String(cause));
1680
+ this.fail(
1681
+ cause instanceof Error ? cause.message : String(cause),
1682
+ cause instanceof chunkCEGU5AVD_cjs.TheokitAgentError ? cause : void 0
1683
+ );
1680
1684
  }
1681
1685
  }
1682
1686
  async postRun(apiKey, baseUrl) {
@@ -1707,7 +1711,7 @@ var RealCloudRun = class extends FixtureRunBase {
1707
1711
  async consumeStream(response) {
1708
1712
  let finalStatus = "finished";
1709
1713
  let finalText = "";
1710
- for await (const record of chunk4UYHP6NF_cjs.parseSseStream(response.body, this.controller.signal)) {
1714
+ for await (const record of chunkDJKGDLYZ_cjs.parseSseStream(response.body, this.controller.signal)) {
1711
1715
  const parsed = safeParse(record.data);
1712
1716
  if (parsed === void 0) continue;
1713
1717
  const update = this.applyRecord(record.event, parsed);
@@ -1754,13 +1758,17 @@ var RealCloudRun = class extends FixtureRunBase {
1754
1758
  message: { role: "assistant", content: [{ type: "text", text }] }
1755
1759
  };
1756
1760
  }
1757
- fail(message, code) {
1761
+ fail(message, cause) {
1758
1762
  const event = this.buildAssistantEvent(message);
1759
1763
  this.script.events.push(event);
1760
1764
  this.notifyNewEvents();
1761
1765
  this.script.result = message;
1762
1766
  if (this.script.errorDetail === void 0) {
1763
- this.script.errorDetail = { message, ...code !== void 0 ? { code } : {} };
1767
+ this.script.errorDetail = {
1768
+ message,
1769
+ ...cause?.code !== void 0 ? { code: cause.code } : {},
1770
+ ...cause !== void 0 ? { cause } : {}
1771
+ };
1764
1772
  }
1765
1773
  this.transitionTo("error");
1766
1774
  }
@@ -1874,7 +1882,7 @@ var CloudAgent = class _CloudAgent {
1874
1882
  */
1875
1883
  isFixtureMode() {
1876
1884
  const apiKey = chunkRNXXYF22_cjs.resolveApiKey(this.options.apiKey);
1877
- return chunk4UYHP6NF_cjs.isFixtureApiKey(apiKey) && chunk4UYHP6NF_cjs.getConfiguredBaseUrl() === void 0;
1885
+ return chunkDJKGDLYZ_cjs.isFixtureApiKey(apiKey) && chunkDJKGDLYZ_cjs.getConfiguredBaseUrl() === void 0;
1878
1886
  }
1879
1887
  // SE9 — integrated structured output; delegates to the shared helper.
1880
1888
  generate(message, options) {
@@ -1900,7 +1908,7 @@ var CloudAgent = class _CloudAgent {
1900
1908
  throw new UnsupportedTaskOperationError("send", { cause: void 0 });
1901
1909
  }
1902
1910
  return new Promise((resolve, reject) => {
1903
- void chunkZF2LDKQQ_cjs.withCwdMutex(`agent-send:${this.agentId}`, async () => {
1911
+ void chunkU3DW3WDE_cjs.withCwdMutex(`agent-send:${this.agentId}`, async () => {
1904
1912
  let run;
1905
1913
  try {
1906
1914
  run = await this.sendLocked(message, options);
@@ -1929,7 +1937,7 @@ var CloudAgent = class _CloudAgent {
1929
1937
  const userText = typeof message === "string" ? message : message.text;
1930
1938
  const systemPrompt = await this.resolveSystemPromptForSend(userText, options);
1931
1939
  const apiKey = chunkRNXXYF22_cjs.resolveApiKey(this.options.apiKey);
1932
- const useRealRuntime = apiKey !== void 0 && !chunk4UYHP6NF_cjs.isFixtureApiKey(apiKey) && chunk4UYHP6NF_cjs.getConfiguredBaseUrl() !== void 0;
1940
+ const useRealRuntime = apiKey !== void 0 && !chunkDJKGDLYZ_cjs.isFixtureApiKey(apiKey) && chunkDJKGDLYZ_cjs.getConfiguredBaseUrl() !== void 0;
1933
1941
  return useRealRuntime ? createRealCloudRun({
1934
1942
  agentId: this.agentId,
1935
1943
  model: this.model ?? { id: DEFAULT_AGENTIC_MODEL_ID },
@@ -2263,7 +2271,7 @@ var PersonalityStore = class {
2263
2271
  async #persist(agentId, slug) {
2264
2272
  const filePath = this.#filePath();
2265
2273
  await promises.mkdir(path.dirname(filePath), { recursive: true });
2266
- await chunkG7XBVM3T_cjs.withFileLock(filePath, async () => {
2274
+ await chunkMHUOVS5I_cjs.withFileLock(filePath, async () => {
2267
2275
  const current = await readState(filePath);
2268
2276
  const nextAgents = { ...current.agents };
2269
2277
  if (slug === void 0) delete nextAgents[agentId];
@@ -2969,7 +2977,7 @@ function resolveWindowForRun(model, contextWindow) {
2969
2977
  const override = contextWindow !== void 0 && contextWindow > 0 ? contextWindow : void 0;
2970
2978
  return chunkKX5QXLBS_cjs.resolveEffectiveContextWindow({
2971
2979
  ...override !== void 0 ? { override } : {},
2972
- catalog: chunkS46WJTDL_cjs.getCatalogModelInfo(model)?.limit?.context,
2980
+ catalog: chunkP7QYG4RZ_cjs.getCatalogModelInfo(model)?.limit?.context,
2973
2981
  margin: chunkKX5QXLBS_cjs.CONTEXT_WINDOW_MARGIN,
2974
2982
  floor: chunkKX5QXLBS_cjs.CONTEXT_WINDOW_FLOOR
2975
2983
  });
@@ -2994,7 +3002,7 @@ async function runPostRunLifecycle(inputs) {
2994
3002
  try {
2995
3003
  const partial = await safeConversation(run);
2996
3004
  if (partial !== void 0) {
2997
- chunkDVP3YMDA_cjs.persistTurnToTranscript(sessionStore, { cwd: workspaceCwd, agentId, model }, agentId, {
3005
+ chunkU7PRI3XM_cjs.persistTurnToTranscript(sessionStore, { cwd: workspaceCwd, agentId, model }, agentId, {
2998
3006
  userText,
2999
3007
  conversation: partial
3000
3008
  });
@@ -3004,11 +3012,11 @@ async function runPostRunLifecycle(inputs) {
3004
3012
  chunkRNXXYF22_cjs.diag(`[theokit-sdk] partial transcript write failed (${agentId}): ${msg}
3005
3013
  `);
3006
3014
  }
3007
- await chunkDVP3YMDA_cjs.flushSessionWrites();
3015
+ await chunkU7PRI3XM_cjs.flushSessionWrites();
3008
3016
  return;
3009
3017
  }
3010
3018
  if (result.result !== void 0) {
3011
- chunkDVP3YMDA_cjs.appendSessionMessage(agentId, { role: "assistant", text: result.result });
3019
+ chunkU7PRI3XM_cjs.appendSessionMessage(agentId, { role: "assistant", text: result.result });
3012
3020
  }
3013
3021
  const conversation = await safeConversation(run);
3014
3022
  const resolvedWindow = resolveWindowForRun(model, contextWindow);
@@ -3019,7 +3027,7 @@ async function runPostRunLifecycle(inputs) {
3019
3027
  }
3020
3028
  const lastRequestUsage = result.usage?.requests?.at(-1)?.totalTokens;
3021
3029
  const usageForTrigger = lastRequestUsage ?? result.usage?.totalTokens;
3022
- chunkDVP3YMDA_cjs.persistTurnToTranscript(
3030
+ chunkU7PRI3XM_cjs.persistTurnToTranscript(
3023
3031
  sessionStore,
3024
3032
  { cwd: workspaceCwd, agentId, model },
3025
3033
  agentId,
@@ -3031,7 +3039,7 @@ async function runPostRunLifecycle(inputs) {
3031
3039
  // The EFFECTIVE window (after override, clamp and margin) — not the declared one. Swapping for
3032
3040
  // `contextWindow` here would budget against a number the clamp already rejected.
3033
3041
  contextWindow: effectiveWindow,
3034
- summarize: chunk4UYHP6NF_cjs.buildDefaultSummarizer({
3042
+ summarize: chunkDJKGDLYZ_cjs.buildDefaultSummarizer({
3035
3043
  agentModel: model,
3036
3044
  ...inputs.apiKey !== void 0 ? { apiKey: inputs.apiKey } : {}
3037
3045
  })
@@ -3044,7 +3052,7 @@ async function runPostRunLifecycle(inputs) {
3044
3052
  cwd: workspaceCwd,
3045
3053
  // Resolved once, here, and handed to both writers. Recomputing it inside either one is how
3046
3054
  // the summary ended up in a directory the indexer never scanned (#463).
3047
- memoryRoot: chunkSDZ4XDWS_cjs.resolveMemoryRoot(workspaceCwd, inputs.memory),
3055
+ memoryRoot: chunkVWYFGE27_cjs.resolveMemoryRoot(workspaceCwd, inputs.memory),
3048
3056
  runId: result.id,
3049
3057
  agentId,
3050
3058
  userText,
@@ -3056,7 +3064,7 @@ async function runPostRunLifecycle(inputs) {
3056
3064
  if (memoryProvider?.recordSessionSummary !== void 0) {
3057
3065
  await memoryProvider.recordSessionSummary(summaryArgs);
3058
3066
  } else {
3059
- await chunkSDZ4XDWS_cjs.writeSessionSummary(summaryArgs);
3067
+ await chunkVWYFGE27_cjs.writeSessionSummary(summaryArgs);
3060
3068
  }
3061
3069
  } catch (cause) {
3062
3070
  const message = cause instanceof Error ? cause.message : String(cause);
@@ -3073,7 +3081,7 @@ async function runPostRunLifecycle(inputs) {
3073
3081
  agentId,
3074
3082
  runId: result.id
3075
3083
  });
3076
- await chunkDVP3YMDA_cjs.flushSessionWrites();
3084
+ await chunkU7PRI3XM_cjs.flushSessionWrites();
3077
3085
  }
3078
3086
  async function safeConversation(run) {
3079
3087
  try {
@@ -3090,12 +3098,12 @@ var WORKSPACE_TRUST = {
3090
3098
  entries: "absolute folder realpaths"
3091
3099
  };
3092
3100
  function workspaceTrustRecordPath() {
3093
- return path.join(path.dirname(chunk4UYHP6NF_cjs.trustFilePath()), "trusted-workspace-plugins.json");
3101
+ return path.join(path.dirname(chunkDJKGDLYZ_cjs.trustFilePath()), "trusted-workspace-plugins.json");
3094
3102
  }
3095
3103
  function readTrustedWorkspaceFolders() {
3096
3104
  const path$1 = workspaceTrustRecordPath();
3097
3105
  const trusted = /* @__PURE__ */ new Set();
3098
- for (const entry of chunk4UYHP6NF_cjs.readTrustArray(path$1, WORKSPACE_TRUST)) {
3106
+ for (const entry of chunkDJKGDLYZ_cjs.readTrustArray(path$1, WORKSPACE_TRUST)) {
3099
3107
  if (path.isAbsolute(entry)) {
3100
3108
  trusted.add(entry);
3101
3109
  continue;
@@ -3166,38 +3174,234 @@ async function importEntry(candidate) {
3166
3174
  function isGeneralPlugin(value) {
3167
3175
  return chunkBV2MWEMV_cjs.isCodePlugin(value) && value.kind === "general" && typeof value.name === "string";
3168
3176
  }
3177
+
3178
+ // src/internal/runtime/registry/live-agent-registry.ts
3179
+ var DEFAULT_MAX_AGENTS = 100;
3180
+ var DEFAULT_IDLE_TIMEOUT_MS = 30 * 60 * 1e3;
3181
+ var DEFAULT_SWEEP_INTERVAL_MS = 6e4;
3182
+ var LiveAgentRegistry = class {
3183
+ #agents = /* @__PURE__ */ new Map();
3184
+ #maxAgents = DEFAULT_MAX_AGENTS;
3185
+ #idleTimeoutMs = DEFAULT_IDLE_TIMEOUT_MS;
3186
+ #sweepIntervalMs = DEFAULT_SWEEP_INTERVAL_MS;
3187
+ #onEvict;
3188
+ #sweepTimer;
3189
+ /**
3190
+ * Reconfigure registry behavior. Process-wide singleton (D310) — last
3191
+ * configure call wins for all subsequent operations.
3192
+ */
3193
+ configure(opts) {
3194
+ if (opts.maxAgents !== void 0) this.#maxAgents = Math.max(0, opts.maxAgents);
3195
+ if (opts.idleTimeoutMs !== void 0) this.#idleTimeoutMs = Math.max(0, opts.idleTimeoutMs);
3196
+ if (opts.sweepIntervalMs !== void 0)
3197
+ this.#sweepIntervalMs = Math.max(1e3, opts.sweepIntervalMs);
3198
+ this.#onEvict = opts.onEvict;
3199
+ this.#stopSweep();
3200
+ if (this.#idleTimeoutMs > 0) this.#startSweep();
3201
+ }
3202
+ /**
3203
+ * Lookup a cached agent. `get` is a use — refreshes `lastUsedAt` so the
3204
+ * entry survives LRU eviction.
3205
+ */
3206
+ get(id) {
3207
+ const entry = this.#agents.get(id);
3208
+ if (entry === void 0) return void 0;
3209
+ entry.lastUsedAt = Date.now();
3210
+ return entry.agent;
3211
+ }
3212
+ /**
3213
+ * Insert or overwrite an agent in the cache. Triggers fire-and-forget LRU
3214
+ * eviction when `size > maxAgents`.
3215
+ *
3216
+ * EC-4: when `id` already maps to a DIFFERENT agent instance, dispose the
3217
+ * old one before overwriting (race protection against two `getOrCreate`
3218
+ * calls creating two agents but only the second being cached — the first
3219
+ * would leak file handles + lifecycle controllers).
3220
+ */
3221
+ set(id, agent) {
3222
+ if (this.#maxAgents === 0) return;
3223
+ const existing = this.#agents.get(id);
3224
+ if (existing !== void 0 && existing.agent !== agent) {
3225
+ void existing.agent.dispose().catch(() => {
3226
+ chunkRNXXYF22_cjs.diag(`[theokit-sdk] dispose during overwrite failed (${id})
3227
+ `);
3228
+ });
3229
+ }
3230
+ this.#agents.set(id, { agent, lastUsedAt: Date.now() });
3231
+ if (this.#agents.size > this.#maxAgents) void this.#evictLRU();
3232
+ }
3233
+ /**
3234
+ * Remove the entry from the cache WITHOUT calling `dispose()` or
3235
+ * `onEvict`. Used by `LocalAgent.dispose()` itself so the disposed
3236
+ * instance can never be returned by a subsequent `get(id)` (dispose-cache
3237
+ * race fix). Idempotent — calling on an unknown id is a no-op.
3238
+ *
3239
+ * @internal
3240
+ */
3241
+ forget(id) {
3242
+ this.#agents.delete(id);
3243
+ }
3244
+ /**
3245
+ * Explicitly evict an agent by id. Returns `true` when the entry was
3246
+ * present (false = already gone). Calls `agent.dispose()` + `onEvict`
3247
+ * with reason `"explicit"`.
3248
+ */
3249
+ async evict(id) {
3250
+ const entry = this.#agents.get(id);
3251
+ if (entry === void 0) return false;
3252
+ this.#agents.delete(id);
3253
+ await this.#disposeAndNotify(id, entry.agent, "explicit");
3254
+ return true;
3255
+ }
3256
+ /**
3257
+ * Evict every cached agent. Used by graceful shutdown (`process.on('SIGTERM')`)
3258
+ * or end-of-test cleanup.
3259
+ */
3260
+ async evictAll() {
3261
+ const entries = Array.from(this.#agents.entries());
3262
+ this.#agents.clear();
3263
+ this.#stopSweep();
3264
+ for (const [id, entry] of entries) {
3265
+ await this.#disposeAndNotify(id, entry.agent, "explicit");
3266
+ }
3267
+ }
3268
+ /** Number of currently cached agents. */
3269
+ size() {
3270
+ return this.#agents.size;
3271
+ }
3272
+ /** Ids of cached agents, newest first (by lastUsedAt). */
3273
+ ids() {
3274
+ return Array.from(this.#agents.entries()).sort((a, b) => b[1].lastUsedAt - a[1].lastUsedAt).map(([id]) => id);
3275
+ }
3276
+ /**
3277
+ * LRU eviction: drop the entry with the smallest `lastUsedAt`. Runs only
3278
+ * when `size > maxAgents`. Asynchronous because `dispose()` is a Promise;
3279
+ * the hot-path caller (`set`) does not await.
3280
+ *
3281
+ * @internal
3282
+ */
3283
+ async #evictLRU() {
3284
+ if (this.#agents.size <= this.#maxAgents) return;
3285
+ let oldestId;
3286
+ let oldestAt = Infinity;
3287
+ for (const [id, entry2] of this.#agents) {
3288
+ if (entry2.lastUsedAt < oldestAt) {
3289
+ oldestAt = entry2.lastUsedAt;
3290
+ oldestId = id;
3291
+ }
3292
+ }
3293
+ if (oldestId === void 0) return;
3294
+ const entry = this.#agents.get(oldestId);
3295
+ if (entry === void 0) return;
3296
+ this.#agents.delete(oldestId);
3297
+ await this.#disposeAndNotify(oldestId, entry.agent, "lru");
3298
+ }
3299
+ /** Background sweep — drops entries whose `lastUsedAt < now - idleTimeoutMs`. */
3300
+ async #sweepIdle() {
3301
+ if (this.#idleTimeoutMs === 0) return;
3302
+ const threshold = Date.now() - this.#idleTimeoutMs;
3303
+ const toEvict = [];
3304
+ for (const [id, entry] of this.#agents) {
3305
+ if (entry.lastUsedAt < threshold) toEvict.push([id, entry]);
3306
+ }
3307
+ for (const [id, entry] of toEvict) {
3308
+ const current = this.#agents.get(id);
3309
+ if (current === void 0 || current.agent !== entry.agent) continue;
3310
+ this.#agents.delete(id);
3311
+ await this.#disposeAndNotify(id, entry.agent, "idle");
3312
+ }
3313
+ }
3314
+ #startSweep() {
3315
+ this.#sweepTimer = setInterval(() => void this.#sweepIdle(), this.#sweepIntervalMs);
3316
+ this.#sweepTimer.unref?.();
3317
+ }
3318
+ #stopSweep() {
3319
+ if (this.#sweepTimer !== void 0) {
3320
+ clearInterval(this.#sweepTimer);
3321
+ this.#sweepTimer = void 0;
3322
+ }
3323
+ }
3324
+ /** Dispose + notify with errors swallowed (D309). Single chokepoint. */
3325
+ async #disposeAndNotify(id, agent, reason) {
3326
+ try {
3327
+ await agent.dispose();
3328
+ } catch (cause) {
3329
+ const msg = cause instanceof Error ? cause.message : String(cause);
3330
+ chunkRNXXYF22_cjs.diag(`[theokit-sdk] dispose during eviction failed (${id}): ${msg}
3331
+ `);
3332
+ }
3333
+ if (this.#onEvict !== void 0) {
3334
+ try {
3335
+ this.#onEvict(id, reason);
3336
+ } catch (cause) {
3337
+ const msg = cause instanceof Error ? cause.message : String(cause);
3338
+ chunkRNXXYF22_cjs.diag(`[theokit-sdk] onEvict listener threw (${id}): ${msg}
3339
+ `);
3340
+ }
3341
+ }
3342
+ }
3343
+ };
3344
+ var liveAgentRegistry = chunkNVXXWAU7_cjs.globalSingleton(
3345
+ "theokit-sdk.runtime.live-agents",
3346
+ () => new LiveAgentRegistry()
3347
+ );
3348
+ function executableExtensions() {
3349
+ return process.platform === "win32" ? ["", ...(process.env.PATHEXT ?? ".EXE;.CMD").split(";")] : [""];
3350
+ }
3351
+ function isExecutable(file) {
3352
+ try {
3353
+ fs.accessSync(file, fs.constants.X_OK);
3354
+ return true;
3355
+ } catch {
3356
+ return false;
3357
+ }
3358
+ }
3359
+ function binaryOnPath(bin) {
3360
+ if (bin.length === 0 || /[\\/]/.test(bin)) return false;
3361
+ const dirs = (process.env.PATH ?? "").split(path.delimiter).filter((dir) => dir.length > 0);
3362
+ return dirs.some(
3363
+ (dir) => executableExtensions().some((ext) => isExecutable(path.join(dir, bin + ext)))
3364
+ );
3365
+ }
3169
3366
  var SkillsManager = class {
3170
- constructor(cwd, _enabled, settingSourcesIncludeProject, skillsDir, inline, compatSources = []) {
3367
+ constructor(cwd, enabled, settingSourcesIncludeProject, skillsDir, inline, compatSources = [], bundledDirs = []) {
3171
3368
  this.cwd = cwd;
3369
+ this.enabled = enabled;
3172
3370
  this.settingSourcesIncludeProject = settingSourcesIncludeProject;
3173
3371
  this.skillsDir = skillsDir;
3174
3372
  this.inline = inline;
3175
3373
  this.compatSources = compatSources;
3374
+ this.bundledDirs = bundledDirs;
3176
3375
  }
3177
3376
  cwd;
3377
+ enabled;
3178
3378
  settingSourcesIncludeProject;
3179
3379
  skillsDir;
3180
3380
  inline;
3181
3381
  compatSources;
3382
+ bundledDirs;
3182
3383
  skills = [];
3183
3384
  async initialize() {
3184
3385
  if (!this.settingSourcesIncludeProject) {
3185
- this.skills = this.mergeInline([]);
3386
+ this.skills = this.mergeInline(await this.discoverFrom(this.bundledDirs));
3186
3387
  return;
3187
3388
  }
3188
3389
  await this.refresh();
3189
3390
  }
3190
3391
  async refresh() {
3191
- const roots = this.skillsDir === void 0 ? [
3392
+ const ownRoots = this.skillsDir === void 0 ? [
3192
3393
  ...chunkYQ3XC6C2_cjs.projectConfigRoots(this.cwd, this.compatSources, "skills").map(
3193
3394
  (root) => path.join(root, "skills")
3194
3395
  ),
3195
- ...(await chunkWDVG5R2Q_cjs.pluginBundleDirs(this.cwd, this.compatSources)).map((b) => path.join(b, "skills"))
3396
+ ...(await chunkAUH2EVWY_cjs.pluginBundleDirs(this.cwd, this.compatSources)).map((b) => path.join(b, "skills"))
3196
3397
  ] : [this.skillsDir];
3398
+ this.skills = this.mergeInline(await this.discoverFrom([...ownRoots, ...this.bundledDirs]));
3399
+ }
3400
+ async discoverFrom(roots) {
3197
3401
  const discovered = [];
3198
3402
  const seen = /* @__PURE__ */ new Set();
3199
3403
  for (const root of roots) {
3200
- for (const skill of await chunk7WARNHWW_cjs.discoverSkills(root, {
3404
+ for (const skill of await chunk3UMPP553_cjs.discoverSkills(root, {
3201
3405
  onInvalidSkill: (info) => {
3202
3406
  chunkRNXXYF22_cjs.diag(`[theokit-sdk] skill ${info.name} skipped (${info.code}): ${info.message}
3203
3407
  `);
@@ -3208,7 +3412,7 @@ var SkillsManager = class {
3208
3412
  discovered.push(skill);
3209
3413
  }
3210
3414
  }
3211
- this.skills = this.mergeInline(discovered);
3415
+ return discovered;
3212
3416
  }
3213
3417
  /** M22 — merge inline skills over discovered ones; inline wins on a name conflict. */
3214
3418
  mergeInline(discovered) {
@@ -3216,8 +3420,12 @@ var SkillsManager = class {
3216
3420
  const inlineNames = new Set(this.inline.map((s) => s.name));
3217
3421
  return [...discovered.filter((s) => !inlineNames.has(s.name)), ...this.inline];
3218
3422
  }
3423
+ visible() {
3424
+ const allowed = this.enabled;
3425
+ return allowed === void 0 ? this.skills : this.skills.filter((s) => allowed.includes(s.name));
3426
+ }
3219
3427
  list() {
3220
- return Promise.resolve(this.skills);
3428
+ return Promise.resolve(this.visible());
3221
3429
  }
3222
3430
  /**
3223
3431
  * SE20 — resolve a skill by name INCLUDING its body. Inline (`createSkill`)
@@ -3226,9 +3434,9 @@ var SkillsManager = class {
3226
3434
  * enabled skill matches (malformed skills were already excluded at discovery).
3227
3435
  */
3228
3436
  async get(name) {
3229
- const skill = this.skills.find((s) => s.name === name);
3437
+ const skill = this.visible().find((s) => s.name === name);
3230
3438
  if (skill === void 0) return void 0;
3231
- const instructions = typeof skill.instructions === "string" ? skill.instructions : chunk7WARNHWW_cjs.stripSkillFrontmatter(await promises.readFile(skill.source, "utf8"));
3439
+ const instructions = typeof skill.instructions === "string" ? skill.instructions : chunk3UMPP553_cjs.stripSkillFrontmatter(await promises.readFile(skill.source, "utf8"));
3232
3440
  const references = skill.references;
3233
3441
  return {
3234
3442
  name: skill.name,
@@ -3336,7 +3544,8 @@ async function resolveSendSkills(inputs, userText, memoryFacts) {
3336
3544
  inputs.settingSourcesIncludeProject,
3337
3545
  settings.skillsDir,
3338
3546
  settings.inline,
3339
- resolveCompatSources(inputs.options, inputs.workspaceCwd)
3547
+ resolveCompatSources(inputs.options, inputs.workspaceCwd),
3548
+ settings.bundledDirs
3340
3549
  );
3341
3550
  await manager.initialize();
3342
3551
  return { manager, autoInject: settings.autoInject ?? true };
@@ -3355,7 +3564,9 @@ async function buildSystemPromptContext(inputs, userText, memoryFacts, manager =
3355
3564
  // because a caller naming one has already made the decision this field keeps away from the
3356
3565
  // model. Widening it to execution would break the case the field is FOR — a side-effecting
3357
3566
  // skill a human may run and the model may not propose.
3358
- skills: skills.filter((skill) => skill.disableModelInvocation !== true).map((skill) => ({ name: skill.name, description: skill.description })),
3567
+ skills: skills.filter((skill) => skill.disableModelInvocation !== true).filter(
3568
+ (skill) => skill.requiresBins === void 0 || skill.requiresBins.every((bin) => binaryOnPath(bin))
3569
+ ).map((skill) => ({ name: skill.name, description: skill.description })),
3359
3570
  userMessage: userText,
3360
3571
  memory: memoryFacts.map((fact) => ({ text: fact.text }))
3361
3572
  };
@@ -3415,7 +3626,7 @@ var ActiveMemoryPromptProvider = class {
3415
3626
  if (ctx.activeMemorySummary === void 0 || ctx.activeMemorySummary.length === 0) {
3416
3627
  return Promise.resolve(void 0);
3417
3628
  }
3418
- const body = chunk7WARNHWW_cjs.escapeBlockBody(ctx.activeMemorySummary);
3629
+ const body = chunk3UMPP553_cjs.escapeBlockBody(ctx.activeMemorySummary);
3419
3630
  return Promise.resolve(`<active-memory>
3420
3631
  ${body}
3421
3632
  </active-memory>`);
@@ -3468,7 +3679,7 @@ function formatSource(name, tokens) {
3468
3679
  if (tokens.length === 0) {
3469
3680
  return ` <source name="${escapeAttribute(name)}" />`;
3470
3681
  }
3471
- const body = chunk7WARNHWW_cjs.escapeBlockBody(tokens.join(" "));
3682
+ const body = chunk3UMPP553_cjs.escapeBlockBody(tokens.join(" "));
3472
3683
  return ` <source name="${escapeAttribute(name)}">
3473
3684
  ${body}
3474
3685
  </source>`;
@@ -3492,7 +3703,7 @@ var MemoryPromptProvider = class {
3492
3703
  if (ctx.memory.length === 0) return Promise.resolve(void 0);
3493
3704
  const lines = ctx.memory.map((fact) => {
3494
3705
  const tag = fact.observations === 1 ? "[unconfirmed] " : "";
3495
- return ` - ${tag}${chunk7WARNHWW_cjs.escapeBlockBody(fact.text)}`;
3706
+ return ` - ${tag}${chunk3UMPP553_cjs.escapeBlockBody(fact.text)}`;
3496
3707
  });
3497
3708
  return Promise.resolve(`${MEMORY_GUIDANCE}
3498
3709
  <memory>
@@ -3516,7 +3727,7 @@ var SkillsPromptProvider = class {
3516
3727
  priority = 20;
3517
3728
  contribute(ctx) {
3518
3729
  if (ctx.skillsAutoInject === false) return Promise.resolve(void 0);
3519
- return Promise.resolve(chunk7WARNHWW_cjs.buildSkillsBlock(ctx.skills));
3730
+ return Promise.resolve(chunk3UMPP553_cjs.buildSkillsBlock(ctx.skills));
3520
3731
  }
3521
3732
  };
3522
3733
 
@@ -3651,6 +3862,23 @@ function validateMcpServers(options) {
3651
3862
  { code: "cloud_stdio_cwd_rejected" }
3652
3863
  );
3653
3864
  }
3865
+ rejectUnhonourableAuth(name, config, options.cloud !== void 0);
3866
+ }
3867
+ }
3868
+ function rejectUnhonourableAuth(name, config, cloud) {
3869
+ const auth = config.auth;
3870
+ if (auth === void 0) return;
3871
+ if (auth.oauth === void 0) {
3872
+ throw new chunkCEGU5AVD_cjs.ConfigurationError(
3873
+ `MCP server "${name}" declares auth without auth.oauth, which the SDK cannot honour; use auth.oauth or set an Authorization header`,
3874
+ { code: "mcp_auth_unsupported" }
3875
+ );
3876
+ }
3877
+ if (cloud) {
3878
+ throw new chunkCEGU5AVD_cjs.ConfigurationError(
3879
+ `MCP server "${name}" declares auth.oauth, which the SDK cannot run for a cloud agent`,
3880
+ { code: "mcp_auth_unsupported" }
3881
+ );
3654
3882
  }
3655
3883
  }
3656
3884
  function isStdioWithCwd(config) {
@@ -3759,7 +3987,7 @@ function validateToolSchema(tool) {
3759
3987
  }
3760
3988
  function validateMemory(options) {
3761
3989
  const memory = options.memory;
3762
- chunkSDZ4XDWS_cjs.resolveMaxFacts(memory?.maxFacts);
3990
+ chunkVWYFGE27_cjs.resolveMaxFacts(memory?.maxFacts);
3763
3991
  if (memory?.storePath === void 0) return;
3764
3992
  const storePath = memory.storePath;
3765
3993
  if (storePath.includes("..") || storePath.startsWith("/") || /^[A-Z]:/i.test(storePath)) {
@@ -3785,7 +4013,7 @@ var HISTOGRAM_NAMES = {
3785
4013
  };
3786
4014
  function safeRequire(moduleName) {
3787
4015
  try {
3788
- const r = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('chunk-KL7ZUMK3.cjs', document.baseURI).href)));
4016
+ const r = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('chunk-64ECM3XM.cjs', document.baseURI).href)));
3789
4017
  return r(moduleName);
3790
4018
  } catch {
3791
4019
  return void 0;
@@ -4028,7 +4256,7 @@ var cachedOtel;
4028
4256
  function loadOtel() {
4029
4257
  if (cachedOtel === void 0) {
4030
4258
  try {
4031
- const r = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('chunk-KL7ZUMK3.cjs', document.baseURI).href)));
4259
+ const r = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('chunk-64ECM3XM.cjs', document.baseURI).href)));
4032
4260
  const mod = r("@opentelemetry/api");
4033
4261
  cachedOtel = mod;
4034
4262
  } catch {
@@ -4167,8 +4395,13 @@ function wrapSpan(span, openSpans) {
4167
4395
  setAttribute: (k, v) => safe(() => span.setAttribute(k, redactAttrValue(v)), void 0),
4168
4396
  setAttributes: (attrs) => safe(() => span.setAttributes(redactAttrs(attrs)), void 0),
4169
4397
  addEvent: (name, attrs) => safe(() => span.addEvent(name, attrs ? redactAttrs(attrs) : void 0), void 0),
4170
- setStatus: (status) => safe(() => span.setStatus(status), void 0),
4171
- recordException: (err) => safe(() => span.recordException(err), void 0),
4398
+ setStatus: (status) => safe(
4399
+ () => span.setStatus(
4400
+ status.message === void 0 ? status : { ...status, message: chunkRNXXYF22_cjs.redactSecrets(status.message) }
4401
+ ),
4402
+ void 0
4403
+ ),
4404
+ recordException: (err) => safe(() => span.recordException(redactException(err)), void 0),
4172
4405
  end: (endTime) => {
4173
4406
  safe(() => span.end(endTime), void 0);
4174
4407
  openSpans.delete(span);
@@ -4177,6 +4410,18 @@ function wrapSpan(span, openSpans) {
4177
4410
  isRecording: () => safe(() => span.isRecording(), false)
4178
4411
  };
4179
4412
  }
4413
+ function redactException(err) {
4414
+ if (typeof err === "string") return chunkRNXXYF22_cjs.redactSecrets(err);
4415
+ if (typeof err !== "object" || err === null) return err;
4416
+ const src = err;
4417
+ const out = {};
4418
+ for (const k of ["name", "code", "message", "stack"]) {
4419
+ const v = src[k];
4420
+ if (typeof v === "string") out[k] = chunkRNXXYF22_cjs.redactSecrets(v);
4421
+ else if (typeof v === "number") out[k] = v;
4422
+ }
4423
+ return out;
4424
+ }
4180
4425
  function redactAttrValue(value) {
4181
4426
  if (typeof value !== "string") return value;
4182
4427
  return chunkRNXXYF22_cjs.redactSecrets(value);
@@ -4900,7 +5145,8 @@ function buildSkills(args, out) {
4900
5145
  staticSkills?.inline,
4901
5146
  // #524 — the same declaration the per-send manager reads. Omitting it here would make
4902
5147
  // `agent.skills` disagree with the system prompt about which skills exist.
4903
- resolveCompatSources(args.options, args.workspaceCwd)
5148
+ resolveCompatSources(args.options, args.workspaceCwd),
5149
+ staticSkills?.bundledDirs
4904
5150
  );
4905
5151
  const localSkills = out.skillsManager;
4906
5152
  out.skills = {
@@ -5140,7 +5386,9 @@ function evaluateBudgetGate(tracker) {
5140
5386
  return {
5141
5387
  allowed: false,
5142
5388
  reason: "custom",
5143
- detail: `budget_tracker_check_threw: ${message}`
5389
+ detail: `budget_tracker_check_threw: ${message}`,
5390
+ // Keep the thrown value so the run's error can carry it as its cause.
5391
+ cause: error
5144
5392
  };
5145
5393
  }
5146
5394
  }
@@ -5150,11 +5398,12 @@ function createDoomLoopTracker(option) {
5150
5398
  if (option === false) return void 0;
5151
5399
  return new DoomLoopTracker(option);
5152
5400
  }
5153
- var DEFAULT_CONFIG = { softThreshold: 3, hardThreshold: 5 };
5154
- function assertValidThresholds(soft, hard) {
5401
+ var DEFAULT_CONFIG = { softThreshold: 3, hardThreshold: 5, churnThreshold: 6 };
5402
+ function assertValidThresholds(soft, hard, churn) {
5155
5403
  for (const [label, value] of [
5156
5404
  ["softThreshold", soft],
5157
- ["hardThreshold", hard]
5405
+ ["hardThreshold", hard],
5406
+ ["churnThreshold", churn]
5158
5407
  ]) {
5159
5408
  if (!Number.isInteger(value) || value < 1) {
5160
5409
  throw new chunkCEGU5AVD_cjs.ConfigurationError(
@@ -5191,17 +5440,40 @@ var DoomLoopTracker = class {
5191
5440
  #config;
5192
5441
  #lastSignature = "";
5193
5442
  #count = 0;
5443
+ #lastName = "";
5444
+ #lastResult;
5445
+ #churn = 0;
5194
5446
  constructor(config) {
5195
5447
  const softThreshold = config?.softThreshold ?? DEFAULT_CONFIG.softThreshold;
5196
5448
  const hardThreshold = config?.hardThreshold ?? DEFAULT_CONFIG.hardThreshold;
5197
- assertValidThresholds(softThreshold, hardThreshold);
5198
- this.#config = { softThreshold, hardThreshold };
5449
+ const churnThreshold = config?.churnThreshold ?? DEFAULT_CONFIG.churnThreshold;
5450
+ assertValidThresholds(softThreshold, hardThreshold, churnThreshold);
5451
+ this.#config = { softThreshold, hardThreshold, churnThreshold };
5199
5452
  }
5200
5453
  inspect(call) {
5201
5454
  const signature = signatureOf(call);
5202
- this.#count = signature === this.#lastSignature ? this.#count + 1 : 1;
5455
+ const identical = signature === this.#lastSignature;
5456
+ const churning = !identical && call.name === this.#lastName && call.result !== void 0 && call.result === this.#lastResult;
5457
+ this.#churn = churning ? this.#churn + 1 : 1;
5458
+ this.#lastName = call.name;
5459
+ this.#lastResult = call.result;
5460
+ this.#count = identical ? this.#count + 1 : 1;
5203
5461
  this.#lastSignature = signature;
5204
5462
  const count = this.#count;
5463
+ const churn = this.#churn;
5464
+ const churnHard = this.#config.churnThreshold;
5465
+ if (churn >= churnHard) {
5466
+ return {
5467
+ kind: "hard",
5468
+ message: `Detected argument churn: ${churn} consecutive calls to \`${call.name}\` with different arguments and no change in the result; stopping to avoid a loop.`
5469
+ };
5470
+ }
5471
+ if (churn > 1 && churn === Math.max(2, churnHard - 2)) {
5472
+ return {
5473
+ kind: "soft",
5474
+ message: `Detected argument churn: ${churn} consecutive calls to \`${call.name}\` with different arguments and no change in the result; try a different approach.`
5475
+ };
5476
+ }
5205
5477
  if (count >= this.#config.hardThreshold) {
5206
5478
  return {
5207
5479
  kind: "hard",
@@ -5219,6 +5491,9 @@ var DoomLoopTracker = class {
5219
5491
  reset() {
5220
5492
  this.#lastSignature = "";
5221
5493
  this.#count = 0;
5494
+ this.#lastName = "";
5495
+ this.#lastResult = void 0;
5496
+ this.#churn = 0;
5222
5497
  }
5223
5498
  };
5224
5499
  function firstDoomLoopVerdict(tracker, calls) {
@@ -5463,7 +5738,16 @@ async function initLoopContext(inputs) {
5463
5738
  ),
5464
5739
  buildUserEvent(inputs)
5465
5740
  ]);
5466
- if (inputs.onLoopEvent !== void 0) events.subscribe(inputs.onLoopEvent);
5741
+ if (inputs.onLoopEvent !== void 0) {
5742
+ const sink = inputs.onLoopEvent;
5743
+ for (const seeded of events) {
5744
+ try {
5745
+ sink(seeded);
5746
+ } catch {
5747
+ }
5748
+ }
5749
+ events.subscribe(sink);
5750
+ }
5467
5751
  const priorMessages = replayMessages(inputs.priorMessages ?? []);
5468
5752
  let memorySystemPromptAdditions;
5469
5753
  if (inputs.memoryProvider !== void 0 && memoryProviderHandle !== void 0) {
@@ -5552,7 +5836,8 @@ async function collectTools(mcp, withheld, sink) {
5552
5836
  inputSchema: tool.inputSchema,
5553
5837
  origin: "mcp",
5554
5838
  mcpServerName: serverName,
5555
- mcpToolName: tool.name
5839
+ mcpToolName: tool.name,
5840
+ ...client.sequential === true ? { mcpSequential: true } : {}
5556
5841
  });
5557
5842
  }
5558
5843
  }
@@ -5752,7 +6037,7 @@ function catalogCostFallback(provider, cleanedModel) {
5752
6037
  const candidates = [`${provider}/${cleanedModel}`, cleanedModel];
5753
6038
  if (stripped !== cleanedModel) candidates.push(`${provider}/${stripped}`, stripped);
5754
6039
  for (const key of candidates) {
5755
- const info = chunkS46WJTDL_cjs.getCatalogModelInfo(key);
6040
+ const info = chunkP7QYG4RZ_cjs.getCatalogModelInfo(key);
5756
6041
  const cost = info?.cost;
5757
6042
  if (cost === void 0) continue;
5758
6043
  const [prov, ...modelParts] = key.split("/");
@@ -5764,7 +6049,7 @@ function catalogCostFallback(provider, cleanedModel) {
5764
6049
  ...cost.cache_read !== void 0 ? { cacheReadCostPerMillion: cost.cache_read } : {},
5765
6050
  ...cost.cache_write !== void 0 ? { cacheWriteCostPerMillion: cost.cache_write } : {},
5766
6051
  // M44 M5 fix — honest provenance: a key patched by the LIVE models-dev source is not "vendored".
5767
- pricingVersion: chunkS46WJTDL_cjs.isPatchedModelKey(key) ? "catalog-models-dev" : "catalog-vendored"
6052
+ pricingVersion: chunkP7QYG4RZ_cjs.isPatchedModelKey(key) ? "catalog-models-dev" : "catalog-vendored"
5768
6053
  };
5769
6054
  }
5770
6055
  return void 0;
@@ -5967,6 +6252,42 @@ function stripThinkBlocks(content) {
5967
6252
  return { visible, thinking };
5968
6253
  }
5969
6254
 
6255
+ // src/internal/agent-loop/prune-tool-results.ts
6256
+ function stubFor(olderThanRounds) {
6257
+ return `[tool result pruned: older than ${olderThanRounds} rounds]`;
6258
+ }
6259
+ function carriesToolResult(message) {
6260
+ return message.content.some((part) => part.type === "tool_result");
6261
+ }
6262
+ function stubbed(message, stub) {
6263
+ const content = message.content.map(
6264
+ (part) => part.type === "tool_result" ? { ...part, content: stub } : part
6265
+ );
6266
+ return { ...message, content };
6267
+ }
6268
+ function pruneToolResultsForRequest(messages, options) {
6269
+ if (options === void 0) return messages;
6270
+ const stub = stubFor(options.olderThanRounds);
6271
+ const out = [...messages];
6272
+ let rounds = 0;
6273
+ for (let index = messages.length - 1; index >= 0; index -= 1) {
6274
+ const message = messages[index];
6275
+ if (!carriesToolResult(message)) continue;
6276
+ rounds += 1;
6277
+ if (rounds > options.olderThanRounds) out[index] = stubbed(message, stub);
6278
+ }
6279
+ return out;
6280
+ }
6281
+ function validatePruneToolResults(options) {
6282
+ if (options === void 0) return;
6283
+ const value = options.olderThanRounds;
6284
+ if (typeof value === "number" && Number.isInteger(value) && value >= 1) return;
6285
+ throw new chunkCEGU5AVD_cjs.ConfigurationError(
6286
+ `SendOptions.pruneToolResults.olderThanRounds must be an integer of at least 1, got ${String(value)}`,
6287
+ { code: "invalid_prune_tool_results" }
6288
+ );
6289
+ }
6290
+
5970
6291
  // src/internal/agent-loop/loop-llm-stream.ts
5971
6292
  function resolveSystemPromptWithMemoryAdditions(systemPrompt, additions) {
5972
6293
  if (additions === void 0 || additions.length === 0) return systemPrompt;
@@ -5978,11 +6299,11 @@ ${systemPrompt}`;
5978
6299
  }
5979
6300
  function activeMemoryBlock(additions) {
5980
6301
  return `<active-memory>
5981
- ${chunk7WARNHWW_cjs.escapeBlockBody(additions)}
6302
+ ${chunk3UMPP553_cjs.escapeBlockBody(additions)}
5982
6303
  </active-memory>`;
5983
6304
  }
5984
6305
  function buildLoopSystem(systemPrompt, additions, modelId) {
5985
- if (!chunkNWWTYBD3_cjs.isAnthropicFamilyModel(modelId) || systemPrompt === void 0 || systemPrompt.length === 0) {
6306
+ if (!chunkRTDVSHJR_cjs.isAnthropicFamilyModel(modelId) || systemPrompt === void 0 || systemPrompt.length === 0) {
5986
6307
  return resolveSystemPromptWithMemoryAdditions(systemPrompt, additions);
5987
6308
  }
5988
6309
  const blocks = [{ text: systemPrompt, cacheable: true }];
@@ -6055,7 +6376,8 @@ async function streamLlmTurn(inputs, ctx) {
6055
6376
  const key = derivePromptCacheKey(inputs.agentId);
6056
6377
  return key !== void 0 ? { promptCacheKey: key } : {};
6057
6378
  })(),
6058
- messages: ctx.messages,
6379
+ // B-564: the request gets a pruned copy; ctx.messages stays whole (the transcript is resent from it).
6380
+ messages: pruneToolResultsForRequest(ctx.messages, inputs.pruneToolResults),
6059
6381
  tools: ctx.tools.map(toLlmTool)
6060
6382
  },
6061
6383
  signal
@@ -6502,11 +6824,35 @@ function raceToolExecution(exec, opts) {
6502
6824
  // src/internal/agent-loop/tool-dispatch.ts
6503
6825
  async function dispatchTools(inputs, tools, toolCalls, events, parentSpan) {
6504
6826
  const maxConcurrent = inputs.maxConcurrentTools ?? 4;
6505
- return chunk27V5I2WW_cjs.mapWithConcurrency(
6506
- toolCalls,
6507
- maxConcurrent,
6508
- (call) => dispatchSingleCall(inputs, tools, call, events, parentSpan)
6509
- );
6827
+ const units = [];
6828
+ const bySequentialServer = /* @__PURE__ */ new Map();
6829
+ toolCalls.forEach((call, index) => {
6830
+ const tool = tools.find((t) => t.name === call.name);
6831
+ if (tool?.mcpSequential === true && tool.mcpServerName !== void 0) {
6832
+ let unit = bySequentialServer.get(tool.mcpServerName);
6833
+ if (unit === void 0) {
6834
+ unit = { indexes: [] };
6835
+ bySequentialServer.set(tool.mcpServerName, unit);
6836
+ units.push(unit);
6837
+ }
6838
+ unit.indexes.push(index);
6839
+ } else {
6840
+ units.push({ indexes: [index] });
6841
+ }
6842
+ });
6843
+ const results = new Array(toolCalls.length);
6844
+ await chunk27V5I2WW_cjs.mapWithConcurrency(units, maxConcurrent, async (unit) => {
6845
+ for (const index of unit.indexes) {
6846
+ results[index] = await dispatchSingleCall(
6847
+ inputs,
6848
+ tools,
6849
+ toolCalls[index],
6850
+ events,
6851
+ parentSpan
6852
+ );
6853
+ }
6854
+ });
6855
+ return results;
6510
6856
  }
6511
6857
  async function dispatchSingleCall(inputs, tools, call, events, parentSpan) {
6512
6858
  const { call: workingCall, repairs } = applyRepairAndExtractCall(tools, call);
@@ -6846,7 +7192,7 @@ function applyToolResultGuard(parts, opts) {
6846
7192
  (p) => (
6847
7193
  // SE7 — guard the TEXT of a tool result (string or the text blocks of a
6848
7194
  // structured content); image blocks pass through untouched.
6849
- p.type === "tool_result" ? { ...p, content: chunk4UYHP6NF_cjs.renderToolResultContentText(p.content, (t) => guardText(t, opts)) } : p
7195
+ p.type === "tool_result" ? { ...p, content: chunkDJKGDLYZ_cjs.renderToolResultContentText(p.content, (t) => guardText(t, opts)) } : p
6850
7196
  )
6851
7197
  );
6852
7198
  }
@@ -6883,12 +7229,17 @@ async function runAgentLoop(inputs) {
6883
7229
  const budget = inputs.budget ?? new IterationBudget({ maxIterations: inputs.maxIterations ?? 8 });
6884
7230
  let lastTurnDecision;
6885
7231
  while (budget.shouldContinue()) {
7232
+ injectSteered(ctx, inputs.steerQueue?.drain());
6886
7233
  if (inputs.budgetTracker !== void 0) {
6887
7234
  const decision2 = evaluateBudgetGate(inputs.budgetTracker);
6888
7235
  if (decision2.allowed === false) {
6889
7236
  ctx.finalStatus = "error";
6890
7237
  if (decision2.detail !== void 0) {
6891
- ctx.error = { message: decision2.detail, code: decision2.reason ?? "budget" };
7238
+ ctx.error = {
7239
+ message: decision2.detail,
7240
+ code: decision2.reason ?? "budget",
7241
+ ...decision2.cause !== void 0 ? { cause: decision2.cause } : {}
7242
+ };
6892
7243
  }
6893
7244
  if (decision2.reason === "iteration_limit") {
6894
7245
  ctx.stoppedAtIterationLimit = true;
@@ -6900,7 +7251,13 @@ async function runAgentLoop(inputs) {
6900
7251
  if (usingGrace) budget.useGraceCall();
6901
7252
  const decision = await runIteration(inputs, ctx);
6902
7253
  lastTurnDecision = decision;
6903
- if (decision === "done") break;
7254
+ if (decision === "done") {
7255
+ const late = inputs.steerQueue?.drainOrClose() ?? [];
7256
+ if (late.length === 0) break;
7257
+ injectSteered(ctx, late);
7258
+ budget.consume();
7259
+ continue;
7260
+ }
6904
7261
  if (decision === "error") {
6905
7262
  ctx.finalStatus = "error";
6906
7263
  break;
@@ -7028,6 +7385,10 @@ async function finishOrReflect(inputs, ctx, llmOutput) {
7028
7385
  ctx.finalStatus = "finished";
7029
7386
  return "done";
7030
7387
  }
7388
+ function injectSteered(ctx, texts) {
7389
+ if (texts === void 0) return;
7390
+ for (const text of texts) ctx.messages.push({ role: "user", content: [{ type: "text", text }] });
7391
+ }
7031
7392
  async function runIteration(inputs, ctx) {
7032
7393
  const hookCtx = { agentId: inputs.agentId, runId: inputs.runId };
7033
7394
  await inputs.pluginManager?.runPreLlmCallHooks(hookCtx);
@@ -7041,12 +7402,11 @@ function trackTurnUsage(inputs, llmOutput) {
7041
7402
  const tracker = inputs.budgetTracker;
7042
7403
  if (tracker === void 0) return;
7043
7404
  const model = inputs.model.id ?? "auto";
7044
- trackEvent(tracker, { tokens: promptTokens(llmOutput), model, type: "input" });
7405
+ trackEvent(tracker, { tokens: llmOutput.inputTokens ?? 0, model, type: "input" });
7406
+ trackEvent(tracker, { tokens: llmOutput.cacheReadTokens ?? 0, model, type: "cache_read" });
7407
+ trackEvent(tracker, { tokens: llmOutput.cacheWriteTokens ?? 0, model, type: "cache_write" });
7045
7408
  trackEvent(tracker, { tokens: llmOutput.outputTokens ?? 0, model, type: "output" });
7046
7409
  }
7047
- function promptTokens(llmOutput) {
7048
- return (llmOutput.inputTokens ?? 0) + (llmOutput.cacheReadTokens ?? 0) + (llmOutput.cacheWriteTokens ?? 0);
7049
- }
7050
7410
  function trackEvent(tracker, event) {
7051
7411
  if (event.tokens <= 0) return;
7052
7412
  try {
@@ -7105,12 +7465,22 @@ async function continueOrTerminate(inputs, ctx, llmOutput) {
7105
7465
  }
7106
7466
  }
7107
7467
  pushToolConversationSteps(ctx, llmOutput.toolCalls, toolResults);
7108
- if (await inspectDoomLoop(inputs, ctx, llmOutput.toolCalls) === "stop") return "done";
7468
+ if (await inspectDoomLoop(inputs, ctx, llmOutput.toolCalls, toolResults) === "stop")
7469
+ return "done";
7109
7470
  return handleToolErrorContinuation(inputs, ctx, toolResults);
7110
7471
  }
7111
- async function inspectDoomLoop(inputs, ctx, toolCalls) {
7472
+ async function inspectDoomLoop(inputs, ctx, toolCalls, toolResults) {
7112
7473
  if (ctx.doomLoop === void 0) return "continue";
7113
- const verdict = firstDoomLoopVerdict(ctx.doomLoop, toolCalls);
7474
+ const resultById = /* @__PURE__ */ new Map();
7475
+ for (const part of toolResults) {
7476
+ if (part.type === "tool_result") {
7477
+ resultById.set(part.toolUseId, JSON.stringify([part.content, part.isError === true]));
7478
+ }
7479
+ }
7480
+ const verdict = firstDoomLoopVerdict(
7481
+ ctx.doomLoop,
7482
+ toolCalls.map((c) => ({ name: c.name, input: c.input, result: resultById.get(c.id) }))
7483
+ );
7114
7484
  if (verdict.kind === "hard") {
7115
7485
  ctx.stoppedByDoomLoop = true;
7116
7486
  await emitAssistantTextStep(
@@ -7164,13 +7534,13 @@ var FallbackLlmClient = class {
7164
7534
  async *stream(request, signal) {
7165
7535
  let lastError;
7166
7536
  for (const client of this.clients) {
7167
- if (signal.aborted) throw chunk4UYHP6NF_cjs.abortError(signal);
7168
- const attempt = await chunk4UYHP6NF_cjs.tryFirstEvent(client, request, signal, true);
7537
+ if (signal.aborted) throw chunkDJKGDLYZ_cjs.abortError(signal);
7538
+ const attempt = await chunkDJKGDLYZ_cjs.tryFirstEvent(client, request, signal, true);
7169
7539
  if (attempt.kind === "handshake_error") {
7170
7540
  lastError = attempt.error;
7171
7541
  continue;
7172
7542
  }
7173
- return yield* chunk4UYHP6NF_cjs.relayStream(attempt.generator, attempt.firstResult);
7543
+ return yield* chunkDJKGDLYZ_cjs.relayStream(attempt.generator, attempt.firstResult);
7174
7544
  }
7175
7545
  if (lastError !== void 0) throw lastError;
7176
7546
  throw new chunkCEGU5AVD_cjs.NetworkError("FallbackLlmClient has no providers configured", {
@@ -7187,6 +7557,34 @@ function handshakeAwareTimeout(input) {
7187
7557
  return isReconnectHandshake ? Math.max(input.requestTimeoutMs, HANDSHAKE_FLOOR_MS) : input.requestTimeoutMs;
7188
7558
  }
7189
7559
 
7560
+ // src/internal/mcp/oauth-bearer.ts
7561
+ var EXPIRY_SKEW_MS = 3e4;
7562
+ async function obtain(serverName, clientId, scopes, oauth) {
7563
+ const stored = await chunkXOU3CL7S_cjs.getTokens(serverName);
7564
+ if (stored?.accessToken !== void 0 && stored.expiresAt - EXPIRY_SKEW_MS > Date.now()) {
7565
+ return stored;
7566
+ }
7567
+ const refreshToken = stored?.refreshToken;
7568
+ if (refreshToken !== void 0) {
7569
+ try {
7570
+ return await chunkXOU3CL7S_cjs.lockedRefresh(
7571
+ serverName,
7572
+ () => chunkXOU3CL7S_cjs.refreshAccessToken(serverName, clientId, refreshToken, oauth)
7573
+ );
7574
+ } catch {
7575
+ }
7576
+ }
7577
+ const fresh = await chunkXOU3CL7S_cjs.runPkceFlow(serverName, clientId, scopes, oauth);
7578
+ await chunkXOU3CL7S_cjs.setTokens(serverName, fresh);
7579
+ return fresh;
7580
+ }
7581
+ async function resolveBearer(serverName, auth) {
7582
+ if (auth.oauth === void 0)
7583
+ throw new Error(`MCP server "${serverName}" declares no auth.oauth`);
7584
+ const tokens = await obtain(serverName, auth.CLIENT_ID, auth.scopes, auth.oauth);
7585
+ return `Bearer ${tokens.accessToken}`;
7586
+ }
7587
+
7190
7588
  // src/internal/mcp/client.ts
7191
7589
  function createMcpClient(name, config, fetchImpl = fetch) {
7192
7590
  if (isStdio(config)) return new StdioMcpClient(name, config);
@@ -7267,6 +7665,9 @@ var StdioMcpClient = class extends BaseMcpClient {
7267
7665
  reconnectPromise;
7268
7666
  /** True only while `reconnect()`'s handshake is in flight — see `timeoutFor`. */
7269
7667
  reconnecting = false;
7668
+ get sequential() {
7669
+ return this.config.sequential === true;
7670
+ }
7270
7671
  get timeoutMs() {
7271
7672
  return this.config.requestTimeoutMs ?? DEFAULT_MCP_TIMEOUT_MS;
7272
7673
  }
@@ -7473,6 +7874,9 @@ var HttpMcpClient = class extends BaseMcpClient {
7473
7874
  */
7474
7875
  sessionId;
7475
7876
  fetchImpl;
7877
+ get sequential() {
7878
+ return this.config.sequential === true;
7879
+ }
7476
7880
  close() {
7477
7881
  return Promise.resolve();
7478
7882
  }
@@ -7485,7 +7889,9 @@ var HttpMcpClient = class extends BaseMcpClient {
7485
7889
  * override contract predates this change and is the only escape a user has while a server
7486
7890
  * misbehaves.
7487
7891
  */
7488
- buildHeaders() {
7892
+ async buildHeaders() {
7893
+ const auth = this.config.auth;
7894
+ const bearer = auth?.oauth !== void 0 ? await resolveBearer(this.name, auth) : void 0;
7489
7895
  return {
7490
7896
  "content-type": "application/json",
7491
7897
  // Streamable HTTP asks for BOTH media types. Declaring only `application/json` makes a
@@ -7494,6 +7900,7 @@ var HttpMcpClient = class extends BaseMcpClient {
7494
7900
  // Present only for a STATEFUL server. For a stateless one nothing is sent — inventing a
7495
7901
  // header would trade one broken transport for another.
7496
7902
  ...this.sessionId !== void 0 ? { "mcp-session-id": this.sessionId } : {},
7903
+ ...bearer !== void 0 ? { authorization: bearer } : {},
7497
7904
  ...this.config.headers ?? {}
7498
7905
  };
7499
7906
  }
@@ -7536,7 +7943,7 @@ var HttpMcpClient = class extends BaseMcpClient {
7536
7943
  async request(method, params) {
7537
7944
  const id = this.nextId++;
7538
7945
  const payload = { jsonrpc: "2.0", id, method, params };
7539
- const headers = this.buildHeaders();
7946
+ const headers = await this.buildHeaders();
7540
7947
  const timeoutMs = this.config.requestTimeoutMs ?? DEFAULT_MCP_TIMEOUT_MS;
7541
7948
  let response;
7542
7949
  try {
@@ -7798,6 +8205,13 @@ function createRealLocalRun(options) {
7798
8205
  registerRun(handle);
7799
8206
  return handle;
7800
8207
  }
8208
+ function toolResultPolicyInputs(sendOptions) {
8209
+ return {
8210
+ ...sendOptions.perToolTimeoutMs !== void 0 ? { perToolTimeoutMs: sendOptions.perToolTimeoutMs } : {},
8211
+ ...sendOptions.toolResultGuard !== void 0 ? { toolResultGuard: sendOptions.toolResultGuard } : {},
8212
+ ...sendOptions.pruneToolResults !== void 0 ? { pruneToolResults: sendOptions.pruneToolResults } : {}
8213
+ };
8214
+ }
7801
8215
  function buildLoopInputs(options, runId, userText, userImages) {
7802
8216
  const maxIterations = options.sendOptions.maxIterations;
7803
8217
  if (maxIterations !== void 0 && (!Number.isInteger(maxIterations) || maxIterations < 1)) {
@@ -7806,9 +8220,10 @@ function buildLoopInputs(options, runId, userText, userImages) {
7806
8220
  { code: "invalid_max_iterations" }
7807
8221
  );
7808
8222
  }
7809
- const { primary, effectiveModelId } = chunk4UYHP6NF_cjs.resolveRunProvider(options);
8223
+ validatePruneToolResults(options.sendOptions.pruneToolResults);
8224
+ const { primary, effectiveModelId } = chunkDJKGDLYZ_cjs.resolveRunProvider(options);
7810
8225
  const fallback = options.agentOptions.providers?.fallback;
7811
- const apiKeys = chunk4UYHP6NF_cjs.mergeExplicitApiKey(
8226
+ const apiKeys = chunkDJKGDLYZ_cjs.mergeExplicitApiKey(
7812
8227
  options.agentOptions.providers?.apiKeys,
7813
8228
  primary,
7814
8229
  options.agentOptions.apiKey
@@ -7817,7 +8232,7 @@ function buildLoopInputs(options, runId, userText, userImages) {
7817
8232
  const extractToolCallsFromContent = options.agentOptions.providers?.routes?.[0]?.extractToolCallsFromContent;
7818
8233
  const rateLimitSink = options.sendOptions.onRunEvent;
7819
8234
  const modelBaseUrl = options.model?.url;
7820
- const chain = chunk4UYHP6NF_cjs.resolveProviderChain({
8235
+ const chain = chunkDJKGDLYZ_cjs.resolveProviderChain({
7821
8236
  primary,
7822
8237
  ...modelBaseUrl !== void 0 ? { baseUrl: modelBaseUrl } : {},
7823
8238
  ...fallback !== void 0 ? { fallback } : {},
@@ -7875,10 +8290,8 @@ function buildLoopInputs(options, runId, userText, userImages) {
7875
8290
  ...options.sendOptions.context !== void 0 ? { context: options.sendOptions.context } : {},
7876
8291
  // SE2 — forward the opt-in typed runtime-event sink to the loop.
7877
8292
  ...options.sendOptions.onRunEvent !== void 0 ? { runEventSink: options.sendOptions.onRunEvent } : {},
7878
- // #58 / #57 — forward the per-tool timeout + tool-result guard so a consumer
7879
- // can enable them via SendOptions (not only internal AgentLoopInputs).
7880
- ...options.sendOptions.perToolTimeoutMs !== void 0 ? { perToolTimeoutMs: options.sendOptions.perToolTimeoutMs } : {},
7881
- ...options.sendOptions.toolResultGuard !== void 0 ? { toolResultGuard: options.sendOptions.toolResultGuard } : {},
8293
+ ...options.steerQueue !== void 0 ? { steerQueue: options.steerQueue } : {},
8294
+ ...toolResultPolicyInputs(options.sendOptions),
7882
8295
  // M1-2: per-send iteration ceiling (validated above). The loop reads
7883
8296
  // inputs.maxIterations (default 8 when unset).
7884
8297
  ...maxIterations !== void 0 ? { maxIterations } : {},
@@ -8099,11 +8512,12 @@ function buildRealRunOptions(args) {
8099
8512
  ...args.priorMessages.length > 0 ? { priorMessages: args.priorMessages } : {},
8100
8513
  ...args.memoryTools !== void 0 && args.memoryTools.length > 0 ? { memoryTools: args.memoryTools } : {},
8101
8514
  ...args.personalityToolWhitelist !== void 0 ? { personalityToolWhitelist: args.personalityToolWhitelist } : {},
8102
- ...args.personalityName !== void 0 ? { personalityName: args.personalityName } : {}
8515
+ ...args.personalityName !== void 0 ? { personalityName: args.personalityName } : {},
8516
+ ...args.steerQueue !== void 0 ? { steerQueue: args.steerQueue } : {}
8103
8517
  };
8104
8518
  }
8105
8519
  async function createFixtureRunHelper(args) {
8106
- const sessionMessages = chunkDVP3YMDA_cjs.getSessionMessages(args.inputs.agentId);
8520
+ const sessionMessages = chunkU7PRI3XM_cjs.getSessionMessages(args.inputs.agentId);
8107
8521
  const projectMcpServers = args.inputs.settingSourcesIncludeProject ? await readProjectMcpServers(args.inputs.workspaceCwd) : {};
8108
8522
  return createLocalRun({
8109
8523
  agentId: args.inputs.agentId,
@@ -8122,7 +8536,7 @@ async function createFixtureRunHelper(args) {
8122
8536
  }
8123
8537
  async function dispatchLocalRun(args) {
8124
8538
  const apiKey = chunkRNXXYF22_cjs.resolveApiKey(args.inputs.options.apiKey);
8125
- if (chunk4UYHP6NF_cjs.shouldUseRealLocalRuntime(apiKey)) {
8539
+ if (chunkDJKGDLYZ_cjs.shouldUseRealLocalRuntime(apiKey)) {
8126
8540
  return createRealLocalRun(
8127
8541
  buildRealRunOptions({
8128
8542
  inputs: args.inputs,
@@ -8131,6 +8545,7 @@ async function dispatchLocalRun(args) {
8131
8545
  systemPrompt: args.systemPrompt,
8132
8546
  priorMessages: args.priorMessages,
8133
8547
  memoryTools: args.memoryTools,
8548
+ ...args.steerQueue !== void 0 ? { steerQueue: args.steerQueue } : {},
8134
8549
  ...args.activePreset?.tools !== void 0 ? { personalityToolWhitelist: args.activePreset.tools } : {},
8135
8550
  ...args.activePreset !== void 0 ? { personalityName: args.activePreset.name } : {}
8136
8551
  })
@@ -8183,177 +8598,6 @@ async function consumePending(agentId, pending, clear, refresh) {
8183
8598
  await applyDeferredInvalidation(agentId, pending, refresh);
8184
8599
  }
8185
8600
 
8186
- // src/internal/runtime/registry/live-agent-registry.ts
8187
- var DEFAULT_MAX_AGENTS = 100;
8188
- var DEFAULT_IDLE_TIMEOUT_MS = 30 * 60 * 1e3;
8189
- var DEFAULT_SWEEP_INTERVAL_MS = 6e4;
8190
- var LiveAgentRegistry = class {
8191
- #agents = /* @__PURE__ */ new Map();
8192
- #maxAgents = DEFAULT_MAX_AGENTS;
8193
- #idleTimeoutMs = DEFAULT_IDLE_TIMEOUT_MS;
8194
- #sweepIntervalMs = DEFAULT_SWEEP_INTERVAL_MS;
8195
- #onEvict;
8196
- #sweepTimer;
8197
- /**
8198
- * Reconfigure registry behavior. Process-wide singleton (D310) — last
8199
- * configure call wins for all subsequent operations.
8200
- */
8201
- configure(opts) {
8202
- if (opts.maxAgents !== void 0) this.#maxAgents = Math.max(0, opts.maxAgents);
8203
- if (opts.idleTimeoutMs !== void 0) this.#idleTimeoutMs = Math.max(0, opts.idleTimeoutMs);
8204
- if (opts.sweepIntervalMs !== void 0)
8205
- this.#sweepIntervalMs = Math.max(1e3, opts.sweepIntervalMs);
8206
- this.#onEvict = opts.onEvict;
8207
- this.#stopSweep();
8208
- if (this.#idleTimeoutMs > 0) this.#startSweep();
8209
- }
8210
- /**
8211
- * Lookup a cached agent. `get` is a use — refreshes `lastUsedAt` so the
8212
- * entry survives LRU eviction.
8213
- */
8214
- get(id) {
8215
- const entry = this.#agents.get(id);
8216
- if (entry === void 0) return void 0;
8217
- entry.lastUsedAt = Date.now();
8218
- return entry.agent;
8219
- }
8220
- /**
8221
- * Insert or overwrite an agent in the cache. Triggers fire-and-forget LRU
8222
- * eviction when `size > maxAgents`.
8223
- *
8224
- * EC-4: when `id` already maps to a DIFFERENT agent instance, dispose the
8225
- * old one before overwriting (race protection against two `getOrCreate`
8226
- * calls creating two agents but only the second being cached — the first
8227
- * would leak file handles + lifecycle controllers).
8228
- */
8229
- set(id, agent) {
8230
- if (this.#maxAgents === 0) return;
8231
- const existing = this.#agents.get(id);
8232
- if (existing !== void 0 && existing.agent !== agent) {
8233
- void existing.agent.dispose().catch(() => {
8234
- chunkRNXXYF22_cjs.diag(`[theokit-sdk] dispose during overwrite failed (${id})
8235
- `);
8236
- });
8237
- }
8238
- this.#agents.set(id, { agent, lastUsedAt: Date.now() });
8239
- if (this.#agents.size > this.#maxAgents) void this.#evictLRU();
8240
- }
8241
- /**
8242
- * Remove the entry from the cache WITHOUT calling `dispose()` or
8243
- * `onEvict`. Used by `LocalAgent.dispose()` itself so the disposed
8244
- * instance can never be returned by a subsequent `get(id)` (dispose-cache
8245
- * race fix). Idempotent — calling on an unknown id is a no-op.
8246
- *
8247
- * @internal
8248
- */
8249
- forget(id) {
8250
- this.#agents.delete(id);
8251
- }
8252
- /**
8253
- * Explicitly evict an agent by id. Returns `true` when the entry was
8254
- * present (false = already gone). Calls `agent.dispose()` + `onEvict`
8255
- * with reason `"explicit"`.
8256
- */
8257
- async evict(id) {
8258
- const entry = this.#agents.get(id);
8259
- if (entry === void 0) return false;
8260
- this.#agents.delete(id);
8261
- await this.#disposeAndNotify(id, entry.agent, "explicit");
8262
- return true;
8263
- }
8264
- /**
8265
- * Evict every cached agent. Used by graceful shutdown (`process.on('SIGTERM')`)
8266
- * or end-of-test cleanup.
8267
- */
8268
- async evictAll() {
8269
- const entries = Array.from(this.#agents.entries());
8270
- this.#agents.clear();
8271
- this.#stopSweep();
8272
- for (const [id, entry] of entries) {
8273
- await this.#disposeAndNotify(id, entry.agent, "explicit");
8274
- }
8275
- }
8276
- /** Number of currently cached agents. */
8277
- size() {
8278
- return this.#agents.size;
8279
- }
8280
- /** Ids of cached agents, newest first (by lastUsedAt). */
8281
- ids() {
8282
- return Array.from(this.#agents.entries()).sort((a, b) => b[1].lastUsedAt - a[1].lastUsedAt).map(([id]) => id);
8283
- }
8284
- /**
8285
- * LRU eviction: drop the entry with the smallest `lastUsedAt`. Runs only
8286
- * when `size > maxAgents`. Asynchronous because `dispose()` is a Promise;
8287
- * the hot-path caller (`set`) does not await.
8288
- *
8289
- * @internal
8290
- */
8291
- async #evictLRU() {
8292
- if (this.#agents.size <= this.#maxAgents) return;
8293
- let oldestId;
8294
- let oldestAt = Infinity;
8295
- for (const [id, entry2] of this.#agents) {
8296
- if (entry2.lastUsedAt < oldestAt) {
8297
- oldestAt = entry2.lastUsedAt;
8298
- oldestId = id;
8299
- }
8300
- }
8301
- if (oldestId === void 0) return;
8302
- const entry = this.#agents.get(oldestId);
8303
- if (entry === void 0) return;
8304
- this.#agents.delete(oldestId);
8305
- await this.#disposeAndNotify(oldestId, entry.agent, "lru");
8306
- }
8307
- /** Background sweep — drops entries whose `lastUsedAt < now - idleTimeoutMs`. */
8308
- async #sweepIdle() {
8309
- if (this.#idleTimeoutMs === 0) return;
8310
- const threshold = Date.now() - this.#idleTimeoutMs;
8311
- const toEvict = [];
8312
- for (const [id, entry] of this.#agents) {
8313
- if (entry.lastUsedAt < threshold) toEvict.push([id, entry]);
8314
- }
8315
- for (const [id, entry] of toEvict) {
8316
- const current = this.#agents.get(id);
8317
- if (current === void 0 || current.agent !== entry.agent) continue;
8318
- this.#agents.delete(id);
8319
- await this.#disposeAndNotify(id, entry.agent, "idle");
8320
- }
8321
- }
8322
- #startSweep() {
8323
- this.#sweepTimer = setInterval(() => void this.#sweepIdle(), this.#sweepIntervalMs);
8324
- this.#sweepTimer.unref?.();
8325
- }
8326
- #stopSweep() {
8327
- if (this.#sweepTimer !== void 0) {
8328
- clearInterval(this.#sweepTimer);
8329
- this.#sweepTimer = void 0;
8330
- }
8331
- }
8332
- /** Dispose + notify with errors swallowed (D309). Single chokepoint. */
8333
- async #disposeAndNotify(id, agent, reason) {
8334
- try {
8335
- await agent.dispose();
8336
- } catch (cause) {
8337
- const msg = cause instanceof Error ? cause.message : String(cause);
8338
- chunkRNXXYF22_cjs.diag(`[theokit-sdk] dispose during eviction failed (${id}): ${msg}
8339
- `);
8340
- }
8341
- if (this.#onEvict !== void 0) {
8342
- try {
8343
- this.#onEvict(id, reason);
8344
- } catch (cause) {
8345
- const msg = cause instanceof Error ? cause.message : String(cause);
8346
- chunkRNXXYF22_cjs.diag(`[theokit-sdk] onEvict listener threw (${id}): ${msg}
8347
- `);
8348
- }
8349
- }
8350
- }
8351
- };
8352
- var liveAgentRegistry = chunkNVXXWAU7_cjs.globalSingleton(
8353
- "theokit-sdk.runtime.live-agents",
8354
- () => new LiveAgentRegistry()
8355
- );
8356
-
8357
8601
  // src/internal/local-agent/local-agent-lifecycle.ts
8358
8602
  async function acquireLeaseIfPossible(store, agentId) {
8359
8603
  if (typeof store.acquire !== "function") return;
@@ -8376,18 +8620,18 @@ async function disposeSessionStore(store) {
8376
8620
  async function disposeLocalAgentSession(agent) {
8377
8621
  liveAgentRegistry.forget(agent.agentId);
8378
8622
  agent.lifecycleAbortController.abort();
8379
- await chunkZF2LDKQQ_cjs.withCwdMutex(`agent-send:${agent.agentId}`, () => Promise.resolve());
8623
+ await chunkU3DW3WDE_cjs.withCwdMutex(`agent-send:${agent.agentId}`, () => Promise.resolve());
8380
8624
  disposeSessionMcpClients(agent.agentId);
8381
- await chunkDVP3YMDA_cjs.flushSessionWrites();
8625
+ await chunkU7PRI3XM_cjs.flushSessionWrites();
8382
8626
  await flushRegistrySaves(agent.workspaceCwd);
8383
8627
  await disposeSessionStore(agent.sessionStore);
8384
- chunkDVP3YMDA_cjs.discardSession(agent.workspaceCwd, agent.agentId);
8628
+ chunkU7PRI3XM_cjs.discardSession(agent.workspaceCwd, agent.agentId);
8385
8629
  }
8386
8630
  async function reloadLocalAgent(agent) {
8387
8631
  if (agent.context !== void 0) await agent.context.refresh();
8388
8632
  if (agent.skillsManager !== void 0) await agent.skillsManager.refresh();
8389
8633
  if (agent.pluginsManager !== void 0) await agent.pluginsManager.refresh();
8390
- return await chunkWDVG5R2Q_cjs.loadSubagents(
8634
+ return await chunkAUH2EVWY_cjs.loadSubagents(
8391
8635
  agent.workspaceCwd,
8392
8636
  agent.settingSourcesIncludeProject,
8393
8637
  agent.options.agents
@@ -8633,7 +8877,7 @@ async function finalize(args, queryMode, result) {
8633
8877
  };
8634
8878
  args.cache?.set(args.userText, queryMode, result, tenantCtx);
8635
8879
  if (args.persistTranscripts === true && args.cwd !== void 0) {
8636
- await chunkRS7YQR4X_cjs.persistActiveMemoryTranscript(args.memoryRoot ?? chunkSDZ4XDWS_cjs.resolveMemoryRoot(args.cwd), {
8880
+ await chunkRS7YQR4X_cjs.persistActiveMemoryTranscript(args.memoryRoot ?? chunkVWYFGE27_cjs.resolveMemoryRoot(args.cwd), {
8637
8881
  runId: args.runId ?? `run-${Date.now()}`,
8638
8882
  startedAtMs: Date.now() - result.durationMs,
8639
8883
  userText: args.userText,
@@ -8736,7 +8980,7 @@ var openAiMemoryEmbeddingProviderAdapter = {
8736
8980
  transport: "remote",
8737
8981
  authProviderId: "openai",
8738
8982
  autoSelectPriority: 20,
8739
- create: (options) => chunkCGH4BCIY_cjs.createOpenAiCompatibleRuntime(
8983
+ create: (options) => chunkXE3CAY6Z_cjs.createOpenAiCompatibleRuntime(
8740
8984
  {
8741
8985
  id: "openai",
8742
8986
  defaultBaseUrl: "https://api.openai.com",
@@ -8758,7 +9002,7 @@ var azureOpenAiMemoryEmbeddingProviderAdapter = {
8758
9002
  transport: "remote",
8759
9003
  authProviderId: "azure-openai",
8760
9004
  autoSelectPriority: 25,
8761
- create: (options) => chunkCGH4BCIY_cjs.createOpenAiCompatibleRuntime(
9005
+ create: (options) => chunkXE3CAY6Z_cjs.createOpenAiCompatibleRuntime(
8762
9006
  {
8763
9007
  id: "azure-openai",
8764
9008
  defaultBaseUrl: "https://your-resource.openai.azure.com",
@@ -8794,7 +9038,7 @@ var cohereMemoryEmbeddingProviderAdapter = {
8794
9038
  transport: "remote",
8795
9039
  authProviderId: "cohere",
8796
9040
  autoSelectPriority: 30,
8797
- create: (options) => chunkCGH4BCIY_cjs.createOpenAiCompatibleRuntime(
9041
+ create: (options) => chunkXE3CAY6Z_cjs.createOpenAiCompatibleRuntime(
8798
9042
  {
8799
9043
  id: "cohere",
8800
9044
  defaultBaseUrl: "https://api.cohere.com",
@@ -8840,7 +9084,7 @@ var deepinfraMemoryEmbeddingProviderAdapter = {
8840
9084
  transport: "remote",
8841
9085
  authProviderId: "deepinfra",
8842
9086
  autoSelectPriority: 13,
8843
- create: (options) => chunkCGH4BCIY_cjs.createOpenAiCompatibleRuntime(
9087
+ create: (options) => chunkXE3CAY6Z_cjs.createOpenAiCompatibleRuntime(
8844
9088
  {
8845
9089
  id: "deepinfra",
8846
9090
  defaultBaseUrl: "https://api.deepinfra.com",
@@ -8866,7 +9110,7 @@ var geminiMemoryEmbeddingProviderAdapter = {
8866
9110
  transport: "remote",
8867
9111
  authProviderId: "gemini",
8868
9112
  autoSelectPriority: 30,
8869
- create: (options) => chunkCGH4BCIY_cjs.createOpenAiCompatibleRuntime(
9113
+ create: (options) => chunkXE3CAY6Z_cjs.createOpenAiCompatibleRuntime(
8870
9114
  {
8871
9115
  id: "gemini",
8872
9116
  defaultBaseUrl: "https://generativelanguage.googleapis.com",
@@ -8894,7 +9138,7 @@ var jinaMemoryEmbeddingProviderAdapter = {
8894
9138
  transport: "remote",
8895
9139
  authProviderId: "jina",
8896
9140
  autoSelectPriority: 35,
8897
- create: (options) => chunkCGH4BCIY_cjs.createOpenAiCompatibleRuntime(
9141
+ create: (options) => chunkXE3CAY6Z_cjs.createOpenAiCompatibleRuntime(
8898
9142
  {
8899
9143
  id: "jina",
8900
9144
  defaultBaseUrl: "https://api.jina.ai",
@@ -8917,7 +9161,7 @@ var mistralMemoryEmbeddingProviderAdapter = {
8917
9161
  transport: "remote",
8918
9162
  authProviderId: "mistral",
8919
9163
  autoSelectPriority: 18,
8920
- create: (options) => chunkCGH4BCIY_cjs.createOpenAiCompatibleRuntime(
9164
+ create: (options) => chunkXE3CAY6Z_cjs.createOpenAiCompatibleRuntime(
8921
9165
  {
8922
9166
  id: "mistral",
8923
9167
  defaultBaseUrl: "https://api.mistral.ai",
@@ -8959,7 +9203,7 @@ var ollamaMemoryEmbeddingProviderAdapter = {
8959
9203
  autoSelectPriority: 10,
8960
9204
  create: (options) => {
8961
9205
  const apiKey = options.apiKey ?? process.env.OLLAMA_API_KEY ?? OLLAMA_LOCAL_SENTINEL_KEY;
8962
- return chunkCGH4BCIY_cjs.createOpenAiCompatibleRuntime(
9206
+ return chunkXE3CAY6Z_cjs.createOpenAiCompatibleRuntime(
8963
9207
  {
8964
9208
  id: "ollama",
8965
9209
  defaultBaseUrl: "http://localhost:11434",
@@ -8987,7 +9231,7 @@ var openRouterMemoryEmbeddingProviderAdapter = {
8987
9231
  transport: "remote",
8988
9232
  authProviderId: "openrouter",
8989
9233
  autoSelectPriority: 15,
8990
- create: (options) => chunkCGH4BCIY_cjs.createOpenAiCompatibleRuntime(
9234
+ create: (options) => chunkXE3CAY6Z_cjs.createOpenAiCompatibleRuntime(
8991
9235
  {
8992
9236
  id: "openrouter",
8993
9237
  defaultBaseUrl: "https://openrouter.ai/api",
@@ -9015,7 +9259,7 @@ var voyageMemoryEmbeddingProviderAdapter = {
9015
9259
  transport: "remote",
9016
9260
  authProviderId: "voyage",
9017
9261
  autoSelectPriority: 14,
9018
- create: (options) => chunkCGH4BCIY_cjs.createOpenAiCompatibleRuntime(
9262
+ create: (options) => chunkXE3CAY6Z_cjs.createOpenAiCompatibleRuntime(
9019
9263
  {
9020
9264
  id: "voyage",
9021
9265
  defaultBaseUrl: "https://api.voyageai.com",
@@ -9224,7 +9468,7 @@ var LocalAgentMemory = class {
9224
9468
  const openOpts = { cwd: this.workspaceCwd, memoryRoot };
9225
9469
  if (embedding !== void 0) openOpts.embedding = embedding;
9226
9470
  if (cfg?.backend !== void 0) openOpts.backend = cfg.backend;
9227
- this.index = await chunkCWQPQTUZ_cjs.IndexManager.open(openOpts);
9471
+ this.index = await chunkNEH3BPFD_cjs.IndexManager.open(openOpts);
9228
9472
  await this.index.sync();
9229
9473
  this.toolsCache = [
9230
9474
  createMemorySearchTool({ index: this.index }),
@@ -9245,7 +9489,7 @@ var LocalAgentMemory = class {
9245
9489
  async runActiveMemoryIfEnabled(userText, priorMessages, telemetry) {
9246
9490
  const cfg = this.options.memory?.activeRecall;
9247
9491
  if (cfg?.enabled !== true || this.index === void 0) return void 0;
9248
- if (this.breaker === void 0) this.breaker = new chunk4UYHP6NF_cjs.CircuitBreaker();
9492
+ if (this.breaker === void 0) this.breaker = new chunkDJKGDLYZ_cjs.CircuitBreaker();
9249
9493
  if (this.cache === void 0) this.cache = new ActiveMemoryCache();
9250
9494
  const result = await runActiveMemory({
9251
9495
  userText,
@@ -9268,7 +9512,7 @@ var LocalAgentMemory = class {
9268
9512
  * and the active-memory transcript writer. Three separate resolutions is how they drifted (#463).
9269
9513
  */
9270
9514
  memoryRoot() {
9271
- this.memoryRootCache ??= chunkSDZ4XDWS_cjs.resolveMemoryRoot(this.workspaceCwd, this.options.memory);
9515
+ this.memoryRootCache ??= chunkVWYFGE27_cjs.resolveMemoryRoot(this.workspaceCwd, this.options.memory);
9272
9516
  return this.memoryRootCache;
9273
9517
  }
9274
9518
  buildActiveMemoryOptions(cfg) {
@@ -9383,7 +9627,7 @@ function createLocalAgentMemoryProvider(opts) {
9383
9627
  return { facts: [], systemPromptAdditions: summary };
9384
9628
  },
9385
9629
  async recordSessionSummary(args) {
9386
- await chunkSDZ4XDWS_cjs.writeSessionSummary(args);
9630
+ await chunkVWYFGE27_cjs.writeSessionSummary(args);
9387
9631
  },
9388
9632
  async sync(handle) {
9389
9633
  const state = handle[INTERNAL_LAM_KEY];
@@ -9551,7 +9795,7 @@ async function localAgentUsePersonality(agent, name, opts) {
9551
9795
  agent.personalityRegistry = await PersonalityRegistry.load(agent.workspaceCwd);
9552
9796
  }
9553
9797
  const registry = agent.personalityRegistry;
9554
- return chunkZF2LDKQQ_cjs.withCwdMutex(
9798
+ return chunkU3DW3WDE_cjs.withCwdMutex(
9555
9799
  `agent-send:${agent.agentId}`,
9556
9800
  () => performPersonalitySwitch({
9557
9801
  agentId: agent.agentId,
@@ -9560,8 +9804,8 @@ async function localAgentUsePersonality(agent, name, opts) {
9560
9804
  registry,
9561
9805
  store: agent.personalityStore,
9562
9806
  invalidateCache: (reason) => agent.invalidateCache(reason),
9563
- appendSessionMessage: (msg) => chunkDVP3YMDA_cjs.appendSessionMessage(agent.agentId, msg),
9564
- clearSession: () => chunkDVP3YMDA_cjs.clearSession(agent.agentId),
9807
+ appendSessionMessage: (msg) => chunkU7PRI3XM_cjs.appendSessionMessage(agent.agentId, msg),
9808
+ clearSession: () => chunkU7PRI3XM_cjs.clearSession(agent.agentId),
9565
9809
  opts: opts ?? {}
9566
9810
  })
9567
9811
  );
@@ -10072,6 +10316,14 @@ async function applyInputProcessors(inputs, message, rawUserText, options, sendM
10072
10316
  const effectiveMessage = typeof message === "string" ? res.value : { ...message, text: res.value };
10073
10317
  return { userText: res.value, effectiveMessage };
10074
10318
  }
10319
+ var lastSendAt = /* @__PURE__ */ new Map();
10320
+ function applyIdleReset(agentId, minutes) {
10321
+ const now = Date.now();
10322
+ const previous = lastSendAt.get(agentId);
10323
+ lastSendAt.set(agentId, now);
10324
+ if (minutes === void 0 || !Number.isFinite(minutes) || minutes <= 0) return;
10325
+ if (previous !== void 0 && now - previous > minutes * 6e4) chunkU7PRI3XM_cjs.clearSession(agentId);
10326
+ }
10075
10327
  async function executeSendLocked(inputs, message, options) {
10076
10328
  if (inputs.disposed) throw new chunkCEGU5AVD_cjs.AgentDisposedError(inputs.agentId);
10077
10329
  await consumePending(
@@ -10086,10 +10338,11 @@ async function executeSendLocked(inputs, message, options) {
10086
10338
  const gated = await applyInputProcessors(inputs, message, rawUserText, options, sendModel);
10087
10339
  if ("tripwireRun" in gated) return gated.tripwireRun;
10088
10340
  const { userText, effectiveMessage } = gated;
10341
+ applyIdleReset(inputs.agentId, inputs.options.sessionIdleResetMinutes);
10089
10342
  if (inputs.options.onBeforeSend !== void 0) {
10090
10343
  await inputs.options.onBeforeSend({
10091
10344
  conversationId: inputs.agentId,
10092
- previousMessageCount: chunkDVP3YMDA_cjs.getSessionMessages(inputs.agentId).length
10345
+ previousMessageCount: chunkU7PRI3XM_cjs.getSessionMessages(inputs.agentId).length
10093
10346
  });
10094
10347
  }
10095
10348
  await inputs.runPreHook(userText);
@@ -10101,8 +10354,8 @@ async function executeSendLocked(inputs, message, options) {
10101
10354
  userText,
10102
10355
  sendOptions: options
10103
10356
  });
10104
- const priorMessages = [...chunkDVP3YMDA_cjs.getSessionMessages(inputs.agentId)];
10105
- chunkDVP3YMDA_cjs.appendSessionMessage(inputs.agentId, { role: "user", text: userText });
10357
+ const priorMessages = [...chunkU7PRI3XM_cjs.getSessionMessages(inputs.agentId)];
10358
+ chunkU7PRI3XM_cjs.appendSessionMessage(inputs.agentId, { role: "user", text: userText });
10106
10359
  await persistMemoryFactIfWritePrompt(inputs.workspaceCwd, inputs.options.memory, userText);
10107
10360
  const memoryFacts = await readMemoryForSend(inputs.workspaceCwd, inputs.options.memory, userText);
10108
10361
  const memoryTools = void 0;
@@ -10271,6 +10524,43 @@ function reportUnknownLocalOptions(local) {
10271
10524
  }
10272
10525
  }
10273
10526
 
10527
+ // src/internal/local-agent/send-queue.ts
10528
+ var TurnSteerQueue = class {
10529
+ pending = [];
10530
+ closed = false;
10531
+ /** @returns false when the turn can no longer pick the message up. */
10532
+ push(text) {
10533
+ if (this.closed) return false;
10534
+ this.pending.push(text);
10535
+ return true;
10536
+ }
10537
+ drain() {
10538
+ const taken = this.pending;
10539
+ this.pending = [];
10540
+ return taken;
10541
+ }
10542
+ drainOrClose() {
10543
+ const taken = this.drain();
10544
+ if (taken.length === 0) this.closed = true;
10545
+ return taken;
10546
+ }
10547
+ /** Stop accepting and hand back what no loop iteration picked up. */
10548
+ closeAndTake() {
10549
+ this.closed = true;
10550
+ return this.drain();
10551
+ }
10552
+ };
10553
+ function joinCollected(messages) {
10554
+ if (messages.length === 1) return messages[0];
10555
+ const texts = messages.map((m) => typeof m === "string" ? m : m.text);
10556
+ const images = messages.flatMap((m) => typeof m === "string" ? [] : m.images ?? []);
10557
+ const text = texts.join("\n\n");
10558
+ return images.length > 0 ? { text, images } : text;
10559
+ }
10560
+ function hasImages(message) {
10561
+ return typeof message !== "string" && (message.images?.length ?? 0) > 0;
10562
+ }
10563
+
10274
10564
  // src/internal/local-agent/local-agent.ts
10275
10565
  var LocalAgent = class {
10276
10566
  /**
@@ -10319,6 +10609,9 @@ var LocalAgent = class {
10319
10609
  settingSourcesIncludePlugins;
10320
10610
  resolvedSubagents = {};
10321
10611
  disposed = false;
10612
+ activeTurn;
10613
+ inflight = 0;
10614
+ collectBatch;
10322
10615
  invalidationPending;
10323
10616
  skillsManager;
10324
10617
  pluginsManager;
@@ -10355,7 +10648,7 @@ var LocalAgent = class {
10355
10648
  this.options = options;
10356
10649
  this.workspaceCwd = resolveCwd(options.local?.cwd);
10357
10650
  this.transcriptBaseDir = resolveSessionDir(options.local);
10358
- this.sessionStore = options.local?.sessionStore ?? new chunk6OCJWGVD_cjs.FsSessionStore({ baseDir: this.transcriptBaseDir, cwd: this.workspaceCwd });
10651
+ this.sessionStore = options.local?.sessionStore ?? new chunkFTXY4D44_cjs.FsSessionStore({ baseDir: this.transcriptBaseDir, cwd: this.workspaceCwd });
10359
10652
  this.settingSourcesIncludeProject = includesSetting(options, "project");
10360
10653
  this.settingSourcesIncludePlugins = includesSetting(options, "plugins");
10361
10654
  const sub = bootstrapSubmanagers({
@@ -10407,7 +10700,7 @@ var LocalAgent = class {
10407
10700
  const codePlugins = chunkBV2MWEMV_cjs.extractCodePlugins(this.options.plugins);
10408
10701
  const manifestPlugins = await this.importManifestPlugins();
10409
10702
  await this.pluginManagerCode.initialize([...codePlugins, ...manifestPlugins]);
10410
- this.resolvedSubagents = await chunkWDVG5R2Q_cjs.loadSubagents(
10703
+ this.resolvedSubagents = await chunkAUH2EVWY_cjs.loadSubagents(
10411
10704
  this.workspaceCwd,
10412
10705
  this.settingSourcesIncludeProject,
10413
10706
  this.options.agents,
@@ -10415,7 +10708,7 @@ var LocalAgent = class {
10415
10708
  );
10416
10709
  await acquireLeaseIfPossible(this.sessionStore, this.agentId);
10417
10710
  try {
10418
- await chunkDVP3YMDA_cjs.hydrateSession(this.agentId, { store: this.sessionStore, cwd: this.workspaceCwd });
10711
+ await chunkU7PRI3XM_cjs.hydrateSession(this.agentId, { store: this.sessionStore, cwd: this.workspaceCwd });
10419
10712
  await this.personalityStore.hydrate(this.agentId);
10420
10713
  } catch (err) {
10421
10714
  await releaseLeaseIfPossible(this.sessionStore, this.agentId);
@@ -10443,10 +10736,48 @@ var LocalAgent = class {
10443
10736
  agentId: this.agentId,
10444
10737
  ...this.model?.id !== void 0 ? { model: this.model.id } : {}
10445
10738
  });
10739
+ return this.enqueueSend(message, options, sendSpan);
10740
+ }
10741
+ /** Queue one send behind the lock, or fold it into the running turn / pending batch. */
10742
+ enqueueSend(message, options, sendSpan) {
10743
+ const mode = options.queueMode ?? "followup";
10744
+ const text = typeof message === "string" ? message : message.text;
10745
+ const active = this.activeTurn;
10746
+ if (mode === "steer" && active !== void 0 && !hasImages(message) && active.steer.push(text)) {
10747
+ sendSpan.end();
10748
+ return active.run;
10749
+ }
10750
+ if (mode === "collect" && this.collectBatch !== void 0) {
10751
+ this.collectBatch.messages.push(message);
10752
+ sendSpan.end();
10753
+ return this.collectBatch.run;
10754
+ }
10755
+ const key = `agent-send:${this.agentId}`;
10756
+ this.inflight += 1;
10757
+ const release = () => {
10758
+ this.inflight -= 1;
10759
+ };
10760
+ if (mode === "collect" && this.inflight > 1) {
10761
+ const messages = [message];
10762
+ const run = new Promise((resolve, reject) => {
10763
+ void chunkU3DW3WDE_cjs.withCwdMutex(key, () => {
10764
+ this.collectBatch = void 0;
10765
+ return this.runLockedSendCycle(
10766
+ joinCollected(messages),
10767
+ options,
10768
+ sendSpan,
10769
+ resolve,
10770
+ reject
10771
+ ).finally(release);
10772
+ });
10773
+ });
10774
+ this.collectBatch = { messages, run };
10775
+ return run;
10776
+ }
10446
10777
  return new Promise((resolve, reject) => {
10447
- void chunkZF2LDKQQ_cjs.withCwdMutex(
10448
- `agent-send:${this.agentId}`,
10449
- () => this.runLockedSendCycle(message, options, sendSpan, resolve, reject)
10778
+ void chunkU3DW3WDE_cjs.withCwdMutex(
10779
+ key,
10780
+ () => this.runLockedSendCycle(message, options, sendSpan, resolve, reject).finally(release)
10450
10781
  );
10451
10782
  });
10452
10783
  }
@@ -10462,20 +10793,40 @@ var LocalAgent = class {
10462
10793
  const declared = this.model?.contextWindow;
10463
10794
  return declared !== void 0 ? { contextWindow: declared } : {};
10464
10795
  }
10796
+ /** A steered message the loop never picked up (run errored, was cancelled) still gets answered. */
10797
+ followUpUnsteered(leftover) {
10798
+ if (leftover.length === 0) return;
10799
+ this.send(leftover.join("\n\n")).catch(
10800
+ (err) => chunkRNXXYF22_cjs.diagFailure(`[theokit-sdk] steered message followup failed: ${String(err)}`)
10801
+ );
10802
+ }
10465
10803
  async runLockedSendCycle(message, options, sendSpan, resolve, reject) {
10466
10804
  const userText = typeof message === "string" ? message : message.text;
10467
10805
  let run;
10806
+ const steer = new TurnSteerQueue();
10807
+ let res = () => void 0;
10808
+ let rej = () => void 0;
10809
+ const turnRun = new Promise((a, b) => {
10810
+ res = a;
10811
+ rej = b;
10812
+ });
10813
+ turnRun.catch(() => void 0);
10814
+ this.activeTurn = { steer, run: turnRun };
10468
10815
  try {
10469
10816
  run = await this.sendLocked(message, options);
10470
10817
  } catch (err) {
10471
10818
  sendSpan.recordException(err);
10472
10819
  sendSpan.setStatus({ code: 2, message: err instanceof Error ? err.message : String(err) });
10473
10820
  sendSpan.end();
10821
+ this.activeTurn = void 0;
10822
+ rej(err);
10474
10823
  reject(err);
10475
10824
  return;
10476
10825
  }
10477
10826
  if (options.task !== void 0) registerRunAsTask(run, this.agentId, options.task, userText);
10478
- resolve(callerView(run, this.options.throwOnError));
10827
+ const view = callerView(run, this.options.throwOnError);
10828
+ res(view);
10829
+ resolve(view);
10479
10830
  try {
10480
10831
  await runPostRunLifecycle({
10481
10832
  run,
@@ -10499,6 +10850,8 @@ var LocalAgent = class {
10499
10850
  });
10500
10851
  } finally {
10501
10852
  sendSpan.end();
10853
+ this.activeTurn = void 0;
10854
+ this.followUpUnsteered(steer.closeAndTake());
10502
10855
  }
10503
10856
  }
10504
10857
  async sendLocked(message, options) {
@@ -10606,11 +10959,13 @@ var LocalAgent = class {
10606
10959
  memoryFacts,
10607
10960
  priorMessages,
10608
10961
  memoryTools,
10609
- activePreset: this.activePreset()
10962
+ activePreset: this.activePreset(),
10963
+ ...this.activeTurn !== void 0 ? { steerQueue: this.activeTurn.steer } : {}
10610
10964
  });
10611
10965
  }
10612
10966
  close() {
10613
10967
  this.disposed = true;
10968
+ liveAgentRegistry.forget(this.agentId);
10614
10969
  }
10615
10970
  async reload() {
10616
10971
  this.resolvedSubagents = await reloadLocalAgent(this);
@@ -10759,22 +11114,22 @@ async function maybeInjectHandoffTools(options) {
10759
11114
  };
10760
11115
  }
10761
11116
  function keyWillFlowToProvider(apiKey, provider) {
10762
- if (chunk4UYHP6NF_cjs.isFixtureApiKey(apiKey)) return false;
10763
- if (chunk4UYHP6NF_cjs.getConfiguredBaseUrl() !== void 0) return false;
11117
+ if (chunkDJKGDLYZ_cjs.isFixtureApiKey(apiKey)) return false;
11118
+ if (chunkDJKGDLYZ_cjs.getConfiguredBaseUrl() !== void 0) return false;
10764
11119
  if (provider === void 0) return false;
10765
- const profile = chunkLO6LIUZ6_cjs.getProviderProfile(provider);
11120
+ const profile = chunkSPEN7RJU_cjs.getProviderProfile(provider);
10766
11121
  if (profile === void 0) return false;
10767
11122
  return profile.authType !== "none";
10768
11123
  }
10769
11124
  function missingApiKeyMessage() {
10770
- const present = chunk4UYHP6NF_cjs.presentProviderCredentialEnvVars();
11125
+ const present = chunkDJKGDLYZ_cjs.presentProviderCredentialEnvVars();
10771
11126
  const base = `Missing API key \u2014 set ${chunkRNXXYF22_cjs.API_KEY_ENV_VAR}, or pass \`apiKey\` to Agent.create()`;
10772
11127
  if (present.length === 0) return `${base}.`;
10773
11128
  return `${base}. ${present.join(" and ")} ${present.length === 1 ? "is" : "are"} set, but a provider credential is not read from the environment automatically \u2014 pass it explicitly, e.g. \`Agent.create({ apiKey: process.env.${present[0]}, ... })\`.`;
10774
11129
  }
10775
11130
  function providerNeedsCallerKey(provider) {
10776
11131
  if (provider === void 0) return true;
10777
- const profile = chunkLO6LIUZ6_cjs.getProviderProfile(provider);
11132
+ const profile = chunkSPEN7RJU_cjs.getProviderProfile(provider);
10778
11133
  if (profile === void 0) return true;
10779
11134
  return profile.authType === "api_key";
10780
11135
  }
@@ -10787,7 +11142,7 @@ async function createLocalAgent(options) {
10787
11142
  }
10788
11143
  } else {
10789
11144
  const willFlowToProvider = keyWillFlowToProvider(apiKey, provider);
10790
- const shape = chunk4UYHP6NF_cjs.validateApiKeyShape(apiKey, {
11145
+ const shape = chunkDJKGDLYZ_cjs.validateApiKeyShape(apiKey, {
10791
11146
  strict: willFlowToProvider,
10792
11147
  ...willFlowToProvider ? { provider } : {}
10793
11148
  });
@@ -10806,15 +11161,15 @@ async function createCloudAgent(options) {
10806
11161
  code: "missing_api_key"
10807
11162
  });
10808
11163
  }
10809
- const shape = chunk4UYHP6NF_cjs.validateApiKeyShape(apiKey);
11164
+ const shape = chunkDJKGDLYZ_cjs.validateApiKeyShape(apiKey);
10810
11165
  if (shape.malformed) {
10811
11166
  throw new chunkCEGU5AVD_cjs.AuthenticationError(shape.message, { code: "malformed_api_key" });
10812
11167
  }
10813
- const baseUrl = chunk4UYHP6NF_cjs.getConfiguredBaseUrl();
11168
+ const baseUrl = chunkDJKGDLYZ_cjs.getConfiguredBaseUrl();
10814
11169
  if (baseUrl === void 0) {
10815
11170
  return new CloudAgent(options);
10816
11171
  }
10817
- const response = await chunk4UYHP6NF_cjs.httpRequest("/v1/agents", {
11172
+ const response = await chunkDJKGDLYZ_cjs.httpRequest("/v1/agents", {
10818
11173
  apiKey,
10819
11174
  method: "POST",
10820
11175
  body: {
@@ -10839,7 +11194,7 @@ function resolveAgentPersistenceCwd(options) {
10839
11194
  return process.cwd();
10840
11195
  }
10841
11196
  async function rehydrateExistingAgent(agentId, existing, options) {
10842
- await chunk4UYHP6NF_cjs.discoverProviderPlugins();
11197
+ await chunkDJKGDLYZ_cjs.discoverProviderPlugins();
10843
11198
  await validateRehydratedAgent(agentId, existing);
10844
11199
  const mergedLocal = options.local !== void 0 && existing.options.local !== void 0 ? { ...existing.options.local, ...options.local } : options.local ?? existing.options.local;
10845
11200
  const mergedMemory = mergeResumedMemory(existing.options.memory, options.memory);
@@ -10855,7 +11210,7 @@ async function rehydrateExistingAgent(agentId, existing, options) {
10855
11210
  mcpServers: void 0,
10856
11211
  agentId
10857
11212
  };
10858
- chunkSDZ4XDWS_cjs.resolveMaxFacts(mergedOptions.memory?.maxFacts);
11213
+ chunkVWYFGE27_cjs.resolveMaxFacts(mergedOptions.memory?.maxFacts);
10859
11214
  if (existing.runtime === "cloud") {
10860
11215
  return new CloudAgent(mergedOptions, agentId);
10861
11216
  }
@@ -10961,6 +11316,7 @@ function paginateByKey(all, keyOf, limit, cursor, sortByKey) {
10961
11316
 
10962
11317
  // src/agent.ts
10963
11318
  var streamObjectImport;
11319
+ var getOrCreateInFlight = /* @__PURE__ */ new Map();
10964
11320
  var Agent = class _Agent {
10965
11321
  constructor() {
10966
11322
  }
@@ -10999,7 +11355,7 @@ var Agent = class _Agent {
10999
11355
  pluginCount: enabledPluginNames(options.plugins).length
11000
11356
  });
11001
11357
  try {
11002
- await chunk4UYHP6NF_cjs.discoverProviderPlugins();
11358
+ await chunkDJKGDLYZ_cjs.discoverProviderPlugins();
11003
11359
  const agent = await runCreateUnderSpan(options, span);
11004
11360
  return agent;
11005
11361
  } catch (err) {
@@ -11145,7 +11501,7 @@ var Agent = class _Agent {
11145
11501
  * @public
11146
11502
  */
11147
11503
  static async batch(prompts, options) {
11148
- const { batchImpl } = await import('./batch-IZ5EDKJ5.cjs');
11504
+ const { batchImpl } = await import('./batch-VFR2MAUE.cjs');
11149
11505
  return batchImpl(prompts, options, { create: (opts) => _Agent.create(opts) });
11150
11506
  }
11151
11507
  /**
@@ -11175,18 +11531,27 @@ var Agent = class _Agent {
11175
11531
  * The agent-builder's M85 interrupt rotates the session id to work around a
11176
11532
  * constraint that does not exist.
11177
11533
  *
11178
- * - `close()` marks the handle disposed WITHOUT evicting the cache entry. It is
11179
- * internal and unused today; if it becomes reachable, this bullet stops being true
11180
- * for that path.
11534
+ * - `close()` marks the handle disposed AND drops its cache entry, so the next call
11535
+ * builds a fresh handle.
11181
11536
  *
11182
11537
  * @public
11183
11538
  */
11184
11539
  static async getOrCreate(agentId, options) {
11185
11540
  const cached = _Agent.registry.get(agentId);
11186
11541
  if (cached !== void 0) return cached;
11187
- const fresh = await getOrCreateUncached(agentId, options);
11188
- _Agent.registry.set(agentId, fresh);
11189
- return fresh;
11542
+ const inFlight = getOrCreateInFlight.get(agentId);
11543
+ if (inFlight !== void 0) return inFlight;
11544
+ const build = (async () => {
11545
+ const fresh = await getOrCreateUncached(agentId, options);
11546
+ _Agent.registry.set(agentId, fresh);
11547
+ return fresh;
11548
+ })();
11549
+ getOrCreateInFlight.set(agentId, build);
11550
+ try {
11551
+ return await build;
11552
+ } finally {
11553
+ if (getOrCreateInFlight.get(agentId) === build) getOrCreateInFlight.delete(agentId);
11554
+ }
11190
11555
  }
11191
11556
  /**
11192
11557
  * List agents (local or cloud). M107 — `cwd` is READ, not ignored. B-115 (2026-08-19) —
@@ -11297,9 +11662,9 @@ var Agent = class _Agent {
11297
11662
  */
11298
11663
  static async compact(agentId, options = {}) {
11299
11664
  const reg = await requireLocalAgent(agentId, "compact");
11300
- const { compactSessionTranscript, buildDefaultSummarizer: buildDefaultSummarizer2 } = await import('./compact-session-B7P6EU3Z.cjs');
11665
+ const { compactSessionTranscript, buildDefaultSummarizer: buildDefaultSummarizer2 } = await import('./compact-session-NX7HUNTB.cjs');
11301
11666
  const { cwd, model, store } = await openLocalStore(reg);
11302
- return chunkDVP3YMDA_cjs.enqueueSessionWrite(
11667
+ return chunkU7PRI3XM_cjs.enqueueSessionWrite(
11303
11668
  cwd,
11304
11669
  agentId,
11305
11670
  () => compactSessionTranscript({
@@ -11327,7 +11692,7 @@ var Agent = class _Agent {
11327
11692
  */
11328
11693
  static async injectSessionTurn(agentId, turn) {
11329
11694
  const reg = await requireLocalAgent(agentId, "injectSessionTurn");
11330
- const { injectSessionTurn } = await import('./inject-session-WOH7TPDX.cjs');
11695
+ const { injectSessionTurn } = await import('./inject-session-AWKDCGHV.cjs');
11331
11696
  const { cwd, model, store } = await openLocalStore(reg);
11332
11697
  await injectSessionTurn({
11333
11698
  store,
@@ -11378,7 +11743,7 @@ var Agent = class _Agent {
11378
11743
  */
11379
11744
  static async describe(agentId) {
11380
11745
  const agent = await getRegisteredAgentOrThrow(agentId);
11381
- const { loadSubagents: loadSubagents2 } = await import('./subagents-loader-TXOA5EJJ.cjs');
11746
+ const { loadSubagents: loadSubagents2 } = await import('./subagents-loader-KLWF4QPD.cjs');
11382
11747
  const settingSources = agent.options.local?.settingSources;
11383
11748
  const subagents = await loadSubagents2(
11384
11749
  agent.cwd ?? process.cwd(),
@@ -11477,7 +11842,9 @@ async function openLocalStore(reg) {
11477
11842
  const cwd = reg.cwd ?? process.cwd();
11478
11843
  const optModel = reg.options.model;
11479
11844
  const model = reg.model?.id ?? (typeof optModel === "string" ? optModel : optModel?.id) ?? "unknown";
11480
- const { FsSessionStore: FsSessionStore2 } = await import('./fs-session-store-S2AXVJIX.cjs');
11845
+ const injected = reg.options.local?.sessionStore;
11846
+ if (injected !== void 0) return { cwd, model, store: injected };
11847
+ const { FsSessionStore: FsSessionStore2 } = await import('./fs-session-store-CYNTEPJZ.cjs');
11481
11848
  const { defaultBaseDir: defaultBaseDir2, expandTilde: expandTilde2 } = await import('./session-transcript-7TZ6HXSX.cjs');
11482
11849
  const configuredSessionDir = reg.options.local?.sessionDir ?? reg.options.local?.baseDir;
11483
11850
  const baseDir = configuredSessionDir !== void 0 ? expandTilde2(configuredSessionDir) : defaultBaseDir2();
@@ -11498,5 +11865,5 @@ exports.managedSettingsPathFor = managedSettingsPathFor;
11498
11865
  exports.openRouterMemoryEmbeddingProviderAdapter = openRouterMemoryEmbeddingProviderAdapter;
11499
11866
  exports.readManagedSettings = readManagedSettings;
11500
11867
  exports.resolveSessionDir = resolveSessionDir;
11501
- //# sourceMappingURL=chunk-KL7ZUMK3.cjs.map
11502
- //# sourceMappingURL=chunk-KL7ZUMK3.cjs.map
11868
+ //# sourceMappingURL=chunk-64ECM3XM.cjs.map
11869
+ //# sourceMappingURL=chunk-64ECM3XM.cjs.map