v0.3.0 · MIT · zero runtime deps · vitest-native

Run your agent test once.
Replay it forever, offline.

tapedeck wraps your Vercel AI SDK model in one line. Record once against the live API and commit the cassette — every CI run after that is deterministic, offline, free, and stream-accurate.

$ pnpm add -D @nkwib/tapedeck

One-line wrap

cassetteMiddleware plugs into wrapLanguageModel. It normalizes at the SDK abstraction, so it's provider-agnostic — swap OpenAI for Anthropic and the cassette still replays.

Stream-accurate

Recorded stream parts replay as a genuine ReadableStream through the SDK's own simulateReadableStream. streamText and tool-call streaming see the exact surface they would live.

Deterministic CI

Cassettes are keyed by a stable hash of the request. In replay a miss throws — a changed prompt or tool schema fails the test loudly instead of replaying stale data.

Secrets never reach disk

Redaction is key-name based and runs at record time. A replayed cassette that still contains a value a matcher would strip throws CassetteSecretError — a committed key fails the build instead of leaking.

Diff-clean cassettes

Cassettes are pretty-printed JSON designed to read in a PR. You can see exactly what the model returned, review it like code, and re-record with one env var when it changes.

Calling card, not platform

No proxy, no infra, no hosted dashboard, no SaaS. Zero runtime dependencies beyond the ai peer. tapedeck's own tests use tapedeck — zero distraction surface.

A cassette is just JSON you can read

Pretty-printed, hash-addressed, and designed to diff cleanly in a PR. The request half is the cache key; the response half is the recorded stream parts. Commit it and your test is offline forever — until the request changes and the hash misses.

How the format works
// cassettes/checkout-flow.cassette.json — diff-stable.
{
  "version": "tapedeck@0.1.0",
  "hash": "sha256:abc123…",
  "request": { "modelId": "gpt-4o", /* … */ },
  "response": {
    "type": "stream",
    "chunks": [
      { "type": "text-delta", "delta": "I'll" },
      { "type": "tool-call", "toolName": "search" }
    ]
  }
}

Wrap an existing Vercel AI SDK agent in one line.

Read mode from an env var, record your suite once against the live API, and commit the cassettes. Flip CASSETTE_MODE=replay in CI — deterministic, offline, and free from then on.