@datalayer/agent-runtimes 1.0.4 → 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 +182 -1
- package/lib/AgentNode.d.ts +3 -0
- package/lib/AgentNode.js +676 -0
- package/lib/App.js +1 -1
- 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/agents/AgentDetails.d.ts +22 -1
- package/lib/agents/AgentDetails.js +34 -47
- package/lib/api/index.d.ts +0 -1
- package/lib/api/index.js +4 -2
- package/lib/chat/Chat.d.ts +5 -106
- package/lib/chat/Chat.js +20 -14
- package/lib/chat/ChatFloating.d.ts +7 -140
- package/lib/chat/ChatFloating.js +3 -3
- package/lib/chat/ChatPopupStandalone.d.ts +8 -47
- package/lib/chat/ChatPopupStandalone.js +3 -3
- package/lib/chat/ChatSidebar.d.ts +4 -69
- package/lib/chat/ChatSidebar.js +83 -51
- package/lib/chat/ChatStandalone.d.ts +4 -54
- package/lib/chat/ChatStandalone.js +3 -3
- package/lib/chat/base/ChatBase.js +1414 -174
- 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 +30 -5
- package/lib/chat/header/ChatHeaderBase.js +41 -16
- package/lib/chat/indicators/McpStatusIndicator.d.ts +7 -4
- package/lib/chat/indicators/McpStatusIndicator.js +7 -32
- package/lib/chat/indicators/SandboxStatusIndicator.d.ts +4 -1
- package/lib/chat/indicators/SandboxStatusIndicator.js +91 -56
- package/lib/chat/indicators/SkillsStatusIndicator.d.ts +7 -0
- package/lib/chat/indicators/SkillsStatusIndicator.js +88 -0
- package/lib/chat/indicators/index.d.ts +1 -0
- package/lib/chat/indicators/index.js +1 -0
- package/lib/chat/messages/ChatMessageList.d.ts +1 -1
- package/lib/chat/messages/ChatMessageList.js +154 -114
- package/lib/chat/messages/ChatMessages.js +6 -2
- package/lib/chat/prompt/InputFooter.d.ts +21 -6
- package/lib/chat/prompt/InputFooter.js +76 -20
- package/lib/chat/prompt/InputPrompt.d.ts +5 -1
- package/lib/chat/prompt/InputPrompt.js +4 -4
- package/lib/chat/prompt/InputPromptFooter.d.ts +3 -1
- package/lib/chat/prompt/InputPromptFooter.js +3 -3
- package/lib/chat/prompt/InputPromptLexical.d.ts +3 -1
- package/lib/chat/prompt/InputPromptLexical.js +12 -5
- package/lib/chat/prompt/InputPromptText.d.ts +3 -1
- package/lib/chat/prompt/InputPromptText.js +2 -2
- package/lib/chat/tools/ToolApprovalBanner.js +1 -1
- package/lib/chat/tools/ToolCallDisplay.d.ts +3 -1
- package/lib/chat/tools/ToolCallDisplay.js +2 -2
- package/lib/chat/usage/TokenUsageBar.js +20 -2
- package/lib/client/AgentRuntimesClientContext.d.ts +53 -0
- package/lib/client/AgentRuntimesClientContext.js +55 -0
- package/lib/client/AgentsMixin.d.ts +0 -18
- package/lib/client/AgentsMixin.js +20 -30
- package/lib/client/IAgentRuntimesClient.d.ts +215 -0
- package/lib/client/IAgentRuntimesClient.js +5 -0
- package/lib/client/SdkAgentRuntimesClient.d.ts +151 -0
- package/lib/client/SdkAgentRuntimesClient.js +134 -0
- package/lib/client/index.d.ts +4 -1
- package/lib/client/index.js +3 -1
- package/lib/components/NotificationEventCard.js +5 -1
- package/lib/config/AgentConfiguration.d.ts +22 -0
- package/lib/config/AgentConfiguration.js +319 -64
- package/lib/context/ContextDistribution.d.ts +3 -1
- package/lib/context/ContextDistribution.js +8 -27
- package/lib/context/ContextInspector.d.ts +3 -1
- package/lib/context/ContextInspector.js +19 -67
- package/lib/context/ContextPanel.d.ts +3 -1
- package/lib/context/ContextPanel.js +104 -64
- package/lib/context/ContextUsage.d.ts +3 -1
- package/lib/context/ContextUsage.js +3 -3
- package/lib/context/CostTracker.d.ts +9 -3
- package/lib/context/CostTracker.js +26 -47
- package/lib/context/CostUsageChart.d.ts +12 -0
- package/lib/context/CostUsageChart.js +378 -0
- package/lib/context/GraphFlowChart.d.ts +16 -0
- package/lib/context/GraphFlowChart.js +182 -0
- package/lib/context/TokenUsageChart.d.ts +8 -1
- package/lib/context/TokenUsageChart.js +349 -211
- package/lib/context/TurnGraphChart.d.ts +39 -0
- package/lib/context/TurnGraphChart.js +538 -0
- package/lib/context/otelWsPool.d.ts +20 -0
- package/lib/context/otelWsPool.js +69 -0
- package/lib/examples/A2UiComponentGalleryExample.d.ts +0 -17
- package/lib/examples/A2UiComponentGalleryExample.js +315 -522
- package/lib/examples/A2UiContactCardExample.d.ts +0 -18
- package/lib/examples/A2UiContactCardExample.js +154 -411
- package/lib/examples/A2UiRestaurantExample.d.ts +0 -30
- package/lib/examples/A2UiRestaurantExample.js +114 -212
- package/lib/examples/A2UiViewerExample.d.ts +0 -18
- package/lib/examples/A2UiViewerExample.js +283 -532
- package/lib/examples/AgUiBackendToolRenderingExample.js +1 -1
- package/lib/examples/AgUiHaikuGenUiExample.d.ts +1 -1
- package/lib/examples/AgUiHaikuGenUiExample.js +1 -1
- package/lib/examples/AgUiSharedStateExample.js +2 -1
- package/lib/examples/AgentCheckpointsExample.js +14 -28
- package/lib/examples/AgentCodemodeExample.d.ts +4 -6
- package/lib/examples/AgentCodemodeExample.js +603 -169
- package/lib/examples/AgentEvalsExample.js +339 -53
- package/lib/examples/AgentGuardrailsExample.js +383 -66
- package/lib/examples/AgentHooksExample.d.ts +3 -0
- package/lib/examples/AgentHooksExample.js +122 -0
- package/lib/examples/AgentInferenceProviderExample.d.ts +3 -0
- package/lib/examples/AgentInferenceProviderExample.js +329 -0
- package/lib/examples/AgentMCPExample.d.ts +3 -0
- package/lib/examples/AgentMCPExample.js +481 -0
- package/lib/examples/AgentMemoryExample.d.ts +1 -2
- package/lib/examples/AgentMemoryExample.js +78 -33
- package/lib/examples/AgentMonitoringExample.js +261 -200
- package/lib/examples/AgentNotificationsExample.d.ts +1 -2
- package/lib/examples/AgentNotificationsExample.js +114 -33
- package/lib/examples/AgentOtelExample.js +32 -42
- package/lib/examples/AgentOutputsExample.d.ts +11 -6
- package/lib/examples/AgentOutputsExample.js +433 -81
- package/lib/examples/AgentParametersExample.d.ts +3 -0
- package/lib/examples/AgentParametersExample.js +248 -0
- package/lib/examples/AgentSandboxExample.d.ts +3 -3
- package/lib/examples/AgentSandboxExample.js +74 -45
- package/lib/examples/AgentSkillsExample.js +95 -103
- package/lib/examples/AgentSubagentsExample.d.ts +14 -0
- package/lib/examples/AgentSubagentsExample.js +228 -0
- package/lib/examples/AgentToolApprovalsExample.js +49 -561
- package/lib/examples/AgentTriggersExample.js +823 -569
- package/lib/examples/{AgentspecExample.d.ts → AgentspecsExample.d.ts} +2 -2
- package/lib/examples/AgentspecsExample.js +1096 -0
- package/lib/examples/ChatCustomExample.js +16 -28
- package/lib/examples/ChatExample.js +13 -29
- package/lib/examples/CopilotKitLexicalExample.js +2 -1
- package/lib/examples/CopilotKitNotebookExample.js +2 -1
- package/lib/examples/HomeExample.d.ts +15 -0
- package/lib/examples/HomeExample.js +77 -0
- package/lib/examples/Lexical2Example.js +4 -2
- package/lib/examples/{LexicalExample.d.ts → LexicalAgentExample.d.ts} +4 -4
- package/lib/examples/{LexicalExample.js → LexicalAgentExample.js} +66 -17
- package/lib/examples/{LexicalSidebarExample.d.ts → LexicalAgentSidebarExample.d.ts} +5 -5
- package/lib/examples/LexicalAgentSidebarExample.js +261 -0
- package/lib/examples/NotebookAgentExample.d.ts +9 -0
- package/lib/examples/NotebookAgentExample.js +192 -0
- package/lib/examples/{NotebookSidebarExample.d.ts → NotebookAgentSidebarExample.d.ts} +2 -2
- package/lib/examples/NotebookAgentSidebarExample.js +221 -0
- package/lib/examples/{DatalayerNotebookExample.d.ts → NotebookCollaborationExample.d.ts} +4 -4
- package/lib/examples/{DatalayerNotebookExample.js → NotebookCollaborationExample.js} +3 -3
- package/lib/examples/NotebookExample.d.ts +4 -7
- package/lib/examples/NotebookExample.js +14 -146
- package/lib/examples/components/AuthRequiredView.d.ts +6 -0
- package/lib/examples/components/AuthRequiredView.js +33 -0
- package/lib/examples/components/ExampleWrapper.d.ts +9 -3
- package/lib/examples/components/ExampleWrapper.js +45 -9
- package/lib/examples/{ag-ui → components}/haiku/HaikuDisplay.js +1 -1
- package/lib/examples/{ag-ui → components}/haiku/InlineHaikuCard.js +1 -1
- package/lib/examples/{ag-ui → components}/haiku/index.d.ts +1 -1
- package/lib/examples/{ag-ui → components}/haiku/index.js +1 -1
- package/lib/examples/components/index.d.ts +3 -0
- package/lib/examples/components/index.js +4 -0
- package/lib/examples/{ag-ui → components}/weather/index.d.ts +1 -1
- package/lib/examples/{ag-ui → components}/weather/index.js +1 -1
- package/lib/examples/example-selector.d.ts +17 -4
- package/lib/examples/example-selector.js +108 -41
- package/lib/examples/index.d.ts +10 -6
- package/lib/examples/index.js +10 -6
- package/lib/examples/lexical/initial-content.json +6 -6
- package/lib/examples/main.js +257 -27
- package/lib/examples/utils/a2ui.d.ts +18 -0
- package/lib/examples/utils/a2ui.js +69 -0
- package/lib/examples/utils/a2uiMarkdownProvider.d.ts +7 -0
- package/lib/examples/utils/a2uiMarkdownProvider.js +9 -0
- package/lib/examples/utils/agentId.d.ts +18 -0
- package/lib/examples/utils/agentId.js +54 -0
- package/lib/examples/utils/agents/earthquake-detector.json +11 -11
- package/lib/examples/utils/agents/sales-forecaster.json +11 -11
- package/lib/examples/utils/agents/social-post-generator.json +11 -11
- package/lib/examples/utils/agents/stock-market.json +11 -11
- package/lib/examples/utils/examplesStore.js +82 -27
- package/lib/examples/utils/useExampleAgentRuntimesUrl.d.ts +5 -0
- package/lib/examples/utils/useExampleAgentRuntimesUrl.js +19 -0
- package/lib/hooks/index.d.ts +8 -8
- package/lib/hooks/index.js +7 -7
- package/lib/hooks/useA2A.d.ts +2 -3
- package/lib/hooks/useAIAgentsWebSocket.d.ts +43 -4
- package/lib/hooks/useAIAgentsWebSocket.js +153 -12
- package/lib/hooks/useAcp.d.ts +1 -2
- package/lib/hooks/useAgUi.d.ts +1 -1
- package/lib/hooks/{useAgents.d.ts → useAgentRuntimes.d.ts} +70 -4
- package/lib/hooks/{useAgents.js → useAgentRuntimes.js} +237 -32
- package/lib/hooks/useAgentsCatalog.js +1 -1
- package/lib/hooks/useAgentsService.d.ts +2 -2
- package/lib/hooks/useAgentsService.js +7 -7
- package/lib/hooks/useCheckpoints.js +1 -1
- package/lib/hooks/useConfig.d.ts +4 -1
- package/lib/hooks/useConfig.js +10 -3
- package/lib/hooks/useContextSnapshot.d.ts +9 -4
- package/lib/hooks/useContextSnapshot.js +9 -37
- package/lib/hooks/useMonitoring.js +3 -0
- package/lib/hooks/useSandbox.d.ts +20 -8
- package/lib/hooks/useSandbox.js +105 -40
- package/lib/hooks/useSkills.d.ts +23 -5
- package/lib/hooks/useSkills.js +94 -39
- package/lib/hooks/useToolApprovals.d.ts +60 -36
- package/lib/hooks/useToolApprovals.js +318 -69
- package/lib/hooks/useVercelAI.d.ts +1 -1
- package/lib/index.d.ts +2 -1
- package/lib/index.js +1 -0
- package/lib/inference/index.d.ts +0 -1
- package/lib/middleware/index.d.ts +0 -1
- package/lib/protocols/AGUIAdapter.js +6 -0
- package/lib/protocols/VercelAIAdapter.d.ts +7 -0
- package/lib/protocols/VercelAIAdapter.js +59 -7
- package/lib/specs/agents/agents.d.ts +21 -4
- package/lib/specs/agents/agents.js +2879 -316
- package/lib/specs/agents/index.js +3 -1
- package/lib/specs/benchmarks.d.ts +20 -0
- package/lib/specs/benchmarks.js +205 -0
- package/lib/specs/envvars.js +27 -20
- package/lib/specs/evals.d.ts +10 -9
- package/lib/specs/evals.js +128 -88
- package/lib/specs/events.d.ts +3 -10
- package/lib/specs/events.js +127 -84
- package/lib/specs/frontendTools.js +2 -2
- package/lib/specs/guardrails.d.ts +0 -7
- package/lib/specs/guardrails.js +240 -159
- package/lib/specs/mcpServers.js +35 -6
- package/lib/specs/memory.d.ts +0 -2
- package/lib/specs/memory.js +4 -17
- package/lib/specs/models.d.ts +0 -2
- package/lib/specs/models.js +20 -15
- package/lib/specs/notifications.js +102 -18
- package/lib/specs/outputs.js +15 -9
- package/lib/specs/personas.d.ts +41 -0
- package/lib/specs/personas.js +168 -0
- package/lib/specs/skills.d.ts +1 -1
- package/lib/specs/skills.js +23 -23
- package/lib/specs/teams/index.js +3 -1
- package/lib/specs/teams/teams.js +468 -348
- package/lib/specs/tools.js +4 -4
- package/lib/specs/triggers.js +61 -11
- package/lib/stores/agentRuntimeStore.d.ts +208 -0
- package/lib/stores/agentRuntimeStore.js +650 -0
- package/lib/stores/conversationStore.js +2 -2
- package/lib/stores/index.d.ts +1 -1
- package/lib/stores/index.js +1 -1
- package/lib/tools/adapters/copilotkit/lexicalHooks.d.ts +1 -2
- package/lib/tools/adapters/copilotkit/lexicalHooks.js +1 -3
- package/lib/tools/adapters/copilotkit/notebookHooks.d.ts +1 -2
- package/lib/tools/adapters/copilotkit/notebookHooks.js +1 -3
- package/lib/tools/index.d.ts +0 -2
- package/lib/tools/index.js +0 -1
- package/lib/types/agents-lifecycle.d.ts +18 -0
- package/lib/types/agents.d.ts +6 -0
- package/lib/types/agentspecs.d.ts +54 -1
- package/lib/types/benchmarks.d.ts +43 -0
- package/lib/types/benchmarks.js +5 -0
- package/lib/types/chat.d.ts +325 -8
- package/lib/types/context.d.ts +27 -0
- package/lib/types/cost.d.ts +2 -2
- package/lib/types/evals.d.ts +26 -17
- package/lib/types/index.d.ts +3 -0
- package/lib/types/index.js +3 -0
- package/lib/types/mcp.d.ts +8 -0
- package/lib/types/models.d.ts +2 -2
- package/lib/types/personas.d.ts +25 -0
- package/lib/types/personas.js +5 -0
- package/lib/types/skills.d.ts +43 -1
- package/lib/types/stream.d.ts +110 -0
- package/lib/types/stream.js +36 -0
- package/lib/utils/utils.d.ts +9 -5
- package/lib/utils/utils.js +9 -5
- package/package.json +19 -11
- 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/__pycache__/generate_events.cpython-313.pyc +0 -0
- package/scripts/codegen/__pycache__/versioning.cpython-313.pyc +0 -0
- package/scripts/codegen/generate_agents.py +187 -45
- package/scripts/codegen/generate_benchmarks.py +441 -0
- package/scripts/codegen/generate_evals.py +94 -16
- package/scripts/codegen/generate_events.py +35 -14
- package/scripts/codegen/generate_personas.py +319 -0
- package/scripts/codegen/generate_skills.py +9 -9
- package/scripts/sync-jupyter.sh +26 -7
- package/lib/api/tool-approvals.d.ts +0 -62
- package/lib/api/tool-approvals.js +0 -145
- package/lib/examples/AgentspecExample.js +0 -705
- package/lib/examples/LexicalSidebarExample.js +0 -163
- package/lib/examples/NotebookSidebarExample.js +0 -119
- package/lib/examples/NotebookSimpleExample.d.ts +0 -6
- package/lib/examples/NotebookSimpleExample.js +0 -22
- package/lib/examples/ag-ui/index.d.ts +0 -10
- package/lib/examples/ag-ui/index.js +0 -16
- package/lib/hooks/useAgentsRegistry.d.ts +0 -10
- package/lib/hooks/useAgentsRegistry.js +0 -20
- package/lib/stores/agentsStore.d.ts +0 -123
- package/lib/stores/agentsStore.js +0 -270
- /package/lib/examples/{ag-ui → components}/haiku/HaikuDisplay.d.ts +0 -0
- /package/lib/examples/{ag-ui → components}/haiku/InlineHaikuCard.d.ts +0 -0
- /package/lib/examples/{ag-ui → components}/weather/InlineWeatherCard.d.ts +0 -0
- /package/lib/examples/{ag-ui → components}/weather/InlineWeatherCard.js +0 -0
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright (c) 2025-2026 Datalayer, Inc.
|
|
4
|
+
* Distributed under the terms of the Modified BSD License.
|
|
5
|
+
*/
|
|
6
|
+
import { useEffect, useMemo, useState } from 'react';
|
|
7
|
+
import { Box, setupPrimerPortals } from '@datalayer/primer-addons';
|
|
8
|
+
import { Button, Heading, Label, Spinner, Text } from '@primer/react';
|
|
9
|
+
import { FileIcon } from '@primer/octicons-react';
|
|
10
|
+
import validator from '@rjsf/validator-ajv8';
|
|
11
|
+
import { Form, yamlSchemaToJsonSchema } from '@datalayer/primer-rjsf';
|
|
12
|
+
import { ThemedProvider } from './utils/themedProvider';
|
|
13
|
+
import { uniqueAgentId } from './utils/agentId';
|
|
14
|
+
import { useExampleAgentRuntimesUrl } from './utils/useExampleAgentRuntimesUrl';
|
|
15
|
+
import { ErrorView } from './components';
|
|
16
|
+
import { Chat } from '../chat';
|
|
17
|
+
setupPrimerPortals();
|
|
18
|
+
const AGENT_SPEC_ID = 'example-parameters';
|
|
19
|
+
const AGENT_NAME = 'parameters-demo';
|
|
20
|
+
function isRecord(value) {
|
|
21
|
+
return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
|
|
22
|
+
}
|
|
23
|
+
function looksLikeJsonSchema(value) {
|
|
24
|
+
if (!isRecord(value)) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
return (typeof value.type === 'string' ||
|
|
28
|
+
isRecord(value.properties) ||
|
|
29
|
+
Array.isArray(value.required));
|
|
30
|
+
}
|
|
31
|
+
function unwrapTypedLiterals(value) {
|
|
32
|
+
if (Array.isArray(value)) {
|
|
33
|
+
return value.map(unwrapTypedLiterals);
|
|
34
|
+
}
|
|
35
|
+
if (!isRecord(value)) {
|
|
36
|
+
return value;
|
|
37
|
+
}
|
|
38
|
+
const keys = Object.keys(value);
|
|
39
|
+
const hasTypedDefault = typeof value.type === 'string' && 'default' in value && keys.length <= 2;
|
|
40
|
+
if (hasTypedDefault) {
|
|
41
|
+
return unwrapTypedLiterals(value.default);
|
|
42
|
+
}
|
|
43
|
+
const normalized = {};
|
|
44
|
+
for (const [key, nested] of Object.entries(value)) {
|
|
45
|
+
normalized[key] = unwrapTypedLiterals(nested);
|
|
46
|
+
}
|
|
47
|
+
return normalized;
|
|
48
|
+
}
|
|
49
|
+
function hasWrappedSchemaLiterals(value) {
|
|
50
|
+
const schema = value;
|
|
51
|
+
const typeIsWrapped = isRecord(schema.type);
|
|
52
|
+
const requiredHasWrapped = Array.isArray(schema.required) &&
|
|
53
|
+
schema.required.some(item => isRecord(item));
|
|
54
|
+
return typeIsWrapped || requiredHasWrapped;
|
|
55
|
+
}
|
|
56
|
+
function toRjsfSchema(parameters) {
|
|
57
|
+
if (looksLikeJsonSchema(parameters)) {
|
|
58
|
+
return parameters;
|
|
59
|
+
}
|
|
60
|
+
const converted = yamlSchemaToJsonSchema(parameters ?? {});
|
|
61
|
+
if (hasWrappedSchemaLiterals(converted)) {
|
|
62
|
+
return unwrapTypedLiterals(converted);
|
|
63
|
+
}
|
|
64
|
+
return converted;
|
|
65
|
+
}
|
|
66
|
+
function collectTopLevelDefaults(schema) {
|
|
67
|
+
const defaults = {};
|
|
68
|
+
const properties = schema.properties && typeof schema.properties === 'object'
|
|
69
|
+
? schema.properties
|
|
70
|
+
: {};
|
|
71
|
+
for (const [key, value] of Object.entries(properties)) {
|
|
72
|
+
if (value &&
|
|
73
|
+
typeof value === 'object' &&
|
|
74
|
+
!Array.isArray(value) &&
|
|
75
|
+
'default' in value) {
|
|
76
|
+
defaults[key] = value.default;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return defaults;
|
|
80
|
+
}
|
|
81
|
+
function hasRequiredValues(schema, formData) {
|
|
82
|
+
if (!schema ||
|
|
83
|
+
!Array.isArray(schema.required) ||
|
|
84
|
+
schema.required.length === 0) {
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
87
|
+
return schema.required.every(fieldName => {
|
|
88
|
+
if (typeof fieldName !== 'string') {
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
const value = formData[fieldName];
|
|
92
|
+
if (value === undefined || value === null) {
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
if (typeof value === 'string') {
|
|
96
|
+
return value.trim().length > 0;
|
|
97
|
+
}
|
|
98
|
+
if (Array.isArray(value)) {
|
|
99
|
+
return value.length > 0;
|
|
100
|
+
}
|
|
101
|
+
return true;
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
const AgentParametersExample = () => {
|
|
105
|
+
const baseUrl = useExampleAgentRuntimesUrl();
|
|
106
|
+
const [showSchemaForm, setShowSchemaForm] = useState(false);
|
|
107
|
+
const [isSchemaLoading, setIsSchemaLoading] = useState(false);
|
|
108
|
+
const [schema, setSchema] = useState(null);
|
|
109
|
+
const [formData, setFormData] = useState({});
|
|
110
|
+
const [agentId, setAgentId] = useState(null);
|
|
111
|
+
const [isCreating, setIsCreating] = useState(false);
|
|
112
|
+
const [error, setError] = useState(null);
|
|
113
|
+
const [formTouched, setFormTouched] = useState(false);
|
|
114
|
+
const hasRequired = useMemo(() => hasRequiredValues(schema, formData), [schema, formData]);
|
|
115
|
+
const canLaunch = useMemo(() => {
|
|
116
|
+
return showSchemaForm && schema !== null && !isSchemaLoading && hasRequired;
|
|
117
|
+
}, [schema, showSchemaForm, isSchemaLoading, hasRequired]);
|
|
118
|
+
const loadSchemaForm = async () => {
|
|
119
|
+
if (schema) {
|
|
120
|
+
setShowSchemaForm(true);
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
setIsSchemaLoading(true);
|
|
124
|
+
setError(null);
|
|
125
|
+
try {
|
|
126
|
+
const response = await fetch(`${baseUrl}/api/v1/agents/library/${AGENT_SPEC_ID}`);
|
|
127
|
+
if (!response.ok) {
|
|
128
|
+
throw new Error(`Failed to load schema: ${response.status}`);
|
|
129
|
+
}
|
|
130
|
+
const data = (await response.json());
|
|
131
|
+
const convertedSchema = toRjsfSchema(data.parameters ?? {});
|
|
132
|
+
setSchema(convertedSchema);
|
|
133
|
+
setFormData(collectTopLevelDefaults(convertedSchema));
|
|
134
|
+
setShowSchemaForm(true);
|
|
135
|
+
setFormTouched(false);
|
|
136
|
+
}
|
|
137
|
+
catch (err) {
|
|
138
|
+
setError(err instanceof Error ? err.message : 'Failed to load schema');
|
|
139
|
+
}
|
|
140
|
+
finally {
|
|
141
|
+
setIsSchemaLoading(false);
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
const launchAgent = async () => {
|
|
145
|
+
if (!canLaunch) {
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
setIsCreating(true);
|
|
149
|
+
setError(null);
|
|
150
|
+
try {
|
|
151
|
+
const name = uniqueAgentId(AGENT_NAME);
|
|
152
|
+
const response = await fetch(`${baseUrl}/api/v1/agents`, {
|
|
153
|
+
method: 'POST',
|
|
154
|
+
headers: { 'Content-Type': 'application/json' },
|
|
155
|
+
body: JSON.stringify({
|
|
156
|
+
name,
|
|
157
|
+
agent_spec_id: AGENT_SPEC_ID,
|
|
158
|
+
transport: 'vercel-ai',
|
|
159
|
+
agent_parameters: formData,
|
|
160
|
+
}),
|
|
161
|
+
});
|
|
162
|
+
if (!response.ok) {
|
|
163
|
+
const data = await response
|
|
164
|
+
.json()
|
|
165
|
+
.catch(() => ({ detail: 'Unknown error' }));
|
|
166
|
+
throw new Error(data.detail || `Failed to create agent: ${response.status}`);
|
|
167
|
+
}
|
|
168
|
+
const data = await response.json();
|
|
169
|
+
setAgentId(data.id);
|
|
170
|
+
}
|
|
171
|
+
catch (err) {
|
|
172
|
+
setError(err instanceof Error ? err.message : 'Failed to launch agent');
|
|
173
|
+
}
|
|
174
|
+
finally {
|
|
175
|
+
setIsCreating(false);
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
useEffect(() => {
|
|
179
|
+
return () => {
|
|
180
|
+
if (!agentId) {
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
void fetch(`${baseUrl}/api/v1/agents/${encodeURIComponent(agentId)}`, {
|
|
184
|
+
method: 'DELETE',
|
|
185
|
+
}).catch(() => {
|
|
186
|
+
// Ignore teardown failures in example mode.
|
|
187
|
+
});
|
|
188
|
+
};
|
|
189
|
+
}, [agentId, baseUrl]);
|
|
190
|
+
if (!agentId) {
|
|
191
|
+
return (_jsx(ThemedProvider, { children: _jsxs(Box, { sx: {
|
|
192
|
+
maxWidth: 760,
|
|
193
|
+
mx: 'auto',
|
|
194
|
+
mt: 6,
|
|
195
|
+
px: 3,
|
|
196
|
+
py: 2,
|
|
197
|
+
border: '1px solid',
|
|
198
|
+
borderColor: 'border.default',
|
|
199
|
+
borderRadius: 2,
|
|
200
|
+
display: 'flex',
|
|
201
|
+
flexDirection: 'column',
|
|
202
|
+
gap: 2,
|
|
203
|
+
bg: 'canvas.subtle',
|
|
204
|
+
}, children: [_jsx(Text, { sx: { fontSize: 0, fontWeight: 'bold', color: 'fg.muted' }, children: "CONFIGURE AGENT" }), _jsx(Heading, { as: "h2", sx: { fontSize: 2 }, children: "Launch Parameterized Agent" }), _jsx(Text, { sx: { color: 'fg.muted', fontSize: 1, maxWidth: 620 }, children: "Load the runtime schema directly from example-parameters, fill the generated form, then launch with validated parameters." }), _jsxs(Box, { sx: {
|
|
205
|
+
display: 'flex',
|
|
206
|
+
alignItems: 'center',
|
|
207
|
+
gap: 2,
|
|
208
|
+
flexWrap: 'wrap',
|
|
209
|
+
}, children: [_jsxs(Label, { variant: "accent", children: ["Spec: ", AGENT_SPEC_ID] }), _jsx(Label, { variant: "secondary", children: "Transport: vercel-ai" })] }), _jsxs(Box, { sx: { display: 'flex', gap: 2, flexWrap: 'wrap' }, children: [_jsx(Button, { variant: "primary", size: "small", type: "button", onClick: loadSchemaForm, disabled: isSchemaLoading, children: isSchemaLoading ? (_jsxs(_Fragment, { children: [_jsx(Spinner, { size: "small" }), " Loading Schema..."] })) : ('Show Parameter Form') }), schema && (_jsx(Button, { variant: "invisible", size: "small", type: "button", onClick: () => {
|
|
210
|
+
setShowSchemaForm(v => !v);
|
|
211
|
+
}, children: showSchemaForm ? 'Hide Form' : 'Show Form' }))] }), schema && (_jsxs(Box, { sx: {
|
|
212
|
+
display: 'flex',
|
|
213
|
+
gap: 2,
|
|
214
|
+
flexWrap: 'wrap',
|
|
215
|
+
alignItems: 'center',
|
|
216
|
+
py: 2,
|
|
217
|
+
px: 3,
|
|
218
|
+
border: '1px solid',
|
|
219
|
+
borderColor: 'border.default',
|
|
220
|
+
borderRadius: 2,
|
|
221
|
+
bg: 'canvas.subtle',
|
|
222
|
+
}, children: [_jsxs(Text, { sx: { color: 'fg.muted', fontSize: 1 }, children: ["Required fields:", ' ', Array.isArray(schema.required) ? schema.required.length : 0] }), _jsx(Label, { variant: hasRequired ? 'success' : 'attention', children: hasRequired ? 'Ready to launch' : 'Complete required fields' })] })), showSchemaForm && schema && (_jsx(Box, { sx: {
|
|
223
|
+
border: '1px solid',
|
|
224
|
+
borderColor: 'border.default',
|
|
225
|
+
borderRadius: 2,
|
|
226
|
+
p: 2,
|
|
227
|
+
bg: 'canvas.default',
|
|
228
|
+
}, children: _jsx(Form, { schema: schema, formData: formData, uiSchema: { 'ui:submitButtonOptions': { norender: true } }, validator: validator, onChange: ({ formData: nextData }) => {
|
|
229
|
+
setFormTouched(true);
|
|
230
|
+
setFormData(nextData ?? {});
|
|
231
|
+
}, onSubmit: (_, event) => {
|
|
232
|
+
event?.preventDefault();
|
|
233
|
+
event?.stopPropagation();
|
|
234
|
+
// Prevent implicit form submission; launching is click-only.
|
|
235
|
+
}, noHtml5Validate: true }) })), _jsx(Button, { variant: "primary", size: "small", type: "button", onClick: launchAgent, disabled: !canLaunch || isCreating, sx: { width: '100%' }, children: isCreating ? (_jsxs(_Fragment, { children: [_jsx(Spinner, { size: "small" }), " Launching..."] })) : ('Launch Agent') }), schema && formTouched && (_jsx(Text, { sx: { color: 'fg.muted', fontSize: 1 }, children: "Parameters are sent as agent_parameters in the create-agent request." })), error && _jsx(ErrorView, { error: "Launch failed", detail: error })] }) }));
|
|
236
|
+
}
|
|
237
|
+
return (_jsx(Chat, { protocol: "vercel-ai", baseUrl: baseUrl, agentId: agentId, title: `Parameterized Agent: ${String(formData.project ?? 'Project')}`, brandIcon: _jsx(FileIcon, { size: 16 }), placeholder: "Ask something about your configured project...", description: `Role: ${String(formData.role ?? 'n/a')} · Tone: ${String(formData.tone ?? 'n/a')}`, showHeader: true, showModelSelector: true, showToolsMenu: true, showSkillsMenu: true, showTokenUsage: true, showInformation: true, autoFocus: true, height: "100vh", runtimeId: agentId, historyEndpoint: `${baseUrl}/api/v1/history`, suggestions: [
|
|
238
|
+
{
|
|
239
|
+
title: 'Print demo_params',
|
|
240
|
+
message: 'Use execute_code to print(demo_params) from the sandbox, then explain what it is.',
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
title: 'Inspect demo_params',
|
|
244
|
+
message: "Use execute_code to print('demo_params =', demo_params) and confirm its type.",
|
|
245
|
+
},
|
|
246
|
+
], submitOnSuggestionClick: true }));
|
|
247
|
+
};
|
|
248
|
+
export default AgentParametersExample;
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* AgentSandboxExample
|
|
3
3
|
*
|
|
4
|
-
* Demonstrates sandbox variant switching (
|
|
4
|
+
* Demonstrates sandbox variant switching (eval / jupyter) with a live
|
|
5
5
|
* sidebar that streams WebSocket messages to and from the
|
|
6
6
|
* `/configure/sandbox/ws` endpoint.
|
|
7
7
|
*
|
|
8
|
-
* - Creates a local agent (spec:
|
|
9
|
-
* - SegmentedControl toggles between "
|
|
8
|
+
* - Creates a local agent (spec: example-full) with codemode enabled
|
|
9
|
+
* - SegmentedControl toggles between "eval" and "jupyter" variants
|
|
10
10
|
* - Sidebar shows live sandbox status, WebSocket event log, and an
|
|
11
11
|
* interrupt button
|
|
12
12
|
*
|
|
@@ -6,12 +6,12 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
6
6
|
/**
|
|
7
7
|
* AgentSandboxExample
|
|
8
8
|
*
|
|
9
|
-
* Demonstrates sandbox variant switching (
|
|
9
|
+
* Demonstrates sandbox variant switching (eval / jupyter) with a live
|
|
10
10
|
* sidebar that streams WebSocket messages to and from the
|
|
11
11
|
* `/configure/sandbox/ws` endpoint.
|
|
12
12
|
*
|
|
13
|
-
* - Creates a local agent (spec:
|
|
14
|
-
* - SegmentedControl toggles between "
|
|
13
|
+
* - Creates a local agent (spec: example-full) with codemode enabled
|
|
14
|
+
* - SegmentedControl toggles between "eval" and "jupyter" variants
|
|
15
15
|
* - Sidebar shows live sandbox status, WebSocket event log, and an
|
|
16
16
|
* interrupt button
|
|
17
17
|
*
|
|
@@ -21,19 +21,18 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
21
21
|
import { useCallback, useEffect, useMemo, useRef, useState, } from 'react';
|
|
22
22
|
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
23
23
|
import { Box } from '@datalayer/primer-addons';
|
|
24
|
-
import { ErrorView } from './components';
|
|
24
|
+
import { AuthRequiredView, ErrorView } from './components';
|
|
25
25
|
import { Button, Flash, Heading, Label, SegmentedControl, Spinner, Text, } from '@primer/react';
|
|
26
|
-
import { CodeIcon,
|
|
26
|
+
import { CodeIcon, StopIcon, TerminalIcon } from '@primer/octicons-react';
|
|
27
27
|
import { useSimpleAuthStore } from '@datalayer/core/lib/views/otel';
|
|
28
|
-
import { SignInSimple } from '@datalayer/core/lib/views/iam';
|
|
29
|
-
import { UserBadge } from '@datalayer/core/lib/views/profile';
|
|
30
28
|
import { ThemedProvider } from './utils/themedProvider';
|
|
29
|
+
import { uniqueAgentId } from './utils/agentId';
|
|
31
30
|
import { Chat } from '../chat';
|
|
32
31
|
import { SANDBOX_STATUS_COLORS, SANDBOX_STATUS_LABELS } from '../types/sandbox';
|
|
33
32
|
// ─── Constants ─────────────────────────────────────────────────────────────
|
|
34
33
|
const queryClient = new QueryClient();
|
|
35
|
-
const AGENT_NAME = 'sandbox-
|
|
36
|
-
const AGENT_SPEC_ID = '
|
|
34
|
+
const AGENT_NAME = 'sandbox-example-agent';
|
|
35
|
+
const AGENT_SPEC_ID = 'example-full';
|
|
37
36
|
const DEFAULT_LOCAL_BASE_URL = import.meta.env.VITE_BASE_URL || 'http://localhost:8765';
|
|
38
37
|
let _logId = 0;
|
|
39
38
|
function tsNow() {
|
|
@@ -62,16 +61,18 @@ function apiVariantFromUi(variant) {
|
|
|
62
61
|
// ─── Inner component (after auth) ──────────────────────────────────────────
|
|
63
62
|
const AgentSandboxInner = ({ onLogout, }) => {
|
|
64
63
|
const { token } = useSimpleAuthStore();
|
|
64
|
+
const agentName = useRef(uniqueAgentId(AGENT_NAME)).current;
|
|
65
65
|
const chatAuthToken = token === null ? undefined : token;
|
|
66
66
|
const agentBaseUrl = DEFAULT_LOCAL_BASE_URL;
|
|
67
67
|
// ── Agent lifecycle ──
|
|
68
68
|
const [runtimeStatus, setRuntimeStatus] = useState('launching');
|
|
69
69
|
const [isReady, setIsReady] = useState(false);
|
|
70
70
|
const [hookError, setHookError] = useState(null);
|
|
71
|
-
const [agentId, setAgentId] = useState(
|
|
71
|
+
const [agentId, setAgentId] = useState(agentName);
|
|
72
72
|
const [isReconnectedAgent, setIsReconnectedAgent] = useState(false);
|
|
73
73
|
// ── Sandbox variant toggle ──
|
|
74
|
-
const [variant, setVariant] = useState('
|
|
74
|
+
const [variant, setVariant] = useState('eval');
|
|
75
|
+
const [pendingVariant, setPendingVariant] = useState(null);
|
|
75
76
|
const [variantSwitching, setVariantSwitching] = useState(false);
|
|
76
77
|
const [lastSwitch, setLastSwitch] = useState(null);
|
|
77
78
|
// ── WebSocket state ──
|
|
@@ -107,7 +108,7 @@ const AgentSandboxInner = ({ onLogout, }) => {
|
|
|
107
108
|
try {
|
|
108
109
|
// Always delete any existing agent with this name first so we
|
|
109
110
|
// recreate it with the latest configuration (system prompt, toolsets).
|
|
110
|
-
await authFetch(`${agentBaseUrl}/api/v1/agents/${
|
|
111
|
+
await authFetch(`${agentBaseUrl}/api/v1/agents/${agentName}`, {
|
|
111
112
|
method: 'DELETE',
|
|
112
113
|
}).catch(() => {
|
|
113
114
|
/* ignore 404 / not-found */
|
|
@@ -115,7 +116,7 @@ const AgentSandboxInner = ({ onLogout, }) => {
|
|
|
115
116
|
const response = await authFetch(`${agentBaseUrl}/api/v1/agents`, {
|
|
116
117
|
method: 'POST',
|
|
117
118
|
body: JSON.stringify({
|
|
118
|
-
name:
|
|
119
|
+
name: agentName,
|
|
119
120
|
description: 'Agent with sandbox code execution',
|
|
120
121
|
agent_library: 'pydantic-ai',
|
|
121
122
|
transport: 'vercel-ai',
|
|
@@ -129,13 +130,13 @@ const AgentSandboxInner = ({ onLogout, }) => {
|
|
|
129
130
|
tools: [],
|
|
130
131
|
selected_mcp_servers: [],
|
|
131
132
|
enable_codemode: true,
|
|
132
|
-
sandbox_variant: '
|
|
133
|
+
sandbox_variant: 'eval',
|
|
133
134
|
}),
|
|
134
135
|
});
|
|
135
|
-
let resolvedAgentId =
|
|
136
|
+
let resolvedAgentId = agentName;
|
|
136
137
|
if (response.ok) {
|
|
137
138
|
const data = await response.json();
|
|
138
|
-
resolvedAgentId = data?.id ||
|
|
139
|
+
resolvedAgentId = data?.id || agentName;
|
|
139
140
|
}
|
|
140
141
|
else {
|
|
141
142
|
const contentType = response.headers.get('content-type') || '';
|
|
@@ -166,11 +167,11 @@ const AgentSandboxInner = ({ onLogout, }) => {
|
|
|
166
167
|
const text = await toggleResp.text().catch(() => '');
|
|
167
168
|
throw new Error(text || `Failed to activate codemode (${toggleResp.status})`);
|
|
168
169
|
}
|
|
169
|
-
addLog('sent', 'POST /agents/sandbox/configure {variant:
|
|
170
|
+
addLog('sent', 'POST /agents/sandbox/configure {variant:eval}');
|
|
170
171
|
const configureResp = await authFetch(`${agentBaseUrl}/api/v1/agents/sandbox/configure`, {
|
|
171
172
|
method: 'POST',
|
|
172
173
|
body: JSON.stringify({
|
|
173
|
-
variant: '
|
|
174
|
+
variant: 'eval',
|
|
174
175
|
}),
|
|
175
176
|
});
|
|
176
177
|
addLog('recv', `HTTP ${configureResp.status} /agents/sandbox/configure`);
|
|
@@ -191,7 +192,7 @@ const AgentSandboxInner = ({ onLogout, }) => {
|
|
|
191
192
|
}
|
|
192
193
|
await restartResp.json().catch(() => null);
|
|
193
194
|
setLastSwitch({
|
|
194
|
-
variant: String(configureData?.variant || '
|
|
195
|
+
variant: String(configureData?.variant || 'eval'),
|
|
195
196
|
switchedAt: new Date().toISOString(),
|
|
196
197
|
});
|
|
197
198
|
setAgentId(resolvedAgentId);
|
|
@@ -217,6 +218,7 @@ const AgentSandboxInner = ({ onLogout, }) => {
|
|
|
217
218
|
if (newVariant === variant)
|
|
218
219
|
return;
|
|
219
220
|
setVariantSwitching(true);
|
|
221
|
+
setPendingVariant(newVariant);
|
|
220
222
|
try {
|
|
221
223
|
// Keep codemode active, then reconfigure sandbox manager variant.
|
|
222
224
|
addLog('sent', 'POST /configure/codemode/toggle {enabled:true}');
|
|
@@ -264,6 +266,7 @@ const AgentSandboxInner = ({ onLogout, }) => {
|
|
|
264
266
|
setHookError(error instanceof Error ? error.message : 'Failed to switch variant');
|
|
265
267
|
}
|
|
266
268
|
finally {
|
|
269
|
+
setPendingVariant(null);
|
|
267
270
|
setVariantSwitching(false);
|
|
268
271
|
}
|
|
269
272
|
}, [variant, agentBaseUrl, authFetch]);
|
|
@@ -329,6 +332,25 @@ const AgentSandboxInner = ({ onLogout, }) => {
|
|
|
329
332
|
}, [addLog]);
|
|
330
333
|
// ── Derived display ──
|
|
331
334
|
const aggregate = useMemo(() => deriveAggregate(sandboxStatus), [sandboxStatus]);
|
|
335
|
+
const displayedVariant = pendingVariant ?? variant;
|
|
336
|
+
const isTransitionLocked = variantSwitching;
|
|
337
|
+
// Always use the example's authoritative variant (pending or confirmed)
|
|
338
|
+
// merged with the live WebSocket execution data. The WS status may lag
|
|
339
|
+
// behind after a configure+restart, so we never rely on its `variant` field.
|
|
340
|
+
const chatSandboxStatus = useMemo(() => {
|
|
341
|
+
if (sandboxStatus) {
|
|
342
|
+
return {
|
|
343
|
+
...sandboxStatus,
|
|
344
|
+
variant: displayedVariant,
|
|
345
|
+
};
|
|
346
|
+
}
|
|
347
|
+
// No WS status yet — construct an optimistic placeholder.
|
|
348
|
+
return {
|
|
349
|
+
variant: displayedVariant,
|
|
350
|
+
sandbox_running: true,
|
|
351
|
+
is_executing: false,
|
|
352
|
+
};
|
|
353
|
+
}, [displayedVariant, sandboxStatus]);
|
|
332
354
|
const statusColor = SANDBOX_STATUS_COLORS[aggregate];
|
|
333
355
|
const statusLabel = SANDBOX_STATUS_LABELS[aggregate];
|
|
334
356
|
// ── Loading state ──
|
|
@@ -338,7 +360,7 @@ const AgentSandboxInner = ({ onLogout, }) => {
|
|
|
338
360
|
flexDirection: 'column',
|
|
339
361
|
alignItems: 'center',
|
|
340
362
|
justifyContent: 'center',
|
|
341
|
-
height: '
|
|
363
|
+
height: '100%',
|
|
342
364
|
gap: 3,
|
|
343
365
|
}, children: [_jsx(Spinner, { size: "large" }), _jsx(Text, { sx: { color: 'fg.muted' }, children: "Launching sandbox demo\u2026" })] }));
|
|
344
366
|
}
|
|
@@ -376,7 +398,7 @@ const AgentSandboxInner = ({ onLogout, }) => {
|
|
|
376
398
|
borderRadius: '50%',
|
|
377
399
|
bg: statusColor,
|
|
378
400
|
flexShrink: 0,
|
|
379
|
-
} }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: statusLabel })] }), _jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted', mt: 1, display: 'block' }, children: ["Last switch:", ' ', lastSwitch
|
|
401
|
+
} }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: statusLabel })] }), _jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted', mt: 1, display: 'block' }, children: ["Active variant: ", displayedVariant, pendingVariant ? ' (switching...)' : ''] }), _jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted', mt: 1, display: 'block' }, children: ["Last switch:", ' ', lastSwitch
|
|
380
402
|
? `${lastSwitch.variant} at ${formatSwitchTime(lastSwitch.switchedAt)}`
|
|
381
403
|
: 'n/a'] })] }), sandboxStatus && (_jsxs(Box, { sx: {
|
|
382
404
|
mx: 2,
|
|
@@ -388,7 +410,7 @@ const AgentSandboxInner = ({ onLogout, }) => {
|
|
|
388
410
|
bg: 'canvas.default',
|
|
389
411
|
fontSize: 0,
|
|
390
412
|
fontFamily: 'mono',
|
|
391
|
-
}, children: [_jsxs(Box, { sx: { mb: 1 }, children: [_jsx(Text, { sx: { fontWeight: 600 }, children: "variant: " }), _jsx(Text, { children: sandboxStatus.variant })] }), _jsxs(Box, { sx: { mb: 1 }, children: [_jsx(Text, { sx: { fontWeight: 600 }, children: "sandbox_running: " }), _jsx(Text, { children: String(sandboxStatus.sandbox_running) })] }), _jsxs(Box, { sx: { mb: 1 }, children: [_jsx(Text, { sx: { fontWeight: 600 }, children: "is_executing: " }), _jsx(Label, { variant: sandboxStatus.is_executing ? 'accent' : 'secondary', children: String(sandboxStatus.is_executing) })] }), sandboxStatus.jupyter_url && (_jsxs(Box, { sx: { mb: 1 }, children: [_jsx(Text, { sx: { fontWeight: 600 }, children: "jupyter_url: " }), _jsx(Text, { sx: { wordBreak: 'break-all' }, children: sandboxStatus.jupyter_url })] })), sandboxStatus.error && (_jsx(Flash, { variant: "danger", sx: { mt: 1, fontSize: 0, p: 1 }, children: sandboxStatus.error }))] })), _jsx(Box, { sx: { mx: 2, mt: 2 }, children: _jsx(Button, { size: "small", variant: "danger", disabled: aggregate !== 'executing', onClick: sendInterrupt, leadingVisual: StopIcon, block: true, children: "Interrupt Execution" }) }), _jsxs(Box, { sx: {
|
|
413
|
+
}, children: [_jsxs(Box, { sx: { mb: 1 }, children: [_jsx(Text, { sx: { fontWeight: 600 }, children: "variant: " }), _jsx(Text, { children: pendingVariant ? displayedVariant : sandboxStatus.variant })] }), _jsxs(Box, { sx: { mb: 1 }, children: [_jsx(Text, { sx: { fontWeight: 600 }, children: "sandbox_running: " }), _jsx(Text, { children: String(sandboxStatus.sandbox_running) })] }), _jsxs(Box, { sx: { mb: 1 }, children: [_jsx(Text, { sx: { fontWeight: 600 }, children: "is_executing: " }), _jsx(Label, { variant: sandboxStatus.is_executing ? 'accent' : 'secondary', children: String(sandboxStatus.is_executing) })] }), sandboxStatus.jupyter_url && (_jsxs(Box, { sx: { mb: 1 }, children: [_jsx(Text, { sx: { fontWeight: 600 }, children: "jupyter_url: " }), _jsx(Text, { sx: { wordBreak: 'break-all' }, children: sandboxStatus.jupyter_url })] })), sandboxStatus.error && (_jsx(Flash, { variant: "danger", sx: { mt: 1, fontSize: 0, p: 1 }, children: sandboxStatus.error }))] })), _jsx(Box, { sx: { mx: 2, mt: 2 }, children: _jsx(Button, { size: "small", variant: "danger", disabled: aggregate !== 'executing' || isTransitionLocked, onClick: sendInterrupt, leadingVisual: StopIcon, block: true, children: "Interrupt Execution" }) }), _jsxs(Box, { sx: {
|
|
392
414
|
mx: 2,
|
|
393
415
|
mt: 2,
|
|
394
416
|
mb: 2,
|
|
@@ -408,7 +430,7 @@ const AgentSandboxInner = ({ onLogout, }) => {
|
|
|
408
430
|
display: 'flex',
|
|
409
431
|
alignItems: 'center',
|
|
410
432
|
justifyContent: 'space-between',
|
|
411
|
-
}, children: [_jsxs(Text, { sx: { fontWeight: 600, fontSize: 0 }, children: ["WebSocket Log (", wsLog.length, ")"] }), _jsx(Button, { size: "small", variant: "invisible", onClick: () => setWsLog([]), sx: { fontSize: 0, px: 1 }, children: "Clear" })] }), _jsx(Box, { sx: {
|
|
433
|
+
}, children: [_jsxs(Text, { sx: { fontWeight: 600, fontSize: 0 }, children: ["WebSocket Log (", wsLog.length, ")"] }), _jsx(Button, { size: "small", variant: "invisible", disabled: isTransitionLocked, onClick: () => setWsLog([]), sx: { fontSize: 0, px: 1 }, children: "Clear" })] }), _jsx(Box, { sx: {
|
|
412
434
|
overflow: 'auto',
|
|
413
435
|
flex: 1,
|
|
414
436
|
fontFamily: 'mono',
|
|
@@ -432,7 +454,8 @@ const AgentSandboxInner = ({ onLogout, }) => {
|
|
|
432
454
|
fontWeight: entry.direction === 'sent' ? 600 : 400,
|
|
433
455
|
}, children: [entry.direction === 'sent' ? '▲ ' : '▼ ', entry.raw] })] }, entry.id)))) })] })] }));
|
|
434
456
|
return (_jsxs(Box, { sx: {
|
|
435
|
-
height: '
|
|
457
|
+
height: '100%',
|
|
458
|
+
minHeight: 0,
|
|
436
459
|
display: 'flex',
|
|
437
460
|
flexDirection: 'column',
|
|
438
461
|
}, children: [isReconnectedAgent && (_jsx(Box, { sx: {
|
|
@@ -440,20 +463,31 @@ const AgentSandboxInner = ({ onLogout, }) => {
|
|
|
440
463
|
py: 1,
|
|
441
464
|
borderBottom: '1px solid',
|
|
442
465
|
borderColor: 'border.default',
|
|
443
|
-
}, children: _jsx(Text, { sx: { color: 'fg.muted', fontSize: 0 }, children: "Agent already running \u2014 reconnected." }) })), _jsxs(Box, { sx: { flex: 1, minHeight: 0, display: 'flex' }, children: [_jsx(Box, { sx: { flex: 1, minWidth: 0 }, children: _jsx(Chat, { protocol: "vercel-ai", baseUrl: agentBaseUrl, agentId: agentId, authToken: chatAuthToken, title: "Sandbox Agent", placeholder: "Ask the agent to write and run code\u2026", showHeader: true, showNewChatButton: true, showClearButton: false, showTokenUsage: true, autoFocus: true, height: "100%", runtimeId: agentId, historyEndpoint: `${agentBaseUrl}/api/v1/history`, headerActions: _jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsxs(SegmentedControl, { "aria-label": "Sandbox variant", size: "small", onChange: index =>
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
466
|
+
}, children: _jsx(Text, { sx: { color: 'fg.muted', fontSize: 0 }, children: "Agent already running \u2014 reconnected." }) })), _jsxs(Box, { sx: { flex: 1, minHeight: 0, display: 'flex' }, children: [_jsx(Box, { sx: { flex: 1, minWidth: 0 }, children: _jsxs(Box, { sx: { position: 'relative', height: '100%' }, children: [_jsx(Chat, { protocol: "vercel-ai", baseUrl: agentBaseUrl, agentId: agentId, authToken: chatAuthToken, title: "Sandbox Agent", brandIcon: _jsx(TerminalIcon, { size: 16 }), placeholder: "Ask the agent to write and run code\u2026", showHeader: true, showNewChatButton: true, showClearButton: false, showTokenUsage: true, autoFocus: true, height: "100%", runtimeId: agentId, historyEndpoint: `${agentBaseUrl}/api/v1/history`, headerActions: _jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsxs(SegmentedControl, { "aria-label": "Sandbox variant", size: "small", onChange: index => {
|
|
467
|
+
if (isTransitionLocked)
|
|
468
|
+
return;
|
|
469
|
+
void switchVariant(index === 0 ? 'eval' : 'jupyter');
|
|
470
|
+
}, children: [_jsx(SegmentedControl.Button, { selected: displayedVariant === 'eval', leadingIcon: TerminalIcon, disabled: isTransitionLocked, children: "eval" }), _jsx(SegmentedControl.Button, { selected: displayedVariant === 'jupyter', leadingIcon: CodeIcon, disabled: isTransitionLocked, children: "jupyter" })] }), variantSwitching && _jsx(Spinner, { size: "small" })] }), suggestions: [
|
|
471
|
+
{
|
|
472
|
+
title: 'Run some Python',
|
|
473
|
+
message: 'Write a Python script that computes the first 20 Fibonacci numbers and prints them.',
|
|
474
|
+
},
|
|
475
|
+
{
|
|
476
|
+
title: 'Generate a plot',
|
|
477
|
+
message: 'Write Python code to generate a matplotlib bar chart of the top 5 programming languages by popularity, and save it to chart.png.',
|
|
478
|
+
},
|
|
479
|
+
{
|
|
480
|
+
title: 'Long-running task',
|
|
481
|
+
message: 'Write Python code that counts from 1 to 30 with a 1-second sleep between each number, printing each one.',
|
|
482
|
+
},
|
|
483
|
+
], submitOnSuggestionClick: true, sandboxStatusData: chatSandboxStatus }), isTransitionLocked && (_jsx(Box, { sx: {
|
|
484
|
+
position: 'absolute',
|
|
485
|
+
inset: 0,
|
|
486
|
+
bg: 'canvas.default',
|
|
487
|
+
opacity: 0.35,
|
|
488
|
+
zIndex: 2,
|
|
489
|
+
cursor: 'wait',
|
|
490
|
+
} }))] }) }), sidebar] })] }));
|
|
457
491
|
};
|
|
458
492
|
// ─── Auth wrapper ──────────────────────────────────────────────────────────
|
|
459
493
|
const syncTokenToIamStore = (newToken) => {
|
|
@@ -462,7 +496,7 @@ const syncTokenToIamStore = (newToken) => {
|
|
|
462
496
|
});
|
|
463
497
|
};
|
|
464
498
|
const AgentSandboxExample = () => {
|
|
465
|
-
const { token,
|
|
499
|
+
const { token, clearAuth } = useSimpleAuthStore();
|
|
466
500
|
const hasSynced = useRef(false);
|
|
467
501
|
useEffect(() => {
|
|
468
502
|
if (token && !hasSynced.current) {
|
|
@@ -470,11 +504,6 @@ const AgentSandboxExample = () => {
|
|
|
470
504
|
syncTokenToIamStore(token);
|
|
471
505
|
}
|
|
472
506
|
}, [token]);
|
|
473
|
-
const handleSignIn = useCallback((newToken, handle) => {
|
|
474
|
-
setAuth(newToken, handle);
|
|
475
|
-
hasSynced.current = true;
|
|
476
|
-
syncTokenToIamStore(newToken);
|
|
477
|
-
}, [setAuth]);
|
|
478
507
|
const handleLogout = useCallback(() => {
|
|
479
508
|
clearAuth();
|
|
480
509
|
hasSynced.current = false;
|
|
@@ -483,7 +512,7 @@ const AgentSandboxExample = () => {
|
|
|
483
512
|
});
|
|
484
513
|
}, [clearAuth]);
|
|
485
514
|
if (!token) {
|
|
486
|
-
return (_jsx(ThemedProvider, { children: _jsx(
|
|
515
|
+
return (_jsx(ThemedProvider, { children: _jsx(AuthRequiredView, {}) }));
|
|
487
516
|
}
|
|
488
517
|
return (_jsx(QueryClientProvider, { client: queryClient, children: _jsx(ThemedProvider, { children: _jsx(AgentSandboxInner, { onLogout: handleLogout }) }) }));
|
|
489
518
|
};
|