@oneuptime/common 14.0.8 → 14.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (976) hide show
  1. package/Models/DatabaseModels/AutoRemediationSuggestion.ts +60 -0
  2. package/Models/DatabaseModels/CephCluster.ts +213 -0
  3. package/Models/DatabaseModels/DatabaseServer.ts +213 -0
  4. package/Models/DatabaseModels/DockerHost.ts +213 -0
  5. package/Models/DatabaseModels/DockerSwarmCluster.ts +213 -0
  6. package/Models/DatabaseModels/GlobalConfig.ts +1 -1
  7. package/Models/DatabaseModels/Host.ts +213 -0
  8. package/Models/DatabaseModels/Index.ts +4 -0
  9. package/Models/DatabaseModels/KubernetesAiAgent.ts +364 -0
  10. package/Models/DatabaseModels/KubernetesCluster.ts +3 -3
  11. package/Models/DatabaseModels/PodmanHost.ts +213 -0
  12. package/Models/DatabaseModels/Project.ts +55 -5
  13. package/Models/DatabaseModels/ProxmoxCluster.ts +213 -0
  14. package/Models/DatabaseModels/ProxmoxResource.ts +49 -1
  15. package/Models/DatabaseModels/ResourceAiAgent.ts +419 -0
  16. package/Models/DatabaseModels/RunnerJob.ts +219 -0
  17. package/Models/DatabaseModels/TeamComplianceSetting.ts +143 -2
  18. package/Models/DatabaseModels/VMwareVCenter.ts +213 -0
  19. package/Models/DatabaseModels/WorkspaceProjectAuthToken.ts +17 -0
  20. package/Server/API/AIChatAPI.ts +6 -3
  21. package/Server/API/AIInvestigationAPI.ts +17 -10
  22. package/Server/API/AutoRemediationAPI.ts +598 -25
  23. package/Server/API/KubernetesClusterAiAccessAPI.ts +623 -21
  24. package/Server/API/MicrosoftTeamsAPI.ts +93 -14
  25. package/Server/API/ProxmoxResourceAPI.ts +244 -14
  26. package/Server/API/ResourceAiAccessAPI.ts +1669 -0
  27. package/Server/Infrastructure/GlobalCache.ts +32 -0
  28. package/Server/Infrastructure/Postgres/SchemaMigrations/1796000000000-AddTeamComplianceRuleScope.ts +99 -0
  29. package/Server/Infrastructure/Postgres/SchemaMigrations/1796100000000-AddKubernetesAiAgentAndAiDefaults.ts +137 -0
  30. package/Server/Infrastructure/Postgres/SchemaMigrations/1796200000000-AddProxmoxResourceNativePushColumns.ts +42 -0
  31. package/Server/Infrastructure/Postgres/SchemaMigrations/1796300000000-AddResourceAiAgents.ts +423 -0
  32. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +8 -0
  33. package/Server/Infrastructure/Semaphore.ts +22 -0
  34. package/Server/Middleware/TelemetryIngest.ts +51 -18
  35. package/Server/Services/AIService.ts +70 -1
  36. package/Server/Services/AlertService.ts +352 -11
  37. package/Server/Services/AlertSeverityService.ts +65 -15
  38. package/Server/Services/AnalyticsDatabaseService.ts +45 -1
  39. package/Server/Services/AutoRemediationRuleEngineService.ts +940 -112
  40. package/Server/Services/AutoRemediationRuleService.ts +1 -1
  41. package/Server/Services/CephClusterService.ts +109 -1
  42. package/Server/Services/DatabaseServerService.ts +116 -1
  43. package/Server/Services/DockerHostService.ts +109 -1
  44. package/Server/Services/DockerSwarmClusterService.ts +113 -1
  45. package/Server/Services/HostService.ts +126 -4
  46. package/Server/Services/IncidentService.ts +280 -104
  47. package/Server/Services/IncidentSeverityService.ts +66 -15
  48. package/Server/Services/KubernetesAiAgentJobService.ts +185 -0
  49. package/Server/Services/KubernetesAiAgentService.ts +1634 -0
  50. package/Server/Services/KubernetesClusterAiAccessService.ts +1118 -451
  51. package/Server/Services/KubernetesClusterService.ts +129 -21
  52. package/Server/Services/MetricRecordingRuleService.ts +47 -0
  53. package/Server/Services/PodmanHostService.ts +109 -1
  54. package/Server/Services/ProjectService.ts +32 -0
  55. package/Server/Services/ProxmoxClusterService.ts +110 -1
  56. package/Server/Services/ProxmoxResourceService.ts +322 -5
  57. package/Server/Services/ResourceAiAccessService.ts +1439 -0
  58. package/Server/Services/ResourceAiAgentJobService.ts +202 -0
  59. package/Server/Services/ResourceAiAgentService.ts +2432 -0
  60. package/Server/Services/RunnerJobService.ts +852 -108
  61. package/Server/Services/RunnerService.ts +1 -1
  62. package/Server/Services/ScheduledMaintenanceService.ts +737 -1
  63. package/Server/Services/ScheduledMaintenanceStateTimelineService.ts +414 -56
  64. package/Server/Services/TeamComplianceSettingService.ts +1125 -9
  65. package/Server/Services/TelemetryUsageBillingService.ts +28 -0
  66. package/Server/Services/TraceRecordingRuleService.ts +33 -0
  67. package/Server/Services/VMwareVCenterService.ts +110 -1
  68. package/Server/Utils/AI/ClusterAccess/ClusterAccessContext.ts +67 -9
  69. package/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.ts +39 -10
  70. package/Server/Utils/AI/ClusterAccess/KubectlJobRunner.ts +14 -3
  71. package/Server/Utils/AI/Remediation/RemediationCommandTools.ts +1475 -51
  72. package/Server/Utils/AI/Remediation/RemediationExecutionRunner.ts +1000 -43
  73. package/Server/Utils/AI/Remediation/RemediationPlanRunner.ts +25 -1
  74. package/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.ts +577 -0
  75. package/Server/Utils/AI/ResourceAccess/ResourceAccessContext.ts +271 -0
  76. package/Server/Utils/AI/ResourceAccess/ResourceAccessToolNames.ts +45 -0
  77. package/Server/Utils/AI/ResourceAccess/ResourceAiAccessSettings.ts +964 -0
  78. package/Server/Utils/AI/ResourceAccess/ResourceAiDeleteCleanup.ts +333 -0
  79. package/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.ts +873 -0
  80. package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +120 -7
  81. package/Server/Utils/AI/SRE/AlertInvestigationRunner.ts +72 -5
  82. package/Server/Utils/AI/SRE/IncidentInvestigationRunner.ts +72 -5
  83. package/Server/Utils/AI/SRE/IncidentPostmortemRunner.ts +40 -8
  84. package/Server/Utils/AI/SRE/InvestigationEligibility.ts +13 -2
  85. package/Server/Utils/AI/SRE/InvestigationGrader.ts +1 -1
  86. package/Server/Utils/AutoRemediation/CommandPlanExecutor.ts +402 -14
  87. package/Server/Utils/AutoRemediation/RemediationVerifier.ts +35 -2
  88. package/Server/Utils/Database/ProjectScopedReferenceValidator.ts +9 -1
  89. package/Server/Utils/SessionReplay/SessionReplayBudgetMetrics.ts +920 -0
  90. package/Server/Utils/SessionReplay/SessionReplayUsage.ts +84 -6
  91. package/Server/Utils/Telemetry/InventoryEntityRegistry.ts +133 -7
  92. package/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.ts +58 -4
  93. package/Server/Utils/Telemetry/ProxmoxNativeNodeLiveness.ts +447 -0
  94. package/Server/Utils/Telemetry/ProxmoxNativePush.ts +903 -0
  95. package/Server/Utils/Telemetry/TelemetryEntity.ts +87 -27
  96. package/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.ts +35 -15
  97. package/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.ts +33 -15
  98. package/Server/Utils/Workspace/MicrosoftTeams/Actions/Auth.ts +21 -1
  99. package/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.ts +298 -224
  100. package/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.ts +35 -15
  101. package/Server/Utils/Workspace/MicrosoftTeams/Actions/ScheduledMaintenance.ts +389 -175
  102. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +1073 -213
  103. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsActivityDeduplicator.ts +163 -0
  104. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCardChoices.ts +396 -0
  105. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateCommands.ts +418 -0
  106. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsMessageSize.ts +152 -0
  107. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsReplies.ts +251 -0
  108. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsTimezone.ts +214 -0
  109. package/Tests/App/AdminDashboard/RowActionPlacementOverrides.test.tsx +278 -0
  110. package/Tests/App/Dashboard/AIChatChartWidgetZoom.test.tsx +738 -0
  111. package/Tests/App/Dashboard/AIFeaturesSettingsPointers.test.tsx +147 -0
  112. package/Tests/App/Dashboard/AIInsightsKubernetesClusterPage.test.tsx +1523 -0
  113. package/Tests/App/Dashboard/AdminUserNotificationMethodsPage.test.tsx +463 -3
  114. package/Tests/App/Dashboard/AffectedResourcesPickerDropdownPlacement.test.tsx +958 -0
  115. package/Tests/App/Dashboard/AffectedResourcesPickerFocusLeave.test.tsx +595 -0
  116. package/Tests/App/Dashboard/AskAiAvailability.test.ts +20 -3
  117. package/Tests/App/Dashboard/AskAiDisabled.test.tsx +8 -3
  118. package/Tests/App/Dashboard/CephRateChartReload.test.tsx +1456 -0
  119. package/Tests/App/Dashboard/CephTimeRangeZoom.test.tsx +1229 -0
  120. package/Tests/App/Dashboard/ChartCardTimeRangeZoom.test.tsx +151 -0
  121. package/Tests/App/Dashboard/ChartCardZoomAffordances.test.tsx +257 -0
  122. package/Tests/App/Dashboard/ChartRefetchFrame.test.tsx +141 -0
  123. package/Tests/App/Dashboard/ChartZoomHarness.tsx +249 -0
  124. package/Tests/App/Dashboard/ChartZoomStandIn.tsx +131 -0
  125. package/Tests/App/Dashboard/CloudServerlessSlowLoads.test.tsx +628 -0
  126. package/Tests/App/Dashboard/CloudServerlessTimeRangeZoom.test.tsx +607 -0
  127. package/Tests/App/Dashboard/ClusterAccessNotice.test.tsx +184 -19
  128. package/Tests/App/Dashboard/CompanionMetricsTabZoom.test.tsx +632 -0
  129. package/Tests/App/Dashboard/ContainerChartZoomStandIn.tsx +195 -0
  130. package/Tests/App/Dashboard/ContainerHostOverviewSlowLoads.test.tsx +542 -0
  131. package/Tests/App/Dashboard/ContainerHostOverviewTimeRangeZoom.test.tsx +848 -0
  132. package/Tests/App/Dashboard/ContainerMetricsTimeRangeZoom.test.tsx +561 -0
  133. package/Tests/App/Dashboard/DashboardBoardWideZoomShell.test.tsx +1147 -0
  134. package/Tests/App/Dashboard/DashboardEditPermissions.test.tsx +3 -2
  135. package/Tests/App/Dashboard/DashboardHistogramWidgetDragCursor.test.tsx +399 -0
  136. package/Tests/App/Dashboard/DashboardHistogramWidgetZoom.test.tsx +985 -0
  137. package/Tests/App/Dashboard/DashboardHistogramWidgetZoomHint.test.tsx +803 -0
  138. package/Tests/App/Dashboard/DashboardLazyPages.test.tsx +1 -0
  139. package/Tests/App/Dashboard/DashboardSettingsPreviewZoom.test.tsx +679 -0
  140. package/Tests/App/Dashboard/DashboardSloAndDataSourceChartZoom.test.tsx +881 -0
  141. package/Tests/App/Dashboard/DashboardTraceStatusWidgets.test.tsx +878 -0
  142. package/Tests/App/Dashboard/DatabaseDocumentationMarkdown.test.ts +18 -6
  143. package/Tests/App/Dashboard/DatabaseMetricChartModalTimeRangeZoom.test.tsx +442 -0
  144. package/Tests/App/Dashboard/DatabaseOverviewTimeRangeZoom.test.tsx +831 -0
  145. package/Tests/App/Dashboard/DatabaseServerComponents.test.tsx +43 -0
  146. package/Tests/App/Dashboard/DockerSwarmInsightsTimeRangeZoom.test.tsx +524 -0
  147. package/Tests/App/Dashboard/DockerSwarmRateChartRefresh.test.tsx +259 -0
  148. package/Tests/App/Dashboard/EdgeDetailPanelHistory.test.tsx +763 -0
  149. package/Tests/App/Dashboard/EdgeDetailPanelTimeRangeZoom.test.tsx +547 -0
  150. package/Tests/App/Dashboard/EdgeHistoryBucketsCases.tsx +565 -0
  151. package/Tests/App/Dashboard/EdgeHistoryBucketsKathmandu.test.tsx +73 -0
  152. package/Tests/App/Dashboard/EdgeHistoryBucketsKolkata.test.tsx +74 -0
  153. package/Tests/App/Dashboard/EdgeHistoryBucketsNewYork.test.tsx +72 -0
  154. package/Tests/App/Dashboard/EdgeHistoryBucketsUtc.test.tsx +72 -0
  155. package/Tests/App/Dashboard/EmbeddedMetricCardRefresh.test.tsx +310 -0
  156. package/Tests/App/Dashboard/EmbeddedMetricCardTimeRangeZoom.test.tsx +536 -0
  157. package/Tests/App/Dashboard/EscalationRuleReadiness.test.tsx +3 -1
  158. package/Tests/App/Dashboard/EscalationRuleRowActions.test.tsx +660 -0
  159. package/Tests/App/Dashboard/EventNotes.test.tsx +2 -2
  160. package/Tests/App/Dashboard/EventOverviewPages.test.tsx +587 -13
  161. package/Tests/App/Dashboard/EventOverviewSnapshotExplorerZoom.test.tsx +1139 -0
  162. package/Tests/App/Dashboard/EventOverviewSnapshotZoomAcrossTabs.test.tsx +1057 -0
  163. package/Tests/App/Dashboard/EventOverviewTelemetrySnapshotZoom.test.tsx +757 -0
  164. package/Tests/App/Dashboard/ExceptionOccurrenceTrendZoom.test.tsx +675 -0
  165. package/Tests/App/Dashboard/ExceptionOccurrencesZoomSurvivesViewSwitch.test.tsx +405 -0
  166. package/Tests/App/Dashboard/ExceptionSignalPages.test.tsx +67 -3
  167. package/Tests/App/Dashboard/ExceptionTablesSpanStatus.test.tsx +515 -0
  168. package/Tests/App/Dashboard/ExplorerOwnZoomRegression.test.tsx +739 -0
  169. package/Tests/App/Dashboard/FlowBandwidthAxisCases.tsx +461 -0
  170. package/Tests/App/Dashboard/FlowBandwidthAxisKathmandu.test.tsx +25 -0
  171. package/Tests/App/Dashboard/FlowBandwidthAxisKolkata.test.tsx +25 -0
  172. package/Tests/App/Dashboard/FlowBandwidthAxisNewYork.test.tsx +25 -0
  173. package/Tests/App/Dashboard/FlowBandwidthAxisUtc.test.tsx +24 -0
  174. package/Tests/App/Dashboard/FlowTopTalkersZoomRefetch.test.tsx +722 -0
  175. package/Tests/App/Dashboard/FlowViewportGuard.test.tsx +2526 -0
  176. package/Tests/App/Dashboard/HostPagesSlowLoads.test.tsx +872 -0
  177. package/Tests/App/Dashboard/HostPagesTimeRangeZoom.test.tsx +1208 -0
  178. package/Tests/App/Dashboard/IncidentRootCauseTimeRangeZoom.test.tsx +358 -0
  179. package/Tests/App/Dashboard/InfrastructureGraph.test.tsx +100 -9
  180. package/Tests/App/Dashboard/InfrastructureMetricsTabTimeRangeZoom.test.tsx +485 -0
  181. package/Tests/App/Dashboard/InvestigationDrawerCompanionZoom.test.tsx +655 -0
  182. package/Tests/App/Dashboard/InvestigationDrawerZoom.test.tsx +830 -0
  183. package/Tests/App/Dashboard/InvestigationInfrastructureTools.test.tsx +506 -0
  184. package/Tests/App/Dashboard/InvestigationNotStarted.test.tsx +338 -2
  185. package/Tests/App/Dashboard/InvoicesPayInvoice.test.tsx +454 -16
  186. package/Tests/App/Dashboard/KubernetesClusterAiAccessSettings.test.ts +799 -819
  187. package/Tests/App/Dashboard/KubernetesClusterAiAgentOverviewCard.test.tsx +367 -0
  188. package/Tests/App/Dashboard/KubernetesClusterAiAgentStatus.test.ts +1202 -0
  189. package/Tests/App/Dashboard/KubernetesClusterAiDocumentationMarkdown.test.ts +106 -0
  190. package/Tests/App/Dashboard/KubernetesClusterAiNavigation.test.tsx +354 -0
  191. package/Tests/App/Dashboard/KubernetesClusterAiPage.test.tsx +1884 -2054
  192. package/Tests/App/Dashboard/KubernetesClusterAiPageServerParity.test.ts +478 -179
  193. package/Tests/App/Dashboard/KubernetesClusterMetricTooltips.test.ts +50 -0
  194. package/Tests/App/Dashboard/KubernetesClusterOverviewTooltips.test.tsx +2 -1
  195. package/Tests/App/Dashboard/KubernetesClusterOverviewZoom.test.tsx +1217 -0
  196. package/Tests/App/Dashboard/KubernetesClusterPagesZoom.test.tsx +731 -0
  197. package/Tests/App/Dashboard/KubernetesCostsLoadRecovery.test.tsx +869 -0
  198. package/Tests/App/Dashboard/KubernetesCostsZoom.test.tsx +1214 -0
  199. package/Tests/App/Dashboard/KubernetesCostsZoomExactHours.test.tsx +692 -0
  200. package/Tests/App/Dashboard/KubernetesNetworkThroughputReload.test.tsx +902 -0
  201. package/Tests/App/Dashboard/KubernetesNetworkZoomBucketEdges.test.tsx +571 -0
  202. package/Tests/App/Dashboard/KubernetesOverviewZoomBucketEdges.test.tsx +697 -0
  203. package/Tests/App/Dashboard/KubernetesResourceMetricsTabZoom.test.tsx +633 -0
  204. package/Tests/App/Dashboard/LogsExplorerTimeRangeZoom.test.tsx +470 -0
  205. package/Tests/App/Dashboard/LogsInsightsTimeRangeZoom.test.tsx +948 -0
  206. package/Tests/App/Dashboard/LogsViewerPinnedWindowZoom.test.tsx +486 -0
  207. package/Tests/App/Dashboard/MetricChartsBucketInspectorDoubleClick.test.tsx +1001 -0
  208. package/Tests/App/Dashboard/MetricExplorerInvestigationAutoRefresh.test.tsx +514 -0
  209. package/Tests/App/Dashboard/MetricExplorerSavedViewZoomRoundTrip.test.tsx +581 -0
  210. package/Tests/App/Dashboard/MetricExplorerTimeRangeZoom.test.tsx +1162 -0
  211. package/Tests/App/Dashboard/MetricMonitorPreviewZoomLabel.test.ts +72 -0
  212. package/Tests/App/Dashboard/MetricRowSparklineTimeRangeZoom.test.tsx +204 -0
  213. package/Tests/App/Dashboard/MetricViewFirstResultLands.test.tsx +408 -0
  214. package/Tests/App/Dashboard/MetricViewOwnZoomResetPlacement.test.tsx +952 -0
  215. package/Tests/App/Dashboard/MetricViewTimeRange.test.ts +139 -0
  216. package/Tests/App/Dashboard/MetricViewTimeRangeZoom.test.tsx +556 -0
  217. package/Tests/App/Dashboard/MonitorMetricsChartWrappersZoom.test.tsx +552 -0
  218. package/Tests/App/Dashboard/MonitorMetricsTabsTimeRangeZoom.test.tsx +740 -0
  219. package/Tests/App/Dashboard/MonitorOverviewChartsTimeRangeZoom.test.tsx +735 -0
  220. package/Tests/App/Dashboard/MonitorStepPreviewsTimeRangeZoom.test.tsx +835 -0
  221. package/Tests/App/Dashboard/NetworkDeviceTimeRangeZoom.test.tsx +1115 -0
  222. package/Tests/App/Dashboard/OnCallPreventionGuards.test.tsx +186 -17
  223. package/Tests/App/Dashboard/OnCallRulesDeleteGuard.test.tsx +155 -46
  224. package/Tests/App/Dashboard/PasskeySettings.test.tsx +87 -2
  225. package/Tests/App/Dashboard/ProjectAISettingsPages.test.tsx +884 -0
  226. package/Tests/App/Dashboard/ProxmoxNodeRemove.test.tsx +621 -0
  227. package/Tests/App/Dashboard/ProxmoxOverviewSlowLoads.test.tsx +584 -0
  228. package/Tests/App/Dashboard/ProxmoxPagesTimeRangeZoom.test.tsx +823 -0
  229. package/Tests/App/Dashboard/ProxmoxRateChartReload.test.tsx +1253 -0
  230. package/Tests/App/Dashboard/PublicDashboardBoardWideZoom.test.tsx +605 -0
  231. package/Tests/App/Dashboard/RealRowsLineChart.tsx +250 -0
  232. package/Tests/App/Dashboard/RechartsHostsPlotCursor.test.tsx +513 -0
  233. package/Tests/App/Dashboard/RemediationSuggestionCardDescription.test.tsx +209 -0
  234. package/Tests/App/Dashboard/RemediationSuggestionCardResource.test.tsx +317 -0
  235. package/Tests/App/Dashboard/ResourceAiAccessSettingsUtil.test.ts +921 -0
  236. package/Tests/App/Dashboard/ResourceAiAgentInstall.test.ts +860 -0
  237. package/Tests/App/Dashboard/ResourceAiAgentPage.test.tsx +1721 -0
  238. package/Tests/App/Dashboard/ResourceAiAgentStatus.test.ts +1002 -0
  239. package/Tests/App/Dashboard/ResourceAiInsightsPage.test.tsx +931 -0
  240. package/Tests/App/Dashboard/ResourceAiNavigation.test.tsx +575 -0
  241. package/Tests/App/Dashboard/RowActionPlacementOverrides.test.tsx +865 -0
  242. package/Tests/App/Dashboard/RumOverviewTimeRangeZoom.test.tsx +877 -0
  243. package/Tests/App/Dashboard/RunbookStepTypeMaps.test.ts +38 -7
  244. package/Tests/App/Dashboard/RunnerKubernetesAgentForm.test.tsx +20 -4
  245. package/Tests/App/Dashboard/RunnerSupersededByAiAgentNote.test.tsx +296 -0
  246. package/Tests/App/Dashboard/SecurityEventConnectionsTable.test.tsx +146 -36
  247. package/Tests/App/Dashboard/ServiceDatabaseSlowLoads.test.tsx +1166 -0
  248. package/Tests/App/Dashboard/ServiceMapGraph.test.tsx +1243 -104
  249. package/Tests/App/Dashboard/ServiceOverviewTimeRangeZoom.test.tsx +792 -0
  250. package/Tests/App/Dashboard/SloBudgetBurnDownZoom.test.tsx +771 -0
  251. package/Tests/App/Dashboard/SloBudgetBurnDownZoomAffordances.test.tsx +380 -0
  252. package/Tests/App/Dashboard/SloEventMetricsBarChartZoom.test.tsx +369 -0
  253. package/Tests/App/Dashboard/SloHistoryChartsTimeRangeZoom.test.tsx +694 -0
  254. package/Tests/App/Dashboard/SloHistoryChartsZoomAffordances.test.tsx +497 -0
  255. package/Tests/App/Dashboard/SloMetricsTimeRangeZoom.test.tsx +541 -0
  256. package/Tests/App/Dashboard/SlowLoadHarness.ts +123 -0
  257. package/Tests/App/Dashboard/SnapshotExplorerPrimaryZoom.test.tsx +1194 -0
  258. package/Tests/App/Dashboard/SnapshotViewerPinnedWindow.test.tsx +620 -0
  259. package/Tests/App/Dashboard/TelemetrySnapshotPanelTimeRangeZoom.test.tsx +765 -0
  260. package/Tests/App/Dashboard/TelemetrySnapshotZoom.test.tsx +516 -0
  261. package/Tests/App/Dashboard/TelemetrySnapshotZoomAcrossTabs.test.tsx +827 -0
  262. package/Tests/App/Dashboard/TimeRangeZoomPageHarness.tsx +463 -0
  263. package/Tests/App/Dashboard/TraceChartEditorStatusSplit.test.tsx +543 -0
  264. package/Tests/App/Dashboard/TraceStatusPresentation.test.tsx +967 -0
  265. package/Tests/App/Dashboard/TraceTimelineMinimapZoom.test.tsx +315 -0
  266. package/Tests/App/Dashboard/TracesAnalyticsStatusSplit.test.tsx +778 -0
  267. package/Tests/App/Dashboard/TracesAnalyticsViewZoom.test.tsx +349 -0
  268. package/Tests/App/Dashboard/TracesExplorerTimeRangeZoom.test.tsx +551 -0
  269. package/Tests/App/Dashboard/TracesStatusChartAndFacet.test.tsx +687 -0
  270. package/Tests/App/Dashboard/TracesViewerStaleResponses.test.tsx +458 -0
  271. package/Tests/App/Dashboard/UptimeStripsExcludedFromZoom.test.tsx +406 -0
  272. package/Tests/App/Dashboard/VMwareOverviewSlowLoads.test.tsx +535 -0
  273. package/Tests/App/Dashboard/VMwarePagesTimeRangeZoom.test.tsx +606 -0
  274. package/Tests/App/Dashboard/ValueWidgetSparklineStaleHover.test.tsx +1292 -0
  275. package/Tests/App/Dashboard/ValueWidgetSparklineZoom.test.tsx +765 -0
  276. package/Tests/App/StatusPage/StatusPageResourceExplorer.test.tsx +98 -0
  277. package/Tests/Models/DatabaseModels/DatabaseServerModels.test.ts +33 -1
  278. package/Tests/Models/DatabaseModels/KubernetesAiAgentModel.test.ts +295 -0
  279. package/Tests/Models/DatabaseModels/ResourceAiAccessColumns.test.ts +738 -0
  280. package/Tests/Models/DatabaseModels/ResourceAiAgentModel.test.ts +842 -0
  281. package/Tests/Models/DatabaseModels/TeamComplianceSettingModel.test.ts +347 -0
  282. package/Tests/Server/API/AIChatRouteAuthorization.test.ts +58 -0
  283. package/Tests/Server/API/AIGenerationProjectAIToggle.test.ts +1 -1
  284. package/Tests/Server/API/AIInvestigationAPI.test.ts +123 -45
  285. package/Tests/Server/API/AutoRemediationApproveClusterRound.test.ts +1329 -0
  286. package/Tests/Server/API/AutoRemediationApproveKubectlRecheck.test.ts +25 -2
  287. package/Tests/Server/API/AutoRemediationApproveResourceRound.test.ts +835 -0
  288. package/Tests/Server/API/KubernetesClusterAiAccessAPI.test.ts +2 -0
  289. package/Tests/Server/API/KubernetesClusterAiAccessAPIAgent.test.ts +903 -0
  290. package/Tests/Server/API/MicrosoftTeamsChatsRefreshRoute.test.ts +667 -0
  291. package/Tests/Server/API/MicrosoftTeamsManifest.test.ts +294 -6
  292. package/Tests/Server/API/ProxmoxResourceAPIRemoveNode.test.ts +1932 -0
  293. package/Tests/Server/API/ResourceAiAccessAPI.test.ts +2730 -0
  294. package/Tests/Server/Infrastructure/GlobalCache.test.ts +195 -0
  295. package/Tests/Server/Infrastructure/Postgres/AddDatabaseServerTablesMigration.test.ts +60 -0
  296. package/Tests/Server/Infrastructure/Postgres/AddKubernetesAiAgentAndAiDefaultsMigration.test.ts +623 -0
  297. package/Tests/Server/Infrastructure/Postgres/AddKubernetesClusterAiAccessMigration.test.ts +87 -10
  298. package/Tests/Server/Infrastructure/Postgres/AddResourceAiAgentsMigration.test.ts +659 -0
  299. package/Tests/Server/Infrastructure/Postgres/AddTeamComplianceRuleScopeMigration.test.ts +622 -0
  300. package/Tests/Server/Infrastructure/SemaphoreMutex.test.ts +31 -0
  301. package/Tests/Server/Middleware/TelemetryIngestBrowserKey.test.ts +119 -4
  302. package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerPinnedKey.test.ts +196 -2
  303. package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerRateLimit.test.ts +123 -2
  304. package/Tests/Server/Services/AIServiceBalanceBlocker.test.ts +282 -0
  305. package/Tests/Server/Services/AlertMonitorClearWritesNull.test.ts +409 -0
  306. package/Tests/Server/Services/AlertMonitorEditFeed.test.ts +474 -0
  307. package/Tests/Server/Services/AlertMonitorEditGuard.test.ts +610 -0
  308. package/Tests/Server/Services/AutoRemediationClusterRuleEngine.test.ts +2 -0
  309. package/Tests/Server/Services/AutoRemediationResourceRuleEngine.test.ts +1279 -0
  310. package/Tests/Server/Services/AutoRemediationRuleCommandRunners.test.ts +2 -1
  311. package/Tests/Server/Services/DatabaseServerService.test.ts +55 -0
  312. package/Tests/Server/Services/GroupTelemetryUsageExcludeNames.test.ts +299 -0
  313. package/Tests/Server/Services/HostServiceFindOrCreateMemo.test.ts +44 -0
  314. package/Tests/Server/Services/IncidentAffectedMonitorsEdit.test.ts +1360 -0
  315. package/Tests/Server/Services/IncidentAlertSloLinkSurvivesEdit.test.ts +3 -1
  316. package/Tests/Server/Services/IncidentSeverityDeletePausesComplianceRules.test.ts +488 -0
  317. package/Tests/Server/Services/KubernetesAiAgentJobService.test.ts +329 -0
  318. package/Tests/Server/Services/KubernetesAiAgentServiceHelpers.test.ts +618 -0
  319. package/Tests/Server/Services/KubernetesAiAgentServiceLifecycle.test.ts +1444 -0
  320. package/Tests/Server/Services/KubernetesAiAgentServiceRegister.test.ts +1666 -0
  321. package/Tests/Server/Services/KubernetesClusterAiAccessDeletedRunnerRemedy.test.ts +140 -111
  322. package/Tests/Server/Services/KubernetesClusterAiAccessGapNextSteps.test.ts +267 -105
  323. package/Tests/Server/Services/KubernetesClusterAiAccessLegacySuperseded.test.ts +440 -0
  324. package/Tests/Server/Services/KubernetesClusterAiAccessService.test.ts +567 -411
  325. package/Tests/Server/Services/KubernetesClusterAiAccessTarget.test.ts +1168 -0
  326. package/Tests/Server/Services/KubernetesClusterAiSettingsPermission.test.ts +410 -12
  327. package/Tests/Server/Services/KubernetesClusterServiceAiAccessFeed.test.ts +55 -0
  328. package/Tests/Server/Services/MonitorProbeServiceIntervalScheduling.test.ts +45 -6
  329. package/Tests/Server/Services/ProjectServiceNewProjectAiDefaults.test.ts +288 -0
  330. package/Tests/Server/Services/ProxmoxResourcePostgres.test.ts +5633 -0
  331. package/Tests/Server/Services/ProxmoxResourceService.test.ts +6458 -5
  332. package/Tests/Server/Services/RecordingRuleReservedMetricName.test.ts +171 -0
  333. package/Tests/Server/Services/ResourceAiAccessChangeAuthorization.test.ts +256 -0
  334. package/Tests/Server/Services/ResourceAiAccessService.test.ts +1373 -0
  335. package/Tests/Server/Services/ResourceAiAgentJobService.test.ts +375 -0
  336. package/Tests/Server/Services/ResourceAiAgentServiceHelpers.test.ts +1114 -0
  337. package/Tests/Server/Services/ResourceAiAgentServiceLifecycle.test.ts +1050 -0
  338. package/Tests/Server/Services/ResourceAiAgentServiceRegister.test.ts +2251 -0
  339. package/Tests/Server/Services/ResourceAiSettingsCreate.test.ts +373 -0
  340. package/Tests/Server/Services/ResourceAiSettingsPermission.test.ts +1042 -0
  341. package/Tests/Server/Services/ResourceServiceDeleteCleansUpAi.test.ts +319 -0
  342. package/Tests/Server/Services/RunnerJobEnqueueKubectl.test.ts +153 -15
  343. package/Tests/Server/Services/RunnerJobEnqueueKubectlAiAgent.test.ts +620 -0
  344. package/Tests/Server/Services/RunnerJobEnqueueResourceCommand.test.ts +986 -0
  345. package/Tests/Server/Services/RunnerJobKubectlWriteScope.test.ts +170 -3
  346. package/Tests/Server/Services/RunnerJobResourceCommandLane.test.ts +211 -0
  347. package/Tests/Server/Services/RunnerJobResourceCommandTimeoutAndRedaction.test.ts +352 -0
  348. package/Tests/Server/Services/RunnerJobTimeoutReason.test.ts +72 -0
  349. package/Tests/Server/Services/RunnerServiceAgentName.test.ts +6 -4
  350. package/Tests/Server/Services/ScheduledMaintenanceAttachmentEdit.test.ts +2113 -0
  351. package/Tests/Server/Services/ScheduledMaintenanceMonitorRelease.test.ts +972 -0
  352. package/Tests/Server/Services/TeamComplianceSettingPostgres.test.ts +2237 -0
  353. package/Tests/Server/Services/TeamComplianceSettingService.test.ts +3988 -138
  354. package/Tests/Server/Services/TelemetryUsageBillingSloExclusion.test.ts +218 -0
  355. package/Tests/Server/TestingUtils/Services/FakeRunnerJobCount.ts +145 -0
  356. package/Tests/Server/Utils/AI/ClusterAccessContext.test.ts +107 -1
  357. package/Tests/Server/Utils/AI/IncidentPostmortemRunner.test.ts +351 -0
  358. package/Tests/Server/Utils/AI/InvestigationClusterAccessWiring.test.ts +2 -0
  359. package/Tests/Server/Utils/AI/InvestigationEligibility.test.ts +310 -0
  360. package/Tests/Server/Utils/AI/InvestigationInfrastructureAccessWiring.test.ts +453 -0
  361. package/Tests/Server/Utils/AI/InvestigationInfrastructureReport.test.ts +721 -0
  362. package/Tests/Server/Utils/AI/KubectlInvestigationToolkit.test.ts +70 -0
  363. package/Tests/Server/Utils/AI/KubectlJobRunnerFinishedJob.test.ts +58 -0
  364. package/Tests/Server/Utils/AI/RemediationCommandTools.test.ts +94 -1
  365. package/Tests/Server/Utils/AI/RemediationCommandToolsKubectl.test.ts +2 -0
  366. package/Tests/Server/Utils/AI/RemediationCommandToolsKubectlOutcome.test.ts +2 -0
  367. package/Tests/Server/Utils/AI/RemediationCommandToolsLiveCluster.test.ts +2 -0
  368. package/Tests/Server/Utils/AI/RemediationCommandToolsResource.test.ts +1530 -0
  369. package/Tests/Server/Utils/AI/RemediationCommandToolsRunnerScope.test.ts +125 -1
  370. package/Tests/Server/Utils/AI/RemediationExecutionRunner.test.ts +252 -3
  371. package/Tests/Server/Utils/AI/RemediationExecutionRunnerClusterMode.test.ts +2 -0
  372. package/Tests/Server/Utils/AI/RemediationExecutionRunnerProjectGates.test.ts +240 -0
  373. package/Tests/Server/Utils/AI/RemediationExecutionRunnerResourceMode.test.ts +1249 -0
  374. package/Tests/Server/Utils/AI/RemediationKubectlCopyParity.test.ts +2 -0
  375. package/Tests/Server/Utils/AI/RemediationPlanRunner.test.ts +117 -0
  376. package/Tests/Server/Utils/AI/RemediationResourceCopyParity.test.ts +463 -0
  377. package/Tests/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.test.ts +722 -0
  378. package/Tests/Server/Utils/AI/ResourceAccess/ResourceAccessContext.test.ts +266 -0
  379. package/Tests/Server/Utils/AI/ResourceAccess/ResourceAiAccessSettings.test.ts +1220 -0
  380. package/Tests/Server/Utils/AI/ResourceAccess/ResourceAiDeleteCleanup.test.ts +569 -0
  381. package/Tests/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.test.ts +830 -0
  382. package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutor.test.ts +2 -0
  383. package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutorResource.test.ts +717 -0
  384. package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutorUnknownRun.test.ts +2 -0
  385. package/Tests/Server/Utils/AutoRemediation/CommandPlanVerification.test.ts +2 -0
  386. package/Tests/Server/Utils/AutoRemediation/RemediationVerifierResourceFollowUp.test.ts +338 -0
  387. package/Tests/Server/Utils/Monitor/Criteria/SessionReplayBudgetTemplateCriteria.test.ts +422 -0
  388. package/Tests/Server/Utils/SessionReplay/SessionReplayBudgetMetrics.test.ts +1647 -0
  389. package/Tests/Server/Utils/SessionReplay/SessionReplayUsage.test.ts +143 -1
  390. package/Tests/Server/Utils/Telemetry/HostAssetAttributesFromOtlp.test.ts +68 -0
  391. package/Tests/Server/Utils/Telemetry/InventoryMirrorPostgres.test.ts +370 -0
  392. package/Tests/Server/Utils/Telemetry/NetworkDeviceInventoryAttributes.test.ts +522 -0
  393. package/Tests/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.test.ts +155 -0
  394. package/Tests/Server/Utils/Telemetry/ProxmoxNativeNodeLiveness.test.ts +8631 -0
  395. package/Tests/Server/Utils/Telemetry/ProxmoxNativePush.test.ts +2852 -0
  396. package/Tests/Server/Utils/Telemetry/TelemetryEntity.test.ts +367 -1
  397. package/Tests/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.test.ts +75 -3
  398. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsAccountNotLinked.test.ts +1093 -0
  399. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsActivityDeduplicator.test.ts +1049 -0
  400. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCardChoices.test.ts +1676 -0
  401. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateCards.test.ts +2884 -0
  402. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateCommands.test.ts +2490 -0
  403. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateSubmit.test.ts +2293 -0
  404. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateSubmitServerTimezone.test.ts +386 -0
  405. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsMessageSize.test.ts +1477 -0
  406. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsReplies.test.ts +1967 -0
  407. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsStripHtmlTags.test.ts +92 -0
  408. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsSubmittedFormRemoval.test.ts +1819 -0
  409. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsTimezone.test.ts +1033 -0
  410. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsTimezoneServerZone.test.ts +610 -0
  411. package/Tests/Server/Utils/Workspace/MicrosoftTeamsBotMessageHandling.test.ts +2610 -0
  412. package/Tests/Server/Utils/Workspace/MicrosoftTeamsChats.test.ts +25 -0
  413. package/Tests/Server/Utils/Workspace/MicrosoftTeamsCreateCommandsEndToEnd.test.ts +4672 -0
  414. package/Tests/Server/Utils/Workspace/MicrosoftTeamsGroupChatNames.test.ts +3119 -0
  415. package/Tests/Server/Utils/Workspace/MicrosoftTeamsGroupChatNamesPostgres.test.ts +1721 -0
  416. package/Tests/Server/Utils/Workspace/WorkspaceCreateProjectReferences.test.ts +190 -65
  417. package/Tests/Types/AutoRemediation/AiRemediationCommandPlan.test.ts +10 -4
  418. package/Tests/Types/AutoRemediation/AiRemediationCommandPlanResourceCommand.test.ts +305 -0
  419. package/Tests/Types/Kubernetes/KubernetesAgentChartAiAccess.test.ts +581 -113
  420. package/Tests/Types/Kubernetes/KubernetesAiAgentAccessContract.test.ts +510 -0
  421. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCatalog.test.ts +277 -13
  422. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationUtil.test.ts +113 -0
  423. package/Tests/Types/Monitor/RumAlertTemplates.test.ts +773 -2
  424. package/Tests/Types/ResourceAiAgent/AiResourceType.test.ts +419 -0
  425. package/Tests/Types/ResourceAiAgent/ResourceAiAccess.test.ts +517 -0
  426. package/Tests/Types/Runbook/RunbookStepType.test.ts +147 -8
  427. package/Tests/Types/Team/ComplianceRule.test.ts +1029 -0
  428. package/Tests/Types/Team/TeamComplianceStatus.test.ts +176 -0
  429. package/Tests/UI/Components/ActionButton/RowActions.test.tsx +641 -0
  430. package/Tests/UI/Components/ActionButton/RowActionsAccessibility.test.tsx +414 -0
  431. package/Tests/UI/Components/ActionButton/SplitActionButtons.test.ts +565 -0
  432. package/Tests/UI/Components/Charts/BarChartDragToSelect.test.tsx +386 -0
  433. package/Tests/UI/Components/Charts/ChartDoubleClickResetWithoutDblclick.test.tsx +1025 -0
  434. package/Tests/UI/Components/Charts/ChartGroupPageZoomHint.test.tsx +196 -0
  435. package/Tests/UI/Components/Charts/ChartPlaceholdersTakeDoubleClick.test.tsx +1861 -0
  436. package/Tests/UI/Components/Charts/ChartPlotClicksWhileResetArmed.test.tsx +382 -0
  437. package/Tests/UI/Components/Charts/ChartRangeSelection.test.tsx +704 -0
  438. package/Tests/UI/Components/Charts/ChartRangeSelectionDoubleClickReset.test.tsx +1481 -0
  439. package/Tests/UI/Components/Charts/ChartRangeSelectionRealRecharts.test.tsx +918 -0
  440. package/Tests/UI/Components/Charts/ChartRowBucketStart.test.ts +350 -0
  441. package/Tests/UI/Components/Charts/DoubleClickReset.test.tsx +996 -0
  442. package/Tests/UI/Components/Charts/HistogramDoubleClickResetRealRecharts.test.tsx +965 -0
  443. package/Tests/UI/Components/Charts/HistogramDriftThenRefetch.test.tsx +277 -0
  444. package/Tests/UI/Components/Charts/HistogramRangeSelectionDataChange.test.tsx +1757 -0
  445. package/Tests/UI/Components/Charts/HistogramRangeSelectionRealRecharts.test.tsx +560 -0
  446. package/Tests/UI/Components/Charts/TimeRangeZoom/ChartPageTimeRangeZoom.test.tsx +513 -0
  447. package/Tests/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomContext.test.tsx +845 -0
  448. package/Tests/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHint.test.tsx +119 -0
  449. package/Tests/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHintTailwind.test.tsx +274 -0
  450. package/Tests/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomUtil.test.ts +433 -0
  451. package/Tests/UI/Components/Charts/TimeRangeZoom/UseTimeRangeZoom.test.tsx +863 -0
  452. package/Tests/UI/Components/Charts/TimeRangeZoom/ZoomDocsPromises.test.tsx +1147 -0
  453. package/Tests/UI/Components/DisabledButtonTooltip.test.tsx +14 -3
  454. package/Tests/UI/Components/EntityDropdownEscape.test.tsx +454 -0
  455. package/Tests/UI/Components/EntityDropdownFocusLeave.test.tsx +420 -0
  456. package/Tests/UI/Components/Forms/FormFieldDropdownDisabled.test.tsx +233 -0
  457. package/Tests/UI/Components/Input.test.tsx +80 -1
  458. package/Tests/UI/Components/LogsAnalyticsViewZoom.test.tsx +947 -0
  459. package/Tests/UI/Components/LogsHistogramDragTooltip.test.tsx +17 -5
  460. package/Tests/UI/Components/LogsViewerAnalyticsZoom.test.tsx +501 -0
  461. package/Tests/UI/Components/LogsViewerHistogramZoom.test.tsx +1 -1
  462. package/Tests/UI/Components/ModelTable/BaseModelTableBulkDelete.test.tsx +6 -4
  463. package/Tests/UI/Components/ModelTable/BaseModelTablePermissionGating.test.tsx +60 -8
  464. package/Tests/UI/Components/ModelTable/BaseModelTableRowActions.test.tsx +476 -0
  465. package/Tests/UI/Components/ModelTable/ModelTableWrapContent.test.tsx +7 -5
  466. package/Tests/UI/Components/MoreMenuPortal.test.tsx +623 -0
  467. package/Tests/UI/Components/StatusPage/ResourceGridActions.test.tsx +538 -0
  468. package/Tests/UI/Components/StatusPage/ResourceGridSelection.test.tsx +14 -4
  469. package/Tests/UI/Components/TableCellWrapping.test.tsx +3 -3
  470. package/Tests/UI/Components/TableRowActions.test.tsx +472 -0
  471. package/Tests/UI/Components/TelemetryHistogramDragTooltip.test.tsx +1 -1
  472. package/Tests/UI/Components/TelemetryViewer/TelemetryViewerHistogramClickZoom.test.tsx +1 -1
  473. package/Tests/UI/Components/TelemetryViewer/TelemetryViewerZoomScope.test.tsx +470 -0
  474. package/Tests/UI/Components/TelemetryViewer/UseViewerTimeRangeZoom.test.tsx +571 -0
  475. package/Tests/UI/Components/TelemetryViewer/ViewerDoubleClickResetUnderDataChange.test.tsx +928 -0
  476. package/Tests/UI/Components/TelemetryViewer/ViewerFollowsEnclosingZoom.test.tsx +1569 -0
  477. package/Tests/UI/Components/Toggle.test.tsx +66 -0
  478. package/Tests/UI/MicrosoftTeams/MicrosoftTeamsChatsCardRefreshNames.test.tsx +1023 -0
  479. package/Tests/UI/Rum/ChunkLoader.test.ts +201 -0
  480. package/Tests/UI/Rum/FidelityNotices.test.ts +54 -0
  481. package/Tests/UI/Rum/RecordingHealthDashboard.test.tsx +769 -1
  482. package/Tests/UI/Rum/ReplayCorrelationPanel.test.tsx +72 -0
  483. package/Tests/UI/Rum/ReplayFrameCapture.test.ts +1009 -9
  484. package/Tests/UI/Rum/ReplayRecordedAssets.test.ts +1069 -0
  485. package/Tests/UI/Rum/ReplayStage.test.tsx +913 -2
  486. package/Tests/UI/Rum/SessionReplayTable.test.tsx +443 -8
  487. package/Tests/UI/Rum/SessionReplayUsersTable.test.tsx +439 -9
  488. package/Tests/UI/Rum/UserFlowTablesRowActions.test.tsx +501 -0
  489. package/Tests/Utils/AiRemediation/KubectlPolicyChartRbacParity.test.ts +47 -19
  490. package/Tests/Utils/AiRemediation/KubectlWriteScopeCallerParity.test.ts +2 -0
  491. package/Tests/Utils/AiRemediation/KubernetesAiAgentPolicyCopyParity.test.ts +396 -0
  492. package/Tests/Utils/AiRemediation/Resource/CephCommandPolicy.test.ts +1653 -0
  493. package/Tests/Utils/AiRemediation/Resource/CephOutputRedaction.test.ts +204 -0
  494. package/Tests/Utils/AiRemediation/Resource/DatabaseCommandPolicy.test.ts +1077 -0
  495. package/Tests/Utils/AiRemediation/Resource/DatabaseDiagnosticCatalog.test.ts +558 -0
  496. package/Tests/Utils/AiRemediation/Resource/DatabaseQueryRedactor.test.ts +834 -0
  497. package/Tests/Utils/AiRemediation/Resource/DockerCliGrammar.test.ts +747 -0
  498. package/Tests/Utils/AiRemediation/Resource/DockerEngineCommandPolicy.test.ts +1259 -0
  499. package/Tests/Utils/AiRemediation/Resource/DockerOutputRedaction.test.ts +386 -0
  500. package/Tests/Utils/AiRemediation/Resource/DockerSwarmCommandPolicy.test.ts +782 -0
  501. package/Tests/Utils/AiRemediation/Resource/GovcCommandPolicy.test.ts +2259 -0
  502. package/Tests/Utils/AiRemediation/Resource/HostCommandPolicy.test.ts +2019 -0
  503. package/Tests/Utils/AiRemediation/Resource/ProxmoxCommandPolicy.test.ts +2497 -0
  504. package/Tests/Utils/AiRemediation/Resource/ResourceCommandPolicy.test.ts +1305 -0
  505. package/Tests/Utils/AiRemediation/Resource/ResourceCommandPolicyCore.test.ts +585 -0
  506. package/Tests/Utils/AiRemediation/Resource/ResourceOutputRedactor.test.ts +334 -0
  507. package/Tests/Utils/AiRemediation/Resource/ResourceOutputRedactorCopyParity.test.ts +98 -0
  508. package/Tests/Utils/AiRemediation/Resource/ResourcePolicyImportClosure.test.ts +391 -0
  509. package/Tests/Utils/AiRemediation/ResourceAiAgentPolicyCopyParity.test.ts +497 -0
  510. package/Tests/Utils/Dashboard/DashboardTimeRangeZoom.test.ts +104 -1
  511. package/Tests/Utils/SessionReplay/SessionReplayBudgetMetricType.test.ts +383 -0
  512. package/Types/AI/AIRunType.ts +9 -4
  513. package/Types/AI/InvestigationNotStartedReason.ts +6 -0
  514. package/Types/AI/ResourceAiAccessApi.ts +140 -0
  515. package/Types/AI/ResourceAiAccessPermissions.ts +126 -0
  516. package/Types/AutoRemediation/AiRemediationCommandPlan.ts +197 -18
  517. package/Types/AutoRemediation/AiRemediationCommandPolicyVerdict.ts +28 -0
  518. package/Types/Dashboard/DashboardComponents/DashboardTraceChartComponent.ts +4 -2
  519. package/Types/Kubernetes/KubernetesClusterAiAccess.ts +263 -32
  520. package/Types/Kubernetes/KubernetesClusterAiAccessPermissions.ts +20 -16
  521. package/Types/Kubernetes/KubernetesClusterAiInsights.ts +81 -0
  522. package/Types/Monitor/ProxmoxAlertTemplates.ts +4 -4
  523. package/Types/Monitor/Recommendation/MonitorRecommendationCatalog.ts +55 -22
  524. package/Types/Monitor/Recommendation/MonitorRecommendationTypes.ts +35 -3
  525. package/Types/Monitor/RumAlertTemplates.ts +351 -4
  526. package/Types/ResourceAiAgent/AiResourceType.ts +310 -0
  527. package/Types/ResourceAiAgent/ResourceAiAccess.ts +574 -0
  528. package/Types/Rum/SessionReplayBudgetMetricType.ts +47 -0
  529. package/Types/Runbook/RunbookStepType.ts +29 -0
  530. package/Types/Team/ComplianceNotificationChannel.ts +22 -0
  531. package/Types/Team/ComplianceRule.ts +434 -0
  532. package/Types/Team/ComplianceRuleType.ts +21 -0
  533. package/Types/Team/TeamComplianceStatus.ts +81 -0
  534. package/Types/Telemetry/TelemetryIngestSurface.ts +40 -0
  535. package/UI/Components/ActionButton/ActionButtonSchema.ts +21 -0
  536. package/UI/Components/ActionButton/RowActions.tsx +238 -0
  537. package/UI/Components/ActionButton/SplitActionButtons.ts +173 -0
  538. package/UI/Components/Charts/Area/AreaChart.tsx +32 -2
  539. package/UI/Components/Charts/Bar/BarChart.tsx +40 -3
  540. package/UI/Components/Charts/ChartGroup/ChartGroup.tsx +37 -11
  541. package/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.tsx +80 -243
  542. package/UI/Components/Charts/ChartLibrary/BarChart/BarChart.tsx +122 -31
  543. package/UI/Components/Charts/ChartLibrary/LineChart/LineChart.tsx +95 -244
  544. package/UI/Components/Charts/ChartLibrary/Utils/DoubleClick.ts +214 -0
  545. package/UI/Components/Charts/ChartLibrary/Utils/UseChartBucketsChange.ts +32 -0
  546. package/UI/Components/Charts/ChartLibrary/Utils/UseChartRangeSelection.ts +599 -0
  547. package/UI/Components/Charts/Line/LineChart.tsx +32 -2
  548. package/UI/Components/Charts/TimeRangeZoom/ResetTimeRangeZoomButton.tsx +70 -0
  549. package/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomContext.tsx +226 -0
  550. package/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHint.tsx +73 -0
  551. package/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomUtil.ts +163 -0
  552. package/UI/Components/Charts/TimeRangeZoom/UseTimeRangeZoom.ts +215 -0
  553. package/UI/Components/Charts/Utils/DataPoint.ts +20 -8
  554. package/UI/Components/Charts/Utils/XAxis.ts +75 -0
  555. package/UI/Components/Charts/Utils/useHistogramRangeSelection.ts +493 -59
  556. package/UI/Components/EntityDropdown/EntityDropdown.tsx +107 -11
  557. package/UI/Components/Forms/Fields/FormField.tsx +10 -0
  558. package/UI/Components/Input/Input.tsx +90 -57
  559. package/UI/Components/List/ListRow.tsx +8 -74
  560. package/UI/Components/LogsViewer/LogsViewer.tsx +40 -11
  561. package/UI/Components/LogsViewer/components/LogTimeRangePicker.tsx +22 -6
  562. package/UI/Components/LogsViewer/components/LogsAnalyticsView.tsx +209 -6
  563. package/UI/Components/LogsViewer/components/LogsHistogram.tsx +127 -84
  564. package/UI/Components/LogsViewer/components/LogsViewerToolbar.tsx +3 -0
  565. package/UI/Components/ModelTable/BaseModelTable.tsx +12 -1
  566. package/UI/Components/MoreMenu/MoreMenu.tsx +365 -30
  567. package/UI/Components/MoreMenu/MoreMenuItem.tsx +70 -17
  568. package/UI/Components/OrderedStatesList/Item.tsx +7 -72
  569. package/UI/Components/StatusPage/ResourceGrid.tsx +126 -77
  570. package/UI/Components/Table/TableBody.tsx +8 -2
  571. package/UI/Components/Table/TableRow.tsx +20 -140
  572. package/UI/Components/TelemetryViewer/TelemetryViewer.tsx +41 -10
  573. package/UI/Components/TelemetryViewer/components/TelemetryHistogram.tsx +47 -9
  574. package/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.tsx +25 -6
  575. package/UI/Components/TelemetryViewer/types.ts +2 -0
  576. package/UI/Components/TelemetryViewer/useViewerTimeRangeZoom.ts +448 -0
  577. package/UI/Components/Toggle/Toggle.tsx +26 -0
  578. package/UI/Components/Tooltip/Tooltip.tsx +8 -1
  579. package/UI/Styles/Theme.css +14 -2
  580. package/Utils/AI/InvestigationReport.ts +121 -15
  581. package/Utils/AiRemediation/CommandPolicy.ts +1 -1
  582. package/Utils/AiRemediation/KubectlPolicy.ts +1 -1
  583. package/Utils/AiRemediation/Resource/CephCommandPolicy.ts +1936 -0
  584. package/Utils/AiRemediation/Resource/DatabaseCommandPolicy.ts +166 -0
  585. package/Utils/AiRemediation/Resource/DatabaseDiagnosticCatalog.ts +1532 -0
  586. package/Utils/AiRemediation/Resource/DatabaseQueryRedactor.ts +1394 -0
  587. package/Utils/AiRemediation/Resource/DockerCliGrammar.ts +1839 -0
  588. package/Utils/AiRemediation/Resource/DockerEngineCommandPolicy.ts +490 -0
  589. package/Utils/AiRemediation/Resource/DockerSwarmCommandPolicy.ts +687 -0
  590. package/Utils/AiRemediation/Resource/GovcCommandPolicy.ts +2096 -0
  591. package/Utils/AiRemediation/Resource/HostCommandPolicy.ts +2982 -0
  592. package/Utils/AiRemediation/Resource/ProxmoxCommandPolicy.ts +1679 -0
  593. package/Utils/AiRemediation/Resource/ResourceCommandPolicy.ts +851 -0
  594. package/Utils/AiRemediation/Resource/ResourceCommandPolicyCore.ts +593 -0
  595. package/Utils/AiRemediation/Resource/ResourceOutputRedactor.ts +2812 -0
  596. package/Utils/Dashboard/DashboardTimeRangeZoom.ts +46 -2
  597. package/Utils/SessionReplay/SessionReplayBudgetMetricType.ts +184 -0
  598. package/build/dist/Models/DatabaseModels/AutoRemediationSuggestion.js +62 -0
  599. package/build/dist/Models/DatabaseModels/AutoRemediationSuggestion.js.map +1 -1
  600. package/build/dist/Models/DatabaseModels/CephCluster.js +219 -0
  601. package/build/dist/Models/DatabaseModels/CephCluster.js.map +1 -1
  602. package/build/dist/Models/DatabaseModels/DatabaseServer.js +219 -0
  603. package/build/dist/Models/DatabaseModels/DatabaseServer.js.map +1 -1
  604. package/build/dist/Models/DatabaseModels/DockerHost.js +219 -0
  605. package/build/dist/Models/DatabaseModels/DockerHost.js.map +1 -1
  606. package/build/dist/Models/DatabaseModels/DockerSwarmCluster.js +219 -0
  607. package/build/dist/Models/DatabaseModels/DockerSwarmCluster.js.map +1 -1
  608. package/build/dist/Models/DatabaseModels/GlobalConfig.js +1 -1
  609. package/build/dist/Models/DatabaseModels/GlobalConfig.js.map +1 -1
  610. package/build/dist/Models/DatabaseModels/Host.js +219 -0
  611. package/build/dist/Models/DatabaseModels/Host.js.map +1 -1
  612. package/build/dist/Models/DatabaseModels/Index.js +4 -0
  613. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  614. package/build/dist/Models/DatabaseModels/KubernetesAiAgent.js +385 -0
  615. package/build/dist/Models/DatabaseModels/KubernetesAiAgent.js.map +1 -0
  616. package/build/dist/Models/DatabaseModels/KubernetesCluster.js +3 -3
  617. package/build/dist/Models/DatabaseModels/KubernetesCluster.js.map +1 -1
  618. package/build/dist/Models/DatabaseModels/PodmanHost.js +219 -0
  619. package/build/dist/Models/DatabaseModels/PodmanHost.js.map +1 -1
  620. package/build/dist/Models/DatabaseModels/Project.js +56 -5
  621. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  622. package/build/dist/Models/DatabaseModels/ProxmoxCluster.js +219 -0
  623. package/build/dist/Models/DatabaseModels/ProxmoxCluster.js.map +1 -1
  624. package/build/dist/Models/DatabaseModels/ProxmoxResource.js +51 -1
  625. package/build/dist/Models/DatabaseModels/ProxmoxResource.js.map +1 -1
  626. package/build/dist/Models/DatabaseModels/ResourceAiAgent.js +439 -0
  627. package/build/dist/Models/DatabaseModels/ResourceAiAgent.js.map +1 -0
  628. package/build/dist/Models/DatabaseModels/RunnerJob.js +219 -0
  629. package/build/dist/Models/DatabaseModels/RunnerJob.js.map +1 -1
  630. package/build/dist/Models/DatabaseModels/TeamComplianceSetting.js +134 -3
  631. package/build/dist/Models/DatabaseModels/TeamComplianceSetting.js.map +1 -1
  632. package/build/dist/Models/DatabaseModels/VMwareVCenter.js +219 -0
  633. package/build/dist/Models/DatabaseModels/VMwareVCenter.js.map +1 -1
  634. package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js.map +1 -1
  635. package/build/dist/Server/API/AIChatAPI.js +6 -1
  636. package/build/dist/Server/API/AIChatAPI.js.map +1 -1
  637. package/build/dist/Server/API/AIInvestigationAPI.js +17 -10
  638. package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
  639. package/build/dist/Server/API/AutoRemediationAPI.js +374 -24
  640. package/build/dist/Server/API/AutoRemediationAPI.js.map +1 -1
  641. package/build/dist/Server/API/KubernetesClusterAiAccessAPI.js +436 -22
  642. package/build/dist/Server/API/KubernetesClusterAiAccessAPI.js.map +1 -1
  643. package/build/dist/Server/API/MicrosoftTeamsAPI.js +69 -13
  644. package/build/dist/Server/API/MicrosoftTeamsAPI.js.map +1 -1
  645. package/build/dist/Server/API/ProxmoxResourceAPI.js +187 -14
  646. package/build/dist/Server/API/ProxmoxResourceAPI.js.map +1 -1
  647. package/build/dist/Server/API/ResourceAiAccessAPI.js +1119 -0
  648. package/build/dist/Server/API/ResourceAiAccessAPI.js.map +1 -0
  649. package/build/dist/Server/Infrastructure/GlobalCache.js +27 -0
  650. package/build/dist/Server/Infrastructure/GlobalCache.js.map +1 -1
  651. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796000000000-AddTeamComplianceRuleScope.js +50 -0
  652. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796000000000-AddTeamComplianceRuleScope.js.map +1 -0
  653. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796100000000-AddKubernetesAiAgentAndAiDefaults.js +84 -0
  654. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796100000000-AddKubernetesAiAgentAndAiDefaults.js.map +1 -0
  655. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796200000000-AddProxmoxResourceNativePushColumns.js +31 -0
  656. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796200000000-AddProxmoxResourceNativePushColumns.js.map +1 -0
  657. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796300000000-AddResourceAiAgents.js +168 -0
  658. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796300000000-AddResourceAiAgents.js.map +1 -0
  659. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +8 -0
  660. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  661. package/build/dist/Server/Infrastructure/Semaphore.js +6 -0
  662. package/build/dist/Server/Infrastructure/Semaphore.js.map +1 -1
  663. package/build/dist/Server/Middleware/TelemetryIngest.js +41 -19
  664. package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
  665. package/build/dist/Server/Services/AIService.js +59 -1
  666. package/build/dist/Server/Services/AIService.js.map +1 -1
  667. package/build/dist/Server/Services/AlertService.js +248 -13
  668. package/build/dist/Server/Services/AlertService.js.map +1 -1
  669. package/build/dist/Server/Services/AlertSeverityService.js +51 -15
  670. package/build/dist/Server/Services/AlertSeverityService.js.map +1 -1
  671. package/build/dist/Server/Services/AnalyticsDatabaseService.js +26 -1
  672. package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
  673. package/build/dist/Server/Services/AutoRemediationRuleEngineService.js +601 -3
  674. package/build/dist/Server/Services/AutoRemediationRuleEngineService.js.map +1 -1
  675. package/build/dist/Server/Services/AutoRemediationRuleService.js +1 -1
  676. package/build/dist/Server/Services/AutoRemediationRuleService.js.map +1 -1
  677. package/build/dist/Server/Services/CephClusterService.js +104 -0
  678. package/build/dist/Server/Services/CephClusterService.js.map +1 -1
  679. package/build/dist/Server/Services/DatabaseServerService.js +99 -0
  680. package/build/dist/Server/Services/DatabaseServerService.js.map +1 -1
  681. package/build/dist/Server/Services/DockerHostService.js +104 -0
  682. package/build/dist/Server/Services/DockerHostService.js.map +1 -1
  683. package/build/dist/Server/Services/DockerSwarmClusterService.js +104 -0
  684. package/build/dist/Server/Services/DockerSwarmClusterService.js.map +1 -1
  685. package/build/dist/Server/Services/HostService.js +114 -2
  686. package/build/dist/Server/Services/HostService.js.map +1 -1
  687. package/build/dist/Server/Services/IncidentService.js +199 -72
  688. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  689. package/build/dist/Server/Services/IncidentSeverityService.js +51 -15
  690. package/build/dist/Server/Services/IncidentSeverityService.js.map +1 -1
  691. package/build/dist/Server/Services/KubernetesAiAgentJobService.js +158 -0
  692. package/build/dist/Server/Services/KubernetesAiAgentJobService.js.map +1 -0
  693. package/build/dist/Server/Services/KubernetesAiAgentService.js +1145 -0
  694. package/build/dist/Server/Services/KubernetesAiAgentService.js.map +1 -0
  695. package/build/dist/Server/Services/KubernetesClusterAiAccessService.js +842 -371
  696. package/build/dist/Server/Services/KubernetesClusterAiAccessService.js.map +1 -1
  697. package/build/dist/Server/Services/KubernetesClusterService.js +86 -17
  698. package/build/dist/Server/Services/KubernetesClusterService.js.map +1 -1
  699. package/build/dist/Server/Services/MetricRecordingRuleService.js +46 -0
  700. package/build/dist/Server/Services/MetricRecordingRuleService.js.map +1 -1
  701. package/build/dist/Server/Services/PodmanHostService.js +104 -0
  702. package/build/dist/Server/Services/PodmanHostService.js.map +1 -1
  703. package/build/dist/Server/Services/ProjectService.js +22 -0
  704. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  705. package/build/dist/Server/Services/ProxmoxClusterService.js +104 -0
  706. package/build/dist/Server/Services/ProxmoxClusterService.js.map +1 -1
  707. package/build/dist/Server/Services/ProxmoxResourceService.js +258 -3
  708. package/build/dist/Server/Services/ProxmoxResourceService.js.map +1 -1
  709. package/build/dist/Server/Services/ResourceAiAccessService.js +1028 -0
  710. package/build/dist/Server/Services/ResourceAiAccessService.js.map +1 -0
  711. package/build/dist/Server/Services/ResourceAiAgentJobService.js +173 -0
  712. package/build/dist/Server/Services/ResourceAiAgentJobService.js.map +1 -0
  713. package/build/dist/Server/Services/ResourceAiAgentService.js +1687 -0
  714. package/build/dist/Server/Services/ResourceAiAgentService.js.map +1 -0
  715. package/build/dist/Server/Services/RunnerJobService.js +522 -97
  716. package/build/dist/Server/Services/RunnerJobService.js.map +1 -1
  717. package/build/dist/Server/Services/RunnerService.js +1 -1
  718. package/build/dist/Server/Services/RunnerService.js.map +1 -1
  719. package/build/dist/Server/Services/ScheduledMaintenanceService.js +535 -3
  720. package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
  721. package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js +316 -46
  722. package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js.map +1 -1
  723. package/build/dist/Server/Services/TeamComplianceSettingService.js +833 -7
  724. package/build/dist/Server/Services/TeamComplianceSettingService.js.map +1 -1
  725. package/build/dist/Server/Services/TelemetryUsageBillingService.js +26 -0
  726. package/build/dist/Server/Services/TelemetryUsageBillingService.js.map +1 -1
  727. package/build/dist/Server/Services/TraceRecordingRuleService.js +37 -0
  728. package/build/dist/Server/Services/TraceRecordingRuleService.js.map +1 -1
  729. package/build/dist/Server/Services/VMwareVCenterService.js +104 -0
  730. package/build/dist/Server/Services/VMwareVCenterService.js.map +1 -1
  731. package/build/dist/Server/Utils/AI/ClusterAccess/ClusterAccessContext.js +52 -9
  732. package/build/dist/Server/Utils/AI/ClusterAccess/ClusterAccessContext.js.map +1 -1
  733. package/build/dist/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.js +13 -9
  734. package/build/dist/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.js.map +1 -1
  735. package/build/dist/Server/Utils/AI/ClusterAccess/KubectlJobRunner.js +7 -3
  736. package/build/dist/Server/Utils/AI/ClusterAccess/KubectlJobRunner.js.map +1 -1
  737. package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js +1056 -43
  738. package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js.map +1 -1
  739. package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js +683 -42
  740. package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js.map +1 -1
  741. package/build/dist/Server/Utils/AI/Remediation/RemediationPlanRunner.js +21 -1
  742. package/build/dist/Server/Utils/AI/Remediation/RemediationPlanRunner.js.map +1 -1
  743. package/build/dist/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.js +330 -0
  744. package/build/dist/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.js.map +1 -0
  745. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAccessContext.js +160 -0
  746. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAccessContext.js.map +1 -0
  747. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAccessToolNames.js +33 -0
  748. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAccessToolNames.js.map +1 -0
  749. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAiAccessSettings.js +640 -0
  750. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAiAccessSettings.js.map +1 -0
  751. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAiDeleteCleanup.js +226 -0
  752. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAiDeleteCleanup.js.map +1 -0
  753. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.js +600 -0
  754. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.js.map +1 -0
  755. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +89 -9
  756. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
  757. package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js +55 -4
  758. package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js.map +1 -1
  759. package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js +55 -4
  760. package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js.map +1 -1
  761. package/build/dist/Server/Utils/AI/SRE/IncidentPostmortemRunner.js +30 -3
  762. package/build/dist/Server/Utils/AI/SRE/IncidentPostmortemRunner.js.map +1 -1
  763. package/build/dist/Server/Utils/AI/SRE/InvestigationEligibility.js +13 -2
  764. package/build/dist/Server/Utils/AI/SRE/InvestigationEligibility.js.map +1 -1
  765. package/build/dist/Server/Utils/AI/SRE/InvestigationGrader.js +1 -1
  766. package/build/dist/Server/Utils/AutoRemediation/CommandPlanExecutor.js +294 -15
  767. package/build/dist/Server/Utils/AutoRemediation/CommandPlanExecutor.js.map +1 -1
  768. package/build/dist/Server/Utils/AutoRemediation/RemediationVerifier.js +29 -1
  769. package/build/dist/Server/Utils/AutoRemediation/RemediationVerifier.js.map +1 -1
  770. package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js +9 -1
  771. package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js.map +1 -1
  772. package/build/dist/Server/Utils/SessionReplay/SessionReplayBudgetMetrics.js +627 -0
  773. package/build/dist/Server/Utils/SessionReplay/SessionReplayBudgetMetrics.js.map +1 -0
  774. package/build/dist/Server/Utils/SessionReplay/SessionReplayUsage.js +60 -5
  775. package/build/dist/Server/Utils/SessionReplay/SessionReplayUsage.js.map +1 -1
  776. package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js +111 -6
  777. package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js.map +1 -1
  778. package/build/dist/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.js +40 -4
  779. package/build/dist/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.js.map +1 -1
  780. package/build/dist/Server/Utils/Telemetry/ProxmoxNativeNodeLiveness.js +296 -0
  781. package/build/dist/Server/Utils/Telemetry/ProxmoxNativeNodeLiveness.js.map +1 -0
  782. package/build/dist/Server/Utils/Telemetry/ProxmoxNativePush.js +699 -0
  783. package/build/dist/Server/Utils/Telemetry/ProxmoxNativePush.js.map +1 -0
  784. package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js +77 -19
  785. package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js.map +1 -1
  786. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.js +19 -15
  787. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.js.map +1 -1
  788. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.js +19 -15
  789. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.js.map +1 -1
  790. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Auth.js +17 -1
  791. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Auth.js.map +1 -1
  792. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js +183 -209
  793. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js.map +1 -1
  794. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.js +19 -15
  795. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.js.map +1 -1
  796. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/ScheduledMaintenance.js +233 -167
  797. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/ScheduledMaintenance.js.map +1 -1
  798. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +768 -152
  799. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
  800. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsActivityDeduplicator.js +129 -0
  801. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsActivityDeduplicator.js.map +1 -0
  802. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCardChoices.js +266 -0
  803. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCardChoices.js.map +1 -0
  804. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateCommands.js +258 -0
  805. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateCommands.js.map +1 -0
  806. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsMessageSize.js +104 -0
  807. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsMessageSize.js.map +1 -0
  808. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsReplies.js +183 -0
  809. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsReplies.js.map +1 -0
  810. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsTimezone.js +123 -0
  811. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsTimezone.js.map +1 -0
  812. package/build/dist/Types/AI/AIRunType.js +9 -4
  813. package/build/dist/Types/AI/AIRunType.js.map +1 -1
  814. package/build/dist/Types/AI/ResourceAiAccessApi.js +30 -0
  815. package/build/dist/Types/AI/ResourceAiAccessApi.js.map +1 -0
  816. package/build/dist/Types/AI/ResourceAiAccessPermissions.js +98 -0
  817. package/build/dist/Types/AI/ResourceAiAccessPermissions.js.map +1 -0
  818. package/build/dist/Types/AutoRemediation/AiRemediationCommandPlan.js +126 -45
  819. package/build/dist/Types/AutoRemediation/AiRemediationCommandPlan.js.map +1 -1
  820. package/build/dist/Types/AutoRemediation/AiRemediationCommandPolicyVerdict.js +28 -0
  821. package/build/dist/Types/AutoRemediation/AiRemediationCommandPolicyVerdict.js.map +1 -0
  822. package/build/dist/Types/Kubernetes/KubernetesClusterAiAccess.js +72 -16
  823. package/build/dist/Types/Kubernetes/KubernetesClusterAiAccess.js.map +1 -1
  824. package/build/dist/Types/Kubernetes/KubernetesClusterAiAccessPermissions.js +20 -16
  825. package/build/dist/Types/Kubernetes/KubernetesClusterAiAccessPermissions.js.map +1 -1
  826. package/build/dist/Types/Kubernetes/KubernetesClusterAiInsights.js +17 -0
  827. package/build/dist/Types/Kubernetes/KubernetesClusterAiInsights.js.map +1 -0
  828. package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js +4 -4
  829. package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js.map +1 -1
  830. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js +47 -21
  831. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js.map +1 -1
  832. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js +5 -0
  833. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js.map +1 -1
  834. package/build/dist/Types/Monitor/RumAlertTemplates.js +199 -3
  835. package/build/dist/Types/Monitor/RumAlertTemplates.js.map +1 -1
  836. package/build/dist/Types/ResourceAiAgent/AiResourceType.js +242 -0
  837. package/build/dist/Types/ResourceAiAgent/AiResourceType.js.map +1 -0
  838. package/build/dist/Types/ResourceAiAgent/ResourceAiAccess.js +275 -0
  839. package/build/dist/Types/ResourceAiAgent/ResourceAiAccess.js.map +1 -0
  840. package/build/dist/Types/Rum/SessionReplayBudgetMetricType.js +45 -0
  841. package/build/dist/Types/Rum/SessionReplayBudgetMetricType.js.map +1 -0
  842. package/build/dist/Types/Runbook/RunbookStepType.js +27 -0
  843. package/build/dist/Types/Runbook/RunbookStepType.js.map +1 -1
  844. package/build/dist/Types/Team/ComplianceNotificationChannel.js +23 -0
  845. package/build/dist/Types/Team/ComplianceNotificationChannel.js.map +1 -0
  846. package/build/dist/Types/Team/ComplianceRule.js +304 -0
  847. package/build/dist/Types/Team/ComplianceRule.js.map +1 -0
  848. package/build/dist/Types/Team/ComplianceRuleType.js +21 -0
  849. package/build/dist/Types/Team/ComplianceRuleType.js.map +1 -1
  850. package/build/dist/Types/Team/TeamComplianceStatus.js +2 -0
  851. package/build/dist/Types/Team/TeamComplianceStatus.js.map +1 -0
  852. package/build/dist/Types/Telemetry/TelemetryIngestSurface.js +36 -0
  853. package/build/dist/Types/Telemetry/TelemetryIngestSurface.js.map +1 -1
  854. package/build/dist/UI/Components/ActionButton/ActionButtonSchema.js +20 -1
  855. package/build/dist/UI/Components/ActionButton/ActionButtonSchema.js.map +1 -1
  856. package/build/dist/UI/Components/ActionButton/RowActions.js +113 -0
  857. package/build/dist/UI/Components/ActionButton/RowActions.js.map +1 -0
  858. package/build/dist/UI/Components/ActionButton/SplitActionButtons.js +71 -0
  859. package/build/dist/UI/Components/ActionButton/SplitActionButtons.js.map +1 -0
  860. package/build/dist/UI/Components/Charts/Area/AreaChart.js +16 -1
  861. package/build/dist/UI/Components/Charts/Area/AreaChart.js.map +1 -1
  862. package/build/dist/UI/Components/Charts/Bar/BarChart.js +16 -1
  863. package/build/dist/UI/Components/Charts/Bar/BarChart.js.map +1 -1
  864. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js +27 -5
  865. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js.map +1 -1
  866. package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js +61 -194
  867. package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js.map +1 -1
  868. package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js +84 -26
  869. package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js.map +1 -1
  870. package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js +75 -196
  871. package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js.map +1 -1
  872. package/build/dist/UI/Components/Charts/ChartLibrary/Utils/DoubleClick.js +133 -0
  873. package/build/dist/UI/Components/Charts/ChartLibrary/Utils/DoubleClick.js.map +1 -1
  874. package/build/dist/UI/Components/Charts/ChartLibrary/Utils/UseChartBucketsChange.js +26 -0
  875. package/build/dist/UI/Components/Charts/ChartLibrary/Utils/UseChartBucketsChange.js.map +1 -0
  876. package/build/dist/UI/Components/Charts/ChartLibrary/Utils/UseChartRangeSelection.js +371 -0
  877. package/build/dist/UI/Components/Charts/ChartLibrary/Utils/UseChartRangeSelection.js.map +1 -0
  878. package/build/dist/UI/Components/Charts/Line/LineChart.js +16 -1
  879. package/build/dist/UI/Components/Charts/Line/LineChart.js.map +1 -1
  880. package/build/dist/UI/Components/Charts/TimeRangeZoom/ResetTimeRangeZoomButton.js +35 -0
  881. package/build/dist/UI/Components/Charts/TimeRangeZoom/ResetTimeRangeZoomButton.js.map +1 -0
  882. package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomContext.js +107 -0
  883. package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomContext.js.map +1 -0
  884. package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHint.js +41 -0
  885. package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHint.js.map +1 -0
  886. package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomUtil.js +117 -0
  887. package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomUtil.js.map +1 -0
  888. package/build/dist/UI/Components/Charts/TimeRangeZoom/UseTimeRangeZoom.js +121 -0
  889. package/build/dist/UI/Components/Charts/TimeRangeZoom/UseTimeRangeZoom.js.map +1 -0
  890. package/build/dist/UI/Components/Charts/Utils/DataPoint.js +15 -7
  891. package/build/dist/UI/Components/Charts/Utils/DataPoint.js.map +1 -1
  892. package/build/dist/UI/Components/Charts/Utils/XAxis.js +70 -0
  893. package/build/dist/UI/Components/Charts/Utils/XAxis.js.map +1 -1
  894. package/build/dist/UI/Components/Charts/Utils/useHistogramRangeSelection.js +305 -38
  895. package/build/dist/UI/Components/Charts/Utils/useHistogramRangeSelection.js.map +1 -1
  896. package/build/dist/UI/Components/EntityDropdown/EntityDropdown.js +89 -14
  897. package/build/dist/UI/Components/EntityDropdown/EntityDropdown.js.map +1 -1
  898. package/build/dist/UI/Components/Forms/Fields/FormField.js +11 -2
  899. package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
  900. package/build/dist/UI/Components/Input/Input.js +69 -54
  901. package/build/dist/UI/Components/Input/Input.js.map +1 -1
  902. package/build/dist/UI/Components/List/ListRow.js +4 -39
  903. package/build/dist/UI/Components/List/ListRow.js.map +1 -1
  904. package/build/dist/UI/Components/LogsViewer/LogsViewer.js +31 -8
  905. package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
  906. package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js +10 -1
  907. package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js.map +1 -1
  908. package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js +139 -21
  909. package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js.map +1 -1
  910. package/build/dist/UI/Components/LogsViewer/components/LogsHistogram.js +30 -8
  911. package/build/dist/UI/Components/LogsViewer/components/LogsHistogram.js.map +1 -1
  912. package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js +1 -1
  913. package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js.map +1 -1
  914. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +10 -0
  915. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  916. package/build/dist/UI/Components/MoreMenu/MoreMenu.js +253 -14
  917. package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
  918. package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js +43 -13
  919. package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js.map +1 -1
  920. package/build/dist/UI/Components/OrderedStatesList/Item.js +2 -38
  921. package/build/dist/UI/Components/OrderedStatesList/Item.js.map +1 -1
  922. package/build/dist/UI/Components/StatusPage/ResourceGrid.js +53 -15
  923. package/build/dist/UI/Components/StatusPage/ResourceGrid.js.map +1 -1
  924. package/build/dist/UI/Components/Table/TableBody.js +6 -2
  925. package/build/dist/UI/Components/Table/TableBody.js.map +1 -1
  926. package/build/dist/UI/Components/Table/TableRow.js +12 -75
  927. package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
  928. package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js +32 -7
  929. package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js.map +1 -1
  930. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js +27 -9
  931. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js.map +1 -1
  932. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js +11 -1
  933. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js.map +1 -1
  934. package/build/dist/UI/Components/TelemetryViewer/useViewerTimeRangeZoom.js +272 -0
  935. package/build/dist/UI/Components/TelemetryViewer/useViewerTimeRangeZoom.js.map +1 -0
  936. package/build/dist/UI/Components/Toggle/Toggle.js +14 -1
  937. package/build/dist/UI/Components/Toggle/Toggle.js.map +1 -1
  938. package/build/dist/UI/Components/Tooltip/Tooltip.js +1 -1
  939. package/build/dist/UI/Components/Tooltip/Tooltip.js.map +1 -1
  940. package/build/dist/Utils/AI/InvestigationReport.js +71 -11
  941. package/build/dist/Utils/AI/InvestigationReport.js.map +1 -1
  942. package/build/dist/Utils/AiRemediation/CommandPolicy.js +1 -1
  943. package/build/dist/Utils/AiRemediation/CommandPolicy.js.map +1 -1
  944. package/build/dist/Utils/AiRemediation/KubectlPolicy.js +1 -1
  945. package/build/dist/Utils/AiRemediation/KubectlPolicy.js.map +1 -1
  946. package/build/dist/Utils/AiRemediation/Resource/CephCommandPolicy.js +1462 -0
  947. package/build/dist/Utils/AiRemediation/Resource/CephCommandPolicy.js.map +1 -0
  948. package/build/dist/Utils/AiRemediation/Resource/DatabaseCommandPolicy.js +122 -0
  949. package/build/dist/Utils/AiRemediation/Resource/DatabaseCommandPolicy.js.map +1 -0
  950. package/build/dist/Utils/AiRemediation/Resource/DatabaseDiagnosticCatalog.js +1139 -0
  951. package/build/dist/Utils/AiRemediation/Resource/DatabaseDiagnosticCatalog.js.map +1 -0
  952. package/build/dist/Utils/AiRemediation/Resource/DatabaseQueryRedactor.js +1060 -0
  953. package/build/dist/Utils/AiRemediation/Resource/DatabaseQueryRedactor.js.map +1 -0
  954. package/build/dist/Utils/AiRemediation/Resource/DockerCliGrammar.js +1301 -0
  955. package/build/dist/Utils/AiRemediation/Resource/DockerCliGrammar.js.map +1 -0
  956. package/build/dist/Utils/AiRemediation/Resource/DockerEngineCommandPolicy.js +370 -0
  957. package/build/dist/Utils/AiRemediation/Resource/DockerEngineCommandPolicy.js.map +1 -0
  958. package/build/dist/Utils/AiRemediation/Resource/DockerSwarmCommandPolicy.js +498 -0
  959. package/build/dist/Utils/AiRemediation/Resource/DockerSwarmCommandPolicy.js.map +1 -0
  960. package/build/dist/Utils/AiRemediation/Resource/GovcCommandPolicy.js +1565 -0
  961. package/build/dist/Utils/AiRemediation/Resource/GovcCommandPolicy.js.map +1 -0
  962. package/build/dist/Utils/AiRemediation/Resource/HostCommandPolicy.js +2206 -0
  963. package/build/dist/Utils/AiRemediation/Resource/HostCommandPolicy.js.map +1 -0
  964. package/build/dist/Utils/AiRemediation/Resource/ProxmoxCommandPolicy.js +1129 -0
  965. package/build/dist/Utils/AiRemediation/Resource/ProxmoxCommandPolicy.js.map +1 -0
  966. package/build/dist/Utils/AiRemediation/Resource/ResourceCommandPolicy.js +565 -0
  967. package/build/dist/Utils/AiRemediation/Resource/ResourceCommandPolicy.js.map +1 -0
  968. package/build/dist/Utils/AiRemediation/Resource/ResourceCommandPolicyCore.js +408 -0
  969. package/build/dist/Utils/AiRemediation/Resource/ResourceCommandPolicyCore.js.map +1 -0
  970. package/build/dist/Utils/AiRemediation/Resource/ResourceOutputRedactor.js +1910 -0
  971. package/build/dist/Utils/AiRemediation/Resource/ResourceOutputRedactor.js.map +1 -0
  972. package/build/dist/Utils/Dashboard/DashboardTimeRangeZoom.js +27 -1
  973. package/build/dist/Utils/Dashboard/DashboardTimeRangeZoom.js.map +1 -1
  974. package/build/dist/Utils/SessionReplay/SessionReplayBudgetMetricType.js +160 -0
  975. package/build/dist/Utils/SessionReplay/SessionReplayBudgetMetricType.js.map +1 -0
  976. package/package.json +1 -1
