@oneuptime/common 14.0.9 → 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 (383) 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 +2 -0
  9. package/Models/DatabaseModels/PodmanHost.ts +213 -0
  10. package/Models/DatabaseModels/ProxmoxCluster.ts +213 -0
  11. package/Models/DatabaseModels/ResourceAiAgent.ts +419 -0
  12. package/Models/DatabaseModels/RunnerJob.ts +144 -0
  13. package/Models/DatabaseModels/VMwareVCenter.ts +213 -0
  14. package/Server/API/AutoRemediationAPI.ts +392 -1
  15. package/Server/API/ResourceAiAccessAPI.ts +1669 -0
  16. package/Server/Infrastructure/Postgres/SchemaMigrations/1796300000000-AddResourceAiAgents.ts +423 -0
  17. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +2 -0
  18. package/Server/Infrastructure/Semaphore.ts +22 -0
  19. package/Server/Middleware/TelemetryIngest.ts +15 -5
  20. package/Server/Services/AnalyticsDatabaseService.ts +45 -1
  21. package/Server/Services/AutoRemediationRuleEngineService.ts +940 -112
  22. package/Server/Services/CephClusterService.ts +109 -1
  23. package/Server/Services/DatabaseServerService.ts +116 -1
  24. package/Server/Services/DockerHostService.ts +109 -1
  25. package/Server/Services/DockerSwarmClusterService.ts +113 -1
  26. package/Server/Services/HostService.ts +126 -4
  27. package/Server/Services/MetricRecordingRuleService.ts +47 -0
  28. package/Server/Services/PodmanHostService.ts +109 -1
  29. package/Server/Services/ProxmoxClusterService.ts +110 -1
  30. package/Server/Services/ResourceAiAccessService.ts +1439 -0
  31. package/Server/Services/ResourceAiAgentJobService.ts +202 -0
  32. package/Server/Services/ResourceAiAgentService.ts +2432 -0
  33. package/Server/Services/RunnerJobService.ts +611 -4
  34. package/Server/Services/TelemetryUsageBillingService.ts +28 -0
  35. package/Server/Services/TraceRecordingRuleService.ts +33 -0
  36. package/Server/Services/VMwareVCenterService.ts +110 -1
  37. package/Server/Utils/AI/Remediation/RemediationCommandTools.ts +1434 -32
  38. package/Server/Utils/AI/Remediation/RemediationExecutionRunner.ts +935 -21
  39. package/Server/Utils/AI/Remediation/RemediationPlanRunner.ts +25 -1
  40. package/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.ts +577 -0
  41. package/Server/Utils/AI/ResourceAccess/ResourceAccessContext.ts +271 -0
  42. package/Server/Utils/AI/ResourceAccess/ResourceAccessToolNames.ts +45 -0
  43. package/Server/Utils/AI/ResourceAccess/ResourceAiAccessSettings.ts +964 -0
  44. package/Server/Utils/AI/ResourceAccess/ResourceAiDeleteCleanup.ts +333 -0
  45. package/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.ts +873 -0
  46. package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +72 -2
  47. package/Server/Utils/AI/SRE/AlertInvestigationRunner.ts +72 -5
  48. package/Server/Utils/AI/SRE/IncidentInvestigationRunner.ts +72 -5
  49. package/Server/Utils/AutoRemediation/CommandPlanExecutor.ts +396 -13
  50. package/Server/Utils/AutoRemediation/RemediationVerifier.ts +35 -2
  51. package/Server/Utils/Database/ProjectScopedReferenceValidator.ts +9 -1
  52. package/Server/Utils/SessionReplay/SessionReplayBudgetMetrics.ts +920 -0
  53. package/Server/Utils/SessionReplay/SessionReplayUsage.ts +84 -6
  54. package/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.ts +35 -15
  55. package/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.ts +33 -15
  56. package/Server/Utils/Workspace/MicrosoftTeams/Actions/Auth.ts +21 -1
  57. package/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.ts +298 -224
  58. package/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.ts +35 -15
  59. package/Server/Utils/Workspace/MicrosoftTeams/Actions/ScheduledMaintenance.ts +389 -175
  60. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +366 -143
  61. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsActivityDeduplicator.ts +163 -0
  62. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCardChoices.ts +396 -0
  63. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateCommands.ts +418 -0
  64. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsMessageSize.ts +152 -0
  65. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsReplies.ts +251 -0
  66. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsTimezone.ts +214 -0
  67. package/Tests/App/Dashboard/ClusterAccessNotice.test.tsx +93 -0
  68. package/Tests/App/Dashboard/DatabaseDocumentationMarkdown.test.ts +18 -6
  69. package/Tests/App/Dashboard/InvestigationInfrastructureTools.test.tsx +506 -0
  70. package/Tests/App/Dashboard/RemediationSuggestionCardDescription.test.tsx +209 -0
  71. package/Tests/App/Dashboard/RemediationSuggestionCardResource.test.tsx +317 -0
  72. package/Tests/App/Dashboard/ResourceAiAccessSettingsUtil.test.ts +921 -0
  73. package/Tests/App/Dashboard/ResourceAiAgentInstall.test.ts +860 -0
  74. package/Tests/App/Dashboard/ResourceAiAgentPage.test.tsx +1721 -0
  75. package/Tests/App/Dashboard/ResourceAiAgentStatus.test.ts +1002 -0
  76. package/Tests/App/Dashboard/ResourceAiInsightsPage.test.tsx +931 -0
  77. package/Tests/App/Dashboard/ResourceAiNavigation.test.tsx +575 -0
  78. package/Tests/App/Dashboard/RunbookStepTypeMaps.test.ts +38 -7
  79. package/Tests/Models/DatabaseModels/DatabaseServerModels.test.ts +33 -1
  80. package/Tests/Models/DatabaseModels/ResourceAiAccessColumns.test.ts +738 -0
  81. package/Tests/Models/DatabaseModels/ResourceAiAgentModel.test.ts +842 -0
  82. package/Tests/Server/API/AutoRemediationApproveResourceRound.test.ts +835 -0
  83. package/Tests/Server/API/ResourceAiAccessAPI.test.ts +2730 -0
  84. package/Tests/Server/Infrastructure/Postgres/AddDatabaseServerTablesMigration.test.ts +60 -0
  85. package/Tests/Server/Infrastructure/Postgres/AddResourceAiAgentsMigration.test.ts +659 -0
  86. package/Tests/Server/Infrastructure/SemaphoreMutex.test.ts +31 -0
  87. package/Tests/Server/Middleware/TelemetryIngestBrowserKey.test.ts +63 -5
  88. package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerPinnedKey.test.ts +103 -5
  89. package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerRateLimit.test.ts +19 -1
  90. package/Tests/Server/Services/AutoRemediationResourceRuleEngine.test.ts +1279 -0
  91. package/Tests/Server/Services/DatabaseServerService.test.ts +55 -0
  92. package/Tests/Server/Services/GroupTelemetryUsageExcludeNames.test.ts +299 -0
  93. package/Tests/Server/Services/HostServiceFindOrCreateMemo.test.ts +44 -0
  94. package/Tests/Server/Services/MonitorProbeServiceIntervalScheduling.test.ts +45 -6
  95. package/Tests/Server/Services/RecordingRuleReservedMetricName.test.ts +171 -0
  96. package/Tests/Server/Services/ResourceAiAccessChangeAuthorization.test.ts +256 -0
  97. package/Tests/Server/Services/ResourceAiAccessService.test.ts +1373 -0
  98. package/Tests/Server/Services/ResourceAiAgentJobService.test.ts +375 -0
  99. package/Tests/Server/Services/ResourceAiAgentServiceHelpers.test.ts +1114 -0
  100. package/Tests/Server/Services/ResourceAiAgentServiceLifecycle.test.ts +1050 -0
  101. package/Tests/Server/Services/ResourceAiAgentServiceRegister.test.ts +2251 -0
  102. package/Tests/Server/Services/ResourceAiSettingsCreate.test.ts +373 -0
  103. package/Tests/Server/Services/ResourceAiSettingsPermission.test.ts +1042 -0
  104. package/Tests/Server/Services/ResourceServiceDeleteCleansUpAi.test.ts +319 -0
  105. package/Tests/Server/Services/RunnerJobEnqueueKubectl.test.ts +105 -0
  106. package/Tests/Server/Services/RunnerJobEnqueueResourceCommand.test.ts +986 -0
  107. package/Tests/Server/Services/RunnerJobResourceCommandLane.test.ts +211 -0
  108. package/Tests/Server/Services/RunnerJobResourceCommandTimeoutAndRedaction.test.ts +352 -0
  109. package/Tests/Server/Services/TelemetryUsageBillingSloExclusion.test.ts +218 -0
  110. package/Tests/Server/TestingUtils/Services/FakeRunnerJobCount.ts +145 -0
  111. package/Tests/Server/Utils/AI/InvestigationInfrastructureAccessWiring.test.ts +453 -0
  112. package/Tests/Server/Utils/AI/InvestigationInfrastructureReport.test.ts +721 -0
  113. package/Tests/Server/Utils/AI/RemediationCommandTools.test.ts +94 -1
  114. package/Tests/Server/Utils/AI/RemediationCommandToolsResource.test.ts +1530 -0
  115. package/Tests/Server/Utils/AI/RemediationExecutionRunnerResourceMode.test.ts +1249 -0
  116. package/Tests/Server/Utils/AI/RemediationPlanRunner.test.ts +117 -0
  117. package/Tests/Server/Utils/AI/RemediationResourceCopyParity.test.ts +463 -0
  118. package/Tests/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.test.ts +722 -0
  119. package/Tests/Server/Utils/AI/ResourceAccess/ResourceAccessContext.test.ts +266 -0
  120. package/Tests/Server/Utils/AI/ResourceAccess/ResourceAiAccessSettings.test.ts +1220 -0
  121. package/Tests/Server/Utils/AI/ResourceAccess/ResourceAiDeleteCleanup.test.ts +569 -0
  122. package/Tests/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.test.ts +830 -0
  123. package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutorResource.test.ts +717 -0
  124. package/Tests/Server/Utils/AutoRemediation/RemediationVerifierResourceFollowUp.test.ts +338 -0
  125. package/Tests/Server/Utils/Monitor/Criteria/SessionReplayBudgetTemplateCriteria.test.ts +422 -0
  126. package/Tests/Server/Utils/SessionReplay/SessionReplayBudgetMetrics.test.ts +1647 -0
  127. package/Tests/Server/Utils/SessionReplay/SessionReplayUsage.test.ts +143 -1
  128. package/Tests/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.test.ts +33 -3
  129. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsAccountNotLinked.test.ts +1093 -0
  130. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsActivityDeduplicator.test.ts +1049 -0
  131. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCardChoices.test.ts +1676 -0
  132. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateCards.test.ts +2884 -0
  133. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateCommands.test.ts +2490 -0
  134. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateSubmit.test.ts +2293 -0
  135. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateSubmitServerTimezone.test.ts +386 -0
  136. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsMessageSize.test.ts +1477 -0
  137. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsReplies.test.ts +1967 -0
  138. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsStripHtmlTags.test.ts +92 -0
  139. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsSubmittedFormRemoval.test.ts +1819 -0
  140. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsTimezone.test.ts +1033 -0
  141. package/Tests/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsTimezoneServerZone.test.ts +610 -0
  142. package/Tests/Server/Utils/Workspace/MicrosoftTeamsBotMessageHandling.test.ts +2610 -0
  143. package/Tests/Server/Utils/Workspace/MicrosoftTeamsCreateCommandsEndToEnd.test.ts +4672 -0
  144. package/Tests/Server/Utils/Workspace/WorkspaceCreateProjectReferences.test.ts +190 -65
  145. package/Tests/Types/AutoRemediation/AiRemediationCommandPlan.test.ts +10 -4
  146. package/Tests/Types/AutoRemediation/AiRemediationCommandPlanResourceCommand.test.ts +305 -0
  147. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCatalog.test.ts +277 -13
  148. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationUtil.test.ts +113 -0
  149. package/Tests/Types/Monitor/RumAlertTemplates.test.ts +773 -2
  150. package/Tests/Types/ResourceAiAgent/AiResourceType.test.ts +419 -0
  151. package/Tests/Types/ResourceAiAgent/ResourceAiAccess.test.ts +517 -0
  152. package/Tests/Types/Runbook/RunbookStepType.test.ts +147 -8
  153. package/Tests/UI/Rum/RecordingHealthDashboard.test.tsx +769 -1
  154. package/Tests/Utils/AiRemediation/Resource/CephCommandPolicy.test.ts +1653 -0
  155. package/Tests/Utils/AiRemediation/Resource/CephOutputRedaction.test.ts +204 -0
  156. package/Tests/Utils/AiRemediation/Resource/DatabaseCommandPolicy.test.ts +1077 -0
  157. package/Tests/Utils/AiRemediation/Resource/DatabaseDiagnosticCatalog.test.ts +558 -0
  158. package/Tests/Utils/AiRemediation/Resource/DatabaseQueryRedactor.test.ts +834 -0
  159. package/Tests/Utils/AiRemediation/Resource/DockerCliGrammar.test.ts +747 -0
  160. package/Tests/Utils/AiRemediation/Resource/DockerEngineCommandPolicy.test.ts +1259 -0
  161. package/Tests/Utils/AiRemediation/Resource/DockerOutputRedaction.test.ts +386 -0
  162. package/Tests/Utils/AiRemediation/Resource/DockerSwarmCommandPolicy.test.ts +782 -0
  163. package/Tests/Utils/AiRemediation/Resource/GovcCommandPolicy.test.ts +2259 -0
  164. package/Tests/Utils/AiRemediation/Resource/HostCommandPolicy.test.ts +2019 -0
  165. package/Tests/Utils/AiRemediation/Resource/ProxmoxCommandPolicy.test.ts +2497 -0
  166. package/Tests/Utils/AiRemediation/Resource/ResourceCommandPolicy.test.ts +1305 -0
  167. package/Tests/Utils/AiRemediation/Resource/ResourceCommandPolicyCore.test.ts +585 -0
  168. package/Tests/Utils/AiRemediation/Resource/ResourceOutputRedactor.test.ts +334 -0
  169. package/Tests/Utils/AiRemediation/Resource/ResourceOutputRedactorCopyParity.test.ts +98 -0
  170. package/Tests/Utils/AiRemediation/Resource/ResourcePolicyImportClosure.test.ts +391 -0
  171. package/Tests/Utils/AiRemediation/ResourceAiAgentPolicyCopyParity.test.ts +497 -0
  172. package/Tests/Utils/SessionReplay/SessionReplayBudgetMetricType.test.ts +383 -0
  173. package/Types/AI/ResourceAiAccessApi.ts +140 -0
  174. package/Types/AI/ResourceAiAccessPermissions.ts +126 -0
  175. package/Types/AutoRemediation/AiRemediationCommandPlan.ts +183 -2
  176. package/Types/Monitor/Recommendation/MonitorRecommendationCatalog.ts +55 -22
  177. package/Types/Monitor/Recommendation/MonitorRecommendationTypes.ts +35 -3
  178. package/Types/Monitor/RumAlertTemplates.ts +351 -4
  179. package/Types/ResourceAiAgent/AiResourceType.ts +310 -0
  180. package/Types/ResourceAiAgent/ResourceAiAccess.ts +574 -0
  181. package/Types/Rum/SessionReplayBudgetMetricType.ts +47 -0
  182. package/Types/Runbook/RunbookStepType.ts +29 -0
  183. package/Types/Telemetry/TelemetryIngestSurface.ts +14 -2
  184. package/Utils/AI/InvestigationReport.ts +121 -15
  185. package/Utils/AiRemediation/Resource/CephCommandPolicy.ts +1936 -0
  186. package/Utils/AiRemediation/Resource/DatabaseCommandPolicy.ts +166 -0
  187. package/Utils/AiRemediation/Resource/DatabaseDiagnosticCatalog.ts +1532 -0
  188. package/Utils/AiRemediation/Resource/DatabaseQueryRedactor.ts +1394 -0
  189. package/Utils/AiRemediation/Resource/DockerCliGrammar.ts +1839 -0
  190. package/Utils/AiRemediation/Resource/DockerEngineCommandPolicy.ts +490 -0
  191. package/Utils/AiRemediation/Resource/DockerSwarmCommandPolicy.ts +687 -0
  192. package/Utils/AiRemediation/Resource/GovcCommandPolicy.ts +2096 -0
  193. package/Utils/AiRemediation/Resource/HostCommandPolicy.ts +2982 -0
  194. package/Utils/AiRemediation/Resource/ProxmoxCommandPolicy.ts +1679 -0
  195. package/Utils/AiRemediation/Resource/ResourceCommandPolicy.ts +851 -0
  196. package/Utils/AiRemediation/Resource/ResourceCommandPolicyCore.ts +593 -0
  197. package/Utils/AiRemediation/Resource/ResourceOutputRedactor.ts +2812 -0
  198. package/Utils/SessionReplay/SessionReplayBudgetMetricType.ts +184 -0
  199. package/build/dist/Models/DatabaseModels/AutoRemediationSuggestion.js +62 -0
  200. package/build/dist/Models/DatabaseModels/AutoRemediationSuggestion.js.map +1 -1
  201. package/build/dist/Models/DatabaseModels/CephCluster.js +219 -0
  202. package/build/dist/Models/DatabaseModels/CephCluster.js.map +1 -1
  203. package/build/dist/Models/DatabaseModels/DatabaseServer.js +219 -0
  204. package/build/dist/Models/DatabaseModels/DatabaseServer.js.map +1 -1
  205. package/build/dist/Models/DatabaseModels/DockerHost.js +219 -0
  206. package/build/dist/Models/DatabaseModels/DockerHost.js.map +1 -1
  207. package/build/dist/Models/DatabaseModels/DockerSwarmCluster.js +219 -0
  208. package/build/dist/Models/DatabaseModels/DockerSwarmCluster.js.map +1 -1
  209. package/build/dist/Models/DatabaseModels/GlobalConfig.js +1 -1
  210. package/build/dist/Models/DatabaseModels/GlobalConfig.js.map +1 -1
  211. package/build/dist/Models/DatabaseModels/Host.js +219 -0
  212. package/build/dist/Models/DatabaseModels/Host.js.map +1 -1
  213. package/build/dist/Models/DatabaseModels/Index.js +2 -0
  214. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  215. package/build/dist/Models/DatabaseModels/PodmanHost.js +219 -0
  216. package/build/dist/Models/DatabaseModels/PodmanHost.js.map +1 -1
  217. package/build/dist/Models/DatabaseModels/ProxmoxCluster.js +219 -0
  218. package/build/dist/Models/DatabaseModels/ProxmoxCluster.js.map +1 -1
  219. package/build/dist/Models/DatabaseModels/ResourceAiAgent.js +439 -0
  220. package/build/dist/Models/DatabaseModels/ResourceAiAgent.js.map +1 -0
  221. package/build/dist/Models/DatabaseModels/RunnerJob.js +145 -0
  222. package/build/dist/Models/DatabaseModels/RunnerJob.js.map +1 -1
  223. package/build/dist/Models/DatabaseModels/VMwareVCenter.js +219 -0
  224. package/build/dist/Models/DatabaseModels/VMwareVCenter.js.map +1 -1
  225. package/build/dist/Server/API/AutoRemediationAPI.js +231 -1
  226. package/build/dist/Server/API/AutoRemediationAPI.js.map +1 -1
  227. package/build/dist/Server/API/ResourceAiAccessAPI.js +1119 -0
  228. package/build/dist/Server/API/ResourceAiAccessAPI.js.map +1 -0
  229. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796300000000-AddResourceAiAgents.js +168 -0
  230. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796300000000-AddResourceAiAgents.js.map +1 -0
  231. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +2 -0
  232. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  233. package/build/dist/Server/Infrastructure/Semaphore.js +6 -0
  234. package/build/dist/Server/Infrastructure/Semaphore.js.map +1 -1
  235. package/build/dist/Server/Middleware/TelemetryIngest.js +12 -5
  236. package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
  237. package/build/dist/Server/Services/AnalyticsDatabaseService.js +26 -1
  238. package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
  239. package/build/dist/Server/Services/AutoRemediationRuleEngineService.js +601 -3
  240. package/build/dist/Server/Services/AutoRemediationRuleEngineService.js.map +1 -1
  241. package/build/dist/Server/Services/CephClusterService.js +104 -0
  242. package/build/dist/Server/Services/CephClusterService.js.map +1 -1
  243. package/build/dist/Server/Services/DatabaseServerService.js +99 -0
  244. package/build/dist/Server/Services/DatabaseServerService.js.map +1 -1
  245. package/build/dist/Server/Services/DockerHostService.js +104 -0
  246. package/build/dist/Server/Services/DockerHostService.js.map +1 -1
  247. package/build/dist/Server/Services/DockerSwarmClusterService.js +104 -0
  248. package/build/dist/Server/Services/DockerSwarmClusterService.js.map +1 -1
  249. package/build/dist/Server/Services/HostService.js +114 -2
  250. package/build/dist/Server/Services/HostService.js.map +1 -1
  251. package/build/dist/Server/Services/MetricRecordingRuleService.js +46 -0
  252. package/build/dist/Server/Services/MetricRecordingRuleService.js.map +1 -1
  253. package/build/dist/Server/Services/PodmanHostService.js +104 -0
  254. package/build/dist/Server/Services/PodmanHostService.js.map +1 -1
  255. package/build/dist/Server/Services/ProxmoxClusterService.js +104 -0
  256. package/build/dist/Server/Services/ProxmoxClusterService.js.map +1 -1
  257. package/build/dist/Server/Services/ResourceAiAccessService.js +1028 -0
  258. package/build/dist/Server/Services/ResourceAiAccessService.js.map +1 -0
  259. package/build/dist/Server/Services/ResourceAiAgentJobService.js +173 -0
  260. package/build/dist/Server/Services/ResourceAiAgentJobService.js.map +1 -0
  261. package/build/dist/Server/Services/ResourceAiAgentService.js +1687 -0
  262. package/build/dist/Server/Services/ResourceAiAgentService.js.map +1 -0
  263. package/build/dist/Server/Services/RunnerJobService.js +344 -5
  264. package/build/dist/Server/Services/RunnerJobService.js.map +1 -1
  265. package/build/dist/Server/Services/TelemetryUsageBillingService.js +26 -0
  266. package/build/dist/Server/Services/TelemetryUsageBillingService.js.map +1 -1
  267. package/build/dist/Server/Services/TraceRecordingRuleService.js +37 -0
  268. package/build/dist/Server/Services/TraceRecordingRuleService.js.map +1 -1
  269. package/build/dist/Server/Services/VMwareVCenterService.js +104 -0
  270. package/build/dist/Server/Services/VMwareVCenterService.js.map +1 -1
  271. package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js +1029 -30
  272. package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js.map +1 -1
  273. package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js +633 -28
  274. package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js.map +1 -1
  275. package/build/dist/Server/Utils/AI/Remediation/RemediationPlanRunner.js +21 -1
  276. package/build/dist/Server/Utils/AI/Remediation/RemediationPlanRunner.js.map +1 -1
  277. package/build/dist/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.js +330 -0
  278. package/build/dist/Server/Utils/AI/ResourceAccess/InfrastructureInvestigationToolkit.js.map +1 -0
  279. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAccessContext.js +160 -0
  280. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAccessContext.js.map +1 -0
  281. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAccessToolNames.js +33 -0
  282. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAccessToolNames.js.map +1 -0
  283. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAiAccessSettings.js +640 -0
  284. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAiAccessSettings.js.map +1 -0
  285. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAiDeleteCleanup.js +226 -0
  286. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceAiDeleteCleanup.js.map +1 -0
  287. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.js +600 -0
  288. package/build/dist/Server/Utils/AI/ResourceAccess/ResourceCommandJobRunner.js.map +1 -0
  289. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +50 -4
  290. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
  291. package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js +55 -4
  292. package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js.map +1 -1
  293. package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js +55 -4
  294. package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js.map +1 -1
  295. package/build/dist/Server/Utils/AutoRemediation/CommandPlanExecutor.js +290 -13
  296. package/build/dist/Server/Utils/AutoRemediation/CommandPlanExecutor.js.map +1 -1
  297. package/build/dist/Server/Utils/AutoRemediation/RemediationVerifier.js +29 -1
  298. package/build/dist/Server/Utils/AutoRemediation/RemediationVerifier.js.map +1 -1
  299. package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js +9 -1
  300. package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js.map +1 -1
  301. package/build/dist/Server/Utils/SessionReplay/SessionReplayBudgetMetrics.js +627 -0
  302. package/build/dist/Server/Utils/SessionReplay/SessionReplayBudgetMetrics.js.map +1 -0
  303. package/build/dist/Server/Utils/SessionReplay/SessionReplayUsage.js +60 -5
  304. package/build/dist/Server/Utils/SessionReplay/SessionReplayUsage.js.map +1 -1
  305. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.js +19 -15
  306. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Alert.js.map +1 -1
  307. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.js +19 -15
  308. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/AlertEpisode.js.map +1 -1
  309. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Auth.js +17 -1
  310. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Auth.js.map +1 -1
  311. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js +183 -209
  312. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/Incident.js.map +1 -1
  313. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.js +19 -15
  314. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/IncidentEpisode.js.map +1 -1
  315. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/ScheduledMaintenance.js +233 -167
  316. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/Actions/ScheduledMaintenance.js.map +1 -1
  317. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +263 -110
  318. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
  319. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsActivityDeduplicator.js +129 -0
  320. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsActivityDeduplicator.js.map +1 -0
  321. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCardChoices.js +266 -0
  322. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCardChoices.js.map +1 -0
  323. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateCommands.js +258 -0
  324. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsCreateCommands.js.map +1 -0
  325. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsMessageSize.js +104 -0
  326. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsMessageSize.js.map +1 -0
  327. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsReplies.js +183 -0
  328. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsReplies.js.map +1 -0
  329. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsTimezone.js +123 -0
  330. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeamsTimezone.js.map +1 -0
  331. package/build/dist/Types/AI/ResourceAiAccessApi.js +30 -0
  332. package/build/dist/Types/AI/ResourceAiAccessApi.js.map +1 -0
  333. package/build/dist/Types/AI/ResourceAiAccessPermissions.js +98 -0
  334. package/build/dist/Types/AI/ResourceAiAccessPermissions.js.map +1 -0
  335. package/build/dist/Types/AutoRemediation/AiRemediationCommandPlan.js +116 -29
  336. package/build/dist/Types/AutoRemediation/AiRemediationCommandPlan.js.map +1 -1
  337. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js +47 -21
  338. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js.map +1 -1
  339. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js +5 -0
  340. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js.map +1 -1
  341. package/build/dist/Types/Monitor/RumAlertTemplates.js +199 -3
  342. package/build/dist/Types/Monitor/RumAlertTemplates.js.map +1 -1
  343. package/build/dist/Types/ResourceAiAgent/AiResourceType.js +242 -0
  344. package/build/dist/Types/ResourceAiAgent/AiResourceType.js.map +1 -0
  345. package/build/dist/Types/ResourceAiAgent/ResourceAiAccess.js +275 -0
  346. package/build/dist/Types/ResourceAiAgent/ResourceAiAccess.js.map +1 -0
  347. package/build/dist/Types/Rum/SessionReplayBudgetMetricType.js +45 -0
  348. package/build/dist/Types/Rum/SessionReplayBudgetMetricType.js.map +1 -0
  349. package/build/dist/Types/Runbook/RunbookStepType.js +27 -0
  350. package/build/dist/Types/Runbook/RunbookStepType.js.map +1 -1
  351. package/build/dist/Types/Telemetry/TelemetryIngestSurface.js +13 -2
  352. package/build/dist/Types/Telemetry/TelemetryIngestSurface.js.map +1 -1
  353. package/build/dist/Utils/AI/InvestigationReport.js +71 -11
  354. package/build/dist/Utils/AI/InvestigationReport.js.map +1 -1
  355. package/build/dist/Utils/AiRemediation/Resource/CephCommandPolicy.js +1462 -0
  356. package/build/dist/Utils/AiRemediation/Resource/CephCommandPolicy.js.map +1 -0
  357. package/build/dist/Utils/AiRemediation/Resource/DatabaseCommandPolicy.js +122 -0
  358. package/build/dist/Utils/AiRemediation/Resource/DatabaseCommandPolicy.js.map +1 -0
  359. package/build/dist/Utils/AiRemediation/Resource/DatabaseDiagnosticCatalog.js +1139 -0
  360. package/build/dist/Utils/AiRemediation/Resource/DatabaseDiagnosticCatalog.js.map +1 -0
  361. package/build/dist/Utils/AiRemediation/Resource/DatabaseQueryRedactor.js +1060 -0
  362. package/build/dist/Utils/AiRemediation/Resource/DatabaseQueryRedactor.js.map +1 -0
  363. package/build/dist/Utils/AiRemediation/Resource/DockerCliGrammar.js +1301 -0
  364. package/build/dist/Utils/AiRemediation/Resource/DockerCliGrammar.js.map +1 -0
  365. package/build/dist/Utils/AiRemediation/Resource/DockerEngineCommandPolicy.js +370 -0
  366. package/build/dist/Utils/AiRemediation/Resource/DockerEngineCommandPolicy.js.map +1 -0
  367. package/build/dist/Utils/AiRemediation/Resource/DockerSwarmCommandPolicy.js +498 -0
  368. package/build/dist/Utils/AiRemediation/Resource/DockerSwarmCommandPolicy.js.map +1 -0
  369. package/build/dist/Utils/AiRemediation/Resource/GovcCommandPolicy.js +1565 -0
  370. package/build/dist/Utils/AiRemediation/Resource/GovcCommandPolicy.js.map +1 -0
  371. package/build/dist/Utils/AiRemediation/Resource/HostCommandPolicy.js +2206 -0
  372. package/build/dist/Utils/AiRemediation/Resource/HostCommandPolicy.js.map +1 -0
  373. package/build/dist/Utils/AiRemediation/Resource/ProxmoxCommandPolicy.js +1129 -0
  374. package/build/dist/Utils/AiRemediation/Resource/ProxmoxCommandPolicy.js.map +1 -0
  375. package/build/dist/Utils/AiRemediation/Resource/ResourceCommandPolicy.js +565 -0
  376. package/build/dist/Utils/AiRemediation/Resource/ResourceCommandPolicy.js.map +1 -0
  377. package/build/dist/Utils/AiRemediation/Resource/ResourceCommandPolicyCore.js +408 -0
  378. package/build/dist/Utils/AiRemediation/Resource/ResourceCommandPolicyCore.js.map +1 -0
  379. package/build/dist/Utils/AiRemediation/Resource/ResourceOutputRedactor.js +1910 -0
  380. package/build/dist/Utils/AiRemediation/Resource/ResourceOutputRedactor.js.map +1 -0
  381. package/build/dist/Utils/SessionReplay/SessionReplayBudgetMetricType.js +160 -0
  382. package/build/dist/Utils/SessionReplay/SessionReplayBudgetMetricType.js.map +1 -0
  383. package/package.json +1 -1
