@ai-sdk/openai 4.0.59 → 4.0.60

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.
@@ -192,9 +192,23 @@ The following provider options are available:
192
192
 
193
193
  <Note>
194
194
  Supported reasoning efforts vary by model. GPT-5.6 supports `'none'`, `'low'`,
195
- `'medium'`, `'high'`, `'xhigh'`, and `'max'`.
195
+ `'medium'`, `'high'`, `'xhigh'`, and `'max'`. GPT-6 and later models support
196
+ `'low'`, `'medium'`, `'high'`, `'xhigh'`, and `'max'`.
196
197
  </Note>
197
198
 
199
+ <Note type="warning">
200
+ GPT-6 and later models do not support `temperature`, `topP`, `logprobs`, or
201
+ the legacy `promptCacheRetention` option. The provider removes these settings
202
+ and returns a warning. Use the Responses API for GPT-6 tool calling.
203
+ </Note>
204
+
205
+ - **reasoningEffortUpdate** _'low' | 'medium' | 'high' | 'xhigh' | 'max'_
206
+ Updates the reasoning effort for GPT-6 and later models starting with the
207
+ current response without changing the request-level effort. Use this with
208
+ `previousResponseId` to preserve the original prompt prefix for caching.
209
+ Configuration updates require standard, single-agent mode and cannot be
210
+ combined with automatic compaction or automatic truncation.
211
+
198
212
  - **reasoningMode** _'standard' | 'pro'_
199
213
  Controls how much model work GPT-5.6 performs before returning a final answer. `'standard'` is the default. Use `'pro'` for difficult tasks where quality matters more than latency and token usage.
200
214
 
@@ -302,6 +316,57 @@ The following OpenAI-specific metadata may be returned:
302
316
  - **reasoningContext** _(optional)_
303
317
  Effective persisted-reasoning context returned by GPT-5.6 (`'current_turn'` or `'all_turns'`).
304
318
 
319
+ #### Changing Reasoning Effort Mid-Conversation
320
+
321
+ GPT-6 and later models can change reasoning effort between responses without
322
+ changing the request-level `reasoning` setting. The provider sends
323
+ `reasoningEffortUpdate` as an OpenAI `configuration_update` input item before
324
+ the next user message. Keeping the request-level effort unchanged preserves the
325
+ original prompt prefix for prompt caching.
326
+
327
+ ```ts highlight="8,26,32"
328
+ import {
329
+ openai,
330
+ type OpenAILanguageModelResponsesOptions,
331
+ type OpenaiResponsesProviderMetadata,
332
+ } from '@ai-sdk/openai';
333
+ import { generateText } from 'ai';
334
+
335
+ const first = await generateText({
336
+ model: openai.responses('gpt-6-astra'),
337
+ reasoning: 'low',
338
+ prompt: 'Draft a database migration plan.',
339
+ });
340
+
341
+ const metadata = first.finalStep.providerMetadata as
342
+ | OpenaiResponsesProviderMetadata
343
+ | undefined;
344
+ const previousResponseId = metadata?.openai.responseId;
345
+
346
+ if (!previousResponseId) {
347
+ throw new Error('OpenAI did not return a response ID.');
348
+ }
349
+
350
+ const second = await generateText({
351
+ model: openai.responses('gpt-6-astra'),
352
+ reasoning: 'low',
353
+ prompt: 'Analyze the failure modes and propose rollback steps.',
354
+ providerOptions: {
355
+ openai: {
356
+ previousResponseId,
357
+ reasoningEffortUpdate: 'high',
358
+ } satisfies OpenAILanguageModelResponsesOptions,
359
+ },
360
+ });
361
+ ```
362
+
363
+ The response metadata continues to report the request-level reasoning effort,
364
+ not the effective effort selected by `reasoningEffortUpdate`. Configuration
365
+ updates are not supported with `reasoningMode: 'pro'`,
366
+ `contextManagement`, or `truncation: 'auto'`. Explicit compaction with
367
+ `compactionTrigger` remains supported; send a new `reasoningEffortUpdate` after
368
+ compaction when the effort should change again.
369
+
305
370
  #### Reasoning Output
306
371
 
307
372
  For reasoning models like `gpt-5`, you can enable reasoning summaries to see the model's thought process. Different models support different summarizers—for example, `o4-mini` supports detailed summaries. Set `reasoningSummary: "auto"` to automatically receive the richest level available. When `reasoningEffort` is set to a value other than `'none'`, the OpenAI Responses provider defaults `reasoningSummary` to `'detailed'`; set `reasoningSummary: null` to omit reasoning summaries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/openai",
