@oneuptime/common 11.5.4 → 11.5.6

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 (539) 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/Models/DatabaseModels/User.ts +47 -0
  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/1784048917994-AddCreatedByUserToUser.ts +23 -0
  38. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +32 -0
  39. package/Server/Infrastructure/Queue.ts +82 -4
  40. package/Server/Infrastructure/Semaphore.ts +62 -1
  41. package/Server/Middleware/MasterAdminAuthorization.ts +37 -0
  42. package/Server/Middleware/ProjectAuthorization.ts +40 -15
  43. package/Server/Services/AIAgentService.ts +32 -0
  44. package/Server/Services/AIAgentTaskPullRequestService.ts +117 -0
  45. package/Server/Services/AIInsightService.ts +174 -0
  46. package/Server/Services/AIRunEventService.ts +63 -0
  47. package/Server/Services/AIRunService.ts +259 -1
  48. package/Server/Services/AIService.ts +249 -7
  49. package/Server/Services/AlertService.ts +4 -4
  50. package/Server/Services/CodeRepositoryService.ts +209 -0
  51. package/Server/Services/GlobalConfigService.ts +148 -0
  52. package/Server/Services/IncidentService.ts +183 -38
  53. package/Server/Services/IncidentStateTimelineService.ts +24 -4
  54. package/Server/Services/Index.ts +4 -4
  55. package/Server/Services/{AIAgentTaskLogService.ts → InstanceHealthLogService.ts} +1 -1
  56. package/Server/Services/LlmLogService.ts +27 -0
  57. package/Server/Services/LlmProviderService.ts +108 -0
  58. package/Server/Services/MetricBaselineService.ts +123 -0
  59. package/Server/Services/MonitorService.ts +15 -0
  60. package/Server/Services/TeamMemberService.ts +2 -0
  61. package/Server/Services/TelemetryExceptionService.ts +323 -116
  62. package/Server/Services/TraceAggregationService.ts +176 -0
  63. package/Server/Services/UserService.ts +10 -0
  64. package/Server/Types/Workflow/ComponentCode.ts +6 -0
  65. package/Server/Types/Workflow/Components/AI/GenerateText.ts +326 -0
  66. package/Server/Types/Workflow/Components/Index.ts +2 -0
  67. package/Server/Utils/AI/Chat/ObservabilityAssistant.ts +1 -1
  68. package/Server/Utils/AI/CodeFix/CodeAgentWorkspaceGuard.ts +71 -0
  69. package/Server/Utils/AI/CodeFix/CodeFixAgentCompletion.ts +243 -0
  70. package/Server/Utils/AI/CodeFix/CodeFixRunQueue.ts +131 -0
  71. package/Server/Utils/AI/CodeFix/FixRunBudget.ts +148 -0
  72. package/Server/Utils/AI/CodeFix/OpenPullRequestCap.ts +117 -0
  73. package/Server/Utils/AI/Eval/EvalCorpus.ts +369 -0
  74. package/Server/Utils/AI/Eval/EvalScores.ts +172 -0
  75. package/Server/Utils/AI/Eval/ReplayInvestigation.ts +87 -0
  76. package/Server/Utils/AI/PerfEvidence/SpanTreeAnalyzer.ts +676 -0
  77. package/Server/Utils/AI/{Sentinel/SentinelInvestigationEngine.ts → SRE/AIInvestigationEngine.ts} +58 -37
  78. package/Server/Utils/AI/{Sentinel/SentinelMemory.ts → SRE/AIMemory.ts} +3 -3
  79. package/Server/Utils/AI/{Sentinel → SRE}/AlertInvestigationRunner.ts +50 -20
  80. package/Server/Utils/AI/SRE/ConfidenceSignal.ts +293 -0
  81. package/Server/Utils/AI/SRE/FixFromIncidentTaskTrigger.ts +115 -0
  82. package/Server/Utils/AI/SRE/FixPerformanceTaskTrigger.ts +223 -0
  83. package/Server/Utils/AI/{Sentinel → SRE}/IncidentInvestigationRunner.ts +71 -21
  84. package/Server/Utils/AI/{Sentinel → SRE}/IncidentPostmortemRunner.ts +8 -8
  85. package/Server/Utils/AI/SRE/Insights/Detectors/ErrorLogSpikeDetector.ts +364 -0
  86. package/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.ts +317 -0
  87. package/Server/Utils/AI/SRE/Insights/Detectors/Index.ts +27 -0
  88. package/Server/Utils/AI/SRE/Insights/Detectors/MetricDriftDetector.ts +221 -0
  89. package/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.ts +238 -0
  90. package/Server/Utils/AI/SRE/Insights/Detectors/TraceLatencyRegressionDetector.ts +521 -0
  91. package/Server/Utils/AI/SRE/Insights/FixRouting.ts +242 -0
  92. package/Server/Utils/AI/SRE/Insights/InsightScanner.ts +290 -0
  93. package/Server/Utils/AI/SRE/Insights/InsightStore.ts +283 -0
  94. package/Server/Utils/AI/SRE/Insights/InsightTriageRunner.ts +242 -0
  95. package/Server/Utils/AI/SRE/Insights/Triage.ts +162 -0
  96. package/Server/Utils/AI/SRE/Insights/Types.ts +49 -0
  97. package/Server/Utils/AI/SRE/InstrumentationTaskTrigger.ts +212 -0
  98. package/Server/Utils/AI/SRE/InvestigationGrader.ts +282 -0
  99. package/Server/Utils/AI/{Sentinel → SRE}/InvestigationQueue.ts +114 -19
  100. package/Server/Utils/AI/{Sentinel → SRE}/README.md +4 -4
  101. package/Server/Utils/AI/SRE/SubjectCodeFixRun.ts +172 -0
  102. package/Server/Utils/AI/Toolbox/{SentinelActionTools.ts → AIActionTools.ts} +22 -1
  103. package/Server/Utils/AI/Toolbox/Index.ts +2 -2
  104. package/Server/Utils/AnalyticsDatabase/ClickhouseCapacity.ts +526 -0
  105. package/Server/Utils/CodeRepository/GitHub/GitHub.ts +319 -1
  106. package/Server/Utils/CodeRepository/ServiceRepoLinkSuggester.ts +221 -0
  107. package/Server/Utils/CodeRepository/StackTraceRepoResolver.ts +571 -0
  108. package/Server/Utils/Execute.ts +2 -1
  109. package/Server/Utils/LLM/LLMService.ts +160 -30
  110. package/Server/Utils/Monitor/Criteria/SqlMonitorCriteria.ts +152 -0
  111. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +29 -0
  112. package/Server/Utils/Monitor/MonitorCriteriaExpectationBuilder.ts +16 -6
  113. package/Server/Utils/Monitor/MonitorCriteriaMessageBuilder.ts +14 -0
  114. package/Server/Utils/Monitor/MonitorCriteriaMessageFormatter.ts +14 -3
  115. package/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.ts +130 -12
  116. package/Tests/Server/Infrastructure/Queue.test.ts +227 -0
  117. package/Tests/Server/Infrastructure/SemaphorePermit.test.ts +159 -0
  118. package/Tests/Server/Services/AIAgentTaskPullRequestOutcomeStats.test.ts +154 -0
  119. package/Tests/Server/Services/AIInsightService.test.ts +324 -0
  120. package/Tests/Server/Services/AIRunCodeFixClaim.test.ts +401 -0
  121. package/Tests/Server/Services/AIRunHumanVerdict.test.ts +161 -0
  122. package/Tests/Server/Services/AIServiceDailyBudget.test.ts +95 -5
  123. package/Tests/Server/Services/AIServiceProjectAccess.test.ts +259 -0
  124. package/Tests/Server/Services/FixFromIncidentTaskTrigger.test.ts +249 -0
  125. package/Tests/Server/Services/FixPerformanceTaskTrigger.test.ts +274 -0
  126. package/Tests/Server/Services/GlobalConfigService.test.ts +80 -0
  127. package/Tests/Server/Services/IncidentInternalNoteAnnouncement.test.ts +1 -1
  128. package/Tests/Server/Services/InstrumentationTaskTrigger.test.ts +313 -0
  129. package/Tests/Server/Services/LlmProviderProjectOwned.test.ts +132 -0
  130. package/Tests/Server/Services/TelemetryExceptionAIFixReadiness.test.ts +405 -0
  131. package/Tests/Server/Services/TelemetryExceptionCodeFixRun.test.ts +322 -0
  132. package/Tests/Server/Services/TraceServiceLatencyProfile.test.ts +278 -0
  133. package/Tests/Server/Types/Workflow/Components/AIGenerateText.test.ts +722 -0
  134. package/Tests/Server/Utils/AI/{SentinelAlertGating.test.ts → AIAlertGating.test.ts} +19 -19
  135. package/Tests/Server/Utils/AI/AIConfidenceSignal.test.ts +362 -0
  136. package/Tests/Server/Utils/AI/{SentinelInvestigationQueue.test.ts → AIInvestigationQueue.test.ts} +19 -19
  137. package/Tests/Server/Utils/AI/CodeAgentWorkspaceGuard.test.ts +138 -0
  138. package/Tests/Server/Utils/AI/CodeFixAgentCompletion.test.ts +335 -0
  139. package/Tests/Server/Utils/AI/CodeFixRunQueue.test.ts +134 -0
  140. package/Tests/Server/Utils/AI/EvalCorpus.test.ts +209 -0
  141. package/Tests/Server/Utils/AI/EvalScores.test.ts +343 -0
  142. package/Tests/Server/Utils/AI/FixRunBudget.test.ts +218 -0
  143. package/Tests/Server/Utils/AI/Insights/ErrorLogSpikeDetector.test.ts +437 -0
  144. package/Tests/Server/Utils/AI/Insights/ExceptionSpikeDetector.test.ts +287 -0
  145. package/Tests/Server/Utils/AI/Insights/InsightDetectorsIndex.test.ts +34 -0
  146. package/Tests/Server/Utils/AI/Insights/InsightFixRouting.test.ts +572 -0
  147. package/Tests/Server/Utils/AI/Insights/InsightNeverThrowsHardening.test.ts +344 -0
  148. package/Tests/Server/Utils/AI/Insights/InsightScanner.test.ts +720 -0
  149. package/Tests/Server/Utils/AI/Insights/InsightStore.test.ts +467 -0
  150. package/Tests/Server/Utils/AI/Insights/InsightStoreHardening.test.ts +370 -0
  151. package/Tests/Server/Utils/AI/Insights/InsightTriage.test.ts +210 -0
  152. package/Tests/Server/Utils/AI/Insights/InsightTriageRunner.test.ts +221 -0
  153. package/Tests/Server/Utils/AI/Insights/InvestigationQueueInsightSubject.test.ts +328 -0
  154. package/Tests/Server/Utils/AI/Insights/MetricBaselineDrift.test.ts +182 -0
  155. package/Tests/Server/Utils/AI/Insights/MetricDriftDetector.test.ts +280 -0
  156. package/Tests/Server/Utils/AI/Insights/NewExceptionDetector.test.ts +259 -0
  157. package/Tests/Server/Utils/AI/Insights/TraceLatencyRegressionDetector.test.ts +770 -0
  158. package/Tests/Server/Utils/AI/InvestigationGrader.test.ts +343 -0
  159. package/Tests/Server/Utils/AI/LLMServiceRequestPolicy.test.ts +307 -0
  160. package/Tests/Server/Utils/AI/OpenPullRequestCap.test.ts +170 -0
  161. package/Tests/Server/Utils/AI/SpanTreeAnalyzer.test.ts +559 -0
  162. package/Tests/Server/Utils/AnalyticsDatabase/ClickhouseCapacity.test.ts +158 -0
  163. package/Tests/Server/Utils/GitHubCheckRunsConclusion.test.ts +100 -0
  164. package/Tests/Server/Utils/GitHubPullRequestStateMapping.test.ts +50 -0
  165. package/Tests/Server/Utils/Monitor/Criteria/SqlMonitorCriteria.test.ts +266 -0
  166. package/Tests/Server/Utils/Monitor/MonitorCriteriaExpectationBuilderUnits.test.ts +553 -0
  167. package/Tests/Server/Utils/Monitor/MonitorCriteriaMessageBuilderUnits.test.ts +590 -0
  168. package/Tests/Server/Utils/Monitor/MonitorCriteriaMessageFormatterUnits.test.ts +254 -0
  169. package/Tests/Server/Utils/Monitor/MonitorCriteriaObservationBuilderUnits.test.ts +821 -0
  170. package/Tests/Server/Utils/ServiceRepoLinkSuggester.test.ts +167 -0
  171. package/Tests/Server/Utils/StackTraceRepoResolver.test.ts +527 -0
  172. package/Tests/Types/AI/AIChatPermissionMode.test.ts +112 -0
  173. package/Tests/Types/AI/CodeFixTaskType.test.ts +152 -0
  174. package/Tests/Types/AI/FixPullRequestCiStatus.test.ts +181 -0
  175. package/Tests/Types/Monitor/MonitorStepSqlMonitor.test.ts +110 -0
  176. package/Tests/Types/Monitor/SqlDatabaseType.test.ts +55 -0
  177. package/Tests/Types/Workflow/AIGenerateTextMetadata.test.ts +180 -0
  178. package/Tests/UI/Components/TableBulkCsvExport.test.tsx +168 -0
  179. package/Tests/UI/Utils/TableColumnsToCsv.test.ts +523 -0
  180. package/Types/AI/AIChatTypes.ts +8 -0
  181. package/Types/AI/AIInsightEvidence.ts +77 -0
  182. package/Types/AI/AIInsightHumanVerdict.ts +15 -0
  183. package/Types/AI/AIInsightSeverity.ts +13 -0
  184. package/Types/AI/AIInsightStatus.ts +38 -0
  185. package/Types/AI/AIInsightType.ts +41 -0
  186. package/Types/AI/AIRunAutoGrade.ts +18 -0
  187. package/Types/AI/AIRunEventType.ts +5 -0
  188. package/Types/AI/AIRunHumanVerdict.ts +17 -0
  189. package/Types/AI/AIRunType.ts +6 -0
  190. package/Types/AI/CodeFixTaskContext.ts +88 -0
  191. package/Types/AI/CodeFixTaskType.ts +132 -0
  192. package/Types/AI/FixPullRequestCiStatus.ts +132 -0
  193. package/Types/BaseDatabase/AggregationIntervalUtil.ts +67 -0
  194. package/Types/Incident/IncidentMetricType.ts +7 -0
  195. package/Types/Monitor/CriteriaFilter.ts +8 -0
  196. package/Types/Monitor/MonitorCriteriaInstance.ts +67 -0
  197. package/Types/Monitor/MonitorStep.ts +38 -0
  198. package/Types/Monitor/MonitorStepSqlMonitor.ts +141 -0
  199. package/Types/Monitor/MonitorType.ts +17 -0
  200. package/Types/Monitor/SqlDatabaseType.ts +49 -0
  201. package/Types/Monitor/SqlMonitor/SqlMonitorResponse.ts +28 -0
  202. package/Types/Permission.ts +11 -95
  203. package/Types/Probe/ProbeMonitorResponse.ts +2 -0
  204. package/Types/Runbook/RunbookStep.ts +26 -2
  205. package/Types/Runbook/RunbookStepType.ts +1 -0
  206. package/Types/Workflow/Component.ts +13 -0
  207. package/Types/Workflow/ComponentID.ts +1 -0
  208. package/Types/Workflow/Components/AI.ts +148 -0
  209. package/Types/Workflow/Components.ts +8 -0
  210. package/UI/Components/AI/GenerateFromAIModal.tsx +1 -1
  211. package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +11 -0
  212. package/UI/Components/MoreMenu/MoreMenu.tsx +1 -1
  213. package/UI/Components/Table/Table.tsx +38 -2
  214. package/UI/Utils/TableColumnsToCsv.ts +385 -0
  215. package/Utils/Monitor/MonitorMetricType.ts +1 -0
  216. package/build/dist/Models/DatabaseModels/AIAgentTaskPullRequest.js +59 -45
  217. package/build/dist/Models/DatabaseModels/AIAgentTaskPullRequest.js.map +1 -1
  218. package/build/dist/Models/DatabaseModels/AIInsight.js +795 -0
  219. package/build/dist/Models/DatabaseModels/AIInsight.js.map +1 -0
  220. package/build/dist/Models/DatabaseModels/AIRun.js +274 -0
  221. package/build/dist/Models/DatabaseModels/AIRun.js.map +1 -1
  222. package/build/dist/Models/DatabaseModels/CodeRepository.js +43 -0
  223. package/build/dist/Models/DatabaseModels/CodeRepository.js.map +1 -1
  224. package/build/dist/Models/DatabaseModels/GlobalConfig.js +110 -0
  225. package/build/dist/Models/DatabaseModels/GlobalConfig.js.map +1 -1
  226. package/build/dist/Models/DatabaseModels/Index.js +4 -8
  227. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  228. package/build/dist/Models/DatabaseModels/InstanceHealthLog.js +304 -0
  229. package/build/dist/Models/DatabaseModels/InstanceHealthLog.js.map +1 -0
  230. package/build/dist/Models/DatabaseModels/LlmLog.js +35 -0
  231. package/build/dist/Models/DatabaseModels/LlmLog.js.map +1 -1
  232. package/build/dist/Models/DatabaseModels/Project.js +127 -6
  233. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  234. package/build/dist/Models/DatabaseModels/Runbook.js +1 -1
  235. package/build/dist/Models/DatabaseModels/Runbook.js.map +1 -1
  236. package/build/dist/Models/DatabaseModels/User.js +46 -0
  237. package/build/dist/Models/DatabaseModels/User.js.map +1 -1
  238. package/build/dist/Server/API/AIAgentDataAPI.js +568 -85
  239. package/build/dist/Server/API/AIAgentDataAPI.js.map +1 -1
  240. package/build/dist/Server/API/AIAgentTaskAPI.js +100 -44
  241. package/build/dist/Server/API/AIAgentTaskAPI.js.map +1 -1
  242. package/build/dist/Server/API/AIAgentTaskLogAPI.js +49 -25
  243. package/build/dist/Server/API/AIAgentTaskLogAPI.js.map +1 -1
  244. package/build/dist/Server/API/AIAgentTaskPullRequestAPI.js +27 -0
  245. package/build/dist/Server/API/AIAgentTaskPullRequestAPI.js.map +1 -1
  246. package/build/dist/Server/API/AIInsightAPI.js +140 -0
  247. package/build/dist/Server/API/AIInsightAPI.js.map +1 -0
  248. package/build/dist/Server/API/AIInvestigationAPI.js +257 -1
  249. package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
  250. package/build/dist/Server/API/CodeFixRunAPI.js +181 -0
  251. package/build/dist/Server/API/CodeFixRunAPI.js.map +1 -0
  252. package/build/dist/Server/API/GitHubAPI.js +164 -2
  253. package/build/dist/Server/API/GitHubAPI.js.map +1 -1
  254. package/build/dist/Server/API/TelemetryExceptionAPI.js +148 -43
  255. package/build/dist/Server/API/TelemetryExceptionAPI.js.map +1 -1
  256. package/build/dist/Server/EnvironmentConfig.js +1 -1
  257. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  258. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783943300000-DropServiceCodeRepository.js +23 -0
  259. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783943300000-DropServiceCodeRepository.js.map +1 -0
  260. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783947444597-CodeFixRunsOnAIRun.js +32 -0
  261. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783947444597-CodeFixRunsOnAIRun.js.map +1 -0
  262. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783950962813-AddCodeFixTaskType.js +16 -0
  263. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783950962813-AddCodeFixTaskType.js.map +1 -0
  264. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783954040984-AddInstrumentationFixTasksFlag.js +16 -0
  265. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783954040984-AddInstrumentationFixTasksFlag.js.map +1 -0
  266. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783957160597-MigrationName.js +24 -0
  267. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783957160597-MigrationName.js.map +1 -0
  268. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783958542237-AddTaskContextToAIRun.js +16 -0
  269. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783958542237-AddTaskContextToAIRun.js.map +1 -0
  270. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783965945957-AddInvestigationVerdictAndGrade.js +24 -0
  271. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783965945957-AddInvestigationVerdictAndGrade.js.map +1 -0
  272. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783970619301-AddFixGuardrailColumns.js +24 -0
  273. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783970619301-AddFixGuardrailColumns.js.map +1 -0
  274. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783970619302-DropLegacyAIAgentTaskTables.js +24 -0
  275. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783970619302-DropLegacyAIAgentTaskTables.js.map +1 -0
  276. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783977781677-AddCiStatusToFixPullRequests.js +18 -0
  277. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783977781677-AddCiStatusToFixPullRequests.js.map +1 -0
  278. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783990000000-AddCompletionTokensToLlmLog.js +18 -0
  279. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783990000000-AddCompletionTokensToLlmLog.js.map +1 -0
  280. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784010274993-AddSentinelInsight.js +32 -0
  281. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784010274993-AddSentinelInsight.js.map +1 -0
  282. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784010274994-AddSentinelInsightFlags.js +18 -0
  283. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784010274994-AddSentinelInsightFlags.js.map +1 -0
  284. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784030612266-RenameSentinelToAI.js +125 -0
  285. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784030612266-RenameSentinelToAI.js.map +1 -0
  286. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784033837629-MigrationName.js +62 -0
  287. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784033837629-MigrationName.js.map +1 -0
  288. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784048917994-AddCreatedByUserToUser.js +18 -0
  289. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784048917994-AddCreatedByUserToUser.js.map +1 -0
  290. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +32 -0
  291. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  292. package/build/dist/Server/Infrastructure/Queue.js +73 -3
  293. package/build/dist/Server/Infrastructure/Queue.js.map +1 -1
  294. package/build/dist/Server/Infrastructure/Semaphore.js +44 -1
  295. package/build/dist/Server/Infrastructure/Semaphore.js.map +1 -1
  296. package/build/dist/Server/Middleware/MasterAdminAuthorization.js +26 -0
  297. package/build/dist/Server/Middleware/MasterAdminAuthorization.js.map +1 -1
  298. package/build/dist/Server/Middleware/ProjectAuthorization.js +40 -14
  299. package/build/dist/Server/Middleware/ProjectAuthorization.js.map +1 -1
  300. package/build/dist/Server/Services/AIAgentService.js +29 -0
  301. package/build/dist/Server/Services/AIAgentService.js.map +1 -1
  302. package/build/dist/Server/Services/AIAgentTaskPullRequestService.js +78 -0
  303. package/build/dist/Server/Services/AIAgentTaskPullRequestService.js.map +1 -1
  304. package/build/dist/Server/Services/AIInsightService.js +164 -0
  305. package/build/dist/Server/Services/AIInsightService.js.map +1 -0
  306. package/build/dist/Server/Services/AIRunEventService.js +49 -0
  307. package/build/dist/Server/Services/AIRunEventService.js.map +1 -1
  308. package/build/dist/Server/Services/AIRunService.js +221 -0
  309. package/build/dist/Server/Services/AIRunService.js.map +1 -1
  310. package/build/dist/Server/Services/AIService.js +198 -11
  311. package/build/dist/Server/Services/AIService.js.map +1 -1
  312. package/build/dist/Server/Services/AlertService.js +4 -4
  313. package/build/dist/Server/Services/AlertService.js.map +1 -1
  314. package/build/dist/Server/Services/CodeRepositoryService.js +180 -0
  315. package/build/dist/Server/Services/CodeRepositoryService.js.map +1 -1
  316. package/build/dist/Server/Services/GlobalConfigService.js +84 -0
  317. package/build/dist/Server/Services/GlobalConfigService.js.map +1 -1
  318. package/build/dist/Server/Services/IncidentService.js +149 -37
  319. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  320. package/build/dist/Server/Services/IncidentStateTimelineService.js +24 -4
  321. package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
  322. package/build/dist/Server/Services/Index.js +4 -4
  323. package/build/dist/Server/Services/Index.js.map +1 -1
  324. package/build/dist/Server/Services/{AIAgentTaskLogService.js → InstanceHealthLogService.js} +2 -2
  325. package/build/dist/Server/Services/InstanceHealthLogService.js.map +1 -0
  326. package/build/dist/Server/Services/LlmLogService.js +23 -0
  327. package/build/dist/Server/Services/LlmLogService.js.map +1 -1
  328. package/build/dist/Server/Services/LlmProviderService.js +96 -0
  329. package/build/dist/Server/Services/LlmProviderService.js.map +1 -1
  330. package/build/dist/Server/Services/MetricBaselineService.js +65 -0
  331. package/build/dist/Server/Services/MetricBaselineService.js.map +1 -1
  332. package/build/dist/Server/Services/MonitorService.js +9 -1
  333. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  334. package/build/dist/Server/Services/TeamMemberService.js +2 -0
  335. package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
  336. package/build/dist/Server/Services/TelemetryExceptionService.js +243 -82
  337. package/build/dist/Server/Services/TelemetryExceptionService.js.map +1 -1
  338. package/build/dist/Server/Services/TraceAggregationService.js +124 -0
  339. package/build/dist/Server/Services/TraceAggregationService.js.map +1 -1
  340. package/build/dist/Server/Services/UserService.js +8 -0
  341. package/build/dist/Server/Services/UserService.js.map +1 -1
  342. package/build/dist/Server/Types/Workflow/ComponentCode.js.map +1 -1
  343. package/build/dist/Server/Types/Workflow/Components/AI/GenerateText.js +240 -0
  344. package/build/dist/Server/Types/Workflow/Components/AI/GenerateText.js.map +1 -0
  345. package/build/dist/Server/Types/Workflow/Components/Index.js +2 -0
  346. package/build/dist/Server/Types/Workflow/Components/Index.js.map +1 -1
  347. package/build/dist/Server/Utils/AI/CodeFix/CodeAgentWorkspaceGuard.js +48 -0
  348. package/build/dist/Server/Utils/AI/CodeFix/CodeAgentWorkspaceGuard.js.map +1 -0
  349. package/build/dist/Server/Utils/AI/CodeFix/CodeFixAgentCompletion.js +174 -0
  350. package/build/dist/Server/Utils/AI/CodeFix/CodeFixAgentCompletion.js.map +1 -0
  351. package/build/dist/Server/Utils/AI/CodeFix/CodeFixRunQueue.js +126 -0
  352. package/build/dist/Server/Utils/AI/CodeFix/CodeFixRunQueue.js.map +1 -0
  353. package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js +131 -0
  354. package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js.map +1 -0
  355. package/build/dist/Server/Utils/AI/CodeFix/OpenPullRequestCap.js +99 -0
  356. package/build/dist/Server/Utils/AI/CodeFix/OpenPullRequestCap.js.map +1 -0
  357. package/build/dist/Server/Utils/AI/Eval/EvalCorpus.js +245 -0
  358. package/build/dist/Server/Utils/AI/Eval/EvalCorpus.js.map +1 -0
  359. package/build/dist/Server/Utils/AI/Eval/EvalScores.js +83 -0
  360. package/build/dist/Server/Utils/AI/Eval/EvalScores.js.map +1 -0
  361. package/build/dist/Server/Utils/AI/Eval/ReplayInvestigation.js +12 -0
  362. package/build/dist/Server/Utils/AI/Eval/ReplayInvestigation.js.map +1 -0
  363. package/build/dist/Server/Utils/AI/PerfEvidence/SpanTreeAnalyzer.js +439 -0
  364. package/build/dist/Server/Utils/AI/PerfEvidence/SpanTreeAnalyzer.js.map +1 -0
  365. package/build/dist/Server/Utils/AI/{Sentinel/SentinelInvestigationEngine.js → SRE/AIInvestigationEngine.js} +47 -31
  366. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -0
  367. package/build/dist/Server/Utils/AI/{Sentinel/SentinelMemory.js → SRE/AIMemory.js} +5 -5
  368. package/build/dist/Server/Utils/AI/SRE/AIMemory.js.map +1 -0
  369. package/build/dist/Server/Utils/AI/{Sentinel → SRE}/AlertInvestigationRunner.js +42 -19
  370. package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js.map +1 -0
  371. package/build/dist/Server/Utils/AI/SRE/ConfidenceSignal.js +226 -0
  372. package/build/dist/Server/Utils/AI/SRE/ConfidenceSignal.js.map +1 -0
  373. package/build/dist/Server/Utils/AI/SRE/FixFromIncidentTaskTrigger.js +100 -0
  374. package/build/dist/Server/Utils/AI/SRE/FixFromIncidentTaskTrigger.js.map +1 -0
  375. package/build/dist/Server/Utils/AI/SRE/FixPerformanceTaskTrigger.js +174 -0
  376. package/build/dist/Server/Utils/AI/SRE/FixPerformanceTaskTrigger.js.map +1 -0
  377. package/build/dist/Server/Utils/AI/{Sentinel → SRE}/IncidentInvestigationRunner.js +60 -22
  378. package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js.map +1 -0
  379. package/build/dist/Server/Utils/AI/{Sentinel → SRE}/IncidentPostmortemRunner.js +9 -9
  380. package/build/dist/Server/Utils/AI/SRE/IncidentPostmortemRunner.js.map +1 -0
  381. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ErrorLogSpikeDetector.js +268 -0
  382. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ErrorLogSpikeDetector.js.map +1 -0
  383. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.js +226 -0
  384. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/ExceptionSpikeDetector.js.map +1 -0
  385. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/Index.js +26 -0
  386. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/Index.js.map +1 -0
  387. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/MetricDriftDetector.js +159 -0
  388. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/MetricDriftDetector.js.map +1 -0
  389. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.js +177 -0
  390. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/NewExceptionDetector.js.map +1 -0
  391. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/TraceLatencyRegressionDetector.js +384 -0
  392. package/build/dist/Server/Utils/AI/SRE/Insights/Detectors/TraceLatencyRegressionDetector.js.map +1 -0
  393. package/build/dist/Server/Utils/AI/SRE/Insights/FixRouting.js +180 -0
  394. package/build/dist/Server/Utils/AI/SRE/Insights/FixRouting.js.map +1 -0
  395. package/build/dist/Server/Utils/AI/SRE/Insights/InsightScanner.js +269 -0
  396. package/build/dist/Server/Utils/AI/SRE/Insights/InsightScanner.js.map +1 -0
  397. package/build/dist/Server/Utils/AI/SRE/Insights/InsightStore.js +231 -0
  398. package/build/dist/Server/Utils/AI/SRE/Insights/InsightStore.js.map +1 -0
  399. package/build/dist/Server/Utils/AI/SRE/Insights/InsightTriageRunner.js +206 -0
  400. package/build/dist/Server/Utils/AI/SRE/Insights/InsightTriageRunner.js.map +1 -0
  401. package/build/dist/Server/Utils/AI/SRE/Insights/Triage.js +121 -0
  402. package/build/dist/Server/Utils/AI/SRE/Insights/Triage.js.map +1 -0
  403. package/build/dist/Server/Utils/AI/SRE/Insights/Types.js +2 -0
  404. package/build/dist/Server/Utils/AI/SRE/Insights/Types.js.map +1 -0
  405. package/build/dist/Server/Utils/AI/SRE/InstrumentationTaskTrigger.js +148 -0
  406. package/build/dist/Server/Utils/AI/SRE/InstrumentationTaskTrigger.js.map +1 -0
  407. package/build/dist/Server/Utils/AI/SRE/InvestigationGrader.js +231 -0
  408. package/build/dist/Server/Utils/AI/SRE/InvestigationGrader.js.map +1 -0
  409. package/build/dist/Server/Utils/AI/{Sentinel → SRE}/InvestigationQueue.js +102 -23
  410. package/build/dist/Server/Utils/AI/SRE/InvestigationQueue.js.map +1 -0
  411. package/build/dist/Server/Utils/AI/SRE/SubjectCodeFixRun.js +167 -0
  412. package/build/dist/Server/Utils/AI/SRE/SubjectCodeFixRun.js.map +1 -0
  413. package/build/dist/Server/Utils/AI/Toolbox/{SentinelActionTools.js → AIActionTools.js} +18 -2
  414. package/build/dist/Server/Utils/AI/Toolbox/AIActionTools.js.map +1 -0
  415. package/build/dist/Server/Utils/AI/Toolbox/Index.js +2 -2
  416. package/build/dist/Server/Utils/AI/Toolbox/Index.js.map +1 -1
  417. package/build/dist/Server/Utils/AnalyticsDatabase/ClickhouseCapacity.js +301 -0
  418. package/build/dist/Server/Utils/AnalyticsDatabase/ClickhouseCapacity.js.map +1 -0
  419. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js +240 -2
  420. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js.map +1 -1
  421. package/build/dist/Server/Utils/CodeRepository/ServiceRepoLinkSuggester.js +127 -0
  422. package/build/dist/Server/Utils/CodeRepository/ServiceRepoLinkSuggester.js.map +1 -0
  423. package/build/dist/Server/Utils/CodeRepository/StackTraceRepoResolver.js +336 -0
  424. package/build/dist/Server/Utils/CodeRepository/StackTraceRepoResolver.js.map +1 -0
  425. package/build/dist/Server/Utils/Execute.js.map +1 -1
  426. package/build/dist/Server/Utils/LLM/LLMService.js +125 -25
  427. package/build/dist/Server/Utils/LLM/LLMService.js.map +1 -1
  428. package/build/dist/Server/Utils/Monitor/Criteria/SqlMonitorCriteria.js +120 -0
  429. package/build/dist/Server/Utils/Monitor/Criteria/SqlMonitorCriteria.js.map +1 -0
  430. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +21 -0
  431. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  432. package/build/dist/Server/Utils/Monitor/MonitorCriteriaExpectationBuilder.js +15 -7
  433. package/build/dist/Server/Utils/Monitor/MonitorCriteriaExpectationBuilder.js.map +1 -1
  434. package/build/dist/Server/Utils/Monitor/MonitorCriteriaMessageBuilder.js +12 -1
  435. package/build/dist/Server/Utils/Monitor/MonitorCriteriaMessageBuilder.js.map +1 -1
  436. package/build/dist/Server/Utils/Monitor/MonitorCriteriaMessageFormatter.js +8 -3
  437. package/build/dist/Server/Utils/Monitor/MonitorCriteriaMessageFormatter.js.map +1 -1
  438. package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js +96 -12
  439. package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js.map +1 -1
  440. package/build/dist/Types/AI/AIInsightEvidence.js +2 -0
  441. package/build/dist/Types/AI/AIInsightEvidence.js.map +1 -0
  442. package/build/dist/Types/AI/AIInsightHumanVerdict.js +16 -0
  443. package/build/dist/Types/AI/AIInsightHumanVerdict.js.map +1 -0
  444. package/build/dist/Types/AI/AIInsightSeverity.js +14 -0
  445. package/build/dist/Types/AI/AIInsightSeverity.js.map +1 -0
  446. package/build/dist/Types/AI/AIInsightStatus.js +36 -0
  447. package/build/dist/Types/AI/AIInsightStatus.js.map +1 -0
  448. package/build/dist/Types/AI/AIInsightType.js +42 -0
  449. package/build/dist/Types/AI/AIInsightType.js.map +1 -0
  450. package/build/dist/Types/AI/AIRunAutoGrade.js +19 -0
  451. package/build/dist/Types/AI/AIRunAutoGrade.js.map +1 -0
  452. package/build/dist/Types/AI/AIRunEventType.js +5 -0
  453. package/build/dist/Types/AI/AIRunEventType.js.map +1 -1
  454. package/build/dist/Types/AI/AIRunHumanVerdict.js +18 -0
  455. package/build/dist/Types/AI/AIRunHumanVerdict.js.map +1 -0
  456. package/build/dist/Types/AI/AIRunType.js +6 -0
  457. package/build/dist/Types/AI/AIRunType.js.map +1 -1
  458. package/build/dist/Types/AI/CodeFixTaskContext.js +29 -0
  459. package/build/dist/Types/AI/CodeFixTaskContext.js.map +1 -0
  460. package/build/dist/Types/AI/CodeFixTaskType.js +122 -0
  461. package/build/dist/Types/AI/CodeFixTaskType.js.map +1 -0
  462. package/build/dist/Types/AI/FixPullRequestCiStatus.js +102 -0
  463. package/build/dist/Types/AI/FixPullRequestCiStatus.js.map +1 -0
  464. package/build/dist/Types/BaseDatabase/AggregationIntervalUtil.js +55 -0
  465. package/build/dist/Types/BaseDatabase/AggregationIntervalUtil.js.map +1 -1
  466. package/build/dist/Types/Incident/IncidentMetricType.js +7 -0
  467. package/build/dist/Types/Incident/IncidentMetricType.js.map +1 -1
  468. package/build/dist/Types/Monitor/CriteriaFilter.js +7 -0
  469. package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
  470. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +62 -0
  471. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
  472. package/build/dist/Types/Monitor/MonitorStep.js +28 -0
  473. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  474. package/build/dist/Types/Monitor/MonitorStepSqlMonitor.js +93 -0
  475. package/build/dist/Types/Monitor/MonitorStepSqlMonitor.js.map +1 -0
  476. package/build/dist/Types/Monitor/MonitorType.js +15 -0
  477. package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
  478. package/build/dist/Types/Monitor/SqlDatabaseType.js +47 -0
  479. package/build/dist/Types/Monitor/SqlDatabaseType.js.map +1 -0
  480. package/build/dist/Types/Monitor/SqlMonitor/SqlMonitorResponse.js +2 -0
  481. package/build/dist/Types/Monitor/SqlMonitor/SqlMonitorResponse.js.map +1 -0
  482. package/build/dist/Types/Permission.js +10 -84
  483. package/build/dist/Types/Permission.js.map +1 -1
  484. package/build/dist/Types/Runbook/RunbookStepType.js +1 -0
  485. package/build/dist/Types/Runbook/RunbookStepType.js.map +1 -1
  486. package/build/dist/Types/Workflow/ComponentID.js +1 -0
  487. package/build/dist/Types/Workflow/ComponentID.js.map +1 -1
  488. package/build/dist/Types/Workflow/Components/AI.js +135 -0
  489. package/build/dist/Types/Workflow/Components/AI.js.map +1 -0
  490. package/build/dist/Types/Workflow/Components.js +7 -0
  491. package/build/dist/Types/Workflow/Components.js.map +1 -1
  492. package/build/dist/UI/Components/AI/GenerateFromAIModal.js +1 -1
  493. package/build/dist/UI/Components/AI/GenerateFromAIModal.js.map +1 -1
  494. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +9 -0
  495. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
  496. package/build/dist/UI/Components/MoreMenu/MoreMenu.js +1 -1
  497. package/build/dist/UI/Components/Table/Table.js +28 -2
  498. package/build/dist/UI/Components/Table/Table.js.map +1 -1
  499. package/build/dist/UI/Utils/TableColumnsToCsv.js +291 -0
  500. package/build/dist/UI/Utils/TableColumnsToCsv.js.map +1 -0
  501. package/build/dist/Utils/Monitor/MonitorMetricType.js +1 -0
  502. package/build/dist/Utils/Monitor/MonitorMetricType.js.map +1 -1
  503. package/package.json +1 -1
  504. package/Models/DatabaseModels/AIAgentTask.ts +0 -660
  505. package/Models/DatabaseModels/AIAgentTaskLog.ts +0 -426
  506. package/Models/DatabaseModels/AIAgentTaskTelemetryException.ts +0 -399
  507. package/Models/DatabaseModels/ServiceCodeRepository.ts +0 -647
  508. package/Server/Services/AIAgentTaskService.ts +0 -240
  509. package/Server/Services/AIAgentTaskTelemetryExceptionService.ts +0 -39
  510. package/Server/Services/ServiceCodeRepositoryService.ts +0 -55
  511. package/Tests/Server/Services/AIAgentTaskServiceClaim.test.ts +0 -146
  512. package/Types/AI/AIAgentTaskMetadata.ts +0 -25
  513. package/Types/AI/AIAgentTaskType.ts +0 -40
  514. package/build/dist/Models/DatabaseModels/AIAgentTask.js +0 -691
  515. package/build/dist/Models/DatabaseModels/AIAgentTask.js.map +0 -1
  516. package/build/dist/Models/DatabaseModels/AIAgentTaskLog.js +0 -447
  517. package/build/dist/Models/DatabaseModels/AIAgentTaskLog.js.map +0 -1
  518. package/build/dist/Models/DatabaseModels/AIAgentTaskTelemetryException.js +0 -415
  519. package/build/dist/Models/DatabaseModels/AIAgentTaskTelemetryException.js.map +0 -1
  520. package/build/dist/Models/DatabaseModels/ServiceCodeRepository.js +0 -665
  521. package/build/dist/Models/DatabaseModels/ServiceCodeRepository.js.map +0 -1
  522. package/build/dist/Server/Services/AIAgentTaskLogService.js.map +0 -1
  523. package/build/dist/Server/Services/AIAgentTaskService.js +0 -217
  524. package/build/dist/Server/Services/AIAgentTaskService.js.map +0 -1
  525. package/build/dist/Server/Services/AIAgentTaskTelemetryExceptionService.js +0 -36
  526. package/build/dist/Server/Services/AIAgentTaskTelemetryExceptionService.js.map +0 -1
  527. package/build/dist/Server/Services/ServiceCodeRepositoryService.js +0 -54
  528. package/build/dist/Server/Services/ServiceCodeRepositoryService.js.map +0 -1
  529. package/build/dist/Server/Utils/AI/Sentinel/AlertInvestigationRunner.js.map +0 -1
  530. package/build/dist/Server/Utils/AI/Sentinel/IncidentInvestigationRunner.js.map +0 -1
  531. package/build/dist/Server/Utils/AI/Sentinel/IncidentPostmortemRunner.js.map +0 -1
  532. package/build/dist/Server/Utils/AI/Sentinel/InvestigationQueue.js.map +0 -1
  533. package/build/dist/Server/Utils/AI/Sentinel/SentinelInvestigationEngine.js.map +0 -1
  534. package/build/dist/Server/Utils/AI/Sentinel/SentinelMemory.js.map +0 -1
  535. package/build/dist/Server/Utils/AI/Toolbox/SentinelActionTools.js.map +0 -1
  536. package/build/dist/Types/AI/AIAgentTaskMetadata.js +0 -6
  537. package/build/dist/Types/AI/AIAgentTaskMetadata.js.map +0 -1
  538. package/build/dist/Types/AI/AIAgentTaskType.js +0 -29
  539. package/build/dist/Types/AI/AIAgentTaskType.js.map +0 -1
