@yourgpt/llm-sdk 2.6.0-beta.1 → 2.6.0-beta.2
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 +112 -0
- package/dist/adapters/index.d.mts +5 -5
- package/dist/adapters/index.d.ts +5 -5
- package/dist/adapters/index.js +372 -39
- package/dist/adapters/index.mjs +372 -39
- package/dist/audio-BBSwnjo8.d.mts +92 -0
- package/dist/audio-BBSwnjo8.d.ts +92 -0
- package/dist/{base-CkeT7u-O.d.mts → base-BICaQaRS.d.mts} +7 -3
- package/dist/{base-BdTpUAWI.d.ts → base-CpRPB8u8.d.ts} +7 -3
- package/dist/fallback/index.d.mts +4 -4
- package/dist/fallback/index.d.ts +4 -4
- package/dist/index.d.mts +17 -35
- package/dist/index.d.ts +17 -35
- package/dist/index.js +229 -60
- package/dist/index.mjs +227 -61
- package/dist/providers/anthropic/index.d.mts +3 -3
- package/dist/providers/anthropic/index.d.ts +3 -3
- package/dist/providers/anthropic/index.js +123 -7
- package/dist/providers/anthropic/index.mjs +123 -7
- package/dist/providers/azure/index.d.mts +3 -3
- package/dist/providers/azure/index.d.ts +3 -3
- package/dist/providers/azure/index.js +101 -4
- package/dist/providers/azure/index.mjs +101 -4
- package/dist/providers/fireworks/index.d.mts +3 -3
- package/dist/providers/fireworks/index.d.ts +3 -3
- package/dist/providers/fireworks/index.js +321 -31
- package/dist/providers/fireworks/index.mjs +321 -31
- package/dist/providers/google/index.d.mts +3 -3
- package/dist/providers/google/index.d.ts +3 -3
- package/dist/providers/google/index.js +321 -31
- package/dist/providers/google/index.mjs +321 -31
- package/dist/providers/ollama/index.d.mts +4 -4
- package/dist/providers/ollama/index.d.ts +4 -4
- package/dist/providers/ollama/index.js +87 -2
- package/dist/providers/ollama/index.mjs +87 -2
- package/dist/providers/openai/index.d.mts +25 -6
- package/dist/providers/openai/index.d.ts +25 -6
- package/dist/providers/openai/index.js +750 -40
- package/dist/providers/openai/index.mjs +749 -41
- package/dist/providers/openrouter/index.d.mts +3 -3
- package/dist/providers/openrouter/index.d.ts +3 -3
- package/dist/providers/openrouter/index.js +321 -31
- package/dist/providers/openrouter/index.mjs +321 -31
- package/dist/providers/togetherai/index.d.mts +3 -3
- package/dist/providers/togetherai/index.d.ts +3 -3
- package/dist/providers/togetherai/index.js +321 -31
- package/dist/providers/togetherai/index.mjs +321 -31
- package/dist/providers/xai/index.d.mts +3 -3
- package/dist/providers/xai/index.d.ts +3 -3
- package/dist/providers/xai/index.js +321 -31
- package/dist/providers/xai/index.mjs +321 -31
- package/dist/{types-BWRYIvl_.d.mts → types-C3RgRbEC.d.mts} +1 -1
- package/dist/{types-CpXcT-tY.d.ts → types-DCFqkJAy.d.ts} +1 -1
- package/dist/{types-NOswlhm9.d.mts → types-DHQEMFHA.d.mts} +3 -3
- package/dist/{types-BW3csYo5.d.mts → types-Dg1Bcg1k.d.mts} +106 -3
- package/dist/{types-BW3csYo5.d.ts → types-Dg1Bcg1k.d.ts} +106 -3
- package/dist/{types-DA54bSmX.d.ts → types-Dikj3En4.d.ts} +3 -3
- package/dist/yourgpt/index.d.mts +1 -1
- package/dist/yourgpt/index.d.ts +1 -1
- package/docs/multimodal-and-audio.md +170 -0
- package/package.json +3 -2
|
@@ -1,3 +1,106 @@
|
|
|
1
|
+
// src/core/tool-output.ts
|
|
2
|
+
var imageTypes = /* @__PURE__ */ new Set([
|
|
3
|
+
"image/png",
|
|
4
|
+
"image/jpeg",
|
|
5
|
+
"image/webp",
|
|
6
|
+
"image/gif"
|
|
7
|
+
]);
|
|
8
|
+
function normalizeToolOutput(value) {
|
|
9
|
+
const output = value;
|
|
10
|
+
if (output?.type !== "content" || !Array.isArray(output.content) || !output.content.length) {
|
|
11
|
+
throw new Error("Tool model output must contain a nonempty content array");
|
|
12
|
+
}
|
|
13
|
+
return {
|
|
14
|
+
type: "content",
|
|
15
|
+
content: output.content.map((part) => {
|
|
16
|
+
if (part?.type === "text" && typeof part.text === "string")
|
|
17
|
+
return { type: "text", text: part.text };
|
|
18
|
+
if (part?.type !== "image")
|
|
19
|
+
throw new Error("Unsupported tool output content type");
|
|
20
|
+
const sources = ["data", "url", "fileId"].filter((key) => key in part);
|
|
21
|
+
if (sources.length !== 1)
|
|
22
|
+
throw new Error(
|
|
23
|
+
"Tool image requires exactly one of data, url, or fileId"
|
|
24
|
+
);
|
|
25
|
+
if ("fileId" in part) {
|
|
26
|
+
if (part.provider !== "openai" || typeof part.fileId !== "string" || !part.fileId.trim())
|
|
27
|
+
throw new Error(
|
|
28
|
+
"Tool image file references must name the openai provider and fileId"
|
|
29
|
+
);
|
|
30
|
+
return { type: "image", fileId: part.fileId, provider: "openai" };
|
|
31
|
+
}
|
|
32
|
+
if ("url" in part) {
|
|
33
|
+
let url;
|
|
34
|
+
try {
|
|
35
|
+
url = new URL(part.url);
|
|
36
|
+
} catch {
|
|
37
|
+
throw new Error("Invalid tool image URL");
|
|
38
|
+
}
|
|
39
|
+
if (!["https:", "http:"].includes(url.protocol) || url.username || url.password)
|
|
40
|
+
throw new Error(
|
|
41
|
+
"Tool image URL must use HTTP(S) without credentials"
|
|
42
|
+
);
|
|
43
|
+
return { type: "image", url: url.href };
|
|
44
|
+
}
|
|
45
|
+
if (!("data" in part) || !imageTypes.has(part.mediaType))
|
|
46
|
+
throw new Error("Unsupported tool image media type");
|
|
47
|
+
let data = part.data instanceof Uint8Array ? Buffer.from(part.data).toString("base64") : part.data;
|
|
48
|
+
if (typeof data !== "string")
|
|
49
|
+
throw new Error("Tool image data must be base64 or bytes");
|
|
50
|
+
if (data.startsWith("data:")) {
|
|
51
|
+
const match = /^data:([^;,]+);base64,(.+)$/.exec(data);
|
|
52
|
+
if (!match || match[1] !== part.mediaType)
|
|
53
|
+
throw new Error(
|
|
54
|
+
"Tool image data URL media type does not match mediaType"
|
|
55
|
+
);
|
|
56
|
+
data = match[2];
|
|
57
|
+
}
|
|
58
|
+
if (!data.length || data.length % 4 !== 0 || !/^[A-Za-z0-9+/]+={0,2}$/.test(data))
|
|
59
|
+
throw new Error("Invalid tool image base64 data");
|
|
60
|
+
if (Buffer.byteLength(data, "base64") > 20 * 1024 * 1024)
|
|
61
|
+
throw new Error("Tool image exceeds 20 MiB");
|
|
62
|
+
if (Buffer.from(data, "base64").toString("base64") !== data)
|
|
63
|
+
throw new Error("Invalid tool image base64 data");
|
|
64
|
+
return { type: "image", data, mediaType: part.mediaType };
|
|
65
|
+
})
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function toolOutputForProvider(value, provider) {
|
|
69
|
+
const output = normalizeToolOutput(value);
|
|
70
|
+
return output.content.map((part) => {
|
|
71
|
+
if (part.type === "text")
|
|
72
|
+
return {
|
|
73
|
+
type: provider === "responses" ? "input_text" : "text",
|
|
74
|
+
text: part.text
|
|
75
|
+
};
|
|
76
|
+
if (provider === "unsupported")
|
|
77
|
+
throw new Error(
|
|
78
|
+
"Image tool results require OpenAI Responses or Anthropic; this endpoint is not supported"
|
|
79
|
+
);
|
|
80
|
+
if ("fileId" in part) {
|
|
81
|
+
if (provider !== "responses")
|
|
82
|
+
throw new Error(
|
|
83
|
+
"OpenAI image file references cannot be sent to another provider"
|
|
84
|
+
);
|
|
85
|
+
return { type: "input_image", file_id: part.fileId, detail: "auto" };
|
|
86
|
+
}
|
|
87
|
+
if (provider === "responses")
|
|
88
|
+
return {
|
|
89
|
+
type: "input_image",
|
|
90
|
+
image_url: "url" in part ? part.url : `data:${part.mediaType};base64,${part.data}`,
|
|
91
|
+
detail: "auto"
|
|
92
|
+
};
|
|
93
|
+
return {
|
|
94
|
+
type: "image",
|
|
95
|
+
source: "url" in part ? { type: "url", url: part.url } : { type: "base64", media_type: part.mediaType, data: part.data }
|
|
96
|
+
};
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
function textToolOutput(value, fallback) {
|
|
100
|
+
if (value === void 0) return fallback;
|
|
101
|
+
return toolOutputForProvider(value, "unsupported").map((part) => part.text).join("\n");
|
|
102
|
+
}
|
|
103
|
+
|
|
1
104
|
// src/core/openai-parameters.ts
|
|
2
105
|
function capabilities(model) {
|
|
3
106
|
const gpt = /^gpt-(\d+)(?:\.(\d+))?(?:-(.+))?$/i.exec(model);
|
|
@@ -239,7 +342,7 @@ function messageToOpenAIContent(message) {
|
|
|
239
342
|
}
|
|
240
343
|
return blocks;
|
|
241
344
|
}
|
|
242
|
-
function formatMessagesForOpenAI(messages, systemPrompt) {
|
|
345
|
+
function formatMessagesForOpenAI(messages, systemPrompt, preserveProviderMetadata = false) {
|
|
243
346
|
const formatted = [];
|
|
244
347
|
if (systemPrompt) {
|
|
245
348
|
formatted.push({ role: "system", content: systemPrompt });
|
|
@@ -257,7 +360,8 @@ function formatMessagesForOpenAI(messages, systemPrompt) {
|
|
|
257
360
|
const assistantMsg = {
|
|
258
361
|
role: "assistant",
|
|
259
362
|
// Gemini/xAI (OpenAI-compatible) reject content: "" on assistant messages with tool_calls
|
|
260
|
-
content: hasToolCalls ? msg.content || null : msg.content
|
|
363
|
+
content: hasToolCalls ? msg.content || null : msg.content,
|
|
364
|
+
...preserveProviderMetadata && msg.providerMetadata ? { providerMetadata: msg.providerMetadata } : {}
|
|
261
365
|
};
|
|
262
366
|
if (hasToolCalls) {
|
|
263
367
|
assistantMsg.tool_calls = msg.tool_calls;
|
|
@@ -266,7 +370,8 @@ function formatMessagesForOpenAI(messages, systemPrompt) {
|
|
|
266
370
|
} else if (msg.role === "tool" && msg.tool_call_id) {
|
|
267
371
|
formatted.push({
|
|
268
372
|
role: "tool",
|
|
269
|
-
content: msg.content ?? "",
|
|
373
|
+
content: preserveProviderMetadata ? msg.content ?? "" : textToolOutput(msg.modelOutput, msg.content ?? ""),
|
|
374
|
+
...preserveProviderMetadata && msg.modelOutput ? { modelOutput: msg.modelOutput } : {},
|
|
270
375
|
tool_call_id: msg.tool_call_id
|
|
271
376
|
});
|
|
272
377
|
}
|
|
@@ -473,7 +578,7 @@ function formatMessages(messages) {
|
|
|
473
578
|
return {
|
|
474
579
|
role: "tool",
|
|
475
580
|
tool_call_id: msg.toolCallId,
|
|
476
|
-
content: msg.content
|
|
581
|
+
content: textToolOutput(msg.modelOutput, msg.content)
|
|
477
582
|
};
|
|
478
583
|
default:
|
|
479
584
|
return msg;
|
|
@@ -481,6 +586,64 @@ function formatMessages(messages) {
|
|
|
481
586
|
});
|
|
482
587
|
}
|
|
483
588
|
|
|
589
|
+
// src/core/openai-responses.ts
|
|
590
|
+
function resolveOpenAITransport(defaults, overrides) {
|
|
591
|
+
return {
|
|
592
|
+
api: overrides?.api ?? defaults.api ?? "auto",
|
|
593
|
+
responses: defaults.responses !== void 0 || overrides?.responses !== void 0 ? { ...defaults.responses, ...overrides?.responses } : void 0
|
|
594
|
+
};
|
|
595
|
+
}
|
|
596
|
+
function useOpenAIResponses(model, baseURL, parameters, transport, hasTools, hasReplay, nativeToolSearch = false) {
|
|
597
|
+
const api = transport.api ?? "auto";
|
|
598
|
+
if (!["auto", "chat", "responses"].includes(api)) {
|
|
599
|
+
throw new Error(`Unknown OpenAI API selection: ${api}`);
|
|
600
|
+
}
|
|
601
|
+
if (api === "chat") {
|
|
602
|
+
if (transport.responses !== void 0 || nativeToolSearch) {
|
|
603
|
+
throw new Error(
|
|
604
|
+
"Responses options and native tool search require the Responses API"
|
|
605
|
+
);
|
|
606
|
+
}
|
|
607
|
+
return false;
|
|
608
|
+
}
|
|
609
|
+
let officialEndpoint = !baseURL;
|
|
610
|
+
try {
|
|
611
|
+
officialEndpoint = !baseURL || new URL(baseURL).hostname === "api.openai.com";
|
|
612
|
+
} catch {
|
|
613
|
+
}
|
|
614
|
+
return api === "responses" || transport.responses !== void 0 || hasReplay && officialEndpoint || nativeToolSearch || hasTools && requiresOpenAIResponses(model, baseURL, parameters);
|
|
615
|
+
}
|
|
616
|
+
function responseMetadata(response) {
|
|
617
|
+
const output = Array.isArray(response?.output) ? response.output : [];
|
|
618
|
+
return {
|
|
619
|
+
openai: {
|
|
620
|
+
response: {
|
|
621
|
+
id: response?.id,
|
|
622
|
+
model: response?.model,
|
|
623
|
+
status: response?.status,
|
|
624
|
+
output,
|
|
625
|
+
usage: response?.usage,
|
|
626
|
+
store: response?.store,
|
|
627
|
+
refusals: output.flatMap(
|
|
628
|
+
(item) => item?.type === "message" && Array.isArray(item.content) ? item.content.filter(
|
|
629
|
+
(part) => part?.type === "refusal" && typeof part.refusal === "string"
|
|
630
|
+
).map((part) => part.refusal) : []
|
|
631
|
+
)
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
};
|
|
635
|
+
}
|
|
636
|
+
function getResponseReplay(metadata) {
|
|
637
|
+
const response = metadata?.openai?.response;
|
|
638
|
+
if (response === void 0) return void 0;
|
|
639
|
+
if (!Array.isArray(response.output) || response.output.some((item) => !item || typeof item.type !== "string")) {
|
|
640
|
+
throw new Error(
|
|
641
|
+
"Invalid OpenAI Responses replay metadata: output must contain typed items"
|
|
642
|
+
);
|
|
643
|
+
}
|
|
644
|
+
return response.output;
|
|
645
|
+
}
|
|
646
|
+
|
|
484
647
|
// src/core/provider-error.ts
|
|
485
648
|
function providerErrorEvent(error, code) {
|
|
486
649
|
const details = error ?? {};
|
|
@@ -557,13 +720,16 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
557
720
|
}));
|
|
558
721
|
}
|
|
559
722
|
shouldUseResponsesApi(request) {
|
|
560
|
-
|
|
561
|
-
if (request.providerToolOptions?.openai?.nativeToolSearch?.enabled === true && request.providerToolOptions.openai.nativeToolSearch.useResponsesApi !== false)
|
|
562
|
-
return true;
|
|
563
|
-
return requiresOpenAIResponses(
|
|
723
|
+
return useOpenAIResponses(
|
|
564
724
|
request.config?.model || this.model,
|
|
565
725
|
this.config.baseUrl,
|
|
566
|
-
this.parameterOptions(request)
|
|
726
|
+
this.parameterOptions(request),
|
|
727
|
+
resolveOpenAITransport(this.config, request.config?.openai),
|
|
728
|
+
this.toolDefinitions(request).length > 0,
|
|
729
|
+
!!(request.rawMessages ?? request.messages)?.some(
|
|
730
|
+
(message) => message.providerMetadata?.openai?.response
|
|
731
|
+
),
|
|
732
|
+
request.providerToolOptions?.openai?.nativeToolSearch?.enabled === true && request.providerToolOptions.openai.nativeToolSearch.useResponsesApi !== false
|
|
567
733
|
);
|
|
568
734
|
}
|
|
569
735
|
/**
|
|
@@ -596,11 +762,11 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
596
762
|
});
|
|
597
763
|
}
|
|
598
764
|
buildResponsesInput(request) {
|
|
599
|
-
const sourceMessages = request.rawMessages && request.rawMessages.length > 0 ? this.formatRawMessages(request.rawMessages) : formatMessagesForOpenAI(request.messages, void 0);
|
|
765
|
+
const sourceMessages = request.rawMessages && request.rawMessages.length > 0 ? this.formatRawMessages(request.rawMessages, true) : formatMessagesForOpenAI(request.messages, void 0, true);
|
|
600
766
|
const input = [];
|
|
601
767
|
for (const message of sourceMessages) {
|
|
602
768
|
if (message.role === "system") {
|
|
603
|
-
if (
|
|
769
|
+
if (message.content && message.content !== request.systemPrompt) {
|
|
604
770
|
input.push({
|
|
605
771
|
type: "message",
|
|
606
772
|
role: "developer",
|
|
@@ -610,6 +776,11 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
610
776
|
continue;
|
|
611
777
|
}
|
|
612
778
|
if (message.role === "assistant") {
|
|
779
|
+
const replay = getResponseReplay(message.providerMetadata);
|
|
780
|
+
if (replay) {
|
|
781
|
+
input.push(...replay);
|
|
782
|
+
continue;
|
|
783
|
+
}
|
|
613
784
|
const content = this.toResponsesContent(message.content, "assistant");
|
|
614
785
|
if (typeof content === "string" ? content : Array.isArray(content) && content.length > 0) {
|
|
615
786
|
input.push({
|
|
@@ -633,7 +804,7 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
633
804
|
input.push({
|
|
634
805
|
type: "function_call_output",
|
|
635
806
|
call_id: message.tool_call_id,
|
|
636
|
-
output: typeof message.content === "string" ? message.content : JSON.stringify(message.content ?? null)
|
|
807
|
+
output: message.modelOutput ? toolOutputForProvider(message.modelOutput, "responses") : typeof message.content === "string" ? message.content : JSON.stringify(message.content ?? null)
|
|
637
808
|
});
|
|
638
809
|
continue;
|
|
639
810
|
}
|
|
@@ -647,10 +818,12 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
647
818
|
return input;
|
|
648
819
|
}
|
|
649
820
|
/** Preserve Copilot screenshot attachments on every OpenAI transport. */
|
|
650
|
-
formatRawMessages(messages) {
|
|
821
|
+
formatRawMessages(messages, preserveProviderMetadata = false) {
|
|
651
822
|
return messages.map((message) => {
|
|
652
|
-
const { attachments, ...rest } = message;
|
|
653
|
-
let content = message.content;
|
|
823
|
+
const { attachments, providerMetadata, modelOutput, ...rest } = message;
|
|
824
|
+
let content = message.role === "tool" && !preserveProviderMetadata ? textToolOutput(modelOutput, String(message.content ?? "")) : message.content;
|
|
825
|
+
if (preserveProviderMetadata && modelOutput)
|
|
826
|
+
rest.modelOutput = modelOutput;
|
|
654
827
|
if (message.role === "assistant" && Array.isArray(message.tool_calls) && message.tool_calls.length > 0 && content === "") {
|
|
655
828
|
content = null;
|
|
656
829
|
}
|
|
@@ -663,7 +836,11 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
663
836
|
content = [...parts, ...images];
|
|
664
837
|
}
|
|
665
838
|
}
|
|
666
|
-
return {
|
|
839
|
+
return {
|
|
840
|
+
...rest,
|
|
841
|
+
content,
|
|
842
|
+
...preserveProviderMetadata && providerMetadata ? { providerMetadata } : {}
|
|
843
|
+
};
|
|
667
844
|
});
|
|
668
845
|
}
|
|
669
846
|
/**
|
|
@@ -744,14 +921,25 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
744
921
|
).map((part) => part.text) : []
|
|
745
922
|
).join("") : "";
|
|
746
923
|
const content = textFromOutput || (typeof response?.output_text === "string" ? response.output_text : "");
|
|
747
|
-
const
|
|
748
|
-
|
|
749
|
-
name
|
|
750
|
-
|
|
751
|
-
|
|
924
|
+
const seenCallIds = /* @__PURE__ */ new Set();
|
|
925
|
+
const toolCalls = Array.isArray(response?.output) ? response.output.filter((item) => item?.type === "function_call").map((item) => {
|
|
926
|
+
if (typeof item.call_id !== "string" || !item.call_id || typeof item.name !== "string" || !item.name || typeof item.arguments !== "string" || item.status && item.status !== "completed") {
|
|
927
|
+
throw new Error("Responses contains an incomplete function call");
|
|
928
|
+
}
|
|
929
|
+
if (seenCallIds.has(item.call_id))
|
|
930
|
+
throw new Error("Responses contains duplicate function call IDs");
|
|
931
|
+
seenCallIds.add(item.call_id);
|
|
932
|
+
const args = JSON.parse(item.arguments);
|
|
933
|
+
if (!args || typeof args !== "object" || Array.isArray(args))
|
|
934
|
+
throw new Error(
|
|
935
|
+
"Responses function arguments must be a JSON object"
|
|
936
|
+
);
|
|
937
|
+
return { id: item.call_id, name: item.name, args };
|
|
938
|
+
}) : [];
|
|
752
939
|
return {
|
|
753
940
|
content,
|
|
754
941
|
toolCalls,
|
|
942
|
+
providerMetadata: responseMetadata(response),
|
|
755
943
|
usage: response?.usage ? {
|
|
756
944
|
promptTokens: response.usage.input_tokens ?? 0,
|
|
757
945
|
completionTokens: response.usage.output_tokens ?? 0,
|
|
@@ -762,6 +950,17 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
762
950
|
}
|
|
763
951
|
buildResponsesPayload(request, stream) {
|
|
764
952
|
const openaiToolOptions = request.providerToolOptions?.openai;
|
|
953
|
+
const options = resolveOpenAITransport(
|
|
954
|
+
this.config,
|
|
955
|
+
request.config?.openai
|
|
956
|
+
).responses;
|
|
957
|
+
const parameters = buildOpenAIParameters(
|
|
958
|
+
request.config?.model || this.model,
|
|
959
|
+
request.config?.maxTokens ?? this.config.maxTokens,
|
|
960
|
+
request.config?.temperature ?? this.config.temperature,
|
|
961
|
+
this.parameterOptions(request),
|
|
962
|
+
"responses"
|
|
963
|
+
);
|
|
765
964
|
const responsesTextFormat = toOpenAIResponsesTextFormat(
|
|
766
965
|
request.config?.responseFormat
|
|
767
966
|
);
|
|
@@ -777,13 +976,26 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
777
976
|
),
|
|
778
977
|
tool_choice: openaiToolOptions?.toolChoice,
|
|
779
978
|
parallel_tool_calls: openaiToolOptions?.parallelToolCalls,
|
|
780
|
-
...
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
979
|
+
...parameters,
|
|
980
|
+
...options?.reasoningSummary ? {
|
|
981
|
+
reasoning: {
|
|
982
|
+
...parameters.reasoning,
|
|
983
|
+
summary: options.reasoningSummary
|
|
984
|
+
}
|
|
985
|
+
} : {},
|
|
986
|
+
...options?.store !== void 0 ? { store: options.store } : {},
|
|
987
|
+
...options?.previousResponseId !== void 0 ? { previous_response_id: options.previousResponseId } : {},
|
|
988
|
+
...options?.promptCacheKey !== void 0 ? { prompt_cache_key: options.promptCacheKey } : {},
|
|
989
|
+
...options?.promptCacheOptions !== void 0 ? { prompt_cache_options: options.promptCacheOptions } : {},
|
|
990
|
+
...options?.promptCacheRetention !== void 0 ? { prompt_cache_retention: options.promptCacheRetention } : {},
|
|
991
|
+
...options?.store === false || options?.include ? {
|
|
992
|
+
include: [
|
|
993
|
+
.../* @__PURE__ */ new Set([
|
|
994
|
+
...options?.include ?? [],
|
|
995
|
+
...options?.store === false ? ["reasoning.encrypted_content"] : []
|
|
996
|
+
])
|
|
997
|
+
]
|
|
998
|
+
} : {},
|
|
787
999
|
...responsesTextFormat ? { text: { format: responsesTextFormat } } : {},
|
|
788
1000
|
stream
|
|
789
1001
|
};
|
|
@@ -842,6 +1054,10 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
842
1054
|
let usage;
|
|
843
1055
|
const citations = [];
|
|
844
1056
|
let completed = false;
|
|
1057
|
+
let terminalResponse;
|
|
1058
|
+
let responseIdentity = {};
|
|
1059
|
+
const outputItems = /* @__PURE__ */ new Map();
|
|
1060
|
+
let streamedText = "";
|
|
845
1061
|
function* flushToolCalls() {
|
|
846
1062
|
for (const call of toolCalls.values()) {
|
|
847
1063
|
if (!call.name)
|
|
@@ -858,17 +1074,36 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
858
1074
|
for await (const event of stream) {
|
|
859
1075
|
throwIfAborted(request.signal);
|
|
860
1076
|
logProviderPayload("openai", "stream chunk", event, request.debug);
|
|
1077
|
+
if (completed)
|
|
1078
|
+
throw new Error("Responses stream emitted an event after completion");
|
|
861
1079
|
const index = event?.output_index ?? 0;
|
|
862
1080
|
switch (event?.type) {
|
|
1081
|
+
case "response.created":
|
|
1082
|
+
responseIdentity = {
|
|
1083
|
+
id: event.response?.id,
|
|
1084
|
+
model: event.response?.model
|
|
1085
|
+
};
|
|
1086
|
+
break;
|
|
1087
|
+
case "response.output_item.done":
|
|
1088
|
+
if (event.item) outputItems.set(index, event.item);
|
|
1089
|
+
if (event.item?.type === "function_call") {
|
|
1090
|
+
toolCalls.set(index, {
|
|
1091
|
+
id: event.item.call_id,
|
|
1092
|
+
name: event.item.name,
|
|
1093
|
+
arguments: event.item.arguments
|
|
1094
|
+
});
|
|
1095
|
+
}
|
|
1096
|
+
break;
|
|
863
1097
|
case "response.output_text.delta":
|
|
864
1098
|
if (event.delta) {
|
|
1099
|
+
streamedText += event.delta;
|
|
865
1100
|
yield { type: "message:delta", content: event.delta };
|
|
866
1101
|
}
|
|
867
1102
|
break;
|
|
868
1103
|
case "response.output_item.added":
|
|
869
1104
|
if (event.item?.type === "function_call") {
|
|
870
1105
|
toolCalls.set(index, {
|
|
871
|
-
id: event.item.call_id ??
|
|
1106
|
+
id: event.item.call_id ?? "",
|
|
872
1107
|
name: event.item.name ?? "",
|
|
873
1108
|
arguments: event.item.arguments ?? ""
|
|
874
1109
|
});
|
|
@@ -887,7 +1122,10 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
887
1122
|
break;
|
|
888
1123
|
}
|
|
889
1124
|
case "response.completed": {
|
|
1125
|
+
if (event.response?.status && event.response.status !== "completed")
|
|
1126
|
+
throw new Error(`Responses stream ${event.response.status}`);
|
|
890
1127
|
completed = true;
|
|
1128
|
+
terminalResponse = { ...responseIdentity, ...event.response };
|
|
891
1129
|
const found = this.collectResponsesCitations(
|
|
892
1130
|
event.response?.output,
|
|
893
1131
|
citations.length
|
|
@@ -924,12 +1162,64 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
924
1162
|
throwIfAborted(request.signal);
|
|
925
1163
|
if (!completed)
|
|
926
1164
|
throw new Error("Responses stream ended without a completed response");
|
|
1165
|
+
const output = terminalResponse.output?.length ? terminalResponse.output : [...outputItems.entries()].sort(([a], [b]) => a - b).map(([, item]) => item);
|
|
1166
|
+
if (output.some((item) => item.type === "function_call"))
|
|
1167
|
+
toolCalls.clear();
|
|
1168
|
+
for (const [index, item] of output.entries()) {
|
|
1169
|
+
if (item.type === "function_call") {
|
|
1170
|
+
toolCalls.set(index, {
|
|
1171
|
+
id: item.call_id,
|
|
1172
|
+
name: item.name,
|
|
1173
|
+
arguments: item.arguments
|
|
1174
|
+
});
|
|
1175
|
+
}
|
|
1176
|
+
}
|
|
1177
|
+
const uniqueCalls = /* @__PURE__ */ new Map();
|
|
1178
|
+
for (const call of toolCalls.values()) {
|
|
1179
|
+
if (!call.id || !call.name)
|
|
1180
|
+
throw new Error("Responses stream contains an incomplete tool call");
|
|
1181
|
+
uniqueCalls.set(call.id, call);
|
|
1182
|
+
}
|
|
1183
|
+
toolCalls.clear();
|
|
1184
|
+
[...uniqueCalls.values()].forEach(
|
|
1185
|
+
(call, index) => toolCalls.set(index, call)
|
|
1186
|
+
);
|
|
1187
|
+
if (!output.length && toolCalls.size) {
|
|
1188
|
+
for (const call of toolCalls.values())
|
|
1189
|
+
output.push({
|
|
1190
|
+
type: "function_call",
|
|
1191
|
+
call_id: call.id,
|
|
1192
|
+
name: call.name,
|
|
1193
|
+
arguments: call.arguments
|
|
1194
|
+
});
|
|
1195
|
+
}
|
|
1196
|
+
if (!output.length && streamedText)
|
|
1197
|
+
output.push({
|
|
1198
|
+
type: "message",
|
|
1199
|
+
role: "assistant",
|
|
1200
|
+
content: [{ type: "output_text", text: streamedText, annotations: [] }]
|
|
1201
|
+
});
|
|
1202
|
+
terminalResponse.output = output;
|
|
1203
|
+
const finalText = this.parseResponsesResult(terminalResponse).content;
|
|
1204
|
+
if (finalText.startsWith(streamedText) && finalText.length > streamedText.length) {
|
|
1205
|
+
yield {
|
|
1206
|
+
type: "message:delta",
|
|
1207
|
+
content: finalText.slice(streamedText.length)
|
|
1208
|
+
};
|
|
1209
|
+
}
|
|
927
1210
|
yield* flushToolCalls();
|
|
928
1211
|
if (citations.length > 0) {
|
|
929
1212
|
yield { type: "citation", citations: deduplicateCitations(citations) };
|
|
930
1213
|
}
|
|
931
|
-
yield {
|
|
932
|
-
|
|
1214
|
+
yield {
|
|
1215
|
+
type: "message:end",
|
|
1216
|
+
providerMetadata: responseMetadata(terminalResponse)
|
|
1217
|
+
};
|
|
1218
|
+
yield {
|
|
1219
|
+
type: "done",
|
|
1220
|
+
usage,
|
|
1221
|
+
providerMetadata: responseMetadata(terminalResponse)
|
|
1222
|
+
};
|
|
933
1223
|
}
|
|
934
1224
|
async *stream(request) {
|
|
935
1225
|
throwIfAborted(request.signal);
|
|
@@ -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-Dg1Bcg1k.mjs';
|
|
2
|
+
import { G as GoogleProviderConfig, A as AIProvider } from '../../types-DHQEMFHA.mjs';
|
|
3
3
|
import 'zod';
|
|
4
|
-
import '../../base-
|
|
4
|
+
import '../../base-BICaQaRS.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-Dg1Bcg1k.js';
|
|
2
|
+
import { G as GoogleProviderConfig, A as AIProvider } from '../../types-Dikj3En4.js';
|
|
3
3
|
import 'zod';
|
|
4
|
-
import '../../base-
|
|
4
|
+
import '../../base-CpRPB8u8.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Google Provider - OpenAI-Compatible
|