Vercel AI SDK coupling

What we did

tapedeck targets only the Vercel AI SDK as a peer dependency (ai >= 6.0.0 < 8), and specifically its language-model middleware surface. It is a middleware, not a generic recorder. It records the SDK's normalized request/response shape; it does not know, and deliberately does not abstract over, any provider's raw wire format.

There is no "universal HTTP recorder" mode, no provider plugin system, no neutral cassette schema meant to outlive the SDK. A cassette is exactly as portable as the SDK abstraction it was recorded against.

Why bind tightly instead of staying generic

The honest framing: the SDK's request/response shape at the middleware layer is the structural ceiling on tapedeck's lifetime. If that shape changes incompatibly, tapedeck changes with it. We chose to accept that ceiling rather than paper over it, for two reasons.

  1. Generic recording is what proxies already do — badly. A provider-agnostic HTTP recorder (nock/Polly) has to understand every provider's SSE envelope, auth scheme, and endpoint quirks, and it breaks every time one of them shifts. tapedeck's whole advantage is that it normalizes at the SDK's abstraction, which is precisely what makes it provider-agnostic within the SDK and stream-native by construction — see middleware, not a proxy. You can't get that benefit and also be SDK-agnostic; the benefit is the coupling.

  2. A neutral cassette schema would lag both the SDK and reality. To record against the SDK and some other framework, the cassette would need a third, "neutral" shape that maps onto both. That shape would trail whichever upstream moved last, and every consumer would have to learn it. The SDK's own content[] / stream-part shape is already the lingua franca for AI SDK users; recording it directly means the cassette reads like the SDK and survives provider wire-format changes for free.

What the coupling buys, and how we manage its risk

Tight coupling is a real risk, so we make the boundary explicit rather than hide it behind an abstraction:

  1. COMPATIBILITY.md — a public, dated record of every ai version tapedeck is tested against, what "pass" means (typecheck green, suite green, and a record→replay round-trip that stays byte-identical while a changed prompt misses), and the markers for ⚠️ partial and ❌ fail.

  2. A peer range that only widens on evidence. peerDependencies: { "ai": ">=6.0.0 <8" }. A new SDK major joins it after the weekly compat cron proves it green, which is how ai@7 got in. What forces a tapedeck major is a spec shape change deep enough to break the fields tapedeck reads, not an SDK major that renumbers the spec: the middleware is typed structurally over those fields, so it satisfies spec v3 (ai@6) and spec v4 (ai@7) from one object, and a spec v5 would surface as a red type test rather than a silent consumer-side cast.

  3. The cassette version field plus recorded provider/model. Every cassette carries "version": "tapedeck@0.1.0" and the recorded modelProvider / modelId. If a future tapedeck or SDK changes the format, the version string makes the boundary visible at replay time instead of producing a confusing miss.

{
  "version": "tapedeck@0.1.0",
  "hash": "sha256:abc123…",
  "request": { "modelProvider": "openai", "modelId": "gpt-4o", "prompt": [ … ] }
}
If you're running ahead of the matrix
tapedeck is tested against the SDK versions listed in COMPATIBILITY.md. If your project is on an ai release newer than the latest row there, you're ahead of the tested matrix — a spec-shape change could surface as a CassetteCorruptError or an unexpected replay miss. Check the table before bumping.

What v2 might reconsider

The deferred list kept the first cut tight on purpose, and what has landed since stayed inside the boundary: OTel span emission, the tapedeck CLI, cassette diff/merge tooling, and the edge-safe core in 0.2.0, multi-interaction named cassettes in 0.3.0, and drift detection in 0.4.0. None of them weaken the coupling: they extend what tapedeck does within the SDK abstraction. A genuinely SDK-agnostic recorder is not on the roadmap; it would be a different, weaker product.

Consequences

  • Sharp at one thing. tapedeck is the record/replay tool for AI SDK users, and every distribution surface — the README, the cassette shape, the peer range — reinforces that.
  • The ceiling is visible. COMPATIBILITY.md, the peer range, and the cassette version field make SDK drift a documented, dated, loud event rather than a mystery.
  • The cost is reach. If you're not on the Vercel AI SDK, tapedeck is not for you — by design.

Related