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/dist/index.mjs CHANGED
@@ -591,7 +591,10 @@ var DefaultEmbedManyResult = class {
591
591
  import { createIdGenerator, safeParseJSON } from "@ai-sdk/provider-utils";
592
592
 
593
593
  // core/prompt/convert-to-language-model-prompt.ts
594
- import { getErrorMessage as getErrorMessage2 } from "@ai-sdk/provider-utils";
594
+ import {
595
+ convertUint8ArrayToBase64 as convertUint8ArrayToBase642,
596
+ getErrorMessage as getErrorMessage2
597
+ } from "@ai-sdk/provider-utils";
595
598
 
596
599
  // util/download-error.ts
597
600
  import { AISDKError as AISDKError2 } from "@ai-sdk/provider";
@@ -818,6 +821,22 @@ var InvalidMessageRoleError = class extends AISDKError4 {
818
821
  };
819
822
  _a4 = symbol4;
820
823
 
824
+ // core/prompt/split-data-url.ts
825
+ function splitDataUrl(dataUrl) {
826
+ try {
827
+ const [header, base64Content] = dataUrl.split(",");
828
+ return {
829
+ mimeType: header.split(";")[0].split(":")[1],
830
+ base64Content
831
+ };
832
+ } catch (error) {
833
+ return {
834
+ mimeType: void 0,
835
+ base64Content: void 0
836
+ };
837
+ }
838
+ }
839
+
821
840
  // core/prompt/convert-to-language-model-prompt.ts
822
841
  async function convertToLanguageModelPrompt({
823
842
  prompt,
@@ -828,7 +847,7 @@ async function convertToLanguageModelPrompt({
828
847
  if (prompt.system != null) {
829
848
  languageModelMessages.push({ role: "system", content: prompt.system });
830
849
  }
831
- const downloadedImages = modelSupportsImageUrls || prompt.messages == null ? null : await downloadImages(prompt.messages, downloadImplementation);
850
+ const downloadedAssets = modelSupportsImageUrls || prompt.messages == null ? null : await downloadAssets(prompt.messages, downloadImplementation);
832
851
  const promptType = prompt.type;
833
852
  switch (promptType) {
834
853
  case "prompt": {
@@ -841,7 +860,7 @@ async function convertToLanguageModelPrompt({
841
860
  case "messages": {
842
861
  languageModelMessages.push(
843
862
  ...prompt.messages.map(
844
- (message) => convertToLanguageModelMessage(message, downloadedImages)
863
+ (message) => convertToLanguageModelMessage(message, downloadedAssets)
845
864
  )
846
865
  );
847
866
  break;
@@ -853,7 +872,7 @@ async function convertToLanguageModelPrompt({
853
872
  }
854
873
  return languageModelMessages;
855
874
  }
856
- function convertToLanguageModelMessage(message, downloadedImages) {
875
+ function convertToLanguageModelMessage(message, downloadedAssets) {
857
876
  const role = message.role;
858
877
  switch (role) {
859
878
  case "system": {
@@ -875,7 +894,7 @@ function convertToLanguageModelMessage(message, downloadedImages) {
875
894
  role: "user",
876
895
  content: message.content.map(
877
896
  (part) => {
878
- var _a11, _b, _c;
897
+ var _a11, _b, _c, _d, _e;
879
898
  switch (part.type) {
880
899
  case "text": {
881
900
  return {
@@ -886,7 +905,7 @@ function convertToLanguageModelMessage(message, downloadedImages) {
886
905
  }
887
906
  case "image": {
888
907
  if (part.image instanceof URL) {
889
- if (downloadedImages == null) {
908
+ if (downloadedAssets == null) {
890
909
  return {
891
910
  type: "image",
892
911
  image: part.image,
@@ -894,7 +913,7 @@ function convertToLanguageModelMessage(message, downloadedImages) {
894
913
  providerMetadata: part.experimental_providerMetadata
895
914
  };
896
915
  } else {
897
- const downloadedImage = downloadedImages[part.image.toString()];
916
+ const downloadedImage = downloadedAssets[part.image.toString()];
898
917
  return {
899
918
  type: "image",
900
919
  image: downloadedImage.data,
@@ -909,7 +928,7 @@ function convertToLanguageModelMessage(message, downloadedImages) {
909
928
  switch (url.protocol) {
910
929
  case "http:":
911
930
  case "https:": {
912
- if (downloadedImages == null) {
931
+ if (downloadedAssets == null) {
913
932
  return {
914
933
  type: "image",
915
934
  image: url,
@@ -917,7 +936,7 @@ function convertToLanguageModelMessage(message, downloadedImages) {
917
936
  providerMetadata: part.experimental_providerMetadata
918
937
  };
919
938
  } else {
920
- const downloadedImage = downloadedImages[part.image];
939
+ const downloadedImage = downloadedAssets[url.toString()];
921
940
  return {
922
941
  type: "image",
923
942
  image: downloadedImage.data,
@@ -928,8 +947,9 @@ function convertToLanguageModelMessage(message, downloadedImages) {
928
947
  }
929
948
  case "data:": {
930
949
  try {
931
- const [header, base64Content] = part.image.split(",");
932
- const mimeType = header.split(";")[0].split(":")[1];
950
+ const { mimeType, base64Content } = splitDataUrl(
951
+ part.image
952
+ );
933
953
  if (mimeType == null || base64Content == null) {
934
954
  throw new Error("Invalid data URL format");
935
955
  }
@@ -947,11 +967,6 @@ function convertToLanguageModelMessage(message, downloadedImages) {
947
967
  );
948
968
  }
949
969
  }
950
- default: {
951
- throw new Error(
952
- `Unsupported URL protocol: ${url.protocol}`
953
- );
954
- }
955
970
  }
956
971
  } catch (_ignored) {
957
972
  }
@@ -966,12 +981,75 @@ function convertToLanguageModelMessage(message, downloadedImages) {
966
981
  }
967
982
  case "file": {
968
983
  if (part.data instanceof URL) {
969
- return {
970
- type: "file",
971
- data: part.data,
972
- mimeType: part.mimeType,
973
- providerMetadata: part.experimental_providerMetadata
974
- };
984
+ if (downloadedAssets == null) {
985
+ return {
986
+ type: "file",
987
+ data: part.data,
988
+ mimeType: part.mimeType,
989
+ providerMetadata: part.experimental_providerMetadata
990
+ };
991
+ } else {
992
+ const downloadedImage = downloadedAssets[part.data.toString()];
993
+ return {
994
+ type: "file",
995
+ data: convertUint8ArrayToBase642(downloadedImage.data),
996
+ mimeType: (_d = part.mimeType) != null ? _d : downloadedImage.mimeType,
997
+ providerMetadata: part.experimental_providerMetadata
998
+ };
999
+ }
1000
+ }
1001
+ if (typeof part.data === "string") {
1002
+ try {
1003
+ const url = new URL(part.data);
1004
+ switch (url.protocol) {
1005
+ case "http:":
1006
+ case "https:": {
1007
+ if (downloadedAssets == null) {
1008
+ return {
1009
+ type: "file",
1010
+ data: url,
1011
+ mimeType: part.mimeType,
1012
+ providerMetadata: part.experimental_providerMetadata
1013
+ };
1014
+ } else {
1015
+ const downloadedImage = downloadedAssets[url.toString()];
1016
+ return {
1017
+ type: "file",
1018
+ data: convertUint8ArrayToBase642(
1019
+ downloadedImage.data
1020
+ ),
1021
+ mimeType: (_e = part.mimeType) != null ? _e : downloadedImage.mimeType,
1022
+ providerMetadata: part.experimental_providerMetadata
1023
+ };
1024
+ }
1025
+ }
1026
+ case "data:": {
1027
+ try {
1028
+ const { mimeType, base64Content } = splitDataUrl(
1029
+ part.data
1030
+ );
1031
+ if (mimeType == null || base64Content == null) {
1032
+ throw new Error("Invalid data URL format");
1033
+ }
1034
+ return {
1035
+ type: "file",
1036
+ data: convertDataContentToBase64String(
1037
+ base64Content
1038
+ ),
1039
+ mimeType,
1040
+ providerMetadata: part.experimental_providerMetadata
1041
+ };
1042
+ } catch (error) {
1043
+ throw new Error(
1044
+ `Error processing data URL: ${getErrorMessage2(
1045
+ message
1046
+ )}`
1047
+ );
1048
+ }
1049
+ }
1050
+ }
1051
+ } catch (_ignored) {
1052
+ }
975
1053
  }
976
1054
  const imageBase64 = convertDataContentToBase64String(
977
1055
  part.data
@@ -1031,12 +1109,14 @@ function convertToLanguageModelMessage(message, downloadedImages) {
1031
1109
  }
1032
1110
  }
1033
1111
  }
1034
- async function downloadImages(messages, downloadImplementation) {
1112
+ async function downloadAssets(messages, downloadImplementation) {
1035
1113
  const urls = messages.filter((message) => message.role === "user").map((message) => message.content).filter(
1036
1114
  (content) => Array.isArray(content)
1037
- ).flat().filter((part) => part.type === "image").map((part) => part.image).map(
1115
+ ).flat().filter(
1116
+ (part) => part.type === "image" || part.type === "file"
1117
+ ).map((part) => part.type === "image" ? part.image : part.data).map(
1038
1118
  (part) => (
1039
- // support string urls in image parts:
1119
+ // support string urls:
1040
1120
  typeof part === "string" && (part.startsWith("http:") || part.startsWith("https:")) ? new URL(part) : part
1041
1121
  )
1042
1122
  ).filter((image) => image instanceof URL);
@@ -4625,6 +4705,17 @@ function attachmentsToParts(attachments) {
4625
4705
  case "https:": {
4626
4706
  if ((_a11 = attachment.contentType) == null ? void 0 : _a11.startsWith("image/")) {
4627
4707
  parts.push({ type: "image", image: url });
4708
+ } else {
4709
+ if (!attachment.contentType) {
4710
+ throw new Error(
4711
+ "If the attachment is not an image, it must specify a content type"
4712
+ );
4713
+ }
4714
+ parts.push({
4715
+ type: "file",
4716
+ data: url,
4717
+ mimeType: attachment.contentType
4718
+ });
4628
4719
  }
4629
4720
  break;
4630
4721
  }
@@ -4653,6 +4744,17 @@ function attachmentsToParts(attachments) {
4653
4744
  convertDataContentToUint8Array(base64Content)
4654
4745
  )
4655
4746
  });
4747
+ } else {
4748
+ if (!attachment.contentType) {
4749
+ throw new Error(
4750
+ "If the attachment is not an image or text, it must specify a content type"
4751
+ );
4752
+ }
4753
+ parts.push({
4754
+ type: "file",
4755
+ data: base64Content,
4756
+ mimeType: attachment.contentType
4757
+ });
4656
4758
  }
4657
4759
  break;
4658
4760
  }