@burdenoff/fe-libs 2026.1005.1 → 2026.1005.3

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 (108) hide show
  1. package/dist/chrome/ContextSwitcher.d.ts +2 -0
  2. package/dist/chrome/ContextSwitcher.d.ts.map +1 -1
  3. package/dist/chrome/ContextSwitcher.js +70 -67
  4. package/dist/chrome/contextSwitcher/ProjectList.d.ts +1 -0
  5. package/dist/chrome/contextSwitcher/ProjectList.d.ts.map +1 -1
  6. package/dist/chrome/contextSwitcher/ProjectList.js +18 -5
  7. package/dist/node_modules/fflate/esm/browser.js +3 -3
  8. package/dist/node_modules/hast-util-to-jsx-runtime/lib/index.js +51 -51
  9. package/dist/node_modules/pdfjs-dist/build/pdf.js +2268 -1656
  10. package/dist/node_modules/pdfjs-dist/build/pdf.worker.min.js +8719 -7535
  11. package/dist/shared/assistant/attachments.js +1 -0
  12. package/dist/shared/assistant/i18nManifest.d.ts +4 -0
  13. package/dist/shared/assistant/i18nManifest.d.ts.map +1 -1
  14. package/dist/shared/assistant/i18nManifest.js +4 -0
  15. package/dist/shared/assistant/images.js +1 -1
  16. package/dist/shared/assistant/index.d.ts +16 -0
  17. package/dist/shared/assistant/index.d.ts.map +1 -1
  18. package/dist/shared/assistant/runtime.js +1 -0
  19. package/dist/shared/assistant/speech/browserSpeechEngine.d.ts.map +1 -1
  20. package/dist/shared/assistant/speech/browserSpeechEngine.js +46 -45
  21. package/dist/shared/assistant/speech/createSpeechEngine.js +1 -1
  22. package/dist/shared/assistant/speech/hostedTtsSpeechEngine.d.ts.map +1 -1
  23. package/dist/shared/assistant/speech/hostedTtsSpeechEngine.js +80 -79
  24. package/dist/shared/assistant/store.d.ts +3 -0
  25. package/dist/shared/assistant/store.d.ts.map +1 -1
  26. package/dist/shared/assistant/store.js +43 -35
  27. package/dist/shared/assistant/ui/AssistantChatArea.d.ts.map +1 -1
  28. package/dist/shared/assistant/ui/AssistantChatArea.js +1076 -1074
  29. package/dist/shared/assistant/ui/AssistantMoreMenu.d.ts.map +1 -1
  30. package/dist/shared/assistant/ui/AssistantMoreMenu.js +59 -57
  31. package/dist/shared/assistant/ui/composer/AssistantHandsFreeInterruptToggle.d.ts +17 -0
  32. package/dist/shared/assistant/ui/composer/AssistantHandsFreeInterruptToggle.d.ts.map +1 -0
  33. package/dist/shared/assistant/ui/composer/AssistantHandsFreeInterruptToggle.js +34 -0
  34. package/dist/shared/assistant/ui/useVoiceSession.d.ts +29 -2
  35. package/dist/shared/assistant/ui/useVoiceSession.d.ts.map +1 -1
  36. package/dist/shared/assistant/ui/useVoiceSession.js +247 -213
  37. package/dist/shared/assistant/ui/voice/AssistantVoiceSession.js +2 -0
  38. package/dist/shared/assistant/uiActions/deixis.js +1 -1
  39. package/dist/shared/assistant/voice/handsfree/audioTrackTransport.d.ts +33 -0
  40. package/dist/shared/assistant/voice/handsfree/audioTrackTransport.d.ts.map +1 -0
  41. package/dist/shared/assistant/voice/handsfree/audioTrackTransport.js +98 -0
  42. package/dist/shared/assistant/voice/handsfree/backendStreamTransport.d.ts +34 -0
  43. package/dist/shared/assistant/voice/handsfree/backendStreamTransport.d.ts.map +1 -0
  44. package/dist/shared/assistant/voice/handsfree/backendStreamTransport.js +130 -0
  45. package/dist/shared/assistant/voice/handsfree/bargeIn.d.ts +43 -0
  46. package/dist/shared/assistant/voice/handsfree/bargeIn.d.ts.map +1 -0
  47. package/dist/shared/assistant/voice/handsfree/bargeIn.js +32 -0
  48. package/dist/shared/assistant/voice/handsfree/captureWorklet.d.ts +47 -0
  49. package/dist/shared/assistant/voice/handsfree/captureWorklet.d.ts.map +1 -0
  50. package/dist/shared/assistant/voice/handsfree/captureWorklet.js +85 -0
  51. package/dist/shared/assistant/voice/handsfree/echoGate.d.ts +140 -0
  52. package/dist/shared/assistant/voice/handsfree/echoGate.d.ts.map +1 -0
  53. package/dist/shared/assistant/voice/handsfree/echoGate.js +198 -0
  54. package/dist/shared/assistant/voice/handsfree/handsFreeController.d.ts +77 -0
  55. package/dist/shared/assistant/voice/handsfree/handsFreeController.d.ts.map +1 -0
  56. package/dist/shared/assistant/voice/handsfree/handsFreeController.js +126 -0
  57. package/dist/shared/assistant/voice/handsfree/handsFreeRuntime.d.ts +15 -0
  58. package/dist/shared/assistant/voice/handsfree/handsFreeRuntime.d.ts.map +1 -0
  59. package/dist/shared/assistant/voice/handsfree/handsFreeRuntime.js +78 -0
  60. package/dist/shared/assistant/voice/handsfree/handsFreeSetting.d.ts +26 -0
  61. package/dist/shared/assistant/voice/handsfree/handsFreeSetting.d.ts.map +1 -0
  62. package/dist/shared/assistant/voice/handsfree/handsFreeSetting.js +25 -0
  63. package/dist/shared/assistant/voice/handsfree/micCapture.d.ts +21 -0
  64. package/dist/shared/assistant/voice/handsfree/micCapture.d.ts.map +1 -0
  65. package/dist/shared/assistant/voice/handsfree/micCapture.js +73 -0
  66. package/dist/shared/assistant/voice/handsfree/playbackReference.d.ts +38 -0
  67. package/dist/shared/assistant/voice/handsfree/playbackReference.d.ts.map +1 -0
  68. package/dist/shared/assistant/voice/handsfree/playbackReference.js +55 -0
  69. package/dist/shared/assistant/voice/handsfree/preRollRing.d.ts +32 -0
  70. package/dist/shared/assistant/voice/handsfree/preRollRing.d.ts.map +1 -0
  71. package/dist/shared/assistant/voice/handsfree/preRollRing.js +34 -0
  72. package/dist/shared/assistant/voice/handsfree/sttTransport.d.ts +94 -0
  73. package/dist/shared/assistant/voice/handsfree/sttTransport.d.ts.map +1 -0
  74. package/dist/shared/assistant/voice/handsfree/sttTransport.js +27 -0
  75. package/dist/shared/assistant/voice/handsfree/useHandsFreeInterrupt.d.ts +33 -0
  76. package/dist/shared/assistant/voice/handsfree/useHandsFreeInterrupt.d.ts.map +1 -0
  77. package/dist/shared/assistant/voice/handsfree/useHandsFreeInterrupt.js +70 -0
  78. package/dist/shared/assistant/voice/handsfree/vad.d.ts +55 -0
  79. package/dist/shared/assistant/voice/handsfree/vad.d.ts.map +1 -0
  80. package/dist/shared/assistant/voice/handsfree/vad.js +41 -0
  81. package/dist/shared/assistant/voice/handsfree/webSpeechTransport.d.ts +3 -0
  82. package/dist/shared/assistant/voice/handsfree/webSpeechTransport.d.ts.map +1 -0
  83. package/dist/shared/assistant/voice/handsfree/webSpeechTransport.js +16 -0
  84. package/dist/shared/assistant/voice/voiceSession.d.ts +9 -0
  85. package/dist/shared/assistant/voice/voiceSession.d.ts.map +1 -1
  86. package/dist/shared/assistant/voice/voiceSession.js +2 -2
  87. package/dist/shared/assistant/voice/voiceTranscript.js +14 -14
  88. package/dist/shared/config/gatewayUrls.js +2 -2
  89. package/dist/shared/graphql/workspaceToken.d.ts +1 -0
  90. package/dist/shared/graphql/workspaceToken.d.ts.map +1 -1
  91. package/dist/shared/graphql/workspaceToken.js +18 -14
  92. package/dist/shared/plugins/iframe-mount/client/message-bus.js +1 -0
  93. package/dist/shared/plugins/iframe-mount/client/rpc.js +1 -0
  94. package/dist/shared/providers/shell/ActiveContextProvider.d.ts.map +1 -1
  95. package/dist/shared/providers/shell/ActiveContextProvider.js +165 -144
  96. package/dist/shared/providers/shell/AuthTokenProvider.d.ts.map +1 -1
  97. package/dist/shared/providers/shell/AuthTokenProvider.js +51 -46
  98. package/dist/shared/providers/shell/WorkspaceWideSelection.d.ts +10 -0
  99. package/dist/shared/providers/shell/WorkspaceWideSelection.d.ts.map +1 -0
  100. package/dist/shared/providers/shell/WorkspaceWideSelection.js +37 -0
  101. package/dist/shared/providers/shell/index.d.ts +2 -0
  102. package/dist/shared/providers/shell/index.d.ts.map +1 -1
  103. package/dist/shared/tours/TourTooltip.js +8 -8
  104. package/dist/shared/utils/format.js +1 -1
  105. package/dist/shared/utils/gatewayFetchRewrite.js +1 -1
  106. package/dist/shared-assistant.js +218 -202
  107. package/dist/shared-providers-shell.js +25 -24
  108. package/package.json +18 -8
