Your Model Upgrade Is a Breaking Change: Build Contract Tests for LLM Providers in TypeScript A developer published a TypeScript guide for building contract tests that catch breaking changes when upgrading large language model providers, using mocked Anthropic Sonnet 5 and Sonnet 5.5 providers so no API key is required. The tests encode documented provider changes — such as Sonnet 5.5 rejecting `thinking: {"type": "disabled"}` and `tool_choice` types `any` and `tool` with 400 errors, and moving inter-tool text into `thinking` blocks — and diff two model versions to surface silent response-shape changes. The author argues that changing a model string is a dependency upgrade and deserves its own test suite. Most code that calls a model has one line that looks harmless. model: "claude-sonnet-5" Changing it feels like a config change. But that string is part of an API contract. And this month, the contracts changed. function call steps, "the built-in tools changed": PascalCase parameters, and write file path, content became write to file or replace file content . The old antigravity-preview-05-2026 "shuts down on October 5, 2026." thinking: {"type": "disabled"} and {"type": "enabled", ...} "return a 400 error." So do tool choice types any and tool . none and minimal reasoning efforts are not supported." Here are Sonnet 5.5's five, in the release notes' words: thinking: {"type": "between tools"} instead of "disabled" , at high effort or below." computer 20251124 computer use tool isn't accepted." The What's new page https://platform.claude.com/docs/en/models/sonnet-5-5/whats-new-sonnet-5-5 adds one that "alters the response shape without failing any request": text between tool calls comes back in thinking blocks. A 400 is loud. An empty progress message is quiet. Different companies. Same pattern. Changing a model string is a dependency upgrade. It deserves a test suite. So let's build one. No API key. Both providers are mocks: their request rules follow the docs above, and their replies are made up. One check reads the release notes. The other diffs two model versions. You will need Node.js 18 or newer. mkdir model-upgrade-gate cd model-upgrade-gate npm init -y npm install --save-dev typescript tsx @types/node Save the following blocks, in order, as upgrade-gate.ts . type Req = { prompt: string; maxTokens: number; thinking?: { type: "adaptive" | "disabled" | "between tools" }; toolChoice?: { type: "auto" | "none" | "any" | "tool" }; tools?: string ; }; type Block = | { type: "text"; text: string } | { type: "thinking"; thinking: string } | { type: "tool use"; name: string; input: Record