@@ -28,18 +28,48 @@ import {
28
28
  KubernetesAiRemediationMode,
29
29
  KubernetesRunnerPosture,
30
30
  isInClusterPostureForCluster,
31
+ parseKubernetesAgentPosture,
31
32
  parseKubernetesRunnerPosture,
32
33
  } from "../../Types/Kubernetes/KubernetesClusterAiAccess";
33
34
  import RunbookCredentialType from "../../Types/Runbook/RunbookCredentialType";
34
35
  import AIRunType from "../../Types/AI/AIRunType";
35
36
  import AIRun from "../../Models/DatabaseModels/AIRun";
37
+ import KubernetesAiAgent from "../../Models/DatabaseModels/KubernetesAiAgent";
36
38
  import KubernetesCluster from "../../Models/DatabaseModels/KubernetesCluster";
37
39
  import RunbookCredential from "../../Models/DatabaseModels/RunbookCredential";
38
40
  import Runner from "../../Models/DatabaseModels/Runner";
39
41
  import AIRunService from "./AIRunService";
42
+ import KubernetesClusterAiAccessService, {
43
+ KubernetesAiAccessExecutorKind,
44
+ LoadedKubernetesAiAccessTarget,
45
+ getKubernetesAiAccessTargetId,
46
+ } from "./KubernetesClusterAiAccessService";
40
47
  import KubernetesClusterService from "./KubernetesClusterService";
