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

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 (56) hide show
  1. package/CHANGELOG.md +435 -0
  2. package/dist/components/ChatBubble/ChatBubble.js +12 -7
  3. package/dist/components/ChatBubble/ChatBubble.js.map +1 -1
  4. package/dist/components/FeedbackButtons/FeedbackButtons.js +2 -2
  5. package/dist/components/FeedbackButtons/FeedbackButtons.js.map +1 -1
  6. package/dist/components/MemoriWidget/MemoriWidget.d.ts +1 -0
  7. package/dist/components/MemoriWidget/MemoriWidget.js +58 -1
  8. package/dist/components/MemoriWidget/MemoriWidget.js.map +1 -1
  9. package/dist/components/layouts/chat.css +5 -2
  10. package/dist/helpers/nats/getNatsConfig.js.map +1 -1
  11. package/dist/helpers/nats/useNats.d.ts +2 -1
  12. package/dist/helpers/nats/useNats.js +87 -20
  13. package/dist/helpers/nats/useNats.js.map +1 -1
  14. package/dist/helpers/nats/useNatsSession.d.ts +6 -1
  15. package/dist/helpers/nats/useNatsSession.js +48 -7
  16. package/dist/helpers/nats/useNatsSession.js.map +1 -1
  17. package/dist/styles.css +1 -1
  18. package/dist/version.d.ts +1 -1
  19. package/dist/version.js +1 -1
  20. package/esm/components/ChatBubble/ChatBubble.js +12 -7
  21. package/esm/components/ChatBubble/ChatBubble.js.map +1 -1
  22. package/esm/components/FeedbackButtons/FeedbackButtons.js +2 -2
  23. package/esm/components/FeedbackButtons/FeedbackButtons.js.map +1 -1
  24. package/esm/components/MemoriWidget/MemoriWidget.d.ts +1 -0
  25. package/esm/components/MemoriWidget/MemoriWidget.js +57 -1
  26. package/esm/components/MemoriWidget/MemoriWidget.js.map +1 -1
  27. package/esm/components/layouts/chat.css +5 -2
  28. package/esm/helpers/nats/getNatsConfig.js.map +1 -1
  29. package/esm/helpers/nats/useNats.d.ts +2 -1
  30. package/esm/helpers/nats/useNats.js +87 -20
  31. package/esm/helpers/nats/useNats.js.map +1 -1
  32. package/esm/helpers/nats/useNatsSession.d.ts +6 -1
  33. package/esm/helpers/nats/useNatsSession.js +48 -8
  34. package/esm/helpers/nats/useNatsSession.js.map +1 -1
  35. package/esm/styles.css +1 -1
  36. package/esm/version.d.ts +1 -1
  37. package/esm/version.js +1 -1
  38. package/package.json +4 -3
  39. package/src/components/Chat/__snapshots__/Chat.test.tsx.snap +71 -71
  40. package/src/components/ChatBubble/ChatBubble.stories.tsx +11 -0
  41. package/src/components/ChatBubble/ChatBubble.test.tsx +16 -0
  42. package/src/components/ChatBubble/ChatBubble.tsx +307 -292
  43. package/src/components/ChatBubble/__snapshots__/ChatBubble.test.tsx.snap +268 -121
  44. package/src/components/FeedbackButtons/FeedbackButtons.tsx +2 -0
  45. package/src/components/FeedbackButtons/__snapshots__/FeedbackButtons.test.tsx.snap +1 -1
  46. package/src/components/KnownFacts/__snapshots__/KnownFacts.test.tsx.snap +6 -2
  47. package/src/components/LoginDrawer/__snapshots__/LoginDrawer.test.tsx.snap +33 -11
  48. package/src/components/MemoriWidget/MemoriWidget.tsx +65 -1
  49. package/src/components/WhyThisAnswer/__snapshots__/WhyThisAnswer.test.tsx.snap +9 -3
  50. package/src/components/layouts/chat.css +5 -2
  51. package/src/helpers/nats/getNatsConfig.ts +4 -1
  52. package/src/helpers/nats/useNats.test.tsx +81 -0
  53. package/src/helpers/nats/useNats.ts +109 -29
  54. package/src/helpers/nats/useNatsSession.test.ts +16 -0
  55. package/src/helpers/nats/useNatsSession.ts +79 -13
  56. package/src/version.ts +1 -1
