workflow 5.0.0-beta.5 → 5.0.0-beta.51

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 (256) hide show
  1. package/README.md +68 -23
  2. package/dist/api-workflow.d.ts +1 -1
  3. package/dist/api-workflow.d.ts.map +1 -1
  4. package/dist/api-workflow.js +1 -1
  5. package/dist/api.d.ts +3 -3
  6. package/dist/api.d.ts.map +1 -1
  7. package/dist/api.js +5 -7
  8. package/dist/index.d.ts +1 -0
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +6 -1
  11. package/dist/internal/builtins.d.ts +20 -3
  12. package/dist/internal/builtins.d.ts.map +1 -1
  13. package/dist/internal/builtins.js +68 -4
  14. package/dist/internal/errors.d.ts +1 -1
  15. package/dist/internal/errors.d.ts.map +1 -1
  16. package/dist/internal/errors.js +2 -2
  17. package/dist/nest-builder.d.ts +2 -0
  18. package/dist/nest-builder.d.ts.map +1 -0
  19. package/dist/nest-builder.js +2 -0
  20. package/dist/nest-vercel-builder.d.ts +2 -0
  21. package/dist/nest-vercel-builder.d.ts.map +1 -0
  22. package/dist/nest-vercel-builder.js +2 -0
  23. package/dist/observability.d.ts +1 -1
  24. package/dist/observability.js +2 -2
  25. package/dist/runtime.d.ts +2 -1
  26. package/dist/runtime.d.ts.map +1 -1
  27. package/dist/runtime.js +4 -1
  28. package/docs/ai/chat-session-modeling.mdx +176 -422
  29. package/docs/ai/defining-tools.mdx +6 -7
  30. package/docs/ai/human-in-the-loop.mdx +11 -11
  31. package/docs/ai/index.mdx +71 -75
  32. package/docs/ai/message-queueing.mdx +71 -110
  33. package/docs/ai/meta.json +1 -0
  34. package/docs/ai/resumable-streams.mdx +40 -28
  35. package/docs/ai/sleep-and-delays.mdx +10 -10
  36. package/docs/ai/streaming-updates-from-tools.mdx +6 -6
  37. package/docs/api-reference/index.mdx +25 -1
  38. package/docs/api-reference/meta.json +8 -0
  39. package/docs/api-reference/vitest/index.mdx +9 -15
  40. package/docs/api-reference/workflow/create-hook.mdx +89 -10
  41. package/docs/api-reference/workflow/create-webhook.mdx +16 -15
  42. package/docs/api-reference/workflow/define-hook.mdx +35 -33
  43. package/docs/api-reference/workflow/fatal-error.mdx +30 -8
  44. package/docs/api-reference/workflow/fetch.mdx +14 -10
  45. package/docs/api-reference/workflow/get-step-metadata.mdx +2 -2
  46. package/docs/api-reference/workflow/get-workflow-metadata.mdx +3 -3
  47. package/docs/api-reference/workflow/get-writable.mdx +7 -7
  48. package/docs/api-reference/workflow/index.mdx +4 -1
  49. package/docs/api-reference/workflow/retryable-error.mdx +1 -1
  50. package/docs/api-reference/workflow/set-attributes.mdx +61 -0
  51. package/docs/api-reference/workflow/sleep.mdx +4 -4
  52. package/docs/api-reference/workflow-ai/durable-agent.mdx +63 -101
  53. package/docs/api-reference/workflow-ai/index.mdx +5 -5
  54. package/docs/api-reference/workflow-ai/workflow-chat-transport.mdx +67 -24
  55. package/docs/api-reference/workflow-api/get-hook-by-token.mdx +26 -12
  56. package/docs/api-reference/workflow-api/get-run.mdx +43 -8
  57. package/docs/api-reference/workflow-api/index.mdx +6 -10
  58. package/docs/api-reference/workflow-api/resume-hook.mdx +73 -12
  59. package/docs/api-reference/workflow-api/resume-webhook.mdx +11 -9
  60. package/docs/api-reference/workflow-api/start.mdx +60 -13
  61. package/docs/api-reference/workflow-astro/index.mdx +18 -0
  62. package/docs/api-reference/workflow-astro/meta.json +4 -0
  63. package/docs/api-reference/workflow-astro/workflow.mdx +45 -0
  64. package/docs/api-reference/workflow-errors/entity-conflict-error.mdx +4 -4
  65. package/docs/api-reference/workflow-errors/hook-conflict-error.mdx +60 -0
  66. package/docs/api-reference/workflow-errors/hook-not-found-error.mdx +8 -8
  67. package/docs/api-reference/workflow-errors/index.mdx +88 -0
  68. package/docs/api-reference/workflow-errors/meta.json +6 -0
  69. package/docs/api-reference/workflow-errors/precondition-failed-error.mdx +68 -0
  70. package/docs/api-reference/workflow-errors/run-expired-error.mdx +2 -2
  71. package/docs/api-reference/workflow-errors/run-not-supported-error.mdx +58 -0
  72. package/docs/api-reference/workflow-errors/step-not-registered-error.mdx +5 -5
  73. package/docs/api-reference/workflow-errors/throttle-error.mdx +2 -2
  74. package/docs/api-reference/workflow-errors/too-early-error.mdx +2 -2
  75. package/docs/api-reference/workflow-errors/workflow-error.mdx +52 -0
  76. package/docs/api-reference/workflow-errors/workflow-not-registered-error.mdx +5 -6
  77. package/docs/api-reference/workflow-errors/workflow-run-cancelled-error.mdx +6 -6
  78. package/docs/api-reference/workflow-errors/workflow-run-failed-error.mdx +5 -5
  79. package/docs/api-reference/workflow-errors/workflow-run-not-completed-error.mdx +58 -0
  80. package/docs/api-reference/workflow-errors/workflow-run-not-found-error.mdx +4 -4
  81. package/docs/api-reference/workflow-errors/workflow-runtime-error.mdx +58 -0
  82. package/docs/api-reference/workflow-errors/workflow-world-error.mdx +8 -8
  83. package/docs/api-reference/workflow-globals.mdx +14 -10
  84. package/docs/api-reference/workflow-nest/configure-workflow-controller.mdx +33 -0
  85. package/docs/api-reference/workflow-nest/index.mdx +31 -0
  86. package/docs/api-reference/workflow-nest/meta.json +9 -0
  87. package/docs/api-reference/workflow-nest/nest-local-builder.mdx +64 -0
  88. package/docs/api-reference/workflow-nest/workflow-controller.mdx +40 -0
  89. package/docs/api-reference/workflow-nest/workflow-module.mdx +74 -0
  90. package/docs/api-reference/workflow-next/with-workflow.mdx +39 -17
  91. package/docs/api-reference/workflow-nitro/index.mdx +60 -0
  92. package/docs/api-reference/workflow-nuxt/index.mdx +48 -0
  93. package/docs/api-reference/workflow-observability/hydrate-data.mdx +35 -0
  94. package/docs/api-reference/workflow-observability/hydrate-resource-io.mdx +62 -0
  95. package/docs/api-reference/workflow-observability/index.mdx +62 -0
  96. package/docs/api-reference/workflow-observability/meta.json +11 -0
  97. package/docs/api-reference/workflow-observability/observability-revivers.mdx +50 -0
  98. package/docs/api-reference/workflow-observability/parse-class-name.mdx +41 -0
  99. package/docs/api-reference/workflow-observability/parse-step-name.mdx +40 -0
  100. package/docs/api-reference/workflow-observability/parse-workflow-name.mdx +55 -0
  101. package/docs/api-reference/workflow-runtime/create-world.mdx +39 -0
  102. package/docs/api-reference/workflow-runtime/get-world-handlers.mdx +44 -0
  103. package/docs/api-reference/{workflow-api → workflow-runtime}/get-world.mdx +11 -14
  104. package/docs/api-reference/workflow-runtime/health-check.mdx +50 -0
  105. package/docs/api-reference/workflow-runtime/index.mdx +41 -0
  106. package/docs/api-reference/workflow-runtime/meta.json +12 -0
  107. package/docs/api-reference/workflow-runtime/set-world.mdx +51 -0
  108. package/docs/api-reference/workflow-runtime/workflow-entrypoint.mdx +43 -0
  109. package/docs/api-reference/workflow-runtime/world/analytics.mdx +315 -0
  110. package/docs/api-reference/workflow-runtime/world/index.mdx +60 -0
  111. package/docs/api-reference/workflow-runtime/world/meta.json +4 -0
  112. package/docs/api-reference/workflow-runtime/world/queue.mdx +88 -0
  113. package/docs/api-reference/{workflow-api → workflow-runtime}/world/storage.mdx +98 -34
  114. package/docs/api-reference/{workflow-api → workflow-runtime}/world/streams.mdx +8 -8
  115. package/docs/api-reference/workflow-serde/index.mdx +1 -2
  116. package/docs/api-reference/workflow-serde/workflow-deserialize.mdx +3 -4
  117. package/docs/api-reference/workflow-serde/workflow-serialize.mdx +8 -8
  118. package/docs/api-reference/workflow-sveltekit/index.mdx +18 -0
  119. package/docs/api-reference/workflow-sveltekit/meta.json +4 -0
  120. package/docs/api-reference/workflow-sveltekit/workflow-plugin.mdx +42 -0
  121. package/docs/api-reference/workflow-vite/index.mdx +18 -0
  122. package/docs/api-reference/workflow-vite/meta.json +4 -0
  123. package/docs/api-reference/workflow-vite/workflow.mdx +48 -0
  124. package/docs/changelog/attributes-mvp.mdx +380 -0
  125. package/docs/changelog/batched-event-writes.mdx +79 -0
  126. package/docs/changelog/eager-processing.mdx +110 -436
  127. package/docs/changelog/index.mdx +4 -2
  128. package/docs/changelog/lazy-event-creation.md +127 -0
  129. package/docs/changelog/lazy-hook-resume.mdx +78 -0
  130. package/docs/changelog/meta.json +11 -1
  131. package/docs/changelog/resilient-resume.mdx +32 -0
  132. package/docs/changelog/resilient-start.mdx +33 -285
  133. package/docs/changelog/step-message-ownership.mdx +360 -0
  134. package/docs/changelog/turbo-mode.md +87 -0
  135. package/docs/comparisons/index.mdx +66 -0
  136. package/docs/comparisons/meta.json +11 -0
  137. package/docs/comparisons/workflow-sdk-vs-aws-agentcore.mdx +55 -0
  138. package/docs/comparisons/workflow-sdk-vs-aws-step-functions.mdx +111 -0
  139. package/docs/comparisons/workflow-sdk-vs-cloudflare-workflows.mdx +71 -0
  140. package/docs/comparisons/workflow-sdk-vs-inngest.mdx +102 -0
  141. package/docs/comparisons/workflow-sdk-vs-temporal.mdx +123 -0
  142. package/docs/comparisons/workflow-sdk-vs-trigger-dev.mdx +104 -0
  143. package/docs/configuration/build-and-diagnostics.mdx +70 -0
  144. package/docs/configuration/cli-and-web-ui.mdx +241 -0
  145. package/docs/configuration/framework-options.mdx +165 -0
  146. package/docs/configuration/index.mdx +32 -0
  147. package/docs/configuration/meta.json +12 -0
  148. package/docs/configuration/runtime-tuning.mdx +381 -0
  149. package/docs/configuration/worlds.mdx +313 -0
  150. package/docs/cookbook/advanced/child-workflows.mdx +211 -264
  151. package/docs/cookbook/advanced/meta.json +6 -1
  152. package/docs/cookbook/advanced/publishing-libraries.mdx +65 -56
  153. package/docs/cookbook/advanced/serializable-steps.mdx +48 -68
  154. package/docs/cookbook/advanced/upgrading-workflows.mdx +199 -0
  155. package/docs/cookbook/agent-patterns/agent-cancellation.mdx +78 -60
  156. package/docs/cookbook/agent-patterns/durable-agent.mdx +23 -131
  157. package/docs/cookbook/agent-patterns/human-in-the-loop.mdx +180 -195
  158. package/docs/cookbook/common-patterns/batching.mdx +18 -14
  159. package/docs/cookbook/common-patterns/idempotency.mdx +41 -53
  160. package/docs/cookbook/common-patterns/rate-limiting.mdx +8 -4
  161. package/docs/cookbook/common-patterns/saga.mdx +23 -19
  162. package/docs/cookbook/common-patterns/scheduling.mdx +34 -22
  163. package/docs/cookbook/common-patterns/sequential-and-parallel.mdx +29 -25
  164. package/docs/cookbook/common-patterns/timeouts.mdx +26 -21
  165. package/docs/cookbook/common-patterns/webhooks.mdx +10 -6
  166. package/docs/cookbook/common-patterns/workflow-composition.mdx +30 -27
  167. package/docs/cookbook/index.mdx +22 -21
  168. package/docs/cookbook/integrations/ai-sdk.mdx +86 -48
  169. package/docs/cookbook/integrations/chat-sdk.mdx +50 -33
  170. package/docs/cookbook/integrations/sandbox.mdx +62 -45
  171. package/docs/deploying.mdx +95 -0
  172. package/docs/errors/abort-signal-timeout-in-workflow.mdx +16 -12
  173. package/docs/errors/corrupted-event-log.mdx +39 -18
  174. package/docs/errors/deployment-mismatch.mdx +71 -0
  175. package/docs/errors/fetch-in-workflow.mdx +15 -14
  176. package/docs/errors/hook-conflict.mdx +69 -13
  177. package/docs/errors/index.mdx +2 -36
  178. package/docs/errors/node-js-module-in-workflow.mdx +9 -5
  179. package/docs/errors/replay-divergence.mdx +27 -0
  180. package/docs/errors/run-expired.mdx +85 -0
  181. package/docs/errors/runtime-decryption-failed.mdx +77 -0
  182. package/docs/errors/serialization-failed.mdx +44 -12
  183. package/docs/errors/start-invalid-workflow-function.mdx +9 -5
  184. package/docs/errors/step-executed-multiple-times.mdx +23 -0
  185. package/docs/errors/step-not-registered.mdx +6 -6
  186. package/docs/errors/timeout-in-workflow.mdx +12 -8
  187. package/docs/errors/webhook-invalid-respond-with-value.mdx +18 -18
  188. package/docs/errors/webhook-response-not-sent.mdx +20 -16
  189. package/docs/errors/workflow-not-registered.mdx +5 -5
  190. package/docs/foundations/cancellation.mdx +31 -32
  191. package/docs/foundations/errors-and-retries.mdx +42 -11
  192. package/docs/foundations/hooks.mdx +64 -35
  193. package/docs/foundations/idempotency.mdx +244 -12
  194. package/docs/foundations/index.mdx +1 -23
  195. package/docs/foundations/meta.json +2 -1
  196. package/docs/foundations/serialization.mdx +21 -22
  197. package/docs/foundations/starting-workflows.mdx +106 -30
  198. package/docs/foundations/streaming.mdx +108 -60
  199. package/docs/foundations/versioning.mdx +263 -0
  200. package/docs/foundations/workflows-and-steps.mdx +9 -9
  201. package/docs/getting-started/astro.mdx +22 -18
  202. package/docs/getting-started/express.mdx +15 -11
  203. package/docs/getting-started/fastify.mdx +15 -11
  204. package/docs/getting-started/hono.mdx +15 -11
  205. package/docs/getting-started/index.mdx +10 -3
  206. package/docs/getting-started/meta.json +3 -1
  207. package/docs/getting-started/nestjs.mdx +87 -20
  208. package/docs/getting-started/next.mdx +22 -16
  209. package/docs/getting-started/nitro.mdx +22 -18
  210. package/docs/getting-started/nuxt.mdx +15 -11
  211. package/docs/getting-started/python.mdx +190 -41
  212. package/docs/getting-started/react-router/index.mdx +33 -0
  213. package/docs/getting-started/react-router/meta.json +5 -0
  214. package/docs/getting-started/react-router/v7.mdx +237 -0
  215. package/docs/getting-started/react-router/v8.mdx +232 -0
  216. package/docs/getting-started/sveltekit.mdx +20 -16
  217. package/docs/getting-started/tanstack-start.mdx +17 -13
  218. package/docs/getting-started/vite.mdx +15 -11
  219. package/docs/how-it-works/cancellation.mdx +63 -63
  220. package/docs/how-it-works/code-transform.mdx +83 -67
  221. package/docs/how-it-works/encryption.mdx +30 -26
  222. package/docs/how-it-works/event-sourcing.mdx +125 -34
  223. package/docs/how-it-works/framework-integrations.mdx +96 -337
  224. package/docs/how-it-works/understanding-directives.mdx +22 -22
  225. package/docs/internal/index.mdx +6 -4
  226. package/docs/internal/meta.json +6 -1
  227. package/docs/internal/nitro-native-build.mdx +38 -0
  228. package/docs/internal/nitro-web-ui.mdx +24 -0
  229. package/docs/internal/serializable-abort-controller.mdx +7 -7
  230. package/docs/meta.json +3 -2
  231. package/docs/observability/attributes.mdx +134 -0
  232. package/docs/observability/index.mdx +32 -10
  233. package/docs/observability/meta.json +1 -1
  234. package/docs/observability/retention.mdx +95 -0
  235. package/docs/observability/tracing.mdx +124 -0
  236. package/docs/testing/index.mdx +36 -36
  237. package/docs/testing/server-based.mdx +10 -10
  238. package/docs/whats-new.mdx +186 -0
  239. package/package.json +17 -14
  240. package/docs/api-reference/workflow-api/world/index.mdx +0 -58
  241. package/docs/api-reference/workflow-api/world/meta.json +0 -4
  242. package/docs/api-reference/workflow-api/world/observability.mdx +0 -164
  243. package/docs/api-reference/workflow-api/world/queue.mdx +0 -86
  244. package/docs/deploying/building-a-world.mdx +0 -251
  245. package/docs/deploying/index.mdx +0 -95
  246. package/docs/deploying/meta.json +0 -4
  247. package/docs/deploying/world/local-world.mdx +0 -84
  248. package/docs/deploying/world/meta.json +0 -4
  249. package/docs/deploying/world/postgres-world.mdx +0 -224
  250. package/docs/deploying/world/vercel-world.mdx +0 -179
  251. package/docs/migration-guides/index.mdx +0 -34
  252. package/docs/migration-guides/meta.json +0 -9
  253. package/docs/migration-guides/migrating-from-aws-step-functions.mdx +0 -363
  254. package/docs/migration-guides/migrating-from-inngest.mdx +0 -314
  255. package/docs/migration-guides/migrating-from-temporal.mdx +0 -318
  256. package/docs/migration-guides/migrating-from-trigger-dev.mdx +0 -337