41
48
  import RunbookCredentialService from "./RunbookCredentialService";
42
49
  import RunnerService, { Service as RunnerServiceClass } from "./RunnerService";
50
+ import ResourceAiAccessService, {
51
+ LoadedResourceAiAccessTarget,
52
+ ResourceAiAccessRow,
53
+ describeResourceNoun,
54
+ getResourceAiAgentInstallNextStep,
55
+ getResourceAiAgentPage,
56
+ } from "./ResourceAiAccessService";
57
+ import ResourceAiAgent from "../../Models/DatabaseModels/ResourceAiAgent";
58
+ import AiResourceType, {
59
+ AI_RESOURCE_TYPE_INFO,
60
+ AiResourceTypeInfo,
61
+ isAiResourceType,
62
+ } from "../../Types/ResourceAiAgent/AiResourceType";
63
+ import {
64
+ ResourceAiAgentPosture,
65
+ ResourceAiRemediationMode,
66
+ ResourceCommandJobPayload,
67
+ ResourceCommandTier,
68
+ parseResourceAiAgentPosture,
69
+ } from "../../Types/ResourceAiAgent/ResourceAiAccess";
70
+ import ResourceCommandPolicy from "../../Utils/AiRemediation/Resource/ResourceCommandPolicy";
71
+ import { ResourceCommandPolicyResult } from "../../Utils/AiRemediation/Resource/ResourceCommandPolicyCore";
72
+ import { redactResourceCommandOutput } from "../../Utils/AiRemediation/Resource/ResourceOutputRedactor";
43
73
  import QueryHelper from "../Types/Database/QueryHelper";
