workflow 4.2.0-beta.75 → 4.2.0-beta.77

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 (44) hide show
  1. package/README.md +2 -2
  2. package/docs/api-reference/workflow-ai/durable-agent.mdx +86 -1
  3. package/docs/api-reference/workflow-api/get-world.mdx +59 -14
  4. package/docs/api-reference/workflow-api/start.mdx +5 -0
  5. package/docs/api-reference/workflow-api/world/index.mdx +5 -14
  6. package/docs/api-reference/workflow-api/world/meta.json +1 -9
  7. package/docs/api-reference/workflow-api/world/observability.mdx +14 -139
  8. package/docs/api-reference/workflow-api/world/queue.mdx +26 -67
  9. package/docs/api-reference/workflow-api/world/storage.mdx +408 -0
  10. package/docs/api-reference/workflow-api/world/streams.mdx +89 -27
  11. package/docs/api-reference/workflow-next/with-workflow.mdx +51 -0
  12. package/docs/changelog/meta.json +1 -1
  13. package/docs/changelog/resilient-start.mdx +327 -0
  14. package/docs/deploying/building-a-world.mdx +16 -6
  15. package/docs/deploying/index.mdx +2 -2
  16. package/docs/deploying/world/vercel-world.mdx +30 -1
  17. package/docs/errors/hook-conflict.mdx +1 -1
  18. package/docs/errors/node-js-module-in-workflow.mdx +1 -1
  19. package/docs/errors/start-invalid-workflow-function.mdx +83 -58
  20. package/docs/foundations/serialization.mdx +3 -3
  21. package/docs/foundations/starting-workflows.mdx +1 -1
  22. package/docs/foundations/streaming.mdx +1 -1
  23. package/docs/getting-started/astro.mdx +18 -1
  24. package/docs/getting-started/express.mdx +18 -1
  25. package/docs/getting-started/fastify.mdx +18 -1
  26. package/docs/getting-started/hono.mdx +18 -1
  27. package/docs/getting-started/nestjs.mdx +84 -6
  28. package/docs/getting-started/next.mdx +17 -2
  29. package/docs/getting-started/nitro.mdx +18 -1
  30. package/docs/getting-started/nuxt.mdx +18 -1
  31. package/docs/getting-started/sveltekit.mdx +18 -1
  32. package/docs/getting-started/vite.mdx +18 -1
  33. package/docs/how-it-works/encryption.mdx +39 -2
  34. package/docs/how-it-works/event-sourcing.mdx +19 -2
  35. package/docs/how-it-works/framework-integrations.mdx +68 -11
  36. package/docs/how-it-works/understanding-directives.mdx +3 -3
  37. package/docs/observability/index.mdx +1 -1
  38. package/docs/testing/index.mdx +1 -1
  39. package/docs/testing/server-based.mdx +59 -16
  40. package/package.json +10 -10
  41. package/docs/api-reference/workflow-api/world/events.mdx +0 -227
  42. package/docs/api-reference/workflow-api/world/hooks.mdx +0 -181
  43. package/docs/api-reference/workflow-api/world/runs.mdx +0 -223
  44. package/docs/api-reference/workflow-api/world/steps.mdx +0 -216
package/README.md CHANGED
@@ -5,7 +5,7 @@
5
5
  <img alt="Workflow SDK logo" src="https://useworkflow.dev/workflow-circle-symbol-light.svg" height="128">
6
6
  </picture>
7
7
  </a>
8
- <h1>Workflow Development Kit</h1>
8
+ <h1>Workflow SDK</h1>
9
9
 
10
10
  <a href="https://vercel.com"><img alt="Vercel logo" src="https://img.shields.io/badge/MADE%20BY%20Vercel-000000.svg?style=for-the-badge&logo=Vercel&labelColor=000"></a>
11
11
  <a href="https://www.npmjs.com/package/workflow"><img alt="NPM version" src="https://img.shields.io/npm/v/workflow?style=for-the-badge&labelColor=000000"></a>
@@ -16,7 +16,7 @@
16
16
 
17
17
  ## Getting Started
18
18
 
19
- The **Workflow Development Kit** lets you easily add durability, reliability, and observability to async JavaScript. Build apps and AI agents that can suspend, resume, and maintain state with ease.
19
+ The **Workflow SDK** lets you easily add durability, reliability, and observability to async JavaScript. Build apps and AI agents that can suspend, resume, and maintain state with ease.
20
20
 
