@oneuptime/common 11.3.26 → 11.4.0

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 (298) hide show
  1. package/Models/DatabaseModels/AIRun.ts +50 -0
  2. package/Models/DatabaseModels/IncidentEpisodeRoleMember.ts +1 -1
  3. package/Models/DatabaseModels/IncidentMember.ts +1 -1
  4. package/Models/DatabaseModels/IncomingCallPolicy.ts +13 -0
  5. package/Models/DatabaseModels/Index.ts +3 -0
  6. package/Models/DatabaseModels/MigrationFailure.ts +170 -0
  7. package/Models/DatabaseModels/OnCallDutyPolicyExecutionLog.ts +51 -2
  8. package/Models/DatabaseModels/OnCallDutyPolicySchedule.ts +44 -0
  9. package/Models/DatabaseModels/OnCallDutyPolicyScheduleLayer.ts +6 -0
  10. package/Models/DatabaseModels/OnCallDutyPolicyScheduleLayerUser.ts +6 -0
  11. package/Models/DatabaseModels/OnCallDutyPolicyTimeLog.ts +1 -1
  12. package/Models/DatabaseModels/OnCallDutyPolicyUserOverride.ts +2 -2
  13. package/Models/DatabaseModels/Project.ts +60 -0
  14. package/Server/API/AIInvestigationAPI.ts +148 -0
  15. package/Server/API/AlertAPI.ts +1 -1
  16. package/Server/API/IncidentAPI.ts +2 -2
  17. package/Server/API/IncidentEpisodeAPI.ts +1 -1
  18. package/Server/API/LlmProviderAPI.ts +1 -0
  19. package/Server/API/ScheduledMaintenanceAPI.ts +1 -1
  20. package/Server/Infrastructure/Postgres/SchemaMigrations/1783470000000-AddIncomingCallPolicyRoutingPhoneNumberUnique.ts +25 -0
  21. package/Server/Infrastructure/Postgres/SchemaMigrations/1783510935686-FixNotNullForeignKeysOnDelete.ts +81 -0
  22. package/Server/Infrastructure/Postgres/SchemaMigrations/1783515836148-MigrationName.ts +25 -0
  23. package/Server/Infrastructure/Postgres/SchemaMigrations/1783523076215-AddMigrationFailureTable.ts +35 -0
  24. package/Server/Infrastructure/Postgres/SchemaMigrations/1783598145111-AddEnableAutomaticIncidentInvestigationToProject.ts +19 -0
  25. package/Server/Infrastructure/Postgres/SchemaMigrations/1783615884106-AddInvestigationSubjectToAIRun.ts +33 -0
  26. package/Server/Infrastructure/Postgres/SchemaMigrations/1783632447975-AddEnableAutomaticAlertInvestigationToProject.ts +19 -0
  27. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +14 -0
  28. package/Server/Infrastructure/PostgresDatabase.ts +11 -0
  29. package/Server/Services/AIService.ts +74 -2
  30. package/Server/Services/AlertService.ts +25 -0
  31. package/Server/Services/AnalyticsDatabaseService.ts +10 -1
  32. package/Server/Services/DatabaseService.ts +10 -1
  33. package/Server/Services/IncidentService.ts +26 -1
  34. package/Server/Services/IncidentStateTimelineService.ts +19 -0
  35. package/Server/Services/IncomingCallPolicyEscalationRuleService.ts +75 -2
  36. package/Server/Services/IncomingCallPolicyService.ts +42 -1
  37. package/Server/Services/Index.ts +2 -0
  38. package/Server/Services/MigrationFailureService.ts +9 -0
  39. package/Server/Services/MonitorProbeService.ts +33 -7
  40. package/Server/Services/MonitorService.ts +19 -7
  41. package/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.ts +65 -0
  42. package/Server/Services/OnCallDutyPolicyEscalationRuleService.ts +185 -41
  43. package/Server/Services/OnCallDutyPolicyEscalationRuleUserService.ts +23 -15
  44. package/Server/Services/OnCallDutyPolicyExecutionLogService.ts +39 -0
  45. package/Server/Services/OnCallDutyPolicyScheduleLayerService.ts +148 -0
  46. package/Server/Services/OnCallDutyPolicyScheduleLayerUserService.ts +11 -2
  47. package/Server/Services/OnCallDutyPolicyScheduleService.ts +502 -26
  48. package/Server/Services/OnCallDutyPolicyTimeLogService.ts +49 -7
  49. package/Server/Services/OnCallDutyPolicyUserOverrideService.ts +218 -4
  50. package/Server/Services/ProjectCallSMSConfigService.ts +82 -1
  51. package/Server/Services/TeamMemberService.ts +6 -0
  52. package/Server/Services/UserNotificationRuleService.ts +13 -42
  53. package/Server/Services/UserOnCallLogService.ts +90 -0
  54. package/Server/Services/UserOnCallLogTimelineService.ts +43 -1
  55. package/Server/Types/Database/QueryUtil.ts +57 -0
  56. package/Server/Utils/AI/AlertAIContextBuilder.ts +6 -1
  57. package/Server/Utils/AI/Chat/ChatAgentRunner.ts +14 -2
  58. package/Server/Utils/AI/Chat/ObservabilityAssistant.ts +119 -11
  59. package/Server/Utils/AI/IncidentAIContextBuilder.ts +18 -3
  60. package/Server/Utils/AI/IncidentEpisodeAIContextBuilder.ts +6 -1
  61. package/Server/Utils/AI/ScheduledMaintenanceAIContextBuilder.ts +12 -2
  62. package/Server/Utils/AI/Sentinel/AlertInvestigationRunner.ts +141 -0
  63. package/Server/Utils/AI/Sentinel/IncidentInvestigationRunner.ts +178 -0
  64. package/Server/Utils/AI/Sentinel/IncidentPostmortemRunner.ts +105 -0
  65. package/Server/Utils/AI/Sentinel/SentinelInvestigationEngine.ts +405 -0
  66. package/Server/Utils/AI/Sentinel/SentinelMemory.ts +167 -0
  67. package/Server/Utils/AI/Toolbox/IncidentTools.ts +183 -1
  68. package/Server/Utils/AI/Toolbox/Index.ts +15 -1
  69. package/Server/Utils/AI/Toolbox/RecentChangesTools.ts +208 -0
  70. package/Server/Utils/AI/Toolbox/SentinelActionTools.ts +577 -0
  71. package/Server/Utils/AI/Toolbox/Serializer.ts +42 -0
  72. package/Server/Utils/Database/MigrationFailureLog.ts +240 -0
  73. package/Server/Utils/IncomingCallPhoneNumber.ts +41 -0
  74. package/Server/Utils/LLM/LLMService.ts +110 -11
  75. package/Server/Utils/Telemetry/IoTSnapshotScan.ts +12 -9
  76. package/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.ts +12 -9
  77. package/Tests/Server/API/BaseAPI.test.ts +1 -0
  78. package/Tests/Server/Services/AnalyticsDatabaseService.test.ts +0 -8
  79. package/Tests/Server/Services/OnCallDutyPolicyScheduleLayerUserReorder.test.ts +233 -0
  80. package/Tests/Server/Services/OnCallDutyPolicyTimeLogServiceScoping.test.ts +242 -0
  81. package/Tests/Server/Services/OnCallDutyPolicyUserOverrideEdit.test.ts +198 -0
  82. package/Tests/Server/Services/UserOnCallLogClaimNotificationRule.test.ts +495 -0
  83. package/Tests/Server/Types/Database/QueryUtil.test.ts +74 -0
  84. package/Tests/Server/Utils/AI/LLMServiceToolCalling.test.ts +78 -0
  85. package/Tests/Server/Utils/AI/ToolResultSerializer.test.ts +68 -0
  86. package/Tests/Types/DateExhaustiveTimezone.test.ts +700 -0
  87. package/Tests/Types/DateTimezoneWallClock.test.ts +99 -0
  88. package/Tests/Types/Events/Recurring.test.ts +22 -9
  89. package/Tests/Types/OnCallDutyPolicy/LayerUtilAuditFixes.test.ts +291 -0
  90. package/Tests/Types/OnCallDutyPolicy/LayerUtilAuditFixesRound2.test.ts +398 -0
  91. package/Tests/Types/OnCallDutyPolicy/LayerUtilDSTWeekendGap.test.ts +114 -0
  92. package/Tests/Types/OnCallDutyPolicy/LayerUtilDSTWeeklyDayShift.test.ts +76 -0
  93. package/Tests/Types/OnCallDutyPolicy/LayerUtilDailyMutation.test.ts +128 -0
  94. package/Tests/Types/OnCallDutyPolicy/LayerUtilDailyProbe.test.ts +203 -0
  95. package/Tests/Types/OnCallDutyPolicy/LayerUtilDiffFuzz.test.ts +322 -0
  96. package/Tests/Types/OnCallDutyPolicy/LayerUtilEdgeCases.test.ts +280 -0
  97. package/Tests/Types/OnCallDutyPolicy/LayerUtilExhaustiveCurrentUser.test.ts +863 -0
  98. package/Tests/Types/OnCallDutyPolicy/LayerUtilExhaustiveDaily.test.ts +900 -0
  99. package/Tests/Types/OnCallDutyPolicy/LayerUtilExhaustiveMultiLayer.test.ts +1104 -0
  100. package/Tests/Types/OnCallDutyPolicy/LayerUtilExhaustiveRotation.test.ts +957 -0
  101. package/Tests/Types/OnCallDutyPolicy/LayerUtilExhaustiveWeekly.test.ts +1095 -0
  102. package/Tests/Types/OnCallDutyPolicy/LayerUtilInvariants.test.ts +232 -0
  103. package/Tests/Types/OnCallDutyPolicy/LayerUtilMergeAudit.test.ts +227 -0
  104. package/Tests/Types/OnCallDutyPolicy/LayerUtilMonthYearAudit.test.ts +255 -0
  105. package/Tests/Types/OnCallDutyPolicy/LayerUtilMultiLayerAudit.test.ts +388 -0
  106. package/Tests/Types/OnCallDutyPolicy/LayerUtilMultiLayerEdge.test.ts +300 -0
  107. package/Tests/Types/OnCallDutyPolicy/LayerUtilOvernightDSTAudit.test.ts +158 -0
  108. package/Tests/Types/OnCallDutyPolicy/LayerUtilRestrictedGapFix.test.ts +253 -0
  109. package/Tests/Types/OnCallDutyPolicy/LayerUtilRestrictedGapRepro.test.ts +157 -0
  110. package/Tests/Types/OnCallDutyPolicy/LayerUtilRotationFixes.test.ts +414 -0
  111. package/Tests/Types/OnCallDutyPolicy/LayerUtilTimezone.test.ts +243 -0
  112. package/Tests/Types/OnCallDutyPolicy/LayerUtilWeekendGapRepro.test.ts +112 -0
  113. package/Tests/Types/OnCallDutyPolicy/OverrideLensAudit.test.ts +117 -0
  114. package/Tests/Types/OnCallDutyPolicy/RestrictionTimes.test.ts +8 -6
  115. package/Tests/Types/OnCallDutyPolicy/RestrictionTimesDefaultDayAudit.test.ts +112 -0
  116. package/Tests/Types/OnCallDutyPolicy/RestrictionTimesExhaustive.test.ts +821 -0
  117. package/Tests/Types/OnCallDutyPolicy/RestrictionTimesMutationInvariant.test.ts +886 -0
  118. package/Tests/Types/OnCallDutyPolicy/ScheduleShiftUtil.test.ts +260 -0
  119. package/Tests/Types/OnCallDutyPolicy/UserOverrideUtil.test.ts +255 -0
  120. package/Tests/Types/OnCallDutyPolicy/UserOverrideUtilExhaustive.test.ts +1126 -0
  121. package/Types/Date.ts +246 -15
  122. package/Types/OnCallDutyPolicy/Layer.ts +790 -260
  123. package/Types/OnCallDutyPolicy/RestrictionTimes.ts +39 -13
  124. package/Types/OnCallDutyPolicy/ScheduleShiftUtil.ts +257 -0
  125. package/Types/OnCallDutyPolicy/UserOverrideUtil.ts +21 -5
  126. package/UI/Components/Calendar/Calendar.tsx +8 -2
  127. package/UI/Components/Charts/ChartGroup/ChartGroup.tsx +5 -5
  128. package/UI/Components/Events/RecurringFieldElement.tsx +16 -0
  129. package/UI/Components/ModelFormModal/ModelFormModal.tsx +8 -0
  130. package/UI/Components/RadioButtons/BasicRadioButtons.tsx +1 -1
  131. package/build/dist/Models/DatabaseModels/AIRun.js +52 -0
  132. package/build/dist/Models/DatabaseModels/AIRun.js.map +1 -1
  133. package/build/dist/Models/DatabaseModels/IncidentEpisodeRoleMember.js +1 -1
  134. package/build/dist/Models/DatabaseModels/IncidentEpisodeRoleMember.js.map +1 -1
  135. package/build/dist/Models/DatabaseModels/IncidentMember.js +1 -1
  136. package/build/dist/Models/DatabaseModels/IncidentMember.js.map +1 -1
  137. package/build/dist/Models/DatabaseModels/IncomingCallPolicy.js +10 -0
  138. package/build/dist/Models/DatabaseModels/IncomingCallPolicy.js.map +1 -1
  139. package/build/dist/Models/DatabaseModels/Index.js +2 -0
  140. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  141. package/build/dist/Models/DatabaseModels/MigrationFailure.js +196 -0
  142. package/build/dist/Models/DatabaseModels/MigrationFailure.js.map +1 -0
  143. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyExecutionLog.js +52 -2
  144. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyExecutionLog.js.map +1 -1
  145. package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js +45 -0
  146. package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js.map +1 -1
  147. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleLayer.js +6 -0
  148. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleLayer.js.map +1 -1
  149. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleLayerUser.js +6 -0
  150. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleLayerUser.js.map +1 -1
  151. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyTimeLog.js +1 -1
  152. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyTimeLog.js.map +1 -1
  153. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyUserOverride.js +2 -2
  154. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyUserOverride.js.map +1 -1
  155. package/build/dist/Models/DatabaseModels/Project.js +62 -0
  156. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  157. package/build/dist/Server/API/AIInvestigationAPI.js +107 -0
  158. package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -0
  159. package/build/dist/Server/API/AlertAPI.js +1 -1
  160. package/build/dist/Server/API/IncidentAPI.js +2 -2
  161. package/build/dist/Server/API/IncidentEpisodeAPI.js +1 -1
  162. package/build/dist/Server/API/LlmProviderAPI.js +1 -0
  163. package/build/dist/Server/API/LlmProviderAPI.js.map +1 -1
  164. package/build/dist/Server/API/ScheduledMaintenanceAPI.js +1 -1
  165. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783470000000-AddIncomingCallPolicyRoutingPhoneNumberUnique.js +18 -0
  166. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783470000000-AddIncomingCallPolicyRoutingPhoneNumberUnique.js.map +1 -0
  167. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783510935686-FixNotNullForeignKeysOnDelete.js +38 -0
  168. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783510935686-FixNotNullForeignKeysOnDelete.js.map +1 -0
  169. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783515836148-MigrationName.js +16 -0
  170. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783515836148-MigrationName.js.map +1 -0
  171. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783523076215-AddMigrationFailureTable.js +18 -0
  172. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783523076215-AddMigrationFailureTable.js.map +1 -0
  173. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783598145111-AddEnableAutomaticIncidentInvestigationToProject.js +12 -0
  174. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783598145111-AddEnableAutomaticIncidentInvestigationToProject.js.map +1 -0
  175. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783615884106-AddInvestigationSubjectToAIRun.js +18 -0
  176. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783615884106-AddInvestigationSubjectToAIRun.js.map +1 -0
  177. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783632447975-AddEnableAutomaticAlertInvestigationToProject.js +12 -0
  178. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783632447975-AddEnableAutomaticAlertInvestigationToProject.js.map +1 -0
  179. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +14 -0
  180. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  181. package/build/dist/Server/Infrastructure/PostgresDatabase.js +9 -0
  182. package/build/dist/Server/Infrastructure/PostgresDatabase.js.map +1 -1
  183. package/build/dist/Server/Services/AIService.js +53 -2
  184. package/build/dist/Server/Services/AIService.js.map +1 -1
  185. package/build/dist/Server/Services/AlertService.js +24 -0
  186. package/build/dist/Server/Services/AlertService.js.map +1 -1
  187. package/build/dist/Server/Services/AnalyticsDatabaseService.js +10 -1
  188. package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
  189. package/build/dist/Server/Services/DatabaseService.js +10 -1
  190. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  191. package/build/dist/Server/Services/IncidentService.js +25 -1
  192. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  193. package/build/dist/Server/Services/IncidentStateTimelineService.js +19 -0
  194. package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
  195. package/build/dist/Server/Services/IncomingCallPolicyEscalationRuleService.js +55 -2
  196. package/build/dist/Server/Services/IncomingCallPolicyEscalationRuleService.js.map +1 -1
  197. package/build/dist/Server/Services/IncomingCallPolicyService.js +40 -0
  198. package/build/dist/Server/Services/IncomingCallPolicyService.js.map +1 -1
  199. package/build/dist/Server/Services/Index.js +2 -0
  200. package/build/dist/Server/Services/Index.js.map +1 -1
  201. package/build/dist/Server/Services/MigrationFailureService.js +9 -0
  202. package/build/dist/Server/Services/MigrationFailureService.js.map +1 -0
  203. package/build/dist/Server/Services/MonitorProbeService.js +33 -7
  204. package/build/dist/Server/Services/MonitorProbeService.js.map +1 -1
  205. package/build/dist/Server/Services/MonitorService.js +12 -5
  206. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  207. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js +81 -22
  208. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js.map +1 -1
  209. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleService.js +134 -31
  210. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleService.js.map +1 -1
  211. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleUserService.js +21 -13
  212. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleUserService.js.map +1 -1
  213. package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogService.js +36 -0
  214. package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogService.js.map +1 -1
  215. package/build/dist/Server/Services/OnCallDutyPolicyScheduleLayerService.js +121 -0
  216. package/build/dist/Server/Services/OnCallDutyPolicyScheduleLayerService.js.map +1 -1
  217. package/build/dist/Server/Services/OnCallDutyPolicyScheduleLayerUserService.js +11 -2
  218. package/build/dist/Server/Services/OnCallDutyPolicyScheduleLayerUserService.js.map +1 -1
  219. package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js +409 -36
  220. package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js.map +1 -1
  221. package/build/dist/Server/Services/OnCallDutyPolicyTimeLogService.js +52 -8
  222. package/build/dist/Server/Services/OnCallDutyPolicyTimeLogService.js.map +1 -1
  223. package/build/dist/Server/Services/OnCallDutyPolicyUserOverrideService.js +170 -3
  224. package/build/dist/Server/Services/OnCallDutyPolicyUserOverrideService.js.map +1 -1
  225. package/build/dist/Server/Services/ProjectCallSMSConfigService.js +72 -0
  226. package/build/dist/Server/Services/ProjectCallSMSConfigService.js.map +1 -1
  227. package/build/dist/Server/Services/TeamMemberService.js +6 -0
  228. package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
  229. package/build/dist/Server/Services/UserNotificationRuleService.js +12 -30
  230. package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
  231. package/build/dist/Server/Services/UserOnCallLogService.js +75 -0
  232. package/build/dist/Server/Services/UserOnCallLogService.js.map +1 -1
  233. package/build/dist/Server/Services/UserOnCallLogTimelineService.js +31 -1
  234. package/build/dist/Server/Services/UserOnCallLogTimelineService.js.map +1 -1
  235. package/build/dist/Server/Types/Database/QueryUtil.js +45 -0
  236. package/build/dist/Server/Types/Database/QueryUtil.js.map +1 -1
  237. package/build/dist/Server/Utils/AI/AlertAIContextBuilder.js +6 -1
  238. package/build/dist/Server/Utils/AI/AlertAIContextBuilder.js.map +1 -1
  239. package/build/dist/Server/Utils/AI/Chat/ChatAgentRunner.js +13 -2
  240. package/build/dist/Server/Utils/AI/Chat/ChatAgentRunner.js.map +1 -1
  241. package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js +59 -11
  242. package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js.map +1 -1
  243. package/build/dist/Server/Utils/AI/IncidentAIContextBuilder.js +18 -3
  244. package/build/dist/Server/Utils/AI/IncidentAIContextBuilder.js.map +1 -1
  245. package/build/dist/Server/Utils/AI/IncidentEpisodeAIContextBuilder.js +6 -1
  246. package/build/dist/Server/Utils/AI/IncidentEpisodeAIContextBuilder.js.map +1 -1
  247. package/build/dist/Server/Utils/AI/ScheduledMaintenanceAIContextBuilder.js +12 -2
  248. package/build/dist/Server/Utils/AI/ScheduledMaintenanceAIContextBuilder.js.map +1 -1
  249. package/build/dist/Server/Utils/AI/Sentinel/AlertInvestigationRunner.js +119 -0
  250. package/build/dist/Server/Utils/AI/Sentinel/AlertInvestigationRunner.js.map +1 -0
  251. package/build/dist/Server/Utils/AI/Sentinel/IncidentInvestigationRunner.js +147 -0
  252. package/build/dist/Server/Utils/AI/Sentinel/IncidentInvestigationRunner.js.map +1 -0
  253. package/build/dist/Server/Utils/AI/Sentinel/IncidentPostmortemRunner.js +93 -0
  254. package/build/dist/Server/Utils/AI/Sentinel/IncidentPostmortemRunner.js.map +1 -0
  255. package/build/dist/Server/Utils/AI/Sentinel/SentinelInvestigationEngine.js +311 -0
  256. package/build/dist/Server/Utils/AI/Sentinel/SentinelInvestigationEngine.js.map +1 -0
  257. package/build/dist/Server/Utils/AI/Sentinel/SentinelMemory.js +143 -0
  258. package/build/dist/Server/Utils/AI/Sentinel/SentinelMemory.js.map +1 -0
  259. package/build/dist/Server/Utils/AI/Toolbox/IncidentTools.js +152 -1
  260. package/build/dist/Server/Utils/AI/Toolbox/IncidentTools.js.map +1 -1
  261. package/build/dist/Server/Utils/AI/Toolbox/Index.js +10 -1
  262. package/build/dist/Server/Utils/AI/Toolbox/Index.js.map +1 -1
  263. package/build/dist/Server/Utils/AI/Toolbox/RecentChangesTools.js +165 -0
  264. package/build/dist/Server/Utils/AI/Toolbox/RecentChangesTools.js.map +1 -0
  265. package/build/dist/Server/Utils/AI/Toolbox/SentinelActionTools.js +451 -0
  266. package/build/dist/Server/Utils/AI/Toolbox/SentinelActionTools.js.map +1 -0
  267. package/build/dist/Server/Utils/AI/Toolbox/Serializer.js +40 -0
  268. package/build/dist/Server/Utils/AI/Toolbox/Serializer.js.map +1 -1
  269. package/build/dist/Server/Utils/Database/MigrationFailureLog.js +174 -0
  270. package/build/dist/Server/Utils/Database/MigrationFailureLog.js.map +1 -0
  271. package/build/dist/Server/Utils/IncomingCallPhoneNumber.js +30 -0
  272. package/build/dist/Server/Utils/IncomingCallPhoneNumber.js.map +1 -0
  273. package/build/dist/Server/Utils/LLM/LLMService.js +81 -5
  274. package/build/dist/Server/Utils/LLM/LLMService.js.map +1 -1
  275. package/build/dist/Server/Utils/Telemetry/IoTSnapshotScan.js +11 -8
  276. package/build/dist/Server/Utils/Telemetry/IoTSnapshotScan.js.map +1 -1
  277. package/build/dist/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.js +11 -8
  278. package/build/dist/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.js.map +1 -1
  279. package/build/dist/Types/Date.js +185 -15
  280. package/build/dist/Types/Date.js.map +1 -1
  281. package/build/dist/Types/OnCallDutyPolicy/Layer.js +602 -171
  282. package/build/dist/Types/OnCallDutyPolicy/Layer.js.map +1 -1
  283. package/build/dist/Types/OnCallDutyPolicy/RestrictionTimes.js +27 -13
  284. package/build/dist/Types/OnCallDutyPolicy/RestrictionTimes.js.map +1 -1
  285. package/build/dist/Types/OnCallDutyPolicy/ScheduleShiftUtil.js +159 -0
  286. package/build/dist/Types/OnCallDutyPolicy/ScheduleShiftUtil.js.map +1 -0
  287. package/build/dist/Types/OnCallDutyPolicy/UserOverrideUtil.js +20 -5
  288. package/build/dist/Types/OnCallDutyPolicy/UserOverrideUtil.js.map +1 -1
  289. package/build/dist/UI/Components/Calendar/Calendar.js +2 -2
  290. package/build/dist/UI/Components/Calendar/Calendar.js.map +1 -1
  291. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js +2 -2
  292. package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js.map +1 -1
  293. package/build/dist/UI/Components/Events/RecurringFieldElement.js +13 -0
  294. package/build/dist/UI/Components/Events/RecurringFieldElement.js.map +1 -1
  295. package/build/dist/UI/Components/ModelFormModal/ModelFormModal.js.map +1 -1
  296. package/build/dist/UI/Components/RadioButtons/BasicRadioButtons.js +1 -1
  297. package/build/dist/UI/Components/RadioButtons/BasicRadioButtons.js.map +1 -1
  298. package/package.json +1 -1
