@memori.ai/memori-react 8.35.2 → 8.36.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 +8 -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 +45 -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 +2 -1
- package/dist/locales/en.json +2 -1
- package/dist/locales/es.json +2 -1
- package/dist/locales/fr.json +2 -1
- package/dist/locales/it.json +2 -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 +45 -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 +2 -1
- package/esm/locales/en.json +2 -1
- package/esm/locales/es.json +2 -1
- package/esm/locales/fr.json +2 -1
- package/esm/locales/it.json +2 -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 +81 -14
- package/src/helpers/message.ts +11 -5
- package/src/helpers/utils.ts +7 -4
- package/src/locales/de.json +2 -1
- package/src/locales/en.json +2 -1
- package/src/locales/es.json +2 -1
- package/src/locales/fr.json +2 -1
- package/src/locales/it.json +2 -1
- package/src/version.ts +1 -1
|
@@ -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,23 @@ 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 [sourceUrl, textAssetUrl] = await Promise.all([
|
|
390
|
+
uploadAssetFile(file),
|
|
391
|
+
uploadAssetFile(textFile),
|
|
392
|
+
]);
|
|
393
|
+
|
|
320
394
|
processedFiles.push({
|
|
321
395
|
name: file.name,
|
|
322
396
|
id: fileId,
|
|
323
397
|
content: text,
|
|
324
398
|
mimeType: file.type,
|
|
399
|
+
sourceUrl,
|
|
400
|
+
textAssetUrl,
|
|
325
401
|
});
|
|
326
402
|
}
|
|
327
403
|
} catch (error) {
|
|
@@ -337,15 +413,7 @@ const UploadDocuments: React.FC<UploadDocumentsProps> = ({
|
|
|
337
413
|
|
|
338
414
|
// Add new documents to existing ones (only those that fit within payload)
|
|
339
415
|
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
416
|
setDocumentPreviewFiles([
|
|
348
|
-
...existingDocuments,
|
|
349
417
|
...processedFiles.map(file => ({
|
|
350
418
|
...file,
|
|
351
419
|
type: 'document',
|
|
@@ -384,8 +452,7 @@ const UploadDocuments: React.FC<UploadDocumentsProps> = ({
|
|
|
384
452
|
onClick={() => documentInputRef.current?.click()}
|
|
385
453
|
disabled={
|
|
386
454
|
isLoading ||
|
|
387
|
-
(maxDocuments &&
|
|
388
|
-
documentPreviewFiles.length >= maxDocuments) ||
|
|
455
|
+
(maxDocuments && documentPreviewFiles.length >= maxDocuments) ||
|
|
389
456
|
false
|
|
390
457
|
}
|
|
391
458
|
title="Upload documents"
|
|
@@ -425,4 +492,4 @@ const UploadDocuments: React.FC<UploadDocumentsProps> = ({
|
|
|
425
492
|
);
|
|
426
493
|
};
|
|
427
494
|
|
|
428
|
-
export default UploadDocuments;
|
|
495
|
+
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,8 @@
|
|
|
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
|
+
"anonymousRetentionNotice": "Hinweis: Hochgeladene Dateien werden maximal 24 Stunden gespeichert."
|
|
272
273
|
},
|
|
273
274
|
"media": {
|
|
274
275
|
"title": "Titel",
|
package/src/locales/en.json
CHANGED
|
@@ -295,7 +295,8 @@
|
|
|
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
|
+
"anonymousRetentionNotice": "Note: uploaded files are retained for a maximum of 24 hours."
|
|
299
300
|
},
|
|
300
301
|
"media": {
|
|
301
302
|
"title": "Title",
|
package/src/locales/es.json
CHANGED
|
@@ -268,7 +268,8 @@
|
|
|
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
|
+
"anonymousRetentionNotice": "Nota: los archivos cargados se conservan durante un máximo de 24 horas."
|
|
272
273
|
},
|
|
273
274
|
"media": {
|
|
274
275
|
"title": "Título",
|
package/src/locales/fr.json
CHANGED
|
@@ -276,7 +276,8 @@
|
|
|
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
|
+
"anonymousRetentionNotice": "Remarque : les fichiers téléversés sont conservés pendant un maximum de 24 heures."
|
|
280
281
|
},
|
|
281
282
|
"media": {
|
|
282
283
|
"title": "Titre",
|
package/src/locales/it.json
CHANGED
|
@@ -315,7 +315,8 @@
|
|
|
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
|
+
"anonymousRetentionNotice": "Nota: i file caricati vengono conservati per massimo 24 ore."
|
|
319
320
|
},
|
|
320
321
|
"gamification": {
|
|
321
322
|
"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.36.0';
|