@burdenoff/fe-libs 2026.904.6 → 2026.904.8
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/node_modules/react-markdown/lib/index.js +1 -1
- package/dist/shared/assistant/attachmentSources.d.ts +58 -0
- package/dist/shared/assistant/attachmentSources.d.ts.map +1 -0
- package/dist/shared/assistant/attachmentSources.js +41 -0
- package/dist/shared/assistant/clipboard.d.ts +12 -0
- package/dist/shared/assistant/clipboard.d.ts.map +1 -0
- package/dist/shared/assistant/clipboard.js +10 -0
- package/dist/shared/assistant/context.d.ts +22 -0
- package/dist/shared/assistant/context.d.ts.map +1 -0
- package/dist/shared/assistant/context.js +36 -0
- package/dist/shared/assistant/index.d.ts +26 -0
- package/dist/shared/assistant/index.d.ts.map +1 -1
- package/dist/shared/assistant/sandboxReadiness.d.ts +45 -0
- package/dist/shared/assistant/sandboxReadiness.d.ts.map +1 -0
- package/dist/shared/assistant/sandboxReadiness.js +22 -0
- package/dist/shared/assistant/ui/AssistantAutoSpeakToggle.d.ts +20 -0
- package/dist/shared/assistant/ui/AssistantAutoSpeakToggle.d.ts.map +1 -0
- package/dist/shared/assistant/ui/AssistantAutoSpeakToggle.js +25 -0
- package/dist/shared/assistant/ui/AssistantMarkdownImage.d.ts +38 -0
- package/dist/shared/assistant/ui/AssistantMarkdownImage.d.ts.map +1 -0
- package/dist/shared/assistant/ui/AssistantMarkdownImage.js +147 -0
- package/dist/shared/assistant/ui/AssistantMarkdownRenderer.d.ts +10 -0
- package/dist/shared/assistant/ui/AssistantMarkdownRenderer.d.ts.map +1 -0
- package/dist/shared/assistant/ui/AssistantMarkdownRenderer.js +198 -0
- package/dist/shared/assistant/ui/AssistantMessageAttachments.d.ts +10 -0
- package/dist/shared/assistant/ui/AssistantMessageAttachments.d.ts.map +1 -0
- package/dist/shared/assistant/ui/AssistantMessageAttachments.js +80 -0
- package/dist/shared/assistant/ui/AssistantPendingWriteCard.d.ts +32 -0
- package/dist/shared/assistant/ui/AssistantPendingWriteCard.d.ts.map +1 -0
- package/dist/shared/assistant/ui/AssistantPendingWriteCard.js +53 -0
- package/dist/shared/assistant/ui/AssistantReplyLanguageSelector.d.ts +22 -0
- package/dist/shared/assistant/ui/AssistantReplyLanguageSelector.d.ts.map +1 -0
- package/dist/shared/assistant/ui/AssistantReplyLanguageSelector.js +58 -0
- package/dist/shared/assistant/ui/AssistantSpeakButton.d.ts +33 -0
- package/dist/shared/assistant/ui/AssistantSpeakButton.d.ts.map +1 -0
- package/dist/shared/assistant/ui/AssistantSpeakButton.js +21 -0
- package/dist/shared/assistant/ui/AssistantSpokenTurnsNotice.d.ts +31 -0
- package/dist/shared/assistant/ui/AssistantSpokenTurnsNotice.d.ts.map +1 -0
- package/dist/shared/assistant/ui/AssistantSpokenTurnsNotice.js +31 -0
- package/dist/shared/assistant/ui/composer/AssistantAttachmentButton.d.ts +51 -0
- package/dist/shared/assistant/ui/composer/AssistantAttachmentButton.d.ts.map +1 -0
- package/dist/shared/assistant/ui/composer/AssistantAttachmentButton.js +86 -0
- package/dist/shared/assistant/ui/composer/AssistantAttachmentChips.d.ts +29 -0
- package/dist/shared/assistant/ui/composer/AssistantAttachmentChips.d.ts.map +1 -0
- package/dist/shared/assistant/ui/composer/AssistantAttachmentChips.js +70 -0
- package/dist/shared/assistant/ui/composer/AssistantLanguageSelector.d.ts +39 -0
- package/dist/shared/assistant/ui/composer/AssistantLanguageSelector.d.ts.map +1 -0
- package/dist/shared/assistant/ui/composer/AssistantLanguageSelector.js +42 -0
- package/dist/shared/assistant/ui/composer/AssistantModeSelector.d.ts +44 -0
- package/dist/shared/assistant/ui/composer/AssistantModeSelector.d.ts.map +1 -0
- package/dist/shared/assistant/ui/composer/AssistantModeSelector.js +81 -0
- package/dist/shared/assistant/ui/composer/AssistantVoiceButton.d.ts +20 -0
- package/dist/shared/assistant/ui/composer/AssistantVoiceButton.d.ts.map +1 -0
- package/dist/shared/assistant/ui/composer/AssistantVoiceButton.js +24 -0
- package/dist/shared/assistant/ui/composer/AssistantVoiceSelector.d.ts +25 -0
- package/dist/shared/assistant/ui/composer/AssistantVoiceSelector.d.ts.map +1 -0
- package/dist/shared/assistant/ui/composer/AssistantVoiceSelector.js +37 -0
- package/dist/shared/assistant/ui/voice/AssistantVoiceOrb.d.ts +33 -0
- package/dist/shared/assistant/ui/voice/AssistantVoiceOrb.d.ts.map +1 -0
- package/dist/shared/assistant/ui/voice/AssistantVoiceOrb.js +24 -0
- package/dist/shared/assistant/ui/voice/AssistantVoiceSessionButton.d.ts +23 -0
- package/dist/shared/assistant/ui/voice/AssistantVoiceSessionButton.d.ts.map +1 -0
- package/dist/shared/assistant/ui/voice/AssistantVoiceSessionButton.js +19 -0
- package/dist/shared/assistant/ui/voice/VoiceCaption.d.ts +59 -0
- package/dist/shared/assistant/ui/voice/VoiceCaption.d.ts.map +1 -0
- package/dist/shared/assistant/ui/voice/VoiceCaption.js +25 -0
- package/dist/shared/assistant/ui/voice/VoiceConversationView.d.ts +38 -0
- package/dist/shared/assistant/ui/voice/VoiceConversationView.d.ts.map +1 -0
- package/dist/shared/assistant/ui/voice/VoiceConversationView.js +45 -0
- package/dist/shared/assistant/ui/voice/VoiceMiniController.d.ts +32 -0
- package/dist/shared/assistant/ui/voice/VoiceMiniController.d.ts.map +1 -0
- package/dist/shared/assistant/ui/voice/VoiceMiniController.js +47 -0
- package/dist/shared/assistant/ui/voice/VoiceStage.d.ts +42 -0
- package/dist/shared/assistant/ui/voice/VoiceStage.d.ts.map +1 -0
- package/dist/shared/assistant/ui/voice/VoiceStage.js +58 -0
- package/dist/shared/assistant/ui/voice/VoiceTranscriptDrawer.d.ts +39 -0
- package/dist/shared/assistant/ui/voice/VoiceTranscriptDrawer.d.ts.map +1 -0
- package/dist/shared/assistant/ui/voice/VoiceTranscriptDrawer.js +61 -0
- package/dist/shared/assistant/ui/voice/VoiceWaveform.d.ts +33 -0
- package/dist/shared/assistant/ui/voice/VoiceWaveform.d.ts.map +1 -0
- package/dist/shared/assistant/ui/voice/VoiceWaveform.js +45 -0
- package/dist/shared-assistant.js +27 -1
- package/package.json +1 -1
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* One live caption — either what the user is saying or what the assistant is.
|
|
4
|
+
*
|
|
5
|
+
* Replaces the message-bubble list the voice overlay used to render. That list
|
|
6
|
+
* was the chat transcript squeezed into a modal: bubbles, the whole scrollback,
|
|
7
|
+
* and raw `##`/`**` because it printed the model's markdown as plain text.
|
|
8
|
+
*
|
|
9
|
+
* Three things here are deliberate and were all wrong before:
|
|
10
|
+
*
|
|
11
|
+
* ★ **Left-aligned, not centred.** Centring is fine for one short line and
|
|
12
|
+
* unreadable for four — every line starts in a different place, so the eye has
|
|
13
|
+
* to hunt for each beginning. Tamil/English mixed text makes it worse, because
|
|
14
|
+
* the line lengths vary wildly. The BLOCK is centred on the stage; the text
|
|
15
|
+
* inside it is not.
|
|
16
|
+
*
|
|
17
|
+
* ★ **Responsive type, not one fixed size.** `clamp()` so the same component is
|
|
18
|
+
* legible in a 380px docked panel and from arm's length on a maximised desktop
|
|
19
|
+
* window, without a second component or a transform.
|
|
20
|
+
*
|
|
21
|
+
* ★ **Bounded width.** A caption spanning a 1440px window is one long line the
|
|
22
|
+
* eye cannot track back from, so the measure is capped — 45rem / 720px on the
|
|
23
|
+
* full-screen stage, the middle of the 680-760px the design calls for.
|
|
24
|
+
*
|
|
25
|
+
* ★ That measure is deliberately NOT the 60-75 characters typography usually
|
|
26
|
+
* aims at: at 36px type 720px carries roughly 40. A voice caption is glanced at
|
|
27
|
+
* from arm's length while someone is talking, not read as prose, and the size
|
|
28
|
+
* is what makes it glanceable — so the two constraints are set independently
|
|
29
|
+
* and the width follows the spec rather than the usual reading rule.
|
|
30
|
+
*/
|
|
31
|
+
interface Props {
|
|
32
|
+
text: string;
|
|
33
|
+
/** Who is speaking. The assistant's caption is the loud one. */
|
|
34
|
+
role: "user" | "assistant";
|
|
35
|
+
/** Full-screen rather than docked in the panel. */
|
|
36
|
+
expanded: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* The reply broken into the chunks being SPOKEN, plus the one sounding now.
|
|
39
|
+
*
|
|
40
|
+
* ★ When present the caption reveals only chunks 0..index, so the text tracks
|
|
41
|
+
* the voice instead of arriving whole the instant playback starts. That is
|
|
42
|
+
* what "captions appear multiple sentences ahead of the audio" describes: the
|
|
43
|
+
* user reads the whole answer, then sits through it being read to them.
|
|
44
|
+
*
|
|
45
|
+
* ★ The chunks are the SPOKEN strings, not a parallel rendering of the same
|
|
46
|
+
* markdown. A live caption whose words differ from the audio is not a caption.
|
|
47
|
+
*
|
|
48
|
+
* Absent — no engine support, or nothing playing — falls back to `text` whole,
|
|
49
|
+
* which is exactly today's behaviour.
|
|
50
|
+
*/
|
|
51
|
+
spokenChunks?: {
|
|
52
|
+
chunks: string[];
|
|
53
|
+
index: number;
|
|
54
|
+
} | null;
|
|
55
|
+
testId?: string;
|
|
56
|
+
}
|
|
57
|
+
export declare const VoiceCaption: FC<Props>;
|
|
58
|
+
export {};
|
|
59
|
+
//# sourceMappingURL=VoiceCaption.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VoiceCaption.d.ts","sourceRoot":"","sources":["../../../../../src/shared/assistant/ui/voice/VoiceCaption.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAEhC;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,UAAU,KAAK;IACb,IAAI,EAAE,MAAM,CAAC;IACb,gEAAgE;IAChE,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,mDAAmD;IACnD,QAAQ,EAAE,OAAO,CAAC;IAClB;;;;;;;;;;;;;OAaG;IACH,YAAY,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC1D,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,YAAY,EAAE,EAAE,CAAC,KAAK,CA0ElC,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { jsx as e, jsxs as t } from "react/jsx-runtime";
|
|
2
|
+
//#region src/shared/assistant/ui/voice/VoiceCaption.tsx
|
|
3
|
+
var n = ({ text: n, role: r, expanded: i, spokenChunks: a = null, testId: o }) => {
|
|
4
|
+
let s = r === "assistant", c = s && a && a.index >= 0 ? a : null;
|
|
5
|
+
return /* @__PURE__ */ e("div", {
|
|
6
|
+
className: "flex w-full justify-center",
|
|
7
|
+
children: /* @__PURE__ */ e("p", {
|
|
8
|
+
className: [
|
|
9
|
+
"w-full whitespace-pre-wrap break-words text-left",
|
|
10
|
+
i ? "max-w-[45rem]" : "max-w-md",
|
|
11
|
+
s ? "font-semibold text-text-primary" : "font-medium text-text-secondary",
|
|
12
|
+
i ? s ? "text-[clamp(1.625rem,2.5vw,2.25rem)] leading-[1.5]" : "text-[clamp(1.125rem,1.8vw,1.375rem)] leading-[1.5]" : s ? "text-lg leading-relaxed" : "text-base leading-relaxed"
|
|
13
|
+
].join(" "),
|
|
14
|
+
role: "status",
|
|
15
|
+
"aria-live": "polite",
|
|
16
|
+
"data-testid": o,
|
|
17
|
+
children: c ? c.chunks.slice(0, c.index + 1).map((e, n) => /* @__PURE__ */ t("span", {
|
|
18
|
+
className: n === c.index ? "text-text-primary" : "text-text-muted transition-colors duration-300",
|
|
19
|
+
children: [n > 0 ? " " : "", e]
|
|
20
|
+
}, n)) : n
|
|
21
|
+
})
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
//#endregion
|
|
25
|
+
export { n as VoiceCaption };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
import { VoiceTranscriptTurn } from '../../voice/turnVisibility';
|
|
3
|
+
/**
|
|
4
|
+
* The voice conversation, as a normal chat.
|
|
5
|
+
*
|
|
6
|
+
* ★ This exists because separating voice from chat took something away. The
|
|
7
|
+
* chat panel now filters voice turns OUT, so a conversation held entirely by
|
|
8
|
+
* voice renders the "How can I help?" empty state behind the session — the
|
|
9
|
+
* exchange the user just had appears nowhere in a readable form. Splitting the
|
|
10
|
+
* surfaces was right; leaving no way to READ the voice conversation was not.
|
|
11
|
+
*
|
|
12
|
+
* So voice has two perspectives rather than one:
|
|
13
|
+
* - LIVE — the stage: one state, big captions, what is happening now
|
|
14
|
+
* - CHAT — this: the whole exchange, scrollable, rendered properly
|
|
15
|
+
*
|
|
16
|
+
* ★ It uses `AssistantMarkdownRenderer`, the SAME renderer the typed chat uses.
|
|
17
|
+
* That matters: the old voice overlay printed the model's text raw, which is
|
|
18
|
+
* why `##` and `**` appeared as literal characters. Voice replies should be
|
|
19
|
+
* plain prose now (the prompt asks for it), but if any markdown survives it
|
|
20
|
+
* renders as formatting rather than as syntax.
|
|
21
|
+
*
|
|
22
|
+
* Still NOT the chat thread: these turns stay marked `voice`, so they never
|
|
23
|
+
* appear in the typed conversation. This is a second view of the same voice
|
|
24
|
+
* session, not a merge.
|
|
25
|
+
*/
|
|
26
|
+
interface Props {
|
|
27
|
+
/**
|
|
28
|
+
* Every spoken turn in the conversation, oldest first.
|
|
29
|
+
*
|
|
30
|
+
* `sessionId` is absent on turns recorded before session ids existed. They are
|
|
31
|
+
* shown, not dropped — the user really said them — and they collapse into one
|
|
32
|
+
* leading group rather than being scattered one divider apart.
|
|
33
|
+
*/
|
|
34
|
+
turns: ReadonlyArray<VoiceTranscriptTurn>;
|
|
35
|
+
}
|
|
36
|
+
export declare const VoiceConversationView: FC<Props>;
|
|
37
|
+
export {};
|
|
38
|
+
//# sourceMappingURL=VoiceConversationView.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VoiceConversationView.d.ts","sourceRoot":"","sources":["../../../../../src/shared/assistant/ui/voice/VoiceConversationView.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,EAAE,EAAE,MAAM,OAAO,CAAC;AAEzC,OAAO,EAEL,KAAK,mBAAmB,EACzB,MAAM,4BAA4B,CAAC;AAGpC;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,UAAU,KAAK;IACb;;;;;;OAMG;IACH,KAAK,EAAE,aAAa,CAAC,mBAAmB,CAAC,CAAC;CAC3C;AAED,eAAO,MAAM,qBAAqB,EAAE,EAAE,CAAC,KAAK,CAwE3C,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { groupConsecutiveBySession as e } from "../../voice/turnVisibility.js";
|
|
2
|
+
import { useAssistantTr as t } from "../../i18n.js";
|
|
3
|
+
import { AssistantMarkdownRenderer as n } from "../AssistantMarkdownRenderer.js";
|
|
4
|
+
import { useMemo as r } from "react";
|
|
5
|
+
import { jsx as i, jsxs as a } from "react/jsx-runtime";
|
|
6
|
+
//#region src/shared/assistant/ui/voice/VoiceConversationView.tsx
|
|
7
|
+
var o = ({ turns: o }) => {
|
|
8
|
+
let s = t(), c = r(() => e(o, (e) => e.sessionId), [o]);
|
|
9
|
+
return o.length === 0 ? /* @__PURE__ */ i("div", {
|
|
10
|
+
className: "flex flex-1 items-center justify-center px-6",
|
|
11
|
+
children: /* @__PURE__ */ i("p", {
|
|
12
|
+
className: "text-center text-sm text-text-muted",
|
|
13
|
+
children: s("voiceSession.transcriptEmpty", "Nothing spoken yet in this session.")
|
|
14
|
+
})
|
|
15
|
+
}) : /* @__PURE__ */ i("div", {
|
|
16
|
+
className: "flex-1 overflow-y-auto px-4 py-4",
|
|
17
|
+
"data-testid": "assistant-voice-conversation",
|
|
18
|
+
children: c.map((e, t) => /* @__PURE__ */ a("section", {
|
|
19
|
+
className: "space-y-4 pb-4",
|
|
20
|
+
children: [t > 0 ? /* @__PURE__ */ a("div", {
|
|
21
|
+
className: "flex items-center gap-2 pt-2",
|
|
22
|
+
role: "separator",
|
|
23
|
+
children: [
|
|
24
|
+
/* @__PURE__ */ i("span", { className: "h-px flex-1 bg-border-subtle" }),
|
|
25
|
+
/* @__PURE__ */ i("span", {
|
|
26
|
+
className: "text-[11px] uppercase tracking-wide text-text-muted",
|
|
27
|
+
children: s("voiceSession.newSession", "New voice session")
|
|
28
|
+
}),
|
|
29
|
+
/* @__PURE__ */ i("span", { className: "h-px flex-1 bg-border-subtle" })
|
|
30
|
+
]
|
|
31
|
+
}) : null, e.turns.map((e) => e.role === "user" ? /* @__PURE__ */ i("div", {
|
|
32
|
+
className: "flex justify-end",
|
|
33
|
+
children: /* @__PURE__ */ i("p", {
|
|
34
|
+
className: "max-w-[85%] whitespace-pre-wrap break-words rounded-2xl bg-bg-elevated px-3 py-2 text-sm leading-relaxed text-text-primary",
|
|
35
|
+
children: e.text
|
|
36
|
+
})
|
|
37
|
+
}, e.id) : /* @__PURE__ */ i("div", {
|
|
38
|
+
className: "text-sm leading-relaxed text-text-secondary",
|
|
39
|
+
children: /* @__PURE__ */ i(n, { content: e.text })
|
|
40
|
+
}, e.id))]
|
|
41
|
+
}, `${e.sessionId ?? "earlier"}-${t}`))
|
|
42
|
+
});
|
|
43
|
+
};
|
|
44
|
+
//#endregion
|
|
45
|
+
export { o as VoiceConversationView };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { FC, ReactNode } from 'react';
|
|
2
|
+
import { VoiceStageState } from '../../voice/voiceStageState';
|
|
3
|
+
/**
|
|
4
|
+
* Docked voice: a compact live controller, not the full stage shrunk.
|
|
5
|
+
*
|
|
6
|
+
* Measured in prod, the docked panel was 554px tall — the expanded composition
|
|
7
|
+
* scaled down, with the same generous vertical rhythm in a space that cannot
|
|
8
|
+
* carry it. Docked is a glance-and-listen surface: state, the last thing said,
|
|
9
|
+
* and the controls. Everything else belongs to the expanded stage or the
|
|
10
|
+
* transcript.
|
|
11
|
+
*
|
|
12
|
+
* ★ Two to three lines of caption, hard-clamped. The point is not to save
|
|
13
|
+
* pixels — it is that a docked panel scrolling a long reply is the chat window
|
|
14
|
+
* this feature exists to stop being. If the user wants the whole answer, they
|
|
15
|
+
* expand or open the transcript.
|
|
16
|
+
*
|
|
17
|
+
* The row is deliberately horizontal: status and caption on the left, controls
|
|
18
|
+
* on the right, so the panel reads as one strip rather than a stack. That is
|
|
19
|
+
* what makes it feel like a controller instead of a small conversation.
|
|
20
|
+
*/
|
|
21
|
+
interface Props {
|
|
22
|
+
state: VoiceStageState;
|
|
23
|
+
/** Live user transcript, or the assistant's caption while speaking. */
|
|
24
|
+
caption: string | null;
|
|
25
|
+
statusText: string;
|
|
26
|
+
/** Mic / interrupt control — the same orb, in its compact size. */
|
|
27
|
+
control: ReactNode;
|
|
28
|
+
errorText?: string | null;
|
|
29
|
+
}
|
|
30
|
+
export declare const VoiceMiniController: FC<Props>;
|
|
31
|
+
export {};
|
|
32
|
+
//# sourceMappingURL=VoiceMiniController.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VoiceMiniController.d.ts","sourceRoot":"","sources":["../../../../../src/shared/assistant/ui/voice/VoiceMiniController.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAE3C,OAAO,EAIL,KAAK,eAAe,EACrB,MAAM,6BAA6B,CAAC;AAErC;;;;;;;;;;;;;;;;;GAiBG;AAEH,UAAU,KAAK;IACb,KAAK,EAAE,eAAe,CAAC;IACvB,uEAAuE;IACvE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,mEAAmE;IACnE,OAAO,EAAE,SAAS,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,eAAO,MAAM,mBAAmB,EAAE,EAAE,CAAC,KAAK,CA2EzC,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { showsAssistantCaption as e, waveformIsActive as t, waveformIsSettled as n } from "../../voice/voiceStageState.js";
|
|
2
|
+
import { VoiceWaveform as r } from "./VoiceWaveform.js";
|
|
3
|
+
import { jsx as i, jsxs as a } from "react/jsx-runtime";
|
|
4
|
+
//#region src/shared/assistant/ui/voice/VoiceMiniController.tsx
|
|
5
|
+
var o = ({ state: o, caption: s, statusText: c, control: l, errorText: u = null }) => {
|
|
6
|
+
let d = e(o);
|
|
7
|
+
return /* @__PURE__ */ a("div", {
|
|
8
|
+
className: "flex min-h-0 w-full flex-1 items-center gap-3 px-4",
|
|
9
|
+
"data-testid": "assistant-voice-mini",
|
|
10
|
+
"data-state": o,
|
|
11
|
+
children: [/* @__PURE__ */ a("div", {
|
|
12
|
+
className: "flex min-w-0 flex-1 flex-col gap-1.5",
|
|
13
|
+
children: [/* @__PURE__ */ a("div", {
|
|
14
|
+
className: "flex items-center gap-2",
|
|
15
|
+
children: [/* @__PURE__ */ i(r, {
|
|
16
|
+
active: t(o),
|
|
17
|
+
settled: n(o),
|
|
18
|
+
tone: o === "speaking" ? "speaking" : "listening"
|
|
19
|
+
}), /* @__PURE__ */ i("p", {
|
|
20
|
+
className: "truncate text-xs text-text-muted",
|
|
21
|
+
"aria-live": "polite",
|
|
22
|
+
"data-testid": "assistant-voice-status",
|
|
23
|
+
children: c
|
|
24
|
+
})]
|
|
25
|
+
}), o === "mic-error" ? /* @__PURE__ */ i("p", {
|
|
26
|
+
className: "line-clamp-2 text-xs text-status-warning",
|
|
27
|
+
role: "alert",
|
|
28
|
+
"data-testid": "assistant-voice-mini-error",
|
|
29
|
+
children: u
|
|
30
|
+
}) : s ? /* @__PURE__ */ i("p", {
|
|
31
|
+
className: ["line-clamp-3 break-words text-left text-sm leading-snug", d ? "font-semibold text-text-primary" : "font-medium text-text-secondary"].join(" "),
|
|
32
|
+
role: "status",
|
|
33
|
+
"aria-live": "polite",
|
|
34
|
+
"data-testid": "assistant-voice-caption",
|
|
35
|
+
children: s
|
|
36
|
+
}) : /* @__PURE__ */ i("div", {
|
|
37
|
+
className: "h-9",
|
|
38
|
+
"aria-hidden": "true"
|
|
39
|
+
})]
|
|
40
|
+
}), /* @__PURE__ */ i("div", {
|
|
41
|
+
className: "shrink-0",
|
|
42
|
+
children: l
|
|
43
|
+
})]
|
|
44
|
+
});
|
|
45
|
+
};
|
|
46
|
+
//#endregion
|
|
47
|
+
export { o as VoiceMiniController };
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { FC, ReactNode } from 'react';
|
|
2
|
+
import { VoiceStageState } from '../../voice/voiceStageState';
|
|
3
|
+
/**
|
|
4
|
+
* The middle of the voice panel: exactly ONE state, rendered as itself.
|
|
5
|
+
*
|
|
6
|
+
* What this replaces is the whole problem the operator screenshotted. The old
|
|
7
|
+
* overlay showed, simultaneously: "Listening…", a microphone warning, the last
|
|
8
|
+
* six messages of the chat conversation as bubbles (markdown syntax and all),
|
|
9
|
+
* the assistant's answer AGAIN as a caption, and the orb. Five things competing,
|
|
10
|
+
* none of them readable.
|
|
11
|
+
*
|
|
12
|
+
* ★ A stage shows one thing because the session IS one thing at a time. The
|
|
13
|
+
* state is derived in `voiceStageState`, which is pure and tested; this file is
|
|
14
|
+
* presentational and cannot be tested in this repo (vitest runs in `node`, no
|
|
15
|
+
* DOM), so it deliberately contains no logic worth testing.
|
|
16
|
+
*
|
|
17
|
+
* The microphone warning is NOT rendered here. Mixing a system message into the
|
|
18
|
+
* conversation area is what made it read as part of the reply; it belongs to
|
|
19
|
+
* the chrome around the stage.
|
|
20
|
+
*/
|
|
21
|
+
interface Props {
|
|
22
|
+
state: VoiceStageState;
|
|
23
|
+
/** What the user is saying (live) or last said. */
|
|
24
|
+
userCaption: string | null;
|
|
25
|
+
/** What the assistant is saying. */
|
|
26
|
+
assistantCaption: string | null;
|
|
27
|
+
expanded: boolean;
|
|
28
|
+
/** Status words — already localised by the caller. */
|
|
29
|
+
statusText: string;
|
|
30
|
+
/** The microphone / interrupt control. */
|
|
31
|
+
control: ReactNode;
|
|
32
|
+
/** Shown in the mic-error state instead of a caption. */
|
|
33
|
+
errorText?: string | null;
|
|
34
|
+
/** Reveals the assistant caption in step with the audio — see VoiceCaption. */
|
|
35
|
+
spokenChunks?: {
|
|
36
|
+
chunks: string[];
|
|
37
|
+
index: number;
|
|
38
|
+
} | null;
|
|
39
|
+
}
|
|
40
|
+
export declare const VoiceStage: FC<Props>;
|
|
41
|
+
export {};
|
|
42
|
+
//# sourceMappingURL=VoiceStage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VoiceStage.d.ts","sourceRoot":"","sources":["../../../../../src/shared/assistant/ui/voice/VoiceStage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAG3C,OAAO,EAKL,KAAK,eAAe,EACrB,MAAM,6BAA6B,CAAC;AAErC;;;;;;;;;;;;;;;;;GAiBG;AAEH,UAAU,KAAK;IACb,KAAK,EAAE,eAAe,CAAC;IACvB,mDAAmD;IACnD,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,oCAAoC;IACpC,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,QAAQ,EAAE,OAAO,CAAC;IAClB,sDAAsD;IACtD,UAAU,EAAE,MAAM,CAAC;IACnB,0CAA0C;IAC1C,OAAO,EAAE,SAAS,CAAC;IACnB,yDAAyD;IACzD,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,+EAA+E;IAC/E,YAAY,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CAC3D;AAED,eAAO,MAAM,UAAU,EAAE,EAAE,CAAC,KAAK,CA4HhC,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { showsAssistantCaption as e, showsUserCaption as t, waveformIsActive as n, waveformIsSettled as r } from "../../voice/voiceStageState.js";
|
|
2
|
+
import { VoiceCaption as i } from "./VoiceCaption.js";
|
|
3
|
+
import { VoiceWaveform as a } from "./VoiceWaveform.js";
|
|
4
|
+
import { Fragment as o, jsx as s, jsxs as c } from "react/jsx-runtime";
|
|
5
|
+
//#region src/shared/assistant/ui/voice/VoiceStage.tsx
|
|
6
|
+
var l = ({ state: l, userCaption: u, assistantCaption: d, expanded: f, statusText: p, control: m, errorText: h = null, spokenChunks: g = null }) => {
|
|
7
|
+
let _ = e(l) ? d : t(l) ? u : null;
|
|
8
|
+
return /* @__PURE__ */ c("div", {
|
|
9
|
+
className: [
|
|
10
|
+
"flex min-h-0 w-full flex-1 flex-col items-center",
|
|
11
|
+
f ? "px-8" : "px-14",
|
|
12
|
+
f ? "justify-start pt-[16vh]" : "justify-center"
|
|
13
|
+
].join(" "),
|
|
14
|
+
"data-testid": "assistant-voice-stage",
|
|
15
|
+
"data-state": l,
|
|
16
|
+
children: [
|
|
17
|
+
/* @__PURE__ */ s("p", {
|
|
18
|
+
className: [
|
|
19
|
+
"text-center text-text-muted",
|
|
20
|
+
f ? "text-base" : "text-sm",
|
|
21
|
+
f ? "mb-3" : "mb-2"
|
|
22
|
+
].join(" "),
|
|
23
|
+
"aria-live": "polite",
|
|
24
|
+
"data-testid": "assistant-voice-status",
|
|
25
|
+
children: p
|
|
26
|
+
}),
|
|
27
|
+
l === "mic-error" ? /* @__PURE__ */ s("p", {
|
|
28
|
+
className: `max-w-md text-center text-status-warning ${f ? "text-lg" : "text-sm"}`,
|
|
29
|
+
role: "alert",
|
|
30
|
+
"data-testid": "assistant-voice-stage-error",
|
|
31
|
+
children: h
|
|
32
|
+
}) : /* @__PURE__ */ c(o, { children: [/* @__PURE__ */ s("div", {
|
|
33
|
+
className: f ? "mb-10" : "mb-5",
|
|
34
|
+
children: /* @__PURE__ */ s(a, {
|
|
35
|
+
active: n(l),
|
|
36
|
+
settled: r(l),
|
|
37
|
+
tone: l === "speaking" ? "speaking" : "listening",
|
|
38
|
+
expanded: f
|
|
39
|
+
})
|
|
40
|
+
}), _ ? /* @__PURE__ */ s("div", {
|
|
41
|
+
className: f ? "mb-12 max-h-[46vh] w-full overflow-y-auto" : "mb-6 max-h-[38vh] w-full overflow-y-auto",
|
|
42
|
+
children: /* @__PURE__ */ s(i, {
|
|
43
|
+
text: _,
|
|
44
|
+
role: e(l) ? "assistant" : "user",
|
|
45
|
+
spokenChunks: g,
|
|
46
|
+
expanded: f,
|
|
47
|
+
testId: "assistant-voice-caption"
|
|
48
|
+
})
|
|
49
|
+
}) : /* @__PURE__ */ s("div", {
|
|
50
|
+
className: f ? "mb-12 h-[4.875rem]" : "mb-6 h-12",
|
|
51
|
+
"aria-hidden": "true"
|
|
52
|
+
})] }),
|
|
53
|
+
m
|
|
54
|
+
]
|
|
55
|
+
});
|
|
56
|
+
};
|
|
57
|
+
//#endregion
|
|
58
|
+
export { l as VoiceStage };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
import { VoiceTranscriptTurn } from '../../voice/turnVisibility';
|
|
3
|
+
/**
|
|
4
|
+
* This session's spoken turns, on demand.
|
|
5
|
+
*
|
|
6
|
+
* The stage shows only what is happening NOW, which is right for a live
|
|
7
|
+
* conversation and would otherwise mean the history is simply gone. This is
|
|
8
|
+
* where it goes: secondary, behind a button, and explicitly a VOICE transcript
|
|
9
|
+
* rather than the chat thread.
|
|
10
|
+
*
|
|
11
|
+
* ★ `z-30` is not decoration: the session container is `z-20` docked and
|
|
12
|
+
* `z-[60]` expanded, and a child at `z-10` painted BEHIND its own parent — the
|
|
13
|
+
* drawer opened and was invisible. Stacking contexts are per-parent, so this
|
|
14
|
+
* only has to beat its siblings, not the overlay itself.
|
|
15
|
+
*
|
|
16
|
+
* ★ Renders only the turns it is handed, which are already filtered to the
|
|
17
|
+
* SPOKEN channel — so it can never resurrect the typed conversation the old
|
|
18
|
+
* overlay used to paint. Note "spoken", not "this session": the marker is a
|
|
19
|
+
* boolean, so this is the conversation's whole spoken history. The heading below
|
|
20
|
+
* says so.
|
|
21
|
+
*/
|
|
22
|
+
interface Props {
|
|
23
|
+
turns: ReadonlyArray<VoiceTranscriptTurn>;
|
|
24
|
+
onClose: () => void;
|
|
25
|
+
/** Download the spoken conversation. Hidden when there is nothing to save. */
|
|
26
|
+
onSave?: () => void;
|
|
27
|
+
/**
|
|
28
|
+
* Leave a note of this exchange in the typed thread and carry on there.
|
|
29
|
+
*
|
|
30
|
+
* ★ Supplied only DURING a live session, where "continue in chat" is a move
|
|
31
|
+
* the user is making. Opened from the chat panel afterwards they are already
|
|
32
|
+
* in chat, and a button offering to take them there would be a no-op with a
|
|
33
|
+
* confident label.
|
|
34
|
+
*/
|
|
35
|
+
onContinueInChat?: () => void;
|
|
36
|
+
}
|
|
37
|
+
export declare const VoiceTranscriptDrawer: FC<Props>;
|
|
38
|
+
export {};
|
|
39
|
+
//# sourceMappingURL=VoiceTranscriptDrawer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VoiceTranscriptDrawer.d.ts","sourceRoot":"","sources":["../../../../../src/shared/assistant/ui/voice/VoiceTranscriptDrawer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAIhC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEtE;;;;;;;;;;;;;;;;;;GAkBG;AAEH,UAAU,KAAK;IACb,KAAK,EAAE,aAAa,CAAC,mBAAmB,CAAC,CAAC;IAC1C,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,8EAA8E;IAC9E,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB;;;;;;;OAOG;IACH,gBAAgB,CAAC,EAAE,MAAM,IAAI,CAAC;CAC/B;AAED,eAAO,MAAM,qBAAqB,EAAE,EAAE,CAAC,KAAK,CAsF3C,CAAC"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { useAssistantTr as e } from "../../i18n.js";
|
|
2
|
+
import { VoiceConversationView as t } from "./VoiceConversationView.js";
|
|
3
|
+
import { ArrowRight as n, Download as r, X as i } from "lucide-react";
|
|
4
|
+
import { jsx as a, jsxs as o } from "react/jsx-runtime";
|
|
5
|
+
//#region src/shared/assistant/ui/voice/VoiceTranscriptDrawer.tsx
|
|
6
|
+
var s = ({ turns: s, onClose: c, onSave: l, onContinueInChat: u }) => {
|
|
7
|
+
let d = e();
|
|
8
|
+
return /* @__PURE__ */ o("div", {
|
|
9
|
+
className: "absolute inset-0 z-30 flex flex-col bg-bg-sunken/95 backdrop-blur-sm",
|
|
10
|
+
role: "dialog",
|
|
11
|
+
"aria-label": d("voiceSession.transcriptTitle", "Voice transcript"),
|
|
12
|
+
"data-testid": "assistant-voice-transcript",
|
|
13
|
+
children: [
|
|
14
|
+
/* @__PURE__ */ o("div", {
|
|
15
|
+
className: "flex items-center justify-between border-b border-border-subtle px-4 py-3",
|
|
16
|
+
children: [/* @__PURE__ */ o("div", {
|
|
17
|
+
className: "min-w-0",
|
|
18
|
+
children: [/* @__PURE__ */ a("h2", {
|
|
19
|
+
className: "text-sm font-semibold text-text-primary",
|
|
20
|
+
children: d("voiceSession.transcript", "Voice conversation")
|
|
21
|
+
}), /* @__PURE__ */ a("p", {
|
|
22
|
+
className: "truncate text-xs text-text-muted",
|
|
23
|
+
children: d("voiceSession.transcriptHint", "Spoken turns in this conversation — kept out of your typed chat.")
|
|
24
|
+
})]
|
|
25
|
+
}), /* @__PURE__ */ a("button", {
|
|
26
|
+
type: "button",
|
|
27
|
+
onClick: c,
|
|
28
|
+
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",
|
|
29
|
+
"aria-label": d("voiceSession.transcriptClose", "Close the transcript"),
|
|
30
|
+
"data-testid": "assistant-voice-transcript-close",
|
|
31
|
+
children: /* @__PURE__ */ a(i, { className: "size-4" })
|
|
32
|
+
})]
|
|
33
|
+
}),
|
|
34
|
+
/* @__PURE__ */ a(t, { turns: s }),
|
|
35
|
+
(l || u) && s.length > 0 ? /* @__PURE__ */ o("div", {
|
|
36
|
+
className: "flex items-center justify-end gap-2 border-t border-border-subtle px-4 py-3",
|
|
37
|
+
children: [l ? /* @__PURE__ */ o("button", {
|
|
38
|
+
type: "button",
|
|
39
|
+
onClick: l,
|
|
40
|
+
className: "flex items-center gap-1.5 rounded-lg border border-border-default px-3 py-1.5 text-xs text-text-secondary transition-colors hover:bg-bg-elevated hover:text-text-primary focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong",
|
|
41
|
+
"data-testid": "assistant-voice-save-transcript",
|
|
42
|
+
children: [/* @__PURE__ */ a(r, {
|
|
43
|
+
className: "size-3.5",
|
|
44
|
+
"aria-hidden": "true"
|
|
45
|
+
}), d("voiceSession.save", "Save transcript")]
|
|
46
|
+
}) : null, u ? /* @__PURE__ */ o("button", {
|
|
47
|
+
type: "button",
|
|
48
|
+
onClick: u,
|
|
49
|
+
className: "flex items-center gap-1.5 rounded-lg bg-action-primary-bg px-3 py-1.5 text-xs font-medium text-action-primary-fg transition-opacity hover:opacity-90 focus:outline-none focus-visible:ring-2 focus-visible:ring-border-strong",
|
|
50
|
+
"data-testid": "assistant-voice-continue-in-chat",
|
|
51
|
+
children: [d("voiceSession.continueInChat", "Continue in chat"), /* @__PURE__ */ a(n, {
|
|
52
|
+
className: "size-3.5",
|
|
53
|
+
"aria-hidden": "true"
|
|
54
|
+
})]
|
|
55
|
+
}) : null]
|
|
56
|
+
}) : null
|
|
57
|
+
]
|
|
58
|
+
});
|
|
59
|
+
};
|
|
60
|
+
//#endregion
|
|
61
|
+
export { s as VoiceTranscriptDrawer };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* A small animated bar meter.
|
|
4
|
+
*
|
|
5
|
+
* ★ Deliberately NOT a real audio visualiser. Reading actual microphone
|
|
6
|
+
* amplitude needs `getUserMedia` + an `AnalyserNode`, and this app has neither —
|
|
7
|
+
* the Web Speech API opens its own capture that we never see. Adding a second,
|
|
8
|
+
* parallel microphone stream purely to animate bars would double the permission
|
|
9
|
+
* surface and the battery cost for decoration.
|
|
10
|
+
*
|
|
11
|
+
* What it honestly conveys is LIVENESS: the session is running and in this
|
|
12
|
+
* state. It is `aria-hidden` because it says nothing a screen-reader user can
|
|
13
|
+
* use — the status text and the caption carry the real meaning.
|
|
14
|
+
*
|
|
15
|
+
* When a real VAD stream lands (it is needed for automatic barge-in anyway),
|
|
16
|
+
* this component gets amplitude as a prop and the animation becomes truthful.
|
|
17
|
+
*/
|
|
18
|
+
interface Props {
|
|
19
|
+
/** Bars animate while true; a flat line while false. */
|
|
20
|
+
active: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* Open, but waiting rather than hearing speech — the correction window.
|
|
23
|
+
* Shorter and slower than full listening, so the pause is visible without
|
|
24
|
+
* implying the microphone closed.
|
|
25
|
+
*/
|
|
26
|
+
settled?: boolean;
|
|
27
|
+
/** `speaking` reads as the assistant's voice, `listening` as the user's. */
|
|
28
|
+
tone: "listening" | "speaking";
|
|
29
|
+
expanded?: boolean;
|
|
30
|
+
}
|
|
31
|
+
export declare const VoiceWaveform: FC<Props>;
|
|
32
|
+
export {};
|
|
33
|
+
//# sourceMappingURL=VoiceWaveform.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VoiceWaveform.d.ts","sourceRoot":"","sources":["../../../../../src/shared/assistant/ui/voice/VoiceWaveform.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAEhC;;;;;;;;;;;;;;;GAeG;AAEH,UAAU,KAAK;IACb,wDAAwD;IACxD,MAAM,EAAE,OAAO,CAAC;IAChB;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,4EAA4E;IAC5E,IAAI,EAAE,WAAW,GAAG,UAAU,CAAC;IAC/B,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAID,eAAO,MAAM,aAAa,EAAE,EAAE,CAAC,KAAK,CAmCnC,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { jsx as e } from "react/jsx-runtime";
|
|
2
|
+
//#region src/shared/assistant/ui/voice/VoiceWaveform.tsx
|
|
3
|
+
var t = [
|
|
4
|
+
0,
|
|
5
|
+
1,
|
|
6
|
+
2,
|
|
7
|
+
3,
|
|
8
|
+
4,
|
|
9
|
+
5,
|
|
10
|
+
6
|
|
11
|
+
], n = ({ active: n, tone: r, settled: i = !1, expanded: a = !1 }) => /* @__PURE__ */ e("div", {
|
|
12
|
+
className: `flex items-end justify-center ${a ? "h-8 gap-1.5" : "h-5 gap-1"}`,
|
|
13
|
+
"aria-hidden": "true",
|
|
14
|
+
"data-testid": "assistant-voice-waveform",
|
|
15
|
+
children: t.map((t) => /* @__PURE__ */ e("span", {
|
|
16
|
+
className: [
|
|
17
|
+
"inline-block rounded-full transition-[height,opacity] duration-300",
|
|
18
|
+
a ? "w-1.5" : "w-1",
|
|
19
|
+
r === "speaking" ? "bg-brand-primary" : "bg-text-muted",
|
|
20
|
+
n ? i ? "animate-pulse [animation-duration:2.4s] opacity-70" : "animate-pulse" : "opacity-40"
|
|
21
|
+
].join(" "),
|
|
22
|
+
style: {
|
|
23
|
+
height: n ? `${(i ? [
|
|
24
|
+
25,
|
|
25
|
+
40,
|
|
26
|
+
55,
|
|
27
|
+
45,
|
|
28
|
+
55,
|
|
29
|
+
35,
|
|
30
|
+
22
|
|
31
|
+
] : [
|
|
32
|
+
40,
|
|
33
|
+
70,
|
|
34
|
+
100,
|
|
35
|
+
85,
|
|
36
|
+
100,
|
|
37
|
+
60,
|
|
38
|
+
35
|
|
39
|
+
])[t]}%` : "20%",
|
|
40
|
+
animationDelay: `${t * 90}ms`
|
|
41
|
+
}
|
|
42
|
+
}, t))
|
|
43
|
+
});
|
|
44
|
+
//#endregion
|
|
45
|
+
export { n as VoiceWaveform };
|
package/dist/shared-assistant.js
CHANGED
|
@@ -38,4 +38,30 @@ import { isTurnInFlight as Zn } from "./shared/assistant/turnState.js";
|
|
|
38
38
|
import { AssistantToolActivity as Qn, parseToolActivity as $n } from "./shared/assistant/ui/AssistantToolActivity.js";
|
|
39
39
|
import { AssistantSpeechProvider as er, useAssistantSpeech as tr } from "./shared/assistant/ui/AssistantSpeechProvider.js";
|
|
40
40
|
import { useVoiceSession as nr } from "./shared/assistant/ui/useVoiceSession.js";
|
|
41
|
-
|
|
41
|
+
import { copyToClipboard as rr } from "./shared/assistant/clipboard.js";
|
|
42
|
+
import { getActorId as ir, getOrganizationId as ar, getWorkspaceId as or } from "./shared/assistant/context.js";
|
|
43
|
+
import { ATTACHMENT_SOURCES as sr, availableAttachmentSources as cr, deviceHasCamera as lr } from "./shared/assistant/attachmentSources.js";
|
|
44
|
+
import { SANDBOX_READY_TTL_MS as ur, createReadinessTracker as dr, isRecentlyVerified as fr } from "./shared/assistant/sandboxReadiness.js";
|
|
45
|
+
import { AssistantAutoSpeakToggle as pr } from "./shared/assistant/ui/AssistantAutoSpeakToggle.js";
|
|
46
|
+
import { AssistantMarkdownImage as mr, imageHostLabel as hr, isRemoteImageSrc as gr } from "./shared/assistant/ui/AssistantMarkdownImage.js";
|
|
47
|
+
import { AssistantMarkdownRenderer as _r, assistantUrlTransform as vr } from "./shared/assistant/ui/AssistantMarkdownRenderer.js";
|
|
48
|
+
import { AssistantMessageAttachments as yr } from "./shared/assistant/ui/AssistantMessageAttachments.js";
|
|
49
|
+
import { AssistantPendingWriteCard as br } from "./shared/assistant/ui/AssistantPendingWriteCard.js";
|
|
50
|
+
import { AssistantReplyLanguageSelector as xr } from "./shared/assistant/ui/AssistantReplyLanguageSelector.js";
|
|
51
|
+
import { AssistantSpeakButton as Sr } from "./shared/assistant/ui/AssistantSpeakButton.js";
|
|
52
|
+
import { AssistantSpokenTurnsNotice as Cr } from "./shared/assistant/ui/AssistantSpokenTurnsNotice.js";
|
|
53
|
+
import { AssistantAttachmentButton as wr } from "./shared/assistant/ui/composer/AssistantAttachmentButton.js";
|
|
54
|
+
import { AssistantAttachmentChips as Tr } from "./shared/assistant/ui/composer/AssistantAttachmentChips.js";
|
|
55
|
+
import { AssistantLanguageSelector as Er, FOLLOW_APP_LOCALE as Dr } from "./shared/assistant/ui/composer/AssistantLanguageSelector.js";
|
|
56
|
+
import { ASSISTANT_MODE_META as Or, AssistantModeSelector as kr, nextModeIndex as Ar } from "./shared/assistant/ui/composer/AssistantModeSelector.js";
|
|
57
|
+
import { AssistantVoiceButton as jr } from "./shared/assistant/ui/composer/AssistantVoiceButton.js";
|
|
58
|
+
import { AUTO_VOICE as Mr, AssistantVoiceSelector as Nr } from "./shared/assistant/ui/composer/AssistantVoiceSelector.js";
|
|
59
|
+
import { AssistantVoiceOrb as Pr } from "./shared/assistant/ui/voice/AssistantVoiceOrb.js";
|
|
60
|
+
import { AssistantVoiceSessionButton as Fr } from "./shared/assistant/ui/voice/AssistantVoiceSessionButton.js";
|
|
61
|
+
import { VoiceCaption as Ir } from "./shared/assistant/ui/voice/VoiceCaption.js";
|
|
62
|
+
import { VoiceConversationView as Lr } from "./shared/assistant/ui/voice/VoiceConversationView.js";
|
|
63
|
+
import { VoiceWaveform as Rr } from "./shared/assistant/ui/voice/VoiceWaveform.js";
|
|
64
|
+
import { VoiceMiniController as zr } from "./shared/assistant/ui/voice/VoiceMiniController.js";
|
|
65
|
+
import { VoiceStage as Br } from "./shared/assistant/ui/voice/VoiceStage.js";
|
|
66
|
+
import { VoiceTranscriptDrawer as Vr } from "./shared/assistant/ui/voice/VoiceTranscriptDrawer.js";
|
|
67
|
+
export { p as ASSISTANT_API_AUTH_STRATEGY, At as ASSISTANT_LANGUAGES, Or as ASSISTANT_MODE_META, yn as ATTACHMENT_ACCEPT, sr as ATTACHMENT_SOURCES, Mr as AUTO_VOICE, wr as AssistantAttachmentButton, Tr as AssistantAttachmentChips, pr as AssistantAutoSpeakToggle, Rt as AssistantI18nProvider, Er as AssistantLanguageSelector, mr as AssistantMarkdownImage, _r as AssistantMarkdownRenderer, yr as AssistantMessageAttachments, kr as AssistantModeSelector, br as AssistantPendingWriteCard, xr as AssistantReplyLanguageSelector, U as AssistantRuntimeManager, Sr as AssistantSpeakButton, er as AssistantSpeechProvider, Cr as AssistantSpokenTurnsNotice, Qn as AssistantToolActivity, jr as AssistantVoiceButton, Pr as AssistantVoiceOrb, Nr as AssistantVoiceSelector, Fr as AssistantVoiceSessionButton, bn as AttachmentRejectedError, Qt as BOILERPLATE_PAGE_SHARE, i as CHECK_AI_CREDITS, a as CREATE_SANDBOX, dt as DEFAULT_SPEAKABLE_LABELS, jt as DEFAULT_SPEECH_RATE, Re as ENDPOINT_GRACE_MS, o as EXTEND_SANDBOX_TTL, Dr as FOLLOW_APP_LOCALE, s as GET_ACTIVE_SANDBOXES, c as GET_SANDBOX, me as HOSTED_TTS_MAX_CHARS, ue as HOSTED_TTS_TIER, de as HOSTED_VOICES, Kt as IDLE_PLAYBACK, ze as INITIAL_SESSION, xn as INLINE_IMAGE_MAX_DIM, Sn as INLINE_IMAGE_QUALITY, Be as INTERRUPT_MAX_MS, Ve as INTERRUPT_MIN_MS, Cn as MAX_ATTACHMENTS, $t as MAX_BOILERPLATE_LINE_CHARS, en as MAX_EXTRACTED_CHARS, wn as MAX_FILE_BYTES, Tn as MAX_INLINE_CHARS_PER_FILE, En as MAX_INLINE_CHARS_TOTAL, Xt as MAX_INLINE_IMAGE_BASE64_BYTES, Dn as MAX_INLINE_IMAGE_BASE64_CHARS, On as MAX_INLINE_IMAGE_PARTS, kn as MAX_INLINE_TURN_BODY_BYTES, tn as MAX_PDF_PAGES_SCANNED, Zt as MAX_REQUEST_BODY_BYTES, ft as MAX_SPEAKABLE_CHARS, pt as MAX_SPOKEN_TABLE_ROWS, An as MAX_TURN_BODY_BYTES, nn as MIN_PAGE_TEXT_CHARS, rn as MIN_TEXT_PAGE_SHARE, Ct as POLL_FAST_MS, wt as POLL_FAST_UNTIL_MS, Tt as POLL_SLOW_MS, Et as POLL_STEADY_MS, Dt as POLL_STEADY_UNTIL_MS, xt as PREVIEW_LANGUAGES, jn as PROMPT_ENVELOPE_RESERVE_BYTES, l as PROXY_SANDBOX_REQUEST, u as REPORT_AI_TOKEN_USAGE, ur as SANDBOX_READY_TTL_MS, He as SILENCE_SUBMIT_MS, he as SPEAKING_RATE_MAX, ge as SPEAKING_RATE_MAX_STREAMING, _e as SPEAKING_RATE_MAX_SYNC, ve as SPEAKING_RATE_MIN, mt as SPEECH_CHUNK_CHARS, ht as SPEECH_CHUNK_CJK_CHARS, Xe as SPEECH_LANG, Ht as SPOKEN_LABEL_LANGUAGES, d as STOP_ASSISTANT_SANDBOX, Mn as TURN_BODY_HEADROOM_BYTES, Ze as VOICE_LIST_TIMEOUT_MS, Ir as VoiceCaption, Lr as VoiceConversationView, zr as VoiceMiniController, Br as VoiceStage, Vr as VoiceTranscriptDrawer, Rr as VoiceWaveform, f as WAIT_FOR_SANDBOX_RUNNING, zt as assistantTranslationKey, vr as assistantUrlTransform, cr as availableAttachmentSources, ye as base64ToBytes, le as browserSpeechEngine, C as buildAssistantSandboxEnv, Nn as buildAttachmentPromptBlock, ct as buildContinuedFromVoiceNote, W as buildProgress, Pn as buildPromptParts, w as buildPromptRequestBody, Fn as buildPromptWithAttachments, be as buildRequest, t as buildSandboxContextInput, lt as buildVoiceTranscriptMarkdown, ne as chatTurns, T as checkAssistantAiCredits, gt as chunkForSpeech, In as classifyAttachment, xe as classifyHttpFailure, an as columnLetterToIndex, De as configureSpeechEngine, _t as containsCjk, rr as copyToClipboard, Ln as countInlineImageCandidates, Rn as countInlinedImageParts, E as createAssistantSandbox, D as createAssistantSession, Te as createHostedTtsEngine, dr as createReadinessTracker, Ee as createRoutingSpeechEngine, ee as createSandboxAssistantTransport, Oe as createSpeechEngines, Se as decodeAudioResponse, on as decodeXmlEntities, zn as detectDocumentFormat, Wt as detectScriptLocale, lr as deviceHasCamera, sn as docxXmlToText, O as downloadAssistantArtifact, Bn as estimateTurnBodyBytes, n as executeSandboxGraphQL, k as extendAssistantSandboxTTL, Mt as findAssistantLanguage, A as findExistingSandbox, It as findPendingWrite, cn as fitPdfPages, Vn as formatBytes, ln as formatPageRanges, ir as getActorId, j as getAssistantArtifacts, G as getAssistantMedia, M as getAssistantMessages, N as getAssistantSession, P as getAssistantStreamAccess, K as getAssistantText, Hn as getAttachmentSendBlocker, y as getCapability, Un as getExtension, m as getImageForMode, h as getImageTagForMode, ar as getOrganizationId, q as getRawMessageCreatedAt, g as getResourcesForMode, _ as getSandboxImageRegistry, Wn as getSendableAttachments, ke as getSpeechEngine, J as getToolProgress, or as getWorkspaceId, re as groupBySession, ie as groupConsecutiveBySession, Gn as hasAttachmentWorkInFlight, fe as hostedLocaleFor, pe as hostedSupportsLanguage, hr as imageHostLabel, Ue as isCapturing, We as isEcho, un as isMostlyImagePages, r as isQuotaExhaustedError, Y as isReapedSandboxConnectionError, fr as isRecentlyVerified, X as isRecoverable, gr as isRemoteImageSrc, qt as isSpeakingMessage, Qe as isSpeechBlocked, Ge as isSubmittable, Zn as isTurnInFlight, b as isUnknownFieldError, ae as isVoiceTurn, dn as joinSheets, $e as languageDisplayName, Z as mapSessionToHistory, x as markSupported, S as markUnsupported, Q as mergeMessagesById, Me as micIsInterrupt, F as modeRequiresConfirmWrites, Ar as nextModeIndex, et as normalizeLangTag, Ke as orbMode, fn as pageMarker, Lt as parseConfirmationRefusal, Kn as parseDataUrl, pn as parseSharedStrings, $n as parseToolActivity, mn as parseWorkbookSheets, hn as pdfTextItemsToPage, qe as planReplyConsumption, Ot as pollDelayMs, tt as primaryLanguageSubtag, Ae as readSpeechEngineConfig, Pt as replyFollowsInput, I as reportAssistantAiTokenUsage, Jt as requiresCancel, je as resetSpeechEngine, Nt as resolveAssistantLanguage, Ft as resolveLanguagePair, v as resolveSandboxAssistantMode, Gt as resolveSpeechLocale, $ as sanitize, L as selectExistingAssistantSandbox, nt as selectVoiceForLocale, R as sendAssistantPromptAsync, z as sendHeartbeat, gn as sheetXmlToRows, Ce as shouldDisableEngine, Ne as showsAssistantCaption, Pe as showsUserCaption, vt as speakableEmail, rt as speechGate, Ut as speechLabelsFor, it as speechLangForLocale, Yt as speechPlaybackReducer, we as splitForVendor, yt as splitTableRow, Je as spokenSoFar, B as stopReapedAssistantSandbox, _n as summarisePageText, kt as toCaptionText, qn as toMessageAttachment, bt as toSpeakableText, Jn as truncateForInline, vn as truncatePagesForInline, Bt as useAssistantI18nNamespace, tr as useAssistantSpeech, Xn as useAssistantStore, Vt as useAssistantTr, te as useSandboxAssistantTransport, e as useVoiceInput, nr as useVoiceSession, Yn as validateFile, at as voiceAvailability, oe as voiceMarker, St as voicePreviewText, ot as voiceQualityRank, se as voiceSessionIdOf, Ye as voiceSessionReducer, Fe as voiceStageState, ut as voiceTranscriptFilename, ce as voiceTurnsOnly, st as voicesForLocale, V as waitForAssistantServiceReady, H as waitForSandboxRunning, Ie as waveformIsActive, Le as waveformIsSettled };
|