@ai-sdk/openai 4.0.0-beta.7 → 4.0.0-beta.75
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 +642 -24
- package/README.md +2 -0
- package/dist/index.d.ts +240 -44
- package/dist/index.js +3348 -1685
- package/dist/index.js.map +1 -1
- package/dist/internal/index.d.ts +390 -36
- package/dist/internal/index.js +2710 -1708
- package/dist/internal/index.js.map +1 -1
- package/docs/03-openai.mdx +414 -40
- package/package.json +16 -17
- package/src/chat/convert-openai-chat-usage.ts +1 -1
- package/src/chat/convert-to-openai-chat-messages.ts +96 -68
- package/src/chat/map-openai-finish-reason.ts +1 -1
- package/src/chat/openai-chat-api.ts +6 -2
- package/src/chat/{openai-chat-options.ts → openai-chat-language-model-options.ts} +11 -1
- package/src/chat/openai-chat-language-model.ts +82 -148
- package/src/chat/openai-chat-prepare-tools.ts +3 -3
- package/src/completion/convert-openai-completion-usage.ts +1 -1
- package/src/completion/convert-to-openai-completion-prompt.ts +1 -2
- package/src/completion/map-openai-finish-reason.ts +1 -1
- package/src/completion/openai-completion-api.ts +5 -2
- package/src/completion/{openai-completion-options.ts → openai-completion-language-model-options.ts} +5 -1
- package/src/completion/openai-completion-language-model.ts +53 -17
- package/src/embedding/{openai-embedding-options.ts → openai-embedding-model-options.ts} +5 -1
- package/src/embedding/openai-embedding-model.ts +22 -5
- package/src/files/openai-files-api.ts +17 -0
- package/src/files/openai-files-options.ts +22 -0
- package/src/files/openai-files.ts +100 -0
- package/src/image/openai-image-model-options.ts +123 -0
- package/src/image/openai-image-model.ts +62 -83
- package/src/index.ts +15 -6
- package/src/internal/index.ts +7 -6
- package/src/openai-config.ts +7 -7
- package/src/openai-language-model-capabilities.ts +5 -4
- package/src/openai-provider.ts +80 -9
- package/src/openai-stream-error.ts +181 -0
- package/src/openai-tools.ts +12 -1
- package/src/realtime/index.ts +2 -0
- package/src/realtime/openai-realtime-event-mapper.ts +436 -0
- package/src/realtime/openai-realtime-model-options.ts +3 -0
- package/src/realtime/openai-realtime-model.ts +111 -0
- package/src/responses/convert-openai-responses-usage.ts +1 -1
- package/src/responses/convert-to-openai-responses-input.ts +345 -90
- package/src/responses/map-openai-responses-finish-reason.ts +1 -1
- package/src/responses/openai-responses-api.ts +186 -17
- package/src/responses/{openai-responses-options.ts → openai-responses-language-model-options.ts} +55 -1
- package/src/responses/openai-responses-language-model.ts +339 -55
- package/src/responses/openai-responses-prepare-tools.ts +129 -18
- package/src/responses/openai-responses-provider-metadata.ts +12 -2
- package/src/skills/openai-skills-api.ts +31 -0
- package/src/skills/openai-skills.ts +83 -0
- package/src/speech/{openai-speech-options.ts → openai-speech-model-options.ts} +5 -1
- package/src/speech/openai-speech-model.ts +23 -7
- package/src/tool/apply-patch.ts +33 -32
- package/src/tool/code-interpreter.ts +40 -41
- package/src/tool/custom.ts +2 -8
- package/src/tool/file-search.ts +3 -3
- package/src/tool/image-generation.ts +2 -2
- package/src/tool/local-shell.ts +2 -2
- package/src/tool/mcp.ts +3 -3
- package/src/tool/shell.ts +9 -4
- package/src/tool/tool-search.ts +98 -0
- package/src/tool/web-search-preview.ts +2 -2
- package/src/tool/web-search.ts +10 -2
- package/src/transcription/{openai-transcription-options.ts → openai-transcription-model-options.ts} +5 -1
- package/src/transcription/openai-transcription-model.ts +35 -13
- package/dist/index.d.mts +0 -1107
- package/dist/index.mjs +0 -6509
- package/dist/index.mjs.map +0 -1
- package/dist/internal/index.d.mts +0 -1137
- package/dist/internal/index.mjs +0 -6322
- package/dist/internal/index.mjs.map +0 -1
- package/src/image/openai-image-options.ts +0 -31
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import {
|
|
2
2
|
APICallError,
|
|
3
|
-
JSONValue,
|
|
4
|
-
LanguageModelV4,
|
|
5
|
-
LanguageModelV4Prompt,
|
|
6
|
-
LanguageModelV4CallOptions,
|
|
7
|
-
LanguageModelV4Content,
|
|
8
|
-
LanguageModelV4FinishReason,
|
|
9
|
-
LanguageModelV4GenerateResult,
|
|
10
|
-
LanguageModelV4ProviderTool,
|
|
11
|
-
LanguageModelV4StreamPart,
|
|
12
|
-
LanguageModelV4StreamResult,
|
|
13
|
-
LanguageModelV4ToolApprovalRequest,
|
|
14
|
-
SharedV4ProviderMetadata,
|
|
15
|
-
SharedV4Warning,
|
|
3
|
+
type JSONValue,
|
|
4
|
+
type LanguageModelV4,
|
|
5
|
+
type LanguageModelV4Prompt,
|
|
6
|
+
type LanguageModelV4CallOptions,
|
|
7
|
+
type LanguageModelV4Content,
|
|
8
|
+
type LanguageModelV4FinishReason,
|
|
9
|
+
type LanguageModelV4GenerateResult,
|
|
10
|
+
type LanguageModelV4ProviderTool,
|
|
11
|
+
type LanguageModelV4StreamPart,
|
|
12
|
+
type LanguageModelV4StreamResult,
|
|
13
|
+
type LanguageModelV4ToolApprovalRequest,
|
|
14
|
+
type SharedV4ProviderMetadata,
|
|
15
|
+
type SharedV4Warning,
|
|
16
16
|
} from '@ai-sdk/provider';
|
|
17
17
|
import {
|
|
18
18
|
combineHeaders,
|
|
@@ -20,49 +20,59 @@ import {
|
|
|
20
20
|
createJsonResponseHandler,
|
|
21
21
|
createToolNameMapping,
|
|
22
22
|
generateId,
|
|
23
|
-
|
|
23
|
+
isCustomReasoning,
|
|
24
24
|
parseProviderOptions,
|
|
25
|
-
ParseResult,
|
|
26
25
|
postJsonToApi,
|
|
26
|
+
serializeModelOptions,
|
|
27
|
+
WORKFLOW_DESERIALIZE,
|
|
28
|
+
WORKFLOW_SERIALIZE,
|
|
29
|
+
type InferSchema,
|
|
30
|
+
type ParseResult,
|
|
27
31
|
} from '@ai-sdk/provider-utils';
|
|
28
|
-
import { OpenAIConfig } from '../openai-config';
|
|
32
|
+
import type { OpenAIConfig } from '../openai-config';
|
|
29
33
|
import { openaiFailedResponseHandler } from '../openai-error';
|
|
30
34
|
import { getOpenAILanguageModelCapabilities } from '../openai-language-model-capabilities';
|
|
31
|
-
import {
|
|
32
|
-
import {
|
|
35
|
+
import { throwIfOpenAIStreamErrorBeforeOutput } from '../openai-stream-error';
|
|
36
|
+
import type { applyPatchInputSchema } from '../tool/apply-patch';
|
|
37
|
+
import type {
|
|
33
38
|
codeInterpreterInputSchema,
|
|
34
39
|
codeInterpreterOutputSchema,
|
|
35
40
|
} from '../tool/code-interpreter';
|
|
36
|
-
import { fileSearchOutputSchema } from '../tool/file-search';
|
|
37
|
-
import { imageGenerationOutputSchema } from '../tool/image-generation';
|
|
38
|
-
import { localShellInputSchema } from '../tool/local-shell';
|
|
39
|
-
import { mcpOutputSchema } from '../tool/mcp';
|
|
40
|
-
import { shellInputSchema, shellOutputSchema } from '../tool/shell';
|
|
41
|
-
import {
|
|
41
|
+
import type { fileSearchOutputSchema } from '../tool/file-search';
|
|
42
|
+
import type { imageGenerationOutputSchema } from '../tool/image-generation';
|
|
43
|
+
import type { localShellInputSchema } from '../tool/local-shell';
|
|
44
|
+
import type { mcpOutputSchema } from '../tool/mcp';
|
|
45
|
+
import type { shellInputSchema, shellOutputSchema } from '../tool/shell';
|
|
46
|
+
import type {
|
|
47
|
+
toolSearchInputSchema,
|
|
48
|
+
toolSearchOutputSchema,
|
|
49
|
+
} from '../tool/tool-search';
|
|
50
|
+
import type { webSearchOutputSchema } from '../tool/web-search';
|
|
42
51
|
import {
|
|
43
52
|
convertOpenAIResponsesUsage,
|
|
44
|
-
OpenAIResponsesUsage,
|
|
53
|
+
type OpenAIResponsesUsage,
|
|
45
54
|
} from './convert-openai-responses-usage';
|
|
46
55
|
import { convertToOpenAIResponsesInput } from './convert-to-openai-responses-input';
|
|
47
56
|
import { mapOpenAIResponseFinishReason } from './map-openai-responses-finish-reason';
|
|
48
57
|
import {
|
|
49
|
-
OpenAIResponsesChunk,
|
|
50
58
|
openaiResponsesChunkSchema,
|
|
51
|
-
OpenAIResponsesIncludeOptions,
|
|
52
|
-
OpenAIResponsesIncludeValue,
|
|
53
|
-
OpenAIResponsesLogprobs,
|
|
54
59
|
openaiResponsesResponseSchema,
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
60
|
+
type OpenAIResponsesChunk,
|
|
61
|
+
type OpenAIResponsesIncludeOptions,
|
|
62
|
+
type OpenAIResponsesIncludeValue,
|
|
63
|
+
type OpenAIResponsesLogprobs,
|
|
64
|
+
type OpenAIResponsesWebSearchAction,
|
|
65
|
+
type OpenAIResponsesApplyPatchOperationDiffDeltaChunk,
|
|
66
|
+
type OpenAIResponsesApplyPatchOperationDiffDoneChunk,
|
|
58
67
|
} from './openai-responses-api';
|
|
59
68
|
import {
|
|
60
|
-
OpenAIResponsesModelId,
|
|
61
69
|
openaiLanguageModelResponsesOptionsSchema,
|
|
62
70
|
TOP_LOGPROBS_MAX,
|
|
63
|
-
|
|
71
|
+
type OpenAIResponsesModelId,
|
|
72
|
+
} from './openai-responses-language-model-options';
|
|
64
73
|
import { prepareResponsesTools } from './openai-responses-prepare-tools';
|
|
65
|
-
import {
|
|
74
|
+
import type {
|
|
75
|
+
ResponsesCompactionProviderMetadata,
|
|
66
76
|
ResponsesProviderMetadata,
|
|
67
77
|
ResponsesReasoningProviderMetadata,
|
|
68
78
|
ResponsesSourceDocumentProviderMetadata,
|
|
@@ -101,6 +111,20 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
|
|
|
101
111
|
|
|
102
112
|
private readonly config: OpenAIConfig;
|
|
103
113
|
|
|
114
|
+
static [WORKFLOW_SERIALIZE](model: OpenAIResponsesLanguageModel) {
|
|
115
|
+
return serializeModelOptions({
|
|
116
|
+
modelId: model.modelId,
|
|
117
|
+
config: model.config,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
static [WORKFLOW_DESERIALIZE](options: {
|
|
122
|
+
modelId: OpenAIResponsesModelId;
|
|
123
|
+
config: OpenAIConfig;
|
|
124
|
+
}) {
|
|
125
|
+
return new OpenAIResponsesLanguageModel(options.modelId, options.config);
|
|
126
|
+
}
|
|
127
|
+
|
|
104
128
|
constructor(modelId: OpenAIResponsesModelId, config: OpenAIConfig) {
|
|
105
129
|
this.modelId = modelId;
|
|
106
130
|
this.config = config;
|
|
@@ -125,6 +149,7 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
|
|
|
125
149
|
frequencyPenalty,
|
|
126
150
|
seed,
|
|
127
151
|
prompt,
|
|
152
|
+
reasoning,
|
|
128
153
|
providerOptions,
|
|
129
154
|
tools,
|
|
130
155
|
toolChoice,
|
|
@@ -170,6 +195,16 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
|
|
|
170
195
|
});
|
|
171
196
|
}
|
|
172
197
|
|
|
198
|
+
const resolvedReasoningEffort =
|
|
199
|
+
openaiOptions?.reasoningEffort ??
|
|
200
|
+
(isCustomReasoning(reasoning) ? reasoning : undefined);
|
|
201
|
+
const resolvedReasoningSummary =
|
|
202
|
+
openaiOptions?.reasoningSummary !== undefined
|
|
203
|
+
? openaiOptions.reasoningSummary
|
|
204
|
+
: resolvedReasoningEffort != null && resolvedReasoningEffort !== 'none'
|
|
205
|
+
? 'detailed'
|
|
206
|
+
: undefined;
|
|
207
|
+
|
|
173
208
|
const isReasoningModel =
|
|
174
209
|
openaiOptions?.forceReasoning ?? modelCapabilities.isReasoningModel;
|
|
175
210
|
|
|
@@ -193,11 +228,8 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
|
|
|
193
228
|
'openai.web_search_preview': 'web_search_preview',
|
|
194
229
|
'openai.mcp': 'mcp',
|
|
195
230
|
'openai.apply_patch': 'apply_patch',
|
|
231
|
+
'openai.tool_search': 'tool_search',
|
|
196
232
|
},
|
|
197
|
-
resolveProviderToolName: tool =>
|
|
198
|
-
tool.id === 'openai.custom'
|
|
199
|
-
? (tool.args as { name?: string }).name
|
|
200
|
-
: undefined,
|
|
201
233
|
});
|
|
202
234
|
|
|
203
235
|
const customProviderToolNames = new Set<string>();
|
|
@@ -208,6 +240,7 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
|
|
|
208
240
|
} = await prepareResponsesTools({
|
|
209
241
|
tools,
|
|
210
242
|
toolChoice,
|
|
243
|
+
allowedTools: openaiOptions?.allowedTools ?? undefined,
|
|
211
244
|
toolNameMapping,
|
|
212
245
|
customProviderToolNames,
|
|
213
246
|
});
|
|
@@ -223,8 +256,11 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
|
|
|
223
256
|
: modelCapabilities.systemMessageMode),
|
|
224
257
|
providerOptionsName,
|
|
225
258
|
fileIdPrefixes: this.config.fileIdPrefixes,
|
|
259
|
+
passThroughUnsupportedFiles:
|
|
260
|
+
openaiOptions?.passThroughUnsupportedFiles ?? false,
|
|
226
261
|
store: openaiOptions?.store ?? true,
|
|
227
262
|
hasConversation: openaiOptions?.conversation != null,
|
|
263
|
+
hasPreviousResponseId: openaiOptions?.previousResponseId != null,
|
|
228
264
|
hasLocalShellTool: hasOpenAITool('openai.local_shell'),
|
|
229
265
|
hasShellTool: hasOpenAITool('openai.shell'),
|
|
230
266
|
hasApplyPatchTool: hasOpenAITool('openai.apply_patch'),
|
|
@@ -336,16 +372,24 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
|
|
|
336
372
|
top_logprobs: topLogprobs,
|
|
337
373
|
truncation: openaiOptions?.truncation,
|
|
338
374
|
|
|
375
|
+
// context management (server-side compaction):
|
|
376
|
+
...(openaiOptions?.contextManagement && {
|
|
377
|
+
context_management: openaiOptions.contextManagement.map(cm => ({
|
|
378
|
+
type: cm.type,
|
|
379
|
+
compact_threshold: cm.compactThreshold,
|
|
380
|
+
})),
|
|
381
|
+
}),
|
|
382
|
+
|
|
339
383
|
// model-specific settings:
|
|
340
384
|
...(isReasoningModel &&
|
|
341
|
-
(
|
|
342
|
-
|
|
385
|
+
(resolvedReasoningEffort != null ||
|
|
386
|
+
resolvedReasoningSummary != null) && {
|
|
343
387
|
reasoning: {
|
|
344
|
-
...(
|
|
345
|
-
effort:
|
|
388
|
+
...(resolvedReasoningEffort != null && {
|
|
389
|
+
effort: resolvedReasoningEffort,
|
|
346
390
|
}),
|
|
347
|
-
...(
|
|
348
|
-
summary:
|
|
391
|
+
...(resolvedReasoningSummary != null && {
|
|
392
|
+
summary: resolvedReasoningSummary,
|
|
349
393
|
}),
|
|
350
394
|
},
|
|
351
395
|
}),
|
|
@@ -358,7 +402,7 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
|
|
|
358
402
|
// https://platform.openai.com/docs/guides/latest-model#gpt-5-1-parameter-compatibility
|
|
359
403
|
if (
|
|
360
404
|
!(
|
|
361
|
-
|
|
405
|
+
resolvedReasoningEffort === 'none' &&
|
|
362
406
|
modelCapabilities.supportsNonReasoningParameters
|
|
363
407
|
)
|
|
364
408
|
) {
|
|
@@ -478,7 +522,7 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
|
|
|
478
522
|
rawValue: rawResponse,
|
|
479
523
|
} = await postJsonToApi({
|
|
480
524
|
url,
|
|
481
|
-
headers: combineHeaders(this.config.headers(), options.headers),
|
|
525
|
+
headers: combineHeaders(this.config.headers?.(), options.headers),
|
|
482
526
|
body,
|
|
483
527
|
failedResponseHandler: openaiFailedResponseHandler,
|
|
484
528
|
successfulResponseHandler: createJsonResponseHandler(
|
|
@@ -505,6 +549,7 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
|
|
|
505
549
|
|
|
506
550
|
// flag that checks if there have been client-side tool calls (not executed by openai)
|
|
507
551
|
let hasFunctionCall = false;
|
|
552
|
+
const hostedToolSearchCallIds: string[] = [];
|
|
508
553
|
|
|
509
554
|
// map response content to content array (defined when there is no error)
|
|
510
555
|
for (const part of response.output!) {
|
|
@@ -551,6 +596,54 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
|
|
|
551
596
|
break;
|
|
552
597
|
}
|
|
553
598
|
|
|
599
|
+
case 'tool_search_call': {
|
|
600
|
+
const toolCallId = part.call_id ?? part.id;
|
|
601
|
+
const isHosted = part.execution === 'server';
|
|
602
|
+
|
|
603
|
+
if (isHosted) {
|
|
604
|
+
hostedToolSearchCallIds.push(toolCallId);
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
content.push({
|
|
608
|
+
type: 'tool-call',
|
|
609
|
+
toolCallId,
|
|
610
|
+
toolName: toolNameMapping.toCustomToolName('tool_search'),
|
|
611
|
+
input: JSON.stringify({
|
|
612
|
+
arguments: part.arguments,
|
|
613
|
+
call_id: part.call_id,
|
|
614
|
+
} satisfies InferSchema<typeof toolSearchInputSchema>),
|
|
615
|
+
...(isHosted ? { providerExecuted: true } : {}),
|
|
616
|
+
providerMetadata: {
|
|
617
|
+
[providerOptionsName]: {
|
|
618
|
+
itemId: part.id,
|
|
619
|
+
},
|
|
620
|
+
},
|
|
621
|
+
});
|
|
622
|
+
|
|
623
|
+
break;
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
case 'tool_search_output': {
|
|
627
|
+
const toolCallId =
|
|
628
|
+
part.call_id ?? hostedToolSearchCallIds.shift() ?? part.id;
|
|
629
|
+
|
|
630
|
+
content.push({
|
|
631
|
+
type: 'tool-result',
|
|
632
|
+
toolCallId,
|
|
633
|
+
toolName: toolNameMapping.toCustomToolName('tool_search'),
|
|
634
|
+
result: {
|
|
635
|
+
tools: part.tools,
|
|
636
|
+
} satisfies InferSchema<typeof toolSearchOutputSchema>,
|
|
637
|
+
providerMetadata: {
|
|
638
|
+
[providerOptionsName]: {
|
|
639
|
+
itemId: part.id,
|
|
640
|
+
},
|
|
641
|
+
},
|
|
642
|
+
});
|
|
643
|
+
|
|
644
|
+
break;
|
|
645
|
+
}
|
|
646
|
+
|
|
554
647
|
case 'local_shell_call': {
|
|
555
648
|
content.push({
|
|
556
649
|
type: 'tool-call',
|
|
@@ -721,6 +814,7 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
|
|
|
721
814
|
providerMetadata: {
|
|
722
815
|
[providerOptionsName]: {
|
|
723
816
|
itemId: part.id,
|
|
817
|
+
...(part.namespace != null && { namespace: part.namespace }),
|
|
724
818
|
},
|
|
725
819
|
},
|
|
726
820
|
});
|
|
@@ -927,6 +1021,21 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
|
|
|
927
1021
|
|
|
928
1022
|
break;
|
|
929
1023
|
}
|
|
1024
|
+
|
|
1025
|
+
case 'compaction': {
|
|
1026
|
+
content.push({
|
|
1027
|
+
type: 'custom',
|
|
1028
|
+
kind: 'openai.compaction',
|
|
1029
|
+
providerMetadata: {
|
|
1030
|
+
[providerOptionsName]: {
|
|
1031
|
+
type: 'compaction',
|
|
1032
|
+
itemId: part.id,
|
|
1033
|
+
encryptedContent: part.encrypted_content,
|
|
1034
|
+
} satisfies ResponsesCompactionProviderMetadata,
|
|
1035
|
+
},
|
|
1036
|
+
});
|
|
1037
|
+
break;
|
|
1038
|
+
}
|
|
930
1039
|
}
|
|
931
1040
|
}
|
|
932
1041
|
|
|
@@ -978,12 +1087,14 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
|
|
|
978
1087
|
isShellProviderExecuted,
|
|
979
1088
|
} = await this.getArgs(options);
|
|
980
1089
|
|
|
1090
|
+
const url = this.config.url({
|
|
1091
|
+
path: '/responses',
|
|
1092
|
+
modelId: this.modelId,
|
|
1093
|
+
});
|
|
1094
|
+
|
|
981
1095
|
const { responseHeaders, value: response } = await postJsonToApi({
|
|
982
|
-
url
|
|
983
|
-
|
|
984
|
-
modelId: this.modelId,
|
|
985
|
-
}),
|
|
986
|
-
headers: combineHeaders(this.config.headers(), options.headers),
|
|
1096
|
+
url,
|
|
1097
|
+
headers: combineHeaders(this.config.headers?.(), options.headers),
|
|
987
1098
|
body: {
|
|
988
1099
|
...body,
|
|
989
1100
|
stream: true,
|
|
@@ -996,6 +1107,19 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
|
|
|
996
1107
|
fetch: this.config.fetch,
|
|
997
1108
|
});
|
|
998
1109
|
|
|
1110
|
+
const checkedResponse = await throwIfOpenAIStreamErrorBeforeOutput({
|
|
1111
|
+
stream: response,
|
|
1112
|
+
getError: chunk =>
|
|
1113
|
+
isErrorChunk(chunk) ||
|
|
1114
|
+
(isResponseFailedChunk(chunk) && chunk.response.error != null)
|
|
1115
|
+
? chunk
|
|
1116
|
+
: undefined,
|
|
1117
|
+
isOutputChunk: isResponseOutputChunk,
|
|
1118
|
+
url,
|
|
1119
|
+
requestBodyValues: body,
|
|
1120
|
+
responseHeaders,
|
|
1121
|
+
});
|
|
1122
|
+
|
|
999
1123
|
const self = this;
|
|
1000
1124
|
|
|
1001
1125
|
const approvalRequestIdToDummyToolCallIdFromPrompt =
|
|
@@ -1026,6 +1150,7 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
|
|
|
1026
1150
|
hasDiff: boolean;
|
|
1027
1151
|
endEmitted: boolean;
|
|
1028
1152
|
};
|
|
1153
|
+
toolSearchExecution?: 'server' | 'client';
|
|
1029
1154
|
}
|
|
1030
1155
|
| undefined
|
|
1031
1156
|
> = {};
|
|
@@ -1054,9 +1179,11 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
|
|
|
1054
1179
|
> = {};
|
|
1055
1180
|
|
|
1056
1181
|
let serviceTier: string | undefined;
|
|
1182
|
+
const hostedToolSearchCallIds: string[] = [];
|
|
1183
|
+
let encounteredStreamError = false;
|
|
1057
1184
|
|
|
1058
|
-
|
|
1059
|
-
stream:
|
|
1185
|
+
const result = {
|
|
1186
|
+
stream: checkedResponse.pipeThrough(
|
|
1060
1187
|
new TransformStream<
|
|
1061
1188
|
ParseResult<OpenAIResponsesChunk>,
|
|
1062
1189
|
LanguageModelV4StreamPart
|
|
@@ -1188,6 +1315,28 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
|
|
|
1188
1315
|
input: '{}',
|
|
1189
1316
|
providerExecuted: true,
|
|
1190
1317
|
});
|
|
1318
|
+
} else if (value.item.type === 'tool_search_call') {
|
|
1319
|
+
const toolCallId = value.item.id;
|
|
1320
|
+
const toolName =
|
|
1321
|
+
toolNameMapping.toCustomToolName('tool_search');
|
|
1322
|
+
const isHosted = value.item.execution === 'server';
|
|
1323
|
+
|
|
1324
|
+
ongoingToolCalls[value.output_index] = {
|
|
1325
|
+
toolName,
|
|
1326
|
+
toolCallId,
|
|
1327
|
+
toolSearchExecution: value.item.execution ?? 'server',
|
|
1328
|
+
};
|
|
1329
|
+
|
|
1330
|
+
if (isHosted) {
|
|
1331
|
+
controller.enqueue({
|
|
1332
|
+
type: 'tool-input-start',
|
|
1333
|
+
id: toolCallId,
|
|
1334
|
+
toolName,
|
|
1335
|
+
providerExecuted: true,
|
|
1336
|
+
});
|
|
1337
|
+
}
|
|
1338
|
+
} else if (value.item.type === 'tool_search_output') {
|
|
1339
|
+
// handled on output_item.done so we can pair it with the call
|
|
1191
1340
|
} else if (
|
|
1192
1341
|
value.item.type === 'mcp_call' ||
|
|
1193
1342
|
value.item.type === 'mcp_list_tools' ||
|
|
@@ -1305,6 +1454,13 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
|
|
|
1305
1454
|
controller.enqueue({
|
|
1306
1455
|
type: 'tool-input-end',
|
|
1307
1456
|
id: value.item.call_id,
|
|
1457
|
+
...(value.item.namespace != null && {
|
|
1458
|
+
providerMetadata: {
|
|
1459
|
+
[providerOptionsName]: {
|
|
1460
|
+
namespace: value.item.namespace,
|
|
1461
|
+
},
|
|
1462
|
+
},
|
|
1463
|
+
}),
|
|
1308
1464
|
});
|
|
1309
1465
|
|
|
1310
1466
|
controller.enqueue({
|
|
@@ -1315,6 +1471,9 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
|
|
|
1315
1471
|
providerMetadata: {
|
|
1316
1472
|
[providerOptionsName]: {
|
|
1317
1473
|
itemId: value.item.id,
|
|
1474
|
+
...(value.item.namespace != null && {
|
|
1475
|
+
namespace: value.item.namespace,
|
|
1476
|
+
}),
|
|
1318
1477
|
},
|
|
1319
1478
|
},
|
|
1320
1479
|
});
|
|
@@ -1418,6 +1577,67 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
|
|
|
1418
1577
|
result: value.item.result,
|
|
1419
1578
|
} satisfies InferSchema<typeof imageGenerationOutputSchema>,
|
|
1420
1579
|
});
|
|
1580
|
+
} else if (value.item.type === 'tool_search_call') {
|
|
1581
|
+
const toolCall = ongoingToolCalls[value.output_index];
|
|
1582
|
+
const isHosted = value.item.execution === 'server';
|
|
1583
|
+
|
|
1584
|
+
if (toolCall != null) {
|
|
1585
|
+
const toolCallId = isHosted
|
|
1586
|
+
? toolCall.toolCallId
|
|
1587
|
+
: (value.item.call_id ?? value.item.id);
|
|
1588
|
+
|
|
1589
|
+
if (isHosted) {
|
|
1590
|
+
hostedToolSearchCallIds.push(toolCallId);
|
|
1591
|
+
} else {
|
|
1592
|
+
controller.enqueue({
|
|
1593
|
+
type: 'tool-input-start',
|
|
1594
|
+
id: toolCallId,
|
|
1595
|
+
toolName: toolCall.toolName,
|
|
1596
|
+
});
|
|
1597
|
+
}
|
|
1598
|
+
|
|
1599
|
+
controller.enqueue({
|
|
1600
|
+
type: 'tool-input-end',
|
|
1601
|
+
id: toolCallId,
|
|
1602
|
+
});
|
|
1603
|
+
|
|
1604
|
+
controller.enqueue({
|
|
1605
|
+
type: 'tool-call',
|
|
1606
|
+
toolCallId,
|
|
1607
|
+
toolName: toolCall.toolName,
|
|
1608
|
+
input: JSON.stringify({
|
|
1609
|
+
arguments: value.item.arguments,
|
|
1610
|
+
call_id: isHosted ? null : toolCallId,
|
|
1611
|
+
} satisfies InferSchema<typeof toolSearchInputSchema>),
|
|
1612
|
+
...(isHosted ? { providerExecuted: true } : {}),
|
|
1613
|
+
providerMetadata: {
|
|
1614
|
+
[providerOptionsName]: {
|
|
1615
|
+
itemId: value.item.id,
|
|
1616
|
+
},
|
|
1617
|
+
},
|
|
1618
|
+
});
|
|
1619
|
+
}
|
|
1620
|
+
|
|
1621
|
+
ongoingToolCalls[value.output_index] = undefined;
|
|
1622
|
+
} else if (value.item.type === 'tool_search_output') {
|
|
1623
|
+
const toolCallId =
|
|
1624
|
+
value.item.call_id ??
|
|
1625
|
+
hostedToolSearchCallIds.shift() ??
|
|
1626
|
+
value.item.id;
|
|
1627
|
+
|
|
1628
|
+
controller.enqueue({
|
|
1629
|
+
type: 'tool-result',
|
|
1630
|
+
toolCallId,
|
|
1631
|
+
toolName: toolNameMapping.toCustomToolName('tool_search'),
|
|
1632
|
+
result: {
|
|
1633
|
+
tools: value.item.tools,
|
|
1634
|
+
} satisfies InferSchema<typeof toolSearchOutputSchema>,
|
|
1635
|
+
providerMetadata: {
|
|
1636
|
+
[providerOptionsName]: {
|
|
1637
|
+
itemId: value.item.id,
|
|
1638
|
+
},
|
|
1639
|
+
},
|
|
1640
|
+
});
|
|
1421
1641
|
} else if (value.item.type === 'mcp_call') {
|
|
1422
1642
|
ongoingToolCalls[value.output_index] = undefined;
|
|
1423
1643
|
|
|
@@ -1647,6 +1867,18 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
|
|
|
1647
1867
|
}
|
|
1648
1868
|
|
|
1649
1869
|
delete activeReasoning[value.item.id];
|
|
1870
|
+
} else if (value.item.type === 'compaction') {
|
|
1871
|
+
controller.enqueue({
|
|
1872
|
+
type: 'custom',
|
|
1873
|
+
kind: 'openai.compaction',
|
|
1874
|
+
providerMetadata: {
|
|
1875
|
+
[providerOptionsName]: {
|
|
1876
|
+
type: 'compaction',
|
|
1877
|
+
itemId: value.item.id,
|
|
1878
|
+
encryptedContent: value.item.encrypted_content,
|
|
1879
|
+
} satisfies ResponsesCompactionProviderMetadata,
|
|
1880
|
+
},
|
|
1881
|
+
});
|
|
1650
1882
|
}
|
|
1651
1883
|
} else if (isResponseFunctionCallArgumentsDeltaChunk(value)) {
|
|
1652
1884
|
const toolCall = ongoingToolCalls[value.output_index];
|
|
@@ -1867,6 +2099,35 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
|
|
|
1867
2099
|
if (typeof value.response.service_tier === 'string') {
|
|
1868
2100
|
serviceTier = value.response.service_tier;
|
|
1869
2101
|
}
|
|
2102
|
+
} else if (isResponseFailedChunk(value)) {
|
|
2103
|
+
const incompleteReason =
|
|
2104
|
+
value.response.incomplete_details?.reason;
|
|
2105
|
+
finishReason = {
|
|
2106
|
+
unified: incompleteReason
|
|
2107
|
+
? mapOpenAIResponseFinishReason({
|
|
2108
|
+
finishReason: incompleteReason,
|
|
2109
|
+
hasFunctionCall,
|
|
2110
|
+
})
|
|
2111
|
+
: 'error',
|
|
2112
|
+
raw: incompleteReason ?? 'error',
|
|
2113
|
+
};
|
|
2114
|
+
usage = value.response.usage ?? undefined;
|
|
2115
|
+
|
|
2116
|
+
if (!encounteredStreamError && value.response.error != null) {
|
|
2117
|
+
encounteredStreamError = true;
|
|
2118
|
+
controller.enqueue({
|
|
2119
|
+
type: 'error',
|
|
2120
|
+
error: {
|
|
2121
|
+
type: 'response.failed',
|
|
2122
|
+
sequence_number: value.sequence_number,
|
|
2123
|
+
response: {
|
|
2124
|
+
error: value.response.error,
|
|
2125
|
+
incomplete_details: value.response.incomplete_details,
|
|
2126
|
+
service_tier: value.response.service_tier,
|
|
2127
|
+
},
|
|
2128
|
+
},
|
|
2129
|
+
});
|
|
2130
|
+
}
|
|
1870
2131
|
} else if (isResponseAnnotationAddedChunk(value)) {
|
|
1871
2132
|
ongoingAnnotations.push(value.annotation);
|
|
1872
2133
|
if (value.annotation.type === 'url_citation') {
|
|
@@ -1936,6 +2197,8 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
|
|
|
1936
2197
|
});
|
|
1937
2198
|
}
|
|
1938
2199
|
} else if (isErrorChunk(value)) {
|
|
2200
|
+
encounteredStreamError = true;
|
|
2201
|
+
finishReason = { unified: 'error', raw: 'error' };
|
|
1939
2202
|
controller.enqueue({ type: 'error', error: value });
|
|
1940
2203
|
}
|
|
1941
2204
|
},
|
|
@@ -1961,6 +2224,8 @@ export class OpenAIResponsesLanguageModel implements LanguageModelV4 {
|
|
|
1961
2224
|
request: { body },
|
|
1962
2225
|
response: { headers: responseHeaders },
|
|
1963
2226
|
};
|
|
2227
|
+
|
|
2228
|
+
return result;
|
|
1964
2229
|
}
|
|
1965
2230
|
}
|
|
1966
2231
|
|
|
@@ -1986,6 +2251,12 @@ function isResponseFinishedChunk(
|
|
|
1986
2251
|
);
|
|
1987
2252
|
}
|
|
1988
2253
|
|
|
2254
|
+
function isResponseFailedChunk(
|
|
2255
|
+
chunk: OpenAIResponsesChunk,
|
|
2256
|
+
): chunk is OpenAIResponsesChunk & { type: 'response.failed' } {
|
|
2257
|
+
return chunk.type === 'response.failed';
|
|
2258
|
+
}
|
|
2259
|
+
|
|
1989
2260
|
function isResponseCreatedChunk(
|
|
1990
2261
|
chunk: OpenAIResponsesChunk,
|
|
1991
2262
|
): chunk is OpenAIResponsesChunk & { type: 'response.created' } {
|
|
@@ -2064,6 +2335,15 @@ function isErrorChunk(
|
|
|
2064
2335
|
return chunk.type === 'error';
|
|
2065
2336
|
}
|
|
2066
2337
|
|
|
2338
|
+
function isResponseOutputChunk(chunk: OpenAIResponsesChunk): boolean {
|
|
2339
|
+
return !(
|
|
2340
|
+
chunk.type === 'response.created' ||
|
|
2341
|
+
chunk.type === 'response.failed' ||
|
|
2342
|
+
chunk.type === 'error' ||
|
|
2343
|
+
chunk.type === 'unknown_chunk'
|
|
2344
|
+
);
|
|
2345
|
+
}
|
|
2346
|
+
|
|
2067
2347
|
function mapWebSearchOutput(
|
|
2068
2348
|
action: OpenAIResponsesWebSearchAction | null | undefined,
|
|
2069
2349
|
): InferSchema<typeof webSearchOutputSchema> {
|
|
@@ -2074,7 +2354,11 @@ function mapWebSearchOutput(
|
|
|
2074
2354
|
switch (action.type) {
|
|
2075
2355
|
case 'search':
|
|
2076
2356
|
return {
|
|
2077
|
-
action: {
|
|
2357
|
+
action: {
|
|
2358
|
+
type: 'search',
|
|
2359
|
+
query: action.query ?? undefined,
|
|
2360
|
+
...(action.queries != null && { queries: action.queries }),
|
|
2361
|
+
},
|
|
2078
2362
|
// include sources when provided by the Responses API (behind include flag)
|
|
2079
2363
|
...(action.sources != null && { sources: action.sources }),
|
|
2080
2364
|
};
|