@trigger.dev/sdk 0.0.0-python-preview-20250226140121 → 0.0.0-rc-4-8-0-20261021151928

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 (732) hide show
  1. package/README.md +29 -9
  2. package/dist/commonjs/imports/ai-runtime-cjs.cjs.map +1 -0
  3. package/dist/commonjs/imports/ai-runtime.d.ts +1 -0
  4. package/dist/commonjs/imports/ai-runtime.js +31 -0
  5. package/dist/commonjs/imports/uncrypto.js +4 -4
  6. package/dist/commonjs/package.json +2 -1
  7. package/dist/commonjs/v3/agentSkillsRuntime.d.ts +28 -0
  8. package/dist/commonjs/v3/agentSkillsRuntime.js +173 -0
  9. package/dist/commonjs/v3/agentSkillsRuntime.js.map +1 -0
  10. package/dist/commonjs/v3/ai-shared.d.ts +156 -0
  11. package/dist/commonjs/v3/ai-shared.js +215 -0
  12. package/dist/commonjs/v3/ai-shared.js.map +1 -0
  13. package/dist/commonjs/v3/ai.d.ts +4225 -0
  14. package/dist/commonjs/v3/ai.js +11569 -0
  15. package/dist/commonjs/v3/ai.js.map +1 -0
  16. package/dist/commonjs/v3/aiAutoTelemetry.d.ts +2 -0
  17. package/dist/commonjs/v3/aiAutoTelemetry.js +81 -0
  18. package/dist/commonjs/v3/aiAutoTelemetry.js.map +1 -0
  19. package/dist/commonjs/v3/auth.d.ts +71 -10
  20. package/dist/commonjs/v3/auth.js +85 -19
  21. package/dist/commonjs/v3/auth.js.map +1 -1
  22. package/dist/commonjs/v3/batch.d.ts +3 -3
  23. package/dist/commonjs/v3/batch.js.map +1 -1
  24. package/dist/commonjs/v3/cache.js.map +1 -1
  25. package/dist/commonjs/v3/chat-client.d.ts +324 -0
  26. package/dist/commonjs/v3/chat-client.js +774 -0
  27. package/dist/commonjs/v3/chat-client.js.map +1 -0
  28. package/dist/commonjs/v3/chat-react.d.ts +244 -0
  29. package/dist/commonjs/v3/chat-react.js +463 -0
  30. package/dist/commonjs/v3/chat-react.js.map +1 -0
  31. package/dist/commonjs/v3/chat-server.d.ts +350 -0
  32. package/dist/commonjs/v3/chat-server.js +965 -0
  33. package/dist/commonjs/v3/chat-server.js.map +1 -0
  34. package/dist/commonjs/v3/chat-tab-coordinator.d.ts +65 -0
  35. package/dist/commonjs/v3/chat-tab-coordinator.js +235 -0
  36. package/dist/commonjs/v3/chat-tab-coordinator.js.map +1 -0
  37. package/dist/commonjs/v3/chat.d.ts +792 -0
  38. package/dist/commonjs/v3/chat.js +1662 -0
  39. package/dist/commonjs/v3/chat.js.map +1 -0
  40. package/dist/commonjs/v3/chatRouteWait.d.ts +21 -0
  41. package/dist/commonjs/v3/chatRouteWait.js +43 -0
  42. package/dist/commonjs/v3/chatRouteWait.js.map +1 -0
  43. package/dist/commonjs/v3/chatSnapshotIo.d.ts +2 -0
  44. package/dist/commonjs/v3/chatSnapshotIo.js +173 -0
  45. package/dist/commonjs/v3/chatSnapshotIo.js.map +1 -0
  46. package/dist/commonjs/v3/chatVersionSkew.d.ts +12 -0
  47. package/dist/commonjs/v3/chatVersionSkew.js +30 -0
  48. package/dist/commonjs/v3/chatVersionSkew.js.map +1 -0
  49. package/dist/commonjs/v3/compactionResponse.d.ts +9 -0
  50. package/dist/commonjs/v3/compactionResponse.js +37 -0
  51. package/dist/commonjs/v3/compactionResponse.js.map +1 -0
  52. package/dist/commonjs/v3/concurrency-shared.d.ts +13 -0
  53. package/dist/commonjs/v3/concurrency-shared.js +35 -0
  54. package/dist/commonjs/v3/concurrency-shared.js.map +1 -0
  55. package/dist/commonjs/v3/concurrencyLimits.d.ts +103 -0
  56. package/dist/commonjs/v3/concurrencyLimits.js +134 -0
  57. package/dist/commonjs/v3/concurrencyLimits.js.map +1 -0
  58. package/dist/commonjs/v3/config.js.map +1 -1
  59. package/dist/commonjs/v3/deployments.d.ts +25 -0
  60. package/dist/commonjs/v3/deployments.js +37 -0
  61. package/dist/commonjs/v3/deployments.js.map +1 -0
  62. package/dist/commonjs/v3/envvars.d.ts +5 -5
  63. package/dist/commonjs/v3/envvars.js.map +1 -1
  64. package/dist/commonjs/v3/externalDeploymentId.d.ts +23 -0
  65. package/dist/commonjs/v3/externalDeploymentId.js +43 -0
  66. package/dist/commonjs/v3/externalDeploymentId.js.map +1 -0
  67. package/dist/commonjs/v3/heartbeats.d.ts +37 -0
  68. package/dist/commonjs/v3/heartbeats.js +45 -0
  69. package/dist/commonjs/v3/heartbeats.js.map +1 -0
  70. package/dist/commonjs/v3/hooks.d.ts +26 -0
  71. package/dist/commonjs/v3/hooks.js +79 -0
  72. package/dist/commonjs/v3/hooks.js.map +1 -0
  73. package/dist/commonjs/v3/idempotencyKeys.d.ts +2 -1
  74. package/dist/commonjs/v3/idempotencyKeys.js +1 -0
  75. package/dist/commonjs/v3/idempotencyKeys.js.map +1 -1
  76. package/dist/commonjs/v3/index.d.ts +20 -5
  77. package/dist/commonjs/v3/index.js +56 -20
  78. package/dist/commonjs/v3/index.js.map +1 -1
  79. package/dist/commonjs/v3/locals.d.ts +3 -0
  80. package/dist/commonjs/v3/locals.js +6 -0
  81. package/dist/commonjs/v3/locals.js.map +1 -0
  82. package/dist/commonjs/v3/managedChatResponse.d.ts +44 -0
  83. package/dist/commonjs/v3/managedChatResponse.js +221 -0
  84. package/dist/commonjs/v3/managedChatResponse.js.map +1 -0
  85. package/dist/commonjs/v3/metadata.d.ts +5 -2
  86. package/dist/commonjs/v3/metadata.js +8 -1
  87. package/dist/commonjs/v3/metadata.js.map +1 -1
  88. package/dist/commonjs/v3/modelFileDownload.d.ts +10 -0
  89. package/dist/commonjs/v3/modelFileDownload.js +164 -0
  90. package/dist/commonjs/v3/modelFileDownload.js.map +1 -0
  91. package/dist/commonjs/v3/otel.d.ts +4 -0
  92. package/dist/commonjs/v3/otel.js +12 -0
  93. package/dist/commonjs/v3/otel.js.map +1 -0
  94. package/dist/commonjs/v3/prompt.d.ts +38 -0
  95. package/dist/commonjs/v3/prompt.js +146 -0
  96. package/dist/commonjs/v3/prompt.js.map +1 -0
  97. package/dist/commonjs/v3/promptManagement.d.ts +26 -0
  98. package/dist/commonjs/v3/promptManagement.js +180 -0
  99. package/dist/commonjs/v3/promptManagement.js.map +1 -0
  100. package/dist/commonjs/v3/prompts.d.ts +3 -0
  101. package/dist/commonjs/v3/prompts.js +15 -0
  102. package/dist/commonjs/v3/prompts.js.map +1 -0
  103. package/dist/commonjs/v3/query.d.ts +545 -0
  104. package/dist/commonjs/v3/query.js +163 -0
  105. package/dist/commonjs/v3/query.js.map +1 -0
  106. package/dist/commonjs/v3/queues.d.ts +107 -0
  107. package/dist/commonjs/v3/queues.js +225 -0
  108. package/dist/commonjs/v3/queues.js.map +1 -0
  109. package/dist/commonjs/v3/retry.d.ts +6 -2
  110. package/dist/commonjs/v3/retry.js +34 -23
  111. package/dist/commonjs/v3/retry.js.map +1 -1
  112. package/dist/commonjs/v3/runs.d.ts +182 -101
  113. package/dist/commonjs/v3/runs.js +99 -5
  114. package/dist/commonjs/v3/runs.js.map +1 -1
  115. package/dist/commonjs/v3/schedules/api.d.ts +8 -1
  116. package/dist/commonjs/v3/schedules/index.d.ts +29 -9
  117. package/dist/commonjs/v3/schedules/index.js +5 -1
  118. package/dist/commonjs/v3/schedules/index.js.map +1 -1
  119. package/dist/commonjs/v3/schemas.d.ts +1 -0
  120. package/dist/commonjs/{integrations.js → v3/schemas.js} +1 -1
  121. package/dist/commonjs/v3/schemas.js.map +1 -0
  122. package/dist/commonjs/v3/sessionTracing.d.ts +7 -0
  123. package/dist/commonjs/v3/sessionTracing.js +44 -0
  124. package/dist/commonjs/v3/sessionTracing.js.map +1 -0
  125. package/dist/commonjs/v3/sessions.d.ts +268 -0
  126. package/dist/commonjs/v3/sessions.js +776 -0
  127. package/dist/commonjs/v3/sessions.js.map +1 -0
  128. package/dist/commonjs/v3/shared.d.ts +129 -24
  129. package/dist/commonjs/v3/shared.js +1527 -689
  130. package/dist/commonjs/v3/shared.js.map +1 -1
  131. package/dist/commonjs/v3/skill.d.ts +99 -0
  132. package/dist/commonjs/v3/skill.js +165 -0
  133. package/dist/commonjs/v3/skill.js.map +1 -0
  134. package/dist/commonjs/v3/skills.d.ts +2 -0
  135. package/dist/commonjs/v3/skills.js +6 -0
  136. package/dist/commonjs/v3/skills.js.map +1 -0
  137. package/dist/commonjs/v3/steeringContext.d.ts +41 -0
  138. package/dist/commonjs/v3/steeringContext.js +118 -0
  139. package/dist/commonjs/v3/steeringContext.js.map +1 -0
  140. package/dist/commonjs/v3/streams.d.ts +298 -0
  141. package/dist/commonjs/v3/streams.js +584 -0
  142. package/dist/commonjs/v3/streams.js.map +1 -0
  143. package/dist/commonjs/v3/tasks.d.ts +19 -4
  144. package/dist/commonjs/v3/tasks.js +15 -1
  145. package/dist/commonjs/v3/tasks.js.map +1 -1
  146. package/dist/commonjs/v3/test/index.d.ts +5 -0
  147. package/dist/commonjs/v3/test/index.js +23 -0
  148. package/dist/commonjs/v3/test/index.js.map +1 -0
  149. package/dist/commonjs/v3/test/mock-channel-connector.d.ts +172 -0
  150. package/dist/commonjs/v3/test/mock-channel-connector.js +173 -0
  151. package/dist/commonjs/v3/test/mock-channel-connector.js.map +1 -0
  152. package/dist/commonjs/v3/test/mock-chat-agent.d.ts +388 -0
  153. package/dist/commonjs/v3/test/mock-chat-agent.js +689 -0
  154. package/dist/commonjs/v3/test/mock-chat-agent.js.map +1 -0
  155. package/dist/commonjs/v3/test/setup-catalog.d.ts +1 -0
  156. package/dist/commonjs/v3/test/setup-catalog.js +18 -0
  157. package/dist/commonjs/v3/test/setup-catalog.js.map +1 -0
  158. package/dist/commonjs/v3/test/test-session-handle.d.ts +24 -0
  159. package/dist/commonjs/v3/test/test-session-handle.js +271 -0
  160. package/dist/commonjs/v3/test/test-session-handle.js.map +1 -0
  161. package/dist/commonjs/v3/test/transcript-storage-tests.d.ts +40 -0
  162. package/dist/commonjs/v3/test/transcript-storage-tests.js +258 -0
  163. package/dist/commonjs/v3/test/transcript-storage-tests.js.map +1 -0
  164. package/dist/commonjs/v3/toolResultOrder.d.ts +15 -0
  165. package/dist/commonjs/v3/toolResultOrder.js +58 -0
  166. package/dist/commonjs/v3/toolResultOrder.js.map +1 -0
  167. package/dist/commonjs/v3/transcriptStorage.d.ts +307 -0
  168. package/dist/commonjs/v3/transcriptStorage.js +445 -0
  169. package/dist/commonjs/v3/transcriptStorage.js.map +1 -0
  170. package/dist/commonjs/v3/triggerClient.d.ts +45 -0
  171. package/dist/commonjs/v3/triggerClient.js +114 -0
  172. package/dist/commonjs/v3/triggerClient.js.map +1 -0
  173. package/dist/commonjs/v3/uiMessageChunks.d.ts +1 -0
  174. package/dist/commonjs/v3/uiMessageChunks.js +119 -0
  175. package/dist/commonjs/v3/uiMessageChunks.js.map +1 -0
  176. package/dist/commonjs/v3/usage.js +7 -6
  177. package/dist/commonjs/v3/usage.js.map +1 -1
  178. package/dist/commonjs/v3/wait.d.ts +218 -3
  179. package/dist/commonjs/v3/wait.js +433 -7
  180. package/dist/commonjs/v3/wait.js.map +1 -1
  181. package/dist/commonjs/v3/waitUntil.js.map +1 -1
  182. package/dist/commonjs/v3/webhookWaiters.d.ts +80 -0
  183. package/dist/commonjs/v3/webhookWaiters.js +156 -0
  184. package/dist/commonjs/v3/webhookWaiters.js.map +1 -0
  185. package/dist/commonjs/v3/webhooks.d.ts +192 -2
  186. package/dist/commonjs/v3/webhooks.js +340 -2
  187. package/dist/commonjs/v3/webhooks.js.map +1 -1
  188. package/dist/commonjs/version.js +1 -1
  189. package/dist/esm/imports/ai-runtime.d.ts +2 -0
  190. package/dist/esm/imports/ai-runtime.js +16 -0
  191. package/dist/esm/imports/ai-runtime.js.map +1 -0
  192. package/dist/esm/package.json +2 -1
  193. package/dist/esm/v3/agentSkillsRuntime.d.ts +28 -0
  194. package/dist/esm/v3/agentSkillsRuntime.js +136 -0
  195. package/dist/esm/v3/agentSkillsRuntime.js.map +1 -0
  196. package/dist/esm/v3/ai-shared.d.ts +156 -0
  197. package/dist/esm/v3/ai-shared.js +208 -0
  198. package/dist/esm/v3/ai-shared.js.map +1 -0
  199. package/dist/esm/v3/ai.d.ts +4225 -0
  200. package/dist/esm/v3/ai.js +11550 -0
  201. package/dist/esm/v3/ai.js.map +1 -0
  202. package/dist/esm/v3/aiAutoTelemetry.d.ts +2 -0
  203. package/dist/esm/v3/aiAutoTelemetry.js +78 -0
  204. package/dist/esm/v3/aiAutoTelemetry.js.map +1 -0
  205. package/dist/esm/v3/auth.d.ts +71 -10
  206. package/dist/esm/v3/auth.js +83 -17
  207. package/dist/esm/v3/auth.js.map +1 -1
  208. package/dist/esm/v3/batch.d.ts +3 -3
  209. package/dist/esm/v3/batch.js +2 -2
  210. package/dist/esm/v3/batch.js.map +1 -1
  211. package/dist/esm/v3/chat-client.d.ts +324 -0
  212. package/dist/esm/v3/chat-client.js +769 -0
  213. package/dist/esm/v3/chat-client.js.map +1 -0
  214. package/dist/esm/v3/chat-react.d.ts +244 -0
  215. package/dist/esm/v3/chat-react.js +455 -0
  216. package/dist/esm/v3/chat-react.js.map +1 -0
  217. package/dist/esm/v3/chat-server.d.ts +350 -0
  218. package/dist/esm/v3/chat-server.js +962 -0
  219. package/dist/esm/v3/chat-server.js.map +1 -0
  220. package/dist/esm/v3/chat-tab-coordinator.d.ts +65 -0
  221. package/dist/esm/v3/chat-tab-coordinator.js +231 -0
  222. package/dist/esm/v3/chat-tab-coordinator.js.map +1 -0
  223. package/dist/esm/v3/chat.d.ts +792 -0
  224. package/dist/esm/v3/chat.js +1655 -0
  225. package/dist/esm/v3/chat.js.map +1 -0
  226. package/dist/esm/v3/chatRouteWait.d.ts +21 -0
  227. package/dist/esm/v3/chatRouteWait.js +40 -0
  228. package/dist/esm/v3/chatRouteWait.js.map +1 -0
  229. package/dist/esm/v3/chatSnapshotIo.d.ts +2 -0
  230. package/dist/esm/v3/chatSnapshotIo.js +165 -0
  231. package/dist/esm/v3/chatSnapshotIo.js.map +1 -0
  232. package/dist/esm/v3/chatVersionSkew.d.ts +12 -0
  233. package/dist/esm/v3/chatVersionSkew.js +27 -0
  234. package/dist/esm/v3/chatVersionSkew.js.map +1 -0
  235. package/dist/esm/v3/compactionResponse.d.ts +9 -0
  236. package/dist/esm/v3/compactionResponse.js +34 -0
  237. package/dist/esm/v3/compactionResponse.js.map +1 -0
  238. package/dist/esm/v3/concurrency-shared.d.ts +13 -0
  239. package/dist/esm/v3/concurrency-shared.js +31 -0
  240. package/dist/esm/v3/concurrency-shared.js.map +1 -0
  241. package/dist/esm/v3/concurrencyLimits.d.ts +103 -0
  242. package/dist/esm/v3/concurrencyLimits.js +126 -0
  243. package/dist/esm/v3/concurrencyLimits.js.map +1 -0
  244. package/dist/esm/v3/deployments.d.ts +25 -0
  245. package/dist/esm/v3/deployments.js +34 -0
  246. package/dist/esm/v3/deployments.js.map +1 -0
  247. package/dist/esm/v3/envvars.d.ts +5 -5
  248. package/dist/esm/v3/envvars.js.map +1 -1
  249. package/dist/esm/v3/externalDeploymentId.d.ts +23 -0
  250. package/dist/esm/v3/externalDeploymentId.js +38 -0
  251. package/dist/esm/v3/externalDeploymentId.js.map +1 -0
  252. package/dist/esm/v3/heartbeats.d.ts +37 -0
  253. package/dist/esm/v3/heartbeats.js +42 -0
  254. package/dist/esm/v3/heartbeats.js.map +1 -0
  255. package/dist/esm/v3/hooks.d.ts +26 -0
  256. package/dist/esm/v3/hooks.js +66 -0
  257. package/dist/esm/v3/hooks.js.map +1 -0
  258. package/dist/esm/v3/idempotencyKeys.d.ts +2 -1
  259. package/dist/esm/v3/idempotencyKeys.js +2 -1
  260. package/dist/esm/v3/idempotencyKeys.js.map +1 -1
  261. package/dist/esm/v3/index.d.ts +20 -5
  262. package/dist/esm/v3/index.js +16 -2
  263. package/dist/esm/v3/index.js.map +1 -1
  264. package/dist/esm/v3/locals.d.ts +3 -0
  265. package/dist/esm/v3/locals.js +3 -0
  266. package/dist/esm/v3/locals.js.map +1 -0
  267. package/dist/esm/v3/managedChatResponse.d.ts +44 -0
  268. package/dist/esm/v3/managedChatResponse.js +216 -0
  269. package/dist/esm/v3/managedChatResponse.js.map +1 -0
  270. package/dist/esm/v3/metadata.d.ts +5 -2
  271. package/dist/esm/v3/metadata.js +8 -1
  272. package/dist/esm/v3/metadata.js.map +1 -1
  273. package/dist/esm/v3/modelFileDownload.d.ts +10 -0
  274. package/dist/esm/v3/modelFileDownload.js +161 -0
  275. package/dist/esm/v3/modelFileDownload.js.map +1 -0
  276. package/dist/esm/v3/otel.d.ts +4 -0
  277. package/dist/esm/v3/otel.js +9 -0
  278. package/dist/esm/v3/otel.js.map +1 -0
  279. package/dist/esm/v3/prompt.d.ts +38 -0
  280. package/dist/esm/v3/prompt.js +143 -0
  281. package/dist/esm/v3/prompt.js.map +1 -0
  282. package/dist/esm/v3/promptManagement.d.ts +26 -0
  283. package/dist/esm/v3/promptManagement.js +170 -0
  284. package/dist/esm/v3/promptManagement.js.map +1 -0
  285. package/dist/esm/v3/prompts.d.ts +3 -0
  286. package/dist/esm/v3/prompts.js +3 -0
  287. package/dist/esm/v3/prompts.js.map +1 -0
  288. package/dist/esm/v3/query.d.ts +545 -0
  289. package/dist/esm/v3/query.js +160 -0
  290. package/dist/esm/v3/query.js.map +1 -0
  291. package/dist/esm/v3/queues.d.ts +107 -0
  292. package/dist/esm/v3/queues.js +217 -0
  293. package/dist/esm/v3/queues.js.map +1 -0
  294. package/dist/esm/v3/retry.d.ts +6 -2
  295. package/dist/esm/v3/retry.js +27 -19
  296. package/dist/esm/v3/retry.js.map +1 -1
  297. package/dist/esm/v3/runs.d.ts +179 -98
  298. package/dist/esm/v3/runs.js +99 -5
  299. package/dist/esm/v3/runs.js.map +1 -1
  300. package/dist/esm/v3/schedules/api.d.ts +8 -1
  301. package/dist/esm/v3/schedules/index.d.ts +29 -9
  302. package/dist/esm/v3/schedules/index.js +6 -2
  303. package/dist/esm/v3/schedules/index.js.map +1 -1
  304. package/dist/esm/v3/schemas.d.ts +1 -0
  305. package/dist/esm/v3/schemas.js +2 -0
  306. package/dist/esm/v3/schemas.js.map +1 -0
  307. package/dist/esm/v3/sessionTracing.d.ts +7 -0
  308. package/dist/esm/v3/sessionTracing.js +40 -0
  309. package/dist/esm/v3/sessionTracing.js.map +1 -0
  310. package/dist/esm/v3/sessions.d.ts +268 -0
  311. package/dist/esm/v3/sessions.js +767 -0
  312. package/dist/esm/v3/sessions.js.map +1 -0
  313. package/dist/esm/v3/shared.d.ts +129 -24
  314. package/dist/esm/v3/shared.js +1521 -688
  315. package/dist/esm/v3/shared.js.map +1 -1
  316. package/dist/esm/v3/skill.d.ts +99 -0
  317. package/dist/esm/v3/skill.js +128 -0
  318. package/dist/esm/v3/skill.js.map +1 -0
  319. package/dist/esm/v3/skills.d.ts +2 -0
  320. package/dist/esm/v3/skills.js +2 -0
  321. package/dist/esm/v3/skills.js.map +1 -0
  322. package/dist/esm/v3/steeringContext.d.ts +41 -0
  323. package/dist/esm/v3/steeringContext.js +113 -0
  324. package/dist/esm/v3/steeringContext.js.map +1 -0
  325. package/dist/esm/v3/streams.d.ts +298 -0
  326. package/dist/esm/v3/streams.js +580 -0
  327. package/dist/esm/v3/streams.js.map +1 -0
  328. package/dist/esm/v3/tasks.d.ts +19 -4
  329. package/dist/esm/v3/tasks.js +16 -2
  330. package/dist/esm/v3/tasks.js.map +1 -1
  331. package/dist/esm/v3/test/index.d.ts +5 -0
  332. package/dist/esm/v3/test/index.js +15 -0
  333. package/dist/esm/v3/test/index.js.map +1 -0
  334. package/dist/esm/v3/test/mock-channel-connector.d.ts +172 -0
  335. package/dist/esm/v3/test/mock-channel-connector.js +170 -0
  336. package/dist/esm/v3/test/mock-channel-connector.js.map +1 -0
  337. package/dist/esm/v3/test/mock-chat-agent.d.ts +388 -0
  338. package/dist/esm/v3/test/mock-chat-agent.js +685 -0
  339. package/dist/esm/v3/test/mock-chat-agent.js.map +1 -0
  340. package/dist/esm/v3/test/setup-catalog.d.ts +1 -0
  341. package/dist/esm/v3/test/setup-catalog.js +16 -0
  342. package/dist/esm/v3/test/setup-catalog.js.map +1 -0
  343. package/dist/esm/v3/test/test-session-handle.d.ts +24 -0
  344. package/dist/esm/v3/test/test-session-handle.js +268 -0
  345. package/dist/esm/v3/test/test-session-handle.js.map +1 -0
  346. package/dist/esm/v3/test/transcript-storage-tests.d.ts +40 -0
  347. package/dist/esm/v3/test/transcript-storage-tests.js +255 -0
  348. package/dist/esm/v3/test/transcript-storage-tests.js.map +1 -0
  349. package/dist/esm/v3/toolResultOrder.d.ts +15 -0
  350. package/dist/esm/v3/toolResultOrder.js +55 -0
  351. package/dist/esm/v3/toolResultOrder.js.map +1 -0
  352. package/dist/esm/v3/transcriptStorage.d.ts +307 -0
  353. package/dist/esm/v3/transcriptStorage.js +431 -0
  354. package/dist/esm/v3/transcriptStorage.js.map +1 -0
  355. package/dist/esm/v3/triggerClient.d.ts +45 -0
  356. package/dist/esm/v3/triggerClient.js +77 -0
  357. package/dist/esm/v3/triggerClient.js.map +1 -0
  358. package/dist/esm/v3/uiMessageChunks.d.ts +1 -0
  359. package/dist/esm/v3/uiMessageChunks.js +116 -0
  360. package/dist/esm/v3/uiMessageChunks.js.map +1 -0
  361. package/dist/esm/v3/usage.js +7 -6
  362. package/dist/esm/v3/usage.js.map +1 -1
  363. package/dist/esm/v3/wait.d.ts +218 -3
  364. package/dist/esm/v3/wait.js +431 -7
  365. package/dist/esm/v3/wait.js.map +1 -1
  366. package/dist/esm/v3/webhookWaiters.d.ts +80 -0
  367. package/dist/esm/v3/webhookWaiters.js +149 -0
  368. package/dist/esm/v3/webhookWaiters.js.map +1 -0
  369. package/dist/esm/v3/webhooks.d.ts +192 -2
  370. package/dist/esm/v3/webhooks.js +336 -2
  371. package/dist/esm/v3/webhooks.js.map +1 -1
  372. package/dist/esm/version.js +1 -1
  373. package/docs/ai/observability.mdx +174 -0
  374. package/docs/ai/prompts.mdx +426 -0
  375. package/docs/ai-chat/actions.mdx +148 -0
  376. package/docs/ai-chat/anatomy.mdx +87 -0
  377. package/docs/ai-chat/backend.mdx +933 -0
  378. package/docs/ai-chat/background-injection.mdx +320 -0
  379. package/docs/ai-chat/changelog.mdx +958 -0
  380. package/docs/ai-chat/chat-local.mdx +170 -0
  381. package/docs/ai-chat/client-protocol.mdx +1091 -0
  382. package/docs/ai-chat/compaction.mdx +413 -0
  383. package/docs/ai-chat/custom-agents.mdx +545 -0
  384. package/docs/ai-chat/error-handling.mdx +379 -0
  385. package/docs/ai-chat/fast-starts.mdx +764 -0
  386. package/docs/ai-chat/frontend.mdx +634 -0
  387. package/docs/ai-chat/how-it-works.mdx +226 -0
  388. package/docs/ai-chat/lifecycle-hooks.mdx +532 -0
  389. package/docs/ai-chat/mcp.mdx +97 -0
  390. package/docs/ai-chat/migrating-from-a-route-handler.mdx +594 -0
  391. package/docs/ai-chat/migrating-from-hydrate-messages.mdx +299 -0
  392. package/docs/ai-chat/overview.mdx +86 -0
  393. package/docs/ai-chat/patterns/branching-conversations.mdx +145 -0
  394. package/docs/ai-chat/patterns/code-sandbox.mdx +122 -0
  395. package/docs/ai-chat/patterns/database-persistence.mdx +425 -0
  396. package/docs/ai-chat/patterns/human-in-the-loop.mdx +281 -0
  397. package/docs/ai-chat/patterns/large-payloads.mdx +165 -0
  398. package/docs/ai-chat/patterns/native-compaction.mdx +310 -0
  399. package/docs/ai-chat/patterns/oom-resilience.mdx +116 -0
  400. package/docs/ai-chat/patterns/persistence-and-replay.mdx +218 -0
  401. package/docs/ai-chat/patterns/recovery-boot.mdx +233 -0
  402. package/docs/ai-chat/patterns/redacting-telemetry.mdx +117 -0
  403. package/docs/ai-chat/patterns/skills.mdx +214 -0
  404. package/docs/ai-chat/patterns/sub-agents.mdx +412 -0
  405. package/docs/ai-chat/patterns/tool-result-auditing.mdx +145 -0
  406. package/docs/ai-chat/patterns/trusted-edge-signals.mdx +333 -0
  407. package/docs/ai-chat/patterns/version-upgrades.mdx +261 -0
  408. package/docs/ai-chat/pending-messages.mdx +363 -0
  409. package/docs/ai-chat/prompt-caching.mdx +204 -0
  410. package/docs/ai-chat/quick-start.mdx +163 -0
  411. package/docs/ai-chat/reference.mdx +1071 -0
  412. package/docs/ai-chat/server-chat.mdx +259 -0
  413. package/docs/ai-chat/sessions.mdx +334 -0
  414. package/docs/ai-chat/side-channels.mdx +172 -0
  415. package/docs/ai-chat/testing.mdx +691 -0
  416. package/docs/ai-chat/tools.mdx +192 -0
  417. package/docs/ai-chat/transcript-storage.mdx +247 -0
  418. package/docs/ai-chat/types.mdx +242 -0
  419. package/docs/ai-chat/upgrade-guide.mdx +511 -0
  420. package/docs/apikeys.mdx +170 -0
  421. package/docs/billing-limits.mdx +73 -0
  422. package/docs/building-with-ai.mdx +261 -0
  423. package/docs/bulk-actions.mdx +77 -0
  424. package/docs/changelog.mdx +6 -0
  425. package/docs/cli-deploy-commands.mdx +9 -0
  426. package/docs/cli-dev-commands.mdx +9 -0
  427. package/docs/cli-env-commands.mdx +115 -0
  428. package/docs/cli-init-commands.mdx +84 -0
  429. package/docs/cli-introduction.mdx +25 -0
  430. package/docs/cli-list-profiles-commands.mdx +42 -0
  431. package/docs/cli-login-commands.mdx +53 -0
  432. package/docs/cli-logout-commands.mdx +33 -0
  433. package/docs/cli-preview-archive.mdx +59 -0
  434. package/docs/cli-projects-commands.mdx +74 -0
  435. package/docs/cli-promote-commands.mdx +9 -0
  436. package/docs/cli-runs-commands.mdx +95 -0
  437. package/docs/cli-switch.mdx +43 -0
  438. package/docs/cli-tasks-commands.mdx +95 -0
  439. package/docs/cli-update-commands.mdx +48 -0
  440. package/docs/cli-whoami-commands.mdx +45 -0
  441. package/docs/community.mdx +6 -0
  442. package/docs/concurrency.mdx +416 -0
  443. package/docs/config/config-file.mdx +662 -0
  444. package/docs/config/extensions/additionalFiles.mdx +38 -0
  445. package/docs/config/extensions/additionalPackages.mdx +40 -0
  446. package/docs/config/extensions/aptGet.mdx +34 -0
  447. package/docs/config/extensions/audioWaveform.mdx +23 -0
  448. package/docs/config/extensions/custom.mdx +393 -0
  449. package/docs/config/extensions/emitDecoratorMetadata.mdx +52 -0
  450. package/docs/config/extensions/esbuildPlugin.mdx +31 -0
  451. package/docs/config/extensions/ffmpeg.mdx +45 -0
  452. package/docs/config/extensions/lightpanda.mdx +56 -0
  453. package/docs/config/extensions/overview.mdx +69 -0
  454. package/docs/config/extensions/playwright.mdx +195 -0
  455. package/docs/config/extensions/prismaExtension.mdx +1013 -0
  456. package/docs/config/extensions/puppeteer.mdx +28 -0
  457. package/docs/config/extensions/pythonExtension.mdx +190 -0
  458. package/docs/config/extensions/syncEnvVars.mdx +330 -0
  459. package/docs/context.mdx +235 -0
  460. package/docs/database-connections.mdx +213 -0
  461. package/docs/deploy-environment-variables.mdx +466 -0
  462. package/docs/deployment/atomic-deployment.mdx +470 -0
  463. package/docs/deployment/dev-branches.mdx +92 -0
  464. package/docs/deployment/overview.mdx +260 -0
  465. package/docs/deployment/preview-branches.mdx +227 -0
  466. package/docs/errors-retrying.mdx +383 -0
  467. package/docs/github-actions.mdx +260 -0
  468. package/docs/github-integration.mdx +148 -0
  469. package/docs/github-repo.mdx +8 -0
  470. package/docs/help-email.mdx +6 -0
  471. package/docs/help-slack.mdx +12 -0
  472. package/docs/hidden-tasks.mdx +56 -0
  473. package/docs/how-it-works.mdx +454 -0
  474. package/docs/how-to-reduce-your-spend.mdx +211 -0
  475. package/docs/idempotency.mdx +542 -0
  476. package/docs/introduction.mdx +135 -0
  477. package/docs/limits.mdx +284 -0
  478. package/docs/logging.mdx +195 -0
  479. package/docs/machines.mdx +952 -0
  480. package/docs/manual-setup.mdx +632 -0
  481. package/docs/mcp-agent-rules.mdx +41 -0
  482. package/docs/mcp-introduction.mdx +386 -0
  483. package/docs/mcp-tools.mdx +425 -0
  484. package/docs/migrating-from-v3.mdx +332 -0
  485. package/docs/observability/dashboards.mdx +166 -0
  486. package/docs/observability/query.mdx +614 -0
  487. package/docs/open-source-contributing.mdx +16 -0
  488. package/docs/private-networking/aws-console-setup.mdx +304 -0
  489. package/docs/private-networking/overview.mdx +144 -0
  490. package/docs/private-networking/troubleshooting.mdx +78 -0
  491. package/docs/queues.mdx +271 -0
  492. package/docs/quick-start.mdx +60 -0
  493. package/docs/realtime/auth.mdx +228 -0
  494. package/docs/realtime/backend/input-streams.mdx +159 -0
  495. package/docs/realtime/backend/overview.mdx +45 -0
  496. package/docs/realtime/backend/streams.mdx +433 -0
  497. package/docs/realtime/backend/subscribe.mdx +225 -0
  498. package/docs/realtime/how-it-works.mdx +94 -0
  499. package/docs/realtime/overview.mdx +63 -0
  500. package/docs/realtime/react-hooks/overview.mdx +73 -0
  501. package/docs/realtime/react-hooks/session-stream.mdx +126 -0
  502. package/docs/realtime/react-hooks/streams.mdx +517 -0
  503. package/docs/realtime/react-hooks/subscribe.mdx +690 -0
  504. package/docs/realtime/react-hooks/swr.mdx +87 -0
  505. package/docs/realtime/react-hooks/triggering.mdx +194 -0
  506. package/docs/realtime/react-hooks/use-wait-token.mdx +34 -0
  507. package/docs/realtime/run-object.mdx +197 -0
  508. package/docs/replaying.mdx +97 -0
  509. package/docs/reports.mdx +159 -0
  510. package/docs/request-feature.mdx +6 -0
  511. package/docs/roadmap.mdx +6 -0
  512. package/docs/run-tests.mdx +21 -0
  513. package/docs/run-usage.mdx +113 -0
  514. package/docs/runs/bulk-actions.mdx +183 -0
  515. package/docs/runs/heartbeats.mdx +38 -0
  516. package/docs/runs/list-best-practices.mdx +234 -0
  517. package/docs/runs/max-duration.mdx +143 -0
  518. package/docs/runs/metadata.mdx +731 -0
  519. package/docs/runs/priority.mdx +8 -0
  520. package/docs/runs.mdx +406 -0
  521. package/docs/self-hosting/docker.mdx +512 -0
  522. package/docs/self-hosting/env/supervisor.mdx +78 -0
  523. package/docs/self-hosting/env/webapp.mdx +305 -0
  524. package/docs/self-hosting/kubernetes.mdx +725 -0
  525. package/docs/self-hosting/overview.mdx +145 -0
  526. package/docs/self-hosting/security.mdx +67 -0
  527. package/docs/skills.mdx +85 -0
  528. package/docs/tags.mdx +126 -0
  529. package/docs/tasks/overview.mdx +695 -0
  530. package/docs/tasks/scheduled.mdx +479 -0
  531. package/docs/tasks/schemaTask.mdx +413 -0
  532. package/docs/tasks/streams.mdx +887 -0
  533. package/docs/triggering.mdx +1340 -0
  534. package/docs/troubleshooting-alerts.mdx +607 -0
  535. package/docs/troubleshooting-debugging-in-vscode.mdx +9 -0
  536. package/docs/troubleshooting-github-issues.mdx +6 -0
  537. package/docs/troubleshooting-uptime-status.mdx +7 -0
  538. package/docs/troubleshooting-zod.mdx +158 -0
  539. package/docs/troubleshooting.mdx +414 -0
  540. package/docs/upgrading-packages.mdx +80 -0
  541. package/docs/vercel-integration.mdx +250 -0
  542. package/docs/versioning.mdx +58 -0
  543. package/docs/video-walkthrough.mdx +23 -0
  544. package/docs/wait-for-token.mdx +540 -0
  545. package/docs/wait-for.mdx +42 -0
  546. package/docs/wait-until.mdx +53 -0
  547. package/docs/wait.mdx +18 -0
  548. package/docs/webhooks/channels.mdx +154 -0
  549. package/docs/webhooks/connect.mdx +91 -0
  550. package/docs/webhooks/deliveries.mdx +99 -0
  551. package/docs/webhooks/filters.mdx +146 -0
  552. package/docs/webhooks/human-in-the-loop.mdx +158 -0
  553. package/docs/webhooks/linear.mdx +186 -0
  554. package/docs/webhooks/overview.mdx +115 -0
  555. package/docs/webhooks/session-routing.mdx +141 -0
  556. package/docs/webhooks/slack.mdx +393 -0
  557. package/docs/webhooks/sources.mdx +250 -0
  558. package/docs/webhooks/waiters.mdx +190 -0
  559. package/docs/writing-tasks-introduction.mdx +34 -0
  560. package/package.json +143 -42
  561. package/skills/trigger-authoring-chat-agent/SKILL.md +308 -0
  562. package/skills/trigger-authoring-tasks/SKILL.md +254 -0
  563. package/skills/trigger-chat-agent-advanced/SKILL.md +403 -0
  564. package/skills/trigger-cost-savings/SKILL.md +116 -0
  565. package/skills/trigger-realtime-and-frontend/SKILL.md +276 -0
  566. package/dist/commonjs/apiClient.d.ts +0 -727
  567. package/dist/commonjs/apiClient.js +0 -692
  568. package/dist/commonjs/apiClient.js.map +0 -1
  569. package/dist/commonjs/concurrencyLimit.d.ts +0 -10
  570. package/dist/commonjs/concurrencyLimit.js +0 -17
  571. package/dist/commonjs/concurrencyLimit.js.map +0 -1
  572. package/dist/commonjs/errors.d.ts +0 -66
  573. package/dist/commonjs/errors.js +0 -109
  574. package/dist/commonjs/errors.js.map +0 -1
  575. package/dist/commonjs/httpEndpoint.d.ts +0 -87
  576. package/dist/commonjs/httpEndpoint.js +0 -130
  577. package/dist/commonjs/httpEndpoint.js.map +0 -1
  578. package/dist/commonjs/index.d.ts +0 -23
  579. package/dist/commonjs/index.js +0 -55
  580. package/dist/commonjs/index.js.map +0 -1
  581. package/dist/commonjs/integrations.d.ts +0 -11
  582. package/dist/commonjs/integrations.js.map +0 -1
  583. package/dist/commonjs/io.d.ts +0 -441
  584. package/dist/commonjs/io.js +0 -1165
  585. package/dist/commonjs/io.js.map +0 -1
  586. package/dist/commonjs/ioWithIntegrations.d.ts +0 -4
  587. package/dist/commonjs/ioWithIntegrations.js +0 -32
  588. package/dist/commonjs/ioWithIntegrations.js.map +0 -1
  589. package/dist/commonjs/job.d.ts +0 -96
  590. package/dist/commonjs/job.js +0 -210
  591. package/dist/commonjs/job.js.map +0 -1
  592. package/dist/commonjs/retry.d.ts +0 -20
  593. package/dist/commonjs/retry.js +0 -22
  594. package/dist/commonjs/retry.js.map +0 -1
  595. package/dist/commonjs/runLocalStorage.d.ts +0 -8
  596. package/dist/commonjs/runLocalStorage.js +0 -6
  597. package/dist/commonjs/runLocalStorage.js.map +0 -1
  598. package/dist/commonjs/security.d.ts +0 -18
  599. package/dist/commonjs/security.js +0 -41
  600. package/dist/commonjs/security.js.map +0 -1
  601. package/dist/commonjs/status.d.ts +0 -19
  602. package/dist/commonjs/status.js +0 -38
  603. package/dist/commonjs/status.js.map +0 -1
  604. package/dist/commonjs/store/keyValueStore.d.ts +0 -17
  605. package/dist/commonjs/store/keyValueStore.js +0 -138
  606. package/dist/commonjs/store/keyValueStore.js.map +0 -1
  607. package/dist/commonjs/store/keyValueStoreClient.d.ts +0 -19
  608. package/dist/commonjs/store/keyValueStoreClient.js +0 -65
  609. package/dist/commonjs/store/keyValueStoreClient.js.map +0 -1
  610. package/dist/commonjs/triggerClient.d.ts +0 -290
  611. package/dist/commonjs/triggerClient.js +0 -1366
  612. package/dist/commonjs/triggerClient.js.map +0 -1
  613. package/dist/commonjs/triggers/dynamic.d.ts +0 -56
  614. package/dist/commonjs/triggers/dynamic.js +0 -97
  615. package/dist/commonjs/triggers/dynamic.js.map +0 -1
  616. package/dist/commonjs/triggers/eventTrigger.d.ts +0 -58
  617. package/dist/commonjs/triggers/eventTrigger.js +0 -69
  618. package/dist/commonjs/triggers/eventTrigger.js.map +0 -1
  619. package/dist/commonjs/triggers/externalSource.d.ts +0 -148
  620. package/dist/commonjs/triggers/externalSource.js +0 -106
  621. package/dist/commonjs/triggers/externalSource.js.map +0 -1
  622. package/dist/commonjs/triggers/invokeTrigger.d.ts +0 -39
  623. package/dist/commonjs/triggers/invokeTrigger.js +0 -58
  624. package/dist/commonjs/triggers/invokeTrigger.js.map +0 -1
  625. package/dist/commonjs/triggers/notifications.d.ts +0 -111
  626. package/dist/commonjs/triggers/notifications.js +0 -101
  627. package/dist/commonjs/triggers/notifications.js.map +0 -1
  628. package/dist/commonjs/triggers/scheduled.d.ts +0 -145
  629. package/dist/commonjs/triggers/scheduled.js +0 -208
  630. package/dist/commonjs/triggers/scheduled.js.map +0 -1
  631. package/dist/commonjs/triggers/webhook.d.ts +0 -143
  632. package/dist/commonjs/triggers/webhook.js +0 -133
  633. package/dist/commonjs/triggers/webhook.js.map +0 -1
  634. package/dist/commonjs/typed-emitter.d.ts +0 -37
  635. package/dist/commonjs/typed-emitter.js +0 -3
  636. package/dist/commonjs/typed-emitter.js.map +0 -1
  637. package/dist/commonjs/types.d.ts +0 -204
  638. package/dist/commonjs/types.js +0 -23
  639. package/dist/commonjs/types.js.map +0 -1
  640. package/dist/commonjs/utils/formatSchemaErrors.d.ts +0 -3
  641. package/dist/commonjs/utils/formatSchemaErrors.js +0 -10
  642. package/dist/commonjs/utils/formatSchemaErrors.js.map +0 -1
  643. package/dist/commonjs/utils/typedAsyncLocalStorage.d.ts +0 -6
  644. package/dist/commonjs/utils/typedAsyncLocalStorage.js +0 -18
  645. package/dist/commonjs/utils/typedAsyncLocalStorage.js.map +0 -1
  646. package/dist/commonjs/utils.d.ts +0 -1
  647. package/dist/commonjs/utils.js +0 -11
  648. package/dist/commonjs/utils.js.map +0 -1
  649. package/dist/esm/apiClient.d.ts +0 -727
  650. package/dist/esm/apiClient.js +0 -687
  651. package/dist/esm/apiClient.js.map +0 -1
  652. package/dist/esm/concurrencyLimit.d.ts +0 -10
  653. package/dist/esm/concurrencyLimit.js +0 -13
  654. package/dist/esm/concurrencyLimit.js.map +0 -1
  655. package/dist/esm/errors.d.ts +0 -66
  656. package/dist/esm/errors.js +0 -95
  657. package/dist/esm/errors.js.map +0 -1
  658. package/dist/esm/httpEndpoint.d.ts +0 -87
  659. package/dist/esm/httpEndpoint.js +0 -125
  660. package/dist/esm/httpEndpoint.js.map +0 -1
  661. package/dist/esm/index.d.ts +0 -23
  662. package/dist/esm/index.js +0 -35
  663. package/dist/esm/index.js.map +0 -1
  664. package/dist/esm/integrations.d.ts +0 -11
  665. package/dist/esm/integrations.js +0 -2
  666. package/dist/esm/integrations.js.map +0 -1
  667. package/dist/esm/io.d.ts +0 -441
  668. package/dist/esm/io.js +0 -1159
  669. package/dist/esm/io.js.map +0 -1
  670. package/dist/esm/ioWithIntegrations.d.ts +0 -4
  671. package/dist/esm/ioWithIntegrations.js +0 -29
  672. package/dist/esm/ioWithIntegrations.js.map +0 -1
  673. package/dist/esm/job.d.ts +0 -96
  674. package/dist/esm/job.js +0 -206
  675. package/dist/esm/job.js.map +0 -1
  676. package/dist/esm/retry.d.ts +0 -20
  677. package/dist/esm/retry.js +0 -19
  678. package/dist/esm/retry.js.map +0 -1
  679. package/dist/esm/runLocalStorage.d.ts +0 -8
  680. package/dist/esm/runLocalStorage.js +0 -3
  681. package/dist/esm/runLocalStorage.js.map +0 -1
  682. package/dist/esm/security.d.ts +0 -18
  683. package/dist/esm/security.js +0 -34
  684. package/dist/esm/security.js.map +0 -1
  685. package/dist/esm/status.d.ts +0 -19
  686. package/dist/esm/status.js +0 -34
  687. package/dist/esm/status.js.map +0 -1
  688. package/dist/esm/store/keyValueStore.d.ts +0 -17
  689. package/dist/esm/store/keyValueStore.js +0 -134
  690. package/dist/esm/store/keyValueStore.js.map +0 -1
  691. package/dist/esm/store/keyValueStoreClient.d.ts +0 -19
  692. package/dist/esm/store/keyValueStoreClient.js +0 -61
  693. package/dist/esm/store/keyValueStoreClient.js.map +0 -1
  694. package/dist/esm/triggerClient.d.ts +0 -288
  695. package/dist/esm/triggerClient.js +0 -1359
  696. package/dist/esm/triggerClient.js.map +0 -1
  697. package/dist/esm/triggers/dynamic.d.ts +0 -56
  698. package/dist/esm/triggers/dynamic.js +0 -93
  699. package/dist/esm/triggers/dynamic.js.map +0 -1
  700. package/dist/esm/triggers/eventTrigger.d.ts +0 -58
  701. package/dist/esm/triggers/eventTrigger.js +0 -64
  702. package/dist/esm/triggers/eventTrigger.js.map +0 -1
  703. package/dist/esm/triggers/externalSource.d.ts +0 -148
  704. package/dist/esm/triggers/externalSource.js +0 -100
  705. package/dist/esm/triggers/externalSource.js.map +0 -1
  706. package/dist/esm/triggers/invokeTrigger.d.ts +0 -39
  707. package/dist/esm/triggers/invokeTrigger.js +0 -53
  708. package/dist/esm/triggers/invokeTrigger.js.map +0 -1
  709. package/dist/esm/triggers/notifications.d.ts +0 -111
  710. package/dist/esm/triggers/notifications.js +0 -94
  711. package/dist/esm/triggers/notifications.js.map +0 -1
  712. package/dist/esm/triggers/scheduled.d.ts +0 -145
  713. package/dist/esm/triggers/scheduled.js +0 -197
  714. package/dist/esm/triggers/scheduled.js.map +0 -1
  715. package/dist/esm/triggers/webhook.d.ts +0 -143
  716. package/dist/esm/triggers/webhook.js +0 -128
  717. package/dist/esm/triggers/webhook.js.map +0 -1
  718. package/dist/esm/typed-emitter.d.ts +0 -37
  719. package/dist/esm/typed-emitter.js +0 -2
  720. package/dist/esm/typed-emitter.js.map +0 -1
  721. package/dist/esm/types.d.ts +0 -204
  722. package/dist/esm/types.js +0 -19
  723. package/dist/esm/types.js.map +0 -1
  724. package/dist/esm/utils/formatSchemaErrors.d.ts +0 -3
  725. package/dist/esm/utils/formatSchemaErrors.js +0 -7
  726. package/dist/esm/utils/formatSchemaErrors.js.map +0 -1
  727. package/dist/esm/utils/typedAsyncLocalStorage.d.ts +0 -6
  728. package/dist/esm/utils/typedAsyncLocalStorage.js +0 -14
  729. package/dist/esm/utils/typedAsyncLocalStorage.js.map +0 -1
  730. package/dist/esm/utils.d.ts +0 -1
  731. package/dist/esm/utils.js +0 -8
  732. package/dist/esm/utils.js.map +0 -1
