@yourgpt/llm-sdk 2.6.0-beta.2 → 2.6.0-beta.3
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/README.md +42 -8
- package/dist/adapters/index.js +86 -21
- package/dist/adapters/index.mjs +86 -21
- package/dist/index.d.mts +3 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.js +108 -19
- package/dist/index.mjs +108 -19
- package/dist/providers/anthropic/index.js +6 -13
- package/dist/providers/anthropic/index.mjs +6 -13
- package/dist/providers/fireworks/index.js +80 -8
- package/dist/providers/fireworks/index.mjs +80 -8
- package/dist/providers/google/index.js +80 -8
- package/dist/providers/google/index.mjs +80 -8
- package/dist/providers/openai/index.js +80 -8
- package/dist/providers/openai/index.mjs +80 -8
- package/dist/providers/openrouter/index.js +80 -8
- package/dist/providers/openrouter/index.mjs +80 -8
- package/dist/providers/togetherai/index.js +80 -8
- package/dist/providers/togetherai/index.mjs +80 -8
- package/dist/providers/xai/index.js +80 -8
- package/dist/providers/xai/index.mjs +80 -8
- package/package.json +1 -1
|
@@ -713,6 +713,54 @@ function responseMetadata(response) {
|
|
|
713
713
|
}
|
|
714
714
|
};
|
|
715
715
|
}
|
|
716
|
+
function responseReplayMetadata(metadata) {
|
|
717
|
+
const response = metadata?.openai?.response;
|
|
718
|
+
if (!response) return metadata;
|
|
719
|
+
const output = response.output.map((item) => {
|
|
720
|
+
const fields = ["type", "id", "status"];
|
|
721
|
+
switch (item.type) {
|
|
722
|
+
case "reasoning":
|
|
723
|
+
fields.push("encrypted_content");
|
|
724
|
+
break;
|
|
725
|
+
case "message":
|
|
726
|
+
fields.push("role", "phase");
|
|
727
|
+
break;
|
|
728
|
+
case "function_call":
|
|
729
|
+
fields.push("call_id", "name", "namespace", "arguments");
|
|
730
|
+
break;
|
|
731
|
+
case "tool_search_call":
|
|
732
|
+
fields.push("call_id", "execution", "arguments");
|
|
733
|
+
break;
|
|
734
|
+
case "tool_search_output":
|
|
735
|
+
fields.push("call_id", "tools");
|
|
736
|
+
break;
|
|
737
|
+
case "web_search_call":
|
|
738
|
+
fields.push("action");
|
|
739
|
+
break;
|
|
740
|
+
default:
|
|
741
|
+
return stripItemDiagnostics(item);
|
|
742
|
+
}
|
|
743
|
+
const replay = Object.fromEntries(
|
|
744
|
+
fields.filter((key) => item[key] !== void 0).map((key) => [key, item[key]])
|
|
745
|
+
);
|
|
746
|
+
if (item.type === "reasoning") replay.summary = [];
|
|
747
|
+
if (item.type === "message")
|
|
748
|
+
replay.content = Array.isArray(item.content) ? item.content.flatMap(
|
|
749
|
+
(part) => part?.type === "output_text" && typeof part.text === "string" ? [{ type: "output_text", text: part.text, annotations: [] }] : part?.type === "refusal" && typeof part.refusal === "string" ? [{ type: "refusal", refusal: part.refusal }] : []
|
|
750
|
+
) : [];
|
|
751
|
+
return stripItemDiagnostics(replay);
|
|
752
|
+
});
|
|
753
|
+
return { openai: { response: { output, refusals: [] } } };
|
|
754
|
+
}
|
|
755
|
+
function stripItemDiagnostics(item) {
|
|
756
|
+
const {
|
|
757
|
+
usage: _usage,
|
|
758
|
+
logprobs: _logprobs,
|
|
759
|
+
metadata: _metadata,
|
|
760
|
+
...state
|
|
761
|
+
} = item;
|
|
762
|
+
return state;
|
|
763
|
+
}
|
|
716
764
|
function getResponseReplay(metadata) {
|
|
717
765
|
const response = metadata?.openai?.response;
|
|
718
766
|
if (response === void 0) return void 0;
|
|
@@ -721,10 +769,17 @@ function getResponseReplay(metadata) {
|
|
|
721
769
|
"Invalid OpenAI Responses replay metadata: output must contain typed items"
|
|
722
770
|
);
|
|
723
771
|
}
|
|
724
|
-
return response
|
|
772
|
+
return responseReplayMetadata(metadata)?.openai?.response?.output;
|
|
725
773
|
}
|
|
726
774
|
|
|
727
775
|
// src/core/provider-error.ts
|
|
776
|
+
function invalidProviderResponse(message) {
|
|
777
|
+
return Object.assign(new Error(message), {
|
|
778
|
+
name: "InvalidProviderResponseError",
|
|
779
|
+
status: 502,
|
|
780
|
+
code: "INVALID_PROVIDER_RESPONSE"
|
|
781
|
+
});
|
|
782
|
+
}
|
|
728
783
|
function providerErrorEvent(error, code) {
|
|
729
784
|
const details = error ?? {};
|
|
730
785
|
const event = {
|
|
@@ -901,7 +956,7 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
901
956
|
formatRawMessages(messages, preserveProviderMetadata = false) {
|
|
902
957
|
return messages.map((message) => {
|
|
903
958
|
const { attachments, providerMetadata, modelOutput, ...rest } = message;
|
|
904
|
-
let content = message.role === "tool" && !preserveProviderMetadata ? textToolOutput(modelOutput,
|
|
959
|
+
let content = message.role === "tool" && !preserveProviderMetadata && modelOutput !== void 0 ? textToolOutput(modelOutput, "") : message.content;
|
|
905
960
|
if (preserveProviderMetadata && modelOutput)
|
|
906
961
|
rest.modelOutput = modelOutput;
|
|
907
962
|
if (message.role === "assistant" && Array.isArray(message.tool_calls) && message.tool_calls.length > 0 && content === "") {
|
|
@@ -1004,17 +1059,32 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
1004
1059
|
const seenCallIds = /* @__PURE__ */ new Set();
|
|
1005
1060
|
const toolCalls = Array.isArray(response?.output) ? response.output.filter((item) => item?.type === "function_call").map((item) => {
|
|
1006
1061
|
if (typeof item.call_id !== "string" || !item.call_id || typeof item.name !== "string" || !item.name || typeof item.arguments !== "string" || item.status && item.status !== "completed") {
|
|
1007
|
-
throw
|
|
1062
|
+
throw invalidProviderResponse(
|
|
1063
|
+
"Responses contains an incomplete function call"
|
|
1064
|
+
);
|
|
1008
1065
|
}
|
|
1009
1066
|
if (seenCallIds.has(item.call_id))
|
|
1010
|
-
throw
|
|
1067
|
+
throw invalidProviderResponse(
|
|
1068
|
+
"Responses contains duplicate function call IDs"
|
|
1069
|
+
);
|
|
1011
1070
|
seenCallIds.add(item.call_id);
|
|
1012
|
-
|
|
1071
|
+
let args;
|
|
1072
|
+
try {
|
|
1073
|
+
args = JSON.parse(item.arguments);
|
|
1074
|
+
} catch {
|
|
1075
|
+
throw invalidProviderResponse(
|
|
1076
|
+
"Responses function arguments must be valid JSON"
|
|
1077
|
+
);
|
|
1078
|
+
}
|
|
1013
1079
|
if (!args || typeof args !== "object" || Array.isArray(args))
|
|
1014
|
-
throw
|
|
1080
|
+
throw invalidProviderResponse(
|
|
1015
1081
|
"Responses function arguments must be a JSON object"
|
|
1016
1082
|
);
|
|
1017
|
-
return {
|
|
1083
|
+
return {
|
|
1084
|
+
id: item.call_id,
|
|
1085
|
+
name: item.name,
|
|
1086
|
+
args
|
|
1087
|
+
};
|
|
1018
1088
|
}) : [];
|
|
1019
1089
|
return {
|
|
1020
1090
|
content,
|
|
@@ -1257,7 +1327,9 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
1257
1327
|
const uniqueCalls = /* @__PURE__ */ new Map();
|
|
1258
1328
|
for (const call of toolCalls.values()) {
|
|
1259
1329
|
if (!call.id || !call.name)
|
|
1260
|
-
throw
|
|
1330
|
+
throw invalidProviderResponse(
|
|
1331
|
+
"Responses stream contains an incomplete tool call"
|
|
1332
|
+
);
|
|
1261
1333
|
uniqueCalls.set(call.id, call);
|
|
1262
1334
|
}
|
|
1263
1335
|
toolCalls.clear();
|
|
@@ -201,6 +201,54 @@ function responseMetadata(response) {
|
|
|
201
201
|
}
|
|
202
202
|
};
|
|
203
203
|
}
|
|
204
|
+
function responseReplayMetadata(metadata) {
|
|
205
|
+
const response = metadata?.openai?.response;
|
|
206
|
+
if (!response) return metadata;
|
|
207
|
+
const output = response.output.map((item) => {
|
|
208
|
+
const fields = ["type", "id", "status"];
|
|
209
|
+
switch (item.type) {
|
|
210
|
+
case "reasoning":
|
|
211
|
+
fields.push("encrypted_content");
|
|
212
|
+
break;
|
|
213
|
+
case "message":
|
|
214
|
+
fields.push("role", "phase");
|
|
215
|
+
break;
|
|
216
|
+
case "function_call":
|
|
217
|
+
fields.push("call_id", "name", "namespace", "arguments");
|
|
218
|
+
break;
|
|
219
|
+
case "tool_search_call":
|
|
220
|
+
fields.push("call_id", "execution", "arguments");
|
|
221
|
+
break;
|
|
222
|
+
case "tool_search_output":
|
|
223
|
+
fields.push("call_id", "tools");
|
|
224
|
+
break;
|
|
225
|
+
case "web_search_call":
|
|
226
|
+
fields.push("action");
|
|
227
|
+
break;
|
|
228
|
+
default:
|
|
229
|
+
return stripItemDiagnostics(item);
|
|
230
|
+
}
|
|
231
|
+
const replay = Object.fromEntries(
|
|
232
|
+
fields.filter((key) => item[key] !== void 0).map((key) => [key, item[key]])
|
|
233
|
+
);
|
|
234
|
+
if (item.type === "reasoning") replay.summary = [];
|
|
235
|
+
if (item.type === "message")
|
|
236
|
+
replay.content = Array.isArray(item.content) ? item.content.flatMap(
|
|
237
|
+
(part) => part?.type === "output_text" && typeof part.text === "string" ? [{ type: "output_text", text: part.text, annotations: [] }] : part?.type === "refusal" && typeof part.refusal === "string" ? [{ type: "refusal", refusal: part.refusal }] : []
|
|
238
|
+
) : [];
|
|
239
|
+
return stripItemDiagnostics(replay);
|
|
240
|
+
});
|
|
241
|
+
return { openai: { response: { output, refusals: [] } } };
|
|
242
|
+
}
|
|
243
|
+
function stripItemDiagnostics(item) {
|
|
244
|
+
const {
|
|
245
|
+
usage: _usage,
|
|
246
|
+
logprobs: _logprobs,
|
|
247
|
+
metadata: _metadata,
|
|
248
|
+
...state
|
|
249
|
+
} = item;
|
|
250
|
+
return state;
|
|
251
|
+
}
|
|
204
252
|
function getResponseReplay(metadata) {
|
|
205
253
|
const response = metadata?.openai?.response;
|
|
206
254
|
if (response === void 0) return void 0;
|
|
@@ -209,10 +257,17 @@ function getResponseReplay(metadata) {
|
|
|
209
257
|
"Invalid OpenAI Responses replay metadata: output must contain typed items"
|
|
210
258
|
);
|
|
211
259
|
}
|
|
212
|
-
return response
|
|
260
|
+
return responseReplayMetadata(metadata)?.openai?.response?.output;
|
|
213
261
|
}
|
|
214
262
|
|
|
215
263
|
// src/core/provider-error.ts
|
|
264
|
+
function invalidProviderResponse(message) {
|
|
265
|
+
return Object.assign(new Error(message), {
|
|
266
|
+
name: "InvalidProviderResponseError",
|
|
267
|
+
status: 502,
|
|
268
|
+
code: "INVALID_PROVIDER_RESPONSE"
|
|
269
|
+
});
|
|
270
|
+
}
|
|
216
271
|
function providerErrorEvent(error, code) {
|
|
217
272
|
const details = error ?? {};
|
|
218
273
|
const event = {
|
|
@@ -625,7 +680,7 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
625
680
|
formatRawMessages(messages, preserveProviderMetadata = false) {
|
|
626
681
|
return messages.map((message) => {
|
|
627
682
|
const { attachments, providerMetadata, modelOutput, ...rest } = message;
|
|
628
|
-
let content = message.role === "tool" && !preserveProviderMetadata ? textToolOutput(modelOutput,
|
|
683
|
+
let content = message.role === "tool" && !preserveProviderMetadata && modelOutput !== void 0 ? textToolOutput(modelOutput, "") : message.content;
|
|
629
684
|
if (preserveProviderMetadata && modelOutput)
|
|
630
685
|
rest.modelOutput = modelOutput;
|
|
631
686
|
if (message.role === "assistant" && Array.isArray(message.tool_calls) && message.tool_calls.length > 0 && content === "") {
|
|
@@ -728,17 +783,32 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
728
783
|
const seenCallIds = /* @__PURE__ */ new Set();
|
|
729
784
|
const toolCalls = Array.isArray(response?.output) ? response.output.filter((item) => item?.type === "function_call").map((item) => {
|
|
730
785
|
if (typeof item.call_id !== "string" || !item.call_id || typeof item.name !== "string" || !item.name || typeof item.arguments !== "string" || item.status && item.status !== "completed") {
|
|
731
|
-
throw
|
|
786
|
+
throw invalidProviderResponse(
|
|
787
|
+
"Responses contains an incomplete function call"
|
|
788
|
+
);
|
|
732
789
|
}
|
|
733
790
|
if (seenCallIds.has(item.call_id))
|
|
734
|
-
throw
|
|
791
|
+
throw invalidProviderResponse(
|
|
792
|
+
"Responses contains duplicate function call IDs"
|
|
793
|
+
);
|
|
735
794
|
seenCallIds.add(item.call_id);
|
|
736
|
-
|
|
795
|
+
let args;
|
|
796
|
+
try {
|
|
797
|
+
args = JSON.parse(item.arguments);
|
|
798
|
+
} catch {
|
|
799
|
+
throw invalidProviderResponse(
|
|
800
|
+
"Responses function arguments must be valid JSON"
|
|
801
|
+
);
|
|
802
|
+
}
|
|
737
803
|
if (!args || typeof args !== "object" || Array.isArray(args))
|
|
738
|
-
throw
|
|
804
|
+
throw invalidProviderResponse(
|
|
739
805
|
"Responses function arguments must be a JSON object"
|
|
740
806
|
);
|
|
741
|
-
return {
|
|
807
|
+
return {
|
|
808
|
+
id: item.call_id,
|
|
809
|
+
name: item.name,
|
|
810
|
+
args
|
|
811
|
+
};
|
|
742
812
|
}) : [];
|
|
743
813
|
return {
|
|
744
814
|
content,
|
|
@@ -981,7 +1051,9 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
981
1051
|
const uniqueCalls = /* @__PURE__ */ new Map();
|
|
982
1052
|
for (const call of toolCalls.values()) {
|
|
983
1053
|
if (!call.id || !call.name)
|
|
984
|
-
throw
|
|
1054
|
+
throw invalidProviderResponse(
|
|
1055
|
+
"Responses stream contains an incomplete tool call"
|
|
1056
|
+
);
|
|
985
1057
|
uniqueCalls.set(call.id, call);
|
|
986
1058
|
}
|
|
987
1059
|
toolCalls.clear();
|
|
@@ -199,6 +199,54 @@ function responseMetadata(response) {
|
|
|
199
199
|
}
|
|
200
200
|
};
|
|
201
201
|
}
|
|
202
|
+
function responseReplayMetadata(metadata) {
|
|
203
|
+
const response = metadata?.openai?.response;
|
|
204
|
+
if (!response) return metadata;
|
|
205
|
+
const output = response.output.map((item) => {
|
|
206
|
+
const fields = ["type", "id", "status"];
|
|
207
|
+
switch (item.type) {
|
|
208
|
+
case "reasoning":
|
|
209
|
+
fields.push("encrypted_content");
|
|
210
|
+
break;
|
|
211
|
+
case "message":
|
|
212
|
+
fields.push("role", "phase");
|
|
213
|
+
break;
|
|
214
|
+
case "function_call":
|
|
215
|
+
fields.push("call_id", "name", "namespace", "arguments");
|
|
216
|
+
break;
|
|
217
|
+
case "tool_search_call":
|
|
218
|
+
fields.push("call_id", "execution", "arguments");
|
|
219
|
+
break;
|
|
220
|
+
case "tool_search_output":
|
|
221
|
+
fields.push("call_id", "tools");
|
|
222
|
+
break;
|
|
223
|
+
case "web_search_call":
|
|
224
|
+
fields.push("action");
|
|
225
|
+
break;
|
|
226
|
+
default:
|
|
227
|
+
return stripItemDiagnostics(item);
|
|
228
|
+
}
|
|
229
|
+
const replay = Object.fromEntries(
|
|
230
|
+
fields.filter((key) => item[key] !== void 0).map((key) => [key, item[key]])
|
|
231
|
+
);
|
|
232
|
+
if (item.type === "reasoning") replay.summary = [];
|
|
233
|
+
if (item.type === "message")
|
|
234
|
+
replay.content = Array.isArray(item.content) ? item.content.flatMap(
|
|
235
|
+
(part) => part?.type === "output_text" && typeof part.text === "string" ? [{ type: "output_text", text: part.text, annotations: [] }] : part?.type === "refusal" && typeof part.refusal === "string" ? [{ type: "refusal", refusal: part.refusal }] : []
|
|
236
|
+
) : [];
|
|
237
|
+
return stripItemDiagnostics(replay);
|
|
238
|
+
});
|
|
239
|
+
return { openai: { response: { output, refusals: [] } } };
|
|
240
|
+
}
|
|
241
|
+
function stripItemDiagnostics(item) {
|
|
242
|
+
const {
|
|
243
|
+
usage: _usage,
|
|
244
|
+
logprobs: _logprobs,
|
|
245
|
+
metadata: _metadata,
|
|
246
|
+
...state
|
|
247
|
+
} = item;
|
|
248
|
+
return state;
|
|
249
|
+
}
|
|
202
250
|
function getResponseReplay(metadata) {
|
|
203
251
|
const response = metadata?.openai?.response;
|
|
204
252
|
if (response === void 0) return void 0;
|
|
@@ -207,10 +255,17 @@ function getResponseReplay(metadata) {
|
|
|
207
255
|
"Invalid OpenAI Responses replay metadata: output must contain typed items"
|
|
208
256
|
);
|
|
209
257
|
}
|
|
210
|
-
return response
|
|
258
|
+
return responseReplayMetadata(metadata)?.openai?.response?.output;
|
|
211
259
|
}
|
|
212
260
|
|
|
213
261
|
// src/core/provider-error.ts
|
|
262
|
+
function invalidProviderResponse(message) {
|
|
263
|
+
return Object.assign(new Error(message), {
|
|
264
|
+
name: "InvalidProviderResponseError",
|
|
265
|
+
status: 502,
|
|
266
|
+
code: "INVALID_PROVIDER_RESPONSE"
|
|
267
|
+
});
|
|
268
|
+
}
|
|
214
269
|
function providerErrorEvent(error, code) {
|
|
215
270
|
const details = error ?? {};
|
|
216
271
|
const event = {
|
|
@@ -623,7 +678,7 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
623
678
|
formatRawMessages(messages, preserveProviderMetadata = false) {
|
|
624
679
|
return messages.map((message) => {
|
|
625
680
|
const { attachments, providerMetadata, modelOutput, ...rest } = message;
|
|
626
|
-
let content = message.role === "tool" && !preserveProviderMetadata ? textToolOutput(modelOutput,
|
|
681
|
+
let content = message.role === "tool" && !preserveProviderMetadata && modelOutput !== void 0 ? textToolOutput(modelOutput, "") : message.content;
|
|
627
682
|
if (preserveProviderMetadata && modelOutput)
|
|
628
683
|
rest.modelOutput = modelOutput;
|
|
629
684
|
if (message.role === "assistant" && Array.isArray(message.tool_calls) && message.tool_calls.length > 0 && content === "") {
|
|
@@ -726,17 +781,32 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
726
781
|
const seenCallIds = /* @__PURE__ */ new Set();
|
|
727
782
|
const toolCalls = Array.isArray(response?.output) ? response.output.filter((item) => item?.type === "function_call").map((item) => {
|
|
728
783
|
if (typeof item.call_id !== "string" || !item.call_id || typeof item.name !== "string" || !item.name || typeof item.arguments !== "string" || item.status && item.status !== "completed") {
|
|
729
|
-
throw
|
|
784
|
+
throw invalidProviderResponse(
|
|
785
|
+
"Responses contains an incomplete function call"
|
|
786
|
+
);
|
|
730
787
|
}
|
|
731
788
|
if (seenCallIds.has(item.call_id))
|
|
732
|
-
throw
|
|
789
|
+
throw invalidProviderResponse(
|
|
790
|
+
"Responses contains duplicate function call IDs"
|
|
791
|
+
);
|
|
733
792
|
seenCallIds.add(item.call_id);
|
|
734
|
-
|
|
793
|
+
let args;
|
|
794
|
+
try {
|
|
795
|
+
args = JSON.parse(item.arguments);
|
|
796
|
+
} catch {
|
|
797
|
+
throw invalidProviderResponse(
|
|
798
|
+
"Responses function arguments must be valid JSON"
|
|
799
|
+
);
|
|
800
|
+
}
|
|
735
801
|
if (!args || typeof args !== "object" || Array.isArray(args))
|
|
736
|
-
throw
|
|
802
|
+
throw invalidProviderResponse(
|
|
737
803
|
"Responses function arguments must be a JSON object"
|
|
738
804
|
);
|
|
739
|
-
return {
|
|
805
|
+
return {
|
|
806
|
+
id: item.call_id,
|
|
807
|
+
name: item.name,
|
|
808
|
+
args
|
|
809
|
+
};
|
|
740
810
|
}) : [];
|
|
741
811
|
return {
|
|
742
812
|
content,
|
|
@@ -979,7 +1049,9 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
979
1049
|
const uniqueCalls = /* @__PURE__ */ new Map();
|
|
980
1050
|
for (const call of toolCalls.values()) {
|
|
981
1051
|
if (!call.id || !call.name)
|
|
982
|
-
throw
|
|
1052
|
+
throw invalidProviderResponse(
|
|
1053
|
+
"Responses stream contains an incomplete tool call"
|
|
1054
|
+
);
|
|
983
1055
|
uniqueCalls.set(call.id, call);
|
|
984
1056
|
}
|
|
985
1057
|
toolCalls.clear();
|
|
@@ -688,6 +688,54 @@ function responseMetadata(response) {
|
|
|
688
688
|
}
|
|
689
689
|
};
|
|
690
690
|
}
|
|
691
|
+
function responseReplayMetadata(metadata) {
|
|
692
|
+
const response = metadata?.openai?.response;
|
|
693
|
+
if (!response) return metadata;
|
|
694
|
+
const output = response.output.map((item) => {
|
|
695
|
+
const fields = ["type", "id", "status"];
|
|
696
|
+
switch (item.type) {
|
|
697
|
+
case "reasoning":
|
|
698
|
+
fields.push("encrypted_content");
|
|
699
|
+
break;
|
|
700
|
+
case "message":
|
|
701
|
+
fields.push("role", "phase");
|
|
702
|
+
break;
|
|
703
|
+
case "function_call":
|
|
704
|
+
fields.push("call_id", "name", "namespace", "arguments");
|
|
705
|
+
break;
|
|
706
|
+
case "tool_search_call":
|
|
707
|
+
fields.push("call_id", "execution", "arguments");
|
|
708
|
+
break;
|
|
709
|
+
case "tool_search_output":
|
|
710
|
+
fields.push("call_id", "tools");
|
|
711
|
+
break;
|
|
712
|
+
case "web_search_call":
|
|
713
|
+
fields.push("action");
|
|
714
|
+
break;
|
|
715
|
+
default:
|
|
716
|
+
return stripItemDiagnostics(item);
|
|
717
|
+
}
|
|
718
|
+
const replay = Object.fromEntries(
|
|
719
|
+
fields.filter((key) => item[key] !== void 0).map((key) => [key, item[key]])
|
|
720
|
+
);
|
|
721
|
+
if (item.type === "reasoning") replay.summary = [];
|
|
722
|
+
if (item.type === "message")
|
|
723
|
+
replay.content = Array.isArray(item.content) ? item.content.flatMap(
|
|
724
|
+
(part) => part?.type === "output_text" && typeof part.text === "string" ? [{ type: "output_text", text: part.text, annotations: [] }] : part?.type === "refusal" && typeof part.refusal === "string" ? [{ type: "refusal", refusal: part.refusal }] : []
|
|
725
|
+
) : [];
|
|
726
|
+
return stripItemDiagnostics(replay);
|
|
727
|
+
});
|
|
728
|
+
return { openai: { response: { output, refusals: [] } } };
|
|
729
|
+
}
|
|
730
|
+
function stripItemDiagnostics(item) {
|
|
731
|
+
const {
|
|
732
|
+
usage: _usage,
|
|
733
|
+
logprobs: _logprobs,
|
|
734
|
+
metadata: _metadata,
|
|
735
|
+
...state
|
|
736
|
+
} = item;
|
|
737
|
+
return state;
|
|
738
|
+
}
|
|
691
739
|
function getResponseReplay(metadata) {
|
|
692
740
|
const response = metadata?.openai?.response;
|
|
693
741
|
if (response === void 0) return void 0;
|
|
@@ -696,10 +744,17 @@ function getResponseReplay(metadata) {
|
|
|
696
744
|
"Invalid OpenAI Responses replay metadata: output must contain typed items"
|
|
697
745
|
);
|
|
698
746
|
}
|
|
699
|
-
return response
|
|
747
|
+
return responseReplayMetadata(metadata)?.openai?.response?.output;
|
|
700
748
|
}
|
|
701
749
|
|
|
702
750
|
// src/core/provider-error.ts
|
|
751
|
+
function invalidProviderResponse(message) {
|
|
752
|
+
return Object.assign(new Error(message), {
|
|
753
|
+
name: "InvalidProviderResponseError",
|
|
754
|
+
status: 502,
|
|
755
|
+
code: "INVALID_PROVIDER_RESPONSE"
|
|
756
|
+
});
|
|
757
|
+
}
|
|
703
758
|
function providerErrorEvent(error, code) {
|
|
704
759
|
const details = error ?? {};
|
|
705
760
|
const event = {
|
|
@@ -876,7 +931,7 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
876
931
|
formatRawMessages(messages, preserveProviderMetadata = false) {
|
|
877
932
|
return messages.map((message) => {
|
|
878
933
|
const { attachments, providerMetadata, modelOutput, ...rest } = message;
|
|
879
|
-
let content = message.role === "tool" && !preserveProviderMetadata ? textToolOutput(modelOutput,
|
|
934
|
+
let content = message.role === "tool" && !preserveProviderMetadata && modelOutput !== void 0 ? textToolOutput(modelOutput, "") : message.content;
|
|
880
935
|
if (preserveProviderMetadata && modelOutput)
|
|
881
936
|
rest.modelOutput = modelOutput;
|
|
882
937
|
if (message.role === "assistant" && Array.isArray(message.tool_calls) && message.tool_calls.length > 0 && content === "") {
|
|
@@ -979,17 +1034,32 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
979
1034
|
const seenCallIds = /* @__PURE__ */ new Set();
|
|
980
1035
|
const toolCalls = Array.isArray(response?.output) ? response.output.filter((item) => item?.type === "function_call").map((item) => {
|
|
981
1036
|
if (typeof item.call_id !== "string" || !item.call_id || typeof item.name !== "string" || !item.name || typeof item.arguments !== "string" || item.status && item.status !== "completed") {
|
|
982
|
-
throw
|
|
1037
|
+
throw invalidProviderResponse(
|
|
1038
|
+
"Responses contains an incomplete function call"
|
|
1039
|
+
);
|
|
983
1040
|
}
|
|
984
1041
|
if (seenCallIds.has(item.call_id))
|
|
985
|
-
throw
|
|
1042
|
+
throw invalidProviderResponse(
|
|
1043
|
+
"Responses contains duplicate function call IDs"
|
|
1044
|
+
);
|
|
986
1045
|
seenCallIds.add(item.call_id);
|
|
987
|
-
|
|
1046
|
+
let args;
|
|
1047
|
+
try {
|
|
1048
|
+
args = JSON.parse(item.arguments);
|
|
1049
|
+
} catch {
|
|
1050
|
+
throw invalidProviderResponse(
|
|
1051
|
+
"Responses function arguments must be valid JSON"
|
|
1052
|
+
);
|
|
1053
|
+
}
|
|
988
1054
|
if (!args || typeof args !== "object" || Array.isArray(args))
|
|
989
|
-
throw
|
|
1055
|
+
throw invalidProviderResponse(
|
|
990
1056
|
"Responses function arguments must be a JSON object"
|
|
991
1057
|
);
|
|
992
|
-
return {
|
|
1058
|
+
return {
|
|
1059
|
+
id: item.call_id,
|
|
1060
|
+
name: item.name,
|
|
1061
|
+
args
|
|
1062
|
+
};
|
|
993
1063
|
}) : [];
|
|
994
1064
|
return {
|
|
995
1065
|
content,
|
|
@@ -1232,7 +1302,9 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
1232
1302
|
const uniqueCalls = /* @__PURE__ */ new Map();
|
|
1233
1303
|
for (const call of toolCalls.values()) {
|
|
1234
1304
|
if (!call.id || !call.name)
|
|
1235
|
-
throw
|
|
1305
|
+
throw invalidProviderResponse(
|
|
1306
|
+
"Responses stream contains an incomplete tool call"
|
|
1307
|
+
);
|
|
1236
1308
|
uniqueCalls.set(call.id, call);
|
|
1237
1309
|
}
|
|
1238
1310
|
toolCalls.clear();
|
|
@@ -686,6 +686,54 @@ function responseMetadata(response) {
|
|
|
686
686
|
}
|
|
687
687
|
};
|
|
688
688
|
}
|
|
689
|
+
function responseReplayMetadata(metadata) {
|
|
690
|
+
const response = metadata?.openai?.response;
|
|
691
|
+
if (!response) return metadata;
|
|
692
|
+
const output = response.output.map((item) => {
|
|
693
|
+
const fields = ["type", "id", "status"];
|
|
694
|
+
switch (item.type) {
|
|
695
|
+
case "reasoning":
|
|
696
|
+
fields.push("encrypted_content");
|
|
697
|
+
break;
|
|
698
|
+
case "message":
|
|
699
|
+
fields.push("role", "phase");
|
|
700
|
+
break;
|
|
701
|
+
case "function_call":
|
|
702
|
+
fields.push("call_id", "name", "namespace", "arguments");
|
|
703
|
+
break;
|
|
704
|
+
case "tool_search_call":
|
|
705
|
+
fields.push("call_id", "execution", "arguments");
|
|
706
|
+
break;
|
|
707
|
+
case "tool_search_output":
|
|
708
|
+
fields.push("call_id", "tools");
|
|
709
|
+
break;
|
|
710
|
+
case "web_search_call":
|
|
711
|
+
fields.push("action");
|
|
712
|
+
break;
|
|
713
|
+
default:
|
|
714
|
+
return stripItemDiagnostics(item);
|
|
715
|
+
}
|
|
716
|
+
const replay = Object.fromEntries(
|
|
717
|
+
fields.filter((key) => item[key] !== void 0).map((key) => [key, item[key]])
|
|
718
|
+
);
|
|
719
|
+
if (item.type === "reasoning") replay.summary = [];
|
|
720
|
+
if (item.type === "message")
|
|
721
|
+
replay.content = Array.isArray(item.content) ? item.content.flatMap(
|
|
722
|
+
(part) => part?.type === "output_text" && typeof part.text === "string" ? [{ type: "output_text", text: part.text, annotations: [] }] : part?.type === "refusal" && typeof part.refusal === "string" ? [{ type: "refusal", refusal: part.refusal }] : []
|
|
723
|
+
) : [];
|
|
724
|
+
return stripItemDiagnostics(replay);
|
|
725
|
+
});
|
|
726
|
+
return { openai: { response: { output, refusals: [] } } };
|
|
727
|
+
}
|
|
728
|
+
function stripItemDiagnostics(item) {
|
|
729
|
+
const {
|
|
730
|
+
usage: _usage,
|
|
731
|
+
logprobs: _logprobs,
|
|
732
|
+
metadata: _metadata,
|
|
733
|
+
...state
|
|
734
|
+
} = item;
|
|
735
|
+
return state;
|
|
736
|
+
}
|
|
689
737
|
function getResponseReplay(metadata) {
|
|
690
738
|
const response = metadata?.openai?.response;
|
|
691
739
|
if (response === void 0) return void 0;
|
|
@@ -694,10 +742,17 @@ function getResponseReplay(metadata) {
|
|
|
694
742
|
"Invalid OpenAI Responses replay metadata: output must contain typed items"
|
|
695
743
|
);
|
|
696
744
|
}
|
|
697
|
-
return response
|
|
745
|
+
return responseReplayMetadata(metadata)?.openai?.response?.output;
|
|
698
746
|
}
|
|
699
747
|
|
|
700
748
|
// src/core/provider-error.ts
|
|
749
|
+
function invalidProviderResponse(message) {
|
|
750
|
+
return Object.assign(new Error(message), {
|
|
751
|
+
name: "InvalidProviderResponseError",
|
|
752
|
+
status: 502,
|
|
753
|
+
code: "INVALID_PROVIDER_RESPONSE"
|
|
754
|
+
});
|
|
755
|
+
}
|
|
701
756
|
function providerErrorEvent(error, code) {
|
|
702
757
|
const details = error ?? {};
|
|
703
758
|
const event = {
|
|
@@ -874,7 +929,7 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
874
929
|
formatRawMessages(messages, preserveProviderMetadata = false) {
|
|
875
930
|
return messages.map((message) => {
|
|
876
931
|
const { attachments, providerMetadata, modelOutput, ...rest } = message;
|
|
877
|
-
let content = message.role === "tool" && !preserveProviderMetadata ? textToolOutput(modelOutput,
|
|
932
|
+
let content = message.role === "tool" && !preserveProviderMetadata && modelOutput !== void 0 ? textToolOutput(modelOutput, "") : message.content;
|
|
878
933
|
if (preserveProviderMetadata && modelOutput)
|
|
879
934
|
rest.modelOutput = modelOutput;
|
|
880
935
|
if (message.role === "assistant" && Array.isArray(message.tool_calls) && message.tool_calls.length > 0 && content === "") {
|
|
@@ -977,17 +1032,32 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
977
1032
|
const seenCallIds = /* @__PURE__ */ new Set();
|
|
978
1033
|
const toolCalls = Array.isArray(response?.output) ? response.output.filter((item) => item?.type === "function_call").map((item) => {
|
|
979
1034
|
if (typeof item.call_id !== "string" || !item.call_id || typeof item.name !== "string" || !item.name || typeof item.arguments !== "string" || item.status && item.status !== "completed") {
|
|
980
|
-
throw
|
|
1035
|
+
throw invalidProviderResponse(
|
|
1036
|
+
"Responses contains an incomplete function call"
|
|
1037
|
+
);
|
|
981
1038
|
}
|
|
982
1039
|
if (seenCallIds.has(item.call_id))
|
|
983
|
-
throw
|
|
1040
|
+
throw invalidProviderResponse(
|
|
1041
|
+
"Responses contains duplicate function call IDs"
|
|
1042
|
+
);
|
|
984
1043
|
seenCallIds.add(item.call_id);
|
|
985
|
-
|
|
1044
|
+
let args;
|
|
1045
|
+
try {
|
|
1046
|
+
args = JSON.parse(item.arguments);
|
|
1047
|
+
} catch {
|
|
1048
|
+
throw invalidProviderResponse(
|
|
1049
|
+
"Responses function arguments must be valid JSON"
|
|
1050
|
+
);
|
|
1051
|
+
}
|
|
986
1052
|
if (!args || typeof args !== "object" || Array.isArray(args))
|
|
987
|
-
throw
|
|
1053
|
+
throw invalidProviderResponse(
|
|
988
1054
|
"Responses function arguments must be a JSON object"
|
|
989
1055
|
);
|
|
990
|
-
return {
|
|
1056
|
+
return {
|
|
1057
|
+
id: item.call_id,
|
|
1058
|
+
name: item.name,
|
|
1059
|
+
args
|
|
1060
|
+
};
|
|
991
1061
|
}) : [];
|
|
992
1062
|
return {
|
|
993
1063
|
content,
|
|
@@ -1230,7 +1300,9 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
1230
1300
|
const uniqueCalls = /* @__PURE__ */ new Map();
|
|
1231
1301
|
for (const call of toolCalls.values()) {
|
|
1232
1302
|
if (!call.id || !call.name)
|
|
1233
|
-
throw
|
|
1303
|
+
throw invalidProviderResponse(
|
|
1304
|
+
"Responses stream contains an incomplete tool call"
|
|
1305
|
+
);
|
|
1234
1306
|
uniqueCalls.set(call.id, call);
|
|
1235
1307
|
}
|
|
1236
1308
|
toolCalls.clear();
|