@burdenoff/fe-libs 2026.907.2 → 2026.908.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.
@@ -83,6 +83,21 @@ export interface AssistantSpeechContextValue {
83
83
  */
84
84
  sessionSpeaking: boolean;
85
85
  setSessionSpeaking: (enabled: boolean) => void;
86
+ /**
87
+ * Is the live session's MICROPHONE open right now?
88
+ *
89
+ * ★ Reported by `useVoiceSession` so the auto-speak subscription below can
90
+ * refuse to play audio into an open microphone. `sessionSpeaking` cannot
91
+ * answer this: it is session-scoped — set once on start and cleared on end —
92
+ * so it stays true for the whole conversation, including the `listening`
93
+ * phases between turns.
94
+ *
95
+ * Write-only by design, and deliberately NOT React state: nothing renders it,
96
+ * and making it state would re-render every speech consumer on each phase
97
+ * change AND re-subscribe the store listener mid-turn, which can drop the
98
+ * in-flight → complete edge the subscription exists to catch.
99
+ */
100
+ setSessionMicOpen: (open: boolean) => void;
86
101
  /** Play a short sample in a named voice. No model call, no message, no tokens. */
87
102
  previewVoice: (voiceName: string) => void;
88
103
  }
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantSpeechProvider.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/ui/AssistantSpeechProvider.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EASL,KAAK,EAAE,EACP,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAKf,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AA2B/D,OAAO,EAQL,KAAK,iBAAiB,EACvB,MAAM,uBAAuB,CAAC;AAiB/B,MAAM,WAAW,2BAA2B;IAC1C,gFAAgF;IAChF,WAAW,EAAE,OAAO,CAAC;IACrB,YAAY,EAAE,iBAAiB,CAAC;IAChC;;;;OAIG;IACH,SAAS,EAAE,OAAO,CAAC;IACnB,6EAA6E;IAC7E,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B;;;;;;OAMG;IACH,UAAU,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IACjD;;;;OAIG;IACH,YAAY,EAAE,SAAS,eAAe,EAAE,CAAC;IACzC,8EAA8E;IAC9E;;;;;;OAMG;IACH,YAAY,EAAE;QAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACzD,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B;;;;;;;;OAQG;IACH,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,mEAAmE;IACnE,QAAQ,EAAE,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAC7C,kDAAkD;IAClD,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,UAAU,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC;IAC3C;;;;;;;OAOG;IACH,MAAM,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3E,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,YAAY,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC;;;;;;;;;;;;;OAaG;IACH,eAAe,EAAE,OAAO,CAAC;IACzB,kBAAkB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC/C,kFAAkF;IAClF,YAAY,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CAC3C;AA2BD,wBAAgB,kBAAkB,IAAI,2BAA2B,CAEhE;AAED,UAAU,KAAK;IACb,QAAQ,EAAE,SAAS,CAAC;IACpB,0DAA0D;IAC1D,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB;AAED,eAAO,MAAM,uBAAuB,EAAE,EAAE,CAAC,KAAK,CA6vB7C,CAAC"}
1
+ {"version":3,"file":"AssistantSpeechProvider.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/ui/AssistantSpeechProvider.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EASL,KAAK,EAAE,EACP,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAKf,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AA2B/D,OAAO,EAQL,KAAK,iBAAiB,EACvB,MAAM,uBAAuB,CAAC;AAiB/B,MAAM,WAAW,2BAA2B;IAC1C,gFAAgF;IAChF,WAAW,EAAE,OAAO,CAAC;IACrB,YAAY,EAAE,iBAAiB,CAAC;IAChC;;;;OAIG;IACH,SAAS,EAAE,OAAO,CAAC;IACnB,6EAA6E;IAC7E,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B;;;;;;OAMG;IACH,UAAU,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IACjD;;;;OAIG;IACH,YAAY,EAAE,SAAS,eAAe,EAAE,CAAC;IACzC,8EAA8E;IAC9E;;;;;;OAMG;IACH,YAAY,EAAE;QAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACzD,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B;;;;;;;;OAQG;IACH,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,mEAAmE;IACnE,QAAQ,EAAE,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAC7C,kDAAkD;IAClD,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,UAAU,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC;IAC3C;;;;;;;OAOG;IACH,MAAM,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3E,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,YAAY,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC;;;;;;;;;;;;;OAaG;IACH,eAAe,EAAE,OAAO,CAAC;IACzB,kBAAkB,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IAC/C;;;;;;;;;;;;;OAaG;IACH,iBAAiB,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAC3C,kFAAkF;IAClF,YAAY,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CAC3C;AA4BD,wBAAgB,kBAAkB,IAAI,2BAA2B,CAEhE;AAED,UAAU,KAAK;IACb,QAAQ,EAAE,SAAS,CAAC;IACpB,0DAA0D;IAC1D,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB;AAED,eAAO,MAAM,uBAAuB,EAAE,EAAE,CAAC,KAAK,CAwyB7C,CAAC"}
@@ -9,15 +9,15 @@ import { resolveLanguagePair as te } from "../voice/languagePair.js";
9
9
  import { useAssistantTr as ne } from "../i18n.js";
