# Examples

Each example is a small runnable package that shows part of the Kassette API. The examples live in [`examples/`](https://github.com/lostinpatterns/kassette/tree/main/examples). Each one is a separate pnpm workspace package.

Install dependencies once from the repository root:

```bash
pnpm install
```

Most examples call an LLM through the AI SDK. Set one provider key before you run them:

```bash
export OPENAI_API_KEY=...
# or export ANTHROPIC_API_KEY=...
# or export GOOGLE_GENERATIVE_AI_API_KEY=...
```

By default, the examples choose a provider and model automatically. To choose them yourself, set `LLM_PROVIDER` and `LLM_MODEL`.

## Workflow API examples

These examples use the high-level workflow API: `kassette()`, `ctx.step`, `ctx.suspend`, `ctx.parallel`, `ctx.sleep`, `fork()`.

| Example                                                                                                | Run                                            | Shows                                                                                                                                     |
| ------------------------------------------------------------------------------------------------------ | ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| [`agent-loop`](https://github.com/lostinpatterns/kassette/tree/main/examples/agent-loop)               | `pnpm --filter example-agent-loop demo`        | A durable think, act, observe loop. LLM turns and tool calls are separate steps, and flaky tools retry without re-running prior LLM work. |
| [`loan-underwriting`](https://github.com/lostinpatterns/kassette/tree/main/examples/loan-underwriting) | `pnpm --filter example-loan-underwriting demo` | Parallel credit and appraisal branches, independent human review suspends, and a final decision fork that reuses upstream journaled work. |
| [`coding-agent`](https://github.com/lostinpatterns/kassette/tree/main/examples/coding-agent)           | `pnpm --filter example-coding-agent demo`      | Speculative branching with `fork()`. Reuse one memoized plan for several implementations, then backtrack from the plan step if needed.    |
| [`deploy-assistant`](https://github.com/lostinpatterns/kassette/tree/main/examples/deploy-assistant)   | `pnpm --filter example-deploy-assistant demo`  | A webhook-driven deployment assistant. Resume coordinates ride inside outbound messages, so inbound replies route directly to the waiter. |

The deploy assistant starts a local webhook server at `http://localhost:8000/webhook`. Send an `email.received` payload to start a run.

```bash
curl -X POST http://localhost:8000/webhook \
  -H 'content-type: application/json' \
  -d '{"type":"email.received","email":{"from":"ops@example.com","to":"deploy@example.com","subject":"deploy prod","body":"Deploy the latest approved commit","messageId":"m1"}}'
```

## Framework middleware

[`examples/vercel-ai-sdk/`](https://github.com/lostinpatterns/kassette/tree/main/examples/vercel-ai-sdk) uses `@usekassette/core` directly instead of using the workflow wrapper. It records AI SDK calls inside middleware.

| Command                                           | Shows                                                                                                                                   |
| ------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `pnpm --filter example-vercel-ai-sdk demo`        | Non-streaming `generateText` replay. The first run calls the provider, the second run returns recorded outputs from the journal.        |
| `pnpm --filter example-vercel-ai-sdk demo:stream` | Streaming `streamText` replay. The first run records chunks, and the second run pumps the recorded stream without calling the provider. |

## Cloudflare examples

These next examples run in Cloudflare Workers. They store journals in R2 through `RemoteStorage`.

| Example                                                                                                | Run                                           | Shows                                                                                                                                    |
| ------------------------------------------------------------------------------------------------------ | --------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| [`cloudflare-worker`](https://github.com/lostinpatterns/kassette/tree/main/examples/cloudflare-worker) | `pnpm --filter example-cloudflare-worker dev` | Synchronous HTTP start and resume routes. A later request can resume the same run in a different isolate because R2 is the handoff.      |
| [`cloudflare-queue`](https://github.com/lostinpatterns/kassette/tree/main/examples/cloudflare-queue)   | `pnpm --filter example-cloudflare-queue dev`  | Fire-and-forget submission through a queue. Visibility-timeout redelivery is the crash detector, and replay resumes from the R2 journal. |

For the queue example, use the local and deployment walkthrough in [`examples/cloudflare-queue/README.md`](https://github.com/lostinpatterns/kassette/blob/main/examples/cloudflare-queue/README.md). It includes Miniflare setup, R2 and Queue bindings, resume events, and the crash-recovery demo.

## Choosing one

- Start with `agent-loop` for the smallest durable agent loop.
- Use `loan-underwriting` to see `parallel()`, multiple human review steps, and `fork()` in one workflow.
- Use `coding-agent` to see speculative branches and backtracking.
- Use `deploy-assistant` when webhooks need to resume suspended work.
- Use `vercel-ai-sdk` when you want to add durability inside an AI SDK integration instead of wrapping a whole workflow.
- Use `cloudflare-worker` when HTTP requests start and resume work in Cloudflare Workers.
- Use `cloudflare-queue` when queue redelivery should handle crash recovery.
