@datalayer/agent-runtimes 1.3.88 → 1.3.90
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/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/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/AppRenderer.d.ts +4 -3
- package/lib/loop/apps/AppRenderer.js +11 -12
- package/lib/loop/apps/appspec.js +6 -3
- 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 +5 -21
- package/lib/loop/plugins/app-elements/AppElements.js +2 -31
- package/lib/loop/plugins/app-page/AppPage.js +1 -1
- 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 +40 -106
- 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/scripts/codegen/generate_envvars.py +0 -1
- package/lib/shims/primerAddonsBox.d.ts +0 -1
- package/lib/shims/primerAddonsBox.js +0 -7
|
@@ -160,9 +160,10 @@ export type A2ATeamGraphProps = {
|
|
|
160
160
|
/** The tool calls running now, to the members' connections (`useA2ATeam`). */
|
|
161
161
|
calls?: A2ATeamCall[];
|
|
162
162
|
/**
|
|
163
|
-
* The room above the members for their balloons, in pixels at full
|
|
164
|
-
*
|
|
165
|
-
*
|
|
163
|
+
* The least room above the members for their balloons, in pixels at full
|
|
164
|
+
* scale: the graph keeps what its balloons take now (`useBalloonRoom`) —
|
|
165
|
+
* suggestions, *more* unfolded — and never less than this. A notebook in
|
|
166
|
+
* a balloon gets at least its own.
|
|
166
167
|
*/
|
|
167
168
|
balloonRoom?: number;
|
|
168
169
|
};
|
|
@@ -11,6 +11,7 @@ import { SpecMark } from '../../chat/marks/SpecMark';
|
|
|
11
11
|
import { toolWords, } from './a2aTeamFlow';
|
|
12
12
|
import { NotebookPreview } from './NotebookPreview';
|
|
13
13
|
import { notebookBalloonVisual } from './TeamNotebook';
|
|
14
|
+
import { useBalloonRoom } from './useBalloonRoom';
|
|
14
15
|
import { toolLineText } from '../../chat/assistant/toolLine';
|
|
15
16
|
/** The graph's own coordinates: the members, and room above them for their balloons. */
|
|
16
17
|
const NODE_WIDTH = 200;
|
|
@@ -201,17 +202,9 @@ const MemberNode = memo(function MemberNode({ data, }) {
|
|
|
201
202
|
// nor selected (`pointer-events: none` on its wrapper): the character,
|
|
202
203
|
// its balloon and its menu take it back, and are left to themselves —
|
|
203
204
|
// no drag, no pan, no wheel.
|
|
204
|
-
className: "nodrag nopan nowheel",
|
|
205
|
-
width: NODE_WIDTH,
|
|
206
|
-
display: 'flex',
|
|
207
|
-
flexDirection: 'column',
|
|
208
|
-
alignItems: 'center',
|
|
209
|
-
gap: 1,
|
|
210
|
-
cursor: 'default',
|
|
211
|
-
pointerEvents: 'all',
|
|
212
|
-
}, "data-team-member": member.id, "data-member-balloon": shown, "data-member-moved": offset.dx || offset.dy
|
|
205
|
+
className: "nodrag nopan nowheel", width: NODE_WIDTH, display: "flex", flexDirection: "column", alignItems: "center", gap: 1, cursor: "default", pointerEvents: "all", "data-team-member": member.id, "data-member-balloon": shown, "data-member-moved": offset.dx || offset.dy
|
|
213
206
|
? `${Math.round(offset.dx)},${Math.round(offset.dy)}`
|
|
214
|
-
: undefined, "data-member-state": persona.state, children: [_jsx(Handle, { id: MEMBER_HANDLES.inLeft, type: "target", position: Position.Left, style: HANDLE(size), isConnectable: false }), _jsx(Handle, { id: MEMBER_HANDLES.inRight, type: "target", position: Position.Right, style: HANDLE(size), isConnectable: false }), _jsx(Handle, { id: MEMBER_HANDLES.inTop, type: "target", position: Position.Top, style: { ...HANDLE(size), top: 0 }, isConnectable: false }), _jsx(Handle, { id: MEMBER_HANDLES.inBottom, type: "target", position: Position.Bottom, style: { ...HANDLE(size), top: size }, isConnectable: false }), _jsx(Box, {
|
|
207
|
+
: undefined, "data-member-state": persona.state, children: [_jsx(Handle, { id: MEMBER_HANDLES.inLeft, type: "target", position: Position.Left, style: HANDLE(size), isConnectable: false }), _jsx(Handle, { id: MEMBER_HANDLES.inRight, type: "target", position: Position.Right, style: HANDLE(size), isConnectable: false }), _jsx(Handle, { id: MEMBER_HANDLES.inTop, type: "target", position: Position.Top, style: { ...HANDLE(size), top: 0 }, isConnectable: false }), _jsx(Handle, { id: MEMBER_HANDLES.inBottom, type: "target", position: Position.Bottom, style: { ...HANDLE(size), top: size }, isConnectable: false }), _jsx(Box, { width: size, height: size, position: "relative", children: persona.away ? (_jsxs(Button, { size: "small", sx: { position: 'absolute', top: size / 2 - 16, left: -24 }, onClick: () => member.onAway?.(false), children: ["Call ", member.name, " back"] })) : (_jsx(AssistantStage, { character: member.character, state: persona.state, size: size,
|
|
215
208
|
// In the node, not over the page; the balloon opens toward the
|
|
216
209
|
// middle of the graph: rightward from the left member.
|
|
217
210
|
place: side === 'left'
|
|
@@ -312,42 +305,16 @@ const ConnectionNode = memo(function ConnectionNode({ id, data, }) {
|
|
|
312
305
|
if (!connection) {
|
|
313
306
|
return null;
|
|
314
307
|
}
|
|
315
|
-
return (_jsxs(Box, { className: "nodrag nopan nowheel",
|
|
316
|
-
width: CONNECTION_WIDTH,
|
|
317
|
-
display: 'flex',
|
|
318
|
-
flexDirection: 'column',
|
|
319
|
-
alignItems: 'center',
|
|
320
|
-
gap: '2px',
|
|
321
|
-
cursor: 'default',
|
|
322
|
-
pointerEvents: 'all',
|
|
323
|
-
}, title: connection.name, "data-team-connection": connection.id, "data-connection-busy": tool ? 'true' : 'false', children: [_jsx(Handle, { type: "target", position: Position.Left, style: { ...HANDLE(size), left: 0 }, isConnectable: false }), _jsx(Box, { as: "button", type: "button", className: tool ? 'a2a-team-connection-busy' : undefined, "aria-label": connectionLabel(connection, owner?.name), "aria-expanded": told, "aria-controls": detailsId, "data-connection-figure": "", onClick: () => setTold(shown => !shown), onKeyDown: (event) => {
|
|
308
|
+
return (_jsxs(Box, { className: "nodrag nopan nowheel", width: CONNECTION_WIDTH, display: "flex", flexDirection: "column", alignItems: "center", gap: "2px", cursor: "default", pointerEvents: "all", title: connection.name, "data-team-connection": connection.id, "data-connection-busy": tool ? 'true' : 'false', children: [_jsx(Handle, { type: "target", position: Position.Left, style: { ...HANDLE(size), left: 0 }, isConnectable: false }), _jsx(Box, { as: "button", type: "button", className: tool ? 'a2a-team-connection-busy' : undefined, "aria-label": connectionLabel(connection, owner?.name), "aria-expanded": told, "aria-controls": detailsId, "data-connection-figure": "", onClick: () => setTold(shown => !shown), onKeyDown: (event) => {
|
|
324
309
|
if (event.key === 'Escape' && told) {
|
|
325
310
|
event.stopPropagation();
|
|
326
311
|
setTold(false);
|
|
327
312
|
}
|
|
328
|
-
},
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
alignItems: 'center',
|
|
334
|
-
justifyContent: 'center',
|
|
335
|
-
borderRadius: 2,
|
|
336
|
-
border: '1px solid',
|
|
337
|
-
borderColor: tool ? 'accent.emphasis' : 'border.default',
|
|
338
|
-
bg: 'canvas.default',
|
|
339
|
-
cursor: 'pointer',
|
|
340
|
-
'&:focus-visible': {
|
|
341
|
-
outline: '2px solid',
|
|
342
|
-
outlineColor: 'var(--focus-outlineColor, var(--fgColor-accent))',
|
|
343
|
-
outlineOffset: 2,
|
|
344
|
-
},
|
|
345
|
-
}, children: _jsx(SpecMark, { icon: connection.icon, emoji: connection.emoji, size: Math.round(size * 0.66) }) }), _jsx(Text, { sx: { fontWeight: 600, fontSize: 1, textAlign: 'center' }, children: connection.label }), connection.via && (_jsx(Text, { sx: { fontSize: '10px', color: 'fg.muted', textAlign: 'center' }, "data-connection-via": "", children: connection.via })), _jsx(Box, { id: detailsId, hidden: !told, "data-connection-details": "", sx: {
|
|
346
|
-
fontSize: '10px',
|
|
347
|
-
color: 'fg.muted',
|
|
348
|
-
textAlign: 'center',
|
|
349
|
-
maxWidth: CONNECTION_WIDTH + 40,
|
|
350
|
-
}, children: connectionDetails(connection, owner?.name, tool) })] }));
|
|
313
|
+
}, width: size, height: size, p: 0, display: "flex", alignItems: "center", justifyContent: "center", borderRadius: 2, border: "1px solid", borderColor: tool ? 'accent.emphasis' : 'border.default', bg: "canvas.default", cursor: "pointer", focusVisible: {
|
|
314
|
+
outline: '2px solid',
|
|
315
|
+
outlineColor: 'var(--focus-outlineColor, var(--fgColor-accent))',
|
|
316
|
+
outlineOffset: 2,
|
|
317
|
+
}, children: _jsx(SpecMark, { icon: connection.icon, emoji: connection.emoji, size: Math.round(size * 0.66) }) }), _jsx(Text, { sx: { fontWeight: 600, fontSize: 1, textAlign: 'center' }, children: connection.label }), connection.via && (_jsx(Text, { sx: { fontSize: '10px', color: 'fg.muted', textAlign: 'center' }, "data-connection-via": "", children: connection.via })), _jsx(Box, { id: detailsId, hidden: !told, "data-connection-details": "", fontSize: "10px", color: "fg.muted", textAlign: "center", maxWidth: CONNECTION_WIDTH + 40, children: connectionDetails(connection, owner?.name, tool) })] }));
|
|
351
318
|
});
|
|
352
319
|
/** What a connection's details say: the server, who reaches it, and the call running now. */
|
|
353
320
|
export function connectionDetails(connection, member, calling) {
|
|
@@ -399,12 +366,7 @@ const LinkEdge = memo(function LinkEdge({ id, sourceX, sourceY, targetX, targetY
|
|
|
399
366
|
strokeWidth: 2,
|
|
400
367
|
strokeDasharray: data?.connected ? undefined : '6 6',
|
|
401
368
|
opacity: flow === 'still' ? 0.6 : 0.25,
|
|
402
|
-
} }), flow !== 'still' && (_jsxs("g", { "data-a2a-edge-flow": flow, children: [_jsx("path", { d: path, fill: "none", className: `a2a-team-flow a2a-team-flow-${flow}`, stroke: "var(--fgColor-accent, #0969da)", strokeWidth: 3, strokeLinecap: "round", strokeDasharray: "10 14" }), _jsx("path", { d: arrow, fill: "var(--fgColor-accent, #0969da)" })] })), _jsx(EdgeLabelRenderer, { children: _jsx(Box, { className: "nodrag nopan",
|
|
403
|
-
position: 'absolute',
|
|
404
|
-
transform: `translate(-50%, 12px) translate(${(sourceX + targetX) / 2}px, ${(sourceY + targetY) / 2}px)`,
|
|
405
|
-
pointerEvents: 'none',
|
|
406
|
-
textAlign: 'center',
|
|
407
|
-
}, children: _jsx(Label, { variant: data?.connected ? 'accent' : 'secondary', children: data?.label }) }) })] }));
|
|
369
|
+
} }), flow !== 'still' && (_jsxs("g", { "data-a2a-edge-flow": flow, children: [_jsx("path", { d: path, fill: "none", className: `a2a-team-flow a2a-team-flow-${flow}`, stroke: "var(--fgColor-accent, #0969da)", strokeWidth: 3, strokeLinecap: "round", strokeDasharray: "10 14" }), _jsx("path", { d: arrow, fill: "var(--fgColor-accent, #0969da)" })] })), _jsx(EdgeLabelRenderer, { children: _jsx(Box, { className: "nodrag nopan", position: "absolute", transform: `translate(-50%, 12px) translate(${(sourceX + targetX) / 2}px, ${(sourceY + targetY) / 2}px)`, pointerEvents: "none", textAlign: "center", children: _jsx(Label, { variant: data?.connected ? 'accent' : 'secondary', children: data?.label }) }) })] }));
|
|
408
370
|
});
|
|
409
371
|
/** A member's link to a connection: still, or flowing toward it while a call runs. */
|
|
410
372
|
export const CallEdge = memo(function CallEdge({ id, sourceX, sourceY, targetX, targetY, data, }) {
|
|
@@ -415,13 +377,9 @@ export const CallEdge = memo(function CallEdge({ id, sourceX, sourceY, targetX,
|
|
|
415
377
|
stroke: 'var(--borderColor-default, #d0d7de)',
|
|
416
378
|
strokeWidth: 2,
|
|
417
379
|
opacity: calling ? 0.3 : 0.8,
|
|
418
|
-
} }), calling && (_jsxs("g", { "data-mcp-edge-call": data?.calling, children: [_jsx("path", { d: path, fill: "none", className: "a2a-team-flow a2a-team-call", stroke: "var(--fgColor-accent, #0969da)", strokeWidth: 3, strokeLinecap: "round", strokeDasharray: "6 8" }), _jsx("path", { d: arrow, fill: "var(--fgColor-accent, #0969da)" })] })), calling && (_jsx(EdgeLabelRenderer, { children: _jsx(Box, { className: "nodrag nopan",
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
transform: `translate(calc(-100% - 10px), -50%) translate(${(sourceX + targetX) / 2}px, ${(sourceY + targetY) / 2}px)`,
|
|
422
|
-
pointerEvents: 'none',
|
|
423
|
-
whiteSpace: 'nowrap',
|
|
424
|
-
}, children: _jsx(Label, { variant: "accent", children: data?.calling }) }) }))] }));
|
|
380
|
+
} }), calling && (_jsxs("g", { "data-mcp-edge-call": data?.calling, children: [_jsx("path", { d: path, fill: "none", className: "a2a-team-flow a2a-team-call", stroke: "var(--fgColor-accent, #0969da)", strokeWidth: 3, strokeLinecap: "round", strokeDasharray: "6 8" }), _jsx("path", { d: arrow, fill: "var(--fgColor-accent, #0969da)" })] })), calling && (_jsx(EdgeLabelRenderer, { children: _jsx(Box, { className: "nodrag nopan", position: "absolute",
|
|
381
|
+
// Beside the edge, toward the middle of the graph.
|
|
382
|
+
transform: `translate(calc(-100% - 10px), -50%) translate(${(sourceX + targetX) / 2}px, ${(sourceY + targetY) / 2}px)`, pointerEvents: "none", whiteSpace: "nowrap", children: _jsx(Label, { variant: "accent", children: data?.calling }) }) }))] }));
|
|
425
383
|
});
|
|
426
384
|
const NODE_TYPES = { member: MemberNode, connection: ConnectionNode };
|
|
427
385
|
const EDGE_TYPES = { a2a: LinkEdge, mcp: CallEdge };
|
|
@@ -534,10 +492,16 @@ export function A2ATeamGraph({ entry, peer, peers: more = NO_PEERS, flow, flows,
|
|
|
534
492
|
connections: (member.connections ?? []).map(connection => connection.id),
|
|
535
493
|
}));
|
|
536
494
|
const placedKey = JSON.stringify(placed);
|
|
537
|
-
//
|
|
495
|
+
// What the balloons take now, at least the room the page gives; a
|
|
496
|
+
// notebook in a balloon, at least its own.
|
|
497
|
+
const measured = useBalloonRoom(box, {
|
|
498
|
+
anchor: '[data-team-member]',
|
|
499
|
+
zoom: viewport.zoom,
|
|
500
|
+
floor: balloonRoom,
|
|
501
|
+
});
|
|
538
502
|
const room = members.some(member => member.persona.notebook)
|
|
539
|
-
? Math.max(NOTEBOOK_BALLOON_ROOM,
|
|
540
|
-
:
|
|
503
|
+
? Math.max(NOTEBOOK_BALLOON_ROOM, measured)
|
|
504
|
+
: measured;
|
|
541
505
|
// Beside a member, its connections may reach below it: the row takes them.
|
|
542
506
|
const reach = Math.max(0, ...placed.map(({ connections }) => connectionsReach(size, connections.length, connectionHeight)));
|
|
543
507
|
const rowHeight = Math.max(memberHeight, reach);
|
|
@@ -711,10 +675,7 @@ export function A2ATeamGraph({ entry, peer, peers: more = NO_PEERS, flow, flows,
|
|
|
711
675
|
], [linkKey, placedKey, busy]);
|
|
712
676
|
const heard = [...words, ...busy.said].filter(Boolean).join('. ');
|
|
713
677
|
const flowNow = flowOfAll(peers.map(one => flowOf(one.id)));
|
|
714
|
-
return (_jsxs(Box, { ref: box, "data-a2a-team-graph": "", "data-a2a-flow": flowNow, "data-a2a-calls": calls.length, "data-a2a-members": members.length, sx: {
|
|
715
|
-
width: '100%',
|
|
716
|
-
height,
|
|
717
|
-
position: 'relative',
|
|
678
|
+
return (_jsxs(Box, { ref: box, "data-a2a-team-graph": "", "data-a2a-flow": flowNow, "data-a2a-calls": calls.length, "data-a2a-members": members.length, width: "100%", height: height, position: "relative", sx: {
|
|
718
679
|
'@keyframes a2aTeamFlow': {
|
|
719
680
|
from: { strokeDashoffset: 24 },
|
|
720
681
|
to: { strokeDashoffset: 0 },
|
|
@@ -732,7 +693,7 @@ export function A2ATeamGraph({ entry, peer, peers: more = NO_PEERS, flow, flows,
|
|
|
732
693
|
'@keyframes a2aTeamPulse': {
|
|
733
694
|
'0%, 100%': { boxShadow: '0 0 0 0 transparent' },
|
|
734
695
|
'50%': {
|
|
735
|
-
boxShadow: '0 0 0 4px var(--bgColor-accent-muted
|
|
696
|
+
boxShadow: '0 0 0 4px var(--bgColor-accent-muted)',
|
|
736
697
|
},
|
|
737
698
|
},
|
|
738
699
|
'& .a2a-team-call': {
|
|
@@ -756,14 +717,7 @@ export function A2ATeamGraph({ entry, peer, peers: more = NO_PEERS, flow, flows,
|
|
|
756
717
|
'& [data-team-member] [data-assistant-figure]:active': {
|
|
757
718
|
cursor: 'grabbing',
|
|
758
719
|
},
|
|
759
|
-
}, children: [_jsx(Box, { as: "span", "aria-live": "polite",
|
|
760
|
-
position: 'absolute',
|
|
761
|
-
width: 1,
|
|
762
|
-
height: 1,
|
|
763
|
-
overflow: 'hidden',
|
|
764
|
-
clip: 'rect(0 0 0 0)',
|
|
765
|
-
whiteSpace: 'nowrap',
|
|
766
|
-
}, children: heard }), _jsx(Moving.Provider, { value: movingValue, children: _jsx(Members.Provider, { value: membersById, children: _jsx(Busy.Provider, { value: busy.byNode, children: _jsx(ReactFlow, { nodes: nodes, edges: edges, nodeTypes: NODE_TYPES, edgeTypes: EDGE_TYPES, viewport: viewport, nodesDraggable: false, nodesConnectable: false, nodesFocusable: false, edgesFocusable: false, elementsSelectable: false, deleteKeyCode: null, selectionKeyCode: null, multiSelectionKeyCode: null, panOnDrag: false, panOnScroll: false, zoomOnScroll: false, zoomOnPinch: false, zoomOnDoubleClick: false, preventScrolling: false, style: { overflow: 'visible', background: 'transparent' },
|
|
720
|
+
}, children: [_jsx(Box, { as: "span", "aria-live": "polite", position: "absolute", width: 1, height: 1, overflow: "hidden", clip: "rect(0 0 0 0)", whiteSpace: "nowrap", children: heard }), _jsx(Moving.Provider, { value: movingValue, children: _jsx(Members.Provider, { value: membersById, children: _jsx(Busy.Provider, { value: busy.byNode, children: _jsx(ReactFlow, { nodes: nodes, edges: edges, nodeTypes: NODE_TYPES, edgeTypes: EDGE_TYPES, viewport: viewport, nodesDraggable: false, nodesConnectable: false, nodesFocusable: false, edgesFocusable: false, elementsSelectable: false, deleteKeyCode: null, selectionKeyCode: null, multiSelectionKeyCode: null, panOnDrag: false, panOnScroll: false, zoomOnScroll: false, zoomOnPinch: false, zoomOnDoubleClick: false, preventScrolling: false, style: { overflow: 'visible', background: 'transparent' },
|
|
767
721
|
// The library is MIT: its credit is not required on the page.
|
|
768
722
|
proOptions: { hideAttribution: true }, "aria-label": `${entry.name} and ${peers.map(one => one.name).join(', ')}, over A2A` }) }) }) })] }));
|
|
769
723
|
}
|
|
@@ -22,9 +22,9 @@ function OneSurface({ surface, name, onPress, }) {
|
|
|
22
22
|
}));
|
|
23
23
|
}, [answered, onPress, surface]);
|
|
24
24
|
const title = parsed?.title || surface.artifact.name;
|
|
25
|
-
return (_jsxs(Box, { as: "section", "aria-label": name ? `${name}: ${title}` : title, "data-answer-surface": surface.id,
|
|
25
|
+
return (_jsxs(Box, { as: "section", "aria-label": name ? `${name}: ${title}` : title, "data-answer-surface": surface.id, display: "flex", flexDirection: "column", gap: 2, minWidth: 0, children: [_jsx(Text, { sx: { fontWeight: 'bold', fontSize: 1 }, children: name ? `${name} · ${title}` : title }), parsed?.messages?.length ? (_jsx(InlineSurface, { messages: parsed.messages, onAction: onAction })) : (_jsx(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: "This could not be drawn: it holds no surface." })), answered ? (_jsxs(Box, { role: "status", "data-answer-reply": "", display: "flex", flexDirection: "column", gap: 1, fontSize: 1, children: [_jsxs(Text, { sx: { color: 'fg.muted' }, children: ["You chose: ", answered.chose] }), answered.waiting ? (_jsxs(Box, { display: "flex", alignItems: "center", gap: 2, children: [_jsx(Spinner, { size: "small" }), _jsx(Text, { sx: { color: 'fg.muted' }, children: name ? `Asking ${name}…` : 'Asking…' })] })) : answered.reply ? (_jsx(Text, { children: name ? `${name}: ${answered.reply}` : answered.reply })) : null] })) : null] }));
|
|
26
26
|
}
|
|
27
27
|
export function AnswerSurfacesView({ surfaces, names = {}, onPress, }) {
|
|
28
|
-
return (_jsx(Box, { "data-answer-surfaces": "",
|
|
28
|
+
return (_jsx(Box, { "data-answer-surfaces": "", display: "flex", flexDirection: "column", gap: 3, minWidth: 0, children: surfaces.map(surface => (_jsx(OneSurface, { surface: surface, name: names[surface.giver], onPress: onPress }, surface.id))) }));
|
|
29
29
|
}
|
|
30
30
|
export default AnswerSurfacesView;
|
|
@@ -32,16 +32,7 @@ export function NotebookPreview({ notebook, title, maxHeight = 220, onOpen: onOp
|
|
|
32
32
|
if (!doc) {
|
|
33
33
|
return null;
|
|
34
34
|
}
|
|
35
|
-
return (_jsxs(Box, { "data-notebook-preview": "",
|
|
36
|
-
position: 'relative',
|
|
37
|
-
height: maxHeight,
|
|
38
|
-
overflow: 'hidden',
|
|
39
|
-
border: '1px solid',
|
|
40
|
-
borderColor: 'border.muted',
|
|
41
|
-
borderRadius: 2,
|
|
42
|
-
bg: 'canvas.default',
|
|
43
|
-
cursor: onOpen ? 'pointer' : 'default',
|
|
44
|
-
}, children: _jsx(Suspense, { fallback: _jsx(Text, { as: "p", sx: { color: 'fg.muted', fontSize: 0, m: 2 }, children: "Opening the notebook\u2026" }), children: _jsx(NotebookPreviewView, { nbformat: doc, height: maxHeight }) }) }), onOpen && (onOpenGiven || openLabel) ? (_jsx(Text, { as: "button", type: "button", onClick: onOpen, "data-notebook-preview-open": "", sx: {
|
|
35
|
+
return (_jsxs(Box, { "data-notebook-preview": "", display: "flex", flexDirection: "column", gap: 1, minWidth: 0, children: [_jsx(Box, { role: "region", "aria-label": `${title}, read-only`, onClick: onOpen, "data-notebook-preview-cells": doc.cells.length, position: "relative", height: maxHeight, overflow: "hidden", border: "1px solid", borderColor: "border.muted", borderRadius: 2, bg: "canvas.default", cursor: onOpen ? 'pointer' : 'default', children: _jsx(Suspense, { fallback: _jsx(Text, { as: "p", sx: { color: 'fg.muted', fontSize: 0, m: 2 }, children: "Opening the notebook\u2026" }), children: _jsx(NotebookPreviewView, { nbformat: doc, height: maxHeight }) }) }), onOpen && (onOpenGiven || openLabel) ? (_jsx(Text, { as: "button", type: "button", onClick: onOpen, "data-notebook-preview-open": "", sx: {
|
|
45
36
|
alignSelf: 'flex-start',
|
|
46
37
|
p: 0,
|
|
47
38
|
border: 0,
|
|
@@ -18,14 +18,13 @@ export function NotebookPreviewView({ nbformat, height, }) {
|
|
|
18
18
|
const content = useMemo(() => JSON.parse(JSON.stringify(nbformat)), [nbformat]);
|
|
19
19
|
const { colorScheme } = useTheme();
|
|
20
20
|
const mode = colorScheme?.startsWith('dark') ? 'dark' : 'light';
|
|
21
|
-
return (_jsxs(Box, { "data-notebook-preview-theme": mode,
|
|
21
|
+
return (_jsxs(Box, { "data-notebook-preview-theme": mode, height: height,
|
|
22
22
|
// JupyterLab writes its theme for the whole page, so two previews in
|
|
23
23
|
// two modes would share the last one written: each carries its own
|
|
24
24
|
// mode's variables on its own subtree.
|
|
25
25
|
style: (mode === 'dark'
|
|
26
26
|
? JUPYTER_DARK_VARIABLES
|
|
27
|
-
: JUPYTER_LIGHT_VARIABLES), children: [_jsx("span", { "data-jupyter-react-theme-root": "notebook-preview", hidden: true }), _jsx(JupyterReactTheme, { colormode: mode, children: _jsx(Box, { "data-notebook-preview-view": id, sx: {
|
|
28
|
-
height,
|
|
27
|
+
: JUPYTER_LIGHT_VARIABLES), children: [_jsx("span", { "data-jupyter-react-theme-root": "notebook-preview", hidden: true }), _jsx(JupyterReactTheme, { colormode: mode, children: _jsx(Box, { "data-notebook-preview-view": id, height: height, sx: {
|
|
29
28
|
// No toolbar: no room kept for one.
|
|
30
29
|
'& .datalayer-NotebookPanel-header': {
|
|
31
30
|
display: 'none',
|
|
@@ -26,29 +26,15 @@ export function SceneTranscript({ lines, emptyText = 'What the scene says and do
|
|
|
26
26
|
// The clipboard refused: nothing to say but the text, still on screen.
|
|
27
27
|
}
|
|
28
28
|
};
|
|
29
|
-
return (_jsxs(Box, { "data-scene-transcript": "", "data-scene-lines": lines.length, children: [lines.length === 0 ? (_jsx(Text, { as: "p", sx: { color: 'fg.muted', fontSize: 1, m: 0 }, children: emptyText })) : (_jsx(Box, { as: "ol", "aria-label": "Transcript", sx: {
|
|
30
|
-
listStyle: 'none',
|
|
31
|
-
m: 0,
|
|
32
|
-
p: 0,
|
|
33
|
-
fontSize: 1,
|
|
34
|
-
...(maxHeight ? { maxHeight, overflowY: 'auto' } : {}),
|
|
35
|
-
}, children: lines.map(line => (_jsxs(Box, { as: "li", "data-transcript-line": line.kind, "data-transcript-from": line.from, "data-transcript-to": line.to, "aria-busy": line.open ? 'true' : undefined, sx: {
|
|
36
|
-
display: 'grid',
|
|
37
|
-
gridTemplateColumns: 'auto 1fr',
|
|
38
|
-
gap: 2,
|
|
39
|
-
py: 1,
|
|
40
|
-
borderBottom: '1px solid',
|
|
41
|
-
borderColor: 'border.muted',
|
|
42
|
-
opacity: line.open ? 0.75 : 1,
|
|
43
|
-
}, children: [_jsx(Text, { as: "time", sx: {
|
|
29
|
+
return (_jsxs(Box, { "data-scene-transcript": "", "data-scene-lines": lines.length, children: [lines.length === 0 ? (_jsx(Text, { as: "p", sx: { color: 'fg.muted', fontSize: 1, m: 0 }, children: emptyText })) : (_jsx(Box, { as: "ol", "aria-label": "Transcript", listStyle: "none", m: 0, p: 0, fontSize: 1, sx: maxHeight ? { maxHeight, overflowY: 'auto' } : {}, children: lines.map(line => (_jsxs(Box, { as: "li", "data-transcript-line": line.kind, "data-transcript-from": line.from, "data-transcript-to": line.to, "aria-busy": line.open ? 'true' : undefined, display: "grid", gridTemplateColumns: "auto 1fr", gap: 2, py: 1, borderBottom: "1px solid", borderColor: "border.muted", opacity: line.open ? 0.75 : 1, children: [_jsx(Text, { as: "time", sx: {
|
|
44
30
|
color: 'fg.muted',
|
|
45
31
|
fontFamily: 'mono',
|
|
46
32
|
fontSize: 0,
|
|
47
33
|
pt: '2px',
|
|
48
34
|
whiteSpace: 'nowrap',
|
|
49
|
-
}, dateTime: new Date(line.at).toISOString(), children: timeText(line.at) }), _jsxs(Box, {
|
|
35
|
+
}, dateTime: new Date(line.at).toISOString(), children: timeText(line.at) }), _jsxs(Box, { minWidth: 0, overflowWrap: "anywhere", children: [_jsxs(Text, { sx: { fontWeight: 600 }, children: [lineHeading(line), ": "] }), _jsxs(Text, { sx: {
|
|
50
36
|
fontFamily: line.kind === 'called' ? 'mono' : undefined,
|
|
51
37
|
color: line.failed ? 'danger.fg' : undefined,
|
|
52
|
-
}, children: [line.text, line.open ? '…' : '', line.failed ? ' (failed)' : ''] })] })] }, line.key))) })), copy && lines.length > 0 && (_jsx(Box, {
|
|
38
|
+
}, children: [line.text, line.open ? '…' : '', line.failed ? ' (failed)' : ''] })] })] }, line.key))) })), copy && lines.length > 0 && (_jsx(Box, { mt: 2, children: _jsx(Button, { size: "small", onClick: () => void onCopy(), "data-transcript-copy": "", children: copied ? 'Copied' : 'Copy as text' }) }))] }));
|
|
53
39
|
}
|
|
54
40
|
export default SceneTranscript;
|
|
@@ -14,14 +14,7 @@ export function SceneView({ children, members = NO_MEMBERS, tracer, lines, defau
|
|
|
14
14
|
};
|
|
15
15
|
const live = useSceneTranscript(lines ? null : tracer, members);
|
|
16
16
|
const transcript = lines ?? live;
|
|
17
|
-
return (_jsxs(Box, { "data-scene-view": shown, children: [_jsxs(Box, {
|
|
18
|
-
display: 'flex',
|
|
19
|
-
alignItems: 'center',
|
|
20
|
-
justifyContent: 'space-between',
|
|
21
|
-
gap: 2,
|
|
22
|
-
flexWrap: 'wrap',
|
|
23
|
-
mb: 2,
|
|
24
|
-
}, children: [_jsxs(SegmentedControl, { "aria-label": "Scene view", size: "small", children: [_jsx(SegmentedControl.Button, { selected: shown === 'graph', onClick: () => choose('graph'), "data-scene-choice": "graph", children: "Graph" }), _jsx(SegmentedControl.Button, { selected: shown === 'transcript', onClick: () => choose('transcript'), "data-scene-choice": "transcript", children: transcript.length
|
|
17
|
+
return (_jsxs(Box, { "data-scene-view": shown, children: [_jsxs(Box, { display: "flex", alignItems: "center", justifyContent: "space-between", gap: 2, flexWrap: "wrap", mb: 2, children: [_jsxs(SegmentedControl, { "aria-label": "Scene view", size: "small", children: [_jsx(SegmentedControl.Button, { selected: shown === 'graph', onClick: () => choose('graph'), "data-scene-choice": "graph", children: "Graph" }), _jsx(SegmentedControl.Button, { selected: shown === 'transcript', onClick: () => choose('transcript'), "data-scene-choice": "transcript", children: transcript.length
|
|
25
18
|
? `Transcript (${transcript.length})`
|
|
26
19
|
: 'Transcript' })] }), aside] }), _jsx(Box, { hidden: shown !== 'graph', "data-scene-graph": "", children: children }), shown === 'transcript' && (_jsx(SceneTranscript, { lines: transcript, emptyText: emptyText, maxHeight: maxHeight }))] }));
|
|
27
20
|
}
|
|
@@ -19,19 +19,11 @@ export function notebookFileName(notebook) {
|
|
|
19
19
|
export function TeamNotebook({ notebook, title, height = 560, hideTitle = false, }) {
|
|
20
20
|
return (_jsxs(Box, { as: "section", "aria-label": title, "data-team-notebook": "",
|
|
21
21
|
// Focused when the notebook in a balloon is clicked (`focusExpanded`).
|
|
22
|
-
tabIndex: -1,
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
scrollMarginTop: '16px',
|
|
28
|
-
'&:focus': { outline: 'none' },
|
|
29
|
-
'&:focus-visible': {
|
|
30
|
-
outline: '2px solid',
|
|
31
|
-
outlineColor: 'var(--focus-outlineColor, var(--fgColor-accent))',
|
|
32
|
-
outlineOffset: 4,
|
|
33
|
-
borderRadius: 2,
|
|
34
|
-
},
|
|
22
|
+
tabIndex: -1, display: "flex", flexDirection: "column", gap: 2, minWidth: 0, scrollMarginTop: "16px", focus: { outline: 'none' }, focusVisible: {
|
|
23
|
+
outline: '2px solid',
|
|
24
|
+
outlineColor: 'var(--focus-outlineColor, var(--fgColor-accent))',
|
|
25
|
+
outlineOffset: 4,
|
|
26
|
+
borderRadius: 2,
|
|
35
27
|
}, children: [!hideTitle && (_jsx(Heading, { as: "h3", sx: { fontSize: 2, m: 0 }, children: title })), _jsx(Suspense, { fallback: _jsx(Text, { as: "p", sx: { color: 'fg.muted', fontSize: 1, m: 0 }, children: "Opening the notebook\u2026" }), children: _jsx(TeamNotebookView, { notebook: notebook, fileName: notebookFileName(notebook), height: height }) })] }));
|
|
36
28
|
}
|
|
37
29
|
/**
|
|
@@ -72,21 +72,11 @@ export function TeamNotebookView({ notebook, fileName, height, }) {
|
|
|
72
72
|
}
|
|
73
73
|
};
|
|
74
74
|
}, [running, service]);
|
|
75
|
-
return (_jsx(QueryClientProvider, { client: queries, children: _jsxs(Box, {
|
|
76
|
-
display: 'flex',
|
|
77
|
-
alignItems: 'center',
|
|
78
|
-
gap: 2,
|
|
79
|
-
flexWrap: 'wrap',
|
|
80
|
-
}, children: [_jsx(Text, { sx: { color: 'fg.muted', fontSize: 1, flex: '1 1 auto' }, children: running
|
|
75
|
+
return (_jsx(QueryClientProvider, { client: queries, children: _jsxs(Box, { display: "flex", flexDirection: "column", gap: 2, children: [_jsxs(Box, { display: "flex", alignItems: "center", gap: 2, flexWrap: "wrap", children: [_jsx(Text, { sx: { color: 'fg.muted', fontSize: 1, flex: '1 1 auto' }, children: running
|
|
81
76
|
? 'It runs in your browser, with Python (Pyodide): run its cells, change them, add your own.'
|
|
82
|
-
: 'Starting Python in your browser…' }), _jsx(Button, { size: "small", leadingVisual: DownloadIcon, onClick: save, "data-team-notebook-download": "", children: "Download .ipynb" })] }), failed && _jsx(Flash, { variant: "warning", children: failed }), _jsx(Box, { "data-team-notebook-sheet": "", sx: {
|
|
83
|
-
position: 'relative',
|
|
77
|
+
: 'Starting Python in your browser…' }), _jsx(Button, { size: "small", leadingVisual: DownloadIcon, onClick: save, "data-team-notebook-download": "", children: "Download .ipynb" })] }), failed && _jsx(Flash, { variant: "warning", children: failed }), _jsx(Box, { "data-team-notebook-sheet": "", position: "relative", border: "1px solid", borderColor: "border.default", borderRadius: 2, overflow: "hidden", sx: {
|
|
84
78
|
height,
|
|
85
79
|
minHeight: 0,
|
|
86
|
-
border: '1px solid',
|
|
87
|
-
borderColor: 'border.default',
|
|
88
|
-
borderRadius: 2,
|
|
89
|
-
overflow: 'hidden',
|
|
90
80
|
// As the loop's notebook view pins them: Lumino sizes these
|
|
91
81
|
// itself, and a resize it never hears of leaves them at zero.
|
|
92
82
|
'& .jp-NotebookPanel': {
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The room a scene's balloons take above their members, measured: a graph
|
|
3
|
+
* (`A2ATeamGraph`) or a member alone on its stage keeps above its members
|
|
4
|
+
* what their balloons take now — the greeting, the suggestions, *more*
|
|
5
|
+
* unfolded — and no more, so that the scene's box fits what it shows.
|
|
6
|
+
*
|
|
7
|
+
* @module components/teams/useBalloonRoom
|
|
8
|
+
*/
|
|
9
|
+
import type { RefObject } from 'react';
|
|
10
|
+
/** A balloon, as measured on the page: its top and its anchor's, in pixels. */
|
|
11
|
+
export type BalloonRect = {
|
|
12
|
+
/** The top of what it speaks for: the member's node, or its figure. */
|
|
13
|
+
anchorTop: number;
|
|
14
|
+
/** The balloon's top. */
|
|
15
|
+
top: number;
|
|
16
|
+
/** Its height: a hidden balloon (`display: none`) has none and takes no room. */
|
|
17
|
+
height: number;
|
|
18
|
+
};
|
|
19
|
+
/** Between the tallest balloon and the edge above it, in pixels at full scale. */
|
|
20
|
+
export declare const BALLOON_MARGIN = 12;
|
|
21
|
+
/** The room is kept to steps of this many pixels: a line more or less does not move the members. */
|
|
22
|
+
export declare const BALLOON_ROOM_STEP = 8;
|
|
23
|
+
/**
|
|
24
|
+
* The room above the members their balloons take, in pixels at full scale:
|
|
25
|
+
* the tallest balloon above its anchor, with a margin, in steps — at least
|
|
26
|
+
* `floor`. `zoom` is the scale the balloons are drawn at (a graph's
|
|
27
|
+
* viewport): their measures are divided by it.
|
|
28
|
+
*/
|
|
29
|
+
export declare function balloonRoomOf(balloons: readonly BalloonRect[], zoom?: number, floor?: number): number;
|
|
30
|
+
/**
|
|
31
|
+
* The room the balloons inside `box` take above their anchors (the closest
|
|
32
|
+
* ancestor of each matching `anchor`), kept current as they open, close
|
|
33
|
+
* and change: at least `floor`, in pixels at full scale.
|
|
34
|
+
*/
|
|
35
|
+
export declare function useBalloonRoom(box: RefObject<HTMLElement | null>, { anchor, zoom, floor, }: {
|
|
36
|
+
anchor: string;
|
|
37
|
+
zoom?: number;
|
|
38
|
+
floor?: number;
|
|
39
|
+
}): number;
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2025-2026 Datalayer, Inc.
|
|
3
|
+
* Distributed under the terms of the Modified BSD License.
|
|
4
|
+
*/
|
|
5
|
+
import { useEffect, useState } from 'react';
|
|
6
|
+
/** Between the tallest balloon and the edge above it, in pixels at full scale. */
|
|
7
|
+
export const BALLOON_MARGIN = 12;
|
|
8
|
+
/** The room is kept to steps of this many pixels: a line more or less does not move the members. */
|
|
9
|
+
export const BALLOON_ROOM_STEP = 8;
|
|
10
|
+
/**
|
|
11
|
+
* The room above the members their balloons take, in pixels at full scale:
|
|
12
|
+
* the tallest balloon above its anchor, with a margin, in steps — at least
|
|
13
|
+
* `floor`. `zoom` is the scale the balloons are drawn at (a graph's
|
|
14
|
+
* viewport): their measures are divided by it.
|
|
15
|
+
*/
|
|
16
|
+
export function balloonRoomOf(balloons, zoom = 1, floor = 0) {
|
|
17
|
+
const scale = zoom > 0 ? zoom : 1;
|
|
18
|
+
const above = Math.max(0, ...balloons
|
|
19
|
+
.filter(balloon => balloon.height > 0)
|
|
20
|
+
.map(balloon => (balloon.anchorTop - balloon.top) / scale));
|
|
21
|
+
const room = above > 0
|
|
22
|
+
? Math.ceil((above + BALLOON_MARGIN) / BALLOON_ROOM_STEP) *
|
|
23
|
+
BALLOON_ROOM_STEP
|
|
24
|
+
: 0;
|
|
25
|
+
return Math.max(floor, room);
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* The room the balloons inside `box` take above their anchors (the closest
|
|
29
|
+
* ancestor of each matching `anchor`), kept current as they open, close
|
|
30
|
+
* and change: at least `floor`, in pixels at full scale.
|
|
31
|
+
*/
|
|
32
|
+
export function useBalloonRoom(box, { anchor, zoom = 1, floor = 0, }) {
|
|
33
|
+
const [room, setRoom] = useState(floor);
|
|
34
|
+
useEffect(() => {
|
|
35
|
+
const element = box.current;
|
|
36
|
+
if (!element ||
|
|
37
|
+
typeof ResizeObserver === 'undefined' ||
|
|
38
|
+
typeof MutationObserver === 'undefined') {
|
|
39
|
+
setRoom(floor);
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
let frame = 0;
|
|
43
|
+
const measure = () => {
|
|
44
|
+
frame = 0;
|
|
45
|
+
const balloons = [];
|
|
46
|
+
element
|
|
47
|
+
.querySelectorAll('[data-speech-balloon]')
|
|
48
|
+
.forEach(balloon => {
|
|
49
|
+
const owner = balloon.closest(anchor);
|
|
50
|
+
if (!owner || !element.contains(owner)) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
const rect = balloon.getBoundingClientRect();
|
|
54
|
+
balloons.push({
|
|
55
|
+
anchorTop: owner.getBoundingClientRect().top,
|
|
56
|
+
top: rect.top,
|
|
57
|
+
height: rect.height,
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
const next = balloonRoomOf(balloons, zoom, floor);
|
|
61
|
+
setRoom(current => (current === next ? current : next));
|
|
62
|
+
};
|
|
63
|
+
const later = () => {
|
|
64
|
+
if (!frame) {
|
|
65
|
+
frame = requestAnimationFrame(measure);
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
const sizes = new ResizeObserver(later);
|
|
69
|
+
// A balloon that opens, closes or is made again is observed anew.
|
|
70
|
+
const observe = () => {
|
|
71
|
+
sizes.disconnect();
|
|
72
|
+
element
|
|
73
|
+
.querySelectorAll('[data-speech-balloon]')
|
|
74
|
+
.forEach(balloon => sizes.observe(balloon));
|
|
75
|
+
later();
|
|
76
|
+
};
|
|
77
|
+
const changes = new MutationObserver(observe);
|
|
78
|
+
changes.observe(element, { childList: true, subtree: true });
|
|
79
|
+
observe();
|
|
80
|
+
return () => {
|
|
81
|
+
if (frame) {
|
|
82
|
+
cancelAnimationFrame(frame);
|
|
83
|
+
}
|
|
84
|
+
sizes.disconnect();
|
|
85
|
+
changes.disconnect();
|
|
86
|
+
};
|
|
87
|
+
}, [box, anchor, zoom, floor]);
|
|
88
|
+
return room;
|
|
89
|
+
}
|