@datalayer/core 1.1.60 → 1.1.66
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 +2 -2
- package/lib/api/DatalayerApi.d.ts +42 -1
- package/lib/api/DatalayerApi.js +90 -3
- package/lib/api/constants.d.ts +18 -0
- package/lib/api/constants.js +18 -0
- package/lib/api/contents/attachments.d.ts +9 -0
- package/lib/api/contents/attachments.js +43 -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 +15 -0
- package/lib/api/contents/datasets.js +45 -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 +53 -0
- package/lib/api/contents/sandboxUid.js +78 -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/iam/connectedAgents.d.ts +39 -0
- package/lib/api/iam/connectedAgents.js +52 -0
- package/lib/api/iam/index.d.ts +2 -1
- package/lib/api/iam/index.js +2 -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 +80 -0
- package/lib/api/iam/mcpPolicy.js +132 -0
- package/lib/api/iam/organizationTeams.d.ts +13 -0
- package/lib/api/iam/organizationTeams.js +43 -0
- package/lib/api/iam/serviceAgents.d.ts +68 -0
- package/lib/api/iam/serviceAgents.js +119 -0
- package/lib/api/index.d.ts +4 -1
- package/lib/api/index.js +3 -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 +125 -0
- package/lib/api/mcp/observability.js +254 -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/utils/validation.d.ts +1 -1
- package/lib/api/utils/validation.js +1 -1
- 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/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 +1 -0
- package/lib/components/animation/AnimatedText.js +0 -4
- 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 +9 -0
- package/lib/components/avatars/UserAvatar.js +0 -12
- 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 +10 -0
- package/lib/components/billing/BillingEntitySelect.js +0 -17
- package/lib/components/billing/index.js +0 -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 +31 -0
- package/lib/components/collaboration/LiveEditorCollaborators.js +86 -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 -2
- package/lib/components/display/DatalayerBox.js +6 -6
- 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/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 +1 -0
- 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 +1 -0
- package/lib/components/principal/PrincipalAppearance.js +0 -8
- package/lib/components/principal/PrincipalAvatar.d.ts +1 -0
- package/lib/components/principal/PrincipalAvatar.js +17 -9
- 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 +31 -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/ScreencaptureButton.d.ts +1 -1
- package/lib/components/sharing/ShareAccessComponent.d.ts +15 -1
- package/lib/components/sharing/ShareAccessComponent.js +36 -23
- package/lib/components/sharing/SharingEditor.d.ts +17 -0
- package/lib/components/sharing/SharingEditor.js +0 -24
- 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/index.d.ts +2 -0
- package/lib/hooks/index.js +2 -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/useCache.d.ts +310 -105
- package/lib/hooks/useCache.js +142 -355
- package/lib/hooks/useContainsFocus.d.ts +1 -1
- package/lib/hooks/useContents.d.ts +313 -0
- package/lib/hooks/useContents.js +964 -0
- package/lib/hooks/useFocusTrap.d.ts +4 -4
- package/lib/hooks/useFocusTrap.js +1 -1
- package/lib/hooks/useMcp.d.ts +229 -0
- package/lib/hooks/useMcp.js +656 -0
- package/lib/hooks/useMobile.js +0 -5
- 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/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/McpAuditEvent.d.ts +52 -0
- package/lib/models/McpAuditEvent.js +5 -0
- package/lib/models/McpBinding.d.ts +51 -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/StartedBy.d.ts +57 -0
- package/lib/models/StartedBy.js +81 -0
- package/lib/models/UserDTO.js +4 -2
- package/lib/models/contents/__fixtures__/solr-codec.json +57 -0
- package/lib/models/contents/__fixtures__/v1-contracts.json +66 -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/state/substates/CoreState.d.ts +15 -7
- package/lib/state/substates/CoreState.js +18 -14
- package/lib/state/substates/IAMState.d.ts +1 -1
- package/lib/state/substates/IAMState.js +5 -5
- package/lib/state/substates/ProfileState.js +0 -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/WithSuspense.d.ts +1 -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/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/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 +100 -0
- package/lib/views/mcp/EnterpriseConsole.d.ts +74 -0
- package/lib/views/mcp/EnterpriseConsole.js +173 -0
- package/lib/views/mcp/McpDashboard.d.ts +50 -0
- package/lib/views/mcp/McpDashboard.js +347 -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 +50 -0
- package/lib/views/mcp/McpObservability.js +150 -0
- package/lib/views/mcp/OrganizationPolicy.d.ts +45 -0
- package/lib/views/mcp/OrganizationPolicy.js +107 -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 +125 -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 +67 -0
- package/lib/views/mcp/PolicyForm.js +91 -0
- package/lib/views/mcp/PolicyHistory.d.ts +45 -0
- package/lib/views/mcp/PolicyHistory.js +62 -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 +98 -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 +29 -0
- package/lib/views/mcp/index.js +37 -0
- package/lib/views/mcp/types.d.ts +66 -0
- package/lib/views/mcp/types.js +5 -0
- package/lib/views/secrets/SecretEdit.d.ts +5 -1
- package/lib/views/secrets/SecretEdit.js +2 -2
- package/lib/views/secrets/SecretNew.d.ts +11 -1
- package/lib/views/secrets/SecretNew.js +2 -2
- package/lib/views/secrets/Secrets.d.ts +12 -1
- package/lib/views/secrets/Secrets.js +2 -2
- package/package.json +28 -24
- package/scripts/generate-contents-types.py +169 -0
- package/scripts/generate-mcp-types.py +233 -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,22 @@
|
|
|
1
|
+
export interface HTTPValidationError {
|
|
2
|
+
detail?: Array<ValidationError>;
|
|
3
|
+
}
|
|
4
|
+
export interface ValidationError {
|
|
5
|
+
loc: Array<string | number>;
|
|
6
|
+
msg: string;
|
|
7
|
+
type: string;
|
|
8
|
+
input?: unknown;
|
|
9
|
+
ctx?: Record<string, unknown>;
|
|
10
|
+
}
|
|
11
|
+
/** One REST route the gateway declares. */
|
|
12
|
+
export interface McpGatewayRoute {
|
|
13
|
+
method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
14
|
+
path: string;
|
|
15
|
+
operationId: string;
|
|
16
|
+
parameters: Array<{
|
|
17
|
+
name: string;
|
|
18
|
+
in: string;
|
|
19
|
+
}>;
|
|
20
|
+
}
|
|
21
|
+
/** The gateway version the routes were read from: 0.0.1. */
|
|
22
|
+
export declare const MCP_GATEWAY_ROUTES: ReadonlyArray<McpGatewayRoute>;
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2023-2025 Datalayer, Inc.
|
|
3
|
+
* Distributed under the terms of the Modified BSD License.
|
|
4
|
+
*/
|
|
5
|
+
/** The gateway version the routes were read from: 0.0.1. */
|
|
6
|
+
export const MCP_GATEWAY_ROUTES = [
|
|
7
|
+
{
|
|
8
|
+
method: 'GET',
|
|
9
|
+
path: '/.well-known/mcp-server',
|
|
10
|
+
operationId: 'server_card_endpoint__well_known_mcp_server_get',
|
|
11
|
+
parameters: [],
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
method: 'GET',
|
|
15
|
+
path: '/.well-known/oauth-protected-resource',
|
|
16
|
+
operationId: 'protected_resource_metadata_endpoint__well_known_oauth_protected_resource_get',
|
|
17
|
+
parameters: [],
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
method: 'GET',
|
|
21
|
+
path: '/.well-known/oauth-protected-resource/mcp',
|
|
22
|
+
operationId: 'protected_resource_metadata_endpoint__well_known_oauth_protected_resource_mcp_get',
|
|
23
|
+
parameters: [],
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
method: 'GET',
|
|
27
|
+
path: '/api/mcp/healthz',
|
|
28
|
+
operationId: 'healthz_endpoint_api_mcp_healthz_get',
|
|
29
|
+
parameters: [],
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
method: 'GET',
|
|
33
|
+
path: '/api/mcp/readyz',
|
|
34
|
+
operationId: 'readyz_endpoint_api_mcp_readyz_get',
|
|
35
|
+
parameters: [],
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
method: 'GET',
|
|
39
|
+
path: '/api/mcp/v1/activity',
|
|
40
|
+
operationId: 'activity_endpoint_api_mcp_v1_activity_get',
|
|
41
|
+
parameters: [{ name: 'org', in: 'query' }],
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
method: 'GET',
|
|
45
|
+
path: '/api/mcp/v1/alerts',
|
|
46
|
+
operationId: 'alerts_endpoint_api_mcp_v1_alerts_get',
|
|
47
|
+
parameters: [
|
|
48
|
+
{ name: 'org', in: 'query' },
|
|
49
|
+
{ name: 'scope', in: 'query' },
|
|
50
|
+
{ name: 'unacknowledged', in: 'query' },
|
|
51
|
+
],
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
method: 'POST',
|
|
55
|
+
path: '/api/mcp/v1/alerts/test',
|
|
56
|
+
operationId: 'test_alert_rule_endpoint_api_mcp_v1_alerts_test_post',
|
|
57
|
+
parameters: [],
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
method: 'POST',
|
|
61
|
+
path: '/api/mcp/v1/alerts/{alert_uid}/acknowledge',
|
|
62
|
+
operationId: 'acknowledge_alert_endpoint_api_mcp_v1_alerts__alert_uid__acknowledge_post',
|
|
63
|
+
parameters: [{ name: 'alert_uid', in: 'path' }],
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
method: 'GET',
|
|
67
|
+
path: '/api/mcp/v1/audit',
|
|
68
|
+
operationId: 'audit_endpoint_api_mcp_v1_audit_get',
|
|
69
|
+
parameters: [
|
|
70
|
+
{ name: 'org', in: 'query' },
|
|
71
|
+
{ name: 'team', in: 'query' },
|
|
72
|
+
{ name: 'user', in: 'query' },
|
|
73
|
+
{ name: 'client', in: 'query' },
|
|
74
|
+
{ name: 'agent', in: 'query' },
|
|
75
|
+
{ name: 'tool', in: 'query' },
|
|
76
|
+
{ name: 'method', in: 'query' },
|
|
77
|
+
{ name: 'decision', in: 'query' },
|
|
78
|
+
{ name: 'outcome', in: 'query' },
|
|
79
|
+
{ name: 'notebook', in: 'query' },
|
|
80
|
+
{ name: 'source', in: 'query' },
|
|
81
|
+
{ name: 'task', in: 'query' },
|
|
82
|
+
{ name: 'since', in: 'query' },
|
|
83
|
+
{ name: 'until', in: 'query' },
|
|
84
|
+
{ name: 'cursor', in: 'query' },
|
|
85
|
+
{ name: 'limit', in: 'query' },
|
|
86
|
+
{ name: 'export', in: 'query' },
|
|
87
|
+
],
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
method: 'GET',
|
|
91
|
+
path: '/api/mcp/v1/audit/forwarding',
|
|
92
|
+
operationId: 'audit_forwarding_endpoint_api_mcp_v1_audit_forwarding_get',
|
|
93
|
+
parameters: [{ name: 'org', in: 'query' }],
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
method: 'GET',
|
|
97
|
+
path: '/api/mcp/v1/bindings',
|
|
98
|
+
operationId: 'list_bindings_endpoint_api_mcp_v1_bindings_get',
|
|
99
|
+
parameters: [{ name: 'kind', in: 'query' }],
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
method: 'DELETE',
|
|
103
|
+
path: '/api/mcp/v1/bindings/{binding_uid}',
|
|
104
|
+
operationId: 'delete_binding_endpoint_api_mcp_v1_bindings__binding_uid__delete',
|
|
105
|
+
parameters: [{ name: 'binding_uid', in: 'path' }],
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
method: 'GET',
|
|
109
|
+
path: '/api/mcp/v1/notebooks/{notebook_uid}/tasks',
|
|
110
|
+
operationId: 'list_notebook_tasks_endpoint_api_mcp_v1_notebooks__notebook_uid__tasks_get',
|
|
111
|
+
parameters: [
|
|
112
|
+
{ name: 'notebook_uid', in: 'path' },
|
|
113
|
+
{ name: 'cursor', in: 'query' },
|
|
114
|
+
{ name: 'limit', in: 'query' },
|
|
115
|
+
],
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
method: 'GET',
|
|
119
|
+
path: '/api/mcp/v1/operations/jobs',
|
|
120
|
+
operationId: 'operations_jobs_endpoint_api_mcp_v1_operations_jobs_get',
|
|
121
|
+
parameters: [],
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
method: 'POST',
|
|
125
|
+
path: '/api/mcp/v1/operations/runtime-ended',
|
|
126
|
+
operationId: 'runtime_ended_endpoint_api_mcp_v1_operations_runtime_ended_post',
|
|
127
|
+
parameters: [],
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
method: 'GET',
|
|
131
|
+
path: '/api/mcp/v1/operations/workers',
|
|
132
|
+
operationId: 'operations_workers_endpoint_api_mcp_v1_operations_workers_get',
|
|
133
|
+
parameters: [],
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
method: 'GET',
|
|
137
|
+
path: '/api/mcp/v1/operations/workflows',
|
|
138
|
+
operationId: 'workflows_operations_endpoint_api_mcp_v1_operations_workflows_get',
|
|
139
|
+
parameters: [],
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
method: 'GET',
|
|
143
|
+
path: '/api/mcp/v1/organizations/{org_uid}/overview',
|
|
144
|
+
operationId: 'organization_overview_endpoint_api_mcp_v1_organizations__org_uid__overview_get',
|
|
145
|
+
parameters: [
|
|
146
|
+
{ name: 'org_uid', in: 'path' },
|
|
147
|
+
{ name: 'team', in: 'query' },
|
|
148
|
+
],
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
method: 'GET',
|
|
152
|
+
path: '/api/mcp/v1/organizations/{org_uid}/usage',
|
|
153
|
+
operationId: 'organization_usage_endpoint_api_mcp_v1_organizations__org_uid__usage_get',
|
|
154
|
+
parameters: [
|
|
155
|
+
{ name: 'org_uid', in: 'path' },
|
|
156
|
+
{ name: 'team', in: 'query' },
|
|
157
|
+
],
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
method: 'GET',
|
|
161
|
+
path: '/api/mcp/v1/policy',
|
|
162
|
+
operationId: 'policy_endpoint_api_mcp_v1_policy_get',
|
|
163
|
+
parameters: [
|
|
164
|
+
{ name: 'agent', in: 'query' },
|
|
165
|
+
{ name: 'org', in: 'query' },
|
|
166
|
+
{ name: 'team', in: 'query' },
|
|
167
|
+
],
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
method: 'GET',
|
|
171
|
+
path: '/api/mcp/v1/tasks',
|
|
172
|
+
operationId: 'list_tasks_endpoint_api_mcp_v1_tasks_get',
|
|
173
|
+
parameters: [
|
|
174
|
+
{ name: 'notebook', in: 'query' },
|
|
175
|
+
{ name: 'sandbox', in: 'query' },
|
|
176
|
+
{ name: 'agent', in: 'query' },
|
|
177
|
+
{ name: 'status', in: 'query' },
|
|
178
|
+
{ name: 'org', in: 'query' },
|
|
179
|
+
{ name: 'cursor', in: 'query' },
|
|
180
|
+
{ name: 'limit', in: 'query' },
|
|
181
|
+
],
|
|
182
|
+
},
|
|
183
|
+
{
|
|
184
|
+
method: 'DELETE',
|
|
185
|
+
path: '/api/mcp/v1/tasks/{task_uid}',
|
|
186
|
+
operationId: 'cancel_task_endpoint_api_mcp_v1_tasks__task_uid__delete',
|
|
187
|
+
parameters: [{ name: 'task_uid', in: 'path' }],
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
method: 'GET',
|
|
191
|
+
path: '/api/mcp/v1/tasks/{task_uid}',
|
|
192
|
+
operationId: 'get_task_endpoint_api_mcp_v1_tasks__task_uid__get',
|
|
193
|
+
parameters: [{ name: 'task_uid', in: 'path' }],
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
method: 'GET',
|
|
197
|
+
path: '/api/mcp/v1/tasks/{task_uid}/events',
|
|
198
|
+
operationId: 'task_events_endpoint_api_mcp_v1_tasks__task_uid__events_get',
|
|
199
|
+
parameters: [{ name: 'task_uid', in: 'path' }],
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
method: 'POST',
|
|
203
|
+
path: '/api/mcp/v1/tasks/{task_uid}/input',
|
|
204
|
+
operationId: 'answer_task_endpoint_api_mcp_v1_tasks__task_uid__input_post',
|
|
205
|
+
parameters: [{ name: 'task_uid', in: 'path' }],
|
|
206
|
+
},
|
|
207
|
+
{
|
|
208
|
+
method: 'GET',
|
|
209
|
+
path: '/api/mcp/version',
|
|
210
|
+
operationId: 'version_endpoint_api_mcp_version_get',
|
|
211
|
+
parameters: [],
|
|
212
|
+
},
|
|
213
|
+
];
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Jupyter MCP Server's REST API: tasks, bindings, audit, activity,
|
|
3
|
+
* policy and operations. The MCP endpoint itself is not here — an agent
|
|
4
|
+
* speaks JSON-RPC to it; a browser reads what the agents did.
|
|
5
|
+
*
|
|
6
|
+
* @module api/mcp
|
|
7
|
+
*/
|
|
8
|
+
export * from './generated';
|
|
9
|
+
export * from './gateway';
|
|
10
|
+
export * from './tasks';
|
|
11
|
+
export * from './bindings';
|
|
12
|
+
export * from './audit';
|
|
13
|
+
export * from './activity';
|
|
14
|
+
export * from './organizations';
|
|
15
|
+
export * from './policy';
|
|
16
|
+
export * from './operations';
|
|
17
|
+
export * from './observability';
|
|
@@ -0,0 +1,25 @@
|
|
|
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
|
+
* The Jupyter MCP Server's REST API: tasks, bindings, audit, activity,
|
|
11
|
+
* policy and operations. The MCP endpoint itself is not here — an agent
|
|
12
|
+
* speaks JSON-RPC to it; a browser reads what the agents did.
|
|
13
|
+
*
|
|
14
|
+
* @module api/mcp
|
|
15
|
+
*/
|
|
16
|
+
export * from './generated.js';
|
|
17
|
+
export * from './gateway.js';
|
|
18
|
+
export * from './tasks.js';
|
|
19
|
+
export * from './bindings.js';
|
|
20
|
+
export * from './audit.js';
|
|
21
|
+
export * from './activity.js';
|
|
22
|
+
export * from './organizations.js';
|
|
23
|
+
export * from './policy.js';
|
|
24
|
+
export * from './operations.js';
|
|
25
|
+
export * from './observability.js';
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import type { OtelLog, OtelMetric, OtelSpan } from '../otel/types';
|
|
2
|
+
import type { McpTask } from '../../models/McpTask';
|
|
3
|
+
/**
|
|
4
|
+
* The `service.name` the gateway exports under, and the one its workers use.
|
|
5
|
+
*
|
|
6
|
+
* The bare service name, like every other Datalayer service (`contents`,
|
|
7
|
+
* `iam`, `runtimes`): `instrument(app, name)` is what sets it. A worker is a
|
|
8
|
+
* process of its own and is filed separately, so a worker's last lines stay
|
|
9
|
+
* queryable after the process is gone.
|
|
10
|
+
*/
|
|
11
|
+
export declare const MCP_GATEWAY_SERVICE_NAME = "jupyter-mcp-server";
|
|
12
|
+
/** The `service.name` a worker's relayed output is filed under. */
|
|
13
|
+
export declare const MCP_WORKER_SERVICE_NAME = "jupyter-mcp-worker";
|
|
14
|
+
/**
|
|
15
|
+
* The `service.name` the durable execution service exports under.
|
|
16
|
+
*
|
|
17
|
+
* The `durable.*` metrics come from there, not from the gateway. Querying
|
|
18
|
+
* them against the gateway would be well formed, would be answered
|
|
19
|
+
* truthfully with nothing, and would render a legitimate-looking zero — the
|
|
20
|
+
* same failure that had three panels querying `mcp.forwarded` and
|
|
21
|
+
* `mcp.sandbox_lost`. `serviceNameFor` exists so the question is answered
|
|
22
|
+
* once rather than at each call site.
|
|
23
|
+
*/
|
|
24
|
+
export declare const MCP_DURABLE_SERVICE_NAME = "datalayer-durable";
|
|
25
|
+
/**
|
|
26
|
+
* Which service emits a metric.
|
|
27
|
+
*
|
|
28
|
+
* A metric's service is a property of the metric, not of the caller. Reading
|
|
29
|
+
* it from here is what keeps a new panel from inheriting whichever constant
|
|
30
|
+
* happened to be in scope where it was written.
|
|
31
|
+
*/
|
|
32
|
+
export declare const serviceNameFor: (metric: McpMetricName) => string;
|
|
33
|
+
/** The metric catalog `telemetry.py` owns; no ad-hoc counters. */
|
|
34
|
+
export declare const MCP_METRIC_CATALOG: readonly ["mcp.calls", "mcp.call.duration", "mcp.refusals", "mcp.limit.unenforced", "mcp.forwards", "mcp.workers", "mcp.worker_start_seconds", "mcp.bindings", "mcp.sandbox.lost", "mcp.tasks", "mcp.task.duration", "durable.step.duration", "durable.queue.wait", "durable.recoveries", "sandbox.launch_seconds", "mcp.audit.writes", "mcp.audit.write_failures", "mcp.dependency.duration", "mcp.dependency.timeouts", "mcp.dependency.ready", "mcp.readiness.failures", "mcp.audit.deleted", "mcp.jobs", "mcp.job.duration"];
|
|
35
|
+
export type McpMetricName = (typeof MCP_METRIC_CATALOG)[number];
|
|
36
|
+
/** The four SLIs, and the catalog metric each is read from. */
|
|
37
|
+
export declare const MCP_SLI_METRICS: {
|
|
38
|
+
readonly availability: "mcp.calls";
|
|
39
|
+
readonly latency: "mcp.call.duration";
|
|
40
|
+
readonly taskSuccess: "mcp.tasks";
|
|
41
|
+
readonly sandboxLaunch: "sandbox.launch_seconds";
|
|
42
|
+
};
|
|
43
|
+
export interface McpMetricsFilters {
|
|
44
|
+
/** The `client_id` of one agent: read from spans, not from metrics. */
|
|
45
|
+
agent?: string;
|
|
46
|
+
org?: string;
|
|
47
|
+
/** ISO 8601; points and spans before it are left out. */
|
|
48
|
+
since?: string;
|
|
49
|
+
limit?: number;
|
|
50
|
+
}
|
|
51
|
+
export interface McpSliSummary {
|
|
52
|
+
/** Share of calls that were neither 5xx nor `-32001`; `null` with no call. */
|
|
53
|
+
availability: number | null;
|
|
54
|
+
/** p95 of the synchronous tools' call duration, in milliseconds. */
|
|
55
|
+
p95CallDurationMs: number | null;
|
|
56
|
+
/** `completed` over terminal tasks. */
|
|
57
|
+
taskSuccessRate: number | null;
|
|
58
|
+
/** p95 sandbox launch, in seconds, by provider. */
|
|
59
|
+
p95SandboxLaunchSeconds: Record<string, number>;
|
|
60
|
+
/** How many calls, tasks and launches the numbers rest on. */
|
|
61
|
+
samples: {
|
|
62
|
+
calls: number;
|
|
63
|
+
tasks: number;
|
|
64
|
+
launches: number;
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
export interface McpMetricsSnapshot {
|
|
68
|
+
filters: McpMetricsFilters;
|
|
69
|
+
/** The catalog points read, by metric name. */
|
|
70
|
+
metrics: Partial<Record<McpMetricName, OtelMetric[]>>;
|
|
71
|
+
/** The `mcp.request` spans a per-agent or per-organization reading rests on. */
|
|
72
|
+
spans: OtelSpan[];
|
|
73
|
+
slis: McpSliSummary;
|
|
74
|
+
readAt: string;
|
|
75
|
+
}
|
|
76
|
+
/** The nearest-rank percentile of a sample; `null` for an empty one. */
|
|
77
|
+
export declare const percentile: (values: number[], fraction: number) => number | null;
|
|
78
|
+
/**
|
|
79
|
+
* The SLIs over catalog points — the platform-wide reading.
|
|
80
|
+
*
|
|
81
|
+
* `mcp.calls{outcome}` gives availability, `mcp.call.duration{tool}` the
|
|
82
|
+
* latency, `mcp.tasks{status}` the task success rate and
|
|
83
|
+
* `sandbox.launch_seconds{provider}` the launches.
|
|
84
|
+
*/
|
|
85
|
+
export declare const summarizeMetricPoints: (metrics: Partial<Record<McpMetricName, OtelMetric[]>>, filters?: McpMetricsFilters) => McpSliSummary;
|
|
86
|
+
/**
|
|
87
|
+
* The SLIs over `mcp.request` spans — the per-agent or per-organization
|
|
88
|
+
* reading, since metrics carry neither label.
|
|
89
|
+
*/
|
|
90
|
+
export declare const summarizeRequestSpans: (spans: OtelSpan[], filters?: McpMetricsFilters) => McpSliSummary;
|
|
91
|
+
/** The four SLIs and the catalog, for everyone or for one agent or organization. */
|
|
92
|
+
export declare const fetchMcpMetrics: (token: string, filters?: McpMetricsFilters, otelUrl?: string) => Promise<McpMetricsSnapshot>;
|
|
93
|
+
/** A span with its children, as a tree reads. */
|
|
94
|
+
export interface McpSpanNode {
|
|
95
|
+
span: OtelSpan;
|
|
96
|
+
children: McpSpanNode[];
|
|
97
|
+
}
|
|
98
|
+
/** The spans of a trace as a tree, roots first, siblings by start time. */
|
|
99
|
+
export declare const spanTree: (spans: OtelSpan[]) => McpSpanNode[];
|
|
100
|
+
export interface McpRunTrace {
|
|
101
|
+
taskUid: string;
|
|
102
|
+
traceId: string;
|
|
103
|
+
spans: OtelSpan[];
|
|
104
|
+
tree: McpSpanNode[];
|
|
105
|
+
}
|
|
106
|
+
/** "Show me this run": the spans of the task's trace. A task without one has none yet. */
|
|
107
|
+
export declare const fetchRunTrace: (token: string, task: Pick<McpTask, "uid" | "traceId">, otelUrl?: string) => Promise<McpRunTrace>;
|
|
108
|
+
/**
|
|
109
|
+
* The spans of one trace, named directly.
|
|
110
|
+
*
|
|
111
|
+
* A synchronous call has no task — it finished inside its own request — but
|
|
112
|
+
* it does carry a trace, which is what the audit row records and what
|
|
113
|
+
* "show me this call" means before durable execution exists.
|
|
114
|
+
*/
|
|
115
|
+
export declare const fetchTraceSpans: (token: string, traceId: string, otelUrl?: string) => Promise<McpRunTrace>;
|
|
116
|
+
export interface McpRunLogs {
|
|
117
|
+
taskUid: string;
|
|
118
|
+
traceId: string;
|
|
119
|
+
records: OtelLog[];
|
|
120
|
+
}
|
|
121
|
+
/** The log lines of a run, gateway and worker alike, by the trace they carry. */
|
|
122
|
+
export declare const fetchMcpLogs: (token: string, task: Pick<McpTask, "uid" | "traceId">, options?: {
|
|
123
|
+
limit?: number;
|
|
124
|
+
severity?: string;
|
|
125
|
+
}, otelUrl?: string) => Promise<McpRunLogs>;
|
|
@@ -0,0 +1,254 @@
|
|
|
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
|
+
* The observability of the Jupyter MCP Server, read from the Datalayer OTEL
|
|
11
|
+
* service — never from the gateway, which adds no telemetry route.
|
|
12
|
+
*
|
|
13
|
+
* Audit answers *who did what, and was it allowed*; this answers *how did
|
|
14
|
+
* it run*. A task carries its `trace_id`, so "show me this run" is the
|
|
15
|
+
* task's spans; its logs are the log records of that trace; and the four
|
|
16
|
+
* SLIs are read from the gateway's metric catalog. Metrics carry no user,
|
|
17
|
+
* agent or organization label by design, so a per-agent reading is
|
|
18
|
+
* computed from the `mcp.request` spans, which do carry `client.id` and
|
|
19
|
+
* `org.uid`.
|
|
20
|
+
*
|
|
21
|
+
* @module api/mcp/observability
|
|
22
|
+
*/
|
|
23
|
+
import { DEFAULT_SERVICE_URLS } from '../constants.js';
|
|
24
|
+
import { getTrace, listTraces } from '../otel/traces.js';
|
|
25
|
+
import { queryMetrics } from '../otel/metrics.js';
|
|
26
|
+
import { queryLogs } from '../otel/logs.js';
|
|
27
|
+
/**
|
|
28
|
+
* The `service.name` the gateway exports under, and the one its workers use.
|
|
29
|
+
*
|
|
30
|
+
* The bare service name, like every other Datalayer service (`contents`,
|
|
31
|
+
* `iam`, `runtimes`): `instrument(app, name)` is what sets it. A worker is a
|
|
32
|
+
* process of its own and is filed separately, so a worker's last lines stay
|
|
33
|
+
* queryable after the process is gone.
|
|
34
|
+
*/
|
|
35
|
+
export const MCP_GATEWAY_SERVICE_NAME = 'jupyter-mcp-server';
|
|
36
|
+
/** The `service.name` a worker's relayed output is filed under. */
|
|
37
|
+
export const MCP_WORKER_SERVICE_NAME = 'jupyter-mcp-worker';
|
|
38
|
+
/**
|
|
39
|
+
* The `service.name` the durable execution service exports under.
|
|
40
|
+
*
|
|
41
|
+
* The `durable.*` metrics come from there, not from the gateway. Querying
|
|
42
|
+
* them against the gateway would be well formed, would be answered
|
|
43
|
+
* truthfully with nothing, and would render a legitimate-looking zero — the
|
|
44
|
+
* same failure that had three panels querying `mcp.forwarded` and
|
|
45
|
+
* `mcp.sandbox_lost`. `serviceNameFor` exists so the question is answered
|
|
46
|
+
* once rather than at each call site.
|
|
47
|
+
*/
|
|
48
|
+
export const MCP_DURABLE_SERVICE_NAME = 'datalayer-durable';
|
|
49
|
+
/**
|
|
50
|
+
* Which service emits a metric.
|
|
51
|
+
*
|
|
52
|
+
* A metric's service is a property of the metric, not of the caller. Reading
|
|
53
|
+
* it from here is what keeps a new panel from inheriting whichever constant
|
|
54
|
+
* happened to be in scope where it was written.
|
|
55
|
+
*/
|
|
56
|
+
export const serviceNameFor = (metric) => metric.startsWith('durable.')
|
|
57
|
+
? MCP_DURABLE_SERVICE_NAME
|
|
58
|
+
: MCP_GATEWAY_SERVICE_NAME;
|
|
59
|
+
/** The metric catalog `telemetry.py` owns; no ad-hoc counters. */
|
|
60
|
+
export const MCP_METRIC_CATALOG = [
|
|
61
|
+
'mcp.calls',
|
|
62
|
+
'mcp.call.duration',
|
|
63
|
+
'mcp.refusals',
|
|
64
|
+
// A limit *not* applied because the figure it compares against could not
|
|
65
|
+
// be read. Distinct from a refusal, which is the limit working: an
|
|
66
|
+
// organization whose budget stopped being enforced otherwise looks exactly
|
|
67
|
+
// like one that never set a budget.
|
|
68
|
+
'mcp.limit.unenforced',
|
|
69
|
+
'mcp.forwards',
|
|
70
|
+
'mcp.workers',
|
|
71
|
+
'mcp.worker_start_seconds',
|
|
72
|
+
'mcp.bindings',
|
|
73
|
+
'mcp.sandbox.lost',
|
|
74
|
+
'mcp.tasks',
|
|
75
|
+
'mcp.task.duration',
|
|
76
|
+
'durable.step.duration',
|
|
77
|
+
'durable.queue.wait',
|
|
78
|
+
'durable.recoveries',
|
|
79
|
+
'sandbox.launch_seconds',
|
|
80
|
+
'mcp.audit.writes',
|
|
81
|
+
'mcp.audit.write_failures',
|
|
82
|
+
'mcp.dependency.duration',
|
|
83
|
+
'mcp.dependency.timeouts',
|
|
84
|
+
'mcp.dependency.ready',
|
|
85
|
+
'mcp.readiness.failures',
|
|
86
|
+
'mcp.audit.deleted',
|
|
87
|
+
'mcp.jobs',
|
|
88
|
+
'mcp.job.duration',
|
|
89
|
+
];
|
|
90
|
+
/** The four SLIs, and the catalog metric each is read from. */
|
|
91
|
+
export const MCP_SLI_METRICS = {
|
|
92
|
+
availability: 'mcp.calls',
|
|
93
|
+
latency: 'mcp.call.duration',
|
|
94
|
+
taskSuccess: 'mcp.tasks',
|
|
95
|
+
sandboxLaunch: 'sandbox.launch_seconds',
|
|
96
|
+
};
|
|
97
|
+
/** The nearest-rank percentile of a sample; `null` for an empty one. */
|
|
98
|
+
export const percentile = (values, fraction) => {
|
|
99
|
+
if (values.length === 0) {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
const sorted = [...values].sort((a, b) => a - b);
|
|
103
|
+
const rank = Math.min(sorted.length - 1, Math.max(0, Math.ceil(fraction * sorted.length) - 1));
|
|
104
|
+
return sorted[rank];
|
|
105
|
+
};
|
|
106
|
+
const attribute = (holder, name) => String(holder.attributes?.[name] ?? '');
|
|
107
|
+
const notBefore = (timestamp, since) => !since || !timestamp || timestamp >= since;
|
|
108
|
+
/** Whether an `mcp.request` span is a failed call in the availability sense. */
|
|
109
|
+
const isUnavailable = (span) => {
|
|
110
|
+
const status = attribute(span, 'http.response.status_code') || attribute(span, 'http.status_code');
|
|
111
|
+
const rpc = attribute(span, 'rpc.jsonrpc.error_code') || attribute(span, 'mcp.error.code');
|
|
112
|
+
return status.startsWith('5') || rpc === '-32001';
|
|
113
|
+
};
|
|
114
|
+
/**
|
|
115
|
+
* The SLIs over catalog points — the platform-wide reading.
|
|
116
|
+
*
|
|
117
|
+
* `mcp.calls{outcome}` gives availability, `mcp.call.duration{tool}` the
|
|
118
|
+
* latency, `mcp.tasks{status}` the task success rate and
|
|
119
|
+
* `sandbox.launch_seconds{provider}` the launches.
|
|
120
|
+
*/
|
|
121
|
+
export const summarizeMetricPoints = (metrics, filters = {}) => {
|
|
122
|
+
const within = (point) => notBefore(point.timestamp, filters.since);
|
|
123
|
+
const calls = (metrics['mcp.calls'] ?? []).filter(within);
|
|
124
|
+
const totalCalls = calls.reduce((sum, point) => sum + point.value, 0);
|
|
125
|
+
const failedCalls = calls
|
|
126
|
+
.filter(point => ['error', 'unavailable'].includes(attribute(point, 'outcome')))
|
|
127
|
+
.reduce((sum, point) => sum + point.value, 0);
|
|
128
|
+
const durations = (metrics['mcp.call.duration'] ?? []).filter(within).map(point => point.value);
|
|
129
|
+
const tasks = (metrics['mcp.tasks'] ?? []).filter(within);
|
|
130
|
+
const terminal = tasks.filter(point => ['completed', 'failed', 'cancelled'].includes(attribute(point, 'status')));
|
|
131
|
+
const totalTerminal = terminal.reduce((sum, point) => sum + point.value, 0);
|
|
132
|
+
const completed = terminal
|
|
133
|
+
.filter(point => attribute(point, 'status') === 'completed')
|
|
134
|
+
.reduce((sum, point) => sum + point.value, 0);
|
|
135
|
+
const launches = (metrics['sandbox.launch_seconds'] ?? []).filter(within);
|
|
136
|
+
const byProvider = new Map();
|
|
137
|
+
for (const point of launches) {
|
|
138
|
+
const provider = attribute(point, 'provider') || 'unknown';
|
|
139
|
+
byProvider.set(provider, [...(byProvider.get(provider) ?? []), point.value]);
|
|
140
|
+
}
|
|
141
|
+
const p95SandboxLaunchSeconds = {};
|
|
142
|
+
for (const [provider, values] of byProvider) {
|
|
143
|
+
const p95 = percentile(values, 0.95);
|
|
144
|
+
if (p95 !== null) {
|
|
145
|
+
p95SandboxLaunchSeconds[provider] = p95;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
return {
|
|
149
|
+
availability: totalCalls > 0 ? (totalCalls - failedCalls) / totalCalls : null,
|
|
150
|
+
p95CallDurationMs: percentile(durations, 0.95),
|
|
151
|
+
taskSuccessRate: totalTerminal > 0 ? completed / totalTerminal : null,
|
|
152
|
+
p95SandboxLaunchSeconds,
|
|
153
|
+
samples: { calls: totalCalls, tasks: totalTerminal, launches: launches.length },
|
|
154
|
+
};
|
|
155
|
+
};
|
|
156
|
+
/**
|
|
157
|
+
* The SLIs over `mcp.request` spans — the per-agent or per-organization
|
|
158
|
+
* reading, since metrics carry neither label.
|
|
159
|
+
*/
|
|
160
|
+
export const summarizeRequestSpans = (spans, filters = {}) => {
|
|
161
|
+
const selected = spans.filter(span => span.span_name === 'mcp.request' &&
|
|
162
|
+
notBefore(span.start_time, filters.since) &&
|
|
163
|
+
(!filters.agent || attribute(span, 'client.id') === filters.agent) &&
|
|
164
|
+
(!filters.org || attribute(span, 'org.uid') === filters.org));
|
|
165
|
+
const unavailable = selected.filter(isUnavailable).length;
|
|
166
|
+
const tasks = new Map();
|
|
167
|
+
for (const span of selected) {
|
|
168
|
+
const taskId = attribute(span, 'mcp.task.id');
|
|
169
|
+
if (taskId) {
|
|
170
|
+
tasks.set(taskId, attribute(span, 'mcp.task.status') || span.status_code || '');
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
const terminal = [...tasks.values()].filter(status => ['completed', 'failed', 'cancelled'].includes(status));
|
|
174
|
+
const completed = terminal.filter(status => status === 'completed').length;
|
|
175
|
+
return {
|
|
176
|
+
availability: selected.length > 0 ? (selected.length - unavailable) / selected.length : null,
|
|
177
|
+
p95CallDurationMs: percentile(selected.filter(span => !attribute(span, 'mcp.task.id')).map(span => span.duration_ms), 0.95),
|
|
178
|
+
taskSuccessRate: terminal.length > 0 ? completed / terminal.length : null,
|
|
179
|
+
p95SandboxLaunchSeconds: {},
|
|
180
|
+
samples: { calls: selected.length, tasks: terminal.length, launches: 0 },
|
|
181
|
+
};
|
|
182
|
+
};
|
|
183
|
+
/** The four SLIs and the catalog, for everyone or for one agent or organization. */
|
|
184
|
+
export const fetchMcpMetrics = async (token, filters = {}, otelUrl = DEFAULT_SERVICE_URLS.OTEL) => {
|
|
185
|
+
const limit = filters.limit ?? 500;
|
|
186
|
+
const names = Object.values(MCP_SLI_METRICS);
|
|
187
|
+
const pages = await Promise.all(names.map(name => queryMetrics(token, { metricName: name, serviceName: serviceNameFor(name), limit }, otelUrl)));
|
|
188
|
+
const metrics = {};
|
|
189
|
+
names.forEach((name, index) => {
|
|
190
|
+
metrics[name] = pages[index].data ?? [];
|
|
191
|
+
});
|
|
192
|
+
const scoped = Boolean(filters.agent || filters.org);
|
|
193
|
+
const spans = scoped
|
|
194
|
+
? (await listTraces(token, { serviceName: MCP_GATEWAY_SERVICE_NAME, limit }, otelUrl)).data ?? []
|
|
195
|
+
: [];
|
|
196
|
+
return {
|
|
197
|
+
filters,
|
|
198
|
+
metrics,
|
|
199
|
+
spans,
|
|
200
|
+
slis: scoped ? summarizeRequestSpans(spans, filters) : summarizeMetricPoints(metrics, filters),
|
|
201
|
+
readAt: new Date().toISOString(),
|
|
202
|
+
};
|
|
203
|
+
};
|
|
204
|
+
/** The spans of a trace as a tree, roots first, siblings by start time. */
|
|
205
|
+
export const spanTree = (spans) => {
|
|
206
|
+
const nodes = new Map();
|
|
207
|
+
for (const span of spans) {
|
|
208
|
+
nodes.set(span.span_id, { span, children: [] });
|
|
209
|
+
}
|
|
210
|
+
const roots = [];
|
|
211
|
+
for (const node of nodes.values()) {
|
|
212
|
+
const parent = node.span.parent_span_id ? nodes.get(node.span.parent_span_id) : undefined;
|
|
213
|
+
(parent ? parent.children : roots).push(node);
|
|
214
|
+
}
|
|
215
|
+
const byStart = (a, b) => a.span.start_time.localeCompare(b.span.start_time);
|
|
216
|
+
const sort = (list) => {
|
|
217
|
+
list.sort(byStart);
|
|
218
|
+
list.forEach(node => sort(node.children));
|
|
219
|
+
};
|
|
220
|
+
sort(roots);
|
|
221
|
+
return roots;
|
|
222
|
+
};
|
|
223
|
+
/** "Show me this run": the spans of the task's trace. A task without one has none yet. */
|
|
224
|
+
export const fetchRunTrace = async (token, task, otelUrl = DEFAULT_SERVICE_URLS.OTEL) => {
|
|
225
|
+
if (!task.traceId) {
|
|
226
|
+
return { taskUid: task.uid, traceId: '', spans: [], tree: [] };
|
|
227
|
+
}
|
|
228
|
+
const trace = await getTrace(token, task.traceId, otelUrl);
|
|
229
|
+
const spans = trace.data ?? [];
|
|
230
|
+
return { taskUid: task.uid, traceId: task.traceId, spans, tree: spanTree(spans) };
|
|
231
|
+
};
|
|
232
|
+
/**
|
|
233
|
+
* The spans of one trace, named directly.
|
|
234
|
+
*
|
|
235
|
+
* A synchronous call has no task — it finished inside its own request — but
|
|
236
|
+
* it does carry a trace, which is what the audit row records and what
|
|
237
|
+
* "show me this call" means before durable execution exists.
|
|
238
|
+
*/
|
|
239
|
+
export const fetchTraceSpans = async (token, traceId, otelUrl = DEFAULT_SERVICE_URLS.OTEL) => {
|
|
240
|
+
if (!traceId) {
|
|
241
|
+
return { taskUid: '', traceId: '', spans: [], tree: [] };
|
|
242
|
+
}
|
|
243
|
+
const trace = await getTrace(token, traceId, otelUrl);
|
|
244
|
+
const spans = trace.data ?? [];
|
|
245
|
+
return { taskUid: '', traceId, spans, tree: spanTree(spans) };
|
|
246
|
+
};
|
|
247
|
+
/** The log lines of a run, gateway and worker alike, by the trace they carry. */
|
|
248
|
+
export const fetchMcpLogs = async (token, task, options = {}, otelUrl = DEFAULT_SERVICE_URLS.OTEL) => {
|
|
249
|
+
if (!task.traceId) {
|
|
250
|
+
return { taskUid: task.uid, traceId: '', records: [] };
|
|
251
|
+
}
|
|
252
|
+
const page = await queryLogs(token, { traceId: task.traceId, limit: options.limit ?? 200, severity: options.severity }, otelUrl);
|
|
253
|
+
return { taskUid: task.uid, traceId: task.traceId, records: page.data ?? [] };
|
|
254
|
+
};
|