Repository navigation
deps(ai): migrate the Vercel AI SDK from 6 to 7 - #185
Merged
Merged
Conversation
ai 6.0.297 -> 7.0.123
@ai-sdk/provider 3.0.18 -> 4.0.20
@ai-sdk/openai 3.0.121 -> 4.0.81
@ai-sdk/anthropic 3.0.125 -> 4.0.69
@ai-sdk/google 3.0.129 -> 4.0.86
@ai-sdk/openai-compatible 2.0.80 -> 3.0.60
Ran the official v7 codemod (npx @ai-sdk/codemod@4.0.3 v7), then fixed the one
change the codemod and the type checker cannot see.
The codemod only touched one line: `createGoogleGenerativeAI` -> `createGoogle`
in the Google adapter. KnowNote does not use the other renamed surfaces
(fullStream, onFinish, telemetry, tools, custom providers).
The real risk is that AI SDK 7 rejects `{ role: 'system' }` messages inside
`messages` by default, and it does not throw: the answer comes back empty.
KnowNote puts the retrieved context (RAG) and the title-generation prompt into
the history as a system message, in both chat handlers and noteHandlers. Left
alone, every RAG turn would silently produce a blank answer.
`ModelClient.streamChat` now passes `allowSystemInMessages: true`. Every message
it sends is built by this app, not by the user, so the untrusted-injection case
that default guards against does not apply. A regression test asserts the
system message actually reaches the provider's prompt.
Also verified rather than assumed:
- The ESM-only packaging is fine here: `ai` and the providers are
devDependencies that rollup bundles into `out/main`, and the packaged smoke
starts and self-checks.
- `streamObject` still exists in v7 (deprecated, not removed), so the quiz /
Anki / mind-map services keep working.
- `LanguageModelUsage` still exposes the numeric `inputTokens` / `outputTokens`
/ `totalTokens` this app reads.
Verified on Linux x64 (WSL2):
- `npm run typecheck` - clean
- `npm test` - 471/471 pass
- `npm run build:unpack && npm run smoke:packaged` - 29 checks pass
Note on running the codemod: `@ai-sdk/codemod v7` ignores its positional path
argument and scans the repository root. Its ignore list covers
node_modules/dist/build but not `out/`, so it parses the 6 MB bundled renderer
output once per codemod and appears to hang. Removing `out/` and `dist/` first
takes it from "stuck" to one minute.
`result.toUIMessageStream(...)` is deprecated in v7: it still works but logs a
deprecation warning on every turn, and it is scheduled for removal in the next
major. The stateless top-level helper takes the same options plus the stream:
result.toUIMessageStream({ ... }) -> toUIMessageStream({ stream: result.stream, ... })
Same options, same `messageMetadata` usage-on-finish wiring, so the forwarded
event stream is unchanged - which is what the chat-stream and UI-message tests
assert.
Verified: typecheck clean, 471/471 tests pass, packaged smoke 29/29.
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.
What
Upgrade the AI SDK from 6 to 7, on top of the already-merged 5 → 6 PR (#184).
ai@ai-sdk/provider@ai-sdk/openai@ai-sdk/anthropic@ai-sdk/google@ai-sdk/openai-compatibleThe codemod, and why it looked "stuck"
npx @ai-sdk/codemod v7ignores its positional path argument and scans the repository root. Its ignore list coversnode_modules,distandbuild, but notout/— the bundled renderer output (6 MB ofindex-*.jsplus the 1.3 MB pdf worker). jscodeshift parsed that once per codemod, ~20 times, which reads as a hang.Removing
out/anddist/first takes the whole run from "stuck" to one minute. Worth knowing for the next major.After that, the codemod touched exactly one line:
createGoogleGenerativeAI→createGoogle. KnowNote does not use the other renamed surfaces (fullStream,onFinish, telemetry, tools, custom providers).AI SDK 7 rejects
{ role: 'system' }messages insidemessagesby default — and it does not throw. Verified directly:KnowNote puts the retrieved context (RAG) and the title-generation prompt into the history as a system message (
chatHandlers.ts×2,noteHandlers.ts). Left alone, every RAG turn would silently produce a blank answer — worse than a crash, because nothing surfaces.ModelClient.streamChatnow passesallowSystemInMessages: true. Every message it sends is built by this app, not by the user, so the untrusted-injection case that the default guards against does not apply. A regression test asserts the system message actually reaches the provider'sprompt.Also done: stateless
toUIMessageStreamresult.toUIMessageStream(...)is deprecated in v7 — it works but warns every turn and is slated for removal in v8. Moved to the stateless helper, same options:The
messageMetadatausage-on-finish wiring is unchanged, so the forwarded event stream is identical — which is exactly what the chat-stream and UI-message tests cover.Verified (Linux x64, WSL2)
npm run typechecknpm testnpm run build:unpack && npm run smoke:packagedThe packaged smoke matters here because v7 is ESM-only:
aiand the providers aredevDependenciesthat rollup bundles intoout/main. The build succeeds and the real packaged app starts and self-checks.Also checked rather than assumed:
streamObjectstill exists in v7 (deprecated, not removed), so quiz / Anki / mind-map keep working.LanguageModelUsagestill exposes the numericinputTokens/outputTokens/totalTokensthis app reads.readUIMessageStreamandMockLanguageModelV3are still present.Known remaining deprecations (not fixed here)
streamObjectis deprecated in favour ofstreamText+Output.object. RewritingQuizService,AnkiCardServiceandMindMapServiceis a behaviour-sensitive change (partial-object streams, progress reporting) and belongs in its own PR, not a version bump.'openai-compatible'providerOptions key is still read but should become'openaiCompatible'. It only logs a warning; renaming changes which key the provider reportsproviderMetadataunder, so I left it for a focused follow-up.Rollback
Revert the branch. No schema, storage format, or persisted data changes.