3
- "version": "4.0.59",
3
+ "version": "4.0.60",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "sideEffects": false,
@@ -118,10 +118,25 @@ export class OpenAIChatLanguageModel implements LanguageModelV4 {
118
118
  const modelCapabilities = getOpenAILanguageModelCapabilities(this.modelId);
119
119
 
120
120
  // AI SDK reasoning values map directly to the OpenAI reasoning values.
121
- const resolvedReasoningEffort =
121
+ let resolvedReasoningEffort =
122
122
  openaiOptions.reasoningEffort ??
123
123
  (isCustomReasoning(reasoning) ? reasoning : undefined);
124
124
 
125
+ if (
126
+ resolvedReasoningEffort != null &&
127
+ modelCapabilities.supportedReasoningEfforts != null &&
128
+ !modelCapabilities.supportedReasoningEfforts.includes(
129
+ resolvedReasoningEffort,
130
+ )
131
+ ) {
132
+ warnings.push({
133
+ type: 'unsupported',
134
+ feature: 'reasoningEffort',
135
+ details: `${this.modelId} only supports the following reasoning efforts: ${modelCapabilities.supportedReasoningEfforts.join(', ')}`,
136
+ });
137
+ resolvedReasoningEffort = undefined;
138
+ }
139
+
125
140
  const isReasoningModel =
126
141
  openaiOptions.forceReasoning ?? modelCapabilities.isReasoningModel;
127
142
 
@@ -207,6 +222,19 @@ export class OpenAIChatLanguageModel implements LanguageModelV4 {
207
222
  messages,
208
223
  };
209
224
 
225
+ if (
226
+ modelCapabilities.supportedReasoningEfforts != null &&
227
+ baseArgs.prompt_cache_retention != null
228
+ ) {
229
+ baseArgs.prompt_cache_retention = undefined;
230
+ warnings.push({
231
+ type: 'unsupported',
232
+ feature: 'promptCacheRetention',
233
+ details:
234
+ 'promptCacheRetention is not supported by GPT-6 and later models; use promptCacheOptions instead',
235
+ });
236
+ }
237
+
210
238
  // remove unsupported settings for reasoning models
211
239
  // see https://platform.openai.com/docs/guides/reasoning#limitations
212
240
  if (isReasoningModel) {
@@ -3,6 +3,8 @@ export type OpenAILanguageModelCapabilities = {
3
3
  systemMessageMode: 'remove' | 'system' | 'developer';
4
4
  supportsFlexProcessing: boolean;
5
5
  supportsPriorityProcessing: boolean;
6
+ supportsConfigurationUpdate: boolean;
7
+ supportedReasoningEfforts: readonly string[] | undefined;
6
8
 
7
9
  /**
8
10
  * Allow temperature, topP, logProbs when reasoningEffort is none.
@@ -19,6 +21,7 @@ export function getOpenAILanguageModelCapabilities(
19
21
  gptVersion?.minor == null &&
20
22
  (gptVersion?.variant?.startsWith('chat') ?? false);
21
23
  const isGptNanoModel = gptVersion?.variant?.startsWith('nano') ?? false;
24
+ const isGpt6OrLaterModel = gptVersion != null && gptVersion.major >= 6;
22
25
 
23
26
  const supportsFlexProcessing =
24
27
  (oSeriesVersion != null && oSeriesVersion >= 3) ||
@@ -41,6 +44,7 @@ export function getOpenAILanguageModelCapabilities(
41
44
  // https://platform.openai.com/docs/guides/latest-model#gpt-5-1-parameter-compatibility
42
45
  // GPT-5.1 and later model families support temperature, topP, logProbs when reasoningEffort is none.
43
46
  const supportsNonReasoningParameters =
47
+ !isGpt6OrLaterModel &&
44
48
  gptVersion != null &&
45
49
  (gptVersion.major > 5 ||
46
50
  (gptVersion.major === 5 && (gptVersion.minor ?? 0) >= 1));
@@ -50,6 +54,10 @@ export function getOpenAILanguageModelCapabilities(
50
54
  return {
51
55
  supportsFlexProcessing,
52
56
  supportsPriorityProcessing,
57
+ supportsConfigurationUpdate: isGpt6OrLaterModel,
58
+ supportedReasoningEfforts: isGpt6OrLaterModel
59
+ ? ['low', 'medium', 'high', 'xhigh', 'max']
60
+ : undefined,
53
61
  isReasoningModel,
54
62
  systemMessageMode,
55
63
  supportsNonReasoningParameters,
@@ -180,6 +180,7 @@ export type OpenAIResponsesInputItem =
180
180
  | OpenAIResponsesReasoning
181
181
  | OpenAIResponsesItemReference
182
182
  | OpenAIResponsesCompactionItem
183
+ | OpenAIResponsesConfigurationUpdate
183
184
  | OpenAIResponsesCompactionTrigger;
184
185
 
185
186
  export type OpenAIResponsesIncludeValue =
@@ -468,6 +469,13 @@ export type OpenAIResponsesCompactionItem = {
468
469
  encrypted_content: string;
469
470
  };
470
471
 
472
+ export type OpenAIResponsesConfigurationUpdate = {
473
+ type: 'configuration_update';
474
+ reasoning: {
475
+ effort: 'low' | 'medium' | 'high' | 'xhigh' | 'max';
476
+ };
477
+ };
478
+
471
479
  export type OpenAIResponsesCompactionTrigger = {
472
480
  type: 'compaction_trigger';
473
481
  };
@@ -264,6 +264,18 @@ export const openaiLanguageModelResponsesOptionsSchema = lazySchema(() =>
264
264
  */
265
265
  reasoningEffort: z.string().nullish(),
266
266
 
267
+ /**
268
+ * Updates the reasoning effort for GPT-6 and later models starting with this response
269
+ * without changing the request-level reasoning effort. This preserves the
270
+ * request prefix for prompt caching.
271
+ *
272
+ * Only supported by GPT-6 and later models in standard, single-agent mode. Cannot be
273
+ * combined with automatic compaction or automatic truncation.
274
+ */
275
+ reasoningEffortUpdate: z
276
+ .enum(['low', 'medium', 'high', 'xhigh', 'max'])
277
+ .optional(),
278
+
267
279
  /**
268
280
  * Controls how much model work GPT-5.6 performs before returning a final answer.
269
281
  * `standard` is the default. `pro` increases quality, latency, and token usage.
@@ -296,9 +296,25 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
296
296
  });
297
297
  }
298
298
 
299
- const resolvedReasoningEffort =
299
+ let resolvedReasoningEffort =
300
300
  openaiOptions?.reasoningEffort ??
301
301
  (isCustomReasoning(reasoning) ? reasoning : undefined);
302
+
303
+ if (
304
+ resolvedReasoningEffort != null &&
305
+ modelCapabilities.supportedReasoningEfforts != null &&
306
+ !modelCapabilities.supportedReasoningEfforts.includes(
307
+ resolvedReasoningEffort,
308
+ )
309
+ ) {
310
+ warnings.push({
311
+ type: 'unsupported',
312
+ feature: 'reasoningEffort',
313
+ details: `${this.modelId} only supports the following reasoning efforts: ${modelCapabilities.supportedReasoningEfforts.join(', ')}`,
314
+ });
315
+ resolvedReasoningEffort = undefined;
316
+ }
317
+
302
318
  const resolvedReasoningSummary =
303
319
  openaiOptions?.reasoningSummary !== undefined
304
320
  ? openaiOptions.reasoningSummary
@@ -384,6 +400,29 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
384
400
 
385
401
  warnings.push(...inputWarnings);
386
402
 
403
+ const reasoningEffortUpdate = openaiOptions?.reasoningEffortUpdate;
404
+ const configurationUpdateIsSupported =
405
+ reasoningEffortUpdate == null ||
406
+ (modelCapabilities.supportsConfigurationUpdate &&
407
+ openaiOptions?.reasoningMode !== 'pro' &&
408
+ openaiOptions?.contextManagement == null &&
409
+ openaiOptions?.truncation !== 'auto');
410
+
411
+ if (reasoningEffortUpdate != null && !configurationUpdateIsSupported) {
412
+ warnings.push({
413
+ type: 'unsupported',
414
+ feature: 'reasoningEffortUpdate',
415
+ details: !modelCapabilities.supportsConfigurationUpdate
416
+ ? 'reasoningEffortUpdate is only supported by GPT-6 and later models'
417
+ : 'reasoningEffortUpdate requires standard reasoning mode without automatic compaction or automatic truncation',
418
+ });
419
+ } else if (reasoningEffortUpdate != null) {
420
+ input.unshift({
421
+ type: 'configuration_update',
422
+ reasoning: { effort: reasoningEffortUpdate },
423
+ });
424
+ }
425
+
387
426
  // A compaction trigger is a request control, not conversation history.
388
427
  // OpenAI requires it to be the final input item, so append it only after
389
428
  // the complete prompt has been converted.
@@ -526,6 +565,19 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
526
565
  }),
527
566
  };
528
567
 
568
+ if (
569
+ modelCapabilities.supportsConfigurationUpdate &&
570
+ baseArgs.prompt_cache_retention != null
571
+ ) {
572
+ baseArgs.prompt_cache_retention = undefined;
573
+ warnings.push({
574
+ type: 'unsupported',
575
+ feature: 'promptCacheRetention',
576
+ details:
577
+ 'promptCacheRetention is not supported by GPT-6 and later models; use promptCacheOptions instead',
578
+ });
579
+ }
580
+
529
581
  // remove unsupported settings for reasoning models
530
582
  // see https://platform.openai.com/docs/guides/reasoning#limitations
531
583
  if (isReasoningModel) {
@@ -554,6 +606,26 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
554
606
  details: 'topP is not supported for reasoning models',
555
607
  });
556
608
  }
609
+
610
+ if (
611
+ modelCapabilities.supportedReasoningEfforts != null &&
612
+ (baseArgs.top_logprobs != null ||
613
+ baseArgs.include?.includes('message.output_text.logprobs'))
614
+ ) {
615
+ baseArgs.top_logprobs = undefined;
616
+ const filteredInclude = baseArgs.include?.filter(
617
+ value => value !== 'message.output_text.logprobs',
618
+ );
619
+ baseArgs.include =
620
+ filteredInclude != null && filteredInclude.length > 0
621
+ ? filteredInclude
622
+ : undefined;
623
+ warnings.push({
624
+ type: 'unsupported',
625
+ feature: 'logprobs',
626
+ details: 'logprobs is not supported for reasoning models',
627
+ });
628
+ }
557
629
  }
558
630
  } else {
559
631
  if (openaiOptions?.reasoningEffort != null) {