@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.
Files changed (265) hide show
  1. package/lib/Agent.js +2 -18
  2. package/lib/AgentDocument.js +5 -55
  3. package/lib/AgentNode.js +31 -208
  4. package/lib/AgentNotebook.js +5 -59
  5. package/lib/agent-node/AgentNodeGallery.js +23 -111
  6. package/lib/agents/AgentDetails.js +36 -274
  7. package/lib/agents/AgentRuntimeChat.js +1 -8
  8. package/lib/chat/Chat.js +7 -46
  9. package/lib/chat/ChatFloating.js +15 -100
  10. package/lib/chat/ChatInline.js +5 -47
  11. package/lib/chat/ChatPopupStandalone.js +5 -53
  12. package/lib/chat/ChatSidebar.js +4 -51
  13. package/lib/chat/ChatStandalone.js +4 -45
  14. package/lib/chat/EphemeralSurfaceControl.js +5 -25
  15. package/lib/chat/assistant/AssistantContextMenu.d.ts +8 -0
  16. package/lib/chat/assistant/AssistantContextMenu.js +17 -1
  17. package/lib/chat/assistant/AssistantStage.js +6 -25
  18. package/lib/chat/assistant/BalloonParts.js +8 -40
  19. package/lib/chat/assistant/BalloonVisual.js +2 -2
  20. package/lib/chat/assistant/ConversationBalloon.js +2 -11
  21. package/lib/chat/assistant/DecisionAsk.js +3 -3
  22. package/lib/chat/assistant/SandboxDetailsDialog.js +3 -17
  23. package/lib/chat/assistant/SpeechBalloon.js +14 -78
  24. package/lib/chat/base/ChatBase.js +37 -172
  25. package/lib/chat/display/EmptyState.js +7 -35
  26. package/lib/chat/display/FloatingBrandButton.js +4 -34
  27. package/lib/chat/display/PoweredByTag.js +3 -14
  28. package/lib/chat/document/EphemeralDocument.js +3 -18
  29. package/lib/chat/header/ChatHeader.js +1 -17
  30. package/lib/chat/header/ChatHeaderBase.js +2 -24
  31. package/lib/chat/header/ChatViewModeToggle.js +7 -29
  32. package/lib/chat/indicators/McpStatusIndicator.js +3 -12
  33. package/lib/chat/indicators/SandboxStatusIndicator.js +6 -34
  34. package/lib/chat/indicators/SkillsStatusIndicator.js +3 -12
  35. package/lib/chat/indicators/TypingDots.js +1 -11
  36. package/lib/chat/messages/ChatMessageList.js +58 -185
  37. package/lib/chat/messages/ChatMessages.js +15 -79
  38. package/lib/chat/messages/FormSubmissionMessage.js +2 -33
  39. package/lib/chat/messages/NotebookToolSurfaces.js +12 -41
  40. package/lib/chat/messages/TurnFooter.js +4 -10
  41. package/lib/chat/notebook/EphemeralNotebook.js +2 -10
  42. package/lib/chat/parts/ReasoningPart.js +2 -16
  43. package/lib/chat/parts/TextPart.js +2 -12
  44. package/lib/chat/parts/ToolPart.js +16 -90
  45. package/lib/chat/presence/Presence.js +5 -33
  46. package/lib/chat/prompt/FloatingCard.js +1 -13
  47. package/lib/chat/prompt/InputPrompt.js +1 -6
  48. package/lib/chat/prompt/InputPromptBase.js +4 -17
  49. package/lib/chat/prompt/InputPromptLexical.js +44 -45
  50. package/lib/chat/prompt/InputPromptText.js +1 -1
  51. package/lib/chat/prompt/footer/InPromptFooter.js +1 -8
  52. package/lib/chat/prompt/menus/AgentsMenu.js +1 -1
  53. package/lib/chat/prompt/menus/InlineAgentsMenu.js +1 -1
  54. package/lib/chat/prompt/menus/ModelSelector.js +1 -5
  55. package/lib/chat/prompt/menus/SkillsMenu.js +3 -30
  56. package/lib/chat/prompt/menus/SuggestionsMenu.js +1 -1
  57. package/lib/chat/prompt/menus/ToolsMenu.js +4 -48
  58. package/lib/chat/prompt/plugins/AgentMentionPlugin.js +2 -9
  59. package/lib/chat/prompt/plugins/CommandPlugin.js +2 -9
  60. package/lib/chat/prompt/plugins/MentionChip.js +1 -15
  61. package/lib/chat/prompt/stack.js +1 -19
  62. package/lib/chat/tools/A2AAgentDialog.js +9 -42
  63. package/lib/chat/tools/SubagentActivity.js +5 -22
  64. package/lib/chat/tools/ToolApprovalBanner.js +4 -34
  65. package/lib/chat/tools/ToolApprovalDialog.js +4 -19
  66. package/lib/chat/tools/ToolCallDisplay.js +12 -97
  67. package/lib/chat/usage/ContextPie.js +4 -45
  68. package/lib/chat/words.d.ts +7 -0
  69. package/lib/chat/words.js +12 -0
  70. package/lib/components/a2ui/datalayer/Chart.js +4 -10
  71. package/lib/components/a2ui/datalayer/Chat.js +2 -10
  72. package/lib/components/a2ui/datalayer/Download.js +1 -1
  73. package/lib/components/a2ui/datalayer/Evidence.js +1 -15
  74. package/lib/components/a2ui/datalayer/FileUpload.js +1 -12
  75. package/lib/components/a2ui/datalayer/Table.js +9 -17
  76. package/lib/components/a2ui/datalayer/formWidgets.js +3 -2
  77. package/lib/components/a2ui/datalayer/parts.js +1 -16
  78. package/lib/components/a2ui/styles.js +16 -5
  79. package/lib/components/agents/AgentSummary.js +1 -51
  80. package/lib/components/cards/NotificationEventCard.js +6 -72
  81. package/lib/components/cards/OutputCard.js +4 -48
  82. package/lib/components/cards/ToolApprovalCard.js +2 -35
  83. package/lib/components/code-sandboxes/CodeSandboxCellVariables.js +1 -1
  84. package/lib/components/code-sandboxes/CodeSandboxEnvironmentSelect.js +4 -14
  85. package/lib/components/code-sandboxes/CodeSandboxPicker.js +16 -21
  86. package/lib/components/code-sandboxes/CodeSandboxVariables.js +2 -2
  87. package/lib/components/scheduler/ScheduleMenu.js +5 -10
  88. package/lib/components/specs/SpecPayloadPreview.js +1 -26
  89. package/lib/components/teams/A2ATeamGraph.d.ts +4 -3
  90. package/lib/components/teams/A2ATeamGraph.js +25 -71
  91. package/lib/components/teams/AnswerSurfacesView.js +2 -2
  92. package/lib/components/teams/NotebookPreview.js +1 -10
  93. package/lib/components/teams/NotebookPreviewView.js +2 -3
  94. package/lib/components/teams/SceneTranscript.js +3 -17
  95. package/lib/components/teams/SceneView.js +1 -8
  96. package/lib/components/teams/TeamNotebook.js +5 -13
  97. package/lib/components/teams/TeamNotebookView.js +2 -12
  98. package/lib/components/teams/index.d.ts +1 -0
  99. package/lib/components/teams/index.js +1 -0
  100. package/lib/components/teams/useBalloonRoom.d.ts +39 -0
  101. package/lib/components/teams/useBalloonRoom.js +89 -0
  102. package/lib/config/AgentConfiguration.js +22 -225
  103. package/lib/context/ContextDistribution.js +7 -41
  104. package/lib/context/ContextInspector.js +9 -107
  105. package/lib/context/ContextPanel.js +11 -86
  106. package/lib/context/ContextUsage.js +6 -34
  107. package/lib/context/CostTracker.js +7 -42
  108. package/lib/context/MessageHistory.js +3 -37
  109. package/lib/context/TurnGraphChart.js +9 -41
  110. package/lib/examples/A2UiAgentExample.js +6 -108
  111. package/lib/examples/A2UiComponentsGalleryExample.js +1 -1
  112. package/lib/examples/A2UiContactCardExample.js +1 -1
  113. package/lib/examples/A2UiJupyterOutputExample.js +25 -125
  114. package/lib/examples/A2UiRestaurantExample.js +1 -1
  115. package/lib/examples/A2UiViewerExample.js +1 -1
  116. package/lib/examples/AgUiAgenticExample.js +3 -35
  117. package/lib/examples/AgUiBackendToolRenderingExample.js +2 -25
  118. package/lib/examples/AgUiHaikuGenUiExample.js +2 -32
  119. package/lib/examples/AgUiHumanInTheLoopExample.js +5 -59
  120. package/lib/examples/AgUiSharedStateExample.js +6 -56
  121. package/lib/examples/AgUiToolsBasedGenUiExample.js +25 -120
  122. package/lib/examples/AgentA2AExample.js +1 -15
  123. package/lib/examples/AgentA2ATeamExample.js +6 -30
  124. package/lib/examples/AgentCheckpointsExample.js +11 -145
  125. package/lib/examples/AgentCodeSandboxExample.js +5 -108
  126. package/lib/examples/AgentCodeSandboxesExample.js +3 -30
  127. package/lib/examples/AgentCodemodeExample.js +9 -85
  128. package/lib/examples/AgentCompactionExample.js +3 -64
  129. package/lib/examples/AgentDecideExample.js +1 -13
  130. package/lib/examples/AgentEvalsExample.js +5 -60
  131. package/lib/examples/AgentGuardrailsExample.js +4 -28
  132. package/lib/examples/AgentHooksExample.js +1 -1
  133. package/lib/examples/AgentInferenceProviderExample.js +5 -96
  134. package/lib/examples/AgentMCPExample.js +7 -105
  135. package/lib/examples/AgentMemoryExample.js +5 -74
  136. package/lib/examples/AgentMonitoringExample.js +7 -53
  137. package/lib/examples/AgentNotificationsExample.js +3 -61
  138. package/lib/examples/AgentOtelExample.js +3 -72
  139. package/lib/examples/AgentOutputsExample.js +6 -81
  140. package/lib/examples/AgentParametersExample.js +2 -37
  141. package/lib/examples/AgentSkillsExample.js +3 -45
  142. package/lib/examples/AgentSubagentsExample.js +6 -56
  143. package/lib/examples/AgentToolApprovalsExample.js +1 -11
  144. package/lib/examples/AgentTriggersExample.js +29 -239
  145. package/lib/examples/AgentspecsExample.js +6 -60
  146. package/lib/examples/AssistantExample.js +5 -5
  147. package/lib/examples/AssistantGalleryExample.js +8 -65
  148. package/lib/examples/CellExample.js +1 -6
  149. package/lib/examples/ChatCustomExample.js +2 -31
  150. package/lib/examples/ChatExample.js +1 -9
  151. package/lib/examples/ChatStandaloneExample.js +3 -37
  152. package/lib/examples/CopilotKitLexicalExample.js +1 -24
  153. package/lib/examples/DecksAgent.js +1 -1
  154. package/lib/examples/DocumentPageAgent.js +1 -1
  155. package/lib/examples/HomeExample.js +14 -62
  156. package/lib/examples/Lexical2Example.js +3 -32
  157. package/lib/examples/LexicalAgentExample.js +2 -34
  158. package/lib/examples/LexicalAgentSidebarExample.js +3 -34
  159. package/lib/examples/LoopAppComputerExample.js +1 -1
  160. package/lib/examples/LoopShellExample.js +2 -2
  161. package/lib/examples/LoopStrategyExample.js +15 -87
  162. package/lib/examples/LoopWorkspaceEmbed.js +2 -18
  163. package/lib/examples/LoopWorkspaceExample.js +2 -2
  164. package/lib/examples/NotebookAgentExample.js +2 -33
  165. package/lib/examples/NotebookAgentSidebarExample.js +3 -46
  166. package/lib/examples/NotebookCollaborationExample.js +1 -31
  167. package/lib/examples/NotebookExample.js +1 -18
  168. package/lib/examples/NotebookPageAgent.js +1 -1
  169. package/lib/examples/ScenesExample.js +5 -24
  170. package/lib/examples/VoiceChatExample.js +1 -1
  171. package/lib/examples/components/AuthRequiredView.js +1 -7
  172. package/lib/examples/components/ErrorView.js +1 -8
  173. package/lib/examples/components/ExampleErrorBoundary.js +1 -14
  174. package/lib/examples/components/FooterMetrics.js +1 -7
  175. package/lib/examples/components/Header.js +12 -51
  176. package/lib/examples/components/HeaderControls.js +1 -9
  177. package/lib/examples/components/LexicalEditor.js +1 -8
  178. package/lib/examples/components/MainContent.js +1 -13
  179. package/lib/examples/components/MockFileBrowser.js +4 -40
  180. package/lib/examples/components/SessionTabs.js +1 -1
  181. package/lib/examples/components/TimeTravel.js +1 -13
  182. package/lib/examples/main.js +13 -81
  183. package/lib/examples/scenes/A2UiComponentsGalleryScene.js +3 -34
  184. package/lib/examples/scenes/A2UiContactCardScene.js +3 -35
  185. package/lib/examples/scenes/A2UiRestaurantScene.js +3 -53
  186. package/lib/examples/scenes/A2UiViewerScene.js +3 -34
  187. package/lib/examples/utils/AssistantGalleryGrid.js +6 -35
  188. package/lib/examples2/DatalayerNotebookExample.js +3 -33
  189. package/lib/examples2/NativeNavigationExample.js +4 -10
  190. package/lib/examples2/NotebookMutationsKernel.js +2 -1
  191. package/lib/examples2/NotebookMutationsServiceManager.js +2 -1
  192. package/lib/examples2/ReactRouterExample.js +14 -42
  193. package/lib/hooks/useToolApprovals.d.ts +2 -34
  194. package/lib/hooks/useToolApprovals.js +1 -64
  195. package/lib/identity/AgentIdentity.js +17 -62
  196. package/lib/identity/IdentityConnect.js +13 -59
  197. package/lib/identity/OAuthCallback.js +6 -44
  198. package/lib/lexical/ChatInlinePlugin.js +6 -14
  199. package/lib/loop/apps/AppFeedback.js +12 -3
  200. package/lib/loop/apps/AppRenderer.d.ts +4 -3
  201. package/lib/loop/apps/AppRenderer.js +11 -12
  202. package/lib/loop/apps/appspec.js +6 -3
  203. package/lib/loop/apps/feedback.d.ts +3 -2
  204. package/lib/loop/apps/feedback.js +4 -2
  205. package/lib/loop/core/index.d.ts +19 -0
  206. package/lib/loop/core/index.js +27 -0
  207. package/lib/loop/embed/AppEmbed.d.ts +1 -1
  208. package/lib/loop/embed/AppEmbed.js +2 -1
  209. package/lib/loop/embed/LoopEmbed.js +1 -7
  210. package/lib/loop/embed/embedConfig.d.ts +3 -3
  211. package/lib/loop/embed/embedConfig.js +2 -3
  212. package/lib/loop/embed/embedTheme.d.ts +4 -4
  213. package/lib/loop/embed/embedTheme.js +11 -7
  214. package/lib/loop/plugins/a2a-sidebar/A2ASidebar.js +7 -34
  215. package/lib/loop/plugins/a2ui/A2uiView.js +4 -12
  216. package/lib/loop/plugins/a2ui-surface/InlineSurface.js +1 -16
  217. package/lib/loop/plugins/a2ui-surface/SurfaceToolResult.js +2 -12
  218. package/lib/loop/plugins/agents/AnonymousKeyBadge.js +3 -2
  219. package/lib/loop/plugins/agents/SandboxSelector.js +3 -7
  220. package/lib/loop/plugins/agents/SandboxView.js +4 -27
  221. package/lib/loop/plugins/agents/TeamMemberPicker.js +2 -2
  222. package/lib/loop/plugins/agentspecs/AgentspecPicker.js +3 -2
  223. package/lib/loop/plugins/app-activity/AppActivity.js +1 -1
  224. package/lib/loop/plugins/app-computer/AppComputer.js +32 -27
  225. package/lib/loop/plugins/app-elements/AppElements.js +2 -31
  226. package/lib/loop/plugins/app-page/AppPage.js +26 -8
  227. package/lib/loop/plugins/app-rules/AppRulesCard.js +4 -20
  228. package/lib/loop/plugins/assistant/index.js +1 -13
  229. package/lib/loop/plugins/chat/ChatView.js +89 -130
  230. package/lib/loop/plugins/checkpoints-sidebar/CheckpointsSidebar.js +2 -13
  231. package/lib/loop/plugins/decks/DeckSurface.js +2 -2
  232. package/lib/loop/plugins/document/DocumentView.js +4 -12
  233. package/lib/loop/plugins/document-toolbar/SandboxStatusItem.js +3 -8
  234. package/lib/loop/plugins/graph/GraphView.js +2 -2
  235. package/lib/loop/plugins/input-prompt/ComposerView.js +1 -1
  236. package/lib/loop/plugins/notebook/NotebookView.js +3 -11
  237. package/lib/loop/plugins/page-layout/SplitLayout.js +11 -34
  238. package/lib/loop/plugins/page-layout/TurnPanel.js +9 -35
  239. package/lib/loop/plugins/shell/useEditorPreviews.js +3 -2
  240. package/lib/loop/plugins/subagent-activity/SubagentPulse.js +1 -13
  241. package/lib/loop/plugins/window-frame/WindowFrame.js +10 -44
  242. package/lib/loop/plugins/window-frame/index.js +1 -1
  243. package/lib/loop/shell/LoopWorkspace.js +34 -77
  244. package/lib/loop/shell/PluginToggles.js +4 -15
  245. package/lib/loop/shell/SidebarRail.js +8 -40
  246. package/lib/loop/shell/ViewSwitcher.js +4 -24
  247. package/lib/loop-main.js +2 -3
  248. package/lib/mcp/McpServerManager.js +6 -37
  249. package/lib/portable/index.d.ts +11 -0
  250. package/lib/portable/index.js +20 -0
  251. package/lib/protocols/AGUIAdapter.js +2 -2
  252. package/lib/protocols/BaseProtocolAdapter.d.ts +2 -0
  253. package/lib/protocols/BaseProtocolAdapter.js +4 -0
  254. package/lib/specs/apps.js +6 -0
  255. package/lib/specs/appspecSchema.js +11 -4
  256. package/lib/stories/loop/ReferenceScreens.js +17 -91
  257. package/lib/stories/loop/pictures-main.js +1 -1
  258. package/lib/types/agentspecs.d.ts +5 -2
  259. package/lib/types/protocol.d.ts +2 -0
  260. package/lib/utils/approvals.d.ts +59 -0
  261. package/lib/utils/approvals.js +101 -0
  262. package/lib/voice/VoiceInput.js +3 -39
  263. package/package.json +2 -2
  264. package/lib/shims/primerAddonsBox.d.ts +0 -1
  265. 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
