ai 5.0.0-canary.18 → 5.0.0-canary.19

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,22 +1,25 @@
1
- // core/prompt/standardize-prompt.ts
2
- import { InvalidPromptError } from "@ai-sdk/provider";
3
- import { safeValidateTypes } from "@ai-sdk/provider-utils";
4
- import { z as z7 } from "zod";
1
+ // core/prompt/convert-to-language-model-prompt.ts
2
+ import { isUrlSupported } from "@ai-sdk/provider-utils";
5
3
 
6
- // core/prompt/message-conversion-error.ts
4
+ // util/download-error.ts
7
5
  import { AISDKError } from "@ai-sdk/provider";
8
- var name = "AI_MessageConversionError";
6
+ var name = "AI_DownloadError";
9
7
  var marker = `vercel.ai.error.${name}`;
10
8
  var symbol = Symbol.for(marker);
11
9
  var _a;
12
- var MessageConversionError = class extends AISDKError {
10
+ var DownloadError = class extends AISDKError {
13
11
  constructor({
14
- originalMessage,
15
- message
12
+ url,
13
+ statusCode,
14
+ statusText,
15
+ cause,
16
+ message = cause == null ? `Failed to download ${url}: ${statusCode} ${statusText}` : `Failed to download ${url}: ${cause}`
16
17
  }) {
17
- super({ name, message });
18
+ super({ name, message, cause });
18
19
  this[_a] = true;
19
- this.originalMessage = originalMessage;
20
+ this.url = url;
21
+ this.statusCode = statusCode;
22
+ this.statusText = statusText;
20
23
  }
21
24
  static isInstance(error) {
22
25
  return AISDKError.hasMarker(error, marker);
@@ -24,271 +27,172 @@ var MessageConversionError = class extends AISDKError {
24
27
  };
25
28
  _a = symbol;
26
29
 
27
- // core/prompt/convert-to-model-messages.ts
28
- function convertToModelMessages(messages, options) {
29
- var _a6, _b;
30
- const tools = (_a6 = options == null ? void 0 : options.tools) != null ? _a6 : {};
31
- const coreMessages = [];
32
- for (let i = 0; i < messages.length; i++) {
33
- const message = messages[i];
34
- const isLastMessage = i === messages.length - 1;
35
- const { role, content } = message;
36
- switch (role) {
37
- case "system": {
38
- coreMessages.push({
39
- role: "system",
40
- content
41
- });
42
- break;
43
- }
44
- case "user": {
45
- coreMessages.push({
46
- role: "user",
47
- content: message.parts.filter(
48
- (part) => part.type === "text" || part.type === "file"
49
- ).map(
50
- (part) => part.type === "file" ? {
51
- type: "file",
52
- mediaType: part.mediaType,
53
- filename: part.filename,
54
- data: part.url
55
- } : part
56
- )
57
- });
58
- break;
59
- }
60
- case "assistant": {
61
- if (message.parts != null) {
62
- let processBlock2 = function() {
63
- const content2 = [];
64
- for (const part of block) {
65
- switch (part.type) {
66
- case "text": {
67
- content2.push(part);
68
- break;
69
- }
70
- case "file": {
71
- content2.push({
72
- type: "file",
73
- mediaType: part.mediaType,
74
- data: part.url
75
- });
76
- break;
77
- }
78
- case "reasoning": {
79
- content2.push({
80
- type: "reasoning",
81
- text: part.text,
82
- providerOptions: part.providerMetadata
83
- });
84
- break;
85
- }
86
- case "tool-invocation":
87
- content2.push({
88
- type: "tool-call",
89
- toolCallId: part.toolInvocation.toolCallId,
90
- toolName: part.toolInvocation.toolName,
91
- args: part.toolInvocation.args
92
- });
93
- break;
94
- default: {
95
- const _exhaustiveCheck = part;
96
- throw new Error(`Unsupported part: ${_exhaustiveCheck}`);
97
- }
98
- }
99
- }
100
- coreMessages.push({
101
- role: "assistant",
102
- content: content2
103
- });
104
- const stepInvocations = block.filter(
105
- (part) => part.type === "tool-invocation"
106
- ).map((part) => part.toolInvocation);
107
- if (stepInvocations.length > 0) {
108
- coreMessages.push({
109
- role: "tool",
110
- content: stepInvocations.map(
111
- (toolInvocation) => {
112
- if (!("result" in toolInvocation)) {
113
- throw new MessageConversionError({
114
- originalMessage: message,
115
- message: "ToolInvocation must have a result: " + JSON.stringify(toolInvocation)
116
- });
117
- }
118
- const { toolCallId, toolName, result } = toolInvocation;
119
- const tool = tools[toolName];
120
- return (tool == null ? void 0 : tool.experimental_toToolResultContent) != null ? {
121
- type: "tool-result",
122
- toolCallId,
123
- toolName,
124
- result: tool.experimental_toToolResultContent(result),
125
- experimental_content: tool.experimental_toToolResultContent(result)
126
- } : {
127
- type: "tool-result",
128
- toolCallId,
129
- toolName,
130
- result
131
- };
132
- }
133
- )
134
- });
135
- }
136
- block = [];
137
- blockHasToolInvocations = false;
138
- currentStep++;
139
- };
140
- var processBlock = processBlock2;
141
- let currentStep = 0;
142
- let blockHasToolInvocations = false;
143
- let block = [];
144
- for (const part of message.parts) {
145
- switch (part.type) {
146
- case "text": {
147
- if (blockHasToolInvocations) {
148
- processBlock2();
149
- }
150
- block.push(part);
151
- break;
152
- }
153
- case "file":
154
- case "reasoning": {
155
- block.push(part);
156
- break;
157
- }
158
- case "tool-invocation": {
159
- if (((_b = part.toolInvocation.step) != null ? _b : 0) !== currentStep) {
160
- processBlock2();
161
- }
162
- block.push(part);
163
- blockHasToolInvocations = true;
164
- break;
165
- }
166
- }
167
- }
168
- processBlock2();
169
- break;
170
- }
171
- if (content && !isLastMessage) {
172
- coreMessages.push({ role: "assistant", content });
173
- }
174
- break;
175
- }
176
- default: {
177
- const _exhaustiveCheck = role;
178
- throw new MessageConversionError({
179
- originalMessage: message,
180
- message: `Unsupported role: ${_exhaustiveCheck}`
181
- });
182
- }
183
- }
184
- }
185
- return coreMessages;
186
- }
187
-
188
- // core/prompt/detect-prompt-type.ts
189
- function detectPromptType(prompt) {
190
- if (!Array.isArray(prompt)) {
191
- return "other";
192
- }
193
- if (prompt.length === 0) {
194
- return "messages";
195
- }
196
- const characteristics = prompt.map(detectSingleMessageCharacteristics);
197
- if (characteristics.some((c) => c === "has-ui-specific-parts")) {
198
- return "ui-messages";
199
- } else if (characteristics.every(
200
- (c) => c === "has-core-specific-parts" || c === "message"
201
- )) {
202
- return "messages";
203
- } else {
204
- return "other";
205
- }
206
- }
207
- function detectSingleMessageCharacteristics(message) {
208
- if (typeof message === "object" && message !== null && (message.role === "function" || // UI-only role
209
- message.role === "data" || // UI-only role
210
- "toolInvocations" in message || // UI-specific field
211
- "parts" in message || // UI-specific field
212
- "experimental_attachments" in message)) {
213
- return "has-ui-specific-parts";
214
- } else if (typeof message === "object" && message !== null && "content" in message && (Array.isArray(message.content) || // Core messages can have array content
215
- "providerOptions" in message)) {
216
- return "has-core-specific-parts";
217
- } else if (typeof message === "object" && message !== null && "role" in message && "content" in message && typeof message.content === "string" && ["system", "user", "assistant", "tool"].includes(message.role)) {
218
- return "message";
219
- } else {
220
- return "other";
221
- }
222
- }
223
-
224
- // core/prompt/message.ts
225
- import { z as z6 } from "zod";
226
-
227
- // core/types/provider-metadata.ts
228
- import { z as z2 } from "zod";
229
-
230
- // core/types/json-value.ts
231
- import { z } from "zod";
232
- var jsonValueSchema = z.lazy(
233
- () => z.union([
234
- z.null(),
235
- z.string(),
236
- z.number(),
237
- z.boolean(),
238
- z.record(z.string(), jsonValueSchema),
239
- z.array(jsonValueSchema)
240
- ])
241
- );
242
-
243
- // core/types/provider-metadata.ts
244
- var providerMetadataSchema = z2.record(
245
- z2.string(),
246
- z2.record(z2.string(), jsonValueSchema)
247
- );
248
-
249
- // core/prompt/content-part.ts
250
- import { z as z5 } from "zod";
251
-
252
- // core/prompt/data-content.ts
253
- import { AISDKError as AISDKError2 } from "@ai-sdk/provider";
254
- import {
255
- convertBase64ToUint8Array,
256
- convertUint8ArrayToBase64
257
- } from "@ai-sdk/provider-utils";
258
- import { z as z3 } from "zod";
259
-
260
- // core/prompt/split-data-url.ts
261
- function splitDataUrl(dataUrl) {
30
+ // util/download.ts
31
+ async function download({ url }) {
32
+ var _a6;
33
+ const urlText = url.toString();
262
34
  try {
263
- const [header, base64Content] = dataUrl.split(",");
35
+ const response = await fetch(urlText);
36
+ if (!response.ok) {
37
+ throw new DownloadError({
38
+ url: urlText,
39
+ statusCode: response.status,
40
+ statusText: response.statusText
41
+ });
42
+ }
264
43
  return {
265
- mediaType: header.split(";")[0].split(":")[1],
266
- base64Content
44
+ data: new Uint8Array(await response.arrayBuffer()),
45
+ mediaType: (_a6 = response.headers.get("content-type")) != null ? _a6 : void 0
267
46
  };
268
47
  } catch (error) {
269
- return {
270
- mediaType: void 0,
271
- base64Content: void 0
272
- };
48
+ if (DownloadError.isInstance(error)) {
49
+ throw error;
50
+ }
51
+ throw new DownloadError({ url: urlText, cause: error });
273
52
  }
274
53
  }
275
54
 
276
- // core/prompt/data-content.ts
277
- var dataContentSchema = z3.union([
278
- z3.string(),
279
- z3.instanceof(Uint8Array),
280
- z3.instanceof(ArrayBuffer),
281
- z3.custom(
282
- // Buffer might not be available in some environments such as CloudFlare:
283
- (value) => {
284
- var _a6, _b;
285
- return (_b = (_a6 = globalThis.Buffer) == null ? void 0 : _a6.isBuffer(value)) != null ? _b : false;
286
- },
287
- { message: "Must be a Buffer" }
288
- )
289
- ]);
290
- function convertToLanguageModelV2DataContent(content) {
291
- if (content instanceof Uint8Array) {
55
+ // core/util/detect-media-type.ts
56
+ import { convertBase64ToUint8Array } from "@ai-sdk/provider-utils";
57
+ var imageMediaTypeSignatures = [
58
+ {
59
+ mediaType: "image/gif",
60
+ bytesPrefix: [71, 73, 70],
61
+ base64Prefix: "R0lG"
62
+ },
63
+ {
64
+ mediaType: "image/png",
65
+ bytesPrefix: [137, 80, 78, 71],
66
+ base64Prefix: "iVBORw"
67
+ },
68
+ {
69
+ mediaType: "image/jpeg",
70
+ bytesPrefix: [255, 216],
71
+ base64Prefix: "/9j/"
72
+ },
73
+ {
74
+ mediaType: "image/webp",
75
+ bytesPrefix: [82, 73, 70, 70],
76
+ base64Prefix: "UklGRg"
77
+ },
78
+ {
79
+ mediaType: "image/bmp",
80
+ bytesPrefix: [66, 77],
81
+ base64Prefix: "Qk"
82
+ },
83
+ {
84
+ mediaType: "image/tiff",
85
+ bytesPrefix: [73, 73, 42, 0],
86
+ base64Prefix: "SUkqAA"
87
+ },
88
+ {
89
+ mediaType: "image/tiff",
90
+ bytesPrefix: [77, 77, 0, 42],
91
+ base64Prefix: "TU0AKg"
92
+ },
93
+ {
94
+ mediaType: "image/avif",
95
+ bytesPrefix: [
96
+ 0,
97
+ 0,
98
+ 0,
99
+ 32,
100
+ 102,
101
+ 116,
102
+ 121,
103
+ 112,
104
+ 97,
105
+ 118,
106
+ 105,
107
+ 102
108
+ ],
109
+ base64Prefix: "AAAAIGZ0eXBhdmlm"
110
+ },
111
+ {
112
+ mediaType: "image/heic",
113
+ bytesPrefix: [
114
+ 0,
115
+ 0,
116
+ 0,
117
+ 32,
118
+ 102,
119
+ 116,
120
+ 121,
121
+ 112,
122
+ 104,
123
+ 101,
124
+ 105,
125
+ 99
126
+ ],
127
+ base64Prefix: "AAAAIGZ0eXBoZWlj"
128
+ }
129
+ ];
130
+ var stripID3 = (data) => {
131
+ const bytes = typeof data === "string" ? convertBase64ToUint8Array(data) : data;
132
+ const id3Size = (bytes[6] & 127) << 21 | (bytes[7] & 127) << 14 | (bytes[8] & 127) << 7 | bytes[9] & 127;
133
+ return bytes.slice(id3Size + 10);
134
+ };
135
+ function stripID3TagsIfPresent(data) {
136
+ const hasId3 = typeof data === "string" && data.startsWith("SUQz") || typeof data !== "string" && data.length > 10 && data[0] === 73 && // 'I'
137
+ data[1] === 68 && // 'D'
138
+ data[2] === 51;
139
+ return hasId3 ? stripID3(data) : data;
140
+ }
141
+ function detectMediaType({
142
+ data,
143
+ signatures
144
+ }) {
145
+ const processedData = stripID3TagsIfPresent(data);
146
+ for (const signature of signatures) {
147
+ if (typeof processedData === "string" ? processedData.startsWith(signature.base64Prefix) : processedData.length >= signature.bytesPrefix.length && signature.bytesPrefix.every(
148
+ (byte, index) => processedData[index] === byte
149
+ )) {
150
+ return signature.mediaType;
151
+ }
152
+ }
153
+ return void 0;
154
+ }
155
+
156
+ // core/prompt/data-content.ts
157
+ import { AISDKError as AISDKError2 } from "@ai-sdk/provider";
158
+ import {
159
+ convertBase64ToUint8Array as convertBase64ToUint8Array2,
160
+ convertUint8ArrayToBase64
161
+ } from "@ai-sdk/provider-utils";
162
+ import { z } from "zod";
163
+
164
+ // core/prompt/split-data-url.ts
165
+ function splitDataUrl(dataUrl) {
166
+ try {
167
+ const [header, base64Content] = dataUrl.split(",");
168
+ return {
169
+ mediaType: header.split(";")[0].split(":")[1],
170
+ base64Content
171
+ };
172
+ } catch (error) {
173
+ return {
174
+ mediaType: void 0,
175
+ base64Content: void 0
176
+ };
177
+ }
178
+ }
179
+
180
+ // core/prompt/data-content.ts
181
+ var dataContentSchema = z.union([
182
+ z.string(),
183
+ z.instanceof(Uint8Array),
184
+ z.instanceof(ArrayBuffer),
185
+ z.custom(
186
+ // Buffer might not be available in some environments such as CloudFlare:
187
+ (value) => {
188
+ var _a6, _b;
189
+ return (_b = (_a6 = globalThis.Buffer) == null ? void 0 : _a6.isBuffer(value)) != null ? _b : false;
190
+ },
191
+ { message: "Must be a Buffer" }
192
+ )
193
+ ]);
194
+ function convertToLanguageModelV2DataContent(content) {
195
+ if (content instanceof Uint8Array) {
292
196
  return { data: content, mediaType: void 0 };
293
197
  }
294
198
  if (content instanceof ArrayBuffer) {
@@ -315,631 +219,265 @@ function convertToLanguageModelV2DataContent(content) {
315
219
  return { data: content, mediaType: void 0 };
316
220
  }
317
221
 
318
- // core/prompt/tool-result-content.ts
319
- import { z as z4 } from "zod";
320
- var toolResultContentSchema = z4.array(
321
- z4.union([
322
- z4.object({ type: z4.literal("text"), text: z4.string() }),
323
- z4.object({
324
- type: z4.literal("image"),
325
- data: z4.string(),
326
- mediaType: z4.string().optional()
327
- })
328
- ])
329
- );
330
-
331
- // core/prompt/content-part.ts
332
- var textPartSchema = z5.object({
333
- type: z5.literal("text"),
334
- text: z5.string(),
335
- providerOptions: providerMetadataSchema.optional()
336
- });
337
- var imagePartSchema = z5.object({
338
- type: z5.literal("image"),
339
- image: z5.union([dataContentSchema, z5.instanceof(URL)]),
340
- mediaType: z5.string().optional(),
341
- providerOptions: providerMetadataSchema.optional()
342
- });
343
- var filePartSchema = z5.object({
344
- type: z5.literal("file"),
345
- data: z5.union([dataContentSchema, z5.instanceof(URL)]),
346
- filename: z5.string().optional(),
347
- mediaType: z5.string(),
348
- providerOptions: providerMetadataSchema.optional()
349
- });
350
- var reasoningPartSchema = z5.object({
351
- type: z5.literal("reasoning"),
352
- text: z5.string(),
353
- providerOptions: providerMetadataSchema.optional()
354
- });
355
- var toolCallPartSchema = z5.object({
356
- type: z5.literal("tool-call"),
357
- toolCallId: z5.string(),
358
- toolName: z5.string(),
359
- args: z5.unknown(),
360
- providerOptions: providerMetadataSchema.optional()
361
- });
362
- var toolResultPartSchema = z5.object({
363
- type: z5.literal("tool-result"),
364
- toolCallId: z5.string(),
365
- toolName: z5.string(),
366
- result: z5.unknown(),
367
- content: toolResultContentSchema.optional(),
368
- isError: z5.boolean().optional(),
369
- providerOptions: providerMetadataSchema.optional()
370
- });
371
-
372
- // core/prompt/message.ts
373
- var systemModelMessageSchema = z6.object(
374
- {
375
- role: z6.literal("system"),
376
- content: z6.string(),
377
- providerOptions: providerMetadataSchema.optional()
222
+ // core/prompt/invalid-message-role-error.ts
223
+ import { AISDKError as AISDKError3 } from "@ai-sdk/provider";
224
+ var name2 = "AI_InvalidMessageRoleError";
225
+ var marker2 = `vercel.ai.error.${name2}`;
226
+ var symbol2 = Symbol.for(marker2);
227
+ var _a2;
228
+ var InvalidMessageRoleError = class extends AISDKError3 {
229
+ constructor({
230
+ role,
231
+ message = `Invalid message role: '${role}'. Must be one of: "system", "user", "assistant", "tool".`
232
+ }) {
233
+ super({ name: name2, message });
234
+ this[_a2] = true;
235
+ this.role = role;
378
236
  }
379
- );
380
- var userModelMessageSchema = z6.object({
381
- role: z6.literal("user"),
382
- content: z6.union([
383
- z6.string(),
384
- z6.array(z6.union([textPartSchema, imagePartSchema, filePartSchema]))
385
- ]),
386
- providerOptions: providerMetadataSchema.optional()
387
- });
388
- var assistantModelMessageSchema = z6.object({
389
- role: z6.literal("assistant"),
390
- content: z6.union([
391
- z6.string(),
392
- z6.array(
393
- z6.union([
394
- textPartSchema,
395
- filePartSchema,
396
- reasoningPartSchema,
397
- toolCallPartSchema
398
- ])
399
- )
400
- ]),
401
- providerOptions: providerMetadataSchema.optional()
402
- });
403
- var toolModelMessageSchema = z6.object({
404
- role: z6.literal("tool"),
405
- content: z6.array(toolResultPartSchema),
406
- providerOptions: providerMetadataSchema.optional()
407
- });
408
- var modelMessageSchema = z6.union([
409
- systemModelMessageSchema,
410
- userModelMessageSchema,
411
- assistantModelMessageSchema,
412
- toolModelMessageSchema
413
- ]);
237
+ static isInstance(error) {
238
+ return AISDKError3.hasMarker(error, marker2);
239
+ }
240
+ };
241
+ _a2 = symbol2;
414
242
 
415
- // core/prompt/standardize-prompt.ts
416
- async function standardizePrompt({
243
+ // core/prompt/convert-to-language-model-prompt.ts
244
+ async function convertToLanguageModelPrompt({
417
245
  prompt,
418
- tools
246
+ supportedUrls,
247
+ downloadImplementation = download
419
248
  }) {
420
- if (prompt.prompt == null && prompt.messages == null) {
421
- throw new InvalidPromptError({
422
- prompt,
423
- message: "prompt or messages must be defined"
424
- });
425
- }
426
- if (prompt.prompt != null && prompt.messages != null) {
427
- throw new InvalidPromptError({
428
- prompt,
429
- message: "prompt and messages cannot be defined at the same time"
430
- });
431
- }
432
- if (prompt.system != null && typeof prompt.system !== "string") {
433
- throw new InvalidPromptError({
434
- prompt,
435
- message: "system must be a string"
436
- });
437
- }
438
- if (prompt.prompt != null) {
439
- if (typeof prompt.prompt !== "string") {
440
- throw new InvalidPromptError({
441
- prompt,
442
- message: "prompt must be a string"
443
- });
249
+ const downloadedAssets = await downloadAssets(
250
+ prompt.messages,
251
+ downloadImplementation,
252
+ supportedUrls
253
+ );
254
+ return [
255
+ ...prompt.system != null ? [{ role: "system", content: prompt.system }] : [],
256
+ ...prompt.messages.map(
257
+ (message) => convertToLanguageModelMessage(message, downloadedAssets)
258
+ )
259
+ ];
260
+ }
261
+ function convertToLanguageModelMessage(message, downloadedAssets) {
262
+ const role = message.role;
263
+ switch (role) {
264
+ case "system": {
265
+ return {
266
+ role: "system",
267
+ content: message.content,
268
+ providerOptions: message.providerOptions
269
+ };
444
270
  }
445
- return {
446
- system: prompt.system,
447
- messages: [
448
- {
271
+ case "user": {
272
+ if (typeof message.content === "string") {
273
+ return {
449
274
  role: "user",
450
- content: prompt.prompt
451
- }
452
- ]
453
- };
454
- }
455
- if (prompt.messages != null) {
456
- const promptType = detectPromptType(prompt.messages);
457
- if (promptType === "other") {
458
- throw new InvalidPromptError({
459
- prompt,
460
- message: "messages must be an array of ModelMessage or UIMessage"
461
- });
462
- }
463
- const messages = promptType === "ui-messages" ? convertToModelMessages(prompt.messages, {
464
- tools
465
- }) : prompt.messages;
466
- if (messages.length === 0) {
467
- throw new InvalidPromptError({
468
- prompt,
469
- message: "messages must not be empty"
470
- });
471
- }
472
- const validationResult = await safeValidateTypes({
473
- value: messages,
474
- schema: z7.array(modelMessageSchema)
475
- });
476
- if (!validationResult.success) {
477
- throw new InvalidPromptError({
478
- prompt,
479
- message: "messages must be an array of ModelMessage or UIMessage",
480
- cause: validationResult.error
481
- });
482
- }
483
- return {
484
- messages,
485
- system: prompt.system
486
- };
487
- }
488
- throw new Error("unreachable");
489
- }
490
-
491
- // core/util/index.ts
492
- import {
493
- asSchema,
494
- generateId,
495
- jsonSchema
496
- } from "@ai-sdk/provider-utils";
497
-
498
- // core/util/data-stream-parts.ts
499
- var textStreamPart = {
500
- code: "0",
501
- name: "text",
502
- parse: (value) => {
503
- if (typeof value !== "string") {
504
- throw new Error('"text" parts expect a string value.');
275
+ content: [{ type: "text", text: message.content }],
276
+ providerOptions: message.providerOptions
277
+ };
278
+ }
279
+ return {
280
+ role: "user",
281
+ content: message.content.map((part) => convertPartToLanguageModelPart(part, downloadedAssets)).filter((part) => part.type !== "text" || part.text !== ""),
282
+ providerOptions: message.providerOptions
283
+ };
505
284
  }
506
- return { type: "text", value };
507
- }
508
- };
509
- var dataStreamPart = {
510
- code: "2",
511
- name: "data",
512
- parse: (value) => {
513
- if (!Array.isArray(value)) {
514
- throw new Error('"data" parts expect an array value.');
285
+ case "assistant": {
286
+ if (typeof message.content === "string") {
287
+ return {
288
+ role: "assistant",
289
+ content: [{ type: "text", text: message.content }],
290
+ providerOptions: message.providerOptions
291
+ };
292
+ }
293
+ return {
294
+ role: "assistant",
295
+ content: message.content.filter(
296
+ // remove empty text parts:
297
+ (part) => part.type !== "text" || part.text !== ""
298
+ ).map((part) => {
299
+ const providerOptions = part.providerOptions;
300
+ switch (part.type) {
301
+ case "file": {
302
+ const { data, mediaType } = convertToLanguageModelV2DataContent(
303
+ part.data
304
+ );
305
+ return {
306
+ type: "file",
307
+ data,
308
+ filename: part.filename,
309
+ mediaType: mediaType != null ? mediaType : part.mediaType,
310
+ providerOptions
311
+ };
312
+ }
313
+ case "reasoning": {
314
+ return {
315
+ type: "reasoning",
316
+ text: part.text,
317
+ providerOptions
318
+ };
319
+ }
320
+ case "text": {
321
+ return {
322
+ type: "text",
323
+ text: part.text,
324
+ providerOptions
325
+ };
326
+ }
327
+ case "tool-call": {
328
+ return {
329
+ type: "tool-call",
330
+ toolCallId: part.toolCallId,
331
+ toolName: part.toolName,
332
+ args: part.args,
333
+ providerOptions
334
+ };
335
+ }
336
+ }
337
+ }),
338
+ providerOptions: message.providerOptions
339
+ };
515
340
  }
516
- return { type: "data", value };
517
- }
518
- };
519
- var errorStreamPart = {
520
- code: "3",
521
- name: "error",
522
- parse: (value) => {
523
- if (typeof value !== "string") {
524
- throw new Error('"error" parts expect a string value.');
341
+ case "tool": {
342
+ return {
343
+ role: "tool",
344
+ content: message.content.map((part) => ({
345
+ type: "tool-result",
346
+ toolCallId: part.toolCallId,
347
+ toolName: part.toolName,
348
+ result: part.result,
349
+ content: part.experimental_content,
350
+ isError: part.isError,
351
+ providerOptions: part.providerOptions
352
+ })),
353
+ providerOptions: message.providerOptions
354
+ };
525
355
  }
526
- return { type: "error", value };
527
- }
528
- };
529
- var messageAnnotationsStreamPart = {
530
- code: "8",
531
- name: "message_annotations",
532
- parse: (value) => {
533
- if (!Array.isArray(value)) {
534
- throw new Error('"message_annotations" parts expect an array value.');
356
+ default: {
357
+ const _exhaustiveCheck = role;
358
+ throw new InvalidMessageRoleError({ role: _exhaustiveCheck });
535
359
  }
536
- return { type: "message_annotations", value };
537
360
  }
538
- };
539
- var toolCallStreamPart = {
540
- code: "9",
541
- name: "tool_call",
542
- parse: (value) => {
543
- if (value == null || typeof value !== "object" || !("toolCallId" in value) || typeof value.toolCallId !== "string" || !("toolName" in value) || typeof value.toolName !== "string" || !("args" in value) || typeof value.args !== "object") {
544
- throw new Error(
545
- '"tool_call" parts expect an object with a "toolCallId", "toolName", and "args" property.'
546
- );
361
+ }
362
+ async function downloadAssets(messages, downloadImplementation, supportedUrls) {
363
+ const urls = messages.filter((message) => message.role === "user").map((message) => message.content).filter(
364
+ (content) => Array.isArray(content)
365
+ ).flat().filter(
366
+ (part) => part.type === "image" || part.type === "file"
367
+ ).map((part) => {
368
+ var _a6;
369
+ const mediaType = (_a6 = part.mediaType) != null ? _a6 : part.type === "image" ? "image/*" : void 0;
370
+ let data = part.type === "image" ? part.image : part.data;
371
+ if (typeof data === "string") {
372
+ try {
373
+ data = new URL(data);
374
+ } catch (ignored) {
375
+ }
547
376
  }
377
+ return { mediaType, data };
378
+ }).filter(
379
+ (part) => part.data instanceof URL && part.mediaType != null && !isUrlSupported({
380
+ url: part.data.toString(),
381
+ mediaType: part.mediaType,
382
+ supportedUrls
383
+ })
384
+ ).map((part) => part.data);
385
+ const downloadedImages = await Promise.all(
386
+ urls.map(async (url) => ({
387
+ url,
388
+ data: await downloadImplementation({ url })
389
+ }))
390
+ );
391
+ return Object.fromEntries(
392
+ downloadedImages.map(({ url, data }) => [url.toString(), data])
393
+ );
394
+ }
395
+ function convertPartToLanguageModelPart(part, downloadedAssets) {
396
+ var _a6, _b;
397
+ if (part.type === "text") {
548
398
  return {
549
- type: "tool_call",
550
- value
399
+ type: "text",
400
+ text: part.text,
401
+ providerOptions: part.providerOptions
551
402
  };
552
403
  }
553
- };
554
- var toolResultStreamPart = {
555
- code: "a",
556
- name: "tool_result",
557
- parse: (value) => {
558
- if (value == null || typeof value !== "object" || !("toolCallId" in value) || typeof value.toolCallId !== "string" || !("result" in value)) {
559
- throw new Error(
560
- '"tool_result" parts expect an object with a "toolCallId" and a "result" property.'
561
- );
562
- }
563
- return {
564
- type: "tool_result",
565
- value
566
- };
404
+ let originalData;
405
+ const type = part.type;
406
+ switch (type) {
407
+ case "image":
408
+ originalData = part.image;
409
+ break;
410
+ case "file":
411
+ originalData = part.data;
412
+ break;
413
+ default:
414
+ throw new Error(`Unsupported part type: ${type}`);
567
415
  }
568
- };
569
- var toolCallStreamingStartStreamPart = {
570
- code: "b",
571
- name: "tool_call_streaming_start",
572
- parse: (value) => {
573
- if (value == null || typeof value !== "object" || !("toolCallId" in value) || typeof value.toolCallId !== "string" || !("toolName" in value) || typeof value.toolName !== "string") {
574
- throw new Error(
575
- '"tool_call_streaming_start" parts expect an object with a "toolCallId" and "toolName" property.'
576
- );
416
+ const { data: convertedData, mediaType: convertedMediaType } = convertToLanguageModelV2DataContent(originalData);
417
+ let mediaType = convertedMediaType != null ? convertedMediaType : part.mediaType;
418
+ let data = convertedData;
419
+ if (data instanceof URL) {
420
+ const downloadedFile = downloadedAssets[data.toString()];
421
+ if (downloadedFile) {
422
+ data = downloadedFile.data;
423
+ mediaType = (_a6 = downloadedFile.mediaType) != null ? _a6 : mediaType;
577
424
  }
578
- return {
579
- type: "tool_call_streaming_start",
580
- value
581
- };
582
425
  }
583
- };
584
- var toolCallDeltaStreamPart = {
585
- code: "c",
586
- name: "tool_call_delta",
587
- parse: (value) => {
588
- if (value == null || typeof value !== "object" || !("toolCallId" in value) || typeof value.toolCallId !== "string" || !("argsTextDelta" in value) || typeof value.argsTextDelta !== "string") {
589
- throw new Error(
590
- '"tool_call_delta" parts expect an object with a "toolCallId" and "argsTextDelta" property.'
591
- );
592
- }
593
- return {
594
- type: "tool_call_delta",
595
- value
596
- };
597
- }
598
- };
599
- var finishMessageStreamPart = {
600
- code: "d",
601
- name: "finish_message",
602
- parse: (value) => {
603
- if (value == null || typeof value !== "object" || !("finishReason" in value) || typeof value.finishReason !== "string") {
604
- throw new Error(
605
- '"finish_message" parts expect an object with a "finishReason" property.'
606
- );
607
- }
608
- const result = {
609
- finishReason: value.finishReason
610
- };
611
- if ("usage" in value && value.usage != null && typeof value.usage === "object") {
612
- result.usage = {
613
- inputTokens: "inputTokens" in value.usage && typeof value.usage.inputTokens === "number" ? value.usage.inputTokens : void 0,
614
- outputTokens: "outputTokens" in value.usage && typeof value.usage.outputTokens === "number" ? value.usage.outputTokens : void 0,
615
- totalTokens: "totalTokens" in value.usage && typeof value.usage.totalTokens === "number" ? value.usage.totalTokens : void 0,
616
- reasoningTokens: "reasoningTokens" in value.usage && typeof value.usage.reasoningTokens === "number" ? value.usage.reasoningTokens : void 0,
617
- cachedInputTokens: "cachedInputTokens" in value.usage && typeof value.usage.cachedInputTokens === "number" ? value.usage.cachedInputTokens : void 0
618
- };
619
- }
620
- return {
621
- type: "finish_message",
622
- value: result
623
- };
624
- }
625
- };
626
- var finishStepStreamPart = {
627
- code: "e",
628
- name: "finish_step",
629
- parse: (value) => {
630
- if (value == null || typeof value !== "object" || !("finishReason" in value) || typeof value.finishReason !== "string") {
631
- throw new Error(
632
- '"finish_step" parts expect an object with a "finishReason" property.'
633
- );
634
- }
635
- const result = {
636
- finishReason: value.finishReason,
637
- isContinued: false
638
- };
639
- if ("usage" in value && value.usage != null && typeof value.usage === "object") {
640
- result.usage = {
641
- inputTokens: "inputTokens" in value.usage && typeof value.usage.inputTokens === "number" ? value.usage.inputTokens : void 0,
642
- outputTokens: "outputTokens" in value.usage && typeof value.usage.outputTokens === "number" ? value.usage.outputTokens : void 0,
643
- totalTokens: "totalTokens" in value.usage && typeof value.usage.totalTokens === "number" ? value.usage.totalTokens : void 0,
644
- reasoningTokens: "reasoningTokens" in value.usage && typeof value.usage.reasoningTokens === "number" ? value.usage.reasoningTokens : void 0,
645
- cachedInputTokens: "cachedInputTokens" in value.usage && typeof value.usage.cachedInputTokens === "number" ? value.usage.cachedInputTokens : void 0
646
- };
647
- }
648
- if ("isContinued" in value && typeof value.isContinued === "boolean") {
649
- result.isContinued = value.isContinued;
650
- }
651
- return {
652
- type: "finish_step",
653
- value: result
654
- };
655
- }
656
- };
657
- var startStepStreamPart = {
658
- code: "f",
659
- name: "start_step",
660
- parse: (value) => {
661
- if (value == null || typeof value !== "object" || !("messageId" in value) || typeof value.messageId !== "string") {
662
- throw new Error(
663
- '"start_step" parts expect an object with an "id" property.'
664
- );
665
- }
666
- return {
667
- type: "start_step",
668
- value: {
669
- messageId: value.messageId
426
+ switch (type) {
427
+ case "image": {
428
+ if (data instanceof Uint8Array || typeof data === "string") {
429
+ mediaType = (_b = detectMediaType({ data, signatures: imageMediaTypeSignatures })) != null ? _b : mediaType;
670
430
  }
671
- };
672
- }
673
- };
674
- var reasoningStreamPart = {
675
- code: "g",
676
- name: "reasoning",
677
- parse: (value) => {
678
- if (value == null || typeof value !== "object" || !("text" in value) || typeof value.text !== "string" || "providerMetadata" in value && typeof value.providerMetadata !== "object") {
679
- throw new Error(
680
- '"reasoning" parts expect an object with a "text" property.'
681
- );
431
+ return {
432
+ type: "file",
433
+ mediaType: mediaType != null ? mediaType : "image/*",
434
+ // any image
435
+ filename: void 0,
436
+ data,
437
+ providerOptions: part.providerOptions
438
+ };
682
439
  }
683
- return {
684
- type: "reasoning",
685
- value: {
686
- text: value.text,
687
- providerMetadata: value.providerMetadata
440
+ case "file": {
441
+ if (mediaType == null) {
442
+ throw new Error(`Media type is missing for file part`);
688
443
  }
689
- };
690
- }
691
- };
692
- var sourcePart = {
693
- code: "h",
694
- name: "source",
695
- parse: (value) => {
696
- if (value == null || typeof value !== "object") {
697
- throw new Error('"source" parts expect a Source object.');
698
- }
699
- return {
700
- type: "source",
701
- value
702
- };
703
- }
704
- };
705
- var fileStreamPart = {
706
- code: "k",
707
- name: "file",
708
- parse: (value) => {
709
- if (value == null || typeof value !== "object" || !("url" in value) || typeof value.url !== "string" || !("mediaType" in value) || typeof value.mediaType !== "string") {
710
- throw new Error(
711
- '"file" parts expect an object with a "url" and "mediaType" property.'
712
- );
444
+ return {
445
+ type: "file",
446
+ mediaType,
447
+ filename: part.filename,
448
+ data,
449
+ providerOptions: part.providerOptions
450
+ };
713
451
  }
714
- return { type: "file", value };
715
- }
716
- };
717
- var reasoningPartFinishStreamPart = {
718
- code: "l",
719
- name: "reasoning_part_finish",
720
- parse: () => {
721
- return {
722
- type: "reasoning_part_finish",
723
- value: {}
724
- };
725
452
  }
726
- };
727
- var dataStreamParts = [
728
- textStreamPart,
729
- dataStreamPart,
730
- errorStreamPart,
731
- messageAnnotationsStreamPart,
732
- toolCallStreamPart,
733
- toolResultStreamPart,
734
- toolCallStreamingStartStreamPart,
735
- toolCallDeltaStreamPart,
736
- finishMessageStreamPart,
737
- finishStepStreamPart,
738
- startStepStreamPart,
739
- reasoningStreamPart,
740
- sourcePart,
741
- reasoningPartFinishStreamPart,
742
- fileStreamPart
743
- ];
744
- var dataStreamPartsByCode = Object.fromEntries(
745
- dataStreamParts.map((part) => [part.code, part])
746
- );
747
- var DataStreamStringPrefixes = Object.fromEntries(
748
- dataStreamParts.map((part) => [part.name, part.code])
749
- );
750
- var validCodes = dataStreamParts.map((part) => part.code);
751
- function formatDataStreamPart(type, value) {
752
- const streamPart = dataStreamParts.find((part) => part.name === type);
753
- if (!streamPart) {
754
- throw new Error(`Invalid stream part type: ${type}`);
755
- }
756
- return `${streamPart.code}:${JSON.stringify(value)}
757
- `;
758
- }
759
-
760
- // core/util/is-non-empty-object.ts
761
- function isNonEmptyObject(object) {
762
- return object != null && Object.keys(object).length > 0;
763
- }
764
-
765
- // core/prompt/prepare-tools-and-tool-choice.ts
766
- function prepareToolsAndToolChoice({
767
- tools,
768
- toolChoice,
769
- activeTools
770
- }) {
771
- if (!isNonEmptyObject(tools)) {
772
- return {
773
- tools: void 0,
774
- toolChoice: void 0
775
- };
776
- }
777
- const filteredTools = activeTools != null ? Object.entries(tools).filter(
778
- ([name6]) => activeTools.includes(name6)
779
- ) : Object.entries(tools);
780
- return {
781
- tools: filteredTools.map(([name6, tool]) => {
782
- const toolType = tool.type;
783
- switch (toolType) {
784
- case void 0:
785
- case "function":
786
- return {
787
- type: "function",
788
- name: name6,
789
- description: tool.description,
790
- parameters: asSchema(tool.parameters).jsonSchema
791
- };
792
- case "provider-defined":
793
- return {
794
- type: "provider-defined",
795
- name: name6,
796
- id: tool.id,
797
- args: tool.args
798
- };
799
- default: {
800
- const exhaustiveCheck = toolType;
801
- throw new Error(`Unsupported tool type: ${exhaustiveCheck}`);
802
- }
803
- }
804
- }),
805
- toolChoice: toolChoice == null ? { type: "auto" } : typeof toolChoice === "string" ? { type: toolChoice } : { type: "tool", toolName: toolChoice.toolName }
806
- };
807
453
  }
808
454
 
809
455
  // errors/invalid-argument-error.ts
810
- import { AISDKError as AISDKError3 } from "@ai-sdk/provider";
811
- var name2 = "AI_InvalidArgumentError";
812
- var marker2 = `vercel.ai.error.${name2}`;
813
- var symbol2 = Symbol.for(marker2);
814
- var _a2;
815
- var InvalidArgumentError = class extends AISDKError3 {
456
+ import { AISDKError as AISDKError4 } from "@ai-sdk/provider";
457
+ var name3 = "AI_InvalidArgumentError";
458
+ var marker3 = `vercel.ai.error.${name3}`;
459
+ var symbol3 = Symbol.for(marker3);
460
+ var _a3;
461
+ var InvalidArgumentError = class extends AISDKError4 {
816
462
  constructor({
817
463
  parameter,
818
464
  value,
819
465
  message
820
466
  }) {
821
467
  super({
822
- name: name2,
468
+ name: name3,
823
469
  message: `Invalid argument for parameter ${parameter}: ${message}`
824
470
  });
825
- this[_a2] = true;
471
+ this[_a3] = true;
826
472
  this.parameter = parameter;
827
473
  this.value = value;
828
474
  }
829
- static isInstance(error) {
830
- return AISDKError3.hasMarker(error, marker2);
831
- }
832
- };
833
- _a2 = symbol2;
834
-
835
- // util/retry-with-exponential-backoff.ts
836
- import { APICallError } from "@ai-sdk/provider";
837
- import { delay, getErrorMessage, isAbortError } from "@ai-sdk/provider-utils";
838
-
839
- // util/retry-error.ts
840
- import { AISDKError as AISDKError4 } from "@ai-sdk/provider";
841
- var name3 = "AI_RetryError";
842
- var marker3 = `vercel.ai.error.${name3}`;
843
- var symbol3 = Symbol.for(marker3);
844
- var _a3;
845
- var RetryError = class extends AISDKError4 {
846
- constructor({
847
- message,
848
- reason,
849
- errors
850
- }) {
851
- super({ name: name3, message });
852
- this[_a3] = true;
853
- this.reason = reason;
854
- this.errors = errors;
855
- this.lastError = errors[errors.length - 1];
856
- }
857
475
  static isInstance(error) {
858
476
  return AISDKError4.hasMarker(error, marker3);
859
477
  }
860
478
  };
861
479
  _a3 = symbol3;
862
480
 
863
- // util/retry-with-exponential-backoff.ts
864
- var retryWithExponentialBackoff = ({
865
- maxRetries = 2,
866
- initialDelayInMs = 2e3,
867
- backoffFactor = 2
868
- } = {}) => async (f) => _retryWithExponentialBackoff(f, {
869
- maxRetries,
870
- delayInMs: initialDelayInMs,
871
- backoffFactor
872
- });
873
- async function _retryWithExponentialBackoff(f, {
874
- maxRetries,
875
- delayInMs,
876
- backoffFactor
877
- }, errors = []) {
878
- try {
879
- return await f();
880
- } catch (error) {
881
- if (isAbortError(error)) {
882
- throw error;
883
- }
884
- if (maxRetries === 0) {
885
- throw error;
886
- }
887
- const errorMessage = getErrorMessage(error);
888
- const newErrors = [...errors, error];
889
- const tryNumber = newErrors.length;
890
- if (tryNumber > maxRetries) {
891
- throw new RetryError({
892
- message: `Failed after ${tryNumber} attempts. Last error: ${errorMessage}`,
893
- reason: "maxRetriesExceeded",
894
- errors: newErrors
895
- });
896
- }
897
- if (error instanceof Error && APICallError.isInstance(error) && error.isRetryable === true && tryNumber <= maxRetries) {
898
- await delay(delayInMs);
899
- return _retryWithExponentialBackoff(
900
- f,
901
- { maxRetries, delayInMs: backoffFactor * delayInMs, backoffFactor },
902
- newErrors
903
- );
904
- }
905
- if (tryNumber === 1) {
906
- throw error;
907
- }
908
- throw new RetryError({
909
- message: `Failed after ${tryNumber} attempts with non-retryable error: '${errorMessage}'`,
910
- reason: "errorNotRetryable",
911
- errors: newErrors
912
- });
913
- }
914
- }
915
-
916
- // core/prompt/prepare-retries.ts
917
- function prepareRetries({
918
- maxRetries
919
- }) {
920
- if (maxRetries != null) {
921
- if (!Number.isInteger(maxRetries)) {
922
- throw new InvalidArgumentError({
923
- parameter: "maxRetries",
924
- value: maxRetries,
925
- message: "maxRetries must be an integer"
926
- });
927
- }
928
- if (maxRetries < 0) {
929
- throw new InvalidArgumentError({
930
- parameter: "maxRetries",
931
- value: maxRetries,
932
- message: "maxRetries must be >= 0"
933
- });
934
- }
935
- }
936
- const maxRetriesResult = maxRetries != null ? maxRetries : 2;
937
- return {
938
- maxRetries: maxRetriesResult,
939
- retry: retryWithExponentialBackoff({ maxRetries: maxRetriesResult })
940
- };
941
- }
942
-
943
481
  // core/prompt/prepare-call-settings.ts
944
482
  function prepareCallSettings({
945
483
  maxOutputTokens,
@@ -1033,28 +571,27 @@ function prepareCallSettings({
1033
571
  };
1034
572
  }
1035
573
 
1036
- // core/prompt/convert-to-language-model-prompt.ts
1037
- import { isUrlSupported } from "@ai-sdk/provider-utils";
574
+ // util/retry-with-exponential-backoff.ts
575
+ import { APICallError } from "@ai-sdk/provider";
576
+ import { delay, getErrorMessage, isAbortError } from "@ai-sdk/provider-utils";
1038
577
 
1039
- // util/download-error.ts
578
+ // util/retry-error.ts
1040
579
  import { AISDKError as AISDKError5 } from "@ai-sdk/provider";
1041
- var name4 = "AI_DownloadError";
580
+ var name4 = "AI_RetryError";
1042
581
  var marker4 = `vercel.ai.error.${name4}`;
1043
582
  var symbol4 = Symbol.for(marker4);
1044
583
  var _a4;
1045
- var DownloadError = class extends AISDKError5 {
584
+ var RetryError = class extends AISDKError5 {
1046
585
  constructor({
1047
- url,
1048
- statusCode,
1049
- statusText,
1050
- cause,
1051
- message = cause == null ? `Failed to download ${url}: ${statusCode} ${statusText}` : `Failed to download ${url}: ${cause}`
586
+ message,
587
+ reason,
588
+ errors
1052
589
  }) {
1053
- super({ name: name4, message, cause });
590
+ super({ name: name4, message });
1054
591
  this[_a4] = true;
1055
- this.url = url;
1056
- this.statusCode = statusCode;
1057
- this.statusText = statusText;
592
+ this.reason = reason;
593
+ this.errors = errors;
594
+ this.lastError = errors[errors.length - 1];
1058
595
  }
1059
596
  static isInstance(error) {
1060
597
  return AISDKError5.hasMarker(error, marker4);
@@ -1062,146 +599,166 @@ var DownloadError = class extends AISDKError5 {
1062
599
  };
1063
600
  _a4 = symbol4;
1064
601
 
1065
- // util/download.ts
1066
- async function download({ url }) {
1067
- var _a6;
1068
- const urlText = url.toString();
602
+ // util/retry-with-exponential-backoff.ts
603
+ var retryWithExponentialBackoff = ({
604
+ maxRetries = 2,
605
+ initialDelayInMs = 2e3,
606
+ backoffFactor = 2
607
+ } = {}) => async (f) => _retryWithExponentialBackoff(f, {
608
+ maxRetries,
609
+ delayInMs: initialDelayInMs,
610
+ backoffFactor
611
+ });
612
+ async function _retryWithExponentialBackoff(f, {
613
+ maxRetries,
614
+ delayInMs,
615
+ backoffFactor
616
+ }, errors = []) {
1069
617
  try {
1070
- const response = await fetch(urlText);
1071
- if (!response.ok) {
1072
- throw new DownloadError({
1073
- url: urlText,
1074
- statusCode: response.status,
1075
- statusText: response.statusText
618
+ return await f();
619
+ } catch (error) {
620
+ if (isAbortError(error)) {
621
+ throw error;
622
+ }
623
+ if (maxRetries === 0) {
624
+ throw error;
625
+ }
626
+ const errorMessage = getErrorMessage(error);
627
+ const newErrors = [...errors, error];
628
+ const tryNumber = newErrors.length;
629
+ if (tryNumber > maxRetries) {
630
+ throw new RetryError({
631
+ message: `Failed after ${tryNumber} attempts. Last error: ${errorMessage}`,
632
+ reason: "maxRetriesExceeded",
633
+ errors: newErrors
1076
634
  });
1077
635
  }
1078
- return {
1079
- data: new Uint8Array(await response.arrayBuffer()),
1080
- mediaType: (_a6 = response.headers.get("content-type")) != null ? _a6 : void 0
1081
- };
1082
- } catch (error) {
1083
- if (DownloadError.isInstance(error)) {
636
+ if (error instanceof Error && APICallError.isInstance(error) && error.isRetryable === true && tryNumber <= maxRetries) {
637
+ await delay(delayInMs);
638
+ return _retryWithExponentialBackoff(
639
+ f,
640
+ { maxRetries, delayInMs: backoffFactor * delayInMs, backoffFactor },
641
+ newErrors
642
+ );
643
+ }
644
+ if (tryNumber === 1) {
1084
645
  throw error;
1085
646
  }
1086
- throw new DownloadError({ url: urlText, cause: error });
647
+ throw new RetryError({
648
+ message: `Failed after ${tryNumber} attempts with non-retryable error: '${errorMessage}'`,
649
+ reason: "errorNotRetryable",
650
+ errors: newErrors
651
+ });
1087
652
  }
1088
653
  }
1089
654
 
1090
- // core/util/detect-media-type.ts
1091
- import { convertBase64ToUint8Array as convertBase64ToUint8Array2 } from "@ai-sdk/provider-utils";
1092
- var imageMediaTypeSignatures = [
1093
- {
1094
- mediaType: "image/gif",
1095
- bytesPrefix: [71, 73, 70],
1096
- base64Prefix: "R0lG"
1097
- },
1098
- {
1099
- mediaType: "image/png",
1100
- bytesPrefix: [137, 80, 78, 71],
1101
- base64Prefix: "iVBORw"
1102
- },
1103
- {
1104
- mediaType: "image/jpeg",
1105
- bytesPrefix: [255, 216],
1106
- base64Prefix: "/9j/"
1107
- },
1108
- {
1109
- mediaType: "image/webp",
1110
- bytesPrefix: [82, 73, 70, 70],
1111
- base64Prefix: "UklGRg"
1112
- },
1113
- {
1114
- mediaType: "image/bmp",
1115
- bytesPrefix: [66, 77],
1116
- base64Prefix: "Qk"
1117
- },
1118
- {
1119
- mediaType: "image/tiff",
1120
- bytesPrefix: [73, 73, 42, 0],
1121
- base64Prefix: "SUkqAA"
1122
- },
1123
- {
1124
- mediaType: "image/tiff",
1125
- bytesPrefix: [77, 77, 0, 42],
1126
- base64Prefix: "TU0AKg"
1127
- },
1128
- {
1129
- mediaType: "image/avif",
1130
- bytesPrefix: [
1131
- 0,
1132
- 0,
1133
- 0,
1134
- 32,
1135
- 102,
1136
- 116,
1137
- 121,
1138
- 112,
1139
- 97,
1140
- 118,
1141
- 105,
1142
- 102
1143
- ],
1144
- base64Prefix: "AAAAIGZ0eXBhdmlm"
1145
- },
1146
- {
1147
- mediaType: "image/heic",
1148
- bytesPrefix: [
1149
- 0,
1150
- 0,
1151
- 0,
1152
- 32,
1153
- 102,
1154
- 116,
1155
- 121,
1156
- 112,
1157
- 104,
1158
- 101,
1159
- 105,
1160
- 99
1161
- ],
1162
- base64Prefix: "AAAAIGZ0eXBoZWlj"
655
+ // core/prompt/prepare-retries.ts
656
+ function prepareRetries({
657
+ maxRetries
658
+ }) {
659
+ if (maxRetries != null) {
660
+ if (!Number.isInteger(maxRetries)) {
661
+ throw new InvalidArgumentError({
662
+ parameter: "maxRetries",
663
+ value: maxRetries,
664
+ message: "maxRetries must be an integer"
665
+ });
666
+ }
667
+ if (maxRetries < 0) {
668
+ throw new InvalidArgumentError({
669
+ parameter: "maxRetries",
670
+ value: maxRetries,
671
+ message: "maxRetries must be >= 0"
672
+ });
673
+ }
1163
674
  }
1164
- ];
1165
- var stripID3 = (data) => {
1166
- const bytes = typeof data === "string" ? convertBase64ToUint8Array2(data) : data;
1167
- const id3Size = (bytes[6] & 127) << 21 | (bytes[7] & 127) << 14 | (bytes[8] & 127) << 7 | bytes[9] & 127;
1168
- return bytes.slice(id3Size + 10);
1169
- };
1170
- function stripID3TagsIfPresent(data) {
1171
- const hasId3 = typeof data === "string" && data.startsWith("SUQz") || typeof data !== "string" && data.length > 10 && data[0] === 73 && // 'I'
1172
- data[1] === 68 && // 'D'
1173
- data[2] === 51;
1174
- return hasId3 ? stripID3(data) : data;
675
+ const maxRetriesResult = maxRetries != null ? maxRetries : 2;
676
+ return {
677
+ maxRetries: maxRetriesResult,
678
+ retry: retryWithExponentialBackoff({ maxRetries: maxRetriesResult })
679
+ };
1175
680
  }
1176
- function detectMediaType({
1177
- data,
1178
- signatures
681
+
682
+ // core/util/index.ts
683
+ import {
684
+ asSchema,
685
+ generateId,
686
+ jsonSchema
687
+ } from "@ai-sdk/provider-utils";
688
+
689
+ // core/util/is-non-empty-object.ts
690
+ function isNonEmptyObject(object) {
691
+ return object != null && Object.keys(object).length > 0;
692
+ }
693
+
694
+ // core/prompt/prepare-tools-and-tool-choice.ts
695
+ function prepareToolsAndToolChoice({
696
+ tools,
697
+ toolChoice,
698
+ activeTools
1179
699
  }) {
1180
- const processedData = stripID3TagsIfPresent(data);
1181
- for (const signature of signatures) {
1182
- if (typeof processedData === "string" ? processedData.startsWith(signature.base64Prefix) : processedData.length >= signature.bytesPrefix.length && signature.bytesPrefix.every(
1183
- (byte, index) => processedData[index] === byte
1184
- )) {
1185
- return signature.mediaType;
1186
- }
700
+ if (!isNonEmptyObject(tools)) {
701
+ return {
702
+ tools: void 0,
703
+ toolChoice: void 0
704
+ };
1187
705
  }
1188
- return void 0;
706
+ const filteredTools = activeTools != null ? Object.entries(tools).filter(
707
+ ([name6]) => activeTools.includes(name6)
708
+ ) : Object.entries(tools);
709
+ return {
710
+ tools: filteredTools.map(([name6, tool]) => {
711
+ const toolType = tool.type;
712
+ switch (toolType) {
713
+ case void 0:
714
+ case "function":
715
+ return {
716
+ type: "function",
717
+ name: name6,
718
+ description: tool.description,
719
+ parameters: asSchema(tool.parameters).jsonSchema
720
+ };
721
+ case "provider-defined":
722
+ return {
723
+ type: "provider-defined",
724
+ name: name6,
725
+ id: tool.id,
726
+ args: tool.args
727
+ };
728
+ default: {
729
+ const exhaustiveCheck = toolType;
730
+ throw new Error(`Unsupported tool type: ${exhaustiveCheck}`);
731
+ }
732
+ }
733
+ }),
734
+ toolChoice: toolChoice == null ? { type: "auto" } : typeof toolChoice === "string" ? { type: toolChoice } : { type: "tool", toolName: toolChoice.toolName }
735
+ };
1189
736
  }
1190
737
 
1191
- // core/prompt/invalid-message-role-error.ts
738
+ // core/prompt/standardize-prompt.ts
739
+ import { InvalidPromptError } from "@ai-sdk/provider";
740
+ import { safeValidateTypes } from "@ai-sdk/provider-utils";
741
+ import { z as z7 } from "zod";
742
+
743
+ // core/ui/get-ui-text.ts
744
+ function getUIText(parts) {
745
+ return parts.map((part) => part.type === "text" ? part.text : "").join("");
746
+ }
747
+
748
+ // core/prompt/message-conversion-error.ts
1192
749
  import { AISDKError as AISDKError6 } from "@ai-sdk/provider";
1193
- var name5 = "AI_InvalidMessageRoleError";
750
+ var name5 = "AI_MessageConversionError";
1194
751
  var marker5 = `vercel.ai.error.${name5}`;
1195
752
  var symbol5 = Symbol.for(marker5);
1196
753
  var _a5;
1197
- var InvalidMessageRoleError = class extends AISDKError6 {
754
+ var MessageConversionError = class extends AISDKError6 {
1198
755
  constructor({
1199
- role,
1200
- message = `Invalid message role: '${role}'. Must be one of: "system", "user", "assistant", "tool".`
756
+ originalMessage,
757
+ message
1201
758
  }) {
1202
759
  super({ name: name5, message });
1203
760
  this[_a5] = true;
1204
- this.role = role;
761
+ this.originalMessage = originalMessage;
1205
762
  }
1206
763
  static isInstance(error) {
1207
764
  return AISDKError6.hasMarker(error, marker5);
@@ -1209,324 +766,400 @@ var InvalidMessageRoleError = class extends AISDKError6 {
1209
766
  };
1210
767
  _a5 = symbol5;
1211
768
 
1212
- // core/prompt/convert-to-language-model-prompt.ts
1213
- async function convertToLanguageModelPrompt({
1214
- prompt,
1215
- supportedUrls,
1216
- downloadImplementation = download
1217
- }) {
1218
- const downloadedAssets = await downloadAssets(
1219
- prompt.messages,
1220
- downloadImplementation,
1221
- supportedUrls
1222
- );
1223
- return [
1224
- ...prompt.system != null ? [{ role: "system", content: prompt.system }] : [],
1225
- ...prompt.messages.map(
1226
- (message) => convertToLanguageModelMessage(message, downloadedAssets)
1227
- )
1228
- ];
1229
- }
1230
- function convertToLanguageModelMessage(message, downloadedAssets) {
1231
- const role = message.role;
1232
- switch (role) {
1233
- case "system": {
1234
- return {
1235
- role: "system",
1236
- content: message.content,
1237
- providerOptions: message.providerOptions
1238
- };
1239
- }
1240
- case "user": {
1241
- if (typeof message.content === "string") {
1242
- return {
1243
- role: "user",
1244
- content: [{ type: "text", text: message.content }],
1245
- providerOptions: message.providerOptions
1246
- };
769
+ // core/prompt/convert-to-model-messages.ts
770
+ function convertToModelMessages(messages, options) {
771
+ var _a6, _b;
772
+ const tools = (_a6 = options == null ? void 0 : options.tools) != null ? _a6 : {};
773
+ const modelMessages = [];
774
+ for (const message of messages) {
775
+ switch (message.role) {
776
+ case "system": {
777
+ modelMessages.push({
778
+ role: "system",
779
+ content: getUIText(message.parts)
780
+ });
781
+ break;
1247
782
  }
1248
- return {
1249
- role: "user",
1250
- content: message.content.map((part) => convertPartToLanguageModelPart(part, downloadedAssets)).filter((part) => part.type !== "text" || part.text !== ""),
1251
- providerOptions: message.providerOptions
1252
- };
1253
- }
1254
- case "assistant": {
1255
- if (typeof message.content === "string") {
1256
- return {
1257
- role: "assistant",
1258
- content: [{ type: "text", text: message.content }],
1259
- providerOptions: message.providerOptions
1260
- };
783
+ case "user": {
784
+ modelMessages.push({
785
+ role: "user",
786
+ content: message.parts.filter(
787
+ (part) => part.type === "text" || part.type === "file"
788
+ ).map(
789
+ (part) => part.type === "file" ? {
790
+ type: "file",
791
+ mediaType: part.mediaType,
792
+ filename: part.filename,
793
+ data: part.url
794
+ } : part
795
+ )
796
+ });
797
+ break;
1261
798
  }
1262
- return {
1263
- role: "assistant",
1264
- content: message.content.filter(
1265
- // remove empty text parts:
1266
- (part) => part.type !== "text" || part.text !== ""
1267
- ).map((part) => {
1268
- const providerOptions = part.providerOptions;
1269
- switch (part.type) {
1270
- case "file": {
1271
- const { data, mediaType } = convertToLanguageModelV2DataContent(
1272
- part.data
1273
- );
1274
- return {
1275
- type: "file",
1276
- data,
1277
- filename: part.filename,
1278
- mediaType: mediaType != null ? mediaType : part.mediaType,
1279
- providerOptions
1280
- };
1281
- }
1282
- case "reasoning": {
1283
- return {
1284
- type: "reasoning",
1285
- text: part.text,
1286
- providerOptions
1287
- };
799
+ case "assistant": {
800
+ if (message.parts != null) {
801
+ let processBlock2 = function() {
802
+ const content = [];
803
+ for (const part of block) {
804
+ switch (part.type) {
805
+ case "text": {
806
+ content.push(part);
807
+ break;
808
+ }
809
+ case "file": {
810
+ content.push({
811
+ type: "file",
812
+ mediaType: part.mediaType,
813
+ data: part.url
814
+ });
815
+ break;
816
+ }
817
+ case "reasoning": {
818
+ content.push({
819
+ type: "reasoning",
820
+ text: part.text,
821
+ providerOptions: part.providerMetadata
822
+ });
823
+ break;
824
+ }
825
+ case "tool-invocation":
826
+ content.push({
827
+ type: "tool-call",
828
+ toolCallId: part.toolInvocation.toolCallId,
829
+ toolName: part.toolInvocation.toolName,
830
+ args: part.toolInvocation.args
831
+ });
832
+ break;
833
+ default: {
834
+ const _exhaustiveCheck = part;
835
+ throw new Error(`Unsupported part: ${_exhaustiveCheck}`);
836
+ }
837
+ }
1288
838
  }
1289
- case "text": {
1290
- return {
1291
- type: "text",
1292
- text: part.text,
1293
- providerOptions
1294
- };
839
+ modelMessages.push({
840
+ role: "assistant",
841
+ content
842
+ });
843
+ const stepInvocations = block.filter(
844
+ (part) => part.type === "tool-invocation"
845
+ ).map((part) => part.toolInvocation);
846
+ if (stepInvocations.length > 0) {
847
+ modelMessages.push({
848
+ role: "tool",
849
+ content: stepInvocations.map(
850
+ (toolInvocation) => {
851
+ if (!("result" in toolInvocation)) {
852
+ throw new MessageConversionError({
853
+ originalMessage: message,
854
+ message: "ToolInvocation must have a result: " + JSON.stringify(toolInvocation)
855
+ });
856
+ }
857
+ const { toolCallId, toolName, result } = toolInvocation;
858
+ const tool = tools[toolName];
859
+ return (tool == null ? void 0 : tool.experimental_toToolResultContent) != null ? {
860
+ type: "tool-result",
861
+ toolCallId,
862
+ toolName,
863
+ result: tool.experimental_toToolResultContent(result),
864
+ experimental_content: tool.experimental_toToolResultContent(result)
865
+ } : {
866
+ type: "tool-result",
867
+ toolCallId,
868
+ toolName,
869
+ result
870
+ };
871
+ }
872
+ )
873
+ });
1295
874
  }
1296
- case "tool-call": {
1297
- return {
1298
- type: "tool-call",
1299
- toolCallId: part.toolCallId,
1300
- toolName: part.toolName,
1301
- args: part.args,
1302
- providerOptions
1303
- };
875
+ block = [];
876
+ blockHasToolInvocations = false;
877
+ currentStep++;
878
+ };
879
+ var processBlock = processBlock2;
880
+ let currentStep = 0;
881
+ let blockHasToolInvocations = false;
882
+ let block = [];
883
+ for (const part of message.parts) {
884
+ switch (part.type) {
885
+ case "text": {
886
+ if (blockHasToolInvocations) {
887
+ processBlock2();
888
+ }
889
+ block.push(part);
890
+ break;
891
+ }
892
+ case "file":
893
+ case "reasoning": {
894
+ block.push(part);
895
+ break;
896
+ }
897
+ case "tool-invocation": {
898
+ if (((_b = part.toolInvocation.step) != null ? _b : 0) !== currentStep) {
899
+ processBlock2();
900
+ }
901
+ block.push(part);
902
+ blockHasToolInvocations = true;
903
+ break;
904
+ }
1304
905
  }
1305
906
  }
1306
- }),
1307
- providerOptions: message.providerOptions
1308
- };
1309
- }
1310
- case "tool": {
1311
- return {
1312
- role: "tool",
1313
- content: message.content.map((part) => ({
1314
- type: "tool-result",
1315
- toolCallId: part.toolCallId,
1316
- toolName: part.toolName,
1317
- result: part.result,
1318
- content: part.experimental_content,
1319
- isError: part.isError,
1320
- providerOptions: part.providerOptions
1321
- })),
1322
- providerOptions: message.providerOptions
1323
- };
1324
- }
1325
- default: {
1326
- const _exhaustiveCheck = role;
1327
- throw new InvalidMessageRoleError({ role: _exhaustiveCheck });
1328
- }
1329
- }
1330
- }
1331
- async function downloadAssets(messages, downloadImplementation, supportedUrls) {
1332
- const urls = messages.filter((message) => message.role === "user").map((message) => message.content).filter(
1333
- (content) => Array.isArray(content)
1334
- ).flat().filter(
1335
- (part) => part.type === "image" || part.type === "file"
1336
- ).map((part) => {
1337
- var _a6;
1338
- const mediaType = (_a6 = part.mediaType) != null ? _a6 : part.type === "image" ? "image/*" : void 0;
1339
- let data = part.type === "image" ? part.image : part.data;
1340
- if (typeof data === "string") {
1341
- try {
1342
- data = new URL(data);
1343
- } catch (ignored) {
1344
- }
1345
- }
1346
- return { mediaType, data };
1347
- }).filter(
1348
- (part) => part.data instanceof URL && part.mediaType != null && !isUrlSupported({
1349
- url: part.data.toString(),
1350
- mediaType: part.mediaType,
1351
- supportedUrls
1352
- })
1353
- ).map((part) => part.data);
1354
- const downloadedImages = await Promise.all(
1355
- urls.map(async (url) => ({
1356
- url,
1357
- data: await downloadImplementation({ url })
1358
- }))
1359
- );
1360
- return Object.fromEntries(
1361
- downloadedImages.map(({ url, data }) => [url.toString(), data])
1362
- );
1363
- }
1364
- function convertPartToLanguageModelPart(part, downloadedAssets) {
1365
- var _a6, _b;
1366
- if (part.type === "text") {
1367
- return {
1368
- type: "text",
1369
- text: part.text,
1370
- providerOptions: part.providerOptions
1371
- };
1372
- }
1373
- let originalData;
1374
- const type = part.type;
1375
- switch (type) {
1376
- case "image":
1377
- originalData = part.image;
1378
- break;
1379
- case "file":
1380
- originalData = part.data;
1381
- break;
1382
- default:
1383
- throw new Error(`Unsupported part type: ${type}`);
1384
- }
1385
- const { data: convertedData, mediaType: convertedMediaType } = convertToLanguageModelV2DataContent(originalData);
1386
- let mediaType = convertedMediaType != null ? convertedMediaType : part.mediaType;
1387
- let data = convertedData;
1388
- if (data instanceof URL) {
1389
- const downloadedFile = downloadedAssets[data.toString()];
1390
- if (downloadedFile) {
1391
- data = downloadedFile.data;
1392
- mediaType = (_a6 = downloadedFile.mediaType) != null ? _a6 : mediaType;
1393
- }
1394
- }
1395
- switch (type) {
1396
- case "image": {
1397
- if (data instanceof Uint8Array || typeof data === "string") {
1398
- mediaType = (_b = detectMediaType({ data, signatures: imageMediaTypeSignatures })) != null ? _b : mediaType;
907
+ processBlock2();
908
+ break;
909
+ }
910
+ break;
1399
911
  }
1400
- return {
1401
- type: "file",
1402
- mediaType: mediaType != null ? mediaType : "image/*",
1403
- // any image
1404
- filename: void 0,
1405
- data,
1406
- providerOptions: part.providerOptions
1407
- };
1408
- }
1409
- case "file": {
1410
- if (mediaType == null) {
1411
- throw new Error(`Media type is missing for file part`);
912
+ default: {
913
+ const _exhaustiveCheck = message.role;
914
+ throw new MessageConversionError({
915
+ originalMessage: message,
916
+ message: `Unsupported role: ${_exhaustiveCheck}`
917
+ });
1412
918
  }
1413
- return {
1414
- type: "file",
1415
- mediaType,
1416
- filename: part.filename,
1417
- data,
1418
- providerOptions: part.providerOptions
1419
- };
1420
919
  }
1421
920
  }
921
+ return modelMessages;
1422
922
  }
1423
923
 
1424
- // core/util/prepare-response-headers.ts
1425
- function prepareResponseHeaders(headers, {
1426
- contentType,
1427
- dataStreamVersion
1428
- }) {
1429
- const responseHeaders = new Headers(headers != null ? headers : {});
1430
- if (!responseHeaders.has("Content-Type")) {
1431
- responseHeaders.set("Content-Type", contentType);
924
+ // core/prompt/detect-prompt-type.ts
925
+ function detectPromptType(prompt) {
926
+ if (!Array.isArray(prompt)) {
927
+ return "other";
928
+ }
929
+ if (prompt.length === 0) {
930
+ return "model-messages";
931
+ }
932
+ const characteristics = prompt.map(detectSingleMessageCharacteristics);
933
+ if (characteristics.some((c) => c === "has-ui-specific-parts")) {
934
+ return "ui-messages";
935
+ } else if (characteristics.every(
936
+ (c) => c === "has-core-specific-parts" || c === "message"
937
+ )) {
938
+ return "model-messages";
939
+ } else {
940
+ return "other";
1432
941
  }
1433
- if (dataStreamVersion !== void 0) {
1434
- responseHeaders.set("X-Vercel-AI-Data-Stream", dataStreamVersion);
942
+ }
943
+ function detectSingleMessageCharacteristics(message) {
944
+ if (typeof message === "object" && message !== null && (message.role === "function" || // UI-only role
945
+ message.role === "data" || // UI-only role
946
+ "toolInvocations" in message || // UI-specific field
947
+ "parts" in message || // UI-specific field
948
+ "experimental_attachments" in message)) {
949
+ return "has-ui-specific-parts";
950
+ } else if (typeof message === "object" && message !== null && "content" in message && (Array.isArray(message.content) || // Core messages can have array content
951
+ "providerOptions" in message)) {
952
+ return "has-core-specific-parts";
953
+ } else if (typeof message === "object" && message !== null && "role" in message && "content" in message && typeof message.content === "string" && ["system", "user", "assistant", "tool"].includes(message.role)) {
954
+ return "message";
955
+ } else {
956
+ return "other";
1435
957
  }
1436
- return responseHeaders;
1437
958
  }
1438
959
 
1439
- // core/util/merge-streams.ts
1440
- function mergeStreams(stream1, stream2) {
1441
- const reader1 = stream1.getReader();
1442
- const reader2 = stream2.getReader();
1443
- let lastRead1 = void 0;
1444
- let lastRead2 = void 0;
1445
- let stream1Done = false;
1446
- let stream2Done = false;
1447
- async function readStream1(controller) {
1448
- try {
1449
- if (lastRead1 == null) {
1450
- lastRead1 = reader1.read();
1451
- }
1452
- const result = await lastRead1;
1453
- lastRead1 = void 0;
1454
- if (!result.done) {
1455
- controller.enqueue(result.value);
1456
- } else {
1457
- controller.close();
1458
- }
1459
- } catch (error) {
1460
- controller.error(error);
1461
- }
960
+ // core/prompt/message.ts
961
+ import { z as z6 } from "zod";
962
+
963
+ // core/types/provider-metadata.ts
964
+ import { z as z3 } from "zod";
965
+
966
+ // core/types/json-value.ts
967
+ import { z as z2 } from "zod";
968
+ var jsonValueSchema = z2.lazy(
969
+ () => z2.union([
970
+ z2.null(),
971
+ z2.string(),
972
+ z2.number(),
973
+ z2.boolean(),
974
+ z2.record(z2.string(), jsonValueSchema),
975
+ z2.array(jsonValueSchema)
976
+ ])
977
+ );
978
+
979
+ // core/types/provider-metadata.ts
980
+ var providerMetadataSchema = z3.record(
981
+ z3.string(),
982
+ z3.record(z3.string(), jsonValueSchema)
983
+ );
984
+
985
+ // core/prompt/content-part.ts
986
+ import { z as z5 } from "zod";
987
+
988
+ // core/prompt/tool-result-content.ts
989
+ import { z as z4 } from "zod";
990
+ var toolResultContentSchema = z4.array(
991
+ z4.union([
992
+ z4.object({ type: z4.literal("text"), text: z4.string() }),
993
+ z4.object({
994
+ type: z4.literal("image"),
995
+ data: z4.string(),
996
+ mediaType: z4.string().optional()
997
+ })
998
+ ])
999
+ );
1000
+
1001
+ // core/prompt/content-part.ts
1002
+ var textPartSchema = z5.object({
1003
+ type: z5.literal("text"),
1004
+ text: z5.string(),
1005
+ providerOptions: providerMetadataSchema.optional()
1006
+ });
1007
+ var imagePartSchema = z5.object({
1008
+ type: z5.literal("image"),
1009
+ image: z5.union([dataContentSchema, z5.instanceof(URL)]),
1010
+ mediaType: z5.string().optional(),
1011
+ providerOptions: providerMetadataSchema.optional()
1012
+ });
1013
+ var filePartSchema = z5.object({
1014
+ type: z5.literal("file"),
1015
+ data: z5.union([dataContentSchema, z5.instanceof(URL)]),
1016
+ filename: z5.string().optional(),
1017
+ mediaType: z5.string(),
1018
+ providerOptions: providerMetadataSchema.optional()
1019
+ });
1020
+ var reasoningPartSchema = z5.object({
1021
+ type: z5.literal("reasoning"),
1022
+ text: z5.string(),
1023
+ providerOptions: providerMetadataSchema.optional()
1024
+ });
1025
+ var toolCallPartSchema = z5.object({
1026
+ type: z5.literal("tool-call"),
1027
+ toolCallId: z5.string(),
1028
+ toolName: z5.string(),
1029
+ args: z5.unknown(),
1030
+ providerOptions: providerMetadataSchema.optional()
1031
+ });
1032
+ var toolResultPartSchema = z5.object({
1033
+ type: z5.literal("tool-result"),
1034
+ toolCallId: z5.string(),
1035
+ toolName: z5.string(),
1036
+ result: z5.unknown(),
1037
+ content: toolResultContentSchema.optional(),
1038
+ isError: z5.boolean().optional(),
1039
+ providerOptions: providerMetadataSchema.optional()
1040
+ });
1041
+
1042
+ // core/prompt/message.ts
1043
+ var systemModelMessageSchema = z6.object(
1044
+ {
1045
+ role: z6.literal("system"),
1046
+ content: z6.string(),
1047
+ providerOptions: providerMetadataSchema.optional()
1462
1048
  }
1463
- async function readStream2(controller) {
1464
- try {
1465
- if (lastRead2 == null) {
1466
- lastRead2 = reader2.read();
1467
- }
1468
- const result = await lastRead2;
1469
- lastRead2 = void 0;
1470
- if (!result.done) {
1471
- controller.enqueue(result.value);
1472
- } else {
1473
- controller.close();
1474
- }
1475
- } catch (error) {
1476
- controller.error(error);
1477
- }
1049
+ );
1050
+ var userModelMessageSchema = z6.object({
1051
+ role: z6.literal("user"),
1052
+ content: z6.union([
1053
+ z6.string(),
1054
+ z6.array(z6.union([textPartSchema, imagePartSchema, filePartSchema]))
1055
+ ]),
1056
+ providerOptions: providerMetadataSchema.optional()
1057
+ });
1058
+ var assistantModelMessageSchema = z6.object({
1059
+ role: z6.literal("assistant"),
1060
+ content: z6.union([
1061
+ z6.string(),
1062
+ z6.array(
1063
+ z6.union([
1064
+ textPartSchema,
1065
+ filePartSchema,
1066
+ reasoningPartSchema,
1067
+ toolCallPartSchema
1068
+ ])
1069
+ )
1070
+ ]),
1071
+ providerOptions: providerMetadataSchema.optional()
1072
+ });
1073
+ var toolModelMessageSchema = z6.object({
1074
+ role: z6.literal("tool"),
1075
+ content: z6.array(toolResultPartSchema),
1076
+ providerOptions: providerMetadataSchema.optional()
1077
+ });
1078
+ var modelMessageSchema = z6.union([
1079
+ systemModelMessageSchema,
1080
+ userModelMessageSchema,
1081
+ assistantModelMessageSchema,
1082
+ toolModelMessageSchema
1083
+ ]);
1084
+
1085
+ // core/prompt/standardize-prompt.ts
1086
+ async function standardizePrompt({
1087
+ prompt,
1088
+ tools
1089
+ }) {
1090
+ if (prompt.prompt == null && prompt.messages == null) {
1091
+ throw new InvalidPromptError({
1092
+ prompt,
1093
+ message: "prompt or messages must be defined"
1094
+ });
1478
1095
  }
1479
- return new ReadableStream({
1480
- async pull(controller) {
1481
- try {
1482
- if (stream1Done) {
1483
- await readStream2(controller);
1484
- return;
1485
- }
1486
- if (stream2Done) {
1487
- await readStream1(controller);
1488
- return;
1489
- }
1490
- if (lastRead1 == null) {
1491
- lastRead1 = reader1.read();
1492
- }
1493
- if (lastRead2 == null) {
1494
- lastRead2 = reader2.read();
1495
- }
1496
- const { result, reader } = await Promise.race([
1497
- lastRead1.then((result2) => ({ result: result2, reader: reader1 })),
1498
- lastRead2.then((result2) => ({ result: result2, reader: reader2 }))
1499
- ]);
1500
- if (!result.done) {
1501
- controller.enqueue(result.value);
1502
- }
1503
- if (reader === reader1) {
1504
- lastRead1 = void 0;
1505
- if (result.done) {
1506
- await readStream2(controller);
1507
- stream1Done = true;
1508
- }
1509
- } else {
1510
- lastRead2 = void 0;
1511
- if (result.done) {
1512
- stream2Done = true;
1513
- await readStream1(controller);
1514
- }
1096
+ if (prompt.prompt != null && prompt.messages != null) {
1097
+ throw new InvalidPromptError({
1098
+ prompt,
1099
+ message: "prompt and messages cannot be defined at the same time"
1100
+ });
1101
+ }
1102
+ if (prompt.system != null && typeof prompt.system !== "string") {
1103
+ throw new InvalidPromptError({
1104
+ prompt,
1105
+ message: "system must be a string"
1106
+ });
1107
+ }
1108
+ if (prompt.prompt != null) {
1109
+ if (typeof prompt.prompt !== "string") {
1110
+ throw new InvalidPromptError({
1111
+ prompt,
1112
+ message: "prompt must be a string"
1113
+ });
1114
+ }
1115
+ return {
1116
+ system: prompt.system,
1117
+ messages: [
1118
+ {
1119
+ role: "user",
1120
+ content: prompt.prompt
1515
1121
  }
1516
- } catch (error) {
1517
- controller.error(error);
1518
- }
1519
- },
1520
- cancel() {
1521
- reader1.cancel();
1522
- reader2.cancel();
1122
+ ]
1123
+ };
1124
+ }
1125
+ if (prompt.messages != null) {
1126
+ const promptType = detectPromptType(prompt.messages);
1127
+ if (promptType === "other") {
1128
+ throw new InvalidPromptError({
1129
+ prompt,
1130
+ message: "messages must be an array of ModelMessage or UIMessage"
1131
+ });
1523
1132
  }
1524
- });
1133
+ const messages = promptType === "ui-messages" ? convertToModelMessages(prompt.messages, {
1134
+ tools
1135
+ }) : prompt.messages;
1136
+ if (messages.length === 0) {
1137
+ throw new InvalidPromptError({
1138
+ prompt,
1139
+ message: "messages must not be empty"
1140
+ });
1141
+ }
1142
+ const validationResult = await safeValidateTypes({
1143
+ value: messages,
1144
+ schema: z7.array(modelMessageSchema)
1145
+ });
1146
+ if (!validationResult.success) {
1147
+ throw new InvalidPromptError({
1148
+ prompt,
1149
+ message: "messages must be an array of ModelMessage or UIMessage",
1150
+ cause: validationResult.error
1151
+ });
1152
+ }
1153
+ return {
1154
+ messages,
1155
+ system: prompt.system
1156
+ };
1157
+ }
1158
+ throw new Error("unreachable");
1525
1159
  }
1526
1160
 
1527
1161
  // streams/stream-callbacks.ts
1528
1162
  function createCallbacksTransformer(callbacks = {}) {
1529
- const textEncoder = new TextEncoder();
1530
1163
  let aggregatedResponse = "";
1531
1164
  return new TransformStream({
1532
1165
  async start() {
@@ -1534,7 +1167,7 @@ function createCallbacksTransformer(callbacks = {}) {
1534
1167
  await callbacks.onStart();
1535
1168
  },
1536
1169
  async transform(message, controller) {
1537
- controller.enqueue(textEncoder.encode(message));
1170
+ controller.enqueue(message);
1538
1171
  aggregatedResponse += message;
1539
1172
  if (callbacks.onToken)
1540
1173
  await callbacks.onToken(message);
@@ -1543,9 +1176,6 @@ function createCallbacksTransformer(callbacks = {}) {
1543
1176
  }
1544
1177
  },
1545
1178
  async flush() {
1546
- if (callbacks.onCompletion) {
1547
- await callbacks.onCompletion(aggregatedResponse);
1548
- }
1549
1179
  if (callbacks.onFinal) {
1550
1180
  await callbacks.onFinal(aggregatedResponse);
1551
1181
  }
@@ -1555,78 +1185,11 @@ function createCallbacksTransformer(callbacks = {}) {
1555
1185
 
1556
1186
  // util/constants.ts
1557
1187
  var HANGING_STREAM_WARNING_TIME_MS = 15 * 1e3;
1558
-
1559
- // streams/stream-data.ts
1560
- var StreamData = class {
1561
- constructor() {
1562
- this.encoder = new TextEncoder();
1563
- this.controller = null;
1564
- this.isClosed = false;
1565
- this.warningTimeout = null;
1566
- const self = this;
1567
- this.stream = new ReadableStream({
1568
- start: async (controller) => {
1569
- self.controller = controller;
1570
- if (process.env.NODE_ENV === "development") {
1571
- self.warningTimeout = setTimeout(() => {
1572
- console.warn(
1573
- "The data stream is hanging. Did you forget to close it with `data.close()`?"
1574
- );
1575
- }, HANGING_STREAM_WARNING_TIME_MS);
1576
- }
1577
- },
1578
- pull: (controller) => {
1579
- },
1580
- cancel: (reason) => {
1581
- this.isClosed = true;
1582
- }
1583
- });
1584
- }
1585
- async close() {
1586
- if (this.isClosed) {
1587
- throw new Error("Data Stream has already been closed.");
1588
- }
1589
- if (!this.controller) {
1590
- throw new Error("Stream controller is not initialized.");
1591
- }
1592
- this.controller.close();
1593
- this.isClosed = true;
1594
- if (this.warningTimeout) {
1595
- clearTimeout(this.warningTimeout);
1596
- }
1597
- }
1598
- append(value) {
1599
- if (this.isClosed) {
1600
- throw new Error("Data Stream has already been closed.");
1601
- }
1602
- if (!this.controller) {
1603
- throw new Error("Stream controller is not initialized.");
1604
- }
1605
- this.controller.enqueue(
1606
- this.encoder.encode(formatDataStreamPart("data", [value]))
1607
- );
1608
- }
1609
- appendMessageAnnotation(value) {
1610
- if (this.isClosed) {
1611
- throw new Error("Data Stream has already been closed.");
1612
- }
1613
- if (!this.controller) {
1614
- throw new Error("Stream controller is not initialized.");
1615
- }
1616
- this.controller.enqueue(
1617
- this.encoder.encode(formatDataStreamPart("message_annotations", [value]))
1618
- );
1619
- }
1620
- };
1621
1188
  export {
1622
1189
  HANGING_STREAM_WARNING_TIME_MS,
1623
- StreamData,
1624
1190
  convertToLanguageModelPrompt,
1625
1191
  createCallbacksTransformer,
1626
- formatDataStreamPart,
1627
- mergeStreams,
1628
1192
  prepareCallSettings,
1629
- prepareResponseHeaders,
1630
1193
  prepareRetries,
1631
1194
  prepareToolsAndToolChoice,
1632
1195
  standardizePrompt