@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
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { EXPERIMENTAL_EMBEDDING_MODEL_MAX_INPUT_BYTES_PER_CALL, StreamingToolCallTracker, WORKFLOW_DESERIALIZE, WORKFLOW_SERIALIZE, combineHeaders, connectToWebSocket, convertAsyncIteratorToReadableStream, convertBase64ToUint8Array, convertInlineFileDataToUint8Array, convertToBase64, convertToFormData, convertUint8ArrayToBase64, createBinaryResponseHandler, createBinaryStreamResponseHandler, createEventSourceResponseHandler, createJsonErrorResponseHandler, createJsonLinesResponseHandler, createJsonResponseHandler, createLanguageModelResponseMetadata, createLanguageModelResponseMetadata as getResponseMetadata, createNullLanguageModelUsage, createProviderDefinedToolFactory, createProviderDefinedToolFactoryWithOutputSchema, createProviderExecutedToolFactory, createProviderStreamError, createToolNameMapping, deleteFromApi, detectMediaType, downloadBlob, encodePathSegment, experimental_toolCaller, generateId, getFromApi, getTopLevelMediaType, isCustomReasoning, isFullMediaType, isNonNullable, isRecord, lazySchema, loadApiKey, loadOptionalSetting, mediaTypeToExtension, normalizeBatchRequestCounts, parseJSON, parseProviderOptions, postFormDataToApi, postJsonToApi, postMultipartStreamToApi, postToApi, resolveFullMediaType, resolveProviderReference, safeParseJSON, safeValidateTypes, serializeModelOptions, toWebSocketUrl, validateBaseURL, validateTypes, waitForWebSocketBufferDrain, withUserAgentSuffix, withoutTrailingSlash, zodSchema } from "@ai-sdk/provider-utils";
1
+ import { EXPERIMENTAL_EMBEDDING_MODEL_MAX_INPUT_BYTES_PER_CALL, StreamingToolCallTracker, WORKFLOW_DESERIALIZE, WORKFLOW_SERIALIZE, combineHeaders, connectToWebSocket, convertAsyncIteratorToReadableStream, convertBase64ToUint8Array, convertInlineFileDataToUint8Array, convertToBase64, convertToFormData, convertUint8ArrayToBase64, createBinaryResponseHandler, createBinaryStreamResponseHandler, createEventSourceResponseHandler, createJsonErrorResponseHandler, createJsonLinesResponseHandler, createJsonResponseHandler, createLanguageModelResponseMetadata, createLanguageModelResponseMetadata as getResponseMetadata, createNullLanguageModelUsage, createProviderDefinedToolFactory, createProviderDefinedToolFactoryWithOutputSchema, createProviderExecutedToolFactory, createProviderStreamError, createToolNameMapping, deleteFromApi, detectMediaType, downloadBlob, encodePathSegment, experimental_toolCaller, generateId, getFromApi, getTopLevelMediaType, isCustomReasoning, isFullMediaType, isNonNullable, isRecord, lazySchema, loadApiKey, loadOptionalSetting, mapReasoningToProviderEffort, mediaTypeToExtension, normalizeBatchRequestCounts, parseJSON, parseProviderOptions, postFormDataToApi, postJsonToApi, postMultipartStreamToApi, postToApi, resolve, resolveFullMediaType, resolveProviderReference, resolveWith, safeParseJSON, safeValidateTypes, serializeModelOptions, toWebSocketUrl, validateBaseURL, validateTypes, waitForWebSocketBufferDrain, withUserAgentSuffix, withoutTrailingSlash, zodSchema } from "@ai-sdk/provider-utils";
2
2
  import { APICallError, InvalidArgumentError, InvalidPromptError, InvalidResponseDataError, TooManyEmbeddingValuesForCallError, UnsupportedFunctionalityError, isJSONObject } from "@ai-sdk/provider";
3
3
  import { z } from "zod/v4";
4
4
  //#region src/openai-config.ts
@@ -29,9 +29,11 @@ const openaiFailedResponseHandler = createJsonErrorResponseHandler({
29
29
  });
30
30
  //#endregion
31
31
  //#region src/openai-decision-model-options.ts
32
- const openaiDecisionModelOptions = lazySchema(() => zodSchema(z.object({
33
- /** An opaque end-user identifier for safety monitoring, up to 128 characters. */
34
- safetyIdentifier: z.string().max(128).optional() })));
32
+ const openaiDecisionModelOptions = lazySchema(() => zodSchema(z.object({
33
+ /** An opaque end-user identifier for safety monitoring, up to 128 characters. */
34
+ safetyIdentifier: z.string().max(128).optional(),
35
+ promptCacheKey: z.string().optional()
36
+ })));
35
37
  //#endregion
36
38
  //#region src/openai-decision-model.ts
37
39
  const probability = () => z.number().min(0).max(1);
@@ -117,10 +119,11 @@ var DecisionOpenAIModel = class DecisionOpenAIModel {
117
119
  path: "/decisions",
118
120
  modelId: this.modelId
119
121
  }),
