@yourgpt/llm-sdk 2.6.0-beta.0 → 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 +189 -0
- package/dist/adapters/index.d.mts +11 -13
- package/dist/adapters/index.d.ts +11 -13
- package/dist/adapters/index.js +610 -186
- package/dist/adapters/index.mjs +610 -186
- package/dist/audio-BBSwnjo8.d.mts +92 -0
- package/dist/audio-BBSwnjo8.d.ts +92 -0
- package/dist/{base-tNgbBaSo.d.mts → base-BICaQaRS.d.mts} +8 -3
- package/dist/{base-C58Dsr9p.d.ts → base-CpRPB8u8.d.ts} +8 -3
- package/dist/fallback/index.d.mts +4 -4
- package/dist/fallback/index.d.ts +4 -4
- package/dist/fallback/index.js +75 -39
- package/dist/fallback/index.mjs +75 -39
- package/dist/index.d.mts +18 -35
- package/dist/index.d.ts +18 -35
- package/dist/index.js +304 -88
- package/dist/index.mjs +302 -89
- 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 +559 -178
- package/dist/providers/fireworks/index.mjs +559 -178
- package/dist/providers/google/index.d.mts +3 -3
- package/dist/providers/google/index.d.ts +3 -3
- package/dist/providers/google/index.js +559 -178
- package/dist/providers/google/index.mjs +559 -178
- 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 -23
- package/dist/providers/openai/index.d.ts +25 -23
- package/dist/providers/openai/index.js +1397 -481
- package/dist/providers/openai/index.mjs +1396 -482
- package/dist/providers/openrouter/index.d.mts +3 -3
- package/dist/providers/openrouter/index.d.ts +3 -3
- package/dist/providers/openrouter/index.js +559 -178
- package/dist/providers/openrouter/index.mjs +559 -178
- package/dist/providers/togetherai/index.d.mts +3 -3
- package/dist/providers/togetherai/index.d.ts +3 -3
- package/dist/providers/togetherai/index.js +559 -178
- package/dist/providers/togetherai/index.mjs +559 -178
- package/dist/providers/xai/index.d.mts +3 -3
- package/dist/providers/xai/index.d.ts +3 -3
- package/dist/providers/xai/index.js +559 -178
- package/dist/providers/xai/index.mjs +559 -178
- package/dist/{types-B6dhnguR.d.mts → types-C3RgRbEC.d.mts} +11 -4
- package/dist/{types-CCxPmkmK.d.ts → types-DCFqkJAy.d.ts} +11 -4
- package/dist/{types-BQ31QIsA.d.ts → types-DHQEMFHA.d.mts} +3 -11
- package/dist/{types-BkQCSiIt.d.mts → types-Dg1Bcg1k.d.mts} +127 -3
- package/dist/{types-BkQCSiIt.d.ts → types-Dg1Bcg1k.d.ts} +127 -3
- package/dist/{types-BSSiJW2o.d.mts → types-Dikj3En4.d.ts} +3 -11
- 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 +117 -49
- package/LICENSE +0 -21
package/dist/index.mjs
CHANGED
|
@@ -1,13 +1,87 @@
|
|
|
1
1
|
import { Hono } from 'hono';
|
|
2
2
|
import { cors } from 'hono/cors';
|
|
3
3
|
|
|
4
|
+
// src/core/tool-output.ts
|
|
5
|
+
var imageTypes = /* @__PURE__ */ new Set([
|
|
6
|
+
"image/png",
|
|
7
|
+
"image/jpeg",
|
|
8
|
+
"image/webp",
|
|
9
|
+
"image/gif"
|
|
10
|
+
]);
|
|
11
|
+
function normalizeToolOutput(value) {
|
|
12
|
+
const output = value;
|
|
13
|
+
if (output?.type !== "content" || !Array.isArray(output.content) || !output.content.length) {
|
|
14
|
+
throw new Error("Tool model output must contain a nonempty content array");
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
type: "content",
|
|
18
|
+
content: output.content.map((part) => {
|
|
19
|
+
if (part?.type === "text" && typeof part.text === "string")
|
|
20
|
+
return { type: "text", text: part.text };
|
|
21
|
+
if (part?.type !== "image")
|
|
22
|
+
throw new Error("Unsupported tool output content type");
|
|
23
|
+
const sources = ["data", "url", "fileId"].filter((key) => key in part);
|
|
24
|
+
if (sources.length !== 1)
|
|
25
|
+
throw new Error(
|
|
26
|
+
"Tool image requires exactly one of data, url, or fileId"
|
|
27
|
+
);
|
|
28
|
+
if ("fileId" in part) {
|
|
29
|
+
if (part.provider !== "openai" || typeof part.fileId !== "string" || !part.fileId.trim())
|
|
30
|
+
throw new Error(
|
|
31
|
+
"Tool image file references must name the openai provider and fileId"
|
|
32
|
+
);
|
|
33
|
+
return { type: "image", fileId: part.fileId, provider: "openai" };
|
|
34
|
+
}
|
|
35
|
+
if ("url" in part) {
|
|
36
|
+
let url;
|
|
37
|
+
try {
|
|
38
|
+
url = new URL(part.url);
|
|
39
|
+
} catch {
|
|
40
|
+
throw new Error("Invalid tool image URL");
|
|
41
|
+
}
|
|
42
|
+
if (!["https:", "http:"].includes(url.protocol) || url.username || url.password)
|
|
43
|
+
throw new Error(
|
|
44
|
+
"Tool image URL must use HTTP(S) without credentials"
|
|
45
|
+
);
|
|
46
|
+
return { type: "image", url: url.href };
|
|
47
|
+
}
|
|
48
|
+
if (!("data" in part) || !imageTypes.has(part.mediaType))
|
|
49
|
+
throw new Error("Unsupported tool image media type");
|
|
50
|
+
let data = part.data instanceof Uint8Array ? Buffer.from(part.data).toString("base64") : part.data;
|
|
51
|
+
if (typeof data !== "string")
|
|
52
|
+
throw new Error("Tool image data must be base64 or bytes");
|
|
53
|
+
if (data.startsWith("data:")) {
|
|
54
|
+
const match = /^data:([^;,]+);base64,(.+)$/.exec(data);
|
|
55
|
+
if (!match || match[1] !== part.mediaType)
|
|
56
|
+
throw new Error(
|
|
57
|
+
"Tool image data URL media type does not match mediaType"
|
|
58
|
+
);
|
|
59
|
+
data = match[2];
|
|
60
|
+
}
|
|
61
|
+
if (!data.length || data.length % 4 !== 0 || !/^[A-Za-z0-9+/]+={0,2}$/.test(data))
|
|
62
|
+
throw new Error("Invalid tool image base64 data");
|
|
63
|
+
if (Buffer.byteLength(data, "base64") > 20 * 1024 * 1024)
|
|
64
|
+
throw new Error("Tool image exceeds 20 MiB");
|
|
65
|
+
if (Buffer.from(data, "base64").toString("base64") !== data)
|
|
66
|
+
throw new Error("Invalid tool image base64 data");
|
|
67
|
+
return { type: "image", data, mediaType: part.mediaType };
|
|
68
|
+
})
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
function resolveToolOutput(result, mapped) {
|
|
72
|
+
if (mapped !== void 0) return normalizeToolOutput(mapped);
|
|
73
|
+
const content = result?._aiContent;
|
|
74
|
+
return content !== void 0 ? normalizeToolOutput({ type: "content", content }) : void 0;
|
|
75
|
+
}
|
|
76
|
+
|
|
4
77
|
// src/core/tool.ts
|
|
5
78
|
function tool(config) {
|
|
6
79
|
return {
|
|
7
80
|
description: config.description,
|
|
8
81
|
parameters: config.parameters,
|
|
9
82
|
execute: config.execute,
|
|
10
|
-
hidden: config.hidden
|
|
83
|
+
hidden: config.hidden,
|
|
84
|
+
toModelOutput: config.toModelOutput
|
|
11
85
|
};
|
|
12
86
|
}
|
|
13
87
|
function toolToJsonSchema(toolDef) {
|
|
@@ -130,6 +204,14 @@ function formatToolsForGoogle(tools) {
|
|
|
130
204
|
];
|
|
131
205
|
}
|
|
132
206
|
|
|
207
|
+
// src/core/provider-error.ts
|
|
208
|
+
function throwIfAborted(signal) {
|
|
209
|
+
if (!signal?.aborted) return;
|
|
210
|
+
const error = new Error("The operation was aborted");
|
|
211
|
+
error.name = "AbortError";
|
|
212
|
+
throw error;
|
|
213
|
+
}
|
|
214
|
+
|
|
133
215
|
// src/core/generate-text.ts
|
|
134
216
|
async function generateText(params) {
|
|
135
217
|
const { model, tools, maxSteps = 1, signal } = params;
|
|
@@ -143,22 +225,24 @@ async function generateText(params) {
|
|
|
143
225
|
const allToolCalls = [];
|
|
144
226
|
const allToolResults = [];
|
|
145
227
|
for (let step = 0; step < maxSteps; step++) {
|
|
146
|
-
|
|
147
|
-
throw new Error("Generation aborted");
|
|
148
|
-
}
|
|
228
|
+
throwIfAborted(signal);
|
|
149
229
|
const formattedTools = tools ? formatToolsForProvider(tools, model.provider) : void 0;
|
|
150
230
|
const result = await model.doGenerate({
|
|
151
231
|
messages,
|
|
232
|
+
openai: params.openai,
|
|
152
233
|
tools: formattedTools,
|
|
153
234
|
temperature: params.temperature,
|
|
235
|
+
reasoningEffort: params.reasoningEffort,
|
|
154
236
|
maxTokens: params.maxTokens,
|
|
155
237
|
responseFormat: params.responseFormat,
|
|
156
238
|
signal
|
|
157
239
|
});
|
|
240
|
+
throwIfAborted(signal);
|
|
158
241
|
const stepToolResults = [];
|
|
159
242
|
if (result.toolCalls && result.toolCalls.length > 0 && tools) {
|
|
160
243
|
allToolCalls.push(...result.toolCalls);
|
|
161
244
|
for (const call of result.toolCalls) {
|
|
245
|
+
throwIfAborted(signal);
|
|
162
246
|
const toolDef = tools[call.name];
|
|
163
247
|
if (!toolDef) {
|
|
164
248
|
const errorResult = {
|
|
@@ -176,13 +260,19 @@ async function generateText(params) {
|
|
|
176
260
|
abortSignal: signal,
|
|
177
261
|
messages
|
|
178
262
|
});
|
|
263
|
+
throwIfAborted(signal);
|
|
179
264
|
const result2 = {
|
|
180
265
|
toolCallId: call.id,
|
|
181
|
-
result: toolResult
|
|
266
|
+
result: toolResult,
|
|
267
|
+
modelOutput: resolveToolOutput(
|
|
268
|
+
toolResult,
|
|
269
|
+
toolDef.toModelOutput?.(toolResult)
|
|
270
|
+
)
|
|
182
271
|
};
|
|
183
272
|
stepToolResults.push(result2);
|
|
184
273
|
allToolResults.push(result2);
|
|
185
274
|
} catch (error) {
|
|
275
|
+
throwIfAborted(signal);
|
|
186
276
|
const errorResult = {
|
|
187
277
|
toolCallId: call.id,
|
|
188
278
|
result: {
|
|
@@ -199,22 +289,23 @@ async function generateText(params) {
|
|
|
199
289
|
toolCalls: result.toolCalls,
|
|
200
290
|
toolResults: stepToolResults,
|
|
201
291
|
finishReason: result.finishReason,
|
|
202
|
-
usage: result.usage
|
|
292
|
+
usage: result.usage,
|
|
293
|
+
providerMetadata: result.providerMetadata
|
|
203
294
|
});
|
|
204
|
-
if (!result.toolCalls || result.toolCalls.length === 0) {
|
|
205
|
-
break;
|
|
206
|
-
}
|
|
207
295
|
const assistantMessage = {
|
|
208
296
|
role: "assistant",
|
|
209
297
|
content: result.text || null,
|
|
210
|
-
toolCalls: result.toolCalls
|
|
298
|
+
...result.toolCalls.length ? { toolCalls: result.toolCalls } : {},
|
|
299
|
+
...result.providerMetadata ? { providerMetadata: result.providerMetadata } : {}
|
|
211
300
|
};
|
|
212
301
|
messages = [...messages, assistantMessage];
|
|
302
|
+
if (!result.toolCalls || result.toolCalls.length === 0) break;
|
|
213
303
|
for (const tr of stepToolResults) {
|
|
214
304
|
const toolMessage = {
|
|
215
305
|
role: "tool",
|
|
216
306
|
toolCallId: tr.toolCallId,
|
|
217
|
-
content: JSON.stringify(tr.result)
|
|
307
|
+
content: tr.modelOutput ? "[Tool returned content]" : JSON.stringify(tr.result),
|
|
308
|
+
...tr.modelOutput ? { modelOutput: tr.modelOutput } : {}
|
|
218
309
|
};
|
|
219
310
|
messages = [...messages, toolMessage];
|
|
220
311
|
}
|
|
@@ -222,6 +313,7 @@ async function generateText(params) {
|
|
|
222
313
|
const lastStep = steps[steps.length - 1];
|
|
223
314
|
return {
|
|
224
315
|
text: lastStep?.text ?? "",
|
|
316
|
+
providerMetadata: lastStep?.providerMetadata,
|
|
225
317
|
usage: sumUsage(steps),
|
|
226
318
|
finishReason: lastStep?.finishReason ?? "stop",
|
|
227
319
|
steps,
|
|
@@ -275,6 +367,8 @@ async function streamText(params) {
|
|
|
275
367
|
`[llm-sdk] ${model.provider}/${model.modelId} does not support structured output (responseFormat); the request will be sent but the provider may ignore it.`
|
|
276
368
|
);
|
|
277
369
|
}
|
|
370
|
+
let messages = buildMessages2(params);
|
|
371
|
+
let finalProviderMetadata;
|
|
278
372
|
let fullText = "";
|
|
279
373
|
let finalUsage = {
|
|
280
374
|
promptTokens: 0,
|
|
@@ -283,7 +377,6 @@ async function streamText(params) {
|
|
|
283
377
|
};
|
|
284
378
|
let finalFinishReason = "stop";
|
|
285
379
|
async function* createFullStream() {
|
|
286
|
-
let messages = buildMessages2(params);
|
|
287
380
|
for (let step = 0; step < maxSteps; step++) {
|
|
288
381
|
yield { type: "step-start", step };
|
|
289
382
|
if (signal?.aborted) {
|
|
@@ -292,17 +385,21 @@ async function streamText(params) {
|
|
|
292
385
|
}
|
|
293
386
|
const formattedTools = tools ? formatToolsForProvider2(tools, model.provider) : void 0;
|
|
294
387
|
let stepText = "";
|
|
388
|
+
let stepProviderMetadata;
|
|
295
389
|
const toolCalls = [];
|
|
296
390
|
let stepFinishReason = "stop";
|
|
297
391
|
try {
|
|
298
392
|
for await (const chunk of model.doStream({
|
|
299
393
|
messages,
|
|
394
|
+
openai: params.openai,
|
|
300
395
|
tools: formattedTools,
|
|
301
396
|
temperature: params.temperature,
|
|
397
|
+
reasoningEffort: params.reasoningEffort,
|
|
302
398
|
maxTokens: params.maxTokens,
|
|
303
399
|
responseFormat: params.responseFormat,
|
|
304
400
|
signal
|
|
305
401
|
})) {
|
|
402
|
+
throwIfAborted(signal);
|
|
306
403
|
switch (chunk.type) {
|
|
307
404
|
case "text-delta":
|
|
308
405
|
stepText += chunk.text;
|
|
@@ -317,6 +414,8 @@ async function streamText(params) {
|
|
|
317
414
|
};
|
|
318
415
|
break;
|
|
319
416
|
case "finish":
|
|
417
|
+
stepProviderMetadata = chunk.providerMetadata;
|
|
418
|
+
finalProviderMetadata = chunk.providerMetadata;
|
|
320
419
|
stepFinishReason = chunk.finishReason;
|
|
321
420
|
finalFinishReason = chunk.finishReason;
|
|
322
421
|
if (chunk.usage) {
|
|
@@ -339,17 +438,24 @@ async function streamText(params) {
|
|
|
339
438
|
};
|
|
340
439
|
return;
|
|
341
440
|
}
|
|
342
|
-
yield {
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
role: "assistant",
|
|
348
|
-
content: stepText || null,
|
|
349
|
-
toolCalls
|
|
441
|
+
yield {
|
|
442
|
+
type: "step-finish",
|
|
443
|
+
step,
|
|
444
|
+
finishReason: stepFinishReason,
|
|
445
|
+
providerMetadata: stepProviderMetadata
|
|
350
446
|
};
|
|
351
|
-
messages = [
|
|
447
|
+
messages = [
|
|
448
|
+
...messages,
|
|
449
|
+
{
|
|
450
|
+
role: "assistant",
|
|
451
|
+
content: stepText || null,
|
|
452
|
+
...toolCalls.length ? { toolCalls } : {},
|
|
453
|
+
...stepProviderMetadata ? { providerMetadata: stepProviderMetadata } : {}
|
|
454
|
+
}
|
|
455
|
+
];
|
|
456
|
+
if (toolCalls.length === 0 || !tools) break;
|
|
352
457
|
for (const call of toolCalls) {
|
|
458
|
+
throwIfAborted(signal);
|
|
353
459
|
const toolDef = tools[call.name];
|
|
354
460
|
if (!toolDef) {
|
|
355
461
|
const errorResult = { error: `Tool not found: ${call.name}` };
|
|
@@ -375,16 +481,28 @@ async function streamText(params) {
|
|
|
375
481
|
abortSignal: signal,
|
|
376
482
|
messages
|
|
377
483
|
});
|
|
378
|
-
|
|
484
|
+
throwIfAborted(signal);
|
|
485
|
+
const modelOutput = resolveToolOutput(
|
|
486
|
+
result,
|
|
487
|
+
toolDef.toModelOutput?.(result)
|
|
488
|
+
);
|
|
489
|
+
yield {
|
|
490
|
+
type: "tool-result",
|
|
491
|
+
toolCallId: call.id,
|
|
492
|
+
result,
|
|
493
|
+
modelOutput
|
|
494
|
+
};
|
|
379
495
|
messages = [
|
|
380
496
|
...messages,
|
|
381
497
|
{
|
|
382
498
|
role: "tool",
|
|
383
499
|
toolCallId: call.id,
|
|
384
|
-
content: JSON.stringify(result)
|
|
500
|
+
content: modelOutput ? "[Tool returned content]" : JSON.stringify(result),
|
|
501
|
+
...modelOutput ? { modelOutput } : {}
|
|
385
502
|
}
|
|
386
503
|
];
|
|
387
504
|
} catch (error) {
|
|
505
|
+
throwIfAborted(signal);
|
|
388
506
|
const errorResult = {
|
|
389
507
|
error: error instanceof Error ? error.message : "Tool execution failed"
|
|
390
508
|
};
|
|
@@ -407,43 +525,73 @@ async function streamText(params) {
|
|
|
407
525
|
yield {
|
|
408
526
|
type: "finish",
|
|
409
527
|
finishReason: finalFinishReason,
|
|
410
|
-
usage: finalUsage
|
|
528
|
+
usage: finalUsage,
|
|
529
|
+
providerMetadata: finalProviderMetadata
|
|
411
530
|
};
|
|
412
531
|
}
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
532
|
+
const source = createFullStream();
|
|
533
|
+
const parts = [];
|
|
534
|
+
let finished = false;
|
|
535
|
+
let failure;
|
|
536
|
+
let pending;
|
|
537
|
+
async function advance() {
|
|
538
|
+
if (!pending) {
|
|
539
|
+
pending = (async () => {
|
|
540
|
+
try {
|
|
541
|
+
const next = await source.next();
|
|
542
|
+
if (next.done) finished = true;
|
|
543
|
+
else parts.push(next.value);
|
|
544
|
+
} catch (error) {
|
|
545
|
+
failure = error;
|
|
546
|
+
finished = true;
|
|
547
|
+
}
|
|
548
|
+
})();
|
|
418
549
|
}
|
|
550
|
+
const current = pending;
|
|
551
|
+
await current;
|
|
552
|
+
if (pending === current) pending = void 0;
|
|
419
553
|
}
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
554
|
+
async function* sharedStream() {
|
|
555
|
+
let index = 0;
|
|
556
|
+
while (true) {
|
|
557
|
+
if (index < parts.length) yield parts[index++];
|
|
558
|
+
else if (finished) {
|
|
559
|
+
if (failure) throw failure;
|
|
560
|
+
return;
|
|
561
|
+
} else await advance();
|
|
425
562
|
}
|
|
426
563
|
}
|
|
564
|
+
async function* createTextStream() {
|
|
565
|
+
for await (const part of sharedStream()) {
|
|
566
|
+
if (part.type === "error") throw part.error;
|
|
567
|
+
if (part.type === "text-delta") yield part.text;
|
|
568
|
+
}
|
|
569
|
+
}
|
|
570
|
+
let completion;
|
|
571
|
+
function consumeStream() {
|
|
572
|
+
return completion ?? (completion = (async () => {
|
|
573
|
+
for await (const part of sharedStream()) {
|
|
574
|
+
if (part.type === "error") throw part.error;
|
|
575
|
+
}
|
|
576
|
+
})());
|
|
577
|
+
}
|
|
427
578
|
return {
|
|
428
579
|
textStream: createTextStream(),
|
|
429
|
-
fullStream:
|
|
580
|
+
fullStream: sharedStream(),
|
|
581
|
+
get response() {
|
|
582
|
+
return consumeStream().then(() => ({ messages }));
|
|
583
|
+
},
|
|
584
|
+
get providerMetadata() {
|
|
585
|
+
return consumeStream().then(() => finalProviderMetadata);
|
|
586
|
+
},
|
|
430
587
|
get text() {
|
|
431
|
-
|
|
432
|
-
textPromise = consumeStream().then(() => fullText);
|
|
433
|
-
}
|
|
434
|
-
return textPromise;
|
|
588
|
+
return consumeStream().then(() => fullText);
|
|
435
589
|
},
|
|
436
590
|
get usage() {
|
|
437
|
-
|
|
438
|
-
usagePromise = consumeStream().then(() => finalUsage);
|
|
439
|
-
}
|
|
440
|
-
return usagePromise;
|
|
591
|
+
return consumeStream().then(() => finalUsage);
|
|
441
592
|
},
|
|
442
593
|
get finishReason() {
|
|
443
|
-
|
|
444
|
-
finishReasonPromise = consumeStream().then(() => finalFinishReason);
|
|
445
|
-
}
|
|
446
|
-
return finishReasonPromise;
|
|
594
|
+
return consumeStream().then(() => finalFinishReason);
|
|
447
595
|
},
|
|
448
596
|
toTextStreamResponse(options) {
|
|
449
597
|
const stream = createTextStreamReadable(createTextStream());
|
|
@@ -458,7 +606,7 @@ async function streamText(params) {
|
|
|
458
606
|
});
|
|
459
607
|
},
|
|
460
608
|
toDataStreamResponse(options) {
|
|
461
|
-
const stream = createDataStreamReadable(
|
|
609
|
+
const stream = createDataStreamReadable(sharedStream());
|
|
462
610
|
return new Response(stream, {
|
|
463
611
|
status: options?.status ?? 200,
|
|
464
612
|
headers: {
|
|
@@ -559,6 +707,7 @@ function createMessage(partial) {
|
|
|
559
707
|
tool_calls: partial.tool_calls,
|
|
560
708
|
tool_call_id: partial.tool_call_id,
|
|
561
709
|
metadata: partial.metadata,
|
|
710
|
+
providerMetadata: partial.providerMetadata,
|
|
562
711
|
created_at: partial.created_at ?? /* @__PURE__ */ new Date()
|
|
563
712
|
};
|
|
564
713
|
}
|
|
@@ -607,7 +756,13 @@ function mapOutputMessages(resultMessages) {
|
|
|
607
756
|
role: m.role,
|
|
608
757
|
content: m.content ?? "",
|
|
609
758
|
toolCalls: m.tool_calls,
|
|
610
|
-
toolCallId: m.tool_call_id
|
|
759
|
+
toolCallId: m.tool_call_id,
|
|
760
|
+
...m.providerMetadata || m.modelOutput ? {
|
|
761
|
+
metadata: {
|
|
762
|
+
...m.providerMetadata ? { providerMetadata: m.providerMetadata } : {},
|
|
763
|
+
...m.modelOutput ? { modelOutput: m.modelOutput } : {}
|
|
764
|
+
}
|
|
765
|
+
} : {}
|
|
611
766
|
}));
|
|
612
767
|
}
|
|
613
768
|
|
|
@@ -1497,9 +1652,6 @@ function buildProviderToolOptions(params) {
|
|
|
1497
1652
|
function buildToolResultForAI(tool2, result, args) {
|
|
1498
1653
|
const typedResult = result;
|
|
1499
1654
|
const responseMode = typedResult?._aiResponseMode ?? tool2?.aiResponseMode ?? "full";
|
|
1500
|
-
if (typedResult?._aiContent && typedResult._aiContent.length > 0) {
|
|
1501
|
-
return typedResult._aiContent;
|
|
1502
|
-
}
|
|
1503
1655
|
let aiContext;
|
|
1504
1656
|
if (typedResult?._aiContext) {
|
|
1505
1657
|
aiContext = typedResult._aiContext;
|
|
@@ -1519,25 +1671,6 @@ function buildToolResultForAI(tool2, result, args) {
|
|
|
1519
1671
|
Full data: ${fullData}` : fullData;
|
|
1520
1672
|
}
|
|
1521
1673
|
}
|
|
1522
|
-
function serializeToolResultContent(content) {
|
|
1523
|
-
if (typeof content === "string") {
|
|
1524
|
-
return content;
|
|
1525
|
-
}
|
|
1526
|
-
return content.map((item) => {
|
|
1527
|
-
if (item.type === "image") {
|
|
1528
|
-
return {
|
|
1529
|
-
type: "image_url",
|
|
1530
|
-
image_url: {
|
|
1531
|
-
url: `data:${item.mediaType};base64,${item.data}`
|
|
1532
|
-
}
|
|
1533
|
-
};
|
|
1534
|
-
}
|
|
1535
|
-
return {
|
|
1536
|
-
type: "text",
|
|
1537
|
-
text: item.text
|
|
1538
|
-
};
|
|
1539
|
-
});
|
|
1540
|
-
}
|
|
1541
1674
|
function extractHeaders(request) {
|
|
1542
1675
|
if (!request) return {};
|
|
1543
1676
|
const headers = {};
|
|
@@ -1594,7 +1727,11 @@ var Runtime = class {
|
|
|
1594
1727
|
const messages = request.messages.map(
|
|
1595
1728
|
(m, i) => createMessage({
|
|
1596
1729
|
role: m.role,
|
|
1597
|
-
content: m.content
|
|
1730
|
+
content: m.content,
|
|
1731
|
+
providerMetadata: m.providerMetadata,
|
|
1732
|
+
modelOutput: m.modelOutput,
|
|
1733
|
+
tool_calls: m.tool_calls,
|
|
1734
|
+
tool_call_id: m.tool_call_id
|
|
1598
1735
|
})
|
|
1599
1736
|
);
|
|
1600
1737
|
const allActions = [...this.actions.values()];
|
|
@@ -1838,14 +1975,21 @@ var Runtime = class {
|
|
|
1838
1975
|
);
|
|
1839
1976
|
}
|
|
1840
1977
|
}
|
|
1978
|
+
const resolvedToolIds = new Set(
|
|
1979
|
+
(messages ?? []).filter((message) => message.role === "tool" && message.tool_call_id).map((message) => message.tool_call_id)
|
|
1980
|
+
);
|
|
1981
|
+
const responseToolCalls = requiresAction ? toolCalls.filter((call) => !resolvedToolIds.has(call.id)) : toolCalls;
|
|
1841
1982
|
const response = {
|
|
1842
1983
|
success: !error,
|
|
1843
1984
|
content,
|
|
1844
|
-
toolCalls:
|
|
1985
|
+
toolCalls: responseToolCalls.length > 0 ? responseToolCalls : void 0,
|
|
1845
1986
|
toolResults: toolResults.length > 0 ? toolResults : void 0,
|
|
1846
1987
|
messages,
|
|
1847
1988
|
requiresAction,
|
|
1848
1989
|
error,
|
|
1990
|
+
// Copilot's HTTP transport reads a top-level message for HTTP errors.
|
|
1991
|
+
// Retain the structured error as well for existing API consumers.
|
|
1992
|
+
...error ? { message: error.message } : {},
|
|
1849
1993
|
// Include raw events for debugging
|
|
1850
1994
|
_events: this.config.debug ? events : void 0
|
|
1851
1995
|
};
|
|
@@ -1869,6 +2013,7 @@ var Runtime = class {
|
|
|
1869
2013
|
return new Response(
|
|
1870
2014
|
JSON.stringify({
|
|
1871
2015
|
success: false,
|
|
2016
|
+
message: err instanceof Error ? err.message : "Unknown error",
|
|
1872
2017
|
error: {
|
|
1873
2018
|
message: err instanceof Error ? err.message : "Unknown error"
|
|
1874
2019
|
}
|
|
@@ -2203,6 +2348,7 @@ var Runtime = class {
|
|
|
2203
2348
|
let currentToolCall = null;
|
|
2204
2349
|
const serverToolResults = [];
|
|
2205
2350
|
const toolContextData = "toolContext" in this.config ? this.config.toolContext : void 0;
|
|
2351
|
+
let adapterProviderMetadata;
|
|
2206
2352
|
let adapterUsage;
|
|
2207
2353
|
const completionRequest = {
|
|
2208
2354
|
messages: [],
|
|
@@ -2301,18 +2447,24 @@ var Runtime = class {
|
|
|
2301
2447
|
);
|
|
2302
2448
|
try {
|
|
2303
2449
|
const result = await tool2.handler(args, toolContext);
|
|
2450
|
+
const modelOutput = resolveToolOutput(
|
|
2451
|
+
result,
|
|
2452
|
+
tool2.toModelOutput?.(result)
|
|
2453
|
+
);
|
|
2304
2454
|
serverToolResults.push({
|
|
2305
2455
|
id: event.id,
|
|
2306
2456
|
name: toolName,
|
|
2307
2457
|
args,
|
|
2308
2458
|
result,
|
|
2459
|
+
modelOutput,
|
|
2309
2460
|
tool: tool2
|
|
2310
2461
|
});
|
|
2311
2462
|
yield {
|
|
2312
2463
|
type: "action:end",
|
|
2313
2464
|
id: event.id,
|
|
2314
2465
|
name: toolName,
|
|
2315
|
-
result
|
|
2466
|
+
result,
|
|
2467
|
+
modelOutput
|
|
2316
2468
|
};
|
|
2317
2469
|
} catch (error) {
|
|
2318
2470
|
const errorResult = {
|
|
@@ -2346,6 +2498,7 @@ var Runtime = class {
|
|
|
2346
2498
|
return;
|
|
2347
2499
|
// Exit on error
|
|
2348
2500
|
case "done":
|
|
2501
|
+
adapterProviderMetadata = event.providerMetadata;
|
|
2349
2502
|
if (event.usage) {
|
|
2350
2503
|
adapterUsage = event.usage;
|
|
2351
2504
|
}
|
|
@@ -2366,11 +2519,11 @@ var Runtime = class {
|
|
|
2366
2519
|
(tc) => !serverToolIds.has(tc.id)
|
|
2367
2520
|
);
|
|
2368
2521
|
const serverToolResultMessages = serverToolResults.map((tr) => {
|
|
2369
|
-
const
|
|
2370
|
-
const content = typeof aiContent === "string" ? aiContent : JSON.stringify(serializeToolResultContent(aiContent));
|
|
2522
|
+
const content = tr.modelOutput ? "[Tool returned content]" : buildToolResultForAI(tr.tool, tr.result, tr.args);
|
|
2371
2523
|
return {
|
|
2372
2524
|
role: "tool",
|
|
2373
2525
|
content,
|
|
2526
|
+
...tr.modelOutput ? { modelOutput: tr.modelOutput } : {},
|
|
2374
2527
|
tool_call_id: tr.id
|
|
2375
2528
|
};
|
|
2376
2529
|
});
|
|
@@ -2383,6 +2536,7 @@ var Runtime = class {
|
|
|
2383
2536
|
const assistantMessage = {
|
|
2384
2537
|
role: "assistant",
|
|
2385
2538
|
content: accumulatedText || null,
|
|
2539
|
+
...adapterProviderMetadata ? { providerMetadata: adapterProviderMetadata } : {},
|
|
2386
2540
|
tool_calls: toolCalls.map((tc) => ({
|
|
2387
2541
|
id: tc.id,
|
|
2388
2542
|
type: "function",
|
|
@@ -2417,6 +2571,7 @@ var Runtime = class {
|
|
|
2417
2571
|
const assistantWithToolCalls = {
|
|
2418
2572
|
role: "assistant",
|
|
2419
2573
|
content: accumulatedText || null,
|
|
2574
|
+
...adapterProviderMetadata ? { providerMetadata: adapterProviderMetadata } : {},
|
|
2420
2575
|
tool_calls: serverToolResults.map((tr) => {
|
|
2421
2576
|
const tc = toolCalls.find((t) => t.id === tr.id);
|
|
2422
2577
|
return {
|
|
@@ -2467,6 +2622,7 @@ var Runtime = class {
|
|
|
2467
2622
|
const assistantMessage = {
|
|
2468
2623
|
role: "assistant",
|
|
2469
2624
|
content: accumulatedText || null,
|
|
2625
|
+
...adapterProviderMetadata ? { providerMetadata: adapterProviderMetadata } : {},
|
|
2470
2626
|
tool_calls: clientToolCalls.map((tc) => ({
|
|
2471
2627
|
id: tc.id,
|
|
2472
2628
|
type: "function",
|
|
@@ -2492,10 +2648,11 @@ var Runtime = class {
|
|
|
2492
2648
|
return;
|
|
2493
2649
|
}
|
|
2494
2650
|
}
|
|
2495
|
-
if (accumulatedText) {
|
|
2651
|
+
if (accumulatedText || adapterProviderMetadata) {
|
|
2496
2652
|
newMessages.push({
|
|
2497
2653
|
role: "assistant",
|
|
2498
|
-
content: accumulatedText
|
|
2654
|
+
content: accumulatedText,
|
|
2655
|
+
...adapterProviderMetadata ? { providerMetadata: adapterProviderMetadata } : {}
|
|
2499
2656
|
});
|
|
2500
2657
|
}
|
|
2501
2658
|
if (debug) {
|
|
@@ -2610,7 +2767,10 @@ var Runtime = class {
|
|
|
2610
2767
|
content: result.content
|
|
2611
2768
|
};
|
|
2612
2769
|
}
|
|
2613
|
-
yield {
|
|
2770
|
+
yield {
|
|
2771
|
+
type: "message:end",
|
|
2772
|
+
providerMetadata: result.providerMetadata
|
|
2773
|
+
};
|
|
2614
2774
|
if (result.toolCalls.length > 0) {
|
|
2615
2775
|
const serverToolCalls = [];
|
|
2616
2776
|
const clientToolCalls = [];
|
|
@@ -2657,18 +2817,24 @@ var Runtime = class {
|
|
|
2657
2817
|
);
|
|
2658
2818
|
try {
|
|
2659
2819
|
const toolResult = await tool2.handler(tc.args, toolContext);
|
|
2820
|
+
const modelOutput = resolveToolOutput(
|
|
2821
|
+
toolResult,
|
|
2822
|
+
tool2.toModelOutput?.(toolResult)
|
|
2823
|
+
);
|
|
2660
2824
|
serverToolResults.push({
|
|
2661
2825
|
id: tc.id,
|
|
2662
2826
|
name: tc.name,
|
|
2663
2827
|
args: tc.args,
|
|
2664
2828
|
result: toolResult,
|
|
2829
|
+
modelOutput,
|
|
2665
2830
|
tool: tool2
|
|
2666
2831
|
});
|
|
2667
2832
|
yield {
|
|
2668
2833
|
type: "action:end",
|
|
2669
2834
|
id: tc.id,
|
|
2670
2835
|
name: tc.name,
|
|
2671
|
-
result: toolResult
|
|
2836
|
+
result: toolResult,
|
|
2837
|
+
modelOutput
|
|
2672
2838
|
};
|
|
2673
2839
|
} catch (error) {
|
|
2674
2840
|
const errorResult = {
|
|
@@ -2692,15 +2858,11 @@ var Runtime = class {
|
|
|
2692
2858
|
}
|
|
2693
2859
|
}
|
|
2694
2860
|
const serverToolResultMessages = serverToolResults.map((tr) => {
|
|
2695
|
-
const
|
|
2696
|
-
tr.tool,
|
|
2697
|
-
tr.result,
|
|
2698
|
-
tr.args
|
|
2699
|
-
);
|
|
2700
|
-
const content = typeof aiContent === "string" ? aiContent : JSON.stringify(serializeToolResultContent(aiContent));
|
|
2861
|
+
const content = tr.modelOutput ? "[Tool returned content]" : buildToolResultForAI(tr.tool, tr.result, tr.args);
|
|
2701
2862
|
return {
|
|
2702
2863
|
role: "tool",
|
|
2703
2864
|
content,
|
|
2865
|
+
...tr.modelOutput ? { modelOutput: tr.modelOutput } : {},
|
|
2704
2866
|
tool_call_id: tr.id
|
|
2705
2867
|
};
|
|
2706
2868
|
});
|
|
@@ -2708,6 +2870,7 @@ var Runtime = class {
|
|
|
2708
2870
|
const assistantMessage = {
|
|
2709
2871
|
role: "assistant",
|
|
2710
2872
|
content: result.content || null,
|
|
2873
|
+
...result.providerMetadata ? { providerMetadata: result.providerMetadata } : {},
|
|
2711
2874
|
tool_calls: result.toolCalls.map((tc) => ({
|
|
2712
2875
|
id: tc.id,
|
|
2713
2876
|
type: "function",
|
|
@@ -2737,6 +2900,7 @@ var Runtime = class {
|
|
|
2737
2900
|
const assistantWithToolCalls = {
|
|
2738
2901
|
role: "assistant",
|
|
2739
2902
|
content: result.content || null,
|
|
2903
|
+
...result.providerMetadata ? { providerMetadata: result.providerMetadata } : {},
|
|
2740
2904
|
tool_calls: result.toolCalls.map((tc) => ({
|
|
2741
2905
|
id: tc.id,
|
|
2742
2906
|
type: "function",
|
|
@@ -2768,6 +2932,7 @@ var Runtime = class {
|
|
|
2768
2932
|
const assistantMessage = {
|
|
2769
2933
|
role: "assistant",
|
|
2770
2934
|
content: result.content || null,
|
|
2935
|
+
...result.providerMetadata ? { providerMetadata: result.providerMetadata } : {},
|
|
2771
2936
|
tool_calls: clientToolCalls.map((tc) => ({
|
|
2772
2937
|
id: tc.id,
|
|
2773
2938
|
type: "function",
|
|
@@ -2793,10 +2958,11 @@ var Runtime = class {
|
|
|
2793
2958
|
return;
|
|
2794
2959
|
}
|
|
2795
2960
|
}
|
|
2796
|
-
if (result.content) {
|
|
2961
|
+
if (result.content || result.providerMetadata) {
|
|
2797
2962
|
newMessages.push({
|
|
2798
2963
|
role: "assistant",
|
|
2799
|
-
content: result.content
|
|
2964
|
+
content: result.content,
|
|
2965
|
+
...result.providerMetadata ? { providerMetadata: result.providerMetadata } : {}
|
|
2800
2966
|
});
|
|
2801
2967
|
}
|
|
2802
2968
|
if (debug) {
|
|
@@ -3948,6 +4114,53 @@ async function executeToolCalls(toolCalls, tools, executeServerTool, waitForClie
|
|
|
3948
4114
|
return results;
|
|
3949
4115
|
}
|
|
3950
4116
|
|
|
3951
|
-
|
|
4117
|
+
// src/core/audio.ts
|
|
4118
|
+
var audioErrorMarker = /* @__PURE__ */ Symbol.for("@yourgpt/llm-sdk/AudioAPIError");
|
|
4119
|
+
var _a;
|
|
4120
|
+
var AudioAPIError = class extends Error {
|
|
4121
|
+
constructor(message, code, status, requestId) {
|
|
4122
|
+
super(message);
|
|
4123
|
+
this.code = code;
|
|
4124
|
+
this.status = status;
|
|
4125
|
+
this.requestId = requestId;
|
|
4126
|
+
this[_a] = true;
|
|
4127
|
+
this.name = "AudioAPIError";
|
|
4128
|
+
}
|
|
4129
|
+
static [(_a = audioErrorMarker, Symbol.hasInstance)](value) {
|
|
4130
|
+
return !!value && typeof value === "object" && value[audioErrorMarker] === true;
|
|
4131
|
+
}
|
|
4132
|
+
};
|
|
4133
|
+
async function generateSpeech({
|
|
4134
|
+
model,
|
|
4135
|
+
...options
|
|
4136
|
+
}) {
|
|
4137
|
+
options.signal?.throwIfAborted();
|
|
4138
|
+
if (typeof options.text !== "string" || !options.text.trim())
|
|
4139
|
+
throw new AudioAPIError("Speech text must not be empty", "invalid_input");
|
|
4140
|
+
const result = await model.doGenerate(options);
|
|
4141
|
+
options.signal?.throwIfAborted();
|
|
4142
|
+
if (!(result.audio?.uint8Array instanceof Uint8Array) || !result.audio.uint8Array.length)
|
|
4143
|
+
throw new AudioAPIError(
|
|
4144
|
+
"Speech provider returned empty audio",
|
|
4145
|
+
"invalid_response"
|
|
4146
|
+
);
|
|
4147
|
+
return result;
|
|
4148
|
+
}
|
|
4149
|
+
async function transcribe({
|
|
4150
|
+
model,
|
|
4151
|
+
...options
|
|
4152
|
+
}) {
|
|
4153
|
+
options.signal?.throwIfAborted();
|
|
4154
|
+
const result = await model.doTranscribe(options);
|
|
4155
|
+
options.signal?.throwIfAborted();
|
|
4156
|
+
if (typeof result.text !== "string")
|
|
4157
|
+
throw new AudioAPIError(
|
|
4158
|
+
"Transcription provider returned an invalid transcript",
|
|
4159
|
+
"invalid_response"
|
|
4160
|
+
);
|
|
4161
|
+
return result;
|
|
4162
|
+
}
|
|
4163
|
+
|
|
4164
|
+
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 };
|
|
3952
4165
|
//# sourceMappingURL=index.mjs.map
|
|
3953
4166
|
//# sourceMappingURL=index.mjs.map
|