ai 3.1.0-canary.2 → 3.1.0-canary.4

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.
@@ -1,10 +1,52 @@
1
1
  // core/generate-object/generate-object.ts
2
2
  import zodToJsonSchema from "zod-to-json-schema";
3
3
 
4
- // ai-model-specification/errors/ai-invalid-argument-error.ts
5
- var AI_InvalidArgumentError = class extends Error {
6
- // readonly learnMore =
7
- // 'https://sdk.vercel.com/docs/ai/errors/ai_invalid_argument_error';
4
+ // ai-model-specification/errors/api-call-error.ts
5
+ var APICallError = class extends Error {
6
+ constructor({
7
+ message,
8
+ url,
9
+ requestBodyValues,
10
+ statusCode,
11
+ responseBody,
12
+ cause,
13
+ isRetryable = statusCode != null && (statusCode === 408 || // request timeout
14
+ statusCode === 409 || // conflict
15
+ statusCode === 429 || // too many requests
16
+ statusCode >= 500),
17
+ // server error
18
+ data
19
+ }) {
20
+ super(message);
21
+ this.name = "AI_APICallError";
22
+ this.url = url;
23
+ this.requestBodyValues = requestBodyValues;
24
+ this.statusCode = statusCode;
25
+ this.responseBody = responseBody;
26
+ this.cause = cause;
27
+ this.isRetryable = isRetryable;
28
+ this.data = data;
29
+ }
30
+ static isAPICallError(error) {
31
+ return error instanceof Error && error.name === "AI_APICallError" && typeof error.url === "string" && typeof error.requestBodyValues === "object" && (error.statusCode == null || typeof error.statusCode === "number") && (error.responseBody == null || typeof error.responseBody === "string") && (error.cause == null || typeof error.cause === "object") && typeof error.isRetryable === "boolean" && (error.data == null || typeof error.data === "object");
32
+ }
33
+ toJSON() {
34
+ return {
35
+ name: this.name,
36
+ message: this.message,
37
+ url: this.url,
38
+ requestBodyValues: this.requestBodyValues,
39
+ statusCode: this.statusCode,
40
+ responseBody: this.responseBody,
41
+ cause: this.cause,
42
+ isRetryable: this.isRetryable,
43
+ data: this.data
44
+ };
45
+ }
46
+ };
47
+
48
+ // ai-model-specification/errors/invalid-argument-error.ts
49
+ var InvalidArgumentError = class extends Error {
8
50
  constructor({
9
51
  parameter,
10
52
  value,
@@ -15,6 +57,9 @@ var AI_InvalidArgumentError = class extends Error {
15
57
  this.parameter = parameter;
16
58
  this.value = value;
17
59
  }
60
+ static isInvalidArgumentError(error) {
61
+ return error instanceof Error && error.name === "AI_InvalidArgumentError" && typeof error.parameter === "string" && typeof error.value === "string";
62
+ }
18
63
  toJSON() {
19
64
  return {
20
65
  name: this.name,
@@ -40,6 +85,9 @@ function getErrorMessage(error) {
40
85
  return JSON.stringify(error);
41
86
  }
42
87
 
88
+ // ai-model-specification/util/parse-json.ts
89
+ import SecureJSON from "secure-json-parse";
90
+
43
91
  // ai-model-specification/errors/json-parse-error.ts
44
92
  var JSONParseError = class extends Error {
45
93
  constructor({ text, cause }) {
@@ -47,10 +95,13 @@ var JSONParseError = class extends Error {
47
95
  `JSON parsing failed: Text: ${text}.
48
96
  Error message: ${getErrorMessage(cause)}`
49
97
  );
50
- this.name = "JSONParseError";
98
+ this.name = "AI_JSONParseError";
51
99
  this.cause = cause;
52
100
  this.text = text;
53
101
  }
102
+ static isJSONParseError(error) {
103
+ return error instanceof Error && error.name === "AI_JSONParseError" && typeof error.text === "string" && typeof error.cause === "string";
104
+ }
54
105
  toJSON() {
55
106
  return {
56
107
  name: this.name,
@@ -62,22 +113,6 @@ Error message: ${getErrorMessage(cause)}`
62
113
  }
63
114
  };
64
115
 
65
- // ai-model-specification/errors/no-object-generated-error.ts
66
- var NoTextGeneratedError = class extends Error {
67
- constructor() {
68
- super(`No text generated.`);
69
- this.name = "NoTextGeneratedError";
70
- }
71
- toJSON() {
72
- return {
73
- name: this.name,
74
- cause: this.cause,
75
- message: this.message,
76
- stack: this.stack
77
- };
78
- }
79
- };
80
-
81
116
  // ai-model-specification/errors/type-validation-error.ts
82
117
  var TypeValidationError = class extends Error {
83
118
  constructor({ value, cause }) {
@@ -85,10 +120,13 @@ var TypeValidationError = class extends Error {
85
120
  `Type validation failed: Value: ${JSON.stringify(value)}.
86
121
  Error message: ${getErrorMessage(cause)}`
87
122
  );
88
- this.name = "TypeValidationError";
123
+ this.name = "AI_TypeValidationError";
89
124
  this.cause = cause;
90
125
  this.value = value;
91
126
  }
127
+ static isTypeValidationError(error) {
128
+ return error instanceof Error && error.name === "AI_TypeValidationError" && typeof error.value === "string" && typeof error.cause === "string";
129
+ }
92
130
  toJSON() {
93
131
  return {
94
132
  name: this.name,
@@ -100,9 +138,6 @@ Error message: ${getErrorMessage(cause)}`
100
138
  }
101
139
  };
102
140
 
103
- // ai-model-specification/util/parse-json.ts
104
- import SecureJSON from "secure-json-parse";
105
-
106
141
  // ai-model-specification/util/validate-types.ts
107
142
  function safeValidateTypes({
108
143
  value,
@@ -126,7 +161,7 @@ function safeValidateTypes({
126
161
  } catch (error) {
127
162
  return {
128
163
  success: false,
129
- error: error instanceof TypeValidationError ? error : new TypeValidationError({ value, cause: error })
164
+ error: TypeValidationError.isTypeValidationError(error) ? error : new TypeValidationError({ value, cause: error })
130
165
  };
131
166
  }
132
167
  }
@@ -148,7 +183,7 @@ function safeParseJSON({
148
183
  } catch (error) {
149
184
  return {
150
185
  success: false,
151
- error: error instanceof JSONParseError ? error : new JSONParseError({ text, cause: error })
186
+ error: JSONParseError.isJSONParseError(error) ? error : new JSONParseError({ text, cause: error })
152
187
  };
153
188
  }
154
189
  }
@@ -167,6 +202,112 @@ function convertUint8ArrayToBase64(array) {
167
202
  return globalThis.btoa(latin1string);
168
203
  }
169
204
 
205
+ // ai-model-specification/errors/invalid-tool-arguments-error.ts
206
+ var InvalidToolArgumentsError = class extends Error {
207
+ constructor({
208
+ toolArgs,
209
+ toolName,
210
+ cause,
211
+ message = `Invalid arguments for tool ${toolName}: ${getErrorMessage(
212
+ cause
213
+ )}`
214
+ }) {
215
+ super(message);
216
+ this.name = "AI_InvalidToolArgumentsError";
217
+ this.toolArgs = toolArgs;
218
+ this.toolName = toolName;
219
+ this.cause = cause;
220
+ }
221
+ static isInvalidToolArgumentsError(error) {
222
+ return error instanceof Error && error.name === "AI_InvalidToolArgumentsError" && typeof error.toolName === "string" && typeof error.toolArgs === "string";
223
+ }
224
+ toJSON() {
225
+ return {
226
+ name: this.name,
227
+ message: this.message,
228
+ cause: this.cause,
229
+ stack: this.stack,
230
+ toolName: this.toolName,
231
+ toolArgs: this.toolArgs
232
+ };
233
+ }
234
+ };
235
+
236
+ // ai-model-specification/errors/no-object-generated-error.ts
237
+ var NoTextGeneratedError = class extends Error {
238
+ constructor() {
239
+ super(`No text generated.`);
240
+ this.name = "AI_NoTextGeneratedError";
241
+ }
242
+ static isNoTextGeneratedError(error) {
243
+ return error instanceof Error && error.name === "AI_NoTextGeneratedError";
244
+ }
245
+ toJSON() {
246
+ return {
247
+ name: this.name,
248
+ cause: this.cause,
249
+ message: this.message,
250
+ stack: this.stack
251
+ };
252
+ }
253
+ };
254
+
255
+ // ai-model-specification/errors/no-such-tool-error.ts
256
+ var NoSuchToolError = class extends Error {
257
+ constructor({ message, toolName }) {
258
+ super(message);
259
+ this.name = "AI_NoSuchToolError";
260
+ this.toolName = toolName;
261
+ }
262
+ static isNoSuchToolError(error) {
263
+ return error instanceof Error && error.name === "AI_NoSuchToolError" && typeof error.toolName === "string";
264
+ }
265
+ toJSON() {
266
+ return {
267
+ name: this.name,
268
+ message: this.message,
269
+ stack: this.stack,
270
+ toolName: this.toolName
271
+ };
272
+ }
273
+ };
274
+
275
+ // ai-model-specification/errors/retry-error.ts
276
+ var RetryError = class extends Error {
277
+ constructor({
278
+ message,
279
+ reason,
280
+ errors
281
+ }) {
282
+ super(message);
283
+ this.name = "AI_RetryError";
284
+ this.reason = reason;
285
+ this.errors = errors;
286
+ this.lastError = errors[errors.length - 1];
287
+ }
288
+ static isRetryError(error) {
289
+ return error instanceof Error && error.name === "AI_RetryError" && typeof error.reason === "string" && Array.isArray(error.errors);
290
+ }
291
+ toJSON() {
292
+ return {
293
+ name: this.name,
294
+ message: this.message,
295
+ reason: this.reason,
296
+ lastError: this.lastError,
297
+ errors: this.errors
298
+ };
299
+ }
300
+ };
301
+
302
+ // core/generate-text/token-usage.ts
303
+ function calculateTokenUsage(usage) {
304
+ return {
305
+ promptTokens: usage.promptTokens,
306
+ completionTokens: usage.completionTokens,
307
+ totalTokens: usage.promptTokens + usage.completionTokens
308
+ };
309
+ }
310
+
170
311
  // core/prompt/data-content.ts
171
312
  function convertDataContentToBase64String(content) {
172
313
  if (typeof content === "string") {
@@ -236,7 +377,7 @@ function convertToLanguageModelPrompt({
236
377
  case "image": {
237
378
  return {
238
379
  type: "image",
239
- image: convertDataContentToUint8Array(part.image),
380
+ image: part.image instanceof URL ? part.image : convertDataContentToUint8Array(part.image),
240
381
  mimeType: part.mimeType
241
382
  };
242
383
  }
@@ -278,98 +419,193 @@ function getInputFormat({
278
419
  return prompt != null ? "prompt" : "messages";
279
420
  }
280
421
 
281
- // core/prompt/validate-call-settings.ts
282
- function validateCallSettings(settings) {
283
- if (settings.maxTokens != null) {
284
- if (!Number.isInteger(settings.maxTokens)) {
285
- throw new AI_InvalidArgumentError({
422
+ // core/prompt/prepare-call-settings.ts
423
+ function prepareCallSettings({
424
+ maxTokens,
425
+ temperature,
426
+ topP,
427
+ presencePenalty,
428
+ frequencyPenalty,
429
+ seed,
430
+ maxRetries
431
+ }) {
432
+ if (maxTokens != null) {
433
+ if (!Number.isInteger(maxTokens)) {
434
+ throw new InvalidArgumentError({
286
435
  parameter: "maxTokens",
287
- value: settings.maxTokens,
436
+ value: maxTokens,
288
437
  message: "maxTokens must be an integer"
289
438
  });
290
439
  }
291
- if (settings.maxTokens < 1) {
292
- throw new AI_InvalidArgumentError({
440
+ if (maxTokens < 1) {
441
+ throw new InvalidArgumentError({
293
442
  parameter: "maxTokens",
294
- value: settings.maxTokens,
443
+ value: maxTokens,
295
444
  message: "maxTokens must be >= 1"
296
445
  });
297
446
  }
298
447
  }
299
- if (settings.temperature != null) {
300
- if (typeof settings.temperature !== "number") {
301
- throw new AI_InvalidArgumentError({
448
+ if (temperature != null) {
449
+ if (typeof temperature !== "number") {
450
+ throw new InvalidArgumentError({
302
451
  parameter: "temperature",
303
- value: settings.temperature,
452
+ value: temperature,
304
453
  message: "temperature must be a number"
305
454
  });
306
455
  }
307
- if (settings.temperature < 0 || settings.temperature > 1) {
308
- throw new AI_InvalidArgumentError({
456
+ if (temperature < 0 || temperature > 1) {
457
+ throw new InvalidArgumentError({
309
458
  parameter: "temperature",
310
- value: settings.temperature,
459
+ value: temperature,
311
460
  message: "temperature must be between 0 and 1 (inclusive)"
312
461
  });
313
462
  }
314
463
  }
315
- if (settings.topP != null) {
316
- if (typeof settings.topP !== "number") {
317
- throw new AI_InvalidArgumentError({
464
+ if (topP != null) {
465
+ if (typeof topP !== "number") {
466
+ throw new InvalidArgumentError({
318
467
  parameter: "topP",
319
- value: settings.topP,
468
+ value: topP,
320
469
  message: "topP must be a number"
321
470
  });
322
471
  }
323
- if (settings.topP < 0 || settings.topP > 1) {
324
- throw new AI_InvalidArgumentError({
472
+ if (topP < 0 || topP > 1) {
473
+ throw new InvalidArgumentError({
325
474
  parameter: "topP",
326
- value: settings.topP,
475
+ value: topP,
327
476
  message: "topP must be between 0 and 1 (inclusive)"
328
477
  });
329
478
  }
330
479
  }
331
- if (settings.presencePenalty != null) {
332
- if (typeof settings.presencePenalty !== "number") {
333
- throw new AI_InvalidArgumentError({
480
+ if (presencePenalty != null) {
481
+ if (typeof presencePenalty !== "number") {
482
+ throw new InvalidArgumentError({
334
483
  parameter: "presencePenalty",
335
- value: settings.presencePenalty,
484
+ value: presencePenalty,
336
485
  message: "presencePenalty must be a number"
337
486
  });
338
487
  }
339
- if (settings.presencePenalty < -1 || settings.presencePenalty > 1) {
340
- throw new AI_InvalidArgumentError({
488
+ if (presencePenalty < -1 || presencePenalty > 1) {
489
+ throw new InvalidArgumentError({
341
490
  parameter: "presencePenalty",
342
- value: settings.presencePenalty,
491
+ value: presencePenalty,
343
492
  message: "presencePenalty must be between -1 and 1 (inclusive)"
344
493
  });
345
494
  }
346
495
  }
347
- if (settings.frequencyPenalty != null) {
348
- if (typeof settings.frequencyPenalty !== "number") {
349
- throw new AI_InvalidArgumentError({
496
+ if (frequencyPenalty != null) {
497
+ if (typeof frequencyPenalty !== "number") {
498
+ throw new InvalidArgumentError({
350
499
  parameter: "frequencyPenalty",
351
- value: settings.frequencyPenalty,
500
+ value: frequencyPenalty,
352
501
  message: "frequencyPenalty must be a number"
353
502
  });
354
503
  }
355
- if (settings.frequencyPenalty < -1 || settings.frequencyPenalty > 1) {
356
- throw new AI_InvalidArgumentError({
504
+ if (frequencyPenalty < -1 || frequencyPenalty > 1) {
505
+ throw new InvalidArgumentError({
357
506
  parameter: "frequencyPenalty",
358
- value: settings.frequencyPenalty,
507
+ value: frequencyPenalty,
359
508
  message: "frequencyPenalty must be between -1 and 1 (inclusive)"
360
509
  });
361
510
  }
362
511
  }
363
- if (settings.seed != null) {
364
- if (!Number.isInteger(settings.seed)) {
365
- throw new AI_InvalidArgumentError({
512
+ if (seed != null) {
513
+ if (!Number.isInteger(seed)) {
514
+ throw new InvalidArgumentError({
366
515
  parameter: "seed",
367
- value: settings.seed,
516
+ value: seed,
368
517
  message: "seed must be an integer"
369
518
  });
370
519
  }
371
520
  }
372
- return settings;
521
+ if (maxRetries != null) {
522
+ if (!Number.isInteger(maxRetries)) {
523
+ throw new InvalidArgumentError({
524
+ parameter: "maxRetries",
525
+ value: maxRetries,
526
+ message: "maxRetries must be an integer"
527
+ });
528
+ }
529
+ if (maxRetries < 0) {
530
+ throw new InvalidArgumentError({
531
+ parameter: "maxRetries",
532
+ value: maxRetries,
533
+ message: "maxRetries must be >= 0"
534
+ });
535
+ }
536
+ }
537
+ return {
538
+ maxTokens,
539
+ temperature: temperature != null ? temperature : 0,
540
+ topP,
541
+ presencePenalty: presencePenalty != null ? presencePenalty : 0,
542
+ frequencyPenalty: frequencyPenalty != null ? frequencyPenalty : 0,
543
+ seed,
544
+ maxRetries: maxRetries != null ? maxRetries : 2
545
+ };
546
+ }
547
+
548
+ // core/util/delay.ts
549
+ async function delay(delayInMs) {
550
+ return new Promise((resolve) => setTimeout(resolve, delayInMs));
551
+ }
552
+
553
+ // core/util/retry-with-exponential-backoff.ts
554
+ var retryWithExponentialBackoff = ({
555
+ maxRetries = 2,
556
+ initialDelayInMs = 2e3,
557
+ backoffFactor = 2
558
+ } = {}) => async (f) => _retryWithExponentialBackoff(f, {
559
+ maxRetries,
560
+ delayInMs: initialDelayInMs,
561
+ backoffFactor
562
+ });
563
+ async function _retryWithExponentialBackoff(f, {
564
+ maxRetries,
565
+ delayInMs,
566
+ backoffFactor
567
+ }, errors = []) {
568
+ try {
569
+ return await f();
570
+ } catch (error) {
571
+ if (maxRetries === 0) {
572
+ throw error;
573
+ }
574
+ const errorMessage = getErrorMessage(error);
575
+ const newErrors = [...errors, error];
576
+ const tryNumber = newErrors.length;
577
+ if (tryNumber > maxRetries) {
578
+ throw new RetryError({
579
+ message: `Failed after ${tryNumber} attemps. Last error: ${errorMessage}`,
580
+ reason: "maxRetriesExceeded",
581
+ errors: newErrors
582
+ });
583
+ }
584
+ if (error instanceof Error) {
585
+ if (error.name === "AbortError") {
586
+ throw error;
587
+ }
588
+ if (
589
+ // deal with bundling duplication by using names
590
+ APICallError.isAPICallError(error) && error.isRetryable === true && tryNumber <= maxRetries
591
+ ) {
592
+ await delay(delayInMs);
593
+ return _retryWithExponentialBackoff(
594
+ f,
595
+ { maxRetries, delayInMs: backoffFactor * delayInMs, backoffFactor },
596
+ newErrors
597
+ );
598
+ }
599
+ }
600
+ if (tryNumber === 1) {
601
+ throw error;
602
+ }
603
+ throw new RetryError({
604
+ message: `Failed after ${tryNumber} attemps with non-retryable error: '${errorMessage}'`,
605
+ reason: "errorNotRetryable",
606
+ errors: newErrors
607
+ });
608
+ }
373
609
  }
374
610
 
375
611
  // core/generate-object/inject-json-schema-into-system.ts
@@ -399,69 +635,89 @@ async function generateObject({
399
635
  system,
400
636
  prompt,
401
637
  messages,
638
+ maxRetries,
639
+ abortSignal,
402
640
  ...settings
403
641
  }) {
404
642
  var _a, _b;
643
+ const retry = retryWithExponentialBackoff({ maxRetries });
405
644
  const jsonSchema = zodToJsonSchema(schema);
406
645
  if (mode === "auto" || mode == null) {
407
646
  mode = model.defaultObjectGenerationMode;
408
647
  }
409
648
  let result;
649
+ let finishReason;
650
+ let usage;
410
651
  switch (mode) {
411
652
  case "json": {
412
- const generateResult = await model.doGenerate({
413
- mode: { type: "object-json" },
414
- ...validateCallSettings(settings),
415
- inputFormat: getInputFormat({ prompt, messages }),
416
- prompt: convertToLanguageModelPrompt({
417
- system: injectJsonSchemaIntoSystem({ system, schema: jsonSchema }),
418
- prompt,
419
- messages
653
+ const generateResult = await retry(
654
+ () => model.doGenerate({
655
+ mode: { type: "object-json" },
656
+ ...prepareCallSettings(settings),
657
+ inputFormat: getInputFormat({ prompt, messages }),
658
+ prompt: convertToLanguageModelPrompt({
659
+ system: injectJsonSchemaIntoSystem({ system, schema: jsonSchema }),
660
+ prompt,
661
+ messages
662
+ }),
663
+ abortSignal
420
664
  })
421
- });
665
+ );
422
666
  if (generateResult.text === void 0) {
423
667
  throw new NoTextGeneratedError();
424
668
  }
425
669
  result = generateResult.text;
670
+ finishReason = generateResult.finishReason;
671
+ usage = generateResult.usage;
426
672
  break;
427
673
  }
428
674
  case "grammar": {
429
- const generateResult = await model.doGenerate({
430
- mode: { type: "object-grammar", schema: jsonSchema },
431
- ...settings,
432
- inputFormat: getInputFormat({ prompt, messages }),
433
- prompt: convertToLanguageModelPrompt({
434
- system: injectJsonSchemaIntoSystem({ system, schema: jsonSchema }),
435
- prompt,
436
- messages
675
+ const generateResult = await retry(
676
+ () => model.doGenerate({
677
+ mode: { type: "object-grammar", schema: jsonSchema },
678
+ ...settings,
679
+ inputFormat: getInputFormat({ prompt, messages }),
680
+ prompt: convertToLanguageModelPrompt({
681
+ system: injectJsonSchemaIntoSystem({ system, schema: jsonSchema }),
682
+ prompt,
683
+ messages
684
+ }),
685
+ abortSignal
437
686
  })
438
- });
687
+ );
439
688
  if (generateResult.text === void 0) {
440
689
  throw new NoTextGeneratedError();
441
690
  }
442
691
  result = generateResult.text;
692
+ finishReason = generateResult.finishReason;
693
+ usage = generateResult.usage;
443
694
  break;
444
695
  }
445
696
  case "tool": {
446
- const generateResult = await model.doGenerate({
447
- mode: {
448
- type: "object-tool",
449
- tool: {
450
- type: "function",
451
- name: "json",
452
- description: "Respond with a JSON object.",
453
- parameters: jsonSchema
454
- }
455
- },
456
- ...settings,
457
- inputFormat: getInputFormat({ prompt, messages }),
458
- prompt: convertToLanguageModelPrompt({ system, prompt, messages })
459
- });
697
+ const generateResult = await retry(
698
+ () => model.doGenerate({
699
+ mode: {
700
+ type: "object-tool",
701
+ tool: {
702
+ type: "function",
703
+ name: "json",
704
+ description: "Respond with a JSON object.",
705
+ parameters: jsonSchema
706
+ }
707
+ },
708
+ ...settings,
709
+ inputFormat: getInputFormat({ prompt, messages }),
710
+ prompt: convertToLanguageModelPrompt({ system, prompt, messages }),
711
+ abortSignal
712
+ })
713
+ );
460
714
  const functionArgs = (_b = (_a = generateResult.toolCalls) == null ? void 0 : _a[0]) == null ? void 0 : _b.args;
461
715
  if (functionArgs === void 0) {
462
716
  throw new NoTextGeneratedError();
463
717
  }
464
718
  result = functionArgs;
719
+ finishReason = generateResult.finishReason;
720
+ usage = generateResult.usage;
465
721
  break;
466
722
  }
467
723
  case void 0: {
@@ -477,18 +733,39 @@ async function generateObject({
477
733
  throw parseResult.error;
478
734
  }
479
735
  return new GenerateObjectResult({
480
- object: parseResult.value
736
+ object: parseResult.value,
737
+ finishReason,
738
+ usage: calculateTokenUsage(usage)
481
739
  });
482
740
  }
483
741
  var GenerateObjectResult = class {
484
742
  constructor(options) {
485
743
  this.object = options.object;
744
+ this.finishReason = options.finishReason;
745
+ this.usage = options.usage;
486
746
  }
487
747
  };
488
748
 
489
749
  // core/generate-object/stream-object.ts
490
750
  import zodToJsonSchema2 from "zod-to-json-schema";
491
751
 
752
+ // core/util/async-iterable-stream.ts
753
+ function createAsyncIterableStream(source, transformer) {
754
+ const transformedStream = source.pipeThrough(
755
+ new TransformStream(transformer)
756
+ );
757
+ transformedStream[Symbol.asyncIterator] = () => {
758
+ const reader = transformedStream.getReader();
759
+ return {
760
+ async next() {
761
+ const { done, value } = await reader.read();
762
+ return done ? { done: true, value: void 0 } : { done: false, value };
763
+ }
764
+ };
765
+ };
766
+ return transformedStream;
767
+ }
768
+
492
769
  // core/util/is-deep-equal-data.ts
493
770
  function isDeepEqualData(obj1, obj2) {
494
771
  if (obj1 === obj2)
@@ -869,43 +1146,46 @@ async function streamObject({
869
1146
  system,
870
1147
  prompt,
871
1148
  messages,
1149
+ maxRetries,
1150
+ abortSignal,
872
1151
  ...settings
873
1152
  }) {
1153
+ const retry = retryWithExponentialBackoff({ maxRetries });
874
1154
  const jsonSchema = zodToJsonSchema2(schema);
875
- let modelStream;
876
1155
  if (mode === "auto" || mode == null) {
877
1156
  mode = model.defaultObjectGenerationMode;
878
1157
  }
1158
+ let callOptions;
1159
+ let transformer;
879
1160
  switch (mode) {
880
1161
  case "json": {
881
- const { stream, warnings } = await model.doStream({
1162
+ callOptions = {
882
1163
  mode: { type: "object-json" },
883
- ...validateCallSettings(settings),
1164
+ ...prepareCallSettings(settings),
884
1165
  inputFormat: getInputFormat({ prompt, messages }),
885
1166
  prompt: convertToLanguageModelPrompt({
886
1167
  system: injectJsonSchemaIntoSystem({ system, schema: jsonSchema }),
887
1168
  prompt,
888
1169
  messages
889
- })
890
- });
891
- modelStream = stream.pipeThrough(
892
- new TransformStream({
893
- transform(chunk, controller) {
894
- switch (chunk.type) {
895
- case "text-delta":
896
- controller.enqueue(chunk.textDelta);
897
- break;
898
- case "error":
899
- controller.enqueue(chunk);
900
- break;
901
- }
1170
+ }),
1171
+ abortSignal
1172
+ };
1173
+ transformer = {
1174
+ transform: (chunk, controller) => {
1175
+ switch (chunk.type) {
1176
+ case "text-delta":
1177
+ controller.enqueue(chunk.textDelta);
1178
+ break;
1179
+ case "error":
1180
+ controller.enqueue(chunk);
1181
+ break;
902
1182
  }
903
- })
904
- );
1183
+ }
1184
+ };
905
1185
  break;
906
1186
  }
907
1187
  case "grammar": {
908
- const { stream, warnings } = await model.doStream({
1188
+ callOptions = {
909
1189
  mode: { type: "object-grammar", schema: jsonSchema },
910
1190
  ...settings,
911
1191
  inputFormat: getInputFormat({ prompt, messages }),
@@ -913,26 +1193,25 @@ async function streamObject({
913
1193
  system: injectJsonSchemaIntoSystem({ system, schema: jsonSchema }),
914
1194
  prompt,
915
1195
  messages
916
- })
917
- });
918
- modelStream = stream.pipeThrough(
919
- new TransformStream({
920
- transform(chunk, controller) {
921
- switch (chunk.type) {
922
- case "text-delta":
923
- controller.enqueue(chunk.textDelta);
924
- break;
925
- case "error":
926
- controller.enqueue(chunk);
927
- break;
928
- }
1196
+ }),
1197
+ abortSignal
1198
+ };
1199
+ transformer = {
1200
+ transform: (chunk, controller) => {
1201
+ switch (chunk.type) {
1202
+ case "text-delta":
1203
+ controller.enqueue(chunk.textDelta);
1204
+ break;
1205
+ case "error":
1206
+ controller.enqueue(chunk);
1207
+ break;
929
1208
  }
930
- })
931
- );
1209
+ }
1210
+ };
932
1211
  break;
933
1212
  }
934
1213
  case "tool": {
935
- const { stream, warnings } = await model.doStream({
1214
+ callOptions = {
936
1215
  mode: {
937
1216
  type: "object-tool",
938
1217
  tool: {
@@ -944,22 +1223,21 @@ async function streamObject({
944
1223
  },
945
1224
  ...settings,
946
1225
  inputFormat: getInputFormat({ prompt, messages }),
947
- prompt: convertToLanguageModelPrompt({ system, prompt, messages })
948
- });
949
- modelStream = stream.pipeThrough(
950
- new TransformStream({
951
- transform(chunk, controller) {
952
- switch (chunk.type) {
953
- case "tool-call-delta":
954
- controller.enqueue(chunk.argsTextDelta);
955
- break;
956
- case "error":
957
- controller.enqueue(chunk);
958
- break;
959
- }
1226
+ prompt: convertToLanguageModelPrompt({ system, prompt, messages }),
1227
+ abortSignal
1228
+ };
1229
+ transformer = {
1230
+ transform(chunk, controller) {
1231
+ switch (chunk.type) {
1232
+ case "tool-call-delta":
1233
+ controller.enqueue(chunk.argsTextDelta);
1234
+ break;
1235
+ case "error":
1236
+ controller.enqueue(chunk);
1237
+ break;
960
1238
  }
961
- })
962
- );
1239
+ }
1240
+ };
963
1241
  break;
964
1242
  }
965
1243
  case void 0: {
@@ -970,37 +1248,35 @@ async function streamObject({
970
1248
  throw new Error(`Unsupported mode: ${_exhaustiveCheck}`);
971
1249
  }
972
1250
  }
973
- return new StreamObjectResult(modelStream);
1251
+ const { stream, warnings } = await retry(() => model.doStream(callOptions));
1252
+ return new StreamObjectResult(
1253
+ stream.pipeThrough(new TransformStream(transformer))
1254
+ );
974
1255
  }
975
1256
  var StreamObjectResult = class {
976
- constructor(modelStream) {
1257
+ constructor(stream) {
1258
+ this.originalStream = stream;
1259
+ }
1260
+ get objectStream() {
977
1261
  let accumulatedText = "";
978
1262
  let latestObject = void 0;
979
- this.objectStream = {
980
- [Symbol.asyncIterator]() {
981
- const reader = modelStream.getReader();
982
- return {
983
- next: async () => {
984
- while (true) {
985
- const { done, value } = await reader.read();
986
- if (done) {
987
- return { value: null, done: true };
988
- }
989
- if (typeof value === "string") {
990
- accumulatedText += value;
991
- const currentObject = parsePartialJson(
992
- accumulatedText
993
- );
994
- if (!isDeepEqualData(latestObject, currentObject)) {
995
- latestObject = currentObject;
996
- return { value: currentObject, done: false };
997
- }
998
- }
999
- }
1263
+ return createAsyncIterableStream(this.originalStream, {
1264
+ transform(chunk, controller) {
1265
+ if (typeof chunk === "string") {
1266
+ accumulatedText += chunk;
1267
+ const currentObject = parsePartialJson(
1268
+ accumulatedText
1269
+ );
1270
+ if (!isDeepEqualData(latestObject, currentObject)) {
1271
+ latestObject = currentObject;
1272
+ controller.enqueue(currentObject);
1000
1273
  }
1001
- };
1274
+ }
1275
+ if (typeof chunk === "object" && chunk.type === "error") {
1276
+ throw chunk.error;
1277
+ }
1002
1278
  }
1003
- };
1279
+ });
1004
1280
  }
1005
1281
  };
1006
1282
 
@@ -1014,26 +1290,33 @@ function parseToolCall({
1014
1290
  }) {
1015
1291
  const toolName = toolCall.toolName;
1016
1292
  if (tools == null) {
1017
- throw new Error(`Tool not found: ${toolName}`);
1293
+ throw new NoSuchToolError({
1294
+ message: `Tool ${toolCall.toolName} not found (no tools provided).`,
1295
+ toolName: toolCall.toolName
1296
+ });
1018
1297
  }
1019
1298
  const tool2 = tools[toolName];
1020
1299
  if (tool2 == null) {
1021
- throw new Error(`Tool not found: ${toolName}`);
1300
+ throw new NoSuchToolError({
1301
+ message: `Tool ${toolCall.toolName} not found.`,
1302
+ toolName: toolCall.toolName
1303
+ });
1022
1304
  }
1023
1305
  const parseResult = safeParseJSON({
1024
1306
  text: toolCall.args,
1025
1307
  schema: tool2.parameters
1026
1308
  });
1027
1309
  if (parseResult.success === false) {
1028
- throw new Error(
1029
- `Tool call ${toolName} has invalid arguments: ${parseResult.error}`
1030
- );
1310
+ throw new InvalidToolArgumentsError({
1311
+ toolName,
1312
+ toolArgs: toolCall.args,
1313
+ cause: parseResult.error
1314
+ });
1031
1315
  }
1032
- const toolArgs = parseResult.value;
1033
1316
  return {
1034
1317
  toolCallId: toolCall.toolCallId,
1035
1318
  toolName,
1036
- args: toolArgs
1319
+ args: parseResult.value
1037
1320
  };
1038
1321
  }
1039
1322
 
@@ -1044,27 +1327,33 @@ async function generateText({
1044
1327
  system,
1045
1328
  prompt,
1046
1329
  messages,
1330
+ maxRetries,
1331
+ abortSignal,
1047
1332
  ...settings
1048
1333
  }) {
1049
1334
  var _a, _b;
1050
- const modelResponse = await model.doGenerate({
1051
- mode: {
1052
- type: "regular",
1053
- tools: tools == null ? void 0 : Object.entries(tools).map(([name, tool2]) => ({
1054
- type: "function",
1055
- name,
1056
- description: tool2.description,
1057
- parameters: zodToJsonSchema3(tool2.parameters)
1058
- }))
1059
- },
1060
- ...validateCallSettings(settings),
1061
- inputFormat: getInputFormat({ prompt, messages }),
1062
- prompt: convertToLanguageModelPrompt({
1063
- system,
1064
- prompt,
1065
- messages
1335
+ const retry = retryWithExponentialBackoff({ maxRetries });
1336
+ const modelResponse = await retry(
1337
+ () => model.doGenerate({
1338
+ mode: {
1339
+ type: "regular",
1340
+ tools: tools == null ? void 0 : Object.entries(tools).map(([name, tool2]) => ({
1341
+ type: "function",
1342
+ name,
1343
+ description: tool2.description,
1344
+ parameters: zodToJsonSchema3(tool2.parameters)
1345
+ }))
1346
+ },
1347
+ ...prepareCallSettings(settings),
1348
+ inputFormat: getInputFormat({ prompt, messages }),
1349
+ prompt: convertToLanguageModelPrompt({
1350
+ system,
1351
+ prompt,
1352
+ messages
1353
+ }),
1354
+ abortSignal
1066
1355
  })
1067
- });
1356
+ );
1068
1357
  const toolCalls = [];
1069
1358
  for (const modelToolCall of (_a = modelResponse.toolCalls) != null ? _a : []) {
1070
1359
  toolCalls.push(parseToolCall({ toolCall: modelToolCall, tools }));
@@ -1076,7 +1365,9 @@ async function generateText({
1076
1365
  // they can check the length of the string:
1077
1366
  text: (_b = modelResponse.text) != null ? _b : "",
1078
1367
  toolCalls,
1079
- toolResults
1368
+ toolResults,
1369
+ finishReason: modelResponse.finishReason,
1370
+ usage: calculateTokenUsage(modelResponse.usage)
1080
1371
  });
1081
1372
  }
1082
1373
  async function executeTools({
@@ -1107,131 +1398,14 @@ var GenerateTextResult = class {
1107
1398
  this.text = options.text;
1108
1399
  this.toolCalls = options.toolCalls;
1109
1400
  this.toolResults = options.toolResults;
1401
+ this.finishReason = options.finishReason;
1402
+ this.usage = options.usage;
1110
1403
  }
1111
1404
  };
1112
1405
 
1113
1406
  // core/generate-text/stream-text.ts
1114
1407
  import zodToJsonSchema4 from "zod-to-json-schema";
1115
1408
 
1116
- // core/generate-text/run-tools-transformation.ts
1117
- import { nanoid } from "nanoid";
1118
- function runToolsTransformation({
1119
- tools,
1120
- generatorStream
1121
- }) {
1122
- let canClose = false;
1123
- const outstandingToolCalls = /* @__PURE__ */ new Set();
1124
- let toolResultsStreamController = null;
1125
- const toolResultsStream = new ReadableStream({
1126
- start(controller) {
1127
- toolResultsStreamController = controller;
1128
- }
1129
- });
1130
- const forwardStream = new TransformStream({
1131
- transform(chunk, controller) {
1132
- const chunkType = chunk.type;
1133
- switch (chunkType) {
1134
- case "text-delta":
1135
- case "error": {
1136
- controller.enqueue(chunk);
1137
- break;
1138
- }
1139
- case "tool-call": {
1140
- const toolName = chunk.toolName;
1141
- if (tools == null) {
1142
- toolResultsStreamController.enqueue({
1143
- type: "error",
1144
- error: `Tool ${chunk.toolName} not found (no tools provided)`
1145
- });
1146
- break;
1147
- }
1148
- const tool2 = tools[toolName];
1149
- if (tool2 == null) {
1150
- toolResultsStreamController.enqueue({
1151
- type: "error",
1152
- error: `Tool ${chunk.toolName} not found`
1153
- });
1154
- break;
1155
- }
1156
- const toolCall = parseToolCall({
1157
- toolCall: chunk,
1158
- tools
1159
- });
1160
- controller.enqueue({
1161
- type: "tool-call",
1162
- ...toolCall
1163
- });
1164
- if (tool2.execute != null) {
1165
- const toolExecutionId = nanoid();
1166
- outstandingToolCalls.add(toolExecutionId);
1167
- tool2.execute(toolCall.args).then(
1168
- (result) => {
1169
- toolResultsStreamController.enqueue({
1170
- type: "tool-result",
1171
- ...toolCall,
1172
- result
1173
- });
1174
- outstandingToolCalls.delete(toolExecutionId);
1175
- if (canClose && outstandingToolCalls.size === 0) {
1176
- toolResultsStreamController.close();
1177
- }
1178
- },
1179
- (error) => {
1180
- toolResultsStreamController.enqueue({
1181
- type: "error",
1182
- error
1183
- });
1184
- outstandingToolCalls.delete(toolExecutionId);
1185
- if (canClose && outstandingToolCalls.size === 0) {
1186
- toolResultsStreamController.close();
1187
- }
1188
- }
1189
- );
1190
- }
1191
- break;
1192
- }
1193
- case "finish-metadata":
1194
- case "tool-call-delta": {
1195
- break;
1196
- }
1197
- default: {
1198
- const _exhaustiveCheck = chunkType;
1199
- throw new Error(`Unhandled chunk type: ${_exhaustiveCheck}`);
1200
- }
1201
- }
1202
- },
1203
- flush() {
1204
- canClose = true;
1205
- if (outstandingToolCalls.size === 0) {
1206
- toolResultsStreamController.close();
1207
- }
1208
- }
1209
- });
1210
- return new ReadableStream({
1211
- async start(controller) {
1212
- generatorStream.pipeThrough(forwardStream).pipeTo(
1213
- new WritableStream({
1214
- write(chunk) {
1215
- controller.enqueue(chunk);
1216
- },
1217
- close() {
1218
- }
1219
- })
1220
- );
1221
- toolResultsStream.pipeTo(
1222
- new WritableStream({
1223
- write(chunk) {
1224
- controller.enqueue(chunk);
1225
- },
1226
- close() {
1227
- controller.close();
1228
- }
1229
- })
1230
- );
1231
- }
1232
- });
1233
- }
1234
-
1235
1409
  // shared/stream-parts.ts
1236
1410
  var textStreamPart = {
1237
1411
  code: "0",
@@ -1398,71 +1572,210 @@ function formatStreamPart(type, value) {
1398
1572
  `;
1399
1573
  }
1400
1574
 
1401
- // shared/utils.ts
1402
- import { customAlphabet } from "nanoid/non-secure";
1403
- var nanoid2 = customAlphabet(
1404
- "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
1405
- 7
1406
- );
1407
- var COMPLEX_HEADER = "X-Experimental-Stream-Data";
1575
+ // streams/ai-stream.ts
1576
+ import {
1577
+ createParser
1578
+ } from "eventsource-parser";
1579
+ function createCallbacksTransformer(cb) {
1580
+ const textEncoder = new TextEncoder();
1581
+ let aggregatedResponse = "";
1582
+ const callbacks = cb || {};
1583
+ return new TransformStream({
1584
+ async start() {
1585
+ if (callbacks.onStart)
1586
+ await callbacks.onStart();
1587
+ },
1588
+ async transform(message, controller) {
1589
+ const content = typeof message === "string" ? message : message.content;
1590
+ controller.enqueue(textEncoder.encode(content));
1591
+ aggregatedResponse += content;
1592
+ if (callbacks.onToken)
1593
+ await callbacks.onToken(content);
1594
+ if (callbacks.onText && typeof message === "string") {
1595
+ await callbacks.onText(message);
1596
+ }
1597
+ },
1598
+ async flush() {
1599
+ const isOpenAICallbacks = isOfTypeOpenAIStreamCallbacks(callbacks);
1600
+ if (callbacks.onCompletion) {
1601
+ await callbacks.onCompletion(aggregatedResponse);
1602
+ }
1603
+ if (callbacks.onFinal && !isOpenAICallbacks) {
1604
+ await callbacks.onFinal(aggregatedResponse);
1605
+ }
1606
+ }
1607
+ });
1608
+ }
1609
+ function isOfTypeOpenAIStreamCallbacks(callbacks) {
1610
+ return "experimental_onFunctionCall" in callbacks;
1611
+ }
1612
+ function readableFromAsyncIterable(iterable) {
1613
+ let it = iterable[Symbol.asyncIterator]();
1614
+ return new ReadableStream({
1615
+ async pull(controller) {
1616
+ const { done, value } = await it.next();
1617
+ if (done)
1618
+ controller.close();
1619
+ else
1620
+ controller.enqueue(value);
1621
+ },
1622
+ async cancel(reason) {
1623
+ var _a;
1624
+ await ((_a = it.return) == null ? void 0 : _a.call(it, reason));
1625
+ }
1626
+ });
1627
+ }
1628
+
1629
+ // streams/stream-data.ts
1630
+ function createStreamDataTransformer(experimental_streamData) {
1631
+ if (!experimental_streamData) {
1632
+ return new TransformStream({
1633
+ transform: async (chunk, controller) => {
1634
+ controller.enqueue(chunk);
1635
+ }
1636
+ });
1637
+ }
1638
+ const encoder = new TextEncoder();
1639
+ const decoder = new TextDecoder();
1640
+ return new TransformStream({
1641
+ transform: async (chunk, controller) => {
1642
+ const message = decoder.decode(chunk);
1643
+ controller.enqueue(encoder.encode(formatStreamPart("text", message)));
1644
+ }
1645
+ });
1646
+ }
1408
1647
 
1409
- // core/generate-text/stream-text-http-response.ts
1410
- var StreamTextHttpResponse = class extends Response {
1411
- constructor(messageStream) {
1412
- super(
1413
- messageStream.pipeThrough(
1414
- new TransformStream({
1415
- transform(chunk, controller) {
1416
- var _a;
1417
- switch (chunk.type) {
1418
- case "error": {
1419
- break;
1420
- }
1421
- case "text-delta": {
1422
- controller.enqueue(formatStreamPart("text", chunk.textDelta));
1423
- break;
1424
- }
1425
- case "tool-call": {
1426
- controller.enqueue(
1427
- formatStreamPart("tool_calls", {
1428
- tool_calls: [
1429
- {
1430
- type: "function",
1431
- id: (_a = chunk.toolCallId) != null ? _a : "",
1432
- // TODO client need to support null id
1433
- function: {
1434
- name: chunk.toolName,
1435
- arguments: JSON.stringify(chunk.args)
1436
- }
1437
- }
1438
- ]
1439
- })
1440
- );
1441
- break;
1442
- }
1443
- case "tool-result": {
1444
- break;
1445
- }
1446
- default: {
1447
- const exhaustiveCheck = chunk;
1448
- throw new Error(
1449
- `Unhandled stream part type: ${exhaustiveCheck}`
1450
- );
1451
- }
1648
+ // core/generate-text/run-tools-transformation.ts
1649
+ import { nanoid } from "nanoid";
1650
+ function runToolsTransformation({
1651
+ tools,
1652
+ generatorStream
1653
+ }) {
1654
+ let canClose = false;
1655
+ const outstandingToolCalls = /* @__PURE__ */ new Set();
1656
+ let toolResultsStreamController = null;
1657
+ const toolResultsStream = new ReadableStream({
1658
+ start(controller) {
1659
+ toolResultsStreamController = controller;
1660
+ }
1661
+ });
1662
+ const forwardStream = new TransformStream({
1663
+ transform(chunk, controller) {
1664
+ const chunkType = chunk.type;
1665
+ switch (chunkType) {
1666
+ case "text-delta":
1667
+ case "error": {
1668
+ controller.enqueue(chunk);
1669
+ break;
1670
+ }
1671
+ case "tool-call": {
1672
+ const toolName = chunk.toolName;
1673
+ if (tools == null) {
1674
+ toolResultsStreamController.enqueue({
1675
+ type: "error",
1676
+ error: new NoSuchToolError({
1677
+ message: `Tool ${chunk.toolName} not found (no tools provided).`,
1678
+ toolName: chunk.toolName
1679
+ })
1680
+ });
1681
+ break;
1682
+ }
1683
+ const tool2 = tools[toolName];
1684
+ if (tool2 == null) {
1685
+ toolResultsStreamController.enqueue({
1686
+ type: "error",
1687
+ error: new NoSuchToolError({
1688
+ message: `Tool ${chunk.toolName} not found.`,
1689
+ toolName: chunk.toolName
1690
+ })
1691
+ });
1692
+ break;
1693
+ }
1694
+ try {
1695
+ const toolCall = parseToolCall({
1696
+ toolCall: chunk,
1697
+ tools
1698
+ });
1699
+ controller.enqueue({
1700
+ type: "tool-call",
1701
+ ...toolCall
1702
+ });
1703
+ if (tool2.execute != null) {
1704
+ const toolExecutionId = nanoid();
1705
+ outstandingToolCalls.add(toolExecutionId);
1706
+ tool2.execute(toolCall.args).then(
1707
+ (result) => {
1708
+ toolResultsStreamController.enqueue({
1709
+ type: "tool-result",
1710
+ ...toolCall,
1711
+ result
1712
+ });
1713
+ outstandingToolCalls.delete(toolExecutionId);
1714
+ if (canClose && outstandingToolCalls.size === 0) {
1715
+ toolResultsStreamController.close();
1716
+ }
1717
+ },
1718
+ (error) => {
1719
+ toolResultsStreamController.enqueue({
1720
+ type: "error",
1721
+ error
1722
+ });
1723
+ outstandingToolCalls.delete(toolExecutionId);
1724
+ if (canClose && outstandingToolCalls.size === 0) {
1725
+ toolResultsStreamController.close();
1726
+ }
1727
+ }
1728
+ );
1452
1729
  }
1730
+ } catch (error) {
1731
+ toolResultsStreamController.enqueue({
1732
+ type: "error",
1733
+ error
1734
+ });
1453
1735
  }
1454
- })
1455
- ),
1456
- {
1457
- status: 200,
1458
- headers: {
1459
- "Content-Type": "text/plain; charset=utf-8",
1460
- [COMPLEX_HEADER]: "true"
1736
+ break;
1737
+ }
1738
+ case "finish-metadata":
1739
+ case "tool-call-delta": {
1740
+ break;
1741
+ }
1742
+ default: {
1743
+ const _exhaustiveCheck = chunkType;
1744
+ throw new Error(`Unhandled chunk type: ${_exhaustiveCheck}`);
1461
1745
  }
1462
1746
  }
1463
- );
1464
- }
1465
- };
1747
+ },
1748
+ flush() {
1749
+ canClose = true;
1750
+ if (outstandingToolCalls.size === 0) {
1751
+ toolResultsStreamController.close();
1752
+ }
1753
+ }
1754
+ });
1755
+ return new ReadableStream({
1756
+ async start(controller) {
1757
+ generatorStream.pipeThrough(forwardStream).pipeTo(
1758
+ new WritableStream({
1759
+ write(chunk) {
1760
+ controller.enqueue(chunk);
1761
+ },
1762
+ close() {
1763
+ }
1764
+ })
1765
+ );
1766
+ toolResultsStream.pipeTo(
1767
+ new WritableStream({
1768
+ write(chunk) {
1769
+ controller.enqueue(chunk);
1770
+ },
1771
+ close() {
1772
+ controller.close();
1773
+ }
1774
+ })
1775
+ );
1776
+ }
1777
+ });
1778
+ }
1466
1779
 
1467
1780
  // core/generate-text/stream-text.ts
1468
1781
  async function streamText({
@@ -1471,26 +1784,32 @@ async function streamText({
1471
1784
  system,
1472
1785
  prompt,
1473
1786
  messages,
1787
+ maxRetries,
1788
+ abortSignal,
1474
1789
  ...settings
1475
1790
  }) {
1476
- const { stream, warnings } = await model.doStream({
1477
- mode: {
1478
- type: "regular",
1479
- tools: tools == null ? void 0 : Object.entries(tools).map(([name, tool2]) => ({
1480
- type: "function",
1481
- name,
1482
- description: tool2.description,
1483
- parameters: zodToJsonSchema4(tool2.parameters)
1484
- }))
1485
- },
1486
- ...validateCallSettings(settings),
1487
- inputFormat: getInputFormat({ prompt, messages }),
1488
- prompt: convertToLanguageModelPrompt({
1489
- system,
1490
- prompt,
1491
- messages
1791
+ const retry = retryWithExponentialBackoff({ maxRetries });
1792
+ const { stream, warnings } = await retry(
1793
+ () => model.doStream({
1794
+ mode: {
1795
+ type: "regular",
1796
+ tools: tools == null ? void 0 : Object.entries(tools).map(([name, tool2]) => ({
1797
+ type: "function",
1798
+ name,
1799
+ description: tool2.description,
1800
+ parameters: zodToJsonSchema4(tool2.parameters)
1801
+ }))
1802
+ },
1803
+ ...prepareCallSettings(settings),
1804
+ inputFormat: getInputFormat({ prompt, messages }),
1805
+ prompt: convertToLanguageModelPrompt({
1806
+ system,
1807
+ prompt,
1808
+ messages
1809
+ }),
1810
+ abortSignal
1492
1811
  })
1493
- });
1812
+ );
1494
1813
  const toolStream = runToolsTransformation({
1495
1814
  tools,
1496
1815
  generatorStream: stream
@@ -1499,55 +1818,38 @@ async function streamText({
1499
1818
  }
1500
1819
  var StreamTextResult = class {
1501
1820
  constructor(stream) {
1502
- this.rootStream = stream;
1503
- this.textStream = {
1504
- [Symbol.asyncIterator]() {
1505
- const reader = stream.getReader();
1506
- return {
1507
- next: async () => {
1508
- while (true) {
1509
- const { done, value } = await reader.read();
1510
- if (done) {
1511
- return { value: null, done: true };
1512
- }
1513
- if (value.type === "text-delta") {
1514
- if (value.textDelta.length > 0) {
1515
- return { value: value.textDelta, done: false };
1516
- }
1517
- }
1518
- if (value.type === "error") {
1519
- console.error("Error:", value.error);
1520
- }
1521
- }
1821
+ this.originalStream = stream;
1822
+ }
1823
+ get textStream() {
1824
+ return createAsyncIterableStream(this.originalStream, {
1825
+ transform(chunk, controller) {
1826
+ if (chunk.type === "text-delta") {
1827
+ if (chunk.textDelta.length > 0) {
1828
+ controller.enqueue(chunk.textDelta);
1522
1829
  }
1523
- };
1830
+ } else if (chunk.type === "error") {
1831
+ throw chunk.error;
1832
+ }
1524
1833
  }
1525
- };
1526
- this.fullStream = {
1527
- [Symbol.asyncIterator]() {
1528
- const reader = stream.getReader();
1529
- return {
1530
- next: async () => {
1531
- while (true) {
1532
- const { done, value } = await reader.read();
1533
- if (done) {
1534
- return { value: null, done: true };
1535
- }
1536
- if (value.type === "text-delta") {
1537
- if (value.textDelta.length > 0) {
1538
- return { value, done: false };
1539
- }
1540
- } else {
1541
- return { value, done: false };
1542
- }
1543
- }
1834
+ });
1835
+ }
1836
+ get fullStream() {
1837
+ return createAsyncIterableStream(this.originalStream, {
1838
+ transform(chunk, controller) {
1839
+ if (chunk.type === "text-delta") {
1840
+ if (chunk.textDelta.length > 0) {
1841
+ controller.enqueue(chunk);
1544
1842
  }
1545
- };
1843
+ } else {
1844
+ controller.enqueue(chunk);
1845
+ }
1546
1846
  }
1547
- };
1847
+ });
1548
1848
  }
1549
- toResponse() {
1550
- return new StreamTextHttpResponse(this.rootStream);
1849
+ toAIStream(callbacks) {
1850
+ return readableFromAsyncIterable(this.textStream).pipeThrough(createCallbacksTransformer(callbacks)).pipeThrough(
1851
+ createStreamDataTransformer(callbacks == null ? void 0 : callbacks.experimental_streamData)
1852
+ );
1551
1853
  }
1552
1854
  };
1553
1855
 
@@ -1559,7 +1861,6 @@ export {
1559
1861
  GenerateObjectResult,
1560
1862
  GenerateTextResult,
1561
1863
  StreamObjectResult,
1562
- StreamTextHttpResponse,
1563
1864
  StreamTextResult,
1564
1865
  convertDataContentToBase64String,
1565
1866
  convertDataContentToUint8Array,