@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" };
|
|
@@ -493,6 +534,28 @@ async function searchOpenRouterModels(query, apiKey) {
|
|
|
493
534
|
);
|
|
494
535
|
}
|
|
495
536
|
|
|
537
|
+
// src/core/provider-error.ts
|
|
538
|
+
function providerErrorEvent(error, code) {
|
|
539
|
+
const details = error ?? {};
|
|
540
|
+
const event = {
|
|
541
|
+
type: "error",
|
|
542
|
+
message: error instanceof Error ? error.message : String(error),
|
|
543
|
+
code,
|
|
544
|
+
...typeof details.status === "number" ? { status: details.status } : {},
|
|
545
|
+
...typeof details.code === "string" ? { providerCode: details.code } : {},
|
|
546
|
+
...typeof details.param === "string" ? { param: details.param } : {},
|
|
547
|
+
...typeof details.request_id === "string" ? { requestId: details.request_id } : {}
|
|
548
|
+
};
|
|
549
|
+
Object.defineProperty(event, "cause", { value: error, enumerable: false });
|
|
550
|
+
return event;
|
|
551
|
+
}
|
|
552
|
+
function throwIfAborted(signal) {
|
|
553
|
+
if (!signal?.aborted) return;
|
|
554
|
+
const error = new Error("The operation was aborted");
|
|
555
|
+
error.name = "AbortError";
|
|
556
|
+
throw error;
|
|
557
|
+
}
|
|
558
|
+
|
|
496
559
|
// src/core/utils.ts
|
|
497
560
|
function generateId(prefix = "id") {
|
|
498
561
|
return `${prefix}_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
|
|
@@ -524,39 +587,38 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
524
587
|
const { default: OpenAI } = await import('openai');
|
|
525
588
|
this.client = new OpenAI({
|
|
526
589
|
apiKey: this.config.apiKey,
|
|
527
|
-
baseURL: this.config.baseUrl
|
|
590
|
+
baseURL: this.config.baseUrl,
|
|
591
|
+
organization: this.config.organization,
|
|
592
|
+
defaultHeaders: this.config.headers
|
|
528
593
|
});
|
|
529
594
|
}
|
|
530
595
|
return this.client;
|
|
531
596
|
}
|
|
597
|
+
parameterOptions(request) {
|
|
598
|
+
return {
|
|
599
|
+
...this.config,
|
|
600
|
+
reasoningEffort: request.config?.reasoningEffort ?? this.config.reasoningEffort
|
|
601
|
+
};
|
|
602
|
+
}
|
|
603
|
+
toolDefinitions(request) {
|
|
604
|
+
if (request.toolDefinitions?.length) return request.toolDefinitions;
|
|
605
|
+
return formatTools(request.actions ?? []).map((tool) => ({
|
|
606
|
+
name: tool.function.name,
|
|
607
|
+
description: tool.function.description ?? "",
|
|
608
|
+
location: "server",
|
|
609
|
+
inputSchema: tool.function.parameters
|
|
610
|
+
}));
|
|
611
|
+
}
|
|
532
612
|
shouldUseResponsesApi(request) {
|
|
533
|
-
|
|
534
|
-
if (
|
|
535
|
-
if (request.providerToolOptions?.openai?.nativeToolSearch?.enabled === true && request.providerToolOptions.openai.nativeToolSearch.useResponsesApi !== false) {
|
|
613
|
+
if (this.toolDefinitions(request).length === 0) return false;
|
|
614
|
+
if (request.providerToolOptions?.openai?.nativeToolSearch?.enabled === true && request.providerToolOptions.openai.nativeToolSearch.useResponsesApi !== false)
|
|
536
615
|
return true;
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
616
|
+
return requiresOpenAIResponses(
|
|
617
|
+
request.config?.model || this.model,
|
|
618
|
+
this.config.baseUrl,
|
|
619
|
+
this.parameterOptions(request)
|
|
540
620
|
);
|
|
541
621
|
}
|
|
542
|
-
/**
|
|
543
|
-
* Whether this model rejects function tools on /v1/chat/completions.
|
|
544
|
-
*
|
|
545
|
-
* Applies to OpenAI proper only — the adapter is reused for OpenAI-compatible
|
|
546
|
-
* providers (Azure, xAI, Google, Fireworks) whose endpoints have no such
|
|
547
|
-
* restriction and may not implement /v1/responses at all.
|
|
548
|
-
*/
|
|
549
|
-
requiresResponsesApiForTools(modelId) {
|
|
550
|
-
if (!modelId) return false;
|
|
551
|
-
if (!/^gpt-5\.(?:[4-9]|\d{2,})/i.test(modelId)) return false;
|
|
552
|
-
const baseUrl = this.config.baseUrl;
|
|
553
|
-
if (!baseUrl) return true;
|
|
554
|
-
try {
|
|
555
|
-
return new URL(baseUrl).hostname === "api.openai.com";
|
|
556
|
-
} catch {
|
|
557
|
-
return false;
|
|
558
|
-
}
|
|
559
|
-
}
|
|
560
622
|
/**
|
|
561
623
|
* Convert one message's content to Responses content parts.
|
|
562
624
|
*
|
|
@@ -587,7 +649,7 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
587
649
|
});
|
|
588
650
|
}
|
|
589
651
|
buildResponsesInput(request) {
|
|
590
|
-
const sourceMessages = request.rawMessages && request.rawMessages.length > 0 ? request.rawMessages : formatMessagesForOpenAI(request.messages, void 0);
|
|
652
|
+
const sourceMessages = request.rawMessages && request.rawMessages.length > 0 ? this.formatRawMessages(request.rawMessages) : formatMessagesForOpenAI(request.messages, void 0);
|
|
591
653
|
const input = [];
|
|
592
654
|
for (const message of sourceMessages) {
|
|
593
655
|
if (message.role === "system") {
|
|
@@ -637,6 +699,26 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
637
699
|
}
|
|
638
700
|
return input;
|
|
639
701
|
}
|
|
702
|
+
/** Preserve Copilot screenshot attachments on every OpenAI transport. */
|
|
703
|
+
formatRawMessages(messages) {
|
|
704
|
+
return messages.map((message) => {
|
|
705
|
+
const { attachments, ...rest } = message;
|
|
706
|
+
let content = message.content;
|
|
707
|
+
if (message.role === "assistant" && Array.isArray(message.tool_calls) && message.tool_calls.length > 0 && content === "") {
|
|
708
|
+
content = null;
|
|
709
|
+
}
|
|
710
|
+
if (Array.isArray(attachments) && attachments.length > 0) {
|
|
711
|
+
const images = attachments.filter((attachment) => attachment && typeof attachment === "object").map(
|
|
712
|
+
(attachment) => attachmentToOpenAIImage(attachment)
|
|
713
|
+
).filter((image) => image !== null);
|
|
714
|
+
if (images.length > 0) {
|
|
715
|
+
const parts = Array.isArray(content) ? content : content ? [{ type: "text", text: content }] : [];
|
|
716
|
+
content = [...parts, ...images];
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
return { ...rest, content };
|
|
720
|
+
});
|
|
721
|
+
}
|
|
640
722
|
/**
|
|
641
723
|
* Build the web_search tool for the Responses API, or undefined when web
|
|
642
724
|
* search is off.
|
|
@@ -718,13 +800,7 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
718
800
|
const toolCalls = Array.isArray(response?.output) ? response.output.filter((item) => item?.type === "function_call").map((item) => ({
|
|
719
801
|
id: item.call_id ?? item.id ?? generateToolCallId(),
|
|
720
802
|
name: item.name,
|
|
721
|
-
args: (
|
|
722
|
-
try {
|
|
723
|
-
return JSON.parse(item.arguments ?? "{}");
|
|
724
|
-
} catch {
|
|
725
|
-
return {};
|
|
726
|
-
}
|
|
727
|
-
})()
|
|
803
|
+
args: JSON.parse(item.arguments ?? "{}")
|
|
728
804
|
})) : [];
|
|
729
805
|
return {
|
|
730
806
|
content,
|
|
@@ -748,18 +824,19 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
748
824
|
instructions: request.systemPrompt,
|
|
749
825
|
input: this.buildResponsesInput(request),
|
|
750
826
|
tools: this.buildResponsesTools(
|
|
751
|
-
|
|
827
|
+
this.toolDefinitions(request),
|
|
752
828
|
request.providerToolOptions?.openai?.nativeToolSearch?.enabled === true,
|
|
753
829
|
this.buildResponsesWebSearchTool(request)
|
|
754
830
|
),
|
|
755
|
-
tool_choice: openaiToolOptions?.toolChoice
|
|
831
|
+
tool_choice: openaiToolOptions?.toolChoice,
|
|
756
832
|
parallel_tool_calls: openaiToolOptions?.parallelToolCalls,
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
833
|
+
...buildOpenAIParameters(
|
|
834
|
+
modelIdForPayload,
|
|
835
|
+
request.config?.maxTokens ?? this.config.maxTokens,
|
|
836
|
+
request.config?.temperature ?? this.config.temperature,
|
|
837
|
+
this.parameterOptions(request),
|
|
838
|
+
"responses"
|
|
839
|
+
),
|
|
763
840
|
...responsesTextFormat ? { text: { format: responsesTextFormat } } : {},
|
|
764
841
|
stream
|
|
765
842
|
};
|
|
@@ -767,10 +844,26 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
767
844
|
}
|
|
768
845
|
async completeWithResponses(request) {
|
|
769
846
|
const client = await this.getClient();
|
|
847
|
+
throwIfAborted(request.signal);
|
|
770
848
|
const payload = this.buildResponsesPayload(request, false);
|
|
771
849
|
logProviderPayload("openai", "request payload", payload, request.debug);
|
|
772
|
-
|
|
850
|
+
if (!client.responses?.create)
|
|
851
|
+
throw new Error(
|
|
852
|
+
"This OpenAI client does not support Responses; install an openai version with Responses support."
|
|
853
|
+
);
|
|
854
|
+
const response = await client.responses.create(payload, {
|
|
855
|
+
signal: request.signal
|
|
856
|
+
});
|
|
857
|
+
throwIfAborted(request.signal);
|
|
773
858
|
logProviderPayload("openai", "response payload", response, request.debug);
|
|
859
|
+
if (response.status && response.status !== "completed") {
|
|
860
|
+
throw Object.assign(
|
|
861
|
+
new Error(
|
|
862
|
+
response.error?.message ?? `Responses request ${response.status}`
|
|
863
|
+
),
|
|
864
|
+
response.error
|
|
865
|
+
);
|
|
866
|
+
}
|
|
774
867
|
return this.parseResponsesResult(response);
|
|
775
868
|
}
|
|
776
869
|
/**
|
|
@@ -788,13 +881,26 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
788
881
|
*/
|
|
789
882
|
async *streamWithResponses(request) {
|
|
790
883
|
const client = await this.getClient();
|
|
884
|
+
throwIfAborted(request.signal);
|
|
791
885
|
const payload = this.buildResponsesPayload(request, true);
|
|
792
886
|
logProviderPayload("openai", "request payload", payload, request.debug);
|
|
793
|
-
|
|
887
|
+
if (!client.responses?.create)
|
|
888
|
+
throw new Error(
|
|
889
|
+
"This OpenAI client does not support Responses; install an openai version with Responses support."
|
|
890
|
+
);
|
|
891
|
+
const stream = await client.responses.create(payload, {
|
|
892
|
+
signal: request.signal
|
|
893
|
+
});
|
|
794
894
|
const toolCalls = /* @__PURE__ */ new Map();
|
|
795
895
|
let usage;
|
|
796
896
|
const citations = [];
|
|
897
|
+
let completed = false;
|
|
797
898
|
function* flushToolCalls() {
|
|
899
|
+
for (const call of toolCalls.values()) {
|
|
900
|
+
if (!call.name)
|
|
901
|
+
throw new Error("Responses tool call is missing its name");
|
|
902
|
+
JSON.parse(call.arguments || "{}");
|
|
903
|
+
}
|
|
798
904
|
for (const call of toolCalls.values()) {
|
|
799
905
|
yield { type: "action:start", id: call.id, name: call.name };
|
|
800
906
|
yield { type: "action:args", id: call.id, args: call.arguments };
|
|
@@ -803,7 +909,7 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
803
909
|
toolCalls.clear();
|
|
804
910
|
}
|
|
805
911
|
for await (const event of stream) {
|
|
806
|
-
|
|
912
|
+
throwIfAborted(request.signal);
|
|
807
913
|
logProviderPayload("openai", "stream chunk", event, request.debug);
|
|
808
914
|
const index = event?.output_index ?? 0;
|
|
809
915
|
switch (event?.type) {
|
|
@@ -833,8 +939,8 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
833
939
|
}
|
|
834
940
|
break;
|
|
835
941
|
}
|
|
836
|
-
case "response.completed":
|
|
837
|
-
|
|
942
|
+
case "response.completed": {
|
|
943
|
+
completed = true;
|
|
838
944
|
const found = this.collectResponsesCitations(
|
|
839
945
|
event.response?.output,
|
|
840
946
|
citations.length
|
|
@@ -850,13 +956,27 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
850
956
|
}
|
|
851
957
|
break;
|
|
852
958
|
}
|
|
853
|
-
case "
|
|
854
|
-
case "response.failed":
|
|
959
|
+
case "response.incomplete":
|
|
855
960
|
throw new Error(
|
|
856
|
-
|
|
961
|
+
`Responses stream incomplete: ${event.response?.incomplete_details?.reason ?? "unknown reason"}`
|
|
857
962
|
);
|
|
963
|
+
case "error":
|
|
964
|
+
case "response.failed": {
|
|
965
|
+
const details = event.response?.error ?? event;
|
|
966
|
+
throw Object.assign(
|
|
967
|
+
new Error(details.message ?? "Responses stream failed"),
|
|
968
|
+
{
|
|
969
|
+
code: details.code,
|
|
970
|
+
param: details.param,
|
|
971
|
+
status: details.status
|
|
972
|
+
}
|
|
973
|
+
);
|
|
974
|
+
}
|
|
858
975
|
}
|
|
859
976
|
}
|
|
977
|
+
throwIfAborted(request.signal);
|
|
978
|
+
if (!completed)
|
|
979
|
+
throw new Error("Responses stream ended without a completed response");
|
|
860
980
|
yield* flushToolCalls();
|
|
861
981
|
if (citations.length > 0) {
|
|
862
982
|
yield { type: "citation", citations: deduplicateCitations(citations) };
|
|
@@ -865,6 +985,7 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
865
985
|
yield { type: "done", usage };
|
|
866
986
|
}
|
|
867
987
|
async *stream(request) {
|
|
988
|
+
throwIfAborted(request.signal);
|
|
868
989
|
if (this.shouldUseResponsesApi(request)) {
|
|
869
990
|
const messageId2 = generateMessageId();
|
|
870
991
|
yield { type: "message:start", id: messageId2 };
|
|
@@ -872,47 +993,14 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
872
993
|
yield* this.streamWithResponses(request);
|
|
873
994
|
return;
|
|
874
995
|
} catch (error) {
|
|
875
|
-
yield
|
|
876
|
-
type: "error",
|
|
877
|
-
message: error instanceof Error ? error.message : "Unknown error",
|
|
878
|
-
code: "OPENAI_RESPONSES_ERROR"
|
|
879
|
-
};
|
|
996
|
+
yield providerErrorEvent(error, "OPENAI_RESPONSES_ERROR");
|
|
880
997
|
return;
|
|
881
998
|
}
|
|
882
999
|
}
|
|
883
1000
|
const client = await this.getClient();
|
|
884
1001
|
let messages;
|
|
885
1002
|
if (request.rawMessages && request.rawMessages.length > 0) {
|
|
886
|
-
const processedMessages = request.rawMessages
|
|
887
|
-
if (msg.role === "assistant" && Array.isArray(msg.tool_calls) && msg.tool_calls.length > 0 && msg.content === "") {
|
|
888
|
-
return { ...msg, content: null };
|
|
889
|
-
}
|
|
890
|
-
const hasAttachments = msg.attachments && Array.isArray(msg.attachments) && msg.attachments.length > 0;
|
|
891
|
-
if (hasAttachments) {
|
|
892
|
-
const content = [];
|
|
893
|
-
if (msg.content) {
|
|
894
|
-
content.push({ type: "text", text: msg.content });
|
|
895
|
-
}
|
|
896
|
-
for (const attachment of msg.attachments) {
|
|
897
|
-
if (attachment.type === "image") {
|
|
898
|
-
let imageUrl;
|
|
899
|
-
if (attachment.url) {
|
|
900
|
-
imageUrl = attachment.url;
|
|
901
|
-
} else if (attachment.data) {
|
|
902
|
-
imageUrl = attachment.data.startsWith("data:") ? attachment.data : `data:${attachment.mimeType || "image/png"};base64,${attachment.data}`;
|
|
903
|
-
} else {
|
|
904
|
-
continue;
|
|
905
|
-
}
|
|
906
|
-
content.push({
|
|
907
|
-
type: "image_url",
|
|
908
|
-
image_url: { url: imageUrl, detail: "auto" }
|
|
909
|
-
});
|
|
910
|
-
}
|
|
911
|
-
}
|
|
912
|
-
return { ...msg, content, attachments: void 0 };
|
|
913
|
-
}
|
|
914
|
-
return msg;
|
|
915
|
-
});
|
|
1003
|
+
const processedMessages = this.formatRawMessages(request.rawMessages);
|
|
916
1004
|
if (request.systemPrompt) {
|
|
917
1005
|
const hasSystem = processedMessages.some((m) => m.role === "system");
|
|
918
1006
|
if (!hasSystem) {
|
|
@@ -932,7 +1020,16 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
932
1020
|
request.systemPrompt
|
|
933
1021
|
);
|
|
934
1022
|
}
|
|
935
|
-
const tools = request.
|
|
1023
|
+
const tools = request.toolDefinitions?.length ? request.toolDefinitions.filter((tool) => tool.available !== false).map((tool) => ({
|
|
1024
|
+
type: "function",
|
|
1025
|
+
function: {
|
|
1026
|
+
name: tool.name,
|
|
1027
|
+
description: tool.description,
|
|
1028
|
+
parameters: normalizeObjectJsonSchema(
|
|
1029
|
+
tool.inputSchema
|
|
1030
|
+
)
|
|
1031
|
+
}
|
|
1032
|
+
})) : formatTools(request.actions ?? []);
|
|
936
1033
|
const webSearchConfig = request.webSearch ?? this.config.webSearch;
|
|
937
1034
|
if (webSearchConfig) {
|
|
938
1035
|
const webSearchTool = {
|
|
@@ -961,26 +1058,28 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
961
1058
|
tools: tools.length > 0 ? tools : void 0,
|
|
962
1059
|
tool_choice: tools.length > 0 ? toolChoice : void 0,
|
|
963
1060
|
parallel_tool_calls: tools.length > 0 ? openaiToolOptions?.parallelToolCalls : void 0,
|
|
964
|
-
...
|
|
1061
|
+
...buildOpenAIParameters(
|
|
965
1062
|
modelIdForPayload,
|
|
966
1063
|
request.config?.maxTokens ?? this.config.maxTokens,
|
|
967
|
-
request.config?.temperature ?? this.config.temperature
|
|
1064
|
+
request.config?.temperature ?? this.config.temperature,
|
|
1065
|
+
this.parameterOptions(request)
|
|
968
1066
|
),
|
|
969
1067
|
response_format: toOpenAIResponseFormat(request.config?.responseFormat),
|
|
970
1068
|
stream: true,
|
|
971
1069
|
stream_options: { include_usage: true }
|
|
972
1070
|
};
|
|
973
1071
|
logProviderPayload("openai", "request payload", payload, request.debug);
|
|
974
|
-
const stream = await client.chat.completions.create(payload
|
|
975
|
-
|
|
1072
|
+
const stream = await client.chat.completions.create(payload, {
|
|
1073
|
+
signal: request.signal
|
|
1074
|
+
});
|
|
1075
|
+
const toolCalls = /* @__PURE__ */ new Map();
|
|
1076
|
+
let finishReason;
|
|
976
1077
|
const collectedCitations = [];
|
|
977
1078
|
let citationIndex = 0;
|
|
978
1079
|
let usage;
|
|
979
1080
|
for await (const chunk of stream) {
|
|
980
1081
|
logProviderPayload("openai", "stream chunk", chunk, request.debug);
|
|
981
|
-
|
|
982
|
-
break;
|
|
983
|
-
}
|
|
1082
|
+
throwIfAborted(request.signal);
|
|
984
1083
|
const delta = chunk.choices[0]?.delta;
|
|
985
1084
|
const choice = chunk.choices[0];
|
|
986
1085
|
if (delta?.content) {
|
|
@@ -1003,38 +1102,19 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
1003
1102
|
}
|
|
1004
1103
|
}
|
|
1005
1104
|
}
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
};
|
|
1020
|
-
}
|
|
1021
|
-
const tcExtraContent = toolCall.extra_content;
|
|
1022
|
-
currentToolCall = {
|
|
1023
|
-
id: toolCall.id,
|
|
1024
|
-
name: toolCall.function?.name || "",
|
|
1025
|
-
arguments: toolCall.function?.arguments || "",
|
|
1026
|
-
...tcExtraContent ? { extra_content: tcExtraContent } : {}
|
|
1027
|
-
};
|
|
1028
|
-
yield {
|
|
1029
|
-
type: "action:start",
|
|
1030
|
-
id: currentToolCall.id,
|
|
1031
|
-
name: currentToolCall.name,
|
|
1032
|
-
...currentToolCall.extra_content ? { extra_content: currentToolCall.extra_content } : {}
|
|
1033
|
-
};
|
|
1034
|
-
} else if (currentToolCall && toolCall.function?.arguments) {
|
|
1035
|
-
currentToolCall.arguments += toolCall.function.arguments;
|
|
1036
|
-
}
|
|
1037
|
-
}
|
|
1105
|
+
for (const part of delta?.tool_calls ?? []) {
|
|
1106
|
+
const index = part.index ?? 0;
|
|
1107
|
+
const call = toolCalls.get(index) ?? {
|
|
1108
|
+
id: "",
|
|
1109
|
+
name: "",
|
|
1110
|
+
arguments: ""
|
|
1111
|
+
};
|
|
1112
|
+
if (part.id) call.id = part.id;
|
|
1113
|
+
if (part.function?.name) call.name += part.function.name;
|
|
1114
|
+
if (part.function?.arguments)
|
|
1115
|
+
call.arguments += part.function.arguments;
|
|
1116
|
+
if (part.extra_content) call.extra_content = part.extra_content;
|
|
1117
|
+
toolCalls.set(index, call);
|
|
1038
1118
|
}
|
|
1039
1119
|
if (chunk.usage) {
|
|
1040
1120
|
usage = {
|
|
@@ -1043,21 +1123,28 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
1043
1123
|
total_tokens: chunk.usage.total_tokens
|
|
1044
1124
|
};
|
|
1045
1125
|
}
|
|
1046
|
-
if (choice?.finish_reason)
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1126
|
+
if (choice?.finish_reason) finishReason = choice.finish_reason;
|
|
1127
|
+
}
|
|
1128
|
+
throwIfAborted(request.signal);
|
|
1129
|
+
if (!finishReason)
|
|
1130
|
+
throw new Error("OpenAI stream ended without a finish reason");
|
|
1131
|
+
if (toolCalls.size && !["tool_calls", "function_call"].includes(finishReason)) {
|
|
1132
|
+
throw new Error("OpenAI stream ended with incomplete tool calls");
|
|
1133
|
+
}
|
|
1134
|
+
for (const call of toolCalls.values()) {
|
|
1135
|
+
if (!call.id || !call.name)
|
|
1136
|
+
throw new Error("OpenAI stream contains an incomplete tool call");
|
|
1137
|
+
JSON.parse(call.arguments || "{}");
|
|
1138
|
+
}
|
|
1139
|
+
for (const call of toolCalls.values()) {
|
|
1140
|
+
yield {
|
|
1141
|
+
type: "action:start",
|
|
1142
|
+
id: call.id,
|
|
1143
|
+
name: call.name,
|
|
1144
|
+
...call.extra_content ? { extra_content: call.extra_content } : {}
|
|
1145
|
+
};
|
|
1146
|
+
yield { type: "action:args", id: call.id, args: call.arguments };
|
|
1147
|
+
yield { type: "action:end", id: call.id, name: call.name };
|
|
1061
1148
|
}
|
|
1062
1149
|
if (collectedCitations.length > 0) {
|
|
1063
1150
|
const uniqueCitations = deduplicateCitations(collectedCitations);
|
|
@@ -1066,26 +1153,18 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
1066
1153
|
yield { type: "message:end" };
|
|
1067
1154
|
yield { type: "done", usage };
|
|
1068
1155
|
} catch (error) {
|
|
1069
|
-
yield {
|
|
1070
|
-
type: "error",
|
|
1071
|
-
message: error instanceof Error ? error.message : "Unknown error",
|
|
1072
|
-
code: `${this.provider.toUpperCase()}_ERROR`
|
|
1073
|
-
};
|
|
1156
|
+
yield providerErrorEvent(error, `${this.provider.toUpperCase()}_ERROR`);
|
|
1074
1157
|
}
|
|
1075
1158
|
}
|
|
1076
1159
|
async complete(request) {
|
|
1160
|
+
throwIfAborted(request.signal);
|
|
1077
1161
|
if (this.shouldUseResponsesApi(request)) {
|
|
1078
1162
|
return this.completeWithResponses(request);
|
|
1079
1163
|
}
|
|
1080
1164
|
const client = await this.getClient();
|
|
1081
1165
|
let messages;
|
|
1082
1166
|
if (request.rawMessages && request.rawMessages.length > 0) {
|
|
1083
|
-
const sanitized = request.rawMessages
|
|
1084
|
-
if (msg.role === "assistant" && Array.isArray(msg.tool_calls) && msg.tool_calls.length > 0 && msg.content === "") {
|
|
1085
|
-
return { ...msg, content: null };
|
|
1086
|
-
}
|
|
1087
|
-
return msg;
|
|
1088
|
-
});
|
|
1167
|
+
const sanitized = this.formatRawMessages(request.rawMessages);
|
|
1089
1168
|
if (request.systemPrompt && !sanitized.some((message2) => message2.role === "system")) {
|
|
1090
1169
|
messages = [
|
|
1091
1170
|
{ role: "system", content: request.systemPrompt },
|
|
@@ -1100,7 +1179,16 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
1100
1179
|
request.systemPrompt
|
|
1101
1180
|
);
|
|
1102
1181
|
}
|
|
1103
|
-
const tools = request.
|
|
1182
|
+
const tools = request.toolDefinitions?.length ? request.toolDefinitions.filter((tool) => tool.available !== false).map((tool) => ({
|
|
1183
|
+
type: "function",
|
|
1184
|
+
function: {
|
|
1185
|
+
name: tool.name,
|
|
1186
|
+
description: tool.description,
|
|
1187
|
+
parameters: normalizeObjectJsonSchema(
|
|
1188
|
+
tool.inputSchema
|
|
1189
|
+
)
|
|
1190
|
+
}
|
|
1191
|
+
})) : formatTools(request.actions ?? []);
|
|
1104
1192
|
const openaiToolOptions = request.providerToolOptions?.openai;
|
|
1105
1193
|
const toolChoice = openaiToolOptions?.toolChoice && typeof openaiToolOptions.toolChoice === "object" ? {
|
|
1106
1194
|
type: "function",
|
|
@@ -1115,16 +1203,19 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
1115
1203
|
tools: tools.length > 0 ? tools : void 0,
|
|
1116
1204
|
tool_choice: tools.length > 0 ? toolChoice : void 0,
|
|
1117
1205
|
parallel_tool_calls: tools.length > 0 ? openaiToolOptions?.parallelToolCalls : void 0,
|
|
1118
|
-
...
|
|
1206
|
+
...buildOpenAIParameters(
|
|
1119
1207
|
modelIdForCompletePayload,
|
|
1120
1208
|
request.config?.maxTokens ?? this.config.maxTokens,
|
|
1121
|
-
request.config?.temperature ?? this.config.temperature
|
|
1209
|
+
request.config?.temperature ?? this.config.temperature,
|
|
1210
|
+
this.parameterOptions(request)
|
|
1122
1211
|
),
|
|
1123
1212
|
response_format: toOpenAIResponseFormat(request.config?.responseFormat),
|
|
1124
1213
|
stream: false
|
|
1125
1214
|
};
|
|
1126
1215
|
logProviderPayload("openai", "request payload", payload, request.debug);
|
|
1127
|
-
const response = await client.chat.completions.create(payload
|
|
1216
|
+
const response = await client.chat.completions.create(payload, {
|
|
1217
|
+
signal: request.signal
|
|
1218
|
+
});
|
|
1128
1219
|
logProviderPayload("openai", "response payload", response, request.debug);
|
|
1129
1220
|
const choice = response.choices?.[0];
|
|
1130
1221
|
const message = choice?.message;
|
|
@@ -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-BW3csYo5.mjs';
|
|
2
|
+
import { A as AIProvider } from '../../types-NOswlhm9.mjs';
|
|
3
3
|
import 'zod';
|
|
4
|
-
import '../../base-
|
|
4
|
+
import '../../base-CkeT7u-O.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-BW3csYo5.js';
|
|
2
|
+
import { A as AIProvider } from '../../types-DA54bSmX.js';
|
|
3
3
|
import 'zod';
|
|
4
|
-
import '../../base-
|
|
4
|
+
import '../../base-BdTpUAWI.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Together AI Provider
|