@burdenoff/fe-libs 2026.1002.2 → 2026.1003.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 (52) hide show
  1. package/dist/shared/assistant/index.d.ts +1 -0
  2. package/dist/shared/assistant/index.d.ts.map +1 -1
  3. package/dist/shared/assistant/prewarm.d.ts +71 -0
  4. package/dist/shared/assistant/prewarm.d.ts.map +1 -1
  5. package/dist/shared/assistant/prewarm.js +49 -2
  6. package/dist/shared/assistant/speech/speechFeed.d.ts +63 -0
  7. package/dist/shared/assistant/speech/speechFeed.d.ts.map +1 -0
  8. package/dist/shared/assistant/speech/speechFeed.js +40 -0
  9. package/dist/shared/assistant/turnTimeline.d.ts +22 -2
  10. package/dist/shared/assistant/turnTimeline.d.ts.map +1 -1
  11. package/dist/shared/assistant/turnTimeline.js +18 -1
  12. package/dist/shared/assistant/turnTimingReport.d.ts.map +1 -1
  13. package/dist/shared/assistant/turnTimingReport.js +5 -4
  14. package/dist/shared/assistant/ui/AssistantAvatar.d.ts +0 -21
  15. package/dist/shared/assistant/ui/AssistantAvatar.d.ts.map +1 -1
  16. package/dist/shared/assistant/ui/AssistantAvatar.js +13 -7
  17. package/dist/shared/assistant/ui/AssistantChatArea.d.ts.map +1 -1
  18. package/dist/shared/assistant/ui/AssistantChatArea.js +981 -931
  19. package/dist/shared/assistant/ui/AssistantMessageItem.d.ts +8 -0
  20. package/dist/shared/assistant/ui/AssistantMessageItem.d.ts.map +1 -1
  21. package/dist/shared/assistant/ui/AssistantMessageItem.js +60 -58
  22. package/dist/shared/assistant/ui/AssistantSpeechProvider.d.ts.map +1 -1
  23. package/dist/shared/assistant/ui/AssistantSpeechProvider.js +198 -169
  24. package/dist/shared/assistant/ui/composer/AssistantComposer.js +117 -117
  25. package/dist/shared/assistant/ui/composer/AssistantVoiceButton.d.ts +8 -0
  26. package/dist/shared/assistant/ui/composer/AssistantVoiceButton.d.ts.map +1 -1
  27. package/dist/shared/assistant/ui/composer/AssistantVoiceButton.js +21 -16
  28. package/dist/shared/assistant/ui/useVoiceSession.d.ts +1 -4
  29. package/dist/shared/assistant/ui/useVoiceSession.d.ts.map +1 -1
  30. package/dist/shared/assistant/ui/useVoiceSession.js +171 -156
  31. package/dist/shared/assistant/ui/voice/AssistantVoiceOrb.d.ts.map +1 -1
  32. package/dist/shared/assistant/ui/voice/AssistantVoiceOrb.js +16 -15
  33. package/dist/shared/assistant/ui/voice/VoiceCaption.d.ts.map +1 -1
  34. package/dist/shared/assistant/ui/voice/VoiceCaption.js +1 -1
  35. package/dist/shared/assistant/ui/voice/VoiceMiniController.d.ts.map +1 -1
  36. package/dist/shared/assistant/ui/voice/VoiceMiniController.js +35 -30
  37. package/dist/shared/assistant/ui/voice/VoiceStage.d.ts.map +1 -1
  38. package/dist/shared/assistant/ui/voice/VoiceStage.js +38 -37
  39. package/dist/shared/assistant/ui/voice/VoiceWaveform.d.ts +6 -0
  40. package/dist/shared/assistant/ui/voice/VoiceWaveform.d.ts.map +1 -1
  41. package/dist/shared/assistant/ui/voice/VoiceWaveform.js +40 -36
  42. package/dist/shared/assistant/voice/speakableText.d.ts +16 -1
  43. package/dist/shared/assistant/voice/speakableText.d.ts.map +1 -1
  44. package/dist/shared/assistant/voice/speakableText.js +116 -102
  45. package/dist/shared/assistant/voice/speechPlayback.d.ts +37 -19
  46. package/dist/shared/assistant/voice/speechPlayback.d.ts.map +1 -1
  47. package/dist/shared/assistant/voice/speechPlayback.js +11 -1
  48. package/dist/shared/assistant/voice/voiceSession.d.ts +12 -0
  49. package/dist/shared/assistant/voice/voiceSession.d.ts.map +1 -1
  50. package/dist/shared/assistant/voice/voiceSession.js +6 -0
  51. package/dist/shared-assistant.js +151 -150
  52. package/package.json +1 -1
@@ -1,163 +1,176 @@
1
1
  import { useVoiceInput as e } from "../voice/useVoiceInput.js";
