@oneuptime/common 11.5.3 → 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 (513) 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/Dashboard.ts +3 -3
  6. package/Models/DatabaseModels/GlobalConfig.ts +105 -0
  7. package/Models/DatabaseModels/Index.ts +4 -8
  8. package/Models/DatabaseModels/InstanceHealthLog.ts +277 -0
  9. package/Models/DatabaseModels/LlmLog.ts +33 -0
  10. package/Models/DatabaseModels/Project.ts +123 -6
  11. package/Models/DatabaseModels/Runbook.ts +1 -1
  12. package/Server/API/AIAgentDataAPI.ts +802 -140
  13. package/Server/API/AIAgentTaskAPI.ts +132 -69
  14. package/Server/API/AIAgentTaskLogAPI.ts +65 -41
  15. package/Server/API/AIAgentTaskPullRequestAPI.ts +41 -0
  16. package/Server/API/AIInsightAPI.ts +220 -0
  17. package/Server/API/AIInvestigationAPI.ts +363 -1
  18. package/Server/API/CodeFixRunAPI.ts +251 -0
  19. package/Server/API/GitHubAPI.ts +246 -3
  20. package/Server/API/TelemetryExceptionAPI.ts +193 -48
  21. package/Server/EnvironmentConfig.ts +1 -1
  22. package/Server/Infrastructure/Postgres/SchemaMigrations/1783943300000-DropServiceCodeRepository.ts +26 -0
  23. package/Server/Infrastructure/Postgres/SchemaMigrations/1783947444597-CodeFixRunsOnAIRun.ts +73 -0
  24. package/Server/Infrastructure/Postgres/SchemaMigrations/1783950962813-AddCodeFixTaskType.ts +29 -0
  25. package/Server/Infrastructure/Postgres/SchemaMigrations/1783954040984-AddInstrumentationFixTasksFlag.ts +31 -0
  26. package/Server/Infrastructure/Postgres/SchemaMigrations/1783957160597-MigrationName.ts +51 -0
  27. package/Server/Infrastructure/Postgres/SchemaMigrations/1783958542237-AddTaskContextToAIRun.ts +25 -0
  28. package/Server/Infrastructure/Postgres/SchemaMigrations/1783965945957-AddInvestigationVerdictAndGrade.ts +47 -0
  29. package/Server/Infrastructure/Postgres/SchemaMigrations/1783970619301-AddFixGuardrailColumns.ts +53 -0
  30. package/Server/Infrastructure/Postgres/SchemaMigrations/1783970619302-DropLegacyAIAgentTaskTables.ts +31 -0
  31. package/Server/Infrastructure/Postgres/SchemaMigrations/1783977781677-AddCiStatusToFixPullRequests.ts +37 -0
  32. package/Server/Infrastructure/Postgres/SchemaMigrations/1783990000000-AddCompletionTokensToLlmLog.ts +25 -0
  33. package/Server/Infrastructure/Postgres/SchemaMigrations/1784010274993-AddSentinelInsight.ts +75 -0
  34. package/Server/Infrastructure/Postgres/SchemaMigrations/1784010274994-AddSentinelInsightFlags.ts +37 -0
  35. package/Server/Infrastructure/Postgres/SchemaMigrations/1784030612266-RenameSentinelToAI.ts +203 -0
  36. package/Server/Infrastructure/Postgres/SchemaMigrations/1784033837629-MigrationName.ts +163 -0
  37. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +30 -0
  38. package/Server/Infrastructure/Queue.ts +82 -4
  39. package/Server/Infrastructure/Semaphore.ts +62 -1
  40. package/Server/Services/AIAgentService.ts +32 -0
  41. package/Server/Services/AIAgentTaskPullRequestService.ts +117 -0
  42. package/Server/Services/AIInsightService.ts +174 -0
  43. package/Server/Services/AIRunEventService.ts +63 -0
  44. package/Server/Services/AIRunService.ts +259 -1
  45. package/Server/Services/AIService.ts +249 -7
  46. package/Server/Services/AlertService.ts +4 -4
  47. package/Server/Services/CodeRepositoryService.ts +209 -0
  48. package/Server/Services/DashboardService.ts +11 -2
  49. package/Server/Services/GlobalConfigService.ts +148 -0
  50. package/Server/Services/IncidentService.ts +183 -38
  51. package/Server/Services/IncidentStateTimelineService.ts +24 -4
  52. package/Server/Services/Index.ts +4 -4
  53. package/Server/Services/{AIAgentTaskLogService.ts → InstanceHealthLogService.ts} +1 -1
  54. package/Server/Services/LlmLogService.ts +27 -0
  55. package/Server/Services/LlmProviderService.ts +108 -0
  56. package/Server/Services/MetricBaselineService.ts +123 -0
  57. package/Server/Services/MonitorService.ts +15 -0
  58. package/Server/Services/TelemetryExceptionService.ts +323 -116
  59. package/Server/Services/TraceAggregationService.ts +176 -0
  60. package/Server/Types/Workflow/ComponentCode.ts +6 -0
  61. package/Server/Types/Workflow/Components/AI/GenerateText.ts +326 -0
  62. package/Server/Types/Workflow/Components/Index.ts +2 -0
  63. package/Server/Utils/AI/Chat/ObservabilityAssistant.ts +1 -1
  64. package/Server/Utils/AI/CodeFix/CodeAgentWorkspaceGuard.ts +71 -0
  65. package/Server/Utils/AI/CodeFix/CodeFixAgentCompletion.ts +243 -0
  66. package/Server/Utils/AI/CodeFix/CodeFixRunQueue.ts +131 -0
  67. package/Server/Utils/AI/CodeFix/FixRunBudget.ts +148 -0
  68. package/Server/Utils/AI/CodeFix/OpenPullRequestCap.ts +117 -0
  69. package/Server/Utils/AI/Eval/EvalCorpus.ts +369 -0
  70. package/Server/Utils/AI/Eval/EvalScores.ts +172 -0
  71. package/Server/Utils/AI/Eval/ReplayInvestigation.ts +87 -0
  72. package/Server/Utils/AI/PerfEvidence/SpanTreeAnalyzer.ts +676 -0
  73. package/Server/Utils/AI/{Sentinel/SentinelInvestigationEngine.ts → SRE/AIInvestigationEngine.ts} +58 -37
  74. package/Server/Utils/AI/{Sentinel/SentinelMemory.ts → SRE/AIMemory.ts} +3 -3
  75. package/Server/Utils/AI/{Sentinel → SRE}/AlertInvestigationRunner.ts +50 -20
  76. package/Server/Utils/AI/SRE/ConfidenceSignal.ts +293 -0
  77. package/Server/Utils/AI/SRE/FixFromIncidentTaskTrigger.ts +115 -0
  78. package/Server/Utils/AI/SRE/FixPerformanceTaskTrigger.ts +223 -0
  79. package/Server/Utils/AI/{Sentinel → SRE}/IncidentInvestigationRunner.ts +71 -21
  80. package/Server/Utils/AI/{Sentinel → SRE}/IncidentPostmortemRunner.ts +8 -8
  81. package/Server/Utils/AI/SRE/Insights/Detectors/ErrorLogSpikeDetector.ts +364 -0
  82. package/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.ts +317 -0
  83. package/Server/Utils/AI/SRE/Insights/Detectors/Index.ts +27 -0
  84. package/Server/Utils/AI/SRE/Insights/Detectors/MetricDriftDetector.ts +221 -0
  85. package/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.ts +238 -0
  86. package/Server/Utils/AI/SRE/Insights/Detectors/TraceLatencyRegressionDetector.ts +521 -0
  87. package/Server/Utils/AI/SRE/Insights/FixRouting.ts +242 -0
  88. package/Server/Utils/AI/SRE/Insights/InsightScanner.ts +290 -0
  89. package/Server/Utils/AI/SRE/Insights/InsightStore.ts +283 -0
  90. package/Server/Utils/AI/SRE/Insights/InsightTriageRunner.ts +242 -0
  91. package/Server/Utils/AI/SRE/Insights/Triage.ts +162 -0
  92. package/Server/Utils/AI/SRE/Insights/Types.ts +49 -0
  93. package/Server/Utils/AI/SRE/InstrumentationTaskTrigger.ts +212 -0
  94. package/Server/Utils/AI/SRE/InvestigationGrader.ts +282 -0
  95. package/Server/Utils/AI/{Sentinel → SRE}/InvestigationQueue.ts +114 -19
  96. package/Server/Utils/AI/{Sentinel → SRE}/README.md +4 -4
  97. package/Server/Utils/AI/SRE/SubjectCodeFixRun.ts +172 -0
  98. package/Server/Utils/AI/Toolbox/{SentinelActionTools.ts → AIActionTools.ts} +22 -1
  99. package/Server/Utils/AI/Toolbox/Index.ts +2 -2
  100. package/Server/Utils/AnalyticsDatabase/ClickhouseCapacity.ts +526 -0
  101. package/Server/Utils/CodeRepository/GitHub/GitHub.ts +319 -1
  102. package/Server/Utils/CodeRepository/ServiceRepoLinkSuggester.ts +221 -0
  103. package/Server/Utils/CodeRepository/StackTraceRepoResolver.ts +571 -0
  104. package/Server/Utils/Execute.ts +34 -13
  105. package/Server/Utils/LLM/LLMService.ts +160 -30
  106. package/Server/Utils/Monitor/Criteria/SqlMonitorCriteria.ts +152 -0
  107. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +29 -0
  108. package/Tests/Server/API/DashboardMasterPasswordAPI.test.ts +225 -0
  109. package/Tests/Server/Infrastructure/Queue.test.ts +227 -0
  110. package/Tests/Server/Infrastructure/SemaphorePermit.test.ts +159 -0
  111. package/Tests/Server/Services/AIAgentTaskPullRequestOutcomeStats.test.ts +154 -0
  112. package/Tests/Server/Services/AIInsightService.test.ts +324 -0
  113. package/Tests/Server/Services/AIRunCodeFixClaim.test.ts +401 -0
  114. package/Tests/Server/Services/AIRunHumanVerdict.test.ts +161 -0
  115. package/Tests/Server/Services/AIServiceDailyBudget.test.ts +95 -5
  116. package/Tests/Server/Services/AIServiceProjectAccess.test.ts +259 -0
  117. package/Tests/Server/Services/FixFromIncidentTaskTrigger.test.ts +249 -0
  118. package/Tests/Server/Services/FixPerformanceTaskTrigger.test.ts +274 -0
  119. package/Tests/Server/Services/GlobalConfigService.test.ts +80 -0
  120. package/Tests/Server/Services/IncidentInternalNoteAnnouncement.test.ts +1 -1
  121. package/Tests/Server/Services/InstrumentationTaskTrigger.test.ts +313 -0
  122. package/Tests/Server/Services/LlmProviderProjectOwned.test.ts +132 -0
  123. package/Tests/Server/Services/TelemetryExceptionAIFixReadiness.test.ts +405 -0
  124. package/Tests/Server/Services/TelemetryExceptionCodeFixRun.test.ts +322 -0
  125. package/Tests/Server/Services/TraceServiceLatencyProfile.test.ts +278 -0
  126. package/Tests/Server/Types/Workflow/Components/AIGenerateText.test.ts +722 -0
  127. package/Tests/Server/Utils/AI/{SentinelAlertGating.test.ts → AIAlertGating.test.ts} +19 -19
  128. package/Tests/Server/Utils/AI/AIConfidenceSignal.test.ts +362 -0
  129. package/Tests/Server/Utils/AI/{SentinelInvestigationQueue.test.ts → AIInvestigationQueue.test.ts} +19 -19
  130. package/Tests/Server/Utils/AI/CodeAgentWorkspaceGuard.test.ts +138 -0
  131. package/Tests/Server/Utils/AI/CodeFixAgentCompletion.test.ts +335 -0
  132. package/Tests/Server/Utils/AI/CodeFixRunQueue.test.ts +134 -0
  133. package/Tests/Server/Utils/AI/EvalCorpus.test.ts +209 -0
  134. package/Tests/Server/Utils/AI/EvalScores.test.ts +343 -0
  135. package/Tests/Server/Utils/AI/FixRunBudget.test.ts +218 -0
  136. package/Tests/Server/Utils/AI/Insights/ErrorLogSpikeDetector.test.ts +437 -0
  137. package/Tests/Server/Utils/AI/Insights/ExceptionSpikeDetector.test.ts +287 -0
  138. package/Tests/Server/Utils/AI/Insights/InsightDetectorsIndex.test.ts +34 -0
  139. package/Tests/Server/Utils/AI/Insights/InsightFixRouting.test.ts +572 -0
  140. package/Tests/Server/Utils/AI/Insights/InsightNeverThrowsHardening.test.ts +344 -0
  141. package/Tests/Server/Utils/AI/Insights/InsightScanner.test.ts +720 -0
  142. package/Tests/Server/Utils/AI/Insights/InsightStore.test.ts +467 -0
  143. package/Tests/Server/Utils/AI/Insights/InsightStoreHardening.test.ts +370 -0
  144. package/Tests/Server/Utils/AI/Insights/InsightTriage.test.ts +210 -0
  145. package/Tests/Server/Utils/AI/Insights/InsightTriageRunner.test.ts +221 -0
  146. package/Tests/Server/Utils/AI/Insights/InvestigationQueueInsightSubject.test.ts +328 -0
  147. package/Tests/Server/Utils/AI/Insights/MetricBaselineDrift.test.ts +182 -0
  148. package/Tests/Server/Utils/AI/Insights/MetricDriftDetector.test.ts +280 -0
  149. package/Tests/Server/Utils/AI/Insights/NewExceptionDetector.test.ts +259 -0
  150. package/Tests/Server/Utils/AI/Insights/TraceLatencyRegressionDetector.test.ts +770 -0
  151. package/Tests/Server/Utils/AI/InvestigationGrader.test.ts +343 -0
  152. package/Tests/Server/Utils/AI/LLMServiceRequestPolicy.test.ts +307 -0
  153. package/Tests/Server/Utils/AI/OpenPullRequestCap.test.ts +170 -0
  154. package/Tests/Server/Utils/AI/SpanTreeAnalyzer.test.ts +559 -0
  155. package/Tests/Server/Utils/AnalyticsDatabase/ClickhouseCapacity.test.ts +158 -0
  156. package/Tests/Server/Utils/GitHubCheckRunsConclusion.test.ts +100 -0
  157. package/Tests/Server/Utils/GitHubPullRequestStateMapping.test.ts +50 -0
  158. package/Tests/Server/Utils/Monitor/Criteria/SqlMonitorCriteria.test.ts +266 -0
  159. package/Tests/Server/Utils/ServiceRepoLinkSuggester.test.ts +167 -0
  160. package/Tests/Server/Utils/StackTraceRepoResolver.test.ts +527 -0
  161. package/Tests/Types/AI/AIChatPermissionMode.test.ts +112 -0
  162. package/Tests/Types/AI/CodeFixTaskType.test.ts +152 -0
  163. package/Tests/Types/AI/FixPullRequestCiStatus.test.ts +181 -0
  164. package/Tests/Types/Monitor/MonitorStepSqlMonitor.test.ts +110 -0
  165. package/Tests/Types/Monitor/SqlDatabaseType.test.ts +55 -0
  166. package/Tests/Types/Workflow/AIGenerateTextMetadata.test.ts +180 -0
  167. package/Tests/UI/Components/TableBulkCsvExport.test.tsx +168 -0
  168. package/Tests/UI/Utils/TableColumnsToCsv.test.ts +523 -0
  169. package/Types/AI/AIChatTypes.ts +8 -0
  170. package/Types/AI/AIInsightEvidence.ts +77 -0
  171. package/Types/AI/AIInsightHumanVerdict.ts +15 -0
  172. package/Types/AI/AIInsightSeverity.ts +13 -0
  173. package/Types/AI/AIInsightStatus.ts +38 -0
  174. package/Types/AI/AIInsightType.ts +41 -0
  175. package/Types/AI/AIRunAutoGrade.ts +18 -0
  176. package/Types/AI/AIRunEventType.ts +5 -0
  177. package/Types/AI/AIRunHumanVerdict.ts +17 -0
  178. package/Types/AI/AIRunType.ts +6 -0
  179. package/Types/AI/CodeFixTaskContext.ts +88 -0
  180. package/Types/AI/CodeFixTaskType.ts +132 -0
  181. package/Types/AI/FixPullRequestCiStatus.ts +132 -0
  182. package/Types/BaseDatabase/AggregationIntervalUtil.ts +67 -0
  183. package/Types/Incident/IncidentMetricType.ts +7 -0
  184. package/Types/Monitor/CriteriaFilter.ts +8 -0
  185. package/Types/Monitor/MonitorCriteriaInstance.ts +67 -0
  186. package/Types/Monitor/MonitorStep.ts +38 -0
  187. package/Types/Monitor/MonitorStepSqlMonitor.ts +141 -0
  188. package/Types/Monitor/MonitorType.ts +17 -0
  189. package/Types/Monitor/SqlDatabaseType.ts +49 -0
  190. package/Types/Monitor/SqlMonitor/SqlMonitorResponse.ts +28 -0
  191. package/Types/Permission.ts +11 -95
  192. package/Types/Probe/ProbeMonitorResponse.ts +2 -0
  193. package/Types/Runbook/RunbookStep.ts +26 -2
  194. package/Types/Runbook/RunbookStepType.ts +1 -0
  195. package/Types/Workflow/Component.ts +13 -0
  196. package/Types/Workflow/ComponentID.ts +1 -0
  197. package/Types/Workflow/Components/AI.ts +148 -0
  198. package/Types/Workflow/Components.ts +8 -0
  199. package/UI/Components/AI/GenerateFromAIModal.tsx +1 -1
  200. package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +11 -0
  201. package/UI/Components/MoreMenu/MoreMenu.tsx +1 -1
  202. package/UI/Components/Table/Table.tsx +38 -2
  203. package/UI/Utils/TableColumnsToCsv.ts +385 -0
  204. package/Utils/Monitor/MonitorMetricType.ts +1 -0
  205. package/build/dist/Models/DatabaseModels/AIAgentTaskPullRequest.js +59 -45
  206. package/build/dist/Models/DatabaseModels/AIAgentTaskPullRequest.js.map +1 -1
  207. package/build/dist/Models/DatabaseModels/AIInsight.js +795 -0
  208. package/build/dist/Models/DatabaseModels/AIInsight.js.map +1 -0
  209. package/build/dist/Models/DatabaseModels/AIRun.js +274 -0
  210. package/build/dist/Models/DatabaseModels/AIRun.js.map +1 -1
  211. package/build/dist/Models/DatabaseModels/CodeRepository.js +43 -0
  212. package/build/dist/Models/DatabaseModels/CodeRepository.js.map +1 -1
  213. package/build/dist/Models/DatabaseModels/Dashboard.js +3 -3
  214. package/build/dist/Models/DatabaseModels/Dashboard.js.map +1 -1
  215. package/build/dist/Models/DatabaseModels/GlobalConfig.js +110 -0
  216. package/build/dist/Models/DatabaseModels/GlobalConfig.js.map +1 -1
  217. package/build/dist/Models/DatabaseModels/Index.js +4 -8
  218. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  219. package/build/dist/Models/DatabaseModels/InstanceHealthLog.js +304 -0
  220. package/build/dist/Models/DatabaseModels/InstanceHealthLog.js.map +1 -0
  221. package/build/dist/Models/DatabaseModels/LlmLog.js +35 -0
  222. package/build/dist/Models/DatabaseModels/LlmLog.js.map +1 -1
  223. package/build/dist/Models/DatabaseModels/Project.js +127 -6
  224. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  225. package/build/dist/Models/DatabaseModels/Runbook.js +1 -1
  226. package/build/dist/Models/DatabaseModels/Runbook.js.map +1 -1
  227. package/build/dist/Server/API/AIAgentDataAPI.js +568 -85
  228. package/build/dist/Server/API/AIAgentDataAPI.js.map +1 -1
  229. package/build/dist/Server/API/AIAgentTaskAPI.js +100 -44
  230. package/build/dist/Server/API/AIAgentTaskAPI.js.map +1 -1
  231. package/build/dist/Server/API/AIAgentTaskLogAPI.js +49 -25
  232. package/build/dist/Server/API/AIAgentTaskLogAPI.js.map +1 -1
  233. package/build/dist/Server/API/AIAgentTaskPullRequestAPI.js +27 -0
  234. package/build/dist/Server/API/AIAgentTaskPullRequestAPI.js.map +1 -1
  235. package/build/dist/Server/API/AIInsightAPI.js +140 -0
  236. package/build/dist/Server/API/AIInsightAPI.js.map +1 -0
  237. package/build/dist/Server/API/AIInvestigationAPI.js +257 -1
  238. package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
  239. package/build/dist/Server/API/CodeFixRunAPI.js +181 -0
  240. package/build/dist/Server/API/CodeFixRunAPI.js.map +1 -0
  241. package/build/dist/Server/API/GitHubAPI.js +164 -2
  242. package/build/dist/Server/API/GitHubAPI.js.map +1 -1
  243. package/build/dist/Server/API/TelemetryExceptionAPI.js +148 -43
  244. package/build/dist/Server/API/TelemetryExceptionAPI.js.map +1 -1
  245. package/build/dist/Server/EnvironmentConfig.js +1 -1
  246. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  247. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783943300000-DropServiceCodeRepository.js +23 -0
  248. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783943300000-DropServiceCodeRepository.js.map +1 -0
  249. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783947444597-CodeFixRunsOnAIRun.js +32 -0
  250. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783947444597-CodeFixRunsOnAIRun.js.map +1 -0
  251. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783950962813-AddCodeFixTaskType.js +16 -0
  252. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783950962813-AddCodeFixTaskType.js.map +1 -0
  253. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783954040984-AddInstrumentationFixTasksFlag.js +16 -0
  254. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783954040984-AddInstrumentationFixTasksFlag.js.map +1 -0
  255. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783957160597-MigrationName.js +24 -0
  256. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783957160597-MigrationName.js.map +1 -0
  257. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783958542237-AddTaskContextToAIRun.js +16 -0
  258. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783958542237-AddTaskContextToAIRun.js.map +1 -0
  259. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783965945957-AddInvestigationVerdictAndGrade.js +24 -0
  260. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783965945957-AddInvestigationVerdictAndGrade.js.map +1 -0
  261. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783970619301-AddFixGuardrailColumns.js +24 -0
  262. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783970619301-AddFixGuardrailColumns.js.map +1 -0
  263. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783970619302-DropLegacyAIAgentTaskTables.js +24 -0
  264. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783970619302-DropLegacyAIAgentTaskTables.js.map +1 -0
  265. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783977781677-AddCiStatusToFixPullRequests.js +18 -0
  266. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783977781677-AddCiStatusToFixPullRequests.js.map +1 -0
  267. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783990000000-AddCompletionTokensToLlmLog.js +18 -0
  268. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783990000000-AddCompletionTokensToLlmLog.js.map +1 -0
  269. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784010274993-AddSentinelInsight.js +32 -0
  270. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784010274993-AddSentinelInsight.js.map +1 -0
  271. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784010274994-AddSentinelInsightFlags.js +18 -0
  272. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784010274994-AddSentinelInsightFlags.js.map +1 -0
  273. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784030612266-RenameSentinelToAI.js +125 -0
  274. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784030612266-RenameSentinelToAI.js.map +1 -0
  275. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784033837629-MigrationName.js +62 -0
  276. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784033837629-MigrationName.js.map +1 -0
  277. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +30 -0
  278. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  279. package/build/dist/Server/Infrastructure/Queue.js +73 -3
  280. package/build/dist/Server/Infrastructure/Queue.js.map +1 -1
  281. package/build/dist/Server/Infrastructure/Semaphore.js +44 -1
  282. package/build/dist/Server/Infrastructure/Semaphore.js.map +1 -1
  283. package/build/dist/Server/Services/AIAgentService.js +29 -0
  284. package/build/dist/Server/Services/AIAgentService.js.map +1 -1
  285. package/build/dist/Server/Services/AIAgentTaskPullRequestService.js +78 -0
  286. package/build/dist/Server/Services/AIAgentTaskPullRequestService.js.map +1 -1
  287. package/build/dist/Server/Services/AIInsightService.js +164 -0
  288. package/build/dist/Server/Services/AIInsightService.js.map +1 -0
  289. package/build/dist/Server/Services/AIRunEventService.js +49 -0
  290. package/build/dist/Server/Services/AIRunEventService.js.map +1 -1
  291. package/build/dist/Server/Services/AIRunService.js +221 -0
  292. package/build/dist/Server/Services/AIRunService.js.map +1 -1
  293. package/build/dist/Server/Services/AIService.js +198 -11
  294. package/build/dist/Server/Services/AIService.js.map +1 -1
  295. package/build/dist/Server/Services/AlertService.js +4 -4
  296. package/build/dist/Server/Services/AlertService.js.map +1 -1
  297. package/build/dist/Server/Services/CodeRepositoryService.js +180 -0
  298. package/build/dist/Server/Services/CodeRepositoryService.js.map +1 -1
  299. package/build/dist/Server/Services/DashboardService.js +8 -2
  300. package/build/dist/Server/Services/DashboardService.js.map +1 -1
  301. package/build/dist/Server/Services/GlobalConfigService.js +84 -0
  302. package/build/dist/Server/Services/GlobalConfigService.js.map +1 -1
  303. package/build/dist/Server/Services/IncidentService.js +149 -37
  304. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  305. package/build/dist/Server/Services/IncidentStateTimelineService.js +24 -4
  306. package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
  307. package/build/dist/Server/Services/Index.js +4 -4
  308. package/build/dist/Server/Services/Index.js.map +1 -1
  309. package/build/dist/Server/Services/{AIAgentTaskLogService.js → InstanceHealthLogService.js} +2 -2
  310. package/build/dist/Server/Services/InstanceHealthLogService.js.map +1 -0
  311. package/build/dist/Server/Services/LlmLogService.js +23 -0
  312. package/build/dist/Server/Services/LlmLogService.js.map +1 -1
  313. package/build/dist/Server/Services/LlmProviderService.js +96 -0
  314. package/build/dist/Server/Services/LlmProviderService.js.map +1 -1
  315. package/build/dist/Server/Services/MetricBaselineService.js +65 -0
  316. package/build/dist/Server/Services/MetricBaselineService.js.map +1 -1
  317. package/build/dist/Server/Services/MonitorService.js +9 -1
  318. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  319. package/build/dist/Server/Services/TelemetryExceptionService.js +243 -82
  320. package/build/dist/Server/Services/TelemetryExceptionService.js.map +1 -1
  321. package/build/dist/Server/Services/TraceAggregationService.js +124 -0
  322. package/build/dist/Server/Services/TraceAggregationService.js.map +1 -1
  323. package/build/dist/Server/Types/Workflow/ComponentCode.js.map +1 -1
  324. package/build/dist/Server/Types/Workflow/Components/AI/GenerateText.js +240 -0
  325. package/build/dist/Server/Types/Workflow/Components/AI/GenerateText.js.map +1 -0
  326. package/build/dist/Server/Types/Workflow/Components/Index.js +2 -0
  327. package/build/dist/Server/Types/Workflow/Components/Index.js.map +1 -1
  328. package/build/dist/Server/Utils/AI/CodeFix/CodeAgentWorkspaceGuard.js +48 -0
  329. package/build/dist/Server/Utils/AI/CodeFix/CodeAgentWorkspaceGuard.js.map +1 -0
  330. package/build/dist/Server/Utils/AI/CodeFix/CodeFixAgentCompletion.js +174 -0
  331. package/build/dist/Server/Utils/AI/CodeFix/CodeFixAgentCompletion.js.map +1 -0
  332. package/build/dist/Server/Utils/AI/CodeFix/CodeFixRunQueue.js +126 -0
  333. package/build/dist/Server/Utils/AI/CodeFix/CodeFixRunQueue.js.map +1 -0
  334. package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js +131 -0
  335. package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js.map +1 -0
  336. package/build/dist/Server/Utils/AI/CodeFix/OpenPullRequestCap.js +99 -0
  337. package/build/dist/Server/Utils/AI/CodeFix/OpenPullRequestCap.js.map +1 -0
  338. package/build/dist/Server/Utils/AI/Eval/EvalCorpus.js +245 -0
  339. package/build/dist/Server/Utils/AI/Eval/EvalCorpus.js.map +1 -0
  340. package/build/dist/Server/Utils/AI/Eval/EvalScores.js +83 -0
  341. package/build/dist/Server/Utils/AI/Eval/EvalScores.js.map +1 -0
  342. package/build/dist/Server/Utils/AI/Eval/ReplayInvestigation.js +12 -0
  343. package/build/dist/Server/Utils/AI/Eval/ReplayInvestigation.js.map +1 -0
  344. package/build/dist/Server/Utils/AI/PerfEvidence/SpanTreeAnalyzer.js +439 -0
  345. package/build/dist/Server/Utils/AI/PerfEvidence/SpanTreeAnalyzer.js.map +1 -0
  346. package/build/dist/Server/Utils/AI/{Sentinel/SentinelInvestigationEngine.js → SRE/AIInvestigationEngine.js} +47 -31
  347. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -0
  348. package/build/dist/Server/Utils/AI/{Sentinel/SentinelMemory.js → SRE/AIMemory.js} +5 -5
  349. package/build/dist/Server/Utils/AI/SRE/AIMemory.js.map +1 -0
  350. package/build/dist/Server/Utils/AI/{Sentinel → SRE}/AlertInvestigationRunner.js +42 -19
  351. package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js.map +1 -0
  352. package/build/dist/Server/Utils/AI/SRE/ConfidenceSignal.js +226 -0
  353. package/build/dist/Server/Utils/AI/SRE/ConfidenceSignal.js.map +1 -0
  354. package/build/dist/Server/Utils/AI/SRE/FixFromIncidentTaskTrigger.js +100 -0
  355. package/build/dist/Server/Utils/AI/SRE/FixFromIncidentTaskTrigger.js.map +1 -0
  356. package/build/dist/Server/Utils/AI/SRE/FixPerformanceTaskTrigger.js +174 -0
  357. package/build/dist/Server/Utils/AI/SRE/FixPerformanceTaskTrigger.js.map +1 -0
  358. package/build/dist/Server/Utils/AI/{Sentinel → SRE}/IncidentInvestigationRunner.js +60 -22
  359. package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js.map +1 -0
  360. package/build/dist/Server/Utils/AI/{Sentinel → SRE}/IncidentPostmortemRunner.js +9 -9
  361. package/build/dist/Server/Utils/AI/SRE/IncidentPostmortemRunner.js.map +1 -0
  362. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ErrorLogSpikeDetector.js +268 -0
  363. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ErrorLogSpikeDetector.js.map +1 -0
  364. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.js +226 -0
  365. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.js.map +1 -0
  366. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/Index.js +26 -0
  367. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/Index.js.map +1 -0
  368. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/MetricDriftDetector.js +159 -0
  369. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/MetricDriftDetector.js.map +1 -0
  370. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.js +177 -0
  371. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.js.map +1 -0
  372. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/TraceLatencyRegressionDetector.js +384 -0
  373. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/TraceLatencyRegressionDetector.js.map +1 -0
  374. package/build/dist/Server/Utils/AI/SRE/Insights/FixRouting.js +180 -0
  375. package/build/dist/Server/Utils/AI/SRE/Insights/FixRouting.js.map +1 -0
  376. package/build/dist/Server/Utils/AI/SRE/Insights/InsightScanner.js +269 -0
  377. package/build/dist/Server/Utils/AI/SRE/Insights/InsightScanner.js.map +1 -0
  378. package/build/dist/Server/Utils/AI/SRE/Insights/InsightStore.js +231 -0
  379. package/build/dist/Server/Utils/AI/SRE/Insights/InsightStore.js.map +1 -0
  380. package/build/dist/Server/Utils/AI/SRE/Insights/InsightTriageRunner.js +206 -0
  381. package/build/dist/Server/Utils/AI/SRE/Insights/InsightTriageRunner.js.map +1 -0
  382. package/build/dist/Server/Utils/AI/SRE/Insights/Triage.js +121 -0
  383. package/build/dist/Server/Utils/AI/SRE/Insights/Triage.js.map +1 -0
  384. package/build/dist/Server/Utils/AI/SRE/Insights/Types.js +2 -0
  385. package/build/dist/Server/Utils/AI/SRE/Insights/Types.js.map +1 -0
  386. package/build/dist/Server/Utils/AI/SRE/InstrumentationTaskTrigger.js +148 -0
  387. package/build/dist/Server/Utils/AI/SRE/InstrumentationTaskTrigger.js.map +1 -0
  388. package/build/dist/Server/Utils/AI/SRE/InvestigationGrader.js +231 -0
  389. package/build/dist/Server/Utils/AI/SRE/InvestigationGrader.js.map +1 -0
  390. package/build/dist/Server/Utils/AI/{Sentinel → SRE}/InvestigationQueue.js +102 -23
  391. package/build/dist/Server/Utils/AI/SRE/InvestigationQueue.js.map +1 -0
  392. package/build/dist/Server/Utils/AI/SRE/SubjectCodeFixRun.js +167 -0
  393. package/build/dist/Server/Utils/AI/SRE/SubjectCodeFixRun.js.map +1 -0
  394. package/build/dist/Server/Utils/AI/Toolbox/{SentinelActionTools.js → AIActionTools.js} +18 -2
  395. package/build/dist/Server/Utils/AI/Toolbox/AIActionTools.js.map +1 -0
  396. package/build/dist/Server/Utils/AI/Toolbox/Index.js +2 -2
  397. package/build/dist/Server/Utils/AI/Toolbox/Index.js.map +1 -1
  398. package/build/dist/Server/Utils/AnalyticsDatabase/ClickhouseCapacity.js +301 -0
  399. package/build/dist/Server/Utils/AnalyticsDatabase/ClickhouseCapacity.js.map +1 -0
  400. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js +240 -2
  401. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js.map +1 -1
  402. package/build/dist/Server/Utils/CodeRepository/ServiceRepoLinkSuggester.js +127 -0
  403. package/build/dist/Server/Utils/CodeRepository/ServiceRepoLinkSuggester.js.map +1 -0
  404. package/build/dist/Server/Utils/CodeRepository/StackTraceRepoResolver.js +336 -0
  405. package/build/dist/Server/Utils/CodeRepository/StackTraceRepoResolver.js.map +1 -0
  406. package/build/dist/Server/Utils/Execute.js +21 -11
  407. package/build/dist/Server/Utils/Execute.js.map +1 -1
  408. package/build/dist/Server/Utils/LLM/LLMService.js +125 -25
  409. package/build/dist/Server/Utils/LLM/LLMService.js.map +1 -1
  410. package/build/dist/Server/Utils/Monitor/Criteria/SqlMonitorCriteria.js +120 -0
  411. package/build/dist/Server/Utils/Monitor/Criteria/SqlMonitorCriteria.js.map +1 -0
  412. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +21 -0
  413. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  414. package/build/dist/Types/AI/AIInsightEvidence.js +2 -0
  415. package/build/dist/Types/AI/AIInsightEvidence.js.map +1 -0
  416. package/build/dist/Types/AI/AIInsightHumanVerdict.js +16 -0
  417. package/build/dist/Types/AI/AIInsightHumanVerdict.js.map +1 -0
  418. package/build/dist/Types/AI/AIInsightSeverity.js +14 -0
  419. package/build/dist/Types/AI/AIInsightSeverity.js.map +1 -0
  420. package/build/dist/Types/AI/AIInsightStatus.js +36 -0
  421. package/build/dist/Types/AI/AIInsightStatus.js.map +1 -0
  422. package/build/dist/Types/AI/AIInsightType.js +42 -0
  423. package/build/dist/Types/AI/AIInsightType.js.map +1 -0
  424. package/build/dist/Types/AI/AIRunAutoGrade.js +19 -0
  425. package/build/dist/Types/AI/AIRunAutoGrade.js.map +1 -0
  426. package/build/dist/Types/AI/AIRunEventType.js +5 -0
  427. package/build/dist/Types/AI/AIRunEventType.js.map +1 -1
  428. package/build/dist/Types/AI/AIRunHumanVerdict.js +18 -0
  429. package/build/dist/Types/AI/AIRunHumanVerdict.js.map +1 -0
  430. package/build/dist/Types/AI/AIRunType.js +6 -0
  431. package/build/dist/Types/AI/AIRunType.js.map +1 -1
  432. package/build/dist/Types/AI/CodeFixTaskContext.js +29 -0
  433. package/build/dist/Types/AI/CodeFixTaskContext.js.map +1 -0
  434. package/build/dist/Types/AI/CodeFixTaskType.js +122 -0
  435. package/build/dist/Types/AI/CodeFixTaskType.js.map +1 -0
  436. package/build/dist/Types/AI/FixPullRequestCiStatus.js +102 -0
  437. package/build/dist/Types/AI/FixPullRequestCiStatus.js.map +1 -0
  438. package/build/dist/Types/BaseDatabase/AggregationIntervalUtil.js +55 -0
  439. package/build/dist/Types/BaseDatabase/AggregationIntervalUtil.js.map +1 -1
  440. package/build/dist/Types/Incident/IncidentMetricType.js +7 -0
  441. package/build/dist/Types/Incident/IncidentMetricType.js.map +1 -1
  442. package/build/dist/Types/Monitor/CriteriaFilter.js +7 -0
  443. package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
  444. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +62 -0
  445. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
  446. package/build/dist/Types/Monitor/MonitorStep.js +28 -0
  447. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  448. package/build/dist/Types/Monitor/MonitorStepSqlMonitor.js +93 -0
  449. package/build/dist/Types/Monitor/MonitorStepSqlMonitor.js.map +1 -0
  450. package/build/dist/Types/Monitor/MonitorType.js +15 -0
  451. package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
  452. package/build/dist/Types/Monitor/SqlDatabaseType.js +47 -0
  453. package/build/dist/Types/Monitor/SqlDatabaseType.js.map +1 -0
  454. package/build/dist/Types/Monitor/SqlMonitor/SqlMonitorResponse.js +2 -0
  455. package/build/dist/Types/Monitor/SqlMonitor/SqlMonitorResponse.js.map +1 -0
  456. package/build/dist/Types/Permission.js +10 -84
  457. package/build/dist/Types/Permission.js.map +1 -1
  458. package/build/dist/Types/Runbook/RunbookStepType.js +1 -0
  459. package/build/dist/Types/Runbook/RunbookStepType.js.map +1 -1
  460. package/build/dist/Types/Workflow/ComponentID.js +1 -0
  461. package/build/dist/Types/Workflow/ComponentID.js.map +1 -1
  462. package/build/dist/Types/Workflow/Components/AI.js +135 -0
  463. package/build/dist/Types/Workflow/Components/AI.js.map +1 -0
  464. package/build/dist/Types/Workflow/Components.js +7 -0
  465. package/build/dist/Types/Workflow/Components.js.map +1 -1
  466. package/build/dist/UI/Components/AI/GenerateFromAIModal.js +1 -1
  467. package/build/dist/UI/Components/AI/GenerateFromAIModal.js.map +1 -1
  468. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +9 -0
  469. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
  470. package/build/dist/UI/Components/MoreMenu/MoreMenu.js +1 -1
  471. package/build/dist/UI/Components/Table/Table.js +28 -2
  472. package/build/dist/UI/Components/Table/Table.js.map +1 -1
  473. package/build/dist/UI/Utils/TableColumnsToCsv.js +291 -0
  474. package/build/dist/UI/Utils/TableColumnsToCsv.js.map +1 -0
  475. package/build/dist/Utils/Monitor/MonitorMetricType.js +1 -0
  476. package/build/dist/Utils/Monitor/MonitorMetricType.js.map +1 -1
  477. package/package.json +1 -1
  478. package/Models/DatabaseModels/AIAgentTask.ts +0 -660
  479. package/Models/DatabaseModels/AIAgentTaskLog.ts +0 -426
  480. package/Models/DatabaseModels/AIAgentTaskTelemetryException.ts +0 -399
  481. package/Models/DatabaseModels/ServiceCodeRepository.ts +0 -647
  482. package/Server/Services/AIAgentTaskService.ts +0 -240
  483. package/Server/Services/AIAgentTaskTelemetryExceptionService.ts +0 -39
  484. package/Server/Services/ServiceCodeRepositoryService.ts +0 -55
  485. package/Tests/Server/Services/AIAgentTaskServiceClaim.test.ts +0 -146
  486. package/Types/AI/AIAgentTaskMetadata.ts +0 -25
  487. package/Types/AI/AIAgentTaskType.ts +0 -40
  488. package/build/dist/Models/DatabaseModels/AIAgentTask.js +0 -691
  489. package/build/dist/Models/DatabaseModels/AIAgentTask.js.map +0 -1
  490. package/build/dist/Models/DatabaseModels/AIAgentTaskLog.js +0 -447
  491. package/build/dist/Models/DatabaseModels/AIAgentTaskLog.js.map +0 -1
  492. package/build/dist/Models/DatabaseModels/AIAgentTaskTelemetryException.js +0 -415
  493. package/build/dist/Models/DatabaseModels/AIAgentTaskTelemetryException.js.map +0 -1
  494. package/build/dist/Models/DatabaseModels/ServiceCodeRepository.js +0 -665
  495. package/build/dist/Models/DatabaseModels/ServiceCodeRepository.js.map +0 -1
  496. package/build/dist/Server/Services/AIAgentTaskLogService.js.map +0 -1
  497. package/build/dist/Server/Services/AIAgentTaskService.js +0 -217
  498. package/build/dist/Server/Services/AIAgentTaskService.js.map +0 -1
  499. package/build/dist/Server/Services/AIAgentTaskTelemetryExceptionService.js +0 -36
  500. package/build/dist/Server/Services/AIAgentTaskTelemetryExceptionService.js.map +0 -1
  501. package/build/dist/Server/Services/ServiceCodeRepositoryService.js +0 -54
  502. package/build/dist/Server/Services/ServiceCodeRepositoryService.js.map +0 -1
  503. package/build/dist/Server/Utils/AI/Sentinel/AlertInvestigationRunner.js.map +0 -1
  504. package/build/dist/Server/Utils/AI/Sentinel/IncidentInvestigationRunner.js.map +0 -1
  505. package/build/dist/Server/Utils/AI/Sentinel/IncidentPostmortemRunner.js.map +0 -1
  506. package/build/dist/Server/Utils/AI/Sentinel/InvestigationQueue.js.map +0 -1
  507. package/build/dist/Server/Utils/AI/Sentinel/SentinelInvestigationEngine.js.map +0 -1
  508. package/build/dist/Server/Utils/AI/Sentinel/SentinelMemory.js.map +0 -1
  509. package/build/dist/Server/Utils/AI/Toolbox/SentinelActionTools.js.map +0 -1
  510. package/build/dist/Types/AI/AIAgentTaskMetadata.js +0 -6
  511. package/build/dist/Types/AI/AIAgentTaskMetadata.js.map +0 -1
  512. package/build/dist/Types/AI/AIAgentTaskType.js +0 -29
  513. package/build/dist/Types/AI/AIAgentTaskType.js.map +0 -1
