@ai-sdk/openai 4.0.0-beta.12 → 4.0.0-beta.15

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.
@@ -2303,6 +2303,8 @@ The following optional provider options are available for OpenAI completion mode
2303
2303
  | --------------------- | ------------------- | ------------------- | ------------------- | ------------------- |
2304
2304
  | `gpt-5.4-pro` | <Check size={18} /> | <Cross size={18} /> | <Check size={18} /> | <Check size={18} /> |
2305
2305
  | `gpt-5.4` | <Check size={18} /> | <Cross size={18} /> | <Check size={18} /> | <Check size={18} /> |
2306
+ | `gpt-5.4-mini` | <Check size={18} /> | <Cross size={18} /> | <Check size={18} /> | <Check size={18} /> |
2307
+ | `gpt-5.4-nano` | <Check size={18} /> | <Cross size={18} /> | <Check size={18} /> | <Check size={18} /> |
2306
2308
  | `gpt-5.3-chat-latest` | <Check size={18} /> | <Cross size={18} /> | <Check size={18} /> | <Check size={18} /> |
2307
2309
  | `gpt-5.2-pro` | <Check size={18} /> | <Cross size={18} /> | <Check size={18} /> | <Check size={18} /> |
2308
2310
  | `gpt-5.2-chat-latest` | <Check size={18} /> | <Cross size={18} /> | <Check size={18} /> | <Check size={18} /> |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/openai",
3
- "version": "4.0.0-beta.12",
3
+ "version": "4.0.0-beta.15",
4
4
  "license": "Apache-2.0",
5
5
  "sideEffects": false,
6
6
  "main": "./dist/index.js",
@@ -36,8 +36,8 @@
36
36
  }
37
37
  },
38
38
  "dependencies": {
39
- "@ai-sdk/provider": "4.0.0-beta.3",
40
- "@ai-sdk/provider-utils": "5.0.0-beta.5"
39
+ "@ai-sdk/provider": "4.0.0-beta.4",
40
+ "@ai-sdk/provider-utils": "5.0.0-beta.6"
41
41
  },
42
42
  "devDependencies": {
43
43
  "@types/node": "20.17.24",
@@ -17,6 +17,7 @@ import {
17
17
  createEventSourceResponseHandler,
18
18
  createJsonResponseHandler,
19
19
  generateId,
20
+ isCustomReasoning,
20
21
  isParsableJson,
21
22
  parseProviderOptions,
22
23
  postJsonToApi,
@@ -81,6 +82,7 @@ export class OpenAIChatLanguageModel implements LanguageModelV4 {
81
82
  seed,
82
83
  tools,
83
84
  toolChoice,
85
+ reasoning,
84
86
  providerOptions,
85
87
  }: LanguageModelV4CallOptions) {
86
88
  const warnings: SharedV4Warning[] = [];
@@ -94,6 +96,12 @@ export class OpenAIChatLanguageModel implements LanguageModelV4 {
94
96
  })) ?? {};
95
97
 
96
98
  const modelCapabilities = getOpenAILanguageModelCapabilities(this.modelId);
99
+
100
+ // AI SDK reasoning values map directly to the OpenAI reasoning values.
101
+ const resolvedReasoningEffort =
102
+ openaiOptions.reasoningEffort ??
103
+ (isCustomReasoning(reasoning) ? reasoning : undefined);
104
+
97
105
  const isReasoningModel =
98
106
  openaiOptions.forceReasoning ?? modelCapabilities.isReasoningModel;
99
107
 