2
- import { INITIAL_SESSION as t, INTERRUPT_MAX_MS as ee, NOTHING_HEARD as n, SILENCE_SUBMIT_MS as te, advanceHeardClock as ne, isCapturing as r, isSubmittable as re, planListeningHold as ie, planReplyConsumption as ae, planVoiceAnnouncement as oe, spokenSoFar as i, voiceSessionReducer as se } from "../voice/voiceSession.js";
3
- import { turnClockMs as a } from "../turnTimeline.js";
4
- import { useAssistantSpeech as ce } from "./AssistantSpeechProvider.js";
5
- import { useCallback as o, useEffect as s, useLayoutEffect as le, useMemo as ue, useReducer as de, useRef as c, useState as l } from "react";
2
+ import { speechFeed as t } from "../speech/speechFeed.js";
3
+ import { INITIAL_SESSION as n, INTERRUPT_MAX_MS as ee, NOTHING_HEARD as r, SILENCE_SUBMIT_MS as te, advanceHeardClock as ne, isCapturing as i, isSubmittable as re, planListeningHold as ie, planReplyConsumption as ae, planVoiceAnnouncement as oe, spokenSoFar as a, voiceSessionReducer as se } from "../voice/voiceSession.js";
4
+ import { captionChunks as ce } from "../voice/speechPlayback.js";
5
+ import { turnClockMs as o } from "../turnTimeline.js";
6
+ import { useAssistantSpeech as le } from "./AssistantSpeechProvider.js";
7
+ import { useCallback as s, useEffect as c, useLayoutEffect as ue, useMemo as de, useReducer as fe, useRef as l, useState as u } from "react";
6
8
  //#region src/shared/assistant/ui/useVoiceSession.ts
