@datalayer/core 1.1.60 → 1.2.10
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 +41 -18
- package/lib/api/DatalayerApi.d.ts +42 -1
- package/lib/api/DatalayerApi.js +90 -3
- package/lib/api/constants.d.ts +19 -1
- package/lib/api/constants.js +19 -1
- package/lib/api/contents/attachments.d.ts +9 -0
- package/lib/api/contents/attachments.js +39 -0
- package/lib/api/contents/bridges.d.ts +22 -0
- package/lib/api/contents/bridges.js +79 -0
- package/lib/api/contents/capabilities.d.ts +11 -0
- package/lib/api/contents/capabilities.js +21 -0
- package/lib/api/contents/cloudStorage.d.ts +31 -0
- package/lib/api/contents/cloudStorage.js +89 -0
- package/lib/api/contents/dataservers.d.ts +37 -0
- package/lib/api/contents/dataservers.js +121 -0
- package/lib/api/contents/datasets.d.ts +63 -0
- package/lib/api/contents/datasets.js +82 -0
- package/lib/api/contents/datasources.d.ts +70 -0
- package/lib/api/contents/datasources.js +149 -0
- package/lib/api/contents/generated.d.ts +1070 -0
- package/lib/api/contents/index.d.ts +16 -0
- package/lib/api/contents/index.js +20 -0
- package/lib/api/contents/mcp.d.ts +46 -0
- package/lib/api/contents/mcp.js +157 -0
- package/lib/api/contents/objects.d.ts +31 -0
- package/lib/api/contents/objects.js +88 -0
- package/lib/api/contents/operations.d.ts +3 -0
- package/lib/api/contents/operations.js +19 -0
- package/lib/api/contents/runtimeMounts.d.ts +40 -0
- package/lib/api/contents/runtimeMounts.js +59 -0
- package/lib/api/contents/sandboxUid.d.ts +21 -0
- package/lib/api/contents/sandboxUid.js +27 -0
- package/lib/api/contents/sources.d.ts +19 -0
- package/lib/api/contents/sources.js +119 -0
- package/lib/api/contents/sync.d.ts +18 -0
- package/lib/api/contents/sync.js +69 -0
- package/lib/api/contents/transfers.d.ts +38 -0
- package/lib/api/contents/transfers.js +123 -0
- package/lib/api/evals/client.d.ts +402 -0
- package/lib/api/evals/client.js +359 -0
- package/lib/api/evals/index.d.ts +10 -0
- package/lib/api/evals/index.js +18 -0
- package/lib/api/evals/request.d.ts +43 -0
- package/lib/api/evals/request.js +67 -0
- package/lib/api/evals/status.d.ts +27 -0
- package/lib/api/evals/status.js +122 -0
- package/lib/api/evals/types.d.ts +1335 -0
- package/lib/api/evals/types.js +5 -0
- package/lib/api/iam/connectedAgents.d.ts +68 -0
- package/lib/api/iam/connectedAgents.js +87 -0
- package/lib/api/iam/identityProviders.d.ts +76 -0
- package/lib/api/iam/identityProviders.js +187 -0
- package/lib/api/iam/index.d.ts +3 -1
- package/lib/api/iam/index.js +3 -1
- package/lib/api/iam/mcpAlertRules.d.ts +51 -0
- package/lib/api/iam/mcpAlertRules.js +198 -0
- package/lib/api/iam/mcpAuditSettings.d.ts +46 -0
- package/lib/api/iam/mcpAuditSettings.js +120 -0
- package/lib/api/iam/mcpPolicy.d.ts +181 -0
- package/lib/api/iam/mcpPolicy.js +168 -0
- package/lib/api/iam/organizationTeams.d.ts +13 -0
- package/lib/api/iam/organizationTeams.js +43 -0
- package/lib/api/iam/profile.d.ts +17 -1
- package/lib/api/iam/profile.js +27 -0
- package/lib/api/iam/scimTokens.d.ts +79 -0
- package/lib/api/iam/scimTokens.js +141 -0
- package/lib/api/iam/secrets.js +9 -21
- package/lib/api/iam/serviceAgents.d.ts +68 -0
- package/lib/api/iam/serviceAgents.js +119 -0
- package/lib/api/iam/trials.d.ts +38 -0
- package/lib/api/iam/trials.js +66 -0
- package/lib/api/index.d.ts +8 -1
- package/lib/api/index.js +7 -1
- package/lib/api/mcp/activity.d.ts +37 -0
- package/lib/api/mcp/activity.js +26 -0
- package/lib/api/mcp/alerts.d.ts +25 -0
- package/lib/api/mcp/alerts.js +51 -0
- package/lib/api/mcp/audit.d.ts +29 -0
- package/lib/api/mcp/audit.js +55 -0
- package/lib/api/mcp/bindings.d.ts +18 -0
- package/lib/api/mcp/bindings.js +42 -0
- package/lib/api/mcp/forwarding.d.ts +25 -0
- package/lib/api/mcp/forwarding.js +46 -0
- package/lib/api/mcp/gateway.d.ts +16 -0
- package/lib/api/mcp/gateway.js +70 -0
- package/lib/api/mcp/generated.d.ts +22 -0
- package/lib/api/mcp/generated.js +213 -0
- package/lib/api/mcp/index.d.ts +17 -0
- package/lib/api/mcp/index.js +25 -0
- package/lib/api/mcp/observability.d.ts +141 -0
- package/lib/api/mcp/observability.js +267 -0
- package/lib/api/mcp/operations.d.ts +83 -0
- package/lib/api/mcp/operations.js +50 -0
- package/lib/api/mcp/organizations.d.ts +102 -0
- package/lib/api/mcp/organizations.js +46 -0
- package/lib/api/mcp/policy.d.ts +9 -0
- package/lib/api/mcp/policy.js +23 -0
- package/lib/api/mcp/tasks.d.ts +49 -0
- package/lib/api/mcp/tasks.js +147 -0
- package/lib/api/orchestration/client.d.ts +53 -0
- package/lib/api/orchestration/client.js +105 -0
- package/lib/api/orchestration/events.d.ts +88 -0
- package/lib/api/orchestration/events.js +245 -0
- package/lib/api/orchestration/generated.d.ts +693 -0
- package/lib/api/orchestration/generated.js +687 -0
- package/lib/api/orchestration/index.d.ts +30 -0
- package/lib/api/orchestration/index.js +34 -0
- package/lib/api/orchestration/lifecycle.d.ts +39 -0
- package/lib/api/orchestration/lifecycle.js +57 -0
- package/lib/api/orchestration/measures.d.ts +55 -0
- package/lib/api/orchestration/measures.js +99 -0
- package/lib/api/otel/dashboards.d.ts +56 -0
- package/lib/api/otel/dashboards.js +50 -0
- package/lib/api/otel/index.d.ts +1 -0
- package/lib/api/otel/index.js +1 -0
- package/lib/api/otel/metrics.d.ts +16 -0
- package/lib/api/otel/metrics.js +15 -0
- package/lib/api/scheduler/client.d.ts +32 -0
- package/lib/api/scheduler/client.js +42 -0
- package/lib/api/scheduler/index.d.ts +8 -0
- package/lib/api/scheduler/index.js +16 -0
- package/lib/api/scheduler/request.d.ts +28 -0
- package/lib/api/scheduler/request.js +50 -0
- package/lib/api/scheduler/types.d.ts +88 -0
- package/lib/api/scheduler/types.js +5 -0
- package/lib/api/spacer/comments.d.ts +97 -0
- package/lib/api/spacer/comments.js +45 -0
- package/lib/api/spacer/index.d.ts +9 -0
- package/lib/api/spacer/index.js +17 -0
- package/lib/api/spacer/notebooks.d.ts +33 -0
- package/lib/api/spacer/notebooks.js +39 -0
- package/lib/api/spacer/request.d.ts +25 -0
- package/lib/api/spacer/request.js +46 -0
- package/lib/api/spacer/spaces.d.ts +68 -0
- package/lib/api/spacer/spaces.js +45 -0
- package/lib/api/utils/validation.d.ts +4 -4
- package/lib/api/utils/validation.js +10 -7
- package/lib/client/auth/index.js +0 -5
- package/lib/client/auth/storage.js +0 -5
- package/lib/client/auth/strategies.js +0 -5
- package/lib/client/base.d.ts +6 -0
- package/lib/client/base.js +8 -0
- package/lib/client/constants.d.ts +1 -0
- package/lib/client/constants.js +1 -0
- package/lib/client/index.d.ts +0 -10
- package/lib/client/index.js +2 -2
- package/lib/client/mixins/ContentsMixin.d.ts +71 -0
- package/lib/client/mixins/ContentsMixin.js +157 -0
- package/lib/client/mixins/IAMMixin.d.ts +0 -31
- package/lib/client/mixins/IAMMixin.js +0 -58
- package/lib/components/animation/AnimatedText.d.ts +2 -44
- package/lib/components/animation/AnimatedText.js +6 -126
- package/lib/components/anonymous/AnonymousKeyExpired.d.ts +56 -0
- package/lib/components/anonymous/AnonymousKeyExpired.js +96 -0
- package/lib/components/anonymous/AnonymousKeyTimer.d.ts +63 -0
- package/lib/components/anonymous/AnonymousKeyTimer.js +140 -0
- package/lib/components/anonymous/index.d.ts +7 -0
- package/lib/components/anonymous/index.js +15 -0
- package/lib/components/auth/SigInAPIKey.d.ts +1 -0
- package/lib/components/auth/SigInAPIKey.js +0 -6
- package/lib/components/auth/SignIn.d.ts +1 -0
- package/lib/components/auth/SignIn.js +0 -4
- package/lib/components/auth/SignIn.stories.d.ts +2 -2
- package/lib/components/avatars/BoringAvatar.d.ts +1 -1
- package/lib/components/avatars/BoringAvatar.stories.d.ts +1 -1
- package/lib/components/avatars/DLAvatar.d.ts +1 -1
- package/lib/components/avatars/DLAvatar.js +0 -4
- package/lib/components/avatars/UserAvatar.d.ts +16 -1
- package/lib/components/avatars/UserAvatar.js +15 -13
- package/lib/components/avatars/UserProfileAvatar.d.ts +1 -1
- package/lib/components/banners/NoAutomationBanner.d.ts +1 -1
- package/lib/components/billing/BillingEntitySelect.d.ts +16 -0
- package/lib/components/billing/BillingEntitySelect.js +49 -27
- package/lib/components/billing/eligibility.d.ts +22 -0
- package/lib/components/billing/eligibility.js +27 -0
- package/lib/components/billing/index.d.ts +1 -0
- package/lib/components/billing/index.js +1 -4
- package/lib/components/buttons/DownloadCSVButton.d.ts +1 -1
- package/lib/components/buttons/DownloadJsonButton.d.ts +1 -1
- package/lib/components/buttons/LongActionButton.d.ts +1 -0
- package/lib/components/buttons/LongActionButton.js +0 -4
- package/lib/components/buttons/UploadButton.d.ts +1 -0
- package/lib/components/buttons/UploadButton.js +0 -4
- package/lib/components/checkout/StripeCheckout.d.ts +1 -1
- package/lib/components/collaboration/LiveEditorCollaborators.d.ts +36 -0
- package/lib/components/collaboration/LiveEditorCollaborators.js +88 -53
- package/lib/components/collaboration/index.js +0 -4
- package/lib/components/confetti/ConfettiSuccess.d.ts +1 -1
- package/lib/components/contents/ContentSourceCard.d.ts +8 -0
- package/lib/components/contents/ContentSourceCard.js +23 -0
- package/lib/components/contents/HomeFolderObjectsBrowser.d.ts +10 -0
- package/lib/components/contents/HomeFolderObjectsBrowser.js +148 -0
- package/lib/components/contents/index.d.ts +2 -0
- package/lib/components/contents/index.js +6 -0
- package/lib/components/context/OrganizationSelect.d.ts +1 -1
- package/lib/components/display/AvatarSkeleton.d.ts +1 -1
- package/lib/components/display/BusyDots.d.ts +1 -1
- package/lib/components/display/CenteredSpinner.d.ts +1 -1
- package/lib/components/display/CodePreview.d.ts +1 -1
- package/lib/components/display/DatalayerBox.d.ts +7 -3
- package/lib/components/display/DatalayerBox.js +7 -7
- package/lib/components/display/HorizontalCenter.d.ts +1 -1
- package/lib/components/display/JupyterDialog.d.ts +1 -0
- package/lib/components/display/JupyterDialog.js +1 -7
- package/lib/components/display/Markdown.d.ts +1 -0
- package/lib/components/display/NavLink.js +3 -2
- package/lib/components/display/NotebookSkeleton.d.ts +1 -1
- package/lib/components/display/Placeholder.d.ts +1 -1
- package/lib/components/display/ToTopBranded.d.ts +1 -1
- package/lib/components/echarts/EChartsReact.d.ts +1 -1
- package/lib/components/flashes/FlashClosable.d.ts +1 -0
- package/lib/components/flashes/FlashClosable.js +0 -4
- package/lib/components/flashes/FlashGuest.d.ts +1 -1
- package/lib/components/flashes/FlashSurveys.d.ts +1 -1
- package/lib/components/flashes/FlashUnauthorized.d.ts +1 -0
- package/lib/components/flashes/FlashUnauthorized.js +0 -6
- package/lib/components/flashes/surveys/Survey2025_1.d.ts +1 -1
- package/lib/components/iam/ExternalTokenSilentLogin.d.ts +1 -1
- package/lib/components/index.d.ts +2 -0
- package/lib/components/index.js +2 -0
- package/lib/components/labels/StatusLabels.d.ts +2 -9
- package/lib/components/labels/StatusLabels.js +2 -26
- package/lib/components/labels/VisibilityLabel.d.ts +1 -1
- package/lib/components/landings/StepBlock.d.ts +1 -1
- package/lib/components/mcp/ClientBadge.d.ts +41 -0
- package/lib/components/mcp/ClientBadge.js +33 -0
- package/lib/components/mcp/McpErrorBlankslate.d.ts +21 -0
- package/lib/components/mcp/McpErrorBlankslate.js +17 -0
- package/lib/components/mcp/ScopeList.d.ts +28 -0
- package/lib/components/mcp/ScopeList.js +14 -0
- package/lib/components/mcp/index.d.ts +10 -0
- package/lib/components/mcp/index.js +18 -0
- package/lib/components/navbar/NavigationVisbilityObserver.d.ts +2 -1
- package/lib/components/navbar/SubdomainNavBar.d.ts +10 -5
- package/lib/components/navbar/SubdomainNavBar.js +2 -1
- package/lib/components/notebooks/JupyterNotebook.d.ts +1 -1
- package/lib/components/notebooks/JupyterNotebookToolbar.d.ts +1 -1
- package/lib/components/principal/PrincipalAppearance.d.ts +22 -42
- package/lib/components/principal/PrincipalAppearance.js +232 -182
- package/lib/components/principal/PrincipalAvatar.d.ts +9 -1
- package/lib/components/principal/PrincipalAvatar.js +18 -10
- package/lib/components/principal/PrincipalBadge.d.ts +1 -1
- package/lib/components/principal/PrincipalBanner.d.ts +1 -1
- package/lib/components/principal/PrincipalDetailsOverlay.d.ts +38 -1
- package/lib/components/principal/PrincipalDetailsOverlay.js +64 -33
- package/lib/components/principal/PrincipalHoverCard.d.ts +31 -0
- package/lib/components/principal/PrincipalHoverCard.js +52 -0
- package/lib/components/principal/PrincipalSwitcherMenu.d.ts +1 -0
- package/lib/components/principal/PrincipalSwitcherMenu.js +5 -14
- package/lib/components/principal/index.d.ts +2 -1
- package/lib/components/principal/index.js +2 -1
- package/lib/components/progress/ConsumptionBar.d.ts +1 -0
- package/lib/components/progress/ConsumptionBar.js +0 -4
- package/lib/components/progress/ProgressRing.d.ts +1 -0
- package/lib/components/progress/SpinnerBar.d.ts +1 -1
- package/lib/components/progress/Timer.d.ts +1 -0
- package/lib/components/progress/Timer.js +0 -4
- package/lib/components/screencapture/Screencapture.js +46 -3
- package/lib/components/screencapture/ScreencaptureButton.d.ts +1 -1
- package/lib/components/sharing/ShareAccessComponent.d.ts +58 -3
- package/lib/components/sharing/ShareAccessComponent.js +143 -98
- package/lib/components/sharing/SharingEditor.d.ts +21 -0
- package/lib/components/sharing/SharingEditor.js +9 -28
- package/lib/components/sharing/index.d.ts +1 -0
- package/lib/components/sharing/index.js +1 -0
- package/lib/components/sharing/sandboxSharing.d.ts +26 -0
- package/lib/components/sharing/sandboxSharing.js +41 -0
- package/lib/components/spaces/SpaceDetailsOverlay.d.ts +39 -0
- package/lib/components/spaces/SpaceDetailsOverlay.js +80 -0
- package/lib/components/spaces/SpaceDisplay.d.ts +38 -0
- package/lib/components/spaces/SpaceDisplay.js +92 -0
- package/lib/components/spaces/index.d.ts +4 -0
- package/lib/components/spaces/index.js +7 -0
- package/lib/components/spaces/spaceDisplayModel.d.ts +93 -0
- package/lib/components/spaces/spaceDisplayModel.js +170 -0
- package/lib/components/sparklines/Sparklines.js +3 -4
- package/lib/components/sparklines/index.js +0 -4
- package/lib/components/storage/ContentsBrowser.d.ts +25 -1
- package/lib/components/storage/ContentsBrowser.js +145 -52
- package/lib/components/storage/ContentsBrowserMock.d.ts +3 -0
- package/lib/components/storage/ContentsBrowserMock.js +75 -0
- package/lib/components/storage/ContentsItems.d.ts +2 -1
- package/lib/components/storage/ContentsItems.js +0 -4
- package/lib/components/storage/ContentsTable.d.ts +50 -0
- package/lib/components/storage/ContentsTable.js +134 -0
- package/lib/components/storage/HomeFolderDrive.d.ts +71 -0
- package/lib/components/storage/HomeFolderDrive.js +248 -0
- package/lib/components/storage/index.d.ts +2 -0
- package/lib/components/storage/index.js +2 -0
- package/lib/components/students/StudentItemStatus.d.ts +1 -1
- package/lib/components/students/StudentResultCircle.d.ts +1 -1
- package/lib/components/subnav/SubNav.d.ts +5 -5
- package/lib/components/subnav/SubNav.js +11 -9
- package/lib/components/tables/DataTable.d.ts +1 -1
- package/lib/components/text-reveal/TextRevealAnimation.d.ts +2 -2
- package/lib/components/text-reveal/useTextRevealAnimationLines.d.ts +1 -1
- package/lib/components/time/LiveRelativeTime.d.ts +1 -0
- package/lib/components/time/LiveRelativeTime.js +0 -8
- package/lib/components/time/index.js +0 -4
- package/lib/components/timeline/Timeline.d.ts +1 -1
- package/lib/components/timeline/index.js +0 -4
- package/lib/components/users/PeerIndicator.d.ts +1 -0
- package/lib/components/users/PeerIndicator.js +0 -4
- package/lib/config/Configuration.d.ts +15 -17
- package/lib/config/Configuration.js +7 -0
- package/lib/hooks/cacheConverters.d.ts +0 -7
- package/lib/hooks/cacheConverters.js +0 -25
- package/lib/hooks/index.d.ts +3 -0
- package/lib/hooks/index.js +3 -0
- package/lib/hooks/layouts/LayoutBackdrop.d.ts +1 -1
- package/lib/hooks/layouts/LayoutScreencapture.d.ts +1 -1
- package/lib/hooks/useBackdrop.d.ts +1 -1
- package/lib/hooks/useBackdropJupyterLab.d.ts +3 -2
- package/lib/hooks/useBackdropJupyterLab.js +0 -4
- package/lib/hooks/useBillingEntityStore.js +3 -0
- package/lib/hooks/useCache.d.ts +478 -130
- package/lib/hooks/useCache.js +1580 -676
- package/lib/hooks/useContainsFocus.d.ts +1 -1
- package/lib/hooks/useContents.d.ts +334 -0
- package/lib/hooks/useContents.js +1033 -0
- package/lib/hooks/useFocusTrap.d.ts +4 -4
- package/lib/hooks/useFocusTrap.js +1 -1
- package/lib/hooks/useMcp.d.ts +315 -0
- package/lib/hooks/useMcp.js +891 -0
- package/lib/hooks/useMobile.js +0 -5
- package/lib/hooks/useNavigate.d.ts +41 -3
- package/lib/hooks/useNavigate.js +106 -52
- package/lib/hooks/usePrincipalCacheStore.js +3 -0
- package/lib/hooks/usePrincipalStore.js +3 -0
- package/lib/hooks/useProjectStore.d.ts +3 -3
- package/lib/hooks/useProjectStore.js +4 -4
- package/lib/hooks/useRef.d.ts +1 -1
- package/lib/hooks/useRef.js +3 -0
- package/lib/hooks/useScreencapture.d.ts +2 -1
- package/lib/hooks/useScreencapture.js +0 -4
- package/lib/hooks/useSpaceCacheStore.d.ts +50 -0
- package/lib/hooks/useSpaceCacheStore.js +85 -0
- package/lib/hooks/useToast.js +0 -4
- package/lib/hooks/useVisibilityObserver.d.ts +1 -1
- package/lib/index.d.ts +4 -1
- package/lib/index.js +3 -1
- package/lib/mocks/components/FlashMock.d.ts +1 -1
- package/lib/mocks/views/ActionMenuMock.d.ts +1 -1
- package/lib/mocks/views/ChartMock.d.ts +1 -1
- package/lib/mocks/views/DashboardMock.d.ts +1 -1
- package/lib/mocks/views/FormMock.d.ts +1 -1
- package/lib/mocks/views/TableMock.d.ts +1 -1
- package/lib/mocks/views/WipMock.d.ts +1 -1
- package/lib/models/Credits.d.ts +16 -0
- package/lib/models/Credits.js +22 -0
- package/lib/models/CreditsDTO.d.ts +6 -5
- package/lib/models/CreditsDTO.js +7 -5
- package/lib/models/McpAuditEvent.d.ts +52 -0
- package/lib/models/McpAuditEvent.js +5 -0
- package/lib/models/McpBinding.d.ts +57 -0
- package/lib/models/McpBinding.js +5 -0
- package/lib/models/McpPolicy.d.ts +77 -0
- package/lib/models/McpPolicy.js +5 -0
- package/lib/models/McpTask.d.ts +94 -0
- package/lib/models/McpTask.js +7 -0
- package/lib/models/Organization.d.ts +69 -0
- package/lib/models/Organization.js +96 -0
- package/lib/models/Secret.d.ts +1 -2
- package/lib/models/Secret.js +2 -18
- package/lib/models/StartedBy.d.ts +91 -0
- package/lib/models/StartedBy.js +117 -0
- package/lib/models/Team.d.ts +2 -0
- package/lib/models/Team.js +2 -0
- package/lib/models/User.d.ts +4 -0
- package/lib/models/User.js +3 -0
- package/lib/models/UserDTO.js +4 -2
- package/lib/models/UserSettings.d.ts +13 -0
- package/lib/models/UserSettings.js +9 -0
- package/lib/models/contents/__fixtures__/solr-codec.json +57 -0
- package/lib/models/contents/__fixtures__/v1-contracts.json +194 -0
- package/lib/models/contents/fieldCase.d.ts +8 -0
- package/lib/models/contents/fieldCase.js +37 -0
- package/lib/models/contents/index.d.ts +2 -0
- package/lib/models/contents/index.js +6 -0
- package/lib/models/contents/permissions.d.ts +16 -0
- package/lib/models/contents/permissions.js +34 -0
- package/lib/models/index.d.ts +5 -1
- package/lib/models/index.js +5 -1
- package/lib/navigation/components.js +2 -3
- package/lib/routes/publicPaths.js +4 -0
- package/lib/state/index.d.ts +1 -0
- package/lib/state/index.js +1 -0
- package/lib/state/sessionEnd.d.ts +55 -0
- package/lib/state/sessionEnd.js +162 -0
- package/lib/state/substates/CoreState.d.ts +15 -7
- package/lib/state/substates/CoreState.js +21 -17
- package/lib/state/substates/IAMState.d.ts +1 -1
- package/lib/state/substates/IAMState.js +12 -5
- package/lib/state/substates/LayoutState.js +12 -0
- package/lib/state/substates/ProfileState.d.ts +1 -0
- package/lib/state/substates/ProfileState.js +1 -4
- package/lib/state/substates/index.d.ts +0 -1
- package/lib/state/substates/index.js +0 -1
- package/lib/utils/Jwt.d.ts +26 -0
- package/lib/utils/Jwt.js +37 -0
- package/lib/utils/Lazy.d.ts +20 -0
- package/lib/utils/Lazy.js +32 -6
- package/lib/utils/Screencapture.js +3 -0
- package/lib/utils/WithSuspense.d.ts +11 -1
- package/lib/utils/WithSuspense.js +11 -1
- package/lib/views/api-keys/APIKeyEdit.d.ts +1 -1
- package/lib/views/api-keys/APIKeyNew.d.ts +1 -1
- package/lib/views/api-keys/APIKeys.d.ts +1 -1
- package/lib/views/api-keys/APIKeys.js +30 -4
- package/lib/views/api-keys/APIKeysStandalone.d.ts +5 -1
- package/lib/views/api-keys/APIKeysStandalone.js +2 -2
- package/lib/views/datasources/DatasourceDetail.d.ts +12 -5
- package/lib/views/datasources/DatasourceDetail.js +80 -110
- package/lib/views/datasources/DatasourceNew.d.ts +14 -8
- package/lib/views/datasources/DatasourceNew.js +129 -118
- package/lib/views/datasources/Datasources.d.ts +39 -7
- package/lib/views/datasources/Datasources.js +95 -40
- package/lib/views/datasources/DatasourcesMock.d.ts +3 -0
- package/lib/views/datasources/DatasourcesMock.js +57 -0
- package/lib/views/iam/SignInSimple.d.ts +12 -0
- package/lib/views/iam/SignInSimple.js +4 -4
- package/lib/views/index.d.ts +1 -0
- package/lib/views/index.js +1 -0
- package/lib/views/mcp/AdmittedClients.d.ts +44 -0
- package/lib/views/mcp/AdmittedClients.js +59 -0
- package/lib/views/mcp/AlertDestinations.d.ts +34 -0
- package/lib/views/mcp/AlertDestinations.js +75 -0
- package/lib/views/mcp/AlertRules.d.ts +32 -0
- package/lib/views/mcp/AlertRules.js +245 -0
- package/lib/views/mcp/ApprovalQueue.d.ts +66 -0
- package/lib/views/mcp/ApprovalQueue.js +95 -0
- package/lib/views/mcp/AuditLog.d.ts +42 -0
- package/lib/views/mcp/AuditLog.js +144 -0
- package/lib/views/mcp/ConnectedAgents.d.ts +34 -0
- package/lib/views/mcp/ConnectedAgents.js +135 -0
- package/lib/views/mcp/EnterpriseConsole.d.ts +74 -0
- package/lib/views/mcp/EnterpriseConsole.js +195 -0
- package/lib/views/mcp/IdentityProviders.d.ts +33 -0
- package/lib/views/mcp/IdentityProviders.js +299 -0
- package/lib/views/mcp/McpDashboard.d.ts +50 -0
- package/lib/views/mcp/McpDashboard.js +430 -0
- package/lib/views/mcp/McpHome.d.ts +92 -0
- package/lib/views/mcp/McpHome.js +153 -0
- package/lib/views/mcp/McpObservability.d.ts +79 -0
- package/lib/views/mcp/McpObservability.js +236 -0
- package/lib/views/mcp/NotebookRuns.d.ts +39 -0
- package/lib/views/mcp/NotebookRuns.js +44 -0
- package/lib/views/mcp/OrganizationPolicy.d.ts +45 -0
- package/lib/views/mcp/OrganizationPolicy.js +108 -0
- package/lib/views/mcp/OrganizationUsage.d.ts +69 -0
- package/lib/views/mcp/OrganizationUsage.js +113 -0
- package/lib/views/mcp/PersonalPolicy.d.ts +54 -0
- package/lib/views/mcp/PersonalPolicy.js +126 -0
- package/lib/views/mcp/Policies.d.ts +53 -0
- package/lib/views/mcp/Policies.js +210 -0
- package/lib/views/mcp/PolicyForm.d.ts +83 -0
- package/lib/views/mcp/PolicyForm.js +113 -0
- package/lib/views/mcp/PolicyHistory.d.ts +58 -0
- package/lib/views/mcp/PolicyHistory.js +75 -0
- package/lib/views/mcp/RunDetail.d.ts +87 -0
- package/lib/views/mcp/RunDetail.js +186 -0
- package/lib/views/mcp/ScimProvisioning.d.ts +54 -0
- package/lib/views/mcp/ScimProvisioning.js +173 -0
- package/lib/views/mcp/ServiceAgents.d.ts +46 -0
- package/lib/views/mcp/ServiceAgents.js +194 -0
- package/lib/views/mcp/TeamPolicies.d.ts +33 -0
- package/lib/views/mcp/TeamPolicies.js +159 -0
- package/lib/views/mcp/ToolAccess.d.ts +60 -0
- package/lib/views/mcp/ToolAccess.js +101 -0
- package/lib/views/mcp/TraceTimeline.d.ts +81 -0
- package/lib/views/mcp/TraceTimeline.js +132 -0
- package/lib/views/mcp/format.d.ts +25 -0
- package/lib/views/mcp/format.js +77 -0
- package/lib/views/mcp/index.d.ts +34 -0
- package/lib/views/mcp/index.js +42 -0
- package/lib/views/mcp/types.d.ts +66 -0
- package/lib/views/mcp/types.js +5 -0
- package/lib/views/otel/simpleAuthStore.js +3 -0
- package/lib/views/secrets/SecretEdit.d.ts +5 -1
- package/lib/views/secrets/SecretEdit.js +5 -4
- package/lib/views/secrets/SecretNew.d.ts +11 -1
- package/lib/views/secrets/SecretNew.js +7 -3
- package/lib/views/secrets/Secrets.d.ts +12 -1
- package/lib/views/secrets/Secrets.js +2 -2
- package/package.json +269 -260
- package/scripts/generate-contents-types.py +169 -0
- package/scripts/generate-mcp-types.py +233 -0
- package/scripts/generate-orchestration-types.py +920 -0
- package/lib/api/iam/datasources.d.ts +0 -86
- package/lib/api/iam/datasources.js +0 -185
- package/lib/components/toolbars/index.d.ts +0 -1
- package/lib/models/Datasource.d.ts +0 -181
- package/lib/models/Datasource.js +0 -154
- package/lib/state/substates/DatasourceState.d.ts +0 -11
- package/lib/state/substates/DatasourceState.js +0 -16
- /package/lib/{components/toolbars/index.js → api/contents/generated.js} +0 -0
|
@@ -0,0 +1,891 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2023-2025 Datalayer, Inc.
|
|
3
|
+
* Distributed under the terms of the Modified BSD License.
|
|
4
|
+
*/
|
|
5
|
+
/*
|
|
6
|
+
* Copyright (c) 2023-2026 Datalayer, Inc.
|
|
7
|
+
* Distributed under the terms of the Modified BSD License.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Hooks over the Jupyter MCP Server, IAM's connected agents and the OTEL
|
|
11
|
+
* service, in the `useContents.ts` shape: `enabled` on token and URL,
|
|
12
|
+
* `staleTime` per resource, filters in the query key, mutations that
|
|
13
|
+
* `setQueryData` and invalidate.
|
|
14
|
+
*
|
|
15
|
+
* Polling by predicate: a task refetches every two seconds while it is not
|
|
16
|
+
* terminal and stops when it is; the activity answer every ten seconds as
|
|
17
|
+
* the fallback under the websocket; audit and policy on demand. An open
|
|
18
|
+
* Runs panel subscribes to the task's server-sent events instead.
|
|
19
|
+
*
|
|
20
|
+
* @module hooks/useMcp
|
|
21
|
+
*/
|
|
22
|
+
import { useEffect } from 'react';
|
|
23
|
+
import { useMutation, useQueries, useQuery, useQueryClient, } from '@tanstack/react-query';
|
|
24
|
+
import { answerTask, cancelTask, exportAuditEvents, fetchMcpLogs, fetchMcpMetrics, fetchRunTrace, fetchTraceSpans, getEffectivePolicy, getGatewayVersion, getMcpActivity, getOrganizationMcpOverview, getOrganizationMcpUsage, getTask, getWorkflowsHealth, isMcpTaskTerminal, listAuditEvents, listBindings, listNotebookTasks, listTasks, listWorkers, subscribeTaskEvents, terminateBinding, } from '../api/mcp/index.js';
|
|
25
|
+
import { disconnectAgent, disconnectEveryAgent, disconnectEveryAgentInTeam, listConnectedAgents, } from '../api/iam/connectedAgents.js';
|
|
26
|
+
import { listOrganizationTeams, } from '../api/iam/organizationTeams.js';
|
|
27
|
+
import { getAuditSettings, setAuditSettings, } from '../api/iam/mcpAuditSettings.js';
|
|
28
|
+
import { getMcpForwarding } from '../api/mcp/forwarding.js';
|
|
29
|
+
import { testAlertRule } from '../api/mcp/alerts.js';
|
|
30
|
+
import { createAlertRule, deleteAlertRule, listAlertRules, updateAlertRule, } from '../api/iam/mcpAlertRules.js';
|
|
31
|
+
import { createIdentityProvider, deleteIdentityProvider, disableIdentityProvider, enableIdentityProvider, getDomainVerification, listIdentityProviders, updateIdentityProvider, verifyDomain, } from '../api/iam/identityProviders.js';
|
|
32
|
+
import { createScimToken, listScimTokens, revokeScimToken, rotateScimToken, } from '../api/iam/scimTokens.js';
|
|
33
|
+
import { deleteMcpPolicy, getAdmittedClients, getMcpPolicy, setMcpPolicy, } from '../api/iam/mcpPolicy.js';
|
|
34
|
+
import { createServiceAgent, listServiceAgents, revokeServiceAgent, rotateServiceAgentKey, } from '../api/iam/serviceAgents.js';
|
|
35
|
+
import { useCoreStore, useIAMStore } from '../state/index.js';
|
|
36
|
+
import { queryKeys } from './useCache.js';
|
|
37
|
+
const useMcpServerUrl = () => useCoreStore(state => state.configuration.jupyterMcpServerUrl);
|
|
38
|
+
const useIamUrl = () => useCoreStore(state => state.configuration.iamUrl);
|
|
39
|
+
const useOtelUrl = () => useCoreStore(state => state.configuration.otelUrl);
|
|
40
|
+
// -- Tasks -----------------------------------------------------------------
|
|
41
|
+
export const useTasks = (filters = {}, options = {}) => {
|
|
42
|
+
const token = useIAMStore(state => state.token);
|
|
43
|
+
const mcpUrl = useMcpServerUrl();
|
|
44
|
+
return useQuery({
|
|
45
|
+
queryKey: queryKeys.mcp.taskList(filters),
|
|
46
|
+
queryFn: () => listTasks(token ?? '', filters, mcpUrl),
|
|
47
|
+
enabled: Boolean(token && mcpUrl) && (options.enabled ?? true),
|
|
48
|
+
staleTime: 5_000,
|
|
49
|
+
refetchInterval: filters.status && !isMcpTaskTerminal(filters.status) ? 5_000 : false,
|
|
50
|
+
});
|
|
51
|
+
};
|
|
52
|
+
/** One task, polled every two seconds until it is terminal. */
|
|
53
|
+
export const useTask = (taskUid) => {
|
|
54
|
+
const token = useIAMStore(state => state.token);
|
|
55
|
+
const mcpUrl = useMcpServerUrl();
|
|
56
|
+
return useQuery({
|
|
57
|
+
queryKey: queryKeys.mcp.task(taskUid ?? ''),
|
|
58
|
+
queryFn: () => getTask(token ?? '', taskUid, mcpUrl),
|
|
59
|
+
enabled: Boolean(token && mcpUrl && taskUid),
|
|
60
|
+
refetchInterval: query => query.state.data && isMcpTaskTerminal(query.state.data.status)
|
|
61
|
+
? false
|
|
62
|
+
: 2_000,
|
|
63
|
+
});
|
|
64
|
+
};
|
|
65
|
+
export const useNotebookTasks = (notebookUid, filters = {}) => {
|
|
66
|
+
const token = useIAMStore(state => state.token);
|
|
67
|
+
const mcpUrl = useMcpServerUrl();
|
|
68
|
+
return useQuery({
|
|
69
|
+
queryKey: queryKeys.mcp.notebookTasks(notebookUid ?? '', filters),
|
|
70
|
+
queryFn: () => listNotebookTasks(token ?? '', notebookUid, filters, mcpUrl),
|
|
71
|
+
enabled: Boolean(token && mcpUrl && notebookUid),
|
|
72
|
+
staleTime: 5_000,
|
|
73
|
+
});
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* The task's server-sent events, patched into the task's cache entry so
|
|
77
|
+
* every `useTask` of it updates without polling. Ends by itself when the
|
|
78
|
+
* task is terminal; the subscription closes with the component.
|
|
79
|
+
*/
|
|
80
|
+
export const useTaskEvents = (taskUid, options = {}) => {
|
|
81
|
+
const queryClient = useQueryClient();
|
|
82
|
+
const token = useIAMStore(state => state.token);
|
|
83
|
+
const mcpUrl = useMcpServerUrl();
|
|
84
|
+
const enabled = Boolean(token && mcpUrl && taskUid) && (options.enabled ?? true);
|
|
85
|
+
const { onEvent } = options;
|
|
86
|
+
useEffect(() => {
|
|
87
|
+
if (!enabled) {
|
|
88
|
+
return undefined;
|
|
89
|
+
}
|
|
90
|
+
const close = subscribeTaskEvents(token ?? '', taskUid, {
|
|
91
|
+
onEvent: event => {
|
|
92
|
+
queryClient.setQueryData(queryKeys.mcp.task(taskUid), current => {
|
|
93
|
+
if (event.task) {
|
|
94
|
+
return event.task;
|
|
95
|
+
}
|
|
96
|
+
if (!current) {
|
|
97
|
+
return current;
|
|
98
|
+
}
|
|
99
|
+
return {
|
|
100
|
+
...current,
|
|
101
|
+
status: event.status ?? current.status,
|
|
102
|
+
statusMessage: event.statusMessage ?? current.statusMessage,
|
|
103
|
+
lastUpdatedAt: event.at ?? current.lastUpdatedAt,
|
|
104
|
+
outputs: event.output
|
|
105
|
+
? [...(current.outputs ?? []), event.output]
|
|
106
|
+
: current.outputs,
|
|
107
|
+
};
|
|
108
|
+
});
|
|
109
|
+
onEvent?.(event);
|
|
110
|
+
},
|
|
111
|
+
onClose: () => {
|
|
112
|
+
queryClient.invalidateQueries({
|
|
113
|
+
queryKey: queryKeys.mcp.task(taskUid),
|
|
114
|
+
});
|
|
115
|
+
queryClient.invalidateQueries({ queryKey: queryKeys.mcp.tasks() });
|
|
116
|
+
},
|
|
117
|
+
}, mcpUrl);
|
|
118
|
+
return close;
|
|
119
|
+
}, [enabled, token, taskUid, mcpUrl, queryClient, onEvent]);
|
|
120
|
+
};
|
|
121
|
+
export const useCancelTask = () => {
|
|
122
|
+
const queryClient = useQueryClient();
|
|
123
|
+
const token = useIAMStore(state => state.token);
|
|
124
|
+
const mcpUrl = useMcpServerUrl();
|
|
125
|
+
return useMutation({
|
|
126
|
+
mutationFn: taskUid => cancelTask(token ?? '', taskUid, mcpUrl),
|
|
127
|
+
onSuccess: task => {
|
|
128
|
+
queryClient.setQueryData(queryKeys.mcp.task(task.uid), task);
|
|
129
|
+
queryClient.invalidateQueries({ queryKey: queryKeys.mcp.tasks() });
|
|
130
|
+
queryClient.invalidateQueries({ queryKey: queryKeys.mcp.activity() });
|
|
131
|
+
},
|
|
132
|
+
});
|
|
133
|
+
};
|
|
134
|
+
export const useAnswerTask = () => {
|
|
135
|
+
const queryClient = useQueryClient();
|
|
136
|
+
const token = useIAMStore(state => state.token);
|
|
137
|
+
const mcpUrl = useMcpServerUrl();
|
|
138
|
+
return useMutation({
|
|
139
|
+
mutationFn: ({ taskUid, input }) => answerTask(token ?? '', taskUid, { input }, crypto.randomUUID(), mcpUrl),
|
|
140
|
+
onSuccess: task => {
|
|
141
|
+
queryClient.setQueryData(queryKeys.mcp.task(task.uid), task);
|
|
142
|
+
queryClient.invalidateQueries({ queryKey: queryKeys.mcp.tasks() });
|
|
143
|
+
},
|
|
144
|
+
});
|
|
145
|
+
};
|
|
146
|
+
// -- Bindings --------------------------------------------------------------
|
|
147
|
+
export const useBindings = (filters = {}, options = {}) => {
|
|
148
|
+
const token = useIAMStore(state => state.token);
|
|
149
|
+
const mcpUrl = useMcpServerUrl();
|
|
150
|
+
return useQuery({
|
|
151
|
+
queryKey: queryKeys.mcp.bindingList(filters),
|
|
152
|
+
queryFn: () => listBindings(token ?? '', filters, mcpUrl),
|
|
153
|
+
enabled: Boolean(token && mcpUrl) && (options.enabled ?? true),
|
|
154
|
+
staleTime: 10_000,
|
|
155
|
+
});
|
|
156
|
+
};
|
|
157
|
+
export const useTerminateBinding = () => {
|
|
158
|
+
const queryClient = useQueryClient();
|
|
159
|
+
const token = useIAMStore(state => state.token);
|
|
160
|
+
const mcpUrl = useMcpServerUrl();
|
|
161
|
+
return useMutation({
|
|
162
|
+
mutationFn: bindingUid => terminateBinding(token ?? '', bindingUid, mcpUrl),
|
|
163
|
+
onSuccess: () => {
|
|
164
|
+
queryClient.invalidateQueries({ queryKey: queryKeys.mcp.bindings() });
|
|
165
|
+
queryClient.invalidateQueries({ queryKey: queryKeys.mcp.activity() });
|
|
166
|
+
},
|
|
167
|
+
});
|
|
168
|
+
};
|
|
169
|
+
// -- Activity --------------------------------------------------------------
|
|
170
|
+
/**
|
|
171
|
+
* What is going on for the caller, refetched every ten seconds as the
|
|
172
|
+
* fallback under the ai-agents websocket, which patches the same entry.
|
|
173
|
+
*/
|
|
174
|
+
export const useMcpActivity = (filters = {}, options = {}) => {
|
|
175
|
+
const token = useIAMStore(state => state.token);
|
|
176
|
+
const mcpUrl = useMcpServerUrl();
|
|
177
|
+
return useQuery({
|
|
178
|
+
queryKey: queryKeys.mcp.activity(filters),
|
|
179
|
+
queryFn: () => getMcpActivity(token ?? '', filters, mcpUrl),
|
|
180
|
+
enabled: Boolean(token && mcpUrl) && (options.enabled ?? true),
|
|
181
|
+
staleTime: 5_000,
|
|
182
|
+
/*
|
|
183
|
+
* A poll that cannot succeed stops polling.
|
|
184
|
+
*
|
|
185
|
+
* `refetchInterval` as a plain number re-arms after *every* settle,
|
|
186
|
+
* failures included — so an endpoint the browser refuses outright (no
|
|
187
|
+
* CORS header, a dead host, a revoked token) turned this into a tight
|
|
188
|
+
* loop: fetch, fail, re-arm, fetch. Each failure is a query state change,
|
|
189
|
+
* and every observer re-rendered on each one, which read as a page
|
|
190
|
+
* repainting on a timer with nothing behind it.
|
|
191
|
+
*
|
|
192
|
+
* As a function it can decline. One error is enough to stand down; a
|
|
193
|
+
* remount, a refocus or a token change starts it again, which is when
|
|
194
|
+
* the answer could genuinely have changed.
|
|
195
|
+
*/
|
|
196
|
+
refetchInterval: query => query.state.status === 'error'
|
|
197
|
+
? false
|
|
198
|
+
: (options.pollIntervalMs ?? 10_000),
|
|
199
|
+
refetchIntervalInBackground: false,
|
|
200
|
+
// One retry, not the default three. The failures worth retrying here are
|
|
201
|
+
// transient; a refused origin is not, and three attempts only make the
|
|
202
|
+
// loop above three times as loud.
|
|
203
|
+
retry: 1,
|
|
204
|
+
/*
|
|
205
|
+
* Re-render for the answer, not for the asking.
|
|
206
|
+
*
|
|
207
|
+
* This polls for as long as the page is open, and by default a query
|
|
208
|
+
* notifies on every observed field — so `isFetching` going true and back
|
|
209
|
+
* again re-rendered every consumer twice a poll, whether or not a single
|
|
210
|
+
* byte had changed. On a dashboard that reads only the data, that is a
|
|
211
|
+
* repaint on a timer with nothing behind it.
|
|
212
|
+
*
|
|
213
|
+
* Structural sharing already keeps `data` referentially stable when the
|
|
214
|
+
* payload is unchanged, so with this the quiet polls cost nothing.
|
|
215
|
+
*/
|
|
216
|
+
/*
|
|
217
|
+
* Re-render for the answer, not for the asking.
|
|
218
|
+
*
|
|
219
|
+
* `error` is deliberately absent: this is a background poll, and a
|
|
220
|
+
* consumer that redraws every time it fails is redrawing for something it
|
|
221
|
+
* does not show. `isPending` covers the one transition that matters —
|
|
222
|
+
* nothing yet, then something.
|
|
223
|
+
*/
|
|
224
|
+
notifyOnChangeProps: ['data', 'isPending'],
|
|
225
|
+
});
|
|
226
|
+
};
|
|
227
|
+
// -- Audit -----------------------------------------------------------------
|
|
228
|
+
/** One page of the audit log; the cursor is one of the filters, as the URL keeps it. */
|
|
229
|
+
export const useAuditEvents = (filters = {}, options = {}) => {
|
|
230
|
+
const token = useIAMStore(state => state.token);
|
|
231
|
+
const mcpUrl = useMcpServerUrl();
|
|
232
|
+
return useQuery({
|
|
233
|
+
queryKey: queryKeys.mcp.auditList(filters),
|
|
234
|
+
queryFn: () => listAuditEvents(token ?? '', filters, mcpUrl),
|
|
235
|
+
enabled: Boolean(token && mcpUrl) && (options.enabled ?? true),
|
|
236
|
+
staleTime: 30_000,
|
|
237
|
+
placeholderData: previous => previous,
|
|
238
|
+
});
|
|
239
|
+
};
|
|
240
|
+
/** The whole selection as one JSONL or CSV document, on demand. */
|
|
241
|
+
export const useAuditExport = () => {
|
|
242
|
+
const token = useIAMStore(state => state.token);
|
|
243
|
+
const mcpUrl = useMcpServerUrl();
|
|
244
|
+
return useMutation({
|
|
245
|
+
mutationFn: ({ filters = {}, format = 'jsonl' }) => exportAuditEvents(token ?? '', filters, format, mcpUrl),
|
|
246
|
+
});
|
|
247
|
+
};
|
|
248
|
+
// -- Policy ----------------------------------------------------------------
|
|
249
|
+
/** The effective policy for the caller, or previewed as one agent. */
|
|
250
|
+
export const useEffectivePolicy = (agent, filters = {}, options = {}) => {
|
|
251
|
+
const token = useIAMStore(state => state.token);
|
|
252
|
+
const mcpUrl = useMcpServerUrl();
|
|
253
|
+
const policyFilters = { agent, ...filters };
|
|
254
|
+
return useQuery({
|
|
255
|
+
queryKey: queryKeys.mcp.policy(policyFilters),
|
|
256
|
+
queryFn: () => getEffectivePolicy(token ?? '', policyFilters, mcpUrl),
|
|
257
|
+
enabled: Boolean(token && mcpUrl) && (options.enabled ?? true),
|
|
258
|
+
staleTime: 60_000,
|
|
259
|
+
});
|
|
260
|
+
};
|
|
261
|
+
// -- Organizations (the Enterprise console) --------------------------------
|
|
262
|
+
/**
|
|
263
|
+
* The organization's MCP overview, for the console's first page.
|
|
264
|
+
*
|
|
265
|
+
* Read on demand and kept for a minute: an administrator reads it, acts, and
|
|
266
|
+
* comes back — it is not a live pane, and a page that re-asked every ten
|
|
267
|
+
* seconds would cost the gateway three bounded queries for nothing.
|
|
268
|
+
*/
|
|
269
|
+
export const useOrgMcpOverview = (orgUid, filters = {}, options = {}) => {
|
|
270
|
+
const token = useIAMStore(state => state.token);
|
|
271
|
+
const mcpUrl = useMcpServerUrl();
|
|
272
|
+
return useQuery({
|
|
273
|
+
queryKey: queryKeys.mcp.orgOverview(orgUid ?? '', filters),
|
|
274
|
+
queryFn: () => getOrganizationMcpOverview(token ?? '', orgUid, filters, mcpUrl),
|
|
275
|
+
enabled: Boolean(token && mcpUrl && orgUid) && (options.enabled ?? true),
|
|
276
|
+
staleTime: 60_000,
|
|
277
|
+
});
|
|
278
|
+
};
|
|
279
|
+
/**
|
|
280
|
+
* The organization's use against its quotas, and which agents spent it.
|
|
281
|
+
*
|
|
282
|
+
* Kept for a minute like the overview, and for the same reason: an
|
|
283
|
+
* administrator reads it, acts, and comes back. A budget that re-asked every
|
|
284
|
+
* ten seconds would cost IAM a ledger query for a number that moves in
|
|
285
|
+
* credits, not in milliseconds.
|
|
286
|
+
*/
|
|
287
|
+
export const useOrgMcpUsage = (orgUid, filters = {}, options = {}) => {
|
|
288
|
+
const token = useIAMStore(state => state.token);
|
|
289
|
+
const mcpUrl = useMcpServerUrl();
|
|
290
|
+
return useQuery({
|
|
291
|
+
queryKey: queryKeys.mcp.orgUsage(orgUid ?? '', filters),
|
|
292
|
+
queryFn: () => getOrganizationMcpUsage(token ?? '', orgUid, filters, mcpUrl),
|
|
293
|
+
enabled: Boolean(token && mcpUrl && orgUid) && (options.enabled ?? true),
|
|
294
|
+
staleTime: 60_000,
|
|
295
|
+
});
|
|
296
|
+
};
|
|
297
|
+
// -- Connected agents (IAM) ------------------------------------------------
|
|
298
|
+
export const useConnectedAgents = (options = {}) => {
|
|
299
|
+
const token = useIAMStore(state => state.token);
|
|
300
|
+
const iamUrl = useIamUrl();
|
|
301
|
+
return useQuery({
|
|
302
|
+
queryKey: queryKeys.mcp.connectedAgents(),
|
|
303
|
+
queryFn: () => listConnectedAgents(token ?? '', iamUrl),
|
|
304
|
+
enabled: Boolean(token && iamUrl) && (options.enabled ?? true),
|
|
305
|
+
staleTime: 30_000,
|
|
306
|
+
});
|
|
307
|
+
};
|
|
308
|
+
/** Revoke a grant; the list and the activity are refreshed, never guessed. */
|
|
309
|
+
export const useDisconnectAgent = () => {
|
|
310
|
+
const queryClient = useQueryClient();
|
|
311
|
+
const token = useIAMStore(state => state.token);
|
|
312
|
+
const iamUrl = useIamUrl();
|
|
313
|
+
return useMutation({
|
|
314
|
+
mutationFn: grantUid => disconnectAgent(token ?? '', grantUid, iamUrl),
|
|
315
|
+
onSuccess: () => {
|
|
316
|
+
queryClient.invalidateQueries({
|
|
317
|
+
queryKey: queryKeys.mcp.connectedAgents(),
|
|
318
|
+
});
|
|
319
|
+
queryClient.invalidateQueries({ queryKey: queryKeys.mcp.activity() });
|
|
320
|
+
},
|
|
321
|
+
});
|
|
322
|
+
};
|
|
323
|
+
/**
|
|
324
|
+
* Disconnect every agent of this person — and so force the next
|
|
325
|
+
* authorization through the consent screen.
|
|
326
|
+
*
|
|
327
|
+
* The grant *is* the consent, so there is no separate "ask again" to keep in
|
|
328
|
+
* step: ending them all is what forcing re-consent means.
|
|
329
|
+
*/
|
|
330
|
+
export const useDisconnectEveryAgent = () => {
|
|
331
|
+
const queryClient = useQueryClient();
|
|
332
|
+
const token = useIAMStore(state => state.token);
|
|
333
|
+
const iamUrl = useIamUrl();
|
|
334
|
+
return useMutation({
|
|
335
|
+
mutationFn: () => disconnectEveryAgent(token ?? '', iamUrl),
|
|
336
|
+
onSuccess: () => {
|
|
337
|
+
queryClient.invalidateQueries({
|
|
338
|
+
queryKey: queryKeys.mcp.connectedAgents(),
|
|
339
|
+
});
|
|
340
|
+
queryClient.invalidateQueries({ queryKey: queryKeys.mcp.activity() });
|
|
341
|
+
},
|
|
342
|
+
});
|
|
343
|
+
};
|
|
344
|
+
/** The same for one team's agents, for whoever may manage that team. */
|
|
345
|
+
export const useDisconnectEveryAgentInTeam = () => {
|
|
346
|
+
const queryClient = useQueryClient();
|
|
347
|
+
const token = useIAMStore(state => state.token);
|
|
348
|
+
const iamUrl = useIamUrl();
|
|
349
|
+
return useMutation({
|
|
350
|
+
mutationFn: teamUid => disconnectEveryAgentInTeam(token ?? '', teamUid, iamUrl),
|
|
351
|
+
onSuccess: () => {
|
|
352
|
+
queryClient.invalidateQueries({
|
|
353
|
+
queryKey: queryKeys.mcp.connectedAgents(),
|
|
354
|
+
});
|
|
355
|
+
queryClient.invalidateQueries({ queryKey: queryKeys.mcp.activity() });
|
|
356
|
+
},
|
|
357
|
+
});
|
|
358
|
+
};
|
|
359
|
+
// -- Teams (IAM) ------------------------------------------------------------
|
|
360
|
+
/** One organization's teams, for the console's team policy page. */
|
|
361
|
+
export const useOrganizationTeams = (orgUid, options = {}) => {
|
|
362
|
+
const token = useIAMStore(state => state.token);
|
|
363
|
+
const iamUrl = useIamUrl();
|
|
364
|
+
return useQuery({
|
|
365
|
+
queryKey: queryKeys.mcp.organizationTeams(orgUid),
|
|
366
|
+
queryFn: () => listOrganizationTeams(token ?? '', orgUid, iamUrl),
|
|
367
|
+
enabled: Boolean(token && iamUrl && orgUid) && (options.enabled ?? true),
|
|
368
|
+
staleTime: 60_000,
|
|
369
|
+
});
|
|
370
|
+
};
|
|
371
|
+
/**
|
|
372
|
+
* Whether the audit is reaching the organization's own system of record.
|
|
373
|
+
*
|
|
374
|
+
* Polled rather than read once: a destination that stops answering does so
|
|
375
|
+
* while somebody is looking at the page, and the point of the panel is to
|
|
376
|
+
* say when that happens.
|
|
377
|
+
*/
|
|
378
|
+
export const useMcpForwarding = (org = '', options = {}) => {
|
|
379
|
+
const token = useIAMStore(state => state.token);
|
|
380
|
+
const mcpUrl = useMcpServerUrl();
|
|
381
|
+
return useQuery({
|
|
382
|
+
queryKey: queryKeys.mcp.forwarding(org),
|
|
383
|
+
queryFn: () => getMcpForwarding(token ?? '', org, mcpUrl),
|
|
384
|
+
enabled: Boolean(token && mcpUrl) && (options.enabled ?? true),
|
|
385
|
+
staleTime: 30_000,
|
|
386
|
+
refetchInterval: 60_000,
|
|
387
|
+
});
|
|
388
|
+
};
|
|
389
|
+
// -- Audit settings: retention, forwarding, alert destinations (IAM) --------
|
|
390
|
+
/** One organization's settings, or `null` where it has decided nothing. */
|
|
391
|
+
export const useAuditSettings = (orgUid, options = {}) => {
|
|
392
|
+
const token = useIAMStore(state => state.token);
|
|
393
|
+
const iamUrl = useIamUrl();
|
|
394
|
+
return useQuery({
|
|
395
|
+
queryKey: queryKeys.mcp.auditSettings(orgUid),
|
|
396
|
+
queryFn: () => getAuditSettings(token ?? '', orgUid, iamUrl),
|
|
397
|
+
enabled: Boolean(token && iamUrl && orgUid) && (options.enabled ?? true),
|
|
398
|
+
staleTime: 30_000,
|
|
399
|
+
});
|
|
400
|
+
};
|
|
401
|
+
/**
|
|
402
|
+
* Change some of them. Only what is passed is sent, because IAM merges: a
|
|
403
|
+
* page editing the alert destinations must not clear a retention it never
|
|
404
|
+
* showed.
|
|
405
|
+
*/
|
|
406
|
+
export const useSetAuditSettings = (orgUid) => {
|
|
407
|
+
const queryClient = useQueryClient();
|
|
408
|
+
const token = useIAMStore(state => state.token);
|
|
409
|
+
const iamUrl = useIamUrl();
|
|
410
|
+
return useMutation({
|
|
411
|
+
mutationFn: ({ settings, expectedVersion }) => setAuditSettings(token ?? '', orgUid, settings, { expectedVersion }, iamUrl),
|
|
412
|
+
onSuccess: () => {
|
|
413
|
+
queryClient.invalidateQueries({
|
|
414
|
+
queryKey: queryKeys.mcp.auditSettings(orgUid),
|
|
415
|
+
});
|
|
416
|
+
},
|
|
417
|
+
});
|
|
418
|
+
};
|
|
419
|
+
/**
|
|
420
|
+
* Try a rule against current values.
|
|
421
|
+
*
|
|
422
|
+
* A mutation rather than a query: it is something somebody asks for, once,
|
|
423
|
+
* by pressing a button — and caching "what does this see now" would answer
|
|
424
|
+
* the second press with the first press's numbers.
|
|
425
|
+
*/
|
|
426
|
+
export const useTestAlertRule = () => {
|
|
427
|
+
const token = useIAMStore(state => state.token);
|
|
428
|
+
const mcpUrl = useMcpServerUrl();
|
|
429
|
+
return useMutation({
|
|
430
|
+
mutationFn: rule => testAlertRule(token ?? '', rule, mcpUrl),
|
|
431
|
+
});
|
|
432
|
+
};
|
|
433
|
+
// -- Alert rules (IAM) ------------------------------------------------------
|
|
434
|
+
/** One organization's alert rules, disabled ones included. */
|
|
435
|
+
export const useAlertRules = (orgUid, options = {}) => {
|
|
436
|
+
const token = useIAMStore(state => state.token);
|
|
437
|
+
const iamUrl = useIamUrl();
|
|
438
|
+
return useQuery({
|
|
439
|
+
queryKey: queryKeys.mcp.alertRules(orgUid),
|
|
440
|
+
queryFn: () => listAlertRules(token ?? '', orgUid, iamUrl),
|
|
441
|
+
enabled: Boolean(token && iamUrl && orgUid) && (options.enabled ?? true),
|
|
442
|
+
staleTime: 30_000,
|
|
443
|
+
});
|
|
444
|
+
};
|
|
445
|
+
export const useCreateAlertRule = (orgUid) => {
|
|
446
|
+
const queryClient = useQueryClient();
|
|
447
|
+
const token = useIAMStore(state => state.token);
|
|
448
|
+
const iamUrl = useIamUrl();
|
|
449
|
+
return useMutation({
|
|
450
|
+
mutationFn: rule => createAlertRule(token ?? '', orgUid, rule, iamUrl),
|
|
451
|
+
onSuccess: () => {
|
|
452
|
+
queryClient.invalidateQueries({
|
|
453
|
+
queryKey: queryKeys.mcp.alertRules(orgUid),
|
|
454
|
+
});
|
|
455
|
+
},
|
|
456
|
+
});
|
|
457
|
+
};
|
|
458
|
+
export const useUpdateAlertRule = (orgUid) => {
|
|
459
|
+
const queryClient = useQueryClient();
|
|
460
|
+
const token = useIAMStore(state => state.token);
|
|
461
|
+
const iamUrl = useIamUrl();
|
|
462
|
+
return useMutation({
|
|
463
|
+
mutationFn: ({ uid, rule }) => updateAlertRule(token ?? '', orgUid, uid, rule, iamUrl),
|
|
464
|
+
onSuccess: () => {
|
|
465
|
+
queryClient.invalidateQueries({
|
|
466
|
+
queryKey: queryKeys.mcp.alertRules(orgUid),
|
|
467
|
+
});
|
|
468
|
+
},
|
|
469
|
+
});
|
|
470
|
+
};
|
|
471
|
+
export const useDeleteAlertRule = (orgUid) => {
|
|
472
|
+
const queryClient = useQueryClient();
|
|
473
|
+
const token = useIAMStore(state => state.token);
|
|
474
|
+
const iamUrl = useIamUrl();
|
|
475
|
+
return useMutation({
|
|
476
|
+
mutationFn: uid => deleteAlertRule(token ?? '', orgUid, uid, iamUrl),
|
|
477
|
+
onSuccess: () => {
|
|
478
|
+
queryClient.invalidateQueries({
|
|
479
|
+
queryKey: queryKeys.mcp.alertRules(orgUid),
|
|
480
|
+
});
|
|
481
|
+
},
|
|
482
|
+
});
|
|
483
|
+
};
|
|
484
|
+
// -- Identity providers (IAM) -----------------------------------------------
|
|
485
|
+
/** One organization's identity providers, disabled ones included. */
|
|
486
|
+
export const useIdentityProviders = (orgUid, options = {}) => {
|
|
487
|
+
const token = useIAMStore(state => state.token);
|
|
488
|
+
const iamUrl = useIamUrl();
|
|
489
|
+
return useQuery({
|
|
490
|
+
queryKey: queryKeys.mcp.identityProviders(orgUid),
|
|
491
|
+
queryFn: () => listIdentityProviders(token ?? '', orgUid, iamUrl),
|
|
492
|
+
enabled: Boolean(token && iamUrl && orgUid) && (options.enabled ?? true),
|
|
493
|
+
staleTime: 30_000,
|
|
494
|
+
});
|
|
495
|
+
};
|
|
496
|
+
export const useCreateIdentityProvider = (orgUid) => {
|
|
497
|
+
const queryClient = useQueryClient();
|
|
498
|
+
const token = useIAMStore(state => state.token);
|
|
499
|
+
const iamUrl = useIamUrl();
|
|
500
|
+
return useMutation({
|
|
501
|
+
mutationFn: provider => createIdentityProvider(token ?? '', orgUid, provider, iamUrl),
|
|
502
|
+
onSuccess: () => {
|
|
503
|
+
queryClient.invalidateQueries({
|
|
504
|
+
queryKey: queryKeys.mcp.identityProviders(orgUid),
|
|
505
|
+
});
|
|
506
|
+
},
|
|
507
|
+
});
|
|
508
|
+
};
|
|
509
|
+
export const useUpdateIdentityProvider = (orgUid) => {
|
|
510
|
+
const queryClient = useQueryClient();
|
|
511
|
+
const token = useIAMStore(state => state.token);
|
|
512
|
+
const iamUrl = useIamUrl();
|
|
513
|
+
return useMutation({
|
|
514
|
+
mutationFn: ({ uid, provider }) => updateIdentityProvider(token ?? '', orgUid, uid, provider, iamUrl),
|
|
515
|
+
onSuccess: () => {
|
|
516
|
+
queryClient.invalidateQueries({
|
|
517
|
+
queryKey: queryKeys.mcp.identityProviders(orgUid),
|
|
518
|
+
});
|
|
519
|
+
},
|
|
520
|
+
});
|
|
521
|
+
};
|
|
522
|
+
export const useSetIdentityProviderEnabled = (orgUid) => {
|
|
523
|
+
const queryClient = useQueryClient();
|
|
524
|
+
const token = useIAMStore(state => state.token);
|
|
525
|
+
const iamUrl = useIamUrl();
|
|
526
|
+
return useMutation({
|
|
527
|
+
mutationFn: ({ uid, enabled }) => enabled
|
|
528
|
+
? enableIdentityProvider(token ?? '', orgUid, uid, iamUrl)
|
|
529
|
+
: disableIdentityProvider(token ?? '', orgUid, uid, iamUrl),
|
|
530
|
+
onSuccess: () => {
|
|
531
|
+
queryClient.invalidateQueries({
|
|
532
|
+
queryKey: queryKeys.mcp.identityProviders(orgUid),
|
|
533
|
+
});
|
|
534
|
+
},
|
|
535
|
+
});
|
|
536
|
+
};
|
|
537
|
+
/**
|
|
538
|
+
* What one layer's `allowedClients` entries actually name.
|
|
539
|
+
*
|
|
540
|
+
* Deliberately *not* folded into `useMcpPolicyLayer`. That query is read
|
|
541
|
+
* whenever a policy form mounts; this one may make the server fetch a client
|
|
542
|
+
* document per entry, and an editor typing in a textarea must not set that
|
|
543
|
+
* off on every keystroke — so it is fetched from what is **stored**, and goes
|
|
544
|
+
* stale until the draft is saved.
|
|
545
|
+
*/
|
|
546
|
+
export const useAdmittedClients = (scope, subjectUid, options = {}) => {
|
|
547
|
+
const token = useIAMStore(state => state.token);
|
|
548
|
+
const iamUrl = useIamUrl();
|
|
549
|
+
return useQuery({
|
|
550
|
+
queryKey: queryKeys.mcp.admittedClients(scope, subjectUid),
|
|
551
|
+
queryFn: () => getAdmittedClients(token ?? '', scope, subjectUid, iamUrl),
|
|
552
|
+
enabled: Boolean(token && iamUrl && subjectUid) && (options.enabled ?? true),
|
|
553
|
+
// Longer than the policy layer's: a client document is cached by the
|
|
554
|
+
// server for as long as its own headers say, and re-asking on every
|
|
555
|
+
// focus would make a console page a source of outbound traffic.
|
|
556
|
+
staleTime: 300_000,
|
|
557
|
+
});
|
|
558
|
+
};
|
|
559
|
+
// -- SCIM provisioning credentials (IAM) ------------------------------------
|
|
560
|
+
/**
|
|
561
|
+
* One organization's SCIM tokens, revoked ones included.
|
|
562
|
+
*
|
|
563
|
+
* Revoked ones are *not* filtered out here. A console that hid them would
|
|
564
|
+
* make an organization whose every token is revoked look identical to one
|
|
565
|
+
* that never had any — and those are different problems with different
|
|
566
|
+
* fixes, only one of which is "nobody is being deprovisioned right now".
|
|
567
|
+
*/
|
|
568
|
+
export const useScimTokens = (orgUid, options = {}) => {
|
|
569
|
+
const token = useIAMStore(state => state.token);
|
|
570
|
+
const iamUrl = useIamUrl();
|
|
571
|
+
return useQuery({
|
|
572
|
+
queryKey: queryKeys.mcp.scimTokens(orgUid),
|
|
573
|
+
queryFn: () => listScimTokens(token ?? '', orgUid, iamUrl),
|
|
574
|
+
enabled: Boolean(token && iamUrl && orgUid) && (options.enabled ?? true),
|
|
575
|
+
staleTime: 30_000,
|
|
576
|
+
});
|
|
577
|
+
};
|
|
578
|
+
/**
|
|
579
|
+
* Mint one. The secret is in the result and nowhere else, ever again.
|
|
580
|
+
*
|
|
581
|
+
* The mutation result is deliberately not written into the query cache: a
|
|
582
|
+
* secret that lived in a cache would be re-rendered on every refetch of the
|
|
583
|
+
* list, and outlive the dialog it was shown in.
|
|
584
|
+
*/
|
|
585
|
+
export const useCreateScimToken = (orgUid) => {
|
|
586
|
+
const queryClient = useQueryClient();
|
|
587
|
+
const token = useIAMStore(state => state.token);
|
|
588
|
+
const iamUrl = useIamUrl();
|
|
589
|
+
return useMutation({
|
|
590
|
+
mutationFn: name => createScimToken(token ?? '', orgUid, name, iamUrl),
|
|
591
|
+
onSuccess: () => {
|
|
592
|
+
queryClient.invalidateQueries({
|
|
593
|
+
queryKey: queryKeys.mcp.scimTokens(orgUid),
|
|
594
|
+
});
|
|
595
|
+
},
|
|
596
|
+
});
|
|
597
|
+
};
|
|
598
|
+
export const useRotateScimToken = (orgUid) => {
|
|
599
|
+
const queryClient = useQueryClient();
|
|
600
|
+
const token = useIAMStore(state => state.token);
|
|
601
|
+
const iamUrl = useIamUrl();
|
|
602
|
+
return useMutation({
|
|
603
|
+
mutationFn: uid => rotateScimToken(token ?? '', orgUid, uid, iamUrl),
|
|
604
|
+
onSuccess: () => {
|
|
605
|
+
queryClient.invalidateQueries({
|
|
606
|
+
queryKey: queryKeys.mcp.scimTokens(orgUid),
|
|
607
|
+
});
|
|
608
|
+
},
|
|
609
|
+
});
|
|
610
|
+
};
|
|
611
|
+
export const useRevokeScimToken = (orgUid) => {
|
|
612
|
+
const queryClient = useQueryClient();
|
|
613
|
+
const token = useIAMStore(state => state.token);
|
|
614
|
+
const iamUrl = useIamUrl();
|
|
615
|
+
return useMutation({
|
|
616
|
+
mutationFn: uid => revokeScimToken(token ?? '', orgUid, uid, iamUrl),
|
|
617
|
+
onSuccess: () => {
|
|
618
|
+
queryClient.invalidateQueries({
|
|
619
|
+
queryKey: queryKeys.mcp.scimTokens(orgUid),
|
|
620
|
+
});
|
|
621
|
+
},
|
|
622
|
+
});
|
|
623
|
+
};
|
|
624
|
+
export const useDeleteIdentityProvider = (orgUid) => {
|
|
625
|
+
const queryClient = useQueryClient();
|
|
626
|
+
const token = useIAMStore(state => state.token);
|
|
627
|
+
const iamUrl = useIamUrl();
|
|
628
|
+
return useMutation({
|
|
629
|
+
mutationFn: uid => deleteIdentityProvider(token ?? '', orgUid, uid, iamUrl),
|
|
630
|
+
onSuccess: () => {
|
|
631
|
+
queryClient.invalidateQueries({
|
|
632
|
+
queryKey: queryKeys.mcp.identityProviders(orgUid),
|
|
633
|
+
});
|
|
634
|
+
},
|
|
635
|
+
});
|
|
636
|
+
};
|
|
637
|
+
/**
|
|
638
|
+
* What to publish in DNS, fetched on demand rather than kept fresh.
|
|
639
|
+
*
|
|
640
|
+
* A mutation, not a query with a `refetch`: this is asked for once when
|
|
641
|
+
* somebody opens the verification panel, and the value never changes for a
|
|
642
|
+
* given provider and domain — what changes is `verified`, which the
|
|
643
|
+
* `verify` call below answers directly from the provider it returns.
|
|
644
|
+
*/
|
|
645
|
+
export const useDomainVerification = (orgUid) => {
|
|
646
|
+
const token = useIAMStore(state => state.token);
|
|
647
|
+
const iamUrl = useIamUrl();
|
|
648
|
+
return useMutation({
|
|
649
|
+
mutationFn: ({ uid, domain }) => getDomainVerification(token ?? '', orgUid, uid, domain, iamUrl),
|
|
650
|
+
});
|
|
651
|
+
};
|
|
652
|
+
export const useVerifyDomain = (orgUid) => {
|
|
653
|
+
const queryClient = useQueryClient();
|
|
654
|
+
const token = useIAMStore(state => state.token);
|
|
655
|
+
const iamUrl = useIamUrl();
|
|
656
|
+
return useMutation({
|
|
657
|
+
mutationFn: ({ uid, domain }) => verifyDomain(token ?? '', orgUid, uid, domain, iamUrl),
|
|
658
|
+
onSuccess: () => {
|
|
659
|
+
queryClient.invalidateQueries({
|
|
660
|
+
queryKey: queryKeys.mcp.identityProviders(orgUid),
|
|
661
|
+
});
|
|
662
|
+
},
|
|
663
|
+
});
|
|
664
|
+
};
|
|
665
|
+
// -- The policy layer IAM stores (IAM) -------------------------------------
|
|
666
|
+
/**
|
|
667
|
+
* One layer's rules, or `null` where nobody has written one.
|
|
668
|
+
*
|
|
669
|
+
* `null` is a real answer and not an error: most organizations have never
|
|
670
|
+
* written a policy, and a form needs to tell "narrows nothing" from "does
|
|
671
|
+
* not exist" — only the second has nothing to remove.
|
|
672
|
+
*/
|
|
673
|
+
export const useMcpPolicyLayer = (scope, subjectUid, options = {}) => {
|
|
674
|
+
const token = useIAMStore(state => state.token);
|
|
675
|
+
const iamUrl = useIamUrl();
|
|
676
|
+
return useQuery({
|
|
677
|
+
queryKey: queryKeys.mcp.policyLayer(scope, subjectUid),
|
|
678
|
+
queryFn: () => getMcpPolicy(token ?? '', scope, subjectUid, iamUrl),
|
|
679
|
+
enabled: Boolean(token && iamUrl && subjectUid) && (options.enabled ?? true),
|
|
680
|
+
staleTime: 30_000,
|
|
681
|
+
});
|
|
682
|
+
};
|
|
683
|
+
/**
|
|
684
|
+
* Several layers at once, for a page that has to compare against them all.
|
|
685
|
+
*
|
|
686
|
+
* The personal policy page needs every organization a person belongs to in
|
|
687
|
+
* order to say which of their values will have no effect. One hook per
|
|
688
|
+
* organization is not something a component can do — the count changes — so
|
|
689
|
+
* they are fetched together and answered in the order asked.
|
|
690
|
+
*
|
|
691
|
+
* A layer that could not be read comes back `null`, the same as one nobody
|
|
692
|
+
* has written. That is the safe direction here: the page would rather say
|
|
693
|
+
* nothing about narrowing than invent a cap somebody does not have.
|
|
694
|
+
*/
|
|
695
|
+
export const useMcpPolicyLayers = (scope, subjectUids) => {
|
|
696
|
+
const token = useIAMStore(state => state.token);
|
|
697
|
+
const iamUrl = useIamUrl();
|
|
698
|
+
return useQueries({
|
|
699
|
+
queries: subjectUids.map(subjectUid => ({
|
|
700
|
+
queryKey: queryKeys.mcp.policyLayer(scope, subjectUid),
|
|
701
|
+
queryFn: () => getMcpPolicy(token ?? '', scope, subjectUid, iamUrl),
|
|
702
|
+
enabled: Boolean(token && iamUrl && subjectUid),
|
|
703
|
+
staleTime: 30_000,
|
|
704
|
+
})),
|
|
705
|
+
});
|
|
706
|
+
};
|
|
707
|
+
/**
|
|
708
|
+
* Replace one layer's rules.
|
|
709
|
+
*
|
|
710
|
+
* The **effective** policy is invalidated alongside the layer: the two are
|
|
711
|
+
* the same fact read two ways, and a page still showing the old effective
|
|
712
|
+
* policy after a write is a page saying the change did not take.
|
|
713
|
+
*/
|
|
714
|
+
export const useSetMcpPolicyLayer = (scope, subjectUid) => {
|
|
715
|
+
const queryClient = useQueryClient();
|
|
716
|
+
const token = useIAMStore(state => state.token);
|
|
717
|
+
const iamUrl = useIamUrl();
|
|
718
|
+
return useMutation({
|
|
719
|
+
mutationFn: ({ rules, expectedVersion }) => setMcpPolicy(token ?? '', scope, subjectUid, rules, { expectedVersion }, iamUrl),
|
|
720
|
+
onSuccess: () => {
|
|
721
|
+
queryClient.invalidateQueries({
|
|
722
|
+
queryKey: queryKeys.mcp.policyLayer(scope, subjectUid),
|
|
723
|
+
});
|
|
724
|
+
queryClient.invalidateQueries({ queryKey: queryKeys.mcp.policy() });
|
|
725
|
+
},
|
|
726
|
+
});
|
|
727
|
+
};
|
|
728
|
+
/** Remove one layer, so it narrows nothing again. */
|
|
729
|
+
export const useDeleteMcpPolicyLayer = (scope, subjectUid) => {
|
|
730
|
+
const queryClient = useQueryClient();
|
|
731
|
+
const token = useIAMStore(state => state.token);
|
|
732
|
+
const iamUrl = useIamUrl();
|
|
733
|
+
return useMutation({
|
|
734
|
+
mutationFn: () => deleteMcpPolicy(token ?? '', scope, subjectUid, iamUrl),
|
|
735
|
+
onSuccess: () => {
|
|
736
|
+
queryClient.invalidateQueries({
|
|
737
|
+
queryKey: queryKeys.mcp.policyLayer(scope, subjectUid),
|
|
738
|
+
});
|
|
739
|
+
queryClient.invalidateQueries({ queryKey: queryKeys.mcp.policy() });
|
|
740
|
+
},
|
|
741
|
+
});
|
|
742
|
+
};
|
|
743
|
+
// -- Service agents (IAM) --------------------------------------------------
|
|
744
|
+
/**
|
|
745
|
+
* One organization's service agents, revoked ones included.
|
|
746
|
+
*
|
|
747
|
+
* Keyed by the organization: two organizations' lists must never share a
|
|
748
|
+
* cache entry, or an owner of both would see one under the other's name.
|
|
749
|
+
*/
|
|
750
|
+
export const useServiceAgents = (orgUid, options = {}) => {
|
|
751
|
+
const token = useIAMStore(state => state.token);
|
|
752
|
+
const iamUrl = useIamUrl();
|
|
753
|
+
return useQuery({
|
|
754
|
+
queryKey: queryKeys.mcp.serviceAgents(orgUid),
|
|
755
|
+
queryFn: () => listServiceAgents(token ?? '', orgUid, iamUrl),
|
|
756
|
+
enabled: Boolean(token && iamUrl && orgUid) && (options.enabled ?? true),
|
|
757
|
+
staleTime: 30_000,
|
|
758
|
+
});
|
|
759
|
+
};
|
|
760
|
+
/**
|
|
761
|
+
* Create one. The answer carries the key, and it is the only place it
|
|
762
|
+
* exists — so the caller must render it before doing anything else with it.
|
|
763
|
+
*/
|
|
764
|
+
export const useCreateServiceAgent = (orgUid) => {
|
|
765
|
+
const queryClient = useQueryClient();
|
|
766
|
+
const token = useIAMStore(state => state.token);
|
|
767
|
+
const iamUrl = useIamUrl();
|
|
768
|
+
return useMutation({
|
|
769
|
+
mutationFn: agent => createServiceAgent(token ?? '', orgUid, agent, iamUrl),
|
|
770
|
+
onSuccess: () => {
|
|
771
|
+
queryClient.invalidateQueries({
|
|
772
|
+
queryKey: queryKeys.mcp.serviceAgents(orgUid),
|
|
773
|
+
});
|
|
774
|
+
},
|
|
775
|
+
});
|
|
776
|
+
};
|
|
777
|
+
/** Replace an agent's key; the old one stops working with the call. */
|
|
778
|
+
export const useRotateServiceAgentKey = (orgUid) => {
|
|
779
|
+
const queryClient = useQueryClient();
|
|
780
|
+
const token = useIAMStore(state => state.token);
|
|
781
|
+
const iamUrl = useIamUrl();
|
|
782
|
+
return useMutation({
|
|
783
|
+
mutationFn: agentUid => rotateServiceAgentKey(token ?? '', orgUid, agentUid, iamUrl),
|
|
784
|
+
onSuccess: () => {
|
|
785
|
+
queryClient.invalidateQueries({
|
|
786
|
+
queryKey: queryKeys.mcp.serviceAgents(orgUid),
|
|
787
|
+
});
|
|
788
|
+
},
|
|
789
|
+
});
|
|
790
|
+
};
|
|
791
|
+
/** Stop an agent. The list is refetched rather than edited in place. */
|
|
792
|
+
export const useRevokeServiceAgent = (orgUid) => {
|
|
793
|
+
const queryClient = useQueryClient();
|
|
794
|
+
const token = useIAMStore(state => state.token);
|
|
795
|
+
const iamUrl = useIamUrl();
|
|
796
|
+
return useMutation({
|
|
797
|
+
mutationFn: agentUid => revokeServiceAgent(token ?? '', orgUid, agentUid, iamUrl),
|
|
798
|
+
onSuccess: () => {
|
|
799
|
+
queryClient.invalidateQueries({
|
|
800
|
+
queryKey: queryKeys.mcp.serviceAgents(orgUid),
|
|
801
|
+
});
|
|
802
|
+
},
|
|
803
|
+
});
|
|
804
|
+
};
|
|
805
|
+
// -- Observability (OTEL) --------------------------------------------------
|
|
806
|
+
/** The spans of a run, from the task's trace id; asked again while the task runs. */
|
|
807
|
+
export const useRunTrace = (taskUid, options = {}) => {
|
|
808
|
+
const token = useIAMStore(state => state.token);
|
|
809
|
+
const otelUrl = useOtelUrl();
|
|
810
|
+
const task = useTask(taskUid);
|
|
811
|
+
return useQuery({
|
|
812
|
+
queryKey: queryKeys.mcp.trace(taskUid ?? ''),
|
|
813
|
+
queryFn: () => fetchRunTrace(token ?? '', task.data, otelUrl),
|
|
814
|
+
enabled: Boolean(token && otelUrl && task.data) && (options.enabled ?? true),
|
|
815
|
+
staleTime: 15_000,
|
|
816
|
+
refetchInterval: task.data && !isMcpTaskTerminal(task.data.status) ? 5_000 : false,
|
|
817
|
+
});
|
|
818
|
+
};
|
|
819
|
+
/**
|
|
820
|
+
* The spans of one trace, for a call that finished inside its own request.
|
|
821
|
+
*
|
|
822
|
+
* Read once and kept: a finished trace does not change, and the pane that
|
|
823
|
+
* shows it is opened from an audit row rather than watched.
|
|
824
|
+
*/
|
|
825
|
+
export const useMcpTrace = (traceId, options = {}) => {
|
|
826
|
+
const token = useIAMStore(state => state.token);
|
|
827
|
+
const otelUrl = useOtelUrl();
|
|
828
|
+
return useQuery({
|
|
829
|
+
queryKey: queryKeys.mcp.traceById(traceId ?? ''),
|
|
830
|
+
queryFn: () => fetchTraceSpans(token ?? '', traceId, otelUrl),
|
|
831
|
+
enabled: Boolean(token && otelUrl && traceId) && (options.enabled ?? true),
|
|
832
|
+
staleTime: 60_000,
|
|
833
|
+
});
|
|
834
|
+
};
|
|
835
|
+
/** The four SLIs and the catalog, platform-wide or for one agent or organization. */
|
|
836
|
+
export const useMcpMetrics = (filters = {}, options = {}) => {
|
|
837
|
+
const token = useIAMStore(state => state.token);
|
|
838
|
+
const otelUrl = useOtelUrl();
|
|
839
|
+
return useQuery({
|
|
840
|
+
queryKey: queryKeys.mcp.metrics(filters),
|
|
841
|
+
queryFn: () => fetchMcpMetrics(token ?? '', filters, otelUrl),
|
|
842
|
+
enabled: Boolean(token && otelUrl) && (options.enabled ?? true),
|
|
843
|
+
staleTime: 30_000,
|
|
844
|
+
});
|
|
845
|
+
};
|
|
846
|
+
/** The log lines of a run, gateway and worker alike, by its trace. */
|
|
847
|
+
export const useMcpLogs = (taskUid, options = {}) => {
|
|
848
|
+
const token = useIAMStore(state => state.token);
|
|
849
|
+
const otelUrl = useOtelUrl();
|
|
850
|
+
const task = useTask(taskUid);
|
|
851
|
+
return useQuery({
|
|
852
|
+
queryKey: queryKeys.mcp.logs(taskUid ?? ''),
|
|
853
|
+
queryFn: () => fetchMcpLogs(token ?? '', task.data, { limit: options.limit, severity: options.severity }, otelUrl),
|
|
854
|
+
enabled: Boolean(token && otelUrl && task.data) && (options.enabled ?? true),
|
|
855
|
+
staleTime: 15_000,
|
|
856
|
+
refetchInterval: task.data && !isMcpTaskTerminal(task.data.status) ? 5_000 : false,
|
|
857
|
+
});
|
|
858
|
+
};
|
|
859
|
+
// -- Operations (platform administrators) ----------------------------------
|
|
860
|
+
export const useMcpWorkers = (options = {}) => {
|
|
861
|
+
const token = useIAMStore(state => state.token);
|
|
862
|
+
const mcpUrl = useMcpServerUrl();
|
|
863
|
+
return useQuery({
|
|
864
|
+
queryKey: queryKeys.mcp.workers(),
|
|
865
|
+
queryFn: () => listWorkers(token ?? '', mcpUrl),
|
|
866
|
+
enabled: Boolean(token && mcpUrl) && (options.enabled ?? true),
|
|
867
|
+
staleTime: 5_000,
|
|
868
|
+
refetchInterval: 10_000,
|
|
869
|
+
});
|
|
870
|
+
};
|
|
871
|
+
export const useMcpWorkflowsHealth = (options = {}) => {
|
|
872
|
+
const token = useIAMStore(state => state.token);
|
|
873
|
+
const mcpUrl = useMcpServerUrl();
|
|
874
|
+
return useQuery({
|
|
875
|
+
queryKey: queryKeys.mcp.workflows(),
|
|
876
|
+
queryFn: () => getWorkflowsHealth(token ?? '', mcpUrl),
|
|
877
|
+
enabled: Boolean(token && mcpUrl) && (options.enabled ?? true),
|
|
878
|
+
staleTime: 10_000,
|
|
879
|
+
refetchInterval: 30_000,
|
|
880
|
+
});
|
|
881
|
+
};
|
|
882
|
+
/** The gateway's version and resource; no token needed. */
|
|
883
|
+
export const useMcpGatewayVersion = () => {
|
|
884
|
+
const mcpUrl = useMcpServerUrl();
|
|
885
|
+
return useQuery({
|
|
886
|
+
queryKey: queryKeys.mcp.gatewayVersion(),
|
|
887
|
+
queryFn: () => getGatewayVersion(mcpUrl),
|
|
888
|
+
enabled: Boolean(mcpUrl),
|
|
889
|
+
staleTime: 300_000,
|
|
890
|
+
});
|
|
891
|
+
};
|