@@ -1,43 +1,121 @@
1
1
  import { SpanKind } from "@opentelemetry/api";
2
- import { accessoryAttributes, apiClientManager, conditionallyImportPacket, convertToolParametersToSchema, createErrorTaskError, defaultRetryOptions, getSchemaParseFn, makeIdempotencyKey, parsePacket, runtime, SemanticInternalAttributes, stringifyIO, SubtaskUnwrapError, taskCatalog, taskContext, TaskRunPromise, } from "@trigger.dev/core/v3";
3
- import { runs } from "./runs.js";
2
+ import { accessoryAttributes, apiClientManager, ApiError, conditionallyExportPacket, conditionallyImportPacket, convertToolParametersToSchema, createErrorFromCauses, createErrorTaskError, defaultRetryOptions, flattenIdempotencyKey, generateFriendlyId, getIdempotencyKeyOptions, getSchemaParseFn, lifecycleHooks, makeIdempotencyKey, packetRequiresOffloading, parsePacket, RateLimitError, resourceCatalog, runtime, SemanticInternalAttributes, stringifyIO, SubtaskUnwrapError, taskContext, TaskRunPromise, } from "@trigger.dev/core/v3";
3
+ import { resolveTriggerExternalDeploymentId, scopedEnvVar } from "./externalDeploymentId.js";
4
4
  import { tracer } from "./tracer.js";