@@ -0,0 +1,311 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import ObjectID from "../../../../Types/ObjectID";
11
+ import OneUptimeDate from "../../../../Types/Date";
12
+ import AIRunType from "../../../../Types/AI/AIRunType";
13
+ import AIRunStatus from "../../../../Types/AI/AIRunStatus";
14
+ import AIRunEventType from "../../../../Types/AI/AIRunEventType";
15
+ import AIRun from "../../../../Models/DatabaseModels/AIRun";
16
+ import AIRunEvent from "../../../../Models/DatabaseModels/AIRunEvent";
17
+ import AIRunService from "../../../Services/AIRunService";
18
+ import AIRunEventService from "../../../Services/AIRunEventService";
19
+ import ProjectService from "../../../Services/ProjectService";
20
+ import LlmProviderService from "../../../Services/LlmProviderService";
21
+ import ObservabilityAssistant from "../Chat/ObservabilityAssistant";
22
+ import logger from "../../Logger";
23
+ import CaptureSpan from "../../Telemetry/CaptureSpan";
24
+ /*
25
+ * Sentinel — the shared autonomous-investigation engine.
26
+ *
27
+ * A single subject-agnostic core that powers "wake on signal" investigations
28
+ * for both incidents and alerts (and, later, anomalies). It:
29
+ * 1. records the run as an AIRun(Investigation) + AIRunEvents (audit trail),
30
+ * 2. runs the existing read-only, tool-grounded, citation-minting agent loop
31
+ * (ObservabilityAssistant) with the Sentinel persona and a larger budget,
32
+ * 3. brands the cited analysis, judges confidence, and
33
+ * 4. hands the finished analysis back to the caller to post to the subject's
34
+ * timeline.
35
+ *
36
+ * The investigation is strictly READ-ONLY: it can never mutate anything.
37
+ * Enablement + provider gating is shared via isEnabledForProject().
38
+ */
39
+ // Budgets — larger than an interactive chat-ops answer, small enough to stay cheap.
40
+ const MAX_LLM_CALLS = 8;
41
+ const MAX_TOOL_CALLS = 12;
42
+ const MAX_WALL_CLOCK_MS = 150 * 1000;
43
+ const MAX_OUTPUT_TOKENS = 2000;
44
+ /*
45
+ * Sentinel's own contract: it writes exactly this phrase when it cannot
46
+ * determine a cause. We match it deterministically to drive "quiet mode" —
47
+ * a non-answer should never loudly page the on-call.
48
+ */
49
+ const INCONCLUSIVE_RE = /inconclusive[^.\n]*insufficient signal/i;
50
+ // Maps a live agent step to the AIRunEvent type persisted for the glass-box trail.
51
+ const STEP_EVENT_TYPE = {
52
+ llm_started: AIRunEventType.LlmCallStarted,
53
+ llm_completed: AIRunEventType.LlmCallCompleted,
54
+ tool_started: AIRunEventType.ToolCallStarted,
55
+ tool_completed: AIRunEventType.ToolCallCompleted,
56
+ tool_failed: AIRunEventType.ToolCallFailed,
57
+ };
58
+ const INVESTIGATION_PERSONA = `You are "Sentinel", OneUptime's autonomous AI Site Reliability Engineer. You have been woken automatically because a NEW signal (an incident or alert) was just declared in this project — no human has asked you a question yet. Investigate it proactively and produce a first-pass root cause analysis that the on-call engineer will read the moment they are paged.
59
+
60
+ Investigate like a senior on-call engineer:
61
+ - Start from the affected monitors/services named in the signal.
62
+ - Use your read tools to inspect the telemetry AROUND the signal's creation time: recent exceptions and their trends, error/latency metrics versus their normal range, failing traces, relevant logs, and recent changes / deploys.
63
+ - Form the single most likely root-cause hypothesis. If the evidence is inconclusive, say so plainly and list what you checked — do NOT guess a cause the data does not support.
64
+ - If the context lists past resolved incidents, check whether this is a RECURRENCE. If the current signal matches one, say so explicitly, reference that incident number, and note how it was resolved before — but still verify against the current telemetry.
65
+
66
+ Write your final answer as a concise incident-response note with exactly these sections (use these markdown headings):
67
+ **Summary** — one or two sentences a paged engineer can read in five seconds.
68
+ **Most likely root cause** — your hypothesis, with only the confidence the evidence actually supports, each factual claim carrying its [C#] citation. If you could not determine it, write "Inconclusive — insufficient signal" and explain what is missing.
69
+ **Evidence** — the key findings that support or rule out the hypothesis, each cited.
70
+ **Suggested next steps** — concrete actions for the on-call engineer.
71
+
72
+ Keep it tight and skimmable. You are read-only: never claim to have changed anything.`;
73
+ export default class SentinelInvestigationEngine {
74
+ /*
75
+ * Shared gate: AI enabled, the subject's auto-investigation opt-in on, and an
76
+ * LLM provider configured. Incidents and alerts each have their own opt-in so
77
+ * they can be enabled independently. Runs before any (subject-specific)
78
+ * context assembly.
79
+ */
80
+ static async isEnabledForProject(projectId, subjectType) {
81
+ const project = await ProjectService.findOneById({
82
+ id: projectId,
83
+ select: {
84
+ enableAi: true,
85
+ enableAutomaticIncidentInvestigation: true,
86
+ enableAutomaticAlertInvestigation: true,
87
+ },
88
+ props: { isRoot: true },
89
+ });
90
+ if (!project) {
91
+ return false;
92
+ }
93
+ if (project.enableAi === false) {
94
+ return false;
95
+ }
96
+ const isOptedIn = subjectType === "Alert"
97
+ ? project.enableAutomaticAlertInvestigation === true
98
+ : project.enableAutomaticIncidentInvestigation === true;
99
+ if (!isOptedIn) {
100
+ return false;
101
+ }
102
+ const llmProvider = await LlmProviderService.getLLMProviderForProject(projectId);
103
+ if (!llmProvider) {
104
+ logger.debug(`Sentinel: skipping investigation for project ${projectId.toString()} — no LLM provider configured.`);
105
+ return false;
106
+ }
107
+ return true;
108
+ }
109
+ /*
110
+ * Run one investigation end-to-end. Never throws — failures are logged and
111
+ * recorded on the AIRun.
112
+ */
113
+ static async investigate(request) {
114
+ const { projectId } = request;
115
+ // Record the run up front so it is auditable even if it fails.
116
+ const run = new AIRun();
117
+ run.projectId = projectId;
118
+ run.runType = AIRunType.Investigation;
119
+ run.status = AIRunStatus.Running;
120
+ run.startedAt = OneUptimeDate.getCurrentDate();
121
+ run.lastHeartbeatAt = OneUptimeDate.getCurrentDate();
122
+ if (request.subjectIncidentId) {
123
+ run.triggeredByIncidentId = request.subjectIncidentId;
124
+ }
125
+ if (request.subjectAlertId) {
126
+ run.triggeredByAlertId = request.subjectAlertId;
127
+ }
128
+ let createdRun;
129
+ try {
130
+ createdRun = await AIRunService.create({
131
+ data: run,
132
+ props: { isRoot: true },
133
+ });
134
+ }
135
+ catch (error) {
136
+ logger.error(`Sentinel: failed to create investigation run: ${error}`);
137
+ return;
138
+ }
139
+ const aiRunId = createdRun.id;
140
+ let sequence = 0;
141
+ await this.emitEvent({
142
+ projectId,
143
+ aiRunId,
144
+ sequence: sequence++,
145
+ eventType: AIRunEventType.RunStarted,
146
+ });
147
+ /*
148
+ * Live narration: persist each LLM/tool step as an AIRunEvent so the UI can
149
+ * "watch it think" by polling the run's events. Best-effort, ordered.
150
+ */
151
+ const onStep = async (step) => {
152
+ const resultSummary = step.rowCount !== undefined ||
153
+ step.durationMs !== undefined ||
154
+ step.errorMessage !== undefined
155
+ ? {
156
+ rowCount: step.rowCount,
157
+ durationInMs: step.durationMs,
158
+ errorMessage: step.errorMessage,
159
+ }
160
+ : undefined;
161
+ await this.emitEvent({
162
+ projectId,
163
+ aiRunId,
164
+ sequence: sequence++,
165
+ eventType: STEP_EVENT_TYPE[step.type],
166
+ toolName: step.toolName,
167
+ toolArguments: step.toolArguments,
168
+ resultSummary,
169
+ citationId: step.citationId,
170
+ });
171
+ // Keep the run visibly alive for the stale-run sweeper + live UI.
172
+ if (step.type === "llm_started") {
173
+ await this.touchHeartbeat(aiRunId);
174
+ }
175
+ };
176
+ try {
177
+ const result = await ObservabilityAssistant.answerQuestion({
178
+ projectId,
179
+ // System run — full read access to the project's telemetry.
180
+ props: { isRoot: true },
181
+ feature: request.feature,
182
+ systemInstructions: INVESTIGATION_PERSONA,
183
+ question: `A new signal has just been declared and you have been woken to investigate it. Investigate now and produce your root cause analysis.\n\n${request.contextSummary}`,
184
+ maxLlmCalls: MAX_LLM_CALLS,
185
+ maxToolCalls: MAX_TOOL_CALLS,
186
+ maxWallClockMs: MAX_WALL_CLOCK_MS,
187
+ maxOutputTokens: MAX_OUTPUT_TOKENS,
188
+ onStep,
189
+ });
190
+ await AIRunService.updateOneBy({
191
+ query: { _id: aiRunId.toString(), status: AIRunStatus.Running },
192
+ data: {
193
+ status: AIRunStatus.Completed,
194
+ completedAt: OneUptimeDate.getCurrentDate(),
195
+ lastHeartbeatAt: OneUptimeDate.getCurrentDate(),
196
+ llmCallCount: result.llmCallCount,
197
+ toolCallCount: result.toolCallCount,
198
+ totalTokens: result.totalTokens,
199
+ },
200
+ props: { isRoot: true },
201
+ });
202
+ await this.emitEvent({
203
+ projectId,
204
+ aiRunId,
205
+ sequence: sequence++,
206
+ eventType: AIRunEventType.RunCompleted,
207
+ });
208
+ const analysis = (result.contentInMarkdown || "").trim();
209
+ if (!analysis) {
210
+ logger.debug(`Sentinel: investigation (run ${aiRunId.toString()}) produced no analysis; nothing posted.`);
211
+ return;
212
+ }
213
+ const isConfident = !INCONCLUSIVE_RE.test(analysis);
214
+ await request.postAnalysis({
215
+ analysisMarkdown: this.buildBrandedMarkdown(result, analysis),
216
+ isConfident,
217
+ result,
218
+ });
219
+ logger.debug(`Sentinel: investigation complete (run ${aiRunId.toString()}, confident=${isConfident}, ${result.llmCallCount} LLM calls, ${result.toolCallCount} tools, ${result.totalTokens} tokens).`);
220
+ }
221
+ catch (error) {
222
+ const message = error instanceof Error ? error.message : String(error);
223
+ await AIRunService.updateOneBy({
224
+ query: { _id: aiRunId.toString(), status: AIRunStatus.Running },
225
+ data: {
226
+ status: AIRunStatus.Error,
227
+ completedAt: OneUptimeDate.getCurrentDate(),
228
+ errorMessage: message.substring(0, 480),
229
+ },
230
+ props: { isRoot: true },
231
+ });
232
+ await this.emitEvent({
233
+ projectId,
234
+ aiRunId,
235
+ sequence: sequence++,
236
+ eventType: AIRunEventType.RunFailed,
237
+ });
238
+ logger.error(`Sentinel: investigation failed (run ${aiRunId.toString()}): ${message}`);
239
+ }
240
+ }
241
+ // Wrap the agent's analysis with Sentinel branding + an evidence list.
242
+ static buildBrandedMarkdown(result, analysisMarkdown) {
243
+ let markdown = `## 🧠 Sentinel — Automated Root Cause Analysis\n\n${analysisMarkdown}`;
244
+ const citations = result.citations || [];
245
+ if (citations.length > 0) {
246
+ markdown += `\n\n**Evidence checked**`;
247
+ for (const citation of citations.slice(0, 15)) {
248
+ markdown += `\n- **[${citation.id}]** ${citation.label} — ${citation.rowCount} row(s)`;
249
+ }
250
+ }
251
+ markdown += `\n\n---\n*Investigated automatically by OneUptime Sentinel — read-only, ${result.toolCallCount} quer${result.toolCallCount === 1 ? "y" : "ies"} run across your own telemetry${result.modelName ? ` using ${result.modelName}` : ""}. This is an AI-generated first pass; verify before acting.*`;
252
+ return markdown;
253
+ }
254
+ // Refresh lastHeartbeatAt so a long-running investigation isn't swept as stale.
255
+ static async touchHeartbeat(aiRunId) {
256
+ try {
257
+ await AIRunService.updateOneBy({
258
+ query: { _id: aiRunId.toString(), status: AIRunStatus.Running },
259
+ data: {
260
+ lastHeartbeatAt: OneUptimeDate.getCurrentDate(),
261
+ },
262
+ props: { isRoot: true },
263
+ });
264
+ }
265
+ catch (error) {
266
+ logger.error(`Sentinel: heartbeat update failed: ${error}`);
267
+ }
268
+ }
269
+ static async emitEvent(data) {
270
+ try {
271
+ const event = new AIRunEvent();
272
+ event.projectId = data.projectId;
273
+ event.aiRunId = data.aiRunId;
274
+ event.sequence = data.sequence;
275
+ event.eventType = data.eventType;
276
+ if (data.toolName) {
277
+ event.toolName = data.toolName;
278
+ }
279
+ if (data.toolArguments) {
280
+ event.toolArguments = data.toolArguments;
281
+ }
282
+ if (data.resultSummary) {
283
+ event.resultSummary = data.resultSummary;
284
+ }
285
+ if (data.citationId) {
286
+ event.citationId = data.citationId;
287
+ }
288
+ await AIRunEventService.create({
289
+ data: event,
290
+ props: { isRoot: true },
291
+ });
292
+ }
293
+ catch (error) {
294
+ // Events are best-effort telemetry — never fail the run because of them.
295
+ logger.error(`Sentinel: failed to emit AIRunEvent: ${error}`);
296
+ }
297
+ }
298
+ }
299
+ __decorate([
300
+ CaptureSpan(),
301
+ __metadata("design:type", Function),
302
+ __metadata("design:paramtypes", [ObjectID, String]),
303
+ __metadata("design:returntype", Promise)
304
+ ], SentinelInvestigationEngine, "isEnabledForProject", null);
305
+ __decorate([
306
+ CaptureSpan(),
307
+ __metadata("design:type", Function),
308
+ __metadata("design:paramtypes", [Object]),
309
+ __metadata("design:returntype", Promise)
310
+ ], SentinelInvestigationEngine, "investigate", null);
311
+ //# sourceMappingURL=SentinelInvestigationEngine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SentinelInvestigationEngine.js","sourceRoot":"","sources":["../../../../../../Server/Utils/AI/Sentinel/SentinelInvestigationEngine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,143 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ var __metadata = (this && this.__metadata) || function (k, v) {
8
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
+ };
10
+ import SortOrder from "../../../../Types/BaseDatabase/SortOrder";
11
+ import IncidentService from "../../../Services/IncidentService";
12
+ import CaptureSpan from "../../Telemetry/CaptureSpan";
13
+ import logger from "../../Logger";
14
+ /*
15
+ * Sentinel — episodic memory (Phase 4, "I've seen this before").
16
+ *
17
+ * The first, no-new-storage cut of the recurrence short-circuit: instead of a
18
+ * vector store, retrieve past RESOLVED incidents in the same project that share
19
+ * monitors/labels with the current signal and carry a recorded root cause, then
20
+ * feed a compact digest into the investigation so the agent can recognise a
21
+ * recurrence and reference the prior fix.
22
+ *
23
+ * The full episodic store (pgvector embeddings over postmortems/runbooks + a
24
+ * temporal knowledge graph) is the deferred, larger build — this delivers the
25
+ * user-visible "this matches #123" behaviour on data we already own.
26
+ */
27
+ // How many recent incidents to consider, and how many prior cases to surface.
28
+ const CANDIDATE_LIMIT = 30;
29
+ const MAX_CASES = 4;
30
+ const MAX_ROOT_CAUSE_CHARS = 300;
31
+ const SHARED_MONITOR_SCORE = 2;
32
+ const SHARED_LABEL_SCORE = 1;
33
+ export default class SentinelMemory {
34
+ /*
35
+ * Returns a markdown "past resolved incidents" section to append to the
36
+ * investigation context, or an empty string when there is nothing useful.
37
+ * Never throws — memory is a nice-to-have, not load-bearing.
38
+ */
39
+ static async getPriorSimilarIncidentsContext(data) {
40
+ try {
41
+ const candidates = await IncidentService.findBy({
42
+ query: {
43
+ projectId: data.projectId,
44
+ },
45
+ select: {
46
+ _id: true,
47
+ incidentNumber: true,
48
+ title: true,
49
+ rootCause: true,
50
+ createdAt: true,
51
+ currentIncidentState: {
52
+ isResolvedState: true,
53
+ },
54
+ monitors: {
55
+ name: true,
56
+ },
57
+ labels: {
58
+ name: true,
59
+ },
60
+ },
61
+ sort: {
62
+ createdAt: SortOrder.Descending,
63
+ },
64
+ limit: CANDIDATE_LIMIT,
65
+ skip: 0,
66
+ props: { isRoot: true },
67
+ });
68
+ const currentIdString = data.currentIncidentId.toString();
69
+ const monitorSet = new Set(data.monitorNames.map((n) => {
70
+ return n.toLowerCase();
71
+ }));
72
+ const labelSet = new Set(data.labelNames.map((n) => {
73
+ return n.toLowerCase();
74
+ }));
75
+ const scored = candidates
76
+ .filter((incident) => {
77
+ var _a, _b;
78
+ return (((_a = incident.id) === null || _a === void 0 ? void 0 : _a.toString()) !== currentIdString &&
79
+ ((_b = incident.currentIncidentState) === null || _b === void 0 ? void 0 : _b.isResolvedState) === true &&
80
+ Boolean(incident.rootCause && incident.rootCause.trim().length > 0));
81
+ })
82
+ .map((incident) => {
83
+ let score = 0;
84
+ for (const monitor of incident.monitors || []) {
85
+ if (monitor.name && monitorSet.has(monitor.name.toLowerCase())) {
86
+ score += SHARED_MONITOR_SCORE;
87
+ }
88
+ }
89
+ for (const label of incident.labels || []) {
90
+ if (label.name && labelSet.has(label.name.toLowerCase())) {
91
+ score += SHARED_LABEL_SCORE;
92
+ }
93
+ }
94
+ return { incident, score };
95
+ });
96
+ /*
97
+ * Prefer cases that actually share a monitor/label; otherwise fall back to
98
+ * the most recent resolved incidents (V8's sort is stable, keeping recency).
99
+ */
100
+ const relevant = scored
101
+ .filter((item) => {
102
+ return item.score > 0;
103
+ })
104
+ .sort((a, b) => {
105
+ return b.score - a.score;
106
+ });
107
+ const chosen = (relevant.length > 0 ? relevant : scored).slice(0, MAX_CASES);
108
+ if (chosen.length === 0) {
109
+ return "";
110
+ }
111
+ let markdown = "\n\n# Past resolved incidents in this project (recurrence context)\n" +
112
+ "If the current signal matches one of these, this may be a recurrence — say so explicitly and reference the incident number and how it was resolved.\n";
113
+ for (const { incident } of chosen) {
114
+ const rootCause = (incident.rootCause || "").trim();
115
+ const shortRootCause = rootCause.length > MAX_ROOT_CAUSE_CHARS
116
+ ? `${rootCause.substring(0, MAX_ROOT_CAUSE_CHARS)}…`
117
+ : rootCause;
118
+ markdown += `\n- **#${incident.incidentNumber} — ${incident.title || "Untitled"}**`;
119
+ markdown += `\n Previously resolved. Root cause: ${shortRootCause}`;
120
+ const monitorNames = (incident.monitors || [])
121
+ .map((m) => {
122
+ return m.name || "";
123
+ })
124
+ .filter(Boolean);
125
+ if (monitorNames.length > 0) {
126
+ markdown += `\n Monitors: ${monitorNames.join(", ")}`;
127
+ }
128
+ }
129
+ return markdown;
130
+ }
131
+ catch (error) {
132
+ logger.error(`Sentinel: failed to load recurrence context: ${error}`);
133
+ return "";
134
+ }
135
+ }
136
+ }
137
+ __decorate([
138
+ CaptureSpan(),
139
+ __metadata("design:type", Function),
140
+ __metadata("design:paramtypes", [Object]),
141
+ __metadata("design:returntype", Promise)
142
+ ], SentinelMemory, "getPriorSimilarIncidentsContext", null);
143
+ //# sourceMappingURL=SentinelMemory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SentinelMemory.js","sourceRoot":"","sources":["../../../../../../Server/Utils/AI/Sentinel/SentinelMemory.ts"],"names":[],"mappings":"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"}
@@ -23,7 +23,7 @@ const resolveReadPermissions = () => {
23
23
  };