@@ -0,0 +1,720 @@
1
+ import InsightScanner from "../../../../../Server/Utils/AI/SRE/Insights/InsightScanner";
2
+ import InsightStore, {
3
+ UpsertCandidatesResult,
4
+ } from "../../../../../Server/Utils/AI/SRE/Insights/InsightStore";
5
+ import InsightDetectors from "../../../../../Server/Utils/AI/SRE/Insights/Detectors/Index";
6
+ import InsightFixRouting from "../../../../../Server/Utils/AI/SRE/Insights/FixRouting";
7
+ import InsightTriage from "../../../../../Server/Utils/AI/SRE/Insights/Triage";
8
+ import {
9
+ InsightCandidate,
10
+ InsightDetector,
11
+ InsightScanContext,
12
+ } from "../../../../../Server/Utils/AI/SRE/Insights/Types";
13
+ import FixRunBudget, {
14
+ FixRunBudgetDecision,
15
+ } from "../../../../../Server/Utils/AI/CodeFix/FixRunBudget";
16
+ import ProjectService from "../../../../../Server/Services/ProjectService";
17
+ import AIInsightService from "../../../../../Server/Services/AIInsightService";
18
+ import TelemetryExceptionService from "../../../../../Server/Services/TelemetryExceptionService";
19
+ import AIRunService from "../../../../../Server/Services/AIRunService";
20
+ import Project from "../../../../../Models/DatabaseModels/Project";
21
+ import AIInsight from "../../../../../Models/DatabaseModels/AIInsight";
22
+ import AIInsightStatus from "../../../../../Types/AI/AIInsightStatus";
23
+ import AIInsightType from "../../../../../Types/AI/AIInsightType";
24
+ import AIInsightSeverity from "../../../../../Types/AI/AIInsightSeverity";
25
+ import LIMIT_MAX from "../../../../../Types/Database/LimitMax";
26
+ import ObjectID from "../../../../../Types/ObjectID";
27
+ import { describe, expect, test, afterEach, beforeEach } from "@jest/globals";
28
+
29
+ /*
30
+ * The scanner is the watch loop's orchestration and must uphold the quiet,
31
+ * opt-in posture: only projects with enableAiInsights=true are ever
32
+ * scanned (the flag query IS the gate), every layer fails in isolation (one
33
+ * broken project, detector or insight never stops the rest), only NEWLY
34
+ * created insights are routed — refreshed rows keep their status — and a
35
+ * new insight always leaves the defensive Detected state in the same tick:
36
+ * FixOpened + fixAiRunId when fix routing opened one, ActionRequired
37
+ * otherwise, with triage enqueued for fix and non-fix insights alike.
38
+ *
39
+ * Plus the self-heal sweep: a row an earlier tick created but never routed
40
+ * (pod death, failed status write) is stranded in Detected forever — the
41
+ * refresh path never re-routes it, and its fingerprint stays pinned. The
42
+ * sweep re-routes it on the next tick, runs BEFORE the detectors (so this
43
+ * tick's own rows cannot be routed twice), never breaks the scan when it
44
+ * fails, and cannot double-create work (the fix/triage dedupes hold).
45
+ */
46
+
47
+ const projectId: ObjectID = ObjectID.generate();
48
+
49
+ function fakeProject(overrides?: { id?: ObjectID }): Project {
50
+ return {
51
+ id: overrides?.id ?? projectId,
52
+ enableAiInsights: true,
53
+ enableInsightFixTasks: false,
54
+ enableAi: true,
55
+ } as unknown as Project;
56
+ }
57
+
58
+ function makeCandidate(
59
+ overrides?: Partial<InsightCandidate>,
60
+ ): InsightCandidate {
61
+ return {
62
+ insightType: AIInsightType.NewException,
63
+ fingerprint: "new-exception:abc",
64
+ title: "New exception in checkout",
65
+ detailMarkdown: "**3 occurrences** in the last 24 hours.",
66
+ severity: AIInsightSeverity.Medium,
67
+ evidence: { exception: { recentOccurrenceCount: 3 } },
68
+ ...overrides,
69
+ };
70
+ }
71
+
72
+ function fakeInsight(): AIInsight {
73
+ return {
74
+ id: ObjectID.generate(),
75
+ projectId,
76
+ status: AIInsightStatus.Detected,
77
+ } as unknown as AIInsight;
78
+ }
79
+
80
+ function fakeDetector(data: {
81
+ insightType?: AIInsightType;
82
+ candidates?: Array<InsightCandidate>;
83
+ error?: Error;
84
+ }): InsightDetector {
85
+ return {
86
+ insightType: data.insightType ?? AIInsightType.NewException,
87
+ detect: (
88
+ _context: InsightScanContext,
89
+ ): Promise<Array<InsightCandidate>> => {
90
+ if (data.error) {
91
+ return Promise.reject(data.error);
92
+ }
93
+ return Promise.resolve(data.candidates || []);
94
+ },
95
+ };
96
+ }
97
+
98
+ function emptyUpsertResult(
99
+ overrides?: Partial<UpsertCandidatesResult>,
100
+ ): UpsertCandidatesResult {
101
+ return {
102
+ created: [],
103
+ refreshed: 0,
104
+ suppressed: 0,
105
+ droppedByCap: 0,
106
+ ...overrides,
107
+ };
108
+ }
109
+
110
+ describe("InsightScanner.scanAllProjects — flag gating and isolation", () => {
111
+ afterEach(() => {
112
+ jest.restoreAllMocks();
113
+ });
114
+
115
+ test("queries ONLY opted-in projects (enableAiInsights: true) as root and scans each", async () => {
116
+ const projectA: Project = fakeProject({ id: ObjectID.generate() });
117
+ const projectB: Project = fakeProject({ id: ObjectID.generate() });
118
+ const findBy: jest.SpyInstance = jest
119
+ .spyOn(ProjectService, "findBy")
120
+ .mockResolvedValue([projectA, projectB]);
121
+ const scanProject: jest.SpyInstance = jest
122
+ .spyOn(InsightScanner, "scanProjectForInsights")
123
+ .mockResolvedValue(undefined);
124
+
125
+ await InsightScanner.scanAllProjects();
126
+
127
+ expect(findBy).toHaveBeenCalledWith(
128
+ expect.objectContaining({
129
+ query: expect.objectContaining({ enableAiInsights: true }),
130
+ select: expect.objectContaining({
131
+ _id: true,
132
+ enableInsightFixTasks: true,
133
+ enableAi: true,
134
+ }),
135
+ limit: LIMIT_MAX,
136
+ props: expect.objectContaining({ isRoot: true }),
137
+ }),
138
+ );
139
+ expect(scanProject).toHaveBeenCalledTimes(2);
140
+ expect(scanProject).toHaveBeenCalledWith(projectA);
141
+ expect(scanProject).toHaveBeenCalledWith(projectB);
142
+ });
143
+
144
+ test("no opted-in projects → no scans", async () => {
145
+ jest.spyOn(ProjectService, "findBy").mockResolvedValue([]);
146
+ const scanProject: jest.SpyInstance = jest
147
+ .spyOn(InsightScanner, "scanProjectForInsights")
148
+ .mockResolvedValue(undefined);
149
+
150
+ await InsightScanner.scanAllProjects();
151
+
152
+ expect(scanProject).not.toHaveBeenCalled();
153
+ });
154
+
155
+ test("one project's scan failure does not stop the sweep — the rest still scan", async () => {
156
+ const projectA: Project = fakeProject({ id: ObjectID.generate() });
157
+ const projectB: Project = fakeProject({ id: ObjectID.generate() });
158
+ jest
159
+ .spyOn(ProjectService, "findBy")
160
+ .mockResolvedValue([projectA, projectB]);
161
+ const scanProject: jest.SpyInstance = jest
162
+ .spyOn(InsightScanner, "scanProjectForInsights")
163
+ .mockRejectedValueOnce(new Error("clickhouse down for tenant A"))
164
+ .mockResolvedValueOnce(undefined);
165
+
166
+ await expect(InsightScanner.scanAllProjects()).resolves.toBeUndefined();
167
+
168
+ expect(scanProject).toHaveBeenCalledTimes(2);
169
+ expect(scanProject).toHaveBeenCalledWith(projectB);
170
+ });
171
+
172
+ test("never throws into the cron caller — even the project listing failing resolves quietly", async () => {
173
+ jest
174
+ .spyOn(ProjectService, "findBy")
175
+ .mockRejectedValue(new Error("db down"));
176
+ const scanProject: jest.SpyInstance = jest
177
+ .spyOn(InsightScanner, "scanProjectForInsights")
178
+ .mockResolvedValue(undefined);
179
+
180
+ await expect(InsightScanner.scanAllProjects()).resolves.toBeUndefined();
181
+
182
+ expect(scanProject).not.toHaveBeenCalled();
183
+ });
184
+ });
185
+
186
+ describe("InsightScanner.scanProjectForInsights — detectors and the store", () => {
187
+ beforeEach(() => {
188
+ // Nothing stranded: the self-heal sweep is a no-op for these tests.
189
+ jest.spyOn(AIInsightService, "findBy").mockResolvedValue([]);
190
+ });
191
+
192
+ afterEach(() => {
193
+ jest.restoreAllMocks();
194
+ });
195
+
196
+ test("one throwing detector does not prevent the others — the survivors' candidates still reach the store", async () => {
197
+ const survivorCandidate: InsightCandidate = makeCandidate({
198
+ insightType: AIInsightType.ErrorLogSpike,
199
+ fingerprint: "error-log-spike:svc",
200
+ });
201
+ jest.spyOn(InsightDetectors, "getAllDetectors").mockReturnValue([
202
+ fakeDetector({
203
+ insightType: AIInsightType.NewException,
204
+ error: new Error("query timeout"),
205
+ }),
206
+ fakeDetector({
207
+ insightType: AIInsightType.ErrorLogSpike,
208
+ candidates: [survivorCandidate],
209
+ }),
210
+ ]);
211
+ const upsert: jest.SpyInstance = jest
212
+ .spyOn(InsightStore, "upsertCandidates")
213
+ .mockResolvedValue(emptyUpsertResult());
214
+
215
+ await expect(
216
+ InsightScanner.scanProjectForInsights(fakeProject()),
217
+ ).resolves.toBeUndefined();
218
+
219
+ expect(upsert).toHaveBeenCalledTimes(1);
220
+ expect(upsert).toHaveBeenCalledWith(
221
+ expect.objectContaining({
222
+ projectId,
223
+ candidates: [survivorCandidate],
224
+ now: expect.any(Date),
225
+ }),
226
+ );
227
+ });
228
+
229
+ test("every detector gets the projectId and the tick's single clock", async () => {
230
+ const seenContexts: Array<InsightScanContext> = [];
231
+
232
+ function recordingDetector(insightType: AIInsightType): InsightDetector {
233
+ return {
234
+ insightType,
235
+ detect: (
236
+ context: InsightScanContext,
237
+ ): Promise<Array<InsightCandidate>> => {
238
+ seenContexts.push(context);
239
+ return Promise.resolve([]);
240
+ },
241
+ };
242
+ }
243
+
244
+ jest
245
+ .spyOn(InsightDetectors, "getAllDetectors")
246
+ .mockReturnValue([
247
+ recordingDetector(AIInsightType.NewException),
248
+ recordingDetector(AIInsightType.MetricDrift),
249
+ ]);
250
+ jest
251
+ .spyOn(InsightStore, "upsertCandidates")
252
+ .mockResolvedValue(emptyUpsertResult());
253
+
254
+ await InsightScanner.scanProjectForInsights(fakeProject());
255
+
256
+ expect(seenContexts).toHaveLength(2);
257
+ expect(seenContexts[0]?.projectId).toBe(projectId);
258
+ expect(seenContexts[0]?.now).toBeInstanceOf(Date);
259
+ // Same clock for every detector — windows must line up across sensors.
260
+ expect(seenContexts[1]?.now).toBe(seenContexts[0]?.now);
261
+ });
262
+
263
+ test("no candidates → the store is never touched", async () => {
264
+ jest
265
+ .spyOn(InsightDetectors, "getAllDetectors")
266
+ .mockReturnValue([fakeDetector({ candidates: [] })]);
267
+ const upsert: jest.SpyInstance = jest.spyOn(
268
+ InsightStore,
269
+ "upsertCandidates",
270
+ );
271
+
272
+ await InsightScanner.scanProjectForInsights(fakeProject());
273
+
274
+ expect(upsert).not.toHaveBeenCalled();
275
+ });
276
+ });
277
+
278
+ describe("InsightScanner — routing newly created insights", () => {
279
+ let updateOneById: jest.SpyInstance;
280
+ let routeInsightFix: jest.SpyInstance;
281
+ let enqueueInsightTriage: jest.SpyInstance;
282
+
283
+ beforeEach(() => {
284
+ jest
285
+ .spyOn(InsightDetectors, "getAllDetectors")
286
+ .mockReturnValue([fakeDetector({ candidates: [makeCandidate()] })]);
287
+ // Nothing stranded: the self-heal sweep is a no-op for these tests.
288
+ jest.spyOn(AIInsightService, "findBy").mockResolvedValue([]);
289
+ updateOneById = jest
290
+ .spyOn(AIInsightService, "updateOneById")
291
+ .mockResolvedValue(undefined);
292
+ routeInsightFix = jest
293
+ .spyOn(InsightFixRouting, "routeInsightFix")
294
+ .mockResolvedValue({});
295
+ enqueueInsightTriage = jest
296
+ .spyOn(InsightTriage, "enqueueInsightTriage")
297
+ .mockResolvedValue({});
298
+ });
299
+
300
+ afterEach(() => {
301
+ jest.restoreAllMocks();
302
+ });
303
+
304
+ test("fix routing returned a run → status FixOpened + fixAiRunId persisted", async () => {
305
+ const insight: AIInsight = fakeInsight();
306
+ const fixAiRunId: ObjectID = ObjectID.generate();
307
+ jest
308
+ .spyOn(InsightStore, "upsertCandidates")
309
+ .mockResolvedValue(emptyUpsertResult({ created: [insight] }));
310
+ routeInsightFix.mockResolvedValue({ fixAiRunId });
311
+
312
+ await InsightScanner.scanProjectForInsights(fakeProject());
313
+
314
+ expect(updateOneById).toHaveBeenCalledWith(
315
+ expect.objectContaining({
316
+ id: insight.id,
317
+ data: expect.objectContaining({
318
+ status: AIInsightStatus.FixOpened,
319
+ fixAiRunId,
320
+ }),
321
+ props: expect.objectContaining({ isRoot: true }),
322
+ }),
323
+ );
324
+ });
325
+
326
+ test("no fix opened → status ActionRequired", async () => {
327
+ const insight: AIInsight = fakeInsight();
328
+ jest
329
+ .spyOn(InsightStore, "upsertCandidates")
330
+ .mockResolvedValue(emptyUpsertResult({ created: [insight] }));
331
+
332
+ await InsightScanner.scanProjectForInsights(fakeProject());
333
+
334
+ expect(updateOneById).toHaveBeenCalledWith(
335
+ expect.objectContaining({
336
+ id: insight.id,
337
+ data: expect.objectContaining({
338
+ status: AIInsightStatus.ActionRequired,
339
+ }),
340
+ props: expect.objectContaining({ isRoot: true }),
341
+ }),
342
+ );
343
+ });
344
+
345
+ test("the project (carrying its enableInsightFixTasks flag) is handed to fix routing — the flag gate lives there", async () => {
346
+ const insight: AIInsight = fakeInsight();
347
+ const project: Project = fakeProject();
348
+ jest
349
+ .spyOn(InsightStore, "upsertCandidates")
350
+ .mockResolvedValue(emptyUpsertResult({ created: [insight] }));
351
+
352
+ await InsightScanner.scanProjectForInsights(project);
353
+
354
+ expect(routeInsightFix).toHaveBeenCalledWith({ insight, project });
355
+ });
356
+
357
+ test("triage run enqueued → triageAiRunId persisted", async () => {
358
+ const insight: AIInsight = fakeInsight();
359
+ const triageAiRunId: ObjectID = ObjectID.generate();
360
+ jest
361
+ .spyOn(InsightStore, "upsertCandidates")
362
+ .mockResolvedValue(emptyUpsertResult({ created: [insight] }));
363
+ enqueueInsightTriage.mockResolvedValue({ triageAiRunId });
364
+
365
+ await InsightScanner.scanProjectForInsights(fakeProject());
366
+
367
+ expect(enqueueInsightTriage).toHaveBeenCalledWith({ insight });
368
+ expect(updateOneById).toHaveBeenCalledWith(
369
+ expect.objectContaining({
370
+ id: insight.id,
371
+ data: expect.objectContaining({ triageAiRunId }),
372
+ props: expect.objectContaining({ isRoot: true }),
373
+ }),
374
+ );
375
+ });
376
+
377
+ test("no triage run enqueued (quiet skip) → no triageAiRunId write", async () => {
378
+ const insight: AIInsight = fakeInsight();
379
+ jest
380
+ .spyOn(InsightStore, "upsertCandidates")
381
+ .mockResolvedValue(emptyUpsertResult({ created: [insight] }));
382
+
383
+ await InsightScanner.scanProjectForInsights(fakeProject());
384
+
385
+ // Exactly one write: the ActionRequired status routing.
386
+ expect(updateOneById).toHaveBeenCalledTimes(1);
387
+ });
388
+
389
+ test("triage runs for fix and non-fix insights alike — it enriches both", async () => {
390
+ const fixable: AIInsight = fakeInsight();
391
+ const nonFixable: AIInsight = fakeInsight();
392
+ jest
393
+ .spyOn(InsightStore, "upsertCandidates")
394
+ .mockResolvedValue(emptyUpsertResult({ created: [fixable, nonFixable] }));
395
+ routeInsightFix
396
+ .mockResolvedValueOnce({ fixAiRunId: ObjectID.generate() })
397
+ .mockResolvedValueOnce({});
398
+
399
+ await InsightScanner.scanProjectForInsights(fakeProject());
400
+
401
+ expect(enqueueInsightTriage).toHaveBeenCalledTimes(2);
402
+ expect(enqueueInsightTriage).toHaveBeenCalledWith({ insight: fixable });
403
+ expect(enqueueInsightTriage).toHaveBeenCalledWith({ insight: nonFixable });
404
+ });
405
+
406
+ test("refresh-only upsert result routes NOTHING: no fix, no triage, no status writes, no creates", async () => {
407
+ jest
408
+ .spyOn(InsightStore, "upsertCandidates")
409
+ .mockResolvedValue(emptyUpsertResult({ refreshed: 3 }));
410
+ const create: jest.SpyInstance = jest.spyOn(AIInsightService, "create");
411
+
412
+ await InsightScanner.scanProjectForInsights(fakeProject());
413
+
414
+ expect(routeInsightFix).not.toHaveBeenCalled();
415
+ expect(enqueueInsightTriage).not.toHaveBeenCalled();
416
+ expect(updateOneById).not.toHaveBeenCalled();
417
+ // The scanner itself never creates rows — only the store does.
418
+ expect(create).not.toHaveBeenCalled();
419
+ });
420
+
421
+ test("fix routing rejecting (contract breach) degrades to ActionRequired and still triages", async () => {
422
+ const insight: AIInsight = fakeInsight();
423
+ jest
424
+ .spyOn(InsightStore, "upsertCandidates")
425
+ .mockResolvedValue(emptyUpsertResult({ created: [insight] }));
426
+ routeInsightFix.mockRejectedValue(new Error("routing blew up"));
427
+
428
+ await expect(
429
+ InsightScanner.scanProjectForInsights(fakeProject()),
430
+ ).resolves.toBeUndefined();
431
+
432
+ expect(updateOneById).toHaveBeenCalledWith(
433
+ expect.objectContaining({
434
+ data: expect.objectContaining({
435
+ status: AIInsightStatus.ActionRequired,
436
+ }),
437
+ }),
438
+ );
439
+ expect(enqueueInsightTriage).toHaveBeenCalledWith({ insight });
440
+ });
441
+
442
+ test("triage rejecting (contract breach) does not fail the scan — the status was already routed", async () => {
443
+ const insight: AIInsight = fakeInsight();
444
+ jest
445
+ .spyOn(InsightStore, "upsertCandidates")
446
+ .mockResolvedValue(emptyUpsertResult({ created: [insight] }));
447
+ enqueueInsightTriage.mockRejectedValue(new Error("queue down"));
448
+
449
+ await expect(
450
+ InsightScanner.scanProjectForInsights(fakeProject()),
451
+ ).resolves.toBeUndefined();
452
+
453
+ expect(updateOneById).toHaveBeenCalledWith(
454
+ expect.objectContaining({
455
+ data: expect.objectContaining({
456
+ status: AIInsightStatus.ActionRequired,
457
+ }),
458
+ }),
459
+ );
460
+ });
461
+
462
+ test("per-insight isolation: a failing status write on the first insight does not stop routing the second", async () => {
463
+ const first: AIInsight = fakeInsight();
464
+ const second: AIInsight = fakeInsight();
465
+ jest
466
+ .spyOn(InsightStore, "upsertCandidates")
467
+ .mockResolvedValue(emptyUpsertResult({ created: [first, second] }));
468
+ updateOneById
469
+ .mockRejectedValueOnce(new Error("write conflict"))
470
+ .mockResolvedValue(undefined);
471
+
472
+ await expect(
473
+ InsightScanner.scanProjectForInsights(fakeProject()),
474
+ ).resolves.toBeUndefined();
475
+
476
+ expect(routeInsightFix).toHaveBeenCalledTimes(2);
477
+ expect(routeInsightFix).toHaveBeenCalledWith(
478
+ expect.objectContaining({ insight: second }),
479
+ );
480
+ });
481
+ });
482
+
483
+ describe("InsightScanner — the self-heal sweep for insights stranded in Detected", () => {
484
+ let findBy: jest.SpyInstance;
485
+ let updateOneById: jest.SpyInstance;
486
+ let routeInsightFix: jest.SpyInstance;
487
+ let enqueueInsightTriage: jest.SpyInstance;
488
+
489
+ beforeEach(() => {
490
+ // No candidates this tick: only the sweep is under test.
491
+ jest
492
+ .spyOn(InsightDetectors, "getAllDetectors")
493
+ .mockReturnValue([fakeDetector({ candidates: [] })]);
494
+ findBy = jest
495
+ .spyOn(AIInsightService, "findBy")
496
+ .mockResolvedValue([] as unknown as Array<AIInsight>);
497
+ updateOneById = jest
498
+ .spyOn(AIInsightService, "updateOneById")
499
+ .mockResolvedValue(undefined);
500
+ routeInsightFix = jest
501
+ .spyOn(InsightFixRouting, "routeInsightFix")
502
+ .mockResolvedValue({});
503
+ enqueueInsightTriage = jest
504
+ .spyOn(InsightTriage, "enqueueInsightTriage")
505
+ .mockResolvedValue({});
506
+ });
507
+
508
+ afterEach(() => {
509
+ jest.restoreAllMocks();
510
+ });
511
+
512
+ test("a Detected row left over from an earlier tick is swept up and re-routed to ActionRequired (and triaged)", async () => {
513
+ const stranded: AIInsight = fakeInsight();
514
+ findBy.mockResolvedValue([stranded]);
515
+
516
+ await InsightScanner.scanProjectForInsights(fakeProject());
517
+
518
+ // Scoped to this project's unrouted rows only, as root.
519
+ expect(findBy).toHaveBeenCalledWith(
520
+ expect.objectContaining({
521
+ query: expect.objectContaining({
522
+ projectId,
523
+ status: AIInsightStatus.Detected,
524
+ }),
525
+ limit: LIMIT_MAX,
526
+ props: expect.objectContaining({ isRoot: true }),
527
+ }),
528
+ );
529
+ expect(routeInsightFix).toHaveBeenCalledWith(
530
+ expect.objectContaining({ insight: stranded }),
531
+ );
532
+ expect(updateOneById).toHaveBeenCalledWith(
533
+ expect.objectContaining({
534
+ id: stranded.id,
535
+ data: expect.objectContaining({
536
+ status: AIInsightStatus.ActionRequired,
537
+ }),
538
+ props: expect.objectContaining({ isRoot: true }),
539
+ }),
540
+ );
541
+ expect(enqueueInsightTriage).toHaveBeenCalledWith({ insight: stranded });
542
+ });
543
+
544
+ test("a swept row whose fix routing opens a run lands on FixOpened + fixAiRunId — the full routing path, not a status patch", async () => {
545
+ const stranded: AIInsight = fakeInsight();
546
+ const fixAiRunId: ObjectID = ObjectID.generate();
547
+ findBy.mockResolvedValue([stranded]);
548
+ routeInsightFix.mockResolvedValue({ fixAiRunId });
549
+
550
+ await InsightScanner.scanProjectForInsights(fakeProject());
551
+
552
+ expect(updateOneById).toHaveBeenCalledWith(
553
+ expect.objectContaining({
554
+ id: stranded.id,
555
+ data: expect.objectContaining({
556
+ status: AIInsightStatus.FixOpened,
557
+ fixAiRunId,
558
+ }),
559
+ }),
560
+ );
561
+ });
562
+
563
+ test("the sweep runs BEFORE the detectors — so rows created by THIS tick are routed exactly once, never twice", async () => {
564
+ const callOrder: Array<string> = [];
565
+ const created: AIInsight = fakeInsight();
566
+
567
+ findBy.mockImplementation((): Promise<Array<AIInsight>> => {
568
+ callOrder.push("sweep");
569
+ // Nothing stranded: the row below does not exist yet at sweep time.
570
+ return Promise.resolve([]);
571
+ });
572
+ jest.spyOn(InsightDetectors, "getAllDetectors").mockReturnValue([
573
+ {
574
+ insightType: AIInsightType.NewException,
575
+ detect: (): Promise<Array<InsightCandidate>> => {
576
+ callOrder.push("detect");
577
+ return Promise.resolve([makeCandidate()]);
578
+ },
579
+ },
580
+ ]);
581
+ jest
582
+ .spyOn(InsightStore, "upsertCandidates")
583
+ .mockResolvedValue(emptyUpsertResult({ created: [created] }));
584
+
585
+ await InsightScanner.scanProjectForInsights(fakeProject());
586
+
587
+ expect(callOrder).toEqual(["sweep", "detect"]);
588
+ expect(routeInsightFix).toHaveBeenCalledTimes(1);
589
+ expect(routeInsightFix).toHaveBeenCalledWith(
590
+ expect.objectContaining({ insight: created }),
591
+ );
592
+ });
593
+
594
+ test("a sweep failure never breaks the scan — detectors still run and this tick's new insights still route", async () => {
595
+ const created: AIInsight = fakeInsight();
596
+ findBy.mockRejectedValue(new Error("db down"));
597
+ jest
598
+ .spyOn(InsightDetectors, "getAllDetectors")
599
+ .mockReturnValue([fakeDetector({ candidates: [makeCandidate()] })]);
600
+ const upsert: jest.SpyInstance = jest
601
+ .spyOn(InsightStore, "upsertCandidates")
602
+ .mockResolvedValue(emptyUpsertResult({ created: [created] }));
603
+
604
+ await expect(
605
+ InsightScanner.scanProjectForInsights(fakeProject()),
606
+ ).resolves.toBeUndefined();
607
+
608
+ expect(upsert).toHaveBeenCalledTimes(1);
609
+ expect(routeInsightFix).toHaveBeenCalledWith(
610
+ expect.objectContaining({ insight: created }),
611
+ );
612
+ });
613
+
614
+ test("one stranded row failing to re-route does not stop the next one", async () => {
615
+ const first: AIInsight = fakeInsight();
616
+ const second: AIInsight = fakeInsight();
617
+ findBy.mockResolvedValue([first, second]);
618
+ updateOneById
619
+ .mockRejectedValueOnce(new Error("write conflict"))
620
+ .mockResolvedValue(undefined);
621
+
622
+ await expect(
623
+ InsightScanner.scanProjectForInsights(fakeProject()),
624
+ ).resolves.toBeUndefined();
625
+
626
+ expect(routeInsightFix).toHaveBeenCalledTimes(2);
627
+ expect(routeInsightFix).toHaveBeenCalledWith(
628
+ expect.objectContaining({ insight: second }),
629
+ );
630
+ });
631
+ });
632
+
633
+ /*
634
+ * The safety proof for the sweep: re-routing a row that ALREADY got its fix
635
+ * run (the pod died after the run was created but before the status write)
636
+ * cannot create a second one. The dedupe lives inside the creation path
637
+ * itself — this exercises the REAL InsightFixRouting against it.
638
+ */
639
+ describe("InsightScanner — re-routing a stranded insight cannot double-create a fix run", () => {
640
+ afterEach(() => {
641
+ jest.restoreAllMocks();
642
+ });
643
+
644
+ test("the creation path's per-(exception, recipe) dedupe rejection is a quiet no-fix: no run is stamped, the row lands on ActionRequired", async () => {
645
+ const stranded: AIInsight = {
646
+ id: ObjectID.generate(),
647
+ projectId,
648
+ insightType: AIInsightType.NewException,
649
+ telemetryExceptionId: ObjectID.generate(),
650
+ status: AIInsightStatus.Detected,
651
+ } as unknown as AIInsight;
652
+
653
+ const optedInProject: Project = {
654
+ id: projectId,
655
+ enableAiInsights: true,
656
+ // Fix tasks ON and AI ON: every gate ahead of the dedupe is open.
657
+ enableInsightFixTasks: true,
658
+ enableAi: true,
659
+ } as unknown as Project;
660
+
661
+ const budget: FixRunBudgetDecision = {
662
+ allowed: true,
663
+ limit: 25,
664
+ paused: false,
665
+ runsToday: 0,
666
+ };
667
+
668
+ jest
669
+ .spyOn(InsightDetectors, "getAllDetectors")
670
+ .mockReturnValue([fakeDetector({ candidates: [] })]);
671
+ jest
672
+ .spyOn(AIInsightService, "findBy")
673
+ .mockResolvedValue([stranded] as unknown as Array<AIInsight>);
674
+ const updateOneById: jest.SpyInstance = jest
675
+ .spyOn(AIInsightService, "updateOneById")
676
+ .mockResolvedValue(undefined);
677
+ jest.spyOn(InsightTriage, "enqueueInsightTriage").mockResolvedValue({});
678
+ jest.spyOn(FixRunBudget, "getBudgetStatus").mockResolvedValue(budget);
679
+ jest
680
+ .spyOn(TelemetryExceptionService, "getAIFixReadiness")
681
+ .mockResolvedValue({ ready: true, checks: [] });
682
+
683
+ /*
684
+ * The dedupe: the fix run created before the pod died is still
685
+ * non-terminal, so the creation path refuses a second one.
686
+ */
687
+ const create: jest.SpyInstance = jest
688
+ .spyOn(TelemetryExceptionService, "createCodeFixRunForException")
689
+ .mockRejectedValue(
690
+ new Error(
691
+ "An AI agent task is already in progress for this exception.",
692
+ ),
693
+ );
694
+ const stamp: jest.SpyInstance = jest.spyOn(AIRunService, "updateOneById");
695
+
696
+ await expect(
697
+ InsightScanner.scanProjectForInsights(optedInProject),
698
+ ).resolves.toBeUndefined();
699
+
700
+ // The creation path was asked exactly once — and it refused.
701
+ expect(create).toHaveBeenCalledTimes(1);
702
+ // No second run exists, so nothing was stamped and nothing is FixOpened.
703
+ expect(stamp).not.toHaveBeenCalled();
704
+ expect(updateOneById).toHaveBeenCalledWith(
705
+ expect.objectContaining({
706
+ id: stranded.id,
707
+ data: expect.objectContaining({
708
+ status: AIInsightStatus.ActionRequired,
709
+ }),
710
+ }),
711
+ );
712
+ expect(updateOneById).not.toHaveBeenCalledWith(
713
+ expect.objectContaining({
714
+ data: expect.objectContaining({
715
+ status: AIInsightStatus.FixOpened,
716
+ }),
717
+ }),
718
+ );
719
+ });
720
+ });