@@ -19,6 +19,7 @@ import UniqueColumnBy from "../../Types/Database/UniqueColumnBy";
19
19
  import IconProp from "../../Types/Icon/IconProp";
20
20
  import ObjectID from "../../Types/ObjectID";
21
21
  import Permission from "../../Types/Permission";
22
+ import { ResourceAiRemediationMode } from "../../Types/ResourceAiAgent/ResourceAiAccess";
22
23
  import TelemetryRetentionConfig from "../../Types/Telemetry/TelemetryRetentionConfig";
23
24
  import {
24
25
  Column,
@@ -1119,4 +1120,216 @@ export default class VMwareVCenter extends BaseModel {
1119
1120
  nullable: true,
1120
1121
  })
1121
1122
  public telemetryRetentionConfig?: TelemetryRetentionConfig = undefined;
1123
+
1124
+ /*
1125
+ * OneUptime AI access to this vCenter through its VMware AI agent (a resource AI
1126
+ * agent, ResourceAiAgent). The settings are plain columns written through
1127
+ * ordinary CRUD, so they exist before any agent registers. The columns
1128
+ * keep the vCenter's own update ACL: anyone who may edit the vCenter may make
1129
+ * AI do LESS; making it do MORE is refused by the service unless the
1130
+ * caller may author a FullAuto auto-remediation rule. The aiAccess*
1131
+ * columns are written only by the server.
1132
+ */
1133
+ @ColumnAccessControl({
1134
+ create: [],
1135
+ read: [
1136
+ Permission.ProjectOwner,
1137
+ Permission.ProjectAdmin,
1138
+ Permission.ProjectMember,
1139
+ Permission.Viewer,
1140
+ Permission.SettingsAdmin,
1141
+ Permission.SettingsMember,
1142
+ Permission.SettingsViewer,
1143
+ Permission.ReadVMwareVCenter,
1144
+ ],
1145
+ update: [
1146
+ Permission.ProjectOwner,
1147
+ Permission.ProjectAdmin,
1148
+ Permission.ProjectMember,
1149
+ Permission.SettingsAdmin,
1150
+ Permission.SettingsMember,
1151
+ Permission.EditVMwareVCenter,
1152
+ ],
1153
+ })
1154
+ @TableColumn({
1155
+ isDefaultValueColumn: true,
1156
+ required: true,
1157
+ type: TableColumnType.Boolean,
1158
+ title: "Let AI Investigate With Read-Only Commands",
1159
+ description:
1160
+ "When on, OneUptime AI runs read-only commands (govc about, ls, vm.info, host.info, events) on this vCenter, through its VMware AI agent, while investigating incidents and alerts linked to it, and uses their output, with secret values redacted, as evidence. Nothing is ever changed by an investigation. Off by default. Anyone who may edit the vCenter can turn it on or off.",
1161
+ defaultValue: false,
1162
+ })
1163
+ @Column({
1164
+ type: ColumnType.Boolean,
1165
+ nullable: false,
1166
+ default: false,
1167
+ })
1168
+ public isAiInvestigationEnabled?: boolean = undefined;
1169
+
1170
+ @ColumnAccessControl({
1171
+ create: [],
1172
+ read: [
1173
+ Permission.ProjectOwner,
1174
+ Permission.ProjectAdmin,
1175
+ Permission.ProjectMember,
1176
+ Permission.Viewer,
1177
+ Permission.SettingsAdmin,
1178
+ Permission.SettingsMember,
1179
+ Permission.SettingsViewer,
1180
+ Permission.ReadVMwareVCenter,
1181
+ ],
1182
+ update: [
1183
+ Permission.ProjectOwner,
1184
+ Permission.ProjectAdmin,
1185
+ Permission.ProjectMember,
1186
+ Permission.SettingsAdmin,
1187
+ Permission.SettingsMember,
1188
+ Permission.EditVMwareVCenter,
1189
+ ],
1190
+ })
1191
+ @TableColumn({
1192
+ isDefaultValueColumn: true,
1193
+ required: true,
1194
+ type: TableColumnType.ShortText,
1195
+ title: "AI Remediation Mode",
1196
+ /*
1197
+ * The API and Terraform docs for the mode: the same semantics as the
1198
+ * ResourceAiRemediationMode doc comment in
1199
+ * Types/ResourceAiAgent/ResourceAiAccess.ts (the canonical text).
1200
+ */
1201
+ description:
1202
+ "Disabled: AI never proposes or runs a change on this vCenter. RequireApproval: AI composes a command plan and a human approves it with one click before anything runs. Automatic: safe changes (SafeWrite) run without a human; a riskier change is proposed for approval unless the vCenter's allowlist names its exact shape. BypassApproval: every change the policy allows — safe AND riskier — runs on its own, except what always needs a human. In EVERY mode: Denied commands never run, commands the policy marks requiresHuman always ask, and the agent itself refuses every write unless it was started with ONEUPTIME_AI_ALLOW_WRITES=true (and then only on the targets ONEUPTIME_AI_WRITE_TARGETS allows, never its protected targets). Anyone who may edit the vCenter can lower the mode; raising it needs Project Owner, Project Admin or Edit Auto Remediation Rule.",
1203
+ defaultValue: ResourceAiRemediationMode.Disabled,
1204
+ example: ResourceAiRemediationMode.RequireApproval,
1205
+ })
1206
+ @Column({
1207
+ type: ColumnType.ShortText,
1208
+ length: ColumnLength.ShortText,
1209
+ nullable: false,
1210
+ default: ResourceAiRemediationMode.Disabled,
1211
+ })
1212
+ public aiRemediationMode?: ResourceAiRemediationMode = undefined;
1213
+
1214
+ @ColumnAccessControl({
1215
+ create: [],
1216
+ read: [
1217
+ Permission.ProjectOwner,
1218
+ Permission.ProjectAdmin,
1219
+ Permission.ProjectMember,
1220
+ Permission.Viewer,
1221
+ Permission.SettingsAdmin,
1222
+ Permission.SettingsMember,
1223
+ Permission.SettingsViewer,
1224
+ Permission.ReadVMwareVCenter,
1225
+ ],
1226
+ update: [
1227
+ Permission.ProjectOwner,
1228
+ Permission.ProjectAdmin,
1229
+ Permission.ProjectMember,
1230
+ Permission.SettingsAdmin,
1231
+ Permission.SettingsMember,
1232
+ Permission.EditVMwareVCenter,
1233
+ ],
1234
+ })
1235
+ @TableColumn({
1236
+ type: TableColumnType.JSON,
1237
+ required: false,
1238
+ title: "AI Command Allowlist",
1239
+ description:
1240
+ "Optional JSON array of command patterns that Automatic mode may run on this vCenter without approval even though they are riskier changes. Each pattern is one command line for this vCenter's agent (govc) and is compared with the command word by word: * stands for exactly one word (a name, an id), never for extra words or flags, and every flag the command uses must be written out in the pattern. At most 50 patterns of at most 500 characters each; a pattern that is not one valid write command for this vCenter is refused. Destructive commands (Denied tier) never run regardless, and a command that always needs a human still asks. Adding a pattern needs Project Owner, Project Admin or Edit Auto Remediation Rule; anyone who may edit the vCenter can remove patterns or clear the list.",
1241
+ })
1242
+ @Column({
1243
+ type: ColumnType.JSON,
1244
+ nullable: true,
1245
+ })
1246
+ public aiCommandAllowlist?: Array<string> = undefined;
1247
+
1248
+ @ColumnAccessControl({
1249
+ create: [],
1250
+ read: [
1251
+ Permission.ProjectOwner,
1252
+ Permission.ProjectAdmin,
1253
+ Permission.ProjectMember,
1254
+ Permission.Viewer,
1255
+ Permission.SettingsAdmin,
1256
+ Permission.SettingsMember,
1257
+ Permission.SettingsViewer,
1258
+ Permission.ReadVMwareVCenter,
1259
+ ],
1260
+ update: [],
1261
+ })
1262
+ @TableColumn({
1263
+ required: false,
1264
+ type: TableColumnType.Date,
1265
+ title: "AI Access Last Verified At",
1266
+ description:
1267
+ "When a command from OneUptime AI last succeeded on this vCenter through its VMware AI agent. Set by the server.",
1268
+ })
1269
+ @Column({
1270
+ type: ColumnType.Date,
1271
+ nullable: true,
1272
+ })
1273
+ public aiAccessLastVerifiedAt?: Date = undefined;
1274
+
1275
+ @ColumnAccessControl({
1276
+ create: [],
1277
+ read: [
1278
+ Permission.ProjectOwner,
1279
+ Permission.ProjectAdmin,
1280
+ Permission.ProjectMember,
1281
+ Permission.Viewer,
1282
+ Permission.SettingsAdmin,
1283
+ Permission.SettingsMember,
1284
+ Permission.SettingsViewer,
1285
+ Permission.ReadVMwareVCenter,
1286
+ ],
1287
+ update: [],
1288
+ })
1289
+ @TableColumn({
1290
+ required: false,
1291
+ type: TableColumnType.LongText,
1292
+ title: "AI Access Last Error",
1293
+ description:
1294
+ "The most recent failure OneUptime AI hit while running a command on this vCenter, kept until the next successful command. Set by the server.",
1295
+ })
1296
+ @Column({
1297
+ type: ColumnType.LongText,
1298
+ nullable: true,
1299
+ })
1300
+ public aiAccessLastError?: string = undefined;
1301
+
1302
+ /*
1303
+ * When this vCenter's AI access was first configured — by anyone writing an
1304
+ * AI access setting. Only the server writes it, and nothing ever clears
1305
+ * it. A registering VMware AI agent reads it to tell "never configured" (it may
1306
+ * apply its first-connection defaults) from "an operator chose settings,
1307
+ * perhaps before installing the agent" (every setting stays as chosen).
1308
+ */
1309
+ @ColumnAccessControl({
1310
+ create: [],
1311
+ read: [
1312
+ Permission.ProjectOwner,
1313
+ Permission.ProjectAdmin,
1314
+ Permission.ProjectMember,
1315
+ Permission.Viewer,
1316
+ Permission.SettingsAdmin,
1317
+ Permission.SettingsMember,
1318
+ Permission.SettingsViewer,
1319
+ Permission.ReadVMwareVCenter,
1320
+ ],
1321
+ update: [],
1322
+ })
1323
+ @TableColumn({
1324
+ required: false,
1325
+ type: TableColumnType.Date,
1326
+ title: "AI Access Configured At",
1327
+ description:
1328
+ "When OneUptime AI access to this vCenter was first configured by anyone saving an AI access setting. Set by the server; never cleared, so a VMware AI agent that registers later never overwrites a setting an operator chose.",
1329
+ })
1330
+ @Column({
1331
+ type: ColumnType.Date,
1332
+ nullable: true,
1333
+ })
1334
+ public aiAccessConfiguredAt?: Date = undefined;
1122
1335
  }
