@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" };
|
|
@@ -445,6 +486,28 @@ function formatMessages(messages) {
|
|
|
445
486
|
});
|
|
446
487
|
}
|
|
447
488
|
|
|
489
|
+
// src/core/provider-error.ts
|
|
490
|
+
function providerErrorEvent(error, code) {
|
|
491
|
+
const details = error ?? {};
|
|
492
|
+
const event = {
|
|
493
|
+
type: "error",
|
|
494
|
+
message: error instanceof Error ? error.message : String(error),
|
|
495
|
+
code,
|
|
496
|
+
...typeof details.status === "number" ? { status: details.status } : {},
|
|
497
|
+
...typeof details.code === "string" ? { providerCode: details.code } : {},
|
|
498
|
+
...typeof details.param === "string" ? { param: details.param } : {},
|
|
499
|
+
...typeof details.request_id === "string" ? { requestId: details.request_id } : {}
|
|
500
|
+
};
|
|
501
|
+
Object.defineProperty(event, "cause", { value: error, enumerable: false });
|
|
502
|
+
return event;
|
|
503
|
+
}
|
|
504
|
+
function throwIfAborted(signal) {
|
|
505
|
+
if (!signal?.aborted) return;
|
|
506
|
+
const error = new Error("The operation was aborted");
|
|
507
|
+
error.name = "AbortError";
|
|
508
|
+
throw error;
|
|
509
|
+
}
|
|
510
|
+
|
|
448
511
|
// src/core/utils.ts
|
|
449
512
|
function generateId(prefix = "id") {
|
|
450
513
|
return `${prefix}_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
|
|
@@ -476,39 +539,38 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
476
539
|
const { default: OpenAI } = await import('openai');
|
|
477
540
|
this.client = new OpenAI({
|
|
478
541
|
apiKey: this.config.apiKey,
|
|
479
|
-
baseURL: this.config.baseUrl
|
|
542
|
+
baseURL: this.config.baseUrl,
|
|
543
|
+
organization: this.config.organization,
|
|
544
|
+
defaultHeaders: this.config.headers
|
|
480
545
|
});
|
|
481
546
|
}
|
|
482
547
|
return this.client;
|
|
483
548
|
}
|
|
549
|
+
parameterOptions(request) {
|
|
550
|
+
return {
|
|
551
|
+
...this.config,
|
|
552
|
+
reasoningEffort: request.config?.reasoningEffort ?? this.config.reasoningEffort
|
|
553
|
+
};
|
|
554
|
+
}
|
|
555
|
+
toolDefinitions(request) {
|
|
556
|
+
if (request.toolDefinitions?.length) return request.toolDefinitions;
|
|
557
|
+
return formatTools(request.actions ?? []).map((tool) => ({
|
|
558
|
+
name: tool.function.name,
|
|
559
|
+
description: tool.function.description ?? "",
|
|
560
|
+
location: "server",
|
|
561
|
+
inputSchema: tool.function.parameters
|
|
562
|
+
}));
|
|
563
|
+
}
|
|
484
564
|
shouldUseResponsesApi(request) {
|
|
485
|
-
|
|
486
|
-
if (
|
|
487
|
-
if (request.providerToolOptions?.openai?.nativeToolSearch?.enabled === true && request.providerToolOptions.openai.nativeToolSearch.useResponsesApi !== false) {
|
|
565
|
+
if (this.toolDefinitions(request).length === 0) return false;
|
|
566
|
+
if (request.providerToolOptions?.openai?.nativeToolSearch?.enabled === true && request.providerToolOptions.openai.nativeToolSearch.useResponsesApi !== false)
|
|
488
567
|
return true;
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
568
|
+
return requiresOpenAIResponses(
|
|
569
|
+
request.config?.model || this.model,
|
|
570
|
+
this.config.baseUrl,
|
|
571
|
+
this.parameterOptions(request)
|
|
492
572
|
);
|
|
493
573
|
}
|
|
494
|
-
/**
|
|
495
|
-
* Whether this model rejects function tools on /v1/chat/completions.
|
|
496
|
-
*
|
|
497
|
-
* Applies to OpenAI proper only — the adapter is reused for OpenAI-compatible
|
|
498
|
-
* providers (Azure, xAI, Google, Fireworks) whose endpoints have no such
|
|
499
|
-
* restriction and may not implement /v1/responses at all.
|
|
500
|
-
*/
|
|
501
|
-
requiresResponsesApiForTools(modelId) {
|
|
502
|
-
if (!modelId) return false;
|
|
503
|
-
if (!/^gpt-5\.(?:[4-9]|\d{2,})/i.test(modelId)) return false;
|
|
504
|
-
const baseUrl = this.config.baseUrl;
|
|
505
|
-
if (!baseUrl) return true;
|
|
506
|
-
try {
|
|
507
|
-
return new URL(baseUrl).hostname === "api.openai.com";
|
|
508
|
-
} catch {
|
|
509
|
-
return false;
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
574
|
/**
|
|
513
575
|
* Convert one message's content to Responses content parts.
|
|
514
576
|
*
|
|
@@ -539,7 +601,7 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
539
601
|
});
|
|
540
602
|
}
|
|
541
603
|
buildResponsesInput(request) {
|
|
542
|
-
const sourceMessages = request.rawMessages && request.rawMessages.length > 0 ? request.rawMessages : formatMessagesForOpenAI(request.messages, void 0);
|
|
604
|
+
const sourceMessages = request.rawMessages && request.rawMessages.length > 0 ? this.formatRawMessages(request.rawMessages) : formatMessagesForOpenAI(request.messages, void 0);
|
|
543
605
|
const input = [];
|
|
544
606
|
for (const message of sourceMessages) {
|
|
545
607
|
if (message.role === "system") {
|
|
@@ -589,6 +651,26 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
589
651
|
}
|
|
590
652
|
return input;
|
|
591
653
|
}
|
|
654
|
+
/** Preserve Copilot screenshot attachments on every OpenAI transport. */
|
|
655
|
+
formatRawMessages(messages) {
|
|
656
|
+
return messages.map((message) => {
|
|
657
|
+
const { attachments, ...rest } = message;
|
|
658
|
+
let content = message.content;
|
|
659
|
+
if (message.role === "assistant" && Array.isArray(message.tool_calls) && message.tool_calls.length > 0 && content === "") {
|
|
660
|
+
content = null;
|
|
661
|
+
}
|
|
662
|
+
if (Array.isArray(attachments) && attachments.length > 0) {
|
|
663
|
+
const images = attachments.filter((attachment) => attachment && typeof attachment === "object").map(
|
|
664
|
+
(attachment) => attachmentToOpenAIImage(attachment)
|
|
665
|
+
).filter((image) => image !== null);
|
|
666
|
+
if (images.length > 0) {
|
|
667
|
+
const parts = Array.isArray(content) ? content : content ? [{ type: "text", text: content }] : [];
|
|
668
|
+
content = [...parts, ...images];
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
return { ...rest, content };
|
|
672
|
+
});
|
|
673
|
+
}
|
|
592
674
|
/**
|
|
593
675
|
* Build the web_search tool for the Responses API, or undefined when web
|
|
594
676
|
* search is off.
|
|
@@ -670,13 +752,7 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
670
752
|
const toolCalls = Array.isArray(response?.output) ? response.output.filter((item) => item?.type === "function_call").map((item) => ({
|
|
671
753
|
id: item.call_id ?? item.id ?? generateToolCallId(),
|
|
672
754
|
name: item.name,
|
|
673
|
-
args: (
|
|
674
|
-
try {
|
|
675
|
-
return JSON.parse(item.arguments ?? "{}");
|
|
676
|
-
} catch {
|
|
677
|
-
return {};
|
|
678
|
-
}
|
|
679
|
-
})()
|
|
755
|
+
args: JSON.parse(item.arguments ?? "{}")
|
|
680
756
|
})) : [];
|
|
681
757
|
return {
|
|
682
758
|
content,
|
|
@@ -700,18 +776,19 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
700
776
|
instructions: request.systemPrompt,
|
|
701
777
|
input: this.buildResponsesInput(request),
|
|
702
778
|
tools: this.buildResponsesTools(
|
|
703
|
-
|
|
779
|
+
this.toolDefinitions(request),
|
|
704
780
|
request.providerToolOptions?.openai?.nativeToolSearch?.enabled === true,
|
|
705
781
|
this.buildResponsesWebSearchTool(request)
|
|
706
782
|
),
|
|
707
|
-
tool_choice: openaiToolOptions?.toolChoice
|
|
783
|
+
tool_choice: openaiToolOptions?.toolChoice,
|
|
708
784
|
parallel_tool_calls: openaiToolOptions?.parallelToolCalls,
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
785
|
+
...buildOpenAIParameters(
|
|
786
|
+
modelIdForPayload,
|
|
787
|
+
request.config?.maxTokens ?? this.config.maxTokens,
|
|
788
|
+
request.config?.temperature ?? this.config.temperature,
|
|
789
|
+
this.parameterOptions(request),
|
|
790
|
+
"responses"
|
|
791
|
+
),
|
|
715
792
|
...responsesTextFormat ? { text: { format: responsesTextFormat } } : {},
|
|
716
793
|
stream
|
|
717
794
|
};
|
|
@@ -719,10 +796,26 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
719
796
|
}
|
|
720
797
|
async completeWithResponses(request) {
|
|
721
798
|
const client = await this.getClient();
|
|
799
|
+
throwIfAborted(request.signal);
|
|
722
800
|
const payload = this.buildResponsesPayload(request, false);
|
|
723
801
|
logProviderPayload("openai", "request payload", payload, request.debug);
|
|
724
|
-
|
|
802
|
+
if (!client.responses?.create)
|
|
803
|
+
throw new Error(
|
|
804
|
+
"This OpenAI client does not support Responses; install an openai version with Responses support."
|
|
805
|
+
);
|
|
806
|
+
const response = await client.responses.create(payload, {
|
|
807
|
+
signal: request.signal
|
|
808
|
+
});
|
|
809
|
+
throwIfAborted(request.signal);
|
|
725
810
|
logProviderPayload("openai", "response payload", response, request.debug);
|
|
811
|
+
if (response.status && response.status !== "completed") {
|
|
812
|
+
throw Object.assign(
|
|
813
|
+
new Error(
|
|
814
|
+
response.error?.message ?? `Responses request ${response.status}`
|
|
815
|
+
),
|
|
816
|
+
response.error
|
|
817
|
+
);
|
|
818
|
+
}
|
|
726
819
|
return this.parseResponsesResult(response);
|
|
727
820
|
}
|
|
728
821
|
/**
|
|
@@ -740,13 +833,26 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
740
833
|
*/
|
|
741
834
|
async *streamWithResponses(request) {
|
|
742
835
|
const client = await this.getClient();
|
|
836
|
+
throwIfAborted(request.signal);
|
|
743
837
|
const payload = this.buildResponsesPayload(request, true);
|
|
744
838
|
logProviderPayload("openai", "request payload", payload, request.debug);
|
|
745
|
-
|
|
839
|
+
if (!client.responses?.create)
|
|
840
|
+
throw new Error(
|
|
841
|
+
"This OpenAI client does not support Responses; install an openai version with Responses support."
|
|
842
|
+
);
|
|
843
|
+
const stream = await client.responses.create(payload, {
|
|
844
|
+
signal: request.signal
|
|
845
|
+
});
|
|
746
846
|
const toolCalls = /* @__PURE__ */ new Map();
|
|
747
847
|
let usage;
|
|
748
848
|
const citations = [];
|
|
849
|
+
let completed = false;
|
|
749
850
|
function* flushToolCalls() {
|
|
851
|
+
for (const call of toolCalls.values()) {
|
|
852
|
+
if (!call.name)
|
|
853
|
+
throw new Error("Responses tool call is missing its name");
|
|
854
|
+
JSON.parse(call.arguments || "{}");
|
|
855
|
+
}
|
|
750
856
|
for (const call of toolCalls.values()) {
|
|
751
857
|
yield { type: "action:start", id: call.id, name: call.name };
|
|
752
858
|
yield { type: "action:args", id: call.id, args: call.arguments };
|
|
@@ -755,7 +861,7 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
755
861
|
toolCalls.clear();
|
|
756
862
|
}
|
|
757
863
|
for await (const event of stream) {
|
|
758
|
-
|
|
864
|
+
throwIfAborted(request.signal);
|
|
759
865
|
logProviderPayload("openai", "stream chunk", event, request.debug);
|
|
760
866
|
const index = event?.output_index ?? 0;
|
|
761
867
|
switch (event?.type) {
|
|
@@ -785,8 +891,8 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
785
891
|
}
|
|
786
892
|
break;
|
|
787
893
|
}
|
|
788
|
-
case "response.completed":
|
|
789
|
-
|
|
894
|
+
case "response.completed": {
|
|
895
|
+
completed = true;
|
|
790
896
|
const found = this.collectResponsesCitations(
|
|
791
897
|
event.response?.output,
|
|
792
898
|
citations.length
|
|
@@ -802,13 +908,27 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
802
908
|
}
|
|
803
909
|
break;
|
|
804
910
|
}
|
|
805
|
-
case "
|
|
806
|
-
case "response.failed":
|
|
911
|
+
case "response.incomplete":
|
|
807
912
|
throw new Error(
|
|
808
|
-
|
|
913
|
+
`Responses stream incomplete: ${event.response?.incomplete_details?.reason ?? "unknown reason"}`
|
|
809
914
|
);
|
|
915
|
+
case "error":
|
|
916
|
+
case "response.failed": {
|
|
917
|
+
const details = event.response?.error ?? event;
|
|
918
|
+
throw Object.assign(
|
|
919
|
+
new Error(details.message ?? "Responses stream failed"),
|
|
920
|
+
{
|
|
921
|
+
code: details.code,
|
|
922
|
+
param: details.param,
|
|
923
|
+
status: details.status
|
|
924
|
+
}
|
|
925
|
+
);
|
|
926
|
+
}
|
|
810
927
|
}
|
|
811
928
|
}
|
|
929
|
+
throwIfAborted(request.signal);
|
|
930
|
+
if (!completed)
|
|
931
|
+
throw new Error("Responses stream ended without a completed response");
|
|
812
932
|
yield* flushToolCalls();
|
|
813
933
|
if (citations.length > 0) {
|
|
814
934
|
yield { type: "citation", citations: deduplicateCitations(citations) };
|
|
@@ -817,6 +937,7 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
817
937
|
yield { type: "done", usage };
|
|
818
938
|
}
|
|
819
939
|
async *stream(request) {
|
|
940
|
+
throwIfAborted(request.signal);
|
|
820
941
|
if (this.shouldUseResponsesApi(request)) {
|
|
821
942
|
const messageId2 = generateMessageId();
|
|
822
943
|
yield { type: "message:start", id: messageId2 };
|
|
@@ -824,47 +945,14 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
824
945
|
yield* this.streamWithResponses(request);
|
|
825
946
|
return;
|
|
826
947
|
} catch (error) {
|
|
827
|
-
yield
|
|
828
|
-
type: "error",
|
|
829
|
-
message: error instanceof Error ? error.message : "Unknown error",
|
|
830
|
-
code: "OPENAI_RESPONSES_ERROR"
|
|
831
|
-
};
|
|
948
|
+
yield providerErrorEvent(error, "OPENAI_RESPONSES_ERROR");
|
|
832
949
|
return;
|
|
833
950
|
}
|
|
834
951
|
}
|
|
835
952
|
const client = await this.getClient();
|
|
836
953
|
let messages;
|
|
837
954
|
if (request.rawMessages && request.rawMessages.length > 0) {
|
|
838
|
-
const processedMessages = request.rawMessages
|
|
839
|
-
if (msg.role === "assistant" && Array.isArray(msg.tool_calls) && msg.tool_calls.length > 0 && msg.content === "") {
|
|
840
|
-
return { ...msg, content: null };
|
|
841
|
-
}
|
|
842
|
-
const hasAttachments = msg.attachments && Array.isArray(msg.attachments) && msg.attachments.length > 0;
|
|
843
|
-
if (hasAttachments) {
|
|
844
|
-
const content = [];
|
|
845
|
-
if (msg.content) {
|
|
846
|
-
content.push({ type: "text", text: msg.content });
|
|
847
|
-
}
|
|
848
|
-
for (const attachment of msg.attachments) {
|
|
849
|
-
if (attachment.type === "image") {
|
|
850
|
-
let imageUrl;
|
|
851
|
-
if (attachment.url) {
|
|
852
|
-
imageUrl = attachment.url;
|
|
853
|
-
} else if (attachment.data) {
|
|
854
|
-
imageUrl = attachment.data.startsWith("data:") ? attachment.data : `data:${attachment.mimeType || "image/png"};base64,${attachment.data}`;
|
|
855
|
-
} else {
|
|
856
|
-
continue;
|
|
857
|
-
}
|
|
858
|
-
content.push({
|
|
859
|
-
type: "image_url",
|
|
860
|
-
image_url: { url: imageUrl, detail: "auto" }
|
|
861
|
-
});
|
|
862
|
-
}
|
|
863
|
-
}
|
|
864
|
-
return { ...msg, content, attachments: void 0 };
|
|
865
|
-
}
|
|
866
|
-
return msg;
|
|
867
|
-
});
|
|
955
|
+
const processedMessages = this.formatRawMessages(request.rawMessages);
|
|
868
956
|
if (request.systemPrompt) {
|
|
869
957
|
const hasSystem = processedMessages.some((m) => m.role === "system");
|
|
870
958
|
if (!hasSystem) {
|
|
@@ -884,7 +972,16 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
884
972
|
request.systemPrompt
|
|
885
973
|
);
|
|
886
974
|
}
|
|
887
|
-
const tools = request.
|
|
975
|
+
const tools = request.toolDefinitions?.length ? request.toolDefinitions.filter((tool) => tool.available !== false).map((tool) => ({
|
|
976
|
+
type: "function",
|
|
977
|
+
function: {
|
|
978
|
+
name: tool.name,
|
|
979
|
+
description: tool.description,
|
|
980
|
+
parameters: normalizeObjectJsonSchema(
|
|
981
|
+
tool.inputSchema
|
|
982
|
+
)
|
|
983
|
+
}
|
|
984
|
+
})) : formatTools(request.actions ?? []);
|
|
888
985
|
const webSearchConfig = request.webSearch ?? this.config.webSearch;
|
|
889
986
|
if (webSearchConfig) {
|
|
890
987
|
const webSearchTool = {
|
|
@@ -913,26 +1010,28 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
913
1010
|
tools: tools.length > 0 ? tools : void 0,
|
|
914
1011
|
tool_choice: tools.length > 0 ? toolChoice : void 0,
|
|
915
1012
|
parallel_tool_calls: tools.length > 0 ? openaiToolOptions?.parallelToolCalls : void 0,
|
|
916
|
-
...
|
|
1013
|
+
...buildOpenAIParameters(
|
|
917
1014
|
modelIdForPayload,
|
|
918
1015
|
request.config?.maxTokens ?? this.config.maxTokens,
|
|
919
|
-
request.config?.temperature ?? this.config.temperature
|
|
1016
|
+
request.config?.temperature ?? this.config.temperature,
|
|
1017
|
+
this.parameterOptions(request)
|
|
920
1018
|
),
|
|
921
1019
|
response_format: toOpenAIResponseFormat(request.config?.responseFormat),
|
|
922
1020
|
stream: true,
|
|
923
1021
|
stream_options: { include_usage: true }
|
|
924
1022
|
};
|
|
925
1023
|
logProviderPayload("openai", "request payload", payload, request.debug);
|
|
926
|
-
const stream = await client.chat.completions.create(payload
|
|
927
|
-
|
|
1024
|
+
const stream = await client.chat.completions.create(payload, {
|
|
1025
|
+
signal: request.signal
|
|
1026
|
+
});
|
|
1027
|
+
const toolCalls = /* @__PURE__ */ new Map();
|
|
1028
|
+
let finishReason;
|
|
928
1029
|
const collectedCitations = [];
|
|
929
1030
|
let citationIndex = 0;
|
|
930
1031
|
let usage;
|
|
931
1032
|
for await (const chunk of stream) {
|
|
932
1033
|
logProviderPayload("openai", "stream chunk", chunk, request.debug);
|
|
933
|
-
|
|
934
|
-
break;
|
|
935
|
-
}
|
|
1034
|
+
throwIfAborted(request.signal);
|
|
936
1035
|
const delta = chunk.choices[0]?.delta;
|
|
937
1036
|
const choice = chunk.choices[0];
|
|
938
1037
|
if (delta?.content) {
|
|
@@ -955,38 +1054,19 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
955
1054
|
}
|
|
956
1055
|
}
|
|
957
1056
|
}
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
};
|
|
972
|
-
}
|
|
973
|
-
const tcExtraContent = toolCall.extra_content;
|
|
974
|
-
currentToolCall = {
|
|
975
|
-
id: toolCall.id,
|
|
976
|
-
name: toolCall.function?.name || "",
|
|
977
|
-
arguments: toolCall.function?.arguments || "",
|
|
978
|
-
...tcExtraContent ? { extra_content: tcExtraContent } : {}
|
|
979
|
-
};
|
|
980
|
-
yield {
|
|
981
|
-
type: "action:start",
|
|
982
|
-
id: currentToolCall.id,
|
|
983
|
-
name: currentToolCall.name,
|
|
984
|
-
...currentToolCall.extra_content ? { extra_content: currentToolCall.extra_content } : {}
|
|
985
|
-
};
|
|
986
|
-
} else if (currentToolCall && toolCall.function?.arguments) {
|
|
987
|
-
currentToolCall.arguments += toolCall.function.arguments;
|
|
988
|
-
}
|
|
989
|
-
}
|
|
1057
|
+
for (const part of delta?.tool_calls ?? []) {
|
|
1058
|
+
const index = part.index ?? 0;
|
|
1059
|
+
const call = toolCalls.get(index) ?? {
|
|
1060
|
+
id: "",
|
|
1061
|
+
name: "",
|
|
1062
|
+
arguments: ""
|
|
1063
|
+
};
|
|
1064
|
+
if (part.id) call.id = part.id;
|
|
1065
|
+
if (part.function?.name) call.name += part.function.name;
|
|
1066
|
+
if (part.function?.arguments)
|
|
1067
|
+
call.arguments += part.function.arguments;
|
|
1068
|
+
if (part.extra_content) call.extra_content = part.extra_content;
|
|
1069
|
+
toolCalls.set(index, call);
|
|
990
1070
|
}
|
|
991
1071
|
if (chunk.usage) {
|
|
992
1072
|
usage = {
|
|
@@ -995,21 +1075,28 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
995
1075
|
total_tokens: chunk.usage.total_tokens
|
|
996
1076
|
};
|
|
997
1077
|
}
|
|
998
|
-
if (choice?.finish_reason)
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1078
|
+
if (choice?.finish_reason) finishReason = choice.finish_reason;
|
|
1079
|
+
}
|
|
1080
|
+
throwIfAborted(request.signal);
|
|
1081
|
+
if (!finishReason)
|
|
1082
|
+
throw new Error("OpenAI stream ended without a finish reason");
|
|
1083
|
+
if (toolCalls.size && !["tool_calls", "function_call"].includes(finishReason)) {
|
|
1084
|
+
throw new Error("OpenAI stream ended with incomplete tool calls");
|
|
1085
|
+
}
|
|
1086
|
+
for (const call of toolCalls.values()) {
|
|
1087
|
+
if (!call.id || !call.name)
|
|
1088
|
+
throw new Error("OpenAI stream contains an incomplete tool call");
|
|
1089
|
+
JSON.parse(call.arguments || "{}");
|
|
1090
|
+
}
|
|
1091
|
+
for (const call of toolCalls.values()) {
|
|
1092
|
+
yield {
|
|
1093
|
+
type: "action:start",
|
|
1094
|
+
id: call.id,
|
|
1095
|
+
name: call.name,
|
|
1096
|
+
...call.extra_content ? { extra_content: call.extra_content } : {}
|
|
1097
|
+
};
|
|
1098
|
+
yield { type: "action:args", id: call.id, args: call.arguments };
|
|
1099
|
+
yield { type: "action:end", id: call.id, name: call.name };
|
|
1013
1100
|
}
|
|
1014
1101
|
if (collectedCitations.length > 0) {
|
|
1015
1102
|
const uniqueCitations = deduplicateCitations(collectedCitations);
|
|
@@ -1018,26 +1105,18 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
1018
1105
|
yield { type: "message:end" };
|
|
1019
1106
|
yield { type: "done", usage };
|
|
1020
1107
|
} catch (error) {
|
|
1021
|
-
yield {
|
|
1022
|
-
type: "error",
|
|
1023
|
-
message: error instanceof Error ? error.message : "Unknown error",
|
|
1024
|
-
code: `${this.provider.toUpperCase()}_ERROR`
|
|
1025
|
-
};
|
|
1108
|
+
yield providerErrorEvent(error, `${this.provider.toUpperCase()}_ERROR`);
|
|
1026
1109
|
}
|
|
1027
1110
|
}
|
|
1028
1111
|
async complete(request) {
|
|
1112
|
+
throwIfAborted(request.signal);
|
|
1029
1113
|
if (this.shouldUseResponsesApi(request)) {
|
|
1030
1114
|
return this.completeWithResponses(request);
|
|
1031
1115
|
}
|
|
1032
1116
|
const client = await this.getClient();
|
|
1033
1117
|
let messages;
|
|
1034
1118
|
if (request.rawMessages && request.rawMessages.length > 0) {
|
|
1035
|
-
const sanitized = request.rawMessages
|
|
1036
|
-
if (msg.role === "assistant" && Array.isArray(msg.tool_calls) && msg.tool_calls.length > 0 && msg.content === "") {
|
|
1037
|
-
return { ...msg, content: null };
|
|
1038
|
-
}
|
|
1039
|
-
return msg;
|
|
1040
|
-
});
|
|
1119
|
+
const sanitized = this.formatRawMessages(request.rawMessages);
|
|
1041
1120
|
if (request.systemPrompt && !sanitized.some((message2) => message2.role === "system")) {
|
|
1042
1121
|
messages = [
|
|
1043
1122
|
{ role: "system", content: request.systemPrompt },
|
|
@@ -1052,7 +1131,16 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
1052
1131
|
request.systemPrompt
|
|
1053
1132
|
);
|
|
1054
1133
|
}
|
|
1055
|
-
const tools = request.
|
|
1134
|
+
const tools = request.toolDefinitions?.length ? request.toolDefinitions.filter((tool) => tool.available !== false).map((tool) => ({
|
|
1135
|
+
type: "function",
|
|
1136
|
+
function: {
|
|
1137
|
+
name: tool.name,
|
|
1138
|
+
description: tool.description,
|
|
1139
|
+
parameters: normalizeObjectJsonSchema(
|
|
1140
|
+
tool.inputSchema
|
|
1141
|
+
)
|
|
1142
|
+
}
|
|
1143
|
+
})) : formatTools(request.actions ?? []);
|
|
1056
1144
|
const openaiToolOptions = request.providerToolOptions?.openai;
|
|
1057
1145
|
const toolChoice = openaiToolOptions?.toolChoice && typeof openaiToolOptions.toolChoice === "object" ? {
|
|
1058
1146
|
type: "function",
|
|
@@ -1067,16 +1155,19 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
1067
1155
|
tools: tools.length > 0 ? tools : void 0,
|
|
1068
1156
|
tool_choice: tools.length > 0 ? toolChoice : void 0,
|
|
1069
1157
|
parallel_tool_calls: tools.length > 0 ? openaiToolOptions?.parallelToolCalls : void 0,
|
|
1070
|
-
...
|
|
1158
|
+
...buildOpenAIParameters(
|
|
1071
1159
|
modelIdForCompletePayload,
|
|
1072
1160
|
request.config?.maxTokens ?? this.config.maxTokens,
|
|
1073
|
-
request.config?.temperature ?? this.config.temperature
|
|
1161
|
+
request.config?.temperature ?? this.config.temperature,
|
|
1162
|
+
this.parameterOptions(request)
|
|
1074
1163
|
),
|
|
1075
1164
|
response_format: toOpenAIResponseFormat(request.config?.responseFormat),
|
|
1076
1165
|
stream: false
|
|
1077
1166
|
};
|
|
1078
1167
|
logProviderPayload("openai", "request payload", payload, request.debug);
|
|
1079
|
-
const response = await client.chat.completions.create(payload
|
|
1168
|
+
const response = await client.chat.completions.create(payload, {
|
|
1169
|
+
signal: request.signal
|
|
1170
|
+
});
|
|
1080
1171
|
logProviderPayload("openai", "response payload", response, request.debug);
|
|
1081
1172
|
const choice = response.choices?.[0];
|
|
1082
1173
|
const message = choice?.message;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { L as LanguageModel } from '../../types-
|
|
2
|
-
import { X as XAIProviderConfig, A as AIProvider } from '../../types-
|
|
1
|
+
import { L as LanguageModel } from '../../types-BW3csYo5.mjs';
|
|
2
|
+
import { X as XAIProviderConfig, 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
|
* xAI Provider - Modern Pattern
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { L as LanguageModel } from '../../types-
|
|
2
|
-
import { X as XAIProviderConfig, A as AIProvider } from '../../types-
|
|
1
|
+
import { L as LanguageModel } from '../../types-BW3csYo5.js';
|
|
2
|
+
import { X as XAIProviderConfig, 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
|
* xAI Provider - Modern Pattern
|