ai 3.0.33 → 3.0.35
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 +53 -26
- package/dist/index.d.ts +53 -26
- package/dist/index.js +38 -3
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +40 -6
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
- package/rsc/dist/index.d.ts +287 -9
- package/rsc/dist/rsc-server.d.mts +287 -9
- package/rsc/dist/rsc-server.mjs +599 -2
- package/rsc/dist/rsc-server.mjs.map +1 -1
package/rsc/dist/rsc-server.mjs
CHANGED
@@ -175,7 +175,319 @@ function getMutableAIState(...args) {
|
|
175
175
|
}
|
176
176
|
|
177
177
|
// rsc/streamable.tsx
|
178
|
+
import zodToJsonSchema2 from "zod-to-json-schema";
|
179
|
+
|
180
|
+
// core/util/detect-image-mimetype.ts
|
181
|
+
var mimeTypeSignatures = [
|
182
|
+
{ mimeType: "image/gif", bytes: [71, 73, 70] },
|
183
|
+
{ mimeType: "image/png", bytes: [137, 80, 78, 71] },
|
184
|
+
{ mimeType: "image/jpeg", bytes: [255, 216] },
|
185
|
+
{ mimeType: "image/webp", bytes: [82, 73, 70, 70] }
|
186
|
+
];
|
187
|
+
function detectImageMimeType(image) {
|
188
|
+
for (const { bytes, mimeType } of mimeTypeSignatures) {
|
189
|
+
if (image.length >= bytes.length && bytes.every((byte, index) => image[index] === byte)) {
|
190
|
+
return mimeType;
|
191
|
+
}
|
192
|
+
}
|
193
|
+
return void 0;
|
194
|
+
}
|
195
|
+
|
196
|
+
// core/prompt/data-content.ts
|
197
|
+
import { InvalidDataContentError } from "@ai-sdk/provider";
|
198
|
+
import {
|
199
|
+
convertBase64ToUint8Array,
|
200
|
+
convertUint8ArrayToBase64
|
201
|
+
} from "@ai-sdk/provider-utils";
|
202
|
+
function convertDataContentToUint8Array(content) {
|
203
|
+
if (content instanceof Uint8Array) {
|
204
|
+
return content;
|
205
|
+
}
|
206
|
+
if (typeof content === "string") {
|
207
|
+
return convertBase64ToUint8Array(content);
|
208
|
+
}
|
209
|
+
if (content instanceof ArrayBuffer) {
|
210
|
+
return new Uint8Array(content);
|
211
|
+
}
|
212
|
+
throw new InvalidDataContentError({ content });
|
213
|
+
}
|
214
|
+
|
215
|
+
// core/prompt/convert-to-language-model-prompt.ts
|
216
|
+
function convertToLanguageModelPrompt(prompt) {
|
217
|
+
const languageModelMessages = [];
|
218
|
+
if (prompt.system != null) {
|
219
|
+
languageModelMessages.push({ role: "system", content: prompt.system });
|
220
|
+
}
|
221
|
+
switch (prompt.type) {
|
222
|
+
case "prompt": {
|
223
|
+
languageModelMessages.push({
|
224
|
+
role: "user",
|
225
|
+
content: [{ type: "text", text: prompt.prompt }]
|
226
|
+
});
|
227
|
+
break;
|
228
|
+
}
|
229
|
+
case "messages": {
|
230
|
+
languageModelMessages.push(
|
231
|
+
...prompt.messages.map((message) => {
|
232
|
+
switch (message.role) {
|
233
|
+
case "user": {
|
234
|
+
if (typeof message.content === "string") {
|
235
|
+
return {
|
236
|
+
role: "user",
|
237
|
+
content: [{ type: "text", text: message.content }]
|
238
|
+
};
|
239
|
+
}
|
240
|
+
return {
|
241
|
+
role: "user",
|
242
|
+
content: message.content.map(
|
243
|
+
(part) => {
|
244
|
+
var _a;
|
245
|
+
switch (part.type) {
|
246
|
+
case "text": {
|
247
|
+
return part;
|
248
|
+
}
|
249
|
+
case "image": {
|
250
|
+
if (part.image instanceof URL) {
|
251
|
+
return {
|
252
|
+
type: "image",
|
253
|
+
image: part.image,
|
254
|
+
mimeType: part.mimeType
|
255
|
+
};
|
256
|
+
}
|
257
|
+
const imageUint8 = convertDataContentToUint8Array(
|
258
|
+
part.image
|
259
|
+
);
|
260
|
+
return {
|
261
|
+
type: "image",
|
262
|
+
image: imageUint8,
|
263
|
+
mimeType: (_a = part.mimeType) != null ? _a : detectImageMimeType(imageUint8)
|
264
|
+
};
|
265
|
+
}
|
266
|
+
}
|
267
|
+
}
|
268
|
+
)
|
269
|
+
};
|
270
|
+
}
|
271
|
+
case "assistant": {
|
272
|
+
if (typeof message.content === "string") {
|
273
|
+
return {
|
274
|
+
role: "assistant",
|
275
|
+
content: [{ type: "text", text: message.content }]
|
276
|
+
};
|
277
|
+
}
|
278
|
+
return { role: "assistant", content: message.content };
|
279
|
+
}
|
280
|
+
case "tool": {
|
281
|
+
return message;
|
282
|
+
}
|
283
|
+
}
|
284
|
+
})
|
285
|
+
);
|
286
|
+
break;
|
287
|
+
}
|
288
|
+
default: {
|
289
|
+
const _exhaustiveCheck = prompt;
|
290
|
+
throw new Error(`Unsupported prompt type: ${_exhaustiveCheck}`);
|
291
|
+
}
|
292
|
+
}
|
293
|
+
return languageModelMessages;
|
294
|
+
}
|
295
|
+
|
296
|
+
// core/prompt/get-validated-prompt.ts
|
297
|
+
import { InvalidPromptError } from "@ai-sdk/provider";
|
298
|
+
function getValidatedPrompt(prompt) {
|
299
|
+
if (prompt.prompt == null && prompt.messages == null) {
|
300
|
+
throw new InvalidPromptError({
|
301
|
+
prompt,
|
302
|
+
message: "prompt or messages must be defined"
|
303
|
+
});
|
304
|
+
}
|
305
|
+
if (prompt.prompt != null && prompt.messages != null) {
|
306
|
+
throw new InvalidPromptError({
|
307
|
+
prompt,
|
308
|
+
message: "prompt and messages cannot be defined at the same time"
|
309
|
+
});
|
310
|
+
}
|
311
|
+
return prompt.prompt != null ? {
|
312
|
+
type: "prompt",
|
313
|
+
prompt: prompt.prompt,
|
314
|
+
messages: void 0,
|
315
|
+
system: prompt.system
|
316
|
+
} : {
|
317
|
+
type: "messages",
|
318
|
+
prompt: void 0,
|
319
|
+
messages: prompt.messages,
|
320
|
+
// only possible case bc of checks above
|
321
|
+
system: prompt.system
|
322
|
+
};
|
323
|
+
}
|
324
|
+
|
325
|
+
// core/prompt/prepare-call-settings.ts
|
326
|
+
import { InvalidArgumentError } from "@ai-sdk/provider";
|
327
|
+
function prepareCallSettings({
|
328
|
+
maxTokens,
|
329
|
+
temperature,
|
330
|
+
topP,
|
331
|
+
presencePenalty,
|
332
|
+
frequencyPenalty,
|
333
|
+
seed,
|
334
|
+
maxRetries
|
335
|
+
}) {
|
336
|
+
if (maxTokens != null) {
|
337
|
+
if (!Number.isInteger(maxTokens)) {
|
338
|
+
throw new InvalidArgumentError({
|
339
|
+
parameter: "maxTokens",
|
340
|
+
value: maxTokens,
|
341
|
+
message: "maxTokens must be an integer"
|
342
|
+
});
|
343
|
+
}
|
344
|
+
if (maxTokens < 1) {
|
345
|
+
throw new InvalidArgumentError({
|
346
|
+
parameter: "maxTokens",
|
347
|
+
value: maxTokens,
|
348
|
+
message: "maxTokens must be >= 1"
|
349
|
+
});
|
350
|
+
}
|
351
|
+
}
|
352
|
+
if (temperature != null) {
|
353
|
+
if (typeof temperature !== "number") {
|
354
|
+
throw new InvalidArgumentError({
|
355
|
+
parameter: "temperature",
|
356
|
+
value: temperature,
|
357
|
+
message: "temperature must be a number"
|
358
|
+
});
|
359
|
+
}
|
360
|
+
}
|
361
|
+
if (topP != null) {
|
362
|
+
if (typeof topP !== "number") {
|
363
|
+
throw new InvalidArgumentError({
|
364
|
+
parameter: "topP",
|
365
|
+
value: topP,
|
366
|
+
message: "topP must be a number"
|
367
|
+
});
|
368
|
+
}
|
369
|
+
}
|
370
|
+
if (presencePenalty != null) {
|
371
|
+
if (typeof presencePenalty !== "number") {
|
372
|
+
throw new InvalidArgumentError({
|
373
|
+
parameter: "presencePenalty",
|
374
|
+
value: presencePenalty,
|
375
|
+
message: "presencePenalty must be a number"
|
376
|
+
});
|
377
|
+
}
|
378
|
+
}
|
379
|
+
if (frequencyPenalty != null) {
|
380
|
+
if (typeof frequencyPenalty !== "number") {
|
381
|
+
throw new InvalidArgumentError({
|
382
|
+
parameter: "frequencyPenalty",
|
383
|
+
value: frequencyPenalty,
|
384
|
+
message: "frequencyPenalty must be a number"
|
385
|
+
});
|
386
|
+
}
|
387
|
+
}
|
388
|
+
if (seed != null) {
|
389
|
+
if (!Number.isInteger(seed)) {
|
390
|
+
throw new InvalidArgumentError({
|
391
|
+
parameter: "seed",
|
392
|
+
value: seed,
|
393
|
+
message: "seed must be an integer"
|
394
|
+
});
|
395
|
+
}
|
396
|
+
}
|
397
|
+
if (maxRetries != null) {
|
398
|
+
if (!Number.isInteger(maxRetries)) {
|
399
|
+
throw new InvalidArgumentError({
|
400
|
+
parameter: "maxRetries",
|
401
|
+
value: maxRetries,
|
402
|
+
message: "maxRetries must be an integer"
|
403
|
+
});
|
404
|
+
}
|
405
|
+
if (maxRetries < 0) {
|
406
|
+
throw new InvalidArgumentError({
|
407
|
+
parameter: "maxRetries",
|
408
|
+
value: maxRetries,
|
409
|
+
message: "maxRetries must be >= 0"
|
410
|
+
});
|
411
|
+
}
|
412
|
+
}
|
413
|
+
return {
|
414
|
+
maxTokens,
|
415
|
+
temperature: temperature != null ? temperature : 0,
|
416
|
+
topP,
|
417
|
+
presencePenalty,
|
418
|
+
frequencyPenalty,
|
419
|
+
seed,
|
420
|
+
maxRetries: maxRetries != null ? maxRetries : 2
|
421
|
+
};
|
422
|
+
}
|
423
|
+
|
424
|
+
// core/util/convert-zod-to-json-schema.ts
|
178
425
|
import zodToJsonSchema from "zod-to-json-schema";
|
426
|
+
function convertZodToJSONSchema(zodSchema) {
|
427
|
+
return zodToJsonSchema(zodSchema);
|
428
|
+
}
|
429
|
+
|
430
|
+
// core/util/retry-with-exponential-backoff.ts
|
431
|
+
import { APICallError, RetryError } from "@ai-sdk/provider";
|
432
|
+
import { getErrorMessage, isAbortError } from "@ai-sdk/provider-utils";
|
433
|
+
|
434
|
+
// core/util/delay.ts
|
435
|
+
async function delay(delayInMs) {
|
436
|
+
return new Promise((resolve) => setTimeout(resolve, delayInMs));
|
437
|
+
}
|
438
|
+
|
439
|
+
// core/util/retry-with-exponential-backoff.ts
|
440
|
+
var retryWithExponentialBackoff = ({
|
441
|
+
maxRetries = 2,
|
442
|
+
initialDelayInMs = 2e3,
|
443
|
+
backoffFactor = 2
|
444
|
+
} = {}) => async (f) => _retryWithExponentialBackoff(f, {
|
445
|
+
maxRetries,
|
446
|
+
delayInMs: initialDelayInMs,
|
447
|
+
backoffFactor
|
448
|
+
});
|
449
|
+
async function _retryWithExponentialBackoff(f, {
|
450
|
+
maxRetries,
|
451
|
+
delayInMs,
|
452
|
+
backoffFactor
|
453
|
+
}, errors = []) {
|
454
|
+
try {
|
455
|
+
return await f();
|
456
|
+
} catch (error) {
|
457
|
+
if (isAbortError(error)) {
|
458
|
+
throw error;
|
459
|
+
}
|
460
|
+
if (maxRetries === 0) {
|
461
|
+
throw error;
|
462
|
+
}
|
463
|
+
const errorMessage = getErrorMessage(error);
|
464
|
+
const newErrors = [...errors, error];
|
465
|
+
const tryNumber = newErrors.length;
|
466
|
+
if (tryNumber > maxRetries) {
|
467
|
+
throw new RetryError({
|
468
|
+
message: `Failed after ${tryNumber} attempts. Last error: ${errorMessage}`,
|
469
|
+
reason: "maxRetriesExceeded",
|
470
|
+
errors: newErrors
|
471
|
+
});
|
472
|
+
}
|
473
|
+
if (error instanceof Error && APICallError.isAPICallError(error) && error.isRetryable === true && tryNumber <= maxRetries) {
|
474
|
+
await delay(delayInMs);
|
475
|
+
return _retryWithExponentialBackoff(
|
476
|
+
f,
|
477
|
+
{ maxRetries, delayInMs: backoffFactor * delayInMs, backoffFactor },
|
478
|
+
newErrors
|
479
|
+
);
|
480
|
+
}
|
481
|
+
if (tryNumber === 1) {
|
482
|
+
throw error;
|
483
|
+
}
|
484
|
+
throw new RetryError({
|
485
|
+
message: `Failed after ${tryNumber} attempts with non-retryable error: '${errorMessage}'`,
|
486
|
+
reason: "errorNotRetryable",
|
487
|
+
errors: newErrors
|
488
|
+
});
|
489
|
+
}
|
490
|
+
}
|
179
491
|
|
180
492
|
// shared/stream-parts.ts
|
181
493
|
var textStreamPart = {
|
@@ -933,8 +1245,42 @@ function createStreamableUI(initialValue) {
|
|
933
1245
|
}
|
934
1246
|
};
|
935
1247
|
}
|
1248
|
+
var STREAMABLE_VALUE_INTERNAL_LOCK = Symbol("streamable.value.lock");
|
936
1249
|
function createStreamableValue(initialValue) {
|
1250
|
+
const isReadableStream = initialValue instanceof ReadableStream || typeof initialValue === "object" && initialValue !== null && "getReader" in initialValue && typeof initialValue.getReader === "function" && "locked" in initialValue && typeof initialValue.locked === "boolean";
|
1251
|
+
if (!isReadableStream) {
|
1252
|
+
return createStreamableValueImpl(initialValue);
|
1253
|
+
}
|
1254
|
+
const streamableValue = createStreamableValueImpl();
|
1255
|
+
streamableValue[STREAMABLE_VALUE_INTERNAL_LOCK] = true;
|
1256
|
+
(async () => {
|
1257
|
+
try {
|
1258
|
+
const reader = initialValue.getReader();
|
1259
|
+
while (true) {
|
1260
|
+
const { value, done } = await reader.read();
|
1261
|
+
if (done) {
|
1262
|
+
break;
|
1263
|
+
}
|
1264
|
+
streamableValue[STREAMABLE_VALUE_INTERNAL_LOCK] = false;
|
1265
|
+
if (typeof value === "string") {
|
1266
|
+
streamableValue.append(value);
|
1267
|
+
} else {
|
1268
|
+
streamableValue.update(value);
|
1269
|
+
}
|
1270
|
+
streamableValue[STREAMABLE_VALUE_INTERNAL_LOCK] = true;
|
1271
|
+
}
|
1272
|
+
streamableValue[STREAMABLE_VALUE_INTERNAL_LOCK] = false;
|
1273
|
+
streamableValue.done();
|
1274
|
+
} catch (e) {
|
1275
|
+
streamableValue[STREAMABLE_VALUE_INTERNAL_LOCK] = false;
|
1276
|
+
streamableValue.error(e);
|
1277
|
+
}
|
1278
|
+
})();
|
1279
|
+
return streamableValue;
|
1280
|
+
}
|
1281
|
+
function createStreamableValueImpl(initialValue) {
|
937
1282
|
let closed = false;
|
1283
|
+
let locked = false;
|
938
1284
|
let resolvable = createResolvablePromise();
|
939
1285
|
let currentValue = initialValue;
|
940
1286
|
let currentError;
|
@@ -944,6 +1290,11 @@ function createStreamableValue(initialValue) {
|
|
944
1290
|
if (closed) {
|
945
1291
|
throw new Error(method + ": Value stream is already closed.");
|
946
1292
|
}
|
1293
|
+
if (locked) {
|
1294
|
+
throw new Error(
|
1295
|
+
method + ": Value stream is locked and cannot be updated."
|
1296
|
+
);
|
1297
|
+
}
|
947
1298
|
}
|
948
1299
|
let warningTimeout;
|
949
1300
|
function warnUnclosedStream() {
|
@@ -990,6 +1341,13 @@ function createStreamableValue(initialValue) {
|
|
990
1341
|
currentValue = value;
|
991
1342
|
}
|
992
1343
|
return {
|
1344
|
+
/**
|
1345
|
+
* @internal This is an internal lock to prevent the value from being
|
1346
|
+
* updated by the user.
|
1347
|
+
*/
|
1348
|
+
set [STREAMABLE_VALUE_INTERNAL_LOCK](state) {
|
1349
|
+
locked = state;
|
1350
|
+
},
|
993
1351
|
/**
|
994
1352
|
* The value of the streamable. This can be returned from a Server Action and
|
995
1353
|
* received by the client. To read the streamed values, use the
|
@@ -1010,6 +1368,48 @@ function createStreamableValue(initialValue) {
|
|
1010
1368
|
resolvePrevious(createWrapped());
|
1011
1369
|
warnUnclosedStream();
|
1012
1370
|
},
|
1371
|
+
/**
|
1372
|
+
* This method is used to append a delta string to the current value. It
|
1373
|
+
* requires the current value of the streamable to be a string.
|
1374
|
+
*
|
1375
|
+
* @example
|
1376
|
+
* ```jsx
|
1377
|
+
* const streamable = createStreamableValue('hello');
|
1378
|
+
* streamable.append(' world');
|
1379
|
+
*
|
1380
|
+
* // The value will be 'hello world'
|
1381
|
+
* ```
|
1382
|
+
*/
|
1383
|
+
append(value) {
|
1384
|
+
assertStream(".append()");
|
1385
|
+
if (typeof currentValue !== "string" && typeof currentValue !== "undefined") {
|
1386
|
+
throw new Error(
|
1387
|
+
`.append(): The current value is not a string. Received: ${typeof currentValue}`
|
1388
|
+
);
|
1389
|
+
}
|
1390
|
+
if (typeof value !== "string") {
|
1391
|
+
throw new Error(
|
1392
|
+
`.append(): The value is not a string. Received: ${typeof value}`
|
1393
|
+
);
|
1394
|
+
}
|
1395
|
+
const resolvePrevious = resolvable.resolve;
|
1396
|
+
resolvable = createResolvablePromise();
|
1397
|
+
if (typeof currentValue === "string") {
|
1398
|
+
currentPatchValue = [0, value];
|
1399
|
+
currentValue = currentValue + value;
|
1400
|
+
} else {
|
1401
|
+
currentPatchValue = void 0;
|
1402
|
+
currentValue = value;
|
1403
|
+
}
|
1404
|
+
currentPromise = resolvable.promise;
|
1405
|
+
resolvePrevious(createWrapped());
|
1406
|
+
warnUnclosedStream();
|
1407
|
+
},
|
1408
|
+
/**
|
1409
|
+
* This method is used to signal that there is an error in the value stream.
|
1410
|
+
* It will be thrown on the client side when consumed via
|
1411
|
+
* `readStreamableValue` or `useStreamableValue`.
|
1412
|
+
*/
|
1013
1413
|
error(error) {
|
1014
1414
|
assertStream(".error()");
|
1015
1415
|
if (warningTimeout) {
|
@@ -1020,6 +1420,14 @@ function createStreamableValue(initialValue) {
|
|
1020
1420
|
currentPromise = void 0;
|
1021
1421
|
resolvable.resolve({ error });
|
1022
1422
|
},
|
1423
|
+
/**
|
1424
|
+
* This method marks the value as finalized. You can either call it without
|
1425
|
+
* any parameters or with a new value as the final state.
|
1426
|
+
* Once called, the value cannot be updated or appended anymore.
|
1427
|
+
*
|
1428
|
+
* This method is always **required** to be called, otherwise the response
|
1429
|
+
* will be stuck in a loading state.
|
1430
|
+
*/
|
1023
1431
|
done(...args) {
|
1024
1432
|
assertStream(".done()");
|
1025
1433
|
if (warningTimeout) {
|
@@ -1044,7 +1452,7 @@ function render(options) {
|
|
1044
1452
|
return {
|
1045
1453
|
name,
|
1046
1454
|
description,
|
1047
|
-
parameters:
|
1455
|
+
parameters: zodToJsonSchema2(parameters)
|
1048
1456
|
};
|
1049
1457
|
}
|
1050
1458
|
) : void 0;
|
@@ -1055,7 +1463,7 @@ function render(options) {
|
|
1055
1463
|
function: {
|
1056
1464
|
name,
|
1057
1465
|
description,
|
1058
|
-
parameters:
|
1466
|
+
parameters: zodToJsonSchema2(parameters)
|
1059
1467
|
}
|
1060
1468
|
};
|
1061
1469
|
}
|
@@ -1166,6 +1574,194 @@ function render(options) {
|
|
1166
1574
|
return ui.value;
|
1167
1575
|
}
|
1168
1576
|
|
1577
|
+
// rsc/stream-ui/stream-ui.tsx
|
1578
|
+
import {
|
1579
|
+
InvalidToolArgumentsError,
|
1580
|
+
NoSuchToolError
|
1581
|
+
} from "@ai-sdk/provider";
|
1582
|
+
import { safeParseJSON } from "@ai-sdk/provider-utils";
|
1583
|
+
var defaultTextRenderer = ({ content }) => content;
|
1584
|
+
async function experimental_streamUI({
|
1585
|
+
model,
|
1586
|
+
tools,
|
1587
|
+
system,
|
1588
|
+
prompt,
|
1589
|
+
messages,
|
1590
|
+
maxRetries,
|
1591
|
+
abortSignal,
|
1592
|
+
initial,
|
1593
|
+
text,
|
1594
|
+
...settings
|
1595
|
+
}) {
|
1596
|
+
if (typeof model === "string") {
|
1597
|
+
throw new Error(
|
1598
|
+
"`model` cannot be a string in `experimental_streamUI`. Use the actual model instance instead."
|
1599
|
+
);
|
1600
|
+
}
|
1601
|
+
if ("functions" in settings) {
|
1602
|
+
throw new Error(
|
1603
|
+
"`functions` is not supported in `experimental_streamUI`, use `tools` instead."
|
1604
|
+
);
|
1605
|
+
}
|
1606
|
+
if ("provider" in settings) {
|
1607
|
+
throw new Error(
|
1608
|
+
"`provider` is no longer needed in `experimental_streamUI`. Use `model` instead."
|
1609
|
+
);
|
1610
|
+
}
|
1611
|
+
if (tools) {
|
1612
|
+
for (const [name, tool] of Object.entries(tools)) {
|
1613
|
+
if ("render" in tool) {
|
1614
|
+
throw new Error(
|
1615
|
+
"Tool definition in `experimental_streamUI` should not have `render` property. Use `generate` instead. Found in tool: " + name
|
1616
|
+
);
|
1617
|
+
}
|
1618
|
+
}
|
1619
|
+
}
|
1620
|
+
const ui = createStreamableUI(initial);
|
1621
|
+
const textRender = text || defaultTextRenderer;
|
1622
|
+
let finished;
|
1623
|
+
async function handleRender(args, renderer, res) {
|
1624
|
+
if (!renderer)
|
1625
|
+
return;
|
1626
|
+
const resolvable = createResolvablePromise();
|
1627
|
+
if (finished) {
|
1628
|
+
finished = finished.then(() => resolvable.promise);
|
1629
|
+
} else {
|
1630
|
+
finished = resolvable.promise;
|
1631
|
+
}
|
1632
|
+
const value = renderer(...args);
|
1633
|
+
if (value instanceof Promise || value && typeof value === "object" && "then" in value && typeof value.then === "function") {
|
1634
|
+
const node = await value;
|
1635
|
+
res.update(node);
|
1636
|
+
resolvable.resolve(void 0);
|
1637
|
+
} else if (value && typeof value === "object" && Symbol.asyncIterator in value) {
|
1638
|
+
const it = value;
|
1639
|
+
while (true) {
|
1640
|
+
const { done, value: value2 } = await it.next();
|
1641
|
+
res.update(value2);
|
1642
|
+
if (done)
|
1643
|
+
break;
|
1644
|
+
}
|
1645
|
+
resolvable.resolve(void 0);
|
1646
|
+
} else if (value && typeof value === "object" && Symbol.iterator in value) {
|
1647
|
+
const it = value;
|
1648
|
+
while (true) {
|
1649
|
+
const { done, value: value2 } = it.next();
|
1650
|
+
res.update(value2);
|
1651
|
+
if (done)
|
1652
|
+
break;
|
1653
|
+
}
|
1654
|
+
resolvable.resolve(void 0);
|
1655
|
+
} else {
|
1656
|
+
res.update(value);
|
1657
|
+
resolvable.resolve(void 0);
|
1658
|
+
}
|
1659
|
+
}
|
1660
|
+
const retry = retryWithExponentialBackoff({ maxRetries });
|
1661
|
+
const validatedPrompt = getValidatedPrompt({ system, prompt, messages });
|
1662
|
+
const result = await retry(
|
1663
|
+
() => model.doStream({
|
1664
|
+
mode: {
|
1665
|
+
type: "regular",
|
1666
|
+
tools: tools == null ? void 0 : Object.entries(tools).map(([name, tool]) => ({
|
1667
|
+
type: "function",
|
1668
|
+
name,
|
1669
|
+
description: tool.description,
|
1670
|
+
parameters: convertZodToJSONSchema(tool.parameters)
|
1671
|
+
}))
|
1672
|
+
},
|
1673
|
+
...prepareCallSettings(settings),
|
1674
|
+
inputFormat: validatedPrompt.type,
|
1675
|
+
prompt: convertToLanguageModelPrompt(validatedPrompt),
|
1676
|
+
abortSignal
|
1677
|
+
})
|
1678
|
+
);
|
1679
|
+
const [stream, forkedStream] = result.stream.tee();
|
1680
|
+
(async () => {
|
1681
|
+
try {
|
1682
|
+
let content = "";
|
1683
|
+
let hasToolCall = false;
|
1684
|
+
const reader = forkedStream.getReader();
|
1685
|
+
while (true) {
|
1686
|
+
const { done, value } = await reader.read();
|
1687
|
+
if (done)
|
1688
|
+
break;
|
1689
|
+
switch (value.type) {
|
1690
|
+
case "text-delta": {
|
1691
|
+
content += value.textDelta;
|
1692
|
+
handleRender(
|
1693
|
+
[{ content, done: false, delta: value.textDelta }],
|
1694
|
+
textRender,
|
1695
|
+
ui
|
1696
|
+
);
|
1697
|
+
break;
|
1698
|
+
}
|
1699
|
+
case "tool-call-delta": {
|
1700
|
+
hasToolCall = true;
|
1701
|
+
break;
|
1702
|
+
}
|
1703
|
+
case "tool-call": {
|
1704
|
+
const toolName = value.toolName;
|
1705
|
+
if (!tools) {
|
1706
|
+
throw new NoSuchToolError({ toolName });
|
1707
|
+
}
|
1708
|
+
const tool = tools[toolName];
|
1709
|
+
if (!tool) {
|
1710
|
+
throw new NoSuchToolError({
|
1711
|
+
toolName,
|
1712
|
+
availableTools: Object.keys(tools)
|
1713
|
+
});
|
1714
|
+
}
|
1715
|
+
const parseResult = safeParseJSON({
|
1716
|
+
text: value.args,
|
1717
|
+
schema: tool.parameters
|
1718
|
+
});
|
1719
|
+
if (parseResult.success === false) {
|
1720
|
+
throw new InvalidToolArgumentsError({
|
1721
|
+
toolName,
|
1722
|
+
toolArgs: value.args,
|
1723
|
+
cause: parseResult.error
|
1724
|
+
});
|
1725
|
+
}
|
1726
|
+
handleRender(
|
1727
|
+
[
|
1728
|
+
parseResult.value,
|
1729
|
+
{
|
1730
|
+
toolName,
|
1731
|
+
toolCallId: value.toolCallId
|
1732
|
+
}
|
1733
|
+
],
|
1734
|
+
tool.generate,
|
1735
|
+
ui
|
1736
|
+
);
|
1737
|
+
break;
|
1738
|
+
}
|
1739
|
+
case "error": {
|
1740
|
+
throw value.error;
|
1741
|
+
}
|
1742
|
+
case "finish": {
|
1743
|
+
}
|
1744
|
+
}
|
1745
|
+
}
|
1746
|
+
if (hasToolCall) {
|
1747
|
+
await finished;
|
1748
|
+
ui.done();
|
1749
|
+
} else {
|
1750
|
+
handleRender([{ content, done: true }], textRender, ui);
|
1751
|
+
await finished;
|
1752
|
+
ui.done();
|
1753
|
+
}
|
1754
|
+
} catch (error) {
|
1755
|
+
ui.error(error);
|
1756
|
+
}
|
1757
|
+
})();
|
1758
|
+
return {
|
1759
|
+
...result,
|
1760
|
+
stream,
|
1761
|
+
value: ui.value
|
1762
|
+
};
|
1763
|
+
}
|
1764
|
+
|
1169
1765
|
// rsc/provider.tsx
|
1170
1766
|
import * as React2 from "react";
|
1171
1767
|
import { InternalAIProvider } from "./rsc-shared.mjs";
|
@@ -1239,6 +1835,7 @@ export {
|
|
1239
1835
|
createAI,
|
1240
1836
|
createStreamableUI,
|
1241
1837
|
createStreamableValue,
|
1838
|
+
experimental_streamUI,
|
1242
1839
|
getAIState,
|
1243
1840
|
getMutableAIState,
|
1244
1841
|
render
|