damiensmith.dev

llm-cassette

Record and replay OpenAI and Anthropic calls in tests. When you edit a prompt, a judge model decides whether the saved response still fits, so tests survive prompt changes.

TypeScriptVitestJestLLM-as-judge
About

What it does

The first test run calls the real API and saves each response to a cassette file next to the test. Later runs, including CI, replay them: no network, no API keys, no cost. Calls to OpenAI, Anthropic and OpenRouter are intercepted at the network layer, so app code doesn't change.

Exact-match cassettes break on every prompt edit, and loose matching silently replays stale answers. llm-cassette matches cheapest first: an exact match, then a match with timestamps and IDs scrubbed, then hard checks (a changed model, setting, output format, tool schema or image always re-records). Only when the prompt text alone changed does a judge model decide whether the saved response still answers the new prompt.

The judge only runs while recording, and its verdict is saved in the cassette, so replay stays deterministic and keyless. Jev is the default judge; Respan's span-01 or your own can be swapped in.

  • +Works with Vitest and Jest, streaming included
  • +Supports OpenAI Chat Completions and Responses, Anthropic Messages and OpenRouter
  • +Published on npm as @damiensmith1/llm-cassette
llm-cassette: 38 exact, 4 judged, 1 recorded
  summarizes (test/summary.test.ts)
    judged p=0.96: POST /v1/messages
    recorded: POST /v1/messages — no longer fits (p=0.04 < 0.85)