@ai-sdk/openai 3.0.101 → 3.0.104
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 +21 -0
- package/dist/index.d.mts +29 -12
- package/dist/index.d.ts +29 -12
- package/dist/index.js +190 -119
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +191 -119
- package/dist/index.mjs.map +1 -1
- package/dist/internal/index.d.mts +31 -13
- package/dist/internal/index.d.ts +31 -13
- package/dist/internal/index.js +186 -115
- package/dist/internal/index.js.map +1 -1
- package/dist/internal/index.mjs +187 -115
- package/dist/internal/index.mjs.map +1 -1
- package/package.json +2 -2
- package/src/chat/convert-to-openai-chat-messages.ts +5 -1
- package/src/embedding/openai-embedding-model.ts +2 -0
- package/src/responses/convert-to-openai-responses-input.ts +5 -3
- package/src/responses/openai-responses-api.ts +113 -40
- package/src/responses/openai-responses-language-model.ts +17 -10
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-sdk/openai",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.104",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
39
|
"@ai-sdk/provider": "3.0.15",
|
|
40
|
-
"@ai-sdk/provider-utils": "4.0.
|
|
40
|
+
"@ai-sdk/provider-utils": "4.0.49"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
43
|
"@types/node": "20.17.24",
|
|
@@ -8,7 +8,11 @@ import type { OpenAIChatPrompt } from './openai-chat-prompt';
|
|
|
8
8
|
import { convertToBase64 } from '@ai-sdk/provider-utils';
|
|
9
9
|
|
|
10
10
|
function serializeToolCallArguments(input: unknown): string {
|
|
11
|
-
return JSON.stringify(
|
|
11
|
+
return JSON.stringify(
|
|
12
|
+
typeof input === 'object' && input !== null && !Array.isArray(input)
|
|
13
|
+
? input
|
|
14
|
+
: {},
|
|
15
|
+
);
|
|
12
16
|
}
|
|
13
17
|
|
|
14
18
|
type OpenAIPromptCacheBreakpoint = { mode: 'explicit' };
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
import {
|
|
6
6
|
combineHeaders,
|
|
7
7
|
createJsonResponseHandler,
|
|
8
|
+
EXPERIMENTAL_EMBEDDING_MODEL_MAX_INPUT_BYTES_PER_CALL,
|
|
8
9
|
parseProviderOptions,
|
|
9
10
|
postJsonToApi,
|
|
10
11
|
} from '@ai-sdk/provider-utils';
|
|
@@ -20,6 +21,7 @@ export class OpenAIEmbeddingModel implements EmbeddingModelV3 {
|
|
|
20
21
|
readonly specificationVersion = 'v3';
|
|
21
22
|
readonly modelId: OpenAIEmbeddingModelId;
|
|
22
23
|
readonly maxEmbeddingsPerCall = 2048;
|
|
24
|
+
readonly [EXPERIMENTAL_EMBEDDING_MODEL_MAX_INPUT_BYTES_PER_CALL] = 300_000;
|
|
23
25
|
readonly supportsParallelCalls = true;
|
|
24
26
|
|
|
25
27
|
private readonly config: OpenAIConfig;
|
|
@@ -268,6 +268,7 @@ export async function convertToOpenAIResponsesInput({
|
|
|
268
268
|
hasLocalShellTool = false,
|
|
269
269
|
hasShellTool = false,
|
|
270
270
|
hasApplyPatchTool = false,
|
|
271
|
+
toolSearchToolName,
|
|
271
272
|
customProviderToolNames,
|
|
272
273
|
}: {
|
|
273
274
|
prompt: LanguageModelV3Prompt;
|
|
@@ -282,6 +283,7 @@ export async function convertToOpenAIResponsesInput({
|
|
|
282
283
|
hasLocalShellTool?: boolean;
|
|
283
284
|
hasShellTool?: boolean;
|
|
284
285
|
hasApplyPatchTool?: boolean;
|
|
286
|
+
toolSearchToolName?: string;
|
|
285
287
|
customProviderToolNames?: Set<string>;
|
|
286
288
|
}): Promise<{
|
|
287
289
|
input: OpenAIResponsesInput;
|
|
@@ -559,7 +561,7 @@ export async function convertToOpenAIResponsesInput({
|
|
|
559
561
|
part.toolName,
|
|
560
562
|
);
|
|
561
563
|
|
|
562
|
-
if (
|
|
564
|
+
if (part.toolName === toolSearchToolName) {
|
|
563
565
|
if (store && id != null) {
|
|
564
566
|
input.push({ type: 'item_reference', id });
|
|
565
567
|
break;
|
|
@@ -740,7 +742,7 @@ export async function convertToOpenAIResponsesInput({
|
|
|
740
742
|
part.toolName,
|
|
741
743
|
);
|
|
742
744
|
|
|
743
|
-
if (
|
|
745
|
+
if (part.toolName === toolSearchToolName) {
|
|
744
746
|
const itemId = (part.providerOptions?.[providerOptionsName]
|
|
745
747
|
?.itemId ??
|
|
746
748
|
(
|
|
@@ -1030,7 +1032,7 @@ export async function convertToOpenAIResponsesInput({
|
|
|
1030
1032
|
part.toolName,
|
|
1031
1033
|
);
|
|
1032
1034
|
|
|
1033
|
-
if (
|
|
1035
|
+
if (part.toolName === toolSearchToolName && output.type === 'json') {
|
|
1034
1036
|
const parsedOutput = await validateTypes({
|
|
1035
1037
|
value: output.value,
|
|
1036
1038
|
schema: toolSearchOutputSchema,
|
|
@@ -17,6 +17,24 @@ const jsonValueSchema: z.ZodType<JSONValue> = z.lazy(() =>
|
|
|
17
17
|
]),
|
|
18
18
|
);
|
|
19
19
|
|
|
20
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
21
|
+
return value != null && typeof value === 'object' && !Array.isArray(value);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const openaiResponsesLocalShellCallSchema = z.object({
|
|
25
|
+
type: z.literal('local_shell_call'),
|
|
26
|
+
id: z.string(),
|
|
27
|
+
call_id: z.string(),
|
|
28
|
+
action: z.object({
|
|
29
|
+
type: z.literal('exec'),
|
|
30
|
+
command: z.array(z.string()),
|
|
31
|
+
timeout_ms: z.number().optional(),
|
|
32
|
+
user: z.string().optional(),
|
|
33
|
+
working_directory: z.string().optional(),
|
|
34
|
+
env: z.record(z.string(), z.string()).optional(),
|
|
35
|
+
}),
|
|
36
|
+
});
|
|
37
|
+
|
|
20
38
|
export type OpenAIResponsesInput = Array<OpenAIResponsesInputItem>;
|
|
21
39
|
|
|
22
40
|
export type OpenAIResponsesInputItem =
|
|
@@ -190,19 +208,9 @@ export type OpenAIResponsesComputerCall = {
|
|
|
190
208
|
status?: string;
|
|
191
209
|
};
|
|
192
210
|
|
|
193
|
-
export type OpenAIResponsesLocalShellCall =
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
call_id: string;
|
|
197
|
-
action: {
|
|
198
|
-
type: 'exec';
|
|
199
|
-
command: string[];
|
|
200
|
-
timeout_ms?: number;
|
|
201
|
-
user?: string;
|
|
202
|
-
working_directory?: string;
|
|
203
|
-
env?: Record<string, string>;
|
|
204
|
-
};
|
|
205
|
-
};
|
|
211
|
+
export type OpenAIResponsesLocalShellCall = InferSchema<
|
|
212
|
+
typeof openaiResponsesLocalShellCallSchema
|
|
213
|
+
>;
|
|
206
214
|
|
|
207
215
|
export type OpenAIResponsesLocalShellCallOutput = {
|
|
208
216
|
type: 'local_shell_call_output';
|
|
@@ -555,7 +563,8 @@ const openaiResponsesNestedErrorChunkSchema = z.object({
|
|
|
555
563
|
});
|
|
556
564
|
|
|
557
565
|
// Current OpenAI OpenAPI docs define ResponseErrorEvent with top-level
|
|
558
|
-
// code/message/param fields
|
|
566
|
+
// code/message/param fields:
|
|
567
|
+
// https://developers.openai.com/api/reference/resources/responses/streaming-events
|
|
559
568
|
const openaiResponsesErrorChunkSchema = z.object({
|
|
560
569
|
type: z.literal('error'),
|
|
561
570
|
sequence_number: z.number(),
|
|
@@ -564,6 +573,82 @@ const openaiResponsesErrorChunkSchema = z.object({
|
|
|
564
573
|
param: z.string().nullish(),
|
|
565
574
|
});
|
|
566
575
|
|
|
576
|
+
/**
|
|
577
|
+
* Chunk types explicitly modeled by openaiResponsesChunkSchema. Keep this set
|
|
578
|
+
* in sync with the union below. OpenAI's complete event catalog:
|
|
579
|
+
* https://developers.openai.com/api/reference/resources/responses/streaming-events
|
|
580
|
+
*/
|
|
581
|
+
const openaiResponsesModeledChunkTypes = new Set([
|
|
582
|
+
'error',
|
|
583
|
+
'response.apply_patch_call_operation_diff.delta',
|
|
584
|
+
'response.apply_patch_call_operation_diff.done',
|
|
585
|
+
'response.code_interpreter_call_code.delta',
|
|
586
|
+
'response.code_interpreter_call_code.done',
|
|
587
|
+
'response.completed',
|
|
588
|
+
'response.created',
|
|
589
|
+
'response.custom_tool_call_input.delta',
|
|
590
|
+
'response.failed',
|
|
591
|
+
'response.function_call_arguments.delta',
|
|
592
|
+
'response.function_call_arguments.done',
|
|
593
|
+
'response.image_generation_call.partial_image',
|
|
594
|
+
'response.incomplete',
|
|
595
|
+
'response.output_item.added',
|
|
596
|
+
'response.output_item.done',
|
|
597
|
+
'response.output_text.annotation.added',
|
|
598
|
+
'response.output_text.delta',
|
|
599
|
+
'response.reasoning_summary_part.added',
|
|
600
|
+
'response.reasoning_summary_part.done',
|
|
601
|
+
'response.reasoning_summary_text.delta',
|
|
602
|
+
]);
|
|
603
|
+
|
|
604
|
+
/**
|
|
605
|
+
* Output item types explicitly modeled by both output item event schemas below.
|
|
606
|
+
* OpenAI's complete ResponseOutputItem schema:
|
|
607
|
+
* https://developers.openai.com/api/reference/resources/responses#(resource)%20responses%20%3E%20(model)%20response_output_item%20%3E%20(schema)
|
|
608
|
+
*/
|
|
609
|
+
const openaiResponsesModeledOutputItemTypes = new Set([
|
|
610
|
+
'apply_patch_call',
|
|
611
|
+
'code_interpreter_call',
|
|
612
|
+
'computer_call',
|
|
613
|
+
'custom_tool_call',
|
|
614
|
+
'file_search_call',
|
|
615
|
+
'function_call',
|
|
616
|
+
'image_generation_call',
|
|
617
|
+
'local_shell_call',
|
|
618
|
+
'mcp_approval_request',
|
|
619
|
+
'mcp_call',
|
|
620
|
+
'mcp_list_tools',
|
|
621
|
+
'message',
|
|
622
|
+
'reasoning',
|
|
623
|
+
'shell_call',
|
|
624
|
+
'shell_call_output',
|
|
625
|
+
'tool_search_call',
|
|
626
|
+
'tool_search_output',
|
|
627
|
+
'web_search_call',
|
|
628
|
+
]);
|
|
629
|
+
|
|
630
|
+
function isModeledOpenAIResponsesChunk(value: Record<string, unknown>) {
|
|
631
|
+
if (
|
|
632
|
+
typeof value.type !== 'string' ||
|
|
633
|
+
!openaiResponsesModeledChunkTypes.has(value.type)
|
|
634
|
+
) {
|
|
635
|
+
return false;
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
if (
|
|
639
|
+
value.type !== 'response.output_item.added' &&
|
|
640
|
+
value.type !== 'response.output_item.done'
|
|
641
|
+
) {
|
|
642
|
+
return true;
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
if (!isRecord(value.item) || typeof value.item.type !== 'string') {
|
|
646
|
+
return true;
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
return openaiResponsesModeledOutputItemTypes.has(value.item.type);
|
|
650
|
+
}
|
|
651
|
+
|
|
567
652
|
export const openaiResponsesChunkSchema = lazySchema(() =>
|
|
568
653
|
zodSchema(
|
|
569
654
|
z.union([
|
|
@@ -700,6 +785,7 @@ export const openaiResponsesChunkSchema = lazySchema(() =>
|
|
|
700
785
|
type: z.literal('file_search_call'),
|
|
701
786
|
id: z.string(),
|
|
702
787
|
}),
|
|
788
|
+
openaiResponsesLocalShellCallSchema,
|
|
703
789
|
z.object({
|
|
704
790
|
type: z.literal('image_generation_call'),
|
|
705
791
|
id: z.string(),
|
|
@@ -908,19 +994,7 @@ export const openaiResponsesChunkSchema = lazySchema(() =>
|
|
|
908
994
|
)
|
|
909
995
|
.nullish(),
|
|
910
996
|
}),
|
|
911
|
-
|
|
912
|
-
type: z.literal('local_shell_call'),
|
|
913
|
-
id: z.string(),
|
|
914
|
-
call_id: z.string(),
|
|
915
|
-
action: z.object({
|
|
916
|
-
type: z.literal('exec'),
|
|
917
|
-
command: z.array(z.string()),
|
|
918
|
-
timeout_ms: z.number().optional(),
|
|
919
|
-
user: z.string().optional(),
|
|
920
|
-
working_directory: z.string().optional(),
|
|
921
|
-
env: z.record(z.string(), z.string()).optional(),
|
|
922
|
-
}),
|
|
923
|
-
}),
|
|
997
|
+
openaiResponsesLocalShellCallSchema,
|
|
924
998
|
z.object({
|
|
925
999
|
type: z.literal('computer_call'),
|
|
926
1000
|
id: z.string(),
|
|
@@ -1055,6 +1129,14 @@ export const openaiResponsesChunkSchema = lazySchema(() =>
|
|
|
1055
1129
|
output_index: z.number(),
|
|
1056
1130
|
delta: z.string(),
|
|
1057
1131
|
}),
|
|
1132
|
+
z.object({
|
|
1133
|
+
// `name` is documented as required but omitted from live API events:
|
|
1134
|
+
// https://github.com/openai/openai-openapi/issues/545
|
|
1135
|
+
type: z.literal('response.function_call_arguments.done'),
|
|
1136
|
+
item_id: z.string(),
|
|
1137
|
+
output_index: z.number(),
|
|
1138
|
+
arguments: z.string(),
|
|
1139
|
+
}),
|
|
1058
1140
|
z.object({
|
|
1059
1141
|
type: z.literal('response.custom_tool_call_input.delta'),
|
|
1060
1142
|
item_id: z.string(),
|
|
@@ -1144,6 +1226,9 @@ export const openaiResponsesChunkSchema = lazySchema(() =>
|
|
|
1144
1226
|
z
|
|
1145
1227
|
.object({ type: z.string() })
|
|
1146
1228
|
.loose()
|
|
1229
|
+
.refine(value => !isModeledOpenAIResponsesChunk(value), {
|
|
1230
|
+
message: 'Known response chunk failed schema validation',
|
|
1231
|
+
})
|
|
1147
1232
|
.transform(value => ({
|
|
1148
1233
|
type: 'unknown_chunk' as const,
|
|
1149
1234
|
message: value.type,
|
|
@@ -1315,19 +1400,7 @@ export const openaiResponsesResponseSchema = lazySchema(() =>
|
|
|
1315
1400
|
id: z.string(),
|
|
1316
1401
|
result: z.string(),
|
|
1317
1402
|
}),
|
|
1318
|
-
|
|
1319
|
-
type: z.literal('local_shell_call'),
|
|
1320
|
-
id: z.string(),
|
|
1321
|
-
call_id: z.string(),
|
|
1322
|
-
action: z.object({
|
|
1323
|
-
type: z.literal('exec'),
|
|
1324
|
-
command: z.array(z.string()),
|
|
1325
|
-
timeout_ms: z.number().optional(),
|
|
1326
|
-
user: z.string().optional(),
|
|
1327
|
-
working_directory: z.string().optional(),
|
|
1328
|
-
env: z.record(z.string(), z.string()).optional(),
|
|
1329
|
-
}),
|
|
1330
|
-
}),
|
|
1403
|
+
openaiResponsesLocalShellCallSchema,
|
|
1331
1404
|
z.object({
|
|
1332
1405
|
type: z.literal('function_call'),
|
|
1333
1406
|
call_id: z.string(),
|
|
@@ -243,6 +243,7 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV3 {
|
|
|
243
243
|
hasLocalShellTool: hasOpenAITool('openai.local_shell'),
|
|
244
244
|
hasShellTool: hasOpenAITool('openai.shell'),
|
|
245
245
|
hasApplyPatchTool: hasOpenAITool('openai.apply_patch'),
|
|
246
|
+
toolSearchToolName: getOpenAIToolName('openai.tool_search'),
|
|
246
247
|
customProviderToolNames:
|
|
247
248
|
customProviderToolNames.size > 0
|
|
248
249
|
? customProviderToolNames
|
|
@@ -263,10 +264,13 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV3 {
|
|
|
263
264
|
}
|
|
264
265
|
}
|
|
265
266
|
|
|
267
|
+
function getOpenAIToolName(id: string) {
|
|
268
|
+
return tools?.find(tool => tool.type === 'provider' && tool.id === id)
|
|
269
|
+
?.name;
|
|
270
|
+
}
|
|
271
|
+
|
|
266
272
|
function hasOpenAITool(id: string) {
|
|
267
|
-
return (
|
|
268
|
-
tools?.find(tool => tool.type === 'provider' && tool.id === id) != null
|
|
269
|
-
);
|
|
273
|
+
return getOpenAIToolName(id) != null;
|
|
270
274
|
}
|
|
271
275
|
|
|
272
276
|
// when logprobs are requested, automatically include them:
|
|
@@ -1222,6 +1226,7 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV3 {
|
|
|
1222
1226
|
})
|
|
1223
1227
|
: chunk.error;
|
|
1224
1228
|
|
|
1229
|
+
encounteredStreamError = true;
|
|
1225
1230
|
finishReason = { unified: 'error', raw: undefined };
|
|
1226
1231
|
controller.enqueue({ type: 'error', error });
|
|
1227
1232
|
return;
|
|
@@ -2189,13 +2194,15 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV3 {
|
|
|
2189
2194
|
] = 'can-conclude';
|
|
2190
2195
|
}
|
|
2191
2196
|
} else if (isResponseFinishedChunk(value)) {
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2197
|
+
if (!encounteredStreamError) {
|
|
2198
|
+
finishReason = {
|
|
2199
|
+
unified: mapOpenAIResponseFinishReason({
|
|
2200
|
+
finishReason: value.response.incomplete_details?.reason,
|
|
2201
|
+
hasFunctionCall,
|
|
2202
|
+
}),
|
|
2203
|
+
raw: value.response.incomplete_details?.reason ?? undefined,
|
|
2204
|
+
};
|
|
2205
|
+
}
|
|
2199
2206
|
usage = value.response.usage;
|
|
2200
2207
|
if (typeof value.response.service_tier === 'string') {
|
|
2201
2208
|
serviceTier = value.response.service_tier;
|