@oneuptime/common 11.5.4 → 11.5.5

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 (505) hide show
  1. package/Models/DatabaseModels/AIAgentTaskPullRequest.ts +56 -45
  2. package/Models/DatabaseModels/AIInsight.ts +748 -0
  3. package/Models/DatabaseModels/AIRun.ts +262 -0
  4. package/Models/DatabaseModels/CodeRepository.ts +42 -0
  5. package/Models/DatabaseModels/GlobalConfig.ts +105 -0
  6. package/Models/DatabaseModels/Index.ts +4 -8
  7. package/Models/DatabaseModels/InstanceHealthLog.ts +277 -0
  8. package/Models/DatabaseModels/LlmLog.ts +33 -0
  9. package/Models/DatabaseModels/Project.ts +123 -6
  10. package/Models/DatabaseModels/Runbook.ts +1 -1
  11. package/Server/API/AIAgentDataAPI.ts +802 -140
  12. package/Server/API/AIAgentTaskAPI.ts +132 -69
  13. package/Server/API/AIAgentTaskLogAPI.ts +65 -41
  14. package/Server/API/AIAgentTaskPullRequestAPI.ts +41 -0
  15. package/Server/API/AIInsightAPI.ts +220 -0
  16. package/Server/API/AIInvestigationAPI.ts +363 -1
  17. package/Server/API/CodeFixRunAPI.ts +251 -0
  18. package/Server/API/GitHubAPI.ts +246 -3
  19. package/Server/API/TelemetryExceptionAPI.ts +193 -48
  20. package/Server/EnvironmentConfig.ts +1 -1
  21. package/Server/Infrastructure/Postgres/SchemaMigrations/1783943300000-DropServiceCodeRepository.ts +26 -0
  22. package/Server/Infrastructure/Postgres/SchemaMigrations/1783947444597-CodeFixRunsOnAIRun.ts +73 -0
  23. package/Server/Infrastructure/Postgres/SchemaMigrations/1783950962813-AddCodeFixTaskType.ts +29 -0
  24. package/Server/Infrastructure/Postgres/SchemaMigrations/1783954040984-AddInstrumentationFixTasksFlag.ts +31 -0
  25. package/Server/Infrastructure/Postgres/SchemaMigrations/1783957160597-MigrationName.ts +51 -0
  26. package/Server/Infrastructure/Postgres/SchemaMigrations/1783958542237-AddTaskContextToAIRun.ts +25 -0
  27. package/Server/Infrastructure/Postgres/SchemaMigrations/1783965945957-AddInvestigationVerdictAndGrade.ts +47 -0
  28. package/Server/Infrastructure/Postgres/SchemaMigrations/1783970619301-AddFixGuardrailColumns.ts +53 -0
  29. package/Server/Infrastructure/Postgres/SchemaMigrations/1783970619302-DropLegacyAIAgentTaskTables.ts +31 -0
  30. package/Server/Infrastructure/Postgres/SchemaMigrations/1783977781677-AddCiStatusToFixPullRequests.ts +37 -0
  31. package/Server/Infrastructure/Postgres/SchemaMigrations/1783990000000-AddCompletionTokensToLlmLog.ts +25 -0
  32. package/Server/Infrastructure/Postgres/SchemaMigrations/1784010274993-AddSentinelInsight.ts +75 -0
  33. package/Server/Infrastructure/Postgres/SchemaMigrations/1784010274994-AddSentinelInsightFlags.ts +37 -0
  34. package/Server/Infrastructure/Postgres/SchemaMigrations/1784030612266-RenameSentinelToAI.ts +203 -0
  35. package/Server/Infrastructure/Postgres/SchemaMigrations/1784033837629-MigrationName.ts +163 -0
  36. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +30 -0
  37. package/Server/Infrastructure/Queue.ts +82 -4
  38. package/Server/Infrastructure/Semaphore.ts +62 -1
  39. package/Server/Services/AIAgentService.ts +32 -0
  40. package/Server/Services/AIAgentTaskPullRequestService.ts +117 -0
  41. package/Server/Services/AIInsightService.ts +174 -0
  42. package/Server/Services/AIRunEventService.ts +63 -0
  43. package/Server/Services/AIRunService.ts +259 -1
  44. package/Server/Services/AIService.ts +249 -7
  45. package/Server/Services/AlertService.ts +4 -4
  46. package/Server/Services/CodeRepositoryService.ts +209 -0
  47. package/Server/Services/GlobalConfigService.ts +148 -0
  48. package/Server/Services/IncidentService.ts +183 -38
  49. package/Server/Services/IncidentStateTimelineService.ts +24 -4
  50. package/Server/Services/Index.ts +4 -4
  51. package/Server/Services/{AIAgentTaskLogService.ts → InstanceHealthLogService.ts} +1 -1
  52. package/Server/Services/LlmLogService.ts +27 -0
  53. package/Server/Services/LlmProviderService.ts +108 -0
  54. package/Server/Services/MetricBaselineService.ts +123 -0
  55. package/Server/Services/MonitorService.ts +15 -0
  56. package/Server/Services/TelemetryExceptionService.ts +323 -116
  57. package/Server/Services/TraceAggregationService.ts +176 -0
  58. package/Server/Types/Workflow/ComponentCode.ts +6 -0
  59. package/Server/Types/Workflow/Components/AI/GenerateText.ts +326 -0
  60. package/Server/Types/Workflow/Components/Index.ts +2 -0
  61. package/Server/Utils/AI/Chat/ObservabilityAssistant.ts +1 -1
  62. package/Server/Utils/AI/CodeFix/CodeAgentWorkspaceGuard.ts +71 -0
  63. package/Server/Utils/AI/CodeFix/CodeFixAgentCompletion.ts +243 -0
  64. package/Server/Utils/AI/CodeFix/CodeFixRunQueue.ts +131 -0
  65. package/Server/Utils/AI/CodeFix/FixRunBudget.ts +148 -0
  66. package/Server/Utils/AI/CodeFix/OpenPullRequestCap.ts +117 -0
  67. package/Server/Utils/AI/Eval/EvalCorpus.ts +369 -0
  68. package/Server/Utils/AI/Eval/EvalScores.ts +172 -0
  69. package/Server/Utils/AI/Eval/ReplayInvestigation.ts +87 -0
  70. package/Server/Utils/AI/PerfEvidence/SpanTreeAnalyzer.ts +676 -0
  71. package/Server/Utils/AI/{Sentinel/SentinelInvestigationEngine.ts → SRE/AIInvestigationEngine.ts} +58 -37
  72. package/Server/Utils/AI/{Sentinel/SentinelMemory.ts → SRE/AIMemory.ts} +3 -3
  73. package/Server/Utils/AI/{Sentinel → SRE}/AlertInvestigationRunner.ts +50 -20
  74. package/Server/Utils/AI/SRE/ConfidenceSignal.ts +293 -0
  75. package/Server/Utils/AI/SRE/FixFromIncidentTaskTrigger.ts +115 -0
  76. package/Server/Utils/AI/SRE/FixPerformanceTaskTrigger.ts +223 -0
  77. package/Server/Utils/AI/{Sentinel → SRE}/IncidentInvestigationRunner.ts +71 -21
  78. package/Server/Utils/AI/{Sentinel → SRE}/IncidentPostmortemRunner.ts +8 -8
  79. package/Server/Utils/AI/SRE/Insights/Detectors/ErrorLogSpikeDetector.ts +364 -0
  80. package/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.ts +317 -0
  81. package/Server/Utils/AI/SRE/Insights/Detectors/Index.ts +27 -0
  82. package/Server/Utils/AI/SRE/Insights/Detectors/MetricDriftDetector.ts +221 -0
  83. package/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.ts +238 -0
  84. package/Server/Utils/AI/SRE/Insights/Detectors/TraceLatencyRegressionDetector.ts +521 -0
  85. package/Server/Utils/AI/SRE/Insights/FixRouting.ts +242 -0
  86. package/Server/Utils/AI/SRE/Insights/InsightScanner.ts +290 -0
  87. package/Server/Utils/AI/SRE/Insights/InsightStore.ts +283 -0
  88. package/Server/Utils/AI/SRE/Insights/InsightTriageRunner.ts +242 -0
  89. package/Server/Utils/AI/SRE/Insights/Triage.ts +162 -0
  90. package/Server/Utils/AI/SRE/Insights/Types.ts +49 -0
  91. package/Server/Utils/AI/SRE/InstrumentationTaskTrigger.ts +212 -0
  92. package/Server/Utils/AI/SRE/InvestigationGrader.ts +282 -0
  93. package/Server/Utils/AI/{Sentinel → SRE}/InvestigationQueue.ts +114 -19
  94. package/Server/Utils/AI/{Sentinel → SRE}/README.md +4 -4
  95. package/Server/Utils/AI/SRE/SubjectCodeFixRun.ts +172 -0
  96. package/Server/Utils/AI/Toolbox/{SentinelActionTools.ts → AIActionTools.ts} +22 -1
  97. package/Server/Utils/AI/Toolbox/Index.ts +2 -2
  98. package/Server/Utils/AnalyticsDatabase/ClickhouseCapacity.ts +526 -0
  99. package/Server/Utils/CodeRepository/GitHub/GitHub.ts +319 -1
  100. package/Server/Utils/CodeRepository/ServiceRepoLinkSuggester.ts +221 -0
  101. package/Server/Utils/CodeRepository/StackTraceRepoResolver.ts +571 -0
  102. package/Server/Utils/Execute.ts +2 -1
  103. package/Server/Utils/LLM/LLMService.ts +160 -30
  104. package/Server/Utils/Monitor/Criteria/SqlMonitorCriteria.ts +152 -0
  105. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +29 -0
  106. package/Tests/Server/Infrastructure/Queue.test.ts +227 -0
  107. package/Tests/Server/Infrastructure/SemaphorePermit.test.ts +159 -0
  108. package/Tests/Server/Services/AIAgentTaskPullRequestOutcomeStats.test.ts +154 -0
  109. package/Tests/Server/Services/AIInsightService.test.ts +324 -0
  110. package/Tests/Server/Services/AIRunCodeFixClaim.test.ts +401 -0
  111. package/Tests/Server/Services/AIRunHumanVerdict.test.ts +161 -0
  112. package/Tests/Server/Services/AIServiceDailyBudget.test.ts +95 -5
  113. package/Tests/Server/Services/AIServiceProjectAccess.test.ts +259 -0
  114. package/Tests/Server/Services/FixFromIncidentTaskTrigger.test.ts +249 -0
  115. package/Tests/Server/Services/FixPerformanceTaskTrigger.test.ts +274 -0
  116. package/Tests/Server/Services/GlobalConfigService.test.ts +80 -0
  117. package/Tests/Server/Services/IncidentInternalNoteAnnouncement.test.ts +1 -1
  118. package/Tests/Server/Services/InstrumentationTaskTrigger.test.ts +313 -0
  119. package/Tests/Server/Services/LlmProviderProjectOwned.test.ts +132 -0
  120. package/Tests/Server/Services/TelemetryExceptionAIFixReadiness.test.ts +405 -0
  121. package/Tests/Server/Services/TelemetryExceptionCodeFixRun.test.ts +322 -0
  122. package/Tests/Server/Services/TraceServiceLatencyProfile.test.ts +278 -0
  123. package/Tests/Server/Types/Workflow/Components/AIGenerateText.test.ts +722 -0
  124. package/Tests/Server/Utils/AI/{SentinelAlertGating.test.ts → AIAlertGating.test.ts} +19 -19
  125. package/Tests/Server/Utils/AI/AIConfidenceSignal.test.ts +362 -0
  126. package/Tests/Server/Utils/AI/{SentinelInvestigationQueue.test.ts → AIInvestigationQueue.test.ts} +19 -19
  127. package/Tests/Server/Utils/AI/CodeAgentWorkspaceGuard.test.ts +138 -0
  128. package/Tests/Server/Utils/AI/CodeFixAgentCompletion.test.ts +335 -0
  129. package/Tests/Server/Utils/AI/CodeFixRunQueue.test.ts +134 -0
  130. package/Tests/Server/Utils/AI/EvalCorpus.test.ts +209 -0
  131. package/Tests/Server/Utils/AI/EvalScores.test.ts +343 -0
  132. package/Tests/Server/Utils/AI/FixRunBudget.test.ts +218 -0
  133. package/Tests/Server/Utils/AI/Insights/ErrorLogSpikeDetector.test.ts +437 -0
  134. package/Tests/Server/Utils/AI/Insights/ExceptionSpikeDetector.test.ts +287 -0
  135. package/Tests/Server/Utils/AI/Insights/InsightDetectorsIndex.test.ts +34 -0
  136. package/Tests/Server/Utils/AI/Insights/InsightFixRouting.test.ts +572 -0
  137. package/Tests/Server/Utils/AI/Insights/InsightNeverThrowsHardening.test.ts +344 -0
  138. package/Tests/Server/Utils/AI/Insights/InsightScanner.test.ts +720 -0
  139. package/Tests/Server/Utils/AI/Insights/InsightStore.test.ts +467 -0
  140. package/Tests/Server/Utils/AI/Insights/InsightStoreHardening.test.ts +370 -0
  141. package/Tests/Server/Utils/AI/Insights/InsightTriage.test.ts +210 -0
  142. package/Tests/Server/Utils/AI/Insights/InsightTriageRunner.test.ts +221 -0
  143. package/Tests/Server/Utils/AI/Insights/InvestigationQueueInsightSubject.test.ts +328 -0
  144. package/Tests/Server/Utils/AI/Insights/MetricBaselineDrift.test.ts +182 -0
  145. package/Tests/Server/Utils/AI/Insights/MetricDriftDetector.test.ts +280 -0
  146. package/Tests/Server/Utils/AI/Insights/NewExceptionDetector.test.ts +259 -0
  147. package/Tests/Server/Utils/AI/Insights/TraceLatencyRegressionDetector.test.ts +770 -0
  148. package/Tests/Server/Utils/AI/InvestigationGrader.test.ts +343 -0
  149. package/Tests/Server/Utils/AI/LLMServiceRequestPolicy.test.ts +307 -0
  150. package/Tests/Server/Utils/AI/OpenPullRequestCap.test.ts +170 -0
  151. package/Tests/Server/Utils/AI/SpanTreeAnalyzer.test.ts +559 -0
  152. package/Tests/Server/Utils/AnalyticsDatabase/ClickhouseCapacity.test.ts +158 -0
  153. package/Tests/Server/Utils/GitHubCheckRunsConclusion.test.ts +100 -0
  154. package/Tests/Server/Utils/GitHubPullRequestStateMapping.test.ts +50 -0
  155. package/Tests/Server/Utils/Monitor/Criteria/SqlMonitorCriteria.test.ts +266 -0
  156. package/Tests/Server/Utils/ServiceRepoLinkSuggester.test.ts +167 -0
  157. package/Tests/Server/Utils/StackTraceRepoResolver.test.ts +527 -0
  158. package/Tests/Types/AI/AIChatPermissionMode.test.ts +112 -0
  159. package/Tests/Types/AI/CodeFixTaskType.test.ts +152 -0
  160. package/Tests/Types/AI/FixPullRequestCiStatus.test.ts +181 -0
  161. package/Tests/Types/Monitor/MonitorStepSqlMonitor.test.ts +110 -0
  162. package/Tests/Types/Monitor/SqlDatabaseType.test.ts +55 -0
  163. package/Tests/Types/Workflow/AIGenerateTextMetadata.test.ts +180 -0
  164. package/Tests/UI/Components/TableBulkCsvExport.test.tsx +168 -0
  165. package/Tests/UI/Utils/TableColumnsToCsv.test.ts +523 -0
  166. package/Types/AI/AIChatTypes.ts +8 -0
  167. package/Types/AI/AIInsightEvidence.ts +77 -0
  168. package/Types/AI/AIInsightHumanVerdict.ts +15 -0
  169. package/Types/AI/AIInsightSeverity.ts +13 -0
  170. package/Types/AI/AIInsightStatus.ts +38 -0
  171. package/Types/AI/AIInsightType.ts +41 -0
  172. package/Types/AI/AIRunAutoGrade.ts +18 -0
  173. package/Types/AI/AIRunEventType.ts +5 -0
  174. package/Types/AI/AIRunHumanVerdict.ts +17 -0
  175. package/Types/AI/AIRunType.ts +6 -0
  176. package/Types/AI/CodeFixTaskContext.ts +88 -0
  177. package/Types/AI/CodeFixTaskType.ts +132 -0
  178. package/Types/AI/FixPullRequestCiStatus.ts +132 -0
  179. package/Types/BaseDatabase/AggregationIntervalUtil.ts +67 -0
  180. package/Types/Incident/IncidentMetricType.ts +7 -0
  181. package/Types/Monitor/CriteriaFilter.ts +8 -0
  182. package/Types/Monitor/MonitorCriteriaInstance.ts +67 -0
  183. package/Types/Monitor/MonitorStep.ts +38 -0
  184. package/Types/Monitor/MonitorStepSqlMonitor.ts +141 -0
  185. package/Types/Monitor/MonitorType.ts +17 -0
  186. package/Types/Monitor/SqlDatabaseType.ts +49 -0
  187. package/Types/Monitor/SqlMonitor/SqlMonitorResponse.ts +28 -0
  188. package/Types/Permission.ts +11 -95
  189. package/Types/Probe/ProbeMonitorResponse.ts +2 -0
  190. package/Types/Runbook/RunbookStep.ts +26 -2
  191. package/Types/Runbook/RunbookStepType.ts +1 -0
  192. package/Types/Workflow/Component.ts +13 -0
  193. package/Types/Workflow/ComponentID.ts +1 -0
  194. package/Types/Workflow/Components/AI.ts +148 -0
  195. package/Types/Workflow/Components.ts +8 -0
  196. package/UI/Components/AI/GenerateFromAIModal.tsx +1 -1
  197. package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +11 -0
  198. package/UI/Components/MoreMenu/MoreMenu.tsx +1 -1
  199. package/UI/Components/Table/Table.tsx +38 -2
  200. package/UI/Utils/TableColumnsToCsv.ts +385 -0
  201. package/Utils/Monitor/MonitorMetricType.ts +1 -0
  202. package/build/dist/Models/DatabaseModels/AIAgentTaskPullRequest.js +59 -45
  203. package/build/dist/Models/DatabaseModels/AIAgentTaskPullRequest.js.map +1 -1
  204. package/build/dist/Models/DatabaseModels/AIInsight.js +795 -0
  205. package/build/dist/Models/DatabaseModels/AIInsight.js.map +1 -0
  206. package/build/dist/Models/DatabaseModels/AIRun.js +274 -0
  207. package/build/dist/Models/DatabaseModels/AIRun.js.map +1 -1
  208. package/build/dist/Models/DatabaseModels/CodeRepository.js +43 -0
  209. package/build/dist/Models/DatabaseModels/CodeRepository.js.map +1 -1
  210. package/build/dist/Models/DatabaseModels/GlobalConfig.js +110 -0
  211. package/build/dist/Models/DatabaseModels/GlobalConfig.js.map +1 -1
  212. package/build/dist/Models/DatabaseModels/Index.js +4 -8
  213. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  214. package/build/dist/Models/DatabaseModels/InstanceHealthLog.js +304 -0
  215. package/build/dist/Models/DatabaseModels/InstanceHealthLog.js.map +1 -0
  216. package/build/dist/Models/DatabaseModels/LlmLog.js +35 -0
  217. package/build/dist/Models/DatabaseModels/LlmLog.js.map +1 -1
  218. package/build/dist/Models/DatabaseModels/Project.js +127 -6
  219. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  220. package/build/dist/Models/DatabaseModels/Runbook.js +1 -1
  221. package/build/dist/Models/DatabaseModels/Runbook.js.map +1 -1
  222. package/build/dist/Server/API/AIAgentDataAPI.js +568 -85
  223. package/build/dist/Server/API/AIAgentDataAPI.js.map +1 -1
  224. package/build/dist/Server/API/AIAgentTaskAPI.js +100 -44
  225. package/build/dist/Server/API/AIAgentTaskAPI.js.map +1 -1
  226. package/build/dist/Server/API/AIAgentTaskLogAPI.js +49 -25
  227. package/build/dist/Server/API/AIAgentTaskLogAPI.js.map +1 -1
  228. package/build/dist/Server/API/AIAgentTaskPullRequestAPI.js +27 -0
  229. package/build/dist/Server/API/AIAgentTaskPullRequestAPI.js.map +1 -1
  230. package/build/dist/Server/API/AIInsightAPI.js +140 -0
  231. package/build/dist/Server/API/AIInsightAPI.js.map +1 -0
  232. package/build/dist/Server/API/AIInvestigationAPI.js +257 -1
  233. package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
  234. package/build/dist/Server/API/CodeFixRunAPI.js +181 -0
  235. package/build/dist/Server/API/CodeFixRunAPI.js.map +1 -0
  236. package/build/dist/Server/API/GitHubAPI.js +164 -2
  237. package/build/dist/Server/API/GitHubAPI.js.map +1 -1
  238. package/build/dist/Server/API/TelemetryExceptionAPI.js +148 -43
  239. package/build/dist/Server/API/TelemetryExceptionAPI.js.map +1 -1
  240. package/build/dist/Server/EnvironmentConfig.js +1 -1
  241. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  242. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783943300000-DropServiceCodeRepository.js +23 -0
  243. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783943300000-DropServiceCodeRepository.js.map +1 -0
  244. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783947444597-CodeFixRunsOnAIRun.js +32 -0
  245. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783947444597-CodeFixRunsOnAIRun.js.map +1 -0
  246. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783950962813-AddCodeFixTaskType.js +16 -0
  247. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783950962813-AddCodeFixTaskType.js.map +1 -0
  248. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783954040984-AddInstrumentationFixTasksFlag.js +16 -0
  249. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783954040984-AddInstrumentationFixTasksFlag.js.map +1 -0
  250. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783957160597-MigrationName.js +24 -0
  251. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783957160597-MigrationName.js.map +1 -0
  252. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783958542237-AddTaskContextToAIRun.js +16 -0
  253. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783958542237-AddTaskContextToAIRun.js.map +1 -0
  254. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783965945957-AddInvestigationVerdictAndGrade.js +24 -0
  255. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783965945957-AddInvestigationVerdictAndGrade.js.map +1 -0
  256. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783970619301-AddFixGuardrailColumns.js +24 -0
  257. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783970619301-AddFixGuardrailColumns.js.map +1 -0
  258. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783970619302-DropLegacyAIAgentTaskTables.js +24 -0
  259. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783970619302-DropLegacyAIAgentTaskTables.js.map +1 -0
  260. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783977781677-AddCiStatusToFixPullRequests.js +18 -0
  261. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783977781677-AddCiStatusToFixPullRequests.js.map +1 -0
  262. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783990000000-AddCompletionTokensToLlmLog.js +18 -0
  263. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783990000000-AddCompletionTokensToLlmLog.js.map +1 -0
  264. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784010274993-AddSentinelInsight.js +32 -0
  265. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784010274993-AddSentinelInsight.js.map +1 -0
  266. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784010274994-AddSentinelInsightFlags.js +18 -0
  267. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784010274994-AddSentinelInsightFlags.js.map +1 -0
  268. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784030612266-RenameSentinelToAI.js +125 -0
  269. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784030612266-RenameSentinelToAI.js.map +1 -0
  270. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784033837629-MigrationName.js +62 -0
  271. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784033837629-MigrationName.js.map +1 -0
  272. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +30 -0
  273. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  274. package/build/dist/Server/Infrastructure/Queue.js +73 -3
  275. package/build/dist/Server/Infrastructure/Queue.js.map +1 -1
  276. package/build/dist/Server/Infrastructure/Semaphore.js +44 -1
  277. package/build/dist/Server/Infrastructure/Semaphore.js.map +1 -1
  278. package/build/dist/Server/Services/AIAgentService.js +29 -0
  279. package/build/dist/Server/Services/AIAgentService.js.map +1 -1
  280. package/build/dist/Server/Services/AIAgentTaskPullRequestService.js +78 -0
  281. package/build/dist/Server/Services/AIAgentTaskPullRequestService.js.map +1 -1
  282. package/build/dist/Server/Services/AIInsightService.js +164 -0
  283. package/build/dist/Server/Services/AIInsightService.js.map +1 -0
  284. package/build/dist/Server/Services/AIRunEventService.js +49 -0
  285. package/build/dist/Server/Services/AIRunEventService.js.map +1 -1
  286. package/build/dist/Server/Services/AIRunService.js +221 -0
  287. package/build/dist/Server/Services/AIRunService.js.map +1 -1
  288. package/build/dist/Server/Services/AIService.js +198 -11
  289. package/build/dist/Server/Services/AIService.js.map +1 -1
  290. package/build/dist/Server/Services/AlertService.js +4 -4
  291. package/build/dist/Server/Services/AlertService.js.map +1 -1
  292. package/build/dist/Server/Services/CodeRepositoryService.js +180 -0
  293. package/build/dist/Server/Services/CodeRepositoryService.js.map +1 -1
  294. package/build/dist/Server/Services/GlobalConfigService.js +84 -0
  295. package/build/dist/Server/Services/GlobalConfigService.js.map +1 -1
  296. package/build/dist/Server/Services/IncidentService.js +149 -37
  297. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  298. package/build/dist/Server/Services/IncidentStateTimelineService.js +24 -4
  299. package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
  300. package/build/dist/Server/Services/Index.js +4 -4
  301. package/build/dist/Server/Services/Index.js.map +1 -1
  302. package/build/dist/Server/Services/{AIAgentTaskLogService.js → InstanceHealthLogService.js} +2 -2
  303. package/build/dist/Server/Services/InstanceHealthLogService.js.map +1 -0
  304. package/build/dist/Server/Services/LlmLogService.js +23 -0
  305. package/build/dist/Server/Services/LlmLogService.js.map +1 -1
  306. package/build/dist/Server/Services/LlmProviderService.js +96 -0
  307. package/build/dist/Server/Services/LlmProviderService.js.map +1 -1
  308. package/build/dist/Server/Services/MetricBaselineService.js +65 -0
  309. package/build/dist/Server/Services/MetricBaselineService.js.map +1 -1
  310. package/build/dist/Server/Services/MonitorService.js +9 -1
  311. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  312. package/build/dist/Server/Services/TelemetryExceptionService.js +243 -82
  313. package/build/dist/Server/Services/TelemetryExceptionService.js.map +1 -1
  314. package/build/dist/Server/Services/TraceAggregationService.js +124 -0
  315. package/build/dist/Server/Services/TraceAggregationService.js.map +1 -1
  316. package/build/dist/Server/Types/Workflow/ComponentCode.js.map +1 -1
  317. package/build/dist/Server/Types/Workflow/Components/AI/GenerateText.js +240 -0
  318. package/build/dist/Server/Types/Workflow/Components/AI/GenerateText.js.map +1 -0
  319. package/build/dist/Server/Types/Workflow/Components/Index.js +2 -0
  320. package/build/dist/Server/Types/Workflow/Components/Index.js.map +1 -1
  321. package/build/dist/Server/Utils/AI/CodeFix/CodeAgentWorkspaceGuard.js +48 -0
  322. package/build/dist/Server/Utils/AI/CodeFix/CodeAgentWorkspaceGuard.js.map +1 -0
  323. package/build/dist/Server/Utils/AI/CodeFix/CodeFixAgentCompletion.js +174 -0
  324. package/build/dist/Server/Utils/AI/CodeFix/CodeFixAgentCompletion.js.map +1 -0
  325. package/build/dist/Server/Utils/AI/CodeFix/CodeFixRunQueue.js +126 -0
  326. package/build/dist/Server/Utils/AI/CodeFix/CodeFixRunQueue.js.map +1 -0
  327. package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js +131 -0
  328. package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js.map +1 -0
  329. package/build/dist/Server/Utils/AI/CodeFix/OpenPullRequestCap.js +99 -0
  330. package/build/dist/Server/Utils/AI/CodeFix/OpenPullRequestCap.js.map +1 -0
  331. package/build/dist/Server/Utils/AI/Eval/EvalCorpus.js +245 -0
  332. package/build/dist/Server/Utils/AI/Eval/EvalCorpus.js.map +1 -0
  333. package/build/dist/Server/Utils/AI/Eval/EvalScores.js +83 -0
  334. package/build/dist/Server/Utils/AI/Eval/EvalScores.js.map +1 -0
  335. package/build/dist/Server/Utils/AI/Eval/ReplayInvestigation.js +12 -0
  336. package/build/dist/Server/Utils/AI/Eval/ReplayInvestigation.js.map +1 -0
  337. package/build/dist/Server/Utils/AI/PerfEvidence/SpanTreeAnalyzer.js +439 -0
  338. package/build/dist/Server/Utils/AI/PerfEvidence/SpanTreeAnalyzer.js.map +1 -0
  339. package/build/dist/Server/Utils/AI/{Sentinel/SentinelInvestigationEngine.js → SRE/AIInvestigationEngine.js} +47 -31
  340. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -0
  341. package/build/dist/Server/Utils/AI/{Sentinel/SentinelMemory.js → SRE/AIMemory.js} +5 -5
  342. package/build/dist/Server/Utils/AI/SRE/AIMemory.js.map +1 -0
  343. package/build/dist/Server/Utils/AI/{Sentinel → SRE}/AlertInvestigationRunner.js +42 -19
  344. package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js.map +1 -0
  345. package/build/dist/Server/Utils/AI/SRE/ConfidenceSignal.js +226 -0
  346. package/build/dist/Server/Utils/AI/SRE/ConfidenceSignal.js.map +1 -0
  347. package/build/dist/Server/Utils/AI/SRE/FixFromIncidentTaskTrigger.js +100 -0
  348. package/build/dist/Server/Utils/AI/SRE/FixFromIncidentTaskTrigger.js.map +1 -0
  349. package/build/dist/Server/Utils/AI/SRE/FixPerformanceTaskTrigger.js +174 -0
  350. package/build/dist/Server/Utils/AI/SRE/FixPerformanceTaskTrigger.js.map +1 -0
  351. package/build/dist/Server/Utils/AI/{Sentinel → SRE}/IncidentInvestigationRunner.js +60 -22
  352. package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js.map +1 -0
  353. package/build/dist/Server/Utils/AI/{Sentinel → SRE}/IncidentPostmortemRunner.js +9 -9
  354. package/build/dist/Server/Utils/AI/SRE/IncidentPostmortemRunner.js.map +1 -0
  355. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ErrorLogSpikeDetector.js +268 -0
  356. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ErrorLogSpikeDetector.js.map +1 -0
  357. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.js +226 -0
  358. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.js.map +1 -0
  359. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/Index.js +26 -0
  360. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/Index.js.map +1 -0
  361. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/MetricDriftDetector.js +159 -0
  362. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/MetricDriftDetector.js.map +1 -0
  363. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.js +177 -0
  364. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.js.map +1 -0
  365. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/TraceLatencyRegressionDetector.js +384 -0
  366. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/TraceLatencyRegressionDetector.js.map +1 -0
  367. package/build/dist/Server/Utils/AI/SRE/Insights/FixRouting.js +180 -0
  368. package/build/dist/Server/Utils/AI/SRE/Insights/FixRouting.js.map +1 -0
  369. package/build/dist/Server/Utils/AI/SRE/Insights/InsightScanner.js +269 -0
  370. package/build/dist/Server/Utils/AI/SRE/Insights/InsightScanner.js.map +1 -0
  371. package/build/dist/Server/Utils/AI/SRE/Insights/InsightStore.js +231 -0
  372. package/build/dist/Server/Utils/AI/SRE/Insights/InsightStore.js.map +1 -0
  373. package/build/dist/Server/Utils/AI/SRE/Insights/InsightTriageRunner.js +206 -0
  374. package/build/dist/Server/Utils/AI/SRE/Insights/InsightTriageRunner.js.map +1 -0
  375. package/build/dist/Server/Utils/AI/SRE/Insights/Triage.js +121 -0
  376. package/build/dist/Server/Utils/AI/SRE/Insights/Triage.js.map +1 -0
  377. package/build/dist/Server/Utils/AI/SRE/Insights/Types.js +2 -0
  378. package/build/dist/Server/Utils/AI/SRE/Insights/Types.js.map +1 -0
  379. package/build/dist/Server/Utils/AI/SRE/InstrumentationTaskTrigger.js +148 -0
  380. package/build/dist/Server/Utils/AI/SRE/InstrumentationTaskTrigger.js.map +1 -0
  381. package/build/dist/Server/Utils/AI/SRE/InvestigationGrader.js +231 -0
  382. package/build/dist/Server/Utils/AI/SRE/InvestigationGrader.js.map +1 -0
  383. package/build/dist/Server/Utils/AI/{Sentinel → SRE}/InvestigationQueue.js +102 -23
  384. package/build/dist/Server/Utils/AI/SRE/InvestigationQueue.js.map +1 -0
  385. package/build/dist/Server/Utils/AI/SRE/SubjectCodeFixRun.js +167 -0
  386. package/build/dist/Server/Utils/AI/SRE/SubjectCodeFixRun.js.map +1 -0
  387. package/build/dist/Server/Utils/AI/Toolbox/{SentinelActionTools.js → AIActionTools.js} +18 -2
  388. package/build/dist/Server/Utils/AI/Toolbox/AIActionTools.js.map +1 -0
  389. package/build/dist/Server/Utils/AI/Toolbox/Index.js +2 -2
  390. package/build/dist/Server/Utils/AI/Toolbox/Index.js.map +1 -1
  391. package/build/dist/Server/Utils/AnalyticsDatabase/ClickhouseCapacity.js +301 -0
  392. package/build/dist/Server/Utils/AnalyticsDatabase/ClickhouseCapacity.js.map +1 -0
  393. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js +240 -2
  394. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js.map +1 -1
  395. package/build/dist/Server/Utils/CodeRepository/ServiceRepoLinkSuggester.js +127 -0
  396. package/build/dist/Server/Utils/CodeRepository/ServiceRepoLinkSuggester.js.map +1 -0
  397. package/build/dist/Server/Utils/CodeRepository/StackTraceRepoResolver.js +336 -0
  398. package/build/dist/Server/Utils/CodeRepository/StackTraceRepoResolver.js.map +1 -0
  399. package/build/dist/Server/Utils/Execute.js.map +1 -1
  400. package/build/dist/Server/Utils/LLM/LLMService.js +125 -25
  401. package/build/dist/Server/Utils/LLM/LLMService.js.map +1 -1
  402. package/build/dist/Server/Utils/Monitor/Criteria/SqlMonitorCriteria.js +120 -0
  403. package/build/dist/Server/Utils/Monitor/Criteria/SqlMonitorCriteria.js.map +1 -0
  404. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +21 -0
  405. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  406. package/build/dist/Types/AI/AIInsightEvidence.js +2 -0
  407. package/build/dist/Types/AI/AIInsightEvidence.js.map +1 -0
  408. package/build/dist/Types/AI/AIInsightHumanVerdict.js +16 -0
  409. package/build/dist/Types/AI/AIInsightHumanVerdict.js.map +1 -0
  410. package/build/dist/Types/AI/AIInsightSeverity.js +14 -0
  411. package/build/dist/Types/AI/AIInsightSeverity.js.map +1 -0
  412. package/build/dist/Types/AI/AIInsightStatus.js +36 -0
  413. package/build/dist/Types/AI/AIInsightStatus.js.map +1 -0
  414. package/build/dist/Types/AI/AIInsightType.js +42 -0
  415. package/build/dist/Types/AI/AIInsightType.js.map +1 -0
  416. package/build/dist/Types/AI/AIRunAutoGrade.js +19 -0
  417. package/build/dist/Types/AI/AIRunAutoGrade.js.map +1 -0
  418. package/build/dist/Types/AI/AIRunEventType.js +5 -0
  419. package/build/dist/Types/AI/AIRunEventType.js.map +1 -1
  420. package/build/dist/Types/AI/AIRunHumanVerdict.js +18 -0
  421. package/build/dist/Types/AI/AIRunHumanVerdict.js.map +1 -0
  422. package/build/dist/Types/AI/AIRunType.js +6 -0
  423. package/build/dist/Types/AI/AIRunType.js.map +1 -1
  424. package/build/dist/Types/AI/CodeFixTaskContext.js +29 -0
  425. package/build/dist/Types/AI/CodeFixTaskContext.js.map +1 -0
  426. package/build/dist/Types/AI/CodeFixTaskType.js +122 -0
  427. package/build/dist/Types/AI/CodeFixTaskType.js.map +1 -0
  428. package/build/dist/Types/AI/FixPullRequestCiStatus.js +102 -0
  429. package/build/dist/Types/AI/FixPullRequestCiStatus.js.map +1 -0
  430. package/build/dist/Types/BaseDatabase/AggregationIntervalUtil.js +55 -0
  431. package/build/dist/Types/BaseDatabase/AggregationIntervalUtil.js.map +1 -1
  432. package/build/dist/Types/Incident/IncidentMetricType.js +7 -0
  433. package/build/dist/Types/Incident/IncidentMetricType.js.map +1 -1
  434. package/build/dist/Types/Monitor/CriteriaFilter.js +7 -0
  435. package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
  436. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +62 -0
  437. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
  438. package/build/dist/Types/Monitor/MonitorStep.js +28 -0
  439. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  440. package/build/dist/Types/Monitor/MonitorStepSqlMonitor.js +93 -0
  441. package/build/dist/Types/Monitor/MonitorStepSqlMonitor.js.map +1 -0
  442. package/build/dist/Types/Monitor/MonitorType.js +15 -0
  443. package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
  444. package/build/dist/Types/Monitor/SqlDatabaseType.js +47 -0
  445. package/build/dist/Types/Monitor/SqlDatabaseType.js.map +1 -0
  446. package/build/dist/Types/Monitor/SqlMonitor/SqlMonitorResponse.js +2 -0
  447. package/build/dist/Types/Monitor/SqlMonitor/SqlMonitorResponse.js.map +1 -0
  448. package/build/dist/Types/Permission.js +10 -84
  449. package/build/dist/Types/Permission.js.map +1 -1
  450. package/build/dist/Types/Runbook/RunbookStepType.js +1 -0
  451. package/build/dist/Types/Runbook/RunbookStepType.js.map +1 -1
  452. package/build/dist/Types/Workflow/ComponentID.js +1 -0
  453. package/build/dist/Types/Workflow/ComponentID.js.map +1 -1
  454. package/build/dist/Types/Workflow/Components/AI.js +135 -0
  455. package/build/dist/Types/Workflow/Components/AI.js.map +1 -0
  456. package/build/dist/Types/Workflow/Components.js +7 -0
  457. package/build/dist/Types/Workflow/Components.js.map +1 -1
  458. package/build/dist/UI/Components/AI/GenerateFromAIModal.js +1 -1
  459. package/build/dist/UI/Components/AI/GenerateFromAIModal.js.map +1 -1
  460. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +9 -0
  461. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
  462. package/build/dist/UI/Components/MoreMenu/MoreMenu.js +1 -1
  463. package/build/dist/UI/Components/Table/Table.js +28 -2
  464. package/build/dist/UI/Components/Table/Table.js.map +1 -1
  465. package/build/dist/UI/Utils/TableColumnsToCsv.js +291 -0
  466. package/build/dist/UI/Utils/TableColumnsToCsv.js.map +1 -0
  467. package/build/dist/Utils/Monitor/MonitorMetricType.js +1 -0
  468. package/build/dist/Utils/Monitor/MonitorMetricType.js.map +1 -1
  469. package/package.json +1 -1
  470. package/Models/DatabaseModels/AIAgentTask.ts +0 -660
  471. package/Models/DatabaseModels/AIAgentTaskLog.ts +0 -426
  472. package/Models/DatabaseModels/AIAgentTaskTelemetryException.ts +0 -399
  473. package/Models/DatabaseModels/ServiceCodeRepository.ts +0 -647
  474. package/Server/Services/AIAgentTaskService.ts +0 -240
  475. package/Server/Services/AIAgentTaskTelemetryExceptionService.ts +0 -39
  476. package/Server/Services/ServiceCodeRepositoryService.ts +0 -55
  477. package/Tests/Server/Services/AIAgentTaskServiceClaim.test.ts +0 -146
  478. package/Types/AI/AIAgentTaskMetadata.ts +0 -25
  479. package/Types/AI/AIAgentTaskType.ts +0 -40
  480. package/build/dist/Models/DatabaseModels/AIAgentTask.js +0 -691
  481. package/build/dist/Models/DatabaseModels/AIAgentTask.js.map +0 -1
  482. package/build/dist/Models/DatabaseModels/AIAgentTaskLog.js +0 -447
  483. package/build/dist/Models/DatabaseModels/AIAgentTaskLog.js.map +0 -1
  484. package/build/dist/Models/DatabaseModels/AIAgentTaskTelemetryException.js +0 -415
  485. package/build/dist/Models/DatabaseModels/AIAgentTaskTelemetryException.js.map +0 -1
  486. package/build/dist/Models/DatabaseModels/ServiceCodeRepository.js +0 -665
  487. package/build/dist/Models/DatabaseModels/ServiceCodeRepository.js.map +0 -1
  488. package/build/dist/Server/Services/AIAgentTaskLogService.js.map +0 -1
  489. package/build/dist/Server/Services/AIAgentTaskService.js +0 -217
  490. package/build/dist/Server/Services/AIAgentTaskService.js.map +0 -1
  491. package/build/dist/Server/Services/AIAgentTaskTelemetryExceptionService.js +0 -36
  492. package/build/dist/Server/Services/AIAgentTaskTelemetryExceptionService.js.map +0 -1
  493. package/build/dist/Server/Services/ServiceCodeRepositoryService.js +0 -54
  494. package/build/dist/Server/Services/ServiceCodeRepositoryService.js.map +0 -1
  495. package/build/dist/Server/Utils/AI/Sentinel/AlertInvestigationRunner.js.map +0 -1
  496. package/build/dist/Server/Utils/AI/Sentinel/IncidentInvestigationRunner.js.map +0 -1
  497. package/build/dist/Server/Utils/AI/Sentinel/IncidentPostmortemRunner.js.map +0 -1
  498. package/build/dist/Server/Utils/AI/Sentinel/InvestigationQueue.js.map +0 -1
  499. package/build/dist/Server/Utils/AI/Sentinel/SentinelInvestigationEngine.js.map +0 -1
  500. package/build/dist/Server/Utils/AI/Sentinel/SentinelMemory.js.map +0 -1
  501. package/build/dist/Server/Utils/AI/Toolbox/SentinelActionTools.js.map +0 -1
  502. package/build/dist/Types/AI/AIAgentTaskMetadata.js +0 -6
  503. package/build/dist/Types/AI/AIAgentTaskMetadata.js.map +0 -1
  504. package/build/dist/Types/AI/AIAgentTaskType.js +0 -29
  505. package/build/dist/Types/AI/AIAgentTaskType.js.map +0 -1