@@ -14,16 +14,15 @@ related:
14
14
 
15
15
  This page covers the details for some common patterns when defining tools for AI agents using Workflow SDK.
16
16
 
17
- Using DurableAgent, we model most tools as steps. These can be anything from a simple function call to a entire multi-day long workflow.
17
+ Using WorkflowAgent, we model most tools as steps. These can range from a single function call to an entire multi-day workflow.
18
18
 
19
19
  ## Accessing message context in tools
20
20
 
21
- Just like in regular AI SDK tool definitions, tool in DurableAgent are called with a first argument of the tool's input parameters, and a second argument of the tool call context.
21
+ As with regular AI SDK tool definitions, tools in WorkflowAgent receive the tool's input parameters as the first argument and the tool call context as the second.
22
22
 
23
- When you tool needs access to the full message history, you can access it via the `messages` property of the tool call context:
23
+ When your tool needs access to the full message history, you can access it via the `messages` property of the tool call context:
24
24
 
25
25
  ```typescript title="tools.ts" lineNumbers
26
- import { Experimental_Agent as Agent } from "ai";
27
26
  import type { ModelMessage } from "ai";
28
27
 
29
28
  async function getWeather(
@@ -34,9 +33,9 @@ async function getWeather(
34
33
  }
35
34
  ```
