@memori.ai/memori-react 9.0.0-alpha.23 → 9.0.0-alpha.25

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 (285) hide show
  1. package/CHANGELOG.md +300 -1100
  2. package/dist/components/AgeVerificationModal/AgeVerificationModal.js +1 -3
  3. package/dist/components/AgeVerificationModal/AgeVerificationModal.js.map +1 -1
  4. package/dist/components/Auth/Auth.js +1 -3
  5. package/dist/components/Auth/Auth.js.map +1 -1
  6. package/dist/components/Chat/Chat.css +10 -1
  7. package/dist/components/Chat/Chat.js +1 -3
  8. package/dist/components/Chat/Chat.js.map +1 -1
  9. package/dist/components/ChatBubble/ChatBubble.css +103 -5
  10. package/dist/components/ChatBubble/ChatBubble.js +48 -8
  11. package/dist/components/ChatBubble/ChatBubble.js.map +1 -1
  12. package/dist/components/ChatHistoryDrawer/ChatHistory.js +1 -3
  13. package/dist/components/ChatHistoryDrawer/ChatHistory.js.map +1 -1
  14. package/dist/components/ChatHistoryDrawer/ChatResumeDrawer.css +33 -10
  15. package/dist/components/ChatHistoryDrawer/ChatResumeDrawer.js +2 -4
  16. package/dist/components/ChatHistoryDrawer/ChatResumeDrawer.js.map +1 -1
  17. package/dist/components/ChatInputs/ChatInputs.css +17 -52
  18. package/dist/components/ChatInputs/ChatInputs.js +1 -3
  19. package/dist/components/ChatInputs/ChatInputs.js.map +1 -1
  20. package/dist/components/ContentPreviewModal/ContentPreviewModal.css +3 -3
  21. package/dist/components/ContentPreviewModal/ContentPreviewModal.js +1 -3
  22. package/dist/components/ContentPreviewModal/ContentPreviewModal.js.map +1 -1
  23. package/dist/components/DateSelector/DateSelector.css +66 -3
  24. package/dist/components/DateSelector/DateSelector.js +5 -1
  25. package/dist/components/DateSelector/DateSelector.js.map +1 -1
  26. package/dist/components/ExpertsDrawer/ExpertsDrawer.js +1 -3
  27. package/dist/components/ExpertsDrawer/ExpertsDrawer.js.map +1 -1
  28. package/dist/components/FilePreview/FilePreview.css +94 -220
  29. package/dist/components/FilePreview/FilePreview.js +25 -71
  30. package/dist/components/FilePreview/FilePreview.js.map +1 -1
  31. package/dist/components/IconButton/IconButton.css +2 -11
  32. package/dist/components/KnownFacts/KnownFacts.css +3 -4
  33. package/dist/components/KnownFacts/KnownFacts.js +3 -5
  34. package/dist/components/KnownFacts/KnownFacts.js.map +1 -1
  35. package/dist/components/LoginDrawer/LoginDrawer.css +3 -7
  36. package/dist/components/LoginDrawer/LoginDrawer.js +51 -9
  37. package/dist/components/LoginDrawer/LoginDrawer.js.map +1 -1
  38. package/dist/components/MediaWidget/MediaItemWidget.css +77 -57
  39. package/dist/components/MediaWidget/MediaItemWidget.js +4 -4
  40. package/dist/components/MediaWidget/MediaItemWidget.js.map +1 -1
  41. package/dist/components/MemoriArtifactSystem/components/ArtifactActions/styles.css +1 -1
  42. package/dist/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.js +2 -5
  43. package/dist/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.js.map +1 -1
  44. package/dist/components/MemoriWidget/MemoriWidget.css +0 -55
  45. package/dist/components/MemoriWidget/MemoriWidget.js +115 -117
  46. package/dist/components/MemoriWidget/MemoriWidget.js.map +1 -1
  47. package/dist/components/MobileSessionPanel/MobileSessionPanel.css +20 -0
  48. package/dist/components/MobileSessionPanel/MobileSessionPanel.js +77 -117
  49. package/dist/components/MobileSessionPanel/MobileSessionPanel.js.map +1 -1
  50. package/dist/components/PositionPopover/PositionPopover.css +1 -1
  51. package/dist/components/SettingsDrawer/SettingsDrawer.js +1 -3
  52. package/dist/components/SettingsDrawer/SettingsDrawer.js.map +1 -1
  53. package/dist/components/StartPanel/StartPanel.css +12 -1
  54. package/dist/components/StartPanel/StartPanel.js +30 -7
  55. package/dist/components/StartPanel/StartPanel.js.map +1 -1
  56. package/dist/components/UploadButton/UploadButton.css +7 -7
  57. package/dist/components/UploadButton/UploadButton.js +3 -0
  58. package/dist/components/UploadButton/UploadButton.js.map +1 -1
  59. package/dist/components/UploadButton/UploadDocuments/UploadDocuments.js +15 -5
  60. package/dist/components/UploadButton/UploadDocuments/UploadDocuments.js.map +1 -1
  61. package/dist/components/UploadButton/UploadImages/UploadImages.js +1 -3
  62. package/dist/components/UploadButton/UploadImages/UploadImages.js.map +1 -1
  63. package/dist/components/WhyThisAnswer/WhyThisAnswer.js +1 -3
  64. package/dist/components/WhyThisAnswer/WhyThisAnswer.js.map +1 -1
  65. package/dist/components/layouts/HiddenChat.js +9 -1
  66. package/dist/components/layouts/HiddenChat.js.map +1 -1
  67. package/dist/components/layouts/WebsiteAssistant/WebsiteAssistant.js +84 -5
  68. package/dist/components/layouts/WebsiteAssistant/WebsiteAssistant.js.map +1 -1
  69. package/dist/components/layouts/WebsiteAssistant/website-assistant.css +36 -12
  70. package/dist/components/layouts/fullpage.css +1 -0
  71. package/dist/components/layouts/hidden-chat.css +29 -5
  72. package/dist/helpers/constants.d.ts +3 -2
  73. package/dist/helpers/constants.js +19 -20
  74. package/dist/helpers/constants.js.map +1 -1
  75. package/dist/helpers/error.js +2 -1
  76. package/dist/helpers/error.js.map +1 -1
  77. package/dist/helpers/positionPopover.d.ts +1 -0
  78. package/dist/helpers/positionPopover.js +7 -0
  79. package/dist/helpers/positionPopover.js.map +1 -1
  80. package/dist/helpers/usePressTooltip.d.ts +6 -1
  81. package/dist/helpers/usePressTooltip.js +16 -1
  82. package/dist/helpers/usePressTooltip.js.map +1 -1
  83. package/dist/helpers/utils.d.ts +2 -1
  84. package/dist/helpers/utils.js +7 -1
  85. package/dist/helpers/utils.js.map +1 -1
  86. package/dist/locales/de.json +8 -2
  87. package/dist/locales/en.json +6 -3
  88. package/dist/locales/es.json +6 -3
  89. package/dist/locales/fr.json +6 -3
  90. package/dist/locales/it.json +6 -3
  91. package/dist/styles.css +1 -1
  92. package/dist/version.d.ts +1 -1
  93. package/dist/version.js +1 -1
  94. package/esm/components/AgeVerificationModal/AgeVerificationModal.js +1 -3
  95. package/esm/components/AgeVerificationModal/AgeVerificationModal.js.map +1 -1
  96. package/esm/components/Auth/Auth.js +1 -3
  97. package/esm/components/Auth/Auth.js.map +1 -1
  98. package/esm/components/Chat/Chat.css +10 -1
  99. package/esm/components/Chat/Chat.js +1 -3
  100. package/esm/components/Chat/Chat.js.map +1 -1
  101. package/esm/components/ChatBubble/ChatBubble.css +103 -5
  102. package/esm/components/ChatBubble/ChatBubble.js +48 -8
  103. package/esm/components/ChatBubble/ChatBubble.js.map +1 -1
  104. package/esm/components/ChatHistoryDrawer/ChatHistory.js +1 -3
  105. package/esm/components/ChatHistoryDrawer/ChatHistory.js.map +1 -1
  106. package/esm/components/ChatHistoryDrawer/ChatResumeDrawer.css +33 -10
  107. package/esm/components/ChatHistoryDrawer/ChatResumeDrawer.js +2 -4
  108. package/esm/components/ChatHistoryDrawer/ChatResumeDrawer.js.map +1 -1
  109. package/esm/components/ChatInputs/ChatInputs.css +17 -52
  110. package/esm/components/ChatInputs/ChatInputs.js +1 -3
  111. package/esm/components/ChatInputs/ChatInputs.js.map +1 -1
  112. package/esm/components/ContentPreviewModal/ContentPreviewModal.css +3 -3
  113. package/esm/components/ContentPreviewModal/ContentPreviewModal.js +1 -3
  114. package/esm/components/ContentPreviewModal/ContentPreviewModal.js.map +1 -1
  115. package/esm/components/DateSelector/DateSelector.css +66 -3
  116. package/esm/components/DateSelector/DateSelector.js +5 -1
  117. package/esm/components/DateSelector/DateSelector.js.map +1 -1
  118. package/esm/components/ExpertsDrawer/ExpertsDrawer.js +1 -3
  119. package/esm/components/ExpertsDrawer/ExpertsDrawer.js.map +1 -1
  120. package/esm/components/FilePreview/FilePreview.css +94 -220
  121. package/esm/components/FilePreview/FilePreview.js +25 -71
  122. package/esm/components/FilePreview/FilePreview.js.map +1 -1
  123. package/esm/components/IconButton/IconButton.css +2 -11
  124. package/esm/components/KnownFacts/KnownFacts.css +3 -4
  125. package/esm/components/KnownFacts/KnownFacts.js +3 -5
  126. package/esm/components/KnownFacts/KnownFacts.js.map +1 -1
  127. package/esm/components/LoginDrawer/LoginDrawer.css +3 -7
  128. package/esm/components/LoginDrawer/LoginDrawer.js +51 -9
  129. package/esm/components/LoginDrawer/LoginDrawer.js.map +1 -1
  130. package/esm/components/MediaWidget/MediaItemWidget.css +77 -57
  131. package/esm/components/MediaWidget/MediaItemWidget.js +5 -5
  132. package/esm/components/MediaWidget/MediaItemWidget.js.map +1 -1
  133. package/esm/components/MemoriArtifactSystem/components/ArtifactActions/styles.css +1 -1
  134. package/esm/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.js +2 -5
  135. package/esm/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.js.map +1 -1
  136. package/esm/components/MemoriWidget/MemoriWidget.css +0 -55
  137. package/esm/components/MemoriWidget/MemoriWidget.js +115 -117
  138. package/esm/components/MemoriWidget/MemoriWidget.js.map +1 -1
  139. package/esm/components/MobileSessionPanel/MobileSessionPanel.css +20 -0
  140. package/esm/components/MobileSessionPanel/MobileSessionPanel.js +78 -118
  141. package/esm/components/MobileSessionPanel/MobileSessionPanel.js.map +1 -1
  142. package/esm/components/PositionPopover/PositionPopover.css +1 -1
  143. package/esm/components/SettingsDrawer/SettingsDrawer.js +1 -3
  144. package/esm/components/SettingsDrawer/SettingsDrawer.js.map +1 -1
  145. package/esm/components/StartPanel/StartPanel.css +12 -1
  146. package/esm/components/StartPanel/StartPanel.js +30 -7
  147. package/esm/components/StartPanel/StartPanel.js.map +1 -1
  148. package/esm/components/UploadButton/UploadButton.css +7 -7
  149. package/esm/components/UploadButton/UploadButton.js +4 -1
  150. package/esm/components/UploadButton/UploadButton.js.map +1 -1
  151. package/esm/components/UploadButton/UploadDocuments/UploadDocuments.js +17 -7
  152. package/esm/components/UploadButton/UploadDocuments/UploadDocuments.js.map +1 -1
  153. package/esm/components/UploadButton/UploadImages/UploadImages.js +1 -3
  154. package/esm/components/UploadButton/UploadImages/UploadImages.js.map +1 -1
  155. package/esm/components/WhyThisAnswer/WhyThisAnswer.js +1 -3
  156. package/esm/components/WhyThisAnswer/WhyThisAnswer.js.map +1 -1
  157. package/esm/components/layouts/HiddenChat.js +9 -1
  158. package/esm/components/layouts/HiddenChat.js.map +1 -1
  159. package/esm/components/layouts/WebsiteAssistant/WebsiteAssistant.js +85 -6
  160. package/esm/components/layouts/WebsiteAssistant/WebsiteAssistant.js.map +1 -1
  161. package/esm/components/layouts/WebsiteAssistant/website-assistant.css +36 -12
  162. package/esm/components/layouts/fullpage.css +1 -0
  163. package/esm/components/layouts/hidden-chat.css +29 -5
  164. package/esm/helpers/constants.d.ts +3 -2
  165. package/esm/helpers/constants.js +18 -19
  166. package/esm/helpers/constants.js.map +1 -1
  167. package/esm/helpers/error.js +2 -1
  168. package/esm/helpers/error.js.map +1 -1
  169. package/esm/helpers/positionPopover.d.ts +1 -0
  170. package/esm/helpers/positionPopover.js +6 -0
  171. package/esm/helpers/positionPopover.js.map +1 -1
  172. package/esm/helpers/usePressTooltip.d.ts +6 -1
  173. package/esm/helpers/usePressTooltip.js +17 -2
  174. package/esm/helpers/usePressTooltip.js.map +1 -1
  175. package/esm/helpers/utils.d.ts +2 -1
  176. package/esm/helpers/utils.js +6 -1
  177. package/esm/helpers/utils.js.map +1 -1
  178. package/esm/locales/de.json +8 -2
  179. package/esm/locales/en.json +6 -3
  180. package/esm/locales/es.json +6 -3
  181. package/esm/locales/fr.json +6 -3
  182. package/esm/locales/it.json +6 -3
  183. package/esm/styles.css +1 -1
  184. package/esm/version.d.ts +1 -1
  185. package/esm/version.js +1 -1
  186. package/package.json +4 -46
  187. package/src/components/AgeVerificationModal/AgeVerificationModal.tsx +0 -3
  188. package/src/components/Auth/Auth.tsx +0 -3
  189. package/src/components/Auth/__snapshots__/Auth.test.tsx.snap +1 -0
  190. package/src/components/BlockedMemoriBadge/__snapshots__/BlockedMemoriBadge.test.tsx.snap +5 -0
  191. package/src/components/Chat/Chat.css +10 -1
  192. package/src/components/Chat/Chat.tsx +0 -3
  193. package/src/components/Chat/__snapshots__/Chat.test.tsx.snap +1735 -1765
  194. package/src/components/ChatBubble/ChatBubble.css +103 -5
  195. package/src/components/ChatBubble/ChatBubble.test.tsx +33 -0
  196. package/src/components/ChatBubble/ChatBubble.tsx +524 -273
  197. package/src/components/ChatBubble/__snapshots__/ChatBubble.test.tsx.snap +655 -684
  198. package/src/components/ChatHistoryDrawer/ChatHistory.tsx +0 -3
  199. package/src/components/ChatHistoryDrawer/ChatResumeDrawer.css +33 -10
  200. package/src/components/ChatHistoryDrawer/ChatResumeDrawer.tsx +3 -6
  201. package/src/components/ChatInputs/ChatInputs.css +17 -52
  202. package/src/components/ChatInputs/ChatInputs.tsx +2 -4
  203. package/src/components/CompletionProviderStatus/__snapshots__/CompletionProviderStatus.test.tsx.snap +3 -0
  204. package/src/components/ContentPreviewModal/ContentPreviewModal.css +3 -3
  205. package/src/components/ContentPreviewModal/ContentPreviewModal.tsx +0 -3
  206. package/src/components/DateSelector/DateSelector.css +66 -3
  207. package/src/components/DateSelector/DateSelector.test.tsx +33 -4
  208. package/src/components/DateSelector/DateSelector.tsx +37 -11
  209. package/src/components/ExpertsDrawer/ExpertsDrawer.tsx +0 -3
  210. package/src/components/FeedbackButtons/__snapshots__/FeedbackButtons.test.tsx.snap +2 -1
  211. package/src/components/FilePreview/FilePreview.css +94 -220
  212. package/src/components/FilePreview/FilePreview.tsx +77 -124
  213. package/src/components/FilePreview/__snapshots__/FilePreview.test.tsx.snap +33 -81
  214. package/src/components/Header/ChatConsumptionDropdown.test.tsx +53 -86
  215. package/src/components/Header/__snapshots__/Header.test.tsx.snap +60 -44
  216. package/src/components/IconButton/IconButton.css +2 -11
  217. package/src/components/KnownFacts/KnownFacts.css +3 -4
  218. package/src/components/KnownFacts/KnownFacts.tsx +0 -5
  219. package/src/components/KnownFacts/__snapshots__/KnownFacts.test.tsx.snap +2 -6
  220. package/src/components/LoginDrawer/LoginDrawer.css +3 -7
  221. package/src/components/LoginDrawer/LoginDrawer.tsx +101 -54
  222. package/src/components/LoginDrawer/__snapshots__/LoginDrawer.test.tsx.snap +11 -33
  223. package/src/components/MediaWidget/MediaItemWidget.css +77 -57
  224. package/src/components/MediaWidget/MediaItemWidget.test.tsx +33 -0
  225. package/src/components/MediaWidget/MediaItemWidget.tsx +6 -12
  226. package/src/components/MediaWidget/__snapshots__/MediaItemWidget.test.tsx.snap +2 -0
  227. package/src/components/MediaWidget/__snapshots__/MediaWidget.test.tsx.snap +1 -1
  228. package/src/components/MemoriArtifactSystem/components/ArtifactActions/styles.css +1 -1
  229. package/src/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.tsx +0 -5
  230. package/src/components/MemoriWidget/MemoriUIProvider.contract.test.tsx +25 -7
  231. package/src/components/MemoriWidget/MemoriWidget.css +0 -55
  232. package/src/components/MemoriWidget/MemoriWidget.tsx +18 -12
  233. package/src/components/MobileSessionPanel/MobileSessionPanel.css +20 -0
  234. package/src/components/MobileSessionPanel/MobileSessionPanel.tsx +29 -68
  235. package/src/components/PositionPopover/PositionPopover.css +1 -1
  236. package/src/components/SettingsDrawer/SettingsDrawer.tsx +0 -3
  237. package/src/components/ShareButton/__snapshots__/ShareButton.test.tsx.snap +9 -9
  238. package/src/components/Snippet/__snapshots__/Snippet.test.tsx.snap +8 -0
  239. package/src/components/StartPanel/StartPanel.css +12 -1
  240. package/src/components/StartPanel/StartPanel.test.tsx +57 -0
  241. package/src/components/StartPanel/StartPanel.tsx +41 -4
  242. package/src/components/StartPanel/__snapshots__/StartPanel.test.tsx.snap +41 -6
  243. package/src/components/UploadButton/UploadButton.css +7 -7
  244. package/src/components/UploadButton/UploadButton.tsx +4 -0
  245. package/src/components/UploadButton/UploadDocuments/UploadDocuments.tsx +21 -8
  246. package/src/components/UploadButton/UploadImages/UploadImages.tsx +0 -3
  247. package/src/components/UploadButton/__snapshots__/UploadButton.test.tsx.snap +10 -12
  248. package/src/components/WhyThisAnswer/WhyThisAnswer.tsx +0 -3
  249. package/src/components/WhyThisAnswer/__snapshots__/WhyThisAnswer.test.tsx.snap +3 -9
  250. package/src/components/layouts/HiddenChat.tsx +9 -1
  251. package/src/components/layouts/WebsiteAssistant/WebsiteAssistant.tsx +103 -6
  252. package/src/components/layouts/WebsiteAssistant/__snapshots__/WebsiteAssistant.test.tsx.snap +63 -57
  253. package/src/components/layouts/WebsiteAssistant/website-assistant.css +36 -12
  254. package/src/components/layouts/__snapshots__/Chat.test.tsx.snap +7 -4
  255. package/src/components/layouts/__snapshots__/FullPage.test.tsx.snap +12 -8
  256. package/src/components/layouts/__snapshots__/HiddenChat.test.tsx.snap +7 -4
  257. package/src/components/layouts/__snapshots__/Totem.test.tsx.snap +10 -5
  258. package/src/components/layouts/__snapshots__/ZoomedFullBody.test.tsx.snap +6 -4
  259. package/src/components/layouts/fullpage.css +1 -0
  260. package/src/components/layouts/hidden-chat.css +29 -5
  261. package/src/components/layouts/layouts.stories.tsx +2 -2
  262. package/src/helpers/constants.ts +21 -20
  263. package/src/helpers/error.ts +2 -1
  264. package/src/helpers/positionPopover.test.ts +15 -0
  265. package/src/helpers/positionPopover.ts +16 -0
  266. package/src/helpers/usePressTooltip.test.ts +30 -0
  267. package/src/helpers/usePressTooltip.ts +31 -1
  268. package/src/helpers/utils.test.ts +14 -4
  269. package/src/helpers/utils.ts +6 -1
  270. package/src/index.tsx +1 -1
  271. package/src/locales/de.json +8 -2
  272. package/src/locales/en.json +6 -3
  273. package/src/locales/es.json +6 -3
  274. package/src/locales/fr.json +6 -3
  275. package/src/locales/it.json +6 -3
  276. package/src/styles.brandTokens.test.js +52 -0
  277. package/src/styles.css +27 -2
  278. package/src/version.ts +1 -1
  279. package/dist/context/widgetSurfaceContext.d.ts +0 -3
  280. package/dist/context/widgetSurfaceContext.js +0 -11
  281. package/dist/context/widgetSurfaceContext.js.map +0 -1
  282. package/esm/context/widgetSurfaceContext.d.ts +0 -3
  283. package/esm/context/widgetSurfaceContext.js +0 -7
  284. package/esm/context/widgetSurfaceContext.js.map +0 -1
  285. package/src/context/widgetSurfaceContext.tsx +0 -14
