@ai-sdk/provider-utils
Version:
1,329 lines (1,280 loc) • 106 kB
TypeScript
import { SharedV4FileDataUrl, SharedV4FileDataReference, SharedV4FileDataText, SharedV4ProviderOptions, SharedV4ProviderReference, JSONValue, ImageModelV4File, LanguageModelV4FunctionTool, LanguageModelV4ProviderTool, AISDKError, JSONSchema7, JSONParseError, TypeValidationError, APICallError, LanguageModelV4Prompt, LanguageModelV4CallOptions, SharedV4Warning, JSONObject, LanguageModelV4FilePart, LanguageModelV4StreamPart, SharedV4ProviderMetadata, Experimental_TranscriptionModelV4StreamPart, TypeValidationContext } from '@ai-sdk/provider';
export { getErrorMessage } from '@ai-sdk/provider';
import { StandardSchemaV1, StandardJSONSchemaV1 } from '@standard-schema/spec';
export * from '@standard-schema/spec';
import * as z3 from 'zod/v3';
import * as z4 from 'zod/v4';
export { WORKFLOW_DESERIALIZE, WORKFLOW_SERIALIZE } from '@workflow/serde';
export { EventSourceMessage, EventSourceParserStream } from 'eventsource-parser/stream';
/**
* A value that can be provided either as a single item, an array of items,
* or be left undefined.
*/
type Arrayable<T> = T | T[] | undefined;
/**
* Normalizes a possibly undefined or non-array value into an array.
*/
declare function asArray<T>(value: Arrayable<T>): T[];
declare function combineHeaders(...headers: Array<Record<string, string | undefined> | undefined>): Record<string, string | undefined>;
type WebSocketLike = {
readyState: number;
/** Bytes queued by `send` but not yet transmitted (native + `ws`). */
readonly bufferedAmount?: number;
send(data: string | Uint8Array | ArrayBuffer): void;
close(code?: number, reason?: string): void;
onopen: ((event: unknown) => void) | null;
onmessage: ((event: {
data: unknown;
}) => void) | null;
onerror: ((event: unknown) => void) | null;
onclose: ((event: unknown) => void) | null;
};
type WebSocketConstructor = new (url: string | URL, protocols?: string | string[], options?: {
headers?: Record<string, string | undefined>;
}) => WebSocketLike;
declare function getWebSocketConstructor(webSocket: WebSocketConstructor | undefined): WebSocketConstructor;
/**
* Converts an http(s) URL to the corresponding ws(s) URL.
*/
declare function toWebSocketUrl(url: string | URL): URL;
/**
* Reads WebSocket message data as text, handling string, binary,
* and Blob payloads.
*/
declare function readWebSocketMessageText(data: unknown): Promise<string>;
/**
* Waits until the socket's send buffer drains below `highWaterMark` bytes.
* No-op for implementations that do not expose `bufferedAmount`. There is no
* portable drain event, so this polls. Returns as soon as the socket is no
* longer open or the signal aborts — `bufferedAmount` never drains on a
* closed socket, so waiting on would poll forever.
*/
declare function waitForWebSocketBufferDrain(socket: WebSocketLike, { highWaterMark, pollIntervalMs, abortSignal, }?: {
highWaterMark?: number;
pollIntervalMs?: number;
abortSignal?: AbortSignal;
}): Promise<void>;
interface WebSocketConnection {
/** Undefined when the constructor threw or the signal was already aborted. */
socket: WebSocketLike | undefined;
/**
* Unregisters the abort listener and closes the socket. Never throws.
* Handlers stay attached; callers guard their own terminal state.
*/
close: (code?: number) => void;
}
/**
* Opens a WebSocket for a provider model, owning the transport-generic layer
* (analogous to `postToApi` for HTTP): constructor resolution, header hygiene,
* abort wiring, and message decoding. Callers own the URL, the auth channel
* (subprotocols vs headers), and the wire protocol.
*/
declare function connectToWebSocket({ url, protocols, headers, webSocket, abortSignal, onOpen, onMessageText, onProcessingError, onSocketError, onClose, onAbort, }: {
url: string | URL;
protocols?: string | string[];
headers?: Record<string, string | undefined>;
webSocket?: WebSocketConstructor;
abortSignal?: AbortSignal;
onOpen?: (socket: WebSocketLike) => void;
/** One decoded message. Throws and rejections go to `onProcessingError`. */
onMessageText: (text: string) => void | PromiseLike<void>;
/** Constructor throws and message decoding/processing failures. */
onProcessingError: (error: unknown) => void;
onSocketError?: () => void;
onClose?: () => void;
/** Also called (without opening a socket) when the signal is already aborted. */
onAbort?: (reason: unknown) => void;
}): WebSocketConnection;
/**
* Converts an AsyncIterator to a ReadableStream.
*
* @template T - The type of elements produced by the AsyncIterator.
* @param { <T>} iterator - The AsyncIterator to convert.
* @returns {ReadableStream<T>} - A ReadableStream that provides the same data as the AsyncIterator.
*/
declare function convertAsyncIteratorToReadableStream<T>(iterator: AsyncIterator<T>): ReadableStream<T>;
/**
* Data content. Can either be a base64-encoded string, a Uint8Array, an ArrayBuffer, or a Buffer.
*/
type DataContent = string | Uint8Array | ArrayBuffer | Buffer;
/**
* File data variant containing raw bytes (`Uint8Array`, `ArrayBuffer`, or
* `Buffer`) or a base64-encoded string.
*
* This is slightly more permissive than `SharedV4FileDataData`.
*/
interface FileDataData {
type: 'data';
data: DataContent;
}
/**
* File data variant containing a URL that points to the file.
*/
type FileDataUrl = SharedV4FileDataUrl;
/**
* File data variant containing a provider reference (`{ [provider]: id }`).
*/
type FileDataReference = SharedV4FileDataReference;
/**
* File data variant containing inline text content (e.g. an inline text
* document).
*/
type FileDataText = SharedV4FileDataText;
/**
* File data as a tagged discriminated union:
*
* - `{ type: 'data', data }`: raw bytes (`Uint8Array`, `ArrayBuffer`, or
* `Buffer`) or a base64-encoded string.
* - `{ type: 'url', url }`: a URL that points to the file.
* - `{ type: 'reference', reference }`: a provider reference (`{ [provider]: id }`).
* - `{ type: 'text', text }`: inline text content (e.g. an inline text document).
*/
type FileData = FileDataData | FileDataUrl | FileDataReference | FileDataText;
/**
* Additional provider-specific options.
*
* They are passed through to the provider from the AI SDK and enable
* provider-specific functionality that can be fully encapsulated in the provider.
*/
type ProviderOptions = SharedV4ProviderOptions;
/**
* A mapping of provider names to provider-specific file identifiers.
*
* Provider references allow files to be identified across different
* providers without re-uploading, by storing each provider's own
* identifier for the same logical file.
*/
type ProviderReference = SharedV4ProviderReference;
/**
* Text content part of a prompt. It contains a string of text.
*/
interface TextPart {
type: 'text';
/**
* The text content.
*/
text: string;
/**
* Additional provider-specific metadata. They are passed through
* to the provider from the AI SDK and enable provider-specific
* functionality that can be fully encapsulated in the provider.
*/
providerOptions?: ProviderOptions;
}
/**
* Image content part of a prompt. It contains an image.
*
* @deprecated Use `FilePart` with `mediaType: 'image'` instead:
* `{ type: 'file', mediaType: 'image', data: { type: 'data', data } }`.
*/
interface ImagePart {
type: 'image';
/**
* Image data. Can either be:
*
* - data: a base64-encoded string, a Uint8Array, an ArrayBuffer, or a Buffer
* - URL: a URL that points to the image
* - ProviderReference: a provider reference from `uploadFile`
*/
image: DataContent | URL | ProviderReference;
/**
* Optional IANA media type of the image.
*
* @see https://www.iana.org/assignments/media-types/media-types.xhtml
*/
mediaType?: string;
/**
* Additional provider-specific metadata. They are passed through
* to the provider from the AI SDK and enable provider-specific
* functionality that can be fully encapsulated in the provider.
*/
providerOptions?: ProviderOptions;
}
/**
* File content part of a prompt. It contains a file.
*/
interface FilePart {
type: 'file';
/**
* File data. Either a tagged shape or a bare shorthand:
*
* - `{ type: 'data', data }` or bare `DataContent`: raw bytes
* (base64 string, Uint8Array, ArrayBuffer, Buffer)
* - `{ type: 'url', url }` or bare `URL`: a URL that points to the file
* - `{ type: 'reference', reference }` or bare `ProviderReference`:
* a provider reference from `uploadFile`
* - `{ type: 'text', text }`: inline text content (tagged only)
*/
data: FileData | DataContent | URL | ProviderReference;
/**
* Optional filename of the file.
*/
filename?: string;
/**
* Either a full IANA media type (`type/subtype`, e.g. `image/png`) or just
* the top-level IANA segment (e.g. `image`, `audio`, `video`, `text`).
*
* `*`-subtype wildcards (e.g. `image/*`) are normalized as equivalent to the
* top-level segment alone (e.g. `image`). Providers can use the helpers in
* `@ai-sdk/provider-utils` (`isFullMediaType`, `getTopLevelMediaType`,
* `detectMediaType`) to resolve the field according to their API
* requirements.
*
* @see https://www.iana.org/assignments/media-types/media-types.xhtml
*/
mediaType: string;
/**
* Additional provider-specific metadata. They are passed through
* to the provider from the AI SDK and enable provider-specific
* functionality that can be fully encapsulated in the provider.
*/
providerOptions?: ProviderOptions;
}
/**
* Reasoning content part of a prompt. It contains a reasoning.
*/
interface ReasoningPart {
type: 'reasoning';
/**
* The reasoning text.
*/
text: string;
/**
* Additional provider-specific metadata. They are passed through
* to the provider from the AI SDK and enable provider-specific
* functionality that can be fully encapsulated in the provider.
*/
providerOptions?: ProviderOptions;
}
/**
* Custom content part of a prompt. It contains no standardized payload beyond
* provider-specific options.
*/
interface CustomPart {
type: 'custom';
/**
* The kind of custom content, in the format `{provider}.{provider-type}`.
*/
kind: `${string}.${string}`;
/**
* Additional provider-specific metadata. They are passed through
* to the provider from the AI SDK and enable provider-specific
* functionality that can be fully encapsulated in the provider.
*/
providerOptions?: ProviderOptions;
}
/**
* Reasoning file content part of a prompt. It contains a file generated as part of reasoning.
*/
interface ReasoningFilePart {
type: 'reasoning-file';
/**
* Reasoning file data.
*
* Reasoning files originate from a model's reasoning output and are always
* raw bytes or a fetchable URL. Unlike `FilePart.data`, the `reference` and
* `text` shapes are not supported here: provider references describe files
* uploaded by the user (not produced as model output), and reasoning text is
* carried by `ReasoningPart` rather than as a file.
*
* Either a tagged shape or a bare shorthand:
*
* - `{ type: 'data', data }` or bare `DataContent`: raw bytes
* (base64 string, Uint8Array, ArrayBuffer, Buffer)
* - `{ type: 'url', url }` or bare `URL`: a URL that points to the file
*/
data: FileDataData | FileDataUrl | DataContent | URL;
/**
* IANA media type of the file.
*
* @see https://www.iana.org/assignments/media-types/media-types.xhtml
*/
mediaType: string;
/**
* Additional provider-specific metadata. They are passed through
* to the provider from the AI SDK and enable provider-specific
* functionality that can be fully encapsulated in the provider.
*/
providerOptions?: ProviderOptions;
}
/**
* Tool call content part of a prompt. It contains a tool call (usually generated by the AI model).
*/
interface ToolCallPart {
type: 'tool-call';
/**
* ID of the tool call. This ID is used to match the tool call with the tool result.
*/
toolCallId: string;
/**
* Name of the tool that is being called.
*/
toolName: string;
/**
* Arguments of the tool call. This is a JSON-serializable object that matches the tool's input schema.
*/
input: unknown;
/**
* Additional provider-specific metadata. They are passed through
* to the provider from the AI SDK and enable provider-specific
* functionality that can be fully encapsulated in the provider.
*/
providerOptions?: ProviderOptions;
/**
* Whether the tool call was executed by the provider.
*/
providerExecuted?: boolean;
}
/**
* Tool result content part of a prompt. It contains the result of the tool call with the matching ID.
*/
interface ToolResultPart {
type: 'tool-result';
/**
* ID of the tool call that this result is associated with.
*/
toolCallId: string;
/**
* Name of the tool that generated this result.
*/
toolName: string;
/**
* Result of the tool call. This is a JSON-serializable object.
*/
output: ToolResultOutput;
/**
* Additional provider-specific metadata. They are passed through
* to the provider from the AI SDK and enable provider-specific
* functionality that can be fully encapsulated in the provider.
*/
providerOptions?: ProviderOptions;
}
/**
* Output of a tool result.
*/
type ToolResultOutput = {
/**
* Text tool output that should be directly sent to the API.
*/
type: 'text';
value: string;
/**
* Provider-specific options.
*/
providerOptions?: ProviderOptions;
} | {
type: 'json';
value: JSONValue;
/**
* Provider-specific options.
*/
providerOptions?: ProviderOptions;
} | {
/**
* Type when the user has denied the execution of the tool call.
*/
type: 'execution-denied';
/**
* Optional reason for the execution denial.
*/
reason?: string;
/**
* Provider-specific options.
*/
providerOptions?: ProviderOptions;
} | {
type: 'error-text';
value: string;
/**
* Provider-specific options.
*/
providerOptions?: ProviderOptions;
} | {
type: 'error-json';
value: JSONValue;
/**
* Provider-specific options.
*/
providerOptions?: ProviderOptions;
} | {
type: 'content';
value: Array<{
type: 'text';
/**
* Text content.
*/
text: string;
/**
* Provider-specific options.
*/
providerOptions?: ProviderOptions;
} | {
type: 'file';
/**
* File data as a tagged discriminated union:
*
* - `{ type: 'data', data }`: raw bytes
* (base64 string, Uint8Array, ArrayBuffer, Buffer)
* - `{ type: 'url', url }`: a URL that points to the file
* - `{ type: 'reference', reference }`: a provider reference
* from `uploadFile`
* - `{ type: 'text', text }`: inline text content (e.g. an inline
* text document)
*/
data: FileData;
/**
* Either a full IANA media type (`type/subtype`, e.g. `image/png`) or just
* the top-level IANA segment (e.g. `image`, `audio`, `video`, `text`).
*
* `*`-subtype wildcards (e.g. `image/*`) are normalized as equivalent to the
* top-level segment alone (e.g. `image`). Providers can use the helpers in
* `@ai-sdk/provider-utils` (`isFullMediaType`, `getTopLevelMediaType`,
* `detectMediaType`) to resolve the field according to their API
* requirements.
*
* @see https://www.iana.org/assignments/media-types/media-types.xhtml
*/
mediaType: string;
/**
* Optional filename of the file.
*/
filename?: string;
/**
* Provider-specific options.
*/
providerOptions?: ProviderOptions;
} | {
/**
* @deprecated Use 'file' with mediaType + tagged data instead:
* `{ type: 'file', mediaType, data: { type: 'data', data } }`.
*/
type: 'file-data';
/**
* Base-64 encoded media data.
*/
data: string;
/**
* IANA media type.
* @see https://www.iana.org/assignments/media-types/media-types.xhtml
*/
mediaType: string;
/**
* Optional filename of the file.
*/
filename?: string;
/**
* Provider-specific options.
*/
providerOptions?: ProviderOptions;
} | {
/**
* @deprecated Use 'file' with mediaType and tagged data instead:
* `{ type: 'file', mediaType, data: { type: 'url', url: new URL(url) } }`.
*/
type: 'file-url';
/**
* URL of the file.
*/
url: string;
/**
* IANA media type.
* @see https://www.iana.org/assignments/media-types/media-types.xhtml
*/
mediaType?: string;
/**
* Provider-specific options.
*/
providerOptions?: ProviderOptions;
} | {
/**
* @deprecated Use 'file' with tagged data instead:
* `{ type: 'file', mediaType, data: { type: 'reference', reference } }`.
*/
type: 'file-id';
/**
* ID of the file.
*
* If you use multiple providers, you need to
* specify the provider specific ids using
* the Record option. The key is the provider
* name, e.g. 'openai' or 'anthropic'.
*/
fileId: string | Record<string, string>;
/**
* Provider-specific options.
*/
providerOptions?: ProviderOptions;
} | {
/**
* @deprecated Use 'file' with tagged data instead:
* `{ type: 'file', mediaType, data: { type: 'reference', reference } }`.
*/
type: 'file-reference';
/**
* Provider-specific references for the file.
* The key is the provider name, e.g. 'openai' or 'anthropic'.
*/
providerReference: ProviderReference;
/**
* Provider-specific options.
*/
providerOptions?: ProviderOptions;
} | {
/**
* @deprecated Use 'file' with mediaType (e.g. 'image' or a specific
* `image/*` subtype) and tagged data instead:
* `{ type: 'file', mediaType: 'image', data: { type: 'data', data } }`.
*/
type: 'image-data';
/**
* Base-64 encoded image data.
*/
data: string;
/**
* IANA media type.
* @see https://www.iana.org/assignments/media-types/media-types.xhtml
*/
mediaType: string;
/**
* Provider-specific options.
*/
providerOptions?: ProviderOptions;
} | {
/**
* @deprecated Use 'file' with `mediaType: 'image'` (or a specific
* `image/*` subtype) and tagged data instead:
* `{ type: 'file', mediaType: 'image', data: { type: 'url', url: new URL(url) } }`.
*/
type: 'image-url';
/**
* URL of the image.
*/
url: string;
/**
* Provider-specific options.
*/
providerOptions?: ProviderOptions;
} | {
/**
* @deprecated Use 'file' with `mediaType: 'image'` (or a specific
* `image/*` subtype) and tagged data instead:
* `{ type: 'file', mediaType: 'image', data: { type: 'reference', reference } }`.
*/
type: 'image-file-id';
/**
* Image that is referenced using a provider file id.
*
* If you use multiple providers, you need to
* specify the provider specific ids using
* the Record option. The key is the provider
* name, e.g. 'openai' or 'anthropic'.
*/
fileId: string | Record<string, string>;
/**
* Provider-specific options.
*/
providerOptions?: ProviderOptions;
} | {
/**
* @deprecated Use 'file' with `mediaType: 'image'` (or a specific
* `image/*` subtype) and tagged data instead:
* `{ type: 'file', mediaType: 'image', data: { type: 'reference', reference } }`.
*/
type: 'image-file-reference';
/**
* Provider-specific references for the image file.
* The key is the provider name, e.g. 'openai' or 'anthropic'.
*/
providerReference: ProviderReference;
/**
* Provider-specific options.
*/
providerOptions?: ProviderOptions;
} | {
/**
* Custom content part. This can be used to implement
* provider-specific content parts.
*/
type: 'custom';
/**
* Provider-specific options.
*/
providerOptions?: ProviderOptions;
}>;
};
type InlineFileData = Extract<FilePart['data'], {
type: 'data';
} | {
type: 'text';
}>;
/**
* Converts inline file data (a tagged `data` or `text` shape) into raw bytes.
*
* - `{ type: 'text', text }` → UTF-8 encoded bytes
* - `{ type: 'data', data: Uint8Array | Buffer }` → returned as-is
* - `{ type: 'data', data: ArrayBuffer }` → wrapped in a `Uint8Array`
* - `{ type: 'data', data: string }` → decoded as base64
*/
declare function convertInlineFileDataToUint8Array(data: InlineFileData): Uint8Array;
/**
* Convert an ImageModelV4File to a URL or data URI string.
*
* If the file is a URL, it returns the URL as-is.
* If the file is base64 data, it returns a data URI with the base64 data.
* If the file is a Uint8Array, it converts it to base64 and returns a data URI.
*/
declare function convertImageModelFileToDataUri(file: ImageModelV4File): string;
/**
* Converts an input object to FormData for multipart/form-data requests.
*
* Handles the following cases:
* - `null` or `undefined` values are skipped
* - Arrays with a single element are appended as a single value
* - Arrays with multiple elements are appended with `[]` suffix (e.g., `image[]`)
* unless `useArrayBrackets` is set to `false`
* - All other values are appended directly
*
* @param input - The input object to convert. Use a generic type for type validation.
* @param options - Optional configuration object.
* @param options.useArrayBrackets - Whether to add `[]` suffix for multi-element arrays.
* Defaults to `true`. Set to `false` for APIs that expect repeated keys without brackets.
* @returns A FormData object containing the input values.
*
* @example
* ```ts
* type MyInput = {
* model: string;
* prompt: string;
* images: Blob[];
* };
*
* const formData = convertToFormData<MyInput>({
* model: 'gpt-image-1',
* prompt: 'A cat',
* images: [blob1, blob2],
* });
* ```
*/
declare function convertToFormData<T extends Record<string, unknown>>(input: T, options?: {
useArrayBrackets?: boolean;
}): FormData;
/**
* Interface for mapping between custom tool names and provider tool names.
*/
interface ToolNameMapping {
/**
* Maps a custom tool name (used by the client) to the provider's tool name.
* If the custom tool name does not have a mapping, returns the input name.
*
* @param customToolName - The custom name of the tool defined by the client.
* @returns The corresponding provider tool name, or the input name if not mapped.
*/
toProviderToolName: (customToolName: string) => string;
/**
* Maps a provider tool name to the custom tool name used by the client.
* If the provider tool name does not have a mapping, returns the input name.
*
* @param providerToolName - The name of the tool as understood by the provider.
* @returns The corresponding custom tool name, or the input name if not mapped.
*/
toCustomToolName: (providerToolName: string) => string;
}
/**
* @param tools - Tools that were passed to the language model.
* @param providerToolNames - Maps the provider tool ids to the provider tool names.
*/
declare function createToolNameMapping({ tools, providerToolNames, }: {
/**
* Tools that were passed to the language model.
*/
tools: Array<LanguageModelV4FunctionTool | LanguageModelV4ProviderTool> | undefined;
/**
* Maps the provider tool ids to the provider tool names.
*/
providerToolNames: Record<`${string}.${string}`, string>;
}): ToolNameMapping;
/**
* Creates a Promise that resolves after a specified delay
* @param delayInMs - The delay duration in milliseconds. If null or undefined, resolves immediately.
* @param signal - Optional AbortSignal to cancel the delay
* @returns A Promise that resolves after the specified delay
* @throws {DOMException} When the signal is aborted
*/
declare function delay(delayInMs?: number | null, options?: {
abortSignal?: AbortSignal;
}): Promise<void>;
/**
* Delayed promise. It is only constructed once the value is accessed.
* This is useful to avoid unhandled promise rejections when the promise is created
* but not accessed.
*/
declare class DelayedPromise<T> {
private status;
private _promise;
private _resolve;
private _reject;
get promise(): Promise<T>;
resolve(value: T): void;
reject(error: unknown): void;
isResolved(): boolean;
isRejected(): boolean;
isPending(): boolean;
}
/**
* Detect the IANA media type of a file from its raw bytes or base64 string.
*
* - When `topLevelType` is omitted, every known signature is considered
* (image, audio, video, and application). Returns `undefined` when the
* bytes do not match any known signature.
* - When `topLevelType` is provided, only signatures for that top-level
* segment are considered. Returns `undefined` for unsupported segments
* (e.g. `"text"`) or when no signature matches.
*/
declare function detectMediaType({ data, topLevelType, }: {
data: Uint8Array | string;
topLevelType?: string;
}): string | undefined;
/**
* Returns the top-level segment of a media type (the portion before `/`).
*
* Examples:
* - `"image/png"` -> `"image"`
* - `"image/*"` -> `"image"`
* - `"image"` -> `"image"`
* - `"image/"` -> `"image"`
* - `""` -> `""`
* - `"/"` -> `""`
*/
declare function getTopLevelMediaType(mediaType: string): string;
/**
* Returns `true` only when the given media type has a non-empty, non-wildcard
* subtype (i.e. matches the form `type/subtype`, and `subtype` is not `*`).
*
* Examples:
* - `"image/png"` -> `true`
* - `"image/*"` -> `false`
* - `"image"` -> `false`
* - `"image/"` -> `false`
* - `""` -> `false`
* - `"/"` -> `false`
*/
declare function isFullMediaType(mediaType: string): boolean;
/**
* Download a file from a URL and return it as a Blob.
*
* @param url - The URL to download from.
* @param options - Optional settings for the download.
* @param options.maxBytes - Maximum allowed download size in bytes. Defaults to 100 MiB.
* @param options.abortSignal - An optional abort signal to cancel the download.
* @returns A Promise that resolves to the downloaded Blob.
*
* @throws DownloadError if the download fails or exceeds maxBytes.
*/
declare function downloadBlob(url: string, options?: {
maxBytes?: number;
abortSignal?: AbortSignal;
}): Promise<Blob>;
declare const symbol: unique symbol;
declare class DownloadError extends AISDKError {
private readonly [symbol];
readonly url: string;
readonly statusCode?: number;
readonly statusText?: string;
constructor({ url, statusCode, statusText, cause, message, }: {
url: string;
statusCode?: number;
statusText?: string;
message?: string;
cause?: unknown;
});
static isInstance(error: unknown): error is DownloadError;
}
/**
* Fetch function type (standardizes the version of fetch used).
*/
type FetchFunction = typeof globalThis.fetch;
/**
* Fetches a URL while enforcing the download guard on every hop.
*
* Redirects are followed manually (`redirect: 'manual'`) so each hop is
* validated with {@link validateDownloadUrl} *before* it is requested. Relying
* on the default `redirect: 'follow'` would issue the request to a redirect
* target (e.g. an internal address) before we ever see its URL, defeating the
* guard.
*
* Request headers are also protected: {@link sanitizeRequestHeaders} strips
* proxy/metadata/cookie/hop-by-hop headers before the first request, and all
* caller headers except `User-Agent` are dropped on a cross-origin redirect.
* The fetch spec only strips `Authorization` on cross-origin redirects because
* in a browser, CORS preflighting protects custom headers; there is no CORS on
* the server, so provider API keys carried in custom headers (e.g. `x-key`)
* must be dropped here as well.
*
* A `redirect: 'manual'` request yields an unreadable opaque response in the
* browser (and in other spec-compliant fetch implementations), so the redirect
* target cannot be validated here. In a real browser this is safe to follow
* natively because reaching an internal network is not possible (fetch is
* constrained by CORS and cannot reach a server's internal network or
* cloud-metadata). On any other runtime we cannot validate the hop, so we fail
* closed rather than follow it blindly and bypass the guard.
*
* A hop that is same-origin with `trustedOrigin` (the developer-configured
* provider endpoint) skips target validation: that origin is exactly what an
* unvalidated, config-derived request would fetch anyway, and validating it
* would break legitimate self-hosted / localhost deployments whose response
* URLs point back at the configured host. Hops on any other origin are always
* validated.
*
* The returned response is the final (non-redirect) response. The caller is
* responsible for checking `response.ok` and reading the body.
*
* Not solved here: this does string/literal checks only and does not resolve
* DNS, so a hostname that *resolves* to a private address, and DNS rebinding
* (the resolved IP flipping between validation and connect), are not blocked.
* Server deployments fetching untrusted URLs should constrain egress at the
* network layer or inject a Node `fetch` that pins the resolved IP at connect
* time — those need DNS/socket APIs not available on all target runtimes
* (edge, browser, Bun), so they are intentionally not built in.
*
* @throws DownloadError if a hop is unsafe, the redirect limit is exceeded, or
* a redirect cannot be validated on a non-browser runtime.
*/
declare function fetchWithValidatedRedirects({ url, headers, abortSignal, maxRedirects, fetch, trustedOrigin, }: {
url: string;
headers?: HeadersInit;
abortSignal?: AbortSignal;
maxRedirects?: number;
fetch?: FetchFunction;
/**
* A developer-configured origin (e.g. the provider's `baseURL`) whose hops
* skip target validation. Must never be derived from response data.
*/
trustedOrigin?: string;
}): Promise<Response>;
/**
* Extracts a 1-based inclusive line range from `text`, auto-detecting the
* file's line ending (`\r\n`, `\n`, or `\r`, in that priority).
*
* Mixed line endings are not supported: detection picks one and uses it for
* both the split and the rejoin, so files that mix conventions will not slice
* cleanly. When neither `startLine` nor `endLine` is provided, the input is
* returned unchanged. `endLine` past EOF clamps to the last line.
*/
declare function extractLines({ text, startLine, endLine, }: {
text: string;
startLine?: number;
endLine?: number;
}): string;
/**
* Extracts the headers from a response object and returns them as a key-value object.
*
* @param response - The response object to extract headers from.
* @returns The headers as a key-value object.
*/
declare function extractResponseHeaders(response: Response): {
[k: string]: string;
};
/**
* Filters `null` and `undefined` values out of a list of values.
*
* @param values - The values to filter.
* @returns A new array containing only non-nullish values.
*/
declare function filterNullable<T>(...values: Array<T | undefined | null>): Array<T>;
/**
* Creates an ID generator.
* The total length of the ID is the sum of the prefix, separator, and random part length.
* Not cryptographically secure.
*
* @param alphabet - The alphabet to use for the ID. Default: '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.
* @param prefix - The prefix of the ID to generate. Optional.
* @param separator - The separator between the prefix and the random part of the ID. Default: '-'.
* @param size - The size of the random part of the ID to generate. Default: 16.
*/
declare const createIdGenerator: ({ prefix, size, alphabet, separator, }?: {
prefix?: string;
separator?: string;
size?: number;
alphabet?: string;
}) => IdGenerator;
/**
* A function that generates an ID.
*/
type IdGenerator = () => string;
/**
* Generates a 16-character random string to use for IDs.
* Not cryptographically secure.
*/
declare const generateId: IdGenerator;
/**
* Used to mark schemas so we can support both Zod and custom schemas.
*/
declare const schemaSymbol: unique symbol;
type ValidationResult<OBJECT> = {
success: true;
value: OBJECT;
} | {
success: false;
error: Error;
};
type Schema<OBJECT = unknown> = {
/**
* Used to mark schemas so we can support both Zod and custom schemas.
*/
[schemaSymbol]: true;
/**
* Schema type for inference.
*/
_type: OBJECT;
/**
* Optional. Validates that the structure of a value matches this schema,
* and returns a typed version of the value if it does.
*/
readonly validate?: (value: unknown) => ValidationResult<OBJECT> | PromiseLike<ValidationResult<OBJECT>>;
/**
* The JSON Schema for the schema. It is passed to the providers.
*/
readonly jsonSchema: JSONSchema7 | PromiseLike<JSONSchema7>;
};
/**
* Creates a schema with deferred creation.
* This is important to reduce the startup time of the library
* and to avoid initializing unused validators.
*
* @param createValidator A function that creates a schema.
* @returns A function that returns a schema.
*/
declare function lazySchema<SCHEMA>(createSchema: () => Schema<SCHEMA>): LazySchema<SCHEMA>;
type LazySchema<SCHEMA> = () => Schema<SCHEMA>;
type ZodSchema<SCHEMA = any> = z3.Schema<SCHEMA, z3.ZodTypeDef, any> | z4.core.$ZodType<SCHEMA, any>;
type StandardSchema<SCHEMA = any> = StandardSchemaV1<unknown, SCHEMA> & {
readonly '~standard': StandardSchemaV1.Props<unknown, SCHEMA> & {
readonly jsonSchema?: StandardJSONSchemaV1.Converter;
};
};
type FlexibleSchema<SCHEMA = any> = Schema<SCHEMA> | LazySchema<SCHEMA> | ZodSchema<SCHEMA> | StandardSchema<SCHEMA>;
type InferSchema<SCHEMA> = SCHEMA extends ZodSchema<infer T> ? T : SCHEMA extends StandardSchema<infer T> ? T : SCHEMA extends LazySchema<infer T> ? T : SCHEMA extends Schema<infer T> ? T : never;
/**
* Create a schema using a JSON Schema.
*
* @param jsonSchema The JSON Schema for the schema.
* @param options.validate Optional. A validation function for the schema.
*/
declare function jsonSchema<OBJECT = unknown>(jsonSchema: JSONSchema7 | PromiseLike<JSONSchema7> | (() => JSONSchema7 | PromiseLike<JSONSchema7>), { validate, }?: {
validate?: (value: unknown) => ValidationResult<OBJECT> | PromiseLike<ValidationResult<OBJECT>>;
}): Schema<OBJECT>;
declare function asSchema<OBJECT>(schema: FlexibleSchema<OBJECT> | undefined): Schema<OBJECT>;
declare function zodSchema<OBJECT>(zodSchema: z4.core.$ZodType<OBJECT, any> | z3.Schema<OBJECT, z3.ZodTypeDef, any>, options?: {
/**
* Enables support for references in the schema.
* This is required for recursive schemas, e.g. with `z.lazy`.
* However, not all language models and providers support such references.
* Defaults to `false`.
*/
useReferences?: boolean;
}): Schema<OBJECT>;
/**
* Parses a JSON string into an unknown object.
*
* @param text - The JSON string to parse.
* @returns {JSONValue} - The parsed JSON object.
*/
declare function parseJSON(options: {
text: string;
schema?: undefined;
}): Promise<JSONValue>;
/**
* Parses a JSON string into a strongly-typed object using the provided schema.
*
* @template T - The type of the object to parse the JSON into.
* @param {string} text - The JSON string to parse.
* @param {Validator<T>} schema - The schema to use for parsing the JSON.
* @returns {Promise<T>} - The parsed object.
*/
declare function parseJSON<T>(options: {
text: string;
schema: FlexibleSchema<T>;
}): Promise<T>;
type ParseResult<T> = {
success: true;
value: T;
rawValue: unknown;
} | {
success: false;
error: JSONParseError | TypeValidationError;
rawValue: unknown;
};
/**
* Safely parses a JSON string and returns the result as an object of type `unknown`.
*
* @param text - The JSON string to parse.
* @returns {Promise<object>} Either an object with `success: true` and the parsed data, or an object with `success: false` and the error that occurred.
*/
declare function safeParseJSON(options: {
text: string;
schema?: undefined;
}): Promise<ParseResult<JSONValue>>;
/**
* Safely parses a JSON string into a strongly-typed object, using a provided schema to validate the object.
*
* @template T - The type of the object to parse the JSON into.
* @param {string} text - The JSON string to parse.
* @param {Validator<T>} schema - The schema to use for parsing the JSON.
* @returns An object with either a `success` flag and the parsed and typed data, or a `success` flag and an error object.
*/
declare function safeParseJSON<T>(options: {
text: string;
schema: FlexibleSchema<T>;
}): Promise<ParseResult<T>>;
declare function isParsableJson(input: string): boolean;
type ResponseHandler<RETURN_TYPE> = (options: {
url: string;
requestBodyValues: unknown;
response: Response;
}) => PromiseLike<{
value: RETURN_TYPE;
rawValue?: unknown;
responseHeaders?: Record<string, string>;
}>;
declare const createJsonErrorResponseHandler: <T>({ errorSchema, errorToMessage, isRetryable, }: {
errorSchema: FlexibleSchema<T>;
errorToMessage: (error: T) => string;
isRetryable?: (response: Response, error?: T) => boolean;
}) => ResponseHandler<APICallError>;
declare const createEventSourceResponseHandler: <T>(chunkSchema: FlexibleSchema<T>) => ResponseHandler<ReadableStream<ParseResult<T>>>;
declare const createJsonResponseHandler: <T>(responseSchema: FlexibleSchema<T>) => ResponseHandler<T>;
declare const createBinaryResponseHandler: () => ResponseHandler<Uint8Array>;
declare const createStatusCodeErrorResponseHandler: () => ResponseHandler<APICallError>;
declare const getFromApi: <T>({ url, headers, successfulResponseHandler, failedResponseHandler, abortSignal, fetch, validateUrl, credentialedOrigin, trustedOrigin, }: {
url: string;
headers?: Record<string, string | undefined>;
failedResponseHandler: ResponseHandler<Error>;
successfulResponseHandler: ResponseHandler<T>;
abortSignal?: AbortSignal;
fetch?: FetchFunction;
/**
* Set `true` when `url` is untrusted (e.g. taken from a provider response
* body): it is routed through {@link fetchWithValidatedRedirects}, which
* rejects private/loopback/link-local targets and re-validates redirect
* hops; blocked URLs throw `DownloadError`. Set `false` only for URLs built
* from a developer-configured endpoint.
*
* Optional for backwards compatibility with existing callers; omitting it
* behaves like `false` (no validation). Provider code in this repository
* must always pass it explicitly so every call site makes a visible trust
* decision — see `contributing/secure-url-handling.md`.
*/
validateUrl?: boolean;
/**
* When set, `headers` are sent only if `url` is same-origin with this origin
* (the user-agent suffix is always kept). Pass the provider's configured
* base URL alongside `validateUrl: true` so credentials never ride a request
* to a response-supplied host on a different origin (e.g. a CDN). Redirects
* that later cross origin drop all caller headers regardless (see
* {@link fetchWithValidatedRedirects}).
*/
credentialedOrigin?: string;
/**
* A developer-configured origin (e.g. the provider's `baseURL`) that is
* exempt from URL validation when `validateUrl` is `true`. A response URL
* (or redirect hop) that is same-origin with it is fetched without target
* validation — it points at exactly the host a config-derived
* `validateUrl: false` request would fetch anyway, so blocking it would
* only break legitimate self-hosted / localhost deployments whose response
* URLs point back at the configured host. Hops on any other origin are
* still validated. Must never be derived from response data.
*/
trustedOrigin?: string;
}) => Promise<{
value: T;
rawValue?: unknown;
responseHeaders?: Record<string, string>;
}>;
declare function getRuntimeEnvironmentUserAgent(globalThisAny?: any): string;
/**
* Checks if an object has required keys.
* @param OBJECT - The object to check.
* @returns True if the object has required keys, false otherwise.
*/
type HasRequiredKey<OBJECT> = {} extends OBJECT ? false : true;
declare function injectJsonInstructionIntoMessages({ messages, schema, schemaPrefix, schemaSuffix, }: {
messages: LanguageModelV4Prompt;
schema?: JSONSchema7;
schemaPrefix?: string;
schemaSuffix?: string;
}): LanguageModelV4Prompt;
declare function isAbortError(error: unknown): error is Error;
/**
* Returns `true` when running in a browser.
*
* Detection keys on the presence of a global `window`, matching the browser
* check used elsewhere in this package (see `getRuntimeEnvironmentUserAgent`)
* so the SDK has a single, consistent definition of "browser". Server runtimes
* (Node.js, Deno, Bun, edge/workers) do not define `window`.
*/
declare function isBrowserRuntime(globalThisAny?: any): boolean;
/**
* Type-guard for Node.js `Buffer` instances.
*
* Uses optional chaining on `globalThis.Buffer` so it returns `false` in
* runtimes where `Buffer` is not available (e.g. CloudFlare Workers).
*/
declare function isBuffer(value: unknown): value is Buffer;
/**
* Returns true when `url` has the same origin (scheme + host + port) as
* `baseUrl`.
*
* Used to decide whether provider credentials may be attached to a request to a
* URL taken from a provider response (e.g. a polling or media-download URL).
* Credentials must only be sent to the provider's own origin; a response that
* names a foreign host (a CDN, or an attacker-controlled host if the response
* is tampered with) must not receive the API key.
*
* Returns false if either value is not a valid absolute URL (fail-closed).
*/
declare function isSameOrigin(url: string, baseUrl: string): boolean;
/**
* Type guard that checks whether a value is not `null` or `undefined`.
*
* @template T - The type of the value to check.
* @param value - The value to check.
* @returns `true` if the value is neither `null` nor `undefined`, otherwise `false`.
*/
declare function isNonNullable<T>(value: T | undefined | null): value is NonNullable<T>;
/**
* Checks whether a value is a provider reference (a mapping of provider names
* to provider-specific identifiers) as opposed to raw bytes, a URL, or a
* tagged `{ type: ... }` object.
*/
declare function isProviderReference(data: unknown): data is SharedV4ProviderReference;
/**
* Checks if the given URL is supported natively by the model.
*
* @param mediaType - The media type of the URL. Case-sensitive. May be a full
* `type/subtype`, a wildcard `type/*`, or just the
* top-level segment (e.g. `image`).
* @param url - The URL to check.
* @param supportedUrls - A record where keys are case-sensitive media types (or '*')
* and values are arrays of RegExp patterns for URLs.
*
* @returns `true` if the URL matches a pattern under the specific media type
* or the wildcard '*', `false` otherwise.
*/
declare function isUrlSupported({ mediaType, url, supportedUrls, }: {
mediaType: string;
url: string;
supportedUrls: Record<string, RegExp[]>;
}): boolean;
declare function loadApiKey({ apiKey, environmentVariableName, apiKeyParameterName, description, }: {
apiKey: string | undefined;
environmentVariableName: string;
apiKeyParameterName?: string;
description: string;
}): string;
/**
* Loads an optional `string` setting from the environment or a parameter.
*
* @param settingValue - The setting value.
* @param environmentVariableName - The environment variable name.
* @returns The setting value.
*/
declare function loadOptionalSetting({ settingValue, environmentVariableName, }: {
settingValue: string | undefined;
environmentVariableName: string;
}): string | undefined;
/**
* Loads a `string` setting from the environment or a parameter.
*
* @param settingValue - The setting value.
* @param environmentVariableName - The environment variable name.
* @param settingName - The setting name.
* @param description - The description of the setting.
* @returns The setting value.
*/
declare function loadSetting({ settingValue, environmentVariableName, settingName, description, }: {
settingValue: string | undefined;
environmentVariableName: string;
settingName: string;
description: string;
}): string;
type ReasoningLevel = Exclude<LanguageModelV4CallOptions['reasoning'], 'none' | 'provider-default' | undefined>;
declare function isCustomReasoning(reasoning: LanguageModelV4CallOptions['reasoning']): reasoning is Exclude<LanguageModelV4CallOptions['reasoning'], 'provider-default' | undefined>;
/**
* Maps a top-level reasoning level to a provider-specific effort string using
* the given effort map. Pushes a compatibility warning if the reasoning level
* maps to a different string, or an unsupported warning if the level is not
* present in the map.
*
* @returns The mapped effort string, or `undefined` if the level is not
* supported.
*/
declare function mapReasoningToProviderEffort<T extends string>({ reasoning, effortMap, warnings, }: {
reasoning: ReasoningLevel;
effortMap: Partial<Record<ReasoningLevel, T>>;
warnings: SharedV4Warning[];
}): T | undefined;
/**
* Maps a top-level reasoning level to an absolute token budget by multiplying
* the model's max output tokens by a percentage from the budget percentages
* map. The result is clamped between `minReasoningBudget` (default 1024) and
* `maxReasoningBudget`. Pushes an unsupported warning if the level is not
* present in the budget percentages map.
*
* @returns The computed token budget, or `undefined` if the level is not
* supported.
*/
declare function mapReasoningToProviderBudget({ reasoning, maxOutputTokens, maxReasoningBudget, minReasoningBudget, budgetPercentages, warnings, }: {
reasoning: ReasoningLevel;
maxOutputTokens: number;
maxReasoningBudget: number;
minReasoningBudget?: number;
budgetPercentages?: Partial<Record<ReasoningLevel, number>>;
warnings: SharedV4Warning[];
}): number | undefined;
/**
* A value that can be provided either synchronously or as a promise-like.
*/
type MaybePromiseLike<T> = T | PromiseLike<T>;
/**
* Maps a media type to its corresponding file extension.
* It was originally introduced to set a filename for audio file uploads
* in https://github.com/vercel/ai/pull/8159.
*
* @param mediaType The media type to map.
* @returns The corresponding file extension
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/MIME_types/Common_types
*/
declare function mediaTypeToExtension(mediaType: string): string;
/**
* Normalizes different header inputs into a plain record with lower-case keys.
* Entries with `undefined` or `null` values are removed.
*
* @param headers - Input headers (`Headers`, tuples array, plain record) to normalize.
* @returns A record containing the normalized header entries.
*/
declare function normalizeHeaders(headers: HeadersInit | Record<string, string | undefined> | Array<[string, string | undefined]> | undefined): Record<string, string>;
/**
* Parses a JSON event stream into a stream of parsed JSON objects.
*/
declare function parseJsonEventStream<T>({ stream, schema, }: {
stream: ReadableStream<Uint8Array>;
schema: FlexibleSchema<T>;
}): ReadableStream<ParseResult<T>>;
declare function parseProviderOptions<OPTIONS>({ provider, providerOptions, schema, }: {
provider: string;
providerOptions: Record<string, unknown> | undefined;
schema: FlexibleSchema<OPTIONS>;
}): Promise<OPTIONS | undefined>;
declare const postJsonToApi: <T>({ url, headers, body, failedResponseHandler, successfulResponseHandler, abortSignal, fetch, }: {
url: string;
headers?: Record<string, string | undefined>;
body: unknown;
failedResponseHandler: ResponseHandler<APICallError>;
successfulResponseHandler: ResponseHandler<T>;
abortSignal?: AbortSignal;
fetch?: FetchFunction;
}) => Promise<{
value: T;
rawValue?: unknown;
responseHeaders?: Record<string, string>;
}>