@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
@@ -0,0 +1,1662 @@
1
+ "use strict";
2
+ /**
3
+ * @module @trigger.dev/sdk/chat
4
+ *
5
+ * Browser-safe module for AI SDK chat transport integration.
6
+ * Use this on the frontend with the AI SDK's `useChat` hook.
7
+ *
8
+ * For backend helpers (`chatAgent`, `pipeChat`), use `@trigger.dev/sdk/ai` instead.
9
+ *
10
+ * @example
11
+ * ```tsx
12
+ * import { useChat } from "@ai-sdk/react";
13
+ * import { TriggerChatTransport } from "@trigger.dev/sdk/chat";
14
+ *
15
+ * function Chat() {
16
+ * const { messages, sendMessage, status } = useChat({
17
+ * transport: new TriggerChatTransport({
18
+ * task: "my-chat-task",
19
+ * accessToken: async ({ chatId }) => fetchSessionToken(chatId),
20
+ * startSession: async ({ chatId, taskId }) => createChatSession({ chatId, taskId }),
21
+ * }),
22
+ * });
23
+ * }
24
+ * ```
25
+ */
26
+ Object.defineProperty(exports, "__esModule", { value: true });
27
+ exports.ChatStream = exports.AgentChat = exports.TriggerChatTransport = void 0;
28
+ exports.createChatTransport = createChatTransport;
29
+ const v3_1 = require("@trigger.dev/core/v3");
30
+ function byteLength(body) {
31
+ return new TextEncoder().encode(body).byteLength;
32
+ }
33
+ const chat_tab_coordinator_js_1 = require("./chat-tab-coordinator.js");
34
+ const ai_shared_js_1 = require("./ai-shared.js");
35
+ const DEFAULT_BASE_URL = "https://api.trigger.dev";
36
+ const DEFAULT_STREAM_TIMEOUT_SECONDS = 120;
37
+ /**
38
+ * Detect 401/403 from realtime/input-stream calls without relying on `instanceof`
39
+ * (Vitest can load duplicate `@trigger.dev/core` copies, which breaks subclass checks).
40
+ */
41
+ function isAuthError(error) {
42
+ if (error === null || typeof error !== "object")
43
+ return false;
44
+ const e = error;
45
+ return e.name === "TriggerApiError" && (e.status === 401 || e.status === 403);
46
+ }
47
+ /**
48
+ * Detect the closed-session refusal from `.in/append`: HTTP 409 with the
49
+ * stable `session_closed` code. Terminal — never retried.
50
+ */
51
+ function isSessionClosedError(error) {
52
+ if (error === null || typeof error !== "object")
53
+ return false;
54
+ const e = error;
55
+ return e.name === "TriggerApiError" && e.status === 409 && e.code === "session_closed";
56
+ }
57
+ function sessionClosedReasonOf(error) {
58
+ if (error === null || typeof error !== "object")
59
+ return undefined;
60
+ const reason = error.closedReason;
61
+ return typeof reason === "string" ? reason : undefined;
62
+ }
63
+ /** The local form of the refusal, for sends the transport rejects itself. */
64
+ function sessionClosedError(chatId, reason) {
65
+ const err = new Error(reason ? `Chat session ${chatId} is closed: ${reason}` : `Chat session ${chatId} is closed`);
66
+ err.name = "TriggerApiError";
67
+ err.status = 409;
68
+ err.code = "session_closed";
69
+ if (reason)
70
+ err.closedReason = reason;
71
+ return err;
72
+ }
73
+ /**
74
+ * Detect a 404 from a session-PAT-authed call — i.e. the session doesn't
75
+ * exist in the current environment. Happens when hydrated session state
76
+ * (the `sessions` option / a customer's persisted record) was created in a
77
+ * different trigger environment, or predates the upgrade to the sessions
78
+ * model, so there's no real Session row behind the cached PAT.
79
+ */
80
+ function isSessionNotFoundError(error) {
81
+ if (error === null || typeof error !== "object")
82
+ return false;
83
+ const e = error;
84
+ return e.name === "TriggerApiError" && e.status === 404;
85
+ }
86
+ /**
87
+ * Parses an SSE byte/text stream of `data: <UIMessageChunk JSON>\n\n`
88
+ * frames back into `UIMessageChunk` objects. Used by the handover
89
+ * first-turn path to convert the customer's route handler response
90
+ * (which is AI-SDK-shaped SSE text) into the chunk form the AI SDK's
91
+ * `useChat` consumes from a transport.
92
+ *
93
+ * Spec-light parser — assumes well-formed `data:` events from our own
94
+ * `chat.handover` SSE writer. Lines starting with `:` (comments) and
95
+ * other event types are ignored.
96
+ */
97
+ function parseUIMessageSseTransform() {
98
+ let buffer = "";
99
+ return new TransformStream({
100
+ transform(chunk, controller) {
101
+ buffer += chunk;
102
+ // Frames are separated by blank lines.
103
+ let idx = buffer.indexOf("\n\n");
104
+ while (idx !== -1) {
105
+ const frame = buffer.slice(0, idx);
106
+ buffer = buffer.slice(idx + 2);
107
+ for (const line of frame.split("\n")) {
108
+ if (line.startsWith("data: ")) {
109
+ const data = line.slice(6).trim();
110
+ if (!data)
111
+ continue;
112
+ try {
113
+ controller.enqueue(JSON.parse(data));
114
+ }
115
+ catch {
116
+ /* drop malformed chunk; the response source is our own writer */
117
+ }
118
+ }
119
+ }
120
+ idx = buffer.indexOf("\n\n");
121
+ }
122
+ },
123
+ flush(controller) {
124
+ // Trailing data without a closing blank line — treat as a final frame.
125
+ if (buffer.trim().length === 0)
126
+ return;
127
+ for (const line of buffer.split("\n")) {
128
+ if (line.startsWith("data: ")) {
129
+ const data = line.slice(6).trim();
130
+ if (!data)
131
+ continue;
132
+ try {
133
+ controller.enqueue(JSON.parse(data));
134
+ }
135
+ catch {
136
+ /* drop */
137
+ }
138
+ }
139
+ }
140
+ buffer = "";
141
+ },
142
+ });
143
+ }
144
+ /**
145
+ * A custom AI SDK `ChatTransport` that runs chat completions as durable
146
+ * Trigger.dev tasks via the Sessions primitive.
147
+ *
148
+ * Lifecycle:
149
+ * 1. Customer pre-creates the session server-side OR calls
150
+ * `transport.start(chatId)` to mint a one-shot start token and
151
+ * `POST /api/v1/sessions` from the browser.
152
+ * 2. The server triggers the first run as part of session create and
153
+ * returns a session-scoped PAT.
154
+ * 3. `sendMessages` appends to `.in` and subscribes to `.out`. When a
155
+ * run dies (idle, cancel, end-and-continue), the server's
156
+ * append-time probe triggers a fresh run for the same session —
157
+ * transport keeps streaming.
158
+ * 4. `stop()` posts a `{kind:"stop"}` chunk; the agent's turn aborts
159
+ * but the run keeps reading `.in` for the next message.
160
+ * 5. PAT expiry: transport invokes `accessToken` to refresh and
161
+ * retries the failing request once.
162
+ */
163
+ class TriggerChatTransport {
164
+ taskId;
165
+ resolveAccessToken;
166
+ resolveStartSession;
167
+ resolveBaseURLFn;
168
+ fetchOverride;
169
+ extraHeaders;
170
+ streamTimeoutSeconds;
171
+ defaultMetadata;
172
+ watchMode;
173
+ headStart;
174
+ coordinator = null;
175
+ _onSessionChange;
176
+ _onEvent;
177
+ sessions = new Map();
178
+ pendingResumeCursors = new Map();
179
+ activeStreams = new Map();
180
+ pendingStarts = new Map();
181
+ // Last turn-producing send per chat — attribution source for the
182
+ // response-side events' `messageId` / `sinceSendMs`.
183
+ lastTurnSends = new Map();
184
+ constructor(options) {
185
+ this.taskId = options.task;
186
+ this.resolveAccessToken = options.accessToken;
187
+ this.resolveStartSession = options.startSession;
188
+ const baseURLOption = options.baseURL ?? DEFAULT_BASE_URL;
189
+ const streamOverride = options.streamBaseURL;
190
+ this.resolveBaseURLFn =
191
+ typeof baseURLOption === "function"
192
+ ? (ctx) => (ctx.endpoint === "out" && streamOverride ? streamOverride : baseURLOption(ctx))
193
+ : (ctx) => (ctx.endpoint === "out" && streamOverride ? streamOverride : baseURLOption);
194
+ this.fetchOverride = options.fetch;
195
+ this.extraHeaders = options.headers ?? {};
196
+ this.streamTimeoutSeconds = options.streamTimeoutSeconds ?? DEFAULT_STREAM_TIMEOUT_SECONDS;
197
+ this.defaultMetadata = options.clientData;
198
+ this._onSessionChange = options.onSessionChange;
199
+ this._onEvent = options.onEvent;
200
+ this.watchMode = options.watch ?? false;
201
+ this.headStart = options.headStart;
202
+ if (options.multiTab && !this.watchMode) {
203
+ this.coordinator = new chat_tab_coordinator_js_1.ChatTabCoordinator();
204
+ this.coordinator.addSessionListener((chatId, sessionUpdate) => {
205
+ const session = this.sessions.get(chatId);
206
+ if (session && sessionUpdate.lastEventId) {
207
+ session.lastEventId = sessionUpdate.lastEventId;
208
+ }
209
+ });
210
+ }
211
+ if (options.sessions) {
212
+ for (const [chatId, session] of Object.entries(options.sessions)) {
213
+ this.sessions.set(chatId, {
214
+ publicAccessToken: session.publicAccessToken,
215
+ lastEventId: session.lastEventId,
216
+ activeInputSeq: session.activeInputSeq,
217
+ isStreaming: session.isStreaming,
218
+ closed: session.closed,
219
+ closedReason: session.closedReason,
220
+ });
221
+ }
222
+ }
223
+ }
224
+ // -------------------------------------------------------------------------
225
+ // Public lifecycle
226
+ // -------------------------------------------------------------------------
227
+ /**
228
+ * Eagerly create a Session and trigger its first run. Useful as a
229
+ * "the user might be about to send a message — boot the agent now"
230
+ * preload, or to take ownership of the session before any sendMessage.
231
+ *
232
+ * Idempotent: calling `start(chatId)` twice converges to the same
233
+ * session via the `(env, externalId)` upsert. Concurrent calls
234
+ * deduplicate via an in-flight promise.
235
+ *
236
+ * Requires `getStartToken` to be configured. Customers who pre-create
237
+ * sessions server-side don't need to call this.
238
+ */
239
+ async start(chatId) {
240
+ const existing = this.sessions.get(chatId);
241
+ if (existing?.publicAccessToken) {
242
+ return this.toPersisted(existing);
243
+ }
244
+ const inflight = this.pendingStarts.get(chatId);
245
+ if (inflight)
246
+ return inflight.then(this.toPersisted);
247
+ const promise = this.doStart(chatId).finally(() => {
248
+ this.pendingStarts.delete(chatId);
249
+ });
250
+ this.pendingStarts.set(chatId, promise);
251
+ return promise.then(this.toPersisted);
252
+ }
253
+ /**
254
+ * Eagerly create the session before the user types. Same semantics as
255
+ * {@link start} — kept as a separate name for the AI SDK Chat hook,
256
+ * which calls `preload` rather than `start`.
257
+ */
258
+ async preload(chatId) {
259
+ await this.start(chatId);
260
+ }
261
+ /**
262
+ * Send a user message via the session's `.in` channel. The server
263
+ * probes `currentRunId`; if terminal/null it triggers a fresh run on
264
+ * the same session before the append lands. The returned
265
+ * `ReadableStream` carries the agent's response chunks via `.out` SSE.
266
+ */
267
+ sendMessages = async (options) => {
268
+ const { trigger, chatId, messageId, messages, abortSignal, body, metadata } = options;
269
+ const closedState = this.sessions.get(chatId);
270
+ if (closedState?.closed) {
271
+ throw sessionClosedError(chatId, closedState.closedReason);
272
+ }
273
+ if (this.coordinator) {
274
+ if (this.coordinator.isReadOnly(chatId)) {
275
+ throw new Error("This chat is active in another tab");
276
+ }
277
+ this.coordinator.claim(chatId);
278
+ }
279
+ const mergedMetadata = this.defaultMetadata || metadata
280
+ ? { ...(this.defaultMetadata ?? {}), ...(metadata ?? {}) }
281
+ : undefined;
282
+ // An action sent through `useChat`. `useChatActions` (or any caller) puts
283
+ // it in `body.action`; sending it here rather than through
284
+ // `transport.sendAction` means `useChat` owns the response stream, so an
285
+ // action that becomes a turn renders the way a message turn does.
286
+ const actionInBody = body?.action;
287
+ if (actionInBody !== undefined) {
288
+ return this.sendAction(chatId, actionInBody, { abortSignal, metadata: mergedMetadata });
289
+ }
290
+ // First-turn handover routing — when `headStart` is set AND no
291
+ // session state exists yet for this chatId, POST the wire payload
292
+ // to the customer's `chat.handover` route handler. The handler
293
+ // creates the session, triggers the agent run with
294
+ // `handover-prepare`, runs `streamText` step 1 in its warm
295
+ // process, and tees the output back as the SSE response. We
296
+ // hydrate session state from the response headers so subsequent
297
+ // turns bypass the handler and use direct `session.in` writes.
298
+ if (this.headStart && !this.sessions.has(chatId)) {
299
+ return this.sendMessagesViaHandover({
300
+ trigger,
301
+ chatId,
302
+ messageId,
303
+ messages,
304
+ abortSignal,
305
+ body,
306
+ metadata: mergedMetadata,
307
+ });
308
+ }
309
+ // Slim wire — at most ONE message per record. The agent rebuilds prior
310
+ // history from its durable S3 snapshot + session.out replay at run boot
311
+ // (or `hydrateMessages`, if registered).
312
+ //
313
+ // - "submit-message": ship the latest message (new user message OR a
314
+ // tool-approval-responded assistant message). Throw if absent.
315
+ // Assistant messages with already-resolved tool parts are slimmed
316
+ // to just their resolution payload — reasoning blobs, prior text,
317
+ // and tool `input` stay on the agent side (rebuilt from snapshot
318
+ // or `hydrateMessages`). Keeps continuation payloads under the
319
+ // `.in/append` cap on reasoning-heavy turns.
320
+ // - "regenerate-message": omit `message`; the agent slices its own
321
+ // history (drops the trailing assistant) and re-runs.
322
+ if (trigger === "submit-message" && messages.length === 0) {
323
+ throw new Error("TriggerChatTransport.sendMessages: 'submit-message' trigger requires at least one message");
324
+ }
325
+ const wirePayload = {
326
+ ...(body ?? {}),
327
+ ...(trigger === "submit-message"
328
+ ? { message: (0, ai_shared_js_1.slimSubmitMessageForWire)(messages.at(-1)) }
329
+ : {}),
330
+ chatId,
331
+ trigger,
332
+ messageId,
333
+ metadata: mergedMetadata,
334
+ };
335
+ const state = await this.ensureSessionState(chatId);
336
+ // Generated outside the closure so auth-retries reuse the same part id
337
+ // and the server-side dedupe sees one logical append.
338
+ const partId = crypto.randomUUID();
339
+ const serializedBody = this.serializeInputChunk({ kind: "message", payload: wirePayload });
340
+ const sendChatMessage = (token) => this.appendInputChunk(chatId, token, serializedBody, partId);
341
+ const inSeq = await this.sendWithEvents(chatId, trigger, {
342
+ messageId: messageId ?? messages.at(-1)?.id,
343
+ partId,
344
+ bodyBytes: byteLength(serializedBody),
345
+ }, () => this.callWithAuthRetry(chatId, state, sendChatMessage));
346
+ // Cancel any in-flight stream for this chat — the new turn supersedes it.
347
+ const activeStream = this.activeStreams.get(chatId);
348
+ if (activeStream) {
349
+ activeStream.abort();
350
+ this.activeStreams.delete(chatId);
351
+ }
352
+ state.activeInputSeq = inSeq;
353
+ state.isStreaming = true;
354
+ state.outstandingTurnAbandoned = false;
355
+ this.notifySessionChange(chatId, state);
356
+ // Owning turn: aborting this live send stops the turn the user drives.
357
+ return this.subscribeToSessionStream(state, abortSignal, chatId, {
358
+ sinceInSeq: inSeq,
359
+ sendStopOnAbort: true,
360
+ });
361
+ };
362
+ /**
363
+ * First-turn-only path used when `headStart` is configured. POSTs the
364
+ * wire payload to the customer's `chat.handover` route handler and
365
+ * pipes its SSE response back as a UIMessageChunk stream. Hydrates
366
+ * session state from response headers so subsequent turns bypass
367
+ * the endpoint and use the direct `session.in` path.
368
+ */
369
+ async sendMessagesViaHandover(args) {
370
+ if (!this.headStart) {
371
+ throw new Error("sendMessagesViaHandover called without headStart configured");
372
+ }
373
+ // Head-start ships full UIMessage history via `headStartMessages`. The
374
+ // route handler runs on the customer's own HTTP endpoint (NOT
375
+ // `/realtime/v1/sessions/{id}/in/append`), so the 512 KiB body cap
376
+ // doesn't apply. The agent's run boot consumes `headStartMessages` ONLY
377
+ // when no snapshot exists yet (very first turn) — see plan section B.3.
378
+ const wirePayload = {
379
+ ...(args.body ?? {}),
380
+ headStartMessages: args.messages,
381
+ chatId: args.chatId,
382
+ trigger: args.trigger,
383
+ messageId: args.messageId,
384
+ metadata: args.metadata,
385
+ };
386
+ let response;
387
+ const serializedBody = JSON.stringify(wirePayload);
388
+ await this.sendWithEvents(args.chatId, "head-start", {
389
+ messageId: args.messageId ?? args.messages.at(-1)?.id,
390
+ bodyBytes: byteLength(serializedBody),
391
+ }, async () => {
392
+ response = await fetch(this.headStart, {
393
+ method: "POST",
394
+ headers: {
395
+ "Content-Type": "application/json",
396
+ ...this.extraHeaders,
397
+ },
398
+ body: serializedBody,
399
+ signal: args.abortSignal,
400
+ });
401
+ if (!response.ok) {
402
+ const err = new Error(`chat.handover endpoint returned ${response.status} ${response.statusText}`);
403
+ err.status = response.status;
404
+ throw err;
405
+ }
406
+ });
407
+ if (!response.body) {
408
+ throw new Error("chat.handover endpoint returned no response body");
409
+ }
410
+ // Hydrate session state from response headers so subsequent turns
411
+ // skip the endpoint and write directly to session.in. Failing fast
412
+ // when the header is missing avoids a quiet degraded state where
413
+ // every later turn re-runs the handover route instead of taking
414
+ // the slim-wire path.
415
+ const accessToken = response.headers.get("X-Trigger-Chat-Access-Token");
416
+ const chatId = args.chatId;
417
+ if (!accessToken) {
418
+ throw new Error("chat.handover response is missing the X-Trigger-Chat-Access-Token header. chat.agent's handover endpoint must echo the session PAT so the transport can hydrate.");
419
+ }
420
+ const state = {
421
+ publicAccessToken: accessToken,
422
+ isStreaming: true,
423
+ };
424
+ this.sessions.set(chatId, state);
425
+ this.notifySessionChange(chatId, state);
426
+ // Step 1 streams from the warm server either way; this says the agent run that owes step 2
427
+ // is parked on an undeployed external deployment id.
428
+ if (response.headers.get("X-Trigger-Chat-Pending-Version") === "1") {
429
+ this.emitEvent({
430
+ type: "run-pending-version",
431
+ chatId,
432
+ timestamp: Date.now(),
433
+ source: "head-start",
434
+ });
435
+ }
436
+ // Filter the parsed UIMessage stream:
437
+ // - Drop control chunks (`trigger:turn-complete`,
438
+ // `trigger:session-state`) before they reach AI SDK — they
439
+ // aren't valid UIMessageChunks and the AI SDK chunk parser
440
+ // would reject them.
441
+ // - On `trigger:turn-complete`, clear `isStreaming` so the
442
+ // useChat resume / reconnectToStream path doesn't open a
443
+ // second `session.out` subscription on top of our stitched
444
+ // response.
445
+ // - On `trigger:session-state`, hydrate `state.lastEventId`
446
+ // with the agent's final S2 event id. Without this, turn 2's
447
+ // `session.out` subscribe reads from the start and replays
448
+ // turn 1's chunks back into the UI.
449
+ // - On stream end (handover-skip case — no
450
+ // `trigger:turn-complete` arrives, customer's stream just
451
+ // ends), also clear `isStreaming` for the same reason.
452
+ const sessions = this.sessions;
453
+ const notifyChange = (id, state) => this.notifySessionChange(id, state);
454
+ const TRIGGER_TURN_COMPLETE = "trigger:turn-complete";
455
+ const TRIGGER_SESSION_STATE = "trigger:session-state";
456
+ const clearStreaming = () => {
457
+ const state = sessions.get(chatId);
458
+ if (state && state.isStreaming) {
459
+ state.isStreaming = false;
460
+ notifyChange(chatId, state);
461
+ }
462
+ };
463
+ const setLastEventId = (lastEventId) => {
464
+ const state = sessions.get(chatId);
465
+ if (state) {
466
+ state.lastEventId = lastEventId;
467
+ notifyChange(chatId, state);
468
+ }
469
+ };
470
+ const emit = (event) => this.emitEvent(event);
471
+ const attribution = () => this.turnAttribution(chatId);
472
+ let sawFirstChunk = false;
473
+ emit({
474
+ type: "stream-connected",
475
+ chatId,
476
+ timestamp: Date.now(),
477
+ resumed: false,
478
+ messageId: this.lastTurnSends.get(chatId)?.messageId,
479
+ });
480
+ const piped = response.body
481
+ .pipeThrough(new TextDecoderStream())
482
+ .pipeThrough(parseUIMessageSseTransform())
483
+ .pipeThrough(new TransformStream({
484
+ transform(chunk, controller) {
485
+ if (chunk && typeof chunk === "object") {
486
+ const type = chunk.type;
487
+ if (type === TRIGGER_TURN_COMPLETE) {
488
+ clearStreaming();
489
+ emit({
490
+ type: "turn-completed",
491
+ chatId,
492
+ timestamp: Date.now(),
493
+ lastEventId: sessions.get(chatId)?.lastEventId,
494
+ ...attribution(),
495
+ });
496
+ return; // drop — not a real UIMessageChunk
497
+ }
498
+ if (type === TRIGGER_SESSION_STATE) {
499
+ const lastEventId = chunk.lastEventId;
500
+ if (typeof lastEventId === "string") {
501
+ setLastEventId(lastEventId);
502
+ }
503
+ return; // drop
504
+ }
505
+ }
506
+ if (!sawFirstChunk) {
507
+ sawFirstChunk = true;
508
+ emit({
509
+ type: "first-chunk",
510
+ chatId,
511
+ timestamp: Date.now(),
512
+ chunkType: chunk?.type,
513
+ ...attribution(),
514
+ });
515
+ }
516
+ controller.enqueue(chunk);
517
+ },
518
+ flush() {
519
+ clearStreaming();
520
+ },
521
+ }));
522
+ // Pump wrapper: a TransformStream can't observe upstream errors, so
523
+ // read here to emit stream-error (aborts close cleanly, matching the
524
+ // session subscribe path).
525
+ const pipedReader = piped.getReader();
526
+ return new ReadableStream({
527
+ async pull(controller) {
528
+ try {
529
+ const next = await pipedReader.read();
530
+ if (next.done) {
531
+ controller.close();
532
+ return;
533
+ }
534
+ controller.enqueue(next.value);
535
+ }
536
+ catch (error) {
537
+ if (error instanceof Error && error.name === "AbortError") {
538
+ try {
539
+ controller.close();
540
+ }
541
+ catch {
542
+ /* already closed */
543
+ }
544
+ return;
545
+ }
546
+ const errorStatus = error.status;
547
+ emit({
548
+ type: "stream-error",
549
+ chatId,
550
+ timestamp: Date.now(),
551
+ error: error instanceof Error ? error : new Error(String(error)),
552
+ status: typeof errorStatus === "number" ? errorStatus : undefined,
553
+ });
554
+ controller.error(error);
555
+ }
556
+ },
557
+ cancel(reason) {
558
+ return pipedReader.cancel(reason);
559
+ },
560
+ });
561
+ }
562
+ /**
563
+ * Send a steering message during an active stream without disrupting
564
+ * it. The agent's `pendingMessages` config decides whether to inject
565
+ * between tool-call steps or buffer for the next turn.
566
+ */
567
+ sendPendingMessage = async (chatId, message, metadata) => {
568
+ const state = this.sessions.get(chatId);
569
+ if (!state)
570
+ return false;
571
+ const mergedMetadata = this.defaultMetadata || metadata
572
+ ? { ...(this.defaultMetadata ?? {}), ...(metadata ?? {}) }
573
+ : undefined;
574
+ const wirePayload = {
575
+ message,
576
+ chatId,
577
+ trigger: "submit-message",
578
+ metadata: mergedMetadata,
579
+ };
580
+ const partId = crypto.randomUUID();
581
+ const serializedBody = this.serializeInputChunk({ kind: "message", payload: wirePayload });
582
+ const send = async (token) => {
583
+ await this.appendInputChunk(chatId, token, serializedBody, partId);
584
+ };
585
+ try {
586
+ await this.sendWithEvents(chatId, "steer", { messageId: message.id, partId, bodyBytes: byteLength(serializedBody) }, () => this.callWithAuthRetry(chatId, state, send));
587
+ return true;
588
+ }
589
+ catch {
590
+ return false;
591
+ }
592
+ };
593
+ /**
594
+ * Re-establish an SSE subscription to a known session. Used after a
595
+ * page refresh: the customer hydrates `sessions` in the constructor,
596
+ * the AI SDK calls `reconnectToStream` to resume the stream.
597
+ */
598
+ reconnectToStream = async (options) => {
599
+ const state = this.sessions.get(options.chatId);
600
+ if (!state)
601
+ return null;
602
+ // A closed session has no further turns to resume.
603
+ if (state.closed)
604
+ return null;
605
+ // Watch is a standing subscription: a settled session is exactly the
606
+ // state it waits in, so a completed last turn must not block the resume.
607
+ if (state.isStreaming === false && !this.watchMode)
608
+ return null;
609
+ if (this.activeStreams.has(options.chatId))
610
+ return null;
611
+ const abortController = new AbortController();
612
+ this.activeStreams.set(options.chatId, abortController);
613
+ const abortSignal = options.abortSignal
614
+ ? AbortSignal.any([options.abortSignal, abortController.signal])
615
+ : abortController.signal;
616
+ return this.subscribeToSessionStream(state, abortSignal, options.chatId, {
617
+ resumed: true,
618
+ sendStopOnAbort: options.stopOnAbort ?? false,
619
+ sinceInSeq: state.activeInputSeq,
620
+ // Reconnect-on-reload opts into the server's settled-peek shortcut
621
+ // so the SSE doesn't hang for 60s when no turn is in flight. A known
622
+ // active input must not peek because the previous turn's completion
623
+ // can remain at the tail until the current turn writes its first chunk.
624
+ // Watch mode must NOT peek: a settled peek between turns closes the
625
+ // standing subscription, so the viewer never sees the next turn.
626
+ peekSettled: !this.watchMode && state.activeInputSeq === undefined,
627
+ });
628
+ };
629
+ /**
630
+ * Stop the current generation. Sends `{kind:"stop"}` on `.in`; the
631
+ * agent aborts its `streamText` call but stays alive for the next
632
+ * message.
633
+ */
634
+ stopGeneration = async (chatId) => {
635
+ const state = this.sessions.get(chatId);
636
+ if (!state)
637
+ return false;
638
+ const partId = crypto.randomUUID();
639
+ const serializedBody = this.serializeInputChunk({ kind: "stop" });
640
+ const send = async (token) => {
641
+ await this.appendInputChunk(chatId, token, serializedBody, partId);
642
+ };
643
+ try {
644
+ await this.sendWithEvents(chatId, "stop", { partId, bodyBytes: byteLength(serializedBody) }, () => this.callWithAuthRetry(chatId, state, send));
645
+ }
646
+ catch {
647
+ return false;
648
+ }
649
+ // Only gate when a sent turn is still outstanding. A stop at a boundary has
650
+ // nothing to supersede, and gating it would swallow the next turn.
651
+ if (!state.outstandingTurnAbandoned &&
652
+ (state.isStreaming || state.activeInputSeq !== undefined)) {
653
+ state.skipToTurnComplete = true;
654
+ state.supersededInputSeq = state.activeInputSeq;
655
+ }
656
+ const activeStream = this.activeStreams.get(chatId);
657
+ if (activeStream) {
658
+ activeStream.abort();
659
+ this.activeStreams.delete(chatId);
660
+ }
661
+ // Release here, not in the stream teardown: that only releases while it
662
+ // still owns the map entry, and we just deleted it. Unlike a supersede,
663
+ // no successor stream follows a stop, so the claim would never be freed
664
+ // and other tabs would stay read-only until this one closes.
665
+ this.coordinator?.release(chatId);
666
+ // The turn won't reach its turn-complete on this client (we just
667
+ // aborted the reader), so clear the streaming flag here and persist —
668
+ // otherwise a reload resumes mid-turn and replays the chunks the user
669
+ // explicitly stopped.
670
+ state.isStreaming = false;
671
+ this.notifySessionChange(chatId, state);
672
+ return true;
673
+ };
674
+ /**
675
+ * Clear the supersede gate armed by a stop. Call this when the stopped
676
+ * turn died without ever writing its `trigger:turn-complete` boundary,
677
+ * otherwise the next turn stays gated forever.
678
+ */
679
+ clearSupersedeGate = (chatId) => {
680
+ const state = this.sessions.get(chatId);
681
+ if (!state)
682
+ return;
683
+ state.skipToTurnComplete = false;
684
+ state.supersededInputSeq = undefined;
685
+ state.outstandingTurnAbandoned = true;
686
+ };
687
+ /**
688
+ * Send a custom action chunk (for `chat.agent`'s `actionSchema` /
689
+ * `onAction` hook). An action is an edit: only `hydrateMessages` and
690
+ * `onAction` fire on the agent side, and the returned stream completes
691
+ * with `trigger:turn-complete` once the edit is persisted. When `onAction`
692
+ * returns `chat.turn()` the turn's response follows on the same stream.
693
+ * Per-action `metadata` is merged over the transport's `clientData`.
694
+ */
695
+ sendAction = async (chatId, action, options) => {
696
+ if (this.coordinator) {
697
+ if (this.coordinator.isReadOnly(chatId)) {
698
+ throw new Error("This chat is active in another tab");
699
+ }
700
+ this.coordinator.claim(chatId);
701
+ }
702
+ const state = await this.ensureSessionState(chatId);
703
+ const wirePayload = {
704
+ chatId,
705
+ trigger: "action",
706
+ action,
707
+ metadata: this.defaultMetadata || options?.metadata
708
+ ? { ...(this.defaultMetadata ?? {}), ...(options?.metadata ?? {}) }
709
+ : undefined,
710
+ };
711
+ const body = this.serializeInputChunk({ kind: "message", payload: wirePayload });
712
+ const partId = crypto.randomUUID();
713
+ const send = (token) => this.appendInputChunk(chatId, token, body, partId);
714
+ const inSeq = await this.sendWithEvents(chatId, "action", { partId, bodyBytes: byteLength(body) }, () => this.callWithAuthRetry(chatId, state, send));
715
+ // Supersede any in-flight reader before subscribing — same as
716
+ // `sendMessages`. Two concurrent readers both write `state.lastEventId`
717
+ // and the slower one can regress the cursor, replaying records on the
718
+ // next reconnect.
719
+ const activeStream = this.activeStreams.get(chatId);
720
+ if (activeStream) {
721
+ activeStream.abort();
722
+ this.activeStreams.delete(chatId);
723
+ }
724
+ // Mark streaming + persist so a reload mid-action resumes (reconnectToStream
725
+ // no-ops when the persisted session says isStreaming: false).
726
+ state.activeInputSeq = inSeq;
727
+ state.isStreaming = true;
728
+ state.outstandingTurnAbandoned = false;
729
+ this.notifySessionChange(chatId, state);
730
+ // Owning action: aborting this send stops the turn the user drives.
731
+ return this.subscribeToSessionStream(state, options?.abortSignal, chatId, {
732
+ sinceInSeq: inSeq,
733
+ sendStopOnAbort: true,
734
+ onSettled: options?.onSettled,
735
+ });
736
+ };
737
+ // -------------------------------------------------------------------------
738
+ // External-state surface
739
+ // -------------------------------------------------------------------------
740
+ getSession = (chatId) => {
741
+ const state = this.sessions.get(chatId);
742
+ if (!state)
743
+ return undefined;
744
+ return this.toPersisted(state);
745
+ };
746
+ setSession(chatId, session) {
747
+ this.sessions.set(chatId, this.applyPendingResumeCursor(chatId, {
748
+ publicAccessToken: session.publicAccessToken,
749
+ lastEventId: session.lastEventId,
750
+ activeInputSeq: session.activeInputSeq,
751
+ isStreaming: session.isStreaming,
752
+ }));
753
+ this.notifySessionChange(chatId, this.toPersisted(this.sessions.get(chatId)));
754
+ }
755
+ /**
756
+ * Seed the `.out` resume cursor from a loaded transcript. Applied to the
757
+ * session now if it exists, otherwise held until the session is created so
758
+ * the first live subscription opens past the persisted history instead of
759
+ * replaying it. Never moves an existing cursor backward: the transcript load
760
+ * is async, so a live `.out` record can already have advanced the session
761
+ * past the snapshot, and overwriting it would replay those records.
762
+ */
763
+ seedResumeCursor = (chatId, lastEventId) => {
764
+ const existing = this.sessions.get(chatId);
765
+ if (existing?.publicAccessToken) {
766
+ if (existing.lastEventId === undefined) {
767
+ existing.lastEventId = lastEventId;
768
+ this.notifySessionChange(chatId, this.toPersisted(existing));
769
+ }
770
+ this.pendingResumeCursors.delete(chatId);
771
+ return;
772
+ }
773
+ this.pendingResumeCursors.set(chatId, lastEventId);
774
+ };
775
+ applyPendingResumeCursor(chatId, state) {
776
+ const pending = this.pendingResumeCursors.get(chatId);
777
+ if (pending !== undefined && state.lastEventId === undefined) {
778
+ state.lastEventId = pending;
779
+ }
780
+ this.pendingResumeCursors.delete(chatId);
781
+ return state;
782
+ }
783
+ setOnSessionChange(callback) {
784
+ this._onSessionChange = callback;
785
+ }
786
+ /** Update the `onEvent` callback without recreating the transport. */
787
+ setOnEvent(callback) {
788
+ this._onEvent = callback;
789
+ }
790
+ emitEvent(event) {
791
+ const cb = this._onEvent;
792
+ if (!cb)
793
+ return;
794
+ try {
795
+ cb(event);
796
+ }
797
+ catch {
798
+ // observability must never break the chat
799
+ }
800
+ }
801
+ /** Run a send op, emitting the terminal message-sent / message-send-failed event. */
802
+ async sendWithEvents(chatId, source, extras, op) {
803
+ const startedAt = Date.now();
804
+ try {
805
+ const result = await op();
806
+ const turnProducing = source === "submit-message" || source === "regenerate-message" || source === "head-start";
807
+ if (turnProducing) {
808
+ this.lastTurnSends.set(chatId, { messageId: extras.messageId, at: Date.now() });
809
+ }
810
+ this.emitEvent({
811
+ type: "message-sent",
812
+ chatId,
813
+ timestamp: Date.now(),
814
+ source,
815
+ durationMs: Date.now() - startedAt,
816
+ ...extras,
817
+ });
818
+ return result;
819
+ }
820
+ catch (error) {
821
+ const status = error.status;
822
+ this.emitEvent({
823
+ type: "message-send-failed",
824
+ chatId,
825
+ timestamp: Date.now(),
826
+ source,
827
+ error: error instanceof Error ? error : new Error(String(error)),
828
+ status: typeof status === "number" ? status : undefined,
829
+ durationMs: Date.now() - startedAt,
830
+ ...extras,
831
+ });
832
+ throw error;
833
+ }
834
+ }
835
+ /** Attribution fields for response-side events. */
836
+ turnAttribution(chatId) {
837
+ const lastSend = this.lastTurnSends.get(chatId);
838
+ if (!lastSend)
839
+ return {};
840
+ return { messageId: lastSend.messageId, sinceSendMs: Date.now() - lastSend.at };
841
+ }
842
+ /**
843
+ * Update the transport's `clientData`. Used by `useTriggerChatTransport`
844
+ * to keep the latest value reachable from inside `startSession` and
845
+ * the per-turn `metadata` merge without recreating the transport.
846
+ *
847
+ * Reads always go through the live field — closures around the
848
+ * transport see the latest value the next time they fire.
849
+ */
850
+ setClientData(clientData) {
851
+ this.defaultMetadata = clientData;
852
+ }
853
+ /**
854
+ * Update the request-time callbacks. Same reason as `setClientData`:
855
+ * a host that rebuilds these per render (a dashboard navigating between
856
+ * projects) would otherwise keep hitting the endpoint captured at
857
+ * construction. Every read goes through the live field, so the next
858
+ * request uses the latest callback.
859
+ */
860
+ setAccessToken(accessToken) {
861
+ this.resolveAccessToken = accessToken;
862
+ }
863
+ setStartSession(startSession) {
864
+ this.resolveStartSession = startSession;
865
+ }
866
+ setFetch(fetchOverride) {
867
+ this.fetchOverride = fetchOverride;
868
+ }
869
+ // -------------------------------------------------------------------------
870
+ // Multi-tab coordination passthrough
871
+ // -------------------------------------------------------------------------
872
+ isReadOnly(chatId) {
873
+ return this.coordinator?.isReadOnly(chatId) ?? false;
874
+ }
875
+ hasClaim(chatId) {
876
+ return this.coordinator?.hasClaim(chatId) ?? false;
877
+ }
878
+ addReadOnlyListener(fn) {
879
+ this.coordinator?.addListener(fn);
880
+ }
881
+ removeReadOnlyListener(fn) {
882
+ this.coordinator?.removeListener(fn);
883
+ }
884
+ broadcastMessages(chatId, messages) {
885
+ this.coordinator?.broadcastMessages(chatId, messages);
886
+ }
887
+ addMessagesListener(fn) {
888
+ this.coordinator?.addMessagesListener(fn);
889
+ }
890
+ removeMessagesListener(fn) {
891
+ this.coordinator?.removeMessagesListener(fn);
892
+ }
893
+ dispose() {
894
+ // Tear down any open session.out subscriptions before the coordinator
895
+ // goes away. Otherwise controllers in `activeStreams` keep reading
896
+ // until they time out, leaking network and memory on every
897
+ // unmount/navigation.
898
+ for (const controller of this.activeStreams.values()) {
899
+ controller.abort();
900
+ }
901
+ this.activeStreams.clear();
902
+ this.coordinator?.dispose();
903
+ this.coordinator = null;
904
+ }
905
+ // -------------------------------------------------------------------------
906
+ // Internal helpers
907
+ // -------------------------------------------------------------------------
908
+ serializeInputChunk(chunk) {
909
+ return JSON.stringify(chunk);
910
+ }
911
+ toPersisted = (state) => ({
912
+ publicAccessToken: state.publicAccessToken,
913
+ lastEventId: state.lastEventId,
914
+ activeInputSeq: state.activeInputSeq,
915
+ isStreaming: state.isStreaming,
916
+ closed: state.closed,
917
+ closedReason: state.closedReason,
918
+ });
919
+ /**
920
+ * Flip a session to closed and tell listeners once. Terminal: sends and
921
+ * reconnects stop from here on, and there is no reopening.
922
+ */
923
+ markSessionClosed(chatId, state, reason, source) {
924
+ if (state.closed)
925
+ return;
926
+ state.closed = true;
927
+ if (reason)
928
+ state.closedReason = reason;
929
+ state.isStreaming = false;
930
+ state.activeInputSeq = undefined;
931
+ state.skipToTurnComplete = false;
932
+ state.supersededInputSeq = undefined;
933
+ this.emitEvent({
934
+ type: "session-closed",
935
+ chatId,
936
+ timestamp: Date.now(),
937
+ ...(reason ? { reason } : {}),
938
+ source,
939
+ });
940
+ this.notifySessionChange(chatId, state);
941
+ this.coordinator?.release(chatId);
942
+ }
943
+ /**
944
+ * Whether the conversation has been closed — by the agent via
945
+ * `chat.close()`, or from outside via `sessions.close()`. Closed is
946
+ * one-way: the transport refuses further sends and reconnects, and the
947
+ * transcript stays readable.
948
+ */
949
+ sessionStatus = (chatId) => this.sessions.get(chatId)?.closed ? "closed" : "open";
950
+ /** The reason the session was closed, when one was given. */
951
+ sessionClosedReason = (chatId) => this.sessions.get(chatId)?.closedReason;
952
+ notifySessionChange(chatId, session) {
953
+ if (!this._onSessionChange)
954
+ return;
955
+ this._onSessionChange(chatId, session ? this.toPersisted(session) : null);
956
+ }
957
+ /**
958
+ * Resolves the session state for a chatId, starting the session if
959
+ * needed (and `getStartToken` is configured). Customers who provide
960
+ * `accessToken` but no `getStartToken` are expected to have created
961
+ * the session server-side; in that case the first `accessToken` call
962
+ * returns a fresh session PAT.
963
+ */
964
+ async ensureSessionState(chatId) {
965
+ const existing = this.sessions.get(chatId);
966
+ if (existing?.publicAccessToken)
967
+ return existing;
968
+ if (this.resolveStartSession) {
969
+ // Lazily start: customer's server action creates the session and
970
+ // returns a PAT. Idempotent on `(env, externalId)` so concurrent
971
+ // tabs / repeat calls converge to the same session.
972
+ const inflight = this.pendingStarts.get(chatId);
973
+ if (inflight)
974
+ return inflight;
975
+ const promise = this.doStart(chatId).finally(() => {
976
+ this.pendingStarts.delete(chatId);
977
+ });
978
+ this.pendingStarts.set(chatId, promise);
979
+ return promise;
980
+ }
981
+ // No `startSession` configured. Customer fully manages session
982
+ // lifecycle externally — they're expected to have hydrated
983
+ // `sessions: { ... }` already, or the very first `accessToken` call
984
+ // returns a PAT for an out-of-band-created session.
985
+ const token = await this.resolveAccessToken({ chatId });
986
+ const state = this.applyPendingResumeCursor(chatId, { publicAccessToken: token });
987
+ this.sessions.set(chatId, state);
988
+ this.notifySessionChange(chatId, state);
989
+ return state;
990
+ }
991
+ async doStart(chatId) {
992
+ if (!this.resolveStartSession) {
993
+ throw new Error("TriggerChatTransport: `startSession` is required to call `start()` / `preload()`. Either provide it or pre-hydrate the session via `sessions: { ... }`.");
994
+ }
995
+ const { publicAccessToken, pendingVersion } = await this.resolveStartSession({
996
+ taskId: this.taskId,
997
+ chatId,
998
+ clientData: (this.defaultMetadata ?? {}),
999
+ });
1000
+ if (pendingVersion) {
1001
+ this.emitEvent({
1002
+ type: "run-pending-version",
1003
+ chatId,
1004
+ timestamp: Date.now(),
1005
+ source: "start",
1006
+ });
1007
+ }
1008
+ const state = this.applyPendingResumeCursor(chatId, {
1009
+ publicAccessToken,
1010
+ isStreaming: false,
1011
+ });
1012
+ this.sessions.set(chatId, state);
1013
+ this.notifySessionChange(chatId, state);
1014
+ return state;
1015
+ }
1016
+ /**
1017
+ * Run `op` with the session's stored PAT. On 401/403, refresh the PAT
1018
+ * via `accessToken` and retry once. Surfaces non-auth errors as-is.
1019
+ */
1020
+ resolveBaseURL(ctx) {
1021
+ const raw = this.resolveBaseURLFn(ctx);
1022
+ return raw.replace(/\/$/, "");
1023
+ }
1024
+ /**
1025
+ * `fetchClient` for an `out` subscription. Reads `this.fetchOverride` on
1026
+ * every call, not once per subscription: a watch-mode subscription
1027
+ * reconnects for the lifetime of the page, and `setFetch` may have swapped
1028
+ * the override in between.
1029
+ */
1030
+ sseFetchClient(ctx) {
1031
+ return ((input, init) => {
1032
+ const override = this.fetchOverride;
1033
+ if (!override)
1034
+ return fetch(input, init);
1035
+ if (typeof input === "string") {
1036
+ return override(input, init ?? {}, ctx);
1037
+ }
1038
+ if (input instanceof URL) {
1039
+ return override(input.toString(), init ?? {}, ctx);
1040
+ }
1041
+ // Request — preserve its url + intrinsic init, let any provided init
1042
+ // override on top (matches fetch(Request, init) semantics).
1043
+ return override(input.url, {
1044
+ method: input.method,
1045
+ headers: input.headers,
1046
+ signal: input.signal,
1047
+ ...(init ?? {}),
1048
+ }, ctx);
1049
+ });
1050
+ }
1051
+ async doFetch(ctx, url, init) {
1052
+ return this.fetchOverride ? this.fetchOverride(url, init, ctx) : fetch(url, init);
1053
+ }
1054
+ async appendInputChunk(chatId, token, body, partId) {
1055
+ const ctx = { endpoint: "in", chatId };
1056
+ const url = `${this.resolveBaseURL(ctx)}/realtime/v1/sessions/${encodeURIComponent(chatId)}/in/append`;
1057
+ // extraHeaders first so the fixed headers below win — a transport-wide
1058
+ // X-Part-Id must not override the per-append idempotency key.
1059
+ const headers = {
1060
+ ...this.extraHeaders,
1061
+ "Content-Type": "application/json",
1062
+ Authorization: `Bearer ${token}`,
1063
+ "x-trigger-source": "sdk",
1064
+ "X-Part-Id": partId ?? crypto.randomUUID(),
1065
+ };
1066
+ const response = await this.doFetch(ctx, url, { method: "POST", headers, body });
1067
+ if (!response.ok) {
1068
+ const text = await response.text().catch(() => "");
1069
+ const err = new Error(`appendToSessionStream failed: ${response.status} ${text}`);
1070
+ err.name = "TriggerApiError";
1071
+ err.status = response.status;
1072
+ let parsed;
1073
+ try {
1074
+ parsed = JSON.parse(text);
1075
+ }
1076
+ catch {
1077
+ parsed = undefined;
1078
+ }
1079
+ if (typeof parsed?.code === "string")
1080
+ err.code = parsed.code;
1081
+ if (typeof parsed?.closedReason === "string")
1082
+ err.closedReason = parsed.closedReason;
1083
+ throw err;
1084
+ }
1085
+ // The appended record's `.in` seq, for correlating the response stream to
1086
+ // this send. Omitted by older webapps / a lost idempotency claim.
1087
+ const data = (await response.json().catch(() => undefined));
1088
+ if (data?.pendingVersion === true) {
1089
+ this.emitEvent({
1090
+ type: "run-pending-version",
1091
+ chatId,
1092
+ timestamp: Date.now(),
1093
+ source: "send",
1094
+ });
1095
+ }
1096
+ return typeof data?.seq === "number" ? data.seq : undefined;
1097
+ }
1098
+ async callWithAuthRetry(chatId, state, op) {
1099
+ if (state.closed) {
1100
+ throw sessionClosedError(chatId, state.closedReason);
1101
+ }
1102
+ // Every attempt goes through here, so a closed-session refusal is terminal
1103
+ // on whichever one hits it. Reaching a 409 from a later attempt and not
1104
+ // marking it would leave local status open on a conversation the server
1105
+ // has already ended.
1106
+ const attempt = async (token) => {
1107
+ try {
1108
+ return await op(token);
1109
+ }
1110
+ catch (err) {
1111
+ if (isSessionClosedError(err)) {
1112
+ // Terminal. Retrying, refreshing the PAT, or recreating the session
1113
+ // would all be wrong: the conversation is over.
1114
+ this.markSessionClosed(chatId, state, sessionClosedReasonOf(err), "append");
1115
+ }
1116
+ throw err;
1117
+ }
1118
+ };
1119
+ // 1) Try with the current PAT.
1120
+ try {
1121
+ return await attempt(state.publicAccessToken);
1122
+ }
1123
+ catch (err) {
1124
+ if (isSessionClosedError(err))
1125
+ throw err;
1126
+ if (isSessionNotFoundError(err)) {
1127
+ // The cached PAT authenticated but the session doesn't exist here —
1128
+ // recreate it and retry.
1129
+ await this.recreateSession(chatId, state);
1130
+ return await attempt(state.publicAccessToken);
1131
+ }
1132
+ if (!isAuthError(err))
1133
+ throw err;
1134
+ }
1135
+ // 2) Auth error — refresh the PAT and retry. (A cross-environment cached
1136
+ // PAT fails auth here because it was signed by another env's keys.)
1137
+ const fresh = await this.resolveAccessToken({ chatId });
1138
+ state.publicAccessToken = fresh;
1139
+ this.notifySessionChange(chatId, state);
1140
+ try {
1141
+ return await attempt(fresh);
1142
+ }
1143
+ catch (err) {
1144
+ if (!isSessionNotFoundError(err))
1145
+ throw err;
1146
+ }
1147
+ // 3) PAT is now valid but the session still 404s — the hydrated session
1148
+ // state is stale (created in a different environment, or before the
1149
+ // sessions upgrade). Recreate the session and retry once.
1150
+ await this.recreateSession(chatId, state);
1151
+ return await attempt(state.publicAccessToken);
1152
+ }
1153
+ /**
1154
+ * Repair a stale/phantom hydrated session. The cached state pointed at a
1155
+ * session that doesn't exist in the current environment (404) — typically
1156
+ * because it was persisted against a different trigger environment, or
1157
+ * predates the upgrade to the sessions model. Recreate the session via
1158
+ * `startSession` and overwrite the cached state **in place** so callers
1159
+ * holding a reference (e.g. `sendMessages` before it opens the SSE) pick
1160
+ * up the new PAT. The stale `lastEventId` resume cursor is dropped — it
1161
+ * pointed at a different environment's stream.
1162
+ */
1163
+ async recreateSession(chatId, state) {
1164
+ if (!this.resolveStartSession) {
1165
+ throw new Error("TriggerChatTransport: session not found and no `startSession` configured to recreate it. The stored session state for this chat may be stale (e.g. created in a different environment) — provide `startSession` or clear the stored session so a fresh one can be created.");
1166
+ }
1167
+ const { publicAccessToken, pendingVersion } = await this.resolveStartSession({
1168
+ taskId: this.taskId,
1169
+ chatId,
1170
+ clientData: (this.defaultMetadata ?? {}),
1171
+ });
1172
+ if (pendingVersion) {
1173
+ this.emitEvent({
1174
+ type: "run-pending-version",
1175
+ chatId,
1176
+ timestamp: Date.now(),
1177
+ source: "start",
1178
+ });
1179
+ }
1180
+ state.publicAccessToken = publicAccessToken;
1181
+ state.lastEventId = undefined;
1182
+ state.isStreaming = false;
1183
+ this.sessions.set(chatId, state);
1184
+ this.notifySessionChange(chatId, state);
1185
+ }
1186
+ /**
1187
+ * Open an SSE subscription to the session's `.out` stream and pipe
1188
+ * UIMessageChunks through to the AI SDK. Trigger control records
1189
+ * (`turn-complete`, `upgrade-required` — see `trigger-control` header
1190
+ * on `client-protocol.mdx#records-on-session-out`) are routed by
1191
+ * header and never reach the consumer. `upgrade-required` is purely
1192
+ * telemetry now since the server handles the run swap inline (see
1193
+ * `end-and-continue`).
1194
+ */
1195
+ subscribeToSessionStream(state, abortSignal, chatId, options) {
1196
+ const internalAbort = new AbortController();
1197
+ let didSettle = false;
1198
+ this.activeStreams.set(chatId, internalAbort);
1199
+ const combinedSignal = abortSignal
1200
+ ? AbortSignal.any([abortSignal, internalAbort.signal])
1201
+ : internalAbort.signal;
1202
+ if (abortSignal) {
1203
+ abortSignal.addEventListener("abort", () => {
1204
+ // A late abort (unmount, or the consumer dropping a drained stream)
1205
+ // has no turn to stop: don't gate the next one, don't write a stop.
1206
+ const outstanding = !state.outstandingTurnAbandoned &&
1207
+ (state.isStreaming || state.activeInputSeq !== undefined);
1208
+ if (options?.sendStopOnAbort !== false && outstanding && !internalAbort.signal.aborted) {
1209
+ state.skipToTurnComplete = true;
1210
+ state.supersededInputSeq = state.activeInputSeq;
1211
+ this.appendInputChunk(chatId, state.publicAccessToken, this.serializeInputChunk({ kind: "stop" })).catch(() => { });
1212
+ }
1213
+ internalAbort.abort();
1214
+ }, { once: true });
1215
+ }
1216
+ const streamUrl = `${this.resolveBaseURL({ endpoint: "out", chatId })}/realtime/v1/sessions/${encodeURIComponent(chatId)}/out`;
1217
+ return new ReadableStream({
1218
+ start: async (controller) => {
1219
+ // Track the live subscription so browser wake events can act
1220
+ // on it. Three classes of wake:
1221
+ // - `online`: network came back. Existing connection might
1222
+ // be silently dead; force a fresh one.
1223
+ // - `visibilitychange` → visible after long hidden: tab
1224
+ // was backgrounded long enough that the OS likely killed
1225
+ // the TCP socket. Force reconnect.
1226
+ // - `visibilitychange` → visible after short hidden: cheap
1227
+ // wake of any in-flight backoff.
1228
+ // - `pageshow` with `event.persisted`: bfcache restore
1229
+ // (mobile Safari back/forward, app-switcher resume). The
1230
+ // socket is definitely dead. Force reconnect.
1231
+ let currentSubscription = null;
1232
+ let hiddenSince = null;
1233
+ const FORCE_RECONNECT_AFTER_HIDDEN_MS = 30_000;
1234
+ const onVisibilityChange = () => {
1235
+ if (typeof document === "undefined")
1236
+ return;
1237
+ if (document.visibilityState === "hidden") {
1238
+ hiddenSince = Date.now();
1239
+ return;
1240
+ }
1241
+ const wasHiddenForMs = hiddenSince ? Date.now() - hiddenSince : 0;
1242
+ hiddenSince = null;
1243
+ if (wasHiddenForMs >= FORCE_RECONNECT_AFTER_HIDDEN_MS) {
1244
+ currentSubscription?.forceReconnect();
1245
+ }
1246
+ else {
1247
+ currentSubscription?.retryNow();
1248
+ }
1249
+ };
1250
+ const onPageShow = (event) => {
1251
+ // PageTransitionEvent in browsers; type guard via `persisted`.
1252
+ if (event.persisted) {
1253
+ currentSubscription?.forceReconnect();
1254
+ }
1255
+ };
1256
+ const onOnline = () => currentSubscription?.forceReconnect();
1257
+ const teardownWakeListeners = typeof document !== "undefined" && typeof window !== "undefined"
1258
+ ? (() => {
1259
+ document.addEventListener("visibilitychange", onVisibilityChange);
1260
+ window.addEventListener("online", onOnline);
1261
+ window.addEventListener("pageshow", onPageShow);
1262
+ return () => {
1263
+ document.removeEventListener("visibilitychange", onVisibilityChange);
1264
+ window.removeEventListener("online", onOnline);
1265
+ window.removeEventListener("pageshow", onPageShow);
1266
+ };
1267
+ })()
1268
+ : () => { };
1269
+ const sseCtx = { endpoint: "out", chatId };
1270
+ const sseFetchClient = this.sseFetchClient(sseCtx);
1271
+ let sawFirstChunk = false;
1272
+ let sinceInSeq = options?.sinceInSeq;
1273
+ const connectSseOnce = async (token) => {
1274
+ const subscription = new v3_1.SSEStreamSubscription(streamUrl, {
1275
+ headers: {
1276
+ Authorization: `Bearer ${token}`,
1277
+ ...this.extraHeaders,
1278
+ ...(options?.peekSettled ? { "X-Peek-Settled": "1" } : {}),
1279
+ },
1280
+ signal: combinedSignal,
1281
+ timeoutInSeconds: this.streamTimeoutSeconds,
1282
+ lastEventId: state.lastEventId,
1283
+ // Reconnect if no decoded record arrives for 60 seconds.
1284
+ stallTimeoutMs: 60_000,
1285
+ // Bound connected silence while preserving recovery from network failures.
1286
+ ...(!this.watchMode && {
1287
+ maxStallRetries: 5,
1288
+ retryDelayMs: 1_000,
1289
+ maxRetryDelayMs: 5_000,
1290
+ }),
1291
+ fetchClient: sseFetchClient,
1292
+ });
1293
+ currentSubscription = subscription;
1294
+ const sseStream = await subscription.subscribe();
1295
+ const reader = sseStream.getReader();
1296
+ try {
1297
+ const first = await reader.read();
1298
+ if (first.done) {
1299
+ reader.releaseLock();
1300
+ return null;
1301
+ }
1302
+ return { reader, primed: first.value, subscription };
1303
+ }
1304
+ catch (readErr) {
1305
+ reader.releaseLock();
1306
+ throw readErr;
1307
+ }
1308
+ };
1309
+ const openWithAuthRetry = async () => {
1310
+ try {
1311
+ return await connectSseOnce(state.publicAccessToken);
1312
+ }
1313
+ catch (e) {
1314
+ if (!isAuthError(e))
1315
+ throw e;
1316
+ const fresh = await this.resolveAccessToken({ chatId });
1317
+ state.publicAccessToken = fresh;
1318
+ this.notifySessionChange(chatId, state);
1319
+ return await connectSseOnce(fresh);
1320
+ }
1321
+ };
1322
+ let eofResubscribes = 0;
1323
+ const resumeAfterEof = async () => {
1324
+ // Watch mode is a standing subscription: it outlives turn-complete
1325
+ // (which clears `isStreaming`) and idle windows EOF by design, so the
1326
+ // give-up budget doesn't apply. Only abort or a settled session ends it.
1327
+ while ((this.watchMode || (state.isStreaming && eofResubscribes < ai_shared_js_1.MAX_EOF_RESUBSCRIBES)) &&
1328
+ !currentSubscription?.sessionSettled &&
1329
+ !combinedSignal.aborted) {
1330
+ eofResubscribes++;
1331
+ await (0, ai_shared_js_1.waitBeforeEofResubscribe)(eofResubscribes, combinedSignal);
1332
+ if (combinedSignal.aborted)
1333
+ break;
1334
+ const opened = await openWithAuthRetry();
1335
+ if (opened)
1336
+ return opened;
1337
+ }
1338
+ // A settled session or an abort ends the turn cleanly. Exhausting the
1339
+ // resubscribe budget while the turn is still streaming means it was cut
1340
+ // off — surface an error so the UI doesn't read a truncated reply as
1341
+ // complete. The caller's catch emits stream-error and errors the stream.
1342
+ if (state.isStreaming &&
1343
+ !currentSubscription?.sessionSettled &&
1344
+ !combinedSignal.aborted) {
1345
+ throw new Error("Chat stream ended before the turn completed (reconnect budget exhausted).");
1346
+ }
1347
+ // Settled close, or the turn is gone — tell the UI instead of
1348
+ // leaving it spinning on a stream nobody will finish.
1349
+ if (state.isStreaming && this.activeStreams.get(chatId) === internalAbort) {
1350
+ state.isStreaming = false;
1351
+ this.notifySessionChange(chatId, state);
1352
+ }
1353
+ return null;
1354
+ };
1355
+ try {
1356
+ let reader;
1357
+ let primed;
1358
+ const opened = (await openWithAuthRetry()) ?? (await resumeAfterEof());
1359
+ if (opened === null) {
1360
+ try {
1361
+ controller.close();
1362
+ }
1363
+ catch {
1364
+ /* already closed by a consumer cancel */
1365
+ }
1366
+ return;
1367
+ }
1368
+ reader = opened.reader;
1369
+ primed = opened.primed;
1370
+ this.emitEvent({
1371
+ type: "stream-connected",
1372
+ chatId,
1373
+ timestamp: Date.now(),
1374
+ resumed: options?.resumed ?? false,
1375
+ lastEventId: state.lastEventId,
1376
+ messageId: this.lastTurnSends.get(chatId)?.messageId,
1377
+ });
1378
+ while (true) {
1379
+ let value;
1380
+ if (primed !== undefined) {
1381
+ value = primed;
1382
+ primed = undefined;
1383
+ }
1384
+ else {
1385
+ const next = await reader.read();
1386
+ if (next.done) {
1387
+ const resumed = await resumeAfterEof();
1388
+ if (resumed === null) {
1389
+ try {
1390
+ controller.close();
1391
+ }
1392
+ catch {
1393
+ /* already closed by a consumer cancel */
1394
+ }
1395
+ return;
1396
+ }
1397
+ reader = resumed.reader;
1398
+ primed = resumed.primed;
1399
+ continue;
1400
+ }
1401
+ value = next.value;
1402
+ }
1403
+ if (combinedSignal.aborted) {
1404
+ internalAbort.abort();
1405
+ await reader.cancel();
1406
+ try {
1407
+ controller.close();
1408
+ }
1409
+ catch {
1410
+ /* already closed by a consumer cancel */
1411
+ }
1412
+ return;
1413
+ }
1414
+ if (value.id)
1415
+ state.lastEventId = value.id;
1416
+ // Any record — including the first of a resumed connection, which
1417
+ // arrives via `primed` — re-earns the resubscribe budget, so a long
1418
+ // turn spanning many long-poll windows keeps streaming.
1419
+ eofResubscribes = 0;
1420
+ // Trigger control record (turn-complete, upgrade-required) —
1421
+ // routed by header, body is empty. Detect via the
1422
+ // `trigger-control` header on the SSE record. Data records
1423
+ // (UIMessageChunks) fall through to the chunk path below.
1424
+ //
1425
+ // Cross-version bridge: a customer who redeploys their
1426
+ // Next.js app (new browser SDK) before their next
1427
+ // `trigger deploy` (old agent SDK still writing turn-complete
1428
+ // / upgrade-required as `chunk.type` data records) would
1429
+ // otherwise hang. Fall back to the legacy chunk-type form
1430
+ // when no header is present so the deploy-skew window
1431
+ // closes turns correctly.
1432
+ let controlValue = (0, v3_1.controlSubtype)(value.headers);
1433
+ let legacyChunk;
1434
+ if (!controlValue && value.chunk && typeof value.chunk === "object") {
1435
+ const chunk = value.chunk;
1436
+ if (chunk.type === "trigger:turn-complete") {
1437
+ controlValue = v3_1.TRIGGER_CONTROL_SUBTYPE.TURN_COMPLETE;
1438
+ legacyChunk = chunk;
1439
+ }
1440
+ else if (chunk.type === "trigger:upgrade-required") {
1441
+ controlValue = v3_1.TRIGGER_CONTROL_SUBTYPE.UPGRADE_REQUIRED;
1442
+ }
1443
+ else if (typeof chunk.type === "string" && chunk.type.startsWith("trigger:")) {
1444
+ // Future / unknown `trigger:*` legacy control type from
1445
+ // a pre-upgrade agent — drop so it doesn't reach the AI
1446
+ // SDK as an unrecognised UIMessageChunk.
1447
+ continue;
1448
+ }
1449
+ }
1450
+ if (state.skipToTurnComplete &&
1451
+ controlValue !== v3_1.TRIGGER_CONTROL_SUBTYPE.SESSION_CLOSED &&
1452
+ controlValue !== v3_1.TRIGGER_CONTROL_SUBTYPE.PENDING_VERSION) {
1453
+ // Fall through on a boundary so the `sinceInSeq` check and the
1454
+ // turn-completed emit below still run; content records are skipped.
1455
+ // A close is terminal and a pending version is the gated turn's own
1456
+ // handover status, so neither is ever gated away.
1457
+ if (controlValue !== v3_1.TRIGGER_CONTROL_SUBTYPE.TURN_COMPLETE)
1458
+ continue;
1459
+ // A boundary older than the superseded turn is not its boundary —
1460
+ // keep gating. A header-less boundary (legacy wire) still clears.
1461
+ const gateCursorRaw = (0, v3_1.headerValue)(value.headers, v3_1.SESSION_IN_EVENT_ID_HEADER);
1462
+ const gateCursor = gateCursorRaw !== undefined ? Number.parseInt(gateCursorRaw, 10) : NaN;
1463
+ if (state.supersededInputSeq !== undefined &&
1464
+ !Number.isNaN(gateCursor) &&
1465
+ gateCursor < state.supersededInputSeq) {
1466
+ continue;
1467
+ }
1468
+ state.skipToTurnComplete = false;
1469
+ state.supersededInputSeq = undefined;
1470
+ // This boundary is the new turn's own, so the gate swallowed its
1471
+ // output: fail the turn instead of completing an empty answer, and
1472
+ // leave nothing armed for the retry.
1473
+ if (sinceInSeq !== undefined &&
1474
+ !Number.isNaN(gateCursor) &&
1475
+ gateCursor >= sinceInSeq) {
1476
+ // The lost boundary may also carry the session close.
1477
+ if ((0, v3_1.headerValue)(value.headers, v3_1.SESSION_CLOSED_HEADER) === "true") {
1478
+ this.markSessionClosed(chatId, state, (0, v3_1.headerValue)(value.headers, v3_1.SESSION_CLOSED_REASON_HEADER), "stream");
1479
+ }
1480
+ state.activeInputSeq = undefined;
1481
+ state.isStreaming = false;
1482
+ this.notifySessionChange(chatId, state);
1483
+ throw new Error("The previous turn's output was lost. Try again.");
1484
+ }
1485
+ }
1486
+ if (controlValue === v3_1.TRIGGER_CONTROL_SUBTYPE.UPGRADE_REQUIRED) {
1487
+ // Server has already triggered the new run via
1488
+ // `end-and-continue`; the next chunks on this same `.out`
1489
+ // stream come from v2. Filter the marker for cleanliness
1490
+ // and keep reading.
1491
+ continue;
1492
+ }
1493
+ if (controlValue === v3_1.TRIGGER_CONTROL_SUBTYPE.SESSION_CLOSED) {
1494
+ this.markSessionClosed(chatId, state, (0, v3_1.headerValue)(value.headers, v3_1.SESSION_CLOSED_REASON_HEADER), "stream");
1495
+ internalAbort.abort();
1496
+ try {
1497
+ controller.close();
1498
+ }
1499
+ catch {
1500
+ /* already closed */
1501
+ }
1502
+ return;
1503
+ }
1504
+ if (controlValue === v3_1.TRIGGER_CONTROL_SUBTYPE.PENDING_VERSION) {
1505
+ this.emitEvent({
1506
+ type: "run-pending-version",
1507
+ chatId,
1508
+ timestamp: Date.now(),
1509
+ source: "upgrade",
1510
+ });
1511
+ continue;
1512
+ }
1513
+ if (controlValue === v3_1.TRIGGER_CONTROL_SUBTYPE.TURN_COMPLETE) {
1514
+ const sessionInEventId = (0, v3_1.headerValue)(value.headers, v3_1.SESSION_IN_EVENT_ID_HEADER);
1515
+ const lastEventId = value.id || undefined;
1516
+ // Skip a turn-complete from an earlier turn (committed `.in` cursor
1517
+ // below this send's seq), e.g. an undo action that raced this send.
1518
+ if (sinceInSeq !== undefined) {
1519
+ const cursorRaw = (0, v3_1.headerValue)(value.headers, v3_1.SESSION_IN_EVENT_ID_HEADER);
1520
+ const cursor = cursorRaw !== undefined ? Number.parseInt(cursorRaw, 10) : NaN;
1521
+ if (!Number.isNaN(cursor) && cursor < sinceInSeq) {
1522
+ continue;
1523
+ }
1524
+ }
1525
+ // A close decided during this turn rides out on turn-complete —
1526
+ // the last record a reader sees before it ends the stream.
1527
+ if ((0, v3_1.headerValue)(value.headers, v3_1.SESSION_CLOSED_HEADER) === "true") {
1528
+ this.markSessionClosed(chatId, state, (0, v3_1.headerValue)(value.headers, v3_1.SESSION_CLOSED_REASON_HEADER), "stream");
1529
+ }
1530
+ const refreshedToken = (0, v3_1.headerValue)(value.headers, v3_1.PUBLIC_ACCESS_TOKEN_HEADER) ??
1531
+ legacyChunk?.publicAccessToken;
1532
+ if (refreshedToken) {
1533
+ state.publicAccessToken = refreshedToken;
1534
+ }
1535
+ this.emitEvent({
1536
+ type: "turn-completed",
1537
+ chatId,
1538
+ timestamp: Date.now(),
1539
+ lastEventId: state.lastEventId,
1540
+ sessionInEventId: (0, v3_1.headerValue)(value.headers, v3_1.SESSION_IN_EVENT_ID_HEADER),
1541
+ ...this.turnAttribution(chatId),
1542
+ });
1543
+ state.activeInputSeq = undefined;
1544
+ sinceInSeq = undefined;
1545
+ state.isStreaming = false;
1546
+ this.notifySessionChange(chatId, state);
1547
+ this.coordinator?.release(chatId);
1548
+ this.coordinator?.broadcastSession(chatId, {
1549
+ lastEventId: state.lastEventId,
1550
+ });
1551
+ // Use this subscription's original append, never mutable session state.
1552
+ const inputSeq = options?.sinceInSeq;
1553
+ const settledSeq = sessionInEventId !== undefined &&
1554
+ sessionInEventId.length > 0 &&
1555
+ !/\D/.test(sessionInEventId)
1556
+ ? Number(sessionInEventId)
1557
+ : NaN;
1558
+ if (!didSettle &&
1559
+ !combinedSignal.aborted &&
1560
+ this.activeStreams.get(chatId) === internalAbort &&
1561
+ inputSeq !== undefined &&
1562
+ Number.isSafeInteger(inputSeq) &&
1563
+ inputSeq >= 0 &&
1564
+ sessionInEventId !== undefined &&
1565
+ Number.isSafeInteger(settledSeq) &&
1566
+ settledSeq >= inputSeq) {
1567
+ didSettle = true;
1568
+ try {
1569
+ options?.onSettled?.({ inputSeq, sessionInEventId, lastEventId });
1570
+ }
1571
+ catch {
1572
+ // An observer must not turn a completed action into a stream error.
1573
+ }
1574
+ }
1575
+ // Re-arm per-turn events for watch mode's next turn.
1576
+ sawFirstChunk = false;
1577
+ if (this.watchMode)
1578
+ continue;
1579
+ internalAbort.abort();
1580
+ try {
1581
+ controller.close();
1582
+ }
1583
+ catch {
1584
+ /* already closed */
1585
+ }
1586
+ return;
1587
+ }
1588
+ // Data record — `value.chunk` is the parsed UIMessageChunk
1589
+ // unwrapped from the S2 record envelope (the parser does the
1590
+ // JSON unwrap). Drop empty/malformed payloads defensively.
1591
+ if (value.chunk == null)
1592
+ continue;
1593
+ if (!sawFirstChunk) {
1594
+ sawFirstChunk = true;
1595
+ this.emitEvent({
1596
+ type: "first-chunk",
1597
+ chatId,
1598
+ timestamp: Date.now(),
1599
+ chunkType: value.chunk.type,
1600
+ lastEventId: value.id || undefined,
1601
+ ...this.turnAttribution(chatId),
1602
+ });
1603
+ }
1604
+ controller.enqueue(value.chunk);
1605
+ }
1606
+ }
1607
+ catch (error) {
1608
+ if (error instanceof Error && error.name === "AbortError") {
1609
+ try {
1610
+ controller.close();
1611
+ }
1612
+ catch {
1613
+ /* already closed */
1614
+ }
1615
+ return;
1616
+ }
1617
+ const errorStatus = error.status;
1618
+ // A superseded stream cannot settle the replacement stream.
1619
+ if (this.activeStreams.get(chatId) === internalAbort) {
1620
+ state.isStreaming = false;
1621
+ this.notifySessionChange(chatId, state);
1622
+ }
1623
+ this.emitEvent({
1624
+ type: "stream-error",
1625
+ chatId,
1626
+ timestamp: Date.now(),
1627
+ error: error instanceof Error ? error : new Error(String(error)),
1628
+ status: typeof errorStatus === "number" ? errorStatus : undefined,
1629
+ });
1630
+ controller.error(error);
1631
+ }
1632
+ finally {
1633
+ teardownWakeListeners();
1634
+ // Only clear the entry (and drop the tab claim) if it is still
1635
+ // ours — a superseding send registers its controller before this
1636
+ // teardown runs, and owns the claim from then on.
1637
+ if (this.activeStreams.get(chatId) === internalAbort) {
1638
+ this.activeStreams.delete(chatId);
1639
+ this.coordinator?.release(chatId);
1640
+ }
1641
+ }
1642
+ },
1643
+ // A consumer that stops reading without aborting (drops the reader)
1644
+ // would otherwise leave the resubscribe loop running forever.
1645
+ cancel() {
1646
+ internalAbort.abort();
1647
+ },
1648
+ });
1649
+ }
1650
+ }
1651
+ exports.TriggerChatTransport = TriggerChatTransport;
1652
+ /**
1653
+ * Convenience constructor matching {@link TriggerChatTransport}.
1654
+ */
1655
+ function createChatTransport(options) {
1656
+ return new TriggerChatTransport(options);
1657
+ }
1658
+ // Server-side agent chat re-exports.
1659
+ var chat_client_js_1 = require("./chat-client.js");
1660
+ Object.defineProperty(exports, "AgentChat", { enumerable: true, get: function () { return chat_client_js_1.AgentChat; } });
1661
+ Object.defineProperty(exports, "ChatStream", { enumerable: true, get: function () { return chat_client_js_1.ChatStream; } });
1662
+ //# sourceMappingURL=chat.js.map