@@ -0,0 +1,401 @@
1
+ import AIRunService from "../../../Server/Services/AIRunService";
2
+ import AIRun from "../../../Models/DatabaseModels/AIRun";
3
+ import AIRunStatus from "../../../Types/AI/AIRunStatus";
4
+ import CodeFixTaskType from "../../../Types/AI/CodeFixTaskType";
5
+ import CodeFixTaskContext from "../../../Types/AI/CodeFixTaskContext";
6
+ import ObjectID from "../../../Types/ObjectID";
7
+ import { describe, expect, test, afterEach } from "@jest/globals";
8
+
9
+ /*
10
+ * The code-fix claim behind POST /ai-agent-task/get-pending-task: the
11
+ * oldest Queued CodeFix run is claimed with the same status+attemptCount
12
+ * guarded CAS the investigation queue uses, so concurrent agent workers can
13
+ * never receive the same run. These tests mock findOneBy /
14
+ * attemptStatusTransition (the AIInvestigationQueue test idiom) and
15
+ * lock in the claim invariants.
16
+ */
17
+
18
+ function fakeQueuedRun(data?: {
19
+ exceptionId?: ObjectID | null;
20
+ attemptCount?: number;
21
+ codeFixTaskType?: CodeFixTaskType;
22
+ incidentId?: ObjectID;
23
+ alertId?: ObjectID;
24
+ taskContext?: CodeFixTaskContext;
25
+ }): AIRun {
26
+ return {
27
+ id: ObjectID.generate(),
28
+ projectId: ObjectID.generate(),
29
+ triggeredByTelemetryExceptionId:
30
+ data?.exceptionId === null
31
+ ? undefined
32
+ : data?.exceptionId || ObjectID.generate(),
33
+ triggeredByIncidentId: data?.incidentId,
34
+ triggeredByAlertId: data?.alertId,
35
+ attemptCount: data?.attemptCount || 0,
36
+ codeFixTaskType: data?.codeFixTaskType,
37
+ taskContext: data?.taskContext,
38
+ } as unknown as AIRun;
39
+ }
40
+
41
+ describe("AIRunService.claimNextQueuedCodeFixRun", () => {
42
+ afterEach(() => {
43
+ jest.restoreAllMocks();
44
+ });
45
+
46
+ test("returns null when no queued code-fix run exists — no CAS attempted", async () => {
47
+ jest.spyOn(AIRunService, "findOneBy").mockResolvedValue(null);
48
+ const transition: jest.SpyInstance = jest.spyOn(
49
+ AIRunService,
50
+ "attemptStatusTransition",
51
+ );
52
+
53
+ const claimed: AIRun | null = await AIRunService.claimNextQueuedCodeFixRun({
54
+ aiAgentId: ObjectID.generate(),
55
+ });
56
+
57
+ expect(claimed).toBeNull();
58
+ expect(transition).not.toHaveBeenCalled();
59
+ });
60
+
61
+ test("a won claim transitions Queued -> Running with heartbeat, agent id and attemptCount+1", async () => {
62
+ const run: AIRun = fakeQueuedRun();
63
+ const aiAgentId: ObjectID = ObjectID.generate();
64
+
65
+ jest.spyOn(AIRunService, "findOneBy").mockResolvedValue(run);
66
+ const transition: jest.SpyInstance = jest
67
+ .spyOn(AIRunService, "attemptStatusTransition")
68
+ .mockResolvedValue(1);
69
+
70
+ const claimed: AIRun | null = await AIRunService.claimNextQueuedCodeFixRun({
71
+ aiAgentId,
72
+ });
73
+
74
+ expect(claimed).toBe(run);
75
+ expect(transition).toHaveBeenCalledTimes(1);
76
+ expect(transition).toHaveBeenCalledWith(
77
+ expect.objectContaining({
78
+ aiRunId: run.id,
79
+ fromStatus: AIRunStatus.Queued,
80
+ // Guards against stale snapshots re-claiming or re-numbering.
81
+ expectedAttemptCount: 0,
82
+ set: expect.objectContaining({
83
+ status: AIRunStatus.Running,
84
+ attemptCount: 1,
85
+ startedAt: expect.any(Date),
86
+ lastHeartbeatAt: expect.any(Date),
87
+ /*
88
+ * The transition path bypasses column transformers, so the agent
89
+ * id must be its pre-transformed string form.
90
+ */
91
+ aiAgentId: aiAgentId.toString(),
92
+ }),
93
+ }),
94
+ );
95
+ });
96
+
97
+ test("a lost claim retries with the next candidate instead of returning it", async () => {
98
+ const lostRun: AIRun = fakeQueuedRun();
99
+ const wonRun: AIRun = fakeQueuedRun();
100
+
101
+ jest
102
+ .spyOn(AIRunService, "findOneBy")
103
+ .mockResolvedValueOnce(lostRun)
104
+ .mockResolvedValueOnce(wonRun);
105
+ jest
106
+ .spyOn(AIRunService, "attemptStatusTransition")
107
+ .mockResolvedValueOnce(0) // another agent won lostRun
108
+ .mockResolvedValueOnce(1);
109
+
110
+ const claimed: AIRun | null = await AIRunService.claimNextQueuedCodeFixRun({
111
+ aiAgentId: ObjectID.generate(),
112
+ });
113
+
114
+ expect(claimed).toBe(wonRun);
115
+ });
116
+
117
+ test("an exception-based run without a triggering exception is finalized as Error and skipped", async () => {
118
+ const brokenRun: AIRun = fakeQueuedRun({ exceptionId: null });
119
+ const goodRun: AIRun = fakeQueuedRun();
120
+
121
+ jest
122
+ .spyOn(AIRunService, "findOneBy")
123
+ .mockResolvedValueOnce(brokenRun)
124
+ .mockResolvedValueOnce(goodRun);
125
+ const transition: jest.SpyInstance = jest
126
+ .spyOn(AIRunService, "attemptStatusTransition")
127
+ .mockResolvedValue(1);
128
+
129
+ const claimed: AIRun | null = await AIRunService.claimNextQueuedCodeFixRun({
130
+ aiAgentId: ObjectID.generate(),
131
+ });
132
+
133
+ expect(claimed).toBe(goodRun);
134
+ // Claim broken -> Error broken -> claim good.
135
+ expect(transition).toHaveBeenCalledTimes(3);
136
+ expect(transition).toHaveBeenNthCalledWith(
137
+ 2,
138
+ expect.objectContaining({
139
+ aiRunId: brokenRun.id,
140
+ fromStatus: AIRunStatus.Running,
141
+ set: expect.objectContaining({
142
+ status: AIRunStatus.Error,
143
+ }),
144
+ }),
145
+ );
146
+ });
147
+
148
+ /*
149
+ * The executability guard is recipe-dependent: ImproveInstrumentation
150
+ * runs are enqueued by the inconclusive-investigation trigger with an
151
+ * incident/alert subject and NO telemetry exception — the claim must
152
+ * hand them to the worker, not Error them for lacking an exception.
153
+ */
154
+ test("an ImproveInstrumentation run without an exception but with an incident subject is claimed, not errored", async () => {
155
+ const run: AIRun = fakeQueuedRun({
156
+ exceptionId: null,
157
+ codeFixTaskType: CodeFixTaskType.ImproveInstrumentation,
158
+ incidentId: ObjectID.generate(),
159
+ });
160
+
161
+ jest.spyOn(AIRunService, "findOneBy").mockResolvedValue(run);
162
+ const transition: jest.SpyInstance = jest
163
+ .spyOn(AIRunService, "attemptStatusTransition")
164
+ .mockResolvedValue(1);
165
+
166
+ const claimed: AIRun | null = await AIRunService.claimNextQueuedCodeFixRun({
167
+ aiAgentId: ObjectID.generate(),
168
+ });
169
+
170
+ expect(claimed).toBe(run);
171
+ expect(claimed?.codeFixTaskType).toBe(
172
+ CodeFixTaskType.ImproveInstrumentation,
173
+ );
174
+ // Exactly the claim CAS — no Error transition.
175
+ expect(transition).toHaveBeenCalledTimes(1);
176
+ });
177
+
178
+ test("an ImproveInstrumentation run with an alert subject is claimed too", async () => {
179
+ const run: AIRun = fakeQueuedRun({
180
+ exceptionId: null,
181
+ codeFixTaskType: CodeFixTaskType.ImproveInstrumentation,
182
+ alertId: ObjectID.generate(),
183
+ });
184
+
185
+ jest.spyOn(AIRunService, "findOneBy").mockResolvedValue(run);
186
+ jest.spyOn(AIRunService, "attemptStatusTransition").mockResolvedValue(1);
187
+
188
+ const claimed: AIRun | null = await AIRunService.claimNextQueuedCodeFixRun({
189
+ aiAgentId: ObjectID.generate(),
190
+ });
191
+
192
+ expect(claimed).toBe(run);
193
+ });
194
+
195
+ /*
196
+ * FixFromIncident is the second incident/alert-subject recipe: enqueued
197
+ * by the user from the investigation panel, no telemetry exception — the
198
+ * same recipe grouping as ImproveInstrumentation in the guard.
199
+ */
200
+ test("a FixFromIncident run without an exception but with an incident subject is claimed, not errored", async () => {
201
+ const run: AIRun = fakeQueuedRun({
202
+ exceptionId: null,
203
+ codeFixTaskType: CodeFixTaskType.FixFromIncident,
204
+ incidentId: ObjectID.generate(),
205
+ });
206
+
207
+ jest.spyOn(AIRunService, "findOneBy").mockResolvedValue(run);
208
+ const transition: jest.SpyInstance = jest
209
+ .spyOn(AIRunService, "attemptStatusTransition")
210
+ .mockResolvedValue(1);
211
+
212
+ const claimed: AIRun | null = await AIRunService.claimNextQueuedCodeFixRun({
213
+ aiAgentId: ObjectID.generate(),
214
+ });
215
+
216
+ expect(claimed).toBe(run);
217
+ expect(claimed?.codeFixTaskType).toBe(CodeFixTaskType.FixFromIncident);
218
+ // Exactly the claim CAS — no Error transition.
219
+ expect(transition).toHaveBeenCalledTimes(1);
220
+ });
221
+
222
+ test("a FixFromIncident run with an alert subject is claimed too", async () => {
223
+ const run: AIRun = fakeQueuedRun({
224
+ exceptionId: null,
225
+ codeFixTaskType: CodeFixTaskType.FixFromIncident,
226
+ alertId: ObjectID.generate(),
227
+ });
228
+
229
+ jest.spyOn(AIRunService, "findOneBy").mockResolvedValue(run);
230
+ jest.spyOn(AIRunService, "attemptStatusTransition").mockResolvedValue(1);
231
+
232
+ const claimed: AIRun | null = await AIRunService.claimNextQueuedCodeFixRun({
233
+ aiAgentId: ObjectID.generate(),
234
+ });
235
+
236
+ expect(claimed).toBe(run);
237
+ });
238
+
239
+ test("a FixFromIncident run with NO subject at all is finalized as Error and skipped", async () => {
240
+ const brokenRun: AIRun = fakeQueuedRun({
241
+ exceptionId: null,
242
+ codeFixTaskType: CodeFixTaskType.FixFromIncident,
243
+ });
244
+ const goodRun: AIRun = fakeQueuedRun();
245
+
246
+ jest
247
+ .spyOn(AIRunService, "findOneBy")
248
+ .mockResolvedValueOnce(brokenRun)
249
+ .mockResolvedValueOnce(goodRun);
250
+ const transition: jest.SpyInstance = jest
251
+ .spyOn(AIRunService, "attemptStatusTransition")
252
+ .mockResolvedValue(1);
253
+
254
+ const claimed: AIRun | null = await AIRunService.claimNextQueuedCodeFixRun({
255
+ aiAgentId: ObjectID.generate(),
256
+ });
257
+
258
+ expect(claimed).toBe(goodRun);
259
+ expect(transition).toHaveBeenNthCalledWith(
260
+ 2,
261
+ expect.objectContaining({
262
+ aiRunId: brokenRun.id,
263
+ fromStatus: AIRunStatus.Running,
264
+ set: expect.objectContaining({
265
+ status: AIRunStatus.Error,
266
+ errorMessage: expect.stringContaining("incident or alert subject"),
267
+ }),
268
+ }),
269
+ );
270
+ });
271
+
272
+ /*
273
+ * FixPerformance is the third context kind: no exception AND no
274
+ * incident/alert subject — its trace evidence lives in taskContext. The
275
+ * guard must accept it when taskContext carries a traceId and Error it
276
+ * when the evidence is missing.
277
+ */
278
+ test("a FixPerformance run with trace evidence in taskContext is claimed — no exception, no subject", async () => {
279
+ const run: AIRun = fakeQueuedRun({
280
+ exceptionId: null,
281
+ codeFixTaskType: CodeFixTaskType.FixPerformance,
282
+ taskContext: {
283
+ traceId: "abc123trace",
284
+ performanceFindings: [],
285
+ },
286
+ });
287
+
288
+ jest.spyOn(AIRunService, "findOneBy").mockResolvedValue(run);
289
+ const transition: jest.SpyInstance = jest
290
+ .spyOn(AIRunService, "attemptStatusTransition")
291
+ .mockResolvedValue(1);
292
+
293
+ const claimed: AIRun | null = await AIRunService.claimNextQueuedCodeFixRun({
294
+ aiAgentId: ObjectID.generate(),
295
+ });
296
+
297
+ expect(claimed).toBe(run);
298
+ expect(claimed?.codeFixTaskType).toBe(CodeFixTaskType.FixPerformance);
299
+ // Exactly the claim CAS — no Error transition.
300
+ expect(transition).toHaveBeenCalledTimes(1);
301
+ });
302
+
303
+ test("a FixPerformance run with NO trace evidence is finalized as Error and skipped", async () => {
304
+ const brokenRun: AIRun = fakeQueuedRun({
305
+ exceptionId: null,
306
+ codeFixTaskType: CodeFixTaskType.FixPerformance,
307
+ });
308
+ const goodRun: AIRun = fakeQueuedRun();
309
+
310
+ jest
311
+ .spyOn(AIRunService, "findOneBy")
312
+ .mockResolvedValueOnce(brokenRun)
313
+ .mockResolvedValueOnce(goodRun);
314
+ const transition: jest.SpyInstance = jest
315
+ .spyOn(AIRunService, "attemptStatusTransition")
316
+ .mockResolvedValue(1);
317
+
318
+ const claimed: AIRun | null = await AIRunService.claimNextQueuedCodeFixRun({
319
+ aiAgentId: ObjectID.generate(),
320
+ });
321
+
322
+ expect(claimed).toBe(goodRun);
323
+ expect(transition).toHaveBeenNthCalledWith(
324
+ 2,
325
+ expect.objectContaining({
326
+ aiRunId: brokenRun.id,
327
+ fromStatus: AIRunStatus.Running,
328
+ set: expect.objectContaining({
329
+ status: AIRunStatus.Error,
330
+ errorMessage: expect.stringContaining("trace evidence"),
331
+ }),
332
+ }),
333
+ );
334
+ });
335
+
336
+ test("a FixPerformance run carrying an incident id but no taskContext is still errored — the guard groups by context kind, not by whatever record happens to exist", async () => {
337
+ const brokenRun: AIRun = fakeQueuedRun({
338
+ exceptionId: null,
339
+ codeFixTaskType: CodeFixTaskType.FixPerformance,
340
+ incidentId: ObjectID.generate(),
341
+ });
342
+ const goodRun: AIRun = fakeQueuedRun();
343
+
344
+ jest
345
+ .spyOn(AIRunService, "findOneBy")
346
+ .mockResolvedValueOnce(brokenRun)
347
+ .mockResolvedValueOnce(goodRun);
348
+ const transition: jest.SpyInstance = jest
349
+ .spyOn(AIRunService, "attemptStatusTransition")
350
+ .mockResolvedValue(1);
351
+
352
+ const claimed: AIRun | null = await AIRunService.claimNextQueuedCodeFixRun({
353
+ aiAgentId: ObjectID.generate(),
354
+ });
355
+
356
+ expect(claimed).toBe(goodRun);
357
+ expect(transition).toHaveBeenNthCalledWith(
358
+ 2,
359
+ expect.objectContaining({
360
+ aiRunId: brokenRun.id,
361
+ set: expect.objectContaining({
362
+ status: AIRunStatus.Error,
363
+ errorMessage: expect.stringContaining("trace evidence"),
364
+ }),
365
+ }),
366
+ );
367
+ });
368
+
369
+ test("an ImproveInstrumentation run with NO subject at all is finalized as Error and skipped", async () => {
370
+ const brokenRun: AIRun = fakeQueuedRun({
371
+ exceptionId: null,
372
+ codeFixTaskType: CodeFixTaskType.ImproveInstrumentation,
373
+ });
374
+ const goodRun: AIRun = fakeQueuedRun();
375
+
376
+ jest
377
+ .spyOn(AIRunService, "findOneBy")
378
+ .mockResolvedValueOnce(brokenRun)
379
+ .mockResolvedValueOnce(goodRun);
380
+ const transition: jest.SpyInstance = jest
381
+ .spyOn(AIRunService, "attemptStatusTransition")
382
+ .mockResolvedValue(1);
383
+
384
+ const claimed: AIRun | null = await AIRunService.claimNextQueuedCodeFixRun({
385
+ aiAgentId: ObjectID.generate(),
386
+ });
387
+
388
+ expect(claimed).toBe(goodRun);
389
+ expect(transition).toHaveBeenNthCalledWith(
390
+ 2,
391
+ expect.objectContaining({
392
+ aiRunId: brokenRun.id,
393
+ fromStatus: AIRunStatus.Running,
394
+ set: expect.objectContaining({
395
+ status: AIRunStatus.Error,
396
+ errorMessage: expect.stringContaining("incident or alert subject"),
397
+ }),
398
+ }),
399
+ );
400
+ });
401
+ });
@@ -0,0 +1,161 @@
1
+ import AIRunService from "../../../Server/Services/AIRunService";
2
+ import AIRun from "../../../Models/DatabaseModels/AIRun";
3
+ import AIRunType from "../../../Types/AI/AIRunType";
4
+ import AIRunStatus from "../../../Types/AI/AIRunStatus";
5
+ import AIRunHumanVerdict from "../../../Types/AI/AIRunHumanVerdict";
6
+ import BadDataException from "../../../Types/Exception/BadDataException";
7
+ import ObjectID from "../../../Types/ObjectID";
8
+ import SortOrder from "../../../Types/BaseDatabase/SortOrder";
9
+ import { describe, expect, test, afterEach } from "@jest/globals";
10
+
11
+ /*
12
+ * Human verdict capture (Phase 2 measurement layer): the one-click
13
+ * Confirm / Reject on the investigation panel lands here, via
14
+ * POST /ai-investigation/verdict → applyHumanVerdictToLatestInvestigation.
15
+ * Contract under test: the verdict applies to the LATEST COMPLETED
16
+ * investigation for the subject, rejects when none exists, stores
17
+ * verdict + at + byUserId, and overwriting is allowed (a user may change
18
+ * their mind — there is deliberately no "already has a verdict" guard).
19
+ */
20
+
21
+ const incidentId: ObjectID = ObjectID.generate();
22
+ const alertId: ObjectID = ObjectID.generate();
23
+ const userId: ObjectID = ObjectID.generate();
24
+
25
+ function fakeRun(): AIRun {
26
+ return { id: ObjectID.generate() } as unknown as AIRun;
27
+ }
28
+
29
+ describe("AIRunService.applyHumanVerdictToLatestInvestigation", () => {
30
+ afterEach(() => {
31
+ jest.restoreAllMocks();
32
+ });
33
+
34
+ test("a subjectless call is rejected before any query", async () => {
35
+ const findOneBy: jest.SpyInstance = jest.spyOn(AIRunService, "findOneBy");
36
+
37
+ await expect(
38
+ AIRunService.applyHumanVerdictToLatestInvestigation({
39
+ verdict: AIRunHumanVerdict.Confirmed,
40
+ verdictByUserId: userId,
41
+ }),
42
+ ).rejects.toThrow(BadDataException);
43
+
44
+ expect(findOneBy).not.toHaveBeenCalled();
45
+ });
46
+
47
+ test("no completed investigation → reject with a clear message, nothing written", async () => {
48
+ const findOneBy: jest.SpyInstance = jest
49
+ .spyOn(AIRunService, "findOneBy")
50
+ .mockResolvedValue(null);
51
+ const updateOneById: jest.SpyInstance = jest.spyOn(
52
+ AIRunService,
53
+ "updateOneById",
54
+ );
55
+
56
+ await expect(
57
+ AIRunService.applyHumanVerdictToLatestInvestigation({
58
+ incidentId,
59
+ verdict: AIRunHumanVerdict.Confirmed,
60
+ verdictByUserId: userId,
61
+ }),
62
+ ).rejects.toThrow(/No completed AI investigation/);
63
+
64
+ // The lookup must target the LATEST COMPLETED investigation.
65
+ expect(findOneBy).toHaveBeenCalledWith(
66
+ expect.objectContaining({
67
+ query: expect.objectContaining({
68
+ runType: AIRunType.Investigation,
69
+ status: AIRunStatus.Completed,
70
+ triggeredByIncidentId: incidentId,
71
+ }),
72
+ sort: expect.objectContaining({ createdAt: SortOrder.Descending }),
73
+ }),
74
+ );
75
+ expect(updateOneById).not.toHaveBeenCalled();
76
+ });
77
+
78
+ test("happy path (incident): stores verdict + at + byUserId on the run and returns {runId, verdict}", async () => {
79
+ const run: AIRun = fakeRun();
80
+ jest.spyOn(AIRunService, "findOneBy").mockResolvedValue(run);
81
+ const updateOneById: jest.SpyInstance = jest
82
+ .spyOn(AIRunService, "updateOneById")
83
+ .mockResolvedValue(undefined as never);
84
+
85
+ const result: { runId: ObjectID; verdict: AIRunHumanVerdict } =
86
+ await AIRunService.applyHumanVerdictToLatestInvestigation({
87
+ incidentId,
88
+ verdict: AIRunHumanVerdict.Confirmed,
89
+ verdictByUserId: userId,
90
+ });
91
+
92
+ expect(result.runId).toBe(run.id);
93
+ expect(result.verdict).toBe(AIRunHumanVerdict.Confirmed);
94
+
95
+ expect(updateOneById).toHaveBeenCalledWith(
96
+ expect.objectContaining({
97
+ id: run.id,
98
+ data: expect.objectContaining({
99
+ humanVerdict: AIRunHumanVerdict.Confirmed,
100
+ humanVerdictAt: expect.any(Date),
101
+ humanVerdictByUserId: userId,
102
+ }),
103
+ props: expect.objectContaining({ isRoot: true }),
104
+ }),
105
+ );
106
+ });
107
+
108
+ test("happy path (alert): the lookup keys on triggeredByAlertId", async () => {
109
+ const run: AIRun = fakeRun();
110
+ const findOneBy: jest.SpyInstance = jest
111
+ .spyOn(AIRunService, "findOneBy")
112
+ .mockResolvedValue(run);
113
+ jest
114
+ .spyOn(AIRunService, "updateOneById")
115
+ .mockResolvedValue(undefined as never);
116
+
117
+ await AIRunService.applyHumanVerdictToLatestInvestigation({
118
+ alertId,
119
+ verdict: AIRunHumanVerdict.Rejected,
120
+ verdictByUserId: userId,
121
+ });
122
+
123
+ expect(findOneBy).toHaveBeenCalledWith(
124
+ expect.objectContaining({
125
+ query: expect.objectContaining({
126
+ runType: AIRunType.Investigation,
127
+ status: AIRunStatus.Completed,
128
+ triggeredByAlertId: alertId,
129
+ }),
130
+ }),
131
+ );
132
+ });
133
+
134
+ test("idempotent overwrite: a run that already carries a verdict is simply re-written", async () => {
135
+ // The service deliberately does NOT guard on an existing verdict.
136
+ const run: AIRun = {
137
+ id: ObjectID.generate(),
138
+ humanVerdict: AIRunHumanVerdict.Confirmed,
139
+ } as unknown as AIRun;
140
+ jest.spyOn(AIRunService, "findOneBy").mockResolvedValue(run);
141
+ const updateOneById: jest.SpyInstance = jest
142
+ .spyOn(AIRunService, "updateOneById")
143
+ .mockResolvedValue(undefined as never);
144
+
145
+ const result: { runId: ObjectID; verdict: AIRunHumanVerdict } =
146
+ await AIRunService.applyHumanVerdictToLatestInvestigation({
147
+ incidentId,
148
+ verdict: AIRunHumanVerdict.Rejected,
149
+ verdictByUserId: userId,
150
+ });
151
+
152
+ expect(result.verdict).toBe(AIRunHumanVerdict.Rejected);
153
+ expect(updateOneById).toHaveBeenCalledWith(
154
+ expect.objectContaining({
155
+ data: expect.objectContaining({
156
+ humanVerdict: AIRunHumanVerdict.Rejected,
157
+ }),
158
+ }),
159
+ );
160
+ });
161
+ });
@@ -1,8 +1,17 @@
1
1
  import AIService, {
2
2
  AUTONOMOUS_AI_FEATURES,
3
3
  AutonomousBudgetStatus,
4
+ LEGACY_AUTONOMOUS_AI_FEATURES,
5
+ AI_ALERT_INVESTIGATION_FEATURE,
6
+ AI_CODE_FIX_FEATURE,
7
+ AI_CONFIDENCE_CLASSIFICATION_FEATURE,
8
+ AI_INCIDENT_INVESTIGATION_FEATURE,
9
+ AI_INSIGHT_TRIAGE_FEATURE,
10
+ AI_INVESTIGATION_GRADING_FEATURE,
11
+ RUNBOOK_AI_STEP_FEATURE,
12
+ WORKFLOW_AI_FEATURE,
4
13
  } from "../../../Server/Services/AIService";