@@ -496,19 +496,17 @@ const ChatBubble: React.FC<Props> = ({
496
496
  ) || []),
497
497
  ...parseDocumentAttachmentsFromMessage(
498
498
  message.translatedText || message.text
499
- ).map(
500
- (attachment, attachmentIndex): Medium & { type?: string } => ({
501
- mediumID: `doc_${Date.now()}_${attachmentIndex}_${Math.random()
502
- .toString(36)
503
- .substr(2, 9)}`,
504
- url: attachment.url,
505
- mimeType: attachment.type,
506
- title: attachment.filename,
507
- content: attachment.content,
508
- properties: { isDocumentAttachment: true },
509
- type: 'document',
510
- })
511
- ),
499
+ ).map((attachment, attachmentIndex): Medium & { type?: string } => ({
500
+ mediumID: `doc_${Date.now()}_${attachmentIndex}_${Math.random()
501
+ .toString(36)
502
+ .substr(2, 9)}`,
503
+ url: attachment.url,
504
+ mimeType: attachment.type,
505
+ title: attachment.filename,
506
+ content: attachment.content,
507
+ properties: { isDocumentAttachment: true },
508
+ type: 'document',
509
+ })),
512
510
  ];
513
511
 
514
512
  const codeMediaWidgetMedia =
@@ -560,302 +558,319 @@ const ChatBubble: React.FC<Props> = ({
560
558
  'memori-chat--bubble-shell--from-user': !!message.fromUser,
561
559
  })}
562
560
  >
563
- <div
564
- className={cx('memori-chat--bubble-anchor', {
565
- 'memori-chat--bubble-anchor--from-user': !!message.fromUser,
566
- 'memori-chat--bubble-anchor--has-addon': shouldShowBubbleAddon,
567
- })}
568
- >
569
- <div
570
- className={cx('memori-chat--bubble', {
571
- 'memori-chat--user-bubble': !!message.fromUser,
572
- 'memori-chat--with-addon':
573
- shouldShowCopyButtons || (showFeedback && simulateUserPrompt),
574
- 'memori-chat--ai-generated': message.generatedByAI,
575
- 'memori-chat--with-feedback': showFeedback,
576
- })}
577
- >
578
- {message.fromUser ? (
579
- <Expandable
580
- className="memori-chat--bubble-content"
581
- mode="characters"
582
- >
583
- <div
584
- dir="auto"
585
- className="memori-chat--bubble-content"
586
- dangerouslySetInnerHTML={{ __html: sanitizeMsg(cleanText) }}
587
- />
588
- </Expandable>
589
- ) : (
590
- <div
591
- dir="auto"
592
- className="memori-chat--bubble-content"
593
- dangerouslySetInnerHTML={{ __html: renderedText }}
594
- />
595
- )}
596
-
597
- {!!usageHtml && (
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
+ >
598
567
  <div
599
- className="memori-chat--usage-inside-bubble"
600
- dangerouslySetInnerHTML={{ __html: usageHtml }}
601
- />
602
- )}
603
- </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
+ })}
576
+ >
577
+ {message.fromUser ? (
578
+ <Expandable
579
+ className="memori-chat--bubble-content"
580
+ mode="characters"
581
+ >
582
+ <div
583
+ dir="auto"
584
+ 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
+ )}
604
600
 
