Skip to content

feat: update AI SDK to v7#1922

Open
cjol wants to merge 13 commits into
mainfrom
fix/jul9-ai-sdk-v7
Open

feat: update AI SDK to v7#1922
cjol wants to merge 13 commits into
mainfrom
fix/jul9-ai-sdk-v7

Conversation

@cjol

@cjol cjol commented Jul 10, 2026

Copy link
Copy Markdown
Contributor

This PR updates the repository to AI SDK v7 while preserving AI SDK v6 compatibility for the published packages. It also moves Workers AI integrations to the published workers-ai-provider@4 release.

Why

  • Consumers need the Agents SDK packages to work with AI SDK v7 and the matching @ai-sdk/* package majors without forcing existing AI SDK v6 consumers to migrate immediately.
  • A dependency-only update was insufficient because v7 changed prompt, stop-condition, lifecycle callback, telemetry, tool execution, and provider APIs used throughout the repository.
  • We could expose the v7 renames directly through Think, but that would add a second caller-facing migration. Think keeps its existing API names where practical and translates at the AI SDK boundary instead.
  • Repository applications use v7 by default. A dedicated compatibility matrix repins the shared dependencies and Workers AI provider for v6 consumer validation.

Public API Surface

Symbol Kind Notes
Published package peer dependencies Additive agents, @cloudflare/ai-chat, @cloudflare/codemode, and @cloudflare/think accept their corresponding AI SDK v6 and v7 majors.
@cloudflare/think TurnConfig.telemetry Additive Accepts the v7 option name and takes precedence over experimental_telemetry.
@cloudflare/think TurnConfig.experimental_telemetry Changed Remains accepted, with a type compatible across the supported SDK majors.
@cloudflare/think StepContext Changed Remains exported under the same name and supports the callback shapes from both SDK majors.
@cloudflare/ai-chat AIChatAgent.onChatMessage Changed The onFinish callback uses the generate-text completion callback contract.
  • Think continues to expose system, onStepFinish, and experimental_telemetry where callers already use them.
  • Think maps v7 onToolExecutionEnd events into the existing ToolCallResultContext shape. stepNumber is unavailable for v7 tool completion events.

Code Changes

  • Package and application dependency ranges move to the v7-compatible ai, @ai-sdk/*, and workers-ai-provider@4 releases.
  • The compatibility workflow installs both supported AI SDK majors. Its v6 leg repins workers-ai-provider@3, builds the v7 distribution first, then validates Think as a v6 consumer.
  • AI SDK call sites use v7 prompt, stop-condition, lifecycle, telemetry, and tool execution names while Think translates its stable caller-facing configuration at the SDK boundary.
  • Tool schema adapters normalize function-valued descriptions for integrations that still require strings.
  • agent-think uses functionId because AI SDK v7 removed telemetry metadata.
  • forever-chat preserves the provider specification version when wrapping v3 and v4 language models for buffered replay.

Compatibility

  • Published packages support both AI SDK v6 and v7 through peer ranges and conditional type adapters.
  • Repository examples and default installs use AI SDK v7 with workers-ai-provider@4.
  • Think's bundled default Workers AI provider targets v4. AI SDK v6 consumers that encounter a provider mismatch can pass their own LanguageModel.
  • AI SDK v7 callers cannot pass TelemetryOptions.metadata; use supported telemetry fields or an integration instead.
  • AI SDK v7 no longer provides stepNumber to Think tool completion callbacks.
  • chat@4.31.0 still advertises an ai@^6 peer and does not yet declare v7 support.

This PR updates the repo from AI SDK v6 to v7 across the published packages, examples, guides, experiments, and starters. It migrates the current implementations only: new optimisations or improvements made available by the v7 SDK are intentionally out of scope for this change.

## Why

- Consumers need the Agents SDK packages to work with AI SDK v7 and the matching @ai-sdk/* package majors.
- A version-only bump was not enough because v7 renamed prompt, stop-condition, lifecycle callback, telemetry, and tool execution APIs used throughout the repo.
- We could have renamed the Think-facing API to match v7 directly, but that would add a second API migration on top of the dependency migration. This keeps Think's existing caller-facing names where practical and translates at the AI SDK boundary.
- We could have adopted v7-only follow-up improvements like stateless UI message stream helpers, final-step result audits, or media part cleanup here, but those are behaviour and design choices rather than required compatibility fixes.

## Public API Surface

| Symbol | Kind | Notes |
| ------ | ---- | ----- |
| package peer dependencies | Breaking | Published packages now require ai@7 and @ai-sdk/react@4 where applicable. |
| @cloudflare/think TurnConfig.experimental_telemetry | Changed | Still accepted, but now typed against the v7 telemetry option. v6 metadata is no longer supported by AI SDK v7. |
| @cloudflare/think TurnConfig.telemetry | Additive | Accepted as the v7 option name and forwarded ahead of experimental_telemetry when present. |
| @cloudflare/think StepContext | Changed | Still exported under the same name, now derived from GenerateTextOnStepFinishCallback. |
| @cloudflare/ai-chat AIChatAgent.onChatMessage | Changed | The onFinish callback type now uses GenerateTextOnFinishCallback. |

- Think still exposes system, onStepFinish, and experimental_telemetry as current top-level API names where callers already use them.
- Think adapts v7 onToolExecutionEnd events back into the existing ToolCallResultContext shape for afterToolCall hooks and extensions.
- ToolCallResultContext.stepNumber is now undefined for tool completion callbacks because AI SDK v7 no longer provides that value on the tool execution end event.

## Code Changes

- Dependency ranges move from ai@6 and @ai-sdk/*@3 to ai@7 and @ai-sdk/*@4 across packages, examples, experiments, starters, and the lockfile.
- AI SDK call sites use v7 names: instructions instead of system, isStepCount instead of stepCountIs, telemetry instead of experimental_telemetry at the SDK boundary, and onStepEnd or onToolExecutionEnd instead of the old lifecycle callback names.
- Think keeps its public turn configuration and hook names stable while translating them into v7 streamText options internally.
- Tool schema adapters in agents, codemode, and browser tooling normalize function-valued tool descriptions because downstream connectors still expect string descriptions.
- agent-think drops telemetry metadata and uses functionId because AI SDK v7 removed TelemetryOptions.metadata.
- forever-chat uses includeRawChunks directly for raw OpenAI response chunk handling.

## Compatibility

- Consumers of published packages must install ai@7 and @ai-sdk/*@4-compatible peers.
- Code that passed TelemetryOptions.metadata through Think's experimental_telemetry must move that identity into supported v7 telemetry fields or an integration.
- Code that relied on stepNumber inside Think tool completion callbacks should treat it as unavailable for v7-backed executions.
- This change does not migrate callers to new v7 capabilities beyond what is needed to keep the current implementations working.
@changeset-bot

changeset-bot Bot commented Jul 10, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 2497133

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 5 packages
Name Type
agents Minor
@cloudflare/ai-chat Minor
@cloudflare/codemode Minor
@cloudflare/think Minor
@cloudflare/agent-think Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@cjol

cjol commented Jul 10, 2026

Copy link
Copy Markdown
Contributor Author

AI SDK v7 breaking changes encountered

Area Breaking change Resolution / status
Package majors ai moved from v6 to v7, and @ai-sdk/* packages moved from v3 to v4. Updated package ranges across the repo and regenerated pnpm-lock.yaml. Published package peer ranges now require the v7-compatible majors.
Stop conditions stepCountIs was renamed to isStepCount; the old name remains as a deprecated alias. Updated imports and call sites in Think, voice tests, ai-chat e2e, codemode e2e, examples, and experiments.
Prompt option AI SDK call sites now prefer top-level instructions instead of system. Updated AI SDK call sites. Think’s own public API still exposes system to avoid adding a second API migration in this PR.
Lifecycle callbacks Several callback names changed: onStepFinish to onStepEnd, onFinish to onEnd, and experimental_onToolCallFinish to onToolExecutionEnd. Updated AI SDK-facing call sites and callback type imports. Think’s own hook name onStepFinish remains unchanged for callers.
Tool completion event shape onToolExecutionEnd no longer reports { success, output, error, durationMs, stepNumber }; it reports toolExecutionMs plus a toolOutput discriminated union, with no stepNumber. Think maps the v7 event back into its existing ToolCallResultContext shape. durationMs is preserved from toolExecutionMs; stepNumber is now undefined.
Telemetry options experimental_telemetry was renamed to telemetry; TelemetryOptions.metadata was removed. OpenTelemetry integration moved out to @ai-sdk/otel. Think forwards config.telemetry ?? config.experimental_telemetry as telemetry. agent-think moved run identity into functionId. No @ai-sdk/otel registration was added because there was no previous OTEL registration path here.
Usage token fields usage.reasoningTokens and usage.cachedInputTokens were removed in favour of token detail objects. Extension step-finish snapshots read the v7 fields with fallback support for the old shape.
Tool execution options ToolCallOptions was replaced by generic ToolExecutionOptions<CONTEXT>. Tests and tool execution sites were updated to pass the required context shape where needed.
Tool descriptions Tool.description may now be a string or function. Several local adapters still need a plain string or optional string. Normalized function-valued descriptions away in agents browser/client tooling and @cloudflare/codemode connectors.
Portable declaration output Inferred return types from tool() can pull in non-portable provider utility types. Added explicit Tool / ToolSet return annotations on workspace and extension tool factories where needed.
Runtime/module baseline AI SDK packages are ESM-only and require Node 22+. No repo changes were needed: the monorepo is already ESM and local development is on Node 24.
Stream result property StreamTextResult.fullStream was renamed to stream; the alias still works. Left existing fullStream usage in place where it is still functional. Cleanup can happen separately.
UI message stream helpers Result instance methods like result.toUIMessageStream(...) are deprecated in favour of top-level helpers. Left current usage in place. This PR is a compatibility migration, not a behaviour/API cleanup pass.
System messages inside messages System-role messages inside messages or prompt require allowSystemInMessages: true by default. No code change was needed for the audited paths because Think sends system text through the top-level instructions/system path. Consumers with persisted system-role messages may need a separate audit.
Multi-step result accumulation Top-level usage, toolCalls, content, and related fields now accumulate across steps; final-step-only values are under finalStep. No broad behaviour change was made. Consumers that assumed final-step-only semantics should be audited separately.
Image/media content parts v7 prefers file over legacy image, image-data, and media parts, although many legacy shapes are auto-migrated at runtime. Left existing image-data outputs in workspace tools because runtime migration covers them. Cleanup is deferred.
workers-ai-provider peers workers-ai-provider@3.3.0 still declares peers for AI SDK v6 / @ai-sdk/* v3. Installed with the v7 stack and kept the existing paths working in this repo. This remains an upstream peer-range follow-up.

cjol added 3 commits July 13, 2026 15:39
agent-think uses workers-ai-provider's createClientFallbackModel, which had no
AI SDK v7 (LanguageModelV4) release on npm (latest 3.3.1 is v6/LanguageModelV3).
Pinning agent-think to v6 instead caused a dual ai instance in the monorepo
(agent-think on ai@6 vs the workspace think/agents packages on their own ai@7
devDeps), which does not type-check.

Point workers-ai-provider at the v7 preview build from cloudflare/ai#601
(https://pkg.pr.new/cloudflare/ai/workers-ai-provider@601) and put agent-think
fully on v7 (ai@7, @ai-sdk/*@4). This yields a single ai@7 instance across the
workspace and type-checks cleanly.

TODO: swap the pkg.pr.new URL for the published workers-ai-provider v7 release
once cloudflare/ai#601 lands.
cjol and others added 3 commits July 14, 2026 16:22
…t helper

The AI SDK v7 migration wrapped StreamableResult.toUIMessageStream() in
readableStreamToAsyncIterable, changing its return from a ReadableStream to a
pure async generator. A test helper in tests/agents/think-session.ts still
called getReader() on it, throwing "getReader is not a function" mid-stream.
That throw masked the intended simulated error and failed 17 error-handling
tests.

Consume the stream via its async iterator (next / return) instead, matching the
documented AsyncIterable contract.
Widen the "ai" peer range to "^6 || ^7" (and "@ai-sdk/react" to "^3 || ^4")
across agents, @cloudflare/ai-chat, @cloudflare/codemode, and @cloudflare/think,
so consumers can upgrade these packages without being forced onto AI SDK v7.

Think now calls the AI SDK through the option names present in both majors
(stepCountIs, system, experimental_telemetry, onStepFinish,
experimental_onToolCallFinish) and normalizes the genuine divergences at the
boundary:

- normalizeToolFinishEvent collapses the v6 and v7 tool-execution-finished
  event shapes into one ToolCallResultContext.
- The UI message stream uses the result's toUIMessageStream() method (present
  in both majors) instead of the v7-only standalone helper + result.stream.
- The workspace read tool emits the "file-data" model output content part,
  which both majors accept (v7's newer "file" shape does not exist in v6).

Also fix a v7-migration test regression: a test helper called getReader() on
toUIMessageStream()'s result, which became a pure async iterable when
readableStreamToAsyncIterable was introduced, masking the intended error and
failing 17 error-handling tests. It now consumes the async iterator.

Drop the v7-only telemetry test that froze telemetry.integrations behavior
(v6 has no such API).

Add an ai@6 / ai@7 CI matrix (.github/workflows/ai-sdk-compat.yml +
scripts/use-ai-sdk-major.mjs) that type-checks and runs Think's workers tests
under each major. Verified: 0 typecheck errors and full workers suite passing on
both.

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@pkg-pr-new

pkg-pr-new Bot commented Jul 14, 2026

Copy link
Copy Markdown

Open in StackBlitz

agents

npm i https://pkg.pr.new/agents@1922

@cloudflare/ai-chat

npm i https://pkg.pr.new/@cloudflare/ai-chat@1922

@cloudflare/codemode

npm i https://pkg.pr.new/@cloudflare/codemode@1922

create-think

npm i https://pkg.pr.new/create-think@1922

hono-agents

npm i https://pkg.pr.new/hono-agents@1922

@cloudflare/shell

npm i https://pkg.pr.new/@cloudflare/shell@1922

@cloudflare/think

npm i https://pkg.pr.new/@cloudflare/think@1922

@cloudflare/voice

npm i https://pkg.pr.new/@cloudflare/voice@1922

@cloudflare/worker-bundler

npm i https://pkg.pr.new/@cloudflare/worker-bundler@1922

commit: 2497133

@enk0de

enk0de commented Jul 15, 2026

Copy link
Copy Markdown

when is it expected to be merged?

cjol and others added 3 commits July 21, 2026 22:16
)

Widen the "ai" peer range to "^6 || ^7" (and "@ai-sdk/react" to "^3 || ^4")
across agents, @cloudflare/ai-chat, @cloudflare/codemode, and @cloudflare/think,
so consumers can upgrade these packages without being forced onto AI SDK v7.

Think now calls the AI SDK through the option names present in both majors
(stepCountIs, system, experimental_telemetry, onStepFinish,
experimental_onToolCallFinish) and normalizes the genuine divergences at the
boundary:

- normalizeToolFinishEvent collapses the v6 and v7 tool-execution-finished
  event shapes into one ToolCallResultContext.
- The UI message stream uses the result's toUIMessageStream() method (present
  in both majors) instead of the v7-only standalone helper + result.stream.
- The workspace read tool emits the "file-data" model output content part,
  which both majors accept (v7's newer "file" shape does not exist in v6).

Also fix a v7-migration test regression: a test helper called getReader() on
toUIMessageStream()'s result, which became a pure async iterable when
readableStreamToAsyncIterable was introduced, masking the intended error and
failing 17 error-handling tests. It now consumes the async iterator.

Drop the v7-only telemetry test that froze telemetry.integrations behavior
(v6 has no such API).

Add an ai@6 / ai@7 CI matrix (.github/workflows/ai-sdk-compat.yml +
scripts/use-ai-sdk-major.mjs) that type-checks and runs Think's workers tests
under each major. Verified: 0 typecheck errors and full workers suite passing on
both.

Generated with [Devin](https://devin.ai)

Co-authored-by: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
@mattzcarey

Copy link
Copy Markdown
Contributor

@agent-think fix the conflicts on this pr. then force push.

@mattzcarey
mattzcarey marked this pull request as ready for review July 23, 2026 10:16

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Devin Review found 1 potential issue.

View 2 additional findings in Devin Review.

Open in Devin Review

}

if (isToolOrDynamicToolUIPart(part)) {
if (isToolUIPart(part)) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Dynamic tool calls stop rendering in the sandbox coding agent UI

The message part check was switched (isToolUIPart at examples/sandbox-coding-agent/src/client.tsx:196, and also :314 and :416) to one that only recognizes regular tool parts, so any dynamic tool part in an assistant turn is no longer rendered and silently disappears from the conversation.
Impact: In that example, a tool call that arrives as a dynamic tool (e.g. MCP-style tools) shows nothing to the user instead of its input/output/error.

Why this narrows behavior vs. the rest of the repo

The previous guard isToolOrDynamicToolUIPart matched both tool-* parts and dynamic-tool parts. isToolUIPart only matches tool-* parts. Every other client in the repo (e.g. examples/ai-chat/src/client.tsx, examples/assistant/src/client.tsx, the think-starters, etc.) still imports and uses isToolOrDynamicToolUIPart, which confirms the symbol still exists under AI SDK v7 — so this file was changed unnecessarily and now diverges. Both the top-level part branch (:196), the ToolPart guard (:314), and the nested delegate-part branch (:416) were narrowed, so a dynamic-tool part returns null and is dropped rather than displayed. The AGENTS.md chat-rendering rules require rendering tool input/output/errors for every tool; dropping dynamic tools violates that.

Prompt for agents
In examples/sandbox-coding-agent/src/client.tsx the type guard was changed from isToolOrDynamicToolUIPart to isToolUIPart in three places (around lines 196, 314, and 416), and the import at the top was changed accordingly. isToolUIPart only matches parts whose type starts with tool-, whereas isToolOrDynamicToolUIPart also matches dynamic-tool parts. This narrows rendering so dynamic tool parts no longer display. All other client.tsx files in the repo still use isToolOrDynamicToolUIPart under AI SDK v7, so the symbol is still available. Restore isToolOrDynamicToolUIPart (both the import and the three usage sites) to keep dynamic tool parts rendering, matching the rest of the examples and the chat-rendering rules in examples/AGENTS.md.
Open in Devin Review

Was this helpful? React with 👍 or 👎 to provide feedback.

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.

3 participants