Skip to content

feat: support both AI SDK v6 and v7 in Think and its dependencies#1940

Merged
cjol merged 1 commit into
fix/jul9-ai-sdk-v7from
fix/think-ai-sdk-v6-v7-compat
Jul 21, 2026
Merged

feat: support both AI SDK v6 and v7 in Think and its dependencies#1940
cjol merged 1 commit into
fix/jul9-ai-sdk-v7from
fix/think-ai-sdk-v6-v7-compat

Conversation

@cjol

@cjol cjol commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Warning

Do not merge until cloudflare/ai#601 (workers-ai-provider AI SDK v7 support) is released. agent-think depends on a pkg.pr.new preview build of workers-ai-provider (inherited from the base branch fix/jul9-ai-sdk-v7). The pkg.pr.new URL must be replaced with the published workers-ai-provider release before this reaches main.

This PR makes @cloudflare/think, agents, @cloudflare/ai-chat, and @cloudflare/codemode support both AI SDK v6 and v7, rather than the v7-only cutover in #1922. It stacks on #1922 (base branch fix/jul9-ai-sdk-v7) and is offered as an alternative: take #1922 for a clean v7-only move, or this PR to keep v6 working too.

Why

  • The v7-only migration forces every consumer of these packages to upgrade their own ai and @ai-sdk/* majors in lockstep. @cloudflare/ai-chat and @cloudflare/think declare ai as a required peer, so on npm 7+ a consumer staying on v6 hits an ERESOLVE install failure, not a warning.
  • v7 keeps the v6 option names as aliases (system, stepCountIs, experimental_telemetry, onStepFinish, experimental_onToolCallFinish), so calling the SDK through the shared names lets one code path serve both majors without a compile-time fork.
  • The alternative was maintaining two builds or a version-conditional type layer. That was rejected: the only genuine runtime divergences are the tool-finish event shape, the UI stream helper, and one tool-result content part, all of which are cheaper to normalize at the boundary than to fork.
  • Full type parity across both majors is not attempted. The shipped .d.ts is compiled against one major; consumers get correct types for whichever ai they install, and the runtime is correct for both.

Public API Surface

Symbol Kind Notes
ai peer range Changed ^7.0.0 to ^6.0.0 || ^7.0.0 on agents, @cloudflare/ai-chat, @cloudflare/codemode, @cloudflare/think. Additive: v7 consumers unaffected.
@ai-sdk/react peer range Changed ^4.0.0 to ^3.0.0 || ^4.0.0 on agents, @cloudflare/ai-chat, @cloudflare/think.

No exported symbols are added or removed. The change is to peer acceptance ranges only.

Code Changes

  • @cloudflare/think calls streamText through the names present in both majors: system, stepCountIs, experimental_telemetry, onStepFinish, and experimental_onToolCallFinish. In v7 the last resolves internally to onToolExecutionEnd and fires once, so there is no double dispatch.
  • normalizeToolFinishEvent collapses the two tool-execution-finished event shapes ({ success, output, error, durationMs, stepNumber } in v6, { toolOutput, toolExecutionMs } in v7) into one ToolCallResultContext so afterToolCall and extensions are version-agnostic.
  • The UI message stream uses the result's toUIMessageStream() method, which exists in both majors. The standalone toUIMessageStream({ stream }) helper and result.stream are v7-only.
  • The workspace read tool emits the file-data model-output content part, accepted by both majors. v7's newer { type: "file", data: { type: "data", data } } shape does not exist in v6.
  • A test helper called .getReader() on toUIMessageStream()'s result, which became a pure async iterable when readableStreamToAsyncIterable was introduced in the v7 migration. The resulting throw masked the intended error and failed 17 error-handling tests. It now consumes the async iterator.
  • Dropped the telemetry test that asserted on v7's telemetry.integrations callback API, which does not exist in v6, to avoid freezing v7-only behaviour.
  • Added .github/workflows/ai-sdk-compat.yml and scripts/use-ai-sdk-major.mjs: a matrix that installs each ai major and runs @cloudflare/think's typecheck and workers tests under both.

Compatibility

  • Consumers can stay on ai@6 / @ai-sdk/*@3 or move to ai@7 / @ai-sdk/*@4. Bumping these packages no longer forces an AI SDK major upgrade.
  • workers-ai-provider (Think's default model provider) has no v7 release yet, so a consumer on ai@6 who relies on Think's built-in default model may hit a provider-version mismatch. Passing an explicit LanguageModel avoids this.
  • agent-think (private, not published) uses the workers-ai-provider v7 preview from Add support for AI SDK 7 ai#601 and must be repointed at the release before merge, per the warning above.

@changeset-bot

changeset-bot Bot commented Jul 14, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 4c92b98

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

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

Click here to learn what changesets are, and how to add one.

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

@cjol
cjol force-pushed the fix/think-ai-sdk-v6-v7-compat branch 2 times, most recently from 455de86 to 93144a0 Compare July 14, 2026 15:23
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>
@cjol
cjol force-pushed the fix/think-ai-sdk-v6-v7-compat branch from 93144a0 to 4c92b98 Compare July 14, 2026 15:36
@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@1940

@cloudflare/ai-chat

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

@cloudflare/codemode

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

create-think

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

hono-agents

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

@cloudflare/shell

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

@cloudflare/think

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

@cloudflare/voice

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

@cloudflare/worker-bundler

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

commit: 4c92b98

@cjol
cjol marked this pull request as ready for review July 21, 2026 21:16
@cjol
cjol merged commit da44a70 into fix/jul9-ai-sdk-v7 Jul 21, 2026
9 of 10 checks passed
@cjol
cjol deleted the fix/think-ai-sdk-v6-v7-compat branch July 21, 2026 21: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: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 1 additional finding.

Open in Devin Review

cjol added a commit that referenced this pull request Jul 23, 2026
* feat: update AI SDK to v7

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.

* chore: add AI SDK v7 changeset

* fix: add AI SDK v7 migration aliases

* chore(agent-think): adopt AI SDK v7 via workers-ai-provider preview

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.

* fix(think): consume toUIMessageStream result as async iterable in test 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.

* fix(think): pin CLI augment ai range to v7 to match the basic starter

* feat: support both AI SDK v6 and v7 in Think and its dependencies

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>

* feat: support both AI SDK v6 and v7 in Think and its dependencies (#1940)

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>

* fix: update Workers AI provider for AI SDK v7

---------

Co-authored-by: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Co-authored-by: agent-think[bot] <agent-think[bot]@users.noreply.github.com>
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