@burdenoff/fe-libs 2026.1016.3 → 2026.1017.1
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.d.ts +6 -0
- package/dist/shared/assistant/speech/hostedTtsSpeechEngine.js +118 -101
- package/dist/shared/assistant/speech/notifyCancellationSpeechEngine.js +3 -0
- package/dist/shared/assistant/speech/routingSpeechEngine.js +11 -8
- package/dist/shared/assistant/speech/types.d.ts +11 -0
- package/dist/shared/assistant/ui/AssistantMessageItem.js +110 -100
- package/dist/shared/assistant/ui/AssistantSpeechProvider.d.ts +10 -0
- package/dist/shared/assistant/ui/AssistantSpeechProvider.js +278 -261
- package/dist/shared/assistant/ui/useVoiceSession.js +222 -227
- package/dist/shared/assistant/voice/handsfree/playbackReference.d.ts +15 -4
- package/dist/shared/assistant/voice/handsfree/playbackReference.js +9 -6
- package/dist/shared-assistant.js +270 -270
- package/package.json +1 -1
|
@@ -2,14 +2,15 @@ import { useI18n as e } from "../../providers/shell/I18nProvider.js";
|
|
|
2
2
|
import { useAssistantTr as t } from "../i18n.js";
|
|
3
3
|
import { useAssistantStore as n } from "../store.js";
|
|
4
4
|
import { isVoiceTurn as r } from "../voice/turnVisibility.js";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
5
|
+
import { HOSTED_VOICES as i } from "../speech/hostedVoiceCatalogue.js";
|
|
6
|
+
import { VOICE_LIST_TIMEOUT_MS as a, languageDisplayName as o, selectVoiceForLocale as s, speechGate as ee, speechLangForLocale as c, voiceAvailability as te, voicesForLocale as l } from "../voice/speechVoices.js";
|
|
7
|
+
import { getSpeechEngine as u, subscribeSpeechEngine as ne } from "../speech/createSpeechEngine.js";
|
|
8
|
+
import { speechFeed as d } from "../speech/speechFeed.js";
|
|
9
|
+
import { hasPendingReplyRequests as f, releaseReplyRequestsOutside as p, replyWantsAvatar as re, settleReplyRequest as m, subscribeReplyRequests as h } from "../speech/replySpeechRequests.js";
|
|
10
|
+
import { isTurnSuperseded as g } from "../voice/supersededTurns.js";
|
|
11
|
+
import { chunkForSpeech as ie, toSpeakableText as _ } from "../voice/speakableText.js";
|
|
12
|
+
import { voicePreviewText as ae } from "../voice/voicePreview.js";
|
|
13
|
+
import { findAssistantLanguage as v } from "../voice/languages.js";
|
|
13
14
|
import { resolveLanguagePair as oe } from "../voice/languagePair.js";
|
|
14
15
|
import { speechLabelsFor as se } from "../voice/speechLabels.js";
|
|
15
16
|
import { resolveSpeechLocale as ce } from "../voice/replyLanguage.js";
|
|
@@ -18,7 +19,7 @@ import { isTurnInFlight as pe } from "../turnState.js";
|
|
|
18
19
|
import { parseToolActivity as me } from "./AssistantToolActivity.js";
|
|
19
20
|
import "../speech/index.js";
|
|
20
21
|
import { markTurn as he } from "../turnTimeline.js";
|
|
21
|
-
import { createContext as ge, useCallback as
|
|
22
|
+
import { createContext as ge, useCallback as y, useContext as _e, useEffect as b, useMemo as x, useReducer as ve, useRef as S, useState as C, useSyncExternalStore as ye } from "react";
|
|
22
23
|
import { jsx as be } from "react/jsx-runtime";
|
|
23
24
|
//#region src/shared/assistant/ui/AssistantSpeechProvider.tsx
|
|
24
25
|
var xe = {
|
|
@@ -30,15 +31,15 @@ var xe = {
|
|
|
30
31
|
emailAt: "at",
|
|
31
32
|
emailDot: "dot",
|
|
32
33
|
nestedItem: ""
|
|
33
|
-
}, Se = 4e3,
|
|
34
|
-
subscribe: () =>
|
|
34
|
+
}, Se = 4e3, w = () => {}, Ce = {
|
|
35
|
+
subscribe: () => w,
|
|
35
36
|
getSnapshot: () => !1
|
|
36
37
|
}, we = {
|
|
37
|
-
subscribe:
|
|
38
|
-
getSnapshot:
|
|
38
|
+
subscribe: h,
|
|
39
|
+
getSnapshot: f
|
|
39
40
|
};
|
|
40
41
|
function Te(e, t) {
|
|
41
|
-
return
|
|
42
|
+
return re(t) ? {
|
|
42
43
|
...e,
|
|
43
44
|
autoSpeakEnabled: !0
|
|
44
45
|
} : e;
|
|
@@ -59,6 +60,7 @@ var De = ge({
|
|
|
59
60
|
isBlocked: !0,
|
|
60
61
|
disabledReason: null,
|
|
61
62
|
blockedFor: () => null,
|
|
63
|
+
deviceFallbackFor: () => null,
|
|
62
64
|
voiceChoices: [],
|
|
63
65
|
spokenChunks: null,
|
|
64
66
|
activeVoiceName: null,
|
|
@@ -77,275 +79,288 @@ var De = ge({
|
|
|
77
79
|
speakFinishedReply: () => {},
|
|
78
80
|
previewVoice: () => {}
|
|
79
81
|
});
|
|
80
|
-
function
|
|
82
|
+
function T() {
|
|
81
83
|
return _e(De);
|
|
82
84
|
}
|
|
83
|
-
var
|
|
84
|
-
let _e = ye(
|
|
85
|
-
|
|
86
|
-
|
|
85
|
+
var E = ({ children: f, visible: h = !0, engine: ge }) => {
|
|
86
|
+
let _e = ye(ne, u, u), w = ge ?? _e, T = t(), { locale: E } = e(), [D, O] = ve(fe, le), [k, A] = C(() => w.listVoices()), [j, Oe] = C(!1), [ke, M] = C(() => /* @__PURE__ */ new Map()), [Ae, N] = C(() => /* @__PURE__ */ new Set()), [je, Me] = C(null), P = S(0), F = S(null), I = S(null), L = S(null), R = S(null);
|
|
87
|
+
b(() => () => {
|
|
88
|
+
R.current !== null && clearTimeout(R.current);
|
|
87
89
|
}, []);
|
|
88
|
-
let [
|
|
89
|
-
|
|
90
|
-
}, []),
|
|
91
|
-
|
|
92
|
-
}, []),
|
|
93
|
-
|
|
94
|
-
if (!
|
|
90
|
+
let [Ne, Pe] = C(null), z = S(null), Fe = S(() => {}), B = y(() => {
|
|
91
|
+
z.current?.(), z.current = null;
|
|
92
|
+
}, []), V = n((e) => e.autoSpeakEnabled), Ie = n((e) => e.setAutoSpeak), [H, Le] = C(!1), Re = S(!1), ze = y((e) => {
|
|
93
|
+
Re.current = e;
|
|
94
|
+
}, []), Be = n((e) => e.activeConversationId), U = x(() => w.isSupported(), [w]), Ve = w.wouldSpeakOnAvatar === void 0 ? Ce : we, He = ye(Ve.subscribe, Ve.getSnapshot, Ve.getSnapshot);
|
|
95
|
+
b(() => {
|
|
96
|
+
if (!U) return;
|
|
95
97
|
let e = () => {
|
|
96
|
-
|
|
98
|
+
A(w.listVoices()), M((e) => e.size === 0 ? e : /* @__PURE__ */ new Map());
|
|
97
99
|
};
|
|
98
|
-
return e(),
|
|
99
|
-
}, [
|
|
100
|
-
let
|
|
101
|
-
He,
|
|
100
|
+
return e(), w.subscribeVoices(e);
|
|
101
|
+
}, [w, U]);
|
|
102
|
+
let Ue = n((e) => e.assistantLanguage), We = n((e) => e.replyLanguage), W = n((e) => e.preferredVoices), Ge = n((e) => e.setPreferredVoice), G = x(() => oe(Ue, We, E).reply, [
|
|
102
103
|
Ue,
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
O,
|
|
104
|
+
We,
|
|
105
|
+
E
|
|
106
|
+
]), K = G.code, q = y((e) => v(e)?.tag ?? c(e), []), Ke = y((e) => v(e)?.rate ?? .9, []), J = x(() => te(U, k, G.tag, j), [
|
|
107
107
|
U,
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
}, [
|
|
121
|
-
|
|
108
|
+
k,
|
|
109
|
+
G,
|
|
110
|
+
j
|
|
111
|
+
]), qe = x(() => ({
|
|
112
|
+
codeBlock: T("speech.codeBlock", "Code block"),
|
|
113
|
+
image: T("speech.image", "image"),
|
|
114
|
+
link: T("speech.link", "link"),
|
|
115
|
+
largeTable: T("speech.largeTable", "Table with {{rows}} rows and {{columns}} columns"),
|
|
116
|
+
truncated: T("speech.truncated", "The rest of this message is not read aloud"),
|
|
117
|
+
nestedItem: T("speech.nestedItem", "Sub-item {{ordinal}}"),
|
|
118
|
+
emailAt: T("speech.emailAt", "at"),
|
|
119
|
+
emailDot: T("speech.emailDot", "dot")
|
|
120
|
+
}), [T]), Y = y(() => {
|
|
121
|
+
B(), I.current = null, w.cancel(), m(F.current, "stopped"), O({ type: "stop" });
|
|
122
|
+
}, [B, w]), Je = y((e) => {
|
|
123
|
+
let t = w.listVoices().find((t) => t.name === e) ?? null;
|
|
122
124
|
if (t) {
|
|
123
|
-
|
|
125
|
+
Y();
|
|
124
126
|
try {
|
|
125
|
-
|
|
127
|
+
w.speak([ae(K)], {
|
|
126
128
|
voice: t,
|
|
127
|
-
lang:
|
|
129
|
+
lang: q(K),
|
|
128
130
|
fallback: !1
|
|
129
131
|
});
|
|
130
132
|
} catch {}
|
|
131
133
|
}
|
|
132
134
|
}, [
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
]),
|
|
138
|
-
|
|
139
|
-
let o = !1, s = () => {},
|
|
135
|
+
w,
|
|
136
|
+
K,
|
|
137
|
+
Y,
|
|
138
|
+
q
|
|
139
|
+
]), Ye = y((e) => ke.get(e) ?? null, [ke]), Xe = y((e) => Ae.has(e) ? T("speech.deviceFallback", "Device voice used: the selected voice was unavailable.") : null, [Ae, T]), Ze = y((e, t, n, r, i) => {
|
|
140
|
+
B();
|
|
141
|
+
let o = !1, s = () => {}, ee = (a) => {
|
|
140
142
|
if (!o) {
|
|
141
|
-
if (o = !0,
|
|
142
|
-
Oe(!0),
|
|
143
|
+
if (o = !0, z.current = null, clearTimeout(c), s(), a.length === 0) {
|
|
144
|
+
Oe(!0), m(e, "declined");
|
|
143
145
|
return;
|
|
144
146
|
}
|
|
145
|
-
|
|
147
|
+
A(a), Fe.current(e, t, a, n, r, i);
|
|
146
148
|
}
|
|
147
|
-
},
|
|
148
|
-
s =
|
|
149
|
-
o || (o = !0, clearTimeout(
|
|
149
|
+
}, c = setTimeout(() => ee(w.listVoices()), a);
|
|
150
|
+
s = w.subscribeVoices(() => ee(w.listVoices())), z.current = () => {
|
|
151
|
+
o || (o = !0, clearTimeout(c), s(), z.current = null, m(e, "stopped"));
|
|
150
152
|
};
|
|
151
|
-
}, [
|
|
152
|
-
let
|
|
153
|
-
if (
|
|
154
|
-
let e =
|
|
155
|
-
e.length > 0 && (
|
|
153
|
+
}, [B, w]), X = y((e, t, n, r, a = !1, c) => {
|
|
154
|
+
let l = n;
|
|
155
|
+
if (l.length === 0) {
|
|
156
|
+
let e = w.listVoices();
|
|
157
|
+
e.length > 0 && (l = e, A(e));
|
|
156
158
|
}
|
|
157
|
-
let
|
|
158
|
-
if (
|
|
159
|
-
let t =
|
|
160
|
-
|
|
159
|
+
let u = q(r), ne = ee(te(!0, l, r, j));
|
|
160
|
+
if (ne === "block") {
|
|
161
|
+
let t = T("speech.noVoiceForReply", "This reply is in {{language}}, and no {{language}} voice is installed on this device.", { language: o(u, E) });
|
|
162
|
+
M((n) => new Map(n).set(e, t)), m(e, "declined");
|
|
161
163
|
return;
|
|
162
164
|
}
|
|
163
|
-
if (
|
|
164
|
-
|
|
165
|
+
if (ne === "wait-for-voices") {
|
|
166
|
+
Ze(e, t, r, a, c);
|
|
165
167
|
return;
|
|
166
168
|
}
|
|
167
|
-
let
|
|
168
|
-
voice:
|
|
169
|
-
lang:
|
|
170
|
-
rate:
|
|
171
|
-
},
|
|
172
|
-
if (
|
|
173
|
-
if (
|
|
174
|
-
|
|
169
|
+
let d = {
|
|
170
|
+
voice: s(l, u, W[r]),
|
|
171
|
+
lang: u,
|
|
172
|
+
rate: Ke(r)
|
|
173
|
+
}, f = $e.current;
|
|
174
|
+
if (a && !f.autoSpeakEnabled && !f.sessionSpeaking && re(e)) {
|
|
175
|
+
if (w.wouldSpeakOnAvatar?.(d) !== !0) {
|
|
176
|
+
m(e, "declined");
|
|
175
177
|
return;
|
|
176
178
|
}
|
|
177
|
-
|
|
179
|
+
d.avatarOnly = !0;
|
|
178
180
|
}
|
|
179
|
-
|
|
181
|
+
M((t) => {
|
|
180
182
|
if (!t.has(e)) return t;
|
|
181
183
|
let n = new Map(t);
|
|
182
184
|
return n.delete(e), n;
|
|
183
|
-
})
|
|
184
|
-
let
|
|
185
|
-
|
|
185
|
+
});
|
|
186
|
+
let p = W[r], h = typeof p == "string" && i.some((e) => e.name === p) && !l.some((e) => e.name === p);
|
|
187
|
+
N((t) => {
|
|
188
|
+
if (t.has(e) === h) return t;
|
|
189
|
+
let n = new Set(t);
|
|
190
|
+
return h ? n.add(e) : n.delete(e), n;
|
|
191
|
+
}), B();
|
|
192
|
+
let g = P.current + 1;
|
|
193
|
+
P.current = g, F.current !== e && m(F.current, "stopped"), F.current = e, m(e, "speaking"), O({
|
|
186
194
|
type: "start",
|
|
187
195
|
messageId: e,
|
|
188
|
-
requestId:
|
|
189
|
-
}),
|
|
190
|
-
let
|
|
191
|
-
|
|
192
|
-
requestId:
|
|
193
|
-
chunks:
|
|
196
|
+
requestId: g
|
|
197
|
+
}), I.current = a ? g : null, a && he(e, "ttsStarted");
|
|
198
|
+
let _ = c === void 0 ? ie(t) : ie(t, void 0, void 0, { firstChunkMaxChars: c });
|
|
199
|
+
Pe({
|
|
200
|
+
requestId: g,
|
|
201
|
+
chunks: _,
|
|
194
202
|
index: -1
|
|
195
|
-
}),
|
|
196
|
-
|
|
203
|
+
}), R.current !== null && clearTimeout(R.current), R.current = setTimeout(() => {
|
|
204
|
+
Pe((e) => e?.requestId === g && e.index < 0 ? null : e);
|
|
197
205
|
}, Se);
|
|
198
|
-
let
|
|
199
|
-
|
|
206
|
+
let ae = () => {
|
|
207
|
+
P.current === g && R.current !== null && (clearTimeout(R.current), R.current = null), m(e, "failed"), O({
|
|
200
208
|
type: "failed",
|
|
201
|
-
requestId:
|
|
209
|
+
requestId: g
|
|
202
210
|
});
|
|
203
|
-
},
|
|
211
|
+
}, v = !1;
|
|
204
212
|
try {
|
|
205
|
-
|
|
213
|
+
w.speak(_, d, {
|
|
206
214
|
onStart: () => {
|
|
207
|
-
|
|
215
|
+
P.current === g && I.current === g && he(e, "firstAudio");
|
|
208
216
|
},
|
|
209
217
|
onChunkStart: (e) => {
|
|
210
|
-
|
|
218
|
+
v = !0, P.current === g && R.current !== null && (clearTimeout(R.current), R.current = null), Pe((t) => t?.requestId === g ? {
|
|
211
219
|
...t,
|
|
212
220
|
index: e
|
|
213
|
-
} :
|
|
214
|
-
requestId:
|
|
215
|
-
chunks:
|
|
221
|
+
} : P.current === g ? {
|
|
222
|
+
requestId: g,
|
|
223
|
+
chunks: _,
|
|
216
224
|
index: e
|
|
217
225
|
} : t);
|
|
218
226
|
},
|
|
227
|
+
onDeviceFallback: () => {
|
|
228
|
+
P.current === g && N((t) => t.has(e) ? t : new Set(t).add(e));
|
|
229
|
+
},
|
|
219
230
|
onEnd: () => {
|
|
220
|
-
|
|
231
|
+
P.current === g && I.current === g && he(e, "audioEnded"), m(e, "spoken"), O({
|
|
221
232
|
type: "finished",
|
|
222
|
-
requestId:
|
|
233
|
+
requestId: g
|
|
223
234
|
});
|
|
224
235
|
},
|
|
225
236
|
onError: (t) => {
|
|
226
|
-
|
|
237
|
+
!v && P.current === g && N((t) => {
|
|
238
|
+
if (!t.has(e)) return t;
|
|
239
|
+
let n = new Set(t);
|
|
240
|
+
return n.delete(e), n;
|
|
241
|
+
}), t === "output-not-cleared" && P.current === g && Me({ messageId: e }), m(e, t === "output-not-cleared" ? "not-cleared" : t === "output-left" ? v ? "cut" : "declined" : t === "cancelled" ? "stopped" : "failed"), O({
|
|
227
242
|
type: "failed",
|
|
228
|
-
requestId:
|
|
243
|
+
requestId: g
|
|
229
244
|
});
|
|
230
245
|
}
|
|
231
246
|
});
|
|
232
247
|
} catch {
|
|
233
|
-
|
|
248
|
+
ae();
|
|
234
249
|
}
|
|
235
250
|
}, [
|
|
236
|
-
|
|
237
|
-
C,
|
|
238
|
-
T,
|
|
239
|
-
H,
|
|
240
|
-
Ge,
|
|
241
|
-
G,
|
|
251
|
+
B,
|
|
242
252
|
w,
|
|
243
|
-
|
|
244
|
-
|
|
253
|
+
E,
|
|
254
|
+
W,
|
|
255
|
+
Ke,
|
|
256
|
+
q,
|
|
257
|
+
T,
|
|
258
|
+
j,
|
|
259
|
+
Ze
|
|
245
260
|
]);
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
}, [
|
|
249
|
-
let
|
|
250
|
-
if (!
|
|
251
|
-
let i = ce(_(t, { labels: xe }), n ??
|
|
252
|
-
a &&
|
|
261
|
+
b(() => {
|
|
262
|
+
Fe.current = X;
|
|
263
|
+
}, [X]);
|
|
264
|
+
let Z = y((e, t, n, r) => {
|
|
265
|
+
if (!U) return;
|
|
266
|
+
let i = ce(_(t, { labels: xe }), n ?? K), a = _(t, { labels: se(i, qe) });
|
|
267
|
+
a && X(e, a, k, i, r?.auto === !0, r?.firstChunkMaxChars);
|
|
253
268
|
}, [
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
]),
|
|
260
|
-
if (ue(
|
|
261
|
-
|
|
269
|
+
U,
|
|
270
|
+
qe,
|
|
271
|
+
K,
|
|
272
|
+
X,
|
|
273
|
+
k
|
|
274
|
+
]), Qe = y((e, t, n) => {
|
|
275
|
+
if (ue(D, e)) {
|
|
276
|
+
Y();
|
|
262
277
|
return;
|
|
263
278
|
}
|
|
264
|
-
|
|
279
|
+
Z(e, t, n);
|
|
265
280
|
}, [
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
281
|
+
D,
|
|
282
|
+
Z,
|
|
283
|
+
Y
|
|
269
284
|
]);
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
}, [
|
|
273
|
-
let
|
|
274
|
-
autoSpeakEnabled:
|
|
275
|
-
sessionSpeaking:
|
|
276
|
-
visible:
|
|
277
|
-
isSupported:
|
|
285
|
+
b(() => {
|
|
286
|
+
h || Y();
|
|
287
|
+
}, [h, Y]);
|
|
288
|
+
let $e = S({
|
|
289
|
+
autoSpeakEnabled: V,
|
|
290
|
+
sessionSpeaking: H,
|
|
291
|
+
visible: h,
|
|
292
|
+
isSupported: U
|
|
278
293
|
});
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
autoSpeakEnabled:
|
|
282
|
-
sessionSpeaking:
|
|
283
|
-
visible:
|
|
284
|
-
isSupported:
|
|
294
|
+
b(() => {
|
|
295
|
+
$e.current = {
|
|
296
|
+
autoSpeakEnabled: V,
|
|
297
|
+
sessionSpeaking: H,
|
|
298
|
+
visible: h,
|
|
299
|
+
isSupported: U
|
|
285
300
|
};
|
|
286
301
|
}, [
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
302
|
+
V,
|
|
303
|
+
H,
|
|
304
|
+
h,
|
|
305
|
+
U
|
|
291
306
|
]);
|
|
292
|
-
let
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
let e =
|
|
296
|
-
|
|
297
|
-
}, [
|
|
298
|
-
|
|
299
|
-
}, [
|
|
300
|
-
|
|
301
|
-
}, [
|
|
307
|
+
let et = S(null), tt = S(null), nt = S(() => {});
|
|
308
|
+
b(() => {
|
|
309
|
+
Y(), M(/* @__PURE__ */ new Map()), N(/* @__PURE__ */ new Set()), p(n.getState().activeConversationId), et.current = Be;
|
|
310
|
+
let e = tt.current;
|
|
311
|
+
tt.current = null, e && e.conversationId === Be && nt.current(e.conversationId, e.messageId);
|
|
312
|
+
}, [Be, Y]), b(() => {
|
|
313
|
+
M((e) => e.size === 0 ? e : /* @__PURE__ */ new Map()), Y();
|
|
314
|
+
}, [K, Y]), b(() => () => {
|
|
315
|
+
z.current?.(), z.current = null, w.cancel();
|
|
316
|
+
}, [w]), b(() => {
|
|
302
317
|
if (typeof window > "u") return;
|
|
303
|
-
let e = () =>
|
|
318
|
+
let e = () => w.cancel();
|
|
304
319
|
return window.addEventListener("pagehide", e), () => window.removeEventListener("pagehide", e);
|
|
305
|
-
}, [
|
|
306
|
-
if (typeof document > "u" || !
|
|
320
|
+
}, [w]), b(() => {
|
|
321
|
+
if (typeof document > "u" || !U) return;
|
|
307
322
|
let e = () => {
|
|
308
323
|
if (document.visibilityState !== "visible") return;
|
|
309
|
-
let e =
|
|
310
|
-
e.length > 0 &&
|
|
324
|
+
let e = w.listVoices();
|
|
325
|
+
e.length > 0 && B(), A(e), Oe(!1), M((e) => e.size === 0 ? e : /* @__PURE__ */ new Map());
|
|
311
326
|
};
|
|
312
327
|
return document.addEventListener("visibilitychange", e), window.addEventListener("focus", e), () => {
|
|
313
328
|
document.removeEventListener("visibilitychange", e), window.removeEventListener("focus", e);
|
|
314
329
|
};
|
|
315
330
|
}, [
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
331
|
+
B,
|
|
332
|
+
w,
|
|
333
|
+
U
|
|
319
334
|
]);
|
|
320
|
-
let
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
}, [
|
|
324
|
-
let Q =
|
|
325
|
-
if (r(e) !== t ||
|
|
335
|
+
let rt = S(Z);
|
|
336
|
+
b(() => {
|
|
337
|
+
rt.current = Z;
|
|
338
|
+
}, [Z]);
|
|
339
|
+
let Q = y((e, t) => {
|
|
340
|
+
if (r(e) !== t || g(e.id) || L.current?.messageId === e.id || Re.current) return;
|
|
326
341
|
let { text: n } = me(e.content);
|
|
327
342
|
if (n.trim()) try {
|
|
328
|
-
|
|
343
|
+
rt.current(e.id, n, e.metadata?.lang, { auto: !0 });
|
|
329
344
|
} catch {}
|
|
330
|
-
}, []), $ =
|
|
331
|
-
if (e !==
|
|
332
|
-
n.getState().activeConversationId === e && (
|
|
345
|
+
}, []), $ = y((e, t) => {
|
|
346
|
+
if (e !== et.current) {
|
|
347
|
+
n.getState().activeConversationId === e && (tt.current = {
|
|
333
348
|
conversationId: e,
|
|
334
349
|
messageId: t
|
|
335
350
|
});
|
|
336
351
|
return;
|
|
337
352
|
}
|
|
338
|
-
let r = Te(
|
|
353
|
+
let r = Te($e.current, t);
|
|
339
354
|
if (!r.autoSpeakEnabled && !r.sessionSpeaking || !r.visible || !r.isSupported) return;
|
|
340
355
|
let i = n.getState();
|
|
341
356
|
if (i.activeConversationId !== e) return;
|
|
342
357
|
let a = i.conversations.find((t) => t.id === e)?.messages.find((e) => e.id === t);
|
|
343
358
|
!a || a.role !== "assistant" || Q(a, r.sessionSpeaking);
|
|
344
359
|
}, [Q]);
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
}, [$]),
|
|
348
|
-
if (!(!
|
|
360
|
+
b(() => {
|
|
361
|
+
nt.current = $;
|
|
362
|
+
}, [$]), b(() => {
|
|
363
|
+
if (!(!V && !H || !h || !U)) return n.subscribe((e, t) => {
|
|
349
364
|
let n = e.activeConversationId;
|
|
350
365
|
if (!n || n !== t.activeConversationId) return;
|
|
351
366
|
let r = e.processingByConversationId[n], i = t.processingByConversationId[n];
|
|
@@ -353,107 +368,109 @@ var T = ({ children: p, visible: g = !0, engine: ge }) => {
|
|
|
353
368
|
let a = r.messageId ?? i?.messageId ?? null;
|
|
354
369
|
if (!a) return;
|
|
355
370
|
let o = e.conversations.find((e) => e.id === n)?.messages.find((e) => e.id === a);
|
|
356
|
-
!o || o.role !== "assistant" || Q(o,
|
|
371
|
+
!o || o.role !== "assistant" || Q(o, H);
|
|
357
372
|
});
|
|
358
373
|
}, [
|
|
359
|
-
z,
|
|
360
|
-
B,
|
|
361
374
|
V,
|
|
362
|
-
|
|
375
|
+
H,
|
|
376
|
+
U,
|
|
377
|
+
h,
|
|
363
378
|
Q
|
|
364
|
-
]),
|
|
365
|
-
if (!(
|
|
379
|
+
]), b(() => {
|
|
380
|
+
if (!(V || H || !He || !h || !U)) return n.subscribe((e, t) => {
|
|
366
381
|
let n = Ee(e, t);
|
|
367
|
-
!n || !
|
|
382
|
+
!n || !re(n.id) || Q(n, !1);
|
|
368
383
|
});
|
|
369
384
|
}, [
|
|
370
|
-
z,
|
|
371
|
-
B,
|
|
372
|
-
Ve,
|
|
373
385
|
V,
|
|
374
|
-
|
|
386
|
+
H,
|
|
387
|
+
He,
|
|
388
|
+
U,
|
|
389
|
+
h,
|
|
375
390
|
Q
|
|
376
391
|
]);
|
|
377
|
-
let
|
|
392
|
+
let it = y((e) => {
|
|
378
393
|
if (e.type === "abort") {
|
|
379
|
-
let t =
|
|
394
|
+
let t = L.current;
|
|
380
395
|
if (!t || t.messageId !== e.messageId) return;
|
|
381
|
-
|
|
396
|
+
L.current = null, (t.requestId === null ? t.waiting && z.current !== null : P.current === t.requestId) && Y();
|
|
382
397
|
return;
|
|
383
398
|
}
|
|
384
|
-
let { messageId: t, item: r } = e, i = Te(
|
|
385
|
-
if (!i.autoSpeakEnabled && !i.sessionSpeaking || !i.visible || !i.isSupported || r.channel === "voice" !== i.sessionSpeaking ||
|
|
399
|
+
let { messageId: t, item: r } = e, i = Te($e.current, t);
|
|
400
|
+
if (!i.autoSpeakEnabled && !i.sessionSpeaking || !i.visible || !i.isSupported || r.channel === "voice" !== i.sessionSpeaking || g(t) || Re.current || L.current?.messageId === t || n.getState().activeConversationId !== r.conversationId || et.current !== r.conversationId) return;
|
|
386
401
|
let { text: a } = me(r.text);
|
|
387
402
|
if (!a.trim()) return;
|
|
388
|
-
let o =
|
|
403
|
+
let o = P.current;
|
|
389
404
|
try {
|
|
390
|
-
|
|
405
|
+
rt.current(t, a, r.lang, {
|
|
391
406
|
auto: !0,
|
|
392
407
|
firstChunkMaxChars: 110
|
|
393
408
|
});
|
|
394
409
|
} catch {}
|
|
395
|
-
let s =
|
|
396
|
-
|
|
410
|
+
let s = P.current !== o;
|
|
411
|
+
L.current = {
|
|
397
412
|
messageId: t,
|
|
398
|
-
requestId: s ?
|
|
399
|
-
waiting: !s &&
|
|
413
|
+
requestId: s ? P.current : null,
|
|
414
|
+
waiting: !s && z.current !== null
|
|
400
415
|
};
|
|
401
|
-
}, [
|
|
402
|
-
|
|
403
|
-
let
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
]),
|
|
409
|
-
isSupported:
|
|
410
|
-
availability:
|
|
411
|
-
isBlocked:
|
|
412
|
-
disabledReason:
|
|
413
|
-
blockedFor:
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
416
|
+
}, [Y]);
|
|
417
|
+
b(() => d.subscribe(it), [it]);
|
|
418
|
+
let at = x(() => l(k, G.tag), [k, G]), ot = x(() => s(k, G.tag, W[K]), [
|
|
419
|
+
k,
|
|
420
|
+
G,
|
|
421
|
+
W,
|
|
422
|
+
K
|
|
423
|
+
]), st = x(() => ({
|
|
424
|
+
isSupported: U,
|
|
425
|
+
availability: J,
|
|
426
|
+
isBlocked: J === "no-voices",
|
|
427
|
+
disabledReason: J === "no-voices" ? T("speech.noVoicesOnDevice", "This device has no speech voices installed. Add one in your device speech or accessibility settings.") : null,
|
|
428
|
+
blockedFor: Ye,
|
|
429
|
+
deviceFallbackFor: Xe,
|
|
430
|
+
voiceChoices: at,
|
|
431
|
+
spokenChunks: de(D, Ne),
|
|
432
|
+
activeVoiceName: ot?.name ?? null,
|
|
433
|
+
preferredVoiceName: W[K] ?? null,
|
|
434
|
+
setVoice: (e) => Ge(K, e),
|
|
435
|
+
speakingMessageId: D.status === "speaking" ? D.messageId : null,
|
|
436
|
+
outputNotCleared: je,
|
|
437
|
+
isSpeaking: (e) => ue(D, e),
|
|
438
|
+
toggle: Qe,
|
|
439
|
+
stop: Y,
|
|
440
|
+
autoSpeakEnabled: V,
|
|
441
|
+
setAutoSpeak: Ie,
|
|
442
|
+
sessionSpeaking: H,
|
|
443
|
+
setSessionSpeaking: Le,
|
|
444
|
+
setSessionMicOpen: ze,
|
|
429
445
|
speakFinishedReply: $,
|
|
430
|
-
previewVoice:
|
|
446
|
+
previewVoice: Je
|
|
431
447
|
}), [
|
|
432
|
-
|
|
448
|
+
U,
|
|
449
|
+
J,
|
|
450
|
+
Ye,
|
|
451
|
+
Xe,
|
|
452
|
+
at,
|
|
453
|
+
ot,
|
|
454
|
+
W,
|
|
455
|
+
Ge,
|
|
433
456
|
K,
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
457
|
+
D,
|
|
458
|
+
je,
|
|
459
|
+
Qe,
|
|
460
|
+
Y,
|
|
461
|
+
V,
|
|
462
|
+
Ie,
|
|
437
463
|
H,
|
|
438
|
-
|
|
439
|
-
W,
|
|
440
|
-
E,
|
|
441
|
-
Ae,
|
|
442
|
-
Xe,
|
|
443
|
-
q,
|
|
444
|
-
z,
|
|
445
|
-
Fe,
|
|
446
|
-
B,
|
|
447
|
-
Re,
|
|
464
|
+
ze,
|
|
448
465
|
$,
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
466
|
+
Je,
|
|
467
|
+
T,
|
|
468
|
+
Ne
|
|
452
469
|
]);
|
|
453
470
|
return /* @__PURE__ */ be(De.Provider, {
|
|
454
|
-
value:
|
|
455
|
-
children:
|
|
471
|
+
value: st,
|
|
472
|
+
children: f
|
|
456
473
|
});
|
|
457
474
|
};
|
|
458
475
|
//#endregion
|
|
459
|
-
export {
|
|
476
|
+
export { E as AssistantSpeechProvider, T as useAssistantSpeech };
|