@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
|
* Fireworks 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
|
* Fireworks 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",
|
|
@@ -588,6 +602,63 @@ function formatMessages(messages) {
|
|
|
588
602
|
});
|
|
589
603
|
}
|
|
590
604
|
|
|
605
|
+
// src/core/provider-error.ts
|
|
606
|
+
function invalidProviderResponse(message) {
|
|
607
|
+
return Object.assign(new Error(message), {
|
|
608
|
+
name: "InvalidProviderResponseError",
|
|
609
|
+
status: 502,
|
|
610
|
+
code: "INVALID_PROVIDER_RESPONSE"
|
|
611
|
+
});
|
|
612
|
+
}
|
|
613
|
+
function providerErrorEvent(error, code) {
|
|
614
|
+
const details = error ?? {};
|
|
615
|
+
const event = {
|
|
616
|
+
type: "error",
|
|
617
|
+
message: error instanceof Error ? error.message : String(error),
|
|
618
|
+
code,
|
|
619
|
+
...typeof details.status === "number" ? { status: details.status } : {},
|
|
620
|
+
...typeof details.code === "string" ? { providerCode: details.code } : {},
|
|
621
|
+
...typeof details.param === "string" ? { param: details.param } : {},
|
|
622
|
+
...typeof details.request_id === "string" ? { requestId: details.request_id } : {}
|
|
623
|
+
};
|
|
624
|
+
Object.defineProperty(event, "cause", { value: error, enumerable: false });
|
|
625
|
+
return event;
|
|
626
|
+
}
|
|
627
|
+
function throwIfAborted(signal) {
|
|
628
|
+
if (!signal?.aborted) return;
|
|
629
|
+
const error = new Error("The operation was aborted");
|
|
630
|
+
error.name = "AbortError";
|
|
631
|
+
throw error;
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
// src/core/tool-validation.ts
|
|
635
|
+
function parseToolArguments(value) {
|
|
636
|
+
let args = value;
|
|
637
|
+
if (typeof value === "string") {
|
|
638
|
+
try {
|
|
639
|
+
args = JSON.parse(value || "{}");
|
|
640
|
+
} catch {
|
|
641
|
+
throw invalidProviderResponse("Tool arguments are not valid JSON");
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
if (args === null || typeof args !== "object" || Array.isArray(args))
|
|
645
|
+
throw invalidProviderResponse("Tool arguments must be a JSON object");
|
|
646
|
+
return args;
|
|
647
|
+
}
|
|
648
|
+
function validateToolCalls(calls) {
|
|
649
|
+
const ids = /* @__PURE__ */ new Set();
|
|
650
|
+
for (const call of calls) {
|
|
651
|
+
if (!call || typeof call.id !== "string" || !call.id || typeof call.name !== "string" || !call.name || ids.has(call.id))
|
|
652
|
+
throw invalidProviderResponse(
|
|
653
|
+
"Tool calls have missing or duplicate identities"
|
|
654
|
+
);
|
|
655
|
+
ids.add(call.id);
|
|
656
|
+
if (typeof call.args === "string")
|
|
657
|
+
throw invalidProviderResponse("Parsed tool arguments must be an object");
|
|
658
|
+
parseToolArguments(call.args);
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
|
|
591
662
|
// src/core/openai-responses.ts
|
|
592
663
|
function resolveOpenAITransport(defaults, overrides) {
|
|
593
664
|
return {
|
|
@@ -635,6 +706,54 @@ function responseMetadata(response) {
|
|
|
635
706
|
}
|
|
636
707
|
};
|
|
637
708
|
}
|
|
709
|
+
function responseReplayMetadata(metadata) {
|
|
710
|
+
const response = metadata?.openai?.response;
|
|
711
|
+
if (!response) return metadata;
|
|
712
|
+
const output = response.output.map((item) => {
|
|
713
|
+
const fields = ["type", "id", "status"];
|
|
714
|
+
switch (item.type) {
|
|
715
|
+
case "reasoning":
|
|
716
|
+
fields.push("encrypted_content");
|
|
717
|
+
break;
|
|
718
|
+
case "message":
|
|
719
|
+
fields.push("role", "phase");
|
|
720
|
+
break;
|
|
721
|
+
case "function_call":
|
|
722
|
+
fields.push("call_id", "name", "namespace", "arguments");
|
|
723
|
+
break;
|
|
724
|
+
case "tool_search_call":
|
|
725
|
+
fields.push("call_id", "execution", "arguments");
|
|
726
|
+
break;
|
|
727
|
+
case "tool_search_output":
|
|
728
|
+
fields.push("call_id", "tools");
|
|
729
|
+
break;
|
|
730
|
+
case "web_search_call":
|
|
731
|
+
fields.push("action");
|
|
732
|
+
break;
|
|
733
|
+
default:
|
|
734
|
+
return stripItemDiagnostics(item);
|
|
735
|
+
}
|
|
736
|
+
const replay = Object.fromEntries(
|
|
737
|
+
fields.filter((key) => item[key] !== void 0).map((key) => [key, item[key]])
|
|
738
|
+
);
|
|
739
|
+
if (item.type === "reasoning") replay.summary = [];
|
|
740
|
+
if (item.type === "message")
|
|
741
|
+
replay.content = Array.isArray(item.content) ? item.content.flatMap(
|
|
742
|
+
(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 }] : []
|
|
743
|
+
) : [];
|
|
744
|
+
return stripItemDiagnostics(replay);
|
|
745
|
+
});
|
|
746
|
+
return { openai: { response: { output, refusals: [] } } };
|
|
747
|
+
}
|
|
748
|
+
function stripItemDiagnostics(item) {
|
|
749
|
+
const {
|
|
750
|
+
usage: _usage,
|
|
751
|
+
logprobs: _logprobs,
|
|
752
|
+
metadata: _metadata,
|
|
753
|
+
...state
|
|
754
|
+
} = item;
|
|
755
|
+
return state;
|
|
756
|
+
}
|
|
638
757
|
function getResponseReplay(metadata) {
|
|
639
758
|
const response = metadata?.openai?.response;
|
|
640
759
|
if (response === void 0) return void 0;
|
|
@@ -643,29 +762,7 @@ function getResponseReplay(metadata) {
|
|
|
643
762
|
"Invalid OpenAI Responses replay metadata: output must contain typed items"
|
|
644
763
|
);
|
|
645
764
|
}
|
|
646
|
-
return response
|
|
647
|
-
}
|
|
648
|
-
|
|
649
|
-
// src/core/provider-error.ts
|
|
650
|
-
function providerErrorEvent(error, code) {
|
|
651
|
-
const details = error ?? {};
|
|
652
|
-
const event = {
|
|
653
|
-
type: "error",
|
|
654
|
-
message: error instanceof Error ? error.message : String(error),
|
|
655
|
-
code,
|
|
656
|
-
...typeof details.status === "number" ? { status: details.status } : {},
|
|
657
|
-
...typeof details.code === "string" ? { providerCode: details.code } : {},
|
|
658
|
-
...typeof details.param === "string" ? { param: details.param } : {},
|
|
659
|
-
...typeof details.request_id === "string" ? { requestId: details.request_id } : {}
|
|
660
|
-
};
|
|
661
|
-
Object.defineProperty(event, "cause", { value: error, enumerable: false });
|
|
662
|
-
return event;
|
|
663
|
-
}
|
|
664
|
-
function throwIfAborted(signal) {
|
|
665
|
-
if (!signal?.aborted) return;
|
|
666
|
-
const error = new Error("The operation was aborted");
|
|
667
|
-
error.name = "AbortError";
|
|
668
|
-
throw error;
|
|
765
|
+
return responseReplayMetadata(metadata)?.openai?.response?.output;
|
|
669
766
|
}
|
|
670
767
|
|
|
671
768
|
// src/core/utils.ts
|
|
@@ -675,9 +772,6 @@ function generateId(prefix = "id") {
|
|
|
675
772
|
function generateMessageId() {
|
|
676
773
|
return generateId("msg");
|
|
677
774
|
}
|
|
678
|
-
function generateToolCallId() {
|
|
679
|
-
return generateId("call");
|
|
680
|
-
}
|
|
681
775
|
|
|
682
776
|
// src/adapters/openai.ts
|
|
683
777
|
var OpenAIAdapter = class _OpenAIAdapter {
|
|
@@ -701,6 +795,8 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
701
795
|
apiKey: this.config.apiKey,
|
|
702
796
|
baseURL: this.config.baseUrl,
|
|
703
797
|
organization: this.config.organization,
|
|
798
|
+
project: this.config.project,
|
|
799
|
+
timeout: this.config.timeout,
|
|
704
800
|
defaultHeaders: this.config.headers
|
|
705
801
|
});
|
|
706
802
|
}
|
|
@@ -823,7 +919,7 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
823
919
|
formatRawMessages(messages, preserveProviderMetadata = false) {
|
|
824
920
|
return messages.map((message) => {
|
|
825
921
|
const { attachments, providerMetadata, modelOutput, ...rest } = message;
|
|
826
|
-
let content = message.role === "tool" && !preserveProviderMetadata ? textToolOutput(modelOutput,
|
|
922
|
+
let content = message.role === "tool" && !preserveProviderMetadata && modelOutput !== void 0 ? textToolOutput(modelOutput, "") : message.content;
|
|
827
923
|
if (preserveProviderMetadata && modelOutput)
|
|
828
924
|
rest.modelOutput = modelOutput;
|
|
829
925
|
if (message.role === "assistant" && Array.isArray(message.tool_calls) && message.tool_calls.length > 0 && content === "") {
|
|
@@ -926,17 +1022,32 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
926
1022
|
const seenCallIds = /* @__PURE__ */ new Set();
|
|
927
1023
|
const toolCalls = Array.isArray(response?.output) ? response.output.filter((item) => item?.type === "function_call").map((item) => {
|
|
928
1024
|
if (typeof item.call_id !== "string" || !item.call_id || typeof item.name !== "string" || !item.name || typeof item.arguments !== "string" || item.status && item.status !== "completed") {
|
|
929
|
-
throw
|
|
1025
|
+
throw invalidProviderResponse(
|
|
1026
|
+
"Responses contains an incomplete function call"
|
|
1027
|
+
);
|
|
930
1028
|
}
|
|
931
1029
|
if (seenCallIds.has(item.call_id))
|
|
932
|
-
throw
|
|
1030
|
+
throw invalidProviderResponse(
|
|
1031
|
+
"Responses contains duplicate function call IDs"
|
|
1032
|
+
);
|
|
933
1033
|
seenCallIds.add(item.call_id);
|
|
934
|
-
|
|
1034
|
+
let args;
|
|
1035
|
+
try {
|
|
1036
|
+
args = JSON.parse(item.arguments);
|
|
1037
|
+
} catch {
|
|
1038
|
+
throw invalidProviderResponse(
|
|
1039
|
+
"Responses function arguments must be valid JSON"
|
|
1040
|
+
);
|
|
1041
|
+
}
|
|
935
1042
|
if (!args || typeof args !== "object" || Array.isArray(args))
|
|
936
|
-
throw
|
|
1043
|
+
throw invalidProviderResponse(
|
|
937
1044
|
"Responses function arguments must be a JSON object"
|
|
938
1045
|
);
|
|
939
|
-
return {
|
|
1046
|
+
return {
|
|
1047
|
+
id: item.call_id,
|
|
1048
|
+
name: item.name,
|
|
1049
|
+
args
|
|
1050
|
+
};
|
|
940
1051
|
}) : [];
|
|
941
1052
|
return {
|
|
942
1053
|
content,
|
|
@@ -967,6 +1078,16 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
967
1078
|
request.config?.responseFormat
|
|
968
1079
|
);
|
|
969
1080
|
const modelIdForPayload = request.config?.model || this.model;
|
|
1081
|
+
const include = filterOpenAIResponseInclude(
|
|
1082
|
+
modelIdForPayload,
|
|
1083
|
+
[
|
|
1084
|
+
.../* @__PURE__ */ new Set([
|
|
1085
|
+
...options?.include ?? [],
|
|
1086
|
+
...options?.store === false ? ["reasoning.encrypted_content"] : []
|
|
1087
|
+
])
|
|
1088
|
+
],
|
|
1089
|
+
this.parameterOptions(request)
|
|
1090
|
+
);
|
|
970
1091
|
const payload = {
|
|
971
1092
|
model: modelIdForPayload,
|
|
972
1093
|
instructions: request.systemPrompt,
|
|
@@ -990,14 +1111,7 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
990
1111
|
...options?.promptCacheKey !== void 0 ? { prompt_cache_key: options.promptCacheKey } : {},
|
|
991
1112
|
...options?.promptCacheOptions !== void 0 ? { prompt_cache_options: options.promptCacheOptions } : {},
|
|
992
1113
|
...options?.promptCacheRetention !== void 0 ? { prompt_cache_retention: options.promptCacheRetention } : {},
|
|
993
|
-
...
|
|
994
|
-
include: [
|
|
995
|
-
.../* @__PURE__ */ new Set([
|
|
996
|
-
...options?.include ?? [],
|
|
997
|
-
...options?.store === false ? ["reasoning.encrypted_content"] : []
|
|
998
|
-
])
|
|
999
|
-
]
|
|
1000
|
-
} : {},
|
|
1114
|
+
...include ? { include } : {},
|
|
1001
1115
|
...responsesTextFormat ? { text: { format: responsesTextFormat } } : {},
|
|
1002
1116
|
stream
|
|
1003
1117
|
};
|
|
@@ -1179,7 +1293,9 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
1179
1293
|
const uniqueCalls = /* @__PURE__ */ new Map();
|
|
1180
1294
|
for (const call of toolCalls.values()) {
|
|
1181
1295
|
if (!call.id || !call.name)
|
|
1182
|
-
throw
|
|
1296
|
+
throw invalidProviderResponse(
|
|
1297
|
+
"Responses stream contains an incomplete tool call"
|
|
1298
|
+
);
|
|
1183
1299
|
uniqueCalls.set(call.id, call);
|
|
1184
1300
|
}
|
|
1185
1301
|
toolCalls.clear();
|
|
@@ -1366,15 +1482,20 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
1366
1482
|
}
|
|
1367
1483
|
throwIfAborted(request.signal);
|
|
1368
1484
|
if (!finishReason)
|
|
1369
|
-
throw
|
|
1485
|
+
throw invalidProviderResponse(
|
|
1486
|
+
"OpenAI stream ended without a finish reason"
|
|
1487
|
+
);
|
|
1370
1488
|
if (toolCalls.size && !["tool_calls", "function_call"].includes(finishReason)) {
|
|
1371
|
-
throw
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
if (!call.id || !call.name)
|
|
1375
|
-
throw new Error("OpenAI stream contains an incomplete tool call");
|
|
1376
|
-
JSON.parse(call.arguments || "{}");
|
|
1489
|
+
throw invalidProviderResponse(
|
|
1490
|
+
"OpenAI stream ended with incomplete tool calls"
|
|
1491
|
+
);
|
|
1377
1492
|
}
|
|
1493
|
+
validateToolCalls(
|
|
1494
|
+
[...toolCalls.values()].map((call) => ({
|
|
1495
|
+
...call,
|
|
1496
|
+
args: parseToolArguments(call.arguments)
|
|
1497
|
+
}))
|
|
1498
|
+
);
|
|
1378
1499
|
for (const call of toolCalls.values()) {
|
|
1379
1500
|
yield {
|
|
1380
1501
|
type: "action:start",
|
|
@@ -1458,20 +1579,20 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
1458
1579
|
logProviderPayload("openai", "response payload", response, request.debug);
|
|
1459
1580
|
const choice = response.choices?.[0];
|
|
1460
1581
|
const message = choice?.message;
|
|
1582
|
+
const toolCalls = (message?.tool_calls ?? []).map((toolCall) => ({
|
|
1583
|
+
id: toolCall.id,
|
|
1584
|
+
name: toolCall.function?.name,
|
|
1585
|
+
args: parseToolArguments(toolCall.function?.arguments ?? "{}"),
|
|
1586
|
+
...toolCall.extra_content ? { extra_content: toolCall.extra_content } : {}
|
|
1587
|
+
}));
|
|
1588
|
+
validateToolCalls(toolCalls);
|
|
1589
|
+
if (toolCalls.length && choice?.finish_reason && !["tool_calls", "function_call"].includes(choice.finish_reason))
|
|
1590
|
+
throw invalidProviderResponse(
|
|
1591
|
+
"OpenAI response ended with incomplete tool calls"
|
|
1592
|
+
);
|
|
1461
1593
|
return {
|
|
1462
1594
|
content: message?.content ?? "",
|
|
1463
|
-
toolCalls
|
|
1464
|
-
id: toolCall.id ?? generateToolCallId(),
|
|
1465
|
-
name: toolCall.function?.name ?? "",
|
|
1466
|
-
args: (() => {
|
|
1467
|
-
try {
|
|
1468
|
-
return JSON.parse(toolCall.function?.arguments ?? "{}");
|
|
1469
|
-
} catch {
|
|
1470
|
-
return {};
|
|
1471
|
-
}
|
|
1472
|
-
})(),
|
|
1473
|
-
...toolCall.extra_content ? { extra_content: toolCall.extra_content } : {}
|
|
1474
|
-
})) ?? [],
|
|
1595
|
+
toolCalls,
|
|
1475
1596
|
usage: response.usage ? {
|
|
1476
1597
|
promptTokens: response.usage.prompt_tokens,
|
|
1477
1598
|
completionTokens: response.usage.completion_tokens,
|