@burdenoff/fe-libs 2026.1029.3 → 2026.1029.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/conversation.d.ts +10 -0
- package/dist/shared/assistant/i18nManifest.d.ts +15 -2
- package/dist/shared/assistant/i18nManifest.js +12 -0
- package/dist/shared/assistant/index.d.ts +4 -0
- package/dist/shared/assistant/productCopy.d.ts +8 -0
- package/dist/shared/assistant/productCopy.js +8 -5
- package/dist/shared/assistant/ui/AIAssistantPanel.d.ts +9 -0
- package/dist/shared/assistant/ui/AIAssistantPanel.js +70 -69
- package/dist/shared/assistant/ui/AssistantApiCallsConsentDialog.d.ts +23 -0
- package/dist/shared/assistant/ui/AssistantApiCallsConsentDialog.js +72 -18
- package/dist/shared/assistant/ui/AssistantChatArea.d.ts +6 -0
- package/dist/shared/assistant/ui/AssistantChatArea.js +1176 -1065
- package/dist/shared/assistant/ui/composer/AssistantComposer.d.ts +27 -0
- package/dist/shared/assistant/ui/composer/AssistantComposer.js +350 -206
- package/dist/shared/assistant/ui/composer/AssistantModeMenu.d.ts +51 -0
- package/dist/shared/assistant/ui/composer/AssistantModeMenu.js +188 -0
- package/dist/shared/assistant/ui/composer/imeEnter.d.ts +44 -0
- package/dist/shared/assistant/ui/composer/imeEnter.js +11 -0
- package/dist/shared/assistant/ui/composer/modeMenuKeys.d.ts +76 -0
- package/dist/shared/assistant/ui/composer/modeMenuKeys.js +61 -0
- package/dist/shared/assistant/ui/composer/modeSwitchPlan.d.ts +73 -0
- package/dist/shared/assistant/ui/composer/modeSwitchPlan.js +25 -0
- package/dist/shared-assistant.js +241 -237
- package/package.json +1 -1
|
@@ -407,6 +407,16 @@ export interface AssistantModeConfig {
|
|
|
407
407
|
id: AssistantMode;
|
|
408
408
|
label: string;
|
|
409
409
|
description: string;
|
|
410
|
+
/**
|
|
411
|
+
* One line under the mode's name in the COMPACT presentation's Mode menu
|
|
412
|
+
* (BOFF-10055): what the mode does, in the product's confirmed wording.
|
|
413
|
+
* Translated at display time under `modeShortDescription.<id>`
|
|
414
|
+
* (`productCopy.ts`), which `assistantI18nSeedCopy` emits.
|
|
415
|
+
*
|
|
416
|
+
* ★ Not `description`: that is the long description, already seeded under
|
|
417
|
+
* `modeDescription.<id>` with a different meaning. Absent: no line.
|
|
418
|
+
*/
|
|
419
|
+
shortDescription?: string;
|
|
410
420
|
suggestions: readonly string[];
|
|
411
421
|
/** Only offered to a workspace admin, `sandbox:admin` here (see useAssistantApiAccess). */
|
|
412
422
|
requiresAdmin?: boolean;
|
|
@@ -41,7 +41,8 @@ import { AssistantModeConfig } from './conversation';
|
|
|
41
41
|
* - A mode's `description` and `suggestions`, and the page label from
|
|
42
42
|
* `describeCurrentPage()`, are the product's words too. Since BOFF-8060 (F5)
|
|
43
43
|
* they are translated AT DISPLAY TIME under keys derived from their English
|
|
44
|
-
* (`suggestion.<mode>.<slug>`, `modeDescription.<mode>`,
|
|
44
|
+
* (`suggestion.<mode>.<slug>`, `modeDescription.<mode>`,
|
|
45
|
+
* `modeShortDescription.<mode>`, `page.<slug>`; see
|
|
45
46
|
* `productCopy.ts`). They stay out of the shared manifest, and
|
|
46
47
|
* `assistantI18nSeedCopy` emits them from the product's own modes and the
|
|
47
48
|
* `pageLabels` it passes — so a product passes its ENGLISH, never a
|
|
@@ -352,6 +353,8 @@ export declare const ASSISTANT_I18N_LITERAL_COPY: {
|
|
|
352
353
|
readonly 'composer.dropHere': "Drop files to attach";
|
|
353
354
|
readonly 'composer.hint': "Enter to send · Shift+Enter for newline · drag or paste files to attach";
|
|
354
355
|
readonly 'composer.placeholder': "Ask me anything…";
|
|
356
|
+
readonly 'composer.stop': "Stop the reply";
|
|
357
|
+
readonly 'composer.stopped': "Reply stopped.";
|
|
355
358
|
readonly 'composer.voiceStart': "Dictate a message";
|
|
356
359
|
readonly 'composer.voiceStarting': "Starting the microphone — tap to cancel";
|
|
357
360
|
readonly 'composer.voiceStop': "Stop dictation";
|
|
@@ -500,9 +503,19 @@ export declare const ASSISTANT_I18N_LITERAL_COPY: {
|
|
|
500
503
|
readonly 'message.stopSpeaking': "Stop reading aloud";
|
|
501
504
|
readonly 'message.stopSpeakingShort': "Stop";
|
|
502
505
|
readonly 'messageList.ariaLabel': "Conversation messages";
|
|
506
|
+
readonly 'modeMenu.disabledBusy': "Mode can't change right now.";
|
|
507
|
+
readonly 'modeMenu.disabledReplying': "Mode can't change while the assistant is replying. Stop the reply to change it.";
|
|
508
|
+
readonly 'modeMenu.staticLabel': "Mode: {{mode}}";
|
|
509
|
+
readonly 'modeMenu.trigger': "Assistant mode: {{mode}}";
|
|
503
510
|
readonly 'modeSelector.ariaLabel': "Select assistant mode";
|
|
504
511
|
readonly 'modeSelector.auto': "Auto";
|
|
505
512
|
readonly 'modeSelector.autoHint': "Answers your questions, and proposes changes for you to approve";
|
|
513
|
+
readonly 'modeSwitch.confirm': "Switch to {{mode}}";
|
|
514
|
+
readonly 'modeSwitch.draftKept': "What you typed stays in the message box.";
|
|
515
|
+
readonly 'modeSwitch.intro': "If you switch now:";
|
|
516
|
+
readonly 'modeSwitch.newConversation': "{{mode}} continues in a new conversation. This one stays in History.";
|
|
517
|
+
readonly 'modeSwitch.title': "Switch to {{mode}}?";
|
|
518
|
+
readonly 'modeSwitch.withdrawn': "{{count}} change(s) waiting for your approval will be withdrawn.";
|
|
506
519
|
readonly 'offer.announce': "Suggested page: {{page}}";
|
|
507
520
|
readonly 'offer.expired': "That suggestion has expired. Ask again, or use the menu.";
|
|
508
521
|
readonly 'offer.hintLink': "Tap, or say “take me there”.";
|
|
@@ -708,7 +721,7 @@ export declare const ASSISTANT_I18N_MANIFEST: Readonly<Record<string, string>>;
|
|
|
708
721
|
* The part of a mode that decides its keys and English: the pill, plus (when
|
|
709
722
|
* given) its description and suggestion chips (BOFF-8060, F5).
|
|
710
723
|
*/
|
|
711
|
-
export type AssistantModeCopySource = Pick<AssistantModeConfig, 'id' | 'label' | 'producesArtifacts'> & Partial<Pick<AssistantModeConfig, 'description' | 'suggestions'>>;
|
|
724
|
+
export type AssistantModeCopySource = Pick<AssistantModeConfig, 'id' | 'label' | 'producesArtifacts'> & Partial<Pick<AssistantModeConfig, 'description' | 'shortDescription' | 'suggestions'>>;
|
|
712
725
|
/**
|
|
713
726
|
* `mode.<id>` for each mode a product offers, in the product's own words.
|
|
714
727
|
*
|
|
@@ -246,6 +246,8 @@ var g = {
|
|
|
246
246
|
"composer.dropHere": "Drop files to attach",
|
|
247
247
|
"composer.hint": "Enter to send · Shift+Enter for newline · drag or paste files to attach",
|
|
248
248
|
"composer.placeholder": "Ask me anything…",
|
|
249
|
+
"composer.stop": "Stop the reply",
|
|
250
|
+
"composer.stopped": "Reply stopped.",
|
|
249
251
|
"composer.voiceStart": "Dictate a message",
|
|
250
252
|
"composer.voiceStarting": "Starting the microphone — tap to cancel",
|
|
251
253
|
"composer.voiceStop": "Stop dictation",
|
|
@@ -394,9 +396,19 @@ var g = {
|
|
|
394
396
|
"message.stopSpeaking": "Stop reading aloud",
|
|
395
397
|
"message.stopSpeakingShort": "Stop",
|
|
396
398
|
"messageList.ariaLabel": "Conversation messages",
|
|
399
|
+
"modeMenu.disabledBusy": "Mode can't change right now.",
|
|
400
|
+
"modeMenu.disabledReplying": "Mode can't change while the assistant is replying. Stop the reply to change it.",
|
|
401
|
+
"modeMenu.staticLabel": "Mode: {{mode}}",
|
|
402
|
+
"modeMenu.trigger": "Assistant mode: {{mode}}",
|
|
397
403
|
"modeSelector.ariaLabel": "Select assistant mode",
|
|
398
404
|
"modeSelector.auto": "Auto",
|
|
399
405
|
"modeSelector.autoHint": "Answers your questions, and proposes changes for you to approve",
|
|
406
|
+
"modeSwitch.confirm": "Switch to {{mode}}",
|
|
407
|
+
"modeSwitch.draftKept": "What you typed stays in the message box.",
|
|
408
|
+
"modeSwitch.intro": "If you switch now:",
|
|
409
|
+
"modeSwitch.newConversation": "{{mode}} continues in a new conversation. This one stays in History.",
|
|
410
|
+
"modeSwitch.title": "Switch to {{mode}}?",
|
|
411
|
+
"modeSwitch.withdrawn": "{{count}} change(s) waiting for your approval will be withdrawn.",
|
|
400
412
|
"offer.announce": "Suggested page: {{page}}",
|
|
401
413
|
"offer.expired": "That suggestion has expired. Ask again, or use the menu.",
|
|
402
414
|
"offer.hintLink": "Tap, or say “take me there”.",
|
|
@@ -168,6 +168,10 @@ export * from './preview/bridgeHostContext';
|
|
|
168
168
|
export * from './preview/AssistantPreviewOverlay';
|
|
169
169
|
export * from './ui/composer/AssistantLanguageSelector';
|
|
170
170
|
export * from './ui/composer/AssistantModeSelector';
|
|
171
|
+
export * from './ui/composer/AssistantModeMenu';
|
|
172
|
+
export * from './ui/composer/modeMenuKeys';
|
|
173
|
+
export * from './ui/composer/modeSwitchPlan';
|
|
174
|
+
export * from './ui/composer/imeEnter';
|
|
171
175
|
export * from './ui/composer/AssistantVoiceButton';
|
|
172
176
|
export * from './ui/composer/AssistantVoiceSelector';
|
|
173
177
|
export * from './ui/composer/AssistantVoiceGraceSelector';
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
*
|
|
14
14
|
* suggestion.<modeId>.<slug(english)> a suggestion chip
|
|
15
15
|
* modeDescription.<modeId> a mode's description
|
|
16
|
+
* modeShortDescription.<modeId> a mode's one-line Mode-menu text
|
|
16
17
|
* page.<slug(english)> a page label
|
|
17
18
|
*
|
|
18
19
|
* `slug` is the lower-camel ASCII of the English ("Show overdue tasks" ->
|
|
@@ -62,6 +63,12 @@ export declare function assistantCopySlug(english: string): string | null;
|
|
|
62
63
|
export declare function assistantSuggestionKey(modeId: string, english: string): string | null;
|
|
63
64
|
/** `modeDescription.<modeId>`. */
|
|
64
65
|
export declare function assistantModeDescriptionKey(modeId: string): string;
|
|
66
|
+
/**
|
|
67
|
+
* `modeShortDescription.<modeId>`: the one line under a mode in the compact
|
|
68
|
+
* Mode menu (BOFF-10055). A separate family from `modeDescription.<modeId>`,
|
|
69
|
+
* which holds the long description and is already seeded with that meaning.
|
|
70
|
+
*/
|
|
71
|
+
export declare function assistantModeShortDescriptionKey(modeId: string): string;
|
|
65
72
|
/** `page.<slug>`, or null for a label that cannot be keyed. */
|
|
66
73
|
export declare function assistantPageLabelKey(english: string): string | null;
|
|
67
74
|
/** Translate one piece of product copy, or return it unchanged when unkeyable. */
|
|
@@ -71,6 +78,7 @@ export declare function assistantProductCopyEntries(args: {
|
|
|
71
78
|
modes: readonly {
|
|
72
79
|
id: string;
|
|
73
80
|
description?: string;
|
|
81
|
+
shortDescription?: string;
|
|
74
82
|
suggestions?: readonly string[];
|
|
75
83
|
}[];
|
|
76
84
|
pageLabels?: readonly string[];
|
|
@@ -21,13 +21,16 @@ function o(e) {
|
|
|
21
21
|
return `modeDescription.${e}`;
|
|
22
22
|
}
|
|
23
23
|
function s(e) {
|
|
24
|
+
return `modeShortDescription.${e}`;
|
|
25
|
+
}
|
|
26
|
+
function c(e) {
|
|
24
27
|
let t = i(e);
|
|
25
28
|
return t === null ? null : `page.${t}`;
|
|
26
29
|
}
|
|
27
|
-
function
|
|
30
|
+
function l(e, t, n) {
|
|
28
31
|
return t === null ? n : e(t, n);
|
|
29
32
|
}
|
|
30
|
-
function
|
|
33
|
+
function u(e) {
|
|
31
34
|
let t = {}, n = (e, n) => {
|
|
32
35
|
if (e === null) return;
|
|
33
36
|
let r = t[e];
|
|
@@ -35,11 +38,11 @@ function l(e) {
|
|
|
35
38
|
t[e] = n;
|
|
36
39
|
};
|
|
37
40
|
for (let t of e.modes) {
|
|
38
|
-
t.description && t.description.trim() !== "" && n(o(t.id), t.description);
|
|
41
|
+
t.description && t.description.trim() !== "" && n(o(t.id), t.description), t.shortDescription && t.shortDescription.trim() !== "" && n(s(t.id), t.shortDescription);
|
|
39
42
|
for (let e of t.suggestions ?? []) n(a(t.id, e), e);
|
|
40
43
|
}
|
|
41
|
-
for (let t of e.pageLabels ?? []) n(
|
|
44
|
+
for (let t of e.pageLabels ?? []) n(c(t), t);
|
|
42
45
|
return t;
|
|
43
46
|
}
|
|
44
47
|
//#endregion
|
|
45
|
-
export { e as MAX_COPY_SLUG_LENGTH, i as assistantCopySlug, o as assistantModeDescriptionKey, s as assistantPageLabelKey,
|
|
48
|
+
export { e as MAX_COPY_SLUG_LENGTH, i as assistantCopySlug, o as assistantModeDescriptionKey, s as assistantModeShortDescriptionKey, c as assistantPageLabelKey, u as assistantProductCopyEntries, a as assistantSuggestionKey, l as translateProductCopy };
|
|
@@ -4,6 +4,7 @@ import { WorkspaceWriteAccess } from '../useWorkspaceWriteAccess';
|
|
|
4
4
|
import { AssistantNavigate } from './AssistantMarkdownRenderer';
|
|
5
5
|
import { AssistantLiveAvatarSeam } from './assistantLiveAvatarSeam';
|
|
6
6
|
import { AssistantPreviewController } from '../preview/types';
|
|
7
|
+
import { AssistantPresentation } from './composer/AssistantComposer';
|
|
7
8
|
export type AIAssistantPanelProps = PanelProps & {
|
|
8
9
|
/** When provided, renders a dock/float toggle in the header. */
|
|
9
10
|
docked?: boolean;
|
|
@@ -104,6 +105,14 @@ export type AIAssistantPanelProps = PanelProps & {
|
|
|
104
105
|
* a prop chain. See `assistantLiveAvatarSeam`.
|
|
105
106
|
*/
|
|
106
107
|
liveAvatar?: AssistantLiveAvatarSeam;
|
|
108
|
+
/**
|
|
109
|
+
* BOFF-10055: how the assistant is presented. Absent or `classic`: exactly the
|
|
110
|
+
* panel of before. `compact` opts this product into the redesigned composer
|
|
111
|
+
* (Slice 1: the card, the Mode menu, Stop, IME-safe Enter and the mode-switch
|
|
112
|
+
* confirmation). A product passes it through `AssistantOverlay`'s
|
|
113
|
+
* `panelProps`, behind its own flag.
|
|
114
|
+
*/
|
|
115
|
+
presentation?: AssistantPresentation;
|
|
107
116
|
};
|
|
108
117
|
/**
|
|
109
118
|
* The panel.
|
|
@@ -5,47 +5,47 @@ import { useAssistantTr as n } from "../i18n.js";
|
|
|
5
5
|
import { useAssistantStore as r } from "../store.js";
|
|
6
6
|
import { AssistantSpeechProvider as i } from "./AssistantSpeechProvider.js";
|
|
7
7
|
import { ASSISTANT_OVERLAY_ATTR as a, ASSISTANT_PANEL_ATTR as o, activePanelOverlay as s, escapeDismisses as c, nextPanelOverlays as l } from "./panelOverlays.js";
|
|
8
|
-
import { LiveAvatarSeamProvider as u, LiveAvatarTabContext as d, useLiveAvatarSpeechEngine as
|
|
9
|
-
import { AssistantPreviewProvider as
|
|
10
|
-
import { useAssistantPreviewBridge as
|
|
11
|
-
import { AssistantConnectSourceProvider as
|
|
12
|
-
import { hasAssistantPreviewSurface as
|
|
13
|
-
import { panelOwnedPreviewBridge as
|
|
14
|
-
import { AssistantPreviewOverlay as
|
|
15
|
-
import { AssistantHeader as
|
|
16
|
-
import { AssistantConversationList as
|
|
17
|
-
import { AssistantConversationDeleteDialogProvider as
|
|
18
|
-
import { AssistantControlConfirmProvider as
|
|
19
|
-
import { AssistantLeaveConfirmNavigateProvider as
|
|
20
|
-
import { useAssistantServerHistory as
|
|
21
|
-
import { useFilesServiceWarmup as
|
|
22
|
-
import { AssistantAvatarTabs as
|
|
23
|
-
import { useAssistantHeartbeat as
|
|
24
|
-
import { useAssistantKeyboardShortcuts as
|
|
25
|
-
import { AssistantChatArea as
|
|
26
|
-
import { useCallback as
|
|
27
|
-
import { jsx as
|
|
8
|
+
import { LiveAvatarSeamProvider as u, LiveAvatarTabContext as d, useLiveAvatarSpeechEngine as te, useLiveAvatarTabOffered as ne } from "./assistantLiveAvatarSeam.js";
|
|
9
|
+
import { AssistantPreviewProvider as re } from "../preview/context.js";
|
|
10
|
+
import { useAssistantPreviewBridge as ie } from "../preview/useAssistantPreviewBridge.js";
|
|
11
|
+
import { AssistantConnectSourceProvider as ae } from "./composer/connectSource.js";
|
|
12
|
+
import { hasAssistantPreviewSurface as oe } from "../preview/types.js";
|
|
13
|
+
import { panelOwnedPreviewBridge as se, useHostedAssistantPreviewBridge as ce } from "../preview/bridgeHostContext.js";
|
|
14
|
+
import { AssistantPreviewOverlay as le } from "../preview/AssistantPreviewOverlay.js";
|
|
15
|
+
import { AssistantHeader as ue } from "./AssistantHeader.js";
|
|
16
|
+
import { AssistantConversationList as de } from "./AssistantConversationList.js";
|
|
17
|
+
import { AssistantConversationDeleteDialogProvider as fe } from "./conversationDeleteDialog.js";
|
|
18
|
+
import { AssistantControlConfirmProvider as pe } from "./controlConfirmDialog.js";
|
|
19
|
+
import { AssistantLeaveConfirmNavigateProvider as me } from "./leaveConfirm.js";
|
|
20
|
+
import { useAssistantServerHistory as he } from "../history/useAssistantServerHistory.js";
|
|
21
|
+
import { useFilesServiceWarmup as ge } from "../../../storage/warmFilesService.js";
|
|
22
|
+
import { AssistantAvatarTabs as _e } from "./AssistantAvatarTabs.js";
|
|
23
|
+
import { useAssistantHeartbeat as ve } from "../useAssistantHeartbeat.js";
|
|
24
|
+
import { useAssistantKeyboardShortcuts as ye } from "../useAssistantKeyboardShortcuts.js";
|
|
25
|
+
import { AssistantChatArea as be } from "./AssistantChatArea.js";
|
|
26
|
+
import { useCallback as f, useId as p, useMemo as m, useRef as h, useState as g } from "react";
|
|
27
|
+
import { jsx as _, jsxs as v } from "react/jsx-runtime";
|
|
28
28
|
//#region src/shared/assistant/ui/AIAssistantPanel.tsx
|
|
29
|
-
var
|
|
30
|
-
let M = n(), N =
|
|
31
|
-
|
|
32
|
-
let [P, F] =
|
|
29
|
+
var y = ({ onClose: y, visible: b, docked: x, onToggleDock: S, writeAccess: C, onNavigate: w, isShellLessTarget: T, connectSourceHref: E, onConnectSource: D, preview: O, liveAvatar: k, presentation: A, serverHistory: j = !1 }) => {
|
|
30
|
+
let M = n(), N = te(k);
|
|
31
|
+
he(j);
|
|
32
|
+
let [P, F] = g(!1), I = oe(O);
|
|
33
33
|
P && !I && F(!1);
|
|
34
34
|
let L = P && I;
|
|
35
|
-
|
|
36
|
-
let R =
|
|
35
|
+
ie(se(O, ce()));
|
|
36
|
+
let R = h(null);
|
|
37
37
|
e(R);
|
|
38
|
-
let { conversations:
|
|
39
|
-
U && (!H ||
|
|
40
|
-
let G = H !== void 0 && (
|
|
38
|
+
let { conversations: xe, activeConversationId: Se, conversationListOpen: z, setConversationListOpen: B, createConversation: Ce } = r(), V = z || L, H = k?.tab, we = ne(H), [U, W] = g(!1);
|
|
39
|
+
U && (!H || b === !1) && W(!1);
|
|
40
|
+
let G = H !== void 0 && (we || U), K = p(), q = m(() => G ? {
|
|
41
41
|
chatTab: `${K}-chat-tab`,
|
|
42
42
|
avatarTab: `${K}-avatar-tab`,
|
|
43
43
|
chatPanel: `${K}-chat-panel`,
|
|
44
44
|
avatarPanel: `${K}-avatar-panel`,
|
|
45
45
|
leaveHint: `${K}-avatar-leave`
|
|
46
|
-
} : null, [G, K]), J =
|
|
46
|
+
} : null, [G, K]), J = f(() => W(!1), []), Y = h(null), X = f((e) => {
|
|
47
47
|
Y.current = e;
|
|
48
|
-
}, []),
|
|
48
|
+
}, []), Te = m(() => ({
|
|
49
49
|
open: U,
|
|
50
50
|
close: J,
|
|
51
51
|
ids: q,
|
|
@@ -57,7 +57,7 @@ var b = ({ onClose: b, visible: x, docked: S, onToggleDock: C, writeAccess: w, o
|
|
|
57
57
|
q,
|
|
58
58
|
V,
|
|
59
59
|
X
|
|
60
|
-
]),
|
|
60
|
+
]), Ee = (e) => W(e === "avatar"), Z = s({
|
|
61
61
|
historyOpen: z,
|
|
62
62
|
previewOpen: L,
|
|
63
63
|
avatarOpen: U
|
|
@@ -68,7 +68,7 @@ var b = ({ onClose: b, visible: x, docked: S, onToggleDock: C, writeAccess: w, o
|
|
|
68
68
|
}, e);
|
|
69
69
|
B(t.historyOpen), F(t.previewOpen);
|
|
70
70
|
};
|
|
71
|
-
t("assistant.history",
|
|
71
|
+
t("assistant.history", m(() => ({ run: () => z ? { status: "already" } : (B(!0), F(!1), { status: "done" }) }), [z, B])), t("assistant.preview", m(() => I ? {
|
|
72
72
|
surface: "panel",
|
|
73
73
|
run: () => L ? { status: "already" } : (B(!1), F(!0), { status: "done" }),
|
|
74
74
|
close: () => L ? (F(!1), { status: "done" }) : { status: "already" }
|
|
@@ -77,10 +77,10 @@ var b = ({ onClose: b, visible: x, docked: S, onToggleDock: C, writeAccess: w, o
|
|
|
77
77
|
L,
|
|
78
78
|
B
|
|
79
79
|
]));
|
|
80
|
-
let $ =
|
|
81
|
-
|
|
82
|
-
let
|
|
83
|
-
return
|
|
80
|
+
let $ = xe.find((e) => e.id === Se);
|
|
81
|
+
ve($?.backendSessionId ?? null, $?.mode ?? null, b ?? !0), ge(b ?? !0);
|
|
82
|
+
let De = ee(b !== !1);
|
|
83
|
+
return ye({
|
|
84
84
|
panelRef: R,
|
|
85
85
|
onClose: () => {
|
|
86
86
|
let e = c({
|
|
@@ -101,24 +101,24 @@ var b = ({ onClose: b, visible: x, docked: S, onToggleDock: C, writeAccess: w, o
|
|
|
101
101
|
W(!1), q && document.getElementById(q.chatTab)?.focus();
|
|
102
102
|
return;
|
|
103
103
|
}
|
|
104
|
-
|
|
104
|
+
y();
|
|
105
105
|
}
|
|
106
|
-
}), /* @__PURE__ */
|
|
107
|
-
visible:
|
|
106
|
+
}), /* @__PURE__ */ _(i, {
|
|
107
|
+
visible: b ?? !0,
|
|
108
108
|
engine: N,
|
|
109
|
-
children: /* @__PURE__ */
|
|
110
|
-
value:
|
|
111
|
-
children: /* @__PURE__ */
|
|
112
|
-
value:
|
|
113
|
-
children: /* @__PURE__ */
|
|
114
|
-
value:
|
|
115
|
-
children: /* @__PURE__ */
|
|
116
|
-
navigate:
|
|
117
|
-
isShellLessTarget:
|
|
118
|
-
children: /* @__PURE__ */
|
|
119
|
-
value:
|
|
120
|
-
onOpen:
|
|
121
|
-
children: /* @__PURE__ */
|
|
109
|
+
children: /* @__PURE__ */ _(u, {
|
|
110
|
+
value: k,
|
|
111
|
+
children: /* @__PURE__ */ _(d.Provider, {
|
|
112
|
+
value: Te,
|
|
113
|
+
children: /* @__PURE__ */ _(re, {
|
|
114
|
+
value: O,
|
|
115
|
+
children: /* @__PURE__ */ _(me, {
|
|
116
|
+
navigate: w,
|
|
117
|
+
isShellLessTarget: T,
|
|
118
|
+
children: /* @__PURE__ */ _(ae, {
|
|
119
|
+
value: E,
|
|
120
|
+
onOpen: D,
|
|
121
|
+
children: /* @__PURE__ */ _(fe, { children: /* @__PURE__ */ _(pe, { children: /* @__PURE__ */ v("div", {
|
|
122
122
|
ref: R,
|
|
123
123
|
className: "relative flex h-full w-full flex-col bg-bg-surface",
|
|
124
124
|
role: "complementary",
|
|
@@ -128,33 +128,34 @@ var b = ({ onClose: b, visible: x, docked: S, onToggleDock: C, writeAccess: w, o
|
|
|
128
128
|
...Z ? { [a]: Z } : {},
|
|
129
129
|
tabIndex: -1,
|
|
130
130
|
children: [
|
|
131
|
-
/* @__PURE__ */
|
|
131
|
+
/* @__PURE__ */ v("div", {
|
|
132
132
|
className: "contents",
|
|
133
133
|
inert: V || void 0,
|
|
134
|
-
children: [/* @__PURE__ */
|
|
135
|
-
contextLabel:
|
|
136
|
-
onNewConversation: () =>
|
|
134
|
+
children: [/* @__PURE__ */ _(ue, {
|
|
135
|
+
contextLabel: De,
|
|
136
|
+
onNewConversation: () => Ce(),
|
|
137
137
|
onOpenHistory: () => Q("history"),
|
|
138
138
|
historyOpen: z,
|
|
139
139
|
onTogglePreview: () => Q("preview"),
|
|
140
140
|
previewOpen: L,
|
|
141
|
-
onClose:
|
|
142
|
-
docked:
|
|
143
|
-
onToggleDock:
|
|
144
|
-
}), q ? /* @__PURE__ */
|
|
141
|
+
onClose: y,
|
|
142
|
+
docked: x,
|
|
143
|
+
onToggleDock: S
|
|
144
|
+
}), q ? /* @__PURE__ */ _(_e, {
|
|
145
145
|
selected: U ? "avatar" : "chat",
|
|
146
|
-
onSelect:
|
|
146
|
+
onSelect: Ee,
|
|
147
147
|
ids: q
|
|
148
148
|
}) : null]
|
|
149
149
|
}),
|
|
150
|
-
z && /* @__PURE__ */
|
|
151
|
-
L && /* @__PURE__ */
|
|
152
|
-
/* @__PURE__ */
|
|
150
|
+
z && /* @__PURE__ */ _(de, {}),
|
|
151
|
+
L && /* @__PURE__ */ _(le, { onClose: () => F(!1) }),
|
|
152
|
+
/* @__PURE__ */ _("div", {
|
|
153
153
|
className: "contents",
|
|
154
154
|
inert: V || void 0,
|
|
155
|
-
children: /* @__PURE__ */
|
|
156
|
-
visible:
|
|
157
|
-
writeAccess:
|
|
155
|
+
children: /* @__PURE__ */ _(be, {
|
|
156
|
+
visible: b ?? !0,
|
|
157
|
+
writeAccess: C,
|
|
158
|
+
presentation: A
|
|
158
159
|
})
|
|
159
160
|
})
|
|
160
161
|
]
|
|
@@ -167,4 +168,4 @@ var b = ({ onClose: b, visible: x, docked: S, onToggleDock: C, writeAccess: w, o
|
|
|
167
168
|
});
|
|
168
169
|
};
|
|
169
170
|
//#endregion
|
|
170
|
-
export {
|
|
171
|
+
export { y as AIAssistantPanel };
|
|
@@ -14,6 +14,29 @@ export interface AssistantApiCallsConsentDialogProps {
|
|
|
14
14
|
mode?: WriteConsentMode;
|
|
15
15
|
/** The mode being left, which names the cancel button. Absent: Ask. */
|
|
16
16
|
currentMode?: WriteConsentMode | null;
|
|
17
|
+
/**
|
|
18
|
+
* The COMPACT presentation's mode switch (BOFF-10055, D7 merged with the
|
|
19
|
+
* consent): what this switch costs, said in the same dialog as the consent,
|
|
20
|
+
* so one decision never needs two dialogs.
|
|
21
|
+
*
|
|
22
|
+
* Absent: the consent dialog exactly as before, byte for byte.
|
|
23
|
+
*/
|
|
24
|
+
switchPlan?: AssistantModeSwitchDialogPlan;
|
|
25
|
+
}
|
|
26
|
+
/** What the dialog says about one switch. From `planModeSwitch`, plus the names. */
|
|
27
|
+
export interface AssistantModeSwitchDialogPlan {
|
|
28
|
+
/** First-time write consent applies: the consent's title, body and buttons lead. */
|
|
29
|
+
consent: boolean;
|
|
30
|
+
withdrawnCount: number;
|
|
31
|
+
movesToNewConversation: boolean;
|
|
32
|
+
draftKept: boolean;
|
|
33
|
+
/** The option switched to, named as its menu item names it ("Workflow", "Auto"). */
|
|
34
|
+
targetName: string;
|
|
35
|
+
/**
|
|
36
|
+
* The option being left, when `currentMode` cannot name it (Auto is not a
|
|
37
|
+
* mode). Names the "Stay in …" button.
|
|
38
|
+
*/
|
|
39
|
+
currentName?: string;
|
|
17
40
|
}
|
|
18
41
|
/**
|
|
19
42
|
* One-time consent shown the first time a user switches the assistant into a
|
|
@@ -3,35 +3,89 @@ import { ModalShell as t } from "../../../ui/modal-shell.js";
|
|
|
3
3
|
import { useAssistantTr as n } from "../i18n.js";
|
|
4
4
|
import { writeModeConsentCopy as r } from "../writeModeConsent.js";
|
|
5
5
|
import { modeRequiresConfirmWrites as i } from "../api.js";
|
|
6
|
-
import {
|
|
6
|
+
import { useRef as a } from "react";
|
|
7
|
+
import { Fragment as o, jsx as s, jsxs as c } from "react/jsx-runtime";
|
|
7
8
|
//#region src/shared/assistant/ui/AssistantApiCallsConsentDialog.tsx
|
|
8
|
-
var
|
|
9
|
-
let
|
|
10
|
-
target:
|
|
11
|
-
current:
|
|
12
|
-
confirmsWrites: i(
|
|
9
|
+
var l = { id: "api-calls" }, u = ({ open: a, onConfirm: u, onCancel: f, mode: p = l, currentMode: m, switchPlan: h }) => {
|
|
10
|
+
let g = r(n(), {
|
|
11
|
+
target: p,
|
|
12
|
+
current: m,
|
|
13
|
+
confirmsWrites: i(p.id)
|
|
13
14
|
});
|
|
14
|
-
return /* @__PURE__ */
|
|
15
|
-
open:
|
|
16
|
-
|
|
15
|
+
return h ? /* @__PURE__ */ s(d, {
|
|
16
|
+
open: a,
|
|
17
|
+
onConfirm: u,
|
|
18
|
+
onCancel: f,
|
|
19
|
+
plan: h,
|
|
20
|
+
consentCopy: g
|
|
21
|
+
}) : /* @__PURE__ */ s(t, {
|
|
22
|
+
open: a,
|
|
23
|
+
onClose: f,
|
|
17
24
|
size: "sm",
|
|
18
|
-
title:
|
|
19
|
-
footer: /* @__PURE__ */
|
|
25
|
+
title: g.title,
|
|
26
|
+
footer: /* @__PURE__ */ c(o, { children: [/* @__PURE__ */ s(e, {
|
|
20
27
|
variant: "outline",
|
|
21
|
-
onClick:
|
|
28
|
+
onClick: f,
|
|
22
29
|
"data-testid": "assistant-api-calls-consent-cancel",
|
|
23
|
-
children:
|
|
24
|
-
}), /* @__PURE__ */
|
|
30
|
+
children: g.cancel
|
|
31
|
+
}), /* @__PURE__ */ s(e, {
|
|
25
32
|
variant: "default",
|
|
26
33
|
onClick: u,
|
|
27
34
|
"data-testid": "assistant-api-calls-consent-confirm",
|
|
28
|
-
children:
|
|
35
|
+
children: g.confirm
|
|
29
36
|
})] }),
|
|
30
|
-
children: /* @__PURE__ */
|
|
37
|
+
children: /* @__PURE__ */ c("div", {
|
|
31
38
|
className: "space-y-2 text-sm text-text-secondary",
|
|
32
|
-
children: [/* @__PURE__ */
|
|
39
|
+
children: [/* @__PURE__ */ s("p", { children: g.body }), /* @__PURE__ */ s("p", { children: g.safeguard })]
|
|
40
|
+
})
|
|
41
|
+
});
|
|
42
|
+
}, d = ({ open: r, onConfirm: i, onCancel: l, plan: u, consentCopy: d }) => {
|
|
43
|
+
let f = n(), p = a(null), m = [];
|
|
44
|
+
u.withdrawnCount > 0 && m.push({
|
|
45
|
+
key: "withdrawn",
|
|
46
|
+
text: f("modeSwitch.withdrawn", "{{count}} change(s) waiting for your approval will be withdrawn.", { count: u.withdrawnCount })
|
|
47
|
+
}), u.movesToNewConversation && m.push({
|
|
48
|
+
key: "newConversation",
|
|
49
|
+
text: f("modeSwitch.newConversation", "{{mode}} continues in a new conversation. This one stays in History.", { mode: u.targetName })
|
|
50
|
+
}), u.draftKept && m.length > 0 && m.push({
|
|
51
|
+
key: "draftKept",
|
|
52
|
+
text: f("modeSwitch.draftKept", "What you typed stays in the message box.")
|
|
53
|
+
});
|
|
54
|
+
let h = u.currentName === void 0 ? d.cancel : f("writeConsent.cancel", "Stay in {{mode}}", { mode: u.currentName });
|
|
55
|
+
return /* @__PURE__ */ s(t, {
|
|
56
|
+
open: r,
|
|
57
|
+
onClose: l,
|
|
58
|
+
size: "sm",
|
|
59
|
+
role: "alertdialog",
|
|
60
|
+
testId: "assistant-mode-switch-dialog",
|
|
61
|
+
onOpenAutoFocus: (e) => {
|
|
62
|
+
e.preventDefault(), p.current?.focus();
|
|
63
|
+
},
|
|
64
|
+
title: u.consent ? d.title : f("modeSwitch.title", "Switch to {{mode}}?", { mode: u.targetName }),
|
|
65
|
+
footer: /* @__PURE__ */ c(o, { children: [/* @__PURE__ */ s(e, {
|
|
66
|
+
ref: p,
|
|
67
|
+
variant: "outline",
|
|
68
|
+
onClick: l,
|
|
69
|
+
"data-testid": "assistant-mode-switch-cancel",
|
|
70
|
+
children: h
|
|
71
|
+
}), /* @__PURE__ */ s(e, {
|
|
72
|
+
variant: "default",
|
|
73
|
+
onClick: i,
|
|
74
|
+
"data-testid": "assistant-mode-switch-confirm",
|
|
75
|
+
children: u.consent ? d.confirm : f("modeSwitch.confirm", "Switch to {{mode}}", { mode: u.targetName })
|
|
76
|
+
})] }),
|
|
77
|
+
children: /* @__PURE__ */ c("div", {
|
|
78
|
+
className: "space-y-2 text-sm text-text-secondary",
|
|
79
|
+
children: [u.consent ? /* @__PURE__ */ c(o, { children: [/* @__PURE__ */ s("p", { children: d.body }), /* @__PURE__ */ s("p", { children: d.safeguard })] }) : null, m.length > 0 ? /* @__PURE__ */ c(o, { children: [/* @__PURE__ */ s("p", { children: f("modeSwitch.intro", "If you switch now:") }), /* @__PURE__ */ s("ul", {
|
|
80
|
+
className: "list-disc space-y-1 pl-5",
|
|
81
|
+
"data-testid": "assistant-mode-switch-lines",
|
|
82
|
+
children: m.map((e) => /* @__PURE__ */ s("li", {
|
|
83
|
+
"data-testid": `assistant-mode-switch-${e.key}`,
|
|
84
|
+
children: e.text
|
|
85
|
+
}, e.key))
|
|
86
|
+
})] }) : null]
|
|
33
87
|
})
|
|
34
88
|
});
|
|
35
89
|
};
|
|
36
90
|
//#endregion
|
|
37
|
-
export {
|
|
91
|
+
export { u as AssistantApiCallsConsentDialog };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { FC } from 'react';
|
|
2
|
+
import { AssistantPresentation } from './composer/AssistantComposer';
|
|
2
3
|
import { WorkspaceWriteAccess } from '../useWorkspaceWriteAccess';
|
|
3
4
|
/**
|
|
4
5
|
* `visible` is false when the host HIDES the panel without unmounting it, which
|
|
@@ -22,5 +23,10 @@ export interface AssistantChatAreaProps {
|
|
|
22
23
|
* false claim in either direction.
|
|
23
24
|
*/
|
|
24
25
|
writeAccess?: WorkspaceWriteAccess;
|
|
26
|
+
/**
|
|
27
|
+
* BOFF-10055: `compact` turns on the compact presentation's composer, Stop,
|
|
28
|
+
* and the mode-switch confirmation. Absent or `classic`: as before.
|
|
29
|
+
*/
|
|
30
|
+
presentation?: AssistantPresentation;
|
|
25
31
|
}
|
|
26
32
|
export declare const AssistantChatArea: FC<AssistantChatAreaProps>;
|