@burdenoff/fe-libs 2026.1007.3 → 2026.1007.5

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 (112) hide show
  1. package/dist/chrome/AutoBreadcrumbs.d.ts.map +1 -1
  2. package/dist/chrome/AutoBreadcrumbs.js +65 -76
  3. package/dist/chrome/Breadcrumb.d.ts.map +1 -1
  4. package/dist/chrome/Breadcrumbs.d.ts.map +1 -1
  5. package/dist/chrome/Breadcrumbs.js +47 -46
  6. package/dist/chrome/ContextSwitcher.js +86 -86
  7. package/dist/chrome/HeaderBar.d.ts.map +1 -1
  8. package/dist/chrome/HeaderBar.js +111 -107
  9. package/dist/chrome/HeaderThemeSwitcher.d.ts.map +1 -1
  10. package/dist/chrome/HeaderThemeSwitcher.js +46 -45
  11. package/dist/chrome/LanguageSwitcher.js +4 -4
  12. package/dist/chrome/MobileTabBar.js +4 -4
  13. package/dist/chrome/PageHeader.d.ts.map +1 -1
  14. package/dist/chrome/PageHeader.js +32 -30
  15. package/dist/chrome/PersonaSurfaceControls.js +8 -8
  16. package/dist/chrome/ProductSideNav.js +6 -6
  17. package/dist/chrome/ProfileSwitcher.d.ts.map +1 -1
  18. package/dist/chrome/ProfileSwitcher.js +89 -88
  19. package/dist/chrome/SideNavigation.js +4 -4
  20. package/dist/chrome/Tabs.d.ts.map +1 -1
  21. package/dist/chrome/Tabs.js +30 -29
  22. package/dist/chrome/breadcrumbLabel.d.ts +10 -0
  23. package/dist/chrome/breadcrumbLabel.d.ts.map +1 -0
  24. package/dist/chrome/breadcrumbLabel.js +31 -0
  25. package/dist/chrome/contextSwitcher/TriggerButton.d.ts.map +1 -1
  26. package/dist/chrome/contextSwitcher/TriggerButton.js +40 -36
  27. package/dist/chrome/notificationCenter/BellButton.d.ts.map +1 -1
  28. package/dist/chrome/notificationCenter/BellButton.js +29 -25
  29. package/dist/chrome/shellLabelManifest.d.ts +27 -0
  30. package/dist/chrome/shellLabelManifest.d.ts.map +1 -0
  31. package/dist/chrome/sideNavigation/SidebarHeader.d.ts.map +1 -1
  32. package/dist/chrome/sideNavigation/SidebarHeader.js +23 -22
  33. package/dist/shared/assistant/appControls/languageReply.d.ts +6 -1
  34. package/dist/shared/assistant/appControls/languageReply.d.ts.map +1 -1
  35. package/dist/shared/assistant/i18nManifest.d.ts +20 -5
  36. package/dist/shared/assistant/i18nManifest.d.ts.map +1 -1
  37. package/dist/shared/assistant/i18nManifest.js +30 -22
  38. package/dist/shared/assistant/index.d.ts +3 -0
  39. package/dist/shared/assistant/index.d.ts.map +1 -1
  40. package/dist/shared/assistant/productCopy.d.ts +78 -0
  41. package/dist/shared/assistant/productCopy.d.ts.map +1 -0
  42. package/dist/shared/assistant/productCopy.js +45 -0
  43. package/dist/shared/assistant/store.d.ts +10 -0
  44. package/dist/shared/assistant/store.d.ts.map +1 -1
  45. package/dist/shared/assistant/store.js +19 -8
  46. package/dist/shared/assistant/ui/AssistantChatArea.d.ts.map +1 -1
  47. package/dist/shared/assistant/ui/AssistantChatArea.js +1070 -1067
  48. package/dist/shared/assistant/ui/AssistantEmptyState.d.ts.map +1 -1
  49. package/dist/shared/assistant/ui/AssistantEmptyState.js +30 -22
  50. package/dist/shared/assistant/ui/AssistantHeader.d.ts.map +1 -1
  51. package/dist/shared/assistant/ui/AssistantHeader.js +46 -45
  52. package/dist/shared/assistant/ui/useVoiceSession.d.ts +14 -1
  53. package/dist/shared/assistant/ui/useVoiceSession.d.ts.map +1 -1
  54. package/dist/shared/assistant/ui/useVoiceSession.js +241 -233
  55. package/dist/shared/assistant/ui/voice/AssistantVoiceSession.d.ts +7 -0
  56. package/dist/shared/assistant/ui/voice/AssistantVoiceSession.d.ts.map +1 -1
  57. package/dist/shared/assistant/ui/voice/AssistantVoiceSession.js +137 -130
  58. package/dist/shared/assistant/ui/voice/HandsFreePrivacyNotice.d.ts +27 -0
  59. package/dist/shared/assistant/ui/voice/HandsFreePrivacyNotice.d.ts.map +1 -0
  60. package/dist/shared/assistant/ui/voice/HandsFreePrivacyNotice.js +52 -0
  61. package/dist/shared/assistant/voice/handsfree/backendStreamTransport.d.ts +29 -6
  62. package/dist/shared/assistant/voice/handsfree/backendStreamTransport.d.ts.map +1 -1
  63. package/dist/shared/assistant/voice/handsfree/backendStreamTransport.js +138 -63
  64. package/dist/shared/assistant/voice/handsfree/handsFreeController.d.ts +7 -1
  65. package/dist/shared/assistant/voice/handsfree/handsFreeController.d.ts.map +1 -1
  66. package/dist/shared/assistant/voice/handsfree/handsFreeRuntime.d.ts +18 -10
  67. package/dist/shared/assistant/voice/handsfree/handsFreeRuntime.d.ts.map +1 -1
  68. package/dist/shared/assistant/voice/handsfree/handsFreeRuntime.js +46 -57
  69. package/dist/shared/assistant/voice/handsfree/streamingConfig.d.ts +103 -0
  70. package/dist/shared/assistant/voice/handsfree/streamingConfig.d.ts.map +1 -0
  71. package/dist/shared/assistant/voice/handsfree/streamingConfig.js +71 -0
  72. package/dist/shared/assistant/voice/handsfree/sttTransport.d.ts +12 -7
  73. package/dist/shared/assistant/voice/handsfree/sttTransport.d.ts.map +1 -1
  74. package/dist/shared/assistant/voice/handsfree/sttTransport.js +1 -1
  75. package/dist/shared/assistant/voice/handsfree/useHandsFreeInterrupt.d.ts +23 -1
  76. package/dist/shared/assistant/voice/handsfree/useHandsFreeInterrupt.d.ts.map +1 -1
  77. package/dist/shared/assistant/voice/handsfree/useHandsFreeInterrupt.js +63 -50
  78. package/dist/shared/components/ContextConversationWidget.js +1 -1
  79. package/dist/shared/events/sinks/RybbitSink.d.ts.map +1 -1
  80. package/dist/shared/events/sinks/RybbitSink.js +66 -69
  81. package/dist/shared/providers/AppShellProvider.d.ts +17 -0
  82. package/dist/shared/providers/AppShellProvider.d.ts.map +1 -1
  83. package/dist/shared/providers/AppShellProvider.js +188 -180
  84. package/dist/shared/providers/shell/I18nProvider.d.ts +92 -4
  85. package/dist/shared/providers/shell/I18nProvider.d.ts.map +1 -1
  86. package/dist/shared/providers/shell/I18nProvider.js +187 -79
  87. package/dist/shared/providers/shell/ProfileI18nBridge.d.ts +18 -2
  88. package/dist/shared/providers/shell/ProfileI18nBridge.d.ts.map +1 -1
  89. package/dist/shared/providers/shell/ProfileI18nBridge.js +55 -41
  90. package/dist/shared/providers/shell/directionMode.d.ts +25 -0
  91. package/dist/shared/providers/shell/directionMode.d.ts.map +1 -0
  92. package/dist/shared/providers/shell/directionMode.js +34 -0
  93. package/dist/shared/providers/shell/index.d.ts +4 -2
  94. package/dist/shared/providers/shell/index.d.ts.map +1 -1
  95. package/dist/shared/providers/shell/translationLayers.d.ts +30 -0
  96. package/dist/shared/providers/shell/translationLayers.d.ts.map +1 -0
  97. package/dist/shared/providers/shell/translationLayers.js +35 -0
  98. package/dist/shared/providers/shell/translationStore.d.ts +55 -0
  99. package/dist/shared/providers/shell/translationStore.d.ts.map +1 -0
  100. package/dist/shared/providers/shell/translationStore.js +100 -0
  101. package/dist/shared/providers/shell/useShellLabel.d.ts +13 -1
  102. package/dist/shared/providers/shell/useShellLabel.d.ts.map +1 -1
  103. package/dist/shared/providers/shell/useShellLabel.js +10 -9
  104. package/dist/shared-assistant.js +190 -187
  105. package/dist/shared-providers-shell.js +20 -19
  106. package/dist/ui/boff-ui2.d.ts.map +1 -1
  107. package/dist/ui/cta-overflow-menu.d.ts.map +1 -1
  108. package/dist/ui/cta-overflow-menu.js +20 -18
  109. package/dist/ui/guidance.d.ts +1 -1
  110. package/dist/ui/guidance.d.ts.map +1 -1
  111. package/dist/ui/guidance.js +53 -52
  112. package/package.json +3 -2
