@ai-sdk/openai 4.0.17 → 4.0.19

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/openai",
3
- "version": "4.0.17",
3
+ "version": "4.0.19",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "sideEffects": false,
@@ -26,13 +26,7 @@ export const modelMaxImagesPerCall: Record<OpenAIImageModelId, number> = {
26
26
  'chatgpt-image-latest': 10,
27
27
  };
28
28
 
29
- const defaultResponseFormatPrefixes = [
30
- 'chatgpt-image-',
31
- 'gpt-image-1-mini',
32
- 'gpt-image-1.5',
33
- 'gpt-image-1',
34
- 'gpt-image-2',
35
- ];
29
+ const defaultResponseFormatPrefixes = ['chatgpt-image-', 'gpt-image-'];
36
30
 
37
31
  export function hasDefaultResponseFormat(modelId: string): boolean {
38
32
  return defaultResponseFormatPrefixes.some(prefix =>
@@ -40,6 +34,13 @@ export function hasDefaultResponseFormat(modelId: string): boolean {
40
34
  );
41
35
  }
42
36
 
37
+ export function getMaxImagesPerCall(modelId: OpenAIImageModelId): number {
38
+ return (
39
+ modelMaxImagesPerCall[modelId] ??
40
+ (modelId.startsWith('gpt-image-') ? 10 : 1)
41
+ );
42
+ }
43
+
43
44
  const baseImageModelOptionsObject = z.object({
44
45
  /**
45
46
  * Quality of the generated image(s).
@@ -20,8 +20,8 @@ import type { OpenAIConfig } from '../openai-config';
20
20
  import { openaiFailedResponseHandler } from '../openai-error';
21
21
  import { openaiImageResponseSchema } from './openai-image-api';
22
22
  import {
23
+ getMaxImagesPerCall,
23
24
  hasDefaultResponseFormat,
24
- modelMaxImagesPerCall,
25
25
  openaiImageModelEditOptions,
26
26
  openaiImageModelGenerationOptions,
27
27
  type OpenAIImageModelEditOptions,
@@ -51,7 +51,7 @@ export class OpenAIImageModel implements ImageModelV4 {
51
51
  }
52
52
 
53
53
  get maxImagesPerCall(): number {
54
- return modelMaxImagesPerCall[this.modelId] ?? 1;
54
+ return getMaxImagesPerCall(this.modelId);
55
55
  }
56
56
 
57
57
  get provider(): string {
@@ -13,37 +13,37 @@ export type OpenAILanguageModelCapabilities = {
13
13
  export function getOpenAILanguageModelCapabilities(
14
14
  modelId: string,
15
15
  ): OpenAILanguageModelCapabilities {
16
+ const oSeriesVersion = getOSeriesVersion(modelId);
17
+ const gptVersion = getGptVersion(modelId);
18
+ const isGptChatModel =
19
+ gptVersion?.minor == null &&
20
+ (gptVersion?.variant?.startsWith('chat') ?? false);
21
+ const isGptNanoModel = gptVersion?.variant?.startsWith('nano') ?? false;
22
+
16
23
  const supportsFlexProcessing =
17
- modelId.startsWith('o3') ||
18
- modelId.startsWith('o4-mini') ||
19
- (modelId.startsWith('gpt-5') && !modelId.startsWith('gpt-5-chat'));
24
+ (oSeriesVersion != null && oSeriesVersion >= 3) ||
25
+ (gptVersion != null && gptVersion.major >= 5 && !isGptChatModel);
20
26
 
21
27
  const supportsPriorityProcessing =
22
28
  modelId.startsWith('gpt-4') ||
23
- (modelId.startsWith('gpt-5') &&
24
- !modelId.startsWith('gpt-5-nano') &&
25
- !modelId.startsWith('gpt-5-chat') &&
26
- !modelId.startsWith('gpt-5.4-nano')) ||
27
- modelId.startsWith('o3') ||
28
- modelId.startsWith('o4-mini');
29
-
30
- // Use allowlist approach: only known reasoning models should use 'developer' role
31
- // This prevents issues with fine-tuned models, third-party models, and custom models
29
+ (gptVersion != null &&
30
+ gptVersion.major >= 5 &&
31
+ !isGptNanoModel &&
32
+ !isGptChatModel) ||
33
+ (oSeriesVersion != null && oSeriesVersion >= 3);
34
+
35
+ // Only recognizable OpenAI model families should use the developer role.
36
+ // Fine-tuned, third-party, and custom model IDs keep conservative defaults.
32
37
  const isReasoningModel =
33
- modelId.startsWith('o1') ||
34
- modelId.startsWith('o3') ||
35
- modelId.startsWith('o4-mini') ||
36
- (modelId.startsWith('gpt-5') && !modelId.startsWith('gpt-5-chat'));
38
+ oSeriesVersion != null ||
39
+ (gptVersion != null && gptVersion.major >= 5 && !isGptChatModel);
37
40
 
38
41
  // https://platform.openai.com/docs/guides/latest-model#gpt-5-1-parameter-compatibility
39
42
  // GPT-5.1 and later model families support temperature, topP, logProbs when reasoningEffort is none.
40
43
  const supportsNonReasoningParameters =
41
- modelId.startsWith('gpt-5.1') ||
42
- modelId.startsWith('gpt-5.2') ||
43
- modelId.startsWith('gpt-5.3') ||
44
- modelId.startsWith('gpt-5.4') ||
45
- modelId.startsWith('gpt-5.5') ||
46
- modelId.startsWith('gpt-5.6');
44
+ gptVersion != null &&
45
+ (gptVersion.major > 5 ||
46
+ (gptVersion.major === 5 && (gptVersion.minor ?? 0) >= 1));
47
47
 
48
48
  const systemMessageMode = isReasoningModel ? 'developer' : 'system';
49
49
 
@@ -55,3 +55,28 @@ export function getOpenAILanguageModelCapabilities(
55
55
  supportsNonReasoningParameters,
56
56
  };
57
57
  }
58
+
59
+ function getOSeriesVersion(modelId: string): number | undefined {
60
+ const match = /^o(\d+)(?:-|$)/.exec(modelId);
61
+ return match == null ? undefined : Number(match[1]);
62
+ }
63
+
64
+ function getGptVersion(modelId: string):
65
+ | {
66
+ major: number;
67
+ minor: number | undefined;
68
+ variant: string | undefined;
69
+ }
70
+ | undefined {
71
+ const match = /^gpt-(\d+)(?:\.(\d+))?(?:-(.+))?$/.exec(modelId);
72
+
73
+ if (match == null) {
74
+ return undefined;
75
+ }
76
+
77
+ return {
78
+ major: Number(match[1]),
79
+ minor: match[2] == null ? undefined : Number(match[2]),
80
+ variant: match[3],
81
+ };
82
+ }
@@ -581,12 +581,16 @@ export async function convertToOpenAIResponsesInput({
581
581
  );
582
582
 
583
583
  if (resolvedResultToolName === 'tool_search') {
584
- const itemId =
584
+ const itemId = (part.providerOptions?.[providerOptionsName]
585
+ ?.itemId ??
585
586
  (
586
- part.providerOptions?.[providerOptionsName] as
587
- | { itemId?: string }
588
- | undefined
589
- )?.itemId ?? part.toolCallId;
587
+ part as {
588
+ providerMetadata?: {
589
+ [providerOptionsName]?: { itemId?: string };
590
+ };
591
+ }
592
+ ).providerMetadata?.[providerOptionsName]?.itemId ??
593
+ part.toolCallId) as string;
590
594
 
591
595
  if (store) {
592
596
  input.push({ type: 'item_reference', id: itemId });