@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
|
}
|
|
@@ -478,7 +583,7 @@ function formatMessages(messages) {
|
|
|
478
583
|
return {
|
|
479
584
|
role: "tool",
|
|
480
585
|
tool_call_id: msg.toolCallId,
|
|
481
|
-
content: msg.content
|
|
586
|
+
content: textToolOutput(msg.modelOutput, msg.content)
|
|
482
587
|
};
|
|
483
588
|
default:
|
|
484
589
|
return msg;
|
|
@@ -486,6 +591,64 @@ function formatMessages(messages) {
|
|
|
486
591
|
});
|
|
487
592
|
}
|
|
488
593
|
|
|
594
|
+
// src/core/openai-responses.ts
|
|
595
|
+
function resolveOpenAITransport(defaults, overrides) {
|
|
596
|
+
return {
|
|
597
|
+
api: overrides?.api ?? defaults.api ?? "auto",
|
|
598
|
+
responses: defaults.responses !== void 0 || overrides?.responses !== void 0 ? { ...defaults.responses, ...overrides?.responses } : void 0
|
|
599
|
+
};
|
|
600
|
+
}
|
|
601
|
+
function useOpenAIResponses(model, baseURL, parameters, transport, hasTools, hasReplay, nativeToolSearch = false) {
|
|
602
|
+
const api = transport.api ?? "auto";
|
|
603
|
+
if (!["auto", "chat", "responses"].includes(api)) {
|
|
604
|
+
throw new Error(`Unknown OpenAI API selection: ${api}`);
|
|
605
|
+
}
|
|
606
|
+
if (api === "chat") {
|
|
607
|
+
if (transport.responses !== void 0 || nativeToolSearch) {
|
|
608
|
+
throw new Error(
|
|
609
|
+
"Responses options and native tool search require the Responses API"
|
|
610
|
+
);
|
|
611
|
+
}
|
|
612
|
+
return false;
|
|
613
|
+
}
|
|
614
|
+
let officialEndpoint = !baseURL;
|
|
615
|
+
try {
|
|
616
|
+
officialEndpoint = !baseURL || new URL(baseURL).hostname === "api.openai.com";
|
|
617
|
+
} catch {
|
|
618
|
+
}
|
|
619
|
+
return api === "responses" || transport.responses !== void 0 || hasReplay && officialEndpoint || nativeToolSearch || hasTools && requiresOpenAIResponses(model, baseURL, parameters);
|
|
620
|
+
}
|
|
621
|
+
function responseMetadata(response) {
|
|
622
|
+
const output = Array.isArray(response?.output) ? response.output : [];
|
|
623
|
+
return {
|
|
624
|
+
openai: {
|
|
625
|
+
response: {
|
|
626
|
+
id: response?.id,
|
|
627
|
+
model: response?.model,
|
|
628
|
+
status: response?.status,
|
|
629
|
+
output,
|
|
630
|
+
usage: response?.usage,
|
|
631
|
+
store: response?.store,
|
|
632
|
+
refusals: output.flatMap(
|
|
633
|
+
(item) => item?.type === "message" && Array.isArray(item.content) ? item.content.filter(
|
|
634
|
+
(part) => part?.type === "refusal" && typeof part.refusal === "string"
|
|
635
|
+
).map((part) => part.refusal) : []
|
|
636
|
+
)
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
};
|
|
640
|
+
}
|
|
641
|
+
function getResponseReplay(metadata) {
|
|
642
|
+
const response = metadata?.openai?.response;
|
|
643
|
+
if (response === void 0) return void 0;
|
|
644
|
+
if (!Array.isArray(response.output) || response.output.some((item) => !item || typeof item.type !== "string")) {
|
|
645
|
+
throw new Error(
|
|
646
|
+
"Invalid OpenAI Responses replay metadata: output must contain typed items"
|
|
647
|
+
);
|
|
648
|
+
}
|
|
649
|
+
return response.output;
|
|
650
|
+
}
|
|
651
|
+
|
|
489
652
|
// src/core/provider-error.ts
|
|
490
653
|
function providerErrorEvent(error, code) {
|
|
491
654
|
const details = error ?? {};
|
|
@@ -562,13 +725,16 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
562
725
|
}));
|
|
563
726
|
}
|
|
564
727
|
shouldUseResponsesApi(request) {
|
|
565
|
-
|
|
566
|
-
if (request.providerToolOptions?.openai?.nativeToolSearch?.enabled === true && request.providerToolOptions.openai.nativeToolSearch.useResponsesApi !== false)
|
|
567
|
-
return true;
|
|
568
|
-
return requiresOpenAIResponses(
|
|
728
|
+
return useOpenAIResponses(
|
|
569
729
|
request.config?.model || this.model,
|
|
570
730
|
this.config.baseUrl,
|
|
571
|
-
this.parameterOptions(request)
|
|
731
|
+
this.parameterOptions(request),
|
|
732
|
+
resolveOpenAITransport(this.config, request.config?.openai),
|
|
733
|
+
this.toolDefinitions(request).length > 0,
|
|
734
|
+
!!(request.rawMessages ?? request.messages)?.some(
|
|
735
|
+
(message) => message.providerMetadata?.openai?.response
|
|
736
|
+
),
|
|
737
|
+
request.providerToolOptions?.openai?.nativeToolSearch?.enabled === true && request.providerToolOptions.openai.nativeToolSearch.useResponsesApi !== false
|
|
572
738
|
);
|
|
573
739
|
}
|
|
574
740
|
/**
|
|
@@ -601,11 +767,11 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
601
767
|
});
|
|
602
768
|
}
|
|
603
769
|
buildResponsesInput(request) {
|
|
604
|
-
const sourceMessages = request.rawMessages && request.rawMessages.length > 0 ? this.formatRawMessages(request.rawMessages) : formatMessagesForOpenAI(request.messages, void 0);
|
|
770
|
+
const sourceMessages = request.rawMessages && request.rawMessages.length > 0 ? this.formatRawMessages(request.rawMessages, true) : formatMessagesForOpenAI(request.messages, void 0, true);
|
|
605
771
|
const input = [];
|
|
606
772
|
for (const message of sourceMessages) {
|
|
607
773
|
if (message.role === "system") {
|
|
608
|
-
if (
|
|
774
|
+
if (message.content && message.content !== request.systemPrompt) {
|
|
609
775
|
input.push({
|
|
610
776
|
type: "message",
|
|
611
777
|
role: "developer",
|
|
@@ -615,6 +781,11 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
615
781
|
continue;
|
|
616
782
|
}
|
|
617
783
|
if (message.role === "assistant") {
|
|
784
|
+
const replay = getResponseReplay(message.providerMetadata);
|
|
785
|
+
if (replay) {
|
|
786
|
+
input.push(...replay);
|
|
787
|
+
continue;
|
|
788
|
+
}
|
|
618
789
|
const content = this.toResponsesContent(message.content, "assistant");
|
|
619
790
|
if (typeof content === "string" ? content : Array.isArray(content) && content.length > 0) {
|
|
620
791
|
input.push({
|
|
@@ -638,7 +809,7 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
638
809
|
input.push({
|
|
639
810
|
type: "function_call_output",
|
|
640
811
|
call_id: message.tool_call_id,
|
|
641
|
-
output: typeof message.content === "string" ? message.content : JSON.stringify(message.content ?? null)
|
|
812
|
+
output: message.modelOutput ? toolOutputForProvider(message.modelOutput, "responses") : typeof message.content === "string" ? message.content : JSON.stringify(message.content ?? null)
|
|
642
813
|
});
|
|
643
814
|
continue;
|
|
644
815
|
}
|
|
@@ -652,10 +823,12 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
652
823
|
return input;
|
|
653
824
|
}
|
|
654
825
|
/** Preserve Copilot screenshot attachments on every OpenAI transport. */
|
|
655
|
-
formatRawMessages(messages) {
|
|
826
|
+
formatRawMessages(messages, preserveProviderMetadata = false) {
|
|
656
827
|
return messages.map((message) => {
|
|
657
|
-
const { attachments, ...rest } = message;
|
|
658
|
-
let content = message.content;
|
|
828
|
+
const { attachments, providerMetadata, modelOutput, ...rest } = message;
|
|
829
|
+
let content = message.role === "tool" && !preserveProviderMetadata ? textToolOutput(modelOutput, String(message.content ?? "")) : message.content;
|
|
830
|
+
if (preserveProviderMetadata && modelOutput)
|
|
831
|
+
rest.modelOutput = modelOutput;
|
|
659
832
|
if (message.role === "assistant" && Array.isArray(message.tool_calls) && message.tool_calls.length > 0 && content === "") {
|
|
660
833
|
content = null;
|
|
661
834
|
}
|
|
@@ -668,7 +841,11 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
668
841
|
content = [...parts, ...images];
|
|
669
842
|
}
|
|
670
843
|
}
|
|
671
|
-
return {
|
|
844
|
+
return {
|
|
845
|
+
...rest,
|
|
846
|
+
content,
|
|
847
|
+
...preserveProviderMetadata && providerMetadata ? { providerMetadata } : {}
|
|
848
|
+
};
|
|
672
849
|
});
|
|
673
850
|
}
|
|
674
851
|
/**
|
|
@@ -749,14 +926,25 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
749
926
|
).map((part) => part.text) : []
|
|
750
927
|
).join("") : "";
|
|
751
928
|
const content = textFromOutput || (typeof response?.output_text === "string" ? response.output_text : "");
|
|
752
|
-
const
|
|
753
|
-
|
|
754
|
-
name
|
|
755
|
-
|
|
756
|
-
|
|
929
|
+
const seenCallIds = /* @__PURE__ */ new Set();
|
|
930
|
+
const toolCalls = Array.isArray(response?.output) ? response.output.filter((item) => item?.type === "function_call").map((item) => {
|
|
931
|
+
if (typeof item.call_id !== "string" || !item.call_id || typeof item.name !== "string" || !item.name || typeof item.arguments !== "string" || item.status && item.status !== "completed") {
|
|
932
|
+
throw new Error("Responses contains an incomplete function call");
|
|
933
|
+
}
|
|
934
|
+
if (seenCallIds.has(item.call_id))
|
|
935
|
+
throw new Error("Responses contains duplicate function call IDs");
|
|
936
|
+
seenCallIds.add(item.call_id);
|
|
937
|
+
const args = JSON.parse(item.arguments);
|
|
938
|
+
if (!args || typeof args !== "object" || Array.isArray(args))
|
|
939
|
+
throw new Error(
|
|
940
|
+
"Responses function arguments must be a JSON object"
|
|
941
|
+
);
|
|
942
|
+
return { id: item.call_id, name: item.name, args };
|
|
943
|
+
}) : [];
|
|
757
944
|
return {
|
|
758
945
|
content,
|
|
759
946
|
toolCalls,
|
|
947
|
+
providerMetadata: responseMetadata(response),
|
|
760
948
|
usage: response?.usage ? {
|
|
761
949
|
promptTokens: response.usage.input_tokens ?? 0,
|
|
762
950
|
completionTokens: response.usage.output_tokens ?? 0,
|
|
@@ -767,6 +955,17 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
767
955
|
}
|
|
768
956
|
buildResponsesPayload(request, stream) {
|
|
769
957
|
const openaiToolOptions = request.providerToolOptions?.openai;
|
|
958
|
+
const options = resolveOpenAITransport(
|
|
959
|
+
this.config,
|
|
960
|
+
request.config?.openai
|
|
961
|
+
).responses;
|
|
962
|
+
const parameters = buildOpenAIParameters(
|
|
963
|
+
request.config?.model || this.model,
|
|
964
|
+
request.config?.maxTokens ?? this.config.maxTokens,
|
|
965
|
+
request.config?.temperature ?? this.config.temperature,
|
|
966
|
+
this.parameterOptions(request),
|
|
967
|
+
"responses"
|
|
968
|
+
);
|
|
770
969
|
const responsesTextFormat = toOpenAIResponsesTextFormat(
|
|
771
970
|
request.config?.responseFormat
|
|
772
971
|
);
|
|
@@ -782,13 +981,26 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
782
981
|
),
|
|
783
982
|
tool_choice: openaiToolOptions?.toolChoice,
|
|
784
983
|
parallel_tool_calls: openaiToolOptions?.parallelToolCalls,
|
|
785
|
-
...
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
984
|
+
...parameters,
|
|
985
|
+
...options?.reasoningSummary ? {
|
|
986
|
+
reasoning: {
|
|
987
|
+
...parameters.reasoning,
|
|
988
|
+
summary: options.reasoningSummary
|
|
989
|
+
}
|
|
990
|
+
} : {},
|
|
991
|
+
...options?.store !== void 0 ? { store: options.store } : {},
|
|
992
|
+
...options?.previousResponseId !== void 0 ? { previous_response_id: options.previousResponseId } : {},
|
|
993
|
+
...options?.promptCacheKey !== void 0 ? { prompt_cache_key: options.promptCacheKey } : {},
|
|
994
|
+
...options?.promptCacheOptions !== void 0 ? { prompt_cache_options: options.promptCacheOptions } : {},
|
|
995
|
+
...options?.promptCacheRetention !== void 0 ? { prompt_cache_retention: options.promptCacheRetention } : {},
|
|
996
|
+
...options?.store === false || options?.include ? {
|
|
997
|
+
include: [
|
|
998
|
+
.../* @__PURE__ */ new Set([
|
|
999
|
+
...options?.include ?? [],
|
|
1000
|
+
...options?.store === false ? ["reasoning.encrypted_content"] : []
|
|
1001
|
+
])
|
|
1002
|
+
]
|
|
1003
|
+
} : {},
|
|
792
1004
|
...responsesTextFormat ? { text: { format: responsesTextFormat } } : {},
|
|
793
1005
|
stream
|
|
794
1006
|
};
|
|
@@ -847,6 +1059,10 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
847
1059
|
let usage;
|
|
848
1060
|
const citations = [];
|
|
849
1061
|
let completed = false;
|
|
1062
|
+
let terminalResponse;
|
|
1063
|
+
let responseIdentity = {};
|
|
1064
|
+
const outputItems = /* @__PURE__ */ new Map();
|
|
1065
|
+
let streamedText = "";
|
|
850
1066
|
function* flushToolCalls() {
|
|
851
1067
|
for (const call of toolCalls.values()) {
|
|
852
1068
|
if (!call.name)
|
|
@@ -863,17 +1079,36 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
863
1079
|
for await (const event of stream) {
|
|
864
1080
|
throwIfAborted(request.signal);
|
|
865
1081
|
logProviderPayload("openai", "stream chunk", event, request.debug);
|
|
1082
|
+
if (completed)
|
|
1083
|
+
throw new Error("Responses stream emitted an event after completion");
|
|
866
1084
|
const index = event?.output_index ?? 0;
|
|
867
1085
|
switch (event?.type) {
|
|
1086
|
+
case "response.created":
|
|
1087
|
+
responseIdentity = {
|
|
1088
|
+
id: event.response?.id,
|
|
1089
|
+
model: event.response?.model
|
|
1090
|
+
};
|
|
1091
|
+
break;
|
|
1092
|
+
case "response.output_item.done":
|
|
1093
|
+
if (event.item) outputItems.set(index, event.item);
|
|
1094
|
+
if (event.item?.type === "function_call") {
|
|
1095
|
+
toolCalls.set(index, {
|
|
1096
|
+
id: event.item.call_id,
|
|
1097
|
+
name: event.item.name,
|
|
1098
|
+
arguments: event.item.arguments
|
|
1099
|
+
});
|
|
1100
|
+
}
|
|
1101
|
+
break;
|
|
868
1102
|
case "response.output_text.delta":
|
|
869
1103
|
if (event.delta) {
|
|
1104
|
+
streamedText += event.delta;
|
|
870
1105
|
yield { type: "message:delta", content: event.delta };
|
|
871
1106
|
}
|
|
872
1107
|
break;
|
|
873
1108
|
case "response.output_item.added":
|
|
874
1109
|
if (event.item?.type === "function_call") {
|
|
875
1110
|
toolCalls.set(index, {
|
|
876
|
-
id: event.item.call_id ??
|
|
1111
|
+
id: event.item.call_id ?? "",
|
|
877
1112
|
name: event.item.name ?? "",
|
|
878
1113
|
arguments: event.item.arguments ?? ""
|
|
879
1114
|
});
|
|
@@ -892,7 +1127,10 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
892
1127
|
break;
|
|
893
1128
|
}
|
|
894
1129
|
case "response.completed": {
|
|
1130
|
+
if (event.response?.status && event.response.status !== "completed")
|
|
1131
|
+
throw new Error(`Responses stream ${event.response.status}`);
|
|
895
1132
|
completed = true;
|
|
1133
|
+
terminalResponse = { ...responseIdentity, ...event.response };
|
|
896
1134
|
const found = this.collectResponsesCitations(
|
|
897
1135
|
event.response?.output,
|
|
898
1136
|
citations.length
|
|
@@ -929,12 +1167,64 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
929
1167
|
throwIfAborted(request.signal);
|
|
930
1168
|
if (!completed)
|
|
931
1169
|
throw new Error("Responses stream ended without a completed response");
|
|
1170
|
+
const output = terminalResponse.output?.length ? terminalResponse.output : [...outputItems.entries()].sort(([a], [b]) => a - b).map(([, item]) => item);
|
|
1171
|
+
if (output.some((item) => item.type === "function_call"))
|
|
1172
|
+
toolCalls.clear();
|
|
1173
|
+
for (const [index, item] of output.entries()) {
|
|
1174
|
+
if (item.type === "function_call") {
|
|
1175
|
+
toolCalls.set(index, {
|
|
1176
|
+
id: item.call_id,
|
|
1177
|
+
name: item.name,
|
|
1178
|
+
arguments: item.arguments
|
|
1179
|
+
});
|
|
1180
|
+
}
|
|
1181
|
+
}
|
|
1182
|
+
const uniqueCalls = /* @__PURE__ */ new Map();
|
|
1183
|
+
for (const call of toolCalls.values()) {
|
|
1184
|
+
if (!call.id || !call.name)
|
|
1185
|
+
throw new Error("Responses stream contains an incomplete tool call");
|
|
1186
|
+
uniqueCalls.set(call.id, call);
|
|
1187
|
+
}
|
|
1188
|
+
toolCalls.clear();
|
|
1189
|
+
[...uniqueCalls.values()].forEach(
|
|
1190
|
+
(call, index) => toolCalls.set(index, call)
|
|
1191
|
+
);
|
|
1192
|
+
if (!output.length && toolCalls.size) {
|
|
1193
|
+
for (const call of toolCalls.values())
|
|
1194
|
+
output.push({
|
|
1195
|
+
type: "function_call",
|
|
1196
|
+
call_id: call.id,
|
|
1197
|
+
name: call.name,
|
|
1198
|
+
arguments: call.arguments
|
|
1199
|
+
});
|
|
1200
|
+
}
|
|
1201
|
+
if (!output.length && streamedText)
|
|
1202
|
+
output.push({
|
|
1203
|
+
type: "message",
|
|
1204
|
+
role: "assistant",
|
|
1205
|
+
content: [{ type: "output_text", text: streamedText, annotations: [] }]
|
|
1206
|
+
});
|
|
1207
|
+
terminalResponse.output = output;
|
|
1208
|
+
const finalText = this.parseResponsesResult(terminalResponse).content;
|
|
1209
|
+
if (finalText.startsWith(streamedText) && finalText.length > streamedText.length) {
|
|
1210
|
+
yield {
|
|
1211
|
+
type: "message:delta",
|
|
1212
|
+
content: finalText.slice(streamedText.length)
|
|
1213
|
+
};
|
|
1214
|
+
}
|
|
932
1215
|
yield* flushToolCalls();
|
|
933
1216
|
if (citations.length > 0) {
|
|
934
1217
|
yield { type: "citation", citations: deduplicateCitations(citations) };
|
|
935
1218
|
}
|
|
936
|
-
yield {
|
|
937
|
-
|
|
1219
|
+
yield {
|
|
1220
|
+
type: "message:end",
|
|
1221
|
+
providerMetadata: responseMetadata(terminalResponse)
|
|
1222
|
+
};
|
|
1223
|
+
yield {
|
|
1224
|
+
type: "done",
|
|
1225
|
+
usage,
|
|
1226
|
+
providerMetadata: responseMetadata(terminalResponse)
|
|
1227
|
+
};
|
|
938
1228
|
}
|
|
939
1229
|
async *stream(request) {
|
|
940
1230
|
throwIfAborted(request.signal);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { L as LanguageModel } from '../../types-
|
|
2
|
-
import { X as XAIProviderConfig, A as AIProvider } from '../../types-
|
|
1
|
+
import { L as LanguageModel } from '../../types-Dg1Bcg1k.mjs';
|
|
2
|
+
import { X as XAIProviderConfig, 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
|
* xAI Provider - Modern Pattern
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { L as LanguageModel } from '../../types-
|
|
2
|
-
import { X as XAIProviderConfig, A as AIProvider } from '../../types-
|
|
1
|
+
import { L as LanguageModel } from '../../types-Dg1Bcg1k.js';
|
|
2
|
+
import { X as XAIProviderConfig, 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
|
* xAI Provider - Modern Pattern
|