@ai-sdk/openai 4.0.104 → 4.0.106

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/CHANGELOG.md +34 -0
  2. package/dist/index.d.ts +50 -9
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +651 -185
  5. package/dist/index.js.map +1 -1
  6. package/dist/internal/index.d.ts +4 -4
  7. package/dist/internal/index.d.ts.map +1 -1
  8. package/dist/internal/index.js +573 -142
  9. package/dist/internal/index.js.map +1 -1
  10. package/docs/03-openai.mdx +101 -9
  11. package/package.json +3 -3
  12. package/src/chat/openai-chat-language-model.ts +50 -28
  13. package/src/completion/openai-completion-language-model.ts +11 -3
  14. package/src/embedding/openai-embedding-model.ts +2 -1
  15. package/src/files/openai-files.ts +10 -8
  16. package/src/image/openai-image-model-options.ts +10 -20
  17. package/src/image/openai-image-model.ts +10 -21
  18. package/src/live/openai-realtime-model-live.ts +15 -16
  19. package/src/openai-batch.ts +22 -6
  20. package/src/openai-config.ts +2 -1
  21. package/src/openai-decision-model-options.ts +1 -0
  22. package/src/openai-decision-model.ts +48 -6
  23. package/src/openai-model-catalog.ts +935 -0
  24. package/src/openai-provider.ts +18 -13
  25. package/src/realtime/openai-realtime-factory.ts +6 -6
  26. package/src/realtime/openai-realtime-model.ts +7 -3
  27. package/src/resolve-openai-reasoning-effort.ts +45 -0
  28. package/src/responses/openai-responses-language-model.ts +35 -36
  29. package/src/skills/openai-skills.ts +4 -2
  30. package/src/speech/openai-speech-model.ts +5 -1
  31. package/src/speech-translation/openai-speech-translation-model.ts +5 -1
  32. package/src/transcription/openai-transcription-model.ts +25 -56
  33. package/src/openai-language-model-capabilities.ts +0 -101
@@ -1,5 +1,5 @@
1
1
  import { APICallError, InvalidPromptError, InvalidResponseDataError, TooManyEmbeddingValuesForCallError, UnsupportedFunctionalityError, isJSONObject } from "@ai-sdk/provider";
2
- import { EXPERIMENTAL_EMBEDDING_MODEL_MAX_INPUT_BYTES_PER_CALL, StreamingToolCallTracker, WORKFLOW_DESERIALIZE, WORKFLOW_SERIALIZE, combineHeaders, connectToWebSocket, convertBase64ToUint8Array, convertToBase64, convertToFormData, createBinaryResponseHandler, createEventSourceResponseHandler, createJsonErrorResponseHandler, createJsonResponseHandler, createLanguageModelResponseMetadata, createLanguageModelResponseMetadata as getResponseMetadata, createNullLanguageModelUsage, createProviderDefinedToolFactory, createProviderDefinedToolFactoryWithOutputSchema, createProviderExecutedToolFactory, createProviderStreamError, createToolNameMapping, downloadBlob, experimental_toolCaller, generateId, getTopLevelMediaType, isCustomReasoning, isNonNullable, isRecord, lazySchema, mediaTypeToExtension, parseJSON, parseProviderOptions, postFormDataToApi, postJsonToApi, resolveFullMediaType, resolveProviderReference, safeParseJSON, safeValidateTypes, serializeModelOptions, toWebSocketUrl, validateTypes, waitForWebSocketBufferDrain, zodSchema } from "@ai-sdk/provider-utils";
2
+ import { EXPERIMENTAL_EMBEDDING_MODEL_MAX_INPUT_BYTES_PER_CALL, StreamingToolCallTracker, WORKFLOW_DESERIALIZE, WORKFLOW_SERIALIZE, combineHeaders, connectToWebSocket, convertBase64ToUint8Array, convertToBase64, convertToFormData, createBinaryResponseHandler, createEventSourceResponseHandler, createJsonErrorResponseHandler, createJsonResponseHandler, createLanguageModelResponseMetadata, createLanguageModelResponseMetadata as getResponseMetadata, createNullLanguageModelUsage, createProviderDefinedToolFactory, createProviderDefinedToolFactoryWithOutputSchema, createProviderExecutedToolFactory, createProviderStreamError, createToolNameMapping, downloadBlob, experimental_toolCaller, generateId, getTopLevelMediaType, isCustomReasoning, isNonNullable, isRecord, lazySchema, mapReasoningToProviderEffort, mediaTypeToExtension, parseJSON, parseProviderOptions, postFormDataToApi, postJsonToApi, resolve, resolveFullMediaType, resolveProviderReference, safeParseJSON, safeValidateTypes, serializeModelOptions, toWebSocketUrl, validateTypes, waitForWebSocketBufferDrain, zodSchema } from "@ai-sdk/provider-utils";
3
3
  import { z } from "zod/v4";
4
4
  //#region src/openai-error.ts
