@yourgpt/llm-sdk 2.6.0-beta.2 → 2.6.0
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/LICENSE +21 -0
- package/README.md +87 -17
- package/dist/adapters/index.d.mts +11 -13
- package/dist/adapters/index.d.ts +11 -13
- package/dist/adapters/index.js +406 -114
- package/dist/adapters/index.mjs +406 -114
- package/dist/audio-K-Z3-Bce.d.mts +191 -0
- package/dist/audio-K-Z3-Bce.d.ts +191 -0
- package/dist/{base-BICaQaRS.d.mts → base-6LzczuCg.d.ts} +8 -1
- package/dist/{base-CpRPB8u8.d.ts → base-DySbTP8C.d.mts} +8 -1
- package/dist/decisions-CJzOt87t.d.mts +137 -0
- package/dist/decisions-CJzOt87t.d.ts +137 -0
- package/dist/fallback/index.d.mts +4 -4
- package/dist/fallback/index.d.ts +4 -4
- package/dist/http-BQxUT5A9.d.mts +9 -0
- package/dist/http-BQxUT5A9.d.ts +9 -0
- package/dist/index.d.mts +17 -9
- package/dist/index.d.ts +17 -9
- package/dist/index.js +698 -205
- package/dist/index.mjs +695 -206
- package/dist/providers/anthropic/index.d.mts +7 -4
- package/dist/providers/anthropic/index.d.ts +7 -4
- package/dist/providers/anthropic/index.js +389 -115
- package/dist/providers/anthropic/index.mjs +389 -115
- package/dist/providers/azure/index.d.mts +3 -3
- package/dist/providers/azure/index.d.ts +3 -3
- package/dist/providers/cloudflare/index.d.mts +11 -0
- package/dist/providers/cloudflare/index.d.ts +11 -0
- package/dist/providers/cloudflare/index.js +743 -0
- package/dist/providers/cloudflare/index.mjs +741 -0
- package/dist/providers/fireworks/index.d.mts +3 -3
- package/dist/providers/fireworks/index.d.ts +3 -3
- package/dist/providers/fireworks/index.js +181 -60
- package/dist/providers/fireworks/index.mjs +181 -60
- package/dist/providers/google/index.d.mts +3 -3
- package/dist/providers/google/index.d.ts +3 -3
- package/dist/providers/google/index.js +181 -60
- package/dist/providers/google/index.mjs +181 -60
- package/dist/providers/ollama/index.d.mts +4 -4
- package/dist/providers/ollama/index.d.ts +4 -4
- package/dist/providers/openai/index.d.mts +38 -6
- package/dist/providers/openai/index.d.ts +38 -6
- package/dist/providers/openai/index.js +1451 -85
- package/dist/providers/openai/index.mjs +1449 -86
- package/dist/providers/openrouter/index.d.mts +21 -4
- package/dist/providers/openrouter/index.d.ts +21 -4
- package/dist/providers/openrouter/index.js +1040 -131
- package/dist/providers/openrouter/index.mjs +1040 -132
- package/dist/providers/togetherai/index.d.mts +3 -3
- package/dist/providers/togetherai/index.d.ts +3 -3
- package/dist/providers/togetherai/index.js +181 -60
- package/dist/providers/togetherai/index.mjs +181 -60
- package/dist/providers/typesafe/index.d.mts +8 -0
- package/dist/providers/typesafe/index.d.ts +8 -0
- package/dist/providers/typesafe/index.js +735 -0
- package/dist/providers/typesafe/index.mjs +733 -0
- package/dist/providers/xai/index.d.mts +3 -3
- package/dist/providers/xai/index.d.ts +3 -3
- package/dist/providers/xai/index.js +181 -60
- package/dist/providers/xai/index.mjs +181 -60
- package/dist/{types-DCFqkJAy.d.ts → types-B0y6VZSQ.d.ts} +1 -1
- package/dist/{types-DHQEMFHA.d.mts → types-BXQMtaCX.d.ts} +17 -3
- package/dist/{types-C3RgRbEC.d.mts → types-BY6BVhFg.d.mts} +1 -1
- package/dist/{types-Dikj3En4.d.ts → types-C7_qVSSd.d.mts} +17 -3
- package/dist/{types-Dg1Bcg1k.d.mts → types-D7lzMMLu.d.mts} +13 -1
- package/dist/{types-Dg1Bcg1k.d.ts → types-D7lzMMLu.d.ts} +13 -1
- package/dist/yourgpt/index.d.mts +1 -1
- package/dist/yourgpt/index.d.ts +1 -1
- package/docs/decisions.md +174 -0
- package/docs/media.md +201 -0
- package/docs/multimodal-and-audio.md +9 -2
- package/package.json +34 -12
- package/dist/audio-BBSwnjo8.d.mts +0 -92
- package/dist/audio-BBSwnjo8.d.ts +0 -92
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { L as LanguageModel } from '../../types-
|
|
2
|
-
import { A as AIProvider } from '../../types-
|
|
1
|
+
import { L as LanguageModel } from '../../types-D7lzMMLu.mjs';
|
|
2
|
+
import { A as AIProvider } from '../../types-C7_qVSSd.mjs';
|
|
3
3
|
import 'zod';
|
|
4
|
-
import '../../base-
|
|
4
|
+
import '../../base-DySbTP8C.mjs';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Together AI Provider
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { L as LanguageModel } from '../../types-
|
|
2
|
-
import { A as AIProvider } from '../../types-
|
|
1
|
+
import { L as LanguageModel } from '../../types-D7lzMMLu.js';
|
|
2
|
+
import { A as AIProvider } from '../../types-BXQMtaCX.js';
|
|
3
3
|
import 'zod';
|
|
4
|
-
import '../../base-
|
|
4
|
+
import '../../base-6LzczuCg.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Together AI Provider
|
|
@@ -113,6 +113,19 @@ function capabilities(model) {
|
|
|
113
113
|
const supportsNone = major === 5 && minor >= 1 && !chat || /^gpt-6-(?:sol|luna)(?:-\d{4}-\d{2}-\d{2})?$/i.test(model);
|
|
114
114
|
return { major, minor, reasoning, supportsNone };
|
|
115
115
|
}
|
|
116
|
+
function filterOpenAIResponseInclude(model, include, options = {}) {
|
|
117
|
+
const c = capabilities(model);
|
|
118
|
+
let result = include;
|
|
119
|
+
if (options.parameterPolicy !== "passthrough" && c.reasoning && !(options.reasoningEffort === "none" && c.supportsNone) && include.includes("message.output_text.logprobs")) {
|
|
120
|
+
result = include.filter(
|
|
121
|
+
(value) => value !== "message.output_text.logprobs"
|
|
122
|
+
);
|
|
123
|
+
(options.onWarning ?? console.warn)(
|
|
124
|
+
`[llm-sdk] ${model}: omitted message.output_text.logprobs because reasoning is enabled.`
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
return result.length ? result : void 0;
|
|
128
|
+
}
|
|
116
129
|
function requiresOpenAIResponses(model, baseUrl, options = {}) {
|
|
117
130
|
if (options.parameterPolicy === "passthrough") return false;
|
|
118
131
|
const c = capabilities(model);
|
|
@@ -274,6 +287,7 @@ function toOpenAIResponseFormat(rf) {
|
|
|
274
287
|
};
|
|
275
288
|
}
|
|
276
289
|
function toOpenAIResponsesTextFormat(rf) {
|
|
290
|
+
if (rf?.type === "json_object") return { type: "json_object" };
|
|
277
291
|
if (!rf || rf.type !== "json_schema") return void 0;
|
|
278
292
|
return {
|
|
279
293
|
type: "json_schema",
|
|
@@ -593,6 +607,63 @@ function formatMessages(messages) {
|
|
|
593
607
|
});
|
|
594
608
|
}
|
|
595
609
|
|
|
610
|
+
// src/core/provider-error.ts
|
|
611
|
+
function invalidProviderResponse(message) {
|
|
612
|
+
return Object.assign(new Error(message), {
|
|
613
|
+
name: "InvalidProviderResponseError",
|
|
614
|
+
status: 502,
|
|
615
|
+
code: "INVALID_PROVIDER_RESPONSE"
|
|
616
|
+
});
|
|
617
|
+
}
|
|
618
|
+
function providerErrorEvent(error, code) {
|
|
619
|
+
const details = error ?? {};
|
|
620
|
+
const event = {
|
|
621
|
+
type: "error",
|
|
622
|
+
message: error instanceof Error ? error.message : String(error),
|
|
623
|
+
code,
|
|
624
|
+
...typeof details.status === "number" ? { status: details.status } : {},
|
|
625
|
+
...typeof details.code === "string" ? { providerCode: details.code } : {},
|
|
626
|
+
...typeof details.param === "string" ? { param: details.param } : {},
|
|
627
|
+
...typeof details.request_id === "string" ? { requestId: details.request_id } : {}
|
|
628
|
+
};
|
|
629
|
+
Object.defineProperty(event, "cause", { value: error, enumerable: false });
|
|
630
|
+
return event;
|
|
631
|
+
}
|
|
632
|
+
function throwIfAborted(signal) {
|
|
633
|
+
if (!signal?.aborted) return;
|
|
634
|
+
const error = new Error("The operation was aborted");
|
|
635
|
+
error.name = "AbortError";
|
|
636
|
+
throw error;
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
// src/core/tool-validation.ts
|
|
640
|
+
function parseToolArguments(value) {
|
|
641
|
+
let args = value;
|
|
642
|
+
if (typeof value === "string") {
|
|
643
|
+
try {
|
|
644
|
+
args = JSON.parse(value || "{}");
|
|
645
|
+
} catch {
|
|
646
|
+
throw invalidProviderResponse("Tool arguments are not valid JSON");
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
if (args === null || typeof args !== "object" || Array.isArray(args))
|
|
650
|
+
throw invalidProviderResponse("Tool arguments must be a JSON object");
|
|
651
|
+
return args;
|
|
652
|
+
}
|
|
653
|
+
function validateToolCalls(calls) {
|
|
654
|
+
const ids = /* @__PURE__ */ new Set();
|
|
655
|
+
for (const call of calls) {
|
|
656
|
+
if (!call || typeof call.id !== "string" || !call.id || typeof call.name !== "string" || !call.name || ids.has(call.id))
|
|
657
|
+
throw invalidProviderResponse(
|
|
658
|
+
"Tool calls have missing or duplicate identities"
|
|
659
|
+
);
|
|
660
|
+
ids.add(call.id);
|
|
661
|
+
if (typeof call.args === "string")
|
|
662
|
+
throw invalidProviderResponse("Parsed tool arguments must be an object");
|
|
663
|
+
parseToolArguments(call.args);
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
|
|
596
667
|
// src/core/openai-responses.ts
|
|
597
668
|
function resolveOpenAITransport(defaults, overrides) {
|
|
598
669
|
return {
|
|
@@ -640,6 +711,54 @@ function responseMetadata(response) {
|
|
|
640
711
|
}
|
|
641
712
|
};
|
|
642
713
|
}
|
|
714
|
+
function responseReplayMetadata(metadata) {
|
|
715
|
+
const response = metadata?.openai?.response;
|
|
716
|
+
if (!response) return metadata;
|
|
717
|
+
const output = response.output.map((item) => {
|
|
718
|
+
const fields = ["type", "id", "status"];
|
|
719
|
+
switch (item.type) {
|
|
720
|
+
case "reasoning":
|
|
721
|
+
fields.push("encrypted_content");
|
|
722
|
+
break;
|
|
723
|
+
case "message":
|
|
724
|
+
fields.push("role", "phase");
|
|
725
|
+
break;
|
|
726
|
+
case "function_call":
|
|
727
|
+
fields.push("call_id", "name", "namespace", "arguments");
|
|
728
|
+
break;
|
|
729
|
+
case "tool_search_call":
|
|
730
|
+
fields.push("call_id", "execution", "arguments");
|
|
731
|
+
break;
|
|
732
|
+
case "tool_search_output":
|
|
733
|
+
fields.push("call_id", "tools");
|
|
734
|
+
break;
|
|
735
|
+
case "web_search_call":
|
|
736
|
+
fields.push("action");
|
|
737
|
+
break;
|
|
738
|
+
default:
|
|
739
|
+
return stripItemDiagnostics(item);
|
|
740
|
+
}
|
|
741
|
+
const replay = Object.fromEntries(
|
|
742
|
+
fields.filter((key) => item[key] !== void 0).map((key) => [key, item[key]])
|
|
743
|
+
);
|
|
744
|
+
if (item.type === "reasoning") replay.summary = [];
|
|
745
|
+
if (item.type === "message")
|
|
746
|
+
replay.content = Array.isArray(item.content) ? item.content.flatMap(
|
|
747
|
+
(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 }] : []
|
|
748
|
+
) : [];
|
|
749
|
+
return stripItemDiagnostics(replay);
|
|
750
|
+
});
|
|
751
|
+
return { openai: { response: { output, refusals: [] } } };
|
|
752
|
+
}
|
|
753
|
+
function stripItemDiagnostics(item) {
|
|
754
|
+
const {
|
|
755
|
+
usage: _usage,
|
|
756
|
+
logprobs: _logprobs,
|
|
757
|
+
metadata: _metadata,
|
|
758
|
+
...state
|
|
759
|
+
} = item;
|
|
760
|
+
return state;
|
|
761
|
+
}
|
|
643
762
|
function getResponseReplay(metadata) {
|
|
644
763
|
const response = metadata?.openai?.response;
|
|
645
764
|
if (response === void 0) return void 0;
|
|
@@ -648,29 +767,7 @@ function getResponseReplay(metadata) {
|
|
|
648
767
|
"Invalid OpenAI Responses replay metadata: output must contain typed items"
|
|
649
768
|
);
|
|
650
769
|
}
|
|
651
|
-
return response
|
|
652
|
-
}
|
|
653
|
-
|
|
654
|
-
// src/core/provider-error.ts
|
|
655
|
-
function providerErrorEvent(error, code) {
|
|
656
|
-
const details = error ?? {};
|
|
657
|
-
const event = {
|
|
658
|
-
type: "error",
|
|
659
|
-
message: error instanceof Error ? error.message : String(error),
|
|
660
|
-
code,
|
|
661
|
-
...typeof details.status === "number" ? { status: details.status } : {},
|
|
662
|
-
...typeof details.code === "string" ? { providerCode: details.code } : {},
|
|
663
|
-
...typeof details.param === "string" ? { param: details.param } : {},
|
|
664
|
-
...typeof details.request_id === "string" ? { requestId: details.request_id } : {}
|
|
665
|
-
};
|
|
666
|
-
Object.defineProperty(event, "cause", { value: error, enumerable: false });
|
|
667
|
-
return event;
|
|
668
|
-
}
|
|
669
|
-
function throwIfAborted(signal) {
|
|
670
|
-
if (!signal?.aborted) return;
|
|
671
|
-
const error = new Error("The operation was aborted");
|
|
672
|
-
error.name = "AbortError";
|
|
673
|
-
throw error;
|
|
770
|
+
return responseReplayMetadata(metadata)?.openai?.response?.output;
|
|
674
771
|
}
|
|
675
772
|
|
|
676
773
|
// src/core/utils.ts
|
|
@@ -680,9 +777,6 @@ function generateId(prefix = "id") {
|
|
|
680
777
|
function generateMessageId() {
|
|
681
778
|
return generateId("msg");
|
|
682
779
|
}
|
|
683
|
-
function generateToolCallId() {
|
|
684
|
-
return generateId("call");
|
|
685
|
-
}
|
|
686
780
|
|
|
687
781
|
// src/adapters/openai.ts
|
|
688
782
|
var OpenAIAdapter = class _OpenAIAdapter {
|
|
@@ -706,6 +800,8 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
706
800
|
apiKey: this.config.apiKey,
|
|
707
801
|
baseURL: this.config.baseUrl,
|
|
708
802
|
organization: this.config.organization,
|
|
803
|
+
project: this.config.project,
|
|
804
|
+
timeout: this.config.timeout,
|
|
709
805
|
defaultHeaders: this.config.headers
|
|
710
806
|
});
|
|
711
807
|
}
|
|
@@ -828,7 +924,7 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
828
924
|
formatRawMessages(messages, preserveProviderMetadata = false) {
|
|
829
925
|
return messages.map((message) => {
|
|
830
926
|
const { attachments, providerMetadata, modelOutput, ...rest } = message;
|
|
831
|
-
let content = message.role === "tool" && !preserveProviderMetadata ? textToolOutput(modelOutput,
|
|
927
|
+
let content = message.role === "tool" && !preserveProviderMetadata && modelOutput !== void 0 ? textToolOutput(modelOutput, "") : message.content;
|
|
832
928
|
if (preserveProviderMetadata && modelOutput)
|
|
833
929
|
rest.modelOutput = modelOutput;
|
|
834
930
|
if (message.role === "assistant" && Array.isArray(message.tool_calls) && message.tool_calls.length > 0 && content === "") {
|
|
@@ -931,17 +1027,32 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
931
1027
|
const seenCallIds = /* @__PURE__ */ new Set();
|
|
932
1028
|
const toolCalls = Array.isArray(response?.output) ? response.output.filter((item) => item?.type === "function_call").map((item) => {
|
|
933
1029
|
if (typeof item.call_id !== "string" || !item.call_id || typeof item.name !== "string" || !item.name || typeof item.arguments !== "string" || item.status && item.status !== "completed") {
|
|
934
|
-
throw
|
|
1030
|
+
throw invalidProviderResponse(
|
|
1031
|
+
"Responses contains an incomplete function call"
|
|
1032
|
+
);
|
|
935
1033
|
}
|
|
936
1034
|
if (seenCallIds.has(item.call_id))
|
|
937
|
-
throw
|
|
1035
|
+
throw invalidProviderResponse(
|
|
1036
|
+
"Responses contains duplicate function call IDs"
|
|
1037
|
+
);
|
|
938
1038
|
seenCallIds.add(item.call_id);
|
|
939
|
-
|
|
1039
|
+
let args;
|
|
1040
|
+
try {
|
|
1041
|
+
args = JSON.parse(item.arguments);
|
|
1042
|
+
} catch {
|
|
1043
|
+
throw invalidProviderResponse(
|
|
1044
|
+
"Responses function arguments must be valid JSON"
|
|
1045
|
+
);
|
|
1046
|
+
}
|
|
940
1047
|
if (!args || typeof args !== "object" || Array.isArray(args))
|
|
941
|
-
throw
|
|
1048
|
+
throw invalidProviderResponse(
|
|
942
1049
|
"Responses function arguments must be a JSON object"
|
|
943
1050
|
);
|
|
944
|
-
return {
|
|
1051
|
+
return {
|
|
1052
|
+
id: item.call_id,
|
|
1053
|
+
name: item.name,
|
|
1054
|
+
args
|
|
1055
|
+
};
|
|
945
1056
|
}) : [];
|
|
946
1057
|
return {
|
|
947
1058
|
content,
|
|
@@ -972,6 +1083,16 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
972
1083
|
request.config?.responseFormat
|
|
973
1084
|
);
|
|
974
1085
|
const modelIdForPayload = request.config?.model || this.model;
|
|
1086
|
+
const include = filterOpenAIResponseInclude(
|
|
1087
|
+
modelIdForPayload,
|
|
1088
|
+
[
|
|
1089
|
+
.../* @__PURE__ */ new Set([
|
|
1090
|
+
...options?.include ?? [],
|
|
1091
|
+
...options?.store === false ? ["reasoning.encrypted_content"] : []
|
|
1092
|
+
])
|
|
1093
|
+
],
|
|
1094
|
+
this.parameterOptions(request)
|
|
1095
|
+
);
|
|
975
1096
|
const payload = {
|
|
976
1097
|
model: modelIdForPayload,
|
|
977
1098
|
instructions: request.systemPrompt,
|
|
@@ -995,14 +1116,7 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
995
1116
|
...options?.promptCacheKey !== void 0 ? { prompt_cache_key: options.promptCacheKey } : {},
|
|
996
1117
|
...options?.promptCacheOptions !== void 0 ? { prompt_cache_options: options.promptCacheOptions } : {},
|
|
997
1118
|
...options?.promptCacheRetention !== void 0 ? { prompt_cache_retention: options.promptCacheRetention } : {},
|
|
998
|
-
...
|
|
999
|
-
include: [
|
|
1000
|
-
.../* @__PURE__ */ new Set([
|
|
1001
|
-
...options?.include ?? [],
|
|
1002
|
-
...options?.store === false ? ["reasoning.encrypted_content"] : []
|
|
1003
|
-
])
|
|
1004
|
-
]
|
|
1005
|
-
} : {},
|
|
1119
|
+
...include ? { include } : {},
|
|
1006
1120
|
...responsesTextFormat ? { text: { format: responsesTextFormat } } : {},
|
|
1007
1121
|
stream
|
|
1008
1122
|
};
|
|
@@ -1184,7 +1298,9 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
1184
1298
|
const uniqueCalls = /* @__PURE__ */ new Map();
|
|
1185
1299
|
for (const call of toolCalls.values()) {
|
|
1186
1300
|
if (!call.id || !call.name)
|
|
1187
|
-
throw
|
|
1301
|
+
throw invalidProviderResponse(
|
|
1302
|
+
"Responses stream contains an incomplete tool call"
|
|
1303
|
+
);
|
|
1188
1304
|
uniqueCalls.set(call.id, call);
|
|
1189
1305
|
}
|
|
1190
1306
|
toolCalls.clear();
|
|
@@ -1371,15 +1487,20 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
1371
1487
|
}
|
|
1372
1488
|
throwIfAborted(request.signal);
|
|
1373
1489
|
if (!finishReason)
|
|
1374
|
-
throw
|
|
1490
|
+
throw invalidProviderResponse(
|
|
1491
|
+
"OpenAI stream ended without a finish reason"
|
|
1492
|
+
);
|
|
1375
1493
|
if (toolCalls.size && !["tool_calls", "function_call"].includes(finishReason)) {
|
|
1376
|
-
throw
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
if (!call.id || !call.name)
|
|
1380
|
-
throw new Error("OpenAI stream contains an incomplete tool call");
|
|
1381
|
-
JSON.parse(call.arguments || "{}");
|
|
1494
|
+
throw invalidProviderResponse(
|
|
1495
|
+
"OpenAI stream ended with incomplete tool calls"
|
|
1496
|
+
);
|
|
1382
1497
|
}
|
|
1498
|
+
validateToolCalls(
|
|
1499
|
+
[...toolCalls.values()].map((call) => ({
|
|
1500
|
+
...call,
|
|
1501
|
+
args: parseToolArguments(call.arguments)
|
|
1502
|
+
}))
|
|
1503
|
+
);
|
|
1383
1504
|
for (const call of toolCalls.values()) {
|
|
1384
1505
|
yield {
|
|
1385
1506
|
type: "action:start",
|
|
@@ -1463,20 +1584,20 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
1463
1584
|
logProviderPayload("openai", "response payload", response, request.debug);
|
|
1464
1585
|
const choice = response.choices?.[0];
|
|
1465
1586
|
const message = choice?.message;
|
|
1587
|
+
const toolCalls = (message?.tool_calls ?? []).map((toolCall) => ({
|
|
1588
|
+
id: toolCall.id,
|
|
1589
|
+
name: toolCall.function?.name,
|
|
1590
|
+
args: parseToolArguments(toolCall.function?.arguments ?? "{}"),
|
|
1591
|
+
...toolCall.extra_content ? { extra_content: toolCall.extra_content } : {}
|
|
1592
|
+
}));
|
|
1593
|
+
validateToolCalls(toolCalls);
|
|
1594
|
+
if (toolCalls.length && choice?.finish_reason && !["tool_calls", "function_call"].includes(choice.finish_reason))
|
|
1595
|
+
throw invalidProviderResponse(
|
|
1596
|
+
"OpenAI response ended with incomplete tool calls"
|
|
1597
|
+
);
|
|
1466
1598
|
return {
|
|
1467
1599
|
content: message?.content ?? "",
|
|
1468
|
-
toolCalls
|
|
1469
|
-
id: toolCall.id ?? generateToolCallId(),
|
|
1470
|
-
name: toolCall.function?.name ?? "",
|
|
1471
|
-
args: (() => {
|
|
1472
|
-
try {
|
|
1473
|
-
return JSON.parse(toolCall.function?.arguments ?? "{}");
|
|
1474
|
-
} catch {
|
|
1475
|
-
return {};
|
|
1476
|
-
}
|
|
1477
|
-
})(),
|
|
1478
|
-
...toolCall.extra_content ? { extra_content: toolCall.extra_content } : {}
|
|
1479
|
-
})) ?? [],
|
|
1600
|
+
toolCalls,
|
|
1480
1601
|
usage: response.usage ? {
|
|
1481
1602
|
promptTokens: response.usage.prompt_tokens,
|
|
1482
1603
|
completionTokens: response.usage.completion_tokens,
|