@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
@@ -33,10 +33,13 @@ const ZoomedFullBody_1 = tslib_1.__importDefault(require("../layouts/ZoomedFullB
33
33
  const translations_1 = require("../../helpers/translations");
34
34
  const configuration_1 = require("../../helpers/configuration");
35
35
  const utils_1 = require("../../helpers/utils");
36
+ const ttsVoiceUtility_1 = require("../../helpers/tts/ttsVoiceUtility");
36
37
  const constants_1 = require("../../helpers/constants");
37
38
  const error_1 = require("../../helpers/error");
38
39
  const credits_1 = require("../../helpers/credits");
39
- const visemeContext_1 = require("../../context/visemeContext");
40
+ const sanitizer_1 = require("../../helpers/sanitizer");
41
+ const useTTS_1 = require("../../helpers/tts/useTTS");
42
+ const Alert_1 = tslib_1.__importDefault(require("../ui/Alert"));
40
43
  const ChatHistory_1 = tslib_1.__importDefault(require("../ChatHistoryDrawer/ChatHistory"));
41
44
  const getMemoriState = (integrationId) => {
42
45
  var _a, _b, _c, _d, _f;
@@ -154,14 +157,11 @@ window.typeMessageHidden = typeMessageHidden;
154
157
  window.typeBatchMessages = typeBatchMessages;
155
158
  let recognizer;
156
159
  let speechConfig;
157
- let speechSynthesizer;
158
160
  let audioDestination;
159
161
  let audioContext;
160
162
  let memoriPassword;
161
- let speakerMuted = false;
162
- let memoriSpeaking = false;
163
163
  let userToken;
164
- 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, }) => {
164
+ 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, }) => {
165
165
  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;
166
166
  const { t, i18n } = (0, react_i18next_1.useTranslation)();
167
167
  const [isClient, setIsClient] = (0, react_1.useState)(false);
@@ -227,25 +227,23 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
227
227
  const [typingText, setTypingText] = (0, react_1.useState)();
228
228
  const selectedLayout = layout || (integrationConfig === null || integrationConfig === void 0 ? void 0 : integrationConfig.layout) || 'DEFAULT';
229
229
  const defaultEnableAudio = (_p = enableAudio !== null && enableAudio !== void 0 ? enableAudio : integrationConfig === null || integrationConfig === void 0 ? void 0 : integrationConfig.enableAudio) !== null && _p !== void 0 ? _p : false;
230
- const [hasUserActivatedSpeak, setHasUserActivatedSpeak] = (0, react_1.useState)(false);
231
230
  const [hasUserActivatedListening, setHasUserActivatedListening] = (0, react_1.useState)(false);
232
231
  const [showPositionDrawer, setShowPositionDrawer] = (0, react_1.useState)(false);
233
232
  const [showSettingsDrawer, setShowSettingsDrawer] = (0, react_1.useState)(false);
234
233
  const [showChatHistoryDrawer, setShowChatHistoryDrawer] = (0, react_1.useState)(false);
235
234
  const [showKnownFactsDrawer, setShowKnownFactsDrawer] = (0, react_1.useState)(false);
236
235
  const [showExpertsDrawer, setShowExpertsDrawer] = (0, react_1.useState)(false);
237
- const [muteSpeaker, setMuteSpeaker] = (0, react_1.useState)(!defaultEnableAudio || !defaultSpeakerActive || autoStart);
238
236
  const [continuousSpeech, setContinuousSpeech] = (0, react_1.useState)(false);
239
237
  const [continuousSpeechTimeout, setContinuousSpeechTimeout] = (0, react_1.useState)(2);
240
- const [isPlayingAudio, setIsPlayingAudio] = (0, react_1.useState)(false);
241
238
  const [controlsPosition, setControlsPosition] = (0, react_1.useState)('center');
242
239
  const [enablePositionControls, setEnablePositionControls] = (0, react_1.useState)(false);
243
240
  const [avatarType, setAvatarType] = (0, react_1.useState)(null);
244
241
  const [hideEmissions, setHideEmissions] = (0, react_1.useState)(false);
245
- const { startProcessing, setAudioContext, addViseme, stopProcessing, resetVisemeQueue, } = (0, visemeContext_1.useViseme)();
242
+ const speechSynthesizerRef = (0, react_1.useRef)(null);
243
+ const [memoriSpeaking, setMemoriSpeaking] = (0, react_1.useState)(false);
246
244
  (0, react_1.useEffect)(() => {
247
- memoriSpeaking = !!speechSynthesizer;
248
- }, [speechSynthesizer]);
245
+ setMemoriSpeaking(!!speechSynthesizerRef.current);
246
+ }, [speechSynthesizerRef.current]);
249
247
  (0, react_1.useEffect)(() => {
250
248
  let defaultControlsPosition = 'bottom';
251
249
  let microphoneMode = (0, configuration_1.getLocalConfig)('microphoneMode', 'HOLD_TO_TALK');
@@ -260,11 +258,7 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
260
258
  else {
261
259
  defaultControlsPosition = 'bottom';
262
260
  }
263
- const muteSpeaker = autoStart ||
264
- (0, configuration_1.getLocalConfig)('muteSpeaker', !defaultEnableAudio || !defaultSpeakerActive || autoStart);
265
- setMuteSpeaker(muteSpeaker);
266
- speakerMuted = muteSpeaker;
267
- setContinuousSpeech(muteSpeaker ? false : microphoneMode === 'CONTINUOUS');
261
+ setContinuousSpeech(speakerMuted ? false : microphoneMode === 'CONTINUOUS');
268
262
  setContinuousSpeechTimeout((0, configuration_1.getLocalConfig)('continuousSpeechTimeout', 2));
269
263
  setControlsPosition((0, configuration_1.getLocalConfig)('controlsPosition', defaultControlsPosition));
270
264
  setAvatarType((0, configuration_1.getLocalConfig)('avatarType', 'avatar3d'));
@@ -399,7 +393,7 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
399
393
  translateDialogState(currentState, userLang, msg).then(ts => {
400
394
  let text = ts.translatedEmission || ts.emission;
401
395
  if (text) {
402
- speak(text);
396
+ handleSpeak(text);
403
397
  }
404
398
  });
405
399
  }
@@ -425,7 +419,7 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
425
419
  tag: currentState.currentTag,
426
420
  memoryTags: currentState.memoryTags,
427
421
  });
