workers-ai-provider 3.3.1 → 4.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/README.md +23 -2
  2. package/dist/anthropic.d.mts +5 -1
  3. package/dist/anthropic.mjs +4 -0
  4. package/dist/anthropic.mjs.map +1 -1
  5. package/dist/{gateway-delegate-D_zkIp5r.d.mts → gateway-delegate-DYjgGAa-.d.mts} +9 -6
  6. package/dist/{gateway-provider-CQU-v2IO.mjs → gateway-provider-BQj8ZnKv.mjs} +14 -2
  7. package/dist/{gateway-provider-CQU-v2IO.mjs.map → gateway-provider-BQj8ZnKv.mjs.map} +1 -1
  8. package/dist/gateway-provider.d.mts +12 -0
  9. package/dist/gateway-provider.mjs +1 -1
  10. package/dist/google.d.mts +5 -1
  11. package/dist/google.mjs +6 -2
  12. package/dist/google.mjs.map +1 -1
  13. package/dist/index.d.mts +70 -31
  14. package/dist/index.mjs +113 -41
  15. package/dist/index.mjs.map +1 -1
  16. package/dist/openai.d.mts +8 -3
  17. package/dist/openai.mjs +7 -2
  18. package/dist/openai.mjs.map +1 -1
  19. package/package.json +11 -11
  20. package/src/aisearch-chat-language-model.ts +10 -10
  21. package/src/anthropic.ts +4 -0
  22. package/src/client-fallback.ts +14 -11
  23. package/src/convert-to-workersai-chat-messages.ts +69 -30
  24. package/src/gateway-delegate.ts +12 -12
  25. package/src/gateway-provider.ts +12 -0
  26. package/src/google.ts +6 -4
  27. package/src/index.ts +38 -4
  28. package/src/map-workersai-finish-reason.ts +2 -2
  29. package/src/map-workersai-usage.ts +4 -4
  30. package/src/openai.ts +7 -2
  31. package/src/streaming.ts +18 -18
  32. package/src/utils.ts +8 -8
  33. package/src/workersai-chat-language-model.ts +64 -14
  34. package/src/workersai-embedding-model.ts +6 -6
  35. package/src/workersai-image-model.ts +6 -6
  36. package/src/workersai-reranking-model.ts +9 -9
  37. package/src/workersai-speech-model.ts +7 -7
  38. package/src/workersai-transcription-model.ts +11 -11
package/dist/openai.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { a as ProviderPlugin } from "./gateway-delegate-D_zkIp5r.mjs";
1
+ import { a as ProviderPlugin } from "./gateway-delegate-DYjgGAa-.mjs";
2
2
 
3
3
  //#region src/openai.d.ts
4
4
  /**
@@ -11,8 +11,13 @@ import { a as ProviderPlugin } from "./gateway-delegate-D_zkIp5r.mjs";
11
11
  *
12
12
  * Requires `@ai-sdk/openai` (an optional peer dependency — install it yourself).
13
13
  *
14
- * Uses `.chat()` (Chat Completions) deliberately: AI SDK v6's bare `openai()`
15
- * defaults to the Responses API, which the AI Gateway run catalog does not serve.
14
+ * Uses `.chat()` (Chat Completions) deliberately: the bare `openai()` call
15
+ * (AI SDK v6+) defaults to the Responses API, which the AI Gateway run catalog
16
+ * does not serve.
17
+ *
18
+ * @deprecated Pass the vendor's own model to `createAI` from
19
+ * `agents/models/ai-sdk` instead of a plugin plus a slug:
20
+ * `ai(createOpenAI({ apiKey: "cloudflare" }).chat("gpt-5.4"))`.
16
21
  */
17
22
  declare const openai: ProviderPlugin;
18
23
  //#endregion
package/dist/openai.mjs CHANGED
@@ -10,8 +10,13 @@ import { createOpenAI } from "@ai-sdk/openai";
10
10
  *
11
11
  * Requires `@ai-sdk/openai` (an optional peer dependency — install it yourself).
12
12
  *
13
- * Uses `.chat()` (Chat Completions) deliberately: AI SDK v6's bare `openai()`
14
- * defaults to the Responses API, which the AI Gateway run catalog does not serve.
13
+ * Uses `.chat()` (Chat Completions) deliberately: the bare `openai()` call
14
+ * (AI SDK v6+) defaults to the Responses API, which the AI Gateway run catalog
15
+ * does not serve.
16
+ *
17
+ * @deprecated Pass the vendor's own model to `createAI` from
18
+ * `agents/models/ai-sdk` instead of a plugin plus a slug:
19
+ * `ai(createOpenAI({ apiKey: "cloudflare" }).chat("gpt-5.4"))`.
15
20
  */
