@yourgpt/llm-sdk 2.6.0-beta.1 → 2.6.0-beta.3
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 +146 -0
- package/dist/adapters/index.d.mts +5 -5
- package/dist/adapters/index.d.ts +5 -5
- package/dist/adapters/index.js +437 -39
- package/dist/adapters/index.mjs +437 -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 +20 -36
- package/dist/index.d.ts +20 -36
- package/dist/index.js +327 -69
- package/dist/index.mjs +325 -70
- package/dist/providers/anthropic/index.d.mts +3 -3
- package/dist/providers/anthropic/index.d.ts +3 -3
- package/dist/providers/anthropic/index.js +116 -7
- package/dist/providers/anthropic/index.mjs +116 -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 +393 -31
- package/dist/providers/fireworks/index.mjs +393 -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 +393 -31
- package/dist/providers/google/index.mjs +393 -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 +822 -40
- package/dist/providers/openai/index.mjs +821 -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 +393 -31
- package/dist/providers/openrouter/index.mjs +393 -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 +393 -31
- package/dist/providers/togetherai/index.mjs +393 -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 +393 -31
- package/dist/providers/xai/index.mjs +393 -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
package/dist/index.js
CHANGED
|
@@ -3,13 +3,137 @@
|
|
|
3
3
|
var hono = require('hono');
|
|
4
4
|
var cors = require('hono/cors');
|
|
5
5
|
|
|
6
|
+
// src/core/openai-responses.ts
|
|
7
|
+
function responseReplayMetadata(metadata) {
|
|
8
|
+
const response = metadata?.openai?.response;
|
|
9
|
+
if (!response) return metadata;
|
|
10
|
+
const output = response.output.map((item) => {
|
|
11
|
+
const fields = ["type", "id", "status"];
|
|
12
|
+
switch (item.type) {
|
|
13
|
+
case "reasoning":
|
|
14
|
+
fields.push("encrypted_content");
|
|
15
|
+
break;
|
|
16
|
+
case "message":
|
|
17
|
+
fields.push("role", "phase");
|
|
18
|
+
break;
|
|
19
|
+
case "function_call":
|
|
20
|
+
fields.push("call_id", "name", "namespace", "arguments");
|
|
21
|
+
break;
|
|
22
|
+
case "tool_search_call":
|
|
23
|
+
fields.push("call_id", "execution", "arguments");
|
|
24
|
+
break;
|
|
25
|
+
case "tool_search_output":
|
|
26
|
+
fields.push("call_id", "tools");
|
|
27
|
+
break;
|
|
28
|
+
case "web_search_call":
|
|
29
|
+
fields.push("action");
|
|
30
|
+
break;
|
|
31
|
+
default:
|
|
32
|
+
return stripItemDiagnostics(item);
|
|
33
|
+
}
|
|
34
|
+
const replay = Object.fromEntries(
|
|
35
|
+
fields.filter((key) => item[key] !== void 0).map((key) => [key, item[key]])
|
|
36
|
+
);
|
|
37
|
+
if (item.type === "reasoning") replay.summary = [];
|
|
38
|
+
if (item.type === "message")
|
|
39
|
+
replay.content = Array.isArray(item.content) ? item.content.flatMap(
|
|
40
|
+
(part) => part?.type === "output_text" && typeof part.text === "string" ? [{ type: "output_text", text: part.text, annotations: [] }] : part?.type === "refusal" && typeof part.refusal === "string" ? [{ type: "refusal", refusal: part.refusal }] : []
|
|
41
|
+
) : [];
|
|
42
|
+
return stripItemDiagnostics(replay);
|
|
43
|
+
});
|
|
44
|
+
return { openai: { response: { output, refusals: [] } } };
|
|
45
|
+
}
|
|
46
|
+
function stripItemDiagnostics(item) {
|
|
47
|
+
const {
|
|
48
|
+
usage: _usage,
|
|
49
|
+
logprobs: _logprobs,
|
|
50
|
+
metadata: _metadata,
|
|
51
|
+
...state
|
|
52
|
+
} = item;
|
|
53
|
+
return state;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// src/core/tool-output.ts
|
|
57
|
+
var imageTypes = /* @__PURE__ */ new Set([
|
|
58
|
+
"image/png",
|
|
59
|
+
"image/jpeg",
|
|
60
|
+
"image/webp",
|
|
61
|
+
"image/gif"
|
|
62
|
+
]);
|
|
63
|
+
function normalizeToolOutput(value) {
|
|
64
|
+
const output = value;
|
|
65
|
+
if (output?.type !== "content" || !Array.isArray(output.content) || !output.content.length) {
|
|
66
|
+
throw new Error("Tool model output must contain a nonempty content array");
|
|
67
|
+
}
|
|
68
|
+
return {
|
|
69
|
+
type: "content",
|
|
70
|
+
content: output.content.map((part) => {
|
|
71
|
+
if (part?.type === "text" && typeof part.text === "string")
|
|
72
|
+
return { type: "text", text: part.text };
|
|
73
|
+
if (part?.type !== "image")
|
|
74
|
+
throw new Error("Unsupported tool output content type");
|
|
75
|
+
const sources = ["data", "url", "fileId"].filter((key) => key in part);
|
|
76
|
+
if (sources.length !== 1)
|
|
77
|
+
throw new Error(
|
|
78
|
+
"Tool image requires exactly one of data, url, or fileId"
|
|
79
|
+
);
|
|
80
|
+
if ("fileId" in part) {
|
|
81
|
+
if (part.provider !== "openai" || typeof part.fileId !== "string" || !part.fileId.trim())
|
|
82
|
+
throw new Error(
|
|
83
|
+
"Tool image file references must name the openai provider and fileId"
|
|
84
|
+
);
|
|
85
|
+
return { type: "image", fileId: part.fileId, provider: "openai" };
|
|
86
|
+
}
|
|
87
|
+
if ("url" in part) {
|
|
88
|
+
let url;
|
|
89
|
+
try {
|
|
90
|
+
url = new URL(part.url);
|
|
91
|
+
} catch {
|
|
92
|
+
throw new Error("Invalid tool image URL");
|
|
93
|
+
}
|
|
94
|
+
if (!["https:", "http:"].includes(url.protocol) || url.username || url.password)
|
|
95
|
+
throw new Error(
|
|
96
|
+
"Tool image URL must use HTTP(S) without credentials"
|
|
97
|
+
);
|
|
98
|
+
return { type: "image", url: url.href };
|
|
99
|
+
}
|
|
100
|
+
if (!("data" in part) || !imageTypes.has(part.mediaType))
|
|
101
|
+
throw new Error("Unsupported tool image media type");
|
|
102
|
+
let data = part.data instanceof Uint8Array ? Buffer.from(part.data).toString("base64") : part.data;
|
|
103
|
+
if (typeof data !== "string")
|
|
104
|
+
throw new Error("Tool image data must be base64 or bytes");
|
|
105
|
+
if (data.startsWith("data:")) {
|
|
106
|
+
const match = /^data:([^;,]+);base64,(.+)$/.exec(data);
|
|
107
|
+
if (!match || match[1] !== part.mediaType)
|
|
108
|
+
throw new Error(
|
|
109
|
+
"Tool image data URL media type does not match mediaType"
|
|
110
|
+
);
|
|
111
|
+
data = match[2];
|
|
112
|
+
}
|
|
113
|
+
if (!data.length || data.length % 4 !== 0 || !/^[A-Za-z0-9+/]+={0,2}$/.test(data))
|
|
114
|
+
throw new Error("Invalid tool image base64 data");
|
|
115
|
+
if (Buffer.byteLength(data, "base64") > 20 * 1024 * 1024)
|
|
116
|
+
throw new Error("Tool image exceeds 20 MiB");
|
|
117
|
+
if (Buffer.from(data, "base64").toString("base64") !== data)
|
|
118
|
+
throw new Error("Invalid tool image base64 data");
|
|
119
|
+
return { type: "image", data, mediaType: part.mediaType };
|
|
120
|
+
})
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
function resolveToolOutput(result, mapped) {
|
|
124
|
+
if (mapped !== void 0) return normalizeToolOutput(mapped);
|
|
125
|
+
const content = result?._aiContent;
|
|
126
|
+
return content !== void 0 ? normalizeToolOutput({ type: "content", content }) : void 0;
|
|
127
|
+
}
|
|
128
|
+
|
|
6
129
|
// src/core/tool.ts
|
|
7
130
|
function tool(config) {
|
|
8
131
|
return {
|
|
9
132
|
description: config.description,
|
|
10
133
|
parameters: config.parameters,
|
|
11
134
|
execute: config.execute,
|
|
12
|
-
hidden: config.hidden
|
|
135
|
+
hidden: config.hidden,
|
|
136
|
+
toModelOutput: config.toModelOutput
|
|
13
137
|
};
|
|
14
138
|
}
|
|
15
139
|
function toolToJsonSchema(toolDef) {
|
|
@@ -157,6 +281,7 @@ async function generateText(params) {
|
|
|
157
281
|
const formattedTools = tools ? formatToolsForProvider(tools, model.provider) : void 0;
|
|
158
282
|
const result = await model.doGenerate({
|
|
159
283
|
messages,
|
|
284
|
+
openai: params.openai,
|
|
160
285
|
tools: formattedTools,
|
|
161
286
|
temperature: params.temperature,
|
|
162
287
|
reasoningEffort: params.reasoningEffort,
|
|
@@ -165,10 +290,11 @@ async function generateText(params) {
|
|
|
165
290
|
signal
|
|
166
291
|
});
|
|
167
292
|
throwIfAborted(signal);
|
|
293
|
+
const toolCalls = result.toolCalls ?? [];
|
|
168
294
|
const stepToolResults = [];
|
|
169
|
-
if (
|
|
170
|
-
allToolCalls.push(...
|
|
171
|
-
for (const call of
|
|
295
|
+
if (toolCalls.length > 0 && tools) {
|
|
296
|
+
allToolCalls.push(...toolCalls);
|
|
297
|
+
for (const call of toolCalls) {
|
|
172
298
|
throwIfAborted(signal);
|
|
173
299
|
const toolDef = tools[call.name];
|
|
174
300
|
if (!toolDef) {
|
|
@@ -190,7 +316,11 @@ async function generateText(params) {
|
|
|
190
316
|
throwIfAborted(signal);
|
|
191
317
|
const result2 = {
|
|
192
318
|
toolCallId: call.id,
|
|
193
|
-
result: toolResult
|
|
319
|
+
result: toolResult,
|
|
320
|
+
modelOutput: resolveToolOutput(
|
|
321
|
+
toolResult,
|
|
322
|
+
toolDef.toModelOutput?.(toolResult)
|
|
323
|
+
)
|
|
194
324
|
};
|
|
195
325
|
stepToolResults.push(result2);
|
|
196
326
|
allToolResults.push(result2);
|
|
@@ -209,25 +339,26 @@ async function generateText(params) {
|
|
|
209
339
|
}
|
|
210
340
|
steps.push({
|
|
211
341
|
text: result.text,
|
|
212
|
-
toolCalls
|
|
342
|
+
toolCalls,
|
|
213
343
|
toolResults: stepToolResults,
|
|
214
344
|
finishReason: result.finishReason,
|
|
215
|
-
usage: result.usage
|
|
345
|
+
usage: result.usage,
|
|
346
|
+
providerMetadata: result.providerMetadata
|
|
216
347
|
});
|
|
217
|
-
if (!result.toolCalls || result.toolCalls.length === 0) {
|
|
218
|
-
break;
|
|
219
|
-
}
|
|
220
348
|
const assistantMessage = {
|
|
221
349
|
role: "assistant",
|
|
222
350
|
content: result.text || null,
|
|
223
|
-
toolCalls:
|
|
351
|
+
...toolCalls.length ? { toolCalls } : {},
|
|
352
|
+
...result.providerMetadata ? { providerMetadata: responseReplayMetadata(result.providerMetadata) } : {}
|
|
224
353
|
};
|
|
225
354
|
messages = [...messages, assistantMessage];
|
|
355
|
+
if (toolCalls.length === 0) break;
|
|
226
356
|
for (const tr of stepToolResults) {
|
|
227
357
|
const toolMessage = {
|
|
228
358
|
role: "tool",
|
|
229
359
|
toolCallId: tr.toolCallId,
|
|
230
|
-
content: JSON.stringify(tr.result)
|
|
360
|
+
content: tr.modelOutput ? "[Tool returned content]" : JSON.stringify(tr.result),
|
|
361
|
+
...tr.modelOutput ? { modelOutput: tr.modelOutput } : {}
|
|
231
362
|
};
|
|
232
363
|
messages = [...messages, toolMessage];
|
|
233
364
|
}
|
|
@@ -235,6 +366,7 @@ async function generateText(params) {
|
|
|
235
366
|
const lastStep = steps[steps.length - 1];
|
|
236
367
|
return {
|
|
237
368
|
text: lastStep?.text ?? "",
|
|
369
|
+
providerMetadata: lastStep?.providerMetadata,
|
|
238
370
|
usage: sumUsage(steps),
|
|
239
371
|
finishReason: lastStep?.finishReason ?? "stop",
|
|
240
372
|
steps,
|
|
@@ -288,6 +420,8 @@ async function streamText(params) {
|
|
|
288
420
|
`[llm-sdk] ${model.provider}/${model.modelId} does not support structured output (responseFormat); the request will be sent but the provider may ignore it.`
|
|
289
421
|
);
|
|
290
422
|
}
|
|
423
|
+
let messages = buildMessages2(params);
|
|
424
|
+
let finalProviderMetadata;
|
|
291
425
|
let fullText = "";
|
|
292
426
|
let finalUsage = {
|
|
293
427
|
promptTokens: 0,
|
|
@@ -296,7 +430,6 @@ async function streamText(params) {
|
|
|
296
430
|
};
|
|
297
431
|
let finalFinishReason = "stop";
|
|
298
432
|
async function* createFullStream() {
|
|
299
|
-
let messages = buildMessages2(params);
|
|
300
433
|
for (let step = 0; step < maxSteps; step++) {
|
|
301
434
|
yield { type: "step-start", step };
|
|
302
435
|
if (signal?.aborted) {
|
|
@@ -305,11 +438,13 @@ async function streamText(params) {
|
|
|
305
438
|
}
|
|
306
439
|
const formattedTools = tools ? formatToolsForProvider2(tools, model.provider) : void 0;
|
|
307
440
|
let stepText = "";
|
|
441
|
+
let stepProviderMetadata;
|
|
308
442
|
const toolCalls = [];
|
|
309
443
|
let stepFinishReason = "stop";
|
|
310
444
|
try {
|
|
311
445
|
for await (const chunk of model.doStream({
|
|
312
446
|
messages,
|
|
447
|
+
openai: params.openai,
|
|
313
448
|
tools: formattedTools,
|
|
314
449
|
temperature: params.temperature,
|
|
315
450
|
reasoningEffort: params.reasoningEffort,
|
|
@@ -332,6 +467,8 @@ async function streamText(params) {
|
|
|
332
467
|
};
|
|
333
468
|
break;
|
|
334
469
|
case "finish":
|
|
470
|
+
stepProviderMetadata = chunk.providerMetadata;
|
|
471
|
+
finalProviderMetadata = chunk.providerMetadata;
|
|
335
472
|
stepFinishReason = chunk.finishReason;
|
|
336
473
|
finalFinishReason = chunk.finishReason;
|
|
337
474
|
if (chunk.usage) {
|
|
@@ -354,16 +491,22 @@ async function streamText(params) {
|
|
|
354
491
|
};
|
|
355
492
|
return;
|
|
356
493
|
}
|
|
357
|
-
yield {
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
role: "assistant",
|
|
363
|
-
content: stepText || null,
|
|
364
|
-
toolCalls
|
|
494
|
+
yield {
|
|
495
|
+
type: "step-finish",
|
|
496
|
+
step,
|
|
497
|
+
finishReason: stepFinishReason,
|
|
498
|
+
providerMetadata: stepProviderMetadata
|
|
365
499
|
};
|
|
366
|
-
messages = [
|
|
500
|
+
messages = [
|
|
501
|
+
...messages,
|
|
502
|
+
{
|
|
503
|
+
role: "assistant",
|
|
504
|
+
content: stepText || null,
|
|
505
|
+
...toolCalls.length ? { toolCalls } : {},
|
|
506
|
+
...stepProviderMetadata ? { providerMetadata: responseReplayMetadata(stepProviderMetadata) } : {}
|
|
507
|
+
}
|
|
508
|
+
];
|
|
509
|
+
if (toolCalls.length === 0 || !tools) break;
|
|
367
510
|
for (const call of toolCalls) {
|
|
368
511
|
throwIfAborted(signal);
|
|
369
512
|
const toolDef = tools[call.name];
|
|
@@ -392,13 +535,23 @@ async function streamText(params) {
|
|
|
392
535
|
messages
|
|
393
536
|
});
|
|
394
537
|
throwIfAborted(signal);
|
|
395
|
-
|
|
538
|
+
const modelOutput = resolveToolOutput(
|
|
539
|
+
result,
|
|
540
|
+
toolDef.toModelOutput?.(result)
|
|
541
|
+
);
|
|
542
|
+
yield {
|
|
543
|
+
type: "tool-result",
|
|
544
|
+
toolCallId: call.id,
|
|
545
|
+
result,
|
|
546
|
+
modelOutput
|
|
547
|
+
};
|
|
396
548
|
messages = [
|
|
397
549
|
...messages,
|
|
398
550
|
{
|
|
399
551
|
role: "tool",
|
|
400
552
|
toolCallId: call.id,
|
|
401
|
-
content: JSON.stringify(result)
|
|
553
|
+
content: modelOutput ? "[Tool returned content]" : JSON.stringify(result),
|
|
554
|
+
...modelOutput ? { modelOutput } : {}
|
|
402
555
|
}
|
|
403
556
|
];
|
|
404
557
|
} catch (error) {
|
|
@@ -425,7 +578,8 @@ async function streamText(params) {
|
|
|
425
578
|
yield {
|
|
426
579
|
type: "finish",
|
|
427
580
|
finishReason: finalFinishReason,
|
|
428
|
-
usage: finalUsage
|
|
581
|
+
usage: finalUsage,
|
|
582
|
+
providerMetadata: finalProviderMetadata
|
|
429
583
|
};
|
|
430
584
|
}
|
|
431
585
|
const source = createFullStream();
|
|
@@ -477,6 +631,12 @@ async function streamText(params) {
|
|
|
477
631
|
return {
|
|
478
632
|
textStream: createTextStream(),
|
|
479
633
|
fullStream: sharedStream(),
|
|
634
|
+
get response() {
|
|
635
|
+
return consumeStream().then(() => ({ messages }));
|
|
636
|
+
},
|
|
637
|
+
get providerMetadata() {
|
|
638
|
+
return consumeStream().then(() => finalProviderMetadata);
|
|
639
|
+
},
|
|
480
640
|
get text() {
|
|
481
641
|
return consumeStream().then(() => fullText);
|
|
482
642
|
},
|
|
@@ -600,6 +760,7 @@ function createMessage(partial) {
|
|
|
600
760
|
tool_calls: partial.tool_calls,
|
|
601
761
|
tool_call_id: partial.tool_call_id,
|
|
602
762
|
metadata: partial.metadata,
|
|
763
|
+
providerMetadata: partial.providerMetadata,
|
|
603
764
|
created_at: partial.created_at ?? /* @__PURE__ */ new Date()
|
|
604
765
|
};
|
|
605
766
|
}
|
|
@@ -648,7 +809,13 @@ function mapOutputMessages(resultMessages) {
|
|
|
648
809
|
role: m.role,
|
|
649
810
|
content: m.content ?? "",
|
|
650
811
|
toolCalls: m.tool_calls,
|
|
651
|
-
toolCallId: m.tool_call_id
|
|
812
|
+
toolCallId: m.tool_call_id,
|
|
813
|
+
...m.providerMetadata || m.modelOutput ? {
|
|
814
|
+
metadata: {
|
|
815
|
+
...m.providerMetadata ? { providerMetadata: m.providerMetadata } : {},
|
|
816
|
+
...m.modelOutput ? { modelOutput: m.modelOutput } : {}
|
|
817
|
+
}
|
|
818
|
+
} : {}
|
|
652
819
|
}));
|
|
653
820
|
}
|
|
654
821
|
|
|
@@ -668,17 +835,32 @@ function createTextStreamHeaders() {
|
|
|
668
835
|
};
|
|
669
836
|
}
|
|
670
837
|
function formatSSEData(event) {
|
|
671
|
-
|
|
838
|
+
const safeEvent = { ...event };
|
|
839
|
+
if ("providerMetadata" in safeEvent)
|
|
840
|
+
safeEvent.providerMetadata = responseReplayMetadata(
|
|
841
|
+
safeEvent.providerMetadata
|
|
842
|
+
);
|
|
843
|
+
if (safeEvent.type === "done" && safeEvent.messages)
|
|
844
|
+
safeEvent.messages = safeEvent.messages.map((message) => ({
|
|
845
|
+
...message,
|
|
846
|
+
...message.providerMetadata ? { providerMetadata: responseReplayMetadata(message.providerMetadata) } : {}
|
|
847
|
+
}));
|
|
848
|
+
return `data: ${JSON.stringify(safeEvent)}
|
|
672
849
|
|
|
673
850
|
`;
|
|
674
851
|
}
|
|
675
|
-
function createEventStream(generator) {
|
|
852
|
+
function createEventStream(generator, options) {
|
|
676
853
|
const encoder = new TextEncoder();
|
|
677
854
|
return new ReadableStream({
|
|
678
855
|
async start(controller) {
|
|
679
856
|
try {
|
|
680
857
|
for await (const event of generator) {
|
|
681
|
-
|
|
858
|
+
let clientEvent = event;
|
|
859
|
+
if (event.type === "done" && !options?.includeUsage) {
|
|
860
|
+
const { usage: _usage, ...withoutUsage } = event;
|
|
861
|
+
clientEvent = withoutUsage;
|
|
862
|
+
}
|
|
863
|
+
const data = formatSSEData(clientEvent);
|
|
682
864
|
controller.enqueue(encoder.encode(data));
|
|
683
865
|
}
|
|
684
866
|
} catch (error) {
|
|
@@ -819,7 +1001,9 @@ var StreamResult = class {
|
|
|
819
1001
|
...createSSEHeaders(),
|
|
820
1002
|
...options?.headers
|
|
821
1003
|
};
|
|
822
|
-
return new Response(createEventStream(this.generator), {
|
|
1004
|
+
return new Response(createEventStream(this.generator, options), {
|
|
1005
|
+
headers
|
|
1006
|
+
});
|
|
823
1007
|
}
|
|
824
1008
|
/**
|
|
825
1009
|
* Alias for toResponse() - returns SSE Response
|
|
@@ -1538,9 +1722,6 @@ function buildProviderToolOptions(params) {
|
|
|
1538
1722
|
function buildToolResultForAI(tool2, result, args) {
|
|
1539
1723
|
const typedResult = result;
|
|
1540
1724
|
const responseMode = typedResult?._aiResponseMode ?? tool2?.aiResponseMode ?? "full";
|
|
1541
|
-
if (typedResult?._aiContent && typedResult._aiContent.length > 0) {
|
|
1542
|
-
return typedResult._aiContent;
|
|
1543
|
-
}
|
|
1544
1725
|
let aiContext;
|
|
1545
1726
|
if (typedResult?._aiContext) {
|
|
1546
1727
|
aiContext = typedResult._aiContext;
|
|
@@ -1560,25 +1741,6 @@ function buildToolResultForAI(tool2, result, args) {
|
|
|
1560
1741
|
Full data: ${fullData}` : fullData;
|
|
1561
1742
|
}
|
|
1562
1743
|
}
|
|
1563
|
-
function serializeToolResultContent(content) {
|
|
1564
|
-
if (typeof content === "string") {
|
|
1565
|
-
return content;
|
|
1566
|
-
}
|
|
1567
|
-
return content.map((item) => {
|
|
1568
|
-
if (item.type === "image") {
|
|
1569
|
-
return {
|
|
1570
|
-
type: "image_url",
|
|
1571
|
-
image_url: {
|
|
1572
|
-
url: `data:${item.mediaType};base64,${item.data}`
|
|
1573
|
-
}
|
|
1574
|
-
};
|
|
1575
|
-
}
|
|
1576
|
-
return {
|
|
1577
|
-
type: "text",
|
|
1578
|
-
text: item.text
|
|
1579
|
-
};
|
|
1580
|
-
});
|
|
1581
|
-
}
|
|
1582
1744
|
function extractHeaders(request) {
|
|
1583
1745
|
if (!request) return {};
|
|
1584
1746
|
const headers = {};
|
|
@@ -1635,7 +1797,11 @@ var Runtime = class {
|
|
|
1635
1797
|
const messages = request.messages.map(
|
|
1636
1798
|
(m, i) => createMessage({
|
|
1637
1799
|
role: m.role,
|
|
1638
|
-
content: m.content
|
|
1800
|
+
content: m.content,
|
|
1801
|
+
providerMetadata: m.providerMetadata,
|
|
1802
|
+
modelOutput: m.modelOutput,
|
|
1803
|
+
tool_calls: m.tool_calls,
|
|
1804
|
+
tool_call_id: m.tool_call_id
|
|
1639
1805
|
})
|
|
1640
1806
|
);
|
|
1641
1807
|
const allActions = [...this.actions.values()];
|
|
@@ -2252,6 +2418,7 @@ var Runtime = class {
|
|
|
2252
2418
|
let currentToolCall = null;
|
|
2253
2419
|
const serverToolResults = [];
|
|
2254
2420
|
const toolContextData = "toolContext" in this.config ? this.config.toolContext : void 0;
|
|
2421
|
+
let adapterProviderMetadata;
|
|
2255
2422
|
let adapterUsage;
|
|
2256
2423
|
const completionRequest = {
|
|
2257
2424
|
messages: [],
|
|
@@ -2279,7 +2446,10 @@ var Runtime = class {
|
|
|
2279
2446
|
yield event;
|
|
2280
2447
|
break;
|
|
2281
2448
|
case "message:end":
|
|
2282
|
-
yield
|
|
2449
|
+
yield {
|
|
2450
|
+
...event,
|
|
2451
|
+
providerMetadata: responseReplayMetadata(event.providerMetadata)
|
|
2452
|
+
};
|
|
2283
2453
|
break;
|
|
2284
2454
|
case "message:delta":
|
|
2285
2455
|
accumulatedText += event.content;
|
|
@@ -2350,18 +2520,24 @@ var Runtime = class {
|
|
|
2350
2520
|
);
|
|
2351
2521
|
try {
|
|
2352
2522
|
const result = await tool2.handler(args, toolContext);
|
|
2523
|
+
const modelOutput = resolveToolOutput(
|
|
2524
|
+
result,
|
|
2525
|
+
tool2.toModelOutput?.(result)
|
|
2526
|
+
);
|
|
2353
2527
|
serverToolResults.push({
|
|
2354
2528
|
id: event.id,
|
|
2355
2529
|
name: toolName,
|
|
2356
2530
|
args,
|
|
2357
2531
|
result,
|
|
2532
|
+
modelOutput,
|
|
2358
2533
|
tool: tool2
|
|
2359
2534
|
});
|
|
2360
2535
|
yield {
|
|
2361
2536
|
type: "action:end",
|
|
2362
2537
|
id: event.id,
|
|
2363
2538
|
name: toolName,
|
|
2364
|
-
result
|
|
2539
|
+
result,
|
|
2540
|
+
modelOutput
|
|
2365
2541
|
};
|
|
2366
2542
|
} catch (error) {
|
|
2367
2543
|
const errorResult = {
|
|
@@ -2395,6 +2571,9 @@ var Runtime = class {
|
|
|
2395
2571
|
return;
|
|
2396
2572
|
// Exit on error
|
|
2397
2573
|
case "done":
|
|
2574
|
+
adapterProviderMetadata = responseReplayMetadata(
|
|
2575
|
+
event.providerMetadata
|
|
2576
|
+
);
|
|
2398
2577
|
if (event.usage) {
|
|
2399
2578
|
adapterUsage = event.usage;
|
|
2400
2579
|
}
|
|
@@ -2415,11 +2594,11 @@ var Runtime = class {
|
|
|
2415
2594
|
(tc) => !serverToolIds.has(tc.id)
|
|
2416
2595
|
);
|
|
2417
2596
|
const serverToolResultMessages = serverToolResults.map((tr) => {
|
|
2418
|
-
const
|
|
2419
|
-
const content = typeof aiContent === "string" ? aiContent : JSON.stringify(serializeToolResultContent(aiContent));
|
|
2597
|
+
const content = tr.modelOutput ? "[Tool returned content]" : buildToolResultForAI(tr.tool, tr.result, tr.args);
|
|
2420
2598
|
return {
|
|
2421
2599
|
role: "tool",
|
|
2422
2600
|
content,
|
|
2601
|
+
...tr.modelOutput ? { modelOutput: tr.modelOutput } : {},
|
|
2423
2602
|
tool_call_id: tr.id
|
|
2424
2603
|
};
|
|
2425
2604
|
});
|
|
@@ -2432,6 +2611,7 @@ var Runtime = class {
|
|
|
2432
2611
|
const assistantMessage = {
|
|
2433
2612
|
role: "assistant",
|
|
2434
2613
|
content: accumulatedText || null,
|
|
2614
|
+
...adapterProviderMetadata ? { providerMetadata: adapterProviderMetadata } : {},
|
|
2435
2615
|
tool_calls: toolCalls.map((tc) => ({
|
|
2436
2616
|
id: tc.id,
|
|
2437
2617
|
type: "function",
|
|
@@ -2466,6 +2646,7 @@ var Runtime = class {
|
|
|
2466
2646
|
const assistantWithToolCalls = {
|
|
2467
2647
|
role: "assistant",
|
|
2468
2648
|
content: accumulatedText || null,
|
|
2649
|
+
...adapterProviderMetadata ? { providerMetadata: adapterProviderMetadata } : {},
|
|
2469
2650
|
tool_calls: serverToolResults.map((tr) => {
|
|
2470
2651
|
const tc = toolCalls.find((t) => t.id === tr.id);
|
|
2471
2652
|
return {
|
|
@@ -2516,6 +2697,7 @@ var Runtime = class {
|
|
|
2516
2697
|
const assistantMessage = {
|
|
2517
2698
|
role: "assistant",
|
|
2518
2699
|
content: accumulatedText || null,
|
|
2700
|
+
...adapterProviderMetadata ? { providerMetadata: adapterProviderMetadata } : {},
|
|
2519
2701
|
tool_calls: clientToolCalls.map((tc) => ({
|
|
2520
2702
|
id: tc.id,
|
|
2521
2703
|
type: "function",
|
|
@@ -2541,10 +2723,11 @@ var Runtime = class {
|
|
|
2541
2723
|
return;
|
|
2542
2724
|
}
|
|
2543
2725
|
}
|
|
2544
|
-
if (accumulatedText) {
|
|
2726
|
+
if (accumulatedText || adapterProviderMetadata) {
|
|
2545
2727
|
newMessages.push({
|
|
2546
2728
|
role: "assistant",
|
|
2547
|
-
content: accumulatedText
|
|
2729
|
+
content: accumulatedText,
|
|
2730
|
+
...adapterProviderMetadata ? { providerMetadata: adapterProviderMetadata } : {}
|
|
2548
2731
|
});
|
|
2549
2732
|
}
|
|
2550
2733
|
if (debug) {
|
|
@@ -2659,7 +2842,10 @@ var Runtime = class {
|
|
|
2659
2842
|
content: result.content
|
|
2660
2843
|
};
|
|
2661
2844
|
}
|
|
2662
|
-
yield {
|
|
2845
|
+
yield {
|
|
2846
|
+
type: "message:end",
|
|
2847
|
+
providerMetadata: responseReplayMetadata(result.providerMetadata)
|
|
2848
|
+
};
|
|
2663
2849
|
if (result.toolCalls.length > 0) {
|
|
2664
2850
|
const serverToolCalls = [];
|
|
2665
2851
|
const clientToolCalls = [];
|
|
@@ -2706,18 +2892,24 @@ var Runtime = class {
|
|
|
2706
2892
|
);
|
|
2707
2893
|
try {
|
|
2708
2894
|
const toolResult = await tool2.handler(tc.args, toolContext);
|
|
2895
|
+
const modelOutput = resolveToolOutput(
|
|
2896
|
+
toolResult,
|
|
2897
|
+
tool2.toModelOutput?.(toolResult)
|
|
2898
|
+
);
|
|
2709
2899
|
serverToolResults.push({
|
|
2710
2900
|
id: tc.id,
|
|
2711
2901
|
name: tc.name,
|
|
2712
2902
|
args: tc.args,
|
|
2713
2903
|
result: toolResult,
|
|
2904
|
+
modelOutput,
|
|
2714
2905
|
tool: tool2
|
|
2715
2906
|
});
|
|
2716
2907
|
yield {
|
|
2717
2908
|
type: "action:end",
|
|
2718
2909
|
id: tc.id,
|
|
2719
2910
|
name: tc.name,
|
|
2720
|
-
result: toolResult
|
|
2911
|
+
result: toolResult,
|
|
2912
|
+
modelOutput
|
|
2721
2913
|
};
|
|
2722
2914
|
} catch (error) {
|
|
2723
2915
|
const errorResult = {
|
|
@@ -2741,15 +2933,11 @@ var Runtime = class {
|
|
|
2741
2933
|
}
|
|
2742
2934
|
}
|
|
2743
2935
|
const serverToolResultMessages = serverToolResults.map((tr) => {
|
|
2744
|
-
const
|
|
2745
|
-
tr.tool,
|
|
2746
|
-
tr.result,
|
|
2747
|
-
tr.args
|
|
2748
|
-
);
|
|
2749
|
-
const content = typeof aiContent === "string" ? aiContent : JSON.stringify(serializeToolResultContent(aiContent));
|
|
2936
|
+
const content = tr.modelOutput ? "[Tool returned content]" : buildToolResultForAI(tr.tool, tr.result, tr.args);
|
|
2750
2937
|
return {
|
|
2751
2938
|
role: "tool",
|
|
2752
2939
|
content,
|
|
2940
|
+
...tr.modelOutput ? { modelOutput: tr.modelOutput } : {},
|
|
2753
2941
|
tool_call_id: tr.id
|
|
2754
2942
|
};
|
|
2755
2943
|
});
|
|
@@ -2757,6 +2945,11 @@ var Runtime = class {
|
|
|
2757
2945
|
const assistantMessage = {
|
|
2758
2946
|
role: "assistant",
|
|
2759
2947
|
content: result.content || null,
|
|
2948
|
+
...result.providerMetadata ? {
|
|
2949
|
+
providerMetadata: responseReplayMetadata(
|
|
2950
|
+
result.providerMetadata
|
|
2951
|
+
)
|
|
2952
|
+
} : {},
|
|
2760
2953
|
tool_calls: result.toolCalls.map((tc) => ({
|
|
2761
2954
|
id: tc.id,
|
|
2762
2955
|
type: "function",
|
|
@@ -2786,6 +2979,11 @@ var Runtime = class {
|
|
|
2786
2979
|
const assistantWithToolCalls = {
|
|
2787
2980
|
role: "assistant",
|
|
2788
2981
|
content: result.content || null,
|
|
2982
|
+
...result.providerMetadata ? {
|
|
2983
|
+
providerMetadata: responseReplayMetadata(
|
|
2984
|
+
result.providerMetadata
|
|
2985
|
+
)
|
|
2986
|
+
} : {},
|
|
2789
2987
|
tool_calls: result.toolCalls.map((tc) => ({
|
|
2790
2988
|
id: tc.id,
|
|
2791
2989
|
type: "function",
|
|
@@ -2817,6 +3015,11 @@ var Runtime = class {
|
|
|
2817
3015
|
const assistantMessage = {
|
|
2818
3016
|
role: "assistant",
|
|
2819
3017
|
content: result.content || null,
|
|
3018
|
+
...result.providerMetadata ? {
|
|
3019
|
+
providerMetadata: responseReplayMetadata(
|
|
3020
|
+
result.providerMetadata
|
|
3021
|
+
)
|
|
3022
|
+
} : {},
|
|
2820
3023
|
tool_calls: clientToolCalls.map((tc) => ({
|
|
2821
3024
|
id: tc.id,
|
|
2822
3025
|
type: "function",
|
|
@@ -2842,10 +3045,15 @@ var Runtime = class {
|
|
|
2842
3045
|
return;
|
|
2843
3046
|
}
|
|
2844
3047
|
}
|
|
2845
|
-
if (result.content) {
|
|
3048
|
+
if (result.content || result.providerMetadata) {
|
|
2846
3049
|
newMessages.push({
|
|
2847
3050
|
role: "assistant",
|
|
2848
|
-
content: result.content
|
|
3051
|
+
content: result.content,
|
|
3052
|
+
...result.providerMetadata ? {
|
|
3053
|
+
providerMetadata: responseReplayMetadata(
|
|
3054
|
+
result.providerMetadata
|
|
3055
|
+
)
|
|
3056
|
+
} : {}
|
|
2849
3057
|
});
|
|
2850
3058
|
}
|
|
2851
3059
|
if (debug) {
|
|
@@ -3997,6 +4205,54 @@ async function executeToolCalls(toolCalls, tools, executeServerTool, waitForClie
|
|
|
3997
4205
|
return results;
|
|
3998
4206
|
}
|
|
3999
4207
|
|
|
4208
|
+
// src/core/audio.ts
|
|
4209
|
+
var audioErrorMarker = /* @__PURE__ */ Symbol.for("@yourgpt/llm-sdk/AudioAPIError");
|
|
4210
|
+
var _a;
|
|
4211
|
+
var AudioAPIError = class extends Error {
|
|
4212
|
+
constructor(message, code, status, requestId) {
|
|
4213
|
+
super(message);
|
|
4214
|
+
this.code = code;
|
|
4215
|
+
this.status = status;
|
|
4216
|
+
this.requestId = requestId;
|
|
4217
|
+
this[_a] = true;
|
|
4218
|
+
this.name = "AudioAPIError";
|
|
4219
|
+
}
|
|
4220
|
+
static [(_a = audioErrorMarker, Symbol.hasInstance)](value) {
|
|
4221
|
+
return !!value && typeof value === "object" && value[audioErrorMarker] === true;
|
|
4222
|
+
}
|
|
4223
|
+
};
|
|
4224
|
+
async function generateSpeech({
|
|
4225
|
+
model,
|
|
4226
|
+
...options
|
|
4227
|
+
}) {
|
|
4228
|
+
options.signal?.throwIfAborted();
|
|
4229
|
+
if (typeof options.text !== "string" || !options.text.trim())
|
|
4230
|
+
throw new AudioAPIError("Speech text must not be empty", "invalid_input");
|
|
4231
|
+
const result = await model.doGenerate(options);
|
|
4232
|
+
options.signal?.throwIfAborted();
|
|
4233
|
+
if (!(result.audio?.uint8Array instanceof Uint8Array) || !result.audio.uint8Array.length)
|
|
4234
|
+
throw new AudioAPIError(
|
|
4235
|
+
"Speech provider returned empty audio",
|
|
4236
|
+
"invalid_response"
|
|
4237
|
+
);
|
|
4238
|
+
return result;
|
|
4239
|
+
}
|
|
4240
|
+
async function transcribe({
|
|
4241
|
+
model,
|
|
4242
|
+
...options
|
|
4243
|
+
}) {
|
|
4244
|
+
options.signal?.throwIfAborted();
|
|
4245
|
+
const result = await model.doTranscribe(options);
|
|
4246
|
+
options.signal?.throwIfAborted();
|
|
4247
|
+
if (typeof result.text !== "string")
|
|
4248
|
+
throw new AudioAPIError(
|
|
4249
|
+
"Transcription provider returned an invalid transcript",
|
|
4250
|
+
"invalid_response"
|
|
4251
|
+
);
|
|
4252
|
+
return result;
|
|
4253
|
+
}
|
|
4254
|
+
|
|
4255
|
+
exports.AudioAPIError = AudioAPIError;
|
|
4000
4256
|
exports.DEFAULT_CAPABILITIES = DEFAULT_CAPABILITIES;
|
|
4001
4257
|
exports.DEFAULT_MAX_ITERATIONS = DEFAULT_MAX_ITERATIONS;
|
|
4002
4258
|
exports.GenerateResult = GenerateResult;
|
|
@@ -4021,6 +4277,7 @@ exports.formatToolsForAnthropic = formatToolsForAnthropic;
|
|
|
4021
4277
|
exports.formatToolsForGoogle = formatToolsForGoogle;
|
|
4022
4278
|
exports.formatToolsForOpenAI = formatToolsForOpenAI;
|
|
4023
4279
|
exports.generateMessageId = generateMessageId;
|
|
4280
|
+
exports.generateSpeech = generateSpeech;
|
|
4024
4281
|
exports.generateText = generateText;
|
|
4025
4282
|
exports.generateThreadId = generateThreadId;
|
|
4026
4283
|
exports.generateToolCallId = generateToolCallId;
|
|
@@ -4033,5 +4290,6 @@ exports.selectTools = selectTools;
|
|
|
4033
4290
|
exports.shouldExposeToolSearch = shouldExposeToolSearch;
|
|
4034
4291
|
exports.streamText = streamText;
|
|
4035
4292
|
exports.tool = tool;
|
|
4293
|
+
exports.transcribe = transcribe;
|
|
4036
4294
|
//# sourceMappingURL=index.js.map
|
|
4037
4295
|
//# sourceMappingURL=index.js.map
|