@ai-sdk/openai 3.0.63 → 3.0.65

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.
@@ -165,6 +165,10 @@ The following provider options are available:
165
165
 
166
166
  Whether to store the generation. Defaults to `true`.
167
167
 
168
+ - **passThroughUnsupportedFiles** _boolean_
169
+
170
+ Whether to pass through non-image file types as generic input files. Defaults to `false`, which restricts inline file inputs to images and PDFs. Enable this when the target OpenAI Responses model supports additional file media types.
171
+
168
172
  - **maxToolCalls** _integer_
169
173
  The maximum number of total calls to built-in tools that can be processed in a response.
170
174
  This maximum number applies across all built-in tool calls, not per individual tool.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/openai",
3
- "version": "3.0.63",
3
+ "version": "3.0.65",
4
4
  "license": "Apache-2.0",
5
5
  "sideEffects": false,
6
6
  "main": "./dist/index.js",
@@ -52,8 +52,10 @@ export async function convertToOpenAIResponsesInput({
52
52
  systemMessageMode,
53
53
  providerOptionsName,
54
54
  fileIdPrefixes,
55
+ passThroughUnsupportedFiles = false,
55
56
  store,
56
57
  hasConversation = false,
58
+ hasPreviousResponseId = false,
57
59
  hasLocalShellTool = false,
58
60
  hasShellTool = false,
59
61
  hasApplyPatchTool = false,
@@ -64,8 +66,10 @@ export async function convertToOpenAIResponsesInput({
64
66
  systemMessageMode: 'system' | 'developer' | 'remove';
65
67
  providerOptionsName: string;
66
68
  fileIdPrefixes?: readonly string[];
69
+ passThroughUnsupportedFiles?: boolean;
67
70
  store: boolean;
68
71
  hasConversation?: boolean; // when true, skip assistant messages that already have item IDs
72
+ hasPreviousResponseId?: boolean; // when true, skip reasoning and function-call items that already exist in the previous response chain
69
73
  hasLocalShellTool?: boolean;
70
74
  hasShellTool?: boolean;
71
75
  hasApplyPatchTool?: boolean;
@@ -116,12 +120,10 @@ export async function convertToOpenAIResponsesInput({
116
120
  return { type: 'input_text', text: part.text };
117
121
  }
118
122
  case 'file': {
119
- if (part.mediaType.startsWith('image/')) {
120
- const mediaType =
121
- part.mediaType === 'image/*'
122
- ? 'image/jpeg'
123
- : part.mediaType;
123
+ const mediaType =
124
+ part.mediaType === 'image/*' ? 'image/jpeg' : part.mediaType;
124
125
 
126
+ if (mediaType.startsWith('image/')) {
125
127
  return {
126
128
  type: 'input_image',
127
129
  ...(part.data instanceof URL
@@ -135,28 +137,38 @@ export async function convertToOpenAIResponsesInput({
135
137
  detail:
136
138
  part.providerOptions?.[providerOptionsName]?.imageDetail,
137
139
  };
138
- } else if (part.mediaType === 'application/pdf') {
139
- if (part.data instanceof URL) {
140
- return {
141
- type: 'input_file',
142
- file_url: part.data.toString(),
143
- };
144
- }
140
+ }
141
+
142
+ if (part.data instanceof URL) {
145
143
  return {
146
144
  type: 'input_file',
147
- ...(typeof part.data === 'string' &&
148
- isFileId(part.data, fileIdPrefixes)
149
- ? { file_id: part.data }
150
- : {
151
- filename: part.filename ?? `part-${index}.pdf`,
152
- file_data: `data:application/pdf;base64,${convertToBase64(part.data)}`,
153
- }),
145
+ file_url: part.data.toString(),
154
146
  };
155
- } else {
147
+ }
148
+
149
+ if (
150
+ mediaType !== 'application/pdf' &&
151
+ !passThroughUnsupportedFiles
152
+ ) {
156
153
  throw new UnsupportedFunctionalityError({
157
- functionality: `file part media type ${part.mediaType}`,
154
+ functionality: `file part media type ${mediaType}`,
158
155
  });
159
156
  }
157
+
158
+ return {
159
+ type: 'input_file',
160
+ ...(typeof part.data === 'string' &&
161
+ isFileId(part.data, fileIdPrefixes)
162
+ ? { file_id: part.data }
163
+ : {
164
+ filename:
165
+ part.filename ??
166
+ (mediaType === 'application/pdf'
167
+ ? `part-${index}.pdf`
168
+ : `part-${index}`),
169
+ file_data: `data:${mediaType};base64,${convertToBase64(part.data)}`,
170
+ }),
171
+ };
160
172
  }
161
173
  }
162
174
  }),
@@ -258,6 +270,9 @@ export async function convertToOpenAIResponsesInput({
258
270
  }
259
271
 
260
272
  if (store && id != null) {
273
+ if (hasPreviousResponseId) {
274
+ break;
275
+ }
261
276
  input.push({ type: 'item_reference', id });
262
277
  break;
263
278
  }
@@ -456,7 +471,10 @@ export async function convertToOpenAIResponsesInput({
456
471
 
457
472
  const reasoningId = providerOptions?.itemId;
458
473
 
459
- if (hasConversation && reasoningId != null) {
474
+ if (
475
+ (hasConversation || hasPreviousResponseId) &&
476
+ reasoningId != null
477
+ ) {
460
478
  break;
461
479
  }
462
480
 
@@ -229,8 +229,11 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV3 {
229
229
  : modelCapabilities.systemMessageMode),
230
230
  providerOptionsName,
231
231
  fileIdPrefixes: this.config.fileIdPrefixes,
232
+ passThroughUnsupportedFiles:
233
+ openaiOptions?.passThroughUnsupportedFiles ?? false,
232
234
  store: openaiOptions?.store ?? true,
233
235
  hasConversation: openaiOptions?.conversation != null,
236
+ hasPreviousResponseId: openaiOptions?.previousResponseId != null,
234
237
  hasLocalShellTool: hasOpenAITool('openai.local_shell'),
235
238
  hasShellTool: hasOpenAITool('openai.shell'),
236
239
  hasApplyPatchTool: hasOpenAITool('openai.apply_patch'),
@@ -269,6 +269,15 @@ export const openaiLanguageModelResponsesOptionsSchema = lazySchema(() =>
269
269
  */
270
270
  store: z.boolean().nullish(),
271
271
 
272
+ /**
273
+ * Whether to pass through non-image file types as generic input files.
274
+ *
275
+ * By default, inline file inputs are restricted to images and PDFs.
276
+ * Enable this when the target OpenAI Responses model supports additional
277
+ * file media types, such as text/csv.
278
+ */
279
+ passThroughUnsupportedFiles: z.boolean().optional(),
280
+
272
281
  /**
273
282
  * Whether to use strict JSON schema validation.
274
283
  * Defaults to `true`.