@burdenoff/fe-libs 2026.1013.10 → 2026.1013.12
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 +1 -0
- package/dist/shared/assistant/i18nManifest.js +1 -0
- package/dist/shared/assistant/speech/hostedTtsSpeechEngine.js +86 -81
- package/dist/shared/assistant/speech/pieceSink.d.ts +15 -7
- package/dist/shared/assistant/speech/pieceSink.js +55 -49
- package/dist/shared/assistant/speech/routingSpeechEngine.js +47 -37
- package/dist/shared/assistant/speech/types.d.ts +34 -3
- package/dist/shared/assistant/speech/types.js +2 -2
- package/dist/shared/assistant/ui/AssistantSpeechProvider.d.ts +11 -0
- package/dist/shared/assistant/ui/AssistantSpeechProvider.js +255 -250
- package/dist/shared/assistant/ui/useVoiceSession.d.ts +7 -1
- package/dist/shared/assistant/ui/useVoiceSession.js +253 -245
- package/dist/shared/assistant/ui/voice/AssistantVoiceSession.js +157 -145
- package/dist/shared/native/types.d.ts +1 -1
- package/dist/shared-assistant.js +240 -240
- package/package.json +1 -1
|
@@ -515,6 +515,7 @@ export declare const ASSISTANT_I18N_LITERAL_COPY: {
|
|
|
515
515
|
readonly "voiceSession.noticeNotCapturing": "The microphone did not start. Check that this site is allowed to use it, then try again.";
|
|
516
516
|
readonly "voiceSession.noticeNothingHeard": "Nothing heard yet. Check your microphone is not muted or in use by another app.";
|
|
517
517
|
readonly "voiceSession.noticeRecognitionFailed": "Speech recognition stopped unexpectedly. It will retry — if it keeps happening, reload the page.";
|
|
518
|
+
readonly "voiceSession.noticeReplyNotHeard": "That reply was not read aloud: earlier audio may still be playing. Read it in the transcript.";
|
|
518
519
|
readonly "voiceSession.save": "Save transcript";
|
|
519
520
|
readonly "voiceSession.savedAt": "Saved";
|
|
520
521
|
readonly "voiceSession.sessionLabel": "Session";
|
|
@@ -409,6 +409,7 @@ var m = {
|
|
|
409
409
|
"voiceSession.noticeNotCapturing": "The microphone did not start. Check that this site is allowed to use it, then try again.",
|
|
410
410
|
"voiceSession.noticeNothingHeard": "Nothing heard yet. Check your microphone is not muted or in use by another app.",
|
|
411
411
|
"voiceSession.noticeRecognitionFailed": "Speech recognition stopped unexpectedly. It will retry — if it keeps happening, reload the page.",
|
|
412
|
+
"voiceSession.noticeReplyNotHeard": "That reply was not read aloud: earlier audio may still be playing. Read it in the transcript.",
|
|
412
413
|
"voiceSession.save": "Save transcript",
|
|
413
414
|
"voiceSession.savedAt": "Saved",
|
|
414
415
|
"voiceSession.sessionLabel": "Session",
|
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
import { tapPlaybackElement as e } from "../voice/handsfree/playbackReference.js";
|
|
2
2
|
import { HOSTED_TTS_TIER as t, HOSTED_VOICES as n, hostedLocaleFor as r } from "./hostedVoiceCatalogue.js";
|
|
3
3
|
import { buildRequest as i, classifyHttpFailure as a, decodeAudioResponse as o, disableDurationMs as s, shouldDisableEngine as c, speakableChunks as l } from "./hostedTtsProtocol.js";
|
|
4
|
-
import { createPieceSink as u } from "./pieceSink.js";
|
|
4
|
+
import { createPieceSink as u, isOutputRefusal as d } from "./pieceSink.js";
|
|
5
5
|
//#region src/shared/assistant/speech/hostedTtsSpeechEngine.ts
|
|
6
|
-
function
|
|
6
|
+
function f(e) {
|
|
7
7
|
let t = Object.entries(e).map(([e, t]) => `${e.toLowerCase()}:${t}`).sort().join("\n"), n = 5381;
|
|
8
8
|
for (let e = 0; e < t.length; e += 1) n = (n << 5) + n + t.charCodeAt(e) | 0;
|
|
9
9
|
return `${t.length}:${n >>> 0}`;
|
|
10
10
|
}
|
|
11
|
-
var
|
|
11
|
+
var p = new Set([
|
|
12
12
|
429,
|
|
13
13
|
502,
|
|
14
14
|
503,
|
|
15
15
|
504
|
|
16
|
-
]),
|
|
17
|
-
function
|
|
16
|
+
]), m = 3, h = 400, g = 2e3;
|
|
17
|
+
function _(e, t) {
|
|
18
18
|
let n = e === null ? NaN : Number(e);
|
|
19
|
-
return Math.min(Number.isFinite(n) && n >= 0 ? n * 1e3 :
|
|
19
|
+
return Math.min(Number.isFinite(n) && n >= 0 ? n * 1e3 : h * 2 ** (t - 1), g);
|
|
20
20
|
}
|
|
21
|
-
function
|
|
21
|
+
function v(e, t) {
|
|
22
22
|
return new Promise((n) => {
|
|
23
23
|
if (t.aborted) {
|
|
24
24
|
n();
|
|
@@ -33,44 +33,44 @@ function _(e, t) {
|
|
|
33
33
|
t.addEventListener("abort", i, { once: !0 });
|
|
34
34
|
});
|
|
35
35
|
}
|
|
36
|
-
function
|
|
37
|
-
let
|
|
36
|
+
function y(h) {
|
|
37
|
+
let g = h.fetchImpl ?? ((...e) => fetch(...e)), y = h.now ?? (() => Date.now()), b = null, x = null, S = 0, C = null, w = null, T = 0, E = null, D = null, O = () => {
|
|
38
38
|
try {
|
|
39
|
-
return
|
|
39
|
+
return h.getHeaders?.() ?? {};
|
|
40
40
|
} catch {
|
|
41
41
|
return {};
|
|
42
42
|
}
|
|
43
|
-
},
|
|
44
|
-
for (let e of [...
|
|
45
|
-
},
|
|
46
|
-
|
|
47
|
-
},
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
let e =
|
|
43
|
+
}, k = () => y() >= T ? !1 : D === null ? !0 : f(O()) === D, A = /* @__PURE__ */ new Set(), j = () => {
|
|
44
|
+
for (let e of [...A]) e();
|
|
45
|
+
}, M = () => {
|
|
46
|
+
E !== null && clearTimeout(E), E = null;
|
|
47
|
+
}, N = (e) => {
|
|
48
|
+
M(), E = setTimeout(() => {
|
|
49
|
+
E = null;
|
|
50
|
+
let e = T - y();
|
|
51
51
|
if (e > 0) {
|
|
52
|
-
|
|
52
|
+
N(e);
|
|
53
53
|
return;
|
|
54
54
|
}
|
|
55
|
-
|
|
55
|
+
j();
|
|
56
56
|
}, e);
|
|
57
|
-
},
|
|
58
|
-
|
|
59
|
-
}, P = () => {
|
|
60
|
-
b &&= (URL.revokeObjectURL(b), null);
|
|
57
|
+
}, P = (e, t) => {
|
|
58
|
+
T = y() + e, D = t, N(e), j();
|
|
61
59
|
}, F = () => {
|
|
62
|
-
|
|
63
|
-
|
|
60
|
+
x &&= (URL.revokeObjectURL(x), null);
|
|
61
|
+
}, I = () => {
|
|
62
|
+
if (b) {
|
|
63
|
+
b.onended = null, b.onerror = null;
|
|
64
64
|
try {
|
|
65
|
-
|
|
65
|
+
b.pause();
|
|
66
66
|
} catch {}
|
|
67
|
-
|
|
67
|
+
b = null;
|
|
68
68
|
}
|
|
69
|
-
|
|
69
|
+
F();
|
|
70
70
|
};
|
|
71
|
-
async function
|
|
72
|
-
let c = i(e, r(n.lang) ?? n.lang, t, n.voice?.name ?? null, n.rate), l =
|
|
73
|
-
for (let e = 1; u = await h
|
|
71
|
+
async function L(e, n, s) {
|
|
72
|
+
let c = i(e, r(n.lang) ?? n.lang, t, n.voice?.name ?? null, n.rate), l = h.getHeaders?.() ?? {}, u;
|
|
73
|
+
for (let e = 1; u = await g(h.endpoint, {
|
|
74
74
|
method: "POST",
|
|
75
75
|
signal: s,
|
|
76
76
|
headers: {
|
|
@@ -79,41 +79,41 @@ function v(m) {
|
|
|
79
79
|
},
|
|
80
80
|
body: JSON.stringify(c)
|
|
81
81
|
}), !u.ok; e += 1) {
|
|
82
|
-
if (!(
|
|
82
|
+
if (!(p.has(u.status) && e < m && !s.aborted)) {
|
|
83
83
|
let e = /* @__PURE__ */ Error(`hosted tts ${u.status}`);
|
|
84
|
-
throw e.reason = a(u.status), e.headers =
|
|
84
|
+
throw e.reason = a(u.status), e.headers = f(l), e;
|
|
85
85
|
}
|
|
86
|
-
await _(
|
|
86
|
+
await v(_(u.headers.get("retry-after"), e), s);
|
|
87
87
|
}
|
|
88
|
-
let
|
|
88
|
+
let d = u.headers.get("content-type"), y = o(d, d?.includes("json") ? await u.json() : await u.arrayBuffer());
|
|
89
89
|
if (!y) {
|
|
90
90
|
let e = /* @__PURE__ */ Error("hosted tts returned no audio");
|
|
91
91
|
throw e.reason = "unknown", e;
|
|
92
92
|
}
|
|
93
93
|
return y;
|
|
94
94
|
}
|
|
95
|
-
function
|
|
95
|
+
function R(t, n, r) {
|
|
96
96
|
return new Promise((i, a) => {
|
|
97
|
-
if (n !==
|
|
97
|
+
if (n !== S) {
|
|
98
98
|
i();
|
|
99
99
|
return;
|
|
100
100
|
}
|
|
101
101
|
let o = new Blob([t.slice().buffer], { type: "audio/mpeg" });
|
|
102
|
-
|
|
103
|
-
let s = new Audio(
|
|
104
|
-
e(s),
|
|
105
|
-
n ===
|
|
102
|
+
F(), x = URL.createObjectURL(o);
|
|
103
|
+
let s = new Audio(x);
|
|
104
|
+
e(s), b = s, s.onended = () => {
|
|
105
|
+
n === S && i();
|
|
106
106
|
}, s.onerror = () => {
|
|
107
|
-
if (n !==
|
|
107
|
+
if (n !== S) {
|
|
108
108
|
i();
|
|
109
109
|
return;
|
|
110
110
|
}
|
|
111
111
|
let e = /* @__PURE__ */ Error("audio playback failed");
|
|
112
112
|
e.reason = "unknown", a(e);
|
|
113
113
|
}, s.play().then(() => {
|
|
114
|
-
n ===
|
|
114
|
+
n === S && r?.();
|
|
115
115
|
}, (e) => {
|
|
116
|
-
if (n !==
|
|
116
|
+
if (n !== S) {
|
|
117
117
|
i();
|
|
118
118
|
return;
|
|
119
119
|
}
|
|
@@ -125,14 +125,14 @@ function v(m) {
|
|
|
125
125
|
return {
|
|
126
126
|
id: "hosted-tts",
|
|
127
127
|
isSupported() {
|
|
128
|
-
return
|
|
128
|
+
return k() ? !1 : typeof window < "u" && typeof window.Audio == "function" && typeof fetch == "function";
|
|
129
129
|
},
|
|
130
130
|
listVoices() {
|
|
131
|
-
return
|
|
131
|
+
return k() ? [] : [...n];
|
|
132
132
|
},
|
|
133
133
|
subscribeVoices(e) {
|
|
134
|
-
return
|
|
135
|
-
|
|
134
|
+
return A.add(e), () => {
|
|
135
|
+
A.delete(e);
|
|
136
136
|
};
|
|
137
137
|
},
|
|
138
138
|
speak(e, t, n = {}) {
|
|
@@ -141,61 +141,66 @@ function v(m) {
|
|
|
141
141
|
n.onEnd?.();
|
|
142
142
|
return;
|
|
143
143
|
}
|
|
144
|
-
|
|
145
|
-
let i =
|
|
146
|
-
|
|
144
|
+
S += 1;
|
|
145
|
+
let i = S;
|
|
146
|
+
I(), w?.cancel();
|
|
147
147
|
let a = new AbortController();
|
|
148
|
-
|
|
149
|
-
let o = !1,
|
|
148
|
+
C = a;
|
|
149
|
+
let o = !1, f = () => {
|
|
150
150
|
o || (o = !0, n.onStart?.());
|
|
151
|
-
},
|
|
152
|
-
let n =
|
|
151
|
+
}, p = (e) => {
|
|
152
|
+
let n = L(e, t, a.signal);
|
|
153
153
|
return n.catch(() => {}), n;
|
|
154
|
-
},
|
|
155
|
-
play: (e) =>
|
|
156
|
-
isCurrent: () => i ===
|
|
154
|
+
}, m = t.audioOutput ? u(t.audioOutput, {
|
|
155
|
+
play: (e) => R(e, i, f),
|
|
156
|
+
isCurrent: () => i === S,
|
|
157
157
|
onChunkStart: (e) => n.onChunkStart?.(e),
|
|
158
|
-
onStart:
|
|
158
|
+
onStart: f
|
|
159
159
|
}) : null;
|
|
160
|
-
|
|
160
|
+
w = m, (async () => {
|
|
161
161
|
try {
|
|
162
|
-
let e =
|
|
162
|
+
let e = p(r[0]);
|
|
163
163
|
for (let t = 0; t < r.length; t += 1) {
|
|
164
|
-
if (i !==
|
|
164
|
+
if (i !== S) return;
|
|
165
165
|
let a = await e;
|
|
166
|
-
if (i !==
|
|
166
|
+
if (i !== S) return;
|
|
167
167
|
let o = r[t + 1];
|
|
168
|
-
if (o !== void 0 && (e =
|
|
169
|
-
await
|
|
168
|
+
if (o !== void 0 && (e = p(o)), m) {
|
|
169
|
+
await m.write(a);
|
|
170
170
|
continue;
|
|
171
171
|
}
|
|
172
|
-
n.onChunkStart?.(t), await
|
|
172
|
+
n.onChunkStart?.(t), await R(a, i, f);
|
|
173
173
|
}
|
|
174
|
-
if (
|
|
175
|
-
let e = await
|
|
176
|
-
if (i !==
|
|
174
|
+
if (m) {
|
|
175
|
+
let e = await m.drain();
|
|
176
|
+
if (i !== S) return;
|
|
177
177
|
if (!e) throw Object.assign(/* @__PURE__ */ Error("audio output did not finish"), { reason: "unknown" });
|
|
178
178
|
}
|
|
179
|
-
i ===
|
|
179
|
+
i === S && n.onEnd?.();
|
|
180
180
|
} catch (e) {
|
|
181
|
-
if (a.abort(), i !==
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
181
|
+
if (a.abort(), i !== S) return;
|
|
182
|
+
let t = null;
|
|
183
|
+
if (m) {
|
|
184
|
+
let n = await m.drain().then(() => null, (e) => e);
|
|
185
|
+
if (i !== S) return;
|
|
186
|
+
m.cancel(), d(e) ? t = e : d(n) && (t = n);
|
|
187
|
+
}
|
|
188
|
+
if (S += 1, I(), t) {
|
|
189
|
+
n.onError?.("output-not-cleared");
|
|
190
|
+
return;
|
|
185
191
|
}
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
c(t, e?.transient === !0) && N(s(t), t === "not-allowed" ? e.headers ?? null : null), n.onError?.(t === "not-allowed" || t === "unsupported" || t === "cancelled" ? t : "unknown");
|
|
192
|
+
let r = e?.reason;
|
|
193
|
+
c(r, e?.transient === !0) && P(s(r), r === "not-allowed" ? e.headers ?? null : null), n.onError?.(r === "not-allowed" || r === "unsupported" || r === "cancelled" ? r : "unknown");
|
|
189
194
|
}
|
|
190
195
|
})();
|
|
191
196
|
},
|
|
192
197
|
headersChanged() {
|
|
193
|
-
|
|
198
|
+
y() >= T || D === null || k() || (T = 0, D = null, M(), j());
|
|
194
199
|
},
|
|
195
200
|
cancel() {
|
|
196
|
-
|
|
201
|
+
S += 1, C?.abort(), C = null, I(), w?.cancel(), w = null;
|
|
197
202
|
}
|
|
198
203
|
};
|
|
199
204
|
}
|
|
200
205
|
//#endregion
|
|
201
|
-
export {
|
|
206
|
+
export { y as createHostedTtsEngine, _ as retryDelayMs };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SpeechAudioOutput } from './types';
|
|
1
|
+
import { SpeechAudioOutput, SpeechOutputRefusal } from './types';
|
|
2
2
|
/** @internal What the sink needs from the reply it belongs to. */
|
|
3
3
|
export interface PieceSinkReply {
|
|
4
4
|
/** Plays one piece on the speakers and resolves when it has finished: the engine's own `play`. */
|
|
@@ -16,7 +16,8 @@ export interface PieceSink {
|
|
|
16
16
|
* Hand over the reply's next piece. Pieces are numbered 0, 1, 2… by ONE
|
|
17
17
|
* counter for the whole reply: a queue's count continues across appends and
|
|
18
18
|
* across drains, and a retracted number is never given again. Resolves when
|
|
19
|
-
* the next piece may follow; rejects as `drain` does once the speakers fail
|
|
19
|
+
* the next piece may follow; rejects as `drain` does once the speakers fail
|
|
20
|
+
* or the output refused the reply.
|
|
20
21
|
*/
|
|
21
22
|
write(bytes: Uint8Array): Promise<void>;
|
|
22
23
|
/**
|
|
@@ -25,10 +26,11 @@ export interface PieceSink {
|
|
|
25
26
|
* never confirmed (a leave is not a failure: `true`). Callable any number of
|
|
26
27
|
* times; writing may go on after it, even while it is pending (a piece written
|
|
27
28
|
* meanwhile is not part of it). Never rejects with the output's reason, only
|
|
28
|
-
* with the speakers' own failure, which the engine reports as it always has
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
29
|
+
* with the speakers' own failure, which the engine reports as it always has,
|
|
30
|
+
* or with the output's REFUSAL (`SpeechOutputRefusal`, operator decision
|
|
31
|
+
* D7 b), which the engine reports as `output-not-cleared`. Either one is kept:
|
|
32
|
+
* every later or queued `write` and `drain` rejects with it until `cancel()`,
|
|
33
|
+
* nothing more plays, and nothing is confirmed.
|
|
32
34
|
*/
|
|
33
35
|
drain(): Promise<boolean>;
|
|
34
36
|
/**
|
|
@@ -39,5 +41,11 @@ export interface PieceSink {
|
|
|
39
41
|
/** The hard stop: silence the output and drop everything. Nothing is replayed. */
|
|
40
42
|
cancel(): void;
|
|
41
43
|
}
|
|
42
|
-
/**
|
|
44
|
+
/**
|
|
45
|
+
* @internal The output REFUSED the reply (`SpeechOutputRefusal`, operator
|
|
46
|
+
* decision D7 b): nothing of it may be heard anywhere. The engine reads it to
|
|
47
|
+
* report `output-not-cleared`.
|
|
48
|
+
*/
|
|
49
|
+
export declare const isOutputRefusal: (cause: unknown) => cause is SpeechOutputRefusal;
|
|
50
|
+
/** @internal One reply's piece sink, playing on `output` until it fails, leaves or refuses. */
|
|
43
51
|
export declare function createPieceSink(output: SpeechAudioOutput, reply: PieceSinkReply): PieceSink;
|
|
@@ -1,84 +1,90 @@
|
|
|
1
|
-
import { SPEECH_OUTPUT_LEFT as e } from "./types.js";
|
|
1
|
+
import { SPEECH_OUTPUT_LEFT as e, SPEECH_OUTPUT_REFUSE_AUDIBLE as t } from "./types.js";
|
|
2
2
|
//#region src/shared/assistant/speech/pieceSink.ts
|
|
3
|
-
var
|
|
4
|
-
function
|
|
5
|
-
let
|
|
6
|
-
let e =
|
|
7
|
-
|
|
3
|
+
var n = (t) => t?.reason === e, r = (e) => e?.reason === t;
|
|
4
|
+
function i(e, t) {
|
|
5
|
+
let i = e, a = !1, o = 0, s = /* @__PURE__ */ new Map(), c = null, l = () => !a && t.isCurrent(), u = () => {
|
|
6
|
+
let e = i;
|
|
7
|
+
i = null;
|
|
8
8
|
try {
|
|
9
9
|
e?.cancel();
|
|
10
10
|
} catch {}
|
|
11
|
-
},
|
|
12
|
-
if (
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
}, d = (e) => (c === null && (c = e), s.clear(), u(), c), f = () => {
|
|
12
|
+
if (c !== null && l()) throw c;
|
|
13
|
+
}, p = (e, n) => () => {
|
|
14
|
+
if (!(i !== e || !l() || !s.has(n))) {
|
|
15
|
+
for (let e of s.keys()) {
|
|
16
|
+
if (e > n) break;
|
|
17
|
+
s.delete(e);
|
|
16
18
|
}
|
|
17
|
-
|
|
19
|
+
t.onChunkStart(n), t.onStart();
|
|
18
20
|
}
|
|
19
|
-
},
|
|
20
|
-
for (let [e,
|
|
21
|
-
if (!
|
|
22
|
-
|
|
21
|
+
}, m = !1, h = async () => {
|
|
22
|
+
for (let [e, n] of s) {
|
|
23
|
+
if (!l()) return;
|
|
24
|
+
s.delete(e), m = !0, t.onChunkStart(e);
|
|
23
25
|
try {
|
|
24
|
-
await
|
|
26
|
+
await t.play(n);
|
|
25
27
|
} catch (e) {
|
|
26
|
-
throw
|
|
28
|
+
throw s.clear(), c ?? e;
|
|
27
29
|
}
|
|
28
30
|
}
|
|
29
|
-
},
|
|
30
|
-
if (!
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
}, g = Promise.resolve(), _ = () => {
|
|
32
|
+
if (!l()) return Promise.resolve();
|
|
33
|
+
if (c !== null) return Promise.reject(c);
|
|
34
|
+
let e = g.then(h);
|
|
35
|
+
return g = e, e;
|
|
33
36
|
};
|
|
34
37
|
return {
|
|
35
38
|
async write(e) {
|
|
36
|
-
let t =
|
|
37
|
-
if (
|
|
38
|
-
|
|
39
|
-
|
|
39
|
+
let t = o;
|
|
40
|
+
if (o += 1, !l()) return;
|
|
41
|
+
if (c !== null) throw c;
|
|
42
|
+
s.set(t, e);
|
|
43
|
+
let n = i;
|
|
40
44
|
if (n) try {
|
|
41
|
-
await n.write(e, t,
|
|
42
|
-
} catch {
|
|
43
|
-
if (!
|
|
44
|
-
r
|
|
45
|
+
await n.write(e, t, p(n, t));
|
|
46
|
+
} catch (e) {
|
|
47
|
+
if (!l()) return;
|
|
48
|
+
if (r(e)) throw d(e);
|
|
49
|
+
i === n && u();
|
|
45
50
|
}
|
|
46
|
-
|
|
51
|
+
i === null && await _(), f();
|
|
47
52
|
},
|
|
48
53
|
async drain() {
|
|
49
|
-
let e =
|
|
50
|
-
if (e &&
|
|
51
|
-
let
|
|
54
|
+
let e = i;
|
|
55
|
+
if (e && l()) {
|
|
56
|
+
let t = o;
|
|
52
57
|
try {
|
|
53
|
-
if (await e.drain(),
|
|
54
|
-
for (let e of
|
|
55
|
-
if (e >=
|
|
56
|
-
|
|
58
|
+
if (await e.drain(), i === e) {
|
|
59
|
+
for (let e of s.keys()) {
|
|
60
|
+
if (e >= t) break;
|
|
61
|
+
s.delete(e);
|
|
57
62
|
}
|
|
58
63
|
return !0;
|
|
59
64
|
}
|
|
60
|
-
} catch (
|
|
61
|
-
if (!
|
|
62
|
-
|
|
63
|
-
|
|
65
|
+
} catch (t) {
|
|
66
|
+
if (!l()) return !0;
|
|
67
|
+
if (r(t)) throw d(t);
|
|
68
|
+
let a = n(t) || s.size > 0;
|
|
69
|
+
return i === e && u(), await _(), f(), a || m;
|
|
64
70
|
}
|
|
65
71
|
}
|
|
66
|
-
return await
|
|
72
|
+
return await _(), f(), !0;
|
|
67
73
|
},
|
|
68
74
|
retract(e) {
|
|
69
|
-
if (!
|
|
70
|
-
let t =
|
|
75
|
+
if (!l()) return;
|
|
76
|
+
let t = i;
|
|
71
77
|
if (t) try {
|
|
72
78
|
t.retract(e);
|
|
73
79
|
} catch {
|
|
74
|
-
|
|
80
|
+
i === t && u();
|
|
75
81
|
}
|
|
76
|
-
for (let t of
|
|
82
|
+
for (let t of s.keys()) t >= e && s.delete(t);
|
|
77
83
|
},
|
|
78
84
|
cancel() {
|
|
79
|
-
|
|
85
|
+
a = !0, s.clear(), u();
|
|
80
86
|
}
|
|
81
87
|
};
|
|
82
88
|
}
|
|
83
89
|
//#endregion
|
|
84
|
-
export {
|
|
90
|
+
export { i as createPieceSink, r as isOutputRefusal };
|
|
@@ -2,82 +2,92 @@ import { hostedSupportsLanguage as e } from "./hostedVoiceCatalogue.js";
|
|
|
2
2
|
import { speakableChunks as t } from "./hostedTtsProtocol.js";
|
|
3
3
|
import { selectVoiceForLocale as n } from "../voice/speechVoices.js";
|
|
4
4
|
//#region src/shared/assistant/speech/routingSpeechEngine.ts
|
|
5
|
-
function r(
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
function r(e) {
|
|
6
|
+
switch (e) {
|
|
7
|
+
case "cancelled":
|
|
8
|
+
case "output-not-cleared": return !1;
|
|
9
|
+
case "not-allowed":
|
|
10
|
+
case "unsupported":
|
|
11
|
+
case "unknown": return !0;
|
|
12
|
+
default: return e;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
function i({ device: i, hosted: a }) {
|
|
16
|
+
if (!a) return i;
|
|
17
|
+
let o = new Set(a.listVoices().map((e) => e.name)), s = (e) => e.source === "hosted" || o.has(e.name), c = (e, t, r) => {
|
|
18
|
+
if (!t.voice || !s(t.voice)) {
|
|
19
|
+
i.speak(e, t, r);
|
|
10
20
|
return;
|
|
11
21
|
}
|
|
12
22
|
if (t.fallback === !1) {
|
|
13
|
-
|
|
23
|
+
r?.onError?.("unsupported");
|
|
14
24
|
return;
|
|
15
25
|
}
|
|
16
|
-
let a = n(
|
|
26
|
+
let a = n(i.listVoices(), t.lang);
|
|
17
27
|
if (!a) {
|
|
18
|
-
|
|
28
|
+
r?.onError?.("unsupported");
|
|
19
29
|
return;
|
|
20
30
|
}
|
|
21
|
-
|
|
31
|
+
i.speak(e, {
|
|
22
32
|
...t,
|
|
23
33
|
voice: a
|
|
24
|
-
},
|
|
25
|
-
},
|
|
34
|
+
}, r);
|
|
35
|
+
}, l = (t) => a.isSupported() ? t.voice ? o.has(t.voice.name) ? a : i : e(t.lang) ? a : i : i;
|
|
26
36
|
return {
|
|
27
|
-
id: `routing(${
|
|
37
|
+
id: `routing(${a.id}+${i.id})`,
|
|
28
38
|
isSupported() {
|
|
29
|
-
return
|
|
39
|
+
return a.isSupported() || i.isSupported();
|
|
30
40
|
},
|
|
31
41
|
listVoices() {
|
|
32
|
-
return
|
|
42
|
+
return a.isSupported() ? [...a.listVoices(), ...i.listVoices()] : i.listVoices();
|
|
33
43
|
},
|
|
34
44
|
subscribeVoices(e) {
|
|
35
|
-
let t =
|
|
45
|
+
let t = i.subscribeVoices(e), n = a.subscribeVoices(e);
|
|
36
46
|
return () => {
|
|
37
47
|
t(), n();
|
|
38
48
|
};
|
|
39
49
|
},
|
|
40
|
-
speak(e, n,
|
|
41
|
-
if (
|
|
42
|
-
|
|
50
|
+
speak(e, n, o) {
|
|
51
|
+
if (i.cancel(), a.cancel(), l(n) !== a) {
|
|
52
|
+
c(e, n, o);
|
|
43
53
|
return;
|
|
44
54
|
}
|
|
45
|
-
let
|
|
46
|
-
|
|
47
|
-
...
|
|
55
|
+
let s = !1, u = -1;
|
|
56
|
+
a.speak(e, n, {
|
|
57
|
+
...o,
|
|
48
58
|
onStart: () => {
|
|
49
|
-
|
|
59
|
+
s = !0, o?.onStart?.();
|
|
50
60
|
},
|
|
51
61
|
onChunkStart: (e) => {
|
|
52
|
-
|
|
62
|
+
u = e, o?.onChunkStart?.(e);
|
|
53
63
|
},
|
|
54
|
-
onError: (
|
|
55
|
-
if (r
|
|
56
|
-
|
|
64
|
+
onError: (i) => {
|
|
65
|
+
if (!r(i) || n.fallback === !1) {
|
|
66
|
+
o?.onError?.(i);
|
|
57
67
|
return;
|
|
58
68
|
}
|
|
59
|
-
if (!
|
|
60
|
-
|
|
69
|
+
if (!s) {
|
|
70
|
+
c(e, n, o);
|
|
61
71
|
return;
|
|
62
72
|
}
|
|
63
|
-
let
|
|
64
|
-
if (
|
|
65
|
-
|
|
73
|
+
let a = u >= 0 ? t(e).slice(u + 1) : [];
|
|
74
|
+
if (a.length === 0) {
|
|
75
|
+
o?.onError?.(i);
|
|
66
76
|
return;
|
|
67
77
|
}
|
|
68
|
-
let
|
|
69
|
-
|
|
70
|
-
...
|
|
78
|
+
let l = u + 1;
|
|
79
|
+
c(a, n, {
|
|
80
|
+
...o,
|
|
71
81
|
onStart: void 0,
|
|
72
|
-
onChunkStart: (e) =>
|
|
82
|
+
onChunkStart: (e) => o?.onChunkStart?.(l + e)
|
|
73
83
|
});
|
|
74
84
|
}
|
|
75
85
|
});
|
|
76
86
|
},
|
|
77
87
|
cancel() {
|
|
78
|
-
|
|
88
|
+
i.cancel(), a.cancel();
|
|
79
89
|
}
|
|
80
90
|
};
|
|
81
91
|
}
|
|
82
92
|
//#endregion
|
|
83
|
-
export {
|
|
93
|
+
export { i as createRoutingSpeechEngine };
|