@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
|
}
|
|
@@ -503,7 +608,7 @@ function formatMessagesForOpenRouter(messages) {
|
|
|
503
608
|
return {
|
|
504
609
|
role: "tool",
|
|
505
610
|
tool_call_id: msg.toolCallId,
|
|
506
|
-
content: msg.content
|
|
611
|
+
content: textToolOutput(msg.modelOutput, msg.content)
|
|
507
612
|
};
|
|
508
613
|
default:
|
|
509
614
|
return msg;
|
|
@@ -534,6 +639,64 @@ async function searchOpenRouterModels(query, apiKey) {
|
|
|
534
639
|
);
|
|
535
640
|
}
|
|
536
641
|
|
|
642
|
+
// src/core/openai-responses.ts
|
|
643
|
+
function resolveOpenAITransport(defaults, overrides) {
|
|
644
|
+
return {
|
|
645
|
+
api: overrides?.api ?? defaults.api ?? "auto",
|
|
646
|
+
responses: defaults.responses !== void 0 || overrides?.responses !== void 0 ? { ...defaults.responses, ...overrides?.responses } : void 0
|
|
647
|
+
};
|
|
648
|
+
}
|
|
649
|
+
function useOpenAIResponses(model, baseURL, parameters, transport, hasTools, hasReplay, nativeToolSearch = false) {
|
|
650
|
+
const api = transport.api ?? "auto";
|
|
651
|
+
if (!["auto", "chat", "responses"].includes(api)) {
|
|
652
|
+
throw new Error(`Unknown OpenAI API selection: ${api}`);
|
|
653
|
+
}
|
|
654
|
+
if (api === "chat") {
|
|
655
|
+
if (transport.responses !== void 0 || nativeToolSearch) {
|
|
656
|
+
throw new Error(
|
|
657
|
+
"Responses options and native tool search require the Responses API"
|
|
658
|
+
);
|
|
659
|
+
}
|
|
660
|
+
return false;
|
|
661
|
+
}
|
|
662
|
+
let officialEndpoint = !baseURL;
|
|
663
|
+
try {
|
|
664
|
+
officialEndpoint = !baseURL || new URL(baseURL).hostname === "api.openai.com";
|
|
665
|
+
} catch {
|
|
666
|
+
}
|
|
667
|
+
return api === "responses" || transport.responses !== void 0 || hasReplay && officialEndpoint || nativeToolSearch || hasTools && requiresOpenAIResponses(model, baseURL, parameters);
|
|
668
|
+
}
|
|
669
|
+
function responseMetadata(response) {
|
|
670
|
+
const output = Array.isArray(response?.output) ? response.output : [];
|
|
671
|
+
return {
|
|
672
|
+
openai: {
|
|
673
|
+
response: {
|
|
674
|
+
id: response?.id,
|
|
675
|
+
model: response?.model,
|
|
676
|
+
status: response?.status,
|
|
677
|
+
output,
|
|
678
|
+
usage: response?.usage,
|
|
679
|
+
store: response?.store,
|
|
680
|
+
refusals: output.flatMap(
|
|
681
|
+
(item) => item?.type === "message" && Array.isArray(item.content) ? item.content.filter(
|
|
682
|
+
(part) => part?.type === "refusal" && typeof part.refusal === "string"
|
|
683
|
+
).map((part) => part.refusal) : []
|
|
684
|
+
)
|
|
685
|
+
}
|
|
686
|
+
}
|
|
687
|
+
};
|
|
688
|
+
}
|
|
689
|
+
function getResponseReplay(metadata) {
|
|
690
|
+
const response = metadata?.openai?.response;
|
|
691
|
+
if (response === void 0) return void 0;
|
|
692
|
+
if (!Array.isArray(response.output) || response.output.some((item) => !item || typeof item.type !== "string")) {
|
|
693
|
+
throw new Error(
|
|
694
|
+
"Invalid OpenAI Responses replay metadata: output must contain typed items"
|
|
695
|
+
);
|
|
696
|
+
}
|
|
697
|
+
return response.output;
|
|
698
|
+
}
|
|
699
|
+
|
|
537
700
|
// src/core/provider-error.ts
|
|
538
701
|
function providerErrorEvent(error, code) {
|
|
539
702
|
const details = error ?? {};
|
|
@@ -610,13 +773,16 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
610
773
|
}));
|
|
611
774
|
}
|
|
612
775
|
shouldUseResponsesApi(request) {
|
|
613
|
-
|
|
614
|
-
if (request.providerToolOptions?.openai?.nativeToolSearch?.enabled === true && request.providerToolOptions.openai.nativeToolSearch.useResponsesApi !== false)
|
|
615
|
-
return true;
|
|
616
|
-
return requiresOpenAIResponses(
|
|
776
|
+
return useOpenAIResponses(
|
|
617
777
|
request.config?.model || this.model,
|
|
618
778
|
this.config.baseUrl,
|
|
619
|
-
this.parameterOptions(request)
|
|
779
|
+
this.parameterOptions(request),
|
|
780
|
+
resolveOpenAITransport(this.config, request.config?.openai),
|
|
781
|
+
this.toolDefinitions(request).length > 0,
|
|
782
|
+
!!(request.rawMessages ?? request.messages)?.some(
|
|
783
|
+
(message) => message.providerMetadata?.openai?.response
|
|
784
|
+
),
|
|
785
|
+
request.providerToolOptions?.openai?.nativeToolSearch?.enabled === true && request.providerToolOptions.openai.nativeToolSearch.useResponsesApi !== false
|
|
620
786
|
);
|
|
621
787
|
}
|
|
622
788
|
/**
|
|
@@ -649,11 +815,11 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
649
815
|
});
|
|
650
816
|
}
|
|
651
817
|
buildResponsesInput(request) {
|
|
652
|
-
const sourceMessages = request.rawMessages && request.rawMessages.length > 0 ? this.formatRawMessages(request.rawMessages) : formatMessagesForOpenAI(request.messages, void 0);
|
|
818
|
+
const sourceMessages = request.rawMessages && request.rawMessages.length > 0 ? this.formatRawMessages(request.rawMessages, true) : formatMessagesForOpenAI(request.messages, void 0, true);
|
|
653
819
|
const input = [];
|
|
654
820
|
for (const message of sourceMessages) {
|
|
655
821
|
if (message.role === "system") {
|
|
656
|
-
if (
|
|
822
|
+
if (message.content && message.content !== request.systemPrompt) {
|
|
657
823
|
input.push({
|
|
658
824
|
type: "message",
|
|
659
825
|
role: "developer",
|
|
@@ -663,6 +829,11 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
663
829
|
continue;
|
|
664
830
|
}
|
|
665
831
|
if (message.role === "assistant") {
|
|
832
|
+
const replay = getResponseReplay(message.providerMetadata);
|
|
833
|
+
if (replay) {
|
|
834
|
+
input.push(...replay);
|
|
835
|
+
continue;
|
|
836
|
+
}
|
|
666
837
|
const content = this.toResponsesContent(message.content, "assistant");
|
|
667
838
|
if (typeof content === "string" ? content : Array.isArray(content) && content.length > 0) {
|
|
668
839
|
input.push({
|
|
@@ -686,7 +857,7 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
686
857
|
input.push({
|
|
687
858
|
type: "function_call_output",
|
|
688
859
|
call_id: message.tool_call_id,
|
|
689
|
-
output: typeof message.content === "string" ? message.content : JSON.stringify(message.content ?? null)
|
|
860
|
+
output: message.modelOutput ? toolOutputForProvider(message.modelOutput, "responses") : typeof message.content === "string" ? message.content : JSON.stringify(message.content ?? null)
|
|
690
861
|
});
|
|
691
862
|
continue;
|
|
692
863
|
}
|
|
@@ -700,10 +871,12 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
700
871
|
return input;
|
|
701
872
|
}
|
|
702
873
|
/** Preserve Copilot screenshot attachments on every OpenAI transport. */
|
|
703
|
-
formatRawMessages(messages) {
|
|
874
|
+
formatRawMessages(messages, preserveProviderMetadata = false) {
|
|
704
875
|
return messages.map((message) => {
|
|
705
|
-
const { attachments, ...rest } = message;
|
|
706
|
-
let content = message.content;
|
|
876
|
+
const { attachments, providerMetadata, modelOutput, ...rest } = message;
|
|
877
|
+
let content = message.role === "tool" && !preserveProviderMetadata ? textToolOutput(modelOutput, String(message.content ?? "")) : message.content;
|
|
878
|
+
if (preserveProviderMetadata && modelOutput)
|
|
879
|
+
rest.modelOutput = modelOutput;
|
|
707
880
|
if (message.role === "assistant" && Array.isArray(message.tool_calls) && message.tool_calls.length > 0 && content === "") {
|
|
708
881
|
content = null;
|
|
709
882
|
}
|
|
@@ -716,7 +889,11 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
716
889
|
content = [...parts, ...images];
|
|
717
890
|
}
|
|
718
891
|
}
|
|
719
|
-
return {
|
|
892
|
+
return {
|
|
893
|
+
...rest,
|
|
894
|
+
content,
|
|
895
|
+
...preserveProviderMetadata && providerMetadata ? { providerMetadata } : {}
|
|
896
|
+
};
|
|
720
897
|
});
|
|
721
898
|
}
|
|
722
899
|
/**
|
|
@@ -797,14 +974,25 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
797
974
|
).map((part) => part.text) : []
|
|
798
975
|
).join("") : "";
|
|
799
976
|
const content = textFromOutput || (typeof response?.output_text === "string" ? response.output_text : "");
|
|
800
|
-
const
|
|
801
|
-
|
|
802
|
-
name
|
|
803
|
-
|
|
804
|
-
|
|
977
|
+
const seenCallIds = /* @__PURE__ */ new Set();
|
|
978
|
+
const toolCalls = Array.isArray(response?.output) ? response.output.filter((item) => item?.type === "function_call").map((item) => {
|
|
979
|
+
if (typeof item.call_id !== "string" || !item.call_id || typeof item.name !== "string" || !item.name || typeof item.arguments !== "string" || item.status && item.status !== "completed") {
|
|
980
|
+
throw new Error("Responses contains an incomplete function call");
|
|
981
|
+
}
|
|
982
|
+
if (seenCallIds.has(item.call_id))
|
|
983
|
+
throw new Error("Responses contains duplicate function call IDs");
|
|
984
|
+
seenCallIds.add(item.call_id);
|
|
985
|
+
const args = JSON.parse(item.arguments);
|
|
986
|
+
if (!args || typeof args !== "object" || Array.isArray(args))
|
|
987
|
+
throw new Error(
|
|
988
|
+
"Responses function arguments must be a JSON object"
|
|
989
|
+
);
|
|
990
|
+
return { id: item.call_id, name: item.name, args };
|
|
991
|
+
}) : [];
|
|
805
992
|
return {
|
|
806
993
|
content,
|
|
807
994
|
toolCalls,
|
|
995
|
+
providerMetadata: responseMetadata(response),
|
|
808
996
|
usage: response?.usage ? {
|
|
809
997
|
promptTokens: response.usage.input_tokens ?? 0,
|
|
810
998
|
completionTokens: response.usage.output_tokens ?? 0,
|
|
@@ -815,6 +1003,17 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
815
1003
|
}
|
|
816
1004
|
buildResponsesPayload(request, stream) {
|
|
817
1005
|
const openaiToolOptions = request.providerToolOptions?.openai;
|
|
1006
|
+
const options = resolveOpenAITransport(
|
|
1007
|
+
this.config,
|
|
1008
|
+
request.config?.openai
|
|
1009
|
+
).responses;
|
|
1010
|
+
const parameters = buildOpenAIParameters(
|
|
1011
|
+
request.config?.model || this.model,
|
|
1012
|
+
request.config?.maxTokens ?? this.config.maxTokens,
|
|
1013
|
+
request.config?.temperature ?? this.config.temperature,
|
|
1014
|
+
this.parameterOptions(request),
|
|
1015
|
+
"responses"
|
|
1016
|
+
);
|
|
818
1017
|
const responsesTextFormat = toOpenAIResponsesTextFormat(
|
|
819
1018
|
request.config?.responseFormat
|
|
820
1019
|
);
|
|
@@ -830,13 +1029,26 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
830
1029
|
),
|
|
831
1030
|
tool_choice: openaiToolOptions?.toolChoice,
|
|
832
1031
|
parallel_tool_calls: openaiToolOptions?.parallelToolCalls,
|
|
833
|
-
...
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
1032
|
+
...parameters,
|
|
1033
|
+
...options?.reasoningSummary ? {
|
|
1034
|
+
reasoning: {
|
|
1035
|
+
...parameters.reasoning,
|
|
1036
|
+
summary: options.reasoningSummary
|
|
1037
|
+
}
|
|
1038
|
+
} : {},
|
|
1039
|
+
...options?.store !== void 0 ? { store: options.store } : {},
|
|
1040
|
+
...options?.previousResponseId !== void 0 ? { previous_response_id: options.previousResponseId } : {},
|
|
1041
|
+
...options?.promptCacheKey !== void 0 ? { prompt_cache_key: options.promptCacheKey } : {},
|
|
1042
|
+
...options?.promptCacheOptions !== void 0 ? { prompt_cache_options: options.promptCacheOptions } : {},
|
|
1043
|
+
...options?.promptCacheRetention !== void 0 ? { prompt_cache_retention: options.promptCacheRetention } : {},
|
|
1044
|
+
...options?.store === false || options?.include ? {
|
|
1045
|
+
include: [
|
|
1046
|
+
.../* @__PURE__ */ new Set([
|
|
1047
|
+
...options?.include ?? [],
|
|
1048
|
+
...options?.store === false ? ["reasoning.encrypted_content"] : []
|
|
1049
|
+
])
|
|
1050
|
+
]
|
|
1051
|
+
} : {},
|
|
840
1052
|
...responsesTextFormat ? { text: { format: responsesTextFormat } } : {},
|
|
841
1053
|
stream
|
|
842
1054
|
};
|
|
@@ -895,6 +1107,10 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
895
1107
|
let usage;
|
|
896
1108
|
const citations = [];
|
|
897
1109
|
let completed = false;
|
|
1110
|
+
let terminalResponse;
|
|
1111
|
+
let responseIdentity = {};
|
|
1112
|
+
const outputItems = /* @__PURE__ */ new Map();
|
|
1113
|
+
let streamedText = "";
|
|
898
1114
|
function* flushToolCalls() {
|
|
899
1115
|
for (const call of toolCalls.values()) {
|
|
900
1116
|
if (!call.name)
|
|
@@ -911,17 +1127,36 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
911
1127
|
for await (const event of stream) {
|
|
912
1128
|
throwIfAborted(request.signal);
|
|
913
1129
|
logProviderPayload("openai", "stream chunk", event, request.debug);
|
|
1130
|
+
if (completed)
|
|
1131
|
+
throw new Error("Responses stream emitted an event after completion");
|
|
914
1132
|
const index = event?.output_index ?? 0;
|
|
915
1133
|
switch (event?.type) {
|
|
1134
|
+
case "response.created":
|
|
1135
|
+
responseIdentity = {
|
|
1136
|
+
id: event.response?.id,
|
|
1137
|
+
model: event.response?.model
|
|
1138
|
+
};
|
|
1139
|
+
break;
|
|
1140
|
+
case "response.output_item.done":
|
|
1141
|
+
if (event.item) outputItems.set(index, event.item);
|
|
1142
|
+
if (event.item?.type === "function_call") {
|
|
1143
|
+
toolCalls.set(index, {
|
|
1144
|
+
id: event.item.call_id,
|
|
1145
|
+
name: event.item.name,
|
|
1146
|
+
arguments: event.item.arguments
|
|
1147
|
+
});
|
|
1148
|
+
}
|
|
1149
|
+
break;
|
|
916
1150
|
case "response.output_text.delta":
|
|
917
1151
|
if (event.delta) {
|
|
1152
|
+
streamedText += event.delta;
|
|
918
1153
|
yield { type: "message:delta", content: event.delta };
|
|
919
1154
|
}
|
|
920
1155
|
break;
|
|
921
1156
|
case "response.output_item.added":
|
|
922
1157
|
if (event.item?.type === "function_call") {
|
|
923
1158
|
toolCalls.set(index, {
|
|
924
|
-
id: event.item.call_id ??
|
|
1159
|
+
id: event.item.call_id ?? "",
|
|
925
1160
|
name: event.item.name ?? "",
|
|
926
1161
|
arguments: event.item.arguments ?? ""
|
|
927
1162
|
});
|
|
@@ -940,7 +1175,10 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
940
1175
|
break;
|
|
941
1176
|
}
|
|
942
1177
|
case "response.completed": {
|
|
1178
|
+
if (event.response?.status && event.response.status !== "completed")
|
|
1179
|
+
throw new Error(`Responses stream ${event.response.status}`);
|
|
943
1180
|
completed = true;
|
|
1181
|
+
terminalResponse = { ...responseIdentity, ...event.response };
|
|
944
1182
|
const found = this.collectResponsesCitations(
|
|
945
1183
|
event.response?.output,
|
|
946
1184
|
citations.length
|
|
@@ -977,12 +1215,64 @@ var OpenAIAdapter = class _OpenAIAdapter {
|
|
|
977
1215
|
throwIfAborted(request.signal);
|
|
978
1216
|
if (!completed)
|
|
979
1217
|
throw new Error("Responses stream ended without a completed response");
|
|
1218
|
+
const output = terminalResponse.output?.length ? terminalResponse.output : [...outputItems.entries()].sort(([a], [b]) => a - b).map(([, item]) => item);
|
|
1219
|
+
if (output.some((item) => item.type === "function_call"))
|
|
1220
|
+
toolCalls.clear();
|
|
1221
|
+
for (const [index, item] of output.entries()) {
|
|
1222
|
+
if (item.type === "function_call") {
|
|
1223
|
+
toolCalls.set(index, {
|
|
1224
|
+
id: item.call_id,
|
|
1225
|
+
name: item.name,
|
|
1226
|
+
arguments: item.arguments
|
|
1227
|
+
});
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
const uniqueCalls = /* @__PURE__ */ new Map();
|
|
1231
|
+
for (const call of toolCalls.values()) {
|
|
1232
|
+
if (!call.id || !call.name)
|
|
1233
|
+
throw new Error("Responses stream contains an incomplete tool call");
|
|
1234
|
+
uniqueCalls.set(call.id, call);
|
|
1235
|
+
}
|
|
1236
|
+
toolCalls.clear();
|
|
1237
|
+
[...uniqueCalls.values()].forEach(
|
|
1238
|
+
(call, index) => toolCalls.set(index, call)
|
|
1239
|
+
);
|
|
1240
|
+
if (!output.length && toolCalls.size) {
|
|
1241
|
+
for (const call of toolCalls.values())
|
|
1242
|
+
output.push({
|
|
1243
|
+
type: "function_call",
|
|
1244
|
+
call_id: call.id,
|
|
1245
|
+
name: call.name,
|
|
1246
|
+
arguments: call.arguments
|
|
1247
|
+
});
|
|
1248
|
+
}
|
|
1249
|
+
if (!output.length && streamedText)
|
|
1250
|
+
output.push({
|
|
1251
|
+
type: "message",
|
|
1252
|
+
role: "assistant",
|
|
1253
|
+
content: [{ type: "output_text", text: streamedText, annotations: [] }]
|
|
1254
|
+
});
|
|
1255
|
+
terminalResponse.output = output;
|
|
1256
|
+
const finalText = this.parseResponsesResult(terminalResponse).content;
|
|
1257
|
+
if (finalText.startsWith(streamedText) && finalText.length > streamedText.length) {
|
|
1258
|
+
yield {
|
|
1259
|
+
type: "message:delta",
|
|
1260
|
+
content: finalText.slice(streamedText.length)
|
|
1261
|
+
};
|
|
1262
|
+
}
|
|
980
1263
|
yield* flushToolCalls();
|
|
981
1264
|
if (citations.length > 0) {
|
|
982
1265
|
yield { type: "citation", citations: deduplicateCitations(citations) };
|
|
983
1266
|
}
|
|
984
|
-
yield {
|
|
985
|
-
|
|
1267
|
+
yield {
|
|
1268
|
+
type: "message:end",
|
|
1269
|
+
providerMetadata: responseMetadata(terminalResponse)
|
|
1270
|
+
};
|
|
1271
|
+
yield {
|
|
1272
|
+
type: "done",
|
|
1273
|
+
usage,
|
|
1274
|
+
providerMetadata: responseMetadata(terminalResponse)
|
|
1275
|
+
};
|
|
986
1276
|
}
|
|
987
1277
|
async *stream(request) {
|
|
988
1278
|
throwIfAborted(request.signal);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { L as LanguageModel } from '../../types-
|
|
2
|
-
import { A as AIProvider } from '../../types-
|
|
1
|
+
import { L as LanguageModel } from '../../types-Dg1Bcg1k.mjs';
|
|
2
|
+
import { 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
|
* Together AI Provider
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { L as LanguageModel } from '../../types-
|
|
2
|
-
import { A as AIProvider } from '../../types-
|
|
1
|
+
import { L as LanguageModel } from '../../types-Dg1Bcg1k.js';
|
|
2
|
+
import { 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
|
* Together AI Provider
|