ai 3.1.0-canary.3 → 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.
@@ -47,10 +47,52 @@ module.exports = __toCommonJS(core_exports);
47
47
  // core/generate-object/generate-object.ts
48
48
  var import_zod_to_json_schema = __toESM(require("zod-to-json-schema"));
49
49
 
50
- // ai-model-specification/errors/ai-invalid-argument-error.ts
51
- var AI_InvalidArgumentError = class extends Error {
52
- // readonly learnMore =
53
- // '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 {
54
96
  constructor({
55
97
  parameter,
56
98
  value,
@@ -61,6 +103,9 @@ var AI_InvalidArgumentError = class extends Error {
61
103
  this.parameter = parameter;
62
104
  this.value = value;
63
105
  }
106
+ static isInvalidArgumentError(error) {
107
+ return error instanceof Error && error.name === "AI_InvalidArgumentError" && typeof error.parameter === "string" && typeof error.value === "string";
108
+ }
64
109
  toJSON() {
65
110
  return {
66
111
  name: this.name,
@@ -86,6 +131,9 @@ function getErrorMessage(error) {
86
131
  return JSON.stringify(error);
87
132
  }
88
133
 
134
+ // ai-model-specification/util/parse-json.ts
135
+ var import_secure_json_parse = __toESM(require("secure-json-parse"));
136
+
89
137
  // ai-model-specification/errors/json-parse-error.ts
90
138
  var JSONParseError = class extends Error {
91
139
  constructor({ text, cause }) {
@@ -93,10 +141,13 @@ var JSONParseError = class extends Error {
93
141
  `JSON parsing failed: Text: ${text}.
94
142
  Error message: ${getErrorMessage(cause)}`
95
143
  );
96
- this.name = "JSONParseError";
144
+ this.name = "AI_JSONParseError";
97
145
  this.cause = cause;
98
146
  this.text = text;
99
147
  }
148
+ static isJSONParseError(error) {
149
+ return error instanceof Error && error.name === "AI_JSONParseError" && typeof error.text === "string" && typeof error.cause === "string";
150
+ }
100
151
  toJSON() {
101
152
  return {
102
153
  name: this.name,
@@ -108,46 +159,6 @@ Error message: ${getErrorMessage(cause)}`
108
159
  }
109
160
  };
110
161
 
111
- // ai-model-specification/errors/no-object-generated-error.ts
112
- var NoTextGeneratedError = class extends Error {
113
- constructor() {
114
- super(`No text generated.`);
115
- this.name = "NoTextGeneratedError";
116
- }
117
- toJSON() {
118
- return {
119
- name: this.name,
120
- cause: this.cause,
121
- message: this.message,
122
- stack: this.stack
123
- };
124
- }
125
- };
126
-
127
- // ai-model-specification/errors/retry-error.ts
128
- var RetryError = class extends Error {
129
- constructor({
130
- message,
131
- reason,
132
- errors
133
- }) {
134
- super(message);
135
- this.name = "RetryError";
136
- this.reason = reason;
137
- this.errors = errors;
138
- this.lastError = errors[errors.length - 1];
139
- }
140
- toJSON() {
141
- return {
142
- name: this.name,
143
- message: this.message,
144
- reason: this.reason,
145
- lastError: this.lastError,
146
- errors: this.errors
147
- };
148
- }
149
- };
150
-
151
162
  // ai-model-specification/errors/type-validation-error.ts
152
163
  var TypeValidationError = class extends Error {
153
164
  constructor({ value, cause }) {
@@ -155,10 +166,13 @@ var TypeValidationError = class extends Error {
155
166
  `Type validation failed: Value: ${JSON.stringify(value)}.
156
167
  Error message: ${getErrorMessage(cause)}`
157
168
  );
158
- this.name = "TypeValidationError";
169
+ this.name = "AI_TypeValidationError";
159
170
  this.cause = cause;
160
171
  this.value = value;
161
172
  }
173
+ static isTypeValidationError(error) {
174
+ return error instanceof Error && error.name === "AI_TypeValidationError" && typeof error.value === "string" && typeof error.cause === "string";
175
+ }
162
176
  toJSON() {
163
177
  return {
164
178
  name: this.name,
@@ -170,9 +184,6 @@ Error message: ${getErrorMessage(cause)}`
170
184
  }
171
185
  };
172
186
 
173
- // ai-model-specification/util/parse-json.ts
174
- var import_secure_json_parse = __toESM(require("secure-json-parse"));
175
-
176
187
  // ai-model-specification/util/validate-types.ts
177
188
  function safeValidateTypes({
178
189
  value,
@@ -196,7 +207,7 @@ function safeValidateTypes({
196
207
  } catch (error) {
197
208
  return {
198
209
  success: false,
199
- error: error instanceof TypeValidationError ? error : new TypeValidationError({ value, cause: error })
210
+ error: TypeValidationError.isTypeValidationError(error) ? error : new TypeValidationError({ value, cause: error })
200
211
  };
201
212
  }
202
213
  }
@@ -218,7 +229,7 @@ function safeParseJSON({
218
229
  } catch (error) {
219
230
  return {
220
231
  success: false,
221
- error: error instanceof JSONParseError ? error : new JSONParseError({ text, cause: error })
232
+ error: JSONParseError.isJSONParseError(error) ? error : new JSONParseError({ text, cause: error })
222
233
  };
223
234
  }
224
235
  }
@@ -237,6 +248,103 @@ function convertUint8ArrayToBase64(array) {
237
248
  return globalThis.btoa(latin1string);
238
249
  }
239
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
+
240
348
  // core/generate-text/token-usage.ts
241
349
  function calculateTokenUsage(usage) {
242
350
  return {
@@ -357,98 +465,130 @@ function getInputFormat({
357
465
  return prompt != null ? "prompt" : "messages";
358
466
  }
359
467
 
360
- // core/prompt/validate-call-settings.ts
361
- function validateCallSettings(settings) {
362
- if (settings.maxTokens != null) {
363
- if (!Number.isInteger(settings.maxTokens)) {
364
- 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({
365
481
  parameter: "maxTokens",
366
- value: settings.maxTokens,
482
+ value: maxTokens,
367
483
  message: "maxTokens must be an integer"
368
484
  });
369
485
  }
370
- if (settings.maxTokens < 1) {
371
- throw new AI_InvalidArgumentError({
486
+ if (maxTokens < 1) {
487
+ throw new InvalidArgumentError({
372
488
  parameter: "maxTokens",
373
- value: settings.maxTokens,
489
+ value: maxTokens,
374
490
  message: "maxTokens must be >= 1"
375
491
  });
376
492
  }
377
493
  }
378
- if (settings.temperature != null) {
379
- if (typeof settings.temperature !== "number") {
380
- throw new AI_InvalidArgumentError({
494
+ if (temperature != null) {
495
+ if (typeof temperature !== "number") {
496
+ throw new InvalidArgumentError({
381
497
  parameter: "temperature",
382
- value: settings.temperature,
498
+ value: temperature,
383
499
  message: "temperature must be a number"
384
500
  });
385
501
  }
386
- if (settings.temperature < 0 || settings.temperature > 1) {
387
- throw new AI_InvalidArgumentError({
502
+ if (temperature < 0 || temperature > 1) {
503
+ throw new InvalidArgumentError({
388
504
  parameter: "temperature",
389
- value: settings.temperature,
505
+ value: temperature,
390
506
  message: "temperature must be between 0 and 1 (inclusive)"
391
507
  });
392
508
  }
393
509
  }
394
- if (settings.topP != null) {
395
- if (typeof settings.topP !== "number") {
396
- throw new AI_InvalidArgumentError({
510
+ if (topP != null) {
511
+ if (typeof topP !== "number") {
512
+ throw new InvalidArgumentError({
397
513
  parameter: "topP",
398
- value: settings.topP,
514
+ value: topP,
399
515
  message: "topP must be a number"
400
516
  });
401
517
  }
402
- if (settings.topP < 0 || settings.topP > 1) {
403
- throw new AI_InvalidArgumentError({
518
+ if (topP < 0 || topP > 1) {
519
+ throw new InvalidArgumentError({
404
520
  parameter: "topP",
405
- value: settings.topP,
521
+ value: topP,
406
522
  message: "topP must be between 0 and 1 (inclusive)"
407
523
  });
408
524
  }
409
525
  }
410
- if (settings.presencePenalty != null) {
411
- if (typeof settings.presencePenalty !== "number") {
412
- throw new AI_InvalidArgumentError({
526
+ if (presencePenalty != null) {
527
+ if (typeof presencePenalty !== "number") {
528
+ throw new InvalidArgumentError({
413
529
  parameter: "presencePenalty",
414
- value: settings.presencePenalty,
530
+ value: presencePenalty,
415
531
  message: "presencePenalty must be a number"
416
532
  });
417
533
  }
418
- if (settings.presencePenalty < -1 || settings.presencePenalty > 1) {
419
- throw new AI_InvalidArgumentError({
534
+ if (presencePenalty < -1 || presencePenalty > 1) {
535
+ throw new InvalidArgumentError({
420
536
  parameter: "presencePenalty",
421
- value: settings.presencePenalty,
537
+ value: presencePenalty,
422
538
  message: "presencePenalty must be between -1 and 1 (inclusive)"
423
539
  });
424
540
  }
425
541
  }
426
- if (settings.frequencyPenalty != null) {
427
- if (typeof settings.frequencyPenalty !== "number") {
428
- throw new AI_InvalidArgumentError({
542
+ if (frequencyPenalty != null) {
543
+ if (typeof frequencyPenalty !== "number") {
544
+ throw new InvalidArgumentError({
429
545
  parameter: "frequencyPenalty",
430
- value: settings.frequencyPenalty,
546
+ value: frequencyPenalty,
431
547
  message: "frequencyPenalty must be a number"
432
548
  });
433
549
  }
434
- if (settings.frequencyPenalty < -1 || settings.frequencyPenalty > 1) {
435
- throw new AI_InvalidArgumentError({
550
+ if (frequencyPenalty < -1 || frequencyPenalty > 1) {
551
+ throw new InvalidArgumentError({
436
552
  parameter: "frequencyPenalty",
437
- value: settings.frequencyPenalty,
553
+ value: frequencyPenalty,
438
554
  message: "frequencyPenalty must be between -1 and 1 (inclusive)"
439
555
  });
440
556
  }
441
557
  }
442
- if (settings.seed != null) {
443
- if (!Number.isInteger(settings.seed)) {
444
- throw new AI_InvalidArgumentError({
558
+ if (seed != null) {
559
+ if (!Number.isInteger(seed)) {
560
+ throw new InvalidArgumentError({
445
561
  parameter: "seed",
446
- value: settings.seed,
562
+ value: seed,
447
563
  message: "seed must be an integer"
448
564
  });
449
565
  }
450
566
  }
451
- 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
+ };
452
592
  }
453
593
 
454
594
  // core/util/delay.ts
@@ -482,7 +622,7 @@ async function _retryWithExponentialBackoff(f, {
482
622
  const tryNumber = newErrors.length;
483
623
  if (tryNumber > maxRetries) {
484
624
  throw new RetryError({
485
- message: `Failed after ${tryNumber} tries. Last error: ${errorMessage}`,
625
+ message: `Failed after ${tryNumber} attemps. Last error: ${errorMessage}`,
486
626
  reason: "maxRetriesExceeded",
487
627
  errors: newErrors
488
628
  });
@@ -493,7 +633,7 @@ async function _retryWithExponentialBackoff(f, {
493
633
  }
494
634
  if (
495
635
  // deal with bundling duplication by using names
496
- error.name === "ApiCallError" && error.isRetryable === true && tryNumber <= maxRetries
636
+ APICallError.isAPICallError(error) && error.isRetryable === true && tryNumber <= maxRetries
497
637
  ) {
498
638
  await delay(delayInMs);
499
639
  return _retryWithExponentialBackoff(
@@ -503,8 +643,11 @@ async function _retryWithExponentialBackoff(f, {
503
643
  );
504
644
  }
505
645
  }
646
+ if (tryNumber === 1) {
647
+ throw error;
648
+ }
506
649
  throw new RetryError({
507
- message: `Failed after ${tryNumber} tries with non-retryable error: '${errorMessage}'`,
650
+ message: `Failed after ${tryNumber} attemps with non-retryable error: '${errorMessage}'`,
508
651
  reason: "errorNotRetryable",
509
652
  errors: newErrors
510
653
  });
@@ -556,7 +699,7 @@ async function generateObject({
556
699
  const generateResult = await retry(
557
700
  () => model.doGenerate({
558
701
  mode: { type: "object-json" },
559
- ...validateCallSettings(settings),
702
+ ...prepareCallSettings(settings),
560
703
  inputFormat: getInputFormat({ prompt, messages }),
561
704
  prompt: convertToLanguageModelPrompt({
562
705
  system: injectJsonSchemaIntoSystem({ system, schema: jsonSchema }),
@@ -652,6 +795,23 @@ var GenerateObjectResult = class {
652
795
  // core/generate-object/stream-object.ts
653
796
  var import_zod_to_json_schema2 = __toESM(require("zod-to-json-schema"));
654
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
+
655
815
  // core/util/is-deep-equal-data.ts
656
816
  function isDeepEqualData(obj1, obj2) {
657
817
  if (obj1 === obj2)
@@ -1038,103 +1198,92 @@ async function streamObject({
1038
1198
  }) {
1039
1199
  const retry = retryWithExponentialBackoff({ maxRetries });
1040
1200
  const jsonSchema = (0, import_zod_to_json_schema2.default)(schema);
1041
- let modelStream;
1042
1201
  if (mode === "auto" || mode == null) {
1043
1202
  mode = model.defaultObjectGenerationMode;
1044
1203
  }
1204
+ let callOptions;
1205
+ let transformer;
1045
1206
  switch (mode) {
1046
1207
  case "json": {
1047
- const { stream, warnings } = await retry(
1048
- () => model.doStream({
1049
- mode: { type: "object-json" },
1050
- ...validateCallSettings(settings),
1051
- inputFormat: getInputFormat({ prompt, messages }),
1052
- prompt: convertToLanguageModelPrompt({
1053
- system: injectJsonSchemaIntoSystem({ system, schema: jsonSchema }),
1054
- prompt,
1055
- messages
1056
- }),
1057
- abortSignal
1058
- })
1059
- );
1060
- modelStream = stream.pipeThrough(
1061
- new TransformStream({
1062
- transform(chunk, controller) {
1063
- switch (chunk.type) {
1064
- case "text-delta":
1065
- controller.enqueue(chunk.textDelta);
1066
- break;
1067
- case "error":
1068
- controller.enqueue(chunk);
1069
- break;
1070
- }
1208
+ callOptions = {
1209
+ mode: { type: "object-json" },
1210
+ ...prepareCallSettings(settings),
1211
+ inputFormat: getInputFormat({ prompt, messages }),
1212
+ prompt: convertToLanguageModelPrompt({
1213
+ system: injectJsonSchemaIntoSystem({ system, schema: jsonSchema }),
1214
+ prompt,
1215
+ messages
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;
1071
1228
  }
1072
- })
1073
- );
1229
+ }
1230
+ };
1074
1231
  break;
1075
1232
  }
1076
1233
  case "grammar": {
1077
- const { stream, warnings } = await retry(
1078
- () => model.doStream({
1079
- mode: { type: "object-grammar", schema: jsonSchema },
1080
- ...settings,
1081
- inputFormat: getInputFormat({ prompt, messages }),
1082
- prompt: convertToLanguageModelPrompt({
1083
- system: injectJsonSchemaIntoSystem({ system, schema: jsonSchema }),
1084
- prompt,
1085
- messages
1086
- }),
1087
- abortSignal
1088
- })
1089
- );
1090
- modelStream = stream.pipeThrough(
1091
- new TransformStream({
1092
- transform(chunk, controller) {
1093
- switch (chunk.type) {
1094
- case "text-delta":
1095
- controller.enqueue(chunk.textDelta);
1096
- break;
1097
- case "error":
1098
- controller.enqueue(chunk);
1099
- break;
1100
- }
1234
+ callOptions = {
1235
+ mode: { type: "object-grammar", schema: jsonSchema },
1236
+ ...settings,
1237
+ inputFormat: getInputFormat({ prompt, messages }),
1238
+ prompt: convertToLanguageModelPrompt({
1239
+ system: injectJsonSchemaIntoSystem({ system, schema: jsonSchema }),
1240
+ prompt,
1241
+ messages
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;
1101
1254
  }
1102
- })
1103
- );
1255
+ }
1256
+ };
1104
1257
  break;
1105
1258
  }
1106
1259
  case "tool": {
1107
- const { stream, warnings } = await retry(
1108
- () => model.doStream({
1109
- mode: {
1110
- type: "object-tool",
1111
- tool: {
1112
- type: "function",
1113
- name: "json",
1114
- description: "Respond with a JSON object.",
1115
- parameters: jsonSchema
1116
- }
1117
- },
1118
- ...settings,
1119
- inputFormat: getInputFormat({ prompt, messages }),
1120
- prompt: convertToLanguageModelPrompt({ system, prompt, messages }),
1121
- abortSignal
1122
- })
1123
- );
1124
- modelStream = stream.pipeThrough(
1125
- new TransformStream({
1126
- transform(chunk, controller) {
1127
- switch (chunk.type) {
1128
- case "tool-call-delta":
1129
- controller.enqueue(chunk.argsTextDelta);
1130
- break;
1131
- case "error":
1132
- controller.enqueue(chunk);
1133
- break;
1134
- }
1260
+ callOptions = {
1261
+ mode: {
1262
+ type: "object-tool",
1263
+ tool: {
1264
+ type: "function",
1265
+ name: "json",
1266
+ description: "Respond with a JSON object.",
1267
+ parameters: jsonSchema
1135
1268
  }
1136
- })
1137
- );
1269
+ },
1270
+ ...settings,
1271
+ inputFormat: getInputFormat({ prompt, messages }),
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;
1284
+ }
1285
+ }
1286
+ };
1138
1287
  break;
1139
1288
  }
1140
1289
  case void 0: {
@@ -1145,37 +1294,35 @@ async function streamObject({
1145
1294
  throw new Error(`Unsupported mode: ${_exhaustiveCheck}`);
1146
1295
  }
1147
1296
  }
1148
- return new StreamObjectResult(modelStream);
1297
+ const { stream, warnings } = await retry(() => model.doStream(callOptions));
1298
+ return new StreamObjectResult(
1299
+ stream.pipeThrough(new TransformStream(transformer))
1300
+ );
1149
1301
  }
1150
1302
  var StreamObjectResult = class {
1151
- constructor(modelStream) {
1303
+ constructor(stream) {
1304
+ this.originalStream = stream;
1305
+ }
1306
+ get objectStream() {
1152
1307
  let accumulatedText = "";
1153
1308
  let latestObject = void 0;
1154
- this.objectStream = {
1155
- [Symbol.asyncIterator]() {
1156
- const reader = modelStream.getReader();
1157
- return {
1158
- next: async () => {
1159
- while (true) {
1160
- const { done, value } = await reader.read();
1161
- if (done) {
1162
- return { value: null, done: true };
1163
- }
1164
- if (typeof value === "string") {
1165
- accumulatedText += value;
1166
- const currentObject = parsePartialJson(
1167
- accumulatedText
1168
- );
1169
- if (!isDeepEqualData(latestObject, currentObject)) {
1170
- latestObject = currentObject;
1171
- return { value: currentObject, done: false };
1172
- }
1173
- }
1174
- }
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);
1175
1319
  }
1176
- };
1320
+ }
1321
+ if (typeof chunk === "object" && chunk.type === "error") {
1322
+ throw chunk.error;
1323
+ }
1177
1324
  }
1178
- };
1325
+ });
1179
1326
  }
1180
1327
  };
1181
1328
 
@@ -1189,26 +1336,33 @@ function parseToolCall({
1189
1336
  }) {
1190
1337
  const toolName = toolCall.toolName;
1191
1338
  if (tools == null) {
1192
- 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
+ });
1193
1343
  }
1194
1344
  const tool2 = tools[toolName];
1195
1345
  if (tool2 == null) {
1196
- throw new Error(`Tool not found: ${toolName}`);
1346
+ throw new NoSuchToolError({
1347
+ message: `Tool ${toolCall.toolName} not found.`,
1348
+ toolName: toolCall.toolName
1349
+ });
1197
1350
  }
1198
1351
  const parseResult = safeParseJSON({
1199
1352
  text: toolCall.args,
1200
1353
  schema: tool2.parameters
1201
1354
  });
1202
1355
  if (parseResult.success === false) {
1203
- throw new Error(
1204
- `Tool call ${toolName} has invalid arguments: ${parseResult.error}`
1205
- );
1356
+ throw new InvalidToolArgumentsError({
1357
+ toolName,
1358
+ toolArgs: toolCall.args,
1359
+ cause: parseResult.error
1360
+ });
1206
1361
  }
1207
- const toolArgs = parseResult.value;
1208
1362
  return {
1209
1363
  toolCallId: toolCall.toolCallId,
1210
1364
  toolName,
1211
- args: toolArgs
1365
+ args: parseResult.value
1212
1366
  };
1213
1367
  }
1214
1368
 
@@ -1236,7 +1390,7 @@ async function generateText({
1236
1390
  parameters: (0, import_zod_to_json_schema3.default)(tool2.parameters)
1237
1391
  }))
1238
1392
  },
1239
- ...validateCallSettings(settings),
1393
+ ...prepareCallSettings(settings),
1240
1394
  inputFormat: getInputFormat({ prompt, messages }),
1241
1395
  prompt: convertToLanguageModelPrompt({
1242
1396
  system,
@@ -1298,6 +1452,243 @@ var GenerateTextResult = class {
1298
1452
  // core/generate-text/stream-text.ts
1299
1453
  var import_zod_to_json_schema4 = __toESM(require("zod-to-json-schema"));
1300
1454
 
1455
+ // shared/stream-parts.ts
1456
+ var textStreamPart = {
1457
+ code: "0",
1458
+ name: "text",
1459
+ parse: (value) => {
1460
+ if (typeof value !== "string") {
1461
+ throw new Error('"text" parts expect a string value.');
1462
+ }
1463
+ return { type: "text", value };
1464
+ }
1465
+ };
1466
+ var functionCallStreamPart = {
1467
+ code: "1",
1468
+ name: "function_call",
1469
+ parse: (value) => {
1470
+ if (value == null || typeof value !== "object" || !("function_call" in value) || typeof value.function_call !== "object" || value.function_call == null || !("name" in value.function_call) || !("arguments" in value.function_call) || typeof value.function_call.name !== "string" || typeof value.function_call.arguments !== "string") {
1471
+ throw new Error(
1472
+ '"function_call" parts expect an object with a "function_call" property.'
1473
+ );
1474
+ }
1475
+ return {
1476
+ type: "function_call",
1477
+ value
1478
+ };
1479
+ }
1480
+ };
1481
+ var dataStreamPart = {
1482
+ code: "2",
1483
+ name: "data",
1484
+ parse: (value) => {
1485
+ if (!Array.isArray(value)) {
1486
+ throw new Error('"data" parts expect an array value.');
1487
+ }
1488
+ return { type: "data", value };
1489
+ }
1490
+ };
1491
+ var errorStreamPart = {
1492
+ code: "3",
1493
+ name: "error",
1494
+ parse: (value) => {
1495
+ if (typeof value !== "string") {
1496
+ throw new Error('"error" parts expect a string value.');
1497
+ }
1498
+ return { type: "error", value };
1499
+ }
1500
+ };
1501
+ var assistantMessageStreamPart = {
1502
+ code: "4",
1503
+ name: "assistant_message",
1504
+ parse: (value) => {
1505
+ if (value == null || typeof value !== "object" || !("id" in value) || !("role" in value) || !("content" in value) || typeof value.id !== "string" || typeof value.role !== "string" || value.role !== "assistant" || !Array.isArray(value.content) || !value.content.every(
1506
+ (item) => item != null && typeof item === "object" && "type" in item && item.type === "text" && "text" in item && item.text != null && typeof item.text === "object" && "value" in item.text && typeof item.text.value === "string"
1507
+ )) {
1508
+ throw new Error(
1509
+ '"assistant_message" parts expect an object with an "id", "role", and "content" property.'
1510
+ );
1511
+ }
1512
+ return {
1513
+ type: "assistant_message",
1514
+ value
1515
+ };
1516
+ }
1517
+ };
1518
+ var assistantControlDataStreamPart = {
1519
+ code: "5",
1520
+ name: "assistant_control_data",
1521
+ parse: (value) => {
1522
+ if (value == null || typeof value !== "object" || !("threadId" in value) || !("messageId" in value) || typeof value.threadId !== "string" || typeof value.messageId !== "string") {
1523
+ throw new Error(
1524
+ '"assistant_control_data" parts expect an object with a "threadId" and "messageId" property.'
1525
+ );
1526
+ }
1527
+ return {
1528
+ type: "assistant_control_data",
1529
+ value: {
1530
+ threadId: value.threadId,
1531
+ messageId: value.messageId
1532
+ }
1533
+ };
1534
+ }
1535
+ };
1536
+ var dataMessageStreamPart = {
1537
+ code: "6",
1538
+ name: "data_message",
1539
+ parse: (value) => {
1540
+ if (value == null || typeof value !== "object" || !("role" in value) || !("data" in value) || typeof value.role !== "string" || value.role !== "data") {
1541
+ throw new Error(
1542
+ '"data_message" parts expect an object with a "role" and "data" property.'
1543
+ );
1544
+ }
1545
+ return {
1546
+ type: "data_message",
1547
+ value
1548
+ };
1549
+ }
1550
+ };
1551
+ var toolCallStreamPart = {
1552
+ code: "7",
1553
+ name: "tool_calls",
1554
+ parse: (value) => {
1555
+ if (value == null || typeof value !== "object" || !("tool_calls" in value) || typeof value.tool_calls !== "object" || value.tool_calls == null || !Array.isArray(value.tool_calls) || value.tool_calls.some((tc) => {
1556
+ tc == null || typeof tc !== "object" || !("id" in tc) || typeof tc.id !== "string" || !("type" in tc) || typeof tc.type !== "string" || !("function" in tc) || tc.function == null || typeof tc.function !== "object" || !("arguments" in tc.function) || typeof tc.function.name !== "string" || typeof tc.function.arguments !== "string";
1557
+ })) {
1558
+ throw new Error(
1559
+ '"tool_calls" parts expect an object with a ToolCallPayload.'
1560
+ );
1561
+ }
1562
+ return {
1563
+ type: "tool_calls",
1564
+ value
1565
+ };
1566
+ }
1567
+ };
1568
+ var messageAnnotationsStreamPart = {
1569
+ code: "8",
1570
+ name: "message_annotations",
1571
+ parse: (value) => {
1572
+ if (!Array.isArray(value)) {
1573
+ throw new Error('"message_annotations" parts expect an array value.');
1574
+ }
1575
+ return { type: "message_annotations", value };
1576
+ }
1577
+ };
1578
+ var streamParts = [
1579
+ textStreamPart,
1580
+ functionCallStreamPart,
1581
+ dataStreamPart,
1582
+ errorStreamPart,
1583
+ assistantMessageStreamPart,
1584
+ assistantControlDataStreamPart,
1585
+ dataMessageStreamPart,
1586
+ toolCallStreamPart,
1587
+ messageAnnotationsStreamPart
1588
+ ];
1589
+ var streamPartsByCode = {
1590
+ [textStreamPart.code]: textStreamPart,
1591
+ [functionCallStreamPart.code]: functionCallStreamPart,
1592
+ [dataStreamPart.code]: dataStreamPart,
1593
+ [errorStreamPart.code]: errorStreamPart,
1594
+ [assistantMessageStreamPart.code]: assistantMessageStreamPart,
1595
+ [assistantControlDataStreamPart.code]: assistantControlDataStreamPart,
1596
+ [dataMessageStreamPart.code]: dataMessageStreamPart,
1597
+ [toolCallStreamPart.code]: toolCallStreamPart,
1598
+ [messageAnnotationsStreamPart.code]: messageAnnotationsStreamPart
1599
+ };
1600
+ var StreamStringPrefixes = {
1601
+ [textStreamPart.name]: textStreamPart.code,
1602
+ [functionCallStreamPart.name]: functionCallStreamPart.code,
1603
+ [dataStreamPart.name]: dataStreamPart.code,
1604
+ [errorStreamPart.name]: errorStreamPart.code,
1605
+ [assistantMessageStreamPart.name]: assistantMessageStreamPart.code,
1606
+ [assistantControlDataStreamPart.name]: assistantControlDataStreamPart.code,
1607
+ [dataMessageStreamPart.name]: dataMessageStreamPart.code,
1608
+ [toolCallStreamPart.name]: toolCallStreamPart.code,
1609
+ [messageAnnotationsStreamPart.name]: messageAnnotationsStreamPart.code
1610
+ };
1611
+ var validCodes = streamParts.map((part) => part.code);
1612
+ function formatStreamPart(type, value) {
1613
+ const streamPart = streamParts.find((part) => part.name === type);
1614
+ if (!streamPart) {
1615
+ throw new Error(`Invalid stream part type: ${type}`);
1616
+ }
1617
+ return `${streamPart.code}:${JSON.stringify(value)}
1618
+ `;
1619
+ }
1620
+
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
+ }
1691
+
1301
1692
  // core/generate-text/run-tools-transformation.ts
1302
1693
  var import_nanoid = require("nanoid");
1303
1694
  function runToolsTransformation({
@@ -1326,7 +1717,10 @@ function runToolsTransformation({
1326
1717
  if (tools == null) {
1327
1718
  toolResultsStreamController.enqueue({
1328
1719
  type: "error",
1329
- error: `Tool ${chunk.toolName} not found (no tools provided)`
1720
+ error: new NoSuchToolError({
1721
+ message: `Tool ${chunk.toolName} not found (no tools provided).`,
1722
+ toolName: chunk.toolName
1723
+ })
1330
1724
  });
1331
1725
  break;
1332
1726
  }
@@ -1334,44 +1728,54 @@ function runToolsTransformation({
1334
1728
  if (tool2 == null) {
1335
1729
  toolResultsStreamController.enqueue({
1336
1730
  type: "error",
1337
- error: `Tool ${chunk.toolName} not found`
1731
+ error: new NoSuchToolError({
1732
+ message: `Tool ${chunk.toolName} not found.`,
1733
+ toolName: chunk.toolName
1734
+ })
1338
1735
  });
1339
1736
  break;
1340
1737
  }
1341
- const toolCall = parseToolCall({
1342
- toolCall: chunk,
1343
- tools
1344
- });
1345
- controller.enqueue({
1346
- type: "tool-call",
1347
- ...toolCall
1348
- });
1349
- if (tool2.execute != null) {
1350
- const toolExecutionId = (0, import_nanoid.nanoid)();
1351
- outstandingToolCalls.add(toolExecutionId);
1352
- tool2.execute(toolCall.args).then(
1353
- (result) => {
1354
- toolResultsStreamController.enqueue({
1355
- type: "tool-result",
1356
- ...toolCall,
1357
- result
1358
- });
1359
- outstandingToolCalls.delete(toolExecutionId);
1360
- if (canClose && outstandingToolCalls.size === 0) {
1361
- toolResultsStreamController.close();
1362
- }
1363
- },
1364
- (error) => {
1365
- toolResultsStreamController.enqueue({
1366
- type: "error",
1367
- error
1368
- });
1369
- outstandingToolCalls.delete(toolExecutionId);
1370
- if (canClose && outstandingToolCalls.size === 0) {
1371
- toolResultsStreamController.close();
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
+ }
1372
1771
  }
1373
- }
1374
- );
1772
+ );
1773
+ }
1774
+ } catch (error) {
1775
+ toolResultsStreamController.enqueue({
1776
+ type: "error",
1777
+ error
1778
+ });
1375
1779
  }
1376
1780
  break;
1377
1781
  }
@@ -1440,7 +1844,7 @@ async function streamText({
1440
1844
  parameters: (0, import_zod_to_json_schema4.default)(tool2.parameters)
1441
1845
  }))
1442
1846
  },
1443
- ...validateCallSettings(settings),
1847
+ ...prepareCallSettings(settings),
1444
1848
  inputFormat: getInputFormat({ prompt, messages }),
1445
1849
  prompt: convertToLanguageModelPrompt({
1446
1850
  system,
@@ -1458,52 +1862,38 @@ async function streamText({
1458
1862
  }
1459
1863
  var StreamTextResult = class {
1460
1864
  constructor(stream) {
1461
- this.rootStream = stream;
1462
- this.textStream = {
1463
- [Symbol.asyncIterator]() {
1464
- const reader = stream.getReader();
1465
- return {
1466
- next: async () => {
1467
- while (true) {
1468
- const { done, value } = await reader.read();
1469
- if (done) {
1470
- return { value: null, done: true };
1471
- }
1472
- if (value.type === "text-delta") {
1473
- if (value.textDelta.length > 0) {
1474
- return { value: value.textDelta, done: false };
1475
- }
1476
- }
1477
- if (value.type === "error") {
1478
- console.error("Error:", value.error);
1479
- }
1480
- }
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);
1481
1873
  }
1482
- };
1874
+ } else if (chunk.type === "error") {
1875
+ throw chunk.error;
1876
+ }
1483
1877
  }
1484
- };
1485
- this.fullStream = {
1486
- [Symbol.asyncIterator]() {
1487
- const reader = stream.getReader();
1488
- return {
1489
- next: async () => {
1490
- while (true) {
1491
- const { done, value } = await reader.read();
1492
- if (done) {
1493
- return { value: null, done: true };
1494
- }
1495
- if (value.type === "text-delta") {
1496
- if (value.textDelta.length > 0) {
1497
- return { value, done: false };
1498
- }
1499
- } else {
1500
- return { value, done: false };
1501
- }
1502
- }
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);
1503
1886
  }
1504
- };
1887
+ } else {
1888
+ controller.enqueue(chunk);
1889
+ }
1505
1890
  }
1506
- };
1891
+ });
1892
+ }
1893
+ toAIStream(callbacks) {
1894
+ return readableFromAsyncIterable(this.textStream).pipeThrough(createCallbacksTransformer(callbacks)).pipeThrough(
1895
+ createStreamDataTransformer(callbacks == null ? void 0 : callbacks.experimental_streamData)
1896
+ );
1507
1897
  }
1508
1898
  };
1509
1899