run function.
That context is made from:
- validated workflow input
- resolved dependency outputs from
needs - execution metadata such as the execution id and attempt number
- cancellation and timeout state
ctx.output("...", ...).
The Basic Shape
A step looks like this:run argument is the step context.
Step Context Interface
The source type is namedBuilderStepContext (also referred to as StepContext in some older docs).
Conceptually, Smithers provides something like:
run function receives:
input
input is the validated workflow input defined at the workflow boundary:
Dependency Outputs
Dependencies are the main source of typed step-to-step dataflow.fix, the analysis value is already resolved and typed as Analysis.
This has two important consequences:
- the dependency edge is explicit in the graph
- the step body does not need to know how persistence works
Execution Metadata
Smithers exposes a small amount of orchestration metadata in every step context.executionId
The durable id for the workflow run. Useful for logging, tracing, and correlating external side effects.
stepId
The logical id of the currently executing step.
attempt
The current attempt number for this step. Starts at 1 and increments on each retry.
signal
An AbortSignal that fires when:
- the step times out
- the workflow is interrupted
- the runtime is shutting down
iteration
For looped workflows, this identifies the current durable iteration. For non-loop steps, it is usually 0.
loop
An object with loop metadata: { iteration: number }. Provides structured access to the current loop iteration. This is available on every step context; for non-looped steps, loop.iteration is 0.
No Hook API
There is nouseCtx() in the builder design.
That is intentional:
- workflows are not React components
- steps do not re-render to discover new dependencies
- runtime dataflow should stay explicit in the builder graph
Services Do Not Belong in Step Context
The step context is for workflow data, not infrastructure dependencies. To access services, use normal Effect dependency injection:- Smithers passes workflow data
- Effect provides runtime capabilities
Multiple Dependencies
Steps can depend on more than one upstream value:needs.
Historical Access
The old API exposed helpers likelatest() and outputMaybe() for global output lookup. The builder design should avoid making that the default.
The preferred rule is:
- if a step needs an upstream value, declare it in
needs - if a workflow needs historical or ad hoc reads, use an explicit repository or workflow-state service
Suggested Mental Model
Think of a Smithers step as a typed function:- a missing dependency should be declared in
needs - the workflow needs a repository or service for advanced queries
Next Steps
- Services — Define and provide Effect services.
- Builder API — Full builder primitive reference.
- Approvals — Durable approval gates.