@@ -3,239 +3,245 @@ import { planSubmitTimer as t, resolveVoiceGraceMs as n } from "../voice/handsFr
3
3
  import { readHandsFreeOverride as r, resolveHandsFreeEnabled as ee } from "../voice/handsfree/handsFreeSetting.js";
4
4
  import { silencePlaybackReference as te } from "../voice/handsfree/playbackReference.js";
5
5
  import { speechFeed as ne } from "../speech/speechFeed.js";
6
- import { INITIAL_SESSION as re, INTERRUPT_MAX_MS as ie, NOTHING_HEARD as ae, advanceHeardClock as oe, isCapturing as se, isSubmittable as ce, planListeningHold as le, planReplyConsumption as ue, planVoiceAnnouncement as de, shouldRecognise as fe, spokenSoFar as i, voiceSessionReducer as pe } from "../voice/voiceSession.js";
7
- import { useHandsFreeInterrupt as me } from "../voice/handsfree/useHandsFreeInterrupt.js";
8
- import { isTurnSuperseded as a } from "../voice/supersededTurns.js";
9
- import { captionChunks as he } from "../voice/speechPlayback.js";
10
- import { turnClockMs as o } from "../turnTimeline.js";
11
- import { useAssistantSpeech as ge } from "./AssistantSpeechProvider.js";
12
- import { useCallback as s, useEffect as c, useLayoutEffect as _e, useMemo as ve, useReducer as ye, useRef as l, useState as u } from "react";
6
+ import { INITIAL_SESSION as re, INTERRUPT_MAX_MS as ie, NOTHING_HEARD as ae, advanceHeardClock as oe, isCapturing as i, isSubmittable as se, planListeningHold as ce, planReplyConsumption as le, planVoiceAnnouncement as ue, shouldRecognise as de, spokenSoFar as a, voiceSessionReducer as fe } from "../voice/voiceSession.js";
7
+ import { useHandsFreeInterrupt as pe } from "../voice/handsfree/useHandsFreeInterrupt.js";
8
+ import { isTurnSuperseded as o } from "../voice/supersededTurns.js";
9
+ import { captionChunks as me } from "../voice/speechPlayback.js";
10
+ import { turnClockMs as s } from "../turnTimeline.js";
11
+ import { useAssistantSpeech as he } from "./AssistantSpeechProvider.js";
12
+ import { useCallback as c, useEffect as l, useLayoutEffect as ge, useMemo as _e, useReducer as ve, useRef as u, useState as d } from "react";
13
13
  //#region src/shared/assistant/ui/useVoiceSession.ts
