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.
@@ -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,46 +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
- // ai-model-specification/errors/retry-error.ts
82
- var RetryError = class extends Error {
83
- constructor({
84
- message,
85
- reason,
86
- errors
87
- }) {
88
- super(message);
89
- this.name = "RetryError";
90
- this.reason = reason;
91
- this.errors = errors;
92
- this.lastError = errors[errors.length - 1];
93
- }
94
- toJSON() {
95
- return {
96
- name: this.name,
97
- message: this.message,
98
- reason: this.reason,
99
- lastError: this.lastError,
100
- errors: this.errors
101
- };
102
- }
103
- };
104
-
105
116
  // ai-model-specification/errors/type-validation-error.ts
106
117
  var TypeValidationError = class extends Error {
107
118
  constructor({ value, cause }) {
@@ -109,10 +120,13 @@ var TypeValidationError = class extends Error {
109
120
  `Type validation failed: Value: ${JSON.stringify(value)}.
110
121
  Error message: ${getErrorMessage(cause)}`
111
122
  );
112
- this.name = "TypeValidationError";
123
+ this.name = "AI_TypeValidationError";
113
124
  this.cause = cause;
114
125
  this.value = value;
115
126
  }
127
+ static isTypeValidationError(error) {
128
+ return error instanceof Error && error.name === "AI_TypeValidationError" && typeof error.value === "string" && typeof error.cause === "string";
129
+ }
116
130
  toJSON() {
117
131
  return {
118
132
  name: this.name,
@@ -124,9 +138,6 @@ Error message: ${getErrorMessage(cause)}`
124
138
  }
125
139
  };
126
140
 
127
- // ai-model-specification/util/parse-json.ts
128
- import SecureJSON from "secure-json-parse";
129
-
130
141
  // ai-model-specification/util/validate-types.ts
131
142
  function safeValidateTypes({
132
143
  value,
@@ -150,7 +161,7 @@ function safeValidateTypes({
150
161
  } catch (error) {
151
162
  return {
152
163
  success: false,
153
- error: error instanceof TypeValidationError ? error : new TypeValidationError({ value, cause: error })
164
+ error: TypeValidationError.isTypeValidationError(error) ? error : new TypeValidationError({ value, cause: error })
154
165
  };
155
166
  }
156
167
  }
@@ -172,7 +183,7 @@ function safeParseJSON({
172
183
  } catch (error) {
173
184
  return {
174
185
  success: false,
175
- error: error instanceof JSONParseError ? error : new JSONParseError({ text, cause: error })
186
+ error: JSONParseError.isJSONParseError(error) ? error : new JSONParseError({ text, cause: error })
176
187
  };
177
188
  }
178
189
  }
@@ -191,6 +202,103 @@ function convertUint8ArrayToBase64(array) {
191
202
  return globalThis.btoa(latin1string);
192
203
  }
193
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
+
194
302
  // core/generate-text/token-usage.ts
195
303
  function calculateTokenUsage(usage) {
196
304
  return {
@@ -311,98 +419,130 @@ function getInputFormat({
311
419
  return prompt != null ? "prompt" : "messages";
312
420
  }
313
421
 
314
- // core/prompt/validate-call-settings.ts
315
- function validateCallSettings(settings) {
316
- if (settings.maxTokens != null) {
317
- if (!Number.isInteger(settings.maxTokens)) {
318
- 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({
319
435
  parameter: "maxTokens",
320
- value: settings.maxTokens,
436
+ value: maxTokens,
321
437
  message: "maxTokens must be an integer"
322
438
  });
323
439
  }
324
- if (settings.maxTokens < 1) {
325
- throw new AI_InvalidArgumentError({
440
+ if (maxTokens < 1) {
441
+ throw new InvalidArgumentError({
326
442
  parameter: "maxTokens",
327
- value: settings.maxTokens,
443
+ value: maxTokens,
328
444
  message: "maxTokens must be >= 1"
329
445
  });
330
446
  }
331
447
  }
332
- if (settings.temperature != null) {
333
- if (typeof settings.temperature !== "number") {
334
- throw new AI_InvalidArgumentError({
448
+ if (temperature != null) {
449
+ if (typeof temperature !== "number") {
450
+ throw new InvalidArgumentError({
335
451
  parameter: "temperature",
336
- value: settings.temperature,
452
+ value: temperature,
337
453
  message: "temperature must be a number"
338
454
  });
339
455
  }
340
- if (settings.temperature < 0 || settings.temperature > 1) {
341
- throw new AI_InvalidArgumentError({
456
+ if (temperature < 0 || temperature > 1) {
457
+ throw new InvalidArgumentError({
342
458
  parameter: "temperature",
343
- value: settings.temperature,
459
+ value: temperature,
344
460
  message: "temperature must be between 0 and 1 (inclusive)"
345
461
  });
346
462
  }
347
463
  }
348
- if (settings.topP != null) {
349
- if (typeof settings.topP !== "number") {
350
- throw new AI_InvalidArgumentError({
464
+ if (topP != null) {
465
+ if (typeof topP !== "number") {
466
+ throw new InvalidArgumentError({
351
467
  parameter: "topP",
352
- value: settings.topP,
468
+ value: topP,
353
469
  message: "topP must be a number"
354
470
  });
355
471
  }
356
- if (settings.topP < 0 || settings.topP > 1) {
357
- throw new AI_InvalidArgumentError({
472
+ if (topP < 0 || topP > 1) {
473
+ throw new InvalidArgumentError({
358
474
  parameter: "topP",
359
- value: settings.topP,
475
+ value: topP,
360
476
  message: "topP must be between 0 and 1 (inclusive)"
361
477
  });
362
478
  }
363
479
  }
364
- if (settings.presencePenalty != null) {
365
- if (typeof settings.presencePenalty !== "number") {
366
- throw new AI_InvalidArgumentError({
480
+ if (presencePenalty != null) {
481
+ if (typeof presencePenalty !== "number") {
482
+ throw new InvalidArgumentError({
367
483
  parameter: "presencePenalty",
368
- value: settings.presencePenalty,
484
+ value: presencePenalty,
369
485
  message: "presencePenalty must be a number"
370
486
  });
371
487
  }
372
- if (settings.presencePenalty < -1 || settings.presencePenalty > 1) {
373
- throw new AI_InvalidArgumentError({
488
+ if (presencePenalty < -1 || presencePenalty > 1) {
489
+ throw new InvalidArgumentError({
374
490
  parameter: "presencePenalty",
375
- value: settings.presencePenalty,
491
+ value: presencePenalty,
376
492
  message: "presencePenalty must be between -1 and 1 (inclusive)"
377
493
  });
378
494
  }
379
495
  }
380
- if (settings.frequencyPenalty != null) {
381
- if (typeof settings.frequencyPenalty !== "number") {
382
- throw new AI_InvalidArgumentError({
496
+ if (frequencyPenalty != null) {
497
+ if (typeof frequencyPenalty !== "number") {
498
+ throw new InvalidArgumentError({
383
499
  parameter: "frequencyPenalty",
384
- value: settings.frequencyPenalty,
500
+ value: frequencyPenalty,
385
501
  message: "frequencyPenalty must be a number"
386
502
  });
387
503
  }
388
- if (settings.frequencyPenalty < -1 || settings.frequencyPenalty > 1) {
389
- throw new AI_InvalidArgumentError({
504
+ if (frequencyPenalty < -1 || frequencyPenalty > 1) {
505
+ throw new InvalidArgumentError({
390
506
  parameter: "frequencyPenalty",
391
- value: settings.frequencyPenalty,
507
+ value: frequencyPenalty,
392
508
  message: "frequencyPenalty must be between -1 and 1 (inclusive)"
393
509
  });
394
510
  }
395
511
  }
396
- if (settings.seed != null) {
397
- if (!Number.isInteger(settings.seed)) {
398
- throw new AI_InvalidArgumentError({
512
+ if (seed != null) {
513
+ if (!Number.isInteger(seed)) {
514
+ throw new InvalidArgumentError({
399
515
  parameter: "seed",
400
- value: settings.seed,
516
+ value: seed,
401
517
  message: "seed must be an integer"
402
518
  });
403
519
  }
404
520
  }
405
- 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
+ };
406
546
  }
407
547
 
408
548
  // core/util/delay.ts
@@ -436,7 +576,7 @@ async function _retryWithExponentialBackoff(f, {
436
576
  const tryNumber = newErrors.length;
437
577
  if (tryNumber > maxRetries) {
438
578
  throw new RetryError({
439
- message: `Failed after ${tryNumber} tries. Last error: ${errorMessage}`,
579
+ message: `Failed after ${tryNumber} attemps. Last error: ${errorMessage}`,
440
580
  reason: "maxRetriesExceeded",
441
581
  errors: newErrors
442
582
  });
@@ -447,7 +587,7 @@ async function _retryWithExponentialBackoff(f, {
447
587
  }
448
588
  if (
449
589
  // deal with bundling duplication by using names
450
- error.name === "ApiCallError" && error.isRetryable === true && tryNumber <= maxRetries
590
+ APICallError.isAPICallError(error) && error.isRetryable === true && tryNumber <= maxRetries
451
591
  ) {
452
592
  await delay(delayInMs);
453
593
  return _retryWithExponentialBackoff(
@@ -457,8 +597,11 @@ async function _retryWithExponentialBackoff(f, {
457
597
  );
458
598
  }
459
599
  }
600
+ if (tryNumber === 1) {
601
+ throw error;
602
+ }
460
603
  throw new RetryError({
461
- message: `Failed after ${tryNumber} tries with non-retryable error: '${errorMessage}'`,
604
+ message: `Failed after ${tryNumber} attemps with non-retryable error: '${errorMessage}'`,
462
605
  reason: "errorNotRetryable",
463
606
  errors: newErrors
464
607
  });
@@ -510,7 +653,7 @@ async function generateObject({
510
653
  const generateResult = await retry(
511
654
  () => model.doGenerate({
512
655
  mode: { type: "object-json" },
513
- ...validateCallSettings(settings),
656
+ ...prepareCallSettings(settings),
514
657
  inputFormat: getInputFormat({ prompt, messages }),
515
658
  prompt: convertToLanguageModelPrompt({
516
659
  system: injectJsonSchemaIntoSystem({ system, schema: jsonSchema }),
@@ -606,6 +749,23 @@ var GenerateObjectResult = class {
606
749
  // core/generate-object/stream-object.ts
607
750
  import zodToJsonSchema2 from "zod-to-json-schema";
608
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
+
609
769
  // core/util/is-deep-equal-data.ts
610
770
  function isDeepEqualData(obj1, obj2) {
611
771
  if (obj1 === obj2)
@@ -992,103 +1152,92 @@ async function streamObject({
992
1152
  }) {
993
1153
  const retry = retryWithExponentialBackoff({ maxRetries });
994
1154
  const jsonSchema = zodToJsonSchema2(schema);
995
- let modelStream;
996
1155
  if (mode === "auto" || mode == null) {
997
1156
  mode = model.defaultObjectGenerationMode;
998
1157
  }
1158
+ let callOptions;
1159
+ let transformer;
999
1160
  switch (mode) {
1000
1161
  case "json": {
1001
- const { stream, warnings } = await retry(
1002
- () => model.doStream({
1003
- mode: { type: "object-json" },
1004
- ...validateCallSettings(settings),
1005
- inputFormat: getInputFormat({ prompt, messages }),
1006
- prompt: convertToLanguageModelPrompt({
1007
- system: injectJsonSchemaIntoSystem({ system, schema: jsonSchema }),
1008
- prompt,
1009
- messages
1010
- }),
1011
- abortSignal
1012
- })
1013
- );
1014
- modelStream = stream.pipeThrough(
1015
- new TransformStream({
1016
- transform(chunk, controller) {
1017
- switch (chunk.type) {
1018
- case "text-delta":
1019
- controller.enqueue(chunk.textDelta);
1020
- break;
1021
- case "error":
1022
- controller.enqueue(chunk);
1023
- break;
1024
- }
1162
+ callOptions = {
1163
+ mode: { type: "object-json" },
1164
+ ...prepareCallSettings(settings),
1165
+ inputFormat: getInputFormat({ prompt, messages }),
1166
+ prompt: convertToLanguageModelPrompt({
1167
+ system: injectJsonSchemaIntoSystem({ system, schema: jsonSchema }),
1168
+ prompt,
1169
+ messages
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;
1025
1182
  }
1026
- })
1027
- );
1183
+ }
1184
+ };
1028
1185
  break;
1029
1186
  }
1030
1187
  case "grammar": {
1031
- const { stream, warnings } = await retry(
1032
- () => model.doStream({
1033
- mode: { type: "object-grammar", schema: jsonSchema },
1034
- ...settings,
1035
- inputFormat: getInputFormat({ prompt, messages }),
1036
- prompt: convertToLanguageModelPrompt({
1037
- system: injectJsonSchemaIntoSystem({ system, schema: jsonSchema }),
1038
- prompt,
1039
- messages
1040
- }),
1041
- abortSignal
1042
- })
1043
- );
1044
- modelStream = stream.pipeThrough(
1045
- new TransformStream({
1046
- transform(chunk, controller) {
1047
- switch (chunk.type) {
1048
- case "text-delta":
1049
- controller.enqueue(chunk.textDelta);
1050
- break;
1051
- case "error":
1052
- controller.enqueue(chunk);
1053
- break;
1054
- }
1188
+ callOptions = {
1189
+ mode: { type: "object-grammar", schema: jsonSchema },
1190
+ ...settings,
1191
+ inputFormat: getInputFormat({ prompt, messages }),
1192
+ prompt: convertToLanguageModelPrompt({
1193
+ system: injectJsonSchemaIntoSystem({ system, schema: jsonSchema }),
1194
+ prompt,
1195
+ messages
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;
1055
1208
  }
1056
- })
1057
- );
1209
+ }
1210
+ };
1058
1211
  break;
1059
1212
  }
1060
1213
  case "tool": {
1061
- const { stream, warnings } = await retry(
1062
- () => model.doStream({
1063
- mode: {
1064
- type: "object-tool",
1065
- tool: {
1066
- type: "function",
1067
- name: "json",
1068
- description: "Respond with a JSON object.",
1069
- parameters: jsonSchema
1070
- }
1071
- },
1072
- ...settings,
1073
- inputFormat: getInputFormat({ prompt, messages }),
1074
- prompt: convertToLanguageModelPrompt({ system, prompt, messages }),
1075
- abortSignal
1076
- })
1077
- );
1078
- modelStream = stream.pipeThrough(
1079
- new TransformStream({
1080
- transform(chunk, controller) {
1081
- switch (chunk.type) {
1082
- case "tool-call-delta":
1083
- controller.enqueue(chunk.argsTextDelta);
1084
- break;
1085
- case "error":
1086
- controller.enqueue(chunk);
1087
- break;
1088
- }
1214
+ callOptions = {
1215
+ mode: {
1216
+ type: "object-tool",
1217
+ tool: {
1218
+ type: "function",
1219
+ name: "json",
1220
+ description: "Respond with a JSON object.",
1221
+ parameters: jsonSchema
1089
1222
  }
1090
- })
1091
- );
1223
+ },
1224
+ ...settings,
1225
+ inputFormat: getInputFormat({ prompt, messages }),
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;
1238
+ }
1239
+ }
1240
+ };
1092
1241
  break;
1093
1242
  }
1094
1243
  case void 0: {
@@ -1099,37 +1248,35 @@ async function streamObject({
1099
1248
  throw new Error(`Unsupported mode: ${_exhaustiveCheck}`);
1100
1249
  }
1101
1250
  }
1102
- return new StreamObjectResult(modelStream);
1251
+ const { stream, warnings } = await retry(() => model.doStream(callOptions));
1252
+ return new StreamObjectResult(
1253
+ stream.pipeThrough(new TransformStream(transformer))
1254
+ );
1103
1255
  }
1104
1256
  var StreamObjectResult = class {
1105
- constructor(modelStream) {
1257
+ constructor(stream) {
1258
+ this.originalStream = stream;
1259
+ }
1260
+ get objectStream() {
1106
1261
  let accumulatedText = "";
1107
1262
  let latestObject = void 0;
1108
- this.objectStream = {
1109
- [Symbol.asyncIterator]() {
1110
- const reader = modelStream.getReader();
1111
- return {
1112
- next: async () => {
1113
- while (true) {
1114
- const { done, value } = await reader.read();
1115
- if (done) {
1116
- return { value: null, done: true };
1117
- }
1118
- if (typeof value === "string") {
1119
- accumulatedText += value;
1120
- const currentObject = parsePartialJson(
1121
- accumulatedText
1122
- );
1123
- if (!isDeepEqualData(latestObject, currentObject)) {
1124
- latestObject = currentObject;
1125
- return { value: currentObject, done: false };
1126
- }
1127
- }
1128
- }
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);
1129
1273
  }
1130
- };
1274
+ }
1275
+ if (typeof chunk === "object" && chunk.type === "error") {
1276
+ throw chunk.error;
1277
+ }
1131
1278
  }
1132
- };
1279
+ });
1133
1280
  }
1134
1281
  };
1135
1282
 
@@ -1143,26 +1290,33 @@ function parseToolCall({
1143
1290
  }) {
1144
1291
  const toolName = toolCall.toolName;
1145
1292
  if (tools == null) {
1146
- 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
+ });
1147
1297
  }
1148
1298
  const tool2 = tools[toolName];
1149
1299
  if (tool2 == null) {
1150
- throw new Error(`Tool not found: ${toolName}`);
1300
+ throw new NoSuchToolError({
1301
+ message: `Tool ${toolCall.toolName} not found.`,
1302
+ toolName: toolCall.toolName
1303
+ });
1151
1304
  }
1152
1305
  const parseResult = safeParseJSON({
1153
1306
  text: toolCall.args,
1154
1307
  schema: tool2.parameters
1155
1308
  });
1156
1309
  if (parseResult.success === false) {
1157
- throw new Error(
1158
- `Tool call ${toolName} has invalid arguments: ${parseResult.error}`
1159
- );
1310
+ throw new InvalidToolArgumentsError({
1311
+ toolName,
1312
+ toolArgs: toolCall.args,
1313
+ cause: parseResult.error
1314
+ });
1160
1315
  }
1161
- const toolArgs = parseResult.value;
1162
1316
  return {
1163
1317
  toolCallId: toolCall.toolCallId,
1164
1318
  toolName,
1165
- args: toolArgs
1319
+ args: parseResult.value
1166
1320
  };
1167
1321
  }
1168
1322
 
@@ -1190,7 +1344,7 @@ async function generateText({
1190
1344
  parameters: zodToJsonSchema3(tool2.parameters)
1191
1345
  }))
1192
1346
  },
1193
- ...validateCallSettings(settings),
1347
+ ...prepareCallSettings(settings),
1194
1348
  inputFormat: getInputFormat({ prompt, messages }),
1195
1349
  prompt: convertToLanguageModelPrompt({
1196
1350
  system,
@@ -1252,6 +1406,245 @@ var GenerateTextResult = class {
1252
1406
  // core/generate-text/stream-text.ts
1253
1407
  import zodToJsonSchema4 from "zod-to-json-schema";
1254
1408
 
1409
+ // shared/stream-parts.ts
1410
+ var textStreamPart = {
1411
+ code: "0",
1412
+ name: "text",
1413
+ parse: (value) => {
1414
+ if (typeof value !== "string") {
1415
+ throw new Error('"text" parts expect a string value.');
1416
+ }
1417
+ return { type: "text", value };
1418
+ }
1419
+ };
1420
+ var functionCallStreamPart = {
1421
+ code: "1",
1422
+ name: "function_call",
1423
+ parse: (value) => {
1424
+ 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") {
1425
+ throw new Error(
1426
+ '"function_call" parts expect an object with a "function_call" property.'
1427
+ );
1428
+ }
1429
+ return {
1430
+ type: "function_call",
1431
+ value
1432
+ };
1433
+ }
1434
+ };
1435
+ var dataStreamPart = {
1436
+ code: "2",
1437
+ name: "data",
1438
+ parse: (value) => {
1439
+ if (!Array.isArray(value)) {
1440
+ throw new Error('"data" parts expect an array value.');
1441
+ }
1442
+ return { type: "data", value };
1443
+ }
1444
+ };
1445
+ var errorStreamPart = {
1446
+ code: "3",
1447
+ name: "error",
1448
+ parse: (value) => {
1449
+ if (typeof value !== "string") {
1450
+ throw new Error('"error" parts expect a string value.');
1451
+ }
1452
+ return { type: "error", value };
1453
+ }
1454
+ };
1455
+ var assistantMessageStreamPart = {
1456
+ code: "4",
1457
+ name: "assistant_message",
1458
+ parse: (value) => {
1459
+ 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(
1460
+ (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"
1461
+ )) {
1462
+ throw new Error(
1463
+ '"assistant_message" parts expect an object with an "id", "role", and "content" property.'
1464
+ );
1465
+ }
1466
+ return {
1467
+ type: "assistant_message",
1468
+ value
1469
+ };
1470
+ }
1471
+ };
1472
+ var assistantControlDataStreamPart = {
1473
+ code: "5",
1474
+ name: "assistant_control_data",
1475
+ parse: (value) => {
1476
+ if (value == null || typeof value !== "object" || !("threadId" in value) || !("messageId" in value) || typeof value.threadId !== "string" || typeof value.messageId !== "string") {
1477
+ throw new Error(
1478
+ '"assistant_control_data" parts expect an object with a "threadId" and "messageId" property.'
1479
+ );
1480
+ }
1481
+ return {
1482
+ type: "assistant_control_data",
1483
+ value: {
1484
+ threadId: value.threadId,
1485
+ messageId: value.messageId
1486
+ }
1487
+ };
1488
+ }
1489
+ };
1490
+ var dataMessageStreamPart = {
1491
+ code: "6",
1492
+ name: "data_message",
1493
+ parse: (value) => {
1494
+ if (value == null || typeof value !== "object" || !("role" in value) || !("data" in value) || typeof value.role !== "string" || value.role !== "data") {
1495
+ throw new Error(
1496
+ '"data_message" parts expect an object with a "role" and "data" property.'
1497
+ );
1498
+ }
1499
+ return {
1500
+ type: "data_message",
1501
+ value
1502
+ };
1503
+ }
1504
+ };
1505
+ var toolCallStreamPart = {
1506
+ code: "7",
1507
+ name: "tool_calls",
1508
+ parse: (value) => {
1509
+ 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) => {
1510
+ 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";
1511
+ })) {
1512
+ throw new Error(
1513
+ '"tool_calls" parts expect an object with a ToolCallPayload.'
1514
+ );
1515
+ }
1516
+ return {
1517
+ type: "tool_calls",
1518
+ value
1519
+ };
1520
+ }
1521
+ };
1522
+ var messageAnnotationsStreamPart = {
1523
+ code: "8",
1524
+ name: "message_annotations",
1525
+ parse: (value) => {
1526
+ if (!Array.isArray(value)) {
1527
+ throw new Error('"message_annotations" parts expect an array value.');
1528
+ }
1529
+ return { type: "message_annotations", value };
1530
+ }
1531
+ };
1532
+ var streamParts = [
1533
+ textStreamPart,
1534
+ functionCallStreamPart,
1535
+ dataStreamPart,
1536
+ errorStreamPart,
1537
+ assistantMessageStreamPart,
1538
+ assistantControlDataStreamPart,
1539
+ dataMessageStreamPart,
1540
+ toolCallStreamPart,
1541
+ messageAnnotationsStreamPart
1542
+ ];
1543
+ var streamPartsByCode = {
1544
+ [textStreamPart.code]: textStreamPart,
1545
+ [functionCallStreamPart.code]: functionCallStreamPart,
1546
+ [dataStreamPart.code]: dataStreamPart,
1547
+ [errorStreamPart.code]: errorStreamPart,
1548
+ [assistantMessageStreamPart.code]: assistantMessageStreamPart,
1549
+ [assistantControlDataStreamPart.code]: assistantControlDataStreamPart,
1550
+ [dataMessageStreamPart.code]: dataMessageStreamPart,
1551
+ [toolCallStreamPart.code]: toolCallStreamPart,
1552
+ [messageAnnotationsStreamPart.code]: messageAnnotationsStreamPart
1553
+ };
1554
+ var StreamStringPrefixes = {
1555
+ [textStreamPart.name]: textStreamPart.code,
1556
+ [functionCallStreamPart.name]: functionCallStreamPart.code,
1557
+ [dataStreamPart.name]: dataStreamPart.code,
1558
+ [errorStreamPart.name]: errorStreamPart.code,
1559
+ [assistantMessageStreamPart.name]: assistantMessageStreamPart.code,
1560
+ [assistantControlDataStreamPart.name]: assistantControlDataStreamPart.code,
1561
+ [dataMessageStreamPart.name]: dataMessageStreamPart.code,
1562
+ [toolCallStreamPart.name]: toolCallStreamPart.code,
1563
+ [messageAnnotationsStreamPart.name]: messageAnnotationsStreamPart.code
1564
+ };
1565
+ var validCodes = streamParts.map((part) => part.code);
1566
+ function formatStreamPart(type, value) {
1567
+ const streamPart = streamParts.find((part) => part.name === type);
1568
+ if (!streamPart) {
1569
+ throw new Error(`Invalid stream part type: ${type}`);
1570
+ }
1571
+ return `${streamPart.code}:${JSON.stringify(value)}
1572
+ `;
1573
+ }
1574
+
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
+ }
1647
+
1255
1648
  // core/generate-text/run-tools-transformation.ts
1256
1649
  import { nanoid } from "nanoid";
1257
1650
  function runToolsTransformation({
@@ -1280,7 +1673,10 @@ function runToolsTransformation({
1280
1673
  if (tools == null) {
1281
1674
  toolResultsStreamController.enqueue({
1282
1675
  type: "error",
1283
- error: `Tool ${chunk.toolName} not found (no tools provided)`
1676
+ error: new NoSuchToolError({
1677
+ message: `Tool ${chunk.toolName} not found (no tools provided).`,
1678
+ toolName: chunk.toolName
1679
+ })
1284
1680
  });
1285
1681
  break;
1286
1682
  }
@@ -1288,44 +1684,54 @@ function runToolsTransformation({
1288
1684
  if (tool2 == null) {
1289
1685
  toolResultsStreamController.enqueue({
1290
1686
  type: "error",
1291
- error: `Tool ${chunk.toolName} not found`
1687
+ error: new NoSuchToolError({
1688
+ message: `Tool ${chunk.toolName} not found.`,
1689
+ toolName: chunk.toolName
1690
+ })
1292
1691
  });
1293
1692
  break;
1294
1693
  }
1295
- const toolCall = parseToolCall({
1296
- toolCall: chunk,
1297
- tools
1298
- });
1299
- controller.enqueue({
1300
- type: "tool-call",
1301
- ...toolCall
1302
- });
1303
- if (tool2.execute != null) {
1304
- const toolExecutionId = nanoid();
1305
- outstandingToolCalls.add(toolExecutionId);
1306
- tool2.execute(toolCall.args).then(
1307
- (result) => {
1308
- toolResultsStreamController.enqueue({
1309
- type: "tool-result",
1310
- ...toolCall,
1311
- result
1312
- });
1313
- outstandingToolCalls.delete(toolExecutionId);
1314
- if (canClose && outstandingToolCalls.size === 0) {
1315
- toolResultsStreamController.close();
1316
- }
1317
- },
1318
- (error) => {
1319
- toolResultsStreamController.enqueue({
1320
- type: "error",
1321
- error
1322
- });
1323
- outstandingToolCalls.delete(toolExecutionId);
1324
- if (canClose && outstandingToolCalls.size === 0) {
1325
- toolResultsStreamController.close();
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
+ }
1326
1727
  }
1327
- }
1328
- );
1728
+ );
1729
+ }
1730
+ } catch (error) {
1731
+ toolResultsStreamController.enqueue({
1732
+ type: "error",
1733
+ error
1734
+ });
1329
1735
  }
1330
1736
  break;
1331
1737
  }
@@ -1394,7 +1800,7 @@ async function streamText({
1394
1800
  parameters: zodToJsonSchema4(tool2.parameters)
1395
1801
  }))
1396
1802
  },
1397
- ...validateCallSettings(settings),
1803
+ ...prepareCallSettings(settings),
1398
1804
  inputFormat: getInputFormat({ prompt, messages }),
1399
1805
  prompt: convertToLanguageModelPrompt({
1400
1806
  system,
@@ -1412,52 +1818,38 @@ async function streamText({
1412
1818
  }
1413
1819
  var StreamTextResult = class {
1414
1820
  constructor(stream) {
1415
- this.rootStream = stream;
1416
- this.textStream = {
1417
- [Symbol.asyncIterator]() {
1418
- const reader = stream.getReader();
1419
- return {
1420
- next: async () => {
1421
- while (true) {
1422
- const { done, value } = await reader.read();
1423
- if (done) {
1424
- return { value: null, done: true };
1425
- }
1426
- if (value.type === "text-delta") {
1427
- if (value.textDelta.length > 0) {
1428
- return { value: value.textDelta, done: false };
1429
- }
1430
- }
1431
- if (value.type === "error") {
1432
- console.error("Error:", value.error);
1433
- }
1434
- }
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);
1435
1829
  }
1436
- };
1830
+ } else if (chunk.type === "error") {
1831
+ throw chunk.error;
1832
+ }
1437
1833
  }
1438
- };
1439
- this.fullStream = {
1440
- [Symbol.asyncIterator]() {
1441
- const reader = stream.getReader();
1442
- return {
1443
- next: async () => {
1444
- while (true) {
1445
- const { done, value } = await reader.read();
1446
- if (done) {
1447
- return { value: null, done: true };
1448
- }
1449
- if (value.type === "text-delta") {
1450
- if (value.textDelta.length > 0) {
1451
- return { value, done: false };
1452
- }
1453
- } else {
1454
- return { value, done: false };
1455
- }
1456
- }
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);
1457
1842
  }
1458
- };
1843
+ } else {
1844
+ controller.enqueue(chunk);
1845
+ }
1459
1846
  }
1460
- };
1847
+ });
1848
+ }
1849
+ toAIStream(callbacks) {
1850
+ return readableFromAsyncIterable(this.textStream).pipeThrough(createCallbacksTransformer(callbacks)).pipeThrough(
1851
+ createStreamDataTransformer(callbacks == null ? void 0 : callbacks.experimental_streamData)
1852
+ );
1461
1853
  }
1462
1854
  };
1463
1855