@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
@@ -0,0 +1,305 @@
1
+ import {
2
+ AI_COMMAND_STEP_TYPES,
3
+ AiRemediationCommand,
4
+ AiRemediationCommandPlan,
5
+ AiRemediationCommandPlanUtil,
6
+ AiRemediationCommandPolicyVerdict,
7
+ } from "../../../Types/AutoRemediation/AiRemediationCommandPlan";
8
+ import AiResourceType, {
9
+ AI_RESOURCE_TYPE_INFO,
10
+ } from "../../../Types/ResourceAiAgent/AiResourceType";
11
+ import { ResourceCommandTier } from "../../../Types/ResourceAiAgent/ResourceAiAccess";
12
+ import { KubectlCommandTier } from "../../../Types/Kubernetes/KubernetesClusterAiAccess";
13
+ import RunbookStepType from "../../../Types/Runbook/RunbookStepType";
14
+ import { JSONObject } from "../../../Types/JSON";
15
+ import { describe, expect, test } from "@jest/globals";
16
+
17
+ /*
18
+ * Contract under test — ResourceCommand steps in a stored command plan.
19
+ *
20
+ * A ResourceCommand step runs through an infrastructure resource's own AI
21
+ * agent. Mirroring a Kubectl step aimed at the Kubernetes AI agent (whose
22
+ * runnerId is the KubernetesAiAgent row id and runnerNameSnapshot is
23
+ * "Kubernetes AI agent"), its runnerId holds the ResourceAiAgent row id and
24
+ * runnerNameSnapshot the type's agent display name ("Docker AI agent").
25
+ *
26
+ * parse() fails closed: the executor and the verifier act on what it
27
+ * returns, so a ResourceCommand step without a valid resourceType and
28
+ * resourceId, with any credential or cluster field, or with a Denied (or
29
+ * unknown) tier makes the WHOLE plan null. Plans stored before this step
30
+ * type existed must parse exactly as they did.
31
+ */
32
+
33
+ const AGENT_ID: string = "11111111-1111-4111-8111-111111111111";
34
+ const RESOURCE_ID: string = "22222222-2222-4222-8222-222222222222";
35
+
36
+ function resourceStep(overrides: JSONObject = {}): JSONObject {
37
+ return {
38
+ sequence: 1,
39
+ stepType: RunbookStepType.ResourceCommand,
40
+ runnerId: AGENT_ID,
41
+ runnerNameSnapshot: "Docker AI agent",
42
+ resourceType: AiResourceType.DockerHost,
43
+ resourceId: RESOURCE_ID,
44
+ resourceNameSnapshot: "prod-web-1",
45
+ resourceCommandTier: ResourceCommandTier.SafeWrite,
46
+ command: "docker restart web",
47
+ timeoutInMs: 30000,
48
+ rationale: "web is wedged",
49
+ expectedEffect: "web serves again",
50
+ rollbackCommand: "docker start web",
51
+ policyVerdict: AiRemediationCommandPolicyVerdict.AutoApproved,
52
+ ...overrides,
53
+ };
54
+ }
55
+
56
+ function parseOne(step: JSONObject): AiRemediationCommand | null {
57
+ const plan: AiRemediationCommandPlan | null =
58
+ AiRemediationCommandPlanUtil.parse({ commands: [step] });
59
+
60
+ return plan ? plan.commands[0] || null : null;
61
+ }
62
+
63
+ describe("AI_COMMAND_STEP_TYPES admits ResourceCommand", () => {
64
+ test("ResourceCommand is an AI command step type", () => {
65
+ expect(AI_COMMAND_STEP_TYPES).toContain(RunbookStepType.ResourceCommand);
66
+ });
67
+ });
68
+
69
+ describe("AiRemediationCommandPlanUtil.parse — ResourceCommand steps", () => {
70
+ test("keeps the resource fields and the agent as the step's target", () => {
71
+ const command: AiRemediationCommand | null = parseOne(resourceStep());
72
+
73
+ expect(command).not.toBeNull();
74
+ expect(command?.stepType).toBe(RunbookStepType.ResourceCommand);
75
+ expect(command?.runnerId).toBe(AGENT_ID);
76
+ expect(command?.runnerNameSnapshot).toBe("Docker AI agent");
77
+ expect(command?.resourceType).toBe(AiResourceType.DockerHost);
78
+ expect(command?.resourceId).toBe(RESOURCE_ID);
79
+ expect(command?.resourceNameSnapshot).toBe("prod-web-1");
80
+ expect(command?.resourceCommandTier).toBe(ResourceCommandTier.SafeWrite);
81
+ expect(command?.command).toBe("docker restart web");
82
+ expect(command?.rollbackCommand).toBe("docker start web");
83
+ expect(command?.credentialId).toBeUndefined();
84
+ expect(command?.kubernetesClusterId).toBeUndefined();
85
+ });
86
+
87
+ test("survives a toJSON round trip unchanged", () => {
88
+ const plan: AiRemediationCommandPlan | null =
89
+ AiRemediationCommandPlanUtil.parse({ commands: [resourceStep()] });
90
+
91
+ expect(plan).not.toBeNull();
92
+ expect(
93
+ AiRemediationCommandPlanUtil.parse(
94
+ AiRemediationCommandPlanUtil.toJSON(plan!),
95
+ ),
96
+ ).toEqual(plan);
97
+ });
98
+
99
+ test.each(
100
+ Object.values(AiResourceType).map((type: AiResourceType) => {
101
+ return [type];
102
+ }),
103
+ )("accepts resourceType %s", (type: AiResourceType) => {
104
+ expect(parseOne(resourceStep({ resourceType: type }))?.resourceType).toBe(
105
+ type,
106
+ );
107
+ });
108
+
109
+ test.each([
110
+ ResourceCommandTier.Read,
111
+ ResourceCommandTier.SafeWrite,
112
+ ResourceCommandTier.RiskyWrite,
113
+ ])("accepts the %s tier", (tier: ResourceCommandTier) => {
114
+ expect(
115
+ parseOne(resourceStep({ resourceCommandTier: tier }))
116
+ ?.resourceCommandTier,
117
+ ).toBe(tier);
118
+ });
119
+
120
+ test("an absent tier is allowed (it is informational; execution re-evaluates)", () => {
121
+ const withoutTier: JSONObject = resourceStep();
122
+ delete withoutTier["resourceCommandTier"];
123
+
124
+ const command: AiRemediationCommand | null = parseOne(withoutTier);
125
+
126
+ expect(command).not.toBeNull();
127
+ expect(command?.resourceCommandTier).toBeUndefined();
128
+ expect(
129
+ parseOne(resourceStep({ resourceCommandTier: null })),
130
+ ).not.toBeNull();
131
+ });
132
+
133
+ test("defaults a missing runnerNameSnapshot to the type's agent name", () => {
134
+ const withoutName: JSONObject = resourceStep({
135
+ resourceType: AiResourceType.CephCluster,
136
+ });
137
+ delete withoutName["runnerNameSnapshot"];
138
+
139
+ expect(parseOne(withoutName)?.runnerNameSnapshot).toBe(
140
+ AI_RESOURCE_TYPE_INFO[AiResourceType.CephCluster].agentDisplayName,
141
+ );
142
+ });
143
+
144
+ describe("fails closed", () => {
145
+ test.each([
146
+ ["no resourceType", { resourceType: undefined }],
147
+ ["a null resourceType", { resourceType: null }],
148
+ ["an alias instead of the enum value", { resourceType: "docker" }],
149
+ ["a lowercased enum value", { resourceType: "dockerhost" }],
150
+ ["Kubernetes", { resourceType: "KubernetesCluster" }],
151
+ ["a numeric resourceType", { resourceType: 3 }],
152
+ ["no resourceId", { resourceId: undefined }],
153
+ ["a blank resourceId", { resourceId: " " }],
154
+ ["a numeric resourceId", { resourceId: 42 }],
155
+ [
156
+ "a credentialId",
157
+ { credentialId: "33333333-3333-4333-8333-333333333333" },
158
+ ],
159
+ ["an empty credentialId", { credentialId: "" }],
160
+ ["a credentialNameSnapshot", { credentialNameSnapshot: "prod ssh key" }],
161
+ ["a resolved credential", { credential: { password: "hunter2" } }],
162
+ ["a cluster", { kubernetesClusterId: RESOURCE_ID }],
163
+ ["a Denied tier", { resourceCommandTier: ResourceCommandTier.Denied }],
164
+ ["an unknown tier", { resourceCommandTier: "Safe" }],
165
+ ["a lowercased tier", { resourceCommandTier: "safewrite" }],
166
+ ["a numeric tier", { resourceCommandTier: 1 }],
167
+ ["no runnerId (the agent)", { runnerId: "" }],
168
+ ["a Denied verdict", { policyVerdict: "Denied" }],
169
+ ])(
170
+ "%s makes the whole plan null",
171
+ (_label: string, overrides: JSONObject) => {
172
+ const step: JSONObject = resourceStep();
173
+
174
+ for (const [key, value] of Object.entries(overrides)) {
175
+ if (value === undefined) {
176
+ delete step[key];
177
+ } else {
178
+ step[key] = value;
179
+ }
180
+ }
181
+
182
+ expect(
183
+ AiRemediationCommandPlanUtil.parse({
184
+ commands: [
185
+ {
186
+ sequence: 1,
187
+ stepType: RunbookStepType.Bash,
188
+ runnerId: AGENT_ID,
189
+ command: "uptime",
190
+ policyVerdict: AiRemediationCommandPolicyVerdict.AutoApproved,
191
+ },
192
+ { ...step, sequence: 2 },
193
+ ],
194
+ }),
195
+ ).toBeNull();
196
+ },
197
+ );
198
+ });
199
+
200
+ test("resource fields on a non-resource step are ignored, not trusted", () => {
201
+ const plan: AiRemediationCommandPlan | null =
202
+ AiRemediationCommandPlanUtil.parse({
203
+ commands: [
204
+ {
205
+ sequence: 1,
206
+ stepType: RunbookStepType.Kubectl,
207
+ runnerId: AGENT_ID,
208
+ kubernetesClusterId: RESOURCE_ID,
209
+ kubectlTier: KubectlCommandTier.SafeWrite,
210
+ resourceType: AiResourceType.DockerHost,
211
+ resourceId: RESOURCE_ID,
212
+ resourceCommandTier: ResourceCommandTier.Denied,
213
+ command: "kubectl rollout restart deployment/web -n web",
214
+ policyVerdict: AiRemediationCommandPolicyVerdict.RequiresApproval,
215
+ },
216
+ ],
217
+ });
218
+
219
+ expect(plan).not.toBeNull();
220
+ expect(plan?.commands[0]).not.toHaveProperty("resourceType");
221
+ expect(plan?.commands[0]).not.toHaveProperty("resourceId");
222
+ expect(plan?.commands[0]).not.toHaveProperty("resourceCommandTier");
223
+ });
224
+ });
225
+
226
+ describe("plans stored before ResourceCommand parse exactly as before", () => {
227
+ /*
228
+ * The shape of every key parse produces for an old step — no resource
229
+ * keys added, and the Runner default name kept.
230
+ */
231
+ test("a Bash, an SSH and a Kubectl step keep their exact parsed shape", () => {
232
+ const plan: AiRemediationCommandPlan | null =
233
+ AiRemediationCommandPlanUtil.parse({
234
+ commands: [
235
+ {
236
+ sequence: 1,
237
+ stepType: RunbookStepType.Bash,
238
+ runnerId: AGENT_ID,
239
+ command: "systemctl restart nginx",
240
+ timeoutInMs: 30000,
241
+ rationale: "r",
242
+ expectedEffect: "e",
243
+ policyVerdict: AiRemediationCommandPolicyVerdict.AutoApproved,
244
+ },
245
+ {
246
+ sequence: 2,
247
+ stepType: RunbookStepType.SSH,
248
+ runnerId: AGENT_ID,
249
+ runnerNameSnapshot: "office-runner",
250
+ credentialId: "44444444-4444-4444-8444-444444444444",
251
+ credentialNameSnapshot: "db ssh",
252
+ command: "uptime",
253
+ timeoutInMs: 30000,
254
+ rationale: "r",
255
+ expectedEffect: "e",
256
+ policyVerdict: AiRemediationCommandPolicyVerdict.RequiresApproval,
257
+ },
258
+ {
259
+ sequence: 3,
260
+ stepType: RunbookStepType.Kubectl,
261
+ runnerId: AGENT_ID,
262
+ runnerNameSnapshot: "Kubernetes AI agent",
263
+ kubernetesClusterId: RESOURCE_ID,
264
+ kubernetesClusterNameSnapshot: "prod-us",
265
+ kubectlTier: KubectlCommandTier.SafeWrite,
266
+ command: "kubectl rollout restart deployment/web -n web",
267
+ timeoutInMs: 30000,
268
+ rationale: "r",
269
+ expectedEffect: "e",
270
+ policyVerdict: AiRemediationCommandPolicyVerdict.RequiresApproval,
271
+ },
272
+ ],
273
+ });
274
+
275
+ expect(plan).not.toBeNull();
276
+
277
+ const expectedKeys: Array<string> = [
278
+ "command",
279
+ "credentialId",
280
+ "credentialNameSnapshot",
281
+ "execution",
282
+ "expectedEffect",
283
+ "kubectlTier",
284
+ "kubernetesClusterId",
285
+ "kubernetesClusterNameSnapshot",
286
+ "policyVerdict",
287
+ "rationale",
288
+ "rollbackCommand",
289
+ "rollbackExecution",
290
+ "runnerId",
291
+ "runnerNameSnapshot",
292
+ "sequence",
293
+ "stepType",
294
+ "timeoutInMs",
295
+ "wasAutoExecuted",
296
+ ];
297
+
298
+ for (const command of plan!.commands) {
299
+ expect(Object.keys(command).sort()).toEqual(expectedKeys);
300
+ }
301
+
302
+ expect(plan!.commands[0]?.runnerNameSnapshot).toBe("Runner");
303
+ expect(plan!.commands[2]?.kubectlTier).toBe(KubectlCommandTier.SafeWrite);
304
+ });
305
+ });
@@ -19,7 +19,11 @@ import { getAllIoTAlertTemplates } from "../../../../Types/Monitor/IotAlertTempl
19
19
  import { getAllKubernetesAlertTemplates } from "../../../../Types/Monitor/KubernetesAlertTemplates";
