@anthropic-ai/sdk 0.96.0 → 0.97.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (570) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/api-promise.d.mts +1 -0
  3. package/api-promise.d.mts.map +1 -1
  4. package/api-promise.d.ts +1 -0
  5. package/api-promise.d.ts.map +1 -1
  6. package/api-promise.mjs +1 -0
  7. package/api-promise.mjs.map +1 -1
  8. package/bin/migration-config.json +222 -0
  9. package/client.d.mts.map +1 -1
  10. package/client.d.ts.map +1 -1
  11. package/client.mjs.map +1 -1
  12. package/core/api-promise.d.mts.map +1 -1
  13. package/core/api-promise.d.ts.map +1 -1
  14. package/core/api-promise.mjs.map +1 -1
  15. package/core/credentials.mjs.map +1 -1
  16. package/core/error.d.mts.map +1 -1
  17. package/core/error.d.ts.map +1 -1
  18. package/core/error.mjs.map +1 -1
  19. package/core/pagination.d.mts.map +1 -1
  20. package/core/pagination.d.ts.map +1 -1
  21. package/core/pagination.mjs.map +1 -1
  22. package/core/resource.d.mts.map +1 -1
  23. package/core/resource.d.ts.map +1 -1
  24. package/core/streaming.d.mts.map +1 -1
  25. package/core/streaming.d.ts.map +1 -1
  26. package/core/streaming.js +2 -0
  27. package/core/streaming.js.map +1 -1
  28. package/core/streaming.mjs +2 -0
  29. package/core/streaming.mjs.map +1 -1
  30. package/core/uploads.d.mts.map +1 -1
  31. package/core/uploads.d.ts.map +1 -1
  32. package/core/uploads.mjs.map +1 -1
  33. package/error.d.mts +1 -0
  34. package/error.d.mts.map +1 -1
  35. package/error.d.ts +1 -0
  36. package/error.d.ts.map +1 -1
  37. package/error.mjs +1 -0
  38. package/error.mjs.map +1 -1
  39. package/helpers/beta/environments.d.mts +22 -0
  40. package/helpers/beta/environments.d.mts.map +1 -0
  41. package/helpers/beta/environments.d.ts +22 -0
  42. package/helpers/beta/environments.d.ts.map +1 -0
  43. package/helpers/beta/environments.js +30 -0
  44. package/helpers/beta/environments.js.map +1 -0
  45. package/helpers/beta/environments.mjs +22 -0
  46. package/helpers/beta/environments.mjs.map +1 -0
  47. package/helpers/beta/json-schema.d.mts +6 -0
  48. package/helpers/beta/json-schema.d.mts.map +1 -1
  49. package/helpers/beta/json-schema.d.ts +6 -0
  50. package/helpers/beta/json-schema.d.ts.map +1 -1
  51. package/helpers/beta/json-schema.js +1 -0
  52. package/helpers/beta/json-schema.js.map +1 -1
  53. package/helpers/beta/json-schema.mjs +1 -0
  54. package/helpers/beta/json-schema.mjs.map +1 -1
  55. package/helpers/beta/mcp.d.mts.map +1 -1
  56. package/helpers/beta/mcp.d.ts.map +1 -1
  57. package/helpers/beta/mcp.mjs.map +1 -1
  58. package/helpers/beta/memory.d.mts.map +1 -1
  59. package/helpers/beta/memory.d.ts.map +1 -1
  60. package/helpers/beta/zod.d.mts +6 -0
  61. package/helpers/beta/zod.d.mts.map +1 -1
  62. package/helpers/beta/zod.d.ts +6 -0
  63. package/helpers/beta/zod.d.ts.map +1 -1
  64. package/helpers/beta/zod.js +1 -0
  65. package/helpers/beta/zod.js.map +1 -1
  66. package/helpers/beta/zod.mjs +1 -0
  67. package/helpers/beta/zod.mjs.map +1 -1
  68. package/helpers/index.d.mts.map +1 -1
  69. package/helpers/index.d.ts.map +1 -1
  70. package/helpers/index.mjs.map +1 -1
  71. package/helpers/json-schema.d.mts.map +1 -1
  72. package/helpers/json-schema.d.ts.map +1 -1
  73. package/helpers/json-schema.mjs.map +1 -1
  74. package/helpers/zod.d.mts.map +1 -1
  75. package/helpers/zod.d.ts.map +1 -1
  76. package/helpers/zod.mjs.map +1 -1
  77. package/index.d.mts.map +1 -1
  78. package/index.d.ts.map +1 -1
  79. package/index.mjs.map +1 -1
  80. package/internal/decoders/jsonl.d.mts.map +1 -1
  81. package/internal/decoders/jsonl.d.ts.map +1 -1
  82. package/internal/decoders/jsonl.mjs.map +1 -1
  83. package/internal/decoders/line.mjs.map +1 -1
  84. package/internal/detect-platform.mjs.map +1 -1
  85. package/internal/headers.mjs.map +1 -1
  86. package/internal/parse.d.mts.map +1 -1
  87. package/internal/parse.d.ts.map +1 -1
  88. package/internal/parse.mjs.map +1 -1
  89. package/internal/qs/formats.d.mts.map +1 -1
  90. package/internal/qs/formats.d.ts.map +1 -1
  91. package/internal/qs/index.d.mts +2 -2
  92. package/internal/qs/index.d.mts.map +1 -1
  93. package/internal/qs/index.d.ts +2 -2
  94. package/internal/qs/index.d.ts.map +1 -1
  95. package/internal/qs/index.mjs.map +1 -1
  96. package/internal/qs/stringify.d.mts.map +1 -1
  97. package/internal/qs/stringify.d.ts.map +1 -1
  98. package/internal/qs/stringify.mjs.map +1 -1
  99. package/internal/qs/utils.d.mts.map +1 -1
  100. package/internal/qs/utils.d.ts.map +1 -1
  101. package/internal/qs/utils.mjs.map +1 -1
  102. package/internal/request-options.d.mts.map +1 -1
  103. package/internal/request-options.d.ts.map +1 -1
  104. package/internal/shims.d.mts +6 -0
  105. package/internal/shims.d.mts.map +1 -1
  106. package/internal/shims.d.ts +6 -0
  107. package/internal/shims.d.ts.map +1 -1
  108. package/internal/to-file.d.mts.map +1 -1
  109. package/internal/to-file.d.ts.map +1 -1
  110. package/internal/to-file.mjs.map +1 -1
  111. package/internal/types.d.mts +4 -4
  112. package/internal/types.d.mts.map +1 -1
  113. package/internal/types.d.ts +4 -4
  114. package/internal/types.d.ts.map +1 -1
  115. package/internal/uploads.d.mts.map +1 -1
  116. package/internal/uploads.d.ts.map +1 -1
  117. package/internal/uploads.mjs.map +1 -1
  118. package/internal/utils/abort.d.mts +13 -0
  119. package/internal/utils/abort.d.mts.map +1 -0
  120. package/internal/utils/abort.d.ts +13 -0
  121. package/internal/utils/abort.d.ts.map +1 -0
  122. package/internal/utils/abort.js +26 -0
  123. package/internal/utils/abort.js.map +1 -0
  124. package/internal/utils/abort.mjs +23 -0
  125. package/internal/utils/abort.mjs.map +1 -0
  126. package/internal/utils/async-queue.d.mts +31 -0
  127. package/internal/utils/async-queue.d.mts.map +1 -0
  128. package/internal/utils/async-queue.d.ts +31 -0
  129. package/internal/utils/async-queue.d.ts.map +1 -0
  130. package/internal/utils/async-queue.js +75 -0
  131. package/internal/utils/async-queue.js.map +1 -0
  132. package/internal/utils/async-queue.mjs +71 -0
  133. package/internal/utils/async-queue.mjs.map +1 -0
  134. package/internal/utils/backoff.d.mts +23 -0
  135. package/internal/utils/backoff.d.mts.map +1 -0
  136. package/internal/utils/backoff.d.ts +23 -0
  137. package/internal/utils/backoff.d.ts.map +1 -0
  138. package/internal/utils/backoff.js +44 -0
  139. package/internal/utils/backoff.js.map +1 -0
  140. package/internal/utils/backoff.mjs +36 -0
  141. package/internal/utils/backoff.mjs.map +1 -0
  142. package/internal/utils/base64.mjs.map +1 -1
  143. package/internal/utils/log.d.mts.map +1 -1
  144. package/internal/utils/log.d.ts.map +1 -1
  145. package/internal/utils/log.mjs.map +1 -1
  146. package/internal/utils/path.mjs.map +1 -1
  147. package/internal/utils/promise.d.mts +11 -0
  148. package/internal/utils/promise.d.mts.map +1 -0
  149. package/internal/utils/promise.d.ts +11 -0
  150. package/internal/utils/promise.d.ts.map +1 -0
  151. package/internal/utils/promise.js +18 -0
  152. package/internal/utils/promise.js.map +1 -0
  153. package/internal/utils/promise.mjs +15 -0
  154. package/internal/utils/promise.mjs.map +1 -0
  155. package/internal/utils/query.mjs.map +1 -1
  156. package/internal/utils/sleep.d.mts +9 -1
  157. package/internal/utils/sleep.d.mts.map +1 -1
  158. package/internal/utils/sleep.d.ts +9 -1
  159. package/internal/utils/sleep.d.ts.map +1 -1
  160. package/internal/utils/sleep.js +23 -2
  161. package/internal/utils/sleep.js.map +1 -1
  162. package/internal/utils/sleep.mjs +23 -2
  163. package/internal/utils/sleep.mjs.map +1 -1
  164. package/internal/utils/values.mjs.map +1 -1
  165. package/internal/utils.d.mts.map +1 -1
  166. package/internal/utils.d.ts.map +1 -1
  167. package/internal/utils.mjs.map +1 -1
  168. package/lib/BetaMessageStream.d.mts.map +1 -1
  169. package/lib/BetaMessageStream.d.ts.map +1 -1
  170. package/lib/BetaMessageStream.mjs.map +1 -1
  171. package/lib/MessageStream.d.mts.map +1 -1
  172. package/lib/MessageStream.d.ts.map +1 -1
  173. package/lib/MessageStream.mjs.map +1 -1
  174. package/lib/beta-parser.d.mts.map +1 -1
  175. package/lib/beta-parser.d.ts.map +1 -1
  176. package/lib/beta-parser.mjs.map +1 -1
  177. package/lib/credentials/credential-chain.d.mts.map +1 -1
  178. package/lib/credentials/credential-chain.d.ts.map +1 -1
  179. package/lib/credentials/credential-chain.mjs.map +1 -1
  180. package/lib/credentials/identity-token.d.mts.map +1 -1
  181. package/lib/credentials/identity-token.d.ts.map +1 -1
  182. package/lib/credentials/identity-token.mjs.map +1 -1
  183. package/lib/credentials/oidc-federation.d.mts.map +1 -1
  184. package/lib/credentials/oidc-federation.d.ts.map +1 -1
  185. package/lib/credentials/oidc-federation.mjs.map +1 -1
  186. package/lib/credentials/token-cache.d.mts.map +1 -1
  187. package/lib/credentials/token-cache.d.ts.map +1 -1
  188. package/lib/credentials/token-cache.mjs.map +1 -1
  189. package/lib/credentials/types.d.mts.map +1 -1
  190. package/lib/credentials/types.d.ts.map +1 -1
  191. package/lib/credentials/types.mjs.map +1 -1
  192. package/lib/credentials/user-oauth.d.mts.map +1 -1
  193. package/lib/credentials/user-oauth.d.ts.map +1 -1
  194. package/lib/credentials/user-oauth.mjs.map +1 -1
  195. package/lib/credentials.d.mts.map +1 -1
  196. package/lib/credentials.d.ts.map +1 -1
  197. package/lib/credentials.mjs.map +1 -1
  198. package/lib/environments/index.d.mts +4 -0
  199. package/lib/environments/index.d.mts.map +1 -0
  200. package/lib/environments/index.d.ts +4 -0
  201. package/lib/environments/index.d.ts.map +1 -0
  202. package/lib/environments/index.js +18 -0
  203. package/lib/environments/index.js.map +1 -0
  204. package/lib/environments/index.mjs +4 -0
  205. package/lib/environments/index.mjs.map +1 -0
  206. package/lib/environments/poller.d.mts +89 -0
  207. package/lib/environments/poller.d.mts.map +1 -0
  208. package/lib/environments/poller.d.ts +89 -0
  209. package/lib/environments/poller.d.ts.map +1 -0
  210. package/lib/environments/poller.js +181 -0
  211. package/lib/environments/poller.js.map +1 -0
  212. package/lib/environments/poller.mjs +172 -0
  213. package/lib/environments/poller.mjs.map +1 -0
  214. package/lib/environments/worker.d.mts +143 -0
  215. package/lib/environments/worker.d.mts.map +1 -0
  216. package/lib/environments/worker.d.ts +143 -0
  217. package/lib/environments/worker.d.ts.map +1 -0
  218. package/lib/environments/worker.js +265 -0
  219. package/lib/environments/worker.js.map +1 -0
  220. package/lib/environments/worker.mjs +261 -0
  221. package/lib/environments/worker.mjs.map +1 -0
  222. package/lib/helper-client.d.mts +49 -0
  223. package/lib/helper-client.d.mts.map +1 -0
  224. package/lib/helper-client.d.ts +49 -0
  225. package/lib/helper-client.d.ts.map +1 -0
  226. package/lib/helper-client.js +57 -0
  227. package/lib/helper-client.js.map +1 -0
  228. package/lib/helper-client.mjs +54 -0
  229. package/lib/helper-client.mjs.map +1 -0
  230. package/lib/parser.d.mts.map +1 -1
  231. package/lib/parser.d.ts.map +1 -1
  232. package/lib/parser.mjs.map +1 -1
  233. package/lib/stainless-helper-header.d.mts.map +1 -1
  234. package/lib/stainless-helper-header.d.ts.map +1 -1
  235. package/lib/tools/BetaRunnableTool.d.mts +54 -2
  236. package/lib/tools/BetaRunnableTool.d.mts.map +1 -1
  237. package/lib/tools/BetaRunnableTool.d.ts +54 -2
  238. package/lib/tools/BetaRunnableTool.d.ts.map +1 -1
  239. package/lib/tools/BetaRunnableTool.js +37 -0
  240. package/lib/tools/BetaRunnableTool.js.map +1 -1
  241. package/lib/tools/BetaRunnableTool.mjs +34 -1
  242. package/lib/tools/BetaRunnableTool.mjs.map +1 -1
  243. package/lib/tools/BetaToolRunner.d.mts.map +1 -1
  244. package/lib/tools/BetaToolRunner.d.ts.map +1 -1
  245. package/lib/tools/BetaToolRunner.js +4 -14
  246. package/lib/tools/BetaToolRunner.js.map +1 -1
  247. package/lib/tools/BetaToolRunner.mjs +2 -12
  248. package/lib/tools/BetaToolRunner.mjs.map +1 -1
  249. package/lib/tools/CompactionControl.d.mts.map +1 -1
  250. package/lib/tools/CompactionControl.d.ts.map +1 -1
  251. package/lib/tools/SessionToolRunner.d.mts +146 -0
  252. package/lib/tools/SessionToolRunner.d.mts.map +1 -0
  253. package/lib/tools/SessionToolRunner.d.ts +146 -0
  254. package/lib/tools/SessionToolRunner.d.ts.map +1 -0
  255. package/lib/tools/SessionToolRunner.js +471 -0
  256. package/lib/tools/SessionToolRunner.js.map +1 -0
  257. package/lib/tools/SessionToolRunner.mjs +467 -0
  258. package/lib/tools/SessionToolRunner.mjs.map +1 -0
  259. package/lib/tools/ToolError.d.mts.map +1 -1
  260. package/lib/tools/ToolError.d.ts.map +1 -1
  261. package/lib/tools/ToolRunner.d.mts.map +1 -1
  262. package/lib/tools/ToolRunner.d.ts.map +1 -1
  263. package/lib/tools/ToolRunner.mjs.map +1 -1
  264. package/lib/transform-json-schema.mjs.map +1 -1
  265. package/package.json +1 -1
  266. package/pagination.d.mts +1 -0
  267. package/pagination.d.mts.map +1 -1
  268. package/pagination.d.ts +1 -0
  269. package/pagination.d.ts.map +1 -1
  270. package/pagination.mjs +1 -0
  271. package/pagination.mjs.map +1 -1
  272. package/resource.d.mts +1 -0
  273. package/resource.d.mts.map +1 -1
  274. package/resource.d.ts +1 -0
  275. package/resource.d.ts.map +1 -1
  276. package/resource.mjs +1 -0
  277. package/resource.mjs.map +1 -1
  278. package/resources/beta/agents/agents.d.mts +125 -1
  279. package/resources/beta/agents/agents.d.mts.map +1 -1
  280. package/resources/beta/agents/agents.d.ts +125 -1
  281. package/resources/beta/agents/agents.d.ts.map +1 -1
  282. package/resources/beta/agents/agents.js.map +1 -1
  283. package/resources/beta/agents/agents.mjs.map +1 -1
  284. package/resources/beta/agents/index.d.mts +1 -1
  285. package/resources/beta/agents/index.d.mts.map +1 -1
  286. package/resources/beta/agents/index.d.ts +1 -1
  287. package/resources/beta/agents/index.d.ts.map +1 -1
  288. package/resources/beta/agents/index.js.map +1 -1
  289. package/resources/beta/agents/index.mjs.map +1 -1
  290. package/resources/beta/agents/versions.d.mts.map +1 -1
  291. package/resources/beta/agents/versions.d.ts.map +1 -1
  292. package/resources/beta/agents/versions.mjs.map +1 -1
  293. package/resources/beta/agents.d.mts.map +1 -1
  294. package/resources/beta/agents.d.ts.map +1 -1
  295. package/resources/beta/agents.mjs.map +1 -1
  296. package/resources/beta/beta.d.mts +7 -7
  297. package/resources/beta/beta.d.mts.map +1 -1
  298. package/resources/beta/beta.d.ts +7 -7
  299. package/resources/beta/beta.d.ts.map +1 -1
  300. package/resources/beta/beta.js +2 -2
  301. package/resources/beta/beta.js.map +1 -1
  302. package/resources/beta/beta.mjs +2 -2
  303. package/resources/beta/beta.mjs.map +1 -1
  304. package/resources/beta/environments/environments.d.mts +425 -0
  305. package/resources/beta/environments/environments.d.mts.map +1 -0
  306. package/resources/beta/environments/environments.d.ts +425 -0
  307. package/resources/beta/environments/environments.d.ts.map +1 -0
  308. package/resources/beta/environments/environments.js +150 -0
  309. package/resources/beta/environments/environments.js.map +1 -0
  310. package/resources/beta/environments/environments.mjs +145 -0
  311. package/resources/beta/environments/environments.mjs.map +1 -0
  312. package/resources/beta/environments/index.d.mts +3 -0
  313. package/resources/beta/environments/index.d.mts.map +1 -0
  314. package/resources/beta/environments/index.d.ts +3 -0
  315. package/resources/beta/environments/index.d.ts.map +1 -0
  316. package/resources/beta/environments/index.js +9 -0
  317. package/resources/beta/environments/index.js.map +1 -0
  318. package/resources/beta/environments/index.mjs +4 -0
  319. package/resources/beta/environments/index.mjs.map +1 -0
  320. package/resources/beta/environments/work.d.mts +496 -0
  321. package/resources/beta/environments/work.d.mts.map +1 -0
  322. package/resources/beta/environments/work.d.ts +496 -0
  323. package/resources/beta/environments/work.d.ts.map +1 -0
  324. package/resources/beta/environments/work.js +274 -0
  325. package/resources/beta/environments/work.js.map +1 -0
  326. package/resources/beta/environments/work.mjs +268 -0
  327. package/resources/beta/environments/work.mjs.map +1 -0
  328. package/resources/beta/environments.d.mts +1 -388
  329. package/resources/beta/environments.d.mts.map +1 -1
  330. package/resources/beta/environments.d.ts +1 -388
  331. package/resources/beta/environments.d.ts.map +1 -1
  332. package/resources/beta/environments.js +2 -138
  333. package/resources/beta/environments.js.map +1 -1
  334. package/resources/beta/environments.mjs +1 -136
  335. package/resources/beta/environments.mjs.map +1 -1
  336. package/resources/beta/files.d.mts.map +1 -1
  337. package/resources/beta/files.d.ts.map +1 -1
  338. package/resources/beta/files.mjs.map +1 -1
  339. package/resources/beta/index.d.mts +3 -3
  340. package/resources/beta/index.d.mts.map +1 -1
  341. package/resources/beta/index.d.ts +3 -3
  342. package/resources/beta/index.d.ts.map +1 -1
  343. package/resources/beta/index.js +12 -12
  344. package/resources/beta/index.js.map +1 -1
  345. package/resources/beta/index.mjs +1 -1
  346. package/resources/beta/index.mjs.map +1 -1
  347. package/resources/beta/memory-stores/index.d.mts.map +1 -1
  348. package/resources/beta/memory-stores/index.d.ts.map +1 -1
  349. package/resources/beta/memory-stores/index.mjs.map +1 -1
  350. package/resources/beta/memory-stores/memories.d.mts.map +1 -1
  351. package/resources/beta/memory-stores/memories.d.ts.map +1 -1
  352. package/resources/beta/memory-stores/memories.mjs.map +1 -1
  353. package/resources/beta/memory-stores/memory-stores.d.mts.map +1 -1
  354. package/resources/beta/memory-stores/memory-stores.d.ts.map +1 -1
  355. package/resources/beta/memory-stores/memory-stores.mjs.map +1 -1
  356. package/resources/beta/memory-stores/memory-versions.d.mts.map +1 -1
  357. package/resources/beta/memory-stores/memory-versions.d.ts.map +1 -1
  358. package/resources/beta/memory-stores/memory-versions.mjs.map +1 -1
  359. package/resources/beta/memory-stores.d.mts.map +1 -1
  360. package/resources/beta/memory-stores.d.ts.map +1 -1
  361. package/resources/beta/memory-stores.mjs.map +1 -1
  362. package/resources/beta/messages/batches.d.mts.map +1 -1
  363. package/resources/beta/messages/batches.d.ts.map +1 -1
  364. package/resources/beta/messages/batches.mjs.map +1 -1
  365. package/resources/beta/messages/index.d.mts.map +1 -1
  366. package/resources/beta/messages/index.d.ts.map +1 -1
  367. package/resources/beta/messages/index.mjs.map +1 -1
  368. package/resources/beta/messages/messages.d.mts +4 -4
  369. package/resources/beta/messages/messages.d.mts.map +1 -1
  370. package/resources/beta/messages/messages.d.ts +4 -4
  371. package/resources/beta/messages/messages.d.ts.map +1 -1
  372. package/resources/beta/messages/messages.mjs.map +1 -1
  373. package/resources/beta/messages.d.mts.map +1 -1
  374. package/resources/beta/messages.d.ts.map +1 -1
  375. package/resources/beta/messages.mjs.map +1 -1
  376. package/resources/beta/models.d.mts.map +1 -1
  377. package/resources/beta/models.d.ts.map +1 -1
  378. package/resources/beta/models.mjs.map +1 -1
  379. package/resources/beta/sessions/events.d.mts +52 -5
  380. package/resources/beta/sessions/events.d.mts.map +1 -1
  381. package/resources/beta/sessions/events.d.ts +52 -5
  382. package/resources/beta/sessions/events.d.ts.map +1 -1
  383. package/resources/beta/sessions/events.js +27 -1
  384. package/resources/beta/sessions/events.js.map +1 -1
  385. package/resources/beta/sessions/events.mjs +25 -0
  386. package/resources/beta/sessions/events.mjs.map +1 -1
  387. package/resources/beta/sessions/index.d.mts +3 -3
  388. package/resources/beta/sessions/index.d.mts.map +1 -1
  389. package/resources/beta/sessions/index.d.ts +3 -3
  390. package/resources/beta/sessions/index.d.ts.map +1 -1
  391. package/resources/beta/sessions/index.js.map +1 -1
  392. package/resources/beta/sessions/index.mjs.map +1 -1
  393. package/resources/beta/sessions/resources.d.mts.map +1 -1
  394. package/resources/beta/sessions/resources.d.ts.map +1 -1
  395. package/resources/beta/sessions/resources.mjs.map +1 -1
  396. package/resources/beta/sessions/sessions.d.mts +98 -6
  397. package/resources/beta/sessions/sessions.d.mts.map +1 -1
  398. package/resources/beta/sessions/sessions.d.ts +98 -6
  399. package/resources/beta/sessions/sessions.d.ts.map +1 -1
  400. package/resources/beta/sessions/sessions.js.map +1 -1
  401. package/resources/beta/sessions/sessions.mjs.map +1 -1
  402. package/resources/beta/sessions/threads/events.d.mts.map +1 -1
  403. package/resources/beta/sessions/threads/events.d.ts.map +1 -1
  404. package/resources/beta/sessions/threads/events.mjs.map +1 -1
  405. package/resources/beta/sessions/threads/index.d.mts +1 -1
  406. package/resources/beta/sessions/threads/index.d.mts.map +1 -1
  407. package/resources/beta/sessions/threads/index.d.ts +1 -1
  408. package/resources/beta/sessions/threads/index.d.ts.map +1 -1
  409. package/resources/beta/sessions/threads/index.js.map +1 -1
  410. package/resources/beta/sessions/threads/index.mjs.map +1 -1
  411. package/resources/beta/sessions/threads/threads.d.mts +3 -23
  412. package/resources/beta/sessions/threads/threads.d.mts.map +1 -1
  413. package/resources/beta/sessions/threads/threads.d.ts +3 -23
  414. package/resources/beta/sessions/threads/threads.d.ts.map +1 -1
  415. package/resources/beta/sessions/threads/threads.js.map +1 -1
  416. package/resources/beta/sessions/threads/threads.mjs.map +1 -1
  417. package/resources/beta/sessions/threads.d.mts.map +1 -1
  418. package/resources/beta/sessions/threads.d.ts.map +1 -1
  419. package/resources/beta/sessions/threads.mjs.map +1 -1
  420. package/resources/beta/sessions.d.mts.map +1 -1
  421. package/resources/beta/sessions.d.ts.map +1 -1
  422. package/resources/beta/sessions.mjs.map +1 -1
  423. package/resources/beta/skills/index.d.mts +1 -1
  424. package/resources/beta/skills/index.d.mts.map +1 -1
  425. package/resources/beta/skills/index.d.ts +1 -1
  426. package/resources/beta/skills/index.d.ts.map +1 -1
  427. package/resources/beta/skills/index.js.map +1 -1
  428. package/resources/beta/skills/index.mjs.map +1 -1
  429. package/resources/beta/skills/skills.d.mts +2 -2
  430. package/resources/beta/skills/skills.d.mts.map +1 -1
  431. package/resources/beta/skills/skills.d.ts +2 -2
  432. package/resources/beta/skills/skills.d.ts.map +1 -1
  433. package/resources/beta/skills/skills.js.map +1 -1
  434. package/resources/beta/skills/skills.mjs.map +1 -1
  435. package/resources/beta/skills/versions.d.mts +28 -1
  436. package/resources/beta/skills/versions.d.mts.map +1 -1
  437. package/resources/beta/skills/versions.d.ts +28 -1
  438. package/resources/beta/skills/versions.d.ts.map +1 -1
  439. package/resources/beta/skills/versions.js +28 -0
  440. package/resources/beta/skills/versions.js.map +1 -1
  441. package/resources/beta/skills/versions.mjs +28 -0
  442. package/resources/beta/skills/versions.mjs.map +1 -1
  443. package/resources/beta/skills.d.mts.map +1 -1
  444. package/resources/beta/skills.d.ts.map +1 -1
  445. package/resources/beta/skills.mjs.map +1 -1
  446. package/resources/beta/user-profiles.d.mts.map +1 -1
  447. package/resources/beta/user-profiles.d.ts.map +1 -1
  448. package/resources/beta/user-profiles.mjs.map +1 -1
  449. package/resources/beta/vaults/credentials.d.mts.map +1 -1
  450. package/resources/beta/vaults/credentials.d.ts.map +1 -1
  451. package/resources/beta/vaults/credentials.mjs.map +1 -1
  452. package/resources/beta/vaults/index.d.mts.map +1 -1
  453. package/resources/beta/vaults/index.d.ts.map +1 -1
  454. package/resources/beta/vaults/index.mjs.map +1 -1
  455. package/resources/beta/vaults/vaults.d.mts.map +1 -1
  456. package/resources/beta/vaults/vaults.d.ts.map +1 -1
  457. package/resources/beta/vaults/vaults.mjs.map +1 -1
  458. package/resources/beta/vaults.d.mts.map +1 -1
  459. package/resources/beta/vaults.d.ts.map +1 -1
  460. package/resources/beta/vaults.mjs.map +1 -1
  461. package/resources/beta/webhooks.d.mts.map +1 -1
  462. package/resources/beta/webhooks.d.ts.map +1 -1
  463. package/resources/beta/webhooks.mjs.map +1 -1
  464. package/resources/beta.d.mts.map +1 -1
  465. package/resources/beta.d.ts.map +1 -1
  466. package/resources/beta.mjs.map +1 -1
  467. package/resources/completions.d.mts.map +1 -1
  468. package/resources/completions.d.ts.map +1 -1
  469. package/resources/completions.mjs.map +1 -1
  470. package/resources/index.d.mts.map +1 -1
  471. package/resources/index.d.ts.map +1 -1
  472. package/resources/index.mjs.map +1 -1
  473. package/resources/messages/batches.d.mts.map +1 -1
  474. package/resources/messages/batches.d.ts.map +1 -1
  475. package/resources/messages/batches.mjs.map +1 -1
  476. package/resources/messages/index.d.mts.map +1 -1
  477. package/resources/messages/index.d.ts.map +1 -1
  478. package/resources/messages/index.mjs.map +1 -1
  479. package/resources/messages/messages.d.mts.map +1 -1
  480. package/resources/messages/messages.d.ts.map +1 -1
  481. package/resources/messages/messages.mjs.map +1 -1
  482. package/resources/messages.d.mts.map +1 -1
  483. package/resources/messages.d.ts.map +1 -1
  484. package/resources/messages.mjs.map +1 -1
  485. package/resources/models.d.mts.map +1 -1
  486. package/resources/models.d.ts.map +1 -1
  487. package/resources/models.mjs.map +1 -1
  488. package/resources.d.mts.map +1 -1
  489. package/resources.d.ts.map +1 -1
  490. package/resources.mjs.map +1 -1
  491. package/src/core/streaming.ts +2 -0
  492. package/src/helpers/beta/environments.ts +33 -0
  493. package/src/helpers/beta/json-schema.ts +7 -0
  494. package/src/helpers/beta/zod.ts +7 -0
  495. package/src/internal/utils/abort.ts +21 -0
  496. package/src/internal/utils/async-queue.ts +66 -0
  497. package/src/internal/utils/backoff.ts +41 -0
  498. package/src/internal/utils/promise.ts +18 -0
  499. package/src/internal/utils/sleep.ts +25 -2
  500. package/src/lib/environments/index.ts +23 -0
  501. package/src/lib/environments/poller.ts +253 -0
  502. package/src/lib/environments/worker.ts +395 -0
  503. package/src/lib/helper-client.ts +89 -0
  504. package/src/lib/tools/BetaRunnableTool.ts +82 -1
  505. package/src/lib/tools/BetaToolRunner.ts +2 -17
  506. package/src/lib/tools/SessionToolRunner.ts +610 -0
  507. package/src/resources/beta/agents/agents.ts +158 -0
  508. package/src/resources/beta/agents/index.ts +7 -0
  509. package/src/resources/beta/beta.ts +44 -20
  510. package/src/resources/beta/environments/environments.ts +625 -0
  511. package/src/resources/beta/environments/index.ts +42 -0
  512. package/src/resources/beta/environments/work.ts +697 -0
  513. package/src/resources/beta/environments.ts +1 -540
  514. package/src/resources/beta/index.ts +13 -1
  515. package/src/resources/beta/messages/messages.ts +5 -5
  516. package/src/resources/beta/sessions/events.ts +77 -3
  517. package/src/resources/beta/sessions/index.ts +4 -1
  518. package/src/resources/beta/sessions/sessions.ts +121 -3
  519. package/src/resources/beta/sessions/threads/index.ts +0 -1
  520. package/src/resources/beta/sessions/threads/threads.ts +4 -37
  521. package/src/resources/beta/skills/index.ts +1 -0
  522. package/src/resources/beta/skills/skills.ts +2 -0
  523. package/src/resources/beta/skills/versions.ts +44 -0
  524. package/src/tools/agent-toolset/fs-util.ts +154 -0
  525. package/src/tools/agent-toolset/node.ts +787 -0
  526. package/src/tools/agent-toolset/skills.ts +256 -0
  527. package/src/version.ts +1 -1
  528. package/streaming.d.mts +1 -0
  529. package/streaming.d.mts.map +1 -1
  530. package/streaming.d.ts +1 -0
  531. package/streaming.d.ts.map +1 -1
  532. package/streaming.mjs +1 -0
  533. package/streaming.mjs.map +1 -1
  534. package/tools/agent-toolset/fs-util.d.mts +49 -0
  535. package/tools/agent-toolset/fs-util.d.mts.map +1 -0
  536. package/tools/agent-toolset/fs-util.d.ts +49 -0
  537. package/tools/agent-toolset/fs-util.d.ts.map +1 -0
  538. package/tools/agent-toolset/fs-util.js +159 -0
  539. package/tools/agent-toolset/fs-util.js.map +1 -0
  540. package/tools/agent-toolset/fs-util.mjs +151 -0
  541. package/tools/agent-toolset/fs-util.mjs.map +1 -0
  542. package/tools/agent-toolset/node.d.mts +139 -0
  543. package/tools/agent-toolset/node.d.mts.map +1 -0
  544. package/tools/agent-toolset/node.d.ts +139 -0
  545. package/tools/agent-toolset/node.d.ts.map +1 -0
  546. package/tools/agent-toolset/node.js +746 -0
  547. package/tools/agent-toolset/node.js.map +1 -0
  548. package/tools/agent-toolset/node.mjs +731 -0
  549. package/tools/agent-toolset/node.mjs.map +1 -0
  550. package/tools/agent-toolset/skills.d.mts +50 -0
  551. package/tools/agent-toolset/skills.d.mts.map +1 -0
  552. package/tools/agent-toolset/skills.d.ts +50 -0
  553. package/tools/agent-toolset/skills.d.ts.map +1 -0
  554. package/tools/agent-toolset/skills.js +249 -0
  555. package/tools/agent-toolset/skills.js.map +1 -0
  556. package/tools/agent-toolset/skills.mjs +243 -0
  557. package/tools/agent-toolset/skills.mjs.map +1 -0
  558. package/tools/memory/node.d.mts.map +1 -1
  559. package/tools/memory/node.d.ts.map +1 -1
  560. package/tools/memory/node.mjs.map +1 -1
  561. package/uploads.d.mts +1 -0
  562. package/uploads.d.mts.map +1 -1
  563. package/uploads.d.ts +1 -0
  564. package/uploads.d.ts.map +1 -1
  565. package/uploads.mjs +1 -0
  566. package/uploads.mjs.map +1 -1
  567. package/version.d.mts +1 -1
  568. package/version.d.ts +1 -1
  569. package/version.js +1 -1
  570. package/version.mjs +1 -1
