Examples
July 9, 2026 · View on GitHub
Each example lives in a flat examples/* directory with an index.ts or index.mts entrypoint and a metadata.json file describing its origin and comparison purpose.
Every example is dual-mode: run it directly against a real model with OPENAI_API_KEY=... npx tsx examples/<name>/index.ts, while its tests use injected mocks.
Start Here
- Decisions — the model choosing exactly one legal machine event:
twenty-questions/index.ts - Minimal streaming text workflow:
joke/index.ts - Authoring reusable requests, parts-based messages, and schema-typed state meta:
email-drafter/index.ts - Human-in-the-loop, the idle-first way:
human-in-the-loop/index.ts - Long-running onboarding with durable idle gates:
long-running-onboarding/index.ts - Running with host actors:
ai-sdk-host/index.ts - Machines as data — a full workflow (decision, text request, idle human step) authored as a real
.jsonfile:json-agent/index.ts - Host actor guide:
../docs/host-actors.md - Framework comparison examples:
supervisor/index.test.ts,plan-and-execute/index.test.ts,rag/index.test.ts,tool-calling/index.test.ts
XState Examples
These use setupAgent(...) (or plain XState setup(...) plus createTextLogic(...)) from @statelyai/agent. The runtime is flexible: use runAgent(...)/createActor(...) locally, provide different host actors in apps, or persist XState snapshots in a platform adapter.
twenty-questions/index.ts: decision loop with machine-held context, typed model aliases, final-turn guess enforcement, scoring, play-again reset, and machine-owned user promptsemail-drafter/index.ts: typed email workflow with independently testable requestsemail-drafter-inspector/index.ts: the email-drafter machine run as one livecreateActorsession wired tocreateWebSocketInspector, so the whole flow is visible in the Stately Inspector (works without an API key via heuristic fallbacks)game-agent/index.ts: turn-based game workflow withallowedEventsnarrowed as a function of inputjoke/index.ts: minimal streaming text workflowtriage/index.ts: structured-output support ticket triagejson-agent/index.ts:setupAgent.fromConfig(...)lowering a support-ticket workflow authored as a real.jsonfile (decision, text request, idle human approval step)supervisor/index.ts: a routing request's structured output hands off to a format-specific workerhuman-in-the-loop/index.ts: draft → idle review (typedmeta.interaction) → APPROVE/REJECT redraft, with a JSON snapshot round-triplong-running-onboarding/index.ts: Google ADK-style onboarding coordinator with durable typed state, two idle dormancy gates, JSON snapshot resume across days, and delegated IT provisioningfile-snapshot-store/index.ts: durable HITL checkpoints in a file-backed snapshot store — each idle settle writes JSON to disk and a freshrunAgentcall resumes across turnsmachine-as-tool/index.ts: a whole agent machine embedded inside one tool call of a host harness — start/resume tools bridge a JSON-safe snapshot handle and read the typed interaction metarag/index.ts: retrieve (typed plain actor, keyword scoring over a sample corpus) → grounded answer, with conversational memory in contexttool-calling/index.ts: model selects a tool (structured output), typed tool actors execute, progress viaonTransitionreact-agent/index.ts: LangGraph'screateReactAgentas an explicit visible loop — onereasonOrActrequest per iteration returns a call-a-tool-or-answer union, typed tool actors execute, and a step-budget guard breaks the loop with a best-effort answerplan-and-execute/index.ts: planner structured output, execution states iterate the plan (keeps the ReWOO evidence-map idea)sql-agent/index.ts: query generation, DB execution, and answer synthesis as separate typed statesai-sdk-host/index.ts: Vercel AI SDK host actorsai-sdk-sub-agents/index.ts: Vercel AI SDK ToolLoopAgent workers exposed as host-owned toolsai-sdk-marketing-chain/index.ts: Vercel AI SDK sequential chain as an explicit XState machineai-sdk-routing/index.ts: Vercel AI SDK routing as an explicit XState machineai-sdk-parallel-review/index.ts: Vercel AI SDK parallel review as an explicit XState machineai-sdk-orchestrator-worker/index.ts: Vercel AI SDK orchestrator-worker as an explicit XState machineai-sdk-evaluator-optimizer/index.ts: Vercel AI SDK evaluator-optimizer as an explicit XState machinedebate-sub-agents/index.ts: facilitator schedules two event-based debater sub-agentsai-sdk-game-host/index.ts: Vercel AI SDK step runneropenai-sdk-host/index.ts: the executor contract implemented directly against the rawopenaipackage (Chat Completions API), no Vercel AI SDK in betweenanthropic-sdk-host/index.ts: the executor contract implemented directly against the raw@anthropic-ai/sdkpackage (Messages API), no Vercel AI SDK in betweencloudflare-workers-ai-host/index.ts: Cloudflare Workers AI step runnercloudflare-agent-host/index.ts: Cloudflare Agents host, persisting XState snapshots in Durable Object statesubflows/index.ts: multi-step agent machines invoking other agent machines as XState child actors, each keeping its own executor bindingriver-crossing/index.ts: the machine as a verifiable environment — the model proposes moves on the wolf/goat/cabbage puzzle, guards reject illegal ones (rejected-by-guard+ retry), and a prototypedescribeMachine(...)renders the machine's rules/states/events into the decide contexttodo-nl/index.ts: free-text commands mapped onto a real app's machine events (add/toggle/delete) via oneagent.planinvoke — a multi-action command drives several plan steps in order, the built-in done move ends the plan, and nonexistent ids are guard-rejected mid-plan with a retry;todo-nl/imperative.tsis the same app without the library (rawgenerateObjectwhile-loop) as a deliberate A/B paircontext-compaction/index.ts: a self-managing chat loop — history is compacted into a running summary by an explicitcompactingstate once it exceeds a threshold, keeping only the last N turns and feeding the summary back as contextguardrails/index.ts: input/output guardrails as explicit gate states — validate the question before generating (refuse out-of-scope pre-generation), verify the answer after, revise at most once, never silently return unverified content (gating, vs. evaluator-optimizer's refining)
Comparison Examples
These map LangGraph, Burr, and CrewAI Flow patterns onto XState. The dedicated per-framework ports were consolidated into pattern examples.
Multi-step agent patterns:
supervisor/index.test.ts: supervisor routing / handoff (LangGraph supervisor-handoff, Burr multi-agent collaboration, CrewAI content creator)swarm-handoff/index.test.ts: persistent multi-agent network handing off across turnsplan-and-execute/index.test.ts: plan-and-execute, keeping the ReWOO evidence-map ideasubflows/index.test.ts: nested subgraphs / child flowsrag/index.test.ts: retrieval-augmented generation (LangGraph RAG, Burr conversational RAG)tool-calling/index.test.ts: tool calling with intermediate progress (Burr tool calling, LangGraph tool-calling-progress)sql-agent/index.test.ts: SQL / tool-heavy agent workflowhuman-in-the-loop/index.test.ts: human-in-the-loop plus snapshot persistencelong-running-onboarding/index.test.ts: long-running pause/resume onboarding flow with delegated IT provisioningparallel-streams/index.test.ts: parallel worker streams over a side channelsse-transport/index.test.ts: relaying provider stream chunks over SSE
AI SDK pattern set (fan-out, routing, reflection, map-reduce shapes):
ai-sdk-orchestrator-worker/index.test.tsai-sdk-parallel-review/index.test.tsai-sdk-routing/index.test.tsai-sdk-evaluator-optimizer/index.test.tsai-sdk-marketing-chain/index.test.ts
New examples should use createTextLogic(...) for reusable LLM work and setupAgent({ schemas, actors, requests }) for schema-first machine authoring. Decisions are authored inline in states via src: 'agent.decide' (state-local); to reuse one across states, share the input builder function (a ({ context }) => ({ model, system, prompt, allowedEvents }) fn), not an actor. There is no decisions: key on setupAgent.