createSmithers, configure AI agents, compose tasks in a <Sequence>, read previous outputs through ctx, and inspect the results.
By the end, you will have a three-step code review workflow: analyze a codebase, generate a fix, then produce a summary report.
Step 1: Project Setup
Create a new directory and install dependencies:Step 2: Define Schemas
createSmithers accepts a record of Zod schemas. Each schema becomes a named output table that Smithers auto-creates in SQLite. You never write SQL or Drizzle table definitions by hand.
analysis,fix, andreportare now registered output names. You reference them as strings in<Task output="analysis">.- SQLite tables are auto-created with the correct columns, plus auto-populated
runId,nodeId, anditerationcolumns. Workflowandsmithersare returned pre-configured for this schema set.
Step 3: Configure Agents
Define your AI agents using the Vercel AI SDK. You can use any provider, but this example uses Anthropic:Step 4: Build the Workflow
Now compose the tasks. Tasks inside<Workflow> run sequentially by default (top to bottom). You can also use <Sequence> explicitly for clarity:
ctx.outputMaybe()returnsundefinedif the task has not completed yet. This is safe for conditional rendering.- Conditional rendering (
{analysis ? <Task ... /> : null}) controls task visibility. Thefixtask only mounts afteranalyzefinishes and provides output. ctx.inputcontains the input object you pass at run time. Here we expect{ repo: string, focusArea?: string }.- Output keys like
"analysis"match the schema names passed tocreateSmithers.
Step 5: Create the Runner
You can run the workflow programmatically or via the CLI. Here is the programmatic approach:Step 6: Run It
main.ts required):
Step 7: Inspect Results
Use the CLI to inspect the completed run:smithers.db) contains the full execution history. You can also query it directly:
What Happened
Here is the execution flow:- Render 1: Smithers renders the JSX tree. Only
analyzeis mounted (the other tasks are guarded bynullchecks). The engine executesanalyze. - Render 2:
ctx.outputMaybe("analysis", ...)now returns the persisted row. Thefixtask mounts. The engine executesfix. - Render 3: Both
analysisandfixare available. Thereporttask mounts. The engine executesreport. - Render 4: All tasks are finished. No runnable tasks remain. The run completes with status
"finished".
analyze already has a valid output row, skip it, and continue from fix.
Adding Tools
To give your agents access to the filesystem, add built-in tools:Next Steps
- Structured Output — How schema validation works in depth.
- Error Handling — Add retries, timeouts, and fallback paths.
- Resumability — Understand crash recovery and deterministic replay.
- Patterns — Recommended project structure for larger workflows.
- Components — Reference for all JSX components.