10
10
  import { speechLabelsFor as re } from "../voice/speechLabels.js";
11
11
  import { resolveSpeechLocale as ie } from "../voice/replyLanguage.js";
12
- import { IDLE_PLAYBACK as ae, isSpeakingMessage as p, speechPlaybackReducer as oe } from "../voice/speechPlayback.js";
13
- import { useAssistantStore as m } from "../store.js";
14
- import { isTurnInFlight as se } from "../turnState.js";
15
- import { parseToolActivity as ce } from "./AssistantToolActivity.js";
12
+ import { IDLE_PLAYBACK as ae, isSpeakingMessage as oe, speechPlaybackReducer as se } from "../voice/speechPlayback.js";
13
+ import { useAssistantStore as p } from "../store.js";
14
+ import { isTurnInFlight as ce } from "../turnState.js";
15
+ import { parseToolActivity as le } from "./AssistantToolActivity.js";
16
16
  import "../speech/index.js";
17
- import { createContext as h, useCallback as g, useContext as _, useEffect as v, useMemo as y, useReducer as le, useRef as b, useState as x } from "react";
18
- import { jsx as ue } from "react/jsx-runtime";
17
+ import { createContext as ue, useCallback as m, useContext as h, useEffect as g, useMemo as _, useReducer as de, useRef as v, useState as y } from "react";
18
+ import { jsx as fe } from "react/jsx-runtime";
19
19
  //#region src/shared/assistant/ui/AssistantSpeechProvider.tsx