5
+ import { triggerConcurrencyBody, validateConcurrencyLimitName } from "./concurrency-shared.js";
5
6
  export { SubtaskUnwrapError, TaskRunPromise };
7
+ /** A task's `queue` is a queue object or a string reference to a queue defined elsewhere. */
8
+ function normalizeTaskQueue(queue) {
9
+ if (!queue) {
10
+ return {};
11
+ }
12
+ return { queue: typeof queue === "string" ? { name: queue } : queue };
13
+ }
14
+ /**
15
+ * Validates and normalizes the task `concurrency` option into its manifest shape:
16
+ * at most one inline limit (caps this task) plus up to two named limits (shared).
17
+ */
18
+ function normalizeTaskConcurrency(taskId, concurrency) {
19
+ if (!concurrency) {
20
+ return undefined;
21
+ }
22
+ const items = Array.isArray(concurrency) ? concurrency : [concurrency];
23
+ const inline = [];
24
+ const limits = [];
25
+ for (const item of items) {
26
+ if (typeof item === "string") {
27
+ limits.push(item);
28
+ }
29
+ else if (item &&
30
+ typeof item === "object" &&
31
+ "name" in item &&
32
+ typeof item.name === "string") {
33
+ validateConcurrencyLimitName(item.name);
34
+ resourceCatalog.registerConcurrencyLimitMetadata(item);
35
+ limits.push(item.name);
36
+ }
37
+ else if (item && typeof item === "object") {
38
+ inline.push({ perKey: item.perKey, total: item.total });
39
+ }
40
+ }
41
+ if (inline.length > 1) {
42
+ throw new Error(`Task "${taskId}": concurrency accepts at most one inline limit. Give shared limits a name with concurrencyLimit().`);
43
+ }
44
+ if (limits.length > 2) {
45
+ throw new Error(`Task "${taskId}": concurrency accepts at most two named limits.`);
46
+ }
47
+ return {
48
+ inline: inline[0],
49
+ limits: limits.length > 0 ? limits : undefined,
50
+ };
51
+ }
52
+ /** Builds the queue field of a trigger request body. */
53
+ function triggerQueueBody(queue, fallbackQueueName) {
54
+ const name = queue ?? fallbackQueueName;
55
+ return { queue: name ? { name } : undefined };
56
+ }
6
57
  export function queue(options) {
58
+ resourceCatalog.registerQueueMetadata(options);
59
+ // @ts-expect-error
60
+ options[Symbol.for("trigger.dev/queue")] = true;
61
+ return options;
62
+ }
63
+ /**
64
+ * Declares a named, shareable concurrency limit. Tasks hold it via their `concurrency`
65
+ * option; every task holding the same limit draws from the same pools.
66
+ *
67
+ * @example
68
+ *
69
+ * ```ts
70
+ * export const openaiLimit = concurrencyLimit({ name: "openai", total: 25 });
71
+ *
72
+ * export const generateSummary = task({
73
+ * id: "generate-summary",
74
+ * concurrency: [{ total: 5 }, openaiLimit],
75
+ * run: async (payload) => {},
76
+ * });
77
+ * ```
78
+ */
79
+ export function concurrencyLimit(options) {
80
+ validateConcurrencyLimitName(options.name);
81
+ resourceCatalog.registerConcurrencyLimitMetadata(options);
82
+ // @ts-expect-error
83
+ options[Symbol.for("trigger.dev/concurrencyLimit")] = true;
7
84
  return options;
8
85
  }