5
- import SentinelInvestigationQueue from "../../../Server/Utils/AI/Sentinel/InvestigationQueue";
14
+ import AIInvestigationQueue from "../../../Server/Utils/AI/SRE/InvestigationQueue";
6
15
  import LlmLogService from "../../../Server/Services/LlmLogService";
7
16
  import ProjectService from "../../../Server/Services/ProjectService";
8
17
  import AIRunService from "../../../Server/Services/AIRunService";
@@ -32,6 +41,87 @@ function fakeProject(limit: number | undefined): Project {
32
41
  } as unknown as Project;
33
42
  }
34
43
 
44
+ /*
45
+ * The budget is enforced by matching PERSISTED LlmLog.feature strings against
46
+ * AUTONOMOUS_AI_FEATURES, so these labels are data, not display text. Changing
47
+ * one silently rewrites a project's usage history for the current UTC day:
48
+ * older rows stop matching, usedTokensToday collapses toward zero, and an
49
+ * already-exhausted project gets a fresh full budget. These tests pin the
50
+ * exact wire values and the legacy aliases so no rename can do that quietly.
51
+ */
52
+ describe("AUTONOMOUS_AI_FEATURES persisted labels", () => {
53
+ test("each label has its exact persisted value", () => {
54
+ expect(AI_INCIDENT_INVESTIGATION_FEATURE).toBe("AI Incident Investigation");
55
+ expect(AI_ALERT_INVESTIGATION_FEATURE).toBe("AI Alert Investigation");
56
+ expect(AI_INVESTIGATION_GRADING_FEATURE).toBe("AI Investigation Grading");
57
+ expect(AI_CONFIDENCE_CLASSIFICATION_FEATURE).toBe(
58
+ "AI Confidence Classification",
59
+ );
60
+ expect(AI_CODE_FIX_FEATURE).toBe("AI Code Fix");
61
+ expect(AI_INSIGHT_TRIAGE_FEATURE).toBe("AI Insight Triage");
62
+ expect(RUNBOOK_AI_STEP_FEATURE).toBe("Runbook AI Step");
63
+ expect(WORKFLOW_AI_FEATURE).toBe("Workflow AI");
64
+ });
65
+
66
+ test("the budget match-list covers every autonomous feature", () => {
67
+ for (const feature of [
68
+ AI_INCIDENT_INVESTIGATION_FEATURE,
69
+ AI_ALERT_INVESTIGATION_FEATURE,
70
+ AI_INVESTIGATION_GRADING_FEATURE,
71
+ AI_CONFIDENCE_CLASSIFICATION_FEATURE,
72
+ AI_CODE_FIX_FEATURE,
73
+ AI_INSIGHT_TRIAGE_FEATURE,
74
+ RUNBOOK_AI_STEP_FEATURE,
75
+ WORKFLOW_AI_FEATURE,
76
+ ]) {
77
+ expect(AUTONOMOUS_AI_FEATURES).toContain(feature);
78
+ }
79
+ });
80
+
81
+ /*
82
+ * The budget hole this guards: the six labels below were persisted by the
83
+ * pre-rename code. Dropping them from the match-list stops LlmLog rows that
84
+ * ALREADY carry them from counting — during the deploy window (old and new
85
+ * pods write different labels into the same UTC day) and for any row the
86
+ * backfill migration missed. A future cleanup must fail here and go read the
87
+ * retention argument in AIService before deleting them.
88
+ */
89
+ test("the six legacy Sentinel labels are still counted by the budget", () => {
90
+ expect(LEGACY_AUTONOMOUS_AI_FEATURES).toEqual([
91
+ "Sentinel Incident Investigation",
92
+ "Sentinel Alert Investigation",
93
+ "Sentinel Investigation Grading",
94
+ "Sentinel Confidence Classification",
95
+ "Sentinel Code Fix",
96
+ "Sentinel Insight Triage",
97
+ ]);
98
+
99
+ for (const legacyFeature of LEGACY_AUTONOMOUS_AI_FEATURES) {
100
+ expect(AUTONOMOUS_AI_FEATURES).toContain(legacyFeature);
101
+ }
102
+ });
103
+
104
+ /*
105
+ * Nothing but the constants and the legacy aliases may reach the list — a
106
+ * raw literal here is how a writer and the budget silently drift apart.
107
+ */
108
+ test("the match-list is exactly the current labels plus the legacy aliases", () => {
109
+ expect([...AUTONOMOUS_AI_FEATURES].sort()).toEqual(
110
+ [
111
+ AI_INCIDENT_INVESTIGATION_FEATURE,
112
+ AI_ALERT_INVESTIGATION_FEATURE,
113
+ AI_INVESTIGATION_GRADING_FEATURE,
114
+ AI_CONFIDENCE_CLASSIFICATION_FEATURE,
115
+ AI_CODE_FIX_FEATURE,
116
+ AI_INSIGHT_TRIAGE_FEATURE,
117
+ RUNBOOK_AI_STEP_FEATURE,
118
+ WORKFLOW_AI_FEATURE,
119
+ ...LEGACY_AUTONOMOUS_AI_FEATURES,
120
+ ].sort(),
121
+ );
122
+ });
123
+ });
124
+
35
125
  describe("AIService.getAutonomousDailyBudgetStatus", () => {
36
126
  const projectId: ObjectID = ObjectID.generate();
37
127
 
@@ -107,7 +197,7 @@ describe("AIService.getAutonomousDailyBudgetStatus", () => {
107
197
  });
108
198
  });