605
- {shouldShowBubbleAddon && (
606
- <div className="memori-chat--bubble-addon">
607
- {shouldShowTimestampInAddon && (
608
- <div className="memori-chat--bubble-timestamp-container">
609
- <p className="memori-chat--bubble-timestamp">
610
- {formattedTimestamp}
611
- </p>
612
- {hasAddonAfterTimestamp && (
613
- <span className="memori-chat--bubble-timestamp-separator">
614
- •
615
- </span>
601
+ {!!usageHtml && (
602
+ <div
603
+ className="memori-chat--usage-inside-bubble"
604
+ dangerouslySetInnerHTML={{ __html: usageHtml }}
605
+ />
606
+ )}
607
+ </div>
608
+
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
+ )}
621
+ </div>
616
622
  )}
617
- </div>
618
- )}
619
- {shouldShowCopyButtons && (
620
- <Tooltip
621
- {...bubbleAddonTooltipProps}
622
- placement="bottom"
623
- content={
624
- copyStatus.plain === 'success'
625
- ? copiedLabel
626
- : copyStatus.plain === 'error'
627
- ? t('copyFailed')
628
- : t('copy') || 'Copy'
629
- }
630
- >
631
- <span className="memori-chat--bubble-addon-tooltip-trigger">
632
- <Button
633
- variant="ghost"
634
- shape="circle"
635
- type="button"
636
- aria-label={
623
+ {shouldShowCopyButtons && (
624
+ <Tooltip
625
+ {...bubbleAddonTooltipProps}
626
+ placement="bottom"
627
+ content={
637
628
  copyStatus.plain === 'success'
638
- ? String(copiedLabel)
629
+ ? copiedLabel
639
630
  : copyStatus.plain === 'error'
640
- ? String(t('copyFailed'))
641
- : String(t('copy') || 'Copy')
631
+ ? t('copyFailed')
632
+ : t('copy') || 'Copy'
642
633
  }
643
- className={cx(
644
- 'memori-chat--bubble-action-button',
645
- 'memori-share-button--copy-item',
646
- {
647
- 'memori-share-button--copy-item--success':
648
- copyStatus.plain === 'success',
649
- 'memori-share-button--copy-item--error':
650
- copyStatus.plain === 'error',
651
- }
652
- )}
653
- icon={
654
- copyStatus.plain === 'success' ? (
655
- <Check
656
- className="memori-share-button--copy-icon"
657
- aria-hidden
658
- strokeWidth={2.5}
659
- />
660
- ) : (
661
- <Copy
662
- className="memori-share-button--copy-icon"
663
- aria-hidden
664
- />
665
- )
666
- }
667
- onClick={() => handleCopyClick('plain', copyText)}
668
- />
669
- </span>
670
- </Tooltip>
671
- )}
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={
642
+ copyStatus.plain === 'success'
643
+ ? String(copiedLabel)
644
+ : copyStatus.plain === 'error'
645
+ ? String(t('copyFailed'))
646
+ : String(t('copy') || 'Copy')
647
+ }
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
+ )}
672
677
 
673
- {shouldShowCopyRawButton && (
674
- <Tooltip
675
- {...bubbleAddonTooltipProps}
676
- placement="bottom"
677
- content={
678
- copyStatus.raw === 'success'
679
- ? copiedLabel
680
- : copyStatus.raw === 'error'
681
- ? t('copyFailed')
682
- : t('copyRawCode') || 'Copy raw code'
683
- }
684
- >
685
- <span className="memori-chat--bubble-addon-tooltip-trigger">
686
- <Button
687
- variant="ghost"
688
- shape="circle"
689
- type="button"
690
- aria-label={
678
+ {shouldShowCopyRawButton && (
679
+ <Tooltip
680
+ {...bubbleAddonTooltipProps}
681
+ placement="bottom"
682
+ content={
691
683
  copyStatus.raw === 'success'
692
- ? String(copiedLabel)
684
+ ? copiedLabel
693
685
  : copyStatus.raw === 'error'
694
- ? String(t('copyFailed'))
695
- : String(t('copyRawCode') || 'Copy raw code')
696
- }
697
- className={cx(
698
- 'memori-chat--bubble-action-button',
699
- 'memori-share-button--copy-item',
700
- {
701
- 'memori-share-button--copy-item--success':
702
- copyStatus.raw === 'success',
703
- 'memori-share-button--copy-item--error':
704
- copyStatus.raw === 'error',
705
- }
706
- )}
707
- icon={
708
- copyStatus.raw === 'success' ? (
709
- <Check
710
- className="memori-share-button--copy-icon"
711
- aria-hidden
712
- strokeWidth={2.5}
713
- />
714
- ) : (
715
- <Code
716
- className="memori-share-button--copy-icon"
717
- aria-hidden
718
- />
719
- )
686
+ ? t('copyFailed')
687
+ : t('copyRawCode') || 'Copy raw code'
720
688
  }
721
- onClick={() => handleCopyClick('raw', rawMessageText)}
722
- />
723
- </span>
724
- </Tooltip>
725
- )}
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={
697
+ copyStatus.raw === 'success'
698
+ ? String(copiedLabel)
699
+ : copyStatus.raw === 'error'
700
+ ? String(t('copyFailed'))
701
+ : String(t('copyRawCode') || 'Copy raw code')
702
+ }
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)}
728
+ />
729
+ </span>
730
+ </Tooltip>
731
+ )}
726
732
 
