@memori.ai/memori-react 8.35.2 → 8.37.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/CHANGELOG.md +15 -0
- package/dist/components/ChatBubble/ChatBubble.js +1 -1
- package/dist/components/ChatBubble/ChatBubble.js.map +1 -1
- package/dist/components/ChatHistoryDrawer/ChatResumeDrawer.css +3 -3
- package/dist/components/ChatInputs/ChatInputs.js +1 -1
- package/dist/components/ChatInputs/ChatInputs.js.map +1 -1
- package/dist/components/FilePreview/FilePreview.d.ts +2 -1
- package/dist/components/FilePreview/FilePreview.js +27 -15
- package/dist/components/FilePreview/FilePreview.js.map +1 -1
- package/dist/components/MobileSessionPanel/MobileSessionPanel.css +19 -3
- package/dist/components/MobileSessionPanel/MobileSessionPanel.js +14 -3
- package/dist/components/MobileSessionPanel/MobileSessionPanel.js.map +1 -1
- package/dist/components/PositionPopover/PositionPopover.css +39 -10
- package/dist/components/PositionPopover/PositionPopover.d.ts +5 -0
- package/dist/components/PositionPopover/PositionPopover.js +19 -25
- package/dist/components/PositionPopover/PositionPopover.js.map +1 -1
- package/dist/components/UploadButton/UploadButton.js +10 -2
- package/dist/components/UploadButton/UploadButton.js.map +1 -1
- package/dist/components/UploadButton/UploadDocuments/UploadDocuments.d.ts +7 -0
- package/dist/components/UploadButton/UploadDocuments/UploadDocuments.js +61 -6
- package/dist/components/UploadButton/UploadDocuments/UploadDocuments.js.map +1 -1
- package/dist/components/layouts/WebsiteAssistant/website-assistant.css +16 -4
- package/dist/components/layouts/fullpage.css +97 -24
- package/dist/helpers/message.d.ts +1 -0
- package/dist/helpers/message.js +7 -2
- package/dist/helpers/message.js.map +1 -1
- package/dist/helpers/utils.js +4 -1
- package/dist/helpers/utils.js.map +1 -1
- package/dist/locales/de.json +3 -1
- package/dist/locales/en.json +3 -1
- package/dist/locales/es.json +3 -1
- package/dist/locales/fr.json +3 -1
- package/dist/locales/it.json +3 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/esm/components/ChatBubble/ChatBubble.js +2 -2
- package/esm/components/ChatBubble/ChatBubble.js.map +1 -1
- package/esm/components/ChatHistoryDrawer/ChatResumeDrawer.css +3 -3
- package/esm/components/ChatInputs/ChatInputs.js +1 -1
- package/esm/components/ChatInputs/ChatInputs.js.map +1 -1
- package/esm/components/FilePreview/FilePreview.d.ts +2 -1
- package/esm/components/FilePreview/FilePreview.js +27 -15
- package/esm/components/FilePreview/FilePreview.js.map +1 -1
- package/esm/components/MobileSessionPanel/MobileSessionPanel.css +19 -3
- package/esm/components/MobileSessionPanel/MobileSessionPanel.js +15 -4
- package/esm/components/MobileSessionPanel/MobileSessionPanel.js.map +1 -1
- package/esm/components/PositionPopover/PositionPopover.css +39 -10
- package/esm/components/PositionPopover/PositionPopover.d.ts +5 -0
- package/esm/components/PositionPopover/PositionPopover.js +17 -25
- package/esm/components/PositionPopover/PositionPopover.js.map +1 -1
- package/esm/components/UploadButton/UploadButton.js +10 -2
- package/esm/components/UploadButton/UploadButton.js.map +1 -1
- package/esm/components/UploadButton/UploadDocuments/UploadDocuments.d.ts +7 -0
- package/esm/components/UploadButton/UploadDocuments/UploadDocuments.js +61 -6
- package/esm/components/UploadButton/UploadDocuments/UploadDocuments.js.map +1 -1
- package/esm/components/layouts/WebsiteAssistant/website-assistant.css +16 -4
- package/esm/components/layouts/fullpage.css +97 -24
- package/esm/helpers/message.d.ts +1 -0
- package/esm/helpers/message.js +5 -1
- package/esm/helpers/message.js.map +1 -1
- package/esm/helpers/utils.js +4 -1
- package/esm/helpers/utils.js.map +1 -1
- package/esm/locales/de.json +3 -1
- package/esm/locales/en.json +3 -1
- package/esm/locales/es.json +3 -1
- package/esm/locales/fr.json +3 -1
- package/esm/locales/it.json +3 -1
- package/esm/version.d.ts +1 -1
- package/esm/version.js +1 -1
- package/package.json +1 -1
- package/src/components/ChatBubble/ChatBubble.tsx +8 -6
- package/src/components/ChatInputs/ChatInputs.tsx +1 -0
- package/src/components/FilePreview/FilePreview.tsx +40 -8
- package/src/components/UploadButton/UploadButton.tsx +21 -2
- package/src/components/UploadButton/UploadDocuments/UploadDocuments.tsx +105 -14
- package/src/helpers/message.ts +11 -5
- package/src/helpers/utils.ts +7 -4
- package/src/locales/de.json +3 -1
- package/src/locales/en.json +3 -1
- package/src/locales/es.json +3 -1
- package/src/locales/fr.json +3 -1
- package/src/locales/it.json +3 -1
- package/src/version.ts +1 -1
package/esm/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export const version = '8.
|
|
1
|
+
export const version = '8.37.0';
|
|
2
2
|
//# sourceMappingURL=version.js.map
|
package/package.json
CHANGED
|
@@ -23,7 +23,12 @@ import Code from '../icons/Code';
|
|
|
23
23
|
import Bug from '../icons/Bug';
|
|
24
24
|
import WhyThisAnswer from '../WhyThisAnswer/WhyThisAnswer';
|
|
25
25
|
import { stripHTML, stripOutputTags } from '../../helpers/utils';
|
|
26
|
-
import {
|
|
26
|
+
import {
|
|
27
|
+
renderMsg,
|
|
28
|
+
sanitizeMsg,
|
|
29
|
+
stripAttachmentTags,
|
|
30
|
+
truncateMessage,
|
|
31
|
+
} from '../../helpers/message';
|
|
27
32
|
import Expandable from '../ui/Expandable';
|
|
28
33
|
import Modal from '../ui/Modal';
|
|
29
34
|
import memoriApiClient from '@memori.ai/memori-api-client';
|
|
@@ -109,11 +114,8 @@ const ChatBubble: React.FC<Props> = ({
|
|
|
109
114
|
}
|
|
110
115
|
}, []);
|
|
111
116
|
|
|
112
|
-
// Clean text by removing
|
|
113
|
-
const cleanText = (message.translatedText || message.text)
|
|
114
|
-
/<document_attachment filename="([^"]+)" type="([^"]+)">([\s\S]*?)<\/document_attachment>/g,
|
|
115
|
-
''
|
|
116
|
-
);
|
|
117
|
+
// Clean text by removing attachment blocks before rendering
|
|
118
|
+
const cleanText = stripAttachmentTags(message.translatedText || message.text);
|
|
117
119
|
const { text: renderedText } = renderMsg(
|
|
118
120
|
message.fromUser ? truncateMessage(cleanText) : cleanText,
|
|
119
121
|
useMathFormatting,
|
|
@@ -6,11 +6,13 @@ import ContentPreviewModal from '../ContentPreviewModal';
|
|
|
6
6
|
import Snippet from '../Snippet/Snippet';
|
|
7
7
|
import { stripHTML, stripDocumentAttachmentTags } from '../../helpers/utils';
|
|
8
8
|
import { getFileExtensionFromMime } from '../MediaWidget/MediaItemWidget.utils';
|
|
9
|
+
import { useTranslation } from 'react-i18next';
|
|
9
10
|
|
|
10
11
|
type FilePreviewProps = {
|
|
11
12
|
previewFiles: any;
|
|
12
13
|
removeFile: (id: string, mediumID: string | undefined) => void;
|
|
13
14
|
allowRemove?: boolean;
|
|
15
|
+
showAnonymousRetentionNotice?: boolean;
|
|
14
16
|
// isMessagePreview?: boolean;
|
|
15
17
|
};
|
|
16
18
|
|
|
@@ -18,8 +20,10 @@ const FilePreview = ({
|
|
|
18
20
|
previewFiles,
|
|
19
21
|
removeFile,
|
|
20
22
|
allowRemove = true,
|
|
23
|
+
showAnonymousRetentionNotice = false,
|
|
21
24
|
}: // isMessagePreview = false,
|
|
22
25
|
FilePreviewProps) => {
|
|
26
|
+
const { t } = useTranslation();
|
|
23
27
|
const [selectedFile, setSelectedFile] = useState<{
|
|
24
28
|
name: string;
|
|
25
29
|
id: string;
|
|
@@ -81,16 +85,28 @@ FilePreviewProps) => {
|
|
|
81
85
|
}
|
|
82
86
|
}, [previewFiles]);
|
|
83
87
|
// Detect if the file is HTML (by type or filename)
|
|
84
|
-
const isHtmlFile = (
|
|
88
|
+
const isHtmlFile = (
|
|
89
|
+
file: { name?: string; type?: string; mimeType?: string } | null
|
|
90
|
+
): boolean => {
|
|
85
91
|
if (!file) return false;
|
|
86
92
|
const ext = file.name?.split('.').pop()?.toLowerCase();
|
|
87
93
|
return (
|
|
88
|
-
file.type === 'document' &&
|
|
89
|
-
|
|
94
|
+
(file.type === 'document' &&
|
|
95
|
+
(ext === 'html' || file.mimeType === 'text/html')) ||
|
|
96
|
+
ext === 'html' ||
|
|
97
|
+
file.mimeType === 'text/html'
|
|
98
|
+
);
|
|
90
99
|
};
|
|
91
100
|
|
|
92
101
|
// Get display content for non-image files (strip document_attachment for HTML, stripHTML for others)
|
|
93
|
-
const getDisplayContent = (
|
|
102
|
+
const getDisplayContent = (
|
|
103
|
+
file: {
|
|
104
|
+
content?: string;
|
|
105
|
+
name?: string;
|
|
106
|
+
type?: string;
|
|
107
|
+
mimeType?: string;
|
|
108
|
+
} | null
|
|
109
|
+
): string => {
|
|
94
110
|
if (!file?.content) return '';
|
|
95
111
|
const content = file.content;
|
|
96
112
|
if (isHtmlFile(file)) {
|
|
@@ -99,12 +115,11 @@ FilePreviewProps) => {
|
|
|
99
115
|
const div = document.createElement('div');
|
|
100
116
|
div.innerHTML = htmlContent;
|
|
101
117
|
htmlContent = div.textContent || div.innerText || htmlContent;
|
|
102
|
-
} else {
|
|
103
|
-
htmlContent = stripDocumentAttachmentTags(htmlContent);
|
|
104
118
|
}
|
|
119
|
+
htmlContent = stripDocumentAttachmentTags(htmlContent);
|
|
105
120
|
return htmlContent;
|
|
106
121
|
}
|
|
107
|
-
return stripHTML(content);
|
|
122
|
+
return stripHTML(stripDocumentAttachmentTags(content));
|
|
108
123
|
};
|
|
109
124
|
|
|
110
125
|
// Detect if the content is an image URL
|
|
@@ -126,6 +141,22 @@ FilePreviewProps) => {
|
|
|
126
141
|
<>
|
|
127
142
|
{previewFiles.length > 0 && (
|
|
128
143
|
<div className="memori--preview-container">
|
|
144
|
+
{showAnonymousRetentionNotice && (
|
|
145
|
+
<small
|
|
146
|
+
style={{
|
|
147
|
+
color: 'rgb(138, 138, 138)',
|
|
148
|
+
display: 'block',
|
|
149
|
+
marginTop: '6px',
|
|
150
|
+
marginBottom: '6px',
|
|
151
|
+
fontSize: '0.7rem',
|
|
152
|
+
}}
|
|
153
|
+
>
|
|
154
|
+
{t('upload.anonymousRetentionNotice', {
|
|
155
|
+
defaultValue:
|
|
156
|
+
'Note: uploaded files are retained for a maximum of 24 hours.',
|
|
157
|
+
})}
|
|
158
|
+
</small>
|
|
159
|
+
)}
|
|
129
160
|
<div className="memori--preview-list">
|
|
130
161
|
{previewFiles.map((file: any) => (
|
|
131
162
|
<div
|
|
@@ -181,7 +212,8 @@ FilePreviewProps) => {
|
|
|
181
212
|
isImageContent(selectedFile.content, selectedFile.type)
|
|
182
213
|
}
|
|
183
214
|
imageSrc={
|
|
184
|
-
selectedFile &&
|
|
215
|
+
selectedFile &&
|
|
216
|
+
isImageContent(selectedFile.content, selectedFile.type)
|
|
185
217
|
? selectedFile.content
|
|
186
218
|
: undefined
|
|
187
219
|
}
|
|
@@ -359,7 +359,14 @@ const UploadButton: React.FC<UploadManagerProps> = ({
|
|
|
359
359
|
|
|
360
360
|
// Handler for document files - now supports multiple documents
|
|
361
361
|
const handleDocumentFiles = (
|
|
362
|
-
files: {
|
|
362
|
+
files: {
|
|
363
|
+
name: string;
|
|
364
|
+
id: string;
|
|
365
|
+
content: string;
|
|
366
|
+
mimeType: string;
|
|
367
|
+
sourceUrl?: string;
|
|
368
|
+
textAssetUrl?: string;
|
|
369
|
+
}[]
|
|
363
370
|
) => {
|
|
364
371
|
if (files.length === 0) return;
|
|
365
372
|
|
|
@@ -380,7 +387,15 @@ const UploadButton: React.FC<UploadManagerProps> = ({
|
|
|
380
387
|
|
|
381
388
|
${file.content}
|
|
382
389
|
|
|
383
|
-
</document_attachment
|
|
390
|
+
</document_attachment>
|
|
391
|
+
|
|
392
|
+
<attachment_source>
|
|
393
|
+
${file.sourceUrl || ''}
|
|
394
|
+
</attachment_source>
|
|
395
|
+
|
|
396
|
+
<attachment_link>
|
|
397
|
+
${file.textAssetUrl || ''}
|
|
398
|
+
</attachment_link>`;
|
|
384
399
|
|
|
385
400
|
return {
|
|
386
401
|
name: file.name,
|
|
@@ -560,6 +575,10 @@ ${file.content}
|
|
|
560
575
|
<div className="memori--hidden-uploader" ref={documentRef}>
|
|
561
576
|
<UploadDocuments
|
|
562
577
|
setDocumentPreviewFiles={handleDocumentFiles}
|
|
578
|
+
authToken={authToken}
|
|
579
|
+
client={client}
|
|
580
|
+
sessionID={sessionID}
|
|
581
|
+
memoriID={memoriID}
|
|
563
582
|
maxDocuments={maxDocumentsPerMessage}
|
|
564
583
|
documentPreviewFiles={documentPreviewFiles}
|
|
565
584
|
onLoadingChange={handleLoadingChange}
|
|
@@ -4,6 +4,7 @@ import Spin from '../../ui/Spin';
|
|
|
4
4
|
import { DocumentIcon } from '../../icons/Document';
|
|
5
5
|
import Modal from '../../ui/Modal';
|
|
6
6
|
import { useTranslation } from 'react-i18next';
|
|
7
|
+
import memoriApiClient from '@memori.ai/memori-api-client';
|
|
7
8
|
// Types
|
|
8
9
|
type PreviewFile = {
|
|
9
10
|
name: string;
|
|
@@ -33,8 +34,19 @@ declare global {
|
|
|
33
34
|
// Props interface
|
|
34
35
|
interface UploadDocumentsProps {
|
|
35
36
|
setDocumentPreviewFiles: (
|
|
36
|
-
files: {
|
|
37
|
+
files: {
|
|
38
|
+
name: string;
|
|
39
|
+
id: string;
|
|
40
|
+
content: string;
|
|
41
|
+
mimeType: string;
|
|
42
|
+
sourceUrl?: string;
|
|
43
|
+
textAssetUrl?: string;
|
|
44
|
+
}[]
|
|
37
45
|
) => void;
|
|
46
|
+
authToken?: string;
|
|
47
|
+
client?: ReturnType<typeof memoriApiClient>;
|
|
48
|
+
sessionID?: string;
|
|
49
|
+
memoriID?: string;
|
|
38
50
|
maxDocuments?: number;
|
|
39
51
|
documentPreviewFiles: any;
|
|
40
52
|
onLoadingChange?: (loading: boolean) => void;
|
|
@@ -57,6 +69,10 @@ interface UploadDocumentsProps {
|
|
|
57
69
|
|
|
58
70
|
const UploadDocuments: React.FC<UploadDocumentsProps> = ({
|
|
59
71
|
setDocumentPreviewFiles,
|
|
72
|
+
authToken = '',
|
|
73
|
+
client,
|
|
74
|
+
sessionID = '',
|
|
75
|
+
memoriID = '',
|
|
60
76
|
maxDocuments,
|
|
61
77
|
documentPreviewFiles,
|
|
62
78
|
onLoadingChange,
|
|
@@ -66,6 +82,9 @@ const UploadDocuments: React.FC<UploadDocumentsProps> = ({
|
|
|
66
82
|
maxDocumentContentLength = 300000,
|
|
67
83
|
}) => {
|
|
68
84
|
const { t } = useTranslation();
|
|
85
|
+
const { backend } = client || {
|
|
86
|
+
backend: { uploadAsset: null, uploadAssetUnlogged: null },
|
|
87
|
+
};
|
|
69
88
|
|
|
70
89
|
// State
|
|
71
90
|
const [isLoading, setIsLoading] = useState(false);
|
|
@@ -261,6 +280,44 @@ const UploadDocuments: React.FC<UploadDocumentsProps> = ({
|
|
|
261
280
|
}
|
|
262
281
|
};
|
|
263
282
|
|
|
283
|
+
const fileToDataUrl = (file: File): Promise<string> =>
|
|
284
|
+
new Promise((resolve, reject) => {
|
|
285
|
+
const reader = new FileReader();
|
|
286
|
+
reader.onload = e => resolve((e.target?.result as string) || '');
|
|
287
|
+
reader.onerror = () => reject(new Error('File reading failed'));
|
|
288
|
+
reader.readAsDataURL(file);
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
const uploadAssetFile = async (file: File): Promise<string> => {
|
|
292
|
+
if (!client) {
|
|
293
|
+
throw new Error('API client not configured properly for media upload');
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
const fileDataUrl = await fileToDataUrl(file);
|
|
297
|
+
let response: any;
|
|
298
|
+
if (authToken && backend?.uploadAsset) {
|
|
299
|
+
response = await backend.uploadAsset(file.name, fileDataUrl, authToken);
|
|
300
|
+
} else if (memoriID && sessionID && backend?.uploadAssetUnlogged) {
|
|
301
|
+
response = await backend.uploadAssetUnlogged(
|
|
302
|
+
file.name,
|
|
303
|
+
fileDataUrl,
|
|
304
|
+
memoriID,
|
|
305
|
+
sessionID
|
|
306
|
+
);
|
|
307
|
+
} else {
|
|
308
|
+
throw new Error('Missing required parameters for upload');
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
if (!response) {
|
|
312
|
+
throw new Error('Upload failed');
|
|
313
|
+
}
|
|
314
|
+
if (response.resultCode !== 0) {
|
|
315
|
+
throw new Error(response.resultMessage || 'Upload failed');
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
return response.asset?.assetURL;
|
|
319
|
+
};
|
|
320
|
+
|
|
264
321
|
const handleDocumentUpload = async (
|
|
265
322
|
e: React.ChangeEvent<HTMLInputElement>
|
|
266
323
|
) => {
|
|
@@ -281,8 +338,13 @@ const UploadDocuments: React.FC<UploadDocumentsProps> = ({
|
|
|
281
338
|
t('upload.documentsNotAddedMaxAllowed', {
|
|
282
339
|
count: skipped,
|
|
283
340
|
max: maxDocuments ?? 10,
|
|
284
|
-
defaultValue: `${skipped} document(s) not added (maximum ${
|
|
285
|
-
|
|
341
|
+
defaultValue: `${skipped} document(s) not added (maximum ${
|
|
342
|
+
maxDocuments ?? 10
|
|
343
|
+
} files allowed).`,
|
|
344
|
+
}) ??
|
|
345
|
+
`${skipped} document(s) not added (maximum ${
|
|
346
|
+
maxDocuments ?? 10
|
|
347
|
+
} files allowed).`,
|
|
286
348
|
severity: 'warning',
|
|
287
349
|
});
|
|
288
350
|
}
|
|
@@ -302,6 +364,8 @@ const UploadDocuments: React.FC<UploadDocumentsProps> = ({
|
|
|
302
364
|
id: string;
|
|
303
365
|
content: string;
|
|
304
366
|
mimeType: string;
|
|
367
|
+
sourceUrl?: string;
|
|
368
|
+
textAssetUrl?: string;
|
|
305
369
|
}[] = [];
|
|
306
370
|
let hadTruncation = false;
|
|
307
371
|
|
|
@@ -317,11 +381,47 @@ const UploadDocuments: React.FC<UploadDocumentsProps> = ({
|
|
|
317
381
|
if (wasTruncated) hadTruncation = true;
|
|
318
382
|
|
|
319
383
|
if (text) {
|
|
384
|
+
const baseName = file.name.replace(/\.[^/.]+$/, '') || file.name;
|
|
385
|
+
const textFile = new File([text], `${baseName}.txt`, {
|
|
386
|
+
type: 'text/plain',
|
|
387
|
+
});
|
|
388
|
+
|
|
389
|
+
const uploadResults = await Promise.allSettled([
|
|
390
|
+
uploadAssetFile(file),
|
|
391
|
+
uploadAssetFile(textFile),
|
|
392
|
+
]);
|
|
393
|
+
|
|
394
|
+
const sourceUrl =
|
|
395
|
+
uploadResults[0].status === 'fulfilled'
|
|
396
|
+
? uploadResults[0].value
|
|
397
|
+
: undefined;
|
|
398
|
+
const textAssetUrl =
|
|
399
|
+
uploadResults[1].status === 'fulfilled'
|
|
400
|
+
? uploadResults[1].value
|
|
401
|
+
: undefined;
|
|
402
|
+
|
|
403
|
+
// Keep the document even when one of the optional links fails to upload.
|
|
404
|
+
if (
|
|
405
|
+
uploadResults[0].status === 'rejected' ||
|
|
406
|
+
uploadResults[1].status === 'rejected'
|
|
407
|
+
) {
|
|
408
|
+
onDocumentError?.({
|
|
409
|
+
message: t('upload.partialAssetUploadWarning', {
|
|
410
|
+
fileName: file.name,
|
|
411
|
+
defaultValue:
|
|
412
|
+
'Some file links could not be uploaded, but the document was added anyway.',
|
|
413
|
+
}),
|
|
414
|
+
severity: 'warning',
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
|
|
320
418
|
processedFiles.push({
|
|
321
419
|
name: file.name,
|
|
322
420
|
id: fileId,
|
|
323
421
|
content: text,
|
|
324
422
|
mimeType: file.type,
|
|
423
|
+
sourceUrl,
|
|
424
|
+
textAssetUrl,
|
|
325
425
|
});
|
|
326
426
|
}
|
|
327
427
|
} catch (error) {
|
|
@@ -337,15 +437,7 @@ const UploadDocuments: React.FC<UploadDocumentsProps> = ({
|
|
|
337
437
|
|
|
338
438
|
// Add new documents to existing ones (only those that fit within payload)
|
|
339
439
|
if (processedFiles.length > 0) {
|
|
340
|
-
const existingDocuments = documentPreviewFiles.filter(
|
|
341
|
-
(file: any) => file.type === 'document'
|
|
342
|
-
);
|
|
343
|
-
const existingImages = documentPreviewFiles.filter(
|
|
344
|
-
(file: any) => file.type === 'image'
|
|
345
|
-
);
|
|
346
|
-
|
|
347
440
|
setDocumentPreviewFiles([
|
|
348
|
-
...existingDocuments,
|
|
349
441
|
...processedFiles.map(file => ({
|
|
350
442
|
...file,
|
|
351
443
|
type: 'document',
|
|
@@ -384,8 +476,7 @@ const UploadDocuments: React.FC<UploadDocumentsProps> = ({
|
|
|
384
476
|
onClick={() => documentInputRef.current?.click()}
|
|
385
477
|
disabled={
|
|
386
478
|
isLoading ||
|
|
387
|
-
(maxDocuments &&
|
|
388
|
-
documentPreviewFiles.length >= maxDocuments) ||
|
|
479
|
+
(maxDocuments && documentPreviewFiles.length >= maxDocuments) ||
|
|
389
480
|
false
|
|
390
481
|
}
|
|
391
482
|
title="Upload documents"
|
|
@@ -425,4 +516,4 @@ const UploadDocuments: React.FC<UploadDocumentsProps> = ({
|
|
|
425
516
|
);
|
|
426
517
|
};
|
|
427
518
|
|
|
428
|
-
export default UploadDocuments;
|
|
519
|
+
export default UploadDocuments;
|
package/src/helpers/message.ts
CHANGED
|
@@ -40,6 +40,15 @@ marked.use({
|
|
|
40
40
|
marked.use(markedLinkifyIt());
|
|
41
41
|
marked.use(markedExtendedTables());
|
|
42
42
|
|
|
43
|
+
export const stripAttachmentTags = (value: string) =>
|
|
44
|
+
value
|
|
45
|
+
.replaceAll(
|
|
46
|
+
/<document_attachment filename="([^"]+)" type="([^"]+)">([\s\S]*?)<\/document_attachment>/g,
|
|
47
|
+
''
|
|
48
|
+
)
|
|
49
|
+
.replaceAll(/<attachment_source>\s*[\s\S]*?\s*<\/attachment_source>/g, '')
|
|
50
|
+
.replaceAll(/<attachment_link>\s*[\s\S]*?\s*<\/attachment_link>/g, '');
|
|
51
|
+
|
|
43
52
|
export const needsTruncation = (message: string) => {
|
|
44
53
|
return (
|
|
45
54
|
message.length > MAX_MSG_CHARS || message.split(' ').length > MAX_MSG_WORDS
|
|
@@ -82,11 +91,6 @@ export const renderMsg = (
|
|
|
82
91
|
? `<details class="memori-think"><summary>${reasoningText}</summary>$1</details>`
|
|
83
92
|
: ''
|
|
84
93
|
)
|
|
85
|
-
// Remove document_attachment tags from text - they will be handled as media
|
|
86
|
-
.replaceAll(
|
|
87
|
-
/<document_attachment filename="([^"]+)" type="([^"]+)">([\s\S]*?)<\/document_attachment>/g,
|
|
88
|
-
''
|
|
89
|
-
)
|
|
90
94
|
.replaceAll(
|
|
91
95
|
/<output\s+class\s*=\s*["\']memori-artifact["\'][^>]*data-mimetype\s*=\s*["\']([^"']+)["\'][^>]*>([\s\S]*?)(?:<\/output>|$)/gi,
|
|
92
96
|
''
|
|
@@ -98,6 +102,8 @@ export const renderMsg = (
|
|
|
98
102
|
.replaceAll('\beta', '\\beta')
|
|
99
103
|
.replaceAll('cdot', '\\cdot');
|
|
100
104
|
|
|
105
|
+
preprocessedText = stripAttachmentTags(preprocessedText);
|
|
106
|
+
|
|
101
107
|
// Correzione dei delimitatori LaTeX inconsistenti
|
|
102
108
|
if (useMathFormatting) {
|
|
103
109
|
// Abilita il supporto per KaTeX
|
package/src/helpers/utils.ts
CHANGED
|
@@ -98,17 +98,17 @@ export const isAndroid = (): boolean => {
|
|
|
98
98
|
|
|
99
99
|
export const isSafari = (): boolean => {
|
|
100
100
|
if (typeof navigator === 'undefined') return false;
|
|
101
|
-
|
|
101
|
+
|
|
102
102
|
const userAgent = navigator.userAgent;
|
|
103
103
|
const isSafariUA = userAgent.includes('Safari') && !userAgent.includes('Chrome');
|
|
104
104
|
const isWebKit = 'WebKit' in window && !('Chrome' in window);
|
|
105
|
-
|
|
105
|
+
|
|
106
106
|
return isSafariUA || isWebKit;
|
|
107
107
|
};
|
|
108
108
|
|
|
109
109
|
export const isSafariIOS = (): boolean => {
|
|
110
110
|
if (typeof navigator === 'undefined') return false;
|
|
111
|
-
|
|
111
|
+
|
|
112
112
|
const userAgent = navigator.userAgent;
|
|
113
113
|
return (
|
|
114
114
|
userAgent.includes('Safari') &&
|
|
@@ -239,7 +239,10 @@ export const stripMarkdown = (text: string) => {
|
|
|
239
239
|
|
|
240
240
|
export const stripDocumentAttachmentTags = (text: string): string => {
|
|
241
241
|
const documentAttachmentTagRegex = /<document_attachment filename="([^"]+)" type="([^"]+)">([\s\S]*?)<\/document_attachment>/g;
|
|
242
|
-
return text
|
|
242
|
+
return text
|
|
243
|
+
.replace(documentAttachmentTagRegex, '$3')
|
|
244
|
+
.replace(/<attachment_source>\s*[\s\S]*?\s*<\/attachment_source>/g, '')
|
|
245
|
+
.replace(/<attachment_link>\s*[\s\S]*?\s*<\/attachment_link>/g, '');
|
|
243
246
|
};
|
|
244
247
|
|
|
245
248
|
export const stripOutputTags = (text: string): string => {
|
package/src/locales/de.json
CHANGED
|
@@ -268,7 +268,9 @@
|
|
|
268
268
|
"filesNotAddedMaxAllowed": "{{count}} Datei(en) nicht hinzugefügt (maximal {{max}} Dateien erlaubt).",
|
|
269
269
|
"documentsNotAddedMaxAllowed": "{{count}} Dokument(e) nicht hinzugefügt (maximal {{max}} Dateien erlaubt).",
|
|
270
270
|
"imagesNotAddedMaxAllowed": "{{count}} Bild(er) nicht hinzugefügt (maximal {{max}} Dateien erlaubt).",
|
|
271
|
-
"documentsNotAddedContextSize": "{{count}} Dokument(e) nicht hinzugefügt (Kontextgrößen-Limit)."
|
|
271
|
+
"documentsNotAddedContextSize": "{{count}} Dokument(e) nicht hinzugefügt (Kontextgrößen-Limit).",
|
|
272
|
+
"partialAssetUploadWarning": "Einige Dateilinks konnten nicht hochgeladen werden, aber das Dokument wurde trotzdem hinzugefügt.",
|
|
273
|
+
"anonymousRetentionNotice": "Hinweis: Hochgeladene Dateien werden maximal 24 Stunden gespeichert."
|
|
272
274
|
},
|
|
273
275
|
"media": {
|
|
274
276
|
"title": "Titel",
|
package/src/locales/en.json
CHANGED
|
@@ -295,7 +295,9 @@
|
|
|
295
295
|
"filesNotAddedMaxAllowed": "{{count}} file(s) not added (maximum {{max}} files allowed).",
|
|
296
296
|
"documentsNotAddedMaxAllowed": "{{count}} document(s) not added (maximum {{max}} files allowed).",
|
|
297
297
|
"imagesNotAddedMaxAllowed": "{{count}} image(s) not added (maximum {{max}} files allowed).",
|
|
298
|
-
"documentsNotAddedContextSize": "{{count}} document(s) not added (context size limit)."
|
|
298
|
+
"documentsNotAddedContextSize": "{{count}} document(s) not added (context size limit).",
|
|
299
|
+
"partialAssetUploadWarning": "Some file links could not be uploaded, but the document was added anyway.",
|
|
300
|
+
"anonymousRetentionNotice": "Note: uploaded files are retained for a maximum of 24 hours."
|
|
299
301
|
},
|
|
300
302
|
"media": {
|
|
301
303
|
"title": "Title",
|
package/src/locales/es.json
CHANGED
|
@@ -268,7 +268,9 @@
|
|
|
268
268
|
"filesNotAddedMaxAllowed": "{{count}} archivo(s) no añadido(s) (máximo {{max}} archivos permitidos).",
|
|
269
269
|
"documentsNotAddedMaxAllowed": "{{count}} documento(s) no añadido(s) (máximo {{max}} archivos permitidos).",
|
|
270
270
|
"imagesNotAddedMaxAllowed": "{{count}} imagen(es) no añadida(s) (máximo {{max}} archivos permitidos).",
|
|
271
|
-
"documentsNotAddedContextSize": "{{count}} documento(s) no añadido(s) (límite de tamaño de contexto)."
|
|
271
|
+
"documentsNotAddedContextSize": "{{count}} documento(s) no añadido(s) (límite de tamaño de contexto).",
|
|
272
|
+
"partialAssetUploadWarning": "No se pudieron cargar algunos enlaces del archivo, pero el documento se agregó igualmente.",
|
|
273
|
+
"anonymousRetentionNotice": "Nota: los archivos cargados se conservan durante un máximo de 24 horas."
|
|
272
274
|
},
|
|
273
275
|
"media": {
|
|
274
276
|
"title": "Título",
|
package/src/locales/fr.json
CHANGED
|
@@ -276,7 +276,9 @@
|
|
|
276
276
|
"filesNotAddedMaxAllowed": "{{count}} fichier(s) non ajouté(s) (maximum {{max}} fichiers autorisés).",
|
|
277
277
|
"documentsNotAddedMaxAllowed": "{{count}} document(s) non ajouté(s) (maximum {{max}} fichiers autorisés).",
|
|
278
278
|
"imagesNotAddedMaxAllowed": "{{count}} image(s) non ajoutée(s) (maximum {{max}} fichiers autorisés).",
|
|
279
|
-
"documentsNotAddedContextSize": "{{count}} document(s) non ajouté(s) (limite de taille du contexte)."
|
|
279
|
+
"documentsNotAddedContextSize": "{{count}} document(s) non ajouté(s) (limite de taille du contexte).",
|
|
280
|
+
"partialAssetUploadWarning": "Certains liens de fichier n'ont pas pu etre televerses, mais le document a ete ajoute quand meme.",
|
|
281
|
+
"anonymousRetentionNotice": "Remarque : les fichiers téléversés sont conservés pendant un maximum de 24 heures."
|
|
280
282
|
},
|
|
281
283
|
"media": {
|
|
282
284
|
"title": "Titre",
|
package/src/locales/it.json
CHANGED
|
@@ -315,7 +315,9 @@
|
|
|
315
315
|
"filesNotAddedMaxAllowed": "{{count}} file non aggiunto/i (massimo {{max}} file consentiti).",
|
|
316
316
|
"documentsNotAddedMaxAllowed": "{{count}} documento/i non aggiunto/i (massimo {{max}} file consentiti).",
|
|
317
317
|
"imagesNotAddedMaxAllowed": "{{count}} immagine/i non aggiunta/e (massimo {{max}} file consentiti).",
|
|
318
|
-
"documentsNotAddedContextSize": "{{count}} documento/i non aggiunto/i (limite dimensione contesto)."
|
|
318
|
+
"documentsNotAddedContextSize": "{{count}} documento/i non aggiunto/i (limite dimensione contesto).",
|
|
319
|
+
"partialAssetUploadWarning": "Alcuni link del file non sono stati caricati, ma il documento e stato aggiunto comunque.",
|
|
320
|
+
"anonymousRetentionNotice": "Nota: i file caricati vengono conservati per massimo 24 ore."
|
|
319
321
|
},
|
|
320
322
|
"gamification": {
|
|
321
323
|
"level": "Livello",
|
package/src/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// This file is auto-generated. Do not edit manually.
|
|
2
|
-
export const version = '8.
|
|
2
|
+
export const version = '8.37.0';
|