@datalayer/core 1.0.1 → 1.0.2
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/lib/api/spacer/index.d.ts +1 -2
- package/lib/api/spacer/index.js +1 -2
- package/lib/components/avatars/BoringAvatar.d.ts +3 -1
- package/lib/components/avatars/BoringAvatar.js +15 -14
- package/lib/components/avatars/BoringAvatar.stories.d.ts +2 -1
- package/lib/components/storage/ContentsBrowser.d.ts +6 -0
- package/lib/components/storage/ContentsBrowser.js +7 -8
- package/lib/hooks/index.d.ts +2 -0
- package/lib/hooks/index.js +2 -0
- package/lib/hooks/useCache.d.ts +2 -31
- package/lib/hooks/useCache.js +0 -233
- package/lib/hooks/useProjectStore.d.ts +58 -0
- package/lib/hooks/useProjectStore.js +64 -0
- package/lib/hooks/useProjects.d.ts +590 -0
- package/lib/hooks/useProjects.js +166 -0
- package/lib/index.d.ts +0 -1
- package/lib/index.js +0 -2
- package/lib/models/Page.d.ts +2 -0
- package/lib/views/iam-tokens/Tokens.js +1 -1
- package/lib/views/secrets/Secrets.js +1 -1
- package/package.json +1 -1
- package/lib/api/spacer/agentSpaces.d.ts +0 -193
- package/lib/api/spacer/agentSpaces.js +0 -127
- package/lib/theme/DatalayerTheme.d.ts +0 -52
- package/lib/theme/DatalayerTheme.js +0 -228
- package/lib/theme/DatalayerThemeProvider.d.ts +0 -29
- package/lib/theme/DatalayerThemeProvider.js +0 -54
- package/lib/theme/Palette.d.ts +0 -4
- package/lib/theme/Palette.js +0 -10
- package/lib/theme/index.d.ts +0 -4
- package/lib/theme/index.js +0 -8
- package/lib/theme/useSystemColorMode.d.ts +0 -9
- package/lib/theme/useSystemColorMode.js +0 -26
|
@@ -2,11 +2,10 @@
|
|
|
2
2
|
* Spacer API exports.
|
|
3
3
|
*
|
|
4
4
|
* Provides organized access to spacer functionality including
|
|
5
|
-
* spaces, notebooks, cells, lexical documents, and agent
|
|
5
|
+
* spaces, notebooks, cells, lexical documents, and agent runtimes.
|
|
6
6
|
*
|
|
7
7
|
* @module api/spacer
|
|
8
8
|
*/
|
|
9
|
-
export * as agentSpaces from './agentSpaces';
|
|
10
9
|
export * as documents from './documents';
|
|
11
10
|
export * as healthz from './healthz';
|
|
12
11
|
export * as items from './items';
|
package/lib/api/spacer/index.js
CHANGED
|
@@ -6,11 +6,10 @@
|
|
|
6
6
|
* Spacer API exports.
|
|
7
7
|
*
|
|
8
8
|
* Provides organized access to spacer functionality including
|
|
9
|
-
* spaces, notebooks, cells, lexical documents, and agent
|
|
9
|
+
* spaces, notebooks, cells, lexical documents, and agent runtimes.
|
|
10
10
|
*
|
|
11
11
|
* @module api/spacer
|
|
12
12
|
*/
|
|
13
|
-
export * as agentSpaces from './agentSpaces';
|
|
14
13
|
export * as documents from './documents';
|
|
15
14
|
export * as healthz from './healthz';
|
|
16
15
|
export * as items from './items';
|
|
@@ -5,6 +5,8 @@ type IBoringAvatarProps = {
|
|
|
5
5
|
size?: number;
|
|
6
6
|
square?: boolean;
|
|
7
7
|
style?: object;
|
|
8
|
+
/** Custom color palette passed to boring-avatars. When omitted the default Datalayer palette is used. */
|
|
9
|
+
colors?: string[];
|
|
8
10
|
};
|
|
9
|
-
export declare const BoringAvatar: ({ displayName, variant, size, square, style, }: IBoringAvatarProps) => import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
export declare const BoringAvatar: ({ displayName, variant, size, square, style, colors, }: IBoringAvatarProps) => import("react/jsx-runtime").JSX.Element;
|
|
10
12
|
export default BoringAvatar;
|
|
@@ -7,23 +7,24 @@ import BoringAvatars from 'boring-avatars';
|
|
|
7
7
|
// export const getRandomBoringAvatarVariant = () => VARIANTS[Math.floor(Math.random() * VARIANTS.length)] as VariantType;
|
|
8
8
|
const getRandomBoringAvatarVariant = () => 'bauhaus';
|
|
9
9
|
const RANDOM_BORING_AVATOR_VARIANT = getRandomBoringAvatarVariant();
|
|
10
|
-
|
|
10
|
+
const DEFAULT_COLORS = [
|
|
11
|
+
'#000000',
|
|
12
|
+
'#146A7C',
|
|
13
|
+
'#16A085',
|
|
14
|
+
'#1ABC9C',
|
|
15
|
+
'#2ECC71',
|
|
16
|
+
'#59595C',
|
|
17
|
+
'#92A1C6',
|
|
18
|
+
'#C20D90',
|
|
19
|
+
'#C271B4',
|
|
20
|
+
'#F0AB3D',
|
|
21
|
+
];
|
|
22
|
+
export const BoringAvatar = ({ displayName = '', variant, size = 40, square = false, style, colors, }) => {
|
|
11
23
|
const resolvedVariant = variant ?? RANDOM_BORING_AVATOR_VARIANT;
|
|
12
24
|
const safeName = String(displayName ?? '');
|
|
25
|
+
const resolvedColors = colors ?? DEFAULT_COLORS;
|
|
13
26
|
try {
|
|
14
|
-
return (_jsx("span", { style: { ...(style || {}) }, children: _jsx(BoringAvatars, { size: size, name: safeName, variant: resolvedVariant, square: square, colors:
|
|
15
|
-
'#000000',
|
|
16
|
-
'#146A7C',
|
|
17
|
-
'#16A085',
|
|
18
|
-
'#1ABC9C',
|
|
19
|
-
'#2ECC71',
|
|
20
|
-
'#59595C',
|
|
21
|
-
'#92A1C6',
|
|
22
|
-
'#C20D90',
|
|
23
|
-
'#C271B4',
|
|
24
|
-
'#F0AB3D',
|
|
25
|
-
// '#FFFFFF',
|
|
26
|
-
] }) }));
|
|
27
|
+
return (_jsx("span", { style: { ...(style || {}) }, children: _jsx(BoringAvatars, { size: size, name: safeName, variant: resolvedVariant, square: square, colors: resolvedColors }) }));
|
|
27
28
|
}
|
|
28
29
|
catch (error) {
|
|
29
30
|
console.error('BoringAvatar error:', error);
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import type { StoryObj } from '@storybook/react-vite';
|
|
2
2
|
declare const meta: {
|
|
3
3
|
title: string;
|
|
4
|
-
component: ({ displayName, variant, size, square, style, }: {
|
|
4
|
+
component: ({ displayName, variant, size, square, style, colors, }: {
|
|
5
5
|
displayName?: string;
|
|
6
6
|
variant?: "marble" | "beam" | "pixel" | "sunset" | "ring" | "bauhaus" | undefined;
|
|
7
7
|
size?: number;
|
|
8
8
|
square?: boolean;
|
|
9
9
|
style?: object;
|
|
10
|
+
colors?: string[];
|
|
10
11
|
}) => import("react/jsx-runtime").JSX.Element;
|
|
11
12
|
tags: string[];
|
|
12
13
|
parameters: {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type ReactNode } from 'react';
|
|
1
2
|
import { DocumentRegistry } from '@jupyterlab/docregistry';
|
|
2
3
|
import { Contents } from '@jupyterlab/services';
|
|
3
4
|
/**
|
|
@@ -24,6 +25,11 @@ export interface IContentsBrowserProps {
|
|
|
24
25
|
* Document registry.
|
|
25
26
|
*/
|
|
26
27
|
documentRegistry?: DocumentRegistry;
|
|
28
|
+
/**
|
|
29
|
+
* Optional title for the browser heading.
|
|
30
|
+
* Defaults to "Contents Browser".
|
|
31
|
+
*/
|
|
32
|
+
title?: ReactNode;
|
|
27
33
|
}
|
|
28
34
|
/**
|
|
29
35
|
* Storage browser component.
|
|
@@ -3,7 +3,7 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
3
3
|
* Copyright (c) 2023-2025 Datalayer, Inc.
|
|
4
4
|
* Distributed under the terms of the Modified BSD License.
|
|
5
5
|
*/
|
|
6
|
-
import { useCallback, useEffect, useState } from 'react';
|
|
6
|
+
import { useCallback, useEffect, useState, } from 'react';
|
|
7
7
|
import { PathExt } from '@jupyterlab/coreutils';
|
|
8
8
|
import { PromiseDelegate } from '@lumino/coreutils';
|
|
9
9
|
import { ActionList, ActionMenu, Heading, IconButton, Spinner, TreeView, } from '@primer/react';
|
|
@@ -26,7 +26,11 @@ export const CHUNK_SIZE = 1024 * 1024;
|
|
|
26
26
|
* Storage browser component.
|
|
27
27
|
*/
|
|
28
28
|
export function ContentsBrowser(props) {
|
|
29
|
-
const { contents, localContents, documentRegistry
|
|
29
|
+
const { contents, localContents, documentRegistry, title = (_jsx(Heading, { as: "h4", sx: {
|
|
30
|
+
fontSize: 'var(--text-title-size-small)',
|
|
31
|
+
lineHeight: 'var(--text-title-lineHeight-medium)',
|
|
32
|
+
fontWeight: 'var(--text-title-weight-medium)',
|
|
33
|
+
}, children: "Contents Browser" })), } = props;
|
|
30
34
|
const isMounted = useIsMounted();
|
|
31
35
|
const { trackAsyncTask } = useToast();
|
|
32
36
|
const [children, setChildren] = useState(null);
|
|
@@ -205,12 +209,7 @@ export function ContentsBrowser(props) {
|
|
|
205
209
|
const onSelect = useCallback((item, refresh) => {
|
|
206
210
|
setSelectedItem(item.path === selectedItem?.path ? null : { ...item, refresh });
|
|
207
211
|
}, [selectedItem]);
|
|
208
|
-
return (_jsxs(Box, { sx: { display: 'grid', gridTemplateAreas: `"header" "content"` }, children: [_jsxs(Box, { sx: { gridArea: 'header', display: 'flex', alignItems: 'center' }, children: [_jsx(
|
|
209
|
-
fontSize: 'var(--text-title-size-small)',
|
|
210
|
-
lineHeight: 'var(--text-title-lineHeight-medium)',
|
|
211
|
-
fontWeight: 'var(--text-title-weight-medium)',
|
|
212
|
-
flex: '1 1 auto',
|
|
213
|
-
}, children: "Contents Browser" }), _jsxs(Box, { children: [_jsx(IconButton, { variant: "invisible", "aria-label": 'Refresh contents browser.', title: 'Refresh contents browser.', icon: CounterClockWiseIcon, onClick: refresh }), _jsx(UploadIconButton, { label: 'Upload a file', multiple: true, upload: upload })] })] }), isLoading ? (_jsx(Box, { sx: {
|
|
212
|
+
return (_jsxs(Box, { sx: { display: 'grid', gridTemplateAreas: `"header" "content"` }, children: [_jsxs(Box, { sx: { gridArea: 'header', display: 'flex', alignItems: 'center' }, children: [_jsx(Box, { sx: { flex: '1 1 auto' }, children: title }), _jsxs(Box, { children: [_jsx(IconButton, { variant: "invisible", "aria-label": 'Refresh contents browser.', title: 'Refresh contents browser.', icon: CounterClockWiseIcon, onClick: refresh }), _jsx(UploadIconButton, { label: 'Upload a file', multiple: true, upload: upload })] })] }), isLoading ? (_jsx(Box, { sx: {
|
|
214
213
|
gridArea: 'content',
|
|
215
214
|
display: 'flex',
|
|
216
215
|
alignItems: 'center',
|
package/lib/hooks/index.d.ts
CHANGED
|
@@ -23,5 +23,7 @@ export * from './useScreencapture';
|
|
|
23
23
|
export * from './useToast';
|
|
24
24
|
export * from './useUpload';
|
|
25
25
|
export * from './useUser';
|
|
26
|
+
export * from './useProjects';
|
|
27
|
+
export * from './useProjectStore';
|
|
26
28
|
export * from './useVisibilityObserver';
|
|
27
29
|
export * from './useWindowSize';
|
package/lib/hooks/index.js
CHANGED
|
@@ -28,5 +28,7 @@ export * from './useScreencapture';
|
|
|
28
28
|
export * from './useToast';
|
|
29
29
|
export * from './useUpload';
|
|
30
30
|
export * from './useUser';
|
|
31
|
+
export * from './useProjects';
|
|
32
|
+
export * from './useProjectStore';
|
|
31
33
|
export * from './useVisibilityObserver';
|
|
32
34
|
export * from './useWindowSize';
|
package/lib/hooks/useCache.d.ts
CHANGED
|
@@ -36,7 +36,6 @@
|
|
|
36
36
|
*/
|
|
37
37
|
import { UseQueryOptions, UseMutationOptions } from '@tanstack/react-query';
|
|
38
38
|
import { IAnyOrganization, IAnySpace, IAssignment, ICell, IContact, ICourse, IDataset, IDatasource, IDocument, IEnvironment, IExercise, IIAMToken, ILesson, INotebook, IOrganization, IPage, ISchool, ISecret, ITeam, IUser, IUserOnboarding, IUserSettings } from '../models';
|
|
39
|
-
import type { AgentSpaceData, CreateAgentSpaceRequest, UpdateAgentSpaceRequest } from '../api/spacer/agentSpaces';
|
|
40
39
|
export type CacheProps = {
|
|
41
40
|
loginRoute?: string;
|
|
42
41
|
};
|
|
@@ -213,13 +212,6 @@ export declare const queryKeys: {
|
|
|
213
212
|
readonly bySpace: (spaceId: string) => readonly ["items", "space", string];
|
|
214
213
|
readonly search: (opts: ISearchOpts) => readonly ["items", "search", ISearchOpts];
|
|
215
214
|
};
|
|
216
|
-
readonly agentSpaces: {
|
|
217
|
-
readonly all: () => readonly ["agentSpaces"];
|
|
218
|
-
readonly lists: () => readonly ["agentSpaces", "list"];
|
|
219
|
-
readonly details: () => readonly ["agentSpaces", "detail"];
|
|
220
|
-
readonly detail: (id: string) => readonly ["agentSpaces", "detail", string];
|
|
221
|
-
readonly public: () => readonly ["agentSpaces", "public"];
|
|
222
|
-
};
|
|
223
215
|
readonly agentRuntimes: {
|
|
224
216
|
readonly all: () => readonly ["agentRuntimes"];
|
|
225
217
|
readonly lists: () => readonly ["agentRuntimes", "list"];
|
|
@@ -488,20 +480,6 @@ export declare const useCache: ({ loginRoute }?: CacheProps) => {
|
|
|
488
480
|
spaceHandle?: string;
|
|
489
481
|
}, unknown>;
|
|
490
482
|
useExportSpace: () => import("@tanstack/react-query").UseMutationResult<any, Error, string, unknown>;
|
|
491
|
-
useAgentSpace: (uid: string | undefined) => import("@tanstack/react-query").UseQueryResult<AgentSpaceData, Error>;
|
|
492
|
-
useAgentSpaces: () => import("@tanstack/react-query").UseQueryResult<AgentSpaceData[], Error>;
|
|
493
|
-
usePublicAgentSpaces: () => import("@tanstack/react-query").UseQueryResult<AgentSpaceData[], Error>;
|
|
494
|
-
useCreateAgentSpace: () => import("@tanstack/react-query").UseMutationResult<any, Error, CreateAgentSpaceRequest, unknown>;
|
|
495
|
-
useUpdateAgentSpace: () => import("@tanstack/react-query").UseMutationResult<any, Error, {
|
|
496
|
-
uid: string;
|
|
497
|
-
data: UpdateAgentSpaceRequest;
|
|
498
|
-
}, unknown>;
|
|
499
|
-
useDeleteAgentSpace: () => import("@tanstack/react-query").UseMutationResult<any, Error, string, unknown>;
|
|
500
|
-
useMakeAgentSpacePublic: () => import("@tanstack/react-query").UseMutationResult<any, Error, string, unknown>;
|
|
501
|
-
useMakeAgentSpacePrivate: () => import("@tanstack/react-query").UseMutationResult<any, Error, string, unknown>;
|
|
502
|
-
useRefreshAgentSpace: () => (uid: string) => void;
|
|
503
|
-
useRefreshAgentSpaces: () => () => void;
|
|
504
|
-
useRefreshPublicAgentSpaces: () => () => void;
|
|
505
483
|
useAgentRuntime: (podName: string | undefined) => import("@tanstack/react-query").UseQueryResult<{
|
|
506
484
|
status: "running" | "paused" | "starting" | "terminated" | "archived";
|
|
507
485
|
name: string;
|
|
@@ -520,7 +498,7 @@ export declare const useCache: ({ loginRoute }?: CacheProps) => {
|
|
|
520
498
|
burning_rate?: number;
|
|
521
499
|
ingress?: string;
|
|
522
500
|
token?: string;
|
|
523
|
-
agentSpec?:
|
|
501
|
+
agentSpec?: any;
|
|
524
502
|
}, Error>;
|
|
525
503
|
useAgentRuntimes: () => import("@tanstack/react-query").UseQueryResult<{
|
|
526
504
|
status: "running" | "paused" | "starting" | "terminated" | "archived";
|
|
@@ -540,7 +518,7 @@ export declare const useCache: ({ loginRoute }?: CacheProps) => {
|
|
|
540
518
|
burning_rate?: number;
|
|
541
519
|
ingress?: string;
|
|
542
520
|
token?: string;
|
|
543
|
-
agentSpec?:
|
|
521
|
+
agentSpec?: any;
|
|
544
522
|
}[], Error>;
|
|
545
523
|
useCreateAgentRuntime: () => import("@tanstack/react-query").UseMutationResult<any, Error, {
|
|
546
524
|
environmentName?: string;
|
|
@@ -1036,13 +1014,6 @@ export declare const useCache: ({ loginRoute }?: CacheProps) => {
|
|
|
1036
1014
|
readonly bySpace: (spaceId: string) => readonly ["items", "space", string];
|
|
1037
1015
|
readonly search: (opts: ISearchOpts) => readonly ["items", "search", ISearchOpts];
|
|
1038
1016
|
};
|
|
1039
|
-
readonly agentSpaces: {
|
|
1040
|
-
readonly all: () => readonly ["agentSpaces"];
|
|
1041
|
-
readonly lists: () => readonly ["agentSpaces", "list"];
|
|
1042
|
-
readonly details: () => readonly ["agentSpaces", "detail"];
|
|
1043
|
-
readonly detail: (id: string) => readonly ["agentSpaces", "detail", string];
|
|
1044
|
-
readonly public: () => readonly ["agentSpaces", "public"];
|
|
1045
|
-
};
|
|
1046
1017
|
readonly agentRuntimes: {
|
|
1047
1018
|
readonly all: () => readonly ["agentRuntimes"];
|
|
1048
1019
|
readonly lists: () => readonly ["agentRuntimes", "list"];
|
package/lib/hooks/useCache.js
CHANGED
|
@@ -272,14 +272,6 @@ export const queryKeys = {
|
|
|
272
272
|
bySpace: (spaceId) => [...queryKeys.items.all(), 'space', spaceId],
|
|
273
273
|
search: (opts) => [...queryKeys.items.all(), 'search', opts],
|
|
274
274
|
},
|
|
275
|
-
// Agent Spaces
|
|
276
|
-
agentSpaces: {
|
|
277
|
-
all: () => ['agentSpaces'],
|
|
278
|
-
lists: () => [...queryKeys.agentSpaces.all(), 'list'],
|
|
279
|
-
details: () => [...queryKeys.agentSpaces.all(), 'detail'],
|
|
280
|
-
detail: (id) => [...queryKeys.agentSpaces.details(), id],
|
|
281
|
-
public: () => [...queryKeys.agentSpaces.all(), 'public'],
|
|
282
|
-
},
|
|
283
275
|
// Agent Runtimes (runtimes with ai-agents environment)
|
|
284
276
|
agentRuntimes: {
|
|
285
277
|
all: () => ['agentRuntimes'],
|
|
@@ -1370,219 +1362,6 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
|
|
|
1370
1362
|
},
|
|
1371
1363
|
});
|
|
1372
1364
|
};
|
|
1373
|
-
// ============================================================================
|
|
1374
|
-
// Agent Spaces Hooks
|
|
1375
|
-
// ============================================================================
|
|
1376
|
-
/**
|
|
1377
|
-
* Get agent space by ID
|
|
1378
|
-
*/
|
|
1379
|
-
const useAgentSpace = (uid) => {
|
|
1380
|
-
return useQuery({
|
|
1381
|
-
queryKey: queryKeys.agentSpaces.detail(uid || ''),
|
|
1382
|
-
queryFn: async () => {
|
|
1383
|
-
const resp = await requestDatalayer({
|
|
1384
|
-
url: `${configuration.spacerRunUrl}/api/spacer/v1/agent-spaces/${uid}`,
|
|
1385
|
-
method: 'GET',
|
|
1386
|
-
});
|
|
1387
|
-
if (resp.success && resp.agentSpace) {
|
|
1388
|
-
return resp.agentSpace;
|
|
1389
|
-
}
|
|
1390
|
-
throw new Error(resp.message || 'Failed to fetch agent space');
|
|
1391
|
-
},
|
|
1392
|
-
...DEFAULT_QUERY_OPTIONS,
|
|
1393
|
-
enabled: !!uid,
|
|
1394
|
-
});
|
|
1395
|
-
};
|
|
1396
|
-
/**
|
|
1397
|
-
* List user's agent spaces
|
|
1398
|
-
*/
|
|
1399
|
-
const useAgentSpaces = () => {
|
|
1400
|
-
return useQuery({
|
|
1401
|
-
queryKey: queryKeys.agentSpaces.lists(),
|
|
1402
|
-
queryFn: async () => {
|
|
1403
|
-
const resp = await requestDatalayer({
|
|
1404
|
-
url: `${configuration.spacerRunUrl}/api/spacer/v1/agent-spaces`,
|
|
1405
|
-
method: 'GET',
|
|
1406
|
-
});
|
|
1407
|
-
if (resp.success && resp.agentSpaces) {
|
|
1408
|
-
const agentSpaces = resp.agentSpaces;
|
|
1409
|
-
// Set detail cache for each agent space
|
|
1410
|
-
agentSpaces.forEach((agentSpace) => {
|
|
1411
|
-
queryClient.setQueryData(queryKeys.agentSpaces.detail(agentSpace.id), agentSpace);
|
|
1412
|
-
});
|
|
1413
|
-
return agentSpaces;
|
|
1414
|
-
}
|
|
1415
|
-
return [];
|
|
1416
|
-
},
|
|
1417
|
-
...DEFAULT_QUERY_OPTIONS,
|
|
1418
|
-
enabled: !!user,
|
|
1419
|
-
});
|
|
1420
|
-
};
|
|
1421
|
-
/**
|
|
1422
|
-
* List public agent spaces (Library)
|
|
1423
|
-
*/
|
|
1424
|
-
const usePublicAgentSpaces = () => {
|
|
1425
|
-
return useQuery({
|
|
1426
|
-
queryKey: queryKeys.agentSpaces.public(),
|
|
1427
|
-
queryFn: async () => {
|
|
1428
|
-
const resp = await requestDatalayer({
|
|
1429
|
-
url: `${configuration.spacerRunUrl}/api/spacer/v1/agent-spaces/public`,
|
|
1430
|
-
method: 'GET',
|
|
1431
|
-
});
|
|
1432
|
-
if (resp.success && resp.agentSpaces) {
|
|
1433
|
-
return resp.agentSpaces;
|
|
1434
|
-
}
|
|
1435
|
-
return [];
|
|
1436
|
-
},
|
|
1437
|
-
...DEFAULT_QUERY_OPTIONS,
|
|
1438
|
-
});
|
|
1439
|
-
};
|
|
1440
|
-
/**
|
|
1441
|
-
* Create agent space
|
|
1442
|
-
*/
|
|
1443
|
-
const useCreateAgentSpace = () => {
|
|
1444
|
-
return useMutation({
|
|
1445
|
-
mutationFn: async (data) => {
|
|
1446
|
-
return requestDatalayer({
|
|
1447
|
-
url: `${configuration.spacerRunUrl}/api/spacer/v1/agent-spaces`,
|
|
1448
|
-
method: 'POST',
|
|
1449
|
-
body: data,
|
|
1450
|
-
});
|
|
1451
|
-
},
|
|
1452
|
-
onSuccess: resp => {
|
|
1453
|
-
if (resp.success && resp.agentSpace) {
|
|
1454
|
-
const agentSpace = resp.agentSpace;
|
|
1455
|
-
// Set detail cache
|
|
1456
|
-
queryClient.setQueryData(queryKeys.agentSpaces.detail(agentSpace.id), agentSpace);
|
|
1457
|
-
// Invalidate all agent space queries
|
|
1458
|
-
queryClient.invalidateQueries({
|
|
1459
|
-
queryKey: queryKeys.agentSpaces.all(),
|
|
1460
|
-
});
|
|
1461
|
-
}
|
|
1462
|
-
},
|
|
1463
|
-
});
|
|
1464
|
-
};
|
|
1465
|
-
/**
|
|
1466
|
-
* Update agent space
|
|
1467
|
-
*/
|
|
1468
|
-
const useUpdateAgentSpace = () => {
|
|
1469
|
-
return useMutation({
|
|
1470
|
-
mutationFn: async ({ uid, data, }) => {
|
|
1471
|
-
return requestDatalayer({
|
|
1472
|
-
url: `${configuration.spacerRunUrl}/api/spacer/v1/agent-spaces/${uid}`,
|
|
1473
|
-
method: 'PUT',
|
|
1474
|
-
body: data,
|
|
1475
|
-
});
|
|
1476
|
-
},
|
|
1477
|
-
onSuccess: (resp, { uid }) => {
|
|
1478
|
-
if (resp.success) {
|
|
1479
|
-
// Invalidate detail cache
|
|
1480
|
-
queryClient.invalidateQueries({
|
|
1481
|
-
queryKey: queryKeys.agentSpaces.detail(uid),
|
|
1482
|
-
});
|
|
1483
|
-
// Invalidate all agent space queries
|
|
1484
|
-
queryClient.invalidateQueries({
|
|
1485
|
-
queryKey: queryKeys.agentSpaces.all(),
|
|
1486
|
-
});
|
|
1487
|
-
}
|
|
1488
|
-
},
|
|
1489
|
-
});
|
|
1490
|
-
};
|
|
1491
|
-
/**
|
|
1492
|
-
* Delete agent space
|
|
1493
|
-
*/
|
|
1494
|
-
const useDeleteAgentSpace = () => {
|
|
1495
|
-
return useMutation({
|
|
1496
|
-
mutationFn: async (uid) => {
|
|
1497
|
-
return requestDatalayer({
|
|
1498
|
-
url: `${configuration.spacerRunUrl}/api/spacer/v1/agent-spaces/${uid}`,
|
|
1499
|
-
method: 'DELETE',
|
|
1500
|
-
});
|
|
1501
|
-
},
|
|
1502
|
-
onSuccess: () => {
|
|
1503
|
-
// Invalidate all agent space queries
|
|
1504
|
-
queryClient.invalidateQueries({
|
|
1505
|
-
queryKey: queryKeys.agentSpaces.all(),
|
|
1506
|
-
});
|
|
1507
|
-
},
|
|
1508
|
-
});
|
|
1509
|
-
};
|
|
1510
|
-
/**
|
|
1511
|
-
* Make agent space public
|
|
1512
|
-
*/
|
|
1513
|
-
const useMakeAgentSpacePublic = () => {
|
|
1514
|
-
return useMutation({
|
|
1515
|
-
mutationFn: async (uid) => {
|
|
1516
|
-
return requestDatalayer({
|
|
1517
|
-
url: `${configuration.spacerRunUrl}/api/spacer/v1/agent-spaces/${uid}/public`,
|
|
1518
|
-
method: 'POST',
|
|
1519
|
-
});
|
|
1520
|
-
},
|
|
1521
|
-
onSuccess: (resp, uid) => {
|
|
1522
|
-
if (resp.success) {
|
|
1523
|
-
queryClient.invalidateQueries({
|
|
1524
|
-
queryKey: queryKeys.agentSpaces.detail(uid),
|
|
1525
|
-
});
|
|
1526
|
-
queryClient.invalidateQueries({
|
|
1527
|
-
queryKey: queryKeys.agentSpaces.all(),
|
|
1528
|
-
});
|
|
1529
|
-
}
|
|
1530
|
-
},
|
|
1531
|
-
});
|
|
1532
|
-
};
|
|
1533
|
-
/**
|
|
1534
|
-
* Make agent space private
|
|
1535
|
-
*/
|
|
1536
|
-
const useMakeAgentSpacePrivate = () => {
|
|
1537
|
-
return useMutation({
|
|
1538
|
-
mutationFn: async (uid) => {
|
|
1539
|
-
return requestDatalayer({
|
|
1540
|
-
url: `${configuration.spacerRunUrl}/api/spacer/v1/agent-spaces/${uid}/private`,
|
|
1541
|
-
method: 'POST',
|
|
1542
|
-
});
|
|
1543
|
-
},
|
|
1544
|
-
onSuccess: (resp, uid) => {
|
|
1545
|
-
if (resp.success) {
|
|
1546
|
-
queryClient.invalidateQueries({
|
|
1547
|
-
queryKey: queryKeys.agentSpaces.detail(uid),
|
|
1548
|
-
});
|
|
1549
|
-
queryClient.invalidateQueries({
|
|
1550
|
-
queryKey: queryKeys.agentSpaces.all(),
|
|
1551
|
-
});
|
|
1552
|
-
}
|
|
1553
|
-
},
|
|
1554
|
-
});
|
|
1555
|
-
};
|
|
1556
|
-
/**
|
|
1557
|
-
* Refresh agent space data
|
|
1558
|
-
*/
|
|
1559
|
-
const useRefreshAgentSpace = () => {
|
|
1560
|
-
return (uid) => {
|
|
1561
|
-
queryClient.invalidateQueries({
|
|
1562
|
-
queryKey: queryKeys.agentSpaces.detail(uid),
|
|
1563
|
-
});
|
|
1564
|
-
};
|
|
1565
|
-
};
|
|
1566
|
-
/**
|
|
1567
|
-
* Refresh agent spaces list
|
|
1568
|
-
*/
|
|
1569
|
-
const useRefreshAgentSpaces = () => {
|
|
1570
|
-
return () => {
|
|
1571
|
-
queryClient.invalidateQueries({
|
|
1572
|
-
queryKey: queryKeys.agentSpaces.all(),
|
|
1573
|
-
});
|
|
1574
|
-
};
|
|
1575
|
-
};
|
|
1576
|
-
/**
|
|
1577
|
-
* Refresh public agent spaces list
|
|
1578
|
-
*/
|
|
1579
|
-
const useRefreshPublicAgentSpaces = () => {
|
|
1580
|
-
return () => {
|
|
1581
|
-
queryClient.invalidateQueries({
|
|
1582
|
-
queryKey: queryKeys.agentSpaces.public(),
|
|
1583
|
-
});
|
|
1584
|
-
};
|
|
1585
|
-
};
|
|
1586
1365
|
/**
|
|
1587
1366
|
* List agent runtimes (runtimes with ai-agents-env environment)
|
|
1588
1367
|
*/
|
|
@@ -6538,18 +6317,6 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
|
|
|
6538
6317
|
useRefreshUserSpace,
|
|
6539
6318
|
useRefreshLayout,
|
|
6540
6319
|
useExportSpace,
|
|
6541
|
-
// Agent Spaces
|
|
6542
|
-
useAgentSpace,
|
|
6543
|
-
useAgentSpaces,
|
|
6544
|
-
usePublicAgentSpaces,
|
|
6545
|
-
useCreateAgentSpace,
|
|
6546
|
-
useUpdateAgentSpace,
|
|
6547
|
-
useDeleteAgentSpace,
|
|
6548
|
-
useMakeAgentSpacePublic,
|
|
6549
|
-
useMakeAgentSpacePrivate,
|
|
6550
|
-
useRefreshAgentSpace,
|
|
6551
|
-
useRefreshAgentSpaces,
|
|
6552
|
-
useRefreshPublicAgentSpaces,
|
|
6553
6320
|
// Agent Runtimes (runtimes with ai-agents environment)
|
|
6554
6321
|
useAgentRuntime,
|
|
6555
6322
|
useAgentRuntimes,
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { Session } from '@jupyterlab/services';
|
|
2
|
+
import type { IKernelConnection } from '@jupyterlab/services/lib/kernel/kernel';
|
|
3
|
+
/**
|
|
4
|
+
* Per-project runtime state tracked in memory.
|
|
5
|
+
*
|
|
6
|
+
* This is **not** persisted — it represents live runtime objects
|
|
7
|
+
* (kernel connections, sessions) that only exist while the project
|
|
8
|
+
* view is mounted.
|
|
9
|
+
*/
|
|
10
|
+
export type ProjectRuntimeEntry = {
|
|
11
|
+
/** The Jupyter session connection (notebook ↔ kernel bridge). */
|
|
12
|
+
sessionConnection?: Session.ISessionConnection;
|
|
13
|
+
/** The assigned agent pod name (mirrors project.attachedAgentPodName). */
|
|
14
|
+
agentPodName?: string;
|
|
15
|
+
/** Display name of the assigned agent. */
|
|
16
|
+
agentName?: string;
|
|
17
|
+
/** Agent runtime status (running, starting, terminated, etc.). */
|
|
18
|
+
agentStatus?: string;
|
|
19
|
+
/** The agent spec ID used to create the runtime. */
|
|
20
|
+
agentSpecId?: string;
|
|
21
|
+
};
|
|
22
|
+
export type ProjectStoreState = {
|
|
23
|
+
/** Map of projectId → runtime entry. */
|
|
24
|
+
projects: Record<string, ProjectRuntimeEntry>;
|
|
25
|
+
/** The currently active/viewed project ID (for sidebar highlighting). */
|
|
26
|
+
currentProjectId: string | undefined;
|
|
27
|
+
/** Set the currently active project (call on mount, clear on unmount). */
|
|
28
|
+
setCurrentProjectId: (projectId: string | undefined) => void;
|
|
29
|
+
/** Set or update the session connection for a project. */
|
|
30
|
+
setSessionConnection: (projectId: string, sessionConnection: Session.ISessionConnection | undefined) => void;
|
|
31
|
+
/** Set the assigned agent info for a project. */
|
|
32
|
+
setAgent: (projectId: string, agentPodName: string | undefined, agentName?: string, agentStatus?: string, agentSpecId?: string) => void;
|
|
33
|
+
/** Remove all runtime state for a project (e.g. on unmount). */
|
|
34
|
+
clearProject: (projectId: string) => void;
|
|
35
|
+
/** Get the kernel connection for a project, or undefined. */
|
|
36
|
+
getKernel: (projectId: string) => IKernelConnection | null | undefined;
|
|
37
|
+
/** Get the full entry for a project. */
|
|
38
|
+
getEntry: (projectId: string) => ProjectRuntimeEntry | undefined;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Zustand store for per-project runtime state (kernel connections, agents).
|
|
42
|
+
*
|
|
43
|
+
* Not persisted — the data is ephemeral and only valid while the project
|
|
44
|
+
* component is mounted and a kernel/agent is active.
|
|
45
|
+
*
|
|
46
|
+
* Usage:
|
|
47
|
+
* ```ts
|
|
48
|
+
* import { useProjectStore } from '@datalayer/core/lib/hooks';
|
|
49
|
+
*
|
|
50
|
+
* // In Project.tsx — store session when Notebook connects:
|
|
51
|
+
* const setSessionConnection = useProjectStore(s => s.setSessionConnection);
|
|
52
|
+
* <Notebook onSessionConnection={sc => setSessionConnection(projectId, sc)} />
|
|
53
|
+
*
|
|
54
|
+
* // Anywhere — read the kernel for a project:
|
|
55
|
+
* const kernel = useProjectStore(s => s.getKernel(projectId));
|
|
56
|
+
* ```
|
|
57
|
+
*/
|
|
58
|
+
export declare const useProjectStore: import("zustand").UseBoundStore<import("zustand").StoreApi<ProjectStoreState>>;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2023-2025 Datalayer, Inc.
|
|
3
|
+
* Distributed under the terms of the Modified BSD License.
|
|
4
|
+
*/
|
|
5
|
+
import { create } from 'zustand';
|
|
6
|
+
/**
|
|
7
|
+
* Zustand store for per-project runtime state (kernel connections, agents).
|
|
8
|
+
*
|
|
9
|
+
* Not persisted — the data is ephemeral and only valid while the project
|
|
10
|
+
* component is mounted and a kernel/agent is active.
|
|
11
|
+
*
|
|
12
|
+
* Usage:
|
|
13
|
+
* ```ts
|
|
14
|
+
* import { useProjectStore } from '@datalayer/core/lib/hooks';
|
|
15
|
+
*
|
|
16
|
+
* // In Project.tsx — store session when Notebook connects:
|
|
17
|
+
* const setSessionConnection = useProjectStore(s => s.setSessionConnection);
|
|
18
|
+
* <Notebook onSessionConnection={sc => setSessionConnection(projectId, sc)} />
|
|
19
|
+
*
|
|
20
|
+
* // Anywhere — read the kernel for a project:
|
|
21
|
+
* const kernel = useProjectStore(s => s.getKernel(projectId));
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export const useProjectStore = create()((set, get) => ({
|
|
25
|
+
projects: {},
|
|
26
|
+
currentProjectId: undefined,
|
|
27
|
+
setCurrentProjectId: projectId => set({ currentProjectId: projectId }),
|
|
28
|
+
setSessionConnection: (projectId, sessionConnection) => set(state => ({
|
|
29
|
+
projects: {
|
|
30
|
+
...state.projects,
|
|
31
|
+
[projectId]: {
|
|
32
|
+
...state.projects[projectId],
|
|
33
|
+
sessionConnection,
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
})),
|
|
37
|
+
setAgent: (projectId, agentPodName, agentName, agentStatus, agentSpecId) => set(state => ({
|
|
38
|
+
projects: {
|
|
39
|
+
...state.projects,
|
|
40
|
+
[projectId]: {
|
|
41
|
+
...state.projects[projectId],
|
|
42
|
+
agentPodName,
|
|
43
|
+
agentName,
|
|
44
|
+
// When removing the agent, also clear the status.
|
|
45
|
+
// When setting, use provided status or preserve existing.
|
|
46
|
+
agentStatus: agentPodName !== undefined
|
|
47
|
+
? (agentStatus ?? state.projects[projectId]?.agentStatus)
|
|
48
|
+
: undefined,
|
|
49
|
+
agentSpecId: agentPodName !== undefined
|
|
50
|
+
? (agentSpecId ?? state.projects[projectId]?.agentSpecId)
|
|
51
|
+
: undefined,
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
})),
|
|
55
|
+
clearProject: projectId => set(state => {
|
|
56
|
+
const { [projectId]: _, ...rest } = state.projects;
|
|
57
|
+
return { projects: rest };
|
|
58
|
+
}),
|
|
59
|
+
getKernel: projectId => {
|
|
60
|
+
const entry = get().projects[projectId];
|
|
61
|
+
return entry?.sessionConnection?.kernel;
|
|
62
|
+
},
|
|
63
|
+
getEntry: projectId => get().projects[projectId],
|
|
64
|
+
}));
|