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