36
35
 
37
- ## Writing to Streams
36
+ ## Writing to streams
38
37
 
39
- As discussed in [Streaming Updates from Tools](/docs/ai/streaming-updates-from-tools), it's common to use a step just to call `getWritable()` for writing custom data parts to the stream.
38
+ As discussed in [Streaming Updates from Tools](/docs/ai/streaming-updates-from-tools), it's common to use a step only to call `getWritable()` for writing custom data parts to the stream.
40
39
 
41
40
  This can be made generic, by creating a helper step function to write arbitrary data to the stream:
42
41
 
@@ -53,7 +52,7 @@ async function writeToStream(data: any) {
53
52
  }
54
53
  ```
55
54
 
56
- ## Step-Level vs Workflow-Level Tools
55
+ ## Step-level vs workflow-level tools
57
56
 
58
57
  Tools can be implemented either at the step level or the workflow level, with different capabilities and constraints.
59
58
 
@@ -19,7 +19,7 @@ Workflow SDK's [webhook](/docs/api-reference/workflow/create-webhook) and [hook]
19
19
 
20
20
  If you need to react to external events programmatically, see the [hooks](/docs/foundations/hooks) documentation for more information. This part of the guide will focus on the human-in-the-loop pattern, which is a subset of the more general hook pattern.
21
21
 
22
- ## How It Works
22
+ ## How it works
23
23
 
24
24
  <Steps>
25
25
 
@@ -45,9 +45,9 @@ The workflow receives the approval data and resumes execution.
45
45
 
46
46
  </Steps>
47
47
 
48
- While this demo will use a client side button for human approval, you could just as easily create a webhook and send the approval link over email or slack to resume the agent.
48
+ While this demo uses a client-side button for human approval, you could instead create a webhook and send the approval link over email or Slack to resume the agent.
49
49
 
50
- ## Creating a Booking Approval Tool
50
+ ## Creating a booking approval tool
51
51
 
52
52
  Add a tool that allows the agent to deliberately pause execution until a human approves or rejects a flight booking:
53
53
 
@@ -55,7 +55,7 @@ Add a tool that allows the agent to deliberately pause execution until a human a
55
55
 
56
56
  <Step>
57
57
 
58
- ### Define the Hook
58
+ ### Define the hook
59
59
 
60
60
  Create a typed hook with a Zod schema for validation:
61
61
 
@@ -78,7 +78,7 @@ export const bookingApprovalHook = defineHook({
78
78
 
79
79
  <Step>
80
80
 
81
- ### Implement the Tool
81
+ ### Implement the tool
82
82
 
83
83
  Create a tool that creates a hook instance using the tool call ID as the token. The UI will use this ID to submit the approval.
84
84
 
@@ -126,14 +126,14 @@ export const flightBookingTools = {
126
126
  ```
