@burdenoff/fe-libs 2026.1014.4 → 2026.1014.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/shared/assistant/avatar/useAvatarCopy.d.ts +2 -0
- package/dist/shared/assistant/avatar/useAvatarCopy.js +1 -0
- package/dist/shared/assistant/i18nManifest.d.ts +1 -0
- package/dist/shared/assistant/i18nManifest.js +1 -0
- package/dist/shared/assistant/ui/AIAssistantPanel.js +20 -20
- package/dist/shared/assistant/ui/assistantLiveAvatarSeam.d.ts +28 -0
- package/dist/shared/assistant/ui/assistantLiveAvatarSeam.js +66 -43
- package/dist/shared/assistant/ui/composer/AssistantHandsFreeInterruptToggle.d.ts +9 -0
- package/dist/shared/assistant/ui/composer/AssistantHandsFreeInterruptToggle.js +28 -14
- package/dist/shared/assistant/ui/useVoiceSession.js +234 -233
- package/dist/shared/assistant/ui/voice/AssistantVoiceSession.js +183 -177
- package/dist/shared/assistant/ui/voice/VoiceMiniController.js +7 -7
- package/dist/shared/assistant/ui/voice/VoiceStage.js +7 -7
- package/dist/shared/assistant/voice/handsfree/handsFreeSetting.d.ts +7 -1
- package/dist/shared/assistant/voice/handsfree/handsFreeSetting.js +2 -2
- package/dist/shared-assistant.js +185 -185
- package/package.json +1 -1
|
@@ -3,282 +3,288 @@ import { useAssistantControl as t } from "../../appControls/useAssistantControl.
|
|
|
3
3
|
import { useAssistantTr as n } from "../../i18n.js";
|
|
4
4
|
import { micIsInterrupt as r, showsAssistantCaption as ee, voiceStageState as i } from "../../voice/voiceStageState.js";
|
|
5
5
|
import { VOICE_THINKING_LABEL as a, composeVoiceStatus as te, voiceStatusSuffix as ne } from "../../voice/voiceStatus.js";
|
|
6
|
-
import { spokenSoFar as
|
|
7
|
-
import {
|
|
8
|
-
import { AssistantAttachmentChips as ie } from "../composer/AssistantAttachmentChips.js";
|
|
6
|
+
import { spokenSoFar as re } from "../../voice/voiceSession.js";
|
|
7
|
+
import { useAvatarCopy as ie } from "../../avatar/useAvatarCopy.js";
|
|
9
8
|
import { ASSISTANT_PANEL_ATTR as ae, ASSISTANT_VOICE_SESSION_ATTR as oe } from "../panelOverlays.js";
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
9
|
+
import { useLiveAvatarHandsFreeGuard as se, useLiveAvatarVoiceView as ce } from "../assistantLiveAvatarSeam.js";
|
|
10
|
+
import { AssistantAttachmentButton as le } from "../composer/AssistantAttachmentButton.js";
|
|
11
|
+
import { AssistantAttachmentChips as ue } from "../composer/AssistantAttachmentChips.js";
|
|
12
|
+
import { AssistantVoiceOrb as de } from "./AssistantVoiceOrb.js";
|
|
13
|
+
import { VoiceMiniController as fe } from "./VoiceMiniController.js";
|
|
14
|
+
import { VoiceStage as pe } from "./VoiceStage.js";
|
|
15
|
+
import { VoiceTranscriptDrawer as me } from "./VoiceTranscriptDrawer.js";
|
|
16
|
+
import { escapeBelongsToLayerAbove as he, voiceSessionEscapeAction as ge } from "./voiceSessionEscape.js";
|
|
17
|
+
import { HandsFreePrivacyNotice as _e } from "./HandsFreePrivacyNotice.js";
|
|
18
|
+
import { useCallback as o, useEffect as s, useMemo as ve, useRef as c, useState as l } from "react";
|
|
19
|
+
import { Maximize2 as ye, Minimize2 as be, ScrollText as xe, X as u } from "lucide-react";
|
|
20
|
+
import { jsx as d, jsxs as f } from "react/jsx-runtime";
|
|
20
21
|
//#region src/shared/assistant/ui/voice/AssistantVoiceSession.tsx
|
|
21
|
-
var
|
|
22
|
-
let
|
|
23
|
-
t("assistant.transcript",
|
|
24
|
-
let
|
|
25
|
-
|
|
26
|
-
let
|
|
27
|
-
|
|
28
|
-
}, [
|
|
29
|
-
|
|
30
|
-
}, []),
|
|
31
|
-
|
|
22
|
+
var p = ({ session: p, turns: we = [], onSaveTranscript: Te, onContinueInChat: Ee, notice: m = null, privacyNotice: h = null, spoken: g, onInterrupt: De, onToggleMute: _, attachments: v = [], onAttachFiles: y, onRemoveAttachment: Oe, onRetryAttachment: ke, canAttachMore: Ae = !0, preparingAttachments: b = 0, attachmentsLocked: x = !1, attachmentNotice: S = null, spokenChunks: C = null, onEnd: w, capturing: je = !0, interrupting: Me = !1, awaitingEndpoint: Ne = !1, holding: T = !1, correcting: Pe = !1, onLetMeFinish: E, onImDone: D, proposalChip: O = null, proposalTray: k = null, renderAfterTurn: Fe }) => {
|
|
23
|
+
let A = n(), { muted: j, error: M } = p, N = c(null), P = c(null), [Ie, F] = l("mini"), I = ce(Ie, p.phase === "ended"), Le = se(), L = ie(), R = I === "full", z = I === "mini", B = I === "mini" ? "panel" : I === "panel" ? "full" : "mini", [V, H] = l(!1);
|
|
24
|
+
t("assistant.transcript", ve(() => ({ run: () => V ? { status: "already" } : (H(!0), { status: "done" }) }), [V]));
|
|
25
|
+
let U = k !== null && !z, W = c(!1), G = c(_);
|
|
26
|
+
G.current = _;
|
|
27
|
+
let K = o(() => {
|
|
28
|
+
p.phase !== "listening" && p.phase !== "thinking" || j || W.current || re(p) || (W.current = !0, G.current());
|
|
29
|
+
}, [j, p]), q = o(() => {
|
|
30
|
+
W.current && (W.current = !1, G.current());
|
|
31
|
+
}, []), Re = K;
|
|
32
|
+
s(() => {
|
|
32
33
|
let e = () => {
|
|
33
|
-
document.visibilityState === "hidden" ?
|
|
34
|
+
document.visibilityState === "hidden" ? K() : q();
|
|
34
35
|
};
|
|
35
36
|
return document.addEventListener("visibilitychange", e), () => document.removeEventListener("visibilitychange", e);
|
|
36
|
-
}, [
|
|
37
|
-
let e =
|
|
37
|
+
}, [K, q]), s(() => {
|
|
38
|
+
let e = q;
|
|
38
39
|
return window.addEventListener("focus", e), () => {
|
|
39
|
-
window.removeEventListener("focus", e),
|
|
40
|
+
window.removeEventListener("focus", e), W.current = !1;
|
|
40
41
|
};
|
|
41
|
-
}, []),
|
|
42
|
-
document.activeElement?.closest("[data-hands-free-notice]") ||
|
|
43
|
-
}, []), e(
|
|
42
|
+
}, []), s(() => {
|
|
43
|
+
document.activeElement?.closest("[data-hands-free-notice]") || N.current?.focus();
|
|
44
|
+
}, []), e(P, { fallbackSelector: `[${ae}]` }), s(() => {
|
|
44
45
|
let e = (e) => {
|
|
45
46
|
if (e.key === "Escape") {
|
|
46
|
-
let t =
|
|
47
|
+
let t = ge({
|
|
47
48
|
defaultPrevented: e.defaultPrevented,
|
|
48
|
-
layerAbove:
|
|
49
|
+
layerAbove: he({
|
|
49
50
|
target: e.target,
|
|
50
|
-
session:
|
|
51
|
+
session: P.current,
|
|
51
52
|
doc: document
|
|
52
53
|
}),
|
|
53
|
-
transcriptOpen:
|
|
54
|
+
transcriptOpen: V
|
|
54
55
|
});
|
|
55
56
|
if (t === "ignore") return;
|
|
56
|
-
e.preventDefault(), t === "close-transcript" ?
|
|
57
|
+
e.preventDefault(), t === "close-transcript" ? H(!1) : h ? h.decline() : U ? k?.onClose() : w();
|
|
57
58
|
return;
|
|
58
59
|
}
|
|
59
|
-
if (e.key !== "Tab" || !
|
|
60
|
-
let t = (
|
|
60
|
+
if (e.key !== "Tab" || !R) return;
|
|
61
|
+
let t = (V ? P.current?.querySelector("[data-testid=\"assistant-voice-transcript\"]") : P.current)?.querySelectorAll("button:not([disabled])");
|
|
61
62
|
if (!t || t.length === 0) return;
|
|
62
63
|
let n = t[0], r = t[t.length - 1];
|
|
63
64
|
!n || !r || (e.shiftKey && document.activeElement === n ? (e.preventDefault(), r.focus()) : !e.shiftKey && document.activeElement === r && (e.preventDefault(), n.focus()));
|
|
64
65
|
};
|
|
65
66
|
return window.addEventListener("keydown", e), () => window.removeEventListener("keydown", e);
|
|
66
67
|
}, [
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
68
|
+
w,
|
|
69
|
+
R,
|
|
70
|
+
V,
|
|
71
|
+
U,
|
|
72
|
+
k,
|
|
73
|
+
h
|
|
73
74
|
]);
|
|
74
|
-
let
|
|
75
|
-
letMeFinish:
|
|
76
|
-
imDone:
|
|
77
|
-
} : null,
|
|
78
|
-
|
|
79
|
-
if (
|
|
75
|
+
let J = m !== null && M === null, Y = Le && m === null && M === null, ze = re(p), X = E && D && p.phase === "listening" && !j && M === null ? {
|
|
76
|
+
letMeFinish: E,
|
|
77
|
+
imDone: D
|
|
78
|
+
} : null, Be = X !== null;
|
|
79
|
+
s(() => {
|
|
80
|
+
if (Be) return;
|
|
80
81
|
let e = document.activeElement;
|
|
81
|
-
(!e || e === document.body) &&
|
|
82
|
-
}, [
|
|
83
|
-
let
|
|
84
|
-
snapshot:
|
|
85
|
-
capturing:
|
|
86
|
-
interrupting:
|
|
87
|
-
awaitingEndpoint:
|
|
88
|
-
}),
|
|
89
|
-
switch (
|
|
90
|
-
case "connecting": return
|
|
91
|
-
case "endpoint-grace": return
|
|
92
|
-
case "interrupting": return
|
|
93
|
-
case "thinking": return
|
|
94
|
-
case "speaking": return
|
|
82
|
+
(!e || e === document.body) && N.current?.focus();
|
|
83
|
+
}, [Be]);
|
|
84
|
+
let Z = i({
|
|
85
|
+
snapshot: p,
|
|
86
|
+
capturing: je,
|
|
87
|
+
interrupting: Me,
|
|
88
|
+
awaitingEndpoint: Ne
|
|
89
|
+
}), Ve = (() => {
|
|
90
|
+
switch (Z) {
|
|
91
|
+
case "connecting": return A("voiceSession.connecting", "Starting the microphone…");
|
|
92
|
+
case "endpoint-grace": return A("voiceSession.endpointGrace", "Still listening — take your time");
|
|
93
|
+
case "interrupting": return A("voiceSession.interrupting", "Stopped — go ahead");
|
|
94
|
+
case "thinking": return A(a.key, a.fallback);
|
|
95
|
+
case "speaking": return A("voiceSession.speaking", "Speaking — tap to stop");
|
|
95
96
|
case "mic-error":
|
|
96
97
|
case "ended": return "";
|
|
97
|
-
case "listening": return
|
|
98
|
-
default: return
|
|
98
|
+
case "listening": return j ? A("voiceSession.muted", "Microphone off") : A("voiceSession.listening", "Listening…");
|
|
99
|
+
default: return Z;
|
|
99
100
|
}
|
|
100
|
-
})(),
|
|
101
|
-
tr:
|
|
102
|
-
stage:
|
|
103
|
-
muted:
|
|
104
|
-
label:
|
|
105
|
-
}),
|
|
106
|
-
return /* @__PURE__ */
|
|
107
|
-
ref:
|
|
108
|
-
className: `flex flex-col items-center justify-between bg-bg-sunken ${
|
|
101
|
+
})(), He = !j && (Z === "listening" || Z === "endpoint-grace"), Ue = He && T ? A("voiceSession.holding", "Take your time — tap “I’m done” when you finish") : He && Pe ? A("voiceSession.correcting", "Stopped that answer — listening to your correction") : Ve, Q = ne({
|
|
102
|
+
tr: A,
|
|
103
|
+
stage: Z,
|
|
104
|
+
muted: j,
|
|
105
|
+
label: Ue
|
|
106
|
+
}), We = te(Ue, Q), $ = Z === "thinking";
|
|
107
|
+
return /* @__PURE__ */ f("div", {
|
|
108
|
+
ref: P,
|
|
109
|
+
className: `flex flex-col items-center justify-between bg-bg-sunken ${I === "full" ? "fixed inset-x-0 bottom-0 top-14 z-[60] px-6 py-8" : I === "panel" ? "absolute inset-0 z-20 px-4 py-6" : "absolute inset-x-0 bottom-0 z-20 min-h-[11.25rem] border-t border-border-subtle px-3 py-3 shadow-lg"}`,
|
|
109
110
|
role: "dialog",
|
|
110
|
-
"aria-modal":
|
|
111
|
-
"aria-label":
|
|
111
|
+
"aria-modal": R || void 0,
|
|
112
|
+
"aria-label": A("voiceSession.title", "Voice conversation"),
|
|
112
113
|
"data-testid": "assistant-voice-session",
|
|
113
114
|
[oe]: "",
|
|
114
115
|
children: [
|
|
115
|
-
/* @__PURE__ */
|
|
116
|
-
ref:
|
|
116
|
+
/* @__PURE__ */ f("button", {
|
|
117
|
+
ref: N,
|
|
117
118
|
type: "button",
|
|
118
|
-
onClick:
|
|
119
|
-
className: `absolute ${
|
|
120
|
-
title:
|
|
119
|
+
onClick: w,
|
|
120
|
+
className: `absolute ${R ? "right-6 top-6 h-14 gap-2 px-5 text-base" : z ? "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`,
|
|
121
|
+
title: A("voiceSession.end", "End the voice conversation"),
|
|
121
122
|
"data-testid": "assistant-voice-end",
|
|
122
|
-
children: [/* @__PURE__ */
|
|
123
|
-
className:
|
|
123
|
+
children: [/* @__PURE__ */ d(u, {
|
|
124
|
+
className: R ? "size-6" : z ? "size-4" : "size-5",
|
|
124
125
|
"aria-hidden": "true"
|
|
125
|
-
}), /* @__PURE__ */
|
|
126
|
-
className: `truncate whitespace-nowrap font-medium ${
|
|
127
|
-
children:
|
|
126
|
+
}), /* @__PURE__ */ d("span", {
|
|
127
|
+
className: `truncate whitespace-nowrap font-medium ${z ? "max-w-[3.5rem] text-xs" : "max-w-[7rem]"}`,
|
|
128
|
+
children: A("voiceSession.endShort", "End")
|
|
128
129
|
})]
|
|
129
130
|
}),
|
|
130
|
-
/* @__PURE__ */
|
|
131
|
-
className: `flex flex-col items-center ${
|
|
131
|
+
/* @__PURE__ */ f("div", {
|
|
132
|
+
className: `flex flex-col items-center ${z ? `px-3 ${J || Y || S ? "pt-9 pb-2" : ""}` : `min-h-[1.5rem] ${J || Y || S ? R ? "pt-14" : "pt-10" : ""}`}`,
|
|
132
133
|
children: [
|
|
133
|
-
|
|
134
|
+
J ? /* @__PURE__ */ d("p", {
|
|
134
135
|
className: "max-w-xs text-center text-xs text-status-warning",
|
|
135
136
|
"data-testid": "assistant-voice-notice",
|
|
136
|
-
children:
|
|
137
|
+
children: Se(m, A)
|
|
138
|
+
}) : null,
|
|
139
|
+
Y ? /* @__PURE__ */ d("p", {
|
|
140
|
+
className: "max-w-xs text-center text-xs text-text-secondary",
|
|
141
|
+
"data-testid": "assistant-voice-avatar-hands-free",
|
|
142
|
+
children: L.handsFreeOff
|
|
137
143
|
}) : null,
|
|
138
|
-
/* @__PURE__ */
|
|
144
|
+
/* @__PURE__ */ d("span", {
|
|
139
145
|
className: "sr-only start-0 top-0",
|
|
140
146
|
role: "status",
|
|
141
147
|
"aria-live": "polite",
|
|
142
148
|
"aria-atomic": "true",
|
|
143
149
|
"data-testid": "assistant-voice-notice-announced",
|
|
144
|
-
children:
|
|
150
|
+
children: J && m === "reply-not-heard" ? Se(m, A) : Y ? L.handsFreeOff : null
|
|
145
151
|
}),
|
|
146
|
-
|
|
152
|
+
S ? /* @__PURE__ */ d("p", {
|
|
147
153
|
className: "max-w-xs text-center text-xs text-status-warning",
|
|
148
154
|
role: "status",
|
|
149
155
|
"aria-live": "polite",
|
|
150
156
|
"data-testid": "assistant-voice-attachment-notice",
|
|
151
|
-
children:
|
|
157
|
+
children: S
|
|
152
158
|
}) : null
|
|
153
159
|
]
|
|
154
160
|
}),
|
|
155
161
|
(() => {
|
|
156
|
-
let e = /* @__PURE__ */
|
|
157
|
-
session:
|
|
158
|
-
compact:
|
|
159
|
-
connecting:
|
|
160
|
-
onPress: r(
|
|
161
|
-
label: r(
|
|
162
|
-
}), t =
|
|
162
|
+
let e = /* @__PURE__ */ d(de, {
|
|
163
|
+
session: p,
|
|
164
|
+
compact: z,
|
|
165
|
+
connecting: Z === "connecting",
|
|
166
|
+
onPress: r(Z) ? De : _,
|
|
167
|
+
label: r(Z) ? A("voiceSession.interrupt", "Stop the assistant and speak") : j ? A("voiceSession.unmute", "Turn the microphone on") : A("voiceSession.mute", "Turn the microphone off")
|
|
168
|
+
}), t = X ? /* @__PURE__ */ d("button", {
|
|
163
169
|
type: "button",
|
|
164
|
-
onClick:
|
|
165
|
-
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 ${
|
|
166
|
-
title:
|
|
170
|
+
onClick: T ? X.imDone : X.letMeFinish,
|
|
171
|
+
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 ${z ? "h-7 px-3 text-xs" : R ? "h-11 px-6 text-base" : "h-9 px-4 text-sm"} ${T ? "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"}`,
|
|
172
|
+
title: T ? A("voiceSession.imDoneHint", "Send what you said now") : A("voiceSession.letMeFinishHint", "Pause sending until you tap “I’m done”"),
|
|
167
173
|
"data-testid": "assistant-voice-hold",
|
|
168
|
-
"data-holding":
|
|
169
|
-
children:
|
|
170
|
-
}) : null, n = t ? /* @__PURE__ */
|
|
174
|
+
"data-holding": T ? "true" : "false",
|
|
175
|
+
children: T ? A("voiceSession.imDone", "I’m done") : A("voiceSession.letMeFinish", "Let me finish")
|
|
176
|
+
}) : null, n = t ? /* @__PURE__ */ f("div", {
|
|
171
177
|
className: "flex flex-col items-center gap-2",
|
|
172
178
|
children: [e, t]
|
|
173
|
-
}) : e, i = ee(
|
|
174
|
-
return
|
|
175
|
-
spokenChunks:
|
|
176
|
-
state:
|
|
179
|
+
}) : e, i = ee(Z) ? g : ze || null, a = M === null ? null : Ce(M, A);
|
|
180
|
+
return z ? /* @__PURE__ */ d(fe, {
|
|
181
|
+
spokenChunks: C,
|
|
182
|
+
state: Z,
|
|
177
183
|
caption: i,
|
|
178
|
-
statusText:
|
|
179
|
-
statusSuffix:
|
|
180
|
-
rotateStatus:
|
|
184
|
+
statusText: We,
|
|
185
|
+
statusSuffix: Q,
|
|
186
|
+
rotateStatus: $,
|
|
181
187
|
errorText: a,
|
|
182
188
|
control: n
|
|
183
|
-
}) : /* @__PURE__ */
|
|
184
|
-
state:
|
|
185
|
-
userCaption:
|
|
186
|
-
spokenChunks:
|
|
187
|
-
assistantCaption:
|
|
188
|
-
expanded:
|
|
189
|
-
statusText:
|
|
190
|
-
statusSuffix:
|
|
191
|
-
rotateStatus:
|
|
189
|
+
}) : /* @__PURE__ */ d(pe, {
|
|
190
|
+
state: Z,
|
|
191
|
+
userCaption: ze || null,
|
|
192
|
+
spokenChunks: C,
|
|
193
|
+
assistantCaption: g,
|
|
194
|
+
expanded: R,
|
|
195
|
+
statusText: We,
|
|
196
|
+
statusSuffix: Q,
|
|
197
|
+
rotateStatus: $,
|
|
192
198
|
errorText: a,
|
|
193
199
|
control: n
|
|
194
200
|
});
|
|
195
201
|
})(),
|
|
196
|
-
|
|
197
|
-
className:
|
|
198
|
-
children: /* @__PURE__ */
|
|
202
|
+
O && !U ? /* @__PURE__ */ d("div", {
|
|
203
|
+
className: z ? "absolute left-20 right-36 top-2 flex justify-center" : `flex w-full justify-center ${R ? "max-w-[calc(100%-12rem)]" : "max-w-[calc(100%-8rem)]"}`,
|
|
204
|
+
children: /* @__PURE__ */ d("button", {
|
|
199
205
|
type: "button",
|
|
200
206
|
onClick: () => {
|
|
201
|
-
|
|
207
|
+
F("panel"), O.onOpen();
|
|
202
208
|
},
|
|
203
|
-
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 ${
|
|
209
|
+
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 ${z ? "h-8 px-3 text-xs" : "h-10 px-4 text-sm"}`,
|
|
204
210
|
"data-testid": "assistant-voice-proposal-chip",
|
|
205
|
-
children:
|
|
211
|
+
children: O.label
|
|
206
212
|
})
|
|
207
213
|
}) : null,
|
|
208
|
-
|
|
209
|
-
className: `absolute z-10 flex flex-col gap-2 overflow-y-auto rounded-lg border border-border-subtle bg-bg-elevated shadow-lg ${
|
|
214
|
+
k && U ? /* @__PURE__ */ f("div", {
|
|
215
|
+
className: `absolute z-10 flex flex-col gap-2 overflow-y-auto rounded-lg border border-border-subtle bg-bg-elevated shadow-lg ${R ? "inset-x-6 bottom-24 top-24 mx-auto max-w-xl p-4" : "inset-x-3 bottom-16 top-16 p-3"}`,
|
|
210
216
|
"data-testid": "assistant-voice-proposal-tray",
|
|
211
|
-
children: [/* @__PURE__ */
|
|
217
|
+
children: [/* @__PURE__ */ d("div", {
|
|
212
218
|
className: "flex justify-end",
|
|
213
|
-
children: /* @__PURE__ */
|
|
219
|
+
children: /* @__PURE__ */ d("button", {
|
|
214
220
|
type: "button",
|
|
215
|
-
onClick:
|
|
221
|
+
onClick: k.onClose,
|
|
216
222
|
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",
|
|
217
|
-
"aria-label":
|
|
223
|
+
"aria-label": k.closeLabel,
|
|
218
224
|
"data-testid": "assistant-voice-proposal-tray-close",
|
|
219
|
-
children: /* @__PURE__ */
|
|
225
|
+
children: /* @__PURE__ */ d(u, {
|
|
220
226
|
className: "size-4",
|
|
221
227
|
"aria-hidden": "true"
|
|
222
228
|
})
|
|
223
229
|
})
|
|
224
|
-
}),
|
|
230
|
+
}), k.content]
|
|
225
231
|
}) : null,
|
|
226
|
-
|
|
227
|
-
view:
|
|
228
|
-
onContinue:
|
|
229
|
-
onNotNow:
|
|
232
|
+
h ? /* @__PURE__ */ d(_e, {
|
|
233
|
+
view: I,
|
|
234
|
+
onContinue: h.accept,
|
|
235
|
+
onNotNow: h.decline
|
|
230
236
|
}) : null,
|
|
231
|
-
|
|
232
|
-
turns:
|
|
233
|
-
onClose: () =>
|
|
234
|
-
onSave:
|
|
235
|
-
onContinueInChat:
|
|
236
|
-
renderAfterTurn:
|
|
237
|
+
V ? /* @__PURE__ */ d(me, {
|
|
238
|
+
turns: we,
|
|
239
|
+
onClose: () => H(!1),
|
|
240
|
+
onSave: Te,
|
|
241
|
+
onContinueInChat: Ee,
|
|
242
|
+
renderAfterTurn: Fe
|
|
237
243
|
}) : null,
|
|
238
|
-
|
|
239
|
-
className: `absolute ${
|
|
240
|
-
children: /* @__PURE__ */
|
|
244
|
+
y ? /* @__PURE__ */ d("div", {
|
|
245
|
+
className: `absolute ${R ? "left-6 top-6" : z ? "left-11 top-2" : "left-3 top-3"}`,
|
|
246
|
+
children: /* @__PURE__ */ d(le, {
|
|
241
247
|
onFiles: (e) => {
|
|
242
|
-
|
|
248
|
+
y(e), F((e) => e === "mini" ? "panel" : e);
|
|
243
249
|
},
|
|
244
|
-
onPickerOpen:
|
|
250
|
+
onPickerOpen: Re,
|
|
245
251
|
direction: "down",
|
|
246
|
-
canAddMore:
|
|
247
|
-
disabled:
|
|
252
|
+
canAddMore: Ae,
|
|
253
|
+
disabled: x
|
|
248
254
|
})
|
|
249
255
|
}) : null,
|
|
250
|
-
(
|
|
251
|
-
className: `absolute ${
|
|
256
|
+
(v.length > 0 || b > 0) && !z ? /* @__PURE__ */ d("div", {
|
|
257
|
+
className: `absolute ${R ? "bottom-24 left-24 right-24" : "bottom-16 left-16 right-16"}`,
|
|
252
258
|
"data-testid": "assistant-voice-attachments",
|
|
253
|
-
children: /* @__PURE__ */
|
|
254
|
-
attachments:
|
|
255
|
-
onRemove:
|
|
256
|
-
onRetry:
|
|
257
|
-
preparingCount:
|
|
258
|
-
disabled:
|
|
259
|
+
children: /* @__PURE__ */ d(ue, {
|
|
260
|
+
attachments: v,
|
|
261
|
+
onRemove: Oe ?? (() => void 0),
|
|
262
|
+
onRetry: ke ?? (() => void 0),
|
|
263
|
+
preparingCount: b,
|
|
264
|
+
disabled: x
|
|
259
265
|
})
|
|
260
266
|
}) : null,
|
|
261
|
-
/* @__PURE__ */
|
|
267
|
+
/* @__PURE__ */ d("button", {
|
|
262
268
|
type: "button",
|
|
263
|
-
onClick: () =>
|
|
264
|
-
className: `absolute ${
|
|
265
|
-
"aria-pressed":
|
|
266
|
-
"aria-label":
|
|
269
|
+
onClick: () => H((e) => !e),
|
|
270
|
+
className: `absolute ${R ? "bottom-6 right-6 size-14" : z ? "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`,
|
|
271
|
+
"aria-pressed": V,
|
|
272
|
+
"aria-label": A("voiceSession.transcriptTitle", "Voice transcript"),
|
|
267
273
|
"data-testid": "assistant-voice-transcript-toggle",
|
|
268
|
-
children: /* @__PURE__ */
|
|
274
|
+
children: /* @__PURE__ */ d(xe, { className: R ? "size-6" : z ? "size-4" : "size-5" })
|
|
269
275
|
}),
|
|
270
|
-
/* @__PURE__ */
|
|
276
|
+
/* @__PURE__ */ d("button", {
|
|
271
277
|
type: "button",
|
|
272
|
-
onClick: () =>
|
|
273
|
-
className: `absolute ${
|
|
274
|
-
"aria-label":
|
|
278
|
+
onClick: () => F(B),
|
|
279
|
+
className: `absolute ${R ? "bottom-6 left-6 size-14" : z ? "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`,
|
|
280
|
+
"aria-label": B === "panel" ? A("voiceSession.expandPanel", "Show the conversation in the panel") : B === "full" ? A("voiceSession.expand", "Expand the conversation to full screen") : A("voiceSession.collapse", "Shrink to the compact controller"),
|
|
275
281
|
"data-testid": "assistant-voice-expand",
|
|
276
|
-
children:
|
|
282
|
+
children: R ? /* @__PURE__ */ d(be, { className: "size-5" }) : /* @__PURE__ */ d(ye, { className: z ? "size-4" : "size-5" })
|
|
277
283
|
})
|
|
278
284
|
]
|
|
279
285
|
});
|
|
280
286
|
};
|
|
281
|
-
function
|
|
287
|
+
function Se(e, t) {
|
|
282
288
|
switch (e) {
|
|
283
289
|
case "network": return t("voiceSession.noticeNetwork", "Speech recognition lost its connection. Check your network — it will retry.");
|
|
284
290
|
case "not-capturing": return t("voiceSession.noticeNotCapturing", "The microphone did not start. Check that this site is allowed to use it, then try again.");
|
|
@@ -290,7 +296,7 @@ function h(e, t) {
|
|
|
290
296
|
default: return e;
|
|
291
297
|
}
|
|
292
298
|
}
|
|
293
|
-
function
|
|
299
|
+
function Ce(e, t) {
|
|
294
300
|
switch (e) {
|
|
295
301
|
case "mic-denied": return t("voiceSession.micDenied", "Microphone access is blocked. Allow it in your browser settings to talk.");
|
|
296
302
|
case "no-speech-support": return t("voiceSession.noSpeechSupport", "This browser cannot listen. Try a different browser, or type instead.");
|
|
@@ -299,4 +305,4 @@ function ye(e, t) {
|
|
|
299
305
|
}
|
|
300
306
|
}
|
|
301
307
|
//#endregion
|
|
302
|
-
export {
|
|
308
|
+
export { p as AssistantVoiceSession };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { showsAssistantCaption as e, waveformIsActive as t, waveformIsSettled as n } from "../../voice/voiceStageState.js";
|
|
2
2
|
import { showPreviousChunk as r } from "../../voice/miniCaptionBudget.js";
|
|
3
3
|
import { isAwaitingFirstChunk as i } from "../../voice/speechPlayback.js";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
4
|
+
import { LiveAvatarMiniIndicator as a, useLiveAvatarMiniIndicatorShown as o } from "../assistantLiveAvatarSeam.js";
|
|
5
|
+
import { VoiceWaveform as s } from "./VoiceWaveform.js";
|
|
6
|
+
import { VoiceStatusText as c } from "./VoiceStatusText.js";
|
|
7
7
|
import { Fragment as l, jsx as u, jsxs as d } from "react/jsx-runtime";
|
|
8
8
|
//#region src/shared/assistant/ui/voice/VoiceMiniController.tsx
|
|
9
9
|
var f = " self-stretch justify-end pb-8.5 [container-type:size] [@container_(min-height:4.0312rem)_and_(max-height:5.2343rem)]:[&>p[role=status]]:line-clamp-2 [@container_(max-height:4.0312rem)]:[&>p[role=status]]:line-clamp-1 [@container_(max-height:4.0312rem)]:[&>p[role=status]]:min-h-5 [@container_(max-height:5.2343rem)]:[&>p[role=status]>span:not(:last-child)]:sr-only", p = ({ state: p, caption: m, spokenChunks: h = null, statusText: g, statusSuffix: _, rotateStatus: v, control: y, errorText: b = null }) => {
|
|
@@ -14,14 +14,14 @@ var f = " self-stretch justify-end pb-8.5 [container-type:size] [@container_(min
|
|
|
14
14
|
"data-state": p,
|
|
15
15
|
children: [
|
|
16
16
|
/* @__PURE__ */ d("div", {
|
|
17
|
-
className: `flex min-w-0 flex-1 flex-col gap-1.5${
|
|
17
|
+
className: `flex min-w-0 flex-1 flex-col gap-1.5${o() ? f : ""}`,
|
|
18
18
|
children: [/* @__PURE__ */ d("div", {
|
|
19
19
|
className: "flex items-center gap-2",
|
|
20
|
-
children: [/* @__PURE__ */ u(
|
|
20
|
+
children: [/* @__PURE__ */ u(s, {
|
|
21
21
|
active: t(p),
|
|
22
22
|
settled: n(p),
|
|
23
23
|
tone: p === "speaking" ? "speaking" : "listening"
|
|
24
|
-
}), /* @__PURE__ */ u(
|
|
24
|
+
}), /* @__PURE__ */ u(c, {
|
|
25
25
|
className: "truncate text-xs text-text-muted",
|
|
26
26
|
status: g,
|
|
27
27
|
suffix: _,
|
|
@@ -58,7 +58,7 @@ var f = " self-stretch justify-end pb-8.5 [container-type:size] [@container_(min
|
|
|
58
58
|
className: "shrink-0",
|
|
59
59
|
children: y
|
|
60
60
|
}),
|
|
61
|
-
/* @__PURE__ */ u(
|
|
61
|
+
/* @__PURE__ */ u(a, {})
|
|
62
62
|
]
|
|
63
63
|
});
|
|
64
64
|
};
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { showsAssistantCaption as e, showsUserCaption as t, waveformIsActive as n, waveformIsSettled as r } from "../../voice/voiceStageState.js";
|
|
2
2
|
import { isAwaitingFirstChunk as i } from "../../voice/speechPlayback.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
3
|
+
import { useLiveAvatarStage as a } from "../assistantLiveAvatarSeam.js";
|
|
4
|
+
import { VoiceCaption as o } from "./VoiceCaption.js";
|
|
5
|
+
import { VoiceWaveform as s } from "./VoiceWaveform.js";
|
|
6
|
+
import { VoiceStatusText as c } from "./VoiceStatusText.js";
|
|
7
7
|
import { Fragment as l, jsx as u, jsxs as d } from "react/jsx-runtime";
|
|
8
8
|
//#region src/shared/assistant/ui/voice/VoiceStage.tsx
|
|
9
9
|
var f = ({ state: f, userCaption: p, assistantCaption: m, expanded: h, statusText: g, statusSuffix: _, rotateStatus: v, control: y, errorText: b = null, spokenChunks: x = null }) => {
|
|
10
|
-
let S =
|
|
10
|
+
let S = a(), C = e(f) && i(x), w = e(f) ? m : t(f) ? p : null, T = /* @__PURE__ */ u(s, {
|
|
11
11
|
active: n(f),
|
|
12
12
|
settled: r(f),
|
|
13
13
|
tone: f === "speaking" ? "speaking" : "listening",
|
|
@@ -22,7 +22,7 @@ var f = ({ state: f, userCaption: p, assistantCaption: m, expanded: h, statusTex
|
|
|
22
22
|
"data-testid": "assistant-voice-stage",
|
|
23
23
|
"data-state": f,
|
|
24
24
|
children: [
|
|
25
|
-
/* @__PURE__ */ u(
|
|
25
|
+
/* @__PURE__ */ u(c, {
|
|
26
26
|
className: [
|
|
27
27
|
"text-center text-text-muted",
|
|
28
28
|
h ? "text-base" : "text-sm",
|
|
@@ -46,7 +46,7 @@ var f = ({ state: f, userCaption: p, assistantCaption: m, expanded: h, statusTex
|
|
|
46
46
|
}), w ? /* @__PURE__ */ u("div", {
|
|
47
47
|
className: [h ? "mb-12 max-h-[46vh] w-full overflow-y-auto" : "mb-6 max-h-[38vh] w-full overflow-y-auto", C ? h ? "min-h-[4.875rem]" : "min-h-12" : ""].join(" "),
|
|
48
48
|
"data-caption-scroll": "",
|
|
49
|
-
children: /* @__PURE__ */ u(
|
|
49
|
+
children: /* @__PURE__ */ u(o, {
|
|
50
50
|
text: w,
|
|
51
51
|
role: e(f) ? "assistant" : "user",
|
|
52
52
|
spokenChunks: x,
|
|
@@ -19,7 +19,13 @@ export declare const HANDS_FREE_OVERRIDE_KEY = "__boffHandsFreeInterrupt";
|
|
|
19
19
|
export declare const HANDS_FREE_TRANSPORT_OVERRIDE_KEY = "__boffHandsFreeTransport";
|
|
20
20
|
/** The stored value is trusted only if it is exactly `true`; anything else is OFF. */
|
|
21
21
|
export declare function resolveStoredHandsFree(value: unknown): boolean;
|
|
22
|
-
|
|
22
|
+
/**
|
|
23
|
+
* ★ BOFF-8822, the avatar pilot: never while a live avatar is ON, the test
|
|
24
|
+
* override included (`useLiveAvatarHandsFreeGuard`). Its voice plays on the
|
|
25
|
+
* speakers, where the microphone hears it, and hands-free would take it for
|
|
26
|
+
* the person speaking over the reply. Without an avatar, as before.
|
|
27
|
+
*/
|
|
28
|
+
export declare function resolveHandsFreeEnabled(stored: unknown, override: unknown, avatarOn?: boolean): boolean;
|
|
23
29
|
export declare function readHandsFreeOverride(): HandsFreeOverride | undefined;
|
|
24
30
|
export type TransportOverride = "web-speech" | "audio-track" | "backend-stream";
|
|
25
31
|
export declare function readTransportOverride(): TransportOverride | undefined;
|
|
@@ -3,8 +3,8 @@ var e = "__boffHandsFreeInterrupt", t = "__boffHandsFreeTransport";
|
|
|
3
3
|
function n(e) {
|
|
4
4
|
return e === !0;
|
|
5
5
|
}
|
|
6
|
-
function r(e, t) {
|
|
7
|
-
return t === "on" ? !0 : t === "off" ? !1 : n(e);
|
|
6
|
+
function r(e, t, r = !1) {
|
|
7
|
+
return r ? !1 : t === "on" ? !0 : t === "off" ? !1 : n(e);
|
|
8
8
|
}
|
|
9
9
|
function i(e) {
|
|
10
10
|
try {
|