UNPKG

@ai-sdk/openai

Version:

The **[OpenAI provider](https://ai-sdk.dev/providers/ai-sdk-providers/openai)** for the [AI SDK](https://ai-sdk.dev/docs) contains language model support for the OpenAI chat and completion APIs and embedding model support for the OpenAI embeddings API.

1,406 lines (1,385 loc) 115 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/internal/index.ts var internal_exports = {}; __export(internal_exports, { OpenAIChatLanguageModel: () => OpenAIChatLanguageModel, OpenAICompletionLanguageModel: () => OpenAICompletionLanguageModel, OpenAIEmbeddingModel: () => OpenAIEmbeddingModel, OpenAIImageModel: () => OpenAIImageModel, OpenAIResponsesLanguageModel: () => OpenAIResponsesLanguageModel, OpenAISpeechModel: () => OpenAISpeechModel, OpenAITranscriptionModel: () => OpenAITranscriptionModel, hasDefaultResponseFormat: () => hasDefaultResponseFormat, modelMaxImagesPerCall: () => modelMaxImagesPerCall, openAITranscriptionProviderOptions: () => openAITranscriptionProviderOptions, openaiCompletionProviderOptions: () => openaiCompletionProviderOptions, openaiEmbeddingProviderOptions: () => openaiEmbeddingProviderOptions, openaiProviderOptions: () => openaiProviderOptions }); module.exports = __toCommonJS(internal_exports); // src/openai-chat-language-model.ts var import_provider3 = require("@ai-sdk/provider"); var import_provider_utils5 = require("@ai-sdk/provider-utils"); var import_v45 = require("zod/v4"); // src/convert-to-openai-chat-messages.ts var import_provider = require("@ai-sdk/provider"); var import_provider_utils = require("@ai-sdk/provider-utils"); function convertToOpenAIChatMessages({ prompt, systemMessageMode = "system" }) { const messages = []; const warnings = []; for (const { role, content } of prompt) { switch (role) { case "system": { switch (systemMessageMode) { case "system": { messages.push({ role: "system", content }); break; } case "developer": { messages.push({ role: "developer", content }); break; } case "remove": { warnings.push({ type: "other", message: "system messages are removed for this model" }); break; } default: { const _exhaustiveCheck = systemMessageMode; throw new Error( `Unsupported system message mode: ${_exhaustiveCheck}` ); } } break; } case "user": { if (content.length === 1 && content[0].type === "text") { messages.push({ role: "user", content: content[0].text }); break; } messages.push({ role: "user", content: content.map((part, index) => { var _a, _b, _c; switch (part.type) { case "text": { return { type: "text", text: part.text }; } case "file": { if (part.mediaType.startsWith("image/")) { const mediaType = part.mediaType === "image/*" ? "image/jpeg" : part.mediaType; return { type: "image_url", image_url: { url: part.data instanceof URL ? part.data.toString() : `data:${mediaType};base64,${(0, import_provider_utils.convertToBase64)(part.data)}`, // OpenAI specific extension: image detail detail: (_b = (_a = part.providerOptions) == null ? void 0 : _a.openai) == null ? void 0 : _b.imageDetail } }; } else if (part.mediaType.startsWith("audio/")) { if (part.data instanceof URL) { throw new import_provider.UnsupportedFunctionalityError({ functionality: "audio file parts with URLs" }); } switch (part.mediaType) { case "audio/wav": { return { type: "input_audio", input_audio: { data: (0, import_provider_utils.convertToBase64)(part.data), format: "wav" } }; } case "audio/mp3": case "audio/mpeg": { return { type: "input_audio", input_audio: { data: (0, import_provider_utils.convertToBase64)(part.data), format: "mp3" } }; } default: { throw new import_provider.UnsupportedFunctionalityError({ functionality: `audio content parts with media type ${part.mediaType}` }); } } } else if (part.mediaType === "application/pdf") { if (part.data instanceof URL) { throw new import_provider.UnsupportedFunctionalityError({ functionality: "PDF file parts with URLs" }); } return { type: "file", file: { filename: (_c = part.filename) != null ? _c : `part-${index}.pdf`, file_data: `data:application/pdf;base64,${(0, import_provider_utils.convertToBase64)(part.data)}` } }; } else { throw new import_provider.UnsupportedFunctionalityError({ functionality: `file part media type ${part.mediaType}` }); } } } }) }); break; } case "assistant": { let text = ""; const toolCalls = []; for (const part of content) { switch (part.type) { case "text": { text += part.text; break; } case "tool-call": { toolCalls.push({ id: part.toolCallId, type: "function", function: { name: part.toolName, arguments: JSON.stringify(part.input) } }); break; } } } messages.push({ role: "assistant", content: text, tool_calls: toolCalls.length > 0 ? toolCalls : void 0 }); break; } case "tool": { for (const toolResponse of content) { const output = toolResponse.output; let contentValue; switch (output.type) { case "text": case "error-text": contentValue = output.value; break; case "content": case "json": case "error-json": contentValue = JSON.stringify(output.value); break; } messages.push({ role: "tool", tool_call_id: toolResponse.toolCallId, content: contentValue }); } break; } default: { const _exhaustiveCheck = role; throw new Error(`Unsupported role: ${_exhaustiveCheck}`); } } } return { messages, warnings }; } // src/get-response-metadata.ts function getResponseMetadata({ id, model, created }) { return { id: id != null ? id : void 0, modelId: model != null ? model : void 0, timestamp: created != null ? new Date(created * 1e3) : void 0 }; } // src/map-openai-finish-reason.ts function mapOpenAIFinishReason(finishReason) { switch (finishReason) { case "stop": return "stop"; case "length": return "length"; case "content_filter": return "content-filter"; case "function_call": case "tool_calls": return "tool-calls"; default: return "unknown"; } } // src/openai-chat-options.ts var import_v4 = require("zod/v4"); var openaiProviderOptions = import_v4.z.object({ /** * Modify the likelihood of specified tokens appearing in the completion. * * Accepts a JSON object that maps tokens (specified by their token ID in * the GPT tokenizer) to an associated bias value from -100 to 100. */ logitBias: import_v4.z.record(import_v4.z.coerce.number(), import_v4.z.number()).optional(), /** * Return the log probabilities of the tokens. * * Setting to true will return the log probabilities of the tokens that * were generated. * * Setting to a number will return the log probabilities of the top n * tokens that were generated. */ logprobs: import_v4.z.union([import_v4.z.boolean(), import_v4.z.number()]).optional(), /** * Whether to enable parallel function calling during tool use. Default to true. */ parallelToolCalls: import_v4.z.boolean().optional(), /** * A unique identifier representing your end-user, which can help OpenAI to * monitor and detect abuse. */ user: import_v4.z.string().optional(), /** * Reasoning effort for reasoning models. Defaults to `medium`. */ reasoningEffort: import_v4.z.enum(["low", "medium", "high"]).optional(), /** * Maximum number of completion tokens to generate. Useful for reasoning models. */ maxCompletionTokens: import_v4.z.number().optional(), /** * Whether to enable persistence in responses API. */ store: import_v4.z.boolean().optional(), /** * Metadata to associate with the request. */ metadata: import_v4.z.record(import_v4.z.string().max(64), import_v4.z.string().max(512)).optional(), /** * Parameters for prediction mode. */ prediction: import_v4.z.record(import_v4.z.string(), import_v4.z.any()).optional(), /** * Whether to use structured outputs. * * @default true */ structuredOutputs: import_v4.z.boolean().optional(), /** * Service tier for the request. * - 'auto': Default service tier * - 'flex': 50% cheaper processing at the cost of increased latency. Only available for o3 and o4-mini models. * - 'priority': Higher-speed processing with predictably low latency at premium cost. Available for Enterprise customers. * * @default 'auto' */ serviceTier: import_v4.z.enum(["auto", "flex", "priority"]).optional(), /** * Whether to use strict JSON schema validation. * * @default false */ strictJsonSchema: import_v4.z.boolean().optional() }); // src/openai-error.ts var import_v42 = require("zod/v4"); var import_provider_utils2 = require("@ai-sdk/provider-utils"); var openaiErrorDataSchema = import_v42.z.object({ error: import_v42.z.object({ message: import_v42.z.string(), // The additional information below is handled loosely to support // OpenAI-compatible providers that have slightly different error // responses: type: import_v42.z.string().nullish(), param: import_v42.z.any().nullish(), code: import_v42.z.union([import_v42.z.string(), import_v42.z.number()]).nullish() }) }); var openaiFailedResponseHandler = (0, import_provider_utils2.createJsonErrorResponseHandler)({ errorSchema: openaiErrorDataSchema, errorToMessage: (data) => data.error.message }); // src/openai-prepare-tools.ts var import_provider2 = require("@ai-sdk/provider"); // src/tool/file-search.ts var import_provider_utils3 = require("@ai-sdk/provider-utils"); var import_v43 = require("zod/v4"); var comparisonFilterSchema = import_v43.z.object({ key: import_v43.z.string(), type: import_v43.z.enum(["eq", "ne", "gt", "gte", "lt", "lte"]), value: import_v43.z.union([import_v43.z.string(), import_v43.z.number(), import_v43.z.boolean()]) }); var compoundFilterSchema = import_v43.z.object({ type: import_v43.z.enum(["and", "or"]), filters: import_v43.z.array( import_v43.z.union([comparisonFilterSchema, import_v43.z.lazy(() => compoundFilterSchema)]) ) }); var filtersSchema = import_v43.z.union([comparisonFilterSchema, compoundFilterSchema]); var fileSearchArgsSchema = import_v43.z.object({ /** * List of vector store IDs to search through. If not provided, searches all available vector stores. */ vectorStoreIds: import_v43.z.array(import_v43.z.string()).optional(), /** * Maximum number of search results to return. Defaults to 10. */ maxNumResults: import_v43.z.number().optional(), /** * Ranking options for the search. */ ranking: import_v43.z.object({ ranker: import_v43.z.enum(["auto", "default-2024-08-21"]).optional() }).optional(), /** * A filter to apply based on file attributes. */ filters: filtersSchema.optional() }); var fileSearch = (0, import_provider_utils3.createProviderDefinedToolFactory)({ id: "openai.file_search", name: "file_search", inputSchema: import_v43.z.object({ query: import_v43.z.string() }) }); // src/tool/web-search-preview.ts var import_provider_utils4 = require("@ai-sdk/provider-utils"); var import_v44 = require("zod/v4"); var webSearchPreviewArgsSchema = import_v44.z.object({ /** * Search context size to use for the web search. * - high: Most comprehensive context, highest cost, slower response * - medium: Balanced context, cost, and latency (default) * - low: Least context, lowest cost, fastest response */ searchContextSize: import_v44.z.enum(["low", "medium", "high"]).optional(), /** * User location information to provide geographically relevant search results. */ userLocation: import_v44.z.object({ /** * Type of location (always 'approximate') */ type: import_v44.z.literal("approximate"), /** * Two-letter ISO country code (e.g., 'US', 'GB') */ country: import_v44.z.string().optional(), /** * City name (free text, e.g., 'Minneapolis') */ city: import_v44.z.string().optional(), /** * Region name (free text, e.g., 'Minnesota') */ region: import_v44.z.string().optional(), /** * IANA timezone (e.g., 'America/Chicago') */ timezone: import_v44.z.string().optional() }).optional() }); var webSearchPreview = (0, import_provider_utils4.createProviderDefinedToolFactory)({ id: "openai.web_search_preview", name: "web_search_preview", inputSchema: import_v44.z.object({}) }); // src/openai-prepare-tools.ts function prepareTools({ tools, toolChoice, structuredOutputs, strictJsonSchema }) { tools = (tools == null ? void 0 : tools.length) ? tools : void 0; const toolWarnings = []; if (tools == null) { return { tools: void 0, toolChoice: void 0, toolWarnings }; } const openaiTools = []; for (const tool of tools) { switch (tool.type) { case "function": openaiTools.push({ type: "function", function: { name: tool.name, description: tool.description, parameters: tool.inputSchema, strict: structuredOutputs ? strictJsonSchema : void 0 } }); break; case "provider-defined": switch (tool.id) { case "openai.file_search": { const args = fileSearchArgsSchema.parse(tool.args); openaiTools.push({ type: "file_search", vector_store_ids: args.vectorStoreIds, max_num_results: args.maxNumResults, ranking_options: args.ranking ? { ranker: args.ranking.ranker } : void 0, filters: args.filters }); break; } case "openai.web_search_preview": { const args = webSearchPreviewArgsSchema.parse(tool.args); openaiTools.push({ type: "web_search_preview", search_context_size: args.searchContextSize, user_location: args.userLocation }); break; } default: toolWarnings.push({ type: "unsupported-tool", tool }); break; } break; default: toolWarnings.push({ type: "unsupported-tool", tool }); break; } } if (toolChoice == null) { return { tools: openaiTools, toolChoice: void 0, toolWarnings }; } const type = toolChoice.type; switch (type) { case "auto": case "none": case "required": return { tools: openaiTools, toolChoice: type, toolWarnings }; case "tool": return { tools: openaiTools, toolChoice: { type: "function", function: { name: toolChoice.toolName } }, toolWarnings }; default: { const _exhaustiveCheck = type; throw new import_provider2.UnsupportedFunctionalityError({ functionality: `tool choice type: ${_exhaustiveCheck}` }); } } } // src/openai-chat-language-model.ts var OpenAIChatLanguageModel = class { constructor(modelId, config) { this.specificationVersion = "v2"; this.supportedUrls = { "image/*": [/^https?:\/\/.*$/] }; this.modelId = modelId; this.config = config; } get provider() { return this.config.provider; } async getArgs({ prompt, maxOutputTokens, temperature, topP, topK, frequencyPenalty, presencePenalty, stopSequences, responseFormat, seed, tools, toolChoice, providerOptions }) { var _a, _b, _c, _d; const warnings = []; const openaiOptions = (_a = await (0, import_provider_utils5.parseProviderOptions)({ provider: "openai", providerOptions, schema: openaiProviderOptions })) != null ? _a : {}; const structuredOutputs = (_b = openaiOptions.structuredOutputs) != null ? _b : true; if (topK != null) { warnings.push({ type: "unsupported-setting", setting: "topK" }); } if ((responseFormat == null ? void 0 : responseFormat.type) === "json" && responseFormat.schema != null && !structuredOutputs) { warnings.push({ type: "unsupported-setting", setting: "responseFormat", details: "JSON response format schema is only supported with structuredOutputs" }); } const { messages, warnings: messageWarnings } = convertToOpenAIChatMessages( { prompt, systemMessageMode: getSystemMessageMode(this.modelId) } ); warnings.push(...messageWarnings); const strictJsonSchema = (_c = openaiOptions.strictJsonSchema) != null ? _c : false; const baseArgs = { // model id: model: this.modelId, // model specific settings: logit_bias: openaiOptions.logitBias, logprobs: openaiOptions.logprobs === true || typeof openaiOptions.logprobs === "number" ? true : void 0, top_logprobs: typeof openaiOptions.logprobs === "number" ? openaiOptions.logprobs : typeof openaiOptions.logprobs === "boolean" ? openaiOptions.logprobs ? 0 : void 0 : void 0, user: openaiOptions.user, parallel_tool_calls: openaiOptions.parallelToolCalls, // standardized settings: max_tokens: maxOutputTokens, temperature, top_p: topP, frequency_penalty: frequencyPenalty, presence_penalty: presencePenalty, response_format: (responseFormat == null ? void 0 : responseFormat.type) === "json" ? structuredOutputs && responseFormat.schema != null ? { type: "json_schema", json_schema: { schema: responseFormat.schema, strict: strictJsonSchema, name: (_d = responseFormat.name) != null ? _d : "response", description: responseFormat.description } } : { type: "json_object" } : void 0, stop: stopSequences, seed, // openai specific settings: // TODO remove in next major version; we auto-map maxOutputTokens now max_completion_tokens: openaiOptions.maxCompletionTokens, store: openaiOptions.store, metadata: openaiOptions.metadata, prediction: openaiOptions.prediction, reasoning_effort: openaiOptions.reasoningEffort, service_tier: openaiOptions.serviceTier, // messages: messages }; if (isReasoningModel(this.modelId)) { if (baseArgs.temperature != null) { baseArgs.temperature = void 0; warnings.push({ type: "unsupported-setting", setting: "temperature", details: "temperature is not supported for reasoning models" }); } if (baseArgs.top_p != null) { baseArgs.top_p = void 0; warnings.push({ type: "unsupported-setting", setting: "topP", details: "topP is not supported for reasoning models" }); } if (baseArgs.frequency_penalty != null) { baseArgs.frequency_penalty = void 0; warnings.push({ type: "unsupported-setting", setting: "frequencyPenalty", details: "frequencyPenalty is not supported for reasoning models" }); } if (baseArgs.presence_penalty != null) { baseArgs.presence_penalty = void 0; warnings.push({ type: "unsupported-setting", setting: "presencePenalty", details: "presencePenalty is not supported for reasoning models" }); } if (baseArgs.logit_bias != null) { baseArgs.logit_bias = void 0; warnings.push({ type: "other", message: "logitBias is not supported for reasoning models" }); } if (baseArgs.logprobs != null) { baseArgs.logprobs = void 0; warnings.push({ type: "other", message: "logprobs is not supported for reasoning models" }); } if (baseArgs.top_logprobs != null) { baseArgs.top_logprobs = void 0; warnings.push({ type: "other", message: "topLogprobs is not supported for reasoning models" }); } if (baseArgs.max_tokens != null) { if (baseArgs.max_completion_tokens == null) { baseArgs.max_completion_tokens = baseArgs.max_tokens; } baseArgs.max_tokens = void 0; } } else if (this.modelId.startsWith("gpt-4o-search-preview") || this.modelId.startsWith("gpt-4o-mini-search-preview")) { if (baseArgs.temperature != null) { baseArgs.temperature = void 0; warnings.push({ type: "unsupported-setting", setting: "temperature", details: "temperature is not supported for the search preview models and has been removed." }); } } if (openaiOptions.serviceTier === "flex" && !supportsFlexProcessing(this.modelId)) { warnings.push({ type: "unsupported-setting", setting: "serviceTier", details: "flex processing is only available for o3 and o4-mini models" }); baseArgs.service_tier = void 0; } if (openaiOptions.serviceTier === "priority" && !supportsPriorityProcessing(this.modelId)) { warnings.push({ type: "unsupported-setting", setting: "serviceTier", details: "priority processing is only available for supported models (GPT-4, o3, o4-mini) and requires Enterprise access" }); baseArgs.service_tier = void 0; } const { tools: openaiTools, toolChoice: openaiToolChoice, toolWarnings } = prepareTools({ tools, toolChoice, structuredOutputs, strictJsonSchema }); return { args: { ...baseArgs, tools: openaiTools, tool_choice: openaiToolChoice }, warnings: [...warnings, ...toolWarnings] }; } async doGenerate(options) { var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n; const { args: body, warnings } = await this.getArgs(options); const { responseHeaders, value: response, rawValue: rawResponse } = await (0, import_provider_utils5.postJsonToApi)({ url: this.config.url({ path: "/chat/completions", modelId: this.modelId }), headers: (0, import_provider_utils5.combineHeaders)(this.config.headers(), options.headers), body, failedResponseHandler: openaiFailedResponseHandler, successfulResponseHandler: (0, import_provider_utils5.createJsonResponseHandler)( openaiChatResponseSchema ), abortSignal: options.abortSignal, fetch: this.config.fetch }); const choice = response.choices[0]; const content = []; const text = choice.message.content; if (text != null && text.length > 0) { content.push({ type: "text", text }); } for (const toolCall of (_a = choice.message.tool_calls) != null ? _a : []) { content.push({ type: "tool-call", toolCallId: (_b = toolCall.id) != null ? _b : (0, import_provider_utils5.generateId)(), toolName: toolCall.function.name, input: toolCall.function.arguments }); } for (const annotation of (_c = choice.message.annotations) != null ? _c : []) { content.push({ type: "source", sourceType: "url", id: (0, import_provider_utils5.generateId)(), url: annotation.url, title: annotation.title }); } const completionTokenDetails = (_d = response.usage) == null ? void 0 : _d.completion_tokens_details; const promptTokenDetails = (_e = response.usage) == null ? void 0 : _e.prompt_tokens_details; const providerMetadata = { openai: {} }; if ((completionTokenDetails == null ? void 0 : completionTokenDetails.accepted_prediction_tokens) != null) { providerMetadata.openai.acceptedPredictionTokens = completionTokenDetails == null ? void 0 : completionTokenDetails.accepted_prediction_tokens; } if ((completionTokenDetails == null ? void 0 : completionTokenDetails.rejected_prediction_tokens) != null) { providerMetadata.openai.rejectedPredictionTokens = completionTokenDetails == null ? void 0 : completionTokenDetails.rejected_prediction_tokens; } if (((_f = choice.logprobs) == null ? void 0 : _f.content) != null) { providerMetadata.openai.logprobs = choice.logprobs.content; } return { content, finishReason: mapOpenAIFinishReason(choice.finish_reason), usage: { inputTokens: (_h = (_g = response.usage) == null ? void 0 : _g.prompt_tokens) != null ? _h : void 0, outputTokens: (_j = (_i = response.usage) == null ? void 0 : _i.completion_tokens) != null ? _j : void 0, totalTokens: (_l = (_k = response.usage) == null ? void 0 : _k.total_tokens) != null ? _l : void 0, reasoningTokens: (_m = completionTokenDetails == null ? void 0 : completionTokenDetails.reasoning_tokens) != null ? _m : void 0, cachedInputTokens: (_n = promptTokenDetails == null ? void 0 : promptTokenDetails.cached_tokens) != null ? _n : void 0 }, request: { body }, response: { ...getResponseMetadata(response), headers: responseHeaders, body: rawResponse }, warnings, providerMetadata }; } async doStream(options) { const { args, warnings } = await this.getArgs(options); const body = { ...args, stream: true, stream_options: { include_usage: true } }; const { responseHeaders, value: response } = await (0, import_provider_utils5.postJsonToApi)({ url: this.config.url({ path: "/chat/completions", modelId: this.modelId }), headers: (0, import_provider_utils5.combineHeaders)(this.config.headers(), options.headers), body, failedResponseHandler: openaiFailedResponseHandler, successfulResponseHandler: (0, import_provider_utils5.createEventSourceResponseHandler)( openaiChatChunkSchema ), abortSignal: options.abortSignal, fetch: this.config.fetch }); const toolCalls = []; let finishReason = "unknown"; const usage = { inputTokens: void 0, outputTokens: void 0, totalTokens: void 0 }; let isFirstChunk = true; let isActiveText = false; const providerMetadata = { openai: {} }; return { stream: response.pipeThrough( new TransformStream({ start(controller) { controller.enqueue({ type: "stream-start", warnings }); }, transform(chunk, controller) { var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x; if (options.includeRawChunks) { controller.enqueue({ type: "raw", rawValue: chunk.rawValue }); } if (!chunk.success) { finishReason = "error"; controller.enqueue({ type: "error", error: chunk.error }); return; } const value = chunk.value; if ("error" in value) { finishReason = "error"; controller.enqueue({ type: "error", error: value.error }); return; } if (isFirstChunk) { isFirstChunk = false; controller.enqueue({ type: "response-metadata", ...getResponseMetadata(value) }); } if (value.usage != null) { usage.inputTokens = (_a = value.usage.prompt_tokens) != null ? _a : void 0; usage.outputTokens = (_b = value.usage.completion_tokens) != null ? _b : void 0; usage.totalTokens = (_c = value.usage.total_tokens) != null ? _c : void 0; usage.reasoningTokens = (_e = (_d = value.usage.completion_tokens_details) == null ? void 0 : _d.reasoning_tokens) != null ? _e : void 0; usage.cachedInputTokens = (_g = (_f = value.usage.prompt_tokens_details) == null ? void 0 : _f.cached_tokens) != null ? _g : void 0; if (((_h = value.usage.completion_tokens_details) == null ? void 0 : _h.accepted_prediction_tokens) != null) { providerMetadata.openai.acceptedPredictionTokens = (_i = value.usage.completion_tokens_details) == null ? void 0 : _i.accepted_prediction_tokens; } if (((_j = value.usage.completion_tokens_details) == null ? void 0 : _j.rejected_prediction_tokens) != null) { providerMetadata.openai.rejectedPredictionTokens = (_k = value.usage.completion_tokens_details) == null ? void 0 : _k.rejected_prediction_tokens; } } const choice = value.choices[0]; if ((choice == null ? void 0 : choice.finish_reason) != null) { finishReason = mapOpenAIFinishReason(choice.finish_reason); } if (((_l = choice == null ? void 0 : choice.logprobs) == null ? void 0 : _l.content) != null) { providerMetadata.openai.logprobs = choice.logprobs.content; } if ((choice == null ? void 0 : choice.delta) == null) { return; } const delta = choice.delta; if (delta.content != null) { if (!isActiveText) { controller.enqueue({ type: "text-start", id: "0" }); isActiveText = true; } controller.enqueue({ type: "text-delta", id: "0", delta: delta.content }); } if (delta.tool_calls != null) { for (const toolCallDelta of delta.tool_calls) { const index = toolCallDelta.index; if (toolCalls[index] == null) { if (toolCallDelta.type !== "function") { throw new import_provider3.InvalidResponseDataError({ data: toolCallDelta, message: `Expected 'function' type.` }); } if (toolCallDelta.id == null) { throw new import_provider3.InvalidResponseDataError({ data: toolCallDelta, message: `Expected 'id' to be a string.` }); } if (((_m = toolCallDelta.function) == null ? void 0 : _m.name) == null) { throw new import_provider3.InvalidResponseDataError({ data: toolCallDelta, message: `Expected 'function.name' to be a string.` }); } controller.enqueue({ type: "tool-input-start", id: toolCallDelta.id, toolName: toolCallDelta.function.name }); toolCalls[index] = { id: toolCallDelta.id, type: "function", function: { name: toolCallDelta.function.name, arguments: (_n = toolCallDelta.function.arguments) != null ? _n : "" }, hasFinished: false }; const toolCall2 = toolCalls[index]; if (((_o = toolCall2.function) == null ? void 0 : _o.name) != null && ((_p = toolCall2.function) == null ? void 0 : _p.arguments) != null) { if (toolCall2.function.arguments.length > 0) { controller.enqueue({ type: "tool-input-delta", id: toolCall2.id, delta: toolCall2.function.arguments }); } if ((0, import_provider_utils5.isParsableJson)(toolCall2.function.arguments)) { controller.enqueue({ type: "tool-input-end", id: toolCall2.id }); controller.enqueue({ type: "tool-call", toolCallId: (_q = toolCall2.id) != null ? _q : (0, import_provider_utils5.generateId)(), toolName: toolCall2.function.name, input: toolCall2.function.arguments }); toolCall2.hasFinished = true; } } continue; } const toolCall = toolCalls[index]; if (toolCall.hasFinished) { continue; } if (((_r = toolCallDelta.function) == null ? void 0 : _r.arguments) != null) { toolCall.function.arguments += (_t = (_s = toolCallDelta.function) == null ? void 0 : _s.arguments) != null ? _t : ""; } controller.enqueue({ type: "tool-input-delta", id: toolCall.id, delta: (_u = toolCallDelta.function.arguments) != null ? _u : "" }); if (((_v = toolCall.function) == null ? void 0 : _v.name) != null && ((_w = toolCall.function) == null ? void 0 : _w.arguments) != null && (0, import_provider_utils5.isParsableJson)(toolCall.function.arguments)) { controller.enqueue({ type: "tool-input-end", id: toolCall.id }); controller.enqueue({ type: "tool-call", toolCallId: (_x = toolCall.id) != null ? _x : (0, import_provider_utils5.generateId)(), toolName: toolCall.function.name, input: toolCall.function.arguments }); toolCall.hasFinished = true; } } } if (delta.annotations != null) { for (const annotation of delta.annotations) { controller.enqueue({ type: "source", sourceType: "url", id: (0, import_provider_utils5.generateId)(), url: annotation.url, title: annotation.title }); } } }, flush(controller) { if (isActiveText) { controller.enqueue({ type: "text-end", id: "0" }); } controller.enqueue({ type: "finish", finishReason, usage, ...providerMetadata != null ? { providerMetadata } : {} }); } }) ), request: { body }, response: { headers: responseHeaders } }; } }; var openaiTokenUsageSchema = import_v45.z.object({ prompt_tokens: import_v45.z.number().nullish(), completion_tokens: import_v45.z.number().nullish(), total_tokens: import_v45.z.number().nullish(), prompt_tokens_details: import_v45.z.object({ cached_tokens: import_v45.z.number().nullish() }).nullish(), completion_tokens_details: import_v45.z.object({ reasoning_tokens: import_v45.z.number().nullish(), accepted_prediction_tokens: import_v45.z.number().nullish(), rejected_prediction_tokens: import_v45.z.number().nullish() }).nullish() }).nullish(); var openaiChatResponseSchema = import_v45.z.object({ id: import_v45.z.string().nullish(), created: import_v45.z.number().nullish(), model: import_v45.z.string().nullish(), choices: import_v45.z.array( import_v45.z.object({ message: import_v45.z.object({ role: import_v45.z.literal("assistant").nullish(), content: import_v45.z.string().nullish(), tool_calls: import_v45.z.array( import_v45.z.object({ id: import_v45.z.string().nullish(), type: import_v45.z.literal("function"), function: import_v45.z.object({ name: import_v45.z.string(), arguments: import_v45.z.string() }) }) ).nullish(), annotations: import_v45.z.array( import_v45.z.object({ type: import_v45.z.literal("url_citation"), start_index: import_v45.z.number(), end_index: import_v45.z.number(), url: import_v45.z.string(), title: import_v45.z.string() }) ).nullish() }), index: import_v45.z.number(), logprobs: import_v45.z.object({ content: import_v45.z.array( import_v45.z.object({ token: import_v45.z.string(), logprob: import_v45.z.number(), top_logprobs: import_v45.z.array( import_v45.z.object({ token: import_v45.z.string(), logprob: import_v45.z.number() }) ) }) ).nullish() }).nullish(), finish_reason: import_v45.z.string().nullish() }) ), usage: openaiTokenUsageSchema }); var openaiChatChunkSchema = import_v45.z.union([ import_v45.z.object({ id: import_v45.z.string().nullish(), created: import_v45.z.number().nullish(), model: import_v45.z.string().nullish(), choices: import_v45.z.array( import_v45.z.object({ delta: import_v45.z.object({ role: import_v45.z.enum(["assistant"]).nullish(), content: import_v45.z.string().nullish(), tool_calls: import_v45.z.array( import_v45.z.object({ index: import_v45.z.number(), id: import_v45.z.string().nullish(), type: import_v45.z.literal("function").nullish(), function: import_v45.z.object({ name: import_v45.z.string().nullish(), arguments: import_v45.z.string().nullish() }) }) ).nullish(), annotations: import_v45.z.array( import_v45.z.object({ type: import_v45.z.literal("url_citation"), start_index: import_v45.z.number(), end_index: import_v45.z.number(), url: import_v45.z.string(), title: import_v45.z.string() }) ).nullish() }).nullish(), logprobs: import_v45.z.object({ content: import_v45.z.array( import_v45.z.object({ token: import_v45.z.string(), logprob: import_v45.z.number(), top_logprobs: import_v45.z.array( import_v45.z.object({ token: import_v45.z.string(), logprob: import_v45.z.number() }) ) }) ).nullish() }).nullish(), finish_reason: import_v45.z.string().nullish(), index: import_v45.z.number() }) ), usage: openaiTokenUsageSchema }), openaiErrorDataSchema ]); function isReasoningModel(modelId) { return modelId.startsWith("o"); } function supportsFlexProcessing(modelId) { return modelId.startsWith("o3") || modelId.startsWith("o4-mini"); } function supportsPriorityProcessing(modelId) { return modelId.startsWith("gpt-4") || modelId.startsWith("o3") || modelId.startsWith("o4-mini"); } function getSystemMessageMode(modelId) { var _a, _b; if (!isReasoningModel(modelId)) { return "system"; } return (_b = (_a = reasoningModels[modelId]) == null ? void 0 : _a.systemMessageMode) != null ? _b : "developer"; } var reasoningModels = { "o1-mini": { systemMessageMode: "remove" }, "o1-mini-2024-09-12": { systemMessageMode: "remove" }, "o1-preview": { systemMessageMode: "remove" }, "o1-preview-2024-09-12": { systemMessageMode: "remove" }, o3: { systemMessageMode: "developer" }, "o3-2025-04-16": { systemMessageMode: "developer" }, "o3-mini": { systemMessageMode: "developer" }, "o3-mini-2025-01-31": { systemMessageMode: "developer" }, "o4-mini": { systemMessageMode: "developer" }, "o4-mini-2025-04-16": { systemMessageMode: "developer" } }; // src/openai-completion-language-model.ts var import_provider_utils6 = require("@ai-sdk/provider-utils"); var import_v47 = require("zod/v4"); // src/convert-to-openai-completion-prompt.ts var import_provider4 = require("@ai-sdk/provider"); function convertToOpenAICompletionPrompt({ prompt, user = "user", assistant = "assistant" }) { let text = ""; if (prompt[0].role === "system") { text += `${prompt[0].content} `; prompt = prompt.slice(1); } for (const { role, content } of prompt) { switch (role) { case "system": { throw new import_provider4.InvalidPromptError({ message: "Unexpected system message in prompt: ${content}", prompt }); } case "user": { const userMessage = content.map((part) => { switch (part.type) { case "text": { return part.text; } } }).filter(Boolean).join(""); text += `${user}: ${userMessage} `; break; } case "assistant": { const assistantMessage = content.map((part) => { switch (part.type) { case "text": { return part.text; } case "tool-call": { throw new import_provider4.UnsupportedFunctionalityError({ functionality: "tool-call messages" }); } } }).join(""); text += `${assistant}: ${assistantMessage} `; break; } case "tool": { throw new import_provider4.UnsupportedFunctionalityError({ functionality: "tool messages" }); } default: { const _exhaustiveCheck = role; throw new Error(`Unsupported role: ${_exhaustiveCheck}`); } } } text += `${assistant}: `; return { prompt: text, stopSequences: [` ${user}:`] }; } // src/openai-completion-options.ts var import_v46 = require("zod/v4"); var openaiCompletionProviderOptions = import_v46.z.object({ /** Echo back the prompt in addition to the completion. */ echo: import_v46.z.boolean().optional(), /** Modify the likelihood of specified tokens appearing in the completion. Accepts a JSON object that maps tokens (specified by their token ID in the GPT tokenizer) to an associated bias value from -100 to 100. You can use this tokenizer tool to convert text to token IDs. Mathematically, the bias is added to the logits generated by the model prior to sampling. The exact effect will vary per model, but values between -1 and 1 should decrease or increase likelihood of selection; values like -100 or 100 should result in a ban or exclusive selection of the relevant token. As an example, you can pass {"50256": -100} to prevent the <|endoftext|> token from being generated. */ logitBias: import_v46.z.record(import_v46.z.string(), import_v46.z.number()).optional(), /** The suffix that comes after a completion of inserted text. */ suffix: import_v46.z.string().optional(), /** A unique identifier representing your end-user, which can help OpenAI to monitor and detect abuse. Learn more. */ user: import_v46.z.string().optional(), /** Return the log probabilities of the tokens. Including logprobs will increase the response size and can slow down response times. However, it can be useful to better understand how the model is behaving. Setting to true will return the log probabilities of the tokens that were generated. Setting to a number will return the log probabilities of the top n tokens that were generated. */ logprobs: import_v46.z.union([import_v46.z.boolean(), import_v46.z.number()]).optional() }); // src/openai-completion-language-model.ts var OpenAICompletionLanguageModel = class { constructor(modelId, config) { this.specificationVersion = "v2"; this.supportedUrls = { // No URLs are supported for completion models. }; this.modelId = modelId; this.config = config; } get providerOptionsName() { return this.config.provider.split(".")[0].trim(); } get provider() { return this.config.provider; } async getArgs({ prompt, maxOutputTokens, temperature, topP, topK, frequencyPenalty, presencePenalty, stopSequences: userStopSequences, responseFormat, tools, toolChoice, seed, providerOptions }) { const warnings = []; const openaiOptions = { ...await (0, import_provider_utils6.parseProviderOptions)({ provider: "openai", providerOptions, schema: openaiCompletionProviderOptions }), ...await (0, import_provider_utils6.parseProviderOptions)({ provider: this.providerOptionsName, providerOptions, schema: openaiCompletionProviderOptions }) }; if (topK != null) { warnings.push({ type: "unsupported-setting", setting: "topK" }); } if (tools == null ? void 0 : tools.length) { warnings.push({ type: "unsupported-setting", setting: "tools" }); } if (toolChoice != null) { warnings.push({ type: "unsupported-setting", setting: "toolChoice" }); } if (responseFormat != null && responseFormat.type !== "text") { warnings.push({ type: "unsupported-setting", setting: "responseFormat", details: "JSON response format is not supported." }); } const { prompt: completionPrompt, stopSequences } = convertToOpenAICompletionPrompt({ prompt }); const stop = [...stopSequences != null ? stopSequences : [], ...userStopSequences != null ? userStopSequences : []]; return { args: { // model id: model: this.modelId, // model specific settings: echo: openaiOptions.echo, logit_bias: openaiOptions.logitBias, logprobs: (openaiOptions == null ? void 0 : openaiOptions.logprobs) === true ? 0 : (openaiOptions == null ? void 0 : openaiOptions.logprobs) === false ? void 0 : openaiOptions == null ? void 0 : openaiOptions.logprobs, suffix: openaiOptions.suffix, user: openaiOptions.user, // standardized settings: max_tokens: maxOutputTokens, temperature, top_p: topP, frequency_penalty: frequencyPenalty, presence_penalty: presencePenalty, seed, // prompt: prompt: completionPrompt, // stop sequences: stop: stop.length > 0 ? stop : void 0 }, warnings }; } async doGenerate(options) { var _a, _b, _c; const { args, warnings } = await this.getArgs(options); const { responseHeaders, value: response, rawValue: rawResponse } = await (0, import_provider_utils6.postJsonToApi)({ url: this.config.url({ path: "/completions", modelId: this.modelId }), headers: (0, import_provider_utils6.combineHeaders)(this.config.headers(), options.headers), body: args, failedResponseHandler: openaiFailedResponseHandler, successfulResponseHandler: (0, import_provider_utils6.createJsonResponseHandler)( openaiCompletionResponseSchema ), abortSignal: options.abortSignal, fetch: this.config.fetch }); const choice = response.choices[0]; const providerMetadata = { openai: {} }; if (choice.logprobs != null) { providerMe