@magmamath/students-features 1.5.3-rc.3 → 1.5.3-rc.4
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/dist/commonjs/features/chatbot/model/VoiceTranscriptSnapshotModel.js +23 -4
- package/dist/commonjs/features/chatbot/model/VoiceTranscriptSnapshotModel.js.map +1 -1
- package/dist/commonjs/lib/effector/createControllerEffect.js +7 -6
- package/dist/commonjs/lib/effector/createControllerEffect.js.map +1 -1
- package/dist/module/features/chatbot/model/VoiceTranscriptSnapshotModel.js +23 -4
- package/dist/module/features/chatbot/model/VoiceTranscriptSnapshotModel.js.map +1 -1
- package/dist/module/lib/effector/createControllerEffect.js +7 -6
- package/dist/module/lib/effector/createControllerEffect.js.map +1 -1
- package/dist/typescript/commonjs/features/chatbot/model/VoiceTranscriptSnapshotModel.d.ts +2 -0
- package/dist/typescript/commonjs/features/chatbot/model/VoiceTranscriptSnapshotModel.d.ts.map +1 -1
- package/dist/typescript/commonjs/lib/effector/createControllerEffect.d.ts +1 -0
- package/dist/typescript/commonjs/lib/effector/createControllerEffect.d.ts.map +1 -1
- package/dist/typescript/module/features/chatbot/model/VoiceTranscriptSnapshotModel.d.ts +2 -0
- package/dist/typescript/module/features/chatbot/model/VoiceTranscriptSnapshotModel.d.ts.map +1 -1
- package/dist/typescript/module/lib/effector/createControllerEffect.d.ts +1 -0
- package/dist/typescript/module/lib/effector/createControllerEffect.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/features/chatbot/model/VoiceTranscriptSnapshotModel.ts +27 -4
- package/src/lib/effector/createControllerEffect.ts +13 -6
|
@@ -8,6 +8,7 @@ var _effector = require("effector");
|
|
|
8
8
|
var _types = require("../../voice/types.js");
|
|
9
9
|
const TRANSCRIPT_RETRY_INTERVAL_MS = 2000;
|
|
10
10
|
const TRANSCRIPT_MAX_RETRIES = 20;
|
|
11
|
+
const CHAT_WITH_VOICE_TIMEOUT_MS = 60_000;
|
|
11
12
|
// Voice key: `${assignmentId}-${problemId}-${attemptsCount}`
|
|
12
13
|
// Chat key: `${assignmentId}-${problemId}` — survives attempt increments and voice deletion.
|
|
13
14
|
const toChatKey = voiceKey => {
|
|
@@ -39,6 +40,9 @@ class VoiceTranscriptSnapshotModel {
|
|
|
39
40
|
};
|
|
40
41
|
wrapRequestHint = apiFn => {
|
|
41
42
|
return async (params, requestConfig) => {
|
|
43
|
+
if (this.hasPendingVoice()) {
|
|
44
|
+
requestConfig?.extendTimeoutMs?.(CHAT_WITH_VOICE_TIMEOUT_MS);
|
|
45
|
+
}
|
|
42
46
|
const voiceTranscript = await this.getTranscriptForCurrent();
|
|
43
47
|
return apiFn(voiceTranscript ? {
|
|
44
48
|
...params,
|
|
@@ -46,6 +50,13 @@ class VoiceTranscriptSnapshotModel {
|
|
|
46
50
|
} : params, requestConfig);
|
|
47
51
|
};
|
|
48
52
|
};
|
|
53
|
+
hasPendingVoice() {
|
|
54
|
+
const voiceKey = this.voiceRecord.$currentKey.getState();
|
|
55
|
+
if (!voiceKey) return false;
|
|
56
|
+
const chatKey = toChatKey(voiceKey);
|
|
57
|
+
if (chatKey && this.snapshotByChatKey.has(chatKey)) return true;
|
|
58
|
+
return !!this.voiceRecord.collection.get(voiceKey);
|
|
59
|
+
}
|
|
49
60
|
constructor({
|
|
50
61
|
voiceRecord,
|
|
51
62
|
api
|
|
@@ -62,18 +73,26 @@ class VoiceTranscriptSnapshotModel {
|
|
|
62
73
|
}),
|
|
63
74
|
target: this.captureSnapshotFx
|
|
64
75
|
});
|
|
76
|
+
(0, _effector.sample)({
|
|
77
|
+
clock: voiceRecord.deleteCurrentRecording,
|
|
78
|
+
source: voiceRecord.$currentKey,
|
|
79
|
+
target: this.clearSnapshotFx
|
|
80
|
+
});
|
|
65
81
|
}
|
|
66
82
|
transcriptByAudioFileId = new Map();
|
|
67
83
|
snapshotByChatKey = new Map();
|
|
68
|
-
captureSnapshotFx = (0, _effector.createEffect)(
|
|
84
|
+
captureSnapshotFx = (0, _effector.createEffect)(({
|
|
69
85
|
voiceKey,
|
|
70
86
|
record
|
|
71
87
|
}) => {
|
|
72
88
|
const chatKey = toChatKey(voiceKey);
|
|
73
89
|
if (!chatKey) return;
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
90
|
+
const transcriptPromise = this.resolveAudioFileId(record).then(audioFileId => audioFileId ? this.fetchTranscript(audioFileId) : undefined);
|
|
91
|
+
this.snapshotByChatKey.set(chatKey, transcriptPromise);
|
|
92
|
+
});
|
|
93
|
+
clearSnapshotFx = (0, _effector.createEffect)(voiceKey => {
|
|
94
|
+
const chatKey = toChatKey(voiceKey);
|
|
95
|
+
if (chatKey) this.snapshotByChatKey.delete(chatKey);
|
|
77
96
|
});
|
|
78
97
|
async pollTranscript(audioFileId) {
|
|
79
98
|
for (let attempt = 0; attempt < TRANSCRIPT_MAX_RETRIES; attempt++) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_effector","require","_types","TRANSCRIPT_RETRY_INTERVAL_MS","TRANSCRIPT_MAX_RETRIES","toChatKey","voiceKey","lastDashIndex","lastIndexOf","slice","VoiceTranscriptSnapshotModel","fetchTranscript","audioFileId","cached","transcriptByAudioFileId","get","promise","pollTranscript","catch","undefined","set","getTranscriptForCurrent","voiceRecord","$currentKey","getState","chatKey","snapshot","snapshotByChatKey","record","collection","resolveAudioFileId","wrapRequestHint","apiFn","params","requestConfig","voiceTranscript","constructor","api","sample","clock","setCurrentRecord","source","filter","_","fn","target","captureSnapshotFx","Map","createEffect","attempt","Promise","resolve","setTimeout","response","getAudioFileTranscript","status","TranscriptionStatus","COMPLETED","text","FAILED","id","audioUploadPromise","result","exports"],"sourceRoot":"../../../../../src","sources":["features/chatbot/model/VoiceTranscriptSnapshotModel.ts"],"mappings":";;;;;;AAAA,IAAAA,SAAA,GAAAC,OAAA;AACA,IAAAC,MAAA,GAAAD,OAAA;AAQA,MAAME,4BAA4B,GAAG,IAAI;AACzC,MAAMC,sBAAsB,GAAG,EAAE;
|
|
1
|
+
{"version":3,"names":["_effector","require","_types","TRANSCRIPT_RETRY_INTERVAL_MS","TRANSCRIPT_MAX_RETRIES","CHAT_WITH_VOICE_TIMEOUT_MS","toChatKey","voiceKey","lastDashIndex","lastIndexOf","slice","VoiceTranscriptSnapshotModel","fetchTranscript","audioFileId","cached","transcriptByAudioFileId","get","promise","pollTranscript","catch","undefined","set","getTranscriptForCurrent","voiceRecord","$currentKey","getState","chatKey","snapshot","snapshotByChatKey","record","collection","resolveAudioFileId","wrapRequestHint","apiFn","params","requestConfig","hasPendingVoice","extendTimeoutMs","voiceTranscript","has","constructor","api","sample","clock","setCurrentRecord","source","filter","_","fn","target","captureSnapshotFx","deleteCurrentRecording","clearSnapshotFx","Map","createEffect","transcriptPromise","then","delete","attempt","Promise","resolve","setTimeout","response","getAudioFileTranscript","status","TranscriptionStatus","COMPLETED","text","FAILED","id","audioUploadPromise","result","exports"],"sourceRoot":"../../../../../src","sources":["features/chatbot/model/VoiceTranscriptSnapshotModel.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -13,14 +13,15 @@ function controlledRequest(request) {
|
|
|
13
13
|
abortAfter = 20000
|
|
14
14
|
}) => {
|
|
15
15
|
let timeout = null;
|
|
16
|
-
|
|
17
|
-
timeout
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
const scheduleAbort = ms => {
|
|
17
|
+
if (timeout !== null) clearTimeout(timeout);
|
|
18
|
+
timeout = ms > 0 ? setTimeout(() => controller.abort('timeout'), ms) : null;
|
|
19
|
+
};
|
|
20
|
+
if (abortAfter) scheduleAbort(abortAfter);
|
|
21
21
|
try {
|
|
22
22
|
const response = await request(data, {
|
|
23
|
-
signal: controller?.signal
|
|
23
|
+
signal: controller?.signal,
|
|
24
|
+
extendTimeoutMs: scheduleAbort
|
|
24
25
|
});
|
|
25
26
|
if (timeout !== null) clearTimeout(timeout);
|
|
26
27
|
return response;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_effector","require","controlledRequest","request","data","controller","AbortController","abortAfter","timeout","setTimeout","abort","response","signal","
|
|
1
|
+
{"version":3,"names":["_effector","require","controlledRequest","request","data","controller","AbortController","abortAfter","timeout","scheduleAbort","ms","clearTimeout","setTimeout","abort","response","signal","extendTimeoutMs","error","code","reason","Error","createControllerEffect","fn","effect","createEffect","fail","watch","exports"],"sourceRoot":"../../../../src","sources":["lib/effector/createControllerEffect.ts"],"mappings":";;;;;;;AAAA,IAAAA,SAAA,GAAAC,OAAA;AAqBO,SAASC,iBAAiBA,CAC/BC,OAAiE,EACjE;EACA,OAAO,OAAO;IACZC,IAAI;IACJC,UAAU,GAAG,IAAIC,eAAe,CAAC,CAAC;IAClCC,UAAU,GAAG;EACY,CAAC,KAAK;IAC/B,IAAIC,OAA6C,GAAG,IAAI;IAExD,MAAMC,aAAa,GAAIC,EAAU,IAAK;MACpC,IAAIF,OAAO,KAAK,IAAI,EAAEG,YAAY,CAACH,OAAO,CAAC;MAC3CA,OAAO,GAAGE,EAAE,GAAG,CAAC,GAAGE,UAAU,CAAC,MAAMP,UAAU,CAACQ,KAAK,CAAC,SAAS,CAAC,EAAEH,EAAE,CAAC,GAAG,IAAI;IAC7E,CAAC;IAED,IAAIH,UAAU,EAAEE,aAAa,CAACF,UAAU,CAAC;IAEzC,IAAI;MACF,MAAMO,QAAQ,GAAG,MAAMX,OAAO,CAACC,IAAI,EAAE;QACnCW,MAAM,EAAEV,UAAU,EAAEU,MAAM;QAC1BC,eAAe,EAAEP;MACnB,CAAC,CAAC;MACF,IAAID,OAAO,KAAK,IAAI,EAAEG,YAAY,CAACH,OAAO,CAAC;MAC3C,OAAOM,QAAQ;IACjB,CAAC,CAAC,OAAOG,KAAc,EAAE;MACvB,IAAKA,KAAK,CAAuBC,IAAI,KAAK,cAAc,EAAE;QACxD,IAAIb,UAAU,CAACU,MAAM,CAACI,MAAM,KAAK,SAAS,EAAE;UAC1C,MAAM,IAAIC,KAAK,CAAC,mBAAmB,CAAC;QACtC;QACA,MAAM,IAAIA,KAAK,CAAC,0BAA0B,CAAC;MAC7C;MAEA,MAAMH,KAAK;IACb;EACF,CAAC;AACH;AAEO,MAAMI,sBAAsB,GACjCC,EAA4D,IACzD;EACH,MAAMnB,OAAO,GAAGD,iBAAiB,CAAOoB,EAAE,CAAC;EAC3C,MAAMC,MAAM,GAAG,IAAAC,sBAAY,EAAEpB,IAAO,IAClCD,OAAO,CAAC;IAAEC,IAAI;IAAEC,UAAU,EAAEkB,MAAM,CAAClB;EAAW,CAAC,CACjD,CAA2B;EAC3BkB,MAAM,CAAClB,UAAU,GAAG,IAAIC,eAAe,CAAC,CAAC;EAEzCiB,MAAM,CAACE,IAAI,CAACC,KAAK,CAAC,MAAM;IACtBH,MAAM,CAAClB,UAAU,GAAG,IAAIC,eAAe,CAAC,CAAC;EAC3C,CAAC,CAAC;EAEF,OAAOiB,MAAM;AACf,CAAC;AAAAI,OAAA,CAAAN,sBAAA,GAAAA,sBAAA","ignoreList":[]}
|
|
@@ -4,6 +4,7 @@ import { createEffect, sample } from 'effector';
|
|
|
4
4
|
import { TranscriptionStatus } from "../../voice/types.js";
|
|
5
5
|
const TRANSCRIPT_RETRY_INTERVAL_MS = 2000;
|
|
6
6
|
const TRANSCRIPT_MAX_RETRIES = 20;
|
|
7
|
+
const CHAT_WITH_VOICE_TIMEOUT_MS = 60_000;
|
|
7
8
|
// Voice key: `${assignmentId}-${problemId}-${attemptsCount}`
|
|
8
9
|
// Chat key: `${assignmentId}-${problemId}` — survives attempt increments and voice deletion.
|
|
9
10
|
const toChatKey = voiceKey => {
|
|
@@ -35,6 +36,9 @@ export class VoiceTranscriptSnapshotModel {
|
|
|
35
36
|
};
|
|
36
37
|
wrapRequestHint = apiFn => {
|
|
37
38
|
return async (params, requestConfig) => {
|
|
39
|
+
if (this.hasPendingVoice()) {
|
|
40
|
+
requestConfig?.extendTimeoutMs?.(CHAT_WITH_VOICE_TIMEOUT_MS);
|
|
41
|
+
}
|
|
38
42
|
const voiceTranscript = await this.getTranscriptForCurrent();
|
|
39
43
|
return apiFn(voiceTranscript ? {
|
|
40
44
|
...params,
|
|
@@ -42,6 +46,13 @@ export class VoiceTranscriptSnapshotModel {
|
|
|
42
46
|
} : params, requestConfig);
|
|
43
47
|
};
|
|
44
48
|
};
|
|
49
|
+
hasPendingVoice() {
|
|
50
|
+
const voiceKey = this.voiceRecord.$currentKey.getState();
|
|
51
|
+
if (!voiceKey) return false;
|
|
52
|
+
const chatKey = toChatKey(voiceKey);
|
|
53
|
+
if (chatKey && this.snapshotByChatKey.has(chatKey)) return true;
|
|
54
|
+
return !!this.voiceRecord.collection.get(voiceKey);
|
|
55
|
+
}
|
|
45
56
|
constructor({
|
|
46
57
|
voiceRecord,
|
|
47
58
|
api
|
|
@@ -58,18 +69,26 @@ export class VoiceTranscriptSnapshotModel {
|
|
|
58
69
|
}),
|
|
59
70
|
target: this.captureSnapshotFx
|
|
60
71
|
});
|
|
72
|
+
sample({
|
|
73
|
+
clock: voiceRecord.deleteCurrentRecording,
|
|
74
|
+
source: voiceRecord.$currentKey,
|
|
75
|
+
target: this.clearSnapshotFx
|
|
76
|
+
});
|
|
61
77
|
}
|
|
62
78
|
transcriptByAudioFileId = new Map();
|
|
63
79
|
snapshotByChatKey = new Map();
|
|
64
|
-
captureSnapshotFx = createEffect(
|
|
80
|
+
captureSnapshotFx = createEffect(({
|
|
65
81
|
voiceKey,
|
|
66
82
|
record
|
|
67
83
|
}) => {
|
|
68
84
|
const chatKey = toChatKey(voiceKey);
|
|
69
85
|
if (!chatKey) return;
|
|
70
|
-
const
|
|
71
|
-
|
|
72
|
-
|
|
86
|
+
const transcriptPromise = this.resolveAudioFileId(record).then(audioFileId => audioFileId ? this.fetchTranscript(audioFileId) : undefined);
|
|
87
|
+
this.snapshotByChatKey.set(chatKey, transcriptPromise);
|
|
88
|
+
});
|
|
89
|
+
clearSnapshotFx = createEffect(voiceKey => {
|
|
90
|
+
const chatKey = toChatKey(voiceKey);
|
|
91
|
+
if (chatKey) this.snapshotByChatKey.delete(chatKey);
|
|
73
92
|
});
|
|
74
93
|
async pollTranscript(audioFileId) {
|
|
75
94
|
for (let attempt = 0; attempt < TRANSCRIPT_MAX_RETRIES; attempt++) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["createEffect","sample","TranscriptionStatus","TRANSCRIPT_RETRY_INTERVAL_MS","TRANSCRIPT_MAX_RETRIES","toChatKey","voiceKey","lastDashIndex","lastIndexOf","slice","VoiceTranscriptSnapshotModel","fetchTranscript","audioFileId","cached","transcriptByAudioFileId","get","promise","pollTranscript","catch","undefined","set","getTranscriptForCurrent","voiceRecord","$currentKey","getState","chatKey","snapshot","snapshotByChatKey","record","collection","resolveAudioFileId","wrapRequestHint","apiFn","params","requestConfig","voiceTranscript","constructor","api","clock","setCurrentRecord","source","filter","_","fn","target","captureSnapshotFx","Map","attempt","Promise","resolve","setTimeout","response","getAudioFileTranscript","status","COMPLETED","text","FAILED","id","audioUploadPromise","result"],"sourceRoot":"../../../../../src","sources":["features/chatbot/model/VoiceTranscriptSnapshotModel.ts"],"mappings":";;AAAA,SAASA,YAAY,EAAEC,MAAM,QAAQ,UAAU;AAC/C,SAEEC,mBAAmB,QAEd,sBAAmB;AAI1B,MAAMC,4BAA4B,GAAG,IAAI;AACzC,MAAMC,sBAAsB,GAAG,EAAE;
|
|
1
|
+
{"version":3,"names":["createEffect","sample","TranscriptionStatus","TRANSCRIPT_RETRY_INTERVAL_MS","TRANSCRIPT_MAX_RETRIES","CHAT_WITH_VOICE_TIMEOUT_MS","toChatKey","voiceKey","lastDashIndex","lastIndexOf","slice","VoiceTranscriptSnapshotModel","fetchTranscript","audioFileId","cached","transcriptByAudioFileId","get","promise","pollTranscript","catch","undefined","set","getTranscriptForCurrent","voiceRecord","$currentKey","getState","chatKey","snapshot","snapshotByChatKey","record","collection","resolveAudioFileId","wrapRequestHint","apiFn","params","requestConfig","hasPendingVoice","extendTimeoutMs","voiceTranscript","has","constructor","api","clock","setCurrentRecord","source","filter","_","fn","target","captureSnapshotFx","deleteCurrentRecording","clearSnapshotFx","Map","transcriptPromise","then","delete","attempt","Promise","resolve","setTimeout","response","getAudioFileTranscript","status","COMPLETED","text","FAILED","id","audioUploadPromise","result"],"sourceRoot":"../../../../../src","sources":["features/chatbot/model/VoiceTranscriptSnapshotModel.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -8,14 +8,15 @@ export function controlledRequest(request) {
|
|
|
8
8
|
abortAfter = 20000
|
|
9
9
|
}) => {
|
|
10
10
|
let timeout = null;
|
|
11
|
-
|
|
12
|
-
timeout
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
const scheduleAbort = ms => {
|
|
12
|
+
if (timeout !== null) clearTimeout(timeout);
|
|
13
|
+
timeout = ms > 0 ? setTimeout(() => controller.abort('timeout'), ms) : null;
|
|
14
|
+
};
|
|
15
|
+
if (abortAfter) scheduleAbort(abortAfter);
|
|
16
16
|
try {
|
|
17
17
|
const response = await request(data, {
|
|
18
|
-
signal: controller?.signal
|
|
18
|
+
signal: controller?.signal,
|
|
19
|
+
extendTimeoutMs: scheduleAbort
|
|
19
20
|
});
|
|
20
21
|
if (timeout !== null) clearTimeout(timeout);
|
|
21
22
|
return response;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["createEffect","controlledRequest","request","data","controller","AbortController","abortAfter","timeout","setTimeout","abort","response","signal","
|
|
1
|
+
{"version":3,"names":["createEffect","controlledRequest","request","data","controller","AbortController","abortAfter","timeout","scheduleAbort","ms","clearTimeout","setTimeout","abort","response","signal","extendTimeoutMs","error","code","reason","Error","createControllerEffect","fn","effect","fail","watch"],"sourceRoot":"../../../../src","sources":["lib/effector/createControllerEffect.ts"],"mappings":";;AAAA,SAASA,YAAY,QAAqB,UAAU;AAqBpD,OAAO,SAASC,iBAAiBA,CAC/BC,OAAiE,EACjE;EACA,OAAO,OAAO;IACZC,IAAI;IACJC,UAAU,GAAG,IAAIC,eAAe,CAAC,CAAC;IAClCC,UAAU,GAAG;EACY,CAAC,KAAK;IAC/B,IAAIC,OAA6C,GAAG,IAAI;IAExD,MAAMC,aAAa,GAAIC,EAAU,IAAK;MACpC,IAAIF,OAAO,KAAK,IAAI,EAAEG,YAAY,CAACH,OAAO,CAAC;MAC3CA,OAAO,GAAGE,EAAE,GAAG,CAAC,GAAGE,UAAU,CAAC,MAAMP,UAAU,CAACQ,KAAK,CAAC,SAAS,CAAC,EAAEH,EAAE,CAAC,GAAG,IAAI;IAC7E,CAAC;IAED,IAAIH,UAAU,EAAEE,aAAa,CAACF,UAAU,CAAC;IAEzC,IAAI;MACF,MAAMO,QAAQ,GAAG,MAAMX,OAAO,CAACC,IAAI,EAAE;QACnCW,MAAM,EAAEV,UAAU,EAAEU,MAAM;QAC1BC,eAAe,EAAEP;MACnB,CAAC,CAAC;MACF,IAAID,OAAO,KAAK,IAAI,EAAEG,YAAY,CAACH,OAAO,CAAC;MAC3C,OAAOM,QAAQ;IACjB,CAAC,CAAC,OAAOG,KAAc,EAAE;MACvB,IAAKA,KAAK,CAAuBC,IAAI,KAAK,cAAc,EAAE;QACxD,IAAIb,UAAU,CAACU,MAAM,CAACI,MAAM,KAAK,SAAS,EAAE;UAC1C,MAAM,IAAIC,KAAK,CAAC,mBAAmB,CAAC;QACtC;QACA,MAAM,IAAIA,KAAK,CAAC,0BAA0B,CAAC;MAC7C;MAEA,MAAMH,KAAK;IACb;EACF,CAAC;AACH;AAEA,OAAO,MAAMI,sBAAsB,GACjCC,EAA4D,IACzD;EACH,MAAMnB,OAAO,GAAGD,iBAAiB,CAAOoB,EAAE,CAAC;EAC3C,MAAMC,MAAM,GAAGtB,YAAY,CAAEG,IAAO,IAClCD,OAAO,CAAC;IAAEC,IAAI;IAAEC,UAAU,EAAEkB,MAAM,CAAClB;EAAW,CAAC,CACjD,CAA2B;EAC3BkB,MAAM,CAAClB,UAAU,GAAG,IAAIC,eAAe,CAAC,CAAC;EAEzCiB,MAAM,CAACC,IAAI,CAACC,KAAK,CAAC,MAAM;IACtBF,MAAM,CAAClB,UAAU,GAAG,IAAIC,eAAe,CAAC,CAAC;EAC3C,CAAC,CAAC;EAEF,OAAOiB,MAAM;AACf,CAAC","ignoreList":[]}
|
|
@@ -14,12 +14,14 @@ export declare class VoiceTranscriptSnapshotModel {
|
|
|
14
14
|
readonly wrapRequestHint: <P extends object, R>(apiFn: (params: P & {
|
|
15
15
|
voiceTranscript?: string;
|
|
16
16
|
}, requestConfig?: RequestOptionalConfig) => Promise<R>) => (params: P, requestConfig?: RequestOptionalConfig) => Promise<R>;
|
|
17
|
+
private hasPendingVoice;
|
|
17
18
|
constructor({ voiceRecord, api }: VoiceTranscriptSnapshotModelProps);
|
|
18
19
|
private readonly voiceRecord;
|
|
19
20
|
private readonly api;
|
|
20
21
|
private readonly transcriptByAudioFileId;
|
|
21
22
|
private readonly snapshotByChatKey;
|
|
22
23
|
private readonly captureSnapshotFx;
|
|
24
|
+
private readonly clearSnapshotFx;
|
|
23
25
|
private pollTranscript;
|
|
24
26
|
private resolveAudioFileId;
|
|
25
27
|
}
|
package/dist/typescript/commonjs/features/chatbot/model/VoiceTranscriptSnapshotModel.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VoiceTranscriptSnapshotModel.d.ts","sourceRoot":"","sources":["../../../../../../src/features/chatbot/model/VoiceTranscriptSnapshotModel.ts"],"names":[],"mappings":"AACA,OAAO,EACL,uBAAuB,EAGxB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,gBAAgB,EAAE,MAAM,+CAA+C,CAAA;AAChF,OAAO,EAAE,qBAAqB,EAAE,MAAM,8CAA8C,CAAA;
|
|
1
|
+
{"version":3,"file":"VoiceTranscriptSnapshotModel.d.ts","sourceRoot":"","sources":["../../../../../../src/features/chatbot/model/VoiceTranscriptSnapshotModel.ts"],"names":[],"mappings":"AACA,OAAO,EACL,uBAAuB,EAGxB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,gBAAgB,EAAE,MAAM,+CAA+C,CAAA;AAChF,OAAO,EAAE,qBAAqB,EAAE,MAAM,8CAA8C,CAAA;AAMpF,KAAK,gBAAgB,GAAG;IACtB,sBAAsB,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,uBAAuB,CAAC,CAAA;CAClF,CAAA;AAOD,KAAK,iCAAiC,GAAG;IACvC,WAAW,EAAE,gBAAgB,CAAA;IAC7B,GAAG,EAAE,gBAAgB,CAAA;CACtB,CAAA;AAUD,qBAAa,4BAA4B;IACvC,SAAgB,eAAe,gBAAiB,MAAM,KAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAOnF;IAED,SAAgB,uBAAuB,QAAa,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAiB9E;IAED,SAAgB,eAAe,GAAI,CAAC,SAAS,MAAM,EAAE,CAAC,SAC7C,CACL,MAAM,EAAE,CAAC,GAAG;QAAE,eAAe,CAAC,EAAE,MAAM,CAAA;KAAE,EACxC,aAAa,CAAC,EAAE,qBAAqB,KAClC,OAAO,CAAC,CAAC,CAAC,cAEO,CAAC,kBAAkB,qBAAqB,KAAG,OAAO,CAAC,CAAC,CAAC,CAO5E;IAED,OAAO,CAAC,eAAe;gBAQX,EAAE,WAAW,EAAE,GAAG,EAAE,EAAE,iCAAiC;IAmBnE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAkB;IAC9C,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAkB;IACtC,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAiD;IACzF,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAiD;IAEnF,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAQhC;IAEF,OAAO,CAAC,QAAQ,CAAC,eAAe,CAG9B;YAEY,cAAc;YAYd,kBAAkB;CAUjC"}
|
|
@@ -9,6 +9,7 @@ type ControlledRequestProps<P> = {
|
|
|
9
9
|
};
|
|
10
10
|
export type RequestOptionalConfig = {
|
|
11
11
|
signal?: AbortSignal;
|
|
12
|
+
extendTimeoutMs?: (ms: number) => void;
|
|
12
13
|
};
|
|
13
14
|
export declare function controlledRequest<R = void, P = void>(request: (props: P, config?: RequestOptionalConfig) => Promise<R>): ({ data, controller, abortAfter, }: ControlledRequestProps<P>) => Promise<R>;
|
|
14
15
|
export declare const createControllerEffect: <T, P = void>(fn: (props: P, config?: RequestOptionalConfig) => Promise<T>) => ControlledEffect<P, T>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createControllerEffect.d.ts","sourceRoot":"","sources":["../../../../../src/lib/effector/createControllerEffect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,UAAU,CAAA;AAMpD,MAAM,MAAM,gBAAgB,CAAC,CAAC,EAAE,CAAC,IAAI,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG;IAClD,UAAU,EAAE,eAAe,CAAA;CAC5B,CAAA;AAED,KAAK,sBAAsB,CAAC,CAAC,IAAI;IAC/B,IAAI,EAAE,CAAC,CAAA;IACP,UAAU,CAAC,EAAE,eAAe,CAAA;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,MAAM,MAAM,qBAAqB,GAAG;
|
|
1
|
+
{"version":3,"file":"createControllerEffect.d.ts","sourceRoot":"","sources":["../../../../../src/lib/effector/createControllerEffect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,UAAU,CAAA;AAMpD,MAAM,MAAM,gBAAgB,CAAC,CAAC,EAAE,CAAC,IAAI,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG;IAClD,UAAU,EAAE,eAAe,CAAA;CAC5B,CAAA;AAED,KAAK,sBAAsB,CAAC,CAAC,IAAI;IAC/B,IAAI,EAAE,CAAC,CAAA;IACP,UAAU,CAAC,EAAE,eAAe,CAAA;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,MAAM,MAAM,qBAAqB,GAAG;IAClC,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,eAAe,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;CACvC,CAAA;AAED,wBAAgB,iBAAiB,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,IAAI,EAClD,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,MAAM,CAAC,EAAE,qBAAqB,KAAK,OAAO,CAAC,CAAC,CAAC,uCAM9D,sBAAsB,CAAC,CAAC,CAAC,gBA4B7B;AAED,eAAO,MAAM,sBAAsB,GAAI,CAAC,EAAE,CAAC,aACrC,CAAC,KAAK,EAAE,CAAC,EAAE,MAAM,CAAC,EAAE,qBAAqB,KAAK,OAAO,CAAC,CAAC,CAAC,2BAa7D,CAAA"}
|
|
@@ -14,12 +14,14 @@ export declare class VoiceTranscriptSnapshotModel {
|
|
|
14
14
|
readonly wrapRequestHint: <P extends object, R>(apiFn: (params: P & {
|
|
15
15
|
voiceTranscript?: string;
|
|
16
16
|
}, requestConfig?: RequestOptionalConfig) => Promise<R>) => (params: P, requestConfig?: RequestOptionalConfig) => Promise<R>;
|
|
17
|
+
private hasPendingVoice;
|
|
17
18
|
constructor({ voiceRecord, api }: VoiceTranscriptSnapshotModelProps);
|
|
18
19
|
private readonly voiceRecord;
|
|
19
20
|
private readonly api;
|
|
20
21
|
private readonly transcriptByAudioFileId;
|
|
21
22
|
private readonly snapshotByChatKey;
|
|
22
23
|
private readonly captureSnapshotFx;
|
|
24
|
+
private readonly clearSnapshotFx;
|
|
23
25
|
private pollTranscript;
|
|
24
26
|
private resolveAudioFileId;
|
|
25
27
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VoiceTranscriptSnapshotModel.d.ts","sourceRoot":"","sources":["../../../../../../src/features/chatbot/model/VoiceTranscriptSnapshotModel.ts"],"names":[],"mappings":"AACA,OAAO,EACL,uBAAuB,EAGxB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,gBAAgB,EAAE,MAAM,+CAA+C,CAAA;AAChF,OAAO,EAAE,qBAAqB,EAAE,MAAM,8CAA8C,CAAA;
|
|
1
|
+
{"version":3,"file":"VoiceTranscriptSnapshotModel.d.ts","sourceRoot":"","sources":["../../../../../../src/features/chatbot/model/VoiceTranscriptSnapshotModel.ts"],"names":[],"mappings":"AACA,OAAO,EACL,uBAAuB,EAGxB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,gBAAgB,EAAE,MAAM,+CAA+C,CAAA;AAChF,OAAO,EAAE,qBAAqB,EAAE,MAAM,8CAA8C,CAAA;AAMpF,KAAK,gBAAgB,GAAG;IACtB,sBAAsB,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,uBAAuB,CAAC,CAAA;CAClF,CAAA;AAOD,KAAK,iCAAiC,GAAG;IACvC,WAAW,EAAE,gBAAgB,CAAA;IAC7B,GAAG,EAAE,gBAAgB,CAAA;CACtB,CAAA;AAUD,qBAAa,4BAA4B;IACvC,SAAgB,eAAe,gBAAiB,MAAM,KAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAOnF;IAED,SAAgB,uBAAuB,QAAa,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAiB9E;IAED,SAAgB,eAAe,GAAI,CAAC,SAAS,MAAM,EAAE,CAAC,SAC7C,CACL,MAAM,EAAE,CAAC,GAAG;QAAE,eAAe,CAAC,EAAE,MAAM,CAAA;KAAE,EACxC,aAAa,CAAC,EAAE,qBAAqB,KAClC,OAAO,CAAC,CAAC,CAAC,cAEO,CAAC,kBAAkB,qBAAqB,KAAG,OAAO,CAAC,CAAC,CAAC,CAO5E;IAED,OAAO,CAAC,eAAe;gBAQX,EAAE,WAAW,EAAE,GAAG,EAAE,EAAE,iCAAiC;IAmBnE,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAkB;IAC9C,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAkB;IACtC,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAiD;IACzF,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAiD;IAEnF,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAQhC;IAEF,OAAO,CAAC,QAAQ,CAAC,eAAe,CAG9B;YAEY,cAAc;YAYd,kBAAkB;CAUjC"}
|
|
@@ -9,6 +9,7 @@ type ControlledRequestProps<P> = {
|
|
|
9
9
|
};
|
|
10
10
|
export type RequestOptionalConfig = {
|
|
11
11
|
signal?: AbortSignal;
|
|
12
|
+
extendTimeoutMs?: (ms: number) => void;
|
|
12
13
|
};
|
|
13
14
|
export declare function controlledRequest<R = void, P = void>(request: (props: P, config?: RequestOptionalConfig) => Promise<R>): ({ data, controller, abortAfter, }: ControlledRequestProps<P>) => Promise<R>;
|
|
14
15
|
export declare const createControllerEffect: <T, P = void>(fn: (props: P, config?: RequestOptionalConfig) => Promise<T>) => ControlledEffect<P, T>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createControllerEffect.d.ts","sourceRoot":"","sources":["../../../../../src/lib/effector/createControllerEffect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,UAAU,CAAA;AAMpD,MAAM,MAAM,gBAAgB,CAAC,CAAC,EAAE,CAAC,IAAI,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG;IAClD,UAAU,EAAE,eAAe,CAAA;CAC5B,CAAA;AAED,KAAK,sBAAsB,CAAC,CAAC,IAAI;IAC/B,IAAI,EAAE,CAAC,CAAA;IACP,UAAU,CAAC,EAAE,eAAe,CAAA;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,MAAM,MAAM,qBAAqB,GAAG;
|
|
1
|
+
{"version":3,"file":"createControllerEffect.d.ts","sourceRoot":"","sources":["../../../../../src/lib/effector/createControllerEffect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,UAAU,CAAA;AAMpD,MAAM,MAAM,gBAAgB,CAAC,CAAC,EAAE,CAAC,IAAI,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG;IAClD,UAAU,EAAE,eAAe,CAAA;CAC5B,CAAA;AAED,KAAK,sBAAsB,CAAC,CAAC,IAAI;IAC/B,IAAI,EAAE,CAAC,CAAA;IACP,UAAU,CAAC,EAAE,eAAe,CAAA;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,MAAM,MAAM,qBAAqB,GAAG;IAClC,MAAM,CAAC,EAAE,WAAW,CAAA;IACpB,eAAe,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;CACvC,CAAA;AAED,wBAAgB,iBAAiB,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,IAAI,EAClD,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,MAAM,CAAC,EAAE,qBAAqB,KAAK,OAAO,CAAC,CAAC,CAAC,uCAM9D,sBAAsB,CAAC,CAAC,CAAC,gBA4B7B;AAED,eAAO,MAAM,sBAAsB,GAAI,CAAC,EAAE,CAAC,aACrC,CAAC,KAAK,EAAE,CAAC,EAAE,MAAM,CAAC,EAAE,qBAAqB,KAAK,OAAO,CAAC,CAAC,CAAC,2BAa7D,CAAA"}
|
package/package.json
CHANGED
|
@@ -9,6 +9,7 @@ import { RequestOptionalConfig } from '../../../lib/effector/createControllerEff
|
|
|
9
9
|
|
|
10
10
|
const TRANSCRIPT_RETRY_INTERVAL_MS = 2000
|
|
11
11
|
const TRANSCRIPT_MAX_RETRIES = 20
|
|
12
|
+
const CHAT_WITH_VOICE_TIMEOUT_MS = 60_000
|
|
12
13
|
|
|
13
14
|
type GetTranscriptApi = {
|
|
14
15
|
getAudioFileTranscript: (audioFileId: string) => Promise<AudioTranscriptResponse>
|
|
@@ -68,11 +69,22 @@ export class VoiceTranscriptSnapshotModel {
|
|
|
68
69
|
) => Promise<R>,
|
|
69
70
|
) => {
|
|
70
71
|
return async (params: P, requestConfig?: RequestOptionalConfig): Promise<R> => {
|
|
72
|
+
if (this.hasPendingVoice()) {
|
|
73
|
+
requestConfig?.extendTimeoutMs?.(CHAT_WITH_VOICE_TIMEOUT_MS)
|
|
74
|
+
}
|
|
71
75
|
const voiceTranscript = await this.getTranscriptForCurrent()
|
|
72
76
|
return apiFn(voiceTranscript ? { ...params, voiceTranscript } : params, requestConfig)
|
|
73
77
|
}
|
|
74
78
|
}
|
|
75
79
|
|
|
80
|
+
private hasPendingVoice(): boolean {
|
|
81
|
+
const voiceKey = this.voiceRecord.$currentKey.getState()
|
|
82
|
+
if (!voiceKey) return false
|
|
83
|
+
const chatKey = toChatKey(voiceKey)
|
|
84
|
+
if (chatKey && this.snapshotByChatKey.has(chatKey)) return true
|
|
85
|
+
return !!this.voiceRecord.collection.get(voiceKey)
|
|
86
|
+
}
|
|
87
|
+
|
|
76
88
|
constructor({ voiceRecord, api }: VoiceTranscriptSnapshotModelProps) {
|
|
77
89
|
this.voiceRecord = voiceRecord
|
|
78
90
|
this.api = api
|
|
@@ -84,6 +96,12 @@ export class VoiceTranscriptSnapshotModel {
|
|
|
84
96
|
fn: (voiceKey, record) => ({ voiceKey, record }),
|
|
85
97
|
target: this.captureSnapshotFx,
|
|
86
98
|
})
|
|
99
|
+
|
|
100
|
+
sample({
|
|
101
|
+
clock: voiceRecord.deleteCurrentRecording,
|
|
102
|
+
source: voiceRecord.$currentKey,
|
|
103
|
+
target: this.clearSnapshotFx,
|
|
104
|
+
})
|
|
87
105
|
}
|
|
88
106
|
|
|
89
107
|
private readonly voiceRecord: VoiceRecordModel
|
|
@@ -91,14 +109,19 @@ export class VoiceTranscriptSnapshotModel {
|
|
|
91
109
|
private readonly transcriptByAudioFileId = new Map<string, Promise<string | undefined>>()
|
|
92
110
|
private readonly snapshotByChatKey = new Map<string, Promise<string | undefined>>()
|
|
93
111
|
|
|
94
|
-
private readonly captureSnapshotFx = createEffect(
|
|
112
|
+
private readonly captureSnapshotFx = createEffect(({ voiceKey, record }: CaptureParams) => {
|
|
95
113
|
const chatKey = toChatKey(voiceKey)
|
|
96
114
|
if (!chatKey) return
|
|
97
115
|
|
|
98
|
-
const
|
|
99
|
-
|
|
116
|
+
const transcriptPromise = this.resolveAudioFileId(record).then((audioFileId) =>
|
|
117
|
+
audioFileId ? this.fetchTranscript(audioFileId) : undefined,
|
|
118
|
+
)
|
|
119
|
+
this.snapshotByChatKey.set(chatKey, transcriptPromise)
|
|
120
|
+
})
|
|
100
121
|
|
|
101
|
-
|
|
122
|
+
private readonly clearSnapshotFx = createEffect((voiceKey: string) => {
|
|
123
|
+
const chatKey = toChatKey(voiceKey)
|
|
124
|
+
if (chatKey) this.snapshotByChatKey.delete(chatKey)
|
|
102
125
|
})
|
|
103
126
|
|
|
104
127
|
private async pollTranscript(audioFileId: string): Promise<string | undefined> {
|
|
@@ -14,7 +14,10 @@ type ControlledRequestProps<P> = {
|
|
|
14
14
|
abortAfter?: number
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
export type RequestOptionalConfig = {
|
|
17
|
+
export type RequestOptionalConfig = {
|
|
18
|
+
signal?: AbortSignal
|
|
19
|
+
extendTimeoutMs?: (ms: number) => void
|
|
20
|
+
}
|
|
18
21
|
|
|
19
22
|
export function controlledRequest<R = void, P = void>(
|
|
20
23
|
request: (props: P, config?: RequestOptionalConfig) => Promise<R>,
|
|
@@ -26,14 +29,18 @@ export function controlledRequest<R = void, P = void>(
|
|
|
26
29
|
}: ControlledRequestProps<P>) => {
|
|
27
30
|
let timeout: ReturnType<typeof setTimeout> | null = null
|
|
28
31
|
|
|
29
|
-
|
|
30
|
-
timeout
|
|
31
|
-
|
|
32
|
-
}, abortAfter)
|
|
32
|
+
const scheduleAbort = (ms: number) => {
|
|
33
|
+
if (timeout !== null) clearTimeout(timeout)
|
|
34
|
+
timeout = ms > 0 ? setTimeout(() => controller.abort('timeout'), ms) : null
|
|
33
35
|
}
|
|
34
36
|
|
|
37
|
+
if (abortAfter) scheduleAbort(abortAfter)
|
|
38
|
+
|
|
35
39
|
try {
|
|
36
|
-
const response = await request(data, {
|
|
40
|
+
const response = await request(data, {
|
|
41
|
+
signal: controller?.signal,
|
|
42
|
+
extendTimeoutMs: scheduleAbort,
|
|
43
|
+
})
|
|
37
44
|
if (timeout !== null) clearTimeout(timeout)
|
|
38
45
|
return response
|
|
39
46
|
} catch (error: unknown) {
|