24
24
  export const QueryIncidentsTool = {
25
25
  name: "query_incidents",
26
- description: "Query incidents in this project. Returns the most recent incidents with their current state and severity. Pass incidentId to get full details of one incident.",
26
+ description: "Query incidents in this project. Returns the most recent incidents with their current state and severity. Pass incidentId to get full details of one incident — including its affected monitors, labels, root cause, remediation and postmortem notes, and the incident window (telemetryWindowStart) to pivot into logs/traces/metrics for the affected services.",
27
27
  inputSchema: {
28
28
  type: "object",
29
29
  properties: {
@@ -62,9 +62,41 @@ export const QueryIncidentsTool = {
62
62
  incidentSeverity: {
63
63
  name: true,
64
64
  },
65
+ monitors: {
66
+ _id: true,
67
+ name: true,
68
+ },
69
+ labels: {
70
+ name: true,
71
+ },
72
+ rootCause: true,
73
+ remediationNotes: true,
74
+ postmortemNote: true,
65
75
  },
66
76
  props: ctx.props,
67
77
  });
78
+ /*
79
+ * Surface the incident's blast radius (affected monitors + labels) and
80
+ * its own window so the model can pivot from an incident into the
81
+ * logs/traces/metrics of the affected services over the right time
82
+ * range, instead of guessing which service or hour to look at.
83
+ */
84
+ const affectedMonitors = ((incident === null || incident === void 0 ? void 0 : incident.monitors) || [])
85
+ .map((monitor) => {
86
+ return monitor.name || "";
87
+ })
88
+ .filter((value) => {
89
+ return value.length > 0;
90
+ })
91
+ .join(", ");
92
+ const incidentLabels = ((incident === null || incident === void 0 ? void 0 : incident.labels) || [])
93
+ .map((label) => {
94
+ return label.name || "";
95
+ })
96
+ .filter((value) => {
97
+ return value.length > 0;
98
+ })
99
+ .join(", ");
68
100
  const rows = incident
69
101
  ? [
70
102
  {
@@ -75,6 +107,12 @@ export const QueryIncidentsTool = {
75
107
  state: (_b = incident.currentIncidentState) === null || _b === void 0 ? void 0 : _b.name,
76
108
  severity: (_c = incident.incidentSeverity) === null || _c === void 0 ? void 0 : _c.name,
77
109
  createdAt: incident.createdAt,
110
+ affectedMonitors: affectedMonitors || undefined,
111
+ labels: incidentLabels || undefined,
112
+ rootCause: incident.rootCause,
113
+ remediationNotes: incident.remediationNotes,
114
+ postmortemNote: incident.postmortemNote,
115
+ telemetryWindowStart: incident.createdAt,
78
116
  },
79
117
  ]
80
118
  : [];
@@ -164,4 +202,117 @@ export const QueryIncidentsTool = {
164
202
  };
165
203
  },
166
204
  };
