@datalayer/core 0.0.25 → 0.0.27

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 (109) hide show
  1. package/README.md +11 -11
  2. package/lib/api/index.d.ts +1 -1
  3. package/lib/api/index.js +1 -1
  4. package/lib/api/spacer/agentSpaces.d.ts +193 -0
  5. package/lib/api/spacer/agentSpaces.js +127 -0
  6. package/lib/api/spacer/index.d.ts +2 -1
  7. package/lib/api/spacer/index.js +2 -1
  8. package/lib/api/utils/validation.d.ts +1 -1
  9. package/lib/api/utils/validation.js +1 -1
  10. package/lib/client/auth/AuthenticationManager.d.ts +2 -2
  11. package/lib/client/auth/AuthenticationManager.js +2 -2
  12. package/lib/client/auth/index.d.ts +1 -1
  13. package/lib/client/auth/index.js +1 -1
  14. package/lib/client/auth/types.d.ts +1 -1
  15. package/lib/client/auth/types.js +1 -1
  16. package/lib/client/base.d.ts +9 -9
  17. package/lib/client/base.js +3 -3
  18. package/lib/client/constants.d.ts +2 -2
  19. package/lib/client/constants.js +2 -2
  20. package/lib/client/index.d.ts +2 -2
  21. package/lib/client/mixins/IAMMixin.js +1 -1
  22. package/lib/client/utils/spacerUtils.d.ts +1 -1
  23. package/lib/client/utils/spacerUtils.js +1 -1
  24. package/lib/components/auth/Login.d.ts +4 -0
  25. package/lib/components/auth/Login.js +8 -2
  26. package/lib/components/auth/Login.stories.d.ts +1 -0
  27. package/lib/components/progress/ConsumptionBar.js +26 -8
  28. package/lib/components/progress/CreditsIndicator.d.ts +7 -1
  29. package/lib/components/progress/CreditsIndicator.js +4 -2
  30. package/lib/components/{screenshot/ScreenCapture.d.ts → screencapture/Screencapture.d.ts} +5 -5
  31. package/lib/components/{screenshot/ScreenCapture.js → screencapture/Screencapture.js} +2 -2
  32. package/lib/components/screencapture/ScreencaptureButton.d.ts +3 -0
  33. package/lib/components/{screenshot/ScreenCaptureButton.js → screencapture/ScreencaptureButton.js} +8 -8
  34. package/lib/components/screencapture/index.d.ts +2 -0
  35. package/lib/components/{screenshot → screencapture}/index.js +2 -2
  36. package/lib/hooks/index.d.ts +1 -1
  37. package/lib/hooks/index.js +1 -1
  38. package/lib/hooks/layouts/{LayoutScreenshot.css → LayoutScreencapture.css} +2 -2
  39. package/lib/hooks/layouts/LayoutScreencapture.d.ts +3 -0
  40. package/lib/hooks/layouts/{LayoutScreenshot.js → LayoutScreencapture.js} +14 -14
  41. package/lib/hooks/layouts/index.d.ts +1 -1
  42. package/lib/hooks/layouts/index.js +1 -1
  43. package/lib/hooks/useCache.d.ts +91 -1
  44. package/lib/hooks/useCache.js +523 -59
  45. package/lib/hooks/useCellOutputshot.js +2 -2
  46. package/lib/hooks/useScreencapture.d.ts +18 -0
  47. package/lib/hooks/useScreencapture.js +53 -0
  48. package/lib/index.d.ts +1 -1
  49. package/lib/models/CreditsDTO.js +1 -1
  50. package/lib/models/Datasource.d.ts +2 -2
  51. package/lib/models/Datasource.js +2 -2
  52. package/lib/models/EnvironmentDTO.d.ts +3 -3
  53. package/lib/models/EnvironmentDTO.js +2 -2
  54. package/lib/models/HealthCheck.d.ts +1 -1
  55. package/lib/models/HealthCheck.js +1 -1
  56. package/lib/models/IAMProviderUsers.d.ts +11 -0
  57. package/lib/models/IAMProvidersSpecs.d.ts +2 -1
  58. package/lib/models/IAMProvidersSpecs.js +14 -0
  59. package/lib/models/ItemDTO.d.ts +2 -2
  60. package/lib/models/ItemDTO.js +2 -2
  61. package/lib/models/LexicalDTO.d.ts +2 -2
  62. package/lib/models/LexicalDTO.js +2 -2
  63. package/lib/models/NotebookDTO.d.ts +2 -2
  64. package/lib/models/NotebookDTO.js +1 -1
  65. package/lib/models/Page.js +1 -1
  66. package/lib/models/PageTag.d.ts +1 -1
  67. package/lib/models/PageTag.js +21 -0
  68. package/lib/models/RuntimeDTO.d.ts +2 -2
  69. package/lib/models/RuntimeDTO.js +2 -2
  70. package/lib/models/RuntimeSnapshotDTO.d.ts +3 -3
  71. package/lib/models/RuntimeSnapshotDTO.js +1 -1
  72. package/lib/models/Secret.d.ts +3 -3
  73. package/lib/models/Secret.js +2 -2
  74. package/lib/models/SpaceDTO.d.ts +2 -2
  75. package/lib/models/SpaceDTO.js +3 -3
  76. package/lib/models/UserDTO.d.ts +2 -2
  77. package/lib/models/UserDTO.js +1 -1
  78. package/lib/models/index.d.ts +1 -1
  79. package/lib/models/index.js +1 -1
  80. package/lib/state/substates/CoreState.js +1 -1
  81. package/lib/state/substates/LayoutState.d.ts +5 -5
  82. package/lib/state/substates/LayoutState.js +3 -3
  83. package/lib/theme/DatalayerThemeProvider.d.ts +22 -2
  84. package/lib/theme/DatalayerThemeProvider.js +17 -9
  85. package/lib/theme/index.d.ts +1 -0
  86. package/lib/theme/index.js +1 -0
  87. package/lib/theme/useSystemColorMode.d.ts +9 -0
  88. package/lib/theme/useSystemColorMode.js +26 -0
  89. package/lib/utils/Screencapture.d.ts +1 -0
  90. package/lib/utils/{Screenshot.js → Screencapture.js} +1 -1
  91. package/lib/utils/index.js +1 -1
  92. package/lib/views/datasources/DatasourceNew.d.ts +7 -1
  93. package/lib/views/datasources/DatasourceNew.js +3 -3
  94. package/lib/views/datasources/Datasources.d.ts +7 -1
  95. package/lib/views/datasources/Datasources.js +6 -4
  96. package/lib/views/iam-tokens/IAMTokenNew.d.ts +5 -1
  97. package/lib/views/iam-tokens/IAMTokenNew.js +2 -2
  98. package/lib/views/iam-tokens/IAMTokens.d.ts +7 -1
  99. package/lib/views/iam-tokens/IAMTokens.js +6 -4
  100. package/package.json +1 -1
  101. package/style/screencapture/index.css +58 -0
  102. package/lib/components/screenshot/ScreenCaptureButton.d.ts +0 -3
  103. package/lib/components/screenshot/index.d.ts +0 -2
  104. package/lib/hooks/layouts/LayoutScreenshot.d.ts +0 -3
  105. package/lib/hooks/useCache0.d.ts +0 -312
  106. package/lib/hooks/useCache0.js +0 -3189
  107. package/lib/hooks/useScreenshot.d.ts +0 -18
  108. package/lib/hooks/useScreenshot.js +0 -53
  109. package/lib/utils/Screenshot.d.ts +0 -1
