@burdenoff/fe-libs 2026.1007.2 → 2026.1007.4

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 (38) hide show
  1. package/dist/shared/assistant/i18nManifest.d.ts +3 -0
  2. package/dist/shared/assistant/i18nManifest.d.ts.map +1 -1
  3. package/dist/shared/assistant/i18nManifest.js +3 -0
  4. package/dist/shared/assistant/index.d.ts +2 -0
  5. package/dist/shared/assistant/index.d.ts.map +1 -1
  6. package/dist/shared/assistant/store.d.ts +10 -0
  7. package/dist/shared/assistant/store.d.ts.map +1 -1
  8. package/dist/shared/assistant/store.js +19 -8
  9. package/dist/shared/assistant/ui/AssistantChatArea.d.ts.map +1 -1
  10. package/dist/shared/assistant/ui/AssistantChatArea.js +1070 -1067
  11. package/dist/shared/assistant/ui/useVoiceSession.d.ts +14 -1
  12. package/dist/shared/assistant/ui/useVoiceSession.d.ts.map +1 -1
  13. package/dist/shared/assistant/ui/useVoiceSession.js +241 -233
  14. package/dist/shared/assistant/ui/voice/AssistantVoiceSession.d.ts +7 -0
  15. package/dist/shared/assistant/ui/voice/AssistantVoiceSession.d.ts.map +1 -1
  16. package/dist/shared/assistant/ui/voice/AssistantVoiceSession.js +137 -130
  17. package/dist/shared/assistant/ui/voice/HandsFreePrivacyNotice.d.ts +27 -0
  18. package/dist/shared/assistant/ui/voice/HandsFreePrivacyNotice.d.ts.map +1 -0
  19. package/dist/shared/assistant/ui/voice/HandsFreePrivacyNotice.js +52 -0
  20. package/dist/shared/assistant/voice/handsfree/backendStreamTransport.d.ts +29 -6
  21. package/dist/shared/assistant/voice/handsfree/backendStreamTransport.d.ts.map +1 -1
  22. package/dist/shared/assistant/voice/handsfree/backendStreamTransport.js +138 -63
  23. package/dist/shared/assistant/voice/handsfree/handsFreeController.d.ts +7 -1
  24. package/dist/shared/assistant/voice/handsfree/handsFreeController.d.ts.map +1 -1
  25. package/dist/shared/assistant/voice/handsfree/handsFreeRuntime.d.ts +18 -10
  26. package/dist/shared/assistant/voice/handsfree/handsFreeRuntime.d.ts.map +1 -1
  27. package/dist/shared/assistant/voice/handsfree/handsFreeRuntime.js +46 -57
  28. package/dist/shared/assistant/voice/handsfree/streamingConfig.d.ts +103 -0
  29. package/dist/shared/assistant/voice/handsfree/streamingConfig.d.ts.map +1 -0
  30. package/dist/shared/assistant/voice/handsfree/streamingConfig.js +71 -0
  31. package/dist/shared/assistant/voice/handsfree/sttTransport.d.ts +12 -7
  32. package/dist/shared/assistant/voice/handsfree/sttTransport.d.ts.map +1 -1
  33. package/dist/shared/assistant/voice/handsfree/sttTransport.js +1 -1
  34. package/dist/shared/assistant/voice/handsfree/useHandsFreeInterrupt.d.ts +23 -1
  35. package/dist/shared/assistant/voice/handsfree/useHandsFreeInterrupt.d.ts.map +1 -1
  36. package/dist/shared/assistant/voice/handsfree/useHandsFreeInterrupt.js +63 -50
  37. package/dist/shared-assistant.js +189 -187
  38. package/package.json +3 -3
@@ -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"}
@@ -12,245 +12,252 @@ import { VoiceMiniController as ce } from "./VoiceMiniController.js";
12
12
  import { VoiceStage as le } from "./VoiceStage.js";
13
13
  import { VoiceTranscriptDrawer as ue } from "./VoiceTranscriptDrawer.js";
14
14
  import { escapeBelongsToLayerAbove as de, voiceSessionEscapeAction as fe } from "./voiceSessionEscape.js";
15
- import { useCallback as s, useEffect as c, useMemo as pe, useRef as l, useState as u } from "react";
16
- import { Maximize2 as me, Minimize2 as he, ScrollText as ge, X as d } from "lucide-react";
15
+ import { HandsFreePrivacyNotice as pe } from "./HandsFreePrivacyNotice.js";
16
+ import { useCallback as s, useEffect as c, useMemo as me, useRef as l, useState as u } from "react";
17
+ import { Maximize2 as he, Minimize2 as ge, ScrollText as _e, X as d } from "lucide-react";
17
18
  import { jsx as f, jsxs as p } from "react/jsx-runtime";
18
19
  //#region src/shared/assistant/ui/voice/AssistantVoiceSession.tsx