428
- speak(emission);
422
+ handleSpeak(emission);
429
423
  }
430
424
  }
431
425
  }
@@ -1019,6 +1013,44 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
1019
1013
  timeoutRef.current = undefined;
1020
1014
  }
1021
1015
  };
1016
+ (0, react_1.useEffect)(() => {
1017
+ return () => {
1018
+ setHasUserActivatedSpeak(false);
1019
+ setClickedStart(false);
1020
+ clearInteractionTimeout();
1021
+ timeoutRef.current = undefined;
1022
+ };
1023
+ }, []);
1024
+ const [requestedListening, setRequestedListening] = (0, react_1.useState)(false);
1025
+ const onEndSpeakStartListen = (0, react_1.useCallback)((_e) => {
1026
+ if (isPlayingAudio && speechSynthesizerRef.current) {
1027
+ speechSynthesizerRef.current.close();
1028
+ speechSynthesizerRef.current = null;
1029
+ }
1030
+ if (continuousSpeech &&
1031
+ (hasUserActivatedListening || !requestedListening)) {
1032
+ setRequestedListening(true);
1033
+ startListening();
1034
+ }
1035
+ }, [continuousSpeech, hasUserActivatedListening]);
1036
+ const audioPlaybackOptions = (0, react_1.useMemo)(() => ({
1037
+ apiUrl: apiURL,
1038
+ continuousSpeech: continuousSpeech,
1039
+ onEndSpeakStartListen: onEndSpeakStartListen,
1040
+ preview: preview,
1041
+ }), [apiURL, continuousSpeech, preview, onEndSpeakStartListen]);
1042
+ console.log('tenantID', tenantID);
1043
+ const ttsConfig = (0, react_1.useMemo)(() => {
1044
+ var _a, _b;
1045
+ return ({
1046
+ provider: ttsProvider,
1047
+ voice: (0, ttsVoiceUtility_1.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),
1048
+ tenant: tenantID,
1049
+ region: 'westeurope',
1050
+ voiceType: memori.voiceType
1051
+ });
1052
+ }, [ttsProvider, userLang, memori.culture, memori.voiceType]);
1053
+ const { speak: ttsSpeak, stop: ttsStop, isPlaying: isPlayingAudio, speakerMuted, toggleMute, hasUserActivatedSpeak, setHasUserActivatedSpeak, error, setError, } = (0, useTTS_1.useTTS)(ttsConfig, audioPlaybackOptions, autoStart, defaultEnableAudio, defaultSpeakerActive);
1022
1054
  const resetInteractionTimeout = () => {
1023
1055
  clearInteractionTimeout();
1024
1056
  if (!isPlayingAudio && !userMessage.length && !memoriTyping && !listening)
@@ -1047,7 +1079,7 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
1047
1079
  translateDialogState({ ...currentState, emission: emission }, userLang).then(ts => {
1048
1080
  let text = ts.translatedEmission || ts.emission;
1049
1081
  if (text) {
1050
- speak(text);
1082
+ handleSpeak(text);
1051
1083
  }
1052
1084
  });
1053
1085
  }
@@ -1067,7 +1099,7 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
1067
1099
  tag: currentState.currentTag,
1068
1100
  memoryTags: currentState.memoryTags,
1069
1101
  });
1070
- speak(emission);
1102
+ handleSpeak(emission);
1071
1103
  setCurrentDialogState({
1072
1104
  ...currentState,
1073
1105
  hints: (_b = currentState.hints) !== null && _b !== void 0 ? _b : (currentState.state === 'G1' ? currentDialogState === null || currentDialogState === void 0 ? void 0 : currentDialogState.hints : []),
@@ -1120,97 +1152,6 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
1120
1152
  memoriTyping,
1121
1153
  hasUserActivatedSpeak,
1122
1154
  ]);
