@ai-sdk/openai 4.0.57 → 4.0.59

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.
@@ -217,12 +217,13 @@ The following provider options are available:
217
217
  `.nullable()`.
218
218
  </Note>
219
219
 
220
- - **serviceTier** _'auto' | 'flex' | 'priority' | 'fast' | 'default'_
220
+ - **serviceTier** _'auto' | 'flex' | 'priority' | 'fast' | 'ultrafast' | 'default'_
221
221
  Service tier for the request. Set to 'flex' for 50% cheaper processing
222
222
  at the cost of increased latency (available for o3, o4-mini, and gpt-5 models).
223
223
  Set to 'priority' for faster processing with Enterprise access (available for gpt-4, gpt-5, gpt-5-mini, o3, o4-mini; gpt-5-nano is not supported).
224
224
  'fast' is OpenAI's newer name for the 'priority' tier; the two are interchangeable, and responses from
225
225
  gpt-5.6 and earlier report `serviceTier: 'priority'` for either.
226
+ Set to 'ultrafast' for access-controlled Ultrafast processing (available only for gpt-5.6-sol).
226
227
 
227
228
  Defaults to 'auto'.
228
229
 
@@ -2106,13 +2107,14 @@ The following optional provider options are available for OpenAI chat models:
2106
2107
 
2107
2108
  Parameters for prediction mode.
2108
2109
 
2109
- - **serviceTier** _'auto' | 'flex' | 'priority' | 'fast' | 'default'_
2110
+ - **serviceTier** _'auto' | 'flex' | 'priority' | 'fast' | 'ultrafast' | 'default'_
2110
2111
 
2111
2112
  Service tier for the request. Set to 'flex' for 50% cheaper processing
2112
2113
  at the cost of increased latency (available for o3, o4-mini, and gpt-5 models).
2113
2114
  Set to 'priority' for faster processing with Enterprise access (available for gpt-4, gpt-5, gpt-5-mini, o3, o4-mini; gpt-5-nano is not supported).
2114
2115
  'fast' is OpenAI's newer name for the 'priority' tier; the two are interchangeable, and responses from
2115
2116
  gpt-5.6 and earlier report `serviceTier: 'priority'` for either.
2117
+ Set to 'ultrafast' for access-controlled Ultrafast processing (available only for gpt-5.6-sol).
2116
2118
 
2117
2119
  Defaults to 'auto'.
2118
2120
 
@@ -2718,6 +2720,7 @@ The following optional provider options are available for OpenAI completion mode
2718
2720
 
2719
2721
  | Model | Image Input | Audio Input | Object Generation | Tool Usage |
2720
2722
  | --------------------- | ----------- | ----------- | ----------------- | ---------- |
2723
+ | `gpt-6-astra` | <Check /> | <Cross /> | <Check /> | <Check /> |
2721
2724
  | `gpt-5.6` | <Check /> | <Cross /> | <Check /> | <Check /> |
2722
2725
  | `gpt-5.6-luna` | <Check /> | <Cross /> | <Check /> | <Check /> |
2723
2726
  | `gpt-5.6-sol` | <Check /> | <Cross /> | <Check /> | <Check /> |
