@memori.ai/memori-react 7.25.1 → 7.26.1

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.
Files changed (163) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/dist/components/Chat/Chat.d.ts +5 -10
  3. package/dist/components/Chat/Chat.js +3 -3
  4. package/dist/components/Chat/Chat.js.map +1 -1
  5. package/dist/components/ChatBubble/ChatBubble.css +10 -0
  6. package/dist/components/ChatBubble/ChatBubble.d.ts +1 -0
  7. package/dist/components/ChatBubble/ChatBubble.js +24 -20
  8. package/dist/components/ChatBubble/ChatBubble.js.map +1 -1
  9. package/dist/components/ChatBubble/VirtualizedContent/VirtualizedContent.d.ts +7 -0
  10. package/dist/components/ChatBubble/VirtualizedContent/VirtualizedContent.js +69 -0
  11. package/dist/components/ChatBubble/VirtualizedContent/VirtualizedContent.js.map +1 -0
  12. package/dist/components/ChatInputs/ChatInputs.d.ts +6 -10
  13. package/dist/components/ChatInputs/ChatInputs.js +37 -30
  14. package/dist/components/ChatInputs/ChatInputs.js.map +1 -1
  15. package/dist/components/FilePreview/FilePreview.css +169 -140
  16. package/dist/components/FilePreview/FilePreview.d.ts +2 -6
  17. package/dist/components/FilePreview/FilePreview.js +58 -5
  18. package/dist/components/FilePreview/FilePreview.js.map +1 -1
  19. package/dist/components/MediaWidget/LinkItemWidget.css +1 -0
  20. package/dist/components/MediaWidget/MediaItemWidget.css +10 -0
  21. package/dist/components/MediaWidget/MediaItemWidget.d.ts +6 -2
  22. package/dist/components/MediaWidget/MediaItemWidget.js +49 -11
  23. package/dist/components/MediaWidget/MediaItemWidget.js.map +1 -1
  24. package/dist/components/MediaWidget/MediaWidget.d.ts +3 -1
  25. package/dist/components/MemoriWidget/MemoriWidget.d.ts +2 -1
  26. package/dist/components/MemoriWidget/MemoriWidget.js +10 -18
  27. package/dist/components/MemoriWidget/MemoriWidget.js.map +1 -1
  28. package/dist/components/UploadButton/UploadButton.css +506 -27
  29. package/dist/components/UploadButton/UploadButton.d.ts +14 -11
  30. package/dist/components/UploadButton/UploadButton.js +121 -288
  31. package/dist/components/UploadButton/UploadButton.js.map +1 -1
  32. package/dist/components/UploadButton/UploadDocuments/UploadDocuments.d.ts +19 -0
  33. package/dist/components/UploadButton/UploadDocuments/UploadDocuments.js +211 -0
  34. package/dist/components/UploadButton/UploadDocuments/UploadDocuments.js.map +1 -0
  35. package/dist/components/UploadButton/UploadImages/UploadImages.d.ts +13 -0
  36. package/dist/components/UploadButton/UploadImages/UploadImages.js +198 -0
  37. package/dist/components/UploadButton/UploadImages/UploadImages.js.map +1 -0
  38. package/dist/components/icons/Bug.d.ts +5 -0
  39. package/dist/components/icons/Bug.js +6 -0
  40. package/dist/components/icons/Bug.js.map +1 -0
  41. package/dist/components/icons/Document.d.ts +5 -0
  42. package/dist/components/icons/Document.js +10 -0
  43. package/dist/components/icons/Document.js.map +1 -0
  44. package/dist/components/icons/Image.d.ts +4 -0
  45. package/dist/components/icons/Image.js +9 -0
  46. package/dist/components/icons/Image.js.map +1 -0
  47. package/dist/components/icons/Preview.d.ts +4 -5
  48. package/dist/components/icons/Preview.js +5 -2
  49. package/dist/components/icons/Preview.js.map +1 -1
  50. package/dist/components/icons/Upload.d.ts +4 -5
  51. package/dist/components/icons/Upload.js +5 -2
  52. package/dist/components/icons/Upload.js.map +1 -1
  53. package/dist/components/layouts/HiddenChat.js +100 -10
  54. package/dist/components/layouts/HiddenChat.js.map +1 -1
  55. package/dist/components/layouts/hidden-chat.css +189 -119
  56. package/dist/components/ui/Card.d.ts +1 -0
  57. package/dist/components/ui/Card.js +2 -2
  58. package/dist/components/ui/Card.js.map +1 -1
  59. package/dist/locales/de.json +16 -0
  60. package/dist/locales/en.json +24 -0
  61. package/dist/locales/es.json +16 -0
  62. package/dist/locales/fr.json +16 -0
  63. package/dist/locales/it.json +22 -0
  64. package/esm/components/Chat/Chat.d.ts +5 -10
  65. package/esm/components/Chat/Chat.js +3 -3
  66. package/esm/components/Chat/Chat.js.map +1 -1
  67. package/esm/components/ChatBubble/ChatBubble.css +10 -0
  68. package/esm/components/ChatBubble/ChatBubble.d.ts +1 -0
  69. package/esm/components/ChatBubble/ChatBubble.js +24 -20
  70. package/esm/components/ChatBubble/ChatBubble.js.map +1 -1
  71. package/esm/components/ChatBubble/VirtualizedContent/VirtualizedContent.d.ts +7 -0
  72. package/esm/components/ChatBubble/VirtualizedContent/VirtualizedContent.js +67 -0
  73. package/esm/components/ChatBubble/VirtualizedContent/VirtualizedContent.js.map +1 -0
  74. package/esm/components/ChatInputs/ChatInputs.d.ts +6 -10
  75. package/esm/components/ChatInputs/ChatInputs.js +37 -30
  76. package/esm/components/ChatInputs/ChatInputs.js.map +1 -1
  77. package/esm/components/FilePreview/FilePreview.css +169 -140
  78. package/esm/components/FilePreview/FilePreview.d.ts +2 -6
  79. package/esm/components/FilePreview/FilePreview.js +58 -5
  80. package/esm/components/FilePreview/FilePreview.js.map +1 -1
  81. package/esm/components/MediaWidget/LinkItemWidget.css +1 -0
  82. package/esm/components/MediaWidget/MediaItemWidget.css +10 -0
  83. package/esm/components/MediaWidget/MediaItemWidget.d.ts +6 -2
  84. package/esm/components/MediaWidget/MediaItemWidget.js +50 -12
  85. package/esm/components/MediaWidget/MediaItemWidget.js.map +1 -1
  86. package/esm/components/MediaWidget/MediaWidget.d.ts +3 -1
  87. package/esm/components/MemoriWidget/MemoriWidget.d.ts +2 -1
  88. package/esm/components/MemoriWidget/MemoriWidget.js +10 -18
  89. package/esm/components/MemoriWidget/MemoriWidget.js.map +1 -1
  90. package/esm/components/UploadButton/UploadButton.css +506 -27
  91. package/esm/components/UploadButton/UploadButton.d.ts +14 -11
  92. package/esm/components/UploadButton/UploadButton.js +122 -289
  93. package/esm/components/UploadButton/UploadButton.js.map +1 -1
  94. package/esm/components/UploadButton/UploadDocuments/UploadDocuments.d.ts +19 -0
  95. package/esm/components/UploadButton/UploadDocuments/UploadDocuments.js +208 -0
  96. package/esm/components/UploadButton/UploadDocuments/UploadDocuments.js.map +1 -0
  97. package/esm/components/UploadButton/UploadImages/UploadImages.d.ts +13 -0
  98. package/esm/components/UploadButton/UploadImages/UploadImages.js +195 -0
  99. package/esm/components/UploadButton/UploadImages/UploadImages.js.map +1 -0
  100. package/esm/components/icons/Bug.d.ts +5 -0
  101. package/esm/components/icons/Bug.js +4 -0
  102. package/esm/components/icons/Bug.js.map +1 -0
  103. package/esm/components/icons/Document.d.ts +5 -0
  104. package/esm/components/icons/Document.js +6 -0
  105. package/esm/components/icons/Document.js.map +1 -0
  106. package/esm/components/icons/Image.d.ts +4 -0
  107. package/esm/components/icons/Image.js +5 -0
  108. package/esm/components/icons/Image.js.map +1 -0
  109. package/esm/components/icons/Preview.d.ts +4 -5
  110. package/esm/components/icons/Preview.js +4 -3
  111. package/esm/components/icons/Preview.js.map +1 -1
  112. package/esm/components/icons/Upload.d.ts +4 -5
  113. package/esm/components/icons/Upload.js +4 -3
  114. package/esm/components/icons/Upload.js.map +1 -1
  115. package/esm/components/layouts/HiddenChat.js +101 -11
  116. package/esm/components/layouts/HiddenChat.js.map +1 -1
  117. package/esm/components/layouts/hidden-chat.css +189 -119
  118. package/esm/components/ui/Card.d.ts +1 -0
  119. package/esm/components/ui/Card.js +2 -2
  120. package/esm/components/ui/Card.js.map +1 -1
  121. package/esm/locales/de.json +16 -0
  122. package/esm/locales/en.json +24 -0
  123. package/esm/locales/es.json +16 -0
  124. package/esm/locales/fr.json +16 -0
  125. package/esm/locales/it.json +22 -0
  126. package/package.json +1 -1
  127. package/src/components/Chat/Chat.stories.tsx +12 -0
  128. package/src/components/Chat/Chat.tsx +8 -8
  129. package/src/components/ChatBubble/ChatBubble.css +10 -0
  130. package/src/components/ChatBubble/ChatBubble.stories.tsx +203 -1
  131. package/src/components/ChatBubble/ChatBubble.tsx +49 -22
  132. package/src/components/ChatInputs/ChatInputs.tsx +92 -43
  133. package/src/components/FilePreview/FilePreview.css +169 -140
  134. package/src/components/FilePreview/FilePreview.tsx +106 -14
  135. package/src/components/FilePreview/__snapshots__/FilePreview.test.tsx.snap +146 -29
  136. package/src/components/MediaWidget/LinkItemWidget.css +1 -0
  137. package/src/components/MediaWidget/MediaItemWidget.css +10 -0
  138. package/src/components/MediaWidget/MediaItemWidget.tsx +136 -118
  139. package/src/components/MediaWidget/MediaWidget.test.tsx +2 -1
  140. package/src/components/MediaWidget/MediaWidget.tsx +1 -1
  141. package/src/components/MemoriWidget/MemoriWidget.tsx +7 -19
  142. package/src/components/UploadButton/UploadButton.css +506 -27
  143. package/src/components/UploadButton/UploadButton.stories.tsx +122 -20
  144. package/src/components/UploadButton/UploadButton.test.tsx +1 -1
  145. package/src/components/UploadButton/UploadButton.tsx +282 -451
  146. package/src/components/UploadButton/UploadDocuments/UploadDocuments.tsx +352 -0
  147. package/src/components/UploadButton/UploadImages/UploadImages.tsx +417 -0
  148. package/src/components/UploadButton/__snapshots__/UploadButton.test.tsx.snap +139 -13
  149. package/src/components/icons/Bug.tsx +81 -0
  150. package/src/components/icons/Document.tsx +50 -0
  151. package/src/components/icons/Image.tsx +37 -0
  152. package/src/components/icons/Preview.tsx +28 -22
  153. package/src/components/icons/Upload.tsx +33 -22
  154. package/src/components/layouts/HiddenChat.tsx +143 -7
  155. package/src/components/layouts/__snapshots__/HiddenChat.test.tsx.snap +1 -1
  156. package/src/components/layouts/hidden-chat.css +189 -119
  157. package/src/components/ui/Card.tsx +3 -0
  158. package/src/index.stories.tsx +19 -19
  159. package/src/locales/de.json +16 -0
  160. package/src/locales/en.json +24 -0
  161. package/src/locales/es.json +16 -0
  162. package/src/locales/fr.json +16 -0
  163. package/src/locales/it.json +22 -0
