When to Use Workflows
Ask yourself: does this job need more than one step, and does the order matter? If you have a single prompt that needs one LLM call, a workflow is overkill. But the moment you need coordination — analyze, then fix, then validate, then report — you need answers to questions that ad hoc scripts dodge:- Which agent handles each step?
- How does data flow between steps?
- Which steps can run in parallel?
- Where does a human need to approve something?
- What happens when a step fails at 2 AM?
Core Principles
Three ideas, in order:- Define tasks as JSX components with typed input/output schemas
- Compose tasks using control-flow primitives (
<Sequence>,<Parallel>,<Branch>,<Loop>) - Run workflows with built-in persistence, resumability, approval gates, and streaming
Building Blocks
Tasks
A<Task> is the smallest unit of work. It has an id, an output schema, and one of three modes. The simplest way to see the difference is to look at all three:
Control Flow
“But why not just writeawait step1(); await step2();?”
You could. But then you lose resumability, parallelism, and conditional branching — and you’re back to the ad hoc script. These four primitives give you the same expressiveness with none of the bookkeeping:
| Component | Purpose | Behavior |
|---|---|---|
<Sequence> | Run tasks one after another | Each child waits for the previous to complete |
<Parallel> | Run tasks concurrently | All children start together (respecting concurrency limits) |
<Branch> | Choose one path | Evaluates a condition and runs then or else |
<Loop> | Repeat until a condition | Re-executes children each iteration until until is true |
Schemas
You might be wondering: how does Smithers know if an agent returned useful output or nonsense? Every task declares what it produces using a Zod schema. Smithers validates the agent’s output against that schema automatically. If validation fails, the agent is retried with the error as feedback — no manual wrangling required.outputs object is type-checked at compile time. Write outputs.analysis incorrectly and the compiler catches it — not your production logs at midnight.
A Complete Workflow
Here is a workflow that analyzes code, optionally fixes issues, and writes a report:- Typed schemas define what each task produces. No ambiguity about shape.
- Sequential execution via
<Sequence>ensuresanalyzefinishes before anything downstream runs. - Typed handoff via
deps={{ ... }}gives downstream tasks direct access to upstream output — no prompt-plumbing boilerplate. - Render-time branching via
ctx.outputMaybe(...)handles the case where the analysis hasn’t run yet (first render) versus when it has (subsequent renders). - Conditional logic with
<Branch>skips the fix step entirely when there are no issues.
How Execution Works
The workflow runs in a loop — think of it like React’s render cycle, but for task orchestration:- Render — Smithers renders the JSX tree with the current context
- Extract — It finds executable tasks from the rendered tree
- Execute — Ready tasks run (agent calls, functions, or static writes)
- Persist — Outputs are validated and written to SQLite
- Repeat — The tree re-renders with updated context until all tasks complete
outputMaybe respond to what’s already been computed. This is the high-level cycle. For the full internal model, see Execution Model.
Durability
Here is where workflows earn their keep over a chain ofawait calls.
Every completed task writes its output to SQLite immediately. If the process crashes:
- Completed tasks are never re-run
- The workflow resumes from the last incomplete task
- Approval gates survive restarts
- Loop iteration state is preserved
Running Workflows
From the CLI
Programmatically
Result Statuses
A workflow run resolves to one of these statuses:| Status | Meaning |
|---|---|
finished | All tasks completed successfully |
failed | A task failed after exhausting retries |
waiting-approval | Paused at an approval gate |
cancelled | Stopped by the user or runtime |
Next Steps
- Control Flow — Learn the four control-flow primitives and when to use each.
- Workflow State — Understand how data flows between tasks.
- JSX Quickstart — Build your first workflow hands-on.