9
86
  export function createTask(params) {
10
- const customQueue = params.queue
11
- ? queue({
12
- name: params.queue?.name ?? `task/${params.id}`,
13
- ...params.queue,
14
- })
15
- : undefined;
87
+ const normalizedQueue = normalizeTaskQueue(params.queue);
16
88
  const task = {
17
89
  id: params.id,
18
90
  description: params.description,
91
+ jsonSchema: params.jsonSchema,
19
92
  trigger: async (payload, options) => {
20
- const taskMetadata = taskCatalog.getTaskManifest(params.id);
21
- return await trigger_internal(taskMetadata && taskMetadata.exportName
22
- ? `${taskMetadata.exportName}.trigger()`
23
- : `trigger()`, params.id, payload, undefined, {
24
- queue: customQueue,
93
+ return await trigger_internal("trigger()", params.id, payload, undefined, {
94
+ queue: normalizedQueue.queue?.name,
25
95
  ...options,
26
96
  });
27
97
  },
28
98
  batchTrigger: async (items, options) => {
29
- const taskMetadata = taskCatalog.getTaskManifest(params.id);
30
- return await batchTrigger_internal(taskMetadata && taskMetadata.exportName
31
- ? `${taskMetadata.exportName}.batchTrigger()`
32
- : `batchTrigger()`, params.id, items, options, undefined, undefined, customQueue);
99
+ return await batchTrigger_internal("batchTrigger()", params.id, items, options, undefined, undefined, normalizedQueue.queue?.name);
33
100
  },
34
- triggerAndWait: (payload, options) => {
35
- const taskMetadata = taskCatalog.getTaskManifest(params.id);
101
+ triggerAndWait: (payload, options, requestOptions) => {
102
+ return new TaskRunPromise((resolve, reject) => {
103
+ triggerAndWait_internal("triggerAndWait()", params.id, payload, undefined, {
104
+ queue: normalizedQueue.queue?.name,
105
+ ...options,
106
+ }, requestOptions)
107
+ .then((result) => {
108
+ resolve(result);
109
+ })
110
+ .catch((error) => {
111
+ reject(error);
112
+ });
113
+ }, params.id);
114
+ },
115
+ triggerAndSubscribe: (payload, options) => {
36
116
  return new TaskRunPromise((resolve, reject) => {
37
- triggerAndWait_internal(taskMetadata && taskMetadata.exportName
38
- ? `${taskMetadata.exportName}.triggerAndWait()`
39
- : `triggerAndWait()`, params.id, payload, undefined, {
40
- queue: customQueue,
117
+ triggerAndSubscribe_internal("triggerAndSubscribe()", params.id, payload, undefined, {
118
+ queue: normalizedQueue.queue?.name,
41
119
  ...options,
42
120
  })
43
121
  .then((result) => {
@@ -49,34 +127,46 @@ export function createTask(params) {
49
127
  }, params.id);
50
128
  },
51
129
  batchTriggerAndWait: async (items, options) => {
52
- const taskMetadata = taskCatalog.getTaskManifest(params.id);
53
- return await batchTriggerAndWait_internal(taskMetadata && taskMetadata.exportName
54
- ? `${taskMetadata.exportName}.batchTriggerAndWait()`
55
- : `batchTriggerAndWait()`, params.id, items, undefined, options, undefined, customQueue);
130
+ return await batchTriggerAndWait_internal("batchTriggerAndWait()", params.id, items, undefined, options, undefined, normalizedQueue.queue?.name);
56
131
  },
57
132
  };
58
- taskCatalog.registerTaskMetadata({
133
+ registerTaskLifecycleHooks(params.id, params);
134
+ resourceCatalog.registerTaskMetadata({
59
135
  id: params.id,
60
136
  description: params.description,
61
- queue: params.queue,
137
+ queue: normalizedQueue.queue,
138
+ concurrency: normalizeTaskConcurrency(params.id, params.concurrency),
62
139
  retry: params.retry ? { ...defaultRetryOptions, ...params.retry } : undefined,
63
140
  machine: typeof params.machine === "string" ? { preset: params.machine } : params.machine,
141
+ triggerSource: params.triggerSource,
142
+ agentConfig: params.agentConfig,
64
143
  maxDuration: params.maxDuration,
144
+ ttl: params.ttl,
145
+ payloadSchema: params.jsonSchema,
65
146
  fns: {
66
147
  run: params.run,
67
- init: params.init,
68
- cleanup: params.cleanup,
69
- middleware: params.middleware,
70
- handleError: params.handleError,
71
- onSuccess: params.onSuccess,
72
- onFailure: params.onFailure,
73
- onStart: params.onStart,
74
148
  },
75
149
  });
150
+ const queue = normalizedQueue.queue;
151
+ /**
152
+ * A string queue name (bare or as a tuple's first element) is a REFERENCE to a
153
+ * queue defined elsewhere; registering it would create an empty definition that
154
+ * can shadow the real one depending on module evaluation order.
155
+ */
156
+ const homeIsReference = typeof params.queue === "string";
157
+ if (queue && typeof queue.name === "string" && !homeIsReference) {
158
+ resourceCatalog.registerQueueMetadata({
159
+ name: queue.name,
160
+ concurrencyLimit: queue.concurrencyLimit,
161
+ });
162
+ }
76
163
  // @ts-expect-error
77
164
  task[Symbol.for("trigger.dev/task")] = true;
78
165
  return task;
79
166
  }
167
+ /**
168
+ * @deprecated Use `schemaTask` plus AI SDK `tool()` with `execute: ai.toolExecute(task)` instead.
169
+ */
80
170
  export function createToolTask(params) {
81
171
  const task = createSchemaTask({
82
172
  ...params,
@@ -94,41 +184,41 @@ export function createToolTask(params) {
94
184
  };
95
185
  }
96
186
  export function createSchemaTask(params) {
97
- const customQueue = params.queue
98
- ? queue({
99
- name: params.queue?.name ?? `task/${params.id}`,
100
- ...params.queue,
101
- })
102
- : undefined;
103
187
  const parsePayload = params.schema
104
188
  ? getSchemaParseFn(params.schema)
105
189
  : undefined;
190
+ const normalizedQueue = normalizeTaskQueue(params.queue);
106
191
  const task = {
107
192
  id: params.id,
108
193
  description: params.description,
109
194
  schema: params.schema,
110
195
  trigger: async (payload, options, requestOptions) => {
111
- const taskMetadata = taskCatalog.getTaskManifest(params.id);
112
- return await trigger_internal(taskMetadata && taskMetadata.exportName
113
- ? `${taskMetadata.exportName}.trigger()`
114
- : `trigger()`, params.id, payload, parsePayload, {
115
- queue: customQueue,
196
+ return await trigger_internal("trigger()", params.id, payload, parsePayload, {
197
+ queue: normalizedQueue.queue?.name,
116
198
  ...options,
117
199
  }, requestOptions);
118
200
  },
119
201
  batchTrigger: async (items, options, requestOptions) => {
120
- const taskMetadata = taskCatalog.getTaskManifest(params.id);
121
- return await batchTrigger_internal(taskMetadata && taskMetadata.exportName
122
- ? `${taskMetadata.exportName}.batchTrigger()`
123
- : `batchTrigger()`, params.id, items, options, parsePayload, requestOptions, customQueue);
202
+ return await batchTrigger_internal("batchTrigger()", params.id, items, options, parsePayload, requestOptions, normalizedQueue.queue?.name);
124
203
  },
125
204
  triggerAndWait: (payload, options) => {
126
- const taskMetadata = taskCatalog.getTaskManifest(params.id);
127
205
  return new TaskRunPromise((resolve, reject) => {
128
- triggerAndWait_internal(taskMetadata && taskMetadata.exportName
129
- ? `${taskMetadata.exportName}.triggerAndWait()`
130
- : `triggerAndWait()`, params.id, payload, parsePayload, {
131
- queue: customQueue,
206
+ triggerAndWait_internal("triggerAndWait()", params.id, payload, parsePayload, {
207
+ queue: normalizedQueue.queue?.name,
208
+ ...options,
209
+ })
210
+ .then((result) => {
211
+ resolve(result);
212
+ })
213
+ .catch((error) => {
214
+ reject(error);
215
+ });
216
+ }, params.id);
217
+ },
218
+ triggerAndSubscribe: (payload, options) => {
219
+ return new TaskRunPromise((resolve, reject) => {
220
+ triggerAndSubscribe_internal("triggerAndSubscribe()", params.id, payload, parsePayload, {
221
+ queue: normalizedQueue.queue?.name,
132
222
  ...options,
133
223
  })
134
224
  .then((result) => {
@@ -140,31 +230,40 @@ export function createSchemaTask(params) {
140
230
  }, params.id);
141
231
  },
142
232
  batchTriggerAndWait: async (items, options) => {
143
- const taskMetadata = taskCatalog.getTaskManifest(params.id);
144
- return await batchTriggerAndWait_internal(taskMetadata && taskMetadata.exportName
145
- ? `${taskMetadata.exportName}.batchTriggerAndWait()`
146
- : `batchTriggerAndWait()`, params.id, items, parsePayload, options, undefined, customQueue);
233
+ return await batchTriggerAndWait_internal("batchTriggerAndWait()", params.id, items, parsePayload, options, undefined, normalizedQueue.queue?.name);
147
234
  },
148
235
  };
149
- taskCatalog.registerTaskMetadata({
236
+ registerTaskLifecycleHooks(params.id, params);
237
+ resourceCatalog.registerTaskMetadata({
150
238
  id: params.id,
151
239
  description: params.description,
152
- queue: params.queue,
240
+ queue: normalizedQueue.queue,
241
+ concurrency: normalizeTaskConcurrency(params.id, params.concurrency),
153
242
  retry: params.retry ? { ...defaultRetryOptions, ...params.retry } : undefined,
154
243
  machine: typeof params.machine === "string" ? { preset: params.machine } : params.machine,
244
+ triggerSource: params.triggerSource,
245
+ agentConfig: params.agentConfig,
155
246
  maxDuration: params.maxDuration,
247
+ ttl: params.ttl,
156
248
  fns: {
157
249
  run: params.run,
158
- init: params.init,
159
- cleanup: params.cleanup,
160
- middleware: params.middleware,
161
- handleError: params.handleError,
162
- onSuccess: params.onSuccess,
163
- onFailure: params.onFailure,
164
- onStart: params.onStart,
165
250
  parsePayload,
166
251
  },
252
+ schema: params.schema,
167
253
  });
254
+ const queue = normalizedQueue.queue;
255
+ /**
256
+ * A string queue name (bare or as a tuple's first element) is a REFERENCE to a
257
+ * queue defined elsewhere; registering it would create an empty definition that
258
+ * can shadow the real one depending on module evaluation order.
259
+ */
260
+ const homeIsReference = typeof params.queue === "string";
261
+ if (queue && typeof queue.name === "string" && !homeIsReference) {
262
+ resourceCatalog.registerQueueMetadata({
263
+ name: queue.name,
264
+ concurrencyLimit: queue.concurrencyLimit,
265
+ });
266
+ }
168
267
  // @ts-expect-error
169
268
  task[Symbol.for("trigger.dev/task")] = true;
170
269
  return task;
@@ -217,6 +316,38 @@ export function triggerAndWait(id, payload, options, requestOptions) {
217
316
  });
218
317
  }, id);
219
318
  }
319
+ /**
320
+ * Trigger a task and subscribe to its updates via realtime. Unlike `triggerAndWait`,
321
+ * this does NOT suspend the parent run — the parent stays alive and subscribes to updates.
322
+ * This enables parallel execution and proper abort signal handling.
323
+ *
324
+ * @param id - The id of the task to trigger
325
+ * @param payload
326
+ * @param options - Options for the task run, including an optional `signal` to cancel the subscription and child run
327
+ * @returns TaskRunPromise
328
+ * @example
329
+ * ```ts
330
+ * import { tasks } from "@trigger.dev/sdk/v3";
331
+ * const result = await tasks.triggerAndSubscribe("my-task", { foo: "bar" });
332
+ *
333
+ * if (result.ok) {
334
+ * console.log(result.output);
335
+ * } else {
336
+ * console.error(result.error);
337
+ * }
338
+ * ```
339
+ */
340
+ export function triggerAndSubscribe(id, payload, options, requestOptions) {
341
+ return new TaskRunPromise((resolve, reject) => {
342
+ triggerAndSubscribe_internal("tasks.triggerAndSubscribe()", id, payload, undefined, options, requestOptions)
343
+ .then((result) => {
344
+ resolve(result);
345
+ })
346
+ .catch((error) => {
347
+ reject(error);
348
+ });
349
+ }, id);
350
+ }
220
351
  /**
221
352
  * Batch trigger multiple task runs with the given payloads, and wait for the results. Returns the results of the task runs.
222
353
  * @param id - The id of the task to trigger
@@ -244,597 +375,946 @@ export function triggerAndWait(id, payload, options, requestOptions) {
244
375
  export async function batchTriggerAndWait(id, items, options, requestOptions) {
245
376
  return await batchTriggerAndWait_internal("tasks.batchTriggerAndWait()", id, items, undefined, options, requestOptions);
246
377
  }
247
- /**
248
- * Trigger a task by its identifier with the given payload and poll until the run is completed.
249
- *
250
- * @example
251
- *
252
- * ```ts
253
- * import { tasks, runs } from "@trigger.dev/sdk/v3";
254
- * import type { myTask } from "./myTasks"; // Import just the type of the task
255
- *
256
- * const run = await tasks.triggerAndPoll<typeof myTask>("my-task", { foo: "bar" }); // The id and payload are fully typesafe
257
- * console.log(run.output) // The output is also fully typed
258
- * ```
259
- *
260
- * @returns {Run} The completed run, either successful or failed.
261
- */
262
- export async function triggerAndPoll(id, payload, options, requestOptions) {
263
- const handle = await trigger(id, payload, options, requestOptions);
264
- return runs.poll(handle, options, requestOptions);
265
- }
266
378
  export async function batchTrigger(id, items, options, requestOptions) {
267
379
  return await batchTrigger_internal("tasks.batchTrigger()", id, items, options, undefined, requestOptions);
268
380
  }
269
- /**
270
- * Triggers multiple runs of different tasks with specified payloads and options.
271
- *
272
- * @template TTask - The type of task(s) to be triggered, extends AnyTask
273
- *
274
- * @param {Array<BatchByIdItem<InferRunTypes<TTask>>>} items - Array of task items to trigger
275
- * @param {BatchTriggerOptions} [options] - Optional batch-level trigger options
276
- * @param {TriggerApiRequestOptions} [requestOptions] - Optional API request configuration
277
- *
278
- * @returns {Promise<BatchRunHandleFromTypes<InferRunTypes<TTask>>>} A promise that resolves with the batch run handle
279
- * containing batch ID, cached status, idempotency info, runs, and public access token
280
- *
281
- * @example
282
- * ```ts
283
- * import { batch } from "@trigger.dev/sdk/v3";
284
- * import type { myTask1, myTask2 } from "~/trigger/myTasks";
285
- *
286
- * // Trigger multiple tasks with different payloads
287
- * const result = await batch.trigger<typeof myTask1 | typeof myTask2>([
288
- * {
289
- * id: "my-task-1",
290
- * payload: { some: "data" },
291
- * options: {
292
- * queue: "default",
293
- * concurrencyKey: "key",
294
- * idempotencyKey: "unique-key",
295
- * delay: "5m",
296
- * tags: ["tag1", "tag2"]
297
- * }
298
- * },
299
- * {
300
- * id: "my-task-2",
301
- * payload: { other: "data" }
302
- * }
303
- * ]);
304
- * ```
305
- *
306
- * @description
307
- * Each task item in the array can include:
308
- * - `id`: The unique identifier of the task
309
- * - `payload`: The data to pass to the task
310
- * - `options`: Optional task-specific settings including:
311
- * - `queue`: Specify a queue for the task
312
- * - `concurrencyKey`: Control concurrent execution
313
- * - `idempotencyKey`: Prevent duplicate runs
314
- * - `idempotencyKeyTTL`: Time-to-live for idempotency key
315
- * - `delay`: Delay before task execution
316
- * - `ttl`: Time-to-live for the task
317
- * - `tags`: Array of tags for the task
318
- * - `maxAttempts`: Maximum retry attempts
319
- * - `metadata`: Additional metadata
320
- * - `maxDuration`: Maximum execution duration
321
- */
322
- export async function batchTriggerById(items, options, requestOptions) {
323
- const apiClient = apiClientManager.clientOrThrow();
324
- const response = await apiClient.batchTriggerV2({
325
- items: await Promise.all(items.map(async (item) => {
326
- const taskMetadata = taskCatalog.getTask(item.id);
381
+ // Implementation
382
+ export async function batchTriggerById(...args) {
383
+ const [items, options, requestOptions] = args;
384
+ const apiClient = apiClientManager.clientOrThrow(requestOptions?.clientConfig);
385
+ // Check if items is an array or a stream
386
+ if (Array.isArray(items)) {
387
+ // Array path: existing logic
388
+ const ndJsonItems = await Promise.all(items.map(async (item, index) => {
389
+ const taskMetadata = resourceCatalog.getTask(item.id);
327
390
  const parsedPayload = taskMetadata?.fns.parsePayload
328
391
  ? await taskMetadata?.fns.parsePayload(item.payload)
329
392
  : item.payload;
330
393
  const payloadPacket = await stringifyIO(parsedPayload);
394
+ const batchItemIdempotencyKey = await makeIdempotencyKey(flattenIdempotencyKey([options?.idempotencyKey, `${index}`]));
331
395
  return {
396
+ index,
332
397
  task: item.id,
333
398
  payload: payloadPacket.data,
334
399
  options: {
335
- queue: item.options?.queue,
400
+ ...triggerQueueBody(item.options?.queue),
401
+ ...triggerConcurrencyBody(item.options?.concurrency),
336
402
  concurrencyKey: item.options?.concurrencyKey,
337
403
  test: taskContext.ctx?.run.isTest,
338
404
  payloadType: payloadPacket.dataType,
339
- idempotencyKey: await makeIdempotencyKey(item.options?.idempotencyKey),
340
- idempotencyKeyTTL: item.options?.idempotencyKeyTTL,
341
405
  delay: item.options?.delay,
342
406
  ttl: item.options?.ttl,
343
407
  tags: item.options?.tags,
344
408
  maxAttempts: item.options?.maxAttempts,
345
- parentAttempt: taskContext.ctx?.attempt.id,
346
409
  metadata: item.options?.metadata,
347
410
  maxDuration: item.options?.maxDuration,
411
+ idempotencyKey: (await makeIdempotencyKey(item.options?.idempotencyKey)) ?? batchItemIdempotencyKey,
412
+ idempotencyKeyTTL: item.options?.idempotencyKeyTTL ?? options?.idempotencyKeyTTL,
348
413
  machine: item.options?.machine,
414
+ priority: item.options?.priority,
415
+ region: item.options?.region,
416
+ lockToVersion: item.options?.version ?? scopedEnvVar("TRIGGER_VERSION"),
417
+ externalDeploymentId: resolveTriggerExternalDeploymentId(item.options?.externalDeploymentId),
418
+ debounce: item.options?.debounce,
349
419
  },
350
420
  };
351
- })),
352
- }, {
353
- spanParentAsLink: true,
354
- idempotencyKey: await makeIdempotencyKey(options?.idempotencyKey),
355
- idempotencyKeyTTL: options?.idempotencyKeyTTL,
356
- processingStrategy: options?.triggerSequentially ? "sequential" : undefined,
357
- }, {
358
- name: "batch.trigger()",
359
- tracer,
360
- icon: "trigger",
361
- onResponseBody(body, span) {
362
- if (body && typeof body === "object" && !Array.isArray(body)) {
363
- if ("id" in body && typeof body.id === "string") {
364
- span.setAttribute("batchId", body.id);
365
- }
366
- if ("runs" in body && Array.isArray(body.runs)) {
367
- span.setAttribute("runCount", body.runs.length);
368
- }
369
- if ("isCached" in body && typeof body.isCached === "boolean") {
370
- if (body.isCached) {
371
- console.warn(`Result is a cached response because the request was idempotent.`);
372
- }
373
- span.setAttribute("isCached", body.isCached);
374
- }
375
- if ("idempotencyKey" in body && typeof body.idempotencyKey === "string") {
376
- span.setAttribute("idempotencyKey", body.idempotencyKey);
377
- }
378
- }
379
- },
380
- ...requestOptions,
381
- });
382
- const handle = {
383
- batchId: response.id,
384
- isCached: response.isCached,
385
- idempotencyKey: response.idempotencyKey,
386
- runs: response.runs,
387
- publicAccessToken: response.publicAccessToken,
388
- };
389
- return handle;
421
+ }));
422
+ // Execute 2-phase batch
423
+ const response = await tracer.startActiveSpan("batch.trigger()", async (span) => {
424
+ const result = await executeBatchTwoPhase(apiClient, ndJsonItems, {
425
+ parentRunId: taskContext.ctx?.run.id,
426
+ idempotencyKey: await makeIdempotencyKey(options?.idempotencyKey),
427
+ spanParentAsLink: true, // Fire-and-forget: child runs get separate trace IDs
428
+ }, requestOptions);
429
+ span.setAttribute("batchId", result.id);
430
+ span.setAttribute("runCount", result.runCount);
431
+ return result;
432
+ }, {
433
+ kind: SpanKind.PRODUCER,
434
+ attributes: {
435
+ [SemanticInternalAttributes.STYLE_ICON]: "trigger",
436
+ },
437
+ });
438
+ const handle = {
439
+ batchId: response.id,
440
+ runCount: response.runCount,
441
+ publicAccessToken: response.publicAccessToken,
442
+ };
443
+ return handle;
444
+ }
445
+ else {
446
+ // Stream path: convert to AsyncIterable and transform
447
+ const asyncItems = normalizeToAsyncIterable(items);
448
+ const transformedItems = transformBatchItemsStream(asyncItems, options);
449
+ // Execute streaming 2-phase batch
450
+ const response = await tracer.startActiveSpan("batch.trigger()", async (span) => {
451
+ const result = await executeBatchTwoPhaseStreaming(apiClient, transformedItems, {
452
+ parentRunId: taskContext.ctx?.run.id,
453
+ idempotencyKey: await makeIdempotencyKey(options?.idempotencyKey),
454
+ spanParentAsLink: true, // Fire-and-forget: child runs get separate trace IDs
455
+ }, requestOptions);
456
+ span.setAttribute("batchId", result.id);
457
+ span.setAttribute("runCount", result.runCount);
458
+ return result;
459
+ }, {
460
+ kind: SpanKind.PRODUCER,
461
+ attributes: {
462
+ [SemanticInternalAttributes.STYLE_ICON]: "trigger",
463
+ },
464
+ });
465
+ const handle = {
466
+ batchId: response.id,
467
+ runCount: response.runCount,
468
+ publicAccessToken: response.publicAccessToken,
469
+ };
470
+ return handle;
471
+ }
390
472
  }
391
- /**
392
- * Triggers multiple tasks and waits for all of them to complete before returning their results.
393
- * This function must be called from within a task.run() context.
394
- *
395
- * @template TTask - Union type of tasks to be triggered, extends AnyTask
396
- *
397
- * @param {Array<BatchByIdAndWaitItem<InferRunTypes<TTask>>>} items - Array of task items to trigger
398
- * @param {TriggerApiRequestOptions} [requestOptions] - Optional API request configuration
399
- *
400
- * @returns {Promise<BatchByIdResult<TTask>>} A promise that resolves with the batch results, including
401
- * success/failure status and strongly-typed outputs for each task
402
- *
403
- * @throws {Error} If called outside of a task.run() context
404
- * @throws {Error} If no API client is configured
405
- *
406
- * @example
407
- * ```ts
408
- * import { batch, task } from "@trigger.dev/sdk/v3";
409
- *
410
- * export const parentTask = task({
411
- * id: "parent-task",
412
- * run: async (payload: string) => {
413
- * const results = await batch.triggerAndWait<typeof childTask1 | typeof childTask2>([
414
- * {
415
- * id: "child-task-1",
416
- * payload: { foo: "World" },
417
- * options: {
418
- * queue: "default",
419
- * delay: "5m",
420
- * tags: ["batch", "child1"]
421
- * }
422
- * },
423
- * {
424
- * id: "child-task-2",
425
- * payload: { bar: 42 }
426
- * }
427
- * ]);
428
- *
429
- * // Type-safe result handling
430
- * for (const result of results) {
431
- * if (result.ok) {
432
- * switch (result.taskIdentifier) {
433
- * case "child-task-1":
434
- * console.log("Child task 1 output:", result.output); // string type
435
- * break;
436
- * case "child-task-2":
437
- * console.log("Child task 2 output:", result.output); // number type
438
- * break;
439
- * }
440
- * } else {
441
- * console.error("Task failed:", result.error);
442
- * }
443
- * }
444
- * }
445
- * });
446
- * ```
447
- *
448
- * @description
449
- * Each task item in the array can include:
450
- * - `id`: The task identifier (must match one of the tasks in the union type)
451
- * - `payload`: Strongly-typed payload matching the task's input type
452
- * - `options`: Optional task-specific settings including:
453
- * - `queue`: Specify a queue for the task
454
- * - `concurrencyKey`: Control concurrent execution
455
- * - `delay`: Delay before task execution
456
- * - `ttl`: Time-to-live for the task
457
- * - `tags`: Array of tags for the task
458
- * - `maxAttempts`: Maximum retry attempts
459
- * - `metadata`: Additional metadata
460
- * - `maxDuration`: Maximum execution duration
461
- *
462
- * The function provides full type safety for:
463
- * - Task IDs
464
- * - Payload types
465
- * - Return value types
466
- * - Error handling
467
- */
468
- export async function batchTriggerByIdAndWait(items, options, requestOptions) {
473
+ // Implementation
474
+ export async function batchTriggerByIdAndWait(...args) {
475
+ const [items, options, requestOptions] = args;
469
476
  const ctx = taskContext.ctx;
470
477
  if (!ctx) {
471
478
  throw new Error("batchTriggerAndWait can only be used from inside a task.run()");
472
479
  }
473
- const apiClient = apiClientManager.clientOrThrow();
474
- return await tracer.startActiveSpan("batch.triggerAndWait()", async (span) => {
475
- const response = await apiClient.batchTriggerV2({
476
- items: await Promise.all(items.map(async (item) => {
477
- const taskMetadata = taskCatalog.getTask(item.id);
478
- const parsedPayload = taskMetadata?.fns.parsePayload
479
- ? await taskMetadata?.fns.parsePayload(item.payload)
480
- : item.payload;
481
- const payloadPacket = await stringifyIO(parsedPayload);
482
- return {
483
- task: item.id,
484
- payload: payloadPacket.data,
485
- options: {
486
- lockToVersion: taskContext.worker?.version,
487
- queue: item.options?.queue,
488
- concurrencyKey: item.options?.concurrencyKey,
489
- test: taskContext.ctx?.run.isTest,
490
- payloadType: payloadPacket.dataType,
491
- delay: item.options?.delay,
492
- ttl: item.options?.ttl,
493
- tags: item.options?.tags,
494
- maxAttempts: item.options?.maxAttempts,
495
- metadata: item.options?.metadata,
496
- maxDuration: item.options?.maxDuration,
497
- machine: item.options?.machine,
498
- },
499
- };
500
- })),
501
- dependentAttempt: ctx.attempt.id,
480
+ const apiClient = apiClientManager.clientOrThrow(requestOptions?.clientConfig);
481
+ // Check if items is an array or a stream
482
+ if (Array.isArray(items)) {
483
+ // Array path: existing logic
484
+ const ndJsonItems = await Promise.all(items.map(async (item, index) => {
485
+ const taskMetadata = resourceCatalog.getTask(item.id);
486
+ const parsedPayload = taskMetadata?.fns.parsePayload
487
+ ? await taskMetadata?.fns.parsePayload(item.payload)
488
+ : item.payload;
489
+ const payloadPacket = await stringifyIO(parsedPayload);
490
+ const batchItemIdempotencyKey = await makeIdempotencyKey(flattenIdempotencyKey([options?.idempotencyKey, `${index}`]));
491
+ return {
492
+ index,
493
+ task: item.id,
494
+ payload: payloadPacket.data,
495
+ options: {
496
+ lockToVersion: taskContext.worker?.version,
497
+ ...triggerQueueBody(item.options?.queue),
498
+ ...triggerConcurrencyBody(item.options?.concurrency),
499
+ concurrencyKey: item.options?.concurrencyKey,
500
+ test: taskContext.ctx?.run.isTest,
501
+ payloadType: payloadPacket.dataType,
502
+ delay: item.options?.delay,
503
+ ttl: item.options?.ttl,
504
+ tags: item.options?.tags,
505
+ maxAttempts: item.options?.maxAttempts,
506
+ metadata: item.options?.metadata,
507
+ maxDuration: item.options?.maxDuration,
508
+ idempotencyKey: (await makeIdempotencyKey(item.options?.idempotencyKey)) ?? batchItemIdempotencyKey,
509
+ idempotencyKeyTTL: item.options?.idempotencyKeyTTL ?? options?.idempotencyKeyTTL,
510
+ machine: item.options?.machine,
511
+ priority: item.options?.priority,
512
+ region: item.options?.region,
513
+ debounce: item.options?.debounce,
514
+ },
515
+ };
516
+ }));
517
+ return await tracer.startActiveSpan("batch.triggerAndWait()", async (span) => {
518
+ // Execute 2-phase batch
519
+ const response = await executeBatchTwoPhase(apiClient, ndJsonItems, {
520
+ parentRunId: ctx.run.id,
521
+ resumeParentOnCompletion: true,
522
+ idempotencyKey: await makeIdempotencyKey(options?.idempotencyKey),
523
+ spanParentAsLink: false, // Waiting: child runs share parent's trace ID
524
+ }, requestOptions);
525
+ span.setAttribute("batchId", response.id);
526
+ span.setAttribute("runCount", response.runCount);
527
+ const result = await runtime.waitForBatch({
528
+ id: response.id,
529
+ runCount: response.runCount,
530
+ ctx,
531
+ });
532
+ const runs = await handleBatchTaskRunExecutionResultV2(result.items, response.taskIdentifiers);
533
+ return {
534
+ id: result.id,
535
+ runs,
536
+ };
502
537
  }, {
503
- processingStrategy: options?.triggerSequentially ? "sequential" : undefined,
504
- }, requestOptions);
505
- span.setAttribute("batchId", response.id);
506
- span.setAttribute("runCount", response.runs.length);
507
- span.setAttribute("isCached", response.isCached);
508
- if (response.isCached) {
509
- console.warn(`Result is a cached response because the request was idempotent.`);
510
- }
511
- if (response.idempotencyKey) {
512
- span.setAttribute("idempotencyKey", response.idempotencyKey);
513
- }
514
- const result = await runtime.waitForBatch({
515
- id: response.id,
516
- runs: response.runs.map((run) => run.id),
517
- ctx,
538
+ kind: SpanKind.PRODUCER,
539
+ attributes: {
540
+ [SemanticInternalAttributes.STYLE_ICON]: "trigger",
541
+ },
518
542
  });
519
- const runs = await handleBatchTaskRunExecutionResultV2(result.items);
520
- return {
521
- id: result.id,
522
- runs,
523
- };
524
- }, {
525
- kind: SpanKind.PRODUCER,
526
- attributes: {
527
- [SemanticInternalAttributes.STYLE_ICON]: "trigger",
528
- },
529
- });
543
+ }
544
+ else {
545
+ // Stream path: convert to AsyncIterable and transform
546
+ const asyncItems = normalizeToAsyncIterable(items);
547
+ const transformedItems = transformBatchItemsStreamForWait(asyncItems, options);
548
+ return await tracer.startActiveSpan("batch.triggerAndWait()", async (span) => {
549
+ // Execute streaming 2-phase batch
550
+ const response = await executeBatchTwoPhaseStreaming(apiClient, transformedItems, {
551
+ parentRunId: ctx.run.id,
552
+ resumeParentOnCompletion: true,
553
+ idempotencyKey: await makeIdempotencyKey(options?.idempotencyKey),
554
+ spanParentAsLink: false, // Waiting: child runs share parent's trace ID
555
+ }, requestOptions);
556
+ span.setAttribute("batchId", response.id);
557
+ span.setAttribute("runCount", response.runCount);
558
+ const result = await runtime.waitForBatch({
559
+ id: response.id,
560
+ runCount: response.runCount,
561
+ ctx,
562
+ });
563
+ const runs = await handleBatchTaskRunExecutionResultV2(result.items, response.taskIdentifiers);
564
+ return {
565
+ id: result.id,
566
+ runs,
567
+ };
568
+ }, {
569
+ kind: SpanKind.PRODUCER,
570
+ attributes: {
571
+ [SemanticInternalAttributes.STYLE_ICON]: "trigger",
572
+ },
573
+ });
574
+ }
530
575
  }
531
- /**
532
- * Triggers multiple tasks and waits for all of them to complete before returning their results.
533
- * This function must be called from within a task.run() context.
534
- *
535
- * @template TTask - Union type of tasks to be triggered, extends AnyTask
536
- *
537
- * @param {Array<BatchByIdAndWaitItem<InferRunTypes<TTask>>>} items - Array of task items to trigger
538
- * @param {TriggerApiRequestOptions} [requestOptions] - Optional API request configuration
539
- *
540
- * @returns {Promise<BatchByIdResult<TTask>>} A promise that resolves with the batch results, including
541
- * success/failure status and strongly-typed outputs for each task
542
- *
543
- * @throws {Error} If called outside of a task.run() context
544
- * @throws {Error} If no API client is configured
545
- *
546
- * @example
547
- * ```ts
548
- * import { batch, task } from "@trigger.dev/sdk/v3";
549
- *
550
- * export const parentTask = task({
551
- * id: "parent-task",
552
- * run: async (payload: string) => {
553
- * const results = await batch.triggerAndWait<typeof childTask1 | typeof childTask2>([
554
- * {
555
- * id: "child-task-1",
556
- * payload: { foo: "World" },
557
- * options: {
558
- * queue: "default",
559
- * delay: "5m",
560
- * tags: ["batch", "child1"]
561
- * }
562
- * },
563
- * {
564
- * id: "child-task-2",
565
- * payload: { bar: 42 }
566
- * }
567
- * ]);
568
- *
569
- * // Type-safe result handling
570
- * for (const result of results) {
571
- * if (result.ok) {
572
- * switch (result.taskIdentifier) {
573
- * case "child-task-1":
574
- * console.log("Child task 1 output:", result.output); // string type
575
- * break;
576
- * case "child-task-2":
577
- * console.log("Child task 2 output:", result.output); // number type
578
- * break;
579
- * }
580
- * } else {
581
- * console.error("Task failed:", result.error);
582
- * }
583
- * }
584
- * }
585
- * });
586
- * ```
587
- *
588
- * @description
589
- * Each task item in the array can include:
590
- * - `id`: The task identifier (must match one of the tasks in the union type)
591
- * - `payload`: Strongly-typed payload matching the task's input type
592
- * - `options`: Optional task-specific settings including:
593
- * - `queue`: Specify a queue for the task
594
- * - `concurrencyKey`: Control concurrent execution
595
- * - `delay`: Delay before task execution
596
- * - `ttl`: Time-to-live for the task
597
- * - `tags`: Array of tags for the task
598
- * - `maxAttempts`: Maximum retry attempts
599
- * - `metadata`: Additional metadata
600
- * - `maxDuration`: Maximum execution duration
601
- *
602
- * The function provides full type safety for:
603
- * - Task IDs
604
- * - Payload types
605
- * - Return value types
606
- * - Error handling
607
- */
608
- export async function batchTriggerTasks(items, options, requestOptions) {
609
- const apiClient = apiClientManager.clientOrThrow();
610
- const response = await apiClient.batchTriggerV2({
611
- items: await Promise.all(items.map(async (item) => {
612
- const taskMetadata = taskCatalog.getTask(item.task.id);
576
+ // Implementation
577
+ export async function batchTriggerTasks(...args) {
578
+ const [items, options, requestOptions] = args;
579
+ const apiClient = apiClientManager.clientOrThrow(requestOptions?.clientConfig);
580
+ // Check if items is an array or a stream
581
+ if (Array.isArray(items)) {
582
+ // Array path: existing logic
583
+ const ndJsonItems = await Promise.all(items.map(async (item, index) => {
584
+ const taskMetadata = resourceCatalog.getTask(item.task.id);
613
585
  const parsedPayload = taskMetadata?.fns.parsePayload
614
586
  ? await taskMetadata?.fns.parsePayload(item.payload)
615
587
  : item.payload;
616
588
  const payloadPacket = await stringifyIO(parsedPayload);
589
+ const batchItemIdempotencyKey = await makeIdempotencyKey(flattenIdempotencyKey([options?.idempotencyKey, `${index}`]));
617
590
  return {
591
+ index,
618
592
  task: item.task.id,
619
593
  payload: payloadPacket.data,
620
594
  options: {
621
- queue: item.options?.queue,
595
+ ...triggerQueueBody(item.options?.queue),
596
+ ...triggerConcurrencyBody(item.options?.concurrency),
622
597
  concurrencyKey: item.options?.concurrencyKey,
623
598
  test: taskContext.ctx?.run.isTest,
624
599
  payloadType: payloadPacket.dataType,
625
- idempotencyKey: await makeIdempotencyKey(item.options?.idempotencyKey),
626
- idempotencyKeyTTL: item.options?.idempotencyKeyTTL,
627
600
  delay: item.options?.delay,
628
601
  ttl: item.options?.ttl,
629
602
  tags: item.options?.tags,
630
603
  maxAttempts: item.options?.maxAttempts,
631
- parentAttempt: taskContext.ctx?.attempt.id,
632
604
  metadata: item.options?.metadata,
633
605
  maxDuration: item.options?.maxDuration,
606
+ idempotencyKey: (await makeIdempotencyKey(item.options?.idempotencyKey)) ?? batchItemIdempotencyKey,
607
+ idempotencyKeyTTL: item.options?.idempotencyKeyTTL ?? options?.idempotencyKeyTTL,
634
608
  machine: item.options?.machine,
609
+ priority: item.options?.priority,
610
+ region: item.options?.region,
611
+ lockToVersion: item.options?.version ?? scopedEnvVar("TRIGGER_VERSION"),
612
+ externalDeploymentId: resolveTriggerExternalDeploymentId(item.options?.externalDeploymentId),
613
+ debounce: item.options?.debounce,
635
614
  },
636
615
  };
637
- })),
638
- }, {
639
- spanParentAsLink: true,
640
- idempotencyKey: await makeIdempotencyKey(options?.idempotencyKey),
641
- idempotencyKeyTTL: options?.idempotencyKeyTTL,
642
- processingStrategy: options?.triggerSequentially ? "sequential" : undefined,
643
- }, {
644
- name: "batch.triggerByTask()",
645
- tracer,
646
- icon: "trigger",
647
- onResponseBody(body, span) {
648
- if (body && typeof body === "object" && !Array.isArray(body)) {
649
- if ("id" in body && typeof body.id === "string") {
650
- span.setAttribute("batchId", body.id);
651
- }
652
- if ("runs" in body && Array.isArray(body.runs)) {
653
- span.setAttribute("runCount", body.runs.length);
654
- }
655
- if ("isCached" in body && typeof body.isCached === "boolean") {
656
- if (body.isCached) {
657
- console.warn(`Result is a cached response because the request was idempotent.`);
658
- }
659
- span.setAttribute("isCached", body.isCached);
660
- }
661
- if ("idempotencyKey" in body && typeof body.idempotencyKey === "string") {
662
- span.setAttribute("idempotencyKey", body.idempotencyKey);
663
- }
664
- }
665
- },
666
- ...requestOptions,
667
- });
668
- const handle = {
669
- batchId: response.id,
670
- isCached: response.isCached,
671
- idempotencyKey: response.idempotencyKey,
672
- runs: response.runs,
673
- publicAccessToken: response.publicAccessToken,
674
- };
675
- return handle;
616
+ }));
617
+ // Execute 2-phase batch
618
+ const response = await tracer.startActiveSpan("batch.triggerByTask()", async (span) => {
619
+ const result = await executeBatchTwoPhase(apiClient, ndJsonItems, {
620
+ parentRunId: taskContext.ctx?.run.id,
621
+ idempotencyKey: await makeIdempotencyKey(options?.idempotencyKey),
622
+ spanParentAsLink: true, // Fire-and-forget: child runs get separate trace IDs
623
+ }, requestOptions);
624
+ span.setAttribute("batchId", result.id);
625
+ span.setAttribute("runCount", result.runCount);
626
+ return result;
627
+ }, {
628
+ kind: SpanKind.PRODUCER,
629
+ attributes: {
630
+ [SemanticInternalAttributes.STYLE_ICON]: "trigger",
631
+ },
632
+ });
633
+ const handle = {
634
+ batchId: response.id,
635
+ runCount: response.runCount,
636
+ publicAccessToken: response.publicAccessToken,
637
+ };
638
+ return handle;
639
+ }
640
+ else {
641
+ // Stream path: convert to AsyncIterable and transform
642
+ const streamItems = items;
643
+ const asyncItems = normalizeToAsyncIterable(streamItems);
644
+ const transformedItems = transformBatchByTaskItemsStream(asyncItems, options);
645
+ // Execute streaming 2-phase batch
646
+ const response = await tracer.startActiveSpan("batch.triggerByTask()", async (span) => {
647
+ const result = await executeBatchTwoPhaseStreaming(apiClient, transformedItems, {
648
+ parentRunId: taskContext.ctx?.run.id,
649
+ idempotencyKey: await makeIdempotencyKey(options?.idempotencyKey),
650
+ spanParentAsLink: true, // Fire-and-forget: child runs get separate trace IDs
651
+ }, requestOptions);
652
+ span.setAttribute("batchId", result.id);
653
+ span.setAttribute("runCount", result.runCount);
654
+ return result;
655
+ }, {
656
+ kind: SpanKind.PRODUCER,
657
+ attributes: {
658
+ [SemanticInternalAttributes.STYLE_ICON]: "trigger",
659
+ },
660
+ });
661
+ const handle = {
662
+ batchId: response.id,
663
+ runCount: response.runCount,
664
+ publicAccessToken: response.publicAccessToken,
665
+ };
666
+ return handle;
667
+ }
676
668
  }
677
- /**
678
- * Triggers multiple tasks and waits for all of them to complete before returning their results.
679
- * This function must be called from within a task.run() context.
680
- *
681
- * @template TTask - Union type of tasks to be triggered, extends AnyTask
682
- *
683
- * @param {Array<BatchByIdAndWaitItem<InferRunTypes<TTask>>>} items - Array of task items to trigger
684
- * @param {TriggerApiRequestOptions} [requestOptions] - Optional API request configuration
685
- *
686
- * @returns {Promise<BatchByIdResult<TTask>>} A promise that resolves with the batch results, including
687
- * success/failure status and strongly-typed outputs for each task
688
- *
689
- * @throws {Error} If called outside of a task.run() context
690
- * @throws {Error} If no API client is configured
691
- *
692
- * @example
693
- * ```ts
694
- * import { batch, task } from "@trigger.dev/sdk/v3";
669
+ // Implementation
670
+ export async function batchTriggerAndWaitTasks(...args) {
671
+ const [items, options, requestOptions] = args;
672
+ const ctx = taskContext.ctx;
673
+ if (!ctx) {
674
+ throw new Error("batchTriggerAndWait can only be used from inside a task.run()");
675
+ }
676
+ const apiClient = apiClientManager.clientOrThrow(requestOptions?.clientConfig);
677
+ // Check if items is an array or a stream
678
+ if (Array.isArray(items)) {
679
+ // Array path: existing logic
680
+ const ndJsonItems = await Promise.all(items.map(async (item, index) => {
681
+ const taskMetadata = resourceCatalog.getTask(item.task.id);
682
+ const parsedPayload = taskMetadata?.fns.parsePayload
683
+ ? await taskMetadata?.fns.parsePayload(item.payload)
684
+ : item.payload;
685
+ const payloadPacket = await stringifyIO(parsedPayload);
686
+ const batchItemIdempotencyKey = await makeIdempotencyKey(flattenIdempotencyKey([options?.idempotencyKey, `${index}`]));
687
+ return {
688
+ index,
689
+ task: item.task.id,
690
+ payload: payloadPacket.data,
691
+ options: {
692
+ lockToVersion: taskContext.worker?.version,
693
+ ...triggerQueueBody(item.options?.queue),
694
+ ...triggerConcurrencyBody(item.options?.concurrency),
695
+ concurrencyKey: item.options?.concurrencyKey,
696
+ test: taskContext.ctx?.run.isTest,
697
+ payloadType: payloadPacket.dataType,
698
+ delay: item.options?.delay,
699
+ ttl: item.options?.ttl,
700
+ tags: item.options?.tags,
701
+ maxAttempts: item.options?.maxAttempts,
702
+ metadata: item.options?.metadata,
703
+ maxDuration: item.options?.maxDuration,
704
+ idempotencyKey: (await makeIdempotencyKey(item.options?.idempotencyKey)) ?? batchItemIdempotencyKey,
705
+ idempotencyKeyTTL: item.options?.idempotencyKeyTTL ?? options?.idempotencyKeyTTL,
706
+ machine: item.options?.machine,
707
+ priority: item.options?.priority,
708
+ region: item.options?.region,
709
+ debounce: item.options?.debounce,
710
+ },
711
+ };
712
+ }));
713
+ return await tracer.startActiveSpan("batch.triggerByTaskAndWait()", async (span) => {
714
+ // Execute 2-phase batch
715
+ const response = await executeBatchTwoPhase(apiClient, ndJsonItems, {
716
+ parentRunId: ctx.run.id,
717
+ resumeParentOnCompletion: true,
718
+ idempotencyKey: await makeIdempotencyKey(options?.idempotencyKey),
719
+ spanParentAsLink: false, // Waiting: child runs share parent's trace ID
720
+ }, requestOptions);
721
+ span.setAttribute("batchId", response.id);
722
+ span.setAttribute("runCount", response.runCount);
723
+ const result = await runtime.waitForBatch({
724
+ id: response.id,
725
+ runCount: response.runCount,
726
+ ctx,
727
+ });
728
+ const runs = await handleBatchTaskRunExecutionResultV2(result.items, response.taskIdentifiers);
729
+ return {
730
+ id: result.id,
731
+ runs,
732
+ };
733
+ }, {
734
+ kind: SpanKind.PRODUCER,
735
+ attributes: {
736
+ [SemanticInternalAttributes.STYLE_ICON]: "trigger",
737
+ },
738
+ });
739
+ }
740
+ else {
741
+ // Stream path: convert to AsyncIterable and transform
742
+ const streamItems = items;
743
+ const asyncItems = normalizeToAsyncIterable(streamItems);
744
+ const transformedItems = transformBatchByTaskItemsStreamForWait(asyncItems, options);
745
+ return await tracer.startActiveSpan("batch.triggerByTaskAndWait()", async (span) => {
746
+ // Execute streaming 2-phase batch
747
+ const response = await executeBatchTwoPhaseStreaming(apiClient, transformedItems, {
748
+ parentRunId: ctx.run.id,
749
+ resumeParentOnCompletion: true,
750
+ idempotencyKey: await makeIdempotencyKey(options?.idempotencyKey),
751
+ spanParentAsLink: false, // Waiting: child runs share parent's trace ID
752
+ }, requestOptions);
753
+ span.setAttribute("batchId", response.id);
754
+ span.setAttribute("runCount", response.runCount);
755
+ const result = await runtime.waitForBatch({
756
+ id: response.id,
757
+ runCount: response.runCount,
758
+ ctx,
759
+ });
760
+ const runs = await handleBatchTaskRunExecutionResultV2(result.items, response.taskIdentifiers);
761
+ return {
762
+ id: result.id,
763
+ runs,
764
+ };
765
+ }, {
766
+ kind: SpanKind.PRODUCER,
767
+ attributes: {
768
+ [SemanticInternalAttributes.STYLE_ICON]: "trigger",
769
+ },
770
+ });
771
+ }
772
+ }
773
+ export function uniqueBatchTaskIdentifiers(items) {
774
+ return Array.from(new Set(items.map((item) => item.task))).sort();
775
+ }
776
+ /**
777
+ * Helper function that executes a 2-phase batch trigger:
778
+ * 1. Creates the batch record with expected run count
779
+ * 2. Streams items as NDJSON to the server
695
780
  *
696
- * export const parentTask = task({
697
- * id: "parent-task",
698
- * run: async (payload: string) => {
699
- * const results = await batch.triggerAndWait<typeof childTask1 | typeof childTask2>([
700
- * {
701
- * id: "child-task-1",
702
- * payload: { foo: "World" },
703
- * options: {
704
- * queue: "default",
705
- * delay: "5m",
706
- * tags: ["batch", "child1"]
707
- * }
708
- * },
709
- * {
710
- * id: "child-task-2",
711
- * payload: { bar: 42 }
712
- * }
713
- * ]);
781
+ * @param apiClient - The API client instance
782
+ * @param items - Array of batch items
783
+ * @param options - Batch options including trace context settings
784
+ * @param options.spanParentAsLink - If true, child runs will have separate trace IDs with a link to parent.
785
+ * Use true for batchTrigger (fire-and-forget), false for batchTriggerAndWait.
786
+ * @param requestOptions - Optional request options
787
+ * @internal
788
+ */
789
+ async function executeBatchTwoPhase(apiClient, items, options, requestOptions) {
790
+ // Offload any oversized per-item payloads to object storage before streaming, so a batch
791
+ // of large items keeps the request body small — the same treatment single triggers get.
792
+ // Both the array and streaming batch paths funnel through here, so this is the one place
793
+ // batch offloading needs to happen. Wrap failures so a presign/upload error carries the
794
+ // same batch context (phase, itemCount, rate-limit info) as the create/stream phases.
795
+ try {
796
+ items = await offloadBatchItemPayloads(items, apiClient);
797
+ }
798
+ catch (error) {
799
+ throw new BatchTriggerError(`Failed to offload payloads for batch with ${items.length} items`, {
800
+ cause: error,
801
+ phase: "offload",
802
+ itemCount: items.length,
803
+ });
804
+ }
805
+ let batch;
806
+ try {
807
+ // Phase 1: Create batch
808
+ batch = await apiClient.createBatch({
809
+ runCount: items.length,
810
+ taskIdentifiers: uniqueBatchTaskIdentifiers(items),
811
+ parentRunId: options.parentRunId,
812
+ resumeParentOnCompletion: options.resumeParentOnCompletion,
813
+ idempotencyKey: options.idempotencyKey,
814
+ idempotencyKeyOptions: options.idempotencyKeyOptions,
815
+ }, { spanParentAsLink: options.spanParentAsLink }, requestOptions);
816
+ }
817
+ catch (error) {
818
+ // Wrap with context about which phase failed
819
+ throw new BatchTriggerError(`Failed to create batch with ${items.length} items`, {
820
+ cause: error,
821
+ phase: "create",
822
+ itemCount: items.length,
823
+ });
824
+ }
825
+ // If the batch was cached (idempotent replay), skip streaming items
826
+ if (!batch.isCached) {
827
+ try {
828
+ // Phase 2: Stream items
829
+ await apiClient.streamBatchItems(batch.id, items, requestOptions);
830
+ }
831
+ catch (error) {
832
+ // Wrap with context about which phase failed and include batch ID
833
+ throw new BatchTriggerError(`Failed to stream items for batch ${batch.id} (${items.length} items)`, { cause: error, phase: "stream", batchId: batch.id, itemCount: items.length });
834
+ }
835
+ }
836
+ return {
837
+ id: batch.id,
838
+ runCount: batch.runCount,
839
+ publicAccessToken: batch.publicAccessToken,
840
+ taskIdentifiers: items.map((item) => item.task),
841
+ };
842
+ }
843
+ /**
844
+ * Offload any oversized per-item payloads in a batch to object storage, mirroring the
845
+ * single-trigger offload path. Small payloads pass through untouched. Every returned item
846
+ * carries `options.payloadSize` (the pre-offload serialized byte size) so the pipeline can
847
+ * reason about payload size without downloading an "application/store" reference.
714
848
  *
715
- * // Type-safe result handling
716
- * for (const result of results) {
717
- * if (result.ok) {
718
- * switch (result.taskIdentifier) {
719
- * case "child-task-1":
720
- * console.log("Child task 1 output:", result.output); // string type
721
- * break;
722
- * case "child-task-2":
723
- * console.log("Child task 2 output:", result.output); // number type
724
- * break;
725
- * }
726
- * } else {
727
- * console.error("Task failed:", result.error);
728
- * }
729
- * }
730
- * }
731
- * });
732
- * ```
849
+ * Uploads run with bounded concurrency so a batch of large items doesn't fire an unbounded
850
+ * number of simultaneous presigned PUTs.
733
851
  *
734
- * @description
735
- * Each task item in the array can include:
736
- * - `id`: The task identifier (must match one of the tasks in the union type)
737
- * - `payload`: Strongly-typed payload matching the task's input type
738
- * - `options`: Optional task-specific settings including:
739
- * - `queue`: Specify a queue for the task
740
- * - `concurrencyKey`: Control concurrent execution
741
- * - `delay`: Delay before task execution
742
- * - `ttl`: Time-to-live for the task
743
- * - `tags`: Array of tags for the task
744
- * - `maxAttempts`: Maximum retry attempts
745
- * - `metadata`: Additional metadata
746
- * - `maxDuration`: Maximum execution duration
852
+ * @internal Exported for testing.
853
+ */
854
+ export async function offloadBatchItemPayloads(items, apiClient, concurrency = 10) {
855
+ if (items.length === 0) {
856
+ return items;
857
+ }
858
+ const results = new Array(items.length);
859
+ let cursor = 0;
860
+ async function worker() {
861
+ while (cursor < items.length) {
862
+ const index = cursor++;
863
+ results[index] = await offloadBatchItemPayload(items[index], apiClient);
864
+ }
865
+ }
866
+ await Promise.all(Array.from({ length: Math.min(concurrency, items.length) }, () => worker()));
867
+ return results;
868
+ }
869
+ async function offloadBatchItemPayload(item, apiClient) {
870
+ // The batch builders serialize each payload to a string via stringifyIO before we get
871
+ // here; anything else has no inline body to offload or measure.
872
+ if (typeof item.payload !== "string" || item.payload.length === 0) {
873
+ return item;
874
+ }
875
+ const dataType = item.options?.payloadType ?? "application/json";
876
+ // Already an object-store reference — the caller pre-offloaded it, nothing to do.
877
+ if (dataType === "application/store") {
878
+ return item;
879
+ }
880
+ const packet = { data: item.payload, dataType };
881
+ // Measure before offload so the size reflects the real payload, not the small reference
882
+ // we may replace it with.
883
+ const { size: payloadSize } = packetRequiresOffloading(packet);
884
+ const exported = await conditionallyExportPacket(packet, createTriggerPayloadPathPrefix(), undefined, apiClient);
885
+ return {
886
+ ...item,
887
+ payload: exported.data,
888
+ options: {
889
+ ...item.options,
890
+ payloadType: exported.dataType,
891
+ payloadSize,
892
+ },
893
+ };
894
+ }
895
+ /**
896
+ * Error thrown when batch trigger operations fail.
897
+ * Includes context about which phase failed and the batch details.
747
898
  *
748
- * The function provides full type safety for:
749
- * - Task IDs
750
- * - Payload types
751
- * - Return value types
752
- * - Error handling
899
+ * When the underlying error is a rate limit (429), additional properties are exposed:
900
+ * - `isRateLimited`: true
901
+ * - `retryAfterMs`: milliseconds until the rate limit resets
753
902
  */
754
- export async function batchTriggerAndWaitTasks(items, options, requestOptions) {
755
- const ctx = taskContext.ctx;
756
- if (!ctx) {
757
- throw new Error("batchTriggerAndWait can only be used from inside a task.run()");
903
+ export class BatchTriggerError extends Error {
904
+ phase;
905
+ batchId;
906
+ itemCount;
907
+ /** True if the error was caused by rate limiting (HTTP 429) */
908
+ isRateLimited;
909
+ /** Milliseconds until the rate limit resets. Only set when `isRateLimited` is true. */
910
+ retryAfterMs;
911
+ /** The underlying API error, if the cause was an ApiError */
912
+ apiError;
913
+ /** The underlying cause of the error */
914
+ cause;
915
+ constructor(message, options) {
916
+ // Build enhanced message that includes the cause's message
917
+ const fullMessage = buildBatchErrorMessage(message, options.cause);
918
+ super(fullMessage, { cause: options.cause });
919
+ this.name = "BatchTriggerError";
920
+ this.cause = options.cause;
921
+ this.phase = options.phase;
922
+ this.batchId = options.batchId;
923
+ this.itemCount = options.itemCount;
924
+ // Extract rate limit info from cause
925
+ if (options.cause instanceof RateLimitError) {
926
+ this.isRateLimited = true;
927
+ this.retryAfterMs = options.cause.millisecondsUntilReset;
928
+ this.apiError = options.cause;
929
+ }
930
+ else if (options.cause instanceof ApiError) {
931
+ this.isRateLimited = options.cause.status === 429;
932
+ this.apiError = options.cause;
933
+ }
934
+ else {
935
+ this.isRateLimited = false;
936
+ }
758
937
  }
759
- const apiClient = apiClientManager.clientOrThrow();
760
- return await tracer.startActiveSpan("batch.triggerByTaskAndWait()", async (span) => {
761
- const response = await apiClient.batchTriggerV2({
762
- items: await Promise.all(items.map(async (item) => {
763
- const taskMetadata = taskCatalog.getTask(item.task.id);
764
- const parsedPayload = taskMetadata?.fns.parsePayload
765
- ? await taskMetadata?.fns.parsePayload(item.payload)
766
- : item.payload;
767
- const payloadPacket = await stringifyIO(parsedPayload);
768
- return {
769
- task: item.task.id,
770
- payload: payloadPacket.data,
771
- options: {
772
- lockToVersion: taskContext.worker?.version,
773
- queue: item.options?.queue,
774
- concurrencyKey: item.options?.concurrencyKey,
775
- test: taskContext.ctx?.run.isTest,
776
- payloadType: payloadPacket.dataType,
777
- delay: item.options?.delay,
778
- ttl: item.options?.ttl,
779
- tags: item.options?.tags,
780
- maxAttempts: item.options?.maxAttempts,
781
- metadata: item.options?.metadata,
782
- maxDuration: item.options?.maxDuration,
783
- machine: item.options?.machine,
784
- },
785
- };
786
- })),
787
- dependentAttempt: ctx.attempt.id,
788
- }, {
789
- processingStrategy: options?.triggerSequentially ? "sequential" : undefined,
790
- }, requestOptions);
791
- span.setAttribute("batchId", response.id);
792
- span.setAttribute("runCount", response.runs.length);
793
- span.setAttribute("isCached", response.isCached);
794
- if (response.isCached) {
795
- console.warn(`Result is a cached response because the request was idempotent.`);
938
+ }
939
+ /**
940
+ * Build an enhanced error message that includes context from the cause.
941
+ */
942
+ function buildBatchErrorMessage(baseMessage, cause) {
943
+ if (!cause) {
944
+ return baseMessage;
945
+ }
946
+ // Handle RateLimitError specifically for better messaging
947
+ if (cause instanceof RateLimitError) {
948
+ const retryMs = cause.millisecondsUntilReset;
949
+ if (retryMs !== undefined) {
950
+ const retrySeconds = Math.ceil(retryMs / 1000);
951
+ return `${baseMessage}: Rate limit exceeded - retry after ${retrySeconds}s`;
796
952
  }
797
- if (response.idempotencyKey) {
798
- span.setAttribute("idempotencyKey", response.idempotencyKey);
953
+ return `${baseMessage}: Rate limit exceeded`;
954
+ }
955
+ // Handle other ApiErrors
956
+ if (cause instanceof ApiError) {
957
+ return `${baseMessage}: ${cause.message}`;
958
+ }
959
+ // Handle generic errors
960
+ if (cause instanceof Error) {
961
+ return `${baseMessage}: ${cause.message}`;
962
+ }
963
+ return baseMessage;
964
+ }
965
+ /**
966
+ * Execute a streaming 2-phase batch trigger where items are streamed from an AsyncIterable.
967
+ * Unlike executeBatchTwoPhase, this doesn't know the count upfront.
968
+ *
969
+ * @param apiClient - The API client instance
970
+ * @param items - AsyncIterable of batch items
971
+ * @param options - Batch options including trace context settings
972
+ * @param options.spanParentAsLink - If true, child runs will have separate trace IDs with a link to parent.
973
+ * Use true for batchTrigger (fire-and-forget), false for batchTriggerAndWait.
974
+ * @param requestOptions - Optional request options
975
+ * @internal
976
+ */
977
+ async function executeBatchTwoPhaseStreaming(apiClient, items, options, requestOptions) {
978
+ // For streaming, we need to buffer items to get the count first
979
+ // This is because createBatch requires runCount upfront
980
+ // In the future, we could add a streaming-first endpoint that doesn't require this
981
+ const itemsArray = [];
982
+ for await (const item of items) {
983
+ itemsArray.push(item);
984
+ }
985
+ // Now we can use the regular 2-phase approach
986
+ return executeBatchTwoPhase(apiClient, itemsArray, options, requestOptions);
987
+ }
988
+ /**
989
+ * Type guard to check if a value is a ReadableStream
990
+ */
991
+ function isReadableStream(value) {
992
+ return (value != null &&
993
+ typeof value === "object" &&
994
+ "getReader" in value &&
995
+ typeof value.getReader === "function");
996
+ }
997
+ /**
998
+ * Convert a ReadableStream to an AsyncIterable.
999
+ * Properly cancels the stream when the consumer terminates early.
1000
+ *
1001
+ * @internal Exported for testing purposes
1002
+ */
1003
+ export async function* readableStreamToAsyncIterable(stream) {
1004
+ const reader = stream.getReader();
1005
+ try {
1006
+ while (true) {
1007
+ const { done, value } = await reader.read();
1008
+ if (done)
1009
+ break;
1010
+ yield value;
799
1011
  }
800
- const result = await runtime.waitForBatch({
801
- id: response.id,
802
- runs: response.runs.map((run) => run.id),
803
- ctx,
804
- });
805
- const runs = await handleBatchTaskRunExecutionResultV2(result.items);
806
- return {
807
- id: result.id,
808
- runs,
1012
+ }
1013
+ finally {
1014
+ try {
1015
+ await reader.cancel();
1016
+ }
1017
+ catch {
1018
+ // Ignore errors - stream might already be errored or closed
1019
+ }
1020
+ reader.releaseLock();
1021
+ }
1022
+ }
1023
+ /**
1024
+ * Normalize stream input to AsyncIterable
1025
+ */
1026
+ function normalizeToAsyncIterable(input) {
1027
+ if (isReadableStream(input)) {
1028
+ return readableStreamToAsyncIterable(input);
1029
+ }
1030
+ return input;
1031
+ }
1032
+ /**
1033
+ * Transform a stream of BatchByIdItem to BatchItemNDJSON format.
1034
+ * Handles payload serialization and idempotency key generation.
1035
+ *
1036
+ * @internal
1037
+ */
1038
+ async function* transformBatchItemsStream(items, options) {
1039
+ let index = 0;
1040
+ for await (const item of items) {
1041
+ const taskMetadata = resourceCatalog.getTask(item.id);
1042
+ const parsedPayload = taskMetadata?.fns.parsePayload
1043
+ ? await taskMetadata?.fns.parsePayload(item.payload)
1044
+ : item.payload;
1045
+ const payloadPacket = await stringifyIO(parsedPayload);
1046
+ const batchItemIdempotencyKey = await makeIdempotencyKey(flattenIdempotencyKey([options?.idempotencyKey, `${index}`]));
1047
+ yield {
1048
+ index: index++,
1049
+ task: item.id,
1050
+ payload: payloadPacket.data,
1051
+ options: {
1052
+ ...triggerQueueBody(item.options?.queue),
1053
+ ...triggerConcurrencyBody(item.options?.concurrency),
1054
+ concurrencyKey: item.options?.concurrencyKey,
1055
+ test: taskContext.ctx?.run.isTest,
1056
+ payloadType: payloadPacket.dataType,
1057
+ delay: item.options?.delay,
1058
+ ttl: item.options?.ttl,
1059
+ tags: item.options?.tags,
1060
+ maxAttempts: item.options?.maxAttempts,
1061
+ metadata: item.options?.metadata,
1062
+ maxDuration: item.options?.maxDuration,
1063
+ idempotencyKey: (await makeIdempotencyKey(item.options?.idempotencyKey)) ?? batchItemIdempotencyKey,
1064
+ idempotencyKeyTTL: item.options?.idempotencyKeyTTL ?? options?.idempotencyKeyTTL,
1065
+ machine: item.options?.machine,
1066
+ priority: item.options?.priority,
1067
+ region: item.options?.region,
1068
+ lockToVersion: item.options?.version ?? scopedEnvVar("TRIGGER_VERSION"),
1069
+ externalDeploymentId: resolveTriggerExternalDeploymentId(item.options?.externalDeploymentId),
1070
+ debounce: item.options?.debounce,
1071
+ },
809
1072
  };
810
- }, {
811
- kind: SpanKind.PRODUCER,
812
- attributes: {
813
- [SemanticInternalAttributes.STYLE_ICON]: "trigger",
814
- },
815
- });
1073
+ }
1074
+ }
1075
+ /**
1076
+ * Transform a stream of BatchByIdAndWaitItem to BatchItemNDJSON format for triggerAndWait.
1077
+ * Uses the current worker version for lockToVersion.
1078
+ *
1079
+ * @internal
1080
+ */
1081
+ async function* transformBatchItemsStreamForWait(items, options) {
1082
+ let index = 0;
1083
+ for await (const item of items) {
1084
+ const taskMetadata = resourceCatalog.getTask(item.id);
1085
+ const parsedPayload = taskMetadata?.fns.parsePayload
1086
+ ? await taskMetadata?.fns.parsePayload(item.payload)
1087
+ : item.payload;
1088
+ const payloadPacket = await stringifyIO(parsedPayload);
1089
+ const batchItemIdempotencyKey = await makeIdempotencyKey(flattenIdempotencyKey([options?.idempotencyKey, `${index}`]));
1090
+ yield {
1091
+ index: index++,
1092
+ task: item.id,
1093
+ payload: payloadPacket.data,
1094
+ options: {
1095
+ lockToVersion: taskContext.worker?.version,
1096
+ ...triggerQueueBody(item.options?.queue),
1097
+ ...triggerConcurrencyBody(item.options?.concurrency),
1098
+ concurrencyKey: item.options?.concurrencyKey,
1099
+ test: taskContext.ctx?.run.isTest,
1100
+ payloadType: payloadPacket.dataType,
1101
+ delay: item.options?.delay,
1102
+ ttl: item.options?.ttl,
1103
+ tags: item.options?.tags,
1104
+ maxAttempts: item.options?.maxAttempts,
1105
+ metadata: item.options?.metadata,
1106
+ maxDuration: item.options?.maxDuration,
1107
+ idempotencyKey: (await makeIdempotencyKey(item.options?.idempotencyKey)) ?? batchItemIdempotencyKey,
1108
+ idempotencyKeyTTL: item.options?.idempotencyKeyTTL ?? options?.idempotencyKeyTTL,
1109
+ machine: item.options?.machine,
1110
+ priority: item.options?.priority,
1111
+ region: item.options?.region,
1112
+ debounce: item.options?.debounce,
1113
+ },
1114
+ };
1115
+ }
1116
+ }
1117
+ /**
1118
+ * Transform a stream of BatchByTaskItem to BatchItemNDJSON format.
1119
+ *
1120
+ * @internal
1121
+ */
1122
+ async function* transformBatchByTaskItemsStream(items, options) {
1123
+ let index = 0;
1124
+ for await (const item of items) {
1125
+ const taskMetadata = resourceCatalog.getTask(item.task.id);
1126
+ const parsedPayload = taskMetadata?.fns.parsePayload
1127
+ ? await taskMetadata?.fns.parsePayload(item.payload)
1128
+ : item.payload;
1129
+ const payloadPacket = await stringifyIO(parsedPayload);
1130
+ const batchItemIdempotencyKey = await makeIdempotencyKey(flattenIdempotencyKey([options?.idempotencyKey, `${index}`]));
1131
+ yield {
1132
+ index: index++,
1133
+ task: item.task.id,
1134
+ payload: payloadPacket.data,
1135
+ options: {
1136
+ ...triggerQueueBody(item.options?.queue),
1137
+ ...triggerConcurrencyBody(item.options?.concurrency),
1138
+ concurrencyKey: item.options?.concurrencyKey,
1139
+ test: taskContext.ctx?.run.isTest,
1140
+ payloadType: payloadPacket.dataType,
1141
+ delay: item.options?.delay,
1142
+ ttl: item.options?.ttl,
1143
+ tags: item.options?.tags,
1144
+ maxAttempts: item.options?.maxAttempts,
1145
+ metadata: item.options?.metadata,
1146
+ maxDuration: item.options?.maxDuration,
1147
+ idempotencyKey: (await makeIdempotencyKey(item.options?.idempotencyKey)) ?? batchItemIdempotencyKey,
1148
+ idempotencyKeyTTL: item.options?.idempotencyKeyTTL ?? options?.idempotencyKeyTTL,
1149
+ machine: item.options?.machine,
1150
+ priority: item.options?.priority,
1151
+ region: item.options?.region,
1152
+ lockToVersion: item.options?.version ?? scopedEnvVar("TRIGGER_VERSION"),
1153
+ externalDeploymentId: resolveTriggerExternalDeploymentId(item.options?.externalDeploymentId),
1154
+ debounce: item.options?.debounce,
1155
+ },
1156
+ };
1157
+ }
1158
+ }
1159
+ /**
1160
+ * Transform a stream of BatchByTaskAndWaitItem to BatchItemNDJSON format for triggerAndWait.
1161
+ *
1162
+ * @internal
1163
+ */
1164
+ async function* transformBatchByTaskItemsStreamForWait(items, options) {
1165
+ let index = 0;
1166
+ for await (const item of items) {
1167
+ const taskMetadata = resourceCatalog.getTask(item.task.id);
1168
+ const parsedPayload = taskMetadata?.fns.parsePayload
1169
+ ? await taskMetadata?.fns.parsePayload(item.payload)
1170
+ : item.payload;
1171
+ const payloadPacket = await stringifyIO(parsedPayload);
1172
+ const batchItemIdempotencyKey = await makeIdempotencyKey(flattenIdempotencyKey([options?.idempotencyKey, `${index}`]));
1173
+ yield {
1174
+ index: index++,
1175
+ task: item.task.id,
1176
+ payload: payloadPacket.data,
1177
+ options: {
1178
+ lockToVersion: taskContext.worker?.version,
1179
+ ...triggerQueueBody(item.options?.queue),
1180
+ ...triggerConcurrencyBody(item.options?.concurrency),
1181
+ concurrencyKey: item.options?.concurrencyKey,
1182
+ test: taskContext.ctx?.run.isTest,
1183
+ payloadType: payloadPacket.dataType,
1184
+ delay: item.options?.delay,
1185
+ ttl: item.options?.ttl,
1186
+ tags: item.options?.tags,
1187
+ maxAttempts: item.options?.maxAttempts,
1188
+ metadata: item.options?.metadata,
1189
+ maxDuration: item.options?.maxDuration,
1190
+ idempotencyKey: (await makeIdempotencyKey(item.options?.idempotencyKey)) ?? batchItemIdempotencyKey,
1191
+ idempotencyKeyTTL: item.options?.idempotencyKeyTTL ?? options?.idempotencyKeyTTL,
1192
+ machine: item.options?.machine,
1193
+ priority: item.options?.priority,
1194
+ region: item.options?.region,
1195
+ debounce: item.options?.debounce,
1196
+ },
1197
+ };
1198
+ }
1199
+ }
1200
+ /**
1201
+ * Transform a stream of BatchItem (single task type) to BatchItemNDJSON format.
1202
+ *
1203
+ * @internal
1204
+ */
1205
+ async function* transformSingleTaskBatchItemsStream(taskIdentifier, items, parsePayload, options, queue) {
1206
+ let index = 0;
1207
+ for await (const item of items) {
1208
+ const parsedPayload = parsePayload ? await parsePayload(item.payload) : item.payload;
1209
+ const payloadPacket = await stringifyIO(parsedPayload);
1210
+ const batchItemIdempotencyKey = await makeIdempotencyKey(flattenIdempotencyKey([options?.idempotencyKey, `${index}`]));
1211
+ yield {
1212
+ index: index++,
1213
+ task: taskIdentifier,
1214
+ payload: payloadPacket.data,
1215
+ options: {
1216
+ ...triggerQueueBody(item.options?.queue, queue),
1217
+ ...triggerConcurrencyBody(item.options?.concurrency),
1218
+ concurrencyKey: item.options?.concurrencyKey,
1219
+ test: taskContext.ctx?.run.isTest,
1220
+ payloadType: payloadPacket.dataType,
1221
+ delay: item.options?.delay,
1222
+ ttl: item.options?.ttl,
1223
+ tags: item.options?.tags,
1224
+ maxAttempts: item.options?.maxAttempts,
1225
+ metadata: item.options?.metadata,
1226
+ maxDuration: item.options?.maxDuration,
1227
+ idempotencyKey: (await makeIdempotencyKey(item.options?.idempotencyKey)) ?? batchItemIdempotencyKey,
1228
+ idempotencyKeyTTL: item.options?.idempotencyKeyTTL ?? options?.idempotencyKeyTTL,
1229
+ machine: item.options?.machine,
1230
+ priority: item.options?.priority,
1231
+ region: item.options?.region,
1232
+ lockToVersion: item.options?.version ?? scopedEnvVar("TRIGGER_VERSION"),
1233
+ externalDeploymentId: resolveTriggerExternalDeploymentId(item.options?.externalDeploymentId),
1234
+ debounce: item.options?.debounce,
1235
+ },
1236
+ };
1237
+ }
1238
+ }
1239
+ /**
1240
+ * Transform a stream of BatchTriggerAndWaitItem (single task type) to BatchItemNDJSON format.
1241
+ *
1242
+ * @internal
1243
+ */
1244
+ async function* transformSingleTaskBatchItemsStreamForWait(taskIdentifier, items, parsePayload, options, queue) {
1245
+ let index = 0;
1246
+ for await (const item of items) {
1247
+ const parsedPayload = parsePayload ? await parsePayload(item.payload) : item.payload;
1248
+ const payloadPacket = await stringifyIO(parsedPayload);
1249
+ const batchItemIdempotencyKey = await makeIdempotencyKey(flattenIdempotencyKey([options?.idempotencyKey, `${index}`]));
1250
+ // Process item-specific idempotency key and extract options
1251
+ const itemIdempotencyKey = await makeIdempotencyKey(item.options?.idempotencyKey);
1252
+ const finalIdempotencyKey = itemIdempotencyKey ?? batchItemIdempotencyKey;
1253
+ const idempotencyKeyOptions = itemIdempotencyKey
1254
+ ? getIdempotencyKeyOptions(itemIdempotencyKey)
1255
+ : undefined;
1256
+ yield {
1257
+ index: index++,
1258
+ task: taskIdentifier,
1259
+ payload: payloadPacket.data,
1260
+ options: {
1261
+ lockToVersion: taskContext.worker?.version,
1262
+ ...triggerQueueBody(item.options?.queue, queue),
1263
+ ...triggerConcurrencyBody(item.options?.concurrency),
1264
+ concurrencyKey: item.options?.concurrencyKey,
1265
+ test: taskContext.ctx?.run.isTest,
1266
+ payloadType: payloadPacket.dataType,
1267
+ delay: item.options?.delay,
1268
+ ttl: item.options?.ttl,
1269
+ tags: item.options?.tags,
1270
+ maxAttempts: item.options?.maxAttempts,
1271
+ metadata: item.options?.metadata,
1272
+ maxDuration: item.options?.maxDuration,
1273
+ idempotencyKey: finalIdempotencyKey?.toString(),
1274
+ idempotencyKeyTTL: item.options?.idempotencyKeyTTL ?? options?.idempotencyKeyTTL,
1275
+ idempotencyKeyOptions,
1276
+ machine: item.options?.machine,
1277
+ priority: item.options?.priority,
1278
+ region: item.options?.region,
1279
+ debounce: item.options?.debounce,
1280
+ },
1281
+ };
1282
+ }
816
1283
  }
817
1284
  async function trigger_internal(name, id, payload, parsePayload, options, requestOptions) {
818
- const apiClient = apiClientManager.clientOrThrow();
1285
+ const apiClient = apiClientManager.clientOrThrow(requestOptions?.clientConfig);
819
1286
  const parsedPayload = parsePayload ? await parsePayload(payload) : payload;
820
- const payloadPacket = await stringifyIO(parsedPayload);
1287
+ const { packet: triggerPayloadPacket, payloadSize } = await prepareTriggerPayload(parsedPayload, apiClient);
1288
+ // Process idempotency key and extract options for storage
1289
+ const processedIdempotencyKey = await makeIdempotencyKey(options?.idempotencyKey);
1290
+ const idempotencyKeyOptions = processedIdempotencyKey
1291
+ ? getIdempotencyKeyOptions(processedIdempotencyKey)
1292
+ : undefined;
821
1293
  const handle = await apiClient.triggerTask(id, {
822
- payload: payloadPacket.data,
1294
+ payload: triggerPayloadPacket.data,
823
1295
  options: {
824
- queue: options?.queue,
1296
+ ...triggerQueueBody(options?.queue),
1297
+ ...triggerConcurrencyBody(options?.concurrency),
825
1298
  concurrencyKey: options?.concurrencyKey,
826
1299
  test: taskContext.ctx?.run.isTest,
827
- payloadType: payloadPacket.dataType,
828
- idempotencyKey: await makeIdempotencyKey(options?.idempotencyKey),
1300
+ payloadType: triggerPayloadPacket.dataType,
1301
+ payloadSize,
1302
+ idempotencyKey: processedIdempotencyKey?.toString(),
829
1303
  idempotencyKeyTTL: options?.idempotencyKeyTTL,
1304
+ idempotencyKeyOptions,
830
1305
  delay: options?.delay,
831
1306
  ttl: options?.ttl,
832
1307
  tags: options?.tags,
833
1308
  maxAttempts: options?.maxAttempts,
834
- parentAttempt: taskContext.ctx?.attempt.id,
835
1309
  metadata: options?.metadata,
836
1310
  maxDuration: options?.maxDuration,
1311
+ parentRunId: taskContext.ctx?.run.id,
837
1312
  machine: options?.machine,
1313
+ priority: options?.priority,
1314
+ region: options?.region,
1315
+ lockToVersion: options?.version ?? scopedEnvVar("TRIGGER_VERSION"),
1316
+ externalDeploymentId: resolveTriggerExternalDeploymentId(options?.externalDeploymentId),
1317
+ debounce: options?.debounce,
838
1318
  },
839
1319
  }, {
840
1320
  spanParentAsLink: true,
@@ -854,96 +1334,169 @@ async function trigger_internal(name, id, payload, parsePayload, options, reques
854
1334
  return handle;
855
1335
  }
856
1336
  async function batchTrigger_internal(name, taskIdentifier, items, options, parsePayload, requestOptions, queue) {
857
- const apiClient = apiClientManager.clientOrThrow();
858
- const response = await apiClient.batchTriggerV2({
859
- items: await Promise.all(items.map(async (item) => {
1337
+ const apiClient = apiClientManager.clientOrThrow(requestOptions?.clientConfig);
1338
+ const ctx = taskContext.ctx;
1339
+ // Check if items is an array or a stream
1340
+ if (Array.isArray(items)) {
1341
+ // Prepare items as BatchItemNDJSON
1342
+ const ndJsonItems = await Promise.all(items.map(async (item, index) => {
860
1343
  const parsedPayload = parsePayload ? await parsePayload(item.payload) : item.payload;
861
1344
  const payloadPacket = await stringifyIO(parsedPayload);
1345
+ const batchItemIdempotencyKey = await makeIdempotencyKey(flattenIdempotencyKey([options?.idempotencyKey, `${index}`]));
1346
+ // Process item-specific idempotency key and extract options
1347
+ const itemIdempotencyKey = await makeIdempotencyKey(item.options?.idempotencyKey);
1348
+ const finalIdempotencyKey = itemIdempotencyKey ?? batchItemIdempotencyKey;
1349
+ const idempotencyKeyOptions = itemIdempotencyKey
1350
+ ? getIdempotencyKeyOptions(itemIdempotencyKey)
1351
+ : undefined;
862
1352
  return {
1353
+ index,
863
1354
  task: taskIdentifier,
864
1355
  payload: payloadPacket.data,
865
1356
  options: {
866
- queue: item.options?.queue ?? queue,
1357
+ ...triggerQueueBody(item.options?.queue, queue),
1358
+ ...triggerConcurrencyBody(item.options?.concurrency),
867
1359
  concurrencyKey: item.options?.concurrencyKey,
868
1360
  test: taskContext.ctx?.run.isTest,
869
1361
  payloadType: payloadPacket.dataType,
870
- idempotencyKey: await makeIdempotencyKey(item.options?.idempotencyKey),
871
- idempotencyKeyTTL: item.options?.idempotencyKeyTTL,
872
1362
  delay: item.options?.delay,
873
1363
  ttl: item.options?.ttl,
874
1364
  tags: item.options?.tags,
875
1365
  maxAttempts: item.options?.maxAttempts,
876
- parentAttempt: taskContext.ctx?.attempt.id,
877
1366
  metadata: item.options?.metadata,
878
1367
  maxDuration: item.options?.maxDuration,
1368
+ idempotencyKey: finalIdempotencyKey?.toString(),
1369
+ idempotencyKeyTTL: item.options?.idempotencyKeyTTL ?? options?.idempotencyKeyTTL,
1370
+ idempotencyKeyOptions,
879
1371
  machine: item.options?.machine,
1372
+ priority: item.options?.priority,
1373
+ region: item.options?.region,
1374
+ lockToVersion: item.options?.version ?? scopedEnvVar("TRIGGER_VERSION"),
1375
+ externalDeploymentId: resolveTriggerExternalDeploymentId(item.options?.externalDeploymentId),
1376
+ debounce: item.options?.debounce,
880
1377
  },
881
1378
  };
882
- })),
883
- }, {
884
- spanParentAsLink: true,
885
- idempotencyKey: await makeIdempotencyKey(options?.idempotencyKey),
886
- idempotencyKeyTTL: options?.idempotencyKeyTTL,
887
- processingStrategy: options?.triggerSequentially ? "sequential" : undefined,
888
- }, {
889
- name,
890
- tracer,
891
- icon: "trigger",
892
- onResponseBody(body, span) {
893
- if (body && typeof body === "object" && !Array.isArray(body)) {
894
- if ("id" in body && typeof body.id === "string") {
895
- span.setAttribute("batchId", body.id);
896
- }
897
- if ("runs" in body && Array.isArray(body.runs)) {
898
- span.setAttribute("runCount", body.runs.length);
899
- }
900
- if ("isCached" in body && typeof body.isCached === "boolean") {
901
- if (body.isCached) {
902
- console.warn(`Result is a cached response because the request was idempotent.`);
903
- }
904
- span.setAttribute("isCached", body.isCached);
905
- }
906
- if ("idempotencyKey" in body && typeof body.idempotencyKey === "string") {
907
- span.setAttribute("idempotencyKey", body.idempotencyKey);
908
- }
909
- }
910
- },
911
- ...requestOptions,
912
- });
913
- const handle = {
914
- batchId: response.id,
915
- isCached: response.isCached,
916
- idempotencyKey: response.idempotencyKey,
917
- runs: response.runs,
918
- publicAccessToken: response.publicAccessToken,
919
- };
920
- return handle;
1379
+ }));
1380
+ // Execute 2-phase batch
1381
+ // Process batch-level idempotency key
1382
+ const batchIdempotencyKey = await makeIdempotencyKey(options?.idempotencyKey);
1383
+ const batchIdempotencyKeyOptions = batchIdempotencyKey
1384
+ ? getIdempotencyKeyOptions(batchIdempotencyKey)
1385
+ : undefined;
1386
+ const response = await tracer.startActiveSpan(name, async (span) => {
1387
+ const result = await executeBatchTwoPhase(apiClient, ndJsonItems, {
1388
+ parentRunId: ctx?.run.id,
1389
+ idempotencyKey: batchIdempotencyKey?.toString(),
1390
+ idempotencyKeyOptions: batchIdempotencyKeyOptions,
1391
+ spanParentAsLink: true, // Fire-and-forget: child runs get separate trace IDs
1392
+ }, requestOptions);
1393
+ span.setAttribute("batchId", result.id);
1394
+ span.setAttribute("runCount", result.runCount);
1395
+ return result;
1396
+ }, {
1397
+ kind: SpanKind.PRODUCER,
1398
+ attributes: {
1399
+ [SemanticInternalAttributes.STYLE_ICON]: "trigger",
1400
+ ...accessoryAttributes({
1401
+ items: [
1402
+ {
1403
+ text: taskIdentifier,
1404
+ variant: "normal",
1405
+ },
1406
+ ],
1407
+ style: "codepath",
1408
+ }),
1409
+ },
1410
+ });
1411
+ const handle = {
1412
+ batchId: response.id,
1413
+ runCount: response.runCount,
1414
+ publicAccessToken: response.publicAccessToken,
1415
+ };
1416
+ return handle;
1417
+ }
1418
+ else {
1419
+ // Stream path: convert to AsyncIterable and transform
1420
+ const asyncItems = normalizeToAsyncIterable(items);
1421
+ const transformedItems = transformSingleTaskBatchItemsStream(taskIdentifier, asyncItems, parsePayload, options, queue);
1422
+ // Execute streaming 2-phase batch
1423
+ // Process batch-level idempotency key
1424
+ const streamBatchIdempotencyKey = await makeIdempotencyKey(options?.idempotencyKey);
1425
+ const streamBatchIdempotencyKeyOptions = streamBatchIdempotencyKey
1426
+ ? getIdempotencyKeyOptions(streamBatchIdempotencyKey)
1427
+ : undefined;
1428
+ const response = await tracer.startActiveSpan(name, async (span) => {
1429
+ const result = await executeBatchTwoPhaseStreaming(apiClient, transformedItems, {
1430
+ parentRunId: ctx?.run.id,
1431
+ idempotencyKey: streamBatchIdempotencyKey?.toString(),
1432
+ idempotencyKeyOptions: streamBatchIdempotencyKeyOptions,
1433
+ spanParentAsLink: true, // Fire-and-forget: child runs get separate trace IDs
1434
+ }, requestOptions);
1435
+ span.setAttribute("batchId", result.id);
1436
+ span.setAttribute("runCount", result.runCount);
1437
+ return result;
1438
+ }, {
1439
+ kind: SpanKind.PRODUCER,
1440
+ attributes: {
1441
+ [SemanticInternalAttributes.STYLE_ICON]: "trigger",
1442
+ ...accessoryAttributes({
1443
+ items: [
1444
+ {
1445
+ text: taskIdentifier,
1446
+ variant: "normal",
1447
+ },
1448
+ ],
1449
+ style: "codepath",
1450
+ }),
1451
+ },
1452
+ });
1453
+ const handle = {
1454
+ batchId: response.id,
1455
+ runCount: response.runCount,
1456
+ publicAccessToken: response.publicAccessToken,
1457
+ };
1458
+ return handle;
1459
+ }
921
1460
  }
922
1461
  async function triggerAndWait_internal(name, id, payload, parsePayload, options, requestOptions) {
923
1462
  const ctx = taskContext.ctx;
924
1463
  if (!ctx) {
925
1464
  throw new Error("triggerAndWait can only be used from inside a task.run()");
926
1465
  }
927
- const apiClient = apiClientManager.clientOrThrow();
1466
+ const apiClient = apiClientManager.clientOrThrow(requestOptions?.clientConfig);
928
1467
  const parsedPayload = parsePayload ? await parsePayload(payload) : payload;
929
- const payloadPacket = await stringifyIO(parsedPayload);
1468
+ const { packet: triggerPayloadPacket, payloadSize } = await prepareTriggerPayload(parsedPayload, apiClient);
1469
+ // Process idempotency key and extract options for storage
1470
+ const processedIdempotencyKey = await makeIdempotencyKey(options?.idempotencyKey);
1471
+ const idempotencyKeyOptions = processedIdempotencyKey
1472
+ ? getIdempotencyKeyOptions(processedIdempotencyKey)
1473
+ : undefined;
930
1474
  return await tracer.startActiveSpan(name, async (span) => {
931
1475
  const response = await apiClient.triggerTask(id, {
932
- payload: payloadPacket.data,
1476
+ payload: triggerPayloadPacket.data,
933
1477
  options: {
934
- dependentAttempt: ctx.attempt.id,
935
1478
  lockToVersion: taskContext.worker?.version, // Lock to current version because we're waiting for it to finish
936
- queue: options?.queue,
1479
+ ...triggerQueueBody(options?.queue),
1480
+ ...triggerConcurrencyBody(options?.concurrency),
937
1481
  concurrencyKey: options?.concurrencyKey,
938
1482
  test: taskContext.ctx?.run.isTest,
939
- payloadType: payloadPacket.dataType,
1483
+ payloadType: triggerPayloadPacket.dataType,
1484
+ payloadSize,
940
1485
  delay: options?.delay,
941
1486
  ttl: options?.ttl,
942
1487
  tags: options?.tags,
943
1488
  maxAttempts: options?.maxAttempts,
944
1489
  metadata: options?.metadata,
945
1490
  maxDuration: options?.maxDuration,
1491
+ resumeParentOnCompletion: true,
1492
+ parentRunId: ctx.run.id,
1493
+ idempotencyKey: processedIdempotencyKey?.toString(),
1494
+ idempotencyKeyTTL: options?.idempotencyKeyTTL,
1495
+ idempotencyKeyOptions,
946
1496
  machine: options?.machine,
1497
+ priority: options?.priority,
1498
+ region: options?.region,
1499
+ debounce: options?.debounce,
947
1500
  },
948
1501
  }, {}, requestOptions);
949
1502
  span.setAttribute("runId", response.id);
@@ -968,59 +1521,118 @@ async function triggerAndWait_internal(name, id, payload, parsePayload, options,
968
1521
  },
969
1522
  });
970
1523
  }
971
- async function batchTriggerAndWait_internal(name, id, items, parsePayload, options, requestOptions, queue) {
1524
+ async function triggerAndSubscribe_internal(name, id, payload, parsePayload, options, requestOptions) {
972
1525
  const ctx = taskContext.ctx;
973
1526
  if (!ctx) {
974
- throw new Error("batchTriggerAndWait can only be used from inside a task.run()");
1527
+ throw new Error("triggerAndSubscribe can only be used from inside a task.run()");
975
1528
  }
976
- const apiClient = apiClientManager.clientOrThrow();
1529
+ const apiClient = apiClientManager.clientOrThrow(requestOptions?.clientConfig);
1530
+ const parsedPayload = parsePayload ? await parsePayload(payload) : payload;
1531
+ const { packet: triggerPayloadPacket, payloadSize } = await prepareTriggerPayload(parsedPayload, apiClient);
1532
+ const processedIdempotencyKey = await makeIdempotencyKey(options?.idempotencyKey);
1533
+ const idempotencyKeyOptions = processedIdempotencyKey
1534
+ ? getIdempotencyKeyOptions(processedIdempotencyKey)
1535
+ : undefined;
977
1536
  return await tracer.startActiveSpan(name, async (span) => {
978
- const response = await apiClient.batchTriggerV2({
979
- items: await Promise.all(items.map(async (item) => {
980
- const parsedPayload = parsePayload ? await parsePayload(item.payload) : item.payload;
981
- const payloadPacket = await stringifyIO(parsedPayload);
982
- return {
983
- task: id,
984
- payload: payloadPacket.data,
985
- options: {
986
- lockToVersion: taskContext.worker?.version,
987
- queue: item.options?.queue ?? queue,
988
- concurrencyKey: item.options?.concurrencyKey,
989
- test: taskContext.ctx?.run.isTest,
990
- payloadType: payloadPacket.dataType,
991
- delay: item.options?.delay,
992
- ttl: item.options?.ttl,
993
- tags: item.options?.tags,
994
- maxAttempts: item.options?.maxAttempts,
995
- metadata: item.options?.metadata,
996
- maxDuration: item.options?.maxDuration,
997
- machine: item.options?.machine,
998
- },
999
- };
1000
- })),
1001
- dependentAttempt: ctx.attempt.id,
1002
- }, {
1003
- processingStrategy: options?.triggerSequentially ? "sequential" : undefined,
1004
- }, requestOptions);
1005
- span.setAttribute("batchId", response.id);
1006
- span.setAttribute("runCount", response.runs.length);
1007
- span.setAttribute("isCached", response.isCached);
1008
- if (response.isCached) {
1009
- console.warn(`Result is a cached response because the request was idempotent.`);
1537
+ const response = await apiClient.triggerTask(id, {
1538
+ payload: triggerPayloadPacket.data,
1539
+ options: {
1540
+ lockToVersion: taskContext.worker?.version,
1541
+ ...triggerQueueBody(options?.queue),
1542
+ ...triggerConcurrencyBody(options?.concurrency),
1543
+ concurrencyKey: options?.concurrencyKey,
1544
+ test: taskContext.ctx?.run.isTest,
1545
+ payloadType: triggerPayloadPacket.dataType,
1546
+ payloadSize,
1547
+ delay: options?.delay,
1548
+ ttl: options?.ttl,
1549
+ tags: options?.tags,
1550
+ maxAttempts: options?.maxAttempts,
1551
+ metadata: options?.metadata,
1552
+ maxDuration: options?.maxDuration,
1553
+ parentRunId: ctx.run.id,
1554
+ // NOTE: no resumeParentOnCompletion — parent stays alive and subscribes
1555
+ idempotencyKey: processedIdempotencyKey?.toString(),
1556
+ idempotencyKeyTTL: options?.idempotencyKeyTTL,
1557
+ idempotencyKeyOptions,
1558
+ machine: options?.machine,
1559
+ priority: options?.priority,
1560
+ region: options?.region,
1561
+ debounce: options?.debounce,
1562
+ },
1563
+ }, {}, requestOptions);
1564
+ // Set attributes after trigger so the dashboard can link to the child run
1565
+ span.setAttribute("messaging.message.id", response.id);
1566
+ span.setAttribute("runId", response.id);
1567
+ span.setAttribute(SemanticInternalAttributes.ENTITY_TYPE, "run");
1568
+ span.setAttribute(SemanticInternalAttributes.ENTITY_ID, response.id);
1569
+ // Optionally cancel the child run when the abort signal fires (default: true)
1570
+ const cancelOnAbort = options?.cancelOnAbort !== false;
1571
+ let onAbort;
1572
+ if (options?.signal && cancelOnAbort) {
1573
+ if (options.signal.aborted) {
1574
+ await apiClient.cancelRun(response.id).catch(() => { });
1575
+ throw new DOMException("Aborted", "AbortError");
1576
+ }
1577
+ onAbort = () => {
1578
+ apiClient.cancelRun(response.id).catch(() => { });
1579
+ };
1580
+ // `{ once: true }` auto-removes the listener on abort, but if the
1581
+ // run completes normally the listener stays attached and pins
1582
+ // `apiClient` + `response.id` until the signal is GC'd. Long-lived
1583
+ // signals shared across many calls accumulate dead listeners; the
1584
+ // `finally` below removes the listener on every exit path.
1585
+ options.signal.addEventListener("abort", onAbort, { once: true });
1586
+ }
1587
+ try {
1588
+ for await (const run of apiClient.subscribeToRun(response.id, {
1589
+ closeOnComplete: true,
1590
+ signal: options?.signal,
1591
+ skipColumns: ["payload"],
1592
+ })) {
1593
+ if (run.isSuccess) {
1594
+ // run.output from subscribeToRun is already deserialized
1595
+ return {
1596
+ ok: true,
1597
+ id: response.id,
1598
+ taskIdentifier: id,
1599
+ output: run.output,
1600
+ };
1601
+ }
1602
+ if (run.isFailed || run.isCancelled) {
1603
+ // Note: this intentionally diverges from `triggerAndWait`'s
1604
+ // error shape. `triggerAndWait` receives a full `TaskRunError`
1605
+ // (with `type` discriminator: BUILT_IN_ERROR, CUSTOM_ERROR,
1606
+ // INTERNAL_ERROR, STRING_ERROR) via the completion message and
1607
+ // passes it through `createErrorTaskError` to preserve the
1608
+ // discriminator. `subscribeToRun` only surfaces a
1609
+ // `SerializedError` (`{ name, message, stackTrace, causes }`)
1610
+ // because `createJsonErrorObject` strips the discriminator before
1611
+ // the record hits the realtime stream. We can't reconstruct the
1612
+ // discriminator here without lossy guessing — callers that
1613
+ // need exact error-type matching should use `triggerAndWait`
1614
+ // instead; subscribers get message, name and the cause chain.
1615
+ const cause = run.error?.causes?.length
1616
+ ? createErrorFromCauses(run.error.causes)
1617
+ : undefined;
1618
+ const error = new Error(run.error?.message ?? `Task ${id} failed (${run.status})`, cause ? { cause } : undefined);
1619
+ if (run.error?.name)
1620
+ error.name = run.error.name;
1621
+ return {
1622
+ ok: false,
1623
+ id: response.id,
1624
+ taskIdentifier: id,
1625
+ error,
1626
+ };
1627
+ }
1628
+ }
1629
+ throw new Error(`Task ${id}: subscription ended without completion`);
1010
1630
  }
1011
- if (response.idempotencyKey) {
1012
- span.setAttribute("idempotencyKey", response.idempotencyKey);
1631
+ finally {
1632
+ if (onAbort && options?.signal) {
1633
+ options.signal.removeEventListener("abort", onAbort);
1634
+ }
1013
1635
  }
1014
- const result = await runtime.waitForBatch({
1015
- id: response.id,
1016
- runs: response.runs.map((run) => run.id),
1017
- ctx,
1018
- });
1019
- const runs = await handleBatchTaskRunExecutionResult(result.items, id);
1020
- return {
1021
- id: result.id,
1022
- runs,
1023
- };
1024
1636
  }, {
1025
1637
  kind: SpanKind.PRODUCER,
1026
1638
  attributes: {
@@ -1037,6 +1649,141 @@ async function batchTriggerAndWait_internal(name, id, items, parsePayload, optio
1037
1649
  },
1038
1650
  });
1039
1651
  }
1652
+ async function batchTriggerAndWait_internal(name, id, items, parsePayload, options, requestOptions, queue) {
1653
+ const ctx = taskContext.ctx;
1654
+ if (!ctx) {
1655
+ throw new Error("batchTriggerAndWait can only be used from inside a task.run()");
1656
+ }
1657
+ const apiClient = apiClientManager.clientOrThrow(requestOptions?.clientConfig);
1658
+ // Check if items is an array or a stream
1659
+ if (Array.isArray(items)) {
1660
+ // Prepare items as BatchItemNDJSON
1661
+ const ndJsonItems = await Promise.all(items.map(async (item, index) => {
1662
+ const parsedPayload = parsePayload ? await parsePayload(item.payload) : item.payload;
1663
+ const payloadPacket = await stringifyIO(parsedPayload);
1664
+ const batchItemIdempotencyKey = await makeIdempotencyKey(flattenIdempotencyKey([options?.idempotencyKey, `${index}`]));
1665
+ // Process item-specific idempotency key and extract options
1666
+ const itemIdempotencyKey = await makeIdempotencyKey(item.options?.idempotencyKey);
1667
+ const finalIdempotencyKey = itemIdempotencyKey ?? batchItemIdempotencyKey;
1668
+ const idempotencyKeyOptions = itemIdempotencyKey
1669
+ ? getIdempotencyKeyOptions(itemIdempotencyKey)
1670
+ : undefined;
1671
+ return {
1672
+ index,
1673
+ task: id,
1674
+ payload: payloadPacket.data,
1675
+ options: {
1676
+ lockToVersion: taskContext.worker?.version,
1677
+ ...triggerQueueBody(item.options?.queue, queue),
1678
+ ...triggerConcurrencyBody(item.options?.concurrency),
1679
+ concurrencyKey: item.options?.concurrencyKey,
1680
+ test: taskContext.ctx?.run.isTest,
1681
+ payloadType: payloadPacket.dataType,
1682
+ delay: item.options?.delay,
1683
+ ttl: item.options?.ttl,
1684
+ tags: item.options?.tags,
1685
+ maxAttempts: item.options?.maxAttempts,
1686
+ metadata: item.options?.metadata,
1687
+ maxDuration: item.options?.maxDuration,
1688
+ idempotencyKey: finalIdempotencyKey?.toString(),
1689
+ idempotencyKeyTTL: item.options?.idempotencyKeyTTL ?? options?.idempotencyKeyTTL,
1690
+ idempotencyKeyOptions,
1691
+ machine: item.options?.machine,
1692
+ priority: item.options?.priority,
1693
+ region: item.options?.region,
1694
+ debounce: item.options?.debounce,
1695
+ },
1696
+ };
1697
+ }));
1698
+ // Process batch-level idempotency key
1699
+ const batchIdempotencyKey = await makeIdempotencyKey(options?.idempotencyKey);
1700
+ const batchIdempotencyKeyOptions = batchIdempotencyKey
1701
+ ? getIdempotencyKeyOptions(batchIdempotencyKey)
1702
+ : undefined;
1703
+ return await tracer.startActiveSpan(name, async (span) => {
1704
+ // Execute 2-phase batch
1705
+ const response = await executeBatchTwoPhase(apiClient, ndJsonItems, {
1706
+ parentRunId: ctx.run.id,
1707
+ resumeParentOnCompletion: true,
1708
+ idempotencyKey: batchIdempotencyKey?.toString(),
1709
+ idempotencyKeyOptions: batchIdempotencyKeyOptions,
1710
+ spanParentAsLink: false, // Waiting: child runs share parent's trace ID
1711
+ }, requestOptions);
1712
+ span.setAttribute("batchId", response.id);
1713
+ span.setAttribute("runCount", response.runCount);
1714
+ const result = await runtime.waitForBatch({
1715
+ id: response.id,
1716
+ runCount: response.runCount,
1717
+ ctx,
1718
+ });
1719
+ const runs = await handleBatchTaskRunExecutionResult(result.items, id);
1720
+ return {
1721
+ id: result.id,
1722
+ runs,
1723
+ };
1724
+ }, {
1725
+ kind: SpanKind.PRODUCER,
1726
+ attributes: {
1727
+ [SemanticInternalAttributes.STYLE_ICON]: "trigger",
1728
+ ...accessoryAttributes({
1729
+ items: [
1730
+ {
1731
+ text: id,
1732
+ variant: "normal",
1733
+ },
1734
+ ],
1735
+ style: "codepath",
1736
+ }),
1737
+ },
1738
+ });
1739
+ }
1740
+ else {
1741
+ // Stream path: convert to AsyncIterable and transform
1742
+ const asyncItems = normalizeToAsyncIterable(items);
1743
+ const transformedItems = transformSingleTaskBatchItemsStreamForWait(id, asyncItems, parsePayload, options, queue);
1744
+ // Process batch-level idempotency key for streaming path
1745
+ const streamBatchIdempotencyKey = await makeIdempotencyKey(options?.idempotencyKey);
1746
+ const streamBatchIdempotencyKeyOptions = streamBatchIdempotencyKey
1747
+ ? getIdempotencyKeyOptions(streamBatchIdempotencyKey)
1748
+ : undefined;
1749
+ return await tracer.startActiveSpan(name, async (span) => {
1750
+ // Execute streaming 2-phase batch
1751
+ const response = await executeBatchTwoPhaseStreaming(apiClient, transformedItems, {
1752
+ parentRunId: ctx.run.id,
1753
+ resumeParentOnCompletion: true,
1754
+ idempotencyKey: streamBatchIdempotencyKey?.toString(),
1755
+ idempotencyKeyOptions: streamBatchIdempotencyKeyOptions,
1756
+ spanParentAsLink: false, // Waiting: child runs share parent's trace ID
1757
+ }, requestOptions);
1758
+ span.setAttribute("batchId", response.id);
1759
+ span.setAttribute("runCount", response.runCount);
1760
+ const result = await runtime.waitForBatch({
1761
+ id: response.id,
1762
+ runCount: response.runCount,
1763
+ ctx,
1764
+ });
1765
+ const runs = await handleBatchTaskRunExecutionResult(result.items, id);
1766
+ return {
1767
+ id: result.id,
1768
+ runs,
1769
+ };
1770
+ }, {
1771
+ kind: SpanKind.PRODUCER,
1772
+ attributes: {
1773
+ [SemanticInternalAttributes.STYLE_ICON]: "trigger",
1774
+ ...accessoryAttributes({
1775
+ items: [
1776
+ {
1777
+ text: id,
1778
+ variant: "normal",
1779
+ },
1780
+ ],
1781
+ style: "codepath",
1782
+ }),
1783
+ },
1784
+ });
1785
+ }
1786
+ }
1040
1787
  async function handleBatchTaskRunExecutionResult(items, taskIdentifier) {
1041
1788
  const someObjectStoreOutputs = items.some((item) => item.ok && item.outputType === "application/store");
1042
1789
  if (!someObjectStoreOutputs) {
@@ -1055,17 +1802,17 @@ async function handleBatchTaskRunExecutionResult(items, taskIdentifier) {
1055
1802
  [SemanticInternalAttributes.STYLE_ICON]: "cloud-download",
1056
1803
  });
1057
1804
  }
1058
- async function handleBatchTaskRunExecutionResultV2(items) {
1805
+ async function handleBatchTaskRunExecutionResultV2(items, taskIdentifiers) {
1059
1806
  const someObjectStoreOutputs = items.some((item) => item.ok && item.outputType === "application/store");
1060
1807
  if (!someObjectStoreOutputs) {
1061
- const results = await Promise.all(items.map(async (item) => {
1062
- return await handleTaskRunExecutionResult(item, item.taskIdentifier ?? "unknown");
1808
+ const results = await Promise.all(items.map(async (item, index) => {
1809
+ return await handleTaskRunExecutionResult(item, item.taskIdentifier ?? taskIdentifiers?.[index] ?? "unknown");
1063
1810
  }));
1064
1811
  return results;
1065
1812
  }
1066
1813
  return await tracer.startActiveSpan("store.downloadPayloads", async (span) => {
1067
- const results = await Promise.all(items.map(async (item) => {
1068
- return await handleTaskRunExecutionResult(item, item.taskIdentifier ?? "unknown");
1814
+ const results = await Promise.all(items.map(async (item, index) => {
1815
+ return await handleTaskRunExecutionResult(item, item.taskIdentifier ?? taskIdentifiers?.[index] ?? "unknown");
1069
1816
  }));
1070
1817
  return results;
1071
1818
  }, {
@@ -1093,4 +1840,90 @@ async function handleTaskRunExecutionResult(execution, taskIdentifier) {
1093
1840
  };
1094
1841
  }
1095
1842
  }
1843
+ function registerTaskLifecycleHooks(taskId, params) {
1844
+ if (params.init) {
1845
+ lifecycleHooks.registerTaskInitHook(taskId, {
1846
+ fn: params.init,
1847
+ });
1848
+ }
1849
+ if (params.onStart) {
1850
+ lifecycleHooks.registerTaskStartHook(taskId, {
1851
+ fn: params.onStart,
1852
+ });
1853
+ }
1854
+ if (params.onStartAttempt) {
1855
+ lifecycleHooks.registerTaskStartAttemptHook(taskId, {
1856
+ fn: params.onStartAttempt,
1857
+ });
1858
+ }
1859
+ if (params.onFailure) {
1860
+ lifecycleHooks.registerTaskFailureHook(taskId, {
1861
+ fn: params.onFailure,
1862
+ });
1863
+ }
1864
+ if (params.onSuccess) {
1865
+ lifecycleHooks.registerTaskSuccessHook(taskId, {
1866
+ fn: params.onSuccess,
1867
+ });
1868
+ }
1869
+ if (params.onComplete) {
1870
+ lifecycleHooks.registerTaskCompleteHook(taskId, {
1871
+ fn: params.onComplete,
1872
+ });
1873
+ }
1874
+ if (params.onWait) {
1875
+ lifecycleHooks.registerTaskWaitHook(taskId, {
1876
+ fn: params.onWait,
1877
+ });
1878
+ }
1879
+ if (params.onResume) {
1880
+ lifecycleHooks.registerTaskResumeHook(taskId, {
1881
+ fn: params.onResume,
1882
+ });
1883
+ }
1884
+ if (params.catchError) {
1885
+ // We don't need to use an adapter here because catchError is the new version of handleError
1886
+ lifecycleHooks.registerTaskCatchErrorHook(taskId, {
1887
+ fn: params.catchError,
1888
+ });
1889
+ }
1890
+ if (params.handleError) {
1891
+ lifecycleHooks.registerTaskCatchErrorHook(taskId, {
1892
+ fn: params.handleError,
1893
+ });
1894
+ }
1895
+ if (params.middleware) {
1896
+ lifecycleHooks.registerTaskMiddlewareHook(taskId, {
1897
+ fn: params.middleware,
1898
+ });
1899
+ }
1900
+ if (params.cleanup) {
1901
+ lifecycleHooks.registerTaskCleanupHook(taskId, {
1902
+ fn: params.cleanup,
1903
+ });
1904
+ }
1905
+ if (params.onCancel) {
1906
+ lifecycleHooks.registerTaskCancelHook(taskId, {
1907
+ fn: params.onCancel,
1908
+ });
1909
+ }
1910
+ }
1911
+ async function prepareTriggerPayload(payload, apiClient) {
1912
+ const payloadPacket = await stringifyIO(payload);
1913
+ // Measure the serialized size before any offload, so it reflects the real payload
1914
+ // size rather than the small "application/store" reference we may send instead.
1915
+ const { size: payloadSize } = packetRequiresOffloading(payloadPacket);
1916
+ const packet = await conditionallyExportPacket(payloadPacket, createTriggerPayloadPathPrefix(), undefined, apiClient);
1917
+ return { packet, payloadSize };
1918
+ }
1919
+ /**
1920
+ * Build the object-storage path prefix for an offloaded trigger payload.
1921
+ *
1922
+ * Every segment is generated here, so nothing caller-controlled reaches the key.
1923
+ * The id's alphabet is lowercase alphanumeric, which no layer between here and the
1924
+ * object store rewrites, so the path the SDK asks for is the path that gets stored.
1925
+ */
1926
+ function createTriggerPayloadPathPrefix() {
1927
+ return `trigger/${generateFriendlyId("packet")}/payload`;
1928
+ }
1096
1929
  //# sourceMappingURL=shared.js.map