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.
@@ -33,7 +33,6 @@ __export(core_exports, {
33
33
  GenerateObjectResult: () => GenerateObjectResult,
34
34
  GenerateTextResult: () => GenerateTextResult,
35
35
  StreamObjectResult: () => StreamObjectResult,
36
- StreamTextHttpResponse: () => StreamTextHttpResponse,
37
36
  StreamTextResult: () => StreamTextResult,
38
37
  convertDataContentToBase64String: () => convertDataContentToBase64String,
39
38
  convertDataContentToUint8Array: () => convertDataContentToUint8Array,
@@ -48,10 +47,52 @@ module.exports = __toCommonJS(core_exports);
48
47
  // core/generate-object/generate-object.ts
49
48
  var import_zod_to_json_schema = __toESM(require("zod-to-json-schema"));
50
49
 
51
- // ai-model-specification/errors/ai-invalid-argument-error.ts
52
- var AI_InvalidArgumentError = class extends Error {
53
- // readonly learnMore =
54
- // 'https://sdk.vercel.com/docs/ai/errors/ai_invalid_argument_error';
50
+ // ai-model-specification/errors/api-call-error.ts
51
+ var APICallError = class extends Error {
52
+ constructor({
53
+ message,
54
+ url,
55
+ requestBodyValues,
56
+ statusCode,
57
+ responseBody,
58
+ cause,
59
+ isRetryable = statusCode != null && (statusCode === 408 || // request timeout
60
+ statusCode === 409 || // conflict
61
+ statusCode === 429 || // too many requests
62
+ statusCode >= 500),
63
+ // server error
64
+ data
65
+ }) {
66
+ super(message);
67
+ this.name = "AI_APICallError";
68
+ this.url = url;
69
+ this.requestBodyValues = requestBodyValues;
70
+ this.statusCode = statusCode;
71
+ this.responseBody = responseBody;
72
+ this.cause = cause;
73
+ this.isRetryable = isRetryable;
74
+ this.data = data;
75
+ }
76
+ static isAPICallError(error) {
77
+ 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");
78
+ }
79
+ toJSON() {
80
+ return {
81
+ name: this.name,
82
+ message: this.message,
83
+ url: this.url,
84
+ requestBodyValues: this.requestBodyValues,
85
+ statusCode: this.statusCode,
86
+ responseBody: this.responseBody,
87
+ cause: this.cause,
88
+ isRetryable: this.isRetryable,
89
+ data: this.data
90
+ };
91
+ }
92
+ };
93
+
94
+ // ai-model-specification/errors/invalid-argument-error.ts
95
+ var InvalidArgumentError = class extends Error {
55
96
  constructor({
56
97
  parameter,
57
98
  value,
@@ -62,6 +103,9 @@ var AI_InvalidArgumentError = class extends Error {
62
103
  this.parameter = parameter;
63
104
  this.value = value;
64
105
  }
106
+ static isInvalidArgumentError(error) {
107
+ return error instanceof Error && error.name === "AI_InvalidArgumentError" && typeof error.parameter === "string" && typeof error.value === "string";
108
+ }
65
109
  toJSON() {
66
110
  return {
67
111
  name: this.name,
@@ -87,6 +131,9 @@ function getErrorMessage(error) {
87
131
  return JSON.stringify(error);
88
132
  }
89
133
 
134
+ // ai-model-specification/util/parse-json.ts
135
+ var import_secure_json_parse = __toESM(require("secure-json-parse"));
136
+
90
137
  // ai-model-specification/errors/json-parse-error.ts
91
138
  var JSONParseError = class extends Error {
92
139
  constructor({ text, cause }) {
@@ -94,10 +141,13 @@ var JSONParseError = class extends Error {
94
141
  `JSON parsing failed: Text: ${text}.
95
142
  Error message: ${getErrorMessage(cause)}`
96
143
  );
97
- this.name = "JSONParseError";
144
+ this.name = "AI_JSONParseError";
98
145
  this.cause = cause;
99
146
  this.text = text;
100
147
  }
148
+ static isJSONParseError(error) {
149
+ return error instanceof Error && error.name === "AI_JSONParseError" && typeof error.text === "string" && typeof error.cause === "string";
150
+ }
101
151
  toJSON() {
102
152
  return {
103
153
  name: this.name,
@@ -109,22 +159,6 @@ Error message: ${getErrorMessage(cause)}`
109
159
  }
110
160
  };
111
161
 
112
- // ai-model-specification/errors/no-object-generated-error.ts
113
- var NoTextGeneratedError = class extends Error {
114
- constructor() {
115
- super(`No text generated.`);
116
- this.name = "NoTextGeneratedError";
117
- }
118
- toJSON() {
119
- return {
120
- name: this.name,
121
- cause: this.cause,
122
- message: this.message,
123
- stack: this.stack
124
- };
125
- }
126
- };
127
-
128
162
  // ai-model-specification/errors/type-validation-error.ts
129
163
  var TypeValidationError = class extends Error {
130
164
  constructor({ value, cause }) {
@@ -132,10 +166,13 @@ var TypeValidationError = class extends Error {
132
166
  `Type validation failed: Value: ${JSON.stringify(value)}.
133
167
  Error message: ${getErrorMessage(cause)}`
134
168
  );
135
- this.name = "TypeValidationError";
169
+ this.name = "AI_TypeValidationError";
136
170
  this.cause = cause;
137
171
  this.value = value;
138
172
  }
173
+ static isTypeValidationError(error) {
174
+ return error instanceof Error && error.name === "AI_TypeValidationError" && typeof error.value === "string" && typeof error.cause === "string";
175
+ }
139
176
  toJSON() {
140
177
  return {
141
178
  name: this.name,
@@ -147,9 +184,6 @@ Error message: ${getErrorMessage(cause)}`
147
184
  }
148
185
  };
149
186
 
150
- // ai-model-specification/util/parse-json.ts
151
- var import_secure_json_parse = __toESM(require("secure-json-parse"));
152
-
153
187
  // ai-model-specification/util/validate-types.ts
154
188
  function safeValidateTypes({
155
189
  value,
@@ -173,7 +207,7 @@ function safeValidateTypes({
173
207
  } catch (error) {
174
208
  return {
175
209
  success: false,
176
- error: error instanceof TypeValidationError ? error : new TypeValidationError({ value, cause: error })
210
+ error: TypeValidationError.isTypeValidationError(error) ? error : new TypeValidationError({ value, cause: error })
177
211
  };
178
212
  }
179
213
  }
@@ -195,7 +229,7 @@ function safeParseJSON({
195
229
  } catch (error) {
196
230
  return {
197
231
  success: false,
198
- error: error instanceof JSONParseError ? error : new JSONParseError({ text, cause: error })
232
+ error: JSONParseError.isJSONParseError(error) ? error : new JSONParseError({ text, cause: error })
199
233
  };
200
234
  }
201
235
  }
@@ -214,6 +248,112 @@ function convertUint8ArrayToBase64(array) {
214
248
  return globalThis.btoa(latin1string);
215
249
  }
216
250
 
251
+ // ai-model-specification/errors/invalid-tool-arguments-error.ts
252
+ var InvalidToolArgumentsError = class extends Error {
253
+ constructor({
254
+ toolArgs,
255
+ toolName,
256
+ cause,
257
+ message = `Invalid arguments for tool ${toolName}: ${getErrorMessage(
258
+ cause
259
+ )}`
260
+ }) {
261
+ super(message);
262
+ this.name = "AI_InvalidToolArgumentsError";
263
+ this.toolArgs = toolArgs;
264
+ this.toolName = toolName;
265
+ this.cause = cause;
266
+ }
267
+ static isInvalidToolArgumentsError(error) {
268
+ return error instanceof Error && error.name === "AI_InvalidToolArgumentsError" && typeof error.toolName === "string" && typeof error.toolArgs === "string";
269
+ }
270
+ toJSON() {
271
+ return {
272
+ name: this.name,
273
+ message: this.message,
274
+ cause: this.cause,
275
+ stack: this.stack,
276
+ toolName: this.toolName,
277
+ toolArgs: this.toolArgs
278
+ };
279
+ }
280
+ };
281
+
282
+ // ai-model-specification/errors/no-object-generated-error.ts
283
+ var NoTextGeneratedError = class extends Error {
284
+ constructor() {
285
+ super(`No text generated.`);
286
+ this.name = "AI_NoTextGeneratedError";
287
+ }
288
+ static isNoTextGeneratedError(error) {
289
+ return error instanceof Error && error.name === "AI_NoTextGeneratedError";
290
+ }
291
+ toJSON() {
292
+ return {
293
+ name: this.name,
294
+ cause: this.cause,
295
+ message: this.message,
296
+ stack: this.stack
297
+ };
298
+ }
299
+ };
300
+
301
+ // ai-model-specification/errors/no-such-tool-error.ts
302
+ var NoSuchToolError = class extends Error {
303
+ constructor({ message, toolName }) {
304
+ super(message);
305
+ this.name = "AI_NoSuchToolError";
306
+ this.toolName = toolName;
307
+ }
308
+ static isNoSuchToolError(error) {
309
+ return error instanceof Error && error.name === "AI_NoSuchToolError" && typeof error.toolName === "string";
310
+ }
311
+ toJSON() {
312
+ return {
313
+ name: this.name,
314
+ message: this.message,
315
+ stack: this.stack,
316
+ toolName: this.toolName
317
+ };
318
+ }
319
+ };
320
+
321
+ // ai-model-specification/errors/retry-error.ts
322
+ var RetryError = class extends Error {
323
+ constructor({
324
+ message,
325
+ reason,
326
+ errors
327
+ }) {
328
+ super(message);
329
+ this.name = "AI_RetryError";
330
+ this.reason = reason;
331
+ this.errors = errors;
332
+ this.lastError = errors[errors.length - 1];
333
+ }
334
+ static isRetryError(error) {
335
+ return error instanceof Error && error.name === "AI_RetryError" && typeof error.reason === "string" && Array.isArray(error.errors);
336
+ }
337
+ toJSON() {
338
+ return {
339
+ name: this.name,
340
+ message: this.message,
341
+ reason: this.reason,
342
+ lastError: this.lastError,
343
+ errors: this.errors
344
+ };
345
+ }
346
+ };
347
+
348
+ // core/generate-text/token-usage.ts
349
+ function calculateTokenUsage(usage) {
350
+ return {
351
+ promptTokens: usage.promptTokens,
352
+ completionTokens: usage.completionTokens,
353
+ totalTokens: usage.promptTokens + usage.completionTokens
354
+ };
355
+ }
356
+
217
357
  // core/prompt/data-content.ts
218
358
  function convertDataContentToBase64String(content) {
219
359
  if (typeof content === "string") {
@@ -283,7 +423,7 @@ function convertToLanguageModelPrompt({
283
423
  case "image": {
284
424
  return {
285
425
  type: "image",
286
- image: convertDataContentToUint8Array(part.image),
426
+ image: part.image instanceof URL ? part.image : convertDataContentToUint8Array(part.image),
287
427
  mimeType: part.mimeType
288
428
  };
289
429
  }
@@ -325,98 +465,193 @@ function getInputFormat({
325
465
  return prompt != null ? "prompt" : "messages";
326
466
  }
327
467
 
328
- // core/prompt/validate-call-settings.ts
329
- function validateCallSettings(settings) {
330
- if (settings.maxTokens != null) {
331
- if (!Number.isInteger(settings.maxTokens)) {
332
- throw new AI_InvalidArgumentError({
468
+ // core/prompt/prepare-call-settings.ts
469
+ function prepareCallSettings({
470
+ maxTokens,
471
+ temperature,
472
+ topP,
473
+ presencePenalty,
474
+ frequencyPenalty,
475
+ seed,
476
+ maxRetries
477
+ }) {
478
+ if (maxTokens != null) {
479
+ if (!Number.isInteger(maxTokens)) {
480
+ throw new InvalidArgumentError({
333
481
  parameter: "maxTokens",
334
- value: settings.maxTokens,
482
+ value: maxTokens,
335
483
  message: "maxTokens must be an integer"
336
484
  });
337
485
  }
338
- if (settings.maxTokens < 1) {
339
- throw new AI_InvalidArgumentError({
486
+ if (maxTokens < 1) {
487
+ throw new InvalidArgumentError({
340
488
  parameter: "maxTokens",
341
- value: settings.maxTokens,
489
+ value: maxTokens,
342
490
  message: "maxTokens must be >= 1"
343
491
  });
344
492
  }
345
493
  }
346
- if (settings.temperature != null) {
347
- if (typeof settings.temperature !== "number") {
348
- throw new AI_InvalidArgumentError({
494
+ if (temperature != null) {
495
+ if (typeof temperature !== "number") {
496
+ throw new InvalidArgumentError({
349
497
  parameter: "temperature",
350
- value: settings.temperature,
498
+ value: temperature,
351
499
  message: "temperature must be a number"
352
500
  });
353
501
  }
354
- if (settings.temperature < 0 || settings.temperature > 1) {
355
- throw new AI_InvalidArgumentError({
502
+ if (temperature < 0 || temperature > 1) {
503
+ throw new InvalidArgumentError({
356
504
  parameter: "temperature",
357
- value: settings.temperature,
505
+ value: temperature,
358
506
  message: "temperature must be between 0 and 1 (inclusive)"
359
507
  });
360
508
  }
361
509
  }
362
- if (settings.topP != null) {
363
- if (typeof settings.topP !== "number") {
364
- throw new AI_InvalidArgumentError({
510
+ if (topP != null) {
511
+ if (typeof topP !== "number") {
512
+ throw new InvalidArgumentError({
365
513
  parameter: "topP",
366
- value: settings.topP,
514
+ value: topP,
367
515
  message: "topP must be a number"
368
516
  });
369
517
  }
370
- if (settings.topP < 0 || settings.topP > 1) {
371
- throw new AI_InvalidArgumentError({
518
+ if (topP < 0 || topP > 1) {
519
+ throw new InvalidArgumentError({
372
520
  parameter: "topP",
373
- value: settings.topP,
521
+ value: topP,
374
522
  message: "topP must be between 0 and 1 (inclusive)"
375
523
  });
376
524
  }
377
525
  }
378
- if (settings.presencePenalty != null) {
379
- if (typeof settings.presencePenalty !== "number") {
380
- throw new AI_InvalidArgumentError({
526
+ if (presencePenalty != null) {
527
+ if (typeof presencePenalty !== "number") {
528
+ throw new InvalidArgumentError({
381
529
  parameter: "presencePenalty",
382
- value: settings.presencePenalty,
530
+ value: presencePenalty,
383
531
  message: "presencePenalty must be a number"
384
532
  });
385
533
  }
386
- if (settings.presencePenalty < -1 || settings.presencePenalty > 1) {
387
- throw new AI_InvalidArgumentError({
534
+ if (presencePenalty < -1 || presencePenalty > 1) {
535
+ throw new InvalidArgumentError({
388
536
  parameter: "presencePenalty",
389
- value: settings.presencePenalty,
537
+ value: presencePenalty,
390
538
  message: "presencePenalty must be between -1 and 1 (inclusive)"
391
539
  });
392
540
  }
393
541
  }
394
- if (settings.frequencyPenalty != null) {
395
- if (typeof settings.frequencyPenalty !== "number") {
396
- throw new AI_InvalidArgumentError({
542
+ if (frequencyPenalty != null) {
543
+ if (typeof frequencyPenalty !== "number") {
544
+ throw new InvalidArgumentError({
397
545
  parameter: "frequencyPenalty",
398
- value: settings.frequencyPenalty,
546
+ value: frequencyPenalty,
399
547
  message: "frequencyPenalty must be a number"
400
548
  });
401
549
  }
402
- if (settings.frequencyPenalty < -1 || settings.frequencyPenalty > 1) {
403
- throw new AI_InvalidArgumentError({
550
+ if (frequencyPenalty < -1 || frequencyPenalty > 1) {
551
+ throw new InvalidArgumentError({
404
552
  parameter: "frequencyPenalty",
405
- value: settings.frequencyPenalty,
553
+ value: frequencyPenalty,
406
554
  message: "frequencyPenalty must be between -1 and 1 (inclusive)"
407
555
  });
408
556
  }
409
557
  }
410
- if (settings.seed != null) {
411
- if (!Number.isInteger(settings.seed)) {
412
- throw new AI_InvalidArgumentError({
558
+ if (seed != null) {
559
+ if (!Number.isInteger(seed)) {
560
+ throw new InvalidArgumentError({
413
561
  parameter: "seed",
414
- value: settings.seed,
562
+ value: seed,
415
563
  message: "seed must be an integer"
416
564
  });
417
565
  }
418
566
  }
419
- return settings;
567
+ if (maxRetries != null) {
568
+ if (!Number.isInteger(maxRetries)) {
569
+ throw new InvalidArgumentError({
570
+ parameter: "maxRetries",
571
+ value: maxRetries,
572
+ message: "maxRetries must be an integer"
573
+ });
574
+ }
575
+ if (maxRetries < 0) {
576
+ throw new InvalidArgumentError({
577
+ parameter: "maxRetries",
578
+ value: maxRetries,
579
+ message: "maxRetries must be >= 0"
580
+ });
581
+ }
582
+ }
583
+ return {
584
+ maxTokens,
585
+ temperature: temperature != null ? temperature : 0,
586
+ topP,
587
+ presencePenalty: presencePenalty != null ? presencePenalty : 0,
588
+ frequencyPenalty: frequencyPenalty != null ? frequencyPenalty : 0,
589
+ seed,
590
+ maxRetries: maxRetries != null ? maxRetries : 2
591
+ };
592
+ }
593
+
594
+ // core/util/delay.ts
595
+ async function delay(delayInMs) {
596
+ return new Promise((resolve) => setTimeout(resolve, delayInMs));
597
+ }
598
+
599
+ // core/util/retry-with-exponential-backoff.ts
600
+ var retryWithExponentialBackoff = ({
601
+ maxRetries = 2,
602
+ initialDelayInMs = 2e3,
603
+ backoffFactor = 2
604
+ } = {}) => async (f) => _retryWithExponentialBackoff(f, {
605
+ maxRetries,
606
+ delayInMs: initialDelayInMs,
607
+ backoffFactor
608
+ });
609
+ async function _retryWithExponentialBackoff(f, {
610
+ maxRetries,
611
+ delayInMs,
612
+ backoffFactor
613
+ }, errors = []) {
614
+ try {
615
+ return await f();
616
+ } catch (error) {
617
+ if (maxRetries === 0) {
618
+ throw error;
619
+ }
620
+ const errorMessage = getErrorMessage(error);
621
+ const newErrors = [...errors, error];
622
+ const tryNumber = newErrors.length;
623
+ if (tryNumber > maxRetries) {
624
+ throw new RetryError({
625
+ message: `Failed after ${tryNumber} attemps. Last error: ${errorMessage}`,
626
+ reason: "maxRetriesExceeded",
627
+ errors: newErrors
628
+ });
629
+ }
630
+ if (error instanceof Error) {
631
+ if (error.name === "AbortError") {
632
+ throw error;
633
+ }
634
+ if (
635
+ // deal with bundling duplication by using names
636
+ APICallError.isAPICallError(error) && error.isRetryable === true && tryNumber <= maxRetries
637
+ ) {
638
+ await delay(delayInMs);
639
+ return _retryWithExponentialBackoff(
640
+ f,
641
+ { maxRetries, delayInMs: backoffFactor * delayInMs, backoffFactor },
642
+ newErrors
643
+ );
644
+ }
645
+ }
646
+ if (tryNumber === 1) {
647
+ throw error;
648
+ }
649
+ throw new RetryError({
650
+ message: `Failed after ${tryNumber} attemps with non-retryable error: '${errorMessage}'`,
651
+ reason: "errorNotRetryable",
652
+ errors: newErrors
653
+ });
654
+ }
420
655
  }
421
656
 
422
657
  // core/generate-object/inject-json-schema-into-system.ts
@@ -446,69 +681,89 @@ async function generateObject({
446
681
  system,
447
682
  prompt,
448
683
  messages,
684
+ maxRetries,
685
+ abortSignal,
449
686
  ...settings
450
687
  }) {
451
688
  var _a, _b;
689
+ const retry = retryWithExponentialBackoff({ maxRetries });
452
690
  const jsonSchema = (0, import_zod_to_json_schema.default)(schema);
453
691
  if (mode === "auto" || mode == null) {
454
692
  mode = model.defaultObjectGenerationMode;
455
693
  }
456
694
  let result;
695
+ let finishReason;
696
+ let usage;
457
697
  switch (mode) {
458
698
  case "json": {
459
- const generateResult = await model.doGenerate({
460
- mode: { type: "object-json" },
461
- ...validateCallSettings(settings),
462
- inputFormat: getInputFormat({ prompt, messages }),
463
- prompt: convertToLanguageModelPrompt({
464
- system: injectJsonSchemaIntoSystem({ system, schema: jsonSchema }),
465
- prompt,
466
- messages
699
+ const generateResult = await retry(
700
+ () => model.doGenerate({
701
+ mode: { type: "object-json" },
702
+ ...prepareCallSettings(settings),
703
+ inputFormat: getInputFormat({ prompt, messages }),
704
+ prompt: convertToLanguageModelPrompt({
705
+ system: injectJsonSchemaIntoSystem({ system, schema: jsonSchema }),
706
+ prompt,
707
+ messages
708
+ }),
709
+ abortSignal
467
710
  })
468
- });
711
+ );
469
712
  if (generateResult.text === void 0) {
470
713
  throw new NoTextGeneratedError();
471
714
  }
472
715
  result = generateResult.text;
716
+ finishReason = generateResult.finishReason;
717
+ usage = generateResult.usage;
473
718
  break;
474
719
  }
475
720
  case "grammar": {
476
- const generateResult = await model.doGenerate({
477
- mode: { type: "object-grammar", schema: jsonSchema },
478
- ...settings,
479
- inputFormat: getInputFormat({ prompt, messages }),
480
- prompt: convertToLanguageModelPrompt({
481
- system: injectJsonSchemaIntoSystem({ system, schema: jsonSchema }),
482
- prompt,
483
- messages
721
+ const generateResult = await retry(
722
+ () => model.doGenerate({
723
+ mode: { type: "object-grammar", schema: jsonSchema },
724
+ ...settings,
725
+ inputFormat: getInputFormat({ prompt, messages }),
726
+ prompt: convertToLanguageModelPrompt({
727
+ system: injectJsonSchemaIntoSystem({ system, schema: jsonSchema }),
728
+ prompt,
729
+ messages
730
+ }),
731
+ abortSignal
484
732
  })
485
- });
733
+ );
486
734
  if (generateResult.text === void 0) {
487
735
  throw new NoTextGeneratedError();
488
736
  }
489
737
  result = generateResult.text;
738
+ finishReason = generateResult.finishReason;
739
+ usage = generateResult.usage;
490
740
  break;
491
741
  }
492
742
  case "tool": {
493
- const generateResult = await model.doGenerate({
494
- mode: {
495
- type: "object-tool",
496
- tool: {
497
- type: "function",
498
- name: "json",
499
- description: "Respond with a JSON object.",
500
- parameters: jsonSchema
501
- }
502
- },
503
- ...settings,
504
- inputFormat: getInputFormat({ prompt, messages }),
505
- prompt: convertToLanguageModelPrompt({ system, prompt, messages })
506
- });
743
+ const generateResult = await retry(
744
+ () => model.doGenerate({
745
+ mode: {
746
+ type: "object-tool",
747
+ tool: {
748
+ type: "function",
749
+ name: "json",
750
+ description: "Respond with a JSON object.",
751
+ parameters: jsonSchema
752
+ }
753
+ },
754
+ ...settings,
755
+ inputFormat: getInputFormat({ prompt, messages }),
756
+ prompt: convertToLanguageModelPrompt({ system, prompt, messages }),
757
+ abortSignal
758
+ })
759
+ );
507
760
  const functionArgs = (_b = (_a = generateResult.toolCalls) == null ? void 0 : _a[0]) == null ? void 0 : _b.args;
508
761
  if (functionArgs === void 0) {
509
762
  throw new NoTextGeneratedError();
510
763
  }
511
764
  result = functionArgs;
765
+ finishReason = generateResult.finishReason;
766
+ usage = generateResult.usage;
512
767
  break;
513
768
  }
514
769
  case void 0: {
@@ -524,18 +779,39 @@ async function generateObject({
524
779
  throw parseResult.error;
525
780
  }
526
781
  return new GenerateObjectResult({
527
- object: parseResult.value
782
+ object: parseResult.value,
783
+ finishReason,
784
+ usage: calculateTokenUsage(usage)
528
785
  });
529
786
  }
530
787
  var GenerateObjectResult = class {
531
788
  constructor(options) {
532
789
  this.object = options.object;
790
+ this.finishReason = options.finishReason;
791
+ this.usage = options.usage;
533
792
  }
534
793
  };
535
794
 
536
795
  // core/generate-object/stream-object.ts
537
796
  var import_zod_to_json_schema2 = __toESM(require("zod-to-json-schema"));
538
797
 
798
+ // core/util/async-iterable-stream.ts
799
+ function createAsyncIterableStream(source, transformer) {
800
+ const transformedStream = source.pipeThrough(
801
+ new TransformStream(transformer)
802
+ );
803
+ transformedStream[Symbol.asyncIterator] = () => {
804
+ const reader = transformedStream.getReader();
805
+ return {
806
+ async next() {
807
+ const { done, value } = await reader.read();
808
+ return done ? { done: true, value: void 0 } : { done: false, value };
809
+ }
810
+ };
811
+ };
812
+ return transformedStream;
813
+ }
814
+
539
815
  // core/util/is-deep-equal-data.ts
540
816
  function isDeepEqualData(obj1, obj2) {
541
817
  if (obj1 === obj2)
@@ -916,43 +1192,46 @@ async function streamObject({
916
1192
  system,
917
1193
  prompt,
918
1194
  messages,
1195
+ maxRetries,
1196
+ abortSignal,
919
1197
  ...settings
920
1198
  }) {
1199
+ const retry = retryWithExponentialBackoff({ maxRetries });
921
1200
  const jsonSchema = (0, import_zod_to_json_schema2.default)(schema);
922
- let modelStream;
923
1201
  if (mode === "auto" || mode == null) {
924
1202
  mode = model.defaultObjectGenerationMode;
925
1203
  }
1204
+ let callOptions;
1205
+ let transformer;
926
1206
  switch (mode) {
927
1207
  case "json": {
928
- const { stream, warnings } = await model.doStream({
1208
+ callOptions = {
929
1209
  mode: { type: "object-json" },
930
- ...validateCallSettings(settings),
1210
+ ...prepareCallSettings(settings),
931
1211
  inputFormat: getInputFormat({ prompt, messages }),
932
1212
  prompt: convertToLanguageModelPrompt({
933
1213
  system: injectJsonSchemaIntoSystem({ system, schema: jsonSchema }),
934
1214
  prompt,
935
1215
  messages
936
- })
937
- });
938
- modelStream = stream.pipeThrough(
939
- new TransformStream({
940
- transform(chunk, controller) {
941
- switch (chunk.type) {
942
- case "text-delta":
943
- controller.enqueue(chunk.textDelta);
944
- break;
945
- case "error":
946
- controller.enqueue(chunk);
947
- break;
948
- }
1216
+ }),
1217
+ abortSignal
1218
+ };
1219
+ transformer = {
1220
+ transform: (chunk, controller) => {
1221
+ switch (chunk.type) {
1222
+ case "text-delta":
1223
+ controller.enqueue(chunk.textDelta);
1224
+ break;
1225
+ case "error":
1226
+ controller.enqueue(chunk);
1227
+ break;
949
1228
  }
950
- })
951
- );
1229
+ }
1230
+ };
952
1231
  break;
953
1232
  }
954
1233
  case "grammar": {
955
- const { stream, warnings } = await model.doStream({
1234
+ callOptions = {
956
1235
  mode: { type: "object-grammar", schema: jsonSchema },
957
1236
  ...settings,
958
1237
  inputFormat: getInputFormat({ prompt, messages }),
@@ -960,26 +1239,25 @@ async function streamObject({
960
1239
  system: injectJsonSchemaIntoSystem({ system, schema: jsonSchema }),
961
1240
  prompt,
962
1241
  messages
963
- })
964
- });
965
- modelStream = stream.pipeThrough(
966
- new TransformStream({
967
- transform(chunk, controller) {
968
- switch (chunk.type) {
969
- case "text-delta":
970
- controller.enqueue(chunk.textDelta);
971
- break;
972
- case "error":
973
- controller.enqueue(chunk);
974
- break;
975
- }
1242
+ }),
1243
+ abortSignal
1244
+ };
1245
+ transformer = {
1246
+ transform: (chunk, controller) => {
1247
+ switch (chunk.type) {
1248
+ case "text-delta":
1249
+ controller.enqueue(chunk.textDelta);
1250
+ break;
1251
+ case "error":
1252
+ controller.enqueue(chunk);
1253
+ break;
976
1254
  }
977
- })
978
- );
1255
+ }
1256
+ };
979
1257
  break;
980
1258
  }
981
1259
  case "tool": {
982
- const { stream, warnings } = await model.doStream({
1260
+ callOptions = {
983
1261
  mode: {
984
1262
  type: "object-tool",
985
1263
  tool: {
@@ -991,22 +1269,21 @@ async function streamObject({
991
1269
  },
992
1270
  ...settings,
993
1271
  inputFormat: getInputFormat({ prompt, messages }),
994
- prompt: convertToLanguageModelPrompt({ system, prompt, messages })
995
- });
996
- modelStream = stream.pipeThrough(
997
- new TransformStream({
998
- transform(chunk, controller) {
999
- switch (chunk.type) {
1000
- case "tool-call-delta":
1001
- controller.enqueue(chunk.argsTextDelta);
1002
- break;
1003
- case "error":
1004
- controller.enqueue(chunk);
1005
- break;
1006
- }
1272
+ prompt: convertToLanguageModelPrompt({ system, prompt, messages }),
1273
+ abortSignal
1274
+ };
1275
+ transformer = {
1276
+ transform(chunk, controller) {
1277
+ switch (chunk.type) {
1278
+ case "tool-call-delta":
1279
+ controller.enqueue(chunk.argsTextDelta);
1280
+ break;
1281
+ case "error":
1282
+ controller.enqueue(chunk);
1283
+ break;
1007
1284
  }
1008
- })
1009
- );
1285
+ }
1286
+ };
1010
1287
  break;
1011
1288
  }
1012
1289
  case void 0: {
@@ -1017,37 +1294,35 @@ async function streamObject({
1017
1294
  throw new Error(`Unsupported mode: ${_exhaustiveCheck}`);
1018
1295
  }
1019
1296
  }
1020
- return new StreamObjectResult(modelStream);
1297
+ const { stream, warnings } = await retry(() => model.doStream(callOptions));
1298
+ return new StreamObjectResult(
1299
+ stream.pipeThrough(new TransformStream(transformer))
1300
+ );
1021
1301
  }
1022
1302
  var StreamObjectResult = class {
1023
- constructor(modelStream) {
1303
+ constructor(stream) {
1304
+ this.originalStream = stream;
1305
+ }
1306
+ get objectStream() {
1024
1307
  let accumulatedText = "";
1025
1308
  let latestObject = void 0;
1026
- this.objectStream = {
1027
- [Symbol.asyncIterator]() {
1028
- const reader = modelStream.getReader();
1029
- return {
1030
- next: async () => {
1031
- while (true) {
1032
- const { done, value } = await reader.read();
1033
- if (done) {
1034
- return { value: null, done: true };
1035
- }
1036
- if (typeof value === "string") {
1037
- accumulatedText += value;
1038
- const currentObject = parsePartialJson(
1039
- accumulatedText
1040
- );
1041
- if (!isDeepEqualData(latestObject, currentObject)) {
1042
- latestObject = currentObject;
1043
- return { value: currentObject, done: false };
1044
- }
1045
- }
1046
- }
1309
+ return createAsyncIterableStream(this.originalStream, {
1310
+ transform(chunk, controller) {
1311
+ if (typeof chunk === "string") {
1312
+ accumulatedText += chunk;
1313
+ const currentObject = parsePartialJson(
1314
+ accumulatedText
1315
+ );
1316
+ if (!isDeepEqualData(latestObject, currentObject)) {
1317
+ latestObject = currentObject;
1318
+ controller.enqueue(currentObject);
1047
1319
  }
1048
- };
1320
+ }
1321
+ if (typeof chunk === "object" && chunk.type === "error") {
1322
+ throw chunk.error;
1323
+ }
1049
1324
  }
1050
- };
1325
+ });
1051
1326
  }
1052
1327
  };
1053
1328
 
@@ -1061,26 +1336,33 @@ function parseToolCall({
1061
1336
  }) {
1062
1337
  const toolName = toolCall.toolName;
1063
1338
  if (tools == null) {
1064
- throw new Error(`Tool not found: ${toolName}`);
1339
+ throw new NoSuchToolError({
1340
+ message: `Tool ${toolCall.toolName} not found (no tools provided).`,
1341
+ toolName: toolCall.toolName
1342
+ });
1065
1343
  }
1066
1344
  const tool2 = tools[toolName];
1067
1345
  if (tool2 == null) {
1068
- throw new Error(`Tool not found: ${toolName}`);
1346
+ throw new NoSuchToolError({
1347
+ message: `Tool ${toolCall.toolName} not found.`,
1348
+ toolName: toolCall.toolName
1349
+ });
1069
1350
  }
1070
1351
  const parseResult = safeParseJSON({
1071
1352
  text: toolCall.args,
1072
1353
  schema: tool2.parameters
1073
1354
  });
1074
1355
  if (parseResult.success === false) {
1075
- throw new Error(
1076
- `Tool call ${toolName} has invalid arguments: ${parseResult.error}`
1077
- );
1356
+ throw new InvalidToolArgumentsError({
1357
+ toolName,
1358
+ toolArgs: toolCall.args,
1359
+ cause: parseResult.error
1360
+ });
1078
1361
  }
1079
- const toolArgs = parseResult.value;
1080
1362
  return {
1081
1363
  toolCallId: toolCall.toolCallId,
1082
1364
  toolName,
1083
- args: toolArgs
1365
+ args: parseResult.value
1084
1366
  };
1085
1367
  }
1086
1368
 
@@ -1091,27 +1373,33 @@ async function generateText({
1091
1373
  system,
1092
1374
  prompt,
1093
1375
  messages,
1376
+ maxRetries,
1377
+ abortSignal,
1094
1378
  ...settings
1095
1379
  }) {
1096
1380
  var _a, _b;
1097
- const modelResponse = await model.doGenerate({
1098
- mode: {
1099
- type: "regular",
1100
- tools: tools == null ? void 0 : Object.entries(tools).map(([name, tool2]) => ({
1101
- type: "function",
1102
- name,
1103
- description: tool2.description,
1104
- parameters: (0, import_zod_to_json_schema3.default)(tool2.parameters)
1105
- }))
1106
- },
1107
- ...validateCallSettings(settings),
1108
- inputFormat: getInputFormat({ prompt, messages }),
1109
- prompt: convertToLanguageModelPrompt({
1110
- system,
1111
- prompt,
1112
- messages
1381
+ const retry = retryWithExponentialBackoff({ maxRetries });
1382
+ const modelResponse = await retry(
1383
+ () => model.doGenerate({
1384
+ mode: {
1385
+ type: "regular",
1386
+ tools: tools == null ? void 0 : Object.entries(tools).map(([name, tool2]) => ({
1387
+ type: "function",
1388
+ name,
1389
+ description: tool2.description,
1390
+ parameters: (0, import_zod_to_json_schema3.default)(tool2.parameters)
1391
+ }))
1392
+ },
1393
+ ...prepareCallSettings(settings),
1394
+ inputFormat: getInputFormat({ prompt, messages }),
1395
+ prompt: convertToLanguageModelPrompt({
1396
+ system,
1397
+ prompt,
1398
+ messages
1399
+ }),
1400
+ abortSignal
1113
1401
  })
1114
- });
1402
+ );
1115
1403
  const toolCalls = [];
1116
1404
  for (const modelToolCall of (_a = modelResponse.toolCalls) != null ? _a : []) {
1117
1405
  toolCalls.push(parseToolCall({ toolCall: modelToolCall, tools }));
@@ -1123,7 +1411,9 @@ async function generateText({
1123
1411
  // they can check the length of the string:
1124
1412
  text: (_b = modelResponse.text) != null ? _b : "",
1125
1413
  toolCalls,
1126
- toolResults
1414
+ toolResults,
1415
+ finishReason: modelResponse.finishReason,
1416
+ usage: calculateTokenUsage(modelResponse.usage)
1127
1417
  });
1128
1418
  }
1129
1419
  async function executeTools({
@@ -1154,131 +1444,14 @@ var GenerateTextResult = class {
1154
1444
  this.text = options.text;
1155
1445
  this.toolCalls = options.toolCalls;
1156
1446
  this.toolResults = options.toolResults;
1447
+ this.finishReason = options.finishReason;
1448
+ this.usage = options.usage;
1157
1449
  }
1158
1450
  };
1159
1451
 
1160
1452
  // core/generate-text/stream-text.ts
1161
1453
  var import_zod_to_json_schema4 = __toESM(require("zod-to-json-schema"));
1162
1454
 
1163
- // core/generate-text/run-tools-transformation.ts
1164
- var import_nanoid = require("nanoid");
1165
- function runToolsTransformation({
1166
- tools,
1167
- generatorStream
1168
- }) {
1169
- let canClose = false;
1170
- const outstandingToolCalls = /* @__PURE__ */ new Set();
1171
- let toolResultsStreamController = null;
1172
- const toolResultsStream = new ReadableStream({
1173
- start(controller) {
1174
- toolResultsStreamController = controller;
1175
- }
1176
- });
1177
- const forwardStream = new TransformStream({
1178
- transform(chunk, controller) {
1179
- const chunkType = chunk.type;
1180
- switch (chunkType) {
1181
- case "text-delta":
1182
- case "error": {
1183
- controller.enqueue(chunk);
1184
- break;
1185
- }
1186
- case "tool-call": {
1187
- const toolName = chunk.toolName;
1188
- if (tools == null) {
1189
- toolResultsStreamController.enqueue({
1190
- type: "error",
1191
- error: `Tool ${chunk.toolName} not found (no tools provided)`
1192
- });
1193
- break;
1194
- }
1195
- const tool2 = tools[toolName];
1196
- if (tool2 == null) {
1197
- toolResultsStreamController.enqueue({
1198
- type: "error",
1199
- error: `Tool ${chunk.toolName} not found`
1200
- });
1201
- break;
1202
- }
1203
- const toolCall = parseToolCall({
1204
- toolCall: chunk,
1205
- tools
1206
- });
1207
- controller.enqueue({
1208
- type: "tool-call",
1209
- ...toolCall
1210
- });
1211
- if (tool2.execute != null) {
1212
- const toolExecutionId = (0, import_nanoid.nanoid)();
1213
- outstandingToolCalls.add(toolExecutionId);
1214
- tool2.execute(toolCall.args).then(
1215
- (result) => {
1216
- toolResultsStreamController.enqueue({
1217
- type: "tool-result",
1218
- ...toolCall,
1219
- result
1220
- });
1221
- outstandingToolCalls.delete(toolExecutionId);
1222
- if (canClose && outstandingToolCalls.size === 0) {
1223
- toolResultsStreamController.close();
1224
- }
1225
- },
1226
- (error) => {
1227
- toolResultsStreamController.enqueue({
1228
- type: "error",
1229
- error
1230
- });
1231
- outstandingToolCalls.delete(toolExecutionId);
1232
- if (canClose && outstandingToolCalls.size === 0) {
1233
- toolResultsStreamController.close();
1234
- }
1235
- }
1236
- );
1237
- }
1238
- break;
1239
- }
1240
- case "finish-metadata":
1241
- case "tool-call-delta": {
1242
- break;
1243
- }
1244
- default: {
1245
- const _exhaustiveCheck = chunkType;
1246
- throw new Error(`Unhandled chunk type: ${_exhaustiveCheck}`);
1247
- }
1248
- }
1249
- },
1250
- flush() {
1251
- canClose = true;
1252
- if (outstandingToolCalls.size === 0) {
1253
- toolResultsStreamController.close();
1254
- }
1255
- }
1256
- });
1257
- return new ReadableStream({
1258
- async start(controller) {
1259
- generatorStream.pipeThrough(forwardStream).pipeTo(
1260
- new WritableStream({
1261
- write(chunk) {
1262
- controller.enqueue(chunk);
1263
- },
1264
- close() {
1265
- }
1266
- })
1267
- );
1268
- toolResultsStream.pipeTo(
1269
- new WritableStream({
1270
- write(chunk) {
1271
- controller.enqueue(chunk);
1272
- },
1273
- close() {
1274
- controller.close();
1275
- }
1276
- })
1277
- );
1278
- }
1279
- });
1280
- }
1281
-
1282
1455
  // shared/stream-parts.ts
1283
1456
  var textStreamPart = {
1284
1457
  code: "0",
@@ -1445,71 +1618,208 @@ function formatStreamPart(type, value) {
1445
1618
  `;
1446
1619
  }
1447
1620
 
1448
- // shared/utils.ts
1449
- var import_non_secure = require("nanoid/non-secure");
1450
- var nanoid2 = (0, import_non_secure.customAlphabet)(
1451
- "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
1452
- 7
1453
- );
1454
- var COMPLEX_HEADER = "X-Experimental-Stream-Data";
1621
+ // streams/ai-stream.ts
1622
+ var import_eventsource_parser = require("eventsource-parser");
1623
+ function createCallbacksTransformer(cb) {
1624
+ const textEncoder = new TextEncoder();
1625
+ let aggregatedResponse = "";
1626
+ const callbacks = cb || {};
1627
+ return new TransformStream({
1628
+ async start() {
1629
+ if (callbacks.onStart)
1630
+ await callbacks.onStart();
1631
+ },
1632
+ async transform(message, controller) {
1633
+ const content = typeof message === "string" ? message : message.content;
1634
+ controller.enqueue(textEncoder.encode(content));
1635
+ aggregatedResponse += content;
1636
+ if (callbacks.onToken)
1637
+ await callbacks.onToken(content);
1638
+ if (callbacks.onText && typeof message === "string") {
1639
+ await callbacks.onText(message);
1640
+ }
1641
+ },
1642
+ async flush() {
1643
+ const isOpenAICallbacks = isOfTypeOpenAIStreamCallbacks(callbacks);
1644
+ if (callbacks.onCompletion) {
1645
+ await callbacks.onCompletion(aggregatedResponse);
1646
+ }
1647
+ if (callbacks.onFinal && !isOpenAICallbacks) {
1648
+ await callbacks.onFinal(aggregatedResponse);
1649
+ }
1650
+ }
1651
+ });
1652
+ }
1653
+ function isOfTypeOpenAIStreamCallbacks(callbacks) {
1654
+ return "experimental_onFunctionCall" in callbacks;
1655
+ }
1656
+ function readableFromAsyncIterable(iterable) {
1657
+ let it = iterable[Symbol.asyncIterator]();
1658
+ return new ReadableStream({
1659
+ async pull(controller) {
1660
+ const { done, value } = await it.next();
1661
+ if (done)
1662
+ controller.close();
1663
+ else
1664
+ controller.enqueue(value);
1665
+ },
1666
+ async cancel(reason) {
1667
+ var _a;
1668
+ await ((_a = it.return) == null ? void 0 : _a.call(it, reason));
1669
+ }
1670
+ });
1671
+ }
1672
+
1673
+ // streams/stream-data.ts
1674
+ function createStreamDataTransformer(experimental_streamData) {
1675
+ if (!experimental_streamData) {
1676
+ return new TransformStream({
1677
+ transform: async (chunk, controller) => {
1678
+ controller.enqueue(chunk);
1679
+ }
1680
+ });
1681
+ }
1682
+ const encoder = new TextEncoder();
1683
+ const decoder = new TextDecoder();
1684
+ return new TransformStream({
1685
+ transform: async (chunk, controller) => {
1686
+ const message = decoder.decode(chunk);
1687
+ controller.enqueue(encoder.encode(formatStreamPart("text", message)));
1688
+ }
1689
+ });
1690
+ }
1455
1691
 
1456
- // core/generate-text/stream-text-http-response.ts
1457
- var StreamTextHttpResponse = class extends Response {
1458
- constructor(messageStream) {
1459
- super(
1460
- messageStream.pipeThrough(
1461
- new TransformStream({
1462
- transform(chunk, controller) {
1463
- var _a;
1464
- switch (chunk.type) {
1465
- case "error": {
1466
- break;
1467
- }
1468
- case "text-delta": {
1469
- controller.enqueue(formatStreamPart("text", chunk.textDelta));
1470
- break;
1471
- }
1472
- case "tool-call": {
1473
- controller.enqueue(
1474
- formatStreamPart("tool_calls", {
1475
- tool_calls: [
1476
- {
1477
- type: "function",
1478
- id: (_a = chunk.toolCallId) != null ? _a : "",
1479
- // TODO client need to support null id
1480
- function: {
1481
- name: chunk.toolName,
1482
- arguments: JSON.stringify(chunk.args)
1483
- }
1484
- }
1485
- ]
1486
- })
1487
- );
1488
- break;
1489
- }
1490
- case "tool-result": {
1491
- break;
1492
- }
1493
- default: {
1494
- const exhaustiveCheck = chunk;
1495
- throw new Error(
1496
- `Unhandled stream part type: ${exhaustiveCheck}`
1497
- );
1498
- }
1692
+ // core/generate-text/run-tools-transformation.ts
1693
+ var import_nanoid = require("nanoid");
1694
+ function runToolsTransformation({
1695
+ tools,
1696
+ generatorStream
1697
+ }) {
1698
+ let canClose = false;
1699
+ const outstandingToolCalls = /* @__PURE__ */ new Set();
1700
+ let toolResultsStreamController = null;
1701
+ const toolResultsStream = new ReadableStream({
1702
+ start(controller) {
1703
+ toolResultsStreamController = controller;
1704
+ }
1705
+ });
1706
+ const forwardStream = new TransformStream({
1707
+ transform(chunk, controller) {
1708
+ const chunkType = chunk.type;
1709
+ switch (chunkType) {
1710
+ case "text-delta":
1711
+ case "error": {
1712
+ controller.enqueue(chunk);
1713
+ break;
1714
+ }
1715
+ case "tool-call": {
1716
+ const toolName = chunk.toolName;
1717
+ if (tools == null) {
1718
+ toolResultsStreamController.enqueue({
1719
+ type: "error",
1720
+ error: new NoSuchToolError({
1721
+ message: `Tool ${chunk.toolName} not found (no tools provided).`,
1722
+ toolName: chunk.toolName
1723
+ })
1724
+ });
1725
+ break;
1726
+ }
1727
+ const tool2 = tools[toolName];
1728
+ if (tool2 == null) {
1729
+ toolResultsStreamController.enqueue({
1730
+ type: "error",
1731
+ error: new NoSuchToolError({
1732
+ message: `Tool ${chunk.toolName} not found.`,
1733
+ toolName: chunk.toolName
1734
+ })
1735
+ });
1736
+ break;
1737
+ }
1738
+ try {
1739
+ const toolCall = parseToolCall({
1740
+ toolCall: chunk,
1741
+ tools
1742
+ });
1743
+ controller.enqueue({
1744
+ type: "tool-call",
1745
+ ...toolCall
1746
+ });
1747
+ if (tool2.execute != null) {
1748
+ const toolExecutionId = (0, import_nanoid.nanoid)();
1749
+ outstandingToolCalls.add(toolExecutionId);
1750
+ tool2.execute(toolCall.args).then(
1751
+ (result) => {
1752
+ toolResultsStreamController.enqueue({
1753
+ type: "tool-result",
1754
+ ...toolCall,
1755
+ result
1756
+ });
1757
+ outstandingToolCalls.delete(toolExecutionId);
1758
+ if (canClose && outstandingToolCalls.size === 0) {
1759
+ toolResultsStreamController.close();
1760
+ }
1761
+ },
1762
+ (error) => {
1763
+ toolResultsStreamController.enqueue({
1764
+ type: "error",
1765
+ error
1766
+ });
1767
+ outstandingToolCalls.delete(toolExecutionId);
1768
+ if (canClose && outstandingToolCalls.size === 0) {
1769
+ toolResultsStreamController.close();
1770
+ }
1771
+ }
1772
+ );
1499
1773
  }
1774
+ } catch (error) {
1775
+ toolResultsStreamController.enqueue({
1776
+ type: "error",
1777
+ error
1778
+ });
1500
1779
  }
1501
- })
1502
- ),
1503
- {
1504
- status: 200,
1505
- headers: {
1506
- "Content-Type": "text/plain; charset=utf-8",
1507
- [COMPLEX_HEADER]: "true"
1780
+ break;
1781
+ }
1782
+ case "finish-metadata":
1783
+ case "tool-call-delta": {
1784
+ break;
1785
+ }
1786
+ default: {
1787
+ const _exhaustiveCheck = chunkType;
1788
+ throw new Error(`Unhandled chunk type: ${_exhaustiveCheck}`);
1508
1789
  }
1509
1790
  }
1510
- );
1511
- }
1512
- };
1791
+ },
1792
+ flush() {
1793
+ canClose = true;
1794
+ if (outstandingToolCalls.size === 0) {
1795
+ toolResultsStreamController.close();
1796
+ }
1797
+ }
1798
+ });
1799
+ return new ReadableStream({
1800
+ async start(controller) {
1801
+ generatorStream.pipeThrough(forwardStream).pipeTo(
1802
+ new WritableStream({
1803
+ write(chunk) {
1804
+ controller.enqueue(chunk);
1805
+ },
1806
+ close() {
1807
+ }
1808
+ })
1809
+ );
1810
+ toolResultsStream.pipeTo(
1811
+ new WritableStream({
1812
+ write(chunk) {
1813
+ controller.enqueue(chunk);
1814
+ },
1815
+ close() {
1816
+ controller.close();
1817
+ }
1818
+ })
1819
+ );
1820
+ }
1821
+ });
1822
+ }
1513
1823
 
1514
1824
  // core/generate-text/stream-text.ts
1515
1825
  async function streamText({
@@ -1518,26 +1828,32 @@ async function streamText({
1518
1828
  system,
1519
1829
  prompt,
1520
1830
  messages,
1831
+ maxRetries,
1832
+ abortSignal,
1521
1833
  ...settings
1522
1834
  }) {
1523
- const { stream, warnings } = await model.doStream({
1524
- mode: {
1525
- type: "regular",
1526
- tools: tools == null ? void 0 : Object.entries(tools).map(([name, tool2]) => ({
1527
- type: "function",
1528
- name,
1529
- description: tool2.description,
1530
- parameters: (0, import_zod_to_json_schema4.default)(tool2.parameters)
1531
- }))
1532
- },
1533
- ...validateCallSettings(settings),
1534
- inputFormat: getInputFormat({ prompt, messages }),
1535
- prompt: convertToLanguageModelPrompt({
1536
- system,
1537
- prompt,
1538
- messages
1835
+ const retry = retryWithExponentialBackoff({ maxRetries });
1836
+ const { stream, warnings } = await retry(
1837
+ () => model.doStream({
1838
+ mode: {
1839
+ type: "regular",
1840
+ tools: tools == null ? void 0 : Object.entries(tools).map(([name, tool2]) => ({
1841
+ type: "function",
1842
+ name,
1843
+ description: tool2.description,
1844
+ parameters: (0, import_zod_to_json_schema4.default)(tool2.parameters)
1845
+ }))
1846
+ },
1847
+ ...prepareCallSettings(settings),
1848
+ inputFormat: getInputFormat({ prompt, messages }),
1849
+ prompt: convertToLanguageModelPrompt({
1850
+ system,
1851
+ prompt,
1852
+ messages
1853
+ }),
1854
+ abortSignal
1539
1855
  })
1540
- });
1856
+ );
1541
1857
  const toolStream = runToolsTransformation({
1542
1858
  tools,
1543
1859
  generatorStream: stream
@@ -1546,55 +1862,38 @@ async function streamText({
1546
1862
  }
1547
1863
  var StreamTextResult = class {
1548
1864
  constructor(stream) {
1549
- this.rootStream = stream;
1550
- this.textStream = {
1551
- [Symbol.asyncIterator]() {
1552
- const reader = stream.getReader();
1553
- return {
1554
- next: async () => {
1555
- while (true) {
1556
- const { done, value } = await reader.read();
1557
- if (done) {
1558
- return { value: null, done: true };
1559
- }
1560
- if (value.type === "text-delta") {
1561
- if (value.textDelta.length > 0) {
1562
- return { value: value.textDelta, done: false };
1563
- }
1564
- }
1565
- if (value.type === "error") {
1566
- console.error("Error:", value.error);
1567
- }
1568
- }
1865
+ this.originalStream = stream;
1866
+ }
1867
+ get textStream() {
1868
+ return createAsyncIterableStream(this.originalStream, {
1869
+ transform(chunk, controller) {
1870
+ if (chunk.type === "text-delta") {
1871
+ if (chunk.textDelta.length > 0) {
1872
+ controller.enqueue(chunk.textDelta);
1569
1873
  }
1570
- };
1874
+ } else if (chunk.type === "error") {
1875
+ throw chunk.error;
1876
+ }
1571
1877
  }
1572
- };
1573
- this.fullStream = {
1574
- [Symbol.asyncIterator]() {
1575
- const reader = stream.getReader();
1576
- return {
1577
- next: async () => {
1578
- while (true) {
1579
- const { done, value } = await reader.read();
1580
- if (done) {
1581
- return { value: null, done: true };
1582
- }
1583
- if (value.type === "text-delta") {
1584
- if (value.textDelta.length > 0) {
1585
- return { value, done: false };
1586
- }
1587
- } else {
1588
- return { value, done: false };
1589
- }
1590
- }
1878
+ });
1879
+ }
1880
+ get fullStream() {
1881
+ return createAsyncIterableStream(this.originalStream, {
1882
+ transform(chunk, controller) {
1883
+ if (chunk.type === "text-delta") {
1884
+ if (chunk.textDelta.length > 0) {
1885
+ controller.enqueue(chunk);
1591
1886
  }
1592
- };
1887
+ } else {
1888
+ controller.enqueue(chunk);
1889
+ }
1593
1890
  }
1594
- };
1891
+ });
1595
1892
  }
1596
- toResponse() {
1597
- return new StreamTextHttpResponse(this.rootStream);
1893
+ toAIStream(callbacks) {
1894
+ return readableFromAsyncIterable(this.textStream).pipeThrough(createCallbacksTransformer(callbacks)).pipeThrough(
1895
+ createStreamDataTransformer(callbacks == null ? void 0 : callbacks.experimental_streamData)
1896
+ );
1598
1897
  }
1599
1898
  };
1600
1899
 
@@ -1607,7 +1906,6 @@ function tool(tool2) {
1607
1906
  GenerateObjectResult,
1608
1907
  GenerateTextResult,
1609
1908
  StreamObjectResult,
1610
- StreamTextHttpResponse,
1611
1909
  StreamTextResult,
1612
1910
  convertDataContentToBase64String,
1613
1911
  convertDataContentToUint8Array,