1123
- (0, react_1.useEffect)(() => {
1124
- return () => {
1125
- setHasUserActivatedSpeak(false);
1126
- setClickedStart(false);
1127
- clearInteractionTimeout();
1128
- timeoutRef.current = undefined;
1129
- };
1130
- }, []);
1131
- const initializeTTS = () => {
1132
- if (!AZURE_COGNITIVE_SERVICES_TTS_KEY)
1133
- return;
1134
- speechConfig = speechSdk.SpeechConfig.fromSubscription(AZURE_COGNITIVE_SERVICES_TTS_KEY, 'westeurope');
1135
- speechConfig.speechSynthesisLanguage = getCultureCodeByLanguage(userLang);
1136
- speechConfig.speechSynthesisVoiceName = getTTSVoice(userLang);
1137
- speechConfig.speechRecognitionLanguage = getCultureCodeByLanguage(userLang);
1138
- speechConfig.setProperty('speechSynthesis.outputFormat', 'viseme');
1139
- if ((0, utils_1.hasTouchscreen)())
1140
- speechConfig.speechSynthesisOutputFormat =
1141
- speechSdk.SpeechSynthesisOutputFormat.Audio16Khz32KBitRateMonoMp3;
1142
- audioContext = new standardized_audio_context_1.AudioContext();
1143
- let buffer = audioContext.createBuffer(1, 10000, 22050);
1144
- let source = audioContext.createBufferSource();
1145
- source.buffer = buffer;
1146
- source.connect(audioContext.destination);
1147
- audioDestination = new speechSdk.SpeakerAudioDestination();
1148
- let audioConfig = speechSdk.AudioConfig.fromSpeakerOutput(audioDestination);
1149
- speechSynthesizer = new speechSdk.SpeechSynthesizer(speechConfig, audioConfig);
1150
- };
1151
- const getTTSVoice = (0, react_1.useCallback)((lang) => {
1152
- var _a, _b, _c, _d;
1153
- let voice = '';
1154
- 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();
1155
- let voiceType = memori.voiceType;
1156
- if (memori.enableBoardOfExperts && (currentDialogState === null || currentDialogState === void 0 ? void 0 : currentDialogState.emitter)) {
1157
- let expert = experts === null || experts === void 0 ? void 0 : experts.find(e => e.name === (currentDialogState === null || currentDialogState === void 0 ? void 0 : currentDialogState.emitter));
1158
- }
1159
- switch (voiceLang) {
1160
- case 'IT':
1161
- voice = `${voiceType === 'MALE' ? 'it-IT-DiegoNeural' : 'it-IT-ElsaNeural'}`;
1162
- break;
1163
- case 'DE':
1164
- voice = `${voiceType === 'MALE' ? 'de-DE-ConradNeural' : 'de-DE-KatjaNeural'}`;
1165
- break;
1166
- case 'EN':
1167
- voice = `${voiceType === 'MALE' ? 'en-GB-RyanNeural' : 'en-GB-SoniaNeural'}`;
1168
- break;
1169
- case 'ES':
1170
- voice = `${voiceType === 'MALE' ? 'es-ES-AlvaroNeural' : 'es-ES-ElviraNeural'}`;
1171
- break;
1172
- case 'FR':
1173
- voice = `${voiceType === 'MALE' ? 'fr-FR-HenriNeural' : 'fr-FR-DeniseNeural'}`;
1174
- break;
1175
- case 'PT':
1176
- voice = `${voiceType === 'MALE' ? 'pt-PT-DuarteNeural' : 'pt-PT-RaquelNeural'}`;
1177
- break;
1178
- case 'UK':
1179
- voice = `${voiceType === 'MALE' ? 'uk-UA-OstapNeural' : 'uk-UA-PolinaNeural'}`;
1180
- break;
1181
- case 'RU':
1182
- voice = `${voiceType === 'MALE' ? 'ru-RU-DmitryNeural' : 'ru-RU-SvetlanaNeural'}`;
1183
- break;
1184
- case 'PL':
1185
- voice = `${voiceType === 'MALE' ? 'pl-PL-MarekNeural' : 'pl-PL-AgnieszkaNeural'}`;
1186
- break;
1187
- case 'FI':
1188
- voice = `${voiceType === 'MALE' ? 'fi-FI-HarriNeural' : 'fi-FI-SelmaNeural'}`;
1189
- break;
1190
- case 'EL':
1191
- voice = `${voiceType === 'MALE' ? 'el-GR-NestorasNeural' : 'el-GR-AthinaNeural'}`;
1192
- break;
1193
- case 'AR':
1194
- voice = `${voiceType === 'MALE' ? 'ar-SA-HamedNeural' : 'ar-SA-ZariyahNeural'}`;
1195
- break;
1196
- case 'ZH':
1197
- voice = `${voiceType === 'MALE' ? 'zh-CN-YunxiNeural' : 'zh-CN-XiaoxiaoNeural'}`;
1198
- break;
1199
- case 'JA':
1200
- voice = `${voiceType === 'MALE' ? 'ja-JP-KeitaNeural' : 'ja-JP-NanamiNeural'}`;
1201
- break;
1202
- default:
1203
- voice = `${voiceType === 'MALE' ? 'it-IT-DiegoNeural' : 'it-IT-IsabellaNeural'}`;
1204
- break;
1205
- }
1206
- return voice;
1207
- }, [
1208
- memori.voiceType,
1209
- memori.enableBoardOfExperts,
1210
- currentDialogState === null || currentDialogState === void 0 ? void 0 : currentDialogState.emitter,
1211
- i18n.language,
1212
- memori.culture,
1213
- ]);
1214
1155
  const getCultureCodeByLanguage = (lang) => {
1215
1156
  var _a, _b;
1216
1157
  let voice = '';
@@ -1267,185 +1208,58 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
1267
1208
  }
1268
1209
  return voice;
1269
1210
  };
