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.

1,649 lines (1,617 loc) • 107 kB
// internal/index.ts import { convertAsyncIteratorToReadableStream } from "@ai-sdk/provider-utils"; // src/util/async-iterable-stream.ts function createAsyncIterableStream(source) { return asAsyncIterableStream(source.pipeThrough(new TransformStream())); } function asAsyncIterableStream(stream) { stream[Symbol.asyncIterator] = function() { const reader = this.getReader(); let finished = false; async function cleanup(cancelStream) { var _a12; if (finished) return; finished = true; try { if (cancelStream) { await ((_a12 = reader.cancel) == null ? void 0 : _a12.call(reader)); } } finally { try { reader.releaseLock(); } catch (e) { } } } 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 }; } const { done, value } = await reader.read(); 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; } // src/prompt/convert-to-language-model-prompt.ts import { asArray, detectMediaType, isFullMediaType, isUrlSupported } from "@ai-sdk/provider-utils"; // src/util/download/download.ts import { cancelResponseBody, DownloadError, readResponseWithSizeLimit, DEFAULT_MAX_DOWNLOAD_SIZE, fetchWithValidatedRedirects, withUserAgentSuffix, getRuntimeEnvironmentUserAgent } from "@ai-sdk/provider-utils"; // src/version.ts var VERSION = true ? "7.0.22" : "0.0.0-test"; // src/util/download/download.ts var download = async ({ url, maxBytes, abortSignal }) => { var _a12; const urlText = url.toString(); try { const headers = withUserAgentSuffix( {}, `ai-sdk/${VERSION}`, getRuntimeEnvironmentUserAgent() ); const response = await fetchWithValidatedRedirects({ url: urlText, headers, abortSignal }); if (!response.ok) { await cancelResponseBody(response); throw new DownloadError({ url: urlText, statusCode: response.status, statusText: response.statusText }); } const data = await readResponseWithSizeLimit({ response, url: urlText, maxBytes: maxBytes != null ? maxBytes : DEFAULT_MAX_DOWNLOAD_SIZE }); return { data, mediaType: (_a12 = response.headers.get("content-type")) != null ? _a12 : void 0 }; } catch (error) { if (DownloadError.isInstance(error)) { throw error; } throw new DownloadError({ url: urlText, cause: error }); } }; // src/util/download/download-function.ts var createDefaultDownloadFunction = (download2 = download) => (requestedDownloads) => Promise.all( requestedDownloads.map( async (requestedDownload) => requestedDownload.isUrlSupportedByModel ? null : await download2(requestedDownload) ) ); // src/prompt/file-part-data.ts import { isBuffer, isProviderReference } from "@ai-sdk/provider-utils"; // src/prompt/invalid-data-content-error.ts import { AISDKError } from "@ai-sdk/provider"; var name = "AI_InvalidDataContentError"; var marker = `vercel.ai.error.${name}`; var symbol = Symbol.for(marker); var _a; 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, message, cause }); this[_a] = true; this.content = content; } static isInstance(error) { return AISDKError.hasMarker(error, marker); } }; _a = symbol; // src/prompt/split-data-url.ts function splitDataUrl(dataUrl) { try { const [header, base64Content] = dataUrl.split(","); return { mediaType: header.split(";")[0].split(":")[1], base64Content }; } catch (e) { return { mediaType: void 0, base64Content: void 0 }; } } // 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) { 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 }, mediaType: void 0 }; } function convertInlineDataToFilePartData(content) { if (content instanceof Uint8Array) { return { data: { type: "data", data: content }, mediaType: void 0 }; } if (content instanceof ArrayBuffer) { return { data: { type: "data", data: new Uint8Array(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 }; } 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); 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 convertUrlToFilePartData(new URL(content)); } catch (e) { return convertInlineDataToFilePartData(content); } } if (isProviderReference(content)) { return { data: { type: "reference", reference: content }, mediaType: void 0 }; } return convertInlineDataToFilePartData(content); } // src/logger/log-warnings.ts function formatWarning({ warning, provider, model }) { const scope = provider != null && model != null ? ` (${provider} / ${model})` : ""; const prefix = `AI SDK Warning${scope}:`; 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)}`; } } } var FIRST_WARNING_INFO_MESSAGE = "AI SDK Warning System: To turn off warning logging, set the AI_SDK_LOG_WARNINGS global to false."; var hasLoggedBefore = false; var 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; console.info(FIRST_WARNING_INFO_MESSAGE); } for (const warning of options.warnings) { const message = formatWarning({ warning, provider: options.provider, model: options.model }); if (typeof process !== "undefined" && typeof process.emitWarning === "function") { process.emitWarning(message, { type: warning.type === "deprecated" ? "DeprecationWarning" : "Warning" }); } else { console.warn(message); } } }; // src/prompt/invalid-message-role-error.ts import { AISDKError as AISDKError2 } from "@ai-sdk/provider"; var name2 = "AI_InvalidMessageRoleError"; var marker2 = `vercel.ai.error.${name2}`; var symbol2 = Symbol.for(marker2); var _a2; var InvalidMessageRoleError = class extends AISDKError2 { constructor({ role, message = `Invalid message role: '${role}'. Must be one of: "system", "user", "assistant", "tool".` }) { super({ name: name2, message }); this[_a2] = true; this.role = role; } static isInstance(error) { return AISDKError2.hasMarker(error, marker2); } }; _a2 = symbol2; // src/error/missing-tool-result-error.ts import { AISDKError as AISDKError3 } from "@ai-sdk/provider"; var name3 = "AI_MissingToolResultsError"; var marker3 = `vercel.ai.error.${name3}`; var symbol3 = Symbol.for(marker3); var _a3; var MissingToolResultsError = class extends AISDKError3 { constructor({ toolCallIds }) { super({ name: name3, message: `Tool result${toolCallIds.length > 1 ? "s are" : " is"} missing for tool call${toolCallIds.length > 1 ? "s" : ""} ${toolCallIds.join( ", " )}.` }); this[_a3] = true; this.toolCallIds = toolCallIds; } static isInstance(error) { return AISDKError3.hasMarker(error, marker3); } }; _a3 = symbol3; // src/prompt/convert-to-language-model-prompt.ts async function convertToLanguageModelPrompt({ prompt, supportedUrls, download: download2 = createDefaultDownloadFunction(), // `provider` is only needed here to convert legacy tool output types via `mapToolResultOutput`. // TODO: remove in v8 when "file-id" and "image-file-id" types are removed provider }) { const downloadedAssets = await downloadAssets( prompt.messages, download2, supportedUrls ); const approvalIdToToolCallId = /* @__PURE__ */ new Map(); for (const message of prompt.messages) { if (message.role === "assistant" && Array.isArray(message.content)) { for (const part of message.content) { if (part.type === "tool-approval-request" && "approvalId" in part && "toolCallId" in part) { approvalIdToToolCallId.set( part.approvalId, part.toolCallId ); } } } } const approvedToolCallIds = /* @__PURE__ */ new Set(); for (const message of prompt.messages) { if (message.role === "tool") { for (const part of message.content) { if (part.type === "tool-approval-response") { const toolCallId = approvalIdToToolCallId.get(part.approvalId); if (toolCallId) { approvedToolCallIds.add(toolCallId); } } } } } 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 == null ? void 0 : lastCombinedMessage.role) === "tool") { lastCombinedMessage.content.push(...message.content); } 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": for (const id of approvedToolCallIds) { toolCallIds.delete(id); } if (toolCallIds.size > 0) { throw new MissingToolResultsError({ toolCallIds: Array.from(toolCallIds) }); } break; } } for (const id of approvedToolCallIds) { toolCallIds.delete(id); } if (toolCallIds.size > 0) { throw new MissingToolResultsError({ toolCallIds: Array.from(toolCallIds) }); } return combinedMessages.filter( // Filter out empty tool messages (e.g. if they only contained // tool-approval-response parts that were removed). // This prevents sending invalid empty messages to the provider. // Note: provider-executed tool-approval-response parts are preserved. (message) => message.role !== "tool" || message.content.length > 0 ); } function convertToLanguageModelMessage({ message, downloadedAssets, // `provider` is only needed here to convert legacy tool output types via `mapToolResultOutput`. // TODO: remove in v8 when "file-id" and "image-file-id" types are removed 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( // remove empty text parts (no text, and no provider options): (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 != null ? 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 != null ? 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( // Only include tool-approval-response for provider-executed tools (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: { const _exhaustiveCheck = role; throw new InvalidMessageRoleError({ role: _exhaustiveCheck }); } } } function convertImagePartToFilePart(part) { var _a12; if (part.type !== "image") { return part; } return { type: "file", data: part.image, mediaType: (_a12 = part.mediaType) != null ? _a12 : "image", providerOptions: part.providerOptions }; } async function downloadAssets(messages, download2, supportedUrls) { 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) { if (contentPart.type === "file") { downloadableFiles.push(contentPart); } } } } 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) { if (contentPart.type === "file") { downloadableFiles.push(contentPart); } } } } } 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, isUrlSupportedByModel: part.mediaType != null && isUrlSupported({ url: part.data.url.toString(), mediaType: part.mediaType, supportedUrls }) })); const downloadedFiles = await download2(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) ); } 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 != null ? 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` is only needed here to convert legacy "file-id" and "image-file-id" types to provider references, in case they are using string ID values. // TODO: remove in v8 when "file-id" and "image-file-id" types are removed provider, warnings = [], downloadedAssets }) { if (output.type !== "content") { return output; } return { type: "content", value: output.value.map((item) => { var _a12; 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 = (_a12 = item.mediaType) != null ? _a12 : getMediaTypeFromUrl(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", data: { type: "url", url: new URL(item.url) }, 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": { 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", data: { type: "url", url: new URL(item.url) }, 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 }; } var 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") { var _a12; try { const pathname = new URL(url).pathname; const fileExtension = (_a12 = pathname.split(".").pop()) == null ? void 0 : _a12.toLowerCase(); if (fileExtension && Object.hasOwn(URL_EXTENSION_TO_MEDIA_TYPE, fileExtension)) { return URL_EXTENSION_TO_MEDIA_TYPE[fileExtension]; } } catch (e) { } return fallbackMediaType; } // src/prompt/create-tool-model-output.ts import { getErrorMessage } from "@ai-sdk/provider"; 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 == null ? void 0 : tool.toModelOutput) { return await tool.toModelOutput({ toolCallId, input, output }); } return typeof output === "string" ? { type: "text", value: output } : { type: "json", value: toJSONValue(output) }; } function toJSONValue(value) { return value === void 0 ? null : value; } // src/prompt/prepare-tool-choice.ts function prepareToolChoice({ toolChoice }) { return toolChoice == null ? { type: "auto" } : typeof toolChoice === "string" ? { type: toolChoice } : { type: "tool", toolName: toolChoice.toolName }; } // src/prompt/prepare-tools.ts import { asSchema } from "@ai-sdk/provider-utils"; // src/util/is-non-empty-object.ts function isNonEmptyObject(object) { return object != null && Object.keys(object).length > 0; } // src/prompt/prepare-tools.ts async function prepareTools({ tools, toolOrder, toolsContext = {}, experimental_sandbox: sandbox }) { if (!isNonEmptyObject(tools)) { return void 0; } const languageModelTools = []; for (const [name12, tool] of orderToolEntries({ tools, toolOrder })) { const toolType = tool.type; switch (toolType) { case void 0: case "dynamic": case "function": { const description = resolveToolDescription({ tool, toolName: name12, toolsContext, experimental_sandbox: sandbox }); const providerOptions = tool.providerOptions; const inputExamples = tool.inputExamples; const strict = tool.strict; languageModelTools.push({ type: "function", name: name12, 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: name12, id: tool.id, args: tool.args }); break; } default: { const exhaustiveCheck = toolType; throw new Error(`Unsupported tool type: ${exhaustiveCheck}`); } } } return languageModelTools; } function orderToolEntries({ tools, toolOrder }) { if (toolOrder == null) { return Object.entries(tools); } const toolEntries = Object.entries(tools); const orderedTools = toolEntries.filter(([name12]) => toolOrder.includes(name12)).sort( ([nameA], [nameB]) => toolOrder.indexOf(nameA) - toolOrder.indexOf(nameB) ); const unorderedTools = toolEntries.filter(([name12]) => !toolOrder.includes(name12)).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 }); } // src/prompt/standardize-prompt.ts import { InvalidPromptError } from "@ai-sdk/provider"; import { asArray as asArray2, safeValidateTypes } from "@ai-sdk/provider-utils"; import { z as z5 } from "zod/v4"; // src/prompt/message.ts import { z as z4 } from "zod/v4"; // src/types/provider-metadata.ts import { z as z2 } from "zod/v4"; // src/types/json-value.ts import { z } from "zod/v4"; var jsonValueSchema = z.lazy( () => z.union([ z.null(), z.string(), z.number(), z.boolean(), z.record(z.string(), jsonValueSchema.optional()), z.array(jsonValueSchema) ]) ); // src/types/provider-metadata.ts var providerMetadataSchema = z2.record( z2.string(), z2.record(z2.string(), jsonValueSchema.optional()) ); // src/prompt/content-part.ts import { isBuffer as isBuffer2 } from "@ai-sdk/provider-utils"; import { z as z3 } from "zod/v4"; var fileInlineDataSchema = z3.union([ z3.string(), z3.instanceof(Uint8Array), z3.instanceof(ArrayBuffer), z3.custom(isBuffer2, { message: "Must be a Buffer" }) ]); var providerReferenceSchema = z3.record(z3.string(), z3.string()); var textPartSchema = z3.object({ type: z3.literal("text"), text: z3.string(), providerOptions: providerMetadataSchema.optional() }); var imagePartSchema = z3.object({ type: z3.literal("image"), image: z3.union([ fileInlineDataSchema, z3.instanceof(URL), providerReferenceSchema ]), mediaType: z3.string().optional(), providerOptions: providerMetadataSchema.optional() }); var taggedFileDataSchema = z3.discriminatedUnion("type", [ z3.object({ type: z3.literal("data"), data: fileInlineDataSchema }), z3.object({ type: z3.literal("url"), url: z3.instanceof(URL) }), z3.object({ type: z3.literal("reference"), reference: providerReferenceSchema }), z3.object({ type: z3.literal("text"), text: z3.string() }) ]); var taggedReasoningFileDataSchema = z3.discriminatedUnion("type", [ z3.object({ type: z3.literal("data"), data: fileInlineDataSchema }), z3.object({ type: z3.literal("url"), url: z3.instanceof(URL) }) ]); var filePartSchema = z3.object({ type: z3.literal("file"), data: z3.union([ taggedFileDataSchema, fileInlineDataSchema, z3.instanceof(URL), providerReferenceSchema ]), filename: z3.string().optional(), mediaType: z3.string(), providerOptions: providerMetadataSchema.optional() }); var reasoningPartSchema = z3.object({ type: z3.literal("reasoning"), text: z3.string(), providerOptions: providerMetadataSchema.optional() }); var customPartSchema = z3.object({ type: z3.literal("custom"), kind: z3.string().transform((value) => value), providerOptions: providerMetadataSchema.optional() }); var reasoningFilePartSchema = z3.object({ type: z3.literal("reasoning-file"), data: z3.union([ taggedReasoningFileDataSchema, fileInlineDataSchema, z3.instanceof(URL) ]), mediaType: z3.string(), providerOptions: providerMetadataSchema.optional() }); var toolCallPartSchema = z3.object({ type: z3.literal("tool-call"), toolCallId: z3.string(), toolName: z3.string(), input: z3.unknown(), providerOptions: providerMetadataSchema.optional(), providerExecuted: z3.boolean().optional() }); var outputSchema = z3.discriminatedUnion( "type", [ z3.object({ type: z3.literal("text"), value: z3.string(), providerOptions: providerMetadataSchema.optional() }), z3.object({ type: z3.literal("json"), value: jsonValueSchema, providerOptions: providerMetadataSchema.optional() }), z3.object({ type: z3.literal("execution-denied"), reason: z3.string().optional(), providerOptions: providerMetadataSchema.optional() }), z3.object({ type: z3.literal("error-text"), value: z3.string(), providerOptions: providerMetadataSchema.optional() }), z3.object({ type: z3.literal("error-json"), value: jsonValueSchema, providerOptions: providerMetadataSchema.optional() }), z3.object({ type: z3.literal("content"), value: z3.array( z3.union([ z3.object({ type: z3.literal("text"), text: z3.string(), providerOptions: providerMetadataSchema.optional() }), z3.object({ type: z3.literal("file"), data: taggedFileDataSchema, mediaType: z3.string(), filename: z3.string().optional(), providerOptions: providerMetadataSchema.optional() }), z3.object({ // Deprecated. type: z3.literal("file-data"), data: z3.string(), mediaType: z3.string(), filename: z3.string().optional(), providerOptions: providerMetadataSchema.optional() }), z3.object({ // Deprecated. type: z3.literal("file-url"), url: z3.string(), mediaType: z3.string().optional(), providerOptions: providerMetadataSchema.optional() }), z3.object({ // Deprecated. type: z3.literal("file-id"), fileId: z3.union([z3.string(), z3.record(z3.string(), z3.string())]), providerOptions: providerMetadataSchema.optional() }), z3.object({ // Deprecated. type: z3.literal("file-reference"), providerReference: z3.record(z3.string(), z3.string()), providerOptions: providerMetadataSchema.optional() }), z3.object({ // Deprecated. type: z3.literal("image-data"), data: z3.string(), mediaType: z3.string(), providerOptions: providerMetadataSchema.optional() }), z3.object({ // Deprecated. type: z3.literal("image-url"), url: z3.string(), providerOptions: providerMetadataSchema.optional() }), z3.object({ // Deprecated. type: z3.literal("image-file-id"), fileId: z3.union([z3.string(), z3.record(z3.string(), z3.string())]), providerOptions: providerMetadataSchema.optional() }), z3.object({ // Deprecated. type: z3.literal("image-file-reference"), providerReference: z3.record(z3.string(), z3.string()), providerOptions: providerMetadataSchema.optional() }), z3.object({ type: z3.literal("custom"), providerOptions: providerMetadataSchema.optional() }) ]) ) }) ] ); var toolResultPartSchema = z3.object({ type: z3.literal("tool-result"), toolCallId: z3.string(), toolName: z3.string(), output: outputSchema, providerOptions: providerMetadataSchema.optional() }); var toolApprovalRequestSchema = z3.object({ type: z3.literal("tool-approval-request"), approvalId: z3.string(), toolCallId: z3.string() }); var toolApprovalResponseSchema = z3.object({ type: z3.literal("tool-approval-response"), approvalId: z3.string(), approved: z3.boolean(), reason: z3.string().optional() }); // src/prompt/message.ts var systemModelMessageSchema = z4.object( { role: z4.literal("system"), content: z4.string(), providerOptions: providerMetadataSchema.optional() } ); var userModelMessageSchema = z4.object({ role: z4.literal("user"), content: z4.union([ z4.string(), z4.array(z4.union([textPartSchema, imagePartSchema, filePartSchema])) ]), providerOptions: providerMetadataSchema.optional() }); var assistantModelMessageSchema = z4.object({ role: z4.literal("assistant"), content: z4.union([ z4.string(), z4.array( z4.union([ textPartSchema, customPartSchema, filePartSchema, reasoningPartSchema, reasoningFilePartSchema, toolCallPartSchema, toolResultPartSchema, toolApprovalRequestSchema ]) ) ]), providerOptions: providerMetadataSchema.optional() }); var toolModelMessageSchema = z4.object({ role: z4.literal("tool"), content: z4.array(z4.union([toolResultPartSchema, toolApprovalResponseSchema])), providerOptions: providerMetadataSchema.optional() }); var modelMessageSchema = z4.union([ systemModelMessageSchema, userModelMessageSchema, assistantModelMessageSchema, toolModelMessageSchema ]); // src/prompt/standardize-prompt.ts async function standardizePrompt({ allowSystemInMessages = false, system, instructions = system, prompt, messages }) { if (prompt == null && messages == null) { throw new InvalidPromptError({ prompt, message: "prompt or messages must be defined" }); } if (prompt != null && messages != null) { throw new InvalidPromptError({ prompt, message: "prompt and messages cannot be defined at the same time" }); } if (typeof instructions !== "string" && !asArray2(instructions).every((message) => message.role === "system")) { throw new InvalidPromptError({ prompt, message: "instructions must be a string, SystemModelMessage, or array of SystemModelMessage" }); } if (prompt != null && typeof prompt === "string") { messages = [{ role: "user", content: prompt }]; } else if (prompt != null && Array.isArray(prompt)) { messages = prompt; } else if (messages == null) { throw new InvalidPromptError({ prompt, message: "prompt or messages must be defined" }); } 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." }); } const validationResult = await safeValidateTypes({ value: messages, schema: z5.array(modelMessageSchema) }); if (!validationResult.success) { throw new InvalidPromptError({ prompt, message: "The messages do not match the ModelMessage[] schema.", cause: validationResult.error }); } return { messages, instructions }; } // src/error/invalid-argument-error.ts import { AISDKError as AISDKError4 } from "@ai-sdk/provider"; var name4 = "AI_InvalidArgumentError"; var marker4 = `vercel.ai.error.${name4}`; var symbol4 = Symbol.for(marker4); var _a4; var InvalidArgumentError = class extends AISDKError4 { constructor({ parameter, value, message }) { super({ name: name4, message: `Invalid argument for parameter ${parameter}: ${message}` }); this[_a4] = true; this.parameter = parameter; this.value = value; } static isInstance(error) { return AISDKError4.hasMarker(error, marker4); } }; _a4 = symbol4; // src/prompt/prepare-language-model-call-options.ts 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 (temperature != null) { if (typeof temperature !== "number") { throw new InvalidArgumentError({ parameter: "temperature", value: temperature, message: "temperature must be a number" }); } } if (topP != null) { if (typeof topP !== "number") { throw new InvalidArgumentError({ parameter: "topP", value: topP, message: "topP must be a number" }); } } if (topK != null) { if (typeof topK !== "number") { throw new InvalidArgumentError({ parameter: "topK", value: topK, message: "topK must be a number" }); } } if (presencePenalty != null) { if (typeof presencePenalty !== "number") { throw new InvalidArgumentError({ parameter: "presencePenalty", value: presencePenalty, message: "presencePenalty must be a number" }); } } if (frequencyPenalty != null) { if (typeof frequencyPenalty !== "number") { throw new InvalidArgumentError({ parameter: "frequencyPenalty", value: frequencyPenalty, message: "frequencyPenalty must be a number" }); } } 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 }; } // src/util/retry-with-exponential-backoff.ts import { APICallError } from "@ai-sdk/provider"; import { GatewayError } from "@ai-sdk/gateway"; import { retryWithExponentialBackoff } from "@ai-sdk/provider-utils"; // src/util/retry-error.ts import { AISDKError as AISDKError5 } from "@ai-sdk/provider"; var name5 = "AI_RetryError"; var marker5 = `vercel.ai.error.${name5}`; var symbol5 = Symbol.for(marker5); var _a5; var RetryError = class extends AISDKError5 { constructor({ message, reason, errors }) { super({ name: name5, message }); this[_a5] = true; this.reason = reason; this.errors = errors; this.lastError = errors[errors.length - 1]; } static isInstance(error) { return AISDKError5.hasMarker(error, marker5); } }; _a5 = symbol5; // 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 < 60 * 1e3 || ms < exponentialBackoffDelay)) { retu