@@ -0,0 +1,274 @@
1
+ import FixPerformanceTaskTrigger from "../../../Server/Utils/AI/SRE/FixPerformanceTaskTrigger";
2
+ import FixRunBudget from "../../../Server/Utils/AI/CodeFix/FixRunBudget";
3
+ import { AnalyzableSpan } from "../../../Server/Utils/AI/PerfEvidence/SpanTreeAnalyzer";
4
+ import CodeRepositoryService from "../../../Server/Services/CodeRepositoryService";
5
+ import AIRunService from "../../../Server/Services/AIRunService";
6
+ import AIRun from "../../../Models/DatabaseModels/AIRun";
7
+ import AIRunType from "../../../Types/AI/AIRunType";
8
+ import AIRunStatus from "../../../Types/AI/AIRunStatus";
9
+ import CodeFixTaskType from "../../../Types/AI/CodeFixTaskType";
10
+ import CodeFixTaskContext from "../../../Types/AI/CodeFixTaskContext";
11
+ import BadDataException from "../../../Types/Exception/BadDataException";
12
+ import ObjectID from "../../../Types/ObjectID";
13
+ import PositiveNumber from "../../../Types/PositiveNumber";
14
+ import { describe, expect, test, afterEach, beforeEach } from "@jest/globals";
15
+
16
+ /*
17
+ * The FixPerformance trigger: the user clicks "Fix performance with AI" on
18
+ * the trace view, the SpanTreeAnalyzer must find a deterministic pattern in
19
+ * the trace's spans (the recipe's honesty gate — no finding, no task), a
20
+ * GitHub-App repository must exist for the PR, and at most one non-terminal
21
+ * FixPerformance run may exist per trace. Human-triggered, so no project
22
+ * opt-in flag; runs inside a user-facing endpoint, so every unmet gate must
23
+ * THROW a clear message, not swallow.
24
+ */
25
+
26
+ const projectId: ObjectID = ObjectID.generate();
27
+ const traceId: string = "abc123trace";
28
+ const userId: ObjectID = ObjectID.generate();
29
+
30
+ function fakeRun(taskContext?: CodeFixTaskContext): AIRun {
31
+ return {
32
+ id: ObjectID.generate(),
33
+ taskContext,
34
+ } as unknown as AIRun;
35
+ }
36
+
37
+ // A trace with a textbook N+1: root + 5 near-identical children.
38
+ function spansWithNPlusOne(): Array<AnalyzableSpan> {
39
+ const spans: Array<AnalyzableSpan> = [
40
+ {
41
+ spanId: "root",
42
+ name: "GET /orders",
43
+ startMs: 0,
44
+ endMs: 1000,
45
+ },
46
+ ];
47
+ for (let i: number = 0; i < 5; i++) {
48
+ spans.push({
49
+ spanId: `child-${i}`,
50
+ parentSpanId: "root",
51
+ name: `SELECT users ${i}`,
52
+ startMs: i * 100,
53
+ endMs: i * 100 + 100,
54
+ attributes: {
55
+ "db.statement": `SELECT * FROM users WHERE id = ${i}`,
56
+ "code.filepath": "src/orders/loader.ts",
57
+ "code.function": "loadUserForOrder",
58
+ "code.lineno": "42",
59
+ },
60
+ });
61
+ }
62
+ return spans;
63
+ }
64
+
65
+ // A healthy trace: no detector can fire.
66
+ function healthySpans(): Array<AnalyzableSpan> {
67
+ return [
68
+ { spanId: "root", name: "GET /home", startMs: 0, endMs: 1000 },
69
+ { spanId: "a", parentSpanId: "root", name: "auth", startMs: 0, endMs: 500 },
70
+ {
71
+ spanId: "b",
72
+ parentSpanId: "root",
73
+ name: "render",
74
+ startMs: 500,
75
+ endMs: 1000,
76
+ },
77
+ ];
78
+ }
79
+
80
+ describe("FixPerformanceTaskTrigger.createPerformanceFixTaskFromTrace", () => {
81
+ beforeEach(() => {
82
+ // The daily fix-run budget has its own suite (FixRunBudget.test.ts).
83
+ jest.spyOn(FixRunBudget, "assertWithinBudget").mockResolvedValue();
84
+ });
85
+
86
+ afterEach(() => {
87
+ jest.restoreAllMocks();
88
+ });
89
+
90
+ test("a traceId-less call is rejected before any query", async () => {
91
+ const countBy: jest.SpyInstance = jest.spyOn(
92
+ CodeRepositoryService,
93
+ "countBy",
94
+ );
95
+
96
+ await expect(
97
+ FixPerformanceTaskTrigger.createPerformanceFixTaskFromTrace({
98
+ projectId,
99
+ traceId: "",
100
+ spans: spansWithNPlusOne(),
101
+ userId,
102
+ }),
103
+ ).rejects.toThrow(BadDataException);
104
+
105
+ expect(countBy).not.toHaveBeenCalled();
106
+ });
107
+
108
+ test("a span-less trace is rejected before any query", async () => {
109
+ const countBy: jest.SpyInstance = jest.spyOn(
110
+ CodeRepositoryService,
111
+ "countBy",
112
+ );
113
+
114
+ await expect(
115
+ FixPerformanceTaskTrigger.createPerformanceFixTaskFromTrace({
116
+ projectId,
117
+ traceId,
118
+ spans: [],
119
+ userId,
120
+ }),
121
+ ).rejects.toThrow(/no spans/);
122
+
123
+ expect(countBy).not.toHaveBeenCalled();
124
+ });
125
+
126
+ test("no deterministic finding → reject with a clear message, nothing queried or enqueued", async () => {
127
+ const countBy: jest.SpyInstance = jest.spyOn(
128
+ CodeRepositoryService,
129
+ "countBy",
130
+ );
131
+ const create: jest.SpyInstance = jest.spyOn(AIRunService, "create");
132
+
133
+ await expect(
134
+ FixPerformanceTaskTrigger.createPerformanceFixTaskFromTrace({
135
+ projectId,
136
+ traceId,
137
+ spans: healthySpans(),
138
+ userId,
139
+ }),
140
+ ).rejects.toThrow(/No deterministic performance pattern/);
141
+
142
+ expect(countBy).not.toHaveBeenCalled();
143
+ expect(create).not.toHaveBeenCalled();
144
+ });
145
+
146
+ test("no GitHub-App repository → reject, nothing enqueued", async () => {
147
+ jest
148
+ .spyOn(CodeRepositoryService, "countBy")
149
+ .mockResolvedValue(new PositiveNumber(0));
150
+ const create: jest.SpyInstance = jest.spyOn(AIRunService, "create");
151
+
152
+ await expect(
153
+ FixPerformanceTaskTrigger.createPerformanceFixTaskFromTrace({
154
+ projectId,
155
+ traceId,
156
+ spans: spansWithNPlusOne(),
157
+ userId,
158
+ }),
159
+ ).rejects.toThrow(/GitHub/);
160
+
161
+ expect(create).not.toHaveBeenCalled();
162
+ });
163
+
164
+ test("dedupe: a live FixPerformance run for the SAME trace blocks a second one", async () => {
165
+ jest
166
+ .spyOn(CodeRepositoryService, "countBy")
167
+ .mockResolvedValue(new PositiveNumber(1));
168
+ const findBy: jest.SpyInstance = jest
169
+ .spyOn(AIRunService, "findBy")
170
+ .mockResolvedValue([fakeRun({ traceId })]);
171
+ const create: jest.SpyInstance = jest.spyOn(AIRunService, "create");
172
+
173
+ await expect(
174
+ FixPerformanceTaskTrigger.createPerformanceFixTaskFromTrace({
175
+ projectId,
176
+ traceId,
177
+ spans: spansWithNPlusOne(),
178
+ userId,
179
+ }),
180
+ ).rejects.toThrow(/already queued or running/);
181
+
182
+ // The dedupe scan is scoped to non-terminal FixPerformance runs.
183
+ expect(findBy).toHaveBeenCalledWith(
184
+ expect.objectContaining({
185
+ query: expect.objectContaining({
186
+ projectId: projectId,
187
+ runType: AIRunType.CodeFix,
188
+ codeFixTaskType: CodeFixTaskType.FixPerformance,
189
+ }),
190
+ }),
191
+ );
192
+ expect(create).not.toHaveBeenCalled();
193
+ });
194
+
195
+ test("dedupe is per-trace: a live run for a DIFFERENT trace does not block", async () => {
196
+ jest
197
+ .spyOn(CodeRepositoryService, "countBy")
198
+ .mockResolvedValue(new PositiveNumber(1));
199
+ jest
200
+ .spyOn(AIRunService, "findBy")
201
+ .mockResolvedValue([fakeRun({ traceId: "some-other-trace" })]);
202
+ const create: jest.SpyInstance = jest
203
+ .spyOn(AIRunService, "create")
204
+ .mockResolvedValue(fakeRun());
205
+
206
+ await FixPerformanceTaskTrigger.createPerformanceFixTaskFromTrace({
207
+ projectId,
208
+ traceId,
209
+ spans: spansWithNPlusOne(),
210
+ userId,
211
+ });
212
+
213
+ expect(create).toHaveBeenCalledTimes(1);
214
+ });
215
+
216
+ test("happy path: enqueues a Queued FixPerformance run whose taskContext carries the evidence", async () => {
217
+ jest
218
+ .spyOn(CodeRepositoryService, "countBy")
219
+ .mockResolvedValue(new PositiveNumber(1));
220
+ jest.spyOn(AIRunService, "findBy").mockResolvedValue([]);
221
+ const createdRun: AIRun = fakeRun();
222
+ const create: jest.SpyInstance = jest
223
+ .spyOn(AIRunService, "create")
224
+ .mockResolvedValue(createdRun);
225
+
226
+ const run: AIRun =
227
+ await FixPerformanceTaskTrigger.createPerformanceFixTaskFromTrace({
228
+ projectId,
229
+ traceId,
230
+ spans: spansWithNPlusOne(),
231
+ serviceName: "orders-service",
232
+ userId,
233
+ });
234
+
235
+ expect(run).toBe(createdRun);
236
+
237
+ expect(create).toHaveBeenCalledWith(
238
+ expect.objectContaining({
239
+ data: expect.objectContaining({
240
+ projectId: projectId,
241
+ runType: AIRunType.CodeFix,
242
+ codeFixTaskType: CodeFixTaskType.FixPerformance,
243
+ status: AIRunStatus.Queued,
244
+ // Attribution: the user who clicked the button.
245
+ userId: userId,
246
+ // No subject row — the evidence IS the context.
247
+ triggeredByIncidentId: undefined,
248
+ triggeredByAlertId: undefined,
249
+ taskContext: expect.objectContaining({
250
+ traceId: traceId,
251
+ serviceName: "orders-service",
252
+ }),
253
+ }),
254
+ props: expect.objectContaining({ isRoot: true }),
255
+ }),
256
+ );
257
+
258
+ // The stored findings are the deterministic N+1 evidence.
259
+ const storedContext: CodeFixTaskContext = (
260
+ create.mock.calls[0]![0] as { data: AIRun }
261
+ ).data.taskContext!;
262
+ expect(storedContext.performanceFindings).toHaveLength(1);
263
+ expect(storedContext.performanceFindings![0]!.spanCount).toBe(5);
264
+
265
+ // code.* attributes of implicated spans become resolver locations.
266
+ expect(storedContext.codeLocations).toEqual([
267
+ {
268
+ filePath: "src/orders/loader.ts",
269
+ functionName: "loadUserForOrder",
270
+ lineNumber: 42,
271
+ },
272
+ ]);
273
+ });
274
+ });
@@ -0,0 +1,80 @@
1
+ import GlobalConfig from "../../../Models/DatabaseModels/GlobalConfig";
2
+ import GlobalConfigService from "../../../Server/Services/GlobalConfigService";
3
+ import { OnUpdate } from "../../../Server/Types/Database/Hooks";
4
+ import UpdateBy from "../../../Server/Types/Database/UpdateBy";
5
+ import logger from "../../../Server/Utils/Logger";
6
+ import BadDataException from "../../../Types/Exception/BadDataException";
7
+ import { afterEach, beforeEach, describe, expect, test } from "@jest/globals";
8
+
9
+ type GlobalConfigServiceWithUpdateHook = {
10
+ onBeforeUpdate(
11
+ updateBy: UpdateBy<GlobalConfig>,
12
+ ): Promise<OnUpdate<GlobalConfig>>;
13
+ };
14
+
15
+ function makeUpdateBy(data: Record<string, unknown>): UpdateBy<GlobalConfig> {
16
+ return {
17
+ query: {},
18
+ data,
19
+ limit: 1,
20
+ skip: 0,
21
+ props: {
22
+ isRoot: true,
23
+ },
24
+ } as unknown as UpdateBy<GlobalConfig>;
25
+ }
26
+
27
+ describe("GlobalConfigService ClickHouse capacity settings", () => {
28
+ beforeEach(() => {
29
+ jest.spyOn(logger, "error").mockImplementation((): void => {
30
+ return undefined;
31
+ });
32
+ });
33
+
34
+ afterEach(() => {
35
+ jest.restoreAllMocks();
36
+ });
37
+
38
+ test("normalizes integer form strings before persisting", async () => {
39
+ jest.spyOn(GlobalConfigService, "findOneBy").mockResolvedValue({
40
+ clickhouseCapacityNotificationThresholdPercent: 80,
41
+ clickhouseDataPruningThresholdPercent: 90,
42
+ clickhouseDataPruningTargetPercent: 80,
43
+ } as GlobalConfig);
44
+
45
+ const result: OnUpdate<GlobalConfig> = await (
46
+ GlobalConfigService as unknown as GlobalConfigServiceWithUpdateHook
47
+ ).onBeforeUpdate(
48
+ makeUpdateBy({
49
+ clickhouseCapacityNotificationThresholdPercent: "85",
50
+ clickhouseDataPruningThresholdPercent: "95",
51
+ clickhouseDataPruningTargetPercent: "75",
52
+ }),
53
+ );
54
+
55
+ expect(
56
+ result.updateBy.data.clickhouseCapacityNotificationThresholdPercent,
57
+ ).toBe(85);
58
+ expect(result.updateBy.data.clickhouseDataPruningThresholdPercent).toBe(95);
59
+ expect(result.updateBy.data.clickhouseDataPruningTargetPercent).toBe(75);
60
+ });
61
+
62
+ test("rejects a normalized target that is not below the trigger", async () => {
63
+ jest.spyOn(GlobalConfigService, "findOneBy").mockResolvedValue({
64
+ clickhouseCapacityNotificationThresholdPercent: 80,
65
+ clickhouseDataPruningThresholdPercent: 90,
66
+ clickhouseDataPruningTargetPercent: 80,
67
+ } as GlobalConfig);
68
+
69
+ await expect(
70
+ (
71
+ GlobalConfigService as unknown as GlobalConfigServiceWithUpdateHook
72
+ ).onBeforeUpdate(
73
+ makeUpdateBy({
74
+ clickhouseDataPruningThresholdPercent: "85",
75
+ clickhouseDataPruningTargetPercent: "85",
76
+ }),
77
+ ),
78
+ ).rejects.toThrow(BadDataException);
79
+ });
80
+ });
@@ -14,7 +14,7 @@ import { describe, expect, test, afterEach } from "@jest/globals";
14
14
  * and Slack/Teams ping (it sets isOwnerNotified itself, so the hook is its
15
15
  * only push channel).