@@ -148,6 +148,22 @@
148
148
  "attachmentsLabel": "Enrichissez votre message",
149
149
  "iWantToTalkToIn": "je veux parler à {{name}} dans"
150
150
  },
151
+ "upload": {
152
+ "loginRequired": "Connexion requise",
153
+ "loginRequiredDescription": "Veuillez vous connecter pour télécharger des images",
154
+ "uploadFiles": "Télécharger des fichiers",
155
+ "uploadImage": "Télécharger une image",
156
+ "uploadDocument": "Télécharger un document",
157
+ "replace": "Remplacer",
158
+ "remaining": "restant",
159
+ "maxReached": "Limite atteinte",
160
+ "maxImagesReached": "Vous pouvez télécharger jusqu'à {{max}} images",
161
+ "apiClientNotConfigured": "API client non configuré correctement pour le téléchargement de médias",
162
+ "fileReadingFailed": "Échec de la lecture du fichier",
163
+ "uploadFailed": "Échec du téléchargement",
164
+ "uploadSuccess": "Téléchargement réussi",
165
+ "uploadSuccessDescription": "Le fichier a été téléchargé avec succès"
166
+ },
151
167
  "media": {
152
168
  "title": "Titre",
153
169
  "editAttributes": "Modifier les attributs du média",
@@ -187,6 +187,28 @@
187
187
  "linkValue": "Titolo link",
188
188
  "insertThisLink": "Inserisci un link a {{url}} con titolo {{title}}"
189
189
  },
