@meetsmore-oss/use-ai-client 1.15.0 → 1.17.0
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/bundled.js +68 -41
- package/dist/bundled.js.map +1 -1
- package/dist/index.d.ts +63 -13
- package/dist/index.js +68 -41
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/bundled.js
CHANGED
|
@@ -1333,7 +1333,9 @@ var defaultStrings = {
|
|
|
1333
1333
|
/** File size error (use {filename} and {maxSize} placeholders) */
|
|
1334
1334
|
fileSizeError: 'File "{filename}" exceeds {maxSize}MB limit',
|
|
1335
1335
|
/** File type error (use {type} placeholder) */
|
|
1336
|
-
fileTypeError: 'File type "{type}" is not accepted'
|
|
1336
|
+
fileTypeError: 'File type "{type}" is not accepted',
|
|
1337
|
+
/** Error when too many files are attached (use {max} placeholder) */
|
|
1338
|
+
maxAttachmentsError: "You can attach at most {max} files per message"
|
|
1337
1339
|
},
|
|
1338
1340
|
// Floating button
|
|
1339
1341
|
floatingButton: {
|
|
@@ -18289,6 +18291,9 @@ async function getTransformedContent(files, transformer, context, onProgress) {
|
|
|
18289
18291
|
transformationCache.set(cacheKey, results);
|
|
18290
18292
|
return results;
|
|
18291
18293
|
}
|
|
18294
|
+
function normalizeUploadResult(result) {
|
|
18295
|
+
return typeof result === "string" ? { url: result } : result;
|
|
18296
|
+
}
|
|
18292
18297
|
async function toContentPart(attachment, backend) {
|
|
18293
18298
|
if (attachment.transformedContent !== void 0) {
|
|
18294
18299
|
return {
|
|
@@ -18301,16 +18306,12 @@ async function toContentPart(attachment, backend) {
|
|
|
18301
18306
|
}
|
|
18302
18307
|
};
|
|
18303
18308
|
}
|
|
18304
|
-
const
|
|
18305
|
-
|
|
18306
|
-
|
|
18309
|
+
const result = normalizeUploadResult(await backend.prepareForSend(attachment.file));
|
|
18310
|
+
const isImage = attachment.file.type.startsWith("image/");
|
|
18311
|
+
if ("ref" in result) {
|
|
18312
|
+
return isImage ? { type: "image_ref", ref: result.ref } : { type: "file_ref", ref: result.ref, mimeType: attachment.file.type, name: attachment.file.name };
|
|
18307
18313
|
}
|
|
18308
|
-
return {
|
|
18309
|
-
type: "file",
|
|
18310
|
-
url: url3,
|
|
18311
|
-
mimeType: attachment.file.type,
|
|
18312
|
-
name: attachment.file.name
|
|
18313
|
-
};
|
|
18314
|
+
return isImage ? { type: "image_url", url: result.url } : { type: "file_url", url: result.url, mimeType: attachment.file.type, name: attachment.file.name };
|
|
18314
18315
|
}
|
|
18315
18316
|
async function processAttachments(attachments, config2) {
|
|
18316
18317
|
const { getCurrentChat, backend = new EmbedFileUploadBackend(), transformers = {}, onFileProgress } = config2;
|
|
@@ -18464,7 +18465,12 @@ function useFileUpload({
|
|
|
18464
18465
|
const enabled = config2 !== void 0;
|
|
18465
18466
|
const maxFileSize = config2?.maxFileSize ?? DEFAULT_MAX_FILE_SIZE;
|
|
18466
18467
|
const acceptedTypes = config2?.acceptedTypes;
|
|
18468
|
+
const maxAttachments = config2?.maxAttachments;
|
|
18467
18469
|
const transformers = config2?.transformers;
|
|
18470
|
+
const attachmentsRef = useRef3(attachments);
|
|
18471
|
+
useEffect3(() => {
|
|
18472
|
+
attachmentsRef.current = attachments;
|
|
18473
|
+
}, [attachments]);
|
|
18468
18474
|
useEffect3(() => {
|
|
18469
18475
|
if (fileError) {
|
|
18470
18476
|
const timer = setTimeout(() => setFileError(null), 3e3);
|
|
@@ -18500,7 +18506,13 @@ function useFileUpload({
|
|
|
18500
18506
|
}, [getCurrentChat, transformers]);
|
|
18501
18507
|
const handleFiles = useCallback2(async (files) => {
|
|
18502
18508
|
const fileArray = Array.from(files);
|
|
18509
|
+
let currentCount = attachmentsRef.current.length;
|
|
18503
18510
|
for (const file2 of fileArray) {
|
|
18511
|
+
if (maxAttachments !== void 0 && currentCount >= maxAttachments) {
|
|
18512
|
+
const errorMsg = strings.fileUpload.maxAttachmentsError.replace("{max}", String(maxAttachments));
|
|
18513
|
+
setFileError(errorMsg);
|
|
18514
|
+
break;
|
|
18515
|
+
}
|
|
18504
18516
|
if (file2.size > maxFileSize) {
|
|
18505
18517
|
const errorMsg = strings.fileUpload.fileSizeError.replace("{filename}", file2.name).replace("{maxSize}", String(Math.round(maxFileSize / (1024 * 1024))));
|
|
18506
18518
|
setFileError(errorMsg);
|
|
@@ -18519,14 +18531,17 @@ function useFileUpload({
|
|
|
18519
18531
|
preview
|
|
18520
18532
|
};
|
|
18521
18533
|
setAttachments((prev) => [...prev, attachment]);
|
|
18534
|
+
attachmentsRef.current = [...attachmentsRef.current, attachment];
|
|
18535
|
+
currentCount++;
|
|
18522
18536
|
const transformerKey = findTransformerPattern(file2.type, transformers);
|
|
18523
18537
|
if (transformerKey) {
|
|
18524
18538
|
runTransformer(attachmentId, file2, transformerKey);
|
|
18525
18539
|
}
|
|
18526
18540
|
}
|
|
18527
|
-
}, [maxFileSize, acceptedTypes, strings, transformers, runTransformer]);
|
|
18541
|
+
}, [maxFileSize, acceptedTypes, maxAttachments, strings, transformers, runTransformer]);
|
|
18528
18542
|
const removeAttachment = useCallback2((id) => {
|
|
18529
18543
|
setAttachments((prev) => prev.filter((a) => a.id !== id));
|
|
18544
|
+
attachmentsRef.current = attachmentsRef.current.filter((a) => a.id !== id);
|
|
18530
18545
|
setProcessingState((prev) => {
|
|
18531
18546
|
const next = new Map(prev);
|
|
18532
18547
|
next.delete(id);
|
|
@@ -18535,6 +18550,7 @@ function useFileUpload({
|
|
|
18535
18550
|
}, []);
|
|
18536
18551
|
const clearAttachments = useCallback2(() => {
|
|
18537
18552
|
setAttachments([]);
|
|
18553
|
+
attachmentsRef.current = [];
|
|
18538
18554
|
setProcessingState(/* @__PURE__ */ new Map());
|
|
18539
18555
|
}, []);
|
|
18540
18556
|
const openFilePicker = useCallback2(() => {
|
|
@@ -19105,7 +19121,16 @@ function FeedbackButton({ type, isSelected, onClick, selectedColor, unselectedCo
|
|
|
19105
19121
|
);
|
|
19106
19122
|
}
|
|
19107
19123
|
function hasFileContent(content3) {
|
|
19108
|
-
return Array.isArray(content3) && content3.some((part) => part.type === "file");
|
|
19124
|
+
return Array.isArray(content3) && content3.some((part) => part.type === "file" || part.type === "attachment_ref");
|
|
19125
|
+
}
|
|
19126
|
+
function fileChipInfo(part) {
|
|
19127
|
+
if (part.type === "file") {
|
|
19128
|
+
return { name: part.file.name, size: part.file.size };
|
|
19129
|
+
}
|
|
19130
|
+
if (part.type === "attachment_ref") {
|
|
19131
|
+
return { name: part.name, size: part.size };
|
|
19132
|
+
}
|
|
19133
|
+
return null;
|
|
19109
19134
|
}
|
|
19110
19135
|
function UseAIChatPanel({
|
|
19111
19136
|
onSendMessage,
|
|
@@ -19778,14 +19803,10 @@ function UseAIChatPanel({
|
|
|
19778
19803
|
wordWrap: "break-word"
|
|
19779
19804
|
},
|
|
19780
19805
|
children: [
|
|
19781
|
-
message.role === "user" && hasFileContent(message.content) && /* @__PURE__ */ jsx12("div", { style: { display: "flex", flexWrap: "wrap", gap: "6px", marginBottom: "8px" }, children: message.content.
|
|
19782
|
-
|
|
19783
|
-
{
|
|
19784
|
-
|
|
19785
|
-
size: part.file.size
|
|
19786
|
-
},
|
|
19787
|
-
idx
|
|
19788
|
-
)) }),
|
|
19806
|
+
message.role === "user" && hasFileContent(message.content) && /* @__PURE__ */ jsx12("div", { style: { display: "flex", flexWrap: "wrap", gap: "6px", marginBottom: "8px" }, children: message.content.flatMap((part, idx) => {
|
|
19807
|
+
const info = fileChipInfo(part);
|
|
19808
|
+
return info ? [/* @__PURE__ */ jsx12(FilePlaceholder, { name: info.name, size: info.size }, idx)] : [];
|
|
19809
|
+
}) }),
|
|
19789
19810
|
message.role === "assistant" ? /* @__PURE__ */ jsxs9(Fragment, { children: [
|
|
19790
19811
|
message.reasoningParts && message.reasoningParts.length > 0 && /* @__PURE__ */ jsx12(
|
|
19791
19812
|
Reasoning,
|
|
@@ -23995,31 +24016,13 @@ var UseAIClient = class {
|
|
|
23995
24016
|
async sendPrompt(prompt, multimodalContent, forwardedProps) {
|
|
23996
24017
|
let messageContent = prompt;
|
|
23997
24018
|
if (multimodalContent && multimodalContent.length > 0) {
|
|
23998
|
-
messageContent = multimodalContent
|
|
23999
|
-
if (part.type === "text") {
|
|
24000
|
-
return { type: "text", text: part.text };
|
|
24001
|
-
} else if (part.type === "image") {
|
|
24002
|
-
return { type: "image", url: part.url };
|
|
24003
|
-
} else if (part.type === "file") {
|
|
24004
|
-
return {
|
|
24005
|
-
type: "file",
|
|
24006
|
-
url: part.url,
|
|
24007
|
-
mimeType: part.mimeType
|
|
24008
|
-
};
|
|
24009
|
-
} else {
|
|
24010
|
-
return {
|
|
24011
|
-
type: "transformed_file",
|
|
24012
|
-
text: part.text,
|
|
24013
|
-
originalFile: part.originalFile
|
|
24014
|
-
};
|
|
24015
|
-
}
|
|
24016
|
-
});
|
|
24019
|
+
messageContent = multimodalContent;
|
|
24017
24020
|
}
|
|
24018
24021
|
const userMessage = {
|
|
24019
24022
|
id: v4_default(),
|
|
24020
24023
|
role: "user",
|
|
24024
|
+
// @ag-ui/core declares Message.content as `string`; the wire also carries MultimodalContent[].
|
|
24021
24025
|
content: messageContent
|
|
24022
|
-
// Type cast needed for Message type compatibility
|
|
24023
24026
|
};
|
|
24024
24027
|
this._messages.push(userMessage);
|
|
24025
24028
|
const runId = v4_default();
|
|
@@ -38484,6 +38487,7 @@ function buildPersistedParts(message, attachments, fileContent) {
|
|
|
38484
38487
|
parts2.push({ type: "text", text: message });
|
|
38485
38488
|
}
|
|
38486
38489
|
const transformedByKey = /* @__PURE__ */ new Map();
|
|
38490
|
+
const nonTransformedParts = [];
|
|
38487
38491
|
for (const part of fileContent) {
|
|
38488
38492
|
if (part.type === "transformed_file") {
|
|
38489
38493
|
const key = `${part.originalFile.name}:${part.originalFile.size}:${part.originalFile.mimeType}`;
|
|
@@ -38493,6 +38497,8 @@ function buildPersistedParts(message, attachments, fileContent) {
|
|
|
38493
38497
|
} else {
|
|
38494
38498
|
transformedByKey.set(key, [part]);
|
|
38495
38499
|
}
|
|
38500
|
+
} else {
|
|
38501
|
+
nonTransformedParts.push(part);
|
|
38496
38502
|
}
|
|
38497
38503
|
}
|
|
38498
38504
|
for (const attachment of attachments) {
|
|
@@ -38504,6 +38510,18 @@ function buildPersistedParts(message, attachments, fileContent) {
|
|
|
38504
38510
|
text: transformed.text,
|
|
38505
38511
|
originalFile: transformed.originalFile
|
|
38506
38512
|
});
|
|
38513
|
+
continue;
|
|
38514
|
+
}
|
|
38515
|
+
const part = nonTransformedParts.shift();
|
|
38516
|
+
const ref = part && (part.type === "image_ref" || part.type === "file_ref") ? part.ref : void 0;
|
|
38517
|
+
if (ref) {
|
|
38518
|
+
parts2.push({
|
|
38519
|
+
type: "attachment_ref",
|
|
38520
|
+
ref,
|
|
38521
|
+
name: attachment.file.name,
|
|
38522
|
+
mimeType: attachment.file.type,
|
|
38523
|
+
size: attachment.file.size
|
|
38524
|
+
});
|
|
38507
38525
|
} else {
|
|
38508
38526
|
parts2.push({
|
|
38509
38527
|
type: "file",
|
|
@@ -38556,9 +38574,18 @@ function transformMessagesToClientFormat(persistedMessages) {
|
|
|
38556
38574
|
${p.text}`
|
|
38557
38575
|
}];
|
|
38558
38576
|
}
|
|
38577
|
+
if (p.type === "attachment_ref") {
|
|
38578
|
+
return [
|
|
38579
|
+
p.mimeType.startsWith("image/") ? { type: "image_ref", ref: p.ref } : { type: "file_ref", ref: p.ref, mimeType: p.mimeType, name: p.name }
|
|
38580
|
+
];
|
|
38581
|
+
}
|
|
38559
38582
|
return [];
|
|
38560
38583
|
});
|
|
38561
|
-
return {
|
|
38584
|
+
return {
|
|
38585
|
+
id: msg.id,
|
|
38586
|
+
role: "user",
|
|
38587
|
+
content: parts2
|
|
38588
|
+
};
|
|
38562
38589
|
}
|
|
38563
38590
|
}
|
|
38564
38591
|
});
|