ai 3.4.5 → 3.4.7

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";
@@ -743,6 +746,15 @@ var dataContentSchema = z.union([
743
746
  { message: "Must be a Buffer" }
744
747
  )
745
748
  ]);
749
+ function convertDataContentToBase64String(content) {
750
+ if (typeof content === "string") {
751
+ return content;
752
+ }
753
+ if (content instanceof ArrayBuffer) {
754
+ return convertUint8ArrayToBase64(new Uint8Array(content));
755
+ }
756
+ return convertUint8ArrayToBase64(content);
757
+ }
746
758
  function convertDataContentToUint8Array(content) {
747
759
  if (content instanceof Uint8Array) {
748
760
  return content;
@@ -809,6 +821,22 @@ var InvalidMessageRoleError = class extends AISDKError4 {
809
821
  };
810
822
  _a4 = symbol4;
811
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
+
812
840
  // core/prompt/convert-to-language-model-prompt.ts
813
841
  async function convertToLanguageModelPrompt({
814
842
  prompt,
@@ -819,7 +847,7 @@ async function convertToLanguageModelPrompt({
819
847
  if (prompt.system != null) {
820
848
  languageModelMessages.push({ role: "system", content: prompt.system });
821
849
  }
822
- 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);
823
851
  const promptType = prompt.type;
824
852
  switch (promptType) {
825
853
  case "prompt": {
@@ -832,7 +860,7 @@ async function convertToLanguageModelPrompt({
832
860
  case "messages": {
833
861
  languageModelMessages.push(
834
862
  ...prompt.messages.map(
835
- (message) => convertToLanguageModelMessage(message, downloadedImages)
863
+ (message) => convertToLanguageModelMessage(message, downloadedAssets)
836
864
  )
837
865
  );
838
866
  break;
@@ -844,7 +872,7 @@ async function convertToLanguageModelPrompt({
844
872
  }
845
873
  return languageModelMessages;
846
874
  }
847
- function convertToLanguageModelMessage(message, downloadedImages) {
875
+ function convertToLanguageModelMessage(message, downloadedAssets) {
848
876
  const role = message.role;
849
877
  switch (role) {
850
878
  case "system": {
@@ -864,98 +892,178 @@ function convertToLanguageModelMessage(message, downloadedImages) {
864
892
  }
865
893
  return {
866
894
  role: "user",
867
- content: message.content.map((part) => {
868
- var _a11, _b, _c;
869
- switch (part.type) {
870
- case "text": {
871
- return {
872
- type: "text",
873
- text: part.text,
874
- providerMetadata: part.experimental_providerMetadata
875
- };
876
- }
877
- case "image": {
878
- if (part.image instanceof URL) {
879
- if (downloadedImages == null) {
880
- return {
881
- type: "image",
882
- image: part.image,
883
- mimeType: part.mimeType,
884
- providerMetadata: part.experimental_providerMetadata
885
- };
886
- } else {
887
- const downloadedImage = downloadedImages[part.image.toString()];
888
- return {
889
- type: "image",
890
- image: downloadedImage.data,
891
- mimeType: (_a11 = part.mimeType) != null ? _a11 : downloadedImage.mimeType,
892
- providerMetadata: part.experimental_providerMetadata
893
- };
894
- }
895
+ content: message.content.map(
896
+ (part) => {
897
+ var _a11, _b, _c, _d, _e;
898
+ switch (part.type) {
899
+ case "text": {
900
+ return {
901
+ type: "text",
902
+ text: part.text,
903
+ providerMetadata: part.experimental_providerMetadata
904
+ };
895
905
  }
896
- if (typeof part.image === "string") {
897
- try {
898
- const url = new URL(part.image);
899
- switch (url.protocol) {
900
- case "http:":
901
- case "https:": {
902
- if (downloadedImages == null) {
903
- return {
904
- type: "image",
905
- image: url,
906
- mimeType: part.mimeType,
907
- providerMetadata: part.experimental_providerMetadata
908
- };
909
- } else {
910
- const downloadedImage = downloadedImages[part.image];
911
- return {
912
- type: "image",
913
- image: downloadedImage.data,
914
- mimeType: (_b = part.mimeType) != null ? _b : downloadedImage.mimeType,
915
- providerMetadata: part.experimental_providerMetadata
916
- };
906
+ case "image": {
907
+ if (part.image instanceof URL) {
908
+ if (downloadedAssets == null) {
909
+ return {
910
+ type: "image",
911
+ image: part.image,
912
+ mimeType: part.mimeType,
913
+ providerMetadata: part.experimental_providerMetadata
914
+ };
915
+ } else {
916
+ const downloadedImage = downloadedAssets[part.image.toString()];
917
+ return {
918
+ type: "image",
919
+ image: downloadedImage.data,
920
+ mimeType: (_a11 = part.mimeType) != null ? _a11 : downloadedImage.mimeType,
921
+ providerMetadata: part.experimental_providerMetadata
922
+ };
923
+ }
924
+ }
925
+ if (typeof part.image === "string") {
926
+ try {
927
+ const url = new URL(part.image);
928
+ switch (url.protocol) {
929
+ case "http:":
930
+ case "https:": {
931
+ if (downloadedAssets == null) {
932
+ return {
933
+ type: "image",
934
+ image: url,
935
+ mimeType: part.mimeType,
936
+ providerMetadata: part.experimental_providerMetadata
937
+ };
938
+ } else {
939
+ const downloadedImage = downloadedAssets[url.toString()];
940
+ return {
941
+ type: "image",
942
+ image: downloadedImage.data,
943
+ mimeType: (_b = part.mimeType) != null ? _b : downloadedImage.mimeType,
944
+ providerMetadata: part.experimental_providerMetadata
945
+ };
946
+ }
917
947
  }
918
- }
919
- case "data:": {
920
- try {
921
- const [header, base64Content] = part.image.split(",");
922
- const mimeType = header.split(";")[0].split(":")[1];
923
- if (mimeType == null || base64Content == null) {
924
- throw new Error("Invalid data URL format");
948
+ case "data:": {
949
+ try {
950
+ const { mimeType, base64Content } = splitDataUrl(
951
+ part.image
952
+ );
953
+ if (mimeType == null || base64Content == null) {
954
+ throw new Error("Invalid data URL format");
955
+ }
956
+ return {
957
+ type: "image",
958
+ image: convertDataContentToUint8Array(base64Content),
959
+ mimeType,
960
+ providerMetadata: part.experimental_providerMetadata
961
+ };
962
+ } catch (error) {
963
+ throw new Error(
964
+ `Error processing data URL: ${getErrorMessage2(
965
+ message
966
+ )}`
967
+ );
925
968
  }
926
- return {
927
- type: "image",
928
- image: convertDataContentToUint8Array(base64Content),
929
- mimeType,
930
- providerMetadata: part.experimental_providerMetadata
931
- };
932
- } catch (error) {
933
- throw new Error(
934
- `Error processing data URL: ${getErrorMessage2(
935
- message
936
- )}`
937
- );
938
969
  }
939
970
  }
940
- default: {
941
- throw new Error(
942
- `Unsupported URL protocol: ${url.protocol}`
943
- );
971
+ } catch (_ignored) {
972
+ }
973
+ }
974
+ const imageUint8 = convertDataContentToUint8Array(part.image);
975
+ return {
976
+ type: "image",
977
+ image: imageUint8,
978
+ mimeType: (_c = part.mimeType) != null ? _c : detectImageMimeType(imageUint8),
979
+ providerMetadata: part.experimental_providerMetadata
980
+ };
981
+ }
982
+ case "file": {
983
+ if (part.data instanceof URL) {
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
+ }
944
1050
  }
1051
+ } catch (_ignored) {
945
1052
  }
946
- } catch (_ignored) {
947
1053
  }
1054
+ const imageBase64 = convertDataContentToBase64String(
1055
+ part.data
1056
+ );
1057
+ return {
1058
+ type: "file",
1059
+ data: imageBase64,
1060
+ mimeType: part.mimeType,
1061
+ providerMetadata: part.experimental_providerMetadata
1062
+ };
948
1063
  }
949
- const imageUint8 = convertDataContentToUint8Array(part.image);
950
- return {
951
- type: "image",
952
- image: imageUint8,
953
- mimeType: (_c = part.mimeType) != null ? _c : detectImageMimeType(imageUint8),
954
- providerMetadata: part.experimental_providerMetadata
955
- };
956
1064
  }
957
1065
  }
958
- }).filter((part) => part.type !== "text" || part.text !== ""),
1066
+ ).filter((part) => part.type !== "text" || part.text !== ""),
959
1067
  providerMetadata: message.experimental_providerMetadata
960
1068
  };
961
1069
  }
@@ -1001,12 +1109,14 @@ function convertToLanguageModelMessage(message, downloadedImages) {
1001
1109
  }
1002
1110
  }
1003
1111
  }
1004
- async function downloadImages(messages, downloadImplementation) {
1112
+ async function downloadAssets(messages, downloadImplementation) {
1005
1113
  const urls = messages.filter((message) => message.role === "user").map((message) => message.content).filter(
1006
1114
  (content) => Array.isArray(content)
1007
- ).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(
1008
1118
  (part) => (
1009
- // support string urls in image parts:
1119
+ // support string urls:
1010
1120
  typeof part === "string" && (part.startsWith("http:") || part.startsWith("https:")) ? new URL(part) : part
1011
1121
  )
1012
1122
  ).filter((image) => image instanceof URL);
@@ -1216,6 +1326,12 @@ var imagePartSchema = z4.object({
1216
1326
  mimeType: z4.string().optional(),
1217
1327
  experimental_providerMetadata: providerMetadataSchema.optional()
1218
1328
  });
1329
+ var filePartSchema = z4.object({
1330
+ type: z4.literal("file"),
1331
+ data: z4.union([dataContentSchema, z4.instanceof(URL)]),
1332
+ mimeType: z4.string(),
1333
+ experimental_providerMetadata: providerMetadataSchema.optional()
1334
+ });
1219
1335
  var toolCallPartSchema = z4.object({
1220
1336
  type: z4.literal("tool-call"),
1221
1337
  toolCallId: z4.string(),
@@ -1241,7 +1357,7 @@ var coreUserMessageSchema = z5.object({
1241
1357
  role: z5.literal("user"),
1242
1358
  content: z5.union([
1243
1359
  z5.string(),
1244
- z5.array(z5.union([textPartSchema, imagePartSchema]))
1360
+ z5.array(z5.union([textPartSchema, imagePartSchema, filePartSchema]))
1245
1361
  ]),
1246
1362
  experimental_providerMetadata: providerMetadataSchema.optional()
1247
1363
  });
@@ -4589,6 +4705,17 @@ function attachmentsToParts(attachments) {
4589
4705
  case "https:": {
4590
4706
  if ((_a11 = attachment.contentType) == null ? void 0 : _a11.startsWith("image/")) {
4591
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
+ });
4592
4719
  }
4593
4720
  break;
4594
4721
  }
@@ -4617,6 +4744,17 @@ function attachmentsToParts(attachments) {
4617
4744
  convertDataContentToUint8Array(base64Content)
4618
4745
  )
4619
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
+ });
4620
4758
  }
4621
4759
  break;
4622
4760
  }