@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,211 @@
1
+ import RunnerJobService, {
2
+ MAX_AI_COMMAND_JOBS_PER_PROJECT_PER_HOUR,
3
+ } from "../../../Server/Services/RunnerJobService";
4
+ import RunnerService from "../../../Server/Services/RunnerService";
5
+ import RunnerJob from "../../../Models/DatabaseModels/RunnerJob";
6
+ import RunbookStepType, {
7
+ AI_AGENT_EXECUTED_STEP_TYPES,
8
+ RUNNER_EXECUTED_STEP_TYPES,
9
+ } from "../../../Types/Runbook/RunbookStepType";
10
+ import { AI_COMMAND_STEP_TYPES } from "../../../Types/AutoRemediation/AiRemediationCommandPlan";
11
+ import RunnerJobOrigin from "../../../Types/Runbook/RunnerJobOrigin";
12
+ import BadDataException from "../../../Types/Exception/BadDataException";
13
+ import ObjectID from "../../../Types/ObjectID";
14
+ import PositiveNumber from "../../../Types/PositiveNumber";
15
+ import logger from "../../../Server/Utils/Logger";
16
+ import {
17
+ fakeRunnerJobCountBy,
18
+ fakeRunnerJobRows,
19
+ } from "../TestingUtils/Services/FakeRunnerJobCount";
20
+ import { afterEach, beforeEach, describe, expect, it } from "@jest/globals";
21
+
22
+ /*
23
+ * Contract under test — a ResourceCommand job never reaches a Runner.
24
+ *
25
+ * ResourceCommand is the step type of a command for an infrastructure
26
+ * resource's AI agent (a ResourceAiAgent row). It is an AI command step type
27
+ * (AI_COMMAND_STEP_TYPES), so the generic AI-command lane must refuse it
28
+ * explicitly: that lane writes targetAgentId — a Runner — and a Runner
29
+ * must never be handed a resource command. The runbook lane (enqueue)
30
+ * refuses it because it is not a runner-executed type. Both refusals happen
31
+ * before any row is written.
32
+ */
33
+
34
+ const PROJECT_ID: ObjectID = new ObjectID(
35
+ "22222222-2222-4222-8222-222222222222",
36
+ );
37
+ const RUNNER_ID: ObjectID = new ObjectID(
38
+ "44444444-4444-4444-8444-444444444444",
39
+ );
40
+
41
+ describe("ResourceCommand never enters a Runner lane", () => {
42
+ let create: jest.SpyInstance;
43
+ let runnerLookup: jest.SpyInstance;
44
+ let countBy: jest.SpyInstance;
45
+
46
+ beforeEach(() => {
47
+ // @CaptureSpan logs the expected throws at error level.
48
+ jest.spyOn(logger, "error").mockImplementation((): void => {
49
+ return undefined;
50
+ });
51
+ create = jest
52
+ .spyOn(RunnerJobService, "create")
53
+ .mockImplementation(async (data: unknown): Promise<RunnerJob> => {
54
+ return (data as { data: RunnerJob }).data;
55
+ });
56
+ runnerLookup = jest.spyOn(RunnerService, "findOneBy").mockResolvedValue({
57
+ id: RUNNER_ID,
58
+ _id: RUNNER_ID.toString(),
59
+ projectId: PROJECT_ID,
60
+ name: "office-runner",
61
+ } as never);
62
+ countBy = jest
63
+ .spyOn(RunnerJobService, "countBy")
64
+ .mockResolvedValue(new PositiveNumber(0));
65
+ });
66
+
67
+ afterEach(() => {
68
+ jest.restoreAllMocks();
69
+ });
70
+
71
+ it("is an AI command step type but not a Runner-executed one", () => {
72
+ expect(AI_COMMAND_STEP_TYPES).toContain(RunbookStepType.ResourceCommand);
73
+ expect(AI_AGENT_EXECUTED_STEP_TYPES).toContain(
74
+ RunbookStepType.ResourceCommand,
75
+ );
76
+ expect(RUNNER_EXECUTED_STEP_TYPES).not.toContain(
77
+ RunbookStepType.ResourceCommand,
78
+ );
79
+ });
80
+
81
+ it("enqueue (the runbook lane) refuses it before writing a row", async () => {
82
+ await expect(
83
+ RunnerJobService.enqueue({
84
+ projectId: PROJECT_ID,
85
+ runbookExecutionId: new ObjectID(
86
+ "33333333-3333-4333-8333-333333333333",
87
+ ),
88
+ stepId: "step-1",
89
+ stepType: RunbookStepType.ResourceCommand,
90
+ targetAgentId: RUNNER_ID,
91
+ script: "",
92
+ payload: { program: "docker", args: ["ps"] },
93
+ timeoutInMs: 30000,
94
+ }),
95
+ ).rejects.toThrow(
96
+ new BadDataException(
97
+ 'Runner does not execute step type "ResourceCommand".',
98
+ ),
99
+ );
100
+
101
+ expect(create).not.toHaveBeenCalled();
102
+ });
103
+
104
+ it("enqueueAiCommand (the Runner AI-command lane) refuses it before looking anything up", async () => {
105
+ let caught: unknown = null;
106
+
107
+ try {
108
+ await RunnerJobService.enqueueAiCommand({
109
+ projectId: PROJECT_ID,
110
+ aiRunId: new ObjectID("88888888-8888-4888-8888-888888888888"),
111
+ autoRemediationSuggestionId: new ObjectID(
112
+ "77777777-7777-4777-8777-777777777777",
113
+ ),
114
+ stepId: "ai-approved-1",
115
+ stepType: RunbookStepType.ResourceCommand,
116
+ targetAgentId: RUNNER_ID,
117
+ command: "docker restart web",
118
+ timeoutInMs: 30000,
119
+ });
120
+ } catch (err) {
121
+ caught = err;
122
+ }
123
+
124
+ expect(caught).toBeInstanceOf(BadDataException);
125
+ expect((caught as Error).message).toContain("never on a Runner");
126
+ expect((caught as Error).message).toContain("enqueueAiResourceCommand");
127
+ expect(runnerLookup).not.toHaveBeenCalled();
128
+ expect(countBy).not.toHaveBeenCalled();
129
+ expect(create).not.toHaveBeenCalled();
130
+ });
131
+
132
+ it("negative control: a Bash command still goes through the same lane", async () => {
133
+ await RunnerJobService.enqueueAiCommand({
134
+ projectId: PROJECT_ID,
135
+ aiRunId: new ObjectID("88888888-8888-4888-8888-888888888888"),
136
+ autoRemediationSuggestionId: new ObjectID(
137
+ "77777777-7777-4777-8777-777777777777",
138
+ ),
139
+ stepId: "ai-approved-1",
140
+ stepType: RunbookStepType.Bash,
141
+ targetAgentId: RUNNER_ID,
142
+ command: "systemctl restart nginx",
143
+ timeoutInMs: 30000,
144
+ });
145
+
146
+ expect(create).toHaveBeenCalledTimes(1);
147
+ });
148
+
149
+ /*
150
+ * Resource commands are braked on their own ResourceCommand rows, so the
151
+ * Runner lane's hourly brake must not count them: a full hour of fixes on
152
+ * Docker hosts or database servers leaves every Bash and SSH fix its own
153
+ * budget. Counted against an in-memory RunnerJob table.
154
+ */
155
+ describe("the Runner lane's hourly brake never counts resource-command rows", () => {
156
+ function bashCommand(): Parameters<
157
+ typeof RunnerJobService.enqueueAiCommand
158
+ >[0] {
159
+ return {
160
+ projectId: PROJECT_ID,
161
+ aiRunId: new ObjectID("88888888-8888-4888-8888-888888888888"),
162
+ autoRemediationSuggestionId: new ObjectID(
163
+ "77777777-7777-4777-8777-777777777777",
164
+ ),
165
+ stepId: "ai-approved-1",
166
+ stepType: RunbookStepType.Bash,
167
+ targetAgentId: RUNNER_ID,
168
+ command: "systemctl restart nginx",
169
+ timeoutInMs: 30000,
170
+ };
171
+ }
172
+
173
+ it("runs a Bash fix after a full hour of resource fixes", async () => {
174
+ countBy.mockImplementation(
175
+ fakeRunnerJobCountBy(
176
+ fakeRunnerJobRows(MAX_AI_COMMAND_JOBS_PER_PROJECT_PER_HOUR, {
177
+ projectId: PROJECT_ID,
178
+ origin: RunnerJobOrigin.AiRemediation,
179
+ stepType: RunbookStepType.ResourceCommand,
180
+ }),
181
+ ) as never,
182
+ );
183
+
184
+ await RunnerJobService.enqueueAiCommand(bashCommand());
185
+
186
+ expect(create).toHaveBeenCalledTimes(1);
187
+ });
188
+
189
+ it("negative control: a full hour of kubectl and SSH fixes still stops it", async () => {
190
+ countBy.mockImplementation(
191
+ fakeRunnerJobCountBy([
192
+ ...fakeRunnerJobRows(MAX_AI_COMMAND_JOBS_PER_PROJECT_PER_HOUR - 1, {
193
+ projectId: PROJECT_ID,
194
+ origin: RunnerJobOrigin.AiRemediation,
195
+ stepType: RunbookStepType.Kubectl,
196
+ }),
197
+ ...fakeRunnerJobRows(1, {
198
+ projectId: PROJECT_ID,
199
+ origin: RunnerJobOrigin.AiRemediation,
200
+ stepType: RunbookStepType.SSH,
201
+ }),
202
+ ]) as never,
203
+ );
204
+
205
+ await expect(
206
+ RunnerJobService.enqueueAiCommand(bashCommand()),
207
+ ).rejects.toThrow(/AI remediation commands in the last hour/);
208
+ expect(create).not.toHaveBeenCalled();
209
+ });
210
+ });
211
+ });
@@ -0,0 +1,352 @@
1
+ import RunnerJobService, {
2
+ RunnerJobTimeoutKind,
3
+ Service as RunnerJobServiceClass,
4
+ describeRunnerJobTimeout,
5
+ } from "../../../Server/Services/RunnerJobService";
6
+ import PostgresAppInstance from "../../../Server/Infrastructure/PostgresDatabase";
7
+ import RunnerJob from "../../../Models/DatabaseModels/RunnerJob";
8
+ import ObjectID from "../../../Types/ObjectID";
9
+ import AiResourceType from "../../../Types/ResourceAiAgent/AiResourceType";
10
+ import RunbookStepType from "../../../Types/Runbook/RunbookStepType";
11
+ import RunnerJobOrigin from "../../../Types/Runbook/RunnerJobOrigin";
12
+ import RunnerJobStatus from "../../../Types/Runbook/RunnerJobStatus";
13
+ import { afterEach, beforeEach, describe, expect, it } from "@jest/globals";
14
+
15
+ /*
16
+ * Contract under test — the two RunnerJobService readings of a resource
17
+ * command job's row besides its enqueue:
18
+ *
19
+ * - a timed-out ResourceCommand job is worded for the resource's AI agent
20
+ * ("the Docker AI agent did not pick up the command in time ... Nothing
21
+ * was run on the Docker host"), on the row, while every Kubectl and
22
+ * runbook reason stays exactly what it was;
23
+ * - submitResult, given the job's resource type and program, stores the
24
+ * output through the resource command redactor as well, and without them
25
+ * stores exactly what it always has.
26
+ */
27
+
28
+ const JOB_ID: ObjectID = new ObjectID("11111111-1111-4111-8111-111111111111");
29
+ const AGENT_ID: ObjectID = new ObjectID("22222222-2222-4222-8222-222222222222");
30
+ const CLAIM_TIMEOUT_MS: number = 60_000;
31
+ const EXECUTION_TIMEOUT_MS: number = 30_000;
32
+
33
+ function reason(data: {
34
+ kind: RunnerJobTimeoutKind;
35
+ wasClaimed?: boolean | undefined;
36
+ origin?: RunnerJobOrigin | undefined;
37
+ stepType?: RunbookStepType | undefined;
38
+ resourceType?: AiResourceType | null | undefined;
39
+ isForKubernetesAiAgent?: boolean | undefined;
40
+ }): string {
41
+ return describeRunnerJobTimeout({
42
+ kind: data.kind,
43
+ wasClaimed: data.wasClaimed,
44
+ origin: data.origin ?? RunnerJobOrigin.AiInvestigation,
45
+ stepType: data.stepType ?? RunbookStepType.ResourceCommand,
46
+ claimTimeoutInMs: CLAIM_TIMEOUT_MS,
47
+ executionTimeoutInMs: EXECUTION_TIMEOUT_MS,
48
+ isForKubernetesAiAgent: data.isForKubernetesAiAgent,
49
+ resourceType: data.resourceType,
50
+ });
51
+ }
52
+
53
+ describe("describeRunnerJobTimeout for a resource command", () => {
54
+ it("says the agent did not pick up the command in time, and that nothing ran", () => {
55
+ expect(
56
+ reason({ kind: "unclaimed", resourceType: AiResourceType.DockerHost }),
57
+ ).toBe(
58
+ "The Docker AI agent did not pick up the command in time (within 60s) — it may be offline, restarting or busy with other work. Nothing was run on the Docker host.",
59
+ );
60
+ });
61
+
62
+ it("names each type's agent and resource", () => {
63
+ expect(
64
+ reason({ kind: "unclaimed", resourceType: AiResourceType.Host }),
65
+ ).toContain("The Host AI agent did not pick up the command in time");
66
+ expect(
67
+ reason({ kind: "unclaimed", resourceType: AiResourceType.Host }),
68
+ ).toContain("Nothing was run on the host.");
69
+ expect(
70
+ reason({
71
+ kind: "unclaimed",
72
+ resourceType: AiResourceType.DatabaseServer,
73
+ }),
74
+ ).toContain("Nothing was run on the database server.");
75
+ expect(
76
+ reason({
77
+ kind: "unclaimed",
78
+ resourceType: AiResourceType.VMwareVCenter,
79
+ }),
80
+ ).toContain("The VMware AI agent did not pick up the command in time");
81
+ });
82
+
83
+ it("reads a job still Pending at the overall deadline as never picked up", () => {
84
+ expect(
85
+ reason({
86
+ kind: "overall",
87
+ wasClaimed: false,
88
+ resourceType: AiResourceType.CephCluster,
89
+ }),
90
+ ).toContain("The Ceph AI agent did not pick up the command in time");
91
+ });
92
+
93
+ it("says what a command the agent took did is unknown", () => {
94
+ expect(
95
+ reason({
96
+ kind: "lease_expired",
97
+ wasClaimed: true,
98
+ resourceType: AiResourceType.ProxmoxCluster,
99
+ }),
100
+ ).toBe(
101
+ "The Proxmox AI agent stopped responding while this command was running — it may have restarted or lost its connection. What the command did is unknown.",
102
+ );
103
+ expect(
104
+ reason({
105
+ kind: "overall",
106
+ wasClaimed: true,
107
+ resourceType: AiResourceType.ProxmoxCluster,
108
+ }),
109
+ ).toBe(
110
+ "The Proxmox AI agent did not report a result for this command in time — the command may have outlived its 30s timeout. What the command did is unknown.",
111
+ );
112
+ });
113
+
114
+ it("tells a remediation to check the resource before running a change again", () => {
115
+ for (const kind of [
116
+ "lease_expired",
117
+ "overall",
118
+ ] as Array<RunnerJobTimeoutKind>) {
119
+ expect(
120
+ reason({
121
+ kind,
122
+ wasClaimed: true,
123
+ origin: RunnerJobOrigin.AiRemediation,
124
+ resourceType: AiResourceType.DockerSwarmCluster,
125
+ }),
126
+ ).toContain(
127
+ "Check the Docker Swarm cluster before running a change again.",
128
+ );
129
+ }
130
+
131
+ // Nothing ran: nothing to check.
132
+ expect(
133
+ reason({
134
+ kind: "unclaimed",
135
+ origin: RunnerJobOrigin.AiRemediation,
136
+ resourceType: AiResourceType.DockerSwarmCluster,
137
+ }),
138
+ ).not.toContain("Check the");
139
+ });
140
+
141
+ it("falls back to generic words for a row without a readable type", () => {
142
+ expect(reason({ kind: "unclaimed", resourceType: null })).toBe(
143
+ "The resource's AI agent did not pick up the command in time (within 60s) — it may be offline, restarting or busy with other work. Nothing was run on the resource.",
144
+ );
145
+ });
146
+
147
+ it("leaves the kubectl wording exactly as it was", () => {
148
+ expect(
149
+ reason({
150
+ kind: "unclaimed",
151
+ stepType: RunbookStepType.Kubectl,
152
+ isForKubernetesAiAgent: true,
153
+ resourceType: AiResourceType.DockerHost,
154
+ }),
155
+ ).toBe(
156
+ "The cluster's Kubernetes AI agent did not pick up this kubectl command within 60s — it may be offline, restarting or busy with other work. Nothing was run on the cluster.",
157
+ );
158
+ expect(
159
+ reason({ kind: "unclaimed", stepType: RunbookStepType.Kubectl }),
160
+ ).toBe(
161
+ "The cluster's Runner did not pick up this kubectl command within 60s — it may be offline, restarting or busy with other work. Nothing was run on the cluster.",
162
+ );
163
+ });
164
+
165
+ it("leaves a runbook step's wording as it was", () => {
166
+ expect(
167
+ reason({
168
+ kind: "unclaimed",
169
+ origin: RunnerJobOrigin.Runbook,
170
+ stepType: RunbookStepType.Bash,
171
+ }),
172
+ ).toBe(
173
+ "No runbook agent picked up this step before the wait window expired. The agent may be offline — check that it is running and reachable, then try again.",
174
+ );
175
+ });
176
+ });
177
+
178
+ describe("RunnerJobService.pollUntilTerminal on a resource command", () => {
179
+ let row: Record<string, unknown>;
180
+ let findOneById: jest.SpyInstance;
181
+ let timeoutSpy: jest.SpyInstance;
182
+
183
+ beforeEach(() => {
184
+ row = {};
185
+ findOneById = jest
186
+ .spyOn(RunnerJobService, "findOneById")
187
+ .mockImplementation(async (): Promise<RunnerJob> => {
188
+ return row as unknown as RunnerJob;
189
+ });
190
+ timeoutSpy = jest
191
+ .spyOn(RunnerJobService, "timeoutJob")
192
+ .mockImplementation(
193
+ async (data: { reason: string }): Promise<RunnerJob> => {
194
+ return {
195
+ status: RunnerJobStatus.TimedOut,
196
+ errorMessage: data.reason,
197
+ } as unknown as RunnerJob;
198
+ },
199
+ );
200
+ });
201
+
202
+ afterEach(() => {
203
+ jest.restoreAllMocks();
204
+ });
205
+
206
+ it("reads the resource agent and its type off the row and words the timeout", async () => {
207
+ row = {
208
+ status: RunnerJobStatus.Pending,
209
+ origin: RunnerJobOrigin.AiInvestigation,
210
+ stepType: RunbookStepType.ResourceCommand,
211
+ targetResourceAiAgentId: AGENT_ID,
212
+ resourceType: AiResourceType.PodmanHost,
213
+ claimDeadlineAt: new Date(Date.now() - 1000),
214
+ leaseExpiresAt: new Date(Date.now() + 60_000),
215
+ };
216
+
217
+ const job: RunnerJob = await RunnerJobService.pollUntilTerminal({
218
+ jobId: JOB_ID,
219
+ claimTimeoutInMs: CLAIM_TIMEOUT_MS,
220
+ executionTimeoutInMs: EXECUTION_TIMEOUT_MS,
221
+ });
222
+
223
+ const select: Record<string, unknown> = (
224
+ findOneById.mock.calls[0]![0] as { select: Record<string, unknown> }
225
+ ).select;
226
+
227
+ expect(select["targetResourceAiAgentId"]).toBe(true);
228
+ expect(select["resourceType"]).toBe(true);
229
+ // The Kubernetes target is still read for kubectl rows.
230
+ expect(select["targetKubernetesAiAgentId"]).toBe(true);
231
+ expect(timeoutSpy).toHaveBeenCalledTimes(1);
232
+ expect(job.errorMessage).toContain(
233
+ "The Podman AI agent did not pick up the command in time",
234
+ );
235
+ });
236
+
237
+ it("returns a terminal resource job as it is", async () => {
238
+ row = {
239
+ status: RunnerJobStatus.Succeeded,
240
+ stepType: RunbookStepType.ResourceCommand,
241
+ output: "[stdout]\nok",
242
+ };
243
+
244
+ const job: RunnerJob = await RunnerJobService.pollUntilTerminal({
245
+ jobId: JOB_ID,
246
+ claimTimeoutInMs: CLAIM_TIMEOUT_MS,
247
+ executionTimeoutInMs: EXECUTION_TIMEOUT_MS,
248
+ });
249
+
250
+ expect(job.status).toBe(RunnerJobStatus.Succeeded);
251
+ expect(timeoutSpy).not.toHaveBeenCalled();
252
+ });
253
+ });
254
+
255
+ describe("RunnerJobService.submitResult with the job's resource command", () => {
256
+ let queries: Array<{ sql: string; params: Array<unknown> }>;
257
+
258
+ beforeEach(() => {
259
+ queries = [];
260
+ jest.spyOn(PostgresAppInstance, "getDataSource").mockReturnValue({
261
+ query: jest
262
+ .fn()
263
+ .mockImplementation(
264
+ async (sql: string, params: Array<unknown>): Promise<unknown> => {
265
+ queries.push({ sql, params });
266
+ return [[{ _id: JOB_ID.toString() }], 1];
267
+ },
268
+ ),
269
+ } as never);
270
+ });
271
+
272
+ afterEach(() => {
273
+ jest.restoreAllMocks();
274
+ });
275
+
276
+ const INSPECT_OUTPUT: string =
277
+ '[stdout]\n[{"Id":"abc","Config":{"Env":["FOO_SETTING=plainvalue42","PATH=/usr/bin"]}}]';
278
+
279
+ // $10 is the AI-origin output, $11 the AI-origin error (see the UPDATE).
280
+ function aiOriginOutput(): string {
281
+ return queries[queries.length - 1]!.params[9] as string;
282
+ }
283
+
284
+ function aiOriginError(): string {
285
+ return queries[queries.length - 1]!.params[10] as string;
286
+ }
287
+
288
+ function verbatimOutput(): string {
289
+ return queries[queries.length - 1]!.params[1] as string;
290
+ }
291
+
292
+ it("masks every docker inspect environment value for a Docker host's job", async () => {
293
+ await RunnerJobService.submitResult({
294
+ jobId: JOB_ID,
295
+ agentId: AGENT_ID,
296
+ success: true,
297
+ exitCode: 0,
298
+ output: INSPECT_OUTPUT,
299
+ resourceCommand: {
300
+ resourceType: AiResourceType.DockerHost,
301
+ program: "docker",
302
+ },
303
+ });
304
+
305
+ expect(aiOriginOutput()).not.toContain("plainvalue42");
306
+ expect(aiOriginOutput()).toContain("FOO_SETTING=[redacted]");
307
+ // The runbook branch of the CASE keeps the raw text, as always.
308
+ expect(verbatimOutput()).toBe(INSPECT_OUTPUT);
309
+ });
310
+
311
+ it("redacts the error message the same way", async () => {
312
+ await RunnerJobService.submitResult({
313
+ jobId: JOB_ID,
314
+ agentId: AGENT_ID,
315
+ success: false,
316
+ errorMessage:
317
+ '{"query":"SELECT * FROM users WHERE email = \'bob@example.com\' AND pin = 1234"}',
318
+ resourceCommand: {
319
+ resourceType: AiResourceType.DatabaseServer,
320
+ program: "db",
321
+ },
322
+ });
323
+
324
+ expect(aiOriginError()).not.toContain("bob@example.com");
325
+ expect(aiOriginError()).not.toContain("1234");
326
+ });
327
+
328
+ it("stores exactly what it always has without a resource command", async () => {
329
+ await RunnerJobService.submitResult({
330
+ jobId: JOB_ID,
331
+ agentId: AGENT_ID,
332
+ success: true,
333
+ exitCode: 0,
334
+ output: INSPECT_OUTPUT,
335
+ });
336
+
337
+ expect(aiOriginOutput()).toBe(
338
+ RunnerJobServiceClass.redactAiJobText(INSPECT_OUTPUT),
339
+ );
340
+ expect(aiOriginOutput()).toContain("plainvalue42");
341
+ });
342
+
343
+ it("redactResourceCommandText is the identity without a resource command", () => {
344
+ expect(RunnerJobServiceClass.redactResourceCommandText("x=1")).toBe("x=1");
345
+ expect(
346
+ RunnerJobServiceClass.redactResourceCommandText(INSPECT_OUTPUT, {
347
+ resourceType: AiResourceType.PodmanHost,
348
+ program: "docker",
349
+ }),
350
+ ).toContain("FOO_SETTING=[redacted]");
351
+ });
352
+ });