@oneuptime/common 14.0.8 → 14.0.9
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/Models/DatabaseModels/Index.ts +2 -0
- package/Models/DatabaseModels/KubernetesAiAgent.ts +364 -0
- package/Models/DatabaseModels/KubernetesCluster.ts +3 -3
- package/Models/DatabaseModels/Project.ts +55 -5
- package/Models/DatabaseModels/ProxmoxResource.ts +49 -1
- package/Models/DatabaseModels/RunnerJob.ts +75 -0
- package/Models/DatabaseModels/TeamComplianceSetting.ts +143 -2
- package/Models/DatabaseModels/WorkspaceProjectAuthToken.ts +17 -0
- package/Server/API/AIChatAPI.ts +6 -3
- package/Server/API/AIInvestigationAPI.ts +17 -10
- package/Server/API/AutoRemediationAPI.ts +207 -25
- package/Server/API/KubernetesClusterAiAccessAPI.ts +623 -21
- package/Server/API/MicrosoftTeamsAPI.ts +93 -14
- package/Server/API/ProxmoxResourceAPI.ts +244 -14
- package/Server/Infrastructure/GlobalCache.ts +32 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1796000000000-AddTeamComplianceRuleScope.ts +99 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1796100000000-AddKubernetesAiAgentAndAiDefaults.ts +137 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1796200000000-AddProxmoxResourceNativePushColumns.ts +42 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
- package/Server/Middleware/TelemetryIngest.ts +41 -18
- package/Server/Services/AIService.ts +70 -1
- package/Server/Services/AlertService.ts +352 -11
- package/Server/Services/AlertSeverityService.ts +65 -15
- package/Server/Services/AutoRemediationRuleService.ts +1 -1
- package/Server/Services/IncidentService.ts +280 -104
- package/Server/Services/IncidentSeverityService.ts +66 -15
- package/Server/Services/KubernetesAiAgentJobService.ts +185 -0
- package/Server/Services/KubernetesAiAgentService.ts +1634 -0
- package/Server/Services/KubernetesClusterAiAccessService.ts +1118 -451
- package/Server/Services/KubernetesClusterService.ts +129 -21
- package/Server/Services/ProjectService.ts +32 -0
- package/Server/Services/ProxmoxResourceService.ts +322 -5
- package/Server/Services/RunnerJobService.ts +241 -104
- package/Server/Services/RunnerService.ts +1 -1
- package/Server/Services/ScheduledMaintenanceService.ts +737 -1
- package/Server/Services/ScheduledMaintenanceStateTimelineService.ts +414 -56
- package/Server/Services/TeamComplianceSettingService.ts +1125 -9
- package/Server/Utils/AI/ClusterAccess/ClusterAccessContext.ts +67 -9
- package/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.ts +39 -10
- package/Server/Utils/AI/ClusterAccess/KubectlJobRunner.ts +14 -3
- package/Server/Utils/AI/Remediation/RemediationCommandTools.ts +37 -15
- package/Server/Utils/AI/Remediation/RemediationExecutionRunner.ts +67 -24
- package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +48 -5
- package/Server/Utils/AI/SRE/IncidentPostmortemRunner.ts +40 -8
- package/Server/Utils/AI/SRE/InvestigationEligibility.ts +13 -2
- package/Server/Utils/AI/SRE/InvestigationGrader.ts +1 -1
- package/Server/Utils/AutoRemediation/CommandPlanExecutor.ts +6 -1
- package/Server/Utils/Telemetry/InventoryEntityRegistry.ts +133 -7
- package/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.ts +58 -4
- package/Server/Utils/Telemetry/ProxmoxNativeNodeLiveness.ts +447 -0
- package/Server/Utils/Telemetry/ProxmoxNativePush.ts +903 -0
- package/Server/Utils/Telemetry/TelemetryEntity.ts +87 -27
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +684 -47
- package/Tests/App/AdminDashboard/RowActionPlacementOverrides.test.tsx +278 -0
- package/Tests/App/Dashboard/AIChatChartWidgetZoom.test.tsx +738 -0
- package/Tests/App/Dashboard/AIFeaturesSettingsPointers.test.tsx +147 -0
- package/Tests/App/Dashboard/AIInsightsKubernetesClusterPage.test.tsx +1523 -0
- package/Tests/App/Dashboard/AdminUserNotificationMethodsPage.test.tsx +463 -3
- package/Tests/App/Dashboard/AffectedResourcesPickerDropdownPlacement.test.tsx +958 -0
- package/Tests/App/Dashboard/AffectedResourcesPickerFocusLeave.test.tsx +595 -0
- package/Tests/App/Dashboard/AskAiAvailability.test.ts +20 -3
- package/Tests/App/Dashboard/AskAiDisabled.test.tsx +8 -3
- package/Tests/App/Dashboard/CephRateChartReload.test.tsx +1456 -0
- package/Tests/App/Dashboard/CephTimeRangeZoom.test.tsx +1229 -0
- package/Tests/App/Dashboard/ChartCardTimeRangeZoom.test.tsx +151 -0
- package/Tests/App/Dashboard/ChartCardZoomAffordances.test.tsx +257 -0
- package/Tests/App/Dashboard/ChartRefetchFrame.test.tsx +141 -0
- package/Tests/App/Dashboard/ChartZoomHarness.tsx +249 -0
- package/Tests/App/Dashboard/ChartZoomStandIn.tsx +131 -0
- package/Tests/App/Dashboard/CloudServerlessSlowLoads.test.tsx +628 -0
- package/Tests/App/Dashboard/CloudServerlessTimeRangeZoom.test.tsx +607 -0
- package/Tests/App/Dashboard/ClusterAccessNotice.test.tsx +91 -19
- package/Tests/App/Dashboard/CompanionMetricsTabZoom.test.tsx +632 -0
- package/Tests/App/Dashboard/ContainerChartZoomStandIn.tsx +195 -0
- package/Tests/App/Dashboard/ContainerHostOverviewSlowLoads.test.tsx +542 -0
- package/Tests/App/Dashboard/ContainerHostOverviewTimeRangeZoom.test.tsx +848 -0
- package/Tests/App/Dashboard/ContainerMetricsTimeRangeZoom.test.tsx +561 -0
- package/Tests/App/Dashboard/DashboardBoardWideZoomShell.test.tsx +1147 -0
- package/Tests/App/Dashboard/DashboardEditPermissions.test.tsx +3 -2
- package/Tests/App/Dashboard/DashboardHistogramWidgetDragCursor.test.tsx +399 -0
- package/Tests/App/Dashboard/DashboardHistogramWidgetZoom.test.tsx +985 -0
- package/Tests/App/Dashboard/DashboardHistogramWidgetZoomHint.test.tsx +803 -0
- package/Tests/App/Dashboard/DashboardLazyPages.test.tsx +1 -0
- package/Tests/App/Dashboard/DashboardSettingsPreviewZoom.test.tsx +679 -0
- package/Tests/App/Dashboard/DashboardSloAndDataSourceChartZoom.test.tsx +881 -0
- package/Tests/App/Dashboard/DashboardTraceStatusWidgets.test.tsx +878 -0
- package/Tests/App/Dashboard/DatabaseMetricChartModalTimeRangeZoom.test.tsx +442 -0
- package/Tests/App/Dashboard/DatabaseOverviewTimeRangeZoom.test.tsx +831 -0
- package/Tests/App/Dashboard/DatabaseServerComponents.test.tsx +43 -0
- package/Tests/App/Dashboard/DockerSwarmInsightsTimeRangeZoom.test.tsx +524 -0
- package/Tests/App/Dashboard/DockerSwarmRateChartRefresh.test.tsx +259 -0
- package/Tests/App/Dashboard/EdgeDetailPanelHistory.test.tsx +763 -0
- package/Tests/App/Dashboard/EdgeDetailPanelTimeRangeZoom.test.tsx +547 -0
- package/Tests/App/Dashboard/EdgeHistoryBucketsCases.tsx +565 -0
- package/Tests/App/Dashboard/EdgeHistoryBucketsKathmandu.test.tsx +73 -0
- package/Tests/App/Dashboard/EdgeHistoryBucketsKolkata.test.tsx +74 -0
- package/Tests/App/Dashboard/EdgeHistoryBucketsNewYork.test.tsx +72 -0
- package/Tests/App/Dashboard/EdgeHistoryBucketsUtc.test.tsx +72 -0
- package/Tests/App/Dashboard/EmbeddedMetricCardRefresh.test.tsx +310 -0
- package/Tests/App/Dashboard/EmbeddedMetricCardTimeRangeZoom.test.tsx +536 -0
- package/Tests/App/Dashboard/EscalationRuleReadiness.test.tsx +3 -1
- package/Tests/App/Dashboard/EscalationRuleRowActions.test.tsx +660 -0
- package/Tests/App/Dashboard/EventNotes.test.tsx +2 -2
- package/Tests/App/Dashboard/EventOverviewPages.test.tsx +587 -13
- package/Tests/App/Dashboard/EventOverviewSnapshotExplorerZoom.test.tsx +1139 -0
- package/Tests/App/Dashboard/EventOverviewSnapshotZoomAcrossTabs.test.tsx +1057 -0
- package/Tests/App/Dashboard/EventOverviewTelemetrySnapshotZoom.test.tsx +757 -0
- package/Tests/App/Dashboard/ExceptionOccurrenceTrendZoom.test.tsx +675 -0
- package/Tests/App/Dashboard/ExceptionOccurrencesZoomSurvivesViewSwitch.test.tsx +405 -0
- package/Tests/App/Dashboard/ExceptionSignalPages.test.tsx +67 -3
- package/Tests/App/Dashboard/ExceptionTablesSpanStatus.test.tsx +515 -0
- package/Tests/App/Dashboard/ExplorerOwnZoomRegression.test.tsx +739 -0
- package/Tests/App/Dashboard/FlowBandwidthAxisCases.tsx +461 -0
- package/Tests/App/Dashboard/FlowBandwidthAxisKathmandu.test.tsx +25 -0
- package/Tests/App/Dashboard/FlowBandwidthAxisKolkata.test.tsx +25 -0
- package/Tests/App/Dashboard/FlowBandwidthAxisNewYork.test.tsx +25 -0
- package/Tests/App/Dashboard/FlowBandwidthAxisUtc.test.tsx +24 -0
- package/Tests/App/Dashboard/FlowTopTalkersZoomRefetch.test.tsx +722 -0
- package/Tests/App/Dashboard/FlowViewportGuard.test.tsx +2526 -0
- package/Tests/App/Dashboard/HostPagesSlowLoads.test.tsx +872 -0
- package/Tests/App/Dashboard/HostPagesTimeRangeZoom.test.tsx +1208 -0
- package/Tests/App/Dashboard/IncidentRootCauseTimeRangeZoom.test.tsx +358 -0
- package/Tests/App/Dashboard/InfrastructureGraph.test.tsx +100 -9
- package/Tests/App/Dashboard/InfrastructureMetricsTabTimeRangeZoom.test.tsx +485 -0
- package/Tests/App/Dashboard/InvestigationDrawerCompanionZoom.test.tsx +655 -0
- package/Tests/App/Dashboard/InvestigationDrawerZoom.test.tsx +830 -0
- package/Tests/App/Dashboard/InvestigationNotStarted.test.tsx +338 -2
- package/Tests/App/Dashboard/InvoicesPayInvoice.test.tsx +454 -16
- package/Tests/App/Dashboard/KubernetesClusterAiAccessSettings.test.ts +799 -819
- package/Tests/App/Dashboard/KubernetesClusterAiAgentOverviewCard.test.tsx +367 -0
- package/Tests/App/Dashboard/KubernetesClusterAiAgentStatus.test.ts +1202 -0
- package/Tests/App/Dashboard/KubernetesClusterAiDocumentationMarkdown.test.ts +106 -0
- package/Tests/App/Dashboard/KubernetesClusterAiNavigation.test.tsx +354 -0
- package/Tests/App/Dashboard/KubernetesClusterAiPage.test.tsx +1884 -2054
- package/Tests/App/Dashboard/KubernetesClusterAiPageServerParity.test.ts +478 -179
- package/Tests/App/Dashboard/KubernetesClusterMetricTooltips.test.ts +50 -0
- package/Tests/App/Dashboard/KubernetesClusterOverviewTooltips.test.tsx +2 -1
- package/Tests/App/Dashboard/KubernetesClusterOverviewZoom.test.tsx +1217 -0
- package/Tests/App/Dashboard/KubernetesClusterPagesZoom.test.tsx +731 -0
- package/Tests/App/Dashboard/KubernetesCostsLoadRecovery.test.tsx +869 -0
- package/Tests/App/Dashboard/KubernetesCostsZoom.test.tsx +1214 -0
- package/Tests/App/Dashboard/KubernetesCostsZoomExactHours.test.tsx +692 -0
- package/Tests/App/Dashboard/KubernetesNetworkThroughputReload.test.tsx +902 -0
- package/Tests/App/Dashboard/KubernetesNetworkZoomBucketEdges.test.tsx +571 -0
- package/Tests/App/Dashboard/KubernetesOverviewZoomBucketEdges.test.tsx +697 -0
- package/Tests/App/Dashboard/KubernetesResourceMetricsTabZoom.test.tsx +633 -0
- package/Tests/App/Dashboard/LogsExplorerTimeRangeZoom.test.tsx +470 -0
- package/Tests/App/Dashboard/LogsInsightsTimeRangeZoom.test.tsx +948 -0
- package/Tests/App/Dashboard/LogsViewerPinnedWindowZoom.test.tsx +486 -0
- package/Tests/App/Dashboard/MetricChartsBucketInspectorDoubleClick.test.tsx +1001 -0
- package/Tests/App/Dashboard/MetricExplorerInvestigationAutoRefresh.test.tsx +514 -0
- package/Tests/App/Dashboard/MetricExplorerSavedViewZoomRoundTrip.test.tsx +581 -0
- package/Tests/App/Dashboard/MetricExplorerTimeRangeZoom.test.tsx +1162 -0
- package/Tests/App/Dashboard/MetricMonitorPreviewZoomLabel.test.ts +72 -0
- package/Tests/App/Dashboard/MetricRowSparklineTimeRangeZoom.test.tsx +204 -0
- package/Tests/App/Dashboard/MetricViewFirstResultLands.test.tsx +408 -0
- package/Tests/App/Dashboard/MetricViewOwnZoomResetPlacement.test.tsx +952 -0
- package/Tests/App/Dashboard/MetricViewTimeRange.test.ts +139 -0
- package/Tests/App/Dashboard/MetricViewTimeRangeZoom.test.tsx +556 -0
- package/Tests/App/Dashboard/MonitorMetricsChartWrappersZoom.test.tsx +552 -0
- package/Tests/App/Dashboard/MonitorMetricsTabsTimeRangeZoom.test.tsx +740 -0
- package/Tests/App/Dashboard/MonitorOverviewChartsTimeRangeZoom.test.tsx +735 -0
- package/Tests/App/Dashboard/MonitorStepPreviewsTimeRangeZoom.test.tsx +835 -0
- package/Tests/App/Dashboard/NetworkDeviceTimeRangeZoom.test.tsx +1115 -0
- package/Tests/App/Dashboard/OnCallPreventionGuards.test.tsx +186 -17
- package/Tests/App/Dashboard/OnCallRulesDeleteGuard.test.tsx +155 -46
- package/Tests/App/Dashboard/PasskeySettings.test.tsx +87 -2
- package/Tests/App/Dashboard/ProjectAISettingsPages.test.tsx +884 -0
- package/Tests/App/Dashboard/ProxmoxNodeRemove.test.tsx +621 -0
- package/Tests/App/Dashboard/ProxmoxOverviewSlowLoads.test.tsx +584 -0
- package/Tests/App/Dashboard/ProxmoxPagesTimeRangeZoom.test.tsx +823 -0
- package/Tests/App/Dashboard/ProxmoxRateChartReload.test.tsx +1253 -0
- package/Tests/App/Dashboard/PublicDashboardBoardWideZoom.test.tsx +605 -0
- package/Tests/App/Dashboard/RealRowsLineChart.tsx +250 -0
- package/Tests/App/Dashboard/RechartsHostsPlotCursor.test.tsx +513 -0
- package/Tests/App/Dashboard/RowActionPlacementOverrides.test.tsx +865 -0
- package/Tests/App/Dashboard/RumOverviewTimeRangeZoom.test.tsx +877 -0
- package/Tests/App/Dashboard/RunnerKubernetesAgentForm.test.tsx +20 -4
- package/Tests/App/Dashboard/RunnerSupersededByAiAgentNote.test.tsx +296 -0
- package/Tests/App/Dashboard/SecurityEventConnectionsTable.test.tsx +146 -36
- package/Tests/App/Dashboard/ServiceDatabaseSlowLoads.test.tsx +1166 -0
- package/Tests/App/Dashboard/ServiceMapGraph.test.tsx +1243 -104
- package/Tests/App/Dashboard/ServiceOverviewTimeRangeZoom.test.tsx +792 -0
- package/Tests/App/Dashboard/SloBudgetBurnDownZoom.test.tsx +771 -0
- package/Tests/App/Dashboard/SloBudgetBurnDownZoomAffordances.test.tsx +380 -0
- package/Tests/App/Dashboard/SloEventMetricsBarChartZoom.test.tsx +369 -0
- package/Tests/App/Dashboard/SloHistoryChartsTimeRangeZoom.test.tsx +694 -0
- package/Tests/App/Dashboard/SloHistoryChartsZoomAffordances.test.tsx +497 -0
- package/Tests/App/Dashboard/SloMetricsTimeRangeZoom.test.tsx +541 -0
- package/Tests/App/Dashboard/SlowLoadHarness.ts +123 -0
- package/Tests/App/Dashboard/SnapshotExplorerPrimaryZoom.test.tsx +1194 -0
- package/Tests/App/Dashboard/SnapshotViewerPinnedWindow.test.tsx +620 -0
- package/Tests/App/Dashboard/TelemetrySnapshotPanelTimeRangeZoom.test.tsx +765 -0
- package/Tests/App/Dashboard/TelemetrySnapshotZoom.test.tsx +516 -0
- package/Tests/App/Dashboard/TelemetrySnapshotZoomAcrossTabs.test.tsx +827 -0
- package/Tests/App/Dashboard/TimeRangeZoomPageHarness.tsx +463 -0
- package/Tests/App/Dashboard/TraceChartEditorStatusSplit.test.tsx +543 -0
- package/Tests/App/Dashboard/TraceStatusPresentation.test.tsx +967 -0
- package/Tests/App/Dashboard/TraceTimelineMinimapZoom.test.tsx +315 -0
- package/Tests/App/Dashboard/TracesAnalyticsStatusSplit.test.tsx +778 -0
- package/Tests/App/Dashboard/TracesAnalyticsViewZoom.test.tsx +349 -0
- package/Tests/App/Dashboard/TracesExplorerTimeRangeZoom.test.tsx +551 -0
- package/Tests/App/Dashboard/TracesStatusChartAndFacet.test.tsx +687 -0
- package/Tests/App/Dashboard/TracesViewerStaleResponses.test.tsx +458 -0
- package/Tests/App/Dashboard/UptimeStripsExcludedFromZoom.test.tsx +406 -0
- package/Tests/App/Dashboard/VMwareOverviewSlowLoads.test.tsx +535 -0
- package/Tests/App/Dashboard/VMwarePagesTimeRangeZoom.test.tsx +606 -0
- package/Tests/App/Dashboard/ValueWidgetSparklineStaleHover.test.tsx +1292 -0
- package/Tests/App/Dashboard/ValueWidgetSparklineZoom.test.tsx +765 -0
- package/Tests/App/StatusPage/StatusPageResourceExplorer.test.tsx +98 -0
- package/Tests/Models/DatabaseModels/KubernetesAiAgentModel.test.ts +295 -0
- package/Tests/Models/DatabaseModels/TeamComplianceSettingModel.test.ts +347 -0
- package/Tests/Server/API/AIChatRouteAuthorization.test.ts +58 -0
- package/Tests/Server/API/AIGenerationProjectAIToggle.test.ts +1 -1
- package/Tests/Server/API/AIInvestigationAPI.test.ts +123 -45
- package/Tests/Server/API/AutoRemediationApproveClusterRound.test.ts +1329 -0
- package/Tests/Server/API/AutoRemediationApproveKubectlRecheck.test.ts +25 -2
- package/Tests/Server/API/KubernetesClusterAiAccessAPI.test.ts +2 -0
- package/Tests/Server/API/KubernetesClusterAiAccessAPIAgent.test.ts +903 -0
- package/Tests/Server/API/MicrosoftTeamsChatsRefreshRoute.test.ts +667 -0
- package/Tests/Server/API/MicrosoftTeamsManifest.test.ts +294 -6
- package/Tests/Server/API/ProxmoxResourceAPIRemoveNode.test.ts +1932 -0
- package/Tests/Server/Infrastructure/GlobalCache.test.ts +195 -0
- package/Tests/Server/Infrastructure/Postgres/AddKubernetesAiAgentAndAiDefaultsMigration.test.ts +623 -0
- package/Tests/Server/Infrastructure/Postgres/AddKubernetesClusterAiAccessMigration.test.ts +87 -10
- package/Tests/Server/Infrastructure/Postgres/AddTeamComplianceRuleScopeMigration.test.ts +622 -0
- package/Tests/Server/Middleware/TelemetryIngestBrowserKey.test.ts +61 -4
- package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerPinnedKey.test.ts +98 -2
- package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerRateLimit.test.ts +105 -2
- package/Tests/Server/Services/AIServiceBalanceBlocker.test.ts +282 -0
- package/Tests/Server/Services/AlertMonitorClearWritesNull.test.ts +409 -0
- package/Tests/Server/Services/AlertMonitorEditFeed.test.ts +474 -0
- package/Tests/Server/Services/AlertMonitorEditGuard.test.ts +610 -0
- package/Tests/Server/Services/AutoRemediationClusterRuleEngine.test.ts +2 -0
- package/Tests/Server/Services/AutoRemediationRuleCommandRunners.test.ts +2 -1
- package/Tests/Server/Services/IncidentAffectedMonitorsEdit.test.ts +1360 -0
- package/Tests/Server/Services/IncidentAlertSloLinkSurvivesEdit.test.ts +3 -1
- package/Tests/Server/Services/IncidentSeverityDeletePausesComplianceRules.test.ts +488 -0
- package/Tests/Server/Services/KubernetesAiAgentJobService.test.ts +329 -0
- package/Tests/Server/Services/KubernetesAiAgentServiceHelpers.test.ts +618 -0
- package/Tests/Server/Services/KubernetesAiAgentServiceLifecycle.test.ts +1444 -0
- package/Tests/Server/Services/KubernetesAiAgentServiceRegister.test.ts +1666 -0
- package/Tests/Server/Services/KubernetesClusterAiAccessDeletedRunnerRemedy.test.ts +140 -111
- package/Tests/Server/Services/KubernetesClusterAiAccessGapNextSteps.test.ts +267 -105
- package/Tests/Server/Services/KubernetesClusterAiAccessLegacySuperseded.test.ts +440 -0
- package/Tests/Server/Services/KubernetesClusterAiAccessService.test.ts +567 -411
- package/Tests/Server/Services/KubernetesClusterAiAccessTarget.test.ts +1168 -0
- package/Tests/Server/Services/KubernetesClusterAiSettingsPermission.test.ts +410 -12
- package/Tests/Server/Services/KubernetesClusterServiceAiAccessFeed.test.ts +55 -0
- package/Tests/Server/Services/ProjectServiceNewProjectAiDefaults.test.ts +288 -0
- package/Tests/Server/Services/ProxmoxResourcePostgres.test.ts +5633 -0
- package/Tests/Server/Services/ProxmoxResourceService.test.ts +6458 -5
- package/Tests/Server/Services/RunnerJobEnqueueKubectl.test.ts +48 -15
- package/Tests/Server/Services/RunnerJobEnqueueKubectlAiAgent.test.ts +620 -0
- package/Tests/Server/Services/RunnerJobKubectlWriteScope.test.ts +170 -3
- package/Tests/Server/Services/RunnerJobTimeoutReason.test.ts +72 -0
- package/Tests/Server/Services/RunnerServiceAgentName.test.ts +6 -4
- package/Tests/Server/Services/ScheduledMaintenanceAttachmentEdit.test.ts +2113 -0
- package/Tests/Server/Services/ScheduledMaintenanceMonitorRelease.test.ts +972 -0
- package/Tests/Server/Services/TeamComplianceSettingPostgres.test.ts +2237 -0
- package/Tests/Server/Services/TeamComplianceSettingService.test.ts +3988 -138
- package/Tests/Server/Utils/AI/ClusterAccessContext.test.ts +107 -1
- package/Tests/Server/Utils/AI/IncidentPostmortemRunner.test.ts +351 -0
- package/Tests/Server/Utils/AI/InvestigationClusterAccessWiring.test.ts +2 -0
- package/Tests/Server/Utils/AI/InvestigationEligibility.test.ts +310 -0
- package/Tests/Server/Utils/AI/KubectlInvestigationToolkit.test.ts +70 -0
- package/Tests/Server/Utils/AI/KubectlJobRunnerFinishedJob.test.ts +58 -0
- package/Tests/Server/Utils/AI/RemediationCommandToolsKubectl.test.ts +2 -0
- package/Tests/Server/Utils/AI/RemediationCommandToolsKubectlOutcome.test.ts +2 -0
- package/Tests/Server/Utils/AI/RemediationCommandToolsLiveCluster.test.ts +2 -0
- package/Tests/Server/Utils/AI/RemediationCommandToolsRunnerScope.test.ts +125 -1
- package/Tests/Server/Utils/AI/RemediationExecutionRunner.test.ts +252 -3
- package/Tests/Server/Utils/AI/RemediationExecutionRunnerClusterMode.test.ts +2 -0
- package/Tests/Server/Utils/AI/RemediationExecutionRunnerProjectGates.test.ts +240 -0
- package/Tests/Server/Utils/AI/RemediationKubectlCopyParity.test.ts +2 -0
- package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutor.test.ts +2 -0
- package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutorUnknownRun.test.ts +2 -0
- package/Tests/Server/Utils/AutoRemediation/CommandPlanVerification.test.ts +2 -0
- package/Tests/Server/Utils/Telemetry/HostAssetAttributesFromOtlp.test.ts +68 -0
- package/Tests/Server/Utils/Telemetry/InventoryMirrorPostgres.test.ts +370 -0
- package/Tests/Server/Utils/Telemetry/NetworkDeviceInventoryAttributes.test.ts +522 -0
- package/Tests/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.test.ts +155 -0
- package/Tests/Server/Utils/Telemetry/ProxmoxNativeNodeLiveness.test.ts +8631 -0
- package/Tests/Server/Utils/Telemetry/ProxmoxNativePush.test.ts +2852 -0
- package/Tests/Server/Utils/Telemetry/TelemetryEntity.test.ts +367 -1
- package/Tests/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.test.ts +45 -3
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsChats.test.ts +25 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsGroupChatNames.test.ts +3119 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsGroupChatNamesPostgres.test.ts +1721 -0
- package/Tests/Types/Kubernetes/KubernetesAgentChartAiAccess.test.ts +581 -113
- package/Tests/Types/Kubernetes/KubernetesAiAgentAccessContract.test.ts +510 -0
- package/Tests/Types/Team/ComplianceRule.test.ts +1029 -0
- package/Tests/Types/Team/TeamComplianceStatus.test.ts +176 -0
- package/Tests/UI/Components/ActionButton/RowActions.test.tsx +641 -0
- package/Tests/UI/Components/ActionButton/RowActionsAccessibility.test.tsx +414 -0
- package/Tests/UI/Components/ActionButton/SplitActionButtons.test.ts +565 -0
- package/Tests/UI/Components/Charts/BarChartDragToSelect.test.tsx +386 -0
- package/Tests/UI/Components/Charts/ChartDoubleClickResetWithoutDblclick.test.tsx +1025 -0
- package/Tests/UI/Components/Charts/ChartGroupPageZoomHint.test.tsx +196 -0
- package/Tests/UI/Components/Charts/ChartPlaceholdersTakeDoubleClick.test.tsx +1861 -0
- package/Tests/UI/Components/Charts/ChartPlotClicksWhileResetArmed.test.tsx +382 -0
- package/Tests/UI/Components/Charts/ChartRangeSelection.test.tsx +704 -0
- package/Tests/UI/Components/Charts/ChartRangeSelectionDoubleClickReset.test.tsx +1481 -0
- package/Tests/UI/Components/Charts/ChartRangeSelectionRealRecharts.test.tsx +918 -0
- package/Tests/UI/Components/Charts/ChartRowBucketStart.test.ts +350 -0
- package/Tests/UI/Components/Charts/DoubleClickReset.test.tsx +996 -0
- package/Tests/UI/Components/Charts/HistogramDoubleClickResetRealRecharts.test.tsx +965 -0
- package/Tests/UI/Components/Charts/HistogramDriftThenRefetch.test.tsx +277 -0
- package/Tests/UI/Components/Charts/HistogramRangeSelectionDataChange.test.tsx +1757 -0
- package/Tests/UI/Components/Charts/HistogramRangeSelectionRealRecharts.test.tsx +560 -0
- package/Tests/UI/Components/Charts/TimeRangeZoom/ChartPageTimeRangeZoom.test.tsx +513 -0
- package/Tests/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomContext.test.tsx +845 -0
- package/Tests/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHint.test.tsx +119 -0
- package/Tests/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHintTailwind.test.tsx +274 -0
- package/Tests/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomUtil.test.ts +433 -0
- package/Tests/UI/Components/Charts/TimeRangeZoom/UseTimeRangeZoom.test.tsx +863 -0
- package/Tests/UI/Components/Charts/TimeRangeZoom/ZoomDocsPromises.test.tsx +1147 -0
- package/Tests/UI/Components/DisabledButtonTooltip.test.tsx +14 -3
- package/Tests/UI/Components/EntityDropdownEscape.test.tsx +454 -0
- package/Tests/UI/Components/EntityDropdownFocusLeave.test.tsx +420 -0
- package/Tests/UI/Components/Forms/FormFieldDropdownDisabled.test.tsx +233 -0
- package/Tests/UI/Components/Input.test.tsx +80 -1
- package/Tests/UI/Components/LogsAnalyticsViewZoom.test.tsx +947 -0
- package/Tests/UI/Components/LogsHistogramDragTooltip.test.tsx +17 -5
- package/Tests/UI/Components/LogsViewerAnalyticsZoom.test.tsx +501 -0
- package/Tests/UI/Components/LogsViewerHistogramZoom.test.tsx +1 -1
- package/Tests/UI/Components/ModelTable/BaseModelTableBulkDelete.test.tsx +6 -4
- package/Tests/UI/Components/ModelTable/BaseModelTablePermissionGating.test.tsx +60 -8
- package/Tests/UI/Components/ModelTable/BaseModelTableRowActions.test.tsx +476 -0
- package/Tests/UI/Components/ModelTable/ModelTableWrapContent.test.tsx +7 -5
- package/Tests/UI/Components/MoreMenuPortal.test.tsx +623 -0
- package/Tests/UI/Components/StatusPage/ResourceGridActions.test.tsx +538 -0
- package/Tests/UI/Components/StatusPage/ResourceGridSelection.test.tsx +14 -4
- package/Tests/UI/Components/TableCellWrapping.test.tsx +3 -3
- package/Tests/UI/Components/TableRowActions.test.tsx +472 -0
- package/Tests/UI/Components/TelemetryHistogramDragTooltip.test.tsx +1 -1
- package/Tests/UI/Components/TelemetryViewer/TelemetryViewerHistogramClickZoom.test.tsx +1 -1
- package/Tests/UI/Components/TelemetryViewer/TelemetryViewerZoomScope.test.tsx +470 -0
- package/Tests/UI/Components/TelemetryViewer/UseViewerTimeRangeZoom.test.tsx +571 -0
- package/Tests/UI/Components/TelemetryViewer/ViewerDoubleClickResetUnderDataChange.test.tsx +928 -0
- package/Tests/UI/Components/TelemetryViewer/ViewerFollowsEnclosingZoom.test.tsx +1569 -0
- package/Tests/UI/Components/Toggle.test.tsx +66 -0
- package/Tests/UI/MicrosoftTeams/MicrosoftTeamsChatsCardRefreshNames.test.tsx +1023 -0
- package/Tests/UI/Rum/ChunkLoader.test.ts +201 -0
- package/Tests/UI/Rum/FidelityNotices.test.ts +54 -0
- package/Tests/UI/Rum/ReplayCorrelationPanel.test.tsx +72 -0
- package/Tests/UI/Rum/ReplayFrameCapture.test.ts +1009 -9
- package/Tests/UI/Rum/ReplayRecordedAssets.test.ts +1069 -0
- package/Tests/UI/Rum/ReplayStage.test.tsx +913 -2
- package/Tests/UI/Rum/SessionReplayTable.test.tsx +443 -8
- package/Tests/UI/Rum/SessionReplayUsersTable.test.tsx +439 -9
- package/Tests/UI/Rum/UserFlowTablesRowActions.test.tsx +501 -0
- package/Tests/Utils/AiRemediation/KubectlPolicyChartRbacParity.test.ts +47 -19
- package/Tests/Utils/AiRemediation/KubectlWriteScopeCallerParity.test.ts +2 -0
- package/Tests/Utils/AiRemediation/KubernetesAiAgentPolicyCopyParity.test.ts +396 -0
- package/Tests/Utils/Dashboard/DashboardTimeRangeZoom.test.ts +104 -1
- package/Types/AI/AIRunType.ts +9 -4
- package/Types/AI/InvestigationNotStartedReason.ts +6 -0
- package/Types/AutoRemediation/AiRemediationCommandPlan.ts +14 -16
- package/Types/AutoRemediation/AiRemediationCommandPolicyVerdict.ts +28 -0
- package/Types/Dashboard/DashboardComponents/DashboardTraceChartComponent.ts +4 -2
- package/Types/Kubernetes/KubernetesClusterAiAccess.ts +263 -32
- package/Types/Kubernetes/KubernetesClusterAiAccessPermissions.ts +20 -16
- package/Types/Kubernetes/KubernetesClusterAiInsights.ts +81 -0
- package/Types/Monitor/ProxmoxAlertTemplates.ts +4 -4
- package/Types/Team/ComplianceNotificationChannel.ts +22 -0
- package/Types/Team/ComplianceRule.ts +434 -0
- package/Types/Team/ComplianceRuleType.ts +21 -0
- package/Types/Team/TeamComplianceStatus.ts +81 -0
- package/Types/Telemetry/TelemetryIngestSurface.ts +28 -0
- package/UI/Components/ActionButton/ActionButtonSchema.ts +21 -0
- package/UI/Components/ActionButton/RowActions.tsx +238 -0
- package/UI/Components/ActionButton/SplitActionButtons.ts +173 -0
- package/UI/Components/Charts/Area/AreaChart.tsx +32 -2
- package/UI/Components/Charts/Bar/BarChart.tsx +40 -3
- package/UI/Components/Charts/ChartGroup/ChartGroup.tsx +37 -11
- package/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.tsx +80 -243
- package/UI/Components/Charts/ChartLibrary/BarChart/BarChart.tsx +122 -31
- package/UI/Components/Charts/ChartLibrary/LineChart/LineChart.tsx +95 -244
- package/UI/Components/Charts/ChartLibrary/Utils/DoubleClick.ts +214 -0
- package/UI/Components/Charts/ChartLibrary/Utils/UseChartBucketsChange.ts +32 -0
- package/UI/Components/Charts/ChartLibrary/Utils/UseChartRangeSelection.ts +599 -0
- package/UI/Components/Charts/Line/LineChart.tsx +32 -2
- package/UI/Components/Charts/TimeRangeZoom/ResetTimeRangeZoomButton.tsx +70 -0
- package/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomContext.tsx +226 -0
- package/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHint.tsx +73 -0
- package/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomUtil.ts +163 -0
- package/UI/Components/Charts/TimeRangeZoom/UseTimeRangeZoom.ts +215 -0
- package/UI/Components/Charts/Utils/DataPoint.ts +20 -8
- package/UI/Components/Charts/Utils/XAxis.ts +75 -0
- package/UI/Components/Charts/Utils/useHistogramRangeSelection.ts +493 -59
- package/UI/Components/EntityDropdown/EntityDropdown.tsx +107 -11
- package/UI/Components/Forms/Fields/FormField.tsx +10 -0
- package/UI/Components/Input/Input.tsx +90 -57
- package/UI/Components/List/ListRow.tsx +8 -74
- package/UI/Components/LogsViewer/LogsViewer.tsx +40 -11
- package/UI/Components/LogsViewer/components/LogTimeRangePicker.tsx +22 -6
- package/UI/Components/LogsViewer/components/LogsAnalyticsView.tsx +209 -6
- package/UI/Components/LogsViewer/components/LogsHistogram.tsx +127 -84
- package/UI/Components/LogsViewer/components/LogsViewerToolbar.tsx +3 -0
- package/UI/Components/ModelTable/BaseModelTable.tsx +12 -1
- package/UI/Components/MoreMenu/MoreMenu.tsx +365 -30
- package/UI/Components/MoreMenu/MoreMenuItem.tsx +70 -17
- package/UI/Components/OrderedStatesList/Item.tsx +7 -72
- package/UI/Components/StatusPage/ResourceGrid.tsx +126 -77
- package/UI/Components/Table/TableBody.tsx +8 -2
- package/UI/Components/Table/TableRow.tsx +20 -140
- package/UI/Components/TelemetryViewer/TelemetryViewer.tsx +41 -10
- package/UI/Components/TelemetryViewer/components/TelemetryHistogram.tsx +47 -9
- package/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.tsx +25 -6
- package/UI/Components/TelemetryViewer/types.ts +2 -0
- package/UI/Components/TelemetryViewer/useViewerTimeRangeZoom.ts +448 -0
- package/UI/Components/Toggle/Toggle.tsx +26 -0
- package/UI/Components/Tooltip/Tooltip.tsx +8 -1
- package/UI/Styles/Theme.css +14 -2
- package/Utils/AiRemediation/CommandPolicy.ts +1 -1
- package/Utils/AiRemediation/KubectlPolicy.ts +1 -1
- package/Utils/Dashboard/DashboardTimeRangeZoom.ts +46 -2
- package/build/dist/Models/DatabaseModels/Index.js +2 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/KubernetesAiAgent.js +385 -0
- package/build/dist/Models/DatabaseModels/KubernetesAiAgent.js.map +1 -0
- package/build/dist/Models/DatabaseModels/KubernetesCluster.js +3 -3
- package/build/dist/Models/DatabaseModels/KubernetesCluster.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Project.js +56 -5
- package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ProxmoxResource.js +51 -1
- package/build/dist/Models/DatabaseModels/ProxmoxResource.js.map +1 -1
- package/build/dist/Models/DatabaseModels/RunnerJob.js +74 -0
- package/build/dist/Models/DatabaseModels/RunnerJob.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TeamComplianceSetting.js +134 -3
- package/build/dist/Models/DatabaseModels/TeamComplianceSetting.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js.map +1 -1
- package/build/dist/Server/API/AIChatAPI.js +6 -1
- package/build/dist/Server/API/AIChatAPI.js.map +1 -1
- package/build/dist/Server/API/AIInvestigationAPI.js +17 -10
- package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
- package/build/dist/Server/API/AutoRemediationAPI.js +144 -24
- package/build/dist/Server/API/AutoRemediationAPI.js.map +1 -1
- package/build/dist/Server/API/KubernetesClusterAiAccessAPI.js +436 -22
- package/build/dist/Server/API/KubernetesClusterAiAccessAPI.js.map +1 -1
- package/build/dist/Server/API/MicrosoftTeamsAPI.js +69 -13
- package/build/dist/Server/API/MicrosoftTeamsAPI.js.map +1 -1
- package/build/dist/Server/API/ProxmoxResourceAPI.js +187 -14
- package/build/dist/Server/API/ProxmoxResourceAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/GlobalCache.js +27 -0
- package/build/dist/Server/Infrastructure/GlobalCache.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796000000000-AddTeamComplianceRuleScope.js +50 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796000000000-AddTeamComplianceRuleScope.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796100000000-AddKubernetesAiAgentAndAiDefaults.js +84 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796100000000-AddKubernetesAiAgentAndAiDefaults.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796200000000-AddProxmoxResourceNativePushColumns.js +31 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796200000000-AddProxmoxResourceNativePushColumns.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +6 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Middleware/TelemetryIngest.js +34 -19
- package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
- package/build/dist/Server/Services/AIService.js +59 -1
- package/build/dist/Server/Services/AIService.js.map +1 -1
- package/build/dist/Server/Services/AlertService.js +248 -13
- package/build/dist/Server/Services/AlertService.js.map +1 -1
- package/build/dist/Server/Services/AlertSeverityService.js +51 -15
- package/build/dist/Server/Services/AlertSeverityService.js.map +1 -1
- package/build/dist/Server/Services/AutoRemediationRuleService.js +1 -1
- package/build/dist/Server/Services/AutoRemediationRuleService.js.map +1 -1
- package/build/dist/Server/Services/IncidentService.js +199 -72
- package/build/dist/Server/Services/IncidentService.js.map +1 -1
- package/build/dist/Server/Services/IncidentSeverityService.js +51 -15
- package/build/dist/Server/Services/IncidentSeverityService.js.map +1 -1
- package/build/dist/Server/Services/KubernetesAiAgentJobService.js +158 -0
- package/build/dist/Server/Services/KubernetesAiAgentJobService.js.map +1 -0
- package/build/dist/Server/Services/KubernetesAiAgentService.js +1145 -0
- package/build/dist/Server/Services/KubernetesAiAgentService.js.map +1 -0
- package/build/dist/Server/Services/KubernetesClusterAiAccessService.js +842 -371
- package/build/dist/Server/Services/KubernetesClusterAiAccessService.js.map +1 -1
- package/build/dist/Server/Services/KubernetesClusterService.js +86 -17
- package/build/dist/Server/Services/KubernetesClusterService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +22 -0
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/ProxmoxResourceService.js +258 -3
- package/build/dist/Server/Services/ProxmoxResourceService.js.map +1 -1
- package/build/dist/Server/Services/RunnerJobService.js +178 -92
- package/build/dist/Server/Services/RunnerJobService.js.map +1 -1
- package/build/dist/Server/Services/RunnerService.js +1 -1
- package/build/dist/Server/Services/RunnerService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceService.js +535 -3
- package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js +316 -46
- package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/TeamComplianceSettingService.js +833 -7
- package/build/dist/Server/Services/TeamComplianceSettingService.js.map +1 -1
- package/build/dist/Server/Utils/AI/ClusterAccess/ClusterAccessContext.js +52 -9
- package/build/dist/Server/Utils/AI/ClusterAccess/ClusterAccessContext.js.map +1 -1
- package/build/dist/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.js +13 -9
- package/build/dist/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.js.map +1 -1
- package/build/dist/Server/Utils/AI/ClusterAccess/KubectlJobRunner.js +7 -3
- package/build/dist/Server/Utils/AI/ClusterAccess/KubectlJobRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js +29 -15
- package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js.map +1 -1
- package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js +56 -20
- package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +39 -5
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/IncidentPostmortemRunner.js +30 -3
- package/build/dist/Server/Utils/AI/SRE/IncidentPostmortemRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/InvestigationEligibility.js +13 -2
- package/build/dist/Server/Utils/AI/SRE/InvestigationEligibility.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/InvestigationGrader.js +1 -1
- package/build/dist/Server/Utils/AutoRemediation/CommandPlanExecutor.js +4 -2
- package/build/dist/Server/Utils/AutoRemediation/CommandPlanExecutor.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js +111 -6
- package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.js +40 -4
- package/build/dist/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/ProxmoxNativeNodeLiveness.js +296 -0
- package/build/dist/Server/Utils/Telemetry/ProxmoxNativeNodeLiveness.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/ProxmoxNativePush.js +699 -0
- package/build/dist/Server/Utils/Telemetry/ProxmoxNativePush.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js +77 -19
- package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +505 -42
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
- package/build/dist/Types/AI/AIRunType.js +9 -4
- package/build/dist/Types/AI/AIRunType.js.map +1 -1
- package/build/dist/Types/AutoRemediation/AiRemediationCommandPlan.js +10 -16
- package/build/dist/Types/AutoRemediation/AiRemediationCommandPlan.js.map +1 -1
- package/build/dist/Types/AutoRemediation/AiRemediationCommandPolicyVerdict.js +28 -0
- package/build/dist/Types/AutoRemediation/AiRemediationCommandPolicyVerdict.js.map +1 -0
- package/build/dist/Types/Kubernetes/KubernetesClusterAiAccess.js +72 -16
- package/build/dist/Types/Kubernetes/KubernetesClusterAiAccess.js.map +1 -1
- package/build/dist/Types/Kubernetes/KubernetesClusterAiAccessPermissions.js +20 -16
- package/build/dist/Types/Kubernetes/KubernetesClusterAiAccessPermissions.js.map +1 -1
- package/build/dist/Types/Kubernetes/KubernetesClusterAiInsights.js +17 -0
- package/build/dist/Types/Kubernetes/KubernetesClusterAiInsights.js.map +1 -0
- package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js +4 -4
- package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js.map +1 -1
- package/build/dist/Types/Team/ComplianceNotificationChannel.js +23 -0
- package/build/dist/Types/Team/ComplianceNotificationChannel.js.map +1 -0
- package/build/dist/Types/Team/ComplianceRule.js +304 -0
- package/build/dist/Types/Team/ComplianceRule.js.map +1 -0
- package/build/dist/Types/Team/ComplianceRuleType.js +21 -0
- package/build/dist/Types/Team/ComplianceRuleType.js.map +1 -1
- package/build/dist/Types/Team/TeamComplianceStatus.js +2 -0
- package/build/dist/Types/Team/TeamComplianceStatus.js.map +1 -0
- package/build/dist/Types/Telemetry/TelemetryIngestSurface.js +25 -0
- package/build/dist/Types/Telemetry/TelemetryIngestSurface.js.map +1 -1
- package/build/dist/UI/Components/ActionButton/ActionButtonSchema.js +20 -1
- package/build/dist/UI/Components/ActionButton/ActionButtonSchema.js.map +1 -1
- package/build/dist/UI/Components/ActionButton/RowActions.js +113 -0
- package/build/dist/UI/Components/ActionButton/RowActions.js.map +1 -0
- package/build/dist/UI/Components/ActionButton/SplitActionButtons.js +71 -0
- package/build/dist/UI/Components/ActionButton/SplitActionButtons.js.map +1 -0
- package/build/dist/UI/Components/Charts/Area/AreaChart.js +16 -1
- package/build/dist/UI/Components/Charts/Area/AreaChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/Bar/BarChart.js +16 -1
- package/build/dist/UI/Components/Charts/Bar/BarChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js +27 -5
- package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js +61 -194
- package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js +84 -26
- package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js +75 -196
- package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/Utils/DoubleClick.js +133 -0
- package/build/dist/UI/Components/Charts/ChartLibrary/Utils/DoubleClick.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/Utils/UseChartBucketsChange.js +26 -0
- package/build/dist/UI/Components/Charts/ChartLibrary/Utils/UseChartBucketsChange.js.map +1 -0
- package/build/dist/UI/Components/Charts/ChartLibrary/Utils/UseChartRangeSelection.js +371 -0
- package/build/dist/UI/Components/Charts/ChartLibrary/Utils/UseChartRangeSelection.js.map +1 -0
- package/build/dist/UI/Components/Charts/Line/LineChart.js +16 -1
- package/build/dist/UI/Components/Charts/Line/LineChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/TimeRangeZoom/ResetTimeRangeZoomButton.js +35 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/ResetTimeRangeZoomButton.js.map +1 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomContext.js +107 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomContext.js.map +1 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHint.js +41 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHint.js.map +1 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomUtil.js +117 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomUtil.js.map +1 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/UseTimeRangeZoom.js +121 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/UseTimeRangeZoom.js.map +1 -0
- package/build/dist/UI/Components/Charts/Utils/DataPoint.js +15 -7
- package/build/dist/UI/Components/Charts/Utils/DataPoint.js.map +1 -1
- package/build/dist/UI/Components/Charts/Utils/XAxis.js +70 -0
- package/build/dist/UI/Components/Charts/Utils/XAxis.js.map +1 -1
- package/build/dist/UI/Components/Charts/Utils/useHistogramRangeSelection.js +305 -38
- package/build/dist/UI/Components/Charts/Utils/useHistogramRangeSelection.js.map +1 -1
- package/build/dist/UI/Components/EntityDropdown/EntityDropdown.js +89 -14
- package/build/dist/UI/Components/EntityDropdown/EntityDropdown.js.map +1 -1
- package/build/dist/UI/Components/Forms/Fields/FormField.js +11 -2
- package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
- package/build/dist/UI/Components/Input/Input.js +69 -54
- package/build/dist/UI/Components/Input/Input.js.map +1 -1
- package/build/dist/UI/Components/List/ListRow.js +4 -39
- package/build/dist/UI/Components/List/ListRow.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/LogsViewer.js +31 -8
- package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js +10 -1
- package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js +139 -21
- package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsHistogram.js +30 -8
- package/build/dist/UI/Components/LogsViewer/components/LogsHistogram.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js +10 -0
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/build/dist/UI/Components/MoreMenu/MoreMenu.js +253 -14
- package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
- package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js +43 -13
- package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js.map +1 -1
- package/build/dist/UI/Components/OrderedStatesList/Item.js +2 -38
- package/build/dist/UI/Components/OrderedStatesList/Item.js.map +1 -1
- package/build/dist/UI/Components/StatusPage/ResourceGrid.js +53 -15
- package/build/dist/UI/Components/StatusPage/ResourceGrid.js.map +1 -1
- package/build/dist/UI/Components/Table/TableBody.js +6 -2
- package/build/dist/UI/Components/Table/TableBody.js.map +1 -1
- package/build/dist/UI/Components/Table/TableRow.js +12 -75
- package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js +32 -7
- package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js +27 -9
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js +11 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/useViewerTimeRangeZoom.js +272 -0
- package/build/dist/UI/Components/TelemetryViewer/useViewerTimeRangeZoom.js.map +1 -0
- package/build/dist/UI/Components/Toggle/Toggle.js +14 -1
- package/build/dist/UI/Components/Toggle/Toggle.js.map +1 -1
- package/build/dist/UI/Components/Tooltip/Tooltip.js +1 -1
- package/build/dist/UI/Components/Tooltip/Tooltip.js.map +1 -1
- package/build/dist/Utils/AiRemediation/CommandPolicy.js +1 -1
- package/build/dist/Utils/AiRemediation/CommandPolicy.js.map +1 -1
- package/build/dist/Utils/AiRemediation/KubectlPolicy.js +1 -1
- package/build/dist/Utils/AiRemediation/KubectlPolicy.js.map +1 -1
- package/build/dist/Utils/Dashboard/DashboardTimeRangeZoom.js +27 -1
- package/build/dist/Utils/Dashboard/DashboardTimeRangeZoom.js.map +1 -1
- package/package.json +1 -1
|
@@ -2,6 +2,7 @@ import {
|
|
|
2
2
|
KubernetesAiAccessGap,
|
|
3
3
|
KubernetesAiRemediationMode,
|
|
4
4
|
KubernetesClusterAiAccessStatus,
|
|
5
|
+
getKubernetesAiAccessTargetKind,
|
|
5
6
|
} from "../../../../Types/Kubernetes/KubernetesClusterAiAccess";
|
|
6
7
|
import { KUBECTL_ALWAYS_ASKS_SUMMARY } from "../../../../Types/AutoRemediation/AiRemediationCommandPlan";
|
|
7
8
|
|
|
@@ -20,6 +21,46 @@ function capitalizeFirst(text: string): string {
|
|
|
20
21
|
return text.charAt(0).toUpperCase() + text.slice(1);
|
|
21
22
|
}
|
|
22
23
|
|
|
24
|
+
/*
|
|
25
|
+
* Who runs kubectl for a cluster, by name, for copy the model and humans
|
|
26
|
+
* read: "the Kubernetes AI agent", or `Runner "<name>"`. Told apart by
|
|
27
|
+
* runner.kind only — accessMethod is "in_cluster" for both the agent and
|
|
28
|
+
* the chart's previous in-cluster Runner.
|
|
29
|
+
*/
|
|
30
|
+
export function describeClusterAccessTarget(
|
|
31
|
+
status: Pick<KubernetesClusterAiAccessStatus, "runner">,
|
|
32
|
+
): string {
|
|
33
|
+
if (getKubernetesAiAccessTargetKind(status.runner) === "ai_agent") {
|
|
34
|
+
return "the Kubernetes AI agent";
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return `Runner "${status.runner?.name || "Runner"}"`;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/*
|
|
41
|
+
* The same with "its" ("its Kubernetes AI agent", "its Runner"), for copy
|
|
42
|
+
* that has already named the cluster.
|
|
43
|
+
*/
|
|
44
|
+
export function describeClusterAccessTargetOfCluster(
|
|
45
|
+
status: Pick<KubernetesClusterAiAccessStatus, "runner">,
|
|
46
|
+
): string {
|
|
47
|
+
return getKubernetesAiAccessTargetKind(status.runner) === "ai_agent"
|
|
48
|
+
? "its Kubernetes AI agent"
|
|
49
|
+
: "its Runner";
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/*
|
|
53
|
+
* The same as a role, for copy about the cluster in general: "the
|
|
54
|
+
* cluster's Kubernetes AI agent" or "the cluster's Runner".
|
|
55
|
+
*/
|
|
56
|
+
export function describeClusterAccessTargetRole(
|
|
57
|
+
status: Pick<KubernetesClusterAiAccessStatus, "runner">,
|
|
58
|
+
): string {
|
|
59
|
+
return getKubernetesAiAccessTargetKind(status.runner) === "ai_agent"
|
|
60
|
+
? "the cluster's Kubernetes AI agent"
|
|
61
|
+
: "the cluster's Runner";
|
|
62
|
+
}
|
|
63
|
+
|
|
23
64
|
/*
|
|
24
65
|
* The prompt-side view of cluster access.
|
|
25
66
|
*
|
|
@@ -55,7 +96,7 @@ export default class ClusterAccessContext {
|
|
|
55
96
|
})
|
|
56
97
|
.join(
|
|
57
98
|
", ",
|
|
58
|
-
)}. Use run_kubectl for READ-ONLY inspection — kubectl get/describe/events/logs/top/rollout status — the way an on-call engineer would open a terminal: describe the failing pod, read its recent events, check node capacity and pending-pod reasons, tail the crashing container's logs. Prefer direct cluster inspection over guessing from metrics when the two disagree. Every kubectl command that ran is cited like any other tool result; a command that could not run comes back as an error, is not evidence, and must never be described as inspected. The Runner that runs kubectl lives in the cluster and can itself be down: if run_kubectl says a cluster's Runner did not pick up a command, that cluster is unreachable for the rest of this investigation — do not call run_kubectl on it again, continue with OneUptime telemetry, and say so in your report. Reading Secrets is refused and credential-looking values (Secret data, passwords, tokens, keys) are redacted from every output before you see it — never ask for them and never treat a redaction marker as a finding.`,
|
|
99
|
+
)}. Use run_kubectl for READ-ONLY inspection — kubectl get/describe/events/logs/top/rollout status — the way an on-call engineer would open a terminal: describe the failing pod, read its recent events, check node capacity and pending-pod reasons, tail the crashing container's logs. Prefer direct cluster inspection over guessing from metrics when the two disagree. Every kubectl command that ran is cited like any other tool result; a command that could not run comes back as an error, is not evidence, and must never be described as inspected. The agent (or Runner) that runs kubectl lives in the cluster and can itself be down: if run_kubectl says a cluster's agent or Runner did not pick up a command, that cluster is unreachable for the rest of this investigation — do not call run_kubectl on it again, continue with OneUptime telemetry, and say so in your report. Reading Secrets is refused and credential-looking values (Secret data, passwords, tokens, keys) are redacted from every output before you see it — never ask for them and never treat a redaction marker as a finding.`,
|
|
59
100
|
);
|
|
60
101
|
}
|
|
61
102
|
|
|
@@ -78,7 +119,7 @@ export default class ClusterAccessContext {
|
|
|
78
119
|
}
|
|
79
120
|
|
|
80
121
|
lines.push(
|
|
81
|
-
`Add a section **${ClusterAccessContext.REPORT_SECTION_HEADING}** before Suggested next steps: one or two sentences on what you inspected directly on the cluster (or that you could not — access not set up, or the cluster's Runner not responding — and that the human should check the cluster's AI page).`,
|
|
122
|
+
`Add a section **${ClusterAccessContext.REPORT_SECTION_HEADING}** before Suggested next steps: one or two sentences on what you inspected directly on the cluster (or that you could not — access not set up, or the cluster's AI agent or Runner not responding — and that the human should check the cluster's AI agent page (AI → Agent)).`,
|
|
82
123
|
);
|
|
83
124
|
|
|
84
125
|
return lines.join("\n");
|
|
@@ -97,13 +138,9 @@ export default class ClusterAccessContext {
|
|
|
97
138
|
for (const status of statuses) {
|
|
98
139
|
if (status.isInvestigationReady) {
|
|
99
140
|
lines.push(
|
|
100
|
-
`- Cluster "${status.clusterName}" (clusterId: ${status.clusterId}): kubectl READ access available via run_kubectl${
|
|
101
|
-
status
|
|
102
|
-
|
|
103
|
-
: status.credentialName
|
|
104
|
-
? ` (Runner "${status.runner?.name}" with credential "${status.credentialName}")`
|
|
105
|
-
: ""
|
|
106
|
-
}. Remediation: ${ClusterAccessContext.describeRemediationMode(status)}.`,
|
|
141
|
+
`- Cluster "${status.clusterName}" (clusterId: ${status.clusterId}): kubectl READ access available via run_kubectl${ClusterAccessContext.describeAccessPath(
|
|
142
|
+
status,
|
|
143
|
+
)}. Remediation: ${ClusterAccessContext.describeRemediationMode(status)}.`,
|
|
107
144
|
);
|
|
108
145
|
continue;
|
|
109
146
|
}
|
|
@@ -126,6 +163,27 @@ export default class ClusterAccessContext {
|
|
|
126
163
|
return lines.join("\n");
|
|
127
164
|
}
|
|
128
165
|
|
|
166
|
+
/*
|
|
167
|
+
* How kubectl reaches a ready cluster, as a parenthetical: the Kubernetes
|
|
168
|
+
* AI agent, the chart's previous in-cluster Runner, or a Runner with a
|
|
169
|
+
* credential.
|
|
170
|
+
*/
|
|
171
|
+
private static describeAccessPath(
|
|
172
|
+
status: KubernetesClusterAiAccessStatus,
|
|
173
|
+
): string {
|
|
174
|
+
if (getKubernetesAiAccessTargetKind(status.runner) === "ai_agent") {
|
|
175
|
+
return " (via the in-cluster Kubernetes AI agent)";
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
if (status.accessMethod === "in_cluster") {
|
|
179
|
+
return " (in-cluster Runner)";
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return status.credentialName
|
|
183
|
+
? ` (Runner "${status.runner?.name}" with credential "${status.credentialName}")`
|
|
184
|
+
: "";
|
|
185
|
+
}
|
|
186
|
+
|
|
129
187
|
/*
|
|
130
188
|
* The sentence the investigation panel shows humans when AI investigated
|
|
131
189
|
* with OneUptime data only. Deterministic so it reads the same on every
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
KubernetesClusterAiAccessStatus,
|
|
8
8
|
MAX_KUBECTL_COMMANDS_PER_INVESTIGATION,
|
|
9
9
|
MAX_KUBECTL_TIMEOUT_MS,
|
|
10
|
+
getKubernetesAiAccessTargetKind,
|
|
10
11
|
} from "../../../../Types/Kubernetes/KubernetesClusterAiAccess";
|
|
11
12
|
import KubectlPolicy, {
|
|
12
13
|
KubectlPolicyResult,
|
|
@@ -30,6 +31,11 @@ import {
|
|
|
30
31
|
LIST_CLUSTER_ACCESS_TOOL_NAME,
|
|
31
32
|
RUN_KUBECTL_TOOL_NAME,
|
|
32
33
|
} from "../../../../Types/Kubernetes/KubernetesClusterAiAccessToolNames";
|
|
34
|
+
import {
|
|
35
|
+
describeClusterAccessTarget,
|
|
36
|
+
describeClusterAccessTargetOfCluster,
|
|
37
|
+
describeClusterAccessTargetRole,
|
|
38
|
+
} from "./ClusterAccessContext";
|
|
33
39
|
|
|
34
40
|
/*
|
|
35
41
|
* The run-scoped, READ-ONLY kubectl toolkit for an investigation.
|
|
@@ -227,8 +233,13 @@ export default class KubectlInvestigationToolkit {
|
|
|
227
233
|
: ""
|
|
228
234
|
} — ${
|
|
229
235
|
this.isClusterUnreachable(cluster.clusterId)
|
|
230
|
-
? `UNREACHABLE for the rest of this investigation: its
|
|
231
|
-
|
|
236
|
+
? `UNREACHABLE for the rest of this investigation: its ${describeClusterAccessTarget(
|
|
237
|
+
cluster,
|
|
238
|
+
).replace(
|
|
239
|
+
/^the /,
|
|
240
|
+
"",
|
|
241
|
+
)} did not pick up an earlier command. Do not call run_kubectl on it again.`
|
|
242
|
+
: `read-only kubectl via ${describeClusterAccessTarget(cluster)}`
|
|
232
243
|
}`;
|
|
233
244
|
})
|
|
234
245
|
.join("\n");
|
|
@@ -345,15 +356,20 @@ export default class KubectlInvestigationToolkit {
|
|
|
345
356
|
);
|
|
346
357
|
|
|
347
358
|
if (tripped !== undefined) {
|
|
359
|
+
const target: string = describeClusterAccessTarget(cluster);
|
|
360
|
+
const role: string = describeClusterAccessTargetRole(cluster);
|
|
361
|
+
|
|
348
362
|
return this.failure(
|
|
349
|
-
|
|
363
|
+
`${target.charAt(0).toUpperCase()}${target.slice(1)}, which serves cluster "${cluster.clusterName}", did not pick up an earlier command${
|
|
350
364
|
tripped.clusterName !== cluster.clusterName
|
|
351
365
|
? ` (for cluster "${tripped.clusterName}")`
|
|
352
366
|
: ""
|
|
353
367
|
} within ${KubectlInvestigationToolkit.describeSeconds(
|
|
354
368
|
tripped.claimWindowMs,
|
|
355
|
-
)}, so the cluster is treated as unreachable for the rest of this investigation. Nothing was run. Do not call run_kubectl on this cluster again: continue with OneUptime telemetry and say in **Cluster access** that
|
|
356
|
-
`kubectl was not run on cluster "${cluster.clusterName}":
|
|
369
|
+
)}, so the cluster is treated as unreachable for the rest of this investigation. Nothing was run. Do not call run_kubectl on this cluster again: continue with OneUptime telemetry and say in **Cluster access** that ${role} did not respond.`,
|
|
370
|
+
`kubectl was not run on cluster "${cluster.clusterName}": ${describeClusterAccessTargetOfCluster(
|
|
371
|
+
cluster,
|
|
372
|
+
)} did not pick up an earlier command, so the cluster was unreachable for the rest of this investigation.`,
|
|
357
373
|
);
|
|
358
374
|
}
|
|
359
375
|
|
|
@@ -427,8 +443,12 @@ export default class KubectlInvestigationToolkit {
|
|
|
427
443
|
const alsoUnreachable: Array<KubernetesClusterAiAccessStatus> =
|
|
428
444
|
this.getOtherClustersOnRunner(cluster);
|
|
429
445
|
|
|
446
|
+
const role: string = describeClusterAccessTargetRole(cluster);
|
|
447
|
+
|
|
430
448
|
return this.failure(
|
|
431
|
-
`kubectl was NOT run on cluster "${cluster.clusterName}":
|
|
449
|
+
`kubectl was NOT run on cluster "${cluster.clusterName}": ${describeClusterAccessTargetOfCluster(
|
|
450
|
+
cluster,
|
|
451
|
+
)} did not pick up "${outcome.displayCommand}" within ${KubectlInvestigationToolkit.describeSeconds(
|
|
432
452
|
budget.plan.claimTimeoutInMs,
|
|
433
453
|
)} (it may be offline, restarting or busy). The cluster is treated as unreachable for the rest of this investigation — do not call run_kubectl on it again.${
|
|
434
454
|
alsoUnreachable.length > 0
|
|
@@ -440,8 +460,10 @@ export default class KubectlInvestigationToolkit {
|
|
|
440
460
|
", ",
|
|
441
461
|
)}, so ${alsoUnreachable.length === 1 ? "that cluster is" : "those clusters are"} unreachable too.`
|
|
442
462
|
: ""
|
|
443
|
-
} Continue with OneUptime telemetry and say in **Cluster access** that
|
|
444
|
-
`kubectl was not run on cluster "${cluster.clusterName}":
|
|
463
|
+
} Continue with OneUptime telemetry and say in **Cluster access** that ${role} did not respond.`,
|
|
464
|
+
`kubectl was not run on cluster "${cluster.clusterName}": ${describeClusterAccessTargetOfCluster(
|
|
465
|
+
cluster,
|
|
466
|
+
)} did not pick up the command in time.`,
|
|
445
467
|
);
|
|
446
468
|
}
|
|
447
469
|
|
|
@@ -460,9 +482,16 @@ export default class KubectlInvestigationToolkit {
|
|
|
460
482
|
? redactedReason
|
|
461
483
|
: `${redactedReason}.`;
|
|
462
484
|
|
|
485
|
+
const isAgent: boolean =
|
|
486
|
+
getKubernetesAiAccessTargetKind(cluster.runner) === "ai_agent";
|
|
487
|
+
|
|
463
488
|
return this.failure(
|
|
464
|
-
`No kubectl result came back from cluster "${cluster.clusterName}" for "${outcome.displayCommand}": ${reason} Nothing from this command is evidence. Continue with OneUptime telemetry and mention in **Cluster access** that
|
|
465
|
-
|
|
489
|
+
`No kubectl result came back from cluster "${cluster.clusterName}" for "${outcome.displayCommand}": ${reason} Nothing from this command is evidence. Continue with OneUptime telemetry and mention in **Cluster access** that ${describeClusterAccessTargetRole(
|
|
490
|
+
cluster,
|
|
491
|
+
)} stopped responding.`,
|
|
492
|
+
`${KUBECTL_RESULT_UNKNOWN_EVENT_PREFIX} the ${
|
|
493
|
+
isAgent ? "Kubernetes AI agent" : "Runner"
|
|
494
|
+
} of cluster "${cluster.clusterName}" took the command, but no result came back, so whether it ran is unknown.`,
|
|
466
495
|
);
|
|
467
496
|
}
|
|
468
497
|
|
|
@@ -392,6 +392,9 @@ export default class KubectlJobRunner {
|
|
|
392
392
|
wasClaimed: claimState.wasClaimed,
|
|
393
393
|
claimTimeoutInMs: data.claimTimeoutInMs,
|
|
394
394
|
executionTimeoutInMs: data.executionTimeoutInMs,
|
|
395
|
+
isForKubernetesAiAgent: Boolean(
|
|
396
|
+
job.targetKubernetesAiAgentId,
|
|
397
|
+
),
|
|
395
398
|
})
|
|
396
399
|
: terminalJob.errorMessage ||
|
|
397
400
|
`Command ended with status ${terminalJob.status}.`,
|
|
@@ -612,18 +615,26 @@ export default class KubectlJobRunner {
|
|
|
612
615
|
wasClaimed: boolean | undefined;
|
|
613
616
|
claimTimeoutInMs: number;
|
|
614
617
|
executionTimeoutInMs: number;
|
|
618
|
+
// The job was for the cluster's Kubernetes AI agent, not a Runner.
|
|
619
|
+
isForKubernetesAiAgent?: boolean | undefined;
|
|
615
620
|
}): string {
|
|
621
|
+
const executor: string = data.isForKubernetesAiAgent
|
|
622
|
+
? "Kubernetes AI agent"
|
|
623
|
+
: "Runner";
|
|
624
|
+
|
|
616
625
|
if (data.wasClaimed === false) {
|
|
617
|
-
return `The cluster's
|
|
626
|
+
return `The cluster's ${executor} did not pick up this kubectl command within ${KubectlJobRunner.describeSeconds(
|
|
618
627
|
data.claimTimeoutInMs,
|
|
619
628
|
)} — it may be offline, restarting or busy with other work. Nothing was run on the cluster.`;
|
|
620
629
|
}
|
|
621
630
|
|
|
622
631
|
if (data.wasClaimed === undefined) {
|
|
623
|
-
return
|
|
632
|
+
return `No result came back for this kubectl command in time, and whether ${
|
|
633
|
+
data.isForKubernetesAiAgent ? "the Kubernetes AI agent" : "a Runner"
|
|
634
|
+
} picked it up could not be read. What the command did is unknown.`;
|
|
624
635
|
}
|
|
625
636
|
|
|
626
|
-
return `The
|
|
637
|
+
return `The ${executor} took this kubectl command but did not report a result in time — it stopped responding, or kubectl outlived its ${KubectlJobRunner.describeSeconds(
|
|
627
638
|
data.executionTimeoutInMs,
|
|
628
639
|
)} timeout. Whether it ran, and what it did, is unknown.`;
|
|
629
640
|
}
|
|
@@ -38,6 +38,7 @@ import {
|
|
|
38
38
|
KubernetesRunnerPosture,
|
|
39
39
|
isKubernetesAgentRunnerName,
|
|
40
40
|
isKubernetesAgentRunnerPosture,
|
|
41
|
+
getKubernetesAiAccessTargetKind,
|
|
41
42
|
isUnattendedRemediationMode,
|
|
42
43
|
parseKubernetesRunnerPosture,
|
|
43
44
|
} from "../../../../Types/Kubernetes/KubernetesClusterAiAccess";
|
|
@@ -82,7 +83,10 @@ import KubectlJobRunner, {
|
|
|
82
83
|
RedactedKubectlOutput,
|
|
83
84
|
} from "../ClusterAccess/KubectlJobRunner";
|
|
84
85
|
import KubectlOutputRedactor from "../../../../Utils/AiRemediation/KubectlOutputRedactor";
|
|
85
|
-
import {
|
|
86
|
+
import {
|
|
87
|
+
UNATTENDED_ROUND_BECOMES_PROPOSAL_SUMMARY,
|
|
88
|
+
describeClusterAccessTarget,
|
|
89
|
+
} from "../ClusterAccess/ClusterAccessContext";
|
|
86
90
|
import logger from "../../Logger";
|
|
87
91
|
|
|
88
92
|
/*
|
|
@@ -404,7 +408,7 @@ export default class RemediationCommandToolkit {
|
|
|
404
408
|
definition: {
|
|
405
409
|
name: "list_command_targets",
|
|
406
410
|
description:
|
|
407
|
-
"List where this remediation may run commands: Runners (Bash runs on the Runner's host; SSH runs on an assigned credential's host) and Kubernetes clusters (Kubectl runs through the cluster's Runner). Call this before composing any command.",
|
|
411
|
+
"List where this remediation may run commands: Runners (Bash runs on the Runner's host; SSH runs on an assigned credential's host) and Kubernetes clusters (Kubectl runs through the cluster's Kubernetes AI agent or Runner). Call this before composing any command.",
|
|
408
412
|
inputSchema: {
|
|
409
413
|
type: "object",
|
|
410
414
|
properties: {},
|
|
@@ -497,7 +501,7 @@ export default class RemediationCommandToolkit {
|
|
|
497
501
|
kubernetesClusterId: cluster.clusterId,
|
|
498
502
|
name: cluster.clusterName,
|
|
499
503
|
stepTypes: "Kubectl",
|
|
500
|
-
via:
|
|
504
|
+
via: `${describeClusterAccessTarget(cluster)}${
|
|
501
505
|
cluster.accessMethod === "in_cluster" ? " (in-cluster)" : ""
|
|
502
506
|
}`,
|
|
503
507
|
/*
|
|
@@ -785,7 +789,10 @@ export default class RemediationCommandToolkit {
|
|
|
785
789
|
return refusal
|
|
786
790
|
? RemediationCommandToolkit.describeRunnerScopeRefusal({
|
|
787
791
|
refusal,
|
|
788
|
-
runnerLabel:
|
|
792
|
+
runnerLabel:
|
|
793
|
+
getKubernetesAiAccessTargetKind(data.cluster.runner) === "ai_agent"
|
|
794
|
+
? `the Kubernetes AI agent of cluster "${data.cluster.clusterName}"`
|
|
795
|
+
: `the Runner of cluster "${data.cluster.clusterName}"`,
|
|
789
796
|
settings: RemediationCommandToolkit.getRunnerScopeSettings(
|
|
790
797
|
data.cluster,
|
|
791
798
|
),
|
|
@@ -794,14 +801,29 @@ export default class RemediationCommandToolkit {
|
|
|
794
801
|
}
|
|
795
802
|
|
|
796
803
|
/*
|
|
797
|
-
* Where the
|
|
798
|
-
*
|
|
799
|
-
*
|
|
800
|
-
*
|
|
804
|
+
* Where the target's write scope is set, for a refusal to name — three
|
|
805
|
+
* ways, by who runs kubectl for the cluster:
|
|
806
|
+
*
|
|
807
|
+
* - the Kubernetes AI agent (runner.kind "ai_agent"): the chart's
|
|
808
|
+
* aiAgent.remediation.* values;
|
|
809
|
+
* - the chart's previous in-cluster Runner (by its server-owned name, or
|
|
810
|
+
* its posture): its values are aiAccess.remediation.*, and changing
|
|
811
|
+
* them now means upgrading the chart to the AI agent, which replaces it;
|
|
812
|
+
* - any other Runner — a credential Runner, which no chart configures:
|
|
813
|
+
* its own environment.
|
|
801
814
|
*/
|
|
802
|
-
|
|
803
|
-
cluster: KubernetesClusterAiAccessStatus,
|
|
815
|
+
public static getRunnerScopeSettings(
|
|
816
|
+
cluster: Pick<KubernetesClusterAiAccessStatus, "runner">,
|
|
804
817
|
): { namespaces: string; nodeOperations: string } {
|
|
818
|
+
if (getKubernetesAiAccessTargetKind(cluster.runner) === "ai_agent") {
|
|
819
|
+
return {
|
|
820
|
+
namespaces:
|
|
821
|
+
"aiAgent.remediation.namespaces on the Kubernetes agent chart",
|
|
822
|
+
nodeOperations:
|
|
823
|
+
"aiAgent.remediation.nodeOperations=false on the Kubernetes agent chart",
|
|
824
|
+
};
|
|
825
|
+
}
|
|
826
|
+
|
|
805
827
|
const isAgentRunner: boolean =
|
|
806
828
|
isKubernetesAgentRunnerName(cluster.runner?.name) ||
|
|
807
829
|
isKubernetesAgentRunnerPosture(cluster.runner?.posture);
|
|
@@ -809,9 +831,9 @@ export default class RemediationCommandToolkit {
|
|
|
809
831
|
if (isAgentRunner) {
|
|
810
832
|
return {
|
|
811
833
|
namespaces:
|
|
812
|
-
"aiAccess.remediation.namespaces on the Kubernetes agent chart",
|
|
834
|
+
"aiAccess.remediation.namespaces on the Kubernetes agent chart; after upgrading to the Kubernetes AI agent, aiAgent.remediation.namespaces",
|
|
813
835
|
nodeOperations:
|
|
814
|
-
"aiAccess.remediation.nodeOperations=false on the Kubernetes agent chart",
|
|
836
|
+
"aiAccess.remediation.nodeOperations=false on the Kubernetes agent chart; after upgrading to the Kubernetes AI agent, aiAgent.remediation.nodeOperations",
|
|
815
837
|
};
|
|
816
838
|
}
|
|
817
839
|
|
|
@@ -1783,7 +1805,7 @@ export default class RemediationCommandToolkit {
|
|
|
1783
1805
|
return {
|
|
1784
1806
|
text: `Cluster "${status.clusterName}" no longer allows AI remediation${
|
|
1785
1807
|
gap ? ` (${gap.title})` : ""
|
|
1786
|
-
} — its AI page changed during this run. ${stopText}`,
|
|
1808
|
+
} — its AI agent page changed during this run. ${stopText}`,
|
|
1787
1809
|
};
|
|
1788
1810
|
}
|
|
1789
1811
|
|
|
@@ -1794,7 +1816,7 @@ export default class RemediationCommandToolkit {
|
|
|
1794
1816
|
) {
|
|
1795
1817
|
this.revokeCluster(clusterId);
|
|
1796
1818
|
return {
|
|
1797
|
-
text: `Cluster "${status.clusterName}" was re-bound to a different Runner or credential during this run. ${stopText}`,
|
|
1819
|
+
text: `Cluster "${status.clusterName}" was re-bound to a different Runner or credential during this run (or its Kubernetes AI agent took over from its Runner). ${stopText}`,
|
|
1798
1820
|
};
|
|
1799
1821
|
}
|
|
1800
1822
|
|
|
@@ -2001,7 +2023,7 @@ export default class RemediationCommandToolkit {
|
|
|
2001
2023
|
return {
|
|
2002
2024
|
definition: {
|
|
2003
2025
|
name: "propose_remediation_commands",
|
|
2004
|
-
description: `Propose an ordered plan of at most ${MAX_PLAN_COMMANDS} remediation commands for one-click human approval. Nothing executes until a human approves the whole plan. Call this at most once with your final plan (a later call replaces the earlier one). Provide a rollbackCommand for every state-changing command that has an undo (for Kubectl, e.g. kubectl rollout undo deployment/<name> -n <namespace>). Kubectl commands run through the cluster's Runner, and a write outside its writeScope (list_command_targets) is refused; ${KUBECTL_NEVER_RUNS_SUMMARY}.`,
|
|
2026
|
+
description: `Propose an ordered plan of at most ${MAX_PLAN_COMMANDS} remediation commands for one-click human approval. Nothing executes until a human approves the whole plan. Call this at most once with your final plan (a later call replaces the earlier one). Provide a rollbackCommand for every state-changing command that has an undo (for Kubectl, e.g. kubectl rollout undo deployment/<name> -n <namespace>). Kubectl commands run through the cluster's Kubernetes AI agent or Runner, and a write outside its writeScope (list_command_targets) is refused; ${KUBECTL_NEVER_RUNS_SUMMARY}.`,
|
|
2005
2027
|
inputSchema: {
|
|
2006
2028
|
type: "object",
|
|
2007
2029
|
properties: {
|
|
@@ -107,6 +107,26 @@ import CaptureSpan from "../../Telemetry/CaptureSpan";
|
|
|
107
107
|
* suggestion settles what happened instead of re-executing anything.
|
|
108
108
|
*/
|
|
109
109
|
|
|
110
|
+
/*
|
|
111
|
+
* A cluster round: remediation a cluster's AI agent page asked for (its
|
|
112
|
+
* Fixes mode), not an auto-remediation rule — it names a cluster and no
|
|
113
|
+
* rule. The project's "Enable AI command execution" opt-in gates rule
|
|
114
|
+
* rounds only; a cluster round's consent lives on the cluster (see
|
|
115
|
+
* RemediationExecutionRunner.checkProjectGates). Keyed on the suggestion
|
|
116
|
+
* row, never on the plan's step types: a rule can compose an all-kubectl
|
|
117
|
+
* plan, and it was composed under the opt-in, so it stays under it. Shared
|
|
118
|
+
* with the approve route so execution and approval can never disagree about
|
|
119
|
+
* which rounds need the opt-in.
|
|
120
|
+
*/
|
|
121
|
+
export function isClusterRemediationRound(suggestion: {
|
|
122
|
+
kubernetesClusterId?: ObjectID | undefined;
|
|
123
|
+
autoRemediationRuleId?: ObjectID | undefined;
|
|
124
|
+
}): boolean {
|
|
125
|
+
return (
|
|
126
|
+
Boolean(suggestion.kubernetesClusterId) && !suggestion.autoRemediationRuleId
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
|
|
110
130
|
const MAX_SIGNAL_TITLE_CHARS: number = 500;
|
|
111
131
|
const MAX_SIGNAL_DESCRIPTION_CHARS: number = 4000;
|
|
112
132
|
const MAX_POSTED_ANALYSIS_CHARS: number = 6000;
|
|
@@ -507,25 +527,16 @@ export default class RemediationExecutionRunner {
|
|
|
507
527
|
return;
|
|
508
528
|
}
|
|
509
529
|
|
|
510
|
-
// Gates that must still hold at execution time, not just at rule match.
|
|
511
|
-
const gateFailure: string | null =
|
|
512
|
-
await this.checkProjectGates(projectId);
|
|
513
|
-
if (gateFailure) {
|
|
514
|
-
await this.settleNoneApplicable({
|
|
515
|
-
suggestion,
|
|
516
|
-
rationaleMarkdown: gateFailure,
|
|
517
|
-
});
|
|
518
|
-
await this.completeRunQuietly(aiRunId);
|
|
519
|
-
return;
|
|
520
|
-
}
|
|
521
|
-
|
|
522
530
|
/*
|
|
523
531
|
* A cluster-level round whose cluster was deleted while it waited in
|
|
524
532
|
* the queue: the delete nulled kubernetesClusterId (ON DELETE SET
|
|
525
533
|
* NULL), and a cluster round never had a rule — so without this it
|
|
526
534
|
* would fall into the rule lane below and be closed as "the rule
|
|
527
535
|
* behind this suggestion was deleted", naming a rule that never
|
|
528
|
-
* existed. Its server-written name is what is left to tell.
|
|
536
|
+
* existed. Its server-written name is what is left to tell. Checked
|
|
537
|
+
* before the project gates: nothing is left to run, and with no
|
|
538
|
+
* cluster on the row it no longer reads as a cluster round, so the
|
|
539
|
+
* gates would otherwise blame an opt-in it never needed.
|
|
529
540
|
*/
|
|
530
541
|
const deletedClusterRound: { clusterName: string } | null =
|
|
531
542
|
!suggestion.kubernetesClusterId && !suggestion.autoRemediationRuleId
|
|
@@ -541,6 +552,20 @@ export default class RemediationExecutionRunner {
|
|
|
541
552
|
return;
|
|
542
553
|
}
|
|
543
554
|
|
|
555
|
+
// Gates that must still hold at execution time, not just at rule match.
|
|
556
|
+
const gateFailure: string | null = await this.checkProjectGates({
|
|
557
|
+
projectId,
|
|
558
|
+
isClusterRound: isClusterRemediationRound(suggestion),
|
|
559
|
+
});
|
|
560
|
+
if (gateFailure) {
|
|
561
|
+
await this.settleNoneApplicable({
|
|
562
|
+
suggestion,
|
|
563
|
+
rationaleMarkdown: gateFailure,
|
|
564
|
+
});
|
|
565
|
+
await this.completeRunQuietly(aiRunId);
|
|
566
|
+
return;
|
|
567
|
+
}
|
|
568
|
+
|
|
544
569
|
if (suggestion.kubernetesClusterId) {
|
|
545
570
|
/*
|
|
546
571
|
* Cluster-level remediation: the cluster's AI page plays the rule's
|
|
@@ -565,7 +590,7 @@ export default class RemediationExecutionRunner {
|
|
|
565
590
|
suggestion,
|
|
566
591
|
rationaleMarkdown: `OneUptime AI can no longer remediate cluster "${
|
|
567
592
|
clusterTarget?.clusterName || "(deleted)"
|
|
568
|
-
}"${firstGap ? `: ${firstGap}` : ""}. Nothing was run or proposed. Review the cluster's AI page.`,
|
|
593
|
+
}"${firstGap ? `: ${firstGap}` : ""}. Nothing was run or proposed. Review the cluster's AI agent page (AI → Agent).`,
|
|
569
594
|
});
|
|
570
595
|
await this.completeRunQuietly(aiRunId);
|
|
571
596
|
return;
|
|
@@ -1119,7 +1144,7 @@ export default class RemediationExecutionRunner {
|
|
|
1119
1144
|
if (live.withdrawnReason) {
|
|
1120
1145
|
await this.settleNoneApplicable({
|
|
1121
1146
|
suggestion,
|
|
1122
|
-
rationaleMarkdown: `${live.withdrawnReason} Review the cluster's AI page.\n\n${data.rationaleMarkdown}`,
|
|
1147
|
+
rationaleMarkdown: `${live.withdrawnReason} Review the cluster's AI agent page (AI → Agent).\n\n${data.rationaleMarkdown}`,
|
|
1123
1148
|
});
|
|
1124
1149
|
return;
|
|
1125
1150
|
}
|
|
@@ -1386,12 +1411,26 @@ export default class RemediationExecutionRunner {
|
|
|
1386
1411
|
});
|
|
1387
1412
|
}
|
|
1388
1413
|
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1414
|
+
/*
|
|
1415
|
+
* The project switches a round must still pass when it runs. Null when
|
|
1416
|
+
* they do; otherwise the rationale for settling quietly.
|
|
1417
|
+
*
|
|
1418
|
+
* Enable AI and Enable auto-remediation are kill switches for every
|
|
1419
|
+
* round. The "Enable AI command execution" opt-in gates rule rounds
|
|
1420
|
+
* (Bash/SSH on Runners, and kubectl a rule composes) but not a cluster
|
|
1421
|
+
* round (isClusterRemediationRound): its consent is the cluster's own
|
|
1422
|
+
* Fixes mode plus, for the in-cluster Kubernetes AI agent, the chart's
|
|
1423
|
+
* write RBAC. A cluster reached through an advanced Runner with a
|
|
1424
|
+
* Kubernetes credential has no chart RBAC behind it, so its status keeps
|
|
1425
|
+
* the project_ai_command_execution_disabled gap while the opt-in is off —
|
|
1426
|
+
* and the cluster round stops at isRemediationReady instead.
|
|
1427
|
+
*/
|
|
1428
|
+
public static async checkProjectGates(data: {
|
|
1429
|
+
projectId: ObjectID;
|
|
1430
|
+
isClusterRound: boolean;
|
|
1431
|
+
}): Promise<string | null> {
|
|
1393
1432
|
const project: Project | null = await ProjectService.findOneById({
|
|
1394
|
-
id: projectId,
|
|
1433
|
+
id: data.projectId,
|
|
1395
1434
|
select: {
|
|
1396
1435
|
enableAi: true,
|
|
1397
1436
|
enableAutoRemediation: true,
|
|
@@ -1405,15 +1444,19 @@ export default class RemediationExecutionRunner {
|
|
|
1405
1444
|
project.enableAi === false ||
|
|
1406
1445
|
project.enableAutoRemediation === false
|
|
1407
1446
|
) {
|
|
1408
|
-
return "AI or auto-remediation was disabled for this project before the run started — nothing was run or proposed.";
|
|
1447
|
+
return "AI or auto-remediation was disabled for this project before the run started (Project Settings → AI Features) — nothing was run or proposed.";
|
|
1448
|
+
}
|
|
1449
|
+
|
|
1450
|
+
if (data.isClusterRound) {
|
|
1451
|
+
return null;
|
|
1409
1452
|
}
|
|
1410
1453
|
|
|
1411
1454
|
/*
|
|
1412
|
-
* Opt-in semantics (=== true): AI command execution never runs
|
|
1413
|
-
* project that has not explicitly turned it on.
|
|
1455
|
+
* Opt-in semantics (=== true): a rule's AI command execution never runs
|
|
1456
|
+
* in a project that has not explicitly turned it on.
|
|
1414
1457
|
*/
|
|
1415
1458
|
if (project.enableAiCommandExecution !== true) {
|
|
1416
|
-
return "AI command execution is not enabled for this project (Project Settings → AI) — nothing was run or proposed.";
|
|
1459
|
+
return "AI command execution is not enabled for this project (Project Settings → AI Features) — nothing was run or proposed.";
|
|
1417
1460
|
}
|
|
1418
1461
|
|
|
1419
1462
|
return null;
|
|
@@ -18,6 +18,7 @@ import Project from "../../../../Models/DatabaseModels/Project";
|
|
|
18
18
|
import LlmProvider from "../../../../Models/DatabaseModels/LlmProvider";
|
|
19
19
|
import AIRunService from "../../../Services/AIRunService";
|
|
20
20
|
import AIRunEventService from "../../../Services/AIRunEventService";
|
|
21
|
+
import AIService from "../../../Services/AIService";
|
|
21
22
|
import ProjectService from "../../../Services/ProjectService";
|
|
22
23
|
import LlmProviderService from "../../../Services/LlmProviderService";
|
|
23
24
|
import AIInvestigationQueue from "./InvestigationQueue";
|
|
@@ -205,10 +206,10 @@ export interface InvestigationRequest {
|
|
|
205
206
|
|
|
206
207
|
export default class AIInvestigationEngine {
|
|
207
208
|
/*
|
|
208
|
-
* Shared gate: AI enabled, the subject's auto-investigation opt-in on,
|
|
209
|
-
* LLM provider configured
|
|
210
|
-
* they can be enabled independently.
|
|
211
|
-
* context assembly.
|
|
209
|
+
* Shared gate: AI enabled, the subject's auto-investigation opt-in on, an
|
|
210
|
+
* LLM provider configured, and AI credits to pay for it. Incidents and
|
|
211
|
+
* alerts each have their own opt-in so they can be enabled independently.
|
|
212
|
+
* Runs before any (subject-specific) context assembly.
|
|
212
213
|
*/
|
|
213
214
|
@CaptureSpan()
|
|
214
215
|
public static async isEnabledForProject(
|
|
@@ -249,16 +250,58 @@ export default class AIInvestigationEngine {
|
|
|
249
250
|
return "automatic_investigation_disabled";
|
|
250
251
|
}
|
|
251
252
|
|
|
253
|
+
return this.getProviderOrBalanceReason(projectId);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/*
|
|
257
|
+
* The half of the gate that is not a switch: a model to call, and AI
|
|
258
|
+
* credits to pay for it. Shared with the other autonomous AI work that
|
|
259
|
+
* has its own switch (the postmortem draft on resolve), so the two can
|
|
260
|
+
* never disagree about whether AI can run at all.
|
|
261
|
+
*
|
|
262
|
+
* The balance check is the same predicate as the Kubernetes cluster's
|
|
263
|
+
* ai_balance_insufficient gap (AIService.getAiBalanceBlocker): on
|
|
264
|
+
* OneUptime's own billed provider, with no credits left and auto-recharge
|
|
265
|
+
* off, every model call would be refused with "Insufficient AI balance" —
|
|
266
|
+
* so a run started now would only fail, be retried, and fail again, and
|
|
267
|
+
* nobody would see why. It fails OPEN: a balance that cannot be read
|
|
268
|
+
* never blocks, because the model call itself still enforces the balance.
|
|
269
|
+
*/
|
|
270
|
+
public static async getProviderOrBalanceReason(
|
|
271
|
+
projectId: ObjectID,
|
|
272
|
+
): Promise<"provider_missing" | "insufficient_ai_balance" | null> {
|
|
252
273
|
const llmProvider: LlmProvider | null =
|
|
253
274
|
await LlmProviderService.getLLMProviderForProject(projectId);
|
|
254
275
|
|
|
255
276
|
if (!llmProvider) {
|
|
256
277
|
logger.debug(
|
|
257
|
-
`AI: skipping
|
|
278
|
+
`AI: skipping autonomous AI work for project ${projectId.toString()} — no LLM provider configured.`,
|
|
258
279
|
);
|
|
259
280
|
return "provider_missing";
|
|
260
281
|
}
|
|
261
282
|
|
|
283
|
+
let balanceBlocker: string | null = null;
|
|
284
|
+
|
|
285
|
+
try {
|
|
286
|
+
balanceBlocker = await AIService.getAiBalanceBlocker({
|
|
287
|
+
projectId,
|
|
288
|
+
// Already resolved above — spares the predicate a second lookup.
|
|
289
|
+
llmProvider,
|
|
290
|
+
});
|
|
291
|
+
} catch (error) {
|
|
292
|
+
logger.error(
|
|
293
|
+
`AI: could not check the AI balance for project ${projectId.toString()}; not blocking on it: ${error}`,
|
|
294
|
+
);
|
|
295
|
+
balanceBlocker = null;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
if (balanceBlocker) {
|
|
299
|
+
logger.debug(
|
|
300
|
+
`AI: skipping autonomous AI work for project ${projectId.toString()} — ${balanceBlocker}`,
|
|
301
|
+
);
|
|
302
|
+
return "insufficient_ai_balance";
|
|
303
|
+
}
|
|
304
|
+
|
|
262
305
|
return null;
|
|
263
306
|
}
|
|
264
307
|
|