world.steps
List and inspect workflow step execution data with input/output hydration.
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.
Import
import { getWorld } from "workflow/runtime";
const world = getWorld();
const steps = world.steps; Methods
get()
Retrieve a single step by run ID and step ID.
const step = await world.steps.get(runId, stepId); Parameters:
| Parameter | Type | Description |
|---|---|---|
runId | string | The workflow run ID |
stepId | string | The step ID |
params.resolveData | 'all' | 'none' | Whether to hydrate input/output data. Default: 'all' |
Returns: Step
list()
List steps with cursor pagination.
const result = await world.steps.list({
runId,
pagination: { cursor },
}); Parameters:
| Parameter | Type | Description |
|---|---|---|
params.runId | string | Filter steps by run ID |
params.pagination.cursor | string | Cursor for the next page |
params.resolveData | 'all' | 'none' | Whether to hydrate input/output data |
Returns: { data: Step[], cursor?: string }
Types
Step
| Field | Type | Description |
|---|---|---|
runId | string | Parent workflow run ID |
stepId | string | Unique step identifier |
stepName | string | Machine-readable step identifier |
status | string | Step status: 'running', 'completed', 'failed' |
input | any | Step input data (when resolveData: 'all') |
output | any | Step output data (when resolveData: 'all') |
error | any | Error data if the step failed |
attempt | number | Current retry attempt number |
startedAt | string | ISO timestamp when the step started |
completedAt | string | null | ISO timestamp when the step completed |
retryAfter | string | null | ISO timestamp for next retry attempt |
Step I/O is serialized using the devalue format. Use hydrateResourceIO() from workflow/observability to deserialize it for display. See Observability Utilities.
Examples
List Steps for a Run without Data
Use resolveData: 'none' to efficiently get step metadata for progress dashboards:
import { getWorld } from "workflow/runtime";
import { parseStepName } from "workflow/observability";
export async function GET(req: Request) {
const url = new URL(req.url);
const runId = url.searchParams.get("runId");
if (!runId) {
return Response.json({ error: "runId required" }, { status: 400 });
}
const world = getWorld();
const steps = await world.steps.list({
runId,
resolveData: "none", // Skip I/O for performance
});
const progress = steps.data.map((step) => {
const parsed = parseStepName(step.stepName);
return {
stepId: step.stepId,
displayName: parsed?.shortName ?? step.stepName,
module: parsed?.moduleSpecifier,
status: step.status,
startedAt: step.startedAt,
completedAt: step.completedAt,
};
});
return Response.json({ progress, cursor: steps.cursor });
}Get Step with Hydrated Input and Output Data
Retrieve a step with its full serialized data and hydrate it for display:
import { getWorld } from "workflow/runtime";
import { parseStepName } from "workflow/observability";
import {
hydrateResourceIO,
observabilityRevivers,
} from "workflow/observability";
export async function GET(req: Request) {
const url = new URL(req.url);
const runId = url.searchParams.get("runId");
const stepId = url.searchParams.get("stepId");
if (!runId || !stepId) {
return Response.json({ error: "runId and stepId required" }, { status: 400 });
}
const world = getWorld();
const step = await world.steps.get(runId, stepId);
const hydrated = hydrateResourceIO(step, observabilityRevivers);
const parsed = parseStepName(step.stepName);
return Response.json({
stepId: hydrated.stepId,
displayName: parsed?.shortName ?? step.stepName,
status: hydrated.status,
attempt: hydrated.attempt,
input: hydrated.input,
output: hydrated.output,
});
}Calculate Step Duration from Timestamps
import { getWorld } from "workflow/runtime";
const world = getWorld();
const steps = await world.steps.list({ runId });
for (const step of steps.data) {
if (step.completedAt) {
const start = new Date(step.startedAt).getTime();
const end = new Date(step.completedAt).getTime();
const durationMs = end - start;
console.log(`${step.stepName}: ${durationMs}ms`);
}
}Parse Step Display Name from Machine-Readable ID
The stepName field contains a machine-readable identifier like step//./src/workflows/order//processPayment. Use parseStepName() to extract display-friendly names:
import { parseStepName } from "workflow/observability";
const parsed = parseStepName(step.stepName);
// parsed.shortName → "processPayment"
// parsed.moduleSpecifier → "./src/workflows/order"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.
Related
- world.runs — List and inspect workflow runs
- Observability Utilities — Hydrate step I/O and parse display names
- Workflows and Steps — Core concepts for steps