@burdenoff/fe-libs 2026.1007.2 → 2026.1007.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/shared/assistant/i18nManifest.d.ts +3 -0
- package/dist/shared/assistant/i18nManifest.d.ts.map +1 -1
- package/dist/shared/assistant/i18nManifest.js +3 -0
- package/dist/shared/assistant/index.d.ts +2 -0
- package/dist/shared/assistant/index.d.ts.map +1 -1
- package/dist/shared/assistant/store.d.ts +10 -0
- package/dist/shared/assistant/store.d.ts.map +1 -1
- package/dist/shared/assistant/store.js +19 -8
- package/dist/shared/assistant/ui/AssistantChatArea.d.ts.map +1 -1
- package/dist/shared/assistant/ui/AssistantChatArea.js +1070 -1067
- package/dist/shared/assistant/ui/useVoiceSession.d.ts +14 -1
- package/dist/shared/assistant/ui/useVoiceSession.d.ts.map +1 -1
- package/dist/shared/assistant/ui/useVoiceSession.js +241 -233
- package/dist/shared/assistant/ui/voice/AssistantVoiceSession.d.ts +7 -0
- package/dist/shared/assistant/ui/voice/AssistantVoiceSession.d.ts.map +1 -1
- package/dist/shared/assistant/ui/voice/AssistantVoiceSession.js +137 -130
- package/dist/shared/assistant/ui/voice/HandsFreePrivacyNotice.d.ts +27 -0
- package/dist/shared/assistant/ui/voice/HandsFreePrivacyNotice.d.ts.map +1 -0
- package/dist/shared/assistant/ui/voice/HandsFreePrivacyNotice.js +52 -0
- package/dist/shared/assistant/voice/handsfree/backendStreamTransport.d.ts +29 -6
- package/dist/shared/assistant/voice/handsfree/backendStreamTransport.d.ts.map +1 -1
- package/dist/shared/assistant/voice/handsfree/backendStreamTransport.js +138 -63
- package/dist/shared/assistant/voice/handsfree/handsFreeController.d.ts +7 -1
- package/dist/shared/assistant/voice/handsfree/handsFreeController.d.ts.map +1 -1
- package/dist/shared/assistant/voice/handsfree/handsFreeRuntime.d.ts +18 -10
- package/dist/shared/assistant/voice/handsfree/handsFreeRuntime.d.ts.map +1 -1
- package/dist/shared/assistant/voice/handsfree/handsFreeRuntime.js +46 -57
- package/dist/shared/assistant/voice/handsfree/streamingConfig.d.ts +103 -0
- package/dist/shared/assistant/voice/handsfree/streamingConfig.d.ts.map +1 -0
- package/dist/shared/assistant/voice/handsfree/streamingConfig.js +71 -0
- package/dist/shared/assistant/voice/handsfree/sttTransport.d.ts +12 -7
- package/dist/shared/assistant/voice/handsfree/sttTransport.d.ts.map +1 -1
- package/dist/shared/assistant/voice/handsfree/sttTransport.js +1 -1
- package/dist/shared/assistant/voice/handsfree/useHandsFreeInterrupt.d.ts +23 -1
- package/dist/shared/assistant/voice/handsfree/useHandsFreeInterrupt.d.ts.map +1 -1
- package/dist/shared/assistant/voice/handsfree/useHandsFreeInterrupt.js +63 -50
- package/dist/shared-assistant.js +189 -187
- package/package.json +3 -3
|
@@ -80,6 +80,13 @@ interface Options {
|
|
|
80
80
|
* OFF; with it off nothing of the hands-free capture exists at runtime.
|
|
81
81
|
*/
|
|
82
82
|
handsFreeInterrupt?: boolean;
|
|
83
|
+
/**
|
|
84
|
+
* H3 backend stream: the privacy-notice version this profile accepted
|
|
85
|
+
* (`handsFreeStreamNoticeAccepted` in the store), or null.
|
|
86
|
+
*/
|
|
87
|
+
handsFreeStreamNoticeAccepted?: string | null;
|
|
88
|
+
/** H3 backend stream: the person pressed Continue on the notice `version`. */
|
|
89
|
+
onAcceptHandsFreeStreamNotice?: (version: string) => void;
|
|
83
90
|
/**
|
|
84
91
|
* H3: the user's voice started while the assistant was answering. The audio
|
|
85
92
|
* is already stopped and the session is back to `listening`; the owner of the
|
|
@@ -114,7 +121,7 @@ export interface VoiceSubmitMeta {
|
|
|
114
121
|
* microphone's lifetime, and turning "auto-speak is currently on" back off again
|
|
115
122
|
* when the session ends.
|
|
116
123
|
*/
|
|
117
|
-
export declare function useVoiceSession({ onSubmit, latestReply, language, graceMs: graceChoice, onSupersede, handsFreeInterrupt, onBargeIn, }: Options): {
|
|
124
|
+
export declare function useVoiceSession({ onSubmit, latestReply, language, graceMs: graceChoice, onSupersede, handsFreeInterrupt, handsFreeStreamNoticeAccepted, onAcceptHandsFreeStreamNotice, onBargeIn, }: Options): {
|
|
118
125
|
session: Readonly<VoiceSessionSnapshot>;
|
|
119
126
|
/** A recoverable problem worth showing, or null when all is well. */
|
|
120
127
|
notice: VoiceSessionNotice | null;
|
|
@@ -156,6 +163,12 @@ export declare function useVoiceSession({ onSubmit, latestReply, language, grace
|
|
|
156
163
|
nothingHeard: boolean;
|
|
157
164
|
transportKind: import('..').SttTransportKind | null;
|
|
158
165
|
fallbackReason: import('..').FallbackReason | null;
|
|
166
|
+
/**
|
|
167
|
+
* Non-null while the backend stream's privacy notice must be answered
|
|
168
|
+
* before the microphone opens: Continue (`accept`) or Not now
|
|
169
|
+
* (`decline`).
|
|
170
|
+
*/
|
|
171
|
+
privacyNotice: import('..').HandsFreePrivacyNoticeActions | null;
|
|
159
172
|
};
|
|
160
173
|
/** Can a session be offered at all on this device? */
|
|
161
174
|
available: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useVoiceSession.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/ui/useVoiceSession.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAe,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAIpE,OAAO,EAGL,KAAK,YAAY,EAClB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAgBL,KAAK,oBAAoB,EAE1B,MAAM,uBAAuB,CAAC;AAsC/B;;;;;;;;GAQG;AACH,MAAM,MAAM,kBAAkB,GAC1B,SAAS,GACT,eAAe,GACf,eAAe,GACf,oBAAoB;AACtB,oFAAoF;GAClF,0BAA0B;AAC5B,qFAAqF;GACnF,qBAAqB,CAAC;AAE1B;;;;;;;;GAQG;AACH,MAAM,WAAW,iBAAiB;IAChC,iFAAiF;IACjF,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,+DAA+D;IAC/D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC;CAC7B;AAMD,UAAU,OAAO;IACf,+EAA+E;IAC/E;;;;;;;OAOG;IACH,QAAQ,EAAE,CACR,IAAI,EAAE,MAAM,EACZ,cAAc,EAAE,MAAM;IACtB;;;OAGG;IACH,MAAM,EAAE,eAAe;IACvB;;;;;OAKG;IACH,IAAI,EAAE,eAAe,KAClB,IAAI,CAAC;IACV;;;;OAIG;IACH,WAAW,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACjD,6EAA6E;IAC7E,QAAQ,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,OAAO,CAAC,EAAE,YAAY,GAAG,MAAM,CAAC;IAChC;;;OAGG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;CAC1B;AAED,oEAAoE;AACpE,MAAM,WAAW,eAAe;IAC9B,gEAAgE;IAChE,UAAU,EAAE,OAAO,CAAC;CACrB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,EAC9B,QAAQ,EACR,WAAW,EACX,QAAQ,EACR,OAAO,EAAE,WAAW,EACpB,WAAW,EACX,kBAAkB,EAClB,SAAS,GACV,EAAE,OAAO;;
|
|
1
|
+
{"version":3,"file":"useVoiceSession.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/ui/useVoiceSession.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAe,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAIpE,OAAO,EAGL,KAAK,YAAY,EAClB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAgBL,KAAK,oBAAoB,EAE1B,MAAM,uBAAuB,CAAC;AAsC/B;;;;;;;;GAQG;AACH,MAAM,MAAM,kBAAkB,GAC1B,SAAS,GACT,eAAe,GACf,eAAe,GACf,oBAAoB;AACtB,oFAAoF;GAClF,0BAA0B;AAC5B,qFAAqF;GACnF,qBAAqB,CAAC;AAE1B;;;;;;;;GAQG;AACH,MAAM,WAAW,iBAAiB;IAChC,iFAAiF;IACjF,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,+DAA+D;IAC/D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC;CAC7B;AAMD,UAAU,OAAO;IACf,+EAA+E;IAC/E;;;;;;;OAOG;IACH,QAAQ,EAAE,CACR,IAAI,EAAE,MAAM,EACZ,cAAc,EAAE,MAAM;IACtB;;;OAGG;IACH,MAAM,EAAE,eAAe;IACvB;;;;;OAKG;IACH,IAAI,EAAE,eAAe,KAClB,IAAI,CAAC;IACV;;;;OAIG;IACH,WAAW,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACjD,6EAA6E;IAC7E,QAAQ,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,OAAO,CAAC,EAAE,YAAY,GAAG,MAAM,CAAC;IAChC;;;OAGG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B;;;OAGG;IACH,6BAA6B,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9C,8EAA8E;IAC9E,6BAA6B,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1D;;;;;OAKG;IACH,SAAS,CAAC,EAAE,MAAM,IAAI,CAAC;IACvB;;;;;OAKG;IACH,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;CAC1B;AAED,oEAAoE;AACpE,MAAM,WAAW,eAAe;IAC9B,gEAAgE;IAChE,UAAU,EAAE,OAAO,CAAC;CACrB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,EAC9B,QAAQ,EACR,WAAW,EACX,QAAQ,EACR,OAAO,EAAE,WAAW,EACpB,WAAW,EACX,kBAAkB,EAClB,6BAA6B,EAC7B,6BAA6B,EAC7B,SAAS,GACV,EAAE,OAAO;;IAk9BJ,qEAAqE;;IAWrE;;;;;;;OAOG;;IAEH,+DAA+D;;IAE/D;;;;;;;OAOG;;IAIH,0EAA0E;;IAE1E,6DAA6D;;IAE7D,kEAAkE;;IAElE,uEAAuE;;IAEvE;;;;OAIG;;;;;;QAMD;;;;WAIG;;;IAGL,sDAAsD;;;;uCApIvC,MAAM;;;IA2IrB,qDAAqD;;IAErD,uDAAuD;;IAEvD,0EAA0E;qBAp5B1C,iBAAiB;IAs5BjD;;;OAGG;+BAp6BuC,OAAO;IAs6BjD;;;OAGG;0BAn4BE,iBAAiB;EAu6B3B"}
|
|
@@ -3,239 +3,245 @@ import { planSubmitTimer as t, resolveVoiceGraceMs as n } from "../voice/handsFr
|
|
|
3
3
|
import { readHandsFreeOverride as r, resolveHandsFreeEnabled as ee } from "../voice/handsfree/handsFreeSetting.js";
|
|
4
4
|
import { silencePlaybackReference as te } from "../voice/handsfree/playbackReference.js";
|
|
5
5
|
import { speechFeed as ne } from "../speech/speechFeed.js";
|
|
6
|
-
import { INITIAL_SESSION as re, INTERRUPT_MAX_MS as ie, NOTHING_HEARD as ae, advanceHeardClock as oe, isCapturing as
|
|
7
|
-
import { useHandsFreeInterrupt as
|
|
8
|
-
import { isTurnSuperseded as
|
|
9
|
-
import { captionChunks as
|
|
10
|
-
import { turnClockMs as
|
|
11
|
-
import { useAssistantSpeech as
|
|
12
|
-
import { useCallback as
|
|
6
|
+
import { INITIAL_SESSION as re, INTERRUPT_MAX_MS as ie, NOTHING_HEARD as ae, advanceHeardClock as oe, isCapturing as i, isSubmittable as se, planListeningHold as ce, planReplyConsumption as le, planVoiceAnnouncement as ue, shouldRecognise as de, spokenSoFar as a, voiceSessionReducer as fe } from "../voice/voiceSession.js";
|
|
7
|
+
import { useHandsFreeInterrupt as pe } from "../voice/handsfree/useHandsFreeInterrupt.js";
|
|
8
|
+
import { isTurnSuperseded as o } from "../voice/supersededTurns.js";
|
|
9
|
+
import { captionChunks as me } from "../voice/speechPlayback.js";
|
|
10
|
+
import { turnClockMs as s } from "../turnTimeline.js";
|
|
11
|
+
import { useAssistantSpeech as he } from "./AssistantSpeechProvider.js";
|
|
12
|
+
import { useCallback as c, useEffect as l, useLayoutEffect as ge, useMemo as _e, useReducer as ve, useRef as u, useState as d } from "react";
|
|
13
13
|
//#region src/shared/assistant/ui/useVoiceSession.ts
|
|
14
|
-
var
|
|
15
|
-
function
|
|
16
|
-
let
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}, [
|
|
20
|
-
let
|
|
21
|
-
|
|
22
|
-
let
|
|
23
|
-
|
|
24
|
-
}, []),
|
|
14
|
+
var ye = 4e3, be = 2500, xe = 5e3, Se = 12e3, Ce = "data:audio/wav;base64,UklGRiQAAABXQVZFZm10IBAAAAABAAEARKwAAIhYAQACABAAZGF0YQAAAAA=";
|
|
15
|
+
function we({ onSubmit: we, latestReply: f, language: p, graceMs: Te, onSupersede: Ee, handsFreeInterrupt: De, handsFreeStreamNoticeAccepted: Oe, onAcceptHandsFreeStreamNotice: ke, onBargeIn: m }) {
|
|
16
|
+
let h = n(Te), g = u(null), [_, v] = ve(c((e, t) => fe(e, t, g.current), []), re), y = he(), { setSessionSpeaking: b, setSessionMicOpen: x, speakingMessageId: S, stop: C } = y, w = u(y.toggle), T = y.toggle;
|
|
17
|
+
ge(() => {
|
|
18
|
+
w.current = T;
|
|
19
|
+
}, [T]);
|
|
20
|
+
let E = u(null), D = u({}), O = u(ae), k = u(null), A = u(!1), j = u(null), [M, N] = d(null), [P, F] = d(!1), [Ae, I] = d(!1), [L, R] = d(!1), z = u(_);
|
|
21
|
+
z.current = _;
|
|
22
|
+
let B = u([]), V = u(null), H = u(!1), U = c(() => {
|
|
23
|
+
B.current = [], V.current = null, H.current = !1;
|
|
24
|
+
}, []), W = c(() => {
|
|
25
25
|
for (;;) {
|
|
26
|
-
let e =
|
|
26
|
+
let e = B.current.shift();
|
|
27
27
|
if (!e) return !1;
|
|
28
28
|
if (!(e.stillWanted && !e.stillWanted())) {
|
|
29
|
-
|
|
29
|
+
V.current = e, g.current = g.current ? `${g.current} ${e.text}` : e.text;
|
|
30
30
|
try {
|
|
31
|
-
|
|
31
|
+
w.current(e.id, e.text, e.lang);
|
|
32
32
|
} catch {
|
|
33
|
-
|
|
33
|
+
V.current = null;
|
|
34
34
|
continue;
|
|
35
35
|
}
|
|
36
36
|
return !0;
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
|
-
}, []),
|
|
40
|
-
let t =
|
|
39
|
+
}, []), G = u(!1), je = c((e) => {
|
|
40
|
+
let t = ce({
|
|
41
41
|
requested: e,
|
|
42
|
-
held:
|
|
43
|
-
muted:
|
|
42
|
+
held: G.current,
|
|
43
|
+
muted: z.current.muted
|
|
44
44
|
});
|
|
45
|
-
|
|
45
|
+
G.current = t.held, t.mute !== null && v({
|
|
46
46
|
type: "mute",
|
|
47
47
|
muted: t.mute
|
|
48
48
|
});
|
|
49
|
-
}, []),
|
|
50
|
-
let t =
|
|
51
|
-
t !== "drop" && (
|
|
52
|
-
}, []),
|
|
53
|
-
if (
|
|
54
|
-
|
|
49
|
+
}, []), K = c((e) => {
|
|
50
|
+
let t = ue(z.current);
|
|
51
|
+
t !== "drop" && (V.current?.id === e.id || B.current.some((t) => t.id === e.id) || (B.current.push(e), t === "start" && !H.current && (H.current = !0, v({ type: "announce" }))));
|
|
52
|
+
}, []), Me = c((e) => {
|
|
53
|
+
if (z.current.phase !== "thinking") {
|
|
54
|
+
K(e);
|
|
55
55
|
return;
|
|
56
56
|
}
|
|
57
|
-
|
|
58
|
-
}, [
|
|
59
|
-
|
|
60
|
-
if (
|
|
61
|
-
let e =
|
|
62
|
-
|
|
57
|
+
B.current.push(e), H.current = !0, v({ type: "answered-locally" });
|
|
58
|
+
}, [K]), Ne = u(f);
|
|
59
|
+
Ne.current = f, l(() => {
|
|
60
|
+
if (_.phase === "speaking") {
|
|
61
|
+
let e = j.current;
|
|
62
|
+
g.current = e && k.current === e.id && f?.id !== e.id ? e.text : f?.text ?? null;
|
|
63
63
|
return;
|
|
64
64
|
}
|
|
65
|
-
if (
|
|
65
|
+
if (g.current === null) return;
|
|
66
66
|
let e = setTimeout(() => {
|
|
67
|
-
|
|
68
|
-
},
|
|
67
|
+
g.current = null;
|
|
68
|
+
}, be);
|
|
69
69
|
return () => clearTimeout(e);
|
|
70
|
-
}, [
|
|
71
|
-
let
|
|
72
|
-
|
|
73
|
-
let
|
|
74
|
-
|
|
70
|
+
}, [_.phase, f]);
|
|
71
|
+
let q = u(p);
|
|
72
|
+
q.current = p;
|
|
73
|
+
let J = c((e, t) => {
|
|
74
|
+
v({
|
|
75
75
|
type: "speech",
|
|
76
76
|
transcript: e,
|
|
77
77
|
final: t,
|
|
78
78
|
at: Date.now(),
|
|
79
|
-
language:
|
|
79
|
+
language: q.current
|
|
80
80
|
});
|
|
81
|
-
}, []),
|
|
82
|
-
|
|
81
|
+
}, []), Pe = c((e, t, n) => {
|
|
82
|
+
v({
|
|
83
83
|
type: "speech",
|
|
84
84
|
transcript: e,
|
|
85
85
|
final: t,
|
|
86
86
|
at: Date.now(),
|
|
87
|
-
language: n ??
|
|
87
|
+
language: n ?? q.current,
|
|
88
88
|
gated: !0
|
|
89
89
|
});
|
|
90
|
-
}, []),
|
|
91
|
-
|
|
92
|
-
}, [
|
|
93
|
-
onFinalize:
|
|
90
|
+
}, []), Y = u(0), Fe = c(() => {
|
|
91
|
+
U(), C(), Y.current = Date.now(), F(!0), v({ type: "interrupt" });
|
|
92
|
+
}, [C, U]), X = e({
|
|
93
|
+
onFinalize: c((e) => J(e, !0), [J]),
|
|
94
94
|
language: p
|
|
95
|
-
}),
|
|
96
|
-
|
|
97
|
-
let
|
|
98
|
-
|
|
99
|
-
}, [
|
|
95
|
+
}), Ie = u(m);
|
|
96
|
+
Ie.current = m;
|
|
97
|
+
let Le = c(() => {
|
|
98
|
+
U(), te(), C(), Y.current = Date.now(), F(!0), v({ type: "interrupt" }), Ie.current?.();
|
|
99
|
+
}, [C, U]), Z = pe({
|
|
100
100
|
enabled: ee(De, r()),
|
|
101
|
-
phase:
|
|
102
|
-
muted:
|
|
101
|
+
phase: _.phase,
|
|
102
|
+
muted: _.muted,
|
|
103
103
|
language: p,
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
104
|
+
streamNoticeAccepted: Oe ?? null,
|
|
105
|
+
onAcceptStreamNotice: ke,
|
|
106
|
+
onBargeIn: Le,
|
|
107
|
+
onTranscript: Pe
|
|
108
|
+
}), Re = Z.mode === "notice", Q = X.isListening || Z.suppressWebSpeech && Z.mode === "active";
|
|
109
|
+
l(() => {
|
|
110
|
+
X.interim && J(X.interim, !1);
|
|
111
|
+
}, [X.interim, J]), l(() => {
|
|
112
|
+
E.current && clearTimeout(E.current), I(!1), O.current = oe(O.current, _, s());
|
|
111
113
|
let e = t({
|
|
112
|
-
phase:
|
|
113
|
-
muted:
|
|
114
|
-
spoken:
|
|
115
|
-
holding:
|
|
116
|
-
graceMs:
|
|
114
|
+
phase: _.phase,
|
|
115
|
+
muted: _.muted,
|
|
116
|
+
spoken: a(_),
|
|
117
|
+
holding: L,
|
|
118
|
+
graceMs: h
|
|
117
119
|
});
|
|
118
120
|
if (!e.arm) return;
|
|
119
|
-
let n = setTimeout(() =>
|
|
120
|
-
return
|
|
121
|
-
|
|
122
|
-
speechEnded:
|
|
121
|
+
let n = setTimeout(() => I(!0), Math.min(800, e.delayMs)), r = s();
|
|
122
|
+
return E.current = setTimeout(() => {
|
|
123
|
+
D.current = {
|
|
124
|
+
speechEnded: O.current.at ?? r,
|
|
123
125
|
graceStarted: r,
|
|
124
|
-
graceEnded:
|
|
125
|
-
},
|
|
126
|
+
graceEnded: s()
|
|
127
|
+
}, v({
|
|
126
128
|
type: "silence",
|
|
127
129
|
at: Date.now()
|
|
128
130
|
});
|
|
129
131
|
}, e.delayMs), () => {
|
|
130
|
-
clearTimeout(n),
|
|
132
|
+
clearTimeout(n), E.current && clearTimeout(E.current);
|
|
131
133
|
};
|
|
132
134
|
}, [
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
]),
|
|
137
|
-
(
|
|
138
|
-
}, [
|
|
139
|
-
if (!
|
|
140
|
-
let e = Date.now() -
|
|
135
|
+
_,
|
|
136
|
+
L,
|
|
137
|
+
h
|
|
138
|
+
]), l(() => {
|
|
139
|
+
(_.phase !== "listening" || _.muted) && R(!1);
|
|
140
|
+
}, [_.phase, _.muted]), l(() => {
|
|
141
|
+
if (!P) return;
|
|
142
|
+
let e = Date.now() - Y.current, t = Q ? Math.max(0, 500 - e) : Math.max(0, ie - e), n = setTimeout(() => F(!1), t);
|
|
141
143
|
return () => clearTimeout(n);
|
|
142
|
-
}, [
|
|
143
|
-
let
|
|
144
|
-
|
|
145
|
-
if (
|
|
146
|
-
|
|
147
|
-
let e =
|
|
148
|
-
e &&
|
|
149
|
-
}, [
|
|
150
|
-
let e =
|
|
151
|
-
e.claim && (
|
|
144
|
+
}, [P, Q]);
|
|
145
|
+
let ze = u("");
|
|
146
|
+
_.phase === "listening" && (ze.current = a(_)), l(() => {
|
|
147
|
+
if (_.phase !== "thinking") return;
|
|
148
|
+
x(!1), U();
|
|
149
|
+
let e = ze.current.trim();
|
|
150
|
+
e && we(e, $.current ?? `vs-orphan-${Date.now().toString(36)}`, D.current, { correction: z.current.correcting }), D.current = {}, O.current = ae;
|
|
151
|
+
}, [_.phase]), l(() => {
|
|
152
|
+
let e = le(f?.id, _.phase, k.current, o(f?.id));
|
|
153
|
+
e.claim && (k.current = f?.id ?? null, e.advance && f && v({
|
|
152
154
|
type: "reply",
|
|
153
155
|
text: f.text
|
|
154
156
|
}));
|
|
155
|
-
}, [f,
|
|
156
|
-
if (
|
|
157
|
-
if (
|
|
158
|
-
|
|
157
|
+
}, [f, _.phase]), l(() => {
|
|
158
|
+
if (S === null || _.phase !== "thinking" || k.current === S) return;
|
|
159
|
+
if (o(S)) {
|
|
160
|
+
C();
|
|
159
161
|
return;
|
|
160
162
|
}
|
|
161
|
-
let e = ne.peek(
|
|
162
|
-
!e || e.channel !== "voice" || e.voiceSessionId === void 0 || e.voiceSessionId !==
|
|
163
|
-
id:
|
|
163
|
+
let e = ne.peek(S);
|
|
164
|
+
!e || e.channel !== "voice" || e.voiceSessionId === void 0 || e.voiceSessionId !== $.current || (k.current = S, j.current = {
|
|
165
|
+
id: S,
|
|
164
166
|
text: e.text
|
|
165
|
-
},
|
|
167
|
+
}, v({
|
|
166
168
|
type: "reply-audio-started",
|
|
167
|
-
replyId:
|
|
169
|
+
replyId: S
|
|
168
170
|
}));
|
|
169
171
|
}, [
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
]),
|
|
174
|
-
let e =
|
|
175
|
-
|
|
176
|
-
}, [
|
|
177
|
-
|
|
178
|
-
}, [
|
|
179
|
-
if (
|
|
172
|
+
S,
|
|
173
|
+
_.phase,
|
|
174
|
+
C
|
|
175
|
+
]), l(() => {
|
|
176
|
+
let e = S !== null;
|
|
177
|
+
A.current && !e && (V.current = null, (z.current.phase !== "speaking" || !W()) && v({ type: "speech-ended" })), A.current = e;
|
|
178
|
+
}, [S, W]), l(() => {
|
|
179
|
+
_.phase !== "listening" && N((e) => e === "nothing-heard" ? null : e);
|
|
180
|
+
}, [_.phase]), l(() => {
|
|
181
|
+
if (_.phase !== "speaking" || S !== null) return;
|
|
180
182
|
let e = setTimeout(() => {
|
|
181
|
-
|
|
182
|
-
},
|
|
183
|
+
A.current || (U(), v({ type: "speech-ended" }));
|
|
184
|
+
}, ye);
|
|
183
185
|
return () => clearTimeout(e);
|
|
184
186
|
}, [
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
187
|
+
_.phase,
|
|
188
|
+
S,
|
|
189
|
+
U
|
|
188
190
|
]);
|
|
189
|
-
let
|
|
190
|
-
|
|
191
|
-
let
|
|
192
|
-
|
|
193
|
-
let e =
|
|
194
|
-
e !==
|
|
191
|
+
let Be = u(Ee);
|
|
192
|
+
Be.current = Ee;
|
|
193
|
+
let Ve = u(0);
|
|
194
|
+
l(() => {
|
|
195
|
+
let e = _.superseded;
|
|
196
|
+
e !== Ve.current && (Ve.current = e, e !== 0 && (U(), C(), Be.current?.()));
|
|
195
197
|
}, [
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
]),
|
|
200
|
-
|
|
198
|
+
_.superseded,
|
|
199
|
+
U,
|
|
200
|
+
C
|
|
201
|
+
]), l(() => {
|
|
202
|
+
x(i(_)), de(_) && !Z.suppressWebSpeech ? X.isActive || X.start("auto") : X.isActive && X.stop();
|
|
201
203
|
}, [
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
]),
|
|
207
|
-
|
|
208
|
-
}, [
|
|
209
|
-
|
|
204
|
+
_,
|
|
205
|
+
X,
|
|
206
|
+
x,
|
|
207
|
+
Z.suppressWebSpeech
|
|
208
|
+
]), l(() => {
|
|
209
|
+
_.phase !== "speaking" || !H.current || (H.current = !1, W() || v({ type: "speech-ended" }));
|
|
210
|
+
}, [_.phase, W]), l(() => {
|
|
211
|
+
X.error === "not-allowed" || X.error === "audio-capture" ? v({
|
|
210
212
|
type: "fail",
|
|
211
213
|
error: "mic-denied"
|
|
212
|
-
}) :
|
|
214
|
+
}) : X.error === "language-not-supported" ? v({
|
|
213
215
|
type: "fail",
|
|
214
216
|
error: "no-speech-support"
|
|
215
|
-
}) :
|
|
216
|
-
}, [
|
|
217
|
-
|
|
218
|
-
}, [
|
|
219
|
-
if (
|
|
220
|
-
let e = setTimeout(() =>
|
|
217
|
+
}) : X.error === "network" ? N("network") : X.error === "unknown" && N("recognition-failed");
|
|
218
|
+
}, [X.error]), l(() => {
|
|
219
|
+
X.error !== null || !Q || N((e) => e === "network" || e === "recognition-failed" ? null : e);
|
|
220
|
+
}, [X.error, Q]), l(() => {
|
|
221
|
+
if (Q && N((e) => e === "not-capturing" ? null : e), !i(_) || Q || Re) return;
|
|
222
|
+
let e = setTimeout(() => N("not-capturing"), xe);
|
|
221
223
|
return () => clearTimeout(e);
|
|
222
|
-
}, [
|
|
223
|
-
|
|
224
|
-
|
|
224
|
+
}, [
|
|
225
|
+
_,
|
|
226
|
+
Q,
|
|
227
|
+
Re
|
|
228
|
+
]), l(() => {
|
|
229
|
+
if (_.phase !== "listening" || _.muted || !Q || a(_) !== "") return;
|
|
230
|
+
let e = setTimeout(() => N("nothing-heard"), Se);
|
|
225
231
|
return () => clearTimeout(e);
|
|
226
|
-
}, [
|
|
227
|
-
|
|
228
|
-
}, [
|
|
229
|
-
let
|
|
230
|
-
if (
|
|
231
|
-
|
|
232
|
+
}, [_, Q]), l(() => {
|
|
233
|
+
a(_) !== "" && N(null);
|
|
234
|
+
}, [_]);
|
|
235
|
+
let $ = u(null), He = c(() => {
|
|
236
|
+
if (F(!1), I(!1), R(!1), U(), G.current = !1, !X.isSupported) {
|
|
237
|
+
v({
|
|
232
238
|
type: "fail",
|
|
233
239
|
error: "no-speech-support"
|
|
234
240
|
});
|
|
235
241
|
return;
|
|
236
242
|
}
|
|
237
|
-
if (
|
|
238
|
-
|
|
243
|
+
if (y.isBlocked) {
|
|
244
|
+
v({
|
|
239
245
|
type: "fail",
|
|
240
246
|
error: "no-voice-support"
|
|
241
247
|
});
|
|
@@ -250,100 +256,102 @@ function d({ onSubmit: d, latestReply: f, language: p, graceMs: Te, onSupersede:
|
|
|
250
256
|
} catch {}
|
|
251
257
|
try {
|
|
252
258
|
if (typeof window < "u" && typeof window.Audio == "function") {
|
|
253
|
-
let e = new window.Audio(
|
|
259
|
+
let e = new window.Audio(Ce);
|
|
254
260
|
e.volume = 0, e.play().catch(() => {});
|
|
255
261
|
}
|
|
256
262
|
} catch {}
|
|
257
|
-
|
|
263
|
+
b(!0), N(null), k.current = Ne.current?.id ?? null, j.current = null, $.current = `vs-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`, v({ type: "start" });
|
|
258
264
|
}, [
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
]),
|
|
264
|
-
|
|
265
|
+
X.isSupported,
|
|
266
|
+
y.isBlocked,
|
|
267
|
+
b,
|
|
268
|
+
U
|
|
269
|
+
]), Ue = c(() => {
|
|
270
|
+
F(!1), I(!1), R(!1), U(), G.current = !1, $.current = null, v({ type: "end" }), C(), b(!1);
|
|
265
271
|
}, [
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
]),
|
|
270
|
-
let e =
|
|
271
|
-
e.phase !== "listening" || e.muted ||
|
|
272
|
-
}, []),
|
|
273
|
-
|
|
274
|
-
let e =
|
|
275
|
-
if (e.phase !== "listening" || e.muted || !
|
|
276
|
-
let t =
|
|
277
|
-
|
|
278
|
-
speechEnded:
|
|
272
|
+
C,
|
|
273
|
+
b,
|
|
274
|
+
U
|
|
275
|
+
]), We = c((e) => $.current === e, []), Ge = c(() => {
|
|
276
|
+
let e = z.current;
|
|
277
|
+
e.phase !== "listening" || e.muted || R(!0);
|
|
278
|
+
}, []), Ke = c(() => {
|
|
279
|
+
R(!1);
|
|
280
|
+
let e = z.current;
|
|
281
|
+
if (e.phase !== "listening" || e.muted || !se(a(e))) return;
|
|
282
|
+
let t = s();
|
|
283
|
+
D.current = {
|
|
284
|
+
speechEnded: O.current.at ?? t,
|
|
279
285
|
graceStarted: t,
|
|
280
286
|
graceEnded: t
|
|
281
|
-
},
|
|
287
|
+
}, v({
|
|
282
288
|
type: "silence",
|
|
283
289
|
at: Date.now()
|
|
284
290
|
});
|
|
285
|
-
}, []),
|
|
286
|
-
|
|
291
|
+
}, []), qe = c(() => {
|
|
292
|
+
v({
|
|
287
293
|
type: "mute",
|
|
288
|
-
muted: !
|
|
294
|
+
muted: !z.current.muted
|
|
289
295
|
});
|
|
290
296
|
}, []);
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
}, [
|
|
294
|
-
let
|
|
295
|
-
return
|
|
296
|
-
session:
|
|
297
|
-
notice:
|
|
298
|
-
spokenChunks:
|
|
299
|
-
capturing:
|
|
300
|
-
active:
|
|
301
|
-
interrupting:
|
|
302
|
-
awaitingEndpoint:
|
|
303
|
-
holding:
|
|
304
|
-
correcting:
|
|
297
|
+
l(() => () => {
|
|
298
|
+
b(!1), x(!1);
|
|
299
|
+
}, [b, x]);
|
|
300
|
+
let Je = me(y.spokenChunks, _.phase, S);
|
|
301
|
+
return _e(() => ({
|
|
302
|
+
session: _,
|
|
303
|
+
notice: M ?? (Z.fallbackReason !== null && Z.fallbackReason !== "notice-declined" ? "hands-free-fallback" : Z.nothingHeard ? "hands-free-nothing-heard" : null),
|
|
304
|
+
spokenChunks: Je,
|
|
305
|
+
capturing: Q,
|
|
306
|
+
active: _.phase !== "idle" && (_.phase !== "ended" || _.error !== null),
|
|
307
|
+
interrupting: P,
|
|
308
|
+
awaitingEndpoint: Ae,
|
|
309
|
+
holding: L,
|
|
310
|
+
correcting: _.correcting,
|
|
305
311
|
handsFree: {
|
|
306
|
-
mode:
|
|
307
|
-
nothingHeard:
|
|
308
|
-
transportKind:
|
|
309
|
-
fallbackReason:
|
|
312
|
+
mode: Z.mode,
|
|
313
|
+
nothingHeard: Z.nothingHeard,
|
|
314
|
+
transportKind: Z.transportKind,
|
|
315
|
+
fallbackReason: Z.fallbackReason,
|
|
316
|
+
privacyNotice: Z.privacyNotice
|
|
310
317
|
},
|
|
311
|
-
available:
|
|
312
|
-
start:
|
|
313
|
-
end:
|
|
314
|
-
isCurrentSession:
|
|
315
|
-
toggleMute:
|
|
316
|
-
interrupt:
|
|
317
|
-
letMeFinish:
|
|
318
|
-
imDone:
|
|
319
|
-
announce:
|
|
320
|
-
holdListening:
|
|
321
|
-
answerLocally:
|
|
318
|
+
available: X.isSupported && !y.isBlocked,
|
|
319
|
+
start: He,
|
|
320
|
+
end: Ue,
|
|
321
|
+
isCurrentSession: We,
|
|
322
|
+
toggleMute: qe,
|
|
323
|
+
interrupt: Fe,
|
|
324
|
+
letMeFinish: Ge,
|
|
325
|
+
imDone: Ke,
|
|
326
|
+
announce: K,
|
|
327
|
+
holdListening: je,
|
|
328
|
+
answerLocally: Me
|
|
322
329
|
}), [
|
|
323
|
-
|
|
324
|
-
A,
|
|
330
|
+
_,
|
|
325
331
|
M,
|
|
326
332
|
P,
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
333
|
+
Ae,
|
|
334
|
+
L,
|
|
335
|
+
Q,
|
|
336
|
+
Z.mode,
|
|
337
|
+
Z.nothingHeard,
|
|
338
|
+
Z.transportKind,
|
|
339
|
+
Z.fallbackReason,
|
|
340
|
+
Z.privacyNotice,
|
|
341
|
+
X.isSupported,
|
|
342
|
+
y.isBlocked,
|
|
343
|
+
Je,
|
|
338
344
|
He,
|
|
339
|
-
Ge,
|
|
340
|
-
Pe,
|
|
341
345
|
Ue,
|
|
342
346
|
We,
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
347
|
+
qe,
|
|
348
|
+
Fe,
|
|
349
|
+
Ge,
|
|
350
|
+
Ke,
|
|
351
|
+
K,
|
|
352
|
+
je,
|
|
353
|
+
Me
|
|
346
354
|
]);
|
|
347
355
|
}
|
|
348
356
|
//#endregion
|
|
349
|
-
export {
|
|
357
|
+
export { we as useVoiceSession };
|