@memori.ai/memori-react 7.34.2 → 8.0.0-rc.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 (54) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/dist/components/Chat/Chat.d.ts +1 -0
  3. package/dist/components/Chat/Chat.js +2 -2
  4. package/dist/components/Chat/Chat.js.map +1 -1
  5. package/dist/components/ChatInputs/ChatInputs.d.ts +1 -0
  6. package/dist/components/ChatInputs/ChatInputs.js +3 -3
  7. package/dist/components/ChatInputs/ChatInputs.js.map +1 -1
  8. package/dist/components/MemoriWidget/MemoriWidget.d.ts +3 -3
  9. package/dist/components/MemoriWidget/MemoriWidget.js +138 -425
  10. package/dist/components/MemoriWidget/MemoriWidget.js.map +1 -1
  11. package/dist/context/visemeContext.js +39 -30
  12. package/dist/context/visemeContext.js.map +1 -1
  13. package/dist/helpers/sanitizer.d.ts +6 -0
  14. package/dist/helpers/sanitizer.js +41 -0
  15. package/dist/helpers/sanitizer.js.map +1 -0
  16. package/dist/helpers/tts/ttsVoiceUtility.d.ts +158 -0
  17. package/dist/helpers/tts/ttsVoiceUtility.js +192 -0
  18. package/dist/helpers/tts/ttsVoiceUtility.js.map +1 -0
  19. package/dist/helpers/tts/useTTS.d.ts +26 -0
  20. package/dist/helpers/tts/useTTS.js +274 -0
  21. package/dist/helpers/tts/useTTS.js.map +1 -0
  22. package/dist/index.js +12 -7
  23. package/dist/index.js.map +1 -1
  24. package/esm/components/Chat/Chat.d.ts +1 -0
  25. package/esm/components/Chat/Chat.js +2 -2
  26. package/esm/components/Chat/Chat.js.map +1 -1
  27. package/esm/components/ChatInputs/ChatInputs.d.ts +1 -0
  28. package/esm/components/ChatInputs/ChatInputs.js +3 -3
  29. package/esm/components/ChatInputs/ChatInputs.js.map +1 -1
  30. package/esm/components/MemoriWidget/MemoriWidget.d.ts +3 -3
  31. package/esm/components/MemoriWidget/MemoriWidget.js +139 -426
  32. package/esm/components/MemoriWidget/MemoriWidget.js.map +1 -1
  33. package/esm/context/visemeContext.js +39 -30
  34. package/esm/context/visemeContext.js.map +1 -1
  35. package/esm/helpers/sanitizer.d.ts +6 -0
  36. package/esm/helpers/sanitizer.js +32 -0
  37. package/esm/helpers/sanitizer.js.map +1 -0
  38. package/esm/helpers/tts/ttsVoiceUtility.d.ts +158 -0
  39. package/esm/helpers/tts/ttsVoiceUtility.js +182 -0
  40. package/esm/helpers/tts/ttsVoiceUtility.js.map +1 -0
  41. package/esm/helpers/tts/useTTS.d.ts +26 -0
  42. package/esm/helpers/tts/useTTS.js +270 -0
  43. package/esm/helpers/tts/useTTS.js.map +1 -0
  44. package/esm/index.js +12 -7
  45. package/esm/index.js.map +1 -1
  46. package/package.json +2 -2
  47. package/src/components/Chat/Chat.tsx +3 -0
  48. package/src/components/ChatInputs/ChatInputs.tsx +4 -2
  49. package/src/components/MemoriWidget/MemoriWidget.tsx +246 -637
  50. package/src/context/visemeContext.tsx +77 -55
  51. package/src/helpers/sanitizer.ts +71 -0
  52. package/src/helpers/tts/ttsVoiceUtility.ts +275 -0
  53. package/src/helpers/tts/useTTS.ts +431 -0
  54. package/src/index.tsx +14 -10
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useState, useEffect, useCallback, useRef, } from 'react';
2
+ import { useState, useEffect, useCallback, useRef, useMemo, } from 'react';
3
3
  import { useTranslation } from 'react-i18next';
4
4
  import memoriApiClient from '@memori.ai/memori-api-client';
5
5
  import { AudioContext } from 'standardized-audio-context';
@@ -29,11 +29,14 @@ import HiddenChatLayout from '../layouts/HiddenChat';
29
29
  import ZoomedFullBodyLayout from '../layouts/ZoomedFullBody';
30
30
  import { getTranslation } from '../../helpers/translations';
31
31
  import { setLocalConfig, getLocalConfig, removeLocalConfig, } from '../../helpers/configuration';
32
- import { hasTouchscreen, stripDuplicates, stripEmojis, escapeHTML, stripMarkdown, stripOutputTags, stripHTML, installMathJax, stripReasoningTags, } from '../../helpers/utils';
32
+ import { hasTouchscreen, stripDuplicates, installMathJax, } from '../../helpers/utils';
33
+ import { getTTSVoice } from '../../helpers/tts/ttsVoiceUtility';
33
34
  import { allowedMediaTypes, anonTag, uiLanguages, } from '../../helpers/constants';
34
35
  import { getErrori18nKey } from '../../helpers/error';
35
36
  import { getCredits } from '../../helpers/credits';
36
- import { useViseme } from '../../context/visemeContext';
37
+ import { sanitizeText } from '../../helpers/sanitizer';
38
+ import { useTTS } from '../../helpers/tts/useTTS';
39
+ import Alert from '../ui/Alert';
37
40
  import ChatHistoryDrawer from '../ChatHistoryDrawer/ChatHistory';