44
74
 
45
75
  /*
@@ -73,6 +103,69 @@ export const MAX_AI_COMMAND_JOBS_PER_PROJECT_PER_HOUR: number = 30;
73
103
  * ceiling, because every call spends Runner time and LLM budget.
74
104
  */
75
105
  export const MAX_AI_INVESTIGATION_COMMAND_JOBS_PER_PROJECT_PER_HOUR: number = 240;
106
+
107
+ /*
108
+ * The same two brakes for commands on infrastructure resources (Docker,
109
+ * Podman, Swarm, Proxmox, VMware, Ceph, database servers, hosts), counted
110
+ * on their own ResourceCommand rows so a busy hour on one kind of
111
+ * infrastructure never starves the cluster lane, or the other way round.
112
+ */
113
+ export const MAX_AI_INVESTIGATION_RESOURCE_COMMAND_JOBS_PER_PROJECT_PER_HOUR: number = 240;
114
+ export const MAX_AI_RESOURCE_COMMAND_JOBS_PER_PROJECT_PER_HOUR: number = 30;
115
+
116
+ /*
117
+ * Why enqueueAiResourceCommand refused a command, for callers that act on
118
+ * the reason (the remediation tools tell "the agent is read-only" from "the
119
+ * resource's fixes were turned off" from "this hour's budget is spent"):
120
+ *
121
+ * invalid_request: the call itself is malformed (type, id, origin, run).
122
+ * policy_denied: the resource command policy denies the command.
123
+ * not_read_only: an investigation asked for a command that is not Read.
124
+ * hourly_limit: the project's hourly brake for resource commands.
125
+ * resource_not_found: the resource is not this project's.
126
+ * agent_not_online: the resource has no online AI agent right now.
127
+ * agent_changed: the agent the caller named is no longer the resource's.
128
+ * switch_off: the resource's investigation or fixes switch is off.
129
+ * credential_refused: the command named a credential (agents never get one).
130
+ * agent_posture_mismatch: the agent has not reported serving this resource.
131
+ * write_scope: the agent's own posture rules the write out.
132
+ */
133
+ export type ResourceCommandEnqueueRefusalCode =
134
+ | "invalid_request"
135
+ | "policy_denied"
136
+ | "not_read_only"
137
+ | "hourly_limit"
138
+ | "resource_not_found"
139
+ | "agent_not_online"
140
+ | "agent_changed"
141
+ | "switch_off"
142
+ | "credential_refused"
143
+ | "agent_posture_mismatch"
144
+ | "write_scope";
145
+
146
+ /*
147
+ * A refusal of the resource command chokepoint. A BadDataException, so
148
+ * every caller that already handles the kubectl chokepoint's refusals
149
+ * handles this one the same way; `refusalCode` says which rule refused it.
150
+ */
151
+ export class ResourceCommandEnqueueRefusedException extends BadDataException {
152
+ public readonly refusalCode: ResourceCommandEnqueueRefusalCode;
153
+
154
+ public constructor(
155
+ refusalCode: ResourceCommandEnqueueRefusalCode,
156
+ message: string,
157
+ ) {
158
+ super(message);
159
+ this.refusalCode = refusalCode;
160
+ }
161
+ }
162
+
163
+ // The resource modes in which a remediation command may be enqueued at all.
164
+ const ENABLED_RESOURCE_REMEDIATION_MODES: Array<ResourceAiRemediationMode> = [
165
+ ResourceAiRemediationMode.RequireApproval,
166
+ ResourceAiRemediationMode.Automatic,
167
+ ResourceAiRemediationMode.BypassApproval,
168
+ ];
76
169
  import SortOrder from "../../Types/BaseDatabase/SortOrder";
