@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
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
import { useState, useCallback, useRef, useEffect } from 'react';
|
|
2
|
+
import { getLocalConfig } from '../configuration';
|
|
3
|
+
export function useSTT(config, processSpeechAndSendMessage, options = {}, defaultEnableAudio = true) {
|
|
4
|
+
const [recordingState, setRecordingState] = useState('idle');
|
|
5
|
+
const [microphoneMuted, setMicrophoneMuted] = useState(getLocalConfig('muteMicrophone', !defaultEnableAudio));
|
|
6
|
+
const [hasUserActivatedRecord, setHasUserActivatedRecord] = useState(false);
|
|
7
|
+
const [error, setError] = useState(null);
|
|
8
|
+
const [lastTranscription, setLastTranscription] = useState(null);
|
|
9
|
+
const [isListening, setIsListening] = useState(false);
|
|
10
|
+
const mediaRecorderRef = useRef(null);
|
|
11
|
+
const audioStreamRef = useRef(null);
|
|
12
|
+
const chunksRef = useRef([]);
|
|
13
|
+
const isRecordingRef = useRef(false);
|
|
14
|
+
const isMountedRef = useRef(true);
|
|
15
|
+
const silenceTimeoutRef = useRef(null);
|
|
16
|
+
const audioContextRef = useRef(null);
|
|
17
|
+
const analyserRef = useRef(null);
|
|
18
|
+
const dataArrayRef = useRef(null);
|
|
19
|
+
const apiUrl = options.apiUrl || '/api/stt';
|
|
20
|
+
const silenceTimeout = options.silenceTimeout || 2;
|
|
21
|
+
const initializeRecording = useCallback(async () => {
|
|
22
|
+
try {
|
|
23
|
+
if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
|
|
24
|
+
throw new Error('Media recording is not supported in this browser');
|
|
25
|
+
}
|
|
26
|
+
const stream = await navigator.mediaDevices.getUserMedia({
|
|
27
|
+
audio: {
|
|
28
|
+
echoCancellation: true,
|
|
29
|
+
noiseSuppression: true,
|
|
30
|
+
autoGainControl: true,
|
|
31
|
+
sampleRate: 16000,
|
|
32
|
+
},
|
|
33
|
+
});
|
|
34
|
+
audioStreamRef.current = stream;
|
|
35
|
+
if (options.continuousRecording) {
|
|
36
|
+
try {
|
|
37
|
+
audioContextRef.current = new (window.AudioContext || window.webkitAudioContext)();
|
|
38
|
+
analyserRef.current = audioContextRef.current.createAnalyser();
|
|
39
|
+
analyserRef.current.fftSize = 256;
|
|
40
|
+
const bufferLength = analyserRef.current.frequencyBinCount;
|
|
41
|
+
dataArrayRef.current = new Uint8Array(bufferLength);
|
|
42
|
+
const source = audioContextRef.current.createMediaStreamSource(stream);
|
|
43
|
+
source.connect(analyserRef.current);
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
let mimeType = '';
|
|
49
|
+
if (config.provider === 'azure') {
|
|
50
|
+
if (MediaRecorder.isTypeSupported('audio/mp4')) {
|
|
51
|
+
mimeType = 'audio/mp4';
|
|
52
|
+
}
|
|
53
|
+
else if (MediaRecorder.isTypeSupported('audio/ogg;codecs=opus')) {
|
|
54
|
+
mimeType = 'audio/ogg;codecs=opus';
|
|
55
|
+
}
|
|
56
|
+
else if (MediaRecorder.isTypeSupported('audio/ogg')) {
|
|
57
|
+
mimeType = 'audio/ogg';
|
|
58
|
+
}
|
|
59
|
+
else if (MediaRecorder.isTypeSupported('audio/webm')) {
|
|
60
|
+
mimeType = 'audio/webm';
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
if (MediaRecorder.isTypeSupported('audio/webm;codecs=opus')) {
|
|
65
|
+
mimeType = 'audio/webm;codecs=opus';
|
|
66
|
+
}
|
|
67
|
+
else if (MediaRecorder.isTypeSupported('audio/webm')) {
|
|
68
|
+
mimeType = 'audio/webm';
|
|
69
|
+
}
|
|
70
|
+
else if (MediaRecorder.isTypeSupported('audio/mp4')) {
|
|
71
|
+
mimeType = 'audio/mp4';
|
|
72
|
+
}
|
|
73
|
+
else if (MediaRecorder.isTypeSupported('audio/ogg;codecs=opus')) {
|
|
74
|
+
mimeType = 'audio/ogg;codecs=opus';
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
const mediaRecorder = new MediaRecorder(stream, mimeType ? { mimeType } : {});
|
|
78
|
+
mediaRecorder.ondataavailable = (event) => {
|
|
79
|
+
if (event.data.size > 0) {
|
|
80
|
+
chunksRef.current.push(event.data);
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
mediaRecorder.onstop = async () => {
|
|
84
|
+
if (!isRecordingRef.current || !isMountedRef.current) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
setRecordingState('processing');
|
|
88
|
+
try {
|
|
89
|
+
if (chunksRef.current.length === 0) {
|
|
90
|
+
throw new Error('No audio data recorded');
|
|
91
|
+
}
|
|
92
|
+
const audioBlob = new Blob(chunksRef.current, {
|
|
93
|
+
type: mediaRecorder.mimeType,
|
|
94
|
+
});
|
|
95
|
+
if (audioBlob.size === 0) {
|
|
96
|
+
throw new Error('Recorded audio is empty');
|
|
97
|
+
}
|
|
98
|
+
const result = await transcribeAudio(audioBlob);
|
|
99
|
+
if (processSpeechAndSendMessage) {
|
|
100
|
+
processSpeechAndSendMessage(result.text);
|
|
101
|
+
}
|
|
102
|
+
setLastTranscription(result);
|
|
103
|
+
if (options.onTranscriptionComplete) {
|
|
104
|
+
options.onTranscriptionComplete(result);
|
|
105
|
+
}
|
|
106
|
+
setRecordingState('idle');
|
|
107
|
+
}
|
|
108
|
+
catch (err) {
|
|
109
|
+
const errorMsg = err instanceof Error ? err : new Error(String(err));
|
|
110
|
+
setError(errorMsg);
|
|
111
|
+
setRecordingState('error');
|
|
112
|
+
if (options.onError) {
|
|
113
|
+
options.onError(errorMsg);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
finally {
|
|
117
|
+
chunksRef.current = [];
|
|
118
|
+
isRecordingRef.current = false;
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
mediaRecorder.onerror = () => {
|
|
122
|
+
const errorMsg = new Error('Recording failed');
|
|
123
|
+
setError(errorMsg);
|
|
124
|
+
setRecordingState('error');
|
|
125
|
+
isRecordingRef.current = false;
|
|
126
|
+
if (options.onError) {
|
|
127
|
+
options.onError(errorMsg);
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
mediaRecorderRef.current = mediaRecorder;
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
catch (err) {
|
|
134
|
+
const errorMsg = err instanceof Error ? err : new Error('Failed to access microphone');
|
|
135
|
+
setError(errorMsg);
|
|
136
|
+
setRecordingState('error');
|
|
137
|
+
if (options.onError) {
|
|
138
|
+
options.onError(errorMsg);
|
|
139
|
+
}
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
142
|
+
}, [config.provider, options, silenceTimeout]);
|
|
143
|
+
const detectAudioActivity = useCallback(() => {
|
|
144
|
+
if (!analyserRef.current || !dataArrayRef.current) {
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
analyserRef.current.getByteFrequencyData(dataArrayRef.current);
|
|
148
|
+
const average = dataArrayRef.current.reduce((sum, value) => sum + value, 0) / dataArrayRef.current.length;
|
|
149
|
+
const threshold = 10;
|
|
150
|
+
return average > threshold;
|
|
151
|
+
}, []);
|
|
152
|
+
const startSilenceDetection = useCallback(() => {
|
|
153
|
+
if (!options.continuousRecording || !analyserRef.current) {
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
const checkAudioActivity = () => {
|
|
157
|
+
if (!isRecordingRef.current || !isMountedRef.current) {
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
const hasActivity = detectAudioActivity();
|
|
161
|
+
if (hasActivity) {
|
|
162
|
+
if (silenceTimeoutRef.current) {
|
|
163
|
+
clearTimeout(silenceTimeoutRef.current);
|
|
164
|
+
}
|
|
165
|
+
silenceTimeoutRef.current = setTimeout(() => {
|
|
166
|
+
if (isRecordingRef.current && isMountedRef.current) {
|
|
167
|
+
stopRecording();
|
|
168
|
+
}
|
|
169
|
+
}, silenceTimeout * 1000);
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
const intervalId = setInterval(checkAudioActivity, 50);
|
|
173
|
+
window.memoriSilenceDetectionInterval = intervalId;
|
|
174
|
+
}, [options.continuousRecording, detectAudioActivity, silenceTimeout]);
|
|
175
|
+
const stopSilenceDetection = useCallback(() => {
|
|
176
|
+
if (silenceTimeoutRef.current) {
|
|
177
|
+
clearTimeout(silenceTimeoutRef.current);
|
|
178
|
+
silenceTimeoutRef.current = null;
|
|
179
|
+
}
|
|
180
|
+
if (window.memoriSilenceDetectionInterval) {
|
|
181
|
+
clearInterval(window.memoriSilenceDetectionInterval);
|
|
182
|
+
window.memoriSilenceDetectionInterval = null;
|
|
183
|
+
}
|
|
184
|
+
}, []);
|
|
185
|
+
const transcribeAudio = useCallback(async (audioBlob) => {
|
|
186
|
+
var _a;
|
|
187
|
+
const formData = new FormData();
|
|
188
|
+
let fileExtension = 'webm';
|
|
189
|
+
if ((_a = mediaRecorderRef.current) === null || _a === void 0 ? void 0 : _a.mimeType) {
|
|
190
|
+
if (mediaRecorderRef.current.mimeType.includes('webm')) {
|
|
191
|
+
fileExtension = 'webm';
|
|
192
|
+
}
|
|
193
|
+
else if (mediaRecorderRef.current.mimeType.includes('mp4')) {
|
|
194
|
+
fileExtension = 'mp4';
|
|
195
|
+
}
|
|
196
|
+
else if (mediaRecorderRef.current.mimeType.includes('ogg')) {
|
|
197
|
+
fileExtension = 'ogg';
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
formData.append('audio', audioBlob, `recording.${fileExtension}`);
|
|
201
|
+
formData.append('provider', config.provider);
|
|
202
|
+
formData.append('tenant', config.tenant || 'www.aisuru.com');
|
|
203
|
+
if (config.language) {
|
|
204
|
+
formData.append('language', config.language);
|
|
205
|
+
}
|
|
206
|
+
if (config.model) {
|
|
207
|
+
formData.append('model', config.model);
|
|
208
|
+
}
|
|
209
|
+
if (config.region) {
|
|
210
|
+
formData.append('region', config.region);
|
|
211
|
+
}
|
|
212
|
+
const response = await fetch(apiUrl, {
|
|
213
|
+
method: 'POST',
|
|
214
|
+
body: formData,
|
|
215
|
+
});
|
|
216
|
+
if (!response.ok) {
|
|
217
|
+
const errorData = await response.json().catch(() => ({}));
|
|
218
|
+
throw new Error(errorData.error || `API error: ${response.status}`);
|
|
219
|
+
}
|
|
220
|
+
const data = await response.json();
|
|
221
|
+
if (!data.success || !data.result) {
|
|
222
|
+
throw new Error('Invalid response from transcription service');
|
|
223
|
+
}
|
|
224
|
+
return data.result;
|
|
225
|
+
}, [config, apiUrl]);
|
|
226
|
+
const startRecording = useCallback(async () => {
|
|
227
|
+
if (!isMountedRef.current ||
|
|
228
|
+
microphoneMuted ||
|
|
229
|
+
recordingState === 'recording') {
|
|
230
|
+
return;
|
|
231
|
+
}
|
|
232
|
+
if (!hasUserActivatedRecord) {
|
|
233
|
+
setHasUserActivatedRecord(true);
|
|
234
|
+
}
|
|
235
|
+
try {
|
|
236
|
+
setError(null);
|
|
237
|
+
setRecordingState('recording');
|
|
238
|
+
if (!mediaRecorderRef.current) {
|
|
239
|
+
const initialized = await initializeRecording();
|
|
240
|
+
if (!initialized) {
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
chunksRef.current = [];
|
|
245
|
+
isRecordingRef.current = true;
|
|
246
|
+
if (mediaRecorderRef.current &&
|
|
247
|
+
mediaRecorderRef.current.state === 'inactive') {
|
|
248
|
+
mediaRecorderRef.current.start(100);
|
|
249
|
+
setIsListening(true);
|
|
250
|
+
if (options.continuousRecording) {
|
|
251
|
+
startSilenceDetection();
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
catch (err) {
|
|
256
|
+
const errorMsg = err instanceof Error ? err : new Error('Failed to start recording');
|
|
257
|
+
setError(errorMsg);
|
|
258
|
+
setRecordingState('error');
|
|
259
|
+
isRecordingRef.current = false;
|
|
260
|
+
if (options.onError) {
|
|
261
|
+
options.onError(errorMsg);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}, [
|
|
265
|
+
microphoneMuted,
|
|
266
|
+
recordingState,
|
|
267
|
+
hasUserActivatedRecord,
|
|
268
|
+
initializeRecording,
|
|
269
|
+
options,
|
|
270
|
+
startSilenceDetection,
|
|
271
|
+
]);
|
|
272
|
+
const stopRecording = useCallback(() => {
|
|
273
|
+
if (!isRecordingRef.current) {
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
try {
|
|
277
|
+
setIsListening(false);
|
|
278
|
+
stopSilenceDetection();
|
|
279
|
+
if (mediaRecorderRef.current &&
|
|
280
|
+
mediaRecorderRef.current.state === 'recording') {
|
|
281
|
+
mediaRecorderRef.current.stop();
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
catch (err) {
|
|
285
|
+
const errorMsg = err instanceof Error ? err : new Error('Failed to stop recording');
|
|
286
|
+
setError(errorMsg);
|
|
287
|
+
setRecordingState('error');
|
|
288
|
+
isRecordingRef.current = false;
|
|
289
|
+
if (options.onError) {
|
|
290
|
+
options.onError(errorMsg);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
}, [recordingState, options, stopSilenceDetection]);
|
|
294
|
+
const toggleRecording = useCallback(async () => {
|
|
295
|
+
if (recordingState === 'recording') {
|
|
296
|
+
stopRecording();
|
|
297
|
+
}
|
|
298
|
+
else if (recordingState === 'idle') {
|
|
299
|
+
await startRecording();
|
|
300
|
+
}
|
|
301
|
+
}, [recordingState, startRecording, stopRecording]);
|
|
302
|
+
const toggleMute = useCallback((mute) => {
|
|
303
|
+
const newMuteState = mute !== undefined ? mute : !microphoneMuted;
|
|
304
|
+
setMicrophoneMuted(newMuteState);
|
|
305
|
+
if (newMuteState && recordingState === 'recording') {
|
|
306
|
+
stopRecording();
|
|
307
|
+
}
|
|
308
|
+
}, [microphoneMuted, recordingState, stopRecording]);
|
|
309
|
+
const cleanup = useCallback(() => {
|
|
310
|
+
isRecordingRef.current = false;
|
|
311
|
+
if (mediaRecorderRef.current) {
|
|
312
|
+
if (mediaRecorderRef.current.state === 'recording') {
|
|
313
|
+
mediaRecorderRef.current.stop();
|
|
314
|
+
}
|
|
315
|
+
mediaRecorderRef.current = null;
|
|
316
|
+
}
|
|
317
|
+
if (audioStreamRef.current) {
|
|
318
|
+
audioStreamRef.current.getTracks().forEach(track => track.stop());
|
|
319
|
+
audioStreamRef.current = null;
|
|
320
|
+
}
|
|
321
|
+
if (audioContextRef.current) {
|
|
322
|
+
audioContextRef.current.close();
|
|
323
|
+
audioContextRef.current = null;
|
|
324
|
+
}
|
|
325
|
+
stopSilenceDetection();
|
|
326
|
+
chunksRef.current = [];
|
|
327
|
+
setIsListening(false);
|
|
328
|
+
setRecordingState('idle');
|
|
329
|
+
}, [stopSilenceDetection]);
|
|
330
|
+
useEffect(() => {
|
|
331
|
+
return () => {
|
|
332
|
+
isMountedRef.current = false;
|
|
333
|
+
cleanup();
|
|
334
|
+
};
|
|
335
|
+
}, [cleanup]);
|
|
336
|
+
useEffect(() => {
|
|
337
|
+
if (typeof window !== 'undefined') {
|
|
338
|
+
window.memoriListening = isListening;
|
|
339
|
+
}
|
|
340
|
+
}, [isListening]);
|
|
341
|
+
return {
|
|
342
|
+
recordingState,
|
|
343
|
+
microphoneMuted,
|
|
344
|
+
hasUserActivatedRecord,
|
|
345
|
+
error,
|
|
346
|
+
lastTranscription,
|
|
347
|
+
isListening,
|
|
348
|
+
startRecording,
|
|
349
|
+
stopRecording,
|
|
350
|
+
toggleRecording,
|
|
351
|
+
toggleMute,
|
|
352
|
+
transcribeAudio,
|
|
353
|
+
setHasUserActivatedRecord,
|
|
354
|
+
setError,
|
|
355
|
+
cleanup,
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
//# sourceMappingURL=useSTT.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useSTT.js","sourceRoot":"","sources":["../../../src/helpers/stt/useSTT.ts"],"names":[],"mappings":"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"}
|
package/esm/locales/de.json
CHANGED
|
@@ -270,6 +270,17 @@
|
|
|
270
270
|
"editAccount": "Konto bearbeiten",
|
|
271
271
|
"save": "Speichern"
|
|
272
272
|
},
|
|
273
|
+
"chatLogs": {
|
|
274
|
+
"anyMessage": "Jede Nachricht",
|
|
275
|
+
"atLeast": "Mindestens {{count}} Nachrichten",
|
|
276
|
+
"atLeast2": "Mindestens 2 Nachrichten",
|
|
277
|
+
"atLeast3": "Mindestens 3 Nachrichten",
|
|
278
|
+
"atLeast5": "Mindestens 5 Nachrichten",
|
|
279
|
+
"atLeast10": "Mindestens 10 Nachrichten",
|
|
280
|
+
"atLeast15": "Mindestens 15 Nachrichten",
|
|
281
|
+
"atLeast20": "Mindestens 20 Nachrichten",
|
|
282
|
+
"customMinimumMessages": "Anpassen Sie die Anzahl der Nachrichten"
|
|
283
|
+
},
|
|
273
284
|
"success": "Erfolg",
|
|
274
285
|
"Error": "Fehler",
|
|
275
286
|
"internal server error": "Oupsie, tut mir leid... Auf dem Server ist ein Fehler aufgetreten",
|
package/esm/locales/en.json
CHANGED
|
@@ -292,6 +292,17 @@
|
|
|
292
292
|
"editAccount": "Edit account",
|
|
293
293
|
"save": "Save"
|
|
294
294
|
},
|
|
295
|
+
"chatLogs": {
|
|
296
|
+
"anyMessage": "Any message",
|
|
297
|
+
"atLeast": "At least {{count}} messages",
|
|
298
|
+
"atLeast2": "At least 2 messages",
|
|
299
|
+
"atLeast3": "At least 3 messages",
|
|
300
|
+
"atLeast5": "At least 5 messages",
|
|
301
|
+
"atLeast10": "At least 10 messages",
|
|
302
|
+
"atLeast15": "At least 15 messages",
|
|
303
|
+
"atLeast20": "At least 20 messages",
|
|
304
|
+
"customMinimumMessages": "Customize the number of messages"
|
|
305
|
+
},
|
|
295
306
|
"success": "Success",
|
|
296
307
|
"Error": "Error",
|
|
297
308
|
"internal server error": "Oupsie, sorry... Something went wrong on the server",
|
package/esm/locales/es.json
CHANGED
|
@@ -270,6 +270,17 @@
|
|
|
270
270
|
"editAccount": "Editar cuenta",
|
|
271
271
|
"save": "Ahorrar"
|
|
272
272
|
},
|
|
273
|
+
"chatLogs": {
|
|
274
|
+
"anyMessage": "Cualquier mensaje",
|
|
275
|
+
"atLeast": "Al menos {{count}} mensajes",
|
|
276
|
+
"atLeast2": "Al menos 2 mensajes",
|
|
277
|
+
"atLeast3": "Al menos 3 mensajes",
|
|
278
|
+
"atLeast5": "Al menos 5 mensajes",
|
|
279
|
+
"atLeast10": "Al menos 10 mensajes",
|
|
280
|
+
"atLeast15": "Al menos 15 mensajes",
|
|
281
|
+
"atLeast20": "Al menos 20 mensajes",
|
|
282
|
+
"customMinimumMessages": "Personalizar el número de mensajes"
|
|
283
|
+
},
|
|
273
284
|
"success": "Éxito",
|
|
274
285
|
"Error": "Error",
|
|
275
286
|
"internal server error": "Oupsie, lo siento... Algo salió mal en el servidor.",
|
package/esm/locales/fr.json
CHANGED
|
@@ -279,6 +279,17 @@
|
|
|
279
279
|
"editAccount": "Modifier le compte",
|
|
280
280
|
"save": "Sauvegarder"
|
|
281
281
|
},
|
|
282
|
+
"chatLogs": {
|
|
283
|
+
"anyMessage": "Tout message",
|
|
284
|
+
"atLeast": "Au moins {{count}} messages",
|
|
285
|
+
"atLeast2": "Au moins 2 messages",
|
|
286
|
+
"atLeast3": "Au moins 3 messages",
|
|
287
|
+
"atLeast5": "Au moins 5 messages",
|
|
288
|
+
"atLeast10": "Au moins 10 messages",
|
|
289
|
+
"atLeast15": "Au moins 15 messages",
|
|
290
|
+
"atLeast20": "Au moins 20 messages",
|
|
291
|
+
"customMinimumMessages": "Personnaliser le nombre de messages"
|
|
292
|
+
},
|
|
282
293
|
"success": "Succès",
|
|
283
294
|
"Error": "Erreur",
|
|
284
295
|
"internal server error": "Oupsie, désolé... Quelque chose s'est mal passé sur le serveur",
|
package/esm/locales/it.json
CHANGED
|
@@ -293,6 +293,17 @@
|
|
|
293
293
|
"editAccount": "Modifica account",
|
|
294
294
|
"save": "Salva"
|
|
295
295
|
},
|
|
296
|
+
"chatLogs": {
|
|
297
|
+
"atLeast": "Almeno {{count}} messaggi",
|
|
298
|
+
"anyMessage": "Qualunque messaggio",
|
|
299
|
+
"atLeast2": "Almeno 2 messaggi",
|
|
300
|
+
"atLeast3": "Almeno 3 messaggi",
|
|
301
|
+
"atLeast5": "Almeno 5 messaggi",
|
|
302
|
+
"atLeast10": "Almeno 10 messaggi",
|
|
303
|
+
"atLeast15": "Almeno 15 messaggi",
|
|
304
|
+
"atLeast20": "Almeno 20 messaggi",
|
|
305
|
+
"customMinimumMessages": "Personalizza il numero di messaggi"
|
|
306
|
+
},
|
|
296
307
|
"success": "Operazione andata a buon fine",
|
|
297
308
|
"Error": "Errore",
|
|
298
309
|
"internal server error": "Ops, scusa... qualcosa è andato storto nel server",
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "8.0.
|
|
2
|
+
"version": "8.1.0-rc.0",
|
|
3
3
|
"name": "@memori.ai/memori-react",
|
|
4
4
|
"author": "Memori Srl",
|
|
5
5
|
"main": "dist/index.js",
|
|
@@ -292,7 +292,7 @@
|
|
|
292
292
|
},
|
|
293
293
|
"dependencies": {
|
|
294
294
|
"@headlessui/react": "1.7.4",
|
|
295
|
-
"@memori.ai/memori-api-client": "6.
|
|
295
|
+
"@memori.ai/memori-api-client": "6.12.1",
|
|
296
296
|
"@react-three/drei": "8.20.2",
|
|
297
297
|
"@react-three/fiber": "7.0.25",
|
|
298
298
|
"classnames": "2.5.1",
|
|
@@ -306,7 +306,6 @@
|
|
|
306
306
|
"marked": "^15.0.2",
|
|
307
307
|
"marked-katex-extension": "^5.1.3",
|
|
308
308
|
"marked-linkify-it": "^3.1.12",
|
|
309
|
-
"microsoft-cognitiveservices-speech-sdk": "^1.43.1",
|
|
310
309
|
"qrcode.react": "3.1.0",
|
|
311
310
|
"react-hook-form": "7.39.5",
|
|
312
311
|
"react-hot-toast": "^2.4.1",
|
|
@@ -52,7 +52,6 @@ it('renders Chat unchanged', () => {
|
|
|
52
52
|
listening={false}
|
|
53
53
|
startListening={jest.fn()}
|
|
54
54
|
stopListening={jest.fn()}
|
|
55
|
-
resetTranscript={jest.fn()}
|
|
56
55
|
setEnableFocusChatInput={jest.fn()}
|
|
57
56
|
/>
|
|
58
57
|
);
|
|
@@ -77,7 +76,6 @@ it('renders Chat with memori typing unchanged', () => {
|
|
|
77
76
|
onChangeUserMessage={jest.fn()}
|
|
78
77
|
sendMessage={jest.fn()}
|
|
79
78
|
stopListening={jest.fn()}
|
|
80
|
-
resetTranscript={jest.fn()}
|
|
81
79
|
isPlayingAudio={false}
|
|
82
80
|
stopAudio={jest.fn()}
|
|
83
81
|
showMicrophone={false}
|
|
@@ -108,7 +106,6 @@ it('renders Chat with hints unchanged', () => {
|
|
|
108
106
|
onChangeUserMessage={jest.fn()}
|
|
109
107
|
sendMessage={jest.fn()}
|
|
110
108
|
stopListening={jest.fn()}
|
|
111
|
-
resetTranscript={jest.fn()}
|
|
112
109
|
isPlayingAudio={false}
|
|
113
110
|
stopAudio={jest.fn()}
|
|
114
111
|
showMicrophone={false}
|
|
@@ -138,7 +135,6 @@ it('renders Chat with media unchanged', () => {
|
|
|
138
135
|
onChangeUserMessage={jest.fn()}
|
|
139
136
|
sendMessage={jest.fn()}
|
|
140
137
|
stopListening={jest.fn()}
|
|
141
|
-
resetTranscript={jest.fn()}
|
|
142
138
|
isPlayingAudio={false}
|
|
143
139
|
stopAudio={jest.fn()}
|
|
144
140
|
showMicrophone={false}
|
|
@@ -168,7 +164,6 @@ it('renders Chat with dates unchanged', () => {
|
|
|
168
164
|
onChangeUserMessage={jest.fn()}
|
|
169
165
|
sendMessage={jest.fn()}
|
|
170
166
|
stopListening={jest.fn()}
|
|
171
|
-
resetTranscript={jest.fn()}
|
|
172
167
|
isPlayingAudio={false}
|
|
173
168
|
stopAudio={jest.fn()}
|
|
174
169
|
showMicrophone={false}
|
|
@@ -199,7 +194,6 @@ it('renders Chat with context vars unchanged', () => {
|
|
|
199
194
|
onChangeUserMessage={jest.fn()}
|
|
200
195
|
sendMessage={jest.fn()}
|
|
201
196
|
stopListening={jest.fn()}
|
|
202
|
-
resetTranscript={jest.fn()}
|
|
203
197
|
isPlayingAudio={false}
|
|
204
198
|
stopAudio={jest.fn()}
|
|
205
199
|
showMicrophone={false}
|
|
@@ -236,7 +230,6 @@ it('renders Chat with user unchanged', () => {
|
|
|
236
230
|
listening={false}
|
|
237
231
|
startListening={jest.fn()}
|
|
238
232
|
stopListening={jest.fn()}
|
|
239
|
-
resetTranscript={jest.fn()}
|
|
240
233
|
setEnableFocusChatInput={jest.fn()}
|
|
241
234
|
/>
|
|
242
235
|
);
|
|
@@ -267,7 +260,6 @@ it('renders Chat with custom user avatar unchanged', () => {
|
|
|
267
260
|
listening={false}
|
|
268
261
|
startListening={jest.fn()}
|
|
269
262
|
stopListening={jest.fn()}
|
|
270
|
-
resetTranscript={jest.fn()}
|
|
271
263
|
setEnableFocusChatInput={jest.fn()}
|
|
272
264
|
/>
|
|
273
265
|
);
|
|
@@ -298,7 +290,6 @@ it('renders Chat with custom user avatar as react element unchanged', () => {
|
|
|
298
290
|
listening={false}
|
|
299
291
|
startListening={jest.fn()}
|
|
300
292
|
stopListening={jest.fn()}
|
|
301
|
-
resetTranscript={jest.fn()}
|
|
302
293
|
setEnableFocusChatInput={jest.fn()}
|
|
303
294
|
/>
|
|
304
295
|
);
|
|
@@ -63,7 +63,6 @@ export interface Props {
|
|
|
63
63
|
stopAudio: () => void;
|
|
64
64
|
startListening: () => void;
|
|
65
65
|
stopListening: () => void;
|
|
66
|
-
resetTranscript: () => void;
|
|
67
66
|
customMediaRenderer?: MediaWidgetProps['customMediaRenderer'];
|
|
68
67
|
layout?: MemoriProps['layout'];
|
|
69
68
|
userAvatar?: MemoriProps['userAvatar'];
|
|
@@ -72,7 +71,6 @@ export interface Props {
|
|
|
72
71
|
useMathFormatting?: boolean;
|
|
73
72
|
isHistoryView?: boolean;
|
|
74
73
|
showFunctionCache?: boolean;
|
|
75
|
-
provider?: 'azure' | 'openai';
|
|
76
74
|
}
|
|
77
75
|
|
|
78
76
|
const Chat: React.FC<Props> = ({
|
|
@@ -115,7 +113,6 @@ const Chat: React.FC<Props> = ({
|
|
|
115
113
|
stopAudio,
|
|
116
114
|
startListening,
|
|
117
115
|
stopListening,
|
|
118
|
-
resetTranscript,
|
|
119
116
|
customMediaRenderer,
|
|
120
117
|
user,
|
|
121
118
|
userAvatar,
|
|
@@ -124,7 +121,6 @@ const Chat: React.FC<Props> = ({
|
|
|
124
121
|
useMathFormatting = false,
|
|
125
122
|
isHistoryView = false,
|
|
126
123
|
showFunctionCache = false,
|
|
127
|
-
provider = 'azure',
|
|
128
124
|
}) => {
|
|
129
125
|
const scrollToBottom = () => {
|
|
130
126
|
if (isHistoryView) return;
|
|
@@ -398,7 +394,6 @@ const Chat: React.FC<Props> = ({
|
|
|
398
394
|
|
|
399
395
|
{showInputs && (
|
|
400
396
|
<ChatInputs
|
|
401
|
-
resetTranscript={resetTranscript}
|
|
402
397
|
userMessage={userMessage}
|
|
403
398
|
onChangeUserMessage={onChangeUserMessage}
|
|
404
399
|
dialogState={dialogState}
|
|
@@ -422,7 +417,6 @@ const Chat: React.FC<Props> = ({
|
|
|
422
417
|
isPlayingAudio={isPlayingAudio}
|
|
423
418
|
showMicrophone={showMicrophone}
|
|
424
419
|
memoriID={memori?.memoriID}
|
|
425
|
-
provider={provider}
|
|
426
420
|
/>
|
|
427
421
|
)}
|
|
428
422
|
</div>
|
|
@@ -16,6 +16,38 @@
|
|
|
16
16
|
flex-direction: column;
|
|
17
17
|
gap: 1rem;
|
|
18
18
|
}
|
|
19
|
+
.memori-chat-history-drawer--toolbar--min-messages-filter{
|
|
20
|
+
display: flex;
|
|
21
|
+
flex-direction: row;
|
|
22
|
+
align-items: center;
|
|
23
|
+
gap: 0.5rem;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.memori-chat-history-drawer--toolbar--min-messages-filter--select{
|
|
27
|
+
width: 100%;
|
|
28
|
+
min-width: 240px;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.memori-chat-history-drawer--toolbar--min-messages-filter--input-number{
|
|
32
|
+
position: relative;
|
|
33
|
+
width: 100%;
|
|
34
|
+
max-width: 60px;
|
|
35
|
+
min-height: 32px;
|
|
36
|
+
/* padding-top: 0.5rem;
|
|
37
|
+
padding-right: 2.5rem;
|
|
38
|
+
padding-bottom: 0.5rem;
|
|
39
|
+
padding-left: 0.75rem; */
|
|
40
|
+
border: 1px solid #e5e7eb;
|
|
41
|
+
border-radius: 0.5rem;
|
|
42
|
+
background: transparent;
|
|
43
|
+
box-shadow: rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0) 0px 0px 0px 0px, rgba(0, 0, 0, 0.1) 0px 4px 6px -1px,
|
|
44
|
+
rgba(0, 0, 0, 0.1) 0px 2px 4px -2px;
|
|
45
|
+
color: var(--memori-text-color, #333);
|
|
46
|
+
cursor: pointer;
|
|
47
|
+
font-family: var(--memori-font-family);
|
|
48
|
+
font-size: 16px;
|
|
49
|
+
text-align: left;
|
|
50
|
+
}
|
|
19
51
|
|
|
20
52
|
.memori-chat-history-drawer--card--header {
|
|
21
53
|
position: sticky;
|