@datalayer/agent-runtimes 1.0.5 → 1.0.6
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 +157 -10
- package/lib/AgentNode.d.ts +3 -0
- package/lib/AgentNode.js +676 -0
- package/lib/agent-node/themeStore.d.ts +3 -0
- package/lib/agent-node/themeStore.js +156 -0
- package/lib/agent-node-main.d.ts +1 -0
- package/lib/agent-node-main.js +14 -0
- package/lib/chat/Chat.js +16 -10
- package/lib/chat/ChatFloating.js +1 -1
- package/lib/chat/ChatSidebar.js +81 -49
- package/lib/chat/base/ChatBase.js +388 -74
- package/lib/chat/display/FloatingBrandButton.js +8 -1
- package/lib/chat/header/ChatHeader.d.ts +3 -1
- package/lib/chat/header/ChatHeader.js +15 -12
- package/lib/chat/header/ChatHeaderBase.d.ts +29 -9
- package/lib/chat/header/ChatHeaderBase.js +26 -3
- package/lib/chat/indicators/SandboxStatusIndicator.js +82 -47
- package/lib/chat/messages/ChatMessageList.js +46 -1
- package/lib/chat/messages/ChatMessages.js +6 -2
- package/lib/chat/prompt/InputFooter.d.ts +3 -1
- package/lib/chat/prompt/InputFooter.js +8 -5
- package/lib/chat/prompt/InputPrompt.d.ts +3 -1
- package/lib/chat/prompt/InputPrompt.js +2 -2
- package/lib/chat/prompt/InputPromptFooter.d.ts +3 -1
- package/lib/chat/prompt/InputPromptFooter.js +3 -3
- package/lib/client/AgentsMixin.js +14 -0
- package/lib/config/AgentConfiguration.d.ts +22 -0
- package/lib/config/AgentConfiguration.js +319 -64
- package/lib/examples/AgUiSharedStateExample.js +2 -1
- package/lib/examples/AgentCheckpointsExample.js +3 -3
- package/lib/examples/AgentCodemodeExample.d.ts +3 -3
- package/lib/examples/AgentCodemodeExample.js +24 -12
- package/lib/examples/AgentEvalsExample.js +330 -40
- package/lib/examples/AgentGuardrailsExample.js +16 -5
- package/lib/examples/AgentHooksExample.js +27 -9
- package/lib/examples/AgentInferenceProviderExample.d.ts +3 -0
- package/lib/examples/AgentInferenceProviderExample.js +329 -0
- package/lib/examples/AgentMCPExample.js +6 -5
- package/lib/examples/AgentMemoryExample.d.ts +1 -2
- package/lib/examples/AgentMemoryExample.js +71 -22
- package/lib/examples/AgentMonitoringExample.js +5 -5
- package/lib/examples/AgentNotificationsExample.d.ts +1 -2
- package/lib/examples/AgentNotificationsExample.js +71 -22
- package/lib/examples/AgentOtelExample.js +31 -40
- package/lib/examples/AgentOutputsExample.d.ts +1 -1
- package/lib/examples/AgentOutputsExample.js +67 -16
- package/lib/examples/AgentParametersExample.js +10 -8
- package/lib/examples/AgentSandboxExample.d.ts +1 -1
- package/lib/examples/AgentSandboxExample.js +7 -6
- package/lib/examples/AgentSkillsExample.js +6 -6
- package/lib/examples/AgentSubagentsExample.d.ts +1 -1
- package/lib/examples/AgentSubagentsExample.js +6 -6
- package/lib/examples/AgentToolApprovalsExample.js +27 -11
- package/lib/examples/AgentTriggersExample.js +5 -5
- package/lib/examples/{AgentSpecsExample.d.ts → AgentspecsExample.d.ts} +2 -2
- package/lib/examples/AgentspecsExample.js +1096 -0
- package/lib/examples/ChatCustomExample.js +6 -5
- package/lib/examples/ChatExample.js +6 -5
- package/lib/examples/Lexical2Example.js +1 -1
- package/lib/examples/LexicalAgentExample.js +1 -1
- package/lib/examples/NotebookAgentExample.js +3 -3
- package/lib/examples/components/ExampleWrapper.d.ts +6 -7
- package/lib/examples/components/ExampleWrapper.js +27 -10
- package/lib/examples/example-selector.js +2 -1
- package/lib/examples/index.d.ts +2 -1
- package/lib/examples/index.js +2 -1
- package/lib/examples/lexical/initial-content.json +6 -6
- package/lib/examples/main.js +56 -16
- package/lib/examples/utils/agentId.d.ts +1 -1
- package/lib/examples/utils/agentId.js +1 -1
- package/lib/examples/utils/useExampleAgentRuntimesUrl.d.ts +5 -0
- package/lib/examples/utils/useExampleAgentRuntimesUrl.js +19 -0
- package/lib/hooks/useAIAgentsWebSocket.js +35 -0
- package/lib/hooks/useAgentRuntimes.d.ts +32 -3
- package/lib/hooks/useAgentRuntimes.js +114 -19
- package/lib/index.d.ts +1 -1
- package/lib/specs/agents/agents.d.ts +20 -13
- package/lib/specs/agents/agents.js +1267 -581
- package/lib/specs/benchmarks.d.ts +20 -0
- package/lib/specs/benchmarks.js +205 -0
- package/lib/specs/envvars.d.ts +0 -1
- package/lib/specs/envvars.js +0 -11
- package/lib/specs/evals.d.ts +10 -9
- package/lib/specs/evals.js +128 -88
- package/lib/specs/index.d.ts +0 -1
- package/lib/specs/index.js +0 -1
- package/lib/specs/models.d.ts +0 -2
- package/lib/specs/models.js +0 -15
- package/lib/specs/skills.d.ts +0 -1
- package/lib/specs/skills.js +0 -18
- package/lib/stores/agentRuntimeStore.d.ts +5 -1
- package/lib/stores/agentRuntimeStore.js +22 -8
- package/lib/stores/conversationStore.js +2 -2
- package/lib/types/agents-lifecycle.d.ts +18 -0
- package/lib/types/agents.d.ts +6 -0
- package/lib/types/agentspecs.d.ts +4 -0
- package/lib/types/benchmarks.d.ts +43 -0
- package/lib/types/benchmarks.js +5 -0
- package/lib/types/chat.d.ts +16 -0
- package/lib/types/evals.d.ts +26 -17
- package/lib/types/index.d.ts +1 -0
- package/lib/types/index.js +1 -0
- package/package.json +9 -5
- package/scripts/codegen/__pycache__/generate_agents.cpython-313.pyc +0 -0
- package/scripts/codegen/__pycache__/generate_benchmarks.cpython-313.pyc +0 -0
- package/scripts/codegen/__pycache__/generate_evals.cpython-313.pyc +0 -0
- package/scripts/codegen/generate_agents.py +89 -43
- package/scripts/codegen/generate_benchmarks.py +441 -0
- package/scripts/codegen/generate_evals.py +94 -16
- package/scripts/codegen/generate_events.py +0 -1
- package/lib/examples/AgentSpecsExample.js +0 -694
|
@@ -8,6 +8,7 @@ import { Text, TextInput, Button, FormControl, Select, Checkbox, Spinner, Flash,
|
|
|
8
8
|
import { ToolsIcon, KeyIcon, SyncIcon, PlusIcon, XIcon, LinkExternalIcon, } from '@primer/octicons-react';
|
|
9
9
|
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
|
10
10
|
import { Box } from '@datalayer/primer-addons';
|
|
11
|
+
import { getSkillSpec, getSkillSpecs } from '../specs/skills';
|
|
11
12
|
import { IdentityCard, IdentityConnect, useIdentity } from '../identity';
|
|
12
13
|
/**
|
|
13
14
|
* Helper: is the selected agent id a library spec?
|
|
@@ -17,6 +18,14 @@ export const isSpecSelection = (id) => id.startsWith('spec:');
|
|
|
17
18
|
* Helper: extract the spec id from a spec selection value.
|
|
18
19
|
*/
|
|
19
20
|
export const getSpecId = (id) => id.replace(/^spec:/, '');
|
|
21
|
+
/**
|
|
22
|
+
* Helper: is the selected agent id a cloud library spec?
|
|
23
|
+
*/
|
|
24
|
+
export const isCloudSpecSelection = (id) => id.startsWith('cloud-spec:');
|
|
25
|
+
/**
|
|
26
|
+
* Helper: extract the cloud spec id from a cloud selection value.
|
|
27
|
+
*/
|
|
28
|
+
export const getCloudSpecId = (id) => id.replace(/^cloud-spec:/, '');
|
|
20
29
|
/**
|
|
21
30
|
* Token-based identity providers that can be connected via API key
|
|
22
31
|
*/
|
|
@@ -143,6 +152,35 @@ function IdentityConnectWithStatus({ identityProviders = {}, disabled = false, o
|
|
|
143
152
|
setTokenInput('');
|
|
144
153
|
}, variant: "invisible" })] })] }))] }, tp.provider))) }))] }));
|
|
145
154
|
}
|
|
155
|
+
const normalizeEnvVarRef = (ref) => ref.replace(/:\d+\.\d+\.\d+$/, '');
|
|
156
|
+
const normalizeMcpServerId = (id) => id.replace(/:\d+\.\d+\.\d+$/, '');
|
|
157
|
+
const normalizeToolLabel = (tool) => {
|
|
158
|
+
if (typeof tool === 'string') {
|
|
159
|
+
return tool;
|
|
160
|
+
}
|
|
161
|
+
if (typeof tool === 'object' && tool !== null) {
|
|
162
|
+
const toolObj = tool;
|
|
163
|
+
const fromName = typeof toolObj.name === 'string' && toolObj.name.trim().length > 0
|
|
164
|
+
? toolObj.name.trim()
|
|
165
|
+
: null;
|
|
166
|
+
if (fromName) {
|
|
167
|
+
return fromName;
|
|
168
|
+
}
|
|
169
|
+
const fromId = typeof toolObj.id === 'string' && toolObj.id.trim().length > 0
|
|
170
|
+
? toolObj.id.trim()
|
|
171
|
+
: null;
|
|
172
|
+
if (fromId) {
|
|
173
|
+
return fromId;
|
|
174
|
+
}
|
|
175
|
+
const fromTool = typeof toolObj.tool === 'string' && toolObj.tool.trim().length > 0
|
|
176
|
+
? toolObj.tool.trim()
|
|
177
|
+
: null;
|
|
178
|
+
if (fromTool) {
|
|
179
|
+
return fromTool;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
return null;
|
|
183
|
+
};
|
|
146
184
|
const AGENT_LIBRARIES = [
|
|
147
185
|
{
|
|
148
186
|
value: 'pydantic-ai',
|
|
@@ -206,7 +244,7 @@ const EXTENSIONS = [
|
|
|
206
244
|
*
|
|
207
245
|
* Form for configuring agent connection settings.
|
|
208
246
|
*/
|
|
209
|
-
export const AgentConfiguration = ({ agentLibrary, protocol: transport, extensions, wsUrl, baseUrl, agentName, description, goal, model, systemPrompt, systemPromptCodemodeAddons, tools, sandboxVariant, 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, onDescriptionChange, onGoalChange, onModelChange, onSystemPromptChange, onSystemPromptCodemodeAddonsChange, onToolsChange, onSandboxVariantChange, onAgentSelect, onConnect, onEnableCodemodeChange, onAllowDirectToolCallsChange, onEnableToolRerankerChange, onUseJupyterSandboxChange, onSelectedSkillsChange, onSelectedMcpServersChange, }) => {
|
|
247
|
+
export const AgentConfiguration = ({ agentLibrary, protocol: transport, extensions, wsUrl, baseUrl, agentName, description, goal, model, systemPrompt, systemPromptCodemodeAddons, tools, sandboxVariant, agents, selectedAgentId, isCreatingAgent = false, createError = null, enableCodemode = false, allowDirectToolCalls = false, enableToolReranker = false, useJupyterSandbox = false, availableSkills = [], selectedSkills = [], selectedMcpServers = [], cloudLibrarySpecs = [], cloudLibraryLoading = false, cloudLibraryError = null, launchTarget = 'local', launchStatus = 'idle', launchBaseUrl, identityProviders, onIdentityConnect, onIdentityDisconnect, onAgentLibraryChange, onTransportChange, onExtensionsChange, onWsUrlChange, onBaseUrlChange, onAgentNameChange, onDescriptionChange, onGoalChange, onModelChange, onSystemPromptChange, onSystemPromptCodemodeAddonsChange, onToolsChange, onSandboxVariantChange, onAgentSelect, onConnect, onEnableCodemodeChange, onAllowDirectToolCallsChange, onEnableToolRerankerChange, onUseJupyterSandboxChange, onSelectedSkillsChange, onSelectedMcpServersChange, }) => {
|
|
210
248
|
// Fetch general configuration from the backend (models, etc.)
|
|
211
249
|
const configQuery = useQuery({
|
|
212
250
|
queryKey: ['agent-config', baseUrl],
|
|
@@ -250,22 +288,25 @@ export const AgentConfiguration = ({ agentLibrary, protocol: transport, extensio
|
|
|
250
288
|
retry: 1,
|
|
251
289
|
});
|
|
252
290
|
const librarySpecs = libraryQuery.data || [];
|
|
253
|
-
// The currently selected library spec (if any)
|
|
291
|
+
// The currently selected local library spec (if any)
|
|
254
292
|
const selectedSpec = useMemo(() => {
|
|
255
293
|
if (!isSpecSelection(selectedAgentId))
|
|
256
294
|
return null;
|
|
257
295
|
const specId = getSpecId(selectedAgentId);
|
|
258
296
|
return librarySpecs.find(s => s.id === specId) || null;
|
|
259
297
|
}, [selectedAgentId, librarySpecs]);
|
|
260
|
-
const
|
|
261
|
-
if (!
|
|
262
|
-
return
|
|
263
|
-
|
|
264
|
-
|
|
298
|
+
const selectedCloudSpec = useMemo(() => {
|
|
299
|
+
if (!isCloudSpecSelection(selectedAgentId))
|
|
300
|
+
return null;
|
|
301
|
+
const specId = getCloudSpecId(selectedAgentId);
|
|
302
|
+
return cloudLibrarySpecs.find(s => s.id === specId) || null;
|
|
303
|
+
}, [selectedAgentId, cloudLibrarySpecs]);
|
|
265
304
|
// When a spec is selected, form behaves like new-agent but with pre-filled values
|
|
266
|
-
const isNewAgentMode = selectedAgentId === 'new-agent' ||
|
|
305
|
+
const isNewAgentMode = selectedAgentId === 'new-agent' ||
|
|
306
|
+
isSpecSelection(selectedAgentId) ||
|
|
307
|
+
isCloudSpecSelection(selectedAgentId);
|
|
267
308
|
// True when a library spec is selected (fields locked down except Name, URL, Library, Model, Transport, Extensions)
|
|
268
|
-
const isSpecMode = isSpecSelection(selectedAgentId);
|
|
309
|
+
const isSpecMode = isSpecSelection(selectedAgentId) || isCloudSpecSelection(selectedAgentId);
|
|
269
310
|
// Entire form is read-only for existing agents and library spec selections.
|
|
270
311
|
const isFormReadOnly = !isNewAgentMode || isSpecMode;
|
|
271
312
|
// Fetch skills from the backend (always available, independent of codemode)
|
|
@@ -320,16 +361,157 @@ export const AgentConfiguration = ({ agentLibrary, protocol: transport, extensio
|
|
|
320
361
|
const configServers = mcpServersQuery.data || configQuery.data?.mcpServers || [];
|
|
321
362
|
const catalogServers = catalogServersQuery.data || [];
|
|
322
363
|
const models = configQuery.data?.models || [];
|
|
323
|
-
|
|
324
|
-
const
|
|
325
|
-
|
|
364
|
+
const activeSpec = selectedSpec || selectedCloudSpec;
|
|
365
|
+
const availableEnvVars = useMemo(() => {
|
|
366
|
+
const vars = new Set();
|
|
367
|
+
for (const model of models) {
|
|
368
|
+
if (model.isAvailable !== false) {
|
|
369
|
+
for (const envVar of model.requiredEnvVars || []) {
|
|
370
|
+
vars.add(normalizeEnvVarRef(envVar));
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
for (const server of [...configServers, ...catalogServers]) {
|
|
375
|
+
const serverAvailable = server.isAvailable === true || server.isRunning === true;
|
|
376
|
+
if (!serverAvailable) {
|
|
377
|
+
continue;
|
|
378
|
+
}
|
|
379
|
+
for (const envVar of server.requiredEnvVars || []) {
|
|
380
|
+
vars.add(normalizeEnvVarRef(envVar));
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
return vars;
|
|
384
|
+
}, [models, configServers, catalogServers]);
|
|
385
|
+
const skillsFromSelectedSpec = useMemo(() => {
|
|
386
|
+
if (!activeSpec || !Array.isArray(activeSpec.skills)) {
|
|
387
|
+
return [];
|
|
388
|
+
}
|
|
389
|
+
return activeSpec.skills
|
|
390
|
+
.map(skillRef => {
|
|
391
|
+
if (typeof skillRef === 'string') {
|
|
392
|
+
const catalog = getSkillSpec(skillRef);
|
|
393
|
+
return {
|
|
394
|
+
id: skillRef,
|
|
395
|
+
name: catalog?.name || skillRef,
|
|
396
|
+
description: catalog?.description,
|
|
397
|
+
requiredEnvVars: catalog?.requiredEnvVars || [],
|
|
398
|
+
};
|
|
399
|
+
}
|
|
400
|
+
if (typeof skillRef === 'object' && skillRef !== null) {
|
|
401
|
+
const skillObj = skillRef;
|
|
402
|
+
const rawId = skillObj.id || skillObj.name || '';
|
|
403
|
+
if (!rawId) {
|
|
404
|
+
return null;
|
|
405
|
+
}
|
|
406
|
+
const catalog = getSkillSpec(rawId);
|
|
407
|
+
return {
|
|
408
|
+
id: rawId,
|
|
409
|
+
name: skillObj.name || catalog?.name || rawId,
|
|
410
|
+
description: skillObj.description || catalog?.description,
|
|
411
|
+
requiredEnvVars: skillObj.requiredEnvVars || catalog?.requiredEnvVars || [],
|
|
412
|
+
};
|
|
413
|
+
}
|
|
414
|
+
return null;
|
|
415
|
+
})
|
|
416
|
+
.filter((skill) => skill !== null);
|
|
417
|
+
}, [activeSpec]);
|
|
418
|
+
const skillsFromCatalog = useMemo(() => {
|
|
419
|
+
return getSkillSpecs().map(skill => ({
|
|
420
|
+
id: skill.id,
|
|
421
|
+
name: skill.name,
|
|
422
|
+
description: skill.description,
|
|
423
|
+
requiredEnvVars: skill.requiredEnvVars || [],
|
|
424
|
+
}));
|
|
425
|
+
}, []);
|
|
426
|
+
const baseSkills = useMemo(() => {
|
|
427
|
+
if (skillsFromSelectedSpec.length > 0) {
|
|
428
|
+
return skillsFromSelectedSpec;
|
|
429
|
+
}
|
|
430
|
+
return skillsFromCatalog;
|
|
431
|
+
}, [skillsFromSelectedSpec, skillsFromCatalog]);
|
|
432
|
+
const displaySkills = useMemo(() => {
|
|
433
|
+
return baseSkills.map(skill => {
|
|
434
|
+
const required = (skill.requiredEnvVars || []).map(normalizeEnvVarRef);
|
|
435
|
+
const envVarsAvailable = required.length === 0 ||
|
|
436
|
+
required.every(envVar => availableEnvVars.has(envVar));
|
|
437
|
+
return {
|
|
438
|
+
...skill,
|
|
439
|
+
requiredEnvVars: required,
|
|
440
|
+
isAvailable: envVarsAvailable,
|
|
441
|
+
};
|
|
442
|
+
});
|
|
443
|
+
}, [baseSkills, availableEnvVars]);
|
|
444
|
+
const usingSpecSkills = skillsFromSelectedSpec.length > 0;
|
|
445
|
+
const usingCatalogFallback = !usingSpecSkills;
|
|
326
446
|
const skillsEnabled = selectedSkills.length > 0;
|
|
327
|
-
const
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
447
|
+
const configServerIdSet = useMemo(() => new Set(configServers.map(server => normalizeMcpServerId(server.id))), [configServers]);
|
|
448
|
+
const catalogServerIdSet = useMemo(() => new Set(catalogServers.map(server => normalizeMcpServerId(server.id))), [catalogServers]);
|
|
449
|
+
const selectedConfigServers = useMemo(() => {
|
|
450
|
+
return selectedMcpServers
|
|
451
|
+
.filter(selection => {
|
|
452
|
+
const normalizedId = normalizeMcpServerId(selection.id);
|
|
453
|
+
if (selection.origin === 'config') {
|
|
454
|
+
return configServerIdSet.has(normalizedId);
|
|
455
|
+
}
|
|
456
|
+
if (selection.origin === 'catalog') {
|
|
457
|
+
return (!catalogServerIdSet.has(normalizedId) &&
|
|
458
|
+
configServerIdSet.has(normalizedId));
|
|
459
|
+
}
|
|
460
|
+
return false;
|
|
461
|
+
})
|
|
462
|
+
.map(selection => normalizeMcpServerId(selection.id));
|
|
463
|
+
}, [selectedMcpServers, configServerIdSet]);
|
|
464
|
+
const selectedCatalogServers = useMemo(() => {
|
|
465
|
+
return selectedMcpServers
|
|
466
|
+
.filter(selection => {
|
|
467
|
+
const normalizedId = normalizeMcpServerId(selection.id);
|
|
468
|
+
if (selection.origin === 'catalog') {
|
|
469
|
+
return catalogServerIdSet.has(normalizedId);
|
|
470
|
+
}
|
|
471
|
+
if (selection.origin === 'config') {
|
|
472
|
+
return (!configServerIdSet.has(normalizedId) &&
|
|
473
|
+
catalogServerIdSet.has(normalizedId));
|
|
474
|
+
}
|
|
475
|
+
return false;
|
|
476
|
+
})
|
|
477
|
+
.map(selection => normalizeMcpServerId(selection.id));
|
|
478
|
+
}, [selectedMcpServers, catalogServerIdSet]);
|
|
479
|
+
const resolvedSpecTools = useMemo(() => {
|
|
480
|
+
if (!activeSpec || !Array.isArray(activeSpec.tools)) {
|
|
481
|
+
return [];
|
|
482
|
+
}
|
|
483
|
+
return activeSpec.tools
|
|
484
|
+
.map(tool => normalizeToolLabel(tool))
|
|
485
|
+
.filter((tool) => !!tool);
|
|
486
|
+
}, [activeSpec]);
|
|
487
|
+
const toolsInputValue = isSpecMode && resolvedSpecTools.length > 0
|
|
488
|
+
? resolvedSpecTools.join(', ')
|
|
489
|
+
: tools.join(', ');
|
|
490
|
+
const toolsInputPlaceholder = isSpecMode
|
|
491
|
+
? 'No tools defined by selected spec'
|
|
492
|
+
: 'runtime-echo, runtime-send-mail';
|
|
493
|
+
const unresolvedSelectedMcpServers = useMemo(() => {
|
|
494
|
+
return selectedMcpServers
|
|
495
|
+
.map(selection => normalizeMcpServerId(selection.id))
|
|
496
|
+
.filter(id => !configServerIdSet.has(id) && !catalogServerIdSet.has(id))
|
|
497
|
+
.filter((id, index, arr) => arr.indexOf(id) === index);
|
|
498
|
+
}, [selectedMcpServers, configServerIdSet, catalogServerIdSet]);
|
|
499
|
+
const enabledLocalSpecs = [...librarySpecs]
|
|
500
|
+
.filter(s => s.enabled)
|
|
501
|
+
.sort((a, b) => {
|
|
502
|
+
const pkgA = a.id.includes('/') ? a.id.split('/')[0] : '';
|
|
503
|
+
const pkgB = b.id.includes('/') ? b.id.split('/')[0] : '';
|
|
504
|
+
const cmp = pkgA.localeCompare(pkgB);
|
|
505
|
+
return cmp !== 0 ? cmp : a.name.localeCompare(b.name);
|
|
506
|
+
});
|
|
507
|
+
const enabledCloudSpecs = [...cloudLibrarySpecs]
|
|
508
|
+
.filter(s => s.enabled)
|
|
509
|
+
.sort((a, b) => {
|
|
510
|
+
const pkgA = a.id.includes('/') ? a.id.split('/')[0] : '';
|
|
511
|
+
const pkgB = b.id.includes('/') ? b.id.split('/')[0] : '';
|
|
512
|
+
const cmp = pkgA.localeCompare(pkgB);
|
|
513
|
+
return cmp !== 0 ? cmp : a.name.localeCompare(b.name);
|
|
514
|
+
});
|
|
333
515
|
// Preview servers combines both config and catalog selections
|
|
334
516
|
const previewConfigServers = selectedConfigServers.length
|
|
335
517
|
? configServers.filter(server => selectedConfigServers.includes(server.id))
|
|
@@ -341,16 +523,19 @@ export const AgentConfiguration = ({ agentLibrary, protocol: transport, extensio
|
|
|
341
523
|
const handleConfigServerChange = (serverId, checked) => {
|
|
342
524
|
if (!onSelectedMcpServersChange)
|
|
343
525
|
return;
|
|
526
|
+
const normalizedServerId = normalizeMcpServerId(serverId);
|
|
344
527
|
if (checked) {
|
|
345
|
-
if (!selectedMcpServers.some(s => s.id ===
|
|
528
|
+
if (!selectedMcpServers.some(s => normalizeMcpServerId(s.id) === normalizedServerId &&
|
|
529
|
+
s.origin === 'config')) {
|
|
346
530
|
onSelectedMcpServersChange([
|
|
347
|
-
...selectedMcpServers,
|
|
348
|
-
{ id:
|
|
531
|
+
...selectedMcpServers.filter(s => normalizeMcpServerId(s.id) !== normalizedServerId),
|
|
532
|
+
{ id: normalizedServerId, origin: 'config' },
|
|
349
533
|
]);
|
|
350
534
|
}
|
|
351
535
|
}
|
|
352
536
|
else {
|
|
353
|
-
onSelectedMcpServersChange(selectedMcpServers.filter(s => !(s.id ===
|
|
537
|
+
onSelectedMcpServersChange(selectedMcpServers.filter(s => !(normalizeMcpServerId(s.id) === normalizedServerId &&
|
|
538
|
+
s.origin === 'config')));
|
|
354
539
|
}
|
|
355
540
|
};
|
|
356
541
|
// Handle MCP Catalog server checkbox change
|
|
@@ -358,6 +543,7 @@ export const AgentConfiguration = ({ agentLibrary, protocol: transport, extensio
|
|
|
358
543
|
const handleCatalogServerChange = async (serverId, checked, isRunning) => {
|
|
359
544
|
if (!onSelectedMcpServersChange)
|
|
360
545
|
return;
|
|
546
|
+
const normalizedServerId = normalizeMcpServerId(serverId);
|
|
361
547
|
if (checked) {
|
|
362
548
|
// If not running, start the server first
|
|
363
549
|
if (!isRunning) {
|
|
@@ -369,15 +555,17 @@ export const AgentConfiguration = ({ agentLibrary, protocol: transport, extensio
|
|
|
369
555
|
return; // Don't add to selection if enable failed
|
|
370
556
|
}
|
|
371
557
|
}
|
|
372
|
-
if (!selectedMcpServers.some(s => s.id ===
|
|
558
|
+
if (!selectedMcpServers.some(s => normalizeMcpServerId(s.id) === normalizedServerId &&
|
|
559
|
+
s.origin === 'catalog')) {
|
|
373
560
|
onSelectedMcpServersChange([
|
|
374
|
-
...selectedMcpServers,
|
|
375
|
-
{ id:
|
|
561
|
+
...selectedMcpServers.filter(s => normalizeMcpServerId(s.id) !== normalizedServerId),
|
|
562
|
+
{ id: normalizedServerId, origin: 'catalog' },
|
|
376
563
|
]);
|
|
377
564
|
}
|
|
378
565
|
}
|
|
379
566
|
else {
|
|
380
|
-
onSelectedMcpServersChange(selectedMcpServers.filter(s => !(s.id ===
|
|
567
|
+
onSelectedMcpServersChange(selectedMcpServers.filter(s => !(normalizeMcpServerId(s.id) === normalizedServerId &&
|
|
568
|
+
s.origin === 'catalog')));
|
|
381
569
|
}
|
|
382
570
|
};
|
|
383
571
|
const handleSkillChange = (skillId, checked) => {
|
|
@@ -420,31 +608,103 @@ export const AgentConfiguration = ({ agentLibrary, protocol: transport, extensio
|
|
|
420
608
|
fontWeight: 'bold',
|
|
421
609
|
display: 'block',
|
|
422
610
|
marginBottom: 3,
|
|
423
|
-
}, children: "Create a new Agent" }), _jsxs(FormControl, { sx: { marginBottom: 3 }, children: [_jsx(FormControl.Label, { children: "Available Agents" }), _jsxs(
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
611
|
+
}, children: "Create a new Agent" }), _jsxs(FormControl, { sx: { marginBottom: 3 }, children: [_jsx(FormControl.Label, { children: "Available Agents" }), _jsxs(Box, { sx: { display: 'flex', gap: 2, mb: 2 }, children: [_jsxs(Label, { variant: launchTarget === 'cloud' ? 'accent' : 'secondary', children: ["Target: ", launchTarget === 'cloud' ? 'Cloud' : 'Local'] }), _jsxs(Label, { variant: launchStatus === 'error' ? 'danger' : 'attention', children: ["Launch: ", launchStatus] })] }), launchBaseUrl ? (_jsxs(Box, { sx: {
|
|
612
|
+
mb: 2,
|
|
613
|
+
p: 2,
|
|
614
|
+
border: '1px solid',
|
|
615
|
+
borderColor: 'border.default',
|
|
616
|
+
borderRadius: 2,
|
|
617
|
+
bg: 'canvas.default',
|
|
618
|
+
}, children: [_jsx(Text, { sx: { display: 'block', fontSize: 0, color: 'fg.muted' }, children: "Launch URL" }), _jsx(Text, { sx: {
|
|
619
|
+
display: 'block',
|
|
620
|
+
fontSize: 1,
|
|
621
|
+
fontFamily: 'mono',
|
|
622
|
+
wordBreak: 'break-all',
|
|
623
|
+
}, children: launchBaseUrl })] })) : null, _jsxs(Select, { value: selectedAgentId, onChange: e => onAgentSelect(e.target.value), sx: { width: '100%' }, children: [_jsxs("optgroup", { label: "Local Agents", children: [_jsx(Select.Option, { value: "new-agent", disabled: selectedAgentId === 'new-agent', children: "+ New Agent..." }), enabledLocalSpecs.map(spec => {
|
|
624
|
+
const pkg = spec.id.includes('/') ? spec.id.split('/')[0] : '';
|
|
625
|
+
const optionValue = `spec:${spec.id}`;
|
|
626
|
+
return (_jsxs(Select.Option, { value: optionValue, disabled: selectedAgentId === optionValue, children: [spec.emoji ? `${spec.emoji} ` : '', pkg ? `[${pkg}] ` : '', spec.name] }, optionValue));
|
|
627
|
+
}), agents.map(agent => (_jsxs(Select.Option, { value: agent.id, disabled: true, children: ["[Persona] ", agent.status === 'running' && '● ', agent.name] }, agent.id)))] }), _jsxs("optgroup", { label: "Cloud Agents", children: [cloudLibraryLoading && (_jsx(Select.Option, { value: "__cloud_loading", disabled: true, children: "Loading cloud agents..." })), !cloudLibraryLoading && enabledCloudSpecs.length === 0 && (_jsx(Select.Option, { value: "__cloud_empty", disabled: true, children: "No cloud agents available" })), !cloudLibraryLoading &&
|
|
628
|
+
enabledCloudSpecs.map(spec => {
|
|
629
|
+
const pkg = spec.id.includes('/') ? spec.id.split('/')[0] : '';
|
|
630
|
+
const optionValue = `cloud-spec:${spec.id}`;
|
|
631
|
+
return (_jsxs(Select.Option, { value: optionValue, disabled: selectedAgentId === optionValue, children: [spec.emoji ? `${spec.emoji} ` : '', pkg ? `[${pkg}] ` : '', spec.name] }, optionValue));
|
|
632
|
+
})] })] }), _jsxs(FormControl.Caption, { children: [isNewAgentMode
|
|
633
|
+
? selectedSpec || selectedCloudSpec
|
|
634
|
+
? `Creating from spec: ${(selectedSpec || selectedCloudSpec)?.name} — capabilities are locked`
|
|
635
|
+
: 'Configure a new custom agent'
|
|
636
|
+
: 'Selected agent - form fields below are disabled', cloudLibraryError ? ` Cloud fetch error: ${cloudLibraryError}` : ''] })] }), _jsxs(FormControl, { sx: { marginBottom: 3 }, disabled: isFormReadOnly, children: [_jsx(FormControl.Label, { children: "Agent Name" }), _jsx(TextInput, { value: agentName, onChange: e => onAgentNameChange(e.target.value), placeholder: "demo-agent", sx: { width: '100%' } }), _jsx(FormControl.Caption, { children: "The name of the agent to connect to" })] }), _jsxs(FormControl, { sx: { marginBottom: 3 }, disabled: isFormReadOnly, children: [_jsx(FormControl.Label, { children: "Description" }), _jsx(Box, { as: "textarea", value: description, onChange: e => onDescriptionChange(e.target.value), placeholder: "Short agent description", disabled: isFormReadOnly, readOnly: isFormReadOnly, rows: 3, sx: {
|
|
637
|
+
width: '100%',
|
|
638
|
+
maxWidth: '100%',
|
|
639
|
+
minHeight: '88px',
|
|
640
|
+
resize: 'vertical',
|
|
641
|
+
border: '1px solid',
|
|
642
|
+
borderColor: 'border.default',
|
|
643
|
+
borderRadius: 2,
|
|
644
|
+
p: 2,
|
|
645
|
+
fontSize: 1,
|
|
646
|
+
whiteSpace: 'pre-wrap',
|
|
647
|
+
overflowWrap: 'anywhere',
|
|
648
|
+
bg: isFormReadOnly ? 'canvas.subtle' : 'canvas.default',
|
|
649
|
+
color: isFormReadOnly ? 'fg.muted' : 'fg.default',
|
|
650
|
+
} })] }), _jsxs(FormControl, { sx: { marginBottom: 3 }, disabled: isFormReadOnly, children: [_jsx(FormControl.Label, { children: "Goal" }), _jsx(Box, { as: "textarea", value: goal, onChange: e => onGoalChange(e.target.value), placeholder: "User-facing objective", disabled: isFormReadOnly, readOnly: isFormReadOnly, rows: 3, sx: {
|
|
651
|
+
width: '100%',
|
|
652
|
+
maxWidth: '100%',
|
|
653
|
+
minHeight: '88px',
|
|
654
|
+
resize: 'vertical',
|
|
655
|
+
border: '1px solid',
|
|
656
|
+
borderColor: 'border.default',
|
|
657
|
+
borderRadius: 2,
|
|
658
|
+
p: 2,
|
|
659
|
+
fontSize: 1,
|
|
660
|
+
whiteSpace: 'pre-wrap',
|
|
661
|
+
overflowWrap: 'anywhere',
|
|
662
|
+
bg: isFormReadOnly ? 'canvas.subtle' : 'canvas.default',
|
|
663
|
+
color: isFormReadOnly ? 'fg.muted' : 'fg.default',
|
|
664
|
+
} })] }), _jsxs(FormControl, { sx: { marginBottom: 3 }, disabled: isFormReadOnly, children: [_jsx(FormControl.Label, { children: transport === 'acp' ? 'WebSocket URL' : 'Base URL' }), _jsx(TextInput, { value: transport === 'acp' ? wsUrl : baseUrl, onChange: e => transport === 'acp'
|
|
439
665
|
? onWsUrlChange(e.target.value)
|
|
440
666
|
: onBaseUrlChange(e.target.value), placeholder: transport === 'acp'
|
|
441
667
|
? 'ws://localhost:8000/api/v1/acp/ws'
|
|
442
668
|
: 'http://localhost:8000', sx: { width: '100%' } }), _jsx(FormControl.Caption, { children: transport === 'acp'
|
|
443
669
|
? 'The WebSocket endpoint of your agent-runtimes server'
|
|
444
|
-
: 'The base URL of your agent-runtimes server' })] }), _jsxs(Box, { sx: { display: 'flex', gap: 3, marginBottom: 3 }, children: [_jsxs(FormControl, { sx: { flex: 1 }, disabled: isFormReadOnly, children: [_jsx(FormControl.Label, { children: "Agent Library" }), _jsx(Select, { value: agentLibrary, onChange: e => onAgentLibraryChange(e.target.value), sx: { width: '100%' }, children: AGENT_LIBRARIES.map(lib => (_jsxs(Select.Option, { value: lib.value, disabled: lib.disabled, children: [lib.label, lib.disabled && ' (Coming Soon)'] }, lib.value))) })] }), _jsxs(FormControl, { sx: { flex: 1 }, disabled: isFormReadOnly || models.length === 0, children: [_jsx(FormControl.Label, { children: "Model" }), _jsx(Select, { value: model, onChange: e => onModelChange(e.target.value), sx: { width: '100%' }, children: models.length === 0 ? (_jsx(Select.Option, { value: "", children: "Loading models..." })) : (models.map(m => (_jsxs(Select.Option, { value: m.id, disabled: !m.isAvailable, children: [m.name, !m.isAvailable && ' (API key required)'] }, m.id)))) })] }), _jsxs(FormControl, { sx: { flex: 1 }, disabled: isFormReadOnly, children: [_jsx(FormControl.Label, { children: "Transport" }), _jsx(Select, { value: transport, onChange: e => onTransportChange(e.target.value), sx: { width: '100%' }, children: TRANSPORTS.map(t => (_jsx(Select.Option, { value: t.value, children: t.label }, t.value))) })] }), _jsxs(FormControl, { sx: { flex: 1 }, children: [_jsx(FormControl.Label, { children: "Extensions" }), _jsx(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 2 }, children: EXTENSIONS.map(ext => (_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Checkbox, { value: ext.value, checked: extensions.includes(ext.value), disabled: isFormReadOnly || !isExtensionEnabled(ext.value), onChange: e => handleExtensionChange(ext.value, e.target.checked) }), _jsx(Text, { children: ext.label })] }, ext.value))) })] })] }), _jsxs(FormControl, { sx: { marginBottom: 3 }, disabled: isFormReadOnly, children: [_jsx(FormControl.Label, { children: "System Prompt" }), _jsx(
|
|
670
|
+
: 'The base URL of your agent-runtimes server' })] }), _jsxs(Box, { sx: { display: 'flex', gap: 3, marginBottom: 3 }, children: [_jsxs(FormControl, { sx: { flex: 1 }, disabled: isFormReadOnly, children: [_jsx(FormControl.Label, { children: "Agent Library" }), _jsx(Select, { value: agentLibrary, onChange: e => onAgentLibraryChange(e.target.value), sx: { width: '100%' }, children: AGENT_LIBRARIES.map(lib => (_jsxs(Select.Option, { value: lib.value, disabled: lib.disabled, children: [lib.label, lib.disabled && ' (Coming Soon)'] }, lib.value))) })] }), _jsxs(FormControl, { sx: { flex: 1 }, disabled: isFormReadOnly || models.length === 0, children: [_jsx(FormControl.Label, { children: "Model" }), _jsx(Select, { value: model, onChange: e => onModelChange(e.target.value), sx: { width: '100%' }, children: models.length === 0 ? (_jsx(Select.Option, { value: "", children: "Loading models..." })) : (models.map(m => (_jsxs(Select.Option, { value: m.id, disabled: !m.isAvailable, children: [m.name, !m.isAvailable && ' (API key required)'] }, m.id)))) })] }), _jsxs(FormControl, { sx: { flex: 1 }, disabled: isFormReadOnly, children: [_jsx(FormControl.Label, { children: "Transport" }), _jsx(Select, { value: transport, onChange: e => onTransportChange(e.target.value), sx: { width: '100%' }, children: TRANSPORTS.map(t => (_jsx(Select.Option, { value: t.value, children: t.label }, t.value))) })] }), _jsxs(FormControl, { sx: { flex: 1 }, children: [_jsx(FormControl.Label, { children: "Extensions" }), _jsx(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 2 }, children: EXTENSIONS.map(ext => (_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Checkbox, { value: ext.value, checked: extensions.includes(ext.value), disabled: isFormReadOnly || !isExtensionEnabled(ext.value), onChange: e => handleExtensionChange(ext.value, e.target.checked) }), _jsx(Text, { children: ext.label })] }, ext.value))) })] })] }), _jsxs(FormControl, { sx: { marginBottom: 3 }, disabled: isFormReadOnly, children: [_jsx(FormControl.Label, { children: "System Prompt" }), _jsx(Box, { as: "textarea", value: systemPrompt, onChange: e => onSystemPromptChange(e.target.value), placeholder: "You are a helpful AI assistant.", disabled: isFormReadOnly, readOnly: isFormReadOnly, rows: 5, sx: {
|
|
671
|
+
width: '100%',
|
|
672
|
+
maxWidth: '100%',
|
|
673
|
+
minHeight: '120px',
|
|
674
|
+
resize: 'vertical',
|
|
675
|
+
border: '1px solid',
|
|
676
|
+
borderColor: 'border.default',
|
|
677
|
+
borderRadius: 2,
|
|
678
|
+
p: 2,
|
|
679
|
+
fontFamily: 'mono',
|
|
680
|
+
fontSize: 1,
|
|
681
|
+
whiteSpace: 'pre-wrap',
|
|
682
|
+
overflowWrap: 'anywhere',
|
|
683
|
+
bg: isFormReadOnly ? 'canvas.subtle' : 'canvas.default',
|
|
684
|
+
color: isFormReadOnly ? 'fg.muted' : 'fg.default',
|
|
685
|
+
userSelect: isFormReadOnly ? 'none' : 'text',
|
|
686
|
+
cursor: isFormReadOnly ? 'not-allowed' : 'text',
|
|
687
|
+
} })] }), _jsxs(FormControl, { sx: { marginBottom: 3 }, disabled: isFormReadOnly, children: [_jsx(FormControl.Label, { children: "System Prompt Codemode Addons" }), _jsx(Box, { as: "textarea", value: systemPromptCodemodeAddons, onChange: e => onSystemPromptCodemodeAddonsChange(e.target.value), placeholder: "Additional codemode instructions", disabled: isFormReadOnly, readOnly: isFormReadOnly, rows: 4, sx: {
|
|
688
|
+
width: '100%',
|
|
689
|
+
maxWidth: '100%',
|
|
690
|
+
minHeight: '110px',
|
|
691
|
+
resize: 'vertical',
|
|
692
|
+
border: '1px solid',
|
|
693
|
+
borderColor: 'border.default',
|
|
694
|
+
borderRadius: 2,
|
|
695
|
+
p: 2,
|
|
696
|
+
fontFamily: 'mono',
|
|
697
|
+
fontSize: 1,
|
|
698
|
+
whiteSpace: 'pre-wrap',
|
|
699
|
+
overflowWrap: 'anywhere',
|
|
700
|
+
bg: isFormReadOnly ? 'canvas.subtle' : 'canvas.default',
|
|
701
|
+
color: isFormReadOnly ? 'fg.muted' : 'fg.default',
|
|
702
|
+
userSelect: isFormReadOnly ? 'none' : 'text',
|
|
703
|
+
cursor: isFormReadOnly ? 'not-allowed' : 'text',
|
|
704
|
+
} })] }), _jsxs(Box, { sx: { display: 'flex', gap: 3, marginBottom: 3 }, children: [_jsxs(FormControl, { sx: { flex: 1 }, disabled: isFormReadOnly, children: [_jsx(FormControl.Label, { children: "Tools (comma-separated)" }), _jsx(TextInput, { value: toolsInputValue, onChange: e => onToolsChange(e.target.value
|
|
445
705
|
.split(',')
|
|
446
706
|
.map(tool => tool.trim())
|
|
447
|
-
.filter(Boolean)), placeholder:
|
|
707
|
+
.filter(Boolean)), placeholder: toolsInputPlaceholder, sx: { width: '100%' } })] }), _jsxs(FormControl, { sx: { flex: 1 }, disabled: isFormReadOnly, children: [_jsx(FormControl.Label, { children: "Sandbox Variant" }), _jsxs(Select, { value: sandboxVariant, onChange: e => onSandboxVariantChange(e.target.value), sx: { width: '100%' }, children: [_jsx(Select.Option, { value: "", children: "Default" }), _jsx(Select.Option, { value: "eval", children: "eval" }), _jsx(Select.Option, { value: "jupyter", children: "jupyter" })] })] })] }), _jsxs(Box, { sx: {
|
|
448
708
|
marginBottom: 3,
|
|
449
709
|
padding: 3,
|
|
450
710
|
border: '1px solid',
|
|
@@ -470,7 +730,7 @@ export const AgentConfiguration = ({ agentLibrary, protocol: transport, extensio
|
|
|
470
730
|
color: 'fg.muted',
|
|
471
731
|
fontWeight: 'normal',
|
|
472
732
|
ml: 2,
|
|
473
|
-
}, children: "\u2014 defined by spec" }))] }), _jsx(Box, { sx: { display: 'flex', gap: 4, opacity: isSpecMode ? 0.6 : 1 }, children: _jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Checkbox, { checked: enableCodemode, disabled: !isNewAgentMode || isSpecMode, 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: "
|
|
733
|
+
}, children: "\u2014 defined by spec" }))] }), _jsx(Box, { sx: { display: 'flex', gap: 4, opacity: isSpecMode ? 0.6 : 1 }, children: _jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Checkbox, { checked: enableCodemode, disabled: !isNewAgentMode || isSpecMode, 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: "Codemode composes tools with Python for multi-step execution." }) })), skillsEnabled && !enableCodemode && (_jsx(Flash, { variant: "default", sx: { mt: 3 }, children: _jsx(Text, { sx: { fontSize: 0 }, children: "Skills will run with a standalone code sandbox for script execution. Enable Codemode to compose skills with other tools." }) })), 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: !isNewAgentMode || isSpecMode, 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: !isNewAgentMode || isSpecMode, 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: !isNewAgentMode || isSpecMode, 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 Sandbox instead of eval Sandbox" })] })] })] }))] }), _jsxs(Box, { sx: {
|
|
474
734
|
marginBottom: 3,
|
|
475
735
|
padding: 3,
|
|
476
736
|
border: '1px solid',
|
|
@@ -488,7 +748,7 @@ export const AgentConfiguration = ({ agentLibrary, protocol: transport, extensio
|
|
|
488
748
|
color: 'fg.muted',
|
|
489
749
|
fontWeight: 'normal',
|
|
490
750
|
ml: 2,
|
|
491
|
-
}, children: "\u2014 defined by spec" }))] }), skillsQuery.isLoading && _jsx(Spinner, { size: "small" }), !skillsQuery.isLoading && (_jsx(Button, { variant: "invisible", size: "small", onClick: () => skillsQuery.refetch(), sx: { padding: 1 }, "aria-label": "Refresh skills", children: _jsx(SyncIcon, { size: 14 }) }))] }), skillsQuery.isError
|
|
751
|
+
}, children: "\u2014 defined by spec" }))] }), skillsQuery.isLoading && _jsx(Spinner, { size: "small" }), !skillsQuery.isLoading && (_jsx(Button, { variant: "invisible", size: "small", onClick: () => skillsQuery.refetch(), sx: { padding: 1 }, "aria-label": "Refresh skills", children: _jsx(SyncIcon, { size: 14 }) }))] }), skillsQuery.isError && !usingSpecSkills && (_jsx(Flash, { variant: "warning", sx: { marginBottom: 2 }, children: _jsx(Text, { sx: { fontSize: 0 }, children: "Unable to fetch runtime skills. Using built-in skill specs catalog." }) })), usingSpecSkills && (_jsx(Flash, { variant: "default", sx: { marginBottom: 2 }, children: _jsx(Text, { sx: { fontSize: 0 }, children: "Skills are sourced from the selected agent spec." }) })), usingCatalogFallback && !skillsQuery.isLoading && (_jsx(Flash, { variant: "default", sx: { marginBottom: 2 }, children: _jsx(Text, { sx: { fontSize: 0 }, children: "Skills are sourced from the local skill specs catalog." }) })), displaySkills.length === 0 && !skillsQuery.isLoading ? (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "No skills available." })) : (_jsx(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 2 }, children: displaySkills.map(skill => (_jsxs(Box, { sx: {
|
|
492
752
|
display: 'flex',
|
|
493
753
|
alignItems: 'center',
|
|
494
754
|
gap: 2,
|
|
@@ -496,13 +756,16 @@ export const AgentConfiguration = ({ agentLibrary, protocol: transport, extensio
|
|
|
496
756
|
borderRadius: 1,
|
|
497
757
|
backgroundColor: 'canvas.subtle',
|
|
498
758
|
opacity: !isNewAgentMode || isSpecMode ? 0.6 : 1,
|
|
499
|
-
}, children: [_jsx(Checkbox, { checked: selectedSkills.includes(skill.id), disabled: !isNewAgentMode || isSpecMode, onChange: e => handleSkillChange(skill.id, e.target.checked) }), _jsxs(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 1 }, children: [_jsx(Text, { sx: { fontWeight: 'semibold' }, children: skill.name }), skill.description && (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: skill.description }))
|
|
759
|
+
}, children: [_jsx(Checkbox, { checked: selectedSkills.includes(skill.id), disabled: !isNewAgentMode || isSpecMode, onChange: e => handleSkillChange(skill.id, e.target.checked) }), _jsxs(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 1 }, children: [_jsx(Text, { sx: { fontWeight: 'semibold' }, children: skill.name }), skill.description && (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: skill.description })), skill.requiredEnvVars &&
|
|
760
|
+
skill.requiredEnvVars.length > 0 && (_jsx(Box, { sx: { display: 'flex', flexWrap: 'wrap', gap: 1 }, children: skill.requiredEnvVars.map(envVar => (_jsx(Label, { size: "small", variant: skill.isAvailable ? 'success' : 'danger', children: envVar }, `${skill.id}-${envVar}`))) })), (!skill.requiredEnvVars ||
|
|
761
|
+
skill.requiredEnvVars.length === 0) && (_jsx(Label, { size: "small", variant: "success", children: "No env vars required" }))] })] }, skill.id))) }))] }), _jsxs(Box, { sx: {
|
|
500
762
|
marginBottom: 3,
|
|
501
763
|
padding: 3,
|
|
502
764
|
border: '1px solid',
|
|
503
765
|
borderColor: 'border.default',
|
|
504
766
|
borderRadius: 2,
|
|
505
767
|
backgroundColor: 'canvas.default',
|
|
768
|
+
opacity: isSpecMode ? 0.6 : 1,
|
|
506
769
|
}, children: [_jsxs(Box, { sx: {
|
|
507
770
|
display: 'flex',
|
|
508
771
|
alignItems: 'center',
|
|
@@ -513,9 +776,9 @@ export const AgentConfiguration = ({ agentLibrary, protocol: transport, extensio
|
|
|
513
776
|
color: 'fg.muted',
|
|
514
777
|
fontWeight: 'normal',
|
|
515
778
|
ml: 2,
|
|
516
|
-
}, children: "\u2014 defined by spec" }))] }), 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 &&
|
|
779
|
+
}, children: "\u2014 defined by spec" }))] }), mcpServersQuery.isLoading && _jsx(Spinner, { size: "small" }), !mcpServersQuery.isLoading && (_jsx(Button, { variant: "invisible", size: "small", onClick: () => mcpServersQuery.refetch(), disabled: mcpServersDisabled, 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 &&
|
|
517
780
|
!mcpServersQuery.isLoading &&
|
|
518
|
-
!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: {
|
|
781
|
+
!mcpServersQuery.isError && (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "No MCP config servers found. Add servers to ~/.datalayer/mcp.json" })), unresolvedSelectedMcpServers.length > 0 && (_jsx(Flash, { variant: "warning", sx: { marginTop: 2, marginBottom: 2 }, children: _jsxs(Text, { sx: { fontSize: 0 }, children: ["Selected in spec but not available in this environment:", ' ', unresolvedSelectedMcpServers.join(', ')] }) })), 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: {
|
|
519
782
|
marginBottom: 2,
|
|
520
783
|
padding: 2,
|
|
521
784
|
borderRadius: 1,
|
|
@@ -526,7 +789,11 @@ export const AgentConfiguration = ({ agentLibrary, protocol: transport, extensio
|
|
|
526
789
|
selectedCatalogServers.length > 0
|
|
527
790
|
? 'Using selected MCP servers'
|
|
528
791
|
: 'No servers selected — select servers to scope Codemode tools.' }), previewConfigServers.length > 0 ||
|
|
529
|
-
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
|
|
792
|
+
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 > 0
|
|
793
|
+
? ` ${server.tools.length} tools (config)`
|
|
794
|
+
: ' tools discovered when launched (config)'] }, server.id))), previewCatalogServers.map(server => (_jsxs(Text, { sx: { fontSize: 0 }, children: [server.name, " \u2014", (server.tools?.length || 0) > 0
|
|
795
|
+
? ` ${server.tools?.length || 0} tools (catalog)`
|
|
796
|
+
: ' tools discovered when launched (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: {
|
|
530
797
|
display: 'flex',
|
|
531
798
|
alignItems: 'flex-start',
|
|
532
799
|
gap: 2,
|
|
@@ -546,6 +813,7 @@ export const AgentConfiguration = ({ agentLibrary, protocol: transport, extensio
|
|
|
546
813
|
borderColor: 'border.default',
|
|
547
814
|
borderRadius: 2,
|
|
548
815
|
backgroundColor: 'canvas.default',
|
|
816
|
+
opacity: isSpecMode ? 0.6 : 1,
|
|
549
817
|
}, children: [_jsxs(Box, { sx: {
|
|
550
818
|
display: 'flex',
|
|
551
819
|
alignItems: 'center',
|
|
@@ -580,20 +848,7 @@ export const AgentConfiguration = ({ agentLibrary, protocol: transport, extensio
|
|
|
580
848
|
flex: 1,
|
|
581
849
|
}, children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Text, { sx: { fontWeight: 'semibold' }, children: server.name }), enableCatalogServerMutation.isPending &&
|
|
582
850
|
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));
|
|
583
|
-
}) })] })), createError && (_jsx(Flash, { variant: "danger", sx: { marginBottom: 3 }, children: createError })),
|
|
584
|
-
marginBottom: 3,
|
|
585
|
-
padding: 3,
|
|
586
|
-
border: '1px solid',
|
|
587
|
-
borderColor: 'border.default',
|
|
588
|
-
borderRadius: 2,
|
|
589
|
-
backgroundColor: 'canvas.default',
|
|
590
|
-
}, children: [_jsx(Text, { sx: { fontSize: 1, fontWeight: 'bold', display: 'block', mb: 2 }, children: "Agent Spec Attributes" }), _jsx(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 2 }, children: selectedSpecEntries.map(([key, value]) => (_jsxs(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 1 }, children: [_jsx(Text, { sx: { fontSize: 0, fontWeight: 'semibold' }, children: key }), _jsx(Text, { sx: {
|
|
591
|
-
fontSize: 0,
|
|
592
|
-
color: 'fg.muted',
|
|
593
|
-
whiteSpace: 'pre-wrap',
|
|
594
|
-
}, children: typeof value === 'string'
|
|
595
|
-
? value
|
|
596
|
-
: JSON.stringify(value, null, 2) })] }, key))) })] })), _jsx(Button, { variant: "primary", onClick: onConnect, disabled: isCreatingAgent ||
|
|
851
|
+
}) })] })), createError && (_jsx(Flash, { variant: "danger", sx: { marginBottom: 3 }, children: createError })), _jsx(Button, { variant: "primary", onClick: onConnect, disabled: isCreatingAgent ||
|
|
597
852
|
!agentName ||
|
|
598
853
|
(transport === 'acp' ? !wsUrl : !baseUrl), sx: { width: '100%' }, children: isCreatingAgent ? (_jsxs(Box, { sx: {
|
|
599
854
|
display: 'flex',
|
|
@@ -127,7 +127,8 @@ const AgUiSharedStateExample = () => {
|
|
|
127
127
|
setRecipe(DEFAULT_RECIPE);
|
|
128
128
|
}, []);
|
|
129
129
|
return (_jsx(ThemedProvider, { children: _jsxs(Box, { sx: {
|
|
130
|
-
|
|
130
|
+
height: '100%',
|
|
131
|
+
overflow: 'auto',
|
|
131
132
|
backgroundColor: 'canvas.default',
|
|
132
133
|
padding: 4,
|
|
133
134
|
}, children: [_jsxs(Box, { sx: {
|
|
@@ -49,7 +49,7 @@ const AGENT_SPEC = {
|
|
|
49
49
|
id: 'monitor-sales-kpis',
|
|
50
50
|
name: 'Monitor Sales KPIs',
|
|
51
51
|
description: 'Monitor and analyze sales KPIs from the CRM system. Generate daily reports, identify trends, and flag anomalies.',
|
|
52
|
-
model: 'bedrock:us.anthropic.claude-
|
|
52
|
+
model: 'bedrock:us.anthropic.claude-sonnet-4-5-20250929-v1:0',
|
|
53
53
|
protocol: 'vercel-ai',
|
|
54
54
|
memory: 'mem0',
|
|
55
55
|
sandbox_variant: 'jupyter',
|
|
@@ -91,7 +91,7 @@ const AgentCheckpointsInner = ({ onLogout, }) => {
|
|
|
91
91
|
agentSpec: AGENT_SPEC,
|
|
92
92
|
agentConfig: {
|
|
93
93
|
name: DEMO_AGENT_NAME,
|
|
94
|
-
model: 'bedrock:us.anthropic.claude-
|
|
94
|
+
model: 'bedrock:us.anthropic.claude-sonnet-4-5-20250929-v1:0',
|
|
95
95
|
protocol: 'vercel-ai',
|
|
96
96
|
description: 'Monitor Sales KPI agent — exercises pause/resume checkpointing',
|
|
97
97
|
},
|
|
@@ -436,7 +436,7 @@ const AgentCheckpointsInner = ({ onLogout, }) => {
|
|
|
436
436
|
gap: 3,
|
|
437
437
|
px: 3,
|
|
438
438
|
}, children: [_jsx(AgentIcon, { size: 48 }), _jsx(Heading, { as: "h2", sx: { fontSize: 3 }, children: "Checkpoint Agent" }), _jsxs(Text, { sx: { color: 'fg.muted', textAlign: 'center', maxWidth: 560 }, children: ["Launch a cloud agent runtime with pause/resume checkpointing. The agent will be deployed from the", ' ', _jsx("strong", { children: AGENT_SPEC_ID }), " spec."] }), displayError && (_jsx(Flash, { variant: "danger", sx: { maxWidth: 560, width: '100%' }, children: displayError })), _jsx(Button, { variant: "primary", size: "large", leadingVisual: PlayIcon, onClick: handleLaunch, children: "Launch Agent" })] })) : (isReady || runtimeStatus === 'resumed') &&
|
|
439
|
-
runtimeStatus !== 'paused' ? (_jsx(Chat, { protocol: "vercel-ai", baseUrl: agentBaseUrl, agentId: agentId, title: "Monitor Sales KPI Agent", placeholder: "Ask about sales KPIs\u2026", description: "Monitor Sales KPI agent with pause/resume checkpointing", showHeader: false, showTokenUsage: true, autoFocus: true, height: "100%", runtimeId: podName, historyEndpoint: `${agentBaseUrl}/api/v1/history`, suggestions: [
|
|
439
|
+
runtimeStatus !== 'paused' ? (_jsx(Chat, { protocol: "vercel-ai", baseUrl: agentBaseUrl, agentId: agentId, title: "Monitor Sales KPI Agent", brandIcon: _jsx(AgentIcon, { size: 16 }), placeholder: "Ask about sales KPIs\u2026", description: "Monitor Sales KPI agent with pause/resume checkpointing", showHeader: false, showTokenUsage: true, autoFocus: true, height: "100%", runtimeId: podName, historyEndpoint: `${agentBaseUrl}/api/v1/history`, suggestions: [
|
|
440
440
|
{
|
|
441
441
|
title: 'KPIs',
|
|
442
442
|
message: "Show me today's sales KPI dashboard",
|