727
- {!message.fromUser &&
728
- showFunctionCache &&
729
- message.media?.some(
730
- m =>
731
- Boolean(m.properties?.functionCache) ||
732
- m.properties?.functionCache === 'true'
733
- ) && (
734
- <Tooltip
735
- {...bubbleAddonTooltipProps}
736
- placement="bottom"
737
- content={t('functionCache') || 'Function cache'}
738
- className="memori-chat--bubble-action-icon memori-chat--bubble-action-icon--debug"
739
- >
740
- <span className="memori-chat--bubble-addon-tooltip-trigger">
741
- <Button
742
- variant="ghost"
743
- shape="circle"
744
- className="memori-chat--bubble-action-button"
745
- icon={
746
- <Bug
747
- aria-label={t('functionCache') || 'Function cache'}
733
+ {!message.fromUser &&
734
+ showFunctionCache &&
735
+ message.media?.some(
736
+ m =>
737
+ Boolean(m.properties?.functionCache) ||
738
+ m.properties?.functionCache === 'true'
739
+ ) && (
740
+ <Tooltip
741
+ {...bubbleAddonTooltipProps}
742
+ placement="bottom"
743
+ content={t('functionCache') || 'Function cache'}
744
+ className="memori-chat--bubble-action-icon memori-chat--bubble-action-icon--debug"
745
+ >
746
+ <span className="memori-chat--bubble-addon-tooltip-trigger">
747
+ <Button
748
+ variant="ghost"
749
+ shape="circle"
750
+ size="sm"
751
+ className="memori-chat--bubble-action-button"
752
+ icon={
753
+ <Bug
754
+ aria-label={
755
+ t('functionCache') || 'Function cache'
756
+ }
757
+ />
758
+ }
759
+ onClick={() => setOpenFunctionCache(true)}
748
760
  />
749
- }
750
- onClick={() => setOpenFunctionCache(true)}
751
- />
752
- </span>
753
- </Tooltip>
754
- )}
755
-
756
- {showFeedback && !!simulateUserPrompt && (
757
- <FeedbackButtons
758
- memori={memori}
759
- className="memori-chat--bubble-feedback"
760
- dropdown
761
- onNegativeClick={msg => {
762
- if (msg) simulateUserPrompt(msg);
763
- }}
764
- />
765
- )}
761
+ </span>
762
+ </Tooltip>
763
+ )}
764
+
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
+ )}
766
775
 
767
- {message.generatedByAI && showAIicon && (
768
- <Tooltip
769
- {...bubbleAddonTooltipProps}
770
- placement="bottom"
771
- content={t('generatedByAI')}
772
- className="memori-chat--bubble-action-icon memori-chat--bubble-action-icon--ai"
773
- >
774
- <span
775
- className="memori-chat--bubble-addon-tooltip-trigger memori-chat--bubble-ai-icon"
776
- role="img"
777
- aria-label={String(t('generatedByAI'))}
778
- >
779
- <Bot aria-hidden />
780
- </span>
781
- </Tooltip>
782
- )}
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
+ )}
783
792
 
