ai 3.1.0-canary.4 → 3.1.0
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 +982 -24
- package/dist/index.d.ts +982 -24
- package/dist/index.js +1748 -175
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1723 -174
- package/dist/index.mjs.map +1 -1
- package/package.json +11 -28
- package/prompts/dist/index.d.mts +13 -1
- package/prompts/dist/index.d.ts +13 -1
- package/prompts/dist/index.js +13 -0
- package/prompts/dist/index.js.map +1 -1
- package/prompts/dist/index.mjs +12 -0
- package/prompts/dist/index.mjs.map +1 -1
- package/react/dist/index.d.mts +23 -6
- package/react/dist/index.d.ts +27 -8
- package/react/dist/index.js +154 -141
- package/react/dist/index.js.map +1 -1
- package/react/dist/index.mjs +153 -141
- package/react/dist/index.mjs.map +1 -1
- package/react/dist/index.server.d.mts +4 -2
- package/react/dist/index.server.d.ts +4 -2
- package/react/dist/index.server.js.map +1 -1
- package/react/dist/index.server.mjs.map +1 -1
- package/rsc/dist/index.d.ts +385 -20
- package/rsc/dist/rsc-client.d.mts +1 -1
- package/rsc/dist/rsc-client.mjs +2 -0
- package/rsc/dist/rsc-client.mjs.map +1 -1
- package/rsc/dist/rsc-server.d.mts +367 -20
- package/rsc/dist/rsc-server.mjs +676 -35
- package/rsc/dist/rsc-server.mjs.map +1 -1
- package/rsc/dist/rsc-shared.d.mts +24 -9
- package/rsc/dist/rsc-shared.mjs +98 -4
- package/rsc/dist/rsc-shared.mjs.map +1 -1
- package/solid/dist/index.d.mts +7 -3
- package/solid/dist/index.d.ts +7 -3
- package/solid/dist/index.js +106 -107
- package/solid/dist/index.js.map +1 -1
- package/solid/dist/index.mjs +106 -107
- package/solid/dist/index.mjs.map +1 -1
- package/svelte/dist/index.d.mts +7 -3
- package/svelte/dist/index.d.ts +7 -3
- package/svelte/dist/index.js +109 -109
- package/svelte/dist/index.js.map +1 -1
- package/svelte/dist/index.mjs +109 -109
- package/svelte/dist/index.mjs.map +1 -1
- package/vue/dist/index.d.mts +7 -3
- package/vue/dist/index.d.ts +7 -3
- package/vue/dist/index.js +106 -107
- package/vue/dist/index.js.map +1 -1
- package/vue/dist/index.mjs +106 -107
- package/vue/dist/index.mjs.map +1 -1
- package/ai-model-specification/dist/index.d.mts +0 -665
- package/ai-model-specification/dist/index.d.ts +0 -665
- package/ai-model-specification/dist/index.js +0 -716
- package/ai-model-specification/dist/index.js.map +0 -1
- package/ai-model-specification/dist/index.mjs +0 -656
- package/ai-model-specification/dist/index.mjs.map +0 -1
- package/core/dist/index.d.mts +0 -626
- package/core/dist/index.d.ts +0 -626
- package/core/dist/index.js +0 -1918
- package/core/dist/index.js.map +0 -1
- package/core/dist/index.mjs +0 -1873
- package/core/dist/index.mjs.map +0 -1
- package/openai/dist/index.d.mts +0 -429
- package/openai/dist/index.d.ts +0 -429
- package/openai/dist/index.js +0 -1231
- package/openai/dist/index.js.map +0 -1
- package/openai/dist/index.mjs +0 -1195
- package/openai/dist/index.mjs.map +0 -1
package/rsc/dist/rsc-server.mjs
CHANGED
@@ -175,10 +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
|
+
}
|
179
429
|
|
180
|
-
//
|
181
|
-
import {
|
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
|
+
}
|
182
491
|
|
183
492
|
// shared/stream-parts.ts
|
184
493
|
var textStreamPart = {
|
@@ -280,9 +589,9 @@ var toolCallStreamPart = {
|
|
280
589
|
code: "7",
|
281
590
|
name: "tool_calls",
|
282
591
|
parse: (value) => {
|
283
|
-
if (value == null || typeof value !== "object" || !("tool_calls" in value) || typeof value.tool_calls !== "object" || value.tool_calls == null || !Array.isArray(value.tool_calls) || value.tool_calls.some(
|
284
|
-
tc == null || typeof tc !== "object" || !("id" in tc) || typeof tc.id !== "string" || !("type" in tc) || typeof tc.type !== "string" || !("function" in tc) || tc.function == null || typeof tc.function !== "object" || !("arguments" in tc.function) || typeof tc.function.name !== "string" || typeof tc.function.arguments !== "string"
|
285
|
-
|
592
|
+
if (value == null || typeof value !== "object" || !("tool_calls" in value) || typeof value.tool_calls !== "object" || value.tool_calls == null || !Array.isArray(value.tool_calls) || value.tool_calls.some(
|
593
|
+
(tc) => tc == null || typeof tc !== "object" || !("id" in tc) || typeof tc.id !== "string" || !("type" in tc) || typeof tc.type !== "string" || !("function" in tc) || tc.function == null || typeof tc.function !== "object" || !("arguments" in tc.function) || typeof tc.function.name !== "string" || typeof tc.function.arguments !== "string"
|
594
|
+
)) {
|
286
595
|
throw new Error(
|
287
596
|
'"tool_calls" parts expect an object with a ToolCallPayload.'
|
288
597
|
);
|
@@ -361,10 +670,6 @@ function formatStreamPart(type, value) {
|
|
361
670
|
}
|
362
671
|
|
363
672
|
// shared/utils.ts
|
364
|
-
var nanoid = customAlphabet(
|
365
|
-
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
|
366
|
-
7
|
367
|
-
);
|
368
673
|
function createChunkDecoder(complex) {
|
369
674
|
const decoder = new TextDecoder();
|
370
675
|
if (!complex) {
|
@@ -505,14 +810,7 @@ function readableFromAsyncIterable(iterable) {
|
|
505
810
|
}
|
506
811
|
|
507
812
|
// streams/stream-data.ts
|
508
|
-
function createStreamDataTransformer(
|
509
|
-
if (!experimental_streamData) {
|
510
|
-
return new TransformStream({
|
511
|
-
transform: async (chunk, controller) => {
|
512
|
-
controller.enqueue(chunk);
|
513
|
-
}
|
514
|
-
});
|
515
|
-
}
|
813
|
+
function createStreamDataTransformer() {
|
516
814
|
const encoder = new TextEncoder();
|
517
815
|
const decoder = new TextDecoder();
|
518
816
|
return new TransformStream({
|
@@ -664,9 +962,7 @@ function OpenAIStream(res, callbacks) {
|
|
664
962
|
const functionCallTransformer = createFunctionCallTransformer(cb);
|
665
963
|
return stream.pipeThrough(functionCallTransformer);
|
666
964
|
} else {
|
667
|
-
return stream.pipeThrough(
|
668
|
-
createStreamDataTransformer(cb == null ? void 0 : cb.experimental_streamData)
|
669
|
-
);
|
965
|
+
return stream.pipeThrough(createStreamDataTransformer());
|
670
966
|
}
|
671
967
|
}
|
672
968
|
function createFunctionCallTransformer(callbacks) {
|
@@ -676,7 +972,6 @@ function createFunctionCallTransformer(callbacks) {
|
|
676
972
|
let aggregatedFinalCompletionResponse = "";
|
677
973
|
let isFunctionStreamingIn = false;
|
678
974
|
let functionCallMessages = callbacks[__internal__OpenAIFnMessagesSymbol] || [];
|
679
|
-
const isComplexMode = callbacks == null ? void 0 : callbacks.experimental_streamData;
|
680
975
|
const decode = createChunkDecoder();
|
681
976
|
return new TransformStream({
|
682
977
|
async transform(chunk, controller) {
|
@@ -691,7 +986,7 @@ function createFunctionCallTransformer(callbacks) {
|
|
691
986
|
}
|
692
987
|
if (!isFunctionStreamingIn) {
|
693
988
|
controller.enqueue(
|
694
|
-
|
989
|
+
textEncoder.encode(formatStreamPart("text", message))
|
695
990
|
);
|
696
991
|
return;
|
697
992
|
} else {
|
@@ -802,17 +1097,17 @@ function createFunctionCallTransformer(callbacks) {
|
|
802
1097
|
if (!functionResponse) {
|
803
1098
|
controller.enqueue(
|
804
1099
|
textEncoder.encode(
|
805
|
-
|
1100
|
+
formatStreamPart(
|
806
1101
|
payload.function_call ? "function_call" : "tool_calls",
|
807
1102
|
// parse to prevent double-encoding:
|
808
1103
|
JSON.parse(aggregatedResponse)
|
809
|
-
)
|
1104
|
+
)
|
810
1105
|
)
|
811
1106
|
);
|
812
1107
|
return;
|
813
1108
|
} else if (typeof functionResponse === "string") {
|
814
1109
|
controller.enqueue(
|
815
|
-
|
1110
|
+
textEncoder.encode(formatStreamPart("text", functionResponse))
|
816
1111
|
);
|
817
1112
|
aggregatedFinalCompletionResponse = functionResponse;
|
818
1113
|
return;
|
@@ -873,7 +1168,13 @@ function createStreamableUI(initialValue) {
|
|
873
1168
|
}
|
874
1169
|
warnUnclosedStream();
|
875
1170
|
return {
|
1171
|
+
/**
|
1172
|
+
* The value of the streamable UI. This can be returned from a Server Action and received by the client.
|
1173
|
+
*/
|
876
1174
|
value: row,
|
1175
|
+
/**
|
1176
|
+
* This method updates the current UI node. It takes a new UI node and replaces the old one.
|
1177
|
+
*/
|
877
1178
|
update(value) {
|
878
1179
|
assertStream(".update()");
|
879
1180
|
if (value === currentValue) {
|
@@ -887,6 +1188,22 @@ function createStreamableUI(initialValue) {
|
|
887
1188
|
reject = resolvable.reject;
|
888
1189
|
warnUnclosedStream();
|
889
1190
|
},
|
1191
|
+
/**
|
1192
|
+
* This method is used to append a new UI node to the end of the old one.
|
1193
|
+
* Once appended a new UI node, the previous UI node cannot be updated anymore.
|
1194
|
+
*
|
1195
|
+
* @example
|
1196
|
+
* ```jsx
|
1197
|
+
* const ui = createStreamableUI(<div>hello</div>)
|
1198
|
+
* ui.append(<div>world</div>)
|
1199
|
+
*
|
1200
|
+
* // The UI node will be:
|
1201
|
+
* // <>
|
1202
|
+
* // <div>hello</div>
|
1203
|
+
* // <div>world</div>
|
1204
|
+
* // </>
|
1205
|
+
* ```
|
1206
|
+
*/
|
890
1207
|
append(value) {
|
891
1208
|
assertStream(".append()");
|
892
1209
|
const resolvable = createResolvablePromise();
|
@@ -896,6 +1213,10 @@ function createStreamableUI(initialValue) {
|
|
896
1213
|
reject = resolvable.reject;
|
897
1214
|
warnUnclosedStream();
|
898
1215
|
},
|
1216
|
+
/**
|
1217
|
+
* This method is used to signal that there is an error in the UI stream.
|
1218
|
+
* It will be thrown on the client side and caught by the nearest error boundary component.
|
1219
|
+
*/
|
899
1220
|
error(error) {
|
900
1221
|
assertStream(".error()");
|
901
1222
|
if (warningTimeout) {
|
@@ -904,6 +1225,12 @@ function createStreamableUI(initialValue) {
|
|
904
1225
|
closed = true;
|
905
1226
|
reject(error);
|
906
1227
|
},
|
1228
|
+
/**
|
1229
|
+
* This method marks the UI node as finalized. You can either call it without any parameters or with a new UI node as the final state.
|
1230
|
+
* Once called, the UI node cannot be updated or appended anymore.
|
1231
|
+
*
|
1232
|
+
* This method is always **required** to be called, otherwise the response will be stuck in a loading state.
|
1233
|
+
*/
|
907
1234
|
done(...args) {
|
908
1235
|
assertStream(".done()");
|
909
1236
|
if (warningTimeout) {
|
@@ -918,16 +1245,56 @@ function createStreamableUI(initialValue) {
|
|
918
1245
|
}
|
919
1246
|
};
|
920
1247
|
}
|
1248
|
+
var STREAMABLE_VALUE_INTERNAL_LOCK = Symbol("streamable.value.lock");
|
921
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) {
|
922
1282
|
let closed = false;
|
1283
|
+
let locked = false;
|
923
1284
|
let resolvable = createResolvablePromise();
|
924
1285
|
let currentValue = initialValue;
|
925
1286
|
let currentError;
|
926
1287
|
let currentPromise = resolvable.promise;
|
1288
|
+
let currentPatchValue;
|
927
1289
|
function assertStream(method) {
|
928
1290
|
if (closed) {
|
929
1291
|
throw new Error(method + ": Value stream is already closed.");
|
930
1292
|
}
|
1293
|
+
if (locked) {
|
1294
|
+
throw new Error(
|
1295
|
+
method + ": Value stream is locked and cannot be updated."
|
1296
|
+
);
|
1297
|
+
}
|
931
1298
|
}
|
932
1299
|
let warningTimeout;
|
933
1300
|
function warnUnclosedStream() {
|
@@ -943,29 +1310,106 @@ function createStreamableValue(initialValue) {
|
|
943
1310
|
}
|
944
1311
|
}
|
945
1312
|
warnUnclosedStream();
|
946
|
-
function createWrapped(
|
947
|
-
|
1313
|
+
function createWrapped(initialChunk) {
|
1314
|
+
let init;
|
1315
|
+
if (currentError !== void 0) {
|
1316
|
+
init = { error: currentError };
|
1317
|
+
} else {
|
1318
|
+
if (currentPatchValue && !initialChunk) {
|
1319
|
+
init = { diff: currentPatchValue };
|
1320
|
+
} else {
|
1321
|
+
init = { curr: currentValue };
|
1322
|
+
}
|
1323
|
+
}
|
948
1324
|
if (currentPromise) {
|
949
1325
|
init.next = currentPromise;
|
950
1326
|
}
|
951
|
-
if (
|
1327
|
+
if (initialChunk) {
|
952
1328
|
init.type = STREAMABLE_VALUE_TYPE;
|
953
1329
|
}
|
954
1330
|
return init;
|
955
1331
|
}
|
1332
|
+
function updateValueStates(value) {
|
1333
|
+
currentPatchValue = void 0;
|
1334
|
+
if (typeof value === "string") {
|
1335
|
+
if (typeof currentValue === "string") {
|
1336
|
+
if (value.startsWith(currentValue)) {
|
1337
|
+
currentPatchValue = [0, value.slice(currentValue.length)];
|
1338
|
+
}
|
1339
|
+
}
|
1340
|
+
}
|
1341
|
+
currentValue = value;
|
1342
|
+
}
|
956
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
|
+
},
|
1351
|
+
/**
|
1352
|
+
* The value of the streamable. This can be returned from a Server Action and
|
1353
|
+
* received by the client. To read the streamed values, use the
|
1354
|
+
* `readStreamableValue` or `useStreamableValue` APIs.
|
1355
|
+
*/
|
957
1356
|
get value() {
|
958
1357
|
return createWrapped(true);
|
959
1358
|
},
|
1359
|
+
/**
|
1360
|
+
* This method updates the current value with a new one.
|
1361
|
+
*/
|
960
1362
|
update(value) {
|
961
1363
|
assertStream(".update()");
|
962
1364
|
const resolvePrevious = resolvable.resolve;
|
963
1365
|
resolvable = createResolvablePromise();
|
964
|
-
|
1366
|
+
updateValueStates(value);
|
965
1367
|
currentPromise = resolvable.promise;
|
966
1368
|
resolvePrevious(createWrapped());
|
967
1369
|
warnUnclosedStream();
|
968
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
|
+
*/
|
969
1413
|
error(error) {
|
970
1414
|
assertStream(".error()");
|
971
1415
|
if (warningTimeout) {
|
@@ -976,6 +1420,14 @@ function createStreamableValue(initialValue) {
|
|
976
1420
|
currentPromise = void 0;
|
977
1421
|
resolvable.resolve({ error });
|
978
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
|
+
*/
|
979
1431
|
done(...args) {
|
980
1432
|
assertStream(".done()");
|
981
1433
|
if (warningTimeout) {
|
@@ -984,8 +1436,8 @@ function createStreamableValue(initialValue) {
|
|
984
1436
|
closed = true;
|
985
1437
|
currentPromise = void 0;
|
986
1438
|
if (args.length) {
|
987
|
-
|
988
|
-
resolvable.resolve(
|
1439
|
+
updateValueStates(args[0]);
|
1440
|
+
resolvable.resolve(createWrapped());
|
989
1441
|
return;
|
990
1442
|
}
|
991
1443
|
resolvable.resolve({});
|
@@ -1000,7 +1452,7 @@ function render(options) {
|
|
1000
1452
|
return {
|
1001
1453
|
name,
|
1002
1454
|
description,
|
1003
|
-
parameters:
|
1455
|
+
parameters: zodToJsonSchema2(parameters)
|
1004
1456
|
};
|
1005
1457
|
}
|
1006
1458
|
) : void 0;
|
@@ -1011,7 +1463,7 @@ function render(options) {
|
|
1011
1463
|
function: {
|
1012
1464
|
name,
|
1013
1465
|
description,
|
1014
|
-
parameters:
|
1466
|
+
parameters: zodToJsonSchema2(parameters)
|
1015
1467
|
}
|
1016
1468
|
};
|
1017
1469
|
}
|
@@ -1122,6 +1574,194 @@ function render(options) {
|
|
1122
1574
|
return ui.value;
|
1123
1575
|
}
|
1124
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
|
+
|
1125
1765
|
// rsc/provider.tsx
|
1126
1766
|
import * as React2 from "react";
|
1127
1767
|
import { InternalAIProvider } from "./rsc-shared.mjs";
|
@@ -1150,8 +1790,8 @@ function createAI({
|
|
1150
1790
|
actions,
|
1151
1791
|
initialAIState,
|
1152
1792
|
initialUIState,
|
1153
|
-
|
1154
|
-
|
1793
|
+
onSetAIState,
|
1794
|
+
onGetUIState
|
1155
1795
|
}) {
|
1156
1796
|
const wrappedActions = {};
|
1157
1797
|
for (const name in actions) {
|
@@ -1195,6 +1835,7 @@ export {
|
|
1195
1835
|
createAI,
|
1196
1836
|
createStreamableUI,
|
1197
1837
|
createStreamableValue,
|
1838
|
+
experimental_streamUI,
|
1198
1839
|
getAIState,
|
1199
1840
|
getMutableAIState,
|
1200
1841
|
render
|