16
21
  const openai = {
17
22
  wireFormat: "openai",
@@ -1 +1 @@
1
- {"version":3,"file":"openai.mjs","names":[],"sources":["../src/openai.ts"],"sourcesContent":["import { createOpenAI } from \"@ai-sdk/openai\";\nimport type { ProviderPlugin } from \"./gateway-delegate\";\n\n/**\n * OpenAI-wire provider plugin for the gateway delegate. Pass to\n * `createGatewayDelegate({ providers: [openai] })` to handle every\n * OpenAI-compatible provider in one go — `openai/…`, plus the OpenAI-compatible\n * long tail (`deepseek/…`, `xai/…`, `groq/…`, `mistral/…`, `perplexity/…`,\n * `openrouter/…`, `cohere/…`, …). The registry routes each slug to its gateway\n * provider id; this plugin only supplies the response parser.\n *\n * Requires `@ai-sdk/openai` (an optional peer dependency — install it yourself).\n *\n * Uses `.chat()` (Chat Completions) deliberately: AI SDK v6's bare `openai()`\n * defaults to the Responses API, which the AI Gateway run catalog does not serve.\n */\nexport const openai: ProviderPlugin = {\n\twireFormat: \"openai\",\n\tcreate: ({ modelId, fetch, baseURL }) =>\n\t\t// apiKey is a placeholder — the gateway handles auth (unified billing / BYOK)\n\t\t// and the delegate strips the Authorization header on the gateway path.\n\t\t// baseURL (set by the registry for non-OpenAI openai-wire providers) makes\n\t\t// the generated URL host-strip to the right gateway-native endpoint.\n\t\tcreateOpenAI({ apiKey: \"unused\", fetch, ...(baseURL ? { baseURL } : {}) }).chat(modelId),\n};\n"],"mappings":";;;;;;;;;;;;;;;AAgBA,MAAa,SAAyB;CACrC,YAAY;CACZ,SAAS,EAAE,SAAS,OAAO,cAK1B,aAAa;EAAE,QAAQ;EAAU;EAAO,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC;CAAG,CAAC,CAAC,CAAC,KAAK,OAAO;AACzF"}
1
+ {"version":3,"file":"openai.mjs","names":[],"sources":["../src/openai.ts"],"sourcesContent":["import { createOpenAI } from \"@ai-sdk/openai\";\nimport type { ProviderPlugin } from \"./gateway-delegate\";\n\n/**\n * OpenAI-wire provider plugin for the gateway delegate. Pass to\n * `createGatewayDelegate({ providers: [openai] })` to handle every\n * OpenAI-compatible provider in one go — `openai/…`, plus the OpenAI-compatible\n * long tail (`deepseek/…`, `xai/…`, `groq/…`, `mistral/…`, `perplexity/…`,\n * `openrouter/…`, `cohere/…`, …). The registry routes each slug to its gateway\n * provider id; this plugin only supplies the response parser.\n *\n * Requires `@ai-sdk/openai` (an optional peer dependency — install it yourself).\n *\n * Uses `.chat()` (Chat Completions) deliberately: the bare `openai()` call\n * (AI SDK v6+) defaults to the Responses API, which the AI Gateway run catalog\n * does not serve.\n *\n * @deprecated Pass the vendor's own model to `createAI` from\n * `agents/models/ai-sdk` instead of a plugin plus a slug:\n * `ai(createOpenAI({ apiKey: \"cloudflare\" }).chat(\"gpt-5.4\"))`.\n */\nexport const openai: ProviderPlugin = {\n\twireFormat: \"openai\",\n\tcreate: ({ modelId, fetch, baseURL }) =>\n\t\t// apiKey is a placeholder — the gateway handles auth (unified billing / BYOK)\n\t\t// and the delegate strips the Authorization header on the gateway path.\n\t\t// baseURL (set by the registry for non-OpenAI openai-wire providers) makes\n\t\t// the generated URL host-strip to the right gateway-native endpoint.\n\t\tcreateOpenAI({ apiKey: \"unused\", fetch, ...(baseURL ? { baseURL } : {}) }).chat(modelId),\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAqBA,MAAa,SAAyB;CACrC,YAAY;CACZ,SAAS,EAAE,SAAS,OAAO,cAK1B,aAAa;EAAE,QAAQ;EAAU;EAAO,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC;CAAG,CAAC,CAAC,CAAC,KAAK,OAAO;AACzF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "workers-ai-provider",
3
- "version": "3.3.1",
3
+ "version": "4.0.1",
4
4
  "description": "Workers AI Provider for the vercel AI SDK",
5
5
  "keywords": [
6
6
  "ai",
@@ -53,21 +53,21 @@
53
53
  "./package.json": "./package.json"
54
54
  },
55
55
  "devDependencies": {
56
- "@ai-sdk/anthropic": "^3.0.84",
57
- "@ai-sdk/google": "^3.0.0",
58
- "@ai-sdk/openai": "^3.0.71",
59
- "@ai-sdk/provider": "^3.0.10",
56
+ "@ai-sdk/anthropic": "^4.0.5",
57
+ "@ai-sdk/google": "^4.0.6",
58
+ "@ai-sdk/openai": "^4.0.5",
59
+ "@ai-sdk/provider": "^4.0.1",
60
60
  "@cloudflare/workers-types": "^4.20260628.1",
61
- "ai": "^6.0.204",
61
+ "ai": "^7.0.11",
62
62
  "zod": "^4.4.3",
63
63
  "@cloudflare/gateway-core": "0.0.0"
64
64
  },
65
65
  "peerDependencies": {
66
- "@ai-sdk/anthropic": "^3.0.0",
67
- "@ai-sdk/google": "^3.0.0",
68
- "@ai-sdk/openai": "^3.0.0",
69
- "@ai-sdk/provider": "^3.0.0",
70
- "ai": "^6.0.0"
66
+ "@ai-sdk/anthropic": "^4.0.0",
67
+ "@ai-sdk/google": "^4.0.0",
68
+ "@ai-sdk/openai": "^4.0.0",
69
+ "@ai-sdk/provider": "^4.0.0",
70
+ "ai": "^7.0.0"
71
71
  },
72
72
  "peerDependenciesMeta": {
73
73
  "@ai-sdk/anthropic": {
@@ -1,4 +1,4 @@
1
- import type { LanguageModelV3, SharedV3Warning } from "@ai-sdk/provider";
1
+ import type { LanguageModelV4, SharedV4Warning } from "@ai-sdk/provider";
2
2
 
3
3
  import type { AISearchChatSettings } from "./aisearch-chat-settings";
4
4
  import { convertToWorkersAIChatMessages } from "./convert-to-workersai-chat-messages";
@@ -13,8 +13,8 @@ type AISearchChatConfig = {
13
13
  gateway?: GatewayOptions;
14
14
  };
15
15
 
16
- export class AISearchChatLanguageModel implements LanguageModelV3 {
17
- readonly specificationVersion = "v3";
16
+ export class AISearchChatLanguageModel implements LanguageModelV4 {
17
+ readonly specificationVersion = "v4";
18
18
  readonly defaultObjectGenerationMode = "json";
19
19
 
20
20
  readonly supportedUrls: Record<string, RegExp[]> | PromiseLike<Record<string, RegExp[]>> = {};
@@ -43,8 +43,8 @@ export class AISearchChatLanguageModel implements LanguageModelV3 {
43
43
  frequencyPenalty,
44
44
  presencePenalty,
45
45
  responseFormat,
46
- }: Parameters<LanguageModelV3["doGenerate"]>[0]): SharedV3Warning[] {
47
- const warnings: SharedV3Warning[] = [];
46
+ }: Parameters<LanguageModelV4["doGenerate"]>[0]): SharedV4Warning[] {
47
+ const warnings: SharedV4Warning[] = [];
48
48
 
49
49
  if (tools != null && tools.length > 0) {
50
50
  console.warn(
@@ -72,14 +72,14 @@ export class AISearchChatLanguageModel implements LanguageModelV3 {
72
72
  * Build the search query from messages.
73
73
  * Flattens the conversation into a single string for aiSearch.
74
74
  */
75
- private buildQuery(prompt: Parameters<LanguageModelV3["doGenerate"]>[0]["prompt"]): string {
75
+ private buildQuery(prompt: Parameters<LanguageModelV4["doGenerate"]>[0]["prompt"]): string {
76
76
  const { messages } = convertToWorkersAIChatMessages(prompt);
77
77
  return messages.map(({ content, role }) => `${role}: ${content}`).join("\n\n");
78
78
  }
79
79
 
80
80
  async doGenerate(
81
- options: Parameters<LanguageModelV3["doGenerate"]>[0],
82
- ): Promise<Awaited<ReturnType<LanguageModelV3["doGenerate"]>>> {
81
+ options: Parameters<LanguageModelV4["doGenerate"]>[0],
82
+ ): Promise<Awaited<ReturnType<LanguageModelV4["doGenerate"]>>> {
83
83
  const warnings = this.getWarnings(options);
84
84
  const query = this.buildQuery(options.prompt);
85
85
 
@@ -109,8 +109,8 @@ export class AISearchChatLanguageModel implements LanguageModelV3 {
109
109
  }
110
110
 
111
111
  async doStream(
112
- options: Parameters<LanguageModelV3["doStream"]>[0],
113
- ): Promise<Awaited<ReturnType<LanguageModelV3["doStream"]>>> {
112
+ options: Parameters<LanguageModelV4["doStream"]>[0],
113
+ ): Promise<Awaited<ReturnType<LanguageModelV4["doStream"]>>> {
114
114
  const warnings = this.getWarnings(options);
115
115
  const query = this.buildQuery(options.prompt);
116
116
 
package/src/anthropic.ts CHANGED
@@ -7,6 +7,10 @@ import type { ProviderPlugin } from "./gateway-delegate";
7
7
  * `"anthropic/<model>"` slugs.
8
8
  *
9
9
  * Requires `@ai-sdk/anthropic` (an optional peer dependency — install it yourself).
10
+ *
11
+ * @deprecated Pass the vendor's own model to `createAI` from
12
+ * `agents/models/ai-sdk` instead of a plugin plus a slug:
13
+ * `ai(createAnthropic({ apiKey: "cloudflare" })("claude-opus-4-8"))`.
10
14
  */
11
15
  export const anthropic: ProviderPlugin = {
12
16
  wireFormat: "anthropic",
@@ -1,8 +1,8 @@
1
1
  import type {
2
- LanguageModelV3,
3
- LanguageModelV3CallOptions,
4
- LanguageModelV3GenerateResult,
5
- LanguageModelV3StreamResult,
2
+ LanguageModelV4,
3
+ LanguageModelV4CallOptions,
4
+ LanguageModelV4GenerateResult,
5
+ LanguageModelV4StreamResult,
6
6
  } from "@ai-sdk/provider";
7
7
  import { type FallbackAttempt, WorkersAIFallbackError, WorkersAIGatewayError } from "./errors";
8
8
  import type { Transport } from "./gateway-delegate";
@@ -12,7 +12,7 @@ export interface FallbackLeg {
12
12
  /** The model slug this leg dispatches. */
13
13
  slug: string;
14
14
  /** The built AI SDK model. */
15
- model: LanguageModelV3;
15
+ model: LanguageModelV4;
16
16
  /** Transport the leg uses. */
17
17
  transport: Transport;
18
18
  }
@@ -25,14 +25,17 @@ export interface FallbackLeg {
25
25
  * Fallback triggers on `doGenerate`/`doStream` rejection (the dispatch never
26
26
  * produced a stream). Errors that surface *mid-stream* — after content has
27
27
  * already been emitted — are not recoverable here and propagate as-is.
28
+ *
29
+ * @deprecated Use the `fallback` option of `createAI` from
30
+ * `agents/models/ai-sdk`: `ai(primary, { fallback: [secondary, "@cf/…"] })`.
28
31
  */
29
- export function createClientFallbackModel(legs: FallbackLeg[]): LanguageModelV3 {
32
+ export function createClientFallbackModel(legs: FallbackLeg[]): LanguageModelV4 {
30
33
  if (legs.length === 0) {
31
34
  throw new Error("createClientFallbackModel requires at least one model leg.");
32
35
  }
33
36
  const primary = legs[0].model;
34
37
 
35
- async function attempt<T>(run: (model: LanguageModelV3) => PromiseLike<T>): Promise<T> {
38
+ async function attempt<T>(run: (model: LanguageModelV4) => PromiseLike<T>): Promise<T> {
36
39
  const attempts: FallbackAttempt[] = [];
37
40
  for (const leg of legs) {
38
41
  try {
@@ -54,16 +57,16 @@ export function createClientFallbackModel(legs: FallbackLeg[]): LanguageModelV3
54
57
  }
55
58
 
56
59
  return {
57
- specificationVersion: "v3",
60
+ specificationVersion: "v4",
58
61
  provider: primary.provider,
59
62
  modelId: primary.modelId,
60
63
  supportedUrls: primary.supportedUrls,
61
64
  doGenerate(
62
- options: LanguageModelV3CallOptions,
63
- ): PromiseLike<LanguageModelV3GenerateResult> {
65
+ options: LanguageModelV4CallOptions,
66
+ ): PromiseLike<LanguageModelV4GenerateResult> {
64
67
  return attempt((m) => m.doGenerate(options));
65
68
  },
66
- doStream(options: LanguageModelV3CallOptions): PromiseLike<LanguageModelV3StreamResult> {
69
+ doStream(options: LanguageModelV4CallOptions): PromiseLike<LanguageModelV4StreamResult> {
67
70
  return attempt((m) => m.doStream(options));
68
71
  },
69
72
  };
@@ -1,45 +1,72 @@
1
- import type { LanguageModelV3DataContent, LanguageModelV3Prompt } from "@ai-sdk/provider";
1
+ import type { LanguageModelV4Prompt, SharedV4FileData } from "@ai-sdk/provider";
2
2
  import { UnsupportedFunctionalityError } from "@ai-sdk/provider";
3
3
  import { toWorkersAIToolCallId } from "./utils";
4
4
  import type { WorkersAIContentPart, WorkersAIChatPrompt } from "./workersai-chat-prompt";
5
5
 
6
6
  /**
7
- * Normalise any LanguageModelV3DataContent value to a Uint8Array.
7
+ * Normalise a tagged `SharedV4FileData` value to a Uint8Array.
8
8
  *
9
9
  * Handles:
10
- * - Uint8Array → returned as-is
11
- * - string → decoded from base64 (with or without data-URL prefix)
12
- * - URL → not supported (Workers AI needs raw bytes, not a reference)
10
+ * - { type: 'data' } → Uint8Array returned as-is; string decoded from
11
+ * base64 (with or without data-URL prefix)
12
+ * - { type: 'url' } → not supported (Workers AI needs raw bytes, not a reference)
13
+ * - { type: 'reference' } → not supported (Workers AI has no file store to resolve it)
14
+ * - { type: 'text' } → not supported for image parts
13
15
  */
14
- function toUint8Array(data: LanguageModelV3DataContent): Uint8Array | null {
15
- if (data instanceof Uint8Array) {
16
- return data;
17
- }
18
-
19
- if (typeof data === "string") {
20
- let base64 = data;
21
- if (base64.startsWith("data:")) {
22
- const commaIndex = base64.indexOf(",");
23
- if (commaIndex >= 0) {
24
- base64 = base64.slice(commaIndex + 1);
16
+ function toUint8Array(fileData: SharedV4FileData): Uint8Array | null {
17
+ switch (fileData.type) {
18
+ case "data": {
19
+ const data = fileData.data;
20
+ if (data instanceof Uint8Array) {
21
+ return data;
22
+ }
23
+ let base64 = data;
24
+ if (base64.startsWith("data:")) {
25
+ const commaIndex = base64.indexOf(",");
26
+ if (commaIndex >= 0) {
27
+ base64 = base64.slice(commaIndex + 1);
28
+ }
29
+ }
30
+ const binaryString = atob(base64);
31
+ const bytes = new Uint8Array(binaryString.length);
32
+ for (let i = 0; i < binaryString.length; i++) {
33
+ bytes[i] = binaryString.charCodeAt(i);
25
34
  }
35
+ return bytes;
26
36
  }
27
- const binaryString = atob(base64);
28
- const bytes = new Uint8Array(binaryString.length);
29
- for (let i = 0; i < binaryString.length; i++) {
30
- bytes[i] = binaryString.charCodeAt(i);
37
+
38
+ case "url": {
39
+ throw new Error(
40
+ "URL image sources are not supported by Workers AI. " +
41
+ "Provide image data as a Uint8Array or base64 string instead.",
42
+ );
31
43
  }
32
- return bytes;
33
- }
34
44
 
35
- if (data instanceof URL) {
36
- throw new Error(
37
- "URL image sources are not supported by Workers AI. " +
38
- "Provide image data as a Uint8Array or base64 string instead.",
39
- );
40
- }
45
+ case "reference": {
46
+ throw new UnsupportedFunctionalityError({
47
+ functionality: "file-part-provider-reference",
48
+ message:
49
+ "Provider file references are not supported by Workers AI. " +
50
+ "Provide image data as a Uint8Array or base64 string instead.",
51
+ });
52
+ }
41
53
 
42
- return null;
54
+ case "text": {
55
+ throw new UnsupportedFunctionalityError({
56
+ functionality: "file-part-inline-text",
57
+ message:
58
+ "Inline text file parts are not supported by Workers AI chat. " +
59
+ "Pass text as a regular text part instead.",
60
+ });
61
+ }
62
+
63
+ default: {
64
+ const exhaustiveCheck = fileData satisfies never;
65
+ throw new Error(
66
+ `Unsupported file data type: ${(exhaustiveCheck as { type: string }).type}`,
67
+ );
68
+ }
69
+ }
43
70
  }
44
71
 
45
72
  function assertImageMediaType(mediaType: string | undefined): string {
@@ -76,7 +103,7 @@ function uint8ArrayToBase64(bytes: Uint8Array): string {
76
103
  return btoa(binary);
77
104
  }
78
105
 
79
- export function convertToWorkersAIChatMessages(prompt: LanguageModelV3Prompt): {
106
+ export function convertToWorkersAIChatMessages(prompt: LanguageModelV4Prompt): {
80
107
  messages: WorkersAIChatPrompt;
81
108
  } {
82
109
  const messages: WorkersAIChatPrompt = [];
@@ -164,6 +191,18 @@ export function convertToWorkersAIChatMessages(prompt: LanguageModelV3Prompt): {
164
191
  break;
165
192
  }
166
193
 
194
+ case "reasoning-file": {
195
+ // Files inside reasoning traces (new in spec v4) cannot be
196
+ // replayed to Workers AI - no action needed
197
+ break;
198
+ }
199
+
200
+ case "custom": {
201
+ // Provider-specific custom parts (new in spec v4) from other
202
+ // providers are not replayable to Workers AI - no action needed
203
+ break;
204
+ }
205
+
167
206
  case "tool-call": {
168
207
  toolCalls.push({
169
208
  function: {
@@ -1,4 +1,4 @@
1
- import type { LanguageModelV3, LanguageModelV3CallOptions } from "@ai-sdk/provider";
1
+ import type { LanguageModelV4, LanguageModelV4CallOptions } from "@ai-sdk/provider";
2
2
  import {
3
3
  asText,
4
4
  buildGatewayEntry,
@@ -154,7 +154,7 @@ export interface ProviderPlugin {
154
154
  modelId: string;
155
155
  fetch: typeof globalThis.fetch;
156
156
  baseURL?: string;
157
- }): LanguageModelV3;
157
+ }): LanguageModelV4;
158
158
  }
159
159
 
160
160
  // ---------------------------------------------------------------------------
@@ -401,7 +401,7 @@ export interface GatewayDelegateConfig {
401
401
  }
402
402
 
403
403
  export interface GatewayDelegate {
404
- (slug: string, options?: DelegateCallOptions): LanguageModelV3;
404
+ (slug: string, options?: DelegateCallOptions): LanguageModelV4;
405
405
  }
406
406
 
407
407
  /**
@@ -431,7 +431,7 @@ export function createGatewayDelegate(config: GatewayDelegateConfig): GatewayDel
431
431
  const buildOne = (
432
432
  slug: string,
433
433
  options: DelegateCallOptions,
434
- ): { model: LanguageModelV3; transport: Transport } => {
434
+ ): { model: LanguageModelV4; transport: Transport } => {
435
435
  const parsed = parseSlug(slug);
436
436
  const info = resolveProvider(slug, parsed);
437
437
 
@@ -816,7 +816,7 @@ function makeServerFallbackModel(params: {
816
816
  opts: DelegateCallOptions;
817
817
  selection: Selection;
818
818
  callOptions: DelegateCallOptions;
819
- }): LanguageModelV3 {
819
+ }): LanguageModelV4 {
820
820
  const { binding, gatewayId, gatewayOptions, legs, opts, selection, callOptions } = params;
821
821
  const first = legs[0]!;
822
822
 
@@ -834,7 +834,7 @@ function makeServerFallbackModel(params: {
834
834
 
835
835
  const dispatch = async (
836
836
  method: "doGenerate" | "doStream",
837
- options: LanguageModelV3CallOptions,
837
+ options: LanguageModelV4CallOptions,
838
838
  ): Promise<unknown> => {
839
839
  // 1) Capture each leg's native request without hitting the network.
840
840
  const entries: GatewayEntry[] = [];
@@ -854,7 +854,7 @@ function makeServerFallbackModel(params: {
854
854
  ...(leg.info.baseURL ? { baseURL: leg.info.baseURL } : {}),
855
855
  });
856
856
  try {
857
- await (model[method] as (o: LanguageModelV3CallOptions) => Promise<unknown>)(
857
+ await (model[method] as (o: LanguageModelV4CallOptions) => Promise<unknown>)(
858
858
  options,
859
859
  );
860
860
  } catch (e) {
@@ -905,21 +905,21 @@ function makeServerFallbackModel(params: {
905
905
  fetch: (async () => resp) as typeof globalThis.fetch,
906
906
  ...(winner.info.baseURL ? { baseURL: winner.info.baseURL } : {}),
907
907
  });
908
- return (winnerModel[method] as (o: LanguageModelV3CallOptions) => Promise<unknown>)(
908
+ return (winnerModel[method] as (o: LanguageModelV4CallOptions) => Promise<unknown>)(
909
909
  options,
910
910
  );
911
911
  };
912
912
 
913
913
  return {
914
- specificationVersion: "v3",
914
+ specificationVersion: "v4",
915
915
  provider: refModel.provider,
916
916
  modelId: refModel.modelId,
917
917
  supportedUrls: refModel.supportedUrls,
918
918
  doGenerate(options) {
919
- return dispatch("doGenerate", options) as ReturnType<LanguageModelV3["doGenerate"]>;
919
+ return dispatch("doGenerate", options) as ReturnType<LanguageModelV4["doGenerate"]>;
920
920
  },
921
921
  doStream(options) {
922
- return dispatch("doStream", options) as ReturnType<LanguageModelV3["doStream"]>;
922
+ return dispatch("doStream", options) as ReturnType<LanguageModelV4["doStream"]>;
923
923
  },
924
- } as LanguageModelV3;
924
+ } as LanguageModelV4;
925
925
  }
@@ -56,6 +56,12 @@ interface AiGatewayRunner {
56
56
  * A `fetch` that dispatches the wrapped provider's request through AI Gateway.
57
57
  * Detects the gateway provider id from the request URL (or uses `config.provider`),
58
58
  * strips the provider host to the endpoint path, and forwards the body verbatim.
59
+ *
60
+ * @deprecated Route the vendor's model with `createAI` from
61
+ * `agents/models/ai-sdk`: `ai(model)` for language models, `ai.routed(model)`
62
+ * for embedding, image, speech and transcription models, on AI Gateway's
63
+ * provider-native path. `vendorKey: "request"` forwards the vendor key, as
64
+ * `byok: true` does here.
59
65
  */
60
66
  export function createGatewayFetch(config: GatewayFetchConfig): typeof globalThis.fetch {
61
67
  if (!config?.binding) {
@@ -130,6 +136,12 @@ export function createGatewayFetch(config: GatewayFetchConfig): typeof globalThi
130
136
  * });
131
137
  * const model = openai("gpt-5");
132
138
  * ```
139
+ *
140
+ * @deprecated Route the vendor's model with `createAI` from
141
+ * `agents/models/ai-sdk`: `ai(model)` for language models, `ai.routed(model)`
142
+ * for embedding, image, speech and transcription models, on AI Gateway's
143
+ * provider-native path. `vendorKey: "request"` forwards the vendor key, as
144
+ * `byok: true` does here.
133
145
  */
134
146
  export function createGatewayProvider<T>(
135
147
  factory: (opts: { apiKey?: string; baseURL?: string; fetch: typeof globalThis.fetch }) => T,
package/src/google.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { createGoogleGenerativeAI } from "@ai-sdk/google";
1
+ import { createGoogle } from "@ai-sdk/google";
2
2
  import type { ProviderPlugin } from "./gateway-delegate";
3
3
 
4
4
  /**
@@ -7,13 +7,15 @@ import type { ProviderPlugin } from "./gateway-delegate";
7
7
  * (Google AI Studio) and `"google-vertex/<model>"` slugs.
8
8
  *
9
9
  * Requires `@ai-sdk/google` (an optional peer dependency — install it yourself).
10
+ *
11
+ * @deprecated Pass the vendor's own model to `createAI` from
12
+ * `agents/models/ai-sdk` instead of a plugin plus a slug:
13
+ * `ai(createGoogle({ apiKey: "cloudflare" })("gemini-2.5-flash"))`.
10
14
  */
11
15
  export const google: ProviderPlugin = {
12
16
  wireFormat: "google",
13
17
  create: ({ modelId, fetch, baseURL }) =>
14
18
  // apiKey is a placeholder — the gateway handles auth (unified billing / BYOK)
15
19
  // and the delegate strips the x-goog-api-key header on the gateway path.
16
- createGoogleGenerativeAI({ apiKey: "unused", fetch, ...(baseURL ? { baseURL } : {}) })(
17
- modelId,
18
- ),
20
+ createGoogle({ apiKey: "unused", fetch, ...(baseURL ? { baseURL } : {}) })(modelId),
19
21
  };
package/src/index.ts CHANGED
@@ -276,6 +276,23 @@ export interface WorkersAI {
276
276
 
277
277
  /**
278
278
  * Create a Workers AI provider instance.
279
+ *
280
+ * @deprecated Use `createAI` from `agents/models/ai-sdk`, with the binding or
281
+ * with an account id and API token (credentials mode's `apiKey`):
282
+ *
283
+ * ```ts
284
+ * import { createAI } from "agents/models/ai-sdk";
285
+ * const ai = createAI({ binding: env.AI }); // or { accountId, apiToken }
286
+ * ai("@cf/zai-org/glm-4.7-flash"); // was workersai("@cf/…")
287
+ * ai("anthropic/claude-opus-4.8"); // was "anthropic/…" + providers; the catalog's spelling
288
+ * ai("dynamic/support"); // dynamic routes, as before
289
+ * ai(createAnthropic({ apiKey: "cloudflare" })("claude-opus-4-8")); // a vendor's own model
290
+ * ai.embedding("@cf/baai/bge-base-en-v1.5"); // .image/.speech/.transcription/.reranking alike
291
+ * ```
292
+ *
293
+ * `vendorKey`, `byokAlias` and `zdr` cover BYOK, and through the binding a
294
+ * catalog stream resumes after a dropped connection. For AI Search, use
295
+ * `ai-search-provider`.
279
296
  */
280
297
  export function createWorkersAI(options: WorkersAISettings): WorkersAI {
281
298
  if (!options.binding && !("accountId" in options && "apiKey" in options)) {
@@ -508,7 +525,7 @@ export function createWorkersAI(options: WorkersAISettings): WorkersAI {
508
525
  "catalog",
509
526
  );
510
527
  }
511
- // The delegate returns a `LanguageModelV3` built by the configured plugin.
528
+ // The delegate returns a `LanguageModelV4` built by the configured plugin.
512
529
  // It's structurally compatible with the AI SDK consumers this provider is
513
530
  // used with; the cast keeps the public return type unchanged.
514
531
  return getDelegate(modelId)(
@@ -600,10 +617,22 @@ export function createWorkersAI(options: WorkersAISettings): WorkersAI {
600
617
  // AI Search (formerly AutoRAG)
601
618
  // ---------------------------------------------------------------------------
602
619
 
620
+ /**
621
+ * @deprecated Use `createAISearchNamespace` from `ai-search-provider`, over the
622
+ * `ai_search_namespaces` binding that replaces `env.AI.autorag()`:
623
+ * `createAISearchNamespace({ binding: env.AI_SEARCH }).get("my-instance").chat()`.
624
+ * @see https://developers.cloudflare.com/ai-search/api/migration/workers-binding/
625
+ */
603
626
  export type AISearchSettings = {
604
627
  binding: AutoRAG;
605
628
  };
606
629
 
630
+ /**
631
+ * @deprecated Use `createAISearchNamespace` from `ai-search-provider`, over the
632
+ * `ai_search_namespaces` binding that replaces `env.AI.autorag()`:
633
+ * `createAISearchNamespace({ binding: env.AI_SEARCH }).get("my-instance").chat()`.
634
+ * @see https://developers.cloudflare.com/ai-search/api/migration/workers-binding/
635
+ */
607
636
  export interface AISearchProvider {
608
637
  (settings?: AISearchChatSettings): AISearchChatLanguageModel;
609
638
  /**
@@ -616,7 +645,11 @@ export interface AISearchProvider {
616
645
  * Create an AI Search provider instance.
617
646
  *
618
647
  * AI Search (formerly AutoRAG) is Cloudflare's managed search service.
619
- * @see https://developers.cloudflare.com/ai-search/
648
+ *
649
+ * @deprecated Use `createAISearchNamespace` from `ai-search-provider`, over the
650
+ * `ai_search_namespaces` binding that replaces `env.AI.autorag()`:
651
+ * `createAISearchNamespace({ binding: env.AI_SEARCH }).get("my-instance").chat()`.
652
+ * @see https://developers.cloudflare.com/ai-search/api/migration/workers-binding/
620
653
  */
621
654
  export function createAISearch(
622
655
  options: AISearchSettings,
@@ -662,8 +695,9 @@ export type AutoRAGProvider = AISearchProvider;
662
695
  let autoRAGWarned = false;
663
696
 
664
697
  /**
665
- * @deprecated Use `createAISearch` instead. AutoRAG has been renamed to AI Search.
666
- * @see https://developers.cloudflare.com/ai-search/
698
+ * @deprecated Use `createAISearchNamespace` from `ai-search-provider`. AutoRAG
699
+ * has been renamed to AI Search.
700
+ * @see https://developers.cloudflare.com/ai-search/api/migration/workers-binding/
667
701
  */
668
702
  export function createAutoRAG(options: AISearchSettings): AISearchProvider {
669
703
  if (!autoRAGWarned) {
@@ -1,4 +1,4 @@
1
- import type { LanguageModelV3FinishReason } from "@ai-sdk/provider";
1
+ import type { LanguageModelV4FinishReason } from "@ai-sdk/provider";
2
2
 
3
3
  /**
4
4
  * Map a Workers AI finish reason to the AI SDK unified finish reason.
@@ -9,7 +9,7 @@ import type { LanguageModelV3FinishReason } from "@ai-sdk/provider";
9
9
  */
10
10
  export function mapWorkersAIFinishReason(
11
11
  finishReasonOrResponse: string | null | undefined | Record<string, unknown>,
12
- ): LanguageModelV3FinishReason {
12
+ ): LanguageModelV4FinishReason {
13
13
  let finishReason: string | null | undefined;
14
14
 
15
15
  if (
@@ -1,7 +1,7 @@
1
- import type { LanguageModelV3Usage } from "@ai-sdk/provider";
1
+ import type { LanguageModelV4Usage } from "@ai-sdk/provider";
2
2
 
3
3
  /**
4
- * Map Workers AI usage data to the AI SDK V3 usage format.
4
+ * Map Workers AI usage data to the AI SDK v4 usage format.
5
5
  * Accepts any object that may have a `usage` property with token counts.
6
6
  *
7
7
  * Workers AI mirrors the OpenAI usage shape, including
@@ -11,7 +11,7 @@ import type { LanguageModelV3Usage } from "@ai-sdk/provider";
11
11
  */
12
12
  export function mapWorkersAIUsage(
13
13
  output: Record<string, unknown> | AiTextGenerationOutput | AiTextToImageOutput,
14
- ): LanguageModelV3Usage {
14
+ ): LanguageModelV4Usage {
15
15
  const usage = (
16
16
  output as {
17
17
  usage?: {
@@ -30,7 +30,7 @@ export function mapWorkersAIUsage(
30
30
  const cachedTokens = usage.prompt_tokens_details?.cached_tokens;
31
31
 
32
32
  // Clamp at 0 in case the provider ever reports cached_tokens > prompt_tokens;
33
- // the v3 spec expects non-negative counts.
33
+ // the v4 spec expects non-negative counts.
34
34
  const noCache =
35
35
  cachedTokens !== undefined ? Math.max(0, promptTokens - cachedTokens) : undefined;
36
36
 
package/src/openai.ts CHANGED
@@ -11,8 +11,13 @@ import type { ProviderPlugin } from "./gateway-delegate";
11
11
  *
12
12
  * Requires `@ai-sdk/openai` (an optional peer dependency — install it yourself).
13
13
  *
14
- * Uses `.chat()` (Chat Completions) deliberately: AI SDK v6's bare `openai()`
15
- * defaults to the Responses API, which the AI Gateway run catalog does not serve.
14
+ * Uses `.chat()` (Chat Completions) deliberately: the bare `openai()` call
15
+ * (AI SDK v6+) defaults to the Responses API, which the AI Gateway run catalog
16
+ * does not serve.
17
+ *
18
+ * @deprecated Pass the vendor's own model to `createAI` from
19
+ * `agents/models/ai-sdk` instead of a plugin plus a slug:
20
+ * `ai(createOpenAI({ apiKey: "cloudflare" }).chat("gpt-5.4"))`.
16
21
  */
17
22
  export const openai: ProviderPlugin = {
18
23
  wireFormat: "openai",