@@ -1,217 +1,241 @@
1
1
  import { useVoiceInput as e } from "../voice/useVoiceInput.js";
2
2
  import { planSubmitTimer as t, resolveVoiceGraceMs as n } from "../voice/handsFree.js";
3
- import { speechFeed as r } from "../speech/speechFeed.js";
4
- import { INITIAL_SESSION as ee, INTERRUPT_MAX_MS as te, NOTHING_HEARD as i, advanceHeardClock as ne, isCapturing as re, isSubmittable as ie, planListeningHold as ae, planReplyConsumption as oe, planVoiceAnnouncement as se, shouldRecognise as ce, spokenSoFar as a, voiceSessionReducer as le } from "../voice/voiceSession.js";
5
- import { isTurnSuperseded as o } from "../voice/supersededTurns.js";
6
- import { captionChunks as ue } from "../voice/speechPlayback.js";
7
- import { turnClockMs as s } from "../turnTimeline.js";
8
- import { useAssistantSpeech as de } from "./AssistantSpeechProvider.js";
9
- import { useCallback as c, useEffect as l, useLayoutEffect as fe, useMemo as pe, useReducer as me, useRef as u, useState as d } from "react";
3
+ import { readHandsFreeOverride as r, resolveHandsFreeEnabled as ee } from "../voice/handsfree/handsFreeSetting.js";
4
+ import { silencePlaybackReference as te } from "../voice/handsfree/playbackReference.js";
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";
10
13
  //#region src/shared/assistant/ui/useVoiceSession.ts
