@datalayer/core 1.0.1 → 1.0.3

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.
Files changed (103) hide show
  1. package/README.md +1 -1
  2. package/lib/api/constants.d.ts +3 -0
  3. package/lib/api/constants.js +3 -0
  4. package/lib/api/index.d.ts +1 -0
  5. package/lib/api/index.js +1 -0
  6. package/lib/api/otel/index.d.ts +12 -0
  7. package/lib/api/otel/index.js +16 -0
  8. package/lib/api/otel/logs.d.ts +19 -0
  9. package/lib/api/otel/logs.js +43 -0
  10. package/lib/api/otel/metrics.d.ts +31 -0
  11. package/lib/api/otel/metrics.js +65 -0
  12. package/lib/api/otel/query.d.ts +16 -0
  13. package/lib/api/otel/query.js +37 -0
  14. package/lib/api/otel/services.d.ts +39 -0
  15. package/lib/api/otel/services.js +81 -0
  16. package/lib/api/otel/traces.d.ts +24 -0
  17. package/lib/api/otel/traces.js +53 -0
  18. package/lib/api/otel/types.d.ts +112 -0
  19. package/lib/api/otel/types.js +5 -0
  20. package/lib/api/spacer/index.d.ts +1 -2
  21. package/lib/api/spacer/index.js +1 -2
  22. package/lib/components/avatars/BoringAvatar.d.ts +3 -1
  23. package/lib/components/avatars/BoringAvatar.js +15 -14
  24. package/lib/components/avatars/BoringAvatar.stories.d.ts +2 -1
  25. package/lib/components/storage/ContentsBrowser.d.ts +6 -0
  26. package/lib/components/storage/ContentsBrowser.js +7 -8
  27. package/lib/config/Configuration.d.ts +4 -0
  28. package/lib/hooks/index.d.ts +2 -0
  29. package/lib/hooks/index.js +2 -0
  30. package/lib/hooks/useCache.d.ts +16 -40
  31. package/lib/hooks/useCache.js +28 -233
  32. package/lib/hooks/useProjectStore.d.ts +58 -0
  33. package/lib/hooks/useProjectStore.js +64 -0
  34. package/lib/hooks/useProjects.d.ts +590 -0
  35. package/lib/hooks/useProjects.js +166 -0
  36. package/lib/index.d.ts +2 -1
  37. package/lib/index.js +4 -2
  38. package/lib/models/Page.d.ts +2 -0
  39. package/lib/otel/OtelLive.d.ts +12 -0
  40. package/lib/otel/OtelLive.js +354 -0
  41. package/lib/otel/OtelLogsList.d.ts +11 -0
  42. package/lib/otel/OtelLogsList.js +137 -0
  43. package/lib/otel/OtelMetricsChart.d.ts +22 -0
  44. package/lib/otel/OtelMetricsChart.js +300 -0
  45. package/lib/otel/OtelMetricsList.d.ts +15 -0
  46. package/lib/otel/OtelMetricsList.js +213 -0
  47. package/lib/otel/OtelSearchBar.d.ts +11 -0
  48. package/lib/otel/OtelSearchBar.js +22 -0
  49. package/lib/otel/OtelSpanDetail.d.ts +11 -0
  50. package/lib/otel/OtelSpanDetail.js +172 -0
  51. package/lib/otel/OtelSpanTree.d.ts +11 -0
  52. package/lib/otel/OtelSpanTree.js +176 -0
  53. package/lib/otel/OtelSqlView.d.ts +16 -0
  54. package/lib/otel/OtelSqlView.js +239 -0
  55. package/lib/otel/OtelSystemView.d.ts +15 -0
  56. package/lib/otel/OtelSystemView.js +75 -0
  57. package/lib/otel/OtelTimeline.d.ts +11 -0
  58. package/lib/otel/OtelTimeline.js +101 -0
  59. package/lib/otel/OtelTimelineRangeSlider.d.ts +16 -0
  60. package/lib/otel/OtelTimelineRangeSlider.js +338 -0
  61. package/lib/otel/OtelTracesList.d.ts +13 -0
  62. package/lib/otel/OtelTracesList.js +199 -0
  63. package/lib/otel/hooks.d.ts +172 -0
  64. package/lib/otel/hooks.js +490 -0
  65. package/lib/otel/index.d.ts +25 -0
  66. package/lib/otel/index.js +19 -0
  67. package/lib/otel/types.d.ts +190 -0
  68. package/lib/otel/types.js +5 -0
  69. package/lib/otel/utils.d.ts +33 -0
  70. package/lib/otel/utils.js +181 -0
  71. package/lib/state/storage/IAMStorage.d.ts +2 -1
  72. package/lib/state/substates/CoreState.js +1 -0
  73. package/lib/utils/Jwt.d.ts +42 -0
  74. package/lib/utils/Jwt.js +44 -0
  75. package/lib/utils/index.d.ts +1 -0
  76. package/lib/utils/index.js +1 -0
  77. package/lib/views/iam/SignInSimple.d.ts +38 -0
  78. package/lib/views/iam/SignInSimple.js +80 -0
  79. package/lib/views/iam/index.d.ts +2 -0
  80. package/lib/views/iam/index.js +5 -0
  81. package/lib/views/iam-tokens/IAMTokenEdit.js +53 -4
  82. package/lib/views/iam-tokens/IAMTokens.js +65 -33
  83. package/lib/views/iam-tokens/Tokens.js +64 -32
  84. package/lib/views/index.d.ts +2 -1
  85. package/lib/views/index.js +2 -1
  86. package/lib/views/profile/UserBadge.d.ts +18 -0
  87. package/lib/views/profile/UserBadge.js +101 -0
  88. package/lib/views/profile/index.d.ts +2 -0
  89. package/lib/views/profile/index.js +5 -0
  90. package/lib/views/secrets/Secrets.js +1 -1
  91. package/package.json +27 -3
  92. package/lib/api/spacer/agentSpaces.d.ts +0 -193
  93. package/lib/api/spacer/agentSpaces.js +0 -127
  94. package/lib/theme/DatalayerTheme.d.ts +0 -52
  95. package/lib/theme/DatalayerTheme.js +0 -228
  96. package/lib/theme/DatalayerThemeProvider.d.ts +0 -29
  97. package/lib/theme/DatalayerThemeProvider.js +0 -54
  98. package/lib/theme/Palette.d.ts +0 -4
  99. package/lib/theme/Palette.js +0 -10
  100. package/lib/theme/index.d.ts +0 -4
  101. package/lib/theme/index.js +0 -8
  102. package/lib/theme/useSystemColorMode.d.ts +0 -9
  103. package/lib/theme/useSystemColorMode.js +0 -26
