@datalayer/agent-runtimes 1.0.19 → 1.0.21
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 +11 -3
- package/lib/AgentNode.js +141 -40
- package/lib/App.js +2 -2
- package/lib/agent-node/AgentNodeGallery.js +188 -25
- package/lib/api/runtimes/runtimes.d.ts +57 -0
- package/lib/api/runtimes/runtimes.js +55 -1
- package/lib/chat/Chat.d.ts +1 -1
- package/lib/chat/Chat.js +2 -2
- package/lib/chat/base/ChatBase.js +50 -13
- package/lib/chat/document/EphemeralDocument.d.ts +5 -1
- package/lib/chat/document/EphemeralDocument.js +7 -5
- 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 +5 -1
- package/lib/chat/notebook/EphemeralNotebook.js +9 -6
- 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/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/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 +12 -0
- package/lib/types/models.d.ts +5 -0
- package/lib/types/stream.d.ts +58 -1
- package/package.json +4 -4
- package/scripts/codegen/__pycache__/versioning.cpython-313.pyc +0 -0
- 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/README.md
CHANGED
|
@@ -171,6 +171,13 @@ pip install -e ".[chat]" # chat-related extras
|
|
|
171
171
|
pip install -e ".[docs]" # docs build dependencies
|
|
172
172
|
```
|
|
173
173
|
|
|
174
|
+
For deterministic installs in CI (and to avoid resolver backtracking), use the
|
|
175
|
+
version constraints file:
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
pip install -c constraints/py313.txt -e .
|
|
179
|
+
```
|
|
180
|
+
|
|
174
181
|
### Run
|
|
175
182
|
|
|
176
183
|
```bash
|
|
@@ -262,10 +269,11 @@ make examples:prod DATALAYER_URL=https://prod2.datalayer.run
|
|
|
262
269
|
If you are developing against a local Plane (`plane local`), use:
|
|
263
270
|
|
|
264
271
|
```bash
|
|
265
|
-
make
|
|
272
|
+
make example-local
|
|
266
273
|
```
|
|
267
274
|
|
|
268
|
-
This points each `DATALAYER_*_URL`
|
|
275
|
+
This points each `DATALAYER_*_URL` (and its `VITE_*` frontend counterpart, so
|
|
276
|
+
both http and ws traffic stay local) at the matching localhost port exposed by
|
|
269
277
|
`plane local` (see `services/plane/datalayer_plane/sbin/local.sh`):
|
|
270
278
|
|
|
271
279
|
| Variable | Default port |
|
|
@@ -286,7 +294,7 @@ This points each `DATALAYER_*_URL` at the matching localhost port exposed by
|
|
|
286
294
|
Override any port on the command line, e.g.:
|
|
287
295
|
|
|
288
296
|
```bash
|
|
289
|
-
PLANE_LOCAL_IAM_URL=http://localhost:9701 make
|
|
297
|
+
PLANE_LOCAL_IAM_URL=http://localhost:9701 make example-local
|
|
290
298
|
```
|
|
291
299
|
|
|
292
300
|
On the main page, you’ll find an example gallery (cards) that break things down into practical building blocks:
|
package/lib/AgentNode.js
CHANGED
|
@@ -3,13 +3,15 @@ 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 { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
|
6
|
+
import { useCallback, useEffect, useMemo, useRef, useState, } from 'react';
|
|
7
7
|
import { useQueryClient } from '@tanstack/react-query';
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
8
|
+
import { AiAgentIcon, AlienIcon } from '@datalayer/icons-react';
|
|
9
|
+
import { DatalayerLogoText, DatalayerThemeProvider, getColorPalette, getLogoColors, setupPrimerPortals, themeConfigs, } from '@datalayer/primer-addons';
|
|
10
|
+
import { AppearanceMenu } from '@datalayer/primer-addons/lib/components/appearance';
|
|
11
|
+
import { ActionList, ActionMenu, Box, Button, Heading, Label, PageHeader, PageLayout, Text, } from '@primer/react';
|
|
12
|
+
import { CommentIcon, HomeIcon, KeyAsteriskIcon, LockIcon, MoonIcon, PeopleIcon, PersonIcon, GearIcon, SignOutIcon, } from '@primer/octicons-react';
|
|
12
13
|
import { SignInSimple } from '@datalayer/core/lib/views/iam';
|
|
14
|
+
import { UserAvatar } from '@datalayer/core/lib/components/avatars';
|
|
13
15
|
import { UserBadge } from '@datalayer/core/lib/views/profile';
|
|
14
16
|
import { useSimpleAuthStore } from '@datalayer/core/lib/views/otel';
|
|
15
17
|
import { useIAMStore } from '@datalayer/core/lib/state';
|
|
@@ -141,21 +143,33 @@ const DEFAULT_CONFIGURATION = {
|
|
|
141
143
|
* but assembled exclusively from core building blocks so agent-runtimes does
|
|
142
144
|
* not pull in the `ui` package.
|
|
143
145
|
*/
|
|
144
|
-
function AgentNodeProfileView({ token, onTokenExpired, }) {
|
|
146
|
+
function AgentNodeProfileView({ token, onTokenExpired, avatarFallbackBackground, avatarFallbackForeground, }) {
|
|
145
147
|
const user = useIAMStore(state => state.user);
|
|
148
|
+
const hasRealAvatar = (url) => {
|
|
149
|
+
if (!url) {
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
if (url.startsWith('https://www.gravatar.com/avatar')) {
|
|
153
|
+
return false;
|
|
154
|
+
}
|
|
155
|
+
return true;
|
|
156
|
+
};
|
|
146
157
|
const display = useMemo(() => {
|
|
147
158
|
if (!user)
|
|
148
159
|
return null;
|
|
149
160
|
const u = user;
|
|
150
|
-
const displayName =
|
|
151
|
-
u.
|
|
152
|
-
u.
|
|
153
|
-
u.
|
|
154
|
-
u.
|
|
155
|
-
|
|
161
|
+
const displayName = u.display_name ||
|
|
162
|
+
u.displayName ||
|
|
163
|
+
u.profile?.display_name ||
|
|
164
|
+
u.profile?.displayName ||
|
|
165
|
+
u.full_name ||
|
|
166
|
+
u.fullName ||
|
|
167
|
+
[u.first_name, u.last_name].filter(Boolean).join(' ').trim() ||
|
|
168
|
+
'';
|
|
156
169
|
const username = u.username || u.handle || (u.email ? String(u.email).split('@')[0] : '');
|
|
170
|
+
const headingDisplayName = displayName || username || u.email || 'Datalayer user';
|
|
157
171
|
const initials = u.initials ||
|
|
158
|
-
String(
|
|
172
|
+
String(headingDisplayName)
|
|
159
173
|
.split(/\s+/)
|
|
160
174
|
.filter(Boolean)
|
|
161
175
|
.slice(0, 2)
|
|
@@ -165,6 +179,7 @@ function AgentNodeProfileView({ token, onTokenExpired, }) {
|
|
|
165
179
|
id: String(u.id || u.uid || ''),
|
|
166
180
|
username,
|
|
167
181
|
displayName,
|
|
182
|
+
headingDisplayName,
|
|
168
183
|
initials,
|
|
169
184
|
origin: String(u.origin || 'datalayer'),
|
|
170
185
|
handle: u.handle ? `@${u.handle}` : '',
|
|
@@ -181,22 +196,42 @@ function AgentNodeProfileView({ token, onTokenExpired, }) {
|
|
|
181
196
|
display: 'flex',
|
|
182
197
|
flexDirection: 'column',
|
|
183
198
|
gap: 3,
|
|
184
|
-
}, children: !token ? (_jsx(Text, { sx: { color: 'fg.muted' }, children: "Sign in to view your profile." })) : !display ? (_jsx(Text, { sx: { color: 'fg.muted' }, children: "Loading profile\u2026" })) : (_jsxs(_Fragment, { children: [_jsx(Heading, { sx: { fontSize: 2, mb: 2 }, children: "
|
|
185
|
-
width: 72,
|
|
186
|
-
height: 72,
|
|
187
|
-
borderRadius: '50%',
|
|
188
|
-
bg: 'canvas.subtle',
|
|
189
|
-
display: 'inline-flex',
|
|
190
|
-
alignItems: 'center',
|
|
191
|
-
justifyContent: 'center',
|
|
192
|
-
color: 'fg.muted',
|
|
193
|
-
}, children: _jsx(PersonIcon, { size: 30 }) })), _jsxs(Box, { sx: { display: 'flex', flexDirection: 'column' }, children: [_jsx(Heading, { sx: { fontSize: 3, mb: 1 }, children: display.displayName }), display.handle && (_jsx(Text, { sx: { color: 'fg.muted' }, children: display.handle })), display.email && (_jsx(Text, { sx: { color: 'fg.muted', fontSize: 1 }, children: display.email }))] })] }), display.id && (_jsx(Box, { sx: { mt: 2 }, children: _jsx(Label, { size: "large", variant: "secondary", children: display.id }) })), _jsxs(Box, { sx: {
|
|
199
|
+
}, children: !token ? (_jsx(Text, { sx: { color: 'fg.muted' }, children: "Sign in to view your profile." })) : !display ? (_jsx(Text, { sx: { color: 'fg.muted' }, children: "Loading profile\u2026" })) : (_jsxs(_Fragment, { children: [_jsx(Heading, { sx: { fontSize: 2, mb: 2 }, children: "Profile" }), _jsxs(Box, { sx: {
|
|
194
200
|
display: 'grid',
|
|
195
|
-
gridTemplateColumns:
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
201
|
+
gridTemplateColumns: [
|
|
202
|
+
'1fr',
|
|
203
|
+
null,
|
|
204
|
+
'minmax(280px, 1fr) minmax(320px, 2fr)',
|
|
205
|
+
],
|
|
206
|
+
gap: 4,
|
|
207
|
+
alignItems: 'start',
|
|
208
|
+
}, children: [_jsxs(Box, { sx: {
|
|
209
|
+
border: '1px solid',
|
|
210
|
+
borderColor: 'border.default',
|
|
211
|
+
borderRadius: 2,
|
|
212
|
+
p: 3,
|
|
213
|
+
display: 'flex',
|
|
214
|
+
flexDirection: 'column',
|
|
215
|
+
gap: 3,
|
|
216
|
+
}, children: [_jsx(Box, { sx: { textAlign: 'left' }, children: _jsx(UserBadge, { token: token, variant: "small", onTokenExpired: onTokenExpired }) }), _jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 3 }, children: [hasRealAvatar(display.avatarUrl) ? (_jsx(UserAvatar, { avatarUrl: display.avatarUrl, size: 72, square: false })) : (_jsx(Box, { sx: {
|
|
217
|
+
width: 72,
|
|
218
|
+
height: 72,
|
|
219
|
+
borderRadius: '50%',
|
|
220
|
+
bg: avatarFallbackBackground || 'accent.subtle',
|
|
221
|
+
display: 'flex',
|
|
222
|
+
alignItems: 'center',
|
|
223
|
+
justifyContent: 'center',
|
|
224
|
+
'--datalayer-icon-fg': avatarFallbackForeground || 'accent.fg',
|
|
225
|
+
}, children: _jsx(AlienIcon, { size: 34, themed: true, colormode: true }) })), _jsxs(Box, { sx: { display: 'flex', flexDirection: 'column' }, children: [_jsx(Heading, { sx: { fontSize: 3, mb: 1 }, children: display.headingDisplayName }), display.handle && (_jsx(Text, { sx: { color: 'fg.muted' }, children: display.handle }))] })] }), display.id && (_jsx(Box, { children: _jsx(Label, { size: "large", variant: "secondary", children: display.id }) }))] }), _jsxs(Box, { sx: {
|
|
226
|
+
border: '1px solid',
|
|
227
|
+
borderColor: 'border.default',
|
|
228
|
+
borderRadius: 2,
|
|
229
|
+
p: 3,
|
|
230
|
+
display: 'grid',
|
|
231
|
+
gridTemplateColumns: '1fr 2fr',
|
|
232
|
+
rowGap: 2,
|
|
233
|
+
columnGap: 3,
|
|
234
|
+
}, children: [_jsx(Text, { sx: { fontWeight: 'bold' }, children: "Username" }), _jsx(Text, { children: display.username || '-' }), _jsx(Text, { sx: { fontWeight: 'bold' }, children: "Display name" }), _jsx(Text, { children: display.displayName || '-' }), _jsx(Text, { sx: { fontWeight: 'bold' }, children: "Email" }), _jsx(Text, { children: display.email || '-' }), _jsx(Text, { sx: { fontWeight: 'bold' }, children: "Initials" }), _jsx(Text, { children: display.initials || '-' }), _jsx(Text, { sx: { fontWeight: 'bold' }, children: "Origin" }), _jsx(Text, { children: display.origin || '-' }), _jsx(Text, { sx: { fontWeight: 'bold' }, children: "Roles" }), _jsx(Box, { sx: { display: 'flex', gap: 1, flexWrap: 'wrap' }, children: display.roles.length > 0 ? (display.roles.map(role => (_jsx(Label, { size: "small", variant: "secondary", children: role }, role)))) : (_jsx(Text, { children: "-" })) })] })] })] })) }));
|
|
200
235
|
}
|
|
201
236
|
export function AgentNode() {
|
|
202
237
|
const { token, setAuth, clearAuth } = useSimpleAuthStore();
|
|
@@ -205,6 +240,8 @@ export function AgentNode() {
|
|
|
205
240
|
const queryClient = useQueryClient();
|
|
206
241
|
const iamUser = useIAMStore(state => state.user);
|
|
207
242
|
const { colorMode, theme: themeVariant } = useAgentNodeThemeStore();
|
|
243
|
+
const setColorMode = useAgentNodeThemeStore(state => state.setColorMode);
|
|
244
|
+
const setTheme = useAgentNodeThemeStore(state => state.setTheme);
|
|
208
245
|
const cfg = themeConfigs[themeVariant];
|
|
209
246
|
const logoColors = getLogoColors(themeVariant, colorMode);
|
|
210
247
|
const resolvedMode = colorMode === 'auto'
|
|
@@ -215,6 +252,7 @@ export function AgentNode() {
|
|
|
215
252
|
: colorMode === 'dark'
|
|
216
253
|
? 'dark'
|
|
217
254
|
: 'light';
|
|
255
|
+
const avatarPalette = getColorPalette(themeVariant, resolvedMode);
|
|
218
256
|
const authGradient = cfg.cardGradient[resolvedMode];
|
|
219
257
|
const [step, setStep] = useState('auth');
|
|
220
258
|
const [selectedAgentId, setSelectedAgentId] = useState('default');
|
|
@@ -282,13 +320,21 @@ export function AgentNode() {
|
|
|
282
320
|
}
|
|
283
321
|
: undefined,
|
|
284
322
|
};
|
|
285
|
-
}, [
|
|
323
|
+
}, [
|
|
324
|
+
configuration.collaboration_document_uid,
|
|
325
|
+
token,
|
|
326
|
+
collaborationDocumentUser,
|
|
327
|
+
]);
|
|
286
328
|
const [inferenceProvider, setInferenceProvider] = useState('datalayer');
|
|
287
329
|
const [inferenceModels, setInferenceModels] = useState([]);
|
|
288
330
|
const [inferenceDefaultModel, setInferenceDefaultModel] = useState(null);
|
|
289
331
|
const [configurationLoaded, setConfigurationLoaded] = useState(false);
|
|
332
|
+
const [isActiveAgentRunning, setIsActiveAgentRunning] = useState(false);
|
|
290
333
|
const chatRestoreAttemptRef = useRef('');
|
|
291
|
-
const hasActiveAgent = Boolean(String(configuration.active_agent_id || '').trim())
|
|
334
|
+
const hasActiveAgent = Boolean(String(configuration.active_agent_id || '').trim()) &&
|
|
335
|
+
isActiveAgentRunning;
|
|
336
|
+
const isSaasOnlyChat = configuration.chat_access_mode === 'saas_only' ||
|
|
337
|
+
configuration.deployment_target === 'aws';
|
|
292
338
|
// ── Local sandbox runtime override for the ephemeral surfaces ─────────────
|
|
293
339
|
// In the node-local webapp the agent's Jupyter sandbox is a LOCAL server, not
|
|
294
340
|
// a Kubernetes pod resolvable by `pod_name`, so the ephemeral notebook and
|
|
@@ -437,7 +483,9 @@ export function AgentNode() {
|
|
|
437
483
|
};
|
|
438
484
|
}, [step, selectedAgentId, token]);
|
|
439
485
|
const chatTitle = agentSpecInfo?.name || 'Agent Node Chat';
|
|
440
|
-
const chatDescription = agentSpecInfo?.welcomeMessage ||
|
|
486
|
+
const chatDescription = agentSpecInfo?.welcomeMessage ||
|
|
487
|
+
agentSpecInfo?.description ||
|
|
488
|
+
'Node-local chat';
|
|
441
489
|
const chatSuggestions = agentSpecInfo?.suggestions && agentSpecInfo.suggestions.length > 0
|
|
442
490
|
? agentSpecInfo.suggestions.map(s => ({ title: s, message: s }))
|
|
443
491
|
: undefined;
|
|
@@ -698,6 +746,11 @@ export function AgentNode() {
|
|
|
698
746
|
setStep('auth');
|
|
699
747
|
}
|
|
700
748
|
}, [token, step]);
|
|
749
|
+
useEffect(() => {
|
|
750
|
+
if (!token || !String(configuration.active_agent_id || '').trim()) {
|
|
751
|
+
setIsActiveAgentRunning(false);
|
|
752
|
+
}
|
|
753
|
+
}, [token, configuration.active_agent_id]);
|
|
701
754
|
useEffect(() => {
|
|
702
755
|
if (!token || !configurationLoaded) {
|
|
703
756
|
return;
|
|
@@ -733,20 +786,30 @@ export function AgentNode() {
|
|
|
733
786
|
const id = String(agent?.agent_id || agent?.id || '').trim();
|
|
734
787
|
return id === activeAgentId;
|
|
735
788
|
});
|
|
789
|
+
setIsActiveAgentRunning(running);
|
|
736
790
|
if (running) {
|
|
737
791
|
setSelectedAgentId(activeAgentId);
|
|
738
792
|
setConfiguration(prev => prev.mode === 'private' ? prev : { ...prev, mode: 'private' });
|
|
739
793
|
setStep('chat');
|
|
740
794
|
}
|
|
795
|
+
else if (selectedAgentId === activeAgentId) {
|
|
796
|
+
setSelectedAgentId('default');
|
|
797
|
+
}
|
|
741
798
|
}
|
|
742
799
|
catch {
|
|
800
|
+
setIsActiveAgentRunning(false);
|
|
743
801
|
// Best-effort restore only.
|
|
744
802
|
}
|
|
745
803
|
})();
|
|
746
804
|
return () => {
|
|
747
805
|
cancelled = true;
|
|
748
806
|
};
|
|
749
|
-
}, [
|
|
807
|
+
}, [
|
|
808
|
+
token,
|
|
809
|
+
configurationLoaded,
|
|
810
|
+
configuration.active_agent_id,
|
|
811
|
+
selectedAgentId,
|
|
812
|
+
]);
|
|
750
813
|
useEffect(() => {
|
|
751
814
|
// If a persisted session is already authenticated on first load,
|
|
752
815
|
// skip the auth screen and land on the agents gallery.
|
|
@@ -764,6 +827,11 @@ export function AgentNode() {
|
|
|
764
827
|
setStep('gallery');
|
|
765
828
|
}
|
|
766
829
|
}, [step, hasActiveAgent]);
|
|
830
|
+
useEffect(() => {
|
|
831
|
+
if (step === 'chat' && isSaasOnlyChat) {
|
|
832
|
+
setStep('gallery');
|
|
833
|
+
}
|
|
834
|
+
}, [step, isSaasOnlyChat]);
|
|
767
835
|
const handleSignIn = (newToken, handle) => {
|
|
768
836
|
setAutoBootstrapDisabled(false);
|
|
769
837
|
setDisableAutoBootstrap(false);
|
|
@@ -860,7 +928,7 @@ export function AgentNode() {
|
|
|
860
928
|
if (nextStep === 'gallery')
|
|
861
929
|
return true;
|
|
862
930
|
if (nextStep === 'chat') {
|
|
863
|
-
return configuration.mode === 'private' && hasActiveAgent;
|
|
931
|
+
return (configuration.mode === 'private' && hasActiveAgent && !isSaasOnlyChat);
|
|
864
932
|
}
|
|
865
933
|
return true;
|
|
866
934
|
};
|
|
@@ -888,7 +956,7 @@ export function AgentNode() {
|
|
|
888
956
|
gap: 2,
|
|
889
957
|
fontSize: 2,
|
|
890
958
|
lineHeight: '22px',
|
|
891
|
-
}, children: [token && (_jsxs(_Fragment, { children: [_jsx(StepEntry, { entryStep: "chat", label: "Chat", leadingVisual: CommentIcon }), _jsx(StepEntry, { entryStep: "gallery", label: "Agents", leadingVisual:
|
|
959
|
+
}, children: [token && (_jsxs(_Fragment, { children: [_jsx(StepEntry, { entryStep: "chat", label: "Chat", leadingVisual: CommentIcon }), _jsx(StepEntry, { entryStep: "gallery", label: "Agents", leadingVisual: AiAgentIcon }), _jsx(StepEntry, { entryStep: "config", label: "Configuration", leadingVisual: GearIcon })] })), !token ? null : (_jsxs(_Fragment, { children: [_jsx(StepEntry, { entryStep: "profile", label: "Profile", leadingVisual: PersonIcon }), _jsx(Button, { size: "small", variant: "invisible", onClick: handleSignOut, leadingVisual: SignOutIcon, sx: { color: 'fg.default' }, children: "Sign out" })] })), _jsx(AppearanceMenu, { colorMode: colorMode, themeVariant: themeVariant, onColorModeChange: setColorMode, onThemeChange: nextTheme => setTheme(nextTheme, false), shape: "circle" })] }) })] }) }), _jsxs(PageLayout.Content, { children: [_jsx(Box, { "aria-live": "polite", sx: {
|
|
892
960
|
position: 'fixed',
|
|
893
961
|
top: 0,
|
|
894
962
|
left: 0,
|
|
@@ -975,7 +1043,12 @@ export function AgentNode() {
|
|
|
975
1043
|
display: 'flex',
|
|
976
1044
|
flexDirection: 'column',
|
|
977
1045
|
gap: 3,
|
|
978
|
-
}, children: [_jsxs(
|
|
1046
|
+
}, children: [_jsxs(Box, { sx: {
|
|
1047
|
+
border: '1px solid',
|
|
1048
|
+
borderColor: 'border.default',
|
|
1049
|
+
borderRadius: 2,
|
|
1050
|
+
p: 3,
|
|
1051
|
+
}, children: [_jsx(Heading, { sx: { fontSize: 2, m: 0, mb: 2 }, children: "Mode" }), _jsx(Box, { sx: {
|
|
979
1052
|
display: 'grid',
|
|
980
1053
|
gridTemplateColumns: 'repeat(3, 1fr)',
|
|
981
1054
|
gap: 3,
|
|
@@ -1015,7 +1088,12 @@ export function AgentNode() {
|
|
|
1015
1088
|
? cfg.brandColor
|
|
1016
1089
|
: 'fg.default',
|
|
1017
1090
|
}, children: [_jsx(Icon, { size: 20 }), _jsx(Text, { sx: { fontWeight: 'bold' }, children: card.name })] }), _jsx(Text, { sx: { color: 'fg.muted', fontSize: 1 }, children: card.description })] }, card.mode));
|
|
1018
|
-
}) })] }), _jsxs(
|
|
1091
|
+
}) })] }), _jsxs(Box, { sx: {
|
|
1092
|
+
border: '1px solid',
|
|
1093
|
+
borderColor: 'border.default',
|
|
1094
|
+
borderRadius: 2,
|
|
1095
|
+
p: 3,
|
|
1096
|
+
}, children: [_jsx(Heading, { sx: { fontSize: 2, m: 0, mb: 2 }, children: "Inference" }), _jsx(Text, { sx: { color: 'fg.muted', fontSize: 1, mb: 2 }, children: "Used inference provider for newly launched agent sessions." }), _jsxs(Box, { sx: {
|
|
1019
1097
|
display: 'flex',
|
|
1020
1098
|
gap: 2,
|
|
1021
1099
|
flexWrap: 'wrap',
|
|
@@ -1033,14 +1111,30 @@ export function AgentNode() {
|
|
|
1033
1111
|
display: 'flex',
|
|
1034
1112
|
flexDirection: 'column',
|
|
1035
1113
|
gap: 1,
|
|
1036
|
-
}, children: [_jsx(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: "Bedrock Anthropic model" }), inferenceModels.length === 0 ? (_jsx(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: "No model list available." })) : (_jsxs(ActionMenu, { children: [_jsx(ActionMenu.Button, { children: inferenceDefaultModel || inferenceModels[0] }), _jsx(ActionMenu.Overlay, { width: "large", children: _jsx(ActionList, { selectionVariant: "single", children: inferenceModels.map(model => (_jsx(ActionList.Item, { selected: inferenceDefaultModel === model, inactiveText: "Selection is locked", children: model }, model))) }) })] }))] }))] }), iamUser ? (
|
|
1114
|
+
}, children: [_jsx(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: "Bedrock Anthropic model" }), inferenceModels.length === 0 ? (_jsx(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: "No model list available." })) : (_jsxs(ActionMenu, { children: [_jsx(ActionMenu.Button, { children: inferenceDefaultModel || inferenceModels[0] }), _jsx(ActionMenu.Overlay, { width: "large", children: _jsx(ActionList, { selectionVariant: "single", children: inferenceModels.map(model => (_jsx(ActionList.Item, { selected: inferenceDefaultModel === model, inactiveText: "Selection is locked", children: model }, model))) }) })] }))] }))] }), iamUser ? (_jsxs(Box, { sx: {
|
|
1115
|
+
border: '1px solid',
|
|
1116
|
+
borderColor: 'border.default',
|
|
1117
|
+
borderRadius: 2,
|
|
1118
|
+
p: 3,
|
|
1119
|
+
}, children: [_jsx(Heading, { sx: { fontSize: 2, m: 0, mb: 2 }, children: "Billing Entity" }), _jsx(BillingEntitySelect, { value: configuration.billing_entity_uid || '', onChange: handleBillingEntityChange, onSelectedAccountChange: handleSelectedAccountChange, onAccountsResolved: handleAccountsResolved })] })) : (_jsxs(Box, { sx: {
|
|
1120
|
+
border: '1px solid',
|
|
1121
|
+
borderColor: 'border.default',
|
|
1122
|
+
borderRadius: 2,
|
|
1123
|
+
p: 3,
|
|
1124
|
+
}, children: [_jsx(Heading, { sx: { fontSize: 2, m: 0, mb: 2 }, children: "Billing Entity" }), _jsx(Text, { sx: { color: 'fg.muted', fontSize: 1 }, children: "Loading billing entitys..." })] }))] }), _jsx(Box, { sx: {
|
|
1037
1125
|
display: 'flex',
|
|
1038
1126
|
flexDirection: 'column',
|
|
1039
1127
|
gap: 2,
|
|
1040
|
-
}, children:
|
|
1128
|
+
}, children: _jsxs(Box, { sx: {
|
|
1129
|
+
border: '1px solid',
|
|
1130
|
+
borderColor: 'border.default',
|
|
1131
|
+
borderRadius: 2,
|
|
1132
|
+
p: 3,
|
|
1133
|
+
}, children: [_jsx(Heading, { sx: { fontSize: 2, m: 0, mb: 2 }, children: "Share" }), _jsx(ShareAccessComponent, { isOpen: true, displayMode: "inline", requestUrl: `${AGENT_RUNTIMES_BASE_URL}/api/v1/agent-node/sharing`, resourceLabel: "Agent Node", resourceName: "this Agent Node", onClose: handleSharingInlineClose })] }) })] }), error && _jsx(Text, { sx: { color: 'danger.fg' }, children: error }), _jsx(Box, { sx: { display: 'flex', justifyContent: 'flex-end' }, children: _jsx(Button, { variant: "primary", onClick: saveConfiguration, disabled: isSaving, children: isSaving ? 'Saving...' : 'Save' }) })] })), step === 'profile' && (_jsx(AgentNodeProfileView, { token: token, onTokenExpired: handleSignOut, avatarFallbackBackground: avatarPalette.bgAlt, avatarFallbackForeground: avatarPalette.primary })), step === 'gallery' && (_jsx(AgentNodeGallery, { baseUrl: AGENT_RUNTIMES_BASE_URL, token: token, activeAgentId: configuration.active_agent_id, onLaunchError: message => {
|
|
1041
1134
|
showBanner('error', message);
|
|
1042
1135
|
}, onLaunched: agentId => {
|
|
1043
1136
|
setSelectedAgentId(agentId);
|
|
1137
|
+
setIsActiveAgentRunning(true);
|
|
1044
1138
|
const nextConfiguration = {
|
|
1045
1139
|
...configuration,
|
|
1046
1140
|
active_agent_id: agentId,
|
|
@@ -1058,9 +1152,16 @@ export function AgentNode() {
|
|
|
1058
1152
|
}).catch(() => {
|
|
1059
1153
|
// Best-effort persistence; local state already switched.
|
|
1060
1154
|
});
|
|
1061
|
-
|
|
1155
|
+
if (isSaasOnlyChat) {
|
|
1156
|
+
showBanner('info', 'This node is configured for SaaS chat. Open Agent Nodes in Datalayer to chat with it.');
|
|
1157
|
+
setStep('gallery');
|
|
1158
|
+
}
|
|
1159
|
+
else {
|
|
1160
|
+
setStep('chat');
|
|
1161
|
+
}
|
|
1062
1162
|
}, onTerminated: () => {
|
|
1063
1163
|
setSelectedAgentId('default');
|
|
1164
|
+
setIsActiveAgentRunning(false);
|
|
1064
1165
|
setConfiguration(prev => ({
|
|
1065
1166
|
...prev,
|
|
1066
1167
|
active_agent_id: undefined,
|
|
@@ -1071,6 +1172,6 @@ export function AgentNode() {
|
|
|
1071
1172
|
borderColor: 'border.default',
|
|
1072
1173
|
borderRadius: 2,
|
|
1073
1174
|
overflow: 'hidden',
|
|
1074
|
-
}, children: _jsx(Chat, { protocol: "ag-ui", baseUrl: AGENT_RUNTIMES_BASE_URL, agentId: selectedAgentId, title: chatTitle, placeholder: "Send a message...", description: chatDescription, suggestions: chatSuggestions, submitOnSuggestionClick: true, showHeader: true, height: '70vh', showModelSelector: true, showToolsMenu: true, showSkillsMenu: true, showTokenUsage: true, showInformation: true, autoFocus: true, enableEphemeralNotebook: true, enableEphemeralDocument: true, initialEphemeralSurfaceMode: "notebook", runtimeId: selectedAgentId, ephemeralRuntimeOverride: sandboxRuntimeOverride, kernelEnvironmentName: sandboxEnvironmentName, ephemeralNotebookCollaborationProvider: ephemeralNotebookCollaborationProvider, ephemeralNotebookCollaborationDocumentId: ephemeralCollaborationDocumentId, ephemeralDocumentCollaboration: ephemeralDocumentCollaboration, historyEndpoint: `${AGENT_RUNTIMES_BASE_URL}/api/v1/history` }) }))] })] }) }) }));
|
|
1175
|
+
}, children: isSaasOnlyChat ? (_jsxs(Box, { sx: { p: 4 }, children: [_jsx(Heading, { sx: { fontSize: 2, mb: 2 }, children: "Chat From SaaS" }), _jsx(Text, { sx: { color: 'fg.muted' }, children: "This Agent Node deployment is configured for SaaS-only chat. Use the Datalayer Agent Nodes view to open chat sessions over the runtimes tunnel." })] })) : (_jsx(Chat, { protocol: "ag-ui", baseUrl: AGENT_RUNTIMES_BASE_URL, agentId: selectedAgentId, title: chatTitle, placeholder: "Send a message...", description: chatDescription, suggestions: chatSuggestions, submitOnSuggestionClick: true, showHeader: true, height: '70vh', showModelSelector: true, showToolsMenu: true, showSkillsMenu: true, showTokenUsage: true, showInformation: true, autoFocus: true, enableEphemeralNotebook: true, enableEphemeralDocument: true, initialEphemeralSurfaceMode: "notebook", runtimeId: selectedAgentId, ephemeralRuntimeOverride: sandboxRuntimeOverride, kernelEnvironmentName: sandboxEnvironmentName, themeVariant: themeVariant, colorMode: colorMode, ephemeralNotebookCollaborationProvider: ephemeralNotebookCollaborationProvider, ephemeralNotebookCollaborationDocumentId: ephemeralCollaborationDocumentId, ephemeralDocumentCollaboration: ephemeralDocumentCollaboration, historyEndpoint: `${AGENT_RUNTIMES_BASE_URL}/api/v1/history` })) }))] })] }) }) }));
|
|
1075
1176
|
}
|
|
1076
1177
|
export default AgentNode;
|
package/lib/App.js
CHANGED
|
@@ -4,7 +4,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
4
4
|
* Distributed under the terms of the Modified BSD License.
|
|
5
5
|
*/
|
|
6
6
|
import { useJupyter, JupyterReactTheme } from '@datalayer/jupyter-react';
|
|
7
|
-
import {
|
|
7
|
+
import { CellExample } from './examples/CellExample';
|
|
8
8
|
import { JupyterNotebookExample } from './examples/NotebookExample';
|
|
9
9
|
import './App.css';
|
|
10
10
|
export function App() {
|
|
@@ -13,6 +13,6 @@ export function App() {
|
|
|
13
13
|
jupyterServerToken: '60c1661cc408f978c309d04157af55c9588ff9557c9380e4fb50785750703da6',
|
|
14
14
|
startDefaultKernel: true,
|
|
15
15
|
});
|
|
16
|
-
return (_jsxs(JupyterReactTheme, { children: [serviceManager && _jsx(
|
|
16
|
+
return (_jsxs(JupyterReactTheme, { children: [serviceManager && _jsx(CellExample, { serviceManager: serviceManager }), serviceManager && (_jsx(JupyterNotebookExample, { serviceManager: serviceManager }))] }));
|
|
17
17
|
}
|
|
18
18
|
export default App;
|