5
5
  const openaiErrorDataSchema = () => z.object({ error: z.object({
@@ -14,55 +14,515 @@ const openaiFailedResponseHandler = createJsonErrorResponseHandler({
14
14
  errorToMessage: (data) => data.error.message
15
15
  });
16
16
  //#endregion
17
- //#region src/openai-language-model-capabilities.ts
18
- function getOpenAILanguageModelCapabilities(modelId) {
17
+ //#region src/openai-model-catalog.ts
18
+ /**
19
+ * Options accepted under `providerOptions.openai`. Language options are the
20
+ * Responses API options. The `satisfies` check keeps this list in sync with
21
+ * the option schema.
22
+ */
23
+ const openaiProviderOptions = { language: {
24
+ conversation: { description: "OpenAI Conversation ID to continue." },
25
+ include: { description: "Extra fields to include in the response." },
26
+ includeWebSearchSources: { description: "Include web search action sources." },
27
+ instructions: { description: "Instructions for the model." },
28
+ logprobs: { description: "Return token log probabilities." },
29
+ maxToolCalls: { description: "Maximum number of built-in tool calls." },
30
+ metadata: { description: "Metadata to store with the generation." },
31
+ parallelToolCalls: { description: "Whether to use parallel tool calls." },
32
+ previousResponseId: { description: "Previous response ID to continue." },
33
+ promptCacheKey: { description: "Cache key for prompt caching." },
34
+ promptCacheOptions: { description: "Prompt cache mode, TTL, and prewarm." },
35
+ promptCacheRetention: { description: "Prompt cache retention policy." },
36
+ reasoningEffort: { description: "Reasoning effort." },
37
+ reasoningEffortUpdate: { description: "Reasoning effort update from this response onward." },
38
+ reasoningMode: { description: "Standard or pro reasoning mode." },
39
+ reasoningContext: { description: "Which reasoning items can be used." },
40
+ reasoningSummary: { description: "Reasoning summary output." },
41
+ safetyIdentifier: { description: "Identifier for safety monitoring." },
42
+ serviceTier: { description: "Service tier for the request." },
43
+ store: { description: "Whether to store the generation." },
44
+ passThroughUnsupportedFiles: { description: "Send non-image file types as generic input files." },
45
+ strictJsonSchema: { description: "Use strict JSON schema validation." },
46
+ textVerbosity: { description: "Verbosity of text responses." },
47
+ truncation: { description: "Output truncation behavior." },
48
+ user: { description: "End-user identifier for abuse monitoring." },
49
+ systemMessageMode: { description: "System message role override." },
50
+ forceReasoning: { description: "Treat the model as a reasoning model." },
51
+ contextManagement: { description: "Server-side context compaction." },
52
+ compactionTrigger: { description: "Request explicit compaction." },
53
+ allowedTools: { description: "Restrict callable tools to a subset." }
54
+ } };
55
+ const configurableNonReasoning = { capabilities: { language: { reasoning: {
56
+ support: true,
57
+ efforts: [
58
+ "none",
59
+ "low",
60
+ "medium",
61
+ "high",
62
+ "xhigh",
63
+ "max"
64
+ ],
65
+ sampling: "reasoning-effort-none"
66
+ } } } };
67
+ const openaiLanguageModelEntries = Object.fromEntries(Object.entries({
68
+ "gpt-6-astra": {},
69
+ "gpt-6.1-sol": {},
70
+ "gpt-6.1-terra": configurableNonReasoning,
71
+ "gpt-6-luna": configurableNonReasoning,
72
+ "gpt-6-sol": configurableNonReasoning,
73
+ "gpt-5.6": {},
74
+ "gpt-5.6-luna": {},
75
+ "gpt-5.6-sol": {},
76
+ "gpt-5.6-terra": {},
77
+ "gpt-5.5": {},
78
+ "gpt-5.4-pro": {},
79
+ "gpt-5.4": {},
80
+ "gpt-5.4-mini": {},
81
+ "gpt-5.4-nano": {},
82
+ "gpt-5.3-chat-latest": {},
83
+ "gpt-5.2-pro": {},
84
+ "gpt-5.2-chat-latest": {},
85
+ "gpt-5.2": {},
86
+ "gpt-5.1-codex-mini": {},
87
+ "gpt-5.1-codex": {},
88
+ "gpt-5.1-chat-latest": {},
89
+ "gpt-5.1": {},
90
+ "gpt-5-pro": {},
91
+ "gpt-5": {},
92
+ "gpt-5-mini": {},
93
+ "gpt-5-nano": {},
94
+ "gpt-5-codex": {},
95
+ "gpt-5-chat-latest": { capabilities: { language: {
96
+ objectGeneration: false,
97
+ tools: {
98
+ usage: false,
99
+ streaming: false,
100
+ async: false
101
+ }
102
+ } } },
103
+ "gpt-4.1": {},
104
+ "gpt-4.1-mini": {},
105
+ "gpt-4.1-nano": {},
106
+ "gpt-4o": {},
107
+ "gpt-4o-mini": {}
108
+ }).map(([modelId, definition]) => [modelId, createOpenAILanguageModelEntry(modelId, definition)]));
109
+ function createOpenAILanguageModelEntry(modelId, definition) {
19
110
  const oSeriesVersion = getOSeriesVersion(modelId);
20
111
  const gptVersion = getGptVersion(modelId);
112
+ const isRecognizedModelFamily = oSeriesVersion != null || gptVersion != null || /^gpt-4o(?:-|$)/.test(modelId);
21
113
  const isGptChatModel = gptVersion?.minor == null && (gptVersion?.variant?.startsWith("chat") ?? false);
22
114
  const isGptNanoModel = gptVersion?.variant?.startsWith("nano") ?? false;
23
115
  const isGpt6OrLaterModel = gptVersion != null && gptVersion.major >= 6;
24
- const isGpt6OrLaterModelWithNoneEffort = modelId === "gpt-6-sol" || modelId === "gpt-6-luna" || modelId === "gpt-6.1-terra";
116
+ const isGpt56OrLaterModel = isGpt6OrLaterModel || gptVersion?.major === 5 && (gptVersion.minor ?? 0) >= 6;
117
+ const isStandardGpt5Model = gptVersion?.major === 5 && (gptVersion.variant == null || /^(?:(?:mini|nano|sol|luna|terra)(?:-\d{4}-\d{2}-\d{2})?|\d{4}-\d{2}-\d{2})$/.test(gptVersion.variant));
25
118
  const supportsFlexProcessing = oSeriesVersion != null && oSeriesVersion >= 3 || gptVersion != null && gptVersion.major >= 5 && !isGptChatModel;
26
119
  const supportsPriorityProcessing = modelId.startsWith("gpt-4") || gptVersion != null && gptVersion.major >= 5 && !isGptNanoModel && !isGptChatModel || oSeriesVersion != null && oSeriesVersion >= 3;
27
120
  const isReasoningModel = oSeriesVersion != null || gptVersion != null && gptVersion.major >= 5 && !isGptChatModel;
28
- const supportsNonReasoningParameters = isGpt6OrLaterModelWithNoneEffort || !isGpt6OrLaterModel && gptVersion != null && (gptVersion.major > 5 || gptVersion.major === 5 && (gptVersion.minor ?? 0) >= 1);
121
+ const reasoningSampling = definition?.capabilities?.language?.reasoning?.sampling ?? (!isGpt6OrLaterModel && gptVersion != null && (gptVersion.major > 5 || gptVersion.major === 5 && (gptVersion.minor ?? 0) >= 1) ? "reasoning-effort-none" : "unsupported");
122
+ const sampling = !isRecognizedModelFamily ? "unknown" : !isReasoningModel ? true : reasoningSampling === "reasoning-effort-none" ? { condition: "Only when reasoning effort is none." } : false;
123
+ const chatTemperatureSupportedWithoutReasoning = !modelId.startsWith("gpt-4o-search-preview") && !modelId.startsWith("gpt-4o-mini-search-preview");
124
+ const entry = {
125
+ capabilities: { language: {
126
+ inputs: definition?.capabilities?.language?.inputs ?? {
127
+ image: definition != null ? true : "unknown",
128
+ audio: definition != null ? false : "unknown"
129
+ },
130
+ objectGeneration: definition?.capabilities?.language?.objectGeneration ?? (definition != null ? true : "unknown"),
131
+ tools: definition?.capabilities?.language?.tools ?? {
132
+ usage: definition != null ? true : "unknown",
133
+ streaming: definition != null ? true : "unknown",
134
+ async: isGpt6OrLaterModel
135
+ },
136
+ reasoning: {
137
+ support: isRecognizedModelFamily ? isReasoningModel : "unknown",
138
+ efforts: definition?.capabilities?.language?.reasoning?.efforts ?? (isGpt6OrLaterModel ? [
139
+ "low",
140
+ "medium",
141
+ "high",
142
+ "xhigh",
143
+ "max"
144
+ ] : isStandardGpt5Model ? getGpt5ReasoningEfforts(gptVersion.minor ?? 0) : void 0),
145
+ sampling: reasoningSampling
146
+ },
147
+ sampling: {
148
+ temperature: chatTemperatureSupportedWithoutReasoning ? sampling : { condition: "Not supported by Chat Completions search preview models." },
149
+ topP: sampling,
150
+ logprobs: isReasoningModel && !isGpt6OrLaterModel ? { condition: reasoningSampling === "reasoning-effort-none" ? "Chat Completions requires reasoning effort none; Responses support is model-dependent." : "Not supported by Chat Completions while reasoning; Responses support is model-dependent." } : sampling
151
+ },
152
+ serviceTiers: {
153
+ flex: supportsFlexProcessing,
154
+ priority: supportsPriorityProcessing
155
+ },
156
+ configurationUpdates: isGpt6OrLaterModel,
157
+ promptCache: {
158
+ retention: !isGpt6OrLaterModel,
159
+ options: isRecognizedModelFamily ? isGpt56OrLaterModel : "unknown"
160
+ },
161
+ endpoints: {
162
+ chat: {
163
+ temperatureWithoutReasoning: chatTemperatureSupportedWithoutReasoning,
164
+ functionToolsWithReasoning: !(gptVersion?.major === 5 && (gptVersion.minor ?? 0) >= 6)
165
+ },
166
+ responses: { logprobsRequireNonReasoning: isGpt6OrLaterModel }
167
+ }
168
+ } },
169
+ requestConfig: { language: { systemMessageMode: definition?.requestConfig?.language?.systemMessageMode ?? (isReasoningModel ? "developer" : "system") } }
170
+ };
171
+ const { language } = entry.capabilities;
29
172
  return {
30
- supportsFlexProcessing,
31
- supportsPriorityProcessing,
32
- supportsConfigurationUpdate: isGpt6OrLaterModel,
33
- supportsAsyncToolCalling: isGpt6OrLaterModel,
34
- supportedReasoningEfforts: isGpt6OrLaterModelWithNoneEffort ? [
35
- "none",
36
- "low",
37
- "medium",
38
- "high",
39
- "xhigh",
40
- "max"
41
- ] : isGpt6OrLaterModel ? [
42
- "low",
43
- "medium",
44
- "high",
45
- "xhigh",
46
- "max"
47
- ] : void 0,
48
- isReasoningModel,
49
- systemMessageMode: isReasoningModel ? "developer" : "system",
50
- supportsNonReasoningParameters
173
+ ...entry,
174
+ providerOptions: { language: declareProviderOptions(openaiProviderOptions.language, definition != null ? true : "unknown", {
175
+ logprobs: language.sampling.logprobs,
176
+ maxToolCalls: language.tools.usage,
177
+ parallelToolCalls: language.tools.usage,
178
+ allowedTools: language.tools.usage,
179
+ reasoningEffort: language.reasoning.support,
180
+ reasoningSummary: language.reasoning.support,
181
+ reasoningMode: language.reasoning.support,
182
+ reasoningContext: language.reasoning.support,
183
+ reasoningEffortUpdate: language.configurationUpdates,
184
+ promptCacheOptions: language.promptCache.options,
185
+ promptCacheRetention: language.promptCache.retention
186
+ }) }
51
187
  };
52
188
  }
189
+ /** Applies one default support value to every option, except the listed ones. */
190
+ function declareProviderOptions(definitions, support, exceptions) {
191
+ return Object.fromEntries(Object.keys(definitions).map((option) => [option, exceptions[option] ?? support]));
192
+ }
193
+ function getGpt5ReasoningEfforts(minor) {
194
+ if (minor === 0) return [
195
+ "minimal",
196
+ "low",
197
+ "medium",
198
+ "high"
199
+ ];
200
+ if (minor === 1) return [
201
+ "none",
202
+ "low",
203
+ "medium",
204
+ "high"
205
+ ];
206
+ if (minor < 6) return [
207
+ "none",
208
+ "low",
209
+ "medium",
210
+ "high",
211
+ "xhigh"
212
+ ];
213
+ return [
214
+ "none",
215
+ "low",
216
+ "medium",
217
+ "high",
218
+ "xhigh",
219
+ "max"
220
+ ];
221
+ }
53
222
  function getOSeriesVersion(modelId) {
54
223
  const match = /^o(\d+)(?:-|$)/.exec(modelId);
55
224
  return match == null ? void 0 : Number(match[1]);
56
225
  }
57
226
  function getGptVersion(modelId) {
58
227
  const match = /^gpt-(\d+)(?:\.(\d+))?(?:-(.+))?$/.exec(modelId);
59
- if (match == null) return;
60
- return {
228
+ return match == null ? void 0 : {
61
229
  major: Number(match[1]),
62
230
  minor: match[2] == null ? void 0 : Number(match[2]),
63
231
  variant: match[3]
64
232
  };
65
233
  }
234
+ const openaiEmbeddingModelEntries = {
235
+ "text-embedding-3-large": { capabilities: { embedding: {
236
+ defaultDimensions: 3072,
237
+ customDimensions: true
238
+ } } },
239
+ "text-embedding-3-small": { capabilities: { embedding: {
240
+ defaultDimensions: 1536,
241
+ customDimensions: true
242
+ } } },
243
+ "text-embedding-ada-002": { capabilities: { embedding: {
244
+ defaultDimensions: 1536,
245
+ customDimensions: false
246
+ } } }
247
+ };
248
+ const gptImageSizes = [
249
+ "1024x1024",
250
+ "1536x1024",
251
+ "1024x1536"
252
+ ];
253
+ const customImageSizes = { description: "Standard presets and custom dimensions" };
254
+ function createGptImageEntry(sizes) {
255
+ return {
256
+ capabilities: { image: {
257
+ sizes,
258
+ fileInput: true,
259
+ maskInput: true,
260
+ maxImagesPerCall: 10
261
+ } },
262
+ requestConfig: { image: { responseFormat: "provider-default" } }
263
+ };
264
+ }
265
+ const openaiImageModelEntries = {
266
+ "gpt-image-2.5-flare": createGptImageEntry(customImageSizes),
267
+ "gpt-image-2.5-sunburst": createGptImageEntry(customImageSizes),
268
+ "gpt-image-2": createGptImageEntry(gptImageSizes),
269
+ "gpt-image-1.5": createGptImageEntry(gptImageSizes),
270
+ "gpt-image-1-mini": createGptImageEntry(gptImageSizes),
271
+ "gpt-image-1": createGptImageEntry(gptImageSizes),
272
+ "dall-e-3": {
273
+ capabilities: { image: {
274
+ sizes: [
275
+ "1024x1024",
276
+ "1792x1024",
277
+ "1024x1792"
278
+ ],
279
+ fileInput: false,
280
+ maskInput: false,
281
+ maxImagesPerCall: 1
282
+ } },
283
+ requestConfig: { image: { responseFormat: "b64_json" } }
284
+ },
285
+ "dall-e-2": {
286
+ capabilities: { image: {
287
+ sizes: [
288
+ "256x256",
289
+ "512x512",
290
+ "1024x1024"
291
+ ],
292
+ fileInput: true,
293
+ maskInput: true,
294
+ maxImagesPerCall: 10
295
+ } },
296
+ requestConfig: { image: { responseFormat: "b64_json" } }
297
+ }
298
+ };
299
+ const imageModelAliases = {
300
+ "gpt-image-2.5-flare-2026-09-08": openaiImageModelEntries["gpt-image-2.5-flare"],
301
+ "gpt-image-2.5-sunburst-2026-09-08": openaiImageModelEntries["gpt-image-2.5-sunburst"],
302
+ "chatgpt-image-latest": createGptImageEntry({ description: "Unknown" })
303
+ };
304
+ function resolveOpenAIImageModelEntry(modelId) {
305
+ if (Object.prototype.hasOwnProperty.call(openaiImageModelEntries, modelId)) return openaiImageModelEntries[modelId];
306
+ if (Object.prototype.hasOwnProperty.call(imageModelAliases, modelId)) return imageModelAliases[modelId];
307
+ return {
308
+ capabilities: { image: {
309
+ sizes: { description: "Unknown" },
310
+ fileInput: "unknown",
311
+ maskInput: "unknown",
312
+ maxImagesPerCall: modelId.startsWith("gpt-image-") ? 10 : 1
313
+ } },
314
+ requestConfig: { image: { responseFormat: modelId.startsWith("chatgpt-image-") || modelId.startsWith("gpt-image-") ? "provider-default" : "b64_json" } }
315
+ };
316
+ }
317
+ const openaiImageModelMaxImagesPerCall = Object.fromEntries(Object.entries({
318
+ ...openaiImageModelEntries,
319
+ ...imageModelAliases
320
+ }).map(([modelId, entry]) => [modelId, entry.capabilities.image.maxImagesPerCall ?? 1]));
321
+ const defaultTranscriptionRequestConfig = { languageField: "language" };
322
+ const openaiTranscriptionModelEntries = {
323
+ "whisper-1": {
324
+ capabilities: { transcription: {
325
+ transcription: true,
326
+ streaming: false,
327
+ streamingDelay: false,
328
+ duration: true,
329
+ segments: true,
330
+ language: true
331
+ } },
332
+ requestConfig: { transcription: {
333
+ ...defaultTranscriptionRequestConfig,
334
+ responseFormat: "verbose_json"
335
+ } }
336
+ },
337
+ "gpt-4o-mini-transcribe": {
338
+ capabilities: { transcription: {
339
+ transcription: true,
340
+ streaming: false,
341
+ streamingDelay: false,
342
+ duration: false,
343
+ segments: false,
344
+ language: false
345
+ } },
346
+ requestConfig: { transcription: defaultTranscriptionRequestConfig }
347
+ },
348
+ "gpt-4o-transcribe": {
349
+ capabilities: { transcription: {
350
+ transcription: true,
351
+ streaming: false,
352
+ streamingDelay: false,
353
+ duration: false,
354
+ segments: false,
355
+ language: false
356
+ } },
357
+ requestConfig: { transcription: defaultTranscriptionRequestConfig }
358
+ },
359
+ "gpt-4o-transcribe-diarize": {
360
+ capabilities: { transcription: {
361
+ transcription: true,
362
+ streaming: false,
363
+ streamingDelay: false,
364
+ duration: true,
365
+ segments: true,
366
+ language: false
367
+ } },
368
+ requestConfig: { transcription: {
369
+ ...defaultTranscriptionRequestConfig,
370
+ responseFormat: "diarized_json",
371
+ chunkingStrategy: "auto"
372
+ } }
373
+ },
374
+ "gpt-transcribe": {
375
+ capabilities: { transcription: {
376
+ transcription: true,
377
+ streaming: true,
378
+ streamingDelay: false,
379
+ duration: false,
380
+ segments: false,
381
+ language: true
382
+ } },
383
+ requestConfig: { transcription: { languageField: "languages" } }
384
+ },
385
+ "gpt-live-transcribe": {
386
+ capabilities: { transcription: {
387
+ transcription: false,
388
+ streaming: true,
389
+ streamingDelay: true,
390
+ duration: false,
391
+ segments: false,
392
+ language: false
393
+ } },
394
+ requestConfig: { transcription: { languageField: "languages" } }
395
+ },
396
+ "gpt-realtime-whisper": {
397
+ capabilities: { transcription: {
398
+ transcription: false,
399
+ streaming: true,
400
+ streamingDelay: true,
401
+ duration: false,
402
+ segments: false,
403
+ language: false
404
+ } },
405
+ requestConfig: { transcription: defaultTranscriptionRequestConfig }
406
+ }
407
+ };
408
+ const transcriptionSnapshotModelIds = [
409
+ "gpt-transcribe",
410
+ "gpt-live-transcribe",
411
+ "gpt-realtime-whisper"
412
+ ];
413
+ function resolveOpenAITranscriptionModelEntry(modelId) {
414
+ if (Object.prototype.hasOwnProperty.call(openaiTranscriptionModelEntries, modelId)) return openaiTranscriptionModelEntries[modelId];
415
+ for (const baseModelId of transcriptionSnapshotModelIds) if (modelId.startsWith(`${baseModelId}-`)) return openaiTranscriptionModelEntries[baseModelId];
416
+ return {
417
+ capabilities: { transcription: {
418
+ transcription: "unknown",
419
+ streaming: "unknown",
420
+ streamingDelay: "unknown",
421
+ duration: "unknown",
422
+ segments: "unknown",
423
+ language: "unknown"
424
+ } },
425
+ requestConfig: { transcription: defaultTranscriptionRequestConfig }
426
+ };
427
+ }
428
+ const openaiSpeechTranslationModelEntries = { "gpt-realtime-translate": { capabilities: { speechTranslation: {
429
+ translatedAudio: true,
430
+ translatedText: true,
431
+ sourceTranscript: true
432
+ } } } };
433
+ const openaiSpeechModelEntries = {
434
+ "tts-1": { capabilities: { speech: { instructions: false } } },
435
+ "tts-1-hd": { capabilities: { speech: { instructions: false } } },
436
+ "gpt-4o-mini-tts": { capabilities: { speech: { instructions: true } } }
437
+ };
438
+ const liveModelEntry = {
439
+ capabilities: { realtime: {
440
+ conversation: "continuous",
441
+ transports: ["websocket", "webrtc"],
442
+ connections: ["server-websocket", "webrtc"]
443
+ } },
444
+ requestConfig: { realtime: {
445
+ api: "live",
446
+ startup: "session-start",
447
+ finalization: "session-close"
448
+ } }
449
+ };
450
+ const realtimeModelEntries = {
451
+ "gpt-live-1": liveModelEntry,
452
+ "gpt-realtime": {
453
+ capabilities: { realtime: {
454
+ conversation: "turn-based",
455
+ transports: ["websocket"],
456
+ connections: ["client-secret-websocket"]
457
+ } },
458
+ requestConfig: { realtime: {
459
+ api: "realtime",
460
+ startup: "session-update",
461
+ finalization: "transport-close"
462
+ } }
463
+ }
464
+ };
465
+ ({ ...liveModelEntry.capabilities.realtime }), liveModelEntry.requestConfig.realtime.startup, liveModelEntry.requestConfig.realtime.finalization;
466
+ /**
467
+ * The catalog consumed by request builders and documentation. Source declarations
468
+ * are grouped by operation; entries for the same model combine their sections.
469
+ * An absent section is undeclared, not an instruction to reject a request.
470
+ */
471
+ const openaiModelCatalog = combineModelEntries([
472
+ openaiLanguageModelEntries,
473
+ openaiEmbeddingModelEntries,
474
+ openaiImageModelEntries,
475
+ openaiTranscriptionModelEntries,
476
+ openaiSpeechTranslationModelEntries,
477
+ openaiSpeechModelEntries,
478
+ realtimeModelEntries
479
+ ]);
480
+ function combineModelEntries(catalogs) {
481
+ const entries = /* @__PURE__ */ new Map();
482
+ for (const catalog of catalogs) for (const [modelId, entry] of Object.entries(catalog)) {
483
+ const previous = entries.get(modelId);
484
+ entries.set(modelId, {
485
+ capabilities: {
486
+ ...previous?.capabilities,
487
+ ...entry.capabilities
488
+ },
489
+ ...previous?.providerOptions != null || entry.providerOptions != null ? { providerOptions: {
490
+ ...previous?.providerOptions,
491
+ ...entry.providerOptions
492
+ } } : {},
493
+ ...previous?.requestConfig != null || entry.requestConfig != null ? { requestConfig: {
494
+ ...previous?.requestConfig,
495
+ ...entry.requestConfig
496
+ } } : {}
497
+ });
498
+ }
499
+ return Object.fromEntries(entries);
500
+ }
501
+ function findModelEntry(modelId) {
502
+ return Object.prototype.hasOwnProperty.call(openaiModelCatalog, modelId) ? openaiModelCatalog[modelId] : void 0;
503
+ }
504
+ function getOpenAILanguageModelEntry(modelId) {
505
+ const entry = findModelEntry(modelId);
506
+ return entry?.capabilities.language != null && entry.providerOptions?.language != null && entry.requestConfig?.language != null ? {
507
+ capabilities: { language: entry.capabilities.language },
508
+ providerOptions: { language: entry.providerOptions.language },
509
+ requestConfig: { language: entry.requestConfig.language }
510
+ } : createOpenAILanguageModelEntry(modelId);
511
+ }
512
+ function getOpenAIImageModelEntry(modelId) {
513
+ const entry = findModelEntry(modelId);
514
+ return entry?.capabilities.image != null && entry.requestConfig?.image != null ? {
515
+ capabilities: { image: entry.capabilities.image },
516
+ requestConfig: { image: entry.requestConfig.image }
517
+ } : resolveOpenAIImageModelEntry(modelId);
518
+ }
519
+ function getOpenAITranscriptionModelEntry(modelId) {
520
+ const entry = findModelEntry(modelId);
521
+ return entry?.capabilities.transcription != null && entry.requestConfig?.transcription != null ? {
522
+ capabilities: { transcription: entry.capabilities.transcription },
523
+ requestConfig: { transcription: entry.requestConfig.transcription }
524
+ } : resolveOpenAITranscriptionModelEntry(modelId);
525
+ }
66
526
  //#endregion
67
527
  //#region src/openai-stream-error.ts
68
528
  /**
@@ -212,6 +672,26 @@ function isRetryableStreamError(error, statusCode) {
212
672
  return isRetryableStatusCode(statusCode);
213
673
  }
214
674
  //#endregion
675
+ //#region src/resolve-openai-reasoning-effort.ts
676
+ const allOpenAIReasoningEfforts = [
677
+ "none",
678
+ "minimal",
679
+ "low",
680
+ "medium",
681
+ "high",
682
+ "xhigh",
683
+ "max"
684
+ ];
685
+ /** Resolve portable reasoning against the efforts declared by the catalog. */
686
+ function resolveOpenAIReasoningEffort({ providerReasoningEffort, reasoning, supportedReasoningEfforts, warnings }) {
687
+ return mapReasoningToProviderEffort({
688
+ reasoning,
689
+ providerOptionsEffort: providerReasoningEffort,
690
+ effortMap: Object.fromEntries((supportedReasoningEfforts ?? allOpenAIReasoningEfforts).map((effort) => [effort, effort])),
691
+ warnings
692
+ });
693
+ }
694
+ //#endregion
215
695
  //#region src/chat/convert-openai-chat-usage.ts
216
696
  function convertOpenAIChatUsage(usage) {
217
697
  if (usage == null) return createNullLanguageModelUsage();
@@ -934,17 +1414,20 @@ var OpenAIChatLanguageModel = class OpenAIChatLanguageModel {
934
1414
  providerOptions,
935
1415
  schema: openaiLanguageModelChatOptions
936
1416
  }) ?? {};
937
- const modelCapabilities = getOpenAILanguageModelCapabilities(this.modelId);
938
- let resolvedReasoningEffort = openaiOptions.reasoningEffort ?? (isCustomReasoning(reasoning) ? reasoning : void 0);
939
- if (resolvedReasoningEffort != null && modelCapabilities.supportedReasoningEfforts != null && !modelCapabilities.supportedReasoningEfforts.includes(resolvedReasoningEffort)) {
940
- warnings.push({
941
- type: "unsupported",
942
- feature: "reasoningEffort",
943
- details: `${this.modelId} only supports the following reasoning efforts: ${modelCapabilities.supportedReasoningEfforts.join(", ")}`
944
- });
945
- resolvedReasoningEffort = void 0;
946
- }
947
- const isReasoningModel = openaiOptions.forceReasoning ?? modelCapabilities.isReasoningModel;
1417
+ const { capabilities: { language: modelCapabilities }, requestConfig: { language: modelRequestConfig } } = getOpenAILanguageModelEntry(this.modelId);
1418
+ const requiresNoReasoningEffort = !modelCapabilities.endpoints.chat.functionToolsWithReasoning && openaiOptions.reasoningEffort == null && (tools?.some((tool) => tool.type === "function") ?? false);
1419
+ if (requiresNoReasoningEffort && isCustomReasoning(reasoning) && reasoning !== "none") warnings.push({
1420
+ type: "compatibility",
1421
+ feature: "reasoning",
1422
+ details: `${this.modelId} does not support function tools with reasoning in the Chat Completions API. reasoning effort set to "none". Use the Responses API to combine reasoning with function tools.`
1423
+ });
1424
+ const resolvedReasoningEffort = requiresNoReasoningEffort ? "none" : resolveOpenAIReasoningEffort({
1425
+ providerReasoningEffort: openaiOptions.reasoningEffort,
1426
+ reasoning,
1427
+ supportedReasoningEfforts: modelCapabilities.reasoning.efforts?.filter((effort) => effort !== "max"),
1428
+ warnings
1429
+ });
1430
+ const isReasoningModel = openaiOptions.forceReasoning ?? modelCapabilities.reasoning.support === true;
948
1431
  if (topK != null) warnings.push({
949
1432
  type: "unsupported",
950
1433
  feature: "topK"
@@ -956,7 +1439,7 @@ var OpenAIChatLanguageModel = class OpenAIChatLanguageModel {
956
1439
  });
957
1440
  const { messages, warnings: messageWarnings } = convertToOpenAIChatMessages({
958
1441
  prompt,
959
- systemMessageMode: openaiOptions.systemMessageMode ?? (isReasoningModel ? "developer" : modelCapabilities.systemMessageMode)
1442
+ systemMessageMode: openaiOptions.systemMessageMode ?? (isReasoningModel ? "developer" : modelRequestConfig.systemMessageMode)
960
1443
  });
961
1444
  warnings.push(...messageWarnings);
962
1445
  const strictJsonSchema = openaiOptions.strictJsonSchema ?? true;
@@ -998,7 +1481,7 @@ var OpenAIChatLanguageModel = class OpenAIChatLanguageModel {
998
1481
  safety_identifier: openaiOptions.safetyIdentifier,
999
1482
  messages
1000
1483
  };
1001
- if (modelCapabilities.supportedReasoningEfforts != null && baseArgs.prompt_cache_retention != null) {
1484
+ if (!modelCapabilities.promptCache.retention && baseArgs.prompt_cache_retention != null) {
1002
1485
  baseArgs.prompt_cache_retention = void 0;
1003
1486
  warnings.push({
1004
1487
  type: "unsupported",
@@ -1007,7 +1490,7 @@ var OpenAIChatLanguageModel = class OpenAIChatLanguageModel {
1007
1490
  });
1008
1491
  }
1009
1492
  if (isReasoningModel) {
1010
- if (resolvedReasoningEffort !== "none" || !modelCapabilities.supportsNonReasoningParameters) {
1493
+ if (resolvedReasoningEffort !== "none" || modelCapabilities.reasoning.sampling !== "reasoning-effort-none") {
1011
1494
  if (baseArgs.temperature != null) {
1012
1495
  baseArgs.temperature = void 0;
1013
1496
  warnings.push({
@@ -1066,7 +1549,7 @@ var OpenAIChatLanguageModel = class OpenAIChatLanguageModel {
1066
1549
  if (baseArgs.max_completion_tokens == null) baseArgs.max_completion_tokens = baseArgs.max_tokens;
1067
1550
  baseArgs.max_tokens = void 0;
1068
1551
  }
1069
- } else if (this.modelId.startsWith("gpt-4o-search-preview") || this.modelId.startsWith("gpt-4o-mini-search-preview")) {
1552
+ } else if (!modelCapabilities.endpoints.chat.temperatureWithoutReasoning) {
1070
1553
  if (baseArgs.temperature != null) {
1071
1554
  baseArgs.temperature = void 0;
1072
1555
  warnings.push({
@@ -1076,7 +1559,7 @@ var OpenAIChatLanguageModel = class OpenAIChatLanguageModel {
1076
1559
  });
1077
1560
  }
1078
1561
  }
1079
- if (openaiOptions.serviceTier === "flex" && !modelCapabilities.supportsFlexProcessing) {
1562
+ if (openaiOptions.serviceTier === "flex" && !modelCapabilities.serviceTiers.flex) {
1080
1563
  warnings.push({
1081
1564
  type: "unsupported",
1082
1565
  feature: "serviceTier",
@@ -1084,7 +1567,7 @@ var OpenAIChatLanguageModel = class OpenAIChatLanguageModel {
1084
1567
  });
1085
1568
  baseArgs.service_tier = void 0;
1086
1569
  }
1087
- if ((openaiOptions.serviceTier === "priority" || openaiOptions.serviceTier === "fast") && !modelCapabilities.supportsPriorityProcessing) {
1570
+ if ((openaiOptions.serviceTier === "priority" || openaiOptions.serviceTier === "fast") && !modelCapabilities.serviceTiers.priority) {
1088
1571
  warnings.push({
1089
1572
  type: "unsupported",
1090
1573
  feature: "serviceTier",
@@ -1112,7 +1595,7 @@ var OpenAIChatLanguageModel = class OpenAIChatLanguageModel {
1112
1595
  path: "/chat/completions",
1113
1596
  modelId: this.config.requestModelId ?? this.modelId
1114
1597
  }),
1115
- headers: combineHeaders(this.config.headers?.(), options.headers),
1598
+ headers: combineHeaders(await resolve(this.config.headers), options.headers),
1116
1599
  body,
1117
1600
  failedResponseHandler: openaiFailedResponseHandler,
1118
1601
  successfulResponseHandler: createJsonResponseHandler(openaiChatResponseSchema),
@@ -1178,7 +1661,7 @@ var OpenAIChatLanguageModel = class OpenAIChatLanguageModel {
1178
1661
  });
1179
1662
  const { responseHeaders, value: response } = await postJsonToApi({
1180
1663
  url,
1181
- headers: combineHeaders(this.config.headers?.(), options.headers),
1664
+ headers: combineHeaders(await resolve(this.config.headers), options.headers),
1182
1665
  body,
1183
1666
  failedResponseHandler: openaiFailedResponseHandler,
1184
1667
  successfulResponseHandler: createEventSourceResponseHandler(openaiChatChunkSchema),
@@ -1555,7 +2038,7 @@ var OpenAICompletionLanguageModel = class OpenAICompletionLanguageModel {
1555
2038
  path: "/completions",
1556
2039
  modelId: this.config.requestModelId ?? this.modelId
1557
2040
  }),
1558
- headers: combineHeaders(this.config.headers?.(), options.headers),
2041
+ headers: combineHeaders(await resolve(this.config.headers), options.headers),
1559
2042
  body: args,
1560
2043
  failedResponseHandler: openaiFailedResponseHandler,
1561
2044
  successfulResponseHandler: createJsonResponseHandler(openaiCompletionResponseSchema),
@@ -1598,7 +2081,7 @@ var OpenAICompletionLanguageModel = class OpenAICompletionLanguageModel {
1598
2081
  });
1599
2082
  const { responseHeaders, value: response } = await postJsonToApi({
1600
2083
  url,
1601
- headers: combineHeaders(this.config.headers?.(), options.headers),
2084
+ headers: combineHeaders(await resolve(this.config.headers), options.headers),
1602
2085
  body,
1603
2086
  failedResponseHandler: openaiFailedResponseHandler,
1604
2087
  successfulResponseHandler: createEventSourceResponseHandler(openaiCompletionChunkSchema),
@@ -1761,7 +2244,7 @@ var OpenAIEmbeddingModel = class OpenAIEmbeddingModel {
1761
2244
  path: "/embeddings",
1762
2245
  modelId: this.modelId
1763
2246
  }),
1764
- headers: combineHeaders(this.config.headers?.(), headers),
2247
+ headers: combineHeaders(await resolve(this.config.headers), headers),
1765
2248
  body: {
1766
2249
  model: this.modelId,
1767
2250
  input: values,
@@ -1809,25 +2292,12 @@ const openaiImageResponseSchema = lazySchema(() => zodSchema(z.object({
1809
2292
  })));
1810
2293
  //#endregion
1811
2294
  //#region src/image/openai-image-model-options.ts
1812
- const modelMaxImagesPerCall = {
1813
- "dall-e-3": 1,
1814
- "dall-e-2": 10,
1815
- "gpt-image-1": 10,
1816
- "gpt-image-1-mini": 10,
1817
- "gpt-image-1.5": 10,
1818
- "gpt-image-2": 10,
1819
- "gpt-image-2.5-flare": 10,
1820
- "gpt-image-2.5-flare-2026-09-08": 10,
1821
- "gpt-image-2.5-sunburst": 10,
1822
- "gpt-image-2.5-sunburst-2026-09-08": 10,
1823
- "chatgpt-image-latest": 10
1824
- };
1825
- const defaultResponseFormatPrefixes = ["chatgpt-image-", "gpt-image-"];
2295
+ const modelMaxImagesPerCall = openaiImageModelMaxImagesPerCall;
1826
2296
  function hasDefaultResponseFormat(modelId) {
1827
- return defaultResponseFormatPrefixes.some((prefix) => modelId.startsWith(prefix));
2297
+ return getOpenAIImageModelEntry(modelId).requestConfig.image.responseFormat === "provider-default";
1828
2298
  }
1829
2299
  function getMaxImagesPerCall(modelId) {
1830
- return modelMaxImagesPerCall[modelId] ?? (modelId.startsWith("gpt-image-") ? 10 : 1);
2300
+ return getOpenAIImageModelEntry(modelId).capabilities.image.maxImagesPerCall ?? 1;
1831
2301
  }
1832
2302
  const baseImageModelOptionsObject = () => z.object({
1833
2303
  /**
@@ -1912,23 +2382,13 @@ var OpenAIImageModel = class OpenAIImageModel {
1912
2382
  }
1913
2383
  get supportsFileInputs() {
1914
2384
  if (this.config.imageInputCapabilities != null) return this.config.imageInputCapabilities.supportsFileInputs;
1915
- if ([
1916
- "dall-e-2",
1917
- "gpt-image-1",
1918
- "gpt-image-1-mini",
1919
- "gpt-image-1.5",
1920
- "gpt-image-2",
1921
- "gpt-image-2.5-flare",
1922
- "gpt-image-2.5-flare-2026-09-08",
1923
- "gpt-image-2.5-sunburst",
1924
- "gpt-image-2.5-sunburst-2026-09-08",
1925
- "chatgpt-image-latest"
1926
- ].includes(this.modelId)) return true;
1927
- return this.modelId === "dall-e-3" ? false : void 0;
2385
+ const support = getOpenAIImageModelEntry(this.modelId).capabilities.image.fileInput;
2386
+ return typeof support === "boolean" ? support : void 0;
1928
2387
  }
1929
2388
  get supportsMaskInputs() {
1930
2389
  if (this.config.imageInputCapabilities != null) return this.config.imageInputCapabilities.supportsMaskInputs;
1931
- return this.supportsFileInputs;
2390
+ const support = getOpenAIImageModelEntry(this.modelId).capabilities.image.maskInput;
2391
+ return typeof support === "boolean" ? support : void 0;
1932
2392
  }
1933
2393
  get provider() {
1934
2394
  return this.config.provider;
@@ -1961,7 +2421,7 @@ var OpenAIImageModel = class OpenAIImageModel {
1961
2421
  path: "/images/edits",
1962
2422
  modelId: this.modelId
1963
2423
  }),
1964
- headers: combineHeaders(this.config.headers?.(), headers),
2424
+ headers: combineHeaders(await resolve(this.config.headers), headers),
1965
2425
  formData: convertToFormData({
1966
2426
  model: this.modelId,
1967
2427
  prompt,
@@ -2015,7 +2475,7 @@ var OpenAIImageModel = class OpenAIImageModel {
2015
2475
  path: "/images/generations",
2016
2476
  modelId: this.modelId
2017
2477
  }),
2018
- headers: combineHeaders(this.config.headers?.(), headers),
2478
+ headers: combineHeaders(await resolve(this.config.headers), headers),
2019
2479
  body: {
2020
2480
  model: this.modelId,
2021
2481
  prompt,
@@ -2183,34 +2643,6 @@ const openAITranscriptionModelOptions = lazySchema(() => zodSchema(z.object({
2183
2643
  })));
2184
2644
  //#endregion
2185
2645
  //#region src/transcription/openai-transcription-model.ts
2186
- /**
2187
- * Whether `modelId` is `base` or one of its dated snapshots
2188
- * (e.g. `gpt-realtime-whisper-2026-01-01`).
2189
- */
2190
- function isModelOrSnapshot(modelId, base) {
2191
- return modelId === base || modelId.startsWith(`${base}-`);
2192
- }
2193
- /**
2194
- * Model IDs that stream over the realtime transcription WebSocket and do not
2195
- * support the REST transcription endpoint.
2196
- */
2197
- function isRealtimeTranscriptionModelId(modelId) {
2198
- return isModelOrSnapshot(modelId, "gpt-realtime-whisper") || isModelOrSnapshot(modelId, "gpt-live-transcribe");
2199
- }
2200
- /**
2201
- * Model IDs that support streaming transcription. `gpt-transcribe` also
2202
- * supports the REST transcription endpoint.
2203
- */
2204
- function supportsStreamingTranscription(modelId) {
2205
- return isRealtimeTranscriptionModelId(modelId) || isModelOrSnapshot(modelId, "gpt-transcribe");
2206
- }
2207
- /**
2208
- * Models whose realtime transcription session takes a `languages` list
2209
- * instead of the singular `language` field.
2210
- */
2211
- function usesLanguagesList(modelId) {
2212
- return isModelOrSnapshot(modelId, "gpt-live-transcribe") || isModelOrSnapshot(modelId, "gpt-transcribe");
2213
- }
2214
2646
  const languageMap = {
2215
2647
  afrikaans: "af",
2216
2648
  arabic: "ar",
@@ -2303,10 +2735,10 @@ var OpenAITranscriptionModel = class OpenAITranscriptionModel {
2303
2735
  formData.append("model", this.modelId);
2304
2736
  const fileExtension = mediaTypeToExtension(mediaType);
2305
2737
  formData.append("file", new File([blob], "audio", { type: mediaType }), `audio.${fileExtension}`);
2306
- const isDiarizationModel = this.modelId === "gpt-4o-transcribe-diarize";
2307
- const responseFormat = openAIOptions?.responseFormat ?? (isDiarizationModel ? "diarized_json" : this.modelId === "whisper-1" ? "verbose_json" : void 0);
2738
+ const { transcription: requestConfig } = getOpenAITranscriptionModelEntry(this.modelId).requestConfig;
2739
+ const responseFormat = openAIOptions?.responseFormat ?? requestConfig.responseFormat;
2308
2740
  const timestampGranularities = openAIOptions?.timestampGranularities ?? (responseFormat === "verbose_json" ? ["segment"] : void 0);
2309
- const chunkingStrategy = openAIOptions?.chunkingStrategy ?? (isDiarizationModel ? "auto" : void 0);
2741
+ const chunkingStrategy = openAIOptions?.chunkingStrategy ?? requestConfig.chunkingStrategy;
2310
2742
  const transcriptionModelOptions = {
2311
2743
  response_format: responseFormat,
2312
2744
  include: openAIOptions?.include,
@@ -2331,7 +2763,7 @@ var OpenAITranscriptionModel = class OpenAITranscriptionModel {
2331
2763
  };
2332
2764
  }
2333
2765
  async doGenerate(options) {
2334
- if (isRealtimeTranscriptionModelId(this.modelId)) throw new UnsupportedFunctionalityError({ functionality: `non-streaming transcription with ${this.modelId}` });
2766
+ if (getOpenAITranscriptionModelEntry(this.modelId).capabilities.transcription.transcription === false) throw new UnsupportedFunctionalityError({ functionality: `non-streaming transcription with ${this.modelId}` });
2335
2767
  const currentDate = this.config._internal?.currentDate?.() ?? /* @__PURE__ */ new Date();
2336
2768
  const { formData, warnings } = await this.getArgs(options);
2337
2769
  const { value: response, responseHeaders, rawValue: rawResponse } = await postFormDataToApi({
@@ -2339,7 +2771,7 @@ var OpenAITranscriptionModel = class OpenAITranscriptionModel {
2339
2771
  path: "/audio/transcriptions",
2340
2772
  modelId: this.modelId
2341
2773
  }),
2342
- headers: combineHeaders(this.config.headers?.(), options.headers),
2774
+ headers: combineHeaders(await resolve(this.config.headers), options.headers),
2343
2775
  formData,
2344
2776
  failedResponseHandler: openaiFailedResponseHandler,
2345
2777
  successfulResponseHandler: createJsonResponseHandler(openaiTranscriptionResponseSchema),
@@ -2381,7 +2813,8 @@ var OpenAITranscriptionModel = class OpenAITranscriptionModel {
2381
2813
  };
2382
2814
  }
2383
2815
  async doStream(options) {
2384
- if (!supportsStreamingTranscription(this.modelId)) throw new UnsupportedFunctionalityError({ functionality: `streaming transcription with ${this.modelId}` });
2816
+ const entry = getOpenAITranscriptionModelEntry(this.modelId);
2817
+ if (entry.capabilities.transcription.streaming !== true) throw new UnsupportedFunctionalityError({ functionality: `streaming transcription with ${this.modelId}` });
2385
2818
  const currentDate = this.config._internal?.currentDate?.() ?? /* @__PURE__ */ new Date();
2386
2819
  const openAIOptions = await parseProviderOptions({
2387
2820
  provider: "openai",
@@ -2400,13 +2833,13 @@ var OpenAITranscriptionModel = class OpenAITranscriptionModel {
2400
2833
  feature: `providerOptions.openai.${option}`,
2401
2834
  details: `OpenAI streaming transcription does not support ${option}.`
2402
2835
  });
2403
- const supportsDelay = !isModelOrSnapshot(this.modelId, "gpt-transcribe");
2836
+ const supportsDelay = entry.capabilities.transcription.streamingDelay === true;
2404
2837
  if (!supportsDelay && openAIOptions?.streaming?.delay != null) warnings.push({
2405
2838
  type: "unsupported",
2406
2839
  feature: "providerOptions.openai.streaming.delay",
2407
2840
  details: `OpenAI streaming transcription with ${this.modelId} does not support delay.`
2408
2841
  });
2409
- const headers = combineHeaders(this.config.headers?.(), options.headers);
2842
+ const headers = combineHeaders(await resolve(this.config.headers), options.headers);
2410
2843
  const sessionUpdate = buildOpenAIRealtimeTranscriptionSession({
2411
2844
  modelId: this.modelId,
2412
2845
  inputAudioFormat: options.inputAudioFormat,
@@ -2558,7 +2991,7 @@ function buildOpenAIRealtimeTranscriptionSession({ modelId, inputAudioFormat, pr
2558
2991
  },
2559
2992
  transcription: {
2560
2993
  model: modelId,
2561
- ...providerOptions?.language != null ? usesLanguagesList(modelId) ? { languages: [providerOptions.language] } : { language: providerOptions.language } : {},
2994
+ ...providerOptions?.language != null ? getOpenAITranscriptionModelEntry(modelId).requestConfig.transcription.languageField === "languages" ? { languages: [providerOptions.language] } : { language: providerOptions.language } : {},
2562
2995
  ...supportsDelay && providerOptions?.streaming?.delay != null ? { delay: providerOptions.streaming.delay } : {}
2563
2996
  },
2564
2997
  turn_detection: null
@@ -2664,7 +3097,7 @@ var OpenAISpeechModel = class OpenAISpeechModel {
2664
3097
  path: "/audio/speech",
2665
3098
  modelId: this.modelId
2666
3099
  }),
2667
- headers: combineHeaders(this.config.headers?.(), options.headers),
3100
+ headers: combineHeaders(await resolve(this.config.headers), options.headers),
2668
3101
  body: requestBody,
2669
3102
  failedResponseHandler: openaiFailedResponseHandler,
2670
3103
  successfulResponseHandler: createBinaryResponseHandler(),
@@ -6280,7 +6713,7 @@ const openaiResponsesSupportedUrls = {
6280
6713
  * @see https://developers.openai.com/api/docs/guides/reasoning#change-reasoning-mid-conversation
6281
6714
  */
6282
6715
  function getConfigurationUpdateUnsupportedReason({ modelCapabilities, options }) {
6283
- if (!modelCapabilities.supportsConfigurationUpdate) return "reasoningEffortUpdate is only supported by GPT-6 and later models";
6716
+ if (!modelCapabilities.configurationUpdates) return "reasoningEffortUpdate is only supported by GPT-6 and later models";
6284
6717
  if (options?.reasoningMode === "pro" || options?.contextManagement != null || options?.truncation === "auto") return "reasoningEffortUpdate requires standard reasoning mode without automatic compaction or automatic truncation";
6285
6718
  }
6286
6719
  var OpenAIResponsesLanguageModel = class OpenAIResponsesLanguageModel {
@@ -6304,7 +6737,7 @@ var OpenAIResponsesLanguageModel = class OpenAIResponsesLanguageModel {
6304
6737
  }
6305
6738
  static async prepareRequest({ modelId, config, options: { maxOutputTokens, temperature, stopSequences, topP, topK, presencePenalty, frequencyPenalty, seed, prompt, reasoning, providerOptions, tools, toolChoice, responseFormat } }) {
6306
6739
  const warnings = [];
6307
- const modelCapabilities = getOpenAILanguageModelCapabilities(modelId);
6740
+ const { capabilities: { language: modelCapabilities }, requestConfig: { language: modelRequestConfig } } = getOpenAILanguageModelEntry(modelId);
6308
6741
  if (topK != null) warnings.push({
6309
6742
  type: "unsupported",
6310
6743
  feature: "topK"
@@ -6336,17 +6769,14 @@ var OpenAIResponsesLanguageModel = class OpenAIResponsesLanguageModel {
6336
6769
  providerOptions,
6337
6770
  schema: openaiLanguageModelResponsesOptionsSchema
6338
6771
  });
6339
- let resolvedReasoningEffort = openaiOptions?.reasoningEffort ?? (isCustomReasoning(reasoning) ? reasoning : void 0);
6340
- if (resolvedReasoningEffort != null && modelCapabilities.supportedReasoningEfforts != null && !modelCapabilities.supportedReasoningEfforts.includes(resolvedReasoningEffort)) {
6341
- warnings.push({
6342
- type: "unsupported",
6343
- feature: "reasoningEffort",
6344
- details: `${modelId} only supports the following reasoning efforts: ${modelCapabilities.supportedReasoningEfforts.join(", ")}`
6345
- });
6346
- resolvedReasoningEffort = void 0;
6347
- }
6772
+ const resolvedReasoningEffort = resolveOpenAIReasoningEffort({
6773
+ providerReasoningEffort: openaiOptions?.reasoningEffort,
6774
+ reasoning,
6775
+ supportedReasoningEfforts: modelCapabilities.reasoning.efforts,
6776
+ warnings
6777
+ });
6348
6778
  const resolvedReasoningSummary = openaiOptions?.reasoningSummary !== void 0 ? openaiOptions.reasoningSummary : resolvedReasoningEffort != null && resolvedReasoningEffort !== "none" ? "detailed" : void 0;
6349
- const isReasoningModel = openaiOptions?.forceReasoning ?? modelCapabilities.isReasoningModel;
6779
+ const isReasoningModel = openaiOptions?.forceReasoning ?? modelCapabilities.reasoning.support === true;
6350
6780
  if (openaiOptions?.conversation && openaiOptions?.previousResponseId) warnings.push({
6351
6781
  type: "unsupported",
6352
6782
  feature: "conversation",
@@ -6378,7 +6808,7 @@ var OpenAIResponsesLanguageModel = class OpenAIResponsesLanguageModel {
6378
6808
  toolNameMapping,
6379
6809
  customProviderToolNames,
6380
6810
  outputSchemaToolNames,
6381
- supportsAsyncToolCalling: modelCapabilities.supportsAsyncToolCalling,
6811
+ supportsAsyncToolCalling: modelCapabilities.tools.async,
6382
6812
  providerOptionsName
6383
6813
  });
6384
6814
  const configurationUpdateUnsupportedReason = getConfigurationUpdateUnsupportedReason({
@@ -6388,7 +6818,7 @@ var OpenAIResponsesLanguageModel = class OpenAIResponsesLanguageModel {
6388
6818
  const { input, warnings: inputWarnings } = await convertToOpenAIResponsesInput({
6389
6819
  prompt,
6390
6820
  toolNameMapping,
6391
- systemMessageMode: openaiOptions?.systemMessageMode ?? (isReasoningModel ? "developer" : modelCapabilities.systemMessageMode),
6821
+ systemMessageMode: openaiOptions?.systemMessageMode ?? (isReasoningModel ? "developer" : modelRequestConfig.systemMessageMode),
6392
6822
  providerOptionsName,
6393
6823
  configurationUpdateUnsupportedReason,
6394
6824
  explicitMessageItemType: config.explicitMessageItemType,
@@ -6407,7 +6837,8 @@ var OpenAIResponsesLanguageModel = class OpenAIResponsesLanguageModel {
6407
6837
  outputSchemaToolNames: outputSchemaToolNames.size > 0 ? outputSchemaToolNames : void 0
6408
6838
  });
6409
6839
  warnings.push(...inputWarnings);
6410
- const getUpdateEffortUnsupportedReason = (effort) => effort != null && modelCapabilities.supportedReasoningEfforts?.includes(effort) === false ? `${modelId} only supports the following reasoning efforts: ${modelCapabilities.supportedReasoningEfforts.join(", ")}` : void 0;
6840
+ const supportedReasoningEfforts = modelCapabilities.reasoning.efforts;
6841
+ const getUpdateEffortUnsupportedReason = (effort) => effort != null && supportedReasoningEfforts?.includes(effort) === false ? `${modelId} only supports the following reasoning efforts: ${supportedReasoningEfforts.join(", ")}` : void 0;
6411
6842
  for (const item of input) if (item.type === "configuration_update") {
6412
6843
  const unsupportedReason = getUpdateEffortUnsupportedReason(item.reasoning.effort);
6413
6844
  if (unsupportedReason != null) throw new UnsupportedFunctionalityError({
@@ -6495,7 +6926,7 @@ var OpenAIResponsesLanguageModel = class OpenAIResponsesLanguageModel {
6495
6926
  ...openaiOptions?.reasoningContext != null && { context: openaiOptions.reasoningContext }
6496
6927
  } }
6497
6928
  };
6498
- if (modelCapabilities.supportsConfigurationUpdate && baseArgs.prompt_cache_retention != null) {
6929
+ if (!modelCapabilities.promptCache.retention && baseArgs.prompt_cache_retention != null) {
6499
6930
  baseArgs.prompt_cache_retention = void 0;
6500
6931
  warnings.push({
6501
6932
  type: "unsupported",
@@ -6506,7 +6937,7 @@ var OpenAIResponsesLanguageModel = class OpenAIResponsesLanguageModel {
6506
6937
  if (isReasoningModel) {
6507
6938
  let effectiveReasoningEffort = resolvedReasoningEffort;
6508
6939
  for (const item of input) if (item.type === "configuration_update") effectiveReasoningEffort = item.reasoning.effort;
6509
- if (!(effectiveReasoningEffort === "none" && modelCapabilities.supportsNonReasoningParameters)) {
6940
+ if (!(effectiveReasoningEffort === "none" && modelCapabilities.reasoning.sampling === "reasoning-effort-none")) {
6510
6941
  if (baseArgs.temperature != null) {
6511
6942
  baseArgs.temperature = void 0;
6512
6943
  warnings.push({
@@ -6523,7 +6954,7 @@ var OpenAIResponsesLanguageModel = class OpenAIResponsesLanguageModel {
6523
6954
  details: "topP is not supported for reasoning models"
6524
6955
  });
6525
6956
  }
6526
- if (modelCapabilities.supportedReasoningEfforts != null && (baseArgs.top_logprobs != null || baseArgs.include?.includes("message.output_text.logprobs"))) {
6957
+ if (modelCapabilities.endpoints.responses.logprobsRequireNonReasoning && (baseArgs.top_logprobs != null || baseArgs.include?.includes("message.output_text.logprobs"))) {
6527
6958
  baseArgs.top_logprobs = void 0;
6528
6959
  const filteredInclude = baseArgs.include?.filter((value) => value !== "message.output_text.logprobs");
6529
6960
  baseArgs.include = filteredInclude != null && filteredInclude.length > 0 ? filteredInclude : void 0;
@@ -6556,7 +6987,7 @@ var OpenAIResponsesLanguageModel = class OpenAIResponsesLanguageModel {
6556
6987
  details: "reasoningContext is not supported for non-reasoning models"
6557
6988
  });
6558
6989
  }
6559
- if (openaiOptions?.serviceTier === "flex" && !modelCapabilities.supportsFlexProcessing) {
6990
+ if (openaiOptions?.serviceTier === "flex" && !modelCapabilities.serviceTiers.flex) {
6560
6991
  warnings.push({
6561
6992
  type: "unsupported",
6562
6993
  feature: "serviceTier",
@@ -6564,7 +6995,7 @@ var OpenAIResponsesLanguageModel = class OpenAIResponsesLanguageModel {
6564
6995
  });
6565
6996
  delete baseArgs.service_tier;
6566
6997
  }
6567
- if ((openaiOptions?.serviceTier === "priority" || openaiOptions?.serviceTier === "fast") && !modelCapabilities.supportsPriorityProcessing) {
6998
+ if ((openaiOptions?.serviceTier === "priority" || openaiOptions?.serviceTier === "fast") && !modelCapabilities.serviceTiers.priority) {
6568
6999
  warnings.push({
6569
7000
  type: "unsupported",
6570
7001
  feature: "serviceTier",
@@ -6604,7 +7035,7 @@ var OpenAIResponsesLanguageModel = class OpenAIResponsesLanguageModel {
6604
7035
  const approvalRequestIdToDummyToolCallIdFromPrompt = extractApprovalRequestIdToToolCallIdMapping(options.prompt);
6605
7036
  const { responseHeaders, value: response, rawValue: rawResponse } = await postJsonToApi({
6606
7037
  url,
6607
- headers: combineHeaders(this.config.headers?.(), options.headers),
7038
+ headers: combineHeaders(await resolve(this.config.headers), options.headers),
6608
7039
  body,
6609
7040
  failedResponseHandler: openaiFailedResponseHandler,
6610
7041
  successfulResponseHandler: createJsonResponseHandler(openaiResponsesResponseSchema),
@@ -7054,7 +7485,7 @@ var OpenAIResponsesLanguageModel = class OpenAIResponsesLanguageModel {
7054
7485
  });
7055
7486
  const { responseHeaders, value: response } = await postJsonToApi({
7056
7487
  url,
7057
- headers: combineHeaders(this.config.headers?.(), options.headers),
7488
+ headers: combineHeaders(await resolve(this.config.headers), options.headers),
7058
7489
  body: {
7059
7490
  ...body,
7060
7491
  stream: true