workflow 4.2.0-beta.74 → 4.2.0-beta.75
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/docs/api-reference/workflow/create-webhook.mdx +4 -0
- package/docs/api-reference/workflow-api/get-world.mdx +33 -157
- package/docs/api-reference/workflow-api/index.mdx +3 -0
- package/docs/api-reference/workflow-api/world/events.mdx +227 -0
- package/docs/api-reference/workflow-api/world/hooks.mdx +181 -0
- package/docs/api-reference/workflow-api/world/index.mdx +67 -0
- package/docs/api-reference/workflow-api/world/meta.json +12 -0
- package/docs/api-reference/workflow-api/world/observability.mdx +289 -0
- package/docs/api-reference/workflow-api/world/queue.mdx +127 -0
- package/docs/api-reference/workflow-api/world/runs.mdx +223 -0
- package/docs/api-reference/workflow-api/world/steps.mdx +216 -0
- package/docs/api-reference/workflow-api/world/streams.mdx +152 -0
- package/docs/foundations/hooks.mdx +4 -0
- package/docs/foundations/streaming.mdx +1 -0
- package/package.json +11 -11
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: world.runs
|
|
3
|
+
description: List, filter, and inspect workflow runs with cursor pagination and status filtering.
|
|
4
|
+
type: reference
|
|
5
|
+
summary: "Methods: get(), list(). Query workflow runs by status, paginate results, and inspect run metadata."
|
|
6
|
+
prerequisites:
|
|
7
|
+
- /docs/api-reference/workflow-api/get-world
|
|
8
|
+
related:
|
|
9
|
+
- /docs/api-reference/workflow-api/world/steps
|
|
10
|
+
- /docs/api-reference/workflow-api/world/events
|
|
11
|
+
- /docs/api-reference/workflow-api/get-run
|
|
12
|
+
keywords:
|
|
13
|
+
- world.runs
|
|
14
|
+
- world.runs.get
|
|
15
|
+
- world.runs.list
|
|
16
|
+
- WorkflowRun
|
|
17
|
+
- cursor pagination
|
|
18
|
+
- run status
|
|
19
|
+
- resolveData
|
|
20
|
+
- parseWorkflowName
|
|
21
|
+
- list workflow runs
|
|
22
|
+
- filter runs
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
The `world.runs` interface provides direct access to workflow run data. Use it to list runs with pagination, filter by status, and inspect individual run metadata.
|
|
26
|
+
|
|
27
|
+
## Import
|
|
28
|
+
|
|
29
|
+
```typescript lineNumbers
|
|
30
|
+
import { getWorld } from "workflow/runtime";
|
|
31
|
+
|
|
32
|
+
const world = getWorld();
|
|
33
|
+
const runs = world.runs; // [!code highlight]
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Methods
|
|
37
|
+
|
|
38
|
+
### get()
|
|
39
|
+
|
|
40
|
+
Retrieve a single workflow run by ID.
|
|
41
|
+
|
|
42
|
+
```typescript lineNumbers
|
|
43
|
+
const run = await world.runs.get(runId); // [!code highlight]
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**Parameters:**
|
|
47
|
+
|
|
48
|
+
| Parameter | Type | Description |
|
|
49
|
+
|-----------|------|-------------|
|
|
50
|
+
| `runId` | `string` | The workflow run ID |
|
|
51
|
+
| `params.resolveData` | `'all' \| 'none'` | Whether to hydrate input/output data. Default: `'all'` |
|
|
52
|
+
|
|
53
|
+
**Returns:** `WorkflowRun`
|
|
54
|
+
|
|
55
|
+
### list()
|
|
56
|
+
|
|
57
|
+
List workflow runs with cursor pagination.
|
|
58
|
+
|
|
59
|
+
```typescript lineNumbers
|
|
60
|
+
const result = await world.runs.list({ // [!code highlight]
|
|
61
|
+
pagination: { cursor },
|
|
62
|
+
}); // [!code highlight]
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**Parameters:**
|
|
66
|
+
|
|
67
|
+
| Parameter | Type | Description |
|
|
68
|
+
|-----------|------|-------------|
|
|
69
|
+
| `params.pagination.cursor` | `string` | Cursor for the next page |
|
|
70
|
+
| `params.resolveData` | `'all' \| 'none'` | Whether to hydrate input/output data |
|
|
71
|
+
|
|
72
|
+
**Returns:** `{ data: WorkflowRun[], cursor?: string }`
|
|
73
|
+
|
|
74
|
+
### cancel()
|
|
75
|
+
|
|
76
|
+
Cancel a running workflow. This is a convenience method that creates a `run_cancelled` event.
|
|
77
|
+
|
|
78
|
+
```typescript lineNumbers
|
|
79
|
+
const run = await world.runs.cancel(runId); // [!code highlight]
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
**Parameters:**
|
|
83
|
+
|
|
84
|
+
| Parameter | Type | Description |
|
|
85
|
+
|-----------|------|-------------|
|
|
86
|
+
| `runId` | `string` | The workflow run ID to cancel |
|
|
87
|
+
|
|
88
|
+
**Returns:** `WorkflowRun`
|
|
89
|
+
|
|
90
|
+
<Callout type="info">
|
|
91
|
+
Cancellation works by creating an event with `eventType: 'run_cancelled'`. See [world.events](/docs/api-reference/workflow-api/world/events) for the full event creation API.
|
|
92
|
+
</Callout>
|
|
93
|
+
|
|
94
|
+
## Types
|
|
95
|
+
|
|
96
|
+
### WorkflowRun
|
|
97
|
+
|
|
98
|
+
| Field | Type | Description |
|
|
99
|
+
|-------|------|-------------|
|
|
100
|
+
| `runId` | `string` | Unique run identifier |
|
|
101
|
+
| `status` | `string` | Run status: `'running'`, `'completed'`, `'failed'`, `'cancelled'` |
|
|
102
|
+
| `workflowName` | `string` | Machine-readable workflow identifier |
|
|
103
|
+
| `input` | `any` | Workflow input data (when `resolveData: 'all'`) |
|
|
104
|
+
| `output` | `any` | Workflow output data (when `resolveData: 'all'`) |
|
|
105
|
+
| `error` | `any` | Error data if the run failed |
|
|
106
|
+
| `startedAt` | `string` | ISO timestamp when the run started |
|
|
107
|
+
| `completedAt` | `string \| null` | ISO timestamp when the run completed |
|
|
108
|
+
| `specVersion` | `number` | Workflow spec version |
|
|
109
|
+
|
|
110
|
+
<Callout type="warn">
|
|
111
|
+
The `workflowName` field contains a machine-readable identifier like `workflow//./src/workflows/order//processOrder`. Use `parseWorkflowName()` from `workflow/observability` to extract a display-friendly name.
|
|
112
|
+
</Callout>
|
|
113
|
+
|
|
114
|
+
## Examples
|
|
115
|
+
|
|
116
|
+
### List Workflow Runs with Cursor Pagination
|
|
117
|
+
|
|
118
|
+
```typescript lineNumbers
|
|
119
|
+
// app/api/workflow-runs/route.ts
|
|
120
|
+
import { getWorld } from "workflow/runtime";
|
|
121
|
+
|
|
122
|
+
export async function GET(req: Request) {
|
|
123
|
+
const url = new URL(req.url);
|
|
124
|
+
const cursor = url.searchParams.get("cursor") ?? undefined;
|
|
125
|
+
|
|
126
|
+
const world = getWorld(); // [!code highlight]
|
|
127
|
+
const runs = await world.runs.list({ // [!code highlight]
|
|
128
|
+
pagination: { cursor }, // [!code highlight]
|
|
129
|
+
}); // [!code highlight]
|
|
130
|
+
|
|
131
|
+
return Response.json(runs);
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Get a Single Run with Full Data
|
|
136
|
+
|
|
137
|
+
Use `resolveData: 'all'` (the default) to fetch the complete run including input and output:
|
|
138
|
+
|
|
139
|
+
```typescript lineNumbers
|
|
140
|
+
// app/api/workflow-runs/[runId]/route.ts
|
|
141
|
+
import { getWorld } from "workflow/runtime";
|
|
142
|
+
|
|
143
|
+
export async function GET(req: Request) {
|
|
144
|
+
const url = new URL(req.url);
|
|
145
|
+
const runId = url.searchParams.get("runId");
|
|
146
|
+
|
|
147
|
+
if (!runId) {
|
|
148
|
+
return Response.json({ error: "runId required" }, { status: 400 });
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const world = getWorld();
|
|
152
|
+
const run = await world.runs.get(runId, { // [!code highlight]
|
|
153
|
+
resolveData: "all", // [!code highlight]
|
|
154
|
+
}); // [!code highlight]
|
|
155
|
+
|
|
156
|
+
return Response.json({
|
|
157
|
+
runId: run.runId,
|
|
158
|
+
status: run.status,
|
|
159
|
+
input: run.input,
|
|
160
|
+
output: run.output,
|
|
161
|
+
startedAt: run.startedAt,
|
|
162
|
+
completedAt: run.completedAt,
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Get Run without Data for Lightweight Status Checks
|
|
168
|
+
|
|
169
|
+
Use `resolveData: 'none'` when you only need status metadata:
|
|
170
|
+
|
|
171
|
+
```typescript lineNumbers
|
|
172
|
+
import { getWorld } from "workflow/runtime";
|
|
173
|
+
|
|
174
|
+
const world = getWorld();
|
|
175
|
+
const run = await world.runs.get(runId, { // [!code highlight]
|
|
176
|
+
resolveData: "none", // Skip input/output for performance // [!code highlight]
|
|
177
|
+
}); // [!code highlight]
|
|
178
|
+
|
|
179
|
+
console.log(run.status); // 'running' | 'completed' | 'failed' | 'cancelled'
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### Parse Workflow Display Name from Machine-Readable ID
|
|
183
|
+
|
|
184
|
+
```typescript lineNumbers
|
|
185
|
+
import { getWorld } from "workflow/runtime";
|
|
186
|
+
import { parseWorkflowName } from "workflow/observability"; // [!code highlight]
|
|
187
|
+
|
|
188
|
+
const world = getWorld();
|
|
189
|
+
const runs = await world.runs.list({});
|
|
190
|
+
|
|
191
|
+
for (const run of runs.data) {
|
|
192
|
+
const parsed = parseWorkflowName(run.workflowName); // [!code highlight]
|
|
193
|
+
console.log(parsed?.shortName); // e.g., "processOrder" // [!code highlight]
|
|
194
|
+
console.log(parsed?.moduleSpecifier); // e.g., "./src/workflows/order"
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### Cancel a Running Workflow
|
|
199
|
+
|
|
200
|
+
```typescript lineNumbers
|
|
201
|
+
// app/api/workflow-runs/cancel/route.ts
|
|
202
|
+
import { getWorld } from "workflow/runtime";
|
|
203
|
+
|
|
204
|
+
export async function POST(req: Request) {
|
|
205
|
+
const { runId } = await req.json();
|
|
206
|
+
|
|
207
|
+
if (!runId) {
|
|
208
|
+
return Response.json({ error: "runId required" }, { status: 400 });
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const world = getWorld();
|
|
212
|
+
const run = await world.runs.cancel(runId); // [!code highlight]
|
|
213
|
+
|
|
214
|
+
return Response.json({ status: run.status });
|
|
215
|
+
}
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## Related
|
|
219
|
+
|
|
220
|
+
- [world.steps](/docs/api-reference/workflow-api/world/steps) — Inspect individual step execution within a run
|
|
221
|
+
- [world.events](/docs/api-reference/workflow-api/world/events) — Query the event log for a run
|
|
222
|
+
- [getRun()](/docs/api-reference/workflow-api/get-run) — Higher-level API for working with individual runs
|
|
223
|
+
- [Observability Utilities](/docs/api-reference/workflow-api/world/observability) — Parse workflow names and hydrate data
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: world.steps
|
|
3
|
+
description: List and inspect workflow step execution data with input/output hydration.
|
|
4
|
+
type: reference
|
|
5
|
+
summary: "Methods: get(), list(). Query step metadata, hydrate serialized I/O, calculate durations."
|
|
6
|
+
prerequisites:
|
|
7
|
+
- /docs/api-reference/workflow-api/get-world
|
|
8
|
+
related:
|
|
9
|
+
- /docs/api-reference/workflow-api/world/runs
|
|
10
|
+
- /docs/api-reference/workflow-api/world/observability
|
|
11
|
+
keywords:
|
|
12
|
+
- world.steps
|
|
13
|
+
- world.steps.get
|
|
14
|
+
- world.steps.list
|
|
15
|
+
- Step
|
|
16
|
+
- step input output
|
|
17
|
+
- hydrateResourceIO
|
|
18
|
+
- step duration
|
|
19
|
+
- resolveData
|
|
20
|
+
- parseStepName
|
|
21
|
+
- devalue serialization
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
The `world.steps` interface provides access to individual step execution data within workflow runs. Use it to list steps, inspect their input/output, and build progress dashboards.
|
|
25
|
+
|
|
26
|
+
## Import
|
|
27
|
+
|
|
28
|
+
```typescript lineNumbers
|
|
29
|
+
import { getWorld } from "workflow/runtime";
|
|
30
|
+
|
|
31
|
+
const world = getWorld();
|
|
32
|
+
const steps = world.steps; // [!code highlight]
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Methods
|
|
36
|
+
|
|
37
|
+
### get()
|
|
38
|
+
|
|
39
|
+
Retrieve a single step by run ID and step ID.
|
|
40
|
+
|
|
41
|
+
```typescript lineNumbers
|
|
42
|
+
const step = await world.steps.get(runId, stepId); // [!code highlight]
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
**Parameters:**
|
|
46
|
+
|
|
47
|
+
| Parameter | Type | Description |
|
|
48
|
+
|-----------|------|-------------|
|
|
49
|
+
| `runId` | `string` | The workflow run ID |
|
|
50
|
+
| `stepId` | `string` | The step ID |
|
|
51
|
+
| `params.resolveData` | `'all' \| 'none'` | Whether to hydrate input/output data. Default: `'all'` |
|
|
52
|
+
|
|
53
|
+
**Returns:** `Step`
|
|
54
|
+
|
|
55
|
+
### list()
|
|
56
|
+
|
|
57
|
+
List steps with cursor pagination.
|
|
58
|
+
|
|
59
|
+
```typescript lineNumbers
|
|
60
|
+
const result = await world.steps.list({ // [!code highlight]
|
|
61
|
+
runId,
|
|
62
|
+
pagination: { cursor },
|
|
63
|
+
}); // [!code highlight]
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**Parameters:**
|
|
67
|
+
|
|
68
|
+
| Parameter | Type | Description |
|
|
69
|
+
|-----------|------|-------------|
|
|
70
|
+
| `params.runId` | `string` | Filter steps by run ID |
|
|
71
|
+
| `params.pagination.cursor` | `string` | Cursor for the next page |
|
|
72
|
+
| `params.resolveData` | `'all' \| 'none'` | Whether to hydrate input/output data |
|
|
73
|
+
|
|
74
|
+
**Returns:** `{ data: Step[], cursor?: string }`
|
|
75
|
+
|
|
76
|
+
## Types
|
|
77
|
+
|
|
78
|
+
### Step
|
|
79
|
+
|
|
80
|
+
| Field | Type | Description |
|
|
81
|
+
|-------|------|-------------|
|
|
82
|
+
| `runId` | `string` | Parent workflow run ID |
|
|
83
|
+
| `stepId` | `string` | Unique step identifier |
|
|
84
|
+
| `stepName` | `string` | Machine-readable step identifier |
|
|
85
|
+
| `status` | `string` | Step status: `'running'`, `'completed'`, `'failed'` |
|
|
86
|
+
| `input` | `any` | Step input data (when `resolveData: 'all'`) |
|
|
87
|
+
| `output` | `any` | Step output data (when `resolveData: 'all'`) |
|
|
88
|
+
| `error` | `any` | Error data if the step failed |
|
|
89
|
+
| `attempt` | `number` | Current retry attempt number |
|
|
90
|
+
| `startedAt` | `string` | ISO timestamp when the step started |
|
|
91
|
+
| `completedAt` | `string \| null` | ISO timestamp when the step completed |
|
|
92
|
+
| `retryAfter` | `string \| null` | ISO timestamp for next retry attempt |
|
|
93
|
+
|
|
94
|
+
<Callout type="info">
|
|
95
|
+
Step I/O is serialized using the [devalue](https://github.com/Rich-Harris/devalue) format. Use `hydrateResourceIO()` from `workflow/observability` to deserialize it for display. See [Observability Utilities](/docs/api-reference/workflow-api/world/observability).
|
|
96
|
+
</Callout>
|
|
97
|
+
|
|
98
|
+
## Examples
|
|
99
|
+
|
|
100
|
+
### List Steps for a Run without Data
|
|
101
|
+
|
|
102
|
+
Use `resolveData: 'none'` to efficiently get step metadata for progress dashboards:
|
|
103
|
+
|
|
104
|
+
```typescript lineNumbers
|
|
105
|
+
// app/api/workflow-steps/route.ts
|
|
106
|
+
import { getWorld } from "workflow/runtime";
|
|
107
|
+
import { parseStepName } from "workflow/observability"; // [!code highlight]
|
|
108
|
+
|
|
109
|
+
export async function GET(req: Request) {
|
|
110
|
+
const url = new URL(req.url);
|
|
111
|
+
const runId = url.searchParams.get("runId");
|
|
112
|
+
|
|
113
|
+
if (!runId) {
|
|
114
|
+
return Response.json({ error: "runId required" }, { status: 400 });
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const world = getWorld();
|
|
118
|
+
const steps = await world.steps.list({ // [!code highlight]
|
|
119
|
+
runId,
|
|
120
|
+
resolveData: "none", // Skip I/O for performance // [!code highlight]
|
|
121
|
+
}); // [!code highlight]
|
|
122
|
+
|
|
123
|
+
const progress = steps.data.map((step) => {
|
|
124
|
+
const parsed = parseStepName(step.stepName); // [!code highlight]
|
|
125
|
+
return {
|
|
126
|
+
stepId: step.stepId,
|
|
127
|
+
displayName: parsed?.shortName ?? step.stepName, // [!code highlight]
|
|
128
|
+
module: parsed?.moduleSpecifier,
|
|
129
|
+
status: step.status,
|
|
130
|
+
startedAt: step.startedAt,
|
|
131
|
+
completedAt: step.completedAt,
|
|
132
|
+
};
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
return Response.json({ progress, cursor: steps.cursor });
|
|
136
|
+
}
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Get Step with Hydrated Input and Output Data
|
|
140
|
+
|
|
141
|
+
Retrieve a step with its full serialized data and hydrate it for display:
|
|
142
|
+
|
|
143
|
+
```typescript lineNumbers
|
|
144
|
+
// app/api/workflow-steps/[stepId]/route.ts
|
|
145
|
+
import { getWorld } from "workflow/runtime";
|
|
146
|
+
import { parseStepName } from "workflow/observability";
|
|
147
|
+
import { // [!code highlight]
|
|
148
|
+
hydrateResourceIO, // [!code highlight]
|
|
149
|
+
observabilityRevivers, // [!code highlight]
|
|
150
|
+
} from "workflow/observability"; // [!code highlight]
|
|
151
|
+
|
|
152
|
+
export async function GET(req: Request) {
|
|
153
|
+
const url = new URL(req.url);
|
|
154
|
+
const runId = url.searchParams.get("runId");
|
|
155
|
+
const stepId = url.searchParams.get("stepId");
|
|
156
|
+
|
|
157
|
+
if (!runId || !stepId) {
|
|
158
|
+
return Response.json({ error: "runId and stepId required" }, { status: 400 });
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
const world = getWorld();
|
|
162
|
+
const step = await world.steps.get(runId, stepId); // [!code highlight]
|
|
163
|
+
|
|
164
|
+
const hydrated = hydrateResourceIO(step, observabilityRevivers); // [!code highlight]
|
|
165
|
+
const parsed = parseStepName(step.stepName);
|
|
166
|
+
|
|
167
|
+
return Response.json({
|
|
168
|
+
stepId: hydrated.stepId,
|
|
169
|
+
displayName: parsed?.shortName ?? step.stepName,
|
|
170
|
+
status: hydrated.status,
|
|
171
|
+
attempt: hydrated.attempt,
|
|
172
|
+
input: hydrated.input, // [!code highlight]
|
|
173
|
+
output: hydrated.output, // [!code highlight]
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### Calculate Step Duration from Timestamps
|
|
179
|
+
|
|
180
|
+
```typescript lineNumbers
|
|
181
|
+
import { getWorld } from "workflow/runtime";
|
|
182
|
+
|
|
183
|
+
const world = getWorld();
|
|
184
|
+
const steps = await world.steps.list({ runId });
|
|
185
|
+
|
|
186
|
+
for (const step of steps.data) {
|
|
187
|
+
if (step.completedAt) {
|
|
188
|
+
const start = new Date(step.startedAt).getTime();
|
|
189
|
+
const end = new Date(step.completedAt).getTime();
|
|
190
|
+
const durationMs = end - start; // [!code highlight]
|
|
191
|
+
console.log(`${step.stepName}: ${durationMs}ms`);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
### Parse Step Display Name from Machine-Readable ID
|
|
197
|
+
|
|
198
|
+
The `stepName` field contains a machine-readable identifier like `step//./src/workflows/order//processPayment`. Use `parseStepName()` to extract display-friendly names:
|
|
199
|
+
|
|
200
|
+
```typescript lineNumbers
|
|
201
|
+
import { parseStepName } from "workflow/observability"; // [!code highlight]
|
|
202
|
+
|
|
203
|
+
const parsed = parseStepName(step.stepName); // [!code highlight]
|
|
204
|
+
// parsed.shortName → "processPayment"
|
|
205
|
+
// parsed.moduleSpecifier → "./src/workflows/order"
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
<Callout type="warn">
|
|
209
|
+
The `stepName` field is a machine-readable identifier, not a display name. Always use `parseStepName()` from `workflow/observability` to extract the `shortName` for UI display.
|
|
210
|
+
</Callout>
|
|
211
|
+
|
|
212
|
+
## Related
|
|
213
|
+
|
|
214
|
+
- [world.runs](/docs/api-reference/workflow-api/world/runs) — List and inspect workflow runs
|
|
215
|
+
- [Observability Utilities](/docs/api-reference/workflow-api/world/observability) — Hydrate step I/O and parse display names
|
|
216
|
+
- [Workflows and Steps](/docs/foundations/workflows-and-steps) — Core concepts for steps
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Streams
|
|
3
|
+
description: Read, write, and manage real-time data streams for workflow runs.
|
|
4
|
+
type: reference
|
|
5
|
+
summary: "Methods: writeToStream(), readFromStream(), closeStream(), listStreamsByRunId(). Stream methods live directly on the world object."
|
|
6
|
+
prerequisites:
|
|
7
|
+
- /docs/api-reference/workflow-api/get-world
|
|
8
|
+
related:
|
|
9
|
+
- /docs/foundations/streaming
|
|
10
|
+
- /docs/api-reference/workflow/get-writable
|
|
11
|
+
keywords:
|
|
12
|
+
- writeToStream
|
|
13
|
+
- readFromStream
|
|
14
|
+
- closeStream
|
|
15
|
+
- listStreamsByRunId
|
|
16
|
+
- Streamer interface
|
|
17
|
+
- real-time streaming
|
|
18
|
+
- stream lifecycle
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
Stream methods live directly on the `world` object returned by `getWorld()`. Use them to write chunks, read streams, and manage stream lifecycle outside of the standard `getWritable()` pattern.
|
|
22
|
+
|
|
23
|
+
<Callout type="info">
|
|
24
|
+
For most streaming use cases, use [`getWritable()`](/docs/api-reference/workflow/get-writable) inside steps. Direct stream methods are for advanced scenarios like building custom stream consumers or managing streams from outside a workflow.
|
|
25
|
+
</Callout>
|
|
26
|
+
|
|
27
|
+
## Import
|
|
28
|
+
|
|
29
|
+
```typescript lineNumbers
|
|
30
|
+
import { getWorld } from "workflow/runtime";
|
|
31
|
+
|
|
32
|
+
const world = getWorld(); // [!code highlight]
|
|
33
|
+
// Stream methods are called directly on world — e.g. world.writeToStream()
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Methods
|
|
37
|
+
|
|
38
|
+
### writeToStream()
|
|
39
|
+
|
|
40
|
+
Write a data chunk to a named stream for a workflow run.
|
|
41
|
+
|
|
42
|
+
```typescript lineNumbers
|
|
43
|
+
await world.writeToStream("default", runId, chunk); // [!code highlight]
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**Parameters:**
|
|
47
|
+
|
|
48
|
+
| Parameter | Type | Description |
|
|
49
|
+
|-----------|------|-------------|
|
|
50
|
+
| `name` | `string` | The stream name |
|
|
51
|
+
| `runId` | `string` | The workflow run ID |
|
|
52
|
+
| `chunk` | `string \| Uint8Array` | Data to write to the stream |
|
|
53
|
+
|
|
54
|
+
### readFromStream()
|
|
55
|
+
|
|
56
|
+
Read data from a named stream as a `ReadableStream`. Returns a live stream that waits for new chunks in real time.
|
|
57
|
+
|
|
58
|
+
```typescript lineNumbers
|
|
59
|
+
const readable = await world.readFromStream("default"); // [!code highlight]
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
**Parameters:**
|
|
63
|
+
|
|
64
|
+
| Parameter | Type | Description |
|
|
65
|
+
|-----------|------|-------------|
|
|
66
|
+
| `name` | `string` | The stream name |
|
|
67
|
+
| `startIndex` | `number` | Optional starting index for partial reads. Negative values read from the tail (e.g. `-3` starts 3 chunks from the end). |
|
|
68
|
+
|
|
69
|
+
**Returns:** `ReadableStream<Uint8Array>`
|
|
70
|
+
|
|
71
|
+
### closeStream()
|
|
72
|
+
|
|
73
|
+
Close a stream when done writing.
|
|
74
|
+
|
|
75
|
+
```typescript lineNumbers
|
|
76
|
+
await world.closeStream("default", runId); // [!code highlight]
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
**Parameters:**
|
|
80
|
+
|
|
81
|
+
| Parameter | Type | Description |
|
|
82
|
+
|-----------|------|-------------|
|
|
83
|
+
| `name` | `string` | The stream name |
|
|
84
|
+
| `runId` | `string` | The workflow run ID |
|
|
85
|
+
|
|
86
|
+
### listStreamsByRunId()
|
|
87
|
+
|
|
88
|
+
List all stream names associated with a workflow run.
|
|
89
|
+
|
|
90
|
+
```typescript lineNumbers
|
|
91
|
+
const streamNames = await world.listStreamsByRunId(runId); // [!code highlight]
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**Parameters:**
|
|
95
|
+
|
|
96
|
+
| Parameter | Type | Description |
|
|
97
|
+
|-----------|------|-------------|
|
|
98
|
+
| `runId` | `string` | The workflow run ID |
|
|
99
|
+
|
|
100
|
+
**Returns:** `string[]` — Array of stream names
|
|
101
|
+
|
|
102
|
+
## Examples
|
|
103
|
+
|
|
104
|
+
### List All Streams for a Workflow Run
|
|
105
|
+
|
|
106
|
+
```typescript lineNumbers
|
|
107
|
+
// app/api/workflow-streams/route.ts
|
|
108
|
+
import { getWorld } from "workflow/runtime";
|
|
109
|
+
|
|
110
|
+
export async function GET(req: Request) {
|
|
111
|
+
const url = new URL(req.url);
|
|
112
|
+
const runId = url.searchParams.get("runId");
|
|
113
|
+
|
|
114
|
+
if (!runId) {
|
|
115
|
+
return Response.json({ error: "runId required" }, { status: 400 });
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const world = getWorld();
|
|
119
|
+
const streamNames = await world.listStreamsByRunId(runId); // [!code highlight]
|
|
120
|
+
|
|
121
|
+
return Response.json({ streams: streamNames });
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Read a Stream as a Response
|
|
126
|
+
|
|
127
|
+
```typescript lineNumbers
|
|
128
|
+
// app/api/workflow-streams/read/route.ts
|
|
129
|
+
import { getWorld } from "workflow/runtime";
|
|
130
|
+
|
|
131
|
+
export async function GET(req: Request) {
|
|
132
|
+
const url = new URL(req.url);
|
|
133
|
+
const streamName = url.searchParams.get("name");
|
|
134
|
+
|
|
135
|
+
if (!streamName) {
|
|
136
|
+
return Response.json({ error: "name required" }, { status: 400 });
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const world = getWorld();
|
|
140
|
+
const readable = await world.readFromStream(streamName); // [!code highlight]
|
|
141
|
+
|
|
142
|
+
return new Response(readable, {
|
|
143
|
+
headers: { "Content-Type": "application/octet-stream" },
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Related
|
|
149
|
+
|
|
150
|
+
- [Streaming](/docs/foundations/streaming) — Core concepts for streaming data from workflows
|
|
151
|
+
- [getWritable()](/docs/api-reference/workflow/get-writable) — The standard way to write to streams from within steps
|
|
152
|
+
- [world.runs](/docs/api-reference/workflow-api/world/runs) — List runs that may have associated streams
|
|
@@ -221,6 +221,10 @@ While hooks are powerful, they require you to manually handle HTTP requests and
|
|
|
221
221
|
|
|
222
222
|
When using Workflow SDK, webhooks are automatically wired up at `/.well-known/workflow/v1/webhook/:token` without any additional setup.
|
|
223
223
|
|
|
224
|
+
<Callout type="warn">
|
|
225
|
+
`createWebhook()` exposes a public route at `/.well-known/workflow/v1/webhook/:token`, and the token in that URL is the only authorization performed for incoming requests. This is convenient for prototypes and a simple developer experience because you can share the webhook URL (endpoint) without creating another route, but if you need stronger security, prefer [`createHook()`](/docs/api-reference/workflow/create-hook) behind your own route and authorize the request before calling [`resumeHook()`](/docs/api-reference/workflow-api/resume-hook) to avoid unauthenticated workflow resumptions.
|
|
226
|
+
</Callout>
|
|
227
|
+
|
|
224
228
|
<Callout type="info">
|
|
225
229
|
See the full API reference for [`createWebhook()`](/docs/api-reference/workflow/create-webhook) for all available options.
|
|
226
230
|
</Callout>
|
|
@@ -593,6 +593,7 @@ Stream errors don't trigger automatic retries for the producer step. Design your
|
|
|
593
593
|
- [`sleep()` API Reference](/docs/api-reference/workflow/sleep) - Pause workflow execution for a duration
|
|
594
594
|
- [`start()` API Reference](/docs/api-reference/workflow-api/start) - Start workflows and access the `Run` object
|
|
595
595
|
- [`getRun()` API Reference](/docs/api-reference/workflow-api/get-run) - Retrieve runs and their streams later
|
|
596
|
+
- [world.streams](/docs/api-reference/workflow-api/world/streams) - Low-level stream read/write/close via World SDK
|
|
596
597
|
- [DurableAgent](/docs/api-reference/workflow-ai/durable-agent) - AI agents with built-in streaming support
|
|
597
598
|
- [Errors and Retries](/docs/foundations/errors-and-retries) - Understanding error handling and retry behavior
|
|
598
599
|
- [Serialization](/docs/foundations/serialization) - Understanding what data types can be passed in workflows
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "workflow",
|
|
3
|
-
"version": "4.2.0-beta.
|
|
3
|
+
"version": "4.2.0-beta.75",
|
|
4
4
|
"description": "Workflow SDK - Build durable, resilient, and observable workflows",
|
|
5
5
|
"main": "dist/typescript-plugin.cjs",
|
|
6
6
|
"type": "module",
|
|
@@ -57,18 +57,18 @@
|
|
|
57
57
|
},
|
|
58
58
|
"dependencies": {
|
|
59
59
|
"ms": "2.1.3",
|
|
60
|
-
"@workflow/astro": "4.0.0-beta.
|
|
61
|
-
"@workflow/cli": "4.2.0-beta.
|
|
62
|
-
"@workflow/core": "4.2.0-beta.
|
|
63
|
-
"@workflow/errors": "4.1.0-beta.
|
|
60
|
+
"@workflow/astro": "4.0.0-beta.49",
|
|
61
|
+
"@workflow/cli": "4.2.0-beta.75",
|
|
62
|
+
"@workflow/core": "4.2.0-beta.75",
|
|
63
|
+
"@workflow/errors": "4.1.0-beta.20",
|
|
64
64
|
"@workflow/typescript-plugin": "4.0.1-beta.5",
|
|
65
65
|
"@workflow/utils": "4.1.0-beta.13",
|
|
66
|
-
"@workflow/next": "4.0.1-beta.
|
|
67
|
-
"@workflow/nest": "0.0.0-beta.
|
|
68
|
-
"@workflow/nitro": "4.0.1-beta.
|
|
69
|
-
"@workflow/nuxt": "4.0.1-beta.
|
|
70
|
-
"@workflow/sveltekit": "4.0.0-beta.
|
|
71
|
-
"@workflow/rollup": "4.0.0-beta.
|
|
66
|
+
"@workflow/next": "4.0.1-beta.71",
|
|
67
|
+
"@workflow/nest": "0.0.0-beta.24",
|
|
68
|
+
"@workflow/nitro": "4.0.1-beta.70",
|
|
69
|
+
"@workflow/nuxt": "4.0.1-beta.59",
|
|
70
|
+
"@workflow/sveltekit": "4.0.0-beta.64",
|
|
71
|
+
"@workflow/rollup": "4.0.0-beta.32"
|
|
72
72
|
},
|
|
73
73
|
"devDependencies": {
|
|
74
74
|
"@types/ms": "2.1.0",
|