@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.
Files changed (639) hide show
  1. package/Models/DatabaseModels/Index.ts +2 -0
  2. package/Models/DatabaseModels/KubernetesAiAgent.ts +364 -0
  3. package/Models/DatabaseModels/KubernetesCluster.ts +3 -3
  4. package/Models/DatabaseModels/Project.ts +55 -5
  5. package/Models/DatabaseModels/ProxmoxResource.ts +49 -1
  6. package/Models/DatabaseModels/RunnerJob.ts +75 -0
  7. package/Models/DatabaseModels/TeamComplianceSetting.ts +143 -2
  8. package/Models/DatabaseModels/WorkspaceProjectAuthToken.ts +17 -0
  9. package/Server/API/AIChatAPI.ts +6 -3
  10. package/Server/API/AIInvestigationAPI.ts +17 -10
  11. package/Server/API/AutoRemediationAPI.ts +207 -25
  12. package/Server/API/KubernetesClusterAiAccessAPI.ts +623 -21
  13. package/Server/API/MicrosoftTeamsAPI.ts +93 -14
  14. package/Server/API/ProxmoxResourceAPI.ts +244 -14
  15. package/Server/Infrastructure/GlobalCache.ts +32 -0
  16. package/Server/Infrastructure/Postgres/SchemaMigrations/1796000000000-AddTeamComplianceRuleScope.ts +99 -0
  17. package/Server/Infrastructure/Postgres/SchemaMigrations/1796100000000-AddKubernetesAiAgentAndAiDefaults.ts +137 -0
  18. package/Server/Infrastructure/Postgres/SchemaMigrations/1796200000000-AddProxmoxResourceNativePushColumns.ts +42 -0
  19. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
  20. package/Server/Middleware/TelemetryIngest.ts +41 -18
  21. package/Server/Services/AIService.ts +70 -1
  22. package/Server/Services/AlertService.ts +352 -11
  23. package/Server/Services/AlertSeverityService.ts +65 -15
  24. package/Server/Services/AutoRemediationRuleService.ts +1 -1
  25. package/Server/Services/IncidentService.ts +280 -104
  26. package/Server/Services/IncidentSeverityService.ts +66 -15
  27. package/Server/Services/KubernetesAiAgentJobService.ts +185 -0
  28. package/Server/Services/KubernetesAiAgentService.ts +1634 -0
  29. package/Server/Services/KubernetesClusterAiAccessService.ts +1118 -451
  30. package/Server/Services/KubernetesClusterService.ts +129 -21
  31. package/Server/Services/ProjectService.ts +32 -0
  32. package/Server/Services/ProxmoxResourceService.ts +322 -5
  33. package/Server/Services/RunnerJobService.ts +241 -104
  34. package/Server/Services/RunnerService.ts +1 -1
  35. package/Server/Services/ScheduledMaintenanceService.ts +737 -1
  36. package/Server/Services/ScheduledMaintenanceStateTimelineService.ts +414 -56
  37. package/Server/Services/TeamComplianceSettingService.ts +1125 -9
  38. package/Server/Utils/AI/ClusterAccess/ClusterAccessContext.ts +67 -9
  39. package/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.ts +39 -10
  40. package/Server/Utils/AI/ClusterAccess/KubectlJobRunner.ts +14 -3
  41. package/Server/Utils/AI/Remediation/RemediationCommandTools.ts +37 -15
  42. package/Server/Utils/AI/Remediation/RemediationExecutionRunner.ts +67 -24
  43. package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +48 -5
  44. package/Server/Utils/AI/SRE/IncidentPostmortemRunner.ts +40 -8
  45. package/Server/Utils/AI/SRE/InvestigationEligibility.ts +13 -2
  46. package/Server/Utils/AI/SRE/InvestigationGrader.ts +1 -1
  47. package/Server/Utils/AutoRemediation/CommandPlanExecutor.ts +6 -1
  48. package/Server/Utils/Telemetry/InventoryEntityRegistry.ts +133 -7
  49. package/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.ts +58 -4
  50. package/Server/Utils/Telemetry/ProxmoxNativeNodeLiveness.ts +447 -0
  51. package/Server/Utils/Telemetry/ProxmoxNativePush.ts +903 -0
  52. package/Server/Utils/Telemetry/TelemetryEntity.ts +87 -27
  53. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +684 -47
  54. package/Tests/App/AdminDashboard/RowActionPlacementOverrides.test.tsx +278 -0
  55. package/Tests/App/Dashboard/AIChatChartWidgetZoom.test.tsx +738 -0
  56. package/Tests/App/Dashboard/AIFeaturesSettingsPointers.test.tsx +147 -0
  57. package/Tests/App/Dashboard/AIInsightsKubernetesClusterPage.test.tsx +1523 -0
  58. package/Tests/App/Dashboard/AdminUserNotificationMethodsPage.test.tsx +463 -3
  59. package/Tests/App/Dashboard/AffectedResourcesPickerDropdownPlacement.test.tsx +958 -0
  60. package/Tests/App/Dashboard/AffectedResourcesPickerFocusLeave.test.tsx +595 -0
  61. package/Tests/App/Dashboard/AskAiAvailability.test.ts +20 -3
  62. package/Tests/App/Dashboard/AskAiDisabled.test.tsx +8 -3
  63. package/Tests/App/Dashboard/CephRateChartReload.test.tsx +1456 -0
  64. package/Tests/App/Dashboard/CephTimeRangeZoom.test.tsx +1229 -0
  65. package/Tests/App/Dashboard/ChartCardTimeRangeZoom.test.tsx +151 -0
  66. package/Tests/App/Dashboard/ChartCardZoomAffordances.test.tsx +257 -0
  67. package/Tests/App/Dashboard/ChartRefetchFrame.test.tsx +141 -0
  68. package/Tests/App/Dashboard/ChartZoomHarness.tsx +249 -0
  69. package/Tests/App/Dashboard/ChartZoomStandIn.tsx +131 -0
  70. package/Tests/App/Dashboard/CloudServerlessSlowLoads.test.tsx +628 -0
  71. package/Tests/App/Dashboard/CloudServerlessTimeRangeZoom.test.tsx +607 -0
  72. package/Tests/App/Dashboard/ClusterAccessNotice.test.tsx +91 -19
  73. package/Tests/App/Dashboard/CompanionMetricsTabZoom.test.tsx +632 -0
  74. package/Tests/App/Dashboard/ContainerChartZoomStandIn.tsx +195 -0
  75. package/Tests/App/Dashboard/ContainerHostOverviewSlowLoads.test.tsx +542 -0
  76. package/Tests/App/Dashboard/ContainerHostOverviewTimeRangeZoom.test.tsx +848 -0
  77. package/Tests/App/Dashboard/ContainerMetricsTimeRangeZoom.test.tsx +561 -0
  78. package/Tests/App/Dashboard/DashboardBoardWideZoomShell.test.tsx +1147 -0
  79. package/Tests/App/Dashboard/DashboardEditPermissions.test.tsx +3 -2
  80. package/Tests/App/Dashboard/DashboardHistogramWidgetDragCursor.test.tsx +399 -0
  81. package/Tests/App/Dashboard/DashboardHistogramWidgetZoom.test.tsx +985 -0
  82. package/Tests/App/Dashboard/DashboardHistogramWidgetZoomHint.test.tsx +803 -0
  83. package/Tests/App/Dashboard/DashboardLazyPages.test.tsx +1 -0
  84. package/Tests/App/Dashboard/DashboardSettingsPreviewZoom.test.tsx +679 -0
  85. package/Tests/App/Dashboard/DashboardSloAndDataSourceChartZoom.test.tsx +881 -0
  86. package/Tests/App/Dashboard/DashboardTraceStatusWidgets.test.tsx +878 -0
  87. package/Tests/App/Dashboard/DatabaseMetricChartModalTimeRangeZoom.test.tsx +442 -0
  88. package/Tests/App/Dashboard/DatabaseOverviewTimeRangeZoom.test.tsx +831 -0
  89. package/Tests/App/Dashboard/DatabaseServerComponents.test.tsx +43 -0
  90. package/Tests/App/Dashboard/DockerSwarmInsightsTimeRangeZoom.test.tsx +524 -0
  91. package/Tests/App/Dashboard/DockerSwarmRateChartRefresh.test.tsx +259 -0
  92. package/Tests/App/Dashboard/EdgeDetailPanelHistory.test.tsx +763 -0
  93. package/Tests/App/Dashboard/EdgeDetailPanelTimeRangeZoom.test.tsx +547 -0
  94. package/Tests/App/Dashboard/EdgeHistoryBucketsCases.tsx +565 -0
  95. package/Tests/App/Dashboard/EdgeHistoryBucketsKathmandu.test.tsx +73 -0
  96. package/Tests/App/Dashboard/EdgeHistoryBucketsKolkata.test.tsx +74 -0
  97. package/Tests/App/Dashboard/EdgeHistoryBucketsNewYork.test.tsx +72 -0
  98. package/Tests/App/Dashboard/EdgeHistoryBucketsUtc.test.tsx +72 -0
  99. package/Tests/App/Dashboard/EmbeddedMetricCardRefresh.test.tsx +310 -0
  100. package/Tests/App/Dashboard/EmbeddedMetricCardTimeRangeZoom.test.tsx +536 -0
  101. package/Tests/App/Dashboard/EscalationRuleReadiness.test.tsx +3 -1
  102. package/Tests/App/Dashboard/EscalationRuleRowActions.test.tsx +660 -0
  103. package/Tests/App/Dashboard/EventNotes.test.tsx +2 -2
  104. package/Tests/App/Dashboard/EventOverviewPages.test.tsx +587 -13
  105. package/Tests/App/Dashboard/EventOverviewSnapshotExplorerZoom.test.tsx +1139 -0
  106. package/Tests/App/Dashboard/EventOverviewSnapshotZoomAcrossTabs.test.tsx +1057 -0
  107. package/Tests/App/Dashboard/EventOverviewTelemetrySnapshotZoom.test.tsx +757 -0
  108. package/Tests/App/Dashboard/ExceptionOccurrenceTrendZoom.test.tsx +675 -0
  109. package/Tests/App/Dashboard/ExceptionOccurrencesZoomSurvivesViewSwitch.test.tsx +405 -0
  110. package/Tests/App/Dashboard/ExceptionSignalPages.test.tsx +67 -3
  111. package/Tests/App/Dashboard/ExceptionTablesSpanStatus.test.tsx +515 -0
  112. package/Tests/App/Dashboard/ExplorerOwnZoomRegression.test.tsx +739 -0
  113. package/Tests/App/Dashboard/FlowBandwidthAxisCases.tsx +461 -0
  114. package/Tests/App/Dashboard/FlowBandwidthAxisKathmandu.test.tsx +25 -0
  115. package/Tests/App/Dashboard/FlowBandwidthAxisKolkata.test.tsx +25 -0
  116. package/Tests/App/Dashboard/FlowBandwidthAxisNewYork.test.tsx +25 -0
  117. package/Tests/App/Dashboard/FlowBandwidthAxisUtc.test.tsx +24 -0
  118. package/Tests/App/Dashboard/FlowTopTalkersZoomRefetch.test.tsx +722 -0
  119. package/Tests/App/Dashboard/FlowViewportGuard.test.tsx +2526 -0
  120. package/Tests/App/Dashboard/HostPagesSlowLoads.test.tsx +872 -0
  121. package/Tests/App/Dashboard/HostPagesTimeRangeZoom.test.tsx +1208 -0
  122. package/Tests/App/Dashboard/IncidentRootCauseTimeRangeZoom.test.tsx +358 -0
  123. package/Tests/App/Dashboard/InfrastructureGraph.test.tsx +100 -9
  124. package/Tests/App/Dashboard/InfrastructureMetricsTabTimeRangeZoom.test.tsx +485 -0
  125. package/Tests/App/Dashboard/InvestigationDrawerCompanionZoom.test.tsx +655 -0
  126. package/Tests/App/Dashboard/InvestigationDrawerZoom.test.tsx +830 -0
  127. package/Tests/App/Dashboard/InvestigationNotStarted.test.tsx +338 -2
  128. package/Tests/App/Dashboard/InvoicesPayInvoice.test.tsx +454 -16
  129. package/Tests/App/Dashboard/KubernetesClusterAiAccessSettings.test.ts +799 -819
  130. package/Tests/App/Dashboard/KubernetesClusterAiAgentOverviewCard.test.tsx +367 -0
  131. package/Tests/App/Dashboard/KubernetesClusterAiAgentStatus.test.ts +1202 -0
  132. package/Tests/App/Dashboard/KubernetesClusterAiDocumentationMarkdown.test.ts +106 -0
  133. package/Tests/App/Dashboard/KubernetesClusterAiNavigation.test.tsx +354 -0
  134. package/Tests/App/Dashboard/KubernetesClusterAiPage.test.tsx +1884 -2054
  135. package/Tests/App/Dashboard/KubernetesClusterAiPageServerParity.test.ts +478 -179
  136. package/Tests/App/Dashboard/KubernetesClusterMetricTooltips.test.ts +50 -0
  137. package/Tests/App/Dashboard/KubernetesClusterOverviewTooltips.test.tsx +2 -1
  138. package/Tests/App/Dashboard/KubernetesClusterOverviewZoom.test.tsx +1217 -0
  139. package/Tests/App/Dashboard/KubernetesClusterPagesZoom.test.tsx +731 -0
  140. package/Tests/App/Dashboard/KubernetesCostsLoadRecovery.test.tsx +869 -0
  141. package/Tests/App/Dashboard/KubernetesCostsZoom.test.tsx +1214 -0
  142. package/Tests/App/Dashboard/KubernetesCostsZoomExactHours.test.tsx +692 -0
  143. package/Tests/App/Dashboard/KubernetesNetworkThroughputReload.test.tsx +902 -0
  144. package/Tests/App/Dashboard/KubernetesNetworkZoomBucketEdges.test.tsx +571 -0
  145. package/Tests/App/Dashboard/KubernetesOverviewZoomBucketEdges.test.tsx +697 -0
  146. package/Tests/App/Dashboard/KubernetesResourceMetricsTabZoom.test.tsx +633 -0
  147. package/Tests/App/Dashboard/LogsExplorerTimeRangeZoom.test.tsx +470 -0
  148. package/Tests/App/Dashboard/LogsInsightsTimeRangeZoom.test.tsx +948 -0
  149. package/Tests/App/Dashboard/LogsViewerPinnedWindowZoom.test.tsx +486 -0
  150. package/Tests/App/Dashboard/MetricChartsBucketInspectorDoubleClick.test.tsx +1001 -0
  151. package/Tests/App/Dashboard/MetricExplorerInvestigationAutoRefresh.test.tsx +514 -0
  152. package/Tests/App/Dashboard/MetricExplorerSavedViewZoomRoundTrip.test.tsx +581 -0
  153. package/Tests/App/Dashboard/MetricExplorerTimeRangeZoom.test.tsx +1162 -0
  154. package/Tests/App/Dashboard/MetricMonitorPreviewZoomLabel.test.ts +72 -0
  155. package/Tests/App/Dashboard/MetricRowSparklineTimeRangeZoom.test.tsx +204 -0
  156. package/Tests/App/Dashboard/MetricViewFirstResultLands.test.tsx +408 -0
  157. package/Tests/App/Dashboard/MetricViewOwnZoomResetPlacement.test.tsx +952 -0
  158. package/Tests/App/Dashboard/MetricViewTimeRange.test.ts +139 -0
  159. package/Tests/App/Dashboard/MetricViewTimeRangeZoom.test.tsx +556 -0
  160. package/Tests/App/Dashboard/MonitorMetricsChartWrappersZoom.test.tsx +552 -0
  161. package/Tests/App/Dashboard/MonitorMetricsTabsTimeRangeZoom.test.tsx +740 -0
  162. package/Tests/App/Dashboard/MonitorOverviewChartsTimeRangeZoom.test.tsx +735 -0
  163. package/Tests/App/Dashboard/MonitorStepPreviewsTimeRangeZoom.test.tsx +835 -0
  164. package/Tests/App/Dashboard/NetworkDeviceTimeRangeZoom.test.tsx +1115 -0
  165. package/Tests/App/Dashboard/OnCallPreventionGuards.test.tsx +186 -17
  166. package/Tests/App/Dashboard/OnCallRulesDeleteGuard.test.tsx +155 -46
  167. package/Tests/App/Dashboard/PasskeySettings.test.tsx +87 -2
  168. package/Tests/App/Dashboard/ProjectAISettingsPages.test.tsx +884 -0
  169. package/Tests/App/Dashboard/ProxmoxNodeRemove.test.tsx +621 -0
  170. package/Tests/App/Dashboard/ProxmoxOverviewSlowLoads.test.tsx +584 -0
  171. package/Tests/App/Dashboard/ProxmoxPagesTimeRangeZoom.test.tsx +823 -0
  172. package/Tests/App/Dashboard/ProxmoxRateChartReload.test.tsx +1253 -0
  173. package/Tests/App/Dashboard/PublicDashboardBoardWideZoom.test.tsx +605 -0
  174. package/Tests/App/Dashboard/RealRowsLineChart.tsx +250 -0
  175. package/Tests/App/Dashboard/RechartsHostsPlotCursor.test.tsx +513 -0
  176. package/Tests/App/Dashboard/RowActionPlacementOverrides.test.tsx +865 -0
  177. package/Tests/App/Dashboard/RumOverviewTimeRangeZoom.test.tsx +877 -0
  178. package/Tests/App/Dashboard/RunnerKubernetesAgentForm.test.tsx +20 -4
  179. package/Tests/App/Dashboard/RunnerSupersededByAiAgentNote.test.tsx +296 -0
  180. package/Tests/App/Dashboard/SecurityEventConnectionsTable.test.tsx +146 -36
  181. package/Tests/App/Dashboard/ServiceDatabaseSlowLoads.test.tsx +1166 -0
  182. package/Tests/App/Dashboard/ServiceMapGraph.test.tsx +1243 -104
  183. package/Tests/App/Dashboard/ServiceOverviewTimeRangeZoom.test.tsx +792 -0
  184. package/Tests/App/Dashboard/SloBudgetBurnDownZoom.test.tsx +771 -0
  185. package/Tests/App/Dashboard/SloBudgetBurnDownZoomAffordances.test.tsx +380 -0
  186. package/Tests/App/Dashboard/SloEventMetricsBarChartZoom.test.tsx +369 -0
  187. package/Tests/App/Dashboard/SloHistoryChartsTimeRangeZoom.test.tsx +694 -0
  188. package/Tests/App/Dashboard/SloHistoryChartsZoomAffordances.test.tsx +497 -0
  189. package/Tests/App/Dashboard/SloMetricsTimeRangeZoom.test.tsx +541 -0
  190. package/Tests/App/Dashboard/SlowLoadHarness.ts +123 -0
  191. package/Tests/App/Dashboard/SnapshotExplorerPrimaryZoom.test.tsx +1194 -0
  192. package/Tests/App/Dashboard/SnapshotViewerPinnedWindow.test.tsx +620 -0
  193. package/Tests/App/Dashboard/TelemetrySnapshotPanelTimeRangeZoom.test.tsx +765 -0
  194. package/Tests/App/Dashboard/TelemetrySnapshotZoom.test.tsx +516 -0
  195. package/Tests/App/Dashboard/TelemetrySnapshotZoomAcrossTabs.test.tsx +827 -0
  196. package/Tests/App/Dashboard/TimeRangeZoomPageHarness.tsx +463 -0
  197. package/Tests/App/Dashboard/TraceChartEditorStatusSplit.test.tsx +543 -0
  198. package/Tests/App/Dashboard/TraceStatusPresentation.test.tsx +967 -0
  199. package/Tests/App/Dashboard/TraceTimelineMinimapZoom.test.tsx +315 -0
  200. package/Tests/App/Dashboard/TracesAnalyticsStatusSplit.test.tsx +778 -0
  201. package/Tests/App/Dashboard/TracesAnalyticsViewZoom.test.tsx +349 -0
  202. package/Tests/App/Dashboard/TracesExplorerTimeRangeZoom.test.tsx +551 -0
  203. package/Tests/App/Dashboard/TracesStatusChartAndFacet.test.tsx +687 -0
  204. package/Tests/App/Dashboard/TracesViewerStaleResponses.test.tsx +458 -0
  205. package/Tests/App/Dashboard/UptimeStripsExcludedFromZoom.test.tsx +406 -0
  206. package/Tests/App/Dashboard/VMwareOverviewSlowLoads.test.tsx +535 -0
  207. package/Tests/App/Dashboard/VMwarePagesTimeRangeZoom.test.tsx +606 -0
  208. package/Tests/App/Dashboard/ValueWidgetSparklineStaleHover.test.tsx +1292 -0
  209. package/Tests/App/Dashboard/ValueWidgetSparklineZoom.test.tsx +765 -0
  210. package/Tests/App/StatusPage/StatusPageResourceExplorer.test.tsx +98 -0
  211. package/Tests/Models/DatabaseModels/KubernetesAiAgentModel.test.ts +295 -0
  212. package/Tests/Models/DatabaseModels/TeamComplianceSettingModel.test.ts +347 -0
  213. package/Tests/Server/API/AIChatRouteAuthorization.test.ts +58 -0
  214. package/Tests/Server/API/AIGenerationProjectAIToggle.test.ts +1 -1
  215. package/Tests/Server/API/AIInvestigationAPI.test.ts +123 -45
  216. package/Tests/Server/API/AutoRemediationApproveClusterRound.test.ts +1329 -0
  217. package/Tests/Server/API/AutoRemediationApproveKubectlRecheck.test.ts +25 -2
  218. package/Tests/Server/API/KubernetesClusterAiAccessAPI.test.ts +2 -0
  219. package/Tests/Server/API/KubernetesClusterAiAccessAPIAgent.test.ts +903 -0
  220. package/Tests/Server/API/MicrosoftTeamsChatsRefreshRoute.test.ts +667 -0
  221. package/Tests/Server/API/MicrosoftTeamsManifest.test.ts +294 -6
  222. package/Tests/Server/API/ProxmoxResourceAPIRemoveNode.test.ts +1932 -0
  223. package/Tests/Server/Infrastructure/GlobalCache.test.ts +195 -0
  224. package/Tests/Server/Infrastructure/Postgres/AddKubernetesAiAgentAndAiDefaultsMigration.test.ts +623 -0
  225. package/Tests/Server/Infrastructure/Postgres/AddKubernetesClusterAiAccessMigration.test.ts +87 -10
  226. package/Tests/Server/Infrastructure/Postgres/AddTeamComplianceRuleScopeMigration.test.ts +622 -0
  227. package/Tests/Server/Middleware/TelemetryIngestBrowserKey.test.ts +61 -4
  228. package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerPinnedKey.test.ts +98 -2
  229. package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerRateLimit.test.ts +105 -2
  230. package/Tests/Server/Services/AIServiceBalanceBlocker.test.ts +282 -0
  231. package/Tests/Server/Services/AlertMonitorClearWritesNull.test.ts +409 -0
  232. package/Tests/Server/Services/AlertMonitorEditFeed.test.ts +474 -0
  233. package/Tests/Server/Services/AlertMonitorEditGuard.test.ts +610 -0
  234. package/Tests/Server/Services/AutoRemediationClusterRuleEngine.test.ts +2 -0
  235. package/Tests/Server/Services/AutoRemediationRuleCommandRunners.test.ts +2 -1
  236. package/Tests/Server/Services/IncidentAffectedMonitorsEdit.test.ts +1360 -0
  237. package/Tests/Server/Services/IncidentAlertSloLinkSurvivesEdit.test.ts +3 -1
  238. package/Tests/Server/Services/IncidentSeverityDeletePausesComplianceRules.test.ts +488 -0
  239. package/Tests/Server/Services/KubernetesAiAgentJobService.test.ts +329 -0
  240. package/Tests/Server/Services/KubernetesAiAgentServiceHelpers.test.ts +618 -0
  241. package/Tests/Server/Services/KubernetesAiAgentServiceLifecycle.test.ts +1444 -0
  242. package/Tests/Server/Services/KubernetesAiAgentServiceRegister.test.ts +1666 -0
  243. package/Tests/Server/Services/KubernetesClusterAiAccessDeletedRunnerRemedy.test.ts +140 -111
  244. package/Tests/Server/Services/KubernetesClusterAiAccessGapNextSteps.test.ts +267 -105
  245. package/Tests/Server/Services/KubernetesClusterAiAccessLegacySuperseded.test.ts +440 -0
  246. package/Tests/Server/Services/KubernetesClusterAiAccessService.test.ts +567 -411
  247. package/Tests/Server/Services/KubernetesClusterAiAccessTarget.test.ts +1168 -0
  248. package/Tests/Server/Services/KubernetesClusterAiSettingsPermission.test.ts +410 -12
  249. package/Tests/Server/Services/KubernetesClusterServiceAiAccessFeed.test.ts +55 -0
  250. package/Tests/Server/Services/ProjectServiceNewProjectAiDefaults.test.ts +288 -0
  251. package/Tests/Server/Services/ProxmoxResourcePostgres.test.ts +5633 -0
  252. package/Tests/Server/Services/ProxmoxResourceService.test.ts +6458 -5
  253. package/Tests/Server/Services/RunnerJobEnqueueKubectl.test.ts +48 -15
  254. package/Tests/Server/Services/RunnerJobEnqueueKubectlAiAgent.test.ts +620 -0
  255. package/Tests/Server/Services/RunnerJobKubectlWriteScope.test.ts +170 -3
  256. package/Tests/Server/Services/RunnerJobTimeoutReason.test.ts +72 -0
  257. package/Tests/Server/Services/RunnerServiceAgentName.test.ts +6 -4
  258. package/Tests/Server/Services/ScheduledMaintenanceAttachmentEdit.test.ts +2113 -0
  259. package/Tests/Server/Services/ScheduledMaintenanceMonitorRelease.test.ts +972 -0
  260. package/Tests/Server/Services/TeamComplianceSettingPostgres.test.ts +2237 -0
  261. package/Tests/Server/Services/TeamComplianceSettingService.test.ts +3988 -138
  262. package/Tests/Server/Utils/AI/ClusterAccessContext.test.ts +107 -1
  263. package/Tests/Server/Utils/AI/IncidentPostmortemRunner.test.ts +351 -0
  264. package/Tests/Server/Utils/AI/InvestigationClusterAccessWiring.test.ts +2 -0
  265. package/Tests/Server/Utils/AI/InvestigationEligibility.test.ts +310 -0
  266. package/Tests/Server/Utils/AI/KubectlInvestigationToolkit.test.ts +70 -0
  267. package/Tests/Server/Utils/AI/KubectlJobRunnerFinishedJob.test.ts +58 -0
  268. package/Tests/Server/Utils/AI/RemediationCommandToolsKubectl.test.ts +2 -0
  269. package/Tests/Server/Utils/AI/RemediationCommandToolsKubectlOutcome.test.ts +2 -0
  270. package/Tests/Server/Utils/AI/RemediationCommandToolsLiveCluster.test.ts +2 -0
  271. package/Tests/Server/Utils/AI/RemediationCommandToolsRunnerScope.test.ts +125 -1
  272. package/Tests/Server/Utils/AI/RemediationExecutionRunner.test.ts +252 -3
  273. package/Tests/Server/Utils/AI/RemediationExecutionRunnerClusterMode.test.ts +2 -0
  274. package/Tests/Server/Utils/AI/RemediationExecutionRunnerProjectGates.test.ts +240 -0
  275. package/Tests/Server/Utils/AI/RemediationKubectlCopyParity.test.ts +2 -0
  276. package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutor.test.ts +2 -0
  277. package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutorUnknownRun.test.ts +2 -0
  278. package/Tests/Server/Utils/AutoRemediation/CommandPlanVerification.test.ts +2 -0
  279. package/Tests/Server/Utils/Telemetry/HostAssetAttributesFromOtlp.test.ts +68 -0
  280. package/Tests/Server/Utils/Telemetry/InventoryMirrorPostgres.test.ts +370 -0
  281. package/Tests/Server/Utils/Telemetry/NetworkDeviceInventoryAttributes.test.ts +522 -0
  282. package/Tests/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.test.ts +155 -0
  283. package/Tests/Server/Utils/Telemetry/ProxmoxNativeNodeLiveness.test.ts +8631 -0
  284. package/Tests/Server/Utils/Telemetry/ProxmoxNativePush.test.ts +2852 -0
  285. package/Tests/Server/Utils/Telemetry/TelemetryEntity.test.ts +367 -1
  286. package/Tests/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.test.ts +45 -3
  287. package/Tests/Server/Utils/Workspace/MicrosoftTeamsChats.test.ts +25 -0
  288. package/Tests/Server/Utils/Workspace/MicrosoftTeamsGroupChatNames.test.ts +3119 -0
  289. package/Tests/Server/Utils/Workspace/MicrosoftTeamsGroupChatNamesPostgres.test.ts +1721 -0
  290. package/Tests/Types/Kubernetes/KubernetesAgentChartAiAccess.test.ts +581 -113
  291. package/Tests/Types/Kubernetes/KubernetesAiAgentAccessContract.test.ts +510 -0
  292. package/Tests/Types/Team/ComplianceRule.test.ts +1029 -0
  293. package/Tests/Types/Team/TeamComplianceStatus.test.ts +176 -0
  294. package/Tests/UI/Components/ActionButton/RowActions.test.tsx +641 -0
  295. package/Tests/UI/Components/ActionButton/RowActionsAccessibility.test.tsx +414 -0
  296. package/Tests/UI/Components/ActionButton/SplitActionButtons.test.ts +565 -0
  297. package/Tests/UI/Components/Charts/BarChartDragToSelect.test.tsx +386 -0
  298. package/Tests/UI/Components/Charts/ChartDoubleClickResetWithoutDblclick.test.tsx +1025 -0
  299. package/Tests/UI/Components/Charts/ChartGroupPageZoomHint.test.tsx +196 -0
  300. package/Tests/UI/Components/Charts/ChartPlaceholdersTakeDoubleClick.test.tsx +1861 -0
  301. package/Tests/UI/Components/Charts/ChartPlotClicksWhileResetArmed.test.tsx +382 -0
  302. package/Tests/UI/Components/Charts/ChartRangeSelection.test.tsx +704 -0
  303. package/Tests/UI/Components/Charts/ChartRangeSelectionDoubleClickReset.test.tsx +1481 -0
  304. package/Tests/UI/Components/Charts/ChartRangeSelectionRealRecharts.test.tsx +918 -0
  305. package/Tests/UI/Components/Charts/ChartRowBucketStart.test.ts +350 -0
  306. package/Tests/UI/Components/Charts/DoubleClickReset.test.tsx +996 -0
  307. package/Tests/UI/Components/Charts/HistogramDoubleClickResetRealRecharts.test.tsx +965 -0
  308. package/Tests/UI/Components/Charts/HistogramDriftThenRefetch.test.tsx +277 -0
  309. package/Tests/UI/Components/Charts/HistogramRangeSelectionDataChange.test.tsx +1757 -0
  310. package/Tests/UI/Components/Charts/HistogramRangeSelectionRealRecharts.test.tsx +560 -0
  311. package/Tests/UI/Components/Charts/TimeRangeZoom/ChartPageTimeRangeZoom.test.tsx +513 -0
  312. package/Tests/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomContext.test.tsx +845 -0
  313. package/Tests/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHint.test.tsx +119 -0
  314. package/Tests/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHintTailwind.test.tsx +274 -0
  315. package/Tests/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomUtil.test.ts +433 -0
  316. package/Tests/UI/Components/Charts/TimeRangeZoom/UseTimeRangeZoom.test.tsx +863 -0
  317. package/Tests/UI/Components/Charts/TimeRangeZoom/ZoomDocsPromises.test.tsx +1147 -0
  318. package/Tests/UI/Components/DisabledButtonTooltip.test.tsx +14 -3
  319. package/Tests/UI/Components/EntityDropdownEscape.test.tsx +454 -0
  320. package/Tests/UI/Components/EntityDropdownFocusLeave.test.tsx +420 -0
  321. package/Tests/UI/Components/Forms/FormFieldDropdownDisabled.test.tsx +233 -0
  322. package/Tests/UI/Components/Input.test.tsx +80 -1
  323. package/Tests/UI/Components/LogsAnalyticsViewZoom.test.tsx +947 -0
  324. package/Tests/UI/Components/LogsHistogramDragTooltip.test.tsx +17 -5
  325. package/Tests/UI/Components/LogsViewerAnalyticsZoom.test.tsx +501 -0
  326. package/Tests/UI/Components/LogsViewerHistogramZoom.test.tsx +1 -1
  327. package/Tests/UI/Components/ModelTable/BaseModelTableBulkDelete.test.tsx +6 -4
  328. package/Tests/UI/Components/ModelTable/BaseModelTablePermissionGating.test.tsx +60 -8
  329. package/Tests/UI/Components/ModelTable/BaseModelTableRowActions.test.tsx +476 -0
  330. package/Tests/UI/Components/ModelTable/ModelTableWrapContent.test.tsx +7 -5
  331. package/Tests/UI/Components/MoreMenuPortal.test.tsx +623 -0
  332. package/Tests/UI/Components/StatusPage/ResourceGridActions.test.tsx +538 -0
  333. package/Tests/UI/Components/StatusPage/ResourceGridSelection.test.tsx +14 -4
  334. package/Tests/UI/Components/TableCellWrapping.test.tsx +3 -3
  335. package/Tests/UI/Components/TableRowActions.test.tsx +472 -0
  336. package/Tests/UI/Components/TelemetryHistogramDragTooltip.test.tsx +1 -1
  337. package/Tests/UI/Components/TelemetryViewer/TelemetryViewerHistogramClickZoom.test.tsx +1 -1
  338. package/Tests/UI/Components/TelemetryViewer/TelemetryViewerZoomScope.test.tsx +470 -0
  339. package/Tests/UI/Components/TelemetryViewer/UseViewerTimeRangeZoom.test.tsx +571 -0
  340. package/Tests/UI/Components/TelemetryViewer/ViewerDoubleClickResetUnderDataChange.test.tsx +928 -0
  341. package/Tests/UI/Components/TelemetryViewer/ViewerFollowsEnclosingZoom.test.tsx +1569 -0
  342. package/Tests/UI/Components/Toggle.test.tsx +66 -0
  343. package/Tests/UI/MicrosoftTeams/MicrosoftTeamsChatsCardRefreshNames.test.tsx +1023 -0
  344. package/Tests/UI/Rum/ChunkLoader.test.ts +201 -0
  345. package/Tests/UI/Rum/FidelityNotices.test.ts +54 -0
  346. package/Tests/UI/Rum/ReplayCorrelationPanel.test.tsx +72 -0
  347. package/Tests/UI/Rum/ReplayFrameCapture.test.ts +1009 -9
  348. package/Tests/UI/Rum/ReplayRecordedAssets.test.ts +1069 -0
  349. package/Tests/UI/Rum/ReplayStage.test.tsx +913 -2
  350. package/Tests/UI/Rum/SessionReplayTable.test.tsx +443 -8
  351. package/Tests/UI/Rum/SessionReplayUsersTable.test.tsx +439 -9
  352. package/Tests/UI/Rum/UserFlowTablesRowActions.test.tsx +501 -0
  353. package/Tests/Utils/AiRemediation/KubectlPolicyChartRbacParity.test.ts +47 -19
  354. package/Tests/Utils/AiRemediation/KubectlWriteScopeCallerParity.test.ts +2 -0
  355. package/Tests/Utils/AiRemediation/KubernetesAiAgentPolicyCopyParity.test.ts +396 -0
  356. package/Tests/Utils/Dashboard/DashboardTimeRangeZoom.test.ts +104 -1
  357. package/Types/AI/AIRunType.ts +9 -4
  358. package/Types/AI/InvestigationNotStartedReason.ts +6 -0
  359. package/Types/AutoRemediation/AiRemediationCommandPlan.ts +14 -16
  360. package/Types/AutoRemediation/AiRemediationCommandPolicyVerdict.ts +28 -0
  361. package/Types/Dashboard/DashboardComponents/DashboardTraceChartComponent.ts +4 -2
  362. package/Types/Kubernetes/KubernetesClusterAiAccess.ts +263 -32
  363. package/Types/Kubernetes/KubernetesClusterAiAccessPermissions.ts +20 -16
  364. package/Types/Kubernetes/KubernetesClusterAiInsights.ts +81 -0
  365. package/Types/Monitor/ProxmoxAlertTemplates.ts +4 -4
  366. package/Types/Team/ComplianceNotificationChannel.ts +22 -0
  367. package/Types/Team/ComplianceRule.ts +434 -0
  368. package/Types/Team/ComplianceRuleType.ts +21 -0
  369. package/Types/Team/TeamComplianceStatus.ts +81 -0
  370. package/Types/Telemetry/TelemetryIngestSurface.ts +28 -0
  371. package/UI/Components/ActionButton/ActionButtonSchema.ts +21 -0
  372. package/UI/Components/ActionButton/RowActions.tsx +238 -0
  373. package/UI/Components/ActionButton/SplitActionButtons.ts +173 -0
  374. package/UI/Components/Charts/Area/AreaChart.tsx +32 -2
  375. package/UI/Components/Charts/Bar/BarChart.tsx +40 -3
  376. package/UI/Components/Charts/ChartGroup/ChartGroup.tsx +37 -11
  377. package/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.tsx +80 -243
  378. package/UI/Components/Charts/ChartLibrary/BarChart/BarChart.tsx +122 -31
  379. package/UI/Components/Charts/ChartLibrary/LineChart/LineChart.tsx +95 -244
  380. package/UI/Components/Charts/ChartLibrary/Utils/DoubleClick.ts +214 -0
  381. package/UI/Components/Charts/ChartLibrary/Utils/UseChartBucketsChange.ts +32 -0
  382. package/UI/Components/Charts/ChartLibrary/Utils/UseChartRangeSelection.ts +599 -0
  383. package/UI/Components/Charts/Line/LineChart.tsx +32 -2
  384. package/UI/Components/Charts/TimeRangeZoom/ResetTimeRangeZoomButton.tsx +70 -0
  385. package/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomContext.tsx +226 -0
  386. package/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHint.tsx +73 -0
  387. package/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomUtil.ts +163 -0
  388. package/UI/Components/Charts/TimeRangeZoom/UseTimeRangeZoom.ts +215 -0
  389. package/UI/Components/Charts/Utils/DataPoint.ts +20 -8
  390. package/UI/Components/Charts/Utils/XAxis.ts +75 -0
  391. package/UI/Components/Charts/Utils/useHistogramRangeSelection.ts +493 -59
  392. package/UI/Components/EntityDropdown/EntityDropdown.tsx +107 -11
  393. package/UI/Components/Forms/Fields/FormField.tsx +10 -0
  394. package/UI/Components/Input/Input.tsx +90 -57
  395. package/UI/Components/List/ListRow.tsx +8 -74
  396. package/UI/Components/LogsViewer/LogsViewer.tsx +40 -11
  397. package/UI/Components/LogsViewer/components/LogTimeRangePicker.tsx +22 -6
  398. package/UI/Components/LogsViewer/components/LogsAnalyticsView.tsx +209 -6
  399. package/UI/Components/LogsViewer/components/LogsHistogram.tsx +127 -84
  400. package/UI/Components/LogsViewer/components/LogsViewerToolbar.tsx +3 -0
  401. package/UI/Components/ModelTable/BaseModelTable.tsx +12 -1
  402. package/UI/Components/MoreMenu/MoreMenu.tsx +365 -30
  403. package/UI/Components/MoreMenu/MoreMenuItem.tsx +70 -17
  404. package/UI/Components/OrderedStatesList/Item.tsx +7 -72
  405. package/UI/Components/StatusPage/ResourceGrid.tsx +126 -77
  406. package/UI/Components/Table/TableBody.tsx +8 -2
  407. package/UI/Components/Table/TableRow.tsx +20 -140
  408. package/UI/Components/TelemetryViewer/TelemetryViewer.tsx +41 -10
  409. package/UI/Components/TelemetryViewer/components/TelemetryHistogram.tsx +47 -9
  410. package/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.tsx +25 -6
  411. package/UI/Components/TelemetryViewer/types.ts +2 -0
  412. package/UI/Components/TelemetryViewer/useViewerTimeRangeZoom.ts +448 -0
  413. package/UI/Components/Toggle/Toggle.tsx +26 -0
  414. package/UI/Components/Tooltip/Tooltip.tsx +8 -1
  415. package/UI/Styles/Theme.css +14 -2
  416. package/Utils/AiRemediation/CommandPolicy.ts +1 -1
  417. package/Utils/AiRemediation/KubectlPolicy.ts +1 -1
  418. package/Utils/Dashboard/DashboardTimeRangeZoom.ts +46 -2
  419. package/build/dist/Models/DatabaseModels/Index.js +2 -0
  420. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  421. package/build/dist/Models/DatabaseModels/KubernetesAiAgent.js +385 -0
  422. package/build/dist/Models/DatabaseModels/KubernetesAiAgent.js.map +1 -0
  423. package/build/dist/Models/DatabaseModels/KubernetesCluster.js +3 -3
  424. package/build/dist/Models/DatabaseModels/KubernetesCluster.js.map +1 -1
  425. package/build/dist/Models/DatabaseModels/Project.js +56 -5
  426. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  427. package/build/dist/Models/DatabaseModels/ProxmoxResource.js +51 -1
  428. package/build/dist/Models/DatabaseModels/ProxmoxResource.js.map +1 -1
  429. package/build/dist/Models/DatabaseModels/RunnerJob.js +74 -0
  430. package/build/dist/Models/DatabaseModels/RunnerJob.js.map +1 -1
  431. package/build/dist/Models/DatabaseModels/TeamComplianceSetting.js +134 -3
  432. package/build/dist/Models/DatabaseModels/TeamComplianceSetting.js.map +1 -1
  433. package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js.map +1 -1
  434. package/build/dist/Server/API/AIChatAPI.js +6 -1
  435. package/build/dist/Server/API/AIChatAPI.js.map +1 -1
  436. package/build/dist/Server/API/AIInvestigationAPI.js +17 -10
  437. package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
  438. package/build/dist/Server/API/AutoRemediationAPI.js +144 -24
  439. package/build/dist/Server/API/AutoRemediationAPI.js.map +1 -1
  440. package/build/dist/Server/API/KubernetesClusterAiAccessAPI.js +436 -22
  441. package/build/dist/Server/API/KubernetesClusterAiAccessAPI.js.map +1 -1
  442. package/build/dist/Server/API/MicrosoftTeamsAPI.js +69 -13
  443. package/build/dist/Server/API/MicrosoftTeamsAPI.js.map +1 -1
  444. package/build/dist/Server/API/ProxmoxResourceAPI.js +187 -14
  445. package/build/dist/Server/API/ProxmoxResourceAPI.js.map +1 -1
  446. package/build/dist/Server/Infrastructure/GlobalCache.js +27 -0
  447. package/build/dist/Server/Infrastructure/GlobalCache.js.map +1 -1
  448. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796000000000-AddTeamComplianceRuleScope.js +50 -0
  449. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796000000000-AddTeamComplianceRuleScope.js.map +1 -0
  450. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796100000000-AddKubernetesAiAgentAndAiDefaults.js +84 -0
  451. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796100000000-AddKubernetesAiAgentAndAiDefaults.js.map +1 -0
  452. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796200000000-AddProxmoxResourceNativePushColumns.js +31 -0
  453. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796200000000-AddProxmoxResourceNativePushColumns.js.map +1 -0
  454. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +6 -0
  455. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  456. package/build/dist/Server/Middleware/TelemetryIngest.js +34 -19
  457. package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
  458. package/build/dist/Server/Services/AIService.js +59 -1
  459. package/build/dist/Server/Services/AIService.js.map +1 -1
  460. package/build/dist/Server/Services/AlertService.js +248 -13
  461. package/build/dist/Server/Services/AlertService.js.map +1 -1
  462. package/build/dist/Server/Services/AlertSeverityService.js +51 -15
  463. package/build/dist/Server/Services/AlertSeverityService.js.map +1 -1
  464. package/build/dist/Server/Services/AutoRemediationRuleService.js +1 -1
  465. package/build/dist/Server/Services/AutoRemediationRuleService.js.map +1 -1
  466. package/build/dist/Server/Services/IncidentService.js +199 -72
  467. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  468. package/build/dist/Server/Services/IncidentSeverityService.js +51 -15
  469. package/build/dist/Server/Services/IncidentSeverityService.js.map +1 -1
  470. package/build/dist/Server/Services/KubernetesAiAgentJobService.js +158 -0
  471. package/build/dist/Server/Services/KubernetesAiAgentJobService.js.map +1 -0
  472. package/build/dist/Server/Services/KubernetesAiAgentService.js +1145 -0
  473. package/build/dist/Server/Services/KubernetesAiAgentService.js.map +1 -0
  474. package/build/dist/Server/Services/KubernetesClusterAiAccessService.js +842 -371
  475. package/build/dist/Server/Services/KubernetesClusterAiAccessService.js.map +1 -1
  476. package/build/dist/Server/Services/KubernetesClusterService.js +86 -17
  477. package/build/dist/Server/Services/KubernetesClusterService.js.map +1 -1
  478. package/build/dist/Server/Services/ProjectService.js +22 -0
  479. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  480. package/build/dist/Server/Services/ProxmoxResourceService.js +258 -3
  481. package/build/dist/Server/Services/ProxmoxResourceService.js.map +1 -1
  482. package/build/dist/Server/Services/RunnerJobService.js +178 -92
  483. package/build/dist/Server/Services/RunnerJobService.js.map +1 -1
  484. package/build/dist/Server/Services/RunnerService.js +1 -1
  485. package/build/dist/Server/Services/RunnerService.js.map +1 -1
  486. package/build/dist/Server/Services/ScheduledMaintenanceService.js +535 -3
  487. package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
  488. package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js +316 -46
  489. package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js.map +1 -1
  490. package/build/dist/Server/Services/TeamComplianceSettingService.js +833 -7
  491. package/build/dist/Server/Services/TeamComplianceSettingService.js.map +1 -1
  492. package/build/dist/Server/Utils/AI/ClusterAccess/ClusterAccessContext.js +52 -9
  493. package/build/dist/Server/Utils/AI/ClusterAccess/ClusterAccessContext.js.map +1 -1
  494. package/build/dist/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.js +13 -9
  495. package/build/dist/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.js.map +1 -1
  496. package/build/dist/Server/Utils/AI/ClusterAccess/KubectlJobRunner.js +7 -3
  497. package/build/dist/Server/Utils/AI/ClusterAccess/KubectlJobRunner.js.map +1 -1
  498. package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js +29 -15
  499. package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js.map +1 -1
  500. package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js +56 -20
  501. package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js.map +1 -1
  502. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +39 -5
  503. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
  504. package/build/dist/Server/Utils/AI/SRE/IncidentPostmortemRunner.js +30 -3
  505. package/build/dist/Server/Utils/AI/SRE/IncidentPostmortemRunner.js.map +1 -1
  506. package/build/dist/Server/Utils/AI/SRE/InvestigationEligibility.js +13 -2
  507. package/build/dist/Server/Utils/AI/SRE/InvestigationEligibility.js.map +1 -1
  508. package/build/dist/Server/Utils/AI/SRE/InvestigationGrader.js +1 -1
  509. package/build/dist/Server/Utils/AutoRemediation/CommandPlanExecutor.js +4 -2
  510. package/build/dist/Server/Utils/AutoRemediation/CommandPlanExecutor.js.map +1 -1
  511. package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js +111 -6
  512. package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js.map +1 -1
  513. package/build/dist/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.js +40 -4
  514. package/build/dist/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.js.map +1 -1
  515. package/build/dist/Server/Utils/Telemetry/ProxmoxNativeNodeLiveness.js +296 -0
  516. package/build/dist/Server/Utils/Telemetry/ProxmoxNativeNodeLiveness.js.map +1 -0
  517. package/build/dist/Server/Utils/Telemetry/ProxmoxNativePush.js +699 -0
  518. package/build/dist/Server/Utils/Telemetry/ProxmoxNativePush.js.map +1 -0
  519. package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js +77 -19
  520. package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js.map +1 -1
  521. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +505 -42
  522. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
  523. package/build/dist/Types/AI/AIRunType.js +9 -4
  524. package/build/dist/Types/AI/AIRunType.js.map +1 -1
  525. package/build/dist/Types/AutoRemediation/AiRemediationCommandPlan.js +10 -16
  526. package/build/dist/Types/AutoRemediation/AiRemediationCommandPlan.js.map +1 -1
  527. package/build/dist/Types/AutoRemediation/AiRemediationCommandPolicyVerdict.js +28 -0
  528. package/build/dist/Types/AutoRemediation/AiRemediationCommandPolicyVerdict.js.map +1 -0
  529. package/build/dist/Types/Kubernetes/KubernetesClusterAiAccess.js +72 -16
  530. package/build/dist/Types/Kubernetes/KubernetesClusterAiAccess.js.map +1 -1
  531. package/build/dist/Types/Kubernetes/KubernetesClusterAiAccessPermissions.js +20 -16
  532. package/build/dist/Types/Kubernetes/KubernetesClusterAiAccessPermissions.js.map +1 -1
  533. package/build/dist/Types/Kubernetes/KubernetesClusterAiInsights.js +17 -0
  534. package/build/dist/Types/Kubernetes/KubernetesClusterAiInsights.js.map +1 -0
  535. package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js +4 -4
  536. package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js.map +1 -1
  537. package/build/dist/Types/Team/ComplianceNotificationChannel.js +23 -0
  538. package/build/dist/Types/Team/ComplianceNotificationChannel.js.map +1 -0
  539. package/build/dist/Types/Team/ComplianceRule.js +304 -0
  540. package/build/dist/Types/Team/ComplianceRule.js.map +1 -0
  541. package/build/dist/Types/Team/ComplianceRuleType.js +21 -0
  542. package/build/dist/Types/Team/ComplianceRuleType.js.map +1 -1
  543. package/build/dist/Types/Team/TeamComplianceStatus.js +2 -0
  544. package/build/dist/Types/Team/TeamComplianceStatus.js.map +1 -0
  545. package/build/dist/Types/Telemetry/TelemetryIngestSurface.js +25 -0
  546. package/build/dist/Types/Telemetry/TelemetryIngestSurface.js.map +1 -1
  547. package/build/dist/UI/Components/ActionButton/ActionButtonSchema.js +20 -1
  548. package/build/dist/UI/Components/ActionButton/ActionButtonSchema.js.map +1 -1
  549. package/build/dist/UI/Components/ActionButton/RowActions.js +113 -0
  550. package/build/dist/UI/Components/ActionButton/RowActions.js.map +1 -0
  551. package/build/dist/UI/Components/ActionButton/SplitActionButtons.js +71 -0
  552. package/build/dist/UI/Components/ActionButton/SplitActionButtons.js.map +1 -0
  553. package/build/dist/UI/Components/Charts/Area/AreaChart.js +16 -1
  554. package/build/dist/UI/Components/Charts/Area/AreaChart.js.map +1 -1
  555. package/build/dist/UI/Components/Charts/Bar/BarChart.js +16 -1
  556. package/build/dist/UI/Components/Charts/Bar/BarChart.js.map +1 -1
  557. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js +27 -5
  558. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js.map +1 -1
  559. package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js +61 -194
  560. package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js.map +1 -1
  561. package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js +84 -26
  562. package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js.map +1 -1
  563. package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js +75 -196
  564. package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js.map +1 -1
  565. package/build/dist/UI/Components/Charts/ChartLibrary/Utils/DoubleClick.js +133 -0
  566. package/build/dist/UI/Components/Charts/ChartLibrary/Utils/DoubleClick.js.map +1 -1
  567. package/build/dist/UI/Components/Charts/ChartLibrary/Utils/UseChartBucketsChange.js +26 -0
  568. package/build/dist/UI/Components/Charts/ChartLibrary/Utils/UseChartBucketsChange.js.map +1 -0
  569. package/build/dist/UI/Components/Charts/ChartLibrary/Utils/UseChartRangeSelection.js +371 -0
  570. package/build/dist/UI/Components/Charts/ChartLibrary/Utils/UseChartRangeSelection.js.map +1 -0
  571. package/build/dist/UI/Components/Charts/Line/LineChart.js +16 -1
  572. package/build/dist/UI/Components/Charts/Line/LineChart.js.map +1 -1
  573. package/build/dist/UI/Components/Charts/TimeRangeZoom/ResetTimeRangeZoomButton.js +35 -0
  574. package/build/dist/UI/Components/Charts/TimeRangeZoom/ResetTimeRangeZoomButton.js.map +1 -0
  575. package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomContext.js +107 -0
  576. package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomContext.js.map +1 -0
  577. package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHint.js +41 -0
  578. package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHint.js.map +1 -0
  579. package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomUtil.js +117 -0
  580. package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomUtil.js.map +1 -0
  581. package/build/dist/UI/Components/Charts/TimeRangeZoom/UseTimeRangeZoom.js +121 -0
  582. package/build/dist/UI/Components/Charts/TimeRangeZoom/UseTimeRangeZoom.js.map +1 -0
  583. package/build/dist/UI/Components/Charts/Utils/DataPoint.js +15 -7
  584. package/build/dist/UI/Components/Charts/Utils/DataPoint.js.map +1 -1
  585. package/build/dist/UI/Components/Charts/Utils/XAxis.js +70 -0
  586. package/build/dist/UI/Components/Charts/Utils/XAxis.js.map +1 -1
  587. package/build/dist/UI/Components/Charts/Utils/useHistogramRangeSelection.js +305 -38
  588. package/build/dist/UI/Components/Charts/Utils/useHistogramRangeSelection.js.map +1 -1
  589. package/build/dist/UI/Components/EntityDropdown/EntityDropdown.js +89 -14
  590. package/build/dist/UI/Components/EntityDropdown/EntityDropdown.js.map +1 -1
  591. package/build/dist/UI/Components/Forms/Fields/FormField.js +11 -2
  592. package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
  593. package/build/dist/UI/Components/Input/Input.js +69 -54
  594. package/build/dist/UI/Components/Input/Input.js.map +1 -1
  595. package/build/dist/UI/Components/List/ListRow.js +4 -39
  596. package/build/dist/UI/Components/List/ListRow.js.map +1 -1
  597. package/build/dist/UI/Components/LogsViewer/LogsViewer.js +31 -8
  598. package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
  599. package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js +10 -1
  600. package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js.map +1 -1
  601. package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js +139 -21
  602. package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js.map +1 -1
  603. package/build/dist/UI/Components/LogsViewer/components/LogsHistogram.js +30 -8
  604. package/build/dist/UI/Components/LogsViewer/components/LogsHistogram.js.map +1 -1
  605. package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js +1 -1
  606. package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js.map +1 -1
  607. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +10 -0
  608. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  609. package/build/dist/UI/Components/MoreMenu/MoreMenu.js +253 -14
  610. package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
  611. package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js +43 -13
  612. package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js.map +1 -1
  613. package/build/dist/UI/Components/OrderedStatesList/Item.js +2 -38
  614. package/build/dist/UI/Components/OrderedStatesList/Item.js.map +1 -1
  615. package/build/dist/UI/Components/StatusPage/ResourceGrid.js +53 -15
  616. package/build/dist/UI/Components/StatusPage/ResourceGrid.js.map +1 -1
  617. package/build/dist/UI/Components/Table/TableBody.js +6 -2
  618. package/build/dist/UI/Components/Table/TableBody.js.map +1 -1
  619. package/build/dist/UI/Components/Table/TableRow.js +12 -75
  620. package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
  621. package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js +32 -7
  622. package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js.map +1 -1
  623. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js +27 -9
  624. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js.map +1 -1
  625. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js +11 -1
  626. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js.map +1 -1
  627. package/build/dist/UI/Components/TelemetryViewer/useViewerTimeRangeZoom.js +272 -0
  628. package/build/dist/UI/Components/TelemetryViewer/useViewerTimeRangeZoom.js.map +1 -0
  629. package/build/dist/UI/Components/Toggle/Toggle.js +14 -1
  630. package/build/dist/UI/Components/Toggle/Toggle.js.map +1 -1
  631. package/build/dist/UI/Components/Tooltip/Tooltip.js +1 -1
  632. package/build/dist/UI/Components/Tooltip/Tooltip.js.map +1 -1
  633. package/build/dist/Utils/AiRemediation/CommandPolicy.js +1 -1
  634. package/build/dist/Utils/AiRemediation/CommandPolicy.js.map +1 -1
  635. package/build/dist/Utils/AiRemediation/KubectlPolicy.js +1 -1
  636. package/build/dist/Utils/AiRemediation/KubectlPolicy.js.map +1 -1
  637. package/build/dist/Utils/Dashboard/DashboardTimeRangeZoom.js +27 -1
  638. package/build/dist/Utils/Dashboard/DashboardTimeRangeZoom.js.map +1 -1
  639. package/package.json +1 -1
