@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,676 @@
1
+ import {
2
+ ImplicatedSpan,
3
+ PerformanceFinding,
4
+ PerformanceFindingType,
5
+ } from "../../../../Types/AI/CodeFixTaskContext";
6
+
7
+ /*
8
+ * Deterministic span-tree analysis for the FixPerformance recipe — the part
9
+ * of the recipe that must be trustworthy. NO LLM here: this module takes a
10
+ * trace's spans and detects three mechanical performance patterns, each with
11
+ * hard numeric thresholds and human-readable evidence (real counts and
12
+ * durations). The findings are the recipe's entire grounding: the trigger
13
+ * refuses to enqueue a fix task when this returns nothing, and the agent
14
+ * prompt embeds the evidence verbatim.
15
+ *
16
+ * Patterns:
17
+ * 1. N+1 — >=5 sibling spans under one parent with
18
+ * near-identical names (digits/uuids/hex normalized)
19
+ * and, when db.statement is present, near-identical
20
+ * normalized statements.
21
+ * 2. Dominant span — a single span whose SELF time (duration not covered
22
+ * by its children) is >=60% of the trace's total
23
+ * duration. Self time, not raw duration: otherwise
24
+ * every ancestor of a slow leaf — including the root,
25
+ * trivially at 100% — would fire.
26
+ * 3. Sequential — >=3 same-name siblings executing strictly
27
+ * one-after-another (each starts at or after the
28
+ * previous end) whose combined duration is >=50% of
29
+ * their parent — work that could run in parallel.
30
+ *
31
+ * Pure and unit-tested (SpanTreeAnalyzer.test.ts).
32
+ */
33
+
34
+ // One span as the analyzer consumes it. Times are milliseconds.
35
+ export interface AnalyzableSpan {
36
+ spanId: string;
37
+ parentSpanId?: string | undefined;
38
+ name: string;
39
+ /*
40
+ * Absolute (or trace-relative) start/end in ms — enables sequential
41
+ * detection and exact self-time; durationMs alone still enables the rest.
42
+ */
43
+ startMs?: number | undefined;
44
+ endMs?: number | undefined;
45
+ durationMs?: number | undefined;
46
+ // String-valued span attributes (db.statement, db.system, http.url, ...).
47
+ attributes?: Record<string, string> | undefined;
48
+ }
49
+
50
+ // Thresholds — exported so tests and docs state them once.
51
+ export const N_PLUS_ONE_MIN_SIBLINGS: number = 5;
52
+ export const DOMINANT_SPAN_MIN_FRACTION: number = 0.6;
53
+ export const SEQUENTIAL_MIN_SIBLINGS: number = 3;
54
+ export const SEQUENTIAL_MIN_FRACTION_OF_PARENT: number = 0.5;
55
+ export const MAX_IMPLICATED_SPANS_PER_FINDING: number = 10;
56
+
57
+ const UUID_REGEX: RegExp =
58
+ /[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}/g;
59
+ const LONG_HEX_REGEX: RegExp = /\b[0-9a-fA-F]{8,}\b/g;
60
+ const DIGIT_RUN_REGEX: RegExp = /\d+/g;
61
+
62
+ interface NormalizedSpan {
63
+ spanId: string;
64
+ parentSpanId: string | null;
65
+ name: string;
66
+ normalizedName: string;
67
+ startMs: number | null;
68
+ endMs: number | null;
69
+ durationMs: number;
70
+ attributes: Record<string, string>;
71
+ }
72
+
73
+ export default class SpanTreeAnalyzer {
74
+ /*
75
+ * Collapse the variable parts of a span name so repeated operations with
76
+ * different ids compare equal: "GET /users/42" and "GET /users/97" both
77
+ * become "GET /users/{n}". Order matters — uuids and long hex ids must
78
+ * collapse before bare digit runs eat their digit characters.
79
+ */
80
+ public static normalizeSpanName(name: string): string {
81
+ return name
82
+ .trim()
83
+ .replace(UUID_REGEX, "{id}")
84
+ .replace(LONG_HEX_REGEX, "{id}")
85
+ .replace(DIGIT_RUN_REGEX, "{n}")
86
+ .replace(/\s+/g, " ");
87
+ }
88
+
89
+ /*
90
+ * Collapse literals in a db.statement so "near-identical" queries compare
91
+ * equal: quoted strings and numbers become ?, and runs of placeholders
92
+ * collapse to one so IN-lists of different lengths still match.
93
+ */
94
+ public static normalizeDbStatement(statement: string): string {
95
+ return statement
96
+ .trim()
97
+ .replace(/'[^']*'/g, "?")
98
+ .replace(UUID_REGEX, "?")
99
+ .replace(DIGIT_RUN_REGEX, "?")
100
+ .replace(/\?(?:\s*,\s*\?)+/g, "?")
101
+ .replace(/\s+/g, " ");
102
+ }
103
+
104
+ // The three detectors over one trace's spans. Empty array = no pattern.
105
+ public static analyzeTrace(
106
+ spans: Array<AnalyzableSpan>,
107
+ ): Array<PerformanceFinding> {
108
+ const normalized: Array<NormalizedSpan> = this.normalizeSpans(spans);
109
+
110
+ if (normalized.length === 0) {
111
+ return [];
112
+ }
113
+
114
+ const traceDurationMs: number = this.computeTraceDurationMs(normalized);
115
+
116
+ if (traceDurationMs <= 0) {
117
+ // Zero-length traces cannot support percentage-based evidence.
118
+ return [];
119
+ }
120
+
121
+ const spansById: Map<string, NormalizedSpan> = new Map();
122
+ const childrenByParent: Map<string, Array<NormalizedSpan>> = new Map();
123
+
124
+ for (const span of normalized) {
125
+ spansById.set(span.spanId, span);
126
+ }
127
+
128
+ for (const span of normalized) {
129
+ if (!span.parentSpanId) {
130
+ continue;
131
+ }
132
+ const siblings: Array<NormalizedSpan> | undefined = childrenByParent.get(
133
+ span.parentSpanId,
134
+ );
135
+ if (siblings) {
136
+ siblings.push(span);
137
+ } else {
138
+ childrenByParent.set(span.parentSpanId, [span]);
139
+ }
140
+ }
141
+
142
+ const findings: Array<PerformanceFinding> = [];
143
+
144
+ /*
145
+ * Sibling groups that fired as N+1 — a sequential finding on the same
146
+ * group would be noise (batching subsumes parallelizing).
147
+ */
148
+ const groupsReportedAsNPlusOne: Set<string> = new Set();
149
+
150
+ findings.push(
151
+ ...this.detectNPlusOne(
152
+ childrenByParent,
153
+ spansById,
154
+ traceDurationMs,
155
+ groupsReportedAsNPlusOne,
156
+ ),
157
+ );
158
+
159
+ findings.push(
160
+ ...this.detectDominantSpans(
161
+ normalized,
162
+ childrenByParent,
163
+ traceDurationMs,
164
+ ),
165
+ );
166
+
167
+ findings.push(
168
+ ...this.detectSequentialSiblings(
169
+ childrenByParent,
170
+ spansById,
171
+ traceDurationMs,
172
+ groupsReportedAsNPlusOne,
173
+ ),
174
+ );
175
+
176
+ /*
177
+ * Biggest measured cost first (deterministic tie-breaks), so the top
178
+ * finding's headline can title the pull request.
179
+ */
180
+ findings.sort((a: PerformanceFinding, b: PerformanceFinding): number => {
181
+ if (b.combinedDurationMs !== a.combinedDurationMs) {
182
+ return b.combinedDurationMs - a.combinedDurationMs;
183
+ }
184
+ if (a.findingType !== b.findingType) {
185
+ return a.findingType.localeCompare(b.findingType);
186
+ }
187
+ return a.normalizedSpanName.localeCompare(b.normalizedSpanName);
188
+ });
189
+
190
+ return findings;
191
+ }
192
+
193
+ /*
194
+ * Render findings as the markdown block embedded in the agent prompt and
195
+ * the pull request body. Deterministic — rendered once server-side so the
196
+ * worker and the PR always show the identical evidence.
197
+ */
198
+ public static renderFindingsMarkdown(
199
+ findings: Array<PerformanceFinding>,
200
+ ): string {
201
+ const sections: Array<string> = findings.map(
202
+ (finding: PerformanceFinding, index: number): string => {
203
+ const lines: Array<string> = [
204
+ `### Finding ${index + 1}: ${finding.headline}`,
205
+ "",
206
+ finding.evidence,
207
+ ];
208
+
209
+ if (finding.normalizedDbStatement) {
210
+ lines.push(
211
+ "",
212
+ `Normalized statement${finding.dbSystem ? ` (${finding.dbSystem})` : ""}:`,
213
+ "```sql",
214
+ finding.normalizedDbStatement,
215
+ "```",
216
+ );
217
+ }
218
+
219
+ if (finding.httpUrl) {
220
+ lines.push("", `HTTP URL: \`${finding.httpUrl}\``);
221
+ }
222
+
223
+ if (finding.implicatedSpans.length > 0) {
224
+ lines.push("", "Implicated spans (name — duration):");
225
+ for (const span of finding.implicatedSpans) {
226
+ lines.push(
227
+ `- "${span.name}" — ${this.formatMs(span.durationMs)} (spanId ${span.spanId})`,
228
+ );
229
+ }
230
+ if (finding.spanCount > finding.implicatedSpans.length) {
231
+ lines.push(
232
+ `- … and ${finding.spanCount - finding.implicatedSpans.length} more`,
233
+ );
234
+ }
235
+ }
236
+
237
+ return lines.join("\n");
238
+ },
239
+ );
240
+
241
+ return sections.join("\n\n");
242
+ }
243
+
244
+ private static normalizeSpans(
245
+ spans: Array<AnalyzableSpan>,
246
+ ): Array<NormalizedSpan> {
247
+ const normalized: Array<NormalizedSpan> = [];
248
+
249
+ for (const span of spans) {
250
+ if (!span.spanId || !span.name) {
251
+ continue;
252
+ }
253
+
254
+ const startMs: number | null =
255
+ typeof span.startMs === "number" && Number.isFinite(span.startMs)
256
+ ? span.startMs
257
+ : null;
258
+ const endMs: number | null =
259
+ typeof span.endMs === "number" && Number.isFinite(span.endMs)
260
+ ? span.endMs
261
+ : null;
262
+
263
+ let durationMs: number =
264
+ typeof span.durationMs === "number" && Number.isFinite(span.durationMs)
265
+ ? span.durationMs
266
+ : startMs !== null && endMs !== null
267
+ ? endMs - startMs
268
+ : 0;
269
+
270
+ if (durationMs < 0) {
271
+ durationMs = 0;
272
+ }
273
+
274
+ normalized.push({
275
+ spanId: span.spanId,
276
+ parentSpanId: span.parentSpanId || null,
277
+ name: span.name,
278
+ normalizedName: this.normalizeSpanName(span.name),
279
+ startMs,
280
+ endMs,
281
+ durationMs,
282
+ attributes: span.attributes || {},
283
+ });
284
+ }
285
+
286
+ return normalized;
287
+ }
288
+
289
+ /*
290
+ * Total trace duration: the start/end envelope when timestamps exist;
291
+ * otherwise the longest single span (in practice the root) is the honest
292
+ * duration-only proxy.
293
+ */
294
+ private static computeTraceDurationMs(spans: Array<NormalizedSpan>): number {
295
+ let minStart: number | null = null;
296
+ let maxEnd: number | null = null;
297
+
298
+ for (const span of spans) {
299
+ if (span.startMs === null || span.endMs === null) {
300
+ continue;
301
+ }
302
+ if (minStart === null || span.startMs < minStart) {
303
+ minStart = span.startMs;
304
+ }
305
+ if (maxEnd === null || span.endMs > maxEnd) {
306
+ maxEnd = span.endMs;
307
+ }
308
+ }
309
+
310
+ if (minStart !== null && maxEnd !== null && maxEnd > minStart) {
311
+ return maxEnd - minStart;
312
+ }
313
+
314
+ let maxDuration: number = 0;
315
+ for (const span of spans) {
316
+ if (span.durationMs > maxDuration) {
317
+ maxDuration = span.durationMs;
318
+ }
319
+ }
320
+ return maxDuration;
321
+ }
322
+
323
+ private static getDbStatement(span: NormalizedSpan): string | null {
324
+ return (
325
+ span.attributes["db.statement"] ||
326
+ span.attributes["db.query.text"] ||
327
+ null
328
+ );
329
+ }
330
+
331
+ private static getDbSystem(span: NormalizedSpan): string | null {
332
+ return (
333
+ span.attributes["db.system"] || span.attributes["db.system.name"] || null
334
+ );
335
+ }
336
+
337
+ private static getHttpUrl(span: NormalizedSpan): string | null {
338
+ return span.attributes["http.url"] || span.attributes["url.full"] || null;
339
+ }
340
+
341
+ private static formatMs(ms: number): string {
342
+ return `${Math.round(ms * 10) / 10}ms`;
343
+ }
344
+
345
+ private static formatPercent(fraction: number): string {
346
+ return `${Math.round(fraction * 1000) / 10}%`;
347
+ }
348
+
349
+ private static toImplicatedSpans(
350
+ spans: Array<NormalizedSpan>,
351
+ ): Array<ImplicatedSpan> {
352
+ return spans
353
+ .slice(0, MAX_IMPLICATED_SPANS_PER_FINDING)
354
+ .map((span: NormalizedSpan): ImplicatedSpan => {
355
+ return {
356
+ spanId: span.spanId,
357
+ name: span.name,
358
+ durationMs: Math.round(span.durationMs * 10) / 10,
359
+ };
360
+ });
361
+ }
362
+
363
+ /*
364
+ * Same-operation sibling groups under one parent: key = normalized name
365
+ * plus (when present) the normalized db.statement, so "27 SELECTs that
366
+ * only differ by id" group together while different queries behind one
367
+ * generic span name ("query") stay apart.
368
+ */
369
+ private static groupSiblings(
370
+ siblings: Array<NormalizedSpan>,
371
+ ): Map<string, Array<NormalizedSpan>> {
372
+ const groups: Map<string, Array<NormalizedSpan>> = new Map();
373
+
374
+ for (const span of siblings) {
375
+ const statement: string | null = this.getDbStatement(span);
376
+ const key: string = `${span.normalizedName}${
377
+ statement ? this.normalizeDbStatement(statement) : ""
378
+ }`;
379
+ const group: Array<NormalizedSpan> | undefined = groups.get(key);
380
+ if (group) {
381
+ group.push(span);
382
+ } else {
383
+ groups.set(key, [span]);
384
+ }
385
+ }
386
+
387
+ return groups;
388
+ }
389
+
390
+ private static detectNPlusOne(
391
+ childrenByParent: Map<string, Array<NormalizedSpan>>,
392
+ spansById: Map<string, NormalizedSpan>,
393
+ traceDurationMs: number,
394
+ groupsReportedAsNPlusOne: Set<string>,
395
+ ): Array<PerformanceFinding> {
396
+ const findings: Array<PerformanceFinding> = [];
397
+
398
+ for (const [parentSpanId, siblings] of childrenByParent) {
399
+ const parent: NormalizedSpan | undefined = spansById.get(parentSpanId);
400
+
401
+ for (const [groupKey, group] of this.groupSiblings(siblings)) {
402
+ if (group.length < N_PLUS_ONE_MIN_SIBLINGS) {
403
+ continue;
404
+ }
405
+
406
+ const sample: NormalizedSpan = group[0]!;
407
+ const combinedDurationMs: number = group.reduce(
408
+ (sum: number, span: NormalizedSpan): number => {
409
+ return sum + span.durationMs;
410
+ },
411
+ 0,
412
+ );
413
+ const statement: string | null = this.getDbStatement(sample);
414
+ const normalizedStatement: string | null = statement
415
+ ? this.normalizeDbStatement(statement)
416
+ : null;
417
+ const parentLabel: string = parent
418
+ ? `"${parent.name}"`
419
+ : `parent span ${parentSpanId}`;
420
+
421
+ const evidenceLines: Array<string> = [
422
+ `${group.length} sibling spans named "${sample.normalizedName}" execute under ${parentLabel} in this trace — the classic N+1 shape (one span per item instead of one batched operation).`,
423
+ `Combined they take ${this.formatMs(combinedDurationMs)} of the ${this.formatMs(traceDurationMs)} trace (${this.formatPercent(combinedDurationMs / traceDurationMs)}); average ${this.formatMs(combinedDurationMs / group.length)} per span.`,
424
+ ];
425
+
426
+ if (normalizedStatement) {
427
+ evidenceLines.push(
428
+ `All ${group.length} spans run a near-identical statement (literals normalized to ?): ${normalizedStatement}`,
429
+ );
430
+ }
431
+
432
+ groupsReportedAsNPlusOne.add(`${parentSpanId}${groupKey}`);
433
+
434
+ findings.push({
435
+ findingType: PerformanceFindingType.NPlusOneQuery,
436
+ headline: `N+1: ${group.length}× "${sample.normalizedName}"${parent ? ` under "${parent.name}"` : ""}`,
437
+ evidence: evidenceLines.join("\n"),
438
+ spanCount: group.length,
439
+ combinedDurationMs: Math.round(combinedDurationMs * 10) / 10,
440
+ traceDurationMs: Math.round(traceDurationMs * 10) / 10,
441
+ percentOfTrace:
442
+ Math.round((combinedDurationMs / traceDurationMs) * 1000) / 10,
443
+ normalizedSpanName: sample.normalizedName,
444
+ parentSpanName: parent?.name,
445
+ normalizedDbStatement: normalizedStatement || undefined,
446
+ dbSystem: this.getDbSystem(sample) || undefined,
447
+ httpUrl: this.getHttpUrl(sample) || undefined,
448
+ implicatedSpans: this.toImplicatedSpans(group),
449
+ });
450
+ }
451
+ }
452
+
453
+ return findings;
454
+ }
455
+
456
+ /*
457
+ * Self time of a span: its duration minus the time covered by its direct
458
+ * children — the exact interval union when timestamps exist, else the
459
+ * clamped sum of child durations.
460
+ */
461
+ private static computeSelfTimeMs(
462
+ span: NormalizedSpan,
463
+ children: Array<NormalizedSpan>,
464
+ ): number {
465
+ if (children.length === 0) {
466
+ return span.durationMs;
467
+ }
468
+
469
+ const timedChildren: Array<NormalizedSpan> = children.filter(
470
+ (child: NormalizedSpan): boolean => {
471
+ return child.startMs !== null && child.endMs !== null;
472
+ },
473
+ );
474
+
475
+ if (
476
+ span.startMs !== null &&
477
+ span.endMs !== null &&
478
+ timedChildren.length === children.length
479
+ ) {
480
+ // Union of child intervals clipped to the span's own interval.
481
+ const intervals: Array<[number, number]> = timedChildren
482
+ .map((child: NormalizedSpan): [number, number] => {
483
+ return [
484
+ Math.max(child.startMs!, span.startMs!),
485
+ Math.min(child.endMs!, span.endMs!),
486
+ ];
487
+ })
488
+ .filter((interval: [number, number]): boolean => {
489
+ return interval[1] > interval[0];
490
+ })
491
+ .sort((a: [number, number], b: [number, number]): number => {
492
+ return a[0] - b[0];
493
+ });
494
+
495
+ let covered: number = 0;
496
+ let currentStart: number | null = null;
497
+ let currentEnd: number | null = null;
498
+
499
+ for (const [start, end] of intervals) {
500
+ if (currentEnd === null || start > currentEnd) {
501
+ if (currentStart !== null && currentEnd !== null) {
502
+ covered += currentEnd - currentStart;
503
+ }
504
+ currentStart = start;
505
+ currentEnd = end;
506
+ } else if (end > currentEnd) {
507
+ currentEnd = end;
508
+ }
509
+ }
510
+ if (currentStart !== null && currentEnd !== null) {
511
+ covered += currentEnd - currentStart;
512
+ }
513
+
514
+ return Math.max(span.durationMs - covered, 0);
515
+ }
516
+
517
+ const childDurationSum: number = children.reduce(
518
+ (sum: number, child: NormalizedSpan): number => {
519
+ return sum + child.durationMs;
520
+ },
521
+ 0,
522
+ );
523
+
524
+ return Math.max(span.durationMs - childDurationSum, 0);
525
+ }
526
+
527
+ private static detectDominantSpans(
528
+ spans: Array<NormalizedSpan>,
529
+ childrenByParent: Map<string, Array<NormalizedSpan>>,
530
+ traceDurationMs: number,
531
+ ): Array<PerformanceFinding> {
532
+ const findings: Array<PerformanceFinding> = [];
533
+
534
+ for (const span of spans) {
535
+ const selfTimeMs: number = this.computeSelfTimeMs(
536
+ span,
537
+ childrenByParent.get(span.spanId) || [],
538
+ );
539
+
540
+ if (selfTimeMs / traceDurationMs < DOMINANT_SPAN_MIN_FRACTION) {
541
+ continue;
542
+ }
543
+
544
+ const statement: string | null = this.getDbStatement(span);
545
+ const normalizedStatement: string | null = statement
546
+ ? this.normalizeDbStatement(statement)
547
+ : null;
548
+
549
+ const evidenceLines: Array<string> = [
550
+ `The single span "${span.name}" (spanId ${span.spanId}) spends ${this.formatMs(selfTimeMs)} in its own work — ${this.formatPercent(selfTimeMs / traceDurationMs)} of the ${this.formatMs(traceDurationMs)} trace. One operation dominates this request's latency.`,
551
+ ];
552
+
553
+ if (normalizedStatement) {
554
+ evidenceLines.push(
555
+ `The span's statement (literals normalized to ?): ${normalizedStatement}`,
556
+ );
557
+ }
558
+
559
+ findings.push({
560
+ findingType: PerformanceFindingType.DominantSpan,
561
+ headline: `Dominant span: "${span.name}" is ${this.formatPercent(selfTimeMs / traceDurationMs)} of the trace`,
562
+ evidence: evidenceLines.join("\n"),
563
+ spanCount: 1,
564
+ combinedDurationMs: Math.round(selfTimeMs * 10) / 10,
565
+ traceDurationMs: Math.round(traceDurationMs * 10) / 10,
566
+ percentOfTrace: Math.round((selfTimeMs / traceDurationMs) * 1000) / 10,
567
+ normalizedSpanName: span.normalizedName,
568
+ normalizedDbStatement: normalizedStatement || undefined,
569
+ dbSystem: this.getDbSystem(span) || undefined,
570
+ httpUrl: this.getHttpUrl(span) || undefined,
571
+ implicatedSpans: this.toImplicatedSpans([span]),
572
+ });
573
+ }
574
+
575
+ return findings;
576
+ }
577
+
578
+ private static detectSequentialSiblings(
579
+ childrenByParent: Map<string, Array<NormalizedSpan>>,
580
+ spansById: Map<string, NormalizedSpan>,
581
+ traceDurationMs: number,
582
+ groupsReportedAsNPlusOne: Set<string>,
583
+ ): Array<PerformanceFinding> {
584
+ const findings: Array<PerformanceFinding> = [];
585
+
586
+ for (const [parentSpanId, siblings] of childrenByParent) {
587
+ const parent: NormalizedSpan | undefined = spansById.get(parentSpanId);
588
+
589
+ // Percent-of-parent needs a parent with a real duration.
590
+ if (!parent || parent.durationMs <= 0) {
591
+ continue;
592
+ }
593
+
594
+ for (const [groupKey, group] of this.groupSiblings(siblings)) {
595
+ if (group.length < SEQUENTIAL_MIN_SIBLINGS) {
596
+ continue;
597
+ }
598
+
599
+ // Batching (the N+1 fix) subsumes parallelizing — do not report both.
600
+ if (groupsReportedAsNPlusOne.has(`${parentSpanId}${groupKey}`)) {
601
+ continue;
602
+ }
603
+
604
+ // Sequential execution is only observable with timestamps.
605
+ if (
606
+ group.some((span: NormalizedSpan): boolean => {
607
+ return span.startMs === null || span.endMs === null;
608
+ })
609
+ ) {
610
+ continue;
611
+ }
612
+
613
+ const ordered: Array<NormalizedSpan> = [...group].sort(
614
+ (a: NormalizedSpan, b: NormalizedSpan): number => {
615
+ return a.startMs! - b.startMs!;
616
+ },
617
+ );
618
+
619
+ let isStrictlySequential: boolean = true;
620
+ for (let i: number = 1; i < ordered.length; i++) {
621
+ if (ordered[i]!.startMs! < ordered[i - 1]!.endMs!) {
622
+ isStrictlySequential = false;
623
+ break;
624
+ }
625
+ }
626
+
627
+ if (!isStrictlySequential) {
628
+ continue;
629
+ }
630
+
631
+ const combinedDurationMs: number = ordered.reduce(
632
+ (sum: number, span: NormalizedSpan): number => {
633
+ return sum + span.durationMs;
634
+ },
635
+ 0,
636
+ );
637
+
638
+ if (
639
+ combinedDurationMs / parent.durationMs <
640
+ SEQUENTIAL_MIN_FRACTION_OF_PARENT
641
+ ) {
642
+ continue;
643
+ }
644
+
645
+ const sample: NormalizedSpan = ordered[0]!;
646
+ const sampleStatement: string | null = this.getDbStatement(sample);
647
+
648
+ findings.push({
649
+ findingType: PerformanceFindingType.SequentialSiblings,
650
+ headline: `Sequential: ${ordered.length}× "${sample.normalizedName}" run one-after-another under "${parent.name}"`,
651
+ evidence: [
652
+ `${ordered.length} sibling spans named "${sample.normalizedName}" under "${parent.name}" execute strictly sequentially — each starts only after the previous one ends, so none of the work overlaps.`,
653
+ `Combined they take ${this.formatMs(combinedDurationMs)} of the parent's ${this.formatMs(parent.durationMs)} (${this.formatPercent(combinedDurationMs / parent.durationMs)}). If these operations are independent, running them concurrently would remove most of that wall-clock time.`,
654
+ ].join("\n"),
655
+ spanCount: ordered.length,
656
+ combinedDurationMs: Math.round(combinedDurationMs * 10) / 10,
657
+ traceDurationMs: Math.round(traceDurationMs * 10) / 10,
658
+ percentOfTrace:
659
+ Math.round((combinedDurationMs / traceDurationMs) * 1000) / 10,
660
+ percentOfParent:
661
+ Math.round((combinedDurationMs / parent.durationMs) * 1000) / 10,
662
+ normalizedSpanName: sample.normalizedName,
663
+ parentSpanName: parent.name,
664
+ normalizedDbStatement: sampleStatement
665
+ ? this.normalizeDbStatement(sampleStatement)
666
+ : undefined,
667
+ dbSystem: this.getDbSystem(sample) || undefined,
668
+ httpUrl: this.getHttpUrl(sample) || undefined,
669
+ implicatedSpans: this.toImplicatedSpans(ordered),
670
+ });
671
+ }
672
+ }
673
+
674
+ return findings;
675
+ }
676
+ }