@@ -39,7 +39,6 @@ import {
39
39
  } from '../../helpers/message';
40
40
  import { Expandable, Modal } from '@memori.ai/ui';
41
41
  import memoriApiClient from '@memori.ai/memori-api-client';
42
- import { useWidgetSurfaceEl } from '../../context/widgetSurfaceContext';
43
42
  const ASSET_URL_PATTERN = /https?:\/\/\S*\/api\/v\d+\/asset\/\S+/gi;
44
43
 
45
44
  const sanitizeRawCopyText = (text: string) =>
@@ -128,7 +127,6 @@ const ChatBubble: React.FC<Props> = ({
128
127
  customMediaRenderer,
129
128
  }) => {
130
129
  const { t, i18n } = useTranslation();
131
- const surfaceEl = useWidgetSurfaceEl();
132
130
  const lang = i18n.language || 'en';
133
131
  const [showingWhyThisAnswer, setShowingWhyThisAnswer] = useState(false);
134
132
  const [openFunctionCache, setOpenFunctionCache] = useState(false);
@@ -440,7 +438,6 @@ const ChatBubble: React.FC<Props> = ({
440
438
  const shouldShowTimestampInAddon =
441
439
  showDates && !!formattedTimestamp && !message.fromUser && !isChatlogPanel;
442
440
  const bubbleAddonTooltipProps = {
443
- container: surfaceEl ?? undefined,
444
441
  slotProps: {
445
442
  positioner: {
446
443
  className: 'memori-chat--bubble-addon-tooltip-positioner',
@@ -538,268 +535,406 @@ const ChatBubble: React.FC<Props> = ({
538
535
  })}
539
536
  onClick={handleBubbleContainerClick}
540
537
  >
541
- <MediaWidget
542
- simulateUserPrompt={simulateUserPrompt}
543
- links={topMediaWidgetLinks}
544
- media={topMediaWidgetMedia}
545
- sessionID={sessionID}
546
- baseUrl={baseUrl}
547
- apiUrl={apiUrl}
548
- translateTo={translateTo}
549
- customMediaRenderer={customMediaRenderer}
550
- fromUser={message.fromUser}
551
- />
538
+ {!message.fromUser && (
539
+ <MediaWidget
540
+ simulateUserPrompt={simulateUserPrompt}
541
+ links={topMediaWidgetLinks}
542
+ media={topMediaWidgetMedia}
543
+ sessionID={sessionID}
544
+ baseUrl={baseUrl}
545
+ apiUrl={apiUrl}
546
+ translateTo={translateTo}
547
+ customMediaRenderer={customMediaRenderer}
548
+ fromUser={message.fromUser}
549
+ />
550
+ )}
552
551
 
553
552
  <div className="memori-chat--bubble-message-row">
554
553
  {!message.fromUser && renderAssistantAvatar()}
555
554
 
556
- <div
557
- className={cx('memori-chat--bubble-shell', {
558
- 'memori-chat--bubble-shell--from-user': !!message.fromUser,
559
- })}
560
- >
561
- <div
562
- className={cx('memori-chat--bubble-anchor', {
563
- 'memori-chat--bubble-anchor--from-user': !!message.fromUser,
564
- 'memori-chat--bubble-anchor--has-addon': shouldShowBubbleAddon,
565
- })}
566
- >
555
+ {message.fromUser ? (
556
+ <div className="memori-chat--user-block">
557
+ {(topMediaWidgetMedia.length > 0 ||
558
+ topMediaWidgetLinks.length > 0) && (
559
+ <div className="memori-chat--attachment-strip">
560
+ <MediaWidget
561
+ simulateUserPrompt={simulateUserPrompt}
562
+ links={topMediaWidgetLinks}
563
+ media={topMediaWidgetMedia}
564
+ sessionID={sessionID}
565
+ baseUrl={baseUrl}
566
+ apiUrl={apiUrl}
567
+ translateTo={translateTo}
568
+ customMediaRenderer={customMediaRenderer}
569
+ fromUser={message.fromUser}
570
+ />
571
+ </div>
572
+ )}
573
+
567
574
  <div
568
- className={cx('memori-chat--bubble', {
569
- 'memori-chat--user-bubble': !!message.fromUser,
570
- 'memori-chat--with-addon':
571
- shouldShowCopyButtons ||
572
- (showFeedback && simulateUserPrompt),
573
- 'memori-chat--ai-generated': message.generatedByAI,
574
- 'memori-chat--with-feedback': showFeedback,
575
+ className={cx('memori-chat--bubble-shell', {
576
+ 'memori-chat--bubble-shell--from-user': true,
575
577
  })}
576
578
  >
577
- {message.fromUser ? (
578
- <Expandable
579
- className="memori-chat--bubble-content"
580
- mode="characters"
579
+ <div
580
+ className={cx('memori-chat--bubble-anchor', {
581
+ 'memori-chat--bubble-anchor--from-user': true,
582
+ 'memori-chat--bubble-anchor--has-addon':
583
+ shouldShowBubbleAddon,
584
+ })}
585
+ >
586
+ <div
587
+ className={cx('memori-chat--bubble', {
588
+ 'memori-chat--user-bubble': true,
589
+ 'memori-chat--with-addon':
590
+ shouldShowCopyButtons ||
591
+ (showFeedback && simulateUserPrompt),
592
+ 'memori-chat--ai-generated': message.generatedByAI,
593
+ 'memori-chat--with-feedback': showFeedback,
594
+ })}
581
595
  >
582
- <div
583
- dir="auto"
596
+ <Expandable
584
597
  className="memori-chat--bubble-content"
585
- dangerouslySetInnerHTML={{
586
- __html: sanitizeMsg(cleanText).replaceAll(
587
- '\n',
588
- '<br/>'
589
- ),
590
- }}
591
- />
592
- </Expandable>
593
- ) : (
594
- <div
595
- dir="auto"
596
- className="memori-chat--bubble-content"
597
- dangerouslySetInnerHTML={{ __html: renderedText }}
598
- />
599
- )}
598
+ mode="characters"
599
+ >
600
+ <div
601
+ dir="auto"
602
+ className="memori-chat--bubble-content"
603
+ dangerouslySetInnerHTML={{
604
+ __html: sanitizeMsg(cleanText).replaceAll(
605
+ '\n',
606
+ '<br/>'
607
+ ),
608
+ }}
609
+ />
610
+ </Expandable>
600
611
 
601
- {!!usageHtml && (
602
- <div
603
- className="memori-chat--usage-inside-bubble"
604
- dangerouslySetInnerHTML={{ __html: usageHtml }}
605
- />
606
- )}
607
- </div>
612
+ {!!usageHtml && (
613
+ <div
614
+ className="memori-chat--usage-inside-bubble"
615
+ dangerouslySetInnerHTML={{ __html: usageHtml }}
616
+ />
617
+ )}
618
+ </div>
608
619
 
609
- {shouldShowBubbleAddon && (
610
- <div className="memori-chat--bubble-addon">
611
- {shouldShowTimestampInAddon && (
612
- <div className="memori-chat--bubble-timestamp-container">
613
- <p className="memori-chat--bubble-timestamp">
614
- {formattedTimestamp}
615
- </p>
616
- {hasAddonAfterTimestamp && (
617
- <span className="memori-chat--bubble-timestamp-separator">
618
- •
619
- </span>
620
+ {shouldShowBubbleAddon && (
621
+ <div className="memori-chat--bubble-addon">
622
+ {shouldShowTimestampInAddon && (
623
+ <div className="memori-chat--bubble-timestamp-container">
624
+ <p className="memori-chat--bubble-timestamp">
625
+ {formattedTimestamp}
626
+ </p>
627
+ {hasAddonAfterTimestamp && (
628
+ <span className="memori-chat--bubble-timestamp-separator">
629
+ •
630
+ </span>
631
+ )}
632
+ </div>
620
633
  )}
621
- </div>
622
- )}
623
- {shouldShowCopyButtons && (
624
- <Tooltip
625
- {...bubbleAddonTooltipProps}
626
- placement="bottom"
627
- content={
628
- copyStatus.plain === 'success'
629
- ? copiedLabel
630
- : copyStatus.plain === 'error'
631
- ? t('copyFailed')
632
- : t('copy') || 'Copy'
633
- }
634
- >
635
- <span className="memori-chat--bubble-addon-tooltip-trigger">
636
- <Button
637
- variant="ghost"
638
- shape="circle"
639
- type="button"
640
- size="sm"
641
- aria-label={
634
+ {shouldShowCopyButtons && (
635
+ <Tooltip
636
+ {...bubbleAddonTooltipProps}
637
+ placement="bottom"
638
+ content={
642
639
  copyStatus.plain === 'success'
643
- ? String(copiedLabel)
640
+ ? copiedLabel
644
641
  : copyStatus.plain === 'error'
645
- ? String(t('copyFailed'))
646
- : String(t('copy') || 'Copy')
642
+ ? t('copyFailed')
643
+ : t('copy') || 'Copy'
647
644
  }
648
- className={cx(
649
- 'memori-chat--bubble-action-button',
650
- 'memori-share-button--copy-item',
651
- {
652
- 'memori-share-button--copy-item--success':
653
- copyStatus.plain === 'success',
654
- 'memori-share-button--copy-item--error':
655
- copyStatus.plain === 'error',
656
- }
657
- )}
658
- icon={
659
- copyStatus.plain === 'success' ? (
660
- <Check
661
- className="memori-share-button--copy-icon"
662
- aria-hidden
663
- strokeWidth={2.5}
664
- />
665
- ) : (
666
- <Copy
667
- className="memori-share-button--copy-icon"
668
- aria-hidden
669
- />
670
- )
671
- }
672
- onClick={() => handleCopyClick('plain', copyText)}
673
- />
674
- </span>
675
- </Tooltip>
676
- )}
645
+ >
646
+ <span className="memori-chat--bubble-addon-tooltip-trigger">
647
+ <Button
648
+ variant="ghost"
649
+ shape="circle"
650
+ type="button"
651
+ size="sm"
652
+ aria-label={
653
+ copyStatus.plain === 'success'
654
+ ? String(copiedLabel)
655
+ : copyStatus.plain === 'error'
656
+ ? String(t('copyFailed'))
657
+ : String(t('copy') || 'Copy')
658
+ }
659
+ className={cx(
660
+ 'memori-chat--bubble-action-button',
661
+ 'memori-share-button--copy-item',
662
+ {
663
+ 'memori-share-button--copy-item--success':
664
+ copyStatus.plain === 'success',
665
+ 'memori-share-button--copy-item--error':
666
+ copyStatus.plain === 'error',
667
+ }
668
+ )}
669
+ icon={
670
+ copyStatus.plain === 'success' ? (
671
+ <Check
672
+ className="memori-share-button--copy-icon"
673
+ aria-hidden
674
+ strokeWidth={2.5}
675
+ />
676
+ ) : (
677
+ <Copy
678
+ className="memori-share-button--copy-icon"
679
+ aria-hidden
680
+ />
681
+ )
682
+ }
683
+ onClick={() => handleCopyClick('plain', copyText)}
684
+ />
685
+ </span>
686
+ </Tooltip>
687
+ )}
677
688
 
678
- {shouldShowCopyRawButton && (
679
- <Tooltip
680
- {...bubbleAddonTooltipProps}
681
- placement="bottom"
682
- content={
683
- copyStatus.raw === 'success'
684
- ? copiedLabel
685
- : copyStatus.raw === 'error'
686
- ? t('copyFailed')
687
- : t('copyRawCode') || 'Copy raw code'
688
- }
689
- >
690
- <span className="memori-chat--bubble-addon-tooltip-trigger">
691
- <Button
692
- variant="ghost"
693
- shape="circle"
694
- type="button"
695
- size="sm"
696
- aria-label={
689
+ {shouldShowCopyRawButton && (
690
+ <Tooltip
691
+ {...bubbleAddonTooltipProps}
692
+ placement="bottom"
693
+ content={
697
694
  copyStatus.raw === 'success'
698
- ? String(copiedLabel)
695
+ ? copiedLabel
699
696
  : copyStatus.raw === 'error'
700
- ? String(t('copyFailed'))
701
- : String(t('copyRawCode') || 'Copy raw code')
697
+ ? t('copyFailed')
698
+ : t('copyRawCode') || 'Copy raw code'
702
699
  }
703
- className={cx(
704
- 'memori-chat--bubble-action-button',
705
- 'memori-share-button--copy-item',
706
- {
707
- 'memori-share-button--copy-item--success':
708
- copyStatus.raw === 'success',
709
- 'memori-share-button--copy-item--error':
710
- copyStatus.raw === 'error',
711
- }
712
- )}
713
- icon={
714
- copyStatus.raw === 'success' ? (
715
- <Check
716
- className="memori-share-button--copy-icon"
717
- aria-hidden
718
- strokeWidth={2.5}
719
- />
720
- ) : (
721
- <Code
722
- className="memori-share-button--copy-icon"
723
- aria-hidden
724
- />
725
- )
726
- }
727
- onClick={() => handleCopyClick('raw', rawMessageText)}
700
+ >
701
+ <span className="memori-chat--bubble-addon-tooltip-trigger">
702
+ <Button
703
+ variant="ghost"
704
+ shape="circle"
705
+ type="button"
706
+ size="sm"
707
+ aria-label={
708
+ copyStatus.raw === 'success'
709
+ ? String(copiedLabel)
710
+ : copyStatus.raw === 'error'
711
+ ? String(t('copyFailed'))
712
+ : String(t('copyRawCode') || 'Copy raw code')
713
+ }
714
+ className={cx(
715
+ 'memori-chat--bubble-action-button',
716
+ 'memori-share-button--copy-item',
717
+ {
718
+ 'memori-share-button--copy-item--success':
719
+ copyStatus.raw === 'success',
720
+ 'memori-share-button--copy-item--error':
721
+ copyStatus.raw === 'error',
722
+ }
723
+ )}
724
+ icon={
725
+ copyStatus.raw === 'success' ? (
726
+ <Check
727
+ className="memori-share-button--copy-icon"
728
+ aria-hidden
729
+ strokeWidth={2.5}
730
+ />
731
+ ) : (
732
+ <Code
733
+ className="memori-share-button--copy-icon"
734
+ aria-hidden
735
+ />
736
+ )
737
+ }
738
+ onClick={() =>
739
+ handleCopyClick('raw', rawMessageText)
740
+ }
741
+ />
742
+ </span>
743
+ </Tooltip>
744
+ )}
745
+
746
+ {showFeedback && !!simulateUserPrompt && (
747
+ <FeedbackButtons
748
+ memori={memori}
749
+ className="memori-chat--bubble-feedback"
750
+ dropdown
751
+ onNegativeClick={msg => {
752
+ if (msg) simulateUserPrompt(msg);
753
+ }}
728
754
  />
729
- </span>
730
- </Tooltip>
755
+ )}
756
+
757
+ {message.generatedByAI && showAIicon && (
758
+ <Tooltip
759
+ {...bubbleAddonTooltipProps}
760
+ placement="bottom"
761
+ content={t('generatedByAI')}
762
+ className="memori-chat--bubble-action-icon memori-chat--bubble-action-icon--ai"
763
+ >
764
+ <span
765
+ className="memori-chat--bubble-addon-tooltip-trigger memori-chat--bubble-ai-icon"
766
+ role="img"
767
+ aria-label={String(t('generatedByAI'))}
768
+ >
769
+ <Bot aria-hidden />
770
+ </span>
771
+ </Tooltip>
772
+ )}
773
+
774
+ {showTranslationOriginal &&
775
+ message.translatedText &&
776
+ message.translatedText !== message.text && (
777
+ <Tooltip
778
+ {...bubbleAddonTooltipProps}
779
+ placement="bottom"
780
+ content={`${
781
+ lang === 'it'
782
+ ? 'Testo originale'
783
+ : 'Original text'
784
+ }: ${stripAllInternalTags(message.text)}`}
785
+ className="memori-chat--bubble-action-icon memori-chat--bubble-action-icon--ai"
786
+ >
787
+ <span className="memori-chat--bubble-addon-tooltip-trigger">
788
+ <Button
789
+ variant="ghost"
790
+ shape="circle"
791
+ type="button"
792
+ size="sm"
793
+ className="memori-chat--bubble-action-button"
794
+ aria-label={
795
+ lang === 'it'
796
+ ? 'Testo originale'
797
+ : 'Original text'
798
+ }
799
+ icon={<Languages aria-hidden />}
800
+ />
801
+ </span>
802
+ </Tooltip>
803
+ )}
804
+ </div>
805
+ )}
806
+ </div>
807
+ </div>
808
+
809
+ {codeMediaWidgetMedia.length > 0 && (
810
+ <MediaWidget
811
+ simulateUserPrompt={simulateUserPrompt}
812
+ media={codeMediaWidgetMedia}
813
+ sessionID={sessionID}
814
+ baseUrl={baseUrl}
815
+ apiUrl={apiUrl}
816
+ translateTo={translateTo}
817
+ customMediaRenderer={customMediaRenderer}
818
+ fromUser={message.fromUser}
819
+ />
820
+ )}
821
+ </div>
822
+ ) : (
823
+ <div
824
+ className={cx('memori-chat--bubble-shell', {
825
+ 'memori-chat--bubble-shell--from-user': !!message.fromUser,
826
+ })}
827
+ >
828
+ <div
829
+ className={cx('memori-chat--bubble-anchor', {
830
+ 'memori-chat--bubble-anchor--from-user': !!message.fromUser,
831
+ 'memori-chat--bubble-anchor--has-addon': shouldShowBubbleAddon,
832
+ })}
833
+ >
834
+ <div
835
+ className={cx('memori-chat--bubble', {
836
+ 'memori-chat--user-bubble': !!message.fromUser,
837
+ 'memori-chat--with-addon':
838
+ shouldShowCopyButtons ||
839
+ (showFeedback && simulateUserPrompt),
840
+ 'memori-chat--ai-generated': message.generatedByAI,
841
+ 'memori-chat--with-feedback': showFeedback,
842
+ })}
843
+ >
844
+ <div
845
+ dir="auto"
846
+ className="memori-chat--bubble-content"
847
+ dangerouslySetInnerHTML={{ __html: renderedText }}
848
+ />
849
+
850
+ {!!usageHtml && (
851
+ <div
852
+ className="memori-chat--usage-inside-bubble"
853
+ dangerouslySetInnerHTML={{ __html: usageHtml }}
854
+ />
731
855
  )}
856
+ </div>
732
857
 
733
- {!message.fromUser &&
734
- showFunctionCache &&
735
- message.media?.some(
736
- m =>
737
- Boolean(m.properties?.functionCache) ||
738
- m.properties?.functionCache === 'true'
739
- ) && (
858
+ {shouldShowBubbleAddon && (
859
+ <div className="memori-chat--bubble-addon">
860
+ {shouldShowTimestampInAddon && (
861
+ <div className="memori-chat--bubble-timestamp-container">
862
+ <p className="memori-chat--bubble-timestamp">
863
+ {formattedTimestamp}
864
+ </p>
865
+ {hasAddonAfterTimestamp && (
866
+ <span className="memori-chat--bubble-timestamp-separator">
867
+ •
868
+ </span>
869
+ )}
870
+ </div>
871
+ )}
872
+ {shouldShowCopyButtons && (
740
873
  <Tooltip
741
874
  {...bubbleAddonTooltipProps}
742
875
  placement="bottom"
743
- content={t('functionCache') || 'Function cache'}
744
- className="memori-chat--bubble-action-icon memori-chat--bubble-action-icon--debug"
876
+ content={
877
+ copyStatus.plain === 'success'
878
+ ? copiedLabel
879
+ : copyStatus.plain === 'error'
880
+ ? t('copyFailed')
881
+ : t('copy') || 'Copy'
882
+ }
745
883
  >
746
884
  <span className="memori-chat--bubble-addon-tooltip-trigger">
747
885
  <Button
748
886
  variant="ghost"
749
887
  shape="circle"
888
+ type="button"
750
889
  size="sm"
751
- className="memori-chat--bubble-action-button"
890
+ aria-label={
891
+ copyStatus.plain === 'success'
892
+ ? String(copiedLabel)
893
+ : copyStatus.plain === 'error'
894
+ ? String(t('copyFailed'))
895
+ : String(t('copy') || 'Copy')
896
+ }
897
+ className={cx(
898
+ 'memori-chat--bubble-action-button',
899
+ 'memori-share-button--copy-item',
900
+ {
901
+ 'memori-share-button--copy-item--success':
902
+ copyStatus.plain === 'success',
903
+ 'memori-share-button--copy-item--error':
904
+ copyStatus.plain === 'error',
905
+ }
906
+ )}
752
907
  icon={
753
- <Bug
754
- aria-label={
755
- t('functionCache') || 'Function cache'
756
- }
757
- />
908
+ copyStatus.plain === 'success' ? (
909
+ <Check
910
+ className="memori-share-button--copy-icon"
911
+ aria-hidden
912
+ strokeWidth={2.5}
913
+ />
914
+ ) : (
915
+ <Copy
916
+ className="memori-share-button--copy-icon"
917
+ aria-hidden
918
+ />
919
+ )
758
920
  }
759
- onClick={() => setOpenFunctionCache(true)}
921
+ onClick={() => handleCopyClick('plain', copyText)}
760
922
  />
761
923
  </span>
762
924
  </Tooltip>
763
925
  )}
764
926
 
765
- {showFeedback && !!simulateUserPrompt && (
766
- <FeedbackButtons
767
- memori={memori}
768
- className="memori-chat--bubble-feedback"
769
- dropdown
770
- onNegativeClick={msg => {
771
- if (msg) simulateUserPrompt(msg);
772
- }}
773
- />
774
- )}
775
-
776
- {message.generatedByAI && showAIicon && (
777
- <Tooltip
778
- {...bubbleAddonTooltipProps}
779
- placement="bottom"
780
- content={t('generatedByAI')}
781
- className="memori-chat--bubble-action-icon memori-chat--bubble-action-icon--ai"
782
- >
783
- <span
784
- className="memori-chat--bubble-addon-tooltip-trigger memori-chat--bubble-ai-icon"
785
- role="img"
786
- aria-label={String(t('generatedByAI'))}
787
- >
788
- <Bot aria-hidden />
789
- </span>
790
- </Tooltip>
791
- )}
792
-
793
- {showTranslationOriginal &&
794
- message.translatedText &&
795
- message.translatedText !== message.text && (
927
+ {shouldShowCopyRawButton && (
796
928
  <Tooltip
797
929
  {...bubbleAddonTooltipProps}
798
930
  placement="bottom"
799
- content={`${
800
- lang === 'it' ? 'Testo originale' : 'Original text'
801
- }: ${stripAllInternalTags(message.text)}`}
802
- className="memori-chat--bubble-action-icon memori-chat--bubble-action-icon--ai"
931
+ content={
932
+ copyStatus.raw === 'success'
933
+ ? copiedLabel
934
+ : copyStatus.raw === 'error'
935
+ ? t('copyFailed')
936
+ : t('copyRawCode') || 'Copy raw code'
937
+ }
803
938
  >
804
939
  <span className="memori-chat--bubble-addon-tooltip-trigger">
805
940
  <Button
@@ -807,71 +942,188 @@ const ChatBubble: React.FC<Props> = ({
807
942
  shape="circle"
808
943
  type="button"
809
944
  size="sm"
810
- className="memori-chat--bubble-action-button"
811
945
  aria-label={
812
- lang === 'it'
813
- ? 'Testo originale'
814
- : 'Original text'
946
+ copyStatus.raw === 'success'
947
+ ? String(copiedLabel)
948
+ : copyStatus.raw === 'error'
949
+ ? String(t('copyFailed'))
950
+ : String(t('copyRawCode') || 'Copy raw code')
951
+ }
952
+ className={cx(
953
+ 'memori-chat--bubble-action-button',
954
+ 'memori-share-button--copy-item',
955
+ {
956
+ 'memori-share-button--copy-item--success':
957
+ copyStatus.raw === 'success',
958
+ 'memori-share-button--copy-item--error':
959
+ copyStatus.raw === 'error',
960
+ }
961
+ )}
962
+ icon={
963
+ copyStatus.raw === 'success' ? (
964
+ <Check
965
+ className="memori-share-button--copy-icon"
966
+ aria-hidden
967
+ strokeWidth={2.5}
968
+ />
969
+ ) : (
970
+ <Code
971
+ className="memori-share-button--copy-icon"
972
+ aria-hidden
973
+ />
974
+ )
975
+ }
976
+ onClick={() =>
977
+ handleCopyClick('raw', rawMessageText)
815
978
  }
816
- icon={<Languages aria-hidden />}
817
979
  />
818
980
  </span>
819
981
  </Tooltip>
820
982
  )}
821
983
 
822
- {!message.fromUser &&
823
- message.questionAnswered &&
824
- apiUrl &&
825
- showWhyThisAnswer && (
984
+ {!message.fromUser &&
985
+ showFunctionCache &&
986
+ message.media?.some(
987
+ m =>
988
+ Boolean(m.properties?.functionCache) ||
989
+ m.properties?.functionCache === 'true'
990
+ ) && (
991
+ <Tooltip
992
+ {...bubbleAddonTooltipProps}
993
+ placement="bottom"
994
+ content={t('functionCache') || 'Function cache'}
995
+ className="memori-chat--bubble-action-icon memori-chat--bubble-action-icon--debug"
996
+ >
997
+ <span className="memori-chat--bubble-addon-tooltip-trigger">
998
+ <Button
999
+ variant="ghost"
1000
+ shape="circle"
1001
+ size="sm"
1002
+ className="memori-chat--bubble-action-button"
1003
+ icon={
1004
+ <Bug
1005
+ aria-label={
1006
+ t('functionCache') || 'Function cache'
1007
+ }
1008
+ />
1009
+ }
1010
+ onClick={() => setOpenFunctionCache(true)}
1011
+ />
1012
+ </span>
1013
+ </Tooltip>
1014
+ )}
1015
+
1016
+ {showFeedback && !!simulateUserPrompt && (
1017
+ <FeedbackButtons
1018
+ memori={memori}
1019
+ className="memori-chat--bubble-feedback"
1020
+ dropdown
1021
+ onNegativeClick={msg => {
1022
+ if (msg) simulateUserPrompt(msg);
1023
+ }}
1024
+ />
1025
+ )}
1026
+
1027
+ {message.generatedByAI && showAIicon && (
826
1028
  <Tooltip
827
1029
  {...bubbleAddonTooltipProps}
828
1030
  placement="bottom"
829
- content={t('whyThisAnswer') || 'Why this answer?'}
1031
+ content={t('generatedByAI')}
1032
+ className="memori-chat--bubble-action-icon memori-chat--bubble-action-icon--ai"
830
1033
  >
831
- <span className="memori-chat--bubble-addon-tooltip-trigger">
832
- <Button
833
- variant="ghost"
834
- shape="circle"
835
- size="sm"
836
- className="memori-chat--bubble-action-button"
837
- onClick={() => setShowingWhyThisAnswer(true)}
838
- disabled={showingWhyThisAnswer}
839
- aria-label={
840
- t('whyThisAnswer') || 'Why this answer?'
841
- }
842
- icon={<HelpCircle aria-hidden />}
843
- />
1034
+ <span
1035
+ className="memori-chat--bubble-addon-tooltip-trigger memori-chat--bubble-ai-icon"
1036
+ role="img"
1037
+ aria-label={String(t('generatedByAI'))}
1038
+ >
1039
+ <Bot aria-hidden />
844
1040
  </span>
845
1041
  </Tooltip>
846
1042
  )}
1043
+
1044
+ {showTranslationOriginal &&
1045
+ message.translatedText &&
1046
+ message.translatedText !== message.text && (
1047
+ <Tooltip
1048
+ {...bubbleAddonTooltipProps}
1049
+ placement="bottom"
1050
+ content={`${
1051
+ lang === 'it' ? 'Testo originale' : 'Original text'
1052
+ }: ${stripAllInternalTags(message.text)}`}
1053
+ className="memori-chat--bubble-action-icon memori-chat--bubble-action-icon--ai"
1054
+ >
1055
+ <span className="memori-chat--bubble-addon-tooltip-trigger">
1056
+ <Button
1057
+ variant="ghost"
1058
+ shape="circle"
1059
+ type="button"
1060
+ size="sm"
1061
+ className="memori-chat--bubble-action-button"
1062
+ aria-label={
1063
+ lang === 'it'
1064
+ ? 'Testo originale'
1065
+ : 'Original text'
1066
+ }
1067
+ icon={<Languages aria-hidden />}
1068
+ />
1069
+ </span>
1070
+ </Tooltip>
1071
+ )}
1072
+
1073
+ {!message.fromUser &&
1074
+ message.questionAnswered &&
1075
+ apiUrl &&
1076
+ showWhyThisAnswer && (
1077
+ <Tooltip
1078
+ {...bubbleAddonTooltipProps}
1079
+ placement="bottom"
1080
+ content={t('whyThisAnswer') || 'Why this answer?'}
1081
+ >
1082
+ <span className="memori-chat--bubble-addon-tooltip-trigger">
1083
+ <Button
1084
+ variant="ghost"
1085
+ shape="circle"
1086
+ size="sm"
1087
+ className="memori-chat--bubble-action-button"
1088
+ onClick={() => setShowingWhyThisAnswer(true)}
1089
+ disabled={showingWhyThisAnswer}
1090
+ aria-label={
1091
+ t('whyThisAnswer') || 'Why this answer?'
1092
+ }
1093
+ icon={<HelpCircle aria-hidden />}
1094
+ />
1095
+ </span>
1096
+ </Tooltip>
1097
+ )}
1098
+ </div>
1099
+ )}
1100
+ </div>
1101
+
1102
+ {!message.fromUser && (
1103
+ <div
1104
+ className={cx('memori-chat--artifact-block', {
1105
+ 'memori-chat--artifact-block--chatlog': isChatlogPanel,
1106
+ })}
1107
+ >
1108
+ <ArtifactHandler
1109
+ isChatlogPanel={isChatlogPanel}
1110
+ message={message}
1111
+ />
847
1112
  </div>
848
1113
  )}
849
- </div>
850
1114
 
851
- {!message.fromUser && (
852
- <div
853
- className={cx('memori-chat--artifact-block', {
854
- 'memori-chat--artifact-block--chatlog': isChatlogPanel,
855
- })}
856
- >
857
- <ArtifactHandler
858
- isChatlogPanel={isChatlogPanel}
859
- message={message}
860
- />
861
- </div>
862
- )}
863
-
864
- <MediaWidget
865
- simulateUserPrompt={simulateUserPrompt}
866
- media={codeMediaWidgetMedia}
867
- sessionID={sessionID}
868
- baseUrl={baseUrl}
869
- apiUrl={apiUrl}
870
- translateTo={translateTo}
871
- customMediaRenderer={customMediaRenderer}
872
- fromUser={message.fromUser}
873
- />
874
- </div>
1115
+ <MediaWidget
1116
+ simulateUserPrompt={simulateUserPrompt}
1117
+ media={codeMediaWidgetMedia}
1118
+ sessionID={sessionID}
1119
+ baseUrl={baseUrl}
1120
+ apiUrl={apiUrl}
1121
+ translateTo={translateTo}
1122
+ customMediaRenderer={customMediaRenderer}
1123
+ fromUser={message.fromUser}
1124
+ />
1125
+ </div>
1126
+ )}
875
1127
 
876
1128
  {message.fromUser && renderUserAvatar()}
877
1129
  </div>
@@ -890,7 +1142,6 @@ const ChatBubble: React.FC<Props> = ({
890
1142
  )}
891
1143
 
892
1144
  <Modal
893
- container={surfaceEl ?? undefined}
894
1145
  open={openFunctionCache}
895
1146
  className="memori-chat--function-cache-modal"
896
1147
  stacking="stacked"