@@ -54,7 +54,25 @@ import RunnerService from "../Services/RunnerService";
54
54
  import KubernetesClusterAiAccessService from "../Services/KubernetesClusterAiAccessService";
55
55
  import CommandPlanExecutor from "../Utils/AutoRemediation/CommandPlanExecutor";
56
56
  import RemediationCommandToolkit from "../Utils/AI/Remediation/RemediationCommandTools";
57
- import { isClusterRemediationRound } from "../Utils/AI/Remediation/RemediationExecutionRunner";
57
+ import {
58
+ isClusterRemediationRound,
59
+ isResourceRemediationRound,
60
+ } from "../Utils/AI/Remediation/RemediationExecutionRunner";
61
+ import ResourceAiAccessService, {
62
+ describeResourceNoun,
63
+ getResourceAiAgentPage,
64
+ } from "../Services/ResourceAiAccessService";
65
+ import AiResourceType, {
66
+ AI_RESOURCE_TYPE_INFO,
67
+ isAiResourceType,
68
+ } from "../../Types/ResourceAiAgent/AiResourceType";
69
+ import {
70
+ ResourceAiAccessGap,
71
+ ResourceAiAccessStatus,
72
+ ResourceCommandTier,
73
+ } from "../../Types/ResourceAiAgent/ResourceAiAccess";
74
+ import ResourceCommandPolicy from "../../Utils/AiRemediation/Resource/ResourceCommandPolicy";
75
+ import { ResourceCommandPolicyResult } from "../../Utils/AiRemediation/Resource/ResourceCommandPolicyCore";
58
76
  import logger from "../Utils/Logger";