@@ -272,6 +272,21 @@ 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
+ // Agent Runtimes (runtimes with ai-agents environment)
284
+ agentRuntimes: {
285
+ all: () => ['agentRuntimes'],
286
+ lists: () => [...queryKeys.agentRuntimes.all(), 'list'],
287
+ details: () => [...queryKeys.agentRuntimes.all(), 'detail'],
288
+ detail: (podName) => [...queryKeys.agentRuntimes.details(), podName],
289
+ },
275
290
  // Layout
276
291
  layout: {
277
292
  byAccount: (accountHandle, spaceHandle) => spaceHandle
@@ -1334,6 +1349,398 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
1334
1349
  });
1335
1350
  };
1336
1351
  // ============================================================================
1352
+ // Agent Spaces Hooks
1353
+ // ============================================================================
1354
+ /**
1355
+ * Get agent space by ID
1356
+ */
1357
+ const useAgentSpace = (uid) => {
1358
+ return useQuery({
1359
+ queryKey: queryKeys.agentSpaces.detail(uid || ''),
1360
+ queryFn: async () => {
1361
+ const resp = await requestDatalayer({
1362
+ url: `${configuration.spacerRunUrl}/api/spacer/v1/agent-spaces/${uid}`,
1363
+ method: 'GET',
1364
+ });
1365
+ if (resp.success && resp.agentSpace) {
1366
+ return resp.agentSpace;
1367
+ }
1368
+ throw new Error(resp.message || 'Failed to fetch agent space');
1369
+ },
1370
+ ...DEFAULT_QUERY_OPTIONS,
1371
+ enabled: !!uid,
1372
+ });
1373
+ };
1374
+ /**
1375
+ * List user's agent spaces
1376
+ */
1377
+ const useAgentSpaces = () => {
1378
+ return useQuery({
1379
+ queryKey: queryKeys.agentSpaces.lists(),
1380
+ queryFn: async () => {
1381
+ const resp = await requestDatalayer({
1382
+ url: `${configuration.spacerRunUrl}/api/spacer/v1/agent-spaces`,
1383
+ method: 'GET',
1384
+ });
1385
+ if (resp.success && resp.agentSpaces) {
1386
+ const agentSpaces = resp.agentSpaces;
1387
+ // Set detail cache for each agent space
1388
+ agentSpaces.forEach((agentSpace) => {
1389
+ queryClient.setQueryData(queryKeys.agentSpaces.detail(agentSpace.id), agentSpace);
1390
+ });
1391
+ return agentSpaces;
1392
+ }
1393
+ return [];
1394
+ },
1395
+ ...DEFAULT_QUERY_OPTIONS,
1396
+ enabled: !!user,
1397
+ });
1398
+ };
1399
+ /**
1400
+ * List public agent spaces (Library)
1401
+ */
1402
+ const usePublicAgentSpaces = () => {
1403
+ return useQuery({
1404
+ queryKey: queryKeys.agentSpaces.public(),
1405
+ queryFn: async () => {
1406
+ const resp = await requestDatalayer({
1407
+ url: `${configuration.spacerRunUrl}/api/spacer/v1/agent-spaces/public`,
1408
+ method: 'GET',
1409
+ });
1410
+ if (resp.success && resp.agentSpaces) {
1411
+ return resp.agentSpaces;
1412
+ }
1413
+ return [];
1414
+ },
1415
+ ...DEFAULT_QUERY_OPTIONS,
1416
+ });
1417
+ };
1418
+ /**
1419
+ * Create agent space
1420
+ */
1421
+ const useCreateAgentSpace = () => {
1422
+ return useMutation({
1423
+ mutationFn: async (data) => {
1424
+ return requestDatalayer({
1425
+ url: `${configuration.spacerRunUrl}/api/spacer/v1/agent-spaces`,
1426
+ method: 'POST',
1427
+ body: data,
1428
+ });
1429
+ },
1430
+ onSuccess: resp => {
1431
+ if (resp.success && resp.agentSpace) {
1432
+ const agentSpace = resp.agentSpace;
1433
+ // Set detail cache
1434
+ queryClient.setQueryData(queryKeys.agentSpaces.detail(agentSpace.id), agentSpace);
1435
+ // Invalidate all agent space queries
1436
+ queryClient.invalidateQueries({
1437
+ queryKey: queryKeys.agentSpaces.all(),
1438
+ });
1439
+ }
1440
+ },
1441
+ });
1442
+ };
1443
+ /**
1444
+ * Update agent space
1445
+ */
1446
+ const useUpdateAgentSpace = () => {
1447
+ return useMutation({
1448
+ mutationFn: async ({ uid, data, }) => {
1449
+ return requestDatalayer({
1450
+ url: `${configuration.spacerRunUrl}/api/spacer/v1/agent-spaces/${uid}`,
1451
+ method: 'PUT',
1452
+ body: data,
1453
+ });
1454
+ },
1455
+ onSuccess: (resp, { uid }) => {
1456
+ if (resp.success) {
1457
+ // Invalidate detail cache
1458
+ queryClient.invalidateQueries({
1459
+ queryKey: queryKeys.agentSpaces.detail(uid),
1460
+ });
1461
+ // Invalidate all agent space queries
1462
+ queryClient.invalidateQueries({
1463
+ queryKey: queryKeys.agentSpaces.all(),
1464
+ });
1465
+ }
1466
+ },
1467
+ });
1468
+ };
1469
+ /**
1470
+ * Delete agent space
1471
+ */
1472
+ const useDeleteAgentSpace = () => {
1473
+ return useMutation({
1474
+ mutationFn: async (uid) => {
1475
+ return requestDatalayer({
1476
+ url: `${configuration.spacerRunUrl}/api/spacer/v1/agent-spaces/${uid}`,
1477
+ method: 'DELETE',
1478
+ });
1479
+ },
1480
+ onSuccess: () => {
1481
+ // Invalidate all agent space queries
1482
+ queryClient.invalidateQueries({
1483
+ queryKey: queryKeys.agentSpaces.all(),
1484
+ });
1485
+ },
1486
+ });
1487
+ };
1488
+ /**
1489
+ * Make agent space public
1490
+ */
1491
+ const useMakeAgentSpacePublic = () => {
1492
+ return useMutation({
1493
+ mutationFn: async (uid) => {
1494
+ return requestDatalayer({
1495
+ url: `${configuration.spacerRunUrl}/api/spacer/v1/agent-spaces/${uid}/public`,
1496
+ method: 'POST',
1497
+ });
1498
+ },
1499
+ onSuccess: (resp, uid) => {
1500
+ if (resp.success) {
1501
+ queryClient.invalidateQueries({
1502
+ queryKey: queryKeys.agentSpaces.detail(uid),
1503
+ });
1504
+ queryClient.invalidateQueries({
1505
+ queryKey: queryKeys.agentSpaces.all(),
1506
+ });
1507
+ }
1508
+ },
1509
+ });
1510
+ };
1511
+ /**
1512
+ * Make agent space private
1513
+ */
1514
+ const useMakeAgentSpacePrivate = () => {
1515
+ return useMutation({
1516
+ mutationFn: async (uid) => {
1517
+ return requestDatalayer({
1518
+ url: `${configuration.spacerRunUrl}/api/spacer/v1/agent-spaces/${uid}/private`,
1519
+ method: 'POST',
1520
+ });
1521
+ },
1522
+ onSuccess: (resp, uid) => {
1523
+ if (resp.success) {
1524
+ queryClient.invalidateQueries({
1525
+ queryKey: queryKeys.agentSpaces.detail(uid),
1526
+ });
1527
+ queryClient.invalidateQueries({
1528
+ queryKey: queryKeys.agentSpaces.all(),
1529
+ });
1530
+ }
1531
+ },
1532
+ });
1533
+ };
1534
+ /**
1535
+ * Refresh agent space data
1536
+ */
1537
+ const useRefreshAgentSpace = () => {
1538
+ return (uid) => {
1539
+ queryClient.invalidateQueries({
1540
+ queryKey: queryKeys.agentSpaces.detail(uid),
1541
+ });
1542
+ };
1543
+ };
1544
+ /**
1545
+ * Refresh agent spaces list
1546
+ */
1547
+ const useRefreshAgentSpaces = () => {
1548
+ return () => {
1549
+ queryClient.invalidateQueries({
1550
+ queryKey: queryKeys.agentSpaces.all(),
1551
+ });
1552
+ };
1553
+ };
1554
+ /**
1555
+ * Refresh public agent spaces list
1556
+ */
1557
+ const useRefreshPublicAgentSpaces = () => {
1558
+ return () => {
1559
+ queryClient.invalidateQueries({
1560
+ queryKey: queryKeys.agentSpaces.public(),
1561
+ });
1562
+ };
1563
+ };
1564
+ /**
1565
+ * List agent runtimes (runtimes with ai-agents-env environment)
1566
+ */
1567
+ /**
1568
+ * Get all agent runtimes for the current user.
1569
+ *
1570
+ * Note on phase/status mapping:
1571
+ * The backend (operator) RuntimePod model does not include a 'phase' field.
1572
+ * The operator only keeps active/assigned runtimes in its cache (OperatorCache.USER_RUNTIMES),
1573
+ * so any runtime returned by this endpoint is inherently running or starting.
1574
+ * Therefore, if rt.phase is undefined (which it will be), we default to 'running'.
1575
+ * A 'paused' state would require explicit backend support to track paused runtimes.
1576
+ */
1577
+ const useAgentRuntimes = () => {
1578
+ return useQuery({
1579
+ queryKey: queryKeys.agentRuntimes.lists(),
1580
+ queryFn: async () => {
1581
+ const resp = await requestDatalayer({
1582
+ url: `${configuration.runtimesRunUrl}/api/runtimes/v1/runtimes`,
1583
+ method: 'GET',
1584
+ });
1585
+ if (resp.success && resp.runtimes) {
1586
+ // Filter to only include ai-agents-env runtimes
1587
+ const agentRuntimes = resp.runtimes
1588
+ .filter((rt) => rt.environment_name === 'ai-agents-env')
1589
+ .map((rt) => ({
1590
+ ...rt,
1591
+ // Phase/status mapping: see hook JSDoc for details.
1592
+ // Backend returns only active runtimes, so default to 'running'.
1593
+ status: rt.phase === 'Pending'
1594
+ ? 'starting'
1595
+ : rt.phase === 'Terminated'
1596
+ ? 'terminated'
1597
+ : rt.phase === 'Paused'
1598
+ ? 'paused'
1599
+ : rt.phase === 'Archived'
1600
+ ? 'archived'
1601
+ : 'running',
1602
+ name: rt.given_name || rt.pod_name,
1603
+ id: rt.pod_name,
1604
+ // Map ingress URL to url for UI consistency
1605
+ url: rt.ingress,
1606
+ messageCount: 0, // Default for UI compatibility
1607
+ }));
1608
+ // Set detail cache for each runtime
1609
+ agentRuntimes.forEach((runtime) => {
1610
+ queryClient.setQueryData(queryKeys.agentRuntimes.detail(runtime.pod_name), runtime);
1611
+ });
1612
+ return agentRuntimes;
1613
+ }
1614
+ return [];
1615
+ },
1616
+ ...DEFAULT_QUERY_OPTIONS,
1617
+ refetchInterval: 10000, // Refetch every 10 seconds for status updates
1618
+ enabled: !!user,
1619
+ });
1620
+ };
1621
+ /**
1622
+ * Get a single agent runtime by pod name.
1623
+ *
1624
+ * Note on phase/status mapping:
1625
+ * Same as useAgentRuntimes - the backend RuntimePod model has no 'phase' field,
1626
+ * and only active runtimes exist in the operator cache. Default to 'running'.
1627
+ */
1628
+ const useAgentRuntime = (podName) => {
1629
+ return useQuery({
1630
+ queryKey: queryKeys.agentRuntimes.detail(podName ?? ''),
1631
+ queryFn: async () => {
1632
+ const resp = await requestDatalayer({
1633
+ url: `${configuration.runtimesRunUrl}/api/runtimes/v1/runtimes/${podName}`,
1634
+ method: 'GET',
1635
+ });
1636
+ if (resp.runtime) {
1637
+ const rt = resp.runtime;
1638
+ return {
1639
+ ...rt,
1640
+ // Phase/status mapping: see useAgentRuntimes JSDoc for details.
1641
+ status: rt.phase === 'Pending'
1642
+ ? 'starting'
1643
+ : rt.phase === 'Terminated'
1644
+ ? 'terminated'
1645
+ : rt.phase === 'Paused'
1646
+ ? 'paused'
1647
+ : rt.phase === 'Archived'
1648
+ ? 'archived'
1649
+ : 'running',
1650
+ name: rt.given_name || rt.pod_name,
1651
+ id: rt.pod_name,
1652
+ // Map ingress URL to url for UI consistency
1653
+ url: rt.ingress,
1654
+ messageCount: 0,
1655
+ };
1656
+ }
1657
+ throw new Error('Failed to fetch agent runtime');
1658
+ },
1659
+ ...DEFAULT_QUERY_OPTIONS,
1660
+ refetchInterval: 5000, // Refetch every 5 seconds for status
1661
+ enabled: !!podName,
1662
+ });
1663
+ };
1664
+ const useCreateAgentRuntime = () => {
1665
+ return useMutation({
1666
+ mutationFn: async (data) => {
1667
+ return requestDatalayer({
1668
+ url: `${configuration.runtimesRunUrl}/api/runtimes/v1/runtimes`,
1669
+ method: 'POST',
1670
+ body: {
1671
+ environment_name: data.environmentName || 'ai-agents-env',
1672
+ given_name: data.givenName || 'Agent Space',
1673
+ credits_limit: data.creditsLimit || 10,
1674
+ type: data.type || 'notebook',
1675
+ editor_variant: data.editorVariant || 'none',
1676
+ enable_codemode: data.enableCodemode ?? false,
1677
+ },
1678
+ });
1679
+ },
1680
+ onSuccess: resp => {
1681
+ if (resp.success && resp.runtime) {
1682
+ const rt = resp.runtime;
1683
+ // Phase/status mapping: see useAgentRuntimes JSDoc for details.
1684
+ queryClient.setQueryData(queryKeys.agentRuntimes.detail(rt.pod_name), {
1685
+ ...rt,
1686
+ status: rt.phase === 'Pending'
1687
+ ? 'starting'
1688
+ : 'running',
1689
+ name: rt.given_name || rt.pod_name,
1690
+ id: rt.pod_name,
1691
+ // Map ingress URL to url for UI consistency
1692
+ url: rt.ingress,
1693
+ messageCount: 0,
1694
+ });
1695
+ // Invalidate list
1696
+ queryClient.invalidateQueries({
1697
+ queryKey: queryKeys.agentRuntimes.all(),
1698
+ });
1699
+ }
1700
+ },
1701
+ });
1702
+ };
1703
+ /**
1704
+ * Delete agent runtime
1705
+ */
1706
+ const useDeleteAgentRuntime = () => {
1707
+ return useMutation({
1708
+ mutationFn: async (podName) => {
1709
+ return requestDatalayer({
1710
+ url: `${configuration.runtimesRunUrl}/api/runtimes/v1/runtimes/${podName}`,
1711
+ method: 'DELETE',
1712
+ });
1713
+ },
1714
+ onSuccess: (_data, podName) => {
1715
+ // Cancel any in-flight queries for the deleted runtime so they
1716
+ // don't re-fetch a resource that no longer exists.
1717
+ queryClient.cancelQueries({
1718
+ queryKey: queryKeys.agentRuntimes.detail(podName),
1719
+ });
1720
+ // Remove the detail cache entry immediately — prevents React
1721
+ // Query from triggering a stale re-fetch while the component
1722
+ // unmounts.
1723
+ queryClient.removeQueries({
1724
+ queryKey: queryKeys.agentRuntimes.detail(podName),
1725
+ });
1726
+ // Invalidate the list so the sidebar refreshes.
1727
+ queryClient.invalidateQueries({
1728
+ queryKey: queryKeys.agentRuntimes.lists(),
1729
+ });
1730
+ },
1731
+ });
1732
+ };
1733
+ /**
1734
+ * Refresh agent runtimes list
1735
+ */
1736
+ const useRefreshAgentRuntimes = () => {
1737
+ return () => {
1738
+ queryClient.invalidateQueries({
1739
+ queryKey: queryKeys.agentRuntimes.all(),
1740
+ });
1741
+ };
1742
+ };
1743
+ // ============================================================================
1337
1744
  // Notebook Hooks