7
- var fe = 4e3, pe = 2500, me = 5e3, he = 12e3, ge = "data:audio/wav;base64,UklGRiQAAABXQVZFZm10IBAAAAABAAEARKwAAIhYAQACABAAZGF0YQAAAAA=";
8
- function u({ onSubmit: u, latestReply: d, language: _e }) {
9
- let f = c(null), [p, m] = de(o((e, t) => se(e, t, f.current), []), t), h = ce(), { setSessionSpeaking: g, setSessionMicOpen: _, speakingMessageId: v, stop: y } = h, b = c(h.toggle), x = h.toggle;
10
- le(() => {
11
- b.current = x;
12
- }, [x]);
13
- let S = c(null), C = c({}), w = c(n), T = c(null), E = c(!1), [D, O] = l(null), [k, A] = l(!1), [j, M] = l(!1), N = c(p);
14
- N.current = p;
15
- let P = c([]), F = c(null), I = c(!1), L = o(() => {
16
- P.current = [], F.current = null, I.current = !1;
17
- }, []), R = o(() => {
9
+ var pe = 4e3, me = 2500, he = 5e3, ge = 12e3, _e = "data:audio/wav;base64,UklGRiQAAABXQVZFZm10IBAAAAABAAEARKwAAIhYAQACABAAZGF0YQAAAAA=";
10
+ function d({ onSubmit: d, latestReply: f, language: ve }) {
11
+ let p = l(null), [m, h] = fe(s((e, t) => se(e, t, p.current), []), n), g = le(), { setSessionSpeaking: _, setSessionMicOpen: v, speakingMessageId: y, stop: b } = g, x = l(g.toggle), S = g.toggle;
12
+ ue(() => {
13
+ x.current = S;
14
+ }, [S]);
15
+ let C = l(null), w = l({}), T = l(r), E = l(null), D = l(!1), O = l(null), [k, A] = u(null), [j, M] = u(!1), [N, P] = u(!1), F = l(m);
16
+ F.current = m;
17
+ let I = l([]), L = l(null), R = l(!1), z = s(() => {
18
+ I.current = [], L.current = null, R.current = !1;
19
+ }, []), B = s(() => {
18
20
  for (;;) {
19
- let e = P.current.shift();
21
+ let e = I.current.shift();
20
22
  if (!e) return !1;
21
23
  if (!(e.stillWanted && !e.stillWanted())) {
22
- F.current = e, f.current = f.current ? `${f.current} ${e.text}` : e.text;
24
+ L.current = e, p.current = p.current ? `${p.current} ${e.text}` : e.text;
23
25
  try {
24
- b.current(e.id, e.text, e.lang);
26
+ x.current(e.id, e.text, e.lang);
25
27
  } catch {
26
- F.current = null;
28
+ L.current = null;
27
29
  continue;
28
30
  }
29
31
  return !0;
30
32
  }
31
33
  }
32
- }, []), z = c(!1), B = o((e) => {
34
+ }, []), V = l(!1), H = s((e) => {
33
35
  let t = ie({
34
36
  requested: e,
35
- held: z.current,
36
- muted: N.current.muted
37
+ held: V.current,
38
+ muted: F.current.muted
37
39
  });
38
- z.current = t.held, t.mute !== null && m({
40
+ V.current = t.held, t.mute !== null && h({
39
41
  type: "mute",
40
42
  muted: t.mute
41
43
  });
42
- }, []), V = o((e) => {
43
- let t = oe(N.current);
44
- t !== "drop" && (F.current?.id === e.id || P.current.some((t) => t.id === e.id) || (P.current.push(e), t === "start" && !I.current && (I.current = !0, m({ type: "announce" }))));
45
- }, []), H = o((e) => {
46
- if (N.current.phase !== "thinking") {
47
- V(e);
44
+ }, []), U = s((e) => {
45
+ let t = oe(F.current);
46
+ t !== "drop" && (L.current?.id === e.id || I.current.some((t) => t.id === e.id) || (I.current.push(e), t === "start" && !R.current && (R.current = !0, h({ type: "announce" }))));
47
+ }, []), W = s((e) => {
48
+ if (F.current.phase !== "thinking") {
49
+ U(e);
48
50
  return;
49
51
  }
50
- P.current.push(e), I.current = !0, m({ type: "answered-locally" });
51
- }, [V]), U = c(d);
52
- U.current = d, s(() => {
53
- if (p.phase === "speaking") {
54
- f.current = d?.text ?? null;
52
+ I.current.push(e), R.current = !0, h({ type: "answered-locally" });
53
+ }, [U]), G = l(f);
54
+ G.current = f, c(() => {
55
+ if (m.phase === "speaking") {
56
+ let e = O.current;
57
+ p.current = e && E.current === e.id && f?.id !== e.id ? e.text : f?.text ?? null;
55
58
  return;
56
59
  }
57
- if (f.current === null) return;
60
+ if (p.current === null) return;
58
61
  let e = setTimeout(() => {
59
- f.current = null;
60
- }, pe);
62
+ p.current = null;
63
+ }, me);
61
64
  return () => clearTimeout(e);
62
- }, [p.phase, d]);
63
- let W = o((e, t) => {
64
- m({
65
+ }, [m.phase, f]);
66
+ let K = s((e, t) => {
67
+ h({
65
68
  type: "speech",
66
69
  transcript: e,
67
70
  final: t
68
71
  });
69
- }, []), G = c(0), K = o(() => {
70
- L(), y(), G.current = Date.now(), A(!0), m({ type: "interrupt" });
71
- }, [y, L]), q = e({
72
- onFinalize: o((e) => W(e, !0), [W]),
73
- language: _e
72
+ }, []), q = l(0), J = s(() => {
73
+ z(), b(), q.current = Date.now(), M(!0), h({ type: "interrupt" });
74
+ }, [b, z]), Y = e({
75
+ onFinalize: s((e) => K(e, !0), [K]),
76
+ language: ve
74
77
  });
75
- s(() => {
76
- q.interim && W(q.interim, !1);
77
- }, [q.interim, W]), s(() => {
78
- if (S.current && clearTimeout(S.current), M(!1), w.current = ne(w.current, p, a()), p.phase !== "listening" || p.muted || !re(i(p))) return;
79
- let e = setTimeout(() => M(!0), 800), t = a();
80
- return S.current = setTimeout(() => {
81
- C.current = {
82
- speechEnded: w.current.at ?? t,
78
+ c(() => {
79
+ Y.interim && K(Y.interim, !1);
80
+ }, [Y.interim, K]), c(() => {
81
+ if (C.current && clearTimeout(C.current), P(!1), T.current = ne(T.current, m, o()), m.phase !== "listening" || m.muted || !re(a(m))) return;
82
+ let e = setTimeout(() => P(!0), 800), t = o();
83
+ return C.current = setTimeout(() => {
84
+ w.current = {
85
+ speechEnded: T.current.at ?? t,
83
86
  graceStarted: t,
84
- graceEnded: a()
85
- }, m({ type: "silence" });
87
+ graceEnded: o()
88
+ }, h({ type: "silence" });
86
89
  }, te), () => {
87
- clearTimeout(e), S.current && clearTimeout(S.current);
90
+ clearTimeout(e), C.current && clearTimeout(C.current);
88
91
  };
89
- }, [p]), s(() => {
90
- if (!k) return;
91
- let e = Date.now() - G.current, t = q.isListening ? Math.max(0, 500 - e) : Math.max(0, ee - e), n = setTimeout(() => A(!1), t);
92
+ }, [m]), c(() => {
93
+ if (!j) return;
94
+ let e = Date.now() - q.current, t = Y.isListening ? Math.max(0, 500 - e) : Math.max(0, ee - e), n = setTimeout(() => M(!1), t);
92
95
  return () => clearTimeout(n);
93
- }, [k, q.isListening]);
94
- let J = c("");
95
- p.phase === "listening" && (J.current = i(p)), s(() => {
96
- if (p.phase !== "thinking") return;
97
- _(!1), L();
98
- let e = J.current.trim();
99
- e && u(e, Y.current ?? `vs-orphan-${Date.now().toString(36)}`, C.current), C.current = {}, w.current = n;
100
- }, [p.phase]), s(() => {
101
- let e = ae(d?.id, p.phase, T.current);
102
- e.claim && (T.current = d?.id ?? null, e.advance && d && m({
96
+ }, [j, Y.isListening]);
97
+ let X = l("");
98
+ m.phase === "listening" && (X.current = a(m)), c(() => {
99
+ if (m.phase !== "thinking") return;
100
+ v(!1), z();
101
+ let e = X.current.trim();
102
+ e && d(e, Z.current ?? `vs-orphan-${Date.now().toString(36)}`, w.current), w.current = {}, T.current = r;
103
+ }, [m.phase]), c(() => {
104
+ let e = ae(f?.id, m.phase, E.current);
105
+ e.claim && (E.current = f?.id ?? null, e.advance && f && h({
103
106
  type: "reply",
104
- text: d.text
107
+ text: f.text
108
+ }));
109
+ }, [f, m.phase]), c(() => {
110
+ if (y === null || m.phase !== "thinking" || E.current === y) return;
111
+ let e = t.peek(y);
112
+ !e || e.channel !== "voice" || e.voiceSessionId === void 0 || e.voiceSessionId !== Z.current || (E.current = y, O.current = {
113
+ id: y,
114
+ text: e.text
115
+ }, h({
116
+ type: "reply-audio-started",
117
+ replyId: y
105
118
  }));
106
- }, [d, p.phase]), s(() => {
107
- let e = v !== null;
108
- E.current && !e && (F.current = null, (N.current.phase !== "speaking" || !R()) && m({ type: "speech-ended" })), E.current = e;
109
- }, [v, R]), s(() => {
110
- p.phase !== "listening" && O((e) => e === "nothing-heard" ? null : e);
111
- }, [p.phase]), s(() => {
112
- if (p.phase !== "speaking" || v !== null) return;
119
+ }, [y, m.phase]), c(() => {
120
+ let e = y !== null;
121
+ D.current && !e && (L.current = null, (F.current.phase !== "speaking" || !B()) && h({ type: "speech-ended" })), D.current = e;
122
+ }, [y, B]), c(() => {
123
+ m.phase !== "listening" && A((e) => e === "nothing-heard" ? null : e);
124
+ }, [m.phase]), c(() => {
125
+ if (m.phase !== "speaking" || y !== null) return;
113
126
  let e = setTimeout(() => {
114
- E.current || (L(), m({ type: "speech-ended" }));
115
- }, fe);
127
+ D.current || (z(), h({ type: "speech-ended" }));
128
+ }, pe);
116
129
  return () => clearTimeout(e);
117
130
  }, [
118
- p.phase,
119
- v,
120
- L
121
- ]), s(() => {
122
- let e = r(p);
123
- _(e), e ? q.isActive || q.start("auto") : q.isActive && q.stop();
131
+ m.phase,
132
+ y,
133
+ z
134
+ ]), c(() => {
135
+ let e = i(m);
136
+ v(e), e ? Y.isActive || Y.start("auto") : Y.isActive && Y.stop();
124
137
  }, [
125
- p,
126
- q,
127
- _
128
- ]), s(() => {
129
- p.phase !== "speaking" || !I.current || (I.current = !1, R() || m({ type: "speech-ended" }));
130
- }, [p.phase, R]), s(() => {
131
- q.error === "not-allowed" || q.error === "audio-capture" ? m({
138
+ m,
139
+ Y,
140
+ v
141
+ ]), c(() => {
142
+ m.phase !== "speaking" || !R.current || (R.current = !1, B() || h({ type: "speech-ended" }));
143
+ }, [m.phase, B]), c(() => {
144
+ Y.error === "not-allowed" || Y.error === "audio-capture" ? h({
132
145
  type: "fail",
133
146
  error: "mic-denied"
134
- }) : q.error === "language-not-supported" ? m({
147
+ }) : Y.error === "language-not-supported" ? h({
135
148
  type: "fail",
136
149
  error: "no-speech-support"
137
- }) : q.error === "network" ? O("network") : q.error === "unknown" && O("recognition-failed");
138
- }, [q.error]), s(() => {
139
- q.error !== null || !q.isListening || O((e) => e === "network" || e === "recognition-failed" ? null : e);
140
- }, [q.error, q.isListening]), s(() => {
141
- if (q.isListening && O((e) => e === "not-capturing" ? null : e), !r(p) || q.isListening) return;
142
- let e = setTimeout(() => O("not-capturing"), me);
150
+ }) : Y.error === "network" ? A("network") : Y.error === "unknown" && A("recognition-failed");
151
+ }, [Y.error]), c(() => {
152
+ Y.error !== null || !Y.isListening || A((e) => e === "network" || e === "recognition-failed" ? null : e);
153
+ }, [Y.error, Y.isListening]), c(() => {
154
+ if (Y.isListening && A((e) => e === "not-capturing" ? null : e), !i(m) || Y.isListening) return;
155
+ let e = setTimeout(() => A("not-capturing"), he);
143
156
  return () => clearTimeout(e);
144
- }, [p, q.isListening]), s(() => {
145
- if (p.phase !== "listening" || p.muted || !q.isListening || i(p) !== "") return;
146
- let e = setTimeout(() => O("nothing-heard"), he);
157
+ }, [m, Y.isListening]), c(() => {
158
+ if (m.phase !== "listening" || m.muted || !Y.isListening || a(m) !== "") return;
159
+ let e = setTimeout(() => A("nothing-heard"), ge);
147
160
  return () => clearTimeout(e);
148
- }, [p, q.isListening]), s(() => {
149
- i(p) !== "" && O(null);
150
- }, [p]);
151
- let Y = c(null), X = o(() => {
152
- if (A(!1), M(!1), L(), z.current = !1, !q.isSupported) {
153
- m({
161
+ }, [m, Y.isListening]), c(() => {
162
+ a(m) !== "" && A(null);
163
+ }, [m]);
164
+ let Z = l(null), Q = s(() => {
165
+ if (M(!1), P(!1), z(), V.current = !1, !Y.isSupported) {
166
+ h({
154
167
  type: "fail",
155
168
  error: "no-speech-support"
156
169
  });
157
170
  return;
158
171
  }
159
- if (h.isBlocked) {
160
- m({
172
+ if (g.isBlocked) {
173
+ h({
161
174
  type: "fail",
162
175
  error: "no-voice-support"
163
176
  });
@@ -172,65 +185,67 @@ function u({ onSubmit: u, latestReply: d, language: _e }) {
172
185
  } catch {}
173
186
  try {
174
187
  if (typeof window < "u" && typeof window.Audio == "function") {
175
- let e = new window.Audio(ge);
188
+ let e = new window.Audio(_e);
176
189
  e.volume = 0, e.play().catch(() => {});
177
190
  }
178
191
  } catch {}
179
- g(!0), O(null), T.current = U.current?.id ?? null, Y.current = `vs-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`, m({ type: "start" });
192
+ _(!0), A(null), E.current = G.current?.id ?? null, O.current = null, Z.current = `vs-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`, h({ type: "start" });
180
193
  }, [
181
- q.isSupported,
182
- h.isBlocked,
183
- g,
184
- L
185
- ]), Z = o(() => {
186
- A(!1), M(!1), L(), z.current = !1, Y.current = null, m({ type: "end" }), y(), g(!1);
194
+ Y.isSupported,
195
+ g.isBlocked,
196
+ _,
197
+ z
198
+ ]), $ = s(() => {
199
+ M(!1), P(!1), z(), V.current = !1, Z.current = null, h({ type: "end" }), b(), _(!1);
187
200
  }, [
188
- y,
189
- g,
190
- L
191
- ]), Q = o((e) => Y.current === e, []), $ = o(() => {
192
- m({
201
+ b,
202
+ _,
203
+ z
204
+ ]), ye = s((e) => Z.current === e, []), be = s(() => {
205
+ h({
193
206
  type: "mute",
194
- muted: !N.current.muted
207
+ muted: !F.current.muted
195
208
  });
196
209
  }, []);
197
- return s(() => () => {
198
- g(!1), _(!1);
199
- }, [g, _]), ue(() => ({
200
- session: p,
201
- notice: D,
202
- spokenChunks: h.spokenChunks,
203
- capturing: q.isListening,
204
- active: p.phase !== "idle" && (p.phase !== "ended" || p.error !== null),
205
- interrupting: k,
206
- awaitingEndpoint: j,
207
- available: q.isSupported && !h.isBlocked,
208
- start: X,
209
- end: Z,
210
- isCurrentSession: Q,
211
- toggleMute: $,
212
- interrupt: K,
213
- announce: V,
214
- holdListening: B,
215
- answerLocally: H
210
+ c(() => () => {
211
+ _(!1), v(!1);
212
+ }, [_, v]);
213
+ let xe = ce(g.spokenChunks, m.phase, y);
214
+ return de(() => ({
215
+ session: m,
216
+ notice: k,
217
+ spokenChunks: xe,
218
+ capturing: Y.isListening,
219
+ active: m.phase !== "idle" && (m.phase !== "ended" || m.error !== null),
220
+ interrupting: j,
221
+ awaitingEndpoint: N,
222
+ available: Y.isSupported && !g.isBlocked,
223
+ start: Q,
224
+ end: $,
225
+ isCurrentSession: ye,
226
+ toggleMute: be,
227
+ interrupt: J,
228
+ announce: U,
229
+ holdListening: H,
230
+ answerLocally: W
216
231
  }), [
217
- p,
218
- D,
232
+ m,
219
233
  k,
220
234
  j,
221
- q.isListening,
222
- q.isSupported,
223
- h.isBlocked,
224
- h.spokenChunks,
225
- X,
226
- Z,
235
+ N,
236
+ Y.isListening,
237
+ Y.isSupported,
238
+ g.isBlocked,
239
+ xe,
227
240
  Q,
228
241
  $,
229
- K,
230
- V,
231
- B,
232
- H
242
+ ye,
243
+ be,
244
+ J,
245
+ U,
246
+ H,
247
+ W
233
248
  ]);
234
249
  }
235
250
  //#endregion
236
- export { u as useVoiceSession };
251
+ export { d as useVoiceSession };
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantVoiceOrb.d.ts","sourceRoot":"","sources":["../../../../../src/shared/assistant/ui/voice/AssistantVoiceOrb.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAEhC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAGrE;;;;;;;;;;;;;;;;;;GAkBG;AACH,UAAU,KAAK;IACb,OAAO,EAAE,oBAAoB,CAAC;IAC9B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,iEAAiE;IACjE,KAAK,EAAE,MAAM,CAAC;IACd,+EAA+E;IAC/E,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,eAAO,MAAM,iBAAiB,EAAE,EAAE,CAAC,KAAK,CAkGvC,CAAC"}
1
+ {"version":3,"file":"AssistantVoiceOrb.d.ts","sourceRoot":"","sources":["../../../../../src/shared/assistant/ui/voice/AssistantVoiceOrb.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAEhC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAIrE;;;;;;;;;;;;;;;;;;GAkBG;AACH,UAAU,KAAK;IACb,OAAO,EAAE,oBAAoB,CAAC;IAC9B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,iEAAiE;IACjE,KAAK,EAAE,MAAM,CAAC;IACd,+EAA+E;IAC/E,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,eAAO,MAAM,iBAAiB,EAAE,EAAE,CAAC,KAAK,CAsGvC,CAAC"}
@@ -1,24 +1,25 @@
1
1
  import { orbMode as e } from "../../voice/voiceSession.js";
2
- import { Mic as t, MicOff as n, Square as r } from "lucide-react";
3
- import { jsx as i } from "react/jsx-runtime";
2
+ import { usePrefersReducedMotion as t } from "../usePrefersReducedMotion.js";
3
+ import { Mic as n, MicOff as r, Square as i } from "lucide-react";
4
+ import { jsx as a } from "react/jsx-runtime";
4
5
  //#region src/shared/assistant/ui/voice/AssistantVoiceOrb.tsx
5
- var a = ({ session: a, compact: o = !1, onPress: s, label: c, connecting: l = !1 }) => {
6
- let u = e(a), { muted: d, phase: f, error: p } = a, m = f === "idle" || f === "ended" || p !== null || l, h = d && f !== "speaking" ? "from-bg-elevated to-bg-elevated" : u === "listening" ? "from-action-primary-bg/80 to-action-primary-bg/20" : u === "thinking" ? "from-action-primary-bg/55 to-action-primary-bg/15" : u === "speaking" ? "from-action-primary-bg to-action-primary-bg/40" : "from-bg-elevated to-bg-elevated/40", g = d && f !== "speaking" ? "" : u === "listening" ? "motion-safe:animate-pulse" : u === "thinking" ? "motion-safe:animate-[pulse_1.6s_ease-in-out_infinite]" : u === "speaking" ? "motion-safe:animate-[pulse_0.9s_ease-in-out_infinite]" : "", _ = o ? "h-16 w-40" : "h-24 w-56", v = o ? "size-6" : "size-8", y = f === "speaking" || f === "thinking" ? r : d ? n : t;
7
- return /* @__PURE__ */ i("button", {
6
+ var o = ({ session: o, compact: s = !1, onPress: c, label: l, connecting: u = !1 }) => {
7
+ let d = e(o), f = t(), { muted: p, phase: m, error: h } = o, g = m === "idle" || m === "ended" || h !== null || u, _ = p && m !== "speaking" ? "from-bg-elevated to-bg-elevated" : d === "listening" ? "from-action-primary-bg/80 to-action-primary-bg/20" : d === "thinking" ? "from-action-primary-bg/55 to-action-primary-bg/15" : d === "speaking" ? "from-action-primary-bg to-action-primary-bg/40" : "from-bg-elevated to-bg-elevated/40", v = f || p && m !== "speaking" ? "" : d === "listening" ? "motion-safe:animate-pulse" : d === "thinking" ? "motion-safe:animate-[pulse_1.6s_ease-in-out_infinite]" : d === "speaking" ? "motion-safe:animate-[pulse_0.9s_ease-in-out_infinite]" : "", y = s ? "h-16 w-40" : "h-24 w-56", b = s ? "size-6" : "size-8", x = m === "speaking" || m === "thinking" ? i : p ? r : n;
8
+ return /* @__PURE__ */ a("button", {
8
9
  type: "button",
9
- onClick: s,
10
- disabled: m || !s,
11
- className: `flex ${_} items-center justify-center rounded-full bg-gradient-to-b ${h} ${g} text-text-primary shadow-lg transition-colors duration-300 focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong disabled:cursor-default`,
12
- "aria-label": c,
13
- "aria-pressed": f === "speaking" || f === "thinking" ? void 0 : d,
10
+ onClick: c,
11
+ disabled: g || !c,
12
+ className: `flex ${y} items-center justify-center rounded-full bg-gradient-to-b ${_} ${v} text-text-primary shadow-lg transition-colors duration-300 focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong disabled:cursor-default`,
13
+ "aria-label": l,
14
+ "aria-pressed": m === "speaking" || m === "thinking" ? void 0 : p,
14
15
  "data-testid": "assistant-voice-orb",
15
- "data-state": u,
16
- "data-muted": d || void 0,
17
- children: /* @__PURE__ */ i(y, {
18
- className: v,
16
+ "data-state": d,
17
+ "data-muted": p || void 0,
18
+ children: /* @__PURE__ */ a(x, {
19
+ className: b,
19
20
  "aria-hidden": "true"
20
21
  })
21
22
  });
22
23
  };
23
24
  //#endregion
24
- export { a as AssistantVoiceOrb };
25
+ export { o as AssistantVoiceOrb };
@@ -1 +1 @@
1
- {"version":3,"file":"VoiceCaption.d.ts","sourceRoot":"","sources":["../../../../../src/shared/assistant/ui/voice/VoiceCaption.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAEnD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,UAAU,KAAK;IACb,IAAI,EAAE,MAAM,CAAC;IACb,gEAAgE;IAChE,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,mDAAmD;IACnD,QAAQ,EAAE,OAAO,CAAC;IAClB;;;;;;;;;;;;;OAaG;IACH,YAAY,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC1D,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,wBAAwB,CAAC;AAEzD,eAAO,MAAM,YAAY,EAAE,EAAE,CAAC,KAAK,CAqKlC,CAAC"}
1
+ {"version":3,"file":"VoiceCaption.d.ts","sourceRoot":"","sources":["../../../../../src/shared/assistant/ui/voice/VoiceCaption.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAEnD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,UAAU,KAAK;IACb,IAAI,EAAE,MAAM,CAAC;IACb,gEAAgE;IAChE,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,mDAAmD;IACnD,QAAQ,EAAE,OAAO,CAAC;IAClB;;;;;;;;;;;;;OAaG;IACH,YAAY,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC1D,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,wBAAwB,CAAC;AAEzD,eAAO,MAAM,YAAY,EAAE,EAAE,CAAC,KAAK,CAwKlC,CAAC"}
@@ -16,7 +16,7 @@ var r = "data-caption-scroll", i = ({ text: i, role: a, expanded: o, spokenChunk
16
16
  className: [
17
17
  "w-full whitespace-pre-wrap break-words text-left",
18
18
  o ? "max-w-[45rem]" : "max-w-md",
19
- u ? "font-semibold text-text-primary" : "font-medium text-text-secondary",
19
+ u ? "font-semibold text-text-primary" : "font-semibold text-text-secondary",
20
20
  u ? o ? "text-[clamp(1.625rem,2.5vw,2.25rem)] leading-[1.5]" : "text-[clamp(1.625rem,2vw,2rem)] leading-[1.5]" : o ? "text-[clamp(1.125rem,1.8vw,1.375rem)] leading-[1.5]" : "text-base leading-relaxed"
21
21
  ].join(" "),
22
22
  role: "status",
@@ -1 +1 @@
1
- {"version":3,"file":"VoiceMiniController.d.ts","sourceRoot":"","sources":["../../../../../src/shared/assistant/ui/voice/VoiceMiniController.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAI3C,OAAO,EAIL,KAAK,eAAe,EACrB,MAAM,6BAA6B,CAAC;AAErC;;;;;;;;;;;;;;;;;GAiBG;AAEH,UAAU,KAAK;IACb,KAAK,EAAE,eAAe,CAAC;IACvB,uEAAuE;IACvE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB;;;;;;;;;OASG;IACH,YAAY,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC1D,UAAU,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B;;;;;OAKG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,mEAAmE;IACnE,OAAO,EAAE,SAAS,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,eAAO,MAAM,mBAAmB,EAAE,EAAE,CAAC,KAAK,CAiHzC,CAAC"}
1
+ {"version":3,"file":"VoiceMiniController.d.ts","sourceRoot":"","sources":["../../../../../src/shared/assistant/ui/voice/VoiceMiniController.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAK3C,OAAO,EAIL,KAAK,eAAe,EACrB,MAAM,6BAA6B,CAAC;AAErC;;;;;;;;;;;;;;;;;GAiBG;AAEH,UAAU,KAAK;IACb,KAAK,EAAE,eAAe,CAAC;IACvB,uEAAuE;IACvE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB;;;;;;;;;OASG;IACH,YAAY,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC1D,UAAU,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B;;;;;OAKG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,mEAAmE;IACnE,OAAO,EAAE,SAAS,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,eAAO,MAAM,mBAAmB,EAAE,EAAE,CAAC,KAAK,CA8HzC,CAAC"}
@@ -1,56 +1,61 @@
1
1
  import { showsAssistantCaption as e, waveformIsActive as t, waveformIsSettled as n } from "../../voice/voiceStageState.js";
2
2
  import { showPreviousChunk as r } from "../../voice/miniCaptionBudget.js";
3
- import { VoiceWaveform as i } from "./VoiceWaveform.js";
4
- import { VoiceStatusText as a } from "./VoiceStatusText.js";
5
- import { Fragment as o, jsx as s, jsxs as c } from "react/jsx-runtime";
3
+ import { isAwaitingFirstChunk as i } from "../../voice/speechPlayback.js";
4
+ import { VoiceWaveform as a } from "./VoiceWaveform.js";
5
+ import { VoiceStatusText as o } from "./VoiceStatusText.js";
6
+ import { Fragment as s, jsx as c, jsxs as l } from "react/jsx-runtime";
6
7
  //#region src/shared/assistant/ui/voice/VoiceMiniController.tsx
7
- var l = ({ state: l, caption: u, spokenChunks: d = null, statusText: f, statusSuffix: p, rotateStatus: m, control: h, errorText: g = null }) => {
8
- let _ = e(l), v = _ && d && d.index >= 0 ? d : null;
9
- return /* @__PURE__ */ c("div", {
8
+ var u = ({ state: u, caption: d, spokenChunks: f = null, statusText: p, statusSuffix: m, rotateStatus: h, control: g, errorText: _ = null }) => {
9
+ let v = e(u), y = v && f && f.index >= 0 ? f : null, b = v && i(f);
10
+ return /* @__PURE__ */ l("div", {
10
11
  className: "flex min-h-0 w-full flex-1 items-center gap-3 px-4",
11
12
  "data-testid": "assistant-voice-mini",
12
- "data-state": l,
13
- children: [/* @__PURE__ */ c("div", {
13
+ "data-state": u,
14
+ children: [/* @__PURE__ */ l("div", {
14
15
  className: "flex min-w-0 flex-1 flex-col gap-1.5",
15
- children: [/* @__PURE__ */ c("div", {
16
+ children: [/* @__PURE__ */ l("div", {
16
17
  className: "flex items-center gap-2",
17
- children: [/* @__PURE__ */ s(i, {
18
- active: t(l),
19
- settled: n(l),
20
- tone: l === "speaking" ? "speaking" : "listening"
21
- }), /* @__PURE__ */ s(a, {
18
+ children: [/* @__PURE__ */ c(a, {
19
+ active: t(u),
20
+ settled: n(u),
21
+ tone: u === "speaking" ? "speaking" : "listening"
22
+ }), /* @__PURE__ */ c(o, {
22
23
  className: "truncate text-xs text-text-muted",
23
- status: f,
24
- suffix: p,
25
- rotating: m
24
+ status: p,
25
+ suffix: m,
26
+ rotating: h
26
27
  })]
27
- }), l === "mic-error" ? /* @__PURE__ */ s("p", {
28
+ }), u === "mic-error" ? /* @__PURE__ */ c("p", {
28
29
  className: "line-clamp-2 text-xs text-status-warning",
29
30
  role: "alert",
30
31
  "data-testid": "assistant-voice-mini-error",
31
- children: g
32
- }) : u ? /* @__PURE__ */ s("p", {
33
- className: ["line-clamp-3 break-words text-left text-sm leading-snug", _ ? "font-semibold text-text-primary" : "font-medium text-text-secondary"].join(" "),
32
+ children: _
33
+ }) : d ? /* @__PURE__ */ c("p", {
34
+ className: [
35
+ "line-clamp-3 break-words text-left text-sm leading-snug",
36
+ b ? "min-h-9" : "",
37
+ v ? "font-semibold text-text-primary" : "font-semibold text-text-secondary"
38
+ ].join(" "),
34
39
  role: "status",
35
40
  "aria-live": "polite",
36
41
  "data-testid": "assistant-voice-caption",
37
- children: v ? /* @__PURE__ */ c(o, { children: [r(v) ? /* @__PURE__ */ c("span", {
42
+ children: y ? /* @__PURE__ */ l(s, { children: [r(y) ? /* @__PURE__ */ l("span", {
38
43
  className: "text-text-muted transition-colors duration-300",
39
- children: [v.chunks[v.index - 1], " "]
40
- }) : null, /* @__PURE__ */ s("span", {
44
+ children: [y.chunks[y.index - 1], " "]
45
+ }) : null, /* @__PURE__ */ c("span", {
41
46
  className: "text-text-primary",
42
47
  "data-testid": "assistant-voice-caption-current",
43
- children: v.chunks[v.index]
44
- })] }) : u
45
- }) : /* @__PURE__ */ s("div", {
48
+ children: y.chunks[y.index]
49
+ })] }) : b ? null : d
50
+ }) : /* @__PURE__ */ c("div", {
46
51
  className: "h-9",
47
52
  "aria-hidden": "true"
48
53
  })]
49
- }), /* @__PURE__ */ s("div", {
54
+ }), /* @__PURE__ */ c("div", {
50
55
  className: "shrink-0",
51
- children: h
56
+ children: g
52
57
  })]
53
58
  });
54
59
  };
55
60
  //#endregion
56
- export { l as VoiceMiniController };
61
+ export { u as VoiceMiniController };
@@ -1 +1 @@
1
- {"version":3,"file":"VoiceStage.d.ts","sourceRoot":"","sources":["../../../../../src/shared/assistant/ui/voice/VoiceStage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAI3C,OAAO,EAKL,KAAK,eAAe,EACrB,MAAM,6BAA6B,CAAC;AAErC;;;;;;;;;;;;;;;;;GAiBG;AAEH,UAAU,KAAK;IACb,KAAK,EAAE,eAAe,CAAC;IACvB,mDAAmD;IACnD,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,oCAAoC;IACpC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,QAAQ,EAAE,OAAO,CAAC;IAClB,sDAAsD;IACtD,UAAU,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B;;;;;OAKG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,0CAA0C;IAC1C,OAAO,EAAE,SAAS,CAAC;IACnB,yDAAyD;IACzD,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,+EAA+E;IAC/E,YAAY,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CAC3D;AAED,eAAO,MAAM,UAAU,EAAE,EAAE,CAAC,KAAK,CAmIhC,CAAC"}
1
+ {"version":3,"file":"VoiceStage.d.ts","sourceRoot":"","sources":["../../../../../src/shared/assistant/ui/voice/VoiceStage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAK3C,OAAO,EAKL,KAAK,eAAe,EACrB,MAAM,6BAA6B,CAAC;AAErC;;;;;;;;;;;;;;;;;GAiBG;AAEH,UAAU,KAAK;IACb,KAAK,EAAE,eAAe,CAAC;IACvB,mDAAmD;IACnD,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,oCAAoC;IACpC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,QAAQ,EAAE,OAAO,CAAC;IAClB,sDAAsD;IACtD,UAAU,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B;;;;;OAKG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,0CAA0C;IAC1C,OAAO,EAAE,SAAS,CAAC;IACnB,yDAAyD;IACzD,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,+EAA+E;IAC/E,YAAY,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CAC3D;AAED,eAAO,MAAM,UAAU,EAAE,EAAE,CAAC,KAAK,CA6IhC,CAAC"}