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