@yourgpt/llm-sdk 2.6.0-beta.0 → 2.6.0-beta.1
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 +77 -0
- package/dist/adapters/index.d.mts +11 -13
- package/dist/adapters/index.d.ts +11 -13
- package/dist/adapters/index.js +255 -164
- package/dist/adapters/index.mjs +255 -164
- package/dist/{base-C58Dsr9p.d.ts → base-BdTpUAWI.d.ts} +2 -1
- package/dist/{base-tNgbBaSo.d.mts → base-CkeT7u-O.d.mts} +2 -1
- package/dist/fallback/index.d.mts +4 -4
- package/dist/fallback/index.d.ts +4 -4
- package/dist/fallback/index.js +75 -39
- package/dist/fallback/index.mjs +75 -39
- package/dist/index.d.mts +8 -7
- package/dist/index.d.ts +8 -7
- package/dist/index.js +75 -28
- package/dist/index.mjs +75 -28
- package/dist/providers/anthropic/index.d.mts +3 -3
- package/dist/providers/anthropic/index.d.ts +3 -3
- package/dist/providers/azure/index.d.mts +3 -3
- package/dist/providers/azure/index.d.ts +3 -3
- package/dist/providers/fireworks/index.d.mts +3 -3
- package/dist/providers/fireworks/index.d.ts +3 -3
- package/dist/providers/fireworks/index.js +255 -164
- package/dist/providers/fireworks/index.mjs +255 -164
- package/dist/providers/google/index.d.mts +3 -3
- package/dist/providers/google/index.d.ts +3 -3
- package/dist/providers/google/index.js +255 -164
- package/dist/providers/google/index.mjs +255 -164
- 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 +6 -23
- package/dist/providers/openai/index.d.ts +6 -23
- package/dist/providers/openai/index.js +656 -450
- package/dist/providers/openai/index.mjs +656 -450
- package/dist/providers/openrouter/index.d.mts +3 -3
- package/dist/providers/openrouter/index.d.ts +3 -3
- package/dist/providers/openrouter/index.js +255 -164
- package/dist/providers/openrouter/index.mjs +255 -164
- package/dist/providers/togetherai/index.d.mts +3 -3
- package/dist/providers/togetherai/index.d.ts +3 -3
- package/dist/providers/togetherai/index.js +255 -164
- package/dist/providers/togetherai/index.mjs +255 -164
- package/dist/providers/xai/index.d.mts +3 -3
- package/dist/providers/xai/index.d.ts +3 -3
- package/dist/providers/xai/index.js +255 -164
- package/dist/providers/xai/index.mjs +255 -164
- package/dist/{types-BkQCSiIt.d.mts → types-BW3csYo5.d.mts} +22 -1
- package/dist/{types-BkQCSiIt.d.ts → types-BW3csYo5.d.ts} +22 -1
- package/dist/{types-B6dhnguR.d.mts → types-BWRYIvl_.d.mts} +11 -4
- package/dist/{types-CCxPmkmK.d.ts → types-CpXcT-tY.d.ts} +11 -4
- package/dist/{types-BQ31QIsA.d.ts → types-DA54bSmX.d.ts} +3 -11
- package/dist/{types-BSSiJW2o.d.mts → types-NOswlhm9.d.mts} +3 -11
- package/dist/yourgpt/index.d.mts +1 -1
- package/dist/yourgpt/index.d.ts +1 -1
- package/package.json +115 -48
- package/LICENSE +0 -21
|
@@ -1,3 +1,54 @@
|
|
|
1
|
+
// src/core/openai-parameters.ts
|
|
2
|
+
function capabilities(model) {
|
|
3
|
+
const gpt = /^gpt-(\d+)(?:\.(\d+))?(?:-(.+))?$/i.exec(model);
|
|
4
|
+
const major = Number(gpt?.[1] ?? 0);
|
|
5
|
+
const minor = Number(gpt?.[2] ?? 0);
|
|
6
|
+
const chat = gpt?.[3]?.startsWith("chat") ?? false;
|
|
7
|
+
const reasoning = /^o\d+(?:-|$)/i.test(model) || major >= 5 && !chat;
|
|
8
|
+
const supportsNone = major === 5 && minor >= 1 && !chat || /^gpt-6-(?:sol|luna)(?:-\d{4}-\d{2}-\d{2})?$/i.test(model);
|
|
9
|
+
return { major, minor, reasoning, supportsNone };
|
|
10
|
+
}
|
|
11
|
+
function requiresOpenAIResponses(model, baseUrl, options = {}) {
|
|
12
|
+
if (options.parameterPolicy === "passthrough") return false;
|
|
13
|
+
const c = capabilities(model);
|
|
14
|
+
if (!c.reasoning || options.reasoningEffort === "none") return false;
|
|
15
|
+
if (!(c.major >= 6 || c.major === 5 && c.minor >= 4)) return false;
|
|
16
|
+
if (!baseUrl) return true;
|
|
17
|
+
try {
|
|
18
|
+
return new URL(baseUrl).hostname === "api.openai.com";
|
|
19
|
+
} catch {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
function buildOpenAIParameters(model, maxTokens, temperature, options = {}, api = "chat") {
|
|
24
|
+
const c = capabilities(model ?? "");
|
|
25
|
+
const normalize = options.parameterPolicy !== "passthrough";
|
|
26
|
+
const effort = options.reasoningEffort;
|
|
27
|
+
if (normalize && c.reasoning && effort === "none" && !c.supportsNone) {
|
|
28
|
+
throw new Error(`${model} does not support reasoningEffort: none`);
|
|
29
|
+
}
|
|
30
|
+
if (normalize && c.major >= 6 && effort === "minimal") {
|
|
31
|
+
throw new Error(`${model} does not support reasoningEffort: minimal`);
|
|
32
|
+
}
|
|
33
|
+
const result = {
|
|
34
|
+
[api === "responses" ? "max_output_tokens" : normalize && c.reasoning ? "max_completion_tokens" : "max_tokens"]: maxTokens
|
|
35
|
+
};
|
|
36
|
+
if (effort !== void 0) {
|
|
37
|
+
if (api === "responses") result.reasoning = { effort };
|
|
38
|
+
else result.reasoning_effort = effort;
|
|
39
|
+
}
|
|
40
|
+
if (temperature !== void 0) {
|
|
41
|
+
if (!normalize || !c.reasoning || effort === "none" && c.supportsNone) {
|
|
42
|
+
result.temperature = temperature;
|
|
43
|
+
} else {
|
|
44
|
+
(options.onWarning ?? console.warn)(
|
|
45
|
+
`[llm-sdk] ${model}: omitted temperature because reasoning is enabled.`
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return result;
|
|
50
|
+
}
|
|
51
|
+
|
|
1
52
|
// src/adapters/base.ts
|
|
2
53
|
function stringifyForDebug(value) {
|
|
3
54
|
return JSON.stringify(
|
|
@@ -104,16 +155,6 @@ function normalizeObjectJsonSchema(schema) {
|
|
|
104
155
|
}
|
|
105
156
|
return normalized;
|
|
106
157
|
}
|
|
107
|
-
function isOpenAIReasoningModel(modelId) {
|
|
108
|
-
if (!modelId) return false;
|
|
109
|
-
return /^(o1|o3|o4|gpt-5)/i.test(modelId);
|
|
110
|
-
}
|
|
111
|
-
function buildOpenAITokenParams(modelId, maxTokens, temperature) {
|
|
112
|
-
if (isOpenAIReasoningModel(modelId)) {
|
|
113
|
-
return { max_completion_tokens: maxTokens };
|
|
114
|
-
}
|
|
115
|
-
return { max_tokens: maxTokens, temperature };
|
|
116
|
-
}
|
|
117
158
|
function toOpenAIResponseFormat(rf) {
|
|
118
159
|
if (!rf) return void 0;
|
|
119
160
|
if (rf.type === "json_object") return { type: "json_object" };
|
|
@@ -520,6 +561,28 @@ function formatMessagesForGoogle(messages) {
|
|
|
520
561
|
});
|
|
521
562
|
}
|
|
522
563
|
|
|
564
|
+
// src/core/provider-error.ts
|
|
565
|
+
function providerErrorEvent(error, code) {
|
|
566
|
+
const details = error ?? {};
|
|
567
|
+
const event = {
|
|
568
|
+
type: "error",
|
|
569
|
+
message: error instanceof Error ? error.message : String(error),
|
|
570
|
+
code,
|
|
571
|
+
...typeof details.status === "number" ? { status: details.status } : {},
|
|
572
|
+
...typeof details.code === "string" ? { providerCode: details.code } : {},
|
|
573
|
+
...typeof details.param === "string" ? { param: details.param } : {},
|
|
574
|
+
...typeof details.request_id === "string" ? { requestId: details.request_id } : {}
|
|
575
|
+
};
|
|
576
|
+
Object.defineProperty(event, "cause", { value: error, enumerable: false });
|
|
577
|
+
return event;
|
|
578
|
+
}
|
|
579
|
+
function throwIfAborted(signal) {
|
|
580
|
+
if (!signal?.aborted) return;
|
|
581
|
+
const error = new Error("The operation was aborted");
|
|
582
|
+
error.name = "AbortError";
|
|
583
|
+
throw error;
|
|
584
|
+
}
|
|
585
|
+
|
|
523
586
|
// src/core/utils.ts
|
|
524
587
|
function generateId(prefix = "id") {
|
|
525
588
|
return `${prefix}_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
|
|
@@ -551,39 +614,38 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
551
614
|
const { default: OpenAI } = await import('openai');
|
|
552
615
|
this.client = new OpenAI({
|
|
553
616
|
apiKey: this.config.apiKey,
|
|
554
|
-
baseURL: this.config.baseUrl
|
|
617
|
+
baseURL: this.config.baseUrl,
|
|
618
|
+
organization: this.config.organization,
|
|
619
|
+
defaultHeaders: this.config.headers
|
|
555
620
|
});
|
|
556
621
|
}
|
|
557
622
|
return this.client;
|
|
558
623
|
}
|
|
624
|
+
parameterOptions(request) {
|
|
625
|
+
return {
|
|
626
|
+
...this.config,
|
|
627
|
+
reasoningEffort: request.config?.reasoningEffort ?? this.config.reasoningEffort
|
|
628
|
+
};
|
|
629
|
+
}
|
|
630
|
+
toolDefinitions(request) {
|
|
631
|
+
if (request.toolDefinitions?.length) return request.toolDefinitions;
|
|
632
|
+
return formatTools(request.actions ?? []).map((tool) => ({
|
|
633
|
+
name: tool.function.name,
|
|
634
|
+
description: tool.function.description ?? "",
|
|
635
|
+
location: "server",
|
|
636
|
+
inputSchema: tool.function.parameters
|
|
637
|
+
}));
|
|
638
|
+
}
|
|
559
639
|
shouldUseResponsesApi(request) {
|
|
560
|
-
|
|
561
|
-
if (
|
|
562
|
-
if (request.providerToolOptions?.openai?.nativeToolSearch?.enabled === true && request.providerToolOptions.openai.nativeToolSearch.useResponsesApi !== false) {
|
|
640
|
+
if (this.toolDefinitions(request).length === 0) return false;
|
|
641
|
+
if (request.providerToolOptions?.openai?.nativeToolSearch?.enabled === true && request.providerToolOptions.openai.nativeToolSearch.useResponsesApi !== false)
|
|
563
642
|
return true;
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
643
|
+
return requiresOpenAIResponses(
|
|
644
|
+
request.config?.model || this.model,
|
|
645
|
+
this.config.baseUrl,
|
|
646
|
+
this.parameterOptions(request)
|
|
567
647
|
);
|
|
568
648
|
}
|
|
569
|
-
/**
|
|
570
|
-
* Whether this model rejects function tools on /v1/chat/completions.
|
|
571
|
-
*
|
|
572
|
-
* Applies to OpenAI proper only — the adapter is reused for OpenAI-compatible
|
|
573
|
-
* providers (Azure, xAI, Google, Fireworks) whose endpoints have no such
|
|
574
|
-
* restriction and may not implement /v1/responses at all.
|
|
575
|
-
*/
|
|
576
|
-
requiresResponsesApiForTools(modelId) {
|
|
577
|
-
if (!modelId) return false;
|
|
578
|
-
if (!/^gpt-5\.(?:[4-9]|\d{2,})/i.test(modelId)) return false;
|
|
579
|
-
const baseUrl = this.config.baseUrl;
|
|
580
|
-
if (!baseUrl) return true;
|
|
581
|
-
try {
|
|
582
|
-
return new URL(baseUrl).hostname === "api.openai.com";
|
|
583
|
-
} catch {
|
|
584
|
-
return false;
|
|
585
|
-
}
|
|
586
|
-
}
|
|
587
649
|
/**
|
|
588
650
|
* Convert one message's content to Responses content parts.
|
|
589
651
|
*
|
|
@@ -614,7 +676,7 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
614
676
|
});
|
|
615
677
|
}
|
|
616
678
|
buildResponsesInput(request) {
|
|
617
|
-
const sourceMessages = request.rawMessages && request.rawMessages.length > 0 ? request.rawMessages : formatMessagesForOpenAI(request.messages, void 0);
|
|
679
|
+
const sourceMessages = request.rawMessages && request.rawMessages.length > 0 ? this.formatRawMessages(request.rawMessages) : formatMessagesForOpenAI(request.messages, void 0);
|
|
618
680
|
const input = [];
|
|
619
681
|
for (const message of sourceMessages) {
|
|
620
682
|
if (message.role === "system") {
|
|
@@ -664,6 +726,26 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
664
726
|
}
|
|
665
727
|
return input;
|
|
666
728
|
}
|
|
729
|
+
/** Preserve Copilot screenshot attachments on every OpenAI transport. */
|
|
730
|
+
formatRawMessages(messages) {
|
|
731
|
+
return messages.map((message) => {
|
|
732
|
+
const { attachments, ...rest } = message;
|
|
733
|
+
let content = message.content;
|
|
734
|
+
if (message.role === "assistant" && Array.isArray(message.tool_calls) && message.tool_calls.length > 0 && content === "") {
|
|
735
|
+
content = null;
|
|
736
|
+
}
|
|
737
|
+
if (Array.isArray(attachments) && attachments.length > 0) {
|
|
738
|
+
const images = attachments.filter((attachment) => attachment && typeof attachment === "object").map(
|
|
739
|
+
(attachment) => attachmentToOpenAIImage(attachment)
|
|
740
|
+
).filter((image) => image !== null);
|
|
741
|
+
if (images.length > 0) {
|
|
742
|
+
const parts = Array.isArray(content) ? content : content ? [{ type: "text", text: content }] : [];
|
|
743
|
+
content = [...parts, ...images];
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
return { ...rest, content };
|
|
747
|
+
});
|
|
748
|
+
}
|
|
667
749
|
/**
|
|
668
750
|
* Build the web_search tool for the Responses API, or undefined when web
|
|
669
751
|
* search is off.
|
|
@@ -745,13 +827,7 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
745
827
|
const toolCalls = Array.isArray(response?.output) ? response.output.filter((item) => item?.type === "function_call").map((item) => ({
|
|
746
828
|
id: item.call_id ?? item.id ?? generateToolCallId(),
|
|
747
829
|
name: item.name,
|
|
748
|
-
args: (
|
|
749
|
-
try {
|
|
750
|
-
return JSON.parse(item.arguments ?? "{}");
|
|
751
|
-
} catch {
|
|
752
|
-
return {};
|
|
753
|
-
}
|
|
754
|
-
})()
|
|
830
|
+
args: JSON.parse(item.arguments ?? "{}")
|
|
755
831
|
})) : [];
|
|
756
832
|
return {
|
|
757
833
|
content,
|
|
@@ -775,18 +851,19 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
775
851
|
instructions: request.systemPrompt,
|
|
776
852
|
input: this.buildResponsesInput(request),
|
|
777
853
|
tools: this.buildResponsesTools(
|
|
778
|
-
|
|
854
|
+
this.toolDefinitions(request),
|
|
779
855
|
request.providerToolOptions?.openai?.nativeToolSearch?.enabled === true,
|
|
780
856
|
this.buildResponsesWebSearchTool(request)
|
|
781
857
|
),
|
|
782
|
-
tool_choice: openaiToolOptions?.toolChoice
|
|
858
|
+
tool_choice: openaiToolOptions?.toolChoice,
|
|
783
859
|
parallel_tool_calls: openaiToolOptions?.parallelToolCalls,
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
860
|
+
...buildOpenAIParameters(
|
|
861
|
+
modelIdForPayload,
|
|
862
|
+
request.config?.maxTokens ?? this.config.maxTokens,
|
|
863
|
+
request.config?.temperature ?? this.config.temperature,
|
|
864
|
+
this.parameterOptions(request),
|
|
865
|
+
"responses"
|
|
866
|
+
),
|
|
790
867
|
...responsesTextFormat ? { text: { format: responsesTextFormat } } : {},
|
|
791
868
|
stream
|
|
792
869
|
};
|
|
@@ -794,10 +871,26 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
794
871
|
}
|
|
795
872
|
async completeWithResponses(request) {
|
|
796
873
|
const client = await this.getClient();
|
|
874
|
+
throwIfAborted(request.signal);
|
|
797
875
|
const payload = this.buildResponsesPayload(request, false);
|
|
798
876
|
logProviderPayload("openai", "request payload", payload, request.debug);
|
|
799
|
-
|
|
877
|
+
if (!client.responses?.create)
|
|
878
|
+
throw new Error(
|
|
879
|
+
"This OpenAI client does not support Responses; install an openai version with Responses support."
|
|
880
|
+
);
|
|
881
|
+
const response = await client.responses.create(payload, {
|
|
882
|
+
signal: request.signal
|
|
883
|
+
});
|
|
884
|
+
throwIfAborted(request.signal);
|
|
800
885
|
logProviderPayload("openai", "response payload", response, request.debug);
|
|
886
|
+
if (response.status && response.status !== "completed") {
|
|
887
|
+
throw Object.assign(
|
|
888
|
+
new Error(
|
|
889
|
+
response.error?.message ?? `Responses request ${response.status}`
|
|
890
|
+
),
|
|
891
|
+
response.error
|
|
892
|
+
);
|
|
893
|
+
}
|
|
801
894
|
return this.parseResponsesResult(response);
|
|
802
895
|
}
|
|
803
896
|
/**
|
|
@@ -815,13 +908,26 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
815
908
|
*/
|
|
816
909
|
async *streamWithResponses(request) {
|
|
817
910
|
const client = await this.getClient();
|
|
911
|
+
throwIfAborted(request.signal);
|
|
818
912
|
const payload = this.buildResponsesPayload(request, true);
|
|
819
913
|
logProviderPayload("openai", "request payload", payload, request.debug);
|
|
820
|
-
|
|
914
|
+
if (!client.responses?.create)
|
|
915
|
+
throw new Error(
|
|
916
|
+
"This OpenAI client does not support Responses; install an openai version with Responses support."
|
|
917
|
+
);
|
|
918
|
+
const stream = await client.responses.create(payload, {
|
|
919
|
+
signal: request.signal
|
|
920
|
+
});
|
|
821
921
|
const toolCalls = /* @__PURE__ */ new Map();
|
|
822
922
|
let usage;
|
|
823
923
|
const citations = [];
|
|
924
|
+
let completed = false;
|
|
824
925
|
function* flushToolCalls() {
|
|
926
|
+
for (const call of toolCalls.values()) {
|
|
927
|
+
if (!call.name)
|
|
928
|
+
throw new Error("Responses tool call is missing its name");
|
|
929
|
+
JSON.parse(call.arguments || "{}");
|
|
930
|
+
}
|
|
825
931
|
for (const call of toolCalls.values()) {
|
|
826
932
|
yield { type: "action:start", id: call.id, name: call.name };
|
|
827
933
|
yield { type: "action:args", id: call.id, args: call.arguments };
|
|
@@ -830,7 +936,7 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
830
936
|
toolCalls.clear();
|
|
831
937
|
}
|
|
832
938
|
for await (const event of stream) {
|
|
833
|
-
|
|
939
|
+
throwIfAborted(request.signal);
|
|
834
940
|
logProviderPayload("openai", "stream chunk", event, request.debug);
|
|
835
941
|
const index = event?.output_index ?? 0;
|
|
836
942
|
switch (event?.type) {
|
|
@@ -860,8 +966,8 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
860
966
|
}
|
|
861
967
|
break;
|
|
862
968
|
}
|
|
863
|
-
case "response.completed":
|
|
864
|
-
|
|
969
|
+
case "response.completed": {
|
|
970
|
+
completed = true;
|
|
865
971
|
const found = this.collectResponsesCitations(
|
|
866
972
|
event.response?.output,
|
|
867
973
|
citations.length
|
|
@@ -877,13 +983,27 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
877
983
|
}
|
|
878
984
|
break;
|
|
879
985
|
}
|
|
880
|
-
case "
|
|
881
|
-
case "response.failed":
|
|
986
|
+
case "response.incomplete":
|
|
882
987
|
throw new Error(
|
|
883
|
-
|
|
988
|
+
`Responses stream incomplete: ${event.response?.incomplete_details?.reason ?? "unknown reason"}`
|
|
884
989
|
);
|
|
990
|
+
case "error":
|
|
991
|
+
case "response.failed": {
|
|
992
|
+
const details = event.response?.error ?? event;
|
|
993
|
+
throw Object.assign(
|
|
994
|
+
new Error(details.message ?? "Responses stream failed"),
|
|
995
|
+
{
|
|
996
|
+
code: details.code,
|
|
997
|
+
param: details.param,
|
|
998
|
+
status: details.status
|
|
999
|
+
}
|
|
1000
|
+
);
|
|
1001
|
+
}
|
|
885
1002
|
}
|
|
886
1003
|
}
|
|
1004
|
+
throwIfAborted(request.signal);
|
|
1005
|
+
if (!completed)
|
|
1006
|
+
throw new Error("Responses stream ended without a completed response");
|
|
887
1007
|
yield* flushToolCalls();
|
|
888
1008
|
if (citations.length > 0) {
|
|
889
1009
|
yield { type: "citation", citations: deduplicateCitations(citations) };
|
|
@@ -892,6 +1012,7 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
892
1012
|
yield { type: "done", usage };
|
|
893
1013
|
}
|
|
894
1014
|
async *stream(request) {
|
|
1015
|
+
throwIfAborted(request.signal);
|
|
895
1016
|
if (this.shouldUseResponsesApi(request)) {
|
|
896
1017
|
const messageId2 = generateMessageId();
|
|
897
1018
|
yield { type: "message:start", id: messageId2 };
|
|
@@ -899,47 +1020,14 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
899
1020
|
yield* this.streamWithResponses(request);
|
|
900
1021
|
return;
|
|
901
1022
|
} catch (error) {
|
|
902
|
-
yield
|
|
903
|
-
type: "error",
|
|
904
|
-
message: error instanceof Error ? error.message : "Unknown error",
|
|
905
|
-
code: "OPENAI_RESPONSES_ERROR"
|
|
906
|
-
};
|
|
1023
|
+
yield providerErrorEvent(error, "OPENAI_RESPONSES_ERROR");
|
|
907
1024
|
return;
|
|
908
1025
|
}
|
|
909
1026
|
}
|
|
910
1027
|
const client = await this.getClient();
|
|
911
1028
|
let messages;
|
|
912
1029
|
if (request.rawMessages && request.rawMessages.length > 0) {
|
|
913
|
-
const processedMessages = request.rawMessages
|
|
914
|
-
if (msg.role === "assistant" && Array.isArray(msg.tool_calls) && msg.tool_calls.length > 0 && msg.content === "") {
|
|
915
|
-
return { ...msg, content: null };
|
|
916
|
-
}
|
|
917
|
-
const hasAttachments = msg.attachments && Array.isArray(msg.attachments) && msg.attachments.length > 0;
|
|
918
|
-
if (hasAttachments) {
|
|
919
|
-
const content = [];
|
|
920
|
-
if (msg.content) {
|
|
921
|
-
content.push({ type: "text", text: msg.content });
|
|
922
|
-
}
|
|
923
|
-
for (const attachment of msg.attachments) {
|
|
924
|
-
if (attachment.type === "image") {
|
|
925
|
-
let imageUrl;
|
|
926
|
-
if (attachment.url) {
|
|
927
|
-
imageUrl = attachment.url;
|
|
928
|
-
} else if (attachment.data) {
|
|
929
|
-
imageUrl = attachment.data.startsWith("data:") ? attachment.data : `data:${attachment.mimeType || "image/png"};base64,${attachment.data}`;
|
|
930
|
-
} else {
|
|
931
|
-
continue;
|
|
932
|
-
}
|
|
933
|
-
content.push({
|
|
934
|
-
type: "image_url",
|
|
935
|
-
image_url: { url: imageUrl, detail: "auto" }
|
|
936
|
-
});
|
|
937
|
-
}
|
|
938
|
-
}
|
|
939
|
-
return { ...msg, content, attachments: void 0 };
|
|
940
|
-
}
|
|
941
|
-
return msg;
|
|
942
|
-
});
|
|
1030
|
+
const processedMessages = this.formatRawMessages(request.rawMessages);
|
|
943
1031
|
if (request.systemPrompt) {
|
|
944
1032
|
const hasSystem = processedMessages.some((m) => m.role === "system");
|
|
945
1033
|
if (!hasSystem) {
|
|
@@ -959,7 +1047,16 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
959
1047
|
request.systemPrompt
|
|
960
1048
|
);
|
|
961
1049
|
}
|
|
962
|
-
const tools = request.
|
|
1050
|
+
const tools = request.toolDefinitions?.length ? request.toolDefinitions.filter((tool) => tool.available !== false).map((tool) => ({
|
|
1051
|
+
type: "function",
|
|
1052
|
+
function: {
|
|
1053
|
+
name: tool.name,
|
|
1054
|
+
description: tool.description,
|
|
1055
|
+
parameters: normalizeObjectJsonSchema(
|
|
1056
|
+
tool.inputSchema
|
|
1057
|
+
)
|
|
1058
|
+
}
|
|
1059
|
+
})) : formatTools(request.actions ?? []);
|
|
963
1060
|
const webSearchConfig = request.webSearch ?? this.config.webSearch;
|
|
964
1061
|
if (webSearchConfig) {
|
|
965
1062
|
const webSearchTool = {
|
|
@@ -988,26 +1085,28 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
988
1085
|
tools: tools.length > 0 ? tools : void 0,
|
|
989
1086
|
tool_choice: tools.length > 0 ? toolChoice : void 0,
|
|
990
1087
|
parallel_tool_calls: tools.length > 0 ? openaiToolOptions?.parallelToolCalls : void 0,
|
|
991
|
-
...
|
|
1088
|
+
...buildOpenAIParameters(
|
|
992
1089
|
modelIdForPayload,
|
|
993
1090
|
request.config?.maxTokens ?? this.config.maxTokens,
|
|
994
|
-
request.config?.temperature ?? this.config.temperature
|
|
1091
|
+
request.config?.temperature ?? this.config.temperature,
|
|
1092
|
+
this.parameterOptions(request)
|
|
995
1093
|
),
|
|
996
1094
|
response_format: toOpenAIResponseFormat(request.config?.responseFormat),
|
|
997
1095
|
stream: true,
|
|
998
1096
|
stream_options: { include_usage: true }
|
|
999
1097
|
};
|
|
1000
1098
|
logProviderPayload("openai", "request payload", payload, request.debug);
|
|
1001
|
-
const stream = await client.chat.completions.create(payload
|
|
1002
|
-
|
|
1099
|
+
const stream = await client.chat.completions.create(payload, {
|
|
1100
|
+
signal: request.signal
|
|
1101
|
+
});
|
|
1102
|
+
const toolCalls = /* @__PURE__ */ new Map();
|
|
1103
|
+
let finishReason;
|
|
1003
1104
|
const collectedCitations = [];
|
|
1004
1105
|
let citationIndex = 0;
|
|
1005
1106
|
let usage;
|
|
1006
1107
|
for await (const chunk of stream) {
|
|
1007
1108
|
logProviderPayload("openai", "stream chunk", chunk, request.debug);
|
|
1008
|
-
|
|
1009
|
-
break;
|
|
1010
|
-
}
|
|
1109
|
+
throwIfAborted(request.signal);
|
|
1011
1110
|
const delta = chunk.choices[0]?.delta;
|
|
1012
1111
|
const choice = chunk.choices[0];
|
|
1013
1112
|
if (delta?.content) {
|
|
@@ -1030,38 +1129,19 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
1030
1129
|
}
|
|
1031
1130
|
}
|
|
1032
1131
|
}
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
};
|
|
1047
|
-
}
|
|
1048
|
-
const tcExtraContent = toolCall.extra_content;
|
|
1049
|
-
currentToolCall = {
|
|
1050
|
-
id: toolCall.id,
|
|
1051
|
-
name: toolCall.function?.name || "",
|
|
1052
|
-
arguments: toolCall.function?.arguments || "",
|
|
1053
|
-
...tcExtraContent ? { extra_content: tcExtraContent } : {}
|
|
1054
|
-
};
|
|
1055
|
-
yield {
|
|
1056
|
-
type: "action:start",
|
|
1057
|
-
id: currentToolCall.id,
|
|
1058
|
-
name: currentToolCall.name,
|
|
1059
|
-
...currentToolCall.extra_content ? { extra_content: currentToolCall.extra_content } : {}
|
|
1060
|
-
};
|
|
1061
|
-
} else if (currentToolCall && toolCall.function?.arguments) {
|
|
1062
|
-
currentToolCall.arguments += toolCall.function.arguments;
|
|
1063
|
-
}
|
|
1064
|
-
}
|
|
1132
|
+
for (const part of delta?.tool_calls ?? []) {
|
|
1133
|
+
const index = part.index ?? 0;
|
|
1134
|
+
const call = toolCalls.get(index) ?? {
|
|
1135
|
+
id: "",
|
|
1136
|
+
name: "",
|
|
1137
|
+
arguments: ""
|
|
1138
|
+
};
|
|
1139
|
+
if (part.id) call.id = part.id;
|
|
1140
|
+
if (part.function?.name) call.name += part.function.name;
|
|
1141
|
+
if (part.function?.arguments)
|
|
1142
|
+
call.arguments += part.function.arguments;
|
|
1143
|
+
if (part.extra_content) call.extra_content = part.extra_content;
|
|
1144
|
+
toolCalls.set(index, call);
|
|
1065
1145
|
}
|
|
1066
1146
|
if (chunk.usage) {
|
|
1067
1147
|
usage = {
|
|
@@ -1070,21 +1150,28 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
1070
1150
|
total_tokens: chunk.usage.total_tokens
|
|
1071
1151
|
};
|
|
1072
1152
|
}
|
|
1073
|
-
if (choice?.finish_reason)
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1153
|
+
if (choice?.finish_reason) finishReason = choice.finish_reason;
|
|
1154
|
+
}
|
|
1155
|
+
throwIfAborted(request.signal);
|
|
1156
|
+
if (!finishReason)
|
|
1157
|
+
throw new Error("OpenAI stream ended without a finish reason");
|
|
1158
|
+
if (toolCalls.size && !["tool_calls", "function_call"].includes(finishReason)) {
|
|
1159
|
+
throw new Error("OpenAI stream ended with incomplete tool calls");
|
|
1160
|
+
}
|
|
1161
|
+
for (const call of toolCalls.values()) {
|
|
1162
|
+
if (!call.id || !call.name)
|
|
1163
|
+
throw new Error("OpenAI stream contains an incomplete tool call");
|
|
1164
|
+
JSON.parse(call.arguments || "{}");
|
|
1165
|
+
}
|
|
1166
|
+
for (const call of toolCalls.values()) {
|
|
1167
|
+
yield {
|
|
1168
|
+
type: "action:start",
|
|
1169
|
+
id: call.id,
|
|
1170
|
+
name: call.name,
|
|
1171
|
+
...call.extra_content ? { extra_content: call.extra_content } : {}
|
|
1172
|
+
};
|
|
1173
|
+
yield { type: "action:args", id: call.id, args: call.arguments };
|
|
1174
|
+
yield { type: "action:end", id: call.id, name: call.name };
|
|
1088
1175
|
}
|
|
1089
1176
|
if (collectedCitations.length > 0) {
|
|
1090
1177
|
const uniqueCitations = deduplicateCitations(collectedCitations);
|
|
@@ -1093,26 +1180,18 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
1093
1180
|
yield { type: "message:end" };
|
|
1094
1181
|
yield { type: "done", usage };
|
|
1095
1182
|
} catch (error) {
|
|
1096
|
-
yield {
|
|
1097
|
-
type: "error",
|
|
1098
|
-
message: error instanceof Error ? error.message : "Unknown error",
|
|
1099
|
-
code: `${this.provider.toUpperCase()}_ERROR`
|
|
1100
|
-
};
|
|
1183
|
+
yield providerErrorEvent(error, `${this.provider.toUpperCase()}_ERROR`);
|
|
1101
1184
|
}
|
|
1102
1185
|
}
|
|
1103
1186
|
async complete(request) {
|
|
1187
|
+
throwIfAborted(request.signal);
|
|
1104
1188
|
if (this.shouldUseResponsesApi(request)) {
|
|
1105
1189
|
return this.completeWithResponses(request);
|
|
1106
1190
|
}
|
|
1107
1191
|
const client = await this.getClient();
|
|
1108
1192
|
let messages;
|
|
1109
1193
|
if (request.rawMessages && request.rawMessages.length > 0) {
|
|
1110
|
-
const sanitized = request.rawMessages
|
|
1111
|
-
if (msg.role === "assistant" && Array.isArray(msg.tool_calls) && msg.tool_calls.length > 0 && msg.content === "") {
|
|
1112
|
-
return { ...msg, content: null };
|
|
1113
|
-
}
|
|
1114
|
-
return msg;
|
|
1115
|
-
});
|
|
1194
|
+
const sanitized = this.formatRawMessages(request.rawMessages);
|
|
1116
1195
|
if (request.systemPrompt && !sanitized.some((message2) => message2.role === "system")) {
|
|
1117
1196
|
messages = [
|
|
1118
1197
|
{ role: "system", content: request.systemPrompt },
|
|
@@ -1127,7 +1206,16 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
1127
1206
|
request.systemPrompt
|
|
1128
1207
|
);
|
|
1129
1208
|
}
|
|
1130
|
-
const tools = request.
|
|
1209
|
+
const tools = request.toolDefinitions?.length ? request.toolDefinitions.filter((tool) => tool.available !== false).map((tool) => ({
|
|
1210
|
+
type: "function",
|
|
1211
|
+
function: {
|
|
1212
|
+
name: tool.name,
|
|
1213
|
+
description: tool.description,
|
|
1214
|
+
parameters: normalizeObjectJsonSchema(
|
|
1215
|
+
tool.inputSchema
|
|
1216
|
+
)
|
|
1217
|
+
}
|
|
1218
|
+
})) : formatTools(request.actions ?? []);
|
|
1131
1219
|
const openaiToolOptions = request.providerToolOptions?.openai;
|
|
1132
1220
|
const toolChoice = openaiToolOptions?.toolChoice && typeof openaiToolOptions.toolChoice === "object" ? {
|
|
1133
1221
|
type: "function",
|
|
@@ -1142,16 +1230,19 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
1142
1230
|
tools: tools.length > 0 ? tools : void 0,
|
|
1143
1231
|
tool_choice: tools.length > 0 ? toolChoice : void 0,
|
|
1144
1232
|
parallel_tool_calls: tools.length > 0 ? openaiToolOptions?.parallelToolCalls : void 0,
|
|
1145
|
-
...
|
|
1233
|
+
...buildOpenAIParameters(
|
|
1146
1234
|
modelIdForCompletePayload,
|
|
1147
1235
|
request.config?.maxTokens ?? this.config.maxTokens,
|
|
1148
|
-
request.config?.temperature ?? this.config.temperature
|
|
1236
|
+
request.config?.temperature ?? this.config.temperature,
|
|
1237
|
+
this.parameterOptions(request)
|
|
1149
1238
|
),
|
|
1150
1239
|
response_format: toOpenAIResponseFormat(request.config?.responseFormat),
|
|
1151
1240
|
stream: false
|
|
1152
1241
|
};
|
|
1153
1242
|
logProviderPayload("openai", "request payload", payload, request.debug);
|
|
1154
|
-
const response = await client.chat.completions.create(payload
|
|
1243
|
+
const response = await client.chat.completions.create(payload, {
|
|
1244
|
+
signal: request.signal
|
|
1245
|
+
});
|
|
1155
1246
|
logProviderPayload("openai", "response payload", response, request.debug);
|
|
1156
1247
|
const choice = response.choices?.[0];
|
|
1157
1248
|
const message = choice?.message;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { c as OllamaProviderConfig, A as AIProvider } from '../../types-
|
|
2
|
-
export { d as OllamaModelOptions } from '../../types-
|
|
3
|
-
import '../../types-
|
|
1
|
+
import { c as OllamaProviderConfig, A as AIProvider } from '../../types-NOswlhm9.mjs';
|
|
2
|
+
export { d as OllamaModelOptions } from '../../types-NOswlhm9.mjs';
|
|
3
|
+
import '../../types-BW3csYo5.mjs';
|
|
4
4
|
import 'zod';
|
|
5
|
-
import '../../base-
|
|
5
|
+
import '../../base-CkeT7u-O.mjs';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Ollama Provider
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { c as OllamaProviderConfig, A as AIProvider } from '../../types-
|
|
2
|
-
export { d as OllamaModelOptions } from '../../types-
|
|
3
|
-
import '../../types-
|
|
1
|
+
import { c as OllamaProviderConfig, A as AIProvider } from '../../types-DA54bSmX.js';
|
|
2
|
+
export { d as OllamaModelOptions } from '../../types-DA54bSmX.js';
|
|
3
|
+
import '../../types-BW3csYo5.js';
|
|
4
4
|
import 'zod';
|
|
5
|
-
import '../../base-
|
|
5
|
+
import '../../base-BdTpUAWI.js';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Ollama Provider
|