38
41
  const getMemoriState = (integrationId) => {
39
42
  var _a, _b, _c, _d, _f;
@@ -151,14 +154,11 @@ window.typeMessageHidden = typeMessageHidden;
151
154
  window.typeBatchMessages = typeBatchMessages;
152
155
  let recognizer;
153
156
  let speechConfig;
154
- let speechSynthesizer;
155
157
  let audioDestination;
156
158
  let audioContext;
157
159
  let memoriPassword;
158
- let speakerMuted = false;
159
- let memoriSpeaking = false;
160
160
  let userToken;
161
- const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenantID, memoriLang, multilingual, integration, layout, customLayout, showShare, preview = false, embed = false, showCopyButton = true, showTranslationOriginal = false, showInputs = true, showDates = false, showContextPerLine = false, showSettings, showTypingText = false, showClear = false, showLogin = false, showUpload, showOnlyLastMessages, showChatHistory, showReasoning, height = '100vh', secret, baseUrl = 'https://aisuru.com', apiURL = 'https://backend-staging.memori.ai', engineURL = 'https://engine-staging.memori.ai', initialContextVars, initialQuestion, ogImage, sessionID: initialSessionID, tenant, personification, authToken, AZURE_COGNITIVE_SERVICES_TTS_KEY, enableAudio, defaultSpeakerActive = true, disableTextEnteredEvents = false, onStateChange, additionalInfo, additionalSettings, customMediaRenderer, userAvatar, useMathFormatting = false, autoStart = false, applyVarsToRoot = false, showFunctionCache = false, }) => {
161
+ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenantID, memoriLang, multilingual, integration, layout, customLayout, showShare, preview = false, embed = false, showCopyButton = true, showTranslationOriginal = false, showInputs = true, showDates = false, showContextPerLine = false, showSettings, showTypingText = false, showClear = false, showLogin = false, showUpload, showOnlyLastMessages, showChatHistory, showReasoning, height = '100vh', secret, baseUrl = 'https://aisuru.com', apiURL = 'https://backend-staging.memori.ai', engineURL = 'https://engine-staging.memori.ai', initialContextVars, initialQuestion, ttsProvider, ogImage, sessionID: initialSessionID, tenant, personification, authToken, enableAudio, defaultSpeakerActive = true, disableTextEnteredEvents = false, onStateChange, additionalInfo, additionalSettings, customMediaRenderer, userAvatar, useMathFormatting = false, autoStart = false, applyVarsToRoot = false, showFunctionCache = false, }) => {
162
162
  var _a, _b, _c, _d, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6;
163
163
  const { t, i18n } = useTranslation();
164
164
  const [isClient, setIsClient] = useState(false);
@@ -224,25 +224,23 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
224
224
  const [typingText, setTypingText] = useState();
225
225
  const selectedLayout = layout || (integrationConfig === null || integrationConfig === void 0 ? void 0 : integrationConfig.layout) || 'DEFAULT';
226
226
  const defaultEnableAudio = (_p = enableAudio !== null && enableAudio !== void 0 ? enableAudio : integrationConfig === null || integrationConfig === void 0 ? void 0 : integrationConfig.enableAudio) !== null && _p !== void 0 ? _p : false;
227
- const [hasUserActivatedSpeak, setHasUserActivatedSpeak] = useState(false);
228
227
  const [hasUserActivatedListening, setHasUserActivatedListening] = useState(false);
229
228
  const [showPositionDrawer, setShowPositionDrawer] = useState(false);
230
229
  const [showSettingsDrawer, setShowSettingsDrawer] = useState(false);
231
230
  const [showChatHistoryDrawer, setShowChatHistoryDrawer] = useState(false);
232
231
  const [showKnownFactsDrawer, setShowKnownFactsDrawer] = useState(false);
233
232
  const [showExpertsDrawer, setShowExpertsDrawer] = useState(false);
234
- const [muteSpeaker, setMuteSpeaker] = useState(!defaultEnableAudio || !defaultSpeakerActive || autoStart);
235
233
  const [continuousSpeech, setContinuousSpeech] = useState(false);
236
234
  const [continuousSpeechTimeout, setContinuousSpeechTimeout] = useState(2);
237
- const [isPlayingAudio, setIsPlayingAudio] = useState(false);
238
235
  const [controlsPosition, setControlsPosition] = useState('center');
239
236
  const [enablePositionControls, setEnablePositionControls] = useState(false);
240
237
  const [avatarType, setAvatarType] = useState(null);
241
238
  const [hideEmissions, setHideEmissions] = useState(false);
242
- const { startProcessing, setAudioContext, addViseme, stopProcessing, resetVisemeQueue, } = useViseme();
239
+ const speechSynthesizerRef = useRef(null);
240
+ const [memoriSpeaking, setMemoriSpeaking] = useState(false);
243
241
  useEffect(() => {
244
- memoriSpeaking = !!speechSynthesizer;
245
- }, [speechSynthesizer]);
242
+ setMemoriSpeaking(!!speechSynthesizerRef.current);
243
+ }, [speechSynthesizerRef.current]);
246
244
  useEffect(() => {
247
245
  let defaultControlsPosition = 'bottom';
248
246
  let microphoneMode = getLocalConfig('microphoneMode', 'HOLD_TO_TALK');
@@ -257,11 +255,7 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
257
255
  else {
258
256
  defaultControlsPosition = 'bottom';
259
257
  }
260
- const muteSpeaker = autoStart ||
261
- getLocalConfig('muteSpeaker', !defaultEnableAudio || !defaultSpeakerActive || autoStart);
262
- setMuteSpeaker(muteSpeaker);
263
- speakerMuted = muteSpeaker;
264
- setContinuousSpeech(muteSpeaker ? false : microphoneMode === 'CONTINUOUS');
258
+ setContinuousSpeech(speakerMuted ? false : microphoneMode === 'CONTINUOUS');
265
259
  setContinuousSpeechTimeout(getLocalConfig('continuousSpeechTimeout', 2));
266
260
  setControlsPosition(getLocalConfig('controlsPosition', defaultControlsPosition));
267
261
  setAvatarType(getLocalConfig('avatarType', 'avatar3d'));
@@ -396,7 +390,7 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
396
390
  translateDialogState(currentState, userLang, msg).then(ts => {
397
391
  let text = ts.translatedEmission || ts.emission;
398
392
  if (text) {
399
- speak(text);
393
+ handleSpeak(text);
400
394
  }
401
395
  });
402
396
  }
@@ -422,7 +416,7 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
422
416
  tag: currentState.currentTag,
423
417
  memoryTags: currentState.memoryTags,
424
418
  });
425
- speak(emission);
419
+ handleSpeak(emission);
426
420
  }
427
421
  }
428
422
  }
@@ -1016,6 +1010,44 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
1016
1010
  timeoutRef.current = undefined;
1017
1011
  }
1018
1012
  };
