@ai-sdk/openai 4.0.47 → 4.0.49
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.ts +29 -12
- package/dist/index.js +374 -274
- package/dist/index.js.map +1 -1
- package/dist/internal/index.d.ts +45 -26
- package/dist/internal/index.js +270 -166
- package/dist/internal/index.js.map +1 -1
- package/docs/03-openai.mdx +31 -11
- package/package.json +2 -2
- package/src/chat/convert-to-openai-chat-messages.ts +5 -1
- package/src/chat/openai-chat-language-model.ts +9 -2
- package/src/completion/openai-completion-language-model.ts +9 -2
- package/src/embedding/openai-embedding-model.ts +2 -0
- package/src/openai-responses-batch.ts +90 -102
- package/src/openai-stream-error.ts +68 -15
- package/src/responses/openai-responses-api.ts +114 -40
- package/src/responses/openai-responses-language-model.ts +28 -18
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { JSONObject, JSONSchema7, JSONValue } from '@ai-sdk/provider';
|
|
2
2
|
import {
|
|
3
|
+
isRecord,
|
|
3
4
|
lazySchema,
|
|
4
5
|
zodSchema,
|
|
5
6
|
type InferSchema,
|
|
@@ -108,6 +109,20 @@ const openaiResponsesProgramOutputSchema = z.object({
|
|
|
108
109
|
status: z.enum(['completed', 'incomplete']),
|
|
109
110
|
});
|
|
110
111
|
|
|
112
|
+
const openaiResponsesLocalShellCallSchema = z.object({
|
|
113
|
+
type: z.literal('local_shell_call'),
|
|
114
|
+
id: z.string(),
|
|
115
|
+
call_id: z.string(),
|
|
116
|
+
action: z.object({
|
|
117
|
+
type: z.literal('exec'),
|
|
118
|
+
command: z.array(z.string()),
|
|
119
|
+
timeout_ms: z.number().optional(),
|
|
120
|
+
user: z.string().optional(),
|
|
121
|
+
working_directory: z.string().optional(),
|
|
122
|
+
env: z.record(z.string(), z.string()).optional(),
|
|
123
|
+
}),
|
|
124
|
+
});
|
|
125
|
+
|
|
111
126
|
export type OpenAIResponsesInput = Array<OpenAIResponsesInputItem>;
|
|
112
127
|
|
|
113
128
|
export type OpenAIResponsesInputItem =
|
|
@@ -326,19 +341,9 @@ export type OpenAIResponsesComputerCallOutput = {
|
|
|
326
341
|
}>;
|
|
327
342
|
};
|
|
328
343
|
|
|
329
|
-
export type OpenAIResponsesLocalShellCall =
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
call_id: string;
|
|
333
|
-
action: {
|
|
334
|
-
type: 'exec';
|
|
335
|
-
command: string[];
|
|
336
|
-
timeout_ms?: number;
|
|
337
|
-
user?: string;
|
|
338
|
-
working_directory?: string;
|
|
339
|
-
env?: Record<string, string>;
|
|
340
|
-
};
|
|
341
|
-
};
|
|
344
|
+
export type OpenAIResponsesLocalShellCall = InferSchema<
|
|
345
|
+
typeof openaiResponsesLocalShellCallSchema
|
|
346
|
+
>;
|
|
342
347
|
|
|
343
348
|
export type OpenAIResponsesLocalShellCallOutput = {
|
|
344
349
|
type: 'local_shell_call_output';
|
|
@@ -709,7 +714,8 @@ const openaiResponsesNestedErrorChunkSchema = z.object({
|
|
|
709
714
|
});
|
|
710
715
|
|
|
711
716
|
// Current OpenAI OpenAPI docs define ResponseErrorEvent with top-level
|
|
712
|
-
// code/message/param fields
|
|
717
|
+
// code/message/param fields:
|
|
718
|
+
// https://developers.openai.com/api/reference/resources/responses/streaming-events
|
|
713
719
|
const openaiResponsesErrorChunkSchema = z.object({
|
|
714
720
|
type: z.literal('error'),
|
|
715
721
|
sequence_number: z.number(),
|
|
@@ -718,6 +724,86 @@ const openaiResponsesErrorChunkSchema = z.object({
|
|
|
718
724
|
param: z.string().nullish(),
|
|
719
725
|
});
|
|
720
726
|
|
|
727
|
+
/**
|
|
728
|
+
* Chunk types explicitly modeled by openaiResponsesChunkSchema. Keep this set
|
|
729
|
+
* in sync with the union below. OpenAI's complete event catalog:
|
|
730
|
+
* https://developers.openai.com/api/reference/resources/responses/streaming-events
|
|
731
|
+
*/
|
|
732
|
+
const openaiResponsesModeledChunkTypes = new Set([
|
|
733
|
+
'error',
|
|
734
|
+
'response.apply_patch_call_operation_diff.delta',
|
|
735
|
+
'response.apply_patch_call_operation_diff.done',
|
|
736
|
+
'response.code_interpreter_call_code.delta',
|
|
737
|
+
'response.code_interpreter_call_code.done',
|
|
738
|
+
'response.completed',
|
|
739
|
+
'response.created',
|
|
740
|
+
'response.custom_tool_call_input.delta',
|
|
741
|
+
'response.failed',
|
|
742
|
+
'response.function_call_arguments.delta',
|
|
743
|
+
'response.function_call_arguments.done',
|
|
744
|
+
'response.image_generation_call.partial_image',
|
|
745
|
+
'response.in_progress',
|
|
746
|
+
'response.incomplete',
|
|
747
|
+
'response.output_item.added',
|
|
748
|
+
'response.output_item.done',
|
|
749
|
+
'response.output_text.annotation.added',
|
|
750
|
+
'response.output_text.delta',
|
|
751
|
+
'response.reasoning_summary_part.added',
|
|
752
|
+
'response.reasoning_summary_part.done',
|
|
753
|
+
'response.reasoning_summary_text.delta',
|
|
754
|
+
]);
|
|
755
|
+
|
|
756
|
+
/**
|
|
757
|
+
* Output item types explicitly modeled by both output item event schemas below.
|
|
758
|
+
* OpenAI's complete ResponseOutputItem schema:
|
|
759
|
+
* https://developers.openai.com/api/reference/resources/responses#(resource)%20responses%20%3E%20(model)%20response_output_item%20%3E%20(schema)
|
|
760
|
+
*/
|
|
761
|
+
const openaiResponsesModeledOutputItemTypes = new Set([
|
|
762
|
+
'apply_patch_call',
|
|
763
|
+
'code_interpreter_call',
|
|
764
|
+
'compaction',
|
|
765
|
+
'computer_call',
|
|
766
|
+
'custom_tool_call',
|
|
767
|
+
'file_search_call',
|
|
768
|
+
'function_call',
|
|
769
|
+
'image_generation_call',
|
|
770
|
+
'local_shell_call',
|
|
771
|
+
'mcp_approval_request',
|
|
772
|
+
'mcp_call',
|
|
773
|
+
'mcp_list_tools',
|
|
774
|
+
'message',
|
|
775
|
+
'program',
|
|
776
|
+
'program_output',
|
|
777
|
+
'reasoning',
|
|
778
|
+
'shell_call',
|
|
779
|
+
'shell_call_output',
|
|
780
|
+
'tool_search_call',
|
|
781
|
+
'tool_search_output',
|
|
782
|
+
'web_search_call',
|
|
783
|
+
]);
|
|
784
|
+
|
|
785
|
+
function isModeledOpenAIResponsesChunk(value: Record<string, unknown>) {
|
|
786
|
+
if (
|
|
787
|
+
typeof value.type !== 'string' ||
|
|
788
|
+
!openaiResponsesModeledChunkTypes.has(value.type)
|
|
789
|
+
) {
|
|
790
|
+
return false;
|
|
791
|
+
}
|
|
792
|
+
|
|
793
|
+
if (
|
|
794
|
+
value.type !== 'response.output_item.added' &&
|
|
795
|
+
value.type !== 'response.output_item.done'
|
|
796
|
+
) {
|
|
797
|
+
return true;
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
if (!isRecord(value.item) || typeof value.item.type !== 'string') {
|
|
801
|
+
return true;
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
return openaiResponsesModeledOutputItemTypes.has(value.item.type);
|
|
805
|
+
}
|
|
806
|
+
|
|
721
807
|
export const openaiResponsesChunkSchema = lazySchema(() =>
|
|
722
808
|
zodSchema(
|
|
723
809
|
z.union([
|
|
@@ -863,6 +949,7 @@ export const openaiResponsesChunkSchema = lazySchema(() =>
|
|
|
863
949
|
type: z.literal('file_search_call'),
|
|
864
950
|
id: z.string(),
|
|
865
951
|
}),
|
|
952
|
+
openaiResponsesLocalShellCallSchema,
|
|
866
953
|
z.object({
|
|
867
954
|
type: z.literal('image_generation_call'),
|
|
868
955
|
id: z.string(),
|
|
@@ -1079,19 +1166,7 @@ export const openaiResponsesChunkSchema = lazySchema(() =>
|
|
|
1079
1166
|
)
|
|
1080
1167
|
.nullish(),
|
|
1081
1168
|
}),
|
|
1082
|
-
|
|
1083
|
-
type: z.literal('local_shell_call'),
|
|
1084
|
-
id: z.string(),
|
|
1085
|
-
call_id: z.string(),
|
|
1086
|
-
action: z.object({
|
|
1087
|
-
type: z.literal('exec'),
|
|
1088
|
-
command: z.array(z.string()),
|
|
1089
|
-
timeout_ms: z.number().optional(),
|
|
1090
|
-
user: z.string().optional(),
|
|
1091
|
-
working_directory: z.string().optional(),
|
|
1092
|
-
env: z.record(z.string(), z.string()).optional(),
|
|
1093
|
-
}),
|
|
1094
|
-
}),
|
|
1169
|
+
openaiResponsesLocalShellCallSchema,
|
|
1095
1170
|
openaiResponsesComputerCallSchema,
|
|
1096
1171
|
z.object({
|
|
1097
1172
|
type: z.literal('mcp_call'),
|
|
@@ -1227,6 +1302,14 @@ export const openaiResponsesChunkSchema = lazySchema(() =>
|
|
|
1227
1302
|
output_index: z.number(),
|
|
1228
1303
|
delta: z.string(),
|
|
1229
1304
|
}),
|
|
1305
|
+
z.object({
|
|
1306
|
+
// `name` is documented as required but omitted from live API events:
|
|
1307
|
+
// https://github.com/openai/openai-openapi/issues/545
|
|
1308
|
+
type: z.literal('response.function_call_arguments.done'),
|
|
1309
|
+
item_id: z.string(),
|
|
1310
|
+
output_index: z.number(),
|
|
1311
|
+
arguments: z.string(),
|
|
1312
|
+
}),
|
|
1230
1313
|
z.object({
|
|
1231
1314
|
type: z.literal('response.custom_tool_call_input.delta'),
|
|
1232
1315
|
item_id: z.string(),
|
|
@@ -1319,6 +1402,9 @@ export const openaiResponsesChunkSchema = lazySchema(() =>
|
|
|
1319
1402
|
z
|
|
1320
1403
|
.object({ type: z.string() })
|
|
1321
1404
|
.loose()
|
|
1405
|
+
.refine(value => !isModeledOpenAIResponsesChunk(value), {
|
|
1406
|
+
message: 'Known response chunk failed schema validation',
|
|
1407
|
+
})
|
|
1322
1408
|
.transform(value => ({
|
|
1323
1409
|
type: 'unknown_chunk' as const,
|
|
1324
1410
|
message: value.type,
|
|
@@ -1490,19 +1576,7 @@ export const openaiResponsesResponseSchema = lazySchema(() =>
|
|
|
1490
1576
|
id: z.string(),
|
|
1491
1577
|
result: z.string(),
|
|
1492
1578
|
}),
|
|
1493
|
-
|
|
1494
|
-
type: z.literal('local_shell_call'),
|
|
1495
|
-
id: z.string(),
|
|
1496
|
-
call_id: z.string(),
|
|
1497
|
-
action: z.object({
|
|
1498
|
-
type: z.literal('exec'),
|
|
1499
|
-
command: z.array(z.string()),
|
|
1500
|
-
timeout_ms: z.number().optional(),
|
|
1501
|
-
user: z.string().optional(),
|
|
1502
|
-
working_directory: z.string().optional(),
|
|
1503
|
-
env: z.record(z.string(), z.string()).optional(),
|
|
1504
|
-
}),
|
|
1505
|
-
}),
|
|
1579
|
+
openaiResponsesLocalShellCallSchema,
|
|
1506
1580
|
z.object({
|
|
1507
1581
|
type: z.literal('function_call'),
|
|
1508
1582
|
call_id: z.string(),
|
|
@@ -33,7 +33,10 @@ import {
|
|
|
33
33
|
import type { OpenAIConfig } from '../openai-config';
|
|
34
34
|
import { openaiFailedResponseHandler } from '../openai-error';
|
|
35
35
|
import { getOpenAILanguageModelCapabilities } from '../openai-language-model-capabilities';
|
|
36
|
-
import {
|
|
36
|
+
import {
|
|
37
|
+
createOpenAIProviderStreamError,
|
|
38
|
+
throwIfOpenAIStreamErrorBeforeOutput,
|
|
39
|
+
} from '../openai-stream-error';
|
|
37
40
|
import type { applyPatchInputSchema } from '../tool/apply-patch';
|
|
38
41
|
import type {
|
|
39
42
|
codeInterpreterInputSchema,
|
|
@@ -1473,6 +1476,7 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
|
|
|
1473
1476
|
})
|
|
1474
1477
|
: chunk.error;
|
|
1475
1478
|
|
|
1479
|
+
encounteredStreamError = true;
|
|
1476
1480
|
finishReason = { unified: 'error', raw: undefined };
|
|
1477
1481
|
controller.enqueue({ type: 'error', error });
|
|
1478
1482
|
return;
|
|
@@ -2561,13 +2565,15 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
|
|
|
2561
2565
|
}
|
|
2562
2566
|
}
|
|
2563
2567
|
} else if (isResponseFinishedChunk(value)) {
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2568
|
+
if (!encounteredStreamError) {
|
|
2569
|
+
finishReason = {
|
|
2570
|
+
unified: mapOpenAIResponseFinishReason({
|
|
2571
|
+
finishReason: value.response.incomplete_details?.reason,
|
|
2572
|
+
hasFunctionCall,
|
|
2573
|
+
}),
|
|
2574
|
+
raw: value.response.incomplete_details?.reason ?? undefined,
|
|
2575
|
+
};
|
|
2576
|
+
}
|
|
2571
2577
|
usage = value.response.usage;
|
|
2572
2578
|
if (typeof value.response.service_tier === 'string') {
|
|
2573
2579
|
serviceTier = value.response.service_tier;
|
|
@@ -2594,17 +2600,18 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
|
|
|
2594
2600
|
|
|
2595
2601
|
if (!encounteredStreamError && value.response.error != null) {
|
|
2596
2602
|
encounteredStreamError = true;
|
|
2603
|
+
const error = {
|
|
2604
|
+
type: 'response.failed',
|
|
2605
|
+
sequence_number: value.sequence_number,
|
|
2606
|
+
response: {
|
|
2607
|
+
error: value.response.error,
|
|
2608
|
+
incomplete_details: value.response.incomplete_details,
|
|
2609
|
+
service_tier: value.response.service_tier,
|
|
2610
|
+
},
|
|
2611
|
+
};
|
|
2597
2612
|
controller.enqueue({
|
|
2598
2613
|
type: 'error',
|
|
2599
|
-
error:
|
|
2600
|
-
type: 'response.failed',
|
|
2601
|
-
sequence_number: value.sequence_number,
|
|
2602
|
-
response: {
|
|
2603
|
-
error: value.response.error,
|
|
2604
|
-
incomplete_details: value.response.incomplete_details,
|
|
2605
|
-
service_tier: value.response.service_tier,
|
|
2606
|
-
},
|
|
2607
|
-
},
|
|
2614
|
+
error: createOpenAIProviderStreamError(error) ?? error,
|
|
2608
2615
|
});
|
|
2609
2616
|
}
|
|
2610
2617
|
} else if (isResponseAnnotationAddedChunk(value)) {
|
|
@@ -2678,7 +2685,10 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
|
|
|
2678
2685
|
} else if (isErrorChunk(value)) {
|
|
2679
2686
|
encounteredStreamError = true;
|
|
2680
2687
|
finishReason = { unified: 'error', raw: 'error' };
|
|
2681
|
-
controller.enqueue({
|
|
2688
|
+
controller.enqueue({
|
|
2689
|
+
type: 'error',
|
|
2690
|
+
error: createOpenAIProviderStreamError(value) ?? value,
|
|
2691
|
+
});
|
|
2682
2692
|
}
|
|
2683
2693
|
},
|
|
2684
2694
|
|