Subflow is a top-level component export. createSmithers(...) returns typed
Workflow, Task, Approval, Sandbox, Signal, and pure structural helpers
such as Branch, Loop, and Parallel; import Subflow from
"smithers-orchestrator" when you need a child workflow boundary.
The workflow prop takes a SmithersWorkflow value, which is exactly what the
default export of a workflow file is. smithers((ctx) => ...) returns a
SmithersWorkflow, so a child workflow is just another createSmithers module:
<Subflow workflow={...}>.
The parent declares the schema it wants to persist the subflow result under;
that key does not have to match the child’s schema key, but the shape must match
the child result you expect:
input you pass via its own ctx.input. Type it by giving
the child’s createSmithers an input schema (above); without one, ctx.input
is untyped and you must guard each field (ctx.input?.repo ?? ".").
Read the persisted subflow result in the parent exactly like a task output:
ctx.outputMaybe(parent.outputs.childSummary, { nodeId: "run-child" }). The
nodeId is the <Subflow id>, and the output target is the parent’s schema key.
Single-file parent and child
For small examples and eval fixtures, define both factories in one.tsx file.
Use separate createSmithers calls so the child has its own ctx.input type and
output refs, and the parent has its own output table for the subflow result:
input schema is optional but recommended whenever the parent
reads ctx.input.repo; it turns ctx.input from unknown into a typed object.
The child has its own input schema and its own ctx.input, populated from the
value passed through the parent’s <Subflow input={...}> prop.
Notes
childRun(default) gives the child its own DB row; retry/cache/resume scope it as a unit.inlinerenders the child tree as siblings in the parent plan, sharing its scope.- Subflows compose; children may contain
<Subflow>themselves.