120
- headers: combineHeaders(this.config.headers?.(), headers),
122
+ headers: combineHeaders(await resolve(this.config.headers), headers),
121
123
  body: {
122
124
  model: this.modelId,
123
125
  safety_identifier: openaiOptions?.safetyIdentifier,
126
+ prompt_cache_key: openaiOptions?.promptCacheKey,
124
127
  input: [{
125
128
  role: "user",
126
129
  content: state.map((part) => {
@@ -128,7 +131,10 @@ var DecisionOpenAIModel = class DecisionOpenAIModel {
128
131
  type: "input_text",
129
132
  text: part.text
130
133
  };
131
- if (part.type === "json") return {
134
+ if (part.type === "json") return isInputJsonData(part.value) ? {
135
+ type: "input_json",
136
+ data: part.value
137
+ } : {
132
138
  type: "input_text",
133
139
  text: JSON.stringify(part.value)
134
140
  };
@@ -240,7 +246,7 @@ var DecisionOpenAIModel = class DecisionOpenAIModel {
240
246
  type: "unsupported",
241
247
  feature: "reasoning"
242
248
  }] : [],
243
- ...Object.keys(providerOptions?.openai ?? {}).filter((option) => option !== "safetyIdentifier").map((option) => ({
249
+ ...Object.keys(providerOptions?.openai ?? {}).filter((option) => !SUPPORTED_PROVIDER_OPTIONS.has(option)).map((option) => ({
244
250
  type: "unsupported",
245
251
  feature: `providerOptions.openai.${option}`
246
252
  }))
@@ -257,59 +263,554 @@ var DecisionOpenAIModel = class DecisionOpenAIModel {
257
263
  };
258
264
  }
259
265
  };
266
+ const SUPPORTED_PROVIDER_OPTIONS = /* @__PURE__ */ new Set(["safetyIdentifier", "promptCacheKey"]);
260
267
  function toText(input) {
261
268
  return typeof input === "string" ? input : JSON.stringify(input);
262
269
  }
270
+ const INPUT_JSON_MAX_DEPTH = 32;
271
+ const INPUT_JSON_MAX_VALUES = 1e4;
272
+ const INPUT_JSON_MAX_BYTES = 262144;
273
+ function isInputJsonData(value) {
274
+ return (Array.isArray(value) ? value.length > 0 && value.every(isJSONObject$1) : isJSONObject$1(value)) && fitsInputJsonLimits(value);
275
+ }
276
+ function fitsInputJsonLimits(value) {
277
+ let count = 0;
278
+ const visit = (node, depth) => {
279
+ count += 1;
280
+ if (count > INPUT_JSON_MAX_VALUES) return false;
281
+ if (node === null || typeof node !== "object") return true;
282
+ if (depth > INPUT_JSON_MAX_DEPTH) return false;
283
+ return (Array.isArray(node) ? node : Object.values(node)).every((child) => visit(child, depth + 1));
284
+ };
285
+ return visit(value, 1) && new TextEncoder().encode(JSON.stringify(value)).length <= INPUT_JSON_MAX_BYTES;
286
+ }
287
+ function isJSONObject$1(value) {
288
+ return typeof value === "object" && value !== null && !Array.isArray(value);
289
+ }
263
290
  //#endregion
264
- //#region src/openai-language-model-capabilities.ts
265
- function getOpenAILanguageModelCapabilities(modelId) {
291
+ //#region src/openai-model-catalog.ts
292
+ /**
293
+ * Options accepted under `providerOptions.openai`. Language options are the
294
+ * Responses API options. The `satisfies` check keeps this list in sync with
295
+ * the option schema.
296
+ */
297
+ const openaiProviderOptions = { language: {
298
+ conversation: { description: "OpenAI Conversation ID to continue." },
299
+ include: { description: "Extra fields to include in the response." },
300
+ includeWebSearchSources: { description: "Include web search action sources." },
301
+ instructions: { description: "Instructions for the model." },
302
+ logprobs: { description: "Return token log probabilities." },
303
+ maxToolCalls: { description: "Maximum number of built-in tool calls." },
304
+ metadata: { description: "Metadata to store with the generation." },
305
+ parallelToolCalls: { description: "Whether to use parallel tool calls." },
306
+ previousResponseId: { description: "Previous response ID to continue." },
307
+ promptCacheKey: { description: "Cache key for prompt caching." },
308
+ promptCacheOptions: { description: "Prompt cache mode, TTL, and prewarm." },
309
+ promptCacheRetention: { description: "Prompt cache retention policy." },
310
+ reasoningEffort: { description: "Reasoning effort." },
311
+ reasoningEffortUpdate: { description: "Reasoning effort update from this response onward." },
312
+ reasoningMode: { description: "Standard or pro reasoning mode." },
313
+ reasoningContext: { description: "Which reasoning items can be used." },
314
+ reasoningSummary: { description: "Reasoning summary output." },
315
+ safetyIdentifier: { description: "Identifier for safety monitoring." },
316
+ serviceTier: { description: "Service tier for the request." },
317
+ store: { description: "Whether to store the generation." },
318
+ passThroughUnsupportedFiles: { description: "Send non-image file types as generic input files." },
319
+ strictJsonSchema: { description: "Use strict JSON schema validation." },
320
+ textVerbosity: { description: "Verbosity of text responses." },
321
+ truncation: { description: "Output truncation behavior." },
322
+ user: { description: "End-user identifier for abuse monitoring." },
323
+ systemMessageMode: { description: "System message role override." },
324
+ forceReasoning: { description: "Treat the model as a reasoning model." },
325
+ contextManagement: { description: "Server-side context compaction." },
326
+ compactionTrigger: { description: "Request explicit compaction." },
327
+ allowedTools: { description: "Restrict callable tools to a subset." }
328
+ } };
329
+ const configurableNonReasoning = { capabilities: { language: { reasoning: {
330
+ support: true,
331
+ efforts: [
332
+ "none",
333
+ "low",
334
+ "medium",
335
+ "high",
336
+ "xhigh",
337
+ "max"
338
+ ],
339
+ sampling: "reasoning-effort-none"
340
+ } } } };
341
+ const openaiLanguageModelEntries = Object.fromEntries(Object.entries({
342
+ "gpt-6-astra": {},
343
+ "gpt-6.1-sol": {},
344
+ "gpt-6.1-terra": configurableNonReasoning,
345
+ "gpt-6-luna": configurableNonReasoning,
346
+ "gpt-6-sol": configurableNonReasoning,
347
+ "gpt-5.6": {},
348
+ "gpt-5.6-luna": {},
349
+ "gpt-5.6-sol": {},
350
+ "gpt-5.6-terra": {},
351
+ "gpt-5.5": {},
352
+ "gpt-5.4-pro": {},
353
+ "gpt-5.4": {},
354
+ "gpt-5.4-mini": {},
355
+ "gpt-5.4-nano": {},
356
+ "gpt-5.3-chat-latest": {},
357
+ "gpt-5.2-pro": {},
358
+ "gpt-5.2-chat-latest": {},
359
+ "gpt-5.2": {},
360
+ "gpt-5.1-codex-mini": {},
361
+ "gpt-5.1-codex": {},
362
+ "gpt-5.1-chat-latest": {},
363
+ "gpt-5.1": {},
364
+ "gpt-5-pro": {},
365
+ "gpt-5": {},
366
+ "gpt-5-mini": {},
367
+ "gpt-5-nano": {},
368
+ "gpt-5-codex": {},
369
+ "gpt-5-chat-latest": { capabilities: { language: {
370
+ objectGeneration: false,
371
+ tools: {
372
+ usage: false,
373
+ streaming: false,
374
+ async: false
375
+ }
376
+ } } },
377
+ "gpt-4.1": {},
378
+ "gpt-4.1-mini": {},
379
+ "gpt-4.1-nano": {},
380
+ "gpt-4o": {},
381
+ "gpt-4o-mini": {}
382
+ }).map(([modelId, definition]) => [modelId, createOpenAILanguageModelEntry(modelId, definition)]));
383
+ function createOpenAILanguageModelEntry(modelId, definition) {
266
384
  const oSeriesVersion = getOSeriesVersion(modelId);
267
385
  const gptVersion = getGptVersion(modelId);
386
+ const isRecognizedModelFamily = oSeriesVersion != null || gptVersion != null || /^gpt-4o(?:-|$)/.test(modelId);
268
387
  const isGptChatModel = gptVersion?.minor == null && (gptVersion?.variant?.startsWith("chat") ?? false);
269
388
  const isGptNanoModel = gptVersion?.variant?.startsWith("nano") ?? false;
270
389
  const isGpt6OrLaterModel = gptVersion != null && gptVersion.major >= 6;
271
- const isGpt6OrLaterModelWithNoneEffort = modelId === "gpt-6-sol" || modelId === "gpt-6-luna" || modelId === "gpt-6.1-terra";
390
+ const isGpt56OrLaterModel = isGpt6OrLaterModel || gptVersion?.major === 5 && (gptVersion.minor ?? 0) >= 6;
391
+ 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));
272
392
  const supportsFlexProcessing = oSeriesVersion != null && oSeriesVersion >= 3 || gptVersion != null && gptVersion.major >= 5 && !isGptChatModel;
273
393
  const supportsPriorityProcessing = modelId.startsWith("gpt-4") || gptVersion != null && gptVersion.major >= 5 && !isGptNanoModel && !isGptChatModel || oSeriesVersion != null && oSeriesVersion >= 3;
274
394
  const isReasoningModel = oSeriesVersion != null || gptVersion != null && gptVersion.major >= 5 && !isGptChatModel;
275
- const supportsNonReasoningParameters = isGpt6OrLaterModelWithNoneEffort || !isGpt6OrLaterModel && gptVersion != null && (gptVersion.major > 5 || gptVersion.major === 5 && (gptVersion.minor ?? 0) >= 1);
395
+ const reasoningSampling = definition?.capabilities?.language?.reasoning?.sampling ?? (!isGpt6OrLaterModel && gptVersion != null && (gptVersion.major > 5 || gptVersion.major === 5 && (gptVersion.minor ?? 0) >= 1) ? "reasoning-effort-none" : "unsupported");
396
+ const sampling = !isRecognizedModelFamily ? "unknown" : !isReasoningModel ? true : reasoningSampling === "reasoning-effort-none" ? { condition: "Only when reasoning effort is none." } : false;
397
+ const chatTemperatureSupportedWithoutReasoning = !modelId.startsWith("gpt-4o-search-preview") && !modelId.startsWith("gpt-4o-mini-search-preview");
398
+ const entry = {
399
+ capabilities: { language: {
400
+ inputs: definition?.capabilities?.language?.inputs ?? {
401
+ image: definition != null ? true : "unknown",
402
+ audio: definition != null ? false : "unknown"
403
+ },
404
+ objectGeneration: definition?.capabilities?.language?.objectGeneration ?? (definition != null ? true : "unknown"),
405
+ tools: definition?.capabilities?.language?.tools ?? {
406
+ usage: definition != null ? true : "unknown",
407
+ streaming: definition != null ? true : "unknown",
408
+ async: isGpt6OrLaterModel
409
+ },
410
+ reasoning: {
411
+ support: isRecognizedModelFamily ? isReasoningModel : "unknown",
412
+ efforts: definition?.capabilities?.language?.reasoning?.efforts ?? (isGpt6OrLaterModel ? [
413
+ "low",
414
+ "medium",
415
+ "high",
416
+ "xhigh",
417
+ "max"
418
+ ] : isStandardGpt5Model ? getGpt5ReasoningEfforts(gptVersion.minor ?? 0) : void 0),
419
+ sampling: reasoningSampling
420
+ },
421
+ sampling: {
422
+ temperature: chatTemperatureSupportedWithoutReasoning ? sampling : { condition: "Not supported by Chat Completions search preview models." },
423
+ topP: sampling,
424
+ 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
425
+ },
426
+ serviceTiers: {
427
+ flex: supportsFlexProcessing,
428
+ priority: supportsPriorityProcessing
429
+ },
430
+ configurationUpdates: isGpt6OrLaterModel,
431
+ promptCache: {
432
+ retention: !isGpt6OrLaterModel,
433
+ options: isRecognizedModelFamily ? isGpt56OrLaterModel : "unknown"
434
+ },
435
+ endpoints: {
436
+ chat: {
437
+ temperatureWithoutReasoning: chatTemperatureSupportedWithoutReasoning,
438
+ functionToolsWithReasoning: !(gptVersion?.major === 5 && (gptVersion.minor ?? 0) >= 6)
439
+ },
440
+ responses: { logprobsRequireNonReasoning: isGpt6OrLaterModel }
441
+ }
442
+ } },
443
+ requestConfig: { language: { systemMessageMode: definition?.requestConfig?.language?.systemMessageMode ?? (isReasoningModel ? "developer" : "system") } }
444
+ };
445
+ const { language } = entry.capabilities;
276
446
  return {
277
- supportsFlexProcessing,
278
- supportsPriorityProcessing,
279
- supportsConfigurationUpdate: isGpt6OrLaterModel,
280
- supportsAsyncToolCalling: isGpt6OrLaterModel,
281
- supportedReasoningEfforts: isGpt6OrLaterModelWithNoneEffort ? [
282
- "none",
283
- "low",
284
- "medium",
285
- "high",
286
- "xhigh",
287
- "max"
288
- ] : isGpt6OrLaterModel ? [
289
- "low",
290
- "medium",
291
- "high",
292
- "xhigh",
293
- "max"
294
- ] : void 0,
295
- isReasoningModel,
296
- systemMessageMode: isReasoningModel ? "developer" : "system",
297
- supportsNonReasoningParameters
447
+ ...entry,
448
+ providerOptions: { language: declareProviderOptions(openaiProviderOptions.language, definition != null ? true : "unknown", {
449
+ logprobs: language.sampling.logprobs,
450
+ maxToolCalls: language.tools.usage,
451
+ parallelToolCalls: language.tools.usage,
452
+ allowedTools: language.tools.usage,
453
+ reasoningEffort: language.reasoning.support,
454
+ reasoningSummary: language.reasoning.support,
455
+ reasoningMode: language.reasoning.support,
456
+ reasoningContext: language.reasoning.support,
457
+ reasoningEffortUpdate: language.configurationUpdates,
458
+ promptCacheOptions: language.promptCache.options,
459
+ promptCacheRetention: language.promptCache.retention
460
+ }) }
298
461
  };
299
462
  }
463
+ /** Applies one default support value to every option, except the listed ones. */
464
+ function declareProviderOptions(definitions, support, exceptions) {
465
+ return Object.fromEntries(Object.keys(definitions).map((option) => [option, exceptions[option] ?? support]));
466
+ }
467
+ function getGpt5ReasoningEfforts(minor) {
468
+ if (minor === 0) return [
469
+ "minimal",
470
+ "low",
471
+ "medium",
472
+ "high"
473
+ ];
474
+ if (minor === 1) return [
475
+ "none",
476
+ "low",
477
+ "medium",
478
+ "high"
479
+ ];
480
+ if (minor < 6) return [
481
+ "none",
482
+ "low",
483
+ "medium",
484
+ "high",
485
+ "xhigh"
486
+ ];
487
+ return [
488
+ "none",
489
+ "low",
490
+ "medium",
491
+ "high",
492
+ "xhigh",
493
+ "max"
494
+ ];
495
+ }
300
496
  function getOSeriesVersion(modelId) {
301
497
  const match = /^o(\d+)(?:-|$)/.exec(modelId);
302
498
  return match == null ? void 0 : Number(match[1]);
303
499
  }
304
500
  function getGptVersion(modelId) {
305
501
  const match = /^gpt-(\d+)(?:\.(\d+))?(?:-(.+))?$/.exec(modelId);
306
- if (match == null) return;
307
- return {
502
+ return match == null ? void 0 : {
308
503
  major: Number(match[1]),
309
504
  minor: match[2] == null ? void 0 : Number(match[2]),
310
505
  variant: match[3]
311
506
  };
312
507
  }
508
+ const openaiEmbeddingModelEntries = {
509
+ "text-embedding-3-large": { capabilities: { embedding: {
510
+ defaultDimensions: 3072,
511
+ customDimensions: true
512
+ } } },
513
+ "text-embedding-3-small": { capabilities: { embedding: {
514
+ defaultDimensions: 1536,
515
+ customDimensions: true
516
+ } } },
517
+ "text-embedding-ada-002": { capabilities: { embedding: {
518
+ defaultDimensions: 1536,
519
+ customDimensions: false
520
+ } } }
521
+ };
522
+ const gptImageSizes = [
523
+ "1024x1024",
524
+ "1536x1024",
525
+ "1024x1536"
526
+ ];
527
+ const customImageSizes = { description: "Standard presets and custom dimensions" };
528
+ function createGptImageEntry(sizes) {
529
+ return {
530
+ capabilities: { image: {
531
+ sizes,
532
+ fileInput: true,
533
+ maskInput: true,
534
+ maxImagesPerCall: 10
535
+ } },
536
+ requestConfig: { image: { responseFormat: "provider-default" } }
537
+ };
538
+ }
539
+ const openaiImageModelEntries = {
540
+ "gpt-image-2.5-flare": createGptImageEntry(customImageSizes),
541
+ "gpt-image-2.5-sunburst": createGptImageEntry(customImageSizes),
542
+ "gpt-image-2": createGptImageEntry(gptImageSizes),
543
+ "gpt-image-1.5": createGptImageEntry(gptImageSizes),
544
+ "gpt-image-1-mini": createGptImageEntry(gptImageSizes),
545
+ "gpt-image-1": createGptImageEntry(gptImageSizes),
546
+ "dall-e-3": {
547
+ capabilities: { image: {
548
+ sizes: [
549
+ "1024x1024",
550
+ "1792x1024",
551
+ "1024x1792"
552
+ ],
553
+ fileInput: false,
554
+ maskInput: false,
555
+ maxImagesPerCall: 1
556
+ } },
557
+ requestConfig: { image: { responseFormat: "b64_json" } }
558
+ },
559
+ "dall-e-2": {
560
+ capabilities: { image: {
561
+ sizes: [
562
+ "256x256",
563
+ "512x512",
564
+ "1024x1024"
565
+ ],
566
+ fileInput: true,
567
+ maskInput: true,
568
+ maxImagesPerCall: 10
569
+ } },
570
+ requestConfig: { image: { responseFormat: "b64_json" } }
571
+ }
572
+ };
573
+ const imageModelAliases = {
574
+ "gpt-image-2.5-flare-2026-09-08": openaiImageModelEntries["gpt-image-2.5-flare"],
575
+ "gpt-image-2.5-sunburst-2026-09-08": openaiImageModelEntries["gpt-image-2.5-sunburst"],
576
+ "chatgpt-image-latest": createGptImageEntry({ description: "Unknown" })
577
+ };
578
+ function resolveOpenAIImageModelEntry(modelId) {
579
+ if (Object.prototype.hasOwnProperty.call(openaiImageModelEntries, modelId)) return openaiImageModelEntries[modelId];
580
+ if (Object.prototype.hasOwnProperty.call(imageModelAliases, modelId)) return imageModelAliases[modelId];
581
+ return {
582
+ capabilities: { image: {
583
+ sizes: { description: "Unknown" },
584
+ fileInput: "unknown",
585
+ maskInput: "unknown",
586
+ maxImagesPerCall: modelId.startsWith("gpt-image-") ? 10 : 1
587
+ } },
588
+ requestConfig: { image: { responseFormat: modelId.startsWith("chatgpt-image-") || modelId.startsWith("gpt-image-") ? "provider-default" : "b64_json" } }
589
+ };
590
+ }
591
+ Object.fromEntries(Object.entries({
592
+ ...openaiImageModelEntries,
593
+ ...imageModelAliases
594
+ }).map(([modelId, entry]) => [modelId, entry.capabilities.image.maxImagesPerCall ?? 1]));
595
+ const defaultTranscriptionRequestConfig = { languageField: "language" };
596
+ const openaiTranscriptionModelEntries = {
597
+ "whisper-1": {
598
+ capabilities: { transcription: {
599
+ transcription: true,
600
+ streaming: false,
601
+ streamingDelay: false,
602
+ duration: true,
603
+ segments: true,
604
+ language: true
605
+ } },
606
+ requestConfig: { transcription: {
607
+ ...defaultTranscriptionRequestConfig,
608
+ responseFormat: "verbose_json"
609
+ } }
610
+ },
611
+ "gpt-4o-mini-transcribe": {
612
+ capabilities: { transcription: {
613
+ transcription: true,
614
+ streaming: false,
615
+ streamingDelay: false,
616
+ duration: false,
617
+ segments: false,
618
+ language: false
619
+ } },
620
+ requestConfig: { transcription: defaultTranscriptionRequestConfig }
621
+ },
622
+ "gpt-4o-transcribe": {
623
+ capabilities: { transcription: {
624
+ transcription: true,
625
+ streaming: false,
626
+ streamingDelay: false,
627
+ duration: false,
628
+ segments: false,
629
+ language: false
630
+ } },
631
+ requestConfig: { transcription: defaultTranscriptionRequestConfig }
632
+ },
633
+ "gpt-4o-transcribe-diarize": {
634
+ capabilities: { transcription: {
635
+ transcription: true,
636
+ streaming: false,
637
+ streamingDelay: false,
638
+ duration: true,
639
+ segments: true,
640
+ language: false
641
+ } },
642
+ requestConfig: { transcription: {
643
+ ...defaultTranscriptionRequestConfig,
644
+ responseFormat: "diarized_json",
645
+ chunkingStrategy: "auto"
646
+ } }
647
+ },
648
+ "gpt-transcribe": {
649
+ capabilities: { transcription: {
650
+ transcription: true,
651
+ streaming: true,
652
+ streamingDelay: false,
653
+ duration: false,
654
+ segments: false,
655
+ language: true
656
+ } },
657
+ requestConfig: { transcription: { languageField: "languages" } }
658
+ },
659
+ "gpt-live-transcribe": {
660
+ capabilities: { transcription: {
661
+ transcription: false,
662
+ streaming: true,
663
+ streamingDelay: true,
664
+ duration: false,
665
+ segments: false,
666
+ language: false
667
+ } },
668
+ requestConfig: { transcription: { languageField: "languages" } }
669
+ },
670
+ "gpt-realtime-whisper": {
671
+ capabilities: { transcription: {
672
+ transcription: false,
673
+ streaming: true,
674
+ streamingDelay: true,
675
+ duration: false,
676
+ segments: false,
677
+ language: false
678
+ } },
679
+ requestConfig: { transcription: defaultTranscriptionRequestConfig }
680
+ }
681
+ };
682
+ const transcriptionSnapshotModelIds = [
683
+ "gpt-transcribe",
684
+ "gpt-live-transcribe",
685
+ "gpt-realtime-whisper"
686
+ ];
687
+ function resolveOpenAITranscriptionModelEntry(modelId) {
688
+ if (Object.prototype.hasOwnProperty.call(openaiTranscriptionModelEntries, modelId)) return openaiTranscriptionModelEntries[modelId];
689
+ for (const baseModelId of transcriptionSnapshotModelIds) if (modelId.startsWith(`${baseModelId}-`)) return openaiTranscriptionModelEntries[baseModelId];
690
+ return {
691
+ capabilities: { transcription: {
692
+ transcription: "unknown",
693
+ streaming: "unknown",
694
+ streamingDelay: "unknown",
695
+ duration: "unknown",
696
+ segments: "unknown",
697
+ language: "unknown"
698
+ } },
699
+ requestConfig: { transcription: defaultTranscriptionRequestConfig }
700
+ };
701
+ }
702
+ const openaiSpeechTranslationModelEntries = { "gpt-realtime-translate": { capabilities: { speechTranslation: {
703
+ translatedAudio: true,
704
+ translatedText: true,
705
+ sourceTranscript: true
706
+ } } } };
707
+ const openaiSpeechModelEntries = {
708
+ "tts-1": { capabilities: { speech: { instructions: false } } },
709
+ "tts-1-hd": { capabilities: { speech: { instructions: false } } },
710
+ "gpt-4o-mini-tts": { capabilities: { speech: { instructions: true } } }
711
+ };
712
+ const liveModelEntry = {
713
+ capabilities: { realtime: {
714
+ conversation: "continuous",
715
+ transports: ["websocket", "webrtc"],
716
+ connections: ["server-websocket", "webrtc"]
717
+ } },
718
+ requestConfig: { realtime: {
719
+ api: "live",
720
+ startup: "session-start",
721
+ finalization: "session-close"
722
+ } }
723
+ };
724
+ const realtimeModelEntry = {
725
+ capabilities: { realtime: {
726
+ conversation: "turn-based",
727
+ transports: ["websocket"],
728
+ connections: ["client-secret-websocket"]
729
+ } },
730
+ requestConfig: { realtime: {
731
+ api: "realtime",
732
+ startup: "session-update",
733
+ finalization: "transport-close"
734
+ } }
735
+ };
736
+ const realtimeModelEntries = {
737
+ "gpt-live-1": liveModelEntry,
738
+ "gpt-realtime": realtimeModelEntry
739
+ };
740
+ /** Keep the existing realtime interface's shape while deriving it from the catalog. */
741
+ const openaiLiveRealtimeCapabilities = {
742
+ ...liveModelEntry.capabilities.realtime,
743
+ startup: liveModelEntry.requestConfig.realtime.startup,
744
+ finalization: liveModelEntry.requestConfig.realtime.finalization
745
+ };
746
+ /**
747
+ * The catalog consumed by request builders and documentation. Source declarations
748
+ * are grouped by operation; entries for the same model combine their sections.
749
+ * An absent section is undeclared, not an instruction to reject a request.
750
+ */
751
+ const openaiModelCatalog = combineModelEntries([
752
+ openaiLanguageModelEntries,
753
+ openaiEmbeddingModelEntries,
754
+ openaiImageModelEntries,
755
+ openaiTranscriptionModelEntries,
756
+ openaiSpeechTranslationModelEntries,
757
+ openaiSpeechModelEntries,
758
+ realtimeModelEntries
759
+ ]);
760
+ function combineModelEntries(catalogs) {
761
+ const entries = /* @__PURE__ */ new Map();
762
+ for (const catalog of catalogs) for (const [modelId, entry] of Object.entries(catalog)) {
763
+ const previous = entries.get(modelId);
764
+ entries.set(modelId, {
765
+ capabilities: {
766
+ ...previous?.capabilities,
767
+ ...entry.capabilities
768
+ },
769
+ ...previous?.providerOptions != null || entry.providerOptions != null ? { providerOptions: {
770
+ ...previous?.providerOptions,
771
+ ...entry.providerOptions
772
+ } } : {},
773
+ ...previous?.requestConfig != null || entry.requestConfig != null ? { requestConfig: {
774
+ ...previous?.requestConfig,
775
+ ...entry.requestConfig
776
+ } } : {}
777
+ });
778
+ }
779
+ return Object.fromEntries(entries);
780
+ }
781
+ function findModelEntry(modelId) {
782
+ return Object.prototype.hasOwnProperty.call(openaiModelCatalog, modelId) ? openaiModelCatalog[modelId] : void 0;
783
+ }
784
+ function getOpenAILanguageModelEntry(modelId) {
785
+ const entry = findModelEntry(modelId);
786
+ return entry?.capabilities.language != null && entry.providerOptions?.language != null && entry.requestConfig?.language != null ? {
787
+ capabilities: { language: entry.capabilities.language },
788
+ providerOptions: { language: entry.providerOptions.language },
789
+ requestConfig: { language: entry.requestConfig.language }
790
+ } : createOpenAILanguageModelEntry(modelId);
791
+ }
792
+ function getOpenAIImageModelEntry(modelId) {
793
+ const entry = findModelEntry(modelId);
794
+ return entry?.capabilities.image != null && entry.requestConfig?.image != null ? {
795
+ capabilities: { image: entry.capabilities.image },
796
+ requestConfig: { image: entry.requestConfig.image }
797
+ } : resolveOpenAIImageModelEntry(modelId);
798
+ }
799
+ function getOpenAITranscriptionModelEntry(modelId) {
800
+ const entry = findModelEntry(modelId);
801
+ return entry?.capabilities.transcription != null && entry.requestConfig?.transcription != null ? {
802
+ capabilities: { transcription: entry.capabilities.transcription },
803
+ requestConfig: { transcription: entry.requestConfig.transcription }
804
+ } : resolveOpenAITranscriptionModelEntry(modelId);
805
+ }
806
+ function getOpenAIRealtimeModelEntry(modelId, api) {
807
+ const entry = findModelEntry(modelId);
808
+ if (entry?.capabilities.realtime != null && entry.requestConfig?.realtime != null && (api == null || entry.requestConfig.realtime.api === api)) return {
809
+ capabilities: { realtime: entry.capabilities.realtime },
810
+ requestConfig: { realtime: entry.requestConfig.realtime }
811
+ };
812
+ return api === "live" ? liveModelEntry : realtimeModelEntry;
813
+ }
313
814
  //#endregion
314
815
  //#region src/openai-stream-error.ts
315
816
  /**
@@ -459,6 +960,26 @@ function isRetryableStreamError(error, statusCode) {
459
960
  return isRetryableStatusCode(statusCode);
460
961
  }
461
962
  //#endregion
963
+ //#region src/resolve-openai-reasoning-effort.ts
964
+ const allOpenAIReasoningEfforts = [
965
+ "none",
966
+ "minimal",
967
+ "low",
968
+ "medium",
969
+ "high",
970
+ "xhigh",
971
+ "max"
972
+ ];
973
+ /** Resolve portable reasoning against the efforts declared by the catalog. */
974
+ function resolveOpenAIReasoningEffort({ providerReasoningEffort, reasoning, supportedReasoningEfforts, warnings }) {
975
+ return mapReasoningToProviderEffort({
976
+ reasoning,
977
+ providerOptionsEffort: providerReasoningEffort,
978
+ effortMap: Object.fromEntries((supportedReasoningEfforts ?? allOpenAIReasoningEfforts).map((effort) => [effort, effort])),
979
+ warnings
980
+ });
981
+ }
982
+ //#endregion
462
983
  //#region src/chat/convert-openai-chat-usage.ts
463
984
  function convertOpenAIChatUsage(usage) {
464
985
  if (usage == null) return createNullLanguageModelUsage();
@@ -1181,17 +1702,20 @@ var OpenAIChatLanguageModel = class OpenAIChatLanguageModel {
1181
1702
  providerOptions,
1182
1703
  schema: openaiLanguageModelChatOptions
1183
1704
  }) ?? {};
1184
- const modelCapabilities = getOpenAILanguageModelCapabilities(this.modelId);
1185
- let resolvedReasoningEffort = openaiOptions.reasoningEffort ?? (isCustomReasoning(reasoning) ? reasoning : void 0);
1186
- if (resolvedReasoningEffort != null && modelCapabilities.supportedReasoningEfforts != null && !modelCapabilities.supportedReasoningEfforts.includes(resolvedReasoningEffort)) {
1187
- warnings.push({
1188
- type: "unsupported",
1189
- feature: "reasoningEffort",
1190
- details: `${this.modelId} only supports the following reasoning efforts: ${modelCapabilities.supportedReasoningEfforts.join(", ")}`
1191
- });
1192
- resolvedReasoningEffort = void 0;
1193
- }
1194
- const isReasoningModel = openaiOptions.forceReasoning ?? modelCapabilities.isReasoningModel;
1705
+ const { capabilities: { language: modelCapabilities }, requestConfig: { language: modelRequestConfig } } = getOpenAILanguageModelEntry(this.modelId);
1706
+ const requiresNoReasoningEffort = !modelCapabilities.endpoints.chat.functionToolsWithReasoning && openaiOptions.reasoningEffort == null && (tools?.some((tool) => tool.type === "function") ?? false);
1707
+ if (requiresNoReasoningEffort && isCustomReasoning(reasoning) && reasoning !== "none") warnings.push({
1708
+ type: "compatibility",
1709
+ feature: "reasoning",
1710
+ 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.`
1711
+ });
1712
+ const resolvedReasoningEffort = requiresNoReasoningEffort ? "none" : resolveOpenAIReasoningEffort({
1713
+ providerReasoningEffort: openaiOptions.reasoningEffort,
1714
+ reasoning,
1715
+ supportedReasoningEfforts: modelCapabilities.reasoning.efforts?.filter((effort) => effort !== "max"),
1716
+ warnings
1717
+ });
1718
+ const isReasoningModel = openaiOptions.forceReasoning ?? modelCapabilities.reasoning.support === true;
1195
1719
  if (topK != null) warnings.push({
1196
1720
  type: "unsupported",
1197
1721
  feature: "topK"
@@ -1203,7 +1727,7 @@ var OpenAIChatLanguageModel = class OpenAIChatLanguageModel {
1203
1727
  });
1204
1728
  const { messages, warnings: messageWarnings } = convertToOpenAIChatMessages({
1205
1729
  prompt,
1206
- systemMessageMode: openaiOptions.systemMessageMode ?? (isReasoningModel ? "developer" : modelCapabilities.systemMessageMode)
1730
+ systemMessageMode: openaiOptions.systemMessageMode ?? (isReasoningModel ? "developer" : modelRequestConfig.systemMessageMode)
1207
1731
  });
1208
1732
  warnings.push(...messageWarnings);
1209
1733
  const strictJsonSchema = openaiOptions.strictJsonSchema ?? true;
@@ -1245,7 +1769,7 @@ var OpenAIChatLanguageModel = class OpenAIChatLanguageModel {
1245
1769
  safety_identifier: openaiOptions.safetyIdentifier,
1246
1770
  messages
1247
1771
  };
1248
- if (modelCapabilities.supportedReasoningEfforts != null && baseArgs.prompt_cache_retention != null) {
1772
+ if (!modelCapabilities.promptCache.retention && baseArgs.prompt_cache_retention != null) {
1249
1773
  baseArgs.prompt_cache_retention = void 0;
1250
1774
  warnings.push({
1251
1775
  type: "unsupported",
@@ -1254,7 +1778,7 @@ var OpenAIChatLanguageModel = class OpenAIChatLanguageModel {
1254
1778
  });
1255
1779
  }
1256
1780
  if (isReasoningModel) {
1257
- if (resolvedReasoningEffort !== "none" || !modelCapabilities.supportsNonReasoningParameters) {
1781
+ if (resolvedReasoningEffort !== "none" || modelCapabilities.reasoning.sampling !== "reasoning-effort-none") {
1258
1782
  if (baseArgs.temperature != null) {
1259
1783
  baseArgs.temperature = void 0;
1260
1784
  warnings.push({
@@ -1313,7 +1837,7 @@ var OpenAIChatLanguageModel = class OpenAIChatLanguageModel {
1313
1837
  if (baseArgs.max_completion_tokens == null) baseArgs.max_completion_tokens = baseArgs.max_tokens;
1314
1838
  baseArgs.max_tokens = void 0;
1315
1839
  }
1316
- } else if (this.modelId.startsWith("gpt-4o-search-preview") || this.modelId.startsWith("gpt-4o-mini-search-preview")) {
1840
+ } else if (!modelCapabilities.endpoints.chat.temperatureWithoutReasoning) {
1317
1841
  if (baseArgs.temperature != null) {
1318
1842
  baseArgs.temperature = void 0;
1319
1843
  warnings.push({
@@ -1323,7 +1847,7 @@ var OpenAIChatLanguageModel = class OpenAIChatLanguageModel {
1323
1847
  });
1324
1848
  }
1325
1849
  }
1326
- if (openaiOptions.serviceTier === "flex" && !modelCapabilities.supportsFlexProcessing) {
1850
+ if (openaiOptions.serviceTier === "flex" && !modelCapabilities.serviceTiers.flex) {
1327
1851
  warnings.push({
1328
1852
  type: "unsupported",
1329
1853
  feature: "serviceTier",
@@ -1331,7 +1855,7 @@ var OpenAIChatLanguageModel = class OpenAIChatLanguageModel {
1331
1855
  });
1332
1856
  baseArgs.service_tier = void 0;
1333
1857
  }
1334
- if ((openaiOptions.serviceTier === "priority" || openaiOptions.serviceTier === "fast") && !modelCapabilities.supportsPriorityProcessing) {
1858
+ if ((openaiOptions.serviceTier === "priority" || openaiOptions.serviceTier === "fast") && !modelCapabilities.serviceTiers.priority) {
1335
1859
  warnings.push({
1336
1860
  type: "unsupported",
1337
1861
  feature: "serviceTier",
@@ -1359,7 +1883,7 @@ var OpenAIChatLanguageModel = class OpenAIChatLanguageModel {
1359
1883
  path: "/chat/completions",
1360
1884
  modelId: this.config.requestModelId ?? this.modelId
1361
1885
  }),
1362
- headers: combineHeaders(this.config.headers?.(), options.headers),
1886
+ headers: combineHeaders(await resolve(this.config.headers), options.headers),
1363
1887
  body,
1364
1888
  failedResponseHandler: openaiFailedResponseHandler,
1365
1889
  successfulResponseHandler: createJsonResponseHandler(openaiChatResponseSchema),
@@ -1425,7 +1949,7 @@ var OpenAIChatLanguageModel = class OpenAIChatLanguageModel {
1425
1949
  });
1426
1950
  const { responseHeaders, value: response } = await postJsonToApi({
1427
1951
  url,
1428
- headers: combineHeaders(this.config.headers?.(), options.headers),
1952
+ headers: combineHeaders(await resolve(this.config.headers), options.headers),
1429
1953
  body,
1430
1954
  failedResponseHandler: openaiFailedResponseHandler,
1431
1955
  successfulResponseHandler: createEventSourceResponseHandler(openaiChatChunkSchema),
@@ -1802,7 +2326,7 @@ var OpenAICompletionLanguageModel = class OpenAICompletionLanguageModel {
1802
2326
  path: "/completions",
1803
2327
  modelId: this.config.requestModelId ?? this.modelId
1804
2328
  }),
1805
- headers: combineHeaders(this.config.headers?.(), options.headers),
2329
+ headers: combineHeaders(await resolve(this.config.headers), options.headers),
1806
2330
  body: args,
1807
2331
  failedResponseHandler: openaiFailedResponseHandler,
1808
2332
  successfulResponseHandler: createJsonResponseHandler(openaiCompletionResponseSchema),
@@ -1845,7 +2369,7 @@ var OpenAICompletionLanguageModel = class OpenAICompletionLanguageModel {
1845
2369
  });
1846
2370
  const { responseHeaders, value: response } = await postJsonToApi({
1847
2371
  url,
1848
- headers: combineHeaders(this.config.headers?.(), options.headers),
2372
+ headers: combineHeaders(await resolve(this.config.headers), options.headers),
1849
2373
  body,
1850
2374
  failedResponseHandler: openaiFailedResponseHandler,
1851
2375
  successfulResponseHandler: createEventSourceResponseHandler(openaiCompletionChunkSchema),
@@ -2008,7 +2532,7 @@ var OpenAIEmbeddingModel = class OpenAIEmbeddingModel {
2008
2532
  path: "/embeddings",
2009
2533
  modelId: this.modelId
2010
2534
  }),
2011
- headers: combineHeaders(this.config.headers?.(), headers),
2535
+ headers: combineHeaders(await resolve(this.config.headers), headers),
2012
2536
  body: {
2013
2537
  model: this.modelId,
2014
2538
  input: values,
@@ -2073,8 +2597,8 @@ var OpenAIFiles = class {
2073
2597
  });
2074
2598
  return fileId;
2075
2599
  }
2076
- getHeaders(headers) {
2077
- return combineHeaders(this.config.headers(), headers);
2600
+ async getHeaders(headers) {
2601
+ return combineHeaders(await resolve(this.config.headers), headers);
2078
2602
  }
2079
2603
  async uploadFile({ data, mediaType, filename, abortSignal, headers, providerOptions }) {
2080
2604
  let openaiOptions;
@@ -2089,7 +2613,7 @@ var OpenAIFiles = class {
2089
2613
  throw error;
2090
2614
  }
2091
2615
  const purpose = openaiOptions?.purpose ?? "assistants";
2092
- const requestHeaders = this.getHeaders(headers);
2616
+ const requestHeaders = await this.getHeaders(headers);
2093
2617
  const url = `${this.config.baseURL}/files`;
2094
2618
  let response;
2095
2619
  if (data.type === "stream") {
@@ -2159,7 +2683,7 @@ var OpenAIFiles = class {
2159
2683
  const fileId = this.getFileId(file);
2160
2684
  const { value: response } = await getFromApi({
2161
2685
  url: `${this.config.baseURL}/files/${encodePathSegment(fileId)}`,
2162
- headers: this.getHeaders(headers),
2686
+ headers: await this.getHeaders(headers),
2163
2687
  failedResponseHandler: openaiFailedResponseHandler,
2164
2688
  successfulResponseHandler: createJsonResponseHandler(openaiFilesResponseSchema),
2165
2689
  abortSignal,
@@ -2180,7 +2704,7 @@ var OpenAIFiles = class {
2180
2704
  const fileId = this.getFileId(file);
2181
2705
  const { value: content, responseHeaders } = await getFromApi({
2182
2706
  url: `${this.config.baseURL}/files/${encodePathSegment(fileId)}/content`,
2183
- headers: this.getHeaders(headers),
2707
+ headers: await this.getHeaders(headers),
2184
2708
  failedResponseHandler: openaiFailedResponseHandler,
2185
2709
  successfulResponseHandler: createBinaryStreamResponseHandler(),
2186
2710
  abortSignal,
@@ -2198,7 +2722,7 @@ var OpenAIFiles = class {
2198
2722
  const fileId = this.getFileId(file);
2199
2723
  const { value: response } = await deleteFromApi({
2200
2724
  url: `${this.config.baseURL}/files/${encodePathSegment(fileId)}`,
2201
- headers: this.getHeaders(headers),
2725
+ headers: await this.getHeaders(headers),
2202
2726
  failedResponseHandler: openaiFailedResponseHandler,
2203
2727
  successfulResponseHandler: createJsonResponseHandler(openaiFileDeleteResponseSchema),
2204
2728
  abortSignal,
@@ -2245,25 +2769,11 @@ const openaiImageResponseSchema = lazySchema(() => zodSchema(z.object({
2245
2769
  })));
2246
2770
  //#endregion
2247
2771
  //#region src/image/openai-image-model-options.ts
2248
- const modelMaxImagesPerCall = {
2249
- "dall-e-3": 1,
2250
- "dall-e-2": 10,
2251
- "gpt-image-1": 10,
2252
- "gpt-image-1-mini": 10,
2253
- "gpt-image-1.5": 10,
2254
- "gpt-image-2": 10,
2255
- "gpt-image-2.5-flare": 10,
2256
- "gpt-image-2.5-flare-2026-09-08": 10,
2257
- "gpt-image-2.5-sunburst": 10,
2258
- "gpt-image-2.5-sunburst-2026-09-08": 10,
2259
- "chatgpt-image-latest": 10
2260
- };
2261
- const defaultResponseFormatPrefixes = ["chatgpt-image-", "gpt-image-"];
2262
2772
  function hasDefaultResponseFormat(modelId) {
2263
- return defaultResponseFormatPrefixes.some((prefix) => modelId.startsWith(prefix));
2773
+ return getOpenAIImageModelEntry(modelId).requestConfig.image.responseFormat === "provider-default";
2264
2774
  }
2265
2775
  function getMaxImagesPerCall(modelId) {
2266
- return modelMaxImagesPerCall[modelId] ?? (modelId.startsWith("gpt-image-") ? 10 : 1);
2776
+ return getOpenAIImageModelEntry(modelId).capabilities.image.maxImagesPerCall ?? 1;
2267
2777
  }
2268
2778
  const baseImageModelOptionsObject = () => z.object({
2269
2779
  /**
@@ -2348,23 +2858,13 @@ var OpenAIImageModel = class OpenAIImageModel {
2348
2858
  }
2349
2859
  get supportsFileInputs() {
2350
2860
  if (this.config.imageInputCapabilities != null) return this.config.imageInputCapabilities.supportsFileInputs;
2351
- if ([
2352
- "dall-e-2",
2353
- "gpt-image-1",
2354
- "gpt-image-1-mini",
2355
- "gpt-image-1.5",
2356
- "gpt-image-2",
2357
- "gpt-image-2.5-flare",
2358
- "gpt-image-2.5-flare-2026-09-08",
2359
- "gpt-image-2.5-sunburst",
2360
- "gpt-image-2.5-sunburst-2026-09-08",
2361
- "chatgpt-image-latest"
2362
- ].includes(this.modelId)) return true;
2363
- return this.modelId === "dall-e-3" ? false : void 0;
2861
+ const support = getOpenAIImageModelEntry(this.modelId).capabilities.image.fileInput;
2862
+ return typeof support === "boolean" ? support : void 0;
2364
2863
  }
2365
2864
  get supportsMaskInputs() {
2366
2865
  if (this.config.imageInputCapabilities != null) return this.config.imageInputCapabilities.supportsMaskInputs;
2367
- return this.supportsFileInputs;
2866
+ const support = getOpenAIImageModelEntry(this.modelId).capabilities.image.maskInput;
2867
+ return typeof support === "boolean" ? support : void 0;
2368
2868
  }
2369
2869
  get provider() {
2370
2870
  return this.config.provider;
@@ -2397,7 +2897,7 @@ var OpenAIImageModel = class OpenAIImageModel {
2397
2897
  path: "/images/edits",
2398
2898
  modelId: this.modelId
2399
2899
  }),
2400
- headers: combineHeaders(this.config.headers?.(), headers),
2900
+ headers: combineHeaders(await resolve(this.config.headers), headers),
2401
2901
  formData: convertToFormData({
2402
2902
  model: this.modelId,
2403
2903
  prompt,
@@ -2451,7 +2951,7 @@ var OpenAIImageModel = class OpenAIImageModel {
2451
2951
  path: "/images/generations",
2452
2952
  modelId: this.modelId
2453
2953
  }),
2454
- headers: combineHeaders(this.config.headers?.(), headers),
2954
+ headers: combineHeaders(await resolve(this.config.headers), headers),
2455
2955
  body: {
2456
2956
  model: this.modelId,
2457
2957
  prompt,
@@ -6225,7 +6725,7 @@ const openaiResponsesSupportedUrls = {
6225
6725
  * @see https://developers.openai.com/api/docs/guides/reasoning#change-reasoning-mid-conversation
6226
6726
  */
6227
6727
  function getConfigurationUpdateUnsupportedReason({ modelCapabilities, options }) {
6228
- if (!modelCapabilities.supportsConfigurationUpdate) return "reasoningEffortUpdate is only supported by GPT-6 and later models";
6728
+ if (!modelCapabilities.configurationUpdates) return "reasoningEffortUpdate is only supported by GPT-6 and later models";
6229
6729
  if (options?.reasoningMode === "pro" || options?.contextManagement != null || options?.truncation === "auto") return "reasoningEffortUpdate requires standard reasoning mode without automatic compaction or automatic truncation";
6230
6730
  }
6231
6731
  var OpenAIResponsesLanguageModel = class OpenAIResponsesLanguageModel {
@@ -6249,7 +6749,7 @@ var OpenAIResponsesLanguageModel = class OpenAIResponsesLanguageModel {
6249
6749
  }
6250
6750
  static async prepareRequest({ modelId, config, options: { maxOutputTokens, temperature, stopSequences, topP, topK, presencePenalty, frequencyPenalty, seed, prompt, reasoning, providerOptions, tools, toolChoice, responseFormat } }) {
6251
6751
  const warnings = [];
6252
- const modelCapabilities = getOpenAILanguageModelCapabilities(modelId);
6752
+ const { capabilities: { language: modelCapabilities }, requestConfig: { language: modelRequestConfig } } = getOpenAILanguageModelEntry(modelId);
6253
6753
  if (topK != null) warnings.push({
6254
6754
  type: "unsupported",
6255
6755
  feature: "topK"
@@ -6281,17 +6781,14 @@ var OpenAIResponsesLanguageModel = class OpenAIResponsesLanguageModel {
6281
6781
  providerOptions,
6282
6782
  schema: openaiLanguageModelResponsesOptionsSchema
6283
6783
  });
6284
- let resolvedReasoningEffort = openaiOptions?.reasoningEffort ?? (isCustomReasoning(reasoning) ? reasoning : void 0);
6285
- if (resolvedReasoningEffort != null && modelCapabilities.supportedReasoningEfforts != null && !modelCapabilities.supportedReasoningEfforts.includes(resolvedReasoningEffort)) {
6286
- warnings.push({
6287
- type: "unsupported",
6288
- feature: "reasoningEffort",
6289
- details: `${modelId} only supports the following reasoning efforts: ${modelCapabilities.supportedReasoningEfforts.join(", ")}`
6290
- });
6291
- resolvedReasoningEffort = void 0;
6292
- }
6784
+ const resolvedReasoningEffort = resolveOpenAIReasoningEffort({
6785
+ providerReasoningEffort: openaiOptions?.reasoningEffort,
6786
+ reasoning,
6787
+ supportedReasoningEfforts: modelCapabilities.reasoning.efforts,
6788
+ warnings
6789
+ });
6293
6790
  const resolvedReasoningSummary = openaiOptions?.reasoningSummary !== void 0 ? openaiOptions.reasoningSummary : resolvedReasoningEffort != null && resolvedReasoningEffort !== "none" ? "detailed" : void 0;
6294
- const isReasoningModel = openaiOptions?.forceReasoning ?? modelCapabilities.isReasoningModel;
6791
+ const isReasoningModel = openaiOptions?.forceReasoning ?? modelCapabilities.reasoning.support === true;
6295
6792
  if (openaiOptions?.conversation && openaiOptions?.previousResponseId) warnings.push({
6296
6793
  type: "unsupported",
6297
6794
  feature: "conversation",
@@ -6323,7 +6820,7 @@ var OpenAIResponsesLanguageModel = class OpenAIResponsesLanguageModel {
6323
6820
  toolNameMapping,
6324
6821
  customProviderToolNames,
6325
6822
  outputSchemaToolNames,
6326
- supportsAsyncToolCalling: modelCapabilities.supportsAsyncToolCalling,
6823
+ supportsAsyncToolCalling: modelCapabilities.tools.async,
6327
6824
  providerOptionsName
6328
6825
  });
6329
6826
  const configurationUpdateUnsupportedReason = getConfigurationUpdateUnsupportedReason({
@@ -6333,7 +6830,7 @@ var OpenAIResponsesLanguageModel = class OpenAIResponsesLanguageModel {
6333
6830
  const { input, warnings: inputWarnings } = await convertToOpenAIResponsesInput({
6334
6831
  prompt,
6335
6832
  toolNameMapping,
6336
- systemMessageMode: openaiOptions?.systemMessageMode ?? (isReasoningModel ? "developer" : modelCapabilities.systemMessageMode),
6833
+ systemMessageMode: openaiOptions?.systemMessageMode ?? (isReasoningModel ? "developer" : modelRequestConfig.systemMessageMode),
6337
6834
  providerOptionsName,
6338
6835
  configurationUpdateUnsupportedReason,
6339
6836
  explicitMessageItemType: config.explicitMessageItemType,
@@ -6352,7 +6849,8 @@ var OpenAIResponsesLanguageModel = class OpenAIResponsesLanguageModel {
6352
6849
  outputSchemaToolNames: outputSchemaToolNames.size > 0 ? outputSchemaToolNames : void 0
6353
6850
  });
6354
6851
  warnings.push(...inputWarnings);
6355
- const getUpdateEffortUnsupportedReason = (effort) => effort != null && modelCapabilities.supportedReasoningEfforts?.includes(effort) === false ? `${modelId} only supports the following reasoning efforts: ${modelCapabilities.supportedReasoningEfforts.join(", ")}` : void 0;
6852
+ const supportedReasoningEfforts = modelCapabilities.reasoning.efforts;
6853
+ const getUpdateEffortUnsupportedReason = (effort) => effort != null && supportedReasoningEfforts?.includes(effort) === false ? `${modelId} only supports the following reasoning efforts: ${supportedReasoningEfforts.join(", ")}` : void 0;
6356
6854
  for (const item of input) if (item.type === "configuration_update") {
6357
6855
  const unsupportedReason = getUpdateEffortUnsupportedReason(item.reasoning.effort);
6358
6856
  if (unsupportedReason != null) throw new UnsupportedFunctionalityError({
@@ -6440,7 +6938,7 @@ var OpenAIResponsesLanguageModel = class OpenAIResponsesLanguageModel {
6440
6938
  ...openaiOptions?.reasoningContext != null && { context: openaiOptions.reasoningContext }
6441
6939
  } }
6442
6940
  };
6443
- if (modelCapabilities.supportsConfigurationUpdate && baseArgs.prompt_cache_retention != null) {
6941
+ if (!modelCapabilities.promptCache.retention && baseArgs.prompt_cache_retention != null) {
6444
6942
  baseArgs.prompt_cache_retention = void 0;
6445
6943
  warnings.push({
6446
6944
  type: "unsupported",
@@ -6451,7 +6949,7 @@ var OpenAIResponsesLanguageModel = class OpenAIResponsesLanguageModel {
6451
6949
  if (isReasoningModel) {
6452
6950
  let effectiveReasoningEffort = resolvedReasoningEffort;
6453
6951
  for (const item of input) if (item.type === "configuration_update") effectiveReasoningEffort = item.reasoning.effort;
6454
- if (!(effectiveReasoningEffort === "none" && modelCapabilities.supportsNonReasoningParameters)) {
6952
+ if (!(effectiveReasoningEffort === "none" && modelCapabilities.reasoning.sampling === "reasoning-effort-none")) {
6455
6953
  if (baseArgs.temperature != null) {
6456
6954
  baseArgs.temperature = void 0;
6457
6955
  warnings.push({
@@ -6468,7 +6966,7 @@ var OpenAIResponsesLanguageModel = class OpenAIResponsesLanguageModel {
6468
6966
  details: "topP is not supported for reasoning models"
6469
6967
  });
6470
6968
  }
6471
- if (modelCapabilities.supportedReasoningEfforts != null && (baseArgs.top_logprobs != null || baseArgs.include?.includes("message.output_text.logprobs"))) {
6969
+ if (modelCapabilities.endpoints.responses.logprobsRequireNonReasoning && (baseArgs.top_logprobs != null || baseArgs.include?.includes("message.output_text.logprobs"))) {
6472
6970
  baseArgs.top_logprobs = void 0;
6473
6971
  const filteredInclude = baseArgs.include?.filter((value) => value !== "message.output_text.logprobs");
6474
6972
  baseArgs.include = filteredInclude != null && filteredInclude.length > 0 ? filteredInclude : void 0;
@@ -6501,7 +6999,7 @@ var OpenAIResponsesLanguageModel = class OpenAIResponsesLanguageModel {
6501
6999
  details: "reasoningContext is not supported for non-reasoning models"
6502
7000
  });
6503
7001
  }
6504
- if (openaiOptions?.serviceTier === "flex" && !modelCapabilities.supportsFlexProcessing) {
7002
+ if (openaiOptions?.serviceTier === "flex" && !modelCapabilities.serviceTiers.flex) {
6505
7003
  warnings.push({
6506
7004
  type: "unsupported",
6507
7005
  feature: "serviceTier",
@@ -6509,7 +7007,7 @@ var OpenAIResponsesLanguageModel = class OpenAIResponsesLanguageModel {
6509
7007
  });
6510
7008
  delete baseArgs.service_tier;
6511
7009
  }
6512
- if ((openaiOptions?.serviceTier === "priority" || openaiOptions?.serviceTier === "fast") && !modelCapabilities.supportsPriorityProcessing) {
7010
+ if ((openaiOptions?.serviceTier === "priority" || openaiOptions?.serviceTier === "fast") && !modelCapabilities.serviceTiers.priority) {
6513
7011
  warnings.push({
6514
7012
  type: "unsupported",
6515
7013
  feature: "serviceTier",
@@ -6549,7 +7047,7 @@ var OpenAIResponsesLanguageModel = class OpenAIResponsesLanguageModel {
6549
7047
  const approvalRequestIdToDummyToolCallIdFromPrompt = extractApprovalRequestIdToToolCallIdMapping(options.prompt);
6550
7048
  const { responseHeaders, value: response, rawValue: rawResponse } = await postJsonToApi({
6551
7049
  url,
6552
- headers: combineHeaders(this.config.headers?.(), options.headers),
7050
+ headers: combineHeaders(await resolve(this.config.headers), options.headers),
6553
7051
  body,
6554
7052
  failedResponseHandler: openaiFailedResponseHandler,
6555
7053
  successfulResponseHandler: createJsonResponseHandler(openaiResponsesResponseSchema),
@@ -6999,7 +7497,7 @@ var OpenAIResponsesLanguageModel = class OpenAIResponsesLanguageModel {
6999
7497
  });
7000
7498
  const { responseHeaders, value: response } = await postJsonToApi({
7001
7499
  url,
7002
- headers: combineHeaders(this.config.headers?.(), options.headers),
7500
+ headers: combineHeaders(await resolve(this.config.headers), options.headers),
7003
7501
  body: {
7004
7502
  ...body,
7005
7503
  stream: true
@@ -8152,7 +8650,7 @@ var OpenAIBatch = class {
8152
8650
  formData.append("expires_after[seconds]", String(inputFileExpiresAfterSeconds));
8153
8651
  const { value: uploadedFile } = await postToApi({
8154
8652
  url: this.getUrl("/files"),
8155
- headers: combineHeaders(this.options.config.headers?.(), options.headers),
8653
+ headers: combineHeaders(await resolve(this.options.config.headers), options.headers),
8156
8654
  body: {
8157
8655
  content: formData,
8158
8656
  values: {
@@ -8173,7 +8671,7 @@ var OpenAIBatch = class {
8173
8671
  });
8174
8672
  const { value: batch } = await postJsonToApi({
8175
8673
  url: this.getUrl("/batches"),
8176
- headers: combineHeaders(this.options.config.headers?.(), options.headers),
8674
+ headers: combineHeaders(await resolve(this.options.config.headers), options.headers),
8177
8675
  body: {
8178
8676
  input_file_id: uploadedFile.id,
8179
8677
  endpoint: openaiBatchEndpoint,
@@ -8215,7 +8713,7 @@ var OpenAIBatch = class {
8215
8713
  async doCancelBatch(options) {
8216
8714
  await postJsonToApi({
8217
8715
  url: this.getUrl(`/batches/${encodeURIComponent(options.batchId)}/cancel`),
8218
- headers: combineHeaders(this.options.config.headers?.(), options.headers),
8716
+ headers: combineHeaders(await resolve(this.options.config.headers), options.headers),
8219
8717
  body: {},
8220
8718
  failedResponseHandler: openaiFailedResponseHandler,
8221
8719
  successfulResponseHandler: createJsonResponseHandler(openaiBatchResponseSchema),
@@ -8230,7 +8728,7 @@ var OpenAIBatch = class {
8230
8728
  if (options.cursor != null) url.searchParams.set("after", options.cursor);
8231
8729
  const { value: page } = await getFromApi({
8232
8730
  url: url.toString(),
8233
- headers: combineHeaders(this.options.config.headers?.(), options.headers),
8731
+ headers: combineHeaders(await resolve(this.options.config.headers), options.headers),
8234
8732
  failedResponseHandler: openaiFailedResponseHandler,
8235
8733
  successfulResponseHandler: createJsonResponseHandler(openaiBatchListResponseSchema),
8236
8734
  abortSignal: options.abortSignal,
@@ -8266,7 +8764,7 @@ var OpenAIBatch = class {
8266
8764
  async retrieveBatch(options) {
8267
8765
  const { value: batch } = await getFromApi({
8268
8766
  url: this.getUrl(`/batches/${encodeURIComponent(options.batchId)}`),
8269
- headers: combineHeaders(this.options.config.headers?.(), options.headers),
8767
+ headers: combineHeaders(await resolve(this.options.config.headers), options.headers),
8270
8768
  failedResponseHandler: openaiFailedResponseHandler,
8271
8769
  successfulResponseHandler: createJsonResponseHandler(openaiBatchResponseSchema),
8272
8770
  abortSignal: options.abortSignal,
@@ -8279,7 +8777,7 @@ var OpenAIBatch = class {
8279
8777
  for (const fileId of fileIds) {
8280
8778
  const { value: lines } = await getFromApi({
8281
8779
  url: this.getUrl(`/files/${encodeURIComponent(fileId)}/content`),
8282
- headers: combineHeaders(this.options.config.headers?.(), options.headers),
8780
+ headers: combineHeaders(await resolve(this.options.config.headers), options.headers),
8283
8781
  failedResponseHandler: openaiFailedResponseHandler,
8284
8782
  successfulResponseHandler: createJsonLinesResponseHandler(openaiBatchResultLineSchema, { maxLineBytes: this.options.maxLineBytes }),
8285
8783
  abortSignal: options.abortSignal,
@@ -8952,13 +9450,7 @@ var OpenAIRealtimeModelLive = class {
8952
9450
  this.modelId = modelId;
8953
9451
  this.config = config;
8954
9452
  this.specificationVersion = "v4";
8955
- this.capabilities = {
8956
- conversation: "continuous",
8957
- transports: ["websocket", "webrtc"],
8958
- connections: ["server-websocket", "webrtc"],
8959
- startup: "session-start",
8960
- finalization: "session-close"
8961
- };
9453
+ this.capabilities = openaiLiveRealtimeCapabilities;
8962
9454
  }
8963
9455
  get provider() {
8964
9456
  return this.config.provider;
@@ -8967,20 +9459,22 @@ var OpenAIRealtimeModelLive = class {
8967
9459
  return { dataChannelLabel: "oai-events" };
8968
9460
  }
8969
9461
  getServerWebSocketConfig() {
8970
- const url = new URL(`${this.config.baseURL}/live/sessions`);
8971
- url.protocol = url.protocol === "http:" ? "ws:" : "wss:";
8972
- const headers = {};
8973
- for (const [key, value] of Object.entries(this.config.headers())) if (value !== void 0) headers[key] = value;
8974
- return {
8975
- url: url.toString(),
8976
- headers
8977
- };
9462
+ return resolveWith(this.config.headers, (configHeaders) => {
9463
+ const url = new URL(`${this.config.baseURL}/live/sessions`);
9464
+ url.protocol = url.protocol === "http:" ? "ws:" : "wss:";
9465
+ const headers = {};
9466
+ for (const [key, value] of Object.entries(configHeaders)) if (value !== void 0) headers[key] = value;
9467
+ return {
9468
+ url: url.toString(),
9469
+ headers
9470
+ };
9471
+ });
8978
9472
  }
8979
9473
  async doCreateWebRTCSession({ sdp, sessionConfig = {}, abortSignal }) {
8980
9474
  const session = buildOpenAILiveSessionConfig(sessionConfig, this.modelId, "webrtc");
8981
9475
  const { value } = await postJsonToApi({
8982
9476
  url: `${this.config.baseURL}/live/sessions`,
8983
- headers: this.config.headers(),
9477
+ headers: await resolve(this.config.headers),
8984
9478
  body: {
8985
9479
  session,
8986
9480
  transport: {
@@ -9309,7 +9803,7 @@ var OpenAIRealtimeModel = class {
9309
9803
  const response = await fetchFn(url, {
9310
9804
  method: "POST",
9311
9805
  headers: {
9312
- ...this.config.headers(),
9806
+ ...await resolve(this.config.headers),
9313
9807
  "Content-Type": "application/json"
9314
9808
  },
9315
9809
  body: JSON.stringify({
@@ -9349,7 +9843,6 @@ var OpenAIRealtimeModel = class {
9349
9843
  };
9350
9844
  //#endregion
9351
9845
  //#region src/realtime/openai-realtime-factory.ts
9352
- const knownLiveModelIds = ["gpt-live-1"];
9353
9846
  function resolveRealtimeApi(modelId, { api } = {}) {
9354
9847
  if (api !== void 0) {
9355
9848
  if (api !== "live" && api !== "realtime") throw new InvalidArgumentError({
@@ -9358,7 +9851,7 @@ function resolveRealtimeApi(modelId, { api } = {}) {
9358
9851
  });
9359
9852
  return api;
9360
9853
  }
9361
- return knownLiveModelIds.some((knownModelId) => knownModelId === modelId) ? "live" : "realtime";
9854
+ return getOpenAIRealtimeModelEntry(modelId).requestConfig.realtime.api;
9362
9855
  }
9363
9856
  function createOpenAIRealtimeFactory(config) {
9364
9857
  const createModel = (modelId, options) => {
@@ -9467,7 +9960,7 @@ var OpenAISpeechModel = class OpenAISpeechModel {
9467
9960
  path: "/audio/speech",
9468
9961
  modelId: this.modelId
9469
9962
  }),
9470
- headers: combineHeaders(this.config.headers?.(), options.headers),
9963
+ headers: combineHeaders(await resolve(this.config.headers), options.headers),
9471
9964
  body: requestBody,
9472
9965
  failedResponseHandler: openaiFailedResponseHandler,
9473
9966
  successfulResponseHandler: createBinaryResponseHandler(),
@@ -9584,34 +10077,6 @@ const openAITranscriptionModelOptions = lazySchema(() => zodSchema(z.object({
9584
10077
  })));
9585
10078
  //#endregion
9586
10079
  //#region src/transcription/openai-transcription-model.ts
9587
- /**
9588
- * Whether `modelId` is `base` or one of its dated snapshots
9589
- * (e.g. `gpt-realtime-whisper-2026-01-01`).
9590
- */
9591
- function isModelOrSnapshot(modelId, base) {
9592
- return modelId === base || modelId.startsWith(`${base}-`);
9593
- }
9594
- /**
9595
- * Model IDs that stream over the realtime transcription WebSocket and do not
9596
- * support the REST transcription endpoint.
9597
- */
9598
- function isRealtimeTranscriptionModelId(modelId) {
9599
- return isModelOrSnapshot(modelId, "gpt-realtime-whisper") || isModelOrSnapshot(modelId, "gpt-live-transcribe");
9600
- }
9601
- /**
9602
- * Model IDs that support streaming transcription. `gpt-transcribe` also
9603
- * supports the REST transcription endpoint.
9604
- */
9605
- function supportsStreamingTranscription(modelId) {
9606
- return isRealtimeTranscriptionModelId(modelId) || isModelOrSnapshot(modelId, "gpt-transcribe");
9607
- }
9608
- /**
9609
- * Models whose realtime transcription session takes a `languages` list
9610
- * instead of the singular `language` field.
9611
- */
9612
- function usesLanguagesList(modelId) {
9613
- return isModelOrSnapshot(modelId, "gpt-live-transcribe") || isModelOrSnapshot(modelId, "gpt-transcribe");
9614
- }
9615
10080
  const languageMap = {
9616
10081
  afrikaans: "af",
9617
10082
  arabic: "ar",
@@ -9704,10 +10169,10 @@ var OpenAITranscriptionModel = class OpenAITranscriptionModel {
9704
10169
  formData.append("model", this.modelId);
9705
10170
  const fileExtension = mediaTypeToExtension(mediaType);
9706
10171
  formData.append("file", new File([blob], "audio", { type: mediaType }), `audio.${fileExtension}`);
9707
- const isDiarizationModel = this.modelId === "gpt-4o-transcribe-diarize";
9708
- const responseFormat = openAIOptions?.responseFormat ?? (isDiarizationModel ? "diarized_json" : this.modelId === "whisper-1" ? "verbose_json" : void 0);
10172
+ const { transcription: requestConfig } = getOpenAITranscriptionModelEntry(this.modelId).requestConfig;
10173
+ const responseFormat = openAIOptions?.responseFormat ?? requestConfig.responseFormat;
9709
10174
  const timestampGranularities = openAIOptions?.timestampGranularities ?? (responseFormat === "verbose_json" ? ["segment"] : void 0);
9710
- const chunkingStrategy = openAIOptions?.chunkingStrategy ?? (isDiarizationModel ? "auto" : void 0);
10175
+ const chunkingStrategy = openAIOptions?.chunkingStrategy ?? requestConfig.chunkingStrategy;
9711
10176
  const transcriptionModelOptions = {
9712
10177
  response_format: responseFormat,
9713
10178
  include: openAIOptions?.include,
@@ -9732,7 +10197,7 @@ var OpenAITranscriptionModel = class OpenAITranscriptionModel {
9732
10197
  };
9733
10198
  }
9734
10199
  async doGenerate(options) {
9735
- if (isRealtimeTranscriptionModelId(this.modelId)) throw new UnsupportedFunctionalityError({ functionality: `non-streaming transcription with ${this.modelId}` });
10200
+ if (getOpenAITranscriptionModelEntry(this.modelId).capabilities.transcription.transcription === false) throw new UnsupportedFunctionalityError({ functionality: `non-streaming transcription with ${this.modelId}` });
9736
10201
  const currentDate = this.config._internal?.currentDate?.() ?? /* @__PURE__ */ new Date();
9737
10202
  const { formData, warnings } = await this.getArgs(options);
9738
10203
  const { value: response, responseHeaders, rawValue: rawResponse } = await postFormDataToApi({
@@ -9740,7 +10205,7 @@ var OpenAITranscriptionModel = class OpenAITranscriptionModel {
9740
10205
  path: "/audio/transcriptions",
9741
10206
  modelId: this.modelId
9742
10207
  }),
9743
- headers: combineHeaders(this.config.headers?.(), options.headers),
10208
+ headers: combineHeaders(await resolve(this.config.headers), options.headers),
9744
10209
  formData,
9745
10210
  failedResponseHandler: openaiFailedResponseHandler,
9746
10211
  successfulResponseHandler: createJsonResponseHandler(openaiTranscriptionResponseSchema),
@@ -9782,7 +10247,8 @@ var OpenAITranscriptionModel = class OpenAITranscriptionModel {
9782
10247
  };
9783
10248
  }
9784
10249
  async doStream(options) {
9785
- if (!supportsStreamingTranscription(this.modelId)) throw new UnsupportedFunctionalityError({ functionality: `streaming transcription with ${this.modelId}` });
10250
+ const entry = getOpenAITranscriptionModelEntry(this.modelId);
10251
+ if (entry.capabilities.transcription.streaming !== true) throw new UnsupportedFunctionalityError({ functionality: `streaming transcription with ${this.modelId}` });
9786
10252
  const currentDate = this.config._internal?.currentDate?.() ?? /* @__PURE__ */ new Date();
9787
10253
  const openAIOptions = await parseProviderOptions({
9788
10254
  provider: "openai",
@@ -9801,13 +10267,13 @@ var OpenAITranscriptionModel = class OpenAITranscriptionModel {
9801
10267
  feature: `providerOptions.openai.${option}`,
9802
10268
  details: `OpenAI streaming transcription does not support ${option}.`
9803
10269
  });
9804
- const supportsDelay = !isModelOrSnapshot(this.modelId, "gpt-transcribe");
10270
+ const supportsDelay = entry.capabilities.transcription.streamingDelay === true;
9805
10271
  if (!supportsDelay && openAIOptions?.streaming?.delay != null) warnings.push({
9806
10272
  type: "unsupported",
9807
10273
  feature: "providerOptions.openai.streaming.delay",
9808
10274
  details: `OpenAI streaming transcription with ${this.modelId} does not support delay.`
9809
10275
  });
9810
- const headers = combineHeaders(this.config.headers?.(), options.headers);
10276
+ const headers = combineHeaders(await resolve(this.config.headers), options.headers);
9811
10277
  const sessionUpdate = buildOpenAIRealtimeTranscriptionSession({
9812
10278
  modelId: this.modelId,
9813
10279
  inputAudioFormat: options.inputAudioFormat,
@@ -9959,7 +10425,7 @@ function buildOpenAIRealtimeTranscriptionSession({ modelId, inputAudioFormat, pr
9959
10425
  },
9960
10426
  transcription: {
9961
10427
  model: modelId,
9962
- ...providerOptions?.language != null ? usesLanguagesList(modelId) ? { languages: [providerOptions.language] } : { language: providerOptions.language } : {},
10428
+ ...providerOptions?.language != null ? getOpenAITranscriptionModelEntry(modelId).requestConfig.transcription.languageField === "languages" ? { languages: [providerOptions.language] } : { language: providerOptions.language } : {},
9963
10429
  ...supportsDelay && providerOptions?.streaming?.delay != null ? { delay: providerOptions.streaming.delay } : {}
9964
10430
  },
9965
10431
  turn_detection: null
@@ -10027,7 +10493,7 @@ var OpenAISpeechTranslationModel = class OpenAISpeechTranslationModel {
10027
10493
  feature: "outputAudioFormat",
10028
10494
  details: "The OpenAI Realtime translation API always outputs 24kHz 16-bit PCM audio and does not accept an output audio format."
10029
10495
  });
10030
- const headers = combineHeaders(this.config.headers?.(), options.headers);
10496
+ const headers = combineHeaders(await resolve(this.config.headers), options.headers);
10031
10497
  const sessionUpdate = buildOpenAIRealtimeSpeechTranslationSession({ targetLanguage: options.targetLanguage });
10032
10498
  return {
10033
10499
  request: { body: sessionUpdate },
@@ -10252,7 +10718,7 @@ var OpenAISkills = class {
10252
10718
  }
10253
10719
  const { value: response } = await postFormDataToApi({
10254
10720
  url: this.config.url({ path: "/skills" }),
10255
- headers: combineHeaders(this.config.headers()),
10721
+ headers: combineHeaders(await resolve(this.config.headers)),
10256
10722
  formData,
10257
10723
  failedResponseHandler: openaiFailedResponseHandler,
10258
10724
  successfulResponseHandler: createJsonResponseHandler(openaiSkillResponseSchema),
@@ -10274,7 +10740,7 @@ var OpenAISkills = class {
10274
10740
  };
10275
10741
  //#endregion
10276
10742
  //#region src/version.ts
10277
- const VERSION = "4.0.104";
10743
+ const VERSION = "4.0.106";
10278
10744
  //#endregion
10279
10745
  //#region src/openai-provider.ts
10280
10746
  /**
@@ -10286,16 +10752,16 @@ function createOpenAI(options = {}) {
10286
10752
  environmentVariableName: "OPENAI_BASE_URL"
10287
10753
  }))) ?? "https://api.openai.com/v1";
10288
10754
  const providerName = options.name ?? "openai";
10289
- const getHeaders = () => withUserAgentSuffix({
10755
+ const getHeaders = () => resolveWith(options.apiKey, (apiKey) => withUserAgentSuffix({
10290
10756
  Authorization: `Bearer ${loadApiKey({
10291
- apiKey: options.apiKey,
10757
+ apiKey,
10292
10758
  environmentVariableName: "OPENAI_API_KEY",
10293
10759
  description: "OpenAI"
10294
10760
  })}`,
10295
10761
  "OpenAI-Organization": options.organization,
10296
10762
  "OpenAI-Project": options.project,
10297
10763
  ...options.headers
10298
- }, `ai-sdk-openai/${VERSION}`);
10764
+ }, `ai-sdk-openai/${VERSION}`));
10299
10765
  const createChatModel = (modelId) => new OpenAIChatLanguageModel(modelId, {
10300
10766
  provider: `${providerName}.chat`,
10301
10767
  url: ({ path }) => `${baseURL}${path}`,