@@ -18,6 +18,7 @@ import Project from "../../../../Models/DatabaseModels/Project";
18
18
  import AIRun from "../../../../Models/DatabaseModels/AIRun";
19
19
  import LlmProvider from "../../../../Models/DatabaseModels/LlmProvider";
20
20
  import ObjectID from "../../../../Types/ObjectID";
21
+ import logger from "../../../../Server/Utils/Logger";
21
22
  import InvestigationNotStartedReason, {
22
23
  InvestigationNotStartedCode,
23
24
  } from "../../../../Types/AI/InvestigationNotStartedReason";
@@ -33,6 +34,7 @@ const codes: Array<InvestigationNotStartedCode> = [
33
34
  "ai_disabled",
34
35
  "automatic_investigation_disabled",
35
36
  "provider_missing",
37
+ "insufficient_ai_balance",
36
38
  "severity_below_threshold",
37
39
  "monitor_cooldown",
38
40
  "daily_budget_exhausted",
@@ -45,9 +47,29 @@ const configurationCodes: Array<InvestigationNotStartedCode> = [
45
47
  "ai_disabled",
46
48
  "automatic_investigation_disabled",
47
49
  "provider_missing",
50
+ "insufficient_ai_balance",
48
51
  "severity_below_threshold",
49
52
  ];
50
53
 
54
+ const BALANCE_BLOCKER: string =
55
+ "This project is out of AI credits. Add credits under Project Settings → AI Credits, or turn on auto-recharge.";
56
+
57
+ /*
58
+ * AIService.getAiBalanceBlocker — the one AI balance predicate shared with
59
+ * the Kubernetes cluster's ai_balance_insufficient gap. null = no blocker.
60
+ */
61
+ function mockBalanceBlocker(
62
+ outcome: string | null | Error = null,
63
+ ): jest.SpyInstance {
64
+ const spy: jest.SpyInstance = jest.spyOn(AIService, "getAiBalanceBlocker");
65
+ if (outcome instanceof Error) {
66
+ spy.mockRejectedValue(outcome);
67
+ } else {
68
+ spy.mockResolvedValue(outcome);
69
+ }
70
+ return spy;
71
+ }
72
+
51
73
  afterEach(() => {
52
74
  jest.restoreAllMocks();
53
75
  });
@@ -143,6 +165,7 @@ describe("investigation enablement reasons", () => {
143
165
  jest
144
166
  .spyOn(LlmProviderService, "getLLMProviderForProject")
145
167
  .mockResolvedValue(new LlmProvider());
168
+ mockBalanceBlocker(null);
146
169
  expect(
147
170
  await AIInvestigationEngine.getDisabledReason(projectId, "Incident"),
148
171
  ).toBeNull();
@@ -158,6 +181,256 @@ describe("investigation enablement reasons", () => {
158
181
  });
159
182
  });
160
183
 
184
+ /*
185
+ * On OneUptime's own billed provider, a project with no AI credits (and
186
+ * auto-recharge off) has every model call refused with "Insufficient AI
187
+ * balance". Starting an investigation then only produces a failed run that
188
+ * is retried once, with nothing on the incident saying why — so the gate
189
+ * refuses up front with a reason people can act on. It is the same
190
+ * predicate as the cluster's ai_balance_insufficient gap, and it fails OPEN:
191
+ * the model call still enforces the balance.
192
+ */
193
+ describe("the AI balance gate (insufficient_ai_balance)", () => {
194
+ function mockReadyProject(): jest.SpyInstance {
195
+ jest
196
+ .spyOn(ProjectService, "findOneById")
197
+ .mockResolvedValue(enabledProject());
198
+ return jest
199
+ .spyOn(LlmProviderService, "getLLMProviderForProject")
200
+ .mockResolvedValue(new LlmProvider());
201
+ }
202
+
203
+ it.each(["Alert", "Incident"] as const)(
204
+ "refuses a %s investigation when the project is out of AI credits",
205
+ async (kind: "Alert" | "Incident") => {
206
+ mockReadyProject();
207
+ mockBalanceBlocker(BALANCE_BLOCKER);
208
+
209
+ expect(
210
+ await AIInvestigationEngine.getDisabledReason(projectId, kind),
211
+ ).toBe("insufficient_ai_balance");
212
+ expect(
213
+ await AIInvestigationEngine.isEnabledForProject(projectId, kind),
214
+ ).toBe(false);
215
+ },
216
+ );
217
+
218
+ it("asks the shared predicate about this project, handing it the provider it already resolved", async () => {
219
+ const llmProvider: LlmProvider = new LlmProvider();
220
+ jest
221
+ .spyOn(ProjectService, "findOneById")
222
+ .mockResolvedValue(enabledProject());
223
+ const providerLookup: jest.SpyInstance = jest
224
+ .spyOn(LlmProviderService, "getLLMProviderForProject")
225
+ .mockResolvedValue(llmProvider);
226
+ const blocker: jest.SpyInstance = mockBalanceBlocker(null);
227
+
228
+ await AIInvestigationEngine.getDisabledReason(projectId, "Incident");
229
+
230
+ expect(blocker).toHaveBeenCalledTimes(1);
231
+ expect(blocker).toHaveBeenCalledWith({ projectId, llmProvider });
232
+ // One provider lookup for the whole gate, not one per check.
233
+ expect(providerLookup).toHaveBeenCalledTimes(1);
234
+ });
235
+
236
+ it("lets the investigation start when there is no blocker", async () => {
237
+ mockReadyProject();
238
+ mockBalanceBlocker(null);
239
+
240
+ expect(
241
+ await AIInvestigationEngine.getDisabledReason(projectId, "Alert"),
242
+ ).toBeNull();
243
+ });
244
+
245
+ it("an empty blocker string is not a blocker", async () => {
246
+ mockReadyProject();
247
+ mockBalanceBlocker("");
248
+
249
+ expect(
250
+ await AIInvestigationEngine.getDisabledReason(projectId, "Alert"),
251
+ ).toBeNull();
252
+ });
253
+
254
+ it("fails OPEN when the balance cannot be read — logged, never blocking", async () => {
255
+ mockReadyProject();
256
+ mockBalanceBlocker(new Error("billing store unavailable"));
257
+ const errorLog: jest.SpyInstance = jest
258
+ .spyOn(logger, "error")
259
+ .mockImplementation((): void => {
260
+ return undefined;
261
+ });
262
+
263
+ expect(
264
+ await AIInvestigationEngine.getDisabledReason(projectId, "Incident"),
265
+ ).toBeNull();
266
+ expect(errorLog).toHaveBeenCalledWith(
267
+ expect.stringContaining("could not check the AI balance"),
268
+ );
269
+ });
270
+
271
+ it.each([
272
+ ["AI is off", { enableAi: false }, "ai_disabled"],
273
+ [
274
+ "automatic investigation is off",
275
+ { enableAutomaticIncidentInvestigation: false },
276
+ "automatic_investigation_disabled",
277
+ ],
278
+ ] as const)(
279
+ "is not consulted when %s — the switch is the reason, not the balance",
280
+ async (
281
+ _label: string,
282
+ overrides: Partial<Project>,
283
+ expected: InvestigationNotStartedCode,
284
+ ) => {
285
+ jest
286
+ .spyOn(ProjectService, "findOneById")
287
+ .mockResolvedValue(Object.assign(enabledProject(), overrides));
288
+ const blocker: jest.SpyInstance = mockBalanceBlocker(BALANCE_BLOCKER);
289
+
290
+ expect(
291
+ await AIInvestigationEngine.getDisabledReason(projectId, "Incident"),
292
+ ).toBe(expected);
293
+ expect(blocker).not.toHaveBeenCalled();
294
+ },
295
+ );
296
+
297
+ it("is not consulted without a provider — a missing provider is the reason", async () => {
298
+ jest
299
+ .spyOn(ProjectService, "findOneById")
300
+ .mockResolvedValue(enabledProject());
301
+ jest
302
+ .spyOn(LlmProviderService, "getLLMProviderForProject")
303
+ .mockResolvedValue(null);
304
+ const blocker: jest.SpyInstance = mockBalanceBlocker(BALANCE_BLOCKER);
305
+
306
+ expect(
307
+ await AIInvestigationEngine.getDisabledReason(projectId, "Alert"),
308
+ ).toBe("provider_missing");
309
+ expect(blocker).not.toHaveBeenCalled();
310
+ });
311
+
312
+ describe("getProviderOrBalanceReason — the half of the gate that is not a switch", () => {
313
+ it("reports a missing provider first", async () => {
314
+ jest
315
+ .spyOn(LlmProviderService, "getLLMProviderForProject")
316
+ .mockResolvedValue(null);
317
+ const blocker: jest.SpyInstance = mockBalanceBlocker(BALANCE_BLOCKER);
318
+
319
+ expect(
320
+ await AIInvestigationEngine.getProviderOrBalanceReason(projectId),
321
+ ).toBe("provider_missing");
322
+ expect(blocker).not.toHaveBeenCalled();
323
+ });
324
+
325
+ it("reports an empty balance", async () => {
326
+ jest
327
+ .spyOn(LlmProviderService, "getLLMProviderForProject")
328
+ .mockResolvedValue(new LlmProvider());
329
+ mockBalanceBlocker(BALANCE_BLOCKER);
330
+
331
+ expect(
332
+ await AIInvestigationEngine.getProviderOrBalanceReason(projectId),
333
+ ).toBe("insufficient_ai_balance");
334
+ });
335
+
336
+ it("reports nothing when a model can be called and paid for", async () => {
337
+ jest
338
+ .spyOn(LlmProviderService, "getLLMProviderForProject")
339
+ .mockResolvedValue(new LlmProvider());
340
+ mockBalanceBlocker(null);
341
+
342
+ expect(
343
+ await AIInvestigationEngine.getProviderOrBalanceReason(projectId),
344
+ ).toBeNull();
345
+ });
346
+
347
+ it("never reads the project's switches — callers own those", async () => {
348
+ jest
349
+ .spyOn(LlmProviderService, "getLLMProviderForProject")
350
+ .mockResolvedValue(new LlmProvider());
351
+ mockBalanceBlocker(null);
352
+ const projectRead: jest.SpyInstance = jest.spyOn(
353
+ ProjectService,
354
+ "findOneById",
355
+ );
356
+
357
+ await AIInvestigationEngine.getProviderOrBalanceReason(projectId);
358
+
359
+ expect(projectRead).not.toHaveBeenCalled();
360
+ });
361
+ });
362
+
363
+ it.each(subjects)(
364
+ "explains the recorded reason in plain words for %o",
365
+ (subject: InvestigationSubject) => {
366
+ const reason: InvestigationNotStartedReason =
367
+ InvestigationEligibility.reason("insufficient_ai_balance", subject);
368
+
369
+ expect(reason.code).toBe("insufficient_ai_balance");
370
+ expect(reason.title).toBe(
371
+ "The project was out of AI credits at creation",
372
+ );
373
+ expect(reason.description).toBe(
374
+ `This project had no AI credits left when this ${
375
+ subject.alertId ? "alert" : "incident"
376
+ } was created, so its automatic investigation did not start.`,
377
+ );
378
+ expect(reason.nextStep).toContain("Project Settings → AI Credits");
379
+ expect(reason.nextStep).toContain("auto-recharge");
380
+ },
381
+ );
382
+
383
+ it.each(subjects)(
384
+ "explains the current condition, pointing at AI Credits, for %o",
385
+ async (subject: InvestigationSubject) => {
386
+ mockMissingDecision();
387
+ jest
388
+ .spyOn(AIInvestigationEngine, "getDisabledReason")
389
+ .mockResolvedValue("insufficient_ai_balance");
390
+
391
+ const reason: InvestigationNotStartedReason =
392
+ await InvestigationEligibility.getNotStartedReason(subject);
393
+
394
+ expect(reason.code).toBe("insufficient_ai_balance");
395
+ expect(reason.source).toBe("current_configuration");
396
+ expect(reason.title).toBe("The project is currently out of AI credits");
397
+ expect(reason.nextStep).toContain(
398
+ "Add AI credits under Project Settings → AI Credits",
399
+ );
400
+ expect(reason.nextStep).toContain("auto-recharge");
401
+ // The subject gate and the daily budget are never reached.
402
+ expect(
403
+ AIAlertInvestigationRunner.shouldInvestigateAlert,
404
+ ).not.toHaveBeenCalled();
405
+ expect(
406
+ AIIncidentInvestigationRunner.shouldInvestigateIncident,
407
+ ).not.toHaveBeenCalled();
408
+ expect(AIService.getAutonomousDailyBudgetStatus).not.toHaveBeenCalled();
409
+ },
410
+ );
411
+ });
412
+
413
+ describe("the AI switches page is named where AI is off", () => {
414
+ it.each(subjects)(
415
+ "recorded and current ai_disabled next steps name Project Settings → AI Features for %o",
416
+ async (subject: InvestigationSubject) => {
417
+ const recorded: InvestigationNotStartedReason =
418
+ InvestigationEligibility.reason("ai_disabled", subject);
419
+ expect(recorded.nextStep).toContain("Project Settings → AI Features");
420
+ expect(recorded.nextStep).not.toContain("AI Credits");
421
+
422
+ mockMissingDecision();
423
+ jest
424
+ .spyOn(AIInvestigationEngine, "getDisabledReason")
425
+ .mockResolvedValue("ai_disabled");
426
+ const current: InvestigationNotStartedReason =
427
+ await InvestigationEligibility.getNotStartedReason(subject);
428
+ expect(current.nextStep).toContain("Project Settings → AI Features");
429
+ expect(current.nextStep).not.toContain("AI Credits");
430
+ },
431
+ );
432
+ });
433
+
161
434
  describe.each(subjects)(
162
435
  "recorded explanation time context for %o",
163
436
  (subject: InvestigationSubject) => {
@@ -296,6 +569,7 @@ describe.each(subjects)(
296
569
  "ai_disabled",
297
570
  "automatic_investigation_disabled",
298
571
  "provider_missing",
572
+ "insufficient_ai_balance",
299
573
  ] as const)(
300
574
  "labels %s as current conditions, never historical proof",
301
575
  async (code: InvestigationNotStartedCode) => {
@@ -502,6 +776,7 @@ describe.each(subjects)(
502
776
  "ai_disabled",
503
777
  "automatic_investigation_disabled",
504
778
  "provider_missing",
779
+ "insufficient_ai_balance",
505
780
  ] as const)(
506
781
  "records disabled admission %s",
507
782
  async (code: InvestigationNotStartedCode) => {
@@ -593,6 +868,41 @@ describe.each(subjects)(
593
868
  ).not.toHaveBeenCalled();
594
869
  expect(AIInvestigationQueue.processRun).toHaveBeenCalled();
595
870
  });
871
+ it("records an empty AI balance through the real engine gate and never creates a run", async () => {
872
+ (
873
+ AIInvestigationEngine.getDisabledReason as unknown as jest.SpyInstance
874
+ ).mockRestore();
875
+ jest
876
+ .spyOn(ProjectService, "findOneById")
877
+ .mockResolvedValue(enabledProject());
878
+ jest
879
+ .spyOn(LlmProviderService, "getLLMProviderForProject")
880
+ .mockResolvedValue(new LlmProvider());
881
+ mockBalanceBlocker(BALANCE_BLOCKER);
882
+
883
+ expect(await trigger(subject)).toBe(false);
884
+ expectRecorded("insufficient_ai_balance");
885
+ expect(AIRunService.create).not.toHaveBeenCalled();
886
+ expect(AIInvestigationQueue.processRun).not.toHaveBeenCalled();
887
+ });
888
+ it("still starts the investigation through the real engine gate when the balance cannot be read", async () => {
889
+ (
890
+ AIInvestigationEngine.getDisabledReason as unknown as jest.SpyInstance
891
+ ).mockRestore();
892
+ jest
893
+ .spyOn(ProjectService, "findOneById")
894
+ .mockResolvedValue(enabledProject());
895
+ jest
896
+ .spyOn(LlmProviderService, "getLLMProviderForProject")
897
+ .mockResolvedValue(new LlmProvider());
898
+ mockBalanceBlocker(new Error("billing store unavailable"));
899
+ jest.spyOn(logger, "error").mockImplementation((): void => {
900
+ return undefined;
901
+ });
902
+
903
+ expect(await trigger(subject)).toBe(true);
904
+ expect(AIRunService.create).toHaveBeenCalled();
905
+ });
596
906
  it("records unexpected eligibility failures without stranding remediation", async () => {
597
907
  jest
598
908
  .spyOn(AIInvestigationEngine, "getDisabledReason")
@@ -91,6 +91,8 @@ function readyCluster(
91
91
  posture: { inCluster: true, allowWrites: false },
92
92
  },
93
93
  accessMethod: "in_cluster",
94
+ aiAgent: null,
95
+ automaticInvestigation: { incidents: false, alerts: false },
94
96
  kubectlAllowlist: [],
95
97
  isInvestigationEnabled: true,
96
98
  isInvestigationReady: true,
@@ -1248,6 +1250,74 @@ describe("KubectlInvestigationToolkit run_kubectl when kubectl never ran", () =>
1248
1250
  expect(toolkit.getCommandsRun()).toBe(1);
1249
1251
  });
1250
1252
 
1253
+ /*
1254
+ * The same unclaimed command on a cluster reached through its Kubernetes
1255
+ * AI agent: the text names the agent, never "its Runner".
1256
+ */
1257
+ it("names the Kubernetes AI agent, not a Runner, when the agent left the command unclaimed", async () => {
1258
+ const toolkit: KubectlInvestigationToolkit =
1259
+ new KubectlInvestigationToolkit({
1260
+ projectId: PROJECT_ID,
1261
+ aiRunId: RUN_ID,
1262
+ clusters: [
1263
+ readyCluster({
1264
+ runner: {
1265
+ id: RUNNER_ID.toString(),
1266
+ name: "Kubernetes AI agent",
1267
+ kind: "ai_agent",
1268
+ isOnline: true,
1269
+ canRunAiCommands: true,
1270
+ posture: { inCluster: true, allowWrites: false },
1271
+ },
1272
+ }),
1273
+ ],
1274
+ });
1275
+
1276
+ const before: ToolCallOutcome = await getTool(
1277
+ toolkit,
1278
+ LIST_CLUSTER_ACCESS_TOOL_NAME,
1279
+ ).execute({});
1280
+ expect(before.textForLlm).toContain(
1281
+ "read-only kubectl via the Kubernetes AI agent",
1282
+ );
1283
+
1284
+ const outcome: ToolCallOutcome = await runOn(toolkit);
1285
+
1286
+ expect(outcome.errorMessage).toBe(
1287
+ 'kubectl was not run on cluster "prod-us": its Kubernetes AI agent did not pick up the command in time.',
1288
+ );
1289
+ expect(outcome.textForLlm).toContain(
1290
+ "its Kubernetes AI agent did not pick up",
1291
+ );
1292
+ expect(outcome.textForLlm).toContain(
1293
+ "the cluster's Kubernetes AI agent did not respond",
1294
+ );
1295
+ expect(outcome.textForLlm).not.toContain("Runner");
1296
+
1297
+ // The breaker speaks of the agent too.
1298
+ const second: ToolCallOutcome = await runOn(toolkit);
1299
+ expect(second.textForLlm).toMatch(/^The Kubernetes AI agent, which serves/);
1300
+ expect(second.errorMessage).toBe(
1301
+ 'kubectl was not run on cluster "prod-us": its Kubernetes AI agent did not pick up an earlier command, so the cluster was unreachable for the rest of this investigation.',
1302
+ );
1303
+
1304
+ const list: ToolCallOutcome = await getTool(
1305
+ toolkit,
1306
+ LIST_CLUSTER_ACCESS_TOOL_NAME,
1307
+ ).execute({});
1308
+ expect(list.textForLlm).toContain(
1309
+ "its Kubernetes AI agent did not pick up an earlier command",
1310
+ );
1311
+
1312
+ // The command went to the agent's row id with no credential.
1313
+ const data: Record<string, unknown> = enqueue.mock.calls[0]![0] as Record<
1314
+ string,
1315
+ unknown
1316
+ >;
1317
+ expect(String(data["targetAgentId"])).toBe(RUNNER_ID.toString());
1318
+ expect(data["credentialId"]).toBeUndefined();
1319
+ });
1320
+
1251
1321
  it("trips a per-cluster breaker: the next command fails at once, enqueues nothing and spends nothing", async () => {
1252
1322
  const toolkit: KubectlInvestigationToolkit = singleClusterToolkit();
1253
1323
 
@@ -230,6 +230,64 @@ describe("KubectlJobRunner.readFinishedJob", () => {
230
230
  });
231
231
  });
232
232
 
233
+ /*
234
+ * A job enqueued for the cluster's Kubernetes AI agent (the row carries
235
+ * targetKubernetesAiAgentId) is worded for the agent: "Runner" would send
236
+ * the operator looking for a Runner that does not exist.
237
+ */
238
+ describe("KubectlJobRunner.readFinishedJob for a Kubernetes AI agent job", () => {
239
+ function readAgentJob(terminalJob: RunnerJob): Promise<KubectlJobOutcome> {
240
+ return KubectlJobRunner.readFinishedJob({
241
+ job: {
242
+ ...enqueuedJob({ displayCommand: "kubectl get pods -n web" }),
243
+ targetKubernetesAiAgentId: ObjectID.generate(),
244
+ } as unknown as RunnerJob,
245
+ terminalJob,
246
+ command: "kubectl get pods -n web",
247
+ claimTimeoutInMs: KUBECTL_CLAIM_TIMEOUT_MS,
248
+ executionTimeoutInMs: EXECUTION_TIMEOUT_MS,
249
+ });
250
+ }
251
+
252
+ it("never picked up: names the agent", async () => {
253
+ claimRead.mockResolvedValue(terminal({}));
254
+
255
+ const outcome: KubectlJobOutcome = await readAgentJob(
256
+ terminal({ status: RunnerJobStatus.TimedOut }),
257
+ );
258
+
259
+ expect(outcome.errorMessage).toMatch(
260
+ /^The cluster's Kubernetes AI agent did not pick up this kubectl command within \d+s/,
261
+ );
262
+ expect(outcome.runState).toBe(KubectlRunState.NotRun);
263
+ });
264
+
265
+ it("taken and gone silent: names the agent", async () => {
266
+ claimRead.mockResolvedValue(terminal({ claimedAt: new Date() }));
267
+
268
+ const outcome: KubectlJobOutcome = await readAgentJob(
269
+ terminal({ status: RunnerJobStatus.TimedOut }),
270
+ );
271
+
272
+ expect(outcome.errorMessage).toMatch(
273
+ /^The Kubernetes AI agent took this kubectl command but did not report a result in time/,
274
+ );
275
+ expect(outcome.errorMessage).not.toContain("Runner");
276
+ });
277
+
278
+ it("claim unreadable: names the agent", async () => {
279
+ claimRead.mockRejectedValue(new Error("db down"));
280
+
281
+ const outcome: KubectlJobOutcome = await readAgentJob(
282
+ terminal({ status: RunnerJobStatus.TimedOut }),
283
+ );
284
+
285
+ expect(outcome.errorMessage).toContain(
286
+ "whether the Kubernetes AI agent picked it up could not be read",
287
+ );
288
+ });
289
+ });
290
+
233
291
  describe("KubectlJobRunner.recordOutcomeOnCluster", () => {
234
292
  let recordOutcome: jest.SpyInstance;
235
293
 
@@ -107,6 +107,8 @@ function cluster(
107
107
  posture: { inCluster: true, allowWrites: true },
108
108
  },
109
109
  accessMethod: "in_cluster",
110
+ aiAgent: null,
111
+ automaticInvestigation: { incidents: false, alerts: false },
110
112
  kubectlAllowlist: [],
111
113
  isInvestigationEnabled: true,
112
114
  isInvestigationReady: true,
@@ -79,6 +79,8 @@ function cluster(): KubernetesClusterAiAccessStatus {
79
79
  posture: { inCluster: true, allowWrites: true },
80
80
  },
81
81
  accessMethod: "in_cluster",
82
+ aiAgent: null,
83
+ automaticInvestigation: { incidents: false, alerts: false },
82
84
  kubectlAllowlist: [],
83
85
  isInvestigationEnabled: true,
84
86
  isInvestigationReady: true,
@@ -103,6 +103,8 @@ function cluster(
103
103
  posture: { inCluster: true, allowWrites: true },
104
104
  },
105
105
  accessMethod: "in_cluster",
106
+ aiAgent: null,
107
+ automaticInvestigation: { incidents: false, alerts: false },
106
108
  kubectlAllowlist: [],
107
109
  isInvestigationEnabled: true,
108
110
  isInvestigationReady: true,
@@ -111,6 +111,8 @@ function cluster(
111
111
  posture: posture || undefined,
112
112
  },
113
113
  accessMethod: "in_cluster",
114
+ aiAgent: null,
115
+ automaticInvestigation: { incidents: false, alerts: false },
114
116
  kubectlAllowlist: [],
115
117
  isInvestigationEnabled: true,
116
118
  isInvestigationReady: true,
@@ -233,7 +235,7 @@ describe("RemediationCommandToolkit.getRunnerScopeRefusal — the Runner's repor
233
235
  expect(
234
236
  refusalFor("kubectl rollout restart deployment/pay -n payments"),
235
237
  ).toContain(
236
- 'It only lets OneUptime AI change "web", "api" (aiAccess.remediation.namespaces on the Kubernetes agent chart).',
238
+ 'It only lets OneUptime AI change "web", "api" (aiAccess.remediation.namespaces on the Kubernetes agent chart; after upgrading to the Kubernetes AI agent, aiAgent.remediation.namespaces).',
237
239
  );
238
240
  expect(refusalFor("kubectl rollout restart deployment/web")).toContain(
239
241
  "Name the target namespace with -n <namespace>.",
@@ -1063,3 +1065,125 @@ describe("RemediationCommandToolkit tells the model the Runner's scope as the Ru
1063
1065
  }
1064
1066
  });
1065
1067
  });
1068
+
1069
+ /*
1070
+ * The Kubernetes AI agent as the cluster's access target (runner.kind
1071
+ * "ai_agent", accessMethod "in_cluster"): the same rule as the in-cluster
1072
+ * Runner — a write with no -n lands in the agent pod's own namespace — in
1073
+ * the agent's words, naming the aiAgent.* chart values. The previous
1074
+ * in-cluster Runner's refusals say how to move to the agent; a credential
1075
+ * Runner's name its own environment.
1076
+ */
1077
+ describe("RemediationCommandToolkit.getRunnerScopeRefusal — who sets the scope, three ways", () => {
1078
+ const AGENT_POSTURE: KubernetesRunnerPosture = {
1079
+ inCluster: true,
1080
+ allowWrites: true,
1081
+ clusterIdentifier: "prod-us",
1082
+ writeNamespaces: ["web", "api"],
1083
+ podNamespace: "oneuptime-agent",
1084
+ allowNodeOperations: false,
1085
+ };
1086
+
1087
+ function agentCluster(): KubernetesClusterAiAccessStatus {
1088
+ return cluster(AGENT_POSTURE, {
1089
+ runner: {
1090
+ id: RUNNER_ID.toString(),
1091
+ name: "Kubernetes AI agent",
1092
+ kind: "ai_agent",
1093
+ isOnline: true,
1094
+ canRunAiCommands: true,
1095
+ posture: AGENT_POSTURE,
1096
+ },
1097
+ });
1098
+ }
1099
+
1100
+ it("names the agent and aiAgent.remediation.namespaces for a write outside its scope", () => {
1101
+ const refusal: string | null = refusalFor(
1102
+ "kubectl rollout restart deployment/pay -n payments",
1103
+ agentCluster(),
1104
+ );
1105
+
1106
+ expect(refusal).toContain(
1107
+ 'outside the namespaces the Kubernetes AI agent of cluster "prod-us" may change',
1108
+ );
1109
+ expect(refusal).toContain(
1110
+ "(aiAgent.remediation.namespaces on the Kubernetes agent chart)",
1111
+ );
1112
+ expect(refusal).not.toContain("aiAccess");
1113
+ expect(refusal).not.toContain("the Runner of cluster");
1114
+ });
1115
+
1116
+ it("names aiAgent.remediation.nodeOperations for a node operation", () => {
1117
+ const refusal: string | null = refusalFor(
1118
+ "kubectl cordon n1",
1119
+ agentCluster(),
1120
+ );
1121
+
1122
+ expect(refusal).toContain(
1123
+ "aiAgent.remediation.nodeOperations=false on the Kubernetes agent chart",
1124
+ );
1125
+ expect(refusal).not.toContain("aiAccess");
1126
+ });
1127
+
1128
+ it("judges a write with no -n against the agent pod's own namespace, as the agent does", () => {
1129
+ const refusal: string | null = refusalFor(
1130
+ "kubectl rollout restart deployment/web",
1131
+ agentCluster(),
1132
+ );
1133
+
1134
+ expect(refusal).toContain(
1135
+ 'names no namespace, so kubectl would run it in "oneuptime-agent"',
1136
+ );
1137
+ expect(refusal).toContain("never changes its own namespace");
1138
+ });
1139
+
1140
+ it("negative control: a write inside the agent's scope is not refused", () => {
1141
+ expect(
1142
+ refusalFor(
1143
+ "kubectl rollout restart deployment/web -n web",
1144
+ agentCluster(),
1145
+ ),
1146
+ ).toBeNull();
1147
+ });
1148
+
1149
+ it("getRunnerScopeSettings: the agent, the previous in-cluster Runner and a credential Runner each name their own setting", () => {
1150
+ expect(
1151
+ RemediationCommandToolkit.getRunnerScopeSettings(agentCluster()),
1152
+ ).toEqual({
1153
+ namespaces:
1154
+ "aiAgent.remediation.namespaces on the Kubernetes agent chart",
1155
+ nodeOperations:
1156
+ "aiAgent.remediation.nodeOperations=false on the Kubernetes agent chart",
1157
+ });
1158
+
1159
+ const legacy: { namespaces: string; nodeOperations: string } =
1160
+ RemediationCommandToolkit.getRunnerScopeSettings(cluster(AGENT_POSTURE));
1161
+
1162
+ expect(legacy.namespaces).toContain(
1163
+ "aiAccess.remediation.namespaces on the Kubernetes agent chart",
1164
+ );
1165
+ expect(legacy.namespaces).toContain(
1166
+ "after upgrading to the Kubernetes AI agent, aiAgent.remediation.namespaces",
1167
+ );
1168
+ expect(legacy.nodeOperations).toContain(
1169
+ "after upgrading to the Kubernetes AI agent, aiAgent.remediation.nodeOperations",
1170
+ );
1171
+
1172
+ expect(
1173
+ RemediationCommandToolkit.getRunnerScopeSettings(credentialCluster()),
1174
+ ).toEqual({
1175
+ namespaces: "ONEUPTIME_KUBECTL_WRITE_NAMESPACES on the Runner's host",
1176
+ nodeOperations:
1177
+ "ONEUPTIME_KUBECTL_ALLOW_NODE_OPERATIONS on the Runner's host",
1178
+ });
1179
+ });
1180
+
1181
+ it("the agent is told apart by kind only: a posture alone reads as the previous in-cluster Runner", () => {
1182
+ const withoutKind: KubernetesClusterAiAccessStatus = agentCluster();
1183
+ delete withoutKind.runner!.kind;
1184
+
1185
+ expect(
1186
+ RemediationCommandToolkit.getRunnerScopeSettings(withoutKind).namespaces,
1187
+ ).toContain("aiAccess.remediation.namespaces");
1188
+ });
1189
+ });