784
- {showTranslationOriginal &&
785
- message.translatedText &&
786
- message.translatedText !== message.text && (
787
- <Tooltip
788
- {...bubbleAddonTooltipProps}
789
- placement="bottom"
790
- content={`${
791
- lang === 'it' ? 'Testo originale' : 'Original text'
792
- }: ${stripAllInternalTags(message.text)}`}
793
- className="memori-chat--bubble-action-icon memori-chat--bubble-action-icon--ai"
794
- >
795
- <span className="memori-chat--bubble-addon-tooltip-trigger">
796
- <Button
797
- variant="ghost"
798
- shape="circle"
799
- type="button"
800
- className="memori-chat--bubble-action-button"
801
- aria-label={
793
+ {showTranslationOriginal &&
794
+ message.translatedText &&
795
+ message.translatedText !== message.text && (
796
+ <Tooltip
797
+ {...bubbleAddonTooltipProps}
798
+ placement="bottom"
799
+ content={`${
802
800
  lang === 'it' ? 'Testo originale' : 'Original text'
803
- }
804
- icon={<Languages aria-hidden />}
805
- />
806
- </span>
807
- </Tooltip>
808
- )}
809
-
810
- {!message.fromUser &&
811
- message.questionAnswered &&
812
- apiUrl &&
813
- showWhyThisAnswer && (
814
- <Tooltip
815
- {...bubbleAddonTooltipProps}
816
- placement="bottom"
817
- content={t('whyThisAnswer') || 'Why this answer?'}
818
- >
819
- <span className="memori-chat--bubble-addon-tooltip-trigger">
820
- <Button
821
- variant="ghost"
822
- shape="circle"
823
- className="memori-chat--bubble-action-button"
824
- onClick={() => setShowingWhyThisAnswer(true)}
825
- disabled={showingWhyThisAnswer}
826
- aria-label={t('whyThisAnswer') || 'Why this answer?'}
827
- icon={<HelpCircle aria-hidden />}
828
- />
829
- </span>
830
- </Tooltip>
831
- )}
801
+ }: ${stripAllInternalTags(message.text)}`}
802
+ className="memori-chat--bubble-action-icon memori-chat--bubble-action-icon--ai"
803
+ >
804
+ <span className="memori-chat--bubble-addon-tooltip-trigger">
805
+ <Button
806
+ variant="ghost"
807
+ shape="circle"
808
+ type="button"
809
+ size="sm"
810
+ className="memori-chat--bubble-action-button"
811
+ aria-label={
812
+ lang === 'it'
813
+ ? 'Testo originale'
814
+ : 'Original text'
815
+ }
816
+ icon={<Languages aria-hidden />}
817
+ />
818
+ </span>
819
+ </Tooltip>
820
+ )}
821
+
822
+ {!message.fromUser &&
823
+ message.questionAnswered &&
824
+ apiUrl &&
825
+ showWhyThisAnswer && (
826
+ <Tooltip
827
+ {...bubbleAddonTooltipProps}
828
+ placement="bottom"
829
+ content={t('whyThisAnswer') || 'Why this answer?'}
830
+ >
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
+ />
844
+ </span>
845
+ </Tooltip>
846
+ )}
847
+ </div>
848
+ )}
832
849
  </div>
833
- )}
834
- </div>
835
850
 
836
- {!message.fromUser && (
837
- <div
838
- className={cx('memori-chat--artifact-block', {
839
- 'memori-chat--artifact-block--chatlog': isChatlogPanel,
840
- })}
841
- >
842
- <ArtifactHandler
843
- isChatlogPanel={isChatlogPanel}
844
- message={message}
845
- />
846
- </div>
847
- )}
848
-
849
- <MediaWidget
850
- simulateUserPrompt={simulateUserPrompt}
851
- media={codeMediaWidgetMedia}
852
- sessionID={sessionID}
853
- baseUrl={baseUrl}
854
- apiUrl={apiUrl}
855
- translateTo={translateTo}
856
- customMediaRenderer={customMediaRenderer}
857
- fromUser={message.fromUser}
858
- />
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
+ />
859
874
  </div>
860
875
 
861
876
  {message.fromUser && renderUserAvatar()}