59
77
 
60
78
  const router: ExpressRouter = Express.getRouter();
@@ -398,6 +416,329 @@ function assertNotHostStepOnKubernetesAgent(data: {
398
416
  }
399
417
  }
400
418
 
419
+ /*
420
+ * ------------------------------------------------------------------
421
+ * Resource commands (a Docker or Podman host, a Docker Swarm, Proxmox,
422
+ * VMware or Ceph cluster, a database server or a host, reached through its
423
+ * resource AI agent)
424
+ * ------------------------------------------------------------------
425
+ */
426
+
427
+ // One approval reads each resource's AI access status at most once.
428
+ type ResourceStatusCache = Map<string, ResourceAiAccessStatus | null>;
429
+
430
+ function getResourceStatusKey(
431
+ resourceType: AiResourceType,
432
+ resourceId: string,
433
+ ): string {
434
+ return `${resourceType}:${resourceId.toLowerCase()}`;
435
+ }
436
+
437
+ async function getResourceStatusOnce(data: {
438
+ resourceType: AiResourceType;
439
+ resourceId: string;
440
+ projectId: ObjectID;
441
+ statusByResourceKey: ResourceStatusCache;
442
+ }): Promise<ResourceAiAccessStatus | null> {
443
+ const key: string = getResourceStatusKey(data.resourceType, data.resourceId);
444
+
445
+ if (data.statusByResourceKey.has(key)) {
446
+ return data.statusByResourceKey.get(key) || null;
447
+ }
448
+
449
+ const status: ResourceAiAccessStatus | null =
450
+ await ResourceAiAccessService.getStatusForResource({
451
+ projectId: data.projectId,
452
+ resourceType: data.resourceType,
453
+ resourceId: new ObjectID(data.resourceId),
454
+ });
455
+
456
+ data.statusByResourceKey.set(key, status);
457
+
458
+ return status;
459
+ }
460
+
461
+ // 'Docker host "web-1"' — a resource command's resource, from its snapshot.
462
+ function describeCommandResource(command: AiRemediationCommand): string {
463
+ return `${
464
+ isAiResourceType(command.resourceType)
465
+ ? describeResourceNoun(command.resourceType)
466
+ : "resource"
467
+ } "${command.resourceNameSnapshot || command.resourceId || "(unknown)"}"`;
468
+ }
469
+
470
+ /*
471
+ * The resource AI agent's side of the Runner consent re-check — the
472
+ * resource sibling of assertAiAgentCanRunPlan. A ResourceCommand step names
473
+ * its resource's AI agent (a ResourceAiAgent row id) where a Runner id
474
+ * would be. The agent is not a Runner row, so there is no canRunAiCommands
475
+ * flag to re-read: its consent is ONEUPTIME_AI_ALLOW_WRITES on the agent
476
+ * and the resource's own Fixes mode. What can have changed is whether it is
477
+ * still the resource's agent and connected, and it only ever runs
478
+ * ResourceCommand steps for its one resource — so any other step aimed at
479
+ * it, or a step for another resource, fails the click.
480
+ */
481
+ async function assertResourceAgentCanRunPlan(data: {
482
+ plan: AiRemediationCommandPlan;
483
+ runnerId: string;
484
+ projectId: ObjectID;
485
+ statusByResourceKey: ResourceStatusCache;
486
+ }): Promise<void> {
487
+ const commands: Array<AiRemediationCommand> = data.plan.commands.filter(
488
+ (command: AiRemediationCommand): boolean => {
489
+ return command.runnerId === data.runnerId;
490
+ },
491
+ );
492
+
493
+ const first: AiRemediationCommand | undefined = commands.find(
494
+ (command: AiRemediationCommand): boolean => {
495
+ return command.stepType === RunbookStepType.ResourceCommand;
496
+ },
497
+ );
498
+
499
+ if (!first) {
500
+ return;
501
+ }
502
+
503
+ const agentName: string = isAiResourceType(first.resourceType)
504
+ ? AI_RESOURCE_TYPE_INFO[first.resourceType].agentDisplayName
505
+ : "resource's AI agent";
506
+
507
+ const otherStep: AiRemediationCommand | undefined = commands.find(
508
+ (command: AiRemediationCommand): boolean => {
509
+ return command.stepType !== RunbookStepType.ResourceCommand;
510
+ },
511
+ );
512
+
513
+ if (otherStep) {
514
+ throw new BadDataException(
515
+ `Command ${otherStep.sequence} is a ${otherStep.stepType} step on the ${agentName} of ${describeCommandResource(
516
+ first,
517
+ )}, which runs only ResourceCommand steps. The plan cannot be run — dismiss it and let a new suggestion be composed.`,
518
+ );
519
+ }
520
+
521
+ const otherResource: AiRemediationCommand | undefined = commands.find(
522
+ (command: AiRemediationCommand): boolean => {
523
+ return (
524
+ command.resourceType !== first.resourceType ||
525
+ (command.resourceId || "").toLowerCase() !==
526
+ (first.resourceId || "").toLowerCase()
527
+ );
528
+ },
529
+ );
530
+
531
+ if (otherResource) {
532
+ throw new BadDataException(
533
+ `Command ${otherResource.sequence} names a different resource than the ${agentName} it is sent to serves. The plan cannot be run — dismiss it and let a new suggestion be composed.`,
534
+ );
535
+ }
536
+
537
+ if (
538
+ !isAiResourceType(first.resourceType) ||
539
+ !first.resourceId ||
540
+ !ObjectID.isValidUUID(first.resourceId)
541
+ ) {
542
+ throw new BadDataException(
543
+ `Command ${first.sequence} is a resource command with no valid resource, so this plan cannot be run. Dismiss it and let a new suggestion be composed.`,
544
+ );
545
+ }
546
+
547
+ const status: ResourceAiAccessStatus | null = await getResourceStatusOnce({
548
+ resourceType: first.resourceType,
549
+ resourceId: first.resourceId,
550
+ projectId: data.projectId,
551
+ statusByResourceKey: data.statusByResourceKey,
552
+ });
553
+
554
+ if (!status) {
555
+ throw new BadDataException(
556
+ `${describeCommandResource(first)} (command ${first.sequence}) no longer exists in this project, so this plan cannot be run. Dismiss it and let a new suggestion be composed.`,
557
+ );
558
+ }
559
+
560
+ const label: string = `${describeResourceNoun(status.resourceType)} "${status.resourceName}"`;
561
+
562
+ if (!status.agent || status.agent.agentId !== data.runnerId) {
563
+ throw new BadDataException(
564
+ `${label.charAt(0).toUpperCase()}${label.slice(1)} (command ${first.sequence}) is no longer reached through the ${agentName} this plan was composed for (the agent was reset or replaced). Dismiss the suggestion and let a new plan be composed for the current agent.`,
565
+ );
566
+ }
567
+
568
+ if (!status.agent.isOnline) {
569
+ throw new BadDataException(
570
+ `The ${agentName} of ${label} is offline, so this plan cannot be run. Check the agent on ${getResourceAiAgentPage(
571
+ status.resourceType,
572
+ )} and approve again, or dismiss the suggestion.`,
573
+ );
574
+ }
575
+ }
576
+
577
+ /*
578
+ * Approval-time re-check of every ResourceCommand step — the resource
579
+ * sibling of assertKubectlCommandsStillRunnable. The resource must still
580
+ * exist and be remediation-ready (fixes on, agent online and allowed to
581
+ * write, the project switches), be reached through the agent the plan was
582
+ * composed for, and every command and its rollback must still pass the
583
+ * resource command policy and the agent's reported write scope. The
584
+ * executor hard-stops on the same conditions right before each command
585
+ * runs — this makes the click fail up front, with the reason and the next
586
+ * step, instead of claiming the plan and stopping one command in.
587
+ */
588
+ async function assertResourceCommandsStillRunnable(data: {
589
+ plan: AiRemediationCommandPlan;
590
+ projectId: ObjectID;
591
+ statusByResourceKey: ResourceStatusCache;
592
+ }): Promise<void> {
593
+ for (const command of data.plan.commands) {
594
+ if (command.stepType !== RunbookStepType.ResourceCommand) {
595
+ continue;
596
+ }
597
+
598
+ if (
599
+ !isAiResourceType(command.resourceType) ||
600
+ !command.resourceId ||
601
+ !ObjectID.isValidUUID(command.resourceId)
602
+ ) {
603
+ throw new BadDataException(
604
+ `Command ${command.sequence} is a resource command with no valid resource, so this plan cannot be run. Dismiss it and let a new suggestion be composed.`,
605
+ );
606
+ }
607
+
608
+ const status: ResourceAiAccessStatus | null = await getResourceStatusOnce({
609
+ resourceType: command.resourceType,
610
+ resourceId: command.resourceId,
611
+ projectId: data.projectId,
612
+ statusByResourceKey: data.statusByResourceKey,
613
+ });
614
+
615
+ if (!status) {
616
+ throw new BadDataException(
617
+ `${describeCommandResource(command)} (command ${command.sequence}) no longer exists in this project, so this plan cannot be run. Dismiss it and let a new suggestion be composed.`,
618
+ );
619
+ }
620
+
621
+ const noun: string = describeResourceNoun(status.resourceType);
622
+ const label: string = `${noun} "${status.resourceName}"`;
623
+ const capitalizedLabel: string = `${label.charAt(0).toUpperCase()}${label.slice(1)}`;
624
+ const agentName: string =
625
+ AI_RESOURCE_TYPE_INFO[status.resourceType].agentDisplayName;
626
+
627
+ if (!status.isRemediationReady) {
628
+ const gap: ResourceAiAccessGap | undefined = status.gaps.find(
629
+ (candidate: ResourceAiAccessGap): boolean => {
630
+ return candidate.blocksRemediation;
631
+ },
632
+ );
633
+
634
+ throw new BadDataException(
635
+ `${capitalizedLabel} (command ${command.sequence}) no longer allows AI remediation${
636
+ gap ? `: ${gap.title} — ${gap.nextStep}` : ""
637
+ }. Fix that on ${getResourceAiAgentPage(
638
+ status.resourceType,
639
+ )} and approve again, or dismiss the suggestion.`,
640
+ );
641
+ }
642
+
643
+ if (!status.agent || status.agent.agentId !== command.runnerId) {
644
+ throw new BadDataException(
645
+ `${capitalizedLabel} (command ${command.sequence}) is no longer reached through the ${agentName} this plan was composed for (the agent was reset or replaced). Dismiss the suggestion and let a new plan be composed for the current agent.`,
646
+ );
647
+ }
648
+
649
+ /*
650
+ * The command and its rollback, re-checked live: the policy (a command
651
+ * the policy denies now never runs, whoever approves it) and the
652
+ * agent's write scope as it reports it now — a rollback it would refuse
653
+ * would otherwise only surface when verification fails and the change
654
+ * has to be undone.
655
+ */
656
+ const parts: Array<{ label: string; text: string | undefined }> = [
657
+ { label: "", text: command.command },
658
+ { label: "'s rollback", text: command.rollbackCommand },
659
+ ];
660
+
661
+ for (const part of parts) {
662
+ if (!part.text) {
663
+ continue;
664
+ }
665
+
666
+ const policy: ResourceCommandPolicyResult =
667
+ ResourceCommandPolicy.evaluateCommand({
668
+ resourceType: status.resourceType,
669
+ command: part.text,
670
+ });
671
+
672
+ if (policy.tier === ResourceCommandTier.Denied) {
673
+ throw new BadDataException(
674
+ `Command ${command.sequence}${part.label} is denied by the ${
675
+ AI_RESOURCE_TYPE_INFO[status.resourceType].displayName
676
+ } command policy (${policy.reason}), so it can never run. Nothing ran. Dismiss the suggestion and let a new plan be composed.`,
677
+ );
678
+ }
679
+
680
+ const scopeRefusal: string | null =
681
+ RemediationCommandToolkit.getResourceWriteScopeRefusal({
682
+ resource: status,
683
+ command: part.text,
684
+ });
685
+
686
+ if (scopeRefusal) {
687
+ throw new BadDataException(
688
+ `Command ${command.sequence}${part.label} cannot run on ${label}: ${scopeRefusal} Nothing ran. ${RemediationCommandToolkit.getResourceScopeRefusalNextStep(
689
+ status.resourceType,
690
+ )}`,
691
+ );
692
+ }
693
+ }
694
+ }
695
+ }
696
+
697
+ /*
698
+ * Approving a resource command runs it on the resource as root, so the
699
+ * approver must be someone who may edit that resource — its update ACL,
700
+ * label-scoped blocks included — not merely someone who may start runbooks
701
+ * in the project. Each resource is checked once, however many commands
702
+ * target it. Called after assertResourceCommandsStillRunnable, which has
703
+ * already refused a command with no valid resource.
704
+ */
705
+ async function assertApproverMayChangeResources(data: {
706
+ plan: AiRemediationCommandPlan;
707
+ props: DatabaseCommonInteractionProps;
708
+ projectId: ObjectID;
709
+ }): Promise<void> {
710
+ const checked: Set<string> = new Set<string>();
711
+
712
+ for (const command of data.plan.commands) {
713
+ if (
714
+ command.stepType !== RunbookStepType.ResourceCommand ||
715
+ !isAiResourceType(command.resourceType) ||
716
+ !command.resourceId ||
717
+ !ObjectID.isValidUUID(command.resourceId)
718
+ ) {
719
+ continue;
720
+ }
721
+
722
+ const key: string = getResourceStatusKey(
723
+ command.resourceType,
724
+ command.resourceId,
725
+ );
726
+
727
+ if (checked.has(key)) {
728
+ continue;
729
+ }
730
+
731
+ checked.add(key);
732
+
733
+ await ResourceAiAccessService.assertCallerMayChangeResource({
734
+ props: data.props,
735
+ projectId: data.projectId,
736
+ resourceType: command.resourceType,
737
+ resourceId: new ObjectID(command.resourceId),
738
+ });
739
+ }
740
+ }
741
+
401
742
  async function loadSuggestionAsRoot(
402
743
  suggestionId: ObjectID,
403
744
  ): Promise<AutoRemediationSuggestion> {
@@ -423,6 +764,9 @@ async function loadSuggestionAsRoot(
423
764
  */
424
765
  kubernetesClusterId: true,
425
766
  autoRemediationRuleId: true,
767
+ // A resource round (a resource, no rule) needs no opt-in either.
768
+ resourceType: true,
769
+ resourceId: true,
426
770
  },
427
771
  props: { isRoot: true },
428
772
  });