127
127
 
128
128
  <Callout type="info">
129
- Note that the `defineHook().create()` function must be called from within a workflow context, not from within a step. This is why `executeBookingApproval` does not have `"use step"` - it runs in the workflow context where hooks are available.
129
+ Call `defineHook().create()` from within a workflow context, not from within a step. `executeBookingApproval` does not have `"use step"` because it runs in the workflow context where hooks are available.
130
130
  </Callout>
131
131
 
132
132
  </Step>
133
133
 
134
134
  <Step>
135
135
 
136
- ### Create the API Route
136
+ ### Create the API route
137
137
 
138
138
  Create a new API endpoint that the UI will call to submit the approval decision:
139
139
 
@@ -158,7 +158,7 @@ export async function POST(request: Request) {
158
158
 
159
159
  <Step>
160
160
 
161
- ### Create the Approval Component
161
+ ### Create the approval component
162
162
 
163
163
  Build a new component that reacts to the tool call data, and allows the user to approve or reject the booking:
164
164
 
@@ -253,7 +253,7 @@ export function BookingApproval({ toolCallId, input, output }: BookingApprovalPr
253
253
 
254
254
  <Step>
255
255
 
256
- ### Show the Tool Status in the UI
256
+ ### Show the tool status in the UI
257
257
 
258
258
  Use the component we just created to render the tool call and approval controls in your chat interface:
259
259
 
@@ -332,7 +332,7 @@ export default function ChatPage() {
332
332
 
333
333
  </Steps>
334
334
 
335
- ## Using Webhooks Directly
335
+ ## Using webhooks directly
336
336
 
337
337
  For simpler cases where you don't need type-safe validation or programmatic resumption, you can use [`createWebhook()`](/docs/api-reference/workflow/create-webhook) directly. This generates a unique URL that can be called to resume the workflow:
338
338
 
@@ -367,7 +367,7 @@ The webhook URL can be called directly with a POST request containing the approv
367
367
  - Payment provider callbacks
368
368
  - Email-based approval links
369
369
 
370
- ## Related Documentation
370
+ ## Related documentation
371
371
 
372
372
  - [Hooks & Webhooks](/docs/foundations/hooks) - Complete guide to hooks and webhooks
373
373
  - [`createWebhook()` API Reference](/docs/api-reference/workflow/create-webhook) - Webhook configuration options
package/docs/ai/index.mdx CHANGED
@@ -3,6 +3,7 @@ title: Building Durable AI Agents
3
3
  description: Build AI agents that survive crashes, scale across requests, and maintain state with durable LLM tool-call loops.
4
4
  type: overview
5
5
  summary: Convert a basic AI chat app into a durable, resumable agent using Workflow SDK.
6
+ manualCards: true
6
7
  related:
7
8
  - /docs/foundations/workflows-and-steps
8
9
  - /docs/foundations/streaming
@@ -21,7 +22,7 @@ Workflow SDK makes your agents production-ready, by turning them into durable, r
21
22
 
22
23
  This guide walks you through converting a basic AI chat app into a durable AI agent using Workflow SDK.
23
24
 
24
- ## Why Durable Agents?
25
+ ## Why durable agents?
25
26
 
26
27
  Aside from the usual challenges of getting your long-running tasks to be production-ready, building mature AI agents typically requires solving several **additional challenges**:
27
28
 
@@ -30,22 +31,22 @@ Aside from the usual challenges of getting your long-running tasks to be product
30
31
  - **Resumability**: Resuming streams requires not just storing your messages, but also storing streams, and piping them across services.
31
32
  - **Human-in-the-loop**: Your client, API, and async job orchestration need to work together to create, track, route to, and display human approval requests, or similar webhook operations.
32
33
 
33
- Workflow SDK provides all of these capabilities out of the box. Your agent becomes a workflow, your tools become steps, and the framework handles interplay with your existing infrastructure.
34
+ Workflow SDK provides all of these capabilities without additional infrastructure. Your agent becomes a workflow, your tools become steps, and the framework handles interplay with your existing infrastructure.
34
35
 
35
- ## Getting Started
36
+ ## Getting started
36
37
 
37
38
  To make an Agent durable, we first need an Agent, which we'll be setting up here. If you already have an app you'd like to follow along with, you can skip this section.
38
39
 
39
- For our example, we'll need an app with a simple chat interface and an API route calling an LLM, so that we can add Workflow SDK to it. We'll use the [Flight Booking Agent](https://github.com/vercel/workflow-examples/tree/main/flight-booking-app) example as a starting point, which comes with a chat interface built using Next.js, AI SDK, and Shadcn UI.
40
+ For our example, we'll need an app with a basic chat interface and an API route calling an LLM, so that we can add Workflow SDK to it. We'll use the [Flight Booking Agent](https://github.com/vercel/workflow-examples/tree/main/flight-booking-app) example as a starting point, which comes with a chat interface built using Next.js, AI SDK, and Shadcn UI.
40
41
 
41
42
  <Steps>
42
43
 
43
44
  <Step>
44
45
  ### Clone example app
45
46
 
46
- We'll need an app with a simple chat interface and an API route calling an LLM, so that we can add Workflow SDK to it. For the follow-along steps, we'll use the [Flight Booking Agent](https://github.com/vercel/workflow-examples/tree/main/flight-booking-app) example as a starting point, which comes with a chat interface built using Next.js, AI SDK, and Shadcn UI.
47
+ We'll need an app with a basic chat interface and an API route calling an LLM, so that we can add Workflow SDK to it. For the follow-along steps, we'll use the [Flight Booking Agent](https://github.com/vercel/workflow-examples/tree/main/flight-booking-app) example as a starting point, which comes with a chat interface built using Next.js, AI SDK, and Shadcn UI.
47
48
 
48
- If you have your own project, you can skip this step, and simply apply the changes of the following steps to your own project.
49
+ If you have your own project, skip this step and apply the changes in the following steps to your project.
49
50
 
50
51
  ```bash
51
52
  git clone https://github.com/vercel/workflow-examples -b plain-ai-sdk
@@ -56,55 +57,49 @@ cd workflow-examples/flight-booking-app
56
57
 
57
58
  <Step>
58
59
 
59
- ### Set up API keys
60
+ ### Configure model access
60
61
 
61
- In order to connect to an LLM, we'll need to set up an API key. The easiest way to do this is to use Vercel Gateway (works with all providers at zero markup), or you can configure a custom provider.
62
- <Tabs items={['Gateway', 'Custom Provider']}>
62
+ <Tabs items={['AI Gateway', 'Provider package']}>
63
63
 
64
- <Tab value="Gateway">
64
+ <Tab value="AI Gateway">
65
65
 
66
- Get a Gateway API key from the [Vercel Gateway](https://vercel.com/docs/gateway/api-reference/overview) page.
66
+ AI SDK uses [Vercel AI Gateway](https://vercel.com/docs/ai-gateway) as its default global provider, so plain `"provider/model"` strings need no provider-specific package. Vercel deployments authenticate with OIDC automatically. For local development, link the project and pull a short-lived OIDC token:
67
67
 
68
- Then add it to your `.env.local` file:
69
-
70
- ```bash title=".env.local" lineNumbers
71
- GATEWAY_API_KEY=...
68
+ ```bash
69
+ vercel link
70
+ vercel env pull .env.local
72
71
  ```
73
72
 
73
+ You can alternatively set `AI_GATEWAY_API_KEY` from the [AI Gateway authentication](https://vercel.com/docs/ai-gateway/authentication) page.
74
+
74
75
  </Tab>
75
76
 
76
- <Tab value="Custom Provider">
77
+ <Tab value="Provider package">
77
78
 
78
- This is an example of how to use the OpenAI provider for AI SDK. For details on other providers and more details, see the [AI SDK provider guide](https://ai-sdk.dev/providers/ai-sdk-providers).
79
+ `WorkflowAgent` accepts any AI SDK provider. To use OpenAI, install its provider package:
79
80
 
80
81
  ```package-install
81
82
  npm i @ai-sdk/openai
82
83
  ```
83
84
 
84
- Set your OpenAI API key in your environment variables:
85
+ Set the provider's API key:
85
86
 
86
87
  ```bash title=".env.local" lineNumbers
87
88
  OPENAI_API_KEY=...
88
89
  ```
89
90
 
90
- Then modify your API endpoint to use the OpenAI provider:
91
+ Then construct the model with the provider package:
91
92
 
92
- {/* @skip-typecheck: incomplete code sample */}
93
- ```typescript title="app/api/chat/route.ts" lineNumbers
94
- // ...
95
- import { openai } from "@workflow/ai/openai"; // [!code highlight]
93
+ ```typescript
94
+ import { openai } from "@ai-sdk/openai";
96
95
 
97
- export async function POST(req: Request) {
98
- // ...
99
- const agent = new Agent({
100
- // This uses the OPENAI_API_KEY environment variable by default, but you
101
- // can also pass { apiKey: string } as an option.
102
- model: openai("gpt-5.1"), // [!code highlight]
103
- // ...
104
- });
96
+ const model = openai("gpt-5.6-sol");
105
97
  ```
106
98
 
99
+ See the [AI SDK provider guide](https://ai-sdk.dev/providers/ai-sdk-providers) for Anthropic, Google, Amazon Bedrock, and other providers.
100
+
107
101
  </Tab>
102
+
108
103
  </Tabs>
109
104
  </Step>
110
105
 
@@ -112,24 +107,25 @@ export async function POST(req: Request) {
112
107
 
113
108
  ### Get familiar with the code
114
109
 
115
- Let's take a moment to see what we're working with. Run the app with `npm run dev` and open [http://localhost:3000](http://localhost:3000) in your browser. You should see a simple chat interface to play with. Go ahead and give it a try.
110
+ Run the app with `npm run dev` and open [http://localhost:3000](http://localhost:3000) in your browser. You should see a basic chat interface to test.
116
111
 
117
- The core code that makes all of this happen is quite simple. Here's a breakdown of the main parts. Note that there's no changes needed here, we're simply taking a look at the code to understand what's happening.
112
+ The following sections break down the core code. You don't need to make changes yet.
118
113
 
119
114
  <Tabs items={['API Route', 'Tools', 'Client']}>
120
115
 
121
116
  <Tab value="API Route">
122
117
 
123
- Our API route makes a simple call to [AI SDK's `Agent` class](https://ai-sdk.dev/docs/agents/overview), which is a simple wrapper around [AI SDK's `streamText` function](https://ai-sdk.dev/docs/reference/ai-sdk-core/stream-text#streamtext). This is also where we pass tools to the agent.
118
+ Our API route calls [AI SDK's `ToolLoopAgent` class](https://ai-sdk.dev/docs/agents/overview), which encapsulates the LLM call, tool execution loop, and stopping conditions on top of [AI SDK's `streamText` function](https://ai-sdk.dev/docs/reference/ai-sdk-core/stream-text#streamtext). This is also where we pass tools to the agent.
124
119
 
125
120
  ```typescript title="app/api/chat/route.ts" lineNumbers
126
- import { Experimental_Agent as Agent } from "ai";
127
- import type { LanguageModel } from "ai";
121
+ import { ToolLoopAgent } from "ai";
122
+ import type { UIMessage } from "ai";
123
+ import { convertToModelMessages, createUIMessageStreamResponse } from "ai";
128
124
 
129
125
  export async function POST(req: Request) {
130
126
  const { messages }: { messages: UIMessage[] } = await req.json();
131
- const agent = new Agent({ // [!code highlight]
132
- model: gateway("bedrock/claude-4-5-haiku-20251001-v1"),
127
+ const agent = new ToolLoopAgent({ // [!code highlight]
128
+ model: "spacexai/grok-4.6",
133
129
  instructions: FLIGHT_ASSISTANT_PROMPT,
134
130
  tools: flightBookingTools,
135
131
  });
@@ -168,7 +164,7 @@ async function searchFlights({ from, to, date }: { from: string; to: string; dat
168
164
 
169
165
  <Tab value="Client">
170
166
 
171
- Our `ChatPage` component has a lot of logic for nicely displaying the chat messages, but at it's core, it's simply managing input/output for the [`useChat` hook](https://ai-sdk.dev/docs/reference/ai-sdk-ui/use-chat#usechat) from AI SDK.
167
+ Our `ChatPage` component contains logic for displaying chat messages, but its core responsibility is managing input and output for the [`useChat` hook](https://ai-sdk.dev/docs/reference/ai-sdk-ui/use-chat#usechat) from AI SDK.
172
168
 
173
169
  ```typescript title="app/chat.tsx" lineNumbers
174
170
  "use client";
@@ -226,12 +222,12 @@ Now that we have a basic agent using AI SDK, we can modify it to make it durable
226
222
  <Steps>
227
223
  <Step>
228
224
 
229
- ### Install Dependencies
225
+ ### Install dependencies
230
226
 
231
227
  Add the Workflow SDK packages to your project:
232
228
 
233
229
  ```package-install
234
- npm i workflow @workflow/ai
230
+ npm i workflow @ai-sdk/workflow
235
231
  ```
236
232
 
237
233
  and extend the Next.js config to transform your workflow code (see [Getting Started](/docs/getting-started/next) for more details).
@@ -251,68 +247,67 @@ export default withWorkflow(nextConfig);
251
247
 
252
248
  <Step>
253
249
 
254
- ### Create a Workflow Function
250
+ ### Create a workflow function
255
251
 
256
252
  Move the agent logic into a separate function, which will serve as our workflow definition.
257
253
 
258
- {/* @skip-typecheck: Shows two mutually exclusive model options */}
259
254
  ```typescript title="workflows/chat/workflow.ts" lineNumbers
260
- import { DurableAgent } from "@workflow/ai/agent"; // [!code highlight]
255
+ import { WorkflowAgent, type ModelCallStreamPart } from "@ai-sdk/workflow"; // [!code highlight]
261
256
  import { getWritable } from "workflow"; // [!code highlight]
262
- import { tools } from "@/ai/tools";
263
- import { openai } from "@workflow/ai/openai";
264
- import type { ModelMessage, UIMessageChunk } from "ai";
257
+ import { flightBookingTools, FLIGHT_ASSISTANT_PROMPT } from "@/ai/tools";
258
+ import { convertToModelMessages, type UIMessage } from "ai";
265
259
 
266
- export async function chatWorkflow(messages: ModelMessage[]) {
260
+ export async function chatWorkflow(messages: UIMessage[]) {
267
261
  "use workflow"; // [!code highlight]
268
262
 
269
- const writable = getWritable<UIMessageChunk>(); // [!code highlight]
270
-
271
- const agent = new DurableAgent({ // [!code highlight]
272
-
273
- // If using AI Gateway, just specify the model name as a string:
274
- model: "bedrock/claude-4-5-haiku-20251001-v1", // [!code highlight]
275
-
276
- // ELSE if using a custom provider, pass the provider call as an argument:
277
- model: openai("gpt-5.1"), // [!code highlight]
263
+ const writable = getWritable<ModelCallStreamPart>(); // [!code highlight]
278
264
 
265
+ const agent = new WorkflowAgent({ // [!code highlight]
266
+ // Plain model strings use Vercel AI Gateway.
267
+ model: "spacexai/grok-4.6", // [!code highlight]
279
268
  instructions: FLIGHT_ASSISTANT_PROMPT,
280
269
  tools: flightBookingTools,
281
270
  });
282
271
 
272
+ const modelMessages = await convertToModelMessages(messages); // [!code highlight]
273
+
283
274
  await agent.stream({ // [!code highlight]
284
- messages,
275
+ messages: modelMessages,
285
276
  writable,
286
277
  });
287
278
  }
288
279
  ```
289
280
 
281
+ <Callout type="info">
282
+ `WorkflowAgent` accepts any AI SDK provider. Import the provider and pass its model instance, for example `model: openai("gpt-5.6-sol")` from `@ai-sdk/openai`. The rest of the integration is unchanged.
283
+ </Callout>
284
+
290
285
  Key changes:
291
286
 
292
287
  - Add the `"use workflow"` directive to mark our Agent as a workflow function
293
- - Replaced `Agent` with [`DurableAgent`](/docs/api-reference/workflow-ai/durable-agent) from `@workflow/ai/agent`. This ensures that all calls to the LLM are executed as "steps", and results are aggregated within the workflow context (see [Workflows and Steps](/docs/foundations/workflows-and-steps) for more details on how workflows/steps are defined).
294
- - Use [`getWritable()`](/docs/api-reference/workflow/get-writable) to get a stream for agent output. This stream is persistent, and API endpoints can read from a run's stream at any time.
288
+ - Replace the in-memory agent with [`WorkflowAgent`](https://ai-sdk.dev/v7/docs/agents/workflow-agent#workflowagent) from `@ai-sdk/workflow`. This runs the agent loop inside a workflow, persists state across step boundaries, and lets tool executions marked with `"use step"` retry automatically.
289
+ - Convert AI SDK `UIMessage` values to model messages inside the workflow before calling `agent.stream()`.
290
+ - Use [`getWritable()`](/docs/api-reference/workflow/get-writable) to get a stream for agent output. `WorkflowAgent` writes `ModelCallStreamPart` chunks to this persistent stream, and API endpoints can read from a run's stream at any time.
295
291
  </Step>
296
292
 
297
293
  <Step>
298
- ### Update the API Route
294
+ ### Update the API route
299
295
 
300
296
  Remove the agent call that we just extracted, and replace it with a call to `start()` to run the workflow:
301
297
 
302
298
  ```typescript title="app/api/chat/route.ts" lineNumbers
303
- import type { UIMessage } from "ai";
304
- import { convertToModelMessages, createUIMessageStreamResponse } from "ai";
299
+ import { createModelCallToUIChunkTransform } from "@ai-sdk/workflow";
300
+ import { createUIMessageStreamResponse, type UIMessage } from "ai";
305
301
  import { start } from "workflow/api";
306
302
  import { chatWorkflow } from "@/workflows/chat/workflow";
307
303
 
308
304
  export async function POST(req: Request) {
309
305
  const { messages }: { messages: UIMessage[] } = await req.json();
310
- const modelMessages = await convertToModelMessages(messages);
311
306
 
312
- const run = await start(chatWorkflow, [modelMessages]); // [!code highlight]
307
+ const run = await start(chatWorkflow, [messages]); // [!code highlight]
313
308
 
314
309
  return createUIMessageStreamResponse({
315
- stream: run.readable, // [!code highlight]
310
+ stream: run.readable.pipeThrough(createModelCallToUIChunkTransform()), // [!code highlight]
316
311
  });
317
312
  }
318
313
  ```
@@ -320,12 +315,13 @@ export async function POST(req: Request) {
320
315
  Key changes:
321
316
 
322
317
  - Call `start()` to run the workflow function. This returns a `Run` object, which contains the run ID and the readable stream (see [Starting Workflows](/docs/foundations/starting-workflows) for more details on the `Run` object).
323
- - Pass the `writable` to `agent.stream()` instead of returning a stream directly, ensuring all the Agent output is written to to the run's stream.
318
+ - Pass the `writable` to `agent.stream()` instead of returning a stream directly, ensuring all the Agent output is written to the run's stream.
319
+ - Pipe the readable stream through `createModelCallToUIChunkTransform()` so the raw model-call chunks become AI SDK UI message chunks before they are returned to the client.
324
320
 
325
321
  </Step>
326
322
 
327
323
  <Step>
328
- ### Convert Tools to Steps
324
+ ### Convert tools to steps
329
325
 
330
326
  Mark all tool definitions with `"use step"` to make them durable. This enables automatic retries and observability for each tool call:
331
327
 
@@ -377,14 +373,14 @@ export async function checkBaggageAllowance(
377
373
 
378
374
  With `"use step"`:
379
375
 
380
- - The tool execution runs in a separate step with full Node.js access. In production, each step is executed in a separate worker process, which scales automatically with your workload.
376
+ - The tool execution runs as a durable step with full Node.js access. The combined runtime may execute it inline in the flow request or resume it through the workflow queue, and can scale queued work with your workload.
381
377
  - Failed tool calls are automatically retried (up to 3 times by default). See [Errors and Retries](/docs/foundations/errors-and-retries) for more details.
382
378
  - Each tool execution appears as a discrete step in observability tools. See [Observability](/docs/observability) for more details.
383
379
  </Step>
384
380
 
385
381
  </Steps>
386
382
 
387
- That's all you need to do to convert your basic AI SDK agent into a durable agent. If you run your development server, and send a chat message, you should see your agent respond just as before, but now with added durability and observability.
383
+ Your basic AI SDK agent is now durable. Run your development server and send a chat message. The agent should respond as before, with added durability and observability.
388
384
 
389
385
  ## Observability
390
386
 
@@ -396,9 +392,9 @@ npx workflow web
396
392
 
397
393
  This opens a local dashboard showing all workflow runs and their status, as well as a trace viewer to inspect the workflow in detail, including retry attempts, and the data being passed between steps.
398
394
 
399
- ## Next Steps
395
+ ## Next steps
400
396
 
401
- Now that you have a basic durable agent, it's a only a short step to add these additional features:
397
+ Now that you have a basic durable agent, it's only a short step to add these additional features:
402
398
 
403
399
  <Cards>
404
400
  <Card title="Streaming Updates from Tools" href="/docs/ai/streaming-updates-from-tools">
@@ -415,14 +411,14 @@ Now that you have a basic durable agent, it's a only a short step to add these a
415
411
  </Card>
416
412
  </Cards>
417
413
 
418
- ## Complete Example
414
+ ## Complete example
419
415
 
420
416
  A complete example that includes all of the above, plus all of the "next steps" features is available on the main branch of the [Flight Booking Agent](https://github.com/vercel/workflow-examples/tree/main/flight-booking-app) example.
421
417
 
422
- ## Related Documentation
418
+ ## Related documentation
423
419
 
424
420
  - [Tools](/docs/ai/defining-tools) - Patterns for defining tools for your agent
425
- - [`DurableAgent` API Reference](/docs/api-reference/workflow-ai/durable-agent) - Full API documentation
421
+ - [`WorkflowAgent`](https://ai-sdk.dev/v7/docs/agents/workflow-agent#workflowagent) - AI SDK API for durable, resumable agents
426
422
  - [Workflows and Steps](/docs/foundations/workflows-and-steps) - Core concepts
427
423
  - [Streaming](/docs/foundations/streaming) - In-depth streaming guide
428
424
  - [Errors and Retries](/docs/foundations/errors-and-retries) - Error handling patterns