Skip to content

chore: upgrade AI SDK v6 → v7 (api)#716

Open
sweetmantech wants to merge 3 commits into
testfrom
chore/ai-sdk-v7-upgrade
Open

chore: upgrade AI SDK v6 → v7 (api)#716
sweetmantech wants to merge 3 commits into
testfrom
chore/ai-sdk-v7-upgrade

Conversation

@sweetmantech

@sweetmantech sweetmantech commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

The hard one in the monorepo-wide AI SDK v6→v7 migration (chat#1816). Targets test. Key outcome: v7's agent abstraction survived intact (ToolLoopAgent, the agent loop, context passthrough all still exist) — this was a rename + typed-context migration, not the ground-up redesign we feared.

Versions

  • ai 6.0.1907.0.2
  • @ai-sdk/{anthropic,google,openai} 3→4, @ai-sdk/gateway 3→4, @ai-sdk/mcp 1→2 (Zod already v4)

The real v7 change: typed tool context

v7 infers a tool's context type as never unless declared, which broke both the tool() overloads (TS2769) and the toolsContext option. Fix: annotate every context-using tool's execute second arg as ToolExecutionOptions<AgentContext> (bash/glob/grep/task/webFetch/read/write/edit/skill). v7 also split the single experimental_context into a per-tool-name toolsContext map — added lib/agent/tools/buildToolsContext.ts to fan the one AgentContext out to every tool key; wired into runAgentStep + taskTool.

Notably this was not a Zod-duplication issue — a pnpm zod override added during diagnosis was removed once the context typing was correct.

Other manual work

  • Usage token shape — v7 nests details under inputTokenDetails/outputTokenDetails, drops top-level reasoningTokens/cachedInputTokens (addLanguageModelUsage — codemod had doubled a path, ZERO_USAGE, recordCreditDeduction).
  • Provider optionsGoogleProviderOptionsGoogleGenerativeAIProviderOptions.
  • ToolLoopAgent gained a 4th (runtime-context) generic → updated RoutingDecision/ChatConfig agent types.
  • Reverted codemod over-applications — local generateText/generateArray { system } wrappers (pass instructions: system inward), toolChain systeminstructions on custom ToolChainItem/PrepareStepResult types, webFetch discriminant as const + param-default move.
  • Codemod handled the mechanical renames (isToolOrDynamicToolUIPartisToolUIPart, stepCountIsisStepCount, systeminstructions, experimental_contextcontext, experimental_generateImagegenerateImage).
  • Test fixtures aligned to v7 (mock exports + usage/UIMessage shapes); no weakened assertions.

Verification (local)

Check Result
tsc --noEmit (source) 0 errors
pnpm test 3676 passed / 659 files

(~199 pre-existing __tests__ type-debt errors in unrelated domains — Slack/Privy/Resend — left untouched; all tests pass at runtime. next build needs env → validated on the Vercel preview.)

Tracking: chat#1816. Merge target test; sync testmain per repo flow on release. Sibling: chat#1817.

🤖 Generated with Claude Code


Summary by cubic

Upgrade API to AI SDK v7, replacing experimental_context with typed per-tool toolsContext and adopting v7 APIs. Preserves the agent loop; adds a build fix by externalizing @vercel/oidc.

  • Dependencies

    • ai 6.0.1907.0.2
    • @ai-sdk/{anthropic,google,openai} ^3^4, @ai-sdk/gateway ^3^4, @ai-sdk/mcp ^1^2
    • Added @vercel/oidc as a direct dependency
  • Migration

    • Typed tool context: annotate execute with ToolExecutionOptions<AgentContext>; added buildToolsContext() and wired into runAgentStep and taskTool.
    • Renames: systeminstructions, experimental_contextcontext, stepCountIsisStepCount, fullStreamstream.
    • Usage shape: use inputTokenDetails/outputTokenDetails; update zero-usage and credit deduction to read inputTokenDetails.cacheReadTokens.
    • ToolLoopAgent generic arity updated; RoutingDecision/ChatConfig now use Record<string, unknown> for the runtime-context slot.
    • Build: switch to next build --webpack and externalize @vercel/oidc via serverExternalPackages to avoid dynamic require issues from @ai-sdk/gateway@4.
    • Tests updated (onStepFinishonStepEnd, onFinishonEnd); minor tool fixes (keep webFetch defaults in-body for tool() inference).

Written for commit dfc4803. Summary will update on new commits.

Review in cubic

Bump to v7: ai 6.0.190 → 7.0.2; @ai-sdk/{anthropic,google,openai} 3 → 4;
@ai-sdk/gateway 3 → 4; @ai-sdk/mcp 1 → 2. (Zod already v4.)

The agent harness survived v7 intact — ToolLoopAgent, the agent loop, and
context passthrough all still exist. This was a rename + typed-context
migration, not a redesign.

Codemod handled the mechanical renames (isToolOrDynamicToolUIPart →
isToolUIPart, experimental_generateImage → generateImage, stepCountIs →
isStepCount, system → instructions, experimental_context → context, etc.).

Manual work, by category:
- Typed tool context (the real v7 change): v7 infers a tool's context as
  `never` unless declared, which broke both `tool()` overloads (TS2769) and
  `toolsContext`. Annotated every context-using tool's execute 2nd arg as
  `ToolExecutionOptions<AgentContext>` (bash/glob/grep/task/webFetch/read/
  write/edit/skill). v7 also split the old single `experimental_context` into
  a per-tool-name `toolsContext` map — added `buildToolsContext()` to fan the
  one AgentContext out to every tool key; wired it into runAgentStep + taskTool.
- Usage token shape: v7 nests details under inputTokenDetails/outputTokenDetails
  and drops top-level reasoningTokens/cachedInputTokens. Fixed
  addLanguageModelUsage (codemod had doubled a path), ZERO_USAGE,
  recordCreditDeduction.
- Provider options: GoogleProviderOptions → GoogleGenerativeAIProviderOptions.
- ToolLoopAgent gained a 4th (runtime-context) generic — updated RoutingDecision
  / ChatConfig agent types to v7 arity.
- Reverted codemod over-applications: local generateText/generateArray `{system}`
  wrappers (pass `instructions: system` inward), toolChain `system`→`instructions`
  on the custom ToolChainItem/PrepareStepResult types, webFetch discriminant
  `as const` + param-default move (v7 tool() inference).
- Test fixtures aligned to v7 (mock exports + usage/UIMessage shapes); no
  weakened assertions.

Verified: source `tsc --noEmit` clean (0 errors), full `pnpm test` green
(3676 passed / 659 files). Pre-existing test-file type-debt in unrelated
domains left untouched. Full build validated on Vercel preview.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
api Ready Ready Preview Jun 26, 2026 1:09am

Request Review

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@sweetmantech, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 55 minutes and 49 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: d6afbe1a-b750-4ce0-ae33-f1eff01174db

📥 Commits

Reviewing files that changed from the base of the PR and between cae9f35 and dfc4803.

⛔ Files ignored due to path filters (22)
  • app/lib/workflows/__tests__/runAgentStep.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by app/**
  • app/lib/workflows/__tests__/runAgentWorkflow.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by app/**
  • lib/agent/tools/__tests__/bashTool.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/agent/tools/__tests__/editFileTool.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/agent/tools/__tests__/globTool.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/agent/tools/__tests__/grepTool.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/agent/tools/__tests__/readFileTool.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/agent/tools/__tests__/skillTool.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/agent/tools/__tests__/taskTool.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/agent/tools/__tests__/webFetchTool.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/agent/tools/__tests__/writeFileTool.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/agents/CompactAgent/__tests__/createCompactAgent.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/chat/__tests__/integration/chatEndToEnd.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/chat/__tests__/types.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/chat/toolChains/__tests__/getPrepareStepResult.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/chat/toolChains/__tests__/toolChains.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/credits/__tests__/handleChatCredits.test.ts is excluded by !**/*.test.*, !**/__tests__/** and included by lib/**
  • lib/evals/scorers/CatalogAvailability.ts is excluded by !**/evals/** and included by lib/**
  • lib/evals/scorers/QuestionAnswered.ts is excluded by !**/evals/** and included by lib/**
  • next.config.ts is excluded by none and included by none
  • package.json is excluded by none and included by none
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml and included by none
📒 Files selected for processing (25)
  • app/lib/workflows/runAgentStep.ts
  • app/lib/workflows/runAgentWorkflow.ts
  • lib/agent/messageMetadata/addLanguageModelUsage.ts
  • lib/agent/tools/bashTool.ts
  • lib/agent/tools/buildToolsContext.ts
  • lib/agent/tools/editFileTool.ts
  • lib/agent/tools/globTool.ts
  • lib/agent/tools/grepTool.ts
  • lib/agent/tools/readFileTool.ts
  • lib/agent/tools/skillTool.ts
  • lib/agent/tools/taskTool.ts
  • lib/agent/tools/webFetchTool.ts
  • lib/agent/tools/writeFileTool.ts
  • lib/agents/CompactAgent/createCompactAgent.ts
  • lib/agents/EmailReplyAgent/createEmailReplyAgent.ts
  • lib/agents/content/createContentPromptAgent.ts
  • lib/ai/generateArray.ts
  • lib/ai/generateText.ts
  • lib/chat/const.ts
  • lib/chat/toolChains/createNewArtistToolChain.ts
  • lib/chat/toolChains/create_release_report/createReleaseReportToolChain.ts
  • lib/chat/toolChains/getPrepareStepResult.ts
  • lib/chat/toolChains/toolChains.ts
  • lib/chat/types.ts
  • lib/credits/handleChatCredits.ts
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/ai-sdk-v7-upgrade

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 46 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.
Architecture diagram
sequenceDiagram
    participant Client as Client / Request
    participant Workflow as runAgentWorkflow
    participant Step as runAgentStep
    participant SDK as AI SDK v7 (streamText)
    participant Tools as Agent Tools (bash/glob/grep/read/write/edit/skill/task/webFetch)
    participant TaskTool as taskTool (subagent)
    participant SubSDK as AI SDK v7 (subagent streamText)
    participant SubTools as Subagent Tools

    Note over Client,SubTools: Agent Step Execution (v7 migration)

    Client->>Workflow: runAgentWorkflow(messages, chatId)
    Workflow->>Workflow: Build DurableAgentContext

    alt New Step
        Workflow->>Step: runAgentStep(context, tools, messages)
        Step->>Step: buildToolsContext(tools, agentContext)
        Note over Step: Fans single AgentContext to per-tool map

        Step->>SDK: streamText({ model, instructions, messages, tools, toolsContext, stopWhen: isStepCount(111) })
        Note over Step,SDK: instructions replaces system,<br/>toolsContext replaces experimental_context

        SDK->>Tools: execute() with ToolExecutionOptions<AgentContext>
        alt Bash/Glob/Grep Tool
            Tools->>Tools: Destructure { context } from ToolExecutionOptions
            Tools->>Tools: Read sandbox, workingDirectory from context
            Tools-->>SDK: Result
        else Read/Write/Edit/Skill Tool
            Tools->>Tools: Destructure { context } from ToolExecutionOptions
            Tools-->>SDK: Result
        else webFetch Tool
            Tools->>Tools: method = methodInput ?? "GET" (default in body)
            Tools-->>SDK: Result with as const discriminant
        else taskTool
            Step->>TaskTool: execute(task, instructions, { context, abortSignal }: ToolExecutionOptions<AgentContext>)
            TaskTool->>TaskTool: getSubagentModel(context)
            TaskTool->>SubTools: buildSubagentTools()
            TaskTool->>TaskTool: buildToolsContext(subagentTools, context)
            Note over TaskTool: Build subagent tool context map
            TaskTool->>SubSDK: streamText({ model, instructions, prompt, tools, toolsContext, stopWhen: isStepCount(2) })
            Note over TaskTool,SubSDK: Subagent uses its own streamText call
            SubSDK-->>TaskTool: stream (yield tool-call/finish parts)
            loop For each part in result.stream
                TaskTool->>TaskTool: Aggregate tool calls and usage
                TaskTool-->>Step: Yield TaskToolOutput chunks
            end
            TaskTool-->>Tools: Final result
        end

        Step->>Step: onStepEnd / onEnd callbacks capture responseMessage
        Note over Step: onStepEnd replaces onStepFinish,<br/>onEnd replaces onFinish

        SDK-->>Step: stream result
        Step-->>Workflow: StepResult with responseMessage, usage
    end

    Workflow->>Workflow: addLanguageModelUsage(accumulated, step.usage)
    Note over Workflow: Usage shape: inputTokenDetails.cacheReadTokens,<br/>no top-level reasoningTokens/cachedInputTokens

    Workflow->>Workflow: recordCreditDeduction with usage
    Note over Workflow: Reads usage.inputTokenDetails.cacheReadTokens

    Workflow-->>Client: Response
Loading

Note: This PR contains a large number of files. cubic only reviews up to 40 files per PR, so some files may not have been reviewed. cubic prioritizes the most important files to review.
On a pro plan you can use ultrareview for larger PRs.
Requires human review: Major AI SDK v6→v7 upgrade across 46 files with API renames and structural changes; high risk for production regressions.

Re-trigger cubic

CI on the v7 bump surfaced three failures (code was correct; tooling wasn't):

- lint: `@typescript-eslint/no-explicit-any` on the `ToolLoopAgent` 4th
  (runtime-context) generic in RoutingDecision/ChatConfig → use
  `Record<string, unknown>` (which is v7's `Context` constraint, and the
  source agent's inferred `any` slot is assignable to it).
- format: prettier on two v7-updated test fixtures.
- Vercel build: `Error: dynamic usage of require is not supported` while
  collecting page data for the Workflow step route — `@vercel/oidc` (pulled
  in by `@ai-sdk/gateway@4`) does a dynamic require Turbopack can't bundle.
  Switch the build to `next build --webpack` (which tolerates it), matching
  what chat and marketing already use. Verified locally: webpack compiles the
  Workflow routes; the require error is gone (remaining local failures are
  env-only, present on Vercel).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0 issues found across 4 files (changes from recent commits).

Requires human review: Major AI SDK v6→v7 upgrade with changes to tool context, usage token shape, and callback renames across agent tools and workflow logic. High impact requires human review.

Re-trigger cubic

Webpack got past Turbopack's "dynamic require" refusal, but then the Workflow
step route failed at runtime: bundling `@vercel/oidc/index.js` made its
internal `require('./get-vercel-oidc-token.js')` resolve to a relative path
that doesn't exist on Vercel ("Cannot find module …/get-vercel-oidc-token.js").

Fix: add `@vercel/oidc` to `serverExternalPackages` (+ as a direct dependency
so it's resolvable). Node then loads the package — and its internal require —
natively instead of bundling it. Pairs with the `next build --webpack` switch;
Turbopack refuses to externalize it ("can't be external").

Verified locally (webpack): the Workflow routes compile and collect page data
with no @vercel/oidc error; only env-dependent routes fail locally (env present
on Vercel).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0 issues found across 3 files (changes from recent commits).

Requires human review: Core AI SDK v6→v7 upgrade with changes to tool context, streaming callbacks, and usage tracking; requires human review due to high risk of runtime breakage.

Re-trigger cubic

@sweetmantech

Copy link
Copy Markdown
Contributor Author

✅ All checks green under AI SDK v7

Check Result
tsc --noEmit (source) ✅ 0 errors
test (CI) ✅ 3676 passed
lint (CI)
format (CI)
Vercel build Deployment completed
CodeRabbit / cubic ✅ / ✅

The build fix (worth recording for open-agents, which shares the stack)

The v7 @ai-sdk/gateway@4 bump pulls in @vercel/oidc, which does a runtime require('./get-vercel-oidc-token.js'). Two-layer failure during build page-data collection:

  1. Turbopack refuses to bundle the dynamic require at all (dynamic usage of require is not supported) → switched to next build --webpack (what chat/marketing already use).
  2. Webpack bundled @vercel/oidc, breaking its internal relative require at runtime (Cannot find module …/get-vercel-oidc-token.js) → added it to serverExternalPackages (+ as a direct dep so it's resolvable) so Node loads it natively.

The migration itself was a rename + typed-tool-context pass (not the feared redesign) — see the PR description. ToolLoopAgent and the agent loop survived v7; the work was declaring each tool's ToolExecutionOptions<AgentContext> and fanning context into v7's per-tool toolsContext map via buildToolsContext.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant