@datalayer/agent-runtimes 0.0.8 → 0.0.10
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 +27 -12
- package/lib/{examples/components → components}/AgentConfiguration.js +170 -22
- 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 +323 -31
- 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 +11 -4
- package/lib/components/chat/components/ContextInspector.d.ts +81 -0
- package/lib/components/chat/components/ContextInspector.js +261 -0
- package/lib/components/chat/components/ContextPanel.d.ts +112 -0
- package/lib/components/chat/components/ContextPanel.js +373 -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.d.ts +33 -0
- package/lib/config/agents.js +424 -0
- package/lib/config/index.d.ts +4 -0
- package/lib/config/index.js +8 -0
- package/lib/config/mcpServers.d.ts +18 -0
- package/lib/config/mcpServers.js +129 -0
- package/lib/config/skills.d.ts +25 -0
- package/lib/config/skills.js +54 -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 +167 -29
- 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 +150 -0
- package/package.json +4 -5
- package/scripts/apply-patches.sh +32 -0
- package/scripts/codegen/generate_agents.py +452 -0
- package/scripts/codegen/generate_mcp_servers.py +424 -0
- package/scripts/codegen/generate_skills.py +321 -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/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
package/README.md
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
# 🤖 Agent Runtimes
|
|
12
12
|
|
|
13
13
|
[](https://github.com/datalayer/agent-runtimes/actions/workflows/build.yml)
|
|
14
|
+
[](https://app.netlify.com/projects/agent-runtimes/deploys)
|
|
14
15
|
[](https://pypi.org/project/agent-runtimes)
|
|
15
16
|
|
|
16
17
|
**Agent Runtimes** is a unified platform for deploying, managing, and interacting with AI agents across multiple protocols and frameworks. It provides both a Python server for hosting agents and React components for seamless integration into web and desktop applications.
|
|
@@ -40,7 +41,7 @@ Agent Runtimes solves the complexity of deploying AI agents by providing:
|
|
|
40
41
|
- **MCP-UI**: Interactive UI resources protocol with React/Web Components
|
|
41
42
|
- **A2A**: Agent-to-agent communication
|
|
42
43
|
|
|
43
|
-
### Multi-Agent Support
|
|
44
|
+
### Multi-Agent Support
|
|
44
45
|
- **Pydantic AI**: Type-safe agents (fully implemented)
|
|
45
46
|
- **LangChain**: Complex workflows (adapter ready)
|
|
46
47
|
- **Jupyter AI**: Notebook integration (adapter ready)
|
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import type { Agent } from '../stores/examplesStore';
|
|
3
|
-
import type { Transport, Extension } from '
|
|
4
|
-
import type {
|
|
2
|
+
import type { Agent } from '../examples/stores/examplesStore';
|
|
3
|
+
import type { Transport, Extension } from './chat';
|
|
4
|
+
import type { McpServerSelection } from './McpServerManager';
|
|
5
|
+
import type { OAuthProvider, Identity } from '../identity';
|
|
6
|
+
import type { MCPServerTool as MCPServerToolType } from '../types';
|
|
5
7
|
/**
|
|
6
|
-
* MCP Server Tool type
|
|
8
|
+
* MCP Server Tool type (re-exported from types.ts)
|
|
7
9
|
*/
|
|
8
|
-
export
|
|
9
|
-
name: string;
|
|
10
|
-
description?: string;
|
|
11
|
-
enabled: boolean;
|
|
12
|
-
}
|
|
10
|
+
export type MCPServerTool = MCPServerToolType;
|
|
13
11
|
export interface SkillOption {
|
|
14
12
|
id: string;
|
|
15
13
|
name: string;
|
|
@@ -27,7 +25,12 @@ export interface MCPServerConfig {
|
|
|
27
25
|
command?: string;
|
|
28
26
|
args?: string[];
|
|
29
27
|
isAvailable?: boolean;
|
|
28
|
+
isRunning?: boolean;
|
|
29
|
+
/** True if this server is from mcp.json config (vs catalog) */
|
|
30
|
+
isConfig?: boolean;
|
|
30
31
|
transport?: string;
|
|
32
|
+
/** Required environment variables for this server */
|
|
33
|
+
requiredEnvVars?: string[];
|
|
31
34
|
}
|
|
32
35
|
type AgentLibrary = 'pydantic-ai' | 'langchain' | 'jupyter-ai';
|
|
33
36
|
export type { AgentLibrary };
|
|
@@ -59,7 +62,7 @@ export interface AIModelConfig {
|
|
|
59
62
|
requiredEnvVars?: string[];
|
|
60
63
|
isAvailable?: boolean;
|
|
61
64
|
}
|
|
62
|
-
interface AgentConfigurationProps {
|
|
65
|
+
export interface AgentConfigurationProps {
|
|
63
66
|
agentLibrary: AgentLibrary;
|
|
64
67
|
transport: Transport;
|
|
65
68
|
extensions: Extension[];
|
|
@@ -74,9 +77,11 @@ interface AgentConfigurationProps {
|
|
|
74
77
|
enableCodemode?: boolean;
|
|
75
78
|
allowDirectToolCalls?: boolean;
|
|
76
79
|
enableToolReranker?: boolean;
|
|
80
|
+
useJupyterSandbox?: boolean;
|
|
77
81
|
availableSkills?: SkillOption[];
|
|
78
82
|
selectedSkills?: string[];
|
|
79
|
-
|
|
83
|
+
/** Selected MCP servers */
|
|
84
|
+
selectedMcpServers?: McpServerSelection[];
|
|
80
85
|
identityProviders?: {
|
|
81
86
|
[K in OAuthProvider]?: {
|
|
82
87
|
clientId: string;
|
|
@@ -97,8 +102,18 @@ interface AgentConfigurationProps {
|
|
|
97
102
|
onEnableCodemodeChange?: (enabled: boolean) => void;
|
|
98
103
|
onAllowDirectToolCallsChange?: (enabled: boolean) => void;
|
|
99
104
|
onEnableToolRerankerChange?: (enabled: boolean) => void;
|
|
105
|
+
onUseJupyterSandboxChange?: (enabled: boolean) => void;
|
|
100
106
|
onSelectedSkillsChange?: (skills: string[]) => void;
|
|
101
|
-
|
|
107
|
+
/** Callback when MCP server selection changes */
|
|
108
|
+
onSelectedMcpServersChange?: (servers: McpServerSelection[]) => void;
|
|
109
|
+
/** Rich editor mode */
|
|
110
|
+
richEditor?: boolean;
|
|
111
|
+
/** Callback when rich editor changes */
|
|
112
|
+
onRichEditorChange?: (enabled: boolean) => void;
|
|
113
|
+
/** Durable mode */
|
|
114
|
+
durable?: boolean;
|
|
115
|
+
/** Callback when durable changes */
|
|
116
|
+
onDurableChange?: (enabled: boolean) => void;
|
|
102
117
|
}
|
|
103
118
|
/**
|
|
104
119
|
* Agent Configuration Component
|
|
@@ -6,10 +6,10 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
6
6
|
import { useMemo, useState, useCallback } from 'react';
|
|
7
7
|
import { Text, TextInput, Button, FormControl, Select, Checkbox, Spinner, Flash, Label, IconButton, } from '@primer/react';
|
|
8
8
|
import { ToolsIcon, KeyIcon, SyncIcon, PlusIcon, XIcon, LinkExternalIcon, } from '@primer/octicons-react';
|
|
9
|
-
import { useQuery } from '@tanstack/react-query';
|
|
9
|
+
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
|
10
10
|
import { Box } from '@datalayer/primer-addons';
|
|
11
|
-
import { IdentityConnect, useIdentity } from '
|
|
12
|
-
import { IdentityCard } from '
|
|
11
|
+
import { IdentityConnect, useIdentity } from '../identity';
|
|
12
|
+
import { IdentityCard } from './chat';
|
|
13
13
|
/**
|
|
14
14
|
* Token-based identity providers that can be connected via API key
|
|
15
15
|
*/
|
|
@@ -199,8 +199,8 @@ const EXTENSIONS = [
|
|
|
199
199
|
*
|
|
200
200
|
* Form for configuring agent connection settings.
|
|
201
201
|
*/
|
|
202
|
-
export const AgentConfiguration = ({ agentLibrary, transport, extensions, wsUrl, baseUrl, agentName, model, agents, selectedAgentId, isCreatingAgent = false, createError = null, enableCodemode = false, allowDirectToolCalls = false, enableToolReranker = false, availableSkills = [], selectedSkills = [], selectedMcpServers = [], identityProviders, onIdentityConnect, onIdentityDisconnect, onAgentLibraryChange, onTransportChange, onExtensionsChange, onWsUrlChange, onBaseUrlChange, onAgentNameChange, onModelChange, onAgentSelect, onConnect, onEnableCodemodeChange, onAllowDirectToolCallsChange, onEnableToolRerankerChange, onSelectedSkillsChange, onSelectedMcpServersChange, }) => {
|
|
203
|
-
// Fetch
|
|
202
|
+
export const AgentConfiguration = ({ agentLibrary, transport, extensions, wsUrl, baseUrl, agentName, model, agents, selectedAgentId, isCreatingAgent = false, createError = null, enableCodemode = false, allowDirectToolCalls = false, enableToolReranker = false, useJupyterSandbox = false, availableSkills = [], selectedSkills = [], selectedMcpServers = [], identityProviders, onIdentityConnect, onIdentityDisconnect, onAgentLibraryChange, onTransportChange, onExtensionsChange, onWsUrlChange, onBaseUrlChange, onAgentNameChange, onModelChange, onAgentSelect, onConnect, onEnableCodemodeChange, onAllowDirectToolCallsChange, onEnableToolRerankerChange, onUseJupyterSandboxChange, onSelectedSkillsChange, onSelectedMcpServersChange, }) => {
|
|
203
|
+
// Fetch general configuration from the backend (models, etc.)
|
|
204
204
|
const configQuery = useQuery({
|
|
205
205
|
queryKey: ['agent-config', baseUrl],
|
|
206
206
|
queryFn: async () => {
|
|
@@ -214,6 +214,20 @@ export const AgentConfiguration = ({ agentLibrary, transport, extensions, wsUrl,
|
|
|
214
214
|
staleTime: 1000 * 60 * 5, // 5 minutes
|
|
215
215
|
retry: 1,
|
|
216
216
|
});
|
|
217
|
+
// Fetch MCP Config servers from mcp.json (user-defined servers)
|
|
218
|
+
const mcpServersQuery = useQuery({
|
|
219
|
+
queryKey: ['mcp-config', baseUrl],
|
|
220
|
+
queryFn: async () => {
|
|
221
|
+
const response = await fetch(`${baseUrl}/api/v1/mcp/servers/config`);
|
|
222
|
+
if (!response.ok) {
|
|
223
|
+
throw new Error('Failed to fetch MCP config servers');
|
|
224
|
+
}
|
|
225
|
+
return response.json();
|
|
226
|
+
},
|
|
227
|
+
enabled: !!baseUrl,
|
|
228
|
+
staleTime: 1000 * 60 * 1, // 1 minute (refresh more often for running status)
|
|
229
|
+
retry: 1,
|
|
230
|
+
});
|
|
217
231
|
// Fetch skills from the backend (only when codemode is enabled)
|
|
218
232
|
const skillsQuery = useQuery({
|
|
219
233
|
queryKey: ['agent-skills', baseUrl],
|
|
@@ -228,22 +242,102 @@ export const AgentConfiguration = ({ agentLibrary, transport, extensions, wsUrl,
|
|
|
228
242
|
staleTime: 1000 * 60 * 5, // 5 minutes
|
|
229
243
|
retry: 1,
|
|
230
244
|
});
|
|
231
|
-
|
|
245
|
+
// Fetch MCP Catalog servers (predefined servers that can be enabled on-demand)
|
|
246
|
+
const catalogServersQuery = useQuery({
|
|
247
|
+
queryKey: ['mcp-catalog', baseUrl],
|
|
248
|
+
queryFn: async () => {
|
|
249
|
+
const response = await fetch(`${baseUrl}/api/v1/mcp/servers/catalog`);
|
|
250
|
+
if (!response.ok) {
|
|
251
|
+
throw new Error('Failed to fetch MCP catalog servers');
|
|
252
|
+
}
|
|
253
|
+
return response.json();
|
|
254
|
+
},
|
|
255
|
+
enabled: !!baseUrl,
|
|
256
|
+
staleTime: 1000 * 60 * 5, // 5 minutes
|
|
257
|
+
retry: 1,
|
|
258
|
+
});
|
|
259
|
+
// Query client for invalidating queries
|
|
260
|
+
const queryClient = useQueryClient();
|
|
261
|
+
// Mutation to enable a catalog server
|
|
262
|
+
const enableCatalogServerMutation = useMutation({
|
|
263
|
+
mutationFn: async (serverName) => {
|
|
264
|
+
const response = await fetch(`${baseUrl}/api/v1/mcp/servers/catalog/${serverName}/enable`, { method: 'POST' });
|
|
265
|
+
if (!response.ok) {
|
|
266
|
+
const error = await response
|
|
267
|
+
.json()
|
|
268
|
+
.catch(() => ({ detail: 'Unknown error' }));
|
|
269
|
+
throw new Error(error.detail || 'Failed to enable server');
|
|
270
|
+
}
|
|
271
|
+
return response.json();
|
|
272
|
+
},
|
|
273
|
+
onSuccess: () => {
|
|
274
|
+
// Refresh both config and catalog queries to get updated running status
|
|
275
|
+
queryClient.invalidateQueries({ queryKey: ['mcp-config', baseUrl] });
|
|
276
|
+
queryClient.invalidateQueries({ queryKey: ['mcp-catalog', baseUrl] });
|
|
277
|
+
},
|
|
278
|
+
});
|
|
279
|
+
// Use MCP servers from dedicated query, fallback to configQuery for backwards compatibility
|
|
280
|
+
const configServers = mcpServersQuery.data || configQuery.data?.mcpServers || [];
|
|
281
|
+
const catalogServers = catalogServersQuery.data || [];
|
|
232
282
|
const models = configQuery.data?.models || [];
|
|
233
283
|
// Use fetched skills when codemode is enabled, otherwise use passed availableSkills (which may be empty)
|
|
234
284
|
const fetchedSkills = skillsQuery.data?.skills || [];
|
|
235
285
|
const displaySkills = enableCodemode ? fetchedSkills : availableSkills;
|
|
236
|
-
const previewServers = selectedMcpServers.length
|
|
237
|
-
? mcpServers.filter(server => selectedMcpServers.includes(server.id))
|
|
238
|
-
: [];
|
|
239
286
|
const skillsEnabled = selectedSkills.length > 0;
|
|
240
|
-
|
|
241
|
-
|
|
287
|
+
const selectedConfigServers = selectedMcpServers
|
|
288
|
+
.filter(s => s.origin === 'config')
|
|
289
|
+
.map(s => s.id);
|
|
290
|
+
const selectedCatalogServers = selectedMcpServers
|
|
291
|
+
.filter(s => s.origin === 'catalog')
|
|
292
|
+
.map(s => s.id);
|
|
293
|
+
// Preview servers combines both config and catalog selections
|
|
294
|
+
const previewConfigServers = selectedConfigServers.length
|
|
295
|
+
? configServers.filter(server => selectedConfigServers.includes(server.id))
|
|
296
|
+
: [];
|
|
297
|
+
const previewCatalogServers = selectedCatalogServers.length
|
|
298
|
+
? catalogServers.filter(server => selectedCatalogServers.includes(server.id))
|
|
299
|
+
: [];
|
|
300
|
+
// Handle MCP Config server checkbox change
|
|
301
|
+
const handleConfigServerChange = (serverId, checked) => {
|
|
302
|
+
if (!onSelectedMcpServersChange)
|
|
303
|
+
return;
|
|
242
304
|
if (checked) {
|
|
243
|
-
|
|
305
|
+
if (!selectedMcpServers.some(s => s.id === serverId && s.origin === 'config')) {
|
|
306
|
+
onSelectedMcpServersChange([
|
|
307
|
+
...selectedMcpServers,
|
|
308
|
+
{ id: serverId, origin: 'config' },
|
|
309
|
+
]);
|
|
310
|
+
}
|
|
244
311
|
}
|
|
245
312
|
else {
|
|
246
|
-
onSelectedMcpServersChange
|
|
313
|
+
onSelectedMcpServersChange(selectedMcpServers.filter(s => !(s.id === serverId && s.origin === 'config')));
|
|
314
|
+
}
|
|
315
|
+
};
|
|
316
|
+
// Handle MCP Catalog server checkbox change
|
|
317
|
+
// If selected and not running, enable (start) the server first
|
|
318
|
+
const handleCatalogServerChange = async (serverId, checked, isRunning) => {
|
|
319
|
+
if (!onSelectedMcpServersChange)
|
|
320
|
+
return;
|
|
321
|
+
if (checked) {
|
|
322
|
+
// If not running, start the server first
|
|
323
|
+
if (!isRunning) {
|
|
324
|
+
try {
|
|
325
|
+
await enableCatalogServerMutation.mutateAsync(serverId);
|
|
326
|
+
}
|
|
327
|
+
catch (error) {
|
|
328
|
+
console.error('Failed to enable catalog server:', error);
|
|
329
|
+
return; // Don't add to selection if enable failed
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
if (!selectedMcpServers.some(s => s.id === serverId && s.origin === 'catalog')) {
|
|
333
|
+
onSelectedMcpServersChange([
|
|
334
|
+
...selectedMcpServers,
|
|
335
|
+
{ id: serverId, origin: 'catalog' },
|
|
336
|
+
]);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
else {
|
|
340
|
+
onSelectedMcpServersChange(selectedMcpServers.filter(s => !(s.id === serverId && s.origin === 'catalog')));
|
|
247
341
|
}
|
|
248
342
|
};
|
|
249
343
|
const handleSkillChange = (skillId, checked) => {
|
|
@@ -313,7 +407,7 @@ export const AgentConfiguration = ({ agentLibrary, transport, extensions, wsUrl,
|
|
|
313
407
|
borderColor: 'border.default',
|
|
314
408
|
borderRadius: 2,
|
|
315
409
|
backgroundColor: 'canvas.default',
|
|
316
|
-
}, children: [_jsx(Text, { sx: { fontSize: 1, fontWeight: 'bold', display: 'block', mb: 2 }, children: "Agent Capabilities" }), _jsx(Box, { sx: { display: 'flex', gap: 4 }, children: _jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Checkbox, { checked: enableCodemode, disabled: selectedAgentId !== 'new-agent', onChange: e => onEnableCodemodeChange?.(e.target.checked) }), _jsxs(Box, { children: [_jsx(Text, { sx: { fontSize: 1 }, children: "Codemode" }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', display: 'block' }, children: "Execute code to compose tools" })] })] }) }), skillsEnabled && enableCodemode && (_jsx(Flash, { variant: "default", sx: { mt: 3 }, children: _jsx(Text, { sx: { fontSize: 0 }, children: "Skills provide curated capabilities; Codemode composes tools with Python for multi-step execution." }) })), enableCodemode && (_jsxs(Box, { sx: { mt: 3, display: 'flex', flexDirection: 'column', gap: 2 }, children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Checkbox, { checked: allowDirectToolCalls, disabled: selectedAgentId !== 'new-agent', onChange: e => onAllowDirectToolCallsChange?.(e.target.checked) }), _jsxs(Box, { children: [_jsx(Text, { sx: { fontSize: 1 }, children: "Allow direct tool calls" }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', display: 'block' }, children: "Expose call_tool for simple, single-tool operations" })] })] }), _jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Checkbox, { checked: enableToolReranker, disabled: selectedAgentId !== 'new-agent', onChange: e => onEnableToolRerankerChange?.(e.target.checked) }), _jsxs(Box, { children: [_jsx(Text, { sx: { fontSize: 1 }, children: "Enable tool reranker" }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', display: 'block' }, children: "Reorder search results using the configured reranker" })] })] })] }))] }), _jsxs(Box, { sx: {
|
|
410
|
+
}, children: [_jsx(Text, { sx: { fontSize: 1, fontWeight: 'bold', display: 'block', mb: 2 }, children: "Agent Capabilities" }), _jsx(Box, { sx: { display: 'flex', gap: 4 }, children: _jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Checkbox, { checked: enableCodemode, disabled: selectedAgentId !== 'new-agent', onChange: e => onEnableCodemodeChange?.(e.target.checked) }), _jsxs(Box, { children: [_jsx(Text, { sx: { fontSize: 1 }, children: "Codemode" }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', display: 'block' }, children: "Execute code to compose tools" })] })] }) }), skillsEnabled && enableCodemode && (_jsx(Flash, { variant: "default", sx: { mt: 3 }, children: _jsx(Text, { sx: { fontSize: 0 }, children: "Skills provide curated capabilities; Codemode composes tools with Python for multi-step execution." }) })), enableCodemode && (_jsxs(Box, { sx: { mt: 3, display: 'flex', flexDirection: 'column', gap: 2 }, children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Checkbox, { checked: allowDirectToolCalls, disabled: selectedAgentId !== 'new-agent', onChange: e => onAllowDirectToolCallsChange?.(e.target.checked) }), _jsxs(Box, { children: [_jsx(Text, { sx: { fontSize: 1 }, children: "Allow direct tool calls" }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', display: 'block' }, children: "Expose call_tool for simple, single-tool operations" })] })] }), _jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Checkbox, { checked: enableToolReranker, disabled: selectedAgentId !== 'new-agent', onChange: e => onEnableToolRerankerChange?.(e.target.checked) }), _jsxs(Box, { children: [_jsx(Text, { sx: { fontSize: 1 }, children: "Enable tool reranker" }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', display: 'block' }, children: "Reorder search results using the configured reranker" })] })] }), _jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Checkbox, { checked: useJupyterSandbox, disabled: selectedAgentId !== 'new-agent', onChange: e => onUseJupyterSandboxChange?.(e.target.checked) }), _jsxs(Box, { children: [_jsx(Text, { sx: { fontSize: 1 }, children: "Use Jupyter Sandbox" }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', display: 'block' }, children: "Execute code in a Jupyter kernel instead of local-eval" })] })] })] }))] }), _jsxs(Box, { sx: {
|
|
317
411
|
marginBottom: 3,
|
|
318
412
|
padding: 3,
|
|
319
413
|
border: '1px solid',
|
|
@@ -346,31 +440,85 @@ export const AgentConfiguration = ({ agentLibrary, transport, extensions, wsUrl,
|
|
|
346
440
|
alignItems: 'center',
|
|
347
441
|
gap: 2,
|
|
348
442
|
marginBottom: 2,
|
|
349
|
-
}, children: [_jsx(ToolsIcon, { size: 16 }), _jsx(Text, { sx: { fontSize: 1, fontWeight: 'bold' }, children: "MCP Servers" }),
|
|
350
|
-
!
|
|
351
|
-
!
|
|
443
|
+
}, children: [_jsx(ToolsIcon, { size: 16 }), _jsx(Text, { sx: { fontSize: 1, fontWeight: 'bold' }, children: "MCP Config Servers" }), mcpServersQuery.isLoading && _jsx(Spinner, { size: "small" }), !mcpServersQuery.isLoading && (_jsx(Button, { variant: "invisible", size: "small", onClick: () => mcpServersQuery.refetch(), sx: { padding: 1 }, "aria-label": "Refresh MCP config servers", children: _jsx(SyncIcon, { size: 14 }) }))] }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', marginBottom: 2 }, children: "Servers from your mcp.json configuration file. Started automatically." }), mcpServersQuery.isError && (_jsx(Flash, { variant: "warning", sx: { marginBottom: 2 }, children: _jsx(Text, { sx: { fontSize: 0 }, children: "Unable to fetch MCP config servers. Check that the server is running." }) })), configServers.length === 0 &&
|
|
444
|
+
!mcpServersQuery.isLoading &&
|
|
445
|
+
!mcpServersQuery.isError && (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "No MCP config servers found. Add servers to ~/.datalayer/mcp.json" })), enableCodemode && (_jsx(Flash, { variant: "default", sx: { marginBottom: 2 }, children: _jsx(Text, { sx: { fontSize: 0 }, children: "When Codemode is enabled, selected MCP servers are used to build the Codemode tool registry (tools are exposed via Codemode meta tools like search and execute_code)." }) })), enableCodemode && (_jsxs(Box, { sx: {
|
|
352
446
|
marginBottom: 2,
|
|
353
447
|
padding: 2,
|
|
354
448
|
borderRadius: 1,
|
|
355
449
|
border: '1px solid',
|
|
356
450
|
borderColor: 'border.default',
|
|
357
451
|
backgroundColor: 'canvas.subtle',
|
|
358
|
-
}, children: [_jsx(Text, { sx: { fontSize: 0, fontWeight: 'semibold', display: 'block' }, children: "Codemode registry preview" }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', mb: 1 }, children:
|
|
452
|
+
}, children: [_jsx(Text, { sx: { fontSize: 0, fontWeight: 'semibold', display: 'block' }, children: "Codemode registry preview" }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', mb: 1 }, children: selectedConfigServers.length > 0 ||
|
|
453
|
+
selectedCatalogServers.length > 0
|
|
359
454
|
? 'Using selected MCP servers'
|
|
360
|
-
: 'No servers selected — select servers to scope Codemode tools.' }),
|
|
455
|
+
: 'No servers selected — select servers to scope Codemode tools.' }), previewConfigServers.length > 0 ||
|
|
456
|
+
previewCatalogServers.length > 0 ? (_jsxs(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 1 }, children: [previewConfigServers.map(server => (_jsxs(Text, { sx: { fontSize: 0 }, children: [server.name, " \u2014 ", server.tools.length, " tools (config)"] }, server.id))), previewCatalogServers.map(server => (_jsxs(Text, { sx: { fontSize: 0 }, children: [server.name, " \u2014 ", server.tools?.length || 0, " tools (catalog)"] }, server.id)))] })) : (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "No servers selected." })), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', mt: 2 }, children: "Exposed meta-tools: list_tool_names, search_tools, get_tool_details, list_servers, execute_code, call_tool (optional)" })] })), configServers.length > 0 && (_jsx(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 2 }, children: configServers.map(server => (_jsxs(Box, { sx: {
|
|
361
457
|
display: 'flex',
|
|
362
458
|
alignItems: 'flex-start',
|
|
363
459
|
gap: 2,
|
|
364
460
|
padding: 2,
|
|
365
461
|
borderRadius: 1,
|
|
366
462
|
backgroundColor: 'canvas.subtle',
|
|
367
|
-
opacity: mcpServersDisabled
|
|
368
|
-
}, children: [_jsx(Checkbox, { checked:
|
|
463
|
+
opacity: mcpServersDisabled ? 0.6 : 1,
|
|
464
|
+
}, children: [_jsx(Checkbox, { checked: selectedConfigServers.includes(server.id), disabled: mcpServersDisabled, onChange: e => handleConfigServerChange(server.id, e.target.checked) }), _jsxs(Box, { sx: {
|
|
369
465
|
display: 'flex',
|
|
370
466
|
flexDirection: 'column',
|
|
371
467
|
gap: 1,
|
|
372
468
|
flex: 1,
|
|
373
|
-
}, children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Text, { sx: { fontWeight: 'semibold' }, children: server.name }), _jsx(Label, { variant:
|
|
469
|
+
}, children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Text, { sx: { fontWeight: 'semibold' }, children: server.name }), _jsx(Label, { variant: "success", size: "small", children: "Running" })] }), server.tools.length > 0 && (_jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: ["Tools: ", server.tools.map(t => t.name).join(', ')] }))] })] }, server.id))) }))] }), catalogServers.length > 0 && (_jsxs(Box, { sx: {
|
|
470
|
+
marginBottom: 3,
|
|
471
|
+
padding: 3,
|
|
472
|
+
border: '1px solid',
|
|
473
|
+
borderColor: 'border.default',
|
|
474
|
+
borderRadius: 2,
|
|
475
|
+
backgroundColor: 'canvas.default',
|
|
476
|
+
}, children: [_jsxs(Box, { sx: {
|
|
477
|
+
display: 'flex',
|
|
478
|
+
alignItems: 'center',
|
|
479
|
+
gap: 2,
|
|
480
|
+
marginBottom: 2,
|
|
481
|
+
}, children: [_jsx(ToolsIcon, { size: 16 }), _jsx(Text, { sx: { fontSize: 1, fontWeight: 'bold' }, children: "MCP Catalog Servers" })] }), _jsx(Text, { sx: {
|
|
482
|
+
fontSize: 0,
|
|
483
|
+
color: 'fg.muted',
|
|
484
|
+
marginBottom: 2,
|
|
485
|
+
}, children: "Predefined servers that can be enabled on-demand. Select to start and add to your agent." }), _jsx(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 2 }, children: catalogServers.map(server => {
|
|
486
|
+
// If required env vars are not provided, treat as available
|
|
487
|
+
const hasRequiredEnvVars = (server.requiredEnvVars?.length || 0) > 0;
|
|
488
|
+
const envVarsAvailable = hasRequiredEnvVars
|
|
489
|
+
? server.isAvailable === true
|
|
490
|
+
: true;
|
|
491
|
+
const isRunning = server.isRunning === true;
|
|
492
|
+
const canSelect = envVarsAvailable || isRunning;
|
|
493
|
+
return (_jsxs(Box, { sx: {
|
|
494
|
+
display: 'flex',
|
|
495
|
+
alignItems: 'flex-start',
|
|
496
|
+
gap: 2,
|
|
497
|
+
padding: 2,
|
|
498
|
+
borderRadius: 1,
|
|
499
|
+
backgroundColor: 'canvas.subtle',
|
|
500
|
+
opacity: mcpServersDisabled || !canSelect ? 0.6 : 1,
|
|
501
|
+
}, children: [_jsx(Checkbox, { checked: selectedCatalogServers.includes(server.id), disabled: mcpServersDisabled ||
|
|
502
|
+
enableCatalogServerMutation.isPending ||
|
|
503
|
+
!canSelect, onChange: e => handleCatalogServerChange(server.id, e.target.checked, isRunning) }), _jsxs(Box, { sx: {
|
|
504
|
+
display: 'flex',
|
|
505
|
+
flexDirection: 'column',
|
|
506
|
+
gap: 1,
|
|
507
|
+
flex: 1,
|
|
508
|
+
}, children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Text, { sx: { fontWeight: 'semibold' }, children: server.name }), enableCatalogServerMutation.isPending &&
|
|
509
|
+
enableCatalogServerMutation.variables === server.id ? (_jsx(Label, { variant: "accent", size: "small", children: "Starting..." })) : server.isRunning ? (_jsx(Label, { variant: "success", size: "small", children: "Running" })) : (_jsx(Label, { variant: "secondary", size: "small", children: "Not Started" })), server.isConfig && (_jsx(Label, { variant: "secondary", size: "small", children: "From Config" }))] }), hasRequiredEnvVars ? (_jsx(Box, { sx: { display: 'flex', flexWrap: 'wrap', gap: 1 }, children: server.requiredEnvVars?.map(envVar => (_jsx(Label, { variant: envVarsAvailable ? 'success' : 'danger', size: "small", children: envVar }, envVar))) })) : (_jsx(Box, { sx: { display: 'flex' }, children: _jsx(Label, { variant: "success", size: "small", children: "No env vars required" }) })), server.tools && server.tools.length > 0 && (_jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: ["Tools: ", server.tools.map(t => t.name).join(', ')] }))] })] }, server.id));
|
|
510
|
+
}) })] })), createError && (_jsx(Flash, { variant: "danger", sx: { marginBottom: 3 }, children: createError })), _jsxs(Box, { sx: {
|
|
511
|
+
display: 'flex',
|
|
512
|
+
flexDirection: 'column',
|
|
513
|
+
gap: 2,
|
|
514
|
+
marginBottom: 3,
|
|
515
|
+
padding: 3,
|
|
516
|
+
bg: 'canvas.subtle',
|
|
517
|
+
borderRadius: 2,
|
|
518
|
+
border: '1px solid',
|
|
519
|
+
borderColor: 'border.default',
|
|
520
|
+
opacity: 0.6,
|
|
521
|
+
}, children: [_jsx(Text, { sx: { fontSize: 1, fontWeight: 'semibold', color: 'fg.muted' }, children: "Coming Soon" }), _jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Checkbox, { checked: false, disabled: true, onChange: () => { } }), _jsx(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: "Rich Editor" }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "\u2014 Enable rich text editing with formatting options" })] }), _jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Checkbox, { checked: false, disabled: true, onChange: () => { } }), _jsx(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: "Durable" }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "\u2014 Persist agent state across sessions" })] })] }), _jsx(Button, { variant: "primary", onClick: onConnect, disabled: isCreatingAgent ||
|
|
374
522
|
!agentName ||
|
|
375
523
|
(transport === 'acp' ? !wsUrl : !baseUrl), sx: { width: '100%' }, children: isCreatingAgent ? (_jsxs(Box, { sx: {
|
|
376
524
|
display: 'flex',
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
interface FooterMetricsProps {
|
|
2
|
+
export interface FooterMetricsProps {
|
|
3
3
|
tokens: number;
|
|
4
4
|
cost: number;
|
|
5
5
|
}
|
|
@@ -9,4 +9,3 @@ interface FooterMetricsProps {
|
|
|
9
9
|
* Displays token usage and cost.
|
|
10
10
|
*/
|
|
11
11
|
export declare const FooterMetrics: React.FC<FooterMetricsProps>;
|
|
12
|
-
export {};
|
|
@@ -1,17 +1,13 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
interface HeaderProps {
|
|
2
|
+
export interface HeaderProps {
|
|
3
3
|
activeSession: string;
|
|
4
4
|
agentName?: string;
|
|
5
5
|
agentDescription?: string;
|
|
6
6
|
agentStatus?: 'running' | 'paused';
|
|
7
|
-
richEditor: boolean;
|
|
8
|
-
durable: boolean;
|
|
9
7
|
showContextTree: boolean;
|
|
10
8
|
isNewAgent?: boolean;
|
|
11
9
|
isConfigured?: boolean;
|
|
12
10
|
onSessionChange: (sessionId: string) => void;
|
|
13
|
-
onRichEditorChange: (value: boolean) => void;
|
|
14
|
-
onDurableChange: (value: boolean) => void;
|
|
15
11
|
onToggleContextTree: () => void;
|
|
16
12
|
onToggleStatus?: () => void;
|
|
17
13
|
}
|
|
@@ -22,4 +18,3 @@ interface HeaderProps {
|
|
|
22
18
|
* toggle switches, controls, and optional context treemap.
|
|
23
19
|
*/
|
|
24
20
|
export declare const Header: React.FC<HeaderProps>;
|
|
25
|
-
export {};
|
|
@@ -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
|
};
|