ai 3.2.35 → 3.2.37

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai",
3
- "version": "3.2.35",
3
+ "version": "3.2.37",
4
4
  "description": "Vercel AI SDK - The AI Toolkit for TypeScript and JavaScript",
5
5
  "license": "Apache-2.0",
6
6
  "sideEffects": false,
@@ -58,13 +58,13 @@
58
58
  }
59
59
  },
60
60
  "dependencies": {
61
- "@ai-sdk/provider": "0.0.13",
62
- "@ai-sdk/provider-utils": "1.0.4",
63
- "@ai-sdk/react": "0.0.28",
64
- "@ai-sdk/solid": "0.0.21",
65
- "@ai-sdk/svelte": "0.0.22",
66
- "@ai-sdk/ui-utils": "0.0.19",
67
- "@ai-sdk/vue": "0.0.23",
61
+ "@ai-sdk/provider": "0.0.14",
62
+ "@ai-sdk/provider-utils": "1.0.5",
63
+ "@ai-sdk/react": "0.0.30",
64
+ "@ai-sdk/solid": "0.0.23",
65
+ "@ai-sdk/svelte": "0.0.24",
66
+ "@ai-sdk/ui-utils": "0.0.20",
67
+ "@ai-sdk/vue": "0.0.24",
68
68
  "@opentelemetry/api": "1.9.0",
69
69
  "eventsource-parser": "1.1.2",
70
70
  "jsondiffpatch": "0.6.0",
@@ -239,6 +239,9 @@ async function _retryWithExponentialBackoff(f, {
239
239
  }
240
240
  }
241
241
 
242
+ // core/prompt/convert-to-language-model-prompt.ts
243
+ import { getErrorMessage as getErrorMessage2 } from "@ai-sdk/provider-utils";
244
+
242
245
  // core/util/detect-image-mimetype.ts
243
246
  var mimeTypeSignatures = [
244
247
  { mimeType: "image/gif", bytes: [71, 73, 70] },
@@ -255,6 +258,35 @@ function detectImageMimeType(image) {
255
258
  return void 0;
256
259
  }
257
260
 
261
+ // core/util/download.ts
262
+ import { DownloadError } from "@ai-sdk/provider";
263
+ async function download({
264
+ url,
265
+ fetchImplementation = fetch
266
+ }) {
267
+ var _a;
268
+ const urlText = url.toString();
269
+ try {
270
+ const response = await fetchImplementation(urlText);
271
+ if (!response.ok) {
272
+ throw new DownloadError({
273
+ url: urlText,
274
+ statusCode: response.status,
275
+ statusText: response.statusText
276
+ });
277
+ }
278
+ return {
279
+ data: new Uint8Array(await response.arrayBuffer()),
280
+ mimeType: (_a = response.headers.get("content-type")) != null ? _a : void 0
281
+ };
282
+ } catch (error) {
283
+ if (DownloadError.isDownloadError(error)) {
284
+ throw error;
285
+ }
286
+ throw new DownloadError({ url: urlText, cause: error });
287
+ }
288
+ }
289
+
258
290
  // core/prompt/data-content.ts
259
291
  import { InvalidDataContentError } from "@ai-sdk/provider";
260
292
  import {
@@ -306,12 +338,16 @@ var InvalidMessageRoleError = class extends Error {
306
338
  };
307
339
 
308
340
  // core/prompt/convert-to-language-model-prompt.ts
309
- import { getErrorMessage as getErrorMessage2 } from "@ai-sdk/provider-utils";
310
- function convertToLanguageModelPrompt(prompt) {
341
+ async function convertToLanguageModelPrompt({
342
+ prompt,
343
+ modelSupportsImageUrls = true,
344
+ downloadImplementation = download
345
+ }) {
311
346
  const languageModelMessages = [];
312
347
  if (prompt.system != null) {
313
348
  languageModelMessages.push({ role: "system", content: prompt.system });
314
349
  }
350
+ const downloadedImages = modelSupportsImageUrls || prompt.messages == null ? null : await downloadImages(prompt.messages, downloadImplementation);
315
351
  const promptType = prompt.type;
316
352
  switch (promptType) {
317
353
  case "prompt": {
@@ -323,7 +359,9 @@ function convertToLanguageModelPrompt(prompt) {
323
359
  }
324
360
  case "messages": {
325
361
  languageModelMessages.push(
326
- ...prompt.messages.map(convertToLanguageModelMessage)
362
+ ...prompt.messages.map(
363
+ (message) => convertToLanguageModelMessage(message, downloadedImages)
364
+ )
327
365
  );
328
366
  break;
329
367
  }
@@ -334,7 +372,7 @@ function convertToLanguageModelPrompt(prompt) {
334
372
  }
335
373
  return languageModelMessages;
336
374
  }
337
- function convertToLanguageModelMessage(message) {
375
+ function convertToLanguageModelMessage(message, downloadedImages) {
338
376
  const role = message.role;
339
377
  switch (role) {
340
378
  case "system": {
@@ -351,18 +389,27 @@ function convertToLanguageModelMessage(message) {
351
389
  role: "user",
352
390
  content: message.content.map(
353
391
  (part) => {
354
- var _a;
392
+ var _a, _b, _c;
355
393
  switch (part.type) {
356
394
  case "text": {
357
395
  return part;
358
396
  }
359
397
  case "image": {
360
398
  if (part.image instanceof URL) {
361
- return {
362
- type: "image",
363
- image: part.image,
364
- mimeType: part.mimeType
365
- };
399
+ if (downloadedImages == null) {
400
+ return {
401
+ type: "image",
402
+ image: part.image,
403
+ mimeType: part.mimeType
404
+ };
405
+ } else {
406
+ const downloadedImage = downloadedImages[part.image.toString()];
407
+ return {
408
+ type: "image",
409
+ image: downloadedImage.data,
410
+ mimeType: (_a = part.mimeType) != null ? _a : downloadedImage.mimeType
411
+ };
412
+ }
366
413
  }
367
414
  if (typeof part.image === "string") {
368
415
  try {
@@ -370,11 +417,20 @@ function convertToLanguageModelMessage(message) {
370
417
  switch (url.protocol) {
371
418
  case "http:":
372
419
  case "https:": {
373
- return {
374
- type: "image",
375
- image: url,
376
- mimeType: part.mimeType
377
- };
420
+ if (downloadedImages == null) {
421
+ return {
422
+ type: "image",
423
+ image: url,
424
+ mimeType: part.mimeType
425
+ };
426
+ } else {
427
+ const downloadedImage = downloadedImages[part.image];
428
+ return {
429
+ type: "image",
430
+ image: downloadedImage.data,
431
+ mimeType: (_b = part.mimeType) != null ? _b : downloadedImage.mimeType
432
+ };
433
+ }
378
434
  }
379
435
  case "data:": {
380
436
  try {
@@ -409,7 +465,7 @@ function convertToLanguageModelMessage(message) {
409
465
  return {
410
466
  type: "image",
411
467
  image: imageUint8,
412
- mimeType: (_a = part.mimeType) != null ? _a : detectImageMimeType(imageUint8)
468
+ mimeType: (_c = part.mimeType) != null ? _c : detectImageMimeType(imageUint8)
413
469
  };
414
470
  }
415
471
  }
@@ -441,6 +497,25 @@ function convertToLanguageModelMessage(message) {
441
497
  }
442
498
  }
443
499
  }
500
+ async function downloadImages(messages, downloadImplementation) {
501
+ const urls = messages.filter((message) => message.role === "user").map((message) => message.content).filter(
502
+ (content) => Array.isArray(content)
503
+ ).flat().filter((part) => part.type === "image").map((part) => part.image).map(
504
+ (part) => (
505
+ // support string urls in image parts:
506
+ typeof part === "string" && (part.startsWith("http:") || part.startsWith("https:")) ? new URL(part) : part
507
+ )
508
+ ).filter((image) => image instanceof URL);
509
+ const downloadedImages = await Promise.all(
510
+ urls.map(async (url) => ({
511
+ url,
512
+ data: await downloadImplementation({ url })
513
+ }))
514
+ );
515
+ return Object.fromEntries(
516
+ downloadedImages.map(({ url, data }) => [url.toString(), data])
517
+ );
518
+ }
444
519
 
445
520
  // core/prompt/get-validated-prompt.ts
446
521
  import { InvalidPromptError } from "@ai-sdk/provider";
@@ -1593,14 +1668,17 @@ async function streamUI({
1593
1668
  const retry = retryWithExponentialBackoff({ maxRetries });
1594
1669
  const validatedPrompt = getValidatedPrompt({ system, prompt, messages });
1595
1670
  const result = await retry(
1596
- () => model.doStream({
1671
+ async () => model.doStream({
1597
1672
  mode: {
1598
1673
  type: "regular",
1599
1674
  ...prepareToolsAndToolChoice({ tools, toolChoice })
1600
1675
  },
1601
1676
  ...prepareCallSettings(settings),
1602
1677
  inputFormat: validatedPrompt.type,
1603
- prompt: convertToLanguageModelPrompt(validatedPrompt),
1678
+ prompt: await convertToLanguageModelPrompt({
1679
+ prompt: validatedPrompt,
1680
+ modelSupportsImageUrls: model.supportsImageUrls
1681
+ }),
1604
1682
  abortSignal,
1605
1683
  headers
1606
1684
  })