ai 3.4.6 → 3.4.8

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.4.6",
3
+ "version": "3.4.8",
4
4
  "description": "AI SDK by Vercel - The AI Toolkit for TypeScript and JavaScript",
5
5
  "license": "Apache-2.0",
6
6
  "sideEffects": false,
@@ -70,7 +70,7 @@
70
70
  "@ai-sdk/solid": "0.0.49",
71
71
  "@ai-sdk/svelte": "0.0.51",
72
72
  "@ai-sdk/ui-utils": "0.0.46",
73
- "@ai-sdk/vue": "0.0.53",
73
+ "@ai-sdk/vue": "0.0.54",
74
74
  "@opentelemetry/api": "1.9.0",
75
75
  "eventsource-parser": "1.1.2",
76
76
  "jsondiffpatch": "0.6.0",
@@ -214,7 +214,10 @@ function createAI({
214
214
  import { safeParseJSON } from "@ai-sdk/provider-utils";
215
215
 
216
216
  // core/prompt/convert-to-language-model-prompt.ts
217
- import { getErrorMessage } from "@ai-sdk/provider-utils";
217
+ import {
218
+ convertUint8ArrayToBase64 as convertUint8ArrayToBase642,
219
+ getErrorMessage
220
+ } from "@ai-sdk/provider-utils";
218
221
 
219
222
  // util/download-error.ts
220
223
  import { AISDKError } from "@ai-sdk/provider";
@@ -434,6 +437,22 @@ var InvalidMessageRoleError = class extends AISDKError3 {
434
437
  };
435
438
  _a3 = symbol3;
436
439
 
440
+ // core/prompt/split-data-url.ts
441
+ function splitDataUrl(dataUrl) {
442
+ try {
443
+ const [header, base64Content] = dataUrl.split(",");
444
+ return {
445
+ mimeType: header.split(";")[0].split(":")[1],
446
+ base64Content
447
+ };
448
+ } catch (error) {
449
+ return {
450
+ mimeType: void 0,
451
+ base64Content: void 0
452
+ };
453
+ }
454
+ }
455
+
437
456
  // core/prompt/convert-to-language-model-prompt.ts
438
457
  async function convertToLanguageModelPrompt({
439
458
  prompt,
@@ -444,7 +463,7 @@ async function convertToLanguageModelPrompt({
444
463
  if (prompt.system != null) {
445
464
  languageModelMessages.push({ role: "system", content: prompt.system });
446
465
  }
447
- const downloadedImages = modelSupportsImageUrls || prompt.messages == null ? null : await downloadImages(prompt.messages, downloadImplementation);
466
+ const downloadedAssets = modelSupportsImageUrls || prompt.messages == null ? null : await downloadAssets(prompt.messages, downloadImplementation);
448
467
  const promptType = prompt.type;
449
468
  switch (promptType) {
450
469
  case "prompt": {
@@ -457,7 +476,7 @@ async function convertToLanguageModelPrompt({
457
476
  case "messages": {
458
477
  languageModelMessages.push(
459
478
  ...prompt.messages.map(
460
- (message) => convertToLanguageModelMessage(message, downloadedImages)
479
+ (message) => convertToLanguageModelMessage(message, downloadedAssets)
461
480
  )
462
481
  );
463
482
  break;
@@ -469,7 +488,7 @@ async function convertToLanguageModelPrompt({
469
488
  }
470
489
  return languageModelMessages;
471
490
  }
472
- function convertToLanguageModelMessage(message, downloadedImages) {
491
+ function convertToLanguageModelMessage(message, downloadedAssets) {
473
492
  const role = message.role;
474
493
  switch (role) {
475
494
  case "system": {
@@ -491,7 +510,7 @@ function convertToLanguageModelMessage(message, downloadedImages) {
491
510
  role: "user",
492
511
  content: message.content.map(
493
512
  (part) => {
494
- var _a8, _b, _c;
513
+ var _a8, _b, _c, _d, _e;
495
514
  switch (part.type) {
496
515
  case "text": {
497
516
  return {
@@ -502,7 +521,7 @@ function convertToLanguageModelMessage(message, downloadedImages) {
502
521
  }
503
522
  case "image": {
504
523
  if (part.image instanceof URL) {
505
- if (downloadedImages == null) {
524
+ if (downloadedAssets == null) {
506
525
  return {
507
526
  type: "image",
508
527
  image: part.image,
@@ -510,7 +529,7 @@ function convertToLanguageModelMessage(message, downloadedImages) {
510
529
  providerMetadata: part.experimental_providerMetadata
511
530
  };
512
531
  } else {
513
- const downloadedImage = downloadedImages[part.image.toString()];
532
+ const downloadedImage = downloadedAssets[part.image.toString()];
514
533
  return {
515
534
  type: "image",
516
535
  image: downloadedImage.data,
@@ -525,7 +544,7 @@ function convertToLanguageModelMessage(message, downloadedImages) {
525
544
  switch (url.protocol) {
526
545
  case "http:":
527
546
  case "https:": {
528
- if (downloadedImages == null) {
547
+ if (downloadedAssets == null) {
529
548
  return {
530
549
  type: "image",
531
550
  image: url,
@@ -533,7 +552,7 @@ function convertToLanguageModelMessage(message, downloadedImages) {
533
552
  providerMetadata: part.experimental_providerMetadata
534
553
  };
535
554
  } else {
536
- const downloadedImage = downloadedImages[part.image];
555
+ const downloadedImage = downloadedAssets[url.toString()];
537
556
  return {
538
557
  type: "image",
539
558
  image: downloadedImage.data,
@@ -544,8 +563,9 @@ function convertToLanguageModelMessage(message, downloadedImages) {
544
563
  }
545
564
  case "data:": {
546
565
  try {
547
- const [header, base64Content] = part.image.split(",");
548
- const mimeType = header.split(";")[0].split(":")[1];
566
+ const { mimeType, base64Content } = splitDataUrl(
567
+ part.image
568
+ );
549
569
  if (mimeType == null || base64Content == null) {
550
570
  throw new Error("Invalid data URL format");
551
571
  }
@@ -563,11 +583,6 @@ function convertToLanguageModelMessage(message, downloadedImages) {
563
583
  );
564
584
  }
565
585
  }
566
- default: {
567
- throw new Error(
568
- `Unsupported URL protocol: ${url.protocol}`
569
- );
570
- }
571
586
  }
572
587
  } catch (_ignored) {
573
588
  }
@@ -582,12 +597,75 @@ function convertToLanguageModelMessage(message, downloadedImages) {
582
597
  }
583
598
  case "file": {
584
599
  if (part.data instanceof URL) {
585
- return {
586
- type: "file",
587
- data: part.data,
588
- mimeType: part.mimeType,
589
- providerMetadata: part.experimental_providerMetadata
590
- };
600
+ if (downloadedAssets == null) {
601
+ return {
602
+ type: "file",
603
+ data: part.data,
604
+ mimeType: part.mimeType,
605
+ providerMetadata: part.experimental_providerMetadata
606
+ };
607
+ } else {
608
+ const downloadedImage = downloadedAssets[part.data.toString()];
609
+ return {
610
+ type: "file",
611
+ data: convertUint8ArrayToBase642(downloadedImage.data),
612
+ mimeType: (_d = part.mimeType) != null ? _d : downloadedImage.mimeType,
613
+ providerMetadata: part.experimental_providerMetadata
614
+ };
615
+ }
616
+ }
617
+ if (typeof part.data === "string") {
618
+ try {
619
+ const url = new URL(part.data);
620
+ switch (url.protocol) {
621
+ case "http:":
622
+ case "https:": {
623
+ if (downloadedAssets == null) {
624
+ return {
625
+ type: "file",
626
+ data: url,
627
+ mimeType: part.mimeType,
628
+ providerMetadata: part.experimental_providerMetadata
629
+ };
630
+ } else {
631
+ const downloadedImage = downloadedAssets[url.toString()];
632
+ return {
633
+ type: "file",
634
+ data: convertUint8ArrayToBase642(
635
+ downloadedImage.data
636
+ ),
637
+ mimeType: (_e = part.mimeType) != null ? _e : downloadedImage.mimeType,
638
+ providerMetadata: part.experimental_providerMetadata
639
+ };
640
+ }
641
+ }
642
+ case "data:": {
643
+ try {
644
+ const { mimeType, base64Content } = splitDataUrl(
645
+ part.data
646
+ );
647
+ if (mimeType == null || base64Content == null) {
648
+ throw new Error("Invalid data URL format");
649
+ }
650
+ return {
651
+ type: "file",
652
+ data: convertDataContentToBase64String(
653
+ base64Content
654
+ ),
655
+ mimeType,
656
+ providerMetadata: part.experimental_providerMetadata
657
+ };
658
+ } catch (error) {
659
+ throw new Error(
660
+ `Error processing data URL: ${getErrorMessage(
661
+ message
662
+ )}`
663
+ );
664
+ }
665
+ }
666
+ }
667
+ } catch (_ignored) {
668
+ }
591
669
  }
592
670
  const imageBase64 = convertDataContentToBase64String(
593
671
  part.data
@@ -647,12 +725,14 @@ function convertToLanguageModelMessage(message, downloadedImages) {
647
725
  }
648
726
  }
649
727
  }
650
- async function downloadImages(messages, downloadImplementation) {
728
+ async function downloadAssets(messages, downloadImplementation) {
651
729
  const urls = messages.filter((message) => message.role === "user").map((message) => message.content).filter(
652
730
  (content) => Array.isArray(content)
653
- ).flat().filter((part) => part.type === "image").map((part) => part.image).map(
731
+ ).flat().filter(
732
+ (part) => part.type === "image" || part.type === "file"
733
+ ).map((part) => part.type === "image" ? part.image : part.data).map(
654
734
  (part) => (
655
- // support string urls in image parts:
735
+ // support string urls:
656
736
  typeof part === "string" && (part.startsWith("http:") || part.startsWith("https:")) ? new URL(part) : part
657
737
  )
658
738
  ).filter((image) => image instanceof URL);