@ai-sdk/openai 4.0.105 → 4.0.107

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/dist/index.d.ts +51 -9
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +611 -202
  5. package/dist/index.js.map +1 -1
  6. package/dist/internal/index.d.ts +6 -4
  7. package/dist/internal/index.d.ts.map +1 -1
  8. package/dist/internal/index.js +565 -164
  9. package/dist/internal/index.js.map +1 -1
  10. package/docs/03-openai.mdx +127 -5
  11. package/package.json +3 -3
  12. package/src/chat/convert-to-openai-chat-messages.ts +22 -3
  13. package/src/chat/openai-chat-language-model.ts +27 -20
  14. package/src/completion/openai-completion-language-model.ts +11 -3
  15. package/src/embedding/openai-embedding-model.ts +2 -1
  16. package/src/files/openai-files.ts +10 -8
  17. package/src/image/openai-image-model-options.ts +10 -20
  18. package/src/image/openai-image-model.ts +10 -21
  19. package/src/live/openai-realtime-model-live.ts +15 -16
  20. package/src/openai-batch.ts +22 -6
  21. package/src/openai-config.ts +2 -1
  22. package/src/openai-decision-model.ts +2 -1
  23. package/src/openai-model-catalog.ts +935 -0
  24. package/src/openai-provider.ts +18 -13
  25. package/src/realtime/openai-realtime-factory.ts +6 -6
  26. package/src/realtime/openai-realtime-model.ts +7 -3
  27. package/src/resolve-openai-reasoning-effort.ts +45 -0
  28. package/src/responses/convert-to-openai-responses-input.ts +29 -11
  29. package/src/responses/openai-responses-language-model.ts +28 -22
  30. package/src/skills/openai-skills.ts +4 -2
  31. package/src/speech/openai-speech-model.ts +5 -1
  32. package/src/speech-translation/openai-speech-translation-model.ts +5 -1
  33. package/src/transcription/openai-transcription-model-options.ts +12 -0
  34. package/src/transcription/openai-transcription-model.ts +29 -56
  35. package/src/openai-language-model-capabilities.ts +0 -196
@@ -4,6 +4,7 @@ import type {
4
4
  SharedV4Warning,
5
5
  } from '@ai-sdk/provider';
