@datalayer/agent-runtimes 0.0.9 → 0.0.11
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/README.md +2 -1
- package/lib/{examples/components → components}/AgentConfiguration.d.ts +54 -9
- package/lib/components/AgentConfiguration.js +585 -0
- package/lib/{examples/components → components}/FooterMetrics.d.ts +1 -2
- package/lib/{examples/components → components}/Header.d.ts +1 -6
- package/lib/{examples/components → components}/Header.js +5 -39
- package/lib/{examples/components → components}/HeaderControls.d.ts +1 -2
- package/lib/{examples/components → components}/HeaderControls.js +1 -1
- package/lib/{examples/components → components}/LexicalEditor.d.ts +2 -3
- package/lib/{examples/components → components}/LexicalEditor.js +2 -2
- package/lib/components/MainContent.d.ts +34 -0
- package/lib/{examples/components → components}/MainContent.js +18 -9
- package/lib/components/McpServerManager.d.ts +30 -0
- package/lib/components/McpServerManager.js +331 -0
- package/lib/{examples/components → components}/MockFileBrowser.d.ts +1 -2
- package/lib/{examples/components → components}/SessionTabs.d.ts +2 -3
- package/lib/{examples/components → components}/TimeTravel.d.ts +1 -2
- package/lib/components/chat/components/AgentDetails.d.ts +3 -1
- package/lib/components/chat/components/AgentDetails.js +472 -22
- package/lib/components/chat/components/Chat.d.ts +37 -3
- package/lib/components/chat/components/Chat.js +29 -10
- package/lib/components/chat/components/ChatFloating.d.ts +27 -2
- package/lib/components/chat/components/ChatFloating.js +17 -10
- package/lib/components/chat/components/ChatPopupStandalone.js +1 -1
- package/lib/components/chat/components/ChatSidebar.d.ts +1 -1
- package/lib/components/chat/components/ChatStandalone.d.ts +1 -1
- package/lib/components/chat/components/ChatStandalone.js +1 -1
- package/lib/components/chat/components/ContextDistribution.d.ts +70 -6
- package/lib/components/chat/components/ContextDistribution.js +13 -6
- package/lib/components/chat/components/ContextInspector.d.ts +81 -0
- package/lib/components/chat/components/ContextInspector.js +263 -0
- package/lib/components/chat/components/ContextPanel.d.ts +112 -0
- package/lib/components/chat/components/ContextPanel.js +368 -0
- package/lib/components/chat/components/base/ChatBase.d.ts +74 -19
- package/lib/components/chat/components/base/ChatBase.js +296 -37
- package/lib/components/chat/components/index.d.ts +3 -1
- package/lib/components/chat/components/index.js +2 -0
- package/lib/components/chat/extensions/ExtensionRegistry.d.ts +1 -1
- package/lib/components/chat/extensions/index.d.ts +1 -0
- package/lib/components/chat/index.d.ts +3 -3
- package/lib/components/chat/protocols/AGUIAdapter.js +24 -4
- package/lib/components/chat/protocols/VercelAIAdapter.js +35 -1
- package/lib/components/chat/store/chatStore.d.ts +2 -3
- package/lib/components/chat/store/conversationStore.d.ts +83 -0
- package/lib/components/chat/store/conversationStore.js +174 -0
- package/lib/components/chat/store/index.d.ts +2 -1
- package/lib/components/chat/store/index.js +1 -0
- package/lib/components/chat/types/inference.d.ts +17 -0
- package/lib/components/chat/types/protocol.d.ts +10 -0
- package/lib/components/index.d.ts +23 -0
- package/lib/components/index.js +11 -0
- package/lib/config/agents/code-ai/agents.d.ts +25 -0
- package/lib/config/agents/code-ai/agents.js +70 -0
- package/lib/config/agents/code-ai/index.d.ts +1 -0
- package/lib/config/agents/code-ai/index.js +5 -0
- package/lib/config/agents/codemode-paper/agents.d.ts +29 -0
- package/lib/config/agents/codemode-paper/agents.js +288 -0
- package/lib/config/agents/codemode-paper/index.d.ts +1 -0
- package/lib/config/agents/codemode-paper/index.js +5 -0
- package/lib/config/agents/datalayer-ai/agents.d.ts +29 -0
- package/lib/config/agents/datalayer-ai/agents.js +267 -0
- package/lib/config/agents/datalayer-ai/index.d.ts +1 -0
- package/lib/config/agents/datalayer-ai/index.js +5 -0
- package/lib/config/agents/index.d.ts +19 -0
- package/lib/config/agents/index.js +38 -0
- package/lib/config/envvars.d.ts +28 -0
- package/lib/config/envvars.js +115 -0
- package/lib/config/index.d.ts +5 -0
- package/lib/config/index.js +9 -0
- package/lib/config/mcpServers.d.ts +18 -0
- package/lib/config/mcpServers.js +153 -0
- package/lib/config/skills.d.ts +27 -0
- package/lib/config/skills.js +60 -0
- package/lib/{lib → config}/utils.d.ts +1 -1
- package/lib/{lib → config}/utils.js +2 -2
- package/lib/examples/AgentRuntimeLexical2Example.d.ts +1 -0
- package/lib/examples/AgentRuntimeLexical2Example.js +3 -2
- package/lib/examples/AgentRuntimeLexicalExample.d.ts +1 -0
- package/lib/examples/AgentRuntimeLexicalExample.js +5 -3
- package/lib/examples/AgentRuntimeLexicalSidebarExample.d.ts +1 -0
- package/lib/examples/AgentRuntimeLexicalSidebarExample.js +3 -3
- package/lib/examples/AgentRuntimeNotebookExample.js +1 -1
- package/lib/examples/AgentSpaceFormExample.d.ts +2 -2
- package/lib/examples/AgentSpaceFormExample.js +215 -35
- package/lib/examples/CopilotKitLexicalExample.d.ts +1 -0
- package/lib/examples/CopilotKitLexicalExample.js +3 -2
- package/lib/examples/index.d.ts +1 -0
- package/lib/examples/stores/notebooks/NotebookExample2.ipynb.json +43 -43
- package/lib/hooks/useAGUI.d.ts +1 -1
- package/lib/hooks/useAGUI.js +1 -1
- package/lib/identity/types.d.ts +1 -1
- package/lib/index.d.ts +2 -0
- package/lib/index.js +1 -0
- package/lib/runtime/index.d.ts +3 -0
- package/lib/runtime/runtimeStore.d.ts +3 -4
- package/lib/runtime/useAgentConnection.d.ts +2 -3
- package/lib/runtime/useAgentRuntime.d.ts +2 -3
- package/lib/stories/Cell.stories.js +1 -1
- package/lib/tools/adapters/agent-runtimes/notebookHooks.js +1 -0
- package/lib/tools/adapters/copilotkit/notebookHooks.js +1 -0
- package/lib/types.d.ts +158 -0
- package/package.json +5 -6
- package/scripts/apply-patches.sh +1 -1
- package/scripts/codegen/generate_agents.py +863 -0
- package/scripts/codegen/generate_envvars.py +302 -0
- package/scripts/codegen/generate_mcp_servers.py +436 -0
- package/scripts/codegen/generate_skills.py +334 -0
- package/scripts/download-ai-elements.py +35 -20
- package/scripts/sync-jupyter.sh +6 -0
- package/lib/components/ui/accordion.d.ts +0 -7
- package/lib/components/ui/accordion.js +0 -22
- package/lib/components/ui/alert-dialog.d.ts +0 -14
- package/lib/components/ui/alert-dialog.js +0 -43
- package/lib/components/ui/alert.d.ts +0 -9
- package/lib/components/ui/alert.js +0 -24
- package/lib/components/ui/aspect-ratio.d.ts +0 -3
- package/lib/components/ui/aspect-ratio.js +0 -11
- package/lib/components/ui/avatar.d.ts +0 -6
- package/lib/components/ui/avatar.js +0 -18
- package/lib/components/ui/badge.d.ts +0 -9
- package/lib/components/ui/badge.js +0 -22
- package/lib/components/ui/breadcrumb.d.ts +0 -11
- package/lib/components/ui/breadcrumb.js +0 -27
- package/lib/components/ui/button-group.d.ts +0 -11
- package/lib/components/ui/button-group.js +0 -31
- package/lib/components/ui/button.d.ts +0 -13
- package/lib/components/ui/button.js +0 -39
- package/lib/components/ui/calendar.d.ts +0 -8
- package/lib/components/ui/calendar.js +0 -80
- package/lib/components/ui/card.d.ts +0 -9
- package/lib/components/ui/card.js +0 -24
- package/lib/components/ui/carousel.d.ts +0 -19
- package/lib/components/ui/carousel.js +0 -95
- package/lib/components/ui/chart.d.ts +0 -53
- package/lib/components/ui/chart.js +0 -136
- package/lib/components/ui/checkbox.d.ts +0 -4
- package/lib/components/ui/checkbox.js +0 -13
- package/lib/components/ui/collapsible.d.ts +0 -5
- package/lib/components/ui/collapsible.js +0 -17
- package/lib/components/ui/command.d.ts +0 -18
- package/lib/components/ui/command.js +0 -38
- package/lib/components/ui/context-menu.d.ts +0 -25
- package/lib/components/ui/context-menu.js +0 -55
- package/lib/components/ui/dialog.d.ts +0 -15
- package/lib/components/ui/dialog.js +0 -40
- package/lib/components/ui/drawer.d.ts +0 -13
- package/lib/components/ui/drawer.js +0 -39
- package/lib/components/ui/dropdown-menu.d.ts +0 -25
- package/lib/components/ui/dropdown-menu.js +0 -55
- package/lib/components/ui/empty.d.ts +0 -11
- package/lib/components/ui/empty.js +0 -37
- package/lib/components/ui/field.d.ts +0 -24
- package/lib/components/ui/field.js +0 -80
- package/lib/components/ui/form.d.ts +0 -24
- package/lib/components/ui/form.js +0 -63
- package/lib/components/ui/hover-card.d.ts +0 -6
- package/lib/components/ui/hover-card.js +0 -18
- package/lib/components/ui/input-group.d.ts +0 -19
- package/lib/components/ui/input-group.js +0 -69
- package/lib/components/ui/input-otp.d.ts +0 -11
- package/lib/components/ui/input-otp.js +0 -25
- package/lib/components/ui/input.d.ts +0 -3
- package/lib/components/ui/input.js +0 -6
- package/lib/components/ui/item.d.ts +0 -23
- package/lib/components/ui/item.js +0 -66
- package/lib/components/ui/kbd.d.ts +0 -3
- package/lib/components/ui/kbd.js +0 -13
- package/lib/components/ui/label.d.ts +0 -4
- package/lib/components/ui/label.js +0 -12
- package/lib/components/ui/menubar.d.ts +0 -26
- package/lib/components/ui/menubar.js +0 -58
- package/lib/components/ui/navigation-menu.d.ts +0 -14
- package/lib/components/ui/navigation-menu.js +0 -31
- package/lib/components/ui/pagination.d.ts +0 -13
- package/lib/components/ui/pagination.js +0 -29
- package/lib/components/ui/popover.d.ts +0 -7
- package/lib/components/ui/popover.js +0 -21
- package/lib/components/ui/progress.d.ts +0 -4
- package/lib/components/ui/progress.js +0 -12
- package/lib/components/ui/radio-group.d.ts +0 -5
- package/lib/components/ui/radio-group.js +0 -16
- package/lib/components/ui/resizable.d.ts +0 -8
- package/lib/components/ui/resizable.js +0 -19
- package/lib/components/ui/scroll-area.d.ts +0 -5
- package/lib/components/ui/scroll-area.js +0 -17
- package/lib/components/ui/select.d.ts +0 -15
- package/lib/components/ui/select.js +0 -42
- package/lib/components/ui/separator.d.ts +0 -4
- package/lib/components/ui/separator.js +0 -12
- package/lib/components/ui/sheet.d.ts +0 -13
- package/lib/components/ui/sheet.js +0 -44
- package/lib/components/ui/sidebar.d.ts +0 -69
- package/lib/components/ui/sidebar.js +0 -216
- package/lib/components/ui/skeleton.d.ts +0 -2
- package/lib/components/ui/skeleton.js +0 -10
- package/lib/components/ui/slider.d.ts +0 -4
- package/lib/components/ui/slider.js +0 -18
- package/lib/components/ui/sonner.d.ts +0 -3
- package/lib/components/ui/sonner.js +0 -25
- package/lib/components/ui/spinner.d.ts +0 -2
- package/lib/components/ui/spinner.js +0 -11
- package/lib/components/ui/switch.d.ts +0 -4
- package/lib/components/ui/switch.js +0 -12
- package/lib/components/ui/table.d.ts +0 -10
- package/lib/components/ui/table.js +0 -32
- package/lib/components/ui/tabs.d.ts +0 -7
- package/lib/components/ui/tabs.js +0 -21
- package/lib/components/ui/textarea.d.ts +0 -3
- package/lib/components/ui/textarea.js +0 -6
- package/lib/components/ui/toast.d.ts +0 -15
- package/lib/components/ui/toast.js +0 -38
- package/lib/components/ui/toaster.d.ts +0 -1
- package/lib/components/ui/toaster.js +0 -14
- package/lib/components/ui/toggle-group.d.ts +0 -9
- package/lib/components/ui/toggle-group.js +0 -26
- package/lib/components/ui/toggle.d.ts +0 -9
- package/lib/components/ui/toggle.js +0 -30
- package/lib/components/ui/tooltip.d.ts +0 -7
- package/lib/components/ui/tooltip.js +0 -21
- package/lib/components/vercel-ai-elements/artifact.d.ts +0 -23
- package/lib/components/vercel-ai-elements/artifact.js +0 -24
- package/lib/components/vercel-ai-elements/code-block.d.ts +0 -17
- package/lib/components/vercel-ai-elements/code-block.js +0 -94
- package/lib/components/vercel-ai-elements/conversation.d.ts +0 -15
- package/lib/components/vercel-ai-elements/conversation.js +0 -21
- package/lib/components/vercel-ai-elements/loader.d.ts +0 -5
- package/lib/components/vercel-ai-elements/loader.js +0 -8
- package/lib/components/vercel-ai-elements/message.d.ts +0 -46
- package/lib/components/vercel-ai-elements/message.js +0 -109
- package/lib/components/vercel-ai-elements/model-selector.d.ts +0 -35
- package/lib/components/vercel-ai-elements/model-selector.js +0 -22
- package/lib/components/vercel-ai-elements/prompt-input.d.ts +0 -195
- package/lib/components/vercel-ai-elements/prompt-input.js +0 -589
- package/lib/components/vercel-ai-elements/reasoning.d.ts +0 -26
- package/lib/components/vercel-ai-elements/reasoning.js +0 -80
- package/lib/components/vercel-ai-elements/shimmer.d.ts +0 -9
- package/lib/components/vercel-ai-elements/shimmer.js +0 -22
- package/lib/components/vercel-ai-elements/sources.d.ts +0 -12
- package/lib/components/vercel-ai-elements/sources.js +0 -13
- package/lib/components/vercel-ai-elements/suggestion.d.ts +0 -10
- package/lib/components/vercel-ai-elements/suggestion.js +0 -16
- package/lib/components/vercel-ai-elements/tool.d.ts +0 -23
- package/lib/components/vercel-ai-elements/tool.js +0 -52
- package/lib/examples/components/AgentConfiguration.js +0 -382
- package/lib/examples/components/MainContent.d.ts +0 -19
- package/lib/examples/components/index.d.ts +0 -10
- package/lib/examples/components/index.js +0 -13
- package/lib/examples/vercel-ai-elements/VercelAiElementsShowcase.d.ts +0 -12
- package/lib/examples/vercel-ai-elements/VercelAiElementsShowcase.js +0 -69
- package/lib/examples/vercel-ai-elements/components/ArtifactShowcase.d.ts +0 -1
- package/lib/examples/vercel-ai-elements/components/ArtifactShowcase.js +0 -85
- package/lib/examples/vercel-ai-elements/components/CodeBlockShowcase.d.ts +0 -1
- package/lib/examples/vercel-ai-elements/components/CodeBlockShowcase.js +0 -62
- package/lib/examples/vercel-ai-elements/components/ConversationShowcase.d.ts +0 -1
- package/lib/examples/vercel-ai-elements/components/ConversationShowcase.js +0 -51
- package/lib/examples/vercel-ai-elements/components/LoaderShowcase.d.ts +0 -1
- package/lib/examples/vercel-ai-elements/components/LoaderShowcase.js +0 -9
- package/lib/examples/vercel-ai-elements/components/MessageShowcase.d.ts +0 -1
- package/lib/examples/vercel-ai-elements/components/MessageShowcase.js +0 -56
- package/lib/examples/vercel-ai-elements/components/ModelSelectorShowcase.d.ts +0 -1
- package/lib/examples/vercel-ai-elements/components/ModelSelectorShowcase.js +0 -50
- package/lib/examples/vercel-ai-elements/components/PromptInputShowcase.d.ts +0 -1
- package/lib/examples/vercel-ai-elements/components/PromptInputShowcase.js +0 -16
- package/lib/examples/vercel-ai-elements/components/ReasoningShowcase.d.ts +0 -1
- package/lib/examples/vercel-ai-elements/components/ReasoningShowcase.js +0 -72
- package/lib/examples/vercel-ai-elements/components/ShimmerShowcase.d.ts +0 -1
- package/lib/examples/vercel-ai-elements/components/ShimmerShowcase.js +0 -9
- package/lib/examples/vercel-ai-elements/components/SourcesShowcase.d.ts +0 -1
- package/lib/examples/vercel-ai-elements/components/SourcesShowcase.js +0 -43
- package/lib/examples/vercel-ai-elements/components/SuggestionShowcase.d.ts +0 -1
- package/lib/examples/vercel-ai-elements/components/SuggestionShowcase.js +0 -31
- package/lib/examples/vercel-ai-elements/components/ToolShowcase.d.ts +0 -1
- package/lib/examples/vercel-ai-elements/components/ToolShowcase.js +0 -54
- package/lib/examples/vercel-ai-elements/index.d.ts +0 -13
- package/lib/examples/vercel-ai-elements/index.js +0 -17
- package/lib/examples/vercel-ai-elements/main.d.ts +0 -1
- package/lib/examples/vercel-ai-elements/main.js +0 -9
- package/lib/examples/vercel-ai-elements/showcase.css +0 -128
- package/lib/hooks/useToast.d.ts +0 -44
- package/lib/hooks/useToast.js +0 -128
- package/patches/@datalayer+jupyter-lexical+1.0.8.patch +0 -11628
- package/patches/@datalayer+jupyter-react+2.0.2.patch +0 -5338
- package/style/showcase-vercel-ai.css +0 -137
- /package/lib/{examples/components → components}/FooterMetrics.js +0 -0
- /package/lib/{examples/components → components}/MockFileBrowser.js +0 -0
- /package/lib/{examples/components → components}/SessionTabs.js +0 -0
- /package/lib/{examples/components → components}/TimeTravel.js +0 -0
- /package/lib/{models → types}/AIAgent.d.ts +0 -0
- /package/lib/{models → types}/AIAgent.js +0 -0
- /package/lib/{models → types}/index.d.ts +0 -0
- /package/lib/{models → types}/index.js +0 -0
|
@@ -3,9 +3,9 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
* Copyright (c) 2025-2026 Datalayer, Inc.
|
|
4
4
|
* Distributed under the terms of the Modified BSD License.
|
|
5
5
|
*/
|
|
6
|
-
import { useState
|
|
7
|
-
import { Text, Button, PageLayout,
|
|
8
|
-
import { ZapIcon, ListUnorderedIcon,
|
|
6
|
+
import { useState } from 'react';
|
|
7
|
+
import { Text, Button, PageLayout, AvatarStack, Avatar, Spinner, TextInput, FormControl, IconButton, } from '@primer/react';
|
|
8
|
+
import { ZapIcon, ListUnorderedIcon, PlayIcon, PauseIcon, } from '@primer/octicons-react';
|
|
9
9
|
import { Box } from '@datalayer/primer-addons';
|
|
10
10
|
import ReactECharts from 'echarts-for-react';
|
|
11
11
|
import { SessionTabs } from './SessionTabs';
|
|
@@ -112,15 +112,12 @@ const OPTIMIZED_CONTEXT_DATA = {
|
|
|
112
112
|
* Main header for the agent runtime interface with session tabs,
|
|
113
113
|
* toggle switches, controls, and optional context treemap.
|
|
114
114
|
*/
|
|
115
|
-
export const Header = ({ activeSession, agentName, agentDescription, agentStatus,
|
|
115
|
+
export const Header = ({ activeSession, agentName, agentDescription, agentStatus, showContextTree, isNewAgent = false, isConfigured = false, onSessionChange, onToggleContextTree, onToggleStatus, }) => {
|
|
116
116
|
const [isOptimizing, setIsOptimizing] = useState(false);
|
|
117
117
|
const [contextData, setContextData] = useState(MOCK_CONTEXT_DATA);
|
|
118
118
|
const [totalTokens, setTotalTokens] = useState('1.52M');
|
|
119
119
|
const [showDetails, setShowDetails] = useState(false);
|
|
120
120
|
const [showAvatarView, setShowAvatarView] = useState(false);
|
|
121
|
-
const [openOverlay, setOpenOverlay] = useState(null);
|
|
122
|
-
const richEditorRef = useRef(null);
|
|
123
|
-
const durableRef = useRef(null);
|
|
124
121
|
const handleOptimize = () => {
|
|
125
122
|
setIsOptimizing(true);
|
|
126
123
|
setTimeout(() => {
|
|
@@ -136,38 +133,7 @@ export const Header = ({ activeSession, agentName, agentDescription, agentStatus
|
|
|
136
133
|
py: 2,
|
|
137
134
|
}, children: [agentName && (_jsx(SessionTabs, { sessions: MOCK_SESSIONS, activeSession: activeSession, agentName: agentName, agentDescription: agentDescription, onSessionChange: onSessionChange, onAddSession: () => {
|
|
138
135
|
/* Add session */
|
|
139
|
-
} })), _jsxs(Box, { sx: {
|
|
140
|
-
display: 'flex',
|
|
141
|
-
alignItems: 'center',
|
|
142
|
-
gap: 3,
|
|
143
|
-
marginLeft: 'auto',
|
|
144
|
-
}, children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(ToggleSwitch, { size: "small", checked: richEditor, onClick: () => onRichEditorChange(!richEditor), "aria-labelledby": "rich-editor-label", disabled: isNewAgent || !isConfigured }), _jsx(Text, { id: "rich-editor-label", sx: { fontSize: 0 }, children: "Rich Editor" }), _jsx(IconButton, { ref: richEditorRef, icon: InfoIcon, size: "small", variant: "invisible", "aria-label": "Rich Editor info", onClick: () => setOpenOverlay(openOverlay === 'richEditor' ? null : 'richEditor') }), _jsx(AnchoredOverlay, { open: openOverlay === 'richEditor', onOpen: () => setOpenOverlay('richEditor'), onClose: () => setOpenOverlay(null), renderAnchor: () => _jsx("span", {}), anchorRef: richEditorRef, children: _jsxs(Box, { sx: {
|
|
145
|
-
p: 3,
|
|
146
|
-
maxWidth: '300px',
|
|
147
|
-
bg: 'canvas.overlay',
|
|
148
|
-
border: '1px solid',
|
|
149
|
-
borderColor: 'border.default',
|
|
150
|
-
borderRadius: 2,
|
|
151
|
-
boxShadow: 'shadow.large',
|
|
152
|
-
}, children: [_jsx(Text, { sx: {
|
|
153
|
-
fontSize: 0,
|
|
154
|
-
display: 'block',
|
|
155
|
-
mb: 1,
|
|
156
|
-
fontWeight: 'bold',
|
|
157
|
-
}, children: "Rich Editor" }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "Enable rich text editing with formatting options, markdown support, and visual enhancements for a better editing experience." })] }) })] }), _jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(ToggleSwitch, { size: "small", checked: durable, onClick: () => onDurableChange(!durable), "aria-labelledby": "durable-label", disabled: isNewAgent || !isConfigured }), _jsx(Text, { id: "durable-label", sx: { fontSize: 0 }, children: "Durable" }), _jsx(IconButton, { ref: durableRef, icon: InfoIcon, size: "small", variant: "invisible", "aria-label": "Durable info", onClick: () => setOpenOverlay(openOverlay === 'durable' ? null : 'durable') }), _jsx(AnchoredOverlay, { open: openOverlay === 'durable', onOpen: () => setOpenOverlay('durable'), onClose: () => setOpenOverlay(null), renderAnchor: () => _jsx("span", {}), anchorRef: durableRef, children: _jsxs(Box, { sx: {
|
|
158
|
-
p: 3,
|
|
159
|
-
maxWidth: '300px',
|
|
160
|
-
bg: 'canvas.overlay',
|
|
161
|
-
border: '1px solid',
|
|
162
|
-
borderColor: 'border.default',
|
|
163
|
-
borderRadius: 2,
|
|
164
|
-
boxShadow: 'shadow.large',
|
|
165
|
-
}, children: [_jsx(Text, { sx: {
|
|
166
|
-
fontSize: 0,
|
|
167
|
-
display: 'block',
|
|
168
|
-
mb: 1,
|
|
169
|
-
fontWeight: 'bold',
|
|
170
|
-
}, children: "Durable" }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "Persist agent state and conversation history across sessions. Your work is automatically saved and restored when you return." })] }) })] })] }), agentName && (_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [agentStatus && onToggleStatus && (_jsx(IconButton, { "aria-label": agentStatus === 'running' ? 'Pause agent' : 'Play agent', icon: agentStatus === 'running' ? PauseIcon : PlayIcon, onClick: onToggleStatus, variant: "invisible", size: "small", sx: {
|
|
136
|
+
} })), agentName && (_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [agentStatus && onToggleStatus && (_jsx(IconButton, { "aria-label": agentStatus === 'running' ? 'Pause agent' : 'Play agent', icon: agentStatus === 'running' ? PauseIcon : PlayIcon, onClick: onToggleStatus, variant: "invisible", size: "small", sx: {
|
|
171
137
|
color: agentStatus === 'running' ? 'attention.fg' : 'success.fg',
|
|
172
138
|
} })), _jsx(HeaderControls, { onToggleContextTree: onToggleContextTree })] })), agentName && (_jsx(Box, { onClick: () => setShowAvatarView(!showAvatarView), sx: { cursor: 'pointer' }, children: _jsxs(AvatarStack, { size: 24, disableExpand: true, children: [_jsx(Avatar, { alt: "Primer logo", src: "https://avatars.githubusercontent.com/primer" }), _jsx(Avatar, { alt: "GitHub logo", src: "https://avatars.githubusercontent.com/github" }), _jsx(Avatar, { alt: "Atom logo", src: "https://avatars.githubusercontent.com/atom" }), _jsx(Avatar, { alt: "GitHub Desktop logo", src: "https://avatars.githubusercontent.com/desktop" })] }) }))] }), agentName && showContextTree && (_jsxs(Box, { sx: {
|
|
173
139
|
mt: 2,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
interface HeaderControlsProps {
|
|
2
|
+
export interface HeaderControlsProps {
|
|
3
3
|
onToggleContextTree: () => void;
|
|
4
4
|
}
|
|
5
5
|
/**
|
|
@@ -8,4 +8,3 @@ interface HeaderControlsProps {
|
|
|
8
8
|
* Contains the context toggle sparkline.
|
|
9
9
|
*/
|
|
10
10
|
export declare const HeaderControls: React.FC<HeaderControlsProps>;
|
|
11
|
-
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { Box } from '@datalayer/primer-addons';
|
|
3
|
-
import { Sparklines, SparklinesLine } from '
|
|
3
|
+
import { Sparklines, SparklinesLine } from './sparklines';
|
|
4
4
|
/**
|
|
5
5
|
* Header Controls Component
|
|
6
6
|
*
|
|
@@ -13,8 +13,8 @@ import 'prismjs/components/prism-swift';
|
|
|
13
13
|
import React from 'react';
|
|
14
14
|
import type { ServiceManager } from '@jupyterlab/services';
|
|
15
15
|
import '@datalayer/jupyter-lexical/style/index.css';
|
|
16
|
-
import '../lexical/lexical-theme.css';
|
|
17
|
-
interface LexicalEditorProps {
|
|
16
|
+
import '../examples/lexical/lexical-theme.css';
|
|
17
|
+
export interface LexicalEditorProps {
|
|
18
18
|
content?: string;
|
|
19
19
|
serviceManager?: ServiceManager.IManager;
|
|
20
20
|
}
|
|
@@ -24,4 +24,3 @@ interface LexicalEditorProps {
|
|
|
24
24
|
* Rich text editor with Simple integration.
|
|
25
25
|
*/
|
|
26
26
|
export declare const LexicalEditor: React.FC<LexicalEditorProps>;
|
|
27
|
-
export {};
|
|
@@ -34,9 +34,9 @@ import { LinkPlugin } from '@lexical/react/LexicalLinkPlugin';
|
|
|
34
34
|
import { Box } from '@datalayer/primer-addons';
|
|
35
35
|
import { JupyterReactTheme, useJupyter } from '@datalayer/jupyter-react';
|
|
36
36
|
import { ComponentPickerMenuPlugin, JupyterCellPlugin, JupyterInputOutputPlugin, DraggableBlockPlugin, ImagesPlugin, HorizontalRulePlugin, EquationsPlugin, YouTubePlugin, AutoLinkPlugin, AutoEmbedPlugin, LexicalConfigProvider, LexicalStatePlugin, FloatingTextFormatToolbarPlugin, CodeActionMenuPlugin, ListMaxIndentLevelPlugin, } from '@datalayer/jupyter-lexical';
|
|
37
|
-
import { editorConfig } from '../lexical/editorConfig';
|
|
37
|
+
import { editorConfig } from '../examples/lexical/editorConfig';
|
|
38
38
|
import '@datalayer/jupyter-lexical/style/index.css';
|
|
39
|
-
import '../lexical/lexical-theme.css';
|
|
39
|
+
import '../examples/lexical/lexical-theme.css';
|
|
40
40
|
const LEXICAL_ID = 'agent-runtime-lexical-editor';
|
|
41
41
|
const INITIAL_CONTENT = undefined;
|
|
42
42
|
/**
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { ServiceManager } from '@jupyterlab/services';
|
|
3
|
+
import { type McpServerSelection } from './McpServerManager';
|
|
4
|
+
export interface MainContentProps {
|
|
5
|
+
showNotebook: boolean;
|
|
6
|
+
timeTravel: number;
|
|
7
|
+
onTimeTravelChange: (value: number) => void;
|
|
8
|
+
richEditor: boolean;
|
|
9
|
+
notebookFile?: string;
|
|
10
|
+
lexicalFile?: string;
|
|
11
|
+
isNewAgent?: boolean;
|
|
12
|
+
serviceManager?: ServiceManager.IManager;
|
|
13
|
+
/** Base URL for MCP API */
|
|
14
|
+
baseUrl?: string;
|
|
15
|
+
/** Agent ID for updating the running agent */
|
|
16
|
+
agentId?: string;
|
|
17
|
+
/** Whether codemode is enabled */
|
|
18
|
+
enableCodemode?: boolean;
|
|
19
|
+
/** Currently selected MCP servers */
|
|
20
|
+
selectedMcpServers?: McpServerSelection[];
|
|
21
|
+
/** Callback when MCP server selection changes */
|
|
22
|
+
onSelectedMcpServersChange?: (servers: McpServerSelection[]) => void;
|
|
23
|
+
/** Callback when MCP servers are added/removed (for codemode regeneration) */
|
|
24
|
+
onMcpServersChange?: () => void;
|
|
25
|
+
/** Whether the agent is configured and running */
|
|
26
|
+
isConfigured?: boolean;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Main Content Component
|
|
30
|
+
*
|
|
31
|
+
* Displays the main content area with Simple notebook viewer or Lexical editor and time travel.
|
|
32
|
+
* When an agent is running (isConfigured=true), also shows the MCP Server Manager for runtime management.
|
|
33
|
+
*/
|
|
34
|
+
export declare const MainContent: React.FC<MainContentProps>;
|
|
@@ -7,16 +7,18 @@ import React from 'react';
|
|
|
7
7
|
import { Text } from '@primer/react';
|
|
8
8
|
import { Box } from '@datalayer/primer-addons';
|
|
9
9
|
import { JupyterReactTheme, Viewer } from '@datalayer/jupyter-react';
|
|
10
|
-
import matplotlib from '../stores/notebooks/Matplotlib.ipynb.json';
|
|
11
|
-
import emptyNotebook from '../stores/notebooks/Empty.ipynb.json';
|
|
12
10
|
import { TimeTravel } from './TimeTravel';
|
|
13
11
|
import { LexicalEditor } from './LexicalEditor';
|
|
12
|
+
import { McpServerManager } from './McpServerManager';
|
|
13
|
+
import matplotlib from '../examples/stores/notebooks/NotebookExample2.ipynb.json';
|
|
14
|
+
import emptyNotebook from '../examples/stores/notebooks/Empty.ipynb.json';
|
|
14
15
|
/**
|
|
15
16
|
* Main Content Component
|
|
16
17
|
*
|
|
17
18
|
* Displays the main content area with Simple notebook viewer or Lexical editor and time travel.
|
|
19
|
+
* When an agent is running (isConfigured=true), also shows the MCP Server Manager for runtime management.
|
|
18
20
|
*/
|
|
19
|
-
export const MainContent = ({ showNotebook, timeTravel, onTimeTravelChange, richEditor, notebookFile, lexicalFile, isNewAgent, serviceManager, }) => {
|
|
21
|
+
export const MainContent = ({ showNotebook, timeTravel, onTimeTravelChange, richEditor, notebookFile, lexicalFile, isNewAgent, serviceManager, baseUrl, agentId, enableCodemode, selectedMcpServers, onSelectedMcpServersChange, onMcpServersChange, isConfigured, }) => {
|
|
20
22
|
// Use the provided notebook or fall back to matplotlib demo
|
|
21
23
|
const [notebookData, setNotebookData] = React.useState(matplotlib);
|
|
22
24
|
const [lexicalContent, setLexicalContent] = React.useState(undefined);
|
|
@@ -59,10 +61,17 @@ export const MainContent = ({ showNotebook, timeTravel, onTimeTravelChange, rich
|
|
|
59
61
|
setLexicalContent(undefined);
|
|
60
62
|
}
|
|
61
63
|
}, [lexicalFile, isNewAgent]);
|
|
62
|
-
return (
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
64
|
+
return (_jsxs(Box, { sx: { height: '100%', overflow: 'auto', padding: 3 }, children: [isConfigured && baseUrl && (_jsx(Box, { sx: {
|
|
65
|
+
mb: 4,
|
|
66
|
+
p: 3,
|
|
67
|
+
bg: 'canvas.subtle',
|
|
68
|
+
borderRadius: 2,
|
|
69
|
+
border: '1px solid',
|
|
70
|
+
borderColor: 'border.default',
|
|
71
|
+
}, children: _jsx(McpServerManager, { baseUrl: baseUrl, agentId: agentId, enableCodemode: enableCodemode, selectedServers: selectedMcpServers, onSelectedServersChange: onSelectedMcpServersChange, onServersChange: onMcpServersChange, disabled: false }) })), showNotebook ? (_jsxs(_Fragment, { children: [richEditor ? (_jsx(LexicalEditor, { serviceManager: serviceManager, content: lexicalContent })) : (_jsx(JupyterReactTheme, { children: _jsx(Viewer, { nbformat: notebookData, outputs: true }) })), !isNewAgent && (_jsx(TimeTravel, { value: timeTravel, onChange: onTimeTravelChange }))] })) : (_jsx(Box, { sx: {
|
|
72
|
+
display: 'flex',
|
|
73
|
+
alignItems: 'center',
|
|
74
|
+
justifyContent: 'center',
|
|
75
|
+
height: '100%',
|
|
76
|
+
}, children: _jsx(Text, { sx: { color: 'fg.muted' }, children: "Select a file to view or create a new notebook" }) }))] }));
|
|
68
77
|
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { McpServerSelection } from './chat/types';
|
|
2
|
+
export type { McpServerSelection };
|
|
3
|
+
export interface McpServerManagerProps {
|
|
4
|
+
/** Base URL for the API */
|
|
5
|
+
baseUrl: string;
|
|
6
|
+
/** Agent ID for updating the running agent's MCP servers */
|
|
7
|
+
agentId?: string;
|
|
8
|
+
/** Whether codemode is enabled - affects tool regeneration on add/remove */
|
|
9
|
+
enableCodemode?: boolean;
|
|
10
|
+
/** Currently selected MCP servers (for selection mode) */
|
|
11
|
+
selectedServers?: McpServerSelection[];
|
|
12
|
+
/** Callback when server selection changes */
|
|
13
|
+
onSelectedServersChange?: (servers: McpServerSelection[]) => void;
|
|
14
|
+
/** Callback when MCP servers are added/removed (for codemode tool regeneration) */
|
|
15
|
+
onServersChange?: () => void;
|
|
16
|
+
/** Whether the manager is disabled (e.g., for existing agents) */
|
|
17
|
+
disabled?: boolean;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* McpServerManager - Manage MCP servers for agent spaces
|
|
21
|
+
*
|
|
22
|
+
* Features:
|
|
23
|
+
* - View MCP Catalog servers (predefined, can be enabled on-demand)
|
|
24
|
+
* - Add/Enable servers from the catalog
|
|
25
|
+
* - Remove/Disable active catalog servers
|
|
26
|
+
* - View MCP Config servers from mcp.json (read-only, auto-started)
|
|
27
|
+
* - Trigger codemode tool regeneration on changes
|
|
28
|
+
*/
|
|
29
|
+
export declare function McpServerManager({ baseUrl, agentId, enableCodemode, selectedServers, onSelectedServersChange, onServersChange, disabled, }: McpServerManagerProps): import("react/jsx-runtime").JSX.Element;
|
|
30
|
+
export default McpServerManager;
|
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright (c) 2025-2026 Datalayer, Inc.
|
|
4
|
+
* Distributed under the terms of the Modified BSD License.
|
|
5
|
+
*/
|
|
6
|
+
import { useCallback, useMemo, useState } from 'react';
|
|
7
|
+
import { Text, Button, Flash, Label, Spinner, IconButton, TextInput, } from '@primer/react';
|
|
8
|
+
import { ToolsIcon, PlusIcon, TrashIcon, SyncIcon, ServerIcon, CheckIcon, SearchIcon, } from '@primer/octicons-react';
|
|
9
|
+
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
|
10
|
+
import { Box } from '@datalayer/primer-addons';
|
|
11
|
+
/**
|
|
12
|
+
* McpServerManager - Manage MCP servers for agent spaces
|
|
13
|
+
*
|
|
14
|
+
* Features:
|
|
15
|
+
* - View MCP Catalog servers (predefined, can be enabled on-demand)
|
|
16
|
+
* - Add/Enable servers from the catalog
|
|
17
|
+
* - Remove/Disable active catalog servers
|
|
18
|
+
* - View MCP Config servers from mcp.json (read-only, auto-started)
|
|
19
|
+
* - Trigger codemode tool regeneration on changes
|
|
20
|
+
*/
|
|
21
|
+
export function McpServerManager({ baseUrl, agentId, enableCodemode = false, selectedServers = [], onSelectedServersChange, onServersChange, disabled = false, }) {
|
|
22
|
+
const queryClient = useQueryClient();
|
|
23
|
+
const [searchQuery, setSearchQuery] = useState('');
|
|
24
|
+
const [error, setError] = useState(null);
|
|
25
|
+
// Fetch all available servers (catalog + mcp.json running servers)
|
|
26
|
+
const catalogQuery = useQuery({
|
|
27
|
+
queryKey: ['mcp-available', baseUrl],
|
|
28
|
+
queryFn: async () => {
|
|
29
|
+
const response = await fetch(`${baseUrl}/api/v1/mcp/servers/available`);
|
|
30
|
+
if (!response.ok) {
|
|
31
|
+
throw new Error('Failed to fetch available MCP servers');
|
|
32
|
+
}
|
|
33
|
+
return response.json();
|
|
34
|
+
},
|
|
35
|
+
enabled: !!baseUrl,
|
|
36
|
+
staleTime: 1000 * 60 * 5, // 5 minutes
|
|
37
|
+
retry: 1,
|
|
38
|
+
});
|
|
39
|
+
// Enable server mutation
|
|
40
|
+
const enableMutation = useMutation({
|
|
41
|
+
mutationFn: async (serverName) => {
|
|
42
|
+
const response = await fetch(`${baseUrl}/api/v1/mcp/servers/catalog/${serverName}/enable`, { method: 'POST' });
|
|
43
|
+
if (!response.ok) {
|
|
44
|
+
const error = await response
|
|
45
|
+
.json()
|
|
46
|
+
.catch(() => ({ detail: 'Unknown error' }));
|
|
47
|
+
throw new Error(error.detail || 'Failed to enable server');
|
|
48
|
+
}
|
|
49
|
+
return response.json();
|
|
50
|
+
},
|
|
51
|
+
onSuccess: () => {
|
|
52
|
+
setError(null);
|
|
53
|
+
// Invalidate queries to refresh the list
|
|
54
|
+
queryClient.invalidateQueries({ queryKey: ['mcp-servers', baseUrl] });
|
|
55
|
+
queryClient.invalidateQueries({ queryKey: ['mcp-available', baseUrl] });
|
|
56
|
+
// Also invalidate the config query to refresh tools menu in Chat
|
|
57
|
+
queryClient.invalidateQueries({
|
|
58
|
+
queryKey: ['models', `${baseUrl}/api/v1/configure`],
|
|
59
|
+
});
|
|
60
|
+
// Notify parent about server changes (for codemode tool regeneration or other updates)
|
|
61
|
+
onServersChange?.();
|
|
62
|
+
},
|
|
63
|
+
onError: (error) => {
|
|
64
|
+
setError(error.message);
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
// Disable server mutation
|
|
68
|
+
const disableMutation = useMutation({
|
|
69
|
+
mutationFn: async (serverName) => {
|
|
70
|
+
const response = await fetch(`${baseUrl}/api/v1/mcp/servers/catalog/${serverName}/disable`, { method: 'DELETE' });
|
|
71
|
+
if (!response.ok) {
|
|
72
|
+
const error = await response
|
|
73
|
+
.json()
|
|
74
|
+
.catch(() => ({ detail: 'Unknown error' }));
|
|
75
|
+
throw new Error(error.detail || 'Failed to disable server');
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
onSuccess: () => {
|
|
79
|
+
setError(null);
|
|
80
|
+
// Invalidate queries to refresh the list
|
|
81
|
+
queryClient.invalidateQueries({ queryKey: ['mcp-servers', baseUrl] });
|
|
82
|
+
queryClient.invalidateQueries({ queryKey: ['mcp-available', baseUrl] });
|
|
83
|
+
// Also invalidate the config query to refresh tools menu in Chat
|
|
84
|
+
queryClient.invalidateQueries({
|
|
85
|
+
queryKey: ['models', `${baseUrl}/api/v1/configure`],
|
|
86
|
+
});
|
|
87
|
+
// Notify parent about server changes (for codemode tool regeneration or other updates)
|
|
88
|
+
onServersChange?.();
|
|
89
|
+
},
|
|
90
|
+
onError: (error) => {
|
|
91
|
+
setError(error.message);
|
|
92
|
+
},
|
|
93
|
+
});
|
|
94
|
+
// Update agent's MCP servers mutation
|
|
95
|
+
const updateAgentMcpServersMutation = useMutation({
|
|
96
|
+
mutationFn: async (newServers) => {
|
|
97
|
+
if (!agentId)
|
|
98
|
+
return;
|
|
99
|
+
const response = await fetch(`${baseUrl}/api/v1/agents/${agentId}/mcp-servers`, {
|
|
100
|
+
method: 'PATCH',
|
|
101
|
+
headers: { 'Content-Type': 'application/json' },
|
|
102
|
+
body: JSON.stringify({ selected_mcp_servers: newServers }),
|
|
103
|
+
});
|
|
104
|
+
if (!response.ok) {
|
|
105
|
+
const error = await response
|
|
106
|
+
.json()
|
|
107
|
+
.catch(() => ({ detail: 'Unknown error' }));
|
|
108
|
+
throw new Error(error.detail || 'Failed to update agent MCP servers');
|
|
109
|
+
}
|
|
110
|
+
return response.json();
|
|
111
|
+
},
|
|
112
|
+
onSuccess: () => {
|
|
113
|
+
setError(null);
|
|
114
|
+
// Also invalidate the config query to refresh tools menu in Chat
|
|
115
|
+
queryClient.invalidateQueries({
|
|
116
|
+
queryKey: ['models', `${baseUrl}/api/v1/configure`],
|
|
117
|
+
});
|
|
118
|
+
// Notify parent about server changes
|
|
119
|
+
onServersChange?.();
|
|
120
|
+
},
|
|
121
|
+
onError: (error) => {
|
|
122
|
+
setError(error.message);
|
|
123
|
+
},
|
|
124
|
+
});
|
|
125
|
+
// Separate servers into categories based on running status and config flag
|
|
126
|
+
// The /available endpoint returns all servers with isRunning and isConfig flags
|
|
127
|
+
const { assignedConfigServers, assignedCatalogServers } = useMemo(() => {
|
|
128
|
+
const all = catalogQuery.data || [];
|
|
129
|
+
const assignedConfig = [];
|
|
130
|
+
const assignedCatalog = [];
|
|
131
|
+
all.forEach(server => {
|
|
132
|
+
const isConfigSelected = selectedServers.some(s => s.id === server.id && s.origin === 'config');
|
|
133
|
+
const isCatalogSelected = selectedServers.some(s => s.id === server.id && s.origin === 'catalog');
|
|
134
|
+
if (server.isConfig) {
|
|
135
|
+
// mcp.json config servers (only shown if running)
|
|
136
|
+
if (server.isRunning && isConfigSelected) {
|
|
137
|
+
assignedConfig.push(server);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
// Catalog servers - show in running section if running
|
|
142
|
+
if (server.isRunning && isCatalogSelected) {
|
|
143
|
+
assignedCatalog.push(server);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
return {
|
|
148
|
+
assignedConfigServers: assignedConfig,
|
|
149
|
+
assignedCatalogServers: assignedCatalog,
|
|
150
|
+
};
|
|
151
|
+
}, [catalogQuery.data, selectedServers]);
|
|
152
|
+
// Get servers that are not yet running (available to enable)
|
|
153
|
+
// This includes catalog servers that are NOT running and NOT config servers
|
|
154
|
+
const availableCatalogServers = useMemo(() => {
|
|
155
|
+
const all = catalogQuery.data || [];
|
|
156
|
+
// Filter to catalog servers (isConfig=false) that are NOT currently running
|
|
157
|
+
return all.filter(server => !server.isRunning && !server.isConfig);
|
|
158
|
+
}, [catalogQuery.data]);
|
|
159
|
+
// Filter catalog servers by search query
|
|
160
|
+
const filteredCatalogServers = useMemo(() => {
|
|
161
|
+
if (!searchQuery.trim())
|
|
162
|
+
return availableCatalogServers;
|
|
163
|
+
const query = searchQuery.toLowerCase();
|
|
164
|
+
return availableCatalogServers.filter(server => server.name.toLowerCase().includes(query) ||
|
|
165
|
+
server.id.toLowerCase().includes(query) ||
|
|
166
|
+
server.tools.some(t => t.name.toLowerCase().includes(query)));
|
|
167
|
+
}, [availableCatalogServers, searchQuery]);
|
|
168
|
+
// Handle enabling a server
|
|
169
|
+
const handleEnableServer = useCallback((serverName) => {
|
|
170
|
+
enableMutation.mutate(serverName, {
|
|
171
|
+
onSuccess: () => {
|
|
172
|
+
// After enabling, automatically add to selected servers
|
|
173
|
+
// Since we are enabling from catalog, origin is catalog
|
|
174
|
+
const selection = {
|
|
175
|
+
id: serverName,
|
|
176
|
+
origin: 'catalog',
|
|
177
|
+
};
|
|
178
|
+
const exists = selectedServers?.some(s => s.id === serverName && s.origin === 'catalog');
|
|
179
|
+
if (!exists) {
|
|
180
|
+
const newServers = [...(selectedServers || []), selection];
|
|
181
|
+
onSelectedServersChange?.(newServers);
|
|
182
|
+
// Update the running agent's MCP servers
|
|
183
|
+
if (agentId) {
|
|
184
|
+
updateAgentMcpServersMutation.mutate(newServers);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
},
|
|
188
|
+
});
|
|
189
|
+
}, [
|
|
190
|
+
enableMutation,
|
|
191
|
+
selectedServers,
|
|
192
|
+
onSelectedServersChange,
|
|
193
|
+
agentId,
|
|
194
|
+
updateAgentMcpServersMutation,
|
|
195
|
+
]);
|
|
196
|
+
// Handle disabling a server
|
|
197
|
+
const handleDisableServer = useCallback((serverName) => {
|
|
198
|
+
disableMutation.mutate(serverName);
|
|
199
|
+
// Also remove from selected servers so the Chat tools menu updates
|
|
200
|
+
if (selectedServers) {
|
|
201
|
+
const newServers = selectedServers.filter(s => !(s.id === serverName && s.origin === 'catalog'));
|
|
202
|
+
// Only update if changed
|
|
203
|
+
if (newServers.length !== selectedServers.length) {
|
|
204
|
+
onSelectedServersChange?.(newServers);
|
|
205
|
+
// Update the running agent's MCP servers
|
|
206
|
+
if (agentId) {
|
|
207
|
+
updateAgentMcpServersMutation.mutate(newServers);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}, [
|
|
212
|
+
disableMutation,
|
|
213
|
+
selectedServers,
|
|
214
|
+
onSelectedServersChange,
|
|
215
|
+
agentId,
|
|
216
|
+
updateAgentMcpServersMutation,
|
|
217
|
+
]);
|
|
218
|
+
// Handle removing a server from selection (without disabling it globally)
|
|
219
|
+
const handleRemoveServer = useCallback((serverName, isConfig) => {
|
|
220
|
+
if (selectedServers) {
|
|
221
|
+
const origin = isConfig ? 'config' : 'catalog';
|
|
222
|
+
const newServers = selectedServers.filter(s => !(s.id === serverName && s.origin === origin));
|
|
223
|
+
// Only update if changed
|
|
224
|
+
if (newServers.length !== selectedServers.length) {
|
|
225
|
+
onSelectedServersChange?.(newServers);
|
|
226
|
+
// Update the running agent's MCP servers
|
|
227
|
+
if (agentId) {
|
|
228
|
+
updateAgentMcpServersMutation.mutate(newServers);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}, [
|
|
233
|
+
selectedServers,
|
|
234
|
+
onSelectedServersChange,
|
|
235
|
+
agentId,
|
|
236
|
+
updateAgentMcpServersMutation,
|
|
237
|
+
]);
|
|
238
|
+
// Handle refreshing the server lists
|
|
239
|
+
const handleRefresh = useCallback(() => {
|
|
240
|
+
queryClient.invalidateQueries({ queryKey: ['mcp-servers', baseUrl] });
|
|
241
|
+
queryClient.invalidateQueries({ queryKey: ['mcp-available', baseUrl] });
|
|
242
|
+
}, [queryClient, baseUrl]);
|
|
243
|
+
// Handle server selection (for agent configuration)
|
|
244
|
+
const handleServerSelect = useCallback((server, selected) => {
|
|
245
|
+
// Determine origin
|
|
246
|
+
const origin = server.isConfig ? 'config' : 'catalog';
|
|
247
|
+
const selectionItem = { id: server.id, origin };
|
|
248
|
+
let newSelection;
|
|
249
|
+
if (selected) {
|
|
250
|
+
newSelection = [...(selectedServers || []), selectionItem];
|
|
251
|
+
}
|
|
252
|
+
else {
|
|
253
|
+
newSelection = (selectedServers || []).filter(s => !(s.id === server.id && s.origin === origin));
|
|
254
|
+
}
|
|
255
|
+
onSelectedServersChange?.(newSelection);
|
|
256
|
+
}, [selectedServers, onSelectedServersChange]);
|
|
257
|
+
const isLoading = catalogQuery.isLoading;
|
|
258
|
+
const isMutating = enableMutation.isPending || disableMutation.isPending;
|
|
259
|
+
return (_jsxs(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 4 }, children: [_jsxs(Box, { sx: {
|
|
260
|
+
display: 'flex',
|
|
261
|
+
alignItems: 'center',
|
|
262
|
+
justifyContent: 'space-between',
|
|
263
|
+
}, children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(ToolsIcon, { size: 16 }), _jsx(Text, { sx: { fontWeight: 'semibold' }, children: "MCP Server Management" })] }), _jsx(IconButton, { icon: SyncIcon, "aria-label": "Refresh server lists", size: "small", onClick: handleRefresh, disabled: isLoading || isMutating })] }), error && (_jsx(Flash, { variant: "danger", children: _jsx(Text, { sx: { fontSize: 1 }, children: error }) })), enableCodemode && (_jsx(Flash, { variant: "default", children: _jsxs(Text, { sx: { fontSize: 0 }, children: [_jsx("strong", { children: "Codemode enabled:" }), " Adding or removing MCP servers will regenerate the Codemode tool registry."] }) })), isLoading && (_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2, py: 3 }, children: [_jsx(Spinner, { size: "small" }), _jsx(Text, { sx: { color: 'fg.muted' }, children: "Loading MCP servers..." })] })), !isLoading && assignedConfigServers.length > 0 && (_jsxs(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 2 }, children: [_jsxs(Text, { sx: { fontWeight: 'semibold', fontSize: 1 }, children: ["Assigned Configured Servers (", assignedConfigServers.length, ")"] }), _jsx(Text, { sx: { color: 'fg.muted', fontSize: 0 }, children: "These servers are from ~/.datalayer/mcp.json and assigned to this agent." }), _jsx(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 2 }, children: assignedConfigServers.map(server => (_jsx(ServerCard, { server: server, variant: "config", disabled: disabled, isSelected: true, onSelect: onSelectedServersChange ? handleServerSelect : undefined, onRemove: () => handleRemoveServer(server.id, true) }, server.id))) })] })), !isLoading && assignedCatalogServers.length > 0 && (_jsxs(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 2 }, children: [_jsxs(Text, { sx: { fontWeight: 'semibold', fontSize: 1 }, children: ["Assigned Catalog Servers (", assignedCatalogServers.length, ")"] }), _jsx(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 2 }, children: assignedCatalogServers.map(server => (_jsx(ServerCard, { server: server, variant: "active", disabled: disabled || isMutating, isSelected: true, onSelect: onSelectedServersChange ? handleServerSelect : undefined, onRemove: () => handleDisableServer(server.id), isRemoving: disableMutation.isPending &&
|
|
264
|
+
disableMutation.variables === server.id }, server.id))) })] })), !isLoading && (_jsxs(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 2 }, children: [_jsxs(Text, { sx: { fontWeight: 'semibold', fontSize: 1 }, children: ["Available from Catalog (", availableCatalogServers.length, ")"] }), availableCatalogServers.length > 3 && (_jsx(TextInput, { leadingVisual: SearchIcon, placeholder: "Search servers...", value: searchQuery, onChange: e => setSearchQuery(e.target.value), sx: { width: '100%' } })), filteredCatalogServers.length === 0 ? (_jsx(Text, { sx: { color: 'fg.muted', fontSize: 1 }, children: searchQuery
|
|
265
|
+
? 'No servers match your search.'
|
|
266
|
+
: 'All catalog servers are already enabled.' })) : (_jsx(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 2 }, children: filteredCatalogServers.map(server => (_jsx(ServerCard, { server: server, variant: "catalog", disabled: disabled || isMutating, onAdd: () => handleEnableServer(server.id), isAdding: enableMutation.isPending &&
|
|
267
|
+
enableMutation.variables === server.id }, server.id))) }))] }))] }));
|
|
268
|
+
}
|
|
269
|
+
function ServerCard({ server, variant, disabled = false, isSelected = false, onSelect, onAdd, onRemove, isAdding = false, isRemoving = false, }) {
|
|
270
|
+
// Check availability based on isAvailable field from the server
|
|
271
|
+
const isAvailable = server.isAvailable !== false;
|
|
272
|
+
const missingEnvVars = !isAvailable && server.requiredEnvVars && server.requiredEnvVars.length > 0;
|
|
273
|
+
return (_jsxs(Box, { sx: {
|
|
274
|
+
display: 'flex',
|
|
275
|
+
alignItems: 'flex-start',
|
|
276
|
+
gap: 2,
|
|
277
|
+
padding: 2,
|
|
278
|
+
borderRadius: 2,
|
|
279
|
+
backgroundColor: 'canvas.subtle',
|
|
280
|
+
border: '1px solid',
|
|
281
|
+
borderColor: isSelected ? 'accent.emphasis' : 'border.default',
|
|
282
|
+
opacity: disabled || !isAvailable ? 0.6 : 1,
|
|
283
|
+
cursor: onSelect && !disabled && isAvailable ? 'pointer' : 'default',
|
|
284
|
+
}, onClick: () => {
|
|
285
|
+
if (onSelect && !disabled && isAvailable) {
|
|
286
|
+
onSelect(server, !isSelected);
|
|
287
|
+
}
|
|
288
|
+
}, children: [_jsx(Box, { sx: {
|
|
289
|
+
display: 'flex',
|
|
290
|
+
alignItems: 'center',
|
|
291
|
+
justifyContent: 'center',
|
|
292
|
+
width: 32,
|
|
293
|
+
height: 32,
|
|
294
|
+
borderRadius: 2,
|
|
295
|
+
backgroundColor: variant === 'config' ? 'attention.subtle' : 'accent.subtle',
|
|
296
|
+
flexShrink: 0,
|
|
297
|
+
}, children: _jsx(ServerIcon, { size: 16 }) }), _jsxs(Box, { sx: { flex: 1, minWidth: 0 }, children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2, mb: 1 }, children: [_jsx(Text, { sx: { fontWeight: 'semibold', fontSize: 1 }, children: server.name }), variant === 'active' && (_jsx(Label, { variant: "success", size: "small", children: "Active" })), variant === 'config' && (_jsx(Label, { variant: "attention", size: "small", children: "Config" })), !isAvailable && (_jsx(Label, { variant: "danger", size: "small", children: "Missing env vars" })), isSelected && (_jsxs(Label, { variant: "accent", size: "small", children: [_jsx(CheckIcon, { size: 12 }), " Selected"] }))] }), server.description && (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', mb: 1 }, children: server.description })), missingEnvVars && (_jsxs(Box, { sx: {
|
|
298
|
+
fontSize: 0,
|
|
299
|
+
color: 'danger.fg',
|
|
300
|
+
mb: 1,
|
|
301
|
+
p: 1,
|
|
302
|
+
bg: 'danger.subtle',
|
|
303
|
+
borderRadius: 1,
|
|
304
|
+
}, children: [_jsx(Text, { sx: { fontWeight: 'semibold', display: 'block', mb: 1 }, children: "Missing environment variables:" }), server.requiredEnvVars.map(envVar => (_jsx(Text, { as: "code", sx: {
|
|
305
|
+
display: 'inline-block',
|
|
306
|
+
mr: 1,
|
|
307
|
+
mb: 1,
|
|
308
|
+
px: 1,
|
|
309
|
+
py: '2px',
|
|
310
|
+
bg: 'canvas.default',
|
|
311
|
+
borderRadius: 1,
|
|
312
|
+
fontFamily: 'mono',
|
|
313
|
+
fontSize: 0,
|
|
314
|
+
}, children: envVar }, envVar)))] })), server.tools.length > 0 && (_jsxs(Text, { sx: {
|
|
315
|
+
fontSize: 0,
|
|
316
|
+
color: 'fg.muted',
|
|
317
|
+
overflow: 'hidden',
|
|
318
|
+
textOverflow: 'ellipsis',
|
|
319
|
+
whiteSpace: 'nowrap',
|
|
320
|
+
}, children: ["Tools: ", server.tools.map(t => t.name).join(', ')] })), server.transport && (_jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: ["Transport: ", server.transport] }))] }), _jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 1, flexShrink: 0 }, children: [variant === 'catalog' && onAdd && (_jsx(Button, { variant: "primary", size: "small", leadingVisual: isAdding ? Spinner : PlusIcon, onClick: e => {
|
|
321
|
+
e.stopPropagation();
|
|
322
|
+
onAdd();
|
|
323
|
+
}, disabled: disabled || !isAvailable || isAdding, children: "Add" })), variant === 'active' && onRemove && (_jsx(Button, { variant: "danger", size: "small", leadingVisual: isRemoving ? Spinner : TrashIcon, onClick: e => {
|
|
324
|
+
e.stopPropagation();
|
|
325
|
+
onRemove();
|
|
326
|
+
}, disabled: disabled || isRemoving, children: "Remove" })), variant === 'config' && onRemove && (_jsx(Button, { variant: "danger", size: "small", leadingVisual: isRemoving ? Spinner : TrashIcon, onClick: e => {
|
|
327
|
+
e.stopPropagation();
|
|
328
|
+
onRemove();
|
|
329
|
+
}, disabled: disabled || isRemoving, children: "Remove" })), variant === 'config' && !onRemove && (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', fontStyle: 'italic' }, children: "Auto-started from mcp.json" }))] })] }));
|
|
330
|
+
}
|
|
331
|
+
export default McpServerManager;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
interface MockFileBrowserProps {
|
|
2
|
+
export interface MockFileBrowserProps {
|
|
3
3
|
codemode?: boolean;
|
|
4
4
|
}
|
|
5
5
|
/**
|
|
@@ -9,4 +9,3 @@ interface MockFileBrowserProps {
|
|
|
9
9
|
* In production, this would be replaced with a real Simple UI FileBrowser component.
|
|
10
10
|
*/
|
|
11
11
|
export declare const MockFileBrowser: React.FC<MockFileBrowserProps>;
|
|
12
|
-
export {};
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
interface Session {
|
|
2
|
+
export interface Session {
|
|
3
3
|
id: string;
|
|
4
4
|
name: string;
|
|
5
5
|
active: boolean;
|
|
6
6
|
}
|
|
7
|
-
interface SessionTabsProps {
|
|
7
|
+
export interface SessionTabsProps {
|
|
8
8
|
sessions: Session[];
|
|
9
9
|
activeSession: string;
|
|
10
10
|
agentName?: string;
|
|
@@ -18,4 +18,3 @@ interface SessionTabsProps {
|
|
|
18
18
|
* Displays the current session name.
|
|
19
19
|
*/
|
|
20
20
|
export declare const SessionTabs: React.FC<SessionTabsProps>;
|
|
21
|
-
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
interface TimeTravelProps {
|
|
2
|
+
export interface TimeTravelProps {
|
|
3
3
|
value: number;
|
|
4
4
|
onChange: (value: number) => void;
|
|
5
5
|
min?: number;
|
|
@@ -12,4 +12,3 @@ interface TimeTravelProps {
|
|
|
12
12
|
* Slider for navigating through document history.
|
|
13
13
|
*/
|
|
14
14
|
export declare const TimeTravel: React.FC<TimeTravelProps>;
|
|
15
|
-
export {};
|
|
@@ -10,6 +10,8 @@ export interface AgentDetailsProps {
|
|
|
10
10
|
messageCount: number;
|
|
11
11
|
/** Agent ID for context usage tracking */
|
|
12
12
|
agentId?: string;
|
|
13
|
+
/** API base URL for fetching context data */
|
|
14
|
+
apiBase?: string;
|
|
13
15
|
/** Identity provider configurations */
|
|
14
16
|
identityProviders?: {
|
|
15
17
|
[K in OAuthProvider]?: {
|
|
@@ -28,5 +30,5 @@ export interface AgentDetailsProps {
|
|
|
28
30
|
/**
|
|
29
31
|
* AgentDetails component displays comprehensive information about the agent.
|
|
30
32
|
*/
|
|
31
|
-
export declare function AgentDetails({ name, protocol, url, messageCount, agentId, identityProviders, onIdentityConnect, onIdentityDisconnect, onBack, }: AgentDetailsProps): import("react/jsx-runtime").JSX.Element;
|
|
33
|
+
export declare function AgentDetails({ name, protocol, url, messageCount, agentId, apiBase, identityProviders, onIdentityConnect, onIdentityDisconnect, onBack, }: AgentDetailsProps): import("react/jsx-runtime").JSX.Element;
|
|
32
34
|
export default AgentDetails;
|