20
20
  import { getAllPodmanAlertTemplates } from "../../../../Types/Monitor/PodmanAlertTemplates";
21
21
  import { getAllProxmoxAlertTemplates } from "../../../../Types/Monitor/ProxmoxAlertTemplates";
22
- import { getAllRumAlertTemplates } from "../../../../Types/Monitor/RumAlertTemplates";
22
+ import {
23
+ RumAlertTemplate,
24
+ getAllRumAlertTemplates,
25
+ getRumAlertTemplates,
26
+ } from "../../../../Types/Monitor/RumAlertTemplates";
23
27
  import { getAllVMwareAlertTemplates } from "../../../../Types/Monitor/VMwareAlertTemplates";
24
28
  import {
25
29
  getAllServiceAlertTemplates,
@@ -69,16 +73,18 @@ interface ModuleExpectation {
69
73
  resourceType: MonitorRecommendationResourceType;
70
74
  monitorTypes: Array<MonitorType>;
71
75
  /*
72
- * Everything the module can ever produce. For nine of the ten this is also
73
- * what the page shows; for Service it is the union across every runtime.
76
+ * Everything the module can ever produce. For the resource types whose set
77
+ * is a constant this is also what the page shows; for Service it is the
78
+ * union across every runtime, for Database across every engine, and for RUM
79
+ * it includes the session replay budget alerts.
74
80
  */
75
81
  templateCount: number;
76
82
  /*
77
83
  * What `getRecommendations(resourceType)` returns with NO context — what a
78
84
  * caller that knows nothing about the specific resource is offered. Equal to
79
85
  * `templateCount` for every resource type whose set is a constant, and
80
- * smaller for Service, where knowing nothing means the language-agnostic
81
- * subset.
86
+ * smaller for Service (the language-agnostic subset), Database (nothing)
87
+ * and RUM (everything but the budget alerts).
82
88
  */
83
89
  contextFreeTemplateCount: number;
84
90
  identifierFieldName:
@@ -163,7 +169,13 @@ const MODULE_EXPECTATIONS: Array<ModuleExpectation> = [
163
169
  MonitorType.Exceptions,
164
170
  ],
165
171
  templateCount: getAllRumAlertTemplates().length,
166
- contextFreeTemplateCount: getAllRumAlertTemplates().length,
172
+ /*
173
+ * Everything but the session replay budget alerts, which wait until the
174
+ * application is known to record replays. `getRumAlertTemplates(undefined)`
175
+ * is the module's own answer to "what applies to an application we know
176
+ * nothing about".
177
+ */
178
+ contextFreeTemplateCount: getRumAlertTemplates(undefined).length,
167
179
  identifierFieldName: "rumApplicationId",
168
180
  },
169
181
  {
@@ -525,12 +537,13 @@ describe("MonitorRecommendationCatalog", () => {
525
537
  });
526
538
 
527
539
  /*
528
- * Services are the only resource type whose recommendation set is not a
529
- * constant. Everything below is about the seam between "what applies to this
530
- * resource" and "what this catalog can ever produce" — the two are the same
531
- * question for nine resource types and different for the tenth, and the
532
- * failure mode of conflating them is a page that offers JVM heap monitors to
533
- * a Go service.
540
+ * Services were the first resource type whose recommendation set is not a
541
+ * constant (databases and RUM applications have suites of their own below).
542
+ * Everything here is about the seam between "what applies to this resource"
543
+ * and "what this catalog can ever produce" — the same question for every
544
+ * resource type whose set is a constant, and a different one for these, and
545
+ * the failure mode of conflating them is a page that offers JVM heap
546
+ * monitors to a Go service.
534
547
  */
535
548
  describe("context-aware recommendations", () => {
536
549
  const AGNOSTIC_COUNT: number = getServiceAlertTemplates(null).length;
@@ -603,9 +616,16 @@ describe("MonitorRecommendationCatalog", () => {
603
616
  for (const resourceType of Object.values(
604
617
  MonitorRecommendationResourceType,
605
618
  )) {
619
+ /*
620
+ * The three resource types whose set is NOT a constant, each with a
621
+ * suite of its own below: a service by runtime, a database by engine,
622
+ * and a RUM application by whether it records session replays (its
623
+ * budget alerts).
624
+ */
606
625
  if (
607
626
  resourceType === MonitorRecommendationResourceType.Service ||
608
- resourceType === MonitorRecommendationResourceType.DatabaseServer
627
+ resourceType === MonitorRecommendationResourceType.DatabaseServer ||
628
+ resourceType === MonitorRecommendationResourceType.RumApplication
609
629
  ) {
610
630
  continue;
611
631
  }
@@ -617,9 +637,19 @@ describe("MonitorRecommendationCatalog", () => {
617
637
  },
618
638
  );
619
639
 
640
+ /*
641
+ * Every fact any resource type reads, set to the value that moves its
642
+ * own list the most, so a constant set that started reading one of
643
+ * them would change here.
644
+ */
620
645
  const withContext: Array<string> =
621
646
  MonitorRecommendationCatalog.getRecommendations(resourceType, {
622
647
  serviceLanguage: "java",
648
+ databaseEngine: "postgresql",
649
+ databaseEngineMetricsReported: true,
650
+ sessionReplayEnabled: true,
651
+ sessionReplayHasRecorded: true,
652
+ sessionReplayMonthlyBudgetInGB: 10,
623
653
  }).map((recommendation: MonitorRecommendation) => {
624
654
  return recommendation.recommendationId;
625
655
  });
@@ -906,4 +936,238 @@ describe("MonitorRecommendationCatalog", () => {
906
936
  expect(new Set(categories).size).toBe(categories.length);
907
937
  });
908
938
  });
939
+
940
+ /*
941
+ * RUM applications: the third context-dependent resource type. Every
942
+ * application is offered the same web vital and error recommendations, but
943
+ * the session replay budget alerts only once the application records
944
+ * replays (and, for the monthly pair, has a monthly budget) - the sweep
945
+ * writes nothing for any other application, so each would be a monitor
946
+ * that can never fire. The page's side-menu badge counts from the same
947
+ * answer, so a wrong one inflates the badge on every RUM application.
948
+ */
949
+ describe("RUM application recommendations", () => {
950
+ const FULL_REPLAY_CONTEXT: MonitorRecommendationContext = {
951
+ sessionReplayEnabled: true,
952
+ sessionReplayHasRecorded: true,
953
+ sessionReplayMonthlyBudgetInGB: 10,
954
+ };
955
+
956
+ const BUDGET_TEMPLATE_IDS: Array<string> = [
957
+ "rum-session-replay-daily-budget-nearly-spent",
958
+ "rum-session-replay-daily-budget-spent",
959
+ "rum-session-replay-monthly-budget-nearly-spent",
960
+ "rum-session-replay-monthly-budget-spent",
961
+ ];
962
+
963
+ function rumRecommendationIds(
964
+ context?: MonitorRecommendationContext | undefined,
965
+ ): Array<string> {
966
+ return MonitorRecommendationCatalog.getRecommendations(
967
+ MonitorRecommendationResourceType.RumApplication,
968
+ context,
969
+ ).map((recommendation: MonitorRecommendation) => {
970
+ return recommendation.recommendationId;
971
+ });
972
+ }
973
+
974
+ function idsOf(templates: Array<RumAlertTemplate>): Array<string> {
975
+ return templates.map((template: RumAlertTemplate) => {
976
+ return buildRecommendationId(
977
+ MonitorRecommendationResourceType.RumApplication,
978
+ template.id,
979
+ );
980
+ });
981
+ }
982
+
983
+ it("offers the original seven when nothing is known about the application", () => {
984
+ const contextFree: Array<string> = rumRecommendationIds();
985
+
986
+ expect(contextFree).toHaveLength(7);
987
+ expect(contextFree).toEqual(idsOf(getRumAlertTemplates(undefined)));
988
+ expect(rumRecommendationIds({})).toEqual(contextFree);
989
+
990
+ for (const templateId of BUDGET_TEMPLATE_IDS) {
991
+ expect(contextFree).not.toContain(
992
+ buildRecommendationId(
993
+ MonitorRecommendationResourceType.RumApplication,
994
+ templateId,
995
+ ),
996
+ );
997
+ }
998
+ });
999
+
1000
+ it("offers all eleven, in the module's order, to an application that records and has a budget", () => {
1001
+ const offered: Array<string> = rumRecommendationIds(FULL_REPLAY_CONTEXT);
1002
+
1003
+ expect(offered).toHaveLength(11);
1004
+ expect(offered).toEqual(idsOf(getAllRumAlertTemplates()));
1005
+ });
1006
+
1007
+ /*
1008
+ * The adapter re-assembles the module's context field by field, so a
1009
+ * field it forgot to forward would read as "not known" - withholding the
1010
+ * alerts on every page while every other test stays green. One case per
1011
+ * field: each moves the count, so each must have arrived.
1012
+ */
1013
+ it("forwards every replay fact to the module", () => {
1014
+ expect(
1015
+ rumRecommendationIds({
1016
+ sessionReplayEnabled: true,
1017
+ sessionReplayHasRecorded: true,
1018
+ }),
1019
+ ).toEqual(
1020
+ idsOf(
1021
+ getRumAlertTemplates({
1022
+ sessionReplayEnabled: true,
1023
+ sessionReplayHasRecorded: true,
1024
+ }),
1025
+ ),
1026
+ );
1027
+ expect(
1028
+ rumRecommendationIds({
1029
+ sessionReplayEnabled: true,
1030
+ sessionReplayHasRecorded: true,
1031
+ }),
1032
+ ).toHaveLength(9);
1033
+ expect(
1034
+ rumRecommendationIds({
1035
+ ...FULL_REPLAY_CONTEXT,
1036
+ sessionReplayEnabled: false,
1037
+ }),
1038
+ ).toHaveLength(7);
1039
+ expect(
1040
+ rumRecommendationIds({
1041
+ ...FULL_REPLAY_CONTEXT,
1042
+ sessionReplayHasRecorded: false,
1043
+ }),
1044
+ ).toHaveLength(7);
1045
+ expect(
1046
+ rumRecommendationIds({
1047
+ ...FULL_REPLAY_CONTEXT,
1048
+ sessionReplayMonthlyBudgetInGB: 0,
1049
+ }),
1050
+ ).toHaveLength(9);
1051
+ });
1052
+
1053
+ it("stays exhaustive, and resolves every budget recommendation by id with no context", () => {
1054
+ /*
1055
+ * The path a dismissal takes: the row stores a recommendation id and
1056
+ * nothing about the application, so lookup has to work without one.
1057
+ */
1058
+ const all: Array<MonitorRecommendation> =
1059
+ MonitorRecommendationCatalog.getAllPossibleRecommendations(
1060
+ MonitorRecommendationResourceType.RumApplication,
1061
+ );
1062
+
1063
+ expect(all).toHaveLength(11);
1064
+ expect(all.length).toBe(getAllRumAlertTemplates().length);
1065
+
1066
+ for (const templateId of BUDGET_TEMPLATE_IDS) {
1067
+ const recommendation: MonitorRecommendation | undefined =
1068
+ MonitorRecommendationCatalog.getRecommendationById(
1069
+ buildRecommendationId(
1070
+ MonitorRecommendationResourceType.RumApplication,
1071
+ templateId,
1072
+ ),
1073
+ );
1074
+
1075
+ expect(recommendation).toBeDefined();
1076
+ expect(recommendation?.templateId).toBe(templateId);
1077
+ expect(recommendation?.resourceType).toBe(
1078
+ MonitorRecommendationResourceType.RumApplication,
1079
+ );
1080
+ expect(recommendation?.monitorType).toBe(MonitorType.Metrics);
1081
+ expect(recommendation?.category).toBe("Session Replay");
1082
+ }
1083
+ });
1084
+
1085
+ it("lists Session Replay last, and only once the budget alerts are offered", () => {
1086
+ const contextFreeCategories: Array<string> =
1087
+ MonitorRecommendationCatalog.getCategories(
1088
+ MonitorRecommendationResourceType.RumApplication,
1089
+ );
1090
+ const fullCategories: Array<string> =
1091
+ MonitorRecommendationCatalog.getCategories(
1092
+ MonitorRecommendationResourceType.RumApplication,
1093
+ FULL_REPLAY_CONTEXT,
1094
+ );
1095
+
1096
+ expect(contextFreeCategories).toEqual(["Core Web Vitals", "Errors"]);
1097
+ expect(fullCategories).toEqual([
1098
+ ...contextFreeCategories,
1099
+ "Session Replay",
1100
+ ]);
1101
+ expect(fullCategories[fullCategories.length - 1]).toBe("Session Replay");
1102
+ });
1103
+
1104
+ it("scopes every budget recommendation's step to the application id", () => {
1105
+ const rumApplicationId: string = ObjectID.generate().toString();
1106
+
1107
+ const budgetRecommendations: Array<MonitorRecommendation> =
1108
+ MonitorRecommendationCatalog.getRecommendations(
1109
+ MonitorRecommendationResourceType.RumApplication,
1110
+ FULL_REPLAY_CONTEXT,
1111
+ ).filter((item: MonitorRecommendation) => {
1112
+ return item.category === "Session Replay";
1113
+ });
1114
+
1115
+ // Or the loop below would pass having checked nothing.
1116
+ expect(
1117
+ budgetRecommendations.map((recommendation: MonitorRecommendation) => {
1118
+ return recommendation.templateId;
1119
+ }),
1120
+ ).toEqual(BUDGET_TEMPLATE_IDS);
1121
+
1122
+ for (const recommendation of budgetRecommendations) {
1123
+ const step: MonitorStep = recommendation.getMonitorStep({
1124
+ resourceIdentifier: rumApplicationId,
1125
+ onlineMonitorStatusId: ObjectID.generate(),
1126
+ offlineMonitorStatusId: ObjectID.generate(),
1127
+ defaultIncidentSeverityId: ObjectID.generate(),
1128
+ defaultAlertSeverityId: ObjectID.generate(),
1129
+ monitorName: "Storefront",
1130
+ });
1131
+
1132
+ expect(
1133
+ step.data?.metricMonitor?.telemetryServiceIds?.map((id: ObjectID) => {
1134
+ return id.toString();
1135
+ }),
1136
+ ).toEqual([rumApplicationId]);
1137
+ }
1138
+ });
1139
+
1140
+ it("keeps the three context-dependent resource types independent", () => {
1141
+ // Replay facts change nothing for a service or a database...
1142
+ expect(
1143
+ MonitorRecommendationCatalog.getRecommendations(
1144
+ MonitorRecommendationResourceType.Service,
1145
+ FULL_REPLAY_CONTEXT,
1146
+ ).map((recommendation: MonitorRecommendation) => {
1147
+ return recommendation.recommendationId;
1148
+ }),
1149
+ ).toEqual(
1150
+ MonitorRecommendationCatalog.getRecommendations(
1151
+ MonitorRecommendationResourceType.Service,
1152
+ ).map((recommendation: MonitorRecommendation) => {
1153
+ return recommendation.recommendationId;
1154
+ }),
1155
+ );
1156
+ expect(
1157
+ MonitorRecommendationCatalog.getRecommendations(
1158
+ MonitorRecommendationResourceType.DatabaseServer,
1159
+ FULL_REPLAY_CONTEXT,
1160
+ ),
1161
+ ).toEqual([]);
1162
+
1163
+ // ...and a runtime or an engine changes nothing for a RUM application.
1164
+ expect(
1165
+ rumRecommendationIds({
1166
+ serviceLanguage: "java",
1167
+ databaseEngine: "postgresql",
1168
+ databaseEngineMetricsReported: true,
1169
+ }),
1170
+ ).toEqual(rumRecommendationIds());
1171
+ });
1172
+ });
909
1173
  });