@datalayer/agent-runtimes 0.0.5 → 0.0.8
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 +150 -22
- package/lib/components/chat/components/AgentDetails.d.ts +15 -2
- package/lib/components/chat/components/AgentDetails.js +9 -93
- package/lib/components/chat/components/AgentIdentity.d.ts +92 -0
- package/lib/components/chat/components/AgentIdentity.js +318 -0
- package/lib/components/chat/components/Chat.d.ts +24 -1
- package/lib/components/chat/components/Chat.js +41 -19
- package/lib/components/chat/components/ChatFloating.d.ts +6 -1
- package/lib/components/chat/components/ChatFloating.js +12 -6
- package/lib/components/chat/components/ContextDistribution.d.ts +47 -0
- package/lib/components/chat/components/ContextDistribution.js +146 -0
- package/lib/components/chat/components/ContextUsage.d.ts +33 -0
- package/lib/components/chat/components/ContextUsage.js +127 -0
- package/lib/components/chat/components/base/ChatBase.d.ts +51 -1
- package/lib/components/chat/components/base/ChatBase.js +278 -74
- package/lib/components/chat/components/display/ToolCallDisplay.d.ts +16 -2
- package/lib/components/chat/components/display/ToolCallDisplay.js +148 -6
- package/lib/components/chat/components/display/index.d.ts +1 -1
- package/lib/components/chat/components/display/index.js +1 -1
- package/lib/components/chat/components/elements/ChatInputPrompt.d.ts +12 -1
- package/lib/components/chat/components/elements/ChatInputPrompt.js +8 -3
- package/lib/components/chat/components/index.d.ts +3 -0
- package/lib/components/chat/components/index.js +3 -0
- package/lib/components/chat/components/parts/ToolPart.d.ts +1 -1
- package/lib/components/chat/components/parts/ToolPart.js +142 -6
- package/lib/components/chat/index.d.ts +1 -1
- package/lib/components/chat/index.js +1 -1
- package/lib/components/chat/protocols/A2AAdapter.d.ts +9 -0
- package/lib/components/chat/protocols/A2AAdapter.js +13 -2
- package/lib/components/chat/protocols/ACPAdapter.d.ts +9 -0
- package/lib/components/chat/protocols/ACPAdapter.js +13 -2
- package/lib/components/chat/protocols/AGUIAdapter.d.ts +9 -0
- package/lib/components/chat/protocols/AGUIAdapter.js +19 -1
- package/lib/components/chat/protocols/VercelAIAdapter.d.ts +7 -0
- package/lib/components/chat/protocols/VercelAIAdapter.js +19 -0
- package/lib/components/chat/types/execution.d.ts +78 -0
- package/lib/components/chat/types/execution.js +64 -0
- package/lib/components/chat/types/index.d.ts +1 -0
- package/lib/components/chat/types/index.js +1 -0
- package/lib/components/chat/types/protocol.d.ts +9 -0
- package/lib/components/ui/pagination.d.ts +2 -2
- package/lib/components/ui/pagination.js +4 -4
- package/lib/components/ui/resizable.d.ts +4 -4
- package/lib/components/ui/resizable.js +4 -4
- package/lib/examples/A2UiRestaurantExample.js +2 -2
- package/lib/examples/AgUiAgenticExample.js +2 -2
- package/lib/examples/AgUiBackendToolRenderingExample.js +2 -2
- package/lib/examples/AgUiHaikuGenUIExample.js +2 -2
- package/lib/examples/AgUiHumanInTheLoopExample.js +2 -2
- package/lib/examples/AgUiSharedStateExample.js +2 -2
- package/lib/examples/AgUiToolsBasedGenUIExample.js +2 -2
- package/lib/examples/AgentRuntimeCustomExample.js +2 -2
- package/lib/examples/AgentRuntimeLexical2Example.js +2 -1
- package/lib/examples/AgentRuntimeLexicalExample.js +5 -2
- package/lib/examples/AgentRuntimeLexicalSidebarExample.js +4 -2
- package/lib/examples/AgentRuntimeNotebookExample.js +1 -1
- package/lib/examples/AgentRuntimeStandaloneExample.js +2 -2
- package/lib/examples/AgentSpaceFormExample.d.ts +70 -2
- package/lib/examples/AgentSpaceFormExample.js +204 -35
- package/lib/examples/CopilotKitLexicalExample.js +2 -1
- package/lib/examples/components/AgentConfiguration.d.ts +37 -0
- package/lib/examples/components/AgentConfiguration.js +239 -8
- package/lib/examples/components/Header.d.ts +0 -2
- package/lib/examples/components/Header.js +2 -16
- package/lib/examples/components/LexicalEditor.js +2 -1
- package/lib/examples/components/MockFileBrowser.js +6 -2
- package/lib/examples/components/index.d.ts +0 -1
- package/lib/examples/components/index.js +0 -1
- package/lib/examples/example-selector.js +0 -1
- package/lib/examples/index.d.ts +0 -1
- package/lib/examples/index.js +0 -1
- package/lib/examples/lexical/editorConfig.d.ts +3 -2
- package/lib/examples/lexical/editorConfig.js +7 -1
- package/lib/examples/lexical/initial-content.json +2210 -0
- package/lib/examples/main.js +15 -1
- package/lib/identity/IdentityConnect.d.ts +90 -0
- package/lib/identity/IdentityConnect.js +316 -0
- package/lib/identity/OAuthCallback.d.ts +58 -0
- package/lib/identity/OAuthCallback.js +223 -0
- package/lib/identity/dcr.d.ts +257 -0
- package/lib/identity/dcr.js +282 -0
- package/lib/identity/identityStore.d.ts +72 -0
- package/lib/identity/identityStore.js +529 -0
- package/lib/identity/index.d.ts +46 -0
- package/lib/identity/index.js +17 -0
- package/lib/identity/pkce.d.ts +30 -0
- package/lib/identity/pkce.js +65 -0
- package/lib/identity/types.d.ts +293 -0
- package/lib/identity/types.js +73 -0
- package/lib/identity/useIdentity.d.ts +108 -0
- package/lib/identity/useIdentity.js +323 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.js +2 -0
- package/lib/lib/utils.js +1 -1
- package/lib/renderers/a2ui/lib/utils.js +1 -1
- package/lib/runtime/index.d.ts +35 -0
- package/lib/runtime/index.js +40 -0
- package/lib/runtime/runtimeStore.d.ts +77 -0
- package/lib/runtime/runtimeStore.js +184 -0
- package/lib/runtime/types.d.ts +84 -0
- package/lib/runtime/types.js +15 -0
- package/lib/runtime/useAgentConnection.d.ts +46 -0
- package/lib/runtime/useAgentConnection.js +112 -0
- package/lib/runtime/useAgentRuntime.d.ts +94 -0
- package/lib/runtime/useAgentRuntime.js +125 -0
- package/lib/test-setup.d.ts +1 -1
- package/lib/test-setup.js +1 -0
- package/lib/tools/adapters/agent-runtimes/AgentRuntimesToolAdapter.js +32 -1
- package/lib/tools/adapters/agent-runtimes/lexicalHooks.d.ts +6 -0
- package/lib/tools/adapters/agent-runtimes/lexicalHooks.js +16 -17
- package/package.json +20 -7
- package/patches/@datalayer+jupyter-lexical+1.0.8.patch +11628 -0
- package/patches/@datalayer+jupyter-react+2.0.2.patch +5338 -0
- package/lib/examples/AgentSpaceHomeExample.d.ts +0 -8
- package/lib/examples/AgentSpaceHomeExample.js +0 -171
- package/lib/examples/components/AgentsDataTable.d.ts +0 -13
- package/lib/examples/components/AgentsDataTable.js +0 -74
- package/lib/examples/components/Rating.d.ts +0 -14
- package/lib/examples/components/Rating.js +0 -12
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { Transport } from '../components/chat';
|
|
3
|
+
import { type AgentLibrary } from './components';
|
|
1
4
|
/**
|
|
2
5
|
* Agent Runtime Example Component
|
|
3
6
|
*
|
|
@@ -10,13 +13,78 @@
|
|
|
10
13
|
* - Real-time streaming responses
|
|
11
14
|
* - Permission request handling
|
|
12
15
|
* - Connection state management
|
|
16
|
+
* - **OAuth Identity** - Connect GitHub accounts to give agents access to repositories
|
|
17
|
+
* - **Token Identity** - Connect Kaggle accounts for dataset and notebook access
|
|
13
18
|
*
|
|
14
19
|
* Usage:
|
|
15
20
|
* 1. Start the agent-runtimes server: `npm run start:acp`
|
|
16
21
|
* 2. The UI will automatically connect to the ACP server
|
|
17
22
|
* 3. Select your agent library and transport
|
|
18
23
|
* 4. Enter the WebSocket URL and Agent ID (or use defaults)
|
|
19
|
-
* 5.
|
|
24
|
+
* 5. Connect your GitHub account for repository access
|
|
25
|
+
* 6. Connect your Kaggle account for dataset access
|
|
26
|
+
* 7. Click Connect and start chatting!
|
|
20
27
|
*/
|
|
21
|
-
|
|
28
|
+
/**
|
|
29
|
+
* OAuth provider configuration
|
|
30
|
+
*/
|
|
31
|
+
interface OAuthProviderInput {
|
|
32
|
+
type: 'oauth';
|
|
33
|
+
clientId: string;
|
|
34
|
+
scopes?: string[];
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Token-based provider configuration
|
|
38
|
+
*/
|
|
39
|
+
interface TokenProviderInput {
|
|
40
|
+
type: 'token';
|
|
41
|
+
token: string;
|
|
42
|
+
displayName?: string;
|
|
43
|
+
iconUrl?: string;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Unified identity provider input (OAuth or token-based)
|
|
47
|
+
*/
|
|
48
|
+
type IdentityProviderInput = OAuthProviderInput | TokenProviderInput;
|
|
49
|
+
/**
|
|
50
|
+
* Identity providers configuration map.
|
|
51
|
+
* Supports multiple OAuth providers (github, google, etc.) and
|
|
52
|
+
* multiple token-based providers (kaggle, huggingface, etc.)
|
|
53
|
+
*/
|
|
54
|
+
type IdentityProvidersInput = {
|
|
55
|
+
[provider: string]: IdentityProviderInput;
|
|
56
|
+
};
|
|
57
|
+
type AgentSpaceFormExampleProps = {
|
|
58
|
+
initialWsUrl?: string;
|
|
59
|
+
initialBaseUrl?: string;
|
|
60
|
+
initialAgentName?: string;
|
|
61
|
+
initialAgentLibrary?: AgentLibrary;
|
|
62
|
+
initialTransport?: Transport;
|
|
63
|
+
initialModel?: string;
|
|
64
|
+
initialEnableCodemode?: boolean;
|
|
65
|
+
initialAllowDirectToolCalls?: boolean;
|
|
66
|
+
initialEnableToolReranker?: boolean;
|
|
67
|
+
initialSelectedMcpServers?: string[];
|
|
68
|
+
autoSelectMcpServers?: boolean;
|
|
69
|
+
/**
|
|
70
|
+
* Identity providers configuration.
|
|
71
|
+
* Supports both OAuth and token-based providers.
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* ```tsx
|
|
75
|
+
* identityProviders={{
|
|
76
|
+
* github: { type: 'oauth', clientId: 'xxx', scopes: ['repo'] },
|
|
77
|
+
* google: { type: 'oauth', clientId: 'yyy' },
|
|
78
|
+
* kaggle: { type: 'token', token: 'zzz' },
|
|
79
|
+
* huggingface: { type: 'token', token: 'aaa', displayName: 'HuggingFace' },
|
|
80
|
+
* }}
|
|
81
|
+
* ```
|
|
82
|
+
*/
|
|
83
|
+
identityProviders?: IdentityProvidersInput;
|
|
84
|
+
/** @deprecated Use identityProviders instead */
|
|
85
|
+
githubClientId?: string;
|
|
86
|
+
/** @deprecated Use identityProviders instead */
|
|
87
|
+
kaggleToken?: string;
|
|
88
|
+
};
|
|
89
|
+
declare const AgentSpaceFormExample: React.FC<AgentSpaceFormExampleProps>;
|
|
22
90
|
export default AgentSpaceFormExample;
|
|
@@ -4,16 +4,17 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
4
4
|
* Distributed under the terms of the Modified BSD License.
|
|
5
5
|
*/
|
|
6
6
|
/// <reference types="vite/client" />
|
|
7
|
-
import { useState, useEffect, useCallback } from 'react';
|
|
7
|
+
import React, { useState, useEffect, useCallback, useRef } from 'react';
|
|
8
8
|
import { PageLayout, IconButton } from '@primer/react';
|
|
9
9
|
import { SidebarCollapseIcon, SidebarExpandIcon } from '@primer/octicons-react';
|
|
10
10
|
import { AiAgentIcon } from '@datalayer/icons-react';
|
|
11
11
|
import { Blankslate } from '@primer/react/experimental';
|
|
12
12
|
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
13
13
|
import { Box } from '@datalayer/primer-addons';
|
|
14
|
-
import {
|
|
14
|
+
import { DatalayerThemeProvider } from '@datalayer/core';
|
|
15
15
|
import { Chat } from '../components/chat';
|
|
16
16
|
import { useAgentsStore } from './stores/examplesStore';
|
|
17
|
+
import { useIdentity } from '../identity';
|
|
17
18
|
import { MockFileBrowser, MainContent, Header, FooterMetrics, AgentConfiguration, } from './components';
|
|
18
19
|
// Create a query client for React Query
|
|
19
20
|
const queryClient = new QueryClient({
|
|
@@ -31,40 +32,161 @@ const queryClient = new QueryClient({
|
|
|
31
32
|
const DEFAULT_WS_URL = import.meta.env.VITE_ACP_WS_URL || 'ws://localhost:8765/api/v1/acp/ws';
|
|
32
33
|
const DEFAULT_BASE_URL = import.meta.env.VITE_BASE_URL || 'http://localhost:8765';
|
|
33
34
|
const DEFAULT_AGENT_ID = 'demo-agent';
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
35
|
+
// GitHub OAuth client ID - set via environment variable for security
|
|
36
|
+
// For development, you can create a GitHub OAuth App at:
|
|
37
|
+
// https://github.com/settings/developers
|
|
38
|
+
const GITHUB_CLIENT_ID = import.meta.env.VITE_GITHUB_CLIENT_ID || 'demo-client-id';
|
|
39
|
+
// Kaggle API token - set via environment variable
|
|
40
|
+
// Get your token at: https://www.kaggle.com/settings/account (API section)
|
|
41
|
+
// Download kaggle.json and use the "key" value
|
|
42
|
+
const KAGGLE_TOKEN = import.meta.env.VITE_KAGGLE_TOKEN || '';
|
|
43
|
+
const MOCK_SKILLS = [];
|
|
44
|
+
// Skills are now fetched dynamically from the backend API (/api/v1/skills)
|
|
45
|
+
// when Codemode is enabled. The AgentConfiguration component handles this.
|
|
46
|
+
// Build default identity providers from env vars (backward compatibility)
|
|
47
|
+
const DEFAULT_IDENTITY_PROVIDERS = {
|
|
48
|
+
...(GITHUB_CLIENT_ID
|
|
49
|
+
? {
|
|
50
|
+
github: {
|
|
51
|
+
type: 'oauth',
|
|
52
|
+
clientId: GITHUB_CLIENT_ID,
|
|
53
|
+
scopes: ['read:user', 'user:email', 'repo'],
|
|
54
|
+
},
|
|
55
|
+
}
|
|
56
|
+
: {}),
|
|
57
|
+
...(KAGGLE_TOKEN
|
|
58
|
+
? {
|
|
59
|
+
kaggle: {
|
|
60
|
+
type: 'token',
|
|
61
|
+
token: KAGGLE_TOKEN,
|
|
62
|
+
displayName: 'Kaggle',
|
|
63
|
+
iconUrl: 'https://www.kaggle.com/static/images/favicon.ico',
|
|
64
|
+
},
|
|
65
|
+
}
|
|
66
|
+
: {}),
|
|
67
|
+
};
|
|
68
|
+
const AgentSpaceFormExample = ({ initialWsUrl = DEFAULT_WS_URL, initialBaseUrl = DEFAULT_BASE_URL, initialAgentName = DEFAULT_AGENT_ID, initialAgentLibrary = 'pydantic-ai', initialTransport = 'ag-ui', initialModel = 'bedrock:us.anthropic.claude-sonnet-4-5-20250929-v1:0', initialEnableCodemode = false, initialAllowDirectToolCalls = false, initialEnableToolReranker = false, initialSelectedMcpServers = [], autoSelectMcpServers = false, identityProviders = DEFAULT_IDENTITY_PROVIDERS,
|
|
69
|
+
// Deprecated props - merged into identityProviders for backward compat
|
|
70
|
+
githubClientId, kaggleToken, }) => {
|
|
71
|
+
const [wsUrl, setWsUrl] = useState(initialWsUrl);
|
|
72
|
+
const [baseUrl, setBaseUrl] = useState(initialBaseUrl);
|
|
73
|
+
const [agentName, setAgentName] = useState(initialAgentName);
|
|
58
74
|
const [selectedAgentId, setSelectedAgentId] = useState('new-agent');
|
|
59
|
-
const [agentLibrary, setAgentLibrary] = useState(
|
|
60
|
-
const [transport, setTransport] = useState(
|
|
75
|
+
const [agentLibrary, setAgentLibrary] = useState(initialAgentLibrary);
|
|
76
|
+
const [transport, setTransport] = useState(initialTransport);
|
|
61
77
|
const [extensions, setExtensions] = useState([]);
|
|
78
|
+
const [model, setModel] = useState(initialModel);
|
|
62
79
|
const [isConfigured, setIsConfigured] = useState(false);
|
|
80
|
+
// Agent capabilities state (moved from Header toggles)
|
|
81
|
+
const [selectedSkills, setSelectedSkills] = useState([]);
|
|
82
|
+
const [enableCodemode, setEnableCodemode] = useState(initialEnableCodemode);
|
|
83
|
+
const [allowDirectToolCalls, setAllowDirectToolCalls] = useState(initialAllowDirectToolCalls);
|
|
84
|
+
const [enableToolReranker, setEnableToolReranker] = useState(initialEnableToolReranker);
|
|
85
|
+
const [selectedMcpServers, setSelectedMcpServers] = useState(initialSelectedMcpServers);
|
|
86
|
+
const autoSelectRef = useRef(false);
|
|
87
|
+
const enableSkills = selectedSkills.length > 0;
|
|
88
|
+
// Merge deprecated props into identityProviders for backward compatibility
|
|
89
|
+
const mergedIdentityProviders = React.useMemo(() => {
|
|
90
|
+
const merged = { ...identityProviders };
|
|
91
|
+
// Add deprecated githubClientId if provided and not already in config
|
|
92
|
+
if (githubClientId && !merged.github) {
|
|
93
|
+
merged.github = {
|
|
94
|
+
type: 'oauth',
|
|
95
|
+
clientId: githubClientId,
|
|
96
|
+
scopes: ['read:user', 'user:email', 'repo'],
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
// Add deprecated kaggleToken if provided and not already in config
|
|
100
|
+
if (kaggleToken && !merged.kaggle) {
|
|
101
|
+
merged.kaggle = {
|
|
102
|
+
type: 'token',
|
|
103
|
+
token: kaggleToken,
|
|
104
|
+
displayName: 'Kaggle',
|
|
105
|
+
iconUrl: 'https://www.kaggle.com/static/images/favicon.ico',
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
return merged;
|
|
109
|
+
}, [identityProviders, githubClientId, kaggleToken]);
|
|
110
|
+
// Extract OAuth providers for useIdentity hook (token providers are handled separately)
|
|
111
|
+
const oauthProvidersConfig = React.useMemo(() => {
|
|
112
|
+
const providers = {};
|
|
113
|
+
for (const [provider, config] of Object.entries(mergedIdentityProviders)) {
|
|
114
|
+
if (config.type === 'oauth') {
|
|
115
|
+
providers[provider] = {
|
|
116
|
+
clientId: config.clientId,
|
|
117
|
+
scopes: config.scopes,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return Object.keys(providers).length > 0 ? providers : undefined;
|
|
122
|
+
}, [mergedIdentityProviders]);
|
|
123
|
+
// Extract token-based providers for auto-connection
|
|
124
|
+
const tokenProviders = React.useMemo(() => {
|
|
125
|
+
const providers = [];
|
|
126
|
+
for (const [provider, config] of Object.entries(mergedIdentityProviders)) {
|
|
127
|
+
if (config.type === 'token') {
|
|
128
|
+
providers.push({
|
|
129
|
+
provider,
|
|
130
|
+
token: config.token,
|
|
131
|
+
displayName: config.displayName,
|
|
132
|
+
iconUrl: config.iconUrl,
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return providers;
|
|
137
|
+
}, [mergedIdentityProviders]);
|
|
138
|
+
// Identity state - pass OAuth providers to configure them before callback is processed
|
|
139
|
+
const { connectWithToken, isConnected: isIdentityConnected } = useIdentity({
|
|
140
|
+
providers: oauthProvidersConfig,
|
|
141
|
+
autoHandleCallback: true,
|
|
142
|
+
});
|
|
143
|
+
// Track which token providers we've attempted to connect
|
|
144
|
+
const connectedTokenProvidersRef = useRef(new Set());
|
|
145
|
+
// Auto-connect all token-based providers if available and not already connected
|
|
146
|
+
useEffect(() => {
|
|
147
|
+
for (const { provider, token, displayName, iconUrl } of tokenProviders) {
|
|
148
|
+
// Skip if we've already attempted to connect this provider
|
|
149
|
+
if (connectedTokenProvidersRef.current.has(provider)) {
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
// Skip if already connected
|
|
153
|
+
if (isIdentityConnected(provider)) {
|
|
154
|
+
connectedTokenProvidersRef.current.add(provider);
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
// Mark as attempted
|
|
158
|
+
connectedTokenProvidersRef.current.add(provider);
|
|
159
|
+
connectWithToken(provider, token, { displayName, iconUrl })
|
|
160
|
+
.then(() => {
|
|
161
|
+
console.log(`[AgentSpaceFormExample] ${provider} connected with token`);
|
|
162
|
+
})
|
|
163
|
+
.catch(err => {
|
|
164
|
+
console.error(`[AgentSpaceFormExample] Failed to connect ${provider}:`, err);
|
|
165
|
+
// Remove from attempted set so we can retry
|
|
166
|
+
connectedTokenProvidersRef.current.delete(provider);
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
}, [tokenProviders, connectWithToken, isIdentityConnected]);
|
|
170
|
+
// Handle identity connect/disconnect
|
|
171
|
+
const handleIdentityConnect = useCallback((identity) => {
|
|
172
|
+
console.log('[AgentSpaceFormExample] Identity connected:', identity.provider, identity.userInfo?.name || identity.userInfo?.email);
|
|
173
|
+
}, []);
|
|
174
|
+
const handleIdentityDisconnect = useCallback((provider) => {
|
|
175
|
+
console.log('[AgentSpaceFormExample] Identity disconnected:', provider);
|
|
176
|
+
}, []);
|
|
177
|
+
// Handle codemode change - keep MCP server selections to scope codemode tools
|
|
178
|
+
const handleEnableCodemodeChange = (enabled) => {
|
|
179
|
+
setEnableCodemode(enabled);
|
|
180
|
+
if (!enabled) {
|
|
181
|
+
setAllowDirectToolCalls(false);
|
|
182
|
+
setEnableToolReranker(false);
|
|
183
|
+
}
|
|
184
|
+
};
|
|
63
185
|
// UI state
|
|
64
186
|
const [activeSession, setActiveSession] = useState('session-1');
|
|
65
187
|
const [richEditor, setRichEditor] = useState(false);
|
|
66
188
|
const [durable, setDurable] = useState(true);
|
|
67
|
-
const [codemode,
|
|
189
|
+
const [codemode, _] = useState(false);
|
|
68
190
|
const [showContextTree, setShowContextTree] = useState(false);
|
|
69
191
|
const [showNotebook] = useState(true);
|
|
70
192
|
const [leftPaneVisible, setLeftPaneVisible] = useState(true);
|
|
@@ -83,6 +205,35 @@ const AgentSpaceFormExample = () => {
|
|
|
83
205
|
setAgentName(currentAgent.id);
|
|
84
206
|
}
|
|
85
207
|
}, [currentAgent]);
|
|
208
|
+
// Auto-select MCP servers for codemode when requested
|
|
209
|
+
useEffect(() => {
|
|
210
|
+
if (!autoSelectMcpServers || autoSelectRef.current)
|
|
211
|
+
return;
|
|
212
|
+
if (!enableCodemode)
|
|
213
|
+
return;
|
|
214
|
+
if (selectedMcpServers.length > 0)
|
|
215
|
+
return;
|
|
216
|
+
if (!baseUrl)
|
|
217
|
+
return;
|
|
218
|
+
const loadServers = async () => {
|
|
219
|
+
try {
|
|
220
|
+
const response = await fetch(`${baseUrl}/api/v1/configure`);
|
|
221
|
+
if (!response.ok)
|
|
222
|
+
return;
|
|
223
|
+
const data = await response.json();
|
|
224
|
+
const servers = data?.mcpServers || [];
|
|
225
|
+
const available = servers.filter((s) => s.isAvailable);
|
|
226
|
+
if (available.length > 0) {
|
|
227
|
+
setSelectedMcpServers([available[0].id]);
|
|
228
|
+
autoSelectRef.current = true;
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
catch {
|
|
232
|
+
// no-op
|
|
233
|
+
}
|
|
234
|
+
};
|
|
235
|
+
void loadServers();
|
|
236
|
+
}, [autoSelectMcpServers, enableCodemode, selectedMcpServers, baseUrl]);
|
|
86
237
|
const handleAgentSelect = (agentId) => {
|
|
87
238
|
setSelectedAgentId(agentId);
|
|
88
239
|
setCreateError(null);
|
|
@@ -116,8 +267,14 @@ const AgentSpaceFormExample = () => {
|
|
|
116
267
|
description: `Agent created via UI (${agentLibrary})`,
|
|
117
268
|
agent_library: agentLibrary,
|
|
118
269
|
transport: transport,
|
|
119
|
-
model:
|
|
270
|
+
model: model,
|
|
120
271
|
system_prompt: 'You are a helpful AI assistant.',
|
|
272
|
+
enable_skills: enableSkills,
|
|
273
|
+
enable_codemode: enableCodemode,
|
|
274
|
+
allow_direct_tool_calls: allowDirectToolCalls,
|
|
275
|
+
enable_tool_reranker: enableToolReranker,
|
|
276
|
+
selected_mcp_servers: selectedMcpServers,
|
|
277
|
+
skills: selectedSkills,
|
|
121
278
|
}),
|
|
122
279
|
});
|
|
123
280
|
if (!response.ok) {
|
|
@@ -139,7 +296,19 @@ const AgentSpaceFormExample = () => {
|
|
|
139
296
|
finally {
|
|
140
297
|
setIsCreatingAgent(false);
|
|
141
298
|
}
|
|
142
|
-
}, [
|
|
299
|
+
}, [
|
|
300
|
+
baseUrl,
|
|
301
|
+
agentName,
|
|
302
|
+
agentLibrary,
|
|
303
|
+
transport,
|
|
304
|
+
model,
|
|
305
|
+
enableSkills,
|
|
306
|
+
enableCodemode,
|
|
307
|
+
allowDirectToolCalls,
|
|
308
|
+
enableToolReranker,
|
|
309
|
+
selectedMcpServers,
|
|
310
|
+
selectedSkills,
|
|
311
|
+
]);
|
|
143
312
|
/**
|
|
144
313
|
* Delete an agent via the API
|
|
145
314
|
*/
|
|
@@ -204,9 +373,9 @@ const AgentSpaceFormExample = () => {
|
|
|
204
373
|
}
|
|
205
374
|
setIsConfigured(false);
|
|
206
375
|
};
|
|
207
|
-
return (_jsx(QueryClientProvider, { client: queryClient, children: _jsx(DatalayerThemeProvider, {
|
|
376
|
+
return (_jsx(QueryClientProvider, { client: queryClient, children: _jsx(DatalayerThemeProvider, { children: _jsxs(PageLayout, { containerWidth: "full", children: [_jsx(Header, { activeSession: activeSession, agentName: selectedAgentId === 'new-agent' ? undefined : currentAgent?.name, agentDescription: selectedAgentId === 'new-agent'
|
|
208
377
|
? undefined
|
|
209
|
-
: currentAgent?.description, agentStatus: currentAgent?.status, richEditor: richEditor, durable: durable,
|
|
378
|
+
: currentAgent?.description, agentStatus: currentAgent?.status, richEditor: richEditor, durable: durable, showContextTree: showContextTree, isNewAgent: selectedAgentId === 'new-agent', isConfigured: isConfigured, onSessionChange: setActiveSession, onRichEditorChange: setRichEditor, onDurableChange: setDurable, onToggleContextTree: () => setShowContextTree(!showContextTree), onToggleStatus: currentAgent
|
|
210
379
|
? () => toggleAgentStatus(currentAgent.id)
|
|
211
380
|
: undefined }), leftPaneVisible ? (_jsxs(_Fragment, { children: [_jsx(Box, { sx: {
|
|
212
381
|
position: 'fixed',
|
|
@@ -249,9 +418,9 @@ const AgentSpaceFormExample = () => {
|
|
|
249
418
|
display: 'flex',
|
|
250
419
|
flexDirection: 'column',
|
|
251
420
|
p: 2,
|
|
252
|
-
}, children: !isConfigured ? (_jsx(AgentConfiguration, { agentLibrary: agentLibrary, transport: currentAgent?.transport || transport, extensions: extensions, wsUrl: wsUrl, baseUrl: baseUrl, agentName: agentName, agents: agents, selectedAgentId: selectedAgentId, isCreatingAgent: isCreatingAgent, createError: createError, onAgentLibraryChange: setAgentLibrary, onTransportChange: setTransport, onExtensionsChange: setExtensions, onWsUrlChange: setWsUrl, onBaseUrlChange: setBaseUrl, onAgentNameChange: setAgentName, onAgentSelect: handleAgentSelect, onConnect: handleConnect })) : (
|
|
421
|
+
}, children: !isConfigured ? (_jsx(AgentConfiguration, { agentLibrary: agentLibrary, transport: currentAgent?.transport || transport, extensions: extensions, wsUrl: wsUrl, baseUrl: baseUrl, agentName: agentName, model: model, agents: agents, selectedAgentId: selectedAgentId, isCreatingAgent: isCreatingAgent, createError: createError, enableCodemode: enableCodemode, allowDirectToolCalls: allowDirectToolCalls, enableToolReranker: enableToolReranker, availableSkills: MOCK_SKILLS, selectedSkills: selectedSkills, selectedMcpServers: selectedMcpServers, identityProviders: oauthProvidersConfig, onIdentityConnect: handleIdentityConnect, onIdentityDisconnect: handleIdentityDisconnect, onAgentLibraryChange: setAgentLibrary, onTransportChange: setTransport, onExtensionsChange: setExtensions, onWsUrlChange: setWsUrl, onBaseUrlChange: setBaseUrl, onAgentNameChange: setAgentName, onModelChange: setModel, onAgentSelect: handleAgentSelect, onConnect: handleConnect, onEnableCodemodeChange: handleEnableCodemodeChange, onAllowDirectToolCallsChange: setAllowDirectToolCalls, onEnableToolRerankerChange: setEnableToolReranker, onSelectedSkillsChange: setSelectedSkills, onSelectedMcpServersChange: setSelectedMcpServers })) : (
|
|
253
422
|
/* Chat Interface */
|
|
254
|
-
_jsx(Box, { sx: { flex: 1 }, children: _jsx(Chat, { transport: currentAgent?.transport || transport, extensions: extensions, wsUrl: wsUrl, baseUrl: baseUrl, agentId: currentAgent?.id || agentName, title: currentAgent?.name || agentName || 'AI Assistant', autoConnect: true, autoFocus: true, placeholder: "Type your message to the agent...", height: "calc(100vh - 250px)", suggestions: [
|
|
423
|
+
_jsx(Box, { sx: { flex: 1 }, children: _jsx(Chat, { transport: currentAgent?.transport || transport, extensions: extensions, wsUrl: wsUrl, baseUrl: baseUrl, agentId: currentAgent?.id || agentName, title: currentAgent?.name || agentName || 'AI Assistant', autoConnect: true, autoFocus: true, placeholder: "Type your message to the agent...", height: "calc(100vh - 250px)", showModelSelector: true, showToolsMenu: true, showSkillsMenu: true, codemodeEnabled: enableCodemode, initialModel: model, initialMcpServers: selectedMcpServers, initialSkills: selectedSkills, identityProviders: oauthProvidersConfig, onIdentityConnect: handleIdentityConnect, onIdentityDisconnect: handleIdentityDisconnect, suggestions: [
|
|
255
424
|
{
|
|
256
425
|
title: '👋 Say hello',
|
|
257
426
|
message: 'Hello! What can you help me with today?',
|
|
@@ -114,6 +114,7 @@ function SimpleKernelPluginsInner() {
|
|
|
114
114
|
}
|
|
115
115
|
const LexicalUI = React.memo(function LexicalUI({ content = INITIAL_CONTENT, serviceManager, }) {
|
|
116
116
|
const [floatingAnchorElem, setFloatingAnchorElem] = useState(null);
|
|
117
|
+
const [_isLinkEditMode, setIsLinkEditMode] = useState(false);
|
|
117
118
|
const onRef = (_floatingAnchorElem) => {
|
|
118
119
|
if (_floatingAnchorElem !== null) {
|
|
119
120
|
setFloatingAnchorElem(_floatingAnchorElem);
|
|
@@ -145,7 +146,7 @@ const LexicalUI = React.memo(function LexicalUI({ content = INITIAL_CONTENT, ser
|
|
|
145
146
|
padding: 3,
|
|
146
147
|
backgroundColor: 'canvas.default',
|
|
147
148
|
minHeight: '600px',
|
|
148
|
-
}, children: _jsx(LexicalConfigProvider, { lexicalId: LEXICAL_ID, serviceManager: serviceManager, children: _jsx(LexicalComposer, { initialConfig: editorConfig, children: _jsxs("div", { className: "lexical-editor-inner", ref: onRef, children: [_jsx(LexicalStatePlugin, {}), _jsx(RichTextPlugin, { contentEditable: _jsx(ContentEditable, { className: "lexical-editor-content", "aria-label": "Lexical Editor" }), ErrorBoundary: LexicalErrorBoundary }), _jsx(OnChangePlugin, { onChange: handleChange }), _jsx(HistoryPlugin, {}), _jsx(AutoFocusPlugin, {}), _jsx(ListPlugin, {}), _jsx(CheckListPlugin, {}), _jsx(LinkPlugin, {}), _jsx(AutoLinkPlugin, {}), _jsx(ListMaxIndentLevelPlugin, { maxDepth: 7 }), _jsx(MarkdownShortcutPlugin, { transformers: TRANSFORMERS }), _jsx(LoadContentPlugin, { content: content }), _jsx(CodeHighlightPlugin, {}), _jsx(ImagesPlugin, { captionsEnabled: false }), _jsx(HorizontalRulePlugin, {}), _jsx(EquationsPlugin, {}), _jsx(YouTubePlugin, {}), _jsx(AutoEmbedPlugin, {}), _jsx(JupyterCellPlugin, {}), _jsx(JupyterReactTheme, { children: _jsx(SimpleKernelPluginsInner, {}) }), floatingAnchorElem && (_jsxs(_Fragment, { children: [_jsx(DraggableBlockPlugin, { anchorElem: floatingAnchorElem }), _jsx(FloatingTextFormatToolbarPlugin, { anchorElem: floatingAnchorElem }), _jsx(CodeActionMenuPlugin, { anchorElem: floatingAnchorElem })] }))] }) }) }) })] }) }));
|
|
149
|
+
}, children: _jsx(LexicalConfigProvider, { lexicalId: LEXICAL_ID, serviceManager: serviceManager, children: _jsx(LexicalComposer, { initialConfig: editorConfig, children: _jsxs("div", { className: "lexical-editor-inner", ref: onRef, children: [_jsx(LexicalStatePlugin, {}), _jsx(RichTextPlugin, { contentEditable: _jsx(ContentEditable, { className: "lexical-editor-content", "aria-label": "Lexical Editor" }), ErrorBoundary: LexicalErrorBoundary }), _jsx(OnChangePlugin, { onChange: handleChange }), _jsx(HistoryPlugin, {}), _jsx(AutoFocusPlugin, {}), _jsx(ListPlugin, {}), _jsx(CheckListPlugin, {}), _jsx(LinkPlugin, {}), _jsx(AutoLinkPlugin, {}), _jsx(ListMaxIndentLevelPlugin, { maxDepth: 7 }), _jsx(MarkdownShortcutPlugin, { transformers: TRANSFORMERS }), _jsx(LoadContentPlugin, { content: content }), _jsx(CodeHighlightPlugin, {}), _jsx(ImagesPlugin, { captionsEnabled: false }), _jsx(HorizontalRulePlugin, {}), _jsx(EquationsPlugin, {}), _jsx(YouTubePlugin, {}), _jsx(AutoEmbedPlugin, {}), _jsx(JupyterCellPlugin, {}), _jsx(JupyterReactTheme, { children: _jsx(SimpleKernelPluginsInner, {}) }), floatingAnchorElem && (_jsxs(_Fragment, { children: [_jsx(DraggableBlockPlugin, { anchorElem: floatingAnchorElem }), _jsx(FloatingTextFormatToolbarPlugin, { anchorElem: floatingAnchorElem, setIsLinkEditMode: setIsLinkEditMode }), _jsx(CodeActionMenuPlugin, { anchorElem: floatingAnchorElem })] }))] }) }) }) })] }) }));
|
|
149
150
|
});
|
|
150
151
|
function LexicalWithTools({ content, serviceManager, }) {
|
|
151
152
|
// Get all actions for this lexical document
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { Agent } from '../stores/examplesStore';
|
|
3
3
|
import type { Transport, Extension } from '../../components/chat';
|
|
4
|
+
import type { OAuthProvider, Identity } from '../../identity';
|
|
4
5
|
/**
|
|
5
6
|
* MCP Server Tool type
|
|
6
7
|
*/
|
|
@@ -9,6 +10,11 @@ export interface MCPServerTool {
|
|
|
9
10
|
description?: string;
|
|
10
11
|
enabled: boolean;
|
|
11
12
|
}
|
|
13
|
+
export interface SkillOption {
|
|
14
|
+
id: string;
|
|
15
|
+
name: string;
|
|
16
|
+
description?: string;
|
|
17
|
+
}
|
|
12
18
|
/**
|
|
13
19
|
* MCP Server configuration from backend
|
|
14
20
|
*/
|
|
@@ -43,6 +49,16 @@ declare const EXTENSIONS: {
|
|
|
43
49
|
label: string;
|
|
44
50
|
description: string;
|
|
45
51
|
}[];
|
|
52
|
+
/**
|
|
53
|
+
* AI Model configuration from backend
|
|
54
|
+
*/
|
|
55
|
+
export interface AIModelConfig {
|
|
56
|
+
id: string;
|
|
57
|
+
name: string;
|
|
58
|
+
builtinTools?: string[];
|
|
59
|
+
requiredEnvVars?: string[];
|
|
60
|
+
isAvailable?: boolean;
|
|
61
|
+
}
|
|
46
62
|
interface AgentConfigurationProps {
|
|
47
63
|
agentLibrary: AgentLibrary;
|
|
48
64
|
transport: Transport;
|
|
@@ -50,18 +66,39 @@ interface AgentConfigurationProps {
|
|
|
50
66
|
wsUrl: string;
|
|
51
67
|
baseUrl: string;
|
|
52
68
|
agentName: string;
|
|
69
|
+
model: string;
|
|
53
70
|
agents: readonly Agent[];
|
|
54
71
|
selectedAgentId: string;
|
|
55
72
|
isCreatingAgent?: boolean;
|
|
56
73
|
createError?: string | null;
|
|
74
|
+
enableCodemode?: boolean;
|
|
75
|
+
allowDirectToolCalls?: boolean;
|
|
76
|
+
enableToolReranker?: boolean;
|
|
77
|
+
availableSkills?: SkillOption[];
|
|
78
|
+
selectedSkills?: string[];
|
|
79
|
+
selectedMcpServers?: string[];
|
|
80
|
+
identityProviders?: {
|
|
81
|
+
[K in OAuthProvider]?: {
|
|
82
|
+
clientId: string;
|
|
83
|
+
scopes?: string[];
|
|
84
|
+
};
|
|
85
|
+
};
|
|
86
|
+
onIdentityConnect?: (identity: Identity) => void;
|
|
87
|
+
onIdentityDisconnect?: (provider: OAuthProvider) => void;
|
|
57
88
|
onAgentLibraryChange: (library: AgentLibrary) => void;
|
|
58
89
|
onTransportChange: (transport: Transport) => void;
|
|
59
90
|
onExtensionsChange: (extensions: Extension[]) => void;
|
|
60
91
|
onWsUrlChange: (url: string) => void;
|
|
61
92
|
onBaseUrlChange: (url: string) => void;
|
|
62
93
|
onAgentNameChange: (name: string) => void;
|
|
94
|
+
onModelChange: (model: string) => void;
|
|
63
95
|
onAgentSelect: (agentId: string) => void;
|
|
64
96
|
onConnect: () => void;
|
|
97
|
+
onEnableCodemodeChange?: (enabled: boolean) => void;
|
|
98
|
+
onAllowDirectToolCallsChange?: (enabled: boolean) => void;
|
|
99
|
+
onEnableToolRerankerChange?: (enabled: boolean) => void;
|
|
100
|
+
onSelectedSkillsChange?: (skills: string[]) => void;
|
|
101
|
+
onSelectedMcpServersChange?: (servers: string[]) => void;
|
|
65
102
|
}
|
|
66
103
|
/**
|
|
67
104
|
* Agent Configuration Component
|