1013
+ useEffect(() => {
1014
+ return () => {
1015
+ setHasUserActivatedSpeak(false);
1016
+ setClickedStart(false);
1017
+ clearInteractionTimeout();
1018
+ timeoutRef.current = undefined;
1019
+ };
1020
+ }, []);
1021
+ const [requestedListening, setRequestedListening] = useState(false);
1022
+ const onEndSpeakStartListen = useCallback((_e) => {
1023
+ if (isPlayingAudio && speechSynthesizerRef.current) {
1024
+ speechSynthesizerRef.current.close();
1025
+ speechSynthesizerRef.current = null;
1026
+ }
1027
+ if (continuousSpeech &&
1028
+ (hasUserActivatedListening || !requestedListening)) {
1029
+ setRequestedListening(true);
1030
+ startListening();
1031
+ }
1032
+ }, [continuousSpeech, hasUserActivatedListening]);
1033
+ const audioPlaybackOptions = useMemo(() => ({
1034
+ apiUrl: apiURL,
1035
+ continuousSpeech: continuousSpeech,
1036
+ onEndSpeakStartListen: onEndSpeakStartListen,
1037
+ preview: preview,
1038
+ }), [apiURL, continuousSpeech, preview, onEndSpeakStartListen]);
1039
+ console.log('tenantID', tenantID);
1040
+ const ttsConfig = useMemo(() => {
1041
+ var _a, _b;
1042
+ return ({
1043
+ provider: ttsProvider,
1044
+ voice: getTTSVoice(userLang || ((_b = (_a = memori.culture) === null || _a === void 0 ? void 0 : _a.split('-')) === null || _b === void 0 ? void 0 : _b[0]) || 'EN', ttsProvider, memori.voiceType),
1045
+ tenant: tenantID,
1046
+ region: 'westeurope',
1047
+ voiceType: memori.voiceType
1048
+ });
1049
+ }, [ttsProvider, userLang, memori.culture, memori.voiceType]);
1050
+ const { speak: ttsSpeak, stop: ttsStop, isPlaying: isPlayingAudio, speakerMuted, toggleMute, hasUserActivatedSpeak, setHasUserActivatedSpeak, error, setError, } = useTTS(ttsConfig, audioPlaybackOptions, autoStart, defaultEnableAudio, defaultSpeakerActive);
1019
1051
  const resetInteractionTimeout = () => {
1020
1052
  clearInteractionTimeout();
1021
1053
  if (!isPlayingAudio && !userMessage.length && !memoriTyping && !listening)
@@ -1044,7 +1076,7 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
1044
1076
  translateDialogState({ ...currentState, emission: emission }, userLang).then(ts => {
1045
1077
  let text = ts.translatedEmission || ts.emission;
1046
1078
  if (text) {
1047
- speak(text);
1079
+ handleSpeak(text);
1048
1080
  }
1049
1081
  });
1050
1082
  }
@@ -1064,7 +1096,7 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
1064
1096
  tag: currentState.currentTag,
1065
1097
  memoryTags: currentState.memoryTags,
1066
1098
  });
1067
- speak(emission);
1099
+ handleSpeak(emission);
1068
1100
  setCurrentDialogState({
1069
1101
  ...currentState,
1070
1102
  hints: (_b = currentState.hints) !== null && _b !== void 0 ? _b : (currentState.state === 'G1' ? currentDialogState === null || currentDialogState === void 0 ? void 0 : currentDialogState.hints : []),
@@ -1117,97 +1149,6 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
1117
1149
  memoriTyping,
1118
1150
  hasUserActivatedSpeak,
1119
1151
  ]);
1120
- useEffect(() => {
1121
- return () => {
1122
- setHasUserActivatedSpeak(false);
1123
- setClickedStart(false);
1124
- clearInteractionTimeout();
1125
- timeoutRef.current = undefined;
1126
- };
1127
- }, []);
1128
- const initializeTTS = () => {
1129
- if (!AZURE_COGNITIVE_SERVICES_TTS_KEY)
1130
- return;
1131
- speechConfig = speechSdk.SpeechConfig.fromSubscription(AZURE_COGNITIVE_SERVICES_TTS_KEY, 'westeurope');
1132
- speechConfig.speechSynthesisLanguage = getCultureCodeByLanguage(userLang);
1133
- speechConfig.speechSynthesisVoiceName = getTTSVoice(userLang);
1134
- speechConfig.speechRecognitionLanguage = getCultureCodeByLanguage(userLang);
1135
- speechConfig.setProperty('speechSynthesis.outputFormat', 'viseme');
1136
- if (hasTouchscreen())
1137
- speechConfig.speechSynthesisOutputFormat =
1138
- speechSdk.SpeechSynthesisOutputFormat.Audio16Khz32KBitRateMonoMp3;
1139
- audioContext = new AudioContext();
1140
- let buffer = audioContext.createBuffer(1, 10000, 22050);
1141
- let source = audioContext.createBufferSource();
1142
- source.buffer = buffer;
1143
- source.connect(audioContext.destination);
1144
- audioDestination = new speechSdk.SpeakerAudioDestination();
1145
- let audioConfig = speechSdk.AudioConfig.fromSpeakerOutput(audioDestination);
1146
- speechSynthesizer = new speechSdk.SpeechSynthesizer(speechConfig, audioConfig);
1147
- };
1148
- const getTTSVoice = useCallback((lang) => {
1149
- var _a, _b, _c, _d;
1150
- let voice = '';
1151
- let voiceLang = ((_d = (_c = lang !== null && lang !== void 0 ? lang : (_b = (_a = memori.culture) === null || _a === void 0 ? void 0 : _a.split('-')) === null || _b === void 0 ? void 0 : _b[0]) !== null && _c !== void 0 ? _c : i18n.language) !== null && _d !== void 0 ? _d : 'IT').toUpperCase();
1152
- let voiceType = memori.voiceType;
1153
- if (memori.enableBoardOfExperts && (currentDialogState === null || currentDialogState === void 0 ? void 0 : currentDialogState.emitter)) {
1154
- let expert = experts === null || experts === void 0 ? void 0 : experts.find(e => e.name === (currentDialogState === null || currentDialogState === void 0 ? void 0 : currentDialogState.emitter));
1155
- }
1156
- switch (voiceLang) {
1157
- case 'IT':
1158
- voice = `${voiceType === 'MALE' ? 'it-IT-DiegoNeural' : 'it-IT-ElsaNeural'}`;
1159
- break;
1160
- case 'DE':
1161
- voice = `${voiceType === 'MALE' ? 'de-DE-ConradNeural' : 'de-DE-KatjaNeural'}`;
1162
- break;
1163
- case 'EN':
1164
- voice = `${voiceType === 'MALE' ? 'en-GB-RyanNeural' : 'en-GB-SoniaNeural'}`;
1165
- break;
1166
- case 'ES':
1167
- voice = `${voiceType === 'MALE' ? 'es-ES-AlvaroNeural' : 'es-ES-ElviraNeural'}`;
1168
- break;
1169
- case 'FR':
1170
- voice = `${voiceType === 'MALE' ? 'fr-FR-HenriNeural' : 'fr-FR-DeniseNeural'}`;
1171
- break;
1172
- case 'PT':
1173
- voice = `${voiceType === 'MALE' ? 'pt-PT-DuarteNeural' : 'pt-PT-RaquelNeural'}`;
1174
- break;
1175
- case 'UK':
1176
- voice = `${voiceType === 'MALE' ? 'uk-UA-OstapNeural' : 'uk-UA-PolinaNeural'}`;
1177
- break;
1178
- case 'RU':
1179
- voice = `${voiceType === 'MALE' ? 'ru-RU-DmitryNeural' : 'ru-RU-SvetlanaNeural'}`;
1180
- break;
1181
- case 'PL':
1182
- voice = `${voiceType === 'MALE' ? 'pl-PL-MarekNeural' : 'pl-PL-AgnieszkaNeural'}`;
1183
- break;
1184
- case 'FI':
1185
- voice = `${voiceType === 'MALE' ? 'fi-FI-HarriNeural' : 'fi-FI-SelmaNeural'}`;
1186
- break;
1187
- case 'EL':
1188
- voice = `${voiceType === 'MALE' ? 'el-GR-NestorasNeural' : 'el-GR-AthinaNeural'}`;
1189
- break;
1190
- case 'AR':
1191
- voice = `${voiceType === 'MALE' ? 'ar-SA-HamedNeural' : 'ar-SA-ZariyahNeural'}`;
1192
- break;
1193
- case 'ZH':
1194
- voice = `${voiceType === 'MALE' ? 'zh-CN-YunxiNeural' : 'zh-CN-XiaoxiaoNeural'}`;
1195
- break;
1196
- case 'JA':
1197
- voice = `${voiceType === 'MALE' ? 'ja-JP-KeitaNeural' : 'ja-JP-NanamiNeural'}`;
1198
- break;
1199
- default:
1200
- voice = `${voiceType === 'MALE' ? 'it-IT-DiegoNeural' : 'it-IT-IsabellaNeural'}`;
1201
- break;
1202
- }
1203
- return voice;
1204
- }, [
1205
- memori.voiceType,
1206
- memori.enableBoardOfExperts,
1207
- currentDialogState === null || currentDialogState === void 0 ? void 0 : currentDialogState.emitter,
1208
- i18n.language,
1209
- memori.culture,
1210
- ]);
1211
1152
  const getCultureCodeByLanguage = (lang) => {
1212
1153
  var _a, _b;
1213
1154
  let voice = '';
@@ -1264,185 +1205,58 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
1264
1205
  }
