ai 3.3.5 → 3.3.7
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/dist/index.d.mts +95 -64
- package/dist/index.d.ts +95 -64
- package/dist/index.js +253 -230
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +203 -169
- package/dist/index.mjs.map +1 -1
- package/package.json +8 -8
- package/rsc/dist/index.d.ts +186 -183
- package/rsc/dist/rsc-server.d.mts +185 -183
- package/rsc/dist/rsc-server.mjs +1219 -1248
- package/rsc/dist/rsc-server.mjs.map +1 -1
- package/rsc/dist/rsc-shared.d.mts +24 -22
- package/rsc/dist/rsc-shared.mjs +46 -60
- package/rsc/dist/rsc-shared.mjs.map +1 -1
package/rsc/dist/rsc-server.mjs
CHANGED
@@ -139,512 +139,704 @@ function getMutableAIState(...args) {
|
|
139
139
|
return mutableState;
|
140
140
|
}
|
141
141
|
|
142
|
-
// rsc/
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
return
|
160
|
-
current,
|
161
|
-
/* @__PURE__ */ jsx(Suspense, { fallback: chunk.value, children: /* @__PURE__ */ jsx(R, { c: chunk.value, n: chunk.next }) })
|
162
|
-
] });
|
142
|
+
// rsc/provider.tsx
|
143
|
+
import * as React from "react";
|
144
|
+
import { InternalAIProvider } from "./rsc-shared.mjs";
|
145
|
+
import { jsx } from "react/jsx-runtime";
|
146
|
+
async function innerAction({
|
147
|
+
action,
|
148
|
+
options
|
149
|
+
}, state, ...args) {
|
150
|
+
"use server";
|
151
|
+
return await withAIState(
|
152
|
+
{
|
153
|
+
state,
|
154
|
+
options
|
155
|
+
},
|
156
|
+
async () => {
|
157
|
+
const result = await action(...args);
|
158
|
+
sealMutableAIState();
|
159
|
+
return [getAIStateDeltaPromise(), result];
|
163
160
|
}
|
164
|
-
|
165
|
-
}
|
166
|
-
][0];
|
167
|
-
function createSuspendedChunk(initialValue) {
|
168
|
-
const { promise, resolve, reject } = createResolvablePromise();
|
169
|
-
return {
|
170
|
-
row: /* @__PURE__ */ jsx(Suspense, { fallback: initialValue, children: /* @__PURE__ */ jsx(R, { c: initialValue, n: promise }) }),
|
171
|
-
resolve,
|
172
|
-
reject
|
173
|
-
};
|
161
|
+
);
|
174
162
|
}
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
163
|
+
function wrapAction(action, options) {
|
164
|
+
return innerAction.bind(null, { action, options });
|
165
|
+
}
|
166
|
+
function createAI({
|
167
|
+
actions,
|
168
|
+
initialAIState,
|
169
|
+
initialUIState,
|
170
|
+
onSetAIState,
|
171
|
+
onGetUIState
|
172
|
+
}) {
|
173
|
+
const wrappedActions = {};
|
174
|
+
for (const name8 in actions) {
|
175
|
+
wrappedActions[name8] = wrapAction(actions[name8], {
|
176
|
+
onSetAIState
|
177
|
+
});
|
185
178
|
}
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
console.warn(
|
194
|
-
"The streamable UI has been slow to update. This may be a bug or a performance issue or you forgot to call `.done()`."
|
195
|
-
);
|
196
|
-
}, DEV_DEFAULT_STREAMABLE_WARNING_TIME);
|
179
|
+
const wrappedSyncUIState = onGetUIState ? wrapAction(onGetUIState, {}) : void 0;
|
180
|
+
const AI = async (props) => {
|
181
|
+
var _a8, _b;
|
182
|
+
if ("useState" in React) {
|
183
|
+
throw new Error(
|
184
|
+
"This component can only be used inside Server Components."
|
185
|
+
);
|
197
186
|
}
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
return streamable2;
|
207
|
-
}
|
208
|
-
const resolvable = createResolvablePromise();
|
209
|
-
currentValue = value;
|
210
|
-
resolve({ value: currentValue, done: false, next: resolvable.promise });
|
211
|
-
resolve = resolvable.resolve;
|
212
|
-
reject = resolvable.reject;
|
213
|
-
warnUnclosedStream();
|
214
|
-
return streamable2;
|
215
|
-
},
|
216
|
-
append(value) {
|
217
|
-
assertStream(".append()");
|
218
|
-
const resolvable = createResolvablePromise();
|
219
|
-
currentValue = value;
|
220
|
-
resolve({ value, done: false, append: true, next: resolvable.promise });
|
221
|
-
resolve = resolvable.resolve;
|
222
|
-
reject = resolvable.reject;
|
223
|
-
warnUnclosedStream();
|
224
|
-
return streamable2;
|
225
|
-
},
|
226
|
-
error(error) {
|
227
|
-
assertStream(".error()");
|
228
|
-
if (warningTimeout) {
|
229
|
-
clearTimeout(warningTimeout);
|
230
|
-
}
|
231
|
-
closed = true;
|
232
|
-
reject(error);
|
233
|
-
return streamable2;
|
234
|
-
},
|
235
|
-
done(...args) {
|
236
|
-
assertStream(".done()");
|
237
|
-
if (warningTimeout) {
|
238
|
-
clearTimeout(warningTimeout);
|
239
|
-
}
|
240
|
-
closed = true;
|
241
|
-
if (args.length) {
|
242
|
-
resolve({ value: args[0], done: true });
|
243
|
-
return streamable2;
|
187
|
+
let uiState = (_a8 = props.initialUIState) != null ? _a8 : initialUIState;
|
188
|
+
let aiState = (_b = props.initialAIState) != null ? _b : initialAIState;
|
189
|
+
let aiStateDelta = void 0;
|
190
|
+
if (wrappedSyncUIState) {
|
191
|
+
const [newAIStateDelta, newUIState] = await wrappedSyncUIState(aiState);
|
192
|
+
if (newUIState !== void 0) {
|
193
|
+
aiStateDelta = newAIStateDelta;
|
194
|
+
uiState = newUIState;
|
244
195
|
}
|
245
|
-
resolve({ value: currentValue, done: true });
|
246
|
-
return streamable2;
|
247
196
|
}
|
197
|
+
return /* @__PURE__ */ jsx(
|
198
|
+
InternalAIProvider,
|
199
|
+
{
|
200
|
+
wrappedActions,
|
201
|
+
wrappedSyncUIState,
|
202
|
+
initialUIState: uiState,
|
203
|
+
initialAIState: aiState,
|
204
|
+
initialAIStatePatch: aiStateDelta,
|
205
|
+
children: props.children
|
206
|
+
}
|
207
|
+
);
|
248
208
|
};
|
249
|
-
return
|
209
|
+
return AI;
|
250
210
|
}
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
211
|
+
|
212
|
+
// rsc/stream-ui/stream-ui.tsx
|
213
|
+
import { safeParseJSON } from "@ai-sdk/provider-utils";
|
214
|
+
|
215
|
+
// core/prompt/convert-to-language-model-prompt.ts
|
216
|
+
import { getErrorMessage } from "@ai-sdk/provider-utils";
|
217
|
+
|
218
|
+
// util/download-error.ts
|
219
|
+
import { AISDKError } from "@ai-sdk/provider";
|
220
|
+
var name = "AI_DownloadError";
|
221
|
+
var marker = `vercel.ai.error.${name}`;
|
222
|
+
var symbol = Symbol.for(marker);
|
223
|
+
var _a;
|
224
|
+
var DownloadError = class extends AISDKError {
|
225
|
+
constructor({
|
226
|
+
url,
|
227
|
+
statusCode,
|
228
|
+
statusText,
|
229
|
+
cause,
|
230
|
+
message = cause == null ? `Failed to download ${url}: ${statusCode} ${statusText}` : `Failed to download ${url}: ${cause}`
|
231
|
+
}) {
|
232
|
+
super({ name, message, cause });
|
233
|
+
this[_a] = true;
|
234
|
+
this.url = url;
|
235
|
+
this.statusCode = statusCode;
|
236
|
+
this.statusText = statusText;
|
256
237
|
}
|
257
|
-
|
258
|
-
|
259
|
-
(async () => {
|
260
|
-
try {
|
261
|
-
const reader = initialValue.getReader();
|
262
|
-
while (true) {
|
263
|
-
const { value, done } = await reader.read();
|
264
|
-
if (done) {
|
265
|
-
break;
|
266
|
-
}
|
267
|
-
streamableValue[STREAMABLE_VALUE_INTERNAL_LOCK] = false;
|
268
|
-
if (typeof value === "string") {
|
269
|
-
streamableValue.append(value);
|
270
|
-
} else {
|
271
|
-
streamableValue.update(value);
|
272
|
-
}
|
273
|
-
streamableValue[STREAMABLE_VALUE_INTERNAL_LOCK] = true;
|
274
|
-
}
|
275
|
-
streamableValue[STREAMABLE_VALUE_INTERNAL_LOCK] = false;
|
276
|
-
streamableValue.done();
|
277
|
-
} catch (e) {
|
278
|
-
streamableValue[STREAMABLE_VALUE_INTERNAL_LOCK] = false;
|
279
|
-
streamableValue.error(e);
|
280
|
-
}
|
281
|
-
})();
|
282
|
-
return streamableValue;
|
283
|
-
}
|
284
|
-
function createStreamableValueImpl(initialValue) {
|
285
|
-
let closed = false;
|
286
|
-
let locked = false;
|
287
|
-
let resolvable = createResolvablePromise();
|
288
|
-
let currentValue = initialValue;
|
289
|
-
let currentError;
|
290
|
-
let currentPromise = resolvable.promise;
|
291
|
-
let currentPatchValue;
|
292
|
-
function assertStream(method) {
|
293
|
-
if (closed) {
|
294
|
-
throw new Error(method + ": Value stream is already closed.");
|
295
|
-
}
|
296
|
-
if (locked) {
|
297
|
-
throw new Error(
|
298
|
-
method + ": Value stream is locked and cannot be updated."
|
299
|
-
);
|
300
|
-
}
|
238
|
+
static isInstance(error) {
|
239
|
+
return AISDKError.hasMarker(error, marker);
|
301
240
|
}
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
}
|
308
|
-
warningTimeout = setTimeout(() => {
|
309
|
-
console.warn(
|
310
|
-
"The streamable value has been slow to update. This may be a bug or a performance issue or you forgot to call `.done()`."
|
311
|
-
);
|
312
|
-
}, DEV_DEFAULT_STREAMABLE_WARNING_TIME);
|
313
|
-
}
|
241
|
+
/**
|
242
|
+
* @deprecated use `isInstance` instead
|
243
|
+
*/
|
244
|
+
static isDownloadError(error) {
|
245
|
+
return error instanceof Error && error.name === name && typeof error.url === "string" && (error.statusCode == null || typeof error.statusCode === "number") && (error.statusText == null || typeof error.statusText === "string");
|
314
246
|
}
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
247
|
+
/**
|
248
|
+
* @deprecated Do not use this method. It will be removed in the next major version.
|
249
|
+
*/
|
250
|
+
toJSON() {
|
251
|
+
return {
|
252
|
+
name: this.name,
|
253
|
+
message: this.message,
|
254
|
+
url: this.url,
|
255
|
+
statusCode: this.statusCode,
|
256
|
+
statusText: this.statusText,
|
257
|
+
cause: this.cause
|
258
|
+
};
|
259
|
+
}
|
260
|
+
};
|
261
|
+
_a = symbol;
|
262
|
+
|
263
|
+
// util/download.ts
|
264
|
+
async function download({
|
265
|
+
url,
|
266
|
+
fetchImplementation = fetch
|
267
|
+
}) {
|
268
|
+
var _a8;
|
269
|
+
const urlText = url.toString();
|
270
|
+
try {
|
271
|
+
const response = await fetchImplementation(urlText);
|
272
|
+
if (!response.ok) {
|
273
|
+
throw new DownloadError({
|
274
|
+
url: urlText,
|
275
|
+
statusCode: response.status,
|
276
|
+
statusText: response.statusText
|
277
|
+
});
|
278
|
+
}
|
279
|
+
return {
|
280
|
+
data: new Uint8Array(await response.arrayBuffer()),
|
281
|
+
mimeType: (_a8 = response.headers.get("content-type")) != null ? _a8 : void 0
|
282
|
+
};
|
283
|
+
} catch (error) {
|
284
|
+
if (DownloadError.isInstance(error)) {
|
285
|
+
throw error;
|
286
|
+
}
|
287
|
+
throw new DownloadError({ url: urlText, cause: error });
|
288
|
+
}
|
289
|
+
}
|
290
|
+
|
291
|
+
// core/util/detect-image-mimetype.ts
|
292
|
+
var mimeTypeSignatures = [
|
293
|
+
{ mimeType: "image/gif", bytes: [71, 73, 70] },
|
294
|
+
{ mimeType: "image/png", bytes: [137, 80, 78, 71] },
|
295
|
+
{ mimeType: "image/jpeg", bytes: [255, 216] },
|
296
|
+
{ mimeType: "image/webp", bytes: [82, 73, 70, 70] }
|
297
|
+
];
|
298
|
+
function detectImageMimeType(image) {
|
299
|
+
for (const { bytes, mimeType } of mimeTypeSignatures) {
|
300
|
+
if (image.length >= bytes.length && bytes.every((byte, index) => image[index] === byte)) {
|
301
|
+
return mimeType;
|
302
|
+
}
|
303
|
+
}
|
304
|
+
return void 0;
|
305
|
+
}
|
306
|
+
|
307
|
+
// core/prompt/data-content.ts
|
308
|
+
import {
|
309
|
+
convertBase64ToUint8Array,
|
310
|
+
convertUint8ArrayToBase64
|
311
|
+
} from "@ai-sdk/provider-utils";
|
312
|
+
|
313
|
+
// core/prompt/invalid-data-content-error.ts
|
314
|
+
import { AISDKError as AISDKError2 } from "@ai-sdk/provider";
|
315
|
+
var name2 = "AI_InvalidDataContentError";
|
316
|
+
var marker2 = `vercel.ai.error.${name2}`;
|
317
|
+
var symbol2 = Symbol.for(marker2);
|
318
|
+
var _a2;
|
319
|
+
var InvalidDataContentError = class extends AISDKError2 {
|
320
|
+
constructor({
|
321
|
+
content,
|
322
|
+
cause,
|
323
|
+
message = `Invalid data content. Expected a base64 string, Uint8Array, ArrayBuffer, or Buffer, but got ${typeof content}.`
|
324
|
+
}) {
|
325
|
+
super({ name: name2, message, cause });
|
326
|
+
this[_a2] = true;
|
327
|
+
this.content = content;
|
328
|
+
}
|
329
|
+
static isInstance(error) {
|
330
|
+
return AISDKError2.hasMarker(error, marker2);
|
331
|
+
}
|
332
|
+
/**
|
333
|
+
* @deprecated use `isInstance` instead
|
334
|
+
*/
|
335
|
+
static isInvalidDataContentError(error) {
|
336
|
+
return error instanceof Error && error.name === name2 && error.content != null;
|
337
|
+
}
|
338
|
+
/**
|
339
|
+
* @deprecated Do not use this method. It will be removed in the next major version.
|
340
|
+
*/
|
341
|
+
toJSON() {
|
342
|
+
return {
|
343
|
+
name: this.name,
|
344
|
+
message: this.message,
|
345
|
+
stack: this.stack,
|
346
|
+
cause: this.cause,
|
347
|
+
content: this.content
|
348
|
+
};
|
349
|
+
}
|
350
|
+
};
|
351
|
+
_a2 = symbol2;
|
352
|
+
|
353
|
+
// core/prompt/data-content.ts
|
354
|
+
function convertDataContentToUint8Array(content) {
|
355
|
+
if (content instanceof Uint8Array) {
|
356
|
+
return content;
|
357
|
+
}
|
358
|
+
if (typeof content === "string") {
|
359
|
+
try {
|
360
|
+
return convertBase64ToUint8Array(content);
|
361
|
+
} catch (error) {
|
362
|
+
throw new InvalidDataContentError({
|
363
|
+
message: "Invalid data content. Content string is not a base64-encoded media.",
|
364
|
+
content,
|
365
|
+
cause: error
|
366
|
+
});
|
367
|
+
}
|
368
|
+
}
|
369
|
+
if (content instanceof ArrayBuffer) {
|
370
|
+
return new Uint8Array(content);
|
371
|
+
}
|
372
|
+
throw new InvalidDataContentError({ content });
|
373
|
+
}
|
374
|
+
|
375
|
+
// core/prompt/invalid-message-role-error.ts
|
376
|
+
import { AISDKError as AISDKError3 } from "@ai-sdk/provider";
|
377
|
+
var name3 = "AI_InvalidMessageRoleError";
|
378
|
+
var marker3 = `vercel.ai.error.${name3}`;
|
379
|
+
var symbol3 = Symbol.for(marker3);
|
380
|
+
var _a3;
|
381
|
+
var InvalidMessageRoleError = class extends AISDKError3 {
|
382
|
+
constructor({
|
383
|
+
role,
|
384
|
+
message = `Invalid message role: '${role}'. Must be one of: "system", "user", "assistant", "tool".`
|
385
|
+
}) {
|
386
|
+
super({ name: name3, message });
|
387
|
+
this[_a3] = true;
|
388
|
+
this.role = role;
|
389
|
+
}
|
390
|
+
static isInstance(error) {
|
391
|
+
return AISDKError3.hasMarker(error, marker3);
|
392
|
+
}
|
393
|
+
/**
|
394
|
+
* @deprecated use `isInstance` instead
|
395
|
+
*/
|
396
|
+
static isInvalidMessageRoleError(error) {
|
397
|
+
return error instanceof Error && error.name === name3 && typeof error.role === "string";
|
398
|
+
}
|
399
|
+
/**
|
400
|
+
* @deprecated Do not use this method. It will be removed in the next major version.
|
401
|
+
*/
|
402
|
+
toJSON() {
|
403
|
+
return {
|
404
|
+
name: this.name,
|
405
|
+
message: this.message,
|
406
|
+
stack: this.stack,
|
407
|
+
role: this.role
|
408
|
+
};
|
409
|
+
}
|
410
|
+
};
|
411
|
+
_a3 = symbol3;
|
412
|
+
|
413
|
+
// core/prompt/convert-to-language-model-prompt.ts
|
414
|
+
async function convertToLanguageModelPrompt({
|
415
|
+
prompt,
|
416
|
+
modelSupportsImageUrls = true,
|
417
|
+
downloadImplementation = download
|
418
|
+
}) {
|
419
|
+
const languageModelMessages = [];
|
420
|
+
if (prompt.system != null) {
|
421
|
+
languageModelMessages.push({ role: "system", content: prompt.system });
|
422
|
+
}
|
423
|
+
const downloadedImages = modelSupportsImageUrls || prompt.messages == null ? null : await downloadImages(prompt.messages, downloadImplementation);
|
424
|
+
const promptType = prompt.type;
|
425
|
+
switch (promptType) {
|
426
|
+
case "prompt": {
|
427
|
+
languageModelMessages.push({
|
428
|
+
role: "user",
|
429
|
+
content: [{ type: "text", text: prompt.prompt }]
|
430
|
+
});
|
431
|
+
break;
|
432
|
+
}
|
433
|
+
case "messages": {
|
434
|
+
languageModelMessages.push(
|
435
|
+
...prompt.messages.map(
|
436
|
+
(message) => convertToLanguageModelMessage(message, downloadedImages)
|
437
|
+
)
|
438
|
+
);
|
439
|
+
break;
|
440
|
+
}
|
441
|
+
default: {
|
442
|
+
const _exhaustiveCheck = promptType;
|
443
|
+
throw new Error(`Unsupported prompt type: ${_exhaustiveCheck}`);
|
444
|
+
}
|
445
|
+
}
|
446
|
+
return languageModelMessages;
|
447
|
+
}
|
448
|
+
function convertToLanguageModelMessage(message, downloadedImages) {
|
449
|
+
const role = message.role;
|
450
|
+
switch (role) {
|
451
|
+
case "system": {
|
452
|
+
return { role: "system", content: message.content };
|
453
|
+
}
|
454
|
+
case "user": {
|
455
|
+
if (typeof message.content === "string") {
|
456
|
+
return {
|
457
|
+
role: "user",
|
458
|
+
content: [{ type: "text", text: message.content }]
|
459
|
+
};
|
460
|
+
}
|
461
|
+
return {
|
462
|
+
role: "user",
|
463
|
+
content: message.content.map(
|
464
|
+
(part) => {
|
465
|
+
var _a8, _b, _c;
|
466
|
+
switch (part.type) {
|
467
|
+
case "text": {
|
468
|
+
return part;
|
469
|
+
}
|
470
|
+
case "image": {
|
471
|
+
if (part.image instanceof URL) {
|
472
|
+
if (downloadedImages == null) {
|
473
|
+
return {
|
474
|
+
type: "image",
|
475
|
+
image: part.image,
|
476
|
+
mimeType: part.mimeType
|
477
|
+
};
|
478
|
+
} else {
|
479
|
+
const downloadedImage = downloadedImages[part.image.toString()];
|
480
|
+
return {
|
481
|
+
type: "image",
|
482
|
+
image: downloadedImage.data,
|
483
|
+
mimeType: (_a8 = part.mimeType) != null ? _a8 : downloadedImage.mimeType
|
484
|
+
};
|
485
|
+
}
|
486
|
+
}
|
487
|
+
if (typeof part.image === "string") {
|
488
|
+
try {
|
489
|
+
const url = new URL(part.image);
|
490
|
+
switch (url.protocol) {
|
491
|
+
case "http:":
|
492
|
+
case "https:": {
|
493
|
+
if (downloadedImages == null) {
|
494
|
+
return {
|
495
|
+
type: "image",
|
496
|
+
image: url,
|
497
|
+
mimeType: part.mimeType
|
498
|
+
};
|
499
|
+
} else {
|
500
|
+
const downloadedImage = downloadedImages[part.image];
|
501
|
+
return {
|
502
|
+
type: "image",
|
503
|
+
image: downloadedImage.data,
|
504
|
+
mimeType: (_b = part.mimeType) != null ? _b : downloadedImage.mimeType
|
505
|
+
};
|
506
|
+
}
|
507
|
+
}
|
508
|
+
case "data:": {
|
509
|
+
try {
|
510
|
+
const [header, base64Content] = part.image.split(",");
|
511
|
+
const mimeType = header.split(";")[0].split(":")[1];
|
512
|
+
if (mimeType == null || base64Content == null) {
|
513
|
+
throw new Error("Invalid data URL format");
|
514
|
+
}
|
515
|
+
return {
|
516
|
+
type: "image",
|
517
|
+
image: convertDataContentToUint8Array(base64Content),
|
518
|
+
mimeType
|
519
|
+
};
|
520
|
+
} catch (error) {
|
521
|
+
throw new Error(
|
522
|
+
`Error processing data URL: ${getErrorMessage(
|
523
|
+
message
|
524
|
+
)}`
|
525
|
+
);
|
526
|
+
}
|
527
|
+
}
|
528
|
+
default: {
|
529
|
+
throw new Error(
|
530
|
+
`Unsupported URL protocol: ${url.protocol}`
|
531
|
+
);
|
532
|
+
}
|
533
|
+
}
|
534
|
+
} catch (_ignored) {
|
535
|
+
}
|
536
|
+
}
|
537
|
+
const imageUint8 = convertDataContentToUint8Array(part.image);
|
538
|
+
return {
|
539
|
+
type: "image",
|
540
|
+
image: imageUint8,
|
541
|
+
mimeType: (_c = part.mimeType) != null ? _c : detectImageMimeType(imageUint8)
|
542
|
+
};
|
543
|
+
}
|
544
|
+
}
|
545
|
+
}
|
546
|
+
)
|
547
|
+
};
|
548
|
+
}
|
549
|
+
case "assistant": {
|
550
|
+
if (typeof message.content === "string") {
|
551
|
+
return {
|
552
|
+
role: "assistant",
|
553
|
+
content: [{ type: "text", text: message.content }]
|
554
|
+
};
|
325
555
|
}
|
556
|
+
return {
|
557
|
+
role: "assistant",
|
558
|
+
content: message.content.filter(
|
559
|
+
// remove empty text parts:
|
560
|
+
(part) => part.type !== "text" || part.text !== ""
|
561
|
+
)
|
562
|
+
};
|
326
563
|
}
|
327
|
-
|
328
|
-
|
329
|
-
}
|
330
|
-
if (initialChunk) {
|
331
|
-
init.type = STREAMABLE_VALUE_TYPE;
|
564
|
+
case "tool": {
|
565
|
+
return message;
|
332
566
|
}
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
currentPatchValue = void 0;
|
337
|
-
if (typeof value === "string") {
|
338
|
-
if (typeof currentValue === "string") {
|
339
|
-
if (value.startsWith(currentValue)) {
|
340
|
-
currentPatchValue = [0, value.slice(currentValue.length)];
|
341
|
-
}
|
342
|
-
}
|
567
|
+
default: {
|
568
|
+
const _exhaustiveCheck = role;
|
569
|
+
throw new InvalidMessageRoleError({ role: _exhaustiveCheck });
|
343
570
|
}
|
344
|
-
currentValue = value;
|
345
571
|
}
|
346
|
-
const streamable2 = {
|
347
|
-
set [STREAMABLE_VALUE_INTERNAL_LOCK](state) {
|
348
|
-
locked = state;
|
349
|
-
},
|
350
|
-
get value() {
|
351
|
-
return createWrapped(true);
|
352
|
-
},
|
353
|
-
update(value) {
|
354
|
-
assertStream(".update()");
|
355
|
-
const resolvePrevious = resolvable.resolve;
|
356
|
-
resolvable = createResolvablePromise();
|
357
|
-
updateValueStates(value);
|
358
|
-
currentPromise = resolvable.promise;
|
359
|
-
resolvePrevious(createWrapped());
|
360
|
-
warnUnclosedStream();
|
361
|
-
return streamable2;
|
362
|
-
},
|
363
|
-
append(value) {
|
364
|
-
assertStream(".append()");
|
365
|
-
if (typeof currentValue !== "string" && typeof currentValue !== "undefined") {
|
366
|
-
throw new Error(
|
367
|
-
`.append(): The current value is not a string. Received: ${typeof currentValue}`
|
368
|
-
);
|
369
|
-
}
|
370
|
-
if (typeof value !== "string") {
|
371
|
-
throw new Error(
|
372
|
-
`.append(): The value is not a string. Received: ${typeof value}`
|
373
|
-
);
|
374
|
-
}
|
375
|
-
const resolvePrevious = resolvable.resolve;
|
376
|
-
resolvable = createResolvablePromise();
|
377
|
-
if (typeof currentValue === "string") {
|
378
|
-
currentPatchValue = [0, value];
|
379
|
-
currentValue = currentValue + value;
|
380
|
-
} else {
|
381
|
-
currentPatchValue = void 0;
|
382
|
-
currentValue = value;
|
383
|
-
}
|
384
|
-
currentPromise = resolvable.promise;
|
385
|
-
resolvePrevious(createWrapped());
|
386
|
-
warnUnclosedStream();
|
387
|
-
return streamable2;
|
388
|
-
},
|
389
|
-
error(error) {
|
390
|
-
assertStream(".error()");
|
391
|
-
if (warningTimeout) {
|
392
|
-
clearTimeout(warningTimeout);
|
393
|
-
}
|
394
|
-
closed = true;
|
395
|
-
currentError = error;
|
396
|
-
currentPromise = void 0;
|
397
|
-
resolvable.resolve({ error });
|
398
|
-
return streamable2;
|
399
|
-
},
|
400
|
-
done(...args) {
|
401
|
-
assertStream(".done()");
|
402
|
-
if (warningTimeout) {
|
403
|
-
clearTimeout(warningTimeout);
|
404
|
-
}
|
405
|
-
closed = true;
|
406
|
-
currentPromise = void 0;
|
407
|
-
if (args.length) {
|
408
|
-
updateValueStates(args[0]);
|
409
|
-
resolvable.resolve(createWrapped());
|
410
|
-
return streamable2;
|
411
|
-
}
|
412
|
-
resolvable.resolve({});
|
413
|
-
return streamable2;
|
414
|
-
}
|
415
|
-
};
|
416
|
-
return streamable2;
|
417
572
|
}
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
|
573
|
+
async function downloadImages(messages, downloadImplementation) {
|
574
|
+
const urls = messages.filter((message) => message.role === "user").map((message) => message.content).filter(
|
575
|
+
(content) => Array.isArray(content)
|
576
|
+
).flat().filter((part) => part.type === "image").map((part) => part.image).map(
|
577
|
+
(part) => (
|
578
|
+
// support string urls in image parts:
|
579
|
+
typeof part === "string" && (part.startsWith("http:") || part.startsWith("https:")) ? new URL(part) : part
|
580
|
+
)
|
581
|
+
).filter((image) => image instanceof URL);
|
582
|
+
const downloadedImages = await Promise.all(
|
583
|
+
urls.map(async (url) => ({
|
584
|
+
url,
|
585
|
+
data: await downloadImplementation({ url })
|
586
|
+
}))
|
587
|
+
);
|
588
|
+
return Object.fromEntries(
|
589
|
+
downloadedImages.map(({ url, data }) => [url.toString(), data])
|
590
|
+
);
|
429
591
|
}
|
430
592
|
|
431
|
-
//
|
432
|
-
import {
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
message,
|
440
|
-
reason,
|
441
|
-
errors
|
442
|
-
}) {
|
443
|
-
super({ name, message });
|
444
|
-
this[_a] = true;
|
445
|
-
this.reason = reason;
|
446
|
-
this.errors = errors;
|
447
|
-
this.lastError = errors[errors.length - 1];
|
448
|
-
}
|
449
|
-
static isInstance(error) {
|
450
|
-
return AISDKError.hasMarker(error, marker);
|
451
|
-
}
|
452
|
-
/**
|
453
|
-
* @deprecated use `isInstance` instead
|
454
|
-
*/
|
455
|
-
static isRetryError(error) {
|
456
|
-
return error instanceof Error && error.name === name && typeof error.reason === "string" && Array.isArray(error.errors);
|
593
|
+
// core/prompt/get-validated-prompt.ts
|
594
|
+
import { InvalidPromptError } from "@ai-sdk/provider";
|
595
|
+
function getValidatedPrompt(prompt) {
|
596
|
+
if (prompt.prompt == null && prompt.messages == null) {
|
597
|
+
throw new InvalidPromptError({
|
598
|
+
prompt,
|
599
|
+
message: "prompt or messages must be defined"
|
600
|
+
});
|
457
601
|
}
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
name: this.name,
|
464
|
-
message: this.message,
|
465
|
-
reason: this.reason,
|
466
|
-
lastError: this.lastError,
|
467
|
-
errors: this.errors
|
468
|
-
};
|
602
|
+
if (prompt.prompt != null && prompt.messages != null) {
|
603
|
+
throw new InvalidPromptError({
|
604
|
+
prompt,
|
605
|
+
message: "prompt and messages cannot be defined at the same time"
|
606
|
+
});
|
469
607
|
}
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
} = {}) => async (f) => _retryWithExponentialBackoff(f, {
|
479
|
-
maxRetries,
|
480
|
-
delayInMs: initialDelayInMs,
|
481
|
-
backoffFactor
|
482
|
-
});
|
483
|
-
async function _retryWithExponentialBackoff(f, {
|
484
|
-
maxRetries,
|
485
|
-
delayInMs,
|
486
|
-
backoffFactor
|
487
|
-
}, errors = []) {
|
488
|
-
try {
|
489
|
-
return await f();
|
490
|
-
} catch (error) {
|
491
|
-
if (isAbortError(error)) {
|
492
|
-
throw error;
|
493
|
-
}
|
494
|
-
if (maxRetries === 0) {
|
495
|
-
throw error;
|
496
|
-
}
|
497
|
-
const errorMessage = getErrorMessage(error);
|
498
|
-
const newErrors = [...errors, error];
|
499
|
-
const tryNumber = newErrors.length;
|
500
|
-
if (tryNumber > maxRetries) {
|
501
|
-
throw new RetryError({
|
502
|
-
message: `Failed after ${tryNumber} attempts. Last error: ${errorMessage}`,
|
503
|
-
reason: "maxRetriesExceeded",
|
504
|
-
errors: newErrors
|
505
|
-
});
|
506
|
-
}
|
507
|
-
if (error instanceof Error && APICallError.isAPICallError(error) && error.isRetryable === true && tryNumber <= maxRetries) {
|
508
|
-
await delay(delayInMs);
|
509
|
-
return _retryWithExponentialBackoff(
|
510
|
-
f,
|
511
|
-
{ maxRetries, delayInMs: backoffFactor * delayInMs, backoffFactor },
|
512
|
-
newErrors
|
513
|
-
);
|
514
|
-
}
|
515
|
-
if (tryNumber === 1) {
|
516
|
-
throw error;
|
608
|
+
if (prompt.messages != null) {
|
609
|
+
for (const message of prompt.messages) {
|
610
|
+
if (message.role === "system" && typeof message.content !== "string") {
|
611
|
+
throw new InvalidPromptError({
|
612
|
+
prompt,
|
613
|
+
message: "system message content must be a string"
|
614
|
+
});
|
615
|
+
}
|
517
616
|
}
|
518
|
-
throw new RetryError({
|
519
|
-
message: `Failed after ${tryNumber} attempts with non-retryable error: '${errorMessage}'`,
|
520
|
-
reason: "errorNotRetryable",
|
521
|
-
errors: newErrors
|
522
|
-
});
|
523
617
|
}
|
618
|
+
return prompt.prompt != null ? {
|
619
|
+
type: "prompt",
|
620
|
+
prompt: prompt.prompt,
|
621
|
+
messages: void 0,
|
622
|
+
system: prompt.system
|
623
|
+
} : {
|
624
|
+
type: "messages",
|
625
|
+
prompt: void 0,
|
626
|
+
messages: prompt.messages,
|
627
|
+
// only possible case bc of checks above
|
628
|
+
system: prompt.system
|
629
|
+
};
|
524
630
|
}
|
525
631
|
|
526
|
-
//
|
527
|
-
import {
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
var
|
532
|
-
var
|
533
|
-
var symbol2 = Symbol.for(marker2);
|
534
|
-
var _a2;
|
535
|
-
var DownloadError = class extends AISDKError2 {
|
632
|
+
// errors/invalid-argument-error.ts
|
633
|
+
import { AISDKError as AISDKError4 } from "@ai-sdk/provider";
|
634
|
+
var name4 = "AI_InvalidArgumentError";
|
635
|
+
var marker4 = `vercel.ai.error.${name4}`;
|
636
|
+
var symbol4 = Symbol.for(marker4);
|
637
|
+
var _a4;
|
638
|
+
var InvalidArgumentError = class extends AISDKError4 {
|
536
639
|
constructor({
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
cause,
|
541
|
-
message = cause == null ? `Failed to download ${url}: ${statusCode} ${statusText}` : `Failed to download ${url}: ${cause}`
|
640
|
+
parameter,
|
641
|
+
value,
|
642
|
+
message
|
542
643
|
}) {
|
543
|
-
super({
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
this
|
644
|
+
super({
|
645
|
+
name: name4,
|
646
|
+
message: `Invalid argument for parameter ${parameter}: ${message}`
|
647
|
+
});
|
648
|
+
this[_a4] = true;
|
649
|
+
this.parameter = parameter;
|
650
|
+
this.value = value;
|
548
651
|
}
|
549
652
|
static isInstance(error) {
|
550
|
-
return
|
653
|
+
return AISDKError4.hasMarker(error, marker4);
|
551
654
|
}
|
552
655
|
/**
|
553
656
|
* @deprecated use `isInstance` instead
|
554
657
|
*/
|
555
|
-
static
|
556
|
-
return error instanceof Error && error.name ===
|
658
|
+
static isInvalidArgumentError(error) {
|
659
|
+
return error instanceof Error && error.name === name4 && typeof error.parameter === "string" && typeof error.value === "string";
|
557
660
|
}
|
558
|
-
/**
|
559
|
-
* @deprecated Do not use this method. It will be removed in the next major version.
|
560
|
-
*/
|
561
661
|
toJSON() {
|
562
662
|
return {
|
563
663
|
name: this.name,
|
564
664
|
message: this.message,
|
565
|
-
|
566
|
-
|
567
|
-
|
568
|
-
cause: this.cause
|
665
|
+
stack: this.stack,
|
666
|
+
parameter: this.parameter,
|
667
|
+
value: this.value
|
569
668
|
};
|
570
669
|
}
|
571
670
|
};
|
572
|
-
|
671
|
+
_a4 = symbol4;
|
573
672
|
|
574
|
-
//
|
575
|
-
|
576
|
-
|
577
|
-
|
673
|
+
// core/prompt/prepare-call-settings.ts
|
674
|
+
function prepareCallSettings({
|
675
|
+
maxTokens,
|
676
|
+
temperature,
|
677
|
+
topP,
|
678
|
+
presencePenalty,
|
679
|
+
frequencyPenalty,
|
680
|
+
stopSequences,
|
681
|
+
seed,
|
682
|
+
maxRetries
|
578
683
|
}) {
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
url: urlText,
|
586
|
-
statusCode: response.status,
|
587
|
-
statusText: response.statusText
|
684
|
+
if (maxTokens != null) {
|
685
|
+
if (!Number.isInteger(maxTokens)) {
|
686
|
+
throw new InvalidArgumentError({
|
687
|
+
parameter: "maxTokens",
|
688
|
+
value: maxTokens,
|
689
|
+
message: "maxTokens must be an integer"
|
588
690
|
});
|
589
691
|
}
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
692
|
+
if (maxTokens < 1) {
|
693
|
+
throw new InvalidArgumentError({
|
694
|
+
parameter: "maxTokens",
|
695
|
+
value: maxTokens,
|
696
|
+
message: "maxTokens must be >= 1"
|
697
|
+
});
|
698
|
+
}
|
699
|
+
}
|
700
|
+
if (temperature != null) {
|
701
|
+
if (typeof temperature !== "number") {
|
702
|
+
throw new InvalidArgumentError({
|
703
|
+
parameter: "temperature",
|
704
|
+
value: temperature,
|
705
|
+
message: "temperature must be a number"
|
706
|
+
});
|
707
|
+
}
|
708
|
+
}
|
709
|
+
if (topP != null) {
|
710
|
+
if (typeof topP !== "number") {
|
711
|
+
throw new InvalidArgumentError({
|
712
|
+
parameter: "topP",
|
713
|
+
value: topP,
|
714
|
+
message: "topP must be a number"
|
715
|
+
});
|
716
|
+
}
|
717
|
+
}
|
718
|
+
if (presencePenalty != null) {
|
719
|
+
if (typeof presencePenalty !== "number") {
|
720
|
+
throw new InvalidArgumentError({
|
721
|
+
parameter: "presencePenalty",
|
722
|
+
value: presencePenalty,
|
723
|
+
message: "presencePenalty must be a number"
|
724
|
+
});
|
725
|
+
}
|
726
|
+
}
|
727
|
+
if (frequencyPenalty != null) {
|
728
|
+
if (typeof frequencyPenalty !== "number") {
|
729
|
+
throw new InvalidArgumentError({
|
730
|
+
parameter: "frequencyPenalty",
|
731
|
+
value: frequencyPenalty,
|
732
|
+
message: "frequencyPenalty must be a number"
|
733
|
+
});
|
734
|
+
}
|
735
|
+
}
|
736
|
+
if (seed != null) {
|
737
|
+
if (!Number.isInteger(seed)) {
|
738
|
+
throw new InvalidArgumentError({
|
739
|
+
parameter: "seed",
|
740
|
+
value: seed,
|
741
|
+
message: "seed must be an integer"
|
742
|
+
});
|
743
|
+
}
|
744
|
+
}
|
745
|
+
if (maxRetries != null) {
|
746
|
+
if (!Number.isInteger(maxRetries)) {
|
747
|
+
throw new InvalidArgumentError({
|
748
|
+
parameter: "maxRetries",
|
749
|
+
value: maxRetries,
|
750
|
+
message: "maxRetries must be an integer"
|
751
|
+
});
|
752
|
+
}
|
753
|
+
if (maxRetries < 0) {
|
754
|
+
throw new InvalidArgumentError({
|
755
|
+
parameter: "maxRetries",
|
756
|
+
value: maxRetries,
|
757
|
+
message: "maxRetries must be >= 0"
|
758
|
+
});
|
597
759
|
}
|
598
|
-
throw new DownloadError({ url: urlText, cause: error });
|
599
760
|
}
|
761
|
+
return {
|
762
|
+
maxTokens,
|
763
|
+
temperature: temperature != null ? temperature : 0,
|
764
|
+
topP,
|
765
|
+
presencePenalty,
|
766
|
+
frequencyPenalty,
|
767
|
+
stopSequences: stopSequences != null && stopSequences.length > 0 ? stopSequences : void 0,
|
768
|
+
seed,
|
769
|
+
maxRetries: maxRetries != null ? maxRetries : 2
|
770
|
+
};
|
600
771
|
}
|
601
772
|
|
602
|
-
// core/
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
773
|
+
// core/prompt/prepare-tools-and-tool-choice.ts
|
774
|
+
import { asSchema } from "@ai-sdk/ui-utils";
|
775
|
+
|
776
|
+
// core/util/is-non-empty-object.ts
|
777
|
+
function isNonEmptyObject(object) {
|
778
|
+
return object != null && Object.keys(object).length > 0;
|
779
|
+
}
|
780
|
+
|
781
|
+
// core/prompt/prepare-tools-and-tool-choice.ts
|
782
|
+
function prepareToolsAndToolChoice({
|
783
|
+
tools,
|
784
|
+
toolChoice
|
785
|
+
}) {
|
786
|
+
if (!isNonEmptyObject(tools)) {
|
787
|
+
return {
|
788
|
+
tools: void 0,
|
789
|
+
toolChoice: void 0
|
790
|
+
};
|
614
791
|
}
|
615
|
-
return
|
792
|
+
return {
|
793
|
+
tools: Object.entries(tools).map(([name8, tool]) => ({
|
794
|
+
type: "function",
|
795
|
+
name: name8,
|
796
|
+
description: tool.description,
|
797
|
+
parameters: asSchema(tool.parameters).jsonSchema
|
798
|
+
})),
|
799
|
+
toolChoice: toolChoice == null ? { type: "auto" } : typeof toolChoice === "string" ? { type: toolChoice } : { type: "tool", toolName: toolChoice.toolName }
|
800
|
+
};
|
616
801
|
}
|
617
802
|
|
618
|
-
// core/
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
803
|
+
// core/types/token-usage.ts
|
804
|
+
function calculateCompletionTokenUsage(usage) {
|
805
|
+
return {
|
806
|
+
promptTokens: usage.promptTokens,
|
807
|
+
completionTokens: usage.completionTokens,
|
808
|
+
totalTokens: usage.promptTokens + usage.completionTokens
|
809
|
+
};
|
810
|
+
}
|
623
811
|
|
624
|
-
//
|
625
|
-
import { AISDKError as
|
626
|
-
var
|
627
|
-
var
|
628
|
-
var
|
629
|
-
var
|
630
|
-
var
|
812
|
+
// errors/invalid-tool-arguments-error.ts
|
813
|
+
import { AISDKError as AISDKError5, getErrorMessage as getErrorMessage2 } from "@ai-sdk/provider";
|
814
|
+
var name5 = "AI_InvalidToolArgumentsError";
|
815
|
+
var marker5 = `vercel.ai.error.${name5}`;
|
816
|
+
var symbol5 = Symbol.for(marker5);
|
817
|
+
var _a5;
|
818
|
+
var InvalidToolArgumentsError = class extends AISDKError5 {
|
631
819
|
constructor({
|
632
|
-
|
820
|
+
toolArgs,
|
821
|
+
toolName,
|
633
822
|
cause,
|
634
|
-
message = `Invalid
|
823
|
+
message = `Invalid arguments for tool ${toolName}: ${getErrorMessage2(
|
824
|
+
cause
|
825
|
+
)}`
|
635
826
|
}) {
|
636
|
-
super({ name:
|
637
|
-
this[
|
638
|
-
this.
|
827
|
+
super({ name: name5, message, cause });
|
828
|
+
this[_a5] = true;
|
829
|
+
this.toolArgs = toolArgs;
|
830
|
+
this.toolName = toolName;
|
639
831
|
}
|
640
832
|
static isInstance(error) {
|
641
|
-
return
|
833
|
+
return AISDKError5.hasMarker(error, marker5);
|
642
834
|
}
|
643
835
|
/**
|
644
836
|
* @deprecated use `isInstance` instead
|
645
837
|
*/
|
646
|
-
static
|
647
|
-
return error instanceof Error && error.name ===
|
838
|
+
static isInvalidToolArgumentsError(error) {
|
839
|
+
return error instanceof Error && error.name === name5 && typeof error.toolName === "string" && typeof error.toolArgs === "string";
|
648
840
|
}
|
649
841
|
/**
|
650
842
|
* @deprecated Do not use this method. It will be removed in the next major version.
|
@@ -653,59 +845,40 @@ var InvalidDataContentError = class extends AISDKError3 {
|
|
653
845
|
return {
|
654
846
|
name: this.name,
|
655
847
|
message: this.message,
|
656
|
-
stack: this.stack,
|
657
848
|
cause: this.cause,
|
658
|
-
|
849
|
+
stack: this.stack,
|
850
|
+
toolName: this.toolName,
|
851
|
+
toolArgs: this.toolArgs
|
659
852
|
};
|
660
|
-
}
|
661
|
-
};
|
662
|
-
|
663
|
-
|
664
|
-
// core/prompt/data-content.ts
|
665
|
-
function convertDataContentToUint8Array(content) {
|
666
|
-
if (content instanceof Uint8Array) {
|
667
|
-
return content;
|
668
|
-
}
|
669
|
-
if (typeof content === "string") {
|
670
|
-
try {
|
671
|
-
return convertBase64ToUint8Array(content);
|
672
|
-
} catch (error) {
|
673
|
-
throw new InvalidDataContentError({
|
674
|
-
message: "Invalid data content. Content string is not a base64-encoded media.",
|
675
|
-
content,
|
676
|
-
cause: error
|
677
|
-
});
|
678
|
-
}
|
679
|
-
}
|
680
|
-
if (content instanceof ArrayBuffer) {
|
681
|
-
return new Uint8Array(content);
|
682
|
-
}
|
683
|
-
throw new InvalidDataContentError({ content });
|
684
|
-
}
|
853
|
+
}
|
854
|
+
};
|
855
|
+
_a5 = symbol5;
|
685
856
|
|
686
|
-
//
|
687
|
-
import { AISDKError as
|
688
|
-
var
|
689
|
-
var
|
690
|
-
var
|
691
|
-
var
|
692
|
-
var
|
857
|
+
// errors/no-such-tool-error.ts
|
858
|
+
import { AISDKError as AISDKError6 } from "@ai-sdk/provider";
|
859
|
+
var name6 = "AI_NoSuchToolError";
|
860
|
+
var marker6 = `vercel.ai.error.${name6}`;
|
861
|
+
var symbol6 = Symbol.for(marker6);
|
862
|
+
var _a6;
|
863
|
+
var NoSuchToolError = class extends AISDKError6 {
|
693
864
|
constructor({
|
694
|
-
|
695
|
-
|
865
|
+
toolName,
|
866
|
+
availableTools = void 0,
|
867
|
+
message = `Model tried to call unavailable tool '${toolName}'. ${availableTools === void 0 ? "No tools are available." : `Available tools: ${availableTools.join(", ")}.`}`
|
696
868
|
}) {
|
697
|
-
super({ name:
|
698
|
-
this[
|
699
|
-
this.
|
869
|
+
super({ name: name6, message });
|
870
|
+
this[_a6] = true;
|
871
|
+
this.toolName = toolName;
|
872
|
+
this.availableTools = availableTools;
|
700
873
|
}
|
701
874
|
static isInstance(error) {
|
702
|
-
return
|
875
|
+
return AISDKError6.hasMarker(error, marker6);
|
703
876
|
}
|
704
877
|
/**
|
705
878
|
* @deprecated use `isInstance` instead
|
706
879
|
*/
|
707
|
-
static
|
708
|
-
return error instanceof Error && error.name ===
|
880
|
+
static isNoSuchToolError(error) {
|
881
|
+
return error instanceof Error && error.name === name6 && "toolName" in error && error.toolName != void 0 && typeof error.name === "string";
|
709
882
|
}
|
710
883
|
/**
|
711
884
|
* @deprecated Do not use this method. It will be removed in the next major version.
|
@@ -715,528 +888,429 @@ var InvalidMessageRoleError = class extends AISDKError4 {
|
|
715
888
|
name: this.name,
|
716
889
|
message: this.message,
|
717
890
|
stack: this.stack,
|
718
|
-
|
891
|
+
toolName: this.toolName,
|
892
|
+
availableTools: this.availableTools
|
719
893
|
};
|
720
894
|
}
|
721
895
|
};
|
722
|
-
|
896
|
+
_a6 = symbol6;
|
723
897
|
|
724
|
-
//
|
725
|
-
|
726
|
-
|
727
|
-
modelSupportsImageUrls = true,
|
728
|
-
downloadImplementation = download
|
729
|
-
}) {
|
730
|
-
const languageModelMessages = [];
|
731
|
-
if (prompt.system != null) {
|
732
|
-
languageModelMessages.push({ role: "system", content: prompt.system });
|
733
|
-
}
|
734
|
-
const downloadedImages = modelSupportsImageUrls || prompt.messages == null ? null : await downloadImages(prompt.messages, downloadImplementation);
|
735
|
-
const promptType = prompt.type;
|
736
|
-
switch (promptType) {
|
737
|
-
case "prompt": {
|
738
|
-
languageModelMessages.push({
|
739
|
-
role: "user",
|
740
|
-
content: [{ type: "text", text: prompt.prompt }]
|
741
|
-
});
|
742
|
-
break;
|
743
|
-
}
|
744
|
-
case "messages": {
|
745
|
-
languageModelMessages.push(
|
746
|
-
...prompt.messages.map(
|
747
|
-
(message) => convertToLanguageModelMessage(message, downloadedImages)
|
748
|
-
)
|
749
|
-
);
|
750
|
-
break;
|
751
|
-
}
|
752
|
-
default: {
|
753
|
-
const _exhaustiveCheck = promptType;
|
754
|
-
throw new Error(`Unsupported prompt type: ${_exhaustiveCheck}`);
|
755
|
-
}
|
756
|
-
}
|
757
|
-
return languageModelMessages;
|
758
|
-
}
|
759
|
-
function convertToLanguageModelMessage(message, downloadedImages) {
|
760
|
-
const role = message.role;
|
761
|
-
switch (role) {
|
762
|
-
case "system": {
|
763
|
-
return { role: "system", content: message.content };
|
764
|
-
}
|
765
|
-
case "user": {
|
766
|
-
if (typeof message.content === "string") {
|
767
|
-
return {
|
768
|
-
role: "user",
|
769
|
-
content: [{ type: "text", text: message.content }]
|
770
|
-
};
|
771
|
-
}
|
772
|
-
return {
|
773
|
-
role: "user",
|
774
|
-
content: message.content.map(
|
775
|
-
(part) => {
|
776
|
-
var _a8, _b, _c;
|
777
|
-
switch (part.type) {
|
778
|
-
case "text": {
|
779
|
-
return part;
|
780
|
-
}
|
781
|
-
case "image": {
|
782
|
-
if (part.image instanceof URL) {
|
783
|
-
if (downloadedImages == null) {
|
784
|
-
return {
|
785
|
-
type: "image",
|
786
|
-
image: part.image,
|
787
|
-
mimeType: part.mimeType
|
788
|
-
};
|
789
|
-
} else {
|
790
|
-
const downloadedImage = downloadedImages[part.image.toString()];
|
791
|
-
return {
|
792
|
-
type: "image",
|
793
|
-
image: downloadedImage.data,
|
794
|
-
mimeType: (_a8 = part.mimeType) != null ? _a8 : downloadedImage.mimeType
|
795
|
-
};
|
796
|
-
}
|
797
|
-
}
|
798
|
-
if (typeof part.image === "string") {
|
799
|
-
try {
|
800
|
-
const url = new URL(part.image);
|
801
|
-
switch (url.protocol) {
|
802
|
-
case "http:":
|
803
|
-
case "https:": {
|
804
|
-
if (downloadedImages == null) {
|
805
|
-
return {
|
806
|
-
type: "image",
|
807
|
-
image: url,
|
808
|
-
mimeType: part.mimeType
|
809
|
-
};
|
810
|
-
} else {
|
811
|
-
const downloadedImage = downloadedImages[part.image];
|
812
|
-
return {
|
813
|
-
type: "image",
|
814
|
-
image: downloadedImage.data,
|
815
|
-
mimeType: (_b = part.mimeType) != null ? _b : downloadedImage.mimeType
|
816
|
-
};
|
817
|
-
}
|
818
|
-
}
|
819
|
-
case "data:": {
|
820
|
-
try {
|
821
|
-
const [header, base64Content] = part.image.split(",");
|
822
|
-
const mimeType = header.split(";")[0].split(":")[1];
|
823
|
-
if (mimeType == null || base64Content == null) {
|
824
|
-
throw new Error("Invalid data URL format");
|
825
|
-
}
|
826
|
-
return {
|
827
|
-
type: "image",
|
828
|
-
image: convertDataContentToUint8Array(base64Content),
|
829
|
-
mimeType
|
830
|
-
};
|
831
|
-
} catch (error) {
|
832
|
-
throw new Error(
|
833
|
-
`Error processing data URL: ${getErrorMessage2(
|
834
|
-
message
|
835
|
-
)}`
|
836
|
-
);
|
837
|
-
}
|
838
|
-
}
|
839
|
-
default: {
|
840
|
-
throw new Error(
|
841
|
-
`Unsupported URL protocol: ${url.protocol}`
|
842
|
-
);
|
843
|
-
}
|
844
|
-
}
|
845
|
-
} catch (_ignored) {
|
846
|
-
}
|
847
|
-
}
|
848
|
-
const imageUint8 = convertDataContentToUint8Array(part.image);
|
849
|
-
return {
|
850
|
-
type: "image",
|
851
|
-
image: imageUint8,
|
852
|
-
mimeType: (_c = part.mimeType) != null ? _c : detectImageMimeType(imageUint8)
|
853
|
-
};
|
854
|
-
}
|
855
|
-
}
|
856
|
-
}
|
857
|
-
)
|
858
|
-
};
|
859
|
-
}
|
860
|
-
case "assistant": {
|
861
|
-
if (typeof message.content === "string") {
|
862
|
-
return {
|
863
|
-
role: "assistant",
|
864
|
-
content: [{ type: "text", text: message.content }]
|
865
|
-
};
|
866
|
-
}
|
867
|
-
return {
|
868
|
-
role: "assistant",
|
869
|
-
content: message.content.filter(
|
870
|
-
// remove empty text parts:
|
871
|
-
(part) => part.type !== "text" || part.text !== ""
|
872
|
-
)
|
873
|
-
};
|
874
|
-
}
|
875
|
-
case "tool": {
|
876
|
-
return message;
|
877
|
-
}
|
878
|
-
default: {
|
879
|
-
const _exhaustiveCheck = role;
|
880
|
-
throw new InvalidMessageRoleError({ role: _exhaustiveCheck });
|
881
|
-
}
|
882
|
-
}
|
898
|
+
// util/is-async-generator.ts
|
899
|
+
function isAsyncGenerator(value) {
|
900
|
+
return value != null && typeof value === "object" && Symbol.asyncIterator in value;
|
883
901
|
}
|
884
|
-
|
885
|
-
|
886
|
-
|
887
|
-
|
888
|
-
(part) => (
|
889
|
-
// support string urls in image parts:
|
890
|
-
typeof part === "string" && (part.startsWith("http:") || part.startsWith("https:")) ? new URL(part) : part
|
891
|
-
)
|
892
|
-
).filter((image) => image instanceof URL);
|
893
|
-
const downloadedImages = await Promise.all(
|
894
|
-
urls.map(async (url) => ({
|
895
|
-
url,
|
896
|
-
data: await downloadImplementation({ url })
|
897
|
-
}))
|
898
|
-
);
|
899
|
-
return Object.fromEntries(
|
900
|
-
downloadedImages.map(({ url, data }) => [url.toString(), data])
|
901
|
-
);
|
902
|
+
|
903
|
+
// util/is-generator.ts
|
904
|
+
function isGenerator(value) {
|
905
|
+
return value != null && typeof value === "object" && Symbol.iterator in value;
|
902
906
|
}
|
903
907
|
|
904
|
-
//
|
905
|
-
import {
|
906
|
-
|
907
|
-
|
908
|
-
|
909
|
-
|
910
|
-
|
911
|
-
});
|
912
|
-
}
|
913
|
-
if (prompt.prompt != null && prompt.messages != null) {
|
914
|
-
throw new InvalidPromptError({
|
915
|
-
prompt,
|
916
|
-
message: "prompt and messages cannot be defined at the same time"
|
917
|
-
});
|
918
|
-
}
|
919
|
-
if (prompt.messages != null) {
|
920
|
-
for (const message of prompt.messages) {
|
921
|
-
if (message.role === "system" && typeof message.content !== "string") {
|
922
|
-
throw new InvalidPromptError({
|
923
|
-
prompt,
|
924
|
-
message: "system message content must be a string"
|
925
|
-
});
|
926
|
-
}
|
927
|
-
}
|
928
|
-
}
|
929
|
-
return prompt.prompt != null ? {
|
930
|
-
type: "prompt",
|
931
|
-
prompt: prompt.prompt,
|
932
|
-
messages: void 0,
|
933
|
-
system: prompt.system
|
934
|
-
} : {
|
935
|
-
type: "messages",
|
936
|
-
prompt: void 0,
|
937
|
-
messages: prompt.messages,
|
938
|
-
// only possible case bc of checks above
|
939
|
-
system: prompt.system
|
940
|
-
};
|
908
|
+
// util/retry-with-exponential-backoff.ts
|
909
|
+
import { APICallError } from "@ai-sdk/provider";
|
910
|
+
import { getErrorMessage as getErrorMessage3, isAbortError } from "@ai-sdk/provider-utils";
|
911
|
+
|
912
|
+
// util/delay.ts
|
913
|
+
async function delay(delayInMs) {
|
914
|
+
return delayInMs === void 0 ? Promise.resolve() : new Promise((resolve) => setTimeout(resolve, delayInMs));
|
941
915
|
}
|
942
916
|
|
943
|
-
//
|
944
|
-
import { AISDKError as
|
945
|
-
var
|
946
|
-
var
|
947
|
-
var
|
948
|
-
var
|
949
|
-
var
|
917
|
+
// util/retry-error.ts
|
918
|
+
import { AISDKError as AISDKError7 } from "@ai-sdk/provider";
|
919
|
+
var name7 = "AI_RetryError";
|
920
|
+
var marker7 = `vercel.ai.error.${name7}`;
|
921
|
+
var symbol7 = Symbol.for(marker7);
|
922
|
+
var _a7;
|
923
|
+
var RetryError = class extends AISDKError7 {
|
950
924
|
constructor({
|
951
|
-
|
952
|
-
|
953
|
-
|
925
|
+
message,
|
926
|
+
reason,
|
927
|
+
errors
|
954
928
|
}) {
|
955
|
-
super({
|
956
|
-
|
957
|
-
|
958
|
-
|
959
|
-
this
|
960
|
-
this.parameter = parameter;
|
961
|
-
this.value = value;
|
929
|
+
super({ name: name7, message });
|
930
|
+
this[_a7] = true;
|
931
|
+
this.reason = reason;
|
932
|
+
this.errors = errors;
|
933
|
+
this.lastError = errors[errors.length - 1];
|
962
934
|
}
|
963
935
|
static isInstance(error) {
|
964
|
-
return
|
936
|
+
return AISDKError7.hasMarker(error, marker7);
|
965
937
|
}
|
966
938
|
/**
|
967
939
|
* @deprecated use `isInstance` instead
|
968
940
|
*/
|
969
|
-
static
|
970
|
-
return error instanceof Error && error.name ===
|
941
|
+
static isRetryError(error) {
|
942
|
+
return error instanceof Error && error.name === name7 && typeof error.reason === "string" && Array.isArray(error.errors);
|
971
943
|
}
|
944
|
+
/**
|
945
|
+
* @deprecated Do not use this method. It will be removed in the next major version.
|
946
|
+
*/
|
972
947
|
toJSON() {
|
973
948
|
return {
|
974
949
|
name: this.name,
|
975
950
|
message: this.message,
|
976
|
-
|
977
|
-
|
978
|
-
|
951
|
+
reason: this.reason,
|
952
|
+
lastError: this.lastError,
|
953
|
+
errors: this.errors
|
979
954
|
};
|
980
955
|
}
|
981
956
|
};
|
982
|
-
|
957
|
+
_a7 = symbol7;
|
983
958
|
|
984
|
-
//
|
985
|
-
|
986
|
-
|
987
|
-
|
988
|
-
|
989
|
-
|
990
|
-
|
991
|
-
|
992
|
-
|
993
|
-
|
994
|
-
|
995
|
-
|
996
|
-
|
997
|
-
|
998
|
-
|
999
|
-
|
1000
|
-
|
1001
|
-
|
1002
|
-
|
1003
|
-
|
1004
|
-
throw new InvalidArgumentError({
|
1005
|
-
parameter: "maxTokens",
|
1006
|
-
value: maxTokens,
|
1007
|
-
message: "maxTokens must be >= 1"
|
1008
|
-
});
|
1009
|
-
}
|
1010
|
-
}
|
1011
|
-
if (temperature != null) {
|
1012
|
-
if (typeof temperature !== "number") {
|
1013
|
-
throw new InvalidArgumentError({
|
1014
|
-
parameter: "temperature",
|
1015
|
-
value: temperature,
|
1016
|
-
message: "temperature must be a number"
|
1017
|
-
});
|
959
|
+
// util/retry-with-exponential-backoff.ts
|
960
|
+
var retryWithExponentialBackoff = ({
|
961
|
+
maxRetries = 2,
|
962
|
+
initialDelayInMs = 2e3,
|
963
|
+
backoffFactor = 2
|
964
|
+
} = {}) => async (f) => _retryWithExponentialBackoff(f, {
|
965
|
+
maxRetries,
|
966
|
+
delayInMs: initialDelayInMs,
|
967
|
+
backoffFactor
|
968
|
+
});
|
969
|
+
async function _retryWithExponentialBackoff(f, {
|
970
|
+
maxRetries,
|
971
|
+
delayInMs,
|
972
|
+
backoffFactor
|
973
|
+
}, errors = []) {
|
974
|
+
try {
|
975
|
+
return await f();
|
976
|
+
} catch (error) {
|
977
|
+
if (isAbortError(error)) {
|
978
|
+
throw error;
|
1018
979
|
}
|
1019
|
-
|
1020
|
-
|
1021
|
-
if (typeof topP !== "number") {
|
1022
|
-
throw new InvalidArgumentError({
|
1023
|
-
parameter: "topP",
|
1024
|
-
value: topP,
|
1025
|
-
message: "topP must be a number"
|
1026
|
-
});
|
980
|
+
if (maxRetries === 0) {
|
981
|
+
throw error;
|
1027
982
|
}
|
1028
|
-
|
1029
|
-
|
1030
|
-
|
1031
|
-
|
1032
|
-
|
1033
|
-
|
1034
|
-
|
983
|
+
const errorMessage = getErrorMessage3(error);
|
984
|
+
const newErrors = [...errors, error];
|
985
|
+
const tryNumber = newErrors.length;
|
986
|
+
if (tryNumber > maxRetries) {
|
987
|
+
throw new RetryError({
|
988
|
+
message: `Failed after ${tryNumber} attempts. Last error: ${errorMessage}`,
|
989
|
+
reason: "maxRetriesExceeded",
|
990
|
+
errors: newErrors
|
1035
991
|
});
|
1036
992
|
}
|
1037
|
-
|
1038
|
-
|
1039
|
-
|
1040
|
-
|
1041
|
-
|
1042
|
-
|
1043
|
-
|
1044
|
-
});
|
993
|
+
if (error instanceof Error && APICallError.isAPICallError(error) && error.isRetryable === true && tryNumber <= maxRetries) {
|
994
|
+
await delay(delayInMs);
|
995
|
+
return _retryWithExponentialBackoff(
|
996
|
+
f,
|
997
|
+
{ maxRetries, delayInMs: backoffFactor * delayInMs, backoffFactor },
|
998
|
+
newErrors
|
999
|
+
);
|
1045
1000
|
}
|
1046
|
-
|
1047
|
-
|
1048
|
-
if (!Number.isInteger(seed)) {
|
1049
|
-
throw new InvalidArgumentError({
|
1050
|
-
parameter: "seed",
|
1051
|
-
value: seed,
|
1052
|
-
message: "seed must be an integer"
|
1053
|
-
});
|
1001
|
+
if (tryNumber === 1) {
|
1002
|
+
throw error;
|
1054
1003
|
}
|
1004
|
+
throw new RetryError({
|
1005
|
+
message: `Failed after ${tryNumber} attempts with non-retryable error: '${errorMessage}'`,
|
1006
|
+
reason: "errorNotRetryable",
|
1007
|
+
errors: newErrors
|
1008
|
+
});
|
1055
1009
|
}
|
1056
|
-
|
1057
|
-
|
1058
|
-
|
1059
|
-
|
1060
|
-
|
1061
|
-
|
1062
|
-
|
1010
|
+
}
|
1011
|
+
|
1012
|
+
// util/constants.ts
|
1013
|
+
var HANGING_STREAM_WARNING_TIME_MS = 15 * 1e3;
|
1014
|
+
|
1015
|
+
// rsc/streamable-ui/create-suspended-chunk.tsx
|
1016
|
+
import { Suspense } from "react";
|
1017
|
+
import { Fragment, jsx as jsx2, jsxs } from "react/jsx-runtime";
|
1018
|
+
var R = [
|
1019
|
+
async ({
|
1020
|
+
c: current,
|
1021
|
+
n: next
|
1022
|
+
}) => {
|
1023
|
+
const chunk = await next;
|
1024
|
+
if (chunk.done) {
|
1025
|
+
return chunk.value;
|
1063
1026
|
}
|
1064
|
-
if (
|
1065
|
-
|
1066
|
-
|
1067
|
-
value:
|
1068
|
-
|
1069
|
-
});
|
1027
|
+
if (chunk.append) {
|
1028
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
1029
|
+
current,
|
1030
|
+
/* @__PURE__ */ jsx2(Suspense, { fallback: chunk.value, children: /* @__PURE__ */ jsx2(R, { c: chunk.value, n: chunk.next }) })
|
1031
|
+
] });
|
1070
1032
|
}
|
1033
|
+
return /* @__PURE__ */ jsx2(Suspense, { fallback: chunk.value, children: /* @__PURE__ */ jsx2(R, { c: chunk.value, n: chunk.next }) });
|
1071
1034
|
}
|
1035
|
+
][0];
|
1036
|
+
function createSuspendedChunk(initialValue) {
|
1037
|
+
const { promise, resolve, reject } = createResolvablePromise();
|
1072
1038
|
return {
|
1073
|
-
|
1074
|
-
|
1075
|
-
|
1076
|
-
presencePenalty,
|
1077
|
-
frequencyPenalty,
|
1078
|
-
stopSequences: stopSequences != null && stopSequences.length > 0 ? stopSequences : void 0,
|
1079
|
-
seed,
|
1080
|
-
maxRetries: maxRetries != null ? maxRetries : 2
|
1081
|
-
};
|
1082
|
-
}
|
1083
|
-
|
1084
|
-
// core/types/token-usage.ts
|
1085
|
-
function calculateCompletionTokenUsage(usage) {
|
1086
|
-
return {
|
1087
|
-
promptTokens: usage.promptTokens,
|
1088
|
-
completionTokens: usage.completionTokens,
|
1089
|
-
totalTokens: usage.promptTokens + usage.completionTokens
|
1039
|
+
row: /* @__PURE__ */ jsx2(Suspense, { fallback: initialValue, children: /* @__PURE__ */ jsx2(R, { c: initialValue, n: promise }) }),
|
1040
|
+
resolve,
|
1041
|
+
reject
|
1090
1042
|
};
|
1091
1043
|
}
|
1092
1044
|
|
1093
|
-
//
|
1094
|
-
|
1095
|
-
|
1096
|
-
|
1097
|
-
|
1098
|
-
|
1099
|
-
|
1100
|
-
|
1101
|
-
|
1102
|
-
|
1103
|
-
|
1104
|
-
|
1105
|
-
|
1106
|
-
|
1107
|
-
|
1108
|
-
}
|
1109
|
-
|
1110
|
-
|
1111
|
-
|
1112
|
-
|
1113
|
-
|
1114
|
-
}
|
1115
|
-
|
1116
|
-
|
1117
|
-
|
1118
|
-
|
1119
|
-
{
|
1120
|
-
|
1121
|
-
|
1122
|
-
|
1045
|
+
// rsc/streamable-ui/create-streamable-ui.tsx
|
1046
|
+
function createStreamableUI(initialValue) {
|
1047
|
+
let currentValue = initialValue;
|
1048
|
+
let closed = false;
|
1049
|
+
let { row, resolve, reject } = createSuspendedChunk(initialValue);
|
1050
|
+
function assertStream(method) {
|
1051
|
+
if (closed) {
|
1052
|
+
throw new Error(method + ": UI stream is already closed.");
|
1053
|
+
}
|
1054
|
+
}
|
1055
|
+
let warningTimeout;
|
1056
|
+
function warnUnclosedStream() {
|
1057
|
+
if (process.env.NODE_ENV === "development") {
|
1058
|
+
if (warningTimeout) {
|
1059
|
+
clearTimeout(warningTimeout);
|
1060
|
+
}
|
1061
|
+
warningTimeout = setTimeout(() => {
|
1062
|
+
console.warn(
|
1063
|
+
"The streamable UI has been slow to update. This may be a bug or a performance issue or you forgot to call `.done()`."
|
1064
|
+
);
|
1065
|
+
}, HANGING_STREAM_WARNING_TIME_MS);
|
1066
|
+
}
|
1067
|
+
}
|
1068
|
+
warnUnclosedStream();
|
1069
|
+
const streamable2 = {
|
1070
|
+
value: row,
|
1071
|
+
update(value) {
|
1072
|
+
assertStream(".update()");
|
1073
|
+
if (value === currentValue) {
|
1074
|
+
warnUnclosedStream();
|
1075
|
+
return streamable2;
|
1076
|
+
}
|
1077
|
+
const resolvable = createResolvablePromise();
|
1078
|
+
currentValue = value;
|
1079
|
+
resolve({ value: currentValue, done: false, next: resolvable.promise });
|
1080
|
+
resolve = resolvable.resolve;
|
1081
|
+
reject = resolvable.reject;
|
1082
|
+
warnUnclosedStream();
|
1083
|
+
return streamable2;
|
1084
|
+
},
|
1085
|
+
append(value) {
|
1086
|
+
assertStream(".append()");
|
1087
|
+
const resolvable = createResolvablePromise();
|
1088
|
+
currentValue = value;
|
1089
|
+
resolve({ value, done: false, append: true, next: resolvable.promise });
|
1090
|
+
resolve = resolvable.resolve;
|
1091
|
+
reject = resolvable.reject;
|
1092
|
+
warnUnclosedStream();
|
1093
|
+
return streamable2;
|
1094
|
+
},
|
1095
|
+
error(error) {
|
1096
|
+
assertStream(".error()");
|
1097
|
+
if (warningTimeout) {
|
1098
|
+
clearTimeout(warningTimeout);
|
1099
|
+
}
|
1100
|
+
closed = true;
|
1101
|
+
reject(error);
|
1102
|
+
return streamable2;
|
1103
|
+
},
|
1104
|
+
done(...args) {
|
1105
|
+
assertStream(".done()");
|
1106
|
+
if (warningTimeout) {
|
1107
|
+
clearTimeout(warningTimeout);
|
1108
|
+
}
|
1109
|
+
closed = true;
|
1110
|
+
if (args.length) {
|
1111
|
+
resolve({ value: args[0], done: true });
|
1112
|
+
return streamable2;
|
1123
1113
|
}
|
1114
|
+
resolve({ value: currentValue, done: true });
|
1115
|
+
return streamable2;
|
1124
1116
|
}
|
1125
|
-
|
1126
|
-
|
1127
|
-
|
1128
|
-
// core/util/is-non-empty-object.ts
|
1129
|
-
function isNonEmptyObject(object) {
|
1130
|
-
return object != null && Object.keys(object).length > 0;
|
1117
|
+
};
|
1118
|
+
return streamable2;
|
1131
1119
|
}
|
1132
1120
|
|
1133
|
-
//
|
1134
|
-
|
1121
|
+
// rsc/stream-ui/stream-ui.tsx
|
1122
|
+
var defaultTextRenderer = ({ content }) => content;
|
1123
|
+
async function streamUI({
|
1124
|
+
model,
|
1135
1125
|
tools,
|
1136
|
-
toolChoice
|
1126
|
+
toolChoice,
|
1127
|
+
system,
|
1128
|
+
prompt,
|
1129
|
+
messages,
|
1130
|
+
maxRetries,
|
1131
|
+
abortSignal,
|
1132
|
+
headers,
|
1133
|
+
initial,
|
1134
|
+
text,
|
1135
|
+
onFinish,
|
1136
|
+
...settings
|
1137
1137
|
}) {
|
1138
|
-
if (
|
1139
|
-
|
1140
|
-
|
1141
|
-
|
1142
|
-
};
|
1138
|
+
if (typeof model === "string") {
|
1139
|
+
throw new Error(
|
1140
|
+
"`model` cannot be a string in `streamUI`. Use the actual model instance instead."
|
1141
|
+
);
|
1143
1142
|
}
|
1144
|
-
|
1145
|
-
|
1146
|
-
|
1147
|
-
|
1148
|
-
description: tool.description,
|
1149
|
-
parameters: asSchema(tool.parameters).jsonSchema
|
1150
|
-
})),
|
1151
|
-
toolChoice: toolChoice == null ? { type: "auto" } : typeof toolChoice === "string" ? { type: toolChoice } : { type: "tool", toolName: toolChoice.toolName }
|
1152
|
-
};
|
1153
|
-
}
|
1154
|
-
|
1155
|
-
// errors/invalid-tool-arguments-error.ts
|
1156
|
-
import { AISDKError as AISDKError6, getErrorMessage as getErrorMessage3 } from "@ai-sdk/provider";
|
1157
|
-
var name6 = "AI_InvalidToolArgumentsError";
|
1158
|
-
var marker6 = `vercel.ai.error.${name6}`;
|
1159
|
-
var symbol6 = Symbol.for(marker6);
|
1160
|
-
var _a6;
|
1161
|
-
var InvalidToolArgumentsError = class extends AISDKError6 {
|
1162
|
-
constructor({
|
1163
|
-
toolArgs,
|
1164
|
-
toolName,
|
1165
|
-
cause,
|
1166
|
-
message = `Invalid arguments for tool ${toolName}: ${getErrorMessage3(
|
1167
|
-
cause
|
1168
|
-
)}`
|
1169
|
-
}) {
|
1170
|
-
super({ name: name6, message, cause });
|
1171
|
-
this[_a6] = true;
|
1172
|
-
this.toolArgs = toolArgs;
|
1173
|
-
this.toolName = toolName;
|
1143
|
+
if ("functions" in settings) {
|
1144
|
+
throw new Error(
|
1145
|
+
"`functions` is not supported in `streamUI`, use `tools` instead."
|
1146
|
+
);
|
1174
1147
|
}
|
1175
|
-
|
1176
|
-
|
1148
|
+
if ("provider" in settings) {
|
1149
|
+
throw new Error(
|
1150
|
+
"`provider` is no longer needed in `streamUI`. Use `model` instead."
|
1151
|
+
);
|
1177
1152
|
}
|
1178
|
-
|
1179
|
-
|
1180
|
-
|
1181
|
-
|
1182
|
-
|
1153
|
+
if (tools) {
|
1154
|
+
for (const [name8, tool] of Object.entries(tools)) {
|
1155
|
+
if ("render" in tool) {
|
1156
|
+
throw new Error(
|
1157
|
+
"Tool definition in `streamUI` should not have `render` property. Use `generate` instead. Found in tool: " + name8
|
1158
|
+
);
|
1159
|
+
}
|
1160
|
+
}
|
1183
1161
|
}
|
1184
|
-
|
1185
|
-
|
1186
|
-
|
1187
|
-
|
1188
|
-
|
1189
|
-
|
1190
|
-
|
1191
|
-
|
1192
|
-
|
1193
|
-
|
1194
|
-
|
1195
|
-
|
1162
|
+
const ui = createStreamableUI(initial);
|
1163
|
+
const textRender = text || defaultTextRenderer;
|
1164
|
+
let finished;
|
1165
|
+
async function render2({
|
1166
|
+
args,
|
1167
|
+
renderer,
|
1168
|
+
streamableUI,
|
1169
|
+
isLastCall = false
|
1170
|
+
}) {
|
1171
|
+
if (!renderer)
|
1172
|
+
return;
|
1173
|
+
const renderFinished = createResolvablePromise();
|
1174
|
+
finished = finished ? finished.then(() => renderFinished.promise) : renderFinished.promise;
|
1175
|
+
const rendererResult = renderer(...args);
|
1176
|
+
if (isAsyncGenerator(rendererResult) || isGenerator(rendererResult)) {
|
1177
|
+
while (true) {
|
1178
|
+
const { done, value } = await rendererResult.next();
|
1179
|
+
const node = await value;
|
1180
|
+
if (isLastCall && done) {
|
1181
|
+
streamableUI.done(node);
|
1182
|
+
} else {
|
1183
|
+
streamableUI.update(node);
|
1184
|
+
}
|
1185
|
+
if (done)
|
1186
|
+
break;
|
1187
|
+
}
|
1188
|
+
} else {
|
1189
|
+
const node = await rendererResult;
|
1190
|
+
if (isLastCall) {
|
1191
|
+
streamableUI.done(node);
|
1192
|
+
} else {
|
1193
|
+
streamableUI.update(node);
|
1194
|
+
}
|
1195
|
+
}
|
1196
|
+
renderFinished.resolve(void 0);
|
1196
1197
|
}
|
1197
|
-
};
|
1198
|
-
|
1198
|
+
const retry = retryWithExponentialBackoff({ maxRetries });
|
1199
|
+
const validatedPrompt = getValidatedPrompt({ system, prompt, messages });
|
1200
|
+
const result = await retry(
|
1201
|
+
async () => model.doStream({
|
1202
|
+
mode: {
|
1203
|
+
type: "regular",
|
1204
|
+
...prepareToolsAndToolChoice({ tools, toolChoice })
|
1205
|
+
},
|
1206
|
+
...prepareCallSettings(settings),
|
1207
|
+
inputFormat: validatedPrompt.type,
|
1208
|
+
prompt: await convertToLanguageModelPrompt({
|
1209
|
+
prompt: validatedPrompt,
|
1210
|
+
modelSupportsImageUrls: model.supportsImageUrls
|
1211
|
+
}),
|
1212
|
+
abortSignal,
|
1213
|
+
headers
|
1214
|
+
})
|
1215
|
+
);
|
1216
|
+
const [stream, forkedStream] = result.stream.tee();
|
1217
|
+
(async () => {
|
1218
|
+
try {
|
1219
|
+
let content = "";
|
1220
|
+
let hasToolCall = false;
|
1221
|
+
const reader = forkedStream.getReader();
|
1222
|
+
while (true) {
|
1223
|
+
const { done, value } = await reader.read();
|
1224
|
+
if (done)
|
1225
|
+
break;
|
1226
|
+
switch (value.type) {
|
1227
|
+
case "text-delta": {
|
1228
|
+
content += value.textDelta;
|
1229
|
+
render2({
|
1230
|
+
renderer: textRender,
|
1231
|
+
args: [{ content, done: false, delta: value.textDelta }],
|
1232
|
+
streamableUI: ui
|
1233
|
+
});
|
1234
|
+
break;
|
1235
|
+
}
|
1236
|
+
case "tool-call-delta": {
|
1237
|
+
hasToolCall = true;
|
1238
|
+
break;
|
1239
|
+
}
|
1240
|
+
case "tool-call": {
|
1241
|
+
const toolName = value.toolName;
|
1242
|
+
if (!tools) {
|
1243
|
+
throw new NoSuchToolError({ toolName });
|
1244
|
+
}
|
1245
|
+
const tool = tools[toolName];
|
1246
|
+
if (!tool) {
|
1247
|
+
throw new NoSuchToolError({
|
1248
|
+
toolName,
|
1249
|
+
availableTools: Object.keys(tools)
|
1250
|
+
});
|
1251
|
+
}
|
1252
|
+
hasToolCall = true;
|
1253
|
+
const parseResult = safeParseJSON({
|
1254
|
+
text: value.args,
|
1255
|
+
schema: tool.parameters
|
1256
|
+
});
|
1257
|
+
if (parseResult.success === false) {
|
1258
|
+
throw new InvalidToolArgumentsError({
|
1259
|
+
toolName,
|
1260
|
+
toolArgs: value.args,
|
1261
|
+
cause: parseResult.error
|
1262
|
+
});
|
1263
|
+
}
|
1264
|
+
render2({
|
1265
|
+
renderer: tool.generate,
|
1266
|
+
args: [
|
1267
|
+
parseResult.value,
|
1268
|
+
{
|
1269
|
+
toolName,
|
1270
|
+
toolCallId: value.toolCallId
|
1271
|
+
}
|
1272
|
+
],
|
1273
|
+
streamableUI: ui,
|
1274
|
+
isLastCall: true
|
1275
|
+
});
|
1276
|
+
break;
|
1277
|
+
}
|
1278
|
+
case "error": {
|
1279
|
+
throw value.error;
|
1280
|
+
}
|
1281
|
+
case "finish": {
|
1282
|
+
onFinish == null ? void 0 : onFinish({
|
1283
|
+
finishReason: value.finishReason,
|
1284
|
+
usage: calculateCompletionTokenUsage(value.usage),
|
1285
|
+
value: ui.value,
|
1286
|
+
warnings: result.warnings,
|
1287
|
+
rawResponse: result.rawResponse
|
1288
|
+
});
|
1289
|
+
}
|
1290
|
+
}
|
1291
|
+
}
|
1292
|
+
if (!hasToolCall) {
|
1293
|
+
render2({
|
1294
|
+
renderer: textRender,
|
1295
|
+
args: [{ content, done: true }],
|
1296
|
+
streamableUI: ui,
|
1297
|
+
isLastCall: true
|
1298
|
+
});
|
1299
|
+
}
|
1300
|
+
await finished;
|
1301
|
+
} catch (error) {
|
1302
|
+
ui.error(error);
|
1303
|
+
}
|
1304
|
+
})();
|
1305
|
+
return {
|
1306
|
+
...result,
|
1307
|
+
stream,
|
1308
|
+
value: ui.value
|
1309
|
+
};
|
1310
|
+
}
|
1199
1311
|
|
1200
|
-
//
|
1201
|
-
import
|
1202
|
-
var name7 = "AI_NoSuchToolError";
|
1203
|
-
var marker7 = `vercel.ai.error.${name7}`;
|
1204
|
-
var symbol7 = Symbol.for(marker7);
|
1205
|
-
var _a7;
|
1206
|
-
var NoSuchToolError = class extends AISDKError7 {
|
1207
|
-
constructor({
|
1208
|
-
toolName,
|
1209
|
-
availableTools = void 0,
|
1210
|
-
message = `Model tried to call unavailable tool '${toolName}'. ${availableTools === void 0 ? "No tools are available." : `Available tools: ${availableTools.join(", ")}.`}`
|
1211
|
-
}) {
|
1212
|
-
super({ name: name7, message });
|
1213
|
-
this[_a7] = true;
|
1214
|
-
this.toolName = toolName;
|
1215
|
-
this.availableTools = availableTools;
|
1216
|
-
}
|
1217
|
-
static isInstance(error) {
|
1218
|
-
return AISDKError7.hasMarker(error, marker7);
|
1219
|
-
}
|
1220
|
-
/**
|
1221
|
-
* @deprecated use `isInstance` instead
|
1222
|
-
*/
|
1223
|
-
static isNoSuchToolError(error) {
|
1224
|
-
return error instanceof Error && error.name === name7 && "toolName" in error && error.toolName != void 0 && typeof error.name === "string";
|
1225
|
-
}
|
1226
|
-
/**
|
1227
|
-
* @deprecated Do not use this method. It will be removed in the next major version.
|
1228
|
-
*/
|
1229
|
-
toJSON() {
|
1230
|
-
return {
|
1231
|
-
name: this.name,
|
1232
|
-
message: this.message,
|
1233
|
-
stack: this.stack,
|
1234
|
-
toolName: this.toolName,
|
1235
|
-
availableTools: this.availableTools
|
1236
|
-
};
|
1237
|
-
}
|
1238
|
-
};
|
1239
|
-
_a7 = symbol7;
|
1312
|
+
// rsc/stream-ui/render.ts
|
1313
|
+
import zodToJsonSchema from "zod-to-json-schema";
|
1240
1314
|
|
1241
1315
|
// streams/ai-stream.ts
|
1242
1316
|
import {
|
@@ -1364,7 +1438,6 @@ function readableFromAsyncIterable(iterable) {
|
|
1364
1438
|
|
1365
1439
|
// streams/stream-data.ts
|
1366
1440
|
import { formatStreamPart } from "@ai-sdk/ui-utils";
|
1367
|
-
var STREAM_DATA_WARNING_TIME_MS = 15 * 1e3;
|
1368
1441
|
function createStreamDataTransformer() {
|
1369
1442
|
const encoder = new TextEncoder();
|
1370
1443
|
const decoder = new TextDecoder();
|
@@ -1708,7 +1781,7 @@ async function consumeStream(stream) {
|
|
1708
1781
|
}
|
1709
1782
|
}
|
1710
1783
|
|
1711
|
-
// rsc/render.ts
|
1784
|
+
// rsc/stream-ui/render.ts
|
1712
1785
|
function render(options) {
|
1713
1786
|
const ui = createStreamableUI(options.initial);
|
1714
1787
|
const text = options.text ? options.text : ({ content }) => content;
|
@@ -1717,7 +1790,7 @@ function render(options) {
|
|
1717
1790
|
return {
|
1718
1791
|
name: name8,
|
1719
1792
|
description,
|
1720
|
-
parameters:
|
1793
|
+
parameters: zodToJsonSchema(parameters)
|
1721
1794
|
};
|
1722
1795
|
}
|
1723
1796
|
) : void 0;
|
@@ -1728,7 +1801,7 @@ function render(options) {
|
|
1728
1801
|
function: {
|
1729
1802
|
name: name8,
|
1730
1803
|
description,
|
1731
|
-
parameters:
|
1804
|
+
parameters: zodToJsonSchema(parameters)
|
1732
1805
|
}
|
1733
1806
|
};
|
1734
1807
|
}
|
@@ -1809,308 +1882,206 @@ function render(options) {
|
|
1809
1882
|
async experimental_onToolCall(toolCallPayload) {
|
1810
1883
|
var _a8, _b;
|
1811
1884
|
hasFunction = true;
|
1812
|
-
for (const tool of toolCallPayload.tools) {
|
1813
|
-
handleRender(
|
1814
|
-
tool.func.arguments,
|
1815
|
-
(_b = (_a8 = options.tools) == null ? void 0 : _a8[tool.func.name]) == null ? void 0 : _b.render,
|
1816
|
-
ui
|
1817
|
-
);
|
1818
|
-
}
|
1819
|
-
}
|
1820
|
-
} : {},
|
1821
|
-
onText(chunk) {
|
1822
|
-
content += chunk;
|
1823
|
-
handleRender({ content, done: false, delta: chunk }, text, ui);
|
1824
|
-
},
|
1825
|
-
async onFinal() {
|
1826
|
-
if (hasFunction) {
|
1827
|
-
await finished;
|
1828
|
-
ui.done();
|
1829
|
-
return;
|
1830
|
-
}
|
1831
|
-
handleRender({ content, done: true }, text, ui);
|
1832
|
-
await finished;
|
1833
|
-
ui.done();
|
1834
|
-
}
|
1835
|
-
}
|
1836
|
-
)
|
1837
|
-
);
|
1838
|
-
})();
|
1839
|
-
return ui.value;
|
1840
|
-
}
|
1841
|
-
|
1842
|
-
// rsc/stream-ui/stream-ui.tsx
|
1843
|
-
import { safeParseJSON } from "@ai-sdk/provider-utils";
|
1844
|
-
|
1845
|
-
// util/is-async-generator.ts
|
1846
|
-
function isAsyncGenerator(value) {
|
1847
|
-
return value != null && typeof value === "object" && Symbol.asyncIterator in value;
|
1848
|
-
}
|
1849
|
-
|
1850
|
-
// util/is-generator.ts
|
1851
|
-
function isGenerator(value) {
|
1852
|
-
return value != null && typeof value === "object" && Symbol.iterator in value;
|
1853
|
-
}
|
1854
|
-
|
1855
|
-
// rsc/stream-ui/stream-ui.tsx
|
1856
|
-
var defaultTextRenderer = ({ content }) => content;
|
1857
|
-
async function streamUI({
|
1858
|
-
model,
|
1859
|
-
tools,
|
1860
|
-
toolChoice,
|
1861
|
-
system,
|
1862
|
-
prompt,
|
1863
|
-
messages,
|
1864
|
-
maxRetries,
|
1865
|
-
abortSignal,
|
1866
|
-
headers,
|
1867
|
-
initial,
|
1868
|
-
text,
|
1869
|
-
onFinish,
|
1870
|
-
...settings
|
1871
|
-
}) {
|
1872
|
-
if (typeof model === "string") {
|
1873
|
-
throw new Error(
|
1874
|
-
"`model` cannot be a string in `streamUI`. Use the actual model instance instead."
|
1875
|
-
);
|
1876
|
-
}
|
1877
|
-
if ("functions" in settings) {
|
1878
|
-
throw new Error(
|
1879
|
-
"`functions` is not supported in `streamUI`, use `tools` instead."
|
1880
|
-
);
|
1881
|
-
}
|
1882
|
-
if ("provider" in settings) {
|
1883
|
-
throw new Error(
|
1884
|
-
"`provider` is no longer needed in `streamUI`. Use `model` instead."
|
1885
|
-
);
|
1886
|
-
}
|
1887
|
-
if (tools) {
|
1888
|
-
for (const [name8, tool] of Object.entries(tools)) {
|
1889
|
-
if ("render" in tool) {
|
1890
|
-
throw new Error(
|
1891
|
-
"Tool definition in `streamUI` should not have `render` property. Use `generate` instead. Found in tool: " + name8
|
1892
|
-
);
|
1893
|
-
}
|
1894
|
-
}
|
1895
|
-
}
|
1896
|
-
const ui = createStreamableUI(initial);
|
1897
|
-
const textRender = text || defaultTextRenderer;
|
1898
|
-
let finished;
|
1899
|
-
async function render2({
|
1900
|
-
args,
|
1901
|
-
renderer,
|
1902
|
-
streamableUI,
|
1903
|
-
isLastCall = false
|
1904
|
-
}) {
|
1905
|
-
if (!renderer)
|
1906
|
-
return;
|
1907
|
-
const renderFinished = createResolvablePromise();
|
1908
|
-
finished = finished ? finished.then(() => renderFinished.promise) : renderFinished.promise;
|
1909
|
-
const rendererResult = renderer(...args);
|
1910
|
-
if (isAsyncGenerator(rendererResult) || isGenerator(rendererResult)) {
|
1911
|
-
while (true) {
|
1912
|
-
const { done, value } = await rendererResult.next();
|
1913
|
-
const node = await value;
|
1914
|
-
if (isLastCall && done) {
|
1915
|
-
streamableUI.done(node);
|
1916
|
-
} else {
|
1917
|
-
streamableUI.update(node);
|
1918
|
-
}
|
1919
|
-
if (done)
|
1920
|
-
break;
|
1921
|
-
}
|
1922
|
-
} else {
|
1923
|
-
const node = await rendererResult;
|
1924
|
-
if (isLastCall) {
|
1925
|
-
streamableUI.done(node);
|
1926
|
-
} else {
|
1927
|
-
streamableUI.update(node);
|
1928
|
-
}
|
1929
|
-
}
|
1930
|
-
renderFinished.resolve(void 0);
|
1931
|
-
}
|
1932
|
-
const retry = retryWithExponentialBackoff({ maxRetries });
|
1933
|
-
const validatedPrompt = getValidatedPrompt({ system, prompt, messages });
|
1934
|
-
const result = await retry(
|
1935
|
-
async () => model.doStream({
|
1936
|
-
mode: {
|
1937
|
-
type: "regular",
|
1938
|
-
...prepareToolsAndToolChoice({ tools, toolChoice })
|
1939
|
-
},
|
1940
|
-
...prepareCallSettings(settings),
|
1941
|
-
inputFormat: validatedPrompt.type,
|
1942
|
-
prompt: await convertToLanguageModelPrompt({
|
1943
|
-
prompt: validatedPrompt,
|
1944
|
-
modelSupportsImageUrls: model.supportsImageUrls
|
1945
|
-
}),
|
1946
|
-
abortSignal,
|
1947
|
-
headers
|
1948
|
-
})
|
1949
|
-
);
|
1950
|
-
const [stream, forkedStream] = result.stream.tee();
|
1951
|
-
(async () => {
|
1952
|
-
try {
|
1953
|
-
let content = "";
|
1954
|
-
let hasToolCall = false;
|
1955
|
-
const reader = forkedStream.getReader();
|
1956
|
-
while (true) {
|
1957
|
-
const { done, value } = await reader.read();
|
1958
|
-
if (done)
|
1959
|
-
break;
|
1960
|
-
switch (value.type) {
|
1961
|
-
case "text-delta": {
|
1962
|
-
content += value.textDelta;
|
1963
|
-
render2({
|
1964
|
-
renderer: textRender,
|
1965
|
-
args: [{ content, done: false, delta: value.textDelta }],
|
1966
|
-
streamableUI: ui
|
1967
|
-
});
|
1968
|
-
break;
|
1969
|
-
}
|
1970
|
-
case "tool-call-delta": {
|
1971
|
-
hasToolCall = true;
|
1972
|
-
break;
|
1973
|
-
}
|
1974
|
-
case "tool-call": {
|
1975
|
-
const toolName = value.toolName;
|
1976
|
-
if (!tools) {
|
1977
|
-
throw new NoSuchToolError({ toolName });
|
1978
|
-
}
|
1979
|
-
const tool = tools[toolName];
|
1980
|
-
if (!tool) {
|
1981
|
-
throw new NoSuchToolError({
|
1982
|
-
toolName,
|
1983
|
-
availableTools: Object.keys(tools)
|
1984
|
-
});
|
1985
|
-
}
|
1986
|
-
hasToolCall = true;
|
1987
|
-
const parseResult = safeParseJSON({
|
1988
|
-
text: value.args,
|
1989
|
-
schema: tool.parameters
|
1990
|
-
});
|
1991
|
-
if (parseResult.success === false) {
|
1992
|
-
throw new InvalidToolArgumentsError({
|
1993
|
-
toolName,
|
1994
|
-
toolArgs: value.args,
|
1995
|
-
cause: parseResult.error
|
1996
|
-
});
|
1997
|
-
}
|
1998
|
-
render2({
|
1999
|
-
renderer: tool.generate,
|
2000
|
-
args: [
|
2001
|
-
parseResult.value,
|
2002
|
-
{
|
2003
|
-
toolName,
|
2004
|
-
toolCallId: value.toolCallId
|
2005
|
-
}
|
2006
|
-
],
|
2007
|
-
streamableUI: ui,
|
2008
|
-
isLastCall: true
|
2009
|
-
});
|
2010
|
-
break;
|
2011
|
-
}
|
2012
|
-
case "error": {
|
2013
|
-
throw value.error;
|
2014
|
-
}
|
2015
|
-
case "finish": {
|
2016
|
-
onFinish == null ? void 0 : onFinish({
|
2017
|
-
finishReason: value.finishReason,
|
2018
|
-
usage: calculateCompletionTokenUsage(value.usage),
|
2019
|
-
value: ui.value,
|
2020
|
-
warnings: result.warnings,
|
2021
|
-
rawResponse: result.rawResponse
|
2022
|
-
});
|
1885
|
+
for (const tool of toolCallPayload.tools) {
|
1886
|
+
handleRender(
|
1887
|
+
tool.func.arguments,
|
1888
|
+
(_b = (_a8 = options.tools) == null ? void 0 : _a8[tool.func.name]) == null ? void 0 : _b.render,
|
1889
|
+
ui
|
1890
|
+
);
|
1891
|
+
}
|
1892
|
+
}
|
1893
|
+
} : {},
|
1894
|
+
onText(chunk) {
|
1895
|
+
content += chunk;
|
1896
|
+
handleRender({ content, done: false, delta: chunk }, text, ui);
|
1897
|
+
},
|
1898
|
+
async onFinal() {
|
1899
|
+
if (hasFunction) {
|
1900
|
+
await finished;
|
1901
|
+
ui.done();
|
1902
|
+
return;
|
1903
|
+
}
|
1904
|
+
handleRender({ content, done: true }, text, ui);
|
1905
|
+
await finished;
|
1906
|
+
ui.done();
|
2023
1907
|
}
|
2024
1908
|
}
|
2025
|
-
|
2026
|
-
|
2027
|
-
render2({
|
2028
|
-
renderer: textRender,
|
2029
|
-
args: [{ content, done: true }],
|
2030
|
-
streamableUI: ui,
|
2031
|
-
isLastCall: true
|
2032
|
-
});
|
2033
|
-
}
|
2034
|
-
await finished;
|
2035
|
-
} catch (error) {
|
2036
|
-
ui.error(error);
|
2037
|
-
}
|
1909
|
+
)
|
1910
|
+
);
|
2038
1911
|
})();
|
2039
|
-
return
|
2040
|
-
...result,
|
2041
|
-
stream,
|
2042
|
-
value: ui.value
|
2043
|
-
};
|
1912
|
+
return ui.value;
|
2044
1913
|
}
|
2045
1914
|
|
2046
|
-
// rsc/
|
2047
|
-
|
2048
|
-
|
2049
|
-
|
2050
|
-
|
2051
|
-
|
2052
|
-
|
2053
|
-
|
2054
|
-
|
2055
|
-
|
2056
|
-
|
2057
|
-
|
2058
|
-
|
2059
|
-
|
2060
|
-
|
2061
|
-
|
2062
|
-
|
2063
|
-
|
1915
|
+
// rsc/streamable-value/streamable-value.ts
|
1916
|
+
var STREAMABLE_VALUE_TYPE = Symbol.for("ui.streamable.value");
|
1917
|
+
|
1918
|
+
// rsc/streamable-value/create-streamable-value.ts
|
1919
|
+
var STREAMABLE_VALUE_INTERNAL_LOCK = Symbol("streamable.value.lock");
|
1920
|
+
function createStreamableValue(initialValue) {
|
1921
|
+
const isReadableStream = initialValue instanceof ReadableStream || typeof initialValue === "object" && initialValue !== null && "getReader" in initialValue && typeof initialValue.getReader === "function" && "locked" in initialValue && typeof initialValue.locked === "boolean";
|
1922
|
+
if (!isReadableStream) {
|
1923
|
+
return createStreamableValueImpl(initialValue);
|
1924
|
+
}
|
1925
|
+
const streamableValue = createStreamableValueImpl();
|
1926
|
+
streamableValue[STREAMABLE_VALUE_INTERNAL_LOCK] = true;
|
1927
|
+
(async () => {
|
1928
|
+
try {
|
1929
|
+
const reader = initialValue.getReader();
|
1930
|
+
while (true) {
|
1931
|
+
const { value, done } = await reader.read();
|
1932
|
+
if (done) {
|
1933
|
+
break;
|
1934
|
+
}
|
1935
|
+
streamableValue[STREAMABLE_VALUE_INTERNAL_LOCK] = false;
|
1936
|
+
if (typeof value === "string") {
|
1937
|
+
streamableValue.append(value);
|
1938
|
+
} else {
|
1939
|
+
streamableValue.update(value);
|
1940
|
+
}
|
1941
|
+
streamableValue[STREAMABLE_VALUE_INTERNAL_LOCK] = true;
|
1942
|
+
}
|
1943
|
+
streamableValue[STREAMABLE_VALUE_INTERNAL_LOCK] = false;
|
1944
|
+
streamableValue.done();
|
1945
|
+
} catch (e) {
|
1946
|
+
streamableValue[STREAMABLE_VALUE_INTERNAL_LOCK] = false;
|
1947
|
+
streamableValue.error(e);
|
2064
1948
|
}
|
2065
|
-
);
|
2066
|
-
|
2067
|
-
function wrapAction(action, options) {
|
2068
|
-
return innerAction.bind(null, { action, options });
|
1949
|
+
})();
|
1950
|
+
return streamableValue;
|
2069
1951
|
}
|
2070
|
-
function
|
2071
|
-
|
2072
|
-
|
2073
|
-
|
2074
|
-
|
2075
|
-
|
2076
|
-
|
2077
|
-
|
2078
|
-
|
2079
|
-
|
2080
|
-
|
2081
|
-
}
|
2082
|
-
|
2083
|
-
const wrappedSyncUIState = onGetUIState ? wrapAction(onGetUIState, {}) : void 0;
|
2084
|
-
const AI = async (props) => {
|
2085
|
-
var _a8, _b;
|
2086
|
-
if ("useState" in React2) {
|
1952
|
+
function createStreamableValueImpl(initialValue) {
|
1953
|
+
let closed = false;
|
1954
|
+
let locked = false;
|
1955
|
+
let resolvable = createResolvablePromise();
|
1956
|
+
let currentValue = initialValue;
|
1957
|
+
let currentError;
|
1958
|
+
let currentPromise = resolvable.promise;
|
1959
|
+
let currentPatchValue;
|
1960
|
+
function assertStream(method) {
|
1961
|
+
if (closed) {
|
1962
|
+
throw new Error(method + ": Value stream is already closed.");
|
1963
|
+
}
|
1964
|
+
if (locked) {
|
2087
1965
|
throw new Error(
|
2088
|
-
"
|
1966
|
+
method + ": Value stream is locked and cannot be updated."
|
2089
1967
|
);
|
2090
1968
|
}
|
2091
|
-
|
2092
|
-
|
2093
|
-
|
2094
|
-
if (
|
2095
|
-
|
2096
|
-
|
2097
|
-
aiStateDelta = newAIStateDelta;
|
2098
|
-
uiState = newUIState;
|
1969
|
+
}
|
1970
|
+
let warningTimeout;
|
1971
|
+
function warnUnclosedStream() {
|
1972
|
+
if (process.env.NODE_ENV === "development") {
|
1973
|
+
if (warningTimeout) {
|
1974
|
+
clearTimeout(warningTimeout);
|
2099
1975
|
}
|
1976
|
+
warningTimeout = setTimeout(() => {
|
1977
|
+
console.warn(
|
1978
|
+
"The streamable value has been slow to update. This may be a bug or a performance issue or you forgot to call `.done()`."
|
1979
|
+
);
|
1980
|
+
}, HANGING_STREAM_WARNING_TIME_MS);
|
2100
1981
|
}
|
2101
|
-
|
2102
|
-
|
2103
|
-
|
2104
|
-
|
2105
|
-
|
2106
|
-
|
2107
|
-
|
2108
|
-
|
2109
|
-
|
1982
|
+
}
|
1983
|
+
warnUnclosedStream();
|
1984
|
+
function createWrapped(initialChunk) {
|
1985
|
+
let init;
|
1986
|
+
if (currentError !== void 0) {
|
1987
|
+
init = { error: currentError };
|
1988
|
+
} else {
|
1989
|
+
if (currentPatchValue && !initialChunk) {
|
1990
|
+
init = { diff: currentPatchValue };
|
1991
|
+
} else {
|
1992
|
+
init = { curr: currentValue };
|
2110
1993
|
}
|
2111
|
-
|
1994
|
+
}
|
1995
|
+
if (currentPromise) {
|
1996
|
+
init.next = currentPromise;
|
1997
|
+
}
|
1998
|
+
if (initialChunk) {
|
1999
|
+
init.type = STREAMABLE_VALUE_TYPE;
|
2000
|
+
}
|
2001
|
+
return init;
|
2002
|
+
}
|
2003
|
+
function updateValueStates(value) {
|
2004
|
+
currentPatchValue = void 0;
|
2005
|
+
if (typeof value === "string") {
|
2006
|
+
if (typeof currentValue === "string") {
|
2007
|
+
if (value.startsWith(currentValue)) {
|
2008
|
+
currentPatchValue = [0, value.slice(currentValue.length)];
|
2009
|
+
}
|
2010
|
+
}
|
2011
|
+
}
|
2012
|
+
currentValue = value;
|
2013
|
+
}
|
2014
|
+
const streamable2 = {
|
2015
|
+
set [STREAMABLE_VALUE_INTERNAL_LOCK](state) {
|
2016
|
+
locked = state;
|
2017
|
+
},
|
2018
|
+
get value() {
|
2019
|
+
return createWrapped(true);
|
2020
|
+
},
|
2021
|
+
update(value) {
|
2022
|
+
assertStream(".update()");
|
2023
|
+
const resolvePrevious = resolvable.resolve;
|
2024
|
+
resolvable = createResolvablePromise();
|
2025
|
+
updateValueStates(value);
|
2026
|
+
currentPromise = resolvable.promise;
|
2027
|
+
resolvePrevious(createWrapped());
|
2028
|
+
warnUnclosedStream();
|
2029
|
+
return streamable2;
|
2030
|
+
},
|
2031
|
+
append(value) {
|
2032
|
+
assertStream(".append()");
|
2033
|
+
if (typeof currentValue !== "string" && typeof currentValue !== "undefined") {
|
2034
|
+
throw new Error(
|
2035
|
+
`.append(): The current value is not a string. Received: ${typeof currentValue}`
|
2036
|
+
);
|
2037
|
+
}
|
2038
|
+
if (typeof value !== "string") {
|
2039
|
+
throw new Error(
|
2040
|
+
`.append(): The value is not a string. Received: ${typeof value}`
|
2041
|
+
);
|
2042
|
+
}
|
2043
|
+
const resolvePrevious = resolvable.resolve;
|
2044
|
+
resolvable = createResolvablePromise();
|
2045
|
+
if (typeof currentValue === "string") {
|
2046
|
+
currentPatchValue = [0, value];
|
2047
|
+
currentValue = currentValue + value;
|
2048
|
+
} else {
|
2049
|
+
currentPatchValue = void 0;
|
2050
|
+
currentValue = value;
|
2051
|
+
}
|
2052
|
+
currentPromise = resolvable.promise;
|
2053
|
+
resolvePrevious(createWrapped());
|
2054
|
+
warnUnclosedStream();
|
2055
|
+
return streamable2;
|
2056
|
+
},
|
2057
|
+
error(error) {
|
2058
|
+
assertStream(".error()");
|
2059
|
+
if (warningTimeout) {
|
2060
|
+
clearTimeout(warningTimeout);
|
2061
|
+
}
|
2062
|
+
closed = true;
|
2063
|
+
currentError = error;
|
2064
|
+
currentPromise = void 0;
|
2065
|
+
resolvable.resolve({ error });
|
2066
|
+
return streamable2;
|
2067
|
+
},
|
2068
|
+
done(...args) {
|
2069
|
+
assertStream(".done()");
|
2070
|
+
if (warningTimeout) {
|
2071
|
+
clearTimeout(warningTimeout);
|
2072
|
+
}
|
2073
|
+
closed = true;
|
2074
|
+
currentPromise = void 0;
|
2075
|
+
if (args.length) {
|
2076
|
+
updateValueStates(args[0]);
|
2077
|
+
resolvable.resolve(createWrapped());
|
2078
|
+
return streamable2;
|
2079
|
+
}
|
2080
|
+
resolvable.resolve({});
|
2081
|
+
return streamable2;
|
2082
|
+
}
|
2112
2083
|
};
|
2113
|
-
return
|
2084
|
+
return streamable2;
|
2114
2085
|
}
|
2115
2086
|
export {
|
2116
2087
|
createAI,
|