77
170
  import OneUptimeDate from "../../Types/Date";
78
171
  import { JSONObject } from "../../Types/JSON";
@@ -188,7 +281,25 @@ export function describeRunnerJobTimeout(data: {
188
281
  stepType: RunbookStepType | undefined;
189
282
  claimTimeoutInMs: number;
190
283
  executionTimeoutInMs: number;
284
+ /*
285
+ * The job was for the cluster's Kubernetes AI agent
286
+ * (targetKubernetesAiAgentId) rather than a Runner, so the text names it.
287
+ */
288
+ isForKubernetesAiAgent?: boolean | undefined;
289
+ /*
290
+ * For a ResourceCommand job: the type of the resource whose AI agent
291
+ * (targetResourceAiAgentId) the command was for, so the text names that
292
+ * agent ("the Docker AI agent").
293
+ */
294
+ resourceType?: AiResourceType | null | undefined;
191
295
  }): string {
296
+ if (
297
+ data.stepType === RunbookStepType.ResourceCommand &&
298
+ AI_COMMAND_JOB_ORIGINS.includes(data.origin || RunnerJobOrigin.Runbook)
299
+ ) {
300
+ return describeResourceCommandTimeout(data);
301
+ }
302
+
192
303
  const isAiKubectl: boolean =
193
304
  data.stepType === RunbookStepType.Kubectl &&
194
305
  AI_COMMAND_JOB_ORIGINS.includes(data.origin || RunnerJobOrigin.Runbook);
@@ -218,15 +329,19 @@ export function describeRunnerJobTimeout(data: {
218
329
  ? "unclaimed"
219
330
  : data.kind;
220
331
 
332
+ const executor: string = data.isForKubernetesAiAgent
333
+ ? "The cluster's Kubernetes AI agent"
334
+ : "The cluster's Runner";
335
+
221
336
  switch (kind) {
222
337
  case "unclaimed":
223
- return `The cluster's Runner did not pick up this kubectl command within ${describeSeconds(
338
+ return `${executor} did not pick up this kubectl command within ${describeSeconds(
224
339
  data.claimTimeoutInMs,
225
340
  )} — it may be offline, restarting or busy with other work. Nothing was run on the cluster.`;
226
341
  case "lease_expired":
227
- return `The cluster's Runner stopped responding while this kubectl command was running — it may have restarted or lost its connection. What the command did is unknown.${checkFirst}`;
342
+ return `${executor} stopped responding while this kubectl command was running — it may have restarted or lost its connection. What the command did is unknown.${checkFirst}`;
228
343
  default:
229
- return `The cluster's Runner did not report a result for this kubectl command in time — kubectl may have outlived its ${describeSeconds(
344
+ return `${executor} did not report a result for this kubectl command in time — kubectl may have outlived its ${describeSeconds(
230
345
  data.executionTimeoutInMs,
231
346
  )} timeout. What the command did is unknown.${checkFirst}`;
232
347
  }
@@ -236,8 +351,59 @@ function describeSeconds(milliseconds: number): string {
236
351
  return `${Math.max(1, Math.round(milliseconds / 1000))}s`;
237
352
  }
238
353
 
354
+ /*
355
+ * The same three reasons for a command on an infrastructure resource, run
356
+ * by that resource's AI agent: "nobody picked it up" (nothing ran) versus
357
+ * "it was picked up and then went silent" (what it did is unknown), naming
358
+ * the agent ("the Docker AI agent") and the resource ("the Docker host").
359
+ */
360
+ function describeResourceCommandTimeout(data: {
361
+ kind: RunnerJobTimeoutKind;
362
+ wasClaimed?: boolean | undefined;
363
+ origin: RunnerJobOrigin | undefined;
364
+ claimTimeoutInMs: number;
365
+ executionTimeoutInMs: number;
366
+ resourceType?: AiResourceType | null | undefined;
367
+ }): string {
368
+ const agentName: string = isAiResourceType(data.resourceType)
369
+ ? AI_RESOURCE_TYPE_INFO[data.resourceType].agentDisplayName
370
+ : "resource's AI agent";
371
+ const noun: string = isAiResourceType(data.resourceType)
372
+ ? describeResourceNoun(data.resourceType)
373
+ : "resource";
374
+
375
+ const checkFirst: string =
376
+ data.origin === RunnerJobOrigin.AiRemediation
377
+ ? ` Check the ${noun} before running a change again.`
378
+ : "";
379
+
380
+ const kind: RunnerJobTimeoutKind =
381
+ data.kind === "overall" && data.wasClaimed === false
382
+ ? "unclaimed"
383
+ : data.kind;
384
+
385
+ switch (kind) {
386
+ case "unclaimed":
387
+ return `The ${agentName} did not pick up the command in time (within ${describeSeconds(
388
+ data.claimTimeoutInMs,
389
+ )}) — it may be offline, restarting or busy with other work. Nothing was run on the ${noun}.`;
390
+ case "lease_expired":
391
+ return `The ${agentName} stopped responding while this command was running — it may have restarted or lost its connection. What the command did is unknown.${checkFirst}`;
392
+ default:
393
+ return `The ${agentName} did not report a result for this command in time — the command may have outlived its ${describeSeconds(
394
+ data.executionTimeoutInMs,
395
+ )} timeout. What the command did is unknown.${checkFirst}`;
396
+ }
397
+ }
398
+
239
399
  // Where a Runner's write scope is set, as a refusal words it.
240
400
  interface RunnerWriteScopeSettings {
401
+ // Who runs the command, as a refusal names it ("the cluster's Runner").
402
+ executor: string;
403
+ // The same, where it is the one living in the cluster.
404
+ inClusterExecutor: string;
405
+ // The same, short ("the Runner"), for "so ... would refuse it".
406
+ executorShort: string;
241
407
  // Why the Runner refuses node operations (a clause).
242
408
  nodeOperationsOff: string;
243
409
  // How to let it change nodes (a clause, after "To let OneUptime AI change nodes, ").
@@ -285,6 +451,13 @@ export class Service extends DatabaseService<Model> {
285
451
  policy: KubectlPolicyResult;
286
452
  posture: KubernetesRunnerPosture | undefined;
287
453
  usesCredential: boolean;
454
+ /*
455
+ * Who runs the command, for the wording only (the rule is the same):
456
+ * the Kubernetes AI agent, the previous in-cluster Runner or a Runner
457
+ * with a credential. Absent reads from usesCredential, as before the
458
+ * agent existed: in-cluster means the previous in-cluster Runner.
459
+ */
460
+ executorKind?: KubernetesAiAccessExecutorKind | undefined;
288
461
  }): string | null {
289
462
  const { policy, posture } = data;
290
463
 
@@ -308,26 +481,36 @@ export class Service extends DatabaseService<Model> {
308
481
  return refusal
309
482
  ? Service.describeRunnerWriteScopeRefusal(
310
483
  refusal,
311
- Service.getRunnerWriteScopeSettings(data.usesCredential),
484
+ Service.getRunnerWriteScopeSettings(
485
+ data.executorKind ||
486
+ (data.usesCredential ? "credential_runner" : "legacy_runner"),
487
+ ),
312
488
  )
313
489
  : null;
314
490
  }
315
491
 
316
492
  /*
317
- * Where the target Runner's write scope is set, in the words a refusal
318
- * uses. The in-cluster Runner is the Kubernetes agent's: its chart sets
319
- * the scope (and the environment variables behind it), and an upgrade
320
- * changes it. A Runner that reaches the cluster through a Kubernetes
321
- * credential is an ordinary Runner no chart configures: it reports what
322
- * it was started with — ONEUPTIME_KUBECTL_WRITE_NAMESPACES and
323
- * ONEUPTIME_KUBECTL_ALLOW_NODE_OPERATIONS on its own host — and a
324
- * restart picks up a change.
493
+ * Where the target's write scope is set, in the words a refusal uses —
494
+ * three ways, by who runs the command:
495
+ *
496
+ * - the Kubernetes AI agent: the chart's aiAgent.remediation.* values;
497
+ * - the previous in-cluster Runner an older chart installed: its values
498
+ * are aiAccess.remediation.*, and the way to change them now is to
499
+ * upgrade the chart to the AI agent, which replaces the Runner;
500
+ * - a Runner that reaches the cluster through a Kubernetes credential: an
501
+ * ordinary Runner no chart configures, which reports what it was
502
+ * started with — ONEUPTIME_KUBECTL_WRITE_NAMESPACES and
503
+ * ONEUPTIME_KUBECTL_ALLOW_NODE_OPERATIONS on its own host — and picks
504
+ * up a change on restart.
325
505
  */
326
506
  private static getRunnerWriteScopeSettings(
327
- usesCredential: boolean,
507
+ executorKind: KubernetesAiAccessExecutorKind,
328
508
  ): RunnerWriteScopeSettings {
329
- if (usesCredential) {
509
+ if (executorKind === "credential_runner") {
330
510
  return {
511
+ executor: "the cluster's Runner",
512
+ inClusterExecutor: "the cluster's in-cluster Runner",
513
+ executorShort: "the Runner",
331
514
  nodeOperationsOff: `it was started with ${KUBECTL_ALLOW_NODE_OPERATIONS_ENV} (or ${KUBECTL_ALLOW_WRITES_ENV}) set to something other than true on its host`,
332
515
  allowNodeOperations: `set ${KUBECTL_ALLOW_NODE_OPERATIONS_ENV}=true on that Runner's host and restart it`,
333
516
  namespaces: `${KUBECTL_WRITE_NAMESPACES_ENV} on that Runner's host`,
@@ -335,13 +518,30 @@ export class Service extends DatabaseService<Model> {
335
518
  };
336
519
  }
337
520
 
521
+ if (executorKind === "ai_agent") {
522
+ return {
523
+ executor: "the cluster's Kubernetes AI agent",
524
+ inClusterExecutor: "the cluster's Kubernetes AI agent",
525
+ executorShort: "the AI agent",
526
+ nodeOperationsOff: `it was installed with aiAgent.remediation.nodeOperations=false (${KUBECTL_ALLOW_NODE_OPERATIONS_ENV})`,
527
+ allowNodeOperations:
528
+ "upgrade the Kubernetes agent chart with --set aiAgent.remediation.nodeOperations=true",
529
+ namespaces: `aiAgent.remediation.namespaces on the Kubernetes agent chart, ${KUBECTL_WRITE_NAMESPACES_ENV}`,
530
+ addNamespace:
531
+ "add it to aiAgent.remediation.namespaces and upgrade the Kubernetes agent chart",
532
+ };
533
+ }
534
+
338
535
  return {
536
+ executor: "the cluster's Runner",
537
+ inClusterExecutor: "the cluster's in-cluster Runner",
538
+ executorShort: "the Runner",
339
539
  nodeOperationsOff: `its Kubernetes agent was installed with aiAccess.remediation.nodeOperations=false (${KUBECTL_ALLOW_NODE_OPERATIONS_ENV})`,
340
540
  allowNodeOperations:
341
- "upgrade the agent with --set aiAccess.remediation.nodeOperations=true",
541
+ "upgrade the Kubernetes agent chart to the Kubernetes AI agent (it replaces the in-cluster Runner) with --set aiAgent.remediation.nodeOperations=true",
342
542
  namespaces: `aiAccess.remediation.namespaces on the Kubernetes agent chart, ${KUBECTL_WRITE_NAMESPACES_ENV}`,
343
543
  addNamespace:
344
- "add it to aiAccess.remediation.namespaces and upgrade the agent",
544
+ "upgrade the Kubernetes agent chart to the Kubernetes AI agent (it replaces the in-cluster Runner) and add it to aiAgent.remediation.namespaces",
345
545
  };
346
546
  }
347
547
 
@@ -351,8 +551,9 @@ export class Service extends DatabaseService<Model> {
351
551
  settings: RunnerWriteScopeSettings,
352
552
  ): string {
353
553
  const command: string = `"${refusal.displayCommand}"`;
354
- const wouldRefuse: string =
355
- "so the Runner would refuse it. It was not enqueued.";
554
+ const wouldRefuse: string = `so ${settings.executorShort} would refuse it. It was not enqueued.`;
555
+ const executor: string = settings.executor;
556
+ const Executor: string = `${executor.charAt(0).toUpperCase()}${executor.slice(1)}`;
356
557
  const scopeList: string = `${refusal.writeNamespaces
357
558
  .map((allowed: string) => {
358
559
  return `"${allowed}"`;
@@ -366,17 +567,17 @@ export class Service extends DatabaseService<Model> {
366
567
  return `${
367
568
  refusal.uncertainty === null
368
569
  ? `${command} changes a node`
369
- : `The cluster's Runner cannot tell for certain whether ${command} changes a node (${refusal.uncertainty})`
370
- }, and the cluster's Runner does not allow node operations (cordon, uncordon, drain, taint, or labelling, annotating or patching a Node): ${settings.nodeOperationsOff}, ${wouldRefuse}${fix} To let OneUptime AI change nodes, ${settings.allowNodeOperations}.`;
570
+ : `${Executor} cannot tell for certain whether ${command} changes a node (${refusal.uncertainty})`
571
+ }, and ${executor} does not allow node operations (cordon, uncordon, drain, taint, or labelling, annotating or patching a Node): ${settings.nodeOperationsOff}, ${wouldRefuse}${fix} To let OneUptime AI change nodes, ${settings.allowNodeOperations}.`;
371
572
  case "objects_uncertain":
372
573
  case "namespace_uncertain":
373
- return `The cluster's Runner cannot tell for certain which ${
574
+ return `${Executor} cannot tell for certain which ${
374
575
  refusal.code === "namespace_uncertain" ? "namespace" : "objects"
375
576
  } ${command} changes (${refusal.uncertainty}), ${wouldRefuse}${fix}`;
376
577
  case "verb_mismatch":
377
- return `The cluster's Runner reads the verb of ${command} as "${refusal.readVerb}", but the kubectl policy read "${refusal.policyVerb}", so it cannot tell for certain what the command changes, ${wouldRefuse}`;
578
+ return `${Executor} reads the verb of ${command} as "${refusal.readVerb}", but the kubectl policy read "${refusal.policyVerb}", so it cannot tell for certain what the command changes, ${wouldRefuse}`;
378
579
  case "unnamed_namespace_objects":
379
- return `${command} would change Namespace objects without naming them (a selector, --all or no name at all), so the cluster's Runner cannot tell whether one of them is ${
580
+ return `${command} would change Namespace objects without naming them (a selector, --all or no name at all), so ${executor} cannot tell whether one of them is ${
380
581
  refusal.podNamespace
381
582
  ? `"${refusal.podNamespace}", the namespace it runs in`
382
583
  : "outside the namespaces it lets OneUptime AI change"
@@ -384,19 +585,19 @@ export class Service extends DatabaseService<Model> {
384
585
  case "cluster_scoped":
385
586
  return `${command} changes ${refusal.clusterScopedKinds.join(
386
587
  ", ",
387
- )} objects, which are cluster-scoped: they live outside every namespace, so outside the namespaces the cluster's Runner lets OneUptime AI change (${scopeList}) whatever -n says, ${wouldRefuse}`;
588
+ )} objects, which are cluster-scoped: they live outside every namespace, so outside the namespaces ${executor} lets OneUptime AI change (${scopeList}) whatever -n says, ${wouldRefuse}`;
388
589
  case "all_namespaces":
389
- return `${command} would change every namespace, including ones the cluster's Runner may not change, ${wouldRefuse}${fix}`;
590
+ return `${command} would change every namespace, including ones ${executor} may not change, ${wouldRefuse}${fix}`;
390
591
  case "no_namespace":
391
- return `${command} names no namespace, and the cluster's Runner reported no namespace of its own for kubectl to use there, ${wouldRefuse}${fix}`;
592
+ return `${command} names no namespace, and ${executor} reported no namespace of its own for kubectl to use there, ${wouldRefuse}${fix}`;
392
593
  case "own_namespace":
393
594
  return refusal.namespaceSource === "namespace_object"
394
- ? `${command} would change the Namespace object "${namespace}", the namespace the cluster's in-cluster Runner itself runs in. OneUptime AI never changes it — a change there could reconfigure the Kubernetes agent or the Runner — ${wouldRefuse}`
595
+ ? `${command} would change the Namespace object "${namespace}", the namespace ${settings.inClusterExecutor} itself runs in. OneUptime AI never changes it — a change there could reconfigure the Kubernetes agent or ${settings.executorShort} — ${wouldRefuse}`
395
596
  : `${command} would change namespace "${namespace}"${
396
597
  refusal.namespaceSource === "default_namespace"
397
598
  ? " (the command names none, so kubectl would use that one)"
398
599
  : ""
399
- }, the namespace the cluster's in-cluster Runner itself runs in. OneUptime AI never changes it — a change there could scale away the Kubernetes agent or the Runner — ${wouldRefuse} Name the namespace of the workload to fix with -n <namespace>.`;
600
+ }, the namespace ${settings.inClusterExecutor} itself runs in. OneUptime AI never changes it — a change there could scale away the Kubernetes agent or ${settings.executorShort} — ${wouldRefuse} Name the namespace of the workload to fix with -n <namespace>.`;
400
601
  case "outside_scope":
401
602
  return `${command} would change ${
402
603
  refusal.namespaceSource === "namespace_object"
@@ -406,7 +607,7 @@ export class Service extends DatabaseService<Model> {
406
607
  ? " (the command names none, so kubectl would use that one)"
407
608
  : ""
408
609
  }`
409
- }, which is outside the namespaces the cluster's Runner lets OneUptime AI change (${scopeList}), ${wouldRefuse} To let OneUptime AI change "${namespace}", ${settings.addNamespace}.`;
610
+ }, which is outside the namespaces ${executor} lets OneUptime AI change (${scopeList}), ${wouldRefuse} To let OneUptime AI change "${namespace}", ${settings.addNamespace}.`;
410
611
  default: {
411
612
  const unhandled: never = refusal.code;
412
613
  return unhandled;
@@ -525,6 +726,17 @@ export class Service extends DatabaseService<Model> {
525
726
  );
526
727
  }
527
728
 
729
+ /*
730
+ * A resource command runs on that resource's own AI agent, never on a
731
+ * Runner: this lane would target a Runner (targetAgentId), which must
732
+ * never be handed one.
733
+ */
734
+ if (data.stepType === RunbookStepType.ResourceCommand) {
735
+ throw new BadDataException(
736
+ "Resource commands run on the resource's AI agent, never on a Runner, and are enqueued through enqueueAiResourceCommand.",
737
+ );
738
+ }
739
+
528
740
  const command: string = (data.command || "").trim();
529
741
  if (!command) {
530
742
  throw new BadDataException("An AI command job needs a command.");
@@ -579,13 +791,16 @@ export class Service extends DatabaseService<Model> {
579
791
  * approved-plan and rollback paths — not just the FullAuto inline tool
580
792
  * that has its own pre-check for a friendlier message to the model.
581
793
  * Check-then-act, so a burst of concurrent runs can overshoot slightly;
582
- * the cap is a storm brake, not a quota.
794
+ * the cap is a storm brake, not a quota. Resource commands share the
795
+ * table and the origin but have their own brake, so they never count
796
+ * here (see MAX_AI_RESOURCE_COMMAND_JOBS_PER_PROJECT_PER_HOUR).
583
797
  */
584
798
  const jobsInLastHour: number = (
585
799
  await this.countBy({
586
800
  query: {
587
801
  projectId: data.projectId,
588
802
  origin: RunnerJobOrigin.AiRemediation,
803
+ stepType: QueryHelper.notEquals(RunbookStepType.ResourceCommand),
589
804
  createdAt: QueryHelper.greaterThan(OneUptimeDate.getSomeHoursAgo(1)),
590
805
  },
591
806
  props: { isRoot: true },
@@ -651,17 +866,24 @@ export class Service extends DatabaseService<Model> {
651
866
  * the cluster), and the payload carries the cluster's identifier so the
652
867
  * claim path and the Runner can refuse a job that reaches the wrong pod.
653
868
  * A credential is never sent to a kubernetes-agent Runner (its identity
654
- * is minted with the project's telemetry ingestion key).
869
+ * is minted with the project's telemetry ingestion key), nor to the
870
+ * cluster's Kubernetes AI agent.
871
+ *
872
+ * The target may be the cluster's Kubernetes AI agent (a KubernetesAiAgent
873
+ * row, never a Runner): targetAgentId then names the agent row, and the
874
+ * job is written with targetKubernetesAiAgentId instead, so only that
875
+ * agent can claim it and no Runner ever sees it.
655
876
  *
656
877
  * It also re-reads the cluster's CURRENT AI access configuration, because
657
878
  * every caller acts on a snapshot (an investigation reads the cluster's
658
879
  * status once when it starts, a remediation run when it composes): the
659
- * target must still be the cluster's bound Runner, a credential must still
660
- * be its bound Kubernetes credential, an investigation's reads need "Let
661
- * AI investigate with kubectl" still on, and a remediation run's commands
662
- * (its reads included) need the cluster's remediation still enabled. An
663
- * operator who revokes or re-points access therefore stops an in-flight
664
- * run at its next command.
880
+ * target must still be the cluster's access target as resolved now
881
+ * (KubernetesClusterAiAccessService.loadAccessTarget), a credential must
882
+ * still be its bound Kubernetes credential, an investigation's reads need
883
+ * "Investigate with kubectl" still on, and a remediation run's commands
884
+ * (its reads included) need the cluster's fixes still enabled. An
885
+ * operator who revokes or re-points access — or an agent that takes over
886
+ * from a Runner — therefore stops an in-flight run at its next command.
665
887
  */
666
888
  @CaptureSpan()
667
889
  public async enqueueAiKubectlCommand(data: {
@@ -676,6 +898,10 @@ export class Service extends DatabaseService<Model> {
676
898
  autoRemediationSuggestionId?: ObjectID | undefined;
677
899
  kubernetesClusterId: ObjectID;
678
900
  stepId: string;
901
+ /*
902
+ * The cluster's access target: a Runner id, or the id of the cluster's
903
+ * Kubernetes AI agent row (the status's runner.id either way).
904
+ */
679
905
  targetAgentId: ObjectID;
680
906
  credentialId?: string | undefined;
681
907
  command: string;
@@ -770,7 +996,9 @@ export class Service extends DatabaseService<Model> {
770
996
  /*
771
997
  * The access test is bounded by its own route limits instead, and an
772
998
  * investigation's brake counts only rows with an AI run, so tests never
773
- * spend the budget real investigations share.
999
+ * spend the budget real investigations share. Resource commands have
1000
+ * their own brake and never count here, so a busy hour on the project's
1001
+ * other infrastructure never starves the cluster lane.
774
1002
  */
775
1003
  if (!isAccessTest) {
776
1004
  const hourlyCap: number =
@@ -783,6 +1011,7 @@ export class Service extends DatabaseService<Model> {
783
1011
  query: {
784
1012
  projectId: data.projectId,
785
1013
  origin: data.origin,
1014
+ stepType: QueryHelper.notEquals(RunbookStepType.ResourceCommand),
786
1015
  createdAt: QueryHelper.greaterThan(
787
1016
  OneUptimeDate.getSomeHoursAgo(1),
788
1017
  ),
@@ -817,6 +1046,7 @@ export class Service extends DatabaseService<Model> {
817
1046
  },
818
1047
  select: {
819
1048
  _id: true,
1049
+ projectId: true,
820
1050
  name: true,
821
1051
  clusterIdentifier: true,
822
1052
  aiAccessRunnerId: true,
@@ -837,9 +1067,18 @@ export class Service extends DatabaseService<Model> {
837
1067
  const clusterLabel: string =
838
1068
  cluster.name || clusterIdentifier || data.kubernetesClusterId.toString();
839
1069
 
1070
+ /*
1071
+ * The cluster's access target as it resolves NOW. A target that is not
1072
+ * it — a Runner the cluster was re-pointed away from, or a Runner after
1073
+ * the cluster's Kubernetes AI agent came online — is refused below.
1074
+ */
1075
+ const loaded: LoadedKubernetesAiAccessTarget =
1076
+ await KubernetesClusterAiAccessService.loadAccessTarget({ cluster });
1077
+
840
1078
  const bindingRefusal: string | null = Service.getClusterBindingRefusal({
841
1079
  cluster,
842
1080
  clusterLabel,
1081
+ resolvedTargetId: getKubernetesAiAccessTargetId(loaded.target),
843
1082
  targetAgentId: data.targetAgentId,
844
1083
  credentialId: data.credentialId,
845
1084
  requiredSwitch: await this.getRequiredClusterSwitch({
@@ -854,92 +1093,138 @@ export class Service extends DatabaseService<Model> {
854
1093
  throw new BadDataException(bindingRefusal);
855
1094
  }
856
1095
 
857
- const targetRunner: Runner | null = await RunnerService.findOneBy({
858
- query: {
859
- _id: data.targetAgentId.toString(),
860
- projectId: data.projectId,
861
- },
862
- select: { _id: true, name: true, hostInfo: true },
863
- props: { isRoot: true },
864
- });
1096
+ let posture: KubernetesRunnerPosture | undefined = undefined;
1097
+ let executorKind: KubernetesAiAccessExecutorKind;
1098
+ let targetKubernetesAiAgentId: ObjectID | undefined = undefined;
865
1099
 
866
- if (!targetRunner) {
867
- throw new BadDataException(
868
- "The target Runner was not found or it does not belong to this project.",
869
- );
870
- }
1100
+ if (loaded.target.type === "ai_agent") {
1101
+ const agent: KubernetesAiAgent = loaded.target.agent;
871
1102
 
872
- if (data.credentialId) {
873
1103
  /*
874
- * A kubernetes-agent Runner is never handed credential material: its
875
- * identity is issued with the project's telemetry ingestion key, so
876
- * anyone holding that key could come to hold the credential too. The
877
- * claim path refuses it as well (by the same name-or-posture rule);
878
- * refusing here keeps the job from ever existing.
1104
+ * The agent row was read by (project, cluster), so it is this
1105
+ * cluster's: checked again here so the rule reads in one place.
879
1106
  */
880
- if (RunnerServiceClass.isKubernetesAgentRunnerRow(targetRunner)) {
1107
+ if (
1108
+ agent.projectId?.toString() !== data.projectId.toString() ||
1109
+ agent.kubernetesClusterId?.toString() !==
1110
+ data.kubernetesClusterId.toString()
1111
+ ) {
881
1112
  throw new BadDataException(
882
- `Runner "${targetRunner.name}" is a cluster's in-cluster Runner and is never given a credential, so a kubectl command for cluster "${clusterLabel}" that needs one cannot run on it. Create a Runner under Project Settings → Runners, assign the Kubernetes credential to it and select both on the cluster's AI page.`,
1113
+ `The Kubernetes AI agent this kubectl command names is not cluster "${clusterLabel}"'s, so it was not enqueued.`,
883
1114
  );
