@burdenoff/fe-libs 2026.1016.3 → 2026.1017.2

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