@@ -543,6 +887,7 @@ router.post(
543
887
 
544
888
  if (
545
889
  !isClusterRemediationRound(suggestion) &&
890
+ !isResourceRemediationRound(suggestion) &&
546
891
  project.enableAiCommandExecution !== true
547
892
  ) {
548
893
  throw new BadDataException(
@@ -578,6 +923,11 @@ router.post(
578
923
  KubernetesClusterAiAccessStatus | null
579
924
  >();
580
925
 
926
+ const statusByResourceKey: ResourceStatusCache = new Map<
927
+ string,
928
+ ResourceAiAccessStatus | null
929
+ >();
930
+
581
931
  for (const runnerId of runnerIds) {
582
932
  /*
583
933
  * A kubectl command composed for a cluster's Kubernetes AI agent
@@ -603,6 +953,29 @@ router.post(
603
953
  continue;
604
954
  }
605
955
 
956
+ /*
957
+ * A ResourceCommand step names its resource's AI agent the same
958
+ * way; that agent is not a Runner row either, so it is recognised
959
+ * from the resource's status and must be its current, connected
960
+ * agent.
961
+ */
962
+ if (
963
+ plan.commands.some((command: AiRemediationCommand): boolean => {
964
+ return (
965
+ command.stepType === RunbookStepType.ResourceCommand &&
966
+ command.runnerId === runnerId
967
+ );
968
+ })
969
+ ) {
970
+ await assertResourceAgentCanRunPlan({
971
+ plan,
972
+ runnerId,
973
+ projectId: suggestion.projectId,
974
+ statusByResourceKey,
975
+ });
976
+ continue;
977
+ }
978
+
606
979
  const runner: Runner | null = await RunnerService.findOneBy({
607
980
  query: {
608
981
  _id: runnerId,
@@ -638,6 +1011,24 @@ router.post(
638
1011
  statusByClusterId,
639
1012
  });
640
1013
 
1014
+ // And for every resource command: its resource, as it is now.
1015
+ await assertResourceCommandsStillRunnable({
1016
+ plan,
1017
+ projectId: suggestion.projectId,
1018
+ statusByResourceKey,
1019
+ });
1020
+
1021
+ /*
1022
+ * And the approver may change every resource the plan changes: the
1023
+ * plan runs as root on the resource, so this is where the
1024
+ * resource's own edit ACL (with its label scope) applies.
1025
+ */
1026
+ await assertApproverMayChangeResources({
1027
+ plan,
1028
+ props,
1029
+ projectId: suggestion.projectId,
1030
+ });
1031
+
641
1032
  const claimedPlan: number =
642
1033
  await AutoRemediationSuggestionService.attemptStatusTransition({
643
1034
  suggestionId: suggestion.id!,