@ai-sdk/openai 4.0.105 → 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.
- package/CHANGELOG.md +15 -0
- package/dist/index.d.ts +49 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +570 -188
- package/dist/index.js.map +1 -1
- package/dist/internal/index.d.ts +4 -4
- package/dist/internal/index.d.ts.map +1 -1
- package/dist/internal/index.js +524 -150
- package/dist/internal/index.js.map +1 -1
- package/docs/03-openai.mdx +91 -5
- package/package.json +3 -3
- package/src/chat/openai-chat-language-model.ts +27 -20
- package/src/completion/openai-completion-language-model.ts +11 -3
- package/src/embedding/openai-embedding-model.ts +2 -1
- package/src/files/openai-files.ts +10 -8
- package/src/image/openai-image-model-options.ts +10 -20
- package/src/image/openai-image-model.ts +10 -21
- package/src/live/openai-realtime-model-live.ts +15 -16
- package/src/openai-batch.ts +22 -6
- package/src/openai-config.ts +2 -1
- package/src/openai-decision-model.ts +2 -1
- package/src/openai-model-catalog.ts +935 -0
- package/src/openai-provider.ts +18 -13
- package/src/realtime/openai-realtime-factory.ts +6 -6
- package/src/realtime/openai-realtime-model.ts +7 -3
- package/src/resolve-openai-reasoning-effort.ts +45 -0
- package/src/responses/openai-responses-language-model.ts +28 -22
- package/src/skills/openai-skills.ts +4 -2
- package/src/speech/openai-speech-model.ts +5 -1
- package/src/speech-translation/openai-speech-translation-model.ts +5 -1
- package/src/transcription/openai-transcription-model.ts +25 -56
- package/src/openai-language-model-capabilities.ts +0 -196
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, mapReasoningToProviderEffort, 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
|
|
@@ -119,7 +119,7 @@ var DecisionOpenAIModel = class DecisionOpenAIModel {
|
|
|
119
119
|
path: "/decisions",
|
|
120
120
|
modelId: this.modelId
|
|
121
121
|
}),
|
|
122
|
-
headers: combineHeaders(this.config.headers
|
|
122
|
+
headers: combineHeaders(await resolve(this.config.headers), headers),
|
|
123
123
|
body: {
|
|
124
124
|
model: this.modelId,
|
|
125
125
|
safety_identifier: openaiOptions?.safetyIdentifier,
|
|
@@ -288,54 +288,182 @@ function isJSONObject$1(value) {
|
|
|
288
288
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
289
289
|
}
|
|
290
290
|
//#endregion
|
|
291
|
-
//#region src/openai-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
"
|
|
299
|
-
"
|
|
300
|
-
|
|
301
|
-
|
|
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) {
|
|
302
384
|
const oSeriesVersion = getOSeriesVersion(modelId);
|
|
303
385
|
const gptVersion = getGptVersion(modelId);
|
|
386
|
+
const isRecognizedModelFamily = oSeriesVersion != null || gptVersion != null || /^gpt-4o(?:-|$)/.test(modelId);
|
|
304
387
|
const isGptChatModel = gptVersion?.minor == null && (gptVersion?.variant?.startsWith("chat") ?? false);
|
|
305
388
|
const isGptNanoModel = gptVersion?.variant?.startsWith("nano") ?? false;
|
|
306
389
|
const isGpt6OrLaterModel = gptVersion != null && gptVersion.major >= 6;
|
|
390
|
+
const isGpt56OrLaterModel = isGpt6OrLaterModel || gptVersion?.major === 5 && (gptVersion.minor ?? 0) >= 6;
|
|
307
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));
|
|
308
|
-
const isGpt6OrLaterModelWithNoneEffort = modelId === "gpt-6-sol" || modelId === "gpt-6-luna" || modelId === "gpt-6.1-terra";
|
|
309
392
|
const supportsFlexProcessing = oSeriesVersion != null && oSeriesVersion >= 3 || gptVersion != null && gptVersion.major >= 5 && !isGptChatModel;
|
|
310
393
|
const supportsPriorityProcessing = modelId.startsWith("gpt-4") || gptVersion != null && gptVersion.major >= 5 && !isGptNanoModel && !isGptChatModel || oSeriesVersion != null && oSeriesVersion >= 3;
|
|
311
394
|
const isReasoningModel = oSeriesVersion != null || gptVersion != null && gptVersion.major >= 5 && !isGptChatModel;
|
|
312
|
-
const
|
|
313
|
-
const
|
|
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;
|
|
314
446
|
return {
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
"high",
|
|
330
|
-
"xhigh",
|
|
331
|
-
"max"
|
|
332
|
-
] : isStandardGpt5Model ? getGpt5ReasoningEfforts(gptVersion.minor ?? 0) : void 0,
|
|
333
|
-
supportsChatFunctionToolsWithReasoning: !(gptVersion?.major === 5 && (gptVersion.minor ?? 0) >= 6),
|
|
334
|
-
isReasoningModel,
|
|
335
|
-
systemMessageMode,
|
|
336
|
-
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
|
+
}) }
|
|
337
461
|
};
|
|
338
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
|
+
}
|
|
339
467
|
function getGpt5ReasoningEfforts(minor) {
|
|
340
468
|
if (minor === 0) return [
|
|
341
469
|
"minimal",
|
|
@@ -371,27 +499,317 @@ function getOSeriesVersion(modelId) {
|
|
|
371
499
|
}
|
|
372
500
|
function getGptVersion(modelId) {
|
|
373
501
|
const match = /^gpt-(\d+)(?:\.(\d+))?(?:-(.+))?$/.exec(modelId);
|
|
374
|
-
|
|
375
|
-
return {
|
|
502
|
+
return match == null ? void 0 : {
|
|
376
503
|
major: Number(match[1]),
|
|
377
504
|
minor: match[2] == null ? void 0 : Number(match[2]),
|
|
378
505
|
variant: match[3]
|
|
379
506
|
};
|
|
380
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
|
+
};
|
|
381
746
|
/**
|
|
382
|
-
*
|
|
383
|
-
*
|
|
384
|
-
*
|
|
385
|
-
* top-level reasoning value is mapped to the closest effort that the model
|
|
386
|
-
* family supports, or sent directly when the supported efforts are not known.
|
|
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.
|
|
387
750
|
*/
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
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;
|
|
395
813
|
}
|
|
396
814
|
//#endregion
|
|
397
815
|
//#region src/openai-stream-error.ts
|
|
@@ -542,6 +960,26 @@ function isRetryableStreamError(error, statusCode) {
|
|
|
542
960
|
return isRetryableStatusCode(statusCode);
|
|
543
961
|
}
|
|
544
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
|
|
545
983
|
//#region src/chat/convert-openai-chat-usage.ts
|
|
546
984
|
function convertOpenAIChatUsage(usage) {
|
|
547
985
|
if (usage == null) return createNullLanguageModelUsage();
|
|
@@ -1264,8 +1702,8 @@ var OpenAIChatLanguageModel = class OpenAIChatLanguageModel {
|
|
|
1264
1702
|
providerOptions,
|
|
1265
1703
|
schema: openaiLanguageModelChatOptions
|
|
1266
1704
|
}) ?? {};
|
|
1267
|
-
const modelCapabilities =
|
|
1268
|
-
const requiresNoReasoningEffort = !modelCapabilities.
|
|
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);
|
|
1269
1707
|
if (requiresNoReasoningEffort && isCustomReasoning(reasoning) && reasoning !== "none") warnings.push({
|
|
1270
1708
|
type: "compatibility",
|
|
1271
1709
|
feature: "reasoning",
|
|
@@ -1274,10 +1712,10 @@ var OpenAIChatLanguageModel = class OpenAIChatLanguageModel {
|
|
|
1274
1712
|
const resolvedReasoningEffort = requiresNoReasoningEffort ? "none" : resolveOpenAIReasoningEffort({
|
|
1275
1713
|
providerReasoningEffort: openaiOptions.reasoningEffort,
|
|
1276
1714
|
reasoning,
|
|
1277
|
-
supportedReasoningEfforts: modelCapabilities.
|
|
1715
|
+
supportedReasoningEfforts: modelCapabilities.reasoning.efforts?.filter((effort) => effort !== "max"),
|
|
1278
1716
|
warnings
|
|
1279
1717
|
});
|
|
1280
|
-
const isReasoningModel = openaiOptions.forceReasoning ?? modelCapabilities.
|
|
1718
|
+
const isReasoningModel = openaiOptions.forceReasoning ?? modelCapabilities.reasoning.support === true;
|
|
1281
1719
|
if (topK != null) warnings.push({
|
|
1282
1720
|
type: "unsupported",
|
|
1283
1721
|
feature: "topK"
|
|
@@ -1289,7 +1727,7 @@ var OpenAIChatLanguageModel = class OpenAIChatLanguageModel {
|
|
|
1289
1727
|
});
|
|
1290
1728
|
const { messages, warnings: messageWarnings } = convertToOpenAIChatMessages({
|
|
1291
1729
|
prompt,
|
|
1292
|
-
systemMessageMode: openaiOptions.systemMessageMode ?? (isReasoningModel ? "developer" :
|
|
1730
|
+
systemMessageMode: openaiOptions.systemMessageMode ?? (isReasoningModel ? "developer" : modelRequestConfig.systemMessageMode)
|
|
1293
1731
|
});
|
|
1294
1732
|
warnings.push(...messageWarnings);
|
|
1295
1733
|
const strictJsonSchema = openaiOptions.strictJsonSchema ?? true;
|
|
@@ -1331,7 +1769,7 @@ var OpenAIChatLanguageModel = class OpenAIChatLanguageModel {
|
|
|
1331
1769
|
safety_identifier: openaiOptions.safetyIdentifier,
|
|
1332
1770
|
messages
|
|
1333
1771
|
};
|
|
1334
|
-
if (modelCapabilities.
|
|
1772
|
+
if (!modelCapabilities.promptCache.retention && baseArgs.prompt_cache_retention != null) {
|
|
1335
1773
|
baseArgs.prompt_cache_retention = void 0;
|
|
1336
1774
|
warnings.push({
|
|
1337
1775
|
type: "unsupported",
|
|
@@ -1340,7 +1778,7 @@ var OpenAIChatLanguageModel = class OpenAIChatLanguageModel {
|
|
|
1340
1778
|
});
|
|
1341
1779
|
}
|
|
1342
1780
|
if (isReasoningModel) {
|
|
1343
|
-
if (resolvedReasoningEffort !== "none" ||
|
|
1781
|
+
if (resolvedReasoningEffort !== "none" || modelCapabilities.reasoning.sampling !== "reasoning-effort-none") {
|
|
1344
1782
|
if (baseArgs.temperature != null) {
|
|
1345
1783
|
baseArgs.temperature = void 0;
|
|
1346
1784
|
warnings.push({
|
|
@@ -1399,7 +1837,7 @@ var OpenAIChatLanguageModel = class OpenAIChatLanguageModel {
|
|
|
1399
1837
|
if (baseArgs.max_completion_tokens == null) baseArgs.max_completion_tokens = baseArgs.max_tokens;
|
|
1400
1838
|
baseArgs.max_tokens = void 0;
|
|
1401
1839
|
}
|
|
1402
|
-
} else if (
|
|
1840
|
+
} else if (!modelCapabilities.endpoints.chat.temperatureWithoutReasoning) {
|
|
1403
1841
|
if (baseArgs.temperature != null) {
|
|
1404
1842
|
baseArgs.temperature = void 0;
|
|
1405
1843
|
warnings.push({
|
|
@@ -1409,7 +1847,7 @@ var OpenAIChatLanguageModel = class OpenAIChatLanguageModel {
|
|
|
1409
1847
|
});
|
|
1410
1848
|
}
|
|
1411
1849
|
}
|
|
1412
|
-
if (openaiOptions.serviceTier === "flex" && !modelCapabilities.
|
|
1850
|
+
if (openaiOptions.serviceTier === "flex" && !modelCapabilities.serviceTiers.flex) {
|
|
1413
1851
|
warnings.push({
|
|
1414
1852
|
type: "unsupported",
|
|
1415
1853
|
feature: "serviceTier",
|
|
@@ -1417,7 +1855,7 @@ var OpenAIChatLanguageModel = class OpenAIChatLanguageModel {
|
|
|
1417
1855
|
});
|
|
1418
1856
|
baseArgs.service_tier = void 0;
|
|
1419
1857
|
}
|
|
1420
|
-
if ((openaiOptions.serviceTier === "priority" || openaiOptions.serviceTier === "fast") && !modelCapabilities.
|
|
1858
|
+
if ((openaiOptions.serviceTier === "priority" || openaiOptions.serviceTier === "fast") && !modelCapabilities.serviceTiers.priority) {
|
|
1421
1859
|
warnings.push({
|
|
1422
1860
|
type: "unsupported",
|
|
1423
1861
|
feature: "serviceTier",
|
|
@@ -1445,7 +1883,7 @@ var OpenAIChatLanguageModel = class OpenAIChatLanguageModel {
|
|
|
1445
1883
|
path: "/chat/completions",
|
|
1446
1884
|
modelId: this.config.requestModelId ?? this.modelId
|
|
1447
1885
|
}),
|
|
1448
|
-
headers: combineHeaders(this.config.headers
|
|
1886
|
+
headers: combineHeaders(await resolve(this.config.headers), options.headers),
|
|
1449
1887
|
body,
|
|
1450
1888
|
failedResponseHandler: openaiFailedResponseHandler,
|
|
1451
1889
|
successfulResponseHandler: createJsonResponseHandler(openaiChatResponseSchema),
|
|
@@ -1511,7 +1949,7 @@ var OpenAIChatLanguageModel = class OpenAIChatLanguageModel {
|
|
|
1511
1949
|
});
|
|
1512
1950
|
const { responseHeaders, value: response } = await postJsonToApi({
|
|
1513
1951
|
url,
|
|
1514
|
-
headers: combineHeaders(this.config.headers
|
|
1952
|
+
headers: combineHeaders(await resolve(this.config.headers), options.headers),
|
|
1515
1953
|
body,
|
|
1516
1954
|
failedResponseHandler: openaiFailedResponseHandler,
|
|
1517
1955
|
successfulResponseHandler: createEventSourceResponseHandler(openaiChatChunkSchema),
|
|
@@ -1888,7 +2326,7 @@ var OpenAICompletionLanguageModel = class OpenAICompletionLanguageModel {
|
|
|
1888
2326
|
path: "/completions",
|
|
1889
2327
|
modelId: this.config.requestModelId ?? this.modelId
|
|
1890
2328
|
}),
|
|
1891
|
-
headers: combineHeaders(this.config.headers
|
|
2329
|
+
headers: combineHeaders(await resolve(this.config.headers), options.headers),
|
|
1892
2330
|
body: args,
|
|
1893
2331
|
failedResponseHandler: openaiFailedResponseHandler,
|
|
1894
2332
|
successfulResponseHandler: createJsonResponseHandler(openaiCompletionResponseSchema),
|
|
@@ -1931,7 +2369,7 @@ var OpenAICompletionLanguageModel = class OpenAICompletionLanguageModel {
|
|
|
1931
2369
|
});
|
|
1932
2370
|
const { responseHeaders, value: response } = await postJsonToApi({
|
|
1933
2371
|
url,
|
|
1934
|
-
headers: combineHeaders(this.config.headers
|
|
2372
|
+
headers: combineHeaders(await resolve(this.config.headers), options.headers),
|
|
1935
2373
|
body,
|
|
1936
2374
|
failedResponseHandler: openaiFailedResponseHandler,
|
|
1937
2375
|
successfulResponseHandler: createEventSourceResponseHandler(openaiCompletionChunkSchema),
|
|
@@ -2094,7 +2532,7 @@ var OpenAIEmbeddingModel = class OpenAIEmbeddingModel {
|
|
|
2094
2532
|
path: "/embeddings",
|
|
2095
2533
|
modelId: this.modelId
|
|
2096
2534
|
}),
|
|
2097
|
-
headers: combineHeaders(this.config.headers
|
|
2535
|
+
headers: combineHeaders(await resolve(this.config.headers), headers),
|
|
2098
2536
|
body: {
|
|
2099
2537
|
model: this.modelId,
|
|
2100
2538
|
input: values,
|
|
@@ -2159,8 +2597,8 @@ var OpenAIFiles = class {
|
|
|
2159
2597
|
});
|
|
2160
2598
|
return fileId;
|
|
2161
2599
|
}
|
|
2162
|
-
getHeaders(headers) {
|
|
2163
|
-
return combineHeaders(this.config.headers
|
|
2600
|
+
async getHeaders(headers) {
|
|
2601
|
+
return combineHeaders(await resolve(this.config.headers), headers);
|
|
2164
2602
|
}
|
|
2165
2603
|
async uploadFile({ data, mediaType, filename, abortSignal, headers, providerOptions }) {
|
|
2166
2604
|
let openaiOptions;
|
|
@@ -2175,7 +2613,7 @@ var OpenAIFiles = class {
|
|
|
2175
2613
|
throw error;
|
|
2176
2614
|
}
|
|
2177
2615
|
const purpose = openaiOptions?.purpose ?? "assistants";
|
|
2178
|
-
const requestHeaders = this.getHeaders(headers);
|
|
2616
|
+
const requestHeaders = await this.getHeaders(headers);
|
|
2179
2617
|
const url = `${this.config.baseURL}/files`;
|
|
2180
2618
|
let response;
|
|
2181
2619
|
if (data.type === "stream") {
|
|
@@ -2245,7 +2683,7 @@ var OpenAIFiles = class {
|
|
|
2245
2683
|
const fileId = this.getFileId(file);
|
|
2246
2684
|
const { value: response } = await getFromApi({
|
|
2247
2685
|
url: `${this.config.baseURL}/files/${encodePathSegment(fileId)}`,
|
|
2248
|
-
headers: this.getHeaders(headers),
|
|
2686
|
+
headers: await this.getHeaders(headers),
|
|
2249
2687
|
failedResponseHandler: openaiFailedResponseHandler,
|
|
2250
2688
|
successfulResponseHandler: createJsonResponseHandler(openaiFilesResponseSchema),
|
|
2251
2689
|
abortSignal,
|
|
@@ -2266,7 +2704,7 @@ var OpenAIFiles = class {
|
|
|
2266
2704
|
const fileId = this.getFileId(file);
|
|
2267
2705
|
const { value: content, responseHeaders } = await getFromApi({
|
|
2268
2706
|
url: `${this.config.baseURL}/files/${encodePathSegment(fileId)}/content`,
|
|
2269
|
-
headers: this.getHeaders(headers),
|
|
2707
|
+
headers: await this.getHeaders(headers),
|
|
2270
2708
|
failedResponseHandler: openaiFailedResponseHandler,
|
|
2271
2709
|
successfulResponseHandler: createBinaryStreamResponseHandler(),
|
|
2272
2710
|
abortSignal,
|
|
@@ -2284,7 +2722,7 @@ var OpenAIFiles = class {
|
|
|
2284
2722
|
const fileId = this.getFileId(file);
|
|
2285
2723
|
const { value: response } = await deleteFromApi({
|
|
2286
2724
|
url: `${this.config.baseURL}/files/${encodePathSegment(fileId)}`,
|
|
2287
|
-
headers: this.getHeaders(headers),
|
|
2725
|
+
headers: await this.getHeaders(headers),
|
|
2288
2726
|
failedResponseHandler: openaiFailedResponseHandler,
|
|
2289
2727
|
successfulResponseHandler: createJsonResponseHandler(openaiFileDeleteResponseSchema),
|
|
2290
2728
|
abortSignal,
|
|
@@ -2331,25 +2769,11 @@ const openaiImageResponseSchema = lazySchema(() => zodSchema(z.object({
|
|
|
2331
2769
|
})));
|
|
2332
2770
|
//#endregion
|
|
2333
2771
|
//#region src/image/openai-image-model-options.ts
|
|
2334
|
-
const modelMaxImagesPerCall = {
|
|
2335
|
-
"dall-e-3": 1,
|
|
2336
|
-
"dall-e-2": 10,
|
|
2337
|
-
"gpt-image-1": 10,
|
|
2338
|
-
"gpt-image-1-mini": 10,
|
|
2339
|
-
"gpt-image-1.5": 10,
|
|
2340
|
-
"gpt-image-2": 10,
|
|
2341
|
-
"gpt-image-2.5-flare": 10,
|
|
2342
|
-
"gpt-image-2.5-flare-2026-09-08": 10,
|
|
2343
|
-
"gpt-image-2.5-sunburst": 10,
|
|
2344
|
-
"gpt-image-2.5-sunburst-2026-09-08": 10,
|
|
2345
|
-
"chatgpt-image-latest": 10
|
|
2346
|
-
};
|
|
2347
|
-
const defaultResponseFormatPrefixes = ["chatgpt-image-", "gpt-image-"];
|
|
2348
2772
|
function hasDefaultResponseFormat(modelId) {
|
|
2349
|
-
return
|
|
2773
|
+
return getOpenAIImageModelEntry(modelId).requestConfig.image.responseFormat === "provider-default";
|
|
2350
2774
|
}
|
|
2351
2775
|
function getMaxImagesPerCall(modelId) {
|
|
2352
|
-
return
|
|
2776
|
+
return getOpenAIImageModelEntry(modelId).capabilities.image.maxImagesPerCall ?? 1;
|
|
2353
2777
|
}
|
|
2354
2778
|
const baseImageModelOptionsObject = () => z.object({
|
|
2355
2779
|
/**
|
|
@@ -2434,23 +2858,13 @@ var OpenAIImageModel = class OpenAIImageModel {
|
|
|
2434
2858
|
}
|
|
2435
2859
|
get supportsFileInputs() {
|
|
2436
2860
|
if (this.config.imageInputCapabilities != null) return this.config.imageInputCapabilities.supportsFileInputs;
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
"gpt-image-1",
|
|
2440
|
-
"gpt-image-1-mini",
|
|
2441
|
-
"gpt-image-1.5",
|
|
2442
|
-
"gpt-image-2",
|
|
2443
|
-
"gpt-image-2.5-flare",
|
|
2444
|
-
"gpt-image-2.5-flare-2026-09-08",
|
|
2445
|
-
"gpt-image-2.5-sunburst",
|
|
2446
|
-
"gpt-image-2.5-sunburst-2026-09-08",
|
|
2447
|
-
"chatgpt-image-latest"
|
|
2448
|
-
].includes(this.modelId)) return true;
|
|
2449
|
-
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;
|
|
2450
2863
|
}
|
|
2451
2864
|
get supportsMaskInputs() {
|
|
2452
2865
|
if (this.config.imageInputCapabilities != null) return this.config.imageInputCapabilities.supportsMaskInputs;
|
|
2453
|
-
|
|
2866
|
+
const support = getOpenAIImageModelEntry(this.modelId).capabilities.image.maskInput;
|
|
2867
|
+
return typeof support === "boolean" ? support : void 0;
|
|
2454
2868
|
}
|
|
2455
2869
|
get provider() {
|
|
2456
2870
|
return this.config.provider;
|
|
@@ -2483,7 +2897,7 @@ var OpenAIImageModel = class OpenAIImageModel {
|
|
|
2483
2897
|
path: "/images/edits",
|
|
2484
2898
|
modelId: this.modelId
|
|
2485
2899
|
}),
|
|
2486
|
-
headers: combineHeaders(this.config.headers
|
|
2900
|
+
headers: combineHeaders(await resolve(this.config.headers), headers),
|
|
2487
2901
|
formData: convertToFormData({
|
|
2488
2902
|
model: this.modelId,
|
|
2489
2903
|
prompt,
|
|
@@ -2537,7 +2951,7 @@ var OpenAIImageModel = class OpenAIImageModel {
|
|
|
2537
2951
|
path: "/images/generations",
|
|
2538
2952
|
modelId: this.modelId
|
|
2539
2953
|
}),
|
|
2540
|
-
headers: combineHeaders(this.config.headers
|
|
2954
|
+
headers: combineHeaders(await resolve(this.config.headers), headers),
|
|
2541
2955
|
body: {
|
|
2542
2956
|
model: this.modelId,
|
|
2543
2957
|
prompt,
|
|
@@ -6311,7 +6725,7 @@ const openaiResponsesSupportedUrls = {
|
|
|
6311
6725
|
* @see https://developers.openai.com/api/docs/guides/reasoning#change-reasoning-mid-conversation
|
|
6312
6726
|
*/
|
|
6313
6727
|
function getConfigurationUpdateUnsupportedReason({ modelCapabilities, options }) {
|
|
6314
|
-
if (!modelCapabilities.
|
|
6728
|
+
if (!modelCapabilities.configurationUpdates) return "reasoningEffortUpdate is only supported by GPT-6 and later models";
|
|
6315
6729
|
if (options?.reasoningMode === "pro" || options?.contextManagement != null || options?.truncation === "auto") return "reasoningEffortUpdate requires standard reasoning mode without automatic compaction or automatic truncation";
|
|
6316
6730
|
}
|
|
6317
6731
|
var OpenAIResponsesLanguageModel = class OpenAIResponsesLanguageModel {
|
|
@@ -6335,7 +6749,7 @@ var OpenAIResponsesLanguageModel = class OpenAIResponsesLanguageModel {
|
|
|
6335
6749
|
}
|
|
6336
6750
|
static async prepareRequest({ modelId, config, options: { maxOutputTokens, temperature, stopSequences, topP, topK, presencePenalty, frequencyPenalty, seed, prompt, reasoning, providerOptions, tools, toolChoice, responseFormat } }) {
|
|
6337
6751
|
const warnings = [];
|
|
6338
|
-
const modelCapabilities =
|
|
6752
|
+
const { capabilities: { language: modelCapabilities }, requestConfig: { language: modelRequestConfig } } = getOpenAILanguageModelEntry(modelId);
|
|
6339
6753
|
if (topK != null) warnings.push({
|
|
6340
6754
|
type: "unsupported",
|
|
6341
6755
|
feature: "topK"
|
|
@@ -6370,11 +6784,11 @@ var OpenAIResponsesLanguageModel = class OpenAIResponsesLanguageModel {
|
|
|
6370
6784
|
const resolvedReasoningEffort = resolveOpenAIReasoningEffort({
|
|
6371
6785
|
providerReasoningEffort: openaiOptions?.reasoningEffort,
|
|
6372
6786
|
reasoning,
|
|
6373
|
-
supportedReasoningEfforts: modelCapabilities.
|
|
6787
|
+
supportedReasoningEfforts: modelCapabilities.reasoning.efforts,
|
|
6374
6788
|
warnings
|
|
6375
6789
|
});
|
|
6376
6790
|
const resolvedReasoningSummary = openaiOptions?.reasoningSummary !== void 0 ? openaiOptions.reasoningSummary : resolvedReasoningEffort != null && resolvedReasoningEffort !== "none" ? "detailed" : void 0;
|
|
6377
|
-
const isReasoningModel = openaiOptions?.forceReasoning ?? modelCapabilities.
|
|
6791
|
+
const isReasoningModel = openaiOptions?.forceReasoning ?? modelCapabilities.reasoning.support === true;
|
|
6378
6792
|
if (openaiOptions?.conversation && openaiOptions?.previousResponseId) warnings.push({
|
|
6379
6793
|
type: "unsupported",
|
|
6380
6794
|
feature: "conversation",
|
|
@@ -6406,7 +6820,7 @@ var OpenAIResponsesLanguageModel = class OpenAIResponsesLanguageModel {
|
|
|
6406
6820
|
toolNameMapping,
|
|
6407
6821
|
customProviderToolNames,
|
|
6408
6822
|
outputSchemaToolNames,
|
|
6409
|
-
supportsAsyncToolCalling: modelCapabilities.
|
|
6823
|
+
supportsAsyncToolCalling: modelCapabilities.tools.async,
|
|
6410
6824
|
providerOptionsName
|
|
6411
6825
|
});
|
|
6412
6826
|
const configurationUpdateUnsupportedReason = getConfigurationUpdateUnsupportedReason({
|
|
@@ -6416,7 +6830,7 @@ var OpenAIResponsesLanguageModel = class OpenAIResponsesLanguageModel {
|
|
|
6416
6830
|
const { input, warnings: inputWarnings } = await convertToOpenAIResponsesInput({
|
|
6417
6831
|
prompt,
|
|
6418
6832
|
toolNameMapping,
|
|
6419
|
-
systemMessageMode: openaiOptions?.systemMessageMode ?? (isReasoningModel ? "developer" :
|
|
6833
|
+
systemMessageMode: openaiOptions?.systemMessageMode ?? (isReasoningModel ? "developer" : modelRequestConfig.systemMessageMode),
|
|
6420
6834
|
providerOptionsName,
|
|
6421
6835
|
configurationUpdateUnsupportedReason,
|
|
6422
6836
|
explicitMessageItemType: config.explicitMessageItemType,
|
|
@@ -6435,7 +6849,7 @@ var OpenAIResponsesLanguageModel = class OpenAIResponsesLanguageModel {
|
|
|
6435
6849
|
outputSchemaToolNames: outputSchemaToolNames.size > 0 ? outputSchemaToolNames : void 0
|
|
6436
6850
|
});
|
|
6437
6851
|
warnings.push(...inputWarnings);
|
|
6438
|
-
const supportedReasoningEfforts = modelCapabilities.
|
|
6852
|
+
const supportedReasoningEfforts = modelCapabilities.reasoning.efforts;
|
|
6439
6853
|
const getUpdateEffortUnsupportedReason = (effort) => effort != null && supportedReasoningEfforts?.includes(effort) === false ? `${modelId} only supports the following reasoning efforts: ${supportedReasoningEfforts.join(", ")}` : void 0;
|
|
6440
6854
|
for (const item of input) if (item.type === "configuration_update") {
|
|
6441
6855
|
const unsupportedReason = getUpdateEffortUnsupportedReason(item.reasoning.effort);
|
|
@@ -6524,7 +6938,7 @@ var OpenAIResponsesLanguageModel = class OpenAIResponsesLanguageModel {
|
|
|
6524
6938
|
...openaiOptions?.reasoningContext != null && { context: openaiOptions.reasoningContext }
|
|
6525
6939
|
} }
|
|
6526
6940
|
};
|
|
6527
|
-
if (modelCapabilities.
|
|
6941
|
+
if (!modelCapabilities.promptCache.retention && baseArgs.prompt_cache_retention != null) {
|
|
6528
6942
|
baseArgs.prompt_cache_retention = void 0;
|
|
6529
6943
|
warnings.push({
|
|
6530
6944
|
type: "unsupported",
|
|
@@ -6535,7 +6949,7 @@ var OpenAIResponsesLanguageModel = class OpenAIResponsesLanguageModel {
|
|
|
6535
6949
|
if (isReasoningModel) {
|
|
6536
6950
|
let effectiveReasoningEffort = resolvedReasoningEffort;
|
|
6537
6951
|
for (const item of input) if (item.type === "configuration_update") effectiveReasoningEffort = item.reasoning.effort;
|
|
6538
|
-
if (!(effectiveReasoningEffort === "none" && modelCapabilities.
|
|
6952
|
+
if (!(effectiveReasoningEffort === "none" && modelCapabilities.reasoning.sampling === "reasoning-effort-none")) {
|
|
6539
6953
|
if (baseArgs.temperature != null) {
|
|
6540
6954
|
baseArgs.temperature = void 0;
|
|
6541
6955
|
warnings.push({
|
|
@@ -6552,7 +6966,7 @@ var OpenAIResponsesLanguageModel = class OpenAIResponsesLanguageModel {
|
|
|
6552
6966
|
details: "topP is not supported for reasoning models"
|
|
6553
6967
|
});
|
|
6554
6968
|
}
|
|
6555
|
-
if (modelCapabilities.
|
|
6969
|
+
if (modelCapabilities.endpoints.responses.logprobsRequireNonReasoning && (baseArgs.top_logprobs != null || baseArgs.include?.includes("message.output_text.logprobs"))) {
|
|
6556
6970
|
baseArgs.top_logprobs = void 0;
|
|
6557
6971
|
const filteredInclude = baseArgs.include?.filter((value) => value !== "message.output_text.logprobs");
|
|
6558
6972
|
baseArgs.include = filteredInclude != null && filteredInclude.length > 0 ? filteredInclude : void 0;
|
|
@@ -6585,7 +6999,7 @@ var OpenAIResponsesLanguageModel = class OpenAIResponsesLanguageModel {
|
|
|
6585
6999
|
details: "reasoningContext is not supported for non-reasoning models"
|
|
6586
7000
|
});
|
|
6587
7001
|
}
|
|
6588
|
-
if (openaiOptions?.serviceTier === "flex" && !modelCapabilities.
|
|
7002
|
+
if (openaiOptions?.serviceTier === "flex" && !modelCapabilities.serviceTiers.flex) {
|
|
6589
7003
|
warnings.push({
|
|
6590
7004
|
type: "unsupported",
|
|
6591
7005
|
feature: "serviceTier",
|
|
@@ -6593,7 +7007,7 @@ var OpenAIResponsesLanguageModel = class OpenAIResponsesLanguageModel {
|
|
|
6593
7007
|
});
|
|
6594
7008
|
delete baseArgs.service_tier;
|
|
6595
7009
|
}
|
|
6596
|
-
if ((openaiOptions?.serviceTier === "priority" || openaiOptions?.serviceTier === "fast") && !modelCapabilities.
|
|
7010
|
+
if ((openaiOptions?.serviceTier === "priority" || openaiOptions?.serviceTier === "fast") && !modelCapabilities.serviceTiers.priority) {
|
|
6597
7011
|
warnings.push({
|
|
6598
7012
|
type: "unsupported",
|
|
6599
7013
|
feature: "serviceTier",
|
|
@@ -6633,7 +7047,7 @@ var OpenAIResponsesLanguageModel = class OpenAIResponsesLanguageModel {
|
|
|
6633
7047
|
const approvalRequestIdToDummyToolCallIdFromPrompt = extractApprovalRequestIdToToolCallIdMapping(options.prompt);
|
|
6634
7048
|
const { responseHeaders, value: response, rawValue: rawResponse } = await postJsonToApi({
|
|
6635
7049
|
url,
|
|
6636
|
-
headers: combineHeaders(this.config.headers
|
|
7050
|
+
headers: combineHeaders(await resolve(this.config.headers), options.headers),
|
|
6637
7051
|
body,
|
|
6638
7052
|
failedResponseHandler: openaiFailedResponseHandler,
|
|
6639
7053
|
successfulResponseHandler: createJsonResponseHandler(openaiResponsesResponseSchema),
|
|
@@ -7083,7 +7497,7 @@ var OpenAIResponsesLanguageModel = class OpenAIResponsesLanguageModel {
|
|
|
7083
7497
|
});
|
|
7084
7498
|
const { responseHeaders, value: response } = await postJsonToApi({
|
|
7085
7499
|
url,
|
|
7086
|
-
headers: combineHeaders(this.config.headers
|
|
7500
|
+
headers: combineHeaders(await resolve(this.config.headers), options.headers),
|
|
7087
7501
|
body: {
|
|
7088
7502
|
...body,
|
|
7089
7503
|
stream: true
|
|
@@ -8236,7 +8650,7 @@ var OpenAIBatch = class {
|
|
|
8236
8650
|
formData.append("expires_after[seconds]", String(inputFileExpiresAfterSeconds));
|
|
8237
8651
|
const { value: uploadedFile } = await postToApi({
|
|
8238
8652
|
url: this.getUrl("/files"),
|
|
8239
|
-
headers: combineHeaders(this.options.config.headers
|
|
8653
|
+
headers: combineHeaders(await resolve(this.options.config.headers), options.headers),
|
|
8240
8654
|
body: {
|
|
8241
8655
|
content: formData,
|
|
8242
8656
|
values: {
|
|
@@ -8257,7 +8671,7 @@ var OpenAIBatch = class {
|
|
|
8257
8671
|
});
|
|
8258
8672
|
const { value: batch } = await postJsonToApi({
|
|
8259
8673
|
url: this.getUrl("/batches"),
|
|
8260
|
-
headers: combineHeaders(this.options.config.headers
|
|
8674
|
+
headers: combineHeaders(await resolve(this.options.config.headers), options.headers),
|
|
8261
8675
|
body: {
|
|
8262
8676
|
input_file_id: uploadedFile.id,
|
|
8263
8677
|
endpoint: openaiBatchEndpoint,
|
|
@@ -8299,7 +8713,7 @@ var OpenAIBatch = class {
|
|
|
8299
8713
|
async doCancelBatch(options) {
|
|
8300
8714
|
await postJsonToApi({
|
|
8301
8715
|
url: this.getUrl(`/batches/${encodeURIComponent(options.batchId)}/cancel`),
|
|
8302
|
-
headers: combineHeaders(this.options.config.headers
|
|
8716
|
+
headers: combineHeaders(await resolve(this.options.config.headers), options.headers),
|
|
8303
8717
|
body: {},
|
|
8304
8718
|
failedResponseHandler: openaiFailedResponseHandler,
|
|
8305
8719
|
successfulResponseHandler: createJsonResponseHandler(openaiBatchResponseSchema),
|
|
@@ -8314,7 +8728,7 @@ var OpenAIBatch = class {
|
|
|
8314
8728
|
if (options.cursor != null) url.searchParams.set("after", options.cursor);
|
|
8315
8729
|
const { value: page } = await getFromApi({
|
|
8316
8730
|
url: url.toString(),
|
|
8317
|
-
headers: combineHeaders(this.options.config.headers
|
|
8731
|
+
headers: combineHeaders(await resolve(this.options.config.headers), options.headers),
|
|
8318
8732
|
failedResponseHandler: openaiFailedResponseHandler,
|
|
8319
8733
|
successfulResponseHandler: createJsonResponseHandler(openaiBatchListResponseSchema),
|
|
8320
8734
|
abortSignal: options.abortSignal,
|
|
@@ -8350,7 +8764,7 @@ var OpenAIBatch = class {
|
|
|
8350
8764
|
async retrieveBatch(options) {
|
|
8351
8765
|
const { value: batch } = await getFromApi({
|
|
8352
8766
|
url: this.getUrl(`/batches/${encodeURIComponent(options.batchId)}`),
|
|
8353
|
-
headers: combineHeaders(this.options.config.headers
|
|
8767
|
+
headers: combineHeaders(await resolve(this.options.config.headers), options.headers),
|
|
8354
8768
|
failedResponseHandler: openaiFailedResponseHandler,
|
|
8355
8769
|
successfulResponseHandler: createJsonResponseHandler(openaiBatchResponseSchema),
|
|
8356
8770
|
abortSignal: options.abortSignal,
|
|
@@ -8363,7 +8777,7 @@ var OpenAIBatch = class {
|
|
|
8363
8777
|
for (const fileId of fileIds) {
|
|
8364
8778
|
const { value: lines } = await getFromApi({
|
|
8365
8779
|
url: this.getUrl(`/files/${encodeURIComponent(fileId)}/content`),
|
|
8366
|
-
headers: combineHeaders(this.options.config.headers
|
|
8780
|
+
headers: combineHeaders(await resolve(this.options.config.headers), options.headers),
|
|
8367
8781
|
failedResponseHandler: openaiFailedResponseHandler,
|
|
8368
8782
|
successfulResponseHandler: createJsonLinesResponseHandler(openaiBatchResultLineSchema, { maxLineBytes: this.options.maxLineBytes }),
|
|
8369
8783
|
abortSignal: options.abortSignal,
|
|
@@ -9036,13 +9450,7 @@ var OpenAIRealtimeModelLive = class {
|
|
|
9036
9450
|
this.modelId = modelId;
|
|
9037
9451
|
this.config = config;
|
|
9038
9452
|
this.specificationVersion = "v4";
|
|
9039
|
-
this.capabilities =
|
|
9040
|
-
conversation: "continuous",
|
|
9041
|
-
transports: ["websocket", "webrtc"],
|
|
9042
|
-
connections: ["server-websocket", "webrtc"],
|
|
9043
|
-
startup: "session-start",
|
|
9044
|
-
finalization: "session-close"
|
|
9045
|
-
};
|
|
9453
|
+
this.capabilities = openaiLiveRealtimeCapabilities;
|
|
9046
9454
|
}
|
|
9047
9455
|
get provider() {
|
|
9048
9456
|
return this.config.provider;
|
|
@@ -9051,20 +9459,22 @@ var OpenAIRealtimeModelLive = class {
|
|
|
9051
9459
|
return { dataChannelLabel: "oai-events" };
|
|
9052
9460
|
}
|
|
9053
9461
|
getServerWebSocketConfig() {
|
|
9054
|
-
|
|
9055
|
-
|
|
9056
|
-
|
|
9057
|
-
|
|
9058
|
-
|
|
9059
|
-
|
|
9060
|
-
|
|
9061
|
-
|
|
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
|
+
});
|
|
9062
9472
|
}
|
|
9063
9473
|
async doCreateWebRTCSession({ sdp, sessionConfig = {}, abortSignal }) {
|
|
9064
9474
|
const session = buildOpenAILiveSessionConfig(sessionConfig, this.modelId, "webrtc");
|
|
9065
9475
|
const { value } = await postJsonToApi({
|
|
9066
9476
|
url: `${this.config.baseURL}/live/sessions`,
|
|
9067
|
-
headers: this.config.headers
|
|
9477
|
+
headers: await resolve(this.config.headers),
|
|
9068
9478
|
body: {
|
|
9069
9479
|
session,
|
|
9070
9480
|
transport: {
|
|
@@ -9393,7 +9803,7 @@ var OpenAIRealtimeModel = class {
|
|
|
9393
9803
|
const response = await fetchFn(url, {
|
|
9394
9804
|
method: "POST",
|
|
9395
9805
|
headers: {
|
|
9396
|
-
...this.config.headers
|
|
9806
|
+
...await resolve(this.config.headers),
|
|
9397
9807
|
"Content-Type": "application/json"
|
|
9398
9808
|
},
|
|
9399
9809
|
body: JSON.stringify({
|
|
@@ -9433,7 +9843,6 @@ var OpenAIRealtimeModel = class {
|
|
|
9433
9843
|
};
|
|
9434
9844
|
//#endregion
|
|
9435
9845
|
//#region src/realtime/openai-realtime-factory.ts
|
|
9436
|
-
const knownLiveModelIds = ["gpt-live-1"];
|
|
9437
9846
|
function resolveRealtimeApi(modelId, { api } = {}) {
|
|
9438
9847
|
if (api !== void 0) {
|
|
9439
9848
|
if (api !== "live" && api !== "realtime") throw new InvalidArgumentError({
|
|
@@ -9442,7 +9851,7 @@ function resolveRealtimeApi(modelId, { api } = {}) {
|
|
|
9442
9851
|
});
|
|
9443
9852
|
return api;
|
|
9444
9853
|
}
|
|
9445
|
-
return
|
|
9854
|
+
return getOpenAIRealtimeModelEntry(modelId).requestConfig.realtime.api;
|
|
9446
9855
|
}
|
|
9447
9856
|
function createOpenAIRealtimeFactory(config) {
|
|
9448
9857
|
const createModel = (modelId, options) => {
|
|
@@ -9551,7 +9960,7 @@ var OpenAISpeechModel = class OpenAISpeechModel {
|
|
|
9551
9960
|
path: "/audio/speech",
|
|
9552
9961
|
modelId: this.modelId
|
|
9553
9962
|
}),
|
|
9554
|
-
headers: combineHeaders(this.config.headers
|
|
9963
|
+
headers: combineHeaders(await resolve(this.config.headers), options.headers),
|
|
9555
9964
|
body: requestBody,
|
|
9556
9965
|
failedResponseHandler: openaiFailedResponseHandler,
|
|
9557
9966
|
successfulResponseHandler: createBinaryResponseHandler(),
|
|
@@ -9668,34 +10077,6 @@ const openAITranscriptionModelOptions = lazySchema(() => zodSchema(z.object({
|
|
|
9668
10077
|
})));
|
|
9669
10078
|
//#endregion
|
|
9670
10079
|
//#region src/transcription/openai-transcription-model.ts
|
|
9671
|
-
/**
|
|
9672
|
-
* Whether `modelId` is `base` or one of its dated snapshots
|
|
9673
|
-
* (e.g. `gpt-realtime-whisper-2026-01-01`).
|
|
9674
|
-
*/
|
|
9675
|
-
function isModelOrSnapshot(modelId, base) {
|
|
9676
|
-
return modelId === base || modelId.startsWith(`${base}-`);
|
|
9677
|
-
}
|
|
9678
|
-
/**
|
|
9679
|
-
* Model IDs that stream over the realtime transcription WebSocket and do not
|
|
9680
|
-
* support the REST transcription endpoint.
|
|
9681
|
-
*/
|
|
9682
|
-
function isRealtimeTranscriptionModelId(modelId) {
|
|
9683
|
-
return isModelOrSnapshot(modelId, "gpt-realtime-whisper") || isModelOrSnapshot(modelId, "gpt-live-transcribe");
|
|
9684
|
-
}
|
|
9685
|
-
/**
|
|
9686
|
-
* Model IDs that support streaming transcription. `gpt-transcribe` also
|
|
9687
|
-
* supports the REST transcription endpoint.
|
|
9688
|
-
*/
|
|
9689
|
-
function supportsStreamingTranscription(modelId) {
|
|
9690
|
-
return isRealtimeTranscriptionModelId(modelId) || isModelOrSnapshot(modelId, "gpt-transcribe");
|
|
9691
|
-
}
|
|
9692
|
-
/**
|
|
9693
|
-
* Models whose realtime transcription session takes a `languages` list
|
|
9694
|
-
* instead of the singular `language` field.
|
|
9695
|
-
*/
|
|
9696
|
-
function usesLanguagesList(modelId) {
|
|
9697
|
-
return isModelOrSnapshot(modelId, "gpt-live-transcribe") || isModelOrSnapshot(modelId, "gpt-transcribe");
|
|
9698
|
-
}
|
|
9699
10080
|
const languageMap = {
|
|
9700
10081
|
afrikaans: "af",
|
|
9701
10082
|
arabic: "ar",
|
|
@@ -9788,10 +10169,10 @@ var OpenAITranscriptionModel = class OpenAITranscriptionModel {
|
|
|
9788
10169
|
formData.append("model", this.modelId);
|
|
9789
10170
|
const fileExtension = mediaTypeToExtension(mediaType);
|
|
9790
10171
|
formData.append("file", new File([blob], "audio", { type: mediaType }), `audio.${fileExtension}`);
|
|
9791
|
-
const
|
|
9792
|
-
const responseFormat = openAIOptions?.responseFormat ??
|
|
10172
|
+
const { transcription: requestConfig } = getOpenAITranscriptionModelEntry(this.modelId).requestConfig;
|
|
10173
|
+
const responseFormat = openAIOptions?.responseFormat ?? requestConfig.responseFormat;
|
|
9793
10174
|
const timestampGranularities = openAIOptions?.timestampGranularities ?? (responseFormat === "verbose_json" ? ["segment"] : void 0);
|
|
9794
|
-
const chunkingStrategy = openAIOptions?.chunkingStrategy ??
|
|
10175
|
+
const chunkingStrategy = openAIOptions?.chunkingStrategy ?? requestConfig.chunkingStrategy;
|
|
9795
10176
|
const transcriptionModelOptions = {
|
|
9796
10177
|
response_format: responseFormat,
|
|
9797
10178
|
include: openAIOptions?.include,
|
|
@@ -9816,7 +10197,7 @@ var OpenAITranscriptionModel = class OpenAITranscriptionModel {
|
|
|
9816
10197
|
};
|
|
9817
10198
|
}
|
|
9818
10199
|
async doGenerate(options) {
|
|
9819
|
-
if (
|
|
10200
|
+
if (getOpenAITranscriptionModelEntry(this.modelId).capabilities.transcription.transcription === false) throw new UnsupportedFunctionalityError({ functionality: `non-streaming transcription with ${this.modelId}` });
|
|
9820
10201
|
const currentDate = this.config._internal?.currentDate?.() ?? /* @__PURE__ */ new Date();
|
|
9821
10202
|
const { formData, warnings } = await this.getArgs(options);
|
|
9822
10203
|
const { value: response, responseHeaders, rawValue: rawResponse } = await postFormDataToApi({
|
|
@@ -9824,7 +10205,7 @@ var OpenAITranscriptionModel = class OpenAITranscriptionModel {
|
|
|
9824
10205
|
path: "/audio/transcriptions",
|
|
9825
10206
|
modelId: this.modelId
|
|
9826
10207
|
}),
|
|
9827
|
-
headers: combineHeaders(this.config.headers
|
|
10208
|
+
headers: combineHeaders(await resolve(this.config.headers), options.headers),
|
|
9828
10209
|
formData,
|
|
9829
10210
|
failedResponseHandler: openaiFailedResponseHandler,
|
|
9830
10211
|
successfulResponseHandler: createJsonResponseHandler(openaiTranscriptionResponseSchema),
|
|
@@ -9866,7 +10247,8 @@ var OpenAITranscriptionModel = class OpenAITranscriptionModel {
|
|
|
9866
10247
|
};
|
|
9867
10248
|
}
|
|
9868
10249
|
async doStream(options) {
|
|
9869
|
-
|
|
10250
|
+
const entry = getOpenAITranscriptionModelEntry(this.modelId);
|
|
10251
|
+
if (entry.capabilities.transcription.streaming !== true) throw new UnsupportedFunctionalityError({ functionality: `streaming transcription with ${this.modelId}` });
|
|
9870
10252
|
const currentDate = this.config._internal?.currentDate?.() ?? /* @__PURE__ */ new Date();
|
|
9871
10253
|
const openAIOptions = await parseProviderOptions({
|
|
9872
10254
|
provider: "openai",
|
|
@@ -9885,13 +10267,13 @@ var OpenAITranscriptionModel = class OpenAITranscriptionModel {
|
|
|
9885
10267
|
feature: `providerOptions.openai.${option}`,
|
|
9886
10268
|
details: `OpenAI streaming transcription does not support ${option}.`
|
|
9887
10269
|
});
|
|
9888
|
-
const supportsDelay =
|
|
10270
|
+
const supportsDelay = entry.capabilities.transcription.streamingDelay === true;
|
|
9889
10271
|
if (!supportsDelay && openAIOptions?.streaming?.delay != null) warnings.push({
|
|
9890
10272
|
type: "unsupported",
|
|
9891
10273
|
feature: "providerOptions.openai.streaming.delay",
|
|
9892
10274
|
details: `OpenAI streaming transcription with ${this.modelId} does not support delay.`
|
|
9893
10275
|
});
|
|
9894
|
-
const headers = combineHeaders(this.config.headers
|
|
10276
|
+
const headers = combineHeaders(await resolve(this.config.headers), options.headers);
|
|
9895
10277
|
const sessionUpdate = buildOpenAIRealtimeTranscriptionSession({
|
|
9896
10278
|
modelId: this.modelId,
|
|
9897
10279
|
inputAudioFormat: options.inputAudioFormat,
|
|
@@ -10043,7 +10425,7 @@ function buildOpenAIRealtimeTranscriptionSession({ modelId, inputAudioFormat, pr
|
|
|
10043
10425
|
},
|
|
10044
10426
|
transcription: {
|
|
10045
10427
|
model: modelId,
|
|
10046
|
-
...providerOptions?.language != null ?
|
|
10428
|
+
...providerOptions?.language != null ? getOpenAITranscriptionModelEntry(modelId).requestConfig.transcription.languageField === "languages" ? { languages: [providerOptions.language] } : { language: providerOptions.language } : {},
|
|
10047
10429
|
...supportsDelay && providerOptions?.streaming?.delay != null ? { delay: providerOptions.streaming.delay } : {}
|
|
10048
10430
|
},
|
|
10049
10431
|
turn_detection: null
|
|
@@ -10111,7 +10493,7 @@ var OpenAISpeechTranslationModel = class OpenAISpeechTranslationModel {
|
|
|
10111
10493
|
feature: "outputAudioFormat",
|
|
10112
10494
|
details: "The OpenAI Realtime translation API always outputs 24kHz 16-bit PCM audio and does not accept an output audio format."
|
|
10113
10495
|
});
|
|
10114
|
-
const headers = combineHeaders(this.config.headers
|
|
10496
|
+
const headers = combineHeaders(await resolve(this.config.headers), options.headers);
|
|
10115
10497
|
const sessionUpdate = buildOpenAIRealtimeSpeechTranslationSession({ targetLanguage: options.targetLanguage });
|
|
10116
10498
|
return {
|
|
10117
10499
|
request: { body: sessionUpdate },
|
|
@@ -10336,7 +10718,7 @@ var OpenAISkills = class {
|
|
|
10336
10718
|
}
|
|
10337
10719
|
const { value: response } = await postFormDataToApi({
|
|
10338
10720
|
url: this.config.url({ path: "/skills" }),
|
|
10339
|
-
headers: combineHeaders(this.config.headers
|
|
10721
|
+
headers: combineHeaders(await resolve(this.config.headers)),
|
|
10340
10722
|
formData,
|
|
10341
10723
|
failedResponseHandler: openaiFailedResponseHandler,
|
|
10342
10724
|
successfulResponseHandler: createJsonResponseHandler(openaiSkillResponseSchema),
|
|
@@ -10358,7 +10740,7 @@ var OpenAISkills = class {
|
|
|
10358
10740
|
};
|
|
10359
10741
|
//#endregion
|
|
10360
10742
|
//#region src/version.ts
|
|
10361
|
-
const VERSION = "4.0.
|
|
10743
|
+
const VERSION = "4.0.106";
|
|
10362
10744
|
//#endregion
|
|
10363
10745
|
//#region src/openai-provider.ts
|
|
10364
10746
|
/**
|
|
@@ -10370,16 +10752,16 @@ function createOpenAI(options = {}) {
|
|
|
10370
10752
|
environmentVariableName: "OPENAI_BASE_URL"
|
|
10371
10753
|
}))) ?? "https://api.openai.com/v1";
|
|
10372
10754
|
const providerName = options.name ?? "openai";
|
|
10373
|
-
const getHeaders = () => withUserAgentSuffix({
|
|
10755
|
+
const getHeaders = () => resolveWith(options.apiKey, (apiKey) => withUserAgentSuffix({
|
|
10374
10756
|
Authorization: `Bearer ${loadApiKey({
|
|
10375
|
-
apiKey
|
|
10757
|
+
apiKey,
|
|
10376
10758
|
environmentVariableName: "OPENAI_API_KEY",
|
|
10377
10759
|
description: "OpenAI"
|
|
10378
10760
|
})}`,
|
|
10379
10761
|
"OpenAI-Organization": options.organization,
|
|
10380
10762
|
"OpenAI-Project": options.project,
|
|
10381
10763
|
...options.headers
|
|
10382
|
-
}, `ai-sdk-openai/${VERSION}`);
|
|
10764
|
+
}, `ai-sdk-openai/${VERSION}`));
|
|
10383
10765
|
const createChatModel = (modelId) => new OpenAIChatLanguageModel(modelId, {
|
|
10384
10766
|
provider: `${providerName}.chat`,
|
|
10385
10767
|
url: ({ path }) => `${baseURL}${path}`,
|