{"version":3,"file":"index.mjs","names":["coreNormalizeMessagesForBinding","exhaustiveCheck","coreParseLeakedToolCalls","toUint8Array","uint8ArrayToBase64","exhaustiveCheck","exhaustiveCheck","toUint8Array","ai"],"sources":["../src/workersai-error.ts","../src/utils.ts","../src/convert-to-workersai-chat-messages.ts","../src/map-workersai-usage.ts","../src/map-workersai-finish-reason.ts","../src/streaming.ts","../src/aisearch-chat-language-model.ts","../src/workersai-embedding-model.ts","../src/workersai-chat-language-model.ts","../src/workersai-image-model.ts","../src/workersai-transcription-model.ts","../src/workersai-speech-model.ts","../src/workersai-reranking-model.ts","../src/autorag-chat-language-model.ts","../src/client-fallback.ts","../src/gateway-delegate.ts","../src/index.ts"],"sourcesContent":["import { APICallError } from \"@ai-sdk/provider\";\nimport {\n\theadersToObject,\n\tisAbortError,\n\tmessageOf,\n\tparseWorkersAIErrorCode,\n\tWORKERS_AI_ERROR_CODE_TO_STATUS,\n} from \"@cloudflare/gateway-core\";\n\n// Re-exported from `@cloudflare/gateway-core` (single source of truth, shared\n// with `@cloudflare/tanstack-ai`) so existing importers of this module keep\n// working unchanged.\nexport { parseWorkersAIErrorCode, WORKERS_AI_ERROR_CODE_TO_STATUS };\n\n/**\n * Normalize an error thrown by the Workers AI **binding** (`env.AI.run`) into an\n * `APICallError` so the AI SDK can classify and retry it.\n *\n * Cancellations (`AbortError` / `TimeoutError` / `ResponseAborted`, including\n * `DOMException` aborts) and errors that are already an `APICallError` pass\n * through unchanged. Everything else becomes an\n * `APICallError`; when the internal code maps to a known HTTP status, that\n * `statusCode` is attached and `APICallError` derives `isRetryable` from it.\n * Unrecognized errors get no `statusCode`, so they stay non-retryable (the\n * prior behavior).\n */\nexport function normalizeBindingError(\n\terror: unknown,\n\tcontext: { model: string; requestBodyValues: unknown },\n): unknown {\n\tif (APICallError.isInstance(error) || isAbortError(error)) {\n\t\treturn error;\n\t}\n\n\tconst code = parseWorkersAIErrorCode(error);\n\tconst statusCode = code != null ? WORKERS_AI_ERROR_CODE_TO_STATUS[code] : undefined;\n\tconst message = messageOf(error);\n\n\treturn new APICallError({\n\t\tmessage,\n\t\turl: `workers-ai:binding/run/${context.model}`,\n\t\trequestBodyValues: context.requestBodyValues,\n\t\tstatusCode,\n\t\tresponseBody: message,\n\t\tcause: error,\n\t\t...(code != null ? { data: { workersAIErrorCode: code } } : {}),\n\t});\n}\n\n/**\n * Build an `APICallError` from a non-OK Workers AI **REST** response. The HTTP\n * status is authoritative here, so `APICallError` derives `isRetryable` from it\n * directly (429 / 5xx → retryable). Response headers are preserved so the AI\n * SDK can honor `Retry-After`. The message keeps the historical\n * `\"Workers AI API error (<status> <statusText>): <body>\"` shape.\n */\nexport function apiCallErrorFromResponse(\n\tresponse: Response,\n\terrorBody: string,\n\tcontext: { url: string; requestBodyValues: unknown },\n): APICallError {\n\treturn new APICallError({\n\t\tmessage: `Workers AI API error (${response.status} ${response.statusText}): ${errorBody}`,\n\t\turl: context.url,\n\t\trequestBodyValues: context.requestBodyValues,\n\t\tstatusCode: response.status,\n\t\tresponseHeaders: headersToObject(response.headers),\n\t\tresponseBody: errorBody,\n\t});\n}\n","import type { LanguageModelV3, LanguageModelV3ToolCall } from \"@ai-sdk/provider\";\nimport {\n\tgetToolNames,\n\tisForcedToolChoice,\n\tnormalizeMessagesForBinding as coreNormalizeMessagesForBinding,\n\tparseLeakedToolCalls as coreParseLeakedToolCalls,\n\tprocessText,\n} from \"@cloudflare/gateway-core\";\nimport { generateId } from \"ai\";\nimport type { WorkersAIChatPrompt } from \"./workersai-chat-prompt\";\nimport { apiCallErrorFromResponse } from \"./workersai-error\";\n\n// Re-exported from `@cloudflare/gateway-core` (single source of truth) so the\n// existing `workers-ai-provider/src/utils` import paths keep working unchanged.\nexport { getToolNames, isForcedToolChoice, processText } from \"@cloudflare/gateway-core\";\n\n// ---------------------------------------------------------------------------\n// Workers AI quirk workarounds\n// ---------------------------------------------------------------------------\n\n/**\n * Normalize messages before passing to the Workers AI binding.\n *\n * The binding has strict schema validation that differs from the OpenAI API:\n * - `content` must not be null\n */\nexport function normalizeMessagesForBinding(messages: WorkersAIChatPrompt): WorkersAIChatPrompt {\n\treturn coreNormalizeMessagesForBinding(\n\t\tmessages as unknown as Record<string, unknown>[],\n\t) as unknown as WorkersAIChatPrompt;\n}\n\n// ---------------------------------------------------------------------------\n// REST API client\n// ---------------------------------------------------------------------------\n\n/**\n * General AI run interface with overloads to handle distinct return types.\n */\nexport interface AiRun {\n\t<Name extends keyof AiModels>(\n\t\tmodel: Name,\n\t\tinputs: AiModels[Name][\"inputs\"],\n\t\toptions: AiOptions & { returnRawResponse: true },\n\t): Promise<Response>;\n\n\t<Name extends keyof AiModels>(\n\t\tmodel: Name,\n\t\tinputs: AiModels[Name][\"inputs\"] & { stream: true },\n\t\toptions?: AiOptions,\n\t): Promise<ReadableStream<Uint8Array>>;\n\n\t<Name extends keyof AiModels>(\n\t\tmodel: Name,\n\t\tinputs: AiModels[Name][\"inputs\"],\n\t\toptions?: AiOptions,\n\t): Promise<AiModels[Name][\"postProcessedOutputs\"]>;\n}\n\n/**\n * Parameters for configuring the Cloudflare-based AI runner.\n */\nexport interface CreateRunConfig {\n\t/** Your Cloudflare account identifier. */\n\taccountId: string;\n\t/** Cloudflare API token/key with appropriate permissions. */\n\tapiKey: string;\n\t/** Custom fetch implementation for intercepting requests. */\n\tfetch?: typeof globalThis.fetch;\n}\n\n/**\n * Creates a run method that emulates the Cloudflare Workers AI binding,\n * but uses the Cloudflare REST API under the hood.\n */\nexport function createRun(config: CreateRunConfig): AiRun {\n\tconst { accountId, apiKey } = config;\n\tconst fetchFn = config.fetch ?? globalThis.fetch;\n\n\treturn async function run<Name extends keyof AiModels>(\n\t\tmodel: Name,\n\t\tinputs: AiModels[Name][\"inputs\"],\n\t\toptions?: AiOptions & Record<string, unknown>,\n\t): Promise<Response | ReadableStream<Uint8Array> | AiModels[Name][\"postProcessedOutputs\"]> {\n\t\tconst {\n\t\t\tgateway,\n\t\t\tprefix: _prefix,\n\t\t\textraHeaders,\n\t\t\treturnRawResponse,\n\t\t\tsignal, // AbortSignal — not serializable as a query parameter\n\t\t\t...passthroughOptions\n\t\t} = options || {};\n\n\t\tconst urlParams = new URLSearchParams();\n\t\tfor (const [key, value] of Object.entries(passthroughOptions)) {\n\t\t\tif (value === undefined || value === null) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Value for option '${key}' is not able to be coerced into a string.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tconst valueStr = String(value);\n\t\t\t\tif (!valueStr) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\turlParams.append(key, valueStr);\n\t\t\t} catch {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`Value for option '${key}' is not able to be coerced into a string.`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tconst queryString = urlParams.toString();\n\n\t\tconst modelPath = String(model).startsWith(\"run/\") ? model : `run/${model}`;\n\n\t\t// Build URL: use AI Gateway if gateway option is provided, otherwise direct API\n\t\tconst url = gateway?.id\n\t\t\t? `https://gateway.ai.cloudflare.com/v1/${accountId}/${gateway.id}/workers-ai/${modelPath}${\n\t\t\t\t\tqueryString ? `?${queryString}` : \"\"\n\t\t\t\t}`\n\t\t\t: `https://api.cloudflare.com/client/v4/accounts/${accountId}/ai/${modelPath}${\n\t\t\t\t\tqueryString ? `?${queryString}` : \"\"\n\t\t\t\t}`;\n\n\t\tconst headers: Record<string, string> = {\n\t\t\tAuthorization: `Bearer ${apiKey}`,\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t...(extraHeaders && typeof extraHeaders === \"object\"\n\t\t\t\t? (extraHeaders as Record<string, string>)\n\t\t\t\t: {}),\n\t\t};\n\n\t\tif (gateway) {\n\t\t\tif (gateway.skipCache) {\n\t\t\t\theaders[\"cf-aig-skip-cache\"] = \"true\";\n\t\t\t}\n\t\t\tif (typeof gateway.cacheTtl === \"number\") {\n\t\t\t\theaders[\"cf-aig-cache-ttl\"] = String(gateway.cacheTtl);\n\t\t\t}\n\t\t\tif (gateway.cacheKey) {\n\t\t\t\theaders[\"cf-aig-cache-key\"] = gateway.cacheKey;\n\t\t\t}\n\t\t\tif (gateway.metadata) {\n\t\t\t\theaders[\"cf-aig-metadata\"] = JSON.stringify(gateway.metadata);\n\t\t\t}\n\t\t}\n\n\t\tconst body = JSON.stringify(inputs);\n\n\t\tconst response = await fetchFn(url, {\n\t\t\tbody,\n\t\t\theaders,\n\t\t\tmethod: \"POST\",\n\t\t\tsignal: signal as AbortSignal | undefined,\n\t\t});\n\n\t\t// Check for HTTP errors before processing. Surface as an APICallError so\n\t\t// the AI SDK can classify retryability from the status (429 / 5xx → retry)\n\t\t// and honor any Retry-After header.\n\t\tif (!response.ok && !returnRawResponse) {\n\t\t\tlet errorBody: string;\n\t\t\ttry {\n\t\t\t\terrorBody = await response.text();\n\t\t\t} catch {\n\t\t\t\terrorBody = \"<unable to read response body>\";\n\t\t\t}\n\t\t\tthrow apiCallErrorFromResponse(response, errorBody, {\n\t\t\t\turl,\n\t\t\t\trequestBodyValues: inputs,\n\t\t\t});\n\t\t}\n\n\t\tif (returnRawResponse) {\n\t\t\treturn response;\n\t\t}\n\n\t\tif ((inputs as AiTextGenerationInput).stream === true) {\n\t\t\tconst contentType = response.headers.get(\"content-type\") || \"\";\n\t\t\tif (contentType.includes(\"event-stream\") && response.body) {\n\t\t\t\treturn response.body;\n\t\t\t}\n\t\t\tif (response.body && !contentType.includes(\"json\")) {\n\t\t\t\t// Unknown content type — assume it's a stream\n\t\t\t\treturn response.body;\n\t\t\t}\n\n\t\t\t// Some models (e.g. GPT-OSS) don't support streaming via the /ai/run/\n\t\t\t// endpoint and return a JSON response with empty result instead of SSE.\n\t\t\t// Retry without streaming so doStream's graceful degradation path can\n\t\t\t// wrap the complete response as a synthetic stream.\n\t\t\t// Use the same URL (gateway or direct) as the original request.\n\t\t\tconst retryResponse = await fetchFn(url, {\n\t\t\t\tbody: JSON.stringify({\n\t\t\t\t\t...(inputs as Record<string, unknown>),\n\t\t\t\t\tstream: false,\n\t\t\t\t}),\n\t\t\t\theaders,\n\t\t\t\tmethod: \"POST\",\n\t\t\t\tsignal: signal as AbortSignal | undefined,\n\t\t\t});\n\n\t\t\tif (!retryResponse.ok) {\n\t\t\t\tlet errorBody: string;\n\t\t\t\ttry {\n\t\t\t\t\terrorBody = await retryResponse.text();\n\t\t\t\t} catch {\n\t\t\t\t\terrorBody = \"<unable to read response body>\";\n\t\t\t\t}\n\t\t\t\tthrow apiCallErrorFromResponse(retryResponse, errorBody, {\n\t\t\t\t\turl,\n\t\t\t\t\trequestBodyValues: inputs,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst retryData = await retryResponse.json<{\n\t\t\t\tresult: AiModels[Name][\"postProcessedOutputs\"];\n\t\t\t}>();\n\t\t\treturn retryData.result;\n\t\t}\n\n\t\tconst data = await response.json<{\n\t\t\tresult: AiModels[Name][\"postProcessedOutputs\"];\n\t\t}>();\n\t\treturn data.result;\n\t};\n}\n\n/**\n * Make a binary REST API call to Workers AI.\n *\n * Some models (e.g. `@cf/deepgram/nova-3`) require raw audio bytes\n * with an appropriate `Content-Type` header instead of JSON.\n *\n * @param config  Credentials config\n * @param model   Workers AI model name\n * @param audioBytes  Raw audio bytes\n * @param contentType  MIME type (e.g. \"audio/wav\")\n * @param signal  Optional AbortSignal\n * @returns The parsed JSON response body\n */\nexport async function createRunBinary(\n\tconfig: CreateRunConfig,\n\tmodel: string,\n\taudioBytes: Uint8Array,\n\tcontentType: string,\n\tsignal?: AbortSignal,\n): Promise<Record<string, unknown>> {\n\tconst url = `https://api.cloudflare.com/client/v4/accounts/${config.accountId}/ai/run/${model}`;\n\n\tconst response = await fetch(url, {\n\t\tmethod: \"POST\",\n\t\theaders: {\n\t\t\tAuthorization: `Bearer ${config.apiKey}`,\n\t\t\t\"Content-Type\": contentType,\n\t\t},\n\t\tbody: audioBytes,\n\t\tsignal,\n\t});\n\n\tif (!response.ok) {\n\t\tlet errorBody: string;\n\t\ttry {\n\t\t\terrorBody = await response.text();\n\t\t} catch {\n\t\t\terrorBody = \"<unable to read response body>\";\n\t\t}\n\t\tthrow apiCallErrorFromResponse(response, errorBody, {\n\t\t\turl,\n\t\t\trequestBodyValues: { contentType, byteLength: audioBytes.byteLength },\n\t\t});\n\t}\n\n\tconst data = await response.json<{ result?: Record<string, unknown> }>();\n\treturn (data.result ?? data) as Record<string, unknown>;\n}\n\n// ---------------------------------------------------------------------------\n// Structured output (JSON mode)\n// ---------------------------------------------------------------------------\n\n/**\n * Build the `response_format.json_schema` payload for native Workers AI models.\n *\n * Native Workers AI (`@cf/...`) expects `json_schema` to be a **bare** JSON\n * Schema, NOT OpenAI's `{ name, schema, strict }` envelope. That envelope is\n * only required by partner-model routes (e.g. `openai/...`), which never reach\n * this code — they go through the gateway delegate and the real `@ai-sdk/*`\n * providers, which build the envelope themselves. Wrapping the schema here would\n * break native models, so we must keep the bare shape.\n *\n * The AI SDK's structured-output `name` / `description` (from\n * `Output.object({ schema, name, description })` / `generateObject`) would\n * otherwise be silently dropped on this path. We preserve them as the standard\n * JSON Schema `title` (from `name`) and `description` keywords, which keeps the\n * payload a valid bare schema while still passing the LLM guidance through.\n *\n * Existing schema-level `title` / `description` are never overwritten, empty\n * strings are ignored, and the input schema object is never mutated.\n *\n * See https://github.com/cloudflare/ai/issues/559.\n */\nexport function buildJsonSchemaPayload(\n\tschema: unknown,\n\tname?: string,\n\tdescription?: string,\n): unknown {\n\t// Only objects can carry JSON Schema keywords. Anything else (incl.\n\t// `undefined` when no schema was supplied) passes through untouched.\n\tif (typeof schema !== \"object\" || schema === null || Array.isArray(schema)) {\n\t\treturn schema;\n\t}\n\n\tconst record = schema as Record<string, unknown>;\n\tconst addTitle = !!name && record.title === undefined;\n\tconst addDescription = !!description && record.description === undefined;\n\n\tif (!addTitle && !addDescription) {\n\t\treturn schema;\n\t}\n\n\treturn {\n\t\t...record,\n\t\t...(addTitle ? { title: name } : {}),\n\t\t...(addDescription ? { description } : {}),\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// Tool preparation\n// ---------------------------------------------------------------------------\n\nexport function prepareToolsAndToolChoice(\n\ttools: Parameters<LanguageModelV3[\"doGenerate\"]>[0][\"tools\"],\n\ttoolChoice: Parameters<LanguageModelV3[\"doGenerate\"]>[0][\"toolChoice\"],\n) {\n\tif (tools == null) {\n\t\treturn { tool_choice: undefined, tools: undefined };\n\t}\n\n\tconst mappedTools = tools.map((tool) => ({\n\t\tfunction: {\n\t\t\tdescription: tool.type === \"function\" ? tool.description : undefined,\n\t\t\tname: tool.name,\n\t\t\tparameters: tool.type === \"function\" ? tool.inputSchema : undefined,\n\t\t},\n\t\ttype: \"function\",\n\t}));\n\n\tif (toolChoice == null) {\n\t\treturn { tool_choice: undefined, tools: mappedTools };\n\t}\n\n\tconst type = toolChoice.type;\n\n\tswitch (type) {\n\t\tcase \"auto\":\n\t\t\treturn { tool_choice: type, tools: mappedTools };\n\t\tcase \"none\":\n\t\t\treturn { tool_choice: type, tools: mappedTools };\n\t\tcase \"required\":\n\t\t\treturn { tool_choice: \"required\", tools: mappedTools };\n\n\t\t// Force a specific tool via the OpenAI-style named-function form.\n\t\t// Workers AI enforces this server-side, unlike \"required\" which is\n\t\t// advisory and \"fails open\" on long contexts / reasoning models (the\n\t\t// model can answer in prose instead of calling the tool). The full tool\n\t\t// list is kept (not filtered to the single function) to match OpenAI\n\t\t// semantics and preserve tool-result context fidelity.\n\t\t// See https://github.com/cloudflare/ai/issues/560.\n\t\tcase \"tool\":\n\t\t\treturn {\n\t\t\t\ttool_choice: { type: \"function\", function: { name: toolChoice.toolName } },\n\t\t\t\ttools: mappedTools,\n\t\t\t};\n\t\tdefault: {\n\t\t\tconst exhaustiveCheck = type satisfies never;\n\t\t\tthrow new Error(`Unsupported tool choice type: ${exhaustiveCheck}`);\n\t\t}\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Message helpers\n// ---------------------------------------------------------------------------\n\n// ---------------------------------------------------------------------------\n// Tool call processing\n// ---------------------------------------------------------------------------\n\nconst TOOL_CALL_ID_MARKER = \"::cf-wai-tool-call::\";\n\nexport function createAISDKToolCallId(toolCallId: string | null | undefined): string {\n\tconst originalId = toolCallId || generateId();\n\treturn `${originalId}${TOOL_CALL_ID_MARKER}${generateId()}`;\n}\n\nexport function toWorkersAIToolCallId(toolCallId: string): string {\n\tconst markerIndex = toolCallId.lastIndexOf(TOOL_CALL_ID_MARKER);\n\tif (markerIndex === -1) return toolCallId;\n\n\tconst suffixIndex = markerIndex + TOOL_CALL_ID_MARKER.length;\n\tif (suffixIndex >= toolCallId.length) return toolCallId;\n\n\treturn toolCallId.slice(0, markerIndex);\n}\n\n/** Workers AI flat tool call format (non-streaming, native) */\ninterface FlatToolCall {\n\tname: string;\n\targuments: unknown;\n\tid?: string;\n}\n\n/** Workers AI OpenAI-compatible tool call format */\ninterface OpenAIToolCall {\n\tid: string;\n\ttype: \"function\";\n\tfunction: {\n\t\tname: string;\n\t\targuments: unknown;\n\t};\n}\n\n/** Partial tool call from streaming (has index for merging) */\ninterface PartialToolCall {\n\tindex?: number;\n\tid?: string;\n\ttype?: string;\n\tfunction?: {\n\t\tname?: string;\n\t\targuments?: string;\n\t};\n\t// Flat format fields\n\tname?: string;\n\targuments?: string;\n}\n\nfunction mergePartialToolCalls(partialCalls: PartialToolCall[]) {\n\tconst mergedCallsByIndex: Record<\n\t\tnumber,\n\t\t{ function: { arguments: string; name: string }; id: string; type: string }\n\t> = {};\n\n\tfor (const partialCall of partialCalls) {\n\t\tconst index = partialCall.index ?? 0;\n\n\t\tif (!mergedCallsByIndex[index]) {\n\t\t\tmergedCallsByIndex[index] = {\n\t\t\t\tfunction: {\n\t\t\t\t\targuments: \"\",\n\t\t\t\t\tname: partialCall.function?.name || \"\",\n\t\t\t\t},\n\t\t\t\tid: partialCall.id || \"\",\n\t\t\t\ttype: partialCall.type || \"\",\n\t\t\t};\n\t\t} else {\n\t\t\tif (partialCall.id) {\n\t\t\t\tmergedCallsByIndex[index].id = partialCall.id;\n\t\t\t}\n\t\t\tif (partialCall.type) {\n\t\t\t\tmergedCallsByIndex[index].type = partialCall.type;\n\t\t\t}\n\t\t\tif (partialCall.function?.name) {\n\t\t\t\tmergedCallsByIndex[index].function.name = partialCall.function.name;\n\t\t\t}\n\t\t}\n\n\t\t// Append arguments if available (they arrive in order during streaming)\n\t\tif (partialCall.function?.arguments) {\n\t\t\tmergedCallsByIndex[index].function.arguments += partialCall.function.arguments;\n\t\t}\n\t}\n\n\treturn Object.values(mergedCallsByIndex);\n}\n\nfunction processToolCall(toolCall: FlatToolCall | OpenAIToolCall): LanguageModelV3ToolCall {\n\t// OpenAI format: has function.name (the key discriminator)\n\tconst fn =\n\t\t\"function\" in toolCall && typeof toolCall.function === \"object\" && toolCall.function\n\t\t\t? (toolCall.function as { name?: string; arguments?: unknown })\n\t\t\t: null;\n\n\tif (fn?.name) {\n\t\treturn {\n\t\t\tinput:\n\t\t\t\ttypeof fn.arguments === \"string\"\n\t\t\t\t\t? fn.arguments\n\t\t\t\t\t: JSON.stringify(fn.arguments || {}),\n\t\t\ttoolCallId: createAISDKToolCallId(toolCall.id),\n\t\t\ttype: \"tool-call\",\n\t\t\ttoolName: fn.name,\n\t\t};\n\t}\n\n\t// Flat format (native Workers AI non-streaming): has top-level name\n\tconst flat = toolCall as FlatToolCall;\n\treturn {\n\t\tinput:\n\t\t\ttypeof flat.arguments === \"string\"\n\t\t\t\t? flat.arguments\n\t\t\t\t: JSON.stringify(flat.arguments || {}),\n\t\ttoolCallId: createAISDKToolCallId(flat.id),\n\t\ttype: \"tool-call\",\n\t\ttoolName: flat.name,\n\t};\n}\n\nexport function processToolCalls(output: Record<string, unknown>): LanguageModelV3ToolCall[] {\n\tif (output.tool_calls && Array.isArray(output.tool_calls)) {\n\t\treturn output.tool_calls.map((toolCall: FlatToolCall | OpenAIToolCall) =>\n\t\t\tprocessToolCall(toolCall),\n\t\t);\n\t}\n\n\tconst choices = output.choices as\n\t\t| Array<{ message?: { tool_calls?: Array<FlatToolCall | OpenAIToolCall> } }>\n\t\t| undefined;\n\tif (choices?.[0]?.message?.tool_calls && Array.isArray(choices[0].message.tool_calls)) {\n\t\treturn choices[0].message.tool_calls.map((toolCall) => processToolCall(toolCall));\n\t}\n\n\treturn [];\n}\n\nexport function processPartialToolCalls(partialToolCalls: PartialToolCall[]) {\n\tconst mergedToolCalls = mergePartialToolCalls(partialToolCalls);\n\treturn processToolCalls({ tool_calls: mergedToolCalls });\n}\n\n// ---------------------------------------------------------------------------\n// Forced tool-call salvage (gpt-oss harmony quirk)\n// ---------------------------------------------------------------------------\n\n/**\n * Parse tool calls that a model leaked as JSON text instead of structured\n * `tool_calls`, assigning AI-SDK tool-call ids.\n *\n * The recovery logic (which JSON shapes count as a leaked call) lives in\n * `@cloudflare/gateway-core`; this wrapper only layers the framework id on each\n * neutral result so the existing `LanguageModelV3ToolCall` shape is preserved.\n */\nexport function parseLeakedToolCalls(\n\ttext: string,\n\tknownToolNames: Set<string>,\n): LanguageModelV3ToolCall[] {\n\treturn coreParseLeakedToolCalls(text, knownToolNames).map((call) => ({\n\t\tinput: call.input,\n\t\ttoolCallId: createAISDKToolCallId(undefined),\n\t\ttype: \"tool-call\",\n\t\ttoolName: call.toolName,\n\t}));\n}\n\n/**\n * Salvage a tool call that a model leaked into text content instead of the\n * structured `tool_calls` field.\n *\n * Workers AI's gpt-oss models (harmony format) sometimes emit a forced tool\n * call as raw JSON in `message.content` with an empty `tool_calls` array and\n * `finish_reason: \"stop\"` — typically when the forced tool is a poor fit for\n * the conversation. The content looks like one of:\n *\n *   {\"name\":\"read_skill_resource\",\"path\":\"feedback.txt\"}        (flat args)\n *   {\"name\":\"calc\",\"arguments\":{\"a\":1}}                          (wrapped args)\n *   [{\"name\":\"calc\",\"parameters\":{\"a\":1}}]                       (array form)\n *\n * This reinterprets that text as a structured tool call. It is intentionally\n * narrow to avoid false positives:\n *   - only runs when a tool was *forced* (required / named-function), so a\n *     tool call was explicitly demanded by the caller;\n *   - only runs when there are no real structured tool calls to override;\n *   - only matches JSON objects whose `name` is one of the requested tools.\n *\n * Returns the salvaged tool calls, or `null` when nothing was salvaged.\n *\n * See https://github.com/cloudflare/ai/issues/560.\n */\nexport function salvageToolCallsFromText(\n\toutput: Record<string, unknown>,\n\tcontext: {\n\t\ttools: Array<{ function: { name?: string } }> | undefined;\n\t\ttoolChoice: unknown;\n\t},\n): LanguageModelV3ToolCall[] | null {\n\tif (!isForcedToolChoice(context.toolChoice)) return null;\n\n\t// Never override real tool calls.\n\tif (processToolCalls(output).length > 0) return null;\n\n\tconst knownToolNames = getToolNames(context.tools);\n\tif (knownToolNames.size === 0) return null;\n\n\tconst text = processText(output);\n\tif (!text) return null;\n\n\tconst salvaged = parseLeakedToolCalls(text, knownToolNames);\n\treturn salvaged.length > 0 ? salvaged : null;\n}\n","import type { LanguageModelV3DataContent, LanguageModelV3Prompt } from \"@ai-sdk/provider\";\nimport { UnsupportedFunctionalityError } from \"@ai-sdk/provider\";\nimport { toWorkersAIToolCallId } from \"./utils\";\nimport type { WorkersAIContentPart, WorkersAIChatPrompt } from \"./workersai-chat-prompt\";\n\n/**\n * Normalise any LanguageModelV3DataContent value to a Uint8Array.\n *\n * Handles:\n *   - Uint8Array  → returned as-is\n *   - string      → decoded from base64 (with or without data-URL prefix)\n *   - URL         → not supported (Workers AI needs raw bytes, not a reference)\n */\nfunction toUint8Array(data: LanguageModelV3DataContent): Uint8Array | null {\n\tif (data instanceof Uint8Array) {\n\t\treturn data;\n\t}\n\n\tif (typeof data === \"string\") {\n\t\tlet base64 = data;\n\t\tif (base64.startsWith(\"data:\")) {\n\t\t\tconst commaIndex = base64.indexOf(\",\");\n\t\t\tif (commaIndex >= 0) {\n\t\t\t\tbase64 = base64.slice(commaIndex + 1);\n\t\t\t}\n\t\t}\n\t\tconst binaryString = atob(base64);\n\t\tconst bytes = new Uint8Array(binaryString.length);\n\t\tfor (let i = 0; i < binaryString.length; i++) {\n\t\t\tbytes[i] = binaryString.charCodeAt(i);\n\t\t}\n\t\treturn bytes;\n\t}\n\n\tif (data instanceof URL) {\n\t\tthrow new Error(\n\t\t\t\"URL image sources are not supported by Workers AI. \" +\n\t\t\t\t\"Provide image data as a Uint8Array or base64 string instead.\",\n\t\t);\n\t}\n\n\treturn null;\n}\n\nfunction assertImageMediaType(mediaType: string | undefined): string {\n\tif (!mediaType) {\n\t\tthrow new UnsupportedFunctionalityError({\n\t\t\tfunctionality: \"file-part-without-media-type\",\n\t\t\tmessage:\n\t\t\t\t\"Workers AI chat only supports image file parts with an image/* mediaType. \" +\n\t\t\t\t\"Received a file part without a mediaType.\",\n\t\t});\n\t}\n\n\t// Media types are case-insensitive (RFC 2045), so compare against a\n\t// lower-cased copy while preserving the caller's original casing on output.\n\tif (!mediaType.toLowerCase().startsWith(\"image/\")) {\n\t\tthrow new UnsupportedFunctionalityError({\n\t\t\tfunctionality: \"non-image-file-part\",\n\t\t\tmessage:\n\t\t\t\t\"Workers AI chat only supports image file parts with an image/* mediaType. \" +\n\t\t\t\t`Received mediaType \"${mediaType}\".`,\n\t\t});\n\t}\n\n\treturn mediaType;\n}\n\nfunction uint8ArrayToBase64(bytes: Uint8Array): string {\n\tlet binary = \"\";\n\tconst chunkSize = 8192;\n\tfor (let i = 0; i < bytes.length; i += chunkSize) {\n\t\tconst chunk = bytes.subarray(i, Math.min(i + chunkSize, bytes.length));\n\t\tbinary += String.fromCharCode(...chunk);\n\t}\n\treturn btoa(binary);\n}\n\nexport function convertToWorkersAIChatMessages(prompt: LanguageModelV3Prompt): {\n\tmessages: WorkersAIChatPrompt;\n} {\n\tconst messages: WorkersAIChatPrompt = [];\n\n\tfor (const { role, content } of prompt) {\n\t\tswitch (role) {\n\t\t\tcase \"system\": {\n\t\t\t\tmessages.push({ content, role: \"system\" });\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"user\": {\n\t\t\t\tconst textParts: string[] = [];\n\t\t\t\tconst imageParts: { image: Uint8Array; mediaType: string }[] = [];\n\n\t\t\t\tfor (const part of content) {\n\t\t\t\t\tswitch (part.type) {\n\t\t\t\t\t\tcase \"text\": {\n\t\t\t\t\t\t\ttextParts.push(part.text);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcase \"file\": {\n\t\t\t\t\t\t\tconst mediaType = assertImageMediaType(part.mediaType);\n\t\t\t\t\t\t\tconst imageBytes = toUint8Array(part.data);\n\t\t\t\t\t\t\tif (imageBytes) {\n\t\t\t\t\t\t\t\timageParts.push({\n\t\t\t\t\t\t\t\t\timage: imageBytes,\n\t\t\t\t\t\t\t\t\tmediaType,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (imageParts.length > 0) {\n\t\t\t\t\tconst contentArray: WorkersAIContentPart[] = [];\n\t\t\t\t\tif (textParts.length > 0) {\n\t\t\t\t\t\tcontentArray.push({ type: \"text\", text: textParts.join(\"\\n\") });\n\t\t\t\t\t}\n\t\t\t\t\tfor (const img of imageParts) {\n\t\t\t\t\t\tconst base64 = uint8ArrayToBase64(img.image);\n\t\t\t\t\t\tcontentArray.push({\n\t\t\t\t\t\t\ttype: \"image_url\",\n\t\t\t\t\t\t\timage_url: { url: `data:${img.mediaType};base64,${base64}` },\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\tmessages.push({ content: contentArray, role: \"user\" });\n\t\t\t\t} else {\n\t\t\t\t\tmessages.push({ content: textParts.join(\"\\n\"), role: \"user\" });\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"assistant\": {\n\t\t\t\tlet text = \"\";\n\t\t\t\tlet reasoning = \"\";\n\t\t\t\tconst toolCalls: Array<{\n\t\t\t\t\tid: string;\n\t\t\t\t\ttype: \"function\";\n\t\t\t\t\tfunction: { name: string; arguments: string };\n\t\t\t\t}> = [];\n\n\t\t\t\tfor (const part of content) {\n\t\t\t\t\tswitch (part.type) {\n\t\t\t\t\t\tcase \"text\": {\n\t\t\t\t\t\t\ttext += part.text;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcase \"reasoning\": {\n\t\t\t\t\t\t\t// Reasoning is accumulated separately and sent as the `reasoning`\n\t\t\t\t\t\t\t// field on the message object. This is the field name vLLM expects\n\t\t\t\t\t\t\t// on input for reasoning models (kimi-k2.7-code, glm-4.7-flash).\n\t\t\t\t\t\t\t// Concatenating it into `content` corrupts the conversation history\n\t\t\t\t\t\t\t// and causes models to produce empty or garbled responses on the\n\t\t\t\t\t\t\t// next turn.\n\t\t\t\t\t\t\treasoning += part.text;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcase \"file\": {\n\t\t\t\t\t\t\t// File parts in assistant messages - no action needed\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcase \"tool-call\": {\n\t\t\t\t\t\t\ttoolCalls.push({\n\t\t\t\t\t\t\t\tfunction: {\n\t\t\t\t\t\t\t\t\targuments: JSON.stringify(part.input),\n\t\t\t\t\t\t\t\t\tname: part.toolName,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tid: toWorkersAIToolCallId(part.toolCallId),\n\t\t\t\t\t\t\t\ttype: \"function\",\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcase \"tool-result\": {\n\t\t\t\t\t\t\t// Tool results in assistant messages - no action needed\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tdefault: {\n\t\t\t\t\t\t\tconst exhaustiveCheck = part satisfies never;\n\t\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t\t`Unsupported part type: ${(exhaustiveCheck as { type: string }).type}`,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tmessages.push({\n\t\t\t\t\tcontent: text,\n\t\t\t\t\trole: \"assistant\",\n\t\t\t\t\t...(reasoning ? { reasoning } : {}),\n\t\t\t\t\ttool_calls:\n\t\t\t\t\t\ttoolCalls.length > 0\n\t\t\t\t\t\t\t? toolCalls.map(({ function: { name, arguments: args }, id }) => ({\n\t\t\t\t\t\t\t\t\tfunction: { arguments: args, name },\n\t\t\t\t\t\t\t\t\tid,\n\t\t\t\t\t\t\t\t\ttype: \"function\" as const,\n\t\t\t\t\t\t\t\t}))\n\t\t\t\t\t\t\t: undefined,\n\t\t\t\t});\n\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase \"tool\": {\n\t\t\t\tfor (const toolResponse of content) {\n\t\t\t\t\tif (toolResponse.type === \"tool-result\") {\n\t\t\t\t\t\tconst output = toolResponse.output;\n\t\t\t\t\t\tlet content: string;\n\t\t\t\t\t\tswitch (output.type) {\n\t\t\t\t\t\t\tcase \"text\":\n\t\t\t\t\t\t\tcase \"error-text\":\n\t\t\t\t\t\t\t\tcontent = output.value;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase \"json\":\n\t\t\t\t\t\t\tcase \"error-json\":\n\t\t\t\t\t\t\t\tcontent = JSON.stringify(output.value);\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase \"execution-denied\":\n\t\t\t\t\t\t\t\tcontent = output.reason\n\t\t\t\t\t\t\t\t\t? `Tool execution denied: ${output.reason}`\n\t\t\t\t\t\t\t\t\t: \"Tool execution was denied.\";\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase \"content\":\n\t\t\t\t\t\t\t\tcontent = output.value\n\t\t\t\t\t\t\t\t\t.filter(\n\t\t\t\t\t\t\t\t\t\t(p): p is { type: \"text\"; text: string } =>\n\t\t\t\t\t\t\t\t\t\t\tp.type === \"text\",\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t.map((p) => p.text)\n\t\t\t\t\t\t\t\t\t.join(\"\\n\");\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\tcontent = \"\";\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmessages.push({\n\t\t\t\t\t\t\tcontent,\n\t\t\t\t\t\t\tname: toolResponse.toolName,\n\t\t\t\t\t\t\ttool_call_id: toWorkersAIToolCallId(toolResponse.toolCallId),\n\t\t\t\t\t\t\trole: \"tool\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\t// Skip tool-approval-response parts as they're not supported by Workers AI\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tdefault: {\n\t\t\t\tconst exhaustiveCheck = role satisfies never;\n\t\t\t\tthrow new Error(`Unsupported role: ${exhaustiveCheck}`);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { messages };\n}\n","import type { LanguageModelV3Usage } from \"@ai-sdk/provider\";\n\n/**\n * Map Workers AI usage data to the AI SDK V3 usage format.\n * Accepts any object that may have a `usage` property with token counts.\n *\n * Workers AI mirrors the OpenAI usage shape, including\n * `prompt_tokens_details.cached_tokens` for prompt-cache hits. OpenAI-style\n * responses don't distinguish cache reads from cache writes, so we treat\n * `cached_tokens` as `cacheRead` and leave `cacheWrite` undefined.\n */\nexport function mapWorkersAIUsage(\n\toutput: Record<string, unknown> | AiTextGenerationOutput | AiTextToImageOutput,\n): LanguageModelV3Usage {\n\tconst usage = (\n\t\toutput as {\n\t\t\tusage?: {\n\t\t\t\tprompt_tokens?: number;\n\t\t\t\tcompletion_tokens?: number;\n\t\t\t\tprompt_tokens_details?: { cached_tokens?: number };\n\t\t\t};\n\t\t}\n\t).usage ?? {\n\t\tcompletion_tokens: 0,\n\t\tprompt_tokens: 0,\n\t};\n\n\tconst promptTokens = usage.prompt_tokens ?? 0;\n\tconst completionTokens = usage.completion_tokens ?? 0;\n\tconst cachedTokens = usage.prompt_tokens_details?.cached_tokens;\n\n\t// Clamp at 0 in case the provider ever reports cached_tokens > prompt_tokens;\n\t// the v3 spec expects non-negative counts.\n\tconst noCache =\n\t\tcachedTokens !== undefined ? Math.max(0, promptTokens - cachedTokens) : undefined;\n\n\treturn {\n\t\toutputTokens: {\n\t\t\ttotal: completionTokens,\n\t\t\ttext: undefined,\n\t\t\treasoning: undefined,\n\t\t},\n\t\tinputTokens: {\n\t\t\ttotal: promptTokens,\n\t\t\tnoCache,\n\t\t\tcacheRead: cachedTokens,\n\t\t\tcacheWrite: undefined,\n\t\t},\n\t\traw: { total: promptTokens + completionTokens },\n\t};\n}\n","import type { LanguageModelV3FinishReason } from \"@ai-sdk/provider\";\n\n/**\n * Map a Workers AI finish reason to the AI SDK unified finish reason.\n *\n * Accepts either:\n * - A raw finish reason string (e.g., \"stop\", \"tool_calls\")\n * - A full response object with finish_reason in various locations\n */\nexport function mapWorkersAIFinishReason(\n\tfinishReasonOrResponse: string | null | undefined | Record<string, unknown>,\n): LanguageModelV3FinishReason {\n\tlet finishReason: string | null | undefined;\n\n\tif (\n\t\ttypeof finishReasonOrResponse === \"string\" ||\n\t\tfinishReasonOrResponse === null ||\n\t\tfinishReasonOrResponse === undefined\n\t) {\n\t\tfinishReason = finishReasonOrResponse;\n\t} else if (typeof finishReasonOrResponse === \"object\" && finishReasonOrResponse !== null) {\n\t\tconst response = finishReasonOrResponse;\n\n\t\t// OpenAI format: { choices: [{ finish_reason: \"stop\" }] }\n\t\tconst choices = response.choices as Array<{ finish_reason?: string }> | undefined;\n\t\tif (Array.isArray(choices) && choices.length > 0) {\n\t\t\tfinishReason = choices[0].finish_reason;\n\t\t} else if (\"finish_reason\" in response) {\n\t\t\tfinishReason = response.finish_reason as string;\n\t\t} else {\n\t\t\tfinishReason = undefined;\n\t\t}\n\t} else {\n\t\t// Numbers, booleans, etc. -- default to stop\n\t\tfinishReason = undefined;\n\t}\n\n\tconst raw = finishReason ?? \"stop\";\n\n\tswitch (finishReason) {\n\t\tcase \"stop\":\n\t\t\treturn { unified: \"stop\", raw };\n\t\tcase \"length\":\n\t\tcase \"model_length\":\n\t\t\treturn { unified: \"length\", raw };\n\t\tcase \"tool_calls\":\n\t\t\treturn { unified: \"tool-calls\", raw };\n\t\tcase \"error\":\n\t\t\treturn { unified: \"error\", raw };\n\t\tcase \"other\":\n\t\tcase \"unknown\":\n\t\t\treturn { unified: \"other\", raw };\n\t\tdefault:\n\t\t\treturn { unified: \"stop\", raw };\n\t}\n}\n","import type {\n\tLanguageModelV3FinishReason,\n\tLanguageModelV3StreamPart,\n\tLanguageModelV3Usage,\n} from \"@ai-sdk/provider\";\nimport { SSEDecoder } from \"@cloudflare/gateway-core\";\nimport { generateId } from \"ai\";\nimport { mapWorkersAIFinishReason } from \"./map-workersai-finish-reason\";\nimport { mapWorkersAIUsage } from \"./map-workersai-usage\";\nimport {\n\tcreateAISDKToolCallId,\n\tgetToolNames,\n\tisForcedToolChoice,\n\tparseLeakedToolCalls,\n} from \"./utils\";\n\n/**\n * Prepend a stream-start event to an existing LanguageModelV3 stream.\n * Uses pipeThrough for proper backpressure and error propagation.\n */\nexport function prependStreamStart(\n\tsource: ReadableStream<LanguageModelV3StreamPart>,\n\twarnings: LanguageModelV3StreamPart extends { type: \"stream-start\" } ? never : unknown,\n): ReadableStream<LanguageModelV3StreamPart> {\n\tlet sentStart = false;\n\treturn source.pipeThrough(\n\t\tnew TransformStream<LanguageModelV3StreamPart, LanguageModelV3StreamPart>({\n\t\t\ttransform(chunk, controller) {\n\t\t\t\tif (!sentStart) {\n\t\t\t\t\tsentStart = true;\n\t\t\t\t\tcontroller.enqueue({\n\t\t\t\t\t\ttype: \"stream-start\",\n\t\t\t\t\t\twarnings: warnings as [],\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tcontroller.enqueue(chunk);\n\t\t\t},\n\t\t\tflush(controller) {\n\t\t\t\tif (!sentStart) {\n\t\t\t\t\tcontroller.enqueue({\n\t\t\t\t\t\ttype: \"stream-start\",\n\t\t\t\t\t\twarnings: warnings as [],\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t},\n\t\t}),\n\t);\n}\n\n/**\n * Check if a streaming tool call chunk is a null-finalization sentinel.\n */\nfunction isNullFinalizationChunk(tc: Record<string, unknown>): boolean {\n\tconst fn = tc.function as Record<string, unknown> | undefined;\n\tconst name = fn?.name ?? tc.name ?? null;\n\tconst args = fn?.arguments ?? tc.arguments ?? null;\n\tconst id = tc.id ?? null;\n\treturn !id && !name && (!args || args === \"\");\n}\n\n/**\n * Maps a Workers AI SSE stream into AI SDK V3 LanguageModelV3StreamPart events.\n *\n * Uses a TransformStream pipeline for proper backpressure — chunks are emitted\n * one at a time as the downstream consumer pulls, not buffered eagerly.\n *\n * Handles two distinct formats:\n * 1. Native format:  { response: \"chunk\", tool_calls: [...] }\n * 2. OpenAI format:  { choices: [{ delta: { content: \"chunk\" } }] }\n */\nexport function getMappedStream(\n\tresponse: Response | ReadableStream<Uint8Array>,\n\tsalvageContext?: {\n\t\ttools: Array<{ function: { name?: string } }> | undefined;\n\t\ttoolChoice: unknown;\n\t},\n): ReadableStream<LanguageModelV3StreamPart> {\n\tconst rawStream =\n\t\tresponse instanceof ReadableStream\n\t\t\t? response\n\t\t\t: (response.body as ReadableStream<Uint8Array>);\n\n\tif (!rawStream) {\n\t\tthrow new Error(\"No readable stream available for SSE parsing.\");\n\t}\n\n\t// gpt-oss harmony quirk: a forced tool call can be streamed as `content`\n\t// text deltas instead of structured tool calls. When a tool was forced,\n\t// buffer the text content (rather than emitting it incrementally) so we can\n\t// reinterpret it as a tool call at flush time. Text is unexpected in forced\n\t// mode anyway, so buffering it does not regress a useful stream.\n\t// See https://github.com/cloudflare/ai/issues/560.\n\tconst knownToolNames = getToolNames(salvageContext?.tools);\n\tconst bufferContentForSalvage =\n\t\tisForcedToolChoice(salvageContext?.toolChoice) && knownToolNames.size > 0;\n\tlet contentBuffer = \"\";\n\tlet anyToolCallStarted = false;\n\n\t// State shared across the transform\n\tlet usage: LanguageModelV3Usage = {\n\t\toutputTokens: { total: 0, text: undefined, reasoning: undefined },\n\t\tinputTokens: {\n\t\t\ttotal: 0,\n\t\t\tnoCache: undefined,\n\t\t\tcacheRead: undefined,\n\t\t\tcacheWrite: undefined,\n\t\t},\n\t\traw: { totalTokens: 0 },\n\t};\n\tlet textId: string | null = null;\n\tlet reasoningId: string | null = null;\n\tlet finishReason: LanguageModelV3FinishReason | null = null;\n\tlet receivedDone = false;\n\tlet receivedAnyData = false;\n\n\t// Track tool call streaming state per index.\n\t// When we see the first chunk for a tool call index, we emit tool-input-start.\n\t// Subsequent argument deltas emit tool-input-delta.\n\t// tool-input-end is emitted eagerly when a new tool index starts or a null\n\t// finalization chunk arrives; any remaining open calls are closed in flush().\n\tconst activeToolCalls = new Map<number, { id: string; toolName: string; args: string }>();\n\tconst closedToolCalls = new Set<number>();\n\tlet lastActiveToolIndex: number | null = null;\n\n\t// Step 1: Decode bytes into SSE lines\n\tconst sseStream = rawStream.pipeThrough(new SSEDecoder());\n\n\t// Step 2: Transform SSE events into LanguageModelV3StreamPart\n\treturn sseStream.pipeThrough(\n\t\tnew TransformStream<string, LanguageModelV3StreamPart>({\n\t\t\ttransform(data, controller) {\n\t\t\t\tif (!data || data === \"[DONE]\") {\n\t\t\t\t\tif (data === \"[DONE]\") receivedDone = true;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\treceivedAnyData = true;\n\t\t\t\tlet chunk: Record<string, unknown>;\n\t\t\t\ttry {\n\t\t\t\t\tchunk = JSON.parse(data);\n\t\t\t\t} catch {\n\t\t\t\t\tconsole.warn(\"[workers-ai-provider] failed to parse SSE event:\", data);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif (chunk.usage) {\n\t\t\t\t\tusage = mapWorkersAIUsage(chunk as Parameters<typeof mapWorkersAIUsage>[0]);\n\t\t\t\t}\n\n\t\t\t\t// Extract finish_reason\n\t\t\t\tconst choices = chunk.choices as\n\t\t\t\t\t| Array<{\n\t\t\t\t\t\t\tfinish_reason?: string;\n\t\t\t\t\t\t\tdelta?: Record<string, unknown>;\n\t\t\t\t\t  }>\n\t\t\t\t\t| undefined;\n\t\t\t\tconst choiceFinishReason = choices?.[0]?.finish_reason;\n\t\t\t\tconst directFinishReason = chunk.finish_reason as string | undefined;\n\n\t\t\t\tif (choiceFinishReason != null) {\n\t\t\t\t\tfinishReason = mapWorkersAIFinishReason(choiceFinishReason);\n\t\t\t\t} else if (directFinishReason != null) {\n\t\t\t\t\tfinishReason = mapWorkersAIFinishReason(directFinishReason);\n\t\t\t\t}\n\n\t\t\t\t// --- Native format: top-level `response` field ---\n\t\t\t\tconst nativeResponse = chunk.response;\n\t\t\t\tif (nativeResponse != null && nativeResponse !== \"\") {\n\t\t\t\t\tconst responseText = String(nativeResponse);\n\t\t\t\t\tif (responseText.length > 0) {\n\t\t\t\t\t\tif (bufferContentForSalvage) {\n\t\t\t\t\t\t\tcontentBuffer += responseText;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Close active reasoning block before text starts\n\t\t\t\t\t\t\tif (reasoningId) {\n\t\t\t\t\t\t\t\tcontroller.enqueue({ type: \"reasoning-end\", id: reasoningId });\n\t\t\t\t\t\t\t\treasoningId = null;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (!textId) {\n\t\t\t\t\t\t\t\ttextId = generateId();\n\t\t\t\t\t\t\t\tcontroller.enqueue({ type: \"text-start\", id: textId });\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcontroller.enqueue({\n\t\t\t\t\t\t\t\ttype: \"text-delta\",\n\t\t\t\t\t\t\t\tid: textId,\n\t\t\t\t\t\t\t\tdelta: responseText,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// --- Native format: top-level `tool_calls` ---\n\t\t\t\tif (Array.isArray(chunk.tool_calls)) {\n\t\t\t\t\t// Close active reasoning block before tool calls start\n\t\t\t\t\tif (reasoningId) {\n\t\t\t\t\t\tcontroller.enqueue({ type: \"reasoning-end\", id: reasoningId });\n\t\t\t\t\t\treasoningId = null;\n\t\t\t\t\t}\n\t\t\t\t\temitToolCallDeltas(chunk.tool_calls as Record<string, unknown>[], controller);\n\t\t\t\t}\n\n\t\t\t\t// --- OpenAI format: choices[0].delta ---\n\t\t\t\tif (choices?.[0]?.delta) {\n\t\t\t\t\tconst delta = choices[0].delta;\n\n\t\t\t\t\tconst reasoningDelta = (delta.reasoning_content ?? delta.reasoning) as\n\t\t\t\t\t\t| string\n\t\t\t\t\t\t| undefined;\n\t\t\t\t\tif (reasoningDelta && reasoningDelta.length > 0) {\n\t\t\t\t\t\tif (!reasoningId) {\n\t\t\t\t\t\t\treasoningId = generateId();\n\t\t\t\t\t\t\tcontroller.enqueue({\n\t\t\t\t\t\t\t\ttype: \"reasoning-start\",\n\t\t\t\t\t\t\t\tid: reasoningId,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontroller.enqueue({\n\t\t\t\t\t\t\ttype: \"reasoning-delta\",\n\t\t\t\t\t\t\tid: reasoningId,\n\t\t\t\t\t\t\tdelta: reasoningDelta,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst textDelta = delta.content as string | undefined;\n\t\t\t\t\tif (textDelta && textDelta.length > 0) {\n\t\t\t\t\t\tif (bufferContentForSalvage) {\n\t\t\t\t\t\t\tcontentBuffer += textDelta;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Close active reasoning block before text starts\n\t\t\t\t\t\t\tif (reasoningId) {\n\t\t\t\t\t\t\t\tcontroller.enqueue({ type: \"reasoning-end\", id: reasoningId });\n\t\t\t\t\t\t\t\treasoningId = null;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (!textId) {\n\t\t\t\t\t\t\t\ttextId = generateId();\n\t\t\t\t\t\t\t\tcontroller.enqueue({ type: \"text-start\", id: textId });\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcontroller.enqueue({\n\t\t\t\t\t\t\t\ttype: \"text-delta\",\n\t\t\t\t\t\t\t\tid: textId,\n\t\t\t\t\t\t\t\tdelta: textDelta,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tconst deltaToolCalls = delta.tool_calls as\n\t\t\t\t\t\t| Record<string, unknown>[]\n\t\t\t\t\t\t| undefined;\n\t\t\t\t\tif (Array.isArray(deltaToolCalls)) {\n\t\t\t\t\t\t// Close active reasoning block before tool calls start\n\t\t\t\t\t\tif (reasoningId) {\n\t\t\t\t\t\t\tcontroller.enqueue({ type: \"reasoning-end\", id: reasoningId });\n\t\t\t\t\t\t\treasoningId = null;\n\t\t\t\t\t\t}\n\t\t\t\t\t\temitToolCallDeltas(deltaToolCalls, controller);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tflush(controller) {\n\t\t\t\t// Close any tool calls that weren't already closed during streaming\n\t\t\t\tfor (const [idx] of activeToolCalls) {\n\t\t\t\t\tif (closedToolCalls.has(idx)) continue;\n\t\t\t\t\tcloseToolCall(idx, controller);\n\t\t\t\t}\n\n\t\t\t\t// Close open reasoning block before any salvaged tool calls.\n\t\t\t\tif (reasoningId) {\n\t\t\t\t\tcontroller.enqueue({ type: \"reasoning-end\", id: reasoningId });\n\t\t\t\t}\n\n\t\t\t\t// Salvage a forced tool call that streamed as buffered text.\n\t\t\t\tlet salvagedToolCalls = false;\n\t\t\t\tif (bufferContentForSalvage && !anyToolCallStarted && contentBuffer.trim()) {\n\t\t\t\t\tconst salvaged = parseLeakedToolCalls(contentBuffer, knownToolNames);\n\t\t\t\t\tif (salvaged.length > 0) {\n\t\t\t\t\t\tfor (const call of salvaged) {\n\t\t\t\t\t\t\tcontroller.enqueue({\n\t\t\t\t\t\t\t\ttype: \"tool-input-start\",\n\t\t\t\t\t\t\t\tid: call.toolCallId,\n\t\t\t\t\t\t\t\ttoolName: call.toolName,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tcontroller.enqueue({\n\t\t\t\t\t\t\t\ttype: \"tool-input-delta\",\n\t\t\t\t\t\t\t\tid: call.toolCallId,\n\t\t\t\t\t\t\t\tdelta: call.input,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tcontroller.enqueue({ type: \"tool-input-end\", id: call.toolCallId });\n\t\t\t\t\t\t\tcontroller.enqueue(call);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tsalvagedToolCalls = true;\n\t\t\t\t\t\t// Stream warnings are fixed at stream-start, so surface the\n\t\t\t\t\t\t// reinterpretation here for observability instead.\n\t\t\t\t\t\tconsole.warn(\n\t\t\t\t\t\t\t`[workers-ai-provider] Recovered ${salvaged.length} forced tool call(s) that the model streamed as text content instead of structured tool calls.`,\n\t\t\t\t\t\t);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Not a recoverable tool call — emit the buffered text as-is.\n\t\t\t\t\t\tconst id = generateId();\n\t\t\t\t\t\tcontroller.enqueue({ type: \"text-start\", id });\n\t\t\t\t\t\tcontroller.enqueue({ type: \"text-delta\", id, delta: contentBuffer });\n\t\t\t\t\t\tcontroller.enqueue({ type: \"text-end\", id });\n\t\t\t\t\t}\n\t\t\t\t} else if (bufferContentForSalvage && contentBuffer.trim()) {\n\t\t\t\t\t// Real tool calls were present alongside buffered text — emit text.\n\t\t\t\t\tconst id = generateId();\n\t\t\t\t\tcontroller.enqueue({ type: \"text-start\", id });\n\t\t\t\t\tcontroller.enqueue({ type: \"text-delta\", id, delta: contentBuffer });\n\t\t\t\t\tcontroller.enqueue({ type: \"text-end\", id });\n\t\t\t\t}\n\n\t\t\t\tif (textId) {\n\t\t\t\t\tcontroller.enqueue({ type: \"text-end\", id: textId });\n\t\t\t\t}\n\n\t\t\t\t// Detect premature termination\n\t\t\t\tconst effectiveFinishReason = salvagedToolCalls\n\t\t\t\t\t? ({ unified: \"tool-calls\", raw: \"stop\" } as LanguageModelV3FinishReason)\n\t\t\t\t\t: !receivedDone && receivedAnyData && !finishReason\n\t\t\t\t\t\t? ({\n\t\t\t\t\t\t\t\tunified: \"error\",\n\t\t\t\t\t\t\t\traw: \"stream-truncated\",\n\t\t\t\t\t\t\t} as LanguageModelV3FinishReason)\n\t\t\t\t\t\t: (finishReason ?? { unified: \"stop\", raw: \"stop\" });\n\n\t\t\t\tcontroller.enqueue({\n\t\t\t\t\tfinishReason: effectiveFinishReason,\n\t\t\t\t\ttype: \"finish\",\n\t\t\t\t\tusage,\n\t\t\t\t});\n\t\t\t},\n\t\t}),\n\t);\n\n\t/**\n\t * Emit tool-input-end + tool-call for a tool call that is complete.\n\t */\n\tfunction closeToolCall(\n\t\tindex: number,\n\t\tcontroller: TransformStreamDefaultController<LanguageModelV3StreamPart>,\n\t) {\n\t\tconst tc = activeToolCalls.get(index);\n\t\tif (!tc || closedToolCalls.has(index)) return;\n\t\tclosedToolCalls.add(index);\n\t\tcontroller.enqueue({ type: \"tool-input-end\", id: tc.id });\n\t\tcontroller.enqueue({\n\t\t\ttype: \"tool-call\",\n\t\t\ttoolCallId: tc.id,\n\t\t\ttoolName: tc.toolName,\n\t\t\tinput: tc.args,\n\t\t});\n\t}\n\n\t/**\n\t * Emit incremental tool call events from streaming chunks.\n\t *\n\t * Workers AI streams tool calls as:\n\t *   Chunk A: { id, type, index, function: { name } }                — start\n\t *   Chunk B: { index, function: { arguments: \"partial...\" } }       — args delta\n\t *   Chunk C: { index, function: { arguments: \"rest...\" } }          — args delta\n\t *   Chunk D: { id: null, type: null, function: { name: null } }     — finalize\n\t *\n\t * We emit tool-input-start on first sight, tool-input-delta for each\n\t * argument chunk, and tool-input-end eagerly — either when a new tool\n\t * index starts (closing the previous one) or on a null finalization\n\t * chunk. Any remaining open calls are closed in flush().\n\t */\n\tfunction emitToolCallDeltas(\n\t\ttoolCalls: Record<string, unknown>[],\n\t\tcontroller: TransformStreamDefaultController<LanguageModelV3StreamPart>,\n\t) {\n\t\tfor (const tc of toolCalls) {\n\t\t\tif (isNullFinalizationChunk(tc)) {\n\t\t\t\t// Null finalization sentinel — close the last active tool call\n\t\t\t\tif (lastActiveToolIndex != null) {\n\t\t\t\t\tcloseToolCall(lastActiveToolIndex, controller);\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tconst tcIndex = (tc.index as number) ?? 0;\n\t\t\tconst fn = tc.function as Record<string, unknown> | undefined;\n\t\t\tconst tcName = (fn?.name ?? tc.name ?? null) as string | null;\n\t\t\tconst tcArgs = (fn?.arguments ?? tc.arguments ?? null) as string | null;\n\t\t\tconst tcId = tc.id as string | null;\n\n\t\t\tif (!activeToolCalls.has(tcIndex)) {\n\t\t\t\t// A new tool call is starting — close the previous one first\n\t\t\t\tif (lastActiveToolIndex != null && lastActiveToolIndex !== tcIndex) {\n\t\t\t\t\tcloseToolCall(lastActiveToolIndex, controller);\n\t\t\t\t}\n\n\t\t\t\tconst id = createAISDKToolCallId(tcId);\n\t\t\t\tconst toolName = tcName || \"\";\n\t\t\t\tactiveToolCalls.set(tcIndex, { id, toolName, args: \"\" });\n\t\t\t\tlastActiveToolIndex = tcIndex;\n\t\t\t\tanyToolCallStarted = true;\n\n\t\t\t\tcontroller.enqueue({\n\t\t\t\t\ttype: \"tool-input-start\",\n\t\t\t\t\tid,\n\t\t\t\t\ttoolName,\n\t\t\t\t});\n\n\t\t\t\tif (tcArgs != null && tcArgs !== \"\") {\n\t\t\t\t\tconst delta = typeof tcArgs === \"string\" ? tcArgs : JSON.stringify(tcArgs);\n\t\t\t\t\tactiveToolCalls.get(tcIndex)!.args += delta;\n\t\t\t\t\tcontroller.enqueue({\n\t\t\t\t\t\ttype: \"tool-input-delta\",\n\t\t\t\t\t\tid,\n\t\t\t\t\t\tdelta,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tconst active = activeToolCalls.get(tcIndex)!;\n\t\t\t\tlastActiveToolIndex = tcIndex;\n\t\t\t\tif (tcArgs != null && tcArgs !== \"\") {\n\t\t\t\t\tconst delta = typeof tcArgs === \"string\" ? tcArgs : JSON.stringify(tcArgs);\n\t\t\t\t\tactive.args += delta;\n\t\t\t\t\tcontroller.enqueue({\n\t\t\t\t\t\ttype: \"tool-input-delta\",\n\t\t\t\t\t\tid: active.id,\n\t\t\t\t\t\tdelta,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n","import type { LanguageModelV3, SharedV3Warning } from \"@ai-sdk/provider\";\n\nimport type { AISearchChatSettings } from \"./aisearch-chat-settings\";\nimport { convertToWorkersAIChatMessages } from \"./convert-to-workersai-chat-messages\";\nimport { mapWorkersAIUsage } from \"./map-workersai-usage\";\nimport { getMappedStream, prependStreamStart } from \"./streaming\";\nimport { processToolCalls } from \"./utils\";\nimport type { TextGenerationModels } from \"./workersai-models\";\n\ntype AISearchChatConfig = {\n\tprovider: string;\n\tbinding: AutoRAG;\n\tgateway?: GatewayOptions;\n};\n\nexport class AISearchChatLanguageModel implements LanguageModelV3 {\n\treadonly specificationVersion = \"v3\";\n\treadonly defaultObjectGenerationMode = \"json\";\n\n\treadonly supportedUrls: Record<string, RegExp[]> | PromiseLike<Record<string, RegExp[]>> = {};\n\n\treadonly modelId: TextGenerationModels;\n\treadonly settings: AISearchChatSettings;\n\n\tprivate readonly config: AISearchChatConfig;\n\n\tconstructor(\n\t\tmodelId: TextGenerationModels,\n\t\tsettings: AISearchChatSettings,\n\t\tconfig: AISearchChatConfig,\n\t) {\n\t\tthis.modelId = modelId;\n\t\tthis.settings = settings;\n\t\tthis.config = config;\n\t}\n\n\tget provider(): string {\n\t\treturn this.config.provider;\n\t}\n\n\tprivate getWarnings({\n\t\ttools,\n\t\tfrequencyPenalty,\n\t\tpresencePenalty,\n\t\tresponseFormat,\n\t}: Parameters<LanguageModelV3[\"doGenerate\"]>[0]): SharedV3Warning[] {\n\t\tconst warnings: SharedV3Warning[] = [];\n\n\t\tif (tools != null && tools.length > 0) {\n\t\t\tconsole.warn(\n\t\t\t\t\"[workers-ai-provider] Tools are not supported by AI Search. They will be ignored.\",\n\t\t\t);\n\t\t\twarnings.push({ feature: \"tools\", type: \"unsupported\" });\n\t\t}\n\n\t\tif (frequencyPenalty != null) {\n\t\t\twarnings.push({ feature: \"frequencyPenalty\", type: \"unsupported\" });\n\t\t}\n\n\t\tif (presencePenalty != null) {\n\t\t\twarnings.push({ feature: \"presencePenalty\", type: \"unsupported\" });\n\t\t}\n\n\t\tif (responseFormat?.type === \"json\") {\n\t\t\twarnings.push({ feature: \"responseFormat\", type: \"unsupported\" });\n\t\t}\n\n\t\treturn warnings;\n\t}\n\n\t/**\n\t * Build the search query from messages.\n\t * Flattens the conversation into a single string for aiSearch.\n\t */\n\tprivate buildQuery(prompt: Parameters<LanguageModelV3[\"doGenerate\"]>[0][\"prompt\"]): string {\n\t\tconst { messages } = convertToWorkersAIChatMessages(prompt);\n\t\treturn messages.map(({ content, role }) => `${role}: ${content}`).join(\"\\n\\n\");\n\t}\n\n\tasync doGenerate(\n\t\toptions: Parameters<LanguageModelV3[\"doGenerate\"]>[0],\n\t): Promise<Awaited<ReturnType<LanguageModelV3[\"doGenerate\"]>>> {\n\t\tconst warnings = this.getWarnings(options);\n\t\tconst query = this.buildQuery(options.prompt);\n\n\t\tconst output = await this.config.binding.aiSearch({ query });\n\n\t\treturn {\n\t\t\tfinishReason: { unified: \"stop\", raw: \"stop\" },\n\t\t\tcontent: [\n\t\t\t\t...output.data.map(({ file_id, filename, score }) => ({\n\t\t\t\t\ttype: \"source\" as const,\n\t\t\t\t\tsourceType: \"url\" as const,\n\t\t\t\t\tid: file_id,\n\t\t\t\t\turl: filename,\n\t\t\t\t\tproviderMetadata: {\n\t\t\t\t\t\tattributes: { score },\n\t\t\t\t\t},\n\t\t\t\t})),\n\t\t\t\t{\n\t\t\t\t\ttype: \"text\" as const,\n\t\t\t\t\ttext: output.response,\n\t\t\t\t},\n\t\t\t\t...processToolCalls(output as unknown as Record<string, unknown>),\n\t\t\t],\n\t\t\tusage: mapWorkersAIUsage(output as unknown as Record<string, unknown>),\n\t\t\twarnings,\n\t\t};\n\t}\n\n\tasync doStream(\n\t\toptions: Parameters<LanguageModelV3[\"doStream\"]>[0],\n\t): Promise<Awaited<ReturnType<LanguageModelV3[\"doStream\"]>>> {\n\t\tconst warnings = this.getWarnings(options);\n\t\tconst query = this.buildQuery(options.prompt);\n\n\t\tconst response = await this.config.binding.aiSearch({\n\t\t\tquery,\n\t\t\tstream: true,\n\t\t});\n\n\t\treturn {\n\t\t\tstream: prependStreamStart(\n\t\t\t\tgetMappedStream(response as unknown as Response | ReadableStream<Uint8Array>),\n\t\t\t\twarnings,\n\t\t\t),\n\t\t};\n\t}\n}\n","import type {\n\tEmbeddingModelV3,\n\tEmbeddingModelV3CallOptions,\n\tEmbeddingModelV3Result,\n} from \"@ai-sdk/provider\";\nimport { TooManyEmbeddingValuesForCallError } from \"@ai-sdk/provider\";\nimport { normalizeBindingError } from \"./workersai-error\";\nimport type { EmbeddingModels } from \"./workersai-models\";\n\nexport type WorkersAIEmbeddingConfig = {\n\tprovider: string;\n\tbinding: Ai;\n\tgateway?: GatewayOptions;\n};\n\nexport type WorkersAIEmbeddingSettings = {\n\tgateway?: GatewayOptions;\n\tmaxEmbeddingsPerCall?: number;\n\tsupportsParallelCalls?: boolean;\n\n\t/**\n\t * Passthrough settings that are provided directly to the run function.\n\t */\n\t[key: string]: unknown;\n};\n\nexport class WorkersAIEmbeddingModel implements EmbeddingModelV3 {\n\treadonly specificationVersion = \"v3\";\n\treadonly modelId: EmbeddingModels;\n\tprivate readonly config: WorkersAIEmbeddingConfig;\n\tprivate readonly settings: WorkersAIEmbeddingSettings;\n\n\tget provider(): string {\n\t\treturn this.config.provider;\n\t}\n\n\tget maxEmbeddingsPerCall(): number {\n\t\t// https://developers.cloudflare.com/workers-ai/platform/limits/#text-embeddings\n\t\treturn this.settings.maxEmbeddingsPerCall ?? 3000;\n\t}\n\n\tget supportsParallelCalls(): boolean {\n\t\treturn this.settings.supportsParallelCalls ?? true;\n\t}\n\n\tconstructor(\n\t\tmodelId: EmbeddingModels,\n\t\tsettings: WorkersAIEmbeddingSettings,\n\t\tconfig: WorkersAIEmbeddingConfig,\n\t) {\n\t\tthis.modelId = modelId;\n\t\tthis.settings = settings;\n\t\tthis.config = config;\n\t}\n\n\tasync doEmbed({\n\t\tvalues,\n\t\tabortSignal,\n\t}: EmbeddingModelV3CallOptions): Promise<EmbeddingModelV3Result> {\n\t\tif (values.length > this.maxEmbeddingsPerCall) {\n\t\t\tthrow new TooManyEmbeddingValuesForCallError({\n\t\t\t\tmaxEmbeddingsPerCall: this.maxEmbeddingsPerCall,\n\t\t\t\tmodelId: this.modelId,\n\t\t\t\tprovider: this.provider,\n\t\t\t\tvalues,\n\t\t\t});\n\t\t}\n\n\t\tconst {\n\t\t\tgateway,\n\t\t\tmaxEmbeddingsPerCall: _maxEmbeddingsPerCall,\n\t\t\tsupportsParallelCalls: _supportsParallelCalls,\n\t\t\t...passthroughOptions\n\t\t} = this.settings;\n\n\t\tlet response: unknown;\n\t\ttry {\n\t\t\tresponse = await this.config.binding.run(\n\t\t\t\tthis.modelId as keyof AiModels,\n\t\t\t\t{\n\t\t\t\t\ttext: values,\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tgateway: this.config.gateway ?? gateway,\n\t\t\t\t\tsignal: abortSignal,\n\t\t\t\t\t...passthroughOptions,\n\t\t\t\t} as AiOptions,\n\t\t\t);\n\t\t} catch (error) {\n\t\t\t// Normalize binding failures (e.g. 3040 \"out of capacity\" → 429) into a\n\t\t\t// retryable APICallError so the AI SDK's maxRetries can engage.\n\t\t\tthrow normalizeBindingError(error, {\n\t\t\t\tmodel: this.modelId,\n\t\t\t\trequestBodyValues: { text: values },\n\t\t\t});\n\t\t}\n\n\t\treturn {\n\t\t\tembeddings: (response as { data: number[][] }).data,\n\t\t\twarnings: [],\n\t\t};\n\t}\n}\n","import type { LanguageModelV3, SharedV3Warning, LanguageModelV3StreamPart } from \"@ai-sdk/provider\";\nimport { generateId } from \"ai\";\nimport { convertToWorkersAIChatMessages } from \"./convert-to-workersai-chat-messages\";\nimport { mapWorkersAIFinishReason } from \"./map-workersai-finish-reason\";\nimport { mapWorkersAIUsage } from \"./map-workersai-usage\";\nimport { getMappedStream, prependStreamStart } from \"./streaming\";\nimport {\n\tbuildJsonSchemaPayload,\n\tnormalizeMessagesForBinding,\n\tprepareToolsAndToolChoice,\n\tprocessText,\n\tprocessToolCalls,\n\tsalvageToolCallsFromText,\n} from \"./utils\";\nimport type { WorkersAIChatSettings } from \"./workersai-chat-settings\";\nimport { normalizeBindingError } from \"./workersai-error\";\nimport type { TextGenerationModels } from \"./workersai-models\";\n\ntype WorkersAIChatConfig = {\n\tprovider: string;\n\tbinding: Ai;\n\tgateway?: GatewayOptions;\n\t/** True when using a real Workers AI binding (not the REST shim). */\n\tisBinding: boolean;\n};\n\nexport class WorkersAIChatLanguageModel implements LanguageModelV3 {\n\treadonly specificationVersion = \"v3\";\n\treadonly defaultObjectGenerationMode = \"json\";\n\n\treadonly supportedUrls: Record<string, RegExp[]> | PromiseLike<Record<string, RegExp[]>> = {};\n\n\treadonly modelId: TextGenerationModels;\n\treadonly settings: WorkersAIChatSettings;\n\n\tprivate readonly config: WorkersAIChatConfig;\n\n\tconstructor(\n\t\tmodelId: TextGenerationModels,\n\t\tsettings: WorkersAIChatSettings,\n\t\tconfig: WorkersAIChatConfig,\n\t) {\n\t\tthis.modelId = modelId;\n\t\tthis.settings = settings;\n\t\tthis.config = config;\n\t}\n\n\tget provider(): string {\n\t\treturn this.config.provider;\n\t}\n\n\tprivate getArgs({\n\t\tresponseFormat,\n\t\ttools,\n\t\ttoolChoice,\n\t\tmaxOutputTokens,\n\t\ttemperature,\n\t\ttopP,\n\t\tfrequencyPenalty,\n\t\tpresencePenalty,\n\t\tseed,\n\t}: Parameters<LanguageModelV3[\"doGenerate\"]>[0]) {\n\t\tconst type = responseFormat?.type ?? \"text\";\n\n\t\tconst warnings: SharedV3Warning[] = [];\n\n\t\tif (frequencyPenalty != null) {\n\t\t\twarnings.push({ feature: \"frequencyPenalty\", type: \"unsupported\" });\n\t\t}\n\n\t\tif (presencePenalty != null) {\n\t\t\twarnings.push({ feature: \"presencePenalty\", type: \"unsupported\" });\n\t\t}\n\n\t\tconst baseArgs = {\n\t\t\tmax_tokens: maxOutputTokens,\n\t\t\tmodel: this.modelId,\n\t\t\trandom_seed: seed,\n\t\t\tsafe_prompt: this.settings.safePrompt,\n\t\t\ttemperature,\n\t\t\ttop_p: topP,\n\t\t};\n\n\t\tswitch (type) {\n\t\t\tcase \"text\": {\n\t\t\t\treturn {\n\t\t\t\t\targs: {\n\t\t\t\t\t\t...baseArgs,\n\t\t\t\t\t\tresponse_format: undefined as\n\t\t\t\t\t\t\t| { type: string; json_schema?: unknown }\n\t\t\t\t\t\t\t| undefined,\n\t\t\t\t\t\t...prepareToolsAndToolChoice(tools, toolChoice),\n\t\t\t\t\t},\n\t\t\t\t\twarnings,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tcase \"json\": {\n\t\t\t\t// Native Workers AI expects a BARE JSON Schema under `json_schema`\n\t\t\t\t// (not OpenAI's `{ name, schema, strict }` envelope — partner models\n\t\t\t\t// that need that go through the gateway delegate, not this path). We\n\t\t\t\t// fold the AI SDK's `name`/`description` into the schema as `title`/\n\t\t\t\t// `description` so they aren't lost. See\n\t\t\t\t// https://github.com/cloudflare/ai/issues/559.\n\t\t\t\tconst json = responseFormat?.type === \"json\" ? responseFormat : undefined;\n\t\t\t\treturn {\n\t\t\t\t\targs: {\n\t\t\t\t\t\t...baseArgs,\n\t\t\t\t\t\tresponse_format: {\n\t\t\t\t\t\t\ttype: \"json_schema\",\n\t\t\t\t\t\t\tjson_schema: buildJsonSchemaPayload(\n\t\t\t\t\t\t\t\tjson?.schema,\n\t\t\t\t\t\t\t\tjson?.name,\n\t\t\t\t\t\t\t\tjson?.description,\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t},\n\t\t\t\t\t\ttools: undefined,\n\t\t\t\t\t\ttool_choice: undefined,\n\t\t\t\t\t},\n\t\t\t\t\twarnings,\n\t\t\t\t};\n\t\t\t}\n\n\t\t\tdefault: {\n\t\t\t\tconst exhaustiveCheck = type satisfies never;\n\t\t\t\tthrow new Error(`Unsupported type: ${exhaustiveCheck}`);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Build the inputs object for `binding.run()`, shared by doGenerate and doStream.\n\t *\n\t * Images are embedded inline in messages as OpenAI-compatible content\n\t * arrays with `image_url` parts. Both the REST API and the binding\n\t * accept this format at runtime.\n\t *\n\t * The binding path additionally normalises null content to empty strings.\n\t *\n\t * Reasoning controls (`reasoning_effort`, `chat_template_kwargs`) are\n\t * forwarded here from settings. These belong on the INPUTS object, not on\n\t * the 3rd-arg options / REST query string — see\n\t * https://github.com/cloudflare/ai/issues/501. Per-call values from\n\t * `providerOptions[\"workers-ai\"]` override settings.\n\t *\n\t * `reasoning_effort: null` is a valid value (\"disable reasoning\"), so we\n\t * check `!== undefined` rather than truthiness.\n\t */\n\tprivate buildRunInputs(\n\t\targs: ReturnType<typeof this.getArgs>[\"args\"],\n\t\tmessages: ReturnType<typeof convertToWorkersAIChatMessages>[\"messages\"],\n\t\toptions?: { stream?: boolean; providerOptions?: Record<string, unknown> },\n\t) {\n\t\t// The AI SDK types this as `Record<string, JSONObject>` but we defensively\n\t\t// accept anything and only treat it as a lookup if it's a plain object.\n\t\t// `\"key\" in x` throws for primitives, so we can't skip the typeof guard.\n\t\tconst rawPerCall = options?.providerOptions?.[\"workers-ai\"];\n\t\tconst perCall: Record<string, unknown> =\n\t\t\trawPerCall !== null && typeof rawPerCall === \"object\" && !Array.isArray(rawPerCall)\n\t\t\t\t? (rawPerCall as Record<string, unknown>)\n\t\t\t\t: {};\n\t\tconst reasoningEffort =\n\t\t\t\"reasoning_effort\" in perCall\n\t\t\t\t? perCall.reasoning_effort\n\t\t\t\t: this.settings.reasoning_effort;\n\t\tconst chatTemplateKwargs =\n\t\t\t\"chat_template_kwargs\" in perCall\n\t\t\t\t? perCall.chat_template_kwargs\n\t\t\t\t: this.settings.chat_template_kwargs;\n\n\t\treturn {\n\t\t\tmax_tokens: args.max_tokens,\n\t\t\tmessages: this.config.isBinding ? normalizeMessagesForBinding(messages) : messages,\n\t\t\ttemperature: args.temperature,\n\t\t\ttools: args.tools,\n\t\t\t...(args.tool_choice ? { tool_choice: args.tool_choice } : {}),\n\t\t\ttop_p: args.top_p,\n\t\t\t...(args.response_format ? { response_format: args.response_format } : {}),\n\t\t\t...(options?.stream ? { stream: true } : {}),\n\t\t\t...(reasoningEffort !== undefined ? { reasoning_effort: reasoningEffort } : {}),\n\t\t\t...(chatTemplateKwargs !== undefined\n\t\t\t\t? { chat_template_kwargs: chatTemplateKwargs }\n\t\t\t\t: {}),\n\t\t};\n\t}\n\n\t/**\n\t * Get passthrough options for binding.run() from settings.\n\t *\n\t * `reasoning_effort` and `chat_template_kwargs` are explicitly excluded\n\t * here — they belong on the `inputs` object (see `buildRunInputs`), not on\n\t * the `options` (3rd) arg of binding.run() or the REST query string.\n\t */\n\tprivate getRunOptions() {\n\t\tconst {\n\t\t\tgateway,\n\t\t\tsafePrompt: _safePrompt,\n\t\t\tsessionAffinity,\n\t\t\textraHeaders,\n\t\t\treasoning_effort: _reasoningEffort,\n\t\t\tchat_template_kwargs: _chatTemplateKwargs,\n\t\t\t...passthroughOptions\n\t\t} = this.settings;\n\n\t\tconst mergedHeaders = {\n\t\t\t...(extraHeaders && typeof extraHeaders === \"object\"\n\t\t\t\t? (extraHeaders as Record<string, string>)\n\t\t\t\t: {}),\n\t\t\t...(sessionAffinity ? { \"x-session-affinity\": sessionAffinity } : {}),\n\t\t};\n\n\t\treturn {\n\t\t\tgateway: this.config.gateway ?? gateway,\n\t\t\t...(Object.keys(mergedHeaders).length > 0 ? { extraHeaders: mergedHeaders } : {}),\n\t\t\t...passthroughOptions,\n\t\t};\n\t}\n\n\t/**\n\t * Extract reasoning, text, and tool calls from a non-streaming response.\n\t *\n\t * Shared by `doGenerate` and `doStream`'s graceful-degradation branch (the\n\t * path gpt-oss falls through, since it doesn't support `/ai/run/` streaming\n\t * and is retried non-streaming). When a forced tool call was leaked into\n\t * text content (gpt-oss harmony quirk), it is salvaged into a structured\n\t * tool call and the leaked JSON text is suppressed. A warning is appended in\n\t * place so callers can observe the reinterpretation.\n\t */\n\tprivate extractContent(\n\t\toutputRecord: Record<string, unknown>,\n\t\targs: ReturnType<typeof this.getArgs>[\"args\"],\n\t\twarnings: SharedV3Warning[],\n\t) {\n\t\tconst choices = outputRecord.choices as\n\t\t\t| Array<{ message?: { reasoning_content?: string; reasoning?: string } }>\n\t\t\t| undefined;\n\t\tconst reasoningContent =\n\t\t\tchoices?.[0]?.message?.reasoning_content ?? choices?.[0]?.message?.reasoning;\n\n\t\tconst toolCalls = processToolCalls(outputRecord);\n\t\tconst salvaged =\n\t\t\ttoolCalls.length === 0\n\t\t\t\t? salvageToolCallsFromText(outputRecord, {\n\t\t\t\t\t\ttools: args.tools,\n\t\t\t\t\t\ttoolChoice: args.tool_choice,\n\t\t\t\t\t})\n\t\t\t\t: null;\n\n\t\tif (salvaged) {\n\t\t\twarnings.push({\n\t\t\t\ttype: \"other\",\n\t\t\t\tmessage: `Recovered ${salvaged.length} forced tool call(s) that the model emitted as text content instead of structured tool calls (model: ${this.modelId}).`,\n\t\t\t});\n\t\t}\n\n\t\treturn {\n\t\t\treasoningContent,\n\t\t\t// Suppress the leaked JSON text when we salvaged a tool call from it.\n\t\t\ttext: salvaged ? \"\" : (processText(outputRecord) ?? \"\"),\n\t\t\ttoolCalls: salvaged ?? toolCalls,\n\t\t\t// When salvaged, the upstream finish_reason is \"stop\"; report\n\t\t\t// \"tool-calls\" so the response is indistinguishable from a native\n\t\t\t// tool call and the agentic loop continues correctly.\n\t\t\tfinishReason: salvaged\n\t\t\t\t? ({ unified: \"tool-calls\", raw: \"stop\" } as const)\n\t\t\t\t: mapWorkersAIFinishReason(outputRecord),\n\t\t};\n\t}\n\n\tasync doGenerate(\n\t\toptions: Parameters<LanguageModelV3[\"doGenerate\"]>[0],\n\t): Promise<Awaited<ReturnType<LanguageModelV3[\"doGenerate\"]>>> {\n\t\tconst { args, warnings } = this.getArgs(options);\n\t\tconst { messages } = convertToWorkersAIChatMessages(options.prompt);\n\n\t\tconst inputs = this.buildRunInputs(args, messages, {\n\t\t\tproviderOptions: options.providerOptions,\n\t\t});\n\t\tconst runOptions = this.getRunOptions();\n\n\t\tlet output: unknown;\n\t\ttry {\n\t\t\toutput = await this.config.binding.run(\n\t\t\t\targs.model as keyof AiModels,\n\t\t\t\tinputs as AiModels[keyof AiModels][\"inputs\"],\n\t\t\t\t{\n\t\t\t\t\t...runOptions,\n\t\t\t\t\tsignal: options.abortSignal,\n\t\t\t\t} as AiOptions,\n\t\t\t);\n\t\t} catch (error) {\n\t\t\t// Normalize binding failures (e.g. 3040 \"out of capacity\" → 429) into a\n\t\t\t// retryable APICallError so the AI SDK's maxRetries can engage.\n\t\t\tthrow normalizeBindingError(error, {\n\t\t\t\tmodel: args.model,\n\t\t\t\trequestBodyValues: inputs,\n\t\t\t});\n\t\t}\n\n\t\tif (output instanceof ReadableStream) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Unexpected streaming response from non-streaming request. Check that `stream: true` was not passed.\",\n\t\t\t);\n\t\t}\n\n\t\tconst outputRecord = output as Record<string, unknown>;\n\t\tconst { reasoningContent, text, toolCalls, finishReason } = this.extractContent(\n\t\t\toutputRecord,\n\t\t\targs,\n\t\t\twarnings,\n\t\t);\n\n\t\treturn {\n\t\t\tfinishReason,\n\t\t\tcontent: [\n\t\t\t\t...(reasoningContent\n\t\t\t\t\t? [{ type: \"reasoning\" as const, text: reasoningContent }]\n\t\t\t\t\t: []),\n\t\t\t\t{ type: \"text\" as const, text },\n\t\t\t\t...toolCalls,\n\t\t\t],\n\t\t\tusage: mapWorkersAIUsage(output as Record<string, unknown>),\n\t\t\twarnings,\n\t\t};\n\t}\n\n\tasync doStream(\n\t\toptions: Parameters<LanguageModelV3[\"doStream\"]>[0],\n\t): Promise<Awaited<ReturnType<LanguageModelV3[\"doStream\"]>>> {\n\t\tconst { args, warnings } = this.getArgs(options);\n\t\tconst { messages } = convertToWorkersAIChatMessages(options.prompt);\n\n\t\tconst inputs = this.buildRunInputs(args, messages, {\n\t\t\tstream: true,\n\t\t\tproviderOptions: options.providerOptions,\n\t\t});\n\t\tconst runOptions = this.getRunOptions();\n\n\t\tlet response: unknown;\n\t\ttry {\n\t\t\tresponse = await this.config.binding.run(\n\t\t\t\targs.model as keyof AiModels,\n\t\t\t\tinputs as AiModels[keyof AiModels][\"inputs\"],\n\t\t\t\t{\n\t\t\t\t\t...runOptions,\n\t\t\t\t\tsignal: options.abortSignal,\n\t\t\t\t} as AiOptions,\n\t\t\t);\n\t\t} catch (error) {\n\t\t\t// Normalize binding failures (e.g. 3040 \"out of capacity\" → 429) into a\n\t\t\t// retryable APICallError so the AI SDK's maxRetries can engage.\n\t\t\tthrow normalizeBindingError(error, {\n\t\t\t\tmodel: args.model,\n\t\t\t\trequestBodyValues: inputs,\n\t\t\t});\n\t\t}\n\n\t\t// If the binding returned a stream, pipe it through the SSE mapper\n\t\tif (response instanceof ReadableStream) {\n\t\t\treturn {\n\t\t\t\tstream: prependStreamStart(\n\t\t\t\t\tgetMappedStream(response, {\n\t\t\t\t\t\ttools: args.tools,\n\t\t\t\t\t\ttoolChoice: args.tool_choice,\n\t\t\t\t\t}),\n\t\t\t\t\twarnings,\n\t\t\t\t),\n\t\t\t};\n\t\t}\n\n\t\t// Graceful degradation: some models return a non-streaming response even\n\t\t// when stream:true is requested. Wrap the complete response as a stream.\n\t\tconst outputRecord = response as Record<string, unknown>;\n\t\tconst { reasoningContent, text, toolCalls, finishReason } = this.extractContent(\n\t\t\toutputRecord,\n\t\t\targs,\n\t\t\twarnings,\n\t\t);\n\n\t\tlet textId: string | null = null;\n\t\tlet reasoningId: string | null = null;\n\n\t\treturn {\n\t\t\tstream: new ReadableStream<LanguageModelV3StreamPart>({\n\t\t\t\tstart(controller) {\n\t\t\t\t\tcontroller.enqueue({\n\t\t\t\t\t\ttype: \"stream-start\",\n\t\t\t\t\t\twarnings: warnings as SharedV3Warning[],\n\t\t\t\t\t});\n\n\t\t\t\t\tif (reasoningContent) {\n\t\t\t\t\t\treasoningId = generateId();\n\t\t\t\t\t\tcontroller.enqueue({ type: \"reasoning-start\", id: reasoningId });\n\t\t\t\t\t\tcontroller.enqueue({\n\t\t\t\t\t\t\ttype: \"reasoning-delta\",\n\t\t\t\t\t\t\tid: reasoningId,\n\t\t\t\t\t\t\tdelta: reasoningContent,\n\t\t\t\t\t\t});\n\t\t\t\t\t\tcontroller.enqueue({ type: \"reasoning-end\", id: reasoningId });\n\t\t\t\t\t}\n\n\t\t\t\t\tif (text) {\n\t\t\t\t\t\ttextId = generateId();\n\t\t\t\t\t\tcontroller.enqueue({ type: \"text-start\", id: textId });\n\t\t\t\t\t\tcontroller.enqueue({ type: \"text-delta\", id: textId, delta: text });\n\t\t\t\t\t\tcontroller.enqueue({ type: \"text-end\", id: textId });\n\t\t\t\t\t}\n\n\t\t\t\t\tfor (const toolCall of toolCalls) {\n\t\t\t\t\t\tcontroller.enqueue(toolCall);\n\t\t\t\t\t}\n\n\t\t\t\t\tcontroller.enqueue({\n\t\t\t\t\t\ttype: \"finish\",\n\t\t\t\t\t\tfinishReason,\n\t\t\t\t\t\tusage: mapWorkersAIUsage(response as Record<string, unknown>),\n\t\t\t\t\t});\n\t\t\t\t\tcontroller.close();\n\t\t\t\t},\n\t\t\t}),\n\t\t};\n\t}\n}\n","import type { ImageModelV3, SharedV3Warning } from \"@ai-sdk/provider\";\nimport { normalizeBindingError } from \"./workersai-error\";\nimport type { WorkersAIImageSettings } from \"./workersai-image-settings\";\nimport type { ImageGenerationModels } from \"./workersai-models\";\n\nexport type WorkersAIImageConfig = {\n\tprovider: string;\n\tbinding: Ai;\n\tgateway?: GatewayOptions;\n};\n\nexport class WorkersAIImageModel implements ImageModelV3 {\n\treadonly specificationVersion = \"v3\";\n\n\tget maxImagesPerCall(): number {\n\t\treturn this.settings.maxImagesPerCall ?? 1;\n\t}\n\n\tget provider(): string {\n\t\treturn this.config.provider;\n\t}\n\n\tconstructor(\n\t\treadonly modelId: ImageGenerationModels,\n\t\treadonly settings: WorkersAIImageSettings,\n\t\treadonly config: WorkersAIImageConfig,\n\t) {}\n\n\tasync doGenerate({\n\t\tprompt,\n\t\tn,\n\t\tsize,\n\t\taspectRatio,\n\t\tseed,\n\t\tabortSignal,\n\t}: Parameters<ImageModelV3[\"doGenerate\"]>[0]): Promise<\n\t\tAwaited<ReturnType<ImageModelV3[\"doGenerate\"]>>\n\t> {\n\t\tconst { width, height } = getDimensionsFromSizeString(size);\n\n\t\tconst warnings: Array<SharedV3Warning> = [];\n\n\t\tif (aspectRatio != null) {\n\t\t\twarnings.push({\n\t\t\t\tdetails: \"This model does not support aspect ratio. Use `size` instead.\",\n\t\t\t\tfeature: \"aspectRatio\",\n\t\t\t\ttype: \"unsupported\",\n\t\t\t});\n\t\t}\n\n\t\tconst generateImage = async () => {\n\t\t\tconst inputs = {\n\t\t\t\theight,\n\t\t\t\tprompt: prompt ?? \"\",\n\t\t\t\tseed,\n\t\t\t\twidth,\n\t\t\t};\n\t\t\tlet output: unknown;\n\t\t\ttry {\n\t\t\t\toutput = (await this.config.binding.run(this.modelId as keyof AiModels, inputs, {\n\t\t\t\t\tgateway: this.config.gateway,\n\t\t\t\t\tsignal: abortSignal,\n\t\t\t\t} as AiOptions)) as unknown;\n\t\t\t} catch (error) {\n\t\t\t\t// Normalize binding failures (e.g. 3040 \"out of capacity\" → 429) into\n\t\t\t\t// a retryable APICallError so the AI SDK's maxRetries can engage.\n\t\t\t\tthrow normalizeBindingError(error, {\n\t\t\t\t\tmodel: this.modelId,\n\t\t\t\t\trequestBodyValues: inputs,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn toUint8Array(output);\n\t\t};\n\n\t\tconst images: Uint8Array[] = await Promise.all(\n\t\t\tArray.from({ length: n }, () => generateImage()),\n\t\t);\n\n\t\treturn {\n\t\t\timages,\n\t\t\tresponse: {\n\t\t\t\theaders: {},\n\t\t\t\tmodelId: this.modelId,\n\t\t\t\ttimestamp: new Date(),\n\t\t\t},\n\t\t\twarnings,\n\t\t};\n\t}\n}\n\nfunction getDimensionsFromSizeString(size: string | undefined) {\n\tconst [width, height] = size?.split(\"x\") ?? [undefined, undefined];\n\n\treturn {\n\t\theight: parseInteger(height),\n\t\twidth: parseInteger(width),\n\t};\n}\n\nfunction parseInteger(value?: string) {\n\tif (value === \"\" || !value) return undefined;\n\tconst number = Number(value);\n\treturn Number.isInteger(number) ? number : undefined;\n}\n\n/**\n * Convert various output types from binding.run() to Uint8Array.\n * Workers AI image models return different types depending on the runtime:\n * - ReadableStream<Uint8Array> (most common in workerd)\n * - Uint8Array / ArrayBuffer (direct binary)\n * - Response (needs .arrayBuffer())\n * - { image: string } with base64 data\n */\nasync function toUint8Array(output: unknown): Promise<Uint8Array> {\n\tif (output instanceof Uint8Array) {\n\t\treturn output;\n\t}\n\tif (output instanceof ArrayBuffer) {\n\t\treturn new Uint8Array(output);\n\t}\n\tif (output instanceof ReadableStream) {\n\t\tconst reader = (output as ReadableStream<Uint8Array>).getReader();\n\t\tconst chunks: Uint8Array[] = [];\n\t\tlet totalLength = 0;\n\t\twhile (true) {\n\t\t\tconst { done, value } = await reader.read();\n\t\t\tif (done) break;\n\t\t\tchunks.push(value);\n\t\t\ttotalLength += value.length;\n\t\t}\n\t\tconst result = new Uint8Array(totalLength);\n\t\tlet offset = 0;\n\t\tfor (const chunk of chunks) {\n\t\t\tresult.set(chunk, offset);\n\t\t\toffset += chunk.length;\n\t\t}\n\t\treturn result;\n\t}\n\t// Response object (e.g., from REST shim)\n\tif (output instanceof Response) {\n\t\treturn new Uint8Array(await output.arrayBuffer());\n\t}\n\t// Object with binary-like properties\n\tif (typeof output === \"object\" && output !== null) {\n\t\tconst obj = output as Record<string, unknown>;\n\t\t// { image: base64string }\n\t\tif (typeof obj.image === \"string\") {\n\t\t\treturn Uint8Array.from(atob(obj.image), (c) => c.charCodeAt(0));\n\t\t}\n\t\t// { data: Uint8Array }\n\t\tif (obj.data instanceof Uint8Array) {\n\t\t\treturn obj.data;\n\t\t}\n\t\t// { data: ArrayBuffer }\n\t\tif (obj.data instanceof ArrayBuffer) {\n\t\t\treturn new Uint8Array(obj.data);\n\t\t}\n\t\t// Try to get a body if it looks response-like\n\t\tif (typeof obj.arrayBuffer === \"function\") {\n\t\t\treturn new Uint8Array(await (obj as unknown as Response).arrayBuffer());\n\t\t}\n\t}\n\tthrow new Error(\n\t\t`Unexpected output type from image model. Got ${Object.prototype.toString.call(output)} with keys: ${\n\t\t\ttypeof output === \"object\" && output !== null\n\t\t\t\t? JSON.stringify(Object.keys(output))\n\t\t\t\t: \"N/A\"\n\t\t}`,\n\t);\n}\n","import type { TranscriptionModelV3, SharedV3Warning } from \"@ai-sdk/provider\";\nimport type { WorkersAITranscriptionSettings } from \"./workersai-transcription-settings\";\nimport type { TranscriptionModels } from \"./workersai-models\";\nimport { createRunBinary, type CreateRunConfig } from \"./utils\";\nimport { normalizeBindingError } from \"./workersai-error\";\n\nexport type WorkersAITranscriptionConfig = {\n\tprovider: string;\n\tbinding: Ai;\n\tgateway?: GatewayOptions;\n\t/**\n\t * Whether the binding is a real `env.AI` binding (true) or a REST shim (false).\n\t * Nova-3 uses different upload paths depending on this.\n\t */\n\tisBinding: boolean;\n\t/**\n\t * REST credentials, only set when `isBinding` is false.\n\t * Needed for Nova-3 which requires binary upload, bypassing the JSON-based REST shim.\n\t */\n\tcredentials?: CreateRunConfig;\n};\n\n/**\n * Workers AI transcription model implementing the AI SDK's `TranscriptionModelV3` interface.\n *\n * Supports:\n * - Whisper models (`@cf/openai/whisper`, `whisper-tiny-en`, `whisper-large-v3-turbo`)\n * - Deepgram Nova-3 (`@cf/deepgram/nova-3`) — uses a different input/output format\n */\nexport class WorkersAITranscriptionModel implements TranscriptionModelV3 {\n\treadonly specificationVersion = \"v3\";\n\n\tget provider(): string {\n\t\treturn this.config.provider;\n\t}\n\n\tconstructor(\n\t\treadonly modelId: TranscriptionModels,\n\t\treadonly settings: WorkersAITranscriptionSettings,\n\t\treadonly config: WorkersAITranscriptionConfig,\n\t) {}\n\n\tasync doGenerate(\n\t\toptions: Parameters<TranscriptionModelV3[\"doGenerate\"]>[0],\n\t): Promise<Awaited<ReturnType<TranscriptionModelV3[\"doGenerate\"]>>> {\n\t\tconst { audio, mediaType, abortSignal } = options;\n\n\t\tconst warnings: Array<SharedV3Warning> = [];\n\n\t\t// The AI SDK always converts audio to Uint8Array via\n\t\t// convertDataContentToUint8Array before calling doGenerate.\n\t\tconst audioBytes =\n\t\t\ttypeof audio === \"string\"\n\t\t\t\t? Uint8Array.from(atob(audio), (c) => c.charCodeAt(0))\n\t\t\t\t: audio;\n\n\t\tconst isNova3 = this.modelId === \"@cf/deepgram/nova-3\";\n\n\t\tlet rawResult: unknown;\n\n\t\ttry {\n\t\t\tif (isNova3) {\n\t\t\t\trawResult = await this.runNova3(audioBytes, mediaType, abortSignal);\n\t\t\t} else {\n\t\t\t\trawResult = await this.runWhisper(audioBytes, abortSignal);\n\t\t\t}\n\t\t} catch (error) {\n\t\t\t// Normalize binding failures (e.g. 3040 \"out of capacity\" → 429) into a\n\t\t\t// retryable APICallError so the AI SDK's maxRetries can engage. The\n\t\t\t// REST binary path already throws an APICallError, which passes through.\n\t\t\tthrow normalizeBindingError(error, {\n\t\t\t\tmodel: this.modelId,\n\t\t\t\trequestBodyValues: { mediaType },\n\t\t\t});\n\t\t}\n\n\t\tconst result = rawResult as Record<string, unknown>;\n\n\t\t// Normalize response into AI SDK format\n\t\tif (isNova3) {\n\t\t\treturn this.normalizeNova3Response(result, warnings);\n\t\t}\n\t\treturn this.normalizeWhisperResponse(result, warnings);\n\t}\n\n\t// ---------------------------------------------------------------------------\n\t// Whisper models\n\t// ---------------------------------------------------------------------------\n\n\tprivate async runWhisper(audioBytes: Uint8Array, abortSignal?: AbortSignal): Promise<unknown> {\n\t\t// whisper-large-v3-turbo requires base64 audio (both binding and REST).\n\t\t// Other Whisper models accept number[].\n\t\tconst modelStr = this.modelId as string;\n\t\tconst audio =\n\t\t\tmodelStr === \"@cf/openai/whisper-large-v3-turbo\"\n\t\t\t\t? uint8ArrayToBase64(audioBytes)\n\t\t\t\t: Array.from(audioBytes);\n\n\t\tconst inputs: Record<string, unknown> = { audio };\n\n\t\tif (this.settings.language) {\n\t\t\tinputs.language = this.settings.language;\n\t\t}\n\t\tif (this.settings.prompt) {\n\t\t\tinputs.initial_prompt = this.settings.prompt;\n\t\t}\n\n\t\treturn this.config.binding.run(\n\t\t\tthis.modelId as Parameters<Ai[\"run\"]>[0],\n\t\t\tinputs as Parameters<Ai[\"run\"]>[1],\n\t\t\t{ gateway: this.config.gateway, signal: abortSignal } as AiOptions,\n\t\t);\n\t}\n\n\tprivate normalizeWhisperResponse(\n\t\traw: Record<string, unknown>,\n\t\twarnings: Array<SharedV3Warning>,\n\t): Awaited<ReturnType<TranscriptionModelV3[\"doGenerate\"]>> {\n\t\tconst text = (raw.text as string) ?? \"\";\n\n\t\t// Build segments from Whisper's various formats\n\t\tconst segments: Array<{ text: string; startSecond: number; endSecond: number }> = [];\n\n\t\t// whisper-large-v3-turbo returns segments[]\n\t\tif (raw.segments && Array.isArray(raw.segments)) {\n\t\t\tfor (const seg of raw.segments) {\n\t\t\t\tsegments.push({\n\t\t\t\t\ttext: ((seg as Record<string, unknown>).text as string) ?? \"\",\n\t\t\t\t\tstartSecond: ((seg as Record<string, unknown>).start as number) ?? 0,\n\t\t\t\t\tendSecond: ((seg as Record<string, unknown>).end as number) ?? 0,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\t// basic whisper returns words[]\n\t\telse if (raw.words && Array.isArray(raw.words)) {\n\t\t\tfor (const w of raw.words) {\n\t\t\t\tsegments.push({\n\t\t\t\t\ttext: ((w as Record<string, unknown>).word as string) ?? \"\",\n\t\t\t\t\tstartSecond: ((w as Record<string, unknown>).start as number) ?? 0,\n\t\t\t\t\tendSecond: ((w as Record<string, unknown>).end as number) ?? 0,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t// Language and duration from transcription_info (v3-turbo)\n\t\tconst info = raw.transcription_info as Record<string, unknown> | undefined;\n\n\t\treturn {\n\t\t\ttext,\n\t\t\tsegments,\n\t\t\tlanguage: (info?.language as string) ?? undefined,\n\t\t\tdurationInSeconds: (info?.duration as number) ?? undefined,\n\t\t\twarnings,\n\t\t\tresponse: {\n\t\t\t\ttimestamp: new Date(),\n\t\t\t\tmodelId: this.modelId,\n\t\t\t\theaders: {},\n\t\t\t},\n\t\t};\n\t}\n\n\t// ---------------------------------------------------------------------------\n\t// Deepgram Nova-3\n\t// ---------------------------------------------------------------------------\n\n\tprivate async runNova3(\n\t\taudioBytes: Uint8Array,\n\t\tmediaType: string,\n\t\tabortSignal?: AbortSignal,\n\t): Promise<unknown> {\n\t\tif (this.config.isBinding) {\n\t\t\t// Binding path: Nova-3 accepts { audio: { body: base64, contentType } }\n\t\t\treturn this.config.binding.run(\n\t\t\t\tthis.modelId as Parameters<Ai[\"run\"]>[0],\n\t\t\t\t{\n\t\t\t\t\taudio: { body: uint8ArrayToBase64(audioBytes), contentType: mediaType },\n\t\t\t\t} as Parameters<Ai[\"run\"]>[1],\n\t\t\t\t{ gateway: this.config.gateway, signal: abortSignal } as AiOptions,\n\t\t\t);\n\t\t}\n\n\t\t// REST path: Nova-3 requires raw binary with a Content-Type header,\n\t\t// not JSON. The createRun shim always sends JSON, so we bypass it\n\t\t// and use createRunBinary which sends the audio bytes directly.\n\t\tif (!this.config.credentials) {\n\t\t\tthrow new Error(\n\t\t\t\t\"Nova-3 transcription via REST requires credentials in the config. \" +\n\t\t\t\t\t\"This is a bug — credentials should have been set by createWorkersAI.\",\n\t\t\t);\n\t\t}\n\t\treturn createRunBinary(\n\t\t\tthis.config.credentials,\n\t\t\tthis.modelId,\n\t\t\taudioBytes,\n\t\t\tmediaType,\n\t\t\tabortSignal,\n\t\t);\n\t}\n\n\tprivate normalizeNova3Response(\n\t\traw: Record<string, unknown>,\n\t\twarnings: Array<SharedV3Warning>,\n\t): Awaited<ReturnType<TranscriptionModelV3[\"doGenerate\"]>> {\n\t\t// Nova-3 format: { results: { channels: [{ alternatives: [{ transcript, words }] }] } }\n\t\tconst results = raw.results as Record<string, unknown> | undefined;\n\t\tconst channels = results?.channels as\n\t\t\t| Array<{\n\t\t\t\t\talternatives?: Array<{\n\t\t\t\t\t\ttranscript?: string;\n\t\t\t\t\t\tconfidence?: number;\n\t\t\t\t\t\twords?: Array<{ word: string; start: number; end: number }>;\n\t\t\t\t\t}>;\n\t\t\t  }>\n\t\t\t| undefined;\n\t\tconst alt = channels?.[0]?.alternatives?.[0];\n\n\t\tconst text = alt?.transcript ?? \"\";\n\t\tconst segments: Array<{ text: string; startSecond: number; endSecond: number }> = [];\n\n\t\tif (alt?.words && Array.isArray(alt.words)) {\n\t\t\tfor (const w of alt.words) {\n\t\t\t\tsegments.push({\n\t\t\t\t\ttext: w.word ?? \"\",\n\t\t\t\t\tstartSecond: w.start ?? 0,\n\t\t\t\t\tendSecond: w.end ?? 0,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\ttext,\n\t\t\tsegments,\n\t\t\tlanguage: undefined,\n\t\t\tdurationInSeconds: undefined,\n\t\t\twarnings,\n\t\t\tresponse: {\n\t\t\t\ttimestamp: new Date(),\n\t\t\t\tmodelId: this.modelId,\n\t\t\t\theaders: {},\n\t\t\t},\n\t\t};\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction uint8ArrayToBase64(bytes: Uint8Array): string {\n\tlet binary = \"\";\n\tfor (let i = 0; i < bytes.length; i++) {\n\t\tbinary += String.fromCharCode(bytes[i]!);\n\t}\n\treturn btoa(binary);\n}\n","import type { SpeechModelV3, SharedV3Warning } from \"@ai-sdk/provider\";\nimport { apiCallErrorFromResponse, normalizeBindingError } from \"./workersai-error\";\nimport type { WorkersAISpeechSettings } from \"./workersai-speech-settings\";\nimport type { SpeechModels } from \"./workersai-models\";\n\nexport type WorkersAISpeechConfig = {\n\tprovider: string;\n\tbinding: Ai;\n\tgateway?: GatewayOptions;\n};\n\n/**\n * Workers AI speech (text-to-speech) model implementing the AI SDK's `SpeechModelV3` interface.\n *\n * Currently supports Deepgram Aura-1 (`@cf/deepgram/aura-1`).\n * The model accepts `{ text, voice?, speed? }` and returns raw audio bytes.\n */\nexport class WorkersAISpeechModel implements SpeechModelV3 {\n\treadonly specificationVersion = \"v3\";\n\n\tget provider(): string {\n\t\treturn this.config.provider;\n\t}\n\n\tconstructor(\n\t\treadonly modelId: SpeechModels,\n\t\treadonly settings: WorkersAISpeechSettings,\n\t\treadonly config: WorkersAISpeechConfig,\n\t) {}\n\n\tasync doGenerate(\n\t\toptions: Parameters<SpeechModelV3[\"doGenerate\"]>[0],\n\t): Promise<Awaited<ReturnType<SpeechModelV3[\"doGenerate\"]>>> {\n\t\tconst { text, voice, speed, abortSignal } = options;\n\n\t\tconst warnings: Array<SharedV3Warning> = [];\n\n\t\tif (options.instructions) {\n\t\t\twarnings.push({\n\t\t\t\tdetails: \"Workers AI TTS models do not support instructions.\",\n\t\t\t\tfeature: \"instructions\",\n\t\t\t\ttype: \"unsupported\",\n\t\t\t});\n\t\t}\n\n\t\tif (options.outputFormat) {\n\t\t\twarnings.push({\n\t\t\t\tdetails:\n\t\t\t\t\t\"Workers AI TTS models do not support output format selection. Audio is returned as MP3.\",\n\t\t\t\tfeature: \"outputFormat\",\n\t\t\t\ttype: \"unsupported\",\n\t\t\t});\n\t\t}\n\n\t\t// Build inputs for Workers AI TTS\n\t\tconst inputs: Record<string, unknown> = { text };\n\t\tif (voice) inputs.voice = voice;\n\t\tif (speed != null) inputs.speed = speed;\n\n\t\tlet result: unknown;\n\t\ttry {\n\t\t\tresult = await this.config.binding.run(\n\t\t\t\tthis.modelId as Parameters<Ai[\"run\"]>[0],\n\t\t\t\tinputs as Parameters<Ai[\"run\"]>[1],\n\t\t\t\t{\n\t\t\t\t\tgateway: this.config.gateway,\n\t\t\t\t\tsignal: abortSignal,\n\t\t\t\t\t// returnRawResponse prevents the createRun REST shim from trying\n\t\t\t\t\t// to JSON.parse binary audio. Real env.AI bindings don't recognize\n\t\t\t\t\t// this option — it has no effect, and the binding returns the normal\n\t\t\t\t\t// binary result (Uint8Array/ReadableStream) which toUint8Array handles.\n\t\t\t\t\treturnRawResponse: true,\n\t\t\t\t} as AiOptions,\n\t\t\t);\n\t\t} catch (error) {\n\t\t\t// Normalize binding failures (e.g. 3040 \"out of capacity\" → 429) into a\n\t\t\t// retryable APICallError so the AI SDK's maxRetries can engage.\n\t\t\tthrow normalizeBindingError(error, {\n\t\t\t\tmodel: this.modelId,\n\t\t\t\trequestBodyValues: inputs,\n\t\t\t});\n\t\t}\n\n\t\t// The REST shim uses `returnRawResponse`, so it does NOT throw on a non-OK\n\t\t// status — it hands back the raw Response. Without this guard the error body\n\t\t// would be decoded as \"audio\". Surface it as a (retryable-aware) APICallError.\n\t\tif (result instanceof Response && !result.ok) {\n\t\t\tconst errorBody = await result.text().catch(() => \"<unable to read response body>\");\n\t\t\tthrow apiCallErrorFromResponse(result, errorBody, {\n\t\t\t\turl: `workers-ai:run/${this.modelId}`,\n\t\t\t\trequestBodyValues: inputs,\n\t\t\t});\n\t\t}\n\n\t\t// Workers AI TTS returns binary audio in various formats:\n\t\t// - Binding: Uint8Array, ArrayBuffer, ReadableStream, or { audio: base64 }\n\t\t// - REST (returnRawResponse): Response object\n\t\tconst audio = await toUint8Array(result);\n\n\t\treturn {\n\t\t\taudio,\n\t\t\twarnings,\n\t\t\tresponse: {\n\t\t\t\ttimestamp: new Date(),\n\t\t\t\tmodelId: this.modelId,\n\t\t\t\theaders: {},\n\t\t\t},\n\t\t};\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Convert various output types from binding.run() to Uint8Array.\n * Workers AI TTS models return different types depending on the runtime:\n * - Response (from REST shim with returnRawResponse)\n * - ReadableStream<Uint8Array> (most common in workerd)\n * - Uint8Array / ArrayBuffer (direct binary)\n * - { audio: string } with base64 data\n */\nasync function toUint8Array(output: unknown): Promise<Uint8Array> {\n\t// Response object (from REST shim with returnRawResponse: true)\n\tif (output instanceof Response) {\n\t\treturn new Uint8Array(await output.arrayBuffer());\n\t}\n\tif (output instanceof Uint8Array) {\n\t\treturn output;\n\t}\n\tif (output instanceof ArrayBuffer) {\n\t\treturn new Uint8Array(output);\n\t}\n\tif (output instanceof ReadableStream) {\n\t\tconst reader = (output as ReadableStream<Uint8Array>).getReader();\n\t\tconst chunks: Uint8Array[] = [];\n\t\tlet totalLength = 0;\n\t\twhile (true) {\n\t\t\tconst { done, value } = await reader.read();\n\t\t\tif (done) break;\n\t\t\tchunks.push(value);\n\t\t\ttotalLength += value.length;\n\t\t}\n\t\tconst result = new Uint8Array(totalLength);\n\t\tlet offset = 0;\n\t\tfor (const chunk of chunks) {\n\t\t\tresult.set(chunk, offset);\n\t\t\toffset += chunk.length;\n\t\t}\n\t\treturn result;\n\t}\n\t// Object with audio property (e.g. { audio: base64string })\n\tif (typeof output === \"object\" && output !== null) {\n\t\tconst obj = output as Record<string, unknown>;\n\t\tif (typeof obj.audio === \"string\") {\n\t\t\treturn Uint8Array.from(atob(obj.audio), (c) => c.charCodeAt(0));\n\t\t}\n\t}\n\tthrow new Error(\n\t\t`Unexpected output type from TTS model. Got ${Object.prototype.toString.call(output)}`,\n\t);\n}\n","import type { RerankingModelV3, SharedV3Warning } from \"@ai-sdk/provider\";\nimport { normalizeBindingError } from \"./workersai-error\";\nimport type { WorkersAIRerankingSettings } from \"./workersai-reranking-settings\";\nimport type { RerankingModels } from \"./workersai-models\";\n\nexport type WorkersAIRerankingConfig = {\n\tprovider: string;\n\tbinding: Ai;\n\tgateway?: GatewayOptions;\n};\n\n/**\n * Workers AI reranking model implementing the AI SDK's `RerankingModelV3` interface.\n *\n * Supports BGE reranker models (`@cf/baai/bge-reranker-base`, `bge-reranker-v2-m3`).\n *\n * Workers AI reranking API:\n * - Input: `{ query, contexts: [{ text }], top_k? }`\n * - Output: `{ response: [{ id, score }] }`\n */\nexport class WorkersAIRerankingModel implements RerankingModelV3 {\n\treadonly specificationVersion = \"v3\";\n\n\tget provider(): string {\n\t\treturn this.config.provider;\n\t}\n\n\tconstructor(\n\t\treadonly modelId: RerankingModels,\n\t\treadonly settings: WorkersAIRerankingSettings,\n\t\treadonly config: WorkersAIRerankingConfig,\n\t) {}\n\n\tasync doRerank(\n\t\toptions: Parameters<RerankingModelV3[\"doRerank\"]>[0],\n\t): Promise<Awaited<ReturnType<RerankingModelV3[\"doRerank\"]>>> {\n\t\tconst { documents, query, topN, abortSignal } = options;\n\n\t\tconst warnings: Array<SharedV3Warning> = [];\n\n\t\t// Convert AI SDK documents to Workers AI contexts format\n\t\tconst contexts = documentsToContexts(documents, warnings);\n\n\t\t// Build Workers AI inputs\n\t\tconst inputs: Record<string, unknown> = {\n\t\t\tquery,\n\t\t\tcontexts,\n\t\t};\n\t\tif (topN != null) {\n\t\t\tinputs.top_k = topN;\n\t\t}\n\n\t\tlet result: Record<string, unknown>;\n\t\ttry {\n\t\t\tresult = (await this.config.binding.run(\n\t\t\t\tthis.modelId as Parameters<Ai[\"run\"]>[0],\n\t\t\t\tinputs as Parameters<Ai[\"run\"]>[1],\n\t\t\t\t{ gateway: this.config.gateway, signal: abortSignal } as AiOptions,\n\t\t\t)) as Record<string, unknown>;\n\t\t} catch (error) {\n\t\t\t// Normalize binding failures (e.g. 3040 \"out of capacity\" → 429) into a\n\t\t\t// retryable APICallError so the AI SDK's maxRetries can engage.\n\t\t\tthrow normalizeBindingError(error, {\n\t\t\t\tmodel: this.modelId,\n\t\t\t\trequestBodyValues: inputs,\n\t\t\t});\n\t\t}\n\n\t\t// Workers AI returns { response: [{ id, score }] }\n\t\tconst response = result.response as Array<{ id?: number; score?: number }> | undefined;\n\n\t\tconst ranking = (response ?? [])\n\t\t\t.map((item) => ({\n\t\t\t\tindex: item.id ?? 0,\n\t\t\t\trelevanceScore: item.score ?? 0,\n\t\t\t}))\n\t\t\t.sort((a, b) => b.relevanceScore - a.relevanceScore);\n\n\t\treturn {\n\t\t\tranking,\n\t\t\twarnings,\n\t\t\tresponse: {\n\t\t\t\ttimestamp: new Date(),\n\t\t\t\tmodelId: this.modelId,\n\t\t\t\theaders: {},\n\t\t\t},\n\t\t};\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Convert AI SDK document format to Workers AI contexts format.\n *\n * AI SDK supports two document types:\n * - `{ type: 'text', values: string[] }` — direct text strings\n * - `{ type: 'object', values: JSONObject[] }` — JSON objects (stringified for Workers AI)\n */\nfunction documentsToContexts(\n\tdocuments: Parameters<RerankingModelV3[\"doRerank\"]>[0][\"documents\"],\n\twarnings: Array<SharedV3Warning>,\n): Array<{ text: string }> {\n\tif (documents.type === \"text\") {\n\t\treturn documents.values.map((text) => ({ text }));\n\t}\n\n\t// Object documents: stringify each object for the reranker\n\twarnings.push({\n\t\tmessage: \"Workers AI reranker expects text contexts. JSON objects have been stringified.\",\n\t\ttype: \"other\",\n\t});\n\n\treturn documents.values.map((obj) => ({ text: JSON.stringify(obj) }));\n}\n","import { AISearchChatLanguageModel } from \"./aisearch-chat-language-model\";\n\n/**\n * @deprecated Use `AISearchChatLanguageModel` instead. AutoRAG has been renamed to AI Search.\n * @see https://developers.cloudflare.com/ai-search/\n */\nexport class AutoRAGChatLanguageModel extends AISearchChatLanguageModel {}\n","import type {\n\tLanguageModelV3,\n\tLanguageModelV3CallOptions,\n\tLanguageModelV3GenerateResult,\n\tLanguageModelV3StreamResult,\n} from \"@ai-sdk/provider\";\nimport { type FallbackAttempt, WorkersAIFallbackError, WorkersAIGatewayError } from \"./errors\";\nimport type { Transport } from \"./gateway-delegate\";\n\n/** One model in a client-side fallback chain. */\nexport interface FallbackLeg {\n\t/** The model slug this leg dispatches. */\n\tslug: string;\n\t/** The built AI SDK model. */\n\tmodel: LanguageModelV3;\n\t/** Transport the leg uses. */\n\ttransport: Transport;\n}\n\n/**\n * Wrap a chain of models so a failed *pre-stream* dispatch falls through to the\n * next model, preserving resume on each leg's own transport. If every leg fails,\n * throws a {@link WorkersAIFallbackError} carrying the full attempt tree.\n *\n * Fallback triggers on `doGenerate`/`doStream` rejection (the dispatch never\n * produced a stream). Errors that surface *mid-stream* — after content has\n * already been emitted — are not recoverable here and propagate as-is.\n */\nexport function createClientFallbackModel(legs: FallbackLeg[]): LanguageModelV3 {\n\tif (legs.length === 0) {\n\t\tthrow new Error(\"createClientFallbackModel requires at least one model leg.\");\n\t}\n\tconst primary = legs[0].model;\n\n\tasync function attempt<T>(run: (model: LanguageModelV3) => PromiseLike<T>): Promise<T> {\n\t\tconst attempts: FallbackAttempt[] = [];\n\t\tfor (const leg of legs) {\n\t\t\ttry {\n\t\t\t\tconst result = await run(leg.model);\n\t\t\t\tattempts.push({ model: leg.slug, transport: leg.transport, ok: true });\n\t\t\t\treturn result;\n\t\t\t} catch (e) {\n\t\t\t\tconst err = WorkersAIGatewayError.fromUnknown(e);\n\t\t\t\tattempts.push({\n\t\t\t\t\tmodel: leg.slug,\n\t\t\t\t\ttransport: leg.transport,\n\t\t\t\t\tok: false,\n\t\t\t\t\tstatus: err.status,\n\t\t\t\t\terror: err,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\tthrow new WorkersAIFallbackError(attempts);\n\t}\n\n\treturn {\n\t\tspecificationVersion: \"v3\",\n\t\tprovider: primary.provider,\n\t\tmodelId: primary.modelId,\n\t\tsupportedUrls: primary.supportedUrls,\n\t\tdoGenerate(\n\t\t\toptions: LanguageModelV3CallOptions,\n\t\t): PromiseLike<LanguageModelV3GenerateResult> {\n\t\t\treturn attempt((m) => m.doGenerate(options));\n\t\t},\n\t\tdoStream(options: LanguageModelV3CallOptions): PromiseLike<LanguageModelV3StreamResult> {\n\t\t\treturn attempt((m) => m.doStream(options));\n\t\t},\n\t};\n}\n","import type { LanguageModelV3, LanguageModelV3CallOptions } from \"@ai-sdk/provider\";\nimport {\n\tasText,\n\tbuildGatewayEntry,\n\tcreateResumableStream,\n\tGatewayDelegateError,\n\ttype GatewayCacheOptions,\n\ttype GatewayEntry,\n\ttype ResumeExpiredPolicy,\n} from \"@cloudflare/gateway-core\";\nimport { createClientFallbackModel } from \"./client-fallback\";\nimport { findProviderBySlug, type GatewayProviderInfo, type WireFormat } from \"./gateway-providers\";\n\nexport {\n\tcreateResumableStream,\n\tGatewayDelegateError,\n\ttype GatewayDelegateErrorKind,\n\ttype ResumableStreamOptions,\n\ttype ResumeExpiredPolicy,\n} from \"@cloudflare/gateway-core\";\nexport {\n\ttype FallbackAttempt,\n\ttype GatewayErrorCode,\n\ttype GatewayErrorContext,\n\tWorkersAIFallbackError,\n\tWorkersAIGatewayError,\n} from \"./errors\";\nexport { type FallbackLeg, createClientFallbackModel } from \"./client-fallback\";\nexport {\n\ttype Billing,\n\tGATEWAY_PROVIDERS,\n\ttype GatewayProviderInfo,\n\ttype WireFormat,\n\tdetectProviderByUrl,\n\tfindProviderBySlug,\n\twireableProviders,\n} from \"./gateway-providers\";\n\n/**\n * Gateway delegate — route AI SDK catalog models through Cloudflare AI Gateway,\n * with capability-driven transport selection.\n *\n * Two transports back the same model, chosen from the requested options:\n *\n *   - **Run path** `env.AI.run(slug, body, { returnRawResponse })` — resumable\n *     streaming (`cf-aig-run-id`). The default.\n *   - **Gateway path** `env.AI.gateway(id).run([entry, …fallback])` — server-side\n *     fallback and caching. Does not surface `cf-aig-run-id`, so resume is off.\n *\n * The SAME `@ai-sdk/*` provider parses the response on either path, so there is no\n * per-provider or per-path response parsing here. Provider plugins (which import\n * `@ai-sdk/openai`, `@ai-sdk/anthropic`, …) are injected from sub-path modules\n * (`workers-ai-provider/openai`, …) so those AI SDK packages stay OPTIONAL peer\n * dependencies — you only install the ones you use.\n *\n * @example\n * ```ts\n * import { createGatewayDelegate } from \"workers-ai-provider/gateway-delegate\";\n * import { openai } from \"workers-ai-provider/openai\";\n * import { streamText } from \"ai\";\n *\n * const wai = createGatewayDelegate({\n *   binding: env.AI,\n *   gateway: \"my-gateway\",\n *   providers: [openai],\n * });\n *\n * const result = streamText({ model: wai(\"openai/gpt-5\"), prompt: \"Hello\" });\n * // result.response.headers[\"cf-aig-run-id\"] is set — resume from there.\n * ```\n */\n\n// ---------------------------------------------------------------------------\n// Slug parsing\n// ---------------------------------------------------------------------------\n\nexport interface ParsedSlug {\n\t/** First path segment — the registry resolver key (selects provider + wire format). */\n\tresolverKey: string;\n\t/** Remaining segments — the provider-native model id. */\n\tmodelId: string;\n}\n\n/**\n * Parse a `vendor/model` slug. The first segment is the resolver key (which\n * registry entry handles it); the rest is the provider-native model id. Routing\n * providers keep multi-segment model ids, e.g. `openrouter/anthropic/claude`.\n */\nexport function parseSlug(slug: string): ParsedSlug {\n\tconst slash = slug.indexOf(\"/\");\n\tif (slash === -1) {\n\t\tthrow new GatewayDelegateError(\n\t\t\t\"config\",\n\t\t\t`Model slug \"${slug}\" has no resolver key. Use \"<provider>/<model>\" (e.g. \"openai/gpt-5\").`,\n\t\t);\n\t}\n\tconst resolverKey = slug.slice(0, slash);\n\tconst modelId = slug.slice(slash + 1);\n\tif (!resolverKey || !modelId) {\n\t\tthrow new GatewayDelegateError(\n\t\t\t\"config\",\n\t\t\t`Model slug \"${slug}\" is malformed. Use \"<provider>/<model>\" (e.g. \"openai/gpt-5\").`,\n\t\t);\n\t}\n\treturn { resolverKey, modelId };\n}\n\n/**\n * Resolve a slug to its registry entry, raising a helpful error for unknown or\n * bring-your-own-provider-only providers.\n */\nexport function resolveProvider(slug: string, parsed: ParsedSlug): GatewayProviderInfo {\n\tconst info = findProviderBySlug(parsed.resolverKey);\n\tif (!info) {\n\t\tthrow new GatewayDelegateError(\n\t\t\t\"config\",\n\t\t\t`Unknown gateway provider \"${parsed.resolverKey}\" (from slug \"${slug}\"). ` +\n\t\t\t\t\"See the AI Gateway provider directory for valid slugs, or use \" +\n\t\t\t\t\"createGatewayProvider to bring your own @ai-sdk provider.\",\n\t\t);\n\t}\n\tif (!info.wireFormat) {\n\t\tthrow new GatewayDelegateError(\n\t\t\t\"config\",\n\t\t\t`Provider \"${parsed.resolverKey}\" is not chat/completions-shaped and has no built-in ` +\n\t\t\t\t\"parser. Reach it with createGatewayProvider (bring your own @ai-sdk provider).\",\n\t\t);\n\t}\n\treturn info;\n}\n\n// ---------------------------------------------------------------------------\n// Provider plugins (injected from sub-path modules)\n// ---------------------------------------------------------------------------\n\n/**\n * Adapts a `@ai-sdk/*` provider to the delegate, keyed by the response wire\n * format it parses. Imported from a sub-path module (e.g.\n * `workers-ai-provider/openai`) so the AI SDK package stays an optional peer\n * dependency. One plugin serves every registry provider of that wire format —\n * the `openai` plugin covers the whole OpenAI-compatible long tail (deepseek,\n * grok, groq, mistral, perplexity, openrouter, …).\n */\nexport interface ProviderPlugin {\n\t/** The response wire format this builder parses. */\n\treadonly wireFormat: WireFormat;\n\t/**\n\t * Build the AI SDK model, wiring the gateway-dispatching `fetch`. `baseURL`\n\t * (when provided by the registry) targets the provider's host so the request\n\t * URL host-strips to its gateway-native endpoint — pass it to the underlying\n\t * `@ai-sdk` provider.\n\t */\n\tcreate(args: {\n\t\tmodelId: string;\n\t\tfetch: typeof globalThis.fetch;\n\t\tbaseURL?: string;\n\t}): LanguageModelV3;\n}\n\n// ---------------------------------------------------------------------------\n// Options + transport selection\n// ---------------------------------------------------------------------------\n\nexport type Transport = \"run\" | \"gateway\";\n\nexport interface FallbackOptions {\n\t/** `\"client\"` keeps resume (sequential run-path attempts); `\"server\"` uses the gateway path. */\n\tmode: \"client\" | \"server\";\n\t/** Ordered model slugs to try after the primary. */\n\tmodels: string[];\n}\n\nexport interface DispatchInfo {\n\ttransport: Transport;\n\tresumeEnabled: boolean;\n\twarnings: string[];\n\trunId: string | null;\n\tstatus: number | null;\n\tcfStep: string | null;\n\tcacheStatus: string | null;\n\tlogId: string | null;\n}\n\nexport interface DelegateCallOptions {\n\t/** Resumable streaming (run path). Defaults to the delegate's `resume` (true). */\n\tresume?: boolean;\n\t/** Cross-model fallback. `\"server\"` mode uses the gateway path (disables resume). */\n\tfallback?: FallbackOptions;\n\t/** Gateway-path response caching (seconds). Forces the gateway path. */\n\tcacheTtl?: number;\n\t/** Bypass gateway cache. Forces the gateway path. */\n\tskipCache?: boolean;\n\t/** Escape hatch: force a transport. */\n\ttransport?: Transport;\n\t/**\n\t * Run path only: behavior when the resume buffer has expired (404) after a\n\t * mid-stream drop. `\"error\"` (default) surfaces a `GatewayDelegateError`;\n\t * `\"accept-partial\"` ends the stream cleanly with whatever was delivered.\n\t */\n\tonResumeExpired?: ResumeExpiredPolicy;\n\t/** Extra request headers (run path: `extraHeaders`; gateway path: entry headers). */\n\textraHeaders?: Record<string, string>;\n\t/**\n\t * Gateway path only: forward the upstream provider key instead of stripping it.\n\t * Required for BYOK providers (not on unified billing). Supply the key via\n\t * `extraHeaders` (e.g. `{ authorization: \"Bearer …\" }`); without `byok` the\n\t * delegate strips provider auth headers so unified billing applies.\n\t */\n\tbyok?: boolean;\n\t/**\n\t * Gateway path only: BYOK stored-key alias to authenticate with\n\t * (`cf-aig-byok-alias`). Selects a non-`default` key you configured for the\n\t * provider on the gateway. Independent of `byok` (which controls whether the\n\t * caller's own provider auth header is forwarded vs. stripped).\n\t */\n\tbyokAlias?: string;\n\t/**\n\t * Per-request Zero Data Retention override (`cf-aig-zdr`), Unified Billing\n\t * only: `true` forces ZDR-capable upstreams, `false` disables it for this\n\t * request. Overrides the gateway-level ZDR default. Applied on both transports\n\t * (run path: passed through gateway options as a header; gateway path: entry header).\n\t */\n\tzdr?: boolean;\n\t/** Override the delegate's gateway for this model. */\n\tgateway?: GatewayOptions | string;\n\t/**\n\t * Custom metadata attached to the gateway log for this request (spend\n\t * attribution, tenant ids, etc.). Merges over any `metadata` already set via\n\t * `gateway: { metadata }`. Applied on both transports (run path: gateway\n\t * options; gateway path: `cf-aig-metadata` header). `bigint` values are\n\t * coerced to strings for the header form.\n\t */\n\tmetadata?: Record<string, number | string | boolean | null | bigint>;\n\t/** Force gateway log collection on/off for this request (both transports). */\n\tcollectLog?: boolean;\n\t/** Called once per dispatch with the resolved transport + gateway headers. */\n\tonDispatch?: (info: DispatchInfo) => void;\n\t/**\n\t * Run path only: fired with the cumulative SSE event offset as the resumable\n\t * stream advances. Pair with `onDispatch` (for `runId`) to persist\n\t * `{ runId, eventOffset }` for cross-invocation re-attach after eviction.\n\t * Throttle your own writes — this can fire per chunk.\n\t */\n\tonProgress?: (eventOffset: number) => void;\n}\n\ninterface Selection {\n\ttransport: Transport;\n\tresumeEnabled: boolean;\n\twarnings: string[];\n}\n\n/**\n * Resolve the transport from the requested options. Gateway-only features (server\n * fallback, caching) force the gateway path and disable resume — with a loud\n * warning if resume was merely defaulted, or a thrown error if it was explicitly\n * requested.\n */\nexport function selectTransport(\n\topts: DelegateCallOptions,\n\tresumeExplicitlyTrue: boolean,\n\trunCatalog = true,\n\tgatewayAvailable = true,\n): Selection {\n\tconst warnings: string[] = [];\n\tconst wantsServerFallback = opts.fallback?.mode === \"server\";\n\tconst wantsCaching = opts.cacheTtl !== undefined || opts.skipCache === true;\n\tconst gatewayOnly = wantsServerFallback || wantsCaching;\n\tconst feature = wantsServerFallback ? 'fallback.mode:\"server\"' : \"caching (cacheTtl/skipCache)\";\n\n\t// Run-path-only providers (on the run catalog, but not native gateway\n\t// providers) have no gateway path at all — reject anything that would need it\n\t// here, with a clear message, rather than letting it fail upstream.\n\tif (\n\t\trunCatalog &&\n\t\t!gatewayAvailable &&\n\t\t(opts.transport === \"gateway\" || opts.byok || gatewayOnly)\n\t) {\n\t\tconst what =\n\t\t\topts.transport === \"gateway\" ? 'transport:\"gateway\"' : opts.byok ? \"byok\" : feature;\n\t\tthrow new GatewayDelegateError(\n\t\t\t\"config\",\n\t\t\t`${what} is unavailable: this provider is on the unified run catalog but is not a ` +\n\t\t\t\t\"native gateway provider, so it has no gateway path (no caching, server-side \" +\n\t\t\t\t'fallback, BYOK, or transport:\"gateway\"). Use the default run path, or fallback.mode:\"client\".',\n\t\t);\n\t}\n\n\t// BYOK providers are not on the resumable run catalog — they can only be\n\t// reached through the gateway path.\n\tif (!runCatalog) {\n\t\tif (opts.transport === \"run\") {\n\t\t\tthrow new GatewayDelegateError(\n\t\t\t\t\"config\",\n\t\t\t\t'transport:\"run\" is unavailable: this provider is not on the unified-billing run ' +\n\t\t\t\t\t\"catalog, so it can only be reached through the gateway path (BYOK).\",\n\t\t\t);\n\t\t}\n\t\tif (resumeExplicitlyTrue) {\n\t\t\tthrow new GatewayDelegateError(\n\t\t\t\t\"config\",\n\t\t\t\t\"resume:true is unavailable: this provider is not on the resumable run catalog \" +\n\t\t\t\t\t\"(cf-aig-run-id requires the unified-billing run path).\",\n\t\t\t);\n\t\t}\n\t\treturn { transport: \"gateway\", resumeEnabled: false, warnings };\n\t}\n\n\t// BYOK forwards the caller's own provider key, which only the gateway path\n\t// supports — treat it like an explicit gateway transport (no resume-disabled\n\t// warning; the caller opted into a gateway-only mode).\n\tif (opts.byok) {\n\t\tif (opts.transport === \"run\") {\n\t\t\tthrow new GatewayDelegateError(\n\t\t\t\t\"config\",\n\t\t\t\t'transport:\"run\" cannot forward a BYOK key — BYOK is a gateway-path feature. ' +\n\t\t\t\t\t'Drop transport:\"run\" (or set transport:\"gateway\").',\n\t\t\t);\n\t\t}\n\t\tif (resumeExplicitlyTrue) {\n\t\t\tthrow new GatewayDelegateError(\n\t\t\t\t\"config\",\n\t\t\t\t\"byok cannot provide resume — cf-aig-run-id is only on the unified-billing run path.\",\n\t\t\t);\n\t\t}\n\t\treturn { transport: \"gateway\", resumeEnabled: false, warnings };\n\t}\n\n\tif (opts.transport === \"run\" && gatewayOnly) {\n\t\tthrow new GatewayDelegateError(\n\t\t\t\"config\",\n\t\t\t`transport:\"run\" cannot satisfy ${feature}: those features are only available on the ` +\n\t\t\t\t'gateway path. Use the gateway transport, or fallback.mode:\"client\".',\n\t\t);\n\t}\n\tif (opts.transport === \"gateway\" && resumeExplicitlyTrue) {\n\t\tthrow new GatewayDelegateError(\n\t\t\t\"config\",\n\t\t\t'transport:\"gateway\" cannot provide resume — cf-aig-run-id is only on the run path.',\n\t\t);\n\t}\n\n\tif (gatewayOnly) {\n\t\tif (resumeExplicitlyTrue) {\n\t\t\tthrow new GatewayDelegateError(\n\t\t\t\t\"config\",\n\t\t\t\t`resume:true conflicts with ${feature}: resume (cf-aig-run-id) is only on the run path, ` +\n\t\t\t\t\t`which does not support ${wantsServerFallback ? \"server-side fallback\" : \"caching\"}. ` +\n\t\t\t\t\t'Use fallback.mode:\"client\" to keep resume, or drop resume.',\n\t\t\t);\n\t\t}\n\t\twarnings.push(\n\t\t\t`[workers-ai-provider] resume disabled: ${feature} requires the gateway path, which does ` +\n\t\t\t\t'not surface cf-aig-run-id. Use fallback.mode:\"client\" to keep resumable streaming.',\n\t\t);\n\t\treturn { transport: \"gateway\", resumeEnabled: false, warnings };\n\t}\n\n\tconst transport = opts.transport ?? \"run\";\n\treturn {\n\t\ttransport,\n\t\tresumeEnabled: transport === \"run\" && opts.resume !== false,\n\t\twarnings,\n\t};\n}\n\n// ---------------------------------------------------------------------------\n// Dispatch internals\n// ---------------------------------------------------------------------------\n\ninterface AiGatewayRunner {\n\trun(body: unknown, options?: Record<string, unknown>): Promise<Response>;\n}\n\nfunction normalizeGateway(gateway: GatewayOptions | string | undefined): {\n\tid: string;\n\toptions: GatewayOptions;\n} {\n\tif (!gateway) {\n\t\tthrow new GatewayDelegateError(\n\t\t\t\"config\",\n\t\t\t\"A gateway is required for the delegate (resume needs a gateway). \" +\n\t\t\t\t'Pass `gateway: \"<gateway-id>\"` to createGatewayDelegate or per call.',\n\t\t);\n\t}\n\tif (typeof gateway === \"string\") return { id: gateway, options: { id: gateway } };\n\treturn { id: gateway.id, options: gateway };\n}\n\nexport interface GatewayDelegateConfig {\n\t/** A Cloudflare AI binding (e.g. `env.AI`). Required — the gateway path needs `binding.gateway()`. */\n\tbinding: Ai;\n\t/** Default gateway id (or options) for all models. Overridable per call. */\n\tgateway?: GatewayOptions | string;\n\t/** Provider plugins from sub-path modules (e.g. `[openai, anthropic]`). */\n\tproviders: ProviderPlugin[];\n\t/** Default resume behavior when a call does not specify one. Defaults to `true`. */\n\tresume?: boolean;\n\t/** Default resume-expiry policy (run path). Defaults to `\"error\"`. */\n\tonResumeExpired?: ResumeExpiredPolicy;\n}\n\nexport interface GatewayDelegate {\n\t(slug: string, options?: DelegateCallOptions): LanguageModelV3;\n}\n\n/**\n * Create a gateway delegate. Returns a function that builds an AI SDK model for a\n * `\"<provider>/<model>\"` slug, dispatched through AI Gateway on the transport the\n * requested options imply.\n */\nexport function createGatewayDelegate(config: GatewayDelegateConfig): GatewayDelegate {\n\tif (!config?.binding) {\n\t\tthrow new GatewayDelegateError(\n\t\t\t\"config\",\n\t\t\t\"createGatewayDelegate requires a `binding` (e.g. { binding: env.AI }).\",\n\t\t);\n\t}\n\tif (!config.providers?.length) {\n\t\tthrow new GatewayDelegateError(\n\t\t\t\"config\",\n\t\t\t\"createGatewayDelegate requires at least one provider plugin, e.g. \" +\n\t\t\t\t'`providers: [openai]` from \"workers-ai-provider/openai\".',\n\t\t);\n\t}\n\n\tconst plugins = new Map<WireFormat, ProviderPlugin>();\n\tfor (const p of config.providers) plugins.set(p.wireFormat, p);\n\tconst defaultResume = config.resume ?? true;\n\n\tconst buildOne = (\n\t\tslug: string,\n\t\toptions: DelegateCallOptions,\n\t): { model: LanguageModelV3; transport: Transport } => {\n\t\tconst parsed = parseSlug(slug);\n\t\tconst info = resolveProvider(slug, parsed);\n\n\t\tconst resumeExplicitlyTrue = options.resume === true;\n\t\tconst effectiveOptions: DelegateCallOptions = {\n\t\t\t...options,\n\t\t\tresume: options.resume ?? defaultResume,\n\t\t\tonResumeExpired: options.onResumeExpired ?? config.onResumeExpired,\n\t\t};\n\t\tconst selection = selectTransport(\n\t\t\teffectiveOptions,\n\t\t\tresumeExplicitlyTrue,\n\t\t\tinfo.runCatalog,\n\t\t\tinfo.gatewayPath !== false,\n\t\t);\n\t\tfor (const w of selection.warnings) console.warn(w);\n\n\t\t// Pick the parser by transport. The unified-billing run path (`env.AI.run`)\n\t\t// does NOT speak a uniform wire format: Cloudflare normalizes most providers\n\t\t// to OpenAI chat-completions (so `google` is parsed with the `openai` plugin\n\t\t// on the run path), but passes Anthropic through natively. So the run path\n\t\t// uses the registry's `runWireFormat` (default \"openai\"), while the gateway\n\t\t// path — which hits provider-native endpoints — uses the native `wireFormat`.\n\t\tconst wire: WireFormat =\n\t\t\tselection.transport === \"run\"\n\t\t\t\t? (info.runWireFormat ?? \"openai\")\n\t\t\t\t: (info.wireFormat as WireFormat);\n\t\tconst plugin = plugins.get(wire);\n\t\tif (!plugin) {\n\t\t\tthrow new GatewayDelegateError(\n\t\t\t\t\"config\",\n\t\t\t\tselection.transport === \"run\"\n\t\t\t\t\t? `The run path for \"${parsed.resolverKey}\" (from slug \"${slug}\") returns ` +\n\t\t\t\t\t\t\t`\"${wire}\"-wire responses, so it needs the \"${wire}\" plugin. ` +\n\t\t\t\t\t\t\t`Install + pass it from \"workers-ai-provider/${wire}\". ` +\n\t\t\t\t\t\t\t`Registered: ${[...plugins.keys()].join(\", \") || \"<none>\"}.`\n\t\t\t\t\t: `No provider plugin for wire format \"${wire}\" (needed by \"${parsed.resolverKey}\" ` +\n\t\t\t\t\t\t\t`on the gateway path from slug \"${slug}\"). ` +\n\t\t\t\t\t\t\t`Registered: ${[...plugins.keys()].join(\", \") || \"<none>\"}. ` +\n\t\t\t\t\t\t\t`Install + pass the matching plugin from \"workers-ai-provider/${wire}\".`,\n\t\t\t);\n\t\t}\n\n\t\tconst { id: gatewayId, options: gatewayOptions } = normalizeGateway(\n\t\t\toptions.gateway ?? config.gateway,\n\t\t);\n\n\t\tconst fetchImpl =\n\t\t\tselection.transport === \"run\"\n\t\t\t\t? makeRunFetch(\n\t\t\t\t\t\tconfig.binding,\n\t\t\t\t\t\t// Use the canonical run-catalog author (e.g. \"grok\" → \"xai\"), not the\n\t\t\t\t\t\t// raw alias the caller typed, so `env.AI.run` resolves the model.\n\t\t\t\t\t\t`${info.resolverKey}/${parsed.modelId}`,\n\t\t\t\t\t\tgatewayOptions,\n\t\t\t\t\t\teffectiveOptions,\n\t\t\t\t\t\tselection,\n\t\t\t\t\t\toptions,\n\t\t\t\t\t)\n\t\t\t\t: makeGatewayFetch(\n\t\t\t\t\t\tconfig.binding,\n\t\t\t\t\t\tinfo,\n\t\t\t\t\t\tgatewayId,\n\t\t\t\t\t\tgatewayOptions,\n\t\t\t\t\t\teffectiveOptions,\n\t\t\t\t\t\tselection,\n\t\t\t\t\t\toptions,\n\t\t\t\t\t);\n\n\t\treturn {\n\t\t\tmodel: plugin.create({\n\t\t\t\tmodelId: parsed.modelId,\n\t\t\t\tfetch: fetchImpl,\n\t\t\t\t// baseURL only matters on the gateway path (host-strip to the native\n\t\t\t\t// endpoint); the run path ignores the request URL entirely.\n\t\t\t\t...(selection.transport === \"gateway\" && info.baseURL\n\t\t\t\t\t? { baseURL: info.baseURL }\n\t\t\t\t\t: {}),\n\t\t\t}),\n\t\t\ttransport: selection.transport,\n\t\t};\n\t};\n\n\treturn (slug, options = {}) => {\n\t\t// Client-side fallback: build a model per slug and wrap them so a failed\n\t\t// pre-stream dispatch falls through to the next, each on its own transport\n\t\t// (so resume is preserved per leg).\n\t\tif (options.fallback?.mode === \"client\") {\n\t\t\tconst { fallback, ...rest } = options;\n\t\t\tconst slugs = [slug, ...fallback.models];\n\t\t\tconst legs = slugs.map((s) => {\n\t\t\t\tconst { model, transport } = buildOne(s, rest);\n\t\t\t\treturn { slug: s, model, transport };\n\t\t\t});\n\t\t\treturn createClientFallbackModel(legs);\n\t\t}\n\n\t\t// Server-side fallback: all legs ship in one gateway run; `cf-aig-step`\n\t\t// names the winner. Same-vendor legs are handled by makeGatewayFetch (it\n\t\t// just swaps `model` in one body); cross-vendor legs need each leg's own\n\t\t// builder to shape its native request, so route them through the\n\t\t// capture/redispatch engine (ported from ai-gateway-provider).\n\t\tif (options.fallback?.mode === \"server\") {\n\t\t\tconst slugs = [slug, ...options.fallback.models];\n\t\t\tconst resolved = slugs.map((s) => {\n\t\t\t\tconst parsed = parseSlug(s);\n\t\t\t\treturn { slug: s, modelId: parsed.modelId, info: resolveProvider(s, parsed) };\n\t\t\t});\n\t\t\tconst crossVendor = resolved.some(\n\t\t\t\t(r) => r.info.gatewayProviderId !== resolved[0]!.info.gatewayProviderId,\n\t\t\t);\n\t\t\tif (crossVendor) {\n\t\t\t\tconst resumeExplicitlyTrue = options.resume === true;\n\t\t\t\tconst effectiveOptions: DelegateCallOptions = {\n\t\t\t\t\t...options,\n\t\t\t\t\tresume: options.resume ?? defaultResume,\n\t\t\t\t\tonResumeExpired: options.onResumeExpired ?? config.onResumeExpired,\n\t\t\t\t};\n\t\t\t\tconst primaryInfo = resolved[0]!.info;\n\t\t\t\t// Forces the gateway path + disables resume (throws if resume:true).\n\t\t\t\tconst selection = selectTransport(\n\t\t\t\t\teffectiveOptions,\n\t\t\t\t\tresumeExplicitlyTrue,\n\t\t\t\t\tprimaryInfo.runCatalog,\n\t\t\t\t\tprimaryInfo.gatewayPath !== false,\n\t\t\t\t);\n\t\t\t\tfor (const w of selection.warnings) console.warn(w);\n\n\t\t\t\tconst { id: gatewayId, options: gatewayOptions } = normalizeGateway(\n\t\t\t\t\toptions.gateway ?? config.gateway,\n\t\t\t\t);\n\n\t\t\t\tconst legs: ServerFallbackLeg[] = resolved.map((r) => {\n\t\t\t\t\tif (r.info.gatewayPath === false) {\n\t\t\t\t\t\tthrow new GatewayDelegateError(\n\t\t\t\t\t\t\t\"config\",\n\t\t\t\t\t\t\t`Server-side fallback cannot use \"${r.slug}\": it is on the unified ` +\n\t\t\t\t\t\t\t\t\"run catalog but has no native gateway path.\",\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tconst wire = r.info.wireFormat as WireFormat;\n\t\t\t\t\tconst plugin = plugins.get(wire);\n\t\t\t\t\tif (!plugin) {\n\t\t\t\t\t\tthrow new GatewayDelegateError(\n\t\t\t\t\t\t\t\"config\",\n\t\t\t\t\t\t\t`No provider plugin for wire format \"${wire}\" (needed by \"${r.slug}\" ` +\n\t\t\t\t\t\t\t\t`for server-side fallback). Registered: ` +\n\t\t\t\t\t\t\t\t`${[...plugins.keys()].join(\", \") || \"<none>\"}.`,\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\treturn { slug: r.slug, modelId: r.modelId, info: r.info, plugin };\n\t\t\t\t});\n\n\t\t\t\treturn makeServerFallbackModel({\n\t\t\t\t\tbinding: config.binding,\n\t\t\t\t\tgatewayId,\n\t\t\t\t\tgatewayOptions,\n\t\t\t\t\tlegs,\n\t\t\t\t\topts: effectiveOptions,\n\t\t\t\t\tselection,\n\t\t\t\t\tcallOptions: options,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\treturn buildOne(slug, options).model;\n\t};\n}\n\nfunction fireDispatch(resp: Response, selection: Selection, options: DelegateCallOptions): void {\n\tif (!options.onDispatch) return;\n\toptions.onDispatch({\n\t\ttransport: selection.transport,\n\t\tresumeEnabled: selection.resumeEnabled,\n\t\twarnings: selection.warnings,\n\t\tstatus: resp.status,\n\t\trunId: resp.headers.get(\"cf-aig-run-id\"),\n\t\tcfStep: resp.headers.get(\"cf-aig-step\"),\n\t\tcacheStatus: resp.headers.get(\"cf-aig-cache-status\"),\n\t\tlogId: resp.headers.get(\"cf-aig-log-id\"),\n\t});\n}\n\ntype GatewayMetadata = Record<string, number | string | boolean | null | bigint>;\n\n/** Merge call-level metadata over gateway-option metadata (call wins). */\nfunction mergeMetadata(\n\tbase: GatewayMetadata | undefined,\n\toverride: GatewayMetadata | undefined,\n): GatewayMetadata | undefined {\n\tif (!base && !override) return undefined;\n\treturn { ...base, ...override };\n}\n\n/**\n * Build the `cf-aig-*` request controls for a gateway-path entry. First-class\n * call options (`cacheTtl`, `skipCache`, `collectLog`, `metadata`, `byokAlias`,\n * `zdr`) are layered over the binding-style gateway options (`cacheKey`,\n * `eventId`, `requestTimeoutMs`, `retries`) so the gateway path reaches parity\n * with the run path, which forwards the whole `GatewayOptions` to `binding.run`.\n */\nfunction buildGatewayControls(\n\tgatewayOptions: GatewayOptions,\n\topts: DelegateCallOptions,\n): GatewayCacheOptions {\n\tconst metadata = mergeMetadata(gatewayOptions.metadata, opts.metadata);\n\treturn {\n\t\tcacheTtl: opts.cacheTtl,\n\t\tskipCache: opts.skipCache,\n\t\t...(gatewayOptions.cacheKey !== undefined ? { cacheKey: gatewayOptions.cacheKey } : {}),\n\t\t...(metadata ? { metadata } : {}),\n\t\t...(opts.collectLog !== undefined ? { collectLog: opts.collectLog } : {}),\n\t\t...(gatewayOptions.eventId !== undefined ? { eventId: gatewayOptions.eventId } : {}),\n\t\t...(gatewayOptions.requestTimeoutMs !== undefined\n\t\t\t? { requestTimeoutMs: gatewayOptions.requestTimeoutMs }\n\t\t\t: {}),\n\t\t...(gatewayOptions.retries ? { retries: gatewayOptions.retries } : {}),\n\t\t...(opts.byokAlias !== undefined ? { byokAlias: opts.byokAlias } : {}),\n\t\t...(opts.zdr !== undefined ? { zdr: opts.zdr } : {}),\n\t};\n}\n\nfunction makeRunFetch(\n\tbinding: Ai,\n\tslug: string,\n\tgatewayOptions: GatewayOptions,\n\topts: DelegateCallOptions,\n\tselection: Selection,\n\tcallOptions: DelegateCallOptions,\n): typeof globalThis.fetch {\n\treturn (async (_input: RequestInfo | URL, init?: RequestInit): Promise<Response> => {\n\t\tconst body = JSON.parse(asText(init?.body)) as Record<string, unknown>;\n\t\t// The slug carries the model; drop the redundant body field (both are tolerated).\n\t\tdelete body.model;\n\n\t\t// Fold first-class metadata/collectLog over anything supplied via\n\t\t// `gateway: { ... }`; explicit call options win.\n\t\tconst mergedGateway: GatewayOptions = { ...gatewayOptions };\n\t\tconst mergedMeta = mergeMetadata(gatewayOptions.metadata, opts.metadata);\n\t\tif (mergedMeta) mergedGateway.metadata = mergedMeta;\n\t\tif (opts.collectLog !== undefined) mergedGateway.collectLog = opts.collectLog;\n\n\t\t// `zdr` is a Unified-Billing (run path) feature, but it's not a field on the\n\t\t// binding's `GatewayOptions`, so pass it as a `cf-aig-zdr` extra header.\n\t\tconst extraHeaders: Record<string, string> = { ...opts.extraHeaders };\n\t\tif (opts.zdr !== undefined) extraHeaders[\"cf-aig-zdr\"] = String(opts.zdr);\n\n\t\tconst runOptions = {\n\t\t\tgateway: mergedGateway,\n\t\t\treturnRawResponse: true,\n\t\t\t...(Object.keys(extraHeaders).length > 0 ? { extraHeaders } : {}),\n\t\t\t...(init?.signal ? { signal: init.signal } : {}),\n\t\t};\n\n\t\t// The binding's `run` is heavily overloaded; narrow to the raw-Response\n\t\t// streaming signature. Call as a METHOD on the binding — extracting it\n\t\t// into a bare variable detaches `this` and the binding throws on a private\n\t\t// field access (\"Cannot set properties of undefined (setting '#options')\").\n\t\tconst ai = binding as unknown as {\n\t\t\trun(\n\t\t\t\tmodel: string,\n\t\t\t\tinputs: Record<string, unknown>,\n\t\t\t\toptions: Record<string, unknown>,\n\t\t\t): Promise<Response>;\n\t\t};\n\t\tconst resp = await ai.run(slug, body, runOptions);\n\t\tfireDispatch(resp, selection, callOptions);\n\n\t\t// Wrap the stream so a transient mid-stream drop reconnects via the gateway\n\t\t// resume endpoint transparently — the @ai-sdk parser never sees the break.\n\t\tconst runId = resp.headers.get(\"cf-aig-run-id\");\n\t\tif (selection.resumeEnabled && runId && resp.body) {\n\t\t\tconst resumable = createResumableStream({\n\t\t\t\tbinding,\n\t\t\t\tgateway: gatewayOptions.id,\n\t\t\t\trunId,\n\t\t\t\tinitial: resp.body,\n\t\t\t\tonResumeExpired: opts.onResumeExpired,\n\t\t\t\t...(opts.onProgress ? { onProgress: opts.onProgress } : {}),\n\t\t\t});\n\t\t\treturn new Response(resumable, { status: resp.status, headers: resp.headers });\n\t\t}\n\t\treturn resp;\n\t}) as typeof globalThis.fetch;\n}\n\nfunction makeGatewayFetch(\n\tbinding: Ai,\n\tinfo: GatewayProviderInfo,\n\tgatewayId: string,\n\tgatewayOptions: GatewayOptions,\n\topts: DelegateCallOptions,\n\tselection: Selection,\n\tcallOptions: DelegateCallOptions,\n): typeof globalThis.fetch {\n\treturn (async (input: RequestInfo | URL, init?: RequestInit): Promise<Response> => {\n\t\tconst rawUrl = typeof input === \"string\" ? input : input.toString();\n\t\t// Host-strip to the provider's gateway-native endpoint. The registry\n\t\t// transform matches because the builder targeted the provider's baseURL;\n\t\t// fall back to a generic pathname strip if it somehow doesn't.\n\t\tconst endpoint = info.transformEndpoint\n\t\t\t? info.transformEndpoint(rawUrl)\n\t\t\t: new URL(rawUrl).pathname.replace(/^\\//, \"\") + (new URL(rawUrl).search || \"\");\n\t\tconst body = JSON.parse(asText(init?.body)) as Record<string, unknown>;\n\n\t\t// Strip the AI SDK's placeholder provider key unless BYOK forwards a real\n\t\t// one; unified billing / the gateway's stored key authenticates otherwise.\n\t\tconst primary: GatewayEntry = buildGatewayEntry({\n\t\t\tproviderId: info.gatewayProviderId,\n\t\t\tendpoint,\n\t\t\tinitHeaders: init?.headers,\n\t\t\tbody,\n\t\t\t...(opts.byok ? {} : { stripAuthHeaders: info.authHeaders }),\n\t\t\t...(opts.extraHeaders ? { extraHeaders: opts.extraHeaders } : {}),\n\t\t\tcache: buildGatewayControls(gatewayOptions, opts),\n\t\t});\n\t\tconst entries: GatewayEntry[] = [primary];\n\n\t\t// Same-vendor server fallback: every leg shares this provider + endpoint, so\n\t\t// each is just the primary entry with `model` swapped. (Cross-vendor chains\n\t\t// never reach here — the delegate routes them through makeServerFallbackModel,\n\t\t// which captures each leg's native request; this stays a defensive guard.)\n\t\tif (opts.fallback?.mode === \"server\") {\n\t\t\tfor (const fb of opts.fallback.models) {\n\t\t\t\tconst fbParsed = parseSlug(fb);\n\t\t\t\tconst fbInfo = resolveProvider(fb, fbParsed);\n\t\t\t\tif (fbInfo.gatewayProviderId !== info.gatewayProviderId) {\n\t\t\t\t\tthrow new GatewayDelegateError(\n\t\t\t\t\t\t\"dispatch\",\n\t\t\t\t\t\t`Internal: cross-vendor server fallback (${info.gatewayProviderId} → ` +\n\t\t\t\t\t\t\t`${fbInfo.gatewayProviderId}) reached the same-vendor gateway fetch. ` +\n\t\t\t\t\t\t\t\"This should have been routed through makeServerFallbackModel.\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tentries.push({ ...primary, query: { ...body, model: fbParsed.modelId } });\n\t\t\t}\n\t\t}\n\n\t\tconst gw = (binding as unknown as { gateway(id: string): AiGatewayRunner }).gateway(\n\t\t\tgatewayId,\n\t\t);\n\t\tconst runOptions: Record<string, unknown> = {};\n\t\tif (init?.signal) runOptions.signal = init.signal;\n\t\tconst resp = await gw.run(entries, runOptions);\n\t\tfireDispatch(resp, selection, callOptions);\n\t\treturn resp;\n\t}) as typeof globalThis.fetch;\n}\n\n// ---------------------------------------------------------------------------\n// Cross-vendor server-side fallback (ported from ai-gateway-provider)\n// ---------------------------------------------------------------------------\n\n/** Sentinel thrown by the capture fetch to stop a leg before it hits the network. */\nclass ServerFallbackCaptureStop extends Error {}\n\n/** One leg of a server-side fallback chain (gateway path). */\ninterface ServerFallbackLeg {\n\tslug: string;\n\tmodelId: string;\n\tinfo: GatewayProviderInfo;\n\tplugin: ProviderPlugin;\n}\n\n/**\n * Cross-vendor server-side fallback via the gateway universal endpoint.\n *\n * Unlike same-vendor fallback (which just swaps `model` in one body), legs here\n * are DIFFERENT providers with possibly different wire formats, so each leg's own\n * `@ai-sdk` model must shape its native request. Mirrors ai-gateway-provider's\n * `processModelRequest`: run each leg's builder with a capture `fetch` that\n * sentinel-throws before the network, reshape each captured request into a\n * `{ provider, endpoint, headers, query }` entry, dispatch all N as one\n * `env.AI.gateway(id).run([...])`, then read `cf-aig-step` to find the leg the\n * gateway actually served and feed the raw response back into that leg's model.\n */\nfunction makeServerFallbackModel(params: {\n\tbinding: Ai;\n\tgatewayId: string;\n\tgatewayOptions: GatewayOptions;\n\tlegs: ServerFallbackLeg[];\n\topts: DelegateCallOptions;\n\tselection: Selection;\n\tcallOptions: DelegateCallOptions;\n}): LanguageModelV3 {\n\tconst { binding, gatewayId, gatewayOptions, legs, opts, selection, callOptions } = params;\n\tconst first = legs[0]!;\n\n\t// A throwaway model only used to read static metadata (provider/modelId/urls);\n\t// its fetch is never invoked for those synchronous reads.\n\tconst refModel = first.plugin.create({\n\t\tmodelId: first.modelId,\n\t\tfetch: (async () => {\n\t\t\tthrow new ServerFallbackCaptureStop();\n\t\t}) as typeof globalThis.fetch,\n\t\t...(first.info.baseURL ? { baseURL: first.info.baseURL } : {}),\n\t});\n\n\tconst cache = buildGatewayControls(gatewayOptions, opts);\n\n\tconst dispatch = async (\n\t\tmethod: \"doGenerate\" | \"doStream\",\n\t\toptions: LanguageModelV3CallOptions,\n\t): Promise<unknown> => {\n\t\t// 1) Capture each leg's native request without hitting the network.\n\t\tconst entries: GatewayEntry[] = [];\n\t\tfor (const leg of legs) {\n\t\t\tlet captured: { url: string; init?: RequestInit } | undefined;\n\t\t\tconst captureFetch = (async (input: RequestInfo | URL, init?: RequestInit) => {\n\t\t\t\tcaptured = {\n\t\t\t\t\turl: typeof input === \"string\" ? input : input.toString(),\n\t\t\t\t\tinit,\n\t\t\t\t};\n\t\t\t\tthrow new ServerFallbackCaptureStop();\n\t\t\t}) as typeof globalThis.fetch;\n\n\t\t\tconst model = leg.plugin.create({\n\t\t\t\tmodelId: leg.modelId,\n\t\t\t\tfetch: captureFetch,\n\t\t\t\t...(leg.info.baseURL ? { baseURL: leg.info.baseURL } : {}),\n\t\t\t});\n\t\t\ttry {\n\t\t\t\tawait (model[method] as (o: LanguageModelV3CallOptions) => Promise<unknown>)(\n\t\t\t\t\toptions,\n\t\t\t\t);\n\t\t\t} catch (e) {\n\t\t\t\tif (!(e instanceof ServerFallbackCaptureStop)) throw e;\n\t\t\t}\n\t\t\tif (!captured) {\n\t\t\t\tthrow new GatewayDelegateError(\n\t\t\t\t\t\"dispatch\",\n\t\t\t\t\t`Server-side fallback leg \"${leg.slug}\" produced no request to dispatch.`,\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst url = captured.url;\n\t\t\tconst endpoint = leg.info.transformEndpoint\n\t\t\t\t? leg.info.transformEndpoint(url)\n\t\t\t\t: new URL(url).pathname.replace(/^\\//, \"\") + (new URL(url).search || \"\");\n\t\t\tconst body = JSON.parse(asText(captured.init?.body)) as Record<string, unknown>;\n\n\t\t\tentries.push(\n\t\t\t\tbuildGatewayEntry({\n\t\t\t\t\tproviderId: leg.info.gatewayProviderId,\n\t\t\t\t\tendpoint,\n\t\t\t\t\tinitHeaders: captured.init?.headers,\n\t\t\t\t\tbody,\n\t\t\t\t\t...(opts.byok ? {} : { stripAuthHeaders: leg.info.authHeaders }),\n\t\t\t\t\t...(opts.extraHeaders ? { extraHeaders: opts.extraHeaders } : {}),\n\t\t\t\t\tcache,\n\t\t\t\t}),\n\t\t\t);\n\t\t}\n\n\t\t// 2) One gateway run with all legs; `cf-aig-step` names the winner.\n\t\tconst gw = (binding as unknown as { gateway(id: string): AiGatewayRunner }).gateway(\n\t\t\tgatewayId,\n\t\t);\n\t\tconst abortSignal = (options as { abortSignal?: AbortSignal }).abortSignal;\n\t\tconst runOptions: Record<string, unknown> = {};\n\t\tif (abortSignal) runOptions.signal = abortSignal;\n\t\tconst resp = await gw.run(entries, runOptions);\n\t\tfireDispatch(resp, selection, callOptions);\n\n\t\t// 3) Feed the raw winner response into its own model so its parser shapes\n\t\t//    the result for that leg's wire format.\n\t\tconst step = Number.parseInt(resp.headers.get(\"cf-aig-step\") ?? \"0\", 10);\n\t\tconst winner = legs[step] ?? first;\n\t\tconst winnerModel = winner.plugin.create({\n\t\t\tmodelId: winner.modelId,\n\t\t\tfetch: (async () => resp) as typeof globalThis.fetch,\n\t\t\t...(winner.info.baseURL ? { baseURL: winner.info.baseURL } : {}),\n\t\t});\n\t\treturn (winnerModel[method] as (o: LanguageModelV3CallOptions) => Promise<unknown>)(\n\t\t\toptions,\n\t\t);\n\t};\n\n\treturn {\n\t\tspecificationVersion: \"v3\",\n\t\tprovider: refModel.provider,\n\t\tmodelId: refModel.modelId,\n\t\tsupportedUrls: refModel.supportedUrls,\n\t\tdoGenerate(options) {\n\t\t\treturn dispatch(\"doGenerate\", options) as ReturnType<LanguageModelV3[\"doGenerate\"]>;\n\t\t},\n\t\tdoStream(options) {\n\t\t\treturn dispatch(\"doStream\", options) as ReturnType<LanguageModelV3[\"doStream\"]>;\n\t\t},\n\t} as LanguageModelV3;\n}\n","import { AISearchChatLanguageModel } from \"./aisearch-chat-language-model\";\nimport type { AISearchChatSettings } from \"./aisearch-chat-settings\";\nimport { createRun } from \"./utils\";\nimport {\n\tWorkersAIEmbeddingModel,\n\ttype WorkersAIEmbeddingSettings,\n} from \"./workersai-embedding-model\";\nimport { WorkersAIChatLanguageModel } from \"./workersai-chat-language-model\";\nimport type { WorkersAIChatSettings } from \"./workersai-chat-settings\";\nimport { WorkersAIImageModel } from \"./workersai-image-model\";\nimport type { WorkersAIImageSettings } from \"./workersai-image-settings\";\nimport { WorkersAITranscriptionModel } from \"./workersai-transcription-model\";\nimport type { WorkersAITranscriptionSettings } from \"./workersai-transcription-settings\";\nimport { WorkersAISpeechModel } from \"./workersai-speech-model\";\nimport type { WorkersAISpeechSettings } from \"./workersai-speech-settings\";\nimport { WorkersAIRerankingModel } from \"./workersai-reranking-model\";\nimport type { WorkersAIRerankingSettings } from \"./workersai-reranking-settings\";\nimport type {\n\tEmbeddingModels,\n\tImageGenerationModels,\n\tKnownTextGenerationModels,\n\tTextGenerationModels,\n\tTranscriptionModels,\n\tSpeechModels,\n\tRerankingModels,\n} from \"./workersai-models\";\n\n// Re-export deprecated AutoRAG aliases\nexport { AutoRAGChatLanguageModel } from \"./autorag-chat-language-model\";\nexport type { AutoRAGChatSettings } from \"./autorag-chat-settings\";\n\n// Export new AI Search types\nexport { AISearchChatLanguageModel } from \"./aisearch-chat-language-model\";\nexport type { AISearchChatSettings } from \"./aisearch-chat-settings\";\n\n// Export transcription and speech types\nexport { WorkersAITranscriptionModel } from \"./workersai-transcription-model\";\nexport type { WorkersAITranscriptionSettings } from \"./workersai-transcription-settings\";\nexport { WorkersAISpeechModel } from \"./workersai-speech-model\";\nexport type { WorkersAISpeechSettings } from \"./workersai-speech-settings\";\nexport { WorkersAIRerankingModel } from \"./workersai-reranking-model\";\nexport type { WorkersAIRerankingSettings } from \"./workersai-reranking-settings\";\n\n// ---------------------------------------------------------------------------\n// AI Gateway delegate (route catalog models through AI Gateway)\n//\n// The delegate factory itself is internal — it's wired through\n// `createWorkersAI({ providers })` (see below), so `createWorkersAI` is the\n// single public entry point. The transport types, error classes, registry, and\n// resume helpers are safe to re-export here (no optional `@ai-sdk/*` peer\n// imports). The provider plugins (`openai`, `anthropic`, `google`) stay\n// sub-path-only so those packages remain optional.\n// ---------------------------------------------------------------------------\n\nexport {\n\ttype Billing,\n\tcreateClientFallbackModel,\n\ttype DelegateCallOptions,\n\ttype DispatchInfo,\n\ttype FallbackAttempt,\n\ttype FallbackLeg,\n\ttype FallbackOptions,\n\tGatewayDelegateError,\n\ttype GatewayErrorCode,\n\ttype GatewayErrorContext,\n\tGATEWAY_PROVIDERS,\n\ttype GatewayProviderInfo,\n\ttype ParsedSlug,\n\ttype ProviderPlugin,\n\ttype ResumableStreamOptions,\n\ttype ResumeExpiredPolicy,\n\ttype Transport,\n\ttype WireFormat,\n\tWorkersAIFallbackError,\n\tWorkersAIGatewayError,\n\tcreateResumableStream,\n\tdetectProviderByUrl,\n\tfindProviderBySlug,\n\tparseSlug,\n\tselectTransport,\n\twireableProviders,\n} from \"./gateway-delegate\";\nexport {\n\tcreateGatewayFetch,\n\tcreateGatewayProvider,\n\ttype GatewayFetchConfig,\n} from \"./gateway-provider\";\n\nimport {\n\tcreateGatewayDelegate,\n\ttype DelegateCallOptions,\n\ttype GatewayDelegate,\n\ttype ProviderPlugin,\n\ttype ResumeExpiredPolicy,\n\ttype WireFormat,\n} from \"./gateway-delegate\";\n\n// ---------------------------------------------------------------------------\n// Workers AI\n// ---------------------------------------------------------------------------\n\n/**\n * The account-wide AI Gateway used for catalog routing when no `gateway` is\n * configured. Every Cloudflare account has a `\"default\"` gateway.\n */\nconst DEFAULT_GATEWAY_ID = \"default\";\nconst DYNAMIC_ROUTE_WIRE_FORMAT: WireFormat = \"openai\";\n\nexport type WorkersAISettings = (\n\t| {\n\t\t\t/**\n\t\t\t * Provide a Cloudflare AI binding.\n\t\t\t */\n\t\t\tbinding: Ai;\n\n\t\t\t/**\n\t\t\t * Credentials must be absent when a binding is given.\n\t\t\t */\n\t\t\taccountId?: never;\n\t\t\tapiKey?: never;\n\t  }\n\t| {\n\t\t\t/**\n\t\t\t * Provide Cloudflare API credentials directly. Must be used if a binding is not specified.\n\t\t\t */\n\t\t\taccountId: string;\n\t\t\tapiKey: string;\n\t\t\t/**\n\t\t\t * Both binding must be absent if credentials are used directly.\n\t\t\t */\n\t\t\tbinding?: never;\n\n\t\t\t/**\n\t\t\t * Custom fetch implementation. You can use it as a middleware to\n\t\t\t * intercept requests, or to provide a custom fetch implementation\n\t\t\t * for e.g. testing. Only available in credentials mode.\n\t\t\t */\n\t\t\tfetch?: typeof globalThis.fetch;\n\t  }\n) & {\n\t/**\n\t * Optionally specify a gateway. For third-party catalog routing (see\n\t * `providers`) this defaults to the account's `\"default\"` gateway when unset.\n\t */\n\tgateway?: GatewayOptions;\n\n\t/**\n\t * Provider plugins that enable routing third-party catalog models\n\t * (e.g. `\"openai/gpt-5-mini\"`) through AI Gateway. Supply them from the\n\t * sub-path modules, e.g. `import { openai } from \"workers-ai-provider/openai\"`.\n\t *\n\t * When set, calling the provider with a `\"<provider>/<model>\"` slug (anything\n\t * that is not a `@cf/...` Workers AI model id) is automatically dispatched\n\t * through the {@link createGatewayDelegate | gateway delegate}. Leaving this\n\t * unset preserves the exact prior behavior — only Workers AI models are built.\n\t *\n\t * @experimental The gateway delegate is an experimental surface.\n\t */\n\tproviders?: ProviderPlugin[];\n\n\t/**\n\t * Default resume behavior for gateway-routed catalog models. Defaults to\n\t * `true`. Overridable per call. Only relevant when `providers` is set.\n\t */\n\tresume?: boolean;\n\n\t/**\n\t * Default resume-expiry policy for gateway-routed catalog models (run path).\n\t * Defaults to `\"error\"`. Only relevant when `providers` is set.\n\t */\n\tonResumeExpired?: ResumeExpiredPolicy;\n};\n\n/**\n * True when a literal model id is a `\"<provider>/<model>\"` AI Gateway catalog\n * slug rather than a `@cf/...` Workers AI id. Bare `string` (a non-literal,\n * e.g. a variable) resolves to `false` so the common path keeps chat settings.\n */\ntype IsCatalogSlug<M extends string> = string extends M\n\t? false\n\t: M extends `@${string}`\n\t\t? false\n\t\t: M extends `dynamic/${string}`\n\t\t\t? false\n\t\t\t: M extends `${string}/${string}`\n\t\t\t\t? true\n\t\t\t\t: false;\n\ntype IsDynamicRoute<M extends string> = string extends M\n\t? false\n\t: M extends `dynamic/${string}`\n\t\t? true\n\t\t: false;\n\n/**\n * Picks the per-model settings type from the (captured) literal model id:\n * `DelegateCallOptions` for catalog slugs, `WorkersAIChatSettings` otherwise.\n * This is what lets `workersai(\"openai/gpt-5\", { … })` autocomplete delegate\n * options while `workersai(\"@cf/…\", { … })` autocompletes chat settings.\n */\ntype ModelSettings<M extends string> =\n\tIsCatalogSlug<M> extends true\n\t\t? DelegateCallOptions\n\t\t: IsDynamicRoute<M> extends true\n\t\t\t? DelegateCallOptions | WorkersAIChatSettings\n\t\t\t: WorkersAIChatSettings;\n\nexport interface WorkersAI {\n\t<M extends string>(\n\t\tmodelId: M | KnownTextGenerationModels,\n\t\tsettings?: ModelSettings<M>,\n\t): WorkersAIChatLanguageModel;\n\t/**\n\t * Creates a model for text generation. Accepts a `@cf/...` Workers AI id, or\n\t * a `\"<provider>/<model>\"` catalog slug when `providers` is configured.\n\t **/\n\tchat<M extends string>(\n\t\tmodelId: M | KnownTextGenerationModels,\n\t\tsettings?: ModelSettings<M>,\n\t): WorkersAIChatLanguageModel;\n\n\tembedding(\n\t\tmodelId: EmbeddingModels,\n\t\tsettings?: WorkersAIEmbeddingSettings,\n\t): WorkersAIEmbeddingModel;\n\n\ttextEmbedding(\n\t\tmodelId: EmbeddingModels,\n\t\tsettings?: WorkersAIEmbeddingSettings,\n\t): WorkersAIEmbeddingModel;\n\n\ttextEmbeddingModel(\n\t\tmodelId: EmbeddingModels,\n\t\tsettings?: WorkersAIEmbeddingSettings,\n\t): WorkersAIEmbeddingModel;\n\n\t/**\n\t * Creates a model for image generation.\n\t **/\n\timage(modelId: ImageGenerationModels, settings?: WorkersAIImageSettings): WorkersAIImageModel;\n\timageModel(\n\t\tmodelId: ImageGenerationModels,\n\t\tsettings?: WorkersAIImageSettings,\n\t): WorkersAIImageModel;\n\n\t/**\n\t * Creates a model for speech-to-text transcription.\n\t **/\n\ttranscription(\n\t\tmodelId: TranscriptionModels,\n\t\tsettings?: WorkersAITranscriptionSettings,\n\t): WorkersAITranscriptionModel;\n\ttranscriptionModel(\n\t\tmodelId: TranscriptionModels,\n\t\tsettings?: WorkersAITranscriptionSettings,\n\t): WorkersAITranscriptionModel;\n\n\t/**\n\t * Creates a model for text-to-speech synthesis.\n\t **/\n\tspeech(modelId: SpeechModels, settings?: WorkersAISpeechSettings): WorkersAISpeechModel;\n\tspeechModel(modelId: SpeechModels, settings?: WorkersAISpeechSettings): WorkersAISpeechModel;\n\n\t/**\n\t * Creates a model for document reranking.\n\t **/\n\treranking(\n\t\tmodelId: RerankingModels,\n\t\tsettings?: WorkersAIRerankingSettings,\n\t): WorkersAIRerankingModel;\n\trerankingModel(\n\t\tmodelId: RerankingModels,\n\t\tsettings?: WorkersAIRerankingSettings,\n\t): WorkersAIRerankingModel;\n}\n\n/**\n * Create a Workers AI provider instance.\n */\nexport function createWorkersAI(options: WorkersAISettings): WorkersAI {\n\tif (!options.binding && !(\"accountId\" in options && \"apiKey\" in options)) {\n\t\tthrow new Error(\n\t\t\t\"Invalid Workers AI configuration: you must provide either a binding (e.g. { binding: env.AI }) \" +\n\t\t\t\t\"or credentials ({ accountId, apiKey }).\",\n\t\t);\n\t}\n\n\tlet binding: Ai;\n\tconst isBinding = !!options.binding;\n\n\tif (options.binding) {\n\t\tbinding = options.binding;\n\t} else {\n\t\tconst { accountId, apiKey } = options;\n\t\tbinding = {\n\t\t\trun: createRun({ accountId, apiKey, fetch: options.fetch }),\n\t\t} as Ai;\n\t}\n\n\tconst createChatModel = (modelId: TextGenerationModels, settings: WorkersAIChatSettings = {}) =>\n\t\tnew WorkersAIChatLanguageModel(modelId, settings, {\n\t\t\tbinding,\n\t\t\tgateway: options.gateway,\n\t\t\tprovider: \"workersai.chat\",\n\t\t\tisBinding,\n\t\t});\n\n\tconst toGatewayOptions = (\n\t\tgateway: GatewayOptions | string | undefined,\n\t): GatewayOptions | undefined => (typeof gateway === \"string\" ? { id: gateway } : gateway);\n\n\t// The bare unified-billing run path (`env.AI.run(model, …)`) shared by two\n\t// callers that both hit it WITHOUT the gateway delegate:\n\t//   - `dynamic/<route>` AI Gateway dynamic routes, and\n\t//   - `\"<vendor>/<model>\"` catalog slugs when no `providers` are configured\n\t//     (the #596 passthrough).\n\t// Neither has a transport choice, resume engine, or BYOK forwarding — those\n\t// only exist once `providers` are set and the delegate takes over — so this\n\t// path defaults the gateway (third-party run models need one), folds\n\t// cache/metadata into the gateway options, and rejects delegate-only options\n\t// loudly instead of letting `WorkersAIChatLanguageModel` spread them as junk\n\t// into `binding.run`'s options arg.\n\tconst createRunPathModel = (\n\t\tmodelId: TextGenerationModels,\n\t\tsettings: WorkersAIChatSettings & DelegateCallOptions = {},\n\t\tkind: \"dynamic\" | \"catalog\",\n\t) => {\n\t\tif (\n\t\t\tsettings.fallback ||\n\t\t\tsettings.transport === \"gateway\" ||\n\t\t\tsettings.resume === true ||\n\t\t\tsettings.onProgress ||\n\t\t\tsettings.onResumeExpired ||\n\t\t\tsettings.byok\n\t\t) {\n\t\t\tconst subject =\n\t\t\t\tkind === \"dynamic\"\n\t\t\t\t\t? `\"${modelId}\" is an AI Gateway dynamic route`\n\t\t\t\t\t: `\"${modelId}\" routes through the bare unified-billing run path because no \\`providers\\` are configured`;\n\t\t\tthrow new Error(\n\t\t\t\t`${subject}. It uses AI.run with OpenAI-compatible chat-completions wire format; ` +\n\t\t\t\t\t\"fallback, gateway transport, resume, BYOK, and resume callbacks are gateway-delegate \" +\n\t\t\t\t\t\"features — configure provider plugins to use them \" +\n\t\t\t\t\t\"(createWorkersAI({ binding: env.AI, providers: [openai] })), and for dynamic routes \" +\n\t\t\t\t\t\"set caching/fallback on the route or gateway instead of per call.\",\n\t\t\t);\n\t\t}\n\n\t\tconst gateway = {\n\t\t\t...(toGatewayOptions(settings.gateway) ??\n\t\t\t\toptions.gateway ?? { id: DEFAULT_GATEWAY_ID }),\n\t\t};\n\t\tif (settings.metadata) {\n\t\t\tgateway.metadata = {\n\t\t\t\t...(gateway.metadata ?? {}),\n\t\t\t\t...settings.metadata,\n\t\t\t};\n\t\t}\n\t\tif (settings.collectLog !== undefined) {\n\t\t\tgateway.collectLog = settings.collectLog;\n\t\t}\n\t\tif (settings.cacheTtl !== undefined) {\n\t\t\tgateway.cacheTtl = settings.cacheTtl;\n\t\t}\n\t\tif (settings.skipCache !== undefined) {\n\t\t\tgateway.skipCache = settings.skipCache;\n\t\t}\n\n\t\tconst chatSettings = {\n\t\t\t...settings,\n\t\t\tgateway,\n\t\t};\n\t\tdelete chatSettings.metadata;\n\t\tdelete chatSettings.collectLog;\n\t\tdelete chatSettings.cacheTtl;\n\t\tdelete chatSettings.skipCache;\n\t\tdelete chatSettings.resume;\n\t\tdelete chatSettings.fallback;\n\t\tdelete chatSettings.transport;\n\t\tdelete chatSettings.onDispatch;\n\t\tdelete chatSettings.onProgress;\n\t\tdelete chatSettings.onResumeExpired;\n\t\tdelete chatSettings.byok;\n\n\t\tconst plugin = options.providers?.find((p) => p.wireFormat === DYNAMIC_ROUTE_WIRE_FORMAT);\n\t\tif (!plugin) {\n\t\t\t// Dynamic routes with providers configured but no OpenAI plugin can't be\n\t\t\t// parsed (they always return openai-wire), so guide the user. The\n\t\t\t// catalog passthrough only reaches here with no providers at all, where\n\t\t\t// the built-in `WorkersAIChatLanguageModel` parser is the intended\n\t\t\t// fallback (#596) — so let it through.\n\t\t\tif (kind === \"dynamic\" && options.providers?.length) {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t`\"${modelId}\" is an AI Gateway dynamic route. Dynamic routes return OpenAI-compatible ` +\n\t\t\t\t\t\t\"chat-completions wire format on the AI.run path, so configure the OpenAI \" +\n\t\t\t\t\t\t'provider plugin: import { openai } from \"workers-ai-provider/openai\"; ' +\n\t\t\t\t\t\t\"createWorkersAI({ binding: env.AI, providers: [openai] }).\",\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn createChatModel(modelId, chatSettings);\n\t\t}\n\t\tconst fetchImpl = (async (\n\t\t\t_input: RequestInfo | URL,\n\t\t\tinit?: RequestInit,\n\t\t): Promise<Response> => {\n\t\t\tconst body = JSON.parse(String(init?.body ?? \"{}\")) as Record<string, unknown>;\n\t\t\tdelete body.model;\n\n\t\t\tconst runOptions: Record<string, unknown> = {\n\t\t\t\tgateway,\n\t\t\t\treturnRawResponse: true,\n\t\t\t\t...(settings.extraHeaders ? { extraHeaders: settings.extraHeaders } : {}),\n\t\t\t\t...(init?.signal ? { signal: init.signal } : {}),\n\t\t\t};\n\t\t\tconst response = await (\n\t\t\t\tbinding as unknown as {\n\t\t\t\t\trun(\n\t\t\t\t\t\tmodel: string,\n\t\t\t\t\t\tinputs: Record<string, unknown>,\n\t\t\t\t\t\toptions: Record<string, unknown>,\n\t\t\t\t\t): Promise<Response>;\n\t\t\t\t}\n\t\t\t).run(modelId, body, runOptions);\n\t\t\tsettings.onDispatch?.({\n\t\t\t\ttransport: \"run\",\n\t\t\t\tresumeEnabled: false,\n\t\t\t\twarnings: [],\n\t\t\t\tstatus: response.status,\n\t\t\t\trunId: response.headers.get(\"cf-aig-run-id\"),\n\t\t\t\tcfStep: response.headers.get(\"cf-aig-step\"),\n\t\t\t\tcacheStatus: response.headers.get(\"cf-aig-cache-status\"),\n\t\t\t\tlogId: response.headers.get(\"cf-aig-log-id\"),\n\t\t\t});\n\t\t\treturn response;\n\t\t}) as typeof globalThis.fetch;\n\n\t\treturn plugin.create({\n\t\t\tmodelId,\n\t\t\tfetch: fetchImpl,\n\t\t}) as unknown as WorkersAIChatLanguageModel;\n\t};\n\n\t// Third-party catalog routing: when `providers` is configured, a non-`@cf/`\n\t// `\"<provider>/<model>\"` slug is dispatched through the gateway delegate\n\t// instead of being treated as a Workers AI model id. Built lazily so the\n\t// delegate (and its plugin requirements) only materializes on first use.\n\tlet delegate: GatewayDelegate | undefined;\n\tconst getDelegate = (slug: string): GatewayDelegate => {\n\t\tif (!options.providers?.length) {\n\t\t\tthrow new Error(\n\t\t\t\t`\"${slug}\" looks like a third-party AI Gateway catalog model, but this Workers AI ` +\n\t\t\t\t\t\"provider was not configured to route them. Pass provider plugins, e.g.:\\n\" +\n\t\t\t\t\t'  import { openai } from \"workers-ai-provider/openai\";\\n' +\n\t\t\t\t\t\"  createWorkersAI({ binding: env.AI, providers: [openai] });\\n\" +\n\t\t\t\t\t'A gateway defaults to \"default\" but can be set via `gateway`. ' +\n\t\t\t\t\t'Otherwise use a Workers AI model id (e.g. \"@cf/meta/llama-3.1-8b-instruct\").',\n\t\t\t);\n\t\t}\n\t\tdelegate ??= createGatewayDelegate({\n\t\t\tbinding,\n\t\t\t// Catalog routing needs a gateway (resume runs through it). When one\n\t\t\t// isn't configured, fall back to the account's `\"default\"` gateway so\n\t\t\t// `createWorkersAI({ providers })` works out of the box. An explicit\n\t\t\t// `gateway` (here or per call) always wins.\n\t\t\tgateway: options.gateway ?? { id: DEFAULT_GATEWAY_ID },\n\t\t\tproviders: options.providers,\n\t\t\tresume: options.resume,\n\t\t\tonResumeExpired: options.onResumeExpired,\n\t\t});\n\t\treturn delegate;\n\t};\n\n\t// Workers AI model ids are usually `@cf/...`, but AI Gateway dynamic routes\n\t// use the `dynamic/<route>` namespace and must pass through to `AI.run`.\n\t// Other non-`@` ids with a slash are treated as catalog slugs.\n\tconst isGatewaySlug = (id: unknown): id is string =>\n\t\ttypeof id === \"string\" &&\n\t\t!id.startsWith(\"@\") &&\n\t\t!id.startsWith(\"dynamic/\") &&\n\t\tid.includes(\"/\");\n\n\t// Settings is the union of both shapes here; the public `WorkersAI` interface\n\t// narrows it per call via `ModelSettings<M>`. We branch at runtime and cast to\n\t// the concrete shape each path expects.\n\tconst buildChat = (\n\t\tmodelId: TextGenerationModels,\n\t\tsettings?: WorkersAIChatSettings | DelegateCallOptions,\n\t): WorkersAIChatLanguageModel => {\n\t\tif (typeof modelId === \"string\" && modelId.startsWith(\"dynamic/\")) {\n\t\t\treturn createRunPathModel(\n\t\t\t\tmodelId,\n\t\t\t\tsettings as (WorkersAIChatSettings & DelegateCallOptions) | undefined,\n\t\t\t\t\"dynamic\",\n\t\t\t);\n\t\t}\n\t\tif (isGatewaySlug(modelId)) {\n\t\t\t// Without provider plugins there's no gateway/BYOK routing to do, and a\n\t\t\t// bare `\"<vendor>/<model>\"` id is a valid Workers AI unified-billing run\n\t\t\t// model — `env.AI.run(\"deepseek/deepseek-v4-pro\")`. Route it through the\n\t\t\t// same bare run path as dynamic routes (defaults the gateway, folds\n\t\t\t// cache/metadata, rejects delegate-only options) instead of erroring.\n\t\t\t// Catalog routing (resume, fallback, caching, BYOK) only kicks in once\n\t\t\t// `providers` are set. (#596)\n\t\t\tif (!options.providers?.length) {\n\t\t\t\treturn createRunPathModel(\n\t\t\t\t\tmodelId,\n\t\t\t\t\tsettings as (WorkersAIChatSettings & DelegateCallOptions) | undefined,\n\t\t\t\t\t\"catalog\",\n\t\t\t\t);\n\t\t\t}\n\t\t\t// The delegate returns a `LanguageModelV3` built by the configured plugin.\n\t\t\t// It's structurally compatible with the AI SDK consumers this provider is\n\t\t\t// used with; the cast keeps the public return type unchanged.\n\t\t\treturn getDelegate(modelId)(\n\t\t\t\tmodelId,\n\t\t\t\tsettings as DelegateCallOptions,\n\t\t\t) as unknown as WorkersAIChatLanguageModel;\n\t\t}\n\t\treturn createChatModel(modelId, settings as WorkersAIChatSettings | undefined);\n\t};\n\n\tconst createImageModel = (\n\t\tmodelId: ImageGenerationModels,\n\t\tsettings: WorkersAIImageSettings = {},\n\t) =>\n\t\tnew WorkersAIImageModel(modelId, settings, {\n\t\t\tbinding,\n\t\t\tgateway: options.gateway,\n\t\t\tprovider: \"workersai.image\",\n\t\t});\n\tconst createEmbeddingModel = (\n\t\tmodelId: EmbeddingModels,\n\t\tsettings: WorkersAIEmbeddingSettings = {},\n\t) =>\n\t\tnew WorkersAIEmbeddingModel(modelId, settings, {\n\t\t\tbinding,\n\t\t\tgateway: options.gateway,\n\t\t\tprovider: \"workersai.embedding\",\n\t\t});\n\n\tconst createTranscriptionModel = (\n\t\tmodelId: TranscriptionModels,\n\t\tsettings: WorkersAITranscriptionSettings = {},\n\t) =>\n\t\tnew WorkersAITranscriptionModel(modelId, settings, {\n\t\t\tbinding,\n\t\t\tgateway: options.gateway,\n\t\t\tprovider: \"workersai.transcription\",\n\t\t\tisBinding,\n\t\t\tcredentials:\n\t\t\t\t!isBinding && \"accountId\" in options\n\t\t\t\t\t? { accountId: options.accountId, apiKey: options.apiKey }\n\t\t\t\t\t: undefined,\n\t\t});\n\n\tconst createSpeechModel = (modelId: SpeechModels, settings: WorkersAISpeechSettings = {}) =>\n\t\tnew WorkersAISpeechModel(modelId, settings, {\n\t\t\tbinding,\n\t\t\tgateway: options.gateway,\n\t\t\tprovider: \"workersai.speech\",\n\t\t});\n\n\tconst createRerankingModel = (\n\t\tmodelId: RerankingModels,\n\t\tsettings: WorkersAIRerankingSettings = {},\n\t) =>\n\t\tnew WorkersAIRerankingModel(modelId, settings, {\n\t\t\tbinding,\n\t\t\tgateway: options.gateway,\n\t\t\tprovider: \"workersai.reranking\",\n\t\t});\n\n\tconst provider = (\n\t\tmodelId: TextGenerationModels,\n\t\tsettings?: WorkersAIChatSettings | DelegateCallOptions,\n\t) => {\n\t\tif (new.target) {\n\t\t\tthrow new Error(\"The WorkersAI model function cannot be called with the new keyword.\");\n\t\t}\n\t\treturn buildChat(modelId, settings);\n\t};\n\n\tprovider.chat = buildChat;\n\tprovider.embedding = createEmbeddingModel;\n\tprovider.textEmbedding = createEmbeddingModel;\n\tprovider.textEmbeddingModel = createEmbeddingModel;\n\tprovider.image = createImageModel;\n\tprovider.imageModel = createImageModel;\n\tprovider.transcription = createTranscriptionModel;\n\tprovider.transcriptionModel = createTranscriptionModel;\n\tprovider.speech = createSpeechModel;\n\tprovider.speechModel = createSpeechModel;\n\tprovider.reranking = createRerankingModel;\n\tprovider.rerankingModel = createRerankingModel;\n\n\treturn provider;\n}\n\n// ---------------------------------------------------------------------------\n// AI Search (formerly AutoRAG)\n// ---------------------------------------------------------------------------\n\nexport type AISearchSettings = {\n\tbinding: AutoRAG;\n};\n\nexport interface AISearchProvider {\n\t(settings?: AISearchChatSettings): AISearchChatLanguageModel;\n\t/**\n\t * Creates a model for text generation.\n\t **/\n\tchat(settings?: AISearchChatSettings): AISearchChatLanguageModel;\n}\n\n/**\n * Create an AI Search provider instance.\n *\n * AI Search (formerly AutoRAG) is Cloudflare's managed search service.\n * @see https://developers.cloudflare.com/ai-search/\n */\nexport function createAISearch(\n\toptions: AISearchSettings,\n\t/** @internal */\n\tproviderName = \"aisearch.chat\",\n): AISearchProvider {\n\tconst binding = options.binding;\n\n\tconst createChatModel = (settings: AISearchChatSettings = {}) =>\n\t\tnew AISearchChatLanguageModel(\"@cf/meta/llama-3.3-70b-instruct-fp8-fast\", settings, {\n\t\t\tbinding,\n\t\t\tprovider: providerName,\n\t\t});\n\n\tconst provider = (settings?: AISearchChatSettings) => {\n\t\tif (new.target) {\n\t\t\tthrow new Error(\"The AISearch model function cannot be called with the new keyword.\");\n\t\t}\n\t\treturn createChatModel(settings);\n\t};\n\n\tprovider.chat = createChatModel;\n\n\treturn provider;\n}\n\n// ---------------------------------------------------------------------------\n// Deprecated AutoRAG aliases\n// ---------------------------------------------------------------------------\n\n/**\n * @deprecated Use `AISearchSettings` instead. AutoRAG has been renamed to AI Search.\n * @see https://developers.cloudflare.com/ai-search/\n */\nexport type AutoRAGSettings = AISearchSettings;\n\n/**\n * @deprecated Use `AISearchProvider` instead. AutoRAG has been renamed to AI Search.\n * @see https://developers.cloudflare.com/ai-search/\n */\nexport type AutoRAGProvider = AISearchProvider;\n\nlet autoRAGWarned = false;\n\n/**\n * @deprecated Use `createAISearch` instead. AutoRAG has been renamed to AI Search.\n * @see https://developers.cloudflare.com/ai-search/\n */\nexport function createAutoRAG(options: AISearchSettings): AISearchProvider {\n\tif (!autoRAGWarned) {\n\t\tautoRAGWarned = true;\n\t\tconsole.warn(\n\t\t\t\"[workers-ai-provider] createAutoRAG is deprecated. Use createAISearch instead. \" +\n\t\t\t\t\"AutoRAG has been renamed to AI Search. \" +\n\t\t\t\t\"See https://developers.cloudflare.com/ai-search/\",\n\t\t);\n\t}\n\treturn createAISearch(options, \"autorag.chat\");\n}\n"],"mappings":"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"}