21
21
  Visit [https://useworkflow.dev](https://useworkflow.dev) to view the full documentation.
22
22
 
@@ -213,7 +213,7 @@ export default OutputSpecification;`}
213
213
  - Tools can use core library features like `sleep()` and Hooks within their `execute` functions
214
214
  - The agent processes tool calls iteratively until completion or `maxSteps` is reached
215
215
  - **Default `maxSteps` is unlimited** - set a value to limit the number of LLM calls
216
- - The `stream()` method returns `{ messages, steps, experimental_output, uiMessages }` containing the full conversation history, step details, optional structured output, and optionally accumulated UI messages
216
+ - 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
217
217
  - Use `collectUIMessages: true` to accumulate `UIMessage[]` during streaming, useful for persisting conversation state without re-reading the stream
218
218
  - The `prepareStep` callback runs before each step and can modify model, messages, generation settings, tool choice, and context
219
219
  - Generation settings (temperature, maxOutputTokens, etc.) can be set on the constructor and overridden per-stream call
@@ -842,6 +842,91 @@ async function saveConversation(messages: UIMessage[]) {
842
842
  The `uiMessages` property is only available when `collectUIMessages` is set to `true`. When disabled, `uiMessages` is `undefined`.
843
843
  </Callout>
844
844
 
845
+ ### Machine-Readable Tool Results
846
+
847
+ `stream()` returns tool call information you can inspect programmatically. Compare `toolCalls` with `toolResults` to find unresolved tool calls that need client-side handling:
848
+
849
+ ```typescript lineNumbers
850
+ import { DurableAgent } from "@workflow/ai/agent";
851
+ import { getWritable } from "workflow";
852
+ import { z } from "zod";
853
+ import type { UIMessageChunk } from "ai";
854
+
855
+ async function checkOrderStatus({ orderId }: { orderId: string }) {
856
+ "use step";
857
+ return `Order ${orderId}: shipped`;
858
+ }
859
+
860
+ async function agentWithToolInspection(userMessage: string) {
861
+ "use workflow";
862
+
863
+ const agent = new DurableAgent({
864
+ model: "anthropic/claude-haiku-4.5",
865
+ tools: {
866
+ checkOrderStatus: {
867
+ description: "Check order status",
868
+ inputSchema: z.object({ orderId: z.string() }),
869
+ execute: checkOrderStatus,
870
+ },
871
+ },
872
+ });
873
+
874
+ const result = await agent.stream({
875
+ messages: [{ role: "user", content: userMessage }],
876
+ writable: getWritable<UIMessageChunk>(),
877
+ });
878
+
879
+ const unresolved = result.toolCalls.filter( // [!code highlight]
880
+ (tc) => !result.toolResults.some((tr) => tr.toolCallId === tc.toolCallId) // [!code highlight]
881
+ ); // [!code highlight]
882
+
883
+ if (unresolved.length > 0) {
884
+ return {
885
+ status: "needs-client-tools",
886
+ unresolved,
887
+ };
888
+ }
889
+
890
+ return {
891
+ status: "complete",
892
+ messages: result.messages,
893
+ toolResults: result.toolResults,
894
+ };
895
+ }
896
+ ```
897
+
898
+ <Callout type="info">
899
+ `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.
900
+ </Callout>
901
+
902
+ ### Aborting Long-Running Streams
903
+
904
+ Use `timeout` to abort a stream automatically after a fixed duration:
905
+
906
+ <Callout type="warn">
907
+ `abortSignal` is not yet supported and will be available in a future release. Use `timeout` for now.
908
+ </Callout>
909
+
910
+ ```typescript lineNumbers
911
+ import { DurableAgent } from "@workflow/ai/agent";
912
+ import { getWritable } from "workflow";
913
+ import type { UIMessageChunk } from "ai";
914
+
915
+ async function agentWithTimeout(userMessage: string) {
916
+ "use workflow";
917
+
918
+ const agent = new DurableAgent({
919
+ model: "anthropic/claude-haiku-4.5",
920
+ });
921
+
922
+ await agent.stream({
923
+ messages: [{ role: "user", content: userMessage }],
924
+ writable: getWritable<UIMessageChunk>(),
925
+ timeout: 30_000, // [!code highlight]
926
+ });
927
+ }
928
+ ```
929
+
845
930
  ## See Also
846
931
 
847
932
  - [Building Durable AI Agents](/docs/ai) - Complete guide to creating durable agents
@@ -39,23 +39,17 @@ showSections={["returns"]}
39
39
  The World object provides access to several entity interfaces. See the [World SDK](/docs/api-reference/workflow-api/world) reference for complete documentation:
40
40
 
41
41
  <Cards>
42
- <Card href="/docs/api-reference/workflow-api/world/runs" title="world.runs">
43
- List, filter, and inspect workflow runs.
42
+ <Card href="/docs/api-reference/workflow-api/world/storage" title="Storage">
43
+ Query runs, steps, hooks, and the underlying event log.
44
44
  </Card>
45
- <Card href="/docs/api-reference/workflow-api/world/steps" title="world.steps">
46
- List and inspect step execution data.
47
- </Card>
48
- <Card href="/docs/api-reference/workflow-api/world/hooks" title="world.hooks">
49
- Look up hooks by ID or token.
50
- </Card>
51
- <Card href="/docs/api-reference/workflow-api/world/events" title="world.events">
52
- Query the append-only event log.
53
- </Card>
54
- <Card href="/docs/api-reference/workflow-api/world/streams" title="world.streams">
45
+ <Card href="/docs/api-reference/workflow-api/world/streams" title="Streams">
55
46
  Read, write, and manage data streams.
56
47
  </Card>
57
- <Card href="/docs/api-reference/workflow-api/world/queue" title="world.queue">
58
- Enqueue runs and create queue handlers.
48
+ <Card href="/docs/api-reference/workflow-api/world/queue" title="Queue">
49
+ Low-level queue dispatch (internal SDK infrastructure).
50
+ </Card>
51
+ <Card href="/docs/api-reference/workflow-api/world/observability" title="Observability">
52
+ Hydrate step I/O, parse display names, decrypt data.
59
53
  </Card>
60
54
  </Cards>
61
55
 
@@ -72,6 +66,57 @@ const hydrated = hydrateResourceIO(step, observabilityRevivers); // [!code highl
72
66
 
73
67
  See [Observability Utilities](/docs/api-reference/workflow-api/world/observability) for the full hydration, parsing, and encryption API.
74
68
 
69
+ ### List Workflow Runs (Display Names)
70
+
71
+ List workflow runs and derive human-readable names from the `workflowName` field:
72
+
73
+ ```typescript lineNumbers
74
+ import { getWorld } from "workflow/runtime";
75
+ import { parseWorkflowName } from "@workflow/utils/parse-name"; // [!code highlight]
76
+
77
+ export async function GET(req: Request) {
78
+ const url = new URL(req.url);
79
+ const cursor = url.searchParams.get("cursor") ?? undefined;
80
+
81
+ try {
82
+ const world = getWorld(); // [!code highlight]
83
+ const runs = await world.runs.list({
84
+ pagination: { cursor },
85
+ resolveData: "none",
86
+ });
87
+
88
+ return Response.json({
89
+ data: runs.data.map((run) => {
90
+ const parsed = parseWorkflowName(run.workflowName); // [!code highlight]
91
+
92
+ return {
93
+ runId: run.runId,
94
+ // Use shortName for UI display (e.g., "processOrder") // [!code highlight]
95
+ displayName: parsed?.shortName ?? run.workflowName, // [!code highlight]
96
+ // Module info available for debugging // [!code highlight]
97
+ module: parsed?.moduleSpecifier, // [!code highlight]
98
+ status: run.status,
99
+ startedAt: run.startedAt,
100
+ completedAt: run.completedAt,
101
+ };
102
+ }),
103
+ cursor: runs.cursor,
104
+ });
105
+ } catch (error) {
106
+ return Response.json(
107
+ { error: "Failed to list workflow runs" },
108
+ { status: 500 }
109
+ );
110
+ }
111
+ }
112
+ ```
113
+
114
+ <Callout type="info">
115
+ The `workflowName` field contains a machine-readable identifier like `workflow//./src/workflows/order//processOrder`.
116
+ Use `parseWorkflowName()` from `@workflow/utils/parse-name` to extract the `shortName` (e.g., `"processOrder"`)
117
+ and `moduleSpecifier` for display in your UI.
118
+ </Callout>
119
+
75
120
  ## Related Functions
76
121
 
77
122
  - [`getRun()`](/docs/api-reference/workflow-api/get-run) - Higher-level API for working with individual runs by ID.
@@ -54,6 +54,11 @@ Learn more about [`WorkflowReadableStreamOptions`](/docs/api-reference/workflow-
54
54
  * This is different from calling workflow functions directly, which is the typical pattern in Next.js applications.
55
55
  * The function returns immediately after enqueuing the workflow - it doesn't wait for the workflow to complete.
56
56
  * All arguments must be [serializable](/docs/foundations/serialization).
57
+ * When `deploymentId` is provided, the argument types and return type become `unknown` since there is no guarantee the workflow function's types will be consistent across different deployments.
58
+
59
+ <Callout type="info">
60
+ If `start()` throws `'start' received an invalid workflow function. Ensure the Workflow Development Kit is configured correctly and the function includes a 'use workflow' directive.`, the passed function was not transformed as a workflow. The two most common causes are a missing `"use workflow"` directive or missing framework integration. See [start-invalid-workflow-function](/docs/errors/start-invalid-workflow-function).
61
+ </Callout>
57
62
 
58
63
  ## Examples
59
64
 
@@ -22,26 +22,17 @@ import { getWorld } from "workflow/runtime";
22
22
  const world = getWorld(); // [!code highlight]
23
23
  ```
24
24
 
25
- ## Entities
25
+ ## Interfaces
26
26
 
27
27
  <Cards>
28
- <Card href="/docs/api-reference/workflow-api/world/runs" title="world.runs">
29
- List, filter, and inspect workflow runs with pagination and status filtering.
30
- </Card>
31
- <Card href="/docs/api-reference/workflow-api/world/steps" title="world.steps">
32
- List and inspect step execution data including input/output hydration.
33
- </Card>
34
- <Card href="/docs/api-reference/workflow-api/world/hooks" title="world.hooks">
35
- Look up hooks by ID or token for webhook resume flows.
36
- </Card>
37
- <Card href="/docs/api-reference/workflow-api/world/events" title="world.events">
38
- Query the append-only event log — the source of truth for all workflow state changes.
28
+ <Card href="/docs/api-reference/workflow-api/world/storage" title="Storage">
29
+ Query runs, steps, hooks, and the underlying event log.
39
30
  </Card>
40
31
  <Card href="/docs/api-reference/workflow-api/world/streams" title="Streams">
41
32
  Read, write, and manage real-time data streams for workflow runs.
42
33
  </Card>
43
- <Card href="/docs/api-reference/workflow-api/world/queue" title="world.queue">
44
- Enqueue workflow runs and create queue handlers for processing.
34
+ <Card href="/docs/api-reference/workflow-api/world/queue" title="Queue">
35
+ Low-level queue dispatch (internal SDK infrastructure).
45
36
  </Card>
46
37
  <Card href="/docs/api-reference/workflow-api/world/observability" title="Observability Utilities">
47
38
  Hydrate step I/O, parse display names, and decrypt workflow data.
@@ -1,12 +1,4 @@
1
1
  {
2
2
  "title": "World SDK",
3
- "pages": [
4
- "runs",
5
- "steps",
6
- "hooks",
7
- "events",
8
- "streams",
9
- "queue",
10
- "observability"
11
- ]
3
+ "pages": ["storage", "streams", "queue", "observability"]
12
4
  }
@@ -6,8 +6,7 @@ summary: "Functions: hydrateResourceIO(), parseStepName(), parseWorkflowName(),
6
6
  prerequisites:
7
7
  - /docs/api-reference/workflow-api/get-world
8
8
  related:
9
- - /docs/api-reference/workflow-api/world/steps
10
- - /docs/api-reference/workflow-api/world/runs
9
+ - /docs/api-reference/workflow-api/world/storage
11
10
  keywords:
12
11
  - workflow/observability
13
12
  - hydrateResourceIO
@@ -41,18 +40,14 @@ import { // [!code highlight]
41
40
 
42
41
  ### hydrateResourceIO()
43
42
 
44
- Deserialize step or run data that was serialized using the [devalue](https://github.com/Rich-Harris/devalue) format. This is required to display step input/output in your UI.
43
+ Deserialize step or run data that was serialized using the [devalue](https://github.com/Rich-Harris/devalue) format. Required to display step input/output in your UI.
45
44
 
46
45
  ```typescript lineNumbers
47
46
  import { hydrateResourceIO, observabilityRevivers } from "workflow/observability"; // [!code highlight]
48
- import { getWorld } from "workflow/runtime";
49
47
 
50
- const world = getWorld();
51
48
  const step = await world.steps.get(runId, stepId);
52
-
53
49
  const hydrated = hydrateResourceIO(step, observabilityRevivers); // [!code highlight]
54
- console.log(hydrated.input); // Deserialized input data
55
- console.log(hydrated.output); // Deserialized output data
50
+ console.log(hydrated.input, hydrated.output);
56
51
  ```
57
52
 
58
53
  **Parameters:**
@@ -68,77 +63,41 @@ console.log(hydrated.output); // Deserialized output data
68
63
 
69
64
  A set of reviver functions that handle standard workflow serialization types (Date, Map, Set, Error, etc.).
70
65
 
71
- ```typescript lineNumbers
72
- import { observabilityRevivers } from "workflow/observability";
73
- ```
74
-
75
66
  ## Name Parsing
76
67
 
77
- Workflow and step names are stored as machine-readable identifiers. These utilities extract display-friendly names.
68
+ Workflow and step names are stored as machine-readable identifiers. These utilities extract display-friendly names. All return `{ shortName: string, moduleSpecifier: string } | null`.
78
69
 
79
70
  ### parseStepName()
80
71
 
81
- Parse a machine-readable step name into its components.
82
-
83
72
  ```typescript lineNumbers
84
73
  import { parseStepName } from "workflow/observability"; // [!code highlight]
85
74
 
86
75
  const parsed = parseStepName("step//./src/workflows/order//processPayment"); // [!code highlight]
87
- // parsed.shortName → "processPayment"
88
- // parsed.moduleSpecifier → "./src/workflows/order"
76
+ // parsed?.shortName → "processPayment"
77
+ // parsed?.moduleSpecifier → "./src/workflows/order"
89
78
  ```
90
79
 
91
- **Parameters:**
92
-
93
- | Parameter | Type | Description |
94
- |-----------|------|-------------|
95
- | `stepName` | `string` | The machine-readable step name |
96
-
97
- **Returns:** `{ shortName: string, moduleSpecifier: string } | null`
98
-
99
80
  ### parseWorkflowName()
100
81
 
101
- Parse a machine-readable workflow name into its components.
102
-
103
82
  ```typescript lineNumbers
104
83
  import { parseWorkflowName } from "workflow/observability"; // [!code highlight]
105
84
 
106
85
  const parsed = parseWorkflowName("workflow//./src/workflows/order//processOrder"); // [!code highlight]
107
- // parsed.shortName → "processOrder"
108
- // parsed.moduleSpecifier → "./src/workflows/order"
86
+ // parsed?.shortName → "processOrder"
109
87
  ```
110
88
 
111
- **Parameters:**
112
-
113
- | Parameter | Type | Description |
114
- |-----------|------|-------------|
115
- | `workflowName` | `string` | The machine-readable workflow name |
116
-
117
- **Returns:** `{ shortName: string, moduleSpecifier: string } | null`
118
-
119
89
  ### parseClassName()
120
90
 
121
- Parse a machine-readable class name into its components.
122
-
123
91
  ```typescript lineNumbers
124
92
  import { parseClassName } from "workflow/observability"; // [!code highlight]
125
93
 
126
94
  const parsed = parseClassName("class//./src/models//User"); // [!code highlight]
127
- // parsed.shortName → "User"
128
- // parsed.moduleSpecifier → "./src/models"
95
+ // parsed?.shortName → "User"
129
96
  ```
130
97
 
131
- **Parameters:**
132
-
133
- | Parameter | Type | Description |
134
- |-----------|------|-------------|
135
- | `className` | `string` | The machine-readable class name |
136
-
137
- **Returns:** `{ shortName: string, moduleSpecifier: string } | null`
138
-
139
98
  ## Encryption
140
99
 
141
- For workflows with encrypted step data, use these utilities to decrypt before hydrating.
100
+ For workflows with encrypted step data, decrypt before hydrating.
142
101
 
143
102
  ### getEncryptionKeyForRun()
144
103
 
@@ -165,10 +124,7 @@ Hydrate step or run data using a decryption key. Use this instead of `hydrateRes
165
124
 
166
125
  {/* @expect-error:2305,2724 */}
167
126
  ```typescript lineNumbers
168
- import { // [!code highlight]
169
- getEncryptionKeyForRun, // [!code highlight]
170
- hydrateResourceIOWithKey, // [!code highlight]
171
- } from "workflow/observability"; // [!code highlight]
127
+ import { getEncryptionKeyForRun, hydrateResourceIOWithKey } from "workflow/observability"; // [!code highlight]
172
128
 
173
129
  const key = await getEncryptionKeyForRun(runId); // [!code highlight]
174
130
  const hydrated = hydrateResourceIOWithKey(step, key); // [!code highlight]
@@ -185,105 +141,24 @@ const hydrated = hydrateResourceIOWithKey(step, key); // [!code highlight]
185
141
 
186
142
  ## Examples
187
143
 
188
- ### Hydrate Step Input and Output Data
189
-
190
- ```typescript lineNumbers
191
- // app/api/workflow-steps/hydrate/route.ts
192
- import { getWorld } from "workflow/runtime";
193
- import { // [!code highlight]
194
- hydrateResourceIO, // [!code highlight]
195
- observabilityRevivers, // [!code highlight]
196
- parseStepName, // [!code highlight]
197
- } from "workflow/observability"; // [!code highlight]
198
-
199
- export async function GET(req: Request) {
200
- const url = new URL(req.url);
201
- const runId = url.searchParams.get("runId");
202
- const stepId = url.searchParams.get("stepId");
203
-
204
- if (!runId || !stepId) {
205
- return Response.json({ error: "runId and stepId required" }, { status: 400 });
206
- }
207
-
208
- const world = getWorld();
209
- const step = await world.steps.get(runId, stepId);
210
-
211
- const hydrated = hydrateResourceIO(step, observabilityRevivers); // [!code highlight]
212
- const parsed = parseStepName(step.stepName);
213
-
214
- return Response.json({
215
- displayName: parsed?.shortName ?? step.stepName,
216
- input: hydrated.input, // [!code highlight]
217
- output: hydrated.output, // [!code highlight]
218
- });
219
- }
220
- ```
221
-
222
- ### Decrypt and Hydrate Encrypted Step Data
223
-
224
- For teams with encryption enabled, step data must be decrypted before hydration:
225
-
226
- {/* @expect-error:2305,2724 */}
227
- ```typescript lineNumbers
228
- // app/api/workflow-steps/decrypt/route.ts
229
- import { getWorld } from "workflow/runtime";
230
- import { // [!code highlight]
231
- getEncryptionKeyForRun, // [!code highlight]
232
- hydrateResourceIOWithKey, // [!code highlight]
233
- parseStepName, // [!code highlight]
234
- } from "workflow/observability"; // [!code highlight]
235
-
236
- export async function GET(req: Request) {
237
- const url = new URL(req.url);
238
- const runId = url.searchParams.get("runId");
239
- const stepId = url.searchParams.get("stepId");
240
-
241
- if (!runId || !stepId) {
242
- return Response.json({ error: "runId and stepId required" }, { status: 400 });
243
- }
244
-
245
- const world = getWorld();
246
- const step = await world.steps.get(runId, stepId);
247
-
248
- // Decrypt then hydrate // [!code highlight]
249
- const key = await getEncryptionKeyForRun(runId); // [!code highlight]
250
- const hydrated = hydrateResourceIOWithKey(step, key); // [!code highlight]
251
-
252
- const parsed = parseStepName(step.stepName);
253
-
254
- return Response.json({
255
- displayName: parsed?.shortName ?? step.stepName,
256
- input: hydrated.input,
257
- output: hydrated.output,
258
- });
259
- }
260
- ```
261
-
262
144
  ### Parse Display Names for a Run's Steps
263
145
 
264
- Build a progress dashboard with human-readable step names:
265
-
266
146
  ```typescript lineNumbers
267
147
  import { getWorld } from "workflow/runtime";
268
148
  import { parseStepName, parseWorkflowName } from "workflow/observability"; // [!code highlight]
269
149
 
270
150
  const world = getWorld();
271
-
272
- // Parse workflow name
273
151
  const run = await world.runs.get(runId, { resolveData: "none" });
274
- const workflowDisplay = parseWorkflowName(run.workflowName); // [!code highlight]
275
- console.log("Workflow:", workflowDisplay?.shortName); // [!code highlight]
152
+ console.log("Workflow:", parseWorkflowName(run.workflowName)?.shortName); // [!code highlight]
276
153
 
277
- // Parse step names
278
154
  const steps = await world.steps.list({ runId, resolveData: "none" });
279
155
  for (const step of steps.data) {
280
- const stepDisplay = parseStepName(step.stepName); // [!code highlight]
281
- console.log(` ${stepDisplay?.shortName}: ${step.status}`); // [!code highlight]
156
+ const parsed = parseStepName(step.stepName); // [!code highlight]
157
+ console.log(` ${parsed?.shortName}: ${step.status}`); // [!code highlight]
282
158
  }
283
159
  ```
284
160
 
285
161
  ## Related
286
162
 
287
- - [world.steps](/docs/api-reference/workflow-api/world/steps) — Query step data to hydrate
288
- - [world.runs](/docs/api-reference/workflow-api/world/runs) — Query run data to hydrate
163
+ - [Storage](/docs/api-reference/workflow-api/world/storage) — Query runs, steps, hooks, and events
289
164
  - [Serialization](/docs/foundations/serialization) — How workflow data is serialized
@@ -1,8 +1,8 @@
1
1
  ---
2
- title: world.queue
3
- description: Enqueue workflow runs and create queue handlers for background processing.
2
+ title: Queue
3
+ description: Low-level queue interface for dispatching workflow and step invocations.
4
4
  type: reference
5
- summary: "Methods: getDeploymentId(), queue(), createQueueHandler(). Manage workflow run queuing and processing."
5
+ summary: "Methods: getDeploymentId(), queue(), createQueueHandler(). Internal queue dispatch normally handled by the SDK."
6
6
  prerequisites:
7
7
  - /docs/api-reference/workflow-api/get-world
8
8
  related:
@@ -13,115 +13,74 @@ keywords:
13
13
  - getDeploymentId
14
14
  - queue
15
15
  - createQueueHandler
16
- - background processing
17
- - enqueue workflow
18
16
  - ValidQueueName
17
+ - queue dispatch
19
18
  ---
20
19
 
21
- The `world.queue` interface provides access to workflow run queuing and processing. Use it to enqueue runs for background execution and create handlers to process queued items.
20
+ Queue methods live directly on the `world` object (not nested). They dispatch internal workflow and step invocations to the queue backend.
21
+
22
+ <Callout type="warn">
23
+ These methods are used internally by the Workflow SDK to dispatch execution. You do not need to call them in normal operations — use [`start()`](/docs/api-reference/workflow-api/start) to trigger workflows instead. Direct queue access is only needed if you programmatically create a run via `world.events.create()` with a `run_created` event and need to kick off its initial execution, or for debugging resumption of a flow or step route.
24
+ </Callout>
22
25
 
23
26
  ## Import
24
27
 
25
28
  ```typescript lineNumbers
26
29
  import { getWorld } from "workflow/runtime";
27
30
 
28
- const world = getWorld();
29
- const queue = world.queue; // [!code highlight]
31
+ const world = getWorld(); // [!code highlight]
32
+ // Queue methods are called directly on world e.g. world.queue()
30
33
  ```
31
34
 
32
35
  ## Methods
33
36
 
34
37
  ### getDeploymentId()
35
38
 
36
- Get the current deployment ID. Useful for routing queue messages to the correct deployment.
39
+ Get the current deployment ID. Used internally for routing queue messages to the correct deployment.
37
40
 
38
41
  ```typescript lineNumbers
39
- const deploymentId = await world.queue.getDeploymentId(); // [!code highlight]
42
+ const deploymentId = await world.getDeploymentId(); // [!code highlight]
40
43
  ```
41
44
 
42
45
  **Returns:** `string` — The current deployment ID
43
46
 
44
47
  ### queue()
45
48
 
46
- Enqueue a workflow run for background processing.
49
+ Dispatch a message to a named queue. The message payload is an internal SDK type (`WorkflowInvokePayload`, `StepInvokePayload`, or `HealthCheckPayload`).
47
50
 
48
51
  ```typescript lineNumbers
49
- const messageId = await world.queue.queue(name, message, opts); // [!code highlight]
52
+ const { messageId } = await world.queue(queueName, payload, opts); // [!code highlight]
50
53
  ```
51
54
 
52
55
  **Parameters:**
53
56
 
54
57
  | Parameter | Type | Description |
55
58
  |-----------|------|-------------|
56
- | `name` | `ValidQueueName` | The queue name |
57
- | `message` | `object` | The message payload to enqueue |
58
- | `opts` | `object` | Optional configuration |
59
+ | `queueName` | `ValidQueueName` | The queue name (branded string) |
60
+ | `message` | `QueuePayload` | Internal SDK payload |
61
+ | `opts` | `QueueOptions` | Optional `deploymentId`, `idempotencyKey`, `delaySeconds`, `headers` |
59
62
 
60
- **Returns:** `MessageId`
63
+ **Returns:** `{ messageId: MessageId | null }`
61
64
 
62
65
  ### createQueueHandler()
63
66
 
64
- Create a handler function for processing queued messages.
67
+ Create an HTTP handler that processes messages from a queue. Used to set up the queue consumer endpoint.
65
68
 
66
69
  ```typescript lineNumbers
67
- const handler = world.queue.createQueueHandler(prefix, callback); // [!code highlight]
70
+ const handler = world.createQueueHandler(prefix, callback); // [!code highlight]
68
71
  ```
69
72
 
70
73
  **Parameters:**
71
74
 
72
75
  | Parameter | Type | Description |
73
76
  |-----------|------|-------------|
74
- | `prefix` | `string` | Queue name prefix to match |
75
- | `callback` | `function` | Handler function called for each queued message |
76
-
77
- **Returns:** Queue handler function
78
-
79
- ## Examples
80
-
81
- ### Enqueue a Workflow Run for Background Processing
82
-
83
- ```typescript lineNumbers
84
- // app/api/workflow-queue/route.ts
85
- import { getWorld } from "workflow/runtime";
86
-
87
- export async function POST(req: Request) {
88
- const { workflowName, input } = await req.json();
89
-
90
- const world = getWorld();
91
- const messageId = await world.queue.queue(workflowName, { // [!code highlight]
92
- input,
93
- priority: "normal",
94
- }); // [!code highlight]
95
-
96
- return Response.json({ messageId });
97
- }
98
- ```
99
-
100
- ### Create a Queue Handler for Processing
77
+ | `prefix` | `QueuePrefix` | Queue name prefix to match |
78
+ | `callback` | `(message, meta) => Promise<void \| { timeoutSeconds: number }>` | Handler called for each message. `meta` contains `attempt`, `queueName`, `messageId`, `requestId`. |
101
79
 
102
- ```typescript lineNumbers
103
- import { getWorld } from "workflow/runtime";
104
-
105
- const world = getWorld();
106
-
107
- const handler = world.queue.createQueueHandler("my-workflows", async (message) => { // [!code highlight]
108
- console.log("Processing:", message);
109
- // Handle the queued workflow message
110
- }); // [!code highlight]
111
- ```
112
-
113
- ### Get Current Deployment ID
114
-
115
- ```typescript lineNumbers
116
- import { getWorld } from "workflow/runtime";
117
-
118
- const world = getWorld();
119
- const deploymentId = await world.queue.getDeploymentId(); // [!code highlight]
120
- console.log("Running on deployment:", deploymentId);
121
- ```
80
+ **Returns:** `(req: Request) => Promise<Response>`
122
81
 
123
82
  ## Related
124
83
 
125
- - [start()](/docs/api-reference/workflow-api/start) — Higher-level API for starting workflow runs
84
+ - [start()](/docs/api-reference/workflow-api/start) — The standard way to start workflow runs
126
85
  - [Starting Workflows](/docs/foundations/starting-workflows) — Core concepts for workflow invocation
127
- - [world.runs](/docs/api-reference/workflow-api/world/runs) — Inspect queued and running workflows
86
+ - [Storage](/docs/api-reference/workflow-api/world/storage) — Create events that trigger queue dispatch