@@ -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
- export const BoringAvatar = ({ displayName = '', variant, size = 40, square = false, style, }) => {
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 } = props;
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(Heading, { as: "h4", sx: {
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',
@@ -71,6 +71,10 @@ export type IDatalayerCoreConfig = {
71
71
  * MCP Servers API URL.
72
72
  */
73
73
  mcpserversRunUrl: string;
74
+ /**
75
+ * OTEL (OpenTelemetry) API URL.
76
+ */
77
+ otelRunUrl: string;
74
78
  /**
75
79
  * Growth API URL.
76
80
  */
@@ -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';
@@ -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';
@@ -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
  };
@@ -46,6 +45,18 @@ export type ISearchOpts = {
46
45
  max: number;
47
46
  public: boolean;
48
47
  };
48
+ /** Request payload for creating a new agent runtime. */
49
+ export type CreateAgentRuntimeRequest = {
50
+ environmentName?: string;
51
+ givenName?: string;
52
+ creditsLimit?: number;
53
+ type?: string;
54
+ /** 'none', 'notebook', or 'document' */
55
+ editorVariant?: string;
56
+ enableCodemode?: boolean;
57
+ /** ID of the agent spec used to create this runtime */
58
+ agentSpecId?: string;
59
+ };
49
60
  /**
50
61
  * Centralized query key factories for all entities
51
62
  * Following TanStack Query best practices for key structure
@@ -213,13 +224,6 @@ export declare const queryKeys: {
213
224
  readonly bySpace: (spaceId: string) => readonly ["items", "space", string];
214
225
  readonly search: (opts: ISearchOpts) => readonly ["items", "search", ISearchOpts];
215
226
  };
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
227
  readonly agentRuntimes: {
224
228
  readonly all: () => readonly ["agentRuntimes"];
225
229
  readonly lists: () => readonly ["agentRuntimes", "list"];
@@ -488,20 +492,6 @@ export declare const useCache: ({ loginRoute }?: CacheProps) => {
488
492
  spaceHandle?: string;
489
493
  }, unknown>;
490
494
  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
495
  useAgentRuntime: (podName: string | undefined) => import("@tanstack/react-query").UseQueryResult<{
506
496
  status: "running" | "paused" | "starting" | "terminated" | "archived";
507
497
  name: string;
@@ -520,7 +510,7 @@ export declare const useCache: ({ loginRoute }?: CacheProps) => {
520
510
  burning_rate?: number;
521
511
  ingress?: string;
522
512
  token?: string;
523
- agentSpec?: AgentSpaceData["agentSpec"];
513
+ agentSpec?: any;
524
514
  }, Error>;
525
515
  useAgentRuntimes: () => import("@tanstack/react-query").UseQueryResult<{
526
516
  status: "running" | "paused" | "starting" | "terminated" | "archived";
@@ -540,17 +530,9 @@ export declare const useCache: ({ loginRoute }?: CacheProps) => {
540
530
  burning_rate?: number;
541
531
  ingress?: string;
542
532
  token?: string;
543
- agentSpec?: AgentSpaceData["agentSpec"];
533
+ agentSpec?: any;
544
534
  }[], Error>;
545
- useCreateAgentRuntime: () => import("@tanstack/react-query").UseMutationResult<any, Error, {
546
- environmentName?: string;
547
- givenName?: string;
548
- creditsLimit?: number;
549
- type?: string;
550
- editorVariant?: string;
551
- enableCodemode?: boolean;
552
- agentSpecId?: string;
553
- }, unknown>;
535
+ useCreateAgentRuntime: () => import("@tanstack/react-query").UseMutationResult<any, Error, CreateAgentRuntimeRequest, unknown>;
554
536
  useDeleteAgentRuntime: () => import("@tanstack/react-query").UseMutationResult<any, Error, string, unknown>;
555
537
  useRefreshAgentRuntimes: () => () => void;
556
538
  useCourse: (courseId: string) => import("@tanstack/react-query").UseQueryResult<ICourse | undefined, Error>;
@@ -755,6 +737,7 @@ export declare const useCache: ({ loginRoute }?: CacheProps) => {
755
737
  useTokens: () => import("@tanstack/react-query").UseQueryResult<any, Error>;
756
738
  useCreateToken: () => import("@tanstack/react-query").UseMutationResult<any, Error, Omit<IIAMToken, "id" | "value">, unknown>;
757
739
  useUpdateToken: () => import("@tanstack/react-query").UseMutationResult<any, Error, IIAMToken, unknown>;
740
+ useDeleteToken: () => import("@tanstack/react-query").UseMutationResult<any, Error, string, unknown>;
758
741
  useInvite: (token: string) => import("@tanstack/react-query").UseQueryResult<import("..").IInvite | undefined, Error>;
759
742
  useInvitesByUser: (accountId: string) => import("@tanstack/react-query").UseQueryResult<any, Error>;
760
743
  usePutInvite: () => import("@tanstack/react-query").UseMutationResult<any, Error, string, unknown>;
@@ -1036,13 +1019,6 @@ export declare const useCache: ({ loginRoute }?: CacheProps) => {
1036
1019
  readonly bySpace: (spaceId: string) => readonly ["items", "space", string];
1037
1020
  readonly search: (opts: ISearchOpts) => readonly ["items", "search", ISearchOpts];
1038
1021
  };
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
1022
  readonly agentRuntimes: {
1047
1023
  readonly all: () => readonly ["agentRuntimes"];
1048
1024
  readonly lists: () => readonly ["agentRuntimes", "list"];
@@ -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
  */
@@ -1694,6 +1473,14 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1694
1473
  enabled: !!podName,
1695
1474
  });
1696
1475
  };
