workflow 5.0.0-beta.5 → 5.0.0-beta.50
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.
- package/README.md +68 -23
- package/dist/api-workflow.d.ts +1 -1
- package/dist/api-workflow.d.ts.map +1 -1
- package/dist/api-workflow.js +1 -1
- package/dist/api.d.ts +3 -3
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +5 -7
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -1
- package/dist/internal/builtins.d.ts +20 -3
- package/dist/internal/builtins.d.ts.map +1 -1
- package/dist/internal/builtins.js +68 -4
- package/dist/internal/errors.d.ts +1 -1
- package/dist/internal/errors.d.ts.map +1 -1
- package/dist/internal/errors.js +2 -2
- package/dist/nest-builder.d.ts +2 -0
- package/dist/nest-builder.d.ts.map +1 -0
- package/dist/nest-builder.js +2 -0
- package/dist/nest-vercel-builder.d.ts +2 -0
- package/dist/nest-vercel-builder.d.ts.map +1 -0
- package/dist/nest-vercel-builder.js +2 -0
- package/dist/observability.d.ts +1 -1
- package/dist/observability.js +2 -2
- package/dist/runtime.d.ts +2 -1
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +4 -1
- package/docs/ai/chat-session-modeling.mdx +29 -26
- package/docs/ai/defining-tools.mdx +6 -7
- package/docs/ai/human-in-the-loop.mdx +11 -11
- package/docs/ai/index.mdx +50 -45
- package/docs/ai/message-queueing.mdx +16 -16
- package/docs/ai/meta.json +1 -0
- package/docs/ai/resumable-streams.mdx +40 -28
- package/docs/ai/sleep-and-delays.mdx +10 -10
- package/docs/ai/streaming-updates-from-tools.mdx +6 -6
- package/docs/api-reference/index.mdx +24 -0
- package/docs/api-reference/meta.json +8 -0
- package/docs/api-reference/vitest/index.mdx +9 -15
- package/docs/api-reference/workflow/create-hook.mdx +89 -10
- package/docs/api-reference/workflow/create-webhook.mdx +16 -15
- package/docs/api-reference/workflow/define-hook.mdx +35 -33
- package/docs/api-reference/workflow/fatal-error.mdx +30 -8
- package/docs/api-reference/workflow/fetch.mdx +14 -10
- package/docs/api-reference/workflow/get-step-metadata.mdx +2 -2
- package/docs/api-reference/workflow/get-workflow-metadata.mdx +3 -3
- package/docs/api-reference/workflow/get-writable.mdx +7 -7
- package/docs/api-reference/workflow/index.mdx +4 -1
- package/docs/api-reference/workflow/retryable-error.mdx +1 -1
- package/docs/api-reference/workflow/set-attributes.mdx +61 -0
- package/docs/api-reference/workflow/sleep.mdx +4 -4
- package/docs/api-reference/workflow-ai/durable-agent.mdx +48 -86
- package/docs/api-reference/workflow-ai/index.mdx +3 -3
- package/docs/api-reference/workflow-ai/workflow-chat-transport.mdx +67 -24
- package/docs/api-reference/workflow-api/get-hook-by-token.mdx +26 -12
- package/docs/api-reference/workflow-api/get-run.mdx +43 -8
- package/docs/api-reference/workflow-api/index.mdx +6 -10
- package/docs/api-reference/workflow-api/resume-hook.mdx +73 -12
- package/docs/api-reference/workflow-api/resume-webhook.mdx +11 -9
- package/docs/api-reference/workflow-api/start.mdx +60 -13
- package/docs/api-reference/workflow-astro/index.mdx +18 -0
- package/docs/api-reference/workflow-astro/meta.json +4 -0
- package/docs/api-reference/workflow-astro/workflow.mdx +45 -0
- package/docs/api-reference/workflow-errors/entity-conflict-error.mdx +4 -4
- package/docs/api-reference/workflow-errors/hook-conflict-error.mdx +60 -0
- package/docs/api-reference/workflow-errors/hook-not-found-error.mdx +8 -8
- package/docs/api-reference/workflow-errors/index.mdx +88 -0
- package/docs/api-reference/workflow-errors/meta.json +6 -0
- package/docs/api-reference/workflow-errors/precondition-failed-error.mdx +68 -0
- package/docs/api-reference/workflow-errors/run-expired-error.mdx +2 -2
- package/docs/api-reference/workflow-errors/run-not-supported-error.mdx +58 -0
- package/docs/api-reference/workflow-errors/step-not-registered-error.mdx +5 -5
- package/docs/api-reference/workflow-errors/throttle-error.mdx +2 -2
- package/docs/api-reference/workflow-errors/too-early-error.mdx +2 -2
- package/docs/api-reference/workflow-errors/workflow-error.mdx +52 -0
- package/docs/api-reference/workflow-errors/workflow-not-registered-error.mdx +5 -6
- package/docs/api-reference/workflow-errors/workflow-run-cancelled-error.mdx +6 -6
- package/docs/api-reference/workflow-errors/workflow-run-failed-error.mdx +5 -5
- package/docs/api-reference/workflow-errors/workflow-run-not-completed-error.mdx +58 -0
- package/docs/api-reference/workflow-errors/workflow-run-not-found-error.mdx +4 -4
- package/docs/api-reference/workflow-errors/workflow-runtime-error.mdx +58 -0
- package/docs/api-reference/workflow-errors/workflow-world-error.mdx +8 -8
- package/docs/api-reference/workflow-globals.mdx +14 -10
- package/docs/api-reference/workflow-nest/configure-workflow-controller.mdx +33 -0
- package/docs/api-reference/workflow-nest/index.mdx +31 -0
- package/docs/api-reference/workflow-nest/meta.json +9 -0
- package/docs/api-reference/workflow-nest/nest-local-builder.mdx +64 -0
- package/docs/api-reference/workflow-nest/workflow-controller.mdx +40 -0
- package/docs/api-reference/workflow-nest/workflow-module.mdx +74 -0
- package/docs/api-reference/workflow-next/with-workflow.mdx +39 -17
- package/docs/api-reference/workflow-nitro/index.mdx +60 -0
- package/docs/api-reference/workflow-nuxt/index.mdx +48 -0
- package/docs/api-reference/workflow-observability/hydrate-data.mdx +35 -0
- package/docs/api-reference/workflow-observability/hydrate-resource-io.mdx +62 -0
- package/docs/api-reference/workflow-observability/index.mdx +62 -0
- package/docs/api-reference/workflow-observability/meta.json +11 -0
- package/docs/api-reference/workflow-observability/observability-revivers.mdx +50 -0
- package/docs/api-reference/workflow-observability/parse-class-name.mdx +41 -0
- package/docs/api-reference/workflow-observability/parse-step-name.mdx +40 -0
- package/docs/api-reference/workflow-observability/parse-workflow-name.mdx +55 -0
- package/docs/api-reference/workflow-runtime/create-world.mdx +39 -0
- package/docs/api-reference/workflow-runtime/get-world-handlers.mdx +44 -0
- package/docs/api-reference/{workflow-api → workflow-runtime}/get-world.mdx +11 -14
- package/docs/api-reference/workflow-runtime/health-check.mdx +50 -0
- package/docs/api-reference/workflow-runtime/index.mdx +41 -0
- package/docs/api-reference/workflow-runtime/meta.json +12 -0
- package/docs/api-reference/workflow-runtime/set-world.mdx +51 -0
- package/docs/api-reference/workflow-runtime/workflow-entrypoint.mdx +43 -0
- package/docs/api-reference/workflow-runtime/world/analytics.mdx +315 -0
- package/docs/api-reference/workflow-runtime/world/index.mdx +60 -0
- package/docs/api-reference/workflow-runtime/world/meta.json +4 -0
- package/docs/api-reference/workflow-runtime/world/queue.mdx +88 -0
- package/docs/api-reference/{workflow-api → workflow-runtime}/world/storage.mdx +98 -34
- package/docs/api-reference/{workflow-api → workflow-runtime}/world/streams.mdx +8 -8
- package/docs/api-reference/workflow-serde/index.mdx +1 -2
- package/docs/api-reference/workflow-serde/workflow-deserialize.mdx +3 -4
- package/docs/api-reference/workflow-serde/workflow-serialize.mdx +8 -8
- package/docs/api-reference/workflow-sveltekit/index.mdx +18 -0
- package/docs/api-reference/workflow-sveltekit/meta.json +4 -0
- package/docs/api-reference/workflow-sveltekit/workflow-plugin.mdx +42 -0
- package/docs/api-reference/workflow-vite/index.mdx +18 -0
- package/docs/api-reference/workflow-vite/meta.json +4 -0
- package/docs/api-reference/workflow-vite/workflow.mdx +48 -0
- package/docs/changelog/attributes-mvp.mdx +380 -0
- package/docs/changelog/batched-event-writes.mdx +79 -0
- package/docs/changelog/eager-processing.mdx +110 -436
- package/docs/changelog/index.mdx +4 -2
- package/docs/changelog/lazy-event-creation.md +127 -0
- package/docs/changelog/lazy-hook-resume.mdx +78 -0
- package/docs/changelog/meta.json +11 -1
- package/docs/changelog/resilient-resume.mdx +32 -0
- package/docs/changelog/resilient-start.mdx +33 -285
- package/docs/changelog/step-message-ownership.mdx +360 -0
- package/docs/changelog/turbo-mode.md +87 -0
- package/docs/comparisons/index.mdx +66 -0
- package/docs/comparisons/meta.json +11 -0
- package/docs/comparisons/workflow-sdk-vs-aws-agentcore.mdx +55 -0
- package/docs/comparisons/workflow-sdk-vs-aws-step-functions.mdx +111 -0
- package/docs/comparisons/workflow-sdk-vs-cloudflare-workflows.mdx +71 -0
- package/docs/comparisons/workflow-sdk-vs-inngest.mdx +102 -0
- package/docs/comparisons/workflow-sdk-vs-temporal.mdx +123 -0
- package/docs/comparisons/workflow-sdk-vs-trigger-dev.mdx +104 -0
- package/docs/configuration/build-and-diagnostics.mdx +70 -0
- package/docs/configuration/cli-and-web-ui.mdx +241 -0
- package/docs/configuration/framework-options.mdx +165 -0
- package/docs/configuration/index.mdx +32 -0
- package/docs/configuration/meta.json +12 -0
- package/docs/configuration/runtime-tuning.mdx +376 -0
- package/docs/configuration/worlds.mdx +313 -0
- package/docs/cookbook/advanced/child-workflows.mdx +211 -264
- package/docs/cookbook/advanced/meta.json +6 -1
- package/docs/cookbook/advanced/publishing-libraries.mdx +65 -56
- package/docs/cookbook/advanced/serializable-steps.mdx +28 -20
- package/docs/cookbook/advanced/upgrading-workflows.mdx +199 -0
- package/docs/cookbook/agent-patterns/agent-cancellation.mdx +27 -19
- package/docs/cookbook/agent-patterns/durable-agent.mdx +14 -142
- package/docs/cookbook/agent-patterns/human-in-the-loop.mdx +30 -22
- package/docs/cookbook/common-patterns/batching.mdx +18 -14
- package/docs/cookbook/common-patterns/idempotency.mdx +41 -53
- package/docs/cookbook/common-patterns/rate-limiting.mdx +8 -4
- package/docs/cookbook/common-patterns/saga.mdx +23 -19
- package/docs/cookbook/common-patterns/scheduling.mdx +34 -22
- package/docs/cookbook/common-patterns/sequential-and-parallel.mdx +29 -25
- package/docs/cookbook/common-patterns/timeouts.mdx +26 -21
- package/docs/cookbook/common-patterns/webhooks.mdx +10 -6
- package/docs/cookbook/common-patterns/workflow-composition.mdx +30 -27
- package/docs/cookbook/index.mdx +22 -21
- package/docs/cookbook/integrations/ai-sdk.mdx +85 -47
- package/docs/cookbook/integrations/chat-sdk.mdx +50 -33
- package/docs/cookbook/integrations/sandbox.mdx +62 -45
- package/docs/deploying.mdx +95 -0
- package/docs/errors/abort-signal-timeout-in-workflow.mdx +16 -12
- package/docs/errors/corrupted-event-log.mdx +29 -18
- package/docs/errors/deployment-mismatch.mdx +71 -0
- package/docs/errors/fetch-in-workflow.mdx +11 -7
- package/docs/errors/hook-conflict.mdx +69 -13
- package/docs/errors/index.mdx +2 -36
- package/docs/errors/node-js-module-in-workflow.mdx +9 -5
- package/docs/errors/replay-divergence.mdx +27 -0
- package/docs/errors/run-expired.mdx +85 -0
- package/docs/errors/runtime-decryption-failed.mdx +77 -0
- package/docs/errors/serialization-failed.mdx +44 -12
- package/docs/errors/start-invalid-workflow-function.mdx +9 -5
- package/docs/errors/step-executed-multiple-times.mdx +23 -0
- package/docs/errors/step-not-registered.mdx +6 -6
- package/docs/errors/timeout-in-workflow.mdx +12 -8
- package/docs/errors/webhook-invalid-respond-with-value.mdx +18 -18
- package/docs/errors/webhook-response-not-sent.mdx +20 -16
- package/docs/errors/workflow-not-registered.mdx +5 -5
- package/docs/foundations/cancellation.mdx +31 -32
- package/docs/foundations/errors-and-retries.mdx +42 -11
- package/docs/foundations/hooks.mdx +64 -35
- package/docs/foundations/idempotency.mdx +244 -12
- package/docs/foundations/index.mdx +1 -23
- package/docs/foundations/meta.json +2 -1
- package/docs/foundations/serialization.mdx +21 -22
- package/docs/foundations/starting-workflows.mdx +106 -30
- package/docs/foundations/streaming.mdx +107 -59
- package/docs/foundations/versioning.mdx +263 -0
- package/docs/foundations/workflows-and-steps.mdx +9 -9
- package/docs/getting-started/astro.mdx +22 -18
- package/docs/getting-started/express.mdx +15 -11
- package/docs/getting-started/fastify.mdx +15 -11
- package/docs/getting-started/hono.mdx +15 -11
- package/docs/getting-started/index.mdx +10 -3
- package/docs/getting-started/meta.json +3 -1
- package/docs/getting-started/nestjs.mdx +87 -20
- package/docs/getting-started/next.mdx +22 -16
- package/docs/getting-started/nitro.mdx +22 -18
- package/docs/getting-started/nuxt.mdx +15 -11
- package/docs/getting-started/python.mdx +135 -40
- package/docs/getting-started/react-router/index.mdx +33 -0
- package/docs/getting-started/react-router/meta.json +5 -0
- package/docs/getting-started/react-router/v7.mdx +237 -0
- package/docs/getting-started/react-router/v8.mdx +232 -0
- package/docs/getting-started/sveltekit.mdx +20 -16
- package/docs/getting-started/tanstack-start.mdx +17 -13
- package/docs/getting-started/vite.mdx +15 -11
- package/docs/how-it-works/cancellation.mdx +63 -63
- package/docs/how-it-works/code-transform.mdx +83 -67
- package/docs/how-it-works/encryption.mdx +30 -26
- package/docs/how-it-works/event-sourcing.mdx +98 -34
- package/docs/how-it-works/framework-integrations.mdx +96 -337
- package/docs/how-it-works/understanding-directives.mdx +22 -22
- package/docs/internal/index.mdx +6 -4
- package/docs/internal/meta.json +6 -1
- package/docs/internal/nitro-native-build.mdx +38 -0
- package/docs/internal/nitro-web-ui.mdx +24 -0
- package/docs/internal/serializable-abort-controller.mdx +7 -7
- package/docs/meta.json +3 -2
- package/docs/observability/attributes.mdx +134 -0
- package/docs/observability/index.mdx +32 -10
- package/docs/observability/meta.json +1 -1
- package/docs/observability/retention.mdx +93 -0
- package/docs/observability/tracing.mdx +124 -0
- package/docs/testing/index.mdx +36 -36
- package/docs/testing/server-based.mdx +10 -10
- package/docs/whats-new.mdx +186 -0
- package/package.json +17 -14
- package/docs/api-reference/workflow-api/world/index.mdx +0 -58
- package/docs/api-reference/workflow-api/world/meta.json +0 -4
- package/docs/api-reference/workflow-api/world/observability.mdx +0 -164
- package/docs/api-reference/workflow-api/world/queue.mdx +0 -86
- package/docs/deploying/building-a-world.mdx +0 -251
- package/docs/deploying/index.mdx +0 -95
- package/docs/deploying/meta.json +0 -4
- package/docs/deploying/world/local-world.mdx +0 -84
- package/docs/deploying/world/meta.json +0 -4
- package/docs/deploying/world/postgres-world.mdx +0 -224
- package/docs/deploying/world/vercel-world.mdx +0 -179
- package/docs/migration-guides/index.mdx +0 -34
- package/docs/migration-guides/meta.json +0 -9
- package/docs/migration-guides/migrating-from-aws-step-functions.mdx +0 -363
- package/docs/migration-guides/migrating-from-inngest.mdx +0 -314
- package/docs/migration-guides/migrating-from-temporal.mdx +0 -318
- package/docs/migration-guides/migrating-from-trigger-dev.mdx +0 -337
|
@@ -1,61 +1,23 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: DurableAgent
|
|
3
|
-
description:
|
|
3
|
+
description: Deprecated DurableAgent API reference; use WorkflowAgent for new durable agents.
|
|
4
4
|
type: reference
|
|
5
|
-
summary:
|
|
5
|
+
summary: "Deprecated: use AI SDK's WorkflowAgent instead of DurableAgent."
|
|
6
6
|
prerequisites:
|
|
7
7
|
- /docs/ai
|
|
8
8
|
related:
|
|
9
9
|
- /docs/ai/defining-tools
|
|
10
10
|
---
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
```typescript lineNumbers
|
|
17
|
-
import { DurableAgent } from "@workflow/ai/agent";
|
|
18
|
-
import { getWritable } from "workflow";
|
|
19
|
-
import { z } from "zod";
|
|
20
|
-
import type { UIMessageChunk } from "ai";
|
|
21
|
-
|
|
22
|
-
async function getWeather({ city }: { city: string }) {
|
|
23
|
-
"use step";
|
|
24
|
-
|
|
25
|
-
return `Weather in ${city} is sunny`;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
async function myAgent() {
|
|
29
|
-
"use workflow";
|
|
30
|
-
|
|
31
|
-
const agent = new DurableAgent({
|
|
32
|
-
model: "anthropic/claude-haiku-4.5",
|
|
33
|
-
instructions: "You are a helpful weather assistant.",
|
|
34
|
-
temperature: 0.7,
|
|
35
|
-
tools: {
|
|
36
|
-
getWeather: {
|
|
37
|
-
description: "Get weather for a city",
|
|
38
|
-
inputSchema: z.object({ city: z.string() }),
|
|
39
|
-
execute: getWeather,
|
|
40
|
-
},
|
|
41
|
-
},
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
// The agent will stream its output to the workflow
|
|
45
|
-
// run's default output stream
|
|
46
|
-
const writable = getWritable<UIMessageChunk>();
|
|
12
|
+
<Callout type="warn">
|
|
13
|
+
`DurableAgent` is deprecated. Use AI SDK's [`WorkflowAgent`](https://ai-sdk.dev/v7/docs/agents/workflow-agent#workflowagent) for new durable agents. See the [migration guide](https://ai-sdk.dev/v7/docs/agents/workflow-agent#migrating-from-durableagent).
|
|
14
|
+
</Callout>
|
|
47
15
|
|
|
48
|
-
|
|
49
|
-
messages: [{ role: "user", content: "How is the weather in San Francisco?" }],
|
|
50
|
-
writable,
|
|
51
|
-
});
|
|
16
|
+
This reference is kept for existing applications that still import `DurableAgent` from `@workflow/ai/agent`. Do not use `DurableAgent` for new code.
|
|
52
17
|
|
|
53
|
-
|
|
54
|
-
console.log(result.messages);
|
|
55
|
-
}
|
|
56
|
-
```
|
|
18
|
+
For current examples and implementation guidance, see AI SDK's [`WorkflowAgent`](https://ai-sdk.dev/v7/docs/agents/workflow-agent#workflowagent) docs. For legacy code, the API surface below documents the existing `DurableAgent` exports.
|
|
57
19
|
|
|
58
|
-
## API
|
|
20
|
+
## API signature
|
|
59
21
|
|
|
60
22
|
### Class
|
|
61
23
|
|
|
@@ -163,7 +125,7 @@ import type { StreamTextOnAbortCallback } from "@workflow/ai/agent";
|
|
|
163
125
|
export default StreamTextOnAbortCallback;`}
|
|
164
126
|
/>
|
|
165
127
|
|
|
166
|
-
### Advanced
|
|
128
|
+
### Advanced types
|
|
167
129
|
|
|
168
130
|
#### ToolCallRepairFunction
|
|
169
131
|
|
|
@@ -195,30 +157,30 @@ import type { OutputSpecification } from "@workflow/ai/agent";
|
|
|
195
157
|
export default OutputSpecification;`}
|
|
196
158
|
/>
|
|
197
159
|
|
|
198
|
-
## Key
|
|
160
|
+
## Key features
|
|
199
161
|
|
|
200
|
-
- **Durable
|
|
201
|
-
- **Flexible
|
|
202
|
-
- **Stream
|
|
203
|
-
- **Workflow
|
|
204
|
-
- **AI SDK
|
|
162
|
+
- **Durable execution**: Agents can be interrupted and resumed without losing state.
|
|
163
|
+
- **Flexible tool implementation**: Tools can be implemented as workflow steps for automatic retries or as regular workflow-level logic.
|
|
164
|
+
- **Stream processing**: Handles streaming responses and tool calls in a structured way.
|
|
165
|
+
- **Workflow native**: Fully integrated with Workflow SDK for production reliability.
|
|
166
|
+
- **AI SDK parity**: Supports the same options as AI SDK's `streamText`, including generation settings, callbacks, and structured output.
|
|
205
167
|
|
|
206
|
-
## Good to
|
|
168
|
+
## Good to know
|
|
207
169
|
|
|
208
|
-
- Tools can be implemented as workflow steps (using `"use step"` for automatic retries)
|
|
209
|
-
- Tools can use core library features like `sleep()` and
|
|
210
|
-
- The agent processes tool calls iteratively until completion or `maxSteps` is reached
|
|
211
|
-
- **Default `maxSteps` is unlimited
|
|
212
|
-
- The `stream()` method returns `{ messages, steps, toolCalls, toolResults, experimental_output, uiMessages }` containing the full conversation history, step details, tool call details, optional structured output, and optionally accumulated UI messages
|
|
213
|
-
- Use `collectUIMessages: true` to accumulate `UIMessage[]` during streaming, useful for persisting conversation state without re-reading the stream
|
|
214
|
-
- The `prepareStep` callback runs before each step and can modify model, messages, generation settings, tool choice, and context
|
|
215
|
-
- Generation settings (temperature
|
|
216
|
-
- Use `activeTools` to limit which tools are available for a specific stream call
|
|
217
|
-
- The `onFinish` callback is called when all steps complete; `onAbort` is called if aborted
|
|
170
|
+
- Tools can be implemented as workflow steps (using `"use step"` for automatic retries) or as regular workflow-level logic.
|
|
171
|
+
- Tools can use core library features like `sleep()` and hooks within their `execute` functions.
|
|
172
|
+
- The agent processes tool calls iteratively until completion or until `maxSteps` is reached.
|
|
173
|
+
- **Default `maxSteps` is unlimited**: Set a value to limit the number of large language model (LLM) calls.
|
|
174
|
+
- The `stream()` method returns `{ messages, steps, toolCalls, toolResults, experimental_output, uiMessages }` containing the full conversation history, step details, tool call details, optional structured output, and optionally accumulated user interface (UI) messages.
|
|
175
|
+
- Use `collectUIMessages: true` to accumulate `UIMessage[]` during streaming, which is useful for persisting conversation state without re-reading the stream.
|
|
176
|
+
- The `prepareStep` callback runs before each step and can modify the model, messages, generation settings, tool choice, and context.
|
|
177
|
+
- Generation settings (`temperature`, `maxOutputTokens`, and others) can be set on the constructor and overridden per-stream call.
|
|
178
|
+
- Use `activeTools` to limit which tools are available for a specific stream call.
|
|
179
|
+
- The `onFinish` callback is called when all steps complete; `onAbort` is called if aborted.
|
|
218
180
|
|
|
219
181
|
## Examples
|
|
220
182
|
|
|
221
|
-
### Basic
|
|
183
|
+
### Basic agent with tools
|
|
222
184
|
|
|
223
185
|
```typescript
|
|
224
186
|
import { DurableAgent } from "@workflow/ai/agent";
|
|
@@ -260,7 +222,7 @@ async function weatherAgentWorkflow(userQuery: string) {
|
|
|
260
222
|
}
|
|
261
223
|
```
|
|
262
224
|
|
|
263
|
-
### Multiple
|
|
225
|
+
### Multiple tools
|
|
264
226
|
|
|
265
227
|
```typescript
|
|
266
228
|
import { DurableAgent } from "@workflow/ai/agent";
|
|
@@ -309,7 +271,7 @@ async function multiToolAgentWorkflow(userQuery: string) {
|
|
|
309
271
|
}
|
|
310
272
|
```
|
|
311
273
|
|
|
312
|
-
### Multi-turn
|
|
274
|
+
### Multi-turn conversation
|
|
313
275
|
|
|
314
276
|
```typescript
|
|
315
277
|
import { DurableAgent } from "@workflow/ai/agent";
|
|
@@ -363,7 +325,7 @@ async function multiTurnAgentWorkflow() {
|
|
|
363
325
|
}
|
|
364
326
|
```
|
|
365
327
|
|
|
366
|
-
### Tools with Workflow
|
|
328
|
+
### Tools with Workflow library features
|
|
367
329
|
|
|
368
330
|
```typescript
|
|
369
331
|
import { DurableAgent } from "@workflow/ai/agent";
|
|
@@ -385,7 +347,7 @@ async function requestApproval({ message }: { message: string }) {
|
|
|
385
347
|
// Note: No "use step" for this tool call either,
|
|
386
348
|
// since hooks are awaited at the workflow level
|
|
387
349
|
|
|
388
|
-
//
|
|
350
|
+
// Use a Hook for Human-in-the-loop approval
|
|
389
351
|
const hook = approvalHook.create({
|
|
390
352
|
metadata: { message }
|
|
391
353
|
});
|
|
@@ -430,7 +392,7 @@ async function agentWithLibraryFeaturesWorkflow(userRequest: string) {
|
|
|
430
392
|
}
|
|
431
393
|
```
|
|
432
394
|
|
|
433
|
-
### Dynamic
|
|
395
|
+
### Dynamic context with prepareStep
|
|
434
396
|
|
|
435
397
|
Use `prepareStep` to modify settings before each step in the agent loop:
|
|
436
398
|
|
|
@@ -474,7 +436,7 @@ async function agentWithPrepareStep(userMessage: string) {
|
|
|
474
436
|
}
|
|
475
437
|
```
|
|
476
438
|
|
|
477
|
-
### Message
|
|
439
|
+
### Message injection with prepareStep
|
|
478
440
|
|
|
479
441
|
Inject messages from external sources (like hooks) before each LLM call:
|
|
480
442
|
|
|
@@ -524,7 +486,7 @@ async function agentWithMessageQueue(initialMessage: string) {
|
|
|
524
486
|
}
|
|
525
487
|
```
|
|
526
488
|
|
|
527
|
-
### Generation
|
|
489
|
+
### Generation settings
|
|
528
490
|
|
|
529
491
|
Configure model generation parameters at the constructor or stream level:
|
|
530
492
|
|
|
@@ -562,7 +524,7 @@ async function agentWithGenerationSettings() {
|
|
|
562
524
|
}
|
|
563
525
|
```
|
|
564
526
|
|
|
565
|
-
### Limiting
|
|
527
|
+
### Limiting steps with maxSteps
|
|
566
528
|
|
|
567
529
|
By default, the agent loops until completion. Use `maxSteps` to limit the number of LLM calls:
|
|
568
530
|
|
|
@@ -613,7 +575,7 @@ async function multiStepAgent() {
|
|
|
613
575
|
}
|
|
614
576
|
```
|
|
615
577
|
|
|
616
|
-
### Callbacks for
|
|
578
|
+
### Callbacks for monitoring
|
|
617
579
|
|
|
618
580
|
Use callbacks to monitor streaming progress, handle errors, and react to completion:
|
|
619
581
|
|
|
@@ -654,7 +616,7 @@ async function agentWithCallbacks() {
|
|
|
654
616
|
}
|
|
655
617
|
```
|
|
656
618
|
|
|
657
|
-
### Structured
|
|
619
|
+
### Structured output
|
|
658
620
|
|
|
659
621
|
Parse structured data from the LLM response using `Output.object`:
|
|
660
622
|
|
|
@@ -689,7 +651,7 @@ async function agentWithStructuredOutput() {
|
|
|
689
651
|
}
|
|
690
652
|
```
|
|
691
653
|
|
|
692
|
-
### Tool
|
|
654
|
+
### Tool choice control
|
|
693
655
|
|
|
694
656
|
Control when and which tools the model can use:
|
|
695
657
|
|
|
@@ -752,7 +714,7 @@ async function agentWithToolChoice() {
|
|
|
752
714
|
}
|
|
753
715
|
```
|
|
754
716
|
|
|
755
|
-
### Passing
|
|
717
|
+
### Passing context to tools
|
|
756
718
|
|
|
757
719
|
Use `experimental_context` to pass shared context to tool executions:
|
|
758
720
|
|
|
@@ -796,7 +758,7 @@ async function agentWithContext(userId: string) {
|
|
|
796
758
|
}
|
|
797
759
|
```
|
|
798
760
|
|
|
799
|
-
### Collecting UI
|
|
761
|
+
### Collecting UI messages
|
|
800
762
|
|
|
801
763
|
Use `collectUIMessages` to accumulate `UIMessage[]` during streaming. This is useful when you need to persist the conversation without re-reading the run's output stream:
|
|
802
764
|
|
|
@@ -838,7 +800,7 @@ async function saveConversation(messages: UIMessage[]) {
|
|
|
838
800
|
The `uiMessages` property is only available when `collectUIMessages` is set to `true`. When disabled, `uiMessages` is `undefined`.
|
|
839
801
|
</Callout>
|
|
840
802
|
|
|
841
|
-
### Machine-
|
|
803
|
+
### Machine-readable tool results
|
|
842
804
|
|
|
843
805
|
`stream()` returns tool call information you can inspect programmatically. Compare `toolCalls` with `toolResults` to find unresolved tool calls that need client-side handling:
|
|
844
806
|
|
|
@@ -895,7 +857,7 @@ async function agentWithToolInspection(userMessage: string) {
|
|
|
895
857
|
`toolCalls` and `toolResults` reflect the *last step* of the agent loop. Tools without an `execute` function will appear in `toolCalls` but not in `toolResults`, which is how you detect calls that need client-side handling.
|
|
896
858
|
</Callout>
|
|
897
859
|
|
|
898
|
-
### Aborting
|
|
860
|
+
### Aborting long-running streams
|
|
899
861
|
|
|
900
862
|
Use `timeout` to abort a stream automatically after a fixed duration:
|
|
901
863
|
|
|
@@ -923,10 +885,10 @@ async function agentWithTimeout(userMessage: string) {
|
|
|
923
885
|
}
|
|
924
886
|
```
|
|
925
887
|
|
|
926
|
-
## See
|
|
888
|
+
## See also
|
|
927
889
|
|
|
928
|
-
- [Building Durable AI Agents](/docs/ai)
|
|
929
|
-
- [Queueing User Messages](/docs/ai/message-queueing)
|
|
930
|
-
- [WorkflowChatTransport](/docs/api-reference/workflow-ai/workflow-chat-transport)
|
|
931
|
-
- [Workflows and Steps](/docs/foundations/workflows-and-steps)
|
|
932
|
-
- [AI SDK Loop Control](https://ai-sdk.dev/docs/agents/loop-control)
|
|
890
|
+
- [Building Durable AI Agents](/docs/ai): Complete guide to creating durable agents
|
|
891
|
+
- [Queueing User Messages](/docs/ai/message-queueing): Using `prepareStep` for message injection
|
|
892
|
+
- [WorkflowChatTransport](/docs/api-reference/workflow-ai/workflow-chat-transport): Transport layer for AI SDK streams
|
|
893
|
+
- [Workflows and Steps](/docs/foundations/workflows-and-steps): Understanding workflow fundamentals
|
|
894
|
+
- [AI SDK Loop Control](https://ai-sdk.dev/docs/agents/loop-control): AI SDK's agent loop control patterns
|
|
@@ -7,15 +7,15 @@ related:
|
|
|
7
7
|
- /docs/ai
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
The `@workflow/ai` package provides helpers for integrating AI SDK into AI-powered workflows.
|
|
11
11
|
|
|
12
12
|
## Classes
|
|
13
13
|
|
|
14
14
|
<Cards>
|
|
15
15
|
<Card title="DurableAgent" href="/docs/api-reference/workflow-ai/durable-agent">
|
|
16
|
-
|
|
16
|
+
Deprecated: use AI SDK's [`WorkflowAgent`](https://ai-sdk.dev/v7/docs/agents/workflow-agent#workflowagent). Reference kept for existing `@workflow/ai/agent` imports.
|
|
17
17
|
</Card>
|
|
18
18
|
<Card title="WorkflowChatTransport" href="/docs/api-reference/workflow-ai/workflow-chat-transport">
|
|
19
|
-
|
|
19
|
+
Deprecated: use AI SDK's [`WorkflowChatTransport`](https://ai-sdk.dev/v7/docs/agents/workflow-agent#resumable-streaming-with-workflowchattransport) from `@ai-sdk/workflow`. Reference kept for existing `@workflow/ai` imports.
|
|
20
20
|
</Card>
|
|
21
21
|
</Cards>
|
|
@@ -9,7 +9,11 @@ related:
|
|
|
9
9
|
- /docs/ai/resumable-streams
|
|
10
10
|
---
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
<Callout type="warn">
|
|
13
|
+
`WorkflowChatTransport` from `@workflow/ai` is deprecated. AI SDK ships a 1:1 port, so use [`WorkflowChatTransport` from `@ai-sdk/workflow`](https://ai-sdk.dev/v7/docs/agents/workflow-agent#resumable-streaming-with-workflowchattransport) instead. This reference is kept for existing applications that still import it from `@workflow/ai`.
|
|
14
|
+
</Callout>
|
|
15
|
+
|
|
16
|
+
`WorkflowChatTransport` is an AI SDK chat transport that automatically reconnects to interrupted streams. It replaces the default AI SDK transport and recovers from network issues, page refreshes, or Vercel Functions timeouts.
|
|
13
17
|
|
|
14
18
|
<Callout>
|
|
15
19
|
`WorkflowChatTransport` implements the [`ChatTransport`](https://ai-sdk.dev/docs/ai-sdk-ui/transport) interface from the AI SDK and is designed to work with workflow-based chat applications. It requires endpoints that return the `x-workflow-run-id` header to enable stream resumption.
|
|
@@ -34,7 +38,7 @@ export default function Chat() {
|
|
|
34
38
|
}
|
|
35
39
|
```
|
|
36
40
|
|
|
37
|
-
## API
|
|
41
|
+
## API signature
|
|
38
42
|
|
|
39
43
|
### Class
|
|
40
44
|
|
|
@@ -52,27 +56,27 @@ import type { WorkflowChatTransportOptions } from "@workflow/ai";
|
|
|
52
56
|
export default WorkflowChatTransportOptions;`}
|
|
53
57
|
/>
|
|
54
58
|
|
|
55
|
-
## Key
|
|
59
|
+
## Key features
|
|
56
60
|
|
|
57
|
-
- **Automatic
|
|
58
|
-
- **Workflow
|
|
59
|
-
- **Customizable
|
|
60
|
-
- **Stream
|
|
61
|
-
- **Custom
|
|
61
|
+
- **Automatic reconnection**: Recovers from interrupted streams with configurable retry limits.
|
|
62
|
+
- **Workflow integration**: Works with workflow-based endpoints that provide the `x-workflow-run-id` header.
|
|
63
|
+
- **Customizable requests**: Allows intercepting and modifying requests through `prepareSendMessagesRequest` and `prepareReconnectToStreamRequest`.
|
|
64
|
+
- **Stream callbacks**: Provides hooks for tracking the chat lifecycle through `onChatSendMessage` and `onChatEnd`.
|
|
65
|
+
- **Custom fetch**: Supports custom fetch implementations for advanced use cases.
|
|
62
66
|
|
|
63
|
-
## Good to
|
|
67
|
+
## Good to know
|
|
64
68
|
|
|
65
|
-
- The transport expects chat endpoints to return the `x-workflow-run-id` header in the response to enable stream resumption
|
|
66
|
-
- By default, the transport posts to `/api/chat` and reconnects
|
|
67
|
-
- The `onChatSendMessage` callback receives the full response object, allowing you to extract and store the workflow run ID for session resumption
|
|
68
|
-
- Stream interruptions are automatically detected when a
|
|
69
|
-
- The `maxConsecutiveErrors` option controls how many reconnection attempts are made before giving up (default: 3)
|
|
70
|
-
- `initialStartIndex` (constructor option) sets the default chunk position for the **first** reconnection attempt (
|
|
71
|
-
- When using a negative `initialStartIndex`, the reconnection endpoint must return the `x-workflow-stream-tail-index` response header (
|
|
69
|
+
- The transport expects chat endpoints to return the `x-workflow-run-id` header in the response to enable stream resumption.
|
|
70
|
+
- By default, the transport posts to `/api/chat` and reconnects through `/api/chat/{runId}/stream`.
|
|
71
|
+
- The `onChatSendMessage` callback receives the full response object, allowing you to extract and store the workflow run ID for session resumption.
|
|
72
|
+
- Stream interruptions are automatically detected when a `finish` chunk is not received in the initial response.
|
|
73
|
+
- The `maxConsecutiveErrors` option controls how many reconnection attempts are made before giving up (default: 3).
|
|
74
|
+
- `initialStartIndex` (constructor option) sets the default chunk position for the **first** reconnection attempt (for example, after a page refresh). Subsequent retries within the same reconnection loop always resume from the last received chunk. Negative values (for example, `-20`) read from the end of the stream, which is useful for showing only recent output without replaying the full conversation. `startIndex` (per-call option on `reconnectToStream`) overrides `initialStartIndex` for a single reconnection.
|
|
75
|
+
- When using a negative `initialStartIndex`, the reconnection endpoint must return the `x-workflow-stream-tail-index` response header (through `readable.getTailIndex()`). The transport reads this header to compute absolute chunk positions for retries. Without it, `startIndex` is assumed to be `0`, replaying the entire stream.
|
|
72
76
|
|
|
73
77
|
## Examples
|
|
74
78
|
|
|
75
|
-
### Basic
|
|
79
|
+
### Basic chat setup
|
|
76
80
|
|
|
77
81
|
```typescript
|
|
78
82
|
"use client";
|
|
@@ -115,7 +119,7 @@ export default function BasicChat() {
|
|
|
115
119
|
}
|
|
116
120
|
```
|
|
117
121
|
|
|
118
|
-
### With
|
|
122
|
+
### With session persistence and resumption
|
|
119
123
|
|
|
120
124
|
```typescript
|
|
121
125
|
"use client";
|
|
@@ -183,7 +187,7 @@ export default function ChatWithResumption() {
|
|
|
183
187
|
}
|
|
184
188
|
```
|
|
185
189
|
|
|
186
|
-
### With
|
|
190
|
+
### With custom request configuration
|
|
187
191
|
|
|
188
192
|
```typescript
|
|
189
193
|
"use client";
|
|
@@ -250,9 +254,48 @@ export default function ChatWithCustomConfig() {
|
|
|
250
254
|
}
|
|
251
255
|
```
|
|
252
256
|
|
|
253
|
-
##
|
|
257
|
+
## Mid-part resumes
|
|
258
|
+
|
|
259
|
+
A workflow stream is a flat sequence of chunks, but the AI SDK's user interface (UI) protocol groups chunks into logical parts: a `text-start` opens a text part that subsequent `text-delta`s extend and a `text-end` closes, and the same shape applies to `reasoning-*` and `tool-input-*`. The AI SDK client enforces that grammar: a `reasoning-delta` whose `reasoning-start` was never seen throws and breaks the chat.
|
|
260
|
+
|
|
261
|
+
A non-zero `startIndex` (in particular a negative `initialStartIndex`) resolves to a chunk offset with no awareness of those part boundaries, so it can land in the middle of an open part. When that happens, `WorkflowChatTransport` will **drop chunks that reference a part it didn't see a start for** and log a one-time warning. The chat keeps working, but any partial part overlapping the resume cursor is discarded. Tool calls are an exception: `tool-input-available` / `tool-input-error` chunks are self-contained (they carry the full input), so a tool call is recovered as soon as one of those chunks appears in the resumed window. Only its streamed input deltas are lost.
|
|
262
|
+
|
|
263
|
+
To preserve those partial parts, rewind to a step boundary on the server before returning the readable. `start-step` / `finish-step` chunks are the natural seams: no UI part is ever open across them. Sketch:
|
|
264
|
+
|
|
265
|
+
{/*@skip-typecheck: incomplete code sample*/}
|
|
266
|
+
|
|
267
|
+
```typescript title="app/api/chat/[id]/stream/route.ts"
|
|
268
|
+
const run = getRun(id);
|
|
269
|
+
const tailIndex = await run.getReadable().getTailIndex();
|
|
270
|
+
|
|
271
|
+
let resolved = startIndex < 0
|
|
272
|
+
? Math.max(0, tailIndex + 1 + startIndex)
|
|
273
|
+
: startIndex;
|
|
274
|
+
|
|
275
|
+
if (startIndex !== 0) {
|
|
276
|
+
// Walk back from `resolved` to the most recent start-step (or chunk 0),
|
|
277
|
+
// capping the lookback so a single huge step can't trigger an unbounded scan.
|
|
278
|
+
const LOOKBACK = 200;
|
|
279
|
+
const probe = run.getReadable({ startIndex: Math.max(0, resolved - LOOKBACK) });
|
|
280
|
+
let i = Math.max(0, resolved - LOOKBACK);
|
|
281
|
+
let lastBoundary = i;
|
|
282
|
+
for await (const chunk of probe as unknown as AsyncIterable<{ type: string }>) {
|
|
283
|
+
if (i >= resolved) break;
|
|
284
|
+
if (chunk.type === "start-step") lastBoundary = i;
|
|
285
|
+
i++;
|
|
286
|
+
}
|
|
287
|
+
resolved = lastBoundary;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
return createUIMessageStreamResponse({
|
|
291
|
+
stream: run.getReadable({ startIndex: resolved }),
|
|
292
|
+
headers: { "x-workflow-stream-tail-index": String(tailIndex) },
|
|
293
|
+
});
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
## See also
|
|
254
297
|
|
|
255
|
-
- [
|
|
256
|
-
- [AI SDK `useChat`
|
|
257
|
-
- [Workflows and Steps](/docs/foundations/workflows-and-steps)
|
|
258
|
-
- [
|
|
298
|
+
- [`WorkflowAgent`](https://ai-sdk.dev/v7/docs/agents/workflow-agent#workflowagent): Build durable, resumable AI agents (replaces `DurableAgent`)
|
|
299
|
+
- [AI SDK `useChat` documentation](https://ai-sdk.dev/docs/reference/ai-sdk-ui/use-chat): Use `useChat` with custom transports
|
|
300
|
+
- [Workflows and Steps](/docs/foundations/workflows-and-steps): Understand workflow fundamentals
|
|
301
|
+
- [`flight-booking-app` example](https://github.com/vercel/workflow-examples/tree/main/flight-booking-app): View an example application that uses `WorkflowChatTransport`
|
|
@@ -5,14 +5,26 @@ type: reference
|
|
|
5
5
|
summary: Use getHookByToken to look up a hook's metadata and associated workflow run before resuming it.
|
|
6
6
|
prerequisites:
|
|
7
7
|
- /docs/foundations/hooks
|
|
8
|
+
related:
|
|
9
|
+
- /docs/foundations/idempotency
|
|
8
10
|
---
|
|
9
11
|
|
|
10
12
|
Retrieves a hook by its unique token, returning the associated workflow run information and any metadata that was set when the hook was created. This function is useful for inspecting hook details before deciding whether to resume a workflow.
|
|
11
13
|
|
|
14
|
+
When `experimental_minRetention` is set, this function continues to return the Hook after its workflow ends until retention ends. That Hook cannot be resumed. Use `getRun(hook.runId)` to inspect the finished run.
|
|
15
|
+
|
|
12
16
|
<Callout type="warn">
|
|
13
17
|
`getHookByToken` is a runtime function that must be called from outside a workflow function.
|
|
14
18
|
</Callout>
|
|
15
19
|
|
|
20
|
+
<Callout type="info">
|
|
21
|
+
`hook.metadata` is a getter that returns a Promise, so `await` it to read the value. Hydrating metadata can add extra network round trips, so that work is deferred to first access and the lookup itself stays a single read. Awaiting it on a hook with no metadata resolves `undefined` and performs no extra work, and repeat reads are free.
|
|
22
|
+
</Callout>
|
|
23
|
+
|
|
24
|
+
<Callout type="info">
|
|
25
|
+
Looking up a deterministic hook token is useful in hook-based idempotency flows, but it is only an advisory check. If no hook exists yet, another request can still start the same workflow before your `start()` call registers its hook. Use the lookup to avoid obvious duplicate starts, and handle the race inside the workflow by checking `await hook.getConflict()` before duplicate-sensitive work. On a conflict it resolves with the run that owns the token, so the duplicate can route the caller to the active owner. If duplicates must be rejected before a workflow body runs, keep a durable request record until native atomic start-and-hook registration exists. See [Run idempotency](/docs/foundations/idempotency#run-idempotency).
|
|
26
|
+
</Callout>
|
|
27
|
+
|
|
16
28
|
```typescript lineNumbers
|
|
17
29
|
import { getHookByToken } from "workflow/api";
|
|
18
30
|
|
|
@@ -23,7 +35,7 @@ export async function POST(request: Request) {
|
|
|
23
35
|
}
|
|
24
36
|
```
|
|
25
37
|
|
|
26
|
-
## API
|
|
38
|
+
## API signature
|
|
27
39
|
|
|
28
40
|
### Parameters
|
|
29
41
|
|
|
@@ -40,14 +52,14 @@ Returns a `Promise<Hook>` that resolves to:
|
|
|
40
52
|
|
|
41
53
|
<TSDoc
|
|
42
54
|
definition={`
|
|
43
|
-
import type { Hook } from "
|
|
55
|
+
import type { Hook } from "workflow/api";
|
|
44
56
|
export default Hook;`}
|
|
45
57
|
showSections={["returns"]}
|
|
46
58
|
/>
|
|
47
59
|
|
|
48
60
|
## Examples
|
|
49
61
|
|
|
50
|
-
### Basic
|
|
62
|
+
### Basic hook lookup
|
|
51
63
|
|
|
52
64
|
Retrieve hook information before resuming:
|
|
53
65
|
|
|
@@ -62,7 +74,7 @@ export async function POST(request: Request) {
|
|
|
62
74
|
const hook = await getHookByToken(token); // [!code highlight]
|
|
63
75
|
|
|
64
76
|
console.log("Resuming workflow run:", hook.runId);
|
|
65
|
-
console.log("Hook metadata:", hook.metadata);
|
|
77
|
+
console.log("Hook metadata:", await hook.metadata); // [!code highlight]
|
|
66
78
|
|
|
67
79
|
// Then resume the hook with the payload
|
|
68
80
|
await resumeHook(token, data);
|
|
@@ -77,7 +89,7 @@ export async function POST(request: Request) {
|
|
|
77
89
|
}
|
|
78
90
|
```
|
|
79
91
|
|
|
80
|
-
### Validating
|
|
92
|
+
### Validating hook before resume
|
|
81
93
|
|
|
82
94
|
Use `getHookByToken` to validate hook ownership or metadata before resuming:
|
|
83
95
|
|
|
@@ -89,7 +101,8 @@ export async function POST(request: Request) {
|
|
|
89
101
|
|
|
90
102
|
try {
|
|
91
103
|
const hook = await getHookByToken(token); // [!code highlight]
|
|
92
|
-
|
|
104
|
+
// `metadata` is a Promise, so awaiting it hydrates the stored value.
|
|
105
|
+
const metadata = (await hook.metadata) as { allowedUserId?: string } | undefined; // [!code highlight]
|
|
93
106
|
|
|
94
107
|
// Validate that the hook metadata matches the user
|
|
95
108
|
if (metadata?.allowedUserId !== userId) {
|
|
@@ -107,7 +120,7 @@ export async function POST(request: Request) {
|
|
|
107
120
|
}
|
|
108
121
|
```
|
|
109
122
|
|
|
110
|
-
### Checking
|
|
123
|
+
### Checking hook environment
|
|
111
124
|
|
|
112
125
|
Verify the hook belongs to the expected environment:
|
|
113
126
|
|
|
@@ -136,7 +149,7 @@ export async function POST(request: Request) {
|
|
|
136
149
|
}
|
|
137
150
|
```
|
|
138
151
|
|
|
139
|
-
### Logging
|
|
152
|
+
### Logging hook information
|
|
140
153
|
|
|
141
154
|
Log hook details for debugging or auditing:
|
|
142
155
|
|
|
@@ -173,8 +186,9 @@ export async function POST(request: Request) {
|
|
|
173
186
|
}
|
|
174
187
|
```
|
|
175
188
|
|
|
176
|
-
## Related
|
|
189
|
+
## Related functions
|
|
177
190
|
|
|
178
|
-
- [`resumeHook()`](/docs/api-reference/workflow-api/resume-hook)
|
|
179
|
-
- [`createHook()`](/docs/api-reference/workflow/create-hook)
|
|
180
|
-
- [`defineHook()`](/docs/api-reference/workflow/define-hook)
|
|
191
|
+
- [`resumeHook()`](/docs/api-reference/workflow-api/resume-hook): Resume a hook with a payload.
|
|
192
|
+
- [`createHook()`](/docs/api-reference/workflow/create-hook): Create a hook in a workflow.
|
|
193
|
+
- [`defineHook()`](/docs/api-reference/workflow/define-hook): Type-safe hook helper.
|
|
194
|
+
- [Idempotency](/docs/foundations/idempotency): Deduplicate step side effects and workflow starts.
|
|
@@ -5,19 +5,25 @@ type: reference
|
|
|
5
5
|
summary: Use getRun to check a workflow run's status and metadata without blocking on completion.
|
|
6
6
|
prerequisites:
|
|
7
7
|
- /docs/foundations/starting-workflows
|
|
8
|
+
related:
|
|
9
|
+
- /docs/foundations/idempotency
|
|
8
10
|
---
|
|
9
11
|
|
|
10
|
-
Retrieves
|
|
12
|
+
Retrieves workflow run metadata and status information for a given run ID. This function provides immediate access to workflow run details without waiting for completion.
|
|
11
13
|
|
|
12
14
|
Use this function when you need to check workflow status, get timing information, or access workflow metadata without blocking on workflow completion.
|
|
13
15
|
|
|
16
|
+
<Callout type="info">
|
|
17
|
+
`getRun()` retrieves a run when you already have its `runId`. It does not look up runs by a business key. For retried requests that should route to one active workflow, use a deterministic hook token and [`getHookByToken()`](/docs/api-reference/workflow-api/get-hook-by-token). After a hook conflict, `HookConflictError.conflictingRunId` can be passed to `getRun()` to inspect, stream, or return the active owner. See [Run idempotency](/docs/foundations/idempotency#run-idempotency).
|
|
18
|
+
</Callout>
|
|
19
|
+
|
|
14
20
|
```typescript lineNumbers
|
|
15
21
|
import { getRun } from "workflow/api";
|
|
16
22
|
|
|
17
23
|
const run = getRun("my-run-id");
|
|
18
24
|
```
|
|
19
25
|
|
|
20
|
-
## API
|
|
26
|
+
## API signature
|
|
21
27
|
|
|
22
28
|
### Parameters
|
|
23
29
|
|
|
@@ -41,7 +47,7 @@ showSections={["returns"]}
|
|
|
41
47
|
|
|
42
48
|
#### WorkflowReadableStream
|
|
43
49
|
|
|
44
|
-
`run.getReadable()` returns a `WorkflowReadableStream
|
|
50
|
+
`run.getReadable()` returns a `WorkflowReadableStream`, a standard `ReadableStream` extended with a `getTailIndex()` helper:
|
|
45
51
|
|
|
46
52
|
<TSDoc
|
|
47
53
|
definition={`
|
|
@@ -59,6 +65,16 @@ import type { WorkflowReadableStreamOptions } from "workflow/api";
|
|
|
59
65
|
export default WorkflowReadableStreamOptions;`}
|
|
60
66
|
/>
|
|
61
67
|
|
|
68
|
+
#### WorkflowRunWritableStreamOptions
|
|
69
|
+
|
|
70
|
+
<TSDoc
|
|
71
|
+
definition={`
|
|
72
|
+
import type { WorkflowRunWritableStreamOptions } from "workflow/api";
|
|
73
|
+
export default WorkflowRunWritableStreamOptions;`}
|
|
74
|
+
/>
|
|
75
|
+
|
|
76
|
+
Use `run.writable` for the default stream or `run.getWritable(options)` to configure it. See [Writing to another run's stream](/docs/foundations/streaming#writing-to-another-runs-stream) for lifecycle details.
|
|
77
|
+
|
|
62
78
|
#### StopSleepOptions
|
|
63
79
|
|
|
64
80
|
<TSDoc
|
|
@@ -77,7 +93,7 @@ export default StopSleepResult;`}
|
|
|
77
93
|
|
|
78
94
|
## Examples
|
|
79
95
|
|
|
80
|
-
### Check if a
|
|
96
|
+
### Check if a run exists
|
|
81
97
|
|
|
82
98
|
Use the `exists` getter to check whether a workflow run exists without throwing when the run is not found:
|
|
83
99
|
|
|
@@ -106,7 +122,7 @@ export async function GET(req: Request) {
|
|
|
106
122
|
}
|
|
107
123
|
```
|
|
108
124
|
|
|
109
|
-
### Basic
|
|
125
|
+
### Basic status check
|
|
110
126
|
|
|
111
127
|
Check the current status of a workflow run:
|
|
112
128
|
|
|
@@ -135,7 +151,7 @@ export async function GET(req: Request) {
|
|
|
135
151
|
}
|
|
136
152
|
```
|
|
137
153
|
|
|
138
|
-
### Wake
|
|
154
|
+
### Wake up a sleeping workflow
|
|
139
155
|
|
|
140
156
|
Interrupt pending `sleep()` calls to resume a workflow early. This is useful for testing workflows or building custom UIs that let users skip wait periods:
|
|
141
157
|
|
|
@@ -164,6 +180,25 @@ const { stoppedCount } = await run.wakeUp({
|
|
|
164
180
|
});
|
|
165
181
|
```
|
|
166
182
|
|
|
167
|
-
|
|
183
|
+
### Cancel a run
|
|
184
|
+
|
|
185
|
+
Cancel a workflow run. You can pass an optional free-text `cancelReason` (up to 512 characters) that is recorded on the run's cancellation event and shown in the run detail view:
|
|
186
|
+
|
|
187
|
+
```typescript lineNumbers
|
|
188
|
+
import { getRun } from "workflow/api";
|
|
189
|
+
|
|
190
|
+
export async function POST(req: Request) {
|
|
191
|
+
const { runId } = await req.json();
|
|
192
|
+
const run = getRun(runId);
|
|
193
|
+
|
|
194
|
+
await run.cancel({ cancelReason: "Superseded by a newer submission" }); // [!code highlight]
|
|
195
|
+
|
|
196
|
+
return Response.json({ cancelled: true });
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
The options object is optional: `await run.cancel()` cancels the run without recording a reason.
|
|
201
|
+
|
|
202
|
+
## Related functions
|
|
168
203
|
|
|
169
|
-
- [`start()`](/docs/api-reference/workflow-api/start)
|
|
204
|
+
- [`start()`](/docs/api-reference/workflow-api/start): Start a new workflow and get its run ID.
|