From a1826a3bf6d3ee5cb486b09a88799f6201ed70c1 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 11 Feb 2026 21:03:50 +0000 Subject: [PATCH 1/2] Version Packages --- .changeset/bright-doors-march.md | 48 ----- .changeset/wide-knives-strive.md | 45 ----- demos/agent-scheduler/package.json | 2 +- .../package.json | 2 +- demos/agent-task-manager/package.json | 2 +- demos/evaluator-optimiser/package.json | 2 +- demos/image-generation/package.json | 2 +- demos/model-scraper/package.json | 2 +- demos/orchestrator-workers/package.json | 2 +- demos/parallelisation/package.json | 2 +- demos/prompt-chaining/package.json | 2 +- demos/routing/package.json | 2 +- demos/structured-output-node/package.json | 2 +- demos/structured-output/package.json | 2 +- demos/text-generation-stream/package.json | 2 +- demos/text-generation/package.json | 2 +- demos/tool-calling-stream/package.json | 2 +- demos/tool-calling/package.json | 2 +- demos/vision/package.json | 2 +- packages/tanstack-ai/CHANGELOG.md | 47 +++++ packages/tanstack-ai/package.json | 2 +- packages/workers-ai-provider/CHANGELOG.md | 169 ++++++++++++------ packages/workers-ai-provider/package.json | 2 +- 23 files changed, 181 insertions(+), 166 deletions(-) delete mode 100644 .changeset/bright-doors-march.md delete mode 100644 .changeset/wide-knives-strive.md create mode 100644 packages/tanstack-ai/CHANGELOG.md diff --git a/.changeset/bright-doors-march.md b/.changeset/bright-doors-march.md deleted file mode 100644 index d34345e7f..000000000 --- a/.changeset/bright-doors-march.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -"workers-ai-provider": minor ---- - -Add transcription, text-to-speech, and reranking support to the Workers AI provider. - -### New capabilities - -- **Transcription** (`provider.transcription(model)`) — implements `TranscriptionModelV3`. Supports Whisper models (`@cf/openai/whisper`, `whisper-tiny-en`, `whisper-large-v3-turbo`) and Deepgram Nova-3 (`@cf/deepgram/nova-3`). Handles model-specific input formats: number arrays for basic Whisper, base64 for v3-turbo via REST, and `{ body, contentType }` for Nova-3 via binding or raw binary upload for Nova-3 via REST. - -- **Speech / TTS** (`provider.speech(model)`) — implements `SpeechModelV3`. Supports Workers AI TTS models including Deepgram Aura-1 (`@cf/deepgram/aura-1`). Accepts `text`, `voice`, and `speed` options. Returns audio as `Uint8Array`. Uses `returnRawResponse` to handle binary audio from the REST path without JSON parsing. - -- **Reranking** (`provider.reranking(model)`) — implements `RerankingModelV3`. Supports BGE reranker models (`@cf/baai/bge-reranker-base`, `bge-reranker-v2-m3`). Converts AI SDK's document format to Workers AI's `{ query, contexts, top_k }` input. Handles both text and JSON object documents. - -### Bug fixes - -- **AbortSignal passthrough** — `createRun` REST shim now passes the abort signal to `fetch`, enabling request cancellation and timeout handling. Previously the signal was silently dropped. -- **Nova-3 REST support** — Added `createRunBinary` utility for models that require raw binary upload instead of JSON (used by Nova-3 transcription via REST). - -### Usage - -```typescript -import { createWorkersAI } from "workers-ai-provider"; -import { experimental_transcribe, experimental_generateSpeech, rerank } from "ai"; - -const workersai = createWorkersAI({ binding: env.AI }); - -// Transcription -const transcript = await experimental_transcribe({ - model: workersai.transcription("@cf/openai/whisper-large-v3-turbo"), - audio: audioData, - mediaType: "audio/wav", -}); - -// Speech -const speech = await experimental_generateSpeech({ - model: workersai.speech("@cf/deepgram/aura-1"), - text: "Hello world", - voice: "asteria", -}); - -// Reranking -const ranked = await rerank({ - model: workersai.reranking("@cf/baai/bge-reranker-base"), - query: "What is machine learning?", - documents: ["ML is a branch of AI.", "The weather is sunny."], -}); -``` diff --git a/.changeset/wide-knives-strive.md b/.changeset/wide-knives-strive.md deleted file mode 100644 index eb596691c..000000000 --- a/.changeset/wide-knives-strive.md +++ /dev/null @@ -1,45 +0,0 @@ ---- -"@cloudflare/tanstack-ai": minor ---- - -Add `@cloudflare/tanstack-ai` — adapters for using TanStack AI with Cloudflare Workers AI and AI Gateway. - -### Workers AI adapters - -All Workers AI adapters support four configuration modes: plain binding (`env.AI`), plain REST (account ID + API key), AI Gateway binding (`env.AI.gateway(id)`), and AI Gateway REST (account ID + gateway ID). - -- **Chat** (`createWorkersAiChat`) — Streaming chat completions via the OpenAI-compatible API. Includes tool calling with full round-trip support, structured output via `json_schema`, and reasoning text streaming (`STEP_STARTED`/`STEP_FINISHED` AG-UI events) for models like QwQ, DeepSeek R1, and Kimi K2.5. A custom fetch shim translates OpenAI SDK calls to `env.AI.run()` for binding mode, with a stream transformer that handles both Workers AI native format and OpenAI-compatible format. -- **Image generation** (`createWorkersAiImage`) — Stable Diffusion and other text-to-image models. -- **Transcription** (`createWorkersAiTranscription`) — Speech-to-text via Whisper and Deepgram Nova-3. -- **Text-to-speech** (`createWorkersAiTts`) — Audio generation via Deepgram Aura-1. -- **Summarization** (`createWorkersAiSummarize`) — Text summarization via BART-large-CNN. -- **Embeddings** (`createWorkersAiEmbedding`) — Text embeddings (implemented but not yet exported, pending TanStack AI's `BaseEmbeddingAdapter`). - -### AI Gateway adapters (third-party providers) - -Route requests through Cloudflare AI Gateway for caching, rate limiting, and unified billing. Each adapter injects a custom `fetch` (or `httpOptions` for Gemini) that handles both binding and credential-based gateway configurations. - -- **OpenAI** — Chat, summarize, image, transcription, TTS, video (`createOpenAi*`) -- **Anthropic** — Chat, summarize (`createAnthropic*`) -- **Gemini** — Chat, summarize, image, TTS (`createGemini*`). Credentials-only (Google GenAI SDK lacks custom fetch support). -- **Grok** — Chat, summarize, image (`createGrok*`) -- **OpenRouter** — Chat, summarize, image (`createOpenRouter*`). Accepts any model string. - -### Utilities - -- `createGatewayFetch` — Shared fetch factory that routes requests through AI Gateway (binding or REST), with support for cache control headers (`skipCache`, `cacheTtl`, `customCacheKey`, `metadata`). -- `createWorkersAiBindingFetch` — Fetch shim that makes `env.AI` look like an OpenAI endpoint, including stream transformation and tool call ID sanitization for the binding's strict `[a-zA-Z0-9]{9}` validation. -- Config detection helpers (`isDirectBindingConfig`, `isDirectCredentialsConfig`, `isGatewayConfig`) using structural typing to discriminate `env.AI` from `env.AI.gateway(id)`. -- Shared binary utilities for normalizing Workers AI responses (Uint8Array, ArrayBuffer, ReadableStream, JSON wrapper) to base64. - -### Robustness - -- Premature stream termination detection — if Workers AI truncates a response or the connection drops (no `finish_reason`), the adapter emits proper closing events so consumers don't hang. -- Graceful non-streaming fallback — if a model returns a complete response despite `stream: true`, the binding shim wraps it into a valid response. -- Deepgram Nova-3 transcription uses raw binary audio via REST (not JSON), automatically detected by model name. - -### Testing - -- Comprehensive unit tests (186 tests) covering all adapters, config modes, stream transformation, message building, tool calling, reasoning events, premature termination, and public API surface. -- E2E integration tests against real Workers AI APIs (both binding and REST paths) across 12 chat models + 4 transcription models + image/TTS/summarize, validating chat, multi-turn, tool calling, tool round-trips, structured output, reasoning, and all non-chat capabilities. -- Tree-shakeable package exports with per-adapter entry points for ESM and CJS. diff --git a/demos/agent-scheduler/package.json b/demos/agent-scheduler/package.json index 851937398..e1ebdeb4a 100644 --- a/demos/agent-scheduler/package.json +++ b/demos/agent-scheduler/package.json @@ -19,7 +19,7 @@ "agents": "^0.4.0", "ai": "^6.0.78", "hono": "^4.11.9", - "workers-ai-provider": "^3.0.5", + "workers-ai-provider": "^3.1.0", "zod": "^4.3.6" }, "devDependencies": { diff --git a/demos/agent-task-manager-human-in-the-loop/package.json b/demos/agent-task-manager-human-in-the-loop/package.json index 57223ba93..8de356e2c 100644 --- a/demos/agent-task-manager-human-in-the-loop/package.json +++ b/demos/agent-task-manager-human-in-the-loop/package.json @@ -19,7 +19,7 @@ "agents": "^0.4.0", "ai": "^6.0.78", "hono": "^4.11.9", - "workers-ai-provider": "^3.0.5", + "workers-ai-provider": "^3.1.0", "zod": "^4.3.6" }, "devDependencies": { diff --git a/demos/agent-task-manager/package.json b/demos/agent-task-manager/package.json index 47dee2447..3ee4db68b 100644 --- a/demos/agent-task-manager/package.json +++ b/demos/agent-task-manager/package.json @@ -19,7 +19,7 @@ "agents": "^0.4.0", "ai": "^6.0.78", "hono": "^4.11.9", - "workers-ai-provider": "^3.0.5", + "workers-ai-provider": "^3.1.0", "zod": "^4.3.6" }, "devDependencies": { diff --git a/demos/evaluator-optimiser/package.json b/demos/evaluator-optimiser/package.json index 75b44320e..3a4dba524 100644 --- a/demos/evaluator-optimiser/package.json +++ b/demos/evaluator-optimiser/package.json @@ -19,7 +19,7 @@ "agents": "^0.4.0", "ai": "^6.0.78", "hono": "^4.11.9", - "workers-ai-provider": "^3.0.5", + "workers-ai-provider": "^3.1.0", "zod": "^4.3.6" }, "devDependencies": { diff --git a/demos/image-generation/package.json b/demos/image-generation/package.json index 56a95a5a4..45950d990 100644 --- a/demos/image-generation/package.json +++ b/demos/image-generation/package.json @@ -18,7 +18,7 @@ "dependencies": { "ai": "^6.0.78", "hono": "^4.11.9", - "workers-ai-provider": "^3.0.5", + "workers-ai-provider": "^3.1.0", "zod": "^4.3.6" }, "devDependencies": { diff --git a/demos/model-scraper/package.json b/demos/model-scraper/package.json index 3534aea93..5e0487c67 100644 --- a/demos/model-scraper/package.json +++ b/demos/model-scraper/package.json @@ -23,7 +23,7 @@ "agents": "^0.4.0", "ai": "^6.0.78", "hono": "^4.11.9", - "workers-ai-provider": "^3.0.5", + "workers-ai-provider": "^3.1.0", "zod": "^4.3.6" }, "devDependencies": { diff --git a/demos/orchestrator-workers/package.json b/demos/orchestrator-workers/package.json index 2811300c1..5cfb37615 100644 --- a/demos/orchestrator-workers/package.json +++ b/demos/orchestrator-workers/package.json @@ -19,7 +19,7 @@ "agents": "^0.4.0", "ai": "^6.0.78", "hono": "^4.11.9", - "workers-ai-provider": "^3.0.5", + "workers-ai-provider": "^3.1.0", "zod": "^4.3.6" }, "devDependencies": { diff --git a/demos/parallelisation/package.json b/demos/parallelisation/package.json index a94c6ab6a..9cdf37ea3 100644 --- a/demos/parallelisation/package.json +++ b/demos/parallelisation/package.json @@ -19,7 +19,7 @@ "agents": "^0.4.0", "ai": "^6.0.78", "hono": "^4.11.9", - "workers-ai-provider": "^3.0.5", + "workers-ai-provider": "^3.1.0", "zod": "^4.3.6" }, "devDependencies": { diff --git a/demos/prompt-chaining/package.json b/demos/prompt-chaining/package.json index ed4464545..9ef2afaf1 100644 --- a/demos/prompt-chaining/package.json +++ b/demos/prompt-chaining/package.json @@ -19,7 +19,7 @@ "agents": "^0.4.0", "ai": "^6.0.78", "hono": "^4.11.9", - "workers-ai-provider": "^3.0.5", + "workers-ai-provider": "^3.1.0", "zod": "^4.3.6" }, "devDependencies": { diff --git a/demos/routing/package.json b/demos/routing/package.json index 944c507b1..7b1f7aa93 100644 --- a/demos/routing/package.json +++ b/demos/routing/package.json @@ -18,7 +18,7 @@ "agents": "^0.4.0", "ai": "^6.0.78", "hono": "^4.11.9", - "workers-ai-provider": "^3.0.5", + "workers-ai-provider": "^3.1.0", "zod": "^4.3.6" }, "devDependencies": { diff --git a/demos/structured-output-node/package.json b/demos/structured-output-node/package.json index 594a9d7e9..fc3096e0c 100644 --- a/demos/structured-output-node/package.json +++ b/demos/structured-output-node/package.json @@ -11,7 +11,7 @@ }, "dependencies": { "ai": "^6.0.78", - "workers-ai-provider": "^3.0.5", + "workers-ai-provider": "^3.1.0", "zod": "^4.3.6" }, "devDependencies": { diff --git a/demos/structured-output/package.json b/demos/structured-output/package.json index 1a00ff919..91fc87da3 100644 --- a/demos/structured-output/package.json +++ b/demos/structured-output/package.json @@ -20,7 +20,7 @@ "agents": "^0.4.0", "ai": "^6.0.78", "hono": "^4.11.9", - "workers-ai-provider": "^3.0.5", + "workers-ai-provider": "^3.1.0", "zod": "^4.3.6" }, "devDependencies": { diff --git a/demos/text-generation-stream/package.json b/demos/text-generation-stream/package.json index 25ffbed0c..c9a8fbd36 100644 --- a/demos/text-generation-stream/package.json +++ b/demos/text-generation-stream/package.json @@ -19,7 +19,7 @@ "agents": "^0.4.0", "ai": "^6.0.78", "hono": "^4.11.9", - "workers-ai-provider": "^3.0.5", + "workers-ai-provider": "^3.1.0", "zod": "^4.3.6" }, "devDependencies": { diff --git a/demos/text-generation/package.json b/demos/text-generation/package.json index 33980f01a..541da6b32 100644 --- a/demos/text-generation/package.json +++ b/demos/text-generation/package.json @@ -19,7 +19,7 @@ "agents": "^0.4.0", "ai": "^6.0.78", "hono": "^4.11.9", - "workers-ai-provider": "^3.0.5", + "workers-ai-provider": "^3.1.0", "zod": "^4.3.6" }, "devDependencies": { diff --git a/demos/tool-calling-stream/package.json b/demos/tool-calling-stream/package.json index 5d76d0b04..f102c9733 100644 --- a/demos/tool-calling-stream/package.json +++ b/demos/tool-calling-stream/package.json @@ -19,7 +19,7 @@ "agents": "^0.4.0", "ai": "^6.0.78", "hono": "^4.11.9", - "workers-ai-provider": "^3.0.5", + "workers-ai-provider": "^3.1.0", "zod": "^4.3.6" }, "devDependencies": { diff --git a/demos/tool-calling/package.json b/demos/tool-calling/package.json index ed79b4713..0de2032ff 100644 --- a/demos/tool-calling/package.json +++ b/demos/tool-calling/package.json @@ -20,7 +20,7 @@ "agents": "^0.4.0", "ai": "^6.0.78", "hono": "^4.11.9", - "workers-ai-provider": "^3.0.5", + "workers-ai-provider": "^3.1.0", "zod": "^4.3.6" }, "devDependencies": { diff --git a/demos/vision/package.json b/demos/vision/package.json index 39433d4c3..33bc6596e 100644 --- a/demos/vision/package.json +++ b/demos/vision/package.json @@ -18,7 +18,7 @@ "hono": "^4.11.9", "react": "^19.2.4", "react-dom": "^19.2.4", - "workers-ai-provider": "^3.0.5", + "workers-ai-provider": "^3.1.0", "zod": "^4.3.6" }, "devDependencies": { diff --git a/packages/tanstack-ai/CHANGELOG.md b/packages/tanstack-ai/CHANGELOG.md new file mode 100644 index 000000000..30d79f8e3 --- /dev/null +++ b/packages/tanstack-ai/CHANGELOG.md @@ -0,0 +1,47 @@ +# @cloudflare/tanstack-ai + +## 0.1.0 + +### Minor Changes + +- [#389](https://github.com/cloudflare/ai/pull/389) [`a4b756e`](https://github.com/cloudflare/ai/commit/a4b756ebce97c4fa3e376293b0100d7784a15654) Thanks [@vaibhavshn](https://github.com/vaibhavshn)! - Add `@cloudflare/tanstack-ai` — adapters for using TanStack AI with Cloudflare Workers AI and AI Gateway. + + ### Workers AI adapters + + All Workers AI adapters support four configuration modes: plain binding (`env.AI`), plain REST (account ID + API key), AI Gateway binding (`env.AI.gateway(id)`), and AI Gateway REST (account ID + gateway ID). + + - **Chat** (`createWorkersAiChat`) — Streaming chat completions via the OpenAI-compatible API. Includes tool calling with full round-trip support, structured output via `json_schema`, and reasoning text streaming (`STEP_STARTED`/`STEP_FINISHED` AG-UI events) for models like QwQ, DeepSeek R1, and Kimi K2.5. A custom fetch shim translates OpenAI SDK calls to `env.AI.run()` for binding mode, with a stream transformer that handles both Workers AI native format and OpenAI-compatible format. + - **Image generation** (`createWorkersAiImage`) — Stable Diffusion and other text-to-image models. + - **Transcription** (`createWorkersAiTranscription`) — Speech-to-text via Whisper and Deepgram Nova-3. + - **Text-to-speech** (`createWorkersAiTts`) — Audio generation via Deepgram Aura-1. + - **Summarization** (`createWorkersAiSummarize`) — Text summarization via BART-large-CNN. + - **Embeddings** (`createWorkersAiEmbedding`) — Text embeddings (implemented but not yet exported, pending TanStack AI's `BaseEmbeddingAdapter`). + + ### AI Gateway adapters (third-party providers) + + Route requests through Cloudflare AI Gateway for caching, rate limiting, and unified billing. Each adapter injects a custom `fetch` (or `httpOptions` for Gemini) that handles both binding and credential-based gateway configurations. + + - **OpenAI** — Chat, summarize, image, transcription, TTS, video (`createOpenAi*`) + - **Anthropic** — Chat, summarize (`createAnthropic*`) + - **Gemini** — Chat, summarize, image, TTS (`createGemini*`). Credentials-only (Google GenAI SDK lacks custom fetch support). + - **Grok** — Chat, summarize, image (`createGrok*`) + - **OpenRouter** — Chat, summarize, image (`createOpenRouter*`). Accepts any model string. + + ### Utilities + + - `createGatewayFetch` — Shared fetch factory that routes requests through AI Gateway (binding or REST), with support for cache control headers (`skipCache`, `cacheTtl`, `customCacheKey`, `metadata`). + - `createWorkersAiBindingFetch` — Fetch shim that makes `env.AI` look like an OpenAI endpoint, including stream transformation and tool call ID sanitization for the binding's strict `[a-zA-Z0-9]{9}` validation. + - Config detection helpers (`isDirectBindingConfig`, `isDirectCredentialsConfig`, `isGatewayConfig`) using structural typing to discriminate `env.AI` from `env.AI.gateway(id)`. + - Shared binary utilities for normalizing Workers AI responses (Uint8Array, ArrayBuffer, ReadableStream, JSON wrapper) to base64. + + ### Robustness + + - Premature stream termination detection — if Workers AI truncates a response or the connection drops (no `finish_reason`), the adapter emits proper closing events so consumers don't hang. + - Graceful non-streaming fallback — if a model returns a complete response despite `stream: true`, the binding shim wraps it into a valid response. + - Deepgram Nova-3 transcription uses raw binary audio via REST (not JSON), automatically detected by model name. + + ### Testing + + - Comprehensive unit tests (186 tests) covering all adapters, config modes, stream transformation, message building, tool calling, reasoning events, premature termination, and public API surface. + - E2E integration tests against real Workers AI APIs (both binding and REST paths) across 12 chat models + 4 transcription models + image/TTS/summarize, validating chat, multi-turn, tool calling, tool round-trips, structured output, reasoning, and all non-chat capabilities. + - Tree-shakeable package exports with per-adapter entry points for ESM and CJS. diff --git a/packages/tanstack-ai/package.json b/packages/tanstack-ai/package.json index 0dbf48309..0fe292c6d 100644 --- a/packages/tanstack-ai/package.json +++ b/packages/tanstack-ai/package.json @@ -1,6 +1,6 @@ { "name": "@cloudflare/tanstack-ai", - "version": "0.0.0", + "version": "0.1.0", "description": "Use TanStack AI with Cloudflare Workers AI and AI Gateway", "keywords": [ "ai", diff --git a/packages/workers-ai-provider/CHANGELOG.md b/packages/workers-ai-provider/CHANGELOG.md index 1b577a1a8..7aa72dc62 100644 --- a/packages/workers-ai-provider/CHANGELOG.md +++ b/packages/workers-ai-provider/CHANGELOG.md @@ -1,58 +1,118 @@ # workers-ai-provider +## 3.1.0 + +### Minor Changes + +- [#389](https://github.com/cloudflare/ai/pull/389) [`8538cd5`](https://github.com/cloudflare/ai/commit/8538cd53ce2e1be28cca95217725dfd4642fd7da) Thanks [@vaibhavshn](https://github.com/vaibhavshn)! - Add transcription, text-to-speech, and reranking support to the Workers AI provider. + + ### New capabilities + + - **Transcription** (`provider.transcription(model)`) — implements `TranscriptionModelV3`. Supports Whisper models (`@cf/openai/whisper`, `whisper-tiny-en`, `whisper-large-v3-turbo`) and Deepgram Nova-3 (`@cf/deepgram/nova-3`). Handles model-specific input formats: number arrays for basic Whisper, base64 for v3-turbo via REST, and `{ body, contentType }` for Nova-3 via binding or raw binary upload for Nova-3 via REST. + + - **Speech / TTS** (`provider.speech(model)`) — implements `SpeechModelV3`. Supports Workers AI TTS models including Deepgram Aura-1 (`@cf/deepgram/aura-1`). Accepts `text`, `voice`, and `speed` options. Returns audio as `Uint8Array`. Uses `returnRawResponse` to handle binary audio from the REST path without JSON parsing. + + - **Reranking** (`provider.reranking(model)`) — implements `RerankingModelV3`. Supports BGE reranker models (`@cf/baai/bge-reranker-base`, `bge-reranker-v2-m3`). Converts AI SDK's document format to Workers AI's `{ query, contexts, top_k }` input. Handles both text and JSON object documents. + + ### Bug fixes + + - **AbortSignal passthrough** — `createRun` REST shim now passes the abort signal to `fetch`, enabling request cancellation and timeout handling. Previously the signal was silently dropped. + - **Nova-3 REST support** — Added `createRunBinary` utility for models that require raw binary upload instead of JSON (used by Nova-3 transcription via REST). + + ### Usage + + ```typescript + import { createWorkersAI } from "workers-ai-provider"; + import { + experimental_transcribe, + experimental_generateSpeech, + rerank, + } from "ai"; + + const workersai = createWorkersAI({ binding: env.AI }); + + // Transcription + const transcript = await experimental_transcribe({ + model: workersai.transcription("@cf/openai/whisper-large-v3-turbo"), + audio: audioData, + mediaType: "audio/wav", + }); + + // Speech + const speech = await experimental_generateSpeech({ + model: workersai.speech("@cf/deepgram/aura-1"), + text: "Hello world", + voice: "asteria", + }); + + // Reranking + const ranked = await rerank({ + model: workersai.reranking("@cf/baai/bge-reranker-base"), + query: "What is machine learning?", + documents: ["ML is a branch of AI.", "The weather is sunny."], + }); + ``` + ## 3.0.5 ### Patch Changes - [#393](https://github.com/cloudflare/ai/pull/393) [`91b32e0`](https://github.com/cloudflare/ai/commit/91b32e0b0ef543fd198ddf387b9521ac3bd9650a) Thanks [@threepointone](https://github.com/threepointone)! - Comprehensive cleanup of the workers-ai-provider package. - **Bug fixes:** - - Fixed phantom dependency on `fetch-event-stream` that caused runtime crashes when installed outside the monorepo. Replaced with a built-in SSE parser. - - Fixed streaming buffering: responses now stream token-by-token instead of arriving all at once. The root cause was twofold — an eager `ReadableStream` `start()` pattern that buffered all chunks, and a heuristic that silently fell back to non-streaming `doGenerate` whenever tools were defined. Both are fixed. Streaming now uses a proper `TransformStream` pipeline with backpressure. - - Fixed `reasoning-delta` ID mismatch in simulated streaming — was using `generateId()` instead of the `reasoningId` from the preceding `reasoning-start` event, causing the AI SDK to drop reasoning content. - - Fixed REST API client (`createRun`) silently swallowing HTTP errors. Non-200 responses now throw with status code and response body. - - Fixed `response_format` being sent as `undefined` on every non-JSON request. Now only included when actually set. - - Fixed `json_schema` field evaluating to `false` (a boolean) instead of `undefined` when schema was missing. - - **Workers AI quirk workarounds:** - - Added `sanitizeToolCallId()` — strips non-alphanumeric characters and pads/truncates to 9 chars, fixing tool call round-trips through the binding which rejects its own generated IDs. - - Added `normalizeMessagesForBinding()` — converts `content: null` to `""` and sanitizes tool call IDs before every binding call. Only applied on the binding path (REST preserves original IDs). - - Added null-finalization chunk filtering for streaming tool calls. - - Added numeric value coercion in native-format streams (Workers AI sometimes returns numbers instead of strings for the `response` field). - - Improved image model to handle all output types from `binding.run()`: `ReadableStream`, `Uint8Array`, `ArrayBuffer`, `Response`, and `{ image: base64 }` objects. - - Graceful degradation: if `binding.run()` returns a non-streaming response despite `stream: true`, it wraps the complete response as a simulated stream instead of throwing. - - **Premature stream termination detection:** - - Streams that end without a `[DONE]` sentinel now report `finishReason: "error"` with `raw: "stream-truncated"` instead of silently reporting `"stop"`. - - Stream read errors are caught and emit `finishReason: "error"` with `raw: "stream-error"`. - - **AI Search (formerly AutoRAG):** - - Added `createAISearch` and `AISearchChatLanguageModel` as the canonical exports, reflecting the rename from AutoRAG to AI Search. - - `createAutoRAG` still works but emits a one-time deprecation warning pointing to `createAISearch`. - - `createAutoRAG` preserves `"autorag.chat"` as the provider name for backward compatibility. - - AI Search now warns when tools or JSON response format are provided (unsupported by the `aiSearch` API). - - Simplified AI Search internals — removed dead tool/response-format processing code. - - **Code quality:** - - Removed dead code: `workersai-error.ts` (never imported), `workersai-image-config.ts` (inlined). - - Consistent file naming: renamed `workers-ai-embedding-model.ts` to `workersai-embedding-model.ts`. - - Replaced `StringLike` catch-all index signatures with `[key: string]: unknown` on settings types. - - Replaced `any` types with proper interfaces (`FlatToolCall`, `OpenAIToolCall`, `PartialToolCall`). - - Tightened `processToolCall` format detection to check `function.name` instead of just the presence of a `function` property. - - Removed `@ai-sdk/provider-utils` and `zod` peer dependencies (no longer used in source). - - Added `imageModel` to the `WorkersAI` interface type for consistency. - - **Tests:** - - 149 unit tests across 10 test files (up from 82). - - New test coverage: `sanitizeToolCallId`, `normalizeMessagesForBinding`, `prepareToolsAndToolChoice`, `processText`, `mapWorkersAIUsage`, image model output types, streaming error scenarios (malformed SSE, premature termination, empty stream), backpressure verification, graceful degradation (non-streaming fallback with text/tools/reasoning), REST API error handling (401/404/500), AI Search warnings, embedding `TooManyEmbeddingValuesForCallError`, message conversion with images and reasoning. - - Integration tests for REST API and binding across 12 models and 7 categories (chat, streaming, multi-turn, tool calling, tool round-trip, structured output, image generation, embeddings). - - All tests use the AI SDK's public APIs (`generateText`, `streamText`, `generateImage`, `embedMany`) instead of internal `.doGenerate()`/`.doStream()` methods. - - **README:** - - Rewritten from scratch with concise examples, model recommendations, configuration guide, and known limitations section. - - Updated to use current AI SDK v6 APIs (`generateText` + `Output.object` instead of deprecated `generateObject`, `generateImage` instead of `experimental_generateImage`, `stopWhen: stepCountIs(2)` instead of `maxSteps`). - - Added sections for tool calling, structured output, embeddings, image generation, and AI Search. - - Uses `wrangler.jsonc` format for configuration examples. + **Bug fixes:** + + - Fixed phantom dependency on `fetch-event-stream` that caused runtime crashes when installed outside the monorepo. Replaced with a built-in SSE parser. + - Fixed streaming buffering: responses now stream token-by-token instead of arriving all at once. The root cause was twofold — an eager `ReadableStream` `start()` pattern that buffered all chunks, and a heuristic that silently fell back to non-streaming `doGenerate` whenever tools were defined. Both are fixed. Streaming now uses a proper `TransformStream` pipeline with backpressure. + - Fixed `reasoning-delta` ID mismatch in simulated streaming — was using `generateId()` instead of the `reasoningId` from the preceding `reasoning-start` event, causing the AI SDK to drop reasoning content. + - Fixed REST API client (`createRun`) silently swallowing HTTP errors. Non-200 responses now throw with status code and response body. + - Fixed `response_format` being sent as `undefined` on every non-JSON request. Now only included when actually set. + - Fixed `json_schema` field evaluating to `false` (a boolean) instead of `undefined` when schema was missing. + + **Workers AI quirk workarounds:** + + - Added `sanitizeToolCallId()` — strips non-alphanumeric characters and pads/truncates to 9 chars, fixing tool call round-trips through the binding which rejects its own generated IDs. + - Added `normalizeMessagesForBinding()` — converts `content: null` to `""` and sanitizes tool call IDs before every binding call. Only applied on the binding path (REST preserves original IDs). + - Added null-finalization chunk filtering for streaming tool calls. + - Added numeric value coercion in native-format streams (Workers AI sometimes returns numbers instead of strings for the `response` field). + - Improved image model to handle all output types from `binding.run()`: `ReadableStream`, `Uint8Array`, `ArrayBuffer`, `Response`, and `{ image: base64 }` objects. + - Graceful degradation: if `binding.run()` returns a non-streaming response despite `stream: true`, it wraps the complete response as a simulated stream instead of throwing. + + **Premature stream termination detection:** + + - Streams that end without a `[DONE]` sentinel now report `finishReason: "error"` with `raw: "stream-truncated"` instead of silently reporting `"stop"`. + - Stream read errors are caught and emit `finishReason: "error"` with `raw: "stream-error"`. + + **AI Search (formerly AutoRAG):** + + - Added `createAISearch` and `AISearchChatLanguageModel` as the canonical exports, reflecting the rename from AutoRAG to AI Search. + - `createAutoRAG` still works but emits a one-time deprecation warning pointing to `createAISearch`. + - `createAutoRAG` preserves `"autorag.chat"` as the provider name for backward compatibility. + - AI Search now warns when tools or JSON response format are provided (unsupported by the `aiSearch` API). + - Simplified AI Search internals — removed dead tool/response-format processing code. + + **Code quality:** + + - Removed dead code: `workersai-error.ts` (never imported), `workersai-image-config.ts` (inlined). + - Consistent file naming: renamed `workers-ai-embedding-model.ts` to `workersai-embedding-model.ts`. + - Replaced `StringLike` catch-all index signatures with `[key: string]: unknown` on settings types. + - Replaced `any` types with proper interfaces (`FlatToolCall`, `OpenAIToolCall`, `PartialToolCall`). + - Tightened `processToolCall` format detection to check `function.name` instead of just the presence of a `function` property. + - Removed `@ai-sdk/provider-utils` and `zod` peer dependencies (no longer used in source). + - Added `imageModel` to the `WorkersAI` interface type for consistency. + + **Tests:** + + - 149 unit tests across 10 test files (up from 82). + - New test coverage: `sanitizeToolCallId`, `normalizeMessagesForBinding`, `prepareToolsAndToolChoice`, `processText`, `mapWorkersAIUsage`, image model output types, streaming error scenarios (malformed SSE, premature termination, empty stream), backpressure verification, graceful degradation (non-streaming fallback with text/tools/reasoning), REST API error handling (401/404/500), AI Search warnings, embedding `TooManyEmbeddingValuesForCallError`, message conversion with images and reasoning. + - Integration tests for REST API and binding across 12 models and 7 categories (chat, streaming, multi-turn, tool calling, tool round-trip, structured output, image generation, embeddings). + - All tests use the AI SDK's public APIs (`generateText`, `streamText`, `generateImage`, `embedMany`) instead of internal `.doGenerate()`/`.doStream()` methods. + + **README:** + + - Rewritten from scratch with concise examples, model recommendations, configuration guide, and known limitations section. + - Updated to use current AI SDK v6 APIs (`generateText` + `Output.object` instead of deprecated `generateObject`, `generateImage` instead of `experimental_generateImage`, `stopWhen: stepCountIs(2)` instead of `maxSteps`). + - Added sections for tool calling, structured output, embeddings, image generation, and AI Search. + - Uses `wrangler.jsonc` format for configuration examples. ## 3.0.4 @@ -60,13 +120,14 @@ - [#390](https://github.com/cloudflare/ai/pull/390) [`41b92a3`](https://github.com/cloudflare/ai/commit/41b92a34ce4d9dffba8bb42b4933bbc06e4b1aaa) Thanks [@mchenco](https://github.com/mchenco)! - fix(workers-ai-provider): extract actual finish reason in streaming instead of hardcoded "stop" - Previously, the streaming implementation always returned `finishReason: "stop"` regardless of the actual completion reason. This caused: - - Tool calling scenarios to incorrectly report "stop" instead of "tool-calls" - - Multi-turn tool conversations to fail because the AI SDK couldn't detect when tools were requested - - Length limit scenarios to show "stop" instead of "length" - - Error scenarios to show "stop" instead of "error" + Previously, the streaming implementation always returned `finishReason: "stop"` regardless of the actual completion reason. This caused: + + - Tool calling scenarios to incorrectly report "stop" instead of "tool-calls" + - Multi-turn tool conversations to fail because the AI SDK couldn't detect when tools were requested + - Length limit scenarios to show "stop" instead of "length" + - Error scenarios to show "stop" instead of "error" - The fix extracts the actual `finish_reason` from streaming chunks and uses the existing `mapWorkersAIFinishReason()` function to properly map it to the AI SDK's finish reason format. This enables proper multi-turn tool calling and accurate completion status reporting. + The fix extracts the actual `finish_reason` from streaming chunks and uses the existing `mapWorkersAIFinishReason()` function to properly map it to the AI SDK's finish reason format. This enables proper multi-turn tool calling and accurate completion status reporting. ## 3.0.3 @@ -110,7 +171,7 @@ - [#256](https://github.com/cloudflare/ai/pull/256) [`a538901`](https://github.com/cloudflare/ai/commit/a5389013b9a512707fb1de1501a1547fce20c014) Thanks [@jahands](https://github.com/jahands)! - feat: Migrate to AI SDK v5 - This updates workers-ai-provider and ai-gateway-provider to use the AI SDK v5. Please refer to the official migration guide to migrate your code https://ai-sdk.dev/docs/migration-guides/migration-guide-5-0 + This updates workers-ai-provider and ai-gateway-provider to use the AI SDK v5. Please refer to the official migration guide to migrate your code https://ai-sdk.dev/docs/migration-guides/migration-guide-5-0 ### Patch Changes diff --git a/packages/workers-ai-provider/package.json b/packages/workers-ai-provider/package.json index b8d629c79..fdf082f56 100644 --- a/packages/workers-ai-provider/package.json +++ b/packages/workers-ai-provider/package.json @@ -1,6 +1,6 @@ { "name": "workers-ai-provider", - "version": "3.0.5", + "version": "3.1.0", "description": "Workers AI Provider for the vercel AI SDK", "keywords": [ "ai", From 896137ce23a234700a3d787b54c3c55bd9dd25f4 Mon Sep 17 00:00:00 2001 From: Sunil Pai Date: Wed, 11 Feb 2026 21:18:06 +0000 Subject: [PATCH 2/2] down versions for release --- demos/agent-scheduler/package.json | 2 +- demos/agent-task-manager-human-in-the-loop/package.json | 2 +- demos/agent-task-manager/package.json | 2 +- demos/evaluator-optimiser/package.json | 2 +- demos/image-generation/package.json | 2 +- demos/model-scraper/package.json | 2 +- demos/orchestrator-workers/package.json | 2 +- demos/parallelisation/package.json | 2 +- demos/prompt-chaining/package.json | 2 +- demos/routing/package.json | 2 +- demos/structured-output-node/package.json | 2 +- demos/structured-output/package.json | 2 +- demos/text-generation-stream/package.json | 2 +- demos/text-generation/package.json | 2 +- demos/tool-calling-stream/package.json | 2 +- demos/tool-calling/package.json | 2 +- demos/vision/package.json | 2 +- 17 files changed, 17 insertions(+), 17 deletions(-) diff --git a/demos/agent-scheduler/package.json b/demos/agent-scheduler/package.json index e1ebdeb4a..851937398 100644 --- a/demos/agent-scheduler/package.json +++ b/demos/agent-scheduler/package.json @@ -19,7 +19,7 @@ "agents": "^0.4.0", "ai": "^6.0.78", "hono": "^4.11.9", - "workers-ai-provider": "^3.1.0", + "workers-ai-provider": "^3.0.5", "zod": "^4.3.6" }, "devDependencies": { diff --git a/demos/agent-task-manager-human-in-the-loop/package.json b/demos/agent-task-manager-human-in-the-loop/package.json index 8de356e2c..57223ba93 100644 --- a/demos/agent-task-manager-human-in-the-loop/package.json +++ b/demos/agent-task-manager-human-in-the-loop/package.json @@ -19,7 +19,7 @@ "agents": "^0.4.0", "ai": "^6.0.78", "hono": "^4.11.9", - "workers-ai-provider": "^3.1.0", + "workers-ai-provider": "^3.0.5", "zod": "^4.3.6" }, "devDependencies": { diff --git a/demos/agent-task-manager/package.json b/demos/agent-task-manager/package.json index 3ee4db68b..47dee2447 100644 --- a/demos/agent-task-manager/package.json +++ b/demos/agent-task-manager/package.json @@ -19,7 +19,7 @@ "agents": "^0.4.0", "ai": "^6.0.78", "hono": "^4.11.9", - "workers-ai-provider": "^3.1.0", + "workers-ai-provider": "^3.0.5", "zod": "^4.3.6" }, "devDependencies": { diff --git a/demos/evaluator-optimiser/package.json b/demos/evaluator-optimiser/package.json index 3a4dba524..75b44320e 100644 --- a/demos/evaluator-optimiser/package.json +++ b/demos/evaluator-optimiser/package.json @@ -19,7 +19,7 @@ "agents": "^0.4.0", "ai": "^6.0.78", "hono": "^4.11.9", - "workers-ai-provider": "^3.1.0", + "workers-ai-provider": "^3.0.5", "zod": "^4.3.6" }, "devDependencies": { diff --git a/demos/image-generation/package.json b/demos/image-generation/package.json index 45950d990..56a95a5a4 100644 --- a/demos/image-generation/package.json +++ b/demos/image-generation/package.json @@ -18,7 +18,7 @@ "dependencies": { "ai": "^6.0.78", "hono": "^4.11.9", - "workers-ai-provider": "^3.1.0", + "workers-ai-provider": "^3.0.5", "zod": "^4.3.6" }, "devDependencies": { diff --git a/demos/model-scraper/package.json b/demos/model-scraper/package.json index 5e0487c67..3534aea93 100644 --- a/demos/model-scraper/package.json +++ b/demos/model-scraper/package.json @@ -23,7 +23,7 @@ "agents": "^0.4.0", "ai": "^6.0.78", "hono": "^4.11.9", - "workers-ai-provider": "^3.1.0", + "workers-ai-provider": "^3.0.5", "zod": "^4.3.6" }, "devDependencies": { diff --git a/demos/orchestrator-workers/package.json b/demos/orchestrator-workers/package.json index 5cfb37615..2811300c1 100644 --- a/demos/orchestrator-workers/package.json +++ b/demos/orchestrator-workers/package.json @@ -19,7 +19,7 @@ "agents": "^0.4.0", "ai": "^6.0.78", "hono": "^4.11.9", - "workers-ai-provider": "^3.1.0", + "workers-ai-provider": "^3.0.5", "zod": "^4.3.6" }, "devDependencies": { diff --git a/demos/parallelisation/package.json b/demos/parallelisation/package.json index 9cdf37ea3..a94c6ab6a 100644 --- a/demos/parallelisation/package.json +++ b/demos/parallelisation/package.json @@ -19,7 +19,7 @@ "agents": "^0.4.0", "ai": "^6.0.78", "hono": "^4.11.9", - "workers-ai-provider": "^3.1.0", + "workers-ai-provider": "^3.0.5", "zod": "^4.3.6" }, "devDependencies": { diff --git a/demos/prompt-chaining/package.json b/demos/prompt-chaining/package.json index 9ef2afaf1..ed4464545 100644 --- a/demos/prompt-chaining/package.json +++ b/demos/prompt-chaining/package.json @@ -19,7 +19,7 @@ "agents": "^0.4.0", "ai": "^6.0.78", "hono": "^4.11.9", - "workers-ai-provider": "^3.1.0", + "workers-ai-provider": "^3.0.5", "zod": "^4.3.6" }, "devDependencies": { diff --git a/demos/routing/package.json b/demos/routing/package.json index 7b1f7aa93..944c507b1 100644 --- a/demos/routing/package.json +++ b/demos/routing/package.json @@ -18,7 +18,7 @@ "agents": "^0.4.0", "ai": "^6.0.78", "hono": "^4.11.9", - "workers-ai-provider": "^3.1.0", + "workers-ai-provider": "^3.0.5", "zod": "^4.3.6" }, "devDependencies": { diff --git a/demos/structured-output-node/package.json b/demos/structured-output-node/package.json index fc3096e0c..594a9d7e9 100644 --- a/demos/structured-output-node/package.json +++ b/demos/structured-output-node/package.json @@ -11,7 +11,7 @@ }, "dependencies": { "ai": "^6.0.78", - "workers-ai-provider": "^3.1.0", + "workers-ai-provider": "^3.0.5", "zod": "^4.3.6" }, "devDependencies": { diff --git a/demos/structured-output/package.json b/demos/structured-output/package.json index 91fc87da3..1a00ff919 100644 --- a/demos/structured-output/package.json +++ b/demos/structured-output/package.json @@ -20,7 +20,7 @@ "agents": "^0.4.0", "ai": "^6.0.78", "hono": "^4.11.9", - "workers-ai-provider": "^3.1.0", + "workers-ai-provider": "^3.0.5", "zod": "^4.3.6" }, "devDependencies": { diff --git a/demos/text-generation-stream/package.json b/demos/text-generation-stream/package.json index c9a8fbd36..25ffbed0c 100644 --- a/demos/text-generation-stream/package.json +++ b/demos/text-generation-stream/package.json @@ -19,7 +19,7 @@ "agents": "^0.4.0", "ai": "^6.0.78", "hono": "^4.11.9", - "workers-ai-provider": "^3.1.0", + "workers-ai-provider": "^3.0.5", "zod": "^4.3.6" }, "devDependencies": { diff --git a/demos/text-generation/package.json b/demos/text-generation/package.json index 541da6b32..33980f01a 100644 --- a/demos/text-generation/package.json +++ b/demos/text-generation/package.json @@ -19,7 +19,7 @@ "agents": "^0.4.0", "ai": "^6.0.78", "hono": "^4.11.9", - "workers-ai-provider": "^3.1.0", + "workers-ai-provider": "^3.0.5", "zod": "^4.3.6" }, "devDependencies": { diff --git a/demos/tool-calling-stream/package.json b/demos/tool-calling-stream/package.json index f102c9733..5d76d0b04 100644 --- a/demos/tool-calling-stream/package.json +++ b/demos/tool-calling-stream/package.json @@ -19,7 +19,7 @@ "agents": "^0.4.0", "ai": "^6.0.78", "hono": "^4.11.9", - "workers-ai-provider": "^3.1.0", + "workers-ai-provider": "^3.0.5", "zod": "^4.3.6" }, "devDependencies": { diff --git a/demos/tool-calling/package.json b/demos/tool-calling/package.json index 0de2032ff..ed79b4713 100644 --- a/demos/tool-calling/package.json +++ b/demos/tool-calling/package.json @@ -20,7 +20,7 @@ "agents": "^0.4.0", "ai": "^6.0.78", "hono": "^4.11.9", - "workers-ai-provider": "^3.1.0", + "workers-ai-provider": "^3.0.5", "zod": "^4.3.6" }, "devDependencies": { diff --git a/demos/vision/package.json b/demos/vision/package.json index 33bc6596e..39433d4c3 100644 --- a/demos/vision/package.json +++ b/demos/vision/package.json @@ -18,7 +18,7 @@ "hono": "^4.11.9", "react": "^19.2.4", "react-dom": "^19.2.4", - "workers-ai-provider": "^3.1.0", + "workers-ai-provider": "^3.0.5", "zod": "^4.3.6" }, "devDependencies": {