14
- var be = 4e3, xe = 2500, Se = 5e3, Ce = 12e3, we = "data:audio/wav;base64,UklGRiQAAABXQVZFZm10IBAAAAABAAEARKwAAIhYAQACABAAZGF0YQAAAAA=";
15
- function d({ onSubmit: d, latestReply: f, language: p, graceMs: Te, onSupersede: Ee, handsFreeInterrupt: De, onBargeIn: Oe }) {
16
- let ke = n(Te), m = l(null), [h, g] = ye(s((e, t) => pe(e, t, m.current), []), re), _ = ge(), { setSessionSpeaking: v, setSessionMicOpen: y, speakingMessageId: b, stop: x } = _, S = l(_.toggle), C = _.toggle;
17
- _e(() => {
18
- S.current = C;
19
- }, [C]);
20
- let w = l(null), T = l({}), E = l(ae), D = l(null), O = l(!1), k = l(null), [A, j] = u(null), [M, N] = u(!1), [P, F] = u(!1), [I, L] = u(!1), R = l(h);
21
- R.current = h;
22
- let z = l([]), B = l(null), V = l(!1), H = s(() => {
23
- z.current = [], B.current = null, V.current = !1;
24
- }, []), U = s(() => {
14
+ var ye = 4e3, be = 2500, xe = 5e3, Se = 12e3, Ce = "data:audio/wav;base64,UklGRiQAAABXQVZFZm10IBAAAAABAAEARKwAAIhYAQACABAAZGF0YQAAAAA=";
15
+ function we({ onSubmit: we, latestReply: f, language: p, graceMs: Te, onSupersede: Ee, handsFreeInterrupt: De, handsFreeStreamNoticeAccepted: Oe, onAcceptHandsFreeStreamNotice: ke, onBargeIn: m }) {
16
+ let h = n(Te), g = u(null), [_, v] = ve(c((e, t) => fe(e, t, g.current), []), re), y = he(), { setSessionSpeaking: b, setSessionMicOpen: x, speakingMessageId: S, stop: C } = y, w = u(y.toggle), T = y.toggle;
17
+ ge(() => {
18
+ w.current = T;
19
+ }, [T]);
20
+ let E = u(null), D = u({}), O = u(ae), k = u(null), A = u(!1), j = u(null), [M, N] = d(null), [P, F] = d(!1), [Ae, I] = d(!1), [L, R] = d(!1), z = u(_);
21
+ z.current = _;
22
+ let B = u([]), V = u(null), H = u(!1), U = c(() => {
23
+ B.current = [], V.current = null, H.current = !1;
24
+ }, []), W = c(() => {
25
25
  for (;;) {
26
- let e = z.current.shift();
26
+ let e = B.current.shift();
27
27
  if (!e) return !1;
28
28
  if (!(e.stillWanted && !e.stillWanted())) {
29
- B.current = e, m.current = m.current ? `${m.current} ${e.text}` : e.text;
29
+ V.current = e, g.current = g.current ? `${g.current} ${e.text}` : e.text;
30
30
  try {
31
- S.current(e.id, e.text, e.lang);
31
+ w.current(e.id, e.text, e.lang);
32
32
  } catch {
33
- B.current = null;
33
+ V.current = null;
34
34
  continue;
35
35
  }
36
36
  return !0;
37
37
  }
38
38
  }
39
- }, []), W = l(!1), Ae = s((e) => {
40
- let t = le({
39
+ }, []), G = u(!1), je = c((e) => {
40
+ let t = ce({
41
41
  requested: e,
42
- held: W.current,
43
- muted: R.current.muted
42
+ held: G.current,
43
+ muted: z.current.muted
44
44
  });
45
- W.current = t.held, t.mute !== null && g({
45
+ G.current = t.held, t.mute !== null && v({
46
46
  type: "mute",
47
47
  muted: t.mute
48
48
  });
49
- }, []), G = s((e) => {
50
- let t = de(R.current);
51
- t !== "drop" && (B.current?.id === e.id || z.current.some((t) => t.id === e.id) || (z.current.push(e), t === "start" && !V.current && (V.current = !0, g({ type: "announce" }))));
52
- }, []), je = s((e) => {
53
- if (R.current.phase !== "thinking") {
54
- G(e);
49
+ }, []), K = c((e) => {
50
+ let t = ue(z.current);
51
+ t !== "drop" && (V.current?.id === e.id || B.current.some((t) => t.id === e.id) || (B.current.push(e), t === "start" && !H.current && (H.current = !0, v({ type: "announce" }))));
52
+ }, []), Me = c((e) => {
53
+ if (z.current.phase !== "thinking") {
54
+ K(e);
55
55
  return;
56
56
  }
57
- z.current.push(e), V.current = !0, g({ type: "answered-locally" });
58
- }, [G]), Me = l(f);
59
- Me.current = f, c(() => {
60
- if (h.phase === "speaking") {
61
- let e = k.current;
62
- m.current = e && D.current === e.id && f?.id !== e.id ? e.text : f?.text ?? null;
57
+ B.current.push(e), H.current = !0, v({ type: "answered-locally" });
58
+ }, [K]), Ne = u(f);
59
+ Ne.current = f, l(() => {
60
+ if (_.phase === "speaking") {
61
+ let e = j.current;
62
+ g.current = e && k.current === e.id && f?.id !== e.id ? e.text : f?.text ?? null;
63
63
  return;
64
64
  }
65
- if (m.current === null) return;
65
+ if (g.current === null) return;
66
66
  let e = setTimeout(() => {
67
- m.current = null;
68
- }, xe);
67
+ g.current = null;
68
+ }, be);
69
69
  return () => clearTimeout(e);
70
- }, [h.phase, f]);
71
- let K = l(p);
72
- K.current = p;
73
- let q = s((e, t) => {
74
- g({
70
+ }, [_.phase, f]);
71
+ let q = u(p);
72
+ q.current = p;
73
+ let J = c((e, t) => {
74
+ v({
75
75
  type: "speech",
76
76
  transcript: e,
77
77
  final: t,
78
78
  at: Date.now(),
79
- language: K.current
79
+ language: q.current
80
80
  });
81
- }, []), Ne = s((e, t, n) => {
82
- g({
81
+ }, []), Pe = c((e, t, n) => {
82
+ v({
83
83
  type: "speech",
84
84
  transcript: e,
85
85
  final: t,
86
86
  at: Date.now(),
87
- language: n ?? K.current,
87
+ language: n ?? q.current,
88
88
  gated: !0
89
89
  });
90
- }, []), J = l(0), Pe = s(() => {
91
- H(), x(), J.current = Date.now(), N(!0), g({ type: "interrupt" });
92
- }, [x, H]), Y = e({
93
- onFinalize: s((e) => q(e, !0), [q]),
90
+ }, []), Y = u(0), Fe = c(() => {
91
+ U(), C(), Y.current = Date.now(), F(!0), v({ type: "interrupt" });
92
+ }, [C, U]), X = e({
93
+ onFinalize: c((e) => J(e, !0), [J]),
94
94
  language: p
95
- }), Fe = l(Oe);
96
- Fe.current = Oe;
97
- let Ie = s(() => {
98
- H(), te(), x(), J.current = Date.now(), N(!0), g({ type: "interrupt" }), Fe.current?.();
99
- }, [x, H]), X = me({
95
+ }), Ie = u(m);
96
+ Ie.current = m;
97
+ let Le = c(() => {
98
+ U(), te(), C(), Y.current = Date.now(), F(!0), v({ type: "interrupt" }), Ie.current?.();
99
+ }, [C, U]), Z = pe({
100
100
  enabled: ee(De, r()),
101
- phase: h.phase,
102
- muted: h.muted,
101
+ phase: _.phase,
102
+ muted: _.muted,
103
103
  language: p,
104
- onBargeIn: Ie,
105
- onTranscript: Ne
106
- }), Z = Y.isListening || X.suppressWebSpeech && X.mode === "active";
107
- c(() => {
108
- Y.interim && q(Y.interim, !1);
109
- }, [Y.interim, q]), c(() => {
110
- w.current && clearTimeout(w.current), F(!1), E.current = oe(E.current, h, o());
104
+ streamNoticeAccepted: Oe ?? null,
105
+ onAcceptStreamNotice: ke,
106
+ onBargeIn: Le,
107
+ onTranscript: Pe
108
+ }), Re = Z.mode === "notice", Q = X.isListening || Z.suppressWebSpeech && Z.mode === "active";
109
+ l(() => {
110
+ X.interim && J(X.interim, !1);
111
+ }, [X.interim, J]), l(() => {
112
+ E.current && clearTimeout(E.current), I(!1), O.current = oe(O.current, _, s());
111
113
  let e = t({
112
- phase: h.phase,
113
- muted: h.muted,
114
- spoken: i(h),
115
- holding: I,
116
- graceMs: ke
114
+ phase: _.phase,
115
+ muted: _.muted,
116
+ spoken: a(_),
117
+ holding: L,
118
+ graceMs: h
117
119
  });
118
120
  if (!e.arm) return;
119
- let n = setTimeout(() => F(!0), Math.min(800, e.delayMs)), r = o();
120
- return w.current = setTimeout(() => {
121
- T.current = {
122
- speechEnded: E.current.at ?? r,
121
+ let n = setTimeout(() => I(!0), Math.min(800, e.delayMs)), r = s();
122
+ return E.current = setTimeout(() => {
123
+ D.current = {
124
+ speechEnded: O.current.at ?? r,
123
125
  graceStarted: r,
124
- graceEnded: o()
125
- }, g({
126
+ graceEnded: s()
127
+ }, v({
126
128
  type: "silence",
127
129
  at: Date.now()
128
130
  });
129
131
  }, e.delayMs), () => {
130
- clearTimeout(n), w.current && clearTimeout(w.current);
132
+ clearTimeout(n), E.current && clearTimeout(E.current);
131
133
  };
132
134
  }, [
133
- h,
134
- I,
135
- ke
136
- ]), c(() => {
137
- (h.phase !== "listening" || h.muted) && L(!1);
138
- }, [h.phase, h.muted]), c(() => {
139
- if (!M) return;
140
- let e = Date.now() - J.current, t = Z ? Math.max(0, 500 - e) : Math.max(0, ie - e), n = setTimeout(() => N(!1), t);
135
+ _,
136
+ L,
137
+ h
138
+ ]), l(() => {
139
+ (_.phase !== "listening" || _.muted) && R(!1);
140
+ }, [_.phase, _.muted]), l(() => {
141
+ if (!P) return;
142
+ let e = Date.now() - Y.current, t = Q ? Math.max(0, 500 - e) : Math.max(0, ie - e), n = setTimeout(() => F(!1), t);
141
143
  return () => clearTimeout(n);
142
- }, [M, Z]);
143
- let Le = l("");
144
- h.phase === "listening" && (Le.current = i(h)), c(() => {
145
- if (h.phase !== "thinking") return;
146
- y(!1), H();
147
- let e = Le.current.trim();
148
- e && d(e, Q.current ?? `vs-orphan-${Date.now().toString(36)}`, T.current, { correction: R.current.correcting }), T.current = {}, E.current = ae;
149
- }, [h.phase]), c(() => {
150
- let e = ue(f?.id, h.phase, D.current, a(f?.id));
151
- e.claim && (D.current = f?.id ?? null, e.advance && f && g({
144
+ }, [P, Q]);
145
+ let ze = u("");
146
+ _.phase === "listening" && (ze.current = a(_)), l(() => {
147
+ if (_.phase !== "thinking") return;
148
+ x(!1), U();
149
+ let e = ze.current.trim();
150
+ e && we(e, $.current ?? `vs-orphan-${Date.now().toString(36)}`, D.current, { correction: z.current.correcting }), D.current = {}, O.current = ae;
151
+ }, [_.phase]), l(() => {
152
+ let e = le(f?.id, _.phase, k.current, o(f?.id));
153
+ e.claim && (k.current = f?.id ?? null, e.advance && f && v({
152
154
  type: "reply",
153
155
  text: f.text
154
156
  }));
155
- }, [f, h.phase]), c(() => {
156
- if (b === null || h.phase !== "thinking" || D.current === b) return;
157
- if (a(b)) {
158
- x();
157
+ }, [f, _.phase]), l(() => {
158
+ if (S === null || _.phase !== "thinking" || k.current === S) return;
159
+ if (o(S)) {
160
+ C();
159
161
  return;
160
162
  }
161
- let e = ne.peek(b);
162
- !e || e.channel !== "voice" || e.voiceSessionId === void 0 || e.voiceSessionId !== Q.current || (D.current = b, k.current = {
163
- id: b,
163
+ let e = ne.peek(S);
164
+ !e || e.channel !== "voice" || e.voiceSessionId === void 0 || e.voiceSessionId !== $.current || (k.current = S, j.current = {
165
+ id: S,
164
166
  text: e.text
165
- }, g({
167
+ }, v({
166
168
  type: "reply-audio-started",
167
- replyId: b
169
+ replyId: S
168
170
  }));
169
171
  }, [
170
- b,
171
- h.phase,
172
- x
173
- ]), c(() => {
174
- let e = b !== null;
175
- O.current && !e && (B.current = null, (R.current.phase !== "speaking" || !U()) && g({ type: "speech-ended" })), O.current = e;
176
- }, [b, U]), c(() => {
177
- h.phase !== "listening" && j((e) => e === "nothing-heard" ? null : e);
178
- }, [h.phase]), c(() => {
179
- if (h.phase !== "speaking" || b !== null) return;
172
+ S,
173
+ _.phase,
174
+ C
175
+ ]), l(() => {
176
+ let e = S !== null;
177
+ A.current && !e && (V.current = null, (z.current.phase !== "speaking" || !W()) && v({ type: "speech-ended" })), A.current = e;
178
+ }, [S, W]), l(() => {
179
+ _.phase !== "listening" && N((e) => e === "nothing-heard" ? null : e);
180
+ }, [_.phase]), l(() => {
181
+ if (_.phase !== "speaking" || S !== null) return;
180
182
  let e = setTimeout(() => {
181
- O.current || (H(), g({ type: "speech-ended" }));
182
- }, be);
183
+ A.current || (U(), v({ type: "speech-ended" }));
184
+ }, ye);
183
185
  return () => clearTimeout(e);
184
186
  }, [
185
- h.phase,
186
- b,
187
- H
187
+ _.phase,
188
+ S,
189
+ U
188
190
  ]);
189
- let Re = l(Ee);
190
- Re.current = Ee;
191
- let ze = l(0);
192
- c(() => {
193
- let e = h.superseded;
194
- e !== ze.current && (ze.current = e, e !== 0 && (H(), x(), Re.current?.()));
191
+ let Be = u(Ee);
192
+ Be.current = Ee;
193
+ let Ve = u(0);
194
+ l(() => {
195
+ let e = _.superseded;
196
+ e !== Ve.current && (Ve.current = e, e !== 0 && (U(), C(), Be.current?.()));
195
197
  }, [
196
- h.superseded,
197
- H,
198
- x
199
- ]), c(() => {
200
- y(se(h)), fe(h) && !X.suppressWebSpeech ? Y.isActive || Y.start("auto") : Y.isActive && Y.stop();
198
+ _.superseded,
199
+ U,
200
+ C
201
+ ]), l(() => {
202
+ x(i(_)), de(_) && !Z.suppressWebSpeech ? X.isActive || X.start("auto") : X.isActive && X.stop();
201
203
  }, [
202
- h,
203
- Y,
204
- y,
205
- X.suppressWebSpeech
206
- ]), c(() => {
207
- h.phase !== "speaking" || !V.current || (V.current = !1, U() || g({ type: "speech-ended" }));
208
- }, [h.phase, U]), c(() => {
209
- Y.error === "not-allowed" || Y.error === "audio-capture" ? g({
204
+ _,
205
+ X,
206
+ x,
207
+ Z.suppressWebSpeech
208
+ ]), l(() => {
209
+ _.phase !== "speaking" || !H.current || (H.current = !1, W() || v({ type: "speech-ended" }));
210
+ }, [_.phase, W]), l(() => {
211
+ X.error === "not-allowed" || X.error === "audio-capture" ? v({
210
212
  type: "fail",
211
213
  error: "mic-denied"
212
- }) : Y.error === "language-not-supported" ? g({
214
+ }) : X.error === "language-not-supported" ? v({
213
215
  type: "fail",
214
216
  error: "no-speech-support"
215
- }) : Y.error === "network" ? j("network") : Y.error === "unknown" && j("recognition-failed");
216
- }, [Y.error]), c(() => {
217
- Y.error !== null || !Z || j((e) => e === "network" || e === "recognition-failed" ? null : e);
218
- }, [Y.error, Z]), c(() => {
219
- if (Z && j((e) => e === "not-capturing" ? null : e), !se(h) || Z) return;
220
- let e = setTimeout(() => j("not-capturing"), Se);
217
+ }) : X.error === "network" ? N("network") : X.error === "unknown" && N("recognition-failed");
218
+ }, [X.error]), l(() => {
219
+ X.error !== null || !Q || N((e) => e === "network" || e === "recognition-failed" ? null : e);
220
+ }, [X.error, Q]), l(() => {
221
+ if (Q && N((e) => e === "not-capturing" ? null : e), !i(_) || Q || Re) return;
222
+ let e = setTimeout(() => N("not-capturing"), xe);
221
223
  return () => clearTimeout(e);
222
- }, [h, Z]), c(() => {
223
- if (h.phase !== "listening" || h.muted || !Z || i(h) !== "") return;
224
- let e = setTimeout(() => j("nothing-heard"), Ce);
224
+ }, [
225
+ _,
226
+ Q,
227
+ Re
228
+ ]), l(() => {
229
+ if (_.phase !== "listening" || _.muted || !Q || a(_) !== "") return;
230
+ let e = setTimeout(() => N("nothing-heard"), Se);
225
231
  return () => clearTimeout(e);
226
- }, [h, Z]), c(() => {
227
- i(h) !== "" && j(null);
228
- }, [h]);
229
- let Q = l(null), Be = s(() => {
230
- if (N(!1), F(!1), L(!1), H(), W.current = !1, !Y.isSupported) {
231
- g({
232
+ }, [_, Q]), l(() => {
233
+ a(_) !== "" && N(null);
234
+ }, [_]);
235
+ let $ = u(null), He = c(() => {
236
+ if (F(!1), I(!1), R(!1), U(), G.current = !1, !X.isSupported) {
237
+ v({
232
238
  type: "fail",
233
239
  error: "no-speech-support"
234
240
  });
235
241
  return;
236
242
  }
237
- if (_.isBlocked) {
238
- g({
243
+ if (y.isBlocked) {
244
+ v({
239
245
  type: "fail",
240
246
  error: "no-voice-support"
241
247
  });
@@ -250,100 +256,102 @@ function d({ onSubmit: d, latestReply: f, language: p, graceMs: Te, onSupersede:
250
256
  } catch {}
251
257
  try {
252
258
  if (typeof window < "u" && typeof window.Audio == "function") {
253
- let e = new window.Audio(we);
259
+ let e = new window.Audio(Ce);
254
260
  e.volume = 0, e.play().catch(() => {});
255
261
  }
256
262
  } catch {}
257
- v(!0), j(null), D.current = Me.current?.id ?? null, k.current = null, Q.current = `vs-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`, g({ type: "start" });
263
+ b(!0), N(null), k.current = Ne.current?.id ?? null, j.current = null, $.current = `vs-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`, v({ type: "start" });
258
264
  }, [
259
- Y.isSupported,
260
- _.isBlocked,
261
- v,
262
- H
263
- ]), Ve = s(() => {
264
- N(!1), F(!1), L(!1), H(), W.current = !1, Q.current = null, g({ type: "end" }), x(), v(!1);
265
+ X.isSupported,
266
+ y.isBlocked,
267
+ b,
268
+ U
269
+ ]), Ue = c(() => {
270
+ F(!1), I(!1), R(!1), U(), G.current = !1, $.current = null, v({ type: "end" }), C(), b(!1);
265
271
  }, [
266
- x,
267
- v,
268
- H
269
- ]), He = s((e) => Q.current === e, []), Ue = s(() => {
270
- let e = R.current;
271
- e.phase !== "listening" || e.muted || L(!0);
272
- }, []), We = s(() => {
273
- L(!1);
274
- let e = R.current;
275
- if (e.phase !== "listening" || e.muted || !ce(i(e))) return;
276
- let t = o();
277
- T.current = {
278
- speechEnded: E.current.at ?? t,
272
+ C,
273
+ b,
274
+ U
275
+ ]), We = c((e) => $.current === e, []), Ge = c(() => {
276
+ let e = z.current;
277
+ e.phase !== "listening" || e.muted || R(!0);
278
+ }, []), Ke = c(() => {
279
+ R(!1);
280
+ let e = z.current;
281
+ if (e.phase !== "listening" || e.muted || !se(a(e))) return;
282
+ let t = s();
283
+ D.current = {
284
+ speechEnded: O.current.at ?? t,
279
285
  graceStarted: t,
280
286
  graceEnded: t
281
- }, g({
287
+ }, v({
282
288
  type: "silence",
283
289
  at: Date.now()
284
290
  });
285
- }, []), Ge = s(() => {
286
- g({
291
+ }, []), qe = c(() => {
292
+ v({
287
293
  type: "mute",
288
- muted: !R.current.muted
294
+ muted: !z.current.muted
289
295
  });
290
296
  }, []);
291
- c(() => () => {
292
- v(!1), y(!1);
293
- }, [v, y]);
294
- let $ = he(_.spokenChunks, h.phase, b);
295
- return ve(() => ({
296
- session: h,
297
- notice: A ?? (X.fallbackReason === null ? X.nothingHeard ? "hands-free-nothing-heard" : null : "hands-free-fallback"),
298
- spokenChunks: $,
299
- capturing: Z,
300
- active: h.phase !== "idle" && (h.phase !== "ended" || h.error !== null),
301
- interrupting: M,
302
- awaitingEndpoint: P,
303
- holding: I,
304
- correcting: h.correcting,
297
+ l(() => () => {
298
+ b(!1), x(!1);
299
+ }, [b, x]);
300
+ let Je = me(y.spokenChunks, _.phase, S);
301
+ return _e(() => ({
302
+ session: _,
303
+ notice: M ?? (Z.fallbackReason !== null && Z.fallbackReason !== "notice-declined" ? "hands-free-fallback" : Z.nothingHeard ? "hands-free-nothing-heard" : null),
304
+ spokenChunks: Je,
305
+ capturing: Q,
306
+ active: _.phase !== "idle" && (_.phase !== "ended" || _.error !== null),
307
+ interrupting: P,
308
+ awaitingEndpoint: Ae,
309
+ holding: L,
310
+ correcting: _.correcting,
305
311
  handsFree: {
306
- mode: X.mode,
307
- nothingHeard: X.nothingHeard,
308
- transportKind: X.transportKind,
309
- fallbackReason: X.fallbackReason
312
+ mode: Z.mode,
313
+ nothingHeard: Z.nothingHeard,
314
+ transportKind: Z.transportKind,
315
+ fallbackReason: Z.fallbackReason,
316
+ privacyNotice: Z.privacyNotice
310
317
  },
311
- available: Y.isSupported && !_.isBlocked,
312
- start: Be,
313
- end: Ve,
314
- isCurrentSession: He,
315
- toggleMute: Ge,
316
- interrupt: Pe,
317
- letMeFinish: Ue,
318
- imDone: We,
319
- announce: G,
320
- holdListening: Ae,
321
- answerLocally: je
318
+ available: X.isSupported && !y.isBlocked,
319
+ start: He,
320
+ end: Ue,
321
+ isCurrentSession: We,
322
+ toggleMute: qe,
323
+ interrupt: Fe,
324
+ letMeFinish: Ge,
325
+ imDone: Ke,
326
+ announce: K,
327
+ holdListening: je,
328
+ answerLocally: Me
322
329
  }), [
323
- h,
324
- A,
330
+ _,
325
331
  M,
326
332
  P,
327
- I,
328
- Z,
329
- X.mode,
330
- X.nothingHeard,
331
- X.transportKind,
332
- X.fallbackReason,
333
- Y.isSupported,
334
- _.isBlocked,
335
- $,
336
- Be,
337
- Ve,
333
+ Ae,
334
+ L,
335
+ Q,
336
+ Z.mode,
337
+ Z.nothingHeard,
338
+ Z.transportKind,
339
+ Z.fallbackReason,
340
+ Z.privacyNotice,
341
+ X.isSupported,
342
+ y.isBlocked,
343
+ Je,
338
344
  He,
339
- Ge,
340
- Pe,
341
345
  Ue,
342
346
  We,
343
- G,
344
- Ae,
345
- je
347
+ qe,
348
+ Fe,
349
+ Ge,
350
+ Ke,
351
+ K,
352
+ je,
353
+ Me
346
354
  ]);
347
355
  }
348
356
  //#endregion
349
- export { d as useVoiceSession };
357
+ export { we as useVoiceSession };
@@ -1,5 +1,6 @@
1
1
  import { FC, ReactNode } from 'react';
2
2
  import { AssistantAttachment } from '../../attachments';
3
+ import { HandsFreePrivacyNoticeActions } from '../../voice/handsfree/useHandsFreeInterrupt';
3
4
  import { VoiceSessionSnapshot } from '../../voice/voiceSession';
4
5
  import { VoiceSessionNotice } from '../useVoiceSession';
5
6
  import { VoiceTranscriptTurn } from '../../voice/turnVisibility';
@@ -17,6 +18,12 @@ interface Props {
17
18
  onInterrupt?: () => void;
18
19
  /** A recoverable problem to surface. Null when the microphone is healthy. */
19
20
  notice?: VoiceSessionNotice | null;
21
+ /**
22
+ * ★ BOFF-8613 H3: the backend speech stream's privacy notice, while it must
23
+ * be answered before the microphone opens. Null otherwise (always, unless an
24
+ * app configured the stream).
25
+ */
26
+ privacyNotice?: HandsFreePrivacyNoticeActions | null;
20
27
  /** The assistant's last reply, captioned while it is spoken. */
21
28
  spoken: string | null;
22
29
  onToggleMute: () => void;
@@ -1 +1 @@
1
- {"version":3,"file":"AssistantVoiceSession.d.ts","sourceRoot":"","sources":["../../../../../src/shared/assistant/ui/voice/AssistantVoiceSession.tsx"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,EAAE,EACP,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAMf,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAyB7D,OAAO,EAEL,KAAK,oBAAoB,EAC1B,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEtE,gFAAgF;AAChF,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;AAElD,UAAU,KAAK;IACb,OAAO,EAAE,oBAAoB,CAAC;IAC9B,iEAAiE;IACjE,KAAK,CAAC,EAAE,aAAa,CAAC,mBAAmB,CAAC,CAAC;IAC3C,wCAAwC;IACxC,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B,6EAA6E;IAC7E,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B,uCAAuC;IACvC,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,6EAA6E;IAC7E,MAAM,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACnC,gEAAgE;IAChE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACpC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI,KAAK,IAAI,CAAC;IACjD,kBAAkB,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,iBAAiB,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,0EAA0E;IAC1E,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,4DAA4D;IAC5D,YAAY,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC1D,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,mFAAmF;IACnF,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,0EAA0E;IAC1E,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,6DAA6D;IAC7D,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,+DAA+D;IAC/D,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,oDAAoD;IACpD,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB;;;;;OAKG;IACH,YAAY,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;IAC5D,6EAA6E;IAC7E,YAAY,CAAC,EAAE;QACb,OAAO,EAAE,SAAS,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,OAAO,EAAE,MAAM,IAAI,CAAC;KACrB,GAAG,IAAI,CAAC;CACV;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,qBAAqB,EAAE,EAAE,CAAC,KAAK,CA60B3C,CAAC"}
1
+ {"version":3,"file":"AssistantVoiceSession.d.ts","sourceRoot":"","sources":["../../../../../src/shared/assistant/ui/voice/AssistantVoiceSession.tsx"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,EAAE,EACP,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAMf,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAS7D,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,6CAA6C,CAAC;AAqBjG,OAAO,EAEL,KAAK,oBAAoB,EAC1B,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEtE,gFAAgF;AAChF,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;AAElD,UAAU,KAAK;IACb,OAAO,EAAE,oBAAoB,CAAC;IAC9B,iEAAiE;IACjE,KAAK,CAAC,EAAE,aAAa,CAAC,mBAAmB,CAAC,CAAC;IAC3C,wCAAwC;IACxC,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B,6EAA6E;IAC7E,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;IAC9B,uCAAuC;IACvC,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;IACzB,6EAA6E;IAC7E,MAAM,CAAC,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACnC;;;;OAIG;IACH,aAAa,CAAC,EAAE,6BAA6B,GAAG,IAAI,CAAC;IACrD,gEAAgE;IAChE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,YAAY,EAAE,MAAM,IAAI,CAAC;IACzB;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,mBAAmB,EAAE,CAAC;IACpC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI,KAAK,IAAI,CAAC;IACjD,kBAAkB,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC1C,iBAAiB,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,0EAA0E;IAC1E,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,4DAA4D;IAC5D,YAAY,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC1D,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,mFAAmF;IACnF,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,0EAA0E;IAC1E,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,6DAA6D;IAC7D,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,+DAA+D;IAC/D,aAAa,CAAC,EAAE,MAAM,IAAI,CAAC;IAC3B,oDAAoD;IACpD,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IACtB;;;;;OAKG;IACH,YAAY,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;IAC5D,6EAA6E;IAC7E,YAAY,CAAC,EAAE;QACb,OAAO,EAAE,SAAS,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,OAAO,EAAE,MAAM,IAAI,CAAC;KACrB,GAAG,IAAI,CAAC;CACV;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,qBAAqB,EAAE,EAAE,CAAC,KAAK,CA41B3C,CAAC"}