UNPKG

ai

Version:

AI SDK by Vercel - build apps like ChatGPT, Claude, Gemini, and more with a single interface for any model using the Vercel AI Gateway or go direct to OpenAI, Anthropic, Google, or any other model provider.

3,807 lines • 135 kB
import { DEFAULT_MAX_DOWNLOAD_SIZE, DownloadError, asArray, asSchema, cancelResponseBody, convertAsyncIteratorToReadableStream, convertBase64ToUint8Array, convertUint8ArrayToBase64, detectMediaType, experimental_getToolCaller, fetchUntrustedUrl, filterNullable, getRuntimeEnvironmentUserAgent, isArrayBuffer, isBuffer, isExecutableTool, isFullMediaType, isProviderReference, isUint8Array, isUrlSupported, readResponseWithSizeLimit, redactTelemetryValue, retryWithExponentialBackoff, safeParseJSON, safeValidateTypes, validateTypes, withUserAgentSuffix } from "@ai-sdk/provider-utils";
import { AISDKError, APICallError, InvalidPromptError, getErrorMessage } from "@ai-sdk/provider";
import { GatewayError, gateway } from "@ai-sdk/gateway";
//#region src/util/async-iterable-stream.ts
/**
* Wraps a ReadableStream and returns an object that is both a ReadableStream and an AsyncIterable.
* This enables consumption of the stream using for-await-of, with proper resource cleanup on early exit or error.
*
* @template T The type of the stream's chunks.
* @param source The source ReadableStream to wrap.
* @returns An AsyncIterableStream that can be used as both a ReadableStream and an AsyncIterable.
*/
function createAsyncIterableStream(source) {
	return asAsyncIterableStream(source.pipeThrough(new TransformStream()));
}
/**
* Attaches the async iterator protocol to an existing ReadableStream in place,
* turning it into an AsyncIterableStream without piping through an additional
* TransformStream.
*
* Use this when the stream is already known to be fresh and exclusively owned
* (e.g. the readable side of a TransformStream created for this consumer).
* Adding an extra `pipeThrough` in that situation creates a chain of two
* transforms fed by an active upstream pipe, which can surface a spurious
* unhandled `undefined` rejection when the consumer cancels early (observed on
* Node.js 26). {@link createAsyncIterableStream} wraps this after adding a
* fresh transform for callers that may pass shared or locked streams.
*
* @template T The type of the stream's chunks.
* @param stream The ReadableStream to augment. It must be fresh and unlocked.
* @returns The same stream, augmented with the async iterator protocol.
*/
function asAsyncIterableStream(stream) {
	/**
	* Implements the async iterator protocol for the stream.
	* Ensures proper cleanup (cancelling and releasing the reader) on completion, early exit, or error.
	*/
	stream[Symbol.asyncIterator] = function() {
		const reader = this.getReader();
		let finished = false;
		/**
		* Cleans up the reader by cancelling and releasing the lock.
		*/
		async function cleanup(cancelStream) {
			if (finished) return;
			finished = true;
			try {
				if (cancelStream) await reader.cancel?.();
			} finally {
				try {
					reader.releaseLock();
				} catch {}
			}
		}
		return {
			/**
			* Reads the next chunk from the stream.
			* @returns A promise resolving to the next IteratorResult.
			*/
			async next() {
				if (finished) return {
					done: true,
					value: void 0
				};
				let result;
				try {
					result = await reader.read();
				} catch (error) {
					await cleanup(false);
					throw error;
				}
				const { done, value } = result;
				if (done) {
					await cleanup(true);
					return {
						done: true,
						value: void 0
					};
				}
				return {
					done: false,
					value
				};
			},
			/**
			* May be called on early exit (e.g., break from for-await) or after completion.
			* Ensures the stream is cancelled and resources are released.
			* @returns A promise resolving to a completed IteratorResult.
			*/
			async return() {
				await cleanup(true);
				return {
					done: true,
					value: void 0
				};
			},
			/**
			* Called on early exit with error.
			* Ensures the stream is cancelled and resources are released, then rethrows the error.
			* @param err The error to throw.
			* @returns A promise that rejects with the provided error.
			*/
			async throw(err) {
				await cleanup(true);
				throw err;
			}
		};
	};
	return stream;
}
//#endregion
//#region src/version.ts
const VERSION = "7.0.173";
//#endregion
//#region src/util/download/download.ts
/**
* Download a file from a URL.
*
* @param url - The URL to download from.
* @param maxBytes - Maximum allowed download size in bytes. Defaults to 100 MiB.
* @param abortSignal - An optional abort signal to cancel the download.
* @param fetch - An optional fetch transport.
* @returns The downloaded data and media type.
*
* @throws DownloadError if the download fails or exceeds maxBytes.
*/
const download = async ({ url, maxBytes, abortSignal, fetch }) => {
	const urlText = url.toString();
	try {
		const headers = withUserAgentSuffix({}, `ai-sdk/${VERSION}`, getRuntimeEnvironmentUserAgent());
		const response = await fetchUntrustedUrl({
			url: urlText,
			headers,
			abortSignal,
			fetch
		});
		if (!response.ok) {
			await cancelResponseBody(response);
			throw new DownloadError({
				url: urlText,
				statusCode: response.status,
				statusText: response.statusText
			});
		}
		return {
			data: await readResponseWithSizeLimit({
				response,
				url: urlText,
				maxBytes: maxBytes ?? DEFAULT_MAX_DOWNLOAD_SIZE
			}),
			mediaType: response.headers.get("content-type") ?? void 0
		};
	} catch (error) {
		if (DownloadError.isInstance(error)) throw error;
		throw new DownloadError({
			url: urlText,
			cause: error
		});
	}
};
//#endregion
//#region src/util/download/download-function.ts
/**
* Default download function.
* Downloads the file if it is not supported by the model.
*/
const createDefaultDownloadFunction = (download$2 = download, abortSignal) => (requestedDownloads) => Promise.all(requestedDownloads.map(async (requestedDownload) => requestedDownload.isUrlSupportedByModel ? null : await download$2({
	...requestedDownload,
	abortSignal: abortSignal ?? requestedDownload.abortSignal
})));
//#endregion
//#region src/util/merge-objects.ts
/**
* Deeply merges two objects together.
* - Properties from the `overrides` object override those in the `base` object with the same key.
* - For nested objects, the merge is performed recursively (deep merge).
* - Arrays are replaced, not merged.
* - Primitive values are replaced.
* - If both `base` and `overrides` are undefined, returns undefined.
* - If one of `base` or `overrides` is undefined, returns the other.
*
* @param base The target object to merge into
* @param overrides The source object to merge from
* @returns A new object with the merged properties, or undefined if both inputs are undefined
*/
function mergeObjects(base, overrides) {
	if (base === void 0 && overrides === void 0) return;
	if (base === void 0) return overrides;
	if (overrides === void 0) return base;
	const result = { ...base };
	for (const key in overrides) {
		if (key === "__proto__" || key === "constructor" || key === "prototype") continue;
		if (Object.prototype.hasOwnProperty.call(overrides, key)) {
			const overridesValue = overrides[key];
			if (overridesValue === void 0) continue;
			const baseValue = key in base ? base[key] : void 0;
			const isSourceObject = overridesValue !== null && typeof overridesValue === "object" && !Array.isArray(overridesValue) && !(overridesValue instanceof Date) && !(overridesValue instanceof RegExp);
			const isTargetObject = baseValue !== null && baseValue !== void 0 && typeof baseValue === "object" && !Array.isArray(baseValue) && !(baseValue instanceof Date) && !(baseValue instanceof RegExp);
			if (isSourceObject && isTargetObject) result[key] = mergeObjects(baseValue, overridesValue);
			else result[key] = overridesValue;
		}
	}
	return result;
}
//#endregion
//#region src/prompt/invalid-data-content-error.ts
const name$11 = "AI_InvalidDataContentError";
const marker$11 = `vercel.ai.error.${name$11}`;
const symbol$11 = Symbol.for(marker$11);
var InvalidDataContentError = class extends AISDKError {
	constructor({ content, cause, message = `Invalid data content. Expected a base64 string, Uint8Array, ArrayBuffer, or Buffer, but got ${typeof content}.` }) {
		super({
			name: name$11,
			message,
			cause
		});
		this[symbol$11] = true;
		this.content = content;
	}
	static isInstance(error) {
		return AISDKError.hasMarker(error, marker$11);
	}
};
//#endregion
//#region src/prompt/data-content.ts
/**
* Converts data content to a Uint8Array.
*
* @param content - Data content to convert.
* @returns Uint8Array.
*/
function convertDataContentToUint8Array(content) {
	if (isUint8Array(content)) {
		if (content instanceof Uint8Array) return content;
		const { buffer, byteOffset, byteLength } = content;
		return new Uint8Array(buffer, byteOffset, byteLength);
	}
	if (typeof content === "string") try {
		return convertBase64ToUint8Array(content);
	} catch (error) {
		throw new InvalidDataContentError({
			message: "Invalid data content. Content string is not a base64-encoded media.",
			content,
			cause: error
		});
	}
	if (isArrayBuffer(content)) return new Uint8Array(content);
	throw new InvalidDataContentError({ content });
}
//#endregion
//#region src/prompt/split-data-url.ts
function splitDataUrl(dataUrl) {
	try {
		const [header, base64Content] = dataUrl.split(",");
		return {
			mediaType: header.split(";")[0].split(":")[1],
			base64Content
		};
	} catch {
		return {
			mediaType: void 0,
			base64Content: void 0
		};
	}
}
//#endregion
//#region src/prompt/file-part-data.ts
function isTaggedFileData(value) {
	if (typeof value !== "object" || value === null) return false;
	const type = value.type;
	return type === "data" || type === "url" || type === "reference" || type === "text";
}
function convertUrlToFilePartData(url, originalUrl) {
	if (url.protocol === "data:") {
		const { mediaType, base64Content } = splitDataUrl(url.toString());
		if (mediaType == null || base64Content == null) throw new InvalidDataContentError({
			content: url,
			message: `Invalid data URL format in content ${url.toString()}`
		});
		return {
			data: {
				type: "data",
				data: base64Content
			},
			mediaType
		};
	}
	return {
		data: {
			type: "url",
			url,
			...originalUrl != null ? { originalUrl } : {}
		},
		mediaType: void 0
	};
}
function convertUrlStringToFilePartData(content) {
	const result = convertUrlToFilePartData(new URL(content));
	if (result.data.type === "url" && result.data.url.toString() !== content) result.data.originalUrl = content;
	return result;
}
function convertInlineDataToFilePartData(content) {
	if (isUint8Array(content) || isArrayBuffer(content)) return {
		data: {
			type: "data",
			data: convertDataContentToUint8Array(content)
		},
		mediaType: void 0
	};
	if (isBuffer(content)) return {
		data: {
			type: "data",
			data: new Uint8Array(content)
		},
		mediaType: void 0
	};
	return {
		data: {
			type: "data",
			data: content
		},
		mediaType: void 0
	};
}
/**
* Converts any legacy-or-tagged top-level `FilePart.data` /
* `ReasoningFilePart.data` value into the tagged v4 provider prompt shape.
*
* Returns the tagged `data` together with the resolved mediaType (extracted
* from a `data:` URL when applicable).
*/
function convertToLanguageModelV4FilePart(content) {
	if (isTaggedFileData(content)) switch (content.type) {
		case "data":
			if (typeof content.data === "string" && content.data.startsWith("data:")) throw new InvalidDataContentError({
				content: content.data,
				message: "Data URLs are not valid inline data. Pass them as { type: \"url\", url } instead."
			});
			return convertInlineDataToFilePartData(content.data);
		case "url": return convertUrlToFilePartData(content.url, content.originalUrl);
		case "reference": return {
			data: {
				type: "reference",
				reference: content.reference
			},
			mediaType: void 0
		};
		case "text": return {
			data: {
				type: "text",
				text: content.text
			},
			mediaType: void 0
		};
	}
	if (content instanceof URL) return convertUrlToFilePartData(content);
	if (typeof content === "string") try {
		return convertUrlStringToFilePartData(content);
	} catch {
		return convertInlineDataToFilePartData(content);
	}
	if (isUint8Array(content) || isArrayBuffer(content)) return convertInlineDataToFilePartData(content);
	if (isProviderReference(content)) return {
		data: {
			type: "reference",
			reference: content
		},
		mediaType: void 0
	};
	return convertInlineDataToFilePartData(content);
}
//#endregion
//#region src/logger/deprecations.ts
const deprecationCodes = /* @__PURE__ */ new Map([
	["generateObject", "AISDK_DEP_GENERATE_OBJECT"],
	["streamObject", "AISDK_DEP_STREAM_OBJECT"],
	["experimental_generateSpeech", "AISDK_DEP_EXPERIMENTAL_GENERATE_SPEECH"],
	["experimental_transcribe", "AISDK_DEP_EXPERIMENTAL_TRANSCRIBE"],
	["\"image\" content part", "AISDK_DEP_IMAGE_CONTENT_PART"],
	["\"tool-result\" content of type \"file-data\"", "AISDK_DEP_TOOL_RESULT_FILE_DATA"],
	["\"tool-result\" content of type \"file-url\"", "AISDK_DEP_TOOL_RESULT_FILE_URL"],
	["\"tool-result\" content of type \"file-id\"", "AISDK_DEP_TOOL_RESULT_FILE_ID"],
	["\"tool-result\" content of type \"file-reference\"", "AISDK_DEP_TOOL_RESULT_FILE_REFERENCE"],
	["\"tool-result\" content of type \"image-data\"", "AISDK_DEP_TOOL_RESULT_IMAGE_DATA"],
	["\"tool-result\" content of type \"image-url\"", "AISDK_DEP_TOOL_RESULT_IMAGE_URL"],
	["\"tool-result\" content of type \"image-file-id\"", "AISDK_DEP_TOOL_RESULT_IMAGE_FILE_ID"],
	["\"tool-result\" content of type \"image-file-reference\"", "AISDK_DEP_TOOL_RESULT_IMAGE_FILE_REFERENCE"],
	["rawInput in output-error UI message parts", "AISDK_DEP_UI_MESSAGE_RAW_INPUT"]
]);
/**
* Escape punctuation and UTF-16 code units without losing case or collapsing
* distinct settings. Underscores are escaped too, so `__` separates code parts.
*/
function encodeCodePart(value) {
	return value.replace(/[^a-zA-Z0-9]/g, (character) => `_${character.charCodeAt(0).toString(16).toUpperCase().padStart(4, "0")}`);
}
function getDeprecationCode({ setting, provider }) {
	if (provider == null) return deprecationCodes.get(setting) ?? `AISDK_DEP_SETTING_${encodeCodePart(setting)}`;
	return `AISDK_DEP_PROVIDER_${encodeCodePart(provider)}__${encodeCodePart(setting)}`;
}
//#endregion
//#region src/logger/log-warnings.ts
/**
* Formats a warning object into a human-readable string with clear AI SDK branding.
*
* @param options - The options for formatting the warning.
* @param options.warning - The warning to format.
* @param options.provider - The provider id used for the call, if scoped to a specific provider.
* @param options.model - The model id used for the call, if scoped to a specific provider.
* @returns A formatted warning message string.
*/
function formatWarning({ warning, provider, model }) {
	const prefix = `AI SDK Warning${provider != null && model != null ? ` (${provider} / ${model})` : ""}:`;
	switch (warning.type) {
		case "unsupported": {
			let message = `${prefix} The feature "${warning.feature}" is not supported.`;
			if (warning.details) message += ` ${warning.details}`;
			return message;
		}
		case "compatibility": {
			let message = `${prefix} The feature "${warning.feature}" is used in a compatibility mode.`;
			if (warning.details) message += ` ${warning.details}`;
			return message;
		}
		case "deprecated": return `${prefix} Deprecated: "${warning.setting}". ${warning.message}`;
		case "other": return `${prefix} ${warning.message}`;
		default: return `${prefix} ${JSON.stringify(warning, null, 2)}`;
	}
}
const FIRST_WARNING_INFO_MESSAGE = "AI SDK Warning System: To turn off warning logging, set the AI_SDK_LOG_WARNINGS global to false.";
let hasLoggedBefore = false;
const emittedDeprecationCodes = /* @__PURE__ */ new Set();
function emitWarning({ message, type, code }) {
	if (typeof process !== "undefined" && typeof process.emitWarning === "function") process.emitWarning(message, code == null ? { type } : {
		type,
		code
	});
	else console.warn(code == null ? message : `[${code}] ${message}`);
}
/**
* Logs warnings to the console or uses a custom logger if configured.
*
* The behavior can be customized via the `AI_SDK_LOG_WARNINGS` global variable:
* - If set to `false`, warnings are suppressed.
* - If set to a function, that function is called with the warnings.
* - Otherwise, warnings use `process.emitWarning` when available, falling back
*   to `console.warn`. Deprecations have stable codes and are emitted once per
*   code by the default logger. Custom loggers receive every warning.
*
* @param options - The options containing warnings and context.
* @param options.warnings - The warnings to log.
* @param options.provider - The provider id used for the call, if scoped to a specific provider.
* @param options.model - The model id used for the call, if scoped to a specific provider.
*/
const logWarnings = (options) => {
	if (options.warnings.length === 0) return;
	const logger = globalThis.AI_SDK_LOG_WARNINGS;
	if (logger === false) return;
	if (typeof logger === "function") {
		logger(options);
		return;
	}
	if (!hasLoggedBefore) {
		hasLoggedBefore = true;
		emitWarning({
			message: FIRST_WARNING_INFO_MESSAGE,
			type: "Warning"
		});
	}
	for (const warning of options.warnings) {
		const code = warning.type === "deprecated" ? getDeprecationCode({
			setting: warning.setting,
			provider: options.provider
		}) : void 0;
		if (code != null) {
			if (emittedDeprecationCodes.has(code)) continue;
			emittedDeprecationCodes.add(code);
		}
		emitWarning({
			message: formatWarning({
				warning,
				provider: options.provider,
				model: options.model
			}),
			type: warning.type === "deprecated" ? "DeprecationWarning" : "Warning",
			code
		});
	}
};
//#endregion
//#region src/prompt/invalid-message-role-error.ts
const name$10 = "AI_InvalidMessageRoleError";
const marker$10 = `vercel.ai.error.${name$10}`;
const symbol$10 = Symbol.for(marker$10);
var InvalidMessageRoleError = class extends AISDKError {
	constructor({ role, message = `Invalid message role: '${role}'. Must be one of: "system", "user", "assistant", "tool".` }) {
		super({
			name: name$10,
			message
		});
		this[symbol$10] = true;
		this.role = role;
	}
	static isInstance(error) {
		return AISDKError.hasMarker(error, marker$10);
	}
};
//#endregion
//#region src/error/missing-tool-result-error.ts
const name$9 = "AI_MissingToolResultsError";
const marker$9 = `vercel.ai.error.${name$9}`;
const symbol$9 = Symbol.for(marker$9);
var MissingToolResultsError = class extends AISDKError {
	constructor({ toolCallIds }) {
		super({
			name: name$9,
			message: `Tool result${toolCallIds.length > 1 ? "s are" : " is"} missing for tool call${toolCallIds.length > 1 ? "s" : ""} ${toolCallIds.join(", ")}.`
		});
		this[symbol$9] = true;
		this.toolCallIds = toolCallIds;
	}
	static isInstance(error) {
		return AISDKError.hasMarker(error, marker$9);
	}
};
//#endregion
//#region src/prompt/convert-to-language-model-prompt.ts
async function convertToLanguageModelPrompt({ prompt, supportedUrls, download, abortSignal, provider }) {
	const downloadedAssets = await downloadAssets(prompt.messages, download ?? createDefaultDownloadFunction(void 0, abortSignal), supportedUrls, abortSignal);
	const messages = [...prompt.instructions != null ? typeof prompt.instructions === "string" ? [{
		role: "system",
		content: prompt.instructions
	}] : asArray(prompt.instructions).map((message) => ({
		role: "system",
		content: message.content,
		providerOptions: message.providerOptions
	})) : [], ...prompt.messages.map((message) => convertToLanguageModelMessage({
		message,
		downloadedAssets,
		provider
	}))];
	const combinedMessages = [];
	for (const message of messages) {
		if (message.role !== "tool") {
			combinedMessages.push(message);
			continue;
		}
		const lastCombinedMessage = combinedMessages.at(-1);
		if (lastCombinedMessage?.role === "tool") {
			const lastContentPart = lastCombinedMessage.content.at(-1);
			if (lastContentPart != null && lastCombinedMessage.providerOptions != null) lastContentPart.providerOptions = mergeObjects(lastCombinedMessage.providerOptions, lastContentPart.providerOptions);
			lastCombinedMessage.content.push(...message.content);
			lastCombinedMessage.providerOptions = lastContentPart == null ? mergeObjects(lastCombinedMessage.providerOptions, message.providerOptions) : message.providerOptions;
		} else combinedMessages.push(message);
	}
	const toolCallIds = /* @__PURE__ */ new Set();
	for (const message of combinedMessages) switch (message.role) {
		case "assistant":
			for (const content of message.content) if (content.type === "tool-call" && !content.providerExecuted) toolCallIds.add(content.toolCallId);
			break;
		case "tool":
			for (const content of message.content) if (content.type === "tool-result") toolCallIds.delete(content.toolCallId);
			break;
		case "user":
		case "system": if (toolCallIds.size > 0) throw new MissingToolResultsError({ toolCallIds: Array.from(toolCallIds) });
	}
	if (toolCallIds.size > 0) throw new MissingToolResultsError({ toolCallIds: Array.from(toolCallIds) });
	return combinedMessages.filter((message) => message.role !== "tool" || message.content.length > 0);
}
/**
* Convert a ModelMessage to a LanguageModelV4Message.
*
* @param message - The ModelMessage to convert.
* @param downloadedAssets - A map of URLs to their downloaded data. Only
* available if the model does not support URLs, null otherwise.
*/
function convertToLanguageModelMessage({ message, downloadedAssets, provider }) {
	const warnings = [];
	const role = message.role;
	switch (role) {
		case "system": return {
			role: "system",
			content: message.content,
			providerOptions: message.providerOptions
		};
		case "user": {
			if (typeof message.content === "string") return {
				role: "user",
				content: [{
					type: "text",
					text: message.content
				}],
				providerOptions: message.providerOptions
			};
			const converted = {
				role: "user",
				content: message.content.map((part) => {
					if (part.type === "image") warnings.push({
						type: "deprecated",
						setting: "\"image\" content part",
						message: `The "image" content part type is deprecated. Use a "file" part with mediaType: 'image' (or a more specific image/* subtype) instead.`
					});
					return convertImagePartToFilePart(part);
				}).map((part) => convertPartToLanguageModelPart(part, downloadedAssets)).filter((part) => part.type !== "text" || part.text !== ""),
				providerOptions: message.providerOptions
			};
			if (warnings.length > 0) logWarnings({ warnings });
			return converted;
		}
		case "assistant": {
			if (typeof message.content === "string") return {
				role: "assistant",
				content: [{
					type: "text",
					text: message.content
				}],
				providerOptions: message.providerOptions
			};
			const converted = {
				role: "assistant",
				content: message.content.filter((part) => part.type !== "text" || part.text !== "" || part.providerOptions != null).filter((part) => part.type !== "tool-approval-request").map((part) => {
					const providerOptions = part.providerOptions;
					switch (part.type) {
						case "custom": return {
							type: "custom",
							kind: part.kind,
							providerOptions
						};
						case "file": {
							const { data, mediaType } = convertToLanguageModelV4FilePart(part.data);
							return {
								type: "file",
								data,
								filename: part.filename,
								mediaType: mediaType ?? part.mediaType,
								providerOptions
							};
						}
						case "reasoning": return {
							type: "reasoning",
							text: part.text,
							providerOptions
						};
						case "reasoning-file": {
							const { data, mediaType } = convertToLanguageModelV4FilePart(part.data);
							if (data.type !== "data" && data.type !== "url") throw new Error(`Unsupported reasoning-file data type: ${data.type}`);
							return {
								type: "reasoning-file",
								data,
								mediaType: mediaType ?? part.mediaType,
								providerOptions
							};
						}
						case "text": return {
							type: "text",
							text: part.text,
							providerOptions
						};
						case "tool-call": return {
							type: "tool-call",
							toolCallId: part.toolCallId,
							toolName: part.toolName,
							input: part.input,
							providerExecuted: part.providerExecuted,
							providerOptions
						};
						case "tool-result": return {
							type: "tool-result",
							toolCallId: part.toolCallId,
							toolName: part.toolName,
							output: mapToolResultOutput({
								output: part.output,
								provider,
								warnings,
								downloadedAssets
							}),
							providerOptions
						};
					}
				}),
				providerOptions: message.providerOptions
			};
			if (warnings.length > 0) logWarnings({ warnings });
			return converted;
		}
		case "tool": {
			const converted = {
				role: "tool",
				content: message.content.filter((part) => part.type !== "tool-approval-response" || part.providerExecuted).map((part) => {
					switch (part.type) {
						case "tool-result": return {
							type: "tool-result",
							toolCallId: part.toolCallId,
							toolName: part.toolName,
							output: mapToolResultOutput({
								output: part.output,
								provider,
								warnings,
								downloadedAssets
							}),
							providerOptions: part.providerOptions
						};
						case "tool-approval-response": return {
							type: "tool-approval-response",
							approvalId: part.approvalId,
							approved: part.approved,
							reason: part.reason
						};
					}
				}),
				providerOptions: message.providerOptions
			};
			if (warnings.length > 0) logWarnings({ warnings });
			return converted;
		}
		default: throw new InvalidMessageRoleError({ role });
	}
}
function convertImagePartToFilePart(part) {
	if (part.type !== "image") return part;
	return {
		type: "file",
		data: part.image,
		mediaType: part.mediaType ?? "image",
		providerOptions: part.providerOptions
	};
}
/**
* Downloads files from URLs in the user messages.
*/
async function downloadAssets(messages, download, supportedUrls, abortSignal) {
	const downloadableFiles = [];
	for (const message of messages) {
		if (message.role === "user" && Array.isArray(message.content)) for (const part of message.content) {
			const filePart = convertImagePartToFilePart(part);
			if (filePart.type === "file") downloadableFiles.push(filePart);
		}
		if (message.role === "tool") for (const part of message.content) {
			if (part.type !== "tool-result") continue;
			if (part.output.type !== "content") continue;
			for (const contentPart of part.output.value) {
				const filePart = getDownloadableFilePart(contentPart);
				if (filePart != null) downloadableFiles.push(filePart);
			}
		}
		if (message.role === "assistant" && Array.isArray(message.content)) for (const part of message.content) {
			if (part.type !== "tool-result") continue;
			if (part.output.type !== "content") continue;
			for (const contentPart of part.output.value) {
				const filePart = getDownloadableFilePart(contentPart);
				if (filePart != null) downloadableFiles.push(filePart);
			}
		}
	}
	const plannedDownloads = downloadableFiles.map((part) => {
		const mediaType = part.mediaType;
		const { data } = convertToLanguageModelV4FilePart(part.data);
		return {
			mediaType,
			data
		};
	}).filter((part) => part.data.type === "url").map((part) => ({
		url: part.data.url,
		abortSignal,
		isUrlSupportedByModel: part.mediaType != null && isUrlSupported({
			url: part.data.url.toString(),
			mediaType: part.mediaType,
			supportedUrls
		})
	}));
	const downloadedFiles = await download(plannedDownloads);
	return Object.fromEntries(downloadedFiles.map((file, index) => file == null ? null : [plannedDownloads[index].url.toString(), {
		data: file.data,
		mediaType: file.mediaType
	}]).filter((file) => file != null));
}
/**
* Resolves the tool result content parts that point at a remote file to the
* tagged file shape, including the deprecated `file-url` and `image-url`
* types, so that they are downloaded and inlined exactly like their `file`
* replacement. Returns `undefined` for content that is already inline or
* provider-referenced.
*/
function getDownloadableFilePart(contentPart) {
	switch (contentPart.type) {
		case "file": return contentPart;
		case "file-url": return {
			type: "file",
			data: {
				type: "url",
				url: new URL(contentPart.url)
			},
			mediaType: contentPart.mediaType ?? getMediaTypeFromUrl(contentPart.url),
			providerOptions: contentPart.providerOptions
		};
		case "image-url": return {
			type: "file",
			data: {
				type: "url",
				url: new URL(contentPart.url)
			},
			mediaType: "image",
			providerOptions: contentPart.providerOptions
		};
		default: return;
	}
}
/**
* Resolves file data and media type for a remote tool result content part: the downloaded
* bytes when the asset was fetched, otherwise the URL reference. `originalUrl`
* is preserved when the URL string does not round-trip through `URL`.
*/
function resolveDownloadedFile({ url, originalUrl, downloadedAssets, mediaType }) {
	const convertedPart = convertPartToLanguageModelPart({
		type: "file",
		data: {
			type: "url",
			url,
			...url.toString() !== originalUrl ? { originalUrl } : {}
		},
		mediaType
	}, downloadedAssets);
	return {
		data: convertedPart.data,
		mediaType: convertedPart.mediaType
	};
}
/**
* Convert part of a user message to a LanguageModelV4Part.
*
* @param part - The part to convert.
* @param downloadedAssets - A map of URLs to their downloaded data. Only
* available if the model does not support URLs, null otherwise.
* @returns The converted part.
*/
function convertPartToLanguageModelPart(part, downloadedAssets) {
	if (part.type === "text") return {
		type: "text",
		text: part.text,
		providerOptions: part.providerOptions
	};
	const { data: normalizedData, mediaType: dataUrlMediaType } = convertToLanguageModelV4FilePart(part.data);
	let mediaType = dataUrlMediaType ?? part.mediaType;
	let data = normalizedData;
	if (data.type === "url") {
		const downloadedFile = downloadedAssets[data.url.toString()];
		if (downloadedFile) {
			data = {
				type: "data",
				data: downloadedFile.data
			};
			if (downloadedFile.mediaType != null && (mediaType == null || !isFullMediaType(mediaType))) mediaType = downloadedFile.mediaType;
		}
	}
	if (data.type === "data" && (data.data instanceof Uint8Array || typeof data.data === "string")) {
		const imageMediaType = detectMediaType({
			data: data.data,
			topLevelType: "image"
		});
		if (imageMediaType != null) mediaType = imageMediaType;
	}
	if (mediaType == null) throw new Error(`Media type is missing for file part`);
	return {
		type: "file",
		mediaType,
		filename: part.filename,
		data,
		providerOptions: part.providerOptions
	};
}
function mapToolResultOutput({ output, provider, warnings = [], downloadedAssets }) {
	if (output.type !== "content") return output;
	return {
		type: "content",
		value: output.value.map((item) => {
			switch (item.type) {
				case "file": {
					const convertedPart = convertPartToLanguageModelPart(item, downloadedAssets);
					if (convertedPart.type !== "file") throw new Error("Expected tool result file content to convert to file.");
					return convertedPart;
				}
				case "file-data":
					warnings.push({
						type: "deprecated",
						setting: "\"tool-result\" content of type \"file-data\"",
						message: `The "file-data" type for tool result content is deprecated. Use the "file" type with mediaType and { type: 'data', data } instead.`
					});
					return {
						type: "file",
						data: {
							type: "data",
							data: item.data
						},
						filename: item.filename,
						mediaType: item.mediaType,
						providerOptions: item.providerOptions
					};
				case "file-url": {
					const mediaType = item.mediaType ?? getMediaTypeFromUrl(item.url);
					const url = new URL(item.url);
					let message = `The "file-url" type for tool result content is deprecated. Use the "file" type with mediaType and { type: 'url', url } instead.`;
					if (!item.mediaType) {
						const inferenceSuffix = mediaType === "application/octet-stream" ? `Unable to infer media type from URL. Defaulting to 'application/octet-stream'.` : `Inferred media type '${mediaType}' from URL.`;
						message = `The "file-url" tool result content part with URL "${item.url}" is missing a "mediaType". ${inferenceSuffix} ${message}`;
					}
					warnings.push({
						type: "deprecated",
						setting: "\"tool-result\" content of type \"file-url\"",
						message
					});
					return {
						type: "file",
						...resolveDownloadedFile({
							url,
							originalUrl: item.url,
							downloadedAssets,
							mediaType
						}),
						providerOptions: item.providerOptions
					};
				}
				case "file-id":
					warnings.push({
						type: "deprecated",
						setting: "\"tool-result\" content of type \"file-id\"",
						message: `The "file-id" type for tool result content is deprecated. Use the "file" type with mediaType and { type: 'reference', reference } instead.`
					});
					return {
						type: "file",
						data: {
							type: "reference",
							reference: convertFileIdToProviderReference({
								fileId: item.fileId,
								provider
							})
						},
						mediaType: "application",
						providerOptions: item.providerOptions
					};
				case "file-reference":
					warnings.push({
						type: "deprecated",
						setting: "\"tool-result\" content of type \"file-reference\"",
						message: `The "file-reference" type for tool result content is deprecated. Use the "file" type with mediaType and { type: 'reference', reference } instead.`
					});
					return {
						type: "file",
						data: {
							type: "reference",
							reference: item.providerReference
						},
						mediaType: "application",
						providerOptions: item.providerOptions
					};
				case "image-data":
					warnings.push({
						type: "deprecated",
						setting: "\"tool-result\" content of type \"image-data\"",
						message: `The "image-data" type for tool result content is deprecated. Use the "file" type with mediaType and { type: 'data', data } instead.`
					});
					return {
						type: "file",
						data: {
							type: "data",
							data: item.data
						},
						mediaType: item.mediaType,
						providerOptions: item.providerOptions
					};
				case "image-url": {
					const url = new URL(item.url);
					warnings.push({
						type: "deprecated",
						setting: "\"tool-result\" content of type \"image-url\"",
						message: `The "image-url" type for tool result content is deprecated. Use the "file" type with mediaType 'image' (or a specific image/* subtype) and { type: 'url', url } instead.`
					});
					return {
						type: "file",
						...resolveDownloadedFile({
							url,
							originalUrl: item.url,
							downloadedAssets,
							mediaType: "image"
						}),
						providerOptions: item.providerOptions
					};
				}
				case "image-file-id":
					warnings.push({
						type: "deprecated",
						setting: "\"tool-result\" content of type \"image-file-id\"",
						message: `The "image-file-id" type for tool result content is deprecated. Use the "file" type with mediaType and { type: 'reference', reference } instead.`
					});
					return {
						type: "file",
						data: {
							type: "reference",
							reference: convertFileIdToProviderReference({
								fileId: item.fileId,
								provider
							})
						},
						mediaType: "image",
						providerOptions: item.providerOptions
					};
				case "image-file-reference":
					warnings.push({
						type: "deprecated",
						setting: "\"tool-result\" content of type \"image-file-reference\"",
						message: `The "image-file-reference" type for tool result content is deprecated. Use the "file" type with mediaType and { type: 'reference', reference } instead.`
					});
					return {
						type: "file",
						data: {
							type: "reference",
							reference: item.providerReference
						},
						mediaType: "image",
						providerOptions: item.providerOptions
					};
				default: return item;
			}
		})
	};
}
function convertFileIdToProviderReference({ fileId, provider }) {
	if (typeof fileId === "object") return fileId;
	if (provider == null) throw new Error("Cannot convert string fileId to provider reference without a provider ID. Use a Record<string, string> fileId or switch to the file-reference type.");
	return { [provider]: fileId };
}
const URL_EXTENSION_TO_MEDIA_TYPE = {
	jpg: "image/jpeg",
	jpeg: "image/jpeg",
	png: "image/png",
	gif: "image/gif",
	webp: "image/webp",
	svg: "image/svg+xml",
	avif: "image/avif",
	heic: "image/heic",
	bmp: "image/bmp",
	tiff: "image/tiff",
	tif: "image/tiff",
	pdf: "application/pdf",
	mp4: "video/mp4",
	webm: "video/webm",
	mp3: "audio/mpeg",
	wav: "audio/wav",
	ogg: "audio/ogg"
};
function getMediaTypeFromUrl(url, fallbackMediaType = "application/octet-stream") {
	try {
		const fileExtension = new URL(url).pathname.split(".").pop()?.toLowerCase();
		if (fileExtension && Object.hasOwn(URL_EXTENSION_TO_MEDIA_TYPE, fileExtension)) return URL_EXTENSION_TO_MEDIA_TYPE[fileExtension];
	} catch {}
	return fallbackMediaType;
}
//#endregion
//#region src/prompt/create-tool-model-output.ts
async function createToolModelOutput({ toolCallId, input, output, tool, errorMode }) {
	if (errorMode === "text") return {
		type: "error-text",
		value: getErrorMessage(output)
	};
	else if (errorMode === "json") return {
		type: "error-json",
		value: toJSONValue(output)
	};
	if (tool?.toModelOutput) return await tool.toModelOutput({
		toolCallId,
		input,
		output
	});
	return typeof output === "string" ? {
		type: "text",
		value: output
	} : {
		type: "json",
		value: toJSONValue(output)
	};
}
/**
* Normalizes an in-process tool output to a plain JSON value
* (applies `toJSON`, converts `Date`, drops `undefined`, etc.)
* by round-tripping it through `JSON.stringify`.
*
* The parsed text is produced by `JSON.stringify` from a value that is
* already materialized in this process, so it is not untrusted input.
* `JSON.parse` is used deliberately instead of the secure parser from
* `@ai-sdk/provider-utils`: the secure parser rejects own `__proto__` and
* `constructor.prototype` keys, which are valid data in tool outputs
* (e.g. rows from an external API). `JSON.parse` defines `__proto__` as an
* own data property and never modifies the prototype chain, so preserving
* these keys here is safe. Do not reuse this pattern for text that comes
* from outside the process; use `parseJSON` / `safeParseJSON` instead.
*/
function toJSONValue(value) {
	if (value === void 0) return null;
	const serialized = JSON.stringify(value);
	return serialized === void 0 ? null : JSON.parse(serialized);
}
//#endregion
//#region src/prompt/prepare-tool-choice.ts
function prepareToolChoice({ toolChoice }) {
	return toolChoice == null ? { type: "auto" } : typeof toolChoice === "string" ? { type: toolChoice } : {
		type: "tool",
		toolName: toolChoice.toolName
	};
}
//#endregion
//#region src/util/is-non-empty-object.ts
function isNonEmptyObject(object) {
	return object != null && Object.keys(object).length > 0;
}
//#endregion
//#region src/prompt/prepare-tools.ts
async function prepareTools({ tools, toolOrder, toolsContext = {}, experimental_sandbox: sandbox }) {
	if (!isNonEmptyObject(tools)) return;
	const languageModelTools = [];
	for (const [name, tool] of orderToolEntries({
		tools,
		toolOrder
	})) {
		const toolType = tool.type;
		switch (toolType) {
			case void 0:
			case "dynamic":
			case "function": {
				const description = resolveToolDescription({
					tool,
					toolName: name,
					toolsContext,
					experimental_sandbox: sandbox
				});
				const providerOptions = tool.providerOptions;
				const inputExamples = tool.inputExamples;
				const strict = tool.strict;
				languageModelTools.push({
					type: "function",
					name,
					inputSchema: await asSchema(tool.inputSchema).jsonSchema,
					...description != null ? { description } : {},
					...inputExamples != null ? { inputExamples } : {},
					...providerOptions != null ? { providerOptions } : {},
					...strict != null ? { strict } : {}
				});
				break;
			}
			case "provider":
				languageModelTools.push({
					type: "provider",
					name,
					id: tool.id,
					args: tool.args
				});
				break;
			default: throw new Error(`Unsupported tool type: ${toolType}`);
		}
	}
	return languageModelTools;
}
function orderToolEntries({ tools, toolOrder }) {
	if (toolOrder == null) return Object.entries(tools);
	const toolEntries = Object.entries(tools);
	const orderedTools = toolEntries.filter(([name]) => toolOrder.includes(name)).sort(([nameA], [nameB]) => toolOrder.indexOf(nameA) - toolOrder.indexOf(nameB));
	const unorderedTools = toolEntries.filter(([name]) => !toolOrder.includes(name)).sort(([nameA], [nameB]) => nameA < nameB ? -1 : nameA > nameB ? 1 : 0);
	return [...orderedTools, ...unorderedTools];
}
function resolveToolDescription({ tool, toolName, toolsContext, experimental_sandbox: sandbox }) {
	return tool.description === void 0 ? void 0 : typeof tool.description === "string" ? tool.description : tool.description({
		context: toolsContext[toolName],
		experimental_sandbox: sandbox
	});
}
//#endregion
//#region src/prompt/standardize-prompt.ts
/**
* Converts a prompt input into a standardized prompt with model messages.
*
* @param prompt - The prompt definition to standardize.
* Set `allowSystemInMessages` to true to allow system messages in the
* `prompt` or `messages` fields. System messages in the `instructions`
* option are always allowed.
* @returns The standardized prompt.
* @throws {InvalidPromptError} When the prompt is invalid.
*/
async function standardizePrompt({ allowSystemInMessages = false, system, instructions = system, prompt, messages }) {
	messages = prompt == null ? messages : typeof prompt === "string" ? [{
		role: "user",
		content: prompt
	}] : prompt;
	if (messages.length === 0) throw new InvalidPromptError({
		prompt,
		message: "messages must not be empty"
	});
	if (!allowSystemInMessages && messages.some((message) => message.role === "system")) throw new InvalidPromptError({
		prompt,
		message: "System messages are not allowed in the prompt or messages fields. Use the instructions option instead."
	});
	return {
		messages,
		instructions
	};
}
//#endregion
//#region src/error/invalid-argument-error.ts
const name$8 = "AI_InvalidArgumentError";
const marker$8 = `vercel.ai.error.${name$8}`;
const symbol$8 = Symbol.for(marker$8);
var InvalidArgumentError = class extends AISDKError {
	constructor({ parameter, value, message }) {
		super({
			name: name$8,
			message: `Invalid argument for parameter ${parameter}: ${message}`
		});
		this[symbol$8] = true;
		this.parameter = parameter;
		this.value = value;
	}
	static isInstance(error) {
		return AISDKError.hasMarker(error, marker$8);
	}
};
//#endregion
//#region src/prompt/prepare-language-model-call-options.ts
/**
* Validates model call options and returns a new object with normalized values.
*/
function prepareLanguageModelCallOptions({ maxOutputTokens, temperature, topP, topK, presencePenalty, frequencyPenalty, seed, stopSequences, reasoning }) {
	if (maxOutputTokens != null) {
		if (!Number.isInteger(maxOutputTokens)) throw new InvalidArgumentError({
			parameter: "maxOutputTokens",
			value: maxOutputTokens,
			message: "maxOutputTokens must be an integer"
		});
		if (maxOutputTokens < 1) throw new InvalidArgumentError({
			parameter: "maxOutputTokens",
			value: maxOutputTokens,
			message: "maxOutputTokens must be >= 1"
		});
	}
	if (seed != null) {
		if (!Number.isInteger(seed)) throw new InvalidArgumentError({
			parameter: "seed",
			value: seed,
			message: "seed must be an integer"
		});
	}
	return {
		maxOutputTokens,
		temperature,
		topP,
		topK,
		presencePenalty,
		frequencyPenalty,
		stopSequences,
		seed,
		reasoning
	};
}
//#endregion
//#region src/util/retry-error.ts
const name$7 = "AI_RetryError";
const marker$7 = `vercel.ai.error.${name$7}`;
const symbol$7 = Symbol.for(marker$7);
var RetryError = class extends AISDKError {
	constructor({ message, reason, errors }) {
		super({
			name: name$7,
			message
		});
		this[symbol$7] = true;
		this.reason = reason;
		this.errors = errors;
		this.lastError = errors[errors.length - 1];
	}
	static isInstance(error) {
		return AISDKError.hasMarker(error, marker$7);
	}
};
//#endregion
//#region src/util/retry-with-exponential-backoff.ts
function getRetryDelayInMs({ error, exponentialBackoffDelay }) {
	const headers = APICallError.isInstance(error) ? error.responseHeaders : APICallError.isInstance(error.cause) ? error.cause.responseHeaders : void 0;
	if (!headers) return exponentialBackoffDelay;
	let ms;
	const retryAfterMs = headers["retry-after-ms"];
	if (retryAfterMs) {
		const timeoutMs = parseFloat(retryAfterMs);
		if (!Number.isNaN(timeoutMs)) ms = timeoutMs;
	}
	const retryAfter = headers["retry-after"];
	if (retryAfter && ms === void 0) {
		const timeoutSeconds = parseFloat(retryAfter);
		if (!Number.isNaN(timeoutSeconds)) ms = timeoutSeconds * 1e3;
		else ms = Date.parse(retryAfter) - Date.now();
	}
	if (ms != null && !Number.isNaN(ms) && 0 <= ms && (ms < 6e4 || ms < exponentialBackoffDelay)) return ms;
	return exponentialBackoffDelay;
}
/**
* The `retryWithExponentialBackoffRespectingRetryHeaders` strategy retries a failed API call with an exponential backoff,
* while respecting rate limit headers (retry-after-ms and retry-after) if they are provided and reasonable (0-60 seconds).
* You can configure the maximum number of retries, the initial delay, and the backoff factor.
*/
const retryWithExponentialBackoffRespectingRetryHeaders = ({ maxRetries = 2, initialDelayInMs = 2e3, backoffFactor = 2, abortSignal, additionalRetryableError } = {}) => retryWithExponentialBackoff({
	maxRetries,
	initialDelayInMs,
	backoffFactor,
	abortSignal,
	shouldRetry: async (error) => error instanceof Error && (APICallError.isInstance(error) && error.isRetryable === true || GatewayError.isInstance(error) && error.isRetryable === true) || additionalRetryableError != null && await additionalRetryableError(error),
	getDelayInMs: ({ error, exponentialBackoffDelay }) => getRetryDelayInMs({
		error,
		exponentialBackoffDelay
	}),
	createRetryError: ({ message, reason, errors }) => new RetryError({
		message,
		reason,
		errors
	})
});
//#endregion
//#region src/util/prepare-retries.ts
/**
* Validate and prepare retries.
*/
function prepareRetries({ maxRetries, abortSignal, additionalRetryableError, parameter = "maxRetries", defaultMaxRetries = 2 }) {
	if (maxRetries != null) {
		if (!Number.isInteger(maxRetries)) throw new InvalidArgumentError({
			parameter,
			value: maxRetries,
			message: `${parameter} must be an integer`
		});
		if (maxRetries < 0) throw new InvalidArgumentError({
			parameter,
			value: maxRetries,
			message: `${parameter} must be >= 0`
		});
	}
	const maxRetriesResult = maxRetries ?? defaultMaxRetries;
	return {
		maxRetries: maxRetriesResult,
		retry: retryWithExponentialBackoffRespectingRetryHeaders({
			maxRetries: maxRetriesResult,
			abortSignal,
			additionalRetryableError
		})
	};
}
//#endregion
//#region src/types/usage.ts
function asLanguageModelUsage(usage) {
	return {
		inputTokens: usage.inputTokens.total,
		inputTokenDetails: {
			noCacheTokens: usage.inputTokens.noCache,
			cacheReadTokens: usage.inputTokens.cacheRead,
			cacheWriteTokens: usage.inputTokens.cacheWrite
		},
		outputTokens: usage.outputTokens.total,
		outputTokenDetails: {
			textTokens: usage.outputTokens.text,
			reasoningTokens: usage.outputTokens.reasoning
		},
		totalTokens: addTokenCounts(usage.inputTokens.total, usage.outputTokens.total),
		raw: usage.raw
	};
}
function createNullLanguageModelUsage() {
	return {
		inputTokens: void 0,
		inputTokenDetails: {
			noCacheTokens: void 0,
			cacheReadTokens: void 0,
			cacheWriteTokens: void 0
		},
		outputTokens: void 0,
		outputTokenDetails: {
			textTokens: void 0,
			reasoningTokens: void 0
		},
		totalTokens: void 0,
		raw: void 0
	};
}
function addLanguageModelUsage(usage1, usage2) {
	const raw = isNullLanguageModelUsage(usage1) ? usage2.raw : isNullLanguageModelUsage(usage2) ? usage1.raw : void 0;
	return {
		inputTokens: addTokenCounts(usage1.inputTokens, usage2.inputTokens),
		inputTokenDetails: {
			noCacheTokens: addTokenCounts(usage1.inputTokenDetails?.noCacheTokens, usage2.inputTokenDetails?.noCacheTokens),
			cacheReadTokens: addTokenCounts(usage1.inputTokenDetails?.cacheReadTokens, usage2.inputTokenDetails?.cacheReadTokens),
			cacheWriteTokens: addTokenCounts(usage1.inputTokenDetails?.cacheWriteTokens, usage2.inputTokenDetails?.cacheWriteTokens)
		},
		outputTokens: addTokenCounts(usage1.outputTokens, usage2.outputTokens),
		outputTokenDetails: {
			textTokens: addTokenCounts(usage1.outputTokenDetails?.textTokens, usage2.outputTokenDetails?.textTokens),
			reasoningTokens: addTokenCounts(usage1.outputTokenDetails?.reasoningTokens, usage2.outputTokenDetails?.reasoningTokens)
		},
		totalTokens: addTokenCounts(usage1.totalTokens, usage2.totalTokens),
		...raw == null ? {} : { raw }
	};
}
function isNullLanguageModelUsage(usage) {
	return usage.inputTokens == null && usage.inputTokenDetails?.noCacheTokens == null && usage.inputTokenDetails?.cacheReadTokens == null && usage.inputTokenDetails?.cacheWriteTokens == null && usage.outputTokens == null && usage.outputTokenDetails?.textTokens == null && usage.outputTokenDetails?.reasoningTokens == null && usage.totalTokens == null && usage.raw == null;
}
function addTokenCounts(tokenCount1, tokenCount2) {
	return tokenCount1 == null && tokenCount2 == null ? void 0 : (tokenCount1 ?? 0) + (tokenCount2 ?? 0);
}
//#endregion
//#region src/error/invalid-tool-approval-error.ts
const name$6 = "AI_InvalidToolApprovalError";
const marker$6 = `vercel.ai.error.${name$6}`;
const symbol$6 = Symbol.for(marker$6);
var InvalidToolApprovalError = class extends AISDKError {
	constructor({ approvalId }) {
		super({
			name: name$6,
			message: `Tool approval response references unknown approvalId: "${approvalId}". No matching tool-approval-request found in message history.`
		});
		this[symbol$6] = true;
		this.approvalId = approvalId;
	}
	static isInstance(error) {
		return AISDKError.hasMarker(error, marker$6);
	}
};
//#endregion
//#region src/error/invalid-tool-approval-signature-error.ts
const name$5 = "AI_InvalidToolApprovalSignatureError";
const marker$5 = `vercel.ai.error.${name$5}`;
const symbol$5 = Symbol.for(marker$5);
var InvalidToolApprovalSignatureError = class extends AISDKError {
	constructor({ approvalId, toolCallId, reason }) {
		super({
			name: name$5,
			message: `Tool approval signature verification failed for approval "${approvalId}" (tool call "${toolCallId}"): ${reason}`
		});
		this[symbol$5] = true;
		this.approvalId = approvalId;
		this.toolCallId = toolCallId;
	}
	static isInstance(error) {
		return AISDKError.hasMarker(error, marker$5);
	}
};
//#endregion
//#region src/error/invalid-tool-input-error.ts
const name$4 = "AI_InvalidToolInputError";
const marker$4 = `vercel.ai.error.${name$4}`;
const symbol$4 = Symbol.for(marker$4);
var InvalidToolInputError = class extends AISDKError {
	constructor({ toolInput, toolName, cause, message = `Invalid input for tool ${toolName}: ${getErrorMessage(cause)}` }) {
		super({
			name: name$4,
			message,
			cause
		});
		this[symbol$4] = true;
		this.toolInput = toolInput;
		this.toolName = toolName;
	}
	static isInstance(error) {
		return AISDKError.hasMarker(error, marker$4);
	}
};
//#endregion
//#region src/error/tool-call-not-found-for-approval-error.ts
const name$3 = "AI_ToolCallNotFoundForApprovalError";
const marker$3 = `vercel.ai.error.${name$3}`;
const symbol$3 = Symbol.for(marker$3);
var ToolCallNotFoundForApprovalError = class extends AISDKError {
	constructor({ toolCallId, approvalId }) {
		super({
			name: name$3,
			message: `Tool call "${toolCallId}" not found for approval request "${approvalId}".`
		});
		this[symbol$3] = true;
		this.toolCallId = toolCallId;
		this.approvalId = approvalId;
	}
	static isInstance(error) {
		return AISDKError.hasMarker(error, marker$3);
	}
};
//#endregion
//#region src/error/no-output-generated-error.ts
const name$2 = "AI_NoOutputGeneratedError";
const marker$2 = `vercel.ai.error.${name$2}`;
const symbol$2 = Symbol.for(marker$2);
/**
* Thrown when no LLM output was generated, e.g. because of errors.
*/
var NoOutputGeneratedError = class extends AISDKError {
	constructor({ message = "No output generated.", cause } = {}) {
		super({
			name: name$2,
			message,
			cause
		});
		this[symbol$2] = true;
	}
	static isInstance(error) {
		return AISDKError.hasMarker(error, marker$2);
	}
};
//#endregion
//#region src/error/no-such-tool-error.ts
const name$1 = "AI_NoSuchToolError";
const marker$1 = `vercel.ai.error.${name$1}`;
const symbol$1 = Symbol.for(marker$1);
var NoSuchToolError = class extends AISDKError {
	constructor({ toolName, availableTools = void 0, message = `Model tried to call unavailable tool '${toolName}'. ${availableTools === void 0 ? "No tools are available." : `Available tools: ${availableTools.join(", ")}.`}` }) {
		super({
			name: name$1,
			message
		});
		this[symbol$1] = true;
		this.toolName = toolName;
		this.availableTools = availableTools;
	}
	static isInstance(error) {
		return AISDKError.hasMarker(error, marker$1);
	}
};
//#endregion
//#region src/error/tool-call-repair-error.ts
const name = "AI_ToolCallRepairError";
const marker = `vercel.ai.error.${name}`;
const symbol = Symbol.for(marker);
var ToolCallRepairError = class extends AISDKError {
	constructor({ cause, originalError, message = `Error repairing tool call: ${getErrorMessage(cause)}` }) {
		super({
			name,
			message,
			cause
		});
		this[symbol] = true;
		this.originalError = originalError;
	}
	static isInstance(error) {
		return AISDKError.hasMarker(error, marker);
	}
};
//#endregion
//#region src/error/unsupported-model-version-error.ts
/**
* Error that is thrown when a model with an unsupported version is used.
*/
var UnsupportedModelVersionError = class extends AISDKError {
	constructor(options) {
		super({
			name: "AI_UnsupportedModelVersionError",
			message: `Unsupported model version ${options.version} for provider "${options.provider}" and model "${options.modelId}". AI SDK 5 only supports models that implement specification version "v2".`
		});
		this.version = options.version;
		this.provider = options.provider;
		this.modelId = options.modelId;
	}
};
//#endregion
//#region src/util/log-v2-compatibility-warning.ts
function logV2CompatibilityWarning({ provider, modelId }) {
	logWarnings({
		warnings: [{
			type: "compatibility",
			feature: "specificationVersion",
			details: `Using v2 specification compatibility mode. Some features may not be available.`
		}],
		provider,
		model: modelId
	});
}
//#endregion
//#region src/model/as-embedding-model-v3.ts
function asEmbeddingModelV3(model) {
	if (model.specificationVersion === "v3") return model;
	logV2CompatibilityWarning({
		provider: model.provider,
		modelId: model.modelId
	});
	return new Proxy(model, { get(target, prop) {
		if (prop === "specificationVersion") return "v3";
		return target[prop];
	} });
}
//#endregion
//#region src/model/as-embedding-model-v4.ts
function asEmbeddingModelV4(model) {
	if (model.specificationVersion === "v4") return model;
	const v3Model = model.specificationVersion === "v2" ? asEmbeddingModelV3(model) : model;
	return new Proxy(v3Model, { get(target, prop) {
		if (prop === "specificationVersion") return "v4";
		return target[prop];
	} });
}
//#endregion
//#region src/model/as-image-model-v3.ts
function asImageModelV3(model) {
	if (model.specificationVersion === "v3") return model;
	logV2CompatibilityWarning({
		provider: model.provider,
		modelId: model.modelId
	});
	return new Proxy(model, { get(target, prop) {
		if (prop === "specificationVersion") return "v3";
		return target[prop];
	} });
}
//#endregion
//#region src/model/as-image-model-v4.ts
function asImageModelV4(model) {
	if (model.specificationVersion === "v4") return model;
	const v3Model = model.specificationVersion === "v2" ? asImageModelV3(model) : model;
	return new Proxy(v3Model, { get(target, prop) {
		if (prop === "specificationVersion") return "v4";
		return target[prop];
	} });
}
//#endregion
//#region src/model/as-language-model-v3.ts
function asLanguageModelV3(model) {
	if (model.specificationVersion === "v3") return model;
	logV2CompatibilityWarning({
		provider: model.provider,
		modelId: model.modelId
	});
	return new Proxy(model, { get(target, prop) {
		switch (prop) {
			case "specificationVersion": return "v3";
			case "doGenerate": return async (...args) => {
				const result = await target.doGenerate(...args);
				return {
					...result,
					finishReason: convertV2FinishReasonToV3(result.finishReason),
					usage: convertV2UsageToV3(result.usage)
				};
			};
			case "doStream": return async (...args) => {
				const result = await target.doStream(...args);
				return {
					...result,
					stream: convertV2StreamToV3(result.stream)
				};
			};
			default: return target[prop];
		}
	} });
}
function convertV2StreamToV3(stream) {
	return stream.pipeThrough(new TransformStream({ transform(chunk, controller) {
		switch (chunk.type) {
			case "finish":
				controller.enqueue({
					...chunk,
					finishReason: convertV2FinishReasonToV3(chunk.finishReason),
					usage: convertV2UsageToV3(chunk.usage)
				});
				break;
			default: controller.enqueue(chunk);
		}
	} }));
}
function convertV2FinishReasonToV3(finishReason) {
	return {
		unified: finishReason === "unknown" ? "other" : finishReason,
		raw: void 0
	};
}
function convertV2UsageToV3(usage) {
	return {
		inputTokens: {
			total: usage.inputTokens,
			noCache: void 0,
			cacheRead: usage.cachedInputTokens,
			cacheWrite: void 0
		},
		outputTokens: {
			total: usage.outputTokens,
			text: void 0,
			reasoning: usage.reasoningTokens
		},
		raw: usage.totalTokens == null ? void 0 : { totalTokens: usage.totalTokens }
	};
}
//#endregion
//#region src/model/as-language-model-v4.ts
function asLanguageModelV4(model) {
	if (model.specificationVersion === "v4") return model;
	const v3Model = model.specificationVersion === "v2" ? asLanguageModelV3(model) : model;
	return new Proxy(v3Model, { get(target, prop) {
		switch (prop) {
			case "specificationVersion": return "v4";
			case "doGenerate": return async (options) => {
				const result = await target.doGenerate({
					...options,
					prompt: convertV4PromptToV3(options.prompt)
				});
				return {
					...result,
					content: result.content.map(convertV3ContentToV4)
				};
			};
			case "doStream": return async (options) => {
				const result = await target.doStream({
					...options,
					prompt: convertV4PromptToV3(options.prompt)
				});
				return {
					...result,
					stream: convertV3StreamToV4(result.stream)
				};
			};
			default: return target[prop];
		}
	} });
}
function convertV4PromptToV3(prompt) {
	return prompt.map((message) => {
		if (message.role === "system") return message;
		return {
			...message,
			content: message.content.map((part) => {
				switch (part.type) {
					case "file": return {
						...part,
						data: convertV4FileDataToV3(part.data)
					};
					case "tool-result": return {
						...part,
						output: convertV4ToolResultOutputToV3(part.output)
					};
					default: return part;
				}
			})
		};
	});
}
function convertV4FileDataToV3(data) {
	switch (data.type) {
		case "data": return data.data;
		case "url": return data.url;
		case "reference":
		case "text": return data;
	}
}
function convertV4ToolResultOutputToV3(output) {
	if (output.type !== "content") return output;
	return {
		...output,
		value: output.value.map((part) => {
			if (part.type !== "file") return part;
			switch (part.data.type) {
				case "data": return {
					type: "file-data",
					data: typeof part.data.data === "string" ? part.data.data : convertUint8ArrayToBase64(part.data.data),
					mediaType: part.mediaType,
					filename: part.filename,
					providerOptions: part.providerOptions
				};
				case "url": return {
					type: "file-url",
					url: part.data.url.toString(),
					providerOptions: part.providerOptions
				};
				case "reference": return {
					type: "file-id",
					fileId: part.data.reference,
					providerOptions: part.providerOptions
				};
				case "text": return part;
			}
		})
	};
}
function convertV3ContentToV4(content) {
	return content.type === "file" ? {
		...content,
		data: {
			type: "data",
			data: content.data
		}
	} : content;
}
function convertV3StreamToV4(stream) {
	return stream.pipeThrough(new TransformStream({ transform(chunk, controller) {
		controller.enqueue(chunk.type === "file" ? {
			...chunk,
			data: {
				type: "data",
				data: chunk.data
			}
		} : chunk);
	} }));
}
//#endregion
//#region src/model/as-reranking-model-v4.ts
function asRerankingModelV4(model) {
	if (model.specificationVersion === "v4") return model;
	return new Proxy(model, { get(target, prop) {
		if (prop === "specificationVersion") return "v4";
		return target[prop];
	} });
}
//#endregion
//#region src/model/as-speech-model-v3.ts
function asSpeechModelV3(model) {
	if (model.specificationVersion === "v3") return model;
	logV2CompatibilityWarning({
		provider: model.provider,
		modelId: model.modelId
	});
	return new Proxy(model, { get(target, prop) {
		if (prop === "specificationVersion") return "v3";
		return target[prop];
	} });
}
//#endregion
//#region src/model/as-speech-model-v4.ts
function asSpeechModelV4(model) {
	if (model.specificationVersion === "v4") return model;
	const v3Model = model.specificationVersion === "v2" ? asSpeechModelV3(model) : model;
	return new Proxy(v3Model, { get(target, prop) {
		if (prop === "specificationVersion") return "v4";
		return target[prop];
	} });
}
//#endregion
//#region src/model/as-transcription-model-v3.ts
function asTranscriptionModelV3(model) {
	if (model.specificationVersion === "v3") return model;
	logV2CompatibilityWarning({
		provider: model.provider,
		modelId: model.modelId
	});
	return new Proxy(model, { get(target, prop) {
		if (prop === "specificationVersion") return "v3";
		return target[prop];
	} });
}
//#endregion
//#region src/model/as-transcription-model-v4.ts
function asTranscriptionModelV4(model) {
	if (model.specificationVersion === "v4") return model;
	const v3Model = model.specificationVersion === "v2" ? asTranscriptionModelV3(model) : model;
	return new Proxy(v3Model, { get(target, prop) {
		if (prop === "specificationVersion") return "v4";
		if (prop === "doGenerate") return async ({ timestampGranularities, ...options }) => {
			const result = await target.doGenerate.call(model, options);
			if (!timestampGranularities?.length) return result;
			return {
				...result,
				warnings: [...result.warnings, {
					type: "unsupported",
					feature: "timestampGranularities",
					details: `Shared timestamp granularities are not supported by ${model.specificationVersion} transcription models.`
				}]
			};
		};
		return target[prop];
	} });
}
//#endregion
//#region src/model/as-provider-v3.ts
function asProviderV3(provider) {
	if ("specificationVersion" in provider && provider.specificationVersion === "v3") return provider;
	const v2Provider = provider;
	return {
		specificationVersion: "v3",
		languageModel: (modelId) => asLanguageModelV3(v2Provider.languageModel(modelId)),
		embeddingModel: (modelId) => asEmbeddingModelV3(v2Provider.textEmbeddingModel(modelId)),
		imageModel: (modelId) => asImageModelV3(v2Provider.imageModel(modelId)),
		transcriptionModel: v2Provider.transcriptionModel ? (modelId) => asTranscriptionModelV3(v2Provider.transcriptionModel(modelId)) : void 0,
		speechModel: v2Provider.speechModel ? (modelId) => asSpeechModelV3(v2Provider.speechModel(modelId)) : void 0,
		rerankingModel: void 0
	};
}
//#endregion
//#region src/model/as-provider-v4.ts
function asProviderV4(provider) {
	if ("specificationVersion" in provider && provider.specificationVersion === "v4") return provider;
	const v3Provider = !("specificationVersion" in provider) || provider.specificationVersion !== "v3" ? asProviderV3(provider) : provider;
	return {
		specificationVersion: "v4",
		languageModel: (modelId) => asLanguageModelV4(v3Provider.languageModel(modelId)),
		embeddingModel: (modelId) => asEmbeddingModelV4(v3Provider.embeddingModel(modelId)),
		imageModel: (modelId) => asImageModelV4(v3Provider.imageModel(modelId)),
		transcriptionModel: v3Provider.transcriptionModel ? (modelId) => asTranscriptionModelV4(v3Provider.transcriptionModel(modelId)) : void 0,
		speechModel: v3Provider.speechModel ? (modelId) => asSpeechModelV4(v3Provider.speechModel(modelId)) : void 0,
		rerankingModel: v3Provider.rerankingModel ? (modelId) => asRerankingModelV4(v3Provider.rerankingModel(modelId)) : void 0
	};
}
//#endregion
//#region src/model/resolve-model.ts
function resolveLanguageModel(model) {
	if (typeof model === "string") return getGlobalProvider().languageModel(model);
	if (![
		"v4",
		"v3",
		"v2"
	].includes(model.specificationVersion)) {
		const unsupportedModel = model;
		throw new UnsupportedModelVersionError({
			version: unsupportedModel.specificationVersion,
			provider: unsupportedModel.provider,
			modelId: unsupportedModel.modelId
		});
	}
	return asLanguageModelV4(model);
}
function getGlobalProvider() {
	return asProviderV4(globalThis.AI_SDK_DEFAULT_PROVIDER ?? gateway);
}
//#endregion
//#region src/util/merge-abort-signals.ts
/**
* Merges multiple abort sources into a single `AbortSignal`.
* The returned signal will abort when any input signal aborts or when any
* numeric timeout elapses, using the reason from the first source to abort.
*
* @param signals - Abort signals or timeout durations in milliseconds.
* `null` and `undefined` values are ignored.
* @returns An `AbortSignal` that aborts when any valid source aborts,
* or `undefined` if no valid sources are provided.
*/
function mergeAbortSignals(...signals) {
	const validSignals = filterNullable(...signals).map((signal) => typeof signal === "number" ? AbortSignal.timeout(signal) : signal);
	return validSignals.length === 0 ? void 0 : validSignals.length === 1 ? validSignals[0] : AbortSignal.any(validSignals);
}
//#endregion
//#region src/util/set-abort-timeout.ts
/**
* Schedules a timeout that aborts the given controller with a `TimeoutError`
* `DOMException`, matching the reason produced by `AbortSignal.timeout(ms)`.
*
* @param abortController - The controller to abort when the timeout elapses.
* If undefined, no timeout is scheduled.
* @param label - Human-readable label included in the error message
* (e.g. "Step", "Chunk").
* @param timeoutMs - Duration in milliseconds before the controller is aborted.
* If undefined, no timeout is scheduled.
* @returns The timeout id (suitable for passing to `clearTimeout`), or
* `undefined` if no timeout was scheduled.
*/
function setAbortTimeout({ abortController, label, timeoutMs }) {
	if (abortController == null || timeoutMs == null) return;
	return setTimeout(() => abortController.abort(new DOMException(`${label} timeout of ${timeoutMs}ms exceeded`, "TimeoutError")), timeoutMs);
}
//#endregion
//#region src/util/merge-callbacks.ts
/**
* Creates an async callback that invokes the provided callbacks in parallel.
* Undefined callbacks are skipped, and thrown or rejected callback errors are
* ignored.
*
* @param callbacks The callbacks to invoke for each event.
* @returns A callback that forwards each event to all callbacks and waits for
* them to settle.
*/
function mergeCallbacks(...callbacks) {
	return async (event) => {
		await Promise.allSettled(callbacks.map(async (callback) => {
			await callback?.(event);
		}));
	};
}
//#endregion
//#region src/telemetry/filter-included-context.ts
/**
* Returns a shallow copy of the runtime context with only top-level
* properties marked for telemetry inclusion.
*/
function filterIncludedContext({ context, includeContext }) {
	if (context == null) return {};
	return Object.fromEntries(Object.entries(context).filter(([key]) => includeContext?.[key] === true));
}
function filterToolsContext({ toolsContext, includeToolsContext }) {
	if (includeToolsContext == null) return {};
	return Object.fromEntries(Object.entries(toolsContext).map(([toolName, toolContext]) => [toolName, filterToolContext({
		toolName,
		toolContext,
		includeToolsContext
	})]));
}
function filterToolContext({ toolName, toolContext, includeToolsContext }) {
	const includeToolContext = includeToolsContext?.[toolName];
	return filterIncludedContext({
		context: toolContext,
		includeContext: includeToolContext
	});
}
//#endregion
//#region src/telemetry/tracing-channel.ts
const AI_SDK_TELEMETRY_TRACING_CHANNEL = "ai:telemetry";
//#endregion
//#region src/util/is-node-runtime.ts
function isNodeRuntime() {
	return globalThis.process?.release?.name === "node";
}
//#endregion
//#region src/telemetry/redact-telemetry-credentials.ts
/**
* Apply provider-owned credential redaction on telemetry-only copies. Only visit SDK
* metadata containers, never arbitrary prompts, tool outputs, or user context.
*/
function redactTelemetryCredentials(value) {
	return replaceProperties(value, {
		args: redactTelemetryValue,
		tools: redactTools,
		stepTools: redactTools,
		request: redactMetadata,
		response: redactMetadata,
		steps: (steps) => mapArray(steps, redactTelemetryCredentials),
		finalStep: redactTelemetryCredentials,
		error: redactTelemetryCredentials,
		cause: redactTelemetryCredentials,
		errors: (errors) => mapArray(errors, redactTelemetryCredentials),
		lastError: redactTelemetryCredentials,
		requestBodyValues: redactBody
	});
}
function redactMetadata(value) {
	return Array.isArray(value) ? mapArray(value, redactMetadata) : replaceProperties(value, { body: redactBody });
}
function redactBody(value) {
	return replaceProperties(redactTelemetryValue(value), { tools: redactTools });
}
function redactTools(value) {
	if (Array.isArray(value)) return mapArray(value, redactTelemetryCredentials);
	if (!isRecord(value)) return value;
	return replaceProperties(value, Object.fromEntries(Object.keys(value).map((key) => [key, redactTelemetryCredentials])));
}
function isRecord(value) {
	return value != null && typeof value === "object" && !Array.isArray(value);
}
function mapArray(value, redact) {
	if (!Array.isArray(value)) return value;
	const copy = value.map(redact);
	return copy.some((entry, index) => entry !== value[index]) ? copy : value;
}
/** Preserve result getters, streams, and property descriptors without mutation. */
function replaceProperties(value, redactors) {
	if (!isRecord(value)) return value;
	let descriptors;
	for (const [key, redact] of Object.entries(redactors)) {
		const descriptor = Object.getOwnPropertyDescriptor(value, key);
		if (descriptor == null || !("value" in descriptor)) continue;
		const redacted = redact(descriptor.value);
		if (redacted !== descriptor.value) {
			descriptors ??= Object.getOwnPropertyDescriptors(value);
			descriptors[key] = {
				...descriptor,
				value: redacted
			};
		}
	}
	return descriptors == null ? value : Object.create(Object.getPrototypeOf(value), descriptors);
}
//#endregion
//#region src/telemetry/tracing-channel-publisher.ts
let diagnosticsChannelPromise;
/**
* Loads Node's diagnostics channel module only when the current runtime supports
* it. Unsupported runtimes and failed imports intentionally resolve to
* undefined so telemetry tracing never crashes user code.
*/
async function loadDiagnosticsChannel() {
	if (!isNodeRuntime()) return;
	if (diagnosticsChannelPromise == null) diagnosticsChannelPromise = Promise.resolve(loadBuiltinModule("node:diagnostics_channel"));
	return diagnosticsChannelPromise;
}
function loadBuiltinModule(id) {
	const processWithBuiltins = globalThis.process;
	try {
		return processWithBuiltins?.getBuiltinModule?.(id);
	} catch {
		return;
	}
}
/**
* Runs an async operation inside the AI SDK telemetry tracing channel when
* tracing subscribers may exist. Without Node diagnostics-channel support,
* without tracingChannel support, or when the runtime reports no subscribers,
* this is a direct pass-through.
*
* The execution bookkeeping preserves the original model/tool result or error
* if tracing itself throws, and prevents falling back by calling `execute` a
* second time.
*/
async function runWithTracingChannelSpan(message, execute, recordResult = true) {
	const tracingChannel = (await loadDiagnosticsChannel())?.tracingChannel?.(AI_SDK_TELEMETRY_TRACING_CHANNEL);
	if (tracingChannel == null || tracingChannel.hasSubscribers === false) return await execute();
	let executePromise;
	let executionResult;
	let executionError;
	let hasExecutionResult = false;
	let hasExecutionError = false;
	const tracedExecute = () => {
		try {
			executePromise = Promise.resolve(execute());
		} catch (error) {
			executePromise = Promise.reject(error);
		}
		executePromise = executePromise.then((result) => {
			executionResult = result;
			hasExecutionResult = true;
			return result;
		}, (error) => {
			executionError = error;
			hasExecutionError = true;
			throw error;
		});
		return recordResult ? executePromise.then(redactTelemetryCredentials, (error) => {
			throw redactTelemetryCredentials(error);
		}) : executePromise.then(() => void 0, () => {
			throw new Error("AI SDK operation failed");
		});
	};
	try {
		await tracingChannel.tracePromise(tracedExecute, message);
		return executionResult;
	} catch {
		if (hasExecutionError) throw executionError;
		if (hasExecutionResult) return executionResult;
		if (executePromise != null) return await executePromise;
		return await execute();
	}
}
/**
* Opens a long-lived tracing-channel span context and returns a runner that can
* re-enter that context later without changing stream setup timing.
*/
function openTelemetryChannelSpanContext({ message, completion, recordResult = true }) {
	if (!isNodeRuntime()) {
		Promise.resolve(completion).catch(() => {});
		return;
	}
	const diagnosticsChannel = loadBuiltinModule("node:diagnostics_channel");
	const asyncHooks = loadBuiltinModule("node:async_hooks");
	const tracingChannel = diagnosticsChannel?.tracingChannel?.(AI_SDK_TELEMETRY_TRACING_CHANNEL);
	if (tracingChannel == null || tracingChannel.hasSubscribers === false || asyncHooks == null) {
		Promise.resolve(completion).catch(() => {});
		return;
	}
	const context = message;
	let asyncResource;
	let asyncEndPublished = false;
	const safePublish = (publish) => {
		try {
			publish();
		} catch {}
	};
	const publishAsyncEnd = ({ result, error }) => {
		if (asyncEndPublished) return;
		asyncEndPublished = true;
		if (error !== void 0) {
			context.error = recordResult ? redactTelemetryCredentials(error) : /* @__PURE__ */ new Error("AI SDK operation failed");
			safePublish(() => tracingChannel.error.publish(context));
		}
		if (recordResult && result !== void 0) context.result = redactTelemetryCredentials(result);
		safePublish(() => tracingChannel.asyncEnd.publish(context));
	};
	safePublish(() => {
		tracingChannel.start.runStores(context, () => {
			asyncResource = new asyncHooks.AsyncResource("ai.telemetry");
		});
	});
	safePublish(() => tracingChannel.end.publish(context));
	Promise.resolve(completion).then((result) => publishAsyncEnd({ result }), (error) => publishAsyncEnd({ error }));
	return { run: (execute) => asyncResource == null ? execute() : asyncResource.runInAsyncScope(execute) };
}
//#endregion
//#region src/telemetry/telemetry-registry.ts
function getGlobalTelemetryIntegrations() {
	return globalThis.AI_SDK_TELEMETRY_INTEGRATIONS ?? [];
}
//#endregion
//#region src/telemetry/filter-telemetry-event.ts
/**
* Filters SDK-owned content fields on a copy. Only descend into SDK event
* containers; user context has its own inclusion policy.
*/
function filterTelemetryEvent(event, telemetry) {
	const hideInputs = telemetry.recordInputs === false;
	const hideOutputs = telemetry.recordOutputs === false;
	if (!hideInputs && !hideOutputs || event == null || typeof event !== "object") return event;
	const filtered = Object.assign(Object.create(Object.getPrototypeOf(event)), event);
	const replace = (fields) => {
		for (const [key, value] of Object.entries(fields)) if (Object.hasOwn(event, key)) filtered[key] = value;
	};
	const isSpeech = filtered.operationId === "ai.generateSpeech";
	if (hideInputs) {
		replace({
			instructions: void 0,
			system: void 0,
			prompt: void 0,
			messages: [],
			promptMessages: [],
			experimental_steeringMessages: [],
			tools: void 0,
			stepTools: void 0,
			schema: void 0,
			schemaName: void 0,
			schemaDescription: void 0,
			...typeof filtered.output === "object" ? { output: void 0 } : {},
			providerOptions: {},
			value: "",
			values: [],
			query: "",
			documents: [],
			state: Array.isArray(filtered.state) ? [] : typeof filtered.state === "string" ? "" : {},
			questions: {},
			...isSpeech ? { text: "" } : {}
		});
		if (filtered.toolCall != null) filtered.toolCall = {
			...filtered.toolCall,
			input: void 0
		};
		if (filtered.toolOutput != null) filtered.toolOutput = {
			...filtered.toolOutput,
			input: void 0
		};
		if (Array.isArray(filtered.ranking)) filtered.ranking = filtered.ranking.map((entry) => "document" in entry ? {
			...entry,
			document: typeof entry.document === "string" ? "" : {}
		} : entry);
	}
	if (hideOutputs) {
		replace({
			content: [],
			...!isSpeech ? { text: "" } : {},
			reasoning: Array.isArray(filtered.reasoning) ? [] : void 0,
			reasoningText: void 0,
			files: [],
			sources: [],
			toolCalls: [],
			staticToolCalls: [],
			dynamicToolCalls: [],
			toolResults: [],
			staticToolResults: [],
			dynamicToolResults: [],
			responseMessages: [],
			object: void 0,
			objectText: "",
			embedding: [],
			embeddings: [],
			ranking: [],
			answers: {},
			segments: [],
			words: []
		});
		if (filtered.toolOutput != null) filtered.toolOutput = {
			...filtered.toolOutput,
			output: void 0,
			error: void 0
		};
	}
	replace({
		providerMetadata: void 0,
		error: filtered.error == null ? filtered.error : /* @__PURE__ */ new Error("AI SDK operation failed")
	});
	for (const key of ["toolCall", "toolOutput"]) {
		const toolEvent = filtered[key];
		if (toolEvent != null && typeof toolEvent === "object") filtered[key] = {
			...toolEvent,
			providerMetadata: void 0,
			..."error" in toolEvent ? { error: toolEvent.error == null ? toolEvent.error : /* @__PURE__ */ new Error("AI SDK operation failed") } : {}
		};
	}
	for (const key of ["request", "response"]) {
		const filterMetadata = (metadata) => {
			if (metadata == null || typeof metadata !== "object") return metadata;
			const filteredMetadata = { ...metadata };
			delete filteredMetadata.body;
			if (key === "request" ? hideInputs : hideOutputs) {
				if ("messages" in metadata) filteredMetadata.messages = [];
				if ("instructions" in metadata) filteredMetadata.instructions = void 0;
			}
			return filteredMetadata;
		};
		const metadata = filtered[key];
		if (metadata != null) filtered[key] = Array.isArray(metadata) ? metadata.map(filterMetadata) : filterMetadata(metadata);
	}
	if (Array.isArray(filtered.steps)) filtered.steps = filtered.steps.map((step) => filterTelemetryEvent(step, telemetry));
	if (Object.hasOwn(event, "finalStep")) filtered.finalStep = filterTelemetryEvent(filtered.finalStep, telemetry);
	return filtered;
}
//#endregion
//#region src/telemetry/create-telemetry-dispatcher.ts
function augmentEvent(event, telemetry, filterContext = false) {
	const augmentedEvent = Object.assign(Object.create(Object.getPrototypeOf(event)), event, {
		recordInputs: telemetry.recordInputs,
		recordOutputs: telemetry.recordOutputs,
		functionId: telemetry.functionId,
		aiVersion: VERSION
	});
	if (filterContext && event != null && typeof event === "object" && "runtimeContext" in event) augmentedEvent.runtimeContext = filterIncludedContext({
		context: event.runtimeContext,
		includeContext: telemetry.includeRuntimeContext
	});
	if (filterContext && event != null && typeof event === "object") {
		if ("toolsContext" in event) augmentedEvent.toolsContext = filterToolsContext({
			toolsContext: event.toolsContext,
			includeToolsContext: telemetry.includeToolsContext
		});
		else if ("toolContext" in event && event.toolContext != null && "toolCall" in event && event.toolCall != null && typeof event.toolCall === "object" && "toolName" in event.toolCall) augmentedEvent.toolContext = filterToolContext({
			toolName: event.toolCall.toolName,
			toolContext: event.toolContext,
			includeToolsContext: telemetry.includeToolsContext
		});
	}
	return redactTelemetryCredentials(filterTelemetryEvent(augmentedEvent, telemetry));
}
/**
* Creates a telemetry dispatcher that sends telemetry events
* to the resolved set of integrations.
*
* When per-call integrations are provided, they take precedence over the globally
* registered integrations for that call. When no per-call integrations are
* provided, the globally registered integrations are used.
*
* @param args.telemetry - Optional per-call telemetry settings and integrations.
*
* @returns A telemetry dispatcher that fans out lifecycle events to the
* resolved set of integrations.
*/
function createTelemetryDispatcher({ telemetry }) {
	if (telemetry?.isEnabled === false) return {};
	const localIntegrations = telemetry?.integrations;
	const integrations = localIntegrations != null ? asArray(localIntegrations) : getGlobalTelemetryIntegrations();
	const telemetryMetadata = {
		recordInputs: telemetry?.recordInputs,
		recordOutputs: telemetry?.recordOutputs,
		functionId: telemetry?.functionId,
		includeRuntimeContext: telemetry?.includeRuntimeContext,
		includeToolsContext: telemetry?.includeToolsContext
	};
	const recordResult = telemetry?.recordInputs !== false && telemetry?.recordOutputs !== false;
	const mergeTelemetryCallback = (key, deprecatedKey) => {
		const integrationCallbacks = integrations.map((integration) => {
			const callback = integration[key] ?? (deprecatedKey == null ? void 0 : integration[deprecatedKey]);
			return typeof callback === "function" ? callback.bind(integration) : void 0;
		}).filter(Boolean).map((callback) => ((event) => callback(augmentEvent(event, telemetryMetadata))));
		if (integrationCallbacks.length === 0) return;
		const mergedIntegrationCallback = mergeCallbacks(...integrationCallbacks);
		return async (event) => {
			await mergedIntegrationCallback(event);
		};
	};
	const onStepEnd = mergeTelemetryCallback("onStepEnd");
	const onStepFinish = mergeTelemetryCallback("onStepFinish");
	const executeLanguageModelCallWrappers = integrations.map((integration) => integration.executeLanguageModelCall?.bind(integration)).filter(Boolean);
	const executeToolWrappers = integrations.map((integration) => integration.executeTool?.bind(integration)).filter(Boolean);
	return {
		runInTracingChannelSpan: async ({ type, event, execute }) => await runWithTracingChannelSpan({
			type,
			event: augmentEvent(event, telemetryMetadata, true)
		}, execute, recordResult),
		startTracingChannelContext: ({ type, event, completion }) => openTelemetryChannelSpanContext({
			message: {
				type,
				event: augmentEvent(event, telemetryMetadata, true)
			},
			completion,
			recordResult
		}),
		onStart: mergeTelemetryCallback("onStart"),
		onStepStart: mergeTelemetryCallback("onStepStart"),
		onLanguageModelCallStart: mergeTelemetryCallback("onLanguageModelCallStart"),
		onLanguageModelCallEnd: mergeTelemetryCallback("onLanguageModelCallEnd"),
		onToolExecutionStart: mergeTelemetryCallback("onToolExecutionStart"),
		onToolExecutionEnd: mergeTelemetryCallback("onToolExecutionEnd"),
		onStepEnd: onStepEnd == null && onStepFinish == null ? void 0 : mergeCallbacks(onStepEnd, onStepFinish),
		onStepError: mergeTelemetryCallback("onStepError"),
		onObjectStepStart: mergeTelemetryCallback("onObjectStepStart"),
		onObjectStepEnd: mergeTelemetryCallback("onObjectStepEnd"),
		onEmbedStart: mergeTelemetryCallback("onEmbedStart"),
		onEmbedEnd: mergeTelemetryCallback("onEmbedEnd"),
		onRerankStart: mergeTelemetryCallback("onRerankStart"),
		onRerankEnd: mergeTelemetryCallback("onRerankEnd"),
		experimental_onDecideStart: mergeTelemetryCallback("experimental_onDecideStart", "experimental_onEvaluateStart"),
		experimental_onDecisionModelCallStart: mergeTelemetryCallback("experimental_onDecisionModelCallStart", "experimental_onEvaluationModelCallStart"),
		experimental_onDecisionModelCallEnd: mergeTelemetryCallback("experimental_onDecisionModelCallEnd", "experimental_onEvaluationModelCallEnd"),
		experimental_onDecideEnd: mergeTelemetryCallback("experimental_onDecideEnd", "experimental_onEvaluateEnd"),
		experimental_onStreamTranscriptionStart: mergeTelemetryCallback("experimental_onStreamTranscriptionStart"),
		experimental_onStreamTranscriptionEnd: mergeTelemetryCallback("experimental_onStreamTranscriptionEnd"),
		onEnd: mergeTelemetryCallback("onEnd"),
		onAbort: mergeTelemetryCallback("onAbort"),
		onError: mergeTelemetryCallback("onError"),
		/**
		* Runs provider calls inside integration-specific context so
		* auto-instrumented provider requests can be associated with model work.
		*/
		executeLanguageModelCall: async ({ execute, ...event }) => {
			const augmentedEvent = augmentEvent(event, telemetryMetadata);
			let wrappedExecute = execute;
			for (const executeWrapper of executeLanguageModelCallWrappers) {
				const innerExecute = wrappedExecute;
				wrappedExecute = async () => {
					const originals = /* @__PURE__ */ new Map();
					const redact = (original) => {
						const redacted = redactTelemetryCredentials(original);
						if (redacted !== original) originals.set(redacted, original);
						return redacted;
					};
					const restore = (value) => originals.has(value) ? originals.get(value) : value;
					try {
						return restore(await executeWrapper({
							...augmentedEvent,
							execute: async () => {
								try {
									return redact(await innerExecute());
								} catch (error) {
									throw redact(error);
								}
							}
						}));
					} catch (error) {
						throw restore(error);
					}
				};
			}
			return await runWithTracingChannelSpan({
				type: "languageModelCall",
				event: augmentedEvent
			}, wrappedExecute, recordResult);
		},
		/**
		* Composes all `executeTool` wrappers around the original tool execution.
		* Each wrapper receives an `execute` function that calls the next wrapper in
		* the chain, so integrations can establish nested telemetry context before
		* delegating to the underlying tool.
		*/
		executeTool: async ({ execute, ...event }) => {
			const augmentedEvent = augmentEvent(event, telemetryMetadata);
			let wrappedExecute = execute;
			for (const executeWrapper of executeToolWrappers) {
				const innerExecute = wrappedExecute;
				wrappedExecute = () => executeWrapper({
					...augmentedEvent,
					execute: innerExecute
				});
			}
			return await wrappedExecute();
		}
	};
}
//#endregion
//#region src/generate-text/reasoning.ts
function asReasoningText(reasoningParts) {
	const reasoningText = reasoningParts.map((part) => "text" in part ? part.text : "").join("");
	return reasoningText.length > 0 ? reasoningText : void 0;
}
//#endregion
//#region src/generate-text/generated-file.ts
var DefaultGeneratedFile = class {
	constructor({ data, mediaType, providerMetadata }) {
		this.base64Data = typeof data === "string" ? data : void 0;
		this.uint8ArrayData = typeof data === "string" ? void 0 : convertDataContentToUint8Array(data);
		this.mediaType = mediaType;
		this.providerMetadata = providerMetadata;
	}
	get base64() {
		if (this.base64Data == null) this.base64Data = convertUint8ArrayToBase64(this.uint8ArrayData);
		return this.base64Data;
	}
	get uint8Array() {
		if (this.uint8ArrayData == null) this.uint8ArrayData = convertBase64ToUint8Array(this.base64Data);
		return this.uint8ArrayData;
	}
};
//#endregion
//#region src/generate-text/reasoning-output.ts
function unwrapReasoningFileData(data) {
	if (typeof data === "object" && data !== null && "type" in data) return data.type === "data" ? data.data : data.url;
	return data;
}
function convertFromReasoningOutputs(parts) {
	return parts.map((part) => {
		if (part.type === "reasoning") return {
			type: "reasoning",
			text: part.text,
			...part.providerMetadata != null ? { providerOptions: part.providerMetadata } : {}
		};
		return {
			type: "reasoning-file",
			data: part.file.base64,
			mediaType: part.file.mediaType,
			...part.providerMetadata != null ? { providerOptions: part.providerMetadata } : {}
		};
	});
}
function convertToReasoningOutputs(parts) {
	return parts.map((part) => {
		if (part.type === "reasoning") return {
			type: "reasoning",
			text: part.text,
			...part.providerOptions != null ? { providerMetadata: part.providerOptions } : {}
		};
		const rawData = unwrapReasoningFileData(part.data);
		return {
			type: "reasoning-file",
			file: new DefaultGeneratedFile({
				data: rawData instanceof ArrayBuffer ? new Uint8Array(rawData) : rawData instanceof URL ? rawData.toString() : rawData,
				mediaType: part.mediaType
			}),
			...part.providerOptions != null ? { providerMetadata: part.providerOptions } : {}
		};
	});
}
//#endregion
//#region src/generate-text/step-result.ts
var DefaultStepResult = class {
	constructor({ callId, stepNumber, provider, modelId, runtimeContext, toolsContext, content, finishReason, rawFinishReason, usage, performance, warnings, request, response, providerMetadata, steeringMessages }) {
		this.callId = callId;
		this.stepNumber = stepNumber;
		this.model = {
			provider,
			modelId
		};
		this.runtimeContext = runtimeContext;
		this.toolsContext = toolsContext;
		this.content = content;
		this.finishReason = finishReason;
		this.rawFinishReason = rawFinishReason;
		this.usage = usage;
		this.performance = performance;
		this.warnings = warnings;
		this.request = request;
		this.response = response;
		this.providerMetadata = providerMetadata;
		if (steeringMessages != null && steeringMessages.length > 0) this.experimental_steeringMessages = steeringMessages;
	}
	get text() {
		return this.content.filter((part) => part.type === "text").map((part) => part.text).join("");
	}
	get reasoning() {
		return convertFromReasoningOutputs(this.content.filter((part) => part.type === "reasoning" || part.type === "reasoning-file"));
	}
	get reasoningText() {
		return asReasoningText(this.reasoning);
	}
	get files() {
		return this.content.filter((part) => part.type === "file").map((part) => part.file);
	}
	get sources() {
		return this.content.filter((part) => part.type === "source");
	}
	get toolCalls() {
		return this.content.filter((part) => part.type === "tool-call");
	}
	get staticToolCalls() {
		return this.toolCalls.filter((toolCall) => toolCall.dynamic !== true);
	}
	get dynamicToolCalls() {
		return this.toolCalls.filter((toolCall) => toolCall.dynamic === true);
	}
	get toolResults() {
		return this.content.filter((part) => part.type === "tool-result");
	}
	get staticToolResults() {
		return this.toolResults.filter((toolResult) => toolResult.dynamic !== true);
	}
	get dynamicToolResults() {
		return this.toolResults.filter((toolResult) => toolResult.dynamic === true);
	}
};
//#endregion
//#region src/generate-text/restricted-telemetry-dispatcher.ts
/**
* Creates a copy of a step result whose runtime context only contains
* top-level properties marked for telemetry inclusion.
*/
function restrictStepResult({ step, includeRuntimeContext, includeToolsContext }) {
	return new DefaultStepResult({
		callId: step.callId,
		stepNumber: step.stepNumber,
		provider: step.model.provider,
		modelId: step.model.modelId,
		runtimeContext: filterIncludedContext({
			context: step.runtimeContext,
			includeContext: includeRuntimeContext
		}),
		toolsContext: filterToolsContext({
			toolsContext: step.toolsContext,
			includeToolsContext
		}),
		content: step.content,
		finishReason: step.finishReason,
		rawFinishReason: step.rawFinishReason,
		usage: step.usage,
		performance: step.performance,
		warnings: step.warnings,
		request: step.request,
		response: step.response,
		providerMetadata: step.providerMetadata,
		steeringMessages: step.experimental_steeringMessages
	});
}
/**
* Creates a telemetry dispatcher that only includes configured runtime context
* properties in text-generation lifecycle events before dispatching them.
*/
function createRestrictedTelemetryDispatcher({ telemetry, includeRuntimeContext, includeToolsContext }) {
	const telemetryDispatcher = createTelemetryDispatcher({ telemetry });
	const restrictStepStartEvent = (event) => ({
		...event,
		runtimeContext: filterIncludedContext({
			context: event.runtimeContext,
			includeContext: includeRuntimeContext
		}),
		steps: event.steps.map((step) => restrictStepResult({
			step,
			includeRuntimeContext,
			includeToolsContext
		})),
		toolsContext: filterToolsContext({
			toolsContext: event.toolsContext,
			includeToolsContext
		})
	});
	return {
		...telemetryDispatcher,
		onStart: (event) => telemetryDispatcher.onStart?.({
			...event,
			runtimeContext: filterIncludedContext({
				context: event.runtimeContext,
				includeContext: includeRuntimeContext
			}),
			toolsContext: filterToolsContext({
				toolsContext: event.toolsContext,
				includeToolsContext
			})
		}),
		onStepStart: (event) => telemetryDispatcher.onStepStart?.(restrictStepStartEvent(event)),
		onStepEnd: (event) => telemetryDispatcher.onStepEnd?.(restrictStepResult({
			step: event,
			includeRuntimeContext,
			includeToolsContext
		})),
		onStepFinish: (event) => telemetryDispatcher.onStepEnd?.(restrictStepResult({
			step: event,
			includeRuntimeContext,
			includeToolsContext
		})),
		onStepError: (event) => telemetryDispatcher.onStepError?.(restrictStepStartEvent(event)),
		onEnd: (event) => telemetryDispatcher.onEnd?.(((restrictedSteps) => {
			return {
				...event,
				runtimeContext: filterIncludedContext({
					context: event.runtimeContext,
					includeContext: includeRuntimeContext
				}),
				steps: restrictedSteps,
				finalStep: restrictedSteps.at(-1),
				toolsContext: filterToolsContext({
					toolsContext: event.toolsContext,
					includeToolsContext
				})
			};
		})(event.steps.map((step) => restrictStepResult({
			step,
			includeRuntimeContext,
			includeToolsContext
		})))),
		onAbort: (event) => telemetryDispatcher.onAbort?.({
			...event,
			steps: event.steps.map((step) => restrictStepResult({
				step,
				includeRuntimeContext,
				includeToolsContext
			}))
		}),
		onToolExecutionStart: (event) => telemetryDispatcher.onToolExecutionStart?.({
			...event,
			toolContext: filterToolContext({
				toolName: event.toolCall.toolName,
				toolContext: event.toolContext,
				includeToolsContext
			})
		}),
		onToolExecutionEnd: (event) => telemetryDispatcher.onToolExecutionEnd?.({
			...event,
			toolContext: filterToolContext({
				toolName: event.toolCall.toolName,
				toolContext: event.toolContext,
				includeToolsContext
			})
		})
	};
}
//#endregion
//#region src/util/get-own.ts
/**
* Reads a property by an untrusted key, ignoring inherited prototype members.
*
* Tool sets, tool contexts, and similar lookup objects are indexed by names
* that can come from model output or client-supplied message history. Plain
* bracket access (`obj[name]`) resolves names such as `constructor`,
* `toString`, or `__proto__` to values on `Object.prototype`, which would slip
* past the `== null` / `!value` guards that treat an unknown name as "not
* present". This helper returns `undefined` unless `key` is an own property.
*/
function getOwn(obj, key) {
	return obj != null && Object.hasOwn(obj, key) ? obj[key] : void 0;
}
//#endregion
//#region src/generate-text/tool-call.ts
const inputSchemaInputSymbol = Symbol("ai-sdk-tool-call-input-schema-input");
function setToolCallInputSchemaInput(toolCall, inputSchemaInput) {
	Object.defineProperty(toolCall, inputSchemaInputSymbol, { value: inputSchemaInput });
	return toolCall;
}
function getToolCallInputSchemaInput(toolCall) {
	return inputSchemaInputSymbol in toolCall ? { value: toolCall[inputSchemaInputSymbol] } : void 0;
}
//#endregion
//#region src/generate-text/parse-tool-call.ts
async function parseToolCall({ toolCall, tools, repairToolCall, refineToolInput, messages, instructions, abortSignal }) {
	try {
		if (tools == null) {
			if (toolCall.providerExecuted && toolCall.dynamic) return await refineParsedToolCallInput({
				toolCall: await parseProviderExecutedDynamicToolCall(toolCall),
				refineToolInput
			});
			throw new NoSuchToolError({ toolName: toolCall.toolName });
		}
		try {
			return await refineParsedToolCallInput({
				toolCall: await doParseToolCall({
					toolCall,
					tools
				}),
				refineToolInput
			});
		} catch (error) {
			if (repairToolCall == null || !(NoSuchToolError.isInstance(error) || InvalidToolInputError.isInstance(error))) throw error;
			let repairedToolCall = null;
			try {
				abortSignal?.throwIfAborted();
				repairedToolCall = await waitForPromiseWithAbortSignal({
					promise: repairToolCall({
						toolCall,
						tools,
						inputSchema: async ({ toolName }) => {
							const inputSchema = getOwn(tools, toolName)?.inputSchema;
							return await asSchema(inputSchema).jsonSchema;
						},
						instructions,
						system: instructions,
						messages,
						error,
						abortSignal
					}),
					abortSignal
				});
			} catch (repairError) {
				abortSignal?.throwIfAborted();
				throw new ToolCallRepairError({
					cause: repairError,
					originalError: error
				});
			}
			if (repairedToolCall == null) throw error;
			const parsedRepairedToolCall = await refineParsedToolCallInput({
				toolCall: await doParseToolCall({
					toolCall: repairedToolCall,
					tools
				}),
				refineToolInput
			});
			abortSignal?.throwIfAborted();
			return parsedRepairedToolCall;
		}
	} catch (error) {
		abortSignal?.throwIfAborted();
		const parsedInput = await safeParseJSON({ text: toolCall.input });
		const input = parsedInput.success ? parsedInput.value : toolCall.input;
		const tool = getOwn(tools, toolCall.toolName);
		return {
			type: "tool-call",
			toolCallId: toolCall.toolCallId,
			toolName: toolCall.toolName,
			input,
			dynamic: true,
			invalid: true,
			error,
			title: tool?.title,
			providerExecuted: toolCall.providerExecuted,
			providerMetadata: toolCall.providerMetadata,
			...tool?.metadata != null ? { toolMetadata: tool.metadata } : {}
		};
	}
}
async function waitForPromiseWithAbortSignal({ promise, abortSignal }) {
	if (abortSignal == null) return await promise;
	return await new Promise((resolve, reject) => {
		const cleanup = () => {
			abortSignal.removeEventListener("abort", onAbort);
		};
		const onAbort = () => {
			cleanup();
			reject(abortSignal.reason);
		};
		Promise.resolve(promise).then((value) => {
			cleanup();
			resolve(value);
		}).catch((error) => {
			cleanup();
			reject(error);
		});
		abortSignal.addEventListener("abort", onAbort, { once: true });
		if (abortSignal.aborted) onAbort();
	});
}
async function refineParsedToolCallInput({ toolCall, refineToolInput }) {
	const refine = getOwn(refineToolInput, toolCall.toolName);
	if (refine == null) return toolCall;
	const refinedToolCall = {
		...toolCall,
		input: await refine(toolCall.input)
	};
	const inputSchemaInput = getToolCallInputSchemaInput(toolCall);
	return inputSchemaInput == null ? refinedToolCall : setToolCallInputSchemaInput(refinedToolCall, inputSchemaInput.value);
}
async function parseProviderExecutedDynamicToolCall(toolCall) {
	const parseResult = toolCall.input.trim() === "" ? {
		success: true,
		value: {}
	} : await safeParseJSON({ text: toolCall.input });
	if (parseResult.success === false) throw new InvalidToolInputError({
		toolName: toolCall.toolName,
		toolInput: toolCall.input,
		cause: parseResult.error
	});
	return {
		type: "tool-call",
		toolCallId: toolCall.toolCallId,
		toolName: toolCall.toolName,
		input: parseResult.value,
		providerExecuted: true,
		dynamic: true,
		providerMetadata: toolCall.providerMetadata
	};
}
async function doParseToolCall({ toolCall, tools }) {
	const toolName = toolCall.toolName;
	const tool = getOwn(tools, toolName);
	if (tool == null) {
		if (toolCall.providerExecuted && toolCall.dynamic) return await parseProviderExecutedDynamicToolCall(toolCall);
		throw new NoSuchToolError({
			toolName: toolCall.toolName,
			availableTools: Object.keys(tools)
		});
	}
	const schema = asSchema(tool.inputSchema);
	const parseResult = toolCall.input.trim() === "" ? await safeValidateTypes({
		value: {},
		schema
	}) : await safeParseJSON({
		text: toolCall.input,
		schema
	});
	if (parseResult.success === false) throw new InvalidToolInputError({
		toolName,
		toolInput: toolCall.input,
		cause: parseResult.error
	});
	return setToolCallInputSchemaInput(tool.type === "dynamic" ? {
		type: "tool-call",
		toolCallId: toolCall.toolCallId,
		toolName: toolCall.toolName,
		input: parseResult.value,
		providerExecuted: toolCall.providerExecuted,
		providerMetadata: toolCall.providerMetadata,
		...tool.metadata != null ? { toolMetadata: tool.metadata } : {},
		dynamic: true,
		title: tool.title
	} : {
		type: "tool-call",
		toolCallId: toolCall.toolCallId,
		toolName,
		input: parseResult.value,
		providerExecuted: toolCall.providerExecuted,
		providerMetadata: toolCall.providerMetadata,
		...tool.metadata != null ? { toolMetadata: tool.metadata } : {},
		title: tool.title
	}, parseResult.rawValue);
}
//#endregion
//#region src/generate-text/is-output-chunk.ts
const isOutputChunkType = {
	file: true,
	custom: false,
	source: false,
	"text-start": false,
	"text-end": false,
	"text-delta": true,
	"reasoning-start": false,
	"reasoning-end": false,
	"reasoning-delta": true,
	"reasoning-file": true,
	"tool-input-start": false,
	"tool-input-end": false,
	"tool-input-delta": true,
	"tool-approval-request": false,
	"tool-approval-response": false,
	"tool-call": true,
	"tool-result": false,
	"tool-error": false,
	"tool-output-denied": false,
	"tool-execution-end": false,
	"model-call-start": false,
	"model-call-response-metadata": false,
	"model-call-end": false,
	error: false,
	ping: false,
	raw: false
};
function isOutputChunk(chunk) {
	if (!isOutputChunkType[chunk.type]) return false;
	switch (chunk.type) {
		case "text-delta":
		case "reasoning-delta": return chunk.text.length > 0;
		case "tool-input-delta": return chunk.delta.length > 0;
		case "file":
		case "reasoning-file":
		case "tool-call": return true;
		default: return false;
	}
}
//#endregion
//#region src/generate-text/validate-tool-context.ts
/**
* Validates a tool context value against the tool's optional context schema.
*
* When no context schema is defined, the original context value is returned as-is.
* Otherwise, the context is validated and normalized through the schema before
* being passed into tool execution and approval hooks.
*
* @throws {TypeValidationError} When the provided tool context does not match
* the tool's declared `contextSchema`.
*/
async function validateToolContext({ toolName, context, contextSchema }) {
	if (contextSchema == null) return context;
	return await validateTypes({
		value: context,
		schema: contextSchema,
		context: {
			field: "tool context",
			entityName: toolName
		}
	});
}
//#endregion
//#region src/tool-search/tool-search.ts
const toolSearchSymbol = Symbol.for("vercel.ai.toolSearch");
const toolSearchFunctionSymbol = Symbol.for("vercel.ai.toolSearch.search");
const toolSearchMaxResultsSymbol = Symbol.for("vercel.ai.toolSearch.maxResults");
function getToolSearchMaxResults(tool) {
	return tool[toolSearchMaxResultsSymbol] ?? 5;
}
function getToolSearchFunction(tool) {
	return tool[toolSearchFunctionSymbol];
}
function isToolSearch(tool) {
	return tool[toolSearchSymbol] === true;
}
//#endregion
//#region src/tool-search/prepare-tool-search.ts
/** Create discovery state for one generation, never for a shared tool instance. */
function createToolSearchState({ tools, toolCallers }) {
	const searchTools = Object.entries(tools ?? {}).filter(([, tool]) => tool.deferLoading || isToolSearch(tool));
	if (searchTools.length === 0) return (activeTools) => activeTools;
	const discovered = /* @__PURE__ */ new Set();
	const getCallers = (name) => getOwn(toolCallers, name) ?? ["AI_SDK_DIRECT_TOOL_CALL"];
	for (const [name, tool] of searchTools) if (getCallers(name).some((name) => {
		if (name === "AI_SDK_DIRECT_TOOL_CALL") return false;
		const caller = experimental_getToolCaller(tools?.[name]);
		return caller?.type !== "local" || caller.prepareModelMessage == null;
	}) || isToolSearch(tool) && tool.deferLoading) throw new InvalidArgumentError({
		parameter: "tools",
		value: name,
		message: `tool "${name}" must be callable directly or through code mode with toolDiscovery: 'conversation'. The search tool itself must not defer loading.`
	});
	return (activeTools, { toolsContext = {}, experimental_sandbox } = {}) => {
		if (activeTools == null) return;
		const entries = Object.entries(activeTools);
		return Object.fromEntries(entries.filter(([name, tool]) => !tool.deferLoading || discovered.has(name)).map(([searchName, tool]) => {
			if (!isToolSearch(tool)) return [searchName, tool];
			const callers = getCallers(searchName).filter((name) => name === "AI_SDK_DIRECT_TOOL_CALL" || Object.hasOwn(activeTools, name));
			const candidates = entries.filter(([name, candidate]) => candidate.deferLoading && !isToolSearch(candidate) && callers.some((caller) => getCallers(name).includes(caller)));
			return [searchName, {
				...tool,
				execute: async ({ query }) => {
					const availableTools = candidates.map(([name, candidate]) => {
						const description = resolveToolDescription({
							tool: candidate,
							toolName: name,
							toolsContext,
							experimental_sandbox
						});
						return {
							name,
							...description == null ? {} : { description }
						};
					});
					const toolsByName = new Map(availableTools.map((tool) => [tool.name, tool]));
					const customSearch = getToolSearchFunction(tool);
					const terms = [...new Set(tokenize(query))];
					const rankedNames = customSearch ? await customSearch({
						query,
						tools: availableTools.map((tool) => ({ ...tool }))
					}) : availableTools.map(({ name, description }) => {
						const nameTerms = tokenize(name);
						const descriptionTerms = tokenize(description ?? "");
						return {
							name,
							score: terms.reduce((score, term) => score + (nameTerms.includes(term) ? 2 : 0) + (descriptionTerms.includes(term) ? 1 : 0), 0)
						};
					}).filter((match) => match.score > 0).sort((a, b) => b.score - a.score).map((match) => match.name);
					const matches = [...new Set(rankedNames)].flatMap((name) => {
						const match = toolsByName.get(name);
						return match == null ? [] : [match];
					}).slice(0, getToolSearchMaxResults(tool));
					for (const { name } of matches) discovered.add(name);
					return { tools: matches };
				}
			}];
		}));
	};
}
function tokenize(text) {
	return text.replace(/([a-z\d])([A-Z])/g, "$1 $2").toLowerCase().match(/[\p{L}\p{N}]+/gu) ?? [];
}
//#endregion
//#region src/agent/default-stop-condition.ts
/**
* Logs the warning for the default stopWhen condition.
*/
function logDefaultStopConditionWarning({ stepCount, provider, modelId }) {
	logWarnings({
		provider,
		model: modelId,
		warnings: [{
			type: "other",
			message: `The tool loop stopped because it reached the default stopWhen condition, isStepCount(${stepCount}). To allow more steps, set stopWhen to isStepCount(...) with a higher limit or provide a custom stop condition. Learn more: https://ai-sdk.dev/docs/agents/loop-control`
		}]
	});
}
//#endregion
//#region src/generate-text/collect-tool-approvals.ts
/**
* If the last message is a tool message, this function collects all tool approvals
* from that message.
*/
function collectToolApprovals({ messages }) {
	const lastMessage = messages.at(-1);
	if (lastMessage?.role != "tool") return {
		approvedToolApprovals: [],
		deniedToolApprovals: []
	};
	const toolCallsByToolCallId = Object.create(null);
	const toolCallOrder = Object.create(null);
	let nextToolCallIndex = 0;
	for (const message of messages) if (message.role === "assistant" && typeof message.content !== "string") {
		const content = message.content;
		for (const part of content) if (part.type === "tool-call") {
			toolCallsByToolCallId[part.toolCallId] = part;
			toolCallOrder[part.toolCallId] = nextToolCallIndex++;
		}
	}
	const toolApprovalRequestsByApprovalId = Object.create(null);
	for (const message of messages) if (message.role === "assistant" && typeof message.content !== "string") {
		const content = message.content;
		for (const part of content) if (part.type === "tool-approval-request") toolApprovalRequestsByApprovalId[part.approvalId] = part;
	}
	const toolResults = Object.create(null);
	for (const part of lastMessage.content) if (part.type === "tool-result") toolResults[part.toolCallId] = part;
	const approvedToolApprovals = [];
	const deniedToolApprovals = [];
	const collectedToolCallIds = /* @__PURE__ */ new Set();
	const approvalResponses = lastMessage.content.filter((part) => part.type === "tool-approval-response");
	for (const approvalResponse of approvalResponses) {
		const approvalRequest = toolApprovalRequestsByApprovalId[approvalResponse.approvalId];
		if (approvalRequest == null) throw new InvalidToolApprovalError({ approvalId: approvalResponse.approvalId });
		const existingToolResult = toolResults[approvalRequest.toolCallId];
		if (existingToolResult != null && (approvalResponse.approved || existingToolResult.output.type !== "execution-denied")) continue;
		const toolCall = toolCallsByToolCallId[approvalRequest.toolCallId];
		if (toolCall == null) throw new ToolCallNotFoundForApprovalError({
			toolCallId: approvalRequest.toolCallId,
			approvalId: approvalRequest.approvalId
		});
		if (collectedToolCallIds.has(toolCall.toolCallId)) continue;
		collectedToolCallIds.add(toolCall.toolCallId);
		const approval = {
			approvalRequest,
			approvalResponse,
			toolCall,
			...existingToolResult != null ? { existingToolResult } : {}
		};
		if (approvalResponse.approved) approvedToolApprovals.push(approval);
		else deniedToolApprovals.push(approval);
	}
	approvedToolApprovals.sort((a, b) => toolCallOrder[a.toolCall.toolCallId] - toolCallOrder[b.toolCall.toolCallId]);
	return {
		approvedToolApprovals,
		deniedToolApprovals
	};
}
//#endregion
//#region src/util/canonical-hash.ts
const encoder$1 = new TextEncoder();
/**
* Deterministic JSON serialization: object keys are sorted so that two
* structurally-equal values always produce the same string regardless of key
* insertion order. Used as the input to content hashing.
*/
function canonicalJSON(value) {
	if (value === null || value === void 0) return JSON.stringify(value);
	if (typeof value !== "object") return JSON.stringify(value);
	if (Array.isArray(value)) return `[${value.map((element) => element === void 0 ? "null" : canonicalJSON(element)).join(",")}]`;
	return `{${Object.keys(value).sort().map((k) => `${JSON.stringify(k)}:${canonicalJSON(value[k])}`).join(",")}}`;
}
function toBase64url(bytes) {
	return convertUint8ArrayToBase64(bytes).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/g, "");
}
/**
* Canonical SHA-256 digest (base64url) of an arbitrary JSON-serializable value.
*/
async function hashCanonical(value) {
	const digest = await crypto.subtle.digest("SHA-256", encoder$1.encode(canonicalJSON(value)));
	return toBase64url(new Uint8Array(digest));
}
//#endregion
//#region src/generate-text/tool-approval-signature.ts
const encoder = new TextEncoder();
function fromBase64url(str) {
	return convertBase64ToUint8Array(str);
}
async function importKey(secret) {
	const keyData = typeof secret === "string" ? encoder.encode(secret) : secret;
	return crypto.subtle.importKey("raw", keyData, {
		name: "HMAC",
		hash: "SHA-256"
	}, false, ["sign", "verify"]);
}
function buildPayload(approvalId, toolCallId, toolName, inputDigest) {
	return encoder.encode(JSON.stringify([
		"ai-sdk-tool-approval-v1",
		approvalId,
		toolCallId,
		toolName,
		inputDigest
	]));
}
function buildLegacyPayload(approvalId, toolCallId, toolName, inputDigest) {
	return encoder.encode(`${approvalId}\n${toolCallId}\n${toolName}\n${inputDigest}`);
}
async function signToolApproval({ secret, approvalId, toolCallId, toolName, input }) {
	const key = await importKey(secret);
	const payload = buildPayload(approvalId, toolCallId, toolName, await hashCanonical(input));
	const sig = await crypto.subtle.sign("HMAC", key, payload);
	return toBase64url(new Uint8Array(sig));
}
async function verifyToolApprovalSignature({ secret, signature, approvalId, toolCallId, toolName, input }) {
	const key = await importKey(secret);
	const inputDigest = await hashCanonical(input);
	const sigBytes = fromBase64url(signature);
	const payload = buildPayload(approvalId, toolCallId, toolName, inputDigest);
	if (await crypto.subtle.verify("HMAC", key, sigBytes, payload)) return true;
	if (!approvalId.includes("\n") && !toolCallId.includes("\n") && !toolName.includes("\n")) {
		const legacyPayload = buildLegacyPayload(approvalId, toolCallId, toolName, inputDigest);
		return crypto.subtle.verify("HMAC", key, sigBytes, legacyPayload);
	}
	return false;
}
//#endregion
//#region src/util/is-deep-equal-data.ts
/**
* Performs a deep-equal comparison of two parsed JSON objects.
*
* @param {any} obj1 - The first object to compare.
* @param {any} obj2 - The second object to compare.
* @returns {boolean} - Returns true if the two objects are deeply equal, false otherwise.
*/
function isDeepEqualData(obj1, obj2) {
	if (obj1 === obj2) return true;
	if (obj1 == null || obj2 == null) return false;
	if (typeof obj1 !== "object" && typeof obj2 !== "object") return obj1 === obj2;
	if (obj1.constructor !== obj2.constructor) return false;
	if (obj1 instanceof Date && obj2 instanceof Date) return obj1.getTime() === obj2.getTime();
	if (Array.isArray(obj1)) {
		if (obj1.length !== obj2.length) return false;
		for (let i = 0; i < obj1.length; i++) if (!isDeepEqualData(obj1[i], obj2[i])) return false;
		return true;
	}
	const keys1 = Object.keys(obj1);
	const keys2 = Object.keys(obj2);
	if (keys1.length !== keys2.length) return false;
	for (const key of keys1) {
		if (!keys2.includes(key)) return false;
		if (!isDeepEqualData(obj1[key], obj2[key])) return false;
	}
	return true;
}
//#endregion
//#region src/generate-text/resolve-tool-approval.ts
/**
* Resolves the approval state for a tool call by checking user-supplied and tool-defined
* approval settings, and normalizes the result to the object status shape.
* User-defined approval settings take precedence over tool-defined settings.
* If no approval settings are provided, the tool call does not require approval.
*/
async function resolveToolApproval({ tools, toolCall, toolApproval, messages, toolsContext, runtimeContext }) {
	if (toolApproval != null && typeof toolApproval === "function") return normalizeToolApprovalStatus(await toolApproval({
		toolCall,
		tools,
		toolsContext,
		messages,
		runtimeContext
	}));
	const toolName = toolCall.toolName;
	const tool = getOwn(tools, toolName);
	const input = toolCall.input;
	const userDefinedToolApprovalStatus = getOwn(toolApproval, toolName);
	if (userDefinedToolApprovalStatus != null) return normalizeToolApprovalStatus(typeof userDefinedToolApprovalStatus === "function" ? await userDefinedToolApprovalStatus(input, {
		toolCallId: toolCall.toolCallId,
		messages,
		toolContext: await validateToolContext({
			toolName,
			context: getOwn(toolsContext, toolName),
			contextSchema: tool?.contextSchema
		}),
		runtimeContext
	}) : userDefinedToolApprovalStatus);
	if (tool?.needsApproval == null) return { type: "not-applicable" };
	return (typeof tool.needsApproval === "function" ? await tool.needsApproval(input, {
		toolCallId: toolCall.toolCallId,
		messages,
		context: await validateToolContext({
			toolName,
			context: getOwn(toolsContext, toolName),
			contextSchema: tool?.contextSchema
		})
	}) : tool.needsApproval) ? { type: "user-approval" } : { type: "not-applicable" };
}
function normalizeToolApprovalStatus(status) {
	return status === void 0 ? { type: "not-applicable" } : typeof status === "string" ? { type: status } : status;
}
//#endregion
//#region src/generate-text/validate-tool-approvals.ts
/**
* Re-validates approved tool approvals reconstructed from client-supplied
* message history before they are executed. Checks HMAC signature (when
* configured), input schema, and approval policy.
*/
async function validateApprovedToolApprovals({ approvedToolApprovals, tools, toolApproval, messages, toolsContext, runtimeContext, toolApprovalSecret, refineToolInput }) {
	const approved = [];
	const denied = [];
	const invalid = [];
	for (const collectedApproval of approvedToolApprovals) {
		const tool = getOwn(tools, collectedApproval.toolCall.toolName);
		const { toolMetadata: _toolMetadata, dynamic: _dynamic, ...toolCallFromHistory } = collectedApproval.toolCall;
		const approval = {
			...collectedApproval,
			toolCall: {
				...toolCallFromHistory,
				...tool?.metadata != null ? { toolMetadata: tool.metadata } : {},
				...tool?.type === "dynamic" ? { dynamic: true } : {},
				title: tool?.title
			}
		};
		const { approvalRequest, toolCall } = approval;
		if (toolApprovalSecret != null) {
			if (approvalRequest.signature == null) throw new InvalidToolApprovalSignatureError({
				approvalId: approvalRequest.approvalId,
				toolCallId: toolCall.toolCallId,
				reason: "missing signature"
			});
			if (!await verifyToolApprovalSignature({
				secret: toolApprovalSecret,
				signature: approvalRequest.signature,
				approvalId: approvalRequest.approvalId,
				toolCallId: toolCall.toolCallId,
				toolName: toolCall.toolName,
				input: toolCall.input
			})) throw new InvalidToolApprovalSignatureError({
				approvalId: approvalRequest.approvalId,
				toolCallId: toolCall.toolCallId,
				reason: "invalid signature"
			});
		}
		if (isExecutableTool(tool) && tool.inputSchema != null) {
			let validationError;
			try {
				const approvedInput = structuredClone(toolCall.input);
				const hasInputSchemaInput = Object.prototype.hasOwnProperty.call(approvalRequest, "inputSchemaInput");
				const validation = await safeValidateTypes({
					value: structuredClone(hasInputSchemaInput ? approvalRequest.inputSchemaInput : toolCall.input),
					schema: asSchema(tool.inputSchema)
				});
				if (!validation.success) validationError = validation.error;
				else {
					const revalidatedToolCall = await refineParsedToolCallInput({
						toolCall: {
							...toolCall,
							input: validation.value
						},
						refineToolInput
					});
					if (!isDeepEqualData(structuredClone(revalidatedToolCall.input), approvedInput)) validationError = /* @__PURE__ */ new Error("Approved tool input does not match the validated schema output.");
				}
			} catch (error) {
				validationError = error;
			}
			if (validationError != null) {
				invalid.push({
					...approval,
					error: new InvalidToolInputError({
						toolName: toolCall.toolName,
						toolInput: JSON.stringify(toolCall.input),
						cause: validationError
					})
				});
				continue;
			}
		}
		const approvalStatus = await resolveToolApproval({
			tools,
			toolApproval,
			toolCall,
			messages,
			toolsContext,
			runtimeContext
		});
		if (approvalStatus.type === "denied") denied.push({
			...approval,
			approvalResponse: {
				...approval.approvalResponse,
				approved: false,
				reason: approvalStatus.reason ?? approval.approvalResponse.reason
			}
		});
		else approved.push(approval);
	}
	return {
		approvedToolApprovals: approved,
		deniedToolApprovals: denied,
		invalidToolApprovals: invalid
	};
}
//#endregion
//#region src/generate-text/to-response-messages.ts
/**
* Converts the result of a `generateText` or `streamText` call to a list of response messages.
*/
async function toResponseMessages({ content: inputContent, tools }) {
	const responseMessages = [];
	const toolCallOrder = /* @__PURE__ */ new Map();
	const content = [];
	for (const part of inputContent) {
		if (part.type === "source") continue;
		if ((part.type === "tool-result" || part.type === "tool-error") && !part.providerExecuted) continue;
		if (part.type === "text" && part.text.length === 0 && part.providerMetadata == null) continue;
		switch (part.type) {
			case "text":
				content.push({
					type: "text",
					text: part.text,
					providerOptions: part.providerMetadata
				});
				break;
			case "custom":
				content.push({
					type: "custom",
					kind: part.kind,
					providerOptions: part.providerMetadata
				});
				break;
			case "reasoning":
				content.push({
					type: "reasoning",
					text: part.text,
					providerOptions: part.providerMetadata
				});
				break;
			case "file":
				content.push({
					type: "file",
					data: part.file.base64,
					mediaType: part.file.mediaType,
					providerOptions: part.providerMetadata
				});
				break;
			case "reasoning-file":
				content.push({
					type: "reasoning-file",
					data: part.file.base64,
					mediaType: part.file.mediaType,
					providerOptions: part.providerMetadata
				});
				break;
			case "tool-call":
				if (!toolCallOrder.has(part.toolCallId)) toolCallOrder.set(part.toolCallId, toolCallOrder.size);
				content.push({
					type: "tool-call",
					toolCallId: part.toolCallId,
					toolName: part.toolName,
					input: part.invalid && typeof part.input !== "object" ? {} : part.input,
					providerExecuted: part.providerExecuted,
					providerOptions: part.providerMetadata
				});
				break;
			case "tool-result": {
				const output = await createToolModelOutput({
					toolCallId: part.toolCallId,
					input: part.input,
					tool: getOwn(tools, part.toolName),
					output: part.output,
					errorMode: "none"
				});
				content.push({
					type: "tool-result",
					toolCallId: part.toolCallId,
					toolName: part.toolName,
					output,
					providerOptions: part.providerMetadata
				});
				break;
			}
			case "tool-error": {
				const output = await createToolModelOutput({
					toolCallId: part.toolCallId,
					input: part.input,
					tool: getOwn(tools, part.toolName),
					output: part.error,
					errorMode: "json"
				});
				content.push({
					type: "tool-result",
					toolCallId: part.toolCallId,
					toolName: part.toolName,
					output,
					providerOptions: part.providerMetadata
				});
				break;
			}
			case "tool-approval-request":
				const inputSchemaInput = getToolCallInputSchemaInput(part.toolCall);
				content.push({
					type: "tool-approval-request",
					approvalId: part.approvalId,
					toolCallId: part.toolCall.toolCallId,
					...part.reason != null ? { reason: part.reason } : {},
					isAutomatic: part.isAutomatic,
					...part.signature != null ? { signature: part.signature } : {},
					...inputSchemaInput != null && !isDeepEqualData(inputSchemaInput.value, part.toolCall.input) ? { inputSchemaInput: inputSchemaInput.value } : {}
				});
		}
	}
	if (content.length > 0) responseMessages.push({
		role: "assistant",
		content
	});
	const toolResultContent = [];
	for (const part of inputContent) {
		if (part.type !== "tool-approval-response" && part.type !== "tool-result" && part.type !== "tool-error") continue;
		if (part.type === "tool-approval-response") {
			toolResultContent.push({
				type: "tool-approval-response",
				approvalId: part.approvalId,
				approved: part.approved,
				reason: part.reason,
				providerExecuted: part.providerExecuted
			});
			if (part.approved === false) toolResultContent.push({
				type: "tool-result",
				toolCallId: part.toolCall.toolCallId,
				toolName: part.toolCall.toolName,
				output: {
					type: "execution-denied",
					reason: part.reason
				}
			});
			continue;
		}
		if (part.providerExecuted) continue;
		const output = await createToolModelOutput({
			toolCallId: part.toolCallId,
			input: part.input,
			tool: getOwn(tools, part.toolName),
			output: part.type === "tool-result" ? part.output : part.error,
			errorMode: part.type === "tool-error" ? "text" : "none"
		});
		toolResultContent.push({
			type: "tool-result",
			toolCallId: part.toolCallId,
			toolName: part.toolName,
			output,
			...part.providerMetadata != null ? { providerOptions: part.providerMetadata } : {}
		});
	}
	if (toolResultContent.length > 0) responseMessages.push({
		role: "tool",
		content: sortToolResultContentByToolCallOrder({
			toolResultContent,
			toolCallOrder
		})
	});
	return responseMessages;
}
function sortToolResultContentByToolCallOrder({ toolResultContent, toolCallOrder }) {
	const sortedToolResults = toolResultContent.filter((part) => part.type === "tool-result").map((part, index) => ({
		part,
		index
	})).sort((a, b) => {
		const aOrder = toolCallOrder.get(a.part.toolCallId);
		const bOrder = toolCallOrder.get(b.part.toolCallId);
		if (aOrder == null && bOrder == null) return a.index - b.index;
		if (aOrder == null) return 1;
		if (bOrder == null) return -1;
		return aOrder - bOrder || a.index - b.index;
	}).map(({ part }) => part);
	let toolResultIndex = 0;
	return toolResultContent.map((part) => part.type === "tool-result" ? sortedToolResults[toolResultIndex++] : part);
}
//#endregion
//#region src/generate-text/default-generate-text-result.ts
var DefaultGenerateTextResult = class {
	constructor(options) {
		this.initialResponseMessages = options.initialResponseMessages;
		this.steps = options.steps;
		this._output = options.output;
		this.totalUsage = options.totalUsage;
	}
	get finalStep() {
		return this.steps.at(-1);
	}
	get content() {
		return this.steps.flatMap((step) => step.content);
	}
	get text() {
		return this.finalStep.text;
	}
	get files() {
		return this.steps.flatMap((step) => step.files);
	}
	get reasoningText() {
		return this.finalStep.reasoningText;
	}
	get reasoning() {
		return convertToReasoningOutputs(this.finalStep.reasoning);
	}
	get toolCalls() {
		return this.steps.flatMap((step) => step.toolCalls);
	}
	get staticToolCalls() {
		return this.steps.flatMap((step) => step.staticToolCalls);
	}
	get dynamicToolCalls() {
		return this.steps.flatMap((step) => step.dynamicToolCalls);
	}
	get toolResults() {
		return this.steps.flatMap((step) => step.toolResults);
	}
	get staticToolResults() {
		return this.steps.flatMap((step) => step.staticToolResults);
	}
	get dynamicToolResults() {
		return this.steps.flatMap((step) => step.dynamicToolResults);
	}
	get sources() {
		return this.steps.flatMap((step) => step.sources);
	}
	get finishReason() {
		return this.finalStep.finishReason;
	}
	get rawFinishReason() {
		return this.finalStep.rawFinishReason;
	}
	get warnings() {
		return this.steps.flatMap((step) => step.warnings ?? []);
	}
	get providerMetadata() {
		return this.finalStep.providerMetadata;
	}
	get response() {
		return this.finalStep.response;
	}
	get responseMessages() {
		return [...this.initialResponseMessages, ...this.steps.flatMap((step) => step.response.messages)];
	}
	get request() {
		return this.finalStep.request;
	}
	get usage() {
		return this.totalUsage;
	}
	get output() {
		if (this._output == null) throw new NoOutputGeneratedError();
		return this._output;
	}
};
//#endregion
//#region src/generate-text/resolve-generated-file-data.ts
async function resolveGeneratedFileData({ data, download: download$1, abortSignal, cache }) {
	if (data.type === "data") return data.data;
	const cachedData = cache?.get(data);
	if (cachedData != null) return cachedData;
	const downloadedData = download$1 == null ? (await download({
		url: data.url,
		abortSignal
	})).data : await downloadGeneratedFile({
		url: data.url,
		download: download$1,
		abortSignal
	});
	cache?.set(data, downloadedData);
	return downloadedData;
}
async function downloadGeneratedFile({ url, download, abortSignal }) {
	const [result] = await download([{
		url,
		isUrlSupportedByModel: false,
		abortSignal
	}]);
	if (result == null) throw new DownloadError({
		url: url.toString(),
		message: `Generated file URL ${url} must be downloaded, but the download function returned null`
	});
	return result.data;
}
//#endregion
//#region src/generate-text/convert-language-model-content.ts
async function convertLanguageModelContent({ content, toolCalls, toolOutputs, toolApprovalRequests, toolApprovalResponses, tools, download, abortSignal, generatedFileDataCache }) {
	const contentParts = [];
	const toolOutputsWithApprovalResponses = [];
	const toolOutputsWithoutApprovalResponses = [];
	const toolCallIdsWithApprovalResponses = new Set(toolApprovalResponses.map((toolApprovalResponse) => toolApprovalResponse.toolCall.toolCallId));
	for (const part of content) switch (part.type) {
		case "text":
		case "reasoning":
		case "custom":
		case "source":
			contentParts.push(part);
			break;
		case "file":
		case "reasoning-file":
			contentParts.push({
				type: part.type,
				file: new DefaultGeneratedFile({
					data: await resolveGeneratedFileData({
						data: part.data,
						download,
						abortSignal,
						cache: generatedFileDataCache
					}),
					mediaType: part.mediaType
				}),
				...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {}
			});
			break;
		case "tool-call": {
			const toolCall = toolCalls.find((toolCall) => toolCall.toolCallId === part.toolCallId);
			if (toolCall == null) throw new Error(`Tool call ${part.toolCallId} not found.`);
			contentParts.push(toolCall);
			break;
		}
		case "tool-result": {
			const toolCall = toolCalls.find((toolCall) => toolCall.toolCallId === part.toolCallId);
			if (toolCall == null) {
				const tool = getOwn(tools, part.toolName);
				if (!(tool?.type === "provider" && tool.supportsDeferredResults)) throw new Error(`Tool call ${part.toolCallId} not found.`);
				if (part.isError) contentParts.push({
					type: "tool-error",
					toolCallId: part.toolCallId,
					toolName: part.toolName,
					input: void 0,
					error: part.result,
					providerExecuted: true,
					dynamic: part.dynamic,
					...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {},
					...tool?.metadata != null ? { toolMetadata: tool.metadata } : {}
				});
				else contentParts.push({
					type: "tool-result",
					toolCallId: part.toolCallId,
					toolName: part.toolName,
					input: void 0,
					output: part.result,
					providerExecuted: true,
					dynamic: part.dynamic,
					...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {},
					...tool?.metadata != null ? { toolMetadata: tool.metadata } : {}
				});
				break;
			}
			if (part.isError) contentParts.push({
				type: "tool-error",
				toolCallId: part.toolCallId,
				toolName: part.toolName,
				input: toolCall.input,
				error: part.result,
				providerExecuted: true,
				dynamic: toolCall.dynamic,
				...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {},
				...toolCall.toolMetadata != null ? { toolMetadata: toolCall.toolMetadata } : {}
			});
			else contentParts.push({
				type: "tool-result",
				toolCallId: part.toolCallId,
				toolName: part.toolName,
				input: toolCall.input,
				output: part.result,
				providerExecuted: true,
				dynamic: toolCall.dynamic,
				...part.providerMetadata != null ? { providerMetadata: part.providerMetadata } : {},
				...toolCall.toolMetadata != null ? { toolMetadata: toolCall.toolMetadata } : {}
			});
			break;
		}
		case "tool-approval-request": {
			const toolCall = toolCalls.find((toolCall) => toolCall.toolCallId === part.toolCallId);
			if (toolCall == null) throw new ToolCallNotFoundForApprovalError({
				toolCallId: part.toolCallId,
				approvalId: part.approvalId
			});
			contentParts.push({
				type: "tool-approval-request",
				approvalId: part.approvalId,
				toolCall
			});
			break;
		}
	}
	for (const toolOutput of toolOutputs) if (toolCallIdsWithApprovalResponses.has(toolOutput.toolCallId)) toolOutputsWithApprovalResponses.push(toolOutput);
	else toolOutputsWithoutApprovalResponses.push(toolOutput);
	return [
		...contentParts,
		...toolOutputsWithoutApprovalResponses,
		...toolApprovalRequests,
		...toolApprovalResponses,
		...toolOutputsWithApprovalResponses
	];
}
//#endregion
//#region src/generate-text/calculate-tokens-per-second.ts
/**
* Calculates a token rate in tokens per second.
*
* Returns 0 when the token count is unknown, the duration is unknown or 0, or
* the computed rate cannot be represented as a finite JSON-safe number.
*/
function calculateTokensPerSecond({ tokens, durationMs }) {
	const tokenRate = 1e3 * (tokens ?? 0) / (durationMs ?? 0);
	return Number.isFinite(tokenRate) ? tokenRate : 0;
}
//#endregion
//#region src/generate-text/tool-call-concurrency.ts
/**
* Validates the maximum number of tool calls that may execute concurrently.
*/
function prepareToolCallConcurrency(toolCallConcurrency) {
	if (toolCallConcurrency == null) return;
	if (!Number.isInteger(toolCallConcurrency)) throw new InvalidArgumentError({
		parameter: "toolCallConcurrency",
		value: toolCallConcurrency,
		message: "toolCallConcurrency must be an integer"
	});
	if (toolCallConcurrency < 1) throw new InvalidArgumentError({
		parameter: "toolCallConcurrency",
		value: toolCallConcurrency,
		message: "toolCallConcurrency must be >= 1"
	});
	return toolCallConcurrency;
}
/**
* Maps items with an optional concurrency limit while preserving result order.
*
* Workers claim items in input order. When the signal is aborted or an
* execution rejects, no additional queued items are started.
*/
async function mapWithConcurrency({ items, concurrency, abortSignal, execute }) {
	if (concurrency == null || concurrency >= items.length) return Promise.all(items.map(execute));
	const results = new Array(items.length);
	let nextIndex = 0;
	let stopped = false;
	const worker = async () => {
		while (!stopped) {
			abortSignal?.throwIfAborted();
			const index = nextIndex++;
			if (index >= items.length) return;
			try {
				results[index] = await execute(items[index], index);
			} catch (error) {
				stopped = true;
				throw error;
			}
		}
	};
	await Promise.all(Array.from({ length: Math.min(concurrency, items.length) }, worker));
	return results;
}
//#endregion
export { DefaultGenerateTextResult, DefaultStepResult, addLanguageModelUsage, asLanguageModelUsage, calculateTokensPerSecond, collectToolApprovals, convertAsyncIteratorToReadableStream, convertLanguageModelContent, convertToLanguageModelPrompt, createAsyncIterableStream, createDefaultDownloadFunction, createNullLanguageModelUsage, createRestrictedTelemetryDispatcher, createTelemetryDispatcher, createToolModelOutput, createToolSearchState, downloadAssets, filterIncludedContext, isOutputChunk, logDefaultStopConditionWarning, logWarnings, mapToolResultOutput, mapWithConcurrency, mergeAbortSignals, mergeCallbacks, mergeObjects, parseToolCall, prepareLanguageModelCallOptions as prepareCallSettings, prepareLanguageModelCallOptions, prepareRetries, prepareToolCallConcurrency, prepareToolChoice, prepareTools, resolveLanguageModel, resolveToolApproval, setAbortTimeout, signToolApproval, standardizePrompt, toResponseMessages, validateApprovedToolApprovals, validateToolContext, verifyToolApprovalSignature };

//# sourceMappingURL=index.js.map