@ai-sdk/openai 4.0.56 → 4.0.57
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/CHANGELOG.md +7 -0
- package/dist/index.d.ts +14 -12
- package/dist/index.js +83 -59
- package/dist/index.js.map +1 -1
- package/dist/internal/index.d.ts +14 -12
- package/dist/internal/index.js +28 -42
- package/dist/internal/index.js.map +1 -1
- package/package.json +1 -1
- package/src/openai-responses-batch.ts +60 -5
- package/src/responses/convert-openai-responses-usage.ts +17 -12
- package/src/responses/openai-responses-api.ts +34 -60
package/package.json
CHANGED
|
@@ -20,6 +20,7 @@ import {
|
|
|
20
20
|
getFromApi,
|
|
21
21
|
lazySchema,
|
|
22
22
|
normalizeBatchRequestCounts,
|
|
23
|
+
parseProviderOptions,
|
|
23
24
|
postJsonToApi,
|
|
24
25
|
postToApi,
|
|
25
26
|
safeValidateTypes,
|
|
@@ -52,7 +53,25 @@ import type { OpenAIResponsesModelId } from './responses/openai-responses-langua
|
|
|
52
53
|
import type { ResponsesReasoningProviderMetadata } from './responses/openai-responses-provider-metadata';
|
|
53
54
|
|
|
54
55
|
const openaiBatchEndpoint = '/v1/responses';
|
|
55
|
-
const
|
|
56
|
+
const openaiBatchInputFileDefaultExpiresAfterSeconds = 48 * 60 * 60;
|
|
57
|
+
|
|
58
|
+
const openaiBatchProviderOptionsSchema = lazySchema(() =>
|
|
59
|
+
zodSchema(
|
|
60
|
+
z.object({
|
|
61
|
+
/**
|
|
62
|
+
* TTL in seconds for the uploaded batch input file, measured from
|
|
63
|
+
* upload time. OpenAI accepts integers between 3600 (1 hour) and
|
|
64
|
+
* 2592000 (30 days) inclusive. Defaults to 48 hours.
|
|
65
|
+
*/
|
|
66
|
+
inputFileExpiresAfter: z
|
|
67
|
+
.number()
|
|
68
|
+
.int()
|
|
69
|
+
.min(3600)
|
|
70
|
+
.max(2_592_000)
|
|
71
|
+
.optional(),
|
|
72
|
+
}),
|
|
73
|
+
),
|
|
74
|
+
);
|
|
56
75
|
|
|
57
76
|
type OpenAIBatchRequest = Parameters<
|
|
58
77
|
BatchLanguageModelV4['experimental_doStartBatch']
|
|
@@ -153,6 +172,13 @@ class OpenAIResponsesBatch {
|
|
|
153
172
|
},
|
|
154
173
|
];
|
|
155
174
|
|
|
175
|
+
const batchOptions = await this.parseBatchProviderOptions(
|
|
176
|
+
options.providerOptions,
|
|
177
|
+
);
|
|
178
|
+
const inputFileExpiresAfterSeconds =
|
|
179
|
+
batchOptions?.inputFileExpiresAfter ??
|
|
180
|
+
openaiBatchInputFileDefaultExpiresAfterSeconds;
|
|
181
|
+
|
|
156
182
|
for (const request of options.requests) {
|
|
157
183
|
const preparedRequest = await this.options.prepareRequest(request);
|
|
158
184
|
|
|
@@ -200,7 +226,7 @@ class OpenAIResponsesBatch {
|
|
|
200
226
|
formData.append('expires_after[anchor]', 'created_at');
|
|
201
227
|
formData.append(
|
|
202
228
|
'expires_after[seconds]',
|
|
203
|
-
String(
|
|
229
|
+
String(inputFileExpiresAfterSeconds),
|
|
204
230
|
);
|
|
205
231
|
|
|
206
232
|
const { value: uploadedFile } = await postToApi({
|
|
@@ -211,9 +237,7 @@ class OpenAIResponsesBatch {
|
|
|
211
237
|
values: {
|
|
212
238
|
purpose: 'batch',
|
|
213
239
|
'expires_after[anchor]': 'created_at',
|
|
214
|
-
'expires_after[seconds]': String(
|
|
215
|
-
openaiBatchInputFileExpiresAfterSeconds,
|
|
216
|
-
),
|
|
240
|
+
'expires_after[seconds]': String(inputFileExpiresAfterSeconds),
|
|
217
241
|
file: {
|
|
218
242
|
name: filename,
|
|
219
243
|
type: file.type,
|
|
@@ -245,13 +269,44 @@ class OpenAIResponsesBatch {
|
|
|
245
269
|
fetch: this.options.config.fetch,
|
|
246
270
|
});
|
|
247
271
|
|
|
272
|
+
const inputFileExpiresAt = convertUnixTimestamp(uploadedFile.expires_at);
|
|
273
|
+
|
|
248
274
|
return {
|
|
249
275
|
batchId: batch.id,
|
|
250
276
|
...convertOpenAIBatchStatus(batch),
|
|
277
|
+
providerMetadata: {
|
|
278
|
+
openai: {
|
|
279
|
+
inputFileId: uploadedFile.id,
|
|
280
|
+
...(inputFileExpiresAt != null ? { inputFileExpiresAt } : {}),
|
|
281
|
+
},
|
|
282
|
+
},
|
|
251
283
|
warnings,
|
|
252
284
|
};
|
|
253
285
|
}
|
|
254
286
|
|
|
287
|
+
private async parseBatchProviderOptions(
|
|
288
|
+
providerOptions: BatchV4StartOptions<OpenAIBatchRequest>['providerOptions'],
|
|
289
|
+
) {
|
|
290
|
+
const providerOptionsName = this.options.config.provider.includes('azure')
|
|
291
|
+
? 'azure'
|
|
292
|
+
: 'openai';
|
|
293
|
+
let batchOptions = await parseProviderOptions({
|
|
294
|
+
provider: providerOptionsName,
|
|
295
|
+
providerOptions,
|
|
296
|
+
schema: openaiBatchProviderOptionsSchema,
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
if (batchOptions == null && providerOptionsName !== 'openai') {
|
|
300
|
+
batchOptions = await parseProviderOptions({
|
|
301
|
+
provider: 'openai',
|
|
302
|
+
providerOptions,
|
|
303
|
+
schema: openaiBatchProviderOptionsSchema,
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
return batchOptions;
|
|
308
|
+
}
|
|
309
|
+
|
|
255
310
|
async getBatchStatus(
|
|
256
311
|
options: BatchV4OperationOptions,
|
|
257
312
|
): Promise<BatchV4Status> {
|
|
@@ -1,19 +1,24 @@
|
|
|
1
|
-
import type { LanguageModelV4Usage } from '@ai-sdk/provider';
|
|
1
|
+
import type { JSONObject, LanguageModelV4Usage } from '@ai-sdk/provider';
|
|
2
2
|
import { createNullLanguageModelUsage } from '@ai-sdk/provider-utils';
|
|
3
3
|
|
|
4
|
-
export type OpenAIResponsesUsage = {
|
|
4
|
+
export type OpenAIResponsesUsage = JSONObject & {
|
|
5
5
|
input_tokens: number;
|
|
6
6
|
output_tokens: number;
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
7
|
+
total_tokens?: number;
|
|
8
|
+
input_tokens_details?:
|
|
9
|
+
| (JSONObject & {
|
|
10
|
+
cached_tokens?: number | null;
|
|
11
|
+
cache_write_tokens?: number | null;
|
|
12
|
+
orchestration_input_tokens?: number | null;
|
|
13
|
+
orchestration_input_cached_tokens?: number | null;
|
|
14
|
+
})
|
|
15
|
+
| null;
|
|
16
|
+
output_tokens_details?:
|
|
17
|
+
| (JSONObject & {
|
|
18
|
+
reasoning_tokens?: number | null;
|
|
19
|
+
orchestration_output_tokens?: number | null;
|
|
20
|
+
})
|
|
21
|
+
| null;
|
|
17
22
|
};
|
|
18
23
|
|
|
19
24
|
export function convertOpenAIResponsesUsage(
|
|
@@ -18,6 +18,37 @@ const jsonValueSchema: z.ZodType<JSONValue> = z.lazy(() =>
|
|
|
18
18
|
]),
|
|
19
19
|
);
|
|
20
20
|
|
|
21
|
+
const jsonObjectSchema = z.record(z.string(), jsonValueSchema.optional());
|
|
22
|
+
|
|
23
|
+
const openaiResponsesUsageSchema = z.intersection(
|
|
24
|
+
jsonObjectSchema,
|
|
25
|
+
z.object({
|
|
26
|
+
input_tokens: z.number(),
|
|
27
|
+
input_tokens_details: z
|
|
28
|
+
.intersection(
|
|
29
|
+
jsonObjectSchema,
|
|
30
|
+
z.object({
|
|
31
|
+
cached_tokens: z.number().nullish(),
|
|
32
|
+
cache_write_tokens: z.number().nullish(),
|
|
33
|
+
orchestration_input_tokens: z.number().nullish(),
|
|
34
|
+
orchestration_input_cached_tokens: z.number().nullish(),
|
|
35
|
+
}),
|
|
36
|
+
)
|
|
37
|
+
.nullish(),
|
|
38
|
+
output_tokens: z.number(),
|
|
39
|
+
output_tokens_details: z
|
|
40
|
+
.intersection(
|
|
41
|
+
jsonObjectSchema,
|
|
42
|
+
z.object({
|
|
43
|
+
reasoning_tokens: z.number().nullish(),
|
|
44
|
+
orchestration_output_tokens: z.number().nullish(),
|
|
45
|
+
}),
|
|
46
|
+
)
|
|
47
|
+
.nullish(),
|
|
48
|
+
total_tokens: z.number().optional(),
|
|
49
|
+
}),
|
|
50
|
+
);
|
|
51
|
+
|
|
21
52
|
const openaiResponsesComputerSafetyCheckSchema = z.object({
|
|
22
53
|
id: z.string(),
|
|
23
54
|
code: z.string().nullish(),
|
|
@@ -831,26 +862,7 @@ export const openaiResponsesChunkSchema = lazySchema(() =>
|
|
|
831
862
|
type: z.enum(['response.completed', 'response.incomplete']),
|
|
832
863
|
response: z.object({
|
|
833
864
|
incomplete_details: z.object({ reason: z.string() }).nullish(),
|
|
834
|
-
usage:
|
|
835
|
-
.object({
|
|
836
|
-
input_tokens: z.number(),
|
|
837
|
-
input_tokens_details: z
|
|
838
|
-
.object({
|
|
839
|
-
cached_tokens: z.number().nullish(),
|
|
840
|
-
cache_write_tokens: z.number().nullish(),
|
|
841
|
-
orchestration_input_tokens: z.number().nullish(),
|
|
842
|
-
orchestration_input_cached_tokens: z.number().nullish(),
|
|
843
|
-
})
|
|
844
|
-
.nullish(),
|
|
845
|
-
output_tokens: z.number(),
|
|
846
|
-
output_tokens_details: z
|
|
847
|
-
.object({
|
|
848
|
-
reasoning_tokens: z.number().nullish(),
|
|
849
|
-
orchestration_output_tokens: z.number().nullish(),
|
|
850
|
-
})
|
|
851
|
-
.nullish(),
|
|
852
|
-
})
|
|
853
|
-
.nullish(),
|
|
865
|
+
usage: openaiResponsesUsageSchema.nullish(),
|
|
854
866
|
reasoning: z
|
|
855
867
|
.object({
|
|
856
868
|
context: z.string().nullish(),
|
|
@@ -870,26 +882,7 @@ export const openaiResponsesChunkSchema = lazySchema(() =>
|
|
|
870
882
|
})
|
|
871
883
|
.nullish(),
|
|
872
884
|
incomplete_details: z.object({ reason: z.string() }).nullish(),
|
|
873
|
-
usage:
|
|
874
|
-
.object({
|
|
875
|
-
input_tokens: z.number(),
|
|
876
|
-
input_tokens_details: z
|
|
877
|
-
.object({
|
|
878
|
-
cached_tokens: z.number().nullish(),
|
|
879
|
-
cache_write_tokens: z.number().nullish(),
|
|
880
|
-
orchestration_input_tokens: z.number().nullish(),
|
|
881
|
-
orchestration_input_cached_tokens: z.number().nullish(),
|
|
882
|
-
})
|
|
883
|
-
.nullish(),
|
|
884
|
-
output_tokens: z.number(),
|
|
885
|
-
output_tokens_details: z
|
|
886
|
-
.object({
|
|
887
|
-
reasoning_tokens: z.number().nullish(),
|
|
888
|
-
orchestration_output_tokens: z.number().nullish(),
|
|
889
|
-
})
|
|
890
|
-
.nullish(),
|
|
891
|
-
})
|
|
892
|
-
.nullish(),
|
|
885
|
+
usage: openaiResponsesUsageSchema.nullish(),
|
|
893
886
|
reasoning: z
|
|
894
887
|
.object({
|
|
895
888
|
context: z.string().nullish(),
|
|
@@ -1745,26 +1738,7 @@ export const openaiResponsesResponseSchema = lazySchema(() =>
|
|
|
1745
1738
|
})
|
|
1746
1739
|
.nullish(),
|
|
1747
1740
|
incomplete_details: z.object({ reason: z.string() }).nullish(),
|
|
1748
|
-
usage:
|
|
1749
|
-
.object({
|
|
1750
|
-
input_tokens: z.number(),
|
|
1751
|
-
input_tokens_details: z
|
|
1752
|
-
.object({
|
|
1753
|
-
cached_tokens: z.number().nullish(),
|
|
1754
|
-
cache_write_tokens: z.number().nullish(),
|
|
1755
|
-
orchestration_input_tokens: z.number().nullish(),
|
|
1756
|
-
orchestration_input_cached_tokens: z.number().nullish(),
|
|
1757
|
-
})
|
|
1758
|
-
.nullish(),
|
|
1759
|
-
output_tokens: z.number(),
|
|
1760
|
-
output_tokens_details: z
|
|
1761
|
-
.object({
|
|
1762
|
-
reasoning_tokens: z.number().nullish(),
|
|
1763
|
-
orchestration_output_tokens: z.number().nullish(),
|
|
1764
|
-
})
|
|
1765
|
-
.nullish(),
|
|
1766
|
-
})
|
|
1767
|
-
.nullish(),
|
|
1741
|
+
usage: openaiResponsesUsageSchema.nullish(),
|
|
1768
1742
|
}),
|
|
1769
1743
|
),
|
|
1770
1744
|
);
|