- }, sx: {
621
- display: 'block',
622
- width: size,
623
- height: size,
624
- p: 0,
625
- border: 0,
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": "", sx: { 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 }) }));
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, sx: { minWidth: 0, width: '100%' }, children: _jsx(BalloonChatItems, { items: [displayItemOfLine(line)], waiting: waiting }) }));
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": "", sx: VISUALLY_HIDDEN, children: said }));
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": "", sx: {
127
- flexShrink: 0,
128
- display: 'flex',
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": "", sx: { 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' : '', sx: whole
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, sx: { position: 'relative', minWidth: 0 }, children: [_jsx(Box, { sx: { 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);
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, sx: { minWidth: 0 }, children: visual.render('overlay') }) }));
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": "", sx: { position: 'absolute', top: '6px', right: '6px', zIndex: 30 }, children: _jsx(IconButton, { icon: XIcon, size: "small", variant: "invisible", "aria-label": name
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, sx: { px: 3, py: 2, display: 'flex' }, children: _jsxs(Box, { sx: {
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), sx: { ...LINK_SX, display: 'block' }, children: DECISION_WORDS.ask }));
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", sx: { mt: 2 }, children: [_jsx(Text, { as: "p", "data-decision-answer": "", sx: { m: 0, fontWeight: 'semibold' }, children: answer }), _jsxs(Box, { sx: { 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 })] })] }));
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
- }, sx: { 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, { sx: { 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, { sx: { 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, { sx: { 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 })] })] }));
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, { sx: { 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: () => {
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": "", sx: { display: 'flex', flexDirection: 'column', gap: 3 }, children: [_jsxs(Box, { "data-sandbox-summary": "", sx: {
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": "", sx: { 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))) }));
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": "", sx: { display: 'flex', flexDirection: 'column', gap: 2 }, children: [_jsx(BalloonChatItems, { items: withToolCall(history, tool), density: "comfortable" }), attachment ? _jsx(Box, { children: attachment }) : null] }));
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": "", sx: { flex: 1, minWidth: 0, display: 'flex', flexDirection: 'column' }, children: [_jsx(Box, { as: "button", type: "button", "data-balloon-peek": "", "data-balloon-header": "", onClick: onOpen, sx: {
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, sx: {
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, { sx: { display: 'flex', alignItems: 'flex-start', gap: 1 }, children: [current && !approval ? (
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
- }, sx: {
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, { sx: { 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, sx: {
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;