1338
1745
  // ============================================================================
1339
1746
  /**
@@ -4799,7 +5206,9 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4799
5206
  if (!resp.success) {
4800
5207
  throw new Error(resp.message || 'Failed to search public items');
4801
5208
  }
4802
- return resp.items || [];
5209
+ return (resp.items || [])
5210
+ .map((item) => toItem(item))
5211
+ .filter(Boolean);
4803
5212
  },
4804
5213
  });
4805
5214
  };
@@ -4824,6 +5233,23 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4824
5233
  },
4825
5234
  });
4826
5235
  };
5236
+ /**
5237
+ * Get Google profile from access token
5238
+ */
5239
+ const useGetGoogleProfile = () => {
5240
+ return useMutation({
5241
+ mutationFn: async (accessToken) => {
5242
+ const response = await fetch('https://openidconnect.googleapis.com/v1/userinfo', {
5243
+ method: 'GET',
5244
+ headers: {
5245
+ Accept: 'application/json',
5246
+ Authorization: `Bearer ${accessToken}`,
5247
+ },
5248
+ });
5249
+ return response.json();
5250
+ },
5251
+ });
5252
+ };
4827
5253
  /**
4828
5254
  * Get LinkedIn profile via proxy
4829
5255
  */
@@ -4880,68 +5306,87 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
4880
5306
  const usePostLinkedinShareWithUpload = () => {
4881
5307
  return useMutation({
4882
5308
  mutationFn: async ({ linkedinUserUrn, postText, uploadObject, accessToken, }) => {
4883
- // Step 1: Register upload
4884
- const registerUploadRequest = {
4885
- registerUploadRequest: {
4886
- recipes: ['urn:li:digitalmediaRecipe:feedshare-image'],
4887
- owner: linkedinUserUrn,
4888
- serviceRelationships: [
4889
- {
4890
- relationshipType: 'OWNER',
4891
- identifier: 'urn:li:userGeneratedContent',
4892
- },
4893
- ],
4894
- },
4895
- };
4896
- const registerResp = await requestDatalayer({
4897
- url: `${configuration.iamRunUrl}/api/iam/v1/proxy/request`,
4898
- method: 'POST',
4899
- body: {
4900
- request_method: 'POST',
4901
- request_url: 'https://api.linkedin.com/v2/assets?action=registerUpload',
4902
- request_token: accessToken,
4903
- request_body: registerUploadRequest,
4904
- },
4905
- });
4906
- const asset = registerResp.response.value.asset;
4907
- const uploadUrl = registerResp.response.value.uploadMechanism['com.linkedin.digitalmedia.uploading.MediaUploadHttpRequest'].uploadUrl;
4908
- // Step 2: Upload image
4909
- await requestDatalayer({
4910
- url: `${configuration.iamRunUrl}/api/iam/v1/proxy/request`,
4911
- method: 'POST',
4912
- body: {
4913
- request_method: 'PUT',
4914
- request_url: uploadUrl,
4915
- request_token: accessToken,
4916
- request_body: {
4917
- uploadURL: uploadUrl,
4918
- content: uploadObject,
4919
- userURN: linkedinUserUrn,
4920
- },
4921
- },
4922
- });
4923
- // Step 3: Create share with media
4924
- const shareRequest = {
4925
- author: linkedinUserUrn,
4926
- lifecycleState: 'PUBLISHED',
4927
- specificContent: {
4928
- 'com.linkedin.ugc.ShareContent': {
4929
- shareCommentary: { text: postText },
4930
- shareMediaCategory: 'IMAGE',
4931
- media: [
5309
+ let shareRequest;
5310
+ if (uploadObject) {
5311
+ // Step 1: Register upload
5312
+ const registerUploadRequest = {
5313
+ registerUploadRequest: {
5314
+ recipes: ['urn:li:digitalmediaRecipe:feedshare-image'],
5315
+ owner: linkedinUserUrn,
5316
+ serviceRelationships: [
4932
5317
  {
4933
- status: 'READY',
4934
- description: { text: 'Datalayer Notebook' },
4935
- media: asset,
4936
- title: { text: 'Datalayer Notebook' },
5318
+ relationshipType: 'OWNER',
5319
+ identifier: 'urn:li:userGeneratedContent',
4937
5320
  },
4938
5321
  ],
4939
5322
  },
4940
- },
4941
- visibility: {
4942
- 'com.linkedin.ugc.MemberNetworkVisibility': 'PUBLIC',
4943
- },
4944
- };
5323
+ };
5324
+ const registerResp = await requestDatalayer({
5325
+ url: `${configuration.iamRunUrl}/api/iam/v1/proxy/request`,
5326
+ method: 'POST',
5327
+ body: {
5328
+ request_method: 'POST',
5329
+ request_url: 'https://api.linkedin.com/v2/assets?action=registerUpload',
5330
+ request_token: accessToken,
5331
+ request_body: registerUploadRequest,
5332
+ },
5333
+ });
5334
+ const asset = registerResp.response.value.asset;
5335
+ const uploadUrl = registerResp.response.value.uploadMechanism['com.linkedin.digitalmedia.uploading.MediaUploadHttpRequest'].uploadUrl;
5336
+ // Step 2: Upload image
5337
+ await requestDatalayer({
5338
+ url: `${configuration.iamRunUrl}/api/iam/v1/proxy/request`,
5339
+ method: 'POST',
5340
+ body: {
5341
+ request_method: 'PUT',
5342
+ request_url: uploadUrl,
5343
+ request_token: accessToken,
5344
+ request_body: {
5345
+ uploadURL: uploadUrl,
5346
+ content: uploadObject,
5347
+ userURN: linkedinUserUrn,
5348
+ },
5349
+ },
5350
+ });
5351
+ // Step 3: Create share with media
5352
+ shareRequest = {
5353
+ author: linkedinUserUrn,
5354
+ lifecycleState: 'PUBLISHED',
5355
+ specificContent: {
5356
+ 'com.linkedin.ugc.ShareContent': {
5357
+ shareCommentary: { text: postText },
5358
+ shareMediaCategory: 'IMAGE',
5359
+ media: [
5360
+ {
5361
+ status: 'READY',
5362
+ description: { text: 'Datalayer Notebook' },
5363
+ media: asset,
5364
+ title: { text: 'Datalayer Notebook' },
5365
+ },
5366
+ ],
5367
+ },
5368
+ },
5369
+ visibility: {
5370
+ 'com.linkedin.ugc.MemberNetworkVisibility': 'PUBLIC',
5371
+ },
5372
+ };
5373
+ }
5374
+ else {
5375
+ // Text-only share (no image upload)
5376
+ shareRequest = {
5377
+ author: linkedinUserUrn,
5378
+ lifecycleState: 'PUBLISHED',
5379
+ specificContent: {
5380
+ 'com.linkedin.ugc.ShareContent': {
5381
+ shareCommentary: { text: postText },
5382
+ shareMediaCategory: 'NONE',
5383
+ },
5384
+ },
5385
+ visibility: {
5386
+ 'com.linkedin.ugc.MemberNetworkVisibility': 'PUBLIC',
5387
+ },
5388
+ };
5389
+ }
4945
5390
  return requestDatalayer({
4946
5391
  url: `${configuration.iamRunUrl}/api/iam/v1/proxy/request`,
4947
5392
  method: 'POST',
@@ -5958,6 +6403,7 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
5958
6403
  useOAuth2AuthorizationURL,
5959
6404
  useOAuth2AuthorizationLinkURL,
5960
6405
  useGetGitHubProfile,
6406
+ useGetGoogleProfile,
5961
6407
  useGetLinkedinProfile,
5962
6408
  usePostLinkedinShare,
5963
6409
  usePostLinkedinShareWithUpload,
@@ -6032,6 +6478,24 @@ export const useCache = ({ loginRoute = '/login' } = {}) => {
6032
6478
  useRefreshUserSpace,
6033
6479
  useRefreshLayout,
6034
6480
  useExportSpace,
6481
+ // Agent Spaces
6482
+ useAgentSpace,
6483
+ useAgentSpaces,
6484
+ usePublicAgentSpaces,
6485
+ useCreateAgentSpace,
6486
+ useUpdateAgentSpace,
6487
+ useDeleteAgentSpace,
6488
+ useMakeAgentSpacePublic,
6489
+ useMakeAgentSpacePrivate,
6490
+ useRefreshAgentSpace,
6491
+ useRefreshAgentSpaces,
6492
+ useRefreshPublicAgentSpaces,
6493
+ // Agent Runtimes (runtimes with ai-agents environment)
6494
+ useAgentRuntime,
6495
+ useAgentRuntimes,
6496
+ useCreateAgentRuntime,
6497
+ useDeleteAgentRuntime,
6498
+ useRefreshAgentRuntimes,
6035
6499
  // Courses
6036
6500
  useCourse,
6037
6501
  useUpdateCourse,
@@ -4,13 +4,13 @@
4
4
  */
5
5
  import { useState } from 'react';
6
6
  import { useCellStore } from '../state';
7
- import { takeHTMLNodeScreenshot } from '../utils/Screenshot';
7
+ import { takeHTMLNodeScreencapture } from '../utils/Screencapture';
8
8
  const useCellOutputshot = () => {
9
9
  const [outputshot, setOutputshot] = useState('');
10
10
  const [error, setError] = useState();
11
11
  const { update } = useCellStore();
12
12
  const takeOutputshot = (node) => {
13
- takeHTMLNodeScreenshot(node)
13
+ takeHTMLNodeScreencapture(node)
14
14
  .then(outputshotData => {
15
15
  setOutputshot(outputshotData);
16
16
  update({
@@ -0,0 +1,18 @@
1
+ import { ReactNode } from 'react';
2
+ export type ScreencaptureContextType = {
3
+ closeScreencapture: () => void;
4
+ displayScreencapture: (nextScreencapture: any) => void;
5
+ };
6
+ export declare const ScreencaptureContext: import("react").Context<ScreencaptureContextType>;
7
+ export declare function useScreencapture(): ScreencaptureContextType;
8
+ /**
9
+ * The type for the Screencapture context provider.
10
+ */
11
+ export declare const ScreencaptureContextProvider: import("react").Provider<ScreencaptureContextType>;
12
+ export type IScreencaptureProviderProps = {
13
+ children?: ReactNode;
14
+ zIndex?: number;
15
+ disableDarken?: boolean;
16
+ screenshotSurface?: (qfds: any) => JSX.Element;
17
+ };
18
+ export declare function ScreencaptureProvider({ children, zIndex, disableDarken, screenshotSurface, }: IScreencaptureProviderProps): import("react/jsx-runtime").JSX.Element;