@datalayer/agent-runtimes 1.0.18 → 1.0.20
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 +14 -6
- package/lib/AgentNode.js +567 -67
- package/lib/App.js +2 -2
- package/lib/agent-node/AgentNodeGallery.d.ts +80 -0
- package/lib/agent-node/AgentNodeGallery.js +627 -0
- package/lib/agent-notebook-main.js +0 -1
- package/lib/api/runtimes/runtimes.d.ts +57 -0
- package/lib/api/runtimes/runtimes.js +55 -1
- package/lib/chat/Chat.d.ts +14 -1
- package/lib/chat/Chat.js +22 -7
- package/lib/chat/base/ChatBase.js +86 -23
- package/lib/chat/document/EphemeralDocument.d.ts +49 -1
- package/lib/chat/document/EphemeralDocument.js +141 -15
- package/lib/chat/header/ChatHeaderBase.d.ts +3 -1
- package/lib/chat/header/ChatHeaderBase.js +5 -3
- package/lib/chat/messages/ChatMessageList.d.ts +19 -0
- package/lib/chat/messages/ChatMessageList.js +180 -9
- package/lib/chat/notebook/EphemeralNotebook.d.ts +40 -1
- package/lib/chat/notebook/EphemeralNotebook.js +49 -13
- package/lib/chat/prompt/InputPrompt.js +1 -1
- package/lib/chat/tools/SubagentActivity.d.ts +20 -0
- package/lib/chat/tools/SubagentActivity.js +154 -0
- package/lib/chat/tools/index.d.ts +1 -0
- package/lib/chat/tools/index.js +1 -0
- package/lib/chat/usage/TokenUsageBar.js +3 -3
- package/lib/client/AgentRuntimesClient.d.ts +5 -0
- package/lib/client/AgentsMixin.js +3 -1
- package/lib/client/mixins/RuntimesMixin.d.ts +12 -0
- package/lib/client/mixins/RuntimesMixin.js +24 -1
- package/lib/components/AgentSummary.d.ts +1 -0
- package/lib/components/AgentSummary.js +66 -10
- package/lib/components/runtimes/RuntimePickerBase.js +64 -29
- package/lib/components/runtimes/RuntimePickerCell.js +1 -1
- package/lib/components/runtimes/RuntimePickerNotebook.js +1 -1
- package/lib/components/runtimes/RuntimeSimplePicker.js +3 -2
- package/lib/components/runtimes/RuntimeUtils.js +2 -2
- package/lib/context/GraphFlowChart.js +1 -1
- package/lib/context/TokenUsageChart.js +1 -1
- package/lib/context/TurnGraphChart.js +2 -2
- package/lib/examples/A2UiAgentExample.js +4 -4
- package/lib/examples/A2UiComponentsGalleryExample.js +3 -3
- package/lib/examples/A2UiContactCardExample.js +3 -3
- package/lib/examples/A2UiRestaurantExample.js +2 -2
- package/lib/examples/A2UiViewerExample.js +3 -3
- package/lib/examples/AgUiAgenticExample.js +3 -3
- package/lib/examples/AgUiBackendToolRenderingExample.js +2 -2
- package/lib/examples/AgUiHaikuGenUiExample.js +3 -3
- package/lib/examples/AgUiHumanInTheLoopExample.js +5 -5
- package/lib/examples/AgUiSharedStateExample.js +3 -3
- package/lib/examples/AgUiToolsBasedGenUiExample.js +7 -5
- package/lib/examples/AgentCheckpointsExample.js +6 -5
- package/lib/examples/{AgentSandboxExample.d.ts → AgentCodeSandboxExample.d.ts} +4 -4
- package/lib/examples/{AgentSandboxExample.js → AgentCodeSandboxExample.js} +10 -9
- package/lib/examples/AgentCodeSandboxesExample.js +2 -2
- package/lib/examples/AgentCodemodeExample.js +3 -3
- package/lib/examples/AgentCompactionExample.d.ts +12 -0
- package/lib/examples/AgentCompactionExample.js +244 -0
- package/lib/examples/AgentEvalsExample.js +10 -20
- package/lib/examples/AgentGuardrailsExample.js +2 -2
- package/lib/examples/AgentHooksExample.js +1 -1
- package/lib/examples/AgentInferenceProviderExample.js +6 -8
- package/lib/examples/AgentLoopExample.js +3 -3
- package/lib/examples/AgentMCPExample.js +3 -3
- package/lib/examples/AgentMemoryExample.d.ts +4 -2
- package/lib/examples/AgentMemoryExample.js +93 -10
- package/lib/examples/AgentMonitoringExample.js +2 -2
- package/lib/examples/AgentNotificationsExample.js +1 -1
- package/lib/examples/AgentOtelExample.d.ts +2 -3
- package/lib/examples/AgentOtelExample.js +7 -12
- package/lib/examples/AgentOutputsExample.js +5 -5
- package/lib/examples/AgentParametersExample.js +3 -3
- package/lib/examples/AgentSkillsExample.js +4 -4
- package/lib/examples/AgentSubagentsExample.d.ts +2 -2
- package/lib/examples/AgentSubagentsExample.js +43 -34
- package/lib/examples/AgentToolApprovalsExample.js +1 -1
- package/lib/examples/AgentTriggersExample.js +9 -11
- package/lib/examples/AgentspecsExample.js +13 -5
- package/lib/examples/CellExample.d.ts +6 -0
- package/lib/examples/CellExample.js +84 -0
- package/lib/examples/ChatCustomExample.js +1 -1
- package/lib/examples/ChatExample.js +1 -1
- package/lib/examples/ChatStandaloneExample.js +2 -2
- package/lib/examples/HomeExample.js +29 -28
- package/lib/examples/Lexical2Example.js +2 -2
- package/lib/examples/LexicalAgentExample.js +1 -1
- package/lib/examples/LexicalAgentSidebarExample.js +2 -2
- package/lib/examples/NotebookAgentSidebarExample.d.ts +1 -1
- package/lib/examples/NotebookAgentSidebarExample.js +5 -4
- package/lib/examples/NotebookCollaborationExample.js +3 -3
- package/lib/examples/NotebookExample.js +2 -2
- package/lib/examples/components/ExampleWrapper.js +5 -0
- package/lib/examples/components/Header.js +2 -2
- package/lib/examples/components/HeaderControls.js +1 -1
- package/lib/examples/components/LexicalEditor.js +1 -1
- package/lib/examples/components/MainContent.js +1 -1
- package/lib/examples/components/MockFileBrowser.js +8 -8
- package/lib/examples/components/TimeTravel.js +1 -1
- package/lib/examples/components/haiku/HaikuDisplay.js +2 -2
- package/lib/examples/example-selector.js +4 -3
- package/lib/examples/hooks/useExampleAgentRuntime.js +11 -1
- package/lib/examples/hooks/useExampleAgentRuntimes.d.ts +7 -0
- package/lib/examples/hooks/useExampleAgentRuntimes.js +82 -0
- package/lib/examples/index.d.ts +2 -1
- package/lib/examples/index.js +2 -1
- package/lib/examples/main.js +359 -46
- package/lib/examples/utils/agentSummaryStore.d.ts +17 -0
- package/lib/examples/utils/themedProvider.js +32 -2
- package/lib/examples/utils/useExampleAgentRuntimesUrl.js +2 -1
- package/lib/examples2/NotebookMutationsKernel.js +6 -3
- package/lib/examples2/NotebookMutationsServiceManager.js +6 -3
- package/lib/examples2/ReactRouterExample.js +5 -5
- package/lib/examples2/main.js +38 -0
- package/lib/hooks/useAIAgentsWebSocket.js +35 -0
- package/lib/hooks/useAgentRuntimes.d.ts +22 -0
- package/lib/hooks/useAgentRuntimes.js +192 -5
- package/lib/hooks/useCheckpoints.js +2 -2
- package/lib/hooks/useToolApprovals.d.ts +10 -4
- package/lib/hooks/useToolApprovals.js +11 -5
- package/lib/identity/AgentIdentity.js +1 -2
- package/lib/models/Runtime.d.ts +10 -8
- package/lib/models/RuntimeDTO.d.ts +5 -3
- package/lib/models/RuntimeDTO.js +3 -3
- package/lib/runtimes/actions.js +3 -1
- package/lib/runtimes/apis.d.ts +7 -0
- package/lib/shims/primerAddonsBox.d.ts +1 -0
- package/lib/shims/primerAddonsBox.js +7 -0
- package/lib/specs/agents/agents.d.ts +51 -0
- package/lib/specs/agents/agents.js +3389 -94
- package/lib/specs/models.d.ts +2 -0
- package/lib/specs/models.js +37 -0
- package/lib/stores/agentRuntimeStore.d.ts +32 -1
- package/lib/stores/agentRuntimeStore.js +65 -1
- package/lib/stores/index.d.ts +1 -1
- package/lib/stores/index.js +1 -1
- package/lib/types/agents.d.ts +9 -3
- package/lib/types/agentspecs.d.ts +2 -0
- package/lib/types/chat.d.ts +83 -0
- package/lib/types/models.d.ts +5 -0
- package/lib/types/stream.d.ts +58 -1
- package/package.json +6 -5
- package/scripts/codegen/generate_agents.py +7 -0
- package/scripts/codegen/generate_models.py +22 -9
- package/scripts/gen_workers.py +340 -0
- package/lib/examples/CellSimpleExample.d.ts +0 -6
- package/lib/examples/CellSimpleExample.js +0 -20
- package/scripts/codegen/__pycache__/generate_sandbox_agents.cpython-313.pyc +0 -0
|
@@ -21,7 +21,8 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
21
21
|
*/
|
|
22
22
|
import { useEffect, useMemo, useRef, useState } from 'react';
|
|
23
23
|
import { ServerConnection, ServiceManager } from '@jupyterlab/services';
|
|
24
|
-
import {
|
|
24
|
+
import { DatalayerThemeProvider, getThemeConfig, useSystemColorMode, useThemeStore, } from '@datalayer/primer-addons';
|
|
25
|
+
import { Box } from '@primer/react';
|
|
25
26
|
import { Notebook, NotebookToolbar, CellSidebarExtension, CellSidebarButton, JupyterReactTheme, notebookStore, disposeServiceManager, } from '@datalayer/jupyter-react';
|
|
26
27
|
import { useAgentsRuntimes } from '../../hooks/useAgentRuntimes';
|
|
27
28
|
import { registerSandboxServiceManager } from '../../services/sandboxServiceManagers';
|
|
@@ -54,7 +55,7 @@ const EPHEMERAL_NOTEBOOK_CONTENT = {
|
|
|
54
55
|
/**
|
|
55
56
|
* Renders an in-memory notebook backed by a sandbox kernel.
|
|
56
57
|
*/
|
|
57
|
-
export function EphemeralNotebook({ notebookId, runtimePodName, cellSidebarMargin = 120, nbformat, onNbformatChange, toolbarComponent, }) {
|
|
58
|
+
export function EphemeralNotebook({ notebookId, runtimePodName, runtimeOverride, cellSidebarMargin = 120, nbformat, onNbformatChange, toolbarComponent, themeVariant, colorMode, collaborationProvider, }) {
|
|
58
59
|
// The `nbformat` passed to the `Notebook` component MUST stay a stable
|
|
59
60
|
// reference for the lifetime of a given `notebookId`: the underlying
|
|
60
61
|
// `useNotebookModel` hook rebuilds the notebook model (and its context /
|
|
@@ -77,18 +78,36 @@ export function EphemeralNotebook({ notebookId, runtimePodName, cellSidebarMargi
|
|
|
77
78
|
// notebook must bind to exactly the runtime assigned to this agent, or to
|
|
78
79
|
// none at all (straight path).
|
|
79
80
|
const { runtimes, refetchRuntimes } = useAgentsRuntimes();
|
|
80
|
-
const
|
|
81
|
+
const podResolvedRuntime = useMemo(() => {
|
|
81
82
|
const preferredPod = String(runtimePodName || '').trim();
|
|
82
83
|
if (!preferredPod) {
|
|
83
84
|
return undefined;
|
|
84
85
|
}
|
|
85
86
|
return runtimes.find(rt => String(rt?.pod_name || '') === preferredPod);
|
|
86
87
|
}, [runtimePodName, runtimes]);
|
|
88
|
+
// An explicit endpoint override wins over the pod lookup: it lets a SaaS
|
|
89
|
+
// browser bind the kernel through the runtimes tunnel proxy (the node's
|
|
90
|
+
// Jupyter server is not directly reachable, so no pod exists in the list).
|
|
91
|
+
const selectedRuntime = useMemo(() => {
|
|
92
|
+
const overrideBaseUrl = String(runtimeOverride?.baseUrl || '').trim();
|
|
93
|
+
if (overrideBaseUrl) {
|
|
94
|
+
return {
|
|
95
|
+
url: overrideBaseUrl,
|
|
96
|
+
wsUrl: String(runtimeOverride?.wsUrl || '').trim() || undefined,
|
|
97
|
+
token: String(runtimeOverride?.token || '').trim(),
|
|
98
|
+
pod_name: String(runtimeOverride?.podName || '').trim() || 'agent-node-proxy',
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
return podResolvedRuntime;
|
|
102
|
+
}, [runtimeOverride, podResolvedRuntime]);
|
|
87
103
|
// While the assigned pod has not yet appeared in the runtimes list, poll the
|
|
88
104
|
// list quickly instead of waiting for the default (10s) refresh interval.
|
|
89
105
|
// This is what makes the "Starting notebook…" state clear promptly once the
|
|
90
|
-
// agent runtime is ready, rather than lingering for several seconds.
|
|
91
|
-
|
|
106
|
+
// agent runtime is ready, rather than lingering for several seconds. The
|
|
107
|
+
// override path binds immediately, so no polling is needed there.
|
|
108
|
+
const needsRuntimeLookup = Boolean(!runtimeOverride?.baseUrl &&
|
|
109
|
+
String(runtimePodName || '').trim() &&
|
|
110
|
+
!selectedRuntime);
|
|
92
111
|
useEffect(() => {
|
|
93
112
|
if (!needsRuntimeLookup) {
|
|
94
113
|
return;
|
|
@@ -120,9 +139,11 @@ export function EphemeralNotebook({ notebookId, runtimePodName, cellSidebarMargi
|
|
|
120
139
|
}
|
|
121
140
|
try {
|
|
122
141
|
const token = String(selectedRuntime?.token || '').trim();
|
|
142
|
+
const wsUrl = String(selectedRuntime?.wsUrl || '').trim() ||
|
|
143
|
+
baseUrl.replace(/^http/, 'ws');
|
|
123
144
|
const serverSettings = ServerConnection.makeSettings({
|
|
124
145
|
baseUrl,
|
|
125
|
-
wsUrl
|
|
146
|
+
wsUrl,
|
|
126
147
|
token,
|
|
127
148
|
appendToken: true,
|
|
128
149
|
});
|
|
@@ -155,7 +176,12 @@ export function EphemeralNotebook({ notebookId, runtimePodName, cellSidebarMargi
|
|
|
155
176
|
disposeServiceManager(manager);
|
|
156
177
|
}
|
|
157
178
|
};
|
|
158
|
-
}, [
|
|
179
|
+
}, [
|
|
180
|
+
selectedRuntime?.pod_name,
|
|
181
|
+
selectedRuntime?.url,
|
|
182
|
+
selectedRuntime?.token,
|
|
183
|
+
selectedRuntime?.wsUrl,
|
|
184
|
+
]);
|
|
159
185
|
// Bind strictly to the agent runtime sandbox; there is NO local fallback
|
|
160
186
|
// kernel. The notebook executes on the agent's runtime or shows a waiting
|
|
161
187
|
// state until the runtime is ready.
|
|
@@ -163,9 +189,17 @@ export function EphemeralNotebook({ notebookId, runtimePodName, cellSidebarMargi
|
|
|
163
189
|
const activeKernelId = runtimeKernelId;
|
|
164
190
|
const activeStartDefaultKernel = runtimeStartDefaultKernel;
|
|
165
191
|
const ToolbarComponent = toolbarComponent || NotebookToolbar;
|
|
166
|
-
const isRuntimeStarting = Boolean(String(runtimePodName || '').trim()
|
|
192
|
+
const isRuntimeStarting = Boolean((String(runtimePodName || '').trim() ||
|
|
193
|
+
String(runtimeOverride?.baseUrl || '').trim()) &&
|
|
194
|
+
!activeServiceManager);
|
|
167
195
|
useProgressTask(`ephemeral-notebook-start-${notebookId}`, isRuntimeStarting);
|
|
168
196
|
useEffect(() => {
|
|
197
|
+
// When a collaboration provider is active the shared ydoc is the single
|
|
198
|
+
// source of truth and is synced remotely; the local in-memory persistence
|
|
199
|
+
// poll would fight it, so it is disabled in that mode.
|
|
200
|
+
if (collaborationProvider) {
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
169
203
|
// Read the CURRENT live notebook model straight from the notebook store.
|
|
170
204
|
// The `NotebookAdapter` exposes `notebook` (the widget, whose `.model` is
|
|
171
205
|
// the `INotebookModel`) and `panel` (`panel.content.model`). There is NO
|
|
@@ -203,10 +237,12 @@ export function EphemeralNotebook({ notebookId, runtimePodName, cellSidebarMargi
|
|
|
203
237
|
// Resolve the active theme/color-mode exactly like the notebook editor
|
|
204
238
|
// (NotebookEditorPanel) so the notebook honours dark / branded themes
|
|
205
239
|
// instead of always rendering light.
|
|
206
|
-
const { colorMode, theme:
|
|
240
|
+
const { colorMode: storeColorMode, theme: storeThemeVariant } = useThemeStore();
|
|
241
|
+
const effectiveColorMode = colorMode ?? storeColorMode;
|
|
242
|
+
const effectiveThemeVariant = themeVariant ?? storeThemeVariant;
|
|
207
243
|
const systemMode = useSystemColorMode();
|
|
208
|
-
const themeConfig = getThemeConfig(
|
|
209
|
-
const resolvedMode =
|
|
244
|
+
const themeConfig = getThemeConfig(effectiveThemeVariant);
|
|
245
|
+
const resolvedMode = effectiveColorMode === 'auto' ? systemMode : effectiveColorMode;
|
|
210
246
|
const modeStyles = resolvedMode === 'dark'
|
|
211
247
|
? themeConfig.themeStyles.dark
|
|
212
248
|
: themeConfig.themeStyles.light;
|
|
@@ -219,7 +255,7 @@ export function EphemeralNotebook({ notebookId, runtimePodName, cellSidebarMargi
|
|
|
219
255
|
position: 'relative',
|
|
220
256
|
overflow: 'hidden',
|
|
221
257
|
bg: 'canvas.default',
|
|
222
|
-
}, children: activeServiceManager ? (_jsx(DatalayerThemeProvider, { colorMode:
|
|
258
|
+
}, children: activeServiceManager ? (_jsx(DatalayerThemeProvider, { colorMode: effectiveColorMode, theme: themeConfig.primerTheme, themeStyles: themeConfig.themeStyles, children: _jsx(JupyterReactTheme, { colormode: resolvedMode, backgroundColor: themeBackground, children: _jsx(Box, { sx: {
|
|
223
259
|
position: 'absolute',
|
|
224
260
|
inset: 0,
|
|
225
261
|
display: 'flex',
|
|
@@ -247,6 +283,6 @@ export function EphemeralNotebook({ notebookId, runtimePodName, cellSidebarMargi
|
|
|
247
283
|
flex: '1 1 auto',
|
|
248
284
|
minHeight: 0,
|
|
249
285
|
},
|
|
250
|
-
}, children: _jsx(Notebook, { nbformat: initialNbformat, id: notebookId, serviceManager: activeServiceManager, startDefaultKernel: activeStartDefaultKernel, kernelId: activeKernelId, height: "100%", cellSidebarMargin: cellSidebarMargin, extensions: extensions, Toolbar: ToolbarComponent }) }) }) })) : null }));
|
|
286
|
+
}, children: _jsx(Notebook, { nbformat: initialNbformat, id: notebookId, serviceManager: activeServiceManager, startDefaultKernel: activeStartDefaultKernel, kernelId: activeKernelId, height: "100%", cellSidebarMargin: cellSidebarMargin, extensions: extensions, Toolbar: ToolbarComponent, collaborationProvider: collaborationProvider }) }) }) })) : null }));
|
|
251
287
|
}
|
|
252
288
|
export default EphemeralNotebook;
|
|
@@ -76,7 +76,7 @@ export function InputPrompt({ variant = 'text', placeholder = 'Ask anything…',
|
|
|
76
76
|
transition: 'border-color 0.2s ease',
|
|
77
77
|
'&:focus-within': {
|
|
78
78
|
borderColor: 'accent.fg',
|
|
79
|
-
boxShadow: (t) => `0 0 0 1px ${t?.colors?.accent?.fg ?? '#
|
|
79
|
+
boxShadow: (t) => `0 0 0 1px ${t?.colors?.accent?.fg ?? '#16A085'}`,
|
|
80
80
|
},
|
|
81
81
|
}, children: [_jsx(InputPromptHeader, { children: headerContent }), variant === 'lexical' ? (_jsx(InputPromptLexical, { value: input, onChange: setInput, placeholder: placeholder, disabled: isLoading || disabled, readOnly: readOnly, onSubmit: handleSend, autoFocus: autoFocus })) : (_jsx(InputPromptText, { value: input, onChange: setInput, placeholder: placeholder, disabled: isLoading || disabled, readOnly: readOnly, onSubmit: handleSend, inputRef: inputRef })), _jsx(InputPromptFooter, { isLoading: isLoading, isKernelBusy: isKernelBusy, sendDisabled: !input.trim() || disabled || readOnly, onSend: handleSend, onStop: handleStop, rightContent: footerRightContent, children: footerContent })] }) }) }));
|
|
82
82
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Live subagent activity panel.
|
|
3
|
+
*
|
|
4
|
+
* Renders the streamed interaction timeline for a `delegate_task` tool call:
|
|
5
|
+
* text/thinking deltas, nested tool calls and results, and the final output.
|
|
6
|
+
* Events are sourced from the agent runtime store, keyed by the parent
|
|
7
|
+
* delegation tool call id.
|
|
8
|
+
*
|
|
9
|
+
* @module chat/tools/SubagentActivity
|
|
10
|
+
*/
|
|
11
|
+
import React from 'react';
|
|
12
|
+
export interface SubagentActivityProps {
|
|
13
|
+
/** Parent `delegate_task` tool call id used to look up streamed events. */
|
|
14
|
+
toolCallId: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Displays the live activity timeline for a delegated subagent run.
|
|
18
|
+
* Renders nothing until the first event for `toolCallId` arrives.
|
|
19
|
+
*/
|
|
20
|
+
export declare function SubagentActivity({ toolCallId, }: SubagentActivityProps): React.ReactElement | null;
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright (c) 2025-2026 Datalayer, Inc.
|
|
4
|
+
* Distributed under the terms of the Modified BSD License.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Live subagent activity panel.
|
|
8
|
+
*
|
|
9
|
+
* Renders the streamed interaction timeline for a `delegate_task` tool call:
|
|
10
|
+
* text/thinking deltas, nested tool calls and results, and the final output.
|
|
11
|
+
* Events are sourced from the agent runtime store, keyed by the parent
|
|
12
|
+
* delegation tool call id.
|
|
13
|
+
*
|
|
14
|
+
* @module chat/tools/SubagentActivity
|
|
15
|
+
*/
|
|
16
|
+
import { useMemo, useState } from 'react';
|
|
17
|
+
import { Text } from '@primer/react';
|
|
18
|
+
import { Box } from '@datalayer/primer-addons';
|
|
19
|
+
import { ChevronDownIcon, ChevronRightIcon, DependabotIcon, ToolsIcon, CheckCircleIcon, AlertIcon, LightBulbIcon, } from '@primer/octicons-react';
|
|
20
|
+
import { useAgentRuntimeSubagentActivity } from '../../stores/agentRuntimeStore';
|
|
21
|
+
/**
|
|
22
|
+
* Collapse the ordered event stream into render segments, merging consecutive
|
|
23
|
+
* text/thinking deltas into single blocks.
|
|
24
|
+
*/
|
|
25
|
+
function buildSegments(events) {
|
|
26
|
+
const segments = [];
|
|
27
|
+
for (const event of events) {
|
|
28
|
+
const phase = event.phase;
|
|
29
|
+
if (phase === 'text' || phase === 'thinking') {
|
|
30
|
+
const kind = phase;
|
|
31
|
+
const last = segments[segments.length - 1];
|
|
32
|
+
if (last && last.kind === kind) {
|
|
33
|
+
last.text = (last.text ?? '') + (event.text ?? '');
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
segments.push({ kind, text: event.text ?? '' });
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
else if (phase === 'tool_call') {
|
|
40
|
+
segments.push({
|
|
41
|
+
kind: 'tool_call',
|
|
42
|
+
toolName: event.toolName,
|
|
43
|
+
toolArgs: event.toolArgs,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
else if (phase === 'tool_result') {
|
|
47
|
+
segments.push({
|
|
48
|
+
kind: 'tool_result',
|
|
49
|
+
toolName: event.toolName,
|
|
50
|
+
result: event.result,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
else if (phase === 'error') {
|
|
54
|
+
segments.push({ kind: 'error', error: event.error });
|
|
55
|
+
}
|
|
56
|
+
// `start` and `end` phases are represented by header/status, not segments.
|
|
57
|
+
}
|
|
58
|
+
return segments;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Displays the live activity timeline for a delegated subagent run.
|
|
62
|
+
* Renders nothing until the first event for `toolCallId` arrives.
|
|
63
|
+
*/
|
|
64
|
+
export function SubagentActivity({ toolCallId, }) {
|
|
65
|
+
const events = useAgentRuntimeSubagentActivity(toolCallId);
|
|
66
|
+
const [expanded, setExpanded] = useState(true);
|
|
67
|
+
const subagentName = useMemo(() => {
|
|
68
|
+
for (const event of events) {
|
|
69
|
+
if (event.subagentName)
|
|
70
|
+
return event.subagentName;
|
|
71
|
+
}
|
|
72
|
+
return 'subagent';
|
|
73
|
+
}, [events]);
|
|
74
|
+
const isDone = useMemo(() => events.some(e => e.phase === 'end' || e.phase === 'error'), [events]);
|
|
75
|
+
const hasError = useMemo(() => events.some(e => e.phase === 'error'), [events]);
|
|
76
|
+
const segments = useMemo(() => buildSegments(events), [events]);
|
|
77
|
+
if (events.length === 0) {
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
const StatusIcon = hasError
|
|
81
|
+
? AlertIcon
|
|
82
|
+
: isDone
|
|
83
|
+
? CheckCircleIcon
|
|
84
|
+
: DependabotIcon;
|
|
85
|
+
const statusColor = hasError
|
|
86
|
+
? 'danger.fg'
|
|
87
|
+
: isDone
|
|
88
|
+
? 'success.fg'
|
|
89
|
+
: 'accent.fg';
|
|
90
|
+
return (_jsxs(Box, { sx: {
|
|
91
|
+
mt: 1,
|
|
92
|
+
ml: 2,
|
|
93
|
+
borderLeft: '2px solid',
|
|
94
|
+
borderColor: 'border.muted',
|
|
95
|
+
pl: 2,
|
|
96
|
+
}, children: [_jsxs(Box, { as: "button", onClick: () => setExpanded(prev => !prev), sx: {
|
|
97
|
+
display: 'flex',
|
|
98
|
+
alignItems: 'center',
|
|
99
|
+
gap: 1,
|
|
100
|
+
width: '100%',
|
|
101
|
+
border: 'none',
|
|
102
|
+
background: 'transparent',
|
|
103
|
+
cursor: 'pointer',
|
|
104
|
+
p: 0,
|
|
105
|
+
color: 'fg.muted',
|
|
106
|
+
textAlign: 'left',
|
|
107
|
+
}, children: [expanded ? (_jsx(ChevronDownIcon, { size: 12 })) : (_jsx(ChevronRightIcon, { size: 12 })), _jsx(Box, { sx: { color: statusColor, display: 'flex' }, children: _jsx(StatusIcon, { size: 14 }) }), _jsx(Text, { sx: { fontSize: 0, fontWeight: 'bold', color: 'fg.default' }, children: subagentName }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: hasError ? 'failed' : isDone ? 'done' : 'working…' })] }), expanded && (_jsx(Box, { sx: { mt: 1, display: 'flex', flexDirection: 'column', gap: 1 }, children: segments.map((segment, index) => (_jsx(SubagentSegmentView, { segment: segment }, index))) }))] }));
|
|
108
|
+
}
|
|
109
|
+
function SubagentSegmentView({ segment, }) {
|
|
110
|
+
switch (segment.kind) {
|
|
111
|
+
case 'text':
|
|
112
|
+
if (!segment.text)
|
|
113
|
+
return null;
|
|
114
|
+
return (_jsx(Text, { sx: {
|
|
115
|
+
fontSize: 0,
|
|
116
|
+
color: 'fg.default',
|
|
117
|
+
whiteSpace: 'pre-wrap',
|
|
118
|
+
wordBreak: 'break-word',
|
|
119
|
+
}, children: segment.text }));
|
|
120
|
+
case 'thinking':
|
|
121
|
+
if (!segment.text)
|
|
122
|
+
return null;
|
|
123
|
+
return (_jsxs(Box, { sx: { display: 'flex', gap: 1, color: 'fg.muted' }, children: [_jsx(Box, { sx: { mt: '2px', flexShrink: 0 }, children: _jsx(LightBulbIcon, { size: 12 }) }), _jsx(Text, { sx: {
|
|
124
|
+
fontSize: 0,
|
|
125
|
+
fontStyle: 'italic',
|
|
126
|
+
whiteSpace: 'pre-wrap',
|
|
127
|
+
wordBreak: 'break-word',
|
|
128
|
+
}, children: segment.text })] }));
|
|
129
|
+
case 'tool_call':
|
|
130
|
+
return (_jsxs(Box, { sx: { display: 'flex', gap: 1, color: 'fg.muted' }, children: [_jsx(Box, { sx: { mt: '2px', flexShrink: 0 }, children: _jsx(ToolsIcon, { size: 12 }) }), _jsxs(Box, { sx: { minWidth: 0 }, children: [_jsx(Text, { sx: { fontSize: 0, fontWeight: 'bold' }, children: segment.toolName ?? 'tool' }), segment.toolArgs && Object.keys(segment.toolArgs).length > 0 && (_jsx(Text, { as: "pre", sx: {
|
|
131
|
+
fontSize: 0,
|
|
132
|
+
fontFamily: 'mono',
|
|
133
|
+
m: 0,
|
|
134
|
+
mt: '2px',
|
|
135
|
+
whiteSpace: 'pre-wrap',
|
|
136
|
+
wordBreak: 'break-word',
|
|
137
|
+
color: 'fg.muted',
|
|
138
|
+
}, children: JSON.stringify(segment.toolArgs) }))] })] }));
|
|
139
|
+
case 'tool_result':
|
|
140
|
+
if (!segment.result)
|
|
141
|
+
return null;
|
|
142
|
+
return (_jsxs(Box, { sx: { display: 'flex', gap: 1, color: 'fg.muted' }, children: [_jsx(Box, { sx: { mt: '2px', flexShrink: 0, color: 'success.fg' }, children: _jsx(CheckCircleIcon, { size: 12 }) }), _jsx(Text, { as: "pre", sx: {
|
|
143
|
+
fontSize: 0,
|
|
144
|
+
fontFamily: 'mono',
|
|
145
|
+
m: 0,
|
|
146
|
+
whiteSpace: 'pre-wrap',
|
|
147
|
+
wordBreak: 'break-word',
|
|
148
|
+
}, children: segment.result })] }));
|
|
149
|
+
case 'error':
|
|
150
|
+
return (_jsxs(Box, { sx: { display: 'flex', gap: 1, color: 'danger.fg' }, children: [_jsx(Box, { sx: { mt: '2px', flexShrink: 0 }, children: _jsx(AlertIcon, { size: 12 }) }), _jsx(Text, { sx: { fontSize: 0 }, children: segment.error ?? 'Subagent failed' })] }));
|
|
151
|
+
default:
|
|
152
|
+
return null;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
@@ -4,5 +4,6 @@
|
|
|
4
4
|
* @module chat/tools
|
|
5
5
|
*/
|
|
6
6
|
export { ToolCallDisplay, type ToolCallDisplayProps, type ErrorType, } from './ToolCallDisplay';
|
|
7
|
+
export { SubagentActivity, type SubagentActivityProps, } from './SubagentActivity';
|
|
7
8
|
export { ToolApprovalBanner, type ToolApprovalBannerProps, type PendingApproval, } from './ToolApprovalBanner';
|
|
8
9
|
export { ToolApprovalDialog, useToolApprovalDialog, type ToolApprovalDialogProps, } from './ToolApprovalDialog';
|
package/lib/chat/tools/index.js
CHANGED
|
@@ -8,5 +8,6 @@
|
|
|
8
8
|
* @module chat/tools
|
|
9
9
|
*/
|
|
10
10
|
export { ToolCallDisplay, } from './ToolCallDisplay';
|
|
11
|
+
export { SubagentActivity, } from './SubagentActivity';
|
|
11
12
|
export { ToolApprovalBanner, } from './ToolApprovalBanner';
|
|
12
13
|
export { ToolApprovalDialog, useToolApprovalDialog, } from './ToolApprovalDialog';
|
|
@@ -53,7 +53,7 @@ export function TokenUsageBar({ agentUsage, padding }) {
|
|
|
53
53
|
const colorMap = {
|
|
54
54
|
'System Prompts': '#8250df',
|
|
55
55
|
'Tool Definitions': '#bf8700',
|
|
56
|
-
'User Messages': '#
|
|
56
|
+
'User Messages': '#16A085',
|
|
57
57
|
'Assistant Messages': '#1a7f37',
|
|
58
58
|
'Tool Usage': '#cf222e',
|
|
59
59
|
};
|
|
@@ -86,7 +86,7 @@ export function TokenUsageBar({ agentUsage, padding }) {
|
|
|
86
86
|
categories.push({
|
|
87
87
|
name: 'Messages',
|
|
88
88
|
value: messageTokens,
|
|
89
|
-
color: '#
|
|
89
|
+
color: '#16A085',
|
|
90
90
|
});
|
|
91
91
|
}
|
|
92
92
|
const toolResultTokens = (agentUsage.toolCallTokens || 0) + (agentUsage.toolReturnTokens || 0);
|
|
@@ -99,7 +99,7 @@ export function TokenUsageBar({ agentUsage, padding }) {
|
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
101
|
// Tiny filled pie chart options
|
|
102
|
-
const pieColor = pct > 90 ? '#cf222e' : pct > 70 ? '#bf8700' : '#
|
|
102
|
+
const pieColor = pct > 90 ? '#cf222e' : pct > 70 ? '#bf8700' : '#16A085';
|
|
103
103
|
const freeSliceColor = 'var(--bgColor-muted, #f6f8fa)';
|
|
104
104
|
const freeSliceOverlayColor = 'var(--borderColor-default, #d1d9e0)';
|
|
105
105
|
const miniPieOption = {
|
|
@@ -13,6 +13,7 @@ import type { SpaceDTO, UpdateSpaceRequest } from '../models/SpaceDTO';
|
|
|
13
13
|
import type { NotebookDTO } from '../models/NotebookDTO';
|
|
14
14
|
import type { LexicalDTO } from '../models/LexicalDTO';
|
|
15
15
|
import type { ProjectDTO, ProjectDefaultItems } from '../models/ProjectDTO';
|
|
16
|
+
import type { RuntimeMemory, ListRuntimeMemoriesOptions } from '../api/runtimes/runtimes';
|
|
16
17
|
declare const AgentRuntimesClientWithMixins: {
|
|
17
18
|
new (...args: any[]): {
|
|
18
19
|
getMySpaces(): Promise<SpaceDTO[]>;
|
|
@@ -54,6 +55,8 @@ declare const AgentRuntimesClientWithMixins: {
|
|
|
54
55
|
listRuntimes(): Promise<RuntimeDTO[]>;
|
|
55
56
|
getRuntime(podName: string): Promise<RuntimeDTO>;
|
|
56
57
|
deleteRuntime(podName: string): Promise<void>;
|
|
58
|
+
listRuntimeMemories(options?: ListRuntimeMemoriesOptions): Promise<RuntimeMemory[]>;
|
|
59
|
+
getRuntimeMemory(memoryId: string): Promise<RuntimeMemory>;
|
|
57
60
|
terminateAllRuntimes(): Promise<PromiseSettledResult<void>[]>;
|
|
58
61
|
createSnapshot(podName: string, name: string, description: string, stop?: boolean): Promise<CodeSandboxSnapshotDTO>;
|
|
59
62
|
listSnapshots(): Promise<CodeSandboxSnapshotDTO[]>;
|
|
@@ -86,6 +89,8 @@ export interface AgentRuntimesClient extends DatalayerCoreClient {
|
|
|
86
89
|
ensureRuntime(environmentName?: string, creditsLimit?: number, waitForReady?: boolean, maxWaitTime?: number, reuseExisting?: boolean, snapshotId?: string): Promise<RuntimeDTO>;
|
|
87
90
|
createRuntime(environmentName: string, type: 'notebook' | 'terminal' | 'job', givenName: string, minutesLimit: number, fromSnapshotId?: string): Promise<RuntimeDTO>;
|
|
88
91
|
listRuntimes(): Promise<RuntimeDTO[]>;
|
|
92
|
+
listRuntimeMemories(options?: ListRuntimeMemoriesOptions): Promise<RuntimeMemory[]>;
|
|
93
|
+
getRuntimeMemory(memoryId: string): Promise<RuntimeMemory>;
|
|
89
94
|
getRuntime(podName: string): Promise<RuntimeDTO>;
|
|
90
95
|
deleteRuntime(podName: string): Promise<void>;
|
|
91
96
|
terminateAllRuntimes(): Promise<PromiseSettledResult<void>[]>;
|
|
@@ -339,7 +339,9 @@ export function AgentsMixin(Base) {
|
|
|
339
339
|
method: 'POST',
|
|
340
340
|
token,
|
|
341
341
|
body: {
|
|
342
|
-
|
|
342
|
+
environment: {
|
|
343
|
+
name: data.environmentName || 'ai-agents-env',
|
|
344
|
+
},
|
|
343
345
|
given_name: data.givenName || 'Agent',
|
|
344
346
|
credits_limit: data.creditsLimit || 10,
|
|
345
347
|
type: data.type || 'notebook',
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { RuntimeMemory, ListRuntimeMemoriesOptions } from '../../api/runtimes/runtimes';
|
|
1
2
|
import type { Constructor } from '@datalayer/core/lib/client/utils/mixins';
|
|
2
3
|
import { EnvironmentDTO } from '../../models/EnvironmentDTO';
|
|
3
4
|
import { RuntimeDTO } from '../../models/RuntimeDTO';
|
|
@@ -53,6 +54,17 @@ export declare function RuntimesMixin<TBase extends Constructor>(Base: TBase): {
|
|
|
53
54
|
* @param podName - Runtime pod name
|
|
54
55
|
*/
|
|
55
56
|
deleteRuntime(podName: string): Promise<void>;
|
|
57
|
+
/**
|
|
58
|
+
* List persisted memories for the authenticated caller.
|
|
59
|
+
*
|
|
60
|
+
* Backend scoping rules apply: non-admin callers are limited to their own
|
|
61
|
+
* personal account.
|
|
62
|
+
*/
|
|
63
|
+
listRuntimeMemories(options?: ListRuntimeMemoriesOptions): Promise<RuntimeMemory[]>;
|
|
64
|
+
/**
|
|
65
|
+
* Fetch one persisted memory by id.
|
|
66
|
+
*/
|
|
67
|
+
getRuntimeMemory(memoryId: string): Promise<RuntimeMemory>;
|
|
56
68
|
/**
|
|
57
69
|
* Terminate all runtimes.
|
|
58
70
|
* Lists all runtimes and deletes them in parallel.
|
|
@@ -69,7 +69,9 @@ export function RuntimesMixin(Base) {
|
|
|
69
69
|
const runtimesUrl = this.getRuntimesUrl();
|
|
70
70
|
const creditsLimit = this.calculateCreditsFromMinutes(minutesLimit, env.burningRate);
|
|
71
71
|
const data = {
|
|
72
|
-
|
|
72
|
+
environment: {
|
|
73
|
+
name: environmentName,
|
|
74
|
+
},
|
|
73
75
|
type,
|
|
74
76
|
given_name: givenName,
|
|
75
77
|
credits_limit: creditsLimit,
|
|
@@ -113,6 +115,27 @@ export function RuntimesMixin(Base) {
|
|
|
113
115
|
const runtimesUrl = this.getRuntimesUrl();
|
|
114
116
|
await runtimes.deleteRuntime(token, podName, runtimesUrl);
|
|
115
117
|
}
|
|
118
|
+
/**
|
|
119
|
+
* List persisted memories for the authenticated caller.
|
|
120
|
+
*
|
|
121
|
+
* Backend scoping rules apply: non-admin callers are limited to their own
|
|
122
|
+
* personal account.
|
|
123
|
+
*/
|
|
124
|
+
async listRuntimeMemories(options = {}) {
|
|
125
|
+
const token = this.getToken();
|
|
126
|
+
const runtimesUrl = this.getRuntimesUrl();
|
|
127
|
+
const response = await runtimes.listRuntimeMemories(token, options, runtimesUrl);
|
|
128
|
+
return response.memories;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Fetch one persisted memory by id.
|
|
132
|
+
*/
|
|
133
|
+
async getRuntimeMemory(memoryId) {
|
|
134
|
+
const token = this.getToken();
|
|
135
|
+
const runtimesUrl = this.getRuntimesUrl();
|
|
136
|
+
const response = await runtimes.getRuntimeMemory(token, memoryId, runtimesUrl);
|
|
137
|
+
return response.memory;
|
|
138
|
+
}
|
|
116
139
|
/**
|
|
117
140
|
* Terminate all runtimes.
|
|
118
141
|
* Lists all runtimes and deletes them in parallel.
|
|
@@ -3,9 +3,10 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
3
3
|
* Copyright (c) 2025-2026 Datalayer, Inc.
|
|
4
4
|
* Distributed under the terms of the Modified BSD License.
|
|
5
5
|
*/
|
|
6
|
-
import { useState } from 'react';
|
|
6
|
+
import { useEffect, useRef, useState } from 'react';
|
|
7
7
|
import { Spinner } from '@primer/react';
|
|
8
8
|
import { Box } from '@datalayer/primer-addons';
|
|
9
|
+
import { strip } from '@datalayer/core/lib/utils';
|
|
9
10
|
/**
|
|
10
11
|
* Statuses that represent an agent actively being created/started. The spinner
|
|
11
12
|
* only shows for these; app-navigation states ("selected", "switching") and
|
|
@@ -19,20 +20,61 @@ const CREATING_STATUSES = new Set([
|
|
|
19
20
|
'pending',
|
|
20
21
|
'resuming',
|
|
21
22
|
]);
|
|
23
|
+
const MAX_AGENT_NAME_LENGTH = 32;
|
|
24
|
+
const toSandboxStatusUrl = (value) => {
|
|
25
|
+
const raw = String(value || '').trim();
|
|
26
|
+
if (!raw) {
|
|
27
|
+
return undefined;
|
|
28
|
+
}
|
|
29
|
+
try {
|
|
30
|
+
const parsed = new URL(raw);
|
|
31
|
+
parsed.pathname = `${parsed.pathname.replace(/\/$/, '')}/api`;
|
|
32
|
+
return parsed.toString();
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
const normalized = raw.replace(/\/$/, '');
|
|
36
|
+
return normalized.endsWith('/api') ? normalized : `${normalized}/api`;
|
|
37
|
+
}
|
|
38
|
+
};
|
|
22
39
|
/**
|
|
23
40
|
* Compact agent summary badge with a hover overlay for details.
|
|
24
41
|
*/
|
|
25
42
|
export const AgentSummary = ({ summary, title = 'Active Agent', }) => {
|
|
26
43
|
const [isHovering, setIsHovering] = useState(false);
|
|
27
|
-
const
|
|
44
|
+
const closeTimerRef = useRef(null);
|
|
45
|
+
const clearCloseTimer = () => {
|
|
46
|
+
if (closeTimerRef.current !== null) {
|
|
47
|
+
window.clearTimeout(closeTimerRef.current);
|
|
48
|
+
closeTimerRef.current = null;
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
const handleMouseEnter = () => {
|
|
52
|
+
clearCloseTimer();
|
|
53
|
+
setIsHovering(true);
|
|
54
|
+
};
|
|
55
|
+
const handleMouseLeave = () => {
|
|
56
|
+
clearCloseTimer();
|
|
57
|
+
closeTimerRef.current = window.setTimeout(() => {
|
|
58
|
+
setIsHovering(false);
|
|
59
|
+
closeTimerRef.current = null;
|
|
60
|
+
}, 300);
|
|
61
|
+
};
|
|
62
|
+
useEffect(() => {
|
|
63
|
+
return () => {
|
|
64
|
+
clearCloseTimer();
|
|
65
|
+
};
|
|
66
|
+
}, []);
|
|
67
|
+
// Agent status is served by the agent-runtimes API server.
|
|
68
|
+
const apiBase = summary?.baseUrl
|
|
28
69
|
? (() => {
|
|
29
70
|
const normalized = summary.baseUrl.replace(/\/$/, '');
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
return `${normalized}/api/v1/runtime/status`;
|
|
71
|
+
return normalized.endsWith('/api/v1')
|
|
72
|
+
? normalized
|
|
73
|
+
: `${normalized}/api/v1`;
|
|
34
74
|
})()
|
|
35
75
|
: undefined;
|
|
76
|
+
const agentStatusUrl = apiBase ? `${apiBase}/runtime/status` : undefined;
|
|
77
|
+
const sandboxStatusUrl = toSandboxStatusUrl(summary?.sandboxBaseUrl);
|
|
36
78
|
if (!summary) {
|
|
37
79
|
return null;
|
|
38
80
|
}
|
|
@@ -43,9 +85,17 @@ export const AgentSummary = ({ summary, title = 'Active Agent', }) => {
|
|
|
43
85
|
!summary.agentId &&
|
|
44
86
|
CREATING_STATUSES.has(normalizedStatus);
|
|
45
87
|
const hasError = Boolean(summary.error);
|
|
46
|
-
|
|
88
|
+
// The agent is optional: some examples run only a code sandbox. Show the
|
|
89
|
+
// agent status when there is an agent (or one is being created).
|
|
90
|
+
const hasAgent = Boolean(summary.agentId) || isCreating;
|
|
91
|
+
const shortAgentName = strip(summary.agentName, MAX_AGENT_NAME_LENGTH);
|
|
92
|
+
const badgeLabel = `${summary.agentName} · ${summary.location}`;
|
|
93
|
+
const badgeLabelShort = `${shortAgentName} · ${summary.location}`;
|
|
94
|
+
return (_jsxs(Box, { sx: { position: 'relative' }, onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave, children: [_jsxs(Box, { as: "button", type: "button", title: badgeLabel, sx: {
|
|
47
95
|
px: 2,
|
|
48
96
|
py: '6px',
|
|
97
|
+
maxWidth: 280,
|
|
98
|
+
minWidth: 0,
|
|
49
99
|
border: '1px solid',
|
|
50
100
|
borderColor: hasError ? 'danger.emphasis' : 'border.default',
|
|
51
101
|
borderRadius: 2,
|
|
@@ -56,7 +106,13 @@ export const AgentSummary = ({ summary, title = 'Active Agent', }) => {
|
|
|
56
106
|
display: 'flex',
|
|
57
107
|
alignItems: 'center',
|
|
58
108
|
gap: 1,
|
|
59
|
-
}, children: [isCreating && _jsx(Spinner, { size: "small", sx: { width: 12, height: 12 } }), hasError && _jsx("span", { "aria-hidden": true, children: "\u26A0" }),
|
|
109
|
+
}, children: [isCreating && _jsx(Spinner, { size: "small", sx: { width: 12, height: 12 } }), hasError && _jsx("span", { "aria-hidden": true, children: "\u26A0" }), _jsx(Box, { as: "span", sx: {
|
|
110
|
+
display: 'block',
|
|
111
|
+
minWidth: 0,
|
|
112
|
+
overflow: 'hidden',
|
|
113
|
+
textOverflow: 'ellipsis',
|
|
114
|
+
whiteSpace: 'nowrap',
|
|
115
|
+
}, children: badgeLabelShort })] }), isHovering && (_jsxs(Box, { sx: {
|
|
60
116
|
position: 'absolute',
|
|
61
117
|
top: 'calc(100% + 8px)',
|
|
62
118
|
right: 0,
|
|
@@ -70,13 +126,13 @@ export const AgentSummary = ({ summary, title = 'Active Agent', }) => {
|
|
|
70
126
|
zIndex: 120,
|
|
71
127
|
fontSize: 0,
|
|
72
128
|
color: 'fg.default',
|
|
73
|
-
}, children: [_jsx(Box, { sx: { mb: 1, fontWeight: 600 }, children: title }), _jsxs(Box, { sx: { color: 'fg.muted' }, children: ["Name: ", summary.agentName] }), _jsxs(Box, { sx: { color: 'fg.muted' }, children: ["Location: ", summary.location] }), _jsxs(Box, { sx: { color: 'fg.muted' }, children: ["Spec: ", summary.specId || '—'] }), _jsxs(Box, { sx: { color: 'fg.muted' }, children: ["Status: ", isCreating ? 'creating' : summary.status || '—'] }), _jsxs(Box, { sx: { color: 'fg.muted', wordBreak: 'break-all' }, children: ["
|
|
129
|
+
}, children: [_jsx(Box, { sx: { mb: 1, fontWeight: 600 }, children: title }), _jsxs(Box, { sx: { color: 'fg.muted' }, children: ["Name: ", summary.agentName] }), _jsxs(Box, { sx: { color: 'fg.muted' }, children: ["Location: ", summary.location] }), _jsxs(Box, { sx: { color: 'fg.muted' }, children: ["Spec: ", summary.specId || '—'] }), _jsxs(Box, { sx: { color: 'fg.muted' }, children: ["Status: ", isCreating ? 'creating' : summary.status || '—'] }), _jsxs(Box, { sx: { color: 'fg.muted', wordBreak: 'break-all' }, children: ["Agent base URL: ", summary.baseUrl || '—'] }), _jsxs(Box, { sx: { color: 'fg.muted', wordBreak: 'break-all' }, children: ["Code sandbox base URL:", ' ', summary.sandboxBaseUrl ? (_jsx(Box, { as: "a", href: summary.sandboxBaseUrl, target: "_blank", rel: "noopener noreferrer", sx: { color: 'accent.fg', textDecoration: 'underline' }, children: summary.sandboxBaseUrl })) : ('—')] }), _jsxs(Box, { sx: {
|
|
74
130
|
color: 'fg.muted',
|
|
75
131
|
wordBreak: 'break-all',
|
|
76
132
|
display: 'flex',
|
|
77
133
|
alignItems: 'center',
|
|
78
134
|
gap: 1,
|
|
79
|
-
}, children: ["Agent ID:", ' ', summary.agentId ? (summary.agentId) : isCreating ? (_jsxs(_Fragment, { children: [_jsx(Spinner, { size: "small", sx: { width: 12, height: 12 } }), "Creating\u2026"] })) : ('—')] }), _jsxs(Box, { sx: { color: 'fg.muted', wordBreak: 'break-all' }, children: ["
|
|
135
|
+
}, children: ["Agent ID:", ' ', summary.agentId ? (summary.agentId) : isCreating ? (_jsxs(_Fragment, { children: [_jsx(Spinner, { size: "small", sx: { width: 12, height: 12 } }), "Creating\u2026"] })) : ('—')] }), _jsxs(Box, { sx: { color: 'fg.muted', wordBreak: 'break-all' }, children: ["Agent status:", ' ', hasAgent && agentStatusUrl ? (_jsx(Box, { as: "a", href: agentStatusUrl, target: "_blank", rel: "noopener noreferrer", sx: { color: 'accent.fg', textDecoration: 'underline' }, children: agentStatusUrl })) : ('n/a')] }), _jsxs(Box, { sx: { color: 'fg.muted', wordBreak: 'break-all' }, children: ["Code sandbox status:", ' ', sandboxStatusUrl ? (_jsx(Box, { as: "a", href: sandboxStatusUrl, target: "_blank", rel: "noopener noreferrer", sx: { color: 'accent.fg', textDecoration: 'underline' }, children: sandboxStatusUrl })) : ('n/a')] }), hasError && (_jsxs(Box, { sx: {
|
|
80
136
|
mt: 1,
|
|
81
137
|
p: 1,
|
|
82
138
|
border: '1px solid',
|