@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,4225 @@
1
+ import { type AnyTask, type Task, type ApiClientConfiguration, type inferSchemaIn, type inferSchemaOut, type MachinePresetName, type RealtimeDefinedInputStream, type RealtimeDefinedStream, type TaskIdentifier, type TaskOptions, type TaskRunContext, type TaskSchema, type TaskWithSchema, type AnySessionChannel, type SessionChannelName, type AnyChatEvent, type ChatEventActions, type ValidatedWebhookKey, type ValidateWebhookFilter, type NarrowWebhookEvent, type AnyWebhookEndpoint, type InferWebhookEndpointEvent } from "@trigger.dev/core/v3";
2
+ import type { streamText as aiStreamTextSignature, FinishReason, LanguageModelUsage, ModelMessage, SystemModelMessage, ProviderMetadata, Tool, ToolSet, UIMessage, UIMessageChunk, UIMessageStreamOptions } from "ai";
3
+ import { chatEvent } from "./webhooks.js";
4
+ import { type TranscriptLoadResult, type TranscriptChannelBinding, type TranscriptStorage } from "./transcriptStorage.js";
5
+ import { type ChatInputChunk, type ChatTaskWirePayload, type InferChatClientData, type InferChatUIMessage, type InferChatUIMessageFromTools, PENDING_MESSAGE_INJECTED_TYPE, upsertIncomingMessage } from "./ai-shared.js";
6
+ import { locals } from "./locals.js";
7
+ import type { ResolvedPrompt } from "./prompt.js";
8
+ import type { ResolvedSkill } from "./skill.js";
9
+ type ToolCallOptions = {
10
+ toolCallId: string;
11
+ messages?: ModelMessage[];
12
+ abortSignal?: AbortSignal;
13
+ experimental_context?: unknown;
14
+ context?: unknown;
15
+ };
16
+ import { type ChatVersionSkewPolicy } from "./chatVersionSkew.js";
17
+ import { type SessionChannelHandleFor, type SessionTriggerConfigInput } from "./sessions.js";
18
+ /** Re-export for typing `ctx` in `chat.agent` hooks without importing `@trigger.dev/core`. */
19
+ export type { TaskRunContext } from "@trigger.dev/core/v3";
20
+ export type ToolCallExecutionOptions = {
21
+ toolCallId: string;
22
+ experimental_context?: unknown;
23
+ /** v7 name for the user context (`experimental_context` on v6). */
24
+ context?: unknown;
25
+ /** Chat context — only present when the tool runs inside a chat.agent turn. */
26
+ chatId?: string;
27
+ turn?: number;
28
+ continuation?: boolean;
29
+ clientData?: unknown;
30
+ };
31
+ /** Chat context stored in locals during each chat.agent turn for auto-detection. */
32
+ type ChatTurnContext<TClientData = unknown> = {
33
+ chatId: string;
34
+ turn: number;
35
+ continuation: boolean;
36
+ clientData?: TClientData;
37
+ recordUserMessage?: boolean;
38
+ };
39
+ export { __readChatSnapshotProductionPathForTests, __setReadChatSnapshotImplForTests, __setWriteChatSnapshotImplForTests, __writeChatSnapshotProductionPathForTests, } from "./chatSnapshotIo.js";
40
+ export { defaultStorage, memoryTranscriptStorage, reduceTranscriptChanges, snapshotTranscriptStorage, type LoadContextEvent, type MemoryTranscriptStorage, type TranscriptChange, type TranscriptChangeReason, type TranscriptChangeset, type TranscriptCursors, type TranscriptLoadOptions, type TranscriptLoadResult, type TranscriptScope, type TranscriptState, type TranscriptStorage, type TranscriptStorageContext, } from "./transcriptStorage.js";
41
+ type ReplaySessionOutTailImpl = <TUIMessage extends UIMessage>(sessionId: string, options?: {
42
+ lastEventId?: string;
43
+ }) => Promise<ReplaySessionOutTailResult<TUIMessage>>;
44
+ export declare function __setReplaySessionOutTailImplForTests(impl: ReplaySessionOutTailImpl | undefined): void;
45
+ export declare function __setReplaySessionInTailImplForTests(impl: ReplaySessionInTailImpl | undefined): void;
46
+ type ToolResultContent = Array<{
47
+ type: "text";
48
+ text: string;
49
+ } | {
50
+ type: "image";
51
+ data: string;
52
+ mimeType?: string;
53
+ }>;
54
+ export type ToolOptions<TResult> = {
55
+ experimental_toToolResultContent?: (result: TResult) => ToolResultContent;
56
+ };
57
+ /** Satisfies AI SDK `ToolSet` index signature alongside concrete `Tool` input/output types. */
58
+ type ToolSetCompatible<T extends Tool<any, any>> = T & NonNullable<ToolSet[string]>;
59
+ /**
60
+ * Returns an `execute` function for the AI SDK `tool()` helper (or any compatible tool definition).
61
+ * Preferred API for task-backed tools: the same Trigger wiring as the deprecated `ai.tool()`
62
+ * (`triggerAndSubscribe`, tool-call metadata, chat context, `chat.local` serialization) without
63
+ * building the tool object. You supply `description`, `inputSchema`, and any AI-SDK-only options
64
+ * (e.g. `experimental_toToolResultContent`) on `tool()` yourself.
65
+ *
66
+ * @example
67
+ * ```ts
68
+ * import { tool } from "ai";
69
+ * import { z } from "zod";
70
+ * import { ai } from "@trigger.dev/sdk/ai";
71
+ * import { myTask } from "./trigger/myTask";
72
+ *
73
+ * export const myTool = tool({
74
+ * description: myTask.description ?? "",
75
+ * inputSchema: z.object({ id: z.string() }),
76
+ * execute: ai.toolExecute(myTask),
77
+ * });
78
+ * ```
79
+ */
80
+ declare function toolExecute<TIdentifier extends string, TInput = void, TOutput = unknown>(task: Task<TIdentifier, TInput, TOutput>): (input: TInput, toolOpts: ToolCallOptions) => Promise<TOutput>;
81
+ declare function toolExecute<TIdentifier extends string, TTaskSchema extends TaskSchema | undefined = undefined, TOutput = unknown>(task: TaskWithSchema<TIdentifier, TTaskSchema, TOutput>): (input: inferSchemaIn<TTaskSchema>, toolOpts: ToolCallOptions) => Promise<TOutput>;
82
+ /**
83
+ * @deprecated Use `tool()` from the `ai` package with `execute: ai.toolExecute(task)` instead.
84
+ * This helper may be removed in a future major release.
85
+ */
86
+ declare function toolFromTask<TIdentifier extends string, TInput = void, TOutput = unknown>(task: Task<TIdentifier, TInput, TOutput>, options?: ToolOptions<TOutput>): ToolSetCompatible<Tool<TInput, TOutput>>;
87
+ /** @deprecated Use `tool()` from `ai` with `execute: ai.toolExecute(task)`. */
88
+ declare function toolFromTask<TIdentifier extends string, TTaskSchema extends TaskSchema | undefined = undefined, TOutput = unknown>(task: TaskWithSchema<TIdentifier, TTaskSchema, TOutput>, options?: ToolOptions<TOutput>): ToolSetCompatible<Tool<inferSchemaIn<TTaskSchema>, TOutput>>;
89
+ declare function getToolOptionsFromMetadata(): ToolCallExecutionOptions | undefined;
90
+ /**
91
+ * Get the current tool call ID from inside a subtask invoked via `ai.toolExecute()` (or legacy `ai.tool()`).
92
+ * Returns `undefined` if not running as a tool subtask.
93
+ */
94
+ declare function getToolCallId(): string | undefined;
95
+ /**
96
+ * Get the chat context from inside a subtask invoked via `ai.toolExecute()` (or legacy `ai.tool()`) within a `chat.agent`.
97
+ * Pass `typeof yourChatTask` as the type parameter to get typed `clientData`.
98
+ * Returns `undefined` if the parent is not a chat task.
99
+ *
100
+ * @example
101
+ * ```ts
102
+ * const ctx = ai.chatContext<typeof myChat>();
103
+ * // ctx?.clientData is typed based on myChat's clientDataSchema
104
+ * ```
105
+ */
106
+ declare function getToolChatContext<TChatTask extends AnyTask = AnyTask>(): ChatTurnContext<InferChatClientData<TChatTask>> | undefined;
107
+ /**
108
+ * Get the chat context from inside a subtask, throwing if not in a chat context.
109
+ * Pass `typeof yourChatTask` as the type parameter to get typed `clientData`.
110
+ *
111
+ * @example
112
+ * ```ts
113
+ * const ctx = ai.chatContextOrThrow<typeof myChat>();
114
+ * // ctx.chatId, ctx.clientData are guaranteed non-null
115
+ * ```
116
+ */
117
+ declare function getToolChatContextOrThrow<TChatTask extends AnyTask = AnyTask>(): ChatTurnContext<InferChatClientData<TChatTask>>;
118
+ export declare const ai: {
119
+ /**
120
+ * @deprecated Use `tool()` from the `ai` package with `execute: ai.toolExecute(task)` instead.
121
+ */
122
+ tool: typeof toolFromTask;
123
+ /**
124
+ * Preferred: return value for the `execute` field of AI SDK `tool()`. Keeps Trigger subtask and
125
+ * metadata behavior without coupling to a specific `ai` version’s `Tool` / `ToolSet` types.
126
+ */
127
+ toolExecute: typeof toolExecute;
128
+ currentToolOptions: typeof getToolOptionsFromMetadata;
129
+ /** Get the tool call ID from inside a subtask invoked via `ai.toolExecute()` (or legacy `ai.tool()`). */
130
+ toolCallId: typeof getToolCallId;
131
+ /** Get chat context (chatId, turn, clientData, etc.) from inside a subtask of a `chat.agent`. Returns undefined if not in a chat context. */
132
+ chatContext: typeof getToolChatContext;
133
+ /** Get chat context or throw if not in a chat context. Pass `typeof yourChatTask` for typed clientData. */
134
+ chatContextOrThrow: typeof getToolChatContextOrThrow;
135
+ };
136
+ /**
137
+ * Creates a public access token for a chat task.
138
+ *
139
+ * This is a convenience helper that creates a multi-use trigger public token
140
+ * scoped to the given task. Use it in a server action to provide the frontend
141
+ * `TriggerChatTransport` with an `accessToken`.
142
+ *
143
+ * @example
144
+ * ```ts
145
+ * // actions.ts
146
+ * "use server";
147
+ * import { chat } from "@trigger.dev/sdk/ai";
148
+ * import type { myChat } from "@/trigger/chat";
149
+ *
150
+ * export const getChatToken = () => chat.createAccessToken<typeof myChat>("my-chat");
151
+ * ```
152
+ */
153
+ declare function createChatAccessToken<TTask extends AnyTask>(taskId: TaskIdentifier<TTask>): Promise<string>;
154
+ /**
155
+ * Mint a read-only, session-scoped token for WATCHING a chat session by its `externalId`.
156
+ *
157
+ * A session is addressed by `externalId`, so the same session is reachable from any surface that
158
+ * knows it: a web `useChat` client and a Slack thread converge on one session when they share an
159
+ * `externalId` (for a channel, the connector's `key` template produces it). This token carries
160
+ * `read:sessions:{externalId}` only (no write): the holder can subscribe to the session's `.out`
161
+ * stream (observe the conversation, hydrating history from the snapshot) but cannot append to `.in`.
162
+ *
163
+ * Use it for a dashboard viewer or a cross-surface watcher of a Slack-thread session. Run server-side
164
+ * (needs the secret key). To CONTINUE a session from another surface (drive it, not just watch), mint
165
+ * a read+write token instead ({@link createChatStartSessionAction}).
166
+ *
167
+ * @example
168
+ * ```ts
169
+ * // actions.ts
170
+ * "use server";
171
+ * import { chat } from "@trigger.dev/sdk/ai";
172
+ *
173
+ * export const watchChat = (externalId: string) => chat.createWatchToken(externalId);
174
+ * ```
175
+ */
176
+ declare function createChatWatchToken(externalId: string, options?: {
177
+ tokenTTL?: string;
178
+ }): Promise<string>;
179
+ /**
180
+ * Register work that must land before anything from this turn reaches the
181
+ * frontend.
182
+ *
183
+ * Like {@link chatDefer} the work starts immediately and is never awaited by
184
+ * the hook that registered it, so it runs alongside the model and costs no
185
+ * time to first token. Unlike `chat.defer`, the output stream waits for it:
186
+ * no chunk of the answer is written to the session until it settles. That
187
+ * makes it the right home for a write the next page load has to see (a
188
+ * conversation row, a message insert), because a reader that can see the
189
+ * answer can also see what the write persisted.
190
+ *
191
+ * Reach for `chat.defer` instead when the timing does not matter for a
192
+ * reload: analytics, audit logs, search-index updates.
193
+ *
194
+ * This is not a consistency barrier for the turn. The work is still in flight
195
+ * while the model runs, so a tool, a `prepareStep`, or anything else executing
196
+ * during the turn can still read the state as it was before the write. It
197
+ * orders the write against what the frontend can see, nothing more. When the
198
+ * turn's own code has to read the write back, `await` it instead and accept
199
+ * the cost.
200
+ *
201
+ * A write registered here that fails, or outlasts the internal timeout, lets
202
+ * the stream through rather than stalling the conversation.
203
+ *
204
+ * @example
205
+ * ```ts
206
+ * onTurnStart: async ({ chatId, uiMessages }) => {
207
+ * chat.deferBeforeOutput(
208
+ * db.chat.update({ where: { id: chatId }, data: { messages: uiMessages } })
209
+ * );
210
+ * },
211
+ * ```
212
+ */
213
+ declare function chatDeferBeforeOutput(promiseOrFn: Promise<unknown> | (() => Promise<unknown>)): void;
214
+ /**
215
+ * A stream writer passed to chat lifecycle callbacks (`onPreload`, `onChatStart`,
216
+ * `onTurnStart`, `onTurnComplete`, `onCompacted`).
217
+ *
218
+ * Write custom `UIMessageChunk` parts (e.g. `data-*` parts) directly to the chat
219
+ * stream without the ceremony of `chat.stream.writer({ execute })`.
220
+ *
221
+ * The writer is lazy — no stream overhead if you don't call `write()` or `merge()`.
222
+ *
223
+ * @example
224
+ * ```ts
225
+ * onTurnStart: async ({ writer }) => {
226
+ * writer.write({ type: "data-status", data: { loading: true } });
227
+ * },
228
+ * onTurnComplete: async ({ writer, uiMessages }) => {
229
+ * writer.write({ type: "data-analytics", data: { messageCount: uiMessages.length } });
230
+ * },
231
+ * ```
232
+ */
233
+ export type ChatWriter = {
234
+ /** Write a single UIMessageChunk to the chat stream. */
235
+ write(part: UIMessageChunk): void;
236
+ /** Merge another stream's chunks into the chat stream. */
237
+ merge(stream: ReadableStream<UIMessageChunk>): void;
238
+ };
239
+ type ChatCustomAgentClientDataErrorHandler = (event: {
240
+ error: unknown;
241
+ payload: ChatTaskWirePayload;
242
+ }) => Promise<void> | void;
243
+ /**
244
+ * The payload shape passed to the `chatAgent` run function.
245
+ *
246
+ * - `messages` contains model-ready messages (converted via `convertToModelMessages`) —
247
+ * pass these directly to `streamText`.
248
+ * - `clientData` contains custom data from the frontend (the `metadata` field from `sendMessage()`).
249
+ *
250
+ * The backend accumulates the full conversation history across turns, so the frontend
251
+ * only needs to send new messages after the first turn.
252
+ */
253
+ export type ChatTaskPayload<TClientData = unknown> = {
254
+ /** Model-ready messages — pass directly to `streamText({ messages })`. */
255
+ messages: ModelMessage[];
256
+ /** The unique identifier for the chat session */
257
+ chatId: string;
258
+ /**
259
+ * The trigger type:
260
+ * - `"submit-message"`: A new user message
261
+ * - `"regenerate-message"`: Regenerate the last assistant response
262
+ * - `"preload"`: Run was preloaded before the first message (only on turn 0)
263
+ * - `"action"`: A typed action from the frontend (see `actionSchema` + `onAction`).
264
+ * The action has already been applied before `run()` fires — check `trigger === "action"`
265
+ * to short-circuit the LLM call when an action doesn't need a response.
266
+ * - `"close"`: The chat session is being closed (internal; `run()` is not called).
267
+ */
268
+ trigger: "submit-message" | "regenerate-message" | "preload" | "action" | "action-turn" | "close";
269
+ /** The ID of the message to regenerate (only for `"regenerate-message"`) */
270
+ messageId?: string;
271
+ /** Custom data from the frontend (passed via `metadata` on `sendMessage()` or the transport). */
272
+ clientData?: TClientData;
273
+ /** Whether this run is continuing an existing chat (previous run timed out or was cancelled). False for brand new chats. */
274
+ continuation: boolean;
275
+ /** The run ID of the previous run (only set when `continuation` is true). */
276
+ previousRunId?: string;
277
+ /** Whether this run was preloaded before the first message. */
278
+ preloaded: boolean;
279
+ /**
280
+ * The friendlyId of the Session primitive backing this chat. Use with
281
+ * `sessions.open(sessionId)` when you need direct access to the session's
282
+ * `.in` / `.out` channels outside the hooks the agent already wires for
283
+ * you. Undefined only for legacy transports that predate the sessions
284
+ * migration.
285
+ */
286
+ sessionId?: string;
287
+ };
288
+ /**
289
+ * Abort signals provided to the `chatAgent` run function.
290
+ */
291
+ export type ChatTaskSignals = {
292
+ /** Combined signal — fires on run cancel OR stop generation. Pass to `streamText`. */
293
+ signal: AbortSignal;
294
+ /** Fires only when the run is cancelled, expired, or exceeds maxDuration. */
295
+ cancelSignal: AbortSignal;
296
+ /** Fires only when the frontend stops generation for this turn (per-turn, reset each turn). */
297
+ stopSignal: AbortSignal;
298
+ };
299
+ /**
300
+ * The full payload passed to a `chatAgent` run function.
301
+ * Extends `ChatTaskPayload` (the wire payload) with abort signals.
302
+ */
303
+ export type ChatTaskRunPayload<TClientData = unknown, TTools extends ToolSet = ToolSet> = ChatTaskPayload<TClientData> & ChatTaskSignals & {
304
+ /**
305
+ * Task run context — same object as the `ctx` passed to a standard `task({ run })` handler’s second argument.
306
+ * Use for tags, metadata, parent run links, or any API that needs the full run record.
307
+ */
308
+ ctx: TaskRunContext;
309
+ /**
310
+ * `streamText` with this agent's managed options already applied: the
311
+ * prompt from `chat.prompt.set()`, the skill tools, telemetry, and the
312
+ * `prepareStep` that delivers steering, compaction and injected context.
313
+ *
314
+ * Prefer it over importing `streamText` from `ai`. The imported one takes
315
+ * none of that unless you spread `chat.toStreamTextOptions()` yourself, and
316
+ * forgetting the spread fails silently.
317
+ */
318
+ streamText: AiStreamTextFn;
319
+ /** Token usage from the previous turn. Undefined on turn 0. */
320
+ previousTurnUsage?: LanguageModelUsage;
321
+ /** Cumulative token usage across all completed turns so far. */
322
+ totalUsage: LanguageModelUsage;
323
+ /**
324
+ * The resolved tool set for this turn, the same `tools` you declared on
325
+ * `chat.agent({ tools })` (or the result of the per-turn `tools` function).
326
+ * Pass straight to `streamText({ tools })` so you don't redeclare them:
327
+ *
328
+ * ```ts
329
+ * run: ({ messages, tools, signal }) =>
330
+ * streamText({ model, messages, tools, abortSignal: signal })
331
+ * ```
332
+ *
333
+ * Declaring `tools` on the config is also what lets the SDK re-run each
334
+ * tool's `toModelOutput` when it re-converts prior-turn history (see the
335
+ * `tools` option on `chat.agent`). Empty object when no `tools` were declared.
336
+ */
337
+ tools: TTools;
338
+ /**
339
+ * Present for a channel turn whose connector supports reactions or defines a `surface()`. Lets the
340
+ * agent react to the triggering message (e.g. `channel.react("white_check_mark")`) and use the
341
+ * connector's helpers (cast to the connector's exported surface type).
342
+ */
343
+ channel?: ChannelRunSurface;
344
+ };
345
+ /**
346
+ * One message record delivered through {@link chat.messages}.
347
+ *
348
+ * `id` is the append's stable idempotency key and `seqNum` is its monotonic
349
+ * sequence on the Session `.in` channel. Both remain stable if the record is
350
+ * delivered again after a reconnect.
351
+ */
352
+ export type ChatMessageRecord = Readonly<{
353
+ id: string;
354
+ seqNum: number;
355
+ payload: ChatTaskWirePayload;
356
+ }>;
357
+ export type ChatMessages = RealtimeDefinedInputStream<ChatTaskWirePayload> & {
358
+ /** Whether the local buffer head is a message that can be consumed immediately. */
359
+ hasPending(): Promise<boolean>;
360
+ /** Consume one message record, or return `undefined` when the optional timeout elapses. */
361
+ next(options?: {
362
+ timeoutInSeconds?: number;
363
+ }): Promise<ChatMessageRecord | undefined>;
364
+ };
365
+ /**
366
+ * Signal received by a `handover-prepare` agent run waiting on
367
+ * `session.in`. Either the customer's first-turn `streamText` finished
368
+ * with pending tool calls (`"handover"` — agent picks up from tool
369
+ * execution), or it finished pure-text (`"handover-skip"` — agent
370
+ * exits cleanly without making an LLM call).
371
+ *
372
+ * Returned by `chat.waitForHandover()` for custom-agent loops.
373
+ */
374
+ export type HandoverSignal = {
375
+ kind: "handover";
376
+ partialAssistantMessage: ModelMessage[];
377
+ messageId?: string;
378
+ /**
379
+ * Whether the customer's step 1 is the final response. When
380
+ * true, the agent's turn loop runs hooks but skips the LLM
381
+ * call (the partial IS the response). When false, the agent
382
+ * runs `streamText` which executes pending tool-calls via the
383
+ * approval round and continues from step 2.
384
+ */
385
+ isFinal: boolean;
386
+ } | {
387
+ kind: "handover-skip";
388
+ };
389
+ /**
390
+ * Wait for a `chat.headStart` handover signal inside a custom-agent loop or
391
+ * `chat.createSession`. Returns:
392
+ * - `null` — this run is not a `handover-prepare` boot, or the wait idled out /
393
+ * the warm handler crashed before signaling. Treat as "no handover".
394
+ * - `{ kind: "handover-skip" }` — the warm handler aborted; exit without a turn.
395
+ * - `{ kind: "handover", partialAssistantMessage, messageId?, isFinal }` — splice
396
+ * the partial (`chat.MessageAccumulator.applyHandover`) and, when `isFinal` is
397
+ * false, fall through to `streamText` to run the handed-over tool round.
398
+ *
399
+ * For the common case prefer `accumulator.consumeHandover()`, which also seeds
400
+ * `payload.headStartMessages` and applies the partial for you.
401
+ *
402
+ * Safe to call at any point in turn 0: the handover signal has its own route,
403
+ * so a message facade waiting at the same time cannot take it.
404
+ */
405
+ declare function waitForHandover(options: {
406
+ /** The run's wire payload (only `trigger` / `idleTimeoutInSeconds` are read). */
407
+ payload: {
408
+ trigger?: string;
409
+ idleTimeoutInSeconds?: number;
410
+ };
411
+ idleTimeoutInSeconds?: number;
412
+ timeout?: string;
413
+ spanName?: string;
414
+ }): Promise<HandoverSignal | null>;
415
+ /** Convenience re-export of the AI SDK's `LanguageModelUsage` type. */
416
+ export type ChatTurnUsage = LanguageModelUsage;
417
+ /**
418
+ * Replace the accumulated conversation messages for the current run.
419
+ *
420
+ * Call from `onTurnStart` to compact before `run()` executes, or from
421
+ * `onTurnComplete` to compact before the next turn. Takes `UIMessage[]`
422
+ * and converts to `ModelMessage[]` internally.
423
+ */
424
+ declare function setChatMessages<TUIM extends UIMessage = UIMessage>(uiMessages: TUIM[]): void;
425
+ /**
426
+ * A tool call surfaced by `chat.history.getPendingToolCalls()` /
427
+ * `getResolvedToolCalls()`. Identifies the call by its `toolCallId` plus
428
+ * the `messageId` of the assistant message that hosts it, so callers can
429
+ * locate the part precisely without re-walking the chain.
430
+ */
431
+ export type ChatToolCallRef = {
432
+ toolCallId: string;
433
+ toolName: string;
434
+ messageId: string;
435
+ };
436
+ /**
437
+ * A new tool result surfaced by `chat.history.extractNewToolResults()`.
438
+ * `errorText` is set iff the part is in `output-error` state; otherwise
439
+ * `output` carries the resolved value.
440
+ */
441
+ export type ChatNewToolResult = {
442
+ toolCallId: string;
443
+ toolName: string;
444
+ output: unknown;
445
+ errorText?: string;
446
+ };
447
+ /** State stored in locals during prepareStep compaction. */
448
+ interface CompactionState {
449
+ summary: string;
450
+ baseResponseMessageCount: number;
451
+ /** Completed steps summarized this turn; unlike message counts, matches UI step markers. */
452
+ baseResponseStepCount: number;
453
+ }
454
+ /**
455
+ * Event passed to `summarize` callbacks.
456
+ */
457
+ export type SummarizeEvent = {
458
+ /** The current model messages to summarize. */
459
+ messages: ModelMessage[];
460
+ /** Full usage object from the triggering step/turn. */
461
+ usage?: LanguageModelUsage;
462
+ /** Cumulative token usage across all completed turns. Present in chat.agent contexts. */
463
+ totalUsage?: LanguageModelUsage;
464
+ /** The chat session ID (if running inside a chat.agent). */
465
+ chatId?: string;
466
+ /** The current turn number (0-indexed, if inside a chat.agent). */
467
+ turn?: number;
468
+ /** Custom data from the frontend (if inside a chat.agent). */
469
+ clientData?: unknown;
470
+ /**
471
+ * Where compaction is running:
472
+ * - `"inner"` — between tool-call steps (prepareStep)
473
+ * - `"outer"` — between turns
474
+ */
475
+ source?: "inner" | "outer";
476
+ /** The step number (0-indexed). Only present when `source` is `"inner"`. */
477
+ stepNumber?: number;
478
+ };
479
+ /**
480
+ * Event passed to `compactUIMessages` and `compactModelMessages` callbacks.
481
+ */
482
+ export type CompactMessagesEvent<TUIM extends UIMessage = UIMessage> = {
483
+ /** The generated summary text. */
484
+ summary: string;
485
+ /** The current UI messages (full conversation). */
486
+ uiMessages: TUIM[];
487
+ /** The current model messages (full conversation). */
488
+ modelMessages: ModelMessage[];
489
+ /** The chat session ID. */
490
+ chatId: string;
491
+ /** The current turn number (0-indexed). */
492
+ turn: number;
493
+ /** Custom data from the frontend. */
494
+ clientData?: unknown;
495
+ /**
496
+ * Where compaction is running:
497
+ * - `"inner"` — between tool-call steps (prepareStep)
498
+ * - `"outer"` — between turns
499
+ */
500
+ source: "inner" | "outer";
501
+ };
502
+ /**
503
+ * Options for the `compaction` field on `chat.agent()`.
504
+ *
505
+ * Handles compaction automatically in both the inner loop (prepareStep, between
506
+ * tool-call steps) and the outer loop (between turns, for single-step responses
507
+ * where prepareStep never fires).
508
+ */
509
+ export type ChatAgentCompactionOptions<TUIM extends UIMessage = UIMessage> = {
510
+ /** Decide whether to compact. Return true to trigger compaction. */
511
+ shouldCompact: (event: ShouldCompactEvent) => boolean | Promise<boolean>;
512
+ /** Generate a summary from the current messages. Return the summary text. */
513
+ summarize: (event: SummarizeEvent) => Promise<string>;
514
+ /**
515
+ * Transform UI messages after compaction (what gets persisted and displayed).
516
+ * Default: preserve all UI messages unchanged.
517
+ *
518
+ * @example
519
+ * ```ts
520
+ * // Flatten to summary
521
+ * compactUIMessages: ({ summary }) => [{
522
+ * id: generateId(), role: "assistant",
523
+ * parts: [{ type: "text", text: `[Summary]\n\n${summary}` }],
524
+ * }],
525
+ *
526
+ * // Summary + keep last 4 messages
527
+ * compactUIMessages: ({ uiMessages, summary }) => [
528
+ * { id: generateId(), role: "assistant",
529
+ * parts: [{ type: "text", text: `[Summary]\n\n${summary}` }] },
530
+ * ...uiMessages.slice(-4),
531
+ * ],
532
+ * ```
533
+ */
534
+ compactUIMessages?: (event: CompactMessagesEvent<TUIM>) => TUIM[] | Promise<TUIM[]>;
535
+ /**
536
+ * Transform model messages after compaction (what gets sent to the LLM).
537
+ * Default: replace all with a single summary message.
538
+ *
539
+ * @example
540
+ * ```ts
541
+ * // Summary + keep last 2 model messages
542
+ * compactModelMessages: ({ modelMessages, summary }) => [
543
+ * { role: "user", content: summary },
544
+ * ...modelMessages.slice(-2),
545
+ * ],
546
+ * ```
547
+ */
548
+ compactModelMessages?: (event: CompactMessagesEvent<TUIM>) => ModelMessage[] | Promise<ModelMessage[]>;
549
+ };
550
+ /**
551
+ * Event passed to `shouldInject` and `prepareMessages` callbacks.
552
+ */
553
+ export type PendingMessagesBatchEvent<TUIM extends UIMessage = UIMessage> = {
554
+ /** All pending UI messages that arrived during streaming (batch). */
555
+ messages: TUIM[];
556
+ /** Current model messages in the conversation. */
557
+ modelMessages: ModelMessage[];
558
+ /** Completed steps so far. */
559
+ steps: CompactionStep[];
560
+ /** Current step number (0-indexed). */
561
+ stepNumber: number;
562
+ /** Chat session ID. */
563
+ chatId: string;
564
+ /** Current turn number (0-indexed). */
565
+ turn: number;
566
+ /** Custom data from the frontend. */
567
+ clientData?: unknown;
568
+ };
569
+ /**
570
+ * Event passed to `onReceived` callback (per-message, as they arrive).
571
+ */
572
+ export type PendingMessageReceivedEvent<TUIM extends UIMessage = UIMessage> = {
573
+ /** The UI message that arrived during streaming. */
574
+ message: TUIM;
575
+ /** Chat session ID. */
576
+ chatId: string;
577
+ /** Current turn number (0-indexed). */
578
+ turn: number;
579
+ };
580
+ /**
581
+ * Event passed to `onInjected` callback (batch, after injection).
582
+ */
583
+ export type PendingMessagesInjectedEvent<TUIM extends UIMessage = UIMessage> = {
584
+ /** All UI messages that were injected. */
585
+ messages: TUIM[];
586
+ /** The model messages that were injected. */
587
+ injectedModelMessages: ModelMessage[];
588
+ /** Chat session ID. */
589
+ chatId: string;
590
+ /** Current turn number (0-indexed). */
591
+ turn: number;
592
+ /** Step number where injection occurred. */
593
+ stepNumber: number;
594
+ };
595
+ /**
596
+ * Options for the `pendingMessages` field on `chat.agent()`, `chat.createSession()`,
597
+ * or `ChatMessageAccumulator`.
598
+ *
599
+ * Configures how messages that arrive during streaming are handled. When
600
+ * `shouldInject` is provided and returns `true`, the full batch of pending
601
+ * messages is injected between tool-call steps via `prepareStep`.
602
+ * Otherwise, messages queue for the next turn.
603
+ */
604
+ export type PendingMessagesOptions<TUIM extends UIMessage = UIMessage> = {
605
+ /**
606
+ * Decide whether to inject pending messages between tool-call steps.
607
+ * Called once per step boundary with the full batch of pending messages.
608
+ * If absent, no injection happens — messages only queue for the next turn.
609
+ */
610
+ shouldInject?: (event: PendingMessagesBatchEvent<TUIM>) => boolean | Promise<boolean>;
611
+ /**
612
+ * Transform the batch of pending messages before injection.
613
+ * Return the model messages to inject.
614
+ * Default: convert each UI message via `convertToModelMessages`.
615
+ */
616
+ prepare?: (event: PendingMessagesBatchEvent<TUIM>) => ModelMessage[] | Promise<ModelMessage[]>;
617
+ /** Called when a message arrives during streaming (per-message). */
618
+ onReceived?: (event: PendingMessageReceivedEvent<TUIM>) => void | Promise<void>;
619
+ /** Called after a batch of messages is injected via `prepareStep`. */
620
+ onInjected?: (event: PendingMessagesInjectedEvent<TUIM>) => void | Promise<void>;
621
+ };
622
+ /**
623
+ * The data part type used to signal that pending messages were injected
624
+ * between tool-call steps. The frontend can match on this to render
625
+ * injection points inline in the assistant response.
626
+ */
627
+ export { PENDING_MESSAGE_INJECTED_TYPE, upsertIncomingMessage };
628
+ export type { InferChatClientData, InferChatUIMessage, InferChatUIMessageFromTools };
629
+ /**
630
+ * Event passed to the `prepareMessages` hook.
631
+ */
632
+ export type PrepareMessagesEvent<TClientData = unknown> = {
633
+ /** The messages to transform. Return the transformed array. */
634
+ messages: ModelMessage[];
635
+ /** Why messages are being prepared. */
636
+ reason: "run" | "compaction-rebuild" | "compaction-result";
637
+ /** The chat session ID. */
638
+ chatId: string;
639
+ /** The current turn number (0-indexed). */
640
+ turn: number;
641
+ /** Custom data from the frontend. */
642
+ clientData?: TClientData;
643
+ };
644
+ /**
645
+ * Event passed to the per-turn `tools` function form on `chat.agent`.
646
+ *
647
+ * Use this when the active tool set depends on per-turn context (the user, a
648
+ * feature flag, etc.). Return the `ToolSet` to use for converting this turn's
649
+ * history. Only `inputSchema` and `toModelOutput` are read during conversion,
650
+ * so a lightweight map (no `execute`) is fine.
651
+ */
652
+ export type ResolveToolsEvent<TClientData = unknown> = {
653
+ /** The chat session ID. */
654
+ chatId: string;
655
+ /** The current turn number (0-indexed). */
656
+ turn: number;
657
+ /** Whether this run is continuing an existing chat. */
658
+ continuation: boolean;
659
+ /** Custom data from the frontend. */
660
+ clientData?: TClientData;
661
+ };
662
+ /**
663
+ * Data shape for `data-compaction` stream chunks emitted during compaction.
664
+ * Use to type the `data` field when rendering compaction parts in the frontend.
665
+ */
666
+ export type CompactionChunkData = {
667
+ status: "compacting" | "complete";
668
+ totalTokens: number | undefined;
669
+ };
670
+ /**
671
+ * Event passed to the `onCompacted` callback.
672
+ */
673
+ export type CompactedEvent = {
674
+ /** Task run context — same as `task` lifecycle hooks and `chat.agent` `run({ ctx })`. */
675
+ ctx: TaskRunContext;
676
+ /** The generated summary text. */
677
+ summary: string;
678
+ /** The messages that were compacted (pre-compaction). */
679
+ messages: ModelMessage[];
680
+ /** Number of messages before compaction. */
681
+ messageCount: number;
682
+ /** Token usage from the step that triggered compaction. */
683
+ usage: LanguageModelUsage;
684
+ /** Total token count that triggered compaction. */
685
+ totalTokens: number | undefined;
686
+ /** Input token count from the triggering step. */
687
+ inputTokens: number | undefined;
688
+ /** Output token count from the triggering step. */
689
+ outputTokens: number | undefined;
690
+ /** The step number where compaction occurred (0-indexed). */
691
+ stepNumber: number;
692
+ /** The chat session ID (if running inside a chat.agent). */
693
+ chatId?: string;
694
+ /** The current turn number (if running inside a chat.agent). */
695
+ turn?: number;
696
+ /** Stream writer — write custom `UIMessageChunk` parts to the chat stream. Lazy: no overhead if unused. */
697
+ writer: ChatWriter;
698
+ };
699
+ /**
700
+ * Event passed to `shouldCompact` callbacks.
701
+ */
702
+ export type ShouldCompactEvent = {
703
+ /** The current model messages (full conversation). */
704
+ messages: ModelMessage[];
705
+ /**
706
+ * Total token count of the triggering model call: the step that just finished
707
+ * (`"inner"`), or the turn's LAST step (`"outer"`). This is the size of the
708
+ * context the model held on that call, which is what a compaction decision is
709
+ * about. It is never the sum over a multi-step turn; see `turnUsage` for that.
710
+ */
711
+ totalTokens: number | undefined;
712
+ /** Input token count of the triggering model call (see `totalTokens`). */
713
+ inputTokens: number | undefined;
714
+ /** Output token count of the triggering model call (see `totalTokens`). */
715
+ outputTokens: number | undefined;
716
+ /** Full usage object of the triggering model call (see `totalTokens`). */
717
+ usage?: LanguageModelUsage;
718
+ /**
719
+ * The whole turn's usage summed over every step, as the provider billed it.
720
+ * Only present when `source` is `"outer"`.
721
+ */
722
+ turnUsage?: LanguageModelUsage;
723
+ /** Cumulative token usage across all completed turns. Present in chat.agent contexts. */
724
+ totalUsage?: LanguageModelUsage;
725
+ /** The chat session ID (if running inside a chat.agent). */
726
+ chatId?: string;
727
+ /** The current turn number (0-indexed, if inside a chat.agent). */
728
+ turn?: number;
729
+ /** Custom data from the frontend (if inside a chat.agent). */
730
+ clientData?: unknown;
731
+ /**
732
+ * Where this check is running:
733
+ * - `"inner"` — between tool-call steps (prepareStep)
734
+ * - `"outer"` — between turns (after response, before onBeforeTurnComplete)
735
+ */
736
+ source?: "inner" | "outer";
737
+ /** The step number (0-indexed). Only present when `source` is `"inner"`. */
738
+ stepNumber?: number;
739
+ /** The steps array from prepareStep. Only present when `source` is `"inner"`. */
740
+ steps?: CompactionStep[];
741
+ };
742
+ /**
743
+ * Options for `chat.compaction()` — the high-level prepareStep factory.
744
+ */
745
+ export type CompactionOptions = {
746
+ /** Generate a summary from the current messages. Return the summary text. */
747
+ summarize: (messages: ModelMessage[]) => Promise<string>;
748
+ /** Token threshold — compact when totalTokens exceeds this. Ignored if `shouldCompact` is provided. */
749
+ threshold?: number;
750
+ /** Custom compaction trigger. When provided, used instead of `threshold`. */
751
+ shouldCompact?: (event: ShouldCompactEvent) => boolean | Promise<boolean>;
752
+ };
753
+ /** A step object as received in prepareStep's `steps` array. */
754
+ export type CompactionStep = {
755
+ usage: LanguageModelUsage;
756
+ finishReason: string;
757
+ content: Array<{
758
+ type: string;
759
+ toolCallId?: string;
760
+ }>;
761
+ response: {
762
+ messages: Array<any>;
763
+ };
764
+ };
765
+ /**
766
+ * Result of `chat.compact()`. Discriminated union so you can inspect
767
+ * what happened, but also directly compatible with prepareStep's return type.
768
+ *
769
+ * - `"skipped"` — no compaction needed (first step, boundary unsafe, or under threshold). Return `undefined` to prepareStep.
770
+ * - `"rebuilt"` — previous compaction exists, messages rebuilt from summary + new response messages.
771
+ * - `"compacted"` — compaction just happened, includes the generated summary.
772
+ */
773
+ export type CompactResult = {
774
+ type: "skipped";
775
+ } | {
776
+ type: "rebuilt";
777
+ messages: ModelMessage[];
778
+ } | {
779
+ type: "compacted";
780
+ messages: ModelMessage[];
781
+ summary: string;
782
+ };
783
+ /**
784
+ * Options for `chat.compact()` — the low-level compaction function.
785
+ */
786
+ export type CompactOptions = {
787
+ /** Generate a summary from the current messages. Return the summary text. */
788
+ summarize: (messages: ModelMessage[]) => Promise<string>;
789
+ /** Token threshold — compact when totalTokens exceeds this. Ignored if `shouldCompact` is provided. */
790
+ threshold?: number;
791
+ /** Custom compaction trigger. When provided, used instead of `threshold`. */
792
+ shouldCompact?: (event: ShouldCompactEvent) => boolean | Promise<boolean>;
793
+ };
794
+ /**
795
+ * Read the current compaction state. Returns the summary and base message count
796
+ * if compaction has occurred in this turn, or `undefined` if not.
797
+ *
798
+ * Use in a custom `prepareStep` to rebuild from a previous compaction:
799
+ * ```ts
800
+ * const state = chat.getCompactionState();
801
+ * if (state) {
802
+ * return { messages: [{ role: "user", content: state.summary }, ...newMsgs] };
803
+ * }
804
+ * ```
805
+ */
806
+ declare function getCompactionState(): CompactionState | undefined;
807
+ /**
808
+ * Low-level compaction for use inside a custom `prepareStep`.
809
+ *
810
+ * Handles the full decision tree: first step, already-compacted rebuild,
811
+ * boundary safety, threshold check, summarization, stream chunks, state
812
+ * storage, and accumulator update.
813
+ *
814
+ * Returns a `CompactResult` — inspect `result.type` to see what happened,
815
+ * or convert to a prepareStep return with `result.type === "skipped" ? undefined : result`.
816
+ *
817
+ * @example
818
+ * ```ts
819
+ * prepareStep: async ({ messages, steps }) => {
820
+ * // your custom logic here...
821
+ * const result = await chat.compact(messages, steps, {
822
+ * threshold: 80_000,
823
+ * summarize: async (msgs) => generateText({ model, messages: msgs }).then(r => r.text),
824
+ * });
825
+ * if (result.type === "compacted") {
826
+ * logger.info("Compacted!", { summary: result.summary });
827
+ * }
828
+ * return result.type === "skipped" ? undefined : result;
829
+ * },
830
+ * ```
831
+ */
832
+ declare function chatCompact(messages: ModelMessage[], steps: CompactionStep[], options: CompactOptions): Promise<CompactResult>;
833
+ /**
834
+ * Returns a `prepareStep` function that handles context compaction automatically.
835
+ *
836
+ * Monitors token usage between tool-call steps. When `totalTokens` exceeds
837
+ * the threshold, generates a summary via `summarize()`, replaces the message
838
+ * history, and emits `data-compaction` stream chunks for the frontend.
839
+ *
840
+ * @example
841
+ * ```ts
842
+ * return streamText({
843
+ * ...chat.toStreamTextOptions({ registry }),
844
+ * messages: chat.addCacheBreaks(messages),
845
+ * prepareStep: chat.compactionStep({
846
+ * threshold: 80_000,
847
+ * summarize: async (messages) => {
848
+ * return generateText({ model, messages: [...messages, { role: "user", content: "Summarize." }] })
849
+ * .then((r) => r.text);
850
+ * },
851
+ * }),
852
+ * tools: { ... },
853
+ * });
854
+ * ```
855
+ */
856
+ declare function chatCompactionStep(options: CompactionOptions): (args: {
857
+ messages: ModelMessage[];
858
+ steps: CompactionStep[];
859
+ }) => Promise<{
860
+ messages: ModelMessage[];
861
+ } | undefined>;
862
+ /**
863
+ * Checks whether it's safe to compact the message history. Returns `false`
864
+ * if any tool calls are in-flight (incomplete tool invocations without results).
865
+ *
866
+ * Call before `chat.setMessages()` to avoid corrupting tool-call state.
867
+ */
868
+ declare function isCompactionSafe(messages: UIMessage[]): boolean;
869
+ /**
870
+ * A resolved prompt stored via `chat.prompt.set()`. Either a full `ResolvedPrompt`
871
+ * from `prompts.define().resolve()`, or a lightweight wrapper around a plain string.
872
+ */
873
+ export type ChatPromptValue = ResolvedPrompt | {
874
+ text: string;
875
+ model: undefined;
876
+ config: undefined;
877
+ promptId: string;
878
+ version: number;
879
+ labels: string[];
880
+ toAISDKTelemetry: (additionalMetadata?: Record<string, string>) => {
881
+ experimental_telemetry: {
882
+ isEnabled: true;
883
+ metadata: Record<string, string>;
884
+ };
885
+ };
886
+ };
887
+ /**
888
+ * Options for `chat.prompt.set()`.
889
+ */
890
+ export type SetChatPromptOptions = {
891
+ /**
892
+ * Provider options attached to the system prompt so a provider can cache it.
893
+ * The most common use is an Anthropic prompt-cache breakpoint on the (large,
894
+ * stable) system block — see the prompt-caching guide. Carried through to
895
+ * `chat.toStreamTextOptions()` automatically; a `systemProviderOptions` /
896
+ * `cacheControl` passed there overrides this.
897
+ *
898
+ * @example
899
+ * chat.prompt.set(SYSTEM_PROMPT, {
900
+ * providerOptions: { anthropic: { cacheControl: { type: "ephemeral" } } },
901
+ * });
902
+ */
903
+ providerOptions?: ProviderMetadata;
904
+ };
905
+ /**
906
+ * Store a resolved prompt (or plain string) for the current run.
907
+ * Call from any hook (`onPreload`, `onChatStart`, `onTurnStart`) or `run()`.
908
+ */
909
+ declare function setChatPrompt(resolved: ResolvedPrompt | string, options?: SetChatPromptOptions): void;
910
+ /**
911
+ * Read the stored prompt. Throws if `chat.prompt.set()` has not been called.
912
+ */
913
+ declare function getChatPrompt(): ChatPromptValue;
914
+ /**
915
+ * Store resolved skills for the current run. Call from any hook
916
+ * (`onPreload`, `onChatStart`, `onTurnStart`) or `run()`.
917
+ */
918
+ declare function setChatSkills(skills: ResolvedSkill[]): void;
919
+ /** Read the stored skills. Returns `undefined` if none set. */
920
+ declare function getChatSkills(): ResolvedSkill[] | undefined;
921
+ /**
922
+ * Build the three tools we auto-inject into `streamText` when skills are
923
+ * set: `loadSkill`, `readFile`, `bash`. Scoped per-skill by name.
924
+ *
925
+ * Exported so callers can use the same tools outside the auto-wired path
926
+ * (e.g. in a `chat.createSession` loop with custom streamText).
927
+ */
928
+ export declare function buildSkillTools(skills: ResolvedSkill[]): Record<string, Tool>;
929
+ /**
930
+ * Options for {@link toStreamTextOptions}.
931
+ */
932
+ export type ToStreamTextOptionsOptions = {
933
+ /**
934
+ * A base system prompt, used when `chat.prompt.set()` has not supplied one.
935
+ * `chat.agent({ system })` and a `system` passed to the managed `streamText`
936
+ * both arrive here.
937
+ */
938
+ system?: string | SystemModelMessage;
939
+ /** Additional telemetry metadata merged into `experimental_telemetry.metadata`. */
940
+ telemetry?: Record<string, string>;
941
+ /**
942
+ * An AI SDK provider registry (from `createProviderRegistry`) or any object
943
+ * with a `languageModel(id)` method. When provided and the stored prompt has
944
+ * a `model` string, the resolved `LanguageModel` is included in the returned
945
+ * options so `streamText` uses it directly.
946
+ *
947
+ * The model string should use the `"provider:model-id"` format
948
+ * (e.g. `"openai:gpt-4o"`, `"anthropic:claude-sonnet-4-6"`).
949
+ */
950
+ registry?: {
951
+ languageModel(modelId: string): unknown;
952
+ };
953
+ /**
954
+ * User-defined tools to merge alongside the auto-injected skill tools
955
+ * (`loadSkill`, `readFile`, `bash`). User tools win on name conflicts.
956
+ *
957
+ * If you don't pass `tools` here and skills are set, the returned options
958
+ * will include just the skill tools — spread after any `tools` you pass
959
+ * directly to `streamText` and they'll be replaced. Easiest: pass all
960
+ * your tools here.
961
+ */
962
+ tools?: Record<string, Tool>;
963
+ /**
964
+ * Provider options attached to the system prompt so a provider can cache it.
965
+ * When set (or when {@link cacheControl} or `chat.prompt.set`'s
966
+ * `providerOptions` is set), `system` is returned as a structured
967
+ * `SystemModelMessage` carrying these options instead of a plain string —
968
+ * letting providers like Anthropic apply prompt caching to the (large,
969
+ * stable) system block, which is the single highest-value cache target.
970
+ *
971
+ * Overrides any `providerOptions` set on `chat.prompt.set()`.
972
+ *
973
+ * @example
974
+ * chat.toStreamTextOptions({
975
+ * systemProviderOptions: { anthropic: { cacheControl: { type: "ephemeral" } } },
976
+ * });
977
+ */
978
+ systemProviderOptions?: ProviderMetadata;
979
+ /**
980
+ * Anthropic-only convenience for {@link systemProviderOptions}: caches the
981
+ * system prompt with the given cache breakpoint. Equivalent to
982
+ * `systemProviderOptions: { anthropic: { cacheControl } }`. For other
983
+ * providers (e.g. Amazon Bedrock's `cachePoint`), use `systemProviderOptions`.
984
+ *
985
+ * @example
986
+ * chat.toStreamTextOptions({ cacheControl: { type: "ephemeral" } });
987
+ */
988
+ cacheControl?: SystemCacheControl;
989
+ };
990
+ /**
991
+ * Anthropic prompt-cache breakpoint shape (`providerOptions.anthropic.cacheControl`).
992
+ * `ttl` defaults to the 5-minute cache; `"1h"` selects the 1-hour cache.
993
+ */
994
+ export type SystemCacheControl = {
995
+ type: "ephemeral";
996
+ ttl?: "5m" | "1h";
997
+ };
998
+ /**
999
+ * Returns an options object ready to spread into `streamText()`.
1000
+ *
1001
+ * Includes `system`, `experimental_telemetry`, and any config fields
1002
+ * (temperature, maxTokens, etc.) from the stored prompt.
1003
+ *
1004
+ * When a `registry` is provided and the prompt has a `model` string,
1005
+ * the resolved `LanguageModel` is included as `model`.
1006
+ *
1007
+ * If no prompt has been set, returns `{}` (no-op spread).
1008
+ */
1009
+ /**
1010
+ * The AI SDK's own `streamText` signature, borrowed rather than restated.
1011
+ *
1012
+ * The peer range spans `ai` v5, v6 and v7, whose `streamText` options differ.
1013
+ * Describing the shape here would drift against all three; `typeof` resolves to
1014
+ * whichever version the user installed, so generics, overloads and tool
1015
+ * inference are exactly theirs.
1016
+ */
1017
+ type AiStreamTextFn = typeof aiStreamTextSignature;
1018
+ /**
1019
+ * The `streamText` handed to a `chat.agent` `run()`, carrying the agent's
1020
+ * managed options.
1021
+ *
1022
+ * Exported so a loop factored out of `run` can take it as a parameter and keep
1023
+ * them: `function loop(messages: ModelMessage[], streamText: ChatStreamText)`.
1024
+ */
1025
+ export type ChatStreamText = AiStreamTextFn;
1026
+ declare function toStreamTextOptions(options?: ToStreamTextOptionsOptions, retain?: boolean): Record<string, unknown>;
1027
+ /**
1028
+ * Options for `pipeChat`.
1029
+ */
1030
+ export type PipeChatOptions = {
1031
+ /**
1032
+ * Override the stream key. Must match the `streamKey` on `TriggerChatTransport`.
1033
+ * @default "chat"
1034
+ */
1035
+ streamKey?: string;
1036
+ /** An AbortSignal to cancel the stream. */
1037
+ signal?: AbortSignal;
1038
+ /**
1039
+ * The target run ID to pipe to.
1040
+ * @default "self" (current run)
1041
+ */
1042
+ target?: string;
1043
+ /** Override the default span name for this operation. */
1044
+ spanName?: string;
1045
+ };
1046
+ /**
1047
+ * Options for customizing the `toUIMessageStream()` call used when piping
1048
+ * `streamText` results to the frontend.
1049
+ *
1050
+ * Set static defaults via `uiMessageStreamOptions` on `chat.agent()`, or
1051
+ * override per-turn via `chat.setUIMessageStreamOptions()`.
1052
+ *
1053
+ * `onFinish` is omitted because it is managed internally for response capture.
1054
+ * Use `streamText`'s `onFinish` for custom finish handling, or drop down to
1055
+ * raw task mode with `chat.pipe()` for full control.
1056
+ *
1057
+ * `originalMessages` is omitted because it is automatically set from the
1058
+ * accumulated conversation history, ensuring message IDs are reused across
1059
+ * turns (e.g. for tool approval continuations).
1060
+ *
1061
+ * `generateMessageId` can be set to control ID generation for response
1062
+ * messages (e.g. UUID-v7). If not set, the AI SDK's default `generateId` is used.
1063
+ */
1064
+ export type ChatUIMessageStreamOptions<TUIM extends UIMessage = UIMessage> = Omit<UIMessageStreamOptions<TUIM>, "onFinish" | "originalMessages">;
1065
+ /**
1066
+ * An object with a `toUIMessageStream()` method (e.g. `StreamTextResult` from `streamText()`).
1067
+ */
1068
+ type UIMessageStreamable = {
1069
+ toUIMessageStream: (...args: any[]) => AsyncIterable<unknown> | ReadableStream<unknown>;
1070
+ };
1071
+ declare const actionTurnBrand: unique symbol;
1072
+ /**
1073
+ * The marker `onAction` returns to have a turn run on the history it just
1074
+ * edited. Produce it with {@link chat.turn}.
1075
+ */
1076
+ export type ActionTurn = {
1077
+ readonly [actionTurnBrand]: true;
1078
+ /** A user message the turn answers, appended to the history after the action's edit. */
1079
+ readonly message?: string | UIMessage;
1080
+ };
1081
+ /**
1082
+ * Turn the current action into a turn.
1083
+ *
1084
+ * Return it from `onAction` after editing history. The action's own work is
1085
+ * finished first (the edit is applied and snapshotted), then a turn runs on the
1086
+ * result exactly as a message turn does: `onTurnStart`, `run()` with the edited
1087
+ * history, `onBeforeTurnComplete`, `onTurnComplete`, and the turn counter
1088
+ * advances. That gives the answer everything a turn has, the system prompt,
1089
+ * tools, steering, compaction, injected instructions and persistence, with no
1090
+ * action-specific handling.
1091
+ *
1092
+ * Pass `message` to have the turn answer a new user message, appended after the edit: a click on a
1093
+ * "Explain more" button becomes `chat.turn("Explain that in more detail.")`.
1094
+ *
1095
+ * @example
1096
+ * ```ts
1097
+ * onAction: async ({ action }) => {
1098
+ * if (action.type === "regenerate") {
1099
+ * chat.history.slice(0, -1);
1100
+ * return chat.turn();
1101
+ * }
1102
+ * if (action.type === "ask") return chat.turn(action.question);
1103
+ * if (action.type === "undo") chat.history.slice(0, -2); // no turn
1104
+ * },
1105
+ * ```
1106
+ */
1107
+ declare function chatTurn(message?: string | UIMessage): ActionTurn;
1108
+ /**
1109
+ * Pipes a chat stream to the realtime stream, making it available to the
1110
+ * `TriggerChatTransport` on the frontend.
1111
+ *
1112
+ * Accepts:
1113
+ * - A `StreamTextResult` from `streamText()` (has `.toUIMessageStream()`)
1114
+ * - An `AsyncIterable` of `UIMessageChunk`s
1115
+ * - A `ReadableStream` of `UIMessageChunk`s
1116
+ *
1117
+ * Must be called from inside a Trigger.dev task's `run` function.
1118
+ *
1119
+ * @example
1120
+ * ```ts
1121
+ * import { task } from "@trigger.dev/sdk";
1122
+ * import { chat, type ChatTaskPayload } from "@trigger.dev/sdk/ai";
1123
+ * import { streamText, convertToModelMessages } from "ai";
1124
+ *
1125
+ * export const myChatTask = task({
1126
+ * id: "my-chat-task",
1127
+ * run: async (payload: ChatTaskPayload) => {
1128
+ * const result = streamText({
1129
+ * model: openai("gpt-4o"),
1130
+ * messages: payload.messages,
1131
+ * });
1132
+ *
1133
+ * await chat.pipe(result);
1134
+ * },
1135
+ * });
1136
+ * ```
1137
+ *
1138
+ * @example
1139
+ * ```ts
1140
+ * // Works from anywhere inside a task — even deep in your agent code
1141
+ * async function runAgentLoop(messages: CoreMessage[]) {
1142
+ * const result = streamText({ model, messages });
1143
+ * await chat.pipe(result);
1144
+ * }
1145
+ * ```
1146
+ */
1147
+ declare function pipeChat(source: UIMessageStreamable | AsyncIterable<unknown> | ReadableStream<unknown>, options?: PipeChatOptions, capture?: {
1148
+ originalMessages?: UIMessage[];
1149
+ }): Promise<void>;
1150
+ /**
1151
+ * Options for defining a chat task.
1152
+ *
1153
+ * Extends the standard `TaskOptions` but pre-types the payload as `ChatTaskPayload`
1154
+ * and overrides `run` to accept `ChatTaskRunPayload` (with abort signals).
1155
+ *
1156
+ * **Auto-piping:** If the `run` function returns a value with `.toUIMessageStream()`
1157
+ * (like a `StreamTextResult`), the stream is automatically piped to the frontend.
1158
+ *
1159
+ * **Single-run mode:** By default, the task uses input streams so that the
1160
+ * entire conversation lives inside one run. After each AI response, the task
1161
+ * emits a control chunk and suspends via `messagesInput.wait()`. The frontend
1162
+ * transport resumes the same run by sending the next message via input streams.
1163
+ */
1164
+ /**
1165
+ * Event passed to the `onPreload` callback.
1166
+ */
1167
+ export type PreloadEvent<TClientData = unknown> = {
1168
+ /** Task run context — same as `task({ run })` second-argument `ctx`. */
1169
+ ctx: TaskRunContext;
1170
+ /** The unique identifier for the chat session. */
1171
+ chatId: string;
1172
+ /** The Trigger.dev run ID for this conversation. */
1173
+ runId: string;
1174
+ /** A scoped access token for this chat run. */
1175
+ chatAccessToken: string;
1176
+ /** Custom data from the frontend. */
1177
+ clientData?: TClientData;
1178
+ /** Stream writer — write custom `UIMessageChunk` parts to the chat stream. Lazy: no overhead if unused. */
1179
+ writer: ChatWriter;
1180
+ };
1181
+ /**
1182
+ * Event passed to the `onBoot` callback.
1183
+ *
1184
+ * Fires once at the start of every run boot — for the initial first-message
1185
+ * run, for preloaded runs, AND for reactive continuation runs (post-cancel,
1186
+ * post-crash, post-`endRun`, `chat.requestUpgrade`, OOM-retry attempts).
1187
+ * Does NOT fire when the SAME run resumes from snapshot via the
1188
+ * idle-window suspend/resume path — use `onChatResume` for that.
1189
+ *
1190
+ * Use this for per-process setup that needs to run every time a fresh
1191
+ * worker picks up the chat: initialize `chat.local` state, open
1192
+ * per-process resources (DB connections, sandboxes, etc.), or
1193
+ * re-hydrate customer state from your DB on continuation.
1194
+ *
1195
+ * Ordering:
1196
+ * - First message of a chat: `onBoot` → `onChatStart` → `onTurnStart` → `run()`
1197
+ * - Preloaded run: `onBoot` → `onPreload` → (wait) → `onChatStart` → ...
1198
+ * - Continuation run: `onBoot` → (wait for first message) → `onTurnStart` → `run()`
1199
+ * (`onChatStart` does NOT fire on continuation runs)
1200
+ */
1201
+ export type BootEvent<TClientData = unknown> = {
1202
+ /** Task run context — same as `task({ run })` second-argument `ctx`. */
1203
+ ctx: TaskRunContext;
1204
+ /** The unique identifier for the chat session. */
1205
+ chatId: string;
1206
+ /** The Trigger.dev run ID for this run boot. */
1207
+ runId: string;
1208
+ /** A scoped access token for this chat run. Persist this for frontend reconnection. */
1209
+ chatAccessToken: string;
1210
+ /** Custom data from the frontend (passed via `metadata` on `sendMessage()` or the transport). */
1211
+ clientData: TClientData;
1212
+ /**
1213
+ * True when this run is a reactive continuation — the prior run died
1214
+ * (cancel / crash / `endRun` / `requestUpgrade` / OOM retry) and this
1215
+ * fresh worker is taking over the chat. Branch on this to re-load
1216
+ * customer-owned state from your DB.
1217
+ */
1218
+ continuation: boolean;
1219
+ /** Public id of the prior run when `continuation` is true. */
1220
+ previousRunId?: string;
1221
+ /** Whether this run was triggered as a preload. */
1222
+ preloaded: boolean;
1223
+ };
1224
+ /**
1225
+ * A tool call extracted from the partial assistant message of a dead run.
1226
+ * Surfaced on `RecoveryBootEvent.pendingToolCalls` so the customer can
1227
+ * decide how to repair the chain (synthesize a result, drop the partial,
1228
+ * etc.).
1229
+ */
1230
+ export type RecoveryPendingToolCall = {
1231
+ /** The AI SDK tool call id. */
1232
+ toolCallId: string;
1233
+ /** The tool name (the `tool-${name}` suffix). */
1234
+ toolName: string;
1235
+ /** The input the model produced for the tool call. */
1236
+ input: unknown;
1237
+ /** The part index inside `partialAssistant.parts` for in-place edits. */
1238
+ partIndex: number;
1239
+ };
1240
+ /**
1241
+ * Event passed to the `onRecoveryBoot` callback.
1242
+ *
1243
+ * Fires once at boot when a continuation run inherits in-flight state from
1244
+ * a dead predecessor (cancel / crash / OOM / deploy eviction / graceful
1245
+ * `chat.requestUpgrade`). The runtime reads both `session.in` and
1246
+ * `session.out` past the last `turn-complete` cursor and surfaces the
1247
+ * recovered pieces here so the customer can shape the conversational
1248
+ * chain before the first turn fires.
1249
+ *
1250
+ * Does NOT fire when there's nothing to recover (clean continuation after
1251
+ * `chat.endRun()` with no buffered user messages, fresh chat, OOM retry
1252
+ * after a successful turn-complete with no in-flight tail).
1253
+ *
1254
+ * Fires regardless of who owns the model's context. With `hydrateMessages`
1255
+ * or a storage `loadContext`, the recovered tail reaches that hook in
1256
+ * `previousMessages` on the next turn.
1257
+ */
1258
+ export type RecoveryBootEvent<TUIM extends UIMessage = UIMessage> = {
1259
+ /** Task run context — same as `task({ run })` second-argument `ctx`. */
1260
+ ctx: TaskRunContext;
1261
+ /** The unique identifier for the chat session. */
1262
+ chatId: string;
1263
+ /** The Trigger.dev run ID for this run boot. */
1264
+ runId: string;
1265
+ /** Public id of the prior run that died. */
1266
+ previousRunId: string;
1267
+ /**
1268
+ * Best-effort cause of the predecessor's death. Currently always
1269
+ * `"unknown"` — the run engine doesn't yet plumb the real reason
1270
+ * into the continuation payload. Future SDK versions will narrow
1271
+ * this. Don't branch behavior on it yet.
1272
+ */
1273
+ cause: "cancelled" | "crashed" | "unknown";
1274
+ /**
1275
+ * The conversation chain that was successfully persisted by the
1276
+ * predecessor's last `onTurnComplete`. Empty if the predecessor died
1277
+ * before turn 1 ever completed.
1278
+ */
1279
+ settledMessages: TUIM[];
1280
+ /**
1281
+ * User messages that arrived on `session.in` past the cursor — i.e.
1282
+ * the message(s) the predecessor was processing or had queued when
1283
+ * it died. The runtime's default re-dispatches each as a fresh turn
1284
+ * after the chain is restored, except when a `partialAssistant` is
1285
+ * present AND there are two or more of them: the first is then
1286
+ * spliced into the chain (as the question the partial was answering)
1287
+ * rather than dispatched. Return a different list via
1288
+ * `recoveredTurns` to skip / reorder / collapse them.
1289
+ */
1290
+ inFlightUsers: TUIM[];
1291
+ /**
1292
+ * The trailing assistant message the predecessor was streaming when
1293
+ * it died — the orphan whose `turn-complete` never fired. Undefined
1294
+ * if the predecessor died before any assistant output reached
1295
+ * `session.out` (cancel-before-first-token, snapshot-only path).
1296
+ */
1297
+ partialAssistant: TUIM | undefined;
1298
+ /**
1299
+ * Tool calls extracted from `partialAssistant.parts` that the model
1300
+ * had started but the tool runtime never resolved. Empty when
1301
+ * `partialAssistant` is undefined or carries no `input-available`
1302
+ * tool parts.
1303
+ */
1304
+ pendingToolCalls: RecoveryPendingToolCall[];
1305
+ /**
1306
+ * Lazy session.out writer — identical to the `writer` passed to
1307
+ * `onTurnStart` / `onTurnComplete` / `onChatStart`. Use this to emit
1308
+ * a recovery signal (e.g. a `data-chat-recovery` UIMessage chunk)
1309
+ * BEFORE the first recovered turn fires so the bridge can render a
1310
+ * "recovering..." banner. Lazy: no overhead if unused.
1311
+ */
1312
+ writer: ChatWriter;
1313
+ };
1314
+ /**
1315
+ * Return shape for the `onRecoveryBoot` callback. Every field is optional —
1316
+ * omit one to accept the default.
1317
+ */
1318
+ export type RecoveryBootResult<TUIM extends UIMessage = UIMessage> = {
1319
+ /**
1320
+ * The chain the new run boots with. Replaces the default
1321
+ * (`settledMessages`). Use this to keep the partial assistant in
1322
+ * context, mutate its tool parts to inject synthesized results,
1323
+ * collapse history, etc.
1324
+ *
1325
+ * With `hydrateMessages` or a storage `loadContext`, this chain is what
1326
+ * the hook receives as `previousMessages` on the next turn; the hook's
1327
+ * return value is the chain the model sees.
1328
+ */
1329
+ chain?: TUIM[];
1330
+ /**
1331
+ * The user messages to re-dispatch as fresh turns after the chain is
1332
+ * restored. Default: `inFlightUsers.slice(1)` when a
1333
+ * `partialAssistant` is present and there are two or more in-flight
1334
+ * users (the first one is spliced into the chain instead), otherwise
1335
+ * `inFlightUsers` — including the single-user case, where the
1336
+ * interrupted user is re-dispatched and the orphan partial is
1337
+ * dropped. Return `[]` to suppress all of them; return a filtered /
1338
+ * reordered subset to skip specific ones.
1339
+ */
1340
+ recoveredTurns?: TUIM[];
1341
+ /**
1342
+ * Awaitable run AFTER the writer flushes and BEFORE the first
1343
+ * recovered turn fires. Use for blocking persistence (e.g. write the
1344
+ * partial assistant to your DB so a follow-up turn can reference
1345
+ * it). Errors bubble — wrap your own try/catch if you want to soft-
1346
+ * fail.
1347
+ */
1348
+ beforeBoot?: () => Promise<void>;
1349
+ };
1350
+ /**
1351
+ * Event passed to the `onChatStart` callback.
1352
+ *
1353
+ * Fires exactly once per chat, on the very first user message of the chat's
1354
+ * lifetime. Does NOT fire on continuation runs (post-`endRun`,
1355
+ * post-waitpoint-timeout, `chat.requestUpgrade`) or on OOM-retry attempts —
1356
+ * those are runs of an already-started chat.
1357
+ */
1358
+ export type ChatStartEvent<TClientData = unknown> = {
1359
+ /** Task run context — same as `task({ run })` second-argument `ctx`. */
1360
+ ctx: TaskRunContext;
1361
+ /** The unique identifier for the chat session. */
1362
+ chatId: string;
1363
+ /**
1364
+ * The initial model-ready messages for this conversation. Typically just
1365
+ * the first user message (or empty if `chat.headStart` is in play and the
1366
+ * seed message is supplied elsewhere). Since this hook only fires for the
1367
+ * chat's very first message, there's no prior history to load here.
1368
+ */
1369
+ messages: ModelMessage[];
1370
+ /** Custom data from the frontend (passed via `metadata` on `sendMessage()` or the transport). */
1371
+ clientData: TClientData;
1372
+ /** The Trigger.dev run ID for this conversation. */
1373
+ runId: string;
1374
+ /** A scoped access token for this chat run. Persist this for frontend reconnection. */
1375
+ chatAccessToken: string;
1376
+ /**
1377
+ * @deprecated Always `false` — `onChatStart` no longer fires on continuation
1378
+ * runs. Kept for backward compatibility; remove your `continuation` checks
1379
+ * from `onChatStart` and rely on the contract (this hook fires exactly once
1380
+ * per chat, on the very first message).
1381
+ */
1382
+ continuation: boolean;
1383
+ /**
1384
+ * @deprecated Always `undefined` — `onChatStart` no longer fires on
1385
+ * continuation runs.
1386
+ */
1387
+ previousRunId?: string;
1388
+ /** Whether this run was preloaded before the first message. */
1389
+ preloaded: boolean;
1390
+ /** Stream writer — write custom `UIMessageChunk` parts to the chat stream. Lazy: no overhead if unused. */
1391
+ writer: ChatWriter;
1392
+ };
1393
+ /**
1394
+ * Event passed to the `hydrateMessages` callback.
1395
+ */
1396
+ export type HydrateMessagesEvent<TClientData = unknown, TUIM extends UIMessage = UIMessage> = {
1397
+ /** The unique identifier for the chat session. */
1398
+ chatId: string;
1399
+ /** The turn number (0-indexed). */
1400
+ turn: number;
1401
+ /** The trigger type for this turn. */
1402
+ trigger: "submit-message" | "regenerate-message" | "action";
1403
+ /** Validated incoming UI messages from the wire payload (what the frontend sent). Empty for actions. */
1404
+ incomingMessages: TUIM[];
1405
+ /** The accumulated UI messages before this turn (empty on turn 0). */
1406
+ previousMessages: TUIM[];
1407
+ /** Parsed client data from the transport metadata. */
1408
+ clientData?: TClientData;
1409
+ /** Whether this run is continuing from a previous run. */
1410
+ continuation: boolean;
1411
+ /** The ID of the previous run (if continuation). */
1412
+ previousRunId?: string;
1413
+ };
1414
+ /**
1415
+ * Event passed to the `onValidateMessages` callback.
1416
+ */
1417
+ export type ValidateMessagesEvent<TUIM extends UIMessage = UIMessage> = {
1418
+ /**
1419
+ * The incoming UI messages for this turn (after cleanup of aborted tool parts).
1420
+ *
1421
+ * For HITL continuations the assistant entry is slim — `state` + `output` /
1422
+ * `errorText` / `approval` only, no `input` or other parts. Don't pass the
1423
+ * full `messages` array to `validateUIMessages` from `ai`; filter to user
1424
+ * messages (or your own subset) first.
1425
+ */
1426
+ messages: TUIM[];
1427
+ /** The unique identifier for the chat session. */
1428
+ chatId: string;
1429
+ /** The turn number (0-indexed). */
1430
+ turn: number;
1431
+ /** The trigger type for this turn. */
1432
+ trigger: "submit-message" | "regenerate-message" | "preload" | "close";
1433
+ };
1434
+ /**
1435
+ * Event passed to the `onAction` callback.
1436
+ */
1437
+ export type ActionEvent<TAction = unknown, TClientData = unknown, TUIM extends UIMessage = UIMessage> = {
1438
+ /** The parsed and validated action payload. */
1439
+ action: TAction;
1440
+ /** The unique identifier for the chat session. */
1441
+ chatId: string;
1442
+ /** The turn number (0-indexed). */
1443
+ turn: number;
1444
+ /** Parsed client data from the transport metadata. */
1445
+ clientData?: TClientData;
1446
+ /** The accumulated UI messages (after hydration, if set). */
1447
+ uiMessages: TUIM[];
1448
+ /** The accumulated model messages (after hydration, if set). */
1449
+ messages: ModelMessage[];
1450
+ /**
1451
+ * The click that sent a channel action (a `slackButton()` in Slack): the verified provider event,
1452
+ * with who clicked and the message the button was on. Absent for client and webhook actions.
1453
+ */
1454
+ channel?: ChannelActionSource;
1455
+ };
1456
+ /** Where a channel action came from: the connector and the verified event of the click. */
1457
+ export type ChannelActionSource = {
1458
+ connectorId: string;
1459
+ provider: string;
1460
+ event: unknown;
1461
+ deliveryId: string;
1462
+ };
1463
+ /**
1464
+ * Event passed to the `onTurnStart` callback.
1465
+ */
1466
+ export type TurnStartEvent<TClientData = unknown, TUIM extends UIMessage = UIMessage> = {
1467
+ /** Task run context — same as `task({ run })` second-argument `ctx`. */
1468
+ ctx: TaskRunContext;
1469
+ /** The unique identifier for the chat session. */
1470
+ chatId: string;
1471
+ /** The accumulated model-ready messages (all turns so far, including new user message). */
1472
+ messages: ModelMessage[];
1473
+ /** The accumulated UI messages (all turns so far, including new user message). */
1474
+ uiMessages: TUIM[];
1475
+ /** The turn number (0-indexed). */
1476
+ turn: number;
1477
+ /** The Trigger.dev run ID for this conversation. */
1478
+ runId: string;
1479
+ /** A scoped access token for this chat run. */
1480
+ chatAccessToken: string;
1481
+ /** Custom data from the frontend. */
1482
+ clientData?: TClientData;
1483
+ /** Whether this run is continuing an existing chat (previous run timed out or was cancelled). False for brand new chats. */
1484
+ continuation: boolean;
1485
+ /** The run ID of the previous run (only set when `continuation` is true). */
1486
+ previousRunId?: string;
1487
+ /** Whether this run was preloaded before the first message. */
1488
+ preloaded: boolean;
1489
+ /** Token usage from the previous turn. Undefined on turn 0. */
1490
+ previousTurnUsage?: LanguageModelUsage;
1491
+ /** Cumulative token usage across all completed turns so far. */
1492
+ totalUsage: LanguageModelUsage;
1493
+ /** Stream writer — write custom `UIMessageChunk` parts to the chat stream. Lazy: no overhead if unused. */
1494
+ writer: ChatWriter;
1495
+ };
1496
+ /**
1497
+ * Event passed to the `onTurnComplete` callback.
1498
+ */
1499
+ export type TurnCompleteEvent<TClientData = unknown, TUIM extends UIMessage = UIMessage> = {
1500
+ /** Task run context — same as `task({ run })` second-argument `ctx`. */
1501
+ ctx: TaskRunContext;
1502
+ /** The unique identifier for the chat session. */
1503
+ chatId: string;
1504
+ /** The full accumulated conversation in model format (all turns so far). */
1505
+ messages: ModelMessage[];
1506
+ /**
1507
+ * The full accumulated conversation in UI format (all turns so far).
1508
+ * This is the format expected by `useChat` — store this for persistence.
1509
+ */
1510
+ uiMessages: TUIM[];
1511
+ /**
1512
+ * Model messages for this turn's user message(s) and complete assistant response,
1513
+ * including steps summarized during the turn. Same-ID approval and handover
1514
+ * continuations include the full replacement response, so these are not always
1515
+ * an append-only delta. Persist `messages` for future model context, or upsert
1516
+ * `newUIMessages` by ID for the visible conversation.
1517
+ */
1518
+ newMessages: ModelMessage[];
1519
+ /**
1520
+ * New or updated UI messages from this turn (user message(s) + assistant response).
1521
+ * Upsert by message ID: approval and handover continuations can replace an
1522
+ * existing assistant message.
1523
+ */
1524
+ newUIMessages: TUIM[];
1525
+ /** The assistant's response for this turn, with aborted parts cleaned up when `stopped` is true. Undefined if `pipeChat` was used manually. */
1526
+ responseMessage: TUIM | undefined;
1527
+ /**
1528
+ * The raw assistant response before abort cleanup. Includes incomplete tool parts
1529
+ * (`input-available`, `partial-call`) and streaming reasoning/text parts.
1530
+ * Use this if you need custom cleanup logic. Same as `responseMessage` when not stopped.
1531
+ */
1532
+ rawResponseMessage: TUIM | undefined;
1533
+ /** The turn number (0-indexed). */
1534
+ turn: number;
1535
+ /** The Trigger.dev run ID for this conversation. */
1536
+ runId: string;
1537
+ /** A fresh scoped access token for this chat run (renewed each turn). Persist this for frontend reconnection. */
1538
+ chatAccessToken: string;
1539
+ /** The last event ID from the stream writer. Use this with `resume: true` to avoid replaying events after refresh. */
1540
+ lastEventId?: string;
1541
+ /** Custom data from the frontend. */
1542
+ clientData?: TClientData;
1543
+ /** Whether the user stopped generation during this turn. */
1544
+ stopped: boolean;
1545
+ /** Whether this run is continuing an existing chat (previous run timed out or was cancelled). False for brand new chats. */
1546
+ continuation: boolean;
1547
+ /** The run ID of the previous run (only set when `continuation` is true). */
1548
+ previousRunId?: string;
1549
+ /** Whether this run was preloaded before the first message. */
1550
+ preloaded: boolean;
1551
+ /** Token usage for this turn. Undefined if usage couldn't be captured (e.g. manual pipeChat). */
1552
+ usage?: LanguageModelUsage;
1553
+ /** Cumulative token usage across all turns in this run (including this turn). */
1554
+ totalUsage: LanguageModelUsage;
1555
+ /**
1556
+ * Why the LLM stopped generating this turn:
1557
+ * - `"stop"` — model generated a stop sequence (normal completion)
1558
+ * - `"tool-calls"` — model stopped on one or more tool calls. If any tool
1559
+ * has no `execute` function (e.g. an `ask_user` HITL tool), the turn is
1560
+ * paused awaiting user input; inspect `responseMessage.parts` for tool
1561
+ * parts in `input-available` state to distinguish.
1562
+ * - `"length"` — max tokens reached
1563
+ * - `"content-filter"` — content filter stopped the model
1564
+ * - `"error"` — model errored
1565
+ * - `"other"` — provider-specific reason
1566
+ *
1567
+ * Undefined if the underlying stream didn't provide a finish reason (e.g.
1568
+ * manual `pipeChat()` or an aborted stream).
1569
+ */
1570
+ finishReason?: FinishReason;
1571
+ /**
1572
+ * Set when the turn failed (the `run()` body or a lifecycle hook threw).
1573
+ * On an errored turn `responseMessage` is undefined or partial and
1574
+ * `finishReason` is `"error"`. Use this to mark the turn failed in your
1575
+ * persistence. Undefined on a successful turn.
1576
+ */
1577
+ error?: unknown;
1578
+ };
1579
+ /**
1580
+ * Event passed to the `onBeforeTurnComplete` callback.
1581
+ * Same as `TurnCompleteEvent` but includes a `writer` since the stream is still open.
1582
+ */
1583
+ export type BeforeTurnCompleteEvent<TClientData = unknown, TUIM extends UIMessage = UIMessage> = TurnCompleteEvent<TClientData, TUIM> & {
1584
+ /** Stream writer — write custom `UIMessageChunk` parts to the chat stream. Lazy: no overhead if unused. */
1585
+ writer: ChatWriter;
1586
+ };
1587
+ /**
1588
+ * Discriminated event passed to the `onChatSuspend` callback.
1589
+ * Use `phase` to distinguish preload vs turn suspension.
1590
+ */
1591
+ export type ChatSuspendEvent<TClientData = unknown, TUIM extends UIMessage = UIMessage> = {
1592
+ /** Suspend is happening after onPreload, before the first message. */
1593
+ phase: "preload";
1594
+ /** Task run context. */
1595
+ ctx: TaskRunContext;
1596
+ /** The chat session ID. */
1597
+ chatId: string;
1598
+ /** The Trigger.dev run ID. */
1599
+ runId: string;
1600
+ /** Custom data from the frontend. */
1601
+ clientData?: TClientData;
1602
+ } | {
1603
+ /**
1604
+ * Suspend is happening on a continuation run that booted with no incoming
1605
+ * message (post-`endRun`, post-waitpoint-timeout, etc.) and is waiting
1606
+ * for the next session.in record before running any turn. Distinct from
1607
+ * `phase: "preload"` — the chat already started; `onPreload` has not
1608
+ * fired and will not fire on this run.
1609
+ */
1610
+ phase: "continuation";
1611
+ /** Task run context. */
1612
+ ctx: TaskRunContext;
1613
+ /** The chat session ID. */
1614
+ chatId: string;
1615
+ /** The Trigger.dev run ID. */
1616
+ runId: string;
1617
+ /** Custom data from the frontend. */
1618
+ clientData?: TClientData;
1619
+ } | {
1620
+ /** Suspend is happening after a completed turn, waiting for the next message. */
1621
+ phase: "turn";
1622
+ /** Task run context. */
1623
+ ctx: TaskRunContext;
1624
+ /** The chat session ID. */
1625
+ chatId: string;
1626
+ /** The Trigger.dev run ID. */
1627
+ runId: string;
1628
+ /** The turn number (0-indexed) that just completed. */
1629
+ turn: number;
1630
+ /** The accumulated model messages after the completed turn. */
1631
+ messages: ModelMessage[];
1632
+ /** The accumulated UI messages after the completed turn. */
1633
+ uiMessages: TUIM[];
1634
+ /** Custom data from the frontend. */
1635
+ clientData?: TClientData;
1636
+ };
1637
+ /**
1638
+ * Discriminated event passed to the `onChatResume` callback.
1639
+ * Use `phase` to distinguish preload vs turn resumption.
1640
+ */
1641
+ export type ChatResumeEvent<TClientData = unknown, TUIM extends UIMessage = UIMessage> = {
1642
+ /** First message arrived after preload suspension. */
1643
+ phase: "preload";
1644
+ /** Task run context. */
1645
+ ctx: TaskRunContext;
1646
+ /** The chat session ID. */
1647
+ chatId: string;
1648
+ /** The Trigger.dev run ID. */
1649
+ runId: string;
1650
+ /** Custom data from the frontend. */
1651
+ clientData?: TClientData;
1652
+ } | {
1653
+ /**
1654
+ * First message arrived after continuation-wait suspension. Distinct
1655
+ * from `phase: "preload"` — the chat already started; this is a new
1656
+ * run picking up after a prior run ended (`endRun`, waitpoint timeout,
1657
+ * etc.).
1658
+ */
1659
+ phase: "continuation";
1660
+ /** Task run context. */
1661
+ ctx: TaskRunContext;
1662
+ /** The chat session ID. */
1663
+ chatId: string;
1664
+ /** The Trigger.dev run ID. */
1665
+ runId: string;
1666
+ /** Custom data from the frontend. */
1667
+ clientData?: TClientData;
1668
+ } | {
1669
+ /** Next message arrived after turn suspension. */
1670
+ phase: "turn";
1671
+ /** Task run context. */
1672
+ ctx: TaskRunContext;
1673
+ /** The chat session ID. */
1674
+ chatId: string;
1675
+ /** The Trigger.dev run ID. */
1676
+ runId: string;
1677
+ /** The turn number that was completed before suspension. */
1678
+ turn: number;
1679
+ /** The accumulated model messages (from before suspension). */
1680
+ messages: ModelMessage[];
1681
+ /** The accumulated UI messages (from before suspension). */
1682
+ uiMessages: TUIM[];
1683
+ /** Custom data from the frontend. */
1684
+ clientData?: TClientData;
1685
+ };
1686
+ export type ChannelMessageInput = string | UIMessage;
1687
+ /**
1688
+ * What a connector's `inbound()` returns: the turn's message, optionally with who sent it on
1689
+ * the provider and the provider's own message id. Both land on the user message's `metadata`
1690
+ * (with `source: "channel"`, the connector id, the provider and the delivery id), so a
1691
+ * transcript storage can attribute and reconcile channel messages.
1692
+ */
1693
+ export type ChannelInbound = ChannelMessageInput | {
1694
+ message: ChannelMessageInput;
1695
+ externalUserId?: string;
1696
+ externalMessageId?: string;
1697
+ };
1698
+ /** The `metadata` the runtime stamps on a channel-delivered user message. */
1699
+ export type ChannelMessageMetadata = {
1700
+ source: "channel";
1701
+ connectorId: string;
1702
+ provider: string;
1703
+ /** The delivery that carried the message (`whd_...`). */
1704
+ deliveryId: string;
1705
+ /** The provider's id for that delivery, the same across replays. */
1706
+ externalDeliveryId?: string;
1707
+ externalUserId?: string;
1708
+ externalMessageId?: string;
1709
+ /** True on a message the connector supplied from the surface's existing conversation via `seed()`. */
1710
+ seeded?: boolean;
1711
+ };
1712
+ /**
1713
+ * A prior message from the surface, returned by a connector's `seed()` when a session starts on a
1714
+ * conversation that already has history (a Slack thread the bot was summoned into). Becomes a
1715
+ * transcript message ahead of the triggering one, so the agent can answer with the context a human
1716
+ * reading the thread would have.
1717
+ */
1718
+ export type ChannelSeedMessage = {
1719
+ role: "user" | "assistant";
1720
+ text: string;
1721
+ /** The provider's id for the message; used as the transcript message id suffix and kept in metadata. */
1722
+ externalMessageId?: string;
1723
+ externalUserId?: string;
1724
+ };
1725
+ export type ChannelSeedCtx<TEvent = unknown> = {
1726
+ event: TEvent;
1727
+ deliveryId: string;
1728
+ };
1729
+ /** A file a connector fetched for the model: its bytes, and the media type when the surface reports one. */
1730
+ export type ChannelDownloadedFile = {
1731
+ data: Uint8Array;
1732
+ mediaType?: string;
1733
+ };
1734
+ /**
1735
+ * The channel a session answers into, once a channel turn has bound it. The connector's
1736
+ * `bind()` derives the handle from a verified event; later turns that did not start from a
1737
+ * channel delivery (a `chat.event` action that returns `chat.turn()`, a browser message on the
1738
+ * same session) egress through it.
1739
+ */
1740
+ export type ChannelBinding<THandle = unknown> = TranscriptChannelBinding<THandle>;
1741
+ export type ChannelMessage = {
1742
+ text: string;
1743
+ [key: string]: unknown;
1744
+ };
1745
+ export type ChannelReply = {
1746
+ text: string;
1747
+ message: UIMessage;
1748
+ final: boolean;
1749
+ stopped: boolean;
1750
+ error?: unknown;
1751
+ /**
1752
+ * True when the turn paused on a human decision: this text is what the agent wrote before calling
1753
+ * the tool, and the controls follow as their own message. A surface with a notion of "done" (Linear
1754
+ * sessions) should post it as progress rather than as the answer.
1755
+ */
1756
+ pending?: boolean;
1757
+ };
1758
+ export type ChannelSendCtx<TEvent = unknown, THandle = unknown> = {
1759
+ /** The verified event that started this turn. Absent on a bound turn that no channel delivery started. */
1760
+ event?: TEvent;
1761
+ /** The connector's posting handle from `bind()`, when the connector defines one. */
1762
+ handle?: THandle;
1763
+ /** The delivery that started this turn. Absent on a bound turn. */
1764
+ deliveryId?: string;
1765
+ previousRef?: string;
1766
+ mode: "final" | "stream";
1767
+ final: boolean;
1768
+ /** True when this turn was not started by a channel delivery and egresses through the session's binding. */
1769
+ bound: boolean;
1770
+ };
1771
+ export type ChannelAckCtx = {
1772
+ /**
1773
+ * True when this ack is being re-posted because the run is recovering an
1774
+ * interrupted turn after a crash/continuation. The prior run's message ref
1775
+ * is gone, so egress re-emits into the thread as a fresh message; a
1776
+ * connector can vary the placeholder text to read as a deliberate resume
1777
+ * ("picking this back up...") rather than a silent duplicate.
1778
+ */
1779
+ recovered: boolean;
1780
+ };
1781
+ /**
1782
+ * A tool call the turn paused on, awaiting a human decision (HITL). `renderInteraction` maps these to
1783
+ * the controls posted in the thread; the callback resolves one by `toolCallId`.
1784
+ */
1785
+ export type ChannelPendingToolCall = {
1786
+ toolCallId: string;
1787
+ toolName: string;
1788
+ input?: unknown;
1789
+ };
1790
+ /**
1791
+ * A verified interaction callback resolved to a tool output. `onInteraction` returns this to resume the
1792
+ * paused run: the framework stitches `output` onto the pending tool part and continues. Name the call
1793
+ * by `toolCallId` when the surface can carry it (a Slack button value), or by `toolName` when it cannot
1794
+ * (a Linear option whose value the user sees); the most recent pending call of that tool is resolved.
1795
+ */
1796
+ export type ChannelInteractionResolution = {
1797
+ toolCallId: string;
1798
+ toolName?: string;
1799
+ output: unknown;
1800
+ } | {
1801
+ toolName: string;
1802
+ toolCallId?: string;
1803
+ output: unknown;
1804
+ };
1805
+ /**
1806
+ * Context for `renderInteraction`: the event and delivery that started the turn, both absent on a
1807
+ * bound turn (a `chat.turn()` action or a browser message answering into the bound thread).
1808
+ */
1809
+ export type ChannelInteractionCtx<TEvent = unknown> = {
1810
+ event?: TEvent;
1811
+ deliveryId?: string;
1812
+ };
1813
+ export type ChannelReaction = {
1814
+ name: string;
1815
+ remove?: boolean;
1816
+ };
1817
+ export type ChannelReactCtx<TEvent = unknown> = {
1818
+ event: TEvent;
1819
+ deliveryId: string;
1820
+ };
1821
+ export type ChannelReactionChoice<TEvent = unknown> = string | string[] | ((event: TEvent) => string | string[] | null | undefined | Promise<string | string[] | null | undefined>);
1822
+ export type ChannelReactions<TEvent = unknown> = {
1823
+ working?: ChannelReactionChoice<TEvent>;
1824
+ done?: ChannelReactionChoice<TEvent>;
1825
+ error?: ChannelReactionChoice<TEvent>;
1826
+ };
1827
+ export type ChannelRunSurface<TExtra extends Record<string, unknown> = Record<string, unknown>> = {
1828
+ react: (name: string) => Promise<void>;
1829
+ unreact: (name: string) => Promise<void>;
1830
+ } & TExtra;
1831
+ /**
1832
+ * The turn a connector hook is running in: the verified event and delivery that started it (absent on
1833
+ * a bound turn), and the session's posting handle from `bind()` when the connector defines one.
1834
+ */
1835
+ export type ChannelTurnCtx<TEvent = unknown, THandle = unknown> = {
1836
+ event?: TEvent;
1837
+ handle?: THandle;
1838
+ deliveryId?: string;
1839
+ /** True when no channel delivery started this turn and it egresses through the session's binding. */
1840
+ bound: boolean;
1841
+ };
1842
+ /**
1843
+ * What a connector's `onControl()` maps a verified event to. `stop` aborts the turn in flight through
1844
+ * the same per-turn stop signal the browser's stop button uses: the run's `stopSignal` fires,
1845
+ * `streamText` aborts, the partial reply posts with `stopped: true`, and the event itself is consumed
1846
+ * (it does not run as a turn).
1847
+ *
1848
+ * `whenIdle` decides what a stop does when no turn is in flight. `"message"` (the default) handles
1849
+ * the event as a normal inbound message, so the connector's `inbound()` should give it a sensible
1850
+ * reading. `"drop"` consumes it without a turn; if the session is paused on a human decision, the
1851
+ * pending tool calls are resolved as stopped (a later approval click finds nothing to resume) and
1852
+ * the connector's `cancelInteraction()` updates the controls.
1853
+ *
1854
+ * `at` is when the user asked to stop (epoch milliseconds). A stop older than the running turn's
1855
+ * start belongs to an earlier turn: it is consumed without aborting this one.
1856
+ */
1857
+ export type ChannelControl = {
1858
+ kind: "stop";
1859
+ message?: string;
1860
+ whenIdle?: "message" | "drop";
1861
+ at?: number;
1862
+ };
1863
+ /**
1864
+ * What a connector's `progress()` hook observes while a turn streams: each tool call as its input is
1865
+ * complete, and each result or error as it lands. Text deltas are not reported (use `delivery: "stream"`).
1866
+ * `title` is the tool's display title (`tool({ title })`), when it declares one.
1867
+ */
1868
+ export type ChannelProgressEvent = {
1869
+ type: "tool-call";
1870
+ toolCallId: string;
1871
+ toolName: string;
1872
+ title?: string;
1873
+ input: unknown;
1874
+ } | {
1875
+ type: "tool-result";
1876
+ toolCallId: string;
1877
+ toolName: string;
1878
+ title?: string;
1879
+ output: unknown;
1880
+ } | {
1881
+ type: "tool-error";
1882
+ toolCallId: string;
1883
+ toolName: string;
1884
+ title?: string;
1885
+ errorText: string;
1886
+ };
1887
+ /**
1888
+ * Where a channel session stands, reported to a connector's `lifecycle()` hook: `working` when a turn
1889
+ * starts (and again every 50 minutes while it runs), `waiting` when it pauses on a human decision,
1890
+ * `idle` when it ends for any reason (answered, empty, stopped or failed), and `closed` when the
1891
+ * conversation is closed with `chat.close()`. A worker suspending between messages reports nothing.
1892
+ */
1893
+ export type ChannelLifecycleState = "working" | "waiting" | "idle" | "closed";
1894
+ export type ChannelLifecycleCtx<TEvent = unknown, THandle = unknown> = ChannelTurnCtx<TEvent, THandle> & {
1895
+ /** True on the session's first turn, when the surface creates its conversation. */
1896
+ firstTurn: boolean;
1897
+ /** The turn's user message text, when it has one (a title for the conversation). */
1898
+ prompt?: string;
1899
+ /** True on the periodic `working` re-send during a long turn. */
1900
+ refresh?: boolean;
1901
+ };
1902
+ /** How a turn's reply stream ended, handed to {@link ChannelReplyStream.end}. */
1903
+ export type ChannelReplyStreamEnd = {
1904
+ /** The turn was stopped (the partial reply is all there is). */
1905
+ stopped: boolean;
1906
+ /** The turn paused on a human decision; the controls follow as their own message. */
1907
+ pending: boolean;
1908
+ /** The connector's error line (`errorMessage`) when the turn ended on a model or stream error. */
1909
+ errorText?: string;
1910
+ };
1911
+ /**
1912
+ * A connector's native streaming transport for one turn, from its `stream()` hook, used when the
1913
+ * connector's `delivery` is `"stream"`. The runtime feeds it the reply's text deltas as the model
1914
+ * writes them (in the model's markdown) and the turn's tool progress, then ends it exactly once.
1915
+ * `end()` resolves `delivered: true` when the reply reached the surface through the stream, so the
1916
+ * runtime does not post it again; `false` (nothing was streamed) falls back to `send()`.
1917
+ */
1918
+ export type ChannelReplyStream = {
1919
+ text(delta: string): void;
1920
+ progress?(event: ChannelProgressEvent): void;
1921
+ end(outcome: ChannelReplyStreamEnd): Promise<{
1922
+ delivered: boolean;
1923
+ }>;
1924
+ };
1925
+ /**
1926
+ * What a connector's `stream()` hook receives: the turn, and `opened(ref)` to call once the surface
1927
+ * has created the stream message. The ref is saved with the session while the turn runs, so if the
1928
+ * worker dies mid-stream the next worker can end that stream with `endInterruptedStream()`.
1929
+ */
1930
+ export type ChannelStreamCtx<TEvent = unknown, THandle = unknown> = ChannelTurnCtx<TEvent, THandle> & {
1931
+ opened(ref: string): void;
1932
+ };
1933
+ /** A pending tool call a stop cancelled, with the `ref` of the controls message that showed it. */
1934
+ export type ChannelCancelledToolCall = ChannelPendingToolCall & {
1935
+ ref?: string;
1936
+ };
1937
+ export type ResolveChannelToken<TEvent = unknown> = (event: TEvent) => Promise<string>;
1938
+ declare const channelEventPhantom: unique symbol;
1939
+ export interface ChannelConnector<TEvent = unknown, THandle = unknown> {
1940
+ id: string;
1941
+ /** The endpoint this connector subscribes to (`webhooks.endpoint.define` id). */
1942
+ endpointId: string;
1943
+ source: string;
1944
+ key: string;
1945
+ filter?: string;
1946
+ startOn?: string;
1947
+ inbound: (event: TEvent) => ChannelInbound;
1948
+ /**
1949
+ * Derive the durable posting handle from a verified event (for Slack: team, channel, thread). When
1950
+ * set, a channel turn binds the session to this connector, and later turns on the session that no
1951
+ * channel delivery started (an action turn, a browser message) post their answer through `send`
1952
+ * with `ctx.handle` and no `ctx.event`. Return null to leave the binding unchanged.
1953
+ */
1954
+ bind?: (event: TEvent) => THandle | null;
1955
+ /**
1956
+ * Supply the surface's existing conversation when a session starts on it (the bot was summoned
1957
+ * into a thread that already has messages). Called once, on the first channel turn of a session
1958
+ * with no history, before the triggering message is added. Return the prior messages in order,
1959
+ * excluding the triggering one. Best effort: a throw is logged and the session starts empty.
1960
+ */
1961
+ seed?: (event: TEvent, ctx: ChannelSeedCtx<TEvent>) => Promise<ChannelSeedMessage[]> | ChannelSeedMessage[];
1962
+ outbound?: (reply: ChannelReply) => ChannelMessage | null;
1963
+ ack?: (event: TEvent, ctx: ChannelAckCtx) => ChannelMessage | null;
1964
+ send?: (message: ChannelMessage, ctx: ChannelSendCtx<TEvent, THandle>) => Promise<{
1965
+ ref?: string;
1966
+ }>;
1967
+ /** HITL: controls posted when a turn pauses on a human-decision tool (a tool with no `execute`). */
1968
+ renderInteraction?: (pending: ChannelPendingToolCall[], ctx: ChannelInteractionCtx<TEvent>) => ChannelMessage | null;
1969
+ /**
1970
+ * HITL: map a verified callback event to a tool resolution. Non-null resumes the paused run; null
1971
+ * means treat the event as a normal inbound message (a new turn).
1972
+ */
1973
+ onInteraction?: (event: TEvent) => ChannelInteractionResolution | null;
1974
+ /**
1975
+ * HITL: finalize the posted controls once a decision is made (edit them away, show the outcome), so
1976
+ * the buttons can't be clicked again. Called with the same verified callback event when
1977
+ * `onInteraction` resolves, before the run resumes. Best-effort: a throw is logged and the run continues.
1978
+ */
1979
+ finalizeInteraction?: (event: TEvent, resolution: ChannelInteractionResolution) => Promise<void> | void;
1980
+ /**
1981
+ * "final": the ack, then one post (or edit of the ack) when the turn ends. "stream": the connector's
1982
+ * `stream()` transport when it has one, otherwise debounced edits of the ack.
1983
+ */
1984
+ delivery: "final" | "stream";
1985
+ /**
1986
+ * Native streaming for `delivery: "stream"`: open a {@link ChannelReplyStream} for this turn. Called
1987
+ * once per turn that runs the model; return null to fall back to `send()` for this turn.
1988
+ */
1989
+ stream?: (ctx: ChannelStreamCtx<TEvent, THandle>) => ChannelReplyStream | null;
1990
+ /**
1991
+ * A worker booted on a session whose previous worker died with a reply stream open (the `ref` it
1992
+ * passed to `opened()`). End that stream so it does not look like the agent is still writing; the
1993
+ * recovered turn answers in a new one. Best effort: a throw is logged.
1994
+ */
1995
+ endInterruptedStream?: (ref: string, ctx: ChannelTurnCtx<TEvent, THandle>) => Promise<void> | void;
1996
+ /**
1997
+ * Fetch a file URL from the surface for the model, for files only the surface's credentials can
1998
+ * read (a Slack `url_private`). The `streamText` given to `run()` calls it for every file URL in
1999
+ * the prompt; return null for a URL this connector does not own. Throw when an owned file cannot
2000
+ * be read: the turn replaces it with a short note and still runs. `handle` is the session's
2001
+ * binding to this connector, when it has one.
2002
+ */
2003
+ download?: (url: URL, ctx: {
2004
+ handle?: THandle;
2005
+ }) => Promise<ChannelDownloadedFile | null>;
2006
+ /**
2007
+ * Acknowledge a message that arrives while a turn is running, as soon as it arrives: it is either
2008
+ * folded into the running turn (`pendingMessages`) or answered right after it, so the wording
2009
+ * should be true either way (`slack()` reacts with 👀, `linear()` posts a thought). Not called for
2010
+ * stops, interaction clicks or empty messages. Called without waiting; a throw is ignored.
2011
+ * `ctx.event` is the message's event.
2012
+ */
2013
+ received?: (ctx: ChannelTurnCtx<TEvent, THandle>) => Promise<void> | void;
2014
+ /**
2015
+ * Map a click on a control the agent posted (not a pending tool's control) to an action for the
2016
+ * agent's `onAction`, validated against `actionSchema` like a client action. Return null for
2017
+ * anything else. Returning `chat.turn()` from `onAction` answers into the session's thread.
2018
+ */
2019
+ toAction?: (event: TEvent) => unknown | null;
2020
+ /**
2021
+ * Mirror the session's state into the surface (a Slack agent session's status). See
2022
+ * {@link ChannelLifecycleState}. Calls are serialized in order; a throw is logged and never
2023
+ * affects the turn.
2024
+ */
2025
+ lifecycle?: (state: ChannelLifecycleState, ctx: ChannelLifecycleCtx<TEvent, THandle>) => Promise<void> | void;
2026
+ /**
2027
+ * HITL: a stop (`whenIdle: "drop"`) arrived while the session was paused on these tool calls. They
2028
+ * are already resolved as stopped; update the controls so they no longer offer a decision.
2029
+ * Best effort: a throw is logged.
2030
+ */
2031
+ cancelInteraction?: (cancelled: ChannelCancelledToolCall[], ctx: ChannelTurnCtx<TEvent, THandle>) => Promise<void> | void;
2032
+ react?: (reaction: ChannelReaction, ctx: ChannelReactCtx<TEvent>) => Promise<void>;
2033
+ reactions?: ChannelReactions<TEvent>;
2034
+ /**
2035
+ * What the channel shows when a turn fails, in place of the error text: a fixed line, or a
2036
+ * function of the failure that returns one. Defaults to {@link CHANNEL_TURN_ERROR_MESSAGE}. The
2037
+ * error itself is logged on the run, and `outbound()` still receives it as `reply.error`.
2038
+ */
2039
+ errorMessage?: ChannelErrorMessage<TEvent>;
2040
+ /**
2041
+ * Observe tool calls and results as the turn streams, to post progress into the surface (a Linear
2042
+ * `action` activity, a Slack status). Called in order, awaited one at a time, independent of
2043
+ * `delivery`. Best effort: a throw is logged and the turn continues.
2044
+ */
2045
+ progress?: (event: ChannelProgressEvent, ctx: ChannelTurnCtx<TEvent, THandle>) => Promise<void> | void;
2046
+ /**
2047
+ * Provider helpers merged into the `channel` object handed to `run()` (alongside `react`/`unreact`),
2048
+ * such as a plan or a status setter. Built once per turn.
2049
+ */
2050
+ surface?: (ctx: ChannelTurnCtx<TEvent, THandle>) => Record<string, unknown>;
2051
+ /**
2052
+ * Map a verified event to a control instruction while a turn is running (a Stop in Linear, a
2053
+ * "stop" slash command in Slack). See {@link ChannelControl}. Return null for an ordinary message.
2054
+ */
2055
+ onControl?: (event: TEvent) => ChannelControl | null;
2056
+ readonly [channelEventPhantom]?: TEvent;
2057
+ }
2058
+ export type AnyChannelConnector = ChannelConnector<any, any>;
2059
+ /** The line a channel shows when a turn fails, unless the connector sets its own `errorMessage`. */
2060
+ export declare const CHANNEL_TURN_ERROR_MESSAGE = "Something went wrong answering this. Try again.";
2061
+ /** What an `errorMessage` function receives when a channel turn fails. */
2062
+ export type ChannelErrorContext<TEvent = unknown> = {
2063
+ /** The failure: the model or stream error, or what the turn threw. */
2064
+ error: Error;
2065
+ /** The text the turn streamed before it failed; empty when it failed before answering. */
2066
+ partialText: string;
2067
+ /** The event that started the turn; undefined on a turn the channel did not start (an action turn, a browser message). */
2068
+ event: TEvent | undefined;
2069
+ /** The run the turn failed in, for a support reference. */
2070
+ runId: string | undefined;
2071
+ /** The session's chat id. */
2072
+ chatId: string;
2073
+ /** {@link CHANNEL_TURN_ERROR_MESSAGE}, to extend rather than replace. */
2074
+ defaultMessage: string;
2075
+ };
2076
+ /**
2077
+ * A channel's error line: a fixed string, or a function of the failure. A function that returns
2078
+ * nothing, or throws, falls back to {@link CHANNEL_TURN_ERROR_MESSAGE}.
2079
+ *
2080
+ * @example
2081
+ * ```ts
2082
+ * errorMessage: ({ error, runId }) =>
2083
+ * error.name === "RateLimitError" ? "I'm a bit busy, try again in a minute." : `That failed (ref ${runId}).`,
2084
+ * ```
2085
+ */
2086
+ export type ChannelErrorMessage<TEvent = unknown> = string | ((ctx: ChannelErrorContext<TEvent>) => string | null | undefined | Promise<string | null | undefined>);
2087
+ /**
2088
+ * A generic chat-frontend channel over any verified source. Unlike `slack()`, you supply the egress
2089
+ * `send` yourself (post/edit the reply back to your surface), so the whole round-trip is under your
2090
+ * control. Use for providers without a preset, or to test the channel round-trip end to end.
2091
+ */
2092
+ export declare function chatChannelCustom<TEndpoint extends AnyWebhookEndpoint, const TKey extends string = string, const TFilter extends string = string, const TStartOn extends string = string, THandle = unknown>(options: {
2093
+ id: string;
2094
+ /** The endpoint this connector subscribes to. */
2095
+ endpoint: TEndpoint;
2096
+ /**
2097
+ * The session each delivery goes to, as a template: `{event.x}` reads the event, `{header.x}` a
2098
+ * header and `{webhook.x}` the endpoint, and `{a || b}` falls back to `b` when `a` is empty. e.g.
2099
+ * `"{webhook.externalRef}:{event.data.object.customer}"`.
2100
+ */
2101
+ key: ValidatedWebhookKey<NarrowWebhookEvent<InferWebhookEndpointEvent<TEndpoint>, TFilter>, TKey>;
2102
+ inbound: (event: NarrowWebhookEvent<InferWebhookEndpointEvent<TEndpoint>, TFilter>) => ChannelInbound;
2103
+ bind?: (event: NarrowWebhookEvent<InferWebhookEndpointEvent<TEndpoint>, TFilter>) => THandle | null;
2104
+ seed?: (event: NarrowWebhookEvent<InferWebhookEndpointEvent<TEndpoint>, TFilter>, ctx: ChannelSeedCtx<NarrowWebhookEvent<InferWebhookEndpointEvent<TEndpoint>, TFilter>>) => Promise<ChannelSeedMessage[]> | ChannelSeedMessage[];
2105
+ outbound?: (reply: ChannelReply) => ChannelMessage | null;
2106
+ ack?: (event: NarrowWebhookEvent<InferWebhookEndpointEvent<TEndpoint>, TFilter>, ctx: ChannelAckCtx) => ChannelMessage | null;
2107
+ send?: (message: ChannelMessage, ctx: ChannelSendCtx<NarrowWebhookEvent<InferWebhookEndpointEvent<TEndpoint>, TFilter>, THandle>) => Promise<{
2108
+ ref?: string;
2109
+ }>;
2110
+ renderInteraction?: (pending: ChannelPendingToolCall[], ctx: ChannelInteractionCtx<NarrowWebhookEvent<InferWebhookEndpointEvent<TEndpoint>, TFilter>>) => ChannelMessage | null;
2111
+ onInteraction?: (event: NarrowWebhookEvent<InferWebhookEndpointEvent<TEndpoint>, TFilter>) => ChannelInteractionResolution | null;
2112
+ finalizeInteraction?: (event: NarrowWebhookEvent<InferWebhookEndpointEvent<TEndpoint>, TFilter>, resolution: ChannelInteractionResolution) => Promise<void> | void;
2113
+ react?: (reaction: ChannelReaction, ctx: ChannelReactCtx<NarrowWebhookEvent<InferWebhookEndpointEvent<TEndpoint>, TFilter>>) => Promise<void>;
2114
+ reactions?: ChannelReactions<NarrowWebhookEvent<InferWebhookEndpointEvent<TEndpoint>, TFilter>>;
2115
+ progress?: (event: ChannelProgressEvent, ctx: ChannelTurnCtx<NarrowWebhookEvent<InferWebhookEndpointEvent<TEndpoint>, TFilter>, THandle>) => Promise<void> | void;
2116
+ surface?: (ctx: ChannelTurnCtx<NarrowWebhookEvent<InferWebhookEndpointEvent<TEndpoint>, TFilter>, THandle>) => Record<string, unknown>;
2117
+ onControl?: (event: NarrowWebhookEvent<InferWebhookEndpointEvent<TEndpoint>, TFilter>) => ChannelControl | null;
2118
+ stream?: (ctx: ChannelStreamCtx<NarrowWebhookEvent<InferWebhookEndpointEvent<TEndpoint>, TFilter>, THandle>) => ChannelReplyStream | null;
2119
+ endInterruptedStream?: (ref: string, ctx: ChannelTurnCtx<NarrowWebhookEvent<InferWebhookEndpointEvent<TEndpoint>, TFilter>, THandle>) => Promise<void> | void;
2120
+ download?: (url: URL, ctx: {
2121
+ handle?: THandle;
2122
+ }) => Promise<ChannelDownloadedFile | null>;
2123
+ received?: (ctx: ChannelTurnCtx<InferWebhookEndpointEvent<TEndpoint>, THandle>) => Promise<void> | void;
2124
+ toAction?: (event: InferWebhookEndpointEvent<TEndpoint>) => unknown | null;
2125
+ lifecycle?: (state: ChannelLifecycleState, ctx: ChannelLifecycleCtx<NarrowWebhookEvent<InferWebhookEndpointEvent<TEndpoint>, TFilter>, THandle>) => Promise<void> | void;
2126
+ cancelInteraction?: (cancelled: ChannelCancelledToolCall[], ctx: ChannelTurnCtx<NarrowWebhookEvent<InferWebhookEndpointEvent<TEndpoint>, TFilter>, THandle>) => Promise<void> | void;
2127
+ filter?: ValidateWebhookFilter<InferWebhookEndpointEvent<TEndpoint>, TFilter>;
2128
+ startOn?: ValidateWebhookFilter<InferWebhookEndpointEvent<TEndpoint>, TStartOn>;
2129
+ delivery?: "final" | "stream";
2130
+ /** What the channel shows when a turn fails: a line, or a function of the failure. Defaults to {@link CHANNEL_TURN_ERROR_MESSAGE}. */
2131
+ errorMessage?: ChannelErrorMessage<NarrowWebhookEvent<InferWebhookEndpointEvent<TEndpoint>, TFilter>>;
2132
+ }): ChannelConnector<NarrowWebhookEvent<InferWebhookEndpointEvent<TEndpoint>, TFilter>, THandle>;
2133
+ export declare function resolveReactionChoice(choice: ChannelReactionChoice | undefined, event: unknown): Promise<string | undefined>;
2134
+ /**
2135
+ * Feed a connector's `progress()` from the UI message stream: a tool call once its input is available,
2136
+ * then its result or error. Calls are serialized so the surface sees them in order; a throw is logged.
2137
+ * `stop()` refuses further chunks and drains what is already queued, so a slow first post does not
2138
+ * lose the results behind it, and nothing new lands after the turn ended.
2139
+ */
2140
+ declare function makeChannelProgressObserver(connector: AnyChannelConnector, wireEvent: {
2141
+ event: unknown;
2142
+ deliveryId: string;
2143
+ } | undefined, handle: unknown): ChannelStreamEditor;
2144
+ /**
2145
+ * Report a session's lifecycle to its connector in order, one call at a time, and re-send `working`
2146
+ * while a long turn runs. Every report bumps a sequence number and a refresh only fires while its
2147
+ * `working` is still the latest report, so a refresh can never land after the turn went idle.
2148
+ */
2149
+ declare function makeChannelLifecycleReporter(): {
2150
+ report(connector: AnyChannelConnector | undefined, state: ChannelLifecycleState, ctx: ChannelLifecycleCtx): Promise<void>;
2151
+ dispose: () => void;
2152
+ };
2153
+ declare function makeChannelStreamEditor<TEvent>(connector: ChannelConnector<TEvent>, channelEvent: {
2154
+ event: unknown;
2155
+ deliveryId: string;
2156
+ }, ackRef: string, handle?: unknown): {
2157
+ observe(chunk: unknown): void;
2158
+ stop(): Promise<void>;
2159
+ };
2160
+ type ChannelStreamEditor = {
2161
+ observe(chunk: unknown): void;
2162
+ stop(): void | Promise<void>;
2163
+ };
2164
+ /**
2165
+ * Wrap the reply stream so it debounce-edits the channel message as it streams.
2166
+ * Both `flush` (the stream completed) and `cancel` (the stream was aborted or
2167
+ * cancelled downstream) stop the editor, so a pending debounce timer can never
2168
+ * fire an edit after the turn ended, onto a message the next turn already owns.
2169
+ */
2170
+ /**
2171
+ * Feed every chunk of a stream to `editor`. By default the editor is stopped when the stream ends or
2172
+ * is cancelled (one stream per turn, the automatic pipe). With `stopOnEnd: false` the editor outlives
2173
+ * the stream, for a turn whose run() pipes several streams through `chat.pipe()`; the turn boundary
2174
+ * stops it.
2175
+ */
2176
+ declare function makeChannelStreamTap(editor: ChannelStreamEditor, options?: {
2177
+ stopOnEnd?: boolean;
2178
+ }): TransformStream<unknown, unknown>;
2179
+ export { makeChannelStreamEditor as __makeChannelStreamEditorForTests, makeChannelStreamTap as __makeChannelStreamTapForTests, makeChannelProgressObserver as __makeChannelProgressObserverForTests, makeChannelLifecycleReporter as __makeChannelLifecycleReporterForTests, };
2180
+ /** Resolves once the post-turn channel egress for `chatId` has finished (immediately when none is running). */
2181
+ export declare function __waitForChannelEgressForTests(chatId: string): Promise<void>;
2182
+ type ChatActionType<TActionSchema extends TaskSchema | undefined, TW extends readonly AnyChatEvent[]> = [TActionSchema] extends [TaskSchema] ? inferSchemaOut<TActionSchema> | ChatEventActions<TW> : [TW] extends [readonly []] ? unknown : ChatEventActions<TW>;
2183
+ export type ChatAgentOptions<TIdentifier extends string, TClientDataSchema extends TaskSchema | undefined = undefined, TUIMessage extends UIMessage = UIMessage, TActionSchema extends TaskSchema | undefined = undefined, TTools extends ToolSet = ToolSet, TW extends readonly AnyChatEvent[] = [], TChannels extends readonly AnyChannelConnector[] = []> = Omit<TaskOptions<TIdentifier, ChatTaskWirePayload<TUIMessage, inferSchemaIn<TClientDataSchema>>, unknown>, "run" | "retry"> & {
2184
+ /**
2185
+ * Fallback machine preset to use when an attempt fails with an
2186
+ * out-of-memory (OOM) error. Setting this enables a single OOM retry:
2187
+ * the next attempt boots on the larger machine, and the chat picks
2188
+ * up via the standard continuation path (same `chatId` / Session,
2189
+ * accumulator rebuilds via `hydrateMessages` or post-`onTurnStart`
2190
+ * persisted state).
2191
+ *
2192
+ * Set `machine` (top-level `TaskOptions`) to control the *default*
2193
+ * machine the agent runs on. `oomMachine` is the *retry-only* swap.
2194
+ *
2195
+ * Note: an OOM retry restarts the entire turn from the top — the
2196
+ * model call and any in-flight tool executes re-run on the larger
2197
+ * machine. Make tool executes idempotent or persist results before
2198
+ * returning if you can't tolerate re-execution.
2199
+ *
2200
+ * Generic `retry` options are not exposed on `chat.agent` because
2201
+ * arbitrary retries against an LLM-driven loop tend to be expensive
2202
+ * and side-effecting. If you need richer retry semantics, drop down
2203
+ * to `chat.task` (the raw primitive).
2204
+ *
2205
+ * @example
2206
+ * ```ts
2207
+ * chat.agent({
2208
+ * id: "my-chat",
2209
+ * machine: "small-1x",
2210
+ * oomMachine: "medium-2x",
2211
+ * run: async ({ messages, signal }) =>
2212
+ * streamText({ model, messages, abortSignal: signal }),
2213
+ * });
2214
+ * ```
2215
+ */
2216
+ oomMachine?: MachinePresetName;
2217
+ /**
2218
+ * What to do when the session's `externalDeploymentId` no longer names the deployment
2219
+ * this run is on — after a redeploy re-pins the session, say.
2220
+ *
2221
+ * - `"follow"` (default) hands the conversation to the pinned deployment at the next
2222
+ * turn boundary, so no `chat.requestUpgrade()` of your own is needed.
2223
+ * - `"hold"` stays put until you ask to move. Manual `chat.requestUpgrade()` works either way.
2224
+ *
2225
+ * Ignored for sessions with no pin, and for sessions using `lockToVersion`.
2226
+ */
2227
+ versionSkew?: ChatVersionSkewPolicy;
2228
+ /**
2229
+ * Controls which chat content the chat runtime records on its spans in the run trace.
2230
+ *
2231
+ * - `recordUserMessage` (default `true`) records the last user message as `chat.user_message`
2232
+ * and as the turn span's preview text, and messages sent mid-turn as `pending.messages`.
2233
+ * - `recordClientData` (default `true`) records the raw `clientData` sent by the frontend as
2234
+ * `chat.client_data`.
2235
+ *
2236
+ * Set either to `false` to keep that content out of telemetry. Content recorded by the AI SDK's
2237
+ * own spans is controlled separately, through `experimental_telemetry` on the model call.
2238
+ *
2239
+ * @example
2240
+ * ```ts
2241
+ * chat.agent({
2242
+ * id: "my-chat",
2243
+ * telemetry: { recordUserMessage: false, recordClientData: false },
2244
+ * run: async ({ messages, signal, streamText }) =>
2245
+ * streamText({ model, messages, abortSignal: signal }),
2246
+ * });
2247
+ * ```
2248
+ */
2249
+ telemetry?: {
2250
+ recordUserMessage?: boolean;
2251
+ recordClientData?: boolean;
2252
+ };
2253
+ /**
2254
+ * Schema for validating `clientData` from the frontend.
2255
+ * Accepts Zod, ArkType, Valibot, or any supported schema library.
2256
+ * When provided, `clientData` is parsed and typed in all hooks and `run`.
2257
+ *
2258
+ * @example
2259
+ * ```ts
2260
+ * import { z } from "zod";
2261
+ *
2262
+ * chat.agent({
2263
+ * id: "my-chat",
2264
+ * clientDataSchema: z.object({ model: z.string().optional(), userId: z.string() }),
2265
+ * run: async ({ messages, clientData, ctx, signal }) => {
2266
+ * // clientData is typed as { model?: string; userId: string }
2267
+ * // ctx is the same TaskRunContext as in task({ run: (payload, { ctx }) => ... })
2268
+ * },
2269
+ * });
2270
+ * ```
2271
+ */
2272
+ clientDataSchema?: TClientDataSchema;
2273
+ /**
2274
+ * Schema for validating custom actions sent via `transport.sendAction()`.
2275
+ *
2276
+ * When the frontend sends `trigger: "action"`, the `action` payload is
2277
+ * parsed against this schema before reaching `onAction`. Invalid actions
2278
+ * throw and abort the turn.
2279
+ *
2280
+ * @example
2281
+ * ```ts
2282
+ * import { z } from "zod";
2283
+ *
2284
+ * chat.agent({
2285
+ * id: "my-chat",
2286
+ * actionSchema: z.discriminatedUnion("type", [
2287
+ * z.object({ type: z.literal("undo") }),
2288
+ * z.object({ type: z.literal("rollback"), targetMessageId: z.string() }),
2289
+ * ]),
2290
+ * onAction: async ({ action }) => {
2291
+ * if (action.type === "undo") chat.history.slice(0, -2);
2292
+ * if (action.type === "rollback") chat.history.rollbackTo(action.targetMessageId);
2293
+ * },
2294
+ * run: async ({ messages, signal }) => { ... },
2295
+ * });
2296
+ * ```
2297
+ */
2298
+ actionSchema?: TActionSchema;
2299
+ /**
2300
+ * Called when the frontend sends a custom action via `transport.sendAction()`.
2301
+ *
2302
+ * Actions are not turns. They fire `hydrateMessages` (if configured) and
2303
+ * `onAction` only — no `onTurnStart` / `prepareMessages` /
2304
+ * `onBeforeTurnComplete` / `onTurnComplete`, no `run()`. Use
2305
+ * `chat.history.*` inside `onAction` to mutate state.
2306
+ *
2307
+ * To answer after the edit, return `chat.turn()`: the edit is applied and
2308
+ * snapshotted, then a turn runs on the result with every turn guarantee. An
2309
+ * action that returns nothing is a state edit only. Returning anything else
2310
+ * is an error; a response can no longer be returned directly.
2311
+ */
2312
+ /**
2313
+ * Inbound `chat.event(...)` descriptors this agent handles. Listing one subscribes this agent to the
2314
+ * descriptor's endpoint: each verified delivery goes to the session its `key` names and arrives at
2315
+ * `onAction` as a `{ type, event, source, headers, deliveryId, externalDeliveryId, endpoint }` envelope whose `type` is
2316
+ * the descriptor's `type`. The same descriptor listed on another agent is a second subscriber on the
2317
+ * same endpoint.
2318
+ */
2319
+ events?: TW;
2320
+ /**
2321
+ * Inbound chat frontends (Slack, etc.) via `chat.channels.*`. Listing one subscribes this agent to
2322
+ * the connector's endpoint, routing verified events to a durable per-key session as turns: the
2323
+ * connector's `inbound()` maps the raw event to the turn's message, `run()` fires as normal, and the
2324
+ * reply streams back to the channel. Use the connector's `filter` to ignore events.
2325
+ */
2326
+ channels?: TChannels;
2327
+ onAction?: (event: ActionEvent<ChatActionType<TActionSchema, TW>, inferSchemaOut<TClientDataSchema>, TUIMessage>) => Promise<void | ActionTurn> | void | ActionTurn;
2328
+ /**
2329
+ * The tools available to this agent.
2330
+ *
2331
+ * `chat.agent` doesn't call the model for you. Your tools still go to
2332
+ * `streamText({ tools })` inside `run()`. Declaring them here additionally
2333
+ * lets the SDK re-run each tool's
2334
+ * [`toModelOutput`](https://ai-sdk.dev/docs/ai-sdk-core/tools-and-tool-calling#tomodeloutput)
2335
+ * when it re-converts persisted history on later turns. Without this, the
2336
+ * AI SDK has no `tools` to look up `toModelOutput` against, so a tool's
2337
+ * transformed result (e.g. raw image bytes → an image content part, or a
2338
+ * sub-agent summary) silently degrades to its raw JSON output from turn 2
2339
+ * onward.
2340
+ *
2341
+ * Only `inputSchema` and `toModelOutput` are read during conversion (never
2342
+ * `execute`), so you may pass a lightweight map if you keep heavy execute
2343
+ * deps out of this module.
2344
+ *
2345
+ * Pass either a static `ToolSet` or a function of per-turn context (for
2346
+ * tools that depend on the user, a feature flag, etc.). The resolved set is
2347
+ * available on the `run()` payload as `tools`.
2348
+ *
2349
+ * @example
2350
+ * ```ts
2351
+ * const tools = { read_file, search };
2352
+ * chat.agent({
2353
+ * tools,
2354
+ * run: async ({ messages, tools, signal }) =>
2355
+ * streamText({ model, messages, tools, abortSignal: signal }),
2356
+ * });
2357
+ * ```
2358
+ */
2359
+ tools?: TTools | ((event: ResolveToolsEvent<inferSchemaOut<TClientDataSchema>>) => TTools | Promise<TTools>);
2360
+ /**
2361
+ * The run function for the chat task.
2362
+ *
2363
+ * Receives a `ChatTaskRunPayload` with the conversation messages, chat session ID,
2364
+ * trigger type, task `ctx` (same as `task({ run })`’s second argument), and abort signals
2365
+ * (`signal`, `cancelSignal`, `stopSignal`).
2366
+ *
2367
+ * **Auto-piping:** If this function returns a value with `.toUIMessageStream()`,
2368
+ * the stream is automatically piped to the frontend.
2369
+ */
2370
+ run: (payload: ChatTaskRunPayload<inferSchemaOut<TClientDataSchema>, TTools>) => Promise<unknown>;
2371
+ /**
2372
+ * Called once at the start of every run boot — for the initial run, for
2373
+ * preloaded runs, AND for reactive continuation runs (post-cancel /
2374
+ * crash / `endRun` / `requestUpgrade` / OOM retry).
2375
+ *
2376
+ * Use this for per-process setup that needs to run every time a fresh
2377
+ * worker picks up the chat: initialize `chat.local` state, open
2378
+ * per-process resources, or re-hydrate customer state from your DB
2379
+ * on continuation. Branch on `continuation` to decide whether to load
2380
+ * existing state vs. start fresh.
2381
+ *
2382
+ * Fires BEFORE `onPreload` (preloaded path) and `onChatStart`
2383
+ * (first-message path), so `chat.local` is safe to read in those hooks.
2384
+ *
2385
+ * Does NOT fire when the same run resumes from snapshot via the
2386
+ * idle-window suspend/resume path — use `onChatResume` for that.
2387
+ *
2388
+ * @example
2389
+ * ```ts
2390
+ * onBoot: async ({ chatId, clientData, continuation }) => {
2391
+ * const user = await db.user.findFirst({ where: { id: clientData.userId } });
2392
+ * userContext.init({ name: user.name, plan: user.plan });
2393
+ * if (continuation) {
2394
+ * // re-hydrate any per-chat in-memory state from your DB
2395
+ * }
2396
+ * }
2397
+ * ```
2398
+ */
2399
+ onBoot?: (event: BootEvent<inferSchemaOut<TClientDataSchema>>) => Promise<void> | void;
2400
+ /**
2401
+ * Recovery boot hook — fires once on a continuation run that inherited
2402
+ * in-flight state from a dead predecessor (cancel / crash / OOM /
2403
+ * deploy eviction / `chat.requestUpgrade()`). The runtime reads both
2404
+ * stream tails past the last `turn-complete` cursor and hands the
2405
+ * customer the recovered pieces (settled chain, in-flight users,
2406
+ * partial assistant, pending tool calls) so the chain can be shaped
2407
+ * before the first recovered turn fires.
2408
+ *
2409
+ * Does NOT fire when there's nothing to recover — e.g. a clean
2410
+ * continuation after `chat.endRun()` with no buffered user, a fresh
2411
+ * chat, or an OOM retry on top of a complete snapshot.
2412
+ *
2413
+ * Fires regardless of who owns the model's context; a `hydrateMessages`
2414
+ * hook or a storage `loadContext` receives the recovered tail in
2415
+ * `previousMessages` on the next turn.
2416
+ *
2417
+ * Defaults (returned when the hook is omitted or returns no field):
2418
+ * - With two or more in-flight users, the partial and the user it
2419
+ * was answering are spliced into the chain:
2420
+ * `chain` = `[...settledMessages, inFlightUsers[0], partialAssistant]`
2421
+ * and `recoveredTurns` = `inFlightUsers.slice(1)`.
2422
+ * - Otherwise `chain` = `settledMessages` (drop the orphan partial)
2423
+ * and `recoveredTurns` = `inFlightUsers` (re-dispatch every user)
2424
+ * — so a single interrupted user is answered on the new run.
2425
+ *
2426
+ * @example
2427
+ * ```ts
2428
+ * onRecoveryBoot: async ({ partialAssistant, inFlightUsers, writer, cause }) => {
2429
+ * writer.write({
2430
+ * type: "data-chat-recovery",
2431
+ * id: generateId(),
2432
+ * data: { cause, partial: partialAssistant?.id },
2433
+ * });
2434
+ * return {}; // accept defaults: drop partial, re-dispatch users
2435
+ * }
2436
+ * ```
2437
+ */
2438
+ onRecoveryBoot?: (event: RecoveryBootEvent<TUIMessage>) => Promise<RecoveryBootResult<TUIMessage> | void> | RecoveryBootResult<TUIMessage> | void;
2439
+ /**
2440
+ * Called when a preloaded run starts, before the first message arrives.
2441
+ *
2442
+ * Use this to initialize state, create DB records, and load context early —
2443
+ * so everything is ready when the user's first message comes through.
2444
+ *
2445
+ * @example
2446
+ * ```ts
2447
+ * onPreload: async ({ ctx, chatId, clientData }) => {
2448
+ * await db.chat.create({ data: { id: chatId } });
2449
+ * userContext.init(await loadUser(clientData.userId));
2450
+ * }
2451
+ * ```
2452
+ */
2453
+ onPreload?: (event: PreloadEvent<inferSchemaOut<TClientDataSchema>>) => Promise<void> | void;
2454
+ /**
2455
+ * Called exactly once per chat, on the very first user message of the
2456
+ * chat's lifetime. Does NOT fire on continuation runs (post-`endRun`,
2457
+ * post-waitpoint-timeout, `chat.requestUpgrade`) or on OOM-retry attempts —
2458
+ * those are runs of an already-started chat.
2459
+ *
2460
+ * Use this for one-time chat-setup work — creating the Chat DB row,
2461
+ * initializing per-chat in-memory state, minting resources tied to the
2462
+ * chat's lifetime. Safe to assume no prior history exists here.
2463
+ *
2464
+ * For per-turn work, use `onTurnStart`.
2465
+ *
2466
+ * @example
2467
+ * ```ts
2468
+ * onChatStart: async ({ ctx, chatId, messages, clientData }) => {
2469
+ * await db.chat.create({ data: { id: chatId, userId: clientData.userId } });
2470
+ * }
2471
+ * ```
2472
+ */
2473
+ onChatStart?: (event: ChatStartEvent<inferSchemaOut<TClientDataSchema>>) => Promise<void> | void;
2474
+ /**
2475
+ * Validate or transform incoming UI messages before they are converted to model
2476
+ * messages and accumulated. Fires once per turn with the raw `UIMessage[]` from
2477
+ * the wire payload (after cleanup of aborted tool parts).
2478
+ *
2479
+ * Return the validated messages array. Throw to abort the turn with an error.
2480
+ *
2481
+ * This is the right place to call the AI SDK's `validateUIMessages` on fresh
2482
+ * user input. For HITL continuations (`addToolOutput` /
2483
+ * `addToolApproveResponse`), the wire carries a slim assistant message — only
2484
+ * the resolved tool parts, with `state` + `output` / `errorText` / `approval`
2485
+ * and no `input`. `validateUIMessages` against the AI SDK schema rejects
2486
+ * that shape, so filter to user messages (or skip validation entirely) on
2487
+ * those turns.
2488
+ *
2489
+ * @example
2490
+ * ```ts
2491
+ * import { validateUIMessages } from "ai";
2492
+ *
2493
+ * chat.agent({
2494
+ * id: "my-chat",
2495
+ * onValidateMessages: async ({ messages }) => {
2496
+ * const userMessages = messages.filter((m) => m.role === "user");
2497
+ * if (userMessages.length > 0) {
2498
+ * await validateUIMessages({ messages: userMessages, tools: chatTools });
2499
+ * }
2500
+ * return messages;
2501
+ * },
2502
+ * run: async ({ messages }) => {
2503
+ * return streamText({ model, messages, tools: chatTools });
2504
+ * },
2505
+ * });
2506
+ * ```
2507
+ */
2508
+ onValidateMessages?: (event: ValidateMessagesEvent<TUIMessage>) => TUIMessage[] | Promise<TUIMessage[]>;
2509
+ /**
2510
+ * Load the full message history from your backend on every turn,
2511
+ * replacing the built-in linear accumulator.
2512
+ *
2513
+ * When set, the returned messages become the accumulated state for this turn.
2514
+ * The normal accumulation logic (append for submit, replace for regenerate)
2515
+ * is skipped entirely — the hook is the source of truth.
2516
+ *
2517
+ * After the hook returns, any incoming wire messages with matching IDs are
2518
+ * auto-merged (handles tool approval responses transparently).
2519
+ *
2520
+ * Use cases:
2521
+ * - Backend trust: prevent clients from injecting fabricated history
2522
+ * - Branching conversations (DAGs): load only the active branch
2523
+ * - Rollback/undo: exclude undone messages from history
2524
+ *
2525
+ * @example
2526
+ * ```ts
2527
+ * chat.agent({
2528
+ * id: "my-chat",
2529
+ * hydrateMessages: async ({ chatId, trigger, incomingMessages }) => {
2530
+ * // Persist the new message
2531
+ * const newMsg = incomingMessages[incomingMessages.length - 1];
2532
+ * if (newMsg && trigger === "submit-message") {
2533
+ * await db.chatMessages.create({ chatId, message: newMsg });
2534
+ * }
2535
+ * // Return the full authoritative history
2536
+ * return db.chatMessages.findMany({ where: { chatId } });
2537
+ * },
2538
+ * run: async ({ messages, signal }) => {
2539
+ * return streamText({ model: openai("gpt-4o"), messages, abortSignal: signal });
2540
+ * },
2541
+ * });
2542
+ * ```
2543
+ *
2544
+ * Note: on a channel HITL resume turn (a button click that lands on a fresh
2545
+ * run whose accumulator doesn't yet hold the pending tool call), this hook is
2546
+ * called twice for the one delivery: once with `incomingMessages: []` to load
2547
+ * the chain and locate the pending tool call, then again with the synthesized
2548
+ * resolution message so it can be persisted. Keep the hook's read path
2549
+ * idempotent.
2550
+ */
2551
+ hydrateMessages?: (event: HydrateMessagesEvent<inferSchemaOut<TClientDataSchema>, TUIMessage>) => TUIMessage[] | Promise<TUIMessage[]>;
2552
+ /**
2553
+ * Where the conversation is persisted. The runtime calls `save` after
2554
+ * every turn, failed turn and history-changing action with the changes
2555
+ * since the last save, and `load` once when a new run boots to continue
2556
+ * the conversation.
2557
+ *
2558
+ * Defaults to `defaultStorage`, the platform's snapshot in object storage
2559
+ * that the Sessions dashboard renders. Bring your own to write each change
2560
+ * to your database; `memoryTranscriptStorage()` is the reference
2561
+ * implementation and `runTranscriptStorageTests` from
2562
+ * `@trigger.dev/sdk/ai/test` checks yours against the contract.
2563
+ *
2564
+ * A storage with `loadContext` also owns the model's context on every
2565
+ * turn, which is what `hydrateMessages` did. The two cannot be combined.
2566
+ *
2567
+ * @example
2568
+ * ```ts
2569
+ * chat.agent({
2570
+ * id: "my-chat",
2571
+ * storage: myPostgresTranscriptStorage,
2572
+ * run: async ({ messages, signal, streamText }) =>
2573
+ * streamText({ model, messages, abortSignal: signal }),
2574
+ * });
2575
+ * ```
2576
+ */
2577
+ storage?: TranscriptStorage<inferSchemaOut<TClientDataSchema>>;
2578
+ /**
2579
+ * Called at the start of every turn, after message accumulation and `onChatStart` (turn 0),
2580
+ * but before the `run` function executes.
2581
+ *
2582
+ * Use this to persist messages before streaming begins, so a mid-stream page refresh
2583
+ * still shows the user's message.
2584
+ *
2585
+ * @example
2586
+ * ```ts
2587
+ * onTurnStart: async ({ ctx, chatId, uiMessages }) => {
2588
+ * await db.chat.update({ where: { id: chatId }, data: { messages: uiMessages } });
2589
+ * }
2590
+ * ```
2591
+ */
2592
+ onTurnStart?: (event: TurnStartEvent<inferSchemaOut<TClientDataSchema>, TUIMessage>) => Promise<void> | void;
2593
+ /**
2594
+ * Called after the response is captured but before the stream closes.
2595
+ * The stream is still open, so you can write custom chunks to the frontend
2596
+ * (e.g. compaction progress). Use this for compaction, post-processing,
2597
+ * or any work where the user should see real-time status updates.
2598
+ *
2599
+ * @example
2600
+ * ```ts
2601
+ * onBeforeTurnComplete: async ({ ctx, writer, usage }) => {
2602
+ * if (usage?.inputTokens && usage.inputTokens > 5000) {
2603
+ * writer.write({ type: "data-compaction", id: generateId(), data: { status: "compacting" } });
2604
+ * // ... compact messages ...
2605
+ * chat.setMessages(compactedMessages);
2606
+ * writer.write({ type: "data-compaction", id: generateId(), data: { status: "complete" } });
2607
+ * }
2608
+ * }
2609
+ * ```
2610
+ */
2611
+ onBeforeTurnComplete?: (event: BeforeTurnCompleteEvent<inferSchemaOut<TClientDataSchema>, TUIMessage>) => Promise<void> | void;
2612
+ /**
2613
+ * Called when conversation compaction occurs (via `chat.compact()` or
2614
+ * `chat.compactionStep()`). Use for logging, billing, or persisting the summary.
2615
+ *
2616
+ * @example
2617
+ * ```ts
2618
+ * onCompacted: async ({ ctx, summary, totalTokens, chatId }) => {
2619
+ * logger.info("Compacted", { totalTokens, chatId });
2620
+ * await db.compactionLog.create({ data: { chatId, summary } });
2621
+ * }
2622
+ * ```
2623
+ */
2624
+ onCompacted?: (event: CompactedEvent) => Promise<void> | void;
2625
+ /**
2626
+ * Automatic context compaction. When provided, compaction runs automatically
2627
+ * in both the inner loop (prepareStep, between tool-call steps) and the
2628
+ * outer loop (between turns, for single-step responses where prepareStep
2629
+ * never fires).
2630
+ *
2631
+ * The `shouldCompact` callback decides when to compact, and `summarize`
2632
+ * generates the summary. The prepareStep is auto-injected into
2633
+ * `chat.toStreamTextOptions()` — if you provide your own `prepareStep`
2634
+ * after spreading, it overrides the auto-injected one.
2635
+ *
2636
+ * @example
2637
+ * ```ts
2638
+ * chat.agent({
2639
+ * id: "my-chat",
2640
+ * compaction: {
2641
+ * shouldCompact: ({ totalTokens }) => (totalTokens ?? 0) > 80_000,
2642
+ * summarize: async (messages) =>
2643
+ * generateText({ model, messages: [...messages, { role: "user", content: "Summarize." }] })
2644
+ * .then((r) => r.text),
2645
+ * },
2646
+ * run: async ({ messages, signal }) => {
2647
+ * return streamText({ ...chat.toStreamTextOptions({ registry }), messages });
2648
+ * },
2649
+ * });
2650
+ * ```
2651
+ */
2652
+ /**
2653
+ * A provider registry, so the runtime can resolve the managed prompt's model
2654
+ * for the `streamText` it hands to `run()`. Only needed when you set a model
2655
+ * through `chat.prompt.set()` and want the bound `streamText` to honour it.
2656
+ */
2657
+ registry?: ToStreamTextOptionsOptions["registry"];
2658
+ /**
2659
+ * The agent's system prompt. Injected instructions append to it, and the
2660
+ * `streamText` handed to `run()` carries it without a spread.
2661
+ *
2662
+ * Set it here, at the call site, or through `chat.prompt.set()` for versioned
2663
+ * config, but only in one of them.
2664
+ */
2665
+ system?: ToStreamTextOptionsOptions["system"];
2666
+ /**
2667
+ * Mark the system prompt for provider-side caching, the same sugar
2668
+ * `chat.toStreamTextOptions({ cacheControl })` takes. See
2669
+ * [prompt caching](/ai-chat/prompt-caching).
2670
+ */
2671
+ cacheControl?: ToStreamTextOptionsOptions["cacheControl"];
2672
+ /**
2673
+ * Provider options for the system block, when `cacheControl` is not enough.
2674
+ * Takes precedence over `cacheControl`.
2675
+ */
2676
+ systemProviderOptions?: ToStreamTextOptionsOptions["systemProviderOptions"];
2677
+ compaction?: ChatAgentCompactionOptions<TUIMessage>;
2678
+ /**
2679
+ * Configure how messages that arrive during streaming are handled.
2680
+ *
2681
+ * By default, messages queue for the next turn. When `shouldInject` is provided
2682
+ * and returns `true`, messages are injected between tool-call steps via
2683
+ * `prepareStep` — allowing users to steer the agent mid-execution.
2684
+ *
2685
+ * @example
2686
+ * ```ts
2687
+ * pendingMessages: {
2688
+ * shouldInject: ({ steps }) => steps.length > 0,
2689
+ * onReceived: ({ message }) => logger.info("Steering message received"),
2690
+ * },
2691
+ * ```
2692
+ */
2693
+ pendingMessages?: PendingMessagesOptions<TUIMessage>;
2694
+ /**
2695
+ * Called after each assistant response completes. Use to persist the
2696
+ * conversation to your database after each assistant response.
2697
+ *
2698
+ * @example
2699
+ * ```ts
2700
+ * onTurnComplete: async ({ ctx, chatId, messages }) => {
2701
+ * await db.chat.update({ where: { id: chatId }, data: { messages } });
2702
+ * }
2703
+ * ```
2704
+ */
2705
+ onTurnComplete?: (event: TurnCompleteEvent<inferSchemaOut<TClientDataSchema>, TUIMessage>) => Promise<void> | void;
2706
+ /**
2707
+ * Maximum number of conversational turns (message round-trips) a single run
2708
+ * will handle before ending. After this many turns the run completes
2709
+ * normally and the next message will start a fresh run.
2710
+ *
2711
+ * @default 100
2712
+ */
2713
+ maxTurns?: number;
2714
+ /**
2715
+ * How long to wait for the next message before timing out and ending the run.
2716
+ * Accepts any duration string (e.g. `"1h"`, `"30m"`).
2717
+ *
2718
+ * @default "1h"
2719
+ */
2720
+ turnTimeout?: string;
2721
+ /**
2722
+ * How long (in seconds) the run stays idle (active, using compute) after each
2723
+ * turn, waiting for the next message. During this window responses are instant.
2724
+ * After this timeout the run suspends (frees compute) and waits via
2725
+ * `inputStream.wait()`.
2726
+ *
2727
+ * Set to `0` to suspend immediately after each turn.
2728
+ *
2729
+ * @default 30
2730
+ */
2731
+ idleTimeoutInSeconds?: number;
2732
+ /**
2733
+ * How long the `chatAccessToken` (scoped to this run) remains valid.
2734
+ * A fresh token is minted after each turn, so this only needs to cover
2735
+ * the gap between turns.
2736
+ *
2737
+ * Accepts a duration string (e.g. `"1h"`, `"30m"`, `"2h"`).
2738
+ *
2739
+ * @default "1h"
2740
+ */
2741
+ chatAccessTokenTTL?: string;
2742
+ /**
2743
+ * How long (in seconds) the run stays idle after `onPreload` fires,
2744
+ * waiting for the first message before suspending.
2745
+ *
2746
+ * Only applies to preloaded runs (triggered via `transport.preload()`).
2747
+ * Takes precedence over `transport.preload(..., { idleTimeoutInSeconds })`
2748
+ * and over {@link ChatAgentOptions.idleTimeoutInSeconds}.
2749
+ *
2750
+ * @default Same as `idleTimeoutInSeconds`
2751
+ */
2752
+ preloadIdleTimeoutInSeconds?: number;
2753
+ /**
2754
+ * How long to wait (suspended) for the first message after a preloaded run starts.
2755
+ * If no message arrives within this time, the run ends.
2756
+ *
2757
+ * Only applies to preloaded runs.
2758
+ *
2759
+ * @default Same as `turnTimeout`
2760
+ */
2761
+ preloadTimeout?: string;
2762
+ /**
2763
+ * Transform model messages before they're used anywhere — in `run()`,
2764
+ * in compaction rebuilds, and in compaction results.
2765
+ *
2766
+ * Define once, applied everywhere. Use for Anthropic cache breaks,
2767
+ * injecting system context, stripping PII, etc.
2768
+ *
2769
+ * @example
2770
+ * ```ts
2771
+ * prepareMessages: async ({ messages, reason }) => {
2772
+ * // Add Anthropic cache breaks to the last message
2773
+ * if (messages.length === 0) return messages;
2774
+ * const last = messages[messages.length - 1];
2775
+ * return [...messages.slice(0, -1), {
2776
+ * ...last,
2777
+ * providerOptions: { ...last.providerOptions, anthropic: { cacheControl: { type: "ephemeral" } } },
2778
+ * }];
2779
+ * }
2780
+ * ```
2781
+ */
2782
+ prepareMessages?: (event: PrepareMessagesEvent<inferSchemaOut<TClientDataSchema>>) => ModelMessage[] | Promise<ModelMessage[]>;
2783
+ /**
2784
+ * Default options for `toUIMessageStream()` when auto-piping or using
2785
+ * `turn.complete()` / `chat.pipeAndCapture()`.
2786
+ *
2787
+ * Controls how the `StreamTextResult` is converted to a `UIMessageChunk`
2788
+ * stream — error handling, reasoning/source visibility, metadata, etc.
2789
+ *
2790
+ * Can be overridden per-turn by calling `chat.setUIMessageStreamOptions()`
2791
+ * inside `run()` or lifecycle hooks. Per-turn values are merged on top
2792
+ * of these defaults (per-turn wins on conflicts).
2793
+ *
2794
+ * `onFinish` and `originalMessages` are managed internally and cannot be
2795
+ * overridden here. Use `streamText`'s `onFinish` for custom finish
2796
+ * handling. `generateMessageId` can be set to control response message
2797
+ * ID generation (e.g. UUID-v7).
2798
+ *
2799
+ * @example
2800
+ * ```ts
2801
+ * chat.agent({
2802
+ * id: "my-chat",
2803
+ * uiMessageStreamOptions: {
2804
+ * sendReasoning: true,
2805
+ * onError: (error) => error instanceof Error ? error.message : "An error occurred.",
2806
+ * },
2807
+ * run: async ({ messages, signal }) => { ... },
2808
+ * });
2809
+ * ```
2810
+ */
2811
+ uiMessageStreamOptions?: ChatUIMessageStreamOptions<TUIMessage>;
2812
+ /**
2813
+ * Called right before the run suspends to wait for a message.
2814
+ *
2815
+ * The `phase` discriminator tells you when the suspend happened:
2816
+ * - `"preload"`: after `onPreload`, waiting for the first message
2817
+ * - `"turn"`: after `onTurnComplete`, waiting for the next message
2818
+ *
2819
+ * Use this for cleanup before suspension (e.g. disposing sandboxes, closing connections).
2820
+ *
2821
+ * @example
2822
+ * ```ts
2823
+ * onChatSuspend: async (event) => {
2824
+ * await disposeExpensiveResources(event.ctx.run.id);
2825
+ * if (event.phase === "turn") {
2826
+ * logger.info("Suspending after turn", { turn: event.turn });
2827
+ * }
2828
+ * }
2829
+ * ```
2830
+ */
2831
+ onChatSuspend?: (event: ChatSuspendEvent<inferSchemaOut<TClientDataSchema>, TUIMessage>) => Promise<void> | void;
2832
+ /**
2833
+ * Called right after the run resumes from suspension with a new message.
2834
+ *
2835
+ * The `phase` discriminator tells you when the resume happened:
2836
+ * - `"preload"`: first message arrived after preload suspension
2837
+ * - `"turn"`: next message arrived after turn suspension
2838
+ *
2839
+ * Use this for re-initialization after wake (e.g. warming caches, reconnecting).
2840
+ *
2841
+ * @example
2842
+ * ```ts
2843
+ * onChatResume: async (event) => {
2844
+ * warmCache(event.ctx.run.id);
2845
+ * if (event.phase === "turn") {
2846
+ * logger.info("Resumed after turn", { turn: event.turn });
2847
+ * }
2848
+ * }
2849
+ * ```
2850
+ */
2851
+ onChatResume?: (event: ChatResumeEvent<inferSchemaOut<TClientDataSchema>, TUIMessage>) => Promise<void> | void;
2852
+ /**
2853
+ * When `true`, the run exits successfully after the preload idle timeout
2854
+ * instead of suspending and waiting. The run completes with no turn executed.
2855
+ *
2856
+ * Use this for "fire and forget" preloads where you only want to do eager
2857
+ * initialization. If the user doesn't send a message during the idle window,
2858
+ * the run ends cleanly.
2859
+ *
2860
+ * Only applies to preloaded runs (triggered via `transport.preload()`).
2861
+ *
2862
+ * @default false
2863
+ */
2864
+ exitAfterPreloadIdle?: boolean;
2865
+ };
2866
+ /**
2867
+ * Creates a Trigger.dev task pre-configured for AI SDK chat.
2868
+ *
2869
+ * - **Pre-types the payload** as `ChatTaskRunPayload` — includes abort signals
2870
+ * - **Auto-pipes the stream** if `run` returns a `StreamTextResult`
2871
+ * - **Multi-turn**: keeps the conversation in a single run using input streams
2872
+ * - **Stop support**: frontend can stop generation mid-stream via the stop input stream
2873
+ * - For complex flows, use `pipeChat()` from anywhere inside your task code
2874
+ *
2875
+ * @example
2876
+ * ```ts
2877
+ * import { chat } from "@trigger.dev/sdk/ai";
2878
+ * import { streamText, convertToModelMessages } from "ai";
2879
+ * import { openai } from "@ai-sdk/openai";
2880
+ *
2881
+ * export const myChat = chat.agent({
2882
+ * id: "my-chat",
2883
+ * run: async ({ messages, signal }) => {
2884
+ * return streamText({
2885
+ * model: openai("gpt-4o"),
2886
+ * messages, // already converted via convertToModelMessages
2887
+ * abortSignal: signal,
2888
+ * });
2889
+ * },
2890
+ * });
2891
+ * ```
2892
+ */
2893
+ type ChatCustomAgentOptions<TIdentifier extends string, TClientDataSchema extends TaskSchema | undefined = undefined, TUIMessage extends UIMessage = UIMessage> = Omit<TaskOptions<TIdentifier, ChatTaskWirePayload<TUIMessage, inferSchemaIn<TClientDataSchema>>, unknown>, "triggerSource" | "agentConfig" | "run"> & {
2894
+ /**
2895
+ * Schema for validating `metadata` from the frontend.
2896
+ *
2897
+ * The initial payload and later `chat.messages` frames are parsed before
2898
+ * user code receives them. Invalid submitted turns and async reads write an
2899
+ * error chunk followed by `turn-complete`. Messageless boots and active
2900
+ * subscriptions use `onClientDataValidationError` and the task log because
2901
+ * there is no submitted turn to complete or a response may still be streaming.
2902
+ * This validates `metadata` only; raw `action` payloads remain `unknown`.
2903
+ */
2904
+ clientDataSchema?: TClientDataSchema;
2905
+ /**
2906
+ * Called when a custom-agent input fails `clientDataSchema` validation.
2907
+ *
2908
+ * Submitted turns and async reads also write an error chunk followed by
2909
+ * `turn-complete`. Messageless boots and active `chat.messages.on()`
2910
+ * subscriptions are reported through this callback and the task log only.
2911
+ *
2912
+ * `payload.metadata` is typed `unknown`: this callback only fires when
2913
+ * the metadata failed to parse, so it can be any shape the client sent.
2914
+ */
2915
+ onClientDataValidationError?: (event: {
2916
+ error: unknown;
2917
+ payload: ChatTaskWirePayload<TUIMessage, unknown>;
2918
+ }) => Promise<void> | void;
2919
+ /**
2920
+ * When a frame that arrived mid-turn fails `clientDataSchema` validation,
2921
+ * decides when the terminal error reaches the client.
2922
+ *
2923
+ * - `"turn-end"` (default) waits until the turn has closed. A terminal error
2924
+ * written into a live response can close it, so this keeps a bad client
2925
+ * send from truncating an answer the user is already reading.
2926
+ * - `"arrival"` writes it as soon as validation fails, which surfaces the
2927
+ * problem sooner at the cost of ending the response in progress.
2928
+ *
2929
+ * `onClientDataValidationError` and the task log fire on arrival either way;
2930
+ * this only governs the stream-visible error. The frame is never delivered as
2931
+ * a turn in either mode.
2932
+ */
2933
+ clientDataReportErrorAt?: "turn-end" | "arrival";
2934
+ run: TaskOptions<TIdentifier, ChatTaskWirePayload<TUIMessage, inferSchemaOut<TClientDataSchema>>, unknown>["run"];
2935
+ };
2936
+ declare function chatCustomAgent<TIdentifier extends string, TClientDataSchema extends TaskSchema | undefined = undefined, TUIMessage extends UIMessage = UIMessage>(options: ChatCustomAgentOptions<TIdentifier, TClientDataSchema, TUIMessage>): Task<TIdentifier, ChatTaskWirePayload<TUIMessage, inferSchemaIn<TClientDataSchema>>, unknown>;
2937
+ declare function chatAgent<TIdentifier extends string, TClientDataSchema extends TaskSchema | undefined = undefined, TUIMessage extends UIMessage = UIMessage, TActionSchema extends TaskSchema | undefined = undefined, TTools extends ToolSet = ToolSet, const TW extends readonly AnyChatEvent[] = [], const TChannels extends readonly AnyChannelConnector[] = []>(options: ChatAgentOptions<TIdentifier, TClientDataSchema, TUIMessage, TActionSchema, TTools, TW, TChannels>): Task<TIdentifier, ChatTaskWirePayload<TUIMessage, inferSchemaIn<TClientDataSchema>>, unknown>;
2938
+ /**
2939
+ * Optional config for {@link chat.withUIMessage}. `streamOptions` become default
2940
+ * static `toUIMessageStream()` settings; inner `chat.agent({ uiMessageStreamOptions })`
2941
+ * shallow-merges on top (task wins on conflicts).
2942
+ */
2943
+ export type ChatWithUIMessageConfig<TUIM extends UIMessage = UIMessage> = {
2944
+ streamOptions?: ChatUIMessageStreamOptions<TUIM>;
2945
+ };
2946
+ /**
2947
+ * A chainable builder for configuring chat tasks with fixed UI message types,
2948
+ * client data schemas, and builder-level hooks that compose with task-level hooks.
2949
+ *
2950
+ * Obtain a builder via {@link chat.withUIMessage} or {@link chat.withClientData}.
2951
+ *
2952
+ * @example
2953
+ * ```ts
2954
+ * export const myChat = chat
2955
+ * .withUIMessage<AgentUiMessage>({ streamOptions: { sendReasoning: true } })
2956
+ * .withClientData({ schema: z.object({ userId: z.string() }) })
2957
+ * .onChatSuspend(async ({ ctx }) => { await disposeResources(ctx.run.id) })
2958
+ * .task({
2959
+ * id: "my-chat",
2960
+ * run: async ({ messages, signal }) => streamText({ model, messages, abortSignal: signal }),
2961
+ * });
2962
+ * ```
2963
+ */
2964
+ export interface ChatBuilder<TUIMessage extends UIMessage = UIMessage, TClientDataSchema extends TaskSchema | undefined = undefined> {
2965
+ /** Fix the UI message type. Returns a new builder preserving all accumulated state. */
2966
+ withUIMessage<TUIM extends UIMessage = UIMessage>(config?: ChatWithUIMessageConfig<TUIM>): ChatBuilder<TUIM, TClientDataSchema>;
2967
+ /**
2968
+ * Fix the client data schema, and how validation failures are handled.
2969
+ * Returns a new builder preserving all accumulated state.
2970
+ */
2971
+ withClientData<TSchema extends TaskSchema>(config: {
2972
+ schema: TSchema;
2973
+ /**
2974
+ * When a frame that arrived mid-turn fails validation, decides when the
2975
+ * client-visible error is written.
2976
+ *
2977
+ * `"turn-end"` (default) waits for the turn to close, so a bad send cannot
2978
+ * truncate an answer already being read. `"arrival"` writes it as soon as
2979
+ * validation fails, ending the response in progress.
2980
+ *
2981
+ * `onValidationError` and the task log fire on arrival either way, and the
2982
+ * frame is never delivered as a turn.
2983
+ */
2984
+ reportErrorAt?: "turn-end" | "arrival";
2985
+ /** Called when an input fails validation. Composes with the task-level hook. */
2986
+ onValidationError?: (event: {
2987
+ error: unknown;
2988
+ payload: ChatTaskWirePayload<TUIMessage, unknown>;
2989
+ }) => Promise<void> | void;
2990
+ }): ChatBuilder<TUIMessage, TSchema>;
2991
+ /** Register a builder-level `onBoot` hook. Runs before the task-level hook if both are set. */
2992
+ onBoot(fn: (event: BootEvent<inferSchemaOut<TClientDataSchema>>) => Promise<void> | void): ChatBuilder<TUIMessage, TClientDataSchema>;
2993
+ /** Register a builder-level `onPreload` hook. Runs before the task-level hook if both are set. */
2994
+ onPreload(fn: (event: PreloadEvent<inferSchemaOut<TClientDataSchema>>) => Promise<void> | void): ChatBuilder<TUIMessage, TClientDataSchema>;
2995
+ /** Register a builder-level `onChatStart` hook. Runs before the task-level hook if both are set. */
2996
+ onChatStart(fn: (event: ChatStartEvent<inferSchemaOut<TClientDataSchema>>) => Promise<void> | void): ChatBuilder<TUIMessage, TClientDataSchema>;
2997
+ /** Register a builder-level `onTurnStart` hook. Runs before the task-level hook if both are set. */
2998
+ onTurnStart(fn: (event: TurnStartEvent<inferSchemaOut<TClientDataSchema>, TUIMessage>) => Promise<void> | void): ChatBuilder<TUIMessage, TClientDataSchema>;
2999
+ /** Register a builder-level `onBeforeTurnComplete` hook. Runs before the task-level hook if both are set. */
3000
+ onBeforeTurnComplete(fn: (event: BeforeTurnCompleteEvent<inferSchemaOut<TClientDataSchema>, TUIMessage>) => Promise<void> | void): ChatBuilder<TUIMessage, TClientDataSchema>;
3001
+ /** Register a builder-level `onTurnComplete` hook. Runs before the task-level hook if both are set. */
3002
+ onTurnComplete(fn: (event: TurnCompleteEvent<inferSchemaOut<TClientDataSchema>, TUIMessage>) => Promise<void> | void): ChatBuilder<TUIMessage, TClientDataSchema>;
3003
+ /** Register a builder-level `onCompacted` hook. Runs before the task-level hook if both are set. */
3004
+ onCompacted(fn: (event: CompactedEvent) => Promise<void> | void): ChatBuilder<TUIMessage, TClientDataSchema>;
3005
+ /** Register a builder-level `onChatSuspend` hook. Runs before the task-level hook if both are set. */
3006
+ onChatSuspend(fn: (event: ChatSuspendEvent<inferSchemaOut<TClientDataSchema>, TUIMessage>) => Promise<void> | void): ChatBuilder<TUIMessage, TClientDataSchema>;
3007
+ /** Register a builder-level `onChatResume` hook. Runs before the task-level hook if both are set. */
3008
+ onChatResume(fn: (event: ChatResumeEvent<inferSchemaOut<TClientDataSchema>, TUIMessage>) => Promise<void> | void): ChatBuilder<TUIMessage, TClientDataSchema>;
3009
+ /**
3010
+ * Create the chat agent with the accumulated builder configuration.
3011
+ *
3012
+ * When `withClientData` was called, `clientDataSchema` is injected automatically
3013
+ * and omitted from options. Otherwise, it can still be set directly in options
3014
+ * (backwards compatible).
3015
+ */
3016
+ agent: [TClientDataSchema] extends [undefined] ? <TId extends string, TInfer extends TaskSchema | undefined = undefined, TAction extends TaskSchema | undefined = undefined, TTools extends ToolSet = ToolSet>(options: ChatAgentOptions<TId, TInfer, TUIMessage, TAction, TTools>) => Task<TId, ChatTaskWirePayload<TUIMessage, inferSchemaIn<TInfer>>, unknown> : <TId extends string, TAction extends TaskSchema | undefined = undefined, TTools extends ToolSet = ToolSet>(options: Omit<ChatAgentOptions<TId, TClientDataSchema, TUIMessage, TAction, TTools>, "clientDataSchema">) => Task<TId, ChatTaskWirePayload<TUIMessage, inferSchemaIn<TClientDataSchema>>, unknown>;
3017
+ /**
3018
+ * Create a custom agent with manual lifecycle control.
3019
+ *
3020
+ * The agent appears in the playground but you manage the turn loop,
3021
+ * message waiting, and streaming yourself using composable primitives
3022
+ * (`chat.messages`, `chat.MessageAccumulator`, `chat.pipeAndCapture`, etc.).
3023
+ *
3024
+ * Builder hooks (`onPreload`, `onChatStart`, etc.) are not applied —
3025
+ * those are managed-lifecycle concepts handled by `.agent()`.
3026
+ */
3027
+ customAgent: [TClientDataSchema] extends [undefined] ? <TId extends string>(options: ChatCustomAgentOptions<TId, undefined, TUIMessage>) => Task<TId, ChatTaskWirePayload<TUIMessage, undefined>, unknown> : <TId extends string>(options: Omit<ChatCustomAgentOptions<TId, TClientDataSchema, TUIMessage>, "clientDataSchema">) => Task<TId, ChatTaskWirePayload<TUIMessage, inferSchemaIn<TClientDataSchema>>, unknown>;
3028
+ }
3029
+ /**
3030
+ * Fix the UI message type for a chat task (AI SDK `UIMessage` generics) while
3031
+ * keeping `id` and `clientDataSchema` inference on the inner {@link chat.agent} call.
3032
+ *
3033
+ * Returns a {@link ChatBuilder} that supports chaining `.withClientData()`,
3034
+ * hook methods (`.onPreload()`, `.onChatSuspend()`, etc.), and `.task()`.
3035
+ *
3036
+ * @example
3037
+ * ```ts
3038
+ * type AgentUiMessage = UIMessage<unknown, UIDataTypes, UITools>;
3039
+ *
3040
+ * export const myChat = chat.withUIMessage<AgentUiMessage>({
3041
+ * streamOptions: { sendReasoning: true },
3042
+ * }).task({
3043
+ * id: "my-chat",
3044
+ * run: async ({ messages, signal }) => { ... },
3045
+ * });
3046
+ * ```
3047
+ */
3048
+ declare function withUIMessage<TUIM extends UIMessage = UIMessage>(config?: ChatWithUIMessageConfig<TUIM>): ChatBuilder<TUIM, undefined>;
3049
+ /**
3050
+ * Fix the client data schema for a chat task, providing typed `clientData`
3051
+ * in all hooks and the `run` function.
3052
+ *
3053
+ * Returns a {@link ChatBuilder} that supports chaining `.withUIMessage()`,
3054
+ * hook methods (`.onPreload()`, `.onChatSuspend()`, etc.), and `.task()`.
3055
+ *
3056
+ * @example
3057
+ * ```ts
3058
+ * export const myChat = chat
3059
+ * .withClientData({ schema: z.object({ userId: z.string() }) })
3060
+ * .task({
3061
+ * id: "my-chat",
3062
+ * onPreload: async ({ clientData }) => {
3063
+ * // clientData is typed as { userId: string }
3064
+ * },
3065
+ * run: async ({ messages, signal }) => { ... },
3066
+ * });
3067
+ * ```
3068
+ */
3069
+ declare function withClientData<TSchema extends TaskSchema>(config: {
3070
+ schema: TSchema;
3071
+ reportErrorAt?: "turn-end" | "arrival";
3072
+ onValidationError?: ChatCustomAgentClientDataErrorHandler;
3073
+ }): ChatBuilder<UIMessage, TSchema>;
3074
+ /**
3075
+ * Override the turn timeout for subsequent turns in the current run.
3076
+ *
3077
+ * The turn timeout controls how long the run stays suspended (freeing compute)
3078
+ * waiting for the next user message. When it expires, the run completes
3079
+ * gracefully and the next message starts a fresh run.
3080
+ *
3081
+ * Call from inside a `chatAgent` run function to adjust based on context.
3082
+ *
3083
+ * @param duration - A duration string (e.g. `"5m"`, `"1h"`, `"30s"`)
3084
+ *
3085
+ * @example
3086
+ * ```ts
3087
+ * run: async ({ messages, signal }) => {
3088
+ * chat.setTurnTimeout("2h");
3089
+ * return streamText({ model, messages, abortSignal: signal });
3090
+ * }
3091
+ * ```
3092
+ */
3093
+ declare function setTurnTimeout(duration: string): void;
3094
+ /**
3095
+ * Override the turn timeout in seconds for subsequent turns in the current run.
3096
+ *
3097
+ * @param seconds - Number of seconds to wait for the next message before ending the run
3098
+ *
3099
+ * @example
3100
+ * ```ts
3101
+ * run: async ({ messages, signal }) => {
3102
+ * chat.setTurnTimeoutInSeconds(3600); // 1 hour
3103
+ * return streamText({ model, messages, abortSignal: signal });
3104
+ * }
3105
+ * ```
3106
+ */
3107
+ declare function setTurnTimeoutInSeconds(seconds: number): void;
3108
+ /**
3109
+ * Override the idle timeout for subsequent turns in the current run.
3110
+ *
3111
+ * The idle timeout controls how long the run stays active (using compute)
3112
+ * after each turn, waiting for the next message. During this window,
3113
+ * responses are instant. After it expires, the run suspends.
3114
+ *
3115
+ * @param seconds - Number of seconds to stay idle (0 to suspend immediately)
3116
+ *
3117
+ * @example
3118
+ * ```ts
3119
+ * run: async ({ messages, signal }) => {
3120
+ * chat.setIdleTimeoutInSeconds(60);
3121
+ * return streamText({ model, messages, abortSignal: signal });
3122
+ * }
3123
+ * ```
3124
+ */
3125
+ declare function setIdleTimeoutInSeconds(seconds: number): void;
3126
+ /**
3127
+ * Override the `toUIMessageStream()` options for the current turn.
3128
+ *
3129
+ * These options control how the `StreamTextResult` is converted to a
3130
+ * `UIMessageChunk` stream — error handling, reasoning/source visibility,
3131
+ * message metadata, etc.
3132
+ *
3133
+ * Per-turn options are merged on top of the static `uiMessageStreamOptions`
3134
+ * set on `chat.agent()`. Per-turn values win on conflicts.
3135
+ *
3136
+ * @example
3137
+ * ```ts
3138
+ * run: async ({ messages, signal }) => {
3139
+ * chat.setUIMessageStreamOptions({
3140
+ * sendReasoning: true,
3141
+ * onError: (error) => error instanceof Error ? error.message : "An error occurred.",
3142
+ * });
3143
+ * return streamText({ model, messages, abortSignal: signal });
3144
+ * }
3145
+ * ```
3146
+ */
3147
+ declare function setUIMessageStreamOptions(options: ChatUIMessageStreamOptions<UIMessage>): void;
3148
+ /**
3149
+ * The channel surface of the current turn, from anywhere inside a `chat.agent` run, including a
3150
+ * tool's `execute`. Undefined on a browser turn or when the connector defines no reactions and no
3151
+ * `surface()`. Pass the connector's surface type to get its helpers typed:
3152
+ *
3153
+ * @example
3154
+ * ```ts
3155
+ * execute: async ({ steps }) => {
3156
+ * const linear = chat.surface<LinearRunSurface>();
3157
+ * if (linear) await linear.plan(steps);
3158
+ * }
3159
+ * ```
3160
+ */
3161
+ declare function getChannelSurface<T extends ChannelRunSurface = ChannelRunSurface>(): T | undefined;
3162
+ /**
3163
+ * Check whether the user stopped generation during the current turn.
3164
+ *
3165
+ * Works from **anywhere** inside a `chat.agent` run — including inside
3166
+ * `streamText`'s `onFinish` callback — without needing to thread the
3167
+ * `stopSignal` through closures.
3168
+ *
3169
+ * This is especially useful when the AI SDK's `isAborted` flag is unreliable
3170
+ * (e.g. when using `createUIMessageStream` + `writer.merge()`).
3171
+ *
3172
+ * @example
3173
+ * ```ts
3174
+ * onFinish: ({ isAborted }) => {
3175
+ * const wasStopped = isAborted || chat.isStopped();
3176
+ * if (wasStopped) {
3177
+ * // handle stop
3178
+ * }
3179
+ * }
3180
+ * ```
3181
+ */
3182
+ declare function isStopped(): boolean;
3183
+ /**
3184
+ * Hand the conversation over to another deployment.
3185
+ *
3186
+ * The handover happens immediately and server-side: a successor run is created
3187
+ * and picks the conversation up from `session.in`. The transport keeps reading
3188
+ * the same session output, so no client action is needed and nothing waits for
3189
+ * the next message.
3190
+ *
3191
+ * Without a target the session's pin is cleared, so the successor lands on the
3192
+ * latest deployed version; with `externalDeploymentId` the session is re-pinned
3193
+ * to that deployment.
3194
+ *
3195
+ * When called from `onTurnStart` or `onValidateMessages`, `run()` is skipped
3196
+ * entirely and the successor answers the message that opened the turn.
3197
+ *
3198
+ * When called from `run()` or `chat.defer()`, the current turn completes
3199
+ * normally and the handover happens afterward.
3200
+ *
3201
+ * Call from `onTurnStart`, `onValidateMessages`, `onChatResume`, `run()`,
3202
+ * or inside `chat.defer()`.
3203
+ *
3204
+ * @example
3205
+ * ```ts
3206
+ * const SUPPORTED_VERSIONS = new Set(["v2", "v3"]);
3207
+ *
3208
+ * chat.agent({
3209
+ * id: "my-chat",
3210
+ * onTurnStart: async ({ clientData }) => {
3211
+ * if (clientData?.protocolVersion && !SUPPORTED_VERSIONS.has(clientData.protocolVersion)) {
3212
+ * chat.requestUpgrade();
3213
+ * }
3214
+ * },
3215
+ * run: async ({ messages }) => { ... },
3216
+ * });
3217
+ * ```
3218
+ */
3219
+ declare function requestUpgrade(options?: {
3220
+ externalDeploymentId?: string;
3221
+ }): void;
3222
+ /**
3223
+ * Hand off the current custom agent Session to a fresh run.
3224
+ *
3225
+ * This is the low-level handoff for a fully hand-rolled
3226
+ * `chat.customAgent()` loop. This method rejects while a
3227
+ * `chat.createSession()` iterator is active. Close the iterator before calling
3228
+ * it. If `return()` races an active `next()`, it waits for that read to settle
3229
+ * before releasing the handoff guard. Call only between turns and after
3230
+ * detaching input listeners for the old run. If the old run completed its
3231
+ * current turn, persist its state and call {@link chatWriteTurnComplete} before
3232
+ * handing off.
3233
+ * Do not write a new turn boundary after input that the continuation run should
3234
+ * process has been dispatched: the boundary acknowledges that input.
3235
+ *
3236
+ * The server starts the continuation run but does not stop this run, so return
3237
+ * from the task immediately after awaiting this function. The promise rejects
3238
+ * if the server cannot complete the handoff.
3239
+ *
3240
+ * Pending Session input that the old run has not consumed remains on the
3241
+ * durable `.in` stream and is delivered to the continuation run.
3242
+ *
3243
+ * @example
3244
+ * ```ts
3245
+ * // Detach any chat.messages.on() subscriptions you created.
3246
+ * await persistMessages();
3247
+ * await chat.writeTurnComplete();
3248
+ * await chat.endAndContinue();
3249
+ * return;
3250
+ * ```
3251
+ */
3252
+ declare function endAndContinue(): Promise<void>;
3253
+ /**
3254
+ * Exit the run after the current turn completes, without waiting for the
3255
+ * next message. Unlike {@link requestUpgrade}, no upgrade-required signal
3256
+ * is sent to the client — the turn finishes normally, `onTurnComplete`
3257
+ * fires, and the loop exits instead of going idle.
3258
+ *
3259
+ * Call from `run()`, `chat.defer()`, `onBeforeTurnComplete`, or
3260
+ * `onTurnComplete` to end the run on your own terms (budget exhausted,
3261
+ * task complete, goal achieved, etc.).
3262
+ *
3263
+ * The next user message on the same `chatId` starts a fresh run via the
3264
+ * normal continuation mechanism.
3265
+ *
3266
+ * @example
3267
+ * ```ts
3268
+ * chat.agent({
3269
+ * id: "one-shot-agent",
3270
+ * run: async ({ messages, signal }) => {
3271
+ * const result = streamText({ model: openai("gpt-4o"), messages, abortSignal: signal });
3272
+ * // Single-response agent — exit after this turn.
3273
+ * chat.endRun();
3274
+ * return result;
3275
+ * },
3276
+ * });
3277
+ * ```
3278
+ */
3279
+ declare function endRun(): void;
3280
+ /**
3281
+ * End the whole conversation, permanently. The session row is closed, further
3282
+ * appends are refused, and the run exits without scheduling a continuation.
3283
+ *
3284
+ * This is the session-level stop. {@link endRun} ends the current run and lets
3285
+ * the next message start a fresh one; `chat.close()` ends the session itself,
3286
+ * so there is no next message. Use it for a budget cap, a completed goal,
3287
+ * abuse detection, or a user signing out.
3288
+ *
3289
+ * In a `chat.agent`, call it from `run()`, `prepareStep`, or
3290
+ * `onBeforeTurnComplete`. Called mid-step, it aborts the in-flight
3291
+ * `streamText` the same way the stop signal does, so the partial response is
3292
+ * still captured and streamed. The turn then completes normally, a terminal
3293
+ * `session-closed` record carrying `reason` is written to the response stream,
3294
+ * and the loop exits.
3295
+ *
3296
+ * Prefer `onBeforeTurnComplete` over `onTurnComplete`. It carries the same
3297
+ * fields but still runs while the stream is open, so the closed state rides
3298
+ * out on the turn's final record. `onTurnComplete` runs after that record, so
3299
+ * a close decided there does not reach a reader that has already finished the
3300
+ * turn, and the user only finds out when their next message is refused.
3301
+ *
3302
+ * In a `chat.customAgent`, call it anywhere in your own loop. The close is
3303
+ * performed when `run()` returns, so it lands whether you break out of a
3304
+ * `chat.createSession` loop, return early, or hand-roll the loop entirely.
3305
+ *
3306
+ * Closing is one-way: a closed session cannot be reopened. Its transcript
3307
+ * stays readable.
3308
+ *
3309
+ * @example
3310
+ * ```ts
3311
+ * chat.agent({
3312
+ * id: "budgeted-agent",
3313
+ * onBeforeTurnComplete: async ({ usage }) => {
3314
+ * if (await overBudget(usage)) {
3315
+ * chat.close({ reason: "Monthly budget reached" });
3316
+ * }
3317
+ * },
3318
+ * });
3319
+ * ```
3320
+ */
3321
+ declare function close(options?: {
3322
+ reason?: string;
3323
+ }): void;
3324
+ /**
3325
+ * Register a promise that runs in the background during the current turn.
3326
+ *
3327
+ * Use this to move non-blocking work (DB writes, analytics, etc.) out of
3328
+ * the critical path. The promise runs in parallel with streaming and is
3329
+ * awaited (with a 5 s timeout) before `onTurnComplete` fires.
3330
+ *
3331
+ * @example
3332
+ * ```ts
3333
+ * onTurnStart: async ({ chatId, uiMessages }) => {
3334
+ * // Pass a promise directly
3335
+ * chat.defer(db.chat.update({ where: { id: chatId }, data: { messages: uiMessages } }));
3336
+ *
3337
+ * // Or pass an async function — cleaner for multi-step work
3338
+ * chat.defer(async () => {
3339
+ * const flags = await getFeatureFlags();
3340
+ * if (flags.forceUpgrade) chat.requestUpgrade();
3341
+ * });
3342
+ * },
3343
+ * ```
3344
+ */
3345
+ declare function chatDefer(promiseOrFn: Promise<unknown> | (() => Promise<unknown>)): void;
3346
+ /**
3347
+ * Queue model messages for injection at the next `prepareStep` boundary.
3348
+ *
3349
+ * Use this to inject context from background work into the agent's conversation.
3350
+ * Messages are appended to the model messages before the next LLM inference call.
3351
+ *
3352
+ * Combine with `chat.defer()` to run background analysis and inject results:
3353
+ *
3354
+ * @example
3355
+ * ```ts
3356
+ * onTurnComplete: async ({ messages }) => {
3357
+ * chat.defer((async () => {
3358
+ * const review = await generateObject({
3359
+ * model: openai("gpt-4o-mini"),
3360
+ * messages: [...messages, { role: "user", content: "Review the last response." }],
3361
+ * schema: z.object({ suggestions: z.array(z.string()) }),
3362
+ * });
3363
+ * if (review.object.suggestions.length > 0) {
3364
+ * chat.inject([{
3365
+ * role: "system",
3366
+ * content: `Improvements for next response:\n${review.object.suggestions.join("\n")}`,
3367
+ * }]);
3368
+ * }
3369
+ * })());
3370
+ * },
3371
+ * ```
3372
+ */
3373
+ declare function injectBackgroundContext(messages: ModelMessage[]): void;
3374
+ /**
3375
+ * Clean up a UIMessage that was captured during an aborted/stopped turn.
3376
+ *
3377
+ * When generation is stopped mid-stream, the captured message may contain:
3378
+ * - Tool parts stuck in incomplete states (`partial-call`, `input-available`,
3379
+ * `input-streaming`) that cause permanent UI spinners
3380
+ * - Reasoning parts with `state: "streaming"` instead of `"done"`
3381
+ * - Text parts with `state: "streaming"` instead of `"done"`
3382
+ *
3383
+ * This function returns a cleaned copy with:
3384
+ * - Incomplete tool parts removed entirely
3385
+ * - Reasoning and text parts marked as `"done"`
3386
+ *
3387
+ * `chat.agent` calls this automatically when stop is detected before passing
3388
+ * the response to `onTurnComplete`. Use this manually when calling `pipeChat`
3389
+ * directly and capturing response messages yourself.
3390
+ *
3391
+ * @example
3392
+ * ```ts
3393
+ * onTurnComplete: async ({ responseMessage, stopped }) => {
3394
+ * // Already cleaned automatically by chat.agent — but if you captured
3395
+ * // your own message via pipeChat, clean it manually:
3396
+ * const cleaned = chat.cleanupAbortedParts(myMessage);
3397
+ * await db.messages.save(cleaned);
3398
+ * }
3399
+ * ```
3400
+ */
3401
+ declare function cleanupAbortedParts<TUIM extends UIMessage>(message: TUIM): TUIM;
3402
+ /**
3403
+ * Create a managed stop signal wired to the chat stop input stream.
3404
+ *
3405
+ * Call once at the start of your run. Use `signal` as the abort signal for
3406
+ * `streamText`. Call `reset()` at the start of each turn to get a fresh
3407
+ * per-turn signal. Call `cleanup()` when the run ends.
3408
+ *
3409
+ * @example
3410
+ * ```ts
3411
+ * const stop = chat.createStopSignal();
3412
+ * for (let turn = 0; turn < 100; turn++) {
3413
+ * stop.reset();
3414
+ * const result = streamText({ model, messages, abortSignal: stop.signal });
3415
+ * await chat.pipe(result);
3416
+ * // ...
3417
+ * }
3418
+ * stop.cleanup();
3419
+ * ```
3420
+ */
3421
+ declare function createStopSignal(): {
3422
+ readonly signal: AbortSignal;
3423
+ reset: () => void;
3424
+ cleanup: () => void;
3425
+ };
3426
+ /**
3427
+ * Signal the frontend that the current turn is complete.
3428
+ *
3429
+ * The `TriggerChatTransport` intercepts this to close the ReadableStream
3430
+ * for the current turn. Call after piping the response stream.
3431
+ *
3432
+ * Returns two resume cursors for the turn boundary, both saveable from the
3433
+ * task instead of round-tripping them back from the client:
3434
+ * - `lastEventId` — the turn-complete control record's seq_num on
3435
+ * `session.out`; where the next turn's output stream resumes.
3436
+ * - `sessionInEventId` — the safe-to-resume-from cursor on `session.in` as of
3437
+ * this turn-complete. It is the highest sequence that can be resumed past
3438
+ * without skipping an unhandled message, so it is held back behind any
3439
+ * message still buffered unconsumed and is NOT necessarily the sequence of
3440
+ * the record this turn answered. Trigger owns input-cursor recovery, so this
3441
+ * is for correlation / out-of-sync detection, not required. Treat it as a
3442
+ * lower bound: a value below the record you just handled is expected, not a
3443
+ * sign of a lost turn.
3444
+ *
3445
+ * Either is `undefined` when the corresponding cursor isn't available.
3446
+ *
3447
+ * @example
3448
+ * ```ts
3449
+ * await chat.pipe(result);
3450
+ * const { lastEventId, sessionInEventId } = await chat.writeTurnComplete();
3451
+ * await db.chats.update(chatId, { lastEventId, sessionInEventId });
3452
+ * ```
3453
+ */
3454
+ declare function chatWriteTurnComplete(options?: {
3455
+ publicAccessToken?: string;
3456
+ }): Promise<{
3457
+ lastEventId?: string;
3458
+ sessionInEventId?: string;
3459
+ }>;
3460
+ /**
3461
+ * The outcome of a turn's stream, reported by {@link pipeChatAndCapture}.
3462
+ *
3463
+ * - `complete` — the stream finished on its own.
3464
+ * - `aborted` — the stream was stopped via the `signal` (user stop / cancel).
3465
+ * - `error` — the stream threw; `error` carries what was thrown.
3466
+ *
3467
+ * `message` holds whatever the assistant produced and is present for every
3468
+ * status — including `aborted` and `error` — as long as any output streamed
3469
+ * before the stop or failure, so partial responses are never lost.
3470
+ */
3471
+ export type PipeAndCaptureResult = {
3472
+ /** The captured assistant message, or `undefined` if nothing streamed. */
3473
+ message: UIMessage | undefined;
3474
+ /** Coarse outcome of the stream. */
3475
+ status: "complete" | "aborted" | "error";
3476
+ /** The AI SDK finish reason, when the stream reported one. */
3477
+ finishReason?: FinishReason;
3478
+ /** What the stream threw, present only when `status === "error"`. */
3479
+ error?: unknown;
3480
+ };
3481
+ /**
3482
+ * Pipe a `StreamTextResult` (or similar) to the chat stream and capture
3483
+ * the assistant's response message via `onFinish`.
3484
+ *
3485
+ * Combines `toUIMessageStream()` + `onFinish` callback + `chat.pipe()`.
3486
+ * Never throws on a stopped or failed stream: it returns a
3487
+ * {@link PipeAndCaptureResult} whose `message` holds any partial output
3488
+ * captured before the stop/failure, alongside a typed `status` (and `error`
3489
+ * on failure). Save the partial after a stop or error without separate
3490
+ * capture logic.
3491
+ *
3492
+ * @example
3493
+ * ```ts
3494
+ * const result = streamText({ model, messages, abortSignal: signal });
3495
+ * const { message, status, error } = await chat.pipeAndCapture(result, { signal });
3496
+ * if (message) conversation.addResponse(message);
3497
+ * if (status === "error") logger.error("turn failed", { error });
3498
+ * ```
3499
+ */
3500
+ declare function pipeChatAndCapture(source: UIMessageStreamable, options?: {
3501
+ signal?: AbortSignal;
3502
+ spanName?: string;
3503
+ originalMessages?: UIMessage[];
3504
+ }): Promise<PipeAndCaptureResult>;
3505
+ /**
3506
+ * Accumulates conversation messages across turns.
3507
+ *
3508
+ * Handles the transport protocol: turn 0 sends full history (replace),
3509
+ * subsequent turns send only new messages (append), regenerate sends
3510
+ * full history minus last assistant message (replace).
3511
+ *
3512
+ * @example
3513
+ * ```ts
3514
+ * const conversation = new chat.MessageAccumulator();
3515
+ * for (let turn = 0; turn < 100; turn++) {
3516
+ * const messages = await conversation.addIncoming(payload.messages, payload.trigger, turn);
3517
+ * const result = streamText({ model, messages });
3518
+ * const { message } = await chat.pipeAndCapture(result);
3519
+ * if (message) await conversation.addResponse(message);
3520
+ * }
3521
+ * ```
3522
+ */
3523
+ declare class ChatMessageAccumulator {
3524
+ modelMessages: ModelMessage[];
3525
+ uiMessages: UIMessage[];
3526
+ private _compaction?;
3527
+ /** The run a spliced head-start partial contributed, until its response replaces it. */
3528
+ private _handoverRun?;
3529
+ private _pendingMessages?;
3530
+ private _steeringQueue;
3531
+ private _pendingSteer;
3532
+ constructor(options?: {
3533
+ compaction?: ChatAgentCompactionOptions;
3534
+ pendingMessages?: PendingMessagesOptions;
3535
+ });
3536
+ /**
3537
+ * Add incoming messages from the transport payload.
3538
+ * Returns the full accumulated model messages for `streamText`.
3539
+ */
3540
+ addIncoming(messages: UIMessage[], trigger: string, turn: number): Promise<ModelMessage[]>;
3541
+ /**
3542
+ * Add the assistant's response to the accumulator.
3543
+ * Call after `pipeAndCapture` with the captured response.
3544
+ */
3545
+ /**
3546
+ * Replace all accumulated messages (for compaction).
3547
+ * Converts UIMessages to ModelMessages internally.
3548
+ */
3549
+ setMessages(uiMessages: UIMessage[]): Promise<void>;
3550
+ /**
3551
+ * Splice a `chat.headStart` handover partial into the accumulator (the warm
3552
+ * step-1 response). Dedups by `messageId` so a seeded/hydrated history that
3553
+ * already carries the partial isn't doubled. Seed any prior history first
3554
+ * (e.g. `setMessages(payload.headStartMessages)`). Low-level — see
3555
+ * `consumeHandover` for the wait+seed+apply convenience.
3556
+ */
3557
+ applyHandover(signal: {
3558
+ partialAssistantMessage: ModelMessage[];
3559
+ messageId?: string;
3560
+ }): void;
3561
+ /**
3562
+ * One-call `chat.headStart` handover for a custom-agent loop: waits for the
3563
+ * handover signal, seeds prior history from `payload.headStartMessages`,
3564
+ * applies the warm step-1 partial, and reports what to do next.
3565
+ *
3566
+ * Returns `{ isFinal, skipped }`:
3567
+ * - `skipped: true` — not a `handover-prepare` run, the wait idled out, or the
3568
+ * warm handler aborted. Exit the run without a turn.
3569
+ * - `isFinal: true` — step 1 IS the response (pure text). Write turn-complete
3570
+ * and continue; do not call `streamText`.
3571
+ * - `isFinal: false` — fall through to `streamText`, which runs the pending
3572
+ * tool round handed over from step 1.
3573
+ */
3574
+ consumeHandover(options: {
3575
+ payload: {
3576
+ trigger?: string;
3577
+ idleTimeoutInSeconds?: number;
3578
+ headStartMessages?: UIMessage[];
3579
+ };
3580
+ idleTimeoutInSeconds?: number;
3581
+ timeout?: string;
3582
+ }): Promise<{
3583
+ isFinal: boolean;
3584
+ skipped: boolean;
3585
+ }>;
3586
+ addResponse(response: UIMessage): Promise<void>;
3587
+ /**
3588
+ * Queue a message for injection via `prepareStep`. Call from a
3589
+ * `messagesInput.on()` listener when a message arrives during streaming.
3590
+ */
3591
+ steer(message: UIMessage, modelMessages?: ModelMessage[]): void;
3592
+ /**
3593
+ * Queue a message for injection, converting to model messages automatically.
3594
+ */
3595
+ steerAsync(message: UIMessage): Promise<void>;
3596
+ /**
3597
+ * Record the messages a steering drain consumed.
3598
+ *
3599
+ * The drain only puts them in this step's prompt, so without this they
3600
+ * shape one answer and then exist in neither lane: not in `uiMessages`,
3601
+ * which is what an app persists from, and not in `modelMessages`, which is
3602
+ * what every later turn sends.
3603
+ *
3604
+ * Both lanes are appended to. The model lane is never reconverted from the
3605
+ * UI lane, because `compactIfNeeded` replaces it with a summary and leaves
3606
+ * the UI lane whole: a reconversion would restore everything the summary
3607
+ * replaced.
3608
+ */
3609
+ absorbSteering(claimed: UIMessage[], injected?: ModelMessage[]): Promise<void>;
3610
+ /**
3611
+ * Get and clear unconsumed steering messages.
3612
+ */
3613
+ drainSteering(): UIMessage[];
3614
+ /**
3615
+ * Returns a `prepareStep` function that handles both compaction and
3616
+ * pending message injection. Pass to `streamText({ prepareStep: conversation.prepareStep() })`.
3617
+ */
3618
+ prepareStep(): ((args: {
3619
+ messages: ModelMessage[];
3620
+ steps: CompactionStep[];
3621
+ }) => Promise<{
3622
+ messages: ModelMessage[];
3623
+ } | undefined>) | undefined;
3624
+ /**
3625
+ * Run outer-loop compaction if needed. Call after adding the response
3626
+ * and capturing usage. Pass the LAST step's usage (`result.usage`), which is
3627
+ * the context the model held on its final call; `result.totalUsage` sums every
3628
+ * step of a tool-using turn and belongs in `context.turnUsage`. Applies
3629
+ * `compactModelMessages` and `compactUIMessages` callbacks if configured.
3630
+ *
3631
+ * @returns `true` if compaction was performed, `false` otherwise.
3632
+ */
3633
+ compactIfNeeded(usage: LanguageModelUsage | undefined, context?: {
3634
+ chatId?: string;
3635
+ turn?: number;
3636
+ clientData?: unknown;
3637
+ /** The whole turn summed over its steps (`result.totalUsage`). */
3638
+ turnUsage?: LanguageModelUsage;
3639
+ totalUsage?: LanguageModelUsage;
3640
+ }): Promise<boolean>;
3641
+ }
3642
+ export type ChatSessionOptions = {
3643
+ /** Run-level cancel signal (from task context). */
3644
+ signal: AbortSignal;
3645
+ /** Seconds to stay idle between turns before suspending. @default 30 */
3646
+ idleTimeoutInSeconds?: number;
3647
+ /** Duration string for suspend timeout. @default "1h" */
3648
+ timeout?: string;
3649
+ /** Max turns before ending. @default 100 */
3650
+ maxTurns?: number;
3651
+ /**
3652
+ * What to do when the session's `externalDeploymentId` no longer names this deployment.
3653
+ * `"follow"` (default) hands over at the next turn boundary; `"hold"` stays put.
3654
+ */
3655
+ versionSkew?: ChatVersionSkewPolicy;
3656
+ /** Automatic context compaction — same options as `chat.agent({ compaction })`. */
3657
+ compaction?: ChatAgentCompactionOptions;
3658
+ /** Configure mid-execution message injection — same options as `chat.agent({ pendingMessages })`. */
3659
+ pendingMessages?: PendingMessagesOptions;
3660
+ };
3661
+ export type ChatTurn<TClientData = unknown> = {
3662
+ /** Turn number (0-indexed). */
3663
+ number: number;
3664
+ /** Chat session ID. */
3665
+ chatId: string;
3666
+ /** What triggered this turn. */
3667
+ trigger: string;
3668
+ /** Client data from the transport (`metadata` field on the wire payload). */
3669
+ clientData: TClientData;
3670
+ /** Full accumulated model messages — pass directly to `streamText`. */
3671
+ readonly messages: ModelMessage[];
3672
+ /** Full accumulated UI messages — use for persistence. */
3673
+ readonly uiMessages: UIMessage[];
3674
+ /** Combined stop+cancel AbortSignal (fresh each turn). */
3675
+ signal: AbortSignal;
3676
+ /** Whether the user stopped generation this turn. */
3677
+ readonly stopped: boolean;
3678
+ /** Whether this is a continuation run. */
3679
+ continuation: boolean;
3680
+ /** Token usage from the previous turn. Undefined on turn 0. */
3681
+ previousTurnUsage?: LanguageModelUsage;
3682
+ /** Cumulative token usage across all completed turns so far. */
3683
+ totalUsage: LanguageModelUsage;
3684
+ /**
3685
+ * Set on the first turn of a `chat.headStart` handover; `null` otherwise.
3686
+ * When `isFinal` is true the warm step-1 IS the response — call
3687
+ * `turn.complete()` with no argument (don't call `streamText`). When false,
3688
+ * call `streamText` as usual; it runs the handed-over tool round.
3689
+ */
3690
+ handover: {
3691
+ isFinal: boolean;
3692
+ } | null;
3693
+ /**
3694
+ * Replace accumulated messages (for compaction). Takes UIMessages and
3695
+ * converts to ModelMessages internally. After calling this, `turn.messages`
3696
+ * reflects the compacted history.
3697
+ */
3698
+ setMessages(uiMessages: UIMessage[]): Promise<void>;
3699
+ /**
3700
+ * Easy path: pipe stream, capture response, accumulate it,
3701
+ * clean up aborted parts if stopped, and write turn-complete chunk.
3702
+ *
3703
+ * Call with no argument on a head-start final turn (`turn.handover?.isFinal`)
3704
+ * — the warm step-1 partial is already the response, so there's nothing to pipe.
3705
+ */
3706
+ complete(source?: UIMessageStreamable): Promise<UIMessage | undefined>;
3707
+ /**
3708
+ * Manual path: just write turn-complete chunk.
3709
+ * Use when you've already piped and accumulated manually.
3710
+ */
3711
+ done(): Promise<void>;
3712
+ /**
3713
+ * Add the response to the accumulator manually.
3714
+ * Use with `chat.pipeAndCapture` when you need control between pipe and done.
3715
+ */
3716
+ addResponse(response: UIMessage): Promise<void>;
3717
+ /**
3718
+ * Returns a `prepareStep` function that handles both compaction and
3719
+ * pending message injection. Pass to `streamText({ prepareStep: turn.prepareStep() })`.
3720
+ * Only needed when not using `chat.toStreamTextOptions()` (which auto-injects it).
3721
+ */
3722
+ prepareStep(): ((args: {
3723
+ messages: ModelMessage[];
3724
+ steps: CompactionStep[];
3725
+ }) => Promise<{
3726
+ messages: ModelMessage[];
3727
+ } | undefined>) | undefined;
3728
+ };
3729
+ /**
3730
+ * Create a chat session that yields turns as an async iterator.
3731
+ *
3732
+ * Handles: preload wait, stop signals, message accumulation, turn-complete
3733
+ * signaling, and idle/suspend between turns. You control: initialization,
3734
+ * model/tool selection, persistence, and any custom per-turn logic.
3735
+ *
3736
+ * Call from inside a `chat.customAgent()` run — the wrapper binds the
3737
+ * backing Session that the iterator's stop signal and message channels
3738
+ * resolve to. (A plain `task()` does not bind it, so `createSession`
3739
+ * would throw "session handle is not initialized".)
3740
+ *
3741
+ * @example
3742
+ * ```ts
3743
+ * import { chat, type ChatTaskWirePayload } from "@trigger.dev/sdk/ai";
3744
+ * import { streamText } from "ai";
3745
+ * import { openai } from "@ai-sdk/openai";
3746
+ *
3747
+ * export const myChat = chat.customAgent({
3748
+ * id: "my-chat",
3749
+ * run: async (payload: ChatTaskWirePayload, { signal }) => {
3750
+ * const session = chat.createSession(payload, { signal });
3751
+ *
3752
+ * for await (const turn of session) {
3753
+ * const result = streamText({
3754
+ * model: openai("gpt-4o"),
3755
+ * messages: turn.messages,
3756
+ * abortSignal: turn.signal,
3757
+ * });
3758
+ * await turn.complete(result);
3759
+ * }
3760
+ * },
3761
+ * });
3762
+ * ```
3763
+ */
3764
+ declare function createChatSession<TClientData = unknown>(payload: ChatTaskWirePayload<UIMessage, TClientData>, options: ChatSessionOptions): AsyncIterable<ChatTurn<TClientData>>;
3765
+ /**
3766
+ * A Proxy-backed, run-scoped data object that appears as `T` to users.
3767
+ * Includes helper methods for initialization, dirty tracking, and serialization.
3768
+ * Internal metadata is stored behind Symbols and invisible to
3769
+ * `Object.keys()`, `JSON.stringify()`, and spread.
3770
+ */
3771
+ export type ChatLocal<T extends Record<string, unknown>> = T & {
3772
+ /** Initialize the local with a value. Call in `onChatStart` or `run()`. */
3773
+ init(value: T): void;
3774
+ /** Returns `true` if any property was set since the last check. Resets the dirty flag. */
3775
+ hasChanged(): boolean;
3776
+ /** Returns a plain object copy of the current value. Useful for persistence. */
3777
+ get(): T;
3778
+ readonly [CHAT_LOCAL_KEY]: ReturnType<typeof locals.create<T>>;
3779
+ readonly [CHAT_LOCAL_DIRTY_KEY]: ReturnType<typeof locals.create<boolean>>;
3780
+ };
3781
+ /**
3782
+ * Creates a per-run typed data object accessible from anywhere during task execution.
3783
+ *
3784
+ * Declare at module level, then initialize inside `onBoot` (recommended — fires
3785
+ * on every fresh worker including continuation runs). Do NOT initialize in
3786
+ * `onChatStart` alone: `onChatStart` only fires on the chat's very first
3787
+ * message, so `chat.local` would be uninitialized on continuation runs and
3788
+ * `run()` would throw.
3789
+ *
3790
+ * Multiple locals can coexist — each gets its own isolated run-scoped storage.
3791
+ *
3792
+ * The `id` is required and must be unique across all `chat.local()` calls in
3793
+ * your project. It's used to serialize values into subtask metadata so that
3794
+ * `ai.toolExecute()` (or legacy `ai.tool()`) subtasks can auto-hydrate parent locals (read-only).
3795
+ *
3796
+ * @example
3797
+ * ```ts
3798
+ * import { chat } from "@trigger.dev/sdk/ai";
3799
+ *
3800
+ * const userPrefs = chat.local<{ theme: string; language: string }>({ id: "userPrefs" });
3801
+ * const gameState = chat.local<{ score: number; streak: number }>({ id: "gameState" });
3802
+ *
3803
+ * export const myChat = chat.agent({
3804
+ * id: "my-chat",
3805
+ * onBoot: async ({ clientData }) => {
3806
+ * const prefs = await db.prefs.findUnique({ where: { userId: clientData.userId } });
3807
+ * userPrefs.init(prefs ?? { theme: "dark", language: "en" });
3808
+ * gameState.init({ score: 0, streak: 0 });
3809
+ * },
3810
+ * onTurnComplete: async ({ chatId }) => {
3811
+ * if (gameState.hasChanged()) {
3812
+ * await db.save({ where: { chatId }, data: gameState.get() });
3813
+ * }
3814
+ * },
3815
+ * run: async ({ messages }) => {
3816
+ * gameState.score++;
3817
+ * return streamText({
3818
+ * system: `User prefers ${userPrefs.theme} theme. Score: ${gameState.score}`,
3819
+ * messages,
3820
+ * });
3821
+ * },
3822
+ * });
3823
+ * ```
3824
+ */
3825
+ declare function chatLocal<T extends Record<string, unknown>>(options: {
3826
+ id: string;
3827
+ }): ChatLocal<T>;
3828
+ /**
3829
+ * Extracts the client data (metadata) type from a chat task.
3830
+ * Use this to type the `metadata` option on the transport.
3831
+ *
3832
+ * @example
3833
+ * ```ts
3834
+ * import type { InferChatClientData } from "@trigger.dev/sdk/ai";
3835
+ * import type { myChat } from "@/trigger/chat";
3836
+ *
3837
+ * type MyClientData = InferChatClientData<typeof myChat>;
3838
+ * // { model?: string; userId: string }
3839
+ * ```
3840
+ */
3841
+ /**
3842
+ * Options for {@link createChatStartSessionAction}.
3843
+ */
3844
+ /**
3845
+ * Discriminator for per-endpoint `baseURL` / `fetch` callbacks on
3846
+ * `createChatStartSessionAction`.
3847
+ *
3848
+ * - `"sessions"` — `POST /api/v1/sessions` (session create + first run trigger).
3849
+ * - `"auth"` — `POST /api/v1/auth/jwt/claims` (only fired when
3850
+ * `tokenTTL` is set; otherwise the publicAccessToken from session create
3851
+ * is reused as-is).
3852
+ */
3853
+ export type ChatStartSessionEndpoint = "sessions" | "auth";
3854
+ export type ChatStartSessionEndpointContext = {
3855
+ endpoint: ChatStartSessionEndpoint;
3856
+ chatId: string;
3857
+ };
3858
+ export type ChatStartSessionBaseURLResolver = (ctx: ChatStartSessionEndpointContext) => string;
3859
+ export type ChatStartSessionFetchOverride = (url: string, init: RequestInit, ctx: ChatStartSessionEndpointContext) => Promise<Response>;
3860
+ export type CreateChatStartSessionActionOptions = {
3861
+ /** TTL for the session-scoped public access token. @default "1h" */
3862
+ tokenTTL?: string | number | Date;
3863
+ /**
3864
+ * Default trigger config used when starting a new session for a chat.
3865
+ * Per-call `params.triggerConfig` shallow-merges on top.
3866
+ */
3867
+ triggerConfig?: Partial<SessionTriggerConfigInput>;
3868
+ /**
3869
+ * Override the Trigger.dev API base URL. String applies to both
3870
+ * `/api/v1/sessions` and `/api/v1/auth/jwt/claims`; function picks per
3871
+ * endpoint. When unset, falls back to `apiClientManager.baseURL`
3872
+ * (typically the `TRIGGER_API_URL` env var). Set this to route session
3873
+ * create through a trusted edge proxy that injects server-side signal
3874
+ * into `basePayload.metadata` before forwarding upstream.
3875
+ */
3876
+ baseURL?: string | ChatStartSessionBaseURLResolver;
3877
+ /**
3878
+ * Per-request fetch override. Receives the resolved URL, RequestInit,
3879
+ * and endpoint context. Use for header injection, proxy routing, or
3880
+ * custom retry. Applies to both session-create and JWT-claims POSTs.
3881
+ */
3882
+ fetch?: ChatStartSessionFetchOverride;
3883
+ /**
3884
+ * API client config (baseURL / accessToken) to scope this action to a specific
3885
+ * environment, for callers that can't set a global `TRIGGER_SECRET_KEY`. The
3886
+ * returned action runs under this config.
3887
+ */
3888
+ apiClient?: ApiClientConfiguration;
3889
+ };
3890
+ /**
3891
+ * Params for the function returned by {@link createChatStartSessionAction}.
3892
+ */
3893
+ export type ChatStartSessionParams<TChat extends AnyTask = AnyTask> = {
3894
+ /** Conversation id (mapped to the Session's `externalId`). */
3895
+ chatId: string;
3896
+ /**
3897
+ * Typed client data — folded into the first run's `payload.metadata` so
3898
+ * `onPreload`, `onChatStart`, etc. see the same `clientData` shape on the
3899
+ * first turn as subsequent turns get via the transport's `clientData`
3900
+ * option. Typed via the agent's `clientDataSchema` when the action is
3901
+ * parameterised with `createStartSessionAction<typeof myChat>(...)`.
3902
+ */
3903
+ clientData?: InferChatClientData<TChat>;
3904
+ /**
3905
+ * Per-call trigger config. Shallow-merged over the action's default
3906
+ * `triggerConfig`. `basePayload` is the customer's wire payload (for
3907
+ * `chat.agent`: anything beyond `chatId`/`messages`/`trigger`/`metadata`,
3908
+ * which the runtime injects automatically).
3909
+ */
3910
+ triggerConfig?: Partial<SessionTriggerConfigInput>;
3911
+ /**
3912
+ * Opaque session-level metadata stored on the Session row. Separate from
3913
+ * the per-turn `clientData` above. Use this when you want to attach
3914
+ * server-side metadata that doesn't go through the agent's `clientDataSchema`.
3915
+ */
3916
+ metadata?: Record<string, unknown>;
3917
+ /**
3918
+ * Up to 10 tags on the Session row, for filtering sessions in the dashboard.
3919
+ * Run tags go in `triggerConfig.tags`.
3920
+ */
3921
+ tags?: string[];
3922
+ };
3923
+ /**
3924
+ * Result from {@link createChatStartSessionAction}'s returned function.
3925
+ */
3926
+ export type ChatStartSessionResult = {
3927
+ /**
3928
+ * Session-scoped public access token (`read:sessions:{chatId} +
3929
+ * write:sessions:{chatId}`). Pass this to the browser; the transport
3930
+ * uses it to call `.in/append`, `.out`, `end-and-continue`.
3931
+ */
3932
+ publicAccessToken: string;
3933
+ /** Friendly id of the run triggered alongside session create. */
3934
+ runId: string;
3935
+ /** Session friendlyId — informational. */
3936
+ sessionId: string;
3937
+ /**
3938
+ * The session's run is parked waiting for its deployment. Messages sent meanwhile are durable
3939
+ * and delivered once it lands; surface this so the wait reads as a deploy in progress.
3940
+ */
3941
+ pendingVersion?: boolean;
3942
+ };
3943
+ /**
3944
+ * Creates a server-side helper that starts (or resumes) a Session for a
3945
+ * given chatId — atomically creating the row, triggering the first run,
3946
+ * and returning a session-scoped PAT for the browser to use.
3947
+ *
3948
+ * Wrap in a Next.js server action (or any server-side handler) so the
3949
+ * customer's secret key never crosses to the browser.
3950
+ *
3951
+ * Parameterise the action with `<typeof yourChatAgent>` to type the
3952
+ * `clientData` field against your agent's `clientDataSchema`.
3953
+ *
3954
+ * @example
3955
+ * ```ts
3956
+ * // actions.ts
3957
+ * "use server";
3958
+ * import { chat } from "@trigger.dev/sdk/ai";
3959
+ * import type { myChat } from "@/trigger/chat";
3960
+ *
3961
+ * export const startChatSession = chat.createStartSessionAction<typeof myChat>(
3962
+ * "my-chat",
3963
+ * { triggerConfig: { machine: "small-1x" } }
3964
+ * );
3965
+ * ```
3966
+ *
3967
+ * Then in the browser, threading the typed `clientData` from the transport:
3968
+ * ```tsx
3969
+ * const transport = useTriggerChatTransport<typeof myChat>({
3970
+ * task: "my-chat",
3971
+ * accessToken: ({ chatId }) => mintChatAccessToken(chatId),
3972
+ * startSession: ({ chatId, clientData }) =>
3973
+ * startChatSession({ chatId, clientData }),
3974
+ * });
3975
+ * ```
3976
+ */
3977
+ declare function createChatStartSessionAction<TChat extends AnyTask = AnyTask>(taskId: string, options?: CreateChatStartSessionActionOptions): (params: ChatStartSessionParams<TChat>) => Promise<ChatStartSessionResult>;
3978
+ export type CreateChatLoadTranscriptActionOptions = {
3979
+ /**
3980
+ * Scope the action to a specific API client configuration (secret key,
3981
+ * base URL) instead of the process-wide one. The default storage reads
3982
+ * through this client.
3983
+ */
3984
+ apiClient?: ApiClientConfiguration;
3985
+ /** Page size when the caller passes none. */
3986
+ limit?: number;
3987
+ };
3988
+ export type ChatLoadTranscriptParams<TClientData = unknown> = {
3989
+ chatId: string;
3990
+ clientData?: TClientData;
3991
+ limit?: number;
3992
+ before?: string;
3993
+ };
3994
+ /**
3995
+ * Creates a server-side helper that reads a conversation from a transcript
3996
+ * storage, for rendering history before the chat connects. Works the same
3997
+ * for every storage, the platform default included, so the browser never
3998
+ * reads a store directly and the secret key stays on the server.
3999
+ *
4000
+ * Wrap it in a Next.js server action (or any server-side handler), scope it
4001
+ * to the authenticated user through `clientData`, and pass the result to
4002
+ * `useLoadTranscript` in the browser.
4003
+ *
4004
+ * @example
4005
+ * ```ts
4006
+ * // actions.ts
4007
+ * "use server";
4008
+ * import { chat, defaultStorage } from "@trigger.dev/sdk/ai";
4009
+ *
4010
+ * export const loadTranscript = chat.createLoadTranscriptAction(defaultStorage, { limit: 50 });
4011
+ * ```
4012
+ */
4013
+ declare function createChatLoadTranscriptAction<TClientData = unknown>(storage: TranscriptStorage<TClientData>, options?: CreateChatLoadTranscriptActionOptions): (params: ChatLoadTranscriptParams<TClientData>) => Promise<TranscriptLoadResult>;
4014
+ export declare const chat: {
4015
+ /** Create a chat agent. See {@link chatAgent}. */
4016
+ agent: typeof chatAgent;
4017
+ /** Declare an inbound webhook event an agent claims via `chat.agent({ events })`. See {@link chatEvent}. */
4018
+ event: typeof chatEvent;
4019
+ /** Chat frontend connectors (Slack, etc.) an agent claims via `chat.agent({ channels })`. */
4020
+ channels: {
4021
+ /** A generic chat-frontend channel over any source, with your own egress. See {@link chatChannelCustom}. */
4022
+ custom: typeof chatChannelCustom;
4023
+ };
4024
+ /** Create a custom agent with manual lifecycle control. See {@link chatCustomAgent}. */
4025
+ customAgent: typeof chatCustomAgent;
4026
+ /** Create a chat task with a fixed {@link UIMessage} subtype and optional default stream options. See {@link withUIMessage}. */
4027
+ withUIMessage: typeof withUIMessage;
4028
+ /** Create a chat task with a fixed client data schema. See {@link withClientData}. */
4029
+ withClientData: typeof withClientData;
4030
+ /** Create a server-side helper for starting (or resuming) a Session for a chatId. See {@link createChatStartSessionAction}. */
4031
+ createStartSessionAction: typeof createChatStartSessionAction;
4032
+ /** Returns a server-side helper that reads a conversation from a transcript storage. */
4033
+ createLoadTranscriptAction: typeof createChatLoadTranscriptAction;
4034
+ /** Pipe a stream to the chat transport. See {@link pipeChat}. */
4035
+ pipe: typeof pipeChat;
4036
+ /** Return from `onAction` to run a turn on the edited history. See {@link chatTurn}. */
4037
+ turn: typeof chatTurn;
4038
+ /** Create a per-run typed local. See {@link chatLocal}. */
4039
+ local: typeof chatLocal;
4040
+ /** Create a public access token for a chat task. See {@link createChatAccessToken}. */
4041
+ createAccessToken: typeof createChatAccessToken;
4042
+ /** Mint a read-only token to WATCH a session by externalId (cross-surface). See {@link createChatWatchToken}. */
4043
+ createWatchToken: typeof createChatWatchToken;
4044
+ /** Override the turn timeout at runtime (duration string). See {@link setTurnTimeout}. */
4045
+ setTurnTimeout: typeof setTurnTimeout;
4046
+ /** Override the turn timeout at runtime (seconds). See {@link setTurnTimeoutInSeconds}. */
4047
+ setTurnTimeoutInSeconds: typeof setTurnTimeoutInSeconds;
4048
+ /** Override the idle timeout at runtime. See {@link setIdleTimeoutInSeconds}. */
4049
+ setIdleTimeoutInSeconds: typeof setIdleTimeoutInSeconds;
4050
+ /** Override toUIMessageStream() options for the current turn. See {@link setUIMessageStreamOptions}. */
4051
+ setUIMessageStreamOptions: typeof setUIMessageStreamOptions;
4052
+ /** Check if the current turn was stopped by the user. See {@link isStopped}. */
4053
+ isStopped: typeof isStopped;
4054
+ /** The current turn's channel surface (reactions plus connector helpers), also from inside a tool. See {@link getChannelSurface}. */
4055
+ surface: typeof getChannelSurface;
4056
+ /** Request that the run exits after the current turn so the next message starts on the latest version. See {@link requestUpgrade}. */
4057
+ requestUpgrade: typeof requestUpgrade;
4058
+ /** Hand off a custom agent Session to a fresh run. See {@link endAndContinue}. */
4059
+ endAndContinue: typeof endAndContinue;
4060
+ /** Exit the run after the current turn completes, without any upgrade signal. See {@link endRun}. */
4061
+ endRun: typeof endRun;
4062
+ /** End the conversation permanently: close the session and exit the run. See {@link close}. */
4063
+ close: typeof close;
4064
+ /** Clean up aborted parts from a UIMessage. See {@link cleanupAbortedParts}. */
4065
+ cleanupAbortedParts: typeof cleanupAbortedParts;
4066
+ /** Register background work that runs in parallel with streaming. See {@link chatDefer}. */
4067
+ defer: typeof chatDefer;
4068
+ deferBeforeOutput: typeof chatDeferBeforeOutput;
4069
+ /** Queue model messages for injection at the next `prepareStep` boundary. See {@link injectBackgroundContext}. */
4070
+ inject: typeof injectBackgroundContext;
4071
+ /** Typed chat output stream for writing custom chunks or piping from subtasks. */
4072
+ stream: RealtimeDefinedStream<UIMessageChunk>;
4073
+ /** Write data parts that persist to the response message. See {@link chatResponse}. */
4074
+ response: {
4075
+ /**
4076
+ * Write a single chunk. Non-transient data parts are accumulated into the
4077
+ * response message; everything else is stream-only.
4078
+ */
4079
+ write(part: UIMessageChunk): void;
4080
+ };
4081
+ /** Pre-built input stream for receiving messages from the transport. */
4082
+ messages: ChatMessages;
4083
+ /** The current chat.agent run's Session handle. See {@link SessionHandle}. */
4084
+ session: typeof getChatSession;
4085
+ /**
4086
+ * Open a named side channel on the current chat.agent run's Session: a
4087
+ * durable, cross-run `.in`/`.out` pair addressed by `name`, separate from the
4088
+ * chat transcript. Writing its `.in` does not wake a run. Shortcut for
4089
+ * `chat.session().channel(name)`.
4090
+ */
4091
+ channel: <C extends AnySessionChannel = AnySessionChannel>(channel: SessionChannelName<C> | C) => SessionChannelHandleFor<C>;
4092
+ /** Create a managed stop signal wired to the stop input stream. See {@link createStopSignal}. */
4093
+ createStopSignal: typeof createStopSignal;
4094
+ /** Signal the frontend that the current turn is complete. See {@link chatWriteTurnComplete}. */
4095
+ writeTurnComplete: typeof chatWriteTurnComplete;
4096
+ /** Pipe a stream and capture the response message. See {@link pipeChatAndCapture}. */
4097
+ pipeAndCapture: typeof pipeChatAndCapture;
4098
+ /** Message accumulator class for raw task chat. See {@link ChatMessageAccumulator}. */
4099
+ MessageAccumulator: typeof ChatMessageAccumulator;
4100
+ /** Create a chat session (async iterator). See {@link createChatSession}. */
4101
+ createSession: typeof createChatSession;
4102
+ /**
4103
+ * Wait for a `chat.headStart` handover signal inside a `chat.customAgent`
4104
+ * loop (turn 0). See {@link waitForHandover}. For most loops prefer the
4105
+ * `chat.MessageAccumulator.consumeHandover()` convenience, which also seeds
4106
+ * `payload.headStartMessages` and applies the partial.
4107
+ */
4108
+ waitForHandover: typeof waitForHandover;
4109
+ /**
4110
+ * Store and retrieve a resolved prompt for the current run.
4111
+ *
4112
+ * - `chat.prompt.set(resolved)` — store a `ResolvedPrompt` or plain string
4113
+ * - `chat.prompt.set(resolved, { providerOptions })` — also attach provider
4114
+ * options to the system block so a provider can cache it (e.g. Anthropic
4115
+ * prompt caching). See the prompt-caching guide.
4116
+ * - `chat.prompt()` — read the stored prompt (throws if not set)
4117
+ */
4118
+ prompt: typeof getChatPrompt & {
4119
+ set: typeof setChatPrompt;
4120
+ };
4121
+ /**
4122
+ * Store and retrieve resolved agent skills for the current run.
4123
+ *
4124
+ * - `chat.skills.set([...])` — store an array of `ResolvedSkill`s
4125
+ * - `chat.skills()` — read the stored skills (returns undefined if none)
4126
+ *
4127
+ * Skills set here are automatically injected into `streamText` by
4128
+ * `chat.toStreamTextOptions()`: skill descriptions land in the system
4129
+ * prompt and `loadSkill` / `readFile` / `bash` tools are added to the
4130
+ * tool set.
4131
+ */
4132
+ skills: typeof getChatSkills & {
4133
+ set: typeof setChatSkills;
4134
+ };
4135
+ /**
4136
+ * Returns an options object ready to spread into `streamText()`.
4137
+ * Reads the stored prompt and returns `{ system, experimental_telemetry, ...config }`.
4138
+ * With no stored prompt it still returns `experimental_telemetry` (on), so the model call is
4139
+ * traced.
4140
+ */
4141
+ toStreamTextOptions: typeof toStreamTextOptions;
4142
+ /**
4143
+ * Replace the accumulated conversation messages for compaction.
4144
+ * Call from `onTurnStart` or `onTurnComplete`. Takes `UIMessage[]` and
4145
+ * converts to `ModelMessage[]` internally.
4146
+ */
4147
+ setMessages: typeof setChatMessages;
4148
+ /**
4149
+ * Imperative API for modifying the accumulated message history.
4150
+ * Supports rollback, remove, replace, slice, and full replacement.
4151
+ * Can be called from any hook or `run()`.
4152
+ */
4153
+ history: {
4154
+ /** Read the current accumulated UI messages (copy). */
4155
+ all(): UIMessage[];
4156
+ /**
4157
+ * Read the current chain as an ordered `UIMessage[]`. Identical to
4158
+ * `all()`; use whichever name reads better in context.
4159
+ */
4160
+ getChain(): UIMessage[];
4161
+ /**
4162
+ * Find a message by id. Returns `undefined` if no message with that id
4163
+ * is present in the current chain.
4164
+ */
4165
+ findMessage(messageId: string): UIMessage | undefined;
4166
+ /**
4167
+ * Tool calls on the *most recent* assistant message that are still in
4168
+ * `input-available` state (waiting on an `addToolOutput` answer). The
4169
+ * scan walks back from the tail and stops at the first assistant
4170
+ * message it finds, so a trailing user message does not change the
4171
+ * result — pending tool calls remain pending until they're resolved
4172
+ * on that assistant or the assistant is removed.
4173
+ *
4174
+ * Use this to gate fresh user turns or actions during HITL flows: if
4175
+ * `getPendingToolCalls().length > 0`, an `addToolOutput` is expected.
4176
+ *
4177
+ * Returns `[]` if there is no assistant message yet, or if the most
4178
+ * recent assistant has no pending tool calls.
4179
+ *
4180
+ * Approval flows (`approval-requested` / `approval-responded` states)
4181
+ * are not surfaced here. Those are about the user authorizing a tool
4182
+ * to run; "pending" is about the user *answering* a tool call.
4183
+ */
4184
+ getPendingToolCalls(): ChatToolCallRef[];
4185
+ /**
4186
+ * Tool calls across the chain with a final result (`output-available`
4187
+ * or `output-error`). Use this to dedup re-saves when the AI SDK
4188
+ * resends an assistant message with progressively more answered parts.
4189
+ */
4190
+ getResolvedToolCalls(): ChatToolCallRef[];
4191
+ /**
4192
+ * Pure helper: returns the tool parts in `message` whose results are
4193
+ * not already represented in the current chain. Use this when
4194
+ * persisting tool results to your own store: each call surfaces only
4195
+ * the *new* answers, so writes stay idempotent across re-streams.
4196
+ * Duplicate `toolCallId`s within `message` itself are also collapsed
4197
+ * to a single entry.
4198
+ */
4199
+ extractNewToolResults(message: UIMessage): ChatNewToolResult[];
4200
+ /** Replace all accumulated messages. Same as `chat.setMessages()`. */
4201
+ set(messages: UIMessage[]): void;
4202
+ /** Remove a specific message by ID. */
4203
+ remove(messageId: string): void;
4204
+ /** Keep messages up to and including the given ID (undo/rollback). */
4205
+ rollbackTo(messageId: string): void;
4206
+ /** Replace a specific message by ID (edit). */
4207
+ replace(messageId: string, message: UIMessage): void;
4208
+ /** Keep only messages in the given range. */
4209
+ slice(start: number, end?: number): void;
4210
+ };
4211
+ /** Check if it's safe to compact messages (no in-flight tool calls). */
4212
+ isCompactionSafe: typeof isCompactionSafe;
4213
+ /** Returns a `prepareStep` function that handles context compaction automatically. */
4214
+ compactionStep: typeof chatCompactionStep;
4215
+ /** Low-level compaction for use inside a custom `prepareStep`. */
4216
+ compact: typeof chatCompact;
4217
+ /** Read the current compaction state (summary + base message count). */
4218
+ getCompactionState: typeof getCompactionState;
4219
+ /**
4220
+ * The friendlyId (`session_*`) of the backing Session for the current chat.agent run.
4221
+ * Useful for persisting alongside `runId` so reloads can resume the same session.
4222
+ * Throws if called outside a chat.agent `run()` or hook.
4223
+ */
4224
+ readonly sessionId: string;
4225
+ };