11
- var he = 4e3, ge = 2500, _e = 5e3, ve = 12e3, ye = "data:audio/wav;base64,UklGRiQAAABXQVZFZm10IBAAAAABAAEARKwAAIhYAQACABAAZGF0YQAAAAA=";
12
- function f({ onSubmit: f, latestReply: p, language: m, graceMs: be, onSupersede: h }) {
13
- let xe = n(be), g = u(null), [_, v] = me(c((e, t) => le(e, t, g.current), []), ee), y = de(), { setSessionSpeaking: b, setSessionMicOpen: x, speakingMessageId: S, stop: C } = y, w = u(y.toggle), T = y.toggle;
14
- fe(() => {
15
- w.current = T;
16
- }, [T]);
17
- let E = u(null), D = u({}), O = u(i), k = u(null), A = u(!1), j = u(null), [M, N] = d(null), [P, F] = d(!1), [I, L] = d(!1), [R, z] = d(!1), B = u(_);
18
- B.current = _;
19
- let V = u([]), H = u(null), U = u(!1), W = c(() => {
20
- V.current = [], H.current = null, U.current = !1;
21
- }, []), G = c(() => {
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(() => {
22
25
  for (;;) {
23
- let e = V.current.shift();
26
+ let e = z.current.shift();
24
27
  if (!e) return !1;
25
28
  if (!(e.stillWanted && !e.stillWanted())) {
26
- H.current = e, g.current = g.current ? `${g.current} ${e.text}` : e.text;
29
+ B.current = e, m.current = m.current ? `${m.current} ${e.text}` : e.text;
27
30
  try {
28
- w.current(e.id, e.text, e.lang);
31
+ S.current(e.id, e.text, e.lang);
29
32
  } catch {
30
- H.current = null;
33
+ B.current = null;
31
34
  continue;
32
35
  }
33
36
  return !0;
34
37
  }
35
38
  }
36
- }, []), K = u(!1), q = c((e) => {
37
- let t = ae({
39
+ }, []), W = l(!1), Ae = s((e) => {
40
+ let t = le({
38
41
  requested: e,
39
- held: K.current,
40
- muted: B.current.muted
42
+ held: W.current,
43
+ muted: R.current.muted
41
44
  });
42
- K.current = t.held, t.mute !== null && v({
45
+ W.current = t.held, t.mute !== null && g({
43
46
  type: "mute",
44
47
  muted: t.mute
45
48
  });
46
- }, []), J = c((e) => {
47
- let t = se(B.current);
48
- t !== "drop" && (H.current?.id === e.id || V.current.some((t) => t.id === e.id) || (V.current.push(e), t === "start" && !U.current && (U.current = !0, v({ type: "announce" }))));
49
- }, []), Se = c((e) => {
50
- if (B.current.phase !== "thinking") {
51
- J(e);
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);
52
55
  return;
53
56
  }
54
- V.current.push(e), U.current = !0, v({ type: "answered-locally" });
55
- }, [J]), Ce = u(p);
56
- Ce.current = p, l(() => {
57
- if (_.phase === "speaking") {
58
- let e = j.current;
59
- g.current = e && k.current === e.id && p?.id !== e.id ? e.text : p?.text ?? null;
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;
60
63
  return;
61
64
  }
62
- if (g.current === null) return;
65
+ if (m.current === null) return;
63
66
  let e = setTimeout(() => {
64
- g.current = null;
65
- }, ge);
67
+ m.current = null;
68
+ }, xe);
66
69
  return () => clearTimeout(e);
67
- }, [_.phase, p]);
68
- let we = u(m);
69
- we.current = m;
70
- let Y = c((e, t) => {
71
- v({
70
+ }, [h.phase, f]);
71
+ let K = l(p);
72
+ K.current = p;
73
+ let q = s((e, t) => {
74
+ g({
72
75
  type: "speech",
73
76
  transcript: e,
74
77
  final: t,
75
78
  at: Date.now(),
76
- language: we.current
79
+ language: K.current
77
80
  });
78
- }, []), Te = u(0), Ee = c(() => {
79
- W(), C(), Te.current = Date.now(), F(!0), v({ type: "interrupt" });
80
- }, [C, W]), X = e({
81
- onFinalize: c((e) => Y(e, !0), [Y]),
82
- language: m
83
- });
84
- l(() => {
85
- X.interim && Y(X.interim, !1);
86
- }, [X.interim, Y]), l(() => {
87
- E.current && clearTimeout(E.current), L(!1), O.current = ne(O.current, _, s());
81
+ }, []), Ne = s((e, t, n) => {
82
+ g({
83
+ type: "speech",
84
+ transcript: e,
85
+ final: t,
86
+ at: Date.now(),
87
+ language: n ?? K.current,
88
+ gated: !0
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]),
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({
100
+ enabled: ee(De, r()),
101
+ phase: h.phase,
102
+ muted: h.muted,
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());
88
111
  let e = t({
89
- phase: _.phase,
90
- muted: _.muted,
91
- spoken: a(_),
92
- holding: R,
93
- graceMs: xe
112
+ phase: h.phase,
113
+ muted: h.muted,
114
+ spoken: i(h),
115
+ holding: I,
116
+ graceMs: ke
94
117
  });
95
118
  if (!e.arm) return;
96
- let n = setTimeout(() => L(!0), Math.min(800, e.delayMs)), r = s();
97
- return E.current = setTimeout(() => {
98
- D.current = {
99
- speechEnded: O.current.at ?? r,
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,
100
123
  graceStarted: r,
101
- graceEnded: s()
102
- }, v({
124
+ graceEnded: o()
125
+ }, g({
103
126
  type: "silence",
104
127
  at: Date.now()
105
128
  });
106
129
  }, e.delayMs), () => {
107
- clearTimeout(n), E.current && clearTimeout(E.current);
130
+ clearTimeout(n), w.current && clearTimeout(w.current);
108
131
  };
109
132
  }, [
110
- _,
111
- R,
112
- xe
113
- ]), l(() => {
114
- (_.phase !== "listening" || _.muted) && z(!1);
115
- }, [_.phase, _.muted]), l(() => {
116
- if (!P) return;
117
- let e = Date.now() - Te.current, t = X.isListening ? Math.max(0, 500 - e) : Math.max(0, te - e), n = setTimeout(() => F(!1), t);
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);
118
141
  return () => clearTimeout(n);
119
- }, [P, X.isListening]);
120
- let De = u("");
121
- _.phase === "listening" && (De.current = a(_)), l(() => {
122
- if (_.phase !== "thinking") return;
123
- x(!1), W();
124
- let e = De.current.trim();
125
- e && f(e, Q.current ?? `vs-orphan-${Date.now().toString(36)}`, D.current, { correction: B.current.correcting }), D.current = {}, O.current = i;
126
- }, [_.phase]), l(() => {
127
- let e = oe(p?.id, _.phase, k.current, o(p?.id));
128
- e.claim && (k.current = p?.id ?? null, e.advance && p && v({
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({
129
152
  type: "reply",
130
- text: p.text
153
+ text: f.text
131
154
  }));
132
- }, [p, _.phase]), l(() => {
133
- if (S === null || _.phase !== "thinking" || k.current === S) return;
134
- if (o(S)) {
135
- C();
155
+ }, [f, h.phase]), c(() => {
156
+ if (b === null || h.phase !== "thinking" || D.current === b) return;
157
+ if (a(b)) {
158
+ x();
136
159
  return;
137
160
  }
138
- let e = r.peek(S);
139
- !e || e.channel !== "voice" || e.voiceSessionId === void 0 || e.voiceSessionId !== Q.current || (k.current = S, j.current = {
140
- id: S,
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,
141
164
  text: e.text
142
- }, v({
165
+ }, g({
143
166
  type: "reply-audio-started",
144
- replyId: S
167
+ replyId: b
145
168
  }));
146
169
  }, [
147
- S,
148
- _.phase,
149
- C
150
- ]), l(() => {
151
- let e = S !== null;
152
- A.current && !e && (H.current = null, (B.current.phase !== "speaking" || !G()) && v({ type: "speech-ended" })), A.current = e;
153
- }, [S, G]), l(() => {
154
- _.phase !== "listening" && N((e) => e === "nothing-heard" ? null : e);
155
- }, [_.phase]), l(() => {
156
- if (_.phase !== "speaking" || S !== null) return;
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;
157
180
  let e = setTimeout(() => {
158
- A.current || (W(), v({ type: "speech-ended" }));
159
- }, he);
181
+ O.current || (H(), g({ type: "speech-ended" }));
182
+ }, be);
160
183
  return () => clearTimeout(e);
161
184
  }, [
162
- _.phase,
163
- S,
164
- W
185
+ h.phase,
186
+ b,
187
+ H
165
188
  ]);
166
- let Oe = u(h);
167
- Oe.current = h;
168
- let Z = u(0);
169
- l(() => {
170
- let e = _.superseded;
171
- e !== Z.current && (Z.current = e, e !== 0 && (W(), C(), Oe.current?.()));
172
- }, [
173
- _.superseded,
174
- W,
175
- C
176
- ]), l(() => {
177
- x(re(_)), ce(_) ? X.isActive || X.start("auto") : X.isActive && X.stop();
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?.()));
178
195
  }, [
179
- _,
180
- X,
196
+ h.superseded,
197
+ H,
181
198
  x
182
- ]), l(() => {
183
- _.phase !== "speaking" || !U.current || (U.current = !1, G() || v({ type: "speech-ended" }));
184
- }, [_.phase, G]), l(() => {
185
- X.error === "not-allowed" || X.error === "audio-capture" ? v({
199
+ ]), c(() => {
200
+ y(se(h)), fe(h) && !X.suppressWebSpeech ? Y.isActive || Y.start("auto") : Y.isActive && Y.stop();
201
+ }, [
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({
186
210
  type: "fail",
187
211
  error: "mic-denied"
188
- }) : X.error === "language-not-supported" ? v({
212
+ }) : Y.error === "language-not-supported" ? g({
189
213
  type: "fail",
190
214
  error: "no-speech-support"
191
- }) : X.error === "network" ? N("network") : X.error === "unknown" && N("recognition-failed");
192
- }, [X.error]), l(() => {
193
- X.error !== null || !X.isListening || N((e) => e === "network" || e === "recognition-failed" ? null : e);
194
- }, [X.error, X.isListening]), l(() => {
195
- if (X.isListening && N((e) => e === "not-capturing" ? null : e), !re(_) || X.isListening) return;
196
- let e = setTimeout(() => N("not-capturing"), _e);
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);
197
221
  return () => clearTimeout(e);
198
- }, [_, X.isListening]), l(() => {
199
- if (_.phase !== "listening" || _.muted || !X.isListening || a(_) !== "") return;
200
- let e = setTimeout(() => N("nothing-heard"), ve);
222
+ }, [h, Z]), c(() => {
223
+ if (h.phase !== "listening" || h.muted || !Z || i(h) !== "") return;
224
+ let e = setTimeout(() => j("nothing-heard"), Ce);
201
225
  return () => clearTimeout(e);
202
- }, [_, X.isListening]), l(() => {
203
- a(_) !== "" && N(null);
204
- }, [_]);
205
- let Q = u(null), ke = c(() => {
206
- if (F(!1), L(!1), z(!1), W(), K.current = !1, !X.isSupported) {
207
- v({
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({
208
232
  type: "fail",
209
233
  error: "no-speech-support"
210
234
  });
211
235
  return;
212
236
  }
213
- if (y.isBlocked) {
214
- v({
237
+ if (_.isBlocked) {
238
+ g({
215
239
  type: "fail",
216
240
  error: "no-voice-support"
217
241
  });
@@ -226,90 +250,100 @@ function f({ onSubmit: f, latestReply: p, language: m, graceMs: be, onSupersede:
226
250
  } catch {}
227
251
  try {
228
252
  if (typeof window < "u" && typeof window.Audio == "function") {
229
- let e = new window.Audio(ye);
253
+ let e = new window.Audio(we);
230
254
  e.volume = 0, e.play().catch(() => {});
231
255
  }
232
256
  } catch {}
233
- b(!0), N(null), k.current = Ce.current?.id ?? null, j.current = null, Q.current = `vs-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`, v({ type: "start" });
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" });
234
258
  }, [
235
- X.isSupported,
236
- y.isBlocked,
237
- b,
238
- W
239
- ]), Ae = c(() => {
240
- F(!1), L(!1), z(!1), W(), K.current = !1, Q.current = null, v({ type: "end" }), C(), b(!1);
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);
241
265
  }, [
242
- C,
243
- b,
244
- W
245
- ]), je = c((e) => Q.current === e, []), Me = c(() => {
246
- let e = B.current;
247
- e.phase !== "listening" || e.muted || z(!0);
248
- }, []), Ne = c(() => {
249
- z(!1);
250
- let e = B.current;
251
- if (e.phase !== "listening" || e.muted || !ie(a(e))) return;
252
- let t = s();
253
- D.current = {
254
- speechEnded: O.current.at ?? t,
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,
255
279
  graceStarted: t,
256
280
  graceEnded: t
257
- }, v({
281
+ }, g({
258
282
  type: "silence",
259
283
  at: Date.now()
260
284
  });
261
- }, []), Pe = c(() => {
262
- v({
285
+ }, []), Ge = s(() => {
286
+ g({
263
287
  type: "mute",
264
- muted: !B.current.muted
288
+ muted: !R.current.muted
265
289
  });
266
290
  }, []);
267
- l(() => () => {
268
- b(!1), x(!1);
269
- }, [b, x]);
270
- let $ = ue(y.spokenChunks, _.phase, S);
271
- return pe(() => ({
272
- session: _,
273
- notice: M,
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"),
274
298
  spokenChunks: $,
275
- capturing: X.isListening,
276
- active: _.phase !== "idle" && (_.phase !== "ended" || _.error !== null),
277
- interrupting: P,
278
- awaitingEndpoint: I,
279
- holding: R,
280
- correcting: _.correcting,
281
- available: X.isSupported && !y.isBlocked,
282
- start: ke,
283
- end: Ae,
284
- isCurrentSession: je,
285
- toggleMute: Pe,
286
- interrupt: Ee,
287
- letMeFinish: Me,
288
- imDone: Ne,
289
- announce: J,
290
- holdListening: q,
291
- answerLocally: Se
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,
305
+ handsFree: {
306
+ mode: X.mode,
307
+ nothingHeard: X.nothingHeard,
308
+ transportKind: X.transportKind,
309
+ fallbackReason: X.fallbackReason
310
+ },
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
292
322
  }), [
293
- _,
323
+ h,
324
+ A,
294
325
  M,
295
326
  P,
296
327
  I,
297
- R,
298
- X.isListening,
299
- X.isSupported,
300
- y.isBlocked,
328
+ Z,
329
+ X.mode,
330
+ X.nothingHeard,
331
+ X.transportKind,
332
+ X.fallbackReason,
333
+ Y.isSupported,
334
+ _.isBlocked,
301
335
  $,
302
- ke,
303
- Ae,
304
- je,
336
+ Be,
337
+ Ve,
338
+ He,
339
+ Ge,
305
340
  Pe,
306
- Ee,
307
- Me,
308
- Ne,
309
- J,
310
- q,
311
- Se
341
+ Ue,
342
+ We,
343
+ G,
344
+ Ae,
345
+ je
312
346
  ]);
313
347
  }
314
348
  //#endregion
315
- export { f as useVoiceSession };
349
+ export { d as useVoiceSession };
@@ -256,6 +256,8 @@ function _e(e, t) {
256
256
  case "not-capturing": return t("voiceSession.noticeNotCapturing", "The microphone did not start. Check that this site is allowed to use it, then try again.");
257
257
  case "recognition-failed": return t("voiceSession.noticeRecognitionFailed", "Speech recognition stopped unexpectedly. It will retry — if it keeps happening, reload the page.");
258
258
  case "nothing-heard": return t("voiceSession.noticeNothingHeard", "Nothing heard yet. Check your microphone is not muted or in use by another app.");
259
+ case "hands-free-nothing-heard": return t("voiceSession.noticeHandsFreeNothingHeard", "Stopped, but I did not catch that. Say it again, or tap to replay.");
260
+ case "hands-free-fallback": return t("voiceSession.noticeHandsFreeFallback", "Hands-free interrupt turned itself off for this conversation. Tap to interrupt still works.");
259
261
  default: return e;
260
262
  }
261
263
  }
@@ -29,7 +29,7 @@ var e = [
29
29
  2: 2,
30
30
  3: 3,
31
31
  4: 4
32
- }, o = "(?:(?:open|go to|take me to) )?", s = RegExp("^(?:(?:the )?(first|second|third|fourth|last|1st|2nd|3rd|4th)(?: one)?|(?:open|go to|take me to) (?:the )?(first|second|third|fourth|last|1st|2nd|3rd|4th) one)$"), c = RegExp(`^${o}(?:the )?(?:number|option) (one|two|three|four|1|2|3|4)$`), l = RegExp(`^${o}the one (?:in|under|from) (?:the )?(.+)$`);
32
+ }, o = "(?:(?:open|go to|take me to) )?", s = /* @__PURE__ */ RegExp("^(?:(?:the )?(first|second|third|fourth|last|1st|2nd|3rd|4th)(?: one)?|(?:open|go to|take me to) (?:the )?(first|second|third|fourth|last|1st|2nd|3rd|4th) one)$"), c = RegExp(`^${o}(?:the )?(?:number|option) (one|two|three|four|1|2|3|4)$`), l = RegExp(`^${o}the one (?:in|under|from) (?:the )?(.+)$`);
33
33
  function u(e) {
34
34
  let t = s.exec(e);
35
35
  if (t) {
@@ -0,0 +1,33 @@
1
+ import { SttTransport } from './sttTransport';
2
+ export declare const BRANCH_DELAY_S = 0.3;
3
+ export declare const TRAILING_RESULT_MS = 1500;
4
+ /** The slice of `SpeechRecognition` this transport uses. */
5
+ export interface TrackRecognitionLike {
6
+ lang: string;
7
+ continuous: boolean;
8
+ interimResults: boolean;
9
+ onresult: ((event: TrackRecognitionEvent) => void) | null;
10
+ onerror: ((event: {
11
+ error: string;
12
+ }) => void) | null;
13
+ onend: (() => void) | null;
14
+ start(track: MediaStreamTrack): void;
15
+ stop(): void;
16
+ abort(): void;
17
+ }
18
+ export interface TrackRecognitionEvent {
19
+ resultIndex: number;
20
+ results: ArrayLike<{
21
+ isFinal: boolean;
22
+ length: number;
23
+ [index: number]: {
24
+ transcript: string;
25
+ };
26
+ }>;
27
+ }
28
+ export interface AudioTrackTransportDeps {
29
+ createRecognition: () => TrackRecognitionLike | null;
30
+ now?: () => number;
31
+ }
32
+ export declare function createAudioTrackTransport(deps: AudioTrackTransportDeps): SttTransport;
33
+ //# sourceMappingURL=audioTrackTransport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audioTrackTransport.d.ts","sourceRoot":"","sources":["../../../../../src/shared/assistant/voice/handsfree/audioTrackTransport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,KAAK,EAGV,YAAY,EAEb,MAAM,gBAAgB,CAAC;AAExB,eAAO,MAAM,cAAc,MAAM,CAAC;AAClC,eAAO,MAAM,kBAAkB,OAAO,CAAC;AAEvC,4DAA4D;AAC5D,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,OAAO,CAAC;IACpB,cAAc,EAAE,OAAO,CAAC;IACxB,QAAQ,EAAE,CAAC,CAAC,KAAK,EAAE,qBAAqB,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;IAC1D,OAAO,EAAE,CAAC,CAAC,KAAK,EAAE;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC;IACrD,KAAK,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC;IAC3B,KAAK,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI,CAAC;IACrC,IAAI,IAAI,IAAI,CAAC;IACb,KAAK,IAAI,IAAI,CAAC;CACf;AAED,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,SAAS,CAAC;QACjB,OAAO,EAAE,OAAO,CAAC;QACjB,MAAM,EAAE,MAAM,CAAC;QACf,CAAC,KAAK,EAAE,MAAM,GAAG;YAAE,UAAU,EAAE,MAAM,CAAA;SAAE,CAAC;KACzC,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,uBAAuB;IACtC,iBAAiB,EAAE,MAAM,oBAAoB,GAAG,IAAI,CAAC;IACrD,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAED,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,uBAAuB,GAC5B,YAAY,CAgJd"}