1476
+ /**
1477
+ * Create a new agent runtime.
1478
+ *
1479
+ * Note on phase/status mapping:
1480
+ * Newly created runtimes are immediately active (the operator assigns a pod from the pool).
1481
+ * The response won't have a 'phase' field, so we default to 'running'.
1482
+ * See useAgentRuntimes JSDoc for full explanation.
1483
+ */
1697
1484
  const useCreateAgentRuntime = () => {
1698
1485
  return useMutation({
1699
1486
  mutationFn: async (data) => {
@@ -2718,6 +2505,25 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
2718
2505
  },
2719
2506
  });
2720
2507
  };
2508
+ /**
2509
+ * Delete token by ID
2510
+ */
2511
+ const useDeleteToken = () => {
2512
+ return useMutation({
2513
+ mutationFn: async (tokenId) => {
2514
+ return requestDatalayer({
2515
+ url: `${configuration.iamRunUrl}/api/iam/v1/tokens/${tokenId}`,
2516
+ method: 'DELETE',
2517
+ });
2518
+ },
2519
+ onSuccess: (_, tokenId) => {
2520
+ queryClient.removeQueries({
2521
+ queryKey: queryKeys.tokens.detail(tokenId),
2522
+ });
2523
+ queryClient.invalidateQueries({ queryKey: queryKeys.tokens.all() });
2524
+ },
2525
+ });
2526
+ };
2721
2527
  /**
2722
2528
  * Get contact by handle
2723
2529
  */
@@ -6538,18 +6344,6 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6538
6344
  useRefreshUserSpace,
6539
6345
  useRefreshLayout,
6540
6346
  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
6347
  // Agent Runtimes (runtimes with ai-agents environment)
6554
6348
  useAgentRuntime,
6555
6349
  useAgentRuntimes,
@@ -6667,6 +6461,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6667
6461
  useTokens,
6668
6462
  useCreateToken,
6669
6463
  useUpdateToken,
6464
+ useDeleteToken,
6670
6465
  // Invites
6671
6466
  useInvite,
6672
6467
  useInvitesByUser,
@@ -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
+ }));