109
199
 
110
- describe("SentinelInvestigationQueue budget skip", () => {
200
+ describe("AIInvestigationQueue budget skip", () => {
111
201
  afterEach(() => {
112
202
  jest.restoreAllMocks();
113
203
  });
@@ -120,7 +210,7 @@ describe("SentinelInvestigationQueue budget skip", () => {
120
210
  });
121
211
  const create: jest.SpyInstance = jest.spyOn(AIRunService, "create");
122
212
 
123
- await SentinelInvestigationQueue.enqueue({
213
+ await AIInvestigationQueue.enqueue({
124
214
  projectId: ObjectID.generate(),
125
215
  subjectAlertId: ObjectID.generate(),
126
216
  });
@@ -134,7 +224,7 @@ describe("SentinelInvestigationQueue budget skip", () => {
134
224
  .mockRejectedValue(new Error("db down"));
135
225
  const create: jest.SpyInstance = jest.spyOn(AIRunService, "create");
136
226
 
137
- await SentinelInvestigationQueue.enqueue({
227
+ await AIInvestigationQueue.enqueue({
138
228
  projectId: ObjectID.generate(),
139
229
  subjectAlertId: ObjectID.generate(),
140
230
  });
@@ -161,7 +251,7 @@ describe("SentinelInvestigationQueue budget skip", () => {
161
251
  "attemptStatusTransition",
162
252
  );
163
253
 
164
- await SentinelInvestigationQueue.processRun({
254
+ await AIInvestigationQueue.processRun({
165
255
  id: ObjectID.generate(),
166
256
  projectId: ObjectID.generate(),
167
257
  attemptCount: 0,