190
+ "upload": {
191
+ "loginRequired": "Login richiesto",
192
+ "loginRequiredDescription": "Per caricare immagini, devi prima accedere",
193
+ "uploadFiles": "Carica file",
194
+ "uploadImage": "Carica immagine",
195
+ "uploadDocument": "Carica documento",
196
+ "replace": "Sostituisci documento",
197
+ "maxImagesReached": "Puoi caricare fino a {{max}} immagini",
198
+ "apiClientNotConfigured": "Client API non configurato correttamente per il caricamento di media",
199
+ "fileReadingFailed": "Lettura del file fallita",
200
+ "uploadFailed": "Caricamento fallito",
201
+ "uploadSuccess": "Caricamento riuscito",
202
+ "remaining": "rimanenti",
203
+ "maxReached": "Limite raggiunto",
204
+ "titleImage": "Immagine: {{title}}",
205
+ "titleImageUpload": "Carica immagini",
206
+ "titleHelp": "Aggiungi un titolo descrittivo per aiutare l'AI a fornire risposte più appropriate.",
207
+ "titlePlaceholder": "Inserisci il titolo dell'immagine",
208
+ "uploadSuccessDescription": "Il file è stato caricato con successo",
209
+ "partialUpload": "Solo {{uploaded}} immagini su {{total}} immagini saranno caricate. Massimo {{max}} immagini consentite.",
210
+ "cancel": "Annulla"
211
+ },
190
212
  "gamification": {
191
213
  "level": "Livello",
192
214
  "points": "punti",
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "7.25.1",
2
+ "version": "7.26.1",
3
3
  "name": "@memori.ai/memori-react",
4
4
  "author": "Memori Srl",
5
5
  "main": "dist/index.js",
@@ -9,6 +9,7 @@ import {
9
9
  sessionID,
10
10
  dialogState as dialogStateWithHints,
11
11
  historyWithExpandable,
12
+ historyWithLongHTMLTable,
12
13
  } from '../../mocks/data';
13
14
  import I18nWrapper from '../../I18nWrapper';
14
15
  import Chat, { Props } from './Chat';
@@ -301,4 +302,15 @@ WithExpandable.args = {
301
302
  sendMessage: (msg: string) => console.log(msg),
302
303
  stopListening: () => {},
303
304
  resetTranscript: () => {},
305
+ };
306
+
307
+
308
+ export const WithLongHTMLTable = Template.bind({});
309
+ WithLongHTMLTable.args = {
310
+ memori,
311
+ tenant,
312
+ sessionID,
313
+ history: historyWithLongHTMLTable,
314
+ dialogState,
315
+ layout: 'DEFAULT',
304
316
  };
@@ -1,8 +1,9 @@
1
- import React, { useEffect, memo } from 'react';
1
+ import React, { useEffect, memo, useState } from 'react';
2
2
  import cx from 'classnames';
3
3
  import {
4
4
  DialogState,
5
5
  ExpertReference,
6
+ Medium,
6
7
  Memori,
7
8
  Message,
8
9
  Tenant,
@@ -57,13 +58,7 @@ export interface Props {
57
58
  onChangeUserMessage: (userMessage: string) => void;
58
59
  sendMessage: (
59
60
  msg: string,
60
- media?: {
61
- mediumID: string;
62
- mimeType: string;
63
- content: string;
64
- title?: string;
65
- properties?: { [key: string]: any };
66
- }
61
+ media?: (Medium & { type: string })[]
67
62
  ) => void;
68
63
  listening?: boolean;
69
64
  setEnableFocusChatInput: (enableFocusChatInput: boolean) => void;
@@ -78,6 +73,7 @@ export interface Props {
78
73
  user?: User;
79
74
  experts?: ExpertReference[];
80
75
  useMathFormatting?: boolean;
76
+ showFunctionCache?: boolean;
81
77
  }
82
78
 
83
79
  const Chat: React.FC<Props> = ({
@@ -125,6 +121,7 @@ const Chat: React.FC<Props> = ({
125
121
  showUpload = false,
126
122
  experts,
127
123
  useMathFormatting = false,
124
+ showFunctionCache = false,
128
125
  }) => {
129
126
  const scrollToBottom = () => {
130
127
  setTimeout(() => {
@@ -230,6 +227,7 @@ const Chat: React.FC<Props> = ({
230
227
  experts={experts}
231
228
  showCopyButton={showCopyButton}
232
229
  useMathFormatting={useMathFormatting}
230
+ showFunctionCache={showFunctionCache}
233
231
  />
234
232
 
235
233
  {showDates && !!message.timestamp && (
@@ -340,6 +338,7 @@ const Chat: React.FC<Props> = ({
340
338
 
341
339
  {showInputs && (
342
340
  <ChatInputs
341
+ apiURL={apiUrl || ''}
343
342
  resetTranscript={resetTranscript}
344
343
  userMessage={userMessage}
345
344
  onChangeUserMessage={onChangeUserMessage}
@@ -350,6 +349,7 @@ const Chat: React.FC<Props> = ({
350
349
  microphoneMode={microphoneMode}
351
350
  sendOnEnter={sendOnEnter}
352
351
  setSendOnEnter={setSendOnEnter}
352
+ sessionID={sessionID}
353
353
  showUpload={showUpload}
354
354
  attachmentsMenuOpen={attachmentsMenuOpen}
355
355
  setAttachmentsMenuOpen={setAttachmentsMenuOpen}
@@ -305,3 +305,13 @@
305
305
  .memori-chat--bubble.memori-chat--user-bubble .memori-expandable > button {
306
306
  color: var(--memori-primary-text);
307
307
  }
308
+
309
+ .memori-chat--function-cache-modal .memori-modal--panel {
310
+ width: 80%;
311
+ height: 100%;
312
+ /* padding: 20px; */
313
+ max-height: 80vh;
314
+ border-radius: 10px;
315
+ background-color: #fff;
316
+ overflow-y: auto;
317
+ }
@@ -91,7 +91,6 @@ FromUserWithLink.args = {
91
91
  },
92
92
  };
93
93
 
94
-
95
94
  export const Initial = Template.bind({});
96
95
  Initial.args = {
97
96
  memori,
@@ -617,3 +616,206 @@ WithHTML.args = {
617
616
  `,
618
617
  },
619
618
  };
619
+
620
+ // 9. Complex HTML Table
621
+ export const ComplexHTMLTable = Template.bind({});
622
+ ComplexHTMLTable.args = {
623
+ memori,
624
+ tenant,
625
+ message: {
626
+ fromUser: false,
627
+ text: `<table border="1" style="border-collapse: collapse; width: 100%;">
628
+ <thead>
629
+ <tr style="background-color: #f2f2f2;">
630
+ <th colspan="3" style="text-align: center; padding: 8px;">Project Timeline</th>
631
+ </tr>
632
+ <tr style="background-color: #f2f2f2;">
633
+ <th style="text-align: left; padding: 8px;">Phase</th>
634
+ <th style="text-align: left; padding: 8px;">Start Date</th>
635
+ <th style="text-align: left; padding: 8px;">End Date</th>
636
+ </tr>
637
+ </thead>
638
+ <tbody>
639
+ <tr>
640
+ <td style="padding: 8px;">Planning</td>
641
+ <td style="padding: 8px;">Jan 15, 2025</td>
642
+ <td style="padding: 8px;">Feb 28, 2025</td>
643
+ </tr>
644
+ <tr style="background-color: #f9f9f9;">
645
+ <td style="padding: 8px;">Development</td>
646
+ <td style="padding: 8px;">Mar 1, 2025</td>
647
+ <td style="padding: 8px;">Jun 30, 2025</td>
648
+ </tr>
649
+ <tr>
650
+ <td style="padding: 8px;">Testing</td>
651
+ <td style="padding: 8px;">Jul 1, 2025</td>
652
+ <td style="padding: 8px;">Aug 15, 2025</td>
653
+ </tr>
654
+ <tr style="background-color: #f9f9f9;">
655
+ <td style="padding: 8px;">Deployment</td>
656
+ <td style="padding: 8px;">Aug 16, 2025</td>
657
+ <td style="padding: 8px;">Sep 30, 2025</td>
658
+ </tr>
659
+ </tbody>
660
+ <tfoot>
661
+ <tr style="background-color: #f2f2f2;">
662
+ <td colspan="3" style="text-align: center; padding: 8px;">Total Duration: 8.5 months</td>
663
+ </tr>
664
+ </tfoot>
665
+ </table>`,
666
+ initial: false,
667
+ },
668
+ };
669
+ ComplexHTMLTable.parameters = {
670
+ docs: {
671
+ description: {
672
+ story:
673
+ 'A message containing a complex HTML table that should trigger the loading spinner before rendering.',
674
+ },
675
+ },
676
+ };
677
+
678
+ //10. Long text message
679
+ export const MediumLongTextMessage = Template.bind({});
680
+ MediumLongTextMessage.args = {
681
+ memori,
682
+ tenant,
683
+ message: {
684
+ fromUser: false,
685
+ text: Array(100)
686
+ .fill(
687
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor.'
688
+ )
689
+ .join('\n\n'),
690
+ initial: false,
691
+ },
692
+ };
693
+
694
+ export const LongTextMessage = Template.bind({});
695
+ LongTextMessage.args = {
696
+ memori,
697
+ tenant,
698
+ message: {
699
+ fromUser: false,
700
+ text: Array(200)
701
+ .fill(
702
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper congue, euismod non, mi.'
703
+ )
704
+ .join('\n\n'),
705
+ initial: false,
706
+ },
707
+ };
708
+
709
+ export const LongTextMessageWithHTML = Template.bind({});
710
+ LongTextMessageWithHTML.args = {
711
+ memori,
712
+ tenant,
713
+ message: {
714
+ fromUser: false,
715
+ text:
716
+ Array(200)
717
+ .fill(
718
+ 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper congue, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat.'
719
+ )
720
+ .join('\n\n') +
721
+ `
722
+ <div>
723
+ <div style="width: 30%; margin-bottom: 20px;">
724
+ <img src="https://www.e-stayon.com/images/thumbs/0244280_lenovo-ideapad-3-chromebook-15-intel-celeron-4gb-64gb_360.jpeg" style="width:100%">
725
+ <h3>Lenovo IdeaPad 3 Chromebook</h3>
726
+ <p>Intel Celeron, 15", 4GB RAM, 64GB</p>
727
+ <p>Prezzo: €194,88 (sconto 12% da €221,59)</p>
728
+ </div>`,
729
+ },
730
+ };
731
+
732
+ // 10. Message with an embedded helper function to show requiresFormatting detection
733
+ export const FormattingDetectionDemo = Template.bind({});
734
+ FormattingDetectionDemo.args = {
735
+ memori,
736
+ tenant,
737
+ message: {
738
+ fromUser: false,
739
+ text: 'This message demonstrates how the formatting detection works.\n\nBelow are some examples of content that will be detected as requiring formatting:\n\n1. HTML tags: <div>Example</div>\n2. Markdown tables: | Header | Content |\n3. Code blocks: ```javascript\nconst x = 1;\n```\n4. Math formulas: $E = mc^2$\n5. Tabbed data: Name\tAge\tLocation\n\nThe requiresFormatting function will detect these patterns and show a loading spinner.',
740
+ initial: false,
741
+ },
742
+ };
743
+ FormattingDetectionDemo.parameters = {
744
+ docs: {
745
+ description: {
746
+ story:
747
+ 'A demonstration of different content patterns that trigger the loading spinner.',
748
+ },
749
+ },
750
+ };
751
+
752
+ export const HTMLTable = Template.bind({});
753
+ HTMLTable.args = {
754
+ memori,
755
+ tenant,
756
+ message: {
757
+ fromUser: false,
758
+ text: `Ecco la lista formattata in HTML dei task e dei relativi assegnatari:
759
+ <table>
760
+ <tr>
761
+ <th>Task</th>
762
+ <th>Assegnato a</th>
763
+ </tr>
764
+ <tr><td>Market Research</td><td>Alice</td></tr>
765
+ <tr><td>Content Creation</td><td>Bob</td></tr>
766
+ <tr><td>Social Media Planning</td><td>Charlie</td></tr>
767
+ <tr><td>Campaign Analysis</td><td>Daisy</td></tr>
768
+ <tr><td>Prototype Development</td><td>Ethan</td></tr>
769
+ <tr><td>Quality Assurance</td><td>Fiona</td></tr>
770
+ <tr><td>User Interface Design</td><td>Gabriel</td></tr>
771
+ <tr><td>Service Improvement</td><td>Hannah</td></tr>
772
+ <tr><td>Ticket Resolution</td><td>Ian</td></tr>
773
+ <tr><td>Customer Feedback</td><td>Julia</td></tr>
774
+ <tr><td>Budget Analysis</td><td>Kevin</td></tr>
775
+ <tr><td>Financial Reporting</td><td>Mark</td></tr>
776
+ <tr><td>Investment Planning</td><td>Mark</td></tr>
777
+ <tr><td>Market Trends Analysis</td><td>Nathan</td></tr>
778
+ <tr><td>Data Collection</td><td>Olivia</td></tr>
779
+ <tr><td>Research Paper Writing</td><td>Peter</td></tr>
780
+ <tr><td>Software Development</td><td>Quinn</td></tr>
781
+ <tr><td>Feature Enhancement</td><td>Rachel</td></tr>
782
+ <tr><td>Code Review</td><td>Sam</td></tr>
783
+ <tr><td>Manufacturing</td><td>Tim</td></tr>
784
+ <tr><td>Product Design</td><td>Uma</td></tr>
785
+ <tr><td>UX Research</td><td>Victor</td></tr>
786
+ <tr><td>API Development</td><td>Wendy</td></tr>
787
+ <tr><td>Database Management</td><td>Xavier</td></tr>
788
+ <tr><td>Cloud Infrastructure</td><td>Yara</td></tr>
789
+ <tr><td>Security Testing</td><td>Zack</td></tr>
790
+ <tr><td>Documentation</td><td>Adam</td></tr>
791
+ <tr><td>Technical Support</td><td>Beth</td></tr>
792
+ <tr><td>Project Management</td><td>Carl</td></tr>
793
+ <tr><td>Business Analysis</td><td>Diana</td></tr>
794
+ <tr><td>DevOps Engineering</td><td>Erik</td></tr>
795
+ <tr><td>Mobile Development</td><td>Faith</td></tr>
796
+ <tr><td>Frontend Development</td><td>George</td></tr>
797
+ <tr><td>Backend Development</td><td>Helen</td></tr>
798
+ <tr><td>System Architecture</td><td>Isaac</td></tr>
799
+ <tr><td>Data Analysis</td><td>Jane</td></tr>
800
+ <tr><td>Machine Learning</td><td>Kyle</td></tr>
801
+ <tr><td>AI Development</td><td>Lisa</td></tr>
802
+ <tr><td>Network Security</td><td>Mike</td></tr>
803
+ <tr><td>Performance Testing</td><td>Nina</td></tr>
804
+ <tr><td>Load Testing</td><td>Oscar</td></tr>
805
+ <tr><td>Penetration Testing</td><td>Penny</td></tr>
806
+ <tr><td>Automation Testing</td><td>Quentin</td></tr>
807
+ <tr><td>Release Management</td><td>Rose</td></tr>
808
+ <tr><td>Configuration Management</td><td>Steve</td></tr>
809
+ <tr><td>Change Management</td><td>Tina</td></tr>
810
+ <tr><td>Risk Management</td><td>Ulysses</td></tr>
811
+ <tr><td>Resource Planning</td><td>Violet</td></tr>
812
+ <tr><td>Capacity Planning</td><td>Walter</td></tr>
813
+ <tr><td>Strategic Planning</td><td>Xena</td></tr>
814
+ <tr><td>Operations Management</td><td>Yuki</td></tr>
815
+ <tr><td>Quality Management</td><td>Zara</td></tr>
816
+ </table>
817
+
818
+ Ho mostrato i primi 20 task per brevità. La tabella include il nome del task e la persona assegnata.`,
819
+ initial: false,
820
+ },
821
+ };
@@ -20,11 +20,12 @@ import Button from '../ui/Button';
20
20
  import QuestionHelp from '../icons/QuestionHelp';
21
21
  import Copy from '../icons/Copy';
22
22
  import Code from '../icons/Code';
23
+ import Bug from '../icons/Bug';
23
24
  import WhyThisAnswer from '../WhyThisAnswer/WhyThisAnswer';
24
25
  import { stripHTML, stripOutputTags } from '../../helpers/utils';
25
- import FilePreview from '../FilePreview/FilePreview';
26
26
  import { renderMsg, truncateMessage } from '../../helpers/message';
27
27
  import Expandable from '../ui/Expandable';
28
+ import Modal from '../ui/Modal';
28
29
 
29
30
  // Always import and load MathJax
30
31
  import { installMathJax } from '../../helpers/utils';
@@ -56,6 +57,7 @@ export interface Props {
56
57
  userAvatar?: MemoriProps['userAvatar'];
57
58
  user?: User;
58
59
  experts?: ExpertReference[];
60
+ showFunctionCache?: boolean;
59
61
  }
60
62
 
61
63
  const ChatBubble: React.FC<Props> = ({
@@ -76,10 +78,12 @@ const ChatBubble: React.FC<Props> = ({
76
78
  user,
77
79
  userAvatar,
78
80
  experts,
81
+ showFunctionCache = false,
79
82
  }) => {
80
83
  const { t, i18n } = useTranslation();
81
84
  const lang = i18n.language || 'en';
82
85
  const [showingWhyThisAnswer, setShowingWhyThisAnswer] = useState(false);
86
+ const [openFunctionCache, setOpenFunctionCache] = useState(false);
83
87
 
84
88
  // Initialize MathJax on component mount
85
89
  useEffect(() => {
@@ -94,10 +98,12 @@ const ChatBubble: React.FC<Props> = ({
94
98
  ? truncateMessage(text)
95
99
  : stripHTML(stripOutputTags(renderedText));
96
100
 
97
- // Render MathJax whenever message content changes
101
+ // Format function cache content
102
+ const functionCacheData = message.media?.find(
103
+ m => m.properties?.functionCache === 'true'
104
+ );
98
105
  useLayoutEffect(() => {
99
106
  if (typeof window !== 'undefined' && !message.fromUser) {
100
- // Allow a short delay for the DOM to update
101
107
  const timer = setTimeout(() => {
102
108
  if (window.MathJax && window.MathJax.typesetPromise) {
103
109
  try {
@@ -105,9 +111,21 @@ const ChatBubble: React.FC<Props> = ({
105
111
  '.memori-chat--bubble-content'
106
112
  );
107
113
  if (elements.length > 0) {
114
+ // Salva la posizione di scroll corrente
115
+ const scrollContainer = document.querySelector('.memori-chat--history');
116
+ const currentScrollTop = scrollContainer?.scrollTop || 0;
117
+ const currentScrollHeight = scrollContainer?.scrollHeight || 0;
118
+
108
119
  window.MathJax.typesetPromise([
109
120
  '.memori-chat--bubble-content',
110
- ]).catch(err =>
121
+ ]).then(() => {
122
+ // Ripristina la posizione di scroll dopo il rendering MathJax
123
+ if (scrollContainer) {
124
+ const newScrollHeight = scrollContainer.scrollHeight;
125
+ const heightDifference = newScrollHeight - currentScrollHeight;
126
+ scrollContainer.scrollTop = currentScrollTop + heightDifference;
127
+ }
128
+ }).catch(err =>
111
129
  console.error('MathJax typesetting failed:', err)
112
130
  );
113
131
  }
@@ -116,11 +134,10 @@ const ChatBubble: React.FC<Props> = ({
116
134
  }
117
135
  }
118
136
  }, 100);
119
-
137
+
120
138
  return () => clearTimeout(timer);
121
139
  }
122
140
  }, [message.text, message.fromUser, renderedText]);
123
-
124
141
  return (
125
142
  <>
126
143
  {(message.initial || isFirst) && (
@@ -282,6 +299,21 @@ const ChatBubble: React.FC<Props> = ({
282
299
  />
283
300
  )}
284
301
 
302
+ {!message.fromUser &&
303
+ showFunctionCache &&
304
+ message.media?.some(
305
+ m => m.properties?.functionCache === 'true'
306
+ ) && (
307
+ <Button
308
+ ghost
309
+ shape="circle"
310
+ title="Debug"
311
+ className="memori-chat--bubble-action-icon"
312
+ icon={<Bug aria-label="Debug" />}
313
+ onClick={() => setOpenFunctionCache(true)}
314
+ />
315
+ )}
316
+
285
317
  {showFeedback && !!simulateUserPrompt && (
286
318
  <FeedbackButtons
287
319
  memori={memori}
@@ -355,22 +387,6 @@ const ChatBubble: React.FC<Props> = ({
355
387
  )}
356
388
  </div>
357
389
  )}
358
-
359
- {message.fromUser &&
360
- message.media &&
361
- message.media?.length > 0 &&
362
- message.media[0].properties?.isAttachedFile && (
363
- <FilePreview
364
- previewFiles={message.media.map(m => ({
365
- name: m.title ?? '',
366
- id: m.mediumID,
367
- content: m.content ?? '',
368
- }))}
369
- removeFile={() => {}}
370
- allowRemove={false}
371
- isMessagePreview={true}
372
- />
373
- )}
374
390
  </Transition.Child>
375
391
 
376
392
  {message.fromUser && (
@@ -445,6 +461,17 @@ const ChatBubble: React.FC<Props> = ({
445
461
  sessionID={sessionID}
446
462
  />
447
463
  )}
464
+
465
+ <Modal
466
+ title={functionCacheData?.title}
467
+ open={openFunctionCache}
468
+ onClose={() => setOpenFunctionCache(false)}
469
+ className="memori-chat--function-cache-modal"
470
+ >
471
+ <pre style={{ whiteSpace: 'pre-wrap', wordWrap: 'break-word' }}>
472
+ {functionCacheData?.content}
473
+ </pre>
474
+ </Modal>
448
475
  </>
449
476
  );
450
477
  };