884
1115
  }
885
1116
 
886
- const credential: RunbookCredential | null = ObjectID.isValidUUID(
887
- data.credentialId,
888
- )
889
- ? await RunbookCredentialService.findOneBy({
890
- query: {
891
- _id: data.credentialId,
892
- projectId: data.projectId,
893
- },
894
- select: { _id: true, name: true, credentialType: true },
895
- props: { isRoot: true },
896
- })
897
- : null;
898
-
899
- if (
900
- !credential ||
901
- credential.credentialType !== RunbookCredentialType.Kubernetes
902
- ) {
1117
+ /*
1118
+ * The agent runs kubectl with its own ServiceAccount only and is
1119
+ * never handed credential material: its identity is issued with the
1120
+ * project's telemetry ingestion key.
1121
+ */
1122
+ if (data.credentialId) {
903
1123
  throw new BadDataException(
904
- `The credential this kubectl command names is not a Kubernetes credential of this project, so it was not enqueued for cluster "${clusterLabel}".`,
1124
+ `Cluster "${clusterLabel}" is reached through its Kubernetes AI agent, which runs kubectl with its own ServiceAccount and is never given a credential, so a kubectl command that needs one was not enqueued.`,
905
1125
  );
906
1126
  }
907
- }
908
1127
 
909
- const posture: KubernetesRunnerPosture | undefined =
910
- parseKubernetesRunnerPosture(targetRunner.hostInfo);
1128
+ posture = parseKubernetesAgentPosture(agent.posture);
1129
+ executorKind = "ai_agent";
1130
+ targetKubernetesAiAgentId = agent.id!;
911
1131
 
