@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
package/dist/adapters/index.mjs
CHANGED
|
@@ -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(
|
|
@@ -117,16 +168,6 @@ function normalizeObjectJsonSchema(schema) {
|
|
|
117
168
|
}
|
|
118
169
|
return normalized;
|
|
119
170
|
}
|
|
120
|
-
function isOpenAIReasoningModel(modelId) {
|
|
121
|
-
if (!modelId) return false;
|
|
122
|
-
return /^(o1|o3|o4|gpt-5)/i.test(modelId);
|
|
123
|
-
}
|
|
124
|
-
function buildOpenAITokenParams(modelId, maxTokens, temperature) {
|
|
125
|
-
if (isOpenAIReasoningModel(modelId)) {
|
|
126
|
-
return { max_completion_tokens: maxTokens };
|
|
127
|
-
}
|
|
128
|
-
return { max_tokens: maxTokens, temperature };
|
|
129
|
-
}
|
|
130
171
|
function stripSchemaKeys(schema, keysToDrop, options = {}) {
|
|
131
172
|
if (Array.isArray(schema)) {
|
|
132
173
|
return schema.map((item) => stripSchemaKeys(item, keysToDrop, options));
|
|
@@ -473,6 +514,28 @@ function formatMessagesForOpenAI(messages, systemPrompt) {
|
|
|
473
514
|
return formatted;
|
|
474
515
|
}
|
|
475
516
|
|
|
517
|
+
// src/core/provider-error.ts
|
|
518
|
+
function providerErrorEvent(error, code) {
|
|
519
|
+
const details = error ?? {};
|
|
520
|
+
const event = {
|
|
521
|
+
type: "error",
|
|
522
|
+
message: error instanceof Error ? error.message : String(error),
|
|
523
|
+
code,
|
|
524
|
+
...typeof details.status === "number" ? { status: details.status } : {},
|
|
525
|
+
...typeof details.code === "string" ? { providerCode: details.code } : {},
|
|
526
|
+
...typeof details.param === "string" ? { param: details.param } : {},
|
|
527
|
+
...typeof details.request_id === "string" ? { requestId: details.request_id } : {}
|
|
528
|
+
};
|
|
529
|
+
Object.defineProperty(event, "cause", { value: error, enumerable: false });
|
|
530
|
+
return event;
|
|
531
|
+
}
|
|
532
|
+
function throwIfAborted(signal) {
|
|
533
|
+
if (!signal?.aborted) return;
|
|
534
|
+
const error = new Error("The operation was aborted");
|
|
535
|
+
error.name = "AbortError";
|
|
536
|
+
throw error;
|
|
537
|
+
}
|
|
538
|
+
|
|
476
539
|
// src/core/utils.ts
|
|
477
540
|
function generateId(prefix = "id") {
|
|
478
541
|
return `${prefix}_${Date.now()}_${Math.random().toString(36).substring(2, 9)}`;
|
|
@@ -504,39 +567,38 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
504
567
|
const { default: OpenAI } = await import('openai');
|
|
505
568
|
this.client = new OpenAI({
|
|
506
569
|
apiKey: this.config.apiKey,
|
|
507
|
-
baseURL: this.config.baseUrl
|
|
570
|
+
baseURL: this.config.baseUrl,
|
|
571
|
+
organization: this.config.organization,
|
|
572
|
+
defaultHeaders: this.config.headers
|
|
508
573
|
});
|
|
509
574
|
}
|
|
510
575
|
return this.client;
|
|
511
576
|
}
|
|
577
|
+
parameterOptions(request) {
|
|
578
|
+
return {
|
|
579
|
+
...this.config,
|
|
580
|
+
reasoningEffort: request.config?.reasoningEffort ?? this.config.reasoningEffort
|
|
581
|
+
};
|
|
582
|
+
}
|
|
583
|
+
toolDefinitions(request) {
|
|
584
|
+
if (request.toolDefinitions?.length) return request.toolDefinitions;
|
|
585
|
+
return formatTools(request.actions ?? []).map((tool) => ({
|
|
586
|
+
name: tool.function.name,
|
|
587
|
+
description: tool.function.description ?? "",
|
|
588
|
+
location: "server",
|
|
589
|
+
inputSchema: tool.function.parameters
|
|
590
|
+
}));
|
|
591
|
+
}
|
|
512
592
|
shouldUseResponsesApi(request) {
|
|
513
|
-
|
|
514
|
-
if (
|
|
515
|
-
if (request.providerToolOptions?.openai?.nativeToolSearch?.enabled === true && request.providerToolOptions.openai.nativeToolSearch.useResponsesApi !== false) {
|
|
593
|
+
if (this.toolDefinitions(request).length === 0) return false;
|
|
594
|
+
if (request.providerToolOptions?.openai?.nativeToolSearch?.enabled === true && request.providerToolOptions.openai.nativeToolSearch.useResponsesApi !== false)
|
|
516
595
|
return true;
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
596
|
+
return requiresOpenAIResponses(
|
|
597
|
+
request.config?.model || this.model,
|
|
598
|
+
this.config.baseUrl,
|
|
599
|
+
this.parameterOptions(request)
|
|
520
600
|
);
|
|
521
601
|
}
|
|
522
|
-
/**
|
|
523
|
-
* Whether this model rejects function tools on /v1/chat/completions.
|
|
524
|
-
*
|
|
525
|
-
* Applies to OpenAI proper only — the adapter is reused for OpenAI-compatible
|
|
526
|
-
* providers (Azure, xAI, Google, Fireworks) whose endpoints have no such
|
|
527
|
-
* restriction and may not implement /v1/responses at all.
|
|
528
|
-
*/
|
|
529
|
-
requiresResponsesApiForTools(modelId) {
|
|
530
|
-
if (!modelId) return false;
|
|
531
|
-
if (!/^gpt-5\.(?:[4-9]|\d{2,})/i.test(modelId)) return false;
|
|
532
|
-
const baseUrl = this.config.baseUrl;
|
|
533
|
-
if (!baseUrl) return true;
|
|
534
|
-
try {
|
|
535
|
-
return new URL(baseUrl).hostname === "api.openai.com";
|
|
536
|
-
} catch {
|
|
537
|
-
return false;
|
|
538
|
-
}
|
|
539
|
-
}
|
|
540
602
|
/**
|
|
541
603
|
* Convert one message's content to Responses content parts.
|
|
542
604
|
*
|
|
@@ -567,7 +629,7 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
567
629
|
});
|
|
568
630
|
}
|
|
569
631
|
buildResponsesInput(request) {
|
|
570
|
-
const sourceMessages = request.rawMessages && request.rawMessages.length > 0 ? request.rawMessages : formatMessagesForOpenAI(request.messages, void 0);
|
|
632
|
+
const sourceMessages = request.rawMessages && request.rawMessages.length > 0 ? this.formatRawMessages(request.rawMessages) : formatMessagesForOpenAI(request.messages, void 0);
|
|
571
633
|
const input = [];
|
|
572
634
|
for (const message of sourceMessages) {
|
|
573
635
|
if (message.role === "system") {
|
|
@@ -617,6 +679,26 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
617
679
|
}
|
|
618
680
|
return input;
|
|
619
681
|
}
|
|
682
|
+
/** Preserve Copilot screenshot attachments on every OpenAI transport. */
|
|
683
|
+
formatRawMessages(messages) {
|
|
684
|
+
return messages.map((message) => {
|
|
685
|
+
const { attachments, ...rest } = message;
|
|
686
|
+
let content = message.content;
|
|
687
|
+
if (message.role === "assistant" && Array.isArray(message.tool_calls) && message.tool_calls.length > 0 && content === "") {
|
|
688
|
+
content = null;
|
|
689
|
+
}
|
|
690
|
+
if (Array.isArray(attachments) && attachments.length > 0) {
|
|
691
|
+
const images = attachments.filter((attachment) => attachment && typeof attachment === "object").map(
|
|
692
|
+
(attachment) => attachmentToOpenAIImage(attachment)
|
|
693
|
+
).filter((image) => image !== null);
|
|
694
|
+
if (images.length > 0) {
|
|
695
|
+
const parts = Array.isArray(content) ? content : content ? [{ type: "text", text: content }] : [];
|
|
696
|
+
content = [...parts, ...images];
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
return { ...rest, content };
|
|
700
|
+
});
|
|
701
|
+
}
|
|
620
702
|
/**
|
|
621
703
|
* Build the web_search tool for the Responses API, or undefined when web
|
|
622
704
|
* search is off.
|
|
@@ -698,13 +780,7 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
698
780
|
const toolCalls = Array.isArray(response?.output) ? response.output.filter((item) => item?.type === "function_call").map((item) => ({
|
|
699
781
|
id: item.call_id ?? item.id ?? generateToolCallId(),
|
|
700
782
|
name: item.name,
|
|
701
|
-
args: (
|
|
702
|
-
try {
|
|
703
|
-
return JSON.parse(item.arguments ?? "{}");
|
|
704
|
-
} catch {
|
|
705
|
-
return {};
|
|
706
|
-
}
|
|
707
|
-
})()
|
|
783
|
+
args: JSON.parse(item.arguments ?? "{}")
|
|
708
784
|
})) : [];
|
|
709
785
|
return {
|
|
710
786
|
content,
|
|
@@ -728,18 +804,19 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
728
804
|
instructions: request.systemPrompt,
|
|
729
805
|
input: this.buildResponsesInput(request),
|
|
730
806
|
tools: this.buildResponsesTools(
|
|
731
|
-
|
|
807
|
+
this.toolDefinitions(request),
|
|
732
808
|
request.providerToolOptions?.openai?.nativeToolSearch?.enabled === true,
|
|
733
809
|
this.buildResponsesWebSearchTool(request)
|
|
734
810
|
),
|
|
735
|
-
tool_choice: openaiToolOptions?.toolChoice
|
|
811
|
+
tool_choice: openaiToolOptions?.toolChoice,
|
|
736
812
|
parallel_tool_calls: openaiToolOptions?.parallelToolCalls,
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
813
|
+
...buildOpenAIParameters(
|
|
814
|
+
modelIdForPayload,
|
|
815
|
+
request.config?.maxTokens ?? this.config.maxTokens,
|
|
816
|
+
request.config?.temperature ?? this.config.temperature,
|
|
817
|
+
this.parameterOptions(request),
|
|
818
|
+
"responses"
|
|
819
|
+
),
|
|
743
820
|
...responsesTextFormat ? { text: { format: responsesTextFormat } } : {},
|
|
744
821
|
stream
|
|
745
822
|
};
|
|
@@ -747,10 +824,26 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
747
824
|
}
|
|
748
825
|
async completeWithResponses(request) {
|
|
749
826
|
const client = await this.getClient();
|
|
827
|
+
throwIfAborted(request.signal);
|
|
750
828
|
const payload = this.buildResponsesPayload(request, false);
|
|
751
829
|
logProviderPayload("openai", "request payload", payload, request.debug);
|
|
752
|
-
|
|
830
|
+
if (!client.responses?.create)
|
|
831
|
+
throw new Error(
|
|
832
|
+
"This OpenAI client does not support Responses; install an openai version with Responses support."
|
|
833
|
+
);
|
|
834
|
+
const response = await client.responses.create(payload, {
|
|
835
|
+
signal: request.signal
|
|
836
|
+
});
|
|
837
|
+
throwIfAborted(request.signal);
|
|
753
838
|
logProviderPayload("openai", "response payload", response, request.debug);
|
|
839
|
+
if (response.status && response.status !== "completed") {
|
|
840
|
+
throw Object.assign(
|
|
841
|
+
new Error(
|
|
842
|
+
response.error?.message ?? `Responses request ${response.status}`
|
|
843
|
+
),
|
|
844
|
+
response.error
|
|
845
|
+
);
|
|
846
|
+
}
|
|
754
847
|
return this.parseResponsesResult(response);
|
|
755
848
|
}
|
|
756
849
|
/**
|
|
@@ -768,13 +861,26 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
768
861
|
*/
|
|
769
862
|
async *streamWithResponses(request) {
|
|
770
863
|
const client = await this.getClient();
|
|
864
|
+
throwIfAborted(request.signal);
|
|
771
865
|
const payload = this.buildResponsesPayload(request, true);
|
|
772
866
|
logProviderPayload("openai", "request payload", payload, request.debug);
|
|
773
|
-
|
|
867
|
+
if (!client.responses?.create)
|
|
868
|
+
throw new Error(
|
|
869
|
+
"This OpenAI client does not support Responses; install an openai version with Responses support."
|
|
870
|
+
);
|
|
871
|
+
const stream = await client.responses.create(payload, {
|
|
872
|
+
signal: request.signal
|
|
873
|
+
});
|
|
774
874
|
const toolCalls = /* @__PURE__ */ new Map();
|
|
775
875
|
let usage;
|
|
776
876
|
const citations = [];
|
|
877
|
+
let completed = false;
|
|
777
878
|
function* flushToolCalls() {
|
|
879
|
+
for (const call of toolCalls.values()) {
|
|
880
|
+
if (!call.name)
|
|
881
|
+
throw new Error("Responses tool call is missing its name");
|
|
882
|
+
JSON.parse(call.arguments || "{}");
|
|
883
|
+
}
|
|
778
884
|
for (const call of toolCalls.values()) {
|
|
779
885
|
yield { type: "action:start", id: call.id, name: call.name };
|
|
780
886
|
yield { type: "action:args", id: call.id, args: call.arguments };
|
|
@@ -783,7 +889,7 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
783
889
|
toolCalls.clear();
|
|
784
890
|
}
|
|
785
891
|
for await (const event of stream) {
|
|
786
|
-
|
|
892
|
+
throwIfAborted(request.signal);
|
|
787
893
|
logProviderPayload("openai", "stream chunk", event, request.debug);
|
|
788
894
|
const index = event?.output_index ?? 0;
|
|
789
895
|
switch (event?.type) {
|
|
@@ -813,8 +919,8 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
813
919
|
}
|
|
814
920
|
break;
|
|
815
921
|
}
|
|
816
|
-
case "response.completed":
|
|
817
|
-
|
|
922
|
+
case "response.completed": {
|
|
923
|
+
completed = true;
|
|
818
924
|
const found = this.collectResponsesCitations(
|
|
819
925
|
event.response?.output,
|
|
820
926
|
citations.length
|
|
@@ -830,13 +936,27 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
830
936
|
}
|
|
831
937
|
break;
|
|
832
938
|
}
|
|
833
|
-
case "
|
|
834
|
-
case "response.failed":
|
|
939
|
+
case "response.incomplete":
|
|
835
940
|
throw new Error(
|
|
836
|
-
|
|
941
|
+
`Responses stream incomplete: ${event.response?.incomplete_details?.reason ?? "unknown reason"}`
|
|
942
|
+
);
|
|
943
|
+
case "error":
|
|
944
|
+
case "response.failed": {
|
|
945
|
+
const details = event.response?.error ?? event;
|
|
946
|
+
throw Object.assign(
|
|
947
|
+
new Error(details.message ?? "Responses stream failed"),
|
|
948
|
+
{
|
|
949
|
+
code: details.code,
|
|
950
|
+
param: details.param,
|
|
951
|
+
status: details.status
|
|
952
|
+
}
|
|
837
953
|
);
|
|
954
|
+
}
|
|
838
955
|
}
|
|
839
956
|
}
|
|
957
|
+
throwIfAborted(request.signal);
|
|
958
|
+
if (!completed)
|
|
959
|
+
throw new Error("Responses stream ended without a completed response");
|
|
840
960
|
yield* flushToolCalls();
|
|
841
961
|
if (citations.length > 0) {
|
|
842
962
|
yield { type: "citation", citations: deduplicateCitations(citations) };
|
|
@@ -845,6 +965,7 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
845
965
|
yield { type: "done", usage };
|
|
846
966
|
}
|
|
847
967
|
async *stream(request) {
|
|
968
|
+
throwIfAborted(request.signal);
|
|
848
969
|
if (this.shouldUseResponsesApi(request)) {
|
|
849
970
|
const messageId2 = generateMessageId();
|
|
850
971
|
yield { type: "message:start", id: messageId2 };
|
|
@@ -852,47 +973,14 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
852
973
|
yield* this.streamWithResponses(request);
|
|
853
974
|
return;
|
|
854
975
|
} catch (error) {
|
|
855
|
-
yield
|
|
856
|
-
type: "error",
|
|
857
|
-
message: error instanceof Error ? error.message : "Unknown error",
|
|
858
|
-
code: "OPENAI_RESPONSES_ERROR"
|
|
859
|
-
};
|
|
976
|
+
yield providerErrorEvent(error, "OPENAI_RESPONSES_ERROR");
|
|
860
977
|
return;
|
|
861
978
|
}
|
|
862
979
|
}
|
|
863
980
|
const client = await this.getClient();
|
|
864
981
|
let messages;
|
|
865
982
|
if (request.rawMessages && request.rawMessages.length > 0) {
|
|
866
|
-
const processedMessages = request.rawMessages
|
|
867
|
-
if (msg.role === "assistant" && Array.isArray(msg.tool_calls) && msg.tool_calls.length > 0 && msg.content === "") {
|
|
868
|
-
return { ...msg, content: null };
|
|
869
|
-
}
|
|
870
|
-
const hasAttachments = msg.attachments && Array.isArray(msg.attachments) && msg.attachments.length > 0;
|
|
871
|
-
if (hasAttachments) {
|
|
872
|
-
const content = [];
|
|
873
|
-
if (msg.content) {
|
|
874
|
-
content.push({ type: "text", text: msg.content });
|
|
875
|
-
}
|
|
876
|
-
for (const attachment of msg.attachments) {
|
|
877
|
-
if (attachment.type === "image") {
|
|
878
|
-
let imageUrl;
|
|
879
|
-
if (attachment.url) {
|
|
880
|
-
imageUrl = attachment.url;
|
|
881
|
-
} else if (attachment.data) {
|
|
882
|
-
imageUrl = attachment.data.startsWith("data:") ? attachment.data : `data:${attachment.mimeType || "image/png"};base64,${attachment.data}`;
|
|
883
|
-
} else {
|
|
884
|
-
continue;
|
|
885
|
-
}
|
|
886
|
-
content.push({
|
|
887
|
-
type: "image_url",
|
|
888
|
-
image_url: { url: imageUrl, detail: "auto" }
|
|
889
|
-
});
|
|
890
|
-
}
|
|
891
|
-
}
|
|
892
|
-
return { ...msg, content, attachments: void 0 };
|
|
893
|
-
}
|
|
894
|
-
return msg;
|
|
895
|
-
});
|
|
983
|
+
const processedMessages = this.formatRawMessages(request.rawMessages);
|
|
896
984
|
if (request.systemPrompt) {
|
|
897
985
|
const hasSystem = processedMessages.some((m) => m.role === "system");
|
|
898
986
|
if (!hasSystem) {
|
|
@@ -912,7 +1000,16 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
912
1000
|
request.systemPrompt
|
|
913
1001
|
);
|
|
914
1002
|
}
|
|
915
|
-
const tools = request.
|
|
1003
|
+
const tools = request.toolDefinitions?.length ? request.toolDefinitions.filter((tool) => tool.available !== false).map((tool) => ({
|
|
1004
|
+
type: "function",
|
|
1005
|
+
function: {
|
|
1006
|
+
name: tool.name,
|
|
1007
|
+
description: tool.description,
|
|
1008
|
+
parameters: normalizeObjectJsonSchema(
|
|
1009
|
+
tool.inputSchema
|
|
1010
|
+
)
|
|
1011
|
+
}
|
|
1012
|
+
})) : formatTools(request.actions ?? []);
|
|
916
1013
|
const webSearchConfig = request.webSearch ?? this.config.webSearch;
|
|
917
1014
|
if (webSearchConfig) {
|
|
918
1015
|
const webSearchTool = {
|
|
@@ -941,26 +1038,28 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
941
1038
|
tools: tools.length > 0 ? tools : void 0,
|
|
942
1039
|
tool_choice: tools.length > 0 ? toolChoice : void 0,
|
|
943
1040
|
parallel_tool_calls: tools.length > 0 ? openaiToolOptions?.parallelToolCalls : void 0,
|
|
944
|
-
...
|
|
1041
|
+
...buildOpenAIParameters(
|
|
945
1042
|
modelIdForPayload,
|
|
946
1043
|
request.config?.maxTokens ?? this.config.maxTokens,
|
|
947
|
-
request.config?.temperature ?? this.config.temperature
|
|
1044
|
+
request.config?.temperature ?? this.config.temperature,
|
|
1045
|
+
this.parameterOptions(request)
|
|
948
1046
|
),
|
|
949
1047
|
response_format: toOpenAIResponseFormat(request.config?.responseFormat),
|
|
950
1048
|
stream: true,
|
|
951
1049
|
stream_options: { include_usage: true }
|
|
952
1050
|
};
|
|
953
1051
|
logProviderPayload("openai", "request payload", payload, request.debug);
|
|
954
|
-
const stream = await client.chat.completions.create(payload
|
|
955
|
-
|
|
1052
|
+
const stream = await client.chat.completions.create(payload, {
|
|
1053
|
+
signal: request.signal
|
|
1054
|
+
});
|
|
1055
|
+
const toolCalls = /* @__PURE__ */ new Map();
|
|
1056
|
+
let finishReason;
|
|
956
1057
|
const collectedCitations = [];
|
|
957
1058
|
let citationIndex = 0;
|
|
958
1059
|
let usage;
|
|
959
1060
|
for await (const chunk of stream) {
|
|
960
1061
|
logProviderPayload("openai", "stream chunk", chunk, request.debug);
|
|
961
|
-
|
|
962
|
-
break;
|
|
963
|
-
}
|
|
1062
|
+
throwIfAborted(request.signal);
|
|
964
1063
|
const delta = chunk.choices[0]?.delta;
|
|
965
1064
|
const choice = chunk.choices[0];
|
|
966
1065
|
if (delta?.content) {
|
|
@@ -983,38 +1082,19 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
983
1082
|
}
|
|
984
1083
|
}
|
|
985
1084
|
}
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
};
|
|
1000
|
-
}
|
|
1001
|
-
const tcExtraContent = toolCall.extra_content;
|
|
1002
|
-
currentToolCall = {
|
|
1003
|
-
id: toolCall.id,
|
|
1004
|
-
name: toolCall.function?.name || "",
|
|
1005
|
-
arguments: toolCall.function?.arguments || "",
|
|
1006
|
-
...tcExtraContent ? { extra_content: tcExtraContent } : {}
|
|
1007
|
-
};
|
|
1008
|
-
yield {
|
|
1009
|
-
type: "action:start",
|
|
1010
|
-
id: currentToolCall.id,
|
|
1011
|
-
name: currentToolCall.name,
|
|
1012
|
-
...currentToolCall.extra_content ? { extra_content: currentToolCall.extra_content } : {}
|
|
1013
|
-
};
|
|
1014
|
-
} else if (currentToolCall && toolCall.function?.arguments) {
|
|
1015
|
-
currentToolCall.arguments += toolCall.function.arguments;
|
|
1016
|
-
}
|
|
1017
|
-
}
|
|
1085
|
+
for (const part of delta?.tool_calls ?? []) {
|
|
1086
|
+
const index = part.index ?? 0;
|
|
1087
|
+
const call = toolCalls.get(index) ?? {
|
|
1088
|
+
id: "",
|
|
1089
|
+
name: "",
|
|
1090
|
+
arguments: ""
|
|
1091
|
+
};
|
|
1092
|
+
if (part.id) call.id = part.id;
|
|
1093
|
+
if (part.function?.name) call.name += part.function.name;
|
|
1094
|
+
if (part.function?.arguments)
|
|
1095
|
+
call.arguments += part.function.arguments;
|
|
1096
|
+
if (part.extra_content) call.extra_content = part.extra_content;
|
|
1097
|
+
toolCalls.set(index, call);
|
|
1018
1098
|
}
|
|
1019
1099
|
if (chunk.usage) {
|
|
1020
1100
|
usage = {
|
|
@@ -1023,21 +1103,28 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
1023
1103
|
total_tokens: chunk.usage.total_tokens
|
|
1024
1104
|
};
|
|
1025
1105
|
}
|
|
1026
|
-
if (choice?.finish_reason)
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1106
|
+
if (choice?.finish_reason) finishReason = choice.finish_reason;
|
|
1107
|
+
}
|
|
1108
|
+
throwIfAborted(request.signal);
|
|
1109
|
+
if (!finishReason)
|
|
1110
|
+
throw new Error("OpenAI stream ended without a finish reason");
|
|
1111
|
+
if (toolCalls.size && !["tool_calls", "function_call"].includes(finishReason)) {
|
|
1112
|
+
throw new Error("OpenAI stream ended with incomplete tool calls");
|
|
1113
|
+
}
|
|
1114
|
+
for (const call of toolCalls.values()) {
|
|
1115
|
+
if (!call.id || !call.name)
|
|
1116
|
+
throw new Error("OpenAI stream contains an incomplete tool call");
|
|
1117
|
+
JSON.parse(call.arguments || "{}");
|
|
1118
|
+
}
|
|
1119
|
+
for (const call of toolCalls.values()) {
|
|
1120
|
+
yield {
|
|
1121
|
+
type: "action:start",
|
|
1122
|
+
id: call.id,
|
|
1123
|
+
name: call.name,
|
|
1124
|
+
...call.extra_content ? { extra_content: call.extra_content } : {}
|
|
1125
|
+
};
|
|
1126
|
+
yield { type: "action:args", id: call.id, args: call.arguments };
|
|
1127
|
+
yield { type: "action:end", id: call.id, name: call.name };
|
|
1041
1128
|
}
|
|
1042
1129
|
if (collectedCitations.length > 0) {
|
|
1043
1130
|
const uniqueCitations = deduplicateCitations(collectedCitations);
|
|
@@ -1046,26 +1133,18 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
1046
1133
|
yield { type: "message:end" };
|
|
1047
1134
|
yield { type: "done", usage };
|
|
1048
1135
|
} catch (error) {
|
|
1049
|
-
yield {
|
|
1050
|
-
type: "error",
|
|
1051
|
-
message: error instanceof Error ? error.message : "Unknown error",
|
|
1052
|
-
code: `${this.provider.toUpperCase()}_ERROR`
|
|
1053
|
-
};
|
|
1136
|
+
yield providerErrorEvent(error, `${this.provider.toUpperCase()}_ERROR`);
|
|
1054
1137
|
}
|
|
1055
1138
|
}
|
|
1056
1139
|
async complete(request) {
|
|
1140
|
+
throwIfAborted(request.signal);
|
|
1057
1141
|
if (this.shouldUseResponsesApi(request)) {
|
|
1058
1142
|
return this.completeWithResponses(request);
|
|
1059
1143
|
}
|
|
1060
1144
|
const client = await this.getClient();
|
|
1061
1145
|
let messages;
|
|
1062
1146
|
if (request.rawMessages && request.rawMessages.length > 0) {
|
|
1063
|
-
const sanitized = request.rawMessages
|
|
1064
|
-
if (msg.role === "assistant" && Array.isArray(msg.tool_calls) && msg.tool_calls.length > 0 && msg.content === "") {
|
|
1065
|
-
return { ...msg, content: null };
|
|
1066
|
-
}
|
|
1067
|
-
return msg;
|
|
1068
|
-
});
|
|
1147
|
+
const sanitized = this.formatRawMessages(request.rawMessages);
|
|
1069
1148
|
if (request.systemPrompt && !sanitized.some((message2) => message2.role === "system")) {
|
|
1070
1149
|
messages = [
|
|
1071
1150
|
{ role: "system", content: request.systemPrompt },
|
|
@@ -1080,7 +1159,16 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
1080
1159
|
request.systemPrompt
|
|
1081
1160
|
);
|
|
1082
1161
|
}
|
|
1083
|
-
const tools = request.
|
|
1162
|
+
const tools = request.toolDefinitions?.length ? request.toolDefinitions.filter((tool) => tool.available !== false).map((tool) => ({
|
|
1163
|
+
type: "function",
|
|
1164
|
+
function: {
|
|
1165
|
+
name: tool.name,
|
|
1166
|
+
description: tool.description,
|
|
1167
|
+
parameters: normalizeObjectJsonSchema(
|
|
1168
|
+
tool.inputSchema
|
|
1169
|
+
)
|
|
1170
|
+
}
|
|
1171
|
+
})) : formatTools(request.actions ?? []);
|
|
1084
1172
|
const openaiToolOptions = request.providerToolOptions?.openai;
|
|
1085
1173
|
const toolChoice = openaiToolOptions?.toolChoice && typeof openaiToolOptions.toolChoice === "object" ? {
|
|
1086
1174
|
type: "function",
|
|
@@ -1095,16 +1183,19 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
1095
1183
|
tools: tools.length > 0 ? tools : void 0,
|
|
1096
1184
|
tool_choice: tools.length > 0 ? toolChoice : void 0,
|
|
1097
1185
|
parallel_tool_calls: tools.length > 0 ? openaiToolOptions?.parallelToolCalls : void 0,
|
|
1098
|
-
...
|
|
1186
|
+
...buildOpenAIParameters(
|
|
1099
1187
|
modelIdForCompletePayload,
|
|
1100
1188
|
request.config?.maxTokens ?? this.config.maxTokens,
|
|
1101
|
-
request.config?.temperature ?? this.config.temperature
|
|
1189
|
+
request.config?.temperature ?? this.config.temperature,
|
|
1190
|
+
this.parameterOptions(request)
|
|
1102
1191
|
),
|
|
1103
1192
|
response_format: toOpenAIResponseFormat(request.config?.responseFormat),
|
|
1104
1193
|
stream: false
|
|
1105
1194
|
};
|
|
1106
1195
|
logProviderPayload("openai", "request payload", payload, request.debug);
|
|
1107
|
-
const response = await client.chat.completions.create(payload
|
|
1196
|
+
const response = await client.chat.completions.create(payload, {
|
|
1197
|
+
signal: request.signal
|
|
1198
|
+
});
|
|
1108
1199
|
logProviderPayload("openai", "response payload", response, request.debug);
|
|
1109
1200
|
const choice = response.choices?.[0];
|
|
1110
1201
|
const message = choice?.message;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { M as Message, A as ActionDefinition, d as ToolDefinition, R as ResponseFormat, W as WebSearchConfig, P as ProviderToolRuntimeOptions, g as StreamEvent, J as TokenUsage,
|
|
1
|
+
import { M as Message, A as ActionDefinition, d as ToolDefinition, O as OpenAIReasoningEffort, R as ResponseFormat, W as WebSearchConfig, P as ProviderToolRuntimeOptions, g as StreamEvent, J as TokenUsage, Y as LLMConfig, a8 as MessageAttachment } from './types-BW3csYo5.js';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Request-level LLM configuration overrides
|
|
5
5
|
*/
|
|
6
6
|
interface RequestLLMConfig {
|
|
7
7
|
model?: string;
|
|
8
|
+
reasoningEffort?: OpenAIReasoningEffort;
|
|
8
9
|
temperature?: number;
|
|
9
10
|
maxTokens?: number;
|
|
10
11
|
responseFormat?: ResponseFormat;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { M as Message, A as ActionDefinition, d as ToolDefinition, R as ResponseFormat, W as WebSearchConfig, P as ProviderToolRuntimeOptions, g as StreamEvent, J as TokenUsage,
|
|
1
|
+
import { M as Message, A as ActionDefinition, d as ToolDefinition, O as OpenAIReasoningEffort, R as ResponseFormat, W as WebSearchConfig, P as ProviderToolRuntimeOptions, g as StreamEvent, J as TokenUsage, Y as LLMConfig, a8 as MessageAttachment } from './types-BW3csYo5.mjs';
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Request-level LLM configuration overrides
|
|
5
5
|
*/
|
|
6
6
|
interface RequestLLMConfig {
|
|
7
7
|
model?: string;
|
|
8
|
+
reasoningEffort?: OpenAIReasoningEffort;
|
|
8
9
|
temperature?: number;
|
|
9
10
|
maxTokens?: number;
|
|
10
11
|
responseFormat?: ResponseFormat;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { L as LLMAdapter } from '../base-
|
|
2
|
-
import { F as FallbackChainConfig, c as FallbackFailure, R as RoutingStore } from '../types-
|
|
3
|
-
export { d as FallbackInfo, b as RetryBackoff, e as RetryInfo, a as RoutingStrategy } from '../types-
|
|
4
|
-
import '../types-
|
|
1
|
+
import { L as LLMAdapter } from '../base-CkeT7u-O.mjs';
|
|
2
|
+
import { F as FallbackChainConfig, c as FallbackFailure, R as RoutingStore } from '../types-BWRYIvl_.mjs';
|
|
3
|
+
export { d as FallbackInfo, b as RetryBackoff, e as RetryInfo, a as RoutingStrategy } from '../types-BWRYIvl_.mjs';
|
|
4
|
+
import '../types-BW3csYo5.mjs';
|
|
5
5
|
import 'zod';
|
|
6
6
|
|
|
7
7
|
/**
|
package/dist/fallback/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { L as LLMAdapter } from '../base-
|
|
2
|
-
import { F as FallbackChainConfig, c as FallbackFailure, R as RoutingStore } from '../types-
|
|
3
|
-
export { d as FallbackInfo, b as RetryBackoff, e as RetryInfo, a as RoutingStrategy } from '../types-
|
|
4
|
-
import '../types-
|
|
1
|
+
import { L as LLMAdapter } from '../base-BdTpUAWI.js';
|
|
2
|
+
import { F as FallbackChainConfig, c as FallbackFailure, R as RoutingStore } from '../types-CpXcT-tY.js';
|
|
3
|
+
export { d as FallbackInfo, b as RetryBackoff, e as RetryInfo, a as RoutingStrategy } from '../types-CpXcT-tY.js';
|
|
4
|
+
import '../types-BW3csYo5.js';
|
|
5
5
|
import 'zod';
|
|
6
6
|
|
|
7
7
|
/**
|