16
16
  *
17
- * Callers that must NOT announce (Sentinel's RCA note, which has its own
17
+ * Callers that must NOT announce (the AI's RCA note, which has its own
18
18
  * quiet-mode-gated RootCause feed item) opt out explicitly with
19
19
  * props.ignoreHooks — see IncidentInvestigationRunner. These tests lock in
20
20
  * that the hook announces for both user-authored and user-less notes, so the
@@ -0,0 +1,313 @@
1
+ import InstrumentationTaskTrigger from "../../../Server/Utils/AI/SRE/InstrumentationTaskTrigger";
2
+ import FixRunBudget from "../../../Server/Utils/AI/CodeFix/FixRunBudget";
3
+ import ProjectService from "../../../Server/Services/ProjectService";
4
+ import CodeRepositoryService from "../../../Server/Services/CodeRepositoryService";
5
+ import AIRunService from "../../../Server/Services/AIRunService";
6
+ import Project from "../../../Models/DatabaseModels/Project";
7
+ import AIRun from "../../../Models/DatabaseModels/AIRun";
8
+ import AIRunType from "../../../Types/AI/AIRunType";
9
+ import AIRunStatus from "../../../Types/AI/AIRunStatus";
10
+ import CodeFixTaskType from "../../../Types/AI/CodeFixTaskType";
11
+ import ObjectID from "../../../Types/ObjectID";
12
+ import PositiveNumber from "../../../Types/PositiveNumber";
13
+ import { describe, expect, test, afterEach, beforeEach } from "@jest/globals";
14
+
15
+ /*
16
+ * The ImproveInstrumentation trigger: an INCONCLUSIVE AI investigation
17
+ * enqueues a CodeFix AIRun that opens an instrumentation PR — but ONLY for
18
+ * projects that explicitly opted in (enableInstrumentationFixTasks, default
19
+ * FALSE — G11 posture), only when a GitHub-App repo exists to open the PR
20
+ * against, and at most one non-terminal run per incident/alert. The trigger
21
+ * runs inside postAnalysis, so it must NEVER throw.
22
+ */
23
+
24
+ const projectId: ObjectID = ObjectID.generate();
25
+ const incidentId: ObjectID = ObjectID.generate();
26
+ const alertId: ObjectID = ObjectID.generate();
27
+
28
+ function fakeProject(data?: {
29
+ enableAi?: boolean;
30
+ enableInstrumentationFixTasks?: boolean;
31
+ }): Project {
32
+ return {
33
+ id: projectId,
34
+ enableAi: data?.enableAi ?? true,
35
+ enableInstrumentationFixTasks: data?.enableInstrumentationFixTasks ?? true,
36
+ } as unknown as Project;
37
+ }
38
+
39
+ describe("InstrumentationTaskTrigger.shouldEnqueueInstrumentationTask", () => {
40
+ test("does not enqueue when the project is missing", () => {
41
+ expect(
42
+ InstrumentationTaskTrigger.shouldEnqueueInstrumentationTask({
43
+ project: null,
44
+ hasConnectedRepository: true,
45
+ existingRun: null,
46
+ }).enqueue,
47
+ ).toBe(false);
48
+ });
49
+
50
+ test("does not enqueue when AI is disabled for the project", () => {
51
+ expect(
52
+ InstrumentationTaskTrigger.shouldEnqueueInstrumentationTask({
53
+ project: fakeProject({ enableAi: false }),
54
+ hasConnectedRepository: true,
55
+ existingRun: null,
56
+ }).enqueue,
57
+ ).toBe(false);
58
+ });
59
+
60
+ test("opt-in is strict: an unset flag (legacy row) never enqueues — default is FALSE", () => {
61
+ const project: Project = {
62
+ id: projectId,
63
+ enableAi: true,
64
+ // enableInstrumentationFixTasks deliberately absent.
65
+ } as unknown as Project;
66
+
67
+ const decision: ReturnType<
68
+ typeof InstrumentationTaskTrigger.shouldEnqueueInstrumentationTask
69
+ > = InstrumentationTaskTrigger.shouldEnqueueInstrumentationTask({
70
+ project,
71
+ hasConnectedRepository: true,
72
+ existingRun: null,
73
+ });
74
+
75
+ expect(decision.enqueue).toBe(false);
76
+ expect(decision.reason).toMatch(/not opted in/);
77
+ });
78
+
79
+ test("does not enqueue without a GitHub-App-connected repository", () => {
80
+ const decision: ReturnType<
81
+ typeof InstrumentationTaskTrigger.shouldEnqueueInstrumentationTask
82
+ > = InstrumentationTaskTrigger.shouldEnqueueInstrumentationTask({
83
+ project: fakeProject(),
84
+ hasConnectedRepository: false,
85
+ existingRun: null,
86
+ });
87
+
88
+ expect(decision.enqueue).toBe(false);
89
+ expect(decision.reason).toMatch(/repository/);
90
+ });
91
+
92
+ test("dedupe: an existing non-terminal run for the subject blocks a second one", () => {
93
+ const decision: ReturnType<
94
+ typeof InstrumentationTaskTrigger.shouldEnqueueInstrumentationTask
95
+ > = InstrumentationTaskTrigger.shouldEnqueueInstrumentationTask({
96
+ project: fakeProject(),
97
+ hasConnectedRepository: true,
98
+ existingRun: { id: ObjectID.generate() } as unknown as AIRun,
99
+ });
100
+
101
+ expect(decision.enqueue).toBe(false);
102
+ expect(decision.reason).toMatch(/already exists/);
103
+ });
104
+
105
+ test("enqueues when opted in, a repository exists, and no run is live for the subject", () => {
106
+ expect(
107
+ InstrumentationTaskTrigger.shouldEnqueueInstrumentationTask({
108
+ project: fakeProject(),
109
+ hasConnectedRepository: true,
110
+ existingRun: null,
111
+ }).enqueue,
112
+ ).toBe(true);
113
+ });
114
+ });
115
+
116
+ describe("InstrumentationTaskTrigger.enqueueForInconclusiveInvestigation", () => {
117
+ beforeEach(() => {
118
+ /*
119
+ * The daily fix-run budget defaults to allowed; its own decision matrix
120
+ * lives in FixRunBudget.test.ts. Mocking getBudgetStatus covers both
121
+ * the trigger's pre-check and assertWithinBudget inside the enqueue.
122
+ */
123
+ jest.spyOn(FixRunBudget, "getBudgetStatus").mockResolvedValue({
124
+ allowed: true,
125
+ limit: 25,
126
+ paused: false,
127
+ runsToday: 0,
128
+ });
129
+ });
130
+
131
+ afterEach(() => {
132
+ jest.restoreAllMocks();
133
+ });
134
+
135
+ test("over the daily fix-run budget: a logged SKIP — no run created, nothing thrown into the investigation", async () => {
136
+ jest.spyOn(ProjectService, "findOneById").mockResolvedValue(fakeProject());
137
+ jest.spyOn(FixRunBudget, "getBudgetStatus").mockResolvedValue({
138
+ allowed: false,
139
+ limit: 25,
140
+ paused: false,
141
+ runsToday: 25,
142
+ });
143
+ const countBy: jest.SpyInstance = jest.spyOn(
144
+ CodeRepositoryService,
145
+ "countBy",
146
+ );
147
+ const create: jest.SpyInstance = jest.spyOn(AIRunService, "create");
148
+
149
+ await expect(
150
+ InstrumentationTaskTrigger.enqueueForInconclusiveInvestigation({
151
+ projectId,
152
+ incidentId,
153
+ }),
154
+ ).resolves.toBeUndefined();
155
+
156
+ // Skipped before the repo/dedupe queries, and no run was created.
157
+ expect(countBy).not.toHaveBeenCalled();
158
+ expect(create).not.toHaveBeenCalled();
159
+ });
160
+
161
+ test("a not-opted-in project skips cheaply: no repo count, no dedupe query, no run created", async () => {
162
+ jest
163
+ .spyOn(ProjectService, "findOneById")
164
+ .mockResolvedValue(fakeProject({ enableInstrumentationFixTasks: false }));
165
+ const countBy: jest.SpyInstance = jest.spyOn(
166
+ CodeRepositoryService,
167
+ "countBy",
168
+ );
169
+ const findOneBy: jest.SpyInstance = jest.spyOn(AIRunService, "findOneBy");
170
+ const create: jest.SpyInstance = jest.spyOn(AIRunService, "create");
171
+
172
+ await InstrumentationTaskTrigger.enqueueForInconclusiveInvestigation({
173
+ projectId,
174
+ incidentId,
175
+ });
176
+
177
+ expect(countBy).not.toHaveBeenCalled();
178
+ expect(findOneBy).not.toHaveBeenCalled();
179
+ expect(create).not.toHaveBeenCalled();
180
+ });
181
+
182
+ test("records a Queued ImproveInstrumentation CodeFix run carrying the incident subject", async () => {
183
+ jest.spyOn(ProjectService, "findOneById").mockResolvedValue(fakeProject());
184
+ jest
185
+ .spyOn(CodeRepositoryService, "countBy")
186
+ .mockResolvedValue(new PositiveNumber(1));
187
+ const findOneBy: jest.SpyInstance = jest
188
+ .spyOn(AIRunService, "findOneBy")
189
+ .mockResolvedValue(null);
190
+ const create: jest.SpyInstance = jest
191
+ .spyOn(AIRunService, "create")
192
+ .mockResolvedValue({ id: ObjectID.generate() } as unknown as AIRun);
193
+
194
+ await InstrumentationTaskTrigger.enqueueForInconclusiveInvestigation({
195
+ projectId,
196
+ incidentId,
197
+ });
198
+
199
+ // The dedupe guard queries per (subject, ImproveInstrumentation).
200
+ expect(findOneBy).toHaveBeenCalledWith(
201
+ expect.objectContaining({
202
+ query: expect.objectContaining({
203
+ runType: AIRunType.CodeFix,
204
+ codeFixTaskType: CodeFixTaskType.ImproveInstrumentation,
205
+ triggeredByIncidentId: incidentId,
206
+ }),
207
+ }),
208
+ );
209
+
210
+ expect(create).toHaveBeenCalledWith(
211
+ expect.objectContaining({
212
+ data: expect.objectContaining({
213
+ projectId: projectId,
214
+ runType: AIRunType.CodeFix,
215
+ codeFixTaskType: CodeFixTaskType.ImproveInstrumentation,
216
+ status: AIRunStatus.Queued,
217
+ triggeredByIncidentId: incidentId,
218
+ }),
219
+ props: expect.objectContaining({ isRoot: true }),
220
+ }),
221
+ );
222
+ });
223
+
224
+ test("an alert-subject investigation enqueues with triggeredByAlertId", async () => {
225
+ jest.spyOn(ProjectService, "findOneById").mockResolvedValue(fakeProject());
226
+ jest
227
+ .spyOn(CodeRepositoryService, "countBy")
228
+ .mockResolvedValue(new PositiveNumber(1));
229
+ jest.spyOn(AIRunService, "findOneBy").mockResolvedValue(null);
230
+ const create: jest.SpyInstance = jest
231
+ .spyOn(AIRunService, "create")
232
+ .mockResolvedValue({ id: ObjectID.generate() } as unknown as AIRun);
233
+
234
+ await InstrumentationTaskTrigger.enqueueForInconclusiveInvestigation({
235
+ projectId,
236
+ alertId,
237
+ });
238
+
239
+ expect(create).toHaveBeenCalledWith(
240
+ expect.objectContaining({
241
+ data: expect.objectContaining({
242
+ codeFixTaskType: CodeFixTaskType.ImproveInstrumentation,
243
+ triggeredByAlertId: alertId,
244
+ }),
245
+ }),
246
+ );
247
+ });
248
+
249
+ test("dedupe: a live ImproveInstrumentation run for the same subject blocks creation", async () => {
250
+ jest.spyOn(ProjectService, "findOneById").mockResolvedValue(fakeProject());
251
+ jest
252
+ .spyOn(CodeRepositoryService, "countBy")
253
+ .mockResolvedValue(new PositiveNumber(1));
254
+ jest
255
+ .spyOn(AIRunService, "findOneBy")
256
+ .mockResolvedValue({ id: ObjectID.generate() } as unknown as AIRun);
257
+ const create: jest.SpyInstance = jest.spyOn(AIRunService, "create");
258
+
259
+ await InstrumentationTaskTrigger.enqueueForInconclusiveInvestigation({
260
+ projectId,
261
+ incidentId,
262
+ });
263
+
264
+ expect(create).not.toHaveBeenCalled();
265
+ });
266
+
267
+ test("no GitHub-App repository means no run", async () => {
268
+ jest.spyOn(ProjectService, "findOneById").mockResolvedValue(fakeProject());
269
+ jest
270
+ .spyOn(CodeRepositoryService, "countBy")
271
+ .mockResolvedValue(new PositiveNumber(0));
272
+ jest.spyOn(AIRunService, "findOneBy").mockResolvedValue(null);
273
+ const create: jest.SpyInstance = jest.spyOn(AIRunService, "create");
274
+
275
+ await InstrumentationTaskTrigger.enqueueForInconclusiveInvestigation({
276
+ projectId,
277
+ incidentId,
278
+ });
279
+
280
+ expect(create).not.toHaveBeenCalled();
281
+ });
282
+
283
+ test("never throws — a failed enqueue must not fail the investigation's postAnalysis", async () => {
284
+ jest.spyOn(ProjectService, "findOneById").mockResolvedValue(fakeProject());
285
+ jest
286
+ .spyOn(CodeRepositoryService, "countBy")
287
+ .mockResolvedValue(new PositiveNumber(1));
288
+ jest.spyOn(AIRunService, "findOneBy").mockResolvedValue(null);
289
+ jest
290
+ .spyOn(AIRunService, "create")
291
+ .mockRejectedValue(new Error("database is down"));
292
+
293
+ await expect(
294
+ InstrumentationTaskTrigger.enqueueForInconclusiveInvestigation({
295
+ projectId,
296
+ incidentId,
297
+ }),
298
+ ).resolves.toBeUndefined();
299
+ });
300
+
301
+ test("a subjectless call is a no-op", async () => {
302
+ const findProject: jest.SpyInstance = jest.spyOn(
303
+ ProjectService,
304
+ "findOneById",
305
+ );
306
+
307
+ await InstrumentationTaskTrigger.enqueueForInconclusiveInvestigation({
308
+ projectId,
309
+ });
310
+
311
+ expect(findProject).not.toHaveBeenCalled();
312
+ });
313
+ });