912
- if (!data.credentialId) {
913
1132
  if (!isInClusterPostureForCluster(posture, clusterIdentifier)) {
914
1133
  throw new BadDataException(
915
- `A kubectl command without a Kubernetes credential can only run on the in-cluster Runner of cluster "${
1134
+ `The Kubernetes AI agent has not reported that it runs in cluster "${
916
1135
  clusterIdentifier || cluster.name || cluster.id?.toString()
917
- }", and Runner "${targetRunner.name}" ${
918
- posture?.inCluster
919
- ? `is the in-cluster Runner of ${
920
- posture.clusterIdentifier?.trim()
921
- ? `cluster "${posture.clusterIdentifier.trim()}"`
922
- : "an unnamed cluster"
923
- }`
924
- : "runs outside the cluster"
925
- }. Select a Kubernetes credential for this Runner on the cluster's AI page, or install the in-cluster Runner on this cluster.`,
1136
+ }", so this kubectl command was not enqueued. Wait for its next report (within a minute), or reset the agent on the cluster's AI agent page (AI → Agent).`,
926
1137
  );
927
1138
  }
1139
+ } else {
1140
+ /*
1141
+ * A Runner target: the Runner row the resolution read, which is the
1142
+ * cluster's bound Runner and so belongs to this project.
1143
+ */
1144
+ const targetRunner: Runner | null =
1145
+ loaded.target.type === "none" ? null : loaded.target.runner;
1146
+
1147
+ if (!targetRunner) {
1148
+ throw new BadDataException(
1149
+ "The target Runner was not found or it does not belong to this project.",
1150
+ );
1151
+ }
1152
+
1153
+ executorKind = data.credentialId ? "credential_runner" : "legacy_runner";
1154
+
1155
+ if (data.credentialId) {
1156
+ /*
1157
+ * A kubernetes-agent Runner is never handed credential material: its
1158
+ * identity is issued with the project's telemetry ingestion key, so
1159
+ * anyone holding that key could come to hold the credential too. The
1160
+ * claim path refuses it as well (by the same name-or-posture rule);
1161
+ * refusing here keeps the job from ever existing.
1162
+ */
1163
+ if (RunnerServiceClass.isKubernetesAgentRunnerRow(targetRunner)) {
1164
+ throw new BadDataException(
1165
+ `Runner "${targetRunner.name}" is a cluster's in-cluster Runner and is never given a credential, so a kubectl command for cluster "${clusterLabel}" that needs one cannot run on it. Create a Runner under Project Settings → Runners, assign the Kubernetes credential to it and select both on the cluster's AI agent page (AI → Agent).`,
1166
+ );
1167
+ }
1168
+
1169
+ const credential: RunbookCredential | null = ObjectID.isValidUUID(
1170
+ data.credentialId,
1171
+ )
1172
+ ? await RunbookCredentialService.findOneBy({
1173
+ query: {
1174
+ _id: data.credentialId,
1175
+ projectId: data.projectId,
1176
+ },
1177
+ select: { _id: true, name: true, credentialType: true },
1178
+ props: { isRoot: true },
1179
+ })
1180
+ : null;
1181
+
1182
+ if (
1183
+ !credential ||
1184
+ credential.credentialType !== RunbookCredentialType.Kubernetes
1185
+ ) {
1186
+ throw new BadDataException(
1187
+ `The credential this kubectl command names is not a Kubernetes credential of this project, so it was not enqueued for cluster "${clusterLabel}".`,
1188
+ );
1189
+ }
1190
+ }
1191
+
1192
+ posture = parseKubernetesRunnerPosture(targetRunner.hostInfo);
1193
+
1194
+ if (!data.credentialId) {
1195
+ if (!isInClusterPostureForCluster(posture, clusterIdentifier)) {
1196
+ throw new BadDataException(
1197
+ `A kubectl command without a Kubernetes credential can only run on the in-cluster Runner of cluster "${
1198
+ clusterIdentifier || cluster.name || cluster.id?.toString()
1199
+ }", and Runner "${targetRunner.name}" ${
1200
+ posture?.inCluster
1201
+ ? `is the in-cluster Runner of ${
1202
+ posture.clusterIdentifier?.trim()
1203
+ ? `cluster "${posture.clusterIdentifier.trim()}"`
1204
+ : "an unnamed cluster"
1205
+ }`
1206
+ : "runs outside the cluster"
1207
+ }. Select a Kubernetes credential for this Runner on the cluster's AI agent page (AI → Agent), or clear the Runner there to use the cluster's Kubernetes AI agent.`,
1208
+ );
1209
+ }
1210
+ }
928
1211
  }
929
1212
 
930
1213
  /*
931
- * A remediation write the Runner's own posture says it will refuse — a
1214
+ * A remediation write the target's own posture says it will refuse — a
932
1215
  * namespace outside its write scope, its own namespace, or a node
933
1216
  * operation its chart did not grant — is refused here, before it can be
934
1217
  * approved, enqueued or counted by the cluster's circuit breaker, with
935
- * the chart value that would allow it. Reads are never refused for
936
- * scope.
1218
+ * the setting that would allow it. Reads are never refused for scope.
1219
+ * A job with no credential lands in the pod's own namespace when it
1220
+ * names none — for the agent exactly as for the in-cluster Runner.
937
1221
  */
