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/CHANGELOG.md +21 -0
- package/dist/index.d.mts +24 -1
- package/dist/index.d.ts +24 -1
- package/dist/index.js +223 -88
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +227 -89
- package/dist/index.mjs.map +1 -1
- package/package.json +8 -8
- package/rsc/dist/index.d.ts +24 -1
- package/rsc/dist/rsc-server.d.mts +24 -1
- package/rsc/dist/rsc-server.mjs +205 -89
- package/rsc/dist/rsc-server.mjs.map +1 -1
package/CHANGELOG.md
CHANGED
@@ -1,5 +1,26 @@
|
|
1
1
|
# ai
|
2
2
|
|
3
|
+
## 3.4.7
|
4
|
+
|
5
|
+
### Patch Changes
|
6
|
+
|
7
|
+
- db04700: feat (core): support converting attachments to file parts
|
8
|
+
- 988707c: feat (ai/core): automatically download files from urls
|
9
|
+
|
10
|
+
## 3.4.6
|
11
|
+
|
12
|
+
### Patch Changes
|
13
|
+
|
14
|
+
- d595d0d: feat (ai/core): file content parts
|
15
|
+
- Updated dependencies [d595d0d]
|
16
|
+
- @ai-sdk/provider@0.0.24
|
17
|
+
- @ai-sdk/provider-utils@1.0.20
|
18
|
+
- @ai-sdk/ui-utils@0.0.46
|
19
|
+
- @ai-sdk/react@0.0.62
|
20
|
+
- @ai-sdk/solid@0.0.49
|
21
|
+
- @ai-sdk/svelte@0.0.51
|
22
|
+
- @ai-sdk/vue@0.0.53
|
23
|
+
|
3
24
|
## 3.4.5
|
4
25
|
|
5
26
|
### Patch Changes
|
package/dist/index.d.mts
CHANGED
@@ -438,6 +438,29 @@ interface ImagePart {
|
|
438
438
|
experimental_providerMetadata?: ProviderMetadata;
|
439
439
|
}
|
440
440
|
/**
|
441
|
+
File content part of a prompt. It contains a file.
|
442
|
+
*/
|
443
|
+
interface FilePart {
|
444
|
+
type: 'file';
|
445
|
+
/**
|
446
|
+
File data. Can either be:
|
447
|
+
|
448
|
+
- data: a base64-encoded string, a Uint8Array, an ArrayBuffer, or a Buffer
|
449
|
+
- URL: a URL that points to the image
|
450
|
+
*/
|
451
|
+
data: DataContent | URL;
|
452
|
+
/**
|
453
|
+
Mime type of the file.
|
454
|
+
*/
|
455
|
+
mimeType: string;
|
456
|
+
/**
|
457
|
+
Additional provider-specific metadata. They are passed through
|
458
|
+
to the provider from the AI SDK and enable provider-specific
|
459
|
+
functionality that can be fully encapsulated in the provider.
|
460
|
+
*/
|
461
|
+
experimental_providerMetadata?: ProviderMetadata;
|
462
|
+
}
|
463
|
+
/**
|
441
464
|
Tool call content part of a prompt. It contains a tool call (usually generated by the AI model).
|
442
465
|
*/
|
443
466
|
interface ToolCallPart {
|
@@ -531,7 +554,7 @@ type ExperimentalUserMessage = CoreUserMessage;
|
|
531
554
|
/**
|
532
555
|
Content of a user message. It can be a string or an array of text and image parts.
|
533
556
|
*/
|
534
|
-
type UserContent = string | Array<TextPart$1 | ImagePart>;
|
557
|
+
type UserContent = string | Array<TextPart$1 | ImagePart | FilePart>;
|
535
558
|
/**
|
536
559
|
An assistant message. It can contain text, tool calls, or a combination of text and tool calls.
|
537
560
|
*/
|
package/dist/index.d.ts
CHANGED
@@ -438,6 +438,29 @@ interface ImagePart {
|
|
438
438
|
experimental_providerMetadata?: ProviderMetadata;
|
439
439
|
}
|
440
440
|
/**
|
441
|
+
File content part of a prompt. It contains a file.
|
442
|
+
*/
|
443
|
+
interface FilePart {
|
444
|
+
type: 'file';
|
445
|
+
/**
|
446
|
+
File data. Can either be:
|
447
|
+
|
448
|
+
- data: a base64-encoded string, a Uint8Array, an ArrayBuffer, or a Buffer
|
449
|
+
- URL: a URL that points to the image
|
450
|
+
*/
|
451
|
+
data: DataContent | URL;
|
452
|
+
/**
|
453
|
+
Mime type of the file.
|
454
|
+
*/
|
455
|
+
mimeType: string;
|
456
|
+
/**
|
457
|
+
Additional provider-specific metadata. They are passed through
|
458
|
+
to the provider from the AI SDK and enable provider-specific
|
459
|
+
functionality that can be fully encapsulated in the provider.
|
460
|
+
*/
|
461
|
+
experimental_providerMetadata?: ProviderMetadata;
|
462
|
+
}
|
463
|
+
/**
|
441
464
|
Tool call content part of a prompt. It contains a tool call (usually generated by the AI model).
|
442
465
|
*/
|
443
466
|
interface ToolCallPart {
|
@@ -531,7 +554,7 @@ type ExperimentalUserMessage = CoreUserMessage;
|
|
531
554
|
/**
|
532
555
|
Content of a user message. It can be a string or an array of text and image parts.
|
533
556
|
*/
|
534
|
-
type UserContent = string | Array<TextPart$1 | ImagePart>;
|
557
|
+
type UserContent = string | Array<TextPart$1 | ImagePart | FilePart>;
|
535
558
|
/**
|
536
559
|
An assistant message. It can contain text, tool calls, or a combination of text and tool calls.
|
537
560
|
*/
|
package/dist/index.js
CHANGED
@@ -825,6 +825,15 @@ var dataContentSchema = import_zod.z.union([
|
|
825
825
|
{ message: "Must be a Buffer" }
|
826
826
|
)
|
827
827
|
]);
|
828
|
+
function convertDataContentToBase64String(content) {
|
829
|
+
if (typeof content === "string") {
|
830
|
+
return content;
|
831
|
+
}
|
832
|
+
if (content instanceof ArrayBuffer) {
|
833
|
+
return (0, import_provider_utils2.convertUint8ArrayToBase64)(new Uint8Array(content));
|
834
|
+
}
|
835
|
+
return (0, import_provider_utils2.convertUint8ArrayToBase64)(content);
|
836
|
+
}
|
828
837
|
function convertDataContentToUint8Array(content) {
|
829
838
|
if (content instanceof Uint8Array) {
|
830
839
|
return content;
|
@@ -891,6 +900,22 @@ var InvalidMessageRoleError = class extends import_provider5.AISDKError {
|
|
891
900
|
};
|
892
901
|
_a4 = symbol4;
|
893
902
|
|
903
|
+
// core/prompt/split-data-url.ts
|
904
|
+
function splitDataUrl(dataUrl) {
|
905
|
+
try {
|
906
|
+
const [header, base64Content] = dataUrl.split(",");
|
907
|
+
return {
|
908
|
+
mimeType: header.split(";")[0].split(":")[1],
|
909
|
+
base64Content
|
910
|
+
};
|
911
|
+
} catch (error) {
|
912
|
+
return {
|
913
|
+
mimeType: void 0,
|
914
|
+
base64Content: void 0
|
915
|
+
};
|
916
|
+
}
|
917
|
+
}
|
918
|
+
|
894
919
|
// core/prompt/convert-to-language-model-prompt.ts
|
895
920
|
async function convertToLanguageModelPrompt({
|
896
921
|
prompt,
|
@@ -901,7 +926,7 @@ async function convertToLanguageModelPrompt({
|
|
901
926
|
if (prompt.system != null) {
|
902
927
|
languageModelMessages.push({ role: "system", content: prompt.system });
|
903
928
|
}
|
904
|
-
const
|
929
|
+
const downloadedAssets = modelSupportsImageUrls || prompt.messages == null ? null : await downloadAssets(prompt.messages, downloadImplementation);
|
905
930
|
const promptType = prompt.type;
|
906
931
|
switch (promptType) {
|
907
932
|
case "prompt": {
|
@@ -914,7 +939,7 @@ async function convertToLanguageModelPrompt({
|
|
914
939
|
case "messages": {
|
915
940
|
languageModelMessages.push(
|
916
941
|
...prompt.messages.map(
|
917
|
-
(message) => convertToLanguageModelMessage(message,
|
942
|
+
(message) => convertToLanguageModelMessage(message, downloadedAssets)
|
918
943
|
)
|
919
944
|
);
|
920
945
|
break;
|
@@ -926,7 +951,7 @@ async function convertToLanguageModelPrompt({
|
|
926
951
|
}
|
927
952
|
return languageModelMessages;
|
928
953
|
}
|
929
|
-
function convertToLanguageModelMessage(message,
|
954
|
+
function convertToLanguageModelMessage(message, downloadedAssets) {
|
930
955
|
const role = message.role;
|
931
956
|
switch (role) {
|
932
957
|
case "system": {
|
@@ -946,98 +971,178 @@ function convertToLanguageModelMessage(message, downloadedImages) {
|
|
946
971
|
}
|
947
972
|
return {
|
948
973
|
role: "user",
|
949
|
-
content: message.content.map(
|
950
|
-
|
951
|
-
|
952
|
-
|
953
|
-
|
954
|
-
|
955
|
-
|
956
|
-
|
957
|
-
|
958
|
-
|
959
|
-
case "image": {
|
960
|
-
if (part.image instanceof URL) {
|
961
|
-
if (downloadedImages == null) {
|
962
|
-
return {
|
963
|
-
type: "image",
|
964
|
-
image: part.image,
|
965
|
-
mimeType: part.mimeType,
|
966
|
-
providerMetadata: part.experimental_providerMetadata
|
967
|
-
};
|
968
|
-
} else {
|
969
|
-
const downloadedImage = downloadedImages[part.image.toString()];
|
970
|
-
return {
|
971
|
-
type: "image",
|
972
|
-
image: downloadedImage.data,
|
973
|
-
mimeType: (_a11 = part.mimeType) != null ? _a11 : downloadedImage.mimeType,
|
974
|
-
providerMetadata: part.experimental_providerMetadata
|
975
|
-
};
|
976
|
-
}
|
974
|
+
content: message.content.map(
|
975
|
+
(part) => {
|
976
|
+
var _a11, _b, _c, _d, _e;
|
977
|
+
switch (part.type) {
|
978
|
+
case "text": {
|
979
|
+
return {
|
980
|
+
type: "text",
|
981
|
+
text: part.text,
|
982
|
+
providerMetadata: part.experimental_providerMetadata
|
983
|
+
};
|
977
984
|
}
|
978
|
-
|
979
|
-
|
980
|
-
|
981
|
-
|
982
|
-
|
983
|
-
|
984
|
-
|
985
|
-
|
986
|
-
|
987
|
-
|
988
|
-
|
989
|
-
|
990
|
-
|
991
|
-
|
992
|
-
|
993
|
-
|
994
|
-
|
995
|
-
|
996
|
-
|
997
|
-
|
998
|
-
|
985
|
+
case "image": {
|
986
|
+
if (part.image instanceof URL) {
|
987
|
+
if (downloadedAssets == null) {
|
988
|
+
return {
|
989
|
+
type: "image",
|
990
|
+
image: part.image,
|
991
|
+
mimeType: part.mimeType,
|
992
|
+
providerMetadata: part.experimental_providerMetadata
|
993
|
+
};
|
994
|
+
} else {
|
995
|
+
const downloadedImage = downloadedAssets[part.image.toString()];
|
996
|
+
return {
|
997
|
+
type: "image",
|
998
|
+
image: downloadedImage.data,
|
999
|
+
mimeType: (_a11 = part.mimeType) != null ? _a11 : downloadedImage.mimeType,
|
1000
|
+
providerMetadata: part.experimental_providerMetadata
|
1001
|
+
};
|
1002
|
+
}
|
1003
|
+
}
|
1004
|
+
if (typeof part.image === "string") {
|
1005
|
+
try {
|
1006
|
+
const url = new URL(part.image);
|
1007
|
+
switch (url.protocol) {
|
1008
|
+
case "http:":
|
1009
|
+
case "https:": {
|
1010
|
+
if (downloadedAssets == null) {
|
1011
|
+
return {
|
1012
|
+
type: "image",
|
1013
|
+
image: url,
|
1014
|
+
mimeType: part.mimeType,
|
1015
|
+
providerMetadata: part.experimental_providerMetadata
|
1016
|
+
};
|
1017
|
+
} else {
|
1018
|
+
const downloadedImage = downloadedAssets[url.toString()];
|
1019
|
+
return {
|
1020
|
+
type: "image",
|
1021
|
+
image: downloadedImage.data,
|
1022
|
+
mimeType: (_b = part.mimeType) != null ? _b : downloadedImage.mimeType,
|
1023
|
+
providerMetadata: part.experimental_providerMetadata
|
1024
|
+
};
|
1025
|
+
}
|
999
1026
|
}
|
1000
|
-
|
1001
|
-
|
1002
|
-
|
1003
|
-
|
1004
|
-
|
1005
|
-
|
1006
|
-
|
1027
|
+
case "data:": {
|
1028
|
+
try {
|
1029
|
+
const { mimeType, base64Content } = splitDataUrl(
|
1030
|
+
part.image
|
1031
|
+
);
|
1032
|
+
if (mimeType == null || base64Content == null) {
|
1033
|
+
throw new Error("Invalid data URL format");
|
1034
|
+
}
|
1035
|
+
return {
|
1036
|
+
type: "image",
|
1037
|
+
image: convertDataContentToUint8Array(base64Content),
|
1038
|
+
mimeType,
|
1039
|
+
providerMetadata: part.experimental_providerMetadata
|
1040
|
+
};
|
1041
|
+
} catch (error) {
|
1042
|
+
throw new Error(
|
1043
|
+
`Error processing data URL: ${(0, import_provider_utils3.getErrorMessage)(
|
1044
|
+
message
|
1045
|
+
)}`
|
1046
|
+
);
|
1007
1047
|
}
|
1008
|
-
return {
|
1009
|
-
type: "image",
|
1010
|
-
image: convertDataContentToUint8Array(base64Content),
|
1011
|
-
mimeType,
|
1012
|
-
providerMetadata: part.experimental_providerMetadata
|
1013
|
-
};
|
1014
|
-
} catch (error) {
|
1015
|
-
throw new Error(
|
1016
|
-
`Error processing data URL: ${(0, import_provider_utils3.getErrorMessage)(
|
1017
|
-
message
|
1018
|
-
)}`
|
1019
|
-
);
|
1020
1048
|
}
|
1021
1049
|
}
|
1022
|
-
|
1023
|
-
|
1024
|
-
|
1025
|
-
|
1050
|
+
} catch (_ignored) {
|
1051
|
+
}
|
1052
|
+
}
|
1053
|
+
const imageUint8 = convertDataContentToUint8Array(part.image);
|
1054
|
+
return {
|
1055
|
+
type: "image",
|
1056
|
+
image: imageUint8,
|
1057
|
+
mimeType: (_c = part.mimeType) != null ? _c : detectImageMimeType(imageUint8),
|
1058
|
+
providerMetadata: part.experimental_providerMetadata
|
1059
|
+
};
|
1060
|
+
}
|
1061
|
+
case "file": {
|
1062
|
+
if (part.data instanceof URL) {
|
1063
|
+
if (downloadedAssets == null) {
|
1064
|
+
return {
|
1065
|
+
type: "file",
|
1066
|
+
data: part.data,
|
1067
|
+
mimeType: part.mimeType,
|
1068
|
+
providerMetadata: part.experimental_providerMetadata
|
1069
|
+
};
|
1070
|
+
} else {
|
1071
|
+
const downloadedImage = downloadedAssets[part.data.toString()];
|
1072
|
+
return {
|
1073
|
+
type: "file",
|
1074
|
+
data: (0, import_provider_utils3.convertUint8ArrayToBase64)(downloadedImage.data),
|
1075
|
+
mimeType: (_d = part.mimeType) != null ? _d : downloadedImage.mimeType,
|
1076
|
+
providerMetadata: part.experimental_providerMetadata
|
1077
|
+
};
|
1078
|
+
}
|
1079
|
+
}
|
1080
|
+
if (typeof part.data === "string") {
|
1081
|
+
try {
|
1082
|
+
const url = new URL(part.data);
|
1083
|
+
switch (url.protocol) {
|
1084
|
+
case "http:":
|
1085
|
+
case "https:": {
|
1086
|
+
if (downloadedAssets == null) {
|
1087
|
+
return {
|
1088
|
+
type: "file",
|
1089
|
+
data: url,
|
1090
|
+
mimeType: part.mimeType,
|
1091
|
+
providerMetadata: part.experimental_providerMetadata
|
1092
|
+
};
|
1093
|
+
} else {
|
1094
|
+
const downloadedImage = downloadedAssets[url.toString()];
|
1095
|
+
return {
|
1096
|
+
type: "file",
|
1097
|
+
data: (0, import_provider_utils3.convertUint8ArrayToBase64)(
|
1098
|
+
downloadedImage.data
|
1099
|
+
),
|
1100
|
+
mimeType: (_e = part.mimeType) != null ? _e : downloadedImage.mimeType,
|
1101
|
+
providerMetadata: part.experimental_providerMetadata
|
1102
|
+
};
|
1103
|
+
}
|
1104
|
+
}
|
1105
|
+
case "data:": {
|
1106
|
+
try {
|
1107
|
+
const { mimeType, base64Content } = splitDataUrl(
|
1108
|
+
part.data
|
1109
|
+
);
|
1110
|
+
if (mimeType == null || base64Content == null) {
|
1111
|
+
throw new Error("Invalid data URL format");
|
1112
|
+
}
|
1113
|
+
return {
|
1114
|
+
type: "file",
|
1115
|
+
data: convertDataContentToBase64String(
|
1116
|
+
base64Content
|
1117
|
+
),
|
1118
|
+
mimeType,
|
1119
|
+
providerMetadata: part.experimental_providerMetadata
|
1120
|
+
};
|
1121
|
+
} catch (error) {
|
1122
|
+
throw new Error(
|
1123
|
+
`Error processing data URL: ${(0, import_provider_utils3.getErrorMessage)(
|
1124
|
+
message
|
1125
|
+
)}`
|
1126
|
+
);
|
1127
|
+
}
|
1128
|
+
}
|
1026
1129
|
}
|
1130
|
+
} catch (_ignored) {
|
1027
1131
|
}
|
1028
|
-
} catch (_ignored) {
|
1029
1132
|
}
|
1133
|
+
const imageBase64 = convertDataContentToBase64String(
|
1134
|
+
part.data
|
1135
|
+
);
|
1136
|
+
return {
|
1137
|
+
type: "file",
|
1138
|
+
data: imageBase64,
|
1139
|
+
mimeType: part.mimeType,
|
1140
|
+
providerMetadata: part.experimental_providerMetadata
|
1141
|
+
};
|
1030
1142
|
}
|
1031
|
-
const imageUint8 = convertDataContentToUint8Array(part.image);
|
1032
|
-
return {
|
1033
|
-
type: "image",
|
1034
|
-
image: imageUint8,
|
1035
|
-
mimeType: (_c = part.mimeType) != null ? _c : detectImageMimeType(imageUint8),
|
1036
|
-
providerMetadata: part.experimental_providerMetadata
|
1037
|
-
};
|
1038
1143
|
}
|
1039
1144
|
}
|
1040
|
-
|
1145
|
+
).filter((part) => part.type !== "text" || part.text !== ""),
|
1041
1146
|
providerMetadata: message.experimental_providerMetadata
|
1042
1147
|
};
|
1043
1148
|
}
|
@@ -1083,12 +1188,14 @@ function convertToLanguageModelMessage(message, downloadedImages) {
|
|
1083
1188
|
}
|
1084
1189
|
}
|
1085
1190
|
}
|
1086
|
-
async function
|
1191
|
+
async function downloadAssets(messages, downloadImplementation) {
|
1087
1192
|
const urls = messages.filter((message) => message.role === "user").map((message) => message.content).filter(
|
1088
1193
|
(content) => Array.isArray(content)
|
1089
|
-
).flat().filter(
|
1194
|
+
).flat().filter(
|
1195
|
+
(part) => part.type === "image" || part.type === "file"
|
1196
|
+
).map((part) => part.type === "image" ? part.image : part.data).map(
|
1090
1197
|
(part) => (
|
1091
|
-
// support string urls
|
1198
|
+
// support string urls:
|
1092
1199
|
typeof part === "string" && (part.startsWith("http:") || part.startsWith("https:")) ? new URL(part) : part
|
1093
1200
|
)
|
1094
1201
|
).filter((image) => image instanceof URL);
|
@@ -1298,6 +1405,12 @@ var imagePartSchema = import_zod4.z.object({
|
|
1298
1405
|
mimeType: import_zod4.z.string().optional(),
|
1299
1406
|
experimental_providerMetadata: providerMetadataSchema.optional()
|
1300
1407
|
});
|
1408
|
+
var filePartSchema = import_zod4.z.object({
|
1409
|
+
type: import_zod4.z.literal("file"),
|
1410
|
+
data: import_zod4.z.union([dataContentSchema, import_zod4.z.instanceof(URL)]),
|
1411
|
+
mimeType: import_zod4.z.string(),
|
1412
|
+
experimental_providerMetadata: providerMetadataSchema.optional()
|
1413
|
+
});
|
1301
1414
|
var toolCallPartSchema = import_zod4.z.object({
|
1302
1415
|
type: import_zod4.z.literal("tool-call"),
|
1303
1416
|
toolCallId: import_zod4.z.string(),
|
@@ -1323,7 +1436,7 @@ var coreUserMessageSchema = import_zod5.z.object({
|
|
1323
1436
|
role: import_zod5.z.literal("user"),
|
1324
1437
|
content: import_zod5.z.union([
|
1325
1438
|
import_zod5.z.string(),
|
1326
|
-
import_zod5.z.array(import_zod5.z.union([textPartSchema, imagePartSchema]))
|
1439
|
+
import_zod5.z.array(import_zod5.z.union([textPartSchema, imagePartSchema, filePartSchema]))
|
1327
1440
|
]),
|
1328
1441
|
experimental_providerMetadata: providerMetadataSchema.optional()
|
1329
1442
|
});
|
@@ -4651,6 +4764,17 @@ function attachmentsToParts(attachments) {
|
|
4651
4764
|
case "https:": {
|
4652
4765
|
if ((_a11 = attachment.contentType) == null ? void 0 : _a11.startsWith("image/")) {
|
4653
4766
|
parts.push({ type: "image", image: url });
|
4767
|
+
} else {
|
4768
|
+
if (!attachment.contentType) {
|
4769
|
+
throw new Error(
|
4770
|
+
"If the attachment is not an image, it must specify a content type"
|
4771
|
+
);
|
4772
|
+
}
|
4773
|
+
parts.push({
|
4774
|
+
type: "file",
|
4775
|
+
data: url,
|
4776
|
+
mimeType: attachment.contentType
|
4777
|
+
});
|
4654
4778
|
}
|
4655
4779
|
break;
|
4656
4780
|
}
|
@@ -4679,6 +4803,17 @@ function attachmentsToParts(attachments) {
|
|
4679
4803
|
convertDataContentToUint8Array(base64Content)
|
4680
4804
|
)
|
4681
4805
|
});
|
4806
|
+
} else {
|
4807
|
+
if (!attachment.contentType) {
|
4808
|
+
throw new Error(
|
4809
|
+
"If the attachment is not an image or text, it must specify a content type"
|
4810
|
+
);
|
4811
|
+
}
|
4812
|
+
parts.push({
|
4813
|
+
type: "file",
|
4814
|
+
data: base64Content,
|
4815
|
+
mimeType: attachment.contentType
|
4816
|
+
});
|
4682
4817
|
}
|
4683
4818
|
break;
|
4684
4819
|
}
|