@@ -168,7 +176,7 @@ export class OpenAIChatLanguageModel implements LanguageModelV4 {
168
176
  store: openaiOptions.store,
169
177
  metadata: openaiOptions.metadata,
170
178
  prediction: openaiOptions.prediction,
171
- reasoning_effort: openaiOptions.reasoningEffort,
179
+ reasoning_effort: resolvedReasoningEffort,
172
180
  service_tier: openaiOptions.serviceTier,
173
181
  prompt_cache_key: openaiOptions.promptCacheKey,
174
182
  prompt_cache_retention: openaiOptions.promptCacheRetention,
@@ -184,7 +192,7 @@ export class OpenAIChatLanguageModel implements LanguageModelV4 {
184
192
  // when reasoning effort is none, gpt-5.1 models allow temperature, topP, logprobs
185
193
  // https://platform.openai.com/docs/guides/latest-model#gpt-5-1-parameter-compatibility
186
194
  if (
187
- openaiOptions.reasoningEffort !== 'none' ||
195
+ resolvedReasoningEffort !== 'none' ||
188
196
  !modelCapabilities.supportsNonReasoningParameters
189
197
  ) {
190
198
  if (baseArgs.temperature != null) {
@@ -54,6 +54,10 @@ export type OpenAIChatModelId =
54
54
  | 'gpt-5.3-chat-latest'
55
55
  | 'gpt-5.4'
56
56
  | 'gpt-5.4-2026-03-05'
57
+ | 'gpt-5.4-mini'
58
+ | 'gpt-5.4-mini-2026-03-17'
59
+ | 'gpt-5.4-nano'
60
+ | 'gpt-5.4-nano-2026-03-17'
57
61
  | 'gpt-5.4-pro'
58
62
  | 'gpt-5.4-pro-2026-03-05'
59
63
  | (string & {});
@@ -20,10 +20,10 @@ export function getOpenAILanguageModelCapabilities(
20
20
 
21
21
  const supportsPriorityProcessing =
22
22
  modelId.startsWith('gpt-4') ||
23
- modelId.startsWith('gpt-5-mini') ||
24
23
  (modelId.startsWith('gpt-5') &&
25
24
  !modelId.startsWith('gpt-5-nano') &&
26
- !modelId.startsWith('gpt-5-chat')) ||
25
+ !modelId.startsWith('gpt-5-chat') &&
26
+ !modelId.startsWith('gpt-5.4-nano')) ||
27
27
  modelId.startsWith('o3') ||
28
28
  modelId.startsWith('o4-mini');
29
29
 
@@ -503,6 +503,31 @@ export const openaiResponsesChunkSchema = lazySchema(() =>
503
503
  service_tier: z.string().nullish(),
504
504
  }),
505
505
  }),
506
+ z.object({
507
+ type: z.literal('response.failed'),
508
+ response: z.object({
509
+ error: z
510
+ .object({
511
+ code: z.string().nullish(),
512
+ message: z.string(),
513
+ })
514
+ .nullish(),
515
+ incomplete_details: z.object({ reason: z.string() }).nullish(),
516
+ usage: z
517
+ .object({
518
+ input_tokens: z.number(),
519
+ input_tokens_details: z
520
+ .object({ cached_tokens: z.number().nullish() })
521
+ .nullish(),
522
+ output_tokens: z.number(),
523
+ output_tokens_details: z
524
+ .object({ reasoning_tokens: z.number().nullish() })
525
+ .nullish(),
526
+ })
527
+ .nullish(),
528
+ service_tier: z.string().nullish(),
529
+ }),
530
+ }),
506
531
  z.object({
507
532
  type: z.literal('response.created'),
508
533
  response: z.object({
@@ -21,6 +21,7 @@ import {
21
21
  createToolNameMapping,
22
22
  generateId,
23
23
  InferSchema,
24
+ isCustomReasoning,
24
25
  parseProviderOptions,
25
26
  ParseResult,
26
27
  postJsonToApi,
@@ -130,6 +131,7 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
130
131
  frequencyPenalty,
131
132
  seed,
132
133
  prompt,
134
+ reasoning,
133
135
  providerOptions,
134
136
  tools,
135
137
  toolChoice,
@@ -175,6 +177,10 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
175
177
  });
176
178
  }
177
179
 
180
+ const resolvedReasoningEffort =
181
+ openaiOptions?.reasoningEffort ??
182
+ (isCustomReasoning(reasoning) ? reasoning : undefined);
183
+
178
184
  const isReasoningModel =
179
185
  openaiOptions?.forceReasoning ?? modelCapabilities.isReasoningModel;
180
186
 
@@ -348,11 +354,11 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
348
354
 
349
355
  // model-specific settings:
350
356
  ...(isReasoningModel &&
351
- (openaiOptions?.reasoningEffort != null ||
357
+ (resolvedReasoningEffort != null ||
352
358
  openaiOptions?.reasoningSummary != null) && {
353
359
  reasoning: {
354
- ...(openaiOptions?.reasoningEffort != null && {
355
- effort: openaiOptions.reasoningEffort,
360
+ ...(resolvedReasoningEffort != null && {
361
+ effort: resolvedReasoningEffort,
356
362
  }),
357
363
  ...(openaiOptions?.reasoningSummary != null && {
358
364
  summary: openaiOptions.reasoningSummary,
@@ -368,7 +374,7 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
368
374
  // https://platform.openai.com/docs/guides/latest-model#gpt-5-1-parameter-compatibility
369
375
  if (
370
376
  !(
371
- openaiOptions?.reasoningEffort === 'none' &&
377
+ resolvedReasoningEffort === 'none' &&
372
378
  modelCapabilities.supportsNonReasoningParameters
373
379
  )
374
380
  ) {
@@ -2038,6 +2044,19 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
2038
2044
  if (typeof value.response.service_tier === 'string') {
2039
2045
  serviceTier = value.response.service_tier;
2040
2046
  }
2047
+ } else if (isResponseFailedChunk(value)) {
2048
+ const incompleteReason =
2049
+ value.response.incomplete_details?.reason;
2050
+ finishReason = {
2051
+ unified: incompleteReason
2052
+ ? mapOpenAIResponseFinishReason({
2053
+ finishReason: incompleteReason,
2054
+ hasFunctionCall,
2055
+ })
2056
+ : 'error',
2057
+ raw: incompleteReason ?? 'error',
2058
+ };
2059
+ usage = value.response.usage ?? undefined;
2041
2060
  } else if (isResponseAnnotationAddedChunk(value)) {
2042
2061
  ongoingAnnotations.push(value.annotation);
2043
2062
  if (value.annotation.type === 'url_citation') {
@@ -2157,6 +2176,12 @@ function isResponseFinishedChunk(
2157
2176
  );
2158
2177
  }
2159
2178
 
2179
+ function isResponseFailedChunk(
2180
+ chunk: OpenAIResponsesChunk,
2181
+ ): chunk is OpenAIResponsesChunk & { type: 'response.failed' } {
2182
+ return chunk.type === 'response.failed';
2183
+ }
2184
+
2160
2185
  function isResponseCreatedChunk(
2161
2186
  chunk: OpenAIResponsesChunk,
2162
2187
  ): chunk is OpenAIResponsesChunk & { type: 'response.created' } {
@@ -41,6 +41,10 @@ export const openaiResponsesReasoningModelIds = [
41
41
  'gpt-5.3-codex',
42
42
  'gpt-5.4',
43
43
  'gpt-5.4-2026-03-05',
44
+ 'gpt-5.4-mini',
45
+ 'gpt-5.4-mini-2026-03-17',
46
+ 'gpt-5.4-nano',
47
+ 'gpt-5.4-nano-2026-03-17',
44
48
  'gpt-5.4-pro',
45
49
  'gpt-5.4-pro-2026-03-05',
46
50
  ] as const;
@@ -103,6 +107,10 @@ export type OpenAIResponsesModelId =
103
107
  | 'gpt-5.3-codex'
104
108
  | 'gpt-5.4'
105
109
  | 'gpt-5.4-2026-03-05'
110
+ | 'gpt-5.4-mini'
111
+ | 'gpt-5.4-mini-2026-03-17'
112
+ | 'gpt-5.4-nano'
113
+ | 'gpt-5.4-nano-2026-03-17'
106
114
  | 'gpt-5.4-pro'
107
115
  | 'gpt-5.4-pro-2026-03-05'
108
116
  | 'gpt-5-2025-08-07'