1265
1206
  return voice;
1266
1207
  };
1267
- const [phonemesMap, setPhonemesMap] = useState();
1268
- const fetchLexiconJSON = async () => {
1269
- try {
1270
- const lexiconReq = await fetch(`${baseUrl || 'https://aisuru.com'}/api/lexiconmap`);
1271
- const lexicon = await lexiconReq.json();
1272
- return lexicon;
1273
- }
1274
- catch (err) {
1275
- console.error(err);
1276
- }
1277
- };
1278
- useEffect(() => {
1279
- fetchLexiconJSON().then(lexicon => {
1280
- setPhonemesMap(lexicon);
1281
- });
1282
- }, []);
1283
- const replaceTextWithPhonemes = (text, lang) => {
1284
- var _a;
1285
- if (!phonemesMap)
1286
- return text;
1287
- const phonemes = {
1288
- ...((_a = phonemesMap.common) !== null && _a !== void 0 ? _a : {}),
1289
- ...((tenant === null || tenant === void 0 ? void 0 : tenant.name) && phonemesMap[tenant.name]
1290
- ? phonemesMap[tenant.name]
1291
- : {}),
1292
- };
1293
- const phonemesPairs = Object.keys(phonemes).map(word => {
1294
- var _a;
1295
- const phoneme = (_a = phonemes[word][lang.toLowerCase()]) !== null && _a !== void 0 ? _a : phonemes[word].default;
1296
- return { word, phoneme, caseSensitive: phonemes[word].caseSensitive };
1297
- });
1298
- const ssmlText = phonemesPairs.reduce((acc, { word, phoneme, caseSensitive }) => {
1299
- return acc.replace(new RegExp(`\\b${word}\\b`, caseSensitive ? 'g' : 'gi'), `<phoneme alphabet="ipa" ph="${phoneme}">${word}</phoneme>`);
1300
- }, text);
1301
- return ssmlText;
1302
- };
1303
- const emitEndSpeakEvent = () => {
1304
- const e = new CustomEvent('MemoriEndSpeak');
1305
- document.dispatchEvent(e);
1306
- };
1307
- const speak = (text) => {
1308
- console.debug('speak called with text:', text);
1309
- if (!AZURE_COGNITIVE_SERVICES_TTS_KEY || preview) {
1310
- console.debug('No TTS key or preview mode, emitting end speak event');
1311
- emitEndSpeakEvent();
1312
- return;
1313
- }
1314
- console.debug('Stopping listening before speaking');
1315
- stopListening();
1316
- if (preview) {
1317
- console.debug('Preview mode, returning early');
1318
- return;
1319
- }
1320
- if (speakerMuted) {
1321
- console.debug('Speaker muted, skipping speech synthesis');
1322
- memoriSpeaking = false;
1323
- setMemoriTyping(false);
1324
- emitEndSpeakEvent();
1208
+ const handleSpeak = async (text) => {
1209
+ if (!text || preview || speakerMuted) {
1210
+ const e = new CustomEvent('MemoriEndSpeak');
1211
+ document.dispatchEvent(e);
1325
1212
  if (continuousSpeech) {
1326
- console.debug('Setting listening timeout for continuous speech');
1327
1213
  setListeningTimeout();
1328
1214
  }
1329
- return;
1330
- }
1331
- if (audioDestination) {
1332
- console.debug('Pausing existing audio destination');
1333
- audioDestination.pause();
1334
- }
1335
- let isSafari = window.navigator.userAgent.includes('Safari') &&
1336
- !window.navigator.userAgent.includes('Chrome');
1337
- let isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent);
1338
- console.debug('Browser detection - Safari:', isSafari, 'iOS:', isIOS);
1339
- if (audioContext.state === 'interrupted') {
1340
- console.debug('Audio context interrupted, attempting resume');
1341
- audioContext.resume().then(() => speak(text));
1342
- return;
1215
+ return Promise.resolve();
1343
1216
  }
1344
- if (audioContext.state === 'closed') {
1345
- console.debug('Audio context closed, creating new context');
1346
- audioContext = new AudioContext();
1347
- let buffer = audioContext.createBuffer(1, 10000, 22050);
1348
- let source = audioContext.createBufferSource();
1349
- source.buffer = buffer;
1350
- source.connect(audioContext.destination);
1217
+ if (typeof stopListening === 'function') {
1218
+ stopListening();
1351
1219
  }
1352
- else if (audioContext.state === 'suspended') {
1353
- console.debug('Audio context suspended, stopping audio and creating new context');
1354
- stopAudio();
1355
- audioContext = new AudioContext();
1356
- let buffer = audioContext.createBuffer(1, 10000, 22050);
1357
- let source = audioContext.createBufferSource();
1358
- source.buffer = buffer;
1359
- source.connect(audioContext.destination);
1360
- }
1361
- if (!speechSynthesizer) {
1362
- initializeTTS();
1363
- }
1364
- const source = audioContext.createBufferSource();
1365
- source.addEventListener('ended', () => {
1366
- console.debug('Audio source ended');
1367
- setIsPlayingAudio(false);
1368
- memoriSpeaking = false;
1220
+ setMemoriTyping(true);
1221
+ const processedText = sanitizeText(text);
1222
+ return ttsSpeak(processedText)
1223
+ .then(() => {
1224
+ setMemoriTyping(false);
1225
+ })
1226
+ .catch(error => {
1227
+ setMemoriTyping(false);
1228
+ throw error;
1369
1229
  });
1370
- audioDestination.onAudioEnd = () => {
1371
- console.debug('Audio destination ended');
1372
- setIsPlayingAudio(false);
1373
- memoriSpeaking = false;
1374
- source.disconnect();
1375
- emitEndSpeakEvent();
1376
- onEndSpeakStartListen();
1377
- };
1378
- console.debug('Resetting viseme queue');
1379
- resetVisemeQueue();
1380
- if (speechSynthesizer) {
1381
- speechSynthesizer.visemeReceived = function (_, e) {
1382
- console.debug('Viseme received:', e.visemeId, 'at offset:', e.audioOffset);
1383
- addViseme(e.visemeId, e.audioOffset);
1384
- };
1230
+ };
1231
+ const translateAndSpeak = useCallback(async (dialogState, language, msg, skipEmission = false) => {
1232
+ try {
1233
+ if (!dialogState) {
1234
+ console.warn('translateAndSpeak called with empty dialog state');
1235
+ return null;
1236
+ }
1237
+ const translatedState = await translateDialogState(dialogState, language, msg, skipEmission);
1238
+ const textToSpeak = translatedState.translatedEmission || translatedState.emission;
1239
+ if (textToSpeak && !skipEmission) {
1240
+ if (!hasUserActivatedSpeak) {
1241
+ setHasUserActivatedSpeak(true);
1242
+ }
1243
+ await handleSpeak(textToSpeak);
1244
+ }
1245
+ return translatedState;
1385
1246
  }
1386
- const textToSpeak = escapeHTML(stripMarkdown(stripEmojis(stripHTML(stripReasoningTags(stripOutputTags(text))))));
1387
- console.debug('Processed text to speak:', textToSpeak);
1388
- setTimeout(() => {
1389
- if (speechSynthesizer) {
1390
- console.debug('Starting speech synthesis');
1391
- speechSynthesizer.speakSsmlAsync(`<speak version="1.0" xmlns="http://www.w3.org/2001/10/synthesis" xmlns:mstts="https://www.w3.org/2001/mstts" xmlns:emo="http://www.w3.org/2009/10/emotionml" xml:lang="${getCultureCodeByLanguage(userLang)}"><voice name="${getTTSVoice(userLang)}"><s>${replaceTextWithPhonemes(textToSpeak, userLang.toLowerCase())}</s></voice></speak>`, result => {
1392
- if (result) {
1393
- console.debug('Speech synthesis successful');
1394
- setIsPlayingAudio(true);
1395
- memoriSpeaking = true;
1396
- startProcessing(audioContext);
1397
- try {
1398
- console.debug('Decoding audio data');
1399
- audioContext.decodeAudioData(result.audioData, function (buffer) {
1400
- console.debug('Audio data decoded successfully');
1401
- source.buffer = buffer;
1402
- source.connect(audioContext.destination);
1403
- if (history.length < 1 || (isSafari && isIOS)) {
1404
- console.debug('Starting audio playback');
1405
- source.start(0);
1406
- }
1407
- });
1408
- audioContext.onstatechange = () => {
1409
- console.debug('Audio context state changed to:', audioContext.state);
1410
- if (audioContext.state === 'suspended' ||
1411
- audioContext.state === 'closed') {
1412
- source.disconnect();
1413
- setIsPlayingAudio(false);
1414
- stopProcessing();
1415
- resetVisemeQueue();
1416
- memoriSpeaking = false;
1417
- }
1418
- else if (audioContext.state === 'interrupted') {
1419
- audioContext.resume();
1420
- }
1421
- };
1422
- audioContext.resume();
1423
- if (speechSynthesizer) {
1424
- console.debug('Closing speech synthesizer');
1425
- speechSynthesizer.close();
1426
- speechSynthesizer = null;
1427
- }
1428
- }
1429
- catch (error) {
1430
- console.error('Error processing audio data:', error);
1431
- handleFallback(text);
1432
- }
1433
- }
1434
- else {
1435
- console.debug('No result from speech synthesis, using fallback');
1436
- handleFallback(text);
1437
- }
1438
- }, error => {
1439
- console.error('Speak error:', error);
1440
- handleFallback(text);
1441
- });
1247
+ catch (error) {
1248
+ console.error('Error in translateAndSpeak:', error);
1249
+ if (!hasUserActivatedSpeak) {
1250
+ setHasUserActivatedSpeak(true);
1442
1251
  }
1443
- }, 100);
1444
- setMemoriTyping(false);
1445
- };
1252
+ return dialogState;
1253
+ }
1254
+ }, [
1255
+ translateDialogState,
1256
+ handleSpeak,
1257
+ hasUserActivatedSpeak,
1258
+ setHasUserActivatedSpeak,
1259
+ ]);
1446
1260
  const handleFallback = (text) => {
1447
1261
  window.speechSynthesis.speak(new SpeechSynthesisUtterance(text));
1448
1262
  cleanup();
@@ -1453,39 +1267,16 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
1453
1267
  recognizer.close();
1454
1268
  recognizer = null;
1455
1269
  }
1456
- if (speechSynthesizer) {
1457
- speechSynthesizer.close();
1458
- speechSynthesizer = null;
1270
+ if (speechSynthesizerRef.current) {
1271
+ speechSynthesizerRef.current.close();
1272
+ speechSynthesizerRef.current = null;
1459
1273
  }
1460
1274
  setListening(false);
1461
1275
  clearListeningTimeout();
1462
1276
  };
1463
- const stopAudio = async () => {
1464
- setIsPlayingAudio(false);
1465
- memoriSpeaking = false;
1466
- try {
1467
- if (speechSynthesizer) {
1468
- const currentSynthesizer = speechSynthesizer;
1469
- speechSynthesizer = null;
1470
- try {
1471
- currentSynthesizer.close();
1472
- }
1473
- catch (e) {
1474
- console.debug('Error closing speech synthesizer:', e);
1475
- }
1476
- }
1477
- if ((audioContext === null || audioContext === void 0 ? void 0 : audioContext.state) !== 'closed') {
1478
- audioContext.close();
1479
- }
1480
- if (audioDestination) {
1481
- audioDestination.pause();
1482
- audioDestination.close();
1483
- }
1484
- }
1485
- catch (e) {
1486
- console.debug('stopAudio error: ', e);
1487
- }
1488
- };
1277
+ const stopAudio = useCallback(async () => {
1278
+ ttsStop();
1279
+ }, [ttsStop]);
1489
1280
  const focusChatInput = () => {
1490
1281
  let textarea = document.querySelector('#chat-fieldset textarea');
1491
1282
  if (textarea && enableFocusChatInput) {
@@ -1544,10 +1335,6 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
1544
1335
  let microphoneStream = null;
1545
1336
  const startListening = async () => {
1546
1337
  console.debug('Starting speech recognition...');
1547
- if (!AZURE_COGNITIVE_SERVICES_TTS_KEY) {
1548
- console.error('No TTS key available');
1549
- throw new Error('No TTS key available');
1550
- }
1551
1338
  if (!sessionId) {
1552
1339
  console.error('No session ID available');
1553
1340
  throw new Error('No session ID available');
@@ -1585,7 +1372,6 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
1585
1372
  });
1586
1373
  setHasUserActivatedListening(true);
1587
1374
  console.debug('Setting up speech config...');
1588
- speechConfig = setupSpeechConfig(AZURE_COGNITIVE_SERVICES_TTS_KEY);
1589
1375
  console.debug('Creating audio config and recognizer...');
1590
1376
  const audioConfig = speechSdk.AudioConfig.fromDefaultMicrophoneInput();
1591
1377
  recognizer = new speechSdk.SpeechRecognizer(speechConfig, audioConfig);
@@ -1739,18 +1525,6 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
1739
1525
  if ((currentDialogState === null || currentDialogState === void 0 ? void 0 : currentDialogState.state) === 'Z0')
1740
1526
  clearListening();
1741
1527
  }, [currentDialogState === null || currentDialogState === void 0 ? void 0 : currentDialogState.state]);
1742
- const [requestedListening, setRequestedListening] = useState(false);
1743
- const onEndSpeakStartListen = useCallback((_e) => {
1744
- if (isPlayingAudio && speechSynthesizer) {
1745
- speechSynthesizer.close();
1746
- speechSynthesizer = null;
1747
- }
1748
- if (continuousSpeech &&
1749
- (hasUserActivatedListening || !requestedListening)) {
1750
- setRequestedListening(true);
1751
- startListening();
1752
- }
1753
- }, [continuousSpeech, hasUserActivatedListening]);
1754
1528
  useEffect(() => {
1755
1529
  if (!isPlayingAudio &&
1756
1530
  continuousSpeech &&
@@ -1921,7 +1695,7 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
1921
1695
  if (memoriAudioElement && isSafari) {
1922
1696
  memoriAudioElement.muted = false;
1923
1697
  memoriAudioElement.play().catch((e) => {
1924
- console.warn('error playing intro audio', e);
1698
+ console.warn('[CLICK_START] Error playing intro audio:', e);
1925
1699
  });
1926
1700
  }
1927
1701
  let storageBirthDate = getLocalConfig('birthDate', undefined);
@@ -1930,7 +1704,6 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
1930
1704
  birth = '1970-01-01T10:24:03.845Z';
1931
1705
  const localPosition = getLocalConfig('position', undefined);
1932
1706
  if (autoStart && !localPosition && memori.needsPosition) {
1933
- console.log('position required', localPosition);
1934
1707
  setShowPositionDrawer(true);
1935
1708
  return;
1936
1709
  }
@@ -1976,16 +1749,8 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
1976
1749
  if (session === null || session === void 0 ? void 0 : session.dialogState) {
1977
1750
  if (!chatLog) {
1978
1751
  setHistory([]);
1979
- translateDialogState(session.dialogState, userLang)
1980
- .then(ts => {
1981
- let text = ts.translatedEmission || ts.emission;
1982
- if (text) {
1983
- speak(text);
1984
- }
1985
- })
1986
- .finally(() => {
1987
- setHasUserActivatedSpeak(true);
1988
- });
1752
+ await translateAndSpeak(session.dialogState, userLang);
1753
+ setHasUserActivatedSpeak(true);
1989
1754
  }
1990
1755
  else {
1991
1756
  const messages = chatLog.lines.map((l, i) => {
@@ -2006,7 +1771,6 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
2006
1771
  if (language.toUpperCase() !== userLang.toUpperCase() &&
2007
1772
  isMultilanguageEnabled) {
2008
1773
  try {
2009
- console.debug('[CLICK_START] Translating messages');
2010
1774
  translatedMessages = await Promise.all(messages.map(async (m) => ({
2011
1775
  ...m,
2012
1776
  originalText: m.text,
@@ -2014,6 +1778,7 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
2014
1778
  })));
2015
1779
  }
2016
1780
  catch (e) {
1781
+ console.error('[CLICK_START] Error translating messages:', e);
2017
1782
  }
2018
1783
  }
2019
1784
  setHistory(translatedMessages);
@@ -2031,10 +1796,8 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
2031
1796
  return;
2032
1797
  }
2033
1798
  else if (initialSessionID) {
2034
- console.debug('[CLICK_START] Handling initial session');
2035
1799
  const { currentState, ...response } = await getSession(sessionID);
2036
1800
  if (response.resultCode !== 0 || !currentState) {
2037
- console.debug('[CLICK_START] Session expired, opening new session');
2038
1801
  setGotErrorInOpening(true);
2039
1802
  setSessionId(undefined);
2040
1803
  setClickedStart(false);
@@ -2042,35 +1805,25 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
2042
1805
  return;
2043
1806
  }
2044
1807
  setHistory([]);
2045
- if (position && memori.needsPosition)
1808
+ if (position && memori.needsPosition) {
2046
1809
  applyPosition(position, sessionID);
2047
- if (memori.needsDateTime)
1810
+ }
1811
+ if (memori.needsDateTime) {
2048
1812
  sendDateChangedEvent({ sessionID: sessionID, state: currentState });
1813
+ }
2049
1814
  if (personification &&
2050
1815
  currentState.currentTag !== personification.tag) {
2051
1816
  try {
2052
- console.debug('[CLICK_START] Changing tag for personification', personification, currentState);
2053
1817
  await changeTag(memori.engineMemoriID, sessionID, '-');
2054
1818
  const session = await changeTag(memori.engineMemoriID, sessionID, personification.tag, personification.pin);
2055
1819
  if (session && session.resultCode === 0) {
2056
- translateDialogState(session.currentState, userLang)
2057
- .then(ts => {
2058
- let text = ts.translatedEmission || ts.emission;
2059
- if (text) {
2060
- speak(text);
2061
- }
2062
- })
2063
- .finally(() => {
2064
- setHasUserActivatedSpeak(true);
2065
- });
1820
+ await translateAndSpeak(session.currentState, userLang);
2066
1821
  }
2067
1822
  else {
2068
- console.error('[CLICK_START] Session error:', session);
2069
1823
  throw new Error('No session');
2070
1824
  }
2071
1825
  }
2072
1826
  catch (e) {
2073
- console.error('[CLICK_START] Error changing tag:', e);
2074
1827
  reopenSession(true, memori === null || memori === void 0 ? void 0 : memori.secretToken, undefined, personification.tag, personification.pin, {
2075
1828
  PATHNAME: (_h = window.location.pathname) === null || _h === void 0 ? void 0 : _h.toUpperCase(),
2076
1829
  ROUTE: ((_l = (_k = (_j = window.location.pathname) === null || _j === void 0 ? void 0 : _j.split('/')) === null || _k === void 0 ? void 0 : _k.pop()) === null || _l === void 0 ? void 0 : _l.toUpperCase()) ||
@@ -2086,28 +1839,16 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
2086
1839
  (currentState === null || currentState === void 0 ? void 0 : currentState.currentTag) !== anonTag &&
2087
1840
  (currentState === null || currentState === void 0 ? void 0 : currentState.currentTag) !== '-') {
2088
1841
  try {
2089
- console.debug('[CLICK_START] Changing to anonymous tag');
2090
1842
  await changeTag(memori.engineMemoriID, sessionID, '-');
2091
1843
  const session = await changeTag(memori.engineMemoriID, sessionID, anonTag);
2092
1844
  if (session && session.resultCode === 0) {
2093
- translateDialogState(session.currentState, userLang)
2094
- .then(ts => {
2095
- let text = ts.translatedEmission || ts.emission;
2096
- if (text) {
2097
- speak(text);
2098
- }
2099
- })
2100
- .finally(() => {
2101
- setHasUserActivatedSpeak(true);
2102
- });
1845
+ await translateAndSpeak(session.currentState, userLang);
2103
1846
  }
2104
1847
  else {
2105
- console.error('[CLICK_START] Session error:', session);
2106
1848
  throw new Error('No session');
2107
1849
  }
2108
1850
  }
2109
1851
  catch (e) {
2110
- console.error('[CLICK_START] Error changing tag:', e);
2111
1852
  reopenSession(true, memori === null || memori === void 0 ? void 0 : memori.secretToken, undefined, undefined, undefined, {
2112
1853
  PATHNAME: (_m = window.location.pathname) === null || _m === void 0 ? void 0 : _m.toUpperCase(),
2113
1854
  ROUTE: ((_q = (_p = (_o = window.location.pathname) === null || _o === void 0 ? void 0 : _o.split('/')) === null || _p === void 0 ? void 0 : _p.pop()) === null || _q === void 0 ? void 0 : _q.toUpperCase()) ||
@@ -2120,8 +1861,7 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
2120
1861
  }
2121
1862
  else {
2122
1863
  try {
2123
- console.debug('[CLICK_START] Getting chat history');
2124
- const { chatLogs, ...resp } = await getSessionChatLogs(sessionID, sessionID);
1864
+ const { chatLogs } = await getSessionChatLogs(sessionID, sessionID);
2125
1865
  const messages = (_r = chatLogs === null || chatLogs === void 0 ? void 0 : chatLogs[0]) === null || _r === void 0 ? void 0 : _r.lines.map((l, i) => {
2126
1866
  var _a, _b;
2127
1867
  return ({
@@ -2140,7 +1880,6 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
2140
1880
  if (language.toUpperCase() !== userLang.toUpperCase() &&
2141
1881
  isMultilanguageEnabled) {
2142
1882
  try {
2143
- console.debug('[CLICK_START] Translating messages');
2144
1883
  translatedMessages = await Promise.all(messages.map(async (m) => ({
2145
1884
  ...m,
2146
1885
  originalText: m.text,
@@ -2148,30 +1887,19 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
2148
1887
  })));
2149
1888
  }
2150
1889
  catch (e) {
1890
+ console.error('[CLICK_START] Error translating messages:', e);
2151
1891
  }
2152
1892
  }
2153
1893
  setHistory(translatedMessages);
2154
- console.debug('[CLICK_START] props currentState:', currentState, 'userLang:', userLang, 'translatedMessages:', translatedMessages, 'history:', history);
2155
1894
  }
2156
1895
  catch (e) {
2157
- console.log('[CLICK_START] Error retrieving chat logs:', e);
1896
+ console.error('[CLICK_START] Error retrieving chat logs:', e);
2158
1897
  }
2159
1898
  if ((!!(translatedMessages === null || translatedMessages === void 0 ? void 0 : translatedMessages.length) && translatedMessages.length > 1) ||
2160
1899
  !initialQuestion) {
2161
- console.log('[CLICK_START] Using existing chat history');
2162
- translateDialogState(currentState, userLang, undefined, !!(translatedMessages === null || translatedMessages === void 0 ? void 0 : translatedMessages.length))
2163
- .then(ts => {
2164
- let text = ts.translatedEmission || ts.emission;
2165
- if (text) {
2166
- speak(text);
2167
- }
2168
- })
2169
- .finally(() => {
2170
- setHasUserActivatedSpeak(true);
2171
- });
1900
+ await translateAndSpeak(currentState, userLang, undefined, !!(translatedMessages === null || translatedMessages === void 0 ? void 0 : translatedMessages.length));
2172
1901
  }
2173
1902
  else {
2174
- console.log('[CLICK_START] Using existing chat history with message from initial question');
2175
1903
  translatedMessages = [];
2176
1904
  setHistory([]);
2177
1905
  setMemoriTyping(true);
@@ -2179,44 +1907,23 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
2179
1907
  sessionId: sessionID,
2180
1908
  text: initialQuestion,
2181
1909
  });
2182
- translateDialogState((_s = response.currentState) !== null && _s !== void 0 ? _s : currentState, userLang, undefined, false)
2183
- .then(ts => {
2184
- let text = ts.translatedEmission || ts.emission;
2185
- if (text) {
2186
- speak(text);
2187
- }
2188
- })
2189
- .finally(() => {
2190
- setMemoriTyping(false);
2191
- setHasUserActivatedSpeak(true);
2192
- });
1910
+ await translateAndSpeak((_s = response.currentState) !== null && _s !== void 0 ? _s : currentState, userLang, undefined, false);
2193
1911
  }
2194
1912
  }
2195
- if (position && memori.needsPosition)
1913
+ if (position && memori.needsPosition) {
2196
1914
  applyPosition(position, sessionID);
2197
- if (memori.needsDateTime)
1915
+ }
1916
+ if (memori.needsDateTime) {
2198
1917
  sendDateChangedEvent({ sessionID: sessionID, state: currentState });
1918
+ }
2199
1919
  }
2200
1920
  else {
2201
- console.debug('[CLICK_START] Using existing session');
2202
1921
  setHistory([]);
2203
- translateDialogState(dialogState, userLang)
2204
- .then(ts => {
2205
- let text = ts.translatedEmission || ts.emission;
2206
- if (text) {
2207
- speak(text);
2208
- }
2209
- })
2210
- .finally(() => {
2211
- setHasUserActivatedSpeak(true);
2212
- });
1922
+ await translateAndSpeak(dialogState, userLang);
2213
1923
  }
2214
1924
  }, [memoriPwd, memori, memoriTokens, birthDate, sessionId, userLang, position]);
2215
1925
  useEffect(() => {
2216
1926
  if (!clickedStart && autoStart) {
2217
- if (AZURE_COGNITIVE_SERVICES_TTS_KEY && !speechSynthesizer) {
2218
- initializeTTS();
2219
- }
2220
1927
  onClickStart();
2221
1928
  }
2222
1929
  }, [clickedStart, autoStart]);
@@ -2339,11 +2046,10 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
2339
2046
  setShowKnownFactsDrawer,
2340
2047
  setShowExpertsDrawer,
2341
2048
  enableAudio: (_w = enableAudio !== null && enableAudio !== void 0 ? enableAudio : integrationConfig === null || integrationConfig === void 0 ? void 0 : integrationConfig.enableAudio) !== null && _w !== void 0 ? _w : true,
2342
- showSpeaker: !!AZURE_COGNITIVE_SERVICES_TTS_KEY,
2343
- speakerMuted: muteSpeaker || speakerMuted,
2049
+ showSpeaker: !!ttsProvider,
2050
+ speakerMuted: speakerMuted,
2344
2051
  setSpeakerMuted: mute => {
2345
- speakerMuted = !!mute;
2346
- setMuteSpeaker(mute);
2052
+ toggleMute(mute);
2347
2053
  let microphoneMode = getLocalConfig('microphoneMode', 'HOLD_TO_TALK');
2348
2054
  if (microphoneMode === 'CONTINUOUS' && mute) {
2349
2055
  setContinuousSpeech(false);
@@ -2384,7 +2090,7 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
2384
2090
  avatar3dVisible,
2385
2091
  setAvatar3dVisible,
2386
2092
  hasUserActivatedSpeak,
2387
- isPlayingAudio: isPlayingAudio && !muteSpeaker,
2093
+ isPlayingAudio: isPlayingAudio && !speakerMuted,
2388
2094
  loading: !!memoriTyping,
2389
2095
  baseUrl,
2390
2096
  apiUrl: client.constants.BACKEND_URL,
@@ -2408,7 +2114,6 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
2408
2114
  clickedStart: clickedStart,
2409
2115
  isMultilanguageEnabled: isMultilanguageEnabled,
2410
2116
  onClickStart: onClickStart,
2411
- initializeTTS: initializeTTS,
2412
2117
  isUserLoggedIn: !!loginToken && !!(user === null || user === void 0 ? void 0 : user.userID),
2413
2118
  hasInitialSession: !!initialSessionID,
2414
2119
  notEnoughCredits: needsCredits && !hasEnoughCredits,
@@ -2420,6 +2125,7 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
2420
2125
  memori,
2421
2126
  sessionID: sessionId || '',
2422
2127
  tenant,
2128
+ provider: ttsProvider,
2423
2129
  translateTo: isMultilanguageEnabled &&
2424
2130
  userLang.toUpperCase() !==
2425
2131
  ((_3 = ((_2 = (_1 = (_0 = (_z = memori.culture) === null || _z === void 0 ? void 0 : _z.split('-')) === null || _0 === void 0 ? void 0 : _0[0]) !== null && _1 !== void 0 ? _1 : i18n.language) !== null && _2 !== void 0 ? _2 : 'IT')) === null || _3 === void 0 ? void 0 : _3.toUpperCase())
@@ -2453,7 +2159,7 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
2453
2159
  attachmentsMenuOpen,
2454
2160
  setAttachmentsMenuOpen,
2455
2161
  showInputs,
2456
- showMicrophone: !!AZURE_COGNITIVE_SERVICES_TTS_KEY,
2162
+ showMicrophone: !!ttsProvider,
2457
2163
  showFunctionCache,
2458
2164
  userMessage,
2459
2165
  onChangeUserMessage,
@@ -2500,7 +2206,7 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
2500
2206
  'memori--preview': preview,
2501
2207
  'memori--embed': embed,
2502
2208
  'memori--with-integration': integration,
2503
- 'memori--with-speechkey': !!AZURE_COGNITIVE_SERVICES_TTS_KEY,
2209
+ 'memori--with-speechkey': !!ttsProvider,
2504
2210
  'memori--active': hasUserActivatedSpeak,
2505
2211
  'memori--hide-emissions': hideEmissions,
2506
2212
  'memori--has-active-session': !!sessionId,
@@ -2562,6 +2268,10 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
2562
2268
  setChatLogID(chatLog.chatLogID);
2563
2269
  onClickStart(undefined, false, chatLog);
2564
2270
  setShowChatHistoryDrawer(false);
2271
+ }, apiClient: client, sessionId: sessionId || '', memori: memori, baseUrl: baseUrl, history: history, apiUrl: client.constants.BACKEND_URL, loginToken: loginToken })), showChatHistoryDrawer && (_jsx(ChatHistoryDrawer, { open: !!showChatHistoryDrawer, onClose: () => setShowChatHistoryDrawer(false), resumeSession: chatLog => {
2272
+ setChatLogID(chatLog.chatLogID);
2273
+ onClickStart(undefined, false, chatLog);
2274
+ setShowChatHistoryDrawer(false);
2565
2275
  }, apiClient: client, sessionId: sessionId || '', memori: memori, baseUrl: baseUrl, history: history, apiUrl: client.constants.BACKEND_URL, loginToken: loginToken })), showPositionDrawer && (_jsx(PositionDrawer, { memori: memori, open: !!showPositionDrawer, venue: position, setVenue: setPosition, onClose: position => {
2566
2276
  if (position)
2567
2277
  applyPosition(position);
@@ -2585,7 +2295,10 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
2585
2295
  userToken = undefined;
2586
2296
  removeLocalConfig('loginToken');
2587
2297
  });
2588
- } }))] }));
2298
+ } })), error && (_jsx(Alert, { open: !!error, onClose: () => {
2299
+ setError(null);
2300
+ window.open('chrome://settings/content/autoplay', '_blank');
2301
+ }, title: "Error", description: error.message, type: "error" }))] }));
2589
2302
  };
2590
2303
  export default MemoriWidget;
2591
2304
  //# sourceMappingURL=MemoriWidget.js.map