205
+ export const SearchIncidentsTool = {
206
+ name: "search_incidents",
207
+ description: "Search PAST incidents by free text across their title, description, root cause, remediation notes and postmortem. Use this to ground root-cause analysis in history — e.g. 'have we seen this error before, and how was it resolved?'. Returns matching incidents (most recent first) with their root cause and postmortem so you can reuse prior resolutions.",
208
+ inputSchema: {
209
+ type: "object",
210
+ properties: {
211
+ searchText: {
212
+ type: "string",
213
+ description: "Text to match (case-insensitive substring) across incident title, description, root cause, remediation notes and postmortem.",
214
+ },
215
+ createdWithinHours: {
216
+ type: "number",
217
+ description: "Only incidents created within this many hours (default 2160 = 90 days, max 8760 = 1 year).",
218
+ },
219
+ limit: {
220
+ type: "number",
221
+ description: "Maximum incidents to return (default 5, max 15).",
222
+ },
223
+ },
224
+ required: ["searchText"],
225
+ },
226
+ get requiredPermissions() {
227
+ return resolveReadPermissions();
228
+ },
229
+ execute: async (args, ctx) => {
230
+ const searchText = ToolArgs.getString(args, "searchText");
231
+ if (!searchText) {
232
+ return {
233
+ dataForLlm: "Error: searchText is required. Provide the text to search past incidents for.",
234
+ rowCount: 0,
235
+ citationLabel: "Incident search (no query)",
236
+ redactionCount: 0,
237
+ isTruncated: false,
238
+ };
239
+ }
240
+ const createdWithinHours = ToolArgs.getNumber(args, "createdWithinHours", { defaultValue: 2160, min: 1, max: 8760 });
241
+ const limit = ToolArgs.getNumber(args, "limit", {
242
+ defaultValue: 5,
243
+ min: 1,
244
+ max: 15,
245
+ });
246
+ const endTime = OneUptimeDate.getCurrentDate();
247
+ const startTime = OneUptimeDate.addRemoveHours(endTime, -1 * createdWithinHours);
248
+ const incidents = await IncidentService.findBy({
249
+ query: {
250
+ createdAt: QueryHelper.inBetween(startTime, endTime),
251
+ /*
252
+ * The OR-joined ILIKE Raw references the listed columns, not the
253
+ * attached property — this is the established multiSearch attachment
254
+ * pattern (see QueryUtil).
255
+ */
256
+ title: QueryHelper.multiSearch([
257
+ "title",
258
+ "description",
259
+ "rootCause",
260
+ "remediationNotes",
261
+ "postmortemNote",
262
+ ], searchText),
263
+ },
264
+ select: {
265
+ _id: true,
266
+ title: true,
267
+ incidentNumber: true,
268
+ createdAt: true,
269
+ currentIncidentState: {
270
+ name: true,
271
+ },
272
+ incidentSeverity: {
273
+ name: true,
274
+ },
275
+ rootCause: true,
276
+ postmortemNote: true,
277
+ },
278
+ sort: {
279
+ createdAt: SortOrder.Descending,
280
+ },
281
+ limit: limit,
282
+ skip: 0,
283
+ props: ctx.props,
284
+ });
285
+ const rows = incidents.map((incident) => {
286
+ var _a, _b, _c;
287
+ return {
288
+ id: (_a = incident.id) === null || _a === void 0 ? void 0 : _a.toString(),
289
+ incidentNumber: incident.incidentNumber,
290
+ title: incident.title,
291
+ state: (_b = incident.currentIncidentState) === null || _b === void 0 ? void 0 : _b.name,
292
+ severity: (_c = incident.incidentSeverity) === null || _c === void 0 ? void 0 : _c.name,
293
+ createdAt: incident.createdAt,
294
+ rootCause: incident.rootCause,
295
+ postmortemNote: incident.postmortemNote,
296
+ };
297
+ });
298
+ const serialized = ToolResultSerializer.serializeRows(rows);
299
+ return {
300
+ dataForLlm: serialized.text,
301
+ rowCount: serialized.rowCount,
302
+ citationLabel: `Incident search "${searchText}" (${serialized.rowCount} found)`,
303
+ citationTarget: {
304
+ type: AIChatCitationTargetType.Incidents,
305
+ },
306
+ redactionCount: serialized.redactionCount,
307
+ isTruncated: serialized.isTruncated,
308
+ widget: rows.length > 0
309
+ ? WidgetBuilder.incidentList({
310
+ title: `Incidents matching "${searchText}" (${rows.length})`,
311
+ items: rows,
312
+ link: { type: AIChatCitationTargetType.Incidents },
313
+ })
314
+ : undefined,
315
+ };
316
+ },
317
+ };
167
318
  //# sourceMappingURL=IncidentTools.js.map