@@ -0,0 +1,610 @@
1
+ import { AnthropicError } from '../../core/error';
2
+ import type { Anthropic } from '../../client';
3
+ import type {
4
+ BetaManagedAgentsAgentCustomToolUseEvent,
5
+ BetaManagedAgentsAgentToolUseEvent,
6
+ BetaManagedAgentsSessionEvent,
7
+ BetaManagedAgentsStreamSessionEvents,
8
+ BetaManagedAgentsUserCustomToolResultEventParams,
9
+ BetaManagedAgentsUserToolResultEventParams,
10
+ } from '../../resources/beta/sessions/events';
11
+ import type { BetaToolResultContentBlockParam } from '../../resources/beta';
12
+ import { loggerFor, type Logger } from '../../internal/utils/log';
13
+ import { sleep } from '../../internal/utils/sleep';
14
+ import { isFatal4xx } from '../../internal/utils/backoff';
15
+ import { linkAbort } from '../../internal/utils/abort';
16
+ import { AsyncQueue } from '../../internal/utils/async-queue';
17
+ import { buildHeaders } from '../../internal/headers';
18
+ import type { RequestOptions } from '../../internal/request-options';
19
+ import { runRunnableTool, toolName, type BetaRunnableTool } from './BetaRunnableTool';
20
+ import type { BetaToolRunnerRequestOptions } from './BetaToolRunner';
21
+
22
+ /** Beta header for the managed-agents API. */
23
+ export const MANAGED_AGENTS_BETA = 'managed-agents-2026-04-01';
24
+
25
+ /** `x-stainless-helper` value identifying this helper in SDK telemetry. */
26
+ const HELPER_NAME = 'SessionToolRunner';
27
+
28
+ const STREAM_BACKOFF_START_MS = 500;
29
+ const STREAM_BACKOFF_CAP_MS = 10_000;
30
+ const TOOL_TIMEOUT_MS = 120_000;
31
+ const DRAIN_TIMEOUT_MS = 30_000;
32
+ const SEND_RETRIES = 3;
33
+
34
+ /** Block type accepted in a `user.tool_result` event's content — codegen'd, stays in sync with the API. */
35
+ type SessionContentBlock = NonNullable<BetaManagedAgentsUserToolResultEventParams['content']>[number];
36
+
37
+ /**
38
+ * A tool-call event the runner dispatches against the local registry: either a
39
+ * builtin `agent.tool_use` (answered with `user.tool_result`) or a custom
40
+ * `agent.custom_tool_use` (answered with `user.custom_tool_result`). Server-side
41
+ * `agent.mcp_tool_use` calls are intentionally excluded — the runner does not
42
+ * handle them.
43
+ */
44
+ type DispatchedToolUseEvent = BetaManagedAgentsAgentToolUseEvent | BetaManagedAgentsAgentCustomToolUseEvent;
45
+
46
+ /**
47
+ * The result-event params paired with a {@link DispatchedToolUseEvent}: a
48
+ * `user.tool_result` answers an `agent.tool_use`, a `user.custom_tool_result`
49
+ * answers an `agent.custom_tool_use`. The two pairs must be matched exactly.
50
+ */
51
+ type DispatchedToolResultParams =
52
+ | BetaManagedAgentsUserToolResultEventParams
53
+ | BetaManagedAgentsUserCustomToolResultEventParams;
54
+
55
+ export interface SessionToolRunnerOptions {
56
+ client: Anthropic;
57
+ /**
58
+ * Tools to expose to the session, in the same {@link BetaRunnableTool} shape
59
+ * `client.beta.messages.toolRunner` accepts. Use
60
+ * `betaAgentToolset20260401({ workdir })` from
61
+ * `@anthropic-ai/sdk/tools/agent-toolset/node` for the standard
62
+ * `agent_toolset_20260401` set; filter or extend the array to customise.
63
+ */
64
+ tools: Array<BetaRunnableTool>;
65
+ /**
66
+ * Once the session goes idle with `stop_reason.type === "end_turn"`, the
67
+ * runner keeps running for this many milliseconds before stopping; any new
68
+ * event resets the countdown and it re-arms on the next `end_turn` idle.
69
+ * Defaults to {@link DEFAULT_MAX_IDLE_MS} (60s). `0` (or negative) disables
70
+ * it — the runner then only stops on session termination or the consumer
71
+ * breaking out / aborting.
72
+ */
73
+ maxIdleMs?: number;
74
+ /** External abort signal. Aborting it ends the iteration. */
75
+ signal?: AbortSignal;
76
+ /**
77
+ * Extra per-request options merged into every call this runner issues
78
+ * (event stream / list / send). Mirrors what `client.beta.messages.toolRunner`
79
+ * accepts: custom `headers` (e.g. a proxy's auth/routing headers) reach the
80
+ * poll/heartbeat/stop/stream/list/send calls. The runner always owns the abort
81
+ * signal, so a `signal` here is ignored — pass {@link SessionToolRunnerOptions.signal}
82
+ * to abort externally.
83
+ */
84
+ requestOptions?: BetaToolRunnerRequestOptions;
85
+ }
86
+
87
+ /** Default {@link SessionToolRunnerOptions.maxIdleMs}: 60 seconds. */
88
+ export const DEFAULT_MAX_IDLE_MS = 60_000;
89
+
90
+ /**
91
+ * Outcome of a single tool execution dispatched by {@link SessionToolRunner}.
92
+ *
93
+ * Yielded after the tool ran (or failed) and after the result was posted back
94
+ * to the session as a `user.tool_result` event. Consumers can read either the
95
+ * embedded {@link DispatchedToolCall.event} / {@link DispatchedToolCall.result}
96
+ * blocks or the flat top-level convenience fields.
97
+ */
98
+ export interface DispatchedToolCall {
99
+ /**
100
+ * The `agent.tool_use` or `agent.custom_tool_use` event that triggered this
101
+ * dispatch. Read `event.input` for the raw tool input and `event.name` for the
102
+ * tool name; `event.type` distinguishes a builtin tool call from a custom one.
103
+ */
104
+ readonly event: DispatchedToolUseEvent;
105
+ /**
106
+ * The result event posted (or attempted) back to the session for this call: a
107
+ * `user.tool_result` for an `agent.tool_use`, a `user.custom_tool_result` for
108
+ * an `agent.custom_tool_use`. Read `result.content` for the tool's output
109
+ * blocks and `result.is_error` for the error flag.
110
+ *
111
+ * `undefined` when no result event was ever built — i.e. the tool name is
112
+ * not one this runner owns and, under the split-client behavior, it
113
+ * deliberately posted nothing and left the id pending for its owner.
114
+ */
115
+ readonly result?: DispatchedToolResultParams;
116
+ /**
117
+ * Flat convenience for `event.id` — the id of the tool-use event this result
118
+ * answers (echoed back as `tool_use_id` / `custom_tool_use_id` on the result).
119
+ */
120
+ readonly toolUseId: string;
121
+ /** Flat convenience for `event.name` — the dispatched tool's name. */
122
+ readonly name: string;
123
+ /**
124
+ * Flat convenience for `result.is_error` — `true` when the tool threw,
125
+ * `false` on success and for a skipped unowned call.
126
+ */
127
+ readonly isError: boolean;
128
+ /**
129
+ * Whether a result event for this call reached the session. `false` when the
130
+ * post itself failed (typically a permanent 4xx or send-retry exhaustion)
131
+ * and also `false` — with no `result` event ever built — for a tool name
132
+ * this runner does not own when it deliberately posts nothing and leaves the
133
+ * id pending for its owner (the split-client behavior).
134
+ */
135
+ readonly posted: boolean;
136
+ }
137
+
138
+ /** Returns true if `ev` is a `session.status_idle` with `stop_reason` `end_turn`. */
139
+ function isEndTurnIdle(ev: { type?: string; stop_reason?: { type?: string } }): boolean {
140
+ return ev.type === 'session.status_idle' && ev.stop_reason?.type === 'end_turn';
141
+ }
142
+
143
+ /**
144
+ * The sessions-side counterpart to `client.beta.messages.toolRunner`: an
145
+ * async-iterable that attaches to a managed-agents session, executes every
146
+ * incoming `agent.tool_use` and `agent.custom_tool_use` event against a local
147
+ * tool registry, posts the matching result back (`user.tool_result` for the
148
+ * former, `user.custom_tool_result` for the latter), and yields one
149
+ * {@link DispatchedToolCall} per completed call. Server-side `agent.mcp_tool_use`
150
+ * calls are not dispatched. Internally drives event-stream reconnect and result
151
+ * posting.
152
+ *
153
+ * Iteration ends when the session terminates (`session.status_terminated` /
154
+ * `session.deleted`), when the consumer `break`s out of the loop or aborts the
155
+ * supplied signal, or — once the session has gone idle with
156
+ * `stop_reason.type === "end_turn"` — when `maxIdleMs` elapses with no new
157
+ * event (any new event resets that countdown; it re-arms on the next `end_turn`
158
+ * idle; `maxIdleMs <= 0` disables it). The `finally` branch drains any in-flight
159
+ * tool calls and runs each tool's `close()` cleanup hook. It does *not* touch
160
+ * the work-item lease — wrap it in an `EnvironmentWorker` if you need
161
+ * heartbeating / force-stop.
162
+ *
163
+ * @example
164
+ * ```ts
165
+ * import { betaAgentToolset20260401 } from '@anthropic-ai/sdk/tools/agent-toolset/node';
166
+ *
167
+ * for await (const call of client.beta.sessions.events.toolRunner(work.data.id, {
168
+ * tools: [...betaAgentToolset20260401({ workdir }), myTool],
169
+ * })) {
170
+ * console.log(`${call.name} -> ${call.isError ? 'error' : 'ok'}`);
171
+ * }
172
+ * ```
173
+ */
174
+ export class SessionToolRunner implements AsyncIterable<DispatchedToolCall> {
175
+ readonly client: Anthropic;
176
+ readonly sessionId: string;
177
+ readonly tools: ReadonlyArray<BetaRunnableTool>;
178
+ readonly maxIdleMs: number;
179
+
180
+ #consumed = false;
181
+ readonly #controller: AbortController;
182
+ readonly #detachExternal: () => void;
183
+ readonly #requestOpts: BetaToolRunnerRequestOptions | undefined;
184
+ readonly #toolByName: Map<string, BetaRunnableTool>;
185
+ readonly #logger: Logger;
186
+ readonly #seen = new Set<string>();
187
+ readonly #answered = new Set<string>();
188
+ readonly #results = new AsyncQueue<DispatchedToolCall>();
189
+ #inFlightCount = 0;
190
+ #onIdle: (() => void) | null = null;
191
+ // When the session is idle past an `end_turn`, the pending stop timer; cleared
192
+ // by any new event. Event-driven — there is no polling watchdog.
193
+ #idleTimer: ReturnType<typeof setTimeout> | undefined;
194
+
195
+ constructor(sessionId: string, opts: SessionToolRunnerOptions) {
196
+ this.client = opts.client;
197
+ this.sessionId = sessionId;
198
+ this.tools = opts.tools;
199
+ this.maxIdleMs = opts.maxIdleMs ?? DEFAULT_MAX_IDLE_MS;
200
+ this.#logger = loggerFor(opts.client);
201
+ this.#toolByName = new Map(opts.tools.map((t) => [toolName(t), t]));
202
+ this.#controller = new AbortController();
203
+ this.#detachExternal = linkAbort(opts.signal, this.#controller);
204
+ this.#requestOpts = opts.requestOptions;
205
+ }
206
+
207
+ /** Read-only view of this runner's abort signal. */
208
+ get signal(): AbortSignal {
209
+ return this.#controller.signal;
210
+ }
211
+
212
+ /** Abort the runner. Background tasks will wind down and `for await` will exit cleanly. */
213
+ abort(): void {
214
+ this.#controller.abort();
215
+ }
216
+
217
+ async *[Symbol.asyncIterator](): AsyncIterator<DispatchedToolCall> {
218
+ if (this.#consumed) {
219
+ throw new AnthropicError('Cannot iterate over a consumed SessionToolRunner');
220
+ }
221
+ this.#consumed = true;
222
+ this.#logger.info('session tool runner starting', {
223
+ component: 'session-tool-runner',
224
+ session_id: this.sessionId,
225
+ });
226
+
227
+ // The one background promise: drives the event stream and dispatches tools.
228
+ // Its `.catch` aborts the controller so the main loop unwinds.
229
+ const streamPromise = this.#streamLoop().catch((e) => {
230
+ if (!this.#controller.signal.aborted) {
231
+ this.#logger.error('stream loop failed', { error: String(e) });
232
+ }
233
+ this.#controller.abort();
234
+ });
235
+
236
+ try {
237
+ // Phase 1: yield results as they arrive. `next(signal)` resolves
238
+ // `done: true` when the controller aborts — cancellation is handled in
239
+ // the queue read, no outer `Promise.race` needed.
240
+ while (true) {
241
+ const next = await this.#results.next(this.#controller.signal);
242
+ if (next.done) break;
243
+ yield next.value;
244
+ }
245
+
246
+ // Phase 2: let the stream loop settle (and push any final results), then
247
+ // drain whatever is still queued before closing.
248
+ await streamPromise;
249
+ let pending: DispatchedToolCall | undefined;
250
+ while ((pending = this.#results.tryShift()) !== undefined) {
251
+ yield pending;
252
+ }
253
+ } finally {
254
+ this.#controller.abort();
255
+ this.#disarmIdleTimer();
256
+ // Re-await defensively in case the consumer broke out of phase 1 before
257
+ // phase 2 ran — a no-op if it already settled.
258
+ await streamPromise;
259
+ try {
260
+ await this.#drain();
261
+ } catch (e) {
262
+ this.#logger.warn('drain failed', { error: String(e) });
263
+ }
264
+ this.#results.close();
265
+ for (const t of this.tools) {
266
+ try {
267
+ // `close` is typed `() => Promisable<void>`, so a single `await`
268
+ // covers both the sync and async return.
269
+ await t.close?.();
270
+ } catch (e) {
271
+ this.#logger.warn('tool.close failed', { tool: toolName(t), error: String(e) });
272
+ }
273
+ }
274
+ // Detach from the external signal so the consumer can drop their signal
275
+ // reference without leaking this iterator instance.
276
+ this.#detachExternal();
277
+ }
278
+ }
279
+
280
+ // ===== request options =====
281
+
282
+ /**
283
+ * Request options for every helper-issued call: the caller's `requestOptions`
284
+ * (custom proxy headers etc.) with the helper telemetry header stamped on and
285
+ * the runner's own abort signal forced last so it always owns cancellation.
286
+ */
287
+ #requestOptions(): RequestOptions {
288
+ return {
289
+ ...this.#requestOpts,
290
+ headers: buildHeaders([{ 'x-stainless-helper': HELPER_NAME }, this.#requestOpts?.headers]),
291
+ signal: this.#controller.signal,
292
+ };
293
+ }
294
+
295
+ // ===== event stream =====
296
+
297
+ async #streamLoop(): Promise<void> {
298
+ const ctrl = this.#controller;
299
+ let backoff = STREAM_BACKOFF_START_MS;
300
+ while (!ctrl.signal.aborted) {
301
+ try {
302
+ // Establish the event stream *before* reconciling history, so an event
303
+ // emitted in the gap between listing and attaching is buffered on the
304
+ // stream rather than lost. `seen`/`answered` dedup any event that shows
305
+ // up both in the reconcile pass and on the live stream.
306
+ const stream = await this.client.beta.sessions.events.stream(
307
+ this.sessionId,
308
+ {},
309
+ this.#requestOptions(),
310
+ );
311
+ await this.#reconcile();
312
+ for await (const ev of stream) {
313
+ backoff = STREAM_BACKOFF_START_MS;
314
+ if (await this.#handleStreamEvent(ev)) return;
315
+ }
316
+ } catch (e) {
317
+ // An abort throws to unwind the caller (the iterator's `streamPromise`
318
+ // `.catch`) rather than returning early and letting it carry on.
319
+ ctrl.signal.throwIfAborted();
320
+ if (isFatal4xx(e)) {
321
+ this.#logger.error('permanent stream failure, shutting down', { error: String(e) });
322
+ ctrl.abort();
323
+ throw e;
324
+ }
325
+ this.#logger.warn('stream disconnected, reconnecting', {
326
+ error: String(e),
327
+ backoff_ms: backoff,
328
+ });
329
+ }
330
+ ctrl.signal.throwIfAborted();
331
+ await sleep(backoff, ctrl.signal);
332
+ backoff = Math.min(backoff * 2, STREAM_BACKOFF_CAP_MS);
333
+ }
334
+ }
335
+
336
+ /**
337
+ * Read full history before dispatching so a `tool_use` whose result appears
338
+ * later in the same history is not re-executed. Runs after the live stream is
339
+ * already attached (see {@link SessionToolRunner.#streamLoop}).
340
+ */
341
+ async #reconcile(): Promise<void> {
342
+ const ctrl = this.#controller;
343
+ const pending: DispatchedToolUseEvent[] = [];
344
+ let lastWasEndTurn = false;
345
+ try {
346
+ for await (const ev of this.client.beta.sessions.events.list(
347
+ this.sessionId,
348
+ { limit: 1000 },
349
+ this.#requestOptions(),
350
+ )) {
351
+ this.#ingestHistory(ev, pending);
352
+ lastWasEndTurn = isEndTurnIdle(ev);
353
+ }
354
+ } catch (e) {
355
+ // An abort throws to unwind the caller; a real list failure is
356
+ // non-fatal — undo the speculative `seen` entries and let `#streamLoop`
357
+ // carry on with the live stream.
358
+ ctrl.signal.throwIfAborted();
359
+ this.#logger.warn('reconcile list failed', { error: String(e) });
360
+ // If list itself failed, undo the speculative `seen` entries so the next
361
+ // reconcile pass (or the live stream) can pick them up. Leave the idle
362
+ // timer untouched — the history we read may be incomplete.
363
+ for (const ev of pending) this.#seen.delete(ev.id);
364
+ return;
365
+ }
366
+ const unanswered = pending.filter((ev) => !this.#answered.has(ev.id));
367
+ // If the most recent event in history is an `end_turn` idle and there's no
368
+ // outstanding tool work, the session is done — arm the idle timer so the
369
+ // runner stops even if that `end_turn` arrived during a disconnect.
370
+ if (lastWasEndTurn && unanswered.length === 0) this.#armIdleTimer();
371
+ else this.#disarmIdleTimer();
372
+ for (const ev of unanswered) await this.#execute(ev);
373
+ }
374
+
375
+ #ingestHistory(ev: BetaManagedAgentsSessionEvent, pending: DispatchedToolUseEvent[]): void {
376
+ if (ev.type === 'agent.tool_use' || ev.type === 'agent.custom_tool_use') {
377
+ // Mark the event seen so a replay on the live stream is not dispatched
378
+ // twice, but decide whether it still needs executing from `answered`, not
379
+ // `seen`: a call whose result post failed is seen-but-unanswered, and must
380
+ // be retried on the next reconcile pass rather than silently dropped.
381
+ this.#seen.add(ev.id);
382
+ if (!this.#answered.has(ev.id)) pending.push(ev);
383
+ } else if (ev.type === 'user.tool_result') {
384
+ this.#answered.add(ev.tool_use_id);
385
+ } else if (ev.type === 'user.custom_tool_result') {
386
+ this.#answered.add(ev.custom_tool_use_id);
387
+ }
388
+ }
389
+
390
+ /** Returns true when the runner should exit. */
391
+ async #handleStreamEvent(ev: BetaManagedAgentsStreamSessionEvents): Promise<boolean> {
392
+ // Arm/disarm the idle timer: an `end_turn` idle starts the grace countdown;
393
+ // any other event cancels it.
394
+ if (isEndTurnIdle(ev)) this.#armIdleTimer();
395
+ else this.#disarmIdleTimer();
396
+ switch (ev.type) {
397
+ case 'agent.tool_use':
398
+ case 'agent.custom_tool_use':
399
+ if (!this.#seen.has(ev.id)) {
400
+ this.#seen.add(ev.id);
401
+ await this.#execute(ev);
402
+ }
403
+ return false;
404
+ case 'user.tool_result':
405
+ this.#answered.add(ev.tool_use_id);
406
+ return false;
407
+ case 'user.custom_tool_result':
408
+ this.#answered.add(ev.custom_tool_use_id);
409
+ return false;
410
+ case 'session.status_terminated':
411
+ case 'session.deleted':
412
+ this.#logger.info('session terminated', {
413
+ component: 'session-tool-runner',
414
+ session_id: this.sessionId,
415
+ });
416
+ this.#controller.abort();
417
+ return true;
418
+ default:
419
+ return false;
420
+ }
421
+ }
422
+
423
+ // ===== idle timer =====
424
+
425
+ /** (Re)start the grace countdown that stops the runner after `maxIdleMs` of idle. */
426
+ #armIdleTimer(): void {
427
+ this.#disarmIdleTimer();
428
+ if (this.maxIdleMs <= 0) return;
429
+ this.#idleTimer = setTimeout(() => {
430
+ this.#logger.info('session idle after end_turn; stopping', {
431
+ component: 'session-tool-runner',
432
+ session_id: this.sessionId,
433
+ max_idle_ms: this.maxIdleMs,
434
+ });
435
+ this.#controller.abort();
436
+ }, this.maxIdleMs);
437
+ }
438
+
439
+ /** Cancel a pending idle countdown, if any. */
440
+ #disarmIdleTimer(): void {
441
+ if (this.#idleTimer !== undefined) {
442
+ clearTimeout(this.#idleTimer);
443
+ this.#idleTimer = undefined;
444
+ }
445
+ }
446
+
447
+ // ===== tool execution =====
448
+
449
+ async #execute(ev: DispatchedToolUseEvent): Promise<void> {
450
+ if (this.#answered.has(ev.id)) return;
451
+ this.#logger.info('executing tool', {
452
+ component: 'session-tool-runner',
453
+ session_id: this.sessionId,
454
+ tool: ev.name,
455
+ tool_use_id: ev.id,
456
+ });
457
+ this.#inFlightCount++;
458
+ try {
459
+ const tool = this.#toolByName.get(ev.name);
460
+ if (!tool) {
461
+ // Skip (split-client partial fulfilment): a name this runner
462
+ // is not registered for belongs to the other client servicing this
463
+ // session (typically the customer's app backend handling custom tools).
464
+ // Post NO result, do not mark it answered, and leave the tool_use_id
465
+ // pending for its owner — claiming it would corrupt the conversation.
466
+ // Still yield the call so the consumer can observe the unowned
467
+ // dispatch; nothing was sent, so `posted`/`isError` stay false and no
468
+ // `result` event is populated. The id stays unanswered, so reconcile
469
+ // keeps it out of the idle/end-turn accounting and re-surfaces it after
470
+ // a reconnect until its owner answers it.
471
+ this.#logger.info('tool not owned by this runner; leaving the tool_use_id pending for its owner', {
472
+ component: 'session-tool-runner',
473
+ session_id: this.sessionId,
474
+ tool: ev.name,
475
+ tool_use_id: ev.id,
476
+ });
477
+ this.#results.push({ event: ev, toolUseId: ev.id, name: ev.name, isError: false, posted: false });
478
+ return;
479
+ }
480
+ let content: string | Array<BetaToolResultContentBlockParam>;
481
+ let isError: boolean;
482
+ // Per-tool controller: aborts on the runner's own signal *or* the
483
+ // per-tool timeout, so an in-flight tool stops promptly when the runner
484
+ // is aborted instead of running until the timeout.
485
+ const toolCtrl = new AbortController();
486
+ const detachTool = linkAbort(this.#controller.signal, toolCtrl);
487
+ const timer = setTimeout(() => toolCtrl.abort(), TOOL_TIMEOUT_MS);
488
+ try {
489
+ // Pass the source `agent.tool_use` / `agent.custom_tool_use` event
490
+ // straight through as the run context's `toolUse` — it is a union
491
+ // member of `BetaToolUse`, no Messages-block adapter needed.
492
+ const outcome = await runRunnableTool(tool, ev.input, {
493
+ toolUse: ev,
494
+ toolUseBlock: ev,
495
+ signal: toolCtrl.signal,
496
+ });
497
+ content = outcome.content;
498
+ isError = outcome.isError;
499
+ } finally {
500
+ clearTimeout(timer);
501
+ detachTool();
502
+ }
503
+ // Answer with the result event that matches the call kind: a
504
+ // `user.tool_result` for an `agent.tool_use`, a `user.custom_tool_result`
505
+ // for an `agent.custom_tool_use`. Posting the wrong one leaves the call
506
+ // unanswered and the session stuck.
507
+ const result = buildResultEvent(ev, isError, toSessionContent(content));
508
+ const posted = await this.#sendResult(result, ev.id);
509
+ this.#results.push({
510
+ event: ev,
511
+ result,
512
+ toolUseId: ev.id,
513
+ name: ev.name,
514
+ isError,
515
+ posted,
516
+ });
517
+ } finally {
518
+ this.#inFlightCount--;
519
+ if (this.#inFlightCount === 0) this.#onIdle?.();
520
+ }
521
+ }
522
+
523
+ async #sendResult(result: DispatchedToolResultParams, toolUseId: string): Promise<boolean> {
524
+ const ctrl = this.#controller;
525
+ let lastErr: unknown;
526
+ for (let i = 0; i < SEND_RETRIES; i++) {
527
+ // An abort throws to unwind the caller rather than returning a
528
+ // `posted: false` result the iterator would carry on past.
529
+ ctrl.signal.throwIfAborted();
530
+ try {
531
+ await this.client.beta.sessions.events.send(
532
+ this.sessionId,
533
+ { events: [result] },
534
+ this.#requestOptions(),
535
+ );
536
+ this.#answered.add(toolUseId);
537
+ return true;
538
+ } catch (e) {
539
+ lastErr = e;
540
+ // Only short-circuit on a permanent 4xx; 408/409/429 deserve the
541
+ // remaining retries (aligned with the core client's retry policy).
542
+ if (isFatal4xx(e)) break;
543
+ // Back off only *between* attempts — never after the final one, since
544
+ // there is no further try left to wait for.
545
+ if (i < SEND_RETRIES - 1) await sleep((i + 1) * 1000, ctrl.signal);
546
+ }
547
+ }
548
+ this.#logger.error('failed to send tool result', {
549
+ tool_use_id: toolUseId,
550
+ error: String(lastErr),
551
+ });
552
+ return false;
553
+ }
554
+
555
+ /** Wait (bounded) for in-flight tool executions to finish during teardown. */
556
+ async #drain(): Promise<void> {
557
+ if (this.#inFlightCount === 0) return;
558
+ await Promise.race([new Promise<void>((r) => (this.#onIdle = r)), sleep(DRAIN_TIMEOUT_MS)]);
559
+ this.#onIdle = null;
560
+ if (this.#inFlightCount > 0) {
561
+ this.#logger.warn('drain timeout exceeded');
562
+ }
563
+ }
564
+ }
565
+
566
+ /**
567
+ * Build the result event that answers `ev`: a `user.tool_result` for a builtin
568
+ * `agent.tool_use`, a `user.custom_tool_result` for a custom
569
+ * `agent.custom_tool_use`. The two `(use, result)` pairs are distinct API event
570
+ * types and must be matched exactly — a `user.tool_result` does not answer a
571
+ * custom tool call.
572
+ */
573
+ function buildResultEvent(
574
+ ev: DispatchedToolUseEvent,
575
+ isError: boolean,
576
+ content: SessionContentBlock[],
577
+ ): DispatchedToolResultParams {
578
+ if (ev.type === 'agent.custom_tool_use') {
579
+ return { type: 'user.custom_tool_result', custom_tool_use_id: ev.id, is_error: isError, content };
580
+ }
581
+ return { type: 'user.tool_result', tool_use_id: ev.id, is_error: isError, content };
582
+ }
583
+
584
+ // The Messages-API tool-result block union is wider than the Sessions-API
585
+ // tool_result content union; pass through text/image/document and stringify
586
+ // anything else so a BetaRunnableTool authored for toolRunner still works here.
587
+ function toSessionContent(content: string | Array<BetaToolResultContentBlockParam>): SessionContentBlock[] {
588
+ if (typeof content === 'string') return [{ type: 'text', text: content || '(no output)' }];
589
+ const out = content.map((b): SessionContentBlock => {
590
+ if (b.type === 'text') return { type: 'text', text: b.text || '(no output)' };
591
+ if (b.type === 'image' || b.type === 'document') return b as SessionContentBlock;
592
+ if (b.type === 'search_result') {
593
+ // The Messages `search_result` block param maps field-for-field onto the
594
+ // Sessions `BetaManagedAgentsSearchResultBlock`; map it explicitly rather
595
+ // than letting it fall through to the JSON.stringify branch (which would
596
+ // bury a structured result inside a text block). `citations` is required
597
+ // on the Sessions side and optional on the Messages side — default the
598
+ // flag to `false` when the producer left it unset.
599
+ return {
600
+ type: 'search_result',
601
+ source: b.source,
602
+ title: b.title,
603
+ content: b.content.map((c) => ({ type: 'text', text: c.text })),
604
+ citations: { enabled: b.citations?.enabled ?? false },
605
+ };
606
+ }
607
+ return { type: 'text', text: JSON.stringify(b) };
608
+ });
609
+ return out.length > 0 ? out : [{ type: 'text', text: '(no output)' }];
610
+ }