@@ -3020,6 +3023,21 @@ const result = await transcribe({
3020
3023
  console.log(result.segments); // Array of segments with startSecond/endSecond
3021
3024
  ```
3022
3025
 
3026
+ `gpt-4o-transcribe-diarize` identifies speakers in a recording. It defaults to
3027
+ the `diarized_json` response format and automatic chunking:
3028
+
3029
+ ```ts
3030
+ import { transcribe } from 'ai';
3031
+ import { openai } from '@ai-sdk/openai';
3032
+
3033
+ const result = await transcribe({
3034
+ model: openai.transcription('gpt-4o-transcribe-diarize'),
3035
+ audio: new Uint8Array([1, 2, 3, 4]),
3036
+ });
3037
+
3038
+ console.log(result.providerMetadata.openai.segments);
3039
+ ```
3040
+
3023
3041
  The following provider options are available:
3024
3042
 
3025
3043
  - **timestampGranularities** _string[]_
@@ -3044,6 +3062,12 @@ The following provider options are available:
3044
3062
  - **include** _string[]_
3045
3063
  Additional information to include in the transcription response.
3046
3064
 
3065
+ - **responseFormat** _'json' | 'verbose_json' | 'diarized_json'_
3066
+ The format of the transcription response. `gpt-4o-transcribe-diarize` defaults to `diarized_json`.
3067
+
3068
+ - **chunkingStrategy** _'auto' | object_
3069
+ Controls how the audio is split into chunks. `gpt-4o-transcribe-diarize` defaults to `'auto'`; provide this option to override the default. The object form configures OpenAI server-side VAD with `type: 'server_vad'` and optional `threshold`, `prefixPaddingMs`, and `silenceDurationMs` fields.
3070
+
3047
3071
  - **streaming** _object_
3048
3072
  Options for streaming transcription models such as `gpt-realtime-whisper`.
3049
3073
  Use with `experimental_streamTranscribe`.
@@ -3055,12 +3079,13 @@ The following provider options are available:
3055
3079
 
3056
3080
  ### Model Capabilities
3057
3081
 
3058
- | Model | Transcription | Streaming | Duration | Segments | Language |
3059
- | ------------------------ | ------------- | --------- | --------- | --------- | --------- |
3060
- | `whisper-1` | <Check /> | <Cross /> | <Check /> | <Check /> | <Check /> |
3061
- | `gpt-4o-mini-transcribe` | <Check /> | <Cross /> | <Cross /> | <Cross /> | <Cross /> |
3062
- | `gpt-4o-transcribe` | <Check /> | <Cross /> | <Cross /> | <Cross /> | <Cross /> |
3063
- | `gpt-realtime-whisper` | <Cross /> | <Check /> | <Cross /> | <Cross /> | <Cross /> |
3082
+ | Model | Transcription | Streaming | Duration | Segments | Language |
3083
+ | --------------------------- | ------------- | --------- | --------- | --------- | --------- |
3084
+ | `whisper-1` | <Check /> | <Cross /> | <Check /> | <Check /> | <Check /> |
3085
+ | `gpt-4o-mini-transcribe` | <Check /> | <Cross /> | <Cross /> | <Cross /> | <Cross /> |
3086
+ | `gpt-4o-transcribe` | <Check /> | <Cross /> | <Cross /> | <Cross /> | <Cross /> |
3087
+ | `gpt-4o-transcribe-diarize` | <Check /> | <Cross /> | <Check /> | <Check /> | <Cross /> |
3088
+ | `gpt-realtime-whisper` | <Cross /> | <Check /> | <Cross /> | <Cross /> | <Cross /> |
3064
3089
 
3065
3090
  ## Translation Models
3066
3091
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/openai",
3
- "version": "4.0.57",
3
+ "version": "4.0.59",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "sideEffects": false,
@@ -70,6 +70,7 @@ export type OpenAIChatModelId =
70
70
  | 'gpt-5.6-luna'
71
71
  | 'gpt-5.6-sol'
72
72
  | 'gpt-5.6-terra'
73
+ | 'gpt-6-astra'
73
74
  | (string & {});
74
75
 
75
76
  export const openaiLanguageModelChatOptions = lazySchema(() =>
@@ -139,12 +140,13 @@ export const openaiLanguageModelChatOptions = lazySchema(() =>
139
140
  * - 'flex': 50% cheaper processing at the cost of increased latency. Only available for o3 and o4-mini models.
140
141
  * - 'priority': Higher-speed processing with predictably low latency at premium cost. Available for Enterprise customers.
141
142
  * - 'fast': OpenAI's newer name for the 'priority' tier. Interchangeable with it.
143
+ * - 'ultrafast': Access-controlled Ultrafast processing. Only available for gpt-5.6-sol.
142
144
  * - 'default': The request will be processed with the standard pricing and performance for the selected model.
143
145
  *
144
146
  * @default 'auto'
145
147
  */
146
148
  serviceTier: z
147
- .enum(['auto', 'flex', 'priority', 'fast', 'default'])
149
+ .enum(['auto', 'flex', 'priority', 'fast', 'ultrafast', 'default'])
148
150
  .optional(),
149
151
 
150
152
  /**
@@ -601,6 +601,7 @@ export type OpenAIResponsesTool =
601
601
  }
602
602
  | {
603
603
  type: 'image_generation';
604
+ action: 'generate' | 'edit' | 'auto' | undefined;
604
605
  background: 'auto' | 'opaque' | 'transparent' | undefined;
605
606
  input_fidelity: 'low' | 'high' | undefined;
606
607
  input_image_mask:
@@ -610,12 +611,18 @@ export type OpenAIResponsesTool =
610
611
  }
611
612
  | undefined;
612
613
  model: string | undefined;
613
- moderation: 'auto' | undefined;
614
+ moderation: 'auto' | 'low' | undefined;
614
615
  output_compression: number | undefined;
615
616
  output_format: 'png' | 'jpeg' | 'webp' | undefined;
616
617
  partial_images: number | undefined;
617
618
  quality: 'auto' | 'low' | 'medium' | 'high' | undefined;
618
- size: 'auto' | '1024x1024' | '1024x1536' | '1536x1024' | undefined;
619
+ size:
620
+ | 'auto'
621
+ | '1024x1024'
622
+ | '1024x1536'
623
+ | '1536x1024'
624
+ | (string & {})
625
+ | undefined;
619
626
  }
620
627
 
621
628
  /**
@@ -57,6 +57,7 @@ export const openaiResponsesReasoningModelIds = [
57
57
  'gpt-5.6-luna',
58
58
  'gpt-5.6-sol',
59
59
  'gpt-5.6-terra',
60
+ 'gpt-6-astra',
60
61
  ] as const;
61
62
 
62
63
  export const openaiResponsesModelIds = [
@@ -129,6 +130,7 @@ export type OpenAIResponsesModelId =
129
130
  | 'gpt-5.6-luna'
130
131
  | 'gpt-5.6-sol'
131
132
  | 'gpt-5.6-terra'
133
+ | 'gpt-6-astra'
132
134
  | 'gpt-5-2025-08-07'
133
135
  | 'gpt-5-chat-latest'
134
136
  | 'gpt-5-codex'
@@ -294,11 +296,12 @@ export const openaiLanguageModelResponsesOptionsSchema = lazySchema(() =>
294
296
  * Set to 'flex' for 50% cheaper processing at the cost of increased latency (available for o3, o4-mini, and gpt-5 models).
295
297
  * Set to 'priority' for faster processing with Enterprise access (available for gpt-4, gpt-5, gpt-5-mini, o3, o4-mini; gpt-5-nano is not supported).
296
298
  * Set to 'fast' for the same tier as 'priority' (OpenAI's newer name for it).
299
+ * Set to 'ultrafast' for access-controlled Ultrafast processing (available only for gpt-5.6-sol).
297
300
  *
298
301
  * Defaults to 'auto'.
299
302
  */
300
303
  serviceTier: z
301
- .enum(['auto', 'flex', 'priority', 'fast', 'default'])
304
+ .enum(['auto', 'flex', 'priority', 'fast', 'ultrafast', 'default'])
302
305
  .nullish(),
303
306
 
304
307
  /**
@@ -302,6 +302,7 @@ export async function prepareResponsesTools({
302
302
 
303
303
  openaiTools.push({
304
304
  type: 'image_generation',
305
+ action: args.action,
305
306
  background: args.background,
306
307
  input_fidelity: args.inputFidelity,
307
308
  input_image_mask: args.inputImageMask
@@ -9,6 +9,7 @@ export const imageGenerationArgsSchema = lazySchema(() =>
9
9
  zodSchema(
10
10
  z
11
11
  .object({
12
+ action: z.enum(['generate', 'edit', 'auto']).optional(),
12
13
  background: z.enum(['auto', 'opaque', 'transparent']).optional(),
13
14
  inputFidelity: z.enum(['low', 'high']).optional(),
14
15
  inputImageMask: z
@@ -18,13 +19,16 @@ export const imageGenerationArgsSchema = lazySchema(() =>
18
19
  })
19
20
  .optional(),
20
21
  model: z.string().optional(),
21
- moderation: z.enum(['auto']).optional(),
22
+ moderation: z.enum(['auto', 'low']).optional(),
22
23
  outputCompression: z.number().int().min(0).max(100).optional(),
23
24
  outputFormat: z.enum(['png', 'jpeg', 'webp']).optional(),
24
25
  partialImages: z.number().int().min(0).max(3).optional(),
25
26
  quality: z.enum(['auto', 'low', 'medium', 'high']).optional(),
26
27
  size: z
27
- .enum(['1024x1024', '1024x1536', '1536x1024', 'auto'])
28
+ .union([
29
+ z.enum(['1024x1024', '1024x1536', '1536x1024', 'auto']),
30
+ z.string().regex(/^\d+x\d+$/),
31
+ ])
28
32
  .optional(),
29
33
  })
30
34
  .strict(),
@@ -38,6 +42,11 @@ export const imageGenerationOutputSchema = lazySchema(() =>
38
42
  );
39
43
 
40
44
  type ImageGenerationArgs = {
45
+ /**
46
+ * Whether to generate a new image or edit an existing image. Default: auto.
47
+ */
48
+ action?: 'generate' | 'edit' | 'auto';
49
+
41
50
  /**
42
51
  * Background type for the generated image. Default is 'auto'.
43
52
  */
@@ -70,9 +79,9 @@ type ImageGenerationArgs = {
70
79
  model?: string;
71
80
 
72
81
  /**
73
- * Moderation level for the generated image. Default: auto.
82
+ * Moderation level for the generated image. One of auto or low. Default: auto.
74
83
  */
75
- moderation?: 'auto';
84
+ moderation?: 'auto' | 'low';
76
85
 
77
86
  /**
78
87
  * Compression level for the output image. Default: 100.
@@ -98,10 +107,11 @@ type ImageGenerationArgs = {
98
107
 
99
108
  /**
100
109
  * The size of the generated image.
101
- * One of 1024x1024, 1024x1536, 1536x1024, or auto.
110
+ * One of 1024x1024, 1024x1536, 1536x1024, or auto. gpt-image-2 also accepts
111
+ * arbitrary WIDTHxHEIGHT sizes where both are divisible by 16, e.g. 1536x864.
102
112
  * Default: auto.
103
113
  */
104
- size?: 'auto' | '1024x1024' | '1024x1536' | '1536x1024';
114
+ size?: 'auto' | '1024x1024' | '1024x1536' | '1536x1024' | (string & {});
105
115
  };
106
116
 
107
117
  const imageGenerationToolFactory = createProviderExecutedToolFactory<
@@ -18,18 +18,28 @@ export const openaiTranscriptionResponseSchema = lazySchema(() =>
18
18
  .nullish(),
19
19
  segments: z
20
20
  .array(
21
- z.object({
22
- id: z.number(),
23
- seek: z.number(),
24
- start: z.number(),
25
- end: z.number(),
26
- text: z.string(),
27
- tokens: z.array(z.number()),
28
- temperature: z.number(),
29
- avg_logprob: z.number(),
30
- compression_ratio: z.number(),
31
- no_speech_prob: z.number(),
32
- }),
21
+ z.union([
22
+ z.object({
23
+ id: z.number(),
24
+ seek: z.number(),
25
+ start: z.number(),
26
+ end: z.number(),
27
+ text: z.string(),
28
+ tokens: z.array(z.number()),
29
+ temperature: z.number(),
30
+ avg_logprob: z.number(),
31
+ compression_ratio: z.number(),
32
+ no_speech_prob: z.number(),
33
+ }),
34
+ z.object({
35
+ type: z.literal('transcript.text.segment'),
36
+ id: z.string(),
37
+ start: z.number(),
38
+ end: z.number(),
39
+ text: z.string(),
40
+ speaker: z.string(),
41
+ }),
42
+ ]),
33
43
  )
34
44
  .nullish(),
35
45
  }),
@@ -50,6 +50,28 @@ export const openAITranscriptionModelOptions = lazySchema(() =>
50
50
  .default(['segment'])
51
51
  .optional(),
52
52
 
53
+ /**
54
+ * The format of the transcription response.
55
+ */
56
+ responseFormat: z
57
+ .enum(['json', 'verbose_json', 'diarized_json'])
58
+ .optional(),
59
+
60
+ /**
61
+ * Controls how the audio is split into chunks before transcription.
62
+ */
63
+ chunkingStrategy: z
64
+ .union([
65
+ z.literal('auto'),
66
+ z.object({
67
+ type: z.literal('server_vad'),
68
+ threshold: z.number().min(0).max(1).optional(),
69
+ prefixPaddingMs: z.number().int().min(0).optional(),
70
+ silenceDurationMs: z.number().int().min(0).optional(),
71
+ }),
72
+ ])
73
+ .optional(),
74
+
53
75
  /**
54
76
  * Options for streaming transcription models such as `gpt-realtime-whisper`.
55
77
  */
@@ -195,6 +195,11 @@ export class OpenAITranscriptionModel implements TranscriptionModelV4 {
195
195
  formData.append('response_format', 'verbose_json');
196
196
  }
197
197
 
198
+ const isDiarizationModel = this.modelId === 'gpt-4o-transcribe-diarize';
199
+ const chunkingStrategy =
200
+ openAIOptions?.chunkingStrategy ??
201
+ (isDiarizationModel ? 'auto' : undefined);
202
+
198
203
  // Add provider-specific options
199
204
  if (openAIOptions) {
200
205
  const isGpt4oTranscribeModel = [
@@ -209,7 +214,13 @@ export class OpenAITranscriptionModel implements TranscriptionModelV4 {
209
214
  // https://platform.openai.com/docs/api-reference/audio/createTranscription#audio_createtranscription-response_format
210
215
  // prefer verbose_json to get segments for models that support it
211
216
  ...(this.modelId !== 'whisper-1' && {
212
- response_format: isGpt4oTranscribeModel ? 'json' : 'verbose_json',
217
+ response_format:
218
+ openAIOptions.responseFormat ??
219
+ (isDiarizationModel
220
+ ? 'diarized_json'
221
+ : isGpt4oTranscribeModel
222
+ ? 'json'
223
+ : 'verbose_json'),
213
224
  }),
214
225
  temperature: openAIOptions.temperature,
215
226
  timestamp_granularities: openAIOptions.timestampGranularities,
@@ -226,6 +237,28 @@ export class OpenAITranscriptionModel implements TranscriptionModelV4 {
226
237
  }
227
238
  }
228
239
  }
240
+ } else if (isDiarizationModel) {
241
+ formData.append('response_format', 'diarized_json');
242
+ }
243
+
244
+ if (chunkingStrategy != null) {
245
+ formData.append(
246
+ 'chunking_strategy',
247
+ typeof chunkingStrategy === 'string'
248
+ ? chunkingStrategy
249
+ : JSON.stringify({
250
+ type: chunkingStrategy.type,
251
+ ...(chunkingStrategy.threshold != null && {
252
+ threshold: chunkingStrategy.threshold,
253
+ }),
254
+ ...(chunkingStrategy.prefixPaddingMs != null && {
255
+ prefix_padding_ms: chunkingStrategy.prefixPaddingMs,
256
+ }),
257
+ ...(chunkingStrategy.silenceDurationMs != null && {
258
+ silence_duration_ms: chunkingStrategy.silenceDurationMs,
259
+ }),
260
+ }),
261
+ );
229
262
  }
230
263
 
231
264
  return {
@@ -270,6 +303,19 @@ export class OpenAITranscriptionModel implements TranscriptionModelV4 {
270
303
  ? languageMap[response.language as keyof typeof languageMap]
271
304
  : undefined;
272
305
 
306
+ const diarizedSegments = response.segments?.flatMap(segment =>
307
+ 'speaker' in segment
308
+ ? [
309
+ {
310
+ text: segment.text,
311
+ startSecond: segment.start,
312
+ endSecond: segment.end,
313
+ speaker: segment.speaker,
314
+ },
315
+ ]
316
+ : [],
317
+ );
318
+
273
319
  return {
274
320
  text: response.text,
275
321
  segments:
@@ -293,6 +339,14 @@ export class OpenAITranscriptionModel implements TranscriptionModelV4 {
293
339
  headers: responseHeaders,
294
340
  body: rawResponse,
295
341
  },
342
+ ...(diarizedSegments != null &&
343
+ diarizedSegments.length > 0 && {
344
+ providerMetadata: {
345
+ openai: {
346
+ segments: diarizedSegments,
347
+ },
348
+ },
349
+ }),
296
350
  };
297
351
  }
298
352