6
6
  import {
7
+ resolve,
7
8
  combineHeaders,
8
9
  convertBase64ToUint8Array,
9
10
  convertToFormData,
@@ -18,6 +19,7 @@ import {
18
19
  } from '@ai-sdk/provider-utils';
19
20
  import type { OpenAIConfig } from '../openai-config';
20
21
  import { openaiFailedResponseHandler } from '../openai-error';
22
+ import { getOpenAIImageModelEntry } from '../openai-model-catalog';
21
23
  import { openaiImageResponseSchema } from './openai-image-api';
22
24
  import {
23
25
  getMaxImagesPerCall,
@@ -63,24 +65,9 @@ export class OpenAIImageModel implements ImageModelV4 {
63
65
  return this.config.imageInputCapabilities.supportsFileInputs;
64
66
  }
65
67
 
66
- if (
67
- [
68
- 'dall-e-2',
69
- 'gpt-image-1',
70
- 'gpt-image-1-mini',
71
- 'gpt-image-1.5',
72
- 'gpt-image-2',
73
- 'gpt-image-2.5-flare',
74
- 'gpt-image-2.5-flare-2026-09-08',
75
- 'gpt-image-2.5-sunburst',
76
- 'gpt-image-2.5-sunburst-2026-09-08',
77
- 'chatgpt-image-latest',
78
- ].includes(this.modelId)
79
- ) {
80
- return true;
81
- }
82
-
83
- return this.modelId === 'dall-e-3' ? false : undefined;
68
+ const support = getOpenAIImageModelEntry(this.modelId).capabilities.image
69
+ .fileInput;
70
+ return typeof support === 'boolean' ? support : undefined;
84
71
  }
85
72
 
86
73
  get supportsMaskInputs(): boolean | undefined {
@@ -88,7 +75,9 @@ export class OpenAIImageModel implements ImageModelV4 {
88
75
  return this.config.imageInputCapabilities.supportsMaskInputs;
89
76
  }
90
77
 
91
- return this.supportsFileInputs;
78
+ const support = getOpenAIImageModelEntry(this.modelId).capabilities.image
79
+ .maskInput;
80
+ return typeof support === 'boolean' ? support : undefined;
92
81
  }
93
82
 
94
83
  get provider(): string {
@@ -144,7 +133,7 @@ export class OpenAIImageModel implements ImageModelV4 {
144
133
  path: '/images/edits',
145
134
  modelId: this.modelId,
146
135
  }),
147
- headers: combineHeaders(this.config.headers?.(), headers),
136
+ headers: combineHeaders(await resolve(this.config.headers), headers),
148
137
  formData: convertToFormData<OpenAIImageEditInput>({
149
138
  model: this.modelId,
150
139
  prompt,
@@ -234,7 +223,7 @@ export class OpenAIImageModel implements ImageModelV4 {
234
223
  path: '/images/generations',
235
224
  modelId: this.modelId,
236
225
  }),
237
- headers: combineHeaders(this.config.headers?.(), headers),
226
+ headers: combineHeaders(await resolve(this.config.headers), headers),
238
227
  body: {
239
228
  model: this.modelId,
240
229
  prompt,
@@ -4,6 +4,8 @@ import {
4
4
  type Experimental_RealtimeModelV4SessionConfig as RealtimeModelV4SessionConfig,
5
5
  } from '@ai-sdk/provider';
6
6
  import {
7
+ resolveWith,
8
+ resolve,
7
9
  lazySchema,
8
10
  zodSchema,
9
11
  createJsonResponseHandler,
@@ -11,6 +13,7 @@ import {
11
13
  } from '@ai-sdk/provider-utils';
12
14
  import { z } from 'zod/v4';
13
15
  import { openaiFailedResponseHandler } from '../openai-error';
16
+ import { openaiLiveRealtimeCapabilities } from '../openai-model-catalog';
14
17
  import {
15
18
  createOpenAILiveServerEventParser,
16
19
  parseOpenAILiveServerEvent,
@@ -36,13 +39,7 @@ const webRTCSessionSchema = lazySchema(() =>
36
39
 
37
40
  export class OpenAIRealtimeModelLive implements RealtimeModelV4 {
38
41
  readonly specificationVersion = 'v4' as const;
39
- readonly capabilities = {
40
- conversation: 'continuous',
41
- transports: ['websocket', 'webrtc'],
42
- connections: ['server-websocket', 'webrtc'],
43
- startup: 'session-start',
44
- finalization: 'session-close',
45
- } as const;
42
+ readonly capabilities = openaiLiveRealtimeCapabilities;
46
43
 
47
44
  constructor(
48
45
  readonly modelId: OpenAIRealtimeModelLiveId,
@@ -57,14 +54,16 @@ export class OpenAIRealtimeModelLive implements RealtimeModelV4 {
57
54
  return { dataChannelLabel: 'oai-events' };
58
55
  }
59
56
 
60
- getServerWebSocketConfig(): { url: string; headers: Record<string, string> } {
61
- const url = new URL(`${this.config.baseURL}/live/sessions`);
62
- url.protocol = url.protocol === 'http:' ? 'ws:' : 'wss:';
63
- const headers: Record<string, string> = {};
64
- for (const [key, value] of Object.entries(this.config.headers())) {
65
- if (value !== undefined) headers[key] = value;
66
- }
67
- return { url: url.toString(), headers };
57
+ getServerWebSocketConfig() {
58
+ return resolveWith(this.config.headers, configHeaders => {
59
+ const url = new URL(`${this.config.baseURL}/live/sessions`);
60
+ url.protocol = url.protocol === 'http:' ? 'ws:' : 'wss:';
61
+ const headers: Record<string, string> = {};
62
+ for (const [key, value] of Object.entries(configHeaders)) {
63
+ if (value !== undefined) headers[key] = value;
64
+ }
65
+ return { url: url.toString(), headers };
66
+ });
68
67
  }
69
68
 
70
69
  async doCreateWebRTCSession({
@@ -83,7 +82,7 @@ export class OpenAIRealtimeModelLive implements RealtimeModelV4 {
83
82
  );
84
83
  const { value } = await postJsonToApi({
85
84
  url: `${this.config.baseURL}/live/sessions`,
86
- headers: this.config.headers(),
85
+ headers: await resolve(this.config.headers),
87
86
  body: {
88
87
  session,
89
88
  transport: { type: 'webrtc', sdp: z.string().min(1).parse(sdp) },
@@ -19,6 +19,7 @@ import {
19
19
  type SharedV4Warning,
20
20
  } from '@ai-sdk/provider';
21
21
  import {
22
+ resolve,
22
23
  combineHeaders,
23
24
  convertAsyncIteratorToReadableStream,
24
25
  createJsonLinesResponseHandler,
@@ -267,7 +268,10 @@ export class OpenAIBatch implements BatchV4<OpenAIBatchModelIds> {
267
268
 
268
269
  const { value: uploadedFile } = await postToApi({
269
270
  url: this.getUrl('/files'),
270
- headers: combineHeaders(this.options.config.headers?.(), options.headers),
271
+ headers: combineHeaders(
272
+ await resolve(this.options.config.headers),
273
+ options.headers,
274
+ ),
271
275
  body: {
272
276
  content: formData,
273
277
  values: {
@@ -291,7 +295,10 @@ export class OpenAIBatch implements BatchV4<OpenAIBatchModelIds> {
291
295
 
292
296
  const { value: batch } = await postJsonToApi({
293
297
  url: this.getUrl('/batches'),
294
- headers: combineHeaders(this.options.config.headers?.(), options.headers),
298
+ headers: combineHeaders(
299
+ await resolve(this.options.config.headers),
300
+ options.headers,
301
+ ),
295
302
  body: {
296
303
  input_file_id: uploadedFile.id,
297
304
  endpoint: openaiBatchEndpoint,
@@ -357,7 +364,10 @@ export class OpenAIBatch implements BatchV4<OpenAIBatchModelIds> {
357
364
  url: this.getUrl(
358
365
  `/batches/${encodeURIComponent(options.batchId)}/cancel`,
359
366
  ),
360
- headers: combineHeaders(this.options.config.headers?.(), options.headers),
367
+ headers: combineHeaders(
368
+ await resolve(this.options.config.headers),
369
+ options.headers,
370
+ ),
361
371
  body: {},
362
372
  failedResponseHandler: openaiFailedResponseHandler,
363
373
  successfulResponseHandler: createJsonResponseHandler(
@@ -381,7 +391,10 @@ export class OpenAIBatch implements BatchV4<OpenAIBatchModelIds> {
381
391
 
382
392
  const { value: page } = await getFromApi({
383
393
  url: url.toString(),
384
- headers: combineHeaders(this.options.config.headers?.(), options.headers),
394
+ headers: combineHeaders(
395
+ await resolve(this.options.config.headers),
396
+ options.headers,
397
+ ),
385
398
  failedResponseHandler: openaiFailedResponseHandler,
386
399
  successfulResponseHandler: createJsonResponseHandler(
387
400
  openaiBatchListResponseSchema,
@@ -437,7 +450,10 @@ export class OpenAIBatch implements BatchV4<OpenAIBatchModelIds> {
437
450
  ): Promise<OpenAIBatchResponse> {
438
451
  const { value: batch } = await getFromApi({
439
452
  url: this.getUrl(`/batches/${encodeURIComponent(options.batchId)}`),
440
- headers: combineHeaders(this.options.config.headers?.(), options.headers),
453
+ headers: combineHeaders(
454
+ await resolve(this.options.config.headers),
455
+ options.headers,
456
+ ),
441
457
  failedResponseHandler: openaiFailedResponseHandler,
442
458
  successfulResponseHandler: createJsonResponseHandler(
443
459
  openaiBatchResponseSchema,
@@ -461,7 +477,7 @@ export class OpenAIBatch implements BatchV4<OpenAIBatchModelIds> {
461
477
  const { value: lines } = await getFromApi({
462
478
  url: this.getUrl(`/files/${encodeURIComponent(fileId)}/content`),
463
479
  headers: combineHeaders(
464
- this.options.config.headers?.(),
480
+ await resolve(this.options.config.headers),
465
481
  options.headers,
466
482
  ),
467
483
  failedResponseHandler: openaiFailedResponseHandler,
@@ -1,4 +1,5 @@
1
1
  import type {
2
+ Resolvable,
2
3
  FetchFunction,
3
4
  WebSocketConstructor,
4
5
  } from '@ai-sdk/provider-utils';
@@ -15,7 +16,7 @@ export type OpenAIConfig = {
15
16
  requestModelId?: string;
16
17
  baseURL?: string;
17
18
  url: (options: { modelId: string; path: string }) => string;
18
- headers?: () => OpenAIHeaders;
19
+ headers?: Resolvable<OpenAIHeaders>;
19
20
  fetch?: FetchFunction;
20
21
  webSocket?: WebSocketConstructor;
21
22
  generateId?: () => string;
@@ -8,6 +8,7 @@ import {
8
8
  type JSONValue,
9
9
  } from '@ai-sdk/provider';
10
10
  import {
11
+ resolve,
11
12
  lazySchema,
12
13
  zodSchema,
13
14
  combineHeaders,
@@ -146,7 +147,7 @@ export class DecisionOpenAIModel implements DecisionModelV4 {
146
147
  responseHeaders,
147
148
  } = await postJsonToApi({
148
149
  url: this.config.url({ path: '/decisions', modelId: this.modelId }),
149
- headers: combineHeaders(this.config.headers?.(), headers),
150
+ headers: combineHeaders(await resolve(this.config.headers), headers),
150
151
  body: {
151
152
  model: this.modelId,
152
153
  safety_identifier: openaiOptions?.safetyIdentifier,