20
- var de = {
20
+ var pe = {
21
21
  codeBlock: "",
22
22
  image: "",
23
23
  link: "",
@@ -26,7 +26,7 @@ var de = {
26
26
  emailAt: "at",
27
27
  emailDot: "dot",
28
28
  nestedItem: ""
29
- }, fe = 4e3, S = h({
29
+ }, me = 4e3, b = ue({
30
30
  isSupported: !1,
31
31
  availability: "unsupported",
32
32
  isBlocked: !0,
@@ -45,263 +45,268 @@ var de = {
45
45
  setAutoSpeak: () => {},
46
46
  sessionSpeaking: !1,
47
47
  setSessionSpeaking: () => {},
48
+ setSessionMicOpen: () => {},
48
49
  previewVoice: () => {}
49
50
  });
50
- function C() {
51
- return _(S);
51
+ function x() {
52
+ return h(b);
52
53
  }
53
- var w = ({ children: h, visible: _ = !0, engine: C = n() }) => {
54
- let w = ne(), { locale: T } = e(), [E, D] = le(oe, ae), [O, k] = x(() => C.listVoices()), [A, j] = x(!1), [M, N] = x(() => /* @__PURE__ */ new Map()), P = b(0), F = b(null);
55
- v(() => () => {
56
- F.current !== null && clearTimeout(F.current);
54
+ var S = ({ children: ue, visible: h = !0, engine: x = n() }) => {
55
+ let S = ne(), { locale: C } = e(), [w, T] = de(se, ae), [E, D] = y(() => x.listVoices()), [O, k] = y(!1), [A, j] = y(() => /* @__PURE__ */ new Map()), M = v(0), N = v(null);
56
+ g(() => () => {
57
+ N.current !== null && clearTimeout(N.current);
57
58
  }, []);
58
- let [I, L] = x(null), R = b(null), z = b(() => {}), B = g(() => {
59
- R.current?.(), R.current = null;
60
- }, []), V = m((e) => e.autoSpeakEnabled), H = m((e) => e.setAutoSpeak), [U, pe] = x(!1), me = m((e) => e.activeConversationId), W = y(() => C.isSupported(), [C]);
61
- v(() => {
62
- if (!W) return;
59
+ let [P, F] = y(null), I = v(null), he = v(() => {}), L = m(() => {
60
+ I.current?.(), I.current = null;
61
+ }, []), R = p((e) => e.autoSpeakEnabled), z = p((e) => e.setAutoSpeak), [B, ge] = y(!1), V = v(!1), H = m((e) => {
62
+ V.current = e;
63
+ }, []), _e = p((e) => e.activeConversationId), U = _(() => x.isSupported(), [x]);
64
+ g(() => {
65
+ if (!U) return;
63
66
  let e = () => {
64
- k(C.listVoices()), N((e) => e.size === 0 ? e : /* @__PURE__ */ new Map());
67
+ D(x.listVoices()), j((e) => e.size === 0 ? e : /* @__PURE__ */ new Map());
65
68
  };
66
- return e(), C.subscribeVoices(e);
67
- }, [C, W]);
68
- let he = m((e) => e.assistantLanguage), ge = m((e) => e.replyLanguage), G = m((e) => e.preferredVoices), _e = m((e) => e.setPreferredVoice), K = y(() => te(he, ge, T).reply, [
69
- he,
70
- ge,
71
- T
72
- ]), q = K.code, J = g((e) => f(e)?.tag ?? s(e), []), ve = g((e) => f(e)?.rate ?? .9, []), Y = y(() => c(W, O, K.tag, A), [
69
+ return e(), x.subscribeVoices(e);
70
+ }, [x, U]);
71
+ let W = p((e) => e.assistantLanguage), ve = p((e) => e.replyLanguage), G = p((e) => e.preferredVoices), ye = p((e) => e.setPreferredVoice), K = _(() => te(W, ve, C).reply, [
73
72
  W,
74
- O,
73
+ ve,
74
+ C
75
+ ]), q = K.code, J = m((e) => f(e)?.tag ?? s(e), []), be = m((e) => f(e)?.rate ?? .9, []), Y = _(() => c(U, E, K.tag, O), [
76
+ U,
77
+ E,
75
78
  K,
76
- A
77
- ]), ye = y(() => ({
78
- codeBlock: w("speech.codeBlock", "Code block"),
79
- image: w("speech.image", "image"),
80
- link: w("speech.link", "link"),
81
- largeTable: w("speech.largeTable", "Table with {{rows}} rows and {{columns}} columns"),
82
- truncated: w("speech.truncated", "The rest of this message is not read aloud"),
83
- nestedItem: w("speech.nestedItem", "Sub-item {{ordinal}}"),
84
- emailAt: w("speech.emailAt", "at"),
85
- emailDot: w("speech.emailDot", "dot")
86
- }), [w]), X = g(() => {
87
- B(), C.cancel(), D({ type: "stop" });
88
- }, [B, C]), be = g((e) => {
89
- let t = C.listVoices().find((t) => t.name === e) ?? null;
90
- t && (X(), C.speak([d(q)], {
79
+ O
80
+ ]), xe = _(() => ({
81
+ codeBlock: S("speech.codeBlock", "Code block"),
82
+ image: S("speech.image", "image"),
83
+ link: S("speech.link", "link"),
84
+ largeTable: S("speech.largeTable", "Table with {{rows}} rows and {{columns}} columns"),
85
+ truncated: S("speech.truncated", "The rest of this message is not read aloud"),
86
+ nestedItem: S("speech.nestedItem", "Sub-item {{ordinal}}"),
87
+ emailAt: S("speech.emailAt", "at"),
88
+ emailDot: S("speech.emailDot", "dot")
89
+ }), [S]), X = m(() => {
90
+ L(), x.cancel(), T({ type: "stop" });
91
+ }, [L, x]), Se = m((e) => {
92
+ let t = x.listVoices().find((t) => t.name === e) ?? null;
93
+ t && (X(), x.speak([d(q)], {
91
94
  voice: t,
92
95
  lang: J(q)
93
96
  }));
94
97
  }, [
95
- C,
98
+ x,
96
99
  q,
97
100
  X,
98
101
  J
99
- ]), xe = g((e) => M.get(e) ?? null, [M]), Se = g((e, t, n) => {
100
- B();
102
+ ]), Z = m((e) => A.get(e) ?? null, [A]), Ce = m((e, t, n) => {
103
+ L();
101
104
  let i = !1, a = () => {}, o = (r) => {
102
105
  if (!i) {
103
- if (i = !0, R.current = null, clearTimeout(s), a(), r.length === 0) {
104
- j(!0);
106
+ if (i = !0, I.current = null, clearTimeout(s), a(), r.length === 0) {
107
+ k(!0);
105
108
  return;
106
109
  }
107
- k(r), z.current(e, t, r, n);
110
+ D(r), he.current(e, t, r, n);
108
111
  }
109
- }, s = setTimeout(() => o(C.listVoices()), r);
110
- a = C.subscribeVoices(() => o(C.listVoices())), R.current = () => {
111
- i || (i = !0, clearTimeout(s), a(), R.current = null);
112
+ }, s = setTimeout(() => o(x.listVoices()), r);
113
+ a = x.subscribeVoices(() => o(x.listVoices())), I.current = () => {
114
+ i || (i = !0, clearTimeout(s), a(), I.current = null);
112
115
  };
113
- }, [B, C]), Z = g((e, t, n, r) => {
116
+ }, [L, x]), Q = m((e, t, n, r) => {
114
117
  let s = n;
115
118
  if (s.length === 0) {
116
- let e = C.listVoices();
117
- e.length > 0 && (s = e, k(e));
119
+ let e = x.listVoices();
120
+ e.length > 0 && (s = e, D(e));
118
121
  }
119
- let l = J(r), u = o(c(!0, s, r, A));
122
+ let l = J(r), u = o(c(!0, s, r, O));
120
123
  if (u === "block") {
121
- let t = w("speech.noVoiceForReply", "This reply is in {{language}}, and no {{language}} voice is installed on this device.", { language: i(l, T) });
122
- N((n) => new Map(n).set(e, t));
124
+ let t = S("speech.noVoiceForReply", "This reply is in {{language}}, and no {{language}} voice is installed on this device.", { language: i(l, C) });
125
+ j((n) => new Map(n).set(e, t));
123
126
  return;
124
127
  }
125
128
  if (u === "wait-for-voices") {
126
- Se(e, t, r);
129
+ Ce(e, t, r);
127
130
  return;
128
131
  }
129
- N((t) => {
132
+ j((t) => {
130
133
  if (!t.has(e)) return t;
131
134
  let n = new Map(t);
132
135
  return n.delete(e), n;
133
136
  });
134
- let d = P.current + 1;
135
- P.current = d, D({
137
+ let d = M.current + 1;
138
+ M.current = d, T({
136
139
  type: "start",
137
140
  messageId: e,
138
141
  requestId: d
139
142
  });
140
143
  let f = ee(t);
141
- L({
144
+ F({
142
145
  requestId: d,
143
146
  chunks: f,
144
147
  index: -1
145
- }), F.current !== null && clearTimeout(F.current), F.current = setTimeout(() => {
146
- L((e) => e?.requestId === d && e.index < 0 ? null : e);
147
- }, fe), C.speak(f, {
148
+ }), N.current !== null && clearTimeout(N.current), N.current = setTimeout(() => {
149
+ F((e) => e?.requestId === d && e.index < 0 ? null : e);
150
+ }, me), x.speak(f, {
148
151
  voice: a(s, l, G[r]),
149
152
  lang: l,
150
- rate: ve(r)
153
+ rate: be(r)
151
154
  }, {
152
155
  onChunkStart: (e) => {
153
- P.current === d && F.current !== null && (clearTimeout(F.current), F.current = null), L((t) => t?.requestId === d ? {
156
+ M.current === d && N.current !== null && (clearTimeout(N.current), N.current = null), F((t) => t?.requestId === d ? {
154
157
  ...t,
155
158
  index: e
156
- } : P.current === d ? {
159
+ } : M.current === d ? {
157
160
  requestId: d,
158
161
  chunks: f,
159
162
  index: e
160
163
  } : t);
161
164
  },
162
- onEnd: () => D({
165
+ onEnd: () => T({
163
166
  type: "finished",
164
167
  requestId: d
165
168
  }),
166
- onError: () => D({
169
+ onError: () => T({
167
170
  type: "failed",
168
171
  requestId: d
169
172
  })
170
173
  });
171
174
  }, [
175
+ x,
172
176
  C,
173
- T,
174
177
  G,
175
- ve,
178
+ be,
176
179
  J,
177
- w,
178
- A,
179
- Se
180
+ S,
181
+ O,
182
+ Ce
180
183
  ]);
181
- v(() => {
182
- z.current = Z;
183
- }, [Z]);
184
- let Q = g((e, t, n) => {
185
- if (!W) return;
186
- let r = ie(u(t, { labels: de }), n ?? q), i = u(t, { labels: re(r, ye) });
187
- i && Z(e, i, O, r);
184
+ g(() => {
185
+ he.current = Q;
186
+ }, [Q]);
187
+ let $ = m((e, t, n) => {
188
+ if (!U) return;
189
+ let r = ie(u(t, { labels: pe }), n ?? q), i = u(t, { labels: re(r, xe) });
190
+ i && Q(e, i, E, r);
188
191
  }, [
189
- W,
190
- ye,
192
+ U,
193
+ xe,
191
194
  q,
192
- Z,
193
- O
194
- ]), Ce = g((e, t, n) => {
195
- if (p(E, e)) {
195
+ Q,
196
+ E
197
+ ]), we = m((e, t, n) => {
198
+ if (oe(w, e)) {
196
199
  X();
197
200
  return;
198
201
  }
199
- Q(e, t, n);
202
+ $(e, t, n);
200
203
  }, [
201
- E,
202
- Q,
204
+ w,
205
+ $,
203
206
  X
204
207
  ]);
205
- v(() => {
206
- _ || X();
207
- }, [_, X]), v(() => {
208
- X(), N(/* @__PURE__ */ new Map());
209
- }, [me, X]), v(() => {
210
- N((e) => e.size === 0 ? e : /* @__PURE__ */ new Map()), X();
211
- }, [q, X]), v(() => () => {
212
- R.current?.(), R.current = null, C.cancel();
213
- }, [C]), v(() => {
208
+ g(() => {
209
+ h || X();
210
+ }, [h, X]), g(() => {
211
+ X(), j(/* @__PURE__ */ new Map());
212
+ }, [_e, X]), g(() => {
213
+ j((e) => e.size === 0 ? e : /* @__PURE__ */ new Map()), X();
214
+ }, [q, X]), g(() => () => {
215
+ I.current?.(), I.current = null, x.cancel();
216
+ }, [x]), g(() => {
214
217
  if (typeof window > "u") return;
215
- let e = () => C.cancel();
218
+ let e = () => x.cancel();
216
219
  return window.addEventListener("pagehide", e), () => window.removeEventListener("pagehide", e);
217
- }, [C]), v(() => {
218
- if (typeof document > "u" || !W) return;
220
+ }, [x]), g(() => {
221
+ if (typeof document > "u" || !U) return;
219
222
  let e = () => {
220
223
  if (document.visibilityState !== "visible") return;
221
- let e = C.listVoices();
222
- e.length > 0 && B(), k(e), j(!1), N((e) => e.size === 0 ? e : /* @__PURE__ */ new Map());
224
+ let e = x.listVoices();
225
+ e.length > 0 && L(), D(e), k(!1), j((e) => e.size === 0 ? e : /* @__PURE__ */ new Map());
223
226
  };
224
227
  return document.addEventListener("visibilitychange", e), window.addEventListener("focus", e), () => {
225
228
  document.removeEventListener("visibilitychange", e), window.removeEventListener("focus", e);
226
229
  };
227
230
  }, [
228
- B,
229
- C,
230
- W
231
+ L,
232
+ x,
233
+ U
231
234
  ]);
232
- let we = b(Q);
233
- v(() => {
234
- we.current = Q;
235
- }, [Q]), v(() => {
236
- if (!(!V && !U || !_ || !W)) return m.subscribe((e, n) => {
235
+ let Te = v($);
236
+ g(() => {
237
+ Te.current = $;
238
+ }, [$]), g(() => {
239
+ if (!(!R && !B || !h || !U)) return p.subscribe((e, n) => {
237
240
  let r = e.activeConversationId;
238
241
  if (!r || r !== n.activeConversationId) return;
239
242
  let i = e.processingByConversationId[r], a = n.processingByConversationId[r];
240
- if (i?.status !== "complete" || !se(a?.status)) return;
243
+ if (i?.status !== "complete" || !ce(a?.status)) return;
241
244
  let o = i.messageId ?? a?.messageId ?? null;
242
245
  if (!o) return;
243
246
  let s = e.conversations.find((e) => e.id === r)?.messages.find((e) => e.id === o);
244
- if (!s || s.role !== "assistant" || t(s) !== U) return;
245
- let { text: c } = ce(s.content);
246
- c.trim() && we.current(o, c, s.metadata?.lang);
247
+ if (!s || s.role !== "assistant" || t(s) !== B || V.current) return;
248
+ let { text: c } = le(s.content);
249
+ c.trim() && Te.current(o, c, s.metadata?.lang);
247
250
  });
248
251
  }, [
249
- V,
252
+ R,
253
+ B,
250
254
  U,
251
- W,
252
- _
255
+ h
253
256
  ]);
254
- let Te = y(() => l(O, K.tag), [O, K]), $ = y(() => a(O, K.tag, G[q]), [
255
- O,
257
+ let Ee = _(() => l(E, K.tag), [E, K]), De = _(() => a(E, K.tag, G[q]), [
258
+ E,
256
259
  K,
257
260
  G,
258
261
  q
259
- ]), Ee = y(() => ({
260
- isSupported: W,
262
+ ]), Oe = _(() => ({
263
+ isSupported: U,
261
264
  availability: Y,
262
265
  isBlocked: Y === "no-voices",
263
- disabledReason: Y === "no-voices" ? w("speech.noVoicesOnDevice", "This device has no speech voices installed. Add one in your device speech or accessibility settings.") : null,
264
- blockedFor: xe,
265
- voiceChoices: Te,
266
- spokenChunks: I ? {
267
- chunks: I.chunks,
268
- index: I.index
266
+ disabledReason: Y === "no-voices" ? S("speech.noVoicesOnDevice", "This device has no speech voices installed. Add one in your device speech or accessibility settings.") : null,
267
+ blockedFor: Z,
268
+ voiceChoices: Ee,
269
+ spokenChunks: P ? {
270
+ chunks: P.chunks,
271
+ index: P.index
269
272
  } : null,
270
- activeVoiceName: $?.name ?? null,
273
+ activeVoiceName: De?.name ?? null,
271
274
  preferredVoiceName: G[q] ?? null,
272
- setVoice: (e) => _e(q, e),
273
- speakingMessageId: E.status === "speaking" ? E.messageId : null,
274
- isSpeaking: (e) => p(E, e),
275
- toggle: Ce,
275
+ setVoice: (e) => ye(q, e),
276
+ speakingMessageId: w.status === "speaking" ? w.messageId : null,
277
+ isSpeaking: (e) => oe(w, e),
278
+ toggle: we,
276
279
  stop: X,
277
- autoSpeakEnabled: V,
278
- setAutoSpeak: H,
279
- sessionSpeaking: U,
280
- setSessionSpeaking: pe,
281
- previewVoice: be
280
+ autoSpeakEnabled: R,
281
+ setAutoSpeak: z,
282
+ sessionSpeaking: B,
283
+ setSessionSpeaking: ge,
284
+ setSessionMicOpen: H,
285
+ previewVoice: Se
282
286
  }), [
283
- W,
287
+ U,
284
288
  Y,
285
- xe,
286
- Te,
287
- $,
289
+ Z,
290
+ Ee,
291
+ De,
288
292
  G,
289
- _e,
293
+ ye,
290
294
  q,
291
- E,
292
- Ce,
295
+ w,
296
+ we,
293
297
  X,
294
- V,
298
+ R,
299
+ z,
300
+ B,
295
301
  H,
296
- U,
297
- be,
298
- w,
299
- I
302
+ Se,
303
+ S,
304
+ P
300
305
  ]);
301
- return /* @__PURE__ */ ue(S.Provider, {
302
- value: Ee,
303
- children: h
306
+ return /* @__PURE__ */ fe(b.Provider, {
307
+ value: Oe,
308
+ children: ue
304
309
  });
305
310
  };
306
311
  //#endregion
307
- export { w as AssistantSpeechProvider, C as useAssistantSpeech };
312
+ export { S as AssistantSpeechProvider, x as useAssistantSpeech };
@@ -1 +1 @@
1
- {"version":3,"file":"useVoiceSession.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/ui/useVoiceSession.ts"],"names":[],"mappings":"AAUA,OAAO,EAWL,KAAK,oBAAoB,EAE1B,MAAM,uBAAuB,CAAC;AAsC/B;;;;;;;;GAQG;AACH,MAAM,MAAM,kBAAkB,GAC1B,SAAS,GACT,eAAe,GACf,eAAe,GACf,oBAAoB,CAAC;AAMzB,UAAU,OAAO;IACf,+EAA+E;IAC/E;;;;;;;OAOG;IACH,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,KAAK,IAAI,CAAC;IACzD;;;;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;CAClB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,EAAE,OAAO;;IAqftE,qEAAqE;;IAErE;;;;;;;OAOG;;;;;IAEH,+DAA+D;;IAE/D;;;;;;;OAOG;;IAIH,0EAA0E;;IAE1E,6DAA6D;;IAE7D,sDAAsD;;;;;;EA4B3D"}
1
+ {"version":3,"file":"useVoiceSession.d.ts","sourceRoot":"","sources":["../../../../src/shared/assistant/ui/useVoiceSession.ts"],"names":[],"mappings":"AAUA,OAAO,EAWL,KAAK,oBAAoB,EAE1B,MAAM,uBAAuB,CAAC;AAsC/B;;;;;;;;GAQG;AACH,MAAM,MAAM,kBAAkB,GAC1B,SAAS,GACT,eAAe,GACf,eAAe,GACf,oBAAoB,CAAC;AAMzB,UAAU,OAAO;IACf,+EAA+E;IAC/E;;;;;;;OAOG;IACH,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,KAAK,IAAI,CAAC;IACzD;;;;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;CAClB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,EAAE,OAAO;;IAuiBtE,qEAAqE;;IAErE;;;;;;;OAOG;;;;;IAEH,+DAA+D;;IAE/D;;;;;;;OAOG;;IAIH,0EAA0E;;IAE1E,6DAA6D;;IAE7D,sDAAsD;;;;;;EA4B3D"}
@@ -5,10 +5,10 @@ import { useCallback as u, useEffect as d, useMemo as f, useReducer as p, useRef
5
5
  //#region src/shared/assistant/ui/useVoiceSession.ts
6
6
  var g = 4e3, _ = 2500, v = 5e3, y = 12e3, b = "data:audio/wav;base64,UklGRiQAAABXQVZFZm10IBAAAAABAAEARKwAAIhYAQACABAAZGF0YQAAAAA=";
7
7
  function x({ onSubmit: x, latestReply: S, language: C }) {
8
- let w = m(null), [T, E] = p(u((e, t) => c(e, t, w.current), []), t), D = l(), { setSessionSpeaking: O, speakingMessageId: k, stop: A } = D, j = m(null), M = m(null), N = m(!1), [P, F] = h(null), [I, L] = h(!1), [R, z] = h(!1), B = m(T);
9
- B.current = T;
10
- let V = m(S);
11
- V.current = S, d(() => {
8
+ let w = m(null), [T, E] = p(u((e, t) => c(e, t, w.current), []), t), D = l(), { setSessionSpeaking: O, setSessionMicOpen: k, speakingMessageId: A, stop: j } = D, M = m(null), N = m(null), P = m(!1), [F, I] = h(null), [L, R] = h(!1), [z, B] = h(!1), V = m(T);
9
+ V.current = T;
10
+ let H = m(S);
11
+ H.current = S, d(() => {
12
12
  if (T.phase === "speaking") {
13
13
  w.current = S?.text ?? null;
14
14
  return;
@@ -19,78 +19,83 @@ function x({ onSubmit: x, latestReply: S, language: C }) {
19
19
  }, _);
20
20
  return () => clearTimeout(e);
21
21
  }, [T.phase, S]);
22
- let H = u((e, t) => {
22
+ let U = u((e, t) => {
23
23
  E({
24
24
  type: "speech",
25
25
  transcript: e,
26
26
  final: t
27
27
  });
28
- }, []), U = m(0), W = u(() => {
29
- A(), U.current = Date.now(), L(!0), E({ type: "interrupt" });
30
- }, [A]), G = e({
31
- onFinalize: u((e) => H(e, !0), [H]),
28
+ }, []), W = m(0), G = u(() => {
29
+ j(), W.current = Date.now(), R(!0), E({ type: "interrupt" });
30
+ }, [j]), K = e({
31
+ onFinalize: u((e) => U(e, !0), [U]),
32
32
  language: C
33
33
  });
34
34
  d(() => {
35
- G.interim && H(G.interim, !1);
36
- }, [G.interim, H]), d(() => {
37
- if (j.current && clearTimeout(j.current), z(!1), T.phase !== "listening" || T.muted || !a(s(T))) return;
38
- let e = setTimeout(() => z(!0), 800);
39
- return j.current = setTimeout(() => E({ type: "silence" }), r), () => {
40
- clearTimeout(e), j.current && clearTimeout(j.current);
35
+ K.interim && U(K.interim, !1);
36
+ }, [K.interim, U]), d(() => {
37
+ if (M.current && clearTimeout(M.current), B(!1), T.phase !== "listening" || T.muted || !a(s(T))) return;
38
+ let e = setTimeout(() => B(!0), 800);
39
+ return M.current = setTimeout(() => E({ type: "silence" }), r), () => {
40
+ clearTimeout(e), M.current && clearTimeout(M.current);
41
41
  };
42
42
  }, [T]), d(() => {
43
- if (!I) return;
44
- let e = Date.now() - U.current, t = G.isListening ? Math.max(0, 500 - e) : Math.max(0, n - e), r = setTimeout(() => L(!1), t);
43
+ if (!L) return;
44
+ let e = Date.now() - W.current, t = K.isListening ? Math.max(0, 500 - e) : Math.max(0, n - e), r = setTimeout(() => R(!1), t);
45
45
  return () => clearTimeout(r);
46
- }, [I, G.isListening]);
47
- let K = m("");
48
- T.phase === "listening" && (K.current = s(T)), d(() => {
46
+ }, [L, K.isListening]);
47
+ let q = m("");
48
+ T.phase === "listening" && (q.current = s(T)), d(() => {
49
49
  if (T.phase !== "thinking") return;
50
- let e = K.current.trim();
51
- e && x(e, q.current ?? `vs-orphan-${Date.now().toString(36)}`);
50
+ let e = q.current.trim();
51
+ e && x(e, J.current ?? `vs-orphan-${Date.now().toString(36)}`);
52
52
  }, [T.phase]), d(() => {
53
- let e = o(S?.id, T.phase, M.current);
54
- e.claim && (M.current = S?.id ?? null, e.advance && S && E({
53
+ let e = o(S?.id, T.phase, N.current);
54
+ e.claim && (N.current = S?.id ?? null, e.advance && S && E({
55
55
  type: "reply",
56
56
  text: S.text
57
57
  }));
58
58
  }, [S, T.phase]), d(() => {
59
- let e = k !== null;
60
- N.current && !e && E({ type: "speech-ended" }), N.current = e;
61
- }, [k]), d(() => {
62
- T.phase !== "listening" && F((e) => e === "nothing-heard" ? null : e);
59
+ let e = A !== null;
60
+ P.current && !e && E({ type: "speech-ended" }), P.current = e;
61
+ }, [A]), d(() => {
62
+ T.phase !== "listening" && I((e) => e === "nothing-heard" ? null : e);
63
63
  }, [T.phase]), d(() => {
64
- if (T.phase !== "speaking" || k !== null) return;
64
+ if (T.phase !== "speaking" || A !== null) return;
65
65
  let e = setTimeout(() => {
66
- N.current || E({ type: "speech-ended" });
66
+ P.current || E({ type: "speech-ended" });
67
67
  }, g);
68
68
  return () => clearTimeout(e);
69
- }, [T.phase, k]), d(() => {
70
- i(T) ? G.isListening || G.start() : G.isListening && G.stop();
71
- }, [T, G]), d(() => {
72
- G.error === "not-allowed" || G.error === "audio-capture" ? E({
69
+ }, [T.phase, A]), d(() => {
70
+ let e = i(T);
71
+ k(e), e ? K.isActive || K.start() : K.isActive && K.stop();
72
+ }, [
73
+ T,
74
+ K,
75
+ k
76
+ ]), d(() => {
77
+ K.error === "not-allowed" || K.error === "audio-capture" ? E({
73
78
  type: "fail",
74
79
  error: "mic-denied"
75
- }) : G.error === "language-not-supported" ? E({
80
+ }) : K.error === "language-not-supported" ? E({
76
81
  type: "fail",
77
82
  error: "no-speech-support"
78
- }) : G.error === "network" ? F("network") : G.error === "unknown" && F("recognition-failed");
79
- }, [G.error]), d(() => {
80
- G.error !== null || !G.isListening || F((e) => e === "network" || e === "recognition-failed" ? null : e);
81
- }, [G.error, G.isListening]), d(() => {
82
- if (G.isListening && F((e) => e === "not-capturing" ? null : e), !i(T) || G.isListening) return;
83
- let e = setTimeout(() => F("not-capturing"), v);
83
+ }) : K.error === "network" ? I("network") : K.error === "unknown" && I("recognition-failed");
84
+ }, [K.error]), d(() => {
85
+ K.error !== null || !K.isListening || I((e) => e === "network" || e === "recognition-failed" ? null : e);
86
+ }, [K.error, K.isListening]), d(() => {
87
+ if (K.isListening && I((e) => e === "not-capturing" ? null : e), !i(T) || K.isListening) return;
88
+ let e = setTimeout(() => I("not-capturing"), v);
84
89
  return () => clearTimeout(e);
85
- }, [T, G.isListening]), d(() => {
86
- if (T.phase !== "listening" || T.muted || !G.isListening || s(T) !== "") return;
87
- let e = setTimeout(() => F("nothing-heard"), y);
90
+ }, [T, K.isListening]), d(() => {
91
+ if (T.phase !== "listening" || T.muted || !K.isListening || s(T) !== "") return;
92
+ let e = setTimeout(() => I("nothing-heard"), y);
88
93
  return () => clearTimeout(e);
89
- }, [T, G.isListening]), d(() => {
90
- s(T) !== "" && F(null);
94
+ }, [T, K.isListening]), d(() => {
95
+ s(T) !== "" && I(null);
91
96
  }, [T]);
92
- let q = m(null), J = u(() => {
93
- if (L(!1), z(!1), !G.isSupported) {
97
+ let J = m(null), Y = u(() => {
98
+ if (R(!1), B(!1), !K.isSupported) {
94
99
  E({
95
100
  type: "fail",
96
101
  error: "no-speech-support"
@@ -117,47 +122,47 @@ function x({ onSubmit: x, latestReply: S, language: C }) {
117
122
  e.volume = 0, e.play().catch(() => {});
118
123
  }
119
124
  } catch {}
120
- O(!0), F(null), M.current = V.current?.id ?? null, q.current = `vs-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`, E({ type: "start" });
125
+ O(!0), I(null), N.current = H.current?.id ?? null, J.current = `vs-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`, E({ type: "start" });
121
126
  }, [
122
- G.isSupported,
127
+ K.isSupported,
123
128
  D.isBlocked,
124
129
  O
125
- ]), Y = u(() => {
126
- L(!1), z(!1), q.current = null, E({ type: "end" }), A(), O(!1);
127
- }, [A, O]), X = u(() => {
130
+ ]), X = u(() => {
131
+ R(!1), B(!1), J.current = null, E({ type: "end" }), j(), O(!1);
132
+ }, [j, O]), Z = u(() => {
128
133
  E({
129
134
  type: "mute",
130
- muted: !B.current.muted
135
+ muted: !V.current.muted
131
136
  });
132
137
  }, []);
133
138
  return d(() => () => {
134
- O(!1);
135
- }, [O]), f(() => ({
139
+ O(!1), k(!1);
140
+ }, [O, k]), f(() => ({
136
141
  session: T,
137
- notice: P,
142
+ notice: F,
138
143
  spokenChunks: D.spokenChunks,
139
- capturing: G.isListening,
144
+ capturing: K.isListening,
140
145
  active: T.phase !== "idle" && (T.phase !== "ended" || T.error !== null),
141
- interrupting: I,
142
- awaitingEndpoint: R,
143
- available: G.isSupported && !D.isBlocked,
144
- start: J,
145
- end: Y,
146
- toggleMute: X,
147
- interrupt: W
146
+ interrupting: L,
147
+ awaitingEndpoint: z,
148
+ available: K.isSupported && !D.isBlocked,
149
+ start: Y,
150
+ end: X,
151
+ toggleMute: Z,
152
+ interrupt: G
148
153
  }), [
149
154
  T,
150
- P,
151
- I,
152
- R,
153
- G.isListening,
154
- G.isSupported,
155
+ F,
156
+ L,
157
+ z,
158
+ K.isListening,
159
+ K.isSupported,
155
160
  D.isBlocked,
156
161
  D.spokenChunks,
157
- J,
158
162
  Y,
159
163
  X,
160
- W
164
+ Z,
165
+ G
161
166
  ]);
162
167
  }
163
168
  //#endregion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burdenoff/fe-libs",
3
- "version": "2026.907.2",
3
+ "version": "2026.908.1",
4
4
  "description": "Burdenoff frontend primitives and domain libraries",
5
5
  "type": "module",
6
6
  "bin": {