938
1222
  if (data.origin === RunnerJobOrigin.AiRemediation) {
939
1223
  const scopeRefusal: string | null = Service.getRunnerWriteScopeRefusal({
940
1224
  policy,
941
1225
  posture,
942
1226
  usesCredential: Boolean(data.credentialId),
1227
+ executorKind,
943
1228
  });
944
1229
 
945
1230
  if (scopeRefusal) {
@@ -964,7 +1249,15 @@ export class Service extends DatabaseService<Model> {
964
1249
  row.kubernetesClusterId = data.kubernetesClusterId;
965
1250
  row.stepId = data.stepId;
966
1251
  row.stepType = RunbookStepType.Kubectl;
967
- row.targetAgentId = data.targetAgentId;
1252
+ /*
1253
+ * Exactly one target: the agent's row, or the Runner. targetAgentId has
1254
+ * a foreign key to Runner, so it stays empty for the agent.
1255
+ */
1256
+ if (targetKubernetesAiAgentId) {
1257
+ row.targetKubernetesAiAgentId = targetKubernetesAiAgentId;
1258
+ } else {
1259
+ row.targetAgentId = data.targetAgentId;
1260
+ }
968
1261
  row.script = "";
969
1262
  row.payload = {
970
1263
  args: policy.args,
@@ -1023,17 +1316,20 @@ export class Service extends DatabaseService<Model> {
1023
1316
  /*
1024
1317
  * Why a kubectl job may NOT be enqueued for this cluster as it is
1025
1318
  * configured right now, or null when it may. Pure, so the rule reads in
1026
- * one place: the job must go through the cluster's CURRENT binding, and
1027
- * the capability it is for must still be switched on.
1319
+ * one place: the job must go to the cluster's CURRENT access target
1320
+ * (resolvedTargetId, from resolveKubernetesAiAccessTarget), and the
1321
+ * capability it is for must still be switched on.
1028
1322
  *
1029
1323
  * A credential-less job does not require the credential binding to be
1030
- * empty: the in-cluster Runner of the cluster wins over a bound
1031
- * credential (the readiness status prefers it), so such a job is
1032
- * legitimate with a credential still selected.
1324
+ * empty: the in-cluster Runner of the cluster (or its Kubernetes AI
1325
+ * agent) wins over a bound credential (the readiness status prefers it),
1326
+ * so such a job is legitimate with a credential still selected.
1033
1327
  */
1034
1328
  public static getClusterBindingRefusal(data: {
1035
1329
  cluster: KubernetesCluster;
1036
1330
  clusterLabel: string;
1331
+ // The cluster's access target as it resolves now; null when none.
1332
+ resolvedTargetId: string | null;
1037
1333
  targetAgentId: ObjectID;
1038
1334
  credentialId?: string | undefined;
1039
1335
  // The switch that must still be on; null for the access test.
@@ -1042,10 +1338,10 @@ export class Service extends DatabaseService<Model> {
1042
1338
  const { cluster, clusterLabel } = data;
1043
1339
 
1044
1340
  if (
1045
- !cluster.aiAccessRunnerId ||
1046
- cluster.aiAccessRunnerId.toString() !== data.targetAgentId.toString()
1341
+ !data.resolvedTargetId ||
1342
+ data.resolvedTargetId !== data.targetAgentId.toString()
1047
1343
  ) {
1048
- return `Cluster "${clusterLabel}" is no longer reached through this Runner (its AI access binding changed or was cleared on the cluster's AI page), so this kubectl command was not enqueued.`;
1344
+ return `Cluster "${clusterLabel}" is no longer reached through this Runner or agent (its AI access changed on the cluster's AI agent page (AI → Agent), or its Kubernetes AI agent took over), so this kubectl command was not enqueued.`;
1049
1345
  }
1050
1346
 
1051
1347
  if (
@@ -1053,14 +1349,14 @@ export class Service extends DatabaseService<Model> {
1053
1349
  (!cluster.aiAccessCredentialId ||
1054
1350
  cluster.aiAccessCredentialId.toString() !== data.credentialId)
1055
1351
  ) {
1056
- return `Cluster "${clusterLabel}" is no longer reached with this Kubernetes credential (its AI access binding changed or was cleared on the cluster's AI page), so this kubectl command was not enqueued.`;
1352
+ return `Cluster "${clusterLabel}" is no longer reached with this Kubernetes credential (its AI access changed on the cluster's AI agent page (AI → Agent)), so this kubectl command was not enqueued.`;
1057
1353
  }
1058
1354
 
1059
1355
  if (
1060
1356
  data.requiredSwitch === "investigation" &&
1061
1357
  cluster.isAiInvestigationEnabled !== true
1062
1358
  ) {
1063
- return `"Let AI investigate with kubectl" is turned off for cluster "${clusterLabel}", so this investigation command was not enqueued.`;
1359
+ return `"Investigate with kubectl" is turned off for cluster "${clusterLabel}", so this investigation command was not enqueued.`;
1064
1360
  }
1065
1361
 
1066
1362
  if (
@@ -1069,7 +1365,406 @@ export class Service extends DatabaseService<Model> {
1069
1365
  cluster.aiRemediationMode as KubernetesAiRemediationMode,
1070
1366
  )
1071
1367
  ) {
1072
- return `AI remediation is turned off for cluster "${clusterLabel}", so this kubectl command was not enqueued.`;
1368
+ return `AI fixes are turned off for cluster "${clusterLabel}", so this kubectl command was not enqueued.`;
1369
+ }
1370
+
1371
+ return null;
1372
+ }
1373
+
1374
+ /*
1375
+ * Enqueue ONE command OneUptime AI composed for an infrastructure
1376
+ * resource — a Docker or Podman host, a Docker Swarm, Proxmox, VMware or
1377
+ * Ceph cluster, a database server or a host — for that resource's AI
1378
+ * agent (a ResourceAiAgent row, never a Runner).
1379
+ *
1380
+ * The server-side chokepoint between an LLM's output and a resource, in
1381
+ * the order enqueueAiKubectlCommand checks a cluster command:
1382
+ *
1383
+ * 1. the call itself: a resource type and id, an AI origin, the
1384
+ * suggestion a remediation job belongs to, the run an investigation
1385
+ * job belongs to (the access test alone has none, and is a read);
1386
+ * 2. the resource command policy, re-run whatever the tool layer
1387
+ * checked: Denied never enqueues, and an investigation-origin job must
1388
+ * be Read tier — an investigation can never write;
1389
+ * 3. the project's hourly brake for resource commands (investigations
1390
+ * and remediation counted apart, on ResourceCommand rows only);
1391
+ * 4. the resource must be this project's;
1392
+ * 5. the target is re-resolved NOW: the resource's online agent
1393
+ * (ResourceAiAgentService.findOnlineAgentForResource), and the agent
1394
+ * the caller named, if any, must still be it;
1395
+ * 6. the switch the job needs must still be on: an investigation's reads
1396
+ * need the resource's investigation switch (a remediation run's reads
1397
+ * its fixes), and a remediation job needs its fixes (mode not
1398
+ * Disabled) — so an operator who turns AI off stops an in-flight run
1399
+ * at its next command;
1400
+ * 7. no credential: the agent uses only its own environment's;
1401
+ * 8. the agent's reported posture must be for this resource type and
1402
+ * name the identity it registered with (the payload carries it, and
1403
+ * the agent refuses a job for any other), and a write must fit it:
1404
+ * ONEUPTIME_AI_ALLOW_WRITES on, ONEUPTIME_AI_WRITE_TARGETS and the
1405
+ * agent's protected targets respected (ResourceCommandPolicy.
1406
+ * getWriteScopeRefusal, the rule the agent itself applies).
1407
+ *
1408
+ * The command travels as an argv (never a shell line) in a
1409
+ * ResourceCommandJobPayload, and the row names the agent in
1410
+ * targetResourceAiAgentId, so only that agent can claim it. Every
1411
+ * refusal is a ResourceCommandEnqueueRefusedException saying which rule.
1412
+ */
1413
+ @CaptureSpan()
1414
+ public async enqueueAiResourceCommand(data: {
1415
+ projectId: ObjectID;
1416
+ /*
1417
+ * The AI run the command belongs to. Required for an investigation
1418
+ * job; absent only for the resource AI page's access test.
1419
+ */
1420
+ aiRunId?: ObjectID | undefined;
1421
+ origin: RunnerJobOrigin.AiInvestigation | RunnerJobOrigin.AiRemediation;
1422
+ autoRemediationSuggestionId?: ObjectID | undefined;
1423
+ resourceType: AiResourceType;
1424
+ resourceId: ObjectID;
1425
+ stepId: string;
1426
+ /*
1427
+ * The agent the caller expects to run the command (its status's
1428
+ * agent.agentId). Refused when the resource's online agent is another
1429
+ * one now. Absent: whichever agent is the resource's online one.
1430
+ */
1431
+ targetResourceAiAgentId?: ObjectID | undefined;
1432
+ command: string;
1433
+ timeoutInMs: number;
1434
+ claimTimeoutInMs?: number | undefined;
1435
+ /*
1436
+ * Never honoured: a resource's agent is never given a credential. Taken
1437
+ * only so a plan step that carries one is refused, never silently
1438
+ * dropped.
1439
+ */
1440
+ credentialId?: string | undefined;
1441
+ /*
1442
+ * The resource AI page's "Test connection" check: a read with no AI run
1443
+ * behind it, exempt from the investigation switch and the brake —
1444
+ * never from the policy, the binding or the read-only rule.
1445
+ */
1446
+ isAccessTest?: boolean | undefined;
1447
+ }): Promise<Model> {
1448
+ // 1. The call itself.
1449
+ if (!isAiResourceType(data.resourceType)) {
1450
+ throw new ResourceCommandEnqueueRefusedException(
1451
+ "invalid_request",
1452
+ `A resource command needs a resource type; "${String(
1453
+ data.resourceType,
1454
+ )}" is not one.`,
1455
+ );
1456
+ }
1457
+
1458
+ const info: AiResourceTypeInfo = AI_RESOURCE_TYPE_INFO[data.resourceType];
1459
+ const noun: string = describeResourceNoun(data.resourceType);
1460
+
1461
+ if (!data.resourceId) {
1462
+ throw new ResourceCommandEnqueueRefusedException(
1463
+ "invalid_request",
1464
+ `resourceId is required for a command on a ${noun}.`,
1465
+ );
1466
+ }
1467
+
1468
+ if (
1469
+ data.origin !== RunnerJobOrigin.AiInvestigation &&
1470
+ data.origin !== RunnerJobOrigin.AiRemediation
1471
+ ) {
1472
+ throw new ResourceCommandEnqueueRefusedException(
1473
+ "invalid_request",
1474
+ `A resource command job cannot have origin "${String(data.origin)}".`,
1475
+ );
1476
+ }
1477
+
1478
+ if (
1479
+ data.origin === RunnerJobOrigin.AiRemediation &&
1480
+ !data.autoRemediationSuggestionId
1481
+ ) {
1482
+ throw new ResourceCommandEnqueueRefusedException(
1483
+ "invalid_request",
1484
+ "A resource remediation job needs its auto-remediation suggestion.",
1485
+ );
1486
+ }
1487
+
1488
+ const isAccessTest: boolean = data.isAccessTest === true;
1489
+
1490
+ if (
1491
+ isAccessTest &&
1492
+ (data.origin !== RunnerJobOrigin.AiInvestigation || data.aiRunId)
1493
+ ) {
1494
+ throw new ResourceCommandEnqueueRefusedException(
1495
+ "invalid_request",
1496
+ "An access test is a read-only check with no AI run behind it.",
1497
+ );
1498
+ }
1499
+
1500
+ if (
1501
+ data.origin === RunnerJobOrigin.AiInvestigation &&
1502
+ !isAccessTest &&
1503
+ !data.aiRunId
1504
+ ) {
1505
+ throw new ResourceCommandEnqueueRefusedException(
1506
+ "invalid_request",
1507
+ "An investigation resource command job needs the AI run it belongs to.",
1508
+ );
1509
+ }
1510
+
1511
+ // 2. The policy, whatever the tool layer decided.
1512
+ const policy: ResourceCommandPolicyResult =
1513
+ ResourceCommandPolicy.evaluateCommand({
1514
+ resourceType: data.resourceType,
1515
+ command: data.command,
1516
+ });
1517
+
1518
+ if (policy.tier === ResourceCommandTier.Denied) {
1519
+ throw new ResourceCommandEnqueueRefusedException(
1520
+ "policy_denied",
1521
+ `Denied by the ${info.displayName} command policy: ${policy.reason}.`,
1522
+ );
1523
+ }
1524
+
1525
+ if (
1526
+ data.origin === RunnerJobOrigin.AiInvestigation &&
1527
+ policy.tier !== ResourceCommandTier.Read
1528
+ ) {
1529
+ throw new ResourceCommandEnqueueRefusedException(
1530
+ "not_read_only",
1531
+ `An investigation may only run read-only commands; "${policy.displayCommand}" would change the ${noun} (${policy.tier}).`,
1532
+ );
1533
+ }
1534
+
1535
+ // 3. The hourly brake, on resource commands only.
1536
+ if (!isAccessTest) {
1537
+ const hourlyCap: number =
1538
+ data.origin === RunnerJobOrigin.AiInvestigation
1539
+ ? MAX_AI_INVESTIGATION_RESOURCE_COMMAND_JOBS_PER_PROJECT_PER_HOUR
1540
+ : MAX_AI_RESOURCE_COMMAND_JOBS_PER_PROJECT_PER_HOUR;
1541
+
1542
+ const jobsInLastHour: number = (
1543
+ await this.countBy({
1544
+ query: {
1545
+ projectId: data.projectId,
1546
+ origin: data.origin,
1547
+ stepType: RunbookStepType.ResourceCommand,
1548
+ createdAt: QueryHelper.greaterThan(
1549
+ OneUptimeDate.getSomeHoursAgo(1),
1550
+ ),
1551
+ ...(data.origin === RunnerJobOrigin.AiInvestigation
1552
+ ? { aiRunId: QueryHelper.notNull() }
1553
+ : {}),
1554
+ },
1555
+ props: { isRoot: true },
1556
+ })
1557
+ ).toNumber();
1558
+
1559
+ if (jobsInLastHour >= hourlyCap) {
1560
+ throw new ResourceCommandEnqueueRefusedException(
1561
+ "hourly_limit",
1562
+ data.origin === RunnerJobOrigin.AiInvestigation
1563
+ ? `This project has run ${jobsInLastHour} AI investigation commands on its infrastructure in the last hour, which is its limit (${hourlyCap}). No further infrastructure commands can run this hour.`
1564
+ : `This project has run ${jobsInLastHour} AI remediation commands on its infrastructure in the last hour, which is its limit (${hourlyCap}). No further AI commands can run on its infrastructure this hour.`,
1565
+ );
1566
+ }
1567
+ }
1568
+
1569
+ // 4 + 5. The resource, and the agent it is reached through NOW.
1570
+ const loaded: LoadedResourceAiAccessTarget =
1571
+ await ResourceAiAccessService.loadAccessTarget({
1572
+ projectId: data.projectId,
1573
+ resourceType: data.resourceType,
1574
+ resourceId: data.resourceId,
1575
+ });
1576
+
1577
+ if (!loaded.resource) {
1578
+ throw new ResourceCommandEnqueueRefusedException(
1579
+ "resource_not_found",
1580
+ `${info.displayName} not found or it does not belong to this project.`,
1581
+ );
1582
+ }
1583
+
1584
+ const bindingRefusal: {
1585
+ code: ResourceCommandEnqueueRefusalCode;
1586
+ message: string;
1587
+ } | null = Service.getResourceBindingRefusal({
1588
+ resource: loaded.resource,
1589
+ agent: loaded.agent,
1590
+ targetResourceAiAgentId: data.targetResourceAiAgentId,
1591
+ credentialId: data.credentialId,
1592
+ // 6. The switch this job needs.
1593
+ requiredSwitch: await this.getRequiredClusterSwitch({
1594
+ projectId: data.projectId,
1595
+ origin: data.origin,
1596
+ aiRunId: data.aiRunId,
1597
+ isAccessTest,
1598
+ }),
1599
+ });
1600
+
1601
+ if (bindingRefusal) {
1602
+ throw new ResourceCommandEnqueueRefusedException(
1603
+ bindingRefusal.code,
1604
+ bindingRefusal.message,
1605
+ );
1606
+ }
1607
+
1608
+ const agent: ResourceAiAgent = loaded.agent!;
1609
+ const resourceLabel: string = loaded.resource.name;
1610
+
1611
+ // 8. The agent's own posture: this resource, and room for the write.
1612
+ const posture: ResourceAiAgentPosture | null = parseResourceAiAgentPosture(
1613
+ agent.posture,
1614
+ );
1615
+ const resourceIdentifier: string = (
1616
+ agent.resourceIdentifier ||
1617
+ posture?.resourceIdentifier ||
1618
+ ""
1619
+ ).trim();
1620
+
1621
+ if (
1622
+ !posture ||
1623
+ posture.resourceType !== data.resourceType ||
1624
+ !resourceIdentifier
1625
+ ) {
1626
+ throw new ResourceCommandEnqueueRefusedException(
1627
+ "agent_posture_mismatch",
1628
+ `The ${info.agentDisplayName} has not reported that it serves ${noun} "${resourceLabel}", so this command was not enqueued. Wait for its next report (within a minute), or reset the agent on ${getResourceAiAgentPage(
1629
+ data.resourceType,
1630
+ )}.`,
1631
+ );
1632
+ }
1633
+
1634
+ if (policy.tier !== ResourceCommandTier.Read) {
1635
+ const scopeRefusal: string | null =
1636
+ ResourceCommandPolicy.getWriteScopeRefusal({
1637
+ result: policy,
1638
+ allowWrites: posture.allowWrites === true,
1639
+ writeTargets: posture.writeTargets,
1640
+ protectedTargets: posture.protectedTargets,
1641
+ resourceType: data.resourceType,
1642
+ });
1643
+
1644
+ if (scopeRefusal) {
1645
+ throw new ResourceCommandEnqueueRefusedException(
1646
+ "write_scope",
1647
+ `${scopeRefusal} It was not enqueued.`,
1648
+ );
1649
+ }
1650
+ }
1651
+
1652
+ const claimDeadlineAt: Date = OneUptimeDate.addRemoveSeconds(
1653
+ OneUptimeDate.getCurrentDate(),
1654
+ Math.ceil((data.claimTimeoutInMs ?? DEFAULT_CLAIM_TIMEOUT_MS) / 1000),
1655
+ );
1656
+
1657
+ const payload: ResourceCommandJobPayload = {
1658
+ resourceType: data.resourceType,
1659
+ resourceId: loaded.resource.id.toString(),
1660
+ resourceIdentifier,
1661
+ program: policy.program,
1662
+ args: policy.args,
1663
+ displayCommand: policy.displayCommand,
1664
+ tier: policy.tier,
1665
+ };
1666
+
1667
+ const row: Model = new Model();
1668
+ row.projectId = data.projectId;
1669
+ row.origin = data.origin;
1670
+ if (data.aiRunId) {
1671
+ row.aiRunId = data.aiRunId;
1672
+ }
1673
+ if (data.autoRemediationSuggestionId) {
1674
+ row.autoRemediationSuggestionId = data.autoRemediationSuggestionId;
1675
+ }
1676
+ row.stepId = data.stepId;
1677
+ row.stepType = RunbookStepType.ResourceCommand;
1678
+ /*
1679
+ * The one target: the resource's agent row. targetAgentId (a Runner)
1680
+ * and targetKubernetesAiAgentId stay empty, so no Runner and no
1681
+ * Kubernetes AI agent can ever claim it.
1682
+ */
1683
+ row.targetResourceAiAgentId = agent.id!;
1684
+ row.resourceType = data.resourceType;
1685
+ row.resourceId = loaded.resource.id;
1686
+ row.script = "";
1687
+ row.payload = payload as unknown as JSONObject;
1688
+ row.timeoutInMs = data.timeoutInMs;
1689
+ row.status = RunnerJobStatus.Pending;
1690
+ row.claimDeadlineAt = claimDeadlineAt;
1691
+
1692
+ return this.create({ data: row, props: { isRoot: true } });
1693
+ }
1694
+
1695
+ /*
1696
+ * Why a resource command may NOT be enqueued for this resource as it is
1697
+ * configured right now, or null when it may. Pure, so the rule reads in
1698
+ * one place: the resource must have an online agent (the one the caller
1699
+ * named, when it named one) that is this resource's, the switch the job
1700
+ * needs must still be on, and no credential may travel with it.
1701
+ */
1702
+ public static getResourceBindingRefusal(data: {
1703
+ resource: ResourceAiAccessRow;
1704
+ // The resource's ONLINE agent right now, or null.
1705
+ agent: ResourceAiAgent | null;
1706
+ targetResourceAiAgentId?: ObjectID | undefined;
1707
+ credentialId?: string | undefined;
1708
+ // The switch that must still be on; null for the access test.
1709
+ requiredSwitch: "investigation" | "remediation" | null;
1710
+ }): { code: ResourceCommandEnqueueRefusalCode; message: string } | null {
1711
+ const { resource, agent } = data;
1712
+ const info: AiResourceTypeInfo =
1713
+ AI_RESOURCE_TYPE_INFO[resource.resourceType];
1714
+ const noun: string = describeResourceNoun(resource.resourceType);
1715
+ const label: string = resource.name;
1716
+
1717
+ if (!agent || !agent.id) {
1718
+ return {
1719
+ code: "agent_not_online",
1720
+ message: `${noun.charAt(0).toUpperCase()}${noun.slice(1)} "${label}" has no online ${info.agentDisplayName}, so this command was not enqueued. ${getResourceAiAgentInstallNextStep(
1721
+ {
1722
+ resourceType: resource.resourceType,
1723
+ resourceId: resource.id.toString(),
1724
+ identifier: resource.identifier,
1725
+ },
1726
+ )} Already installed? Check that its container is running and can reach your OneUptime URL.`,
1727
+ };
1728
+ }
1729
+
1730
+ if (
1731
+ agent.projectId?.toString() !== resource.projectId.toString() ||
1732
+ agent.resourceType !== resource.resourceType ||
1733
+ agent.resourceId?.toString() !== resource.id.toString() ||
1734
+ (data.targetResourceAiAgentId &&
1735
+ data.targetResourceAiAgentId.toString() !== agent.id.toString())
1736
+ ) {
1737
+ return {
1738
+ code: "agent_changed",
1739
+ message: `${noun.charAt(0).toUpperCase()}${noun.slice(1)} "${label}" is no longer reached through this ${info.agentDisplayName} (the agent was reset or replaced), so this command was not enqueued.`,
1740
+ };
1741
+ }
1742
+
1743
+ if (
1744
+ data.requiredSwitch === "investigation" &&
1745
+ resource.isAiInvestigationEnabled !== true
1746
+ ) {
1747
+ return {
1748
+ code: "switch_off",
1749
+ message: `AI investigation is turned off for ${noun} "${label}", so this investigation command was not enqueued.`,
1750
+ };
1751
+ }
1752
+
1753
+ if (
1754
+ data.requiredSwitch === "remediation" &&
1755
+ !ENABLED_RESOURCE_REMEDIATION_MODES.includes(resource.aiRemediationMode)
1756
+ ) {
1757
+ return {
1758
+ code: "switch_off",
1759
+ message: `AI fixes are turned off for ${noun} "${label}", so this command was not enqueued.`,
1760
+ };
1761
+ }
1762
+
1763
+ if (data.credentialId) {
1764
+ return {
1765
+ code: "credential_refused",
1766
+ message: `${noun.charAt(0).toUpperCase()}${noun.slice(1)} "${label}" is reached through its ${info.agentDisplayName}, which uses only the credentials in its own environment and is never given one by OneUptime, so a command that names a credential was not enqueued.`,
1767
+ };
1073
1768
  }
1074
1769
 
1075
1770
  return null;
@@ -1305,6 +2000,28 @@ export class Service extends DatabaseService<Model> {
1305
2000
  .text;
1306
2001
  }
1307
2002
 
2003
+ /*
2004
+ * A resource command's text through the resource command redactor (the
2005
+ * program's own rules, then the generic ones), or the text unchanged
2006
+ * when it is not one. Pure; redactAiJobText still runs after it.
2007
+ */
2008
+ public static redactResourceCommandText(
2009
+ text: string,
2010
+ resourceCommand?:
2011
+ | { resourceType: AiResourceType; program: string }
2012
+ | undefined,
2013
+ ): string {
2014
+ if (!resourceCommand) {
2015
+ return text;
2016
+ }
2017
+
2018
+ return redactResourceCommandOutput({
2019
+ resourceType: resourceCommand.resourceType,
2020
+ program: resourceCommand.program,
2021
+ text,
2022
+ });
2023
+ }
2024
+
1308
2025
  /*
1309
2026
  * A Runner's text as a Postgres text column can hold it. A NUL byte is
1310
2027
  * ordinary in what a Runner reports — `kubectl logs` of a log that was
@@ -1333,6 +2050,18 @@ export class Service extends DatabaseService<Model> {
1333
2050
  output?: string | undefined;
1334
2051
  exitCode?: number | undefined;
1335
2052
  errorMessage?: string | undefined;
2053
+ /*
2054
+ * Set by the resource AI agent's ingress for its ResourceCommand jobs:
2055
+ * the job's resource type and program (payload.program). The output is
2056
+ * then also run through the resource command redactor (docker inspect
2057
+ * env values, Proxmox and govc secrets, database literals, Ceph keys)
2058
+ * before the AI-job redaction, so a stored row never depends on the
2059
+ * agent having redacted it first. Absent for every other job, whose
2060
+ * text is stored exactly as before.
2061
+ */
2062
+ resourceCommand?:
2063
+ | { resourceType: AiResourceType; program: string }
2064
+ | undefined;
1336
2065
  }): Promise<boolean> {
1337
2066
  const dataSource: ReturnType<typeof PostgresAppInstance.getDataSource> =
1338
2067
  PostgresAppInstance.getDataSource();
@@ -1365,11 +2094,20 @@ export class Service extends DatabaseService<Model> {
1365
2094
  * redacted text for an AI-origin row and the verbatim text otherwise.
1366
2095
  */
1367
2096
  const redactedOutput: string | null =
1368
- rawOutput === null ? null : Service.redactAiJobText(rawOutput);
2097
+ rawOutput === null
2098
+ ? null
2099
+ : Service.redactAiJobText(
2100
+ Service.redactResourceCommandText(rawOutput, data.resourceCommand),
2101
+ );
1369
2102
  const redactedErrorMessage: string | null =
1370
2103
  rawErrorMessage === null
1371
2104
  ? null
1372
- : Service.redactAiJobText(rawErrorMessage);
2105
+ : Service.redactAiJobText(
2106
+ Service.redactResourceCommandText(
2107
+ rawErrorMessage,
2108
+ data.resourceCommand,
2109
+ ),
2110
+ );
1373
2111
 
1374
2112
  /*
1375
2113
  * Only the agent that holds the lease is allowed to write the terminal
@@ -1458,6 +2196,10 @@ export class Service extends DatabaseService<Model> {
1458
2196
  // The timeout reason is worded for what the job is.
1459
2197
  origin: true,
1460
2198
  stepType: true,
2199
+ targetKubernetesAiAgentId: true,
2200
+ // A resource command names its resource's AI agent.
2201
+ targetResourceAiAgentId: true,
2202
+ resourceType: true,
1461
2203
  },
1462
2204
  props: { isRoot: true },
1463
2205
  });
@@ -1504,6 +2246,8 @@ export class Service extends DatabaseService<Model> {
1504
2246
  stepType: job.stepType,
1505
2247
  claimTimeoutInMs: data.claimTimeoutInMs,
1506
2248
  executionTimeoutInMs: data.executionTimeoutInMs,
2249
+ isForKubernetesAiAgent: Boolean(job.targetKubernetesAiAgentId),
2250
+ resourceType: job.resourceType,
1507
2251
  }),
1508
2252
  });
1509
2253
  }