19
- var m = ({ session: m, turns: ye = [], onSaveTranscript: be, onContinueInChat: xe, notice: h = null, spoken: g, onInterrupt: Se, onToggleMute: _, attachments: v = [], onAttachFiles: y, onRemoveAttachment: Ce, onRetryAttachment: we, canAttachMore: Te = !0, preparingAttachments: b = 0, spokenChunks: x = null, onEnd: S, capturing: Ee = !0, interrupting: De = !1, awaitingEndpoint: Oe = !1, holding: C = !1, correcting: ke = !1, onLetMeFinish: w, onImDone: T, proposalChip: E = null, proposalTray: D = null }) => {
20
- let O = n(), { muted: k, error: A } = m, j = l(null), M = l(null), [N, P] = u("mini"), F = N === "full", I = N === "mini", L = N === "mini" ? "panel" : N === "panel" ? "full" : "mini", [R, z] = u(!1);
21
- t("assistant.transcript", pe(() => ({ run: () => R ? { status: "already" } : (z(!0), { status: "done" }) }), [R]));
22
- let B = D !== null && !I, V = l(!1), H = l(_);
23
- H.current = _;
24
- let U = s(() => {
25
- m.phase !== "listening" && m.phase !== "thinking" || k || V.current || o(m) || (V.current = !0, H.current());
26
- }, [k, m]), W = s(() => {
27
- V.current && (V.current = !1, H.current());
28
- }, []), Ae = U;
20
+ var m = ({ session: m, turns: be = [], onSaveTranscript: xe, onContinueInChat: Se, notice: h = null, privacyNotice: g = null, spoken: _, onInterrupt: Ce, onToggleMute: v, attachments: y = [], onAttachFiles: b, onRemoveAttachment: we, onRetryAttachment: Te, canAttachMore: Ee = !0, preparingAttachments: x = 0, spokenChunks: S = null, onEnd: C, capturing: De = !0, interrupting: Oe = !1, awaitingEndpoint: ke = !1, holding: w = !1, correcting: Ae = !1, onLetMeFinish: T, onImDone: E, proposalChip: D = null, proposalTray: O = null }) => {
21
+ let k = n(), { muted: A, error: j } = m, M = l(null), N = l(null), [P, F] = u("mini"), I = P === "full", L = P === "mini", R = P === "mini" ? "panel" : P === "panel" ? "full" : "mini", [z, B] = u(!1);
22
+ t("assistant.transcript", me(() => ({ run: () => z ? { status: "already" } : (B(!0), { status: "done" }) }), [z]));
23
+ let V = O !== null && !L, H = l(!1), U = l(v);
24
+ U.current = v;
25
+ let W = s(() => {
26
+ m.phase !== "listening" && m.phase !== "thinking" || A || H.current || o(m) || (H.current = !0, U.current());
27
+ }, [A, m]), G = s(() => {
28
+ H.current && (H.current = !1, U.current());
29
+ }, []), je = W;
29
30
  c(() => {
30
31
  let e = () => {
31
- document.visibilityState === "hidden" ? U() : W();
32
+ document.visibilityState === "hidden" ? W() : G();
32
33
  };
33
34
  return document.addEventListener("visibilitychange", e), () => document.removeEventListener("visibilitychange", e);
34
- }, [U, W]), c(() => {
35
- let e = W;
35
+ }, [W, G]), c(() => {
36
+ let e = G;
36
37
  return window.addEventListener("focus", e), () => {
37
- window.removeEventListener("focus", e), V.current = !1;
38
+ window.removeEventListener("focus", e), H.current = !1;
38
39
  };
39
40
  }, []), c(() => {
40
- j.current?.focus();
41
- }, []), e(M, { fallbackSelector: `[${ae}]` }), c(() => {
41
+ document.activeElement?.closest("[data-hands-free-notice]") || M.current?.focus();
42
+ }, []), e(N, { fallbackSelector: `[${ae}]` }), c(() => {
42
43
  let e = (e) => {
43
44
  if (e.key === "Escape") {
44
45
  let t = fe({
45
46
  defaultPrevented: e.defaultPrevented,
46
47
  layerAbove: de({
47
48
  target: e.target,
48
- session: M.current,
49
+ session: N.current,
49
50
  doc: document
50
51
  }),
51
- transcriptOpen: R
52
+ transcriptOpen: z
52
53
  });
53
54
  if (t === "ignore") return;
54
- e.preventDefault(), t === "close-transcript" ? z(!1) : B ? D?.onClose() : S();
55
+ e.preventDefault(), t === "close-transcript" ? B(!1) : g ? g.decline() : V ? O?.onClose() : C();
55
56
  return;
56
57
  }
57
- if (e.key !== "Tab" || !F) return;
58
- let t = (R ? M.current?.querySelector("[data-testid=\"assistant-voice-transcript\"]") : M.current)?.querySelectorAll("button:not([disabled])");
58
+ if (e.key !== "Tab" || !I) return;
59
+ let t = (z ? N.current?.querySelector("[data-testid=\"assistant-voice-transcript\"]") : N.current)?.querySelectorAll("button:not([disabled])");
59
60
  if (!t || t.length === 0) return;
60
61
  let n = t[0], r = t[t.length - 1];
61
62
  !n || !r || (e.shiftKey && document.activeElement === n ? (e.preventDefault(), r.focus()) : !e.shiftKey && document.activeElement === r && (e.preventDefault(), n.focus()));
62
63
  };
63
64
  return window.addEventListener("keydown", e), () => window.removeEventListener("keydown", e);
64
65
  }, [
65
- S,
66
- F,
67
- R,
68
- B,
69
- D
66
+ C,
67
+ I,
68
+ z,
69
+ V,
70
+ O,
71
+ g
70
72
  ]);
71
- let G = h !== null && A === null, K = o(m), q = w && T && m.phase === "listening" && !k && A === null ? {
72
- letMeFinish: w,
73
- imDone: T
74
- } : null, J = q !== null;
73
+ let K = h !== null && j === null, q = o(m), J = T && E && m.phase === "listening" && !A && j === null ? {
74
+ letMeFinish: T,
75
+ imDone: E
76
+ } : null, Y = J !== null;
75
77
  c(() => {
76
- if (J) return;
78
+ if (Y) return;
77
79
  let e = document.activeElement;
78
- (!e || e === document.body) && j.current?.focus();
79
- }, [J]);
80
- let Y = i({
80
+ (!e || e === document.body) && M.current?.focus();
81
+ }, [Y]);
82
+ let X = i({
81
83
  snapshot: m,
82
- capturing: Ee,
83
- interrupting: De,
84
- awaitingEndpoint: Oe
85
- }), je = (() => {
86
- switch (Y) {
87
- case "connecting": return O("voiceSession.connecting", "Starting the microphone…");
88
- case "endpoint-grace": return O("voiceSession.endpointGrace", "Still listening — take your time");
89
- case "interrupting": return O("voiceSession.interrupting", "Stopped — go ahead");
90
- case "thinking": return O(a.key, a.fallback);
91
- case "speaking": return O("voiceSession.speaking", "Speaking — tap to stop");
84
+ capturing: De,
85
+ interrupting: Oe,
86
+ awaitingEndpoint: ke
87
+ }), Me = (() => {
88
+ switch (X) {
89
+ case "connecting": return k("voiceSession.connecting", "Starting the microphone…");
90
+ case "endpoint-grace": return k("voiceSession.endpointGrace", "Still listening — take your time");
91
+ case "interrupting": return k("voiceSession.interrupting", "Stopped — go ahead");
92
+ case "thinking": return k(a.key, a.fallback);
93
+ case "speaking": return k("voiceSession.speaking", "Speaking — tap to stop");
92
94
  case "mic-error":
93
95
  case "ended": return "";
94
- case "listening": return k ? O("voiceSession.muted", "Microphone off") : O("voiceSession.listening", "Listening…");
95
- default: return Y;
96
+ case "listening": return A ? k("voiceSession.muted", "Microphone off") : k("voiceSession.listening", "Listening…");
97
+ default: return X;
96
98
  }
97
- })(), X = !k && (Y === "listening" || Y === "endpoint-grace"), Z = X && C ? O("voiceSession.holding", "Take your time — tap “I’m done” when you finish") : X && ke ? O("voiceSession.correcting", "Stopped that answer — listening to your correction") : je, Q = ne({
98
- tr: O,
99
- stage: Y,
100
- muted: k,
101
- label: Z
102
- }), $ = te(Z, Q), Me = Y === "thinking";
99
+ })(), Z = !A && (X === "listening" || X === "endpoint-grace"), Q = Z && w ? k("voiceSession.holding", "Take your time — tap “I’m done” when you finish") : Z && Ae ? k("voiceSession.correcting", "Stopped that answer — listening to your correction") : Me, $ = ne({
100
+ tr: k,
101
+ stage: X,
102
+ muted: A,
103
+ label: Q
104
+ }), Ne = te(Q, $), Pe = X === "thinking";
103
105
  return /* @__PURE__ */ p("div", {
104
- ref: M,
105
- className: `flex flex-col items-center justify-between bg-bg-sunken ${N === "full" ? "fixed inset-x-0 bottom-0 top-14 z-[60] px-6 py-8" : N === "panel" ? "absolute inset-0 z-20 px-4 py-6" : "absolute inset-x-0 bottom-0 z-20 h-[11.25rem] border-t border-border-subtle px-3 py-3 shadow-lg"}`,
106
+ ref: N,
107
+ className: `flex flex-col items-center justify-between bg-bg-sunken ${P === "full" ? "fixed inset-x-0 bottom-0 top-14 z-[60] px-6 py-8" : P === "panel" ? "absolute inset-0 z-20 px-4 py-6" : "absolute inset-x-0 bottom-0 z-20 h-[11.25rem] border-t border-border-subtle px-3 py-3 shadow-lg"}`,
106
108
  role: "dialog",
107
- "aria-modal": F || void 0,
108
- "aria-label": O("voiceSession.title", "Voice conversation"),
109
+ "aria-modal": I || void 0,
110
+ "aria-label": k("voiceSession.title", "Voice conversation"),
109
111
  "data-testid": "assistant-voice-session",
110
112
  [oe]: "",
111
113
  children: [
112
114
  /* @__PURE__ */ p("button", {
113
- ref: j,
115
+ ref: M,
114
116
  type: "button",
115
- onClick: S,
116
- className: `absolute ${F ? "right-6 top-6 h-14 gap-2 px-5 text-base" : I ? "right-12 top-2 h-8 gap-1.5 px-2.5 text-xs" : "right-3 top-3 h-11 gap-2 px-4 text-sm"} flex items-center justify-center rounded-full border border-border-default bg-bg-elevated text-text-secondary hover:bg-bg-sunken transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong`,
117
- title: O("voiceSession.end", "End the voice conversation"),
117
+ onClick: C,
118
+ className: `absolute ${I ? "right-6 top-6 h-14 gap-2 px-5 text-base" : L ? "right-12 top-2 h-8 gap-1.5 px-2.5 text-xs" : "right-3 top-3 h-11 gap-2 px-4 text-sm"} flex items-center justify-center rounded-full border border-border-default bg-bg-elevated text-text-secondary hover:bg-bg-sunken transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong`,
119
+ title: k("voiceSession.end", "End the voice conversation"),
118
120
  "data-testid": "assistant-voice-end",
119
121
  children: [/* @__PURE__ */ f(d, {
120
- className: F ? "size-6" : I ? "size-4" : "size-5",
122
+ className: I ? "size-6" : L ? "size-4" : "size-5",
121
123
  "aria-hidden": "true"
122
124
  }), /* @__PURE__ */ f("span", {
123
- className: `truncate whitespace-nowrap font-medium ${I ? "max-w-[3.5rem] text-xs" : "max-w-[7rem]"}`,
124
- children: O("voiceSession.endShort", "End")
125
+ className: `truncate whitespace-nowrap font-medium ${L ? "max-w-[3.5rem] text-xs" : "max-w-[7rem]"}`,
126
+ children: k("voiceSession.endShort", "End")
125
127
  })]
126
128
  }),
127
129
  /* @__PURE__ */ f("div", {
128
- className: `flex flex-col items-center ${I ? "px-3" : `min-h-[1.5rem] ${G ? F ? "pt-14" : "pt-10" : ""}`}`,
129
- children: G ? /* @__PURE__ */ f("p", {
130
+ className: `flex flex-col items-center ${L ? "px-3" : `min-h-[1.5rem] ${K ? I ? "pt-14" : "pt-10" : ""}`}`,
131
+ children: K ? /* @__PURE__ */ f("p", {
130
132
  className: "max-w-xs text-center text-xs text-status-warning",
131
133
  "data-testid": "assistant-voice-notice",
132
- children: _e(h, O)
134
+ children: ve(h, k)
133
135
  }) : null
134
136
  }),
135
137
  (() => {
136
138
  let e = /* @__PURE__ */ f(se, {
137
139
  session: m,
138
- compact: I,
139
- connecting: Y === "connecting",
140
- onPress: r(Y) ? Se : _,
141
- label: r(Y) ? O("voiceSession.interrupt", "Stop the assistant and speak") : k ? O("voiceSession.unmute", "Turn the microphone on") : O("voiceSession.mute", "Turn the microphone off")
142
- }), t = q ? /* @__PURE__ */ f("button", {
140
+ compact: L,
141
+ connecting: X === "connecting",
142
+ onPress: r(X) ? Ce : v,
143
+ label: r(X) ? k("voiceSession.interrupt", "Stop the assistant and speak") : A ? k("voiceSession.unmute", "Turn the microphone on") : k("voiceSession.mute", "Turn the microphone off")
144
+ }), t = J ? /* @__PURE__ */ f("button", {
143
145
  type: "button",
144
- onClick: C ? q.imDone : q.letMeFinish,
145
- className: `flex items-center justify-center rounded-full border font-medium transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong ${I ? "h-7 px-3 text-xs" : F ? "h-11 px-6 text-base" : "h-9 px-4 text-sm"} ${C ? "border-transparent bg-action-primary-bg text-action-primary-text hover:opacity-90" : "border-border-default bg-bg-elevated text-text-secondary hover:bg-bg-sunken"}`,
146
- title: C ? O("voiceSession.imDoneHint", "Send what you said now") : O("voiceSession.letMeFinishHint", "Pause sending until you tap “I’m done”"),
146
+ onClick: w ? J.imDone : J.letMeFinish,
147
+ className: `flex items-center justify-center rounded-full border font-medium transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong ${L ? "h-7 px-3 text-xs" : I ? "h-11 px-6 text-base" : "h-9 px-4 text-sm"} ${w ? "border-transparent bg-action-primary-bg text-action-primary-text hover:opacity-90" : "border-border-default bg-bg-elevated text-text-secondary hover:bg-bg-sunken"}`,
148
+ title: w ? k("voiceSession.imDoneHint", "Send what you said now") : k("voiceSession.letMeFinishHint", "Pause sending until you tap “I’m done”"),
147
149
  "data-testid": "assistant-voice-hold",
148
- "data-holding": C ? "true" : "false",
149
- children: C ? O("voiceSession.imDone", "I’m done") : O("voiceSession.letMeFinish", "Let me finish")
150
+ "data-holding": w ? "true" : "false",
151
+ children: w ? k("voiceSession.imDone", "I’m done") : k("voiceSession.letMeFinish", "Let me finish")
150
152
  }) : null, n = t ? /* @__PURE__ */ p("div", {
151
153
  className: "flex flex-col items-center gap-2",
152
154
  children: [e, t]
153
- }) : e, i = ee(Y) ? g : K || null, a = A === null ? null : ve(A, O);
154
- return I ? /* @__PURE__ */ f(ce, {
155
- spokenChunks: x,
156
- state: Y,
155
+ }) : e, i = ee(X) ? _ : q || null, a = j === null ? null : ye(j, k);
156
+ return L ? /* @__PURE__ */ f(ce, {
157
+ spokenChunks: S,
158
+ state: X,
157
159
  caption: i,
158
- statusText: $,
159
- statusSuffix: Q,
160
- rotateStatus: Me,
160
+ statusText: Ne,
161
+ statusSuffix: $,
162
+ rotateStatus: Pe,
161
163
  errorText: a,
162
164
  control: n
163
165
  }) : /* @__PURE__ */ f(le, {
164
- state: Y,
165
- userCaption: K || null,
166
- spokenChunks: x,
167
- assistantCaption: g,
168
- expanded: F,
169
- statusText: $,
170
- statusSuffix: Q,
171
- rotateStatus: Me,
166
+ state: X,
167
+ userCaption: q || null,
168
+ spokenChunks: S,
169
+ assistantCaption: _,
170
+ expanded: I,
171
+ statusText: Ne,
172
+ statusSuffix: $,
173
+ rotateStatus: Pe,
172
174
  errorText: a,
173
175
  control: n
174
176
  });
175
177
  })(),
176
- E && !B ? /* @__PURE__ */ f("div", {
177
- className: I ? "absolute left-20 right-36 top-2 flex justify-center" : `flex w-full justify-center ${F ? "max-w-[calc(100%-12rem)]" : "max-w-[calc(100%-8rem)]"}`,
178
+ D && !V ? /* @__PURE__ */ f("div", {
179
+ className: L ? "absolute left-20 right-36 top-2 flex justify-center" : `flex w-full justify-center ${I ? "max-w-[calc(100%-12rem)]" : "max-w-[calc(100%-8rem)]"}`,
178
180
  children: /* @__PURE__ */ f("button", {
179
181
  type: "button",
180
182
  onClick: () => {
181
- P("panel"), E.onOpen();
183
+ F("panel"), D.onOpen();
182
184
  },
183
- className: `max-w-full truncate rounded-full border border-border-default bg-bg-elevated font-medium text-text-primary transition-colors hover:bg-bg-raised focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong ${I ? "h-8 px-3 text-xs" : "h-10 px-4 text-sm"}`,
185
+ className: `max-w-full truncate rounded-full border border-border-default bg-bg-elevated font-medium text-text-primary transition-colors hover:bg-bg-raised focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong ${L ? "h-8 px-3 text-xs" : "h-10 px-4 text-sm"}`,
184
186
  "data-testid": "assistant-voice-proposal-chip",
185
- children: E.label
187
+ children: D.label
186
188
  })
187
189
  }) : null,
188
- D && B ? /* @__PURE__ */ p("div", {
189
- className: `absolute z-10 flex flex-col gap-2 overflow-y-auto rounded-lg border border-border-subtle bg-bg-elevated shadow-lg ${F ? "inset-x-6 bottom-24 top-24 mx-auto max-w-xl p-4" : "inset-x-3 bottom-16 top-16 p-3"}`,
190
+ O && V ? /* @__PURE__ */ p("div", {
191
+ className: `absolute z-10 flex flex-col gap-2 overflow-y-auto rounded-lg border border-border-subtle bg-bg-elevated shadow-lg ${I ? "inset-x-6 bottom-24 top-24 mx-auto max-w-xl p-4" : "inset-x-3 bottom-16 top-16 p-3"}`,
190
192
  "data-testid": "assistant-voice-proposal-tray",
191
193
  children: [/* @__PURE__ */ f("div", {
192
194
  className: "flex justify-end",
193
195
  children: /* @__PURE__ */ f("button", {
194
196
  type: "button",
195
- onClick: D.onClose,
197
+ onClick: O.onClose,
196
198
  className: "flex size-8 items-center justify-center rounded-full text-text-secondary transition-colors hover:bg-bg-raised hover:text-text-primary focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong",
197
- "aria-label": D.closeLabel,
199
+ "aria-label": O.closeLabel,
198
200
  "data-testid": "assistant-voice-proposal-tray-close",
199
201
  children: /* @__PURE__ */ f(d, {
200
202
  className: "size-4",
201
203
  "aria-hidden": "true"
202
204
  })
203
205
  })
204
- }), D.content]
206
+ }), O.content]
205
207
  }) : null,
206
- R ? /* @__PURE__ */ f(ue, {
207
- turns: ye,
208
- onClose: () => z(!1),
209
- onSave: be,
210
- onContinueInChat: xe
208
+ g ? /* @__PURE__ */ f(pe, {
209
+ view: P,
210
+ onContinue: g.accept,
211
+ onNotNow: g.decline
211
212
  }) : null,
212
- y ? /* @__PURE__ */ f("div", {
213
- className: `absolute ${F ? "left-6 top-6" : I ? "left-11 top-2" : "left-3 top-3"}`,
213
+ z ? /* @__PURE__ */ f(ue, {
214
+ turns: be,
215
+ onClose: () => B(!1),
216
+ onSave: xe,
217
+ onContinueInChat: Se
218
+ }) : null,
219
+ b ? /* @__PURE__ */ f("div", {
220
+ className: `absolute ${I ? "left-6 top-6" : L ? "left-11 top-2" : "left-3 top-3"}`,
214
221
  children: /* @__PURE__ */ f(re, {
215
222
  onFiles: (e) => {
216
- y(e), P((e) => e === "mini" ? "panel" : e);
223
+ b(e), F((e) => e === "mini" ? "panel" : e);
217
224
  },
218
- onPickerOpen: Ae,
225
+ onPickerOpen: je,
219
226
  direction: "down",
220
- canAddMore: Te
227
+ canAddMore: Ee
221
228
  })
222
229
  }) : null,
223
- (v.length > 0 || b > 0) && !I ? /* @__PURE__ */ f("div", {
224
- className: `absolute ${F ? "bottom-24 left-24 right-24" : "bottom-16 left-16 right-16"}`,
230
+ (y.length > 0 || x > 0) && !L ? /* @__PURE__ */ f("div", {
231
+ className: `absolute ${I ? "bottom-24 left-24 right-24" : "bottom-16 left-16 right-16"}`,
225
232
  "data-testid": "assistant-voice-attachments",
226
233
  children: /* @__PURE__ */ f(ie, {
227
- attachments: v,
228
- onRemove: Ce ?? (() => void 0),
229
- onRetry: we ?? (() => void 0),
230
- preparingCount: b
234
+ attachments: y,
235
+ onRemove: we ?? (() => void 0),
236
+ onRetry: Te ?? (() => void 0),
237
+ preparingCount: x
231
238
  })
232
239
  }) : null,
233
240
  /* @__PURE__ */ f("button", {
234
241
  type: "button",
235
- onClick: () => z((e) => !e),
236
- className: `absolute ${F ? "bottom-6 right-6 size-14" : I ? "right-2 top-2 size-8" : "bottom-3 right-3 size-11"} flex items-center justify-center rounded-full bg-bg-elevated text-text-secondary transition-colors hover:bg-bg-raised hover:text-text-primary focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong`,
237
- "aria-pressed": R,
238
- "aria-label": O("voiceSession.transcriptTitle", "Voice transcript"),
242
+ onClick: () => B((e) => !e),
243
+ className: `absolute ${I ? "bottom-6 right-6 size-14" : L ? "right-2 top-2 size-8" : "bottom-3 right-3 size-11"} flex items-center justify-center rounded-full bg-bg-elevated text-text-secondary transition-colors hover:bg-bg-raised hover:text-text-primary focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong`,
244
+ "aria-pressed": z,
245
+ "aria-label": k("voiceSession.transcriptTitle", "Voice transcript"),
239
246
  "data-testid": "assistant-voice-transcript-toggle",
240
- children: /* @__PURE__ */ f(ge, { className: F ? "size-6" : I ? "size-4" : "size-5" })
247
+ children: /* @__PURE__ */ f(_e, { className: I ? "size-6" : L ? "size-4" : "size-5" })
241
248
  }),
242
249
  /* @__PURE__ */ f("button", {
243
250
  type: "button",
244
- onClick: () => P(L),
245
- className: `absolute ${F ? "bottom-6 left-6 size-14" : I ? "left-2 top-2 size-8" : "bottom-3 left-3 size-11"} flex items-center justify-center rounded-full bg-bg-elevated text-text-secondary transition-colors hover:bg-bg-raised hover:text-text-primary focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong`,
246
- "aria-label": L === "panel" ? O("voiceSession.expandPanel", "Show the conversation in the panel") : L === "full" ? O("voiceSession.expand", "Expand the conversation to full screen") : O("voiceSession.collapse", "Shrink to the compact controller"),
251
+ onClick: () => F(R),
252
+ className: `absolute ${I ? "bottom-6 left-6 size-14" : L ? "left-2 top-2 size-8" : "bottom-3 left-3 size-11"} flex items-center justify-center rounded-full bg-bg-elevated text-text-secondary transition-colors hover:bg-bg-raised hover:text-text-primary focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong`,
253
+ "aria-label": R === "panel" ? k("voiceSession.expandPanel", "Show the conversation in the panel") : R === "full" ? k("voiceSession.expand", "Expand the conversation to full screen") : k("voiceSession.collapse", "Shrink to the compact controller"),
247
254
  "data-testid": "assistant-voice-expand",
248
- children: F ? /* @__PURE__ */ f(he, { className: "size-5" }) : /* @__PURE__ */ f(me, { className: I ? "size-4" : "size-5" })
255
+ children: I ? /* @__PURE__ */ f(ge, { className: "size-5" }) : /* @__PURE__ */ f(he, { className: L ? "size-4" : "size-5" })
249
256
  })
250
257
  ]
251
258
  });
252
259
  };
253
- function _e(e, t) {
260
+ function ve(e, t) {
254
261
  switch (e) {
255
262
  case "network": return t("voiceSession.noticeNetwork", "Speech recognition lost its connection. Check your network — it will retry.");
256
263
  case "not-capturing": return t("voiceSession.noticeNotCapturing", "The microphone did not start. Check that this site is allowed to use it, then try again.");
@@ -261,7 +268,7 @@ function _e(e, t) {
261
268
  default: return e;
262
269
  }
263
270
  }
264
- function ve(e, t) {
271
+ function ye(e, t) {
265
272
  switch (e) {
266
273
  case "mic-denied": return t("voiceSession.micDenied", "Microphone access is blocked. Allow it in your browser settings to talk.");
267
274
  case "no-speech-support": return t("voiceSession.noSpeechSupport", "This browser cannot listen. Try a different browser, or type instead.");
@@ -0,0 +1,27 @@
1
+ import { FC } from 'react';
2
+ import { VoiceView } from './AssistantVoiceSession';
3
+ /** Marks the notice, so the session does not move focus off it when they open together. */
4
+ export declare const HANDS_FREE_NOTICE_ATTR = "data-hands-free-notice";
5
+ interface Props {
6
+ /** Continue: remember the answer for this profile, then open the microphone. */
7
+ onContinue: () => void;
8
+ /** Not now: hands-free stays off for this conversation; tap-to-talk still works. */
9
+ onNotNow: () => void;
10
+ view: VoiceView;
11
+ }
12
+ /**
13
+ * The backend speech stream's privacy notice (BOFF-8613, H3).
14
+ *
15
+ * Shown inside the voice session BEFORE the microphone first opens on the
16
+ * backend stream, and only then: with that transport the person's voice leaves
17
+ * the device for Google Cloud Speech-to-Text, which neither the setting's
18
+ * tooltip (phones never show a `title`) nor anything else said.
19
+ *
20
+ * ★ A card with two real buttons, not a tooltip or a toast: it is visible on a
21
+ * phone in every size of the session (the docked strip included), it takes
22
+ * focus so a screen reader announces it, and nothing is captured until one of
23
+ * the buttons is pressed. Escape in the session answers "Not now".
24
+ */
25
+ export declare const HandsFreePrivacyNotice: FC<Props>;
26
+ export {};
27
+ //# sourceMappingURL=HandsFreePrivacyNotice.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HandsFreePrivacyNotice.d.ts","sourceRoot":"","sources":["../../../../../src/shared/assistant/ui/voice/HandsFreePrivacyNotice.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA4B,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAE1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEzD,2FAA2F;AAC3F,eAAO,MAAM,sBAAsB,2BAA2B,CAAC;AAE/D,UAAU,KAAK;IACb,gFAAgF;IAChF,UAAU,EAAE,MAAM,IAAI,CAAC;IACvB,oFAAoF;IACpF,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,IAAI,EAAE,SAAS,CAAC;CACjB;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,sBAAsB,EAAE,EAAE,CAAC,KAAK,CA2E5C,CAAC"}
@@ -0,0 +1,52 @@
1
+ import { useAssistantTr as e } from "../../i18n.js";
2
+ import { useEffect as t, useId as n, useRef as r } from "react";
3
+ import { jsx as i, jsxs as a } from "react/jsx-runtime";
4
+ //#region src/shared/assistant/ui/voice/HandsFreePrivacyNotice.tsx
5
+ var o = "data-hands-free-notice", s = ({ onContinue: o, onNotNow: s, view: c }) => {
6
+ let l = e(), u = n(), d = n(), f = r(null);
7
+ t(() => {
8
+ f.current?.focus();
9
+ }, []);
10
+ let p = c === "mini";
11
+ return /* @__PURE__ */ a("div", {
12
+ role: "dialog",
13
+ "aria-modal": "false",
14
+ "aria-labelledby": u,
15
+ "aria-describedby": d,
16
+ className: `absolute z-20 flex flex-col overflow-y-auto rounded-lg border border-border-subtle bg-bg-elevated text-text-primary shadow-lg ${p ? "inset-2 gap-1.5 p-2.5" : c === "full" ? "inset-x-6 top-24 mx-auto max-w-md gap-3 p-5" : "inset-x-3 top-16 gap-2 p-4"}`,
17
+ "data-testid": "assistant-voice-privacy-notice",
18
+ "data-hands-free-notice": "",
19
+ children: [
20
+ /* @__PURE__ */ i("p", {
21
+ id: u,
22
+ className: `font-medium ${p ? "text-xs" : "text-sm"}`,
23
+ children: l("voice.handsFreeLabel", "Hands-free interrupt (beta)")
24
+ }),
25
+ /* @__PURE__ */ i("p", {
26
+ id: d,
27
+ className: `text-text-secondary ${p ? "text-xs" : "text-sm"}`,
28
+ "data-testid": "assistant-voice-privacy-notice-body",
29
+ children: l("voiceSession.streamNoticeBody", "Your voice is sent to Google Cloud Speech-to-Text and processed in the EU. We don't store the audio.")
30
+ }),
31
+ /* @__PURE__ */ a("div", {
32
+ className: `flex flex-wrap justify-end ${p ? "gap-2" : "gap-3"}`,
33
+ children: [/* @__PURE__ */ i("button", {
34
+ type: "button",
35
+ onClick: s,
36
+ className: `flex items-center justify-center rounded-full border border-border-default bg-bg-elevated font-medium text-text-secondary transition-colors hover:bg-bg-sunken focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong ${p ? "h-7 px-3 text-xs" : "h-9 px-4 text-sm"}`,
37
+ "data-testid": "assistant-voice-privacy-notice-not-now",
38
+ children: l("voiceSession.streamNoticeNotNow", "Not now")
39
+ }), /* @__PURE__ */ i("button", {
40
+ ref: f,
41
+ type: "button",
42
+ onClick: o,
43
+ className: `flex items-center justify-center rounded-full border border-transparent bg-action-primary-bg font-medium text-action-primary-text transition-colors hover:opacity-90 focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong ${p ? "h-7 px-3 text-xs" : "h-9 px-4 text-sm"}`,
44
+ "data-testid": "assistant-voice-privacy-notice-continue",
45
+ children: l("voiceSession.streamNoticeContinue", "Continue")
46
+ })]
47
+ })
48
+ ]
49
+ });
50
+ };
51
+ //#endregion
52
+ export { o as HANDS_FREE_NOTICE_ATTR, s as HandsFreePrivacyNotice };
@@ -12,15 +12,28 @@ export interface SocketHandlers {
12
12
  close(code: number): void;
13
13
  error(): void;
14
14
  }
15
- export interface StreamTicket {
16
- ticket: string;
17
- wsUrl: string;
15
+ /** Where to connect and as whom, resolved for each connection. */
16
+ export interface StreamConnection {
17
+ url: string;
18
+ /** The bare access token, offered as `bearer.<token>`. */
19
+ token: string;
18
20
  }
21
+ type IntervalHandle = ReturnType<typeof setInterval>;
19
22
  export interface BackendStreamDeps {
20
- fetchTicket: () => Promise<StreamTicket>;
23
+ /**
24
+ * The URL and the access token for one connection. `null`: there is no
25
+ * usable credential (an `auth` failure). A rejection: the route is not
26
+ * configured (an `unavailable` failure).
27
+ */
28
+ resolveConnection: () => Promise<StreamConnection | null>;
21
29
  createSocket: (url: string, protocols: string[]) => SocketLike;
22
- /** Languages sent with each utterance: the user's input language, then en-IN. */
23
- languages: (language: string) => string[];
30
+ /** Languages sent with each utterance, or null when the stream does not carry this one. */
31
+ languages: (language: string) => string[] | null;
32
+ /** Milliseconds between `{t:'ping'}` keep-alives. */
33
+ keepAliveMs?: number;
34
+ setInterval?: (fn: () => void, ms: number) => IntervalHandle;
35
+ clearInterval?: (handle: IntervalHandle) => void;
36
+ now?: () => number;
24
37
  }
25
38
  /** The gateway's frame cap is 8 KB; stay well under it. */
26
39
  export declare const MAX_SEND_BYTES = 6400;
@@ -28,7 +41,17 @@ export declare const CLOSE_CODE_ERRORS: Readonly<Record<number, {
28
41
  code: SttErrorCode;
29
42
  retryable: boolean;
30
43
  }>>;
44
+ /**
45
+ * Closes that end a healthy connection rather than refuse one: the gateway's
46
+ * session cap (1000), a pod going away (1001, 4503) and an idle close (4408).
47
+ * They reconnect, but only after a connection that stayed up `MIN_STABLE_MS`,
48
+ * so a server that accepts and immediately drops cannot cause a loop.
49
+ */
50
+ export declare const RECONNECT_CLOSE_CODES: ReadonlySet<number>;
51
+ export declare const MIN_STABLE_MS = 5000;
52
+ export declare const KEEP_ALIVE_MS = 20000;
31
53
  /** Concatenate frames into chunks of at most `MAX_SEND_BYTES`. */
32
54
  export declare function chunkFrames(frames: readonly Int16Array[]): Int16Array[];
33
55
  export declare function createBackendStreamTransport(deps: BackendStreamDeps): SttTransport;
56
+ export {};
34
57
  //# sourceMappingURL=backendStreamTransport.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"backendStreamTransport.d.ts","sourceRoot":"","sources":["../../../../../src/shared/assistant/voice/handsfree/backendStreamTransport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,KAAK,EAEV,YAAY,EACZ,YAAY,EAEb,MAAM,gBAAgB,CAAC;AAExB,uFAAuF;AACvF,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,eAAe,GAAG,IAAI,CAAC;IAC7D,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,CAAC,QAAQ,EAAE,cAAc,GAAG,IAAI,CAAC;CACxC;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,IAAI,IAAI,CAAC;IACb,OAAO,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAC7B,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,KAAK,IAAI,IAAI,CAAC;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,MAAM,OAAO,CAAC,YAAY,CAAC,CAAC;IACzC,YAAY,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,UAAU,CAAC;IAC/D,iFAAiF;IACjF,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,EAAE,CAAC;CAC3C;AAED,2DAA2D;AAC3D,eAAO,MAAM,cAAc,OAAO,CAAC;AAGnC,eAAO,MAAM,iBAAiB,EAAE,QAAQ,CACtC,MAAM,CAAC,MAAM,EAAE;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAAC,CAO3D,CAAC;AASF,kEAAkE;AAClE,wBAAgB,WAAW,CAAC,MAAM,EAAE,SAAS,UAAU,EAAE,GAAG,UAAU,EAAE,CAgBvE;AAED,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,iBAAiB,GACtB,YAAY,CAyId"}
1
+ {"version":3,"file":"backendStreamTransport.d.ts","sourceRoot":"","sources":["../../../../../src/shared/assistant/voice/handsfree/backendStreamTransport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,OAAO,KAAK,EAEV,YAAY,EACZ,YAAY,EAEb,MAAM,gBAAgB,CAAC;AAGxB,uFAAuF;AACvF,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,eAAe,GAAG,IAAI,CAAC;IAC7D,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,MAAM,CAAC,QAAQ,EAAE,cAAc,GAAG,IAAI,CAAC;CACxC;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,IAAI,IAAI,CAAC;IACb,OAAO,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI,CAAC;IAC7B,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,KAAK,IAAI,IAAI,CAAC;CACf;AAED,kEAAkE;AAClE,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,0DAA0D;IAC1D,KAAK,EAAE,MAAM,CAAC;CACf;AAED,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC;AAErD,MAAM,WAAW,iBAAiB;IAChC;;;;OAIG;IACH,iBAAiB,EAAE,MAAM,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAAC;IAC1D,YAAY,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,KAAK,UAAU,CAAC;IAC/D,2FAA2F;IAC3F,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAM,EAAE,GAAG,IAAI,CAAC;IACjD,qDAAqD;IACrD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,IAAI,EAAE,EAAE,EAAE,MAAM,KAAK,cAAc,CAAC;IAC7D,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,CAAC;IACjD,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAED,2DAA2D;AAC3D,eAAO,MAAM,cAAc,OAAO,CAAC;AAGnC,eAAO,MAAM,iBAAiB,EAAE,QAAQ,CACtC,MAAM,CAAC,MAAM,EAAE;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,CAAC,CAU3D,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,EAAE,WAAW,CAAC,MAAM,CAEpD,CAAC;AACH,eAAO,MAAM,aAAa,OAAQ,CAAC;AACnC,eAAO,MAAM,aAAa,QAAS,CAAC;AASpC,kEAAkE;AAClE,wBAAgB,WAAW,CAAC,MAAM,EAAE,SAAS,UAAU,EAAE,GAAG,UAAU,EAAE,CAgBvE;AAED,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,iBAAiB,GACtB,YAAY,CAqQd"}