1270
- const [phonemesMap, setPhonemesMap] = (0, react_1.useState)();
1271
- const fetchLexiconJSON = async () => {
1272
- try {
1273
- const lexiconReq = await fetch(`${baseUrl || 'https://aisuru.com'}/api/lexiconmap`);
1274
- const lexicon = await lexiconReq.json();
1275
- return lexicon;
1276
- }
1277
- catch (err) {
1278
- console.error(err);
1279
- }
1280
- };
1281
- (0, react_1.useEffect)(() => {
1282
- fetchLexiconJSON().then(lexicon => {
1283
- setPhonemesMap(lexicon);
1284
- });
1285
- }, []);
1286
- const replaceTextWithPhonemes = (text, lang) => {
1287
- var _a;
1288
- if (!phonemesMap)
1289
- return text;
1290
- const phonemes = {
1291
- ...((_a = phonemesMap.common) !== null && _a !== void 0 ? _a : {}),
1292
- ...((tenant === null || tenant === void 0 ? void 0 : tenant.name) && phonemesMap[tenant.name]
1293
- ? phonemesMap[tenant.name]
1294
- : {}),
1295
- };
1296
- const phonemesPairs = Object.keys(phonemes).map(word => {
1297
- var _a;
1298
- const phoneme = (_a = phonemes[word][lang.toLowerCase()]) !== null && _a !== void 0 ? _a : phonemes[word].default;
1299
- return { word, phoneme, caseSensitive: phonemes[word].caseSensitive };
1300
- });
1301
- const ssmlText = phonemesPairs.reduce((acc, { word, phoneme, caseSensitive }) => {
1302
- return acc.replace(new RegExp(`\\b${word}\\b`, caseSensitive ? 'g' : 'gi'), `<phoneme alphabet="ipa" ph="${phoneme}">${word}</phoneme>`);
1303
- }, text);
1304
- return ssmlText;
1305
- };
1306
- const emitEndSpeakEvent = () => {
1307
- const e = new CustomEvent('MemoriEndSpeak');
1308
- document.dispatchEvent(e);
1309
- };
1310
- const speak = (text) => {
1311
- console.debug('speak called with text:', text);
1312
- if (!AZURE_COGNITIVE_SERVICES_TTS_KEY || preview) {
1313
- console.debug('No TTS key or preview mode, emitting end speak event');
1314
- emitEndSpeakEvent();
1315
- return;
1316
- }
1317
- console.debug('Stopping listening before speaking');
1318
- stopListening();
1319
- if (preview) {
1320
- console.debug('Preview mode, returning early');
1321
- return;
1322
- }
1323
- if (speakerMuted) {
1324
- console.debug('Speaker muted, skipping speech synthesis');
1325
- memoriSpeaking = false;
1326
- setMemoriTyping(false);
1327
- emitEndSpeakEvent();
1211
+ const handleSpeak = async (text) => {
1212
+ if (!text || preview || speakerMuted) {
1213
+ const e = new CustomEvent('MemoriEndSpeak');
1214
+ document.dispatchEvent(e);
1328
1215
  if (continuousSpeech) {
1329
- console.debug('Setting listening timeout for continuous speech');
1330
1216
  setListeningTimeout();
1331
1217
  }
1332
- return;
1333
- }
1334
- if (audioDestination) {
1335
- console.debug('Pausing existing audio destination');
1336
- audioDestination.pause();
1337
- }
1338
- let isSafari = window.navigator.userAgent.includes('Safari') &&
1339
- !window.navigator.userAgent.includes('Chrome');
1340
- let isIOS = /iPad|iPhone|iPod/.test(navigator.userAgent);
1341
- console.debug('Browser detection - Safari:', isSafari, 'iOS:', isIOS);
1342
- if (audioContext.state === 'interrupted') {
1343
- console.debug('Audio context interrupted, attempting resume');
1344
- audioContext.resume().then(() => speak(text));
1345
- return;
1218
+ return Promise.resolve();
1346
1219
  }
1347
- if (audioContext.state === 'closed') {
1348
- console.debug('Audio context closed, creating new context');
1349
- audioContext = new standardized_audio_context_1.AudioContext();
1350
- let buffer = audioContext.createBuffer(1, 10000, 22050);
1351
- let source = audioContext.createBufferSource();
1352
- source.buffer = buffer;
1353
- source.connect(audioContext.destination);
1220
+ if (typeof stopListening === 'function') {
1221
+ stopListening();
1354
1222
  }
1355
- else if (audioContext.state === 'suspended') {
1356
- console.debug('Audio context suspended, stopping audio and creating new context');
1357
- stopAudio();
1358
- audioContext = new standardized_audio_context_1.AudioContext();
1359
- let buffer = audioContext.createBuffer(1, 10000, 22050);
1360
- let source = audioContext.createBufferSource();
1361
- source.buffer = buffer;
1362
- source.connect(audioContext.destination);
1363
- }
1364
- if (!speechSynthesizer) {
1365
- initializeTTS();
1366
- }
1367
- const source = audioContext.createBufferSource();
1368
- source.addEventListener('ended', () => {
1369
- console.debug('Audio source ended');
1370
- setIsPlayingAudio(false);
1371
- memoriSpeaking = false;
1223
+ setMemoriTyping(true);
1224
+ const processedText = (0, sanitizer_1.sanitizeText)(text);
1225
+ return ttsSpeak(processedText)
1226
+ .then(() => {
1227
+ setMemoriTyping(false);
1228
+ })
1229
+ .catch(error => {
1230
+ setMemoriTyping(false);
1231
+ throw error;
1372
1232
  });
1373
- audioDestination.onAudioEnd = () => {
1374
- console.debug('Audio destination ended');
1375
- setIsPlayingAudio(false);
1376
- memoriSpeaking = false;
1377
- source.disconnect();
1378
- emitEndSpeakEvent();
1379
- onEndSpeakStartListen();
1380
- };
1381
- console.debug('Resetting viseme queue');
1382
- resetVisemeQueue();
1383
- if (speechSynthesizer) {
1384
- speechSynthesizer.visemeReceived = function (_, e) {
1385
- console.debug('Viseme received:', e.visemeId, 'at offset:', e.audioOffset);
1386
- addViseme(e.visemeId, e.audioOffset);
1387
- };
1233
+ };
1234
+ const translateAndSpeak = (0, react_1.useCallback)(async (dialogState, language, msg, skipEmission = false) => {
1235
+ try {
1236
+ if (!dialogState) {
1237
+ console.warn('translateAndSpeak called with empty dialog state');
1238
+ return null;
1239
+ }
1240
+ const translatedState = await translateDialogState(dialogState, language, msg, skipEmission);
1241
+ const textToSpeak = translatedState.translatedEmission || translatedState.emission;
1242
+ if (textToSpeak && !skipEmission) {
1243
+ if (!hasUserActivatedSpeak) {
1244
+ setHasUserActivatedSpeak(true);
1245
+ }
1246
+ await handleSpeak(textToSpeak);
1247
+ }
1248
+ return translatedState;
1388
1249
  }
1389
- const textToSpeak = (0, utils_1.escapeHTML)((0, utils_1.stripMarkdown)((0, utils_1.stripEmojis)((0, utils_1.stripHTML)((0, utils_1.stripReasoningTags)((0, utils_1.stripOutputTags)(text))))));
1390
- console.debug('Processed text to speak:', textToSpeak);
1391
- setTimeout(() => {
1392
- if (speechSynthesizer) {
1393
- console.debug('Starting speech synthesis');
1394
- 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 => {
1395
- if (result) {
1396
- console.debug('Speech synthesis successful');
1397
- setIsPlayingAudio(true);
1398
- memoriSpeaking = true;
1399
- startProcessing(audioContext);
1400
- try {
1401
- console.debug('Decoding audio data');
1402
- audioContext.decodeAudioData(result.audioData, function (buffer) {
1403
- console.debug('Audio data decoded successfully');
1404
- source.buffer = buffer;
1405
- source.connect(audioContext.destination);
1406
- if (history.length < 1 || (isSafari && isIOS)) {
1407
- console.debug('Starting audio playback');
1408
- source.start(0);
1409
- }
1410
- });
1411
- audioContext.onstatechange = () => {
1412
- console.debug('Audio context state changed to:', audioContext.state);
1413
- if (audioContext.state === 'suspended' ||
1414
- audioContext.state === 'closed') {
1415
- source.disconnect();
1416
- setIsPlayingAudio(false);
1417
- stopProcessing();
1418
- resetVisemeQueue();
1419
- memoriSpeaking = false;
1420
- }
1421
- else if (audioContext.state === 'interrupted') {
1422
- audioContext.resume();
1423
- }
1424
- };
1425
- audioContext.resume();
1426
- if (speechSynthesizer) {
1427
- console.debug('Closing speech synthesizer');
1428
- speechSynthesizer.close();
1429
- speechSynthesizer = null;
1430
- }
1431
- }
1432
- catch (error) {
1433
- console.error('Error processing audio data:', error);
1434
- handleFallback(text);
1435
- }
1436
- }
1437
- else {
1438
- console.debug('No result from speech synthesis, using fallback');
1439
- handleFallback(text);
1440
- }
1441
- }, error => {
1442
- console.error('Speak error:', error);
1443
- handleFallback(text);
1444
- });
1250
+ catch (error) {
1251
+ console.error('Error in translateAndSpeak:', error);
1252
+ if (!hasUserActivatedSpeak) {
1253
+ setHasUserActivatedSpeak(true);
1445
1254
  }
1446
- }, 100);
1447
- setMemoriTyping(false);
1448
- };
1255
+ return dialogState;
1256
+ }
1257
+ }, [
1258
+ translateDialogState,
1259
+ handleSpeak,
1260
+ hasUserActivatedSpeak,
1261
+ setHasUserActivatedSpeak,
1262
+ ]);
1449
1263
  const handleFallback = (text) => {
1450
1264
  window.speechSynthesis.speak(new SpeechSynthesisUtterance(text));
1451
1265
  cleanup();
@@ -1456,39 +1270,16 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
1456
1270
  recognizer.close();
1457
1271
  recognizer = null;
1458
1272
  }
1459
- if (speechSynthesizer) {
1460
- speechSynthesizer.close();
1461
- speechSynthesizer = null;
1273
+ if (speechSynthesizerRef.current) {
1274
+ speechSynthesizerRef.current.close();
1275
+ speechSynthesizerRef.current = null;
1462
1276
  }
1463
1277
  setListening(false);
1464
1278
  clearListeningTimeout();
1465
1279
  };
1466
- const stopAudio = async () => {
1467
- setIsPlayingAudio(false);
1468
- memoriSpeaking = false;
1469
- try {
1470
- if (speechSynthesizer) {
1471
- const currentSynthesizer = speechSynthesizer;
1472
- speechSynthesizer = null;
1473
- try {
1474
- currentSynthesizer.close();
1475
- }
1476
- catch (e) {
1477
- console.debug('Error closing speech synthesizer:', e);
1478
- }
1479
- }
1480
- if ((audioContext === null || audioContext === void 0 ? void 0 : audioContext.state) !== 'closed') {
1481
- audioContext.close();
1482
- }
1483
- if (audioDestination) {
1484
- audioDestination.pause();
1485
- audioDestination.close();
1486
- }
1487
- }
1488
- catch (e) {
1489
- console.debug('stopAudio error: ', e);
1490
- }
1491
- };
1280
+ const stopAudio = (0, react_1.useCallback)(async () => {
1281
+ ttsStop();
1282
+ }, [ttsStop]);
1492
1283
  const focusChatInput = () => {
1493
1284
  let textarea = document.querySelector('#chat-fieldset textarea');
1494
1285
  if (textarea && enableFocusChatInput) {
@@ -1547,10 +1338,6 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
1547
1338
  let microphoneStream = null;
1548
1339
  const startListening = async () => {
1549
1340
  console.debug('Starting speech recognition...');
1550
- if (!AZURE_COGNITIVE_SERVICES_TTS_KEY) {
1551
- console.error('No TTS key available');
1552
- throw new Error('No TTS key available');
1553
- }
1554
1341
  if (!sessionId) {
1555
1342
  console.error('No session ID available');
1556
1343
  throw new Error('No session ID available');
@@ -1588,7 +1375,6 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
1588
1375
  });
1589
1376
  setHasUserActivatedListening(true);
1590
1377
  console.debug('Setting up speech config...');
1591
- speechConfig = setupSpeechConfig(AZURE_COGNITIVE_SERVICES_TTS_KEY);
1592
1378
  console.debug('Creating audio config and recognizer...');
1593
1379
  const audioConfig = speechSdk.AudioConfig.fromDefaultMicrophoneInput();
1594
1380
  recognizer = new speechSdk.SpeechRecognizer(speechConfig, audioConfig);
@@ -1621,7 +1407,7 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
1621
1407
  console.debug('Setting speech recognition language:', userLang);
1622
1408
  speechConfig.speechRecognitionLanguage = getCultureCodeByLanguage(userLang);
1623
1409
  speechConfig.speechSynthesisLanguage = getCultureCodeByLanguage(userLang);
1624
- speechConfig.speechSynthesisVoiceName = getTTSVoice(userLang);
1410
+ speechConfig.speechSynthesisVoiceName = (0, ttsVoiceUtility_1.getTTSVoice)(userLang);
1625
1411
  return speechConfig;
1626
1412
  };
1627
1413
  const [isProcessingSTT, setIsProcessingSTT] = (0, react_1.useState)(false);
@@ -1742,18 +1528,6 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
1742
1528
  if ((currentDialogState === null || currentDialogState === void 0 ? void 0 : currentDialogState.state) === 'Z0')
1743
1529
  clearListening();
1744
1530
  }, [currentDialogState === null || currentDialogState === void 0 ? void 0 : currentDialogState.state]);
1745
- const [requestedListening, setRequestedListening] = (0, react_1.useState)(false);
1746
- const onEndSpeakStartListen = (0, react_1.useCallback)((_e) => {
1747
- if (isPlayingAudio && speechSynthesizer) {
1748
- speechSynthesizer.close();
1749
- speechSynthesizer = null;
1750
- }
1751
- if (continuousSpeech &&
1752
- (hasUserActivatedListening || !requestedListening)) {
1753
- setRequestedListening(true);
1754
- startListening();
1755
- }
1756
- }, [continuousSpeech, hasUserActivatedListening]);
1757
1531
  (0, react_1.useEffect)(() => {
1758
1532
  if (!isPlayingAudio &&
1759
1533
  continuousSpeech &&
@@ -1924,7 +1698,7 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
1924
1698
  if (memoriAudioElement && isSafari) {
1925
1699
  memoriAudioElement.muted = false;
1926
1700
  memoriAudioElement.play().catch((e) => {
1927
- console.warn('error playing intro audio', e);
1701
+ console.warn('[CLICK_START] Error playing intro audio:', e);
1928
1702
  });
1929
1703
  }
1930
1704
  let storageBirthDate = (0, configuration_1.getLocalConfig)('birthDate', undefined);
@@ -1933,7 +1707,6 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
1933
1707
  birth = '1970-01-01T10:24:03.845Z';
1934
1708
  const localPosition = (0, configuration_1.getLocalConfig)('position', undefined);
1935
1709
  if (autoStart && !localPosition && memori.needsPosition) {
1936
- console.log('position required', localPosition);
1937
1710
  setShowPositionDrawer(true);
1938
1711
  return;
1939
1712
  }
@@ -1979,16 +1752,8 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
1979
1752
  if (session === null || session === void 0 ? void 0 : session.dialogState) {
1980
1753
  if (!chatLog) {
1981
1754
  setHistory([]);
1982
- translateDialogState(session.dialogState, userLang)
1983
- .then(ts => {
1984
- let text = ts.translatedEmission || ts.emission;
1985
- if (text) {
1986
- speak(text);
1987
- }
1988
- })
1989
- .finally(() => {
1990
- setHasUserActivatedSpeak(true);
1991
- });
1755
+ await translateAndSpeak(session.dialogState, userLang);
1756
+ setHasUserActivatedSpeak(true);
1992
1757
  }
1993
1758
  else {
1994
1759
  const messages = chatLog.lines.map((l, i) => {
@@ -2009,7 +1774,6 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
2009
1774
  if (language.toUpperCase() !== userLang.toUpperCase() &&
2010
1775
  isMultilanguageEnabled) {
2011
1776
  try {
2012
- console.debug('[CLICK_START] Translating messages');
2013
1777
  translatedMessages = await Promise.all(messages.map(async (m) => ({
2014
1778
  ...m,
2015
1779
  originalText: m.text,
@@ -2017,6 +1781,7 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
2017
1781
  })));
2018
1782
  }
2019
1783
  catch (e) {
1784
+ console.error('[CLICK_START] Error translating messages:', e);
2020
1785
  }
2021
1786
  }
2022
1787
  setHistory(translatedMessages);
@@ -2034,10 +1799,8 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
2034
1799
  return;
2035
1800
  }
2036
1801
  else if (initialSessionID) {
2037
- console.debug('[CLICK_START] Handling initial session');
2038
1802
  const { currentState, ...response } = await getSession(sessionID);
2039
1803
  if (response.resultCode !== 0 || !currentState) {
2040
- console.debug('[CLICK_START] Session expired, opening new session');
2041
1804
  setGotErrorInOpening(true);
2042
1805
  setSessionId(undefined);
2043
1806
  setClickedStart(false);
@@ -2045,35 +1808,25 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
2045
1808
  return;
2046
1809
  }
2047
1810
  setHistory([]);
2048
- if (position && memori.needsPosition)
1811
+ if (position && memori.needsPosition) {
2049
1812
  applyPosition(position, sessionID);
2050
- if (memori.needsDateTime)
1813
+ }
1814
+ if (memori.needsDateTime) {
2051
1815
  sendDateChangedEvent({ sessionID: sessionID, state: currentState });
1816
+ }
2052
1817
  if (personification &&
2053
1818
  currentState.currentTag !== personification.tag) {
2054
1819
  try {
2055
- console.debug('[CLICK_START] Changing tag for personification', personification, currentState);
2056
1820
  await changeTag(memori.engineMemoriID, sessionID, '-');
2057
1821
  const session = await changeTag(memori.engineMemoriID, sessionID, personification.tag, personification.pin);
2058
1822
  if (session && session.resultCode === 0) {
2059
- translateDialogState(session.currentState, userLang)
2060
- .then(ts => {
2061
- let text = ts.translatedEmission || ts.emission;
2062
- if (text) {
2063
- speak(text);
2064
- }
2065
- })
2066
- .finally(() => {
2067
- setHasUserActivatedSpeak(true);
2068
- });
1823
+ await translateAndSpeak(session.currentState, userLang);
2069
1824
  }
2070
1825
  else {
2071
- console.error('[CLICK_START] Session error:', session);
2072
1826
  throw new Error('No session');
2073
1827
  }
2074
1828
  }
2075
1829
  catch (e) {
2076
- console.error('[CLICK_START] Error changing tag:', e);
2077
1830
  reopenSession(true, memori === null || memori === void 0 ? void 0 : memori.secretToken, undefined, personification.tag, personification.pin, {
2078
1831
  PATHNAME: (_h = window.location.pathname) === null || _h === void 0 ? void 0 : _h.toUpperCase(),
2079
1832
  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()) ||
@@ -2089,28 +1842,16 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
2089
1842
  (currentState === null || currentState === void 0 ? void 0 : currentState.currentTag) !== constants_1.anonTag &&
2090
1843
  (currentState === null || currentState === void 0 ? void 0 : currentState.currentTag) !== '-') {
2091
1844
  try {
2092
- console.debug('[CLICK_START] Changing to anonymous tag');
2093
1845
  await changeTag(memori.engineMemoriID, sessionID, '-');
2094
1846
  const session = await changeTag(memori.engineMemoriID, sessionID, constants_1.anonTag);
2095
1847
  if (session && session.resultCode === 0) {
2096
- translateDialogState(session.currentState, userLang)
2097
- .then(ts => {
2098
- let text = ts.translatedEmission || ts.emission;
2099
- if (text) {
2100
- speak(text);
2101
- }
2102
- })
2103
- .finally(() => {
2104
- setHasUserActivatedSpeak(true);
2105
- });
1848
+ await translateAndSpeak(session.currentState, userLang);
2106
1849
  }
2107
1850
  else {
2108
- console.error('[CLICK_START] Session error:', session);
2109
1851
  throw new Error('No session');
2110
1852
  }
2111
1853
  }
2112
1854
  catch (e) {
2113
- console.error('[CLICK_START] Error changing tag:', e);
2114
1855
  reopenSession(true, memori === null || memori === void 0 ? void 0 : memori.secretToken, undefined, undefined, undefined, {
2115
1856
  PATHNAME: (_m = window.location.pathname) === null || _m === void 0 ? void 0 : _m.toUpperCase(),
2116
1857
  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()) ||
@@ -2123,8 +1864,7 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
2123
1864
  }
2124
1865
  else {
2125
1866
  try {
2126
- console.debug('[CLICK_START] Getting chat history');
2127
- const { chatLogs, ...resp } = await getSessionChatLogs(sessionID, sessionID);
1867
+ const { chatLogs } = await getSessionChatLogs(sessionID, sessionID);
2128
1868
  const messages = (_r = chatLogs === null || chatLogs === void 0 ? void 0 : chatLogs[0]) === null || _r === void 0 ? void 0 : _r.lines.map((l, i) => {
2129
1869
  var _a, _b;
2130
1870
  return ({
@@ -2143,7 +1883,6 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
2143
1883
  if (language.toUpperCase() !== userLang.toUpperCase() &&
2144
1884
  isMultilanguageEnabled) {
2145
1885
  try {
2146
- console.debug('[CLICK_START] Translating messages');
2147
1886
  translatedMessages = await Promise.all(messages.map(async (m) => ({
2148
1887
  ...m,
2149
1888
  originalText: m.text,
@@ -2151,30 +1890,19 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
2151
1890
  })));
2152
1891
  }
2153
1892
  catch (e) {
1893
+ console.error('[CLICK_START] Error translating messages:', e);
2154
1894
  }
2155
1895
  }
2156
1896
  setHistory(translatedMessages);
2157
- console.debug('[CLICK_START] props currentState:', currentState, 'userLang:', userLang, 'translatedMessages:', translatedMessages, 'history:', history);
2158
1897
  }
2159
1898
  catch (e) {
2160
- console.log('[CLICK_START] Error retrieving chat logs:', e);
1899
+ console.error('[CLICK_START] Error retrieving chat logs:', e);
2161
1900
  }
2162
1901
  if ((!!(translatedMessages === null || translatedMessages === void 0 ? void 0 : translatedMessages.length) && translatedMessages.length > 1) ||
2163
1902
  !initialQuestion) {
2164
- console.log('[CLICK_START] Using existing chat history');
2165
- translateDialogState(currentState, userLang, undefined, !!(translatedMessages === null || translatedMessages === void 0 ? void 0 : translatedMessages.length))
2166
- .then(ts => {
2167
- let text = ts.translatedEmission || ts.emission;
2168
- if (text) {
2169
- speak(text);
2170
- }
2171
- })
2172
- .finally(() => {
2173
- setHasUserActivatedSpeak(true);
2174
- });
1903
+ await translateAndSpeak(currentState, userLang, undefined, !!(translatedMessages === null || translatedMessages === void 0 ? void 0 : translatedMessages.length));
2175
1904
  }
2176
1905
  else {
2177
- console.log('[CLICK_START] Using existing chat history with message from initial question');
2178
1906
  translatedMessages = [];
2179
1907
  setHistory([]);
2180
1908
  setMemoriTyping(true);
@@ -2182,44 +1910,23 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
2182
1910
  sessionId: sessionID,
2183
1911
  text: initialQuestion,
2184
1912
  });
2185
- translateDialogState((_s = response.currentState) !== null && _s !== void 0 ? _s : currentState, userLang, undefined, false)
2186
- .then(ts => {
2187
- let text = ts.translatedEmission || ts.emission;
2188
- if (text) {
2189
- speak(text);
2190
- }
2191
- })
2192
- .finally(() => {
2193
- setMemoriTyping(false);
2194
- setHasUserActivatedSpeak(true);
2195
- });
1913
+ await translateAndSpeak((_s = response.currentState) !== null && _s !== void 0 ? _s : currentState, userLang, undefined, false);
2196
1914
  }
2197
1915
  }
2198
- if (position && memori.needsPosition)
1916
+ if (position && memori.needsPosition) {
2199
1917
  applyPosition(position, sessionID);
2200
- if (memori.needsDateTime)
1918
+ }
1919
+ if (memori.needsDateTime) {
2201
1920
  sendDateChangedEvent({ sessionID: sessionID, state: currentState });
1921
+ }
2202
1922
  }
2203
1923
  else {
2204
- console.debug('[CLICK_START] Using existing session');
2205
1924
  setHistory([]);
2206
- translateDialogState(dialogState, userLang)
2207
- .then(ts => {
2208
- let text = ts.translatedEmission || ts.emission;
2209
- if (text) {
2210
- speak(text);
2211
- }
2212
- })
2213
- .finally(() => {
2214
- setHasUserActivatedSpeak(true);
2215
- });
1925
+ await translateAndSpeak(dialogState, userLang);
2216
1926
  }
2217
1927
  }, [memoriPwd, memori, memoriTokens, birthDate, sessionId, userLang, position]);
2218
1928
  (0, react_1.useEffect)(() => {
2219
1929
  if (!clickedStart && autoStart) {
2220
- if (AZURE_COGNITIVE_SERVICES_TTS_KEY && !speechSynthesizer) {
2221
- initializeTTS();
2222
- }
2223
1930
  onClickStart();
2224
1931
  }
2225
1932
  }, [clickedStart, autoStart]);
@@ -2342,11 +2049,10 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
2342
2049
  setShowKnownFactsDrawer,
2343
2050
  setShowExpertsDrawer,
2344
2051
  enableAudio: (_w = enableAudio !== null && enableAudio !== void 0 ? enableAudio : integrationConfig === null || integrationConfig === void 0 ? void 0 : integrationConfig.enableAudio) !== null && _w !== void 0 ? _w : true,
2345
- showSpeaker: !!AZURE_COGNITIVE_SERVICES_TTS_KEY,
2346
- speakerMuted: muteSpeaker || speakerMuted,
2052
+ showSpeaker: !!ttsProvider,
2053
+ speakerMuted: speakerMuted,
2347
2054
  setSpeakerMuted: mute => {
2348
- speakerMuted = !!mute;
2349
- setMuteSpeaker(mute);
2055
+ toggleMute(mute);
2350
2056
  let microphoneMode = (0, configuration_1.getLocalConfig)('microphoneMode', 'HOLD_TO_TALK');
2351
2057
  if (microphoneMode === 'CONTINUOUS' && mute) {
2352
2058
  setContinuousSpeech(false);
@@ -2387,7 +2093,7 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
2387
2093
  avatar3dVisible,
2388
2094
  setAvatar3dVisible,
2389
2095
  hasUserActivatedSpeak,
2390
- isPlayingAudio: isPlayingAudio && !muteSpeaker,
2096
+ isPlayingAudio: isPlayingAudio && !speakerMuted,
2391
2097
  loading: !!memoriTyping,
2392
2098
  baseUrl,
2393
2099
  apiUrl: client.constants.BACKEND_URL,
@@ -2411,7 +2117,6 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
2411
2117
  clickedStart: clickedStart,
2412
2118
  isMultilanguageEnabled: isMultilanguageEnabled,
2413
2119
  onClickStart: onClickStart,
2414
- initializeTTS: initializeTTS,
2415
2120
  isUserLoggedIn: !!loginToken && !!(user === null || user === void 0 ? void 0 : user.userID),
2416
2121
  hasInitialSession: !!initialSessionID,
2417
2122
  notEnoughCredits: needsCredits && !hasEnoughCredits,
@@ -2423,6 +2128,7 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
2423
2128
  memori,
2424
2129
  sessionID: sessionId || '',
2425
2130
  tenant,
2131
+ provider: ttsProvider,
2426
2132
  translateTo: isMultilanguageEnabled &&
2427
2133
  userLang.toUpperCase() !==
2428
2134
  ((_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())
@@ -2456,7 +2162,7 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
2456
2162
  attachmentsMenuOpen,
2457
2163
  setAttachmentsMenuOpen,
2458
2164
  showInputs,
2459
- showMicrophone: !!AZURE_COGNITIVE_SERVICES_TTS_KEY,
2165
+ showMicrophone: !!ttsProvider,
2460
2166
  showFunctionCache,
2461
2167
  userMessage,
2462
2168
  onChangeUserMessage,
@@ -2503,7 +2209,7 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
2503
2209
  'memori--preview': preview,
2504
2210
  'memori--embed': embed,
2505
2211
  'memori--with-integration': integration,
2506
- 'memori--with-speechkey': !!AZURE_COGNITIVE_SERVICES_TTS_KEY,
2212
+ 'memori--with-speechkey': !!ttsProvider,
2507
2213
  'memori--active': hasUserActivatedSpeak,
2508
2214
  'memori--hide-emissions': hideEmissions,
2509
2215
  'memori--has-active-session': !!sessionId,
@@ -2565,6 +2271,10 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
2565
2271
  setChatLogID(chatLog.chatLogID);
2566
2272
  onClickStart(undefined, false, chatLog);
2567
2273
  setShowChatHistoryDrawer(false);
2274
+ }, apiClient: client, sessionId: sessionId || '', memori: memori, baseUrl: baseUrl, history: history, apiUrl: client.constants.BACKEND_URL, loginToken: loginToken })), showChatHistoryDrawer && ((0, jsx_runtime_1.jsx)(ChatHistory_1.default, { open: !!showChatHistoryDrawer, onClose: () => setShowChatHistoryDrawer(false), resumeSession: chatLog => {
2275
+ setChatLogID(chatLog.chatLogID);
2276
+ onClickStart(undefined, false, chatLog);
2277
+ setShowChatHistoryDrawer(false);
2568
2278
  }, apiClient: client, sessionId: sessionId || '', memori: memori, baseUrl: baseUrl, history: history, apiUrl: client.constants.BACKEND_URL, loginToken: loginToken })), showPositionDrawer && ((0, jsx_runtime_1.jsx)(PositionDrawer_1.default, { memori: memori, open: !!showPositionDrawer, venue: position, setVenue: setPosition, onClose: position => {
2569
2279
  if (position)
2570
2280
  applyPosition(position);
@@ -2588,7 +2298,10 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
2588
2298
  userToken = undefined;
2589
2299
  (0, configuration_1.removeLocalConfig)('loginToken');
2590
2300
  });
2591
- } }))] }));
2301
+ } })), error && ((0, jsx_runtime_1.jsx)(Alert_1.default, { open: !!error, onClose: () => {
2302
+ setError(null);
2303
+ window.open('chrome://settings/content/autoplay', '_blank');
2304
+ }, title: "Error", description: error.message, type: "error" }))] }));
2592
2305
  };
2593
2306
  exports.default = MemoriWidget;
2594
2307
  //# sourceMappingURL=MemoriWidget.js.map