@memori.ai/memori-react 8.0.2 → 8.1.0-rc.0
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.
- package/CHANGELOG.md +25 -0
- package/dist/components/Chat/Chat.d.ts +0 -2
- package/dist/components/Chat/Chat.js +2 -2
- package/dist/components/Chat/Chat.js.map +1 -1
- package/dist/components/ChatHistoryDrawer/ChatHistory.css +32 -0
- package/dist/components/ChatHistoryDrawer/ChatHistory.js +104 -31
- package/dist/components/ChatHistoryDrawer/ChatHistory.js.map +1 -1
- package/dist/components/ChatInputs/ChatInputs.d.ts +0 -2
- package/dist/components/ChatInputs/ChatInputs.js +3 -4
- package/dist/components/ChatInputs/ChatInputs.js.map +1 -1
- package/dist/components/MemoriWidget/MemoriWidget.js +103 -329
- package/dist/components/MemoriWidget/MemoriWidget.js.map +1 -1
- package/dist/helpers/stt/useSTT.d.ts +40 -0
- package/dist/helpers/stt/useSTT.js +362 -0
- package/dist/helpers/stt/useSTT.js.map +1 -0
- package/dist/locales/de.json +11 -0
- package/dist/locales/en.json +11 -0
- package/dist/locales/es.json +11 -0
- package/dist/locales/fr.json +11 -0
- package/dist/locales/it.json +11 -0
- package/esm/components/Chat/Chat.d.ts +0 -2
- package/esm/components/Chat/Chat.js +2 -2
- package/esm/components/Chat/Chat.js.map +1 -1
- package/esm/components/ChatHistoryDrawer/ChatHistory.css +32 -0
- package/esm/components/ChatHistoryDrawer/ChatHistory.js +104 -31
- package/esm/components/ChatHistoryDrawer/ChatHistory.js.map +1 -1
- package/esm/components/ChatInputs/ChatInputs.d.ts +0 -2
- package/esm/components/ChatInputs/ChatInputs.js +3 -4
- package/esm/components/ChatInputs/ChatInputs.js.map +1 -1
- package/esm/components/MemoriWidget/MemoriWidget.js +103 -329
- package/esm/components/MemoriWidget/MemoriWidget.js.map +1 -1
- package/esm/helpers/stt/useSTT.d.ts +40 -0
- package/esm/helpers/stt/useSTT.js +358 -0
- package/esm/helpers/stt/useSTT.js.map +1 -0
- package/esm/locales/de.json +11 -0
- package/esm/locales/en.json +11 -0
- package/esm/locales/es.json +11 -0
- package/esm/locales/fr.json +11 -0
- package/esm/locales/it.json +11 -0
- package/package.json +2 -3
- package/src/components/Chat/Chat.test.tsx +0 -9
- package/src/components/Chat/Chat.tsx +0 -6
- package/src/components/ChatHistoryDrawer/ChatHistory.css +32 -0
- package/src/components/ChatHistoryDrawer/ChatHistory.tsx +114 -57
- package/src/components/ChatInputs/ChatInputs.test.tsx +0 -6
- package/src/components/ChatInputs/ChatInputs.tsx +2 -7
- package/src/components/MemoriWidget/MemoriWidget.tsx +152 -476
- package/src/helpers/stt/useSTT.ts +551 -0
- package/src/locales/de.json +11 -0
- package/src/locales/en.json +11 -0
- package/src/locales/es.json +11 -0
- package/src/locales/fr.json +11 -0
- package/src/locales/it.json +11 -0
|
@@ -3,7 +3,6 @@ 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';
|
|
6
|
-
import * as speechSdk from 'microsoft-cognitiveservices-speech-sdk';
|
|
7
6
|
import cx from 'classnames';
|
|
8
7
|
import { DateTime } from 'luxon';
|
|
9
8
|
import toast from 'react-hot-toast';
|
|
@@ -38,6 +37,7 @@ import { sanitizeText } from '../../helpers/sanitizer';
|
|
|
38
37
|
import { useTTS } from '../../helpers/tts/useTTS';
|
|
39
38
|
import Alert from '../ui/Alert';
|
|
40
39
|
import ChatHistoryDrawer from '../ChatHistoryDrawer/ChatHistory';
|
|
40
|
+
import { useSTT } from '../../helpers/stt/useSTT';
|
|
41
41
|
const getMemoriState = (integrationId) => {
|
|
42
42
|
var _a, _b, _c, _d, _f;
|
|
43
43
|
let widget = integrationId
|
|
@@ -152,9 +152,6 @@ window.getMemoriState = getMemoriState;
|
|
|
152
152
|
window.typeMessage = typeMessage;
|
|
153
153
|
window.typeMessageHidden = typeMessageHidden;
|
|
154
154
|
window.typeBatchMessages = typeBatchMessages;
|
|
155
|
-
let recognizer;
|
|
156
|
-
let speechConfig;
|
|
157
|
-
let audioDestination;
|
|
158
155
|
let audioContext;
|
|
159
156
|
let memoriPassword;
|
|
160
157
|
let speakerMuted = false;
|
|
@@ -383,7 +380,9 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
|
|
|
383
380
|
}
|
|
384
381
|
const mediaDocuments = media === null || media === void 0 ? void 0 : media.filter(m => { var _a; return !m.mediumID && ((_a = m.properties) === null || _a === void 0 ? void 0 : _a.isAttachedFile); });
|
|
385
382
|
if (mediaDocuments && mediaDocuments.length > 0) {
|
|
386
|
-
const documentContents = mediaDocuments
|
|
383
|
+
const documentContents = mediaDocuments
|
|
384
|
+
.map(doc => doc.content)
|
|
385
|
+
.join(' ');
|
|
387
386
|
msg = msg + ' ' + documentContents;
|
|
388
387
|
}
|
|
389
388
|
const { currentState, ...response } = await postTextEnteredEvent({
|
|
@@ -568,6 +567,62 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
|
|
|
568
567
|
: 0;
|
|
569
568
|
const [birthDate, setBirthDate] = useState();
|
|
570
569
|
const [showAgeVerification, setShowAgeVerification] = useState(false);
|
|
570
|
+
const getCultureCodeByLanguage = (lang) => {
|
|
571
|
+
var _a, _b;
|
|
572
|
+
let voice = '';
|
|
573
|
+
let voiceLang = (lang ||
|
|
574
|
+
((_b = (_a = memori.culture) === null || _a === void 0 ? void 0 : _a.split('-')) === null || _b === void 0 ? void 0 : _b[0]) ||
|
|
575
|
+
i18n.language ||
|
|
576
|
+
'IT').toUpperCase();
|
|
577
|
+
switch (voiceLang) {
|
|
578
|
+
case 'IT':
|
|
579
|
+
voice = 'it-IT';
|
|
580
|
+
break;
|
|
581
|
+
case 'DE':
|
|
582
|
+
voice = 'de-DE';
|
|
583
|
+
break;
|
|
584
|
+
case 'EN':
|
|
585
|
+
voice = 'en-GB';
|
|
586
|
+
break;
|
|
587
|
+
case 'ES':
|
|
588
|
+
voice = 'es-ES';
|
|
589
|
+
break;
|
|
590
|
+
case 'FR':
|
|
591
|
+
voice = 'fr-FR';
|
|
592
|
+
break;
|
|
593
|
+
case 'PT':
|
|
594
|
+
voice = 'pt-PT';
|
|
595
|
+
break;
|
|
596
|
+
case 'UK':
|
|
597
|
+
voice = 'uk-UK';
|
|
598
|
+
break;
|
|
599
|
+
case 'RU':
|
|
600
|
+
voice = 'ru-RU';
|
|
601
|
+
break;
|
|
602
|
+
case 'PL':
|
|
603
|
+
voice = 'pl-PL';
|
|
604
|
+
break;
|
|
605
|
+
case 'FI':
|
|
606
|
+
voice = 'fi-FI';
|
|
607
|
+
break;
|
|
608
|
+
case 'EL':
|
|
609
|
+
voice = 'el-GR';
|
|
610
|
+
break;
|
|
611
|
+
case 'AR':
|
|
612
|
+
voice = 'ar-SA';
|
|
613
|
+
break;
|
|
614
|
+
case 'ZH':
|
|
615
|
+
voice = 'zh-CN';
|
|
616
|
+
break;
|
|
617
|
+
case 'JA':
|
|
618
|
+
voice = 'ja-JP';
|
|
619
|
+
break;
|
|
620
|
+
default:
|
|
621
|
+
voice = 'it-IT';
|
|
622
|
+
break;
|
|
623
|
+
}
|
|
624
|
+
return voice;
|
|
625
|
+
};
|
|
571
626
|
const [sessionId, setSessionId] = useState(initialSessionID);
|
|
572
627
|
const [currentDialogState, _setCurrentDialogState] = useState();
|
|
573
628
|
const setCurrentDialogState = (state) => {
|
|
@@ -1041,17 +1096,43 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
|
|
|
1041
1096
|
tenant: tenantID,
|
|
1042
1097
|
region: 'westeurope',
|
|
1043
1098
|
voiceType: memori.voiceType,
|
|
1044
|
-
layout: selectedLayout
|
|
1099
|
+
layout: selectedLayout,
|
|
1045
1100
|
});
|
|
1046
1101
|
}, [ttsProvider, userLang, memori.culture, memori.voiceType]);
|
|
1102
|
+
const sttConfig = useMemo(() => ({
|
|
1103
|
+
provider: ttsProvider,
|
|
1104
|
+
language: getCultureCodeByLanguage(userLang),
|
|
1105
|
+
tenant: tenantID,
|
|
1106
|
+
}), [ttsProvider, userLang]);
|
|
1047
1107
|
const { speak: ttsSpeak, stop: ttsStop, isPlaying: isPlayingAudio, speakerMuted, toggleMute, hasUserActivatedSpeak, setHasUserActivatedSpeak, error, setError, } = useTTS(ttsConfig, {
|
|
1048
1108
|
apiUrl: `${baseUrl}/api/tts`,
|
|
1049
1109
|
continuousSpeech: continuousSpeech,
|
|
1050
|
-
onEndSpeakStartListen: () => {
|
|
1051
|
-
console.log('[MemoriWidget] onEndSpeakStartListen called');
|
|
1052
|
-
},
|
|
1053
1110
|
preview: preview,
|
|
1054
1111
|
}, autoStart, defaultEnableAudio, defaultSpeakerActive);
|
|
1112
|
+
const processSpeechAndSendMessage = (text) => {
|
|
1113
|
+
console.log('processSpeechAndSendMessage', text);
|
|
1114
|
+
if (!text || text.trim().length === 0) {
|
|
1115
|
+
return;
|
|
1116
|
+
}
|
|
1117
|
+
try {
|
|
1118
|
+
const message = stripDuplicates(text);
|
|
1119
|
+
console.debug('Processing speech message:', message);
|
|
1120
|
+
if (message.length > 0) {
|
|
1121
|
+
setUserMessage('');
|
|
1122
|
+
console.debug('Sending message:', message);
|
|
1123
|
+
sendMessage(message);
|
|
1124
|
+
}
|
|
1125
|
+
}
|
|
1126
|
+
catch (error) {
|
|
1127
|
+
console.error('Error in processSpeechAndSendMessage:', error);
|
|
1128
|
+
}
|
|
1129
|
+
};
|
|
1130
|
+
const { isListening, startRecording, stopRecording, } = useSTT(sttConfig, processSpeechAndSendMessage, {
|
|
1131
|
+
apiUrl: `${baseUrl}/api/stt`,
|
|
1132
|
+
continuousRecording: continuousSpeech,
|
|
1133
|
+
silenceTimeout: continuousSpeechTimeout,
|
|
1134
|
+
autoStart: autoStart,
|
|
1135
|
+
}, defaultEnableAudio);
|
|
1055
1136
|
const resetInteractionTimeout = () => {
|
|
1056
1137
|
clearInteractionTimeout();
|
|
1057
1138
|
if (!isPlayingAudio && !userMessage.length && !memoriTyping && !listening)
|
|
@@ -1153,73 +1234,14 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
|
|
|
1153
1234
|
memoriTyping,
|
|
1154
1235
|
hasUserActivatedSpeak,
|
|
1155
1236
|
]);
|
|
1156
|
-
const getCultureCodeByLanguage = (lang) => {
|
|
1157
|
-
var _a, _b;
|
|
1158
|
-
let voice = '';
|
|
1159
|
-
let voiceLang = (lang ||
|
|
1160
|
-
((_b = (_a = memori.culture) === null || _a === void 0 ? void 0 : _a.split('-')) === null || _b === void 0 ? void 0 : _b[0]) ||
|
|
1161
|
-
i18n.language ||
|
|
1162
|
-
'IT').toUpperCase();
|
|
1163
|
-
switch (voiceLang) {
|
|
1164
|
-
case 'IT':
|
|
1165
|
-
voice = 'it-IT';
|
|
1166
|
-
break;
|
|
1167
|
-
case 'DE':
|
|
1168
|
-
voice = 'de-DE';
|
|
1169
|
-
break;
|
|
1170
|
-
case 'EN':
|
|
1171
|
-
voice = 'en-GB';
|
|
1172
|
-
break;
|
|
1173
|
-
case 'ES':
|
|
1174
|
-
voice = 'es-ES';
|
|
1175
|
-
break;
|
|
1176
|
-
case 'FR':
|
|
1177
|
-
voice = 'fr-FR';
|
|
1178
|
-
break;
|
|
1179
|
-
case 'PT':
|
|
1180
|
-
voice = 'pt-PT';
|
|
1181
|
-
break;
|
|
1182
|
-
case 'UK':
|
|
1183
|
-
voice = 'uk-UK';
|
|
1184
|
-
break;
|
|
1185
|
-
case 'RU':
|
|
1186
|
-
voice = 'ru-RU';
|
|
1187
|
-
break;
|
|
1188
|
-
case 'PL':
|
|
1189
|
-
voice = 'pl-PL';
|
|
1190
|
-
break;
|
|
1191
|
-
case 'FI':
|
|
1192
|
-
voice = 'fi-FI';
|
|
1193
|
-
break;
|
|
1194
|
-
case 'EL':
|
|
1195
|
-
voice = 'el-GR';
|
|
1196
|
-
break;
|
|
1197
|
-
case 'AR':
|
|
1198
|
-
voice = 'ar-SA';
|
|
1199
|
-
break;
|
|
1200
|
-
case 'ZH':
|
|
1201
|
-
voice = 'zh-CN';
|
|
1202
|
-
break;
|
|
1203
|
-
case 'JA':
|
|
1204
|
-
voice = 'ja-JP';
|
|
1205
|
-
break;
|
|
1206
|
-
default:
|
|
1207
|
-
voice = 'it-IT';
|
|
1208
|
-
break;
|
|
1209
|
-
}
|
|
1210
|
-
return voice;
|
|
1211
|
-
};
|
|
1212
1237
|
const handleSpeak = async (text) => {
|
|
1213
1238
|
if (!text || preview || speakerMuted || !defaultEnableAudio) {
|
|
1214
1239
|
const e = new CustomEvent('MemoriEndSpeak');
|
|
1215
1240
|
document.dispatchEvent(e);
|
|
1216
|
-
if (continuousSpeech) {
|
|
1217
|
-
setListeningTimeout();
|
|
1218
|
-
}
|
|
1219
1241
|
return Promise.resolve();
|
|
1220
1242
|
}
|
|
1221
|
-
if (typeof
|
|
1222
|
-
|
|
1243
|
+
if (typeof stopRecording === 'function') {
|
|
1244
|
+
stopRecording();
|
|
1223
1245
|
}
|
|
1224
1246
|
setMemoriTyping(true);
|
|
1225
1247
|
const processedText = sanitizeText(text);
|
|
@@ -1261,25 +1283,6 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
|
|
|
1261
1283
|
hasUserActivatedSpeak,
|
|
1262
1284
|
setHasUserActivatedSpeak,
|
|
1263
1285
|
]);
|
|
1264
|
-
const handleFallback = (text) => {
|
|
1265
|
-
if (defaultEnableAudio) {
|
|
1266
|
-
window.speechSynthesis.speak(new SpeechSynthesisUtterance(text));
|
|
1267
|
-
}
|
|
1268
|
-
cleanup();
|
|
1269
|
-
};
|
|
1270
|
-
const cleanup = () => {
|
|
1271
|
-
if (recognizer) {
|
|
1272
|
-
recognizer.stopContinuousRecognitionAsync();
|
|
1273
|
-
recognizer.close();
|
|
1274
|
-
recognizer = null;
|
|
1275
|
-
}
|
|
1276
|
-
if (speechSynthesizerRef.current) {
|
|
1277
|
-
speechSynthesizerRef.current.close();
|
|
1278
|
-
speechSynthesizerRef.current = null;
|
|
1279
|
-
}
|
|
1280
|
-
setListening(false);
|
|
1281
|
-
clearListeningTimeout();
|
|
1282
|
-
};
|
|
1283
1286
|
const stopAudio = useCallback(async () => {
|
|
1284
1287
|
ttsStop();
|
|
1285
1288
|
}, [ttsStop]);
|
|
@@ -1297,230 +1300,8 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
|
|
|
1297
1300
|
focusChatInput();
|
|
1298
1301
|
}
|
|
1299
1302
|
}, [currentDialogState === null || currentDialogState === void 0 ? void 0 : currentDialogState.emission]);
|
|
1300
|
-
const [transcript, setTranscript] = useState('');
|
|
1301
|
-
const [transcriptTimeout, setTranscriptTimeout] = useState(null);
|
|
1302
|
-
const [isSpeaking, setIsSpeaking] = useState(false);
|
|
1303
|
-
const resetTranscript = () => {
|
|
1304
|
-
setTranscript('');
|
|
1305
|
-
};
|
|
1306
|
-
const setListeningTimeout = () => {
|
|
1307
|
-
clearListeningTimeout();
|
|
1308
|
-
console.debug('Setting speech processing timeout');
|
|
1309
|
-
const timeout = setTimeout(() => {
|
|
1310
|
-
console.debug('Speech timeout triggered, processing transcript');
|
|
1311
|
-
handleTranscriptProcessing();
|
|
1312
|
-
}, continuousSpeechTimeout * 1000 + 300);
|
|
1313
|
-
setTranscriptTimeout(timeout);
|
|
1314
|
-
};
|
|
1315
|
-
const clearListeningTimeout = () => {
|
|
1316
|
-
if (transcriptTimeout) {
|
|
1317
|
-
console.debug('Clearing transcript timeout');
|
|
1318
|
-
clearTimeout(transcriptTimeout);
|
|
1319
|
-
setTranscriptTimeout(null);
|
|
1320
|
-
}
|
|
1321
|
-
};
|
|
1322
|
-
const resetListeningTimeout = () => {
|
|
1323
|
-
clearListeningTimeout();
|
|
1324
|
-
if (continuousSpeech && !isProcessingSTT) {
|
|
1325
|
-
console.debug('Setting new listening timeout');
|
|
1326
|
-
setListeningTimeout();
|
|
1327
|
-
}
|
|
1328
|
-
};
|
|
1329
|
-
useEffect(() => {
|
|
1330
|
-
if (!isSpeaking && transcript && transcript.length > 0) {
|
|
1331
|
-
console.debug('Transcript updated while not speaking, resetting timeout');
|
|
1332
|
-
resetListeningTimeout();
|
|
1333
|
-
resetInteractionTimeout();
|
|
1334
|
-
}
|
|
1335
|
-
}, [transcript, isSpeaking]);
|
|
1336
|
-
useEffect(() => {
|
|
1337
|
-
return () => {
|
|
1338
|
-
clearListeningTimeout();
|
|
1339
|
-
};
|
|
1340
|
-
}, []);
|
|
1341
|
-
let microphoneStream = null;
|
|
1342
|
-
const startListening = async () => {
|
|
1343
|
-
console.debug('Starting speech recognition...');
|
|
1344
|
-
if (!sessionId) {
|
|
1345
|
-
console.error('No session ID available');
|
|
1346
|
-
throw new Error('No session ID available');
|
|
1347
|
-
}
|
|
1348
|
-
if (recognizer) {
|
|
1349
|
-
console.debug('Cleaning up existing recognizer...');
|
|
1350
|
-
try {
|
|
1351
|
-
await new Promise((resolve, _) => {
|
|
1352
|
-
recognizer === null || recognizer === void 0 ? void 0 : recognizer.stopContinuousRecognitionAsync(resolve, error => {
|
|
1353
|
-
console.error('Error stopping recognition:', error);
|
|
1354
|
-
resolve();
|
|
1355
|
-
});
|
|
1356
|
-
});
|
|
1357
|
-
console.debug('Closing existing recognizer...');
|
|
1358
|
-
recognizer.close();
|
|
1359
|
-
recognizer = null;
|
|
1360
|
-
}
|
|
1361
|
-
catch (error) {
|
|
1362
|
-
console.error('Error during recognizer cleanup:', error);
|
|
1363
|
-
}
|
|
1364
|
-
}
|
|
1365
|
-
console.debug('Resetting transcript and STT state...');
|
|
1366
|
-
resetTranscript();
|
|
1367
|
-
setIsProcessingSTT(false);
|
|
1368
|
-
console.debug('Adding delay for Azure services cleanup...');
|
|
1369
|
-
await new Promise(resolve => setTimeout(resolve, 500));
|
|
1370
|
-
try {
|
|
1371
|
-
console.debug('Requesting microphone access...');
|
|
1372
|
-
if (microphoneStream) {
|
|
1373
|
-
microphoneStream.getTracks().forEach(track => track.stop());
|
|
1374
|
-
microphoneStream = null;
|
|
1375
|
-
}
|
|
1376
|
-
const stream = await navigator.mediaDevices.getUserMedia({
|
|
1377
|
-
audio: true,
|
|
1378
|
-
});
|
|
1379
|
-
setHasUserActivatedListening(true);
|
|
1380
|
-
console.debug('Setting up speech config...');
|
|
1381
|
-
console.debug('Creating audio config and recognizer...');
|
|
1382
|
-
const audioConfig = speechSdk.AudioConfig.fromDefaultMicrophoneInput();
|
|
1383
|
-
recognizer = new speechSdk.SpeechRecognizer(speechConfig, audioConfig);
|
|
1384
|
-
console.debug('Setting up recognizer handlers...');
|
|
1385
|
-
setupRecognizerHandlers(recognizer);
|
|
1386
|
-
console.debug('Starting continuous recognition...');
|
|
1387
|
-
await new Promise((resolve, reject) => {
|
|
1388
|
-
recognizer === null || recognizer === void 0 ? void 0 : recognizer.startContinuousRecognitionAsync(resolve, error => {
|
|
1389
|
-
console.error('Failed to start recognition:', error);
|
|
1390
|
-
reject(error);
|
|
1391
|
-
});
|
|
1392
|
-
});
|
|
1393
|
-
console.debug('Speech recognition started successfully');
|
|
1394
|
-
setListening(true);
|
|
1395
|
-
}
|
|
1396
|
-
catch (error) {
|
|
1397
|
-
console.error('Error in startListening:', error);
|
|
1398
|
-
if (recognizer) {
|
|
1399
|
-
console.debug('Cleaning up recognizer after error...');
|
|
1400
|
-
recognizer.close();
|
|
1401
|
-
recognizer = null;
|
|
1402
|
-
}
|
|
1403
|
-
setListening(false);
|
|
1404
|
-
throw error;
|
|
1405
|
-
}
|
|
1406
|
-
};
|
|
1407
|
-
startListeningRef.current = startListening;
|
|
1408
|
-
const onEndSpeakStartListen = useCallback((_e) => {
|
|
1409
|
-
if (isPlayingAudio && speechSynthesizerRef.current) {
|
|
1410
|
-
speechSynthesizerRef.current.close();
|
|
1411
|
-
speechSynthesizerRef.current = null;
|
|
1412
|
-
}
|
|
1413
|
-
if (continuousSpeech &&
|
|
1414
|
-
(hasUserActivatedListening || !requestedListening)) {
|
|
1415
|
-
setRequestedListening(true);
|
|
1416
|
-
if (startListeningRef.current) {
|
|
1417
|
-
startListeningRef.current();
|
|
1418
|
-
}
|
|
1419
|
-
}
|
|
1420
|
-
}, [continuousSpeech, hasUserActivatedListening, isPlayingAudio, requestedListening]);
|
|
1421
|
-
const setupSpeechConfig = (AZURE_COGNITIVE_SERVICES_TTS_KEY) => {
|
|
1422
|
-
console.debug('Creating speech config...');
|
|
1423
|
-
speechConfig = speechSdk.SpeechConfig.fromSubscription(AZURE_COGNITIVE_SERVICES_TTS_KEY, 'westeurope');
|
|
1424
|
-
console.debug('Setting speech recognition language:', userLang);
|
|
1425
|
-
speechConfig.speechRecognitionLanguage = getCultureCodeByLanguage(userLang);
|
|
1426
|
-
speechConfig.speechSynthesisLanguage = getCultureCodeByLanguage(userLang);
|
|
1427
|
-
speechConfig.speechSynthesisVoiceName = getTTSVoice(userLang);
|
|
1428
|
-
return speechConfig;
|
|
1429
|
-
};
|
|
1430
|
-
const [isProcessingSTT, setIsProcessingSTT] = useState(false);
|
|
1431
|
-
const setupRecognizerHandlers = (recognizer) => {
|
|
1432
|
-
if (recognizer) {
|
|
1433
|
-
console.debug('Setting up recognizer event handlers...');
|
|
1434
|
-
recognizer.recognized = (_, event) => {
|
|
1435
|
-
console.debug('Recognition event received');
|
|
1436
|
-
handleRecognizedSpeech(event.result.text);
|
|
1437
|
-
};
|
|
1438
|
-
console.debug('Configuring recognizer properties...');
|
|
1439
|
-
recognizer.properties.setProperty('SpeechServiceResponse_JsonResult', 'true');
|
|
1440
|
-
recognizer.properties.setProperty('SpeechServiceConnection_NoiseSuppression', 'true');
|
|
1441
|
-
recognizer.properties.setProperty('SpeechServiceConnection_SNRThresholdDb', '10.0');
|
|
1442
|
-
}
|
|
1443
|
-
};
|
|
1444
|
-
let isProcessingSpeech = false;
|
|
1445
|
-
const processSpeechAndSendMessage = (text) => {
|
|
1446
|
-
if (isProcessingSpeech || !text || text.trim().length === 0) {
|
|
1447
|
-
console.debug('Skipping speech processing: already processing or empty text');
|
|
1448
|
-
return;
|
|
1449
|
-
}
|
|
1450
|
-
try {
|
|
1451
|
-
isProcessingSpeech = true;
|
|
1452
|
-
const message = stripDuplicates(text);
|
|
1453
|
-
console.debug('Processing speech message:', message);
|
|
1454
|
-
if (message.length > 0) {
|
|
1455
|
-
setIsProcessingSTT(true);
|
|
1456
|
-
setUserMessage('');
|
|
1457
|
-
console.debug('Sending message:', message);
|
|
1458
|
-
sendMessage(message);
|
|
1459
|
-
resetTranscript();
|
|
1460
|
-
clearListening();
|
|
1461
|
-
}
|
|
1462
|
-
}
|
|
1463
|
-
finally {
|
|
1464
|
-
setTimeout(() => {
|
|
1465
|
-
isProcessingSpeech = false;
|
|
1466
|
-
}, 1000);
|
|
1467
|
-
}
|
|
1468
|
-
};
|
|
1469
|
-
const handleRecognizedSpeech = (text) => {
|
|
1470
|
-
console.debug('Speech recognized:', text);
|
|
1471
|
-
setTranscript(text);
|
|
1472
|
-
setIsSpeaking(false);
|
|
1473
|
-
if (!continuousSpeech) {
|
|
1474
|
-
processSpeechAndSendMessage(text);
|
|
1475
|
-
}
|
|
1476
|
-
};
|
|
1477
|
-
const handleTranscriptProcessing = () => {
|
|
1478
|
-
if (transcript && transcript.length > 0 && listening) {
|
|
1479
|
-
processSpeechAndSendMessage(transcript);
|
|
1480
|
-
}
|
|
1481
|
-
else if (listening) {
|
|
1482
|
-
resetInteractionTimeout();
|
|
1483
|
-
}
|
|
1484
|
-
};
|
|
1485
|
-
const stopListening = async () => {
|
|
1486
|
-
console.debug('Stopping speech recognition');
|
|
1487
|
-
if (recognizer) {
|
|
1488
|
-
try {
|
|
1489
|
-
recognizer.stopContinuousRecognitionAsync();
|
|
1490
|
-
recognizer.close();
|
|
1491
|
-
}
|
|
1492
|
-
catch (error) {
|
|
1493
|
-
console.error('Error stopping recognizer:', error);
|
|
1494
|
-
}
|
|
1495
|
-
recognizer = null;
|
|
1496
|
-
}
|
|
1497
|
-
if (microphoneStream) {
|
|
1498
|
-
try {
|
|
1499
|
-
microphoneStream.getTracks().forEach(track => track.stop());
|
|
1500
|
-
}
|
|
1501
|
-
catch (error) {
|
|
1502
|
-
console.error('Error stopping microphone stream:', error);
|
|
1503
|
-
}
|
|
1504
|
-
microphoneStream = null;
|
|
1505
|
-
}
|
|
1506
|
-
setListening(false);
|
|
1507
|
-
};
|
|
1508
|
-
const clearListening = () => {
|
|
1509
|
-
stopListening();
|
|
1510
|
-
clearListeningTimeout();
|
|
1511
|
-
setIsSpeaking(false);
|
|
1512
|
-
};
|
|
1513
|
-
const resetListening = () => {
|
|
1514
|
-
if (listening) {
|
|
1515
|
-
clearListening();
|
|
1516
|
-
resetTranscript();
|
|
1517
|
-
setUserMessage('');
|
|
1518
|
-
startListening();
|
|
1519
|
-
}
|
|
1520
|
-
};
|
|
1521
1303
|
const resetUIEffects = () => {
|
|
1522
1304
|
try {
|
|
1523
|
-
clearListening();
|
|
1524
1305
|
clearInteractionTimeout();
|
|
1525
1306
|
setClickedStart(false);
|
|
1526
1307
|
timeoutRef.current = undefined;
|
|
@@ -1541,23 +1322,19 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
|
|
|
1541
1322
|
document.removeEventListener('MemoriResetUIEffects', resetUIEffects);
|
|
1542
1323
|
};
|
|
1543
1324
|
}, []);
|
|
1544
|
-
useEffect(() => {
|
|
1545
|
-
if ((currentDialogState === null || currentDialogState === void 0 ? void 0 : currentDialogState.state) === 'Z0')
|
|
1546
|
-
clearListening();
|
|
1547
|
-
}, [currentDialogState === null || currentDialogState === void 0 ? void 0 : currentDialogState.state]);
|
|
1548
1325
|
useEffect(() => {
|
|
1549
1326
|
if (!isPlayingAudio &&
|
|
1550
1327
|
continuousSpeech &&
|
|
1551
1328
|
(hasUserActivatedListening || !requestedListening) &&
|
|
1552
1329
|
sessionId) {
|
|
1553
|
-
|
|
1330
|
+
startRecording();
|
|
1554
1331
|
}
|
|
1555
|
-
else if (isPlayingAudio &&
|
|
1556
|
-
|
|
1332
|
+
else if (isPlayingAudio && isListening) {
|
|
1333
|
+
stopRecording();
|
|
1557
1334
|
}
|
|
1558
1335
|
}, [isPlayingAudio, hasUserActivatedListening]);
|
|
1559
1336
|
useEffect(() => {
|
|
1560
|
-
|
|
1337
|
+
stopRecording();
|
|
1561
1338
|
}, [language]);
|
|
1562
1339
|
const [sendOnEnter, setSendOnEnter] = useState('keypress');
|
|
1563
1340
|
useEffect(() => {
|
|
@@ -1661,7 +1438,6 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
|
|
|
1661
1438
|
}
|
|
1662
1439
|
}, [integrationConfig, memori.avatarURL, ogImage]);
|
|
1663
1440
|
const simulateUserPrompt = (text, translatedText) => {
|
|
1664
|
-
stopListening();
|
|
1665
1441
|
stopAudio();
|
|
1666
1442
|
sendMessage(text, undefined, undefined, false, translatedText);
|
|
1667
1443
|
};
|
|
@@ -1678,7 +1454,6 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
|
|
|
1678
1454
|
}, 1000);
|
|
1679
1455
|
}
|
|
1680
1456
|
else {
|
|
1681
|
-
stopListening();
|
|
1682
1457
|
stopAudio();
|
|
1683
1458
|
sendMessage(text, undefined, undefined, undefined, undefined, hidden, typingText, useLoaderTextAsMsg, hasBatchQueued);
|
|
1684
1459
|
}
|
|
@@ -2107,7 +1882,9 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
|
|
|
2107
1882
|
avatar3dVisible,
|
|
2108
1883
|
setAvatar3dVisible,
|
|
2109
1884
|
hasUserActivatedSpeak,
|
|
2110
|
-
isPlayingAudio: isPlayingAudio &&
|
|
1885
|
+
isPlayingAudio: isPlayingAudio &&
|
|
1886
|
+
!speakerMuted &&
|
|
1887
|
+
((_y = enableAudio !== null && enableAudio !== void 0 ? enableAudio : integrationConfig === null || integrationConfig === void 0 ? void 0 : integrationConfig.enableAudio) !== null && _y !== void 0 ? _y : true),
|
|
2111
1888
|
loading: !!memoriTyping,
|
|
2112
1889
|
baseUrl,
|
|
2113
1890
|
apiUrl: client.constants.BACKEND_URL,
|
|
@@ -2142,7 +1919,6 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
|
|
|
2142
1919
|
memori,
|
|
2143
1920
|
sessionID: sessionId || '',
|
|
2144
1921
|
tenant,
|
|
2145
|
-
provider: ttsProvider,
|
|
2146
1922
|
translateTo: isMultilanguageEnabled &&
|
|
2147
1923
|
userLang.toUpperCase() !==
|
|
2148
1924
|
((_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())
|
|
@@ -2182,16 +1958,14 @@ const MemoriWidget = ({ memori, memoriConfigs, ownerUserID, ownerUserName, tenan
|
|
|
2182
1958
|
onChangeUserMessage,
|
|
2183
1959
|
sendMessage: (msg, media) => {
|
|
2184
1960
|
stopAudio();
|
|
2185
|
-
|
|
1961
|
+
stopRecording();
|
|
2186
1962
|
sendMessage(msg, media);
|
|
2187
1963
|
setUserMessage('');
|
|
2188
|
-
resetTranscript();
|
|
2189
1964
|
},
|
|
2190
|
-
stopListening:
|
|
2191
|
-
startListening,
|
|
1965
|
+
stopListening: stopRecording,
|
|
1966
|
+
startListening: startRecording,
|
|
2192
1967
|
stopAudio,
|
|
2193
|
-
|
|
2194
|
-
listening,
|
|
1968
|
+
listening: isListening,
|
|
2195
1969
|
setEnableFocusChatInput,
|
|
2196
1970
|
isPlayingAudio,
|
|
2197
1971
|
customMediaRenderer,
|