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