@datalayer/agent-runtimes 1.3.89 → 1.3.91
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/Agent.js +2 -18
- package/lib/AgentDocument.js +5 -55
- package/lib/AgentNode.js +31 -208
- package/lib/AgentNotebook.js +5 -59
- package/lib/agent-node/AgentNodeGallery.js +23 -111
- package/lib/agents/AgentDetails.js +36 -274
- package/lib/agents/AgentRuntimeChat.js +1 -8
- package/lib/chat/Chat.js +7 -46
- package/lib/chat/ChatFloating.js +15 -100
- package/lib/chat/ChatInline.js +5 -47
- package/lib/chat/ChatPopupStandalone.js +5 -53
- package/lib/chat/ChatSidebar.js +4 -51
- package/lib/chat/ChatStandalone.js +4 -45
- package/lib/chat/EphemeralSurfaceControl.js +5 -25
- package/lib/chat/assistant/AssistantContextMenu.d.ts +8 -0
- package/lib/chat/assistant/AssistantContextMenu.js +17 -1
- package/lib/chat/assistant/AssistantStage.js +6 -25
- package/lib/chat/assistant/BalloonParts.js +8 -40
- package/lib/chat/assistant/BalloonVisual.js +2 -2
- package/lib/chat/assistant/ConversationBalloon.js +2 -11
- package/lib/chat/assistant/DecisionAsk.js +3 -3
- package/lib/chat/assistant/SandboxDetailsDialog.js +3 -17
- package/lib/chat/assistant/SpeechBalloon.js +14 -78
- package/lib/chat/base/ChatBase.js +37 -172
- package/lib/chat/display/EmptyState.js +7 -35
- package/lib/chat/display/FloatingBrandButton.js +4 -34
- package/lib/chat/display/PoweredByTag.js +3 -14
- package/lib/chat/document/EphemeralDocument.js +3 -18
- package/lib/chat/header/ChatHeader.js +1 -17
- package/lib/chat/header/ChatHeaderBase.js +2 -24
- package/lib/chat/header/ChatViewModeToggle.js +7 -29
- package/lib/chat/indicators/McpStatusIndicator.js +3 -12
- package/lib/chat/indicators/SandboxStatusIndicator.js +6 -34
- package/lib/chat/indicators/SkillsStatusIndicator.js +3 -12
- package/lib/chat/indicators/TypingDots.js +1 -11
- package/lib/chat/messages/ChatMessageList.js +58 -185
- package/lib/chat/messages/ChatMessages.js +15 -79
- package/lib/chat/messages/FormSubmissionMessage.js +2 -33
- package/lib/chat/messages/NotebookToolSurfaces.js +12 -41
- package/lib/chat/messages/TurnFooter.js +4 -10
- package/lib/chat/notebook/EphemeralNotebook.js +2 -10
- package/lib/chat/parts/ReasoningPart.js +2 -16
- package/lib/chat/parts/TextPart.js +2 -12
- package/lib/chat/parts/ToolPart.js +16 -90
- package/lib/chat/presence/Presence.js +5 -33
- package/lib/chat/prompt/FloatingCard.js +1 -13
- package/lib/chat/prompt/InputPrompt.js +1 -6
- package/lib/chat/prompt/InputPromptBase.js +4 -17
- package/lib/chat/prompt/InputPromptLexical.js +44 -45
- package/lib/chat/prompt/InputPromptText.js +1 -1
- package/lib/chat/prompt/footer/InPromptFooter.js +1 -8
- package/lib/chat/prompt/menus/AgentsMenu.js +1 -1
- package/lib/chat/prompt/menus/InlineAgentsMenu.js +1 -1
- package/lib/chat/prompt/menus/ModelSelector.js +1 -5
- package/lib/chat/prompt/menus/SkillsMenu.js +3 -30
- package/lib/chat/prompt/menus/SuggestionsMenu.js +1 -1
- package/lib/chat/prompt/menus/ToolsMenu.js +4 -48
- package/lib/chat/prompt/plugins/AgentMentionPlugin.js +2 -9
- package/lib/chat/prompt/plugins/CommandPlugin.js +2 -9
- package/lib/chat/prompt/plugins/MentionChip.js +1 -15
- package/lib/chat/prompt/stack.js +1 -19
- package/lib/chat/tools/A2AAgentDialog.js +9 -42
- package/lib/chat/tools/SubagentActivity.js +5 -22
- package/lib/chat/tools/ToolApprovalBanner.js +4 -34
- package/lib/chat/tools/ToolApprovalDialog.js +4 -19
- package/lib/chat/tools/ToolCallDisplay.js +12 -97
- package/lib/chat/usage/ContextPie.js +4 -45
- package/lib/chat/words.d.ts +7 -0
- package/lib/chat/words.js +12 -0
- package/lib/components/a2ui/datalayer/Chart.js +4 -10
- package/lib/components/a2ui/datalayer/Chat.js +2 -10
- package/lib/components/a2ui/datalayer/Download.js +1 -1
- package/lib/components/a2ui/datalayer/Evidence.js +1 -15
- package/lib/components/a2ui/datalayer/FileUpload.js +1 -12
- package/lib/components/a2ui/datalayer/Table.js +9 -17
- package/lib/components/a2ui/datalayer/formWidgets.js +3 -2
- package/lib/components/a2ui/datalayer/parts.js +1 -16
- package/lib/components/a2ui/styles.js +16 -5
- package/lib/components/agents/AgentSummary.js +1 -51
- package/lib/components/cards/NotificationEventCard.js +6 -72
- package/lib/components/cards/OutputCard.js +4 -48
- package/lib/components/cards/ToolApprovalCard.js +2 -35
- package/lib/components/code-sandboxes/CodeSandboxCellVariables.js +1 -1
- package/lib/components/code-sandboxes/CodeSandboxEnvironmentSelect.js +4 -14
- package/lib/components/code-sandboxes/CodeSandboxPicker.js +16 -21
- package/lib/components/code-sandboxes/CodeSandboxVariables.js +2 -2
- package/lib/components/scheduler/ScheduleMenu.js +5 -10
- package/lib/components/specs/SpecPayloadPreview.js +1 -26
- package/lib/components/teams/A2ATeamGraph.d.ts +4 -3
- package/lib/components/teams/A2ATeamGraph.js +25 -71
- package/lib/components/teams/AnswerSurfacesView.js +2 -2
- package/lib/components/teams/NotebookPreview.js +1 -10
- package/lib/components/teams/NotebookPreviewView.js +2 -3
- package/lib/components/teams/SceneTranscript.js +3 -17
- package/lib/components/teams/SceneView.js +1 -8
- package/lib/components/teams/TeamNotebook.js +5 -13
- package/lib/components/teams/TeamNotebookView.js +2 -12
- package/lib/components/teams/index.d.ts +1 -0
- package/lib/components/teams/index.js +1 -0
- package/lib/components/teams/useBalloonRoom.d.ts +39 -0
- package/lib/components/teams/useBalloonRoom.js +89 -0
- package/lib/config/AgentConfiguration.js +22 -225
- package/lib/context/ContextDistribution.js +7 -41
- package/lib/context/ContextInspector.js +9 -107
- package/lib/context/ContextPanel.js +11 -86
- package/lib/context/ContextUsage.js +6 -34
- package/lib/context/CostTracker.js +7 -42
- package/lib/context/MessageHistory.js +3 -37
- package/lib/context/TurnGraphChart.js +9 -41
- package/lib/examples/A2UiAgentExample.js +6 -108
- package/lib/examples/A2UiComponentsGalleryExample.js +1 -1
- package/lib/examples/A2UiContactCardExample.js +1 -1
- package/lib/examples/A2UiJupyterOutputExample.js +25 -125
- package/lib/examples/A2UiRestaurantExample.js +1 -1
- package/lib/examples/A2UiViewerExample.js +1 -1
- package/lib/examples/AgUiAgenticExample.js +3 -35
- package/lib/examples/AgUiBackendToolRenderingExample.js +2 -25
- package/lib/examples/AgUiHaikuGenUiExample.js +2 -32
- package/lib/examples/AgUiHumanInTheLoopExample.js +5 -59
- package/lib/examples/AgUiSharedStateExample.js +6 -56
- package/lib/examples/AgUiToolsBasedGenUiExample.js +25 -120
- package/lib/examples/AgentA2AExample.js +1 -15
- package/lib/examples/AgentA2ATeamExample.js +6 -30
- package/lib/examples/AgentCheckpointsExample.js +11 -145
- package/lib/examples/AgentCodeSandboxExample.js +5 -108
- package/lib/examples/AgentCodeSandboxesExample.js +3 -30
- package/lib/examples/AgentCodemodeExample.js +9 -85
- package/lib/examples/AgentCompactionExample.js +3 -64
- package/lib/examples/AgentDecideExample.js +1 -13
- package/lib/examples/AgentEvalsExample.js +5 -60
- package/lib/examples/AgentGuardrailsExample.js +4 -28
- package/lib/examples/AgentHooksExample.js +1 -1
- package/lib/examples/AgentInferenceProviderExample.js +5 -96
- package/lib/examples/AgentMCPExample.js +7 -105
- package/lib/examples/AgentMemoryExample.js +5 -74
- package/lib/examples/AgentMonitoringExample.js +7 -53
- package/lib/examples/AgentNotificationsExample.js +3 -61
- package/lib/examples/AgentOtelExample.js +3 -72
- package/lib/examples/AgentOutputsExample.js +6 -81
- package/lib/examples/AgentParametersExample.js +2 -37
- package/lib/examples/AgentSkillsExample.js +3 -45
- package/lib/examples/AgentSubagentsExample.js +6 -56
- package/lib/examples/AgentToolApprovalsExample.js +1 -11
- package/lib/examples/AgentTriggersExample.js +29 -239
- package/lib/examples/AgentspecsExample.js +6 -60
- package/lib/examples/AssistantExample.js +5 -5
- package/lib/examples/AssistantGalleryExample.js +8 -65
- package/lib/examples/CellExample.js +1 -6
- package/lib/examples/ChatCustomExample.js +2 -31
- package/lib/examples/ChatExample.js +1 -9
- package/lib/examples/ChatStandaloneExample.js +3 -37
- package/lib/examples/CopilotKitLexicalExample.js +1 -24
- package/lib/examples/DecksAgent.js +1 -1
- package/lib/examples/DocumentPageAgent.js +1 -1
- package/lib/examples/HomeExample.js +14 -62
- package/lib/examples/Lexical2Example.js +3 -32
- package/lib/examples/LexicalAgentExample.js +2 -34
- package/lib/examples/LexicalAgentSidebarExample.js +3 -34
- package/lib/examples/LoopAppComputerExample.js +1 -1
- package/lib/examples/LoopShellExample.js +2 -2
- package/lib/examples/LoopStrategyExample.js +15 -87
- package/lib/examples/LoopWorkspaceEmbed.js +2 -18
- package/lib/examples/LoopWorkspaceExample.js +2 -2
- package/lib/examples/NotebookAgentExample.js +2 -33
- package/lib/examples/NotebookAgentSidebarExample.js +3 -46
- package/lib/examples/NotebookCollaborationExample.js +1 -31
- package/lib/examples/NotebookExample.js +1 -18
- package/lib/examples/NotebookPageAgent.js +1 -1
- package/lib/examples/ScenesExample.js +5 -24
- package/lib/examples/VoiceChatExample.js +1 -1
- package/lib/examples/components/AuthRequiredView.js +1 -7
- package/lib/examples/components/ErrorView.js +1 -8
- package/lib/examples/components/ExampleErrorBoundary.js +1 -14
- package/lib/examples/components/FooterMetrics.js +1 -7
- package/lib/examples/components/Header.js +12 -51
- package/lib/examples/components/HeaderControls.js +1 -9
- package/lib/examples/components/LexicalEditor.js +1 -8
- package/lib/examples/components/MainContent.js +1 -13
- package/lib/examples/components/MockFileBrowser.js +4 -40
- package/lib/examples/components/SessionTabs.js +1 -1
- package/lib/examples/components/TimeTravel.js +1 -13
- package/lib/examples/main.js +13 -81
- package/lib/examples/scenes/A2UiComponentsGalleryScene.js +3 -34
- package/lib/examples/scenes/A2UiContactCardScene.js +3 -35
- package/lib/examples/scenes/A2UiRestaurantScene.js +3 -53
- package/lib/examples/scenes/A2UiViewerScene.js +3 -34
- package/lib/examples/utils/AssistantGalleryGrid.js +6 -35
- package/lib/examples2/DatalayerNotebookExample.js +3 -33
- package/lib/examples2/NativeNavigationExample.js +4 -10
- package/lib/examples2/NotebookMutationsKernel.js +2 -1
- package/lib/examples2/NotebookMutationsServiceManager.js +2 -1
- package/lib/examples2/ReactRouterExample.js +14 -42
- package/lib/hooks/useToolApprovals.d.ts +2 -34
- package/lib/hooks/useToolApprovals.js +1 -64
- package/lib/identity/AgentIdentity.js +17 -62
- package/lib/identity/IdentityConnect.js +13 -59
- package/lib/identity/OAuthCallback.js +6 -44
- package/lib/lexical/ChatInlinePlugin.js +6 -14
- package/lib/loop/apps/AppFeedback.js +12 -3
- package/lib/loop/apps/AppRenderer.d.ts +4 -3
- package/lib/loop/apps/AppRenderer.js +11 -12
- package/lib/loop/apps/appspec.js +6 -3
- package/lib/loop/apps/feedback.d.ts +3 -2
- package/lib/loop/apps/feedback.js +4 -2
- package/lib/loop/core/index.d.ts +19 -0
- package/lib/loop/core/index.js +27 -0
- package/lib/loop/embed/AppEmbed.d.ts +1 -1
- package/lib/loop/embed/AppEmbed.js +2 -1
- package/lib/loop/embed/LoopEmbed.js +1 -7
- package/lib/loop/embed/embedConfig.d.ts +3 -3
- package/lib/loop/embed/embedConfig.js +2 -3
- package/lib/loop/embed/embedTheme.d.ts +4 -4
- package/lib/loop/embed/embedTheme.js +11 -7
- package/lib/loop/plugins/a2a-sidebar/A2ASidebar.js +7 -34
- package/lib/loop/plugins/a2ui/A2uiView.js +4 -12
- package/lib/loop/plugins/a2ui-surface/InlineSurface.js +1 -16
- package/lib/loop/plugins/a2ui-surface/SurfaceToolResult.js +2 -12
- package/lib/loop/plugins/agents/AnonymousKeyBadge.js +3 -2
- package/lib/loop/plugins/agents/SandboxSelector.js +3 -7
- package/lib/loop/plugins/agents/SandboxView.js +4 -27
- package/lib/loop/plugins/agents/TeamMemberPicker.js +2 -2
- package/lib/loop/plugins/agentspecs/AgentspecPicker.js +3 -2
- package/lib/loop/plugins/app-activity/AppActivity.js +1 -1
- package/lib/loop/plugins/app-computer/AppComputer.js +32 -27
- package/lib/loop/plugins/app-elements/AppElements.js +2 -31
- package/lib/loop/plugins/app-page/AppPage.js +26 -8
- package/lib/loop/plugins/app-rules/AppRulesCard.js +4 -20
- package/lib/loop/plugins/assistant/index.js +1 -13
- package/lib/loop/plugins/chat/ChatView.js +89 -130
- package/lib/loop/plugins/checkpoints-sidebar/CheckpointsSidebar.js +2 -13
- package/lib/loop/plugins/decks/DeckSurface.js +2 -2
- package/lib/loop/plugins/document/DocumentView.js +4 -12
- package/lib/loop/plugins/document-toolbar/SandboxStatusItem.js +3 -8
- package/lib/loop/plugins/graph/GraphView.js +2 -2
- package/lib/loop/plugins/input-prompt/ComposerView.js +1 -1
- package/lib/loop/plugins/notebook/NotebookView.js +3 -11
- package/lib/loop/plugins/page-layout/SplitLayout.js +11 -34
- package/lib/loop/plugins/page-layout/TurnPanel.js +9 -35
- package/lib/loop/plugins/shell/useEditorPreviews.js +3 -2
- package/lib/loop/plugins/subagent-activity/SubagentPulse.js +1 -13
- package/lib/loop/plugins/window-frame/WindowFrame.js +10 -44
- package/lib/loop/plugins/window-frame/index.js +1 -1
- package/lib/loop/shell/LoopWorkspace.js +34 -77
- package/lib/loop/shell/PluginToggles.js +4 -15
- package/lib/loop/shell/SidebarRail.js +8 -40
- package/lib/loop/shell/ViewSwitcher.js +4 -24
- package/lib/loop-main.js +2 -3
- package/lib/mcp/McpServerManager.js +6 -37
- package/lib/portable/index.d.ts +11 -0
- package/lib/portable/index.js +20 -0
- package/lib/protocols/AGUIAdapter.js +2 -2
- package/lib/protocols/BaseProtocolAdapter.d.ts +2 -0
- package/lib/protocols/BaseProtocolAdapter.js +4 -0
- package/lib/specs/apps.js +6 -0
- package/lib/specs/appspecSchema.js +11 -4
- package/lib/stories/loop/ReferenceScreens.js +17 -91
- package/lib/stories/loop/pictures-main.js +1 -1
- package/lib/types/agentspecs.d.ts +5 -2
- package/lib/types/protocol.d.ts +2 -0
- package/lib/utils/approvals.d.ts +59 -0
- package/lib/utils/approvals.js +101 -0
- package/lib/voice/VoiceInput.js +3 -39
- package/package.json +2 -2
- package/lib/shims/primerAddonsBox.d.ts +0 -1
- package/lib/shims/primerAddonsBox.js +0 -7
|
@@ -49,36 +49,20 @@ export function approvalsOfApp(approvals, appId) {
|
|
|
49
49
|
const PENDING = { status: 'pending' };
|
|
50
50
|
/** A result it wants to keep, shown whole before it is (LOOP R-24). */
|
|
51
51
|
export function DraftShown({ draft }) {
|
|
52
|
-
return (_jsxs(Box, { "data-testid": "app-draft",
|
|
53
|
-
m: 0,
|
|
54
|
-
mt: 1,
|
|
55
|
-
p: 2,
|
|
56
|
-
maxHeight: 240,
|
|
57
|
-
overflow: 'auto',
|
|
58
|
-
whiteSpace: 'pre-wrap',
|
|
59
|
-
fontFamily: 'inherit',
|
|
60
|
-
fontSize: 0,
|
|
61
|
-
bg: 'canvas.subtle',
|
|
62
|
-
borderRadius: 2,
|
|
63
|
-
}, children: draft.content })] }));
|
|
52
|
+
return (_jsxs(Box, { "data-testid": "app-draft", mt: 1, children: [_jsx(Text, { as: "p", sx: { m: 0, fontSize: 0, color: 'fg.muted' }, children: SAVE_WORDS.where(draft.space) }), _jsx(Text, { as: "p", sx: { m: 0, fontWeight: 'semibold' }, children: draft.title }), _jsx(Box, { as: "pre", m: 0, mt: 1, p: 2, maxHeight: 240, overflow: "auto", whiteSpace: "pre-wrap", fontFamily: "inherit", fontSize: 0, bg: "canvas.subtle", borderRadius: 2, children: draft.content })] }));
|
|
64
53
|
}
|
|
65
54
|
function Approvals({ app }) {
|
|
66
55
|
const query = useToolApprovalsQuery(PENDING);
|
|
67
56
|
const approve = useApproveToolRequest();
|
|
68
57
|
const reject = useRejectToolRequest();
|
|
69
58
|
const waiting = useMemo(() => approvalsOfApp(query.data?.approvals ?? [], app.id), [query.data, app.id]);
|
|
70
|
-
return (_jsxs(Box, { "data-testid": "app-approvals", children: [_jsx(Heading, { as: "h4", sx: { fontSize: 1, mt: 3, mb: 1 }, children: APP_RULES_WORDS.waiting }), approve.connectionState !== 'connected' ? (_jsx(Text, { as: "p", sx: { fontSize: 0, color: 'fg.muted', m: 0, mb: 1 }, children: APP_RULES_WORDS.offline })) : null, waiting.length === 0 ? (_jsx(Text, { as: "p", sx: { fontSize: 1, color: 'fg.muted', m: 0 }, children: APP_RULES_WORDS.nothingWaiting })) : (_jsx(Box, { as: "ul",
|
|
59
|
+
return (_jsxs(Box, { "data-testid": "app-approvals", children: [_jsx(Heading, { as: "h4", sx: { fontSize: 1, mt: 3, mb: 1 }, children: APP_RULES_WORDS.waiting }), approve.connectionState !== 'connected' ? (_jsx(Text, { as: "p", sx: { fontSize: 0, color: 'fg.muted', m: 0, mb: 1 }, children: APP_RULES_WORDS.offline })) : null, waiting.length === 0 ? (_jsx(Text, { as: "p", sx: { fontSize: 1, color: 'fg.muted', m: 0 }, children: APP_RULES_WORDS.nothingWaiting })) : (_jsx(Box, { as: "ul", listStyle: "none", p: 0, m: 0, children: waiting.map(approval => {
|
|
71
60
|
const draft = draftOfApproval(approval);
|
|
72
|
-
return (_jsxs(Box, { as: "li", sx: {
|
|
73
|
-
py: 2,
|
|
74
|
-
borderTop: '1px solid',
|
|
75
|
-
borderColor: 'border.muted',
|
|
76
|
-
fontSize: 1,
|
|
77
|
-
}, children: [_jsx(Text, { sx: { fontWeight: 'semibold' }, children: approval.tool_name }), ruleOfApproval(approval) ? (_jsx(Text, { as: "p", sx: { m: 0, color: 'fg.muted', fontSize: 0 }, children: ruleOfApproval(approval) })) : null, draft ? _jsx(DraftShown, { draft: draft }) : null, _jsxs(Box, { sx: { display: 'flex', gap: 2, mt: 1 }, children: [_jsx(Button, { size: "small", variant: "primary", disabled: approve.isPending, onClick: () => approve.mutate({ id: approval.id }), children: draft ? SAVE_WORDS.approve : APP_RULES_WORDS.approve }), _jsx(Button, { size: "small", disabled: reject.isPending, onClick: () => reject.mutate({ id: approval.id }), children: draft ? SAVE_WORDS.decline : APP_RULES_WORDS.reject })] })] }, approval.id));
|
|
61
|
+
return (_jsxs(Box, { as: "li", py: 2, borderTop: "1px solid", borderColor: "border.muted", fontSize: 1, children: [_jsx(Text, { sx: { fontWeight: 'semibold' }, children: approval.tool_name }), ruleOfApproval(approval) ? (_jsx(Text, { as: "p", sx: { m: 0, color: 'fg.muted', fontSize: 0 }, children: ruleOfApproval(approval) })) : null, draft ? _jsx(DraftShown, { draft: draft }) : null, _jsxs(Box, { display: "flex", gap: 2, mt: 1, children: [_jsx(Button, { size: "small", variant: "primary", disabled: approve.isPending, onClick: () => approve.mutate({ id: approval.id }), children: draft ? SAVE_WORDS.approve : APP_RULES_WORDS.approve }), _jsx(Button, { size: "small", disabled: reject.isPending, onClick: () => reject.mutate({ id: approval.id }), children: draft ? SAVE_WORDS.decline : APP_RULES_WORDS.reject })] })] }, approval.id));
|
|
78
62
|
}) }))] }));
|
|
79
63
|
}
|
|
80
64
|
export function AppRulesCard({ app }) {
|
|
81
65
|
const signedIn = Boolean(useIAMStore(state => state.token));
|
|
82
|
-
return (_jsxs(Box, { "data-testid": "app-rules",
|
|
66
|
+
return (_jsxs(Box, { "data-testid": "app-rules", mb: 4, children: [_jsx(Heading, { as: "h3", sx: { fontSize: 2, mb: 2 }, children: APP_RULES_WORDS.title }), app.rules.length === 0 ? (_jsx(Text, { as: "p", sx: { fontSize: 1, color: 'fg.muted', m: 0 }, children: APP_RULES_WORDS.none })) : (_jsx(Box, { as: "ul", listStyle: "none", p: 0, m: 0, children: app.rules.map(ruleInWords).map((rule, index) => (_jsxs(Box, { as: "li", py: 1, fontSize: 1, children: [_jsx(Text, { children: rule.action }), ' ', _jsx(Label, { title: rule.means, children: rule.says }), _jsx(Text, { as: "p", sx: { m: 0, color: 'fg.muted', fontSize: 0 }, children: rule.covers })] }, index))) })), _jsx(Text, { as: "p", sx: { fontSize: 0, color: 'fg.muted', mt: 1, mb: 0 }, children: APP_RULES_WORDS.byDefault }), signedIn ? (_jsx(Approvals, { app: app })) : (_jsx(Text, { as: "p", sx: { fontSize: 1, color: 'fg.muted', mt: 3, mb: 0 }, children: APP_RULES_WORDS.signedOut }))] }));
|
|
83
67
|
}
|
|
84
68
|
export default AppRulesCard;
|
|
@@ -176,19 +176,7 @@ export function LoopAssistant({ app, person, appId, decisions, balloon: displayG
|
|
|
176
176
|
}
|
|
177
177
|
if ('problem' in chosen) {
|
|
178
178
|
// Not replaced by another: what was named is said, where it would stand.
|
|
179
|
-
return (_jsx(Box, { role: "status", "data-assistant-problem": chosen.saidBy, sx: {
|
|
180
|
-
position: 'fixed',
|
|
181
|
-
right: 24,
|
|
182
|
-
bottom: 24,
|
|
183
|
-
zIndex: 1000,
|
|
184
|
-
maxWidth: 320,
|
|
185
|
-
p: 2,
|
|
186
|
-
borderRadius: 2,
|
|
187
|
-
border: '1px solid',
|
|
188
|
-
borderColor: 'attention.muted',
|
|
189
|
-
bg: 'attention.subtle',
|
|
190
|
-
boxShadow: 'shadow.medium',
|
|
191
|
-
}, children: _jsx(Text, { sx: { fontSize: 1 }, children: chosen.problem }) }));
|
|
179
|
+
return (_jsx(Box, { role: "status", "data-assistant-problem": chosen.saidBy, position: "fixed", right: 24, bottom: 24, zIndex: 1000, maxWidth: 320, p: 2, borderRadius: 2, border: "1px solid", borderColor: "attention.muted", bg: "attention.subtle", boxShadow: "shadow.medium", children: _jsx(Text, { sx: { fontSize: 1 }, children: chosen.problem }) }));
|
|
192
180
|
}
|
|
193
181
|
const state = assistantStateOfTurn(turn, presence, { arriving, leaving });
|
|
194
182
|
const unheard = !!saying && saying.id !== heardId;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
3
|
-
import {
|
|
4
|
-
import { loopShapeVars, useColorPalette } from '@datalayer/primer-addons';
|
|
3
|
+
import { IconButton, SegmentedControl, Text, Truncate } from '@primer/react';
|
|
4
|
+
import { Box, loopShapeVars, useColorPalette } from '@datalayer/primer-addons';
|
|
5
5
|
import { ScreenFullIcon, ScreenNormalIcon } from '@primer/octicons-react';
|
|
6
6
|
import { computed, signal } from '@datalayer/reactor';
|
|
7
7
|
/* A signal to read when the layout publishes no live stance: the hook needs one. */
|
|
@@ -41,7 +41,7 @@ import { AGENTS_PLUGIN_NAME } from '../agents/plugin';
|
|
|
41
41
|
import { useConfig } from '../../../hooks/useConfig';
|
|
42
42
|
import { useSkills, useSkillActions } from '../../../hooks/useSkills';
|
|
43
43
|
import { AI_MODEL_CATALOGUE, isChatModel } from '../../../specs/models';
|
|
44
|
-
import { LoopAgentBlueprint, LoopAgentGate, LoopChatComposer, LoopChatExtras, LoopChatHeader, LoopChatLayout, LoopChatSuggestion, LoopChatSurface, LoopChatTurn, LoopCommand, LoopFrontendTool, LoopRunProps, LoopSlots, canOpenView, runForwardedProps, onPromptFocusRequest, onSurfaceRequest, useLoopPromptStore, } from '../../core';
|
|
44
|
+
import { LoopAgentBlueprint, LoopAgentGate, LoopChatComposer, LoopChatExtras, LoopChatHeader, LoopChatLayout, LoopChatSuggestion, LoopChatSurface, LoopChatTurn, LoopCommand, LoopFrontendTool, LoopRunProps, LoopSlots, agentServerOf, noRuntimeSaid, canOpenView, runForwardedProps, onPromptFocusRequest, onSurfaceRequest, useLoopPromptStore, } from '../../core';
|
|
45
45
|
import { messageText, turnWritersOf } from './turnState';
|
|
46
46
|
import { isInactiveSurfaceContribution, orderToolContributions, toolsForChatView, } from './chatViewTools';
|
|
47
47
|
import { useAgentCommandTools } from '../../../tools/adapters/commands';
|
|
@@ -946,8 +946,12 @@ export default function ChatView({ workspace }) {
|
|
|
946
946
|
* opened against. Addressing the latter would be talking to a machine that
|
|
947
947
|
* has never heard of it. The same value for every other target, where the
|
|
948
948
|
* two are the same server.
|
|
949
|
+
*
|
|
950
|
+
* Nothing while a Datalayer runtime is not assigned (the pool had none, or
|
|
951
|
+
* it is still being given): the chat is off and says so below, rather than
|
|
952
|
+
* sending to the host's server — on a hosted page, the page's own origin.
|
|
949
953
|
*/
|
|
950
|
-
const agentServerUrl = workspace.sandbox
|
|
954
|
+
const agentServerUrl = agentServerOf(workspace.sandbox, workspace.serverUrl);
|
|
951
955
|
/*
|
|
952
956
|
* Who a single request may be addressed to.
|
|
953
957
|
*
|
|
@@ -1041,12 +1045,25 @@ export default function ChatView({ workspace }) {
|
|
|
1041
1045
|
* Studio's Preview and the hosted page, rather than left unanswered.
|
|
1042
1046
|
*/
|
|
1043
1047
|
const ambient = useChatAvailability();
|
|
1044
|
-
|
|
1048
|
+
/*
|
|
1049
|
+
* No agent to talk to: a Datalayer runtime not assigned (STUDIO P-24,
|
|
1050
|
+
* round 9). Said in a sentence — why, when its launch was refused — and
|
|
1051
|
+
* nothing is sent; the header does not say *Ready*.
|
|
1052
|
+
*/
|
|
1053
|
+
const noRuntime = agentServerUrl === undefined
|
|
1054
|
+
? noRuntimeSaid(workspace.sandbox, chatText)
|
|
1055
|
+
: undefined;
|
|
1056
|
+
const chatDisabled = gateBlocked ||
|
|
1057
|
+
keyExpired ||
|
|
1058
|
+
Boolean(inPageRefusal) ||
|
|
1059
|
+
Boolean(noRuntime) ||
|
|
1060
|
+
ambient.disabled;
|
|
1045
1061
|
const disabledReason = keyExpired
|
|
1046
1062
|
? expiredKeyIsTemporary
|
|
1047
1063
|
? chatText.demoKeyExpired
|
|
1048
1064
|
: chatText.keyExpired
|
|
1049
1065
|
: (inPageRefusal ??
|
|
1066
|
+
noRuntime ??
|
|
1050
1067
|
gateReason ??
|
|
1051
1068
|
(ambient.disabled ? ambient.disableReason : undefined));
|
|
1052
1069
|
/*
|
|
@@ -1250,6 +1267,10 @@ export default function ChatView({ workspace }) {
|
|
|
1250
1267
|
? openedThread.thread
|
|
1251
1268
|
: undefined
|
|
1252
1269
|
: givenThread;
|
|
1270
|
+
/*
|
|
1271
|
+
* None without a server (`noRuntime`): the chat is off and connects to
|
|
1272
|
+
* nothing — no address is made up for it.
|
|
1273
|
+
*/
|
|
1253
1274
|
const protocol = useMemo(() => inPage
|
|
1254
1275
|
? browserProtocolConfig({
|
|
1255
1276
|
agentId: member?.specId ?? agentId,
|
|
@@ -1280,23 +1301,25 @@ export default function ChatView({ workspace }) {
|
|
|
1280
1301
|
// its session API does on a runtime.
|
|
1281
1302
|
modeEffect: blueprintTurn?.modeEffect,
|
|
1282
1303
|
})
|
|
1283
|
-
:
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1304
|
+
: agentServerUrl !== undefined
|
|
1305
|
+
? {
|
|
1306
|
+
type: 'ag-ui',
|
|
1307
|
+
// An application's agent is spoken to through its session API
|
|
1308
|
+
// (LOOP R-04): each thread a session, recorded under its uid,
|
|
1309
|
+
// run in the name the application runs in, and taking what the
|
|
1310
|
+
// page did besides the message — the same AG-UI events back.
|
|
1311
|
+
endpoint: runsApp
|
|
1312
|
+
? `${agentServerUrl}/api/v1/apps/agents/${encodeURIComponent(agentId)}/ag-ui/`
|
|
1313
|
+
: `${agentServerUrl}/api/v1/ag-ui/${agentId}/`,
|
|
1314
|
+
...(runsApp && iamToken ? { authToken: iamToken } : {}),
|
|
1315
|
+
agentId,
|
|
1316
|
+
// `/api/v1/configure`, not `/api/v1/configure/config`: the hooks
|
|
1317
|
+
// strip one trailing `config`/`configure` segment to find the API
|
|
1318
|
+
// base, so the longer form doubles it.
|
|
1319
|
+
configEndpoint: `${agentServerUrl}/api/v1/configure`,
|
|
1320
|
+
enableConfigQuery: true,
|
|
1321
|
+
}
|
|
1322
|
+
: undefined, [
|
|
1300
1323
|
agentId,
|
|
1301
1324
|
inPage,
|
|
1302
1325
|
inference,
|
|
@@ -1321,7 +1344,7 @@ export default function ChatView({ workspace }) {
|
|
|
1321
1344
|
* need one, and a browser agent has none — hence the menus below being
|
|
1322
1345
|
* gated on the data rather than switched on unconditionally.
|
|
1323
1346
|
*/
|
|
1324
|
-
const configQuery = useConfig(!inPage, protocol
|
|
1347
|
+
const configQuery = useConfig(!inPage, protocol?.type === 'ag-ui' ? protocol.configEndpoint : undefined, undefined, agentId);
|
|
1325
1348
|
const skillsQuery = useSkills(true);
|
|
1326
1349
|
const skillActions = useSkillActions(agentId);
|
|
1327
1350
|
// `undefined` until the runtime answers: its answer is then the list.
|
|
@@ -1338,7 +1361,7 @@ export default function ChatView({ workspace }) {
|
|
|
1338
1361
|
* catalogue that was never going to arrive. The agentspecs catalogue below
|
|
1339
1362
|
* is the answer for this case and needs no request at all.
|
|
1340
1363
|
*/
|
|
1341
|
-
if (inPage) {
|
|
1364
|
+
if (inPage || agentServerUrl === undefined) {
|
|
1342
1365
|
return undefined;
|
|
1343
1366
|
}
|
|
1344
1367
|
let cancelled = false;
|
|
@@ -1424,7 +1447,7 @@ export default function ChatView({ workspace }) {
|
|
|
1424
1447
|
*/
|
|
1425
1448
|
const selectModel = useCallback(async (model) => {
|
|
1426
1449
|
setPickedModel(model);
|
|
1427
|
-
if (inPage) {
|
|
1450
|
+
if (inPage || agentServerUrl === undefined) {
|
|
1428
1451
|
return;
|
|
1429
1452
|
}
|
|
1430
1453
|
await fetch(`${agentServerUrl}/api/v1/configure/inference/provider`, {
|
|
@@ -1597,41 +1620,31 @@ export default function ChatView({ workspace }) {
|
|
|
1597
1620
|
pointerEvents: 'none',
|
|
1598
1621
|
zIndex: -1,
|
|
1599
1622
|
}, children: _jsx(ReactorLazy, { load: surface.load, props: { surfaceId: surface.surfaceId, workspace }, fallback: _jsxs(Centered, { children: ["Loading ", surface.title, "\u2026"] }), errorFallback: error => (_jsxs(Centered, { children: [surface.title, " failed to load: ", error.message] })) }) }, surface.surfaceId));
|
|
1600
|
-
}), !active && waiting ? (_jsx(Box, {
|
|
1601
|
-
const transcriptEl = (_jsx(_Fragment, { children: _jsxs(Box
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
bg: chatExtras.errorBanner.variant === 'warning'
|
|
1626
|
-
? 'attention.subtle'
|
|
1627
|
-
: 'danger.subtle',
|
|
1628
|
-
color: chatExtras.errorBanner.variant === 'warning'
|
|
1629
|
-
? 'attention.fg'
|
|
1630
|
-
: 'danger.fg',
|
|
1631
|
-
borderColor: chatExtras.errorBanner.variant === 'warning'
|
|
1632
|
-
? 'attention.muted'
|
|
1633
|
-
: 'danger.muted',
|
|
1634
|
-
}, children: chatExtras.errorBanner.message })) : null, openedThread?.said && openedThread.given === givenThread?.id ? (_jsx(Text, { as: "p", role: "status", sx: { m: 0, px: 3, py: 2, fontSize: 1, color: 'fg.muted' }, children: openedThread.said })) : null, _jsx(Box, { sx: { flex: '1 1 auto', minHeight: 0, display: 'flex' }, children: opening ? (_jsx(Text, { as: "p", role: "status", sx: { m: 0, p: 3, fontSize: 1, color: 'fg.muted' }, children: THREAD_WORDS.opening })) : (_jsx(ChatBase
|
|
1623
|
+
}), !active && waiting ? (_jsx(Box, { flex: "1 1 0", minWidth: 0, minHeight: 0, children: _jsxs(Centered, { children: ["Starting ", waiting.title, "\u2026"] }) })) : null] }));
|
|
1624
|
+
const transcriptEl = (_jsx(_Fragment, { children: _jsxs(Box
|
|
1625
|
+
/*
|
|
1626
|
+
Beside an editor, with the prompt on top, the conversation is
|
|
1627
|
+
the narrower column: the editor is what a `top` host put the
|
|
1628
|
+
prompt over, and the transcript reads fine at a third of the
|
|
1629
|
+
width. Every other placement splits the row evenly.
|
|
1630
|
+
*/
|
|
1631
|
+
, {
|
|
1632
|
+
/*
|
|
1633
|
+
Beside an editor, with the prompt on top, the conversation is
|
|
1634
|
+
the narrower column: the editor is what a `top` host put the
|
|
1635
|
+
prompt over, and the transcript reads fine at a third of the
|
|
1636
|
+
width. Every other placement splits the row evenly.
|
|
1637
|
+
*/
|
|
1638
|
+
flex: topPrompt && active ? '0 0 34%' : '1 1 0', maxWidth: topPrompt && active ? 460 : undefined, minWidth: 0, minHeight: 0, display: "flex", flexDirection: "column", borderLeft: active ? '1px solid' : undefined, borderColor: "border.default",
|
|
1639
|
+
// So the expired-key panel below can cover exactly this column and
|
|
1640
|
+
// nothing else: the notebook beside it still works.
|
|
1641
|
+
position: "relative", children: [chatExtras.errorBanner ? (_jsx(Box, { flexShrink: 0, px: 3, py: 2, fontSize: 1, borderBottom: "1px solid", bg: chatExtras.errorBanner.variant === 'warning'
|
|
1642
|
+
? 'attention.subtle'
|
|
1643
|
+
: 'danger.subtle', color: chatExtras.errorBanner.variant === 'warning'
|
|
1644
|
+
? 'attention.fg'
|
|
1645
|
+
: 'danger.fg', borderColor: chatExtras.errorBanner.variant === 'warning'
|
|
1646
|
+
? 'attention.muted'
|
|
1647
|
+
: 'danger.muted', children: chatExtras.errorBanner.message })) : null, openedThread?.said && openedThread.given === givenThread?.id ? (_jsx(Text, { as: "p", role: "status", sx: { m: 0, px: 3, py: 2, fontSize: 1, color: 'fg.muted' }, children: openedThread.said })) : null, _jsx(Box, { flex: "1 1 auto", minHeight: 0, display: "flex", children: opening ? (_jsx(Text, { as: "p", role: "status", sx: { m: 0, p: 3, fontSize: 1, color: 'fg.muted' }, children: THREAD_WORDS.opening })) : (_jsx(ChatBase
|
|
1635
1648
|
// The theme it wears, when the host names one (an application's).
|
|
1636
1649
|
, {
|
|
1637
1650
|
// The theme it wears, when the host names one (an application's).
|
|
@@ -1673,7 +1686,9 @@ export default function ChatView({ workspace }) {
|
|
|
1673
1686
|
brandIcon: presence?.face ? (_jsx(PresenceFace, { face: presence.face, size: 20, state: presenceNow })) : (_jsx(BrandIcon, { size: 20 })),
|
|
1674
1687
|
// An application says what it is doing, in plain words, beside
|
|
1675
1688
|
// its name (T-08); an agent's chat keeps its header as it is.
|
|
1676
|
-
headerContent:
|
|
1689
|
+
headerContent:
|
|
1690
|
+
// Not *Ready* with no runtime: the header says why instead.
|
|
1691
|
+
presence && !noRuntime ? (_jsx(PresenceLine, { state: presenceNow })) : undefined, emptyState: {
|
|
1677
1692
|
// An application's own face, at the page's size of the three
|
|
1678
1693
|
// (LOOP T-08, T-19): the thing a person's eye lands on first.
|
|
1679
1694
|
icon: presence?.face ? (_jsx("span", { "aria-hidden": true, style: { fontSize: FACE_LARGE, lineHeight: 1 }, children: _jsx(FaceDrawing, { face: presence.face, size: FACE_LARGE }) })) : (_jsx(BrandIcon, { size: 48 })),
|
|
@@ -1748,7 +1763,7 @@ export default function ChatView({ workspace }) {
|
|
|
1748
1763
|
See `toggleFullScreen` for why it is the browser's API rather
|
|
1749
1764
|
than a big box.
|
|
1750
1765
|
*/
|
|
1751
|
-
headerActions: _jsxs(Box, {
|
|
1766
|
+
headerActions: _jsxs(Box, { display: "inline-flex", alignItems: "center", gap: 2, children: [workspace.chatHeaderActions, chatHeaderItems.length > 0 ? (_jsx(ReactorSlot, { slot: LoopSlots.chatHeader, props: { workspace } })) : null, _jsx(IconButton, { icon: fullScreen ? ScreenNormalIcon : ScreenFullIcon, "aria-label": fullScreen ? 'Exit full screen' : 'Enter full screen', variant: "invisible", size: "small", onClick: () => {
|
|
1752
1767
|
// Whether or not it takes, the hint has been answered:
|
|
1753
1768
|
// they found the control, which is all it was for.
|
|
1754
1769
|
setHintFullScreen(false);
|
|
@@ -1843,45 +1858,23 @@ export default function ChatView({ workspace }) {
|
|
|
1843
1858
|
renderToolResult: chatExtras.renderToolResult, showTurnFooter: chatExtras.showTokenUsage ?? config?.showTokenUsage ?? true, onContextSnapshot: handleContextSnapshot, onLoadingChange: handleLoadingChange, onItemsChange: handleMessagesChange, onDisplayItemsChange: handleDisplayItemsChange, enableStreaming: true }, chatThread?.id)) }), besideChat && !promptHidden ? prompt : null] }) }));
|
|
1844
1859
|
// Off when the host asked for the menu alone: the composer's suggestions
|
|
1845
1860
|
// control carries the same openers (`suggestions` above).
|
|
1846
|
-
const chipsEl = config?.suggestionLabels !== false && chatSuggestions.length > 0 ? (_jsx(Box, { "aria-label": chatText.suggestedPrompts,
|
|
1861
|
+
const chipsEl = config?.suggestionLabels !== false && chatSuggestions.length > 0 ? (_jsx(Box, { "aria-label": chatText.suggestedPrompts, display: "flex", flexWrap: "wrap", gap: 2, px: 2, pb: "6px", children: chatSuggestions.map(item => (_jsx(Box, { as: "button", type: "button",
|
|
1847
1862
|
// The whole request, where the chip shows only its summary.
|
|
1848
|
-
title: item.message, disabled: busy || chatDisabled, onClick: () => void handleSend(item.message),
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
// Room for descenders: the truncated span clips what falls
|
|
1854
|
-
// below its line, and at a line-height of one that is the
|
|
1855
|
-
// tail of every "y".
|
|
1856
|
-
lineHeight: 1.25,
|
|
1857
|
-
px: '10px',
|
|
1858
|
-
py: '5px',
|
|
1859
|
-
width: SUGGESTION_CHIP_WIDTH,
|
|
1860
|
-
flex: `0 0 ${SUGGESTION_CHIP_WIDTH}px`,
|
|
1861
|
-
borderRadius: '999px',
|
|
1862
|
-
border: '1px solid',
|
|
1863
|
+
title: item.message, disabled: busy || chatDisabled, onClick: () => void handleSend(item.message), appearance: "none", font: "inherit", fontSize: 0, fontWeight: "semibold",
|
|
1864
|
+
// Room for descenders: the truncated span clips what falls
|
|
1865
|
+
// below its line, and at a line-height of one that is the
|
|
1866
|
+
// tail of every "y".
|
|
1867
|
+
lineHeight: 1.25, px: "10px", py: "5px", width: SUGGESTION_CHIP_WIDTH, flex: `0 0 ${SUGGESTION_CHIP_WIDTH}px`, borderRadius: "999px", border: "1px solid", bg: "canvas.subtle", whiteSpace: "nowrap", sx: {
|
|
1863
1868
|
borderColor: 'border.default',
|
|
1864
|
-
bg: 'canvas.subtle',
|
|
1865
1869
|
color: 'fg.default',
|
|
1866
1870
|
cursor: 'pointer',
|
|
1867
|
-
whiteSpace: 'nowrap',
|
|
1868
1871
|
'&:hover:not(:disabled)': {
|
|
1869
1872
|
borderColor: 'accent.fg',
|
|
1870
1873
|
color: 'accent.fg',
|
|
1871
1874
|
},
|
|
1872
1875
|
'&:disabled': { opacity: 0.5, cursor: 'default' },
|
|
1873
1876
|
}, children: _jsx(Truncate, { title: item.title, maxWidth: "100%", sx: { minWidth: 0 }, children: item.title }) }, item.title))) })) : null;
|
|
1874
|
-
const transientEl = transient ? (_jsx(Box, {
|
|
1875
|
-
flex: '0 0 auto',
|
|
1876
|
-
px: 3,
|
|
1877
|
-
py: 2,
|
|
1878
|
-
borderTop: '1px solid',
|
|
1879
|
-
borderColor: 'border.default',
|
|
1880
|
-
bg: 'canvas.subtle',
|
|
1881
|
-
fontSize: 1,
|
|
1882
|
-
maxHeight: '40%',
|
|
1883
|
-
overflowY: 'auto',
|
|
1884
|
-
}, children: transient })) : null;
|
|
1877
|
+
const transientEl = transient ? (_jsx(Box, { flex: "0 0 auto", px: 3, py: 2, borderTop: "1px solid", borderColor: "border.default", bg: "canvas.subtle", fontSize: 1, maxHeight: "40%", overflowY: "auto", children: transient })) : null;
|
|
1885
1878
|
return (_jsxs(Box, { ref: viewRef, sx: {
|
|
1886
1879
|
height: '100%',
|
|
1887
1880
|
minHeight: 0,
|
|
@@ -1916,25 +1909,9 @@ export default function ChatView({ workspace }) {
|
|
|
1916
1909
|
zIndex: 1000,
|
|
1917
1910
|
}
|
|
1918
1911
|
: null),
|
|
1919
|
-
}, children: [layout ? (_jsx(layout.Component, { workspace: workspace, editors: editorsEl, hasEditor: !!active, transcript: transcriptEl, prompt: promptHidden ? null : prompt, chips: promptHidden ? null : chipsEl, picker: pickerEl, transient: transientEl })) : (_jsxs(_Fragment, { children: [topPrompt && !promptHidden ? (_jsxs(Box, {
|
|
1920
|
-
|
|
1921
|
-
|
|
1922
|
-
borderColor: 'border.default',
|
|
1923
|
-
}, children: [prompt, chipsEl] })) : null, pickerEl, _jsxs(Box, { sx: {
|
|
1924
|
-
flex: '1 1 auto',
|
|
1925
|
-
minHeight: 0,
|
|
1926
|
-
display: 'flex',
|
|
1927
|
-
// The hidden editors position themselves against this row.
|
|
1928
|
-
position: 'relative',
|
|
1929
|
-
}, children: [editorsEl, transcriptEl] }), transientEl, besideChat || promptHidden || topPrompt ? null : prompt] })), keyExpired ? (_jsx(Box, { sx: {
|
|
1930
|
-
position: 'absolute',
|
|
1931
|
-
inset: 0,
|
|
1932
|
-
zIndex: 5,
|
|
1933
|
-
bg: 'canvas.default',
|
|
1934
|
-
display: 'flex',
|
|
1935
|
-
flexDirection: 'column',
|
|
1936
|
-
minHeight: 0,
|
|
1937
|
-
}, children: _jsx(AnonymousKeyExpired, { agentName: member?.name ?? spec?.name,
|
|
1912
|
+
}, children: [layout ? (_jsx(layout.Component, { workspace: workspace, editors: editorsEl, hasEditor: !!active, transcript: transcriptEl, prompt: promptHidden ? null : prompt, chips: promptHidden ? null : chipsEl, picker: pickerEl, transient: transientEl })) : (_jsxs(_Fragment, { children: [topPrompt && !promptHidden ? (_jsxs(Box, { flex: "0 0 auto", borderBottom: "1px solid", borderColor: "border.default", children: [prompt, chipsEl] })) : null, pickerEl, _jsxs(Box, { flex: "1 1 auto", minHeight: 0, display: "flex",
|
|
1913
|
+
// The hidden editors position themselves against this row.
|
|
1914
|
+
position: "relative", children: [editorsEl, transcriptEl] }), transientEl, besideChat || promptHidden || topPrompt ? null : prompt] })), keyExpired ? (_jsx(Box, { position: "absolute", inset: 0, zIndex: 5, bg: "canvas.default", display: "flex", flexDirection: "column", minHeight: 0, children: _jsx(AnonymousKeyExpired, { agentName: member?.name ?? spec?.name,
|
|
1938
1915
|
// On the browser target the kernel is in this page and owes the
|
|
1939
1916
|
// inference service nothing, so the notebook is genuinely
|
|
1940
1917
|
// unaffected and the panel may say so.
|
|
@@ -1951,16 +1928,7 @@ export default function ChatView({ workspace }) {
|
|
|
1951
1928
|
*/
|
|
1952
1929
|
function SurfacePicker({ surfaces, active, onChange, workspace, }) {
|
|
1953
1930
|
const ordered = [...surfaces].sort((left, right) => (left.order ?? 100) - (right.order ?? 100));
|
|
1954
|
-
return (_jsxs(Box, { sx: {
|
|
1955
|
-
flex: '0 0 auto',
|
|
1956
|
-
display: 'flex',
|
|
1957
|
-
alignItems: 'center',
|
|
1958
|
-
gap: 2,
|
|
1959
|
-
px: 3,
|
|
1960
|
-
py: 2,
|
|
1961
|
-
borderBottom: '1px solid',
|
|
1962
|
-
borderColor: 'border.default',
|
|
1963
|
-
}, children: [_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "Beside the chat" }), _jsxs(SegmentedControl, { "aria-label": "Editor beside the chat", size: "small", children: [_jsx(SegmentedControl.Button, { selected: active === NO_SURFACE, onClick: () => onChange(NO_SURFACE), children: "Chat" }), ordered.map(surface => {
|
|
1931
|
+
return (_jsxs(Box, { flex: "0 0 auto", display: "flex", alignItems: "center", gap: 2, px: 3, py: 2, borderBottom: "1px solid", borderColor: "border.default", children: [_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "Beside the chat" }), _jsxs(SegmentedControl, { "aria-label": "Editor beside the chat", size: "small", children: [_jsx(SegmentedControl.Button, { selected: active === NO_SURFACE, onClick: () => onChange(NO_SURFACE), children: "Chat" }), ordered.map(surface => {
|
|
1964
1932
|
const openable = canOpenView(surface, workspace);
|
|
1965
1933
|
const reason = openable
|
|
1966
1934
|
? undefined
|
|
@@ -1982,14 +1950,5 @@ function SurfacePicker({ surfaces, active, onChange, workspace, }) {
|
|
|
1982
1950
|
})] })] }));
|
|
1983
1951
|
}
|
|
1984
1952
|
function Centered({ children }) {
|
|
1985
|
-
return (_jsx(Box, {
|
|
1986
|
-
height: '100%',
|
|
1987
|
-
display: 'flex',
|
|
1988
|
-
alignItems: 'center',
|
|
1989
|
-
justifyContent: 'center',
|
|
1990
|
-
color: 'fg.muted',
|
|
1991
|
-
fontSize: 1,
|
|
1992
|
-
px: 3,
|
|
1993
|
-
textAlign: 'center',
|
|
1994
|
-
}, children: children }));
|
|
1953
|
+
return (_jsx(Box, { height: "100%", display: "flex", alignItems: "center", justifyContent: "center", color: "fg.muted", fontSize: 1, px: 3, textAlign: "center", children: children }));
|
|
1995
1954
|
}
|
|
@@ -151,24 +151,13 @@ export function CheckpointsSidebar({ workspace, }) {
|
|
|
151
151
|
const remove = useCallback((checkpoint) => act(`delete:${checkpoint.id}`, () => deleteConversationCheckpoint(serverUrl, agentId, checkpoint.id)), [act, agentId, serverUrl]);
|
|
152
152
|
const checkpoints = useMemo(() => state?.checkpoints ?? [], [state]);
|
|
153
153
|
const enabled = state?.enabled ?? false;
|
|
154
|
-
return (_jsxs(Box, { "data-checkpoints-sidebar": agentId || undefined, "data-checkpoints-count": checkpoints.length,
|
|
155
|
-
display: 'grid',
|
|
156
|
-
gridTemplateColumns: 'max-content 1fr',
|
|
157
|
-
columnGap: 3,
|
|
158
|
-
rowGap: 1,
|
|
159
|
-
fontSize: 0,
|
|
160
|
-
}, children: [_jsx(Text, { sx: { color: 'fg.muted' }, children: "Snapshot" }), _jsx(Text, { children: FREQUENCY_LABEL[state.frequency ?? ''] ?? state.frequency }), _jsx(Text, { sx: { color: 'fg.muted' }, children: "Kept" }), _jsxs(Text, { children: ["the last ", state.maxCheckpoints ?? '—', ",", ' ', state.store ?? 'in_memory'] }), _jsx(Text, { sx: { color: 'fg.muted' }, children: "Turn" }), _jsx(Text, { "data-checkpoints-turn": state.turn, children: state.turn })] }))] }), enabled ? (_jsxs(Box, { children: [_jsx(SectionHeading, { children: "Save one now" }), _jsxs(Box, { sx: { display: 'flex', gap: 2 }, children: [_jsx(TextInput, { size: "small", sx: { flex: 1 }, placeholder: "Label, e.g. before-refactor", value: label, "aria-label": "Checkpoint label", onChange: event => setLabel(event.target.value), onKeyDown: event => {
|
|
154
|
+
return (_jsxs(Box, { "data-checkpoints-sidebar": agentId || undefined, "data-checkpoints-count": checkpoints.length, display: "flex", flexDirection: "column", gap: 4, children: [_jsxs(Box, { display: "flex", alignItems: "center", gap: 2, children: [_jsx(VersionsIcon, { size: 16 }), _jsx(Heading, { as: "h3", sx: { fontSize: 2, m: 0, flex: 1 }, children: "Checkpoints" }), _jsx(Label, { variant: "accent", children: checkpoints.length }), _jsx(IconButton, { icon: SyncIcon, size: "small", variant: "invisible", "aria-label": "Refresh checkpoints", onClick: () => void reload() })] }), _jsxs(Box, { children: [_jsx(SectionHeading, { children: "How they are taken" }), state === null ? (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: error ? `Could not read them: ${error}` : 'Reading…' })) : !enabled ? (_jsx(Text, { as: "p", sx: { fontSize: 0, color: 'fg.muted', m: 0 }, children: "This agent's spec asks for no conversation checkpoints." })) : (_jsxs(Box, { display: "grid", gridTemplateColumns: "max-content 1fr", columnGap: 3, rowGap: 1, fontSize: 0, children: [_jsx(Text, { sx: { color: 'fg.muted' }, children: "Snapshot" }), _jsx(Text, { children: FREQUENCY_LABEL[state.frequency ?? ''] ?? state.frequency }), _jsx(Text, { sx: { color: 'fg.muted' }, children: "Kept" }), _jsxs(Text, { children: ["the last ", state.maxCheckpoints ?? '—', ",", ' ', state.store ?? 'in_memory'] }), _jsx(Text, { sx: { color: 'fg.muted' }, children: "Turn" }), _jsx(Text, { "data-checkpoints-turn": state.turn, children: state.turn })] }))] }), enabled ? (_jsxs(Box, { children: [_jsx(SectionHeading, { children: "Save one now" }), _jsxs(Box, { display: "flex", gap: 2, children: [_jsx(TextInput, { size: "small", sx: { flex: 1 }, placeholder: "Label, e.g. before-refactor", value: label, "aria-label": "Checkpoint label", onChange: event => setLabel(event.target.value), onKeyDown: event => {
|
|
161
155
|
if (event.key === 'Enter')
|
|
162
156
|
save();
|
|
163
157
|
} }), _jsx(Button, { size: "small", leadingVisual: BookmarkIcon, disabled: !label.trim() || busy !== null, onClick: save, "data-checkpoints-save": true, children: "Save" })] }), _jsx(Text, { as: "p", sx: { fontSize: 0, color: 'fg.muted', mt: 1, mb: 0 }, children: "The conversation as the last turn left it." })] })) : null, error && state !== null ? (_jsx(Text, { sx: { fontSize: 0, color: 'danger.fg' }, "data-checkpoints-error": true, children: error })) : null, _jsxs(Box, { children: [_jsx(SectionHeading, { children: "Checkpoints" }), checkpoints.length === 0 ? (_jsx(Text, { as: "p", sx: { fontSize: 0, color: 'fg.muted', m: 0 }, children: enabled ? 'None yet — one is taken as each turn ends.' : 'None.' })) : (_jsx(Timeline, { children: checkpoints.map(checkpoint => {
|
|
164
158
|
const auto = isAutoCheckpoint(checkpoint);
|
|
165
159
|
const rewinding = busy === `rewind:${checkpoint.id}`;
|
|
166
|
-
return (_jsxs(Timeline.Item, { "data-checkpoint": checkpoint.id, "data-checkpoint-label": checkpoint.label, "data-checkpoint-auto": auto ? 'true' : 'false', children: [_jsx(Timeline.Badge, { children: auto ? _jsx(HistoryIcon, {}) : _jsx(BookmarkIcon, {}) }), _jsxs(Timeline.Body, { children: [_jsxs(Box, { sx: {
|
|
167
|
-
display: 'flex',
|
|
168
|
-
alignItems: 'center',
|
|
169
|
-
gap: 2,
|
|
170
|
-
flexWrap: 'wrap',
|
|
171
|
-
}, children: [_jsx(Text, { sx: { fontWeight: 'bold', fontSize: 1 }, children: checkpoint.label }), _jsx(Label, { size: "small", variant: auto ? 'secondary' : 'accent', children: auto ? 'auto' : 'saved' })] }), _jsxs(Text, { as: "p", sx: { fontSize: 0, color: 'fg.muted', mt: 0, mb: 1 }, children: ["turn ", checkpoint.turn, " \u00B7 ", checkpoint.messageCount, " message", checkpoint.messageCount === 1 ? '' : 's', " \u00B7", ' ', ago(checkpoint.createdAt, now)] }), _jsxs(Box, { sx: { display: 'flex', gap: 2, alignItems: 'center' }, children: [_jsx(Button, { size: "small", leadingVisual: HistoryIcon, disabled: busy !== null, onClick: () => void rewind(checkpoint), "data-checkpoints-rewind": checkpoint.id, children: rewinding ? 'Rewinding…' : 'Rewind' }), _jsx(IconButton, { icon: TrashIcon, size: "small", variant: "invisible", "aria-label": `Delete checkpoint ${checkpoint.label}`, disabled: busy !== null, onClick: () => void remove(checkpoint) })] })] })] }, checkpoint.id));
|
|
160
|
+
return (_jsxs(Timeline.Item, { "data-checkpoint": checkpoint.id, "data-checkpoint-label": checkpoint.label, "data-checkpoint-auto": auto ? 'true' : 'false', children: [_jsx(Timeline.Badge, { children: auto ? _jsx(HistoryIcon, {}) : _jsx(BookmarkIcon, {}) }), _jsxs(Timeline.Body, { children: [_jsxs(Box, { display: "flex", alignItems: "center", gap: 2, flexWrap: "wrap", children: [_jsx(Text, { sx: { fontWeight: 'bold', fontSize: 1 }, children: checkpoint.label }), _jsx(Label, { size: "small", variant: auto ? 'secondary' : 'accent', children: auto ? 'auto' : 'saved' })] }), _jsxs(Text, { as: "p", sx: { fontSize: 0, color: 'fg.muted', mt: 0, mb: 1 }, children: ["turn ", checkpoint.turn, " \u00B7 ", checkpoint.messageCount, " message", checkpoint.messageCount === 1 ? '' : 's', " \u00B7", ' ', ago(checkpoint.createdAt, now)] }), _jsxs(Box, { display: "flex", gap: 2, alignItems: "center", children: [_jsx(Button, { size: "small", leadingVisual: HistoryIcon, disabled: busy !== null, onClick: () => void rewind(checkpoint), "data-checkpoints-rewind": checkpoint.id, children: rewinding ? 'Rewinding…' : 'Rewind' }), _jsx(IconButton, { icon: TrashIcon, size: "small", variant: "invisible", "aria-label": `Delete checkpoint ${checkpoint.label}`, disabled: busy !== null, onClick: () => void remove(checkpoint) })] })] })] }, checkpoint.id));
|
|
172
161
|
}) }))] })] }));
|
|
173
162
|
}
|
|
174
163
|
export default CheckpointsSidebar;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { Box } from '@primer
|
|
2
|
+
import { Box } from '@datalayer/primer-addons';
|
|
3
3
|
import { DecksView } from '@datalayer/decks/plugin';
|
|
4
4
|
export default function DeckSurface(_) {
|
|
5
|
-
return (_jsx(Box, {
|
|
5
|
+
return (_jsx(Box, { height: "100%", minHeight: 0, overflow: "auto", children: _jsx(DecksView, {}) }));
|
|
6
6
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { useMemo } from 'react';
|
|
3
3
|
import { useContributions, useSignalValue } from '@datalayer/reactor/react';
|
|
4
|
-
import { Box
|
|
4
|
+
import { Box } from '@datalayer/primer-addons';
|
|
5
|
+
import { Text } from '@primer/react';
|
|
5
6
|
import { EphemeralDocument } from '../../../chat/document/EphemeralDocument';
|
|
6
7
|
import { LoopDocumentToolbar, LoopDocumentToolbarItem, LoopOpeningDocument, } from '../../core';
|
|
7
8
|
import { useEditorToolbar } from '../../core/toolbar';
|
|
@@ -30,16 +31,7 @@ export default function DocumentView({ workspace, }) {
|
|
|
30
31
|
const opening = useMemo(() => JSON.stringify((contributedOpening?.document ?? openingDocument)()), [contributedOpening]);
|
|
31
32
|
const autoFocus = contributedOpening?.autoFocus ?? true;
|
|
32
33
|
if (snapshot.state !== 'running') {
|
|
33
|
-
return (_jsx(Box, {
|
|
34
|
-
height: '100%',
|
|
35
|
-
display: 'flex',
|
|
36
|
-
alignItems: 'center',
|
|
37
|
-
justifyContent: 'center',
|
|
38
|
-
color: 'fg.muted',
|
|
39
|
-
fontSize: 1,
|
|
40
|
-
px: 4,
|
|
41
|
-
textAlign: 'center',
|
|
42
|
-
}, children: _jsx(Text, { children: "The document needs a running sandbox for its code blocks. Open the Sandbox view to see what it is doing." }) }));
|
|
34
|
+
return (_jsx(Box, { height: "100%", display: "flex", alignItems: "center", justifyContent: "center", color: "fg.muted", fontSize: 1, px: 4, textAlign: "center", children: _jsx(Text, { children: "The document needs a running sandbox for its code blocks. Open the Sandbox view to see what it is doing." }) }));
|
|
43
35
|
}
|
|
44
36
|
// A browser sandbox already owns its kernel; binding to that manager is what
|
|
45
37
|
// puts the agent's code blocks and the reader's in the same one. A server
|
|
@@ -48,7 +40,7 @@ export default function DocumentView({ workspace, }) {
|
|
|
48
40
|
// came up blank on Pyodide.
|
|
49
41
|
const browserManager = service.getServiceManager() ??
|
|
50
42
|
undefined;
|
|
51
|
-
return (_jsx(Box, {
|
|
43
|
+
return (_jsx(Box, { height: "100%", minHeight: 0, children: _jsx(EphemeralDocument
|
|
52
44
|
// The entry point owns the theme; a second provider here would fight
|
|
53
45
|
// it over BaseStyles and font tokens (§3.5, §3.6).
|
|
54
46
|
, {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useSignalValue } from '@datalayer/reactor/react';
|
|
3
|
-
import { Box
|
|
3
|
+
import { Box } from '@datalayer/primer-addons';
|
|
4
|
+
import { Text } from '@primer/react';
|
|
4
5
|
import { useOptionalSandboxService } from '../agents';
|
|
5
6
|
import { IDLE_SANDBOX_SNAPSHOT_SIGNAL } from '../../core';
|
|
6
7
|
/** How each state reads, and what colour it reads in. */
|
|
@@ -20,12 +21,6 @@ export function SandboxStatusItem() {
|
|
|
20
21
|
return null;
|
|
21
22
|
}
|
|
22
23
|
const appearance = APPEARANCE[snapshot.state] ?? APPEARANCE.idle;
|
|
23
|
-
return (_jsxs(Box, {
|
|
24
|
-
width: 8,
|
|
25
|
-
height: 8,
|
|
26
|
-
borderRadius: '50%',
|
|
27
|
-
bg: appearance.color,
|
|
28
|
-
flexShrink: 0,
|
|
29
|
-
} }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: appearance.label })] }));
|
|
24
|
+
return (_jsxs(Box, { display: "flex", alignItems: "center", gap: 1, px: 2, children: [_jsx(Box, { width: 8, height: 8, borderRadius: "50%", bg: appearance.color, flexShrink: 0 }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: appearance.label })] }));
|
|
30
25
|
}
|
|
31
26
|
export default SandboxStatusItem;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { Box } from '@primer
|
|
2
|
+
import { Box } from '@datalayer/primer-addons';
|
|
3
3
|
import { ReactorSlot } from '@datalayer/reactor/react';
|
|
4
4
|
export default function GraphView() {
|
|
5
|
-
return (_jsx(Box, {
|
|
5
|
+
return (_jsx(Box, { height: "100%", overflowY: "auto", px: 4, py: 3, children: _jsx(ReactorSlot, { slot: "graph" }) }));
|
|
6
6
|
}
|
|
@@ -20,6 +20,6 @@ export function ComposerView({ workspace, composer, }) {
|
|
|
20
20
|
const Panel = entry.value.Component;
|
|
21
21
|
return _jsx(Panel, { workspace: workspace }, entry.value.id);
|
|
22
22
|
}) })) : undefined;
|
|
23
|
-
return (_jsx(Box, {
|
|
23
|
+
return (_jsx(Box, { flex: "0 0 auto", children: _jsx(InputPrompt, { ...composer, leadingPanel: stack(above), trailingPanel: stack(below) }) }));
|
|
24
24
|
}
|
|
25
25
|
export default ComposerView;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { useEffect, useMemo, useRef } from 'react';
|
|
3
3
|
import { useContributions, useSignalValue } from '@datalayer/reactor/react';
|
|
4
|
-
import { Box
|
|
4
|
+
import { Box } from '@datalayer/primer-addons';
|
|
5
|
+
import { Text } from '@primer/react';
|
|
5
6
|
import { EphemeralNotebook } from '../../../chat/notebook/EphemeralNotebook';
|
|
6
7
|
import { LoopNotebookToolbar, LoopNotebookToolbarItem, LoopOpeningNotebook, } from '../../core';
|
|
7
8
|
import { useEditorToolbar } from '../../core/toolbar';
|
|
@@ -96,16 +97,7 @@ export default function NotebookView({ workspace, }) {
|
|
|
96
97
|
// sandbox can go away while it is on screen — say so rather than rendering a
|
|
97
98
|
// notebook wired to nothing.
|
|
98
99
|
if (snapshot.state !== 'running') {
|
|
99
|
-
return (_jsx(Box, {
|
|
100
|
-
height: '100%',
|
|
101
|
-
display: 'flex',
|
|
102
|
-
alignItems: 'center',
|
|
103
|
-
justifyContent: 'center',
|
|
104
|
-
color: 'fg.muted',
|
|
105
|
-
fontSize: 1,
|
|
106
|
-
px: 4,
|
|
107
|
-
textAlign: 'center',
|
|
108
|
-
}, children: _jsx(Text, { children: "The notebook needs a running sandbox. Open the Sandbox view to see what it is doing." }) }));
|
|
100
|
+
return (_jsx(Box, { height: "100%", display: "flex", alignItems: "center", justifyContent: "center", color: "fg.muted", fontSize: 1, px: 4, textAlign: "center", children: _jsx(Text, { children: "The notebook needs a running sandbox. Open the Sandbox view to see what it is doing." }) }));
|
|
109
101
|
}
|
|
110
102
|
// A browser sandbox already owns its kernel; binding to that manager is what
|
|
111
103
|
// puts the agent's executions and the reader's cells in the same one. A
|