@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
@@ -0,0 +1,198 @@
1
+ //#region src/shared/assistant/voice/handsfree/echoGate.ts
2
+ var e = Object.freeze({
3
+ windowFrames: 12,
4
+ lowCorr: .3,
5
+ lowRunFrames: 3,
6
+ headsetLowRunFrames: 2,
7
+ calibFrames: 50,
8
+ maxLagFrames: 25,
9
+ minCalibCorr: .5,
10
+ tailFrames: 30,
11
+ floorDb: -60,
12
+ referenceSilentDb: -58,
13
+ quietMicDb: -55,
14
+ flatStdDb: 1,
15
+ tailDecayDbPerFrame: 3
16
+ }), t = 2400, n = 150, r = 1200, i = (e, t) => {
17
+ let n = [...e].sort((e, t) => e - t);
18
+ return n[Math.min(n.length - 1, Math.floor(t * n.length))] ?? 0;
19
+ };
20
+ function a(e, t, n) {
21
+ let r = e.length, i = 0, a = 0;
22
+ for (let n = 0; n < r; n += 1) i += e[n] ?? 0, a += t[n] ?? 0;
23
+ i /= r, a /= r;
24
+ let o = 0, s = 0, c = 0;
25
+ for (let n = 0; n < r; n += 1) {
26
+ let r = (e[n] ?? 0) - i, l = (t[n] ?? 0) - a;
27
+ o += r * l, s += r * r, c += l * l;
28
+ }
29
+ let l = Math.sqrt(c / r) < n;
30
+ return s === 0 || c === 0 ? {
31
+ corr: 0,
32
+ refFlat: l
33
+ } : {
34
+ corr: o / Math.sqrt(s * c),
35
+ refFlat: l
36
+ };
37
+ }
38
+ var o = class {
39
+ params;
40
+ mic = [];
41
+ ref = [];
42
+ tail = [];
43
+ base = 0;
44
+ total = 0;
45
+ playing = !1;
46
+ hasReference = !0;
47
+ playStart = 0;
48
+ armedUntil = -1;
49
+ current = null;
50
+ prior = null;
51
+ noEchoPath = !1;
52
+ lowRun = 0;
53
+ headset = !1;
54
+ constructor(t = {}) {
55
+ this.params = {
56
+ ...e,
57
+ ...t
58
+ };
59
+ }
60
+ get isPlaying() {
61
+ return this.playing;
62
+ }
63
+ get hasPrior() {
64
+ return this.prior !== null;
65
+ }
66
+ get calibration() {
67
+ let e = this.current ?? this.prior;
68
+ return e ? {
69
+ lagMs: e.lag * 20,
70
+ corr: e.corr
71
+ } : null;
72
+ }
73
+ setHeadset(e) {
74
+ this.headset = e;
75
+ }
76
+ playbackStarted(e) {
77
+ this.playing = !0, this.hasReference = e, this.playStart = this.total, this.current = null, this.noEchoPath = !1, this.lowRun = 0;
78
+ }
79
+ playbackStopped() {
80
+ this.playing && (this.playing = !1, this.armedUntil = this.total + this.params.tailFrames);
81
+ }
82
+ pushFrame(e, t) {
83
+ let n = this.total;
84
+ this.total += 1;
85
+ let r = this.params.floorDb;
86
+ this.mic.push(Math.min(0, Math.max(r, e)));
87
+ let i = Math.min(0, Math.max(r, t));
88
+ this.ref.push(i);
89
+ let a = this.tail[this.tail.length - 1] ?? r;
90
+ if (this.tail.push(Math.max(i, a - this.params.tailDecayDbPerFrame)), this.trim(), !(this.playing || n < this.armedUntil)) return this.lowRun = 0, {
91
+ pass: !0,
92
+ reason: "no-playback",
93
+ coherence: null
94
+ };
95
+ if (!this.hasReference) return this.lowRun = 0, {
96
+ pass: !1,
97
+ reason: "no-reference",
98
+ coherence: null
99
+ };
100
+ let o = n - this.playStart;
101
+ if (this.playing && this.current === null && !this.noEchoPath && o >= this.params.calibFrames && n % 10 == 0 && this.calibrate(n), this.noEchoPath) return this.lowRun = 0, {
102
+ pass: !0,
103
+ reason: "no-echo-path",
104
+ coherence: null
105
+ };
106
+ let s = this.current ?? this.prior;
107
+ if (!s) {
108
+ let e = this.windowMax(this.ref, n, 0) > this.params.referenceSilentDb;
109
+ return this.lowRun = 0, {
110
+ pass: !e,
111
+ reason: e ? "calibrating" : "reference-silent",
112
+ coherence: null
113
+ };
114
+ }
115
+ let c = this.params.windowFrames;
116
+ if (this.windowMax(this.ref, n - s.lag, c + 6) <= this.params.referenceSilentDb) return this.lowRun = 0, {
117
+ pass: !0,
118
+ reason: "reference-silent",
119
+ coherence: null
120
+ };
121
+ let { corr: l, refFlat: u } = this.coherence(n, s.lag);
122
+ if (l === null) return this.lowRun = 0, {
123
+ pass: !1,
124
+ reason: "calibrating",
125
+ coherence: null
126
+ };
127
+ if (u) return {
128
+ pass: !1,
129
+ reason: "flat-reference",
130
+ coherence: l
131
+ };
132
+ this.lowRun = l < this.params.lowCorr ? this.lowRun + 1 : 0;
133
+ let d = this.headset ? this.params.headsetLowRunFrames : this.params.lowRunFrames, f = this.lowRun >= d;
134
+ return {
135
+ pass: f,
136
+ reason: f ? "uncorrelated" : "follows-reference",
137
+ coherence: l
138
+ };
139
+ }
140
+ at(e, t) {
141
+ return e[t - this.base];
142
+ }
143
+ windowMax(e, t, n) {
144
+ let r = this.params.floorDb;
145
+ for (let i = t - n; i <= t; i += 1) {
146
+ let t = this.at(e, i);
147
+ t !== void 0 && t > r && (r = t);
148
+ }
149
+ return r;
150
+ }
151
+ coherence(e, t) {
152
+ let n = this.params.windowFrames, r = [], i = [];
153
+ for (let a = e - n + 1; a <= e; a += 1) {
154
+ let e = this.at(this.mic, a), n = this.at(this.tail, a - t);
155
+ if (e === void 0 || n === void 0) return {
156
+ corr: null,
157
+ refFlat: !1
158
+ };
159
+ r.push(e), i.push(n);
160
+ }
161
+ return a(r, i, this.params.flatStdDb);
162
+ }
163
+ calibrate(e) {
164
+ let t = Math.max(this.playStart, e - n + 1), r = [], o = 0;
165
+ for (let n = t; n <= e; n += 1) {
166
+ let e = this.at(this.mic, n), t = this.at(this.ref, n);
167
+ e !== void 0 && r.push(e), t !== void 0 && t > this.params.referenceSilentDb && (o += 1);
168
+ }
169
+ if (o < this.params.calibFrames * .6) return;
170
+ let s = null;
171
+ for (let n = 0; n <= this.params.maxLagFrames; n += 1) {
172
+ let r = [], i = [];
173
+ for (let a = t; a <= e; a += 1) {
174
+ let e = this.at(this.mic, a), t = this.at(this.tail, a - n);
175
+ e !== void 0 && t !== void 0 && (r.push(e), i.push(t));
176
+ }
177
+ if (r.length < 30) continue;
178
+ let { corr: o, refFlat: c } = a(r, i, this.params.flatStdDb);
179
+ c || (!s || o > s.corr) && (s = {
180
+ lag: n,
181
+ corr: o
182
+ });
183
+ }
184
+ if (s && s.corr >= this.params.minCalibCorr) {
185
+ this.current = s, this.prior = s;
186
+ return;
187
+ }
188
+ i(r, .9) <= this.params.quietMicDb && (this.noEchoPath = !0);
189
+ }
190
+ trim() {
191
+ this.mic.length <= t || (this.mic = this.mic.slice(r), this.ref = this.ref.slice(r), this.tail = this.tail.slice(r), this.base += r);
192
+ }
193
+ reset() {
194
+ this.mic = [], this.ref = [], this.tail = [], this.base = 0, this.total = 0, this.playing = !1, this.armedUntil = -1, this.current = null, this.prior = null, this.noEchoPath = !1, this.lowRun = 0;
195
+ }
196
+ };
197
+ //#endregion
198
+ export { e as DEFAULT_ECHO_GATE_PARAMS, o as EchoGate };
@@ -0,0 +1,77 @@
1
+ import { CaptureFrameMessage } from './captureWorklet';
2
+ import { EpochGuard } from './bargeIn';
3
+ import { MicCaptureHandle } from './micCapture';
4
+ import { PlaybackSource } from './playbackReference';
5
+ import { SttTransport } from './sttTransport';
6
+ import { VoiceSessionPhase } from '../voiceSession';
7
+ export type FallbackReason = "mic-denied" | "mic-unavailable" | "transport-unavailable" | "transport-auth" | "transport-quota" | "transport-upstream" | "phantom-barge-ins";
8
+ export interface ControllerSession {
9
+ phase: VoiceSessionPhase;
10
+ muted: boolean;
11
+ }
12
+ export interface ControllerDeps {
13
+ /** Open the microphone; frames are delivered to the callback. */
14
+ startCapture: (onFrame: (frame: CaptureFrameMessage) => void) => Promise<MicCaptureHandle | FakeCapture>;
15
+ transport: SttTransport;
16
+ getSession: () => ControllerSession;
17
+ /** What is making sound right now. */
18
+ getPlaybackSource: () => PlaybackSource;
19
+ /** Is the output route a headset (a hint)? */
20
+ getHeadsetHint?: () => boolean;
21
+ language: () => string;
22
+ /** The user's voice started while the assistant was audible: STOP PLAYBACK and abandon the turn. */
23
+ onBargeIn: () => void;
24
+ /** Words from the user, already epoch-checked. */
25
+ onTranscript: (text: string, final: boolean, language: string | undefined) => void;
26
+ /** Hands-free gave up: the session falls back to the tap-first Web Speech path. */
27
+ onFallback: (reason: FallbackReason) => void;
28
+ /** A barge-in that produced no words within `NOTHING_HEARD_MS`. */
29
+ onNothingHeard?: () => void;
30
+ isEnabled: () => boolean;
31
+ prerollMs?: number;
32
+ setTimer?: (fn: () => void, ms: number) => ReturnType<typeof setTimeout>;
33
+ clearTimer?: (handle: ReturnType<typeof setTimeout>) => void;
34
+ onTelemetry?: (event: ControllerTelemetry) => void;
35
+ }
36
+ /** The slice of a capture handle the controller needs (so tests can fake it). */
37
+ export interface FakeCapture {
38
+ context?: AudioContext;
39
+ micSource?: MediaStreamAudioSourceNode;
40
+ track?: MediaStreamTrack;
41
+ stop(): void;
42
+ }
43
+ export type ControllerTelemetry = {
44
+ type: "onset";
45
+ plan: string;
46
+ atFrame: number;
47
+ playbackSource: PlaybackSource;
48
+ gate: string;
49
+ calibration: {
50
+ lagMs: number;
51
+ corr: number;
52
+ } | null;
53
+ } | {
54
+ type: "stopped-playback";
55
+ frame: number;
56
+ } | {
57
+ type: "stale-transcript-dropped";
58
+ epoch: number;
59
+ current: number;
60
+ } | {
61
+ type: "fallback";
62
+ reason: FallbackReason;
63
+ } | {
64
+ type: "nothing-heard";
65
+ };
66
+ export interface HandsFreeController {
67
+ start(): Promise<void>;
68
+ stop(): void;
69
+ /** Frames consumed so far (for tests and telemetry). */
70
+ readonly frames: number;
71
+ /** Test seam: feed a frame as the worklet would. */
72
+ feed(frame: CaptureFrameMessage): void;
73
+ readonly epoch: EpochGuard;
74
+ readonly running: boolean;
75
+ }
76
+ export declare function createHandsFreeController(deps: ControllerDeps): HandsFreeController;
77
+ //# sourceMappingURL=handsFreeController.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handsFreeController.d.ts","sourceRoot":"","sources":["../../../../../src/shared/assistant/voice/handsfree/handsFreeController.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,126 @@
1
+ import { NOTHING_HEARD_MS as e, createEpochGuard as t, planOnset as n, shouldFallBackToTap as r } from "./bargeIn.js";
2
+ import "./captureWorklet.js";
3
+ import { EchoGate as i } from "./echoGate.js";
4
+ import { MicCaptureError as a } from "./micCapture.js";
5
+ import { PreRollRing as o } from "./preRollRing.js";
6
+ import { DEFAULT_VAD_PARAMS as s, createVad as c } from "./vad.js";
7
+ //#region src/shared/assistant/voice/handsfree/handsFreeController.ts
8
+ var l = {
9
+ unavailable: "transport-unavailable",
10
+ auth: "transport-auth",
11
+ quota: "transport-quota",
12
+ upstream: "transport-upstream",
13
+ closed: "transport-upstream",
14
+ "not-allowed": "mic-denied"
15
+ };
16
+ function u(u) {
17
+ let d = u.setTimer ?? ((e, t) => setTimeout(e, t)), f = u.clearTimer ?? ((e) => clearTimeout(e)), p = new i(), m = c(), h = new o(u.prerollMs ?? 700, 20), g = t(), _ = null, v = !1, y = 0, b = null, x = null, S = 0, C = null, w = 0, T = null, E = !1, D = (e) => u.onTelemetry?.(e), O = (e) => {
18
+ E || (E = !0, D({
19
+ type: "fallback",
20
+ reason: e
21
+ }), P(), u.onFallback(e));
22
+ }, k = () => {
23
+ T !== null && f(T), T = null;
24
+ }, A = (e) => {
25
+ if (e === C) return;
26
+ let t = C;
27
+ C = e, e === null ? p.playbackStopped() : (t === null || t !== e) && p.playbackStarted(e === "hosted"), m.setOnsetFrames(e === "device" ? 6 : s.onsetFrames);
28
+ }, j = () => {
29
+ b &&= (u.transport.closeUtterance(b.id), null);
30
+ }, M = (t) => {
31
+ let i = u.getSession(), a = n({
32
+ enabled: u.isEnabled(),
33
+ muted: i.muted,
34
+ phase: i.phase,
35
+ playbackAudible: C !== null
36
+ });
37
+ if (D({
38
+ type: "onset",
39
+ plan: a.kind,
40
+ atFrame: y,
41
+ playbackSource: C,
42
+ gate: t,
43
+ calibration: p.calibration
44
+ }), a.kind === "ignore") return;
45
+ a.kind === "barge-in" && (u.onBargeIn(), D({
46
+ type: "stopped-playback",
47
+ frame: y
48
+ }), p.playbackStopped(), C = null, k(), u.transport.recognitionOwner === "transport" && (T = d(() => {
49
+ T = null, w += 1, D({ type: "nothing-heard" }), u.onNothingHeard?.(), r(w) && O("phantom-barge-ins");
50
+ }, e))), x && u.transport.cancelUtterance(x);
51
+ let o = g.open();
52
+ S += 1, b = {
53
+ id: `u${S}`,
54
+ epoch: o
55
+ }, x = b.id, u.transport.openUtterance({
56
+ utteranceId: b.id,
57
+ epoch: o,
58
+ preRoll: h.snapshot()
59
+ });
60
+ }, N = (e) => {
61
+ if (!v) return;
62
+ y += 1, A(u.getPlaybackSource()), u.getHeadsetHint && p.setHeadset(u.getHeadsetHint());
63
+ let t = p.pushFrame(e.rmsDb, e.refDb), n = new Int16Array(e.pcm);
64
+ h.push(n);
65
+ let r = m.push({
66
+ rmsDb: e.rmsDb,
67
+ zcr: e.zcr
68
+ }, t.pass);
69
+ r.event === "onset" ? M(t.reason) : b && r.inSegment && u.transport.pushFrame(n), r.event === "end" && j();
70
+ }, P = () => {
71
+ if (!v && !_) return;
72
+ v = !1, k(), b && u.transport.cancelUtterance(b.id), b = null, g.invalidate(), u.transport.stop(), h.clear(), p.reset(), m.reset();
73
+ let e = _;
74
+ _ = null, e?.stop();
75
+ };
76
+ return {
77
+ async start() {
78
+ if (v || E) return;
79
+ let e = u.getSession();
80
+ if (!u.isEnabled() || e.muted || e.phase === "ended" || e.phase === "idle") return;
81
+ v = !0;
82
+ try {
83
+ _ = await u.startCapture(N);
84
+ } catch (e) {
85
+ v = !1, O(e instanceof a && e.reason === "not-allowed" ? "mic-denied" : "mic-unavailable");
86
+ return;
87
+ }
88
+ if (!v) {
89
+ _.stop(), _ = null;
90
+ return;
91
+ }
92
+ let t = _ && "context" in _ && _.context && _.micSource && _.track ? {
93
+ context: _.context,
94
+ micSource: _.micSource,
95
+ track: _.track
96
+ } : null;
97
+ await u.transport.start(t, u.language(), {
98
+ onTranscript(e) {
99
+ if (!g.accepts(e.epoch)) {
100
+ D({
101
+ type: "stale-transcript-dropped",
102
+ epoch: e.epoch,
103
+ current: g.current()
104
+ });
105
+ return;
106
+ }
107
+ k(), u.onTranscript(e.text, e.final, e.language);
108
+ },
109
+ onError(e) {
110
+ O(l[e.code]);
111
+ }
112
+ });
113
+ },
114
+ stop: P,
115
+ get frames() {
116
+ return y;
117
+ },
118
+ feed: N,
119
+ epoch: g,
120
+ get running() {
121
+ return v;
122
+ }
123
+ };
124
+ }
125
+ //#endregion
126
+ export { u as createHandsFreeController };
@@ -0,0 +1,15 @@
1
+ import { SttTransport, SttTransportKind, TransportChoice, TransportEnvironment } from './sttTransport';
2
+ /** Feature flag + endpoint for the backend stream. Unset by default: never selected. */
3
+ export interface StreamingConfig {
4
+ enabled: boolean;
5
+ ticketUrl: string;
6
+ getAuthorization: () => string | null;
7
+ }
8
+ /** Configure (or, with `null`, clear) the backend-stream route. Nothing calls this today. */
9
+ export declare function configureHandsFreeStreaming(config: StreamingConfig | null): void;
10
+ export declare function readTransportEnvironment(): TransportEnvironment;
11
+ /** Phones: the OS recogniser and a getUserMedia stream contend for the one microphone. */
12
+ export declare function isMobileUserAgent(userAgent: string): boolean;
13
+ export declare function chooseTransport(env?: TransportEnvironment): TransportChoice;
14
+ export declare function createRuntimeTransport(kind: SttTransportKind): SttTransport;
15
+ //# sourceMappingURL=handsFreeRuntime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handsFreeRuntime.d.ts","sourceRoot":"","sources":["../../../../../src/shared/assistant/voice/handsfree/handsFreeRuntime.ts"],"names":[],"mappings":"AAiBA,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,oBAAoB,EAC1B,MAAM,gBAAgB,CAAC;AAOxB,wFAAwF;AACxF,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,MAAM,GAAG,IAAI,CAAC;CACvC;AAID,6FAA6F;AAC7F,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,eAAe,GAAG,IAAI,GAC7B,IAAI,CAEN;AAaD,wBAAgB,wBAAwB,IAAI,oBAAoB,CAS/D;AAED,0FAA0F;AAC1F,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED,wBAAgB,eAAe,CAC7B,GAAG,GAAE,oBAAiD,GACrD,eAAe,CAIjB;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,gBAAgB,GAAG,YAAY,CA0D3E"}
@@ -0,0 +1,78 @@
1
+ import { readTransportOverride as e } from "./handsFreeSetting.js";
2
+ import { createAudioTrackTransport as t } from "./audioTrackTransport.js";
3
+ import { createBackendStreamTransport as n } from "./backendStreamTransport.js";
4
+ import { isMicCaptureSupported as r } from "./micCapture.js";
5
+ import { selectSttTransport as i } from "./sttTransport.js";
6
+ import { createWebSpeechTransport as a } from "./webSpeechTransport.js";
7
+ //#region src/shared/assistant/voice/handsfree/handsFreeRuntime.ts
8
+ var o = null;
9
+ function s(e) {
10
+ o = e;
11
+ }
12
+ function c() {
13
+ if (typeof window > "u") return null;
14
+ let e = window.SpeechRecognition ?? window.webkitSpeechRecognition;
15
+ return typeof e == "function" ? e : null;
16
+ }
17
+ function l() {
18
+ return {
19
+ userAgent: typeof navigator > "u" ? "" : navigator.userAgent,
20
+ hasSpeechRecognition: c() !== null,
21
+ hasAudioWorklet: r(),
22
+ backendStreamEnabled: o?.enabled === !0,
23
+ backendStreamConfigured: o !== null && o.ticketUrl !== ""
24
+ };
25
+ }
26
+ function u(e) {
27
+ return /Android|iPhone|iPad|iPod|Mobile/.test(e);
28
+ }
29
+ function d(t = l()) {
30
+ let n = e();
31
+ return n ? {
32
+ kind: n,
33
+ because: "test-override"
34
+ } : i(t);
35
+ }
36
+ function f(e) {
37
+ if (e === "audio-track") return t({ createRecognition: () => {
38
+ let e = c();
39
+ return e ? new e() : null;
40
+ } });
41
+ if (e === "backend-stream") {
42
+ let e = o;
43
+ return n({
44
+ fetchTicket: async () => {
45
+ if (!e) throw Error("streaming not configured");
46
+ let t = e.getAuthorization(), n = await fetch(e.ticketUrl, {
47
+ method: "POST",
48
+ headers: t ? { authorization: t } : {},
49
+ credentials: "include"
50
+ });
51
+ if (!n.ok) throw Error(`ticket ${n.status}`);
52
+ let r = await n.json(), i = typeof r == "object" && r ? r : {};
53
+ if (typeof i.ticket != "string" || typeof i.wsUrl != "string") throw Error("bad ticket response");
54
+ return {
55
+ ticket: i.ticket,
56
+ wsUrl: i.wsUrl
57
+ };
58
+ },
59
+ createSocket: (e, t) => {
60
+ let n = new WebSocket(e, t);
61
+ return n.binaryType = "arraybuffer", {
62
+ get readyState() {
63
+ return n.readyState;
64
+ },
65
+ send: (e) => n.send(e),
66
+ close: (e) => n.close(e),
67
+ listen(e) {
68
+ n.onopen = () => e.open(), n.onerror = () => e.error(), n.onclose = (t) => e.close(t.code), n.onmessage = (t) => e.message(t.data);
69
+ }
70
+ };
71
+ },
72
+ languages: (e) => e.toLowerCase().startsWith("en") ? [e] : [e, "en-IN"]
73
+ });
74
+ }
75
+ return a();
76
+ }
77
+ //#endregion
78
+ export { d as chooseTransport, s as configureHandsFreeStreaming, f as createRuntimeTransport, u as isMobileUserAgent, l as readTransportEnvironment };
@@ -0,0 +1,26 @@
1
+ /**
2
+ * The "Hands-free interrupt (beta)" setting (BOFF-8613, H3).
3
+ *
4
+ * Default OFF. The viewer's choice is persisted in the assistant store
5
+ * (`handsFreeInterrupt`) next to the grace preference; this file is the pure
6
+ * part - how a stored value and the test-only override resolve to a decision.
7
+ *
8
+ * ★ OFF means OFF. With the setting off nothing in this directory runs: no
9
+ * `getUserMedia`, no worklet, no transport, no listener, and the Web Speech
10
+ * path behaves exactly as it did before this change. That is what makes the
11
+ * feature reversible by a toggle.
12
+ *
13
+ * The TEST-ONLY override is a global the headless-browser tests set before the
14
+ * page loads (`globalThis.__boffHandsFreeInterrupt = "on"`), so a test does not
15
+ * have to click through settings. It can only affect the client that set it.
16
+ */
17
+ export type HandsFreeOverride = "on" | "off";
18
+ export declare const HANDS_FREE_OVERRIDE_KEY = "__boffHandsFreeInterrupt";
19
+ export declare const HANDS_FREE_TRANSPORT_OVERRIDE_KEY = "__boffHandsFreeTransport";
20
+ /** The stored value is trusted only if it is exactly `true`; anything else is OFF. */
21
+ export declare function resolveStoredHandsFree(value: unknown): boolean;
22
+ export declare function resolveHandsFreeEnabled(stored: unknown, override: unknown): boolean;
23
+ export declare function readHandsFreeOverride(): HandsFreeOverride | undefined;
24
+ export type TransportOverride = "web-speech" | "audio-track" | "backend-stream";
25
+ export declare function readTransportOverride(): TransportOverride | undefined;
26
+ //# sourceMappingURL=handsFreeSetting.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handsFreeSetting.d.ts","sourceRoot":"","sources":["../../../../../src/shared/assistant/voice/handsfree/handsFreeSetting.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,iBAAiB,GAAG,IAAI,GAAG,KAAK,CAAC;AAE7C,eAAO,MAAM,uBAAuB,6BAA6B,CAAC;AAClE,eAAO,MAAM,iCAAiC,6BAA6B,CAAC;AAE5E,sFAAsF;AACtF,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAE9D;AAED,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,OAAO,EACf,QAAQ,EAAE,OAAO,GAChB,OAAO,CAIT;AAWD,wBAAgB,qBAAqB,IAAI,iBAAiB,GAAG,SAAS,CAGrE;AAED,MAAM,MAAM,iBAAiB,GAAG,YAAY,GAAG,aAAa,GAAG,gBAAgB,CAAC;AAEhF,wBAAgB,qBAAqB,IAAI,iBAAiB,GAAG,SAAS,CAOrE"}
@@ -0,0 +1,25 @@
1
+ //#region src/shared/assistant/voice/handsfree/handsFreeSetting.ts
2
+ var e = "__boffHandsFreeInterrupt", t = "__boffHandsFreeTransport";
3
+ function n(e) {
4
+ return e === !0;
5
+ }
6
+ function r(e, t) {
7
+ return t === "on" ? !0 : t === "off" ? !1 : n(e);
8
+ }
9
+ function i(e) {
10
+ try {
11
+ return globalThis[e];
12
+ } catch {
13
+ return;
14
+ }
15
+ }
16
+ function a() {
17
+ let t = i(e);
18
+ return t === "on" || t === "off" ? t : void 0;
19
+ }
20
+ function o() {
21
+ let e = i(t);
22
+ return e === "web-speech" || e === "audio-track" || e === "backend-stream" ? e : void 0;
23
+ }
24
+ //#endregion
25
+ export { e as HANDS_FREE_OVERRIDE_KEY, t as HANDS_FREE_TRANSPORT_OVERRIDE_KEY, a as readHandsFreeOverride, o as readTransportOverride, r as resolveHandsFreeEnabled, n as resolveStoredHandsFree };
@@ -0,0 +1,21 @@
1
+ import { CaptureFrameMessage } from './captureWorklet';
2
+ export interface MicCaptureHandle {
3
+ context: AudioContext;
4
+ micSource: MediaStreamAudioSourceNode;
5
+ track: MediaStreamTrack;
6
+ /** What the browser reports it applied. */
7
+ settings: MediaTrackSettings;
8
+ /** Stop everything and release the microphone. */
9
+ stop(): void;
10
+ }
11
+ export type MicCaptureFailure = "unsupported" | "not-allowed" | "unavailable";
12
+ export declare class MicCaptureError extends Error {
13
+ readonly reason: MicCaptureFailure;
14
+ constructor(reason: MicCaptureFailure);
15
+ }
16
+ export declare const CAPTURE_CONSTRAINTS: MediaStreamConstraints;
17
+ export declare function isMicCaptureSupported(): boolean;
18
+ /** Labels of output devices that suggest headphones. A HINT only. */
19
+ export declare function looksLikeHeadset(outputLabels: readonly string[]): boolean;
20
+ export declare function startMicCapture(onFrame: (frame: CaptureFrameMessage) => void): Promise<MicCaptureHandle>;
21
+ //# sourceMappingURL=micCapture.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"micCapture.d.ts","sourceRoot":"","sources":["../../../../../src/shared/assistant/voice/handsfree/micCapture.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAGL,KAAK,mBAAmB,EACzB,MAAM,kBAAkB,CAAC;AAM1B,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,YAAY,CAAC;IACtB,SAAS,EAAE,0BAA0B,CAAC;IACtC,KAAK,EAAE,gBAAgB,CAAC;IACxB,2CAA2C;IAC3C,QAAQ,EAAE,kBAAkB,CAAC;IAC7B,kDAAkD;IAClD,IAAI,IAAI,IAAI,CAAC;CACd;AAED,MAAM,MAAM,iBAAiB,GAAG,aAAa,GAAG,aAAa,GAAG,aAAa,CAAC;AAE9E,qBAAa,eAAgB,SAAQ,KAAK;IAC5B,QAAQ,CAAC,MAAM,EAAE,iBAAiB;gBAAzB,MAAM,EAAE,iBAAiB;CAI/C;AAED,eAAO,MAAM,mBAAmB,EAAE,sBAOjC,CAAC;AAEF,wBAAgB,qBAAqB,IAAI,OAAO,CAO/C;AAED,qEAAqE;AACrE,wBAAgB,gBAAgB,CAAC,YAAY,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAIzE;AAED,wBAAsB,eAAe,CACnC,OAAO,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,IAAI,GAC5C,OAAO,CAAC,gBAAgB,CAAC,CA8E3B"}
@@ -0,0 +1,73 @@
1
+ import { attachPlaybackReference as e, detachPlaybackReference as t } from "./playbackReference.js";
2
+ import { CAPTURE_PROCESSOR_NAME as n, CAPTURE_WORKLET_SOURCE as r } from "./captureWorklet.js";
3
+ //#region src/shared/assistant/voice/handsfree/micCapture.ts
4
+ var i = class extends Error {
5
+ reason;
6
+ constructor(e) {
7
+ super(`mic capture failed: ${e}`), this.reason = e, this.name = "MicCaptureError";
8
+ }
9
+ }, a = { audio: {
10
+ echoCancellation: !0,
11
+ noiseSuppression: !0,
12
+ autoGainControl: !0,
13
+ channelCount: 1
14
+ } };
15
+ function o() {
16
+ return typeof navigator < "u" && typeof navigator.mediaDevices?.getUserMedia == "function" && typeof AudioContext < "u" && typeof AudioWorkletNode < "u";
17
+ }
18
+ function s(e) {
19
+ return e.some((e) => /head(phone|set)|earbud|earphone|airpods|buds|bluetooth/i.test(e));
20
+ }
21
+ async function c(s) {
22
+ if (!o()) throw new i("unsupported");
23
+ let c;
24
+ try {
25
+ c = await navigator.mediaDevices.getUserMedia(a);
26
+ } catch (e) {
27
+ let t = e instanceof DOMException ? e.name : "";
28
+ throw new i(t === "NotAllowedError" || t === "SecurityError" ? "not-allowed" : "unavailable");
29
+ }
30
+ let l = c.getAudioTracks()[0];
31
+ if (!l) throw c.getTracks().forEach((e) => e.stop()), new i("unavailable");
32
+ let u = new AudioContext({ latencyHint: "interactive" }), d = () => {
33
+ c.getTracks().forEach((e) => e.stop());
34
+ };
35
+ try {
36
+ await u.resume();
37
+ let i = URL.createObjectURL(new Blob([r], { type: "text/javascript" }));
38
+ try {
39
+ await u.audioWorklet.addModule(i);
40
+ } finally {
41
+ URL.revokeObjectURL(i);
42
+ }
43
+ let a = new AudioWorkletNode(u, n, {
44
+ numberOfInputs: 2,
45
+ numberOfOutputs: 0
46
+ }), o = u.createGain();
47
+ o.connect(a, 0, 1), a.port.onmessage = (e) => s(e.data);
48
+ let f = u.createMediaStreamSource(c);
49
+ f.connect(a, 0, 0), e(u, o);
50
+ let p = !1, m = () => h.stop(), h = {
51
+ context: u,
52
+ micSource: f,
53
+ track: l,
54
+ settings: l.getSettings(),
55
+ stop() {
56
+ if (!p) {
57
+ p = !0, window.removeEventListener("pagehide", m), a.port.onmessage = null;
58
+ try {
59
+ a.port.postMessage({ type: "stop" }), f.disconnect();
60
+ } catch {}
61
+ d(), t(() => {
62
+ u.close().catch(() => void 0);
63
+ });
64
+ }
65
+ }
66
+ };
67
+ return window.addEventListener("pagehide", m), h;
68
+ } catch (e) {
69
+ throw d(), u.close().catch(() => void 0), e instanceof i ? e : new i("unavailable");
70
+ }
71
+ }
72
+ //#endregion
73
+ export { a as CAPTURE_CONSTRAINTS, i as MicCaptureError, o as isMicCaptureSupported, s as looksLikeHeadset, c as startMicCapture };