fix(docs): move the AI providers onto the provider spec ai@7 expects - #438
Merged
Conversation
#425 took `ai` from ^6.0.214 to ^7.0.66 and left the DeepSeek provider behind. `ai@7` resolves `@ai-sdk/provider@4`; `@ai-sdk/deepseek@2.0.38` and `@ai-sdk/mcp@1.0.52` implement `@ai-sdk/provider@3`. Two majors of the provider spec in one tree, with the assistant talking across the gap. Bumped to ^3.0.28 and 2.0.32, in `docs/` and in both Nuxt playgrounds — they declare `@ai-sdk/deepseek` too, and fixing only `docs/` would have left the same mismatch in place. The lockfile now resolves a single `@ai-sdk/provider@4.0.7`, down from two. `@ai-sdk/mcp` is pinned exactly rather than with a caret, and that is the second finding. Reaching for the newest, `2.0.33`, published the previous day, made pnpm **silently append it to `minimumReleaseAgeExclude`** in `pnpm-workspace.yaml` instead of refusing — a supply-chain policy waived by a line that reads as ordinary config. `2.0.32` carries the same `@ai-sdk/provider@4.0.7`, so the newer release bought nothing; the exclusion list is back to the single entry it had before. Nothing in the gate could have caught the version mismatch, which is the part worth recording. The provider packages peer-depend on `zod`, not on `ai`, so pnpm stays quiet. `typecheck` passes because the provider is still a valid module. `docs:generate` runs with NUXT_PUBLIC_USE_AI=false and no DEEPSEEK_API_KEY, so the request path is never exercised. The break would have first appeared to a user. `dep-parity.json` could not have caught it either, by construction: it records only packages both trees declare, and `@ai-sdk/deepseek` and `@ai-sdk/mcp` are fork-only — this fork's assistant runs on DeepSeek, so upstream's `chore(deps)` batches never mention them. §2 now carries that as an invariant, with the check to run when `ai` moves a major, and the `minimumReleaseAgeExclude` trap alongside it. Also corrects the record. #425 described the version gap as accidental drift. It was not: six ledger entries show the v6 line was a deliberate deferral — `c8e810ca` reads "ai (v6 line, deferred v7), @ai-sdk/vue (v3)" and `229b64f6` reads "ai+@ai-sdk/* (v6 line + DeepSeek)" — deferred for exactly the coupling that then broke. The bump was still the right call and was made on instruction, but it ended a considered decision rather than correcting an oversight. Found while checking why upstream's `CLAUDE.md` commit did not apply here, which surfaced the `.gitignore` entry added in `b55bd3e7` and, in that commit's body, the deferral note. Verify (CI=true): pnpm install --frozen-lockfile · dev:prepare across all four apps · lint · typecheck · test (6708 passed, 6 skipped, 294 files) · build · docs:generate (1240 routes) — all green. The load-bearing check is not the suite but the resolution: one `@ai-sdk/provider` version across the whole lockfile.
IgorShevchik
force-pushed
the
fix/ai-sdk-provider-spec
branch
from
August 19, 2026 13:33
4e1ee4d to
bf7d2fc
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes a break I introduced in #425, which is currently on
main.What broke
#425 aligned dependencies to upstream and took
aifrom^6.0.214to^7.0.66. It did not touch@ai-sdk/deepseekor@ai-sdk/mcp, because upstream does not declare them — this fork's docs assistant runs on DeepSeek.The coupling is the provider spec:
ai@7.0.66@ai-sdk/provider@**4**.0.7@ai-sdk/deepseek@2.0.38@ai-sdk/provider@**3**.0.10@ai-sdk/mcp@1.0.52@ai-sdk/provider@**3**.0.10Two majors of the provider spec in one tree, with the assistant talking across the gap.
The fix
@ai-sdk/deepseek→^3.0.28,@ai-sdk/mcp→2.0.32, indocs/and in both Nuxt playgrounds — they declare@ai-sdk/deepseektoo, and fixing onlydocs/would have left the same mismatch behind.PORTING.md§2's mirror rule, again.The lockfile now resolves one
@ai-sdk/provider@4.0.7, down from two majors. That resolution — not a passing suite — is the load-bearing check here:Second finding: a supply-chain policy nearly waived silently
@ai-sdk/mcpis pinned exactly, and that is deliberate.Reaching for the newest,
2.0.33, published the previous day, made pnpm silently append it tominimumReleaseAgeExcludeinpnpm-workspace.yamlrather than refusing. This repo enforces a 24-hour minimum release age; the exclusion waives it for that package, and in a diff it reads as one unremarkable config line.2.0.32(published 2026-08-14) carries the same@ai-sdk/provider@4.0.7, so the newer release bought nothing. The exclusion line is gone andpnpm-workspace.yamlhas no net change againstmain.Mechanical note for whoever hits this next: reverting the manifest is not enough, because pnpm validates the existing lockfile before doing anything and aborts. Its suggested
pnpm clean --lockfilerebuilds the whole file and produces a large unrelated diff; takingpnpm-lock.yamlfrommainand reinstalling re-resolves just the affected packages.Why nothing caught it
Worth stating, because every gate was green while
mainwas broken:zod, not onai— so pnpm has nothing to warn about;typecheckpasses, because the provider is still a valid module with the right shape;docs:generateruns withNUXT_PUBLIC_USE_AI=falseand noDEEPSEEK_API_KEY, so the request path is never exercised.The break would have first appeared to a user.
dep-parity.json(added in #429) could not have caught it either, by construction: it records only packages both trees declare, so a fork-only dependency is outside it. §2 now carries that as an invariant, with the one-line check to run wheneveraimoves a major, and theminimumReleaseAgeExcludetrap alongside it.Correcting the record
#425 described the version gap as accidental drift. It was not.
Six ledger entries show the v6 line was a deliberate deferral —
c8e810careads "ai (v6 line, deferred v7), @ai-sdk/vue (v3)",229b64f6reads "ai+@ai-sdk/ (v6 line + DeepSeek)"* — and it was deferred for exactly the coupling that then broke. The bump was still the right call and was made on instruction, but it ended a considered decision rather than correcting an oversight, and the record should say so.Found while checking why upstream's
CLAUDE.mdcommit did not apply here — which surfaced the.gitignoreentry added inb55bd3e7, and in that commit's body, the deferral note.Verify (
CI=true)pnpm install --frozen-lockfile·dev:prepare(all four apps) ·lint·typecheck·test·build·docs:generate— all green. Tests 6708 passed | 6 skipped across 294 files. 1240 routes prerendered.Still not verified
The assistant's runtime path remains unexercised here — no
DEEPSEEK_API_KEY, and the build disables it. This PR aligns the provider spec, which is necessary; confirming a real completion still wants one manual request against a live key.Generated by Claude Code