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