@memori.ai/memori-react 2.10.1 → 2.10.2

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.
@@ -270,10 +270,12 @@ const MemoriWidget = ({
270
270
  const [clickedStart, setClickedStart] = useState(false);
271
271
  const [gotErrorInOpening, setGotErrorInOpening] = useState(false);
272
272
 
273
- const language = memoriConfigs
274
- ?.find(c => c.memoriConfigID === memori.memoriConfigurationID)
275
- ?.culture?.split('-')?.[0]
276
- ?.toUpperCase();
273
+ const language =
274
+ memori.culture?.split('-')?.[0]?.toUpperCase()! ||
275
+ memoriConfigs
276
+ ?.find(c => c.memoriConfigID === memori.memoriConfigurationID)
277
+ ?.culture?.split('-')?.[0]
278
+ ?.toUpperCase()!;
277
279
  const integrationConfig = integration?.customData
278
280
  ? JSON.parse(integration.customData)
279
281
  : null;
@@ -284,7 +286,6 @@ const MemoriWidget = ({
284
286
  const [userLang, setUserLang] = useState(
285
287
  memoriLang ??
286
288
  integrationConfig?.lang ??
287
- memori?.culture?.split('-')?.[0] ??
288
289
  language ??
289
290
  integrationConfig?.uiLang ??
290
291
  i18n.language ??
@@ -383,6 +384,264 @@ const MemoriWidget = ({
383
384
  applyPosition(venue);
384
385
  };
385
386
 
387
+ /**
388
+ * History e gestione invio messaggi
389
+ */
390
+ const [userMessage, setUserMessage] = useState<string>('');
391
+ const onChangeUserMessage = (value: string) => {
392
+ if (!value || value === '\n' || value.trim() === '') {
393
+ setUserMessage('');
394
+ resetInteractionTimeout();
395
+ return;
396
+ }
397
+ setUserMessage(value);
398
+ clearInteractionTimeout();
399
+ };
400
+ const [listening, setListening] = useState(false);
401
+ const [history, setHistory] = useState<Message[]>([]);
402
+ const pushMessage = (message: Message) => {
403
+ setHistory(history => [...history, { ...message }]);
404
+ };
405
+ const sendMessage = async (
406
+ text: string,
407
+ media?: Medium[],
408
+ newSessionId?: string,
409
+ translate: boolean = true,
410
+ translatedText?: string,
411
+ hidden: boolean = false
412
+ ) => {
413
+ const sessionID =
414
+ newSessionId ||
415
+ sessionId ||
416
+ (window.getMemoriState() as MemoriSession)?.sessionID;
417
+ if (!sessionID || !text?.length) return;
418
+
419
+ if (!hidden)
420
+ pushMessage({
421
+ text: text,
422
+ translatedText,
423
+ fromUser: true,
424
+ media: media ?? [],
425
+ initial: sessionId
426
+ ? !!newSessionId && newSessionId !== sessionId
427
+ : !!newSessionId,
428
+ });
429
+
430
+ setMemoriTyping(true);
431
+
432
+ let msg = text;
433
+
434
+ if (
435
+ translate &&
436
+ !instruct &&
437
+ isMultilanguageEnabled &&
438
+ userLang.toUpperCase() !== language.toUpperCase()
439
+ ) {
440
+ const translation = await getTranslation(
441
+ text,
442
+ language,
443
+ userLang,
444
+ baseUrl
445
+ );
446
+ msg = translation.text;
447
+ }
448
+
449
+ const { currentState, ...response } = await postTextEnteredEvent({
450
+ sessionId: sessionID,
451
+ text: msg,
452
+ });
453
+ if (response.resultCode === 0 && currentState) {
454
+ const emission = currentState.emission ?? currentDialogState?.emission;
455
+ if (currentState.state === 'X4' && memori.giverTag) {
456
+ const { currentState, ...resp } = await postTagChangedEvent(
457
+ sessionID,
458
+ memori.giverTag
459
+ );
460
+
461
+ if (resp.resultCode === 0) {
462
+ setCurrentDialogState(currentState);
463
+
464
+ if (currentState.emission) {
465
+ pushMessage({
466
+ text: currentState.emission,
467
+ media: currentState.media,
468
+ fromUser: false,
469
+ });
470
+ speak(currentState.emission);
471
+ }
472
+ } else {
473
+ console.error(response, resp);
474
+ message.error(t(getErrori18nKey(resp.resultCode)));
475
+ }
476
+ } else if (currentState.state === 'X2d' && memori.giverTag) {
477
+ const { currentState, ...resp } = await postTextEnteredEvent({
478
+ sessionId: sessionID,
479
+ text: Math.random().toString().substring(2, 8),
480
+ });
481
+
482
+ if (resp.resultCode === 0) {
483
+ const { currentState, ...resp } = await postTagChangedEvent(
484
+ sessionID,
485
+ memori.giverTag
486
+ );
487
+
488
+ if (resp.resultCode === 0) {
489
+ setCurrentDialogState(currentState);
490
+
491
+ if (currentState.emission) {
492
+ pushMessage({
493
+ text: currentState.emission,
494
+ media: currentState.media,
495
+ fromUser: false,
496
+ });
497
+ speak(currentState.emission);
498
+ }
499
+ } else {
500
+ console.error(response, resp);
501
+ message.error(t(getErrori18nKey(resp.resultCode)));
502
+ }
503
+ } else {
504
+ console.error(response, resp);
505
+ message.error(t(getErrori18nKey(resp.resultCode)));
506
+ }
507
+ } else if (
508
+ userLang.toLowerCase() !== language.toLowerCase() &&
509
+ emission &&
510
+ !instruct &&
511
+ isMultilanguageEnabled
512
+ ) {
513
+ translateDialogState(currentState, userLang).then(ts => {
514
+ if (ts.emission) {
515
+ speak(ts.emission);
516
+ }
517
+ });
518
+ } else {
519
+ setCurrentDialogState({
520
+ ...currentState,
521
+ emission,
522
+ });
523
+
524
+ if (emission) {
525
+ pushMessage({
526
+ text: emission,
527
+ media: currentState.media,
528
+ fromUser: false,
529
+ generatedByAI: !!currentState.completion,
530
+ });
531
+ speak(emission);
532
+ }
533
+ }
534
+ } else if (response.resultCode === 404) {
535
+ // remove last sent message, will set it as initial
536
+ setHistory(h => [...h.slice(0, h.length - 1)]);
537
+
538
+ // post session timeout -> Z0/A0 -> restart session and re-send msg
539
+ reopenSession(
540
+ false,
541
+ memoriPwd || memori.secretToken,
542
+ memoriTokens,
543
+ instruct && memori.giverTag ? memori.giverTag : undefined,
544
+ instruct && memori.giverPIN ? memori.giverPIN : undefined,
545
+ initialContextVars,
546
+ initialQuestion
547
+ ).then(state => {
548
+ console.info('session timeout');
549
+ if (state?.sessionID) {
550
+ setTimeout(() => {
551
+ sendMessage(text, media, state?.sessionID);
552
+ }, 500);
553
+ }
554
+ });
555
+ }
556
+
557
+ setMemoriTyping(false);
558
+ };
559
+
560
+ /**
561
+ * Traduzioni istantanee
562
+ */
563
+ const translateDialogState = async (state: DialogState, userLang: string) => {
564
+ const emission = state.emission ?? currentDialogState?.emission;
565
+
566
+ let translatedState = { ...state };
567
+ let translatedMsg = null;
568
+
569
+ if (
570
+ !emission ||
571
+ instruct ||
572
+ language.toUpperCase() === userLang.toUpperCase() ||
573
+ !isMultilanguageEnabled
574
+ ) {
575
+ translatedState = { ...state, emission };
576
+ if (emission) {
577
+ translatedMsg = {
578
+ text: emission,
579
+ media: state.media,
580
+ fromUser: false,
581
+ };
582
+ }
583
+ } else {
584
+ const t = await getTranslation(emission, userLang, language, baseUrl);
585
+ if (state.hints && state.hints.length > 0) {
586
+ const translatedHints = await Promise.all(
587
+ (state.hints ?? []).map(async hint => {
588
+ const tHint = await getTranslation(
589
+ hint,
590
+ userLang,
591
+ language,
592
+ baseUrl
593
+ );
594
+ return {
595
+ text: tHint?.text ?? hint,
596
+ originalText: hint,
597
+ } as TranslatedHint;
598
+ })
599
+ );
600
+ translatedState = {
601
+ ...state,
602
+ emission: t.text,
603
+ translatedHints,
604
+ };
605
+ } else {
606
+ translatedState = {
607
+ ...state,
608
+ emission: t.text,
609
+ hints:
610
+ state.hints ??
611
+ (state.state === 'G1' ? currentDialogState?.hints : []),
612
+ };
613
+ }
614
+
615
+ if (t.text.length > 0)
616
+ translatedMsg = {
617
+ text: t.text,
618
+ media: state.media,
619
+ fromUser: false,
620
+ generatedByAI: !!state.completion,
621
+ };
622
+ }
623
+
624
+ setCurrentDialogState(translatedState);
625
+ if (translatedMsg) {
626
+ pushMessage(translatedMsg);
627
+ }
628
+
629
+ return translatedState;
630
+ };
631
+
632
+ /**
633
+ * Age verification
634
+ */
635
+ const minAge = memori.ageRestriction
636
+ ? memori.ageRestriction
637
+ : memori.nsfw
638
+ ? 18
639
+ : memori.enableCompletions
640
+ ? 14
641
+ : 0;
642
+ const [birthDate, setBirthDate] = useState<string | undefined>();
643
+ const [showAgeVerification, setShowAgeVerification] = useState(false);
644
+
386
645
  /**
387
646
  * Sessione
388
647
  */
@@ -695,264 +954,6 @@ const MemoriWidget = ({
695
954
  // eslint-disable-next-line react-hooks/exhaustive-deps
696
955
  }, []);
697
956
 
698
- /**
699
- * History e gestione invio messaggi
700
- */
701
- const [userMessage, setUserMessage] = useState<string>('');
702
- const onChangeUserMessage = (value: string) => {
703
- if (!value || value === '\n' || value.trim() === '') {
704
- setUserMessage('');
705
- resetInteractionTimeout();
706
- return;
707
- }
708
- setUserMessage(value);
709
- clearInteractionTimeout();
710
- };
711
- const [listening, setListening] = useState(false);
712
- const [history, setHistory] = useState<Message[]>([]);
713
- const pushMessage = (message: Message) => {
714
- setHistory(history => [...history, { ...message }]);
715
- };
716
- const sendMessage = useCallback(
717
- async (
718
- text: string,
719
- media?: Medium[],
720
- newSessionId?: string,
721
- translate: boolean = true,
722
- translatedText?: string,
723
- hidden: boolean = false
724
- ) => {
725
- const sessionID = newSessionId || sessionId;
726
- if (!sessionID || !text?.length) return;
727
-
728
- if (!hidden)
729
- pushMessage({
730
- text: text,
731
- translatedText,
732
- fromUser: true,
733
- media: media ?? [],
734
- initial: !!newSessionId,
735
- });
736
-
737
- setMemoriTyping(true);
738
-
739
- const language = memori.culture?.split('-')?.[0] ?? i18n.language ?? 'IT';
740
- let msg = text;
741
-
742
- if (
743
- translate &&
744
- !instruct &&
745
- isMultilanguageEnabled &&
746
- userLang.toUpperCase() !== language.toUpperCase()
747
- ) {
748
- const translation = await getTranslation(
749
- text,
750
- language,
751
- userLang,
752
- baseUrl
753
- );
754
- msg = translation.text;
755
- }
756
-
757
- const { currentState, ...response } = await postTextEnteredEvent({
758
- sessionId: sessionID,
759
- text: msg,
760
- });
761
- if (response.resultCode === 0 && currentState) {
762
- const emission = currentState.emission ?? currentDialogState?.emission;
763
- if (currentState.state === 'X4' && memori.giverTag) {
764
- const { currentState, ...resp } = await postTagChangedEvent(
765
- sessionID,
766
- memori.giverTag
767
- );
768
-
769
- if (resp.resultCode === 0) {
770
- setCurrentDialogState(currentState);
771
-
772
- if (currentState.emission) {
773
- pushMessage({
774
- text: currentState.emission,
775
- media: currentState.media,
776
- fromUser: false,
777
- });
778
- speak(currentState.emission);
779
- }
780
- } else {
781
- console.error(response, resp);
782
- message.error(t(getErrori18nKey(resp.resultCode)));
783
- }
784
- } else if (currentState.state === 'X2d' && memori.giverTag) {
785
- const { currentState, ...resp } = await postTextEnteredEvent({
786
- sessionId: sessionID,
787
- text: Math.random().toString().substring(2, 8),
788
- });
789
-
790
- if (resp.resultCode === 0) {
791
- const { currentState, ...resp } = await postTagChangedEvent(
792
- sessionID,
793
- memori.giverTag
794
- );
795
-
796
- if (resp.resultCode === 0) {
797
- setCurrentDialogState(currentState);
798
-
799
- if (currentState.emission) {
800
- pushMessage({
801
- text: currentState.emission,
802
- media: currentState.media,
803
- fromUser: false,
804
- });
805
- speak(currentState.emission);
806
- }
807
- } else {
808
- console.error(response, resp);
809
- message.error(t(getErrori18nKey(resp.resultCode)));
810
- }
811
- } else {
812
- console.error(response, resp);
813
- message.error(t(getErrori18nKey(resp.resultCode)));
814
- }
815
- } else if (
816
- userLang.toLowerCase() !== language.toLowerCase() &&
817
- emission &&
818
- !instruct &&
819
- isMultilanguageEnabled
820
- ) {
821
- translateDialogState(currentState, userLang).then(ts => {
822
- if (ts.emission) {
823
- speak(ts.emission);
824
- }
825
- });
826
- } else {
827
- setCurrentDialogState({
828
- ...currentState,
829
- emission,
830
- });
831
-
832
- if (emission) {
833
- pushMessage({
834
- text: emission,
835
- media: currentState.media,
836
- fromUser: false,
837
- generatedByAI: !!currentState.completion,
838
- });
839
- speak(emission);
840
- }
841
- }
842
- } else if (response.resultCode === 404) {
843
- // remove last sent message, will set it as initial
844
- setHistory(h => [...h.slice(0, h.length - 1)]);
845
-
846
- // post session timeout -> Z0/A0 -> restart session and re-send msg
847
- reopenSession(
848
- false,
849
- memoriPwd || memori.secretToken,
850
- memoriTokens,
851
- instruct && memori.giverTag ? memori.giverTag : undefined,
852
- instruct && memori.giverPIN ? memori.giverPIN : undefined,
853
- initialContextVars,
854
- initialQuestion
855
- ).then(state => {
856
- console.info('session timeout');
857
- if (state?.sessionID) {
858
- setTimeout(() => {
859
- sendMessage(text, media, state?.sessionID);
860
- }, 500);
861
- }
862
- });
863
- }
864
-
865
- setMemoriTyping(false);
866
- },
867
- [sessionId]
868
- );
869
-
870
- /**
871
- * Traduzioni istantanee
872
- */
873
- const translateDialogState = async (state: DialogState, userLang: string) => {
874
- const language = memori.culture?.split('-')?.[0] ?? i18n.language ?? 'IT';
875
- const emission = state.emission ?? currentDialogState?.emission;
876
-
877
- let translatedState = { ...state };
878
- let translatedMsg = null;
879
-
880
- if (
881
- !emission ||
882
- instruct ||
883
- language.toUpperCase() === userLang.toUpperCase() ||
884
- !isMultilanguageEnabled
885
- ) {
886
- translatedState = { ...state, emission };
887
- if (emission) {
888
- translatedMsg = {
889
- text: emission,
890
- media: state.media,
891
- fromUser: false,
892
- };
893
- }
894
- } else {
895
- const t = await getTranslation(emission, userLang, language, baseUrl);
896
- if (state.hints && state.hints.length > 0) {
897
- const translatedHints = await Promise.all(
898
- (state.hints ?? []).map(async hint => {
899
- const tHint = await getTranslation(
900
- hint,
901
- userLang,
902
- language,
903
- baseUrl
904
- );
905
- return {
906
- text: tHint?.text ?? hint,
907
- originalText: hint,
908
- } as TranslatedHint;
909
- })
910
- );
911
- translatedState = {
912
- ...state,
913
- emission: t.text,
914
- translatedHints,
915
- };
916
- } else {
917
- translatedState = {
918
- ...state,
919
- emission: t.text,
920
- hints:
921
- state.hints ??
922
- (state.state === 'G1' ? currentDialogState?.hints : []),
923
- };
924
- }
925
-
926
- if (t.text.length > 0)
927
- translatedMsg = {
928
- text: t.text,
929
- media: state.media,
930
- fromUser: false,
931
- generatedByAI: !!state.completion,
932
- };
933
- }
934
-
935
- setCurrentDialogState(translatedState);
936
- if (translatedMsg) {
937
- pushMessage(translatedMsg);
938
- }
939
-
940
- return translatedState;
941
- };
942
-
943
- /**
944
- * Age verification
945
- */
946
- const minAge = memori.ageRestriction
947
- ? memori.ageRestriction
948
- : memori.nsfw
949
- ? 18
950
- : memori.enableCompletions
951
- ? 14
952
- : 0;
953
- const [birthDate, setBirthDate] = useState<string | undefined>();
954
- const [showAgeVerification, setShowAgeVerification] = useState(false);
955
-
956
957
  /**
957
958
  * Timeout conversazione
958
959
  */
@@ -1969,11 +1970,13 @@ const MemoriWidget = ({
1969
1970
  memoriTextEnteredHandler(e);
1970
1971
  }, 1000);
1971
1972
  } else {
1972
- sendMessage(text, undefined, sessionID, undefined, undefined, hidden);
1973
+ stopListening();
1974
+ stopAudio();
1975
+ sendMessage(text, undefined, undefined, undefined, undefined, hidden);
1973
1976
  }
1974
1977
  }
1975
1978
  },
1976
- [sessionId, isPlayingAudio, memoriTyping]
1979
+ [sessionId, isPlayingAudio, memoriTyping, userLang]
1977
1980
  );
1978
1981
  useEffect(() => {
1979
1982
  document.addEventListener('MemoriTextEntered', memoriTextEnteredHandler);
@@ -1984,7 +1987,7 @@ const MemoriWidget = ({
1984
1987
  memoriTextEnteredHandler
1985
1988
  );
1986
1989
  };
1987
- }, []);
1990
+ }, [sessionId, userLang]);
1988
1991
 
1989
1992
  const onClickStart = useCallback(
1990
1993
  async (session?: { dialogState: DialogState; sessionID: string }) => {