@datalayer/agent-runtimes 1.3.89 → 1.3.91
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/lib/Agent.js +2 -18
- package/lib/AgentDocument.js +5 -55
- package/lib/AgentNode.js +31 -208
- package/lib/AgentNotebook.js +5 -59
- package/lib/agent-node/AgentNodeGallery.js +23 -111
- package/lib/agents/AgentDetails.js +36 -274
- package/lib/agents/AgentRuntimeChat.js +1 -8
- package/lib/chat/Chat.js +7 -46
- package/lib/chat/ChatFloating.js +15 -100
- package/lib/chat/ChatInline.js +5 -47
- package/lib/chat/ChatPopupStandalone.js +5 -53
- package/lib/chat/ChatSidebar.js +4 -51
- package/lib/chat/ChatStandalone.js +4 -45
- package/lib/chat/EphemeralSurfaceControl.js +5 -25
- package/lib/chat/assistant/AssistantContextMenu.d.ts +8 -0
- package/lib/chat/assistant/AssistantContextMenu.js +17 -1
- package/lib/chat/assistant/AssistantStage.js +6 -25
- package/lib/chat/assistant/BalloonParts.js +8 -40
- package/lib/chat/assistant/BalloonVisual.js +2 -2
- package/lib/chat/assistant/ConversationBalloon.js +2 -11
- package/lib/chat/assistant/DecisionAsk.js +3 -3
- package/lib/chat/assistant/SandboxDetailsDialog.js +3 -17
- package/lib/chat/assistant/SpeechBalloon.js +14 -78
- package/lib/chat/base/ChatBase.js +37 -172
- package/lib/chat/display/EmptyState.js +7 -35
- package/lib/chat/display/FloatingBrandButton.js +4 -34
- package/lib/chat/display/PoweredByTag.js +3 -14
- package/lib/chat/document/EphemeralDocument.js +3 -18
- package/lib/chat/header/ChatHeader.js +1 -17
- package/lib/chat/header/ChatHeaderBase.js +2 -24
- package/lib/chat/header/ChatViewModeToggle.js +7 -29
- package/lib/chat/indicators/McpStatusIndicator.js +3 -12
- package/lib/chat/indicators/SandboxStatusIndicator.js +6 -34
- package/lib/chat/indicators/SkillsStatusIndicator.js +3 -12
- package/lib/chat/indicators/TypingDots.js +1 -11
- package/lib/chat/messages/ChatMessageList.js +58 -185
- package/lib/chat/messages/ChatMessages.js +15 -79
- package/lib/chat/messages/FormSubmissionMessage.js +2 -33
- package/lib/chat/messages/NotebookToolSurfaces.js +12 -41
- package/lib/chat/messages/TurnFooter.js +4 -10
- package/lib/chat/notebook/EphemeralNotebook.js +2 -10
- package/lib/chat/parts/ReasoningPart.js +2 -16
- package/lib/chat/parts/TextPart.js +2 -12
- package/lib/chat/parts/ToolPart.js +16 -90
- package/lib/chat/presence/Presence.js +5 -33
- package/lib/chat/prompt/FloatingCard.js +1 -13
- package/lib/chat/prompt/InputPrompt.js +1 -6
- package/lib/chat/prompt/InputPromptBase.js +4 -17
- package/lib/chat/prompt/InputPromptLexical.js +44 -45
- package/lib/chat/prompt/InputPromptText.js +1 -1
- package/lib/chat/prompt/footer/InPromptFooter.js +1 -8
- package/lib/chat/prompt/menus/AgentsMenu.js +1 -1
- package/lib/chat/prompt/menus/InlineAgentsMenu.js +1 -1
- package/lib/chat/prompt/menus/ModelSelector.js +1 -5
- package/lib/chat/prompt/menus/SkillsMenu.js +3 -30
- package/lib/chat/prompt/menus/SuggestionsMenu.js +1 -1
- package/lib/chat/prompt/menus/ToolsMenu.js +4 -48
- package/lib/chat/prompt/plugins/AgentMentionPlugin.js +2 -9
- package/lib/chat/prompt/plugins/CommandPlugin.js +2 -9
- package/lib/chat/prompt/plugins/MentionChip.js +1 -15
- package/lib/chat/prompt/stack.js +1 -19
- package/lib/chat/tools/A2AAgentDialog.js +9 -42
- package/lib/chat/tools/SubagentActivity.js +5 -22
- package/lib/chat/tools/ToolApprovalBanner.js +4 -34
- package/lib/chat/tools/ToolApprovalDialog.js +4 -19
- package/lib/chat/tools/ToolCallDisplay.js +12 -97
- package/lib/chat/usage/ContextPie.js +4 -45
- package/lib/chat/words.d.ts +7 -0
- package/lib/chat/words.js +12 -0
- package/lib/components/a2ui/datalayer/Chart.js +4 -10
- package/lib/components/a2ui/datalayer/Chat.js +2 -10
- package/lib/components/a2ui/datalayer/Download.js +1 -1
- package/lib/components/a2ui/datalayer/Evidence.js +1 -15
- package/lib/components/a2ui/datalayer/FileUpload.js +1 -12
- package/lib/components/a2ui/datalayer/Table.js +9 -17
- package/lib/components/a2ui/datalayer/formWidgets.js +3 -2
- package/lib/components/a2ui/datalayer/parts.js +1 -16
- package/lib/components/a2ui/styles.js +16 -5
- package/lib/components/agents/AgentSummary.js +1 -51
- package/lib/components/cards/NotificationEventCard.js +6 -72
- package/lib/components/cards/OutputCard.js +4 -48
- package/lib/components/cards/ToolApprovalCard.js +2 -35
- package/lib/components/code-sandboxes/CodeSandboxCellVariables.js +1 -1
- package/lib/components/code-sandboxes/CodeSandboxEnvironmentSelect.js +4 -14
- package/lib/components/code-sandboxes/CodeSandboxPicker.js +16 -21
- package/lib/components/code-sandboxes/CodeSandboxVariables.js +2 -2
- package/lib/components/scheduler/ScheduleMenu.js +5 -10
- package/lib/components/specs/SpecPayloadPreview.js +1 -26
- package/lib/components/teams/A2ATeamGraph.d.ts +4 -3
- package/lib/components/teams/A2ATeamGraph.js +25 -71
- package/lib/components/teams/AnswerSurfacesView.js +2 -2
- package/lib/components/teams/NotebookPreview.js +1 -10
- package/lib/components/teams/NotebookPreviewView.js +2 -3
- package/lib/components/teams/SceneTranscript.js +3 -17
- package/lib/components/teams/SceneView.js +1 -8
- package/lib/components/teams/TeamNotebook.js +5 -13
- package/lib/components/teams/TeamNotebookView.js +2 -12
- package/lib/components/teams/index.d.ts +1 -0
- package/lib/components/teams/index.js +1 -0
- package/lib/components/teams/useBalloonRoom.d.ts +39 -0
- package/lib/components/teams/useBalloonRoom.js +89 -0
- package/lib/config/AgentConfiguration.js +22 -225
- package/lib/context/ContextDistribution.js +7 -41
- package/lib/context/ContextInspector.js +9 -107
- package/lib/context/ContextPanel.js +11 -86
- package/lib/context/ContextUsage.js +6 -34
- package/lib/context/CostTracker.js +7 -42
- package/lib/context/MessageHistory.js +3 -37
- package/lib/context/TurnGraphChart.js +9 -41
- package/lib/examples/A2UiAgentExample.js +6 -108
- package/lib/examples/A2UiComponentsGalleryExample.js +1 -1
- package/lib/examples/A2UiContactCardExample.js +1 -1
- package/lib/examples/A2UiJupyterOutputExample.js +25 -125
- package/lib/examples/A2UiRestaurantExample.js +1 -1
- package/lib/examples/A2UiViewerExample.js +1 -1
- package/lib/examples/AgUiAgenticExample.js +3 -35
- package/lib/examples/AgUiBackendToolRenderingExample.js +2 -25
- package/lib/examples/AgUiHaikuGenUiExample.js +2 -32
- package/lib/examples/AgUiHumanInTheLoopExample.js +5 -59
- package/lib/examples/AgUiSharedStateExample.js +6 -56
- package/lib/examples/AgUiToolsBasedGenUiExample.js +25 -120
- package/lib/examples/AgentA2AExample.js +1 -15
- package/lib/examples/AgentA2ATeamExample.js +6 -30
- package/lib/examples/AgentCheckpointsExample.js +11 -145
- package/lib/examples/AgentCodeSandboxExample.js +5 -108
- package/lib/examples/AgentCodeSandboxesExample.js +3 -30
- package/lib/examples/AgentCodemodeExample.js +9 -85
- package/lib/examples/AgentCompactionExample.js +3 -64
- package/lib/examples/AgentDecideExample.js +1 -13
- package/lib/examples/AgentEvalsExample.js +5 -60
- package/lib/examples/AgentGuardrailsExample.js +4 -28
- package/lib/examples/AgentHooksExample.js +1 -1
- package/lib/examples/AgentInferenceProviderExample.js +5 -96
- package/lib/examples/AgentMCPExample.js +7 -105
- package/lib/examples/AgentMemoryExample.js +5 -74
- package/lib/examples/AgentMonitoringExample.js +7 -53
- package/lib/examples/AgentNotificationsExample.js +3 -61
- package/lib/examples/AgentOtelExample.js +3 -72
- package/lib/examples/AgentOutputsExample.js +6 -81
- package/lib/examples/AgentParametersExample.js +2 -37
- package/lib/examples/AgentSkillsExample.js +3 -45
- package/lib/examples/AgentSubagentsExample.js +6 -56
- package/lib/examples/AgentToolApprovalsExample.js +1 -11
- package/lib/examples/AgentTriggersExample.js +29 -239
- package/lib/examples/AgentspecsExample.js +6 -60
- package/lib/examples/AssistantExample.js +5 -5
- package/lib/examples/AssistantGalleryExample.js +8 -65
- package/lib/examples/CellExample.js +1 -6
- package/lib/examples/ChatCustomExample.js +2 -31
- package/lib/examples/ChatExample.js +1 -9
- package/lib/examples/ChatStandaloneExample.js +3 -37
- package/lib/examples/CopilotKitLexicalExample.js +1 -24
- package/lib/examples/DecksAgent.js +1 -1
- package/lib/examples/DocumentPageAgent.js +1 -1
- package/lib/examples/HomeExample.js +14 -62
- package/lib/examples/Lexical2Example.js +3 -32
- package/lib/examples/LexicalAgentExample.js +2 -34
- package/lib/examples/LexicalAgentSidebarExample.js +3 -34
- package/lib/examples/LoopAppComputerExample.js +1 -1
- package/lib/examples/LoopShellExample.js +2 -2
- package/lib/examples/LoopStrategyExample.js +15 -87
- package/lib/examples/LoopWorkspaceEmbed.js +2 -18
- package/lib/examples/LoopWorkspaceExample.js +2 -2
- package/lib/examples/NotebookAgentExample.js +2 -33
- package/lib/examples/NotebookAgentSidebarExample.js +3 -46
- package/lib/examples/NotebookCollaborationExample.js +1 -31
- package/lib/examples/NotebookExample.js +1 -18
- package/lib/examples/NotebookPageAgent.js +1 -1
- package/lib/examples/ScenesExample.js +5 -24
- package/lib/examples/VoiceChatExample.js +1 -1
- package/lib/examples/components/AuthRequiredView.js +1 -7
- package/lib/examples/components/ErrorView.js +1 -8
- package/lib/examples/components/ExampleErrorBoundary.js +1 -14
- package/lib/examples/components/FooterMetrics.js +1 -7
- package/lib/examples/components/Header.js +12 -51
- package/lib/examples/components/HeaderControls.js +1 -9
- package/lib/examples/components/LexicalEditor.js +1 -8
- package/lib/examples/components/MainContent.js +1 -13
- package/lib/examples/components/MockFileBrowser.js +4 -40
- package/lib/examples/components/SessionTabs.js +1 -1
- package/lib/examples/components/TimeTravel.js +1 -13
- package/lib/examples/main.js +13 -81
- package/lib/examples/scenes/A2UiComponentsGalleryScene.js +3 -34
- package/lib/examples/scenes/A2UiContactCardScene.js +3 -35
- package/lib/examples/scenes/A2UiRestaurantScene.js +3 -53
- package/lib/examples/scenes/A2UiViewerScene.js +3 -34
- package/lib/examples/utils/AssistantGalleryGrid.js +6 -35
- package/lib/examples2/DatalayerNotebookExample.js +3 -33
- package/lib/examples2/NativeNavigationExample.js +4 -10
- package/lib/examples2/NotebookMutationsKernel.js +2 -1
- package/lib/examples2/NotebookMutationsServiceManager.js +2 -1
- package/lib/examples2/ReactRouterExample.js +14 -42
- package/lib/hooks/useToolApprovals.d.ts +2 -34
- package/lib/hooks/useToolApprovals.js +1 -64
- package/lib/identity/AgentIdentity.js +17 -62
- package/lib/identity/IdentityConnect.js +13 -59
- package/lib/identity/OAuthCallback.js +6 -44
- package/lib/lexical/ChatInlinePlugin.js +6 -14
- package/lib/loop/apps/AppFeedback.js +12 -3
- package/lib/loop/apps/AppRenderer.d.ts +4 -3
- package/lib/loop/apps/AppRenderer.js +11 -12
- package/lib/loop/apps/appspec.js +6 -3
- package/lib/loop/apps/feedback.d.ts +3 -2
- package/lib/loop/apps/feedback.js +4 -2
- package/lib/loop/core/index.d.ts +19 -0
- package/lib/loop/core/index.js +27 -0
- package/lib/loop/embed/AppEmbed.d.ts +1 -1
- package/lib/loop/embed/AppEmbed.js +2 -1
- package/lib/loop/embed/LoopEmbed.js +1 -7
- package/lib/loop/embed/embedConfig.d.ts +3 -3
- package/lib/loop/embed/embedConfig.js +2 -3
- package/lib/loop/embed/embedTheme.d.ts +4 -4
- package/lib/loop/embed/embedTheme.js +11 -7
- package/lib/loop/plugins/a2a-sidebar/A2ASidebar.js +7 -34
- package/lib/loop/plugins/a2ui/A2uiView.js +4 -12
- package/lib/loop/plugins/a2ui-surface/InlineSurface.js +1 -16
- package/lib/loop/plugins/a2ui-surface/SurfaceToolResult.js +2 -12
- package/lib/loop/plugins/agents/AnonymousKeyBadge.js +3 -2
- package/lib/loop/plugins/agents/SandboxSelector.js +3 -7
- package/lib/loop/plugins/agents/SandboxView.js +4 -27
- package/lib/loop/plugins/agents/TeamMemberPicker.js +2 -2
- package/lib/loop/plugins/agentspecs/AgentspecPicker.js +3 -2
- package/lib/loop/plugins/app-activity/AppActivity.js +1 -1
- package/lib/loop/plugins/app-computer/AppComputer.js +32 -27
- package/lib/loop/plugins/app-elements/AppElements.js +2 -31
- package/lib/loop/plugins/app-page/AppPage.js +26 -8
- package/lib/loop/plugins/app-rules/AppRulesCard.js +4 -20
- package/lib/loop/plugins/assistant/index.js +1 -13
- package/lib/loop/plugins/chat/ChatView.js +89 -130
- package/lib/loop/plugins/checkpoints-sidebar/CheckpointsSidebar.js +2 -13
- package/lib/loop/plugins/decks/DeckSurface.js +2 -2
- package/lib/loop/plugins/document/DocumentView.js +4 -12
- package/lib/loop/plugins/document-toolbar/SandboxStatusItem.js +3 -8
- package/lib/loop/plugins/graph/GraphView.js +2 -2
- package/lib/loop/plugins/input-prompt/ComposerView.js +1 -1
- package/lib/loop/plugins/notebook/NotebookView.js +3 -11
- package/lib/loop/plugins/page-layout/SplitLayout.js +11 -34
- package/lib/loop/plugins/page-layout/TurnPanel.js +9 -35
- package/lib/loop/plugins/shell/useEditorPreviews.js +3 -2
- package/lib/loop/plugins/subagent-activity/SubagentPulse.js +1 -13
- package/lib/loop/plugins/window-frame/WindowFrame.js +10 -44
- package/lib/loop/plugins/window-frame/index.js +1 -1
- package/lib/loop/shell/LoopWorkspace.js +34 -77
- package/lib/loop/shell/PluginToggles.js +4 -15
- package/lib/loop/shell/SidebarRail.js +8 -40
- package/lib/loop/shell/ViewSwitcher.js +4 -24
- package/lib/loop-main.js +2 -3
- package/lib/mcp/McpServerManager.js +6 -37
- package/lib/portable/index.d.ts +11 -0
- package/lib/portable/index.js +20 -0
- package/lib/protocols/AGUIAdapter.js +2 -2
- package/lib/protocols/BaseProtocolAdapter.d.ts +2 -0
- package/lib/protocols/BaseProtocolAdapter.js +4 -0
- package/lib/specs/apps.js +6 -0
- package/lib/specs/appspecSchema.js +11 -4
- package/lib/stories/loop/ReferenceScreens.js +17 -91
- package/lib/stories/loop/pictures-main.js +1 -1
- package/lib/types/agentspecs.d.ts +5 -2
- package/lib/types/protocol.d.ts +2 -0
- package/lib/utils/approvals.d.ts +59 -0
- package/lib/utils/approvals.js +101 -0
- package/lib/voice/VoiceInput.js +3 -39
- package/package.json +2 -2
- package/lib/shims/primerAddonsBox.d.ts +0 -1
- package/lib/shims/primerAddonsBox.js +0 -7
|
@@ -15,6 +15,14 @@
|
|
|
15
15
|
*/
|
|
16
16
|
import type { JSX, RefObject } from 'react';
|
|
17
17
|
import type { Icon } from '@primer/octicons-react';
|
|
18
|
+
/** The longest a description is drawn in the menu, in characters. */
|
|
19
|
+
export declare const MENU_DESCRIPTION_MAX = 60;
|
|
20
|
+
/**
|
|
21
|
+
* A description short enough for one line of the menu: whole words up to
|
|
22
|
+
* {@link MENU_DESCRIPTION_MAX} characters, then an ellipsis. The full text
|
|
23
|
+
* stays in its tooltip.
|
|
24
|
+
*/
|
|
25
|
+
export declare function shortDescription(text: string): string;
|
|
18
26
|
/** One entry of the assistant's menu. */
|
|
19
27
|
export type AssistantMenuItem = {
|
|
20
28
|
/** Stable id: `inspect`, `stop`, a plugin's own. */
|
|
@@ -2,6 +2,22 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
2
2
|
import { useEffect, useRef } from 'react';
|
|
3
3
|
import { createPortal } from 'react-dom';
|
|
4
4
|
import { ActionList, ActionMenu } from '@primer/react';
|
|
5
|
+
/** The longest a description is drawn in the menu, in characters. */
|
|
6
|
+
export const MENU_DESCRIPTION_MAX = 60;
|
|
7
|
+
/**
|
|
8
|
+
* A description short enough for one line of the menu: whole words up to
|
|
9
|
+
* {@link MENU_DESCRIPTION_MAX} characters, then an ellipsis. The full text
|
|
10
|
+
* stays in its tooltip.
|
|
11
|
+
*/
|
|
12
|
+
export function shortDescription(text) {
|
|
13
|
+
const flat = text.replace(/\s+/g, ' ').trim();
|
|
14
|
+
if (flat.length <= MENU_DESCRIPTION_MAX) {
|
|
15
|
+
return flat;
|
|
16
|
+
}
|
|
17
|
+
const cut = flat.slice(0, MENU_DESCRIPTION_MAX);
|
|
18
|
+
const space = cut.lastIndexOf(' ');
|
|
19
|
+
return `${(space > MENU_DESCRIPTION_MAX / 2 ? cut.slice(0, space) : cut).replace(/[\s,.;:!?—-]+$/, '')}…`;
|
|
20
|
+
}
|
|
5
21
|
/** The entries by group, in the order their first entry came. */
|
|
6
22
|
export function menuGroups(items) {
|
|
7
23
|
const groups = [];
|
|
@@ -61,7 +77,7 @@ export function AssistantContextMenu({ at, items, onClose, returnFocusRef, label
|
|
|
61
77
|
item.onSelect();
|
|
62
78
|
onClose();
|
|
63
79
|
requestAnimationFrame(() => returnFocusRef?.current?.focus());
|
|
64
|
-
}, children: [item.icon && (_jsx(ActionList.LeadingVisual, { children: _jsx(item.icon, {}) })), item.label, item.description && (_jsx(ActionList.Description, { variant: "block", children: item.description }))] }, item.id)));
|
|
80
|
+
}, children: [item.icon && (_jsx(ActionList.LeadingVisual, { children: _jsx(item.icon, {}) })), item.label, item.description && (_jsx(ActionList.Description, { variant: "block", children: _jsx("span", { title: item.description, children: shortDescription(item.description) }) }))] }, item.id)));
|
|
65
81
|
return (_jsxs(ActionList.Group, { ...(choice ? { selectionVariant: 'single' } : {}), children: [group && (_jsx(ActionList.GroupHeading, { children: group })), list] }, group ?? `ungrouped-${index}`));
|
|
66
82
|
}) }) }) })] }));
|
|
67
83
|
}
|
|
@@ -617,31 +617,12 @@ export function AssistantStage({ character, state, size = 88, place, stageRef, o
|
|
|
617
617
|
return;
|
|
618
618
|
}
|
|
619
619
|
(onCharacterClick ?? onToggle)();
|
|
620
|
-
},
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
bg: 'transparent',
|
|
627
|
-
cursor: 'grab',
|
|
628
|
-
touchAction: 'none',
|
|
629
|
-
filter: 'drop-shadow(0 6px 10px rgba(0, 0, 0, 0.18))',
|
|
630
|
-
'&:active': { cursor: 'grabbing' },
|
|
631
|
-
'&:focus-visible': {
|
|
632
|
-
outline: '2px solid',
|
|
633
|
-
outlineColor: 'var(--focus-outlineColor, var(--fgColor-accent))',
|
|
634
|
-
outlineOffset: 2,
|
|
635
|
-
borderRadius: '50%',
|
|
636
|
-
},
|
|
637
|
-
}, children: [described && (_jsx(Box, { as: "span", id: describedBy, sx: {
|
|
638
|
-
position: 'absolute',
|
|
639
|
-
width: 1,
|
|
640
|
-
height: 1,
|
|
641
|
-
overflow: 'hidden',
|
|
642
|
-
clip: 'rect(0 0 0 0)',
|
|
643
|
-
whiteSpace: 'nowrap',
|
|
644
|
-
}, children: `Its character: ${characterName}` })), shipped ? (_jsx(shipped.Drawing, { size: size, mode: colorMode })) : (_jsx(SpriteCharacter, { character: character, state: state, size: size, sounds: soundsOn, mouthLevel: mouthLevel }))] }), (hovered || menuOpen) && !aside && state !== 'goodbye' && (_jsx(Box, { sx: { position: 'absolute', top: '-6px', right: '-6px' }, children: _jsxs(ActionMenu, { open: menuOpen, onOpenChange: setMenuOpen, children: [_jsx(ActionMenu.Anchor, { children: _jsx(IconButton, { icon: XIcon, "aria-label": `Send ${name} away`, size: "small", variant: "invisible", "data-assistant-dismiss": "", sx: {
|
|
620
|
+
}, display: "block", width: size, height: size, p: 0, border: 0, bg: "transparent", cursor: "grab", filter: "drop-shadow(0 6px 10px rgba(0, 0, 0, 0.18))", active: { cursor: 'grabbing' }, focusVisible: {
|
|
621
|
+
outline: '2px solid',
|
|
622
|
+
outlineColor: 'var(--focus-outlineColor, var(--fgColor-accent))',
|
|
623
|
+
outlineOffset: 2,
|
|
624
|
+
borderRadius: '50%',
|
|
625
|
+
}, touchAction: "none", children: [described && (_jsx(Box, { as: "span", id: describedBy, position: "absolute", width: 1, height: 1, overflow: "hidden", clip: "rect(0 0 0 0)", whiteSpace: "nowrap", children: `Its character: ${characterName}` })), shipped ? (_jsx(shipped.Drawing, { size: size, mode: colorMode })) : (_jsx(SpriteCharacter, { character: character, state: state, size: size, sounds: soundsOn, mouthLevel: mouthLevel }))] }), (hovered || menuOpen) && !aside && state !== 'goodbye' && (_jsx(Box, { position: "absolute", top: "-6px", right: "-6px", children: _jsxs(ActionMenu, { open: menuOpen, onOpenChange: setMenuOpen, children: [_jsx(ActionMenu.Anchor, { children: _jsx(IconButton, { icon: XIcon, "aria-label": `Send ${name} away`, size: "small", variant: "invisible", "data-assistant-dismiss": "", sx: {
|
|
645
626
|
bg: 'canvas.default',
|
|
646
627
|
borderRadius: '50%',
|
|
647
628
|
boxShadow: 'shadow.small',
|
|
@@ -51,7 +51,7 @@ async function respondInBalloon(_toolCallId, result) {
|
|
|
51
51
|
*/
|
|
52
52
|
export function BalloonChatItems({ items, density = 'compact', waiting = false, }) {
|
|
53
53
|
const end = useRef(null);
|
|
54
|
-
return (_jsx(Box, { "data-balloon-chat-items": "",
|
|
54
|
+
return (_jsx(Box, { "data-balloon-chat-items": "", minWidth: 0, children: _jsx(ChatMessageList, { displayItems: items, isLoading: waiting, isStreaming: false, showLoadingIndicator: waiting, hideMessagesAfterToolUI: false, avatarConfig: BALLOON_AVATARS, padding: 0, onRespond: respondInBalloon, messagesEndRef: end, emptyContent: waiting ? _jsx(TypingDots, { size: 6 }) : null, density: density }) }));
|
|
55
55
|
}
|
|
56
56
|
/**
|
|
57
57
|
* The tool being called, in the balloon: the chat's tool call card, compact,
|
|
@@ -59,7 +59,7 @@ export function BalloonChatItems({ items, density = 'compact', waiting = false,
|
|
|
59
59
|
* Seen, not read out: {@link ToolLineAnnouncer} says it once per change.
|
|
60
60
|
*/
|
|
61
61
|
export function BalloonToolCall({ line, waiting = false, }) {
|
|
62
|
-
return (_jsx(Box, { "aria-hidden": "true", "data-balloon-tool": line.phase, "data-balloon-tool-name": line.tool || undefined,
|
|
62
|
+
return (_jsx(Box, { "aria-hidden": "true", "data-balloon-tool": line.phase, "data-balloon-tool-name": line.tool || undefined, minWidth: 0, width: "100%", children: _jsx(BalloonChatItems, { items: [displayItemOfLine(line)], waiting: waiting }) }));
|
|
63
63
|
}
|
|
64
64
|
/**
|
|
65
65
|
* What a screen reader hears of the tool lines, politely: once when a call
|
|
@@ -76,7 +76,7 @@ export function ToolLineAnnouncer({ line, }) {
|
|
|
76
76
|
setSaid(words);
|
|
77
77
|
}
|
|
78
78
|
}, [line?.id, line?.phase]);
|
|
79
|
-
return (_jsx(Box, { as: "span", role: "status", "aria-live": "polite", "data-balloon-announce": "",
|
|
79
|
+
return (_jsx(Box, { as: "span", role: "status", "aria-live": "polite", "data-balloon-announce": "", ...VISUALLY_HIDDEN, children: said }));
|
|
80
80
|
}
|
|
81
81
|
/**
|
|
82
82
|
* The `current` balloon's mark: *Now*, with a dot that breathes while the
|
|
@@ -84,15 +84,7 @@ export function ToolLineAnnouncer({ line, }) {
|
|
|
84
84
|
*/
|
|
85
85
|
export function BalloonNow({ busy = false }) {
|
|
86
86
|
const chatText = useChatWords();
|
|
87
|
-
return (_jsxs(Box, { as: "span", "data-balloon-now": busy ? 'busy' : '', sx: {
|
|
88
|
-
display: 'inline-flex',
|
|
89
|
-
alignItems: 'center',
|
|
90
|
-
gap: '6px',
|
|
91
|
-
fontSize: 0,
|
|
92
|
-
fontWeight: 'semibold',
|
|
93
|
-
color: 'accent.fg',
|
|
94
|
-
textTransform: 'uppercase',
|
|
95
|
-
letterSpacing: '0.04em',
|
|
87
|
+
return (_jsxs(Box, { as: "span", "data-balloon-now": busy ? 'busy' : '', display: "inline-flex", alignItems: "center", gap: "6px", fontSize: 0, fontWeight: "semibold", color: "accent.fg", textTransform: "uppercase", letterSpacing: "0.04em", sx: {
|
|
96
88
|
'@keyframes balloonNowBreathe': {
|
|
97
89
|
'0%, 100%': { opacity: 1, transform: 'scale(1)' },
|
|
98
90
|
'50%': { opacity: 0.35, transform: 'scale(0.7)' },
|
|
@@ -123,21 +115,9 @@ export function conversationHeaderText(count, chatText = ENGLISH_CHAT_WORDS) {
|
|
|
123
115
|
*/
|
|
124
116
|
export function ConversationBalloonHeader({ count, }) {
|
|
125
117
|
const chatText = useChatWords();
|
|
126
|
-
return (_jsx(Box, { "data-balloon-header": "",
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
alignItems: 'center',
|
|
130
|
-
gap: 2,
|
|
131
|
-
// Room for the close control over the corner.
|
|
132
|
-
pl: 3,
|
|
133
|
-
pr: 6,
|
|
134
|
-
py: 2,
|
|
135
|
-
borderBottom: '1px solid',
|
|
136
|
-
borderColor: 'border.muted',
|
|
137
|
-
bg: 'canvas.default',
|
|
138
|
-
borderTopLeftRadius: 'var(--theme-radius-bubble, 16px)',
|
|
139
|
-
borderTopRightRadius: 'var(--theme-radius-bubble, 16px)',
|
|
140
|
-
}, children: _jsx(Text, { sx: { fontSize: 0, fontWeight: 'semibold', color: 'fg.muted' }, children: conversationHeaderText(count, chatText) }) }));
|
|
118
|
+
return (_jsx(Box, { "data-balloon-header": "", flexShrink: 0, display: "flex", alignItems: "center", gap: 2,
|
|
119
|
+
// Room for the close control over the corner.
|
|
120
|
+
pl: 3, pr: 6, py: 2, borderBottom: "1px solid", borderColor: "border.muted", bg: "canvas.default", borderTopLeftRadius: "var(--theme-radius-bubble, 16px)", borderTopRightRadius: "var(--theme-radius-bubble, 16px)", children: _jsx(Text, { sx: { fontSize: 0, fontWeight: 'semibold', color: 'fg.muted' }, children: conversationHeaderText(count, chatText) }) }));
|
|
141
121
|
}
|
|
142
122
|
/**
|
|
143
123
|
* What the `current` balloon holds: *Now*, then the one thing being said or
|
|
@@ -153,17 +133,5 @@ export function CurrentBalloonBody({ text, tool, busy = false, speaking = false,
|
|
|
153
133
|
}
|
|
154
134
|
onOverflow(element.scrollHeight > element.clientHeight + 1);
|
|
155
135
|
}, [text, whole, onOverflow]);
|
|
156
|
-
return (_jsxs(Box, { "data-balloon-current": "",
|
|
157
|
-
? {
|
|
158
|
-
maxHeight: 240,
|
|
159
|
-
overflowY: 'auto',
|
|
160
|
-
overflowWrap: 'anywhere',
|
|
161
|
-
pr: 1,
|
|
162
|
-
}
|
|
163
|
-
: {
|
|
164
|
-
// About four lines; *more* shows the rest.
|
|
165
|
-
maxHeight: '5.6em',
|
|
166
|
-
overflow: 'hidden',
|
|
167
|
-
overflowWrap: 'anywhere',
|
|
168
|
-
}, children: [_jsx(ChatMarkdown, { density: "compact", text: whole ? (fullText ?? text) : text }), waiting && (_jsx(Box, { as: "span", sx: { ml: 2, display: 'inline-flex' }, children: _jsx(TypingDots, { size: 5 }) }))] })) : waiting ? (_jsx(TypingDots, { size: 6 })) : null, attachment, _jsx(ToolLineAnnouncer, { line: tool })] }));
|
|
136
|
+
return (_jsxs(Box, { "data-balloon-current": "", display: "flex", flexDirection: "column", gap: 1, minWidth: 0, children: [_jsx(BalloonNow, { busy: busy }), tool ? (_jsx(BalloonToolCall, { line: tool, waiting: waiting })) : text ? (_jsxs(Box, { "aria-live": "polite", "aria-busy": speaking, ref: textRef, "data-balloon-current-text": whole ? 'whole' : '', maxHeight: whole ? 240 : '5.6em', overflowY: whole ? 'auto' : undefined, overflowWrap: whole ? 'anywhere' : 'anywhere', pr: whole ? 1 : undefined, overflow: whole ? undefined : 'hidden', children: [_jsx(ChatMarkdown, { density: "compact", text: whole ? (fullText ?? text) : text }), waiting && (_jsx(Box, { as: "span", ml: 2, display: "inline-flex", children: _jsx(TypingDots, { size: 5 }) }))] })) : waiting ? (_jsx(TypingDots, { size: 6 })) : null, attachment, _jsx(ToolLineAnnouncer, { line: tool })] }));
|
|
169
137
|
}
|
|
@@ -31,7 +31,7 @@ export function ExpandedVisual({ visual, target, onClose, }) {
|
|
|
31
31
|
if (!element) {
|
|
32
32
|
return null;
|
|
33
33
|
}
|
|
34
|
-
return createPortal(_jsxs(Box, { "data-balloon-expanded": "target", "data-balloon-visual": visual.id,
|
|
34
|
+
return createPortal(_jsxs(Box, { "data-balloon-expanded": "target", "data-balloon-visual": visual.id, position: "relative", minWidth: 0, children: [_jsx(Box, { position: "absolute", top: 0, right: 0, zIndex: 1, children: _jsx(IconButton, { icon: visual.shrink ? ScreenNormalIcon : XIcon, size: "small", variant: "invisible", "aria-label": `${visual.shrink ? 'Shrink' : 'Close'} ${visual.title}`, "data-balloon-expanded-close": "", ...(visual.shrink ? { 'data-balloon-shrink': '' } : {}), onClick: onClose }) }), visual.render('target')] }), element);
|
|
35
35
|
}
|
|
36
36
|
// The dialog's × (and Esc) is what shrinks it back: no Shrink of its own.
|
|
37
37
|
return (_jsx(Dialog, { title: visual.title, onClose: onClose, sx: {
|
|
@@ -39,7 +39,7 @@ export function ExpandedVisual({ visual, target, onClose, }) {
|
|
|
39
39
|
maxWidth: EXPANDED_DIALOG_SIZE.width,
|
|
40
40
|
height: EXPANDED_DIALOG_SIZE.height,
|
|
41
41
|
maxHeight: EXPANDED_DIALOG_SIZE.height,
|
|
42
|
-
}, children: _jsx(Box, { "data-balloon-expanded": "overlay", "data-balloon-visual": visual.id,
|
|
42
|
+
}, children: _jsx(Box, { "data-balloon-expanded": "overlay", "data-balloon-visual": visual.id, minWidth: 0, children: visual.render('overlay') }) }));
|
|
43
43
|
}
|
|
44
44
|
/**
|
|
45
45
|
* Brings an expanded visual into view in its target: scrolled to, and the
|
|
@@ -61,7 +61,7 @@ export function conversationBalloonSx(tail, tailBg = 'canvas.default') {
|
|
|
61
61
|
}
|
|
62
62
|
/** The open balloon's close control, over its top right corner. */
|
|
63
63
|
export function ConversationBalloonClose({ name, onClose, }) {
|
|
64
|
-
return (_jsx(Box, { "data-conversation-balloon-close": "",
|
|
64
|
+
return (_jsx(Box, { "data-conversation-balloon-close": "", position: "absolute", top: "6px", right: "6px", zIndex: 30, children: _jsx(IconButton, { icon: XIcon, size: "small", variant: "invisible", "aria-label": name
|
|
65
65
|
? `Close the conversation with ${name}`
|
|
66
66
|
: 'Close the conversation', onClick: onClose, sx: { bg: 'canvas.default', borderRadius: '50%' } }) }));
|
|
67
67
|
}
|
|
@@ -76,16 +76,7 @@ export function BalloonApprovalMessage({ approval, }) {
|
|
|
76
76
|
useEffect(() => {
|
|
77
77
|
ref.current?.scrollIntoView?.({ block: 'nearest' });
|
|
78
78
|
}, [approval.id]);
|
|
79
|
-
return (_jsx(Box, { ref: ref, "data-balloon-approval": approval.id,
|
|
80
|
-
maxWidth: '90%',
|
|
81
|
-
px: 3,
|
|
82
|
-
py: 2,
|
|
83
|
-
bg: 'attention.subtle',
|
|
84
|
-
border: '1px solid',
|
|
85
|
-
borderColor: 'attention.muted',
|
|
86
|
-
borderRadius: 'var(--theme-radius-bubble, 16px)',
|
|
87
|
-
fontSize: 1,
|
|
88
|
-
}, children: [_jsx(Text, { as: "p", sx: { m: 0, color: 'fg.muted', fontSize: 0 }, children: chatText.waitingForYou }), _jsx(Text, { as: "p", sx: { m: 0, fontWeight: 'semibold' }, children: approval.asks }), approval.why ? (_jsx(Text, { as: "p", sx: { m: 0, color: 'fg.muted', fontSize: 0 }, children: approval.why })) : null, _jsxs(Box, { sx: { display: 'flex', gap: 2, mt: 2, alignItems: 'center' }, children: [_jsx(Button, { size: "small", variant: "primary", disabled: approval.deciding, onClick: approval.onApprove, children: chatText.approve }), _jsx(Button, { size: "small", disabled: approval.deciding, onClick: approval.onDeny, children: chatText.deny }), approval.others > 0 ? (_jsx(Text, { sx: { color: 'fg.muted', fontSize: 0 }, children: chatText.moreWaiting(approval.others) })) : null] })] }) }));
|
|
79
|
+
return (_jsx(Box, { ref: ref, "data-balloon-approval": approval.id, px: 3, py: 2, display: "flex", children: _jsxs(Box, { maxWidth: "90%", px: 3, py: 2, bg: "attention.subtle", border: "1px solid", borderColor: "attention.muted", borderRadius: "var(--theme-radius-bubble, 16px)", fontSize: 1, children: [_jsx(Text, { as: "p", sx: { m: 0, color: 'fg.muted', fontSize: 0 }, children: chatText.waitingForYou }), _jsx(Text, { as: "p", sx: { m: 0, fontWeight: 'semibold' }, children: approval.asks }), approval.why ? (_jsx(Text, { as: "p", sx: { m: 0, color: 'fg.muted', fontSize: 0 }, children: approval.why })) : null, _jsxs(Box, { display: "flex", gap: 2, mt: 2, alignItems: "center", children: [_jsx(Button, { size: "small", variant: "primary", disabled: approval.deciding, onClick: approval.onApprove, children: chatText.approve }), _jsx(Button, { size: "small", disabled: approval.deciding, onClick: approval.onDeny, children: chatText.deny }), approval.others > 0 ? (_jsx(Text, { sx: { color: 'fg.muted', fontSize: 0 }, children: chatText.moreWaiting(approval.others) })) : null] })] }) }));
|
|
89
80
|
}
|
|
90
81
|
/** How many more wait, in two words: "2 more". */
|
|
91
82
|
export function moreWaiting(others) {
|
|
@@ -53,10 +53,10 @@ export function DecisionAsk({ ask, onActiveChange, }) {
|
|
|
53
53
|
show(false);
|
|
54
54
|
};
|
|
55
55
|
if (!open) {
|
|
56
|
-
return (_jsx(Box, { as: "button", type: "button", "data-balloon-ask-decision": "", onClick: () => show(true),
|
|
56
|
+
return (_jsx(Box, { as: "button", type: "button", "data-balloon-ask-decision": "", onClick: () => show(true), ...LINK_SX, display: "block", children: DECISION_WORDS.ask }));
|
|
57
57
|
}
|
|
58
58
|
if (answer !== undefined) {
|
|
59
|
-
return (_jsxs(Box, { "data-balloon-decision": "answered",
|
|
59
|
+
return (_jsxs(Box, { "data-balloon-decision": "answered", mt: 2, children: [_jsx(Text, { as: "p", "data-decision-answer": "", sx: { m: 0, fontWeight: 'semibold' }, children: answer }), _jsxs(Box, { display: "flex", gap: 2, mt: 2, children: [_jsx(Button, { size: "small", onClick: () => setAnswer(undefined), children: DECISION_WORDS.again }), _jsx(Button, { size: "small", variant: "invisible", onClick: close, children: DECISION_WORDS.cancel })] })] }));
|
|
60
60
|
}
|
|
61
61
|
const submit = async () => {
|
|
62
62
|
const asked = {
|
|
@@ -91,6 +91,6 @@ export function DecisionAsk({ ask, onActiveChange, }) {
|
|
|
91
91
|
if (event.key === 'Escape') {
|
|
92
92
|
close();
|
|
93
93
|
}
|
|
94
|
-
},
|
|
94
|
+
}, mt: 2, display: "flex", flexDirection: "column", gap: 2, children: [_jsxs(FormControl, { children: [_jsx(FormControl.Label, { children: "Situation" }), _jsx(Textarea, { block: true, rows: 3, resize: "vertical", name: "situation", placeholder: "Help! My payouts have been failing for 3 days.", value: situation, onChange: event => setSituation(event.target.value) })] }), _jsxs(FormControl, { children: [_jsx(FormControl.Label, { children: "Question" }), _jsx(TextInput, { block: true, size: "small", name: "question", placeholder: "Is it urgent?", value: question, onChange: event => setQuestion(event.target.value) })] }), _jsxs(Box, { display: "flex", gap: 2, children: [_jsxs(FormControl, { sx: { flex: 1 }, children: [_jsx(FormControl.Label, { children: "Type" }), _jsx(Select, { block: true, size: "small", name: "type", value: type, onChange: event => setType(event.target.value), children: Object.keys(DECISION_WORDS.types).map(option => (_jsx(Select.Option, { value: option, children: DECISION_WORDS.types[option] }, option))) })] }), _jsxs(FormControl, { sx: { flex: 1 }, children: [_jsx(FormControl.Label, { children: "Name" }), _jsx(TextInput, { block: true, size: "small", name: "name", placeholder: "Answer", value: name, onChange: event => setName(event.target.value) })] })] }), type === 'choice' && (_jsxs(FormControl, { children: [_jsx(FormControl.Label, { children: "Options, one per line" }), _jsx(Textarea, { block: true, rows: 3, resize: "vertical", name: "options", placeholder: 'Billing\nTech\nSales', value: options, onChange: event => setOptions(event.target.value) })] })), type === 'score' && (_jsxs(Box, { display: "flex", gap: 2, children: [_jsxs(FormControl, { sx: { flex: 1 }, children: [_jsx(FormControl.Label, { children: "From" }), _jsx(TextInput, { block: true, size: "small", type: "number", name: "from", value: from, onChange: event => setFrom(event.target.value) })] }), _jsxs(FormControl, { sx: { flex: 1 }, children: [_jsx(FormControl.Label, { children: "To" }), _jsx(TextInput, { block: true, size: "small", type: "number", name: "to", value: to, onChange: event => setTo(event.target.value) })] })] })), problem ? (_jsx(Text, { as: "p", role: "alert", sx: { m: 0, color: 'danger.fg', fontSize: 0 }, children: problem })) : null, _jsxs(Box, { display: "flex", gap: 2, children: [_jsx(Button, { size: "small", variant: "primary", type: "submit", disabled: asking, children: asking ? DECISION_WORDS.asking : DECISION_WORDS.submit }), _jsx(Button, { size: "small", type: "button", onClick: close, disabled: asking, children: DECISION_WORDS.cancel })] })] }));
|
|
95
95
|
}
|
|
96
96
|
export default DecisionAsk;
|
|
@@ -20,7 +20,7 @@ function StatusLabel({ status }) {
|
|
|
20
20
|
/** A URL, linked, with a copy button. */
|
|
21
21
|
function UrlValue({ url }) {
|
|
22
22
|
const [copied, setCopied] = useState(false);
|
|
23
|
-
return (_jsxs(Box, {
|
|
23
|
+
return (_jsxs(Box, { display: "flex", alignItems: "center", gap: 1, minWidth: 0, children: [_jsx(Link, { href: url, target: "_blank", rel: "noreferrer", sx: { fontFamily: 'mono', fontSize: 0, wordBreak: 'break-all' }, children: url }), _jsx(IconButton, { icon: copied ? CheckIcon : CopyIcon, "aria-label": "Copy the URL", size: "small", variant: "invisible", onClick: () => {
|
|
24
24
|
void navigator.clipboard?.writeText(url).then(() => {
|
|
25
25
|
setCopied(true);
|
|
26
26
|
setTimeout(() => setCopied(false), 1500);
|
|
@@ -193,22 +193,8 @@ export function SandboxDetailsDialog({ sandbox, name, onClose, }) {
|
|
|
193
193
|
add('Packages', pyodide && pyodide.packages.length > 0 ? (_jsxs(Box, { children: [_jsx(Button, { size: "small", variant: "invisible", onClick: () => setShowPackages(!showPackages), "aria-expanded": showPackages, sx: { px: 1 }, children: `${pyodide.packages.length} loaded` }), showPackages && (_jsx(Text, { as: "p", sx: { m: 0, mt: 1, fontFamily: 'mono', fontSize: 0 }, "data-sandbox-packages": "", children: pyodide.packages.join(', ') }))] })) : undefined);
|
|
194
194
|
add('Started', moment(sandbox.startedAt));
|
|
195
195
|
add('Last activity', moment(sandbox.lastActivity ?? kernel.lastActivity));
|
|
196
|
-
return (_jsx(Dialog, { title: `${name} · Code Sandbox`, onClose: onClose, width: "xlarge", height: "large", children: _jsxs(Box, { "data-assistant-sandbox-details": "",
|
|
197
|
-
p: 3,
|
|
198
|
-
bg: 'canvas.subtle',
|
|
199
|
-
border: '1px solid',
|
|
200
|
-
borderColor: 'border.default',
|
|
201
|
-
borderRadius: 2,
|
|
202
|
-
}, children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2, mb: 2 }, children: [_jsxs(Text, { sx: { fontWeight: 'semibold' }, "data-sandbox-kind": sandbox.kind, children: [SANDBOX_KIND_LABELS[sandbox.kind], sandbox.kind === 'runtime' && sandbox.variant
|
|
196
|
+
return (_jsx(Dialog, { title: `${name} · Code Sandbox`, onClose: onClose, width: "xlarge", height: "large", children: _jsxs(Box, { "data-assistant-sandbox-details": "", display: "flex", flexDirection: "column", gap: 3, children: [_jsxs(Box, { "data-sandbox-summary": "", p: 3, bg: "canvas.subtle", border: "1px solid", borderColor: "border.default", borderRadius: 2, children: [_jsxs(Box, { display: "flex", alignItems: "center", gap: 2, mb: 2, children: [_jsxs(Text, { sx: { fontWeight: 'semibold' }, "data-sandbox-kind": sandbox.kind, children: [SANDBOX_KIND_LABELS[sandbox.kind], sandbox.kind === 'runtime' && sandbox.variant
|
|
203
197
|
? ` (${sandbox.variant})`
|
|
204
|
-
: ''] }), sandbox.status && _jsx(StatusLabel, { status: sandbox.status })] }), _jsx(Box, { as: "dl", sx: {
|
|
205
|
-
display: 'grid',
|
|
206
|
-
gridTemplateColumns: 'max-content minmax(0, 1fr)',
|
|
207
|
-
columnGap: 3,
|
|
208
|
-
rowGap: 1,
|
|
209
|
-
m: 0,
|
|
210
|
-
fontSize: 1,
|
|
211
|
-
alignItems: 'center',
|
|
212
|
-
}, children: facts.map(([key, value]) => (_jsxs(Box, { sx: { display: 'contents' }, children: [_jsx(Box, { as: "dt", sx: { color: 'fg.muted' }, children: key }), _jsx(Box, { as: "dd", sx: { m: 0, minWidth: 0 }, "data-sandbox-fact": key, children: value })] }, key))) })] }), _jsxs(Box, { children: [_jsx(Heading, { as: "h3", sx: { fontSize: 2, mb: 2 }, children: "Variables" }), sandboxIsLive(sandbox) ? (_jsx(KernelVariables, { connection: connection, execute: execute, maxHeight: "calc(80vh - 360px)" })) : (_jsx(Text, { as: "p", sx: { color: 'fg.muted', fontSize: 1, m: 0 }, "data-sandbox-not-running": "", children: NO_SANDBOX_YET }))] })] }) }));
|
|
198
|
+
: ''] }), sandbox.status && _jsx(StatusLabel, { status: sandbox.status })] }), _jsx(Box, { as: "dl", display: "grid", gridTemplateColumns: "max-content minmax(0, 1fr)", columnGap: 3, rowGap: 1, m: 0, fontSize: 1, alignItems: "center", children: facts.map(([key, value]) => (_jsxs(Box, { display: "contents", children: [_jsx(Box, { as: "dt", color: "fg.muted", children: key }), _jsx(Box, { as: "dd", m: 0, minWidth: 0, "data-sandbox-fact": key, children: value })] }, key))) })] }), _jsxs(Box, { children: [_jsx(Heading, { as: "h3", sx: { fontSize: 2, mb: 2 }, children: "Variables" }), sandboxIsLive(sandbox) ? (_jsx(KernelVariables, { connection: connection, execute: execute, maxHeight: "calc(80vh - 360px)" })) : (_jsx(Text, { as: "p", sx: { color: 'fg.muted', fontSize: 1, m: 0 }, "data-sandbox-not-running": "", children: NO_SANDBOX_YET }))] })] }) }));
|
|
213
199
|
}
|
|
214
200
|
export default SandboxDetailsDialog;
|
|
@@ -12,7 +12,7 @@ import { useChatWords } from '../ChatLanguage';
|
|
|
12
12
|
/** The suggestions, as chips: each sends its prompt. */
|
|
13
13
|
export function BalloonSuggestions({ suggestions, onSuggestion, }) {
|
|
14
14
|
const chatText = useChatWords();
|
|
15
|
-
return (_jsx(Box, { role: "group", "aria-label": chatText.suggestions, "data-balloon-suggestions": "",
|
|
15
|
+
return (_jsx(Box, { role: "group", "aria-label": chatText.suggestions, "data-balloon-suggestions": "", display: "flex", flexWrap: "wrap", gap: 1, mt: 2, children: suggestions.map(suggestion => (_jsx(Button, { size: "small", "data-balloon-suggestion": suggestion.label, "aria-label": `Ask: ${suggestion.prompt}`, title: suggestion.prompt, onClick: () => onSuggestion(suggestion), sx: { borderRadius: 999 }, children: suggestion.label }, suggestion.label))) }));
|
|
16
16
|
}
|
|
17
17
|
/** How tall the listed conversation grows before it scrolls, in pixels. */
|
|
18
18
|
export const BALLOON_HISTORY_MAX_HEIGHT = 220;
|
|
@@ -30,7 +30,7 @@ export const BALLOON_HISTORY_WITH_ATTACHMENT_MAX_HEIGHT = 120;
|
|
|
30
30
|
*/
|
|
31
31
|
export function BalloonHistoryLarge({ history, tool, attachment, }) {
|
|
32
32
|
const chatText = useChatWords();
|
|
33
|
-
return (_jsxs(Box, { role: "log", "aria-label": chatText.conversation, "data-balloon-history-large": "",
|
|
33
|
+
return (_jsxs(Box, { role: "log", "aria-label": chatText.conversation, "data-balloon-history-large": "", display: "flex", flexDirection: "column", gap: 2, children: [_jsx(BalloonChatItems, { items: withToolCall(history, tool), density: "comfortable" }), attachment ? _jsx(Box, { children: attachment }) : null] }));
|
|
34
34
|
}
|
|
35
35
|
function BalloonHistory({ history, onOpen, maxHeight = BALLOON_HISTORY_MAX_HEIGHT, onExpand, tool, waiting = false, }) {
|
|
36
36
|
const chatText = useChatWords();
|
|
@@ -56,26 +56,7 @@ function BalloonHistory({ history, onOpen, maxHeight = BALLOON_HISTORY_MAX_HEIGH
|
|
|
56
56
|
observer.observe(content);
|
|
57
57
|
return () => observer.disconnect();
|
|
58
58
|
}, []);
|
|
59
|
-
return (_jsxs(Box, { "data-balloon-history": "",
|
|
60
|
-
m: 0,
|
|
61
|
-
p: 0,
|
|
62
|
-
pb: 1,
|
|
63
|
-
border: 0,
|
|
64
|
-
bg: 'transparent',
|
|
65
|
-
font: 'inherit',
|
|
66
|
-
textAlign: 'left',
|
|
67
|
-
cursor: 'pointer',
|
|
68
|
-
fontSize: 0,
|
|
69
|
-
fontWeight: 'semibold',
|
|
70
|
-
color: 'fg.muted',
|
|
71
|
-
'&:hover': { textDecoration: 'underline' },
|
|
72
|
-
}, children: conversationHeaderText(conversationCount(history), chatText) }), onExpand ? (_jsx(IconButton, { icon: ScreenFullIcon, size: "small", variant: "invisible", "aria-label": chatText.expandConversation, "data-balloon-history-expand": "", onClick: onExpand, sx: { position: 'absolute', top: '4px', right: '28px' } })) : null, _jsx(Box, { ref: listRef, role: "log", "aria-label": chatText.conversation, "data-balloon-history-list": "", sx: {
|
|
73
|
-
maxHeight,
|
|
74
|
-
overflowY: 'auto',
|
|
75
|
-
display: 'flex',
|
|
76
|
-
flexDirection: 'column',
|
|
77
|
-
pr: 1,
|
|
78
|
-
}, children: _jsx(BalloonChatItems, { items: withToolCall(history, tool), waiting: waiting }) })] }));
|
|
59
|
+
return (_jsxs(Box, { "data-balloon-history": "", flex: 1, minWidth: 0, display: "flex", flexDirection: "column", children: [_jsx(Box, { as: "button", type: "button", "data-balloon-peek": "", "data-balloon-header": "", onClick: onOpen, m: 0, p: 0, pb: 1, border: 0, bg: "transparent", font: "inherit", textAlign: "left", cursor: "pointer", fontSize: 0, fontWeight: "semibold", color: "fg.muted", hover: { textDecoration: 'underline' }, children: conversationHeaderText(conversationCount(history), chatText) }), onExpand ? (_jsx(IconButton, { icon: ScreenFullIcon, size: "small", variant: "invisible", "aria-label": chatText.expandConversation, "data-balloon-history-expand": "", onClick: onExpand, sx: { position: 'absolute', top: '4px', right: '28px' } })) : null, _jsx(Box, { ref: listRef, role: "log", "aria-label": chatText.conversation, "data-balloon-history-list": "", maxHeight: maxHeight, overflowY: "auto", display: "flex", flexDirection: "column", pr: 1, children: _jsx(BalloonChatItems, { items: withToolCall(history, tool), waiting: waiting }) })] }));
|
|
79
60
|
}
|
|
80
61
|
export function SpeechBalloon({ text, more = false, onOpen, above, side = 'above', align, tailAt, approval, decide, onDecisionActive, wide = false, onDismissPeek, display = 'history', tool, speaking = false, busy = false, attachment, history, onExpand, expandTitle, suggestions, onSuggestion, waiting = false, fullText, onExpandHistory, }) {
|
|
81
62
|
const chatText = useChatWords();
|
|
@@ -94,33 +75,22 @@ export function SpeechBalloon({ text, more = false, onOpen, above, side = 'above
|
|
|
94
75
|
const current = display === 'current';
|
|
95
76
|
// History with messages to list: all of them, not the newest line alone.
|
|
96
77
|
const listed = !current && history && history.length > 0 ? history : null;
|
|
97
|
-
return (_jsxs(Box, { "data-speech-balloon": "", "data-balloon-display": display,
|
|
78
|
+
return (_jsxs(Box, { "data-speech-balloon": "", "data-balloon-display": display, maxWidth: wide || listed || offered || whole || (current && attachment)
|
|
79
|
+
? 300
|
|
80
|
+
: current
|
|
81
|
+
? 260
|
|
82
|
+
: 280, px: 3, py: 2, color: "fg.default", border: "1px solid", borderRadius: "bubble", boxShadow: "shadow.medium", fontSize: 1, textAlign: "left",
|
|
83
|
+
// Pixels, as strings: a number here is read as the theme's space
|
|
84
|
+
// scale (`-7` would be `-space[7]`, 48px).
|
|
85
|
+
bottom: side === 'above' ? `${above}px` : undefined, top: side === 'above' ? undefined : `${above}px`, sx: {
|
|
98
86
|
position: 'absolute',
|
|
99
|
-
// Pixels, as strings: a number here is read as the theme's space
|
|
100
|
-
// scale (`-7` would be `-space[7]`, 48px).
|
|
101
|
-
...(side === 'above'
|
|
102
|
-
? { bottom: `${above}px` }
|
|
103
|
-
: { top: `${above}px` }),
|
|
104
87
|
[align]: 0,
|
|
105
|
-
maxWidth: wide || listed || offered || whole || (current && attachment)
|
|
106
|
-
? 300
|
|
107
|
-
: current
|
|
108
|
-
? 260
|
|
109
|
-
: 280,
|
|
110
88
|
width: wide || listed || offered || whole || (current && attachment)
|
|
111
89
|
? 300
|
|
112
90
|
: 'max-content',
|
|
113
|
-
px: 3,
|
|
114
|
-
py: 2,
|
|
115
91
|
bg: 'canvas.default',
|
|
116
|
-
color: 'fg.default',
|
|
117
|
-
border: '1px solid',
|
|
118
92
|
// The current balloon is the agent's voice now: its accent's edge.
|
|
119
93
|
borderColor: current ? 'accent.muted' : 'border.default',
|
|
120
|
-
borderRadius: 'var(--theme-radius-bubble, 16px)',
|
|
121
|
-
boxShadow: 'shadow.medium',
|
|
122
|
-
fontSize: 1,
|
|
123
|
-
textAlign: 'left',
|
|
124
94
|
// The tail, toward what speaks.
|
|
125
95
|
'&::after': {
|
|
126
96
|
content: '""',
|
|
@@ -135,7 +105,7 @@ export function SpeechBalloon({ text, more = false, onOpen, above, side = 'above
|
|
|
135
105
|
borderColor: current ? 'accent.muted' : 'border.default',
|
|
136
106
|
transform: side === 'above' ? 'rotate(45deg)' : 'rotate(225deg)',
|
|
137
107
|
},
|
|
138
|
-
}, children: [_jsxs(Box, {
|
|
108
|
+
}, children: [_jsxs(Box, { display: "flex", alignItems: "flex-start", gap: 1, children: [current && !approval ? (
|
|
139
109
|
// Not a <button>: the body draws the chat's tool card, a button of
|
|
140
110
|
// its own, and a click on that card is the card's alone.
|
|
141
111
|
_jsx(Box, { role: "button", tabIndex: 0, "data-balloon-peek": "", onClick: (event) => {
|
|
@@ -150,45 +120,11 @@ export function SpeechBalloon({ text, more = false, onOpen, above, side = 'above
|
|
|
150
120
|
event.preventDefault();
|
|
151
121
|
onOpen();
|
|
152
122
|
}
|
|
153
|
-
},
|
|
154
|
-
flex: 1,
|
|
155
|
-
minWidth: 0,
|
|
156
|
-
m: 0,
|
|
157
|
-
p: 0,
|
|
158
|
-
border: 0,
|
|
159
|
-
bg: 'transparent',
|
|
160
|
-
color: 'inherit',
|
|
161
|
-
font: 'inherit',
|
|
162
|
-
textAlign: 'left',
|
|
163
|
-
cursor: 'pointer',
|
|
164
|
-
}, children: _jsx(CurrentBalloonBody, { text: text, tool: tool, busy: busy, speaking: speaking, waiting: waiting, whole: whole, fullText: wholeText, onOverflow: setOverflowing }) })) : listed ? (_jsx(BalloonHistory, { history: listed, onOpen: onOpen, onExpand: onExpandHistory, tool: tool, waiting: waiting, maxHeight: attachment
|
|
123
|
+
}, flex: 1, minWidth: 0, m: 0, p: 0, border: 0, bg: "transparent", color: "inherit", font: "inherit", textAlign: "left", cursor: "pointer", children: _jsx(CurrentBalloonBody, { text: text, tool: tool, busy: busy, speaking: speaking, waiting: waiting, whole: whole, fullText: wholeText, onOverflow: setOverflowing }) })) : listed ? (_jsx(BalloonHistory, { history: listed, onOpen: onOpen, onExpand: onExpandHistory, tool: tool, waiting: waiting, maxHeight: attachment
|
|
165
124
|
? BALLOON_HISTORY_WITH_ATTACHMENT_MAX_HEIGHT
|
|
166
125
|
: BALLOON_HISTORY_MAX_HEIGHT })) : tool ? (
|
|
167
126
|
// The tool being called: the chat's card, not inside the peek's
|
|
168
127
|
// button (the card is a button of its own).
|
|
169
|
-
_jsx(Box, {
|
|
170
|
-
flex: 1,
|
|
171
|
-
minWidth: 0,
|
|
172
|
-
m: 0,
|
|
173
|
-
p: 0,
|
|
174
|
-
border: 0,
|
|
175
|
-
bg: 'transparent',
|
|
176
|
-
color: 'inherit',
|
|
177
|
-
font: 'inherit',
|
|
178
|
-
textAlign: 'left',
|
|
179
|
-
cursor: 'pointer',
|
|
180
|
-
'&:hover': { textDecoration: 'underline' },
|
|
181
|
-
}, children: _jsx(Box, { as: "span", role: "status", "aria-live": "polite", children: text }) })), onDismissPeek && !approval ? (_jsx(IconButton, { icon: XIcon, size: "small", variant: "invisible", "aria-label": chatText.dismiss, "data-balloon-dismiss": "", onClick: onDismissPeek, sx: { mt: '-4px', mr: '-8px', flexShrink: 0 } })) : null] }), current && !approval && !tool && (cut || overflowing || whole) ? (_jsx(Box, { as: "button", type: "button", "aria-expanded": whole, "data-balloon-whole": whole ? 'less' : 'more', onClick: () => setWhole(!whole), sx: {
|
|
182
|
-
m: 0,
|
|
183
|
-
mt: 1,
|
|
184
|
-
p: 0,
|
|
185
|
-
border: 0,
|
|
186
|
-
bg: 'transparent',
|
|
187
|
-
color: 'accent.fg',
|
|
188
|
-
font: 'inherit',
|
|
189
|
-
fontSize: 0,
|
|
190
|
-
cursor: 'pointer',
|
|
191
|
-
'&:hover': { textDecoration: 'underline' },
|
|
192
|
-
}, children: whole ? chatText.showLess : chatText.showMore })) : null, !current && !listed && waiting ? (_jsx(Box, { "data-balloon-waiting": "", sx: { mt: 1 }, children: _jsx(BalloonChatItems, { items: [], waiting: true }) })) : null, approval && (_jsxs(Box, { "data-balloon-approval": approval.id, sx: { mt: 1 }, children: [_jsx(Text, { as: "p", sx: { m: 0, fontWeight: 'semibold' }, children: approval.asks }), approval.why ? (_jsx(Text, { as: "p", sx: { m: 0, color: 'fg.muted', fontSize: 0 }, children: approval.why })) : null, _jsxs(Box, { sx: { display: 'flex', gap: 2, mt: 2 }, children: [_jsx(Button, { size: "small", variant: "primary", disabled: approval.deciding, onClick: approval.onApprove, children: chatText.approve }), _jsx(Button, { size: "small", disabled: approval.deciding, onClick: approval.onDeny, children: chatText.deny })] }), approval.others > 0 ? (_jsx(Text, { as: "p", sx: { m: 0, mt: 1, color: 'fg.muted', fontSize: 0 }, children: chatText.moreWaiting(approval.others) })) : null] })), offered && onSuggestion ? (_jsx(BalloonSuggestions, { suggestions: offered, onSuggestion: onSuggestion })) : null, attachment ? (_jsxs(Box, { "data-balloon-attachment": "", sx: { mt: 2, display: 'flex', flexDirection: 'column', gap: 1 }, children: [attachment, onExpand ? (_jsx(BalloonExpandButton, { title: expandTitle ?? chatText.theVisual, onExpand: onExpand })) : null] })) : null, !current ? _jsx(ToolLineAnnouncer, { line: tool }) : null, decide && _jsx(DecisionAsk, { ask: decide, onActiveChange: onDecisionActive })] }));
|
|
128
|
+
_jsx(Box, { flex: 1, minWidth: 0, children: _jsx(BalloonToolCall, { line: tool }) })) : (_jsx(Box, { as: "button", type: "button", "data-balloon-peek": "", "data-balloon-more": more ? '' : undefined, onClick: onOpen, flex: 1, minWidth: 0, m: 0, p: 0, border: 0, bg: "transparent", color: "inherit", font: "inherit", textAlign: "left", cursor: "pointer", hover: { textDecoration: 'underline' }, children: _jsx(Box, { as: "span", role: "status", "aria-live": "polite", children: text }) })), onDismissPeek && !approval ? (_jsx(IconButton, { icon: XIcon, size: "small", variant: "invisible", "aria-label": chatText.dismiss, "data-balloon-dismiss": "", onClick: onDismissPeek, sx: { mt: '-4px', mr: '-8px', flexShrink: 0 } })) : null] }), current && !approval && !tool && (cut || overflowing || whole) ? (_jsx(Box, { as: "button", type: "button", "aria-expanded": whole, "data-balloon-whole": whole ? 'less' : 'more', onClick: () => setWhole(!whole), m: 0, mt: 1, p: 0, border: 0, bg: "transparent", color: "accent.fg", font: "inherit", fontSize: 0, cursor: "pointer", hover: { textDecoration: 'underline' }, children: whole ? chatText.showLess : chatText.showMore })) : null, !current && !listed && waiting ? (_jsx(Box, { "data-balloon-waiting": "", mt: 1, children: _jsx(BalloonChatItems, { items: [], waiting: true }) })) : null, approval && (_jsxs(Box, { "data-balloon-approval": approval.id, mt: 1, children: [_jsx(Text, { as: "p", sx: { m: 0, fontWeight: 'semibold' }, children: approval.asks }), approval.why ? (_jsx(Text, { as: "p", sx: { m: 0, color: 'fg.muted', fontSize: 0 }, children: approval.why })) : null, _jsxs(Box, { display: "flex", gap: 2, mt: 2, children: [_jsx(Button, { size: "small", variant: "primary", disabled: approval.deciding, onClick: approval.onApprove, children: chatText.approve }), _jsx(Button, { size: "small", disabled: approval.deciding, onClick: approval.onDeny, children: chatText.deny })] }), approval.others > 0 ? (_jsx(Text, { as: "p", sx: { m: 0, mt: 1, color: 'fg.muted', fontSize: 0 }, children: chatText.moreWaiting(approval.others) })) : null] })), offered && onSuggestion ? (_jsx(BalloonSuggestions, { suggestions: offered, onSuggestion: onSuggestion })) : null, attachment ? (_jsxs(Box, { "data-balloon-attachment": "", mt: 2, display: "flex", flexDirection: "column", gap: 1, children: [attachment, onExpand ? (_jsx(BalloonExpandButton, { title: expandTitle ?? chatText.theVisual, onExpand: onExpand })) : null] })) : null, !current ? _jsx(ToolLineAnnouncer, { line: tool }) : null, decide && _jsx(DecisionAsk, { ask: decide, onActiveChange: onDecisionActive })] }));
|
|
193
129
|
}
|
|
194
130
|
export default SpeechBalloon;
|