@memori.ai/memori-react 7.10.0 → 7.11.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 +27 -0
- package/README.md +1 -0
- package/dist/components/AgeVerificationModal/AgeVerificationModal.css +1 -1
- package/dist/components/Chat/Chat.d.ts +1 -0
- package/dist/components/Chat/Chat.js +2 -2
- package/dist/components/Chat/Chat.js.map +1 -1
- package/dist/components/ChatBubble/ChatBubble.d.ts +1 -0
- package/dist/components/ChatBubble/ChatBubble.js +65 -57
- package/dist/components/ChatBubble/ChatBubble.js.map +1 -1
- package/dist/components/MemoriWidget/MemoriWidget.d.ts +2 -1
- package/dist/components/MemoriWidget/MemoriWidget.js +62 -12
- package/dist/components/MemoriWidget/MemoriWidget.js.map +1 -1
- package/dist/components/StartPanel/StartPanel.d.ts +1 -0
- package/dist/components/StartPanel/StartPanel.js +6 -2
- package/dist/components/StartPanel/StartPanel.js.map +1 -1
- package/dist/components/layouts/chat.css +0 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/locales/de.json +3 -0
- package/dist/locales/en.json +4 -0
- package/dist/locales/es.json +3 -0
- package/dist/locales/fr.json +3 -0
- package/dist/locales/it.json +4 -0
- package/esm/components/AgeVerificationModal/AgeVerificationModal.css +1 -1
- package/esm/components/Chat/Chat.d.ts +1 -0
- package/esm/components/Chat/Chat.js +2 -2
- package/esm/components/Chat/Chat.js.map +1 -1
- package/esm/components/ChatBubble/ChatBubble.d.ts +1 -0
- package/esm/components/ChatBubble/ChatBubble.js +65 -57
- package/esm/components/ChatBubble/ChatBubble.js.map +1 -1
- package/esm/components/MemoriWidget/MemoriWidget.d.ts +2 -1
- package/esm/components/MemoriWidget/MemoriWidget.js +63 -13
- package/esm/components/MemoriWidget/MemoriWidget.js.map +1 -1
- package/esm/components/StartPanel/StartPanel.d.ts +1 -0
- package/esm/components/StartPanel/StartPanel.js +6 -2
- package/esm/components/StartPanel/StartPanel.js.map +1 -1
- package/esm/components/layouts/chat.css +0 -1
- package/esm/index.d.ts +1 -0
- package/esm/index.js +3 -2
- package/esm/index.js.map +1 -1
- package/esm/locales/de.json +3 -0
- package/esm/locales/en.json +4 -0
- package/esm/locales/es.json +3 -0
- package/esm/locales/fr.json +3 -0
- package/esm/locales/it.json +4 -0
- package/package.json +1 -1
- package/src/components/AgeVerificationModal/AgeVerificationModal.css +1 -1
- package/src/components/Chat/Chat.tsx +4 -1
- package/src/components/ChatBubble/ChatBubble.stories.tsx +33 -0
- package/src/components/ChatBubble/ChatBubble.test.tsx +22 -0
- package/src/components/ChatBubble/ChatBubble.tsx +110 -94
- package/src/components/ChatBubble/__snapshots__/ChatBubble.test.tsx.snap +229 -0
- package/src/components/MemoriWidget/MemoriWidget.stories.tsx +4 -1
- package/src/components/MemoriWidget/MemoriWidget.tsx +138 -22
- package/src/components/StartPanel/StartPanel.stories.tsx +18 -0
- package/src/components/StartPanel/StartPanel.test.tsx +20 -0
- package/src/components/StartPanel/StartPanel.tsx +9 -1
- package/src/components/StartPanel/__snapshots__/StartPanel.test.tsx.snap +101 -0
- package/src/components/layouts/chat.css +0 -1
- package/src/index.stories.tsx +6 -0
- package/src/index.tsx +4 -0
- package/src/locales/de.json +3 -0
- package/src/locales/en.json +4 -0
- package/src/locales/es.json +3 -0
- package/src/locales/fr.json +3 -0
- package/src/locales/it.json +4 -0
package/esm/locales/fr.json
CHANGED
|
@@ -55,6 +55,9 @@
|
|
|
55
55
|
"birthDateHelper": "Nous demandons votre date de naissance uniquement pour activer ou désactiver les fonctionnalités qui ont des restrictions d'âge",
|
|
56
56
|
"underage": "Vous devez être au moins {{age}} ans pour s'inscrire.",
|
|
57
57
|
"underageTwinSession": "Vous devez être au moins {{age}} ans pour interagir avec ce Twin.",
|
|
58
|
+
"errorFetchingSession": "Erreur lors du chargement de la session",
|
|
59
|
+
"errorGettingReferralURL": "Erreur lors du chargement du référent",
|
|
60
|
+
"errorReopeningSession": "Erreur lors de la re-ouverture de la session",
|
|
58
61
|
"ageVerification": "Vérification de l'âge",
|
|
59
62
|
"ageVerificationText": "Pour interagir avec ce Twin, vous devez être au minimum {{minAge}} ans.",
|
|
60
63
|
"nsfw": "NSFW : Ce jumeau contient du contenu pour adultes",
|
package/esm/locales/it.json
CHANGED
|
@@ -55,6 +55,9 @@
|
|
|
55
55
|
"birthDateHelper": "Ti chiediamo la data di nascita esclusivamente per abilitare o disabilitare le funzionalità che hanno restrizioni in base all'età",
|
|
56
56
|
"underage": "Devi avere almeno {{age}} anni per registrarti.",
|
|
57
57
|
"underageTwinSession": "Devi avere almeno {{age}} anni per interagire con questo Twin.",
|
|
58
|
+
"errorFetchingSession": "Errore durante il caricamento della sessione",
|
|
59
|
+
"errorGettingReferralURL": "Errore durante il caricamento del riferimento",
|
|
60
|
+
"errorReopeningSession": "Errore durante il riapertura della sessione",
|
|
58
61
|
"ageVerification": "Verifica dell'età",
|
|
59
62
|
"ageVerificationText": "Per interagire con questo Twin, devi aver almeno {{minAge}} anni.",
|
|
60
63
|
"nsfw": "NSFW: Questo Twin contiene contenuti per adulti",
|
|
@@ -108,6 +111,7 @@
|
|
|
108
111
|
"pageTryMeExplanation": "Per parlare con me clicca sul pulsante INIZIAMO per cominciare",
|
|
109
112
|
"instructButton": "ISTRUISCIMI",
|
|
110
113
|
"tryMeButton": "INIZIAMO",
|
|
114
|
+
"resumeButton": "RIPRENDI",
|
|
111
115
|
"chatHistory": "Cronologia chat",
|
|
112
116
|
"exportChatHistory": "Esporta la cronologia chat",
|
|
113
117
|
"exportChatHistoryMessage": "Vuoi esportare la cronologia chat?",
|
package/package.json
CHANGED
|
@@ -69,6 +69,7 @@ export interface Props {
|
|
|
69
69
|
userAvatar?: MemoriProps['userAvatar'];
|
|
70
70
|
user?: User;
|
|
71
71
|
experts?: ExpertReference[];
|
|
72
|
+
useMathFormatting?: boolean;
|
|
72
73
|
}
|
|
73
74
|
|
|
74
75
|
const Chat: React.FC<Props> = ({
|
|
@@ -115,6 +116,7 @@ const Chat: React.FC<Props> = ({
|
|
|
115
116
|
user,
|
|
116
117
|
userAvatar,
|
|
117
118
|
experts,
|
|
119
|
+
useMathFormatting = false,
|
|
118
120
|
}) => {
|
|
119
121
|
const scrollToBottom = () => {
|
|
120
122
|
setTimeout(() => {
|
|
@@ -132,7 +134,7 @@ const Chat: React.FC<Props> = ({
|
|
|
132
134
|
|
|
133
135
|
const onTextareaFocus = () => {
|
|
134
136
|
stopListening();
|
|
135
|
-
const hasTouch = hasTouchscreen();
|
|
137
|
+
const hasTouch = hasTouchscreen();
|
|
136
138
|
|
|
137
139
|
if (hasTouch) setEnableFocusChatInput(true);
|
|
138
140
|
// if the user is on mobile and had not recorded audio, add the chat-focused class to the chat wrapper
|
|
@@ -229,6 +231,7 @@ const Chat: React.FC<Props> = ({
|
|
|
229
231
|
userAvatar={userAvatar}
|
|
230
232
|
experts={experts}
|
|
231
233
|
showCopyButton={showCopyButton}
|
|
234
|
+
useMathFormatting={useMathFormatting}
|
|
232
235
|
/>
|
|
233
236
|
{showDates && !!message.timestamp && (
|
|
234
237
|
<small
|
|
@@ -341,11 +341,38 @@ MarkdownWithSquareBrackets.args = {
|
|
|
341
341
|
},
|
|
342
342
|
};
|
|
343
343
|
|
|
344
|
+
export const MarkdownWithSquareBracketsAndTable = Template.bind({});
|
|
345
|
+
MarkdownWithSquareBracketsAndTable.args = {
|
|
346
|
+
memori,
|
|
347
|
+
apiUrl: 'https://backend.memori.ai',
|
|
348
|
+
tenant,
|
|
349
|
+
message: {
|
|
350
|
+
fromUser: false,
|
|
351
|
+
initial: false,
|
|
352
|
+
generatedByAI: true,
|
|
353
|
+
text: `<table border="1" style="border-collapse: collapse; width: 100%; table-layout: fixed; font-family: Arial, sans-serif;">
|
|
354
|
+
<tr style="background-color: #f0f0f0;">
|
|
355
|
+
<th style="text-align: left; padding: 8px; width: 200px;">Attività</th>
|
|
356
|
+
<th colspan="4" style="text-align: center; padding: 8px;">Dic 2024</th>
|
|
357
|
+
<th colspan="4" style="text-align: center; padding: 8px;">Gen 2025</th>
|
|
358
|
+
<th colspan="4" style="text-align: center; padding: 8px;">Feb 2025</th>
|
|
359
|
+
<th colspan="4" style="text-align: center; padding: 8px;">Mar 2025</th>
|
|
360
|
+
<th colspan="4" style="text-align: center; padding: 8px;">Apr 2025</th>
|
|
361
|
+
<th colspan="4" style="text-align: center; padding: 8px;">Mag 2025</th>
|
|
362
|
+
<th colspan="4" style="text-align: center; padding: 8px;">Giu 2025</th>
|
|
363
|
+
</tr>
|
|
364
|
+
</table>
|
|
365
|
+
|
|
366
|
+
[Vuoi che continui con l'intera tabella mantenendo lo stesso formato della precedente ma con table-layout: fixed per garantire celle di uguale dimensione?]`,
|
|
367
|
+
},
|
|
368
|
+
};
|
|
369
|
+
|
|
344
370
|
export const ComplexMarkdownMath1 = Template.bind({});
|
|
345
371
|
ComplexMarkdownMath1.args = {
|
|
346
372
|
memori,
|
|
347
373
|
apiUrl: 'https://backend.memori.ai',
|
|
348
374
|
tenant,
|
|
375
|
+
useMathFormatting: true,
|
|
349
376
|
message: {
|
|
350
377
|
fromUser: false,
|
|
351
378
|
initial: false,
|
|
@@ -359,6 +386,7 @@ ComplexMarkdownMath2.args = {
|
|
|
359
386
|
memori,
|
|
360
387
|
apiUrl: 'https://backend.memori.ai',
|
|
361
388
|
tenant,
|
|
389
|
+
useMathFormatting: true,
|
|
362
390
|
message: {
|
|
363
391
|
fromUser: false,
|
|
364
392
|
initial: false,
|
|
@@ -372,6 +400,7 @@ ComplexMarkdownMath3.args = {
|
|
|
372
400
|
memori,
|
|
373
401
|
apiUrl: 'https://backend.memori.ai',
|
|
374
402
|
tenant,
|
|
403
|
+
useMathFormatting: true,
|
|
375
404
|
message: {
|
|
376
405
|
fromUser: false,
|
|
377
406
|
initial: false,
|
|
@@ -385,6 +414,7 @@ ComplexMarkdownMath4.args = {
|
|
|
385
414
|
memori,
|
|
386
415
|
apiUrl: 'https://backend.memori.ai',
|
|
387
416
|
tenant,
|
|
417
|
+
useMathFormatting: true,
|
|
388
418
|
message: {
|
|
389
419
|
fromUser: false,
|
|
390
420
|
initial: false,
|
|
@@ -397,6 +427,7 @@ export const ComplexMarkdownMath5 = Template.bind({});
|
|
|
397
427
|
ComplexMarkdownMath5.args = {
|
|
398
428
|
memori,
|
|
399
429
|
tenant,
|
|
430
|
+
useMathFormatting: true,
|
|
400
431
|
apiUrl: 'https://backend.memori.ai',
|
|
401
432
|
message: {
|
|
402
433
|
fromUser: false,
|
|
@@ -410,6 +441,7 @@ export const ComplexMarkdownMath6 = Template.bind({});
|
|
|
410
441
|
ComplexMarkdownMath6.args = {
|
|
411
442
|
memori,
|
|
412
443
|
tenant,
|
|
444
|
+
useMathFormatting: true,
|
|
413
445
|
apiUrl: 'https://backend.memori.ai',
|
|
414
446
|
message: {
|
|
415
447
|
fromUser: false,
|
|
@@ -439,6 +471,7 @@ ComplexMarkdownMath7.args = {
|
|
|
439
471
|
memori,
|
|
440
472
|
tenant,
|
|
441
473
|
apiUrl: 'https://backend.memori.ai',
|
|
474
|
+
useMathFormatting: true,
|
|
442
475
|
message: {
|
|
443
476
|
fromUser: false,
|
|
444
477
|
initial: false,
|
|
@@ -266,12 +266,30 @@ it('renders ChatBubble with markdown table unchanged', () => {
|
|
|
266
266
|
expect(container).toMatchSnapshot();
|
|
267
267
|
});
|
|
268
268
|
|
|
269
|
+
it('renders ChatBubble with complex markdown and math but disabled unchanged', () => {
|
|
270
|
+
const { container } = render(
|
|
271
|
+
<ChatBubble
|
|
272
|
+
memori={memori}
|
|
273
|
+
tenant={tenant}
|
|
274
|
+
sessionID={sessionID}
|
|
275
|
+
useMathFormatting={false}
|
|
276
|
+
message={{
|
|
277
|
+
fromUser: false,
|
|
278
|
+
text: `Per calcolare l'ipotenusa di un triangolo rettangolo, puoi usare il Teorema di Pitagora. Il teorema afferma che in un triangolo rettangolo, il quadrato dell'ipotenusa (la lato opposto all'angolo retto) è uguale alla somma dei quadrati degli altri due lati.\n\nLa formula è:\n\n\\[ c = \\sqrt{a^2 + b^2} \\]\n\nDove:\n- $c$ è l'ipotenusa.\n- $a$ e $ b $ sono i due cateti del triangolo.\n\n### Passaggi per il Calcolo\n\n1. **Misura o identifica i cateti $ a $ e $ b $**:\n I cateti sono i due lati che formano l'angolo retto.\n\n2. **Calcola i quadrati dei cateti**:\n Eleva al quadrato entrambe le misure dei cateti: $ a^2 $ e $ b^2 $.\n\n3. **Somma i quadrati dei cateti**:\n Somma i risultati ottenuti: $ a^2 + b^2 $.\n\n4. **Calcola la radice quadrata della somma**:\n Prendi la radice quadrata della somma per trovare l'ipotenusa: $ c = \\sqrt{a^2 + b^2} $.\n\n### Esempio di Calcolo\n\nSupponiamo di avere un triangolo rettangolo con i cateti di lunghezza 3 cm e 4 cm.\n\n1. **Cateto $ a $**: 3 cm\n2. **Cateto $ b $**: 4 cm\n\nUsiamo la formula:\n\n\\[ c = \\sqrt{a^2 + b^2} \\]\n\n\\[ c = \\sqrt{(3 \\, \\text{cm})^2 + (4 \\, \\text{cm})^2} \\]\n\n\\[ c = \\sqrt{9 \\, \\text{cm}^2 + 16 \\, \\text{cm}^2} \\]\n\n\\[ c = \\sqrt{25 \\, \\text{cm}^2} \\]\n\n\\[ c = 5 \\, \\text{cm} \\]\n\nQuindi, l'ipotenusa del triangolo è di 5 cm.`,
|
|
279
|
+
initial: false,
|
|
280
|
+
}}
|
|
281
|
+
/>
|
|
282
|
+
);
|
|
283
|
+
expect(container).toMatchSnapshot();
|
|
284
|
+
});
|
|
285
|
+
|
|
269
286
|
it('renders ChatBubble with complex markdown and math 1 unchanged', () => {
|
|
270
287
|
const { container } = render(
|
|
271
288
|
<ChatBubble
|
|
272
289
|
memori={memori}
|
|
273
290
|
tenant={tenant}
|
|
274
291
|
sessionID={sessionID}
|
|
292
|
+
useMathFormatting
|
|
275
293
|
message={{
|
|
276
294
|
fromUser: false,
|
|
277
295
|
text: `Per calcolare l'ipotenusa di un triangolo rettangolo, puoi usare il Teorema di Pitagora. Il teorema afferma che in un triangolo rettangolo, il quadrato dell'ipotenusa (la lato opposto all'angolo retto) è uguale alla somma dei quadrati degli altri due lati.\n\nLa formula è:\n\n\\[ c = \\sqrt{a^2 + b^2} \\]\n\nDove:\n- $c$ è l'ipotenusa.\n- $a$ e $ b $ sono i due cateti del triangolo.\n\n### Passaggi per il Calcolo\n\n1. **Misura o identifica i cateti $ a $ e $ b $**:\n I cateti sono i due lati che formano l'angolo retto.\n\n2. **Calcola i quadrati dei cateti**:\n Eleva al quadrato entrambe le misure dei cateti: $ a^2 $ e $ b^2 $.\n\n3. **Somma i quadrati dei cateti**:\n Somma i risultati ottenuti: $ a^2 + b^2 $.\n\n4. **Calcola la radice quadrata della somma**:\n Prendi la radice quadrata della somma per trovare l'ipotenusa: $ c = \\sqrt{a^2 + b^2} $.\n\n### Esempio di Calcolo\n\nSupponiamo di avere un triangolo rettangolo con i cateti di lunghezza 3 cm e 4 cm.\n\n1. **Cateto $ a $**: 3 cm\n2. **Cateto $ b $**: 4 cm\n\nUsiamo la formula:\n\n\\[ c = \\sqrt{a^2 + b^2} \\]\n\n\\[ c = \\sqrt{(3 \\, \\text{cm})^2 + (4 \\, \\text{cm})^2} \\]\n\n\\[ c = \\sqrt{9 \\, \\text{cm}^2 + 16 \\, \\text{cm}^2} \\]\n\n\\[ c = \\sqrt{25 \\, \\text{cm}^2} \\]\n\n\\[ c = 5 \\, \\text{cm} \\]\n\nQuindi, l'ipotenusa del triangolo è di 5 cm.`,
|
|
@@ -288,6 +306,7 @@ it('renders ChatBubble with complex markdown and math 2 unchanged', () => {
|
|
|
288
306
|
memori={memori}
|
|
289
307
|
tenant={tenant}
|
|
290
308
|
sessionID={sessionID}
|
|
309
|
+
useMathFormatting
|
|
291
310
|
message={{
|
|
292
311
|
fromUser: false,
|
|
293
312
|
text: "Per calcolare le resistenze dei materiali per le verifiche rispetto ad azioni antropiche e ambientali secondo la Specifica Tecnica ST-VAL4, si procede in questo modo:\n\n1. **Determinazione della resistenza dei materiali:**\n La resistenza dei materiali da utilizzare nelle verifiche accurate si determina a partire dalle indagini sull’opera. La caratterizzazione deve essere distinta per tutti i materiali presenti nell'opera, in accordo con la ST-PI. Le resistenze per verifiche rispetto ad azioni antropiche come i carichi da traffico e le azioni ambientali sono definite dalle LG20. Questo include la distinzione rispetto a quelle utilizzate per le azioni sismiche, come dettagliato dalle NTC18 e CIR19 .\n\n2. **Calcolo della resistenza:**\n Il valore della resistenza dei materiali $ f_d $ da utilizzare nelle verifiche per carichi gravitazionali si ottiene mediante la seguente espressione:\n\n \\[\n f_d = \\min \\left( \\frac{f_m}{FC \\cdot \\gamma_M}, \\frac{f_k}{FC} \\right)\n \\]\n\n Dove:\n - $ f_m $ è il valor medio della resistenza valutato dai risultati delle prove effettuate sui campioni prelevati in situ;\n - $ f_k $ è la resistenza caratteristica calcolata sulla base dei risultati delle prove sui campioni prelevati in situ;\n - $ FC $ è il Fattore di Confidenza associato al Livello di Conoscenza raggiunto;\n - $ \\gamma_M $ è il fattore parziale di sicurezza del materiale .\n\n3. **Caratterizzazione dei materiali:**\n I valori medi, caratteristici e di progetto delle resistenze a compressione e trazione per il calcestruzzo, e delle resistenze a snervamento per l’acciaio ordinario sono determinati a partire dai risultati delle prove. Specifiche espressioni e metodi sono forniti per diversi materiali nell'Appendice 13 della ST-VAL4 .\n\n4. **Stima della resistenza da prove non distruttive:**\n Per valutare le resistenze dei materiali, si possono anche utilizzare prove non distruttive come le prove SonReb per il calcestruzzo e le prove di durezza per l'acciaio ordinario e armonico. Formulazioni specifiche per queste prove si trovano in Appendice al §13.1 della ST-VAL4 .\n\n5. **Analisi dei risultati delle indagini:**\n Gli esiti delle prove devono essere attentamente analizzati per confermare le caratteristiche originarie o rilevare eventuali decadimenti del materiale. Questo processo include anche l'identificazione delle cause di dispersione significative nei risultati delle prove .\n\nSeguendo questi passaggi, si ottiene una stima accurata delle resistenze dei materiali che possono essere utilizzate per le verifiche di sicurezza rispetto ad azioni antropiche e ambientali.",
|
|
@@ -304,6 +323,7 @@ it('renders ChatBubble with complex markdown and math 3 unchanged', () => {
|
|
|
304
323
|
memori={memori}
|
|
305
324
|
tenant={tenant}
|
|
306
325
|
sessionID={sessionID}
|
|
326
|
+
useMathFormatting
|
|
307
327
|
message={{
|
|
308
328
|
fromUser: false,
|
|
309
329
|
initial: false,
|
|
@@ -320,6 +340,7 @@ it('renders ChatBubble with complex markdown and math 4 unchanged', () => {
|
|
|
320
340
|
memori={memori}
|
|
321
341
|
tenant={tenant}
|
|
322
342
|
sessionID={sessionID}
|
|
343
|
+
useMathFormatting
|
|
323
344
|
message={{
|
|
324
345
|
fromUser: false,
|
|
325
346
|
initial: false,
|
|
@@ -336,6 +357,7 @@ it('renders ChatBubble with complex markdown and math 5 unchanged', () => {
|
|
|
336
357
|
memori={memori}
|
|
337
358
|
tenant={tenant}
|
|
338
359
|
sessionID={sessionID}
|
|
360
|
+
useMathFormatting
|
|
339
361
|
message={{
|
|
340
362
|
fromUser: false,
|
|
341
363
|
initial: false,
|
|
@@ -29,24 +29,6 @@ import markedLinkifyIt from 'marked-linkify-it';
|
|
|
29
29
|
import markedKatex from 'marked-katex-extension';
|
|
30
30
|
import markedExtendedTables from '../../helpers/markedExtendedTables';
|
|
31
31
|
|
|
32
|
-
export interface Props {
|
|
33
|
-
message: Message;
|
|
34
|
-
memori: Memori;
|
|
35
|
-
sessionID: string;
|
|
36
|
-
tenant?: Tenant;
|
|
37
|
-
baseUrl?: string;
|
|
38
|
-
apiUrl?: string;
|
|
39
|
-
showFeedback?: boolean;
|
|
40
|
-
showWhyThisAnswer?: boolean;
|
|
41
|
-
showCopyButton?: boolean;
|
|
42
|
-
showTranslationOriginal?: boolean;
|
|
43
|
-
simulateUserPrompt?: (msg: string) => void;
|
|
44
|
-
showAIicon?: boolean;
|
|
45
|
-
isFirst?: boolean;
|
|
46
|
-
userAvatar?: MemoriProps['userAvatar'];
|
|
47
|
-
user?: User;
|
|
48
|
-
experts?: ExpertReference[];
|
|
49
|
-
}
|
|
50
32
|
|
|
51
33
|
marked.use({
|
|
52
34
|
async: false,
|
|
@@ -55,6 +37,7 @@ marked.use({
|
|
|
55
37
|
renderer: {
|
|
56
38
|
link: ({ href, title, text }) => {
|
|
57
39
|
const cleanHref = cleanUrl(href);
|
|
40
|
+
|
|
58
41
|
if (cleanHref === null) {
|
|
59
42
|
return text;
|
|
60
43
|
}
|
|
@@ -69,14 +52,100 @@ marked.use({
|
|
|
69
52
|
},
|
|
70
53
|
});
|
|
71
54
|
marked.use(markedLinkifyIt());
|
|
72
|
-
marked.use(
|
|
73
|
-
markedKatex({
|
|
74
|
-
throwOnError: false,
|
|
75
|
-
output: 'htmlAndMathml',
|
|
76
|
-
})
|
|
77
|
-
);
|
|
78
55
|
marked.use(markedExtendedTables());
|
|
79
56
|
|
|
57
|
+
const parseSquaredBrackets = (text: string) => {
|
|
58
|
+
const rows = text.split('\n');
|
|
59
|
+
|
|
60
|
+
return rows.reduce((acc, row) => {
|
|
61
|
+
if (row.includes('=')) {
|
|
62
|
+
let result = '';
|
|
63
|
+
let isEscaped = false;
|
|
64
|
+
for (let i = 0; i < row.length; i++) {
|
|
65
|
+
if (row[i] === '[' && !isEscaped) {
|
|
66
|
+
result += '\\[';
|
|
67
|
+
} else if (row[i] === ']' && !isEscaped) {
|
|
68
|
+
result += '\\]';
|
|
69
|
+
} else {
|
|
70
|
+
result += row[i];
|
|
71
|
+
}
|
|
72
|
+
isEscaped = row[i] === '\\' && !isEscaped;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return acc?.length ? `${acc}\n${result}` : result;
|
|
76
|
+
} else {
|
|
77
|
+
return acc?.length ? `${acc}\n${row}` : row;
|
|
78
|
+
}
|
|
79
|
+
}, '');
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
const renderMsg = (text: string, useMathFormatting = false) => {
|
|
83
|
+
try {
|
|
84
|
+
let parsedText = DOMPurify.sanitize(
|
|
85
|
+
(
|
|
86
|
+
marked.parse(
|
|
87
|
+
text
|
|
88
|
+
// remove leading and trailing whitespaces
|
|
89
|
+
.trim()
|
|
90
|
+
// remove markdown links
|
|
91
|
+
.replaceAll(
|
|
92
|
+
/\[([^\]]+)\]\(([^\)]+)\)/g,
|
|
93
|
+
'<a href="$2" target="_blank" rel="noopener noreferrer">$1</a>'
|
|
94
|
+
)
|
|
95
|
+
// remove markdown multiline code blocks but keep the content
|
|
96
|
+
.replaceAll(/```markdown([^```]+)```/g, '$1')
|
|
97
|
+
.replaceAll('($', '( $')
|
|
98
|
+
.replaceAll(':$', ': $')
|
|
99
|
+
.replaceAll('\frac', '\\frac')
|
|
100
|
+
.replaceAll('\beta', '\\beta')
|
|
101
|
+
.replaceAll('cdot', '\\cdot')
|
|
102
|
+
) as string
|
|
103
|
+
)
|
|
104
|
+
.trim()
|
|
105
|
+
.replace(/\n/g, '<br>'),
|
|
106
|
+
{
|
|
107
|
+
ADD_ATTR: ['target'],
|
|
108
|
+
}
|
|
109
|
+
);
|
|
110
|
+
|
|
111
|
+
if (useMathFormatting) {
|
|
112
|
+
parsedText = parseSquaredBrackets(parsedText);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return (
|
|
116
|
+
parsedText
|
|
117
|
+
// replace consecutive <br> with a single <br>
|
|
118
|
+
.replace(/(<br>)+/g, '<br>')
|
|
119
|
+
// remove empty paragraphs
|
|
120
|
+
.replace(/<p><\/p>/g, '<br>')
|
|
121
|
+
.replace(/<p><br><\/p>/g, '<br>')
|
|
122
|
+
);
|
|
123
|
+
} catch (e) {
|
|
124
|
+
console.error(e);
|
|
125
|
+
return text;
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
export interface Props {
|
|
130
|
+
message: Message;
|
|
131
|
+
memori: Memori;
|
|
132
|
+
sessionID: string;
|
|
133
|
+
tenant?: Tenant;
|
|
134
|
+
baseUrl?: string;
|
|
135
|
+
apiUrl?: string;
|
|
136
|
+
showFeedback?: boolean;
|
|
137
|
+
showWhyThisAnswer?: boolean;
|
|
138
|
+
showCopyButton?: boolean;
|
|
139
|
+
showTranslationOriginal?: boolean;
|
|
140
|
+
simulateUserPrompt?: (msg: string) => void;
|
|
141
|
+
showAIicon?: boolean;
|
|
142
|
+
useMathFormatting?: boolean;
|
|
143
|
+
isFirst?: boolean;
|
|
144
|
+
userAvatar?: MemoriProps['userAvatar'];
|
|
145
|
+
user?: User;
|
|
146
|
+
experts?: ExpertReference[];
|
|
147
|
+
}
|
|
148
|
+
|
|
80
149
|
const ChatBubble: React.FC<Props> = ({
|
|
81
150
|
message,
|
|
82
151
|
memori,
|
|
@@ -91,6 +160,7 @@ const ChatBubble: React.FC<Props> = ({
|
|
|
91
160
|
simulateUserPrompt,
|
|
92
161
|
showAIicon = true,
|
|
93
162
|
isFirst = false,
|
|
163
|
+
useMathFormatting = false,
|
|
94
164
|
user,
|
|
95
165
|
userAvatar,
|
|
96
166
|
experts,
|
|
@@ -99,83 +169,29 @@ const ChatBubble: React.FC<Props> = ({
|
|
|
99
169
|
const lang = i18n.language || 'en';
|
|
100
170
|
const [showingWhyThisAnswer, setShowingWhyThisAnswer] = useState(false);
|
|
101
171
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
172
|
+
if (useMathFormatting) {
|
|
173
|
+
marked.use(
|
|
174
|
+
markedKatex({
|
|
175
|
+
throwOnError: false,
|
|
176
|
+
output: 'htmlAndMathml',
|
|
177
|
+
})
|
|
178
|
+
);
|
|
179
|
+
}
|
|
106
180
|
|
|
107
|
-
|
|
108
|
-
if (row.includes('=')) {
|
|
109
|
-
let result = '';
|
|
110
|
-
let isEscaped = false;
|
|
111
|
-
for (let i = 0; i < row.length; i++) {
|
|
112
|
-
if (row[i] === '[' && !isEscaped) {
|
|
113
|
-
result += '\\[';
|
|
114
|
-
} else if (row[i] === ']' && !isEscaped) {
|
|
115
|
-
result += '\\]';
|
|
116
|
-
} else {
|
|
117
|
-
result += row[i];
|
|
118
|
-
}
|
|
119
|
-
isEscaped = row[i] === '\\' && !isEscaped;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
return acc?.length ? `${acc}\n${result}` : result;
|
|
123
|
-
} else {
|
|
124
|
-
return acc?.length ? `${acc}\n${row}` : row;
|
|
125
|
-
}
|
|
126
|
-
}, '');
|
|
127
|
-
};
|
|
181
|
+
const text = message.translatedText || message.text;
|
|
128
182
|
|
|
129
|
-
const
|
|
130
|
-
try {
|
|
131
|
-
return (
|
|
132
|
-
parseSquaredBrackets(
|
|
133
|
-
DOMPurify.sanitize(
|
|
134
|
-
(
|
|
135
|
-
marked.parse(
|
|
136
|
-
text
|
|
137
|
-
// remove leading and trailing whitespaces
|
|
138
|
-
.trim()
|
|
139
|
-
// remove markdown links
|
|
140
|
-
.replaceAll(
|
|
141
|
-
/\[([^\]]+)\]\(([^\)]+)\)/g,
|
|
142
|
-
'<a href="$2" target="_blank" rel="noopener noreferrer">$1</a>'
|
|
143
|
-
)
|
|
144
|
-
// remove markdown multiline code blocks but keep the content
|
|
145
|
-
.replaceAll(/```markdown([^```]+)```/g, '$1')
|
|
146
|
-
.replaceAll('($', '( $')
|
|
147
|
-
.replaceAll(':$', ': $')
|
|
148
|
-
.replaceAll('\frac', '\\frac')
|
|
149
|
-
.replaceAll('\beta', '\\beta')
|
|
150
|
-
.replaceAll('cdot', '\\cdot')
|
|
151
|
-
) as string
|
|
152
|
-
)
|
|
153
|
-
.trim()
|
|
154
|
-
.replace(/\n/g, '<br>'),
|
|
155
|
-
{
|
|
156
|
-
ADD_ATTR: ['target'],
|
|
157
|
-
}
|
|
158
|
-
)
|
|
159
|
-
)
|
|
160
|
-
// replace consecutive <br> with a single <br>
|
|
161
|
-
.replace(/(<br>)+/g, '<br>')
|
|
162
|
-
// remove empty paragraphs
|
|
163
|
-
.replace(/<p><\/p>/g, '<br>')
|
|
164
|
-
.replace(/<p><br><\/p>/g, '<br>')
|
|
165
|
-
);
|
|
166
|
-
} catch (e) {
|
|
167
|
-
console.error(e);
|
|
168
|
-
return text;
|
|
169
|
-
}
|
|
170
|
-
};
|
|
171
|
-
const renderedText = renderMsg(text);
|
|
183
|
+
const renderedText = renderMsg(text, useMathFormatting);
|
|
172
184
|
|
|
173
185
|
const plainText = message.fromUser
|
|
174
186
|
? text
|
|
175
187
|
: stripHTML(stripOutputTags(renderedText));
|
|
176
188
|
|
|
177
189
|
useLayoutEffect(() => {
|
|
178
|
-
if (
|
|
190
|
+
if (
|
|
191
|
+
typeof window !== 'undefined' &&
|
|
192
|
+
!message.fromUser &&
|
|
193
|
+
useMathFormatting
|
|
194
|
+
) {
|
|
179
195
|
// @ts-ignore
|
|
180
196
|
// eslint-disable-next-line no-undef
|
|
181
197
|
if ('MathJax' in window && window.MathJax.typesetPromise)
|
|
@@ -183,7 +199,7 @@ const ChatBubble: React.FC<Props> = ({
|
|
|
183
199
|
// eslint-disable-next-line no-undef
|
|
184
200
|
window.MathJax.typesetPromise(['.memori-chat--bubble-content']);
|
|
185
201
|
}
|
|
186
|
-
}, [message.text, message.fromUser]);
|
|
202
|
+
}, [message.text, message.fromUser, useMathFormatting]);
|
|
187
203
|
|
|
188
204
|
return (
|
|
189
205
|
<>
|