@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
@@ -122,7 +122,7 @@ export default class AlertAPI extends BaseAPI<Alert, AlertServiceType> {
122
122
  alertId: alertId,
123
123
  messages: aiContext.messages,
124
124
  maxTokens: 4096,
125
- temperature: 0.7,
125
+ temperature: 0.2,
126
126
  };
127
127
 
128
128
  if (props.userId) {
@@ -230,7 +230,7 @@ export default class IncidentAPI extends BaseAPI<
230
230
  incidentId: incidentId,
231
231
  messages: aiContext.messages,
232
232
  maxTokens: 8192,
233
- temperature: 0.7,
233
+ temperature: 0.2,
234
234
  };
235
235
 
236
236
  if (props.userId) {
@@ -347,7 +347,7 @@ export default class IncidentAPI extends BaseAPI<
347
347
  incidentId: incidentId,
348
348
  messages: aiContext.messages,
349
349
  maxTokens: 4096,
350
- temperature: 0.7,
350
+ temperature: 0.2,
351
351
  };
352
352
 
353
353
  if (props.userId) {
@@ -133,7 +133,7 @@ export default class IncidentEpisodeAPI extends BaseAPI<
133
133
  feature: "Incident Episode Postmortem",
134
134
  messages: aiContext.messages,
135
135
  maxTokens: 8192,
136
- temperature: 0.7,
136
+ temperature: 0.2,
137
137
  };
138
138
 
139
139
  if (props.userId) {
@@ -42,6 +42,7 @@ export default class LlmProviderAPI extends BaseAPI<
42
42
  select: {
43
43
  name: true,
44
44
  description: true,
45
+ costPerMillionTokensInUSDCents: true,
45
46
  },
46
47
  props: {
47
48
  isRoot: true,
@@ -147,7 +147,7 @@ export default class ScheduledMaintenanceAPI extends BaseAPI<
147
147
  scheduledMaintenanceId: scheduledMaintenanceId,
148
148
  messages: aiContext.messages,
149
149
  maxTokens: 4096,
150
- temperature: 0.7,
150
+ temperature: 0.2,
151
151
  };
152
152
 
153
153
  if (props.userId) {
@@ -0,0 +1,25 @@
1
+ import { MigrationInterface, QueryRunner } from "typeorm";
2
+
3
+ export class AddIncomingCallPolicyRoutingPhoneNumberUnique1783470000000
4
+ implements MigrationInterface
5
+ {
6
+ public name = "AddIncomingCallPolicyRoutingPhoneNumberUnique1783470000000";
7
+
8
+ public async up(queryRunner: QueryRunner): Promise<void> {
9
+ /*
10
+ * Enforce that a routing phone number belongs to at most one policy. The
11
+ * inbound /voice webhook resolves the policy by routingPhoneNumber and
12
+ * assumes a single match. Partial index so policies without a number (NULL)
13
+ * are unconstrained and soft-deleted rows never collide.
14
+ */
15
+ await queryRunner.query(
16
+ `CREATE UNIQUE INDEX "IDX_INCOMING_CALL_POLICY_ROUTING_PHONE_UNIQUE" ON "IncomingCallPolicy" ("routingPhoneNumber") WHERE ("deletedAt" IS NULL AND "routingPhoneNumber" IS NOT NULL)`,
17
+ );
18
+ }
19
+
20
+ public async down(queryRunner: QueryRunner): Promise<void> {
21
+ await queryRunner.query(
22
+ `DROP INDEX "public"."IDX_INCOMING_CALL_POLICY_ROUTING_PHONE_UNIQUE"`,
23
+ );
24
+ }
25
+ }
@@ -0,0 +1,81 @@
1
+ import { MigrationInterface, QueryRunner } from "typeorm";
2
+
3
+ /**
4
+ * These foreign keys previously used `ON DELETE SET NULL` even though their
5
+ * referencing columns are `NOT NULL`. Deleting the referenced row (e.g. a User
6
+ * or an IncidentRole) therefore tried to set the column to NULL and failed with
7
+ * a not-null constraint violation. Since each of these columns is required, the
8
+ * dependent row is meaningless without its parent, so the correct behavior is
9
+ * `ON DELETE CASCADE`.
10
+ */
11
+ export class FixNotNullForeignKeysOnDelete1783510935686
12
+ implements MigrationInterface
13
+ {
14
+ public name = "FixNotNullForeignKeysOnDelete1783510935686";
15
+
16
+ public async up(queryRunner: QueryRunner): Promise<void> {
17
+ await queryRunner.query(
18
+ `ALTER TABLE "IncidentMember" DROP CONSTRAINT "FK_6e8334ec5b25d596548c88d0832"`,
19
+ );
20
+ await queryRunner.query(
21
+ `ALTER TABLE "OnCallDutyPolicyTimeLog" DROP CONSTRAINT "FK_43da7ffeee531e9452d36a89ba5"`,
22
+ );
23
+ await queryRunner.query(
24
+ `ALTER TABLE "IncidentEpisodeRoleMember" DROP CONSTRAINT "FK_08c8933e37d14069c0d18b34f14"`,
25
+ );
26
+ await queryRunner.query(
27
+ `ALTER TABLE "OnCallDutyPolicyUserOverride" DROP CONSTRAINT "FK_4b3f696aaaf327b245ebeb3d146"`,
28
+ );
29
+ await queryRunner.query(
30
+ `ALTER TABLE "OnCallDutyPolicyUserOverride" DROP CONSTRAINT "FK_8771068ec4c16763a7ff796895d"`,
31
+ );
32
+ await queryRunner.query(
33
+ `ALTER TABLE "IncidentMember" ADD CONSTRAINT "FK_6e8334ec5b25d596548c88d0832" FOREIGN KEY ("incidentRoleId") REFERENCES "IncidentRole"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
34
+ );
35
+ await queryRunner.query(
36
+ `ALTER TABLE "OnCallDutyPolicyTimeLog" ADD CONSTRAINT "FK_43da7ffeee531e9452d36a89ba5" FOREIGN KEY ("userId") REFERENCES "User"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
37
+ );
38
+ await queryRunner.query(
39
+ `ALTER TABLE "IncidentEpisodeRoleMember" ADD CONSTRAINT "FK_08c8933e37d14069c0d18b34f14" FOREIGN KEY ("incidentRoleId") REFERENCES "IncidentRole"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
40
+ );
41
+ await queryRunner.query(
42
+ `ALTER TABLE "OnCallDutyPolicyUserOverride" ADD CONSTRAINT "FK_4b3f696aaaf327b245ebeb3d146" FOREIGN KEY ("overrideUserId") REFERENCES "User"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
43
+ );
44
+ await queryRunner.query(
45
+ `ALTER TABLE "OnCallDutyPolicyUserOverride" ADD CONSTRAINT "FK_8771068ec4c16763a7ff796895d" FOREIGN KEY ("routeAlertsToUserId") REFERENCES "User"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
46
+ );
47
+ }
48
+
49
+ public async down(queryRunner: QueryRunner): Promise<void> {
50
+ await queryRunner.query(
51
+ `ALTER TABLE "OnCallDutyPolicyUserOverride" DROP CONSTRAINT "FK_8771068ec4c16763a7ff796895d"`,
52
+ );
53
+ await queryRunner.query(
54
+ `ALTER TABLE "OnCallDutyPolicyUserOverride" DROP CONSTRAINT "FK_4b3f696aaaf327b245ebeb3d146"`,
55
+ );
56
+ await queryRunner.query(
57
+ `ALTER TABLE "IncidentEpisodeRoleMember" DROP CONSTRAINT "FK_08c8933e37d14069c0d18b34f14"`,
58
+ );
59
+ await queryRunner.query(
60
+ `ALTER TABLE "OnCallDutyPolicyTimeLog" DROP CONSTRAINT "FK_43da7ffeee531e9452d36a89ba5"`,
61
+ );
62
+ await queryRunner.query(
63
+ `ALTER TABLE "IncidentMember" DROP CONSTRAINT "FK_6e8334ec5b25d596548c88d0832"`,
64
+ );
65
+ await queryRunner.query(
66
+ `ALTER TABLE "OnCallDutyPolicyUserOverride" ADD CONSTRAINT "FK_8771068ec4c16763a7ff796895d" FOREIGN KEY ("routeAlertsToUserId") REFERENCES "User"("_id") ON DELETE SET NULL ON UPDATE NO ACTION`,
67
+ );
68
+ await queryRunner.query(
69
+ `ALTER TABLE "OnCallDutyPolicyUserOverride" ADD CONSTRAINT "FK_4b3f696aaaf327b245ebeb3d146" FOREIGN KEY ("overrideUserId") REFERENCES "User"("_id") ON DELETE SET NULL ON UPDATE NO ACTION`,
70
+ );
71
+ await queryRunner.query(
72
+ `ALTER TABLE "IncidentEpisodeRoleMember" ADD CONSTRAINT "FK_08c8933e37d14069c0d18b34f14" FOREIGN KEY ("incidentRoleId") REFERENCES "IncidentRole"("_id") ON DELETE SET NULL ON UPDATE NO ACTION`,
73
+ );
74
+ await queryRunner.query(
75
+ `ALTER TABLE "OnCallDutyPolicyTimeLog" ADD CONSTRAINT "FK_43da7ffeee531e9452d36a89ba5" FOREIGN KEY ("userId") REFERENCES "User"("_id") ON DELETE SET NULL ON UPDATE NO ACTION`,
76
+ );
77
+ await queryRunner.query(
78
+ `ALTER TABLE "IncidentMember" ADD CONSTRAINT "FK_6e8334ec5b25d596548c88d0832" FOREIGN KEY ("incidentRoleId") REFERENCES "IncidentRole"("_id") ON DELETE SET NULL ON UPDATE NO ACTION`,
79
+ );
80
+ }
81
+ }
@@ -0,0 +1,25 @@
1
+ import { MigrationInterface, QueryRunner } from "typeorm";
2
+
3
+ export class MigrationName1783515836148 implements MigrationInterface {
4
+ public name = "MigrationName1783515836148";
5
+
6
+ public async up(queryRunner: QueryRunner): Promise<void> {
7
+ // HIGH-5: schedule timezone (nullable => existing schedules keep legacy server-local behavior).
8
+ await queryRunner.query(
9
+ `ALTER TABLE "OnCallDutyPolicySchedule" ADD "timezone" character varying(100)`,
10
+ );
11
+ // M-5: bounded retry counter for escalation rules that momentarily resolve to no on-call user.
12
+ await queryRunner.query(
13
+ `ALTER TABLE "OnCallDutyPolicyExecutionLog" ADD "scheduleGapRetryCount" integer NOT NULL DEFAULT '0'`,
14
+ );
15
+ }
16
+
17
+ public async down(queryRunner: QueryRunner): Promise<void> {
18
+ await queryRunner.query(
19
+ `ALTER TABLE "OnCallDutyPolicyExecutionLog" DROP COLUMN "scheduleGapRetryCount"`,
20
+ );
21
+ await queryRunner.query(
22
+ `ALTER TABLE "OnCallDutyPolicySchedule" DROP COLUMN "timezone"`,
23
+ );
24
+ }
25
+ }
@@ -0,0 +1,35 @@
1
+ import { MigrationInterface, QueryRunner } from "typeorm";
2
+
3
+ export class AddMigrationFailureTable1783523076215
4
+ implements MigrationInterface
5
+ {
6
+ public name = "AddMigrationFailureTable1783523076215";
7
+
8
+ public async up(queryRunner: QueryRunner): Promise<void> {
9
+ await queryRunner.query(
10
+ `CREATE TABLE "MigrationFailure" ("_id" uuid NOT NULL DEFAULT uuid_generate_v4(), "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "deletedAt" TIMESTAMP WITH TIME ZONE, "version" integer NOT NULL, "migrationName" character varying(100) NOT NULL, "migrationType" character varying(100) NOT NULL, "errorMessage" text NOT NULL, "errorStack" text, "attemptedAt" TIMESTAMP WITH TIME ZONE NOT NULL, "hostName" character varying(100), "appVersion" character varying(100), CONSTRAINT "PK_db298508bb9e7064755c660eb8b" PRIMARY KEY ("_id"))`,
11
+ );
12
+ await queryRunner.query(
13
+ `CREATE INDEX "IDX_afd3cf5c9703ef3cd3f74bcecf" ON "MigrationFailure" ("migrationName") `,
14
+ );
15
+ await queryRunner.query(
16
+ `CREATE INDEX "IDX_0e4fbfab7ec24121ac4fc66d64" ON "MigrationFailure" ("migrationType") `,
17
+ );
18
+ await queryRunner.query(
19
+ `CREATE INDEX "IDX_d0f64f28973facc22ab17764e4" ON "MigrationFailure" ("attemptedAt") `,
20
+ );
21
+ }
22
+
23
+ public async down(queryRunner: QueryRunner): Promise<void> {
24
+ await queryRunner.query(
25
+ `DROP INDEX "public"."IDX_d0f64f28973facc22ab17764e4"`,
26
+ );
27
+ await queryRunner.query(
28
+ `DROP INDEX "public"."IDX_0e4fbfab7ec24121ac4fc66d64"`,
29
+ );
30
+ await queryRunner.query(
31
+ `DROP INDEX "public"."IDX_afd3cf5c9703ef3cd3f74bcecf"`,
32
+ );
33
+ await queryRunner.query(`DROP TABLE "MigrationFailure"`);
34
+ }
35
+ }
@@ -0,0 +1,19 @@
1
+ import { MigrationInterface, QueryRunner } from "typeorm";
2
+
3
+ export class AddEnableAutomaticIncidentInvestigationToProject1783598145111
4
+ implements MigrationInterface
5
+ {
6
+ public name = "AddEnableAutomaticIncidentInvestigationToProject1783598145111";
7
+
8
+ public async up(queryRunner: QueryRunner): Promise<void> {
9
+ await queryRunner.query(
10
+ `ALTER TABLE "Project" ADD "enableAutomaticIncidentInvestigation" boolean NOT NULL DEFAULT false`,
11
+ );
12
+ }
13
+
14
+ public async down(queryRunner: QueryRunner): Promise<void> {
15
+ await queryRunner.query(
16
+ `ALTER TABLE "Project" DROP COLUMN "enableAutomaticIncidentInvestigation"`,
17
+ );
18
+ }
19
+ }
@@ -0,0 +1,33 @@
1
+ import { MigrationInterface, QueryRunner } from "typeorm";
2
+
3
+ export class AddInvestigationSubjectToAIRun1783615884106
4
+ implements MigrationInterface
5
+ {
6
+ public name = "AddInvestigationSubjectToAIRun1783615884106";
7
+
8
+ public async up(queryRunner: QueryRunner): Promise<void> {
9
+ await queryRunner.query(
10
+ `ALTER TABLE "AIRun" ADD "triggeredByIncidentId" uuid`,
11
+ );
12
+ await queryRunner.query(
13
+ `ALTER TABLE "AIRun" ADD "triggeredByAlertId" uuid`,
14
+ );
15
+ await queryRunner.query(
16
+ `CREATE INDEX "IDX_AIRun_triggeredByIncidentId" ON "AIRun" ("triggeredByIncidentId")`,
17
+ );
18
+ await queryRunner.query(
19
+ `CREATE INDEX "IDX_AIRun_triggeredByAlertId" ON "AIRun" ("triggeredByAlertId")`,
20
+ );
21
+ }
22
+
23
+ public async down(queryRunner: QueryRunner): Promise<void> {
24
+ await queryRunner.query(`DROP INDEX "IDX_AIRun_triggeredByAlertId"`);
25
+ await queryRunner.query(`DROP INDEX "IDX_AIRun_triggeredByIncidentId"`);
26
+ await queryRunner.query(
27
+ `ALTER TABLE "AIRun" DROP COLUMN "triggeredByAlertId"`,
28
+ );
29
+ await queryRunner.query(
30
+ `ALTER TABLE "AIRun" DROP COLUMN "triggeredByIncidentId"`,
31
+ );
32
+ }
33
+ }
@@ -0,0 +1,19 @@
1
+ import { MigrationInterface, QueryRunner } from "typeorm";
2
+
3
+ export class AddEnableAutomaticAlertInvestigationToProject1783632447975
4
+ implements MigrationInterface
5
+ {
6
+ public name = "AddEnableAutomaticAlertInvestigationToProject1783632447975";
7
+
8
+ public async up(queryRunner: QueryRunner): Promise<void> {
9
+ await queryRunner.query(
10
+ `ALTER TABLE "Project" ADD "enableAutomaticAlertInvestigation" boolean NOT NULL DEFAULT false`,
11
+ );
12
+ }
13
+
14
+ public async down(queryRunner: QueryRunner): Promise<void> {
15
+ await queryRunner.query(
16
+ `ALTER TABLE "Project" DROP COLUMN "enableAutomaticAlertInvestigation"`,
17
+ );
18
+ }
19
+ }
@@ -413,6 +413,13 @@ import { AddAIChatModels1783363279075 } from "./1783363279075-AddAIChatModels";
413
413
  import { AddLlmProviderToAIConversation1783443471795 } from "./1783443471795-AddLlmProviderToAIConversation";
414
414
  import { AddAIChatWriteActionsAndWidgets1783453297388 } from "./1783453297388-AddAIChatWriteActionsAndWidgets";
415
415
  import { MigrationName1783461767405 } from "./1783461767405-MigrationName";
416
+ import { AddIncomingCallPolicyRoutingPhoneNumberUnique1783470000000 } from "./1783470000000-AddIncomingCallPolicyRoutingPhoneNumberUnique";
417
+ import { FixNotNullForeignKeysOnDelete1783510935686 } from "./1783510935686-FixNotNullForeignKeysOnDelete";
418
+ import { MigrationName1783515836148 } from "./1783515836148-MigrationName";
419
+ import { AddMigrationFailureTable1783523076215 } from "./1783523076215-AddMigrationFailureTable";
420
+ import { AddEnableAutomaticIncidentInvestigationToProject1783598145111 } from "./1783598145111-AddEnableAutomaticIncidentInvestigationToProject";
421
+ import { AddInvestigationSubjectToAIRun1783615884106 } from "./1783615884106-AddInvestigationSubjectToAIRun";
422
+ import { AddEnableAutomaticAlertInvestigationToProject1783632447975 } from "./1783632447975-AddEnableAutomaticAlertInvestigationToProject";
416
423
 
417
424
  export default [
418
425
  InitialMigration,
@@ -830,4 +837,11 @@ export default [
830
837
  AddLlmProviderToAIConversation1783443471795,
831
838
  AddAIChatWriteActionsAndWidgets1783453297388,
832
839
  MigrationName1783461767405,
840
+ AddIncomingCallPolicyRoutingPhoneNumberUnique1783470000000,
841
+ FixNotNullForeignKeysOnDelete1783510935686,
842
+ MigrationName1783515836148,
843
+ AddMigrationFailureTable1783523076215,
844
+ AddEnableAutomaticIncidentInvestigationToProject1783598145111,
845
+ AddInvestigationSubjectToAIRun1783615884106,
846
+ AddEnableAutomaticAlertInvestigationToProject1783632447975,
833
847
  ];
@@ -1,5 +1,6 @@
1
1
  import logger from "../Utils/Logger";
2
2
  import DatabaseDataSourceOptions from "./Postgres/DataSourceOptions";
3
+ import { recordSchemaMigrationFailureBestEffort } from "../Utils/Database/MigrationFailureLog";
3
4
  import Sleep from "../../Types/Sleep";
4
5
  import { DataSource, DataSourceOptions, QueryRunner } from "typeorm";
5
6
  import { createDatabase, dropDatabase } from "typeorm-extension";
@@ -95,6 +96,16 @@ export default class Database {
95
96
  } catch (err) {
96
97
  logger.error("Postgres Database Connection Failed");
97
98
  logger.error(err);
99
+
100
+ /*
101
+ * When this process runs schema migrations on boot (migrationsRun=true),
102
+ * connect() also fails if a migration threw. Record which migration
103
+ * failed and why — on a throwaway connection, since the DataSource above
104
+ * is unusable — so the admin health page can explain the pending schema.
105
+ * Best-effort and self-contained: it never throws and never masks `err`.
106
+ */
107
+ await recordSchemaMigrationFailureBestEffort(dataSourceOptions, err);
108
+
98
109
  throw err;
99
110
  }
100
111
  }
@@ -11,7 +11,10 @@ import LLMService, {
11
11
  LLMMessage,
12
12
  LLMToolCall,
13
13
  LLMToolDefinition,
14
+ LLMUsage,
14
15
  } from "../Utils/LLM/LLMService";
16
+ import LlmType from "../../Types/LLM/LlmType";
17
+ import { Span, trace } from "@opentelemetry/api";
15
18
  import LlmProvider from "../../Models/DatabaseModels/LlmProvider";
16
19
  import LlmLog from "../../Models/DatabaseModels/LlmLog";
17
20
  import LlmLogStatus from "../../Types/LlmLogStatus";
@@ -129,9 +132,17 @@ export class Service extends BaseService {
129
132
  logEntry.aiRunId = request.aiRunId;
130
133
  }
131
134
 
132
- // Check if billing should apply
135
+ /*
136
+ * Check if billing should apply. Only bill for the global (OneUptime-hosted)
137
+ * provider, and only when it actually has a per-token cost. A free global
138
+ * provider (costPerMillionTokensInUSDCents = 0, the default) consumes no
139
+ * balance, so it must not require or block on one either — otherwise a $0
140
+ * provider would still fail with "Insufficient AI balance".
141
+ */
133
142
  const shouldBill: boolean =
134
- IsBillingEnabled && (llmProvider.isGlobalLlm || false);
143
+ IsBillingEnabled &&
144
+ (llmProvider.isGlobalLlm || false) &&
145
+ (llmProvider.costPerMillionTokensInUSDCents || 0) > 0;
135
146
 
136
147
  // Check balance if billing enabled and using global provider
137
148
  if (shouldBill) {
@@ -234,6 +245,18 @@ export class Service extends BaseService {
234
245
  }
235
246
  }
236
247
 
248
+ /*
249
+ * Emit gen_ai.* semantic-convention attributes on the active span so
250
+ * OneUptime's own AI usage is a first-class LLM span in OneUptime's own
251
+ * telemetry (dogfooding — LlmSpanUtil detects these). Never fails the call.
252
+ */
253
+ this.setGenAiSpanAttributes({
254
+ llmType: llmProvider.llmType,
255
+ modelName: llmConfig.modelName,
256
+ usage: response.usage,
257
+ costInUSDCents: logEntry.costInUSDCents,
258
+ });
259
+
237
260
  // Save log entry
238
261
  const savedLog: LlmLog = await LlmLogService.create({
239
262
  data: logEntry,
@@ -261,6 +284,55 @@ export class Service extends BaseService {
261
284
  throw error;
262
285
  }
263
286
  }
287
+
288
+ /*
289
+ * Set gen_ai.* attributes (OpenTelemetry GenAI semantic conventions) on the
290
+ * currently-active span. The @CaptureSpan()-wrapped caller owns that span, so
291
+ * LlmSpanUtil recognizes these calls as first-class LLM spans.
292
+ */
293
+ private setGenAiSpanAttributes(data: {
294
+ llmType: LlmType;
295
+ modelName?: string | undefined;
296
+ usage?: LLMUsage | undefined;
297
+ costInUSDCents?: number | undefined;
298
+ }): void {
299
+ try {
300
+ const span: Span | undefined = trace.getActiveSpan();
301
+ if (!span) {
302
+ return;
303
+ }
304
+
305
+ span.setAttribute("gen_ai.system", data.llmType.toString());
306
+ span.setAttribute("gen_ai.provider.name", data.llmType.toString());
307
+ span.setAttribute("gen_ai.operation.name", "chat");
308
+
309
+ if (data.modelName) {
310
+ span.setAttribute("gen_ai.request.model", data.modelName);
311
+ span.setAttribute("gen_ai.response.model", data.modelName);
312
+ }
313
+
314
+ if (data.usage) {
315
+ span.setAttribute(
316
+ "gen_ai.usage.input_tokens",
317
+ data.usage.promptTokens || 0,
318
+ );
319
+ span.setAttribute(
320
+ "gen_ai.usage.output_tokens",
321
+ data.usage.completionTokens || 0,
322
+ );
323
+ span.setAttribute(
324
+ "gen_ai.usage.total_tokens",
325
+ data.usage.totalTokens || 0,
326
+ );
327
+ }
328
+
329
+ if (data.costInUSDCents) {
330
+ span.setAttribute("gen_ai.usage.cost_usd", data.costInUSDCents / 100);
331
+ }
332
+ } catch {
333
+ // Telemetry must never fail the LLM call.
334
+ }
335
+ }
264
336
  }
265
337
 
266
338
  export default new Service();
@@ -67,6 +67,7 @@ import AlertLabelRuleEngineService from "./AlertLabelRuleEngineService";
67
67
  import AlertOnCallRuleEngineService from "./AlertOnCallRuleEngineService";
68
68
  import AlertOwnerRuleEngineService from "./AlertOwnerRuleEngineService";
69
69
  import RunbookRuleEngineService from "./RunbookRuleEngineService";
70
+ import SentinelAlertInvestigationRunner from "../Utils/AI/Sentinel/AlertInvestigationRunner";
70
71
  import AlertPrivacyRuleEngineService from "./AlertPrivacyRuleEngineService";
71
72
  import ProjectService from "./ProjectService";
72
73
 
@@ -558,6 +559,30 @@ export class Service extends DatabaseService<Model> {
558
559
  );
559
560
  }
560
561
  })
562
+ .then(async () => {
563
+ /*
564
+ * Sentinel (AI SRE): automatically investigate the new alert and post a
565
+ * cited root cause analysis to the alert timeline + Slack/Teams. Runs
566
+ * last, is gated per project (opt-in) + requires an LLM provider, and is
567
+ * read-only.
568
+ */
569
+ try {
570
+ if (createdItem.projectId && createdItem.id) {
571
+ await SentinelAlertInvestigationRunner.investigateNewAlert({
572
+ alertId: createdItem.id,
573
+ projectId: createdItem.projectId,
574
+ });
575
+ }
576
+ } catch (error) {
577
+ logger.error(
578
+ `Sentinel alert investigation failed in AlertService.onCreateSuccess: ${error}`,
579
+ {
580
+ projectId: createdItem.projectId?.toString(),
581
+ alertId: createdItem.id?.toString(),
582
+ } as LogAttributes,
583
+ );
584
+ }
585
+ })
561
586
  .catch((error: Error) => {
562
587
  logger.error(
563
588
  `Critical error in AlertService sequential operations: ${error}`,
@@ -1899,7 +1899,16 @@ export default class AnalyticsDatabaseService<
1899
1899
  return data;
1900
1900
  }
1901
1901
 
1902
- protected async getException(error: Exception): Promise<void> {
1902
+ /*
1903
+ * Rethrow hook for the catch blocks below. MUST stay synchronous and
1904
+ * `never`-returning: the call sites use `throw this.getException(error)`,
1905
+ * so if this were `async` it would return a Promise that `throw` then
1906
+ * throws verbatim (never awaited) — the real exception is lost, callers up
1907
+ * the stack catch a bare Promise (surfacing as "[object Promise]"), and the
1908
+ * un-awaited rejection becomes an unhandled rejection. Throwing directly
1909
+ * propagates the original exception on the synchronous throw path.
1910
+ */
1911
+ protected getException(error: Exception): never {
1903
1912
  throw error;
1904
1913
  }
1905
1914
 
@@ -443,7 +443,16 @@ class DatabaseService<TBaseModel extends BaseModel> extends BaseService {
443
443
  return Promise.resolve(error);
444
444
  }
445
445
 
446
- protected async getException(error: Exception): Promise<void> {
446
+ /*
447
+ * Rethrow hook for the catch blocks below. MUST stay synchronous and
448
+ * `never`-returning: the call sites use `throw this.getException(error)`,
449
+ * so if this were `async` it would return a Promise that `throw` then
450
+ * throws verbatim (never awaited) — the real exception is lost, callers up
451
+ * the stack catch a bare Promise (surfacing as "[object Promise]"), and the
452
+ * un-awaited rejection becomes an unhandled rejection. Throwing directly
453
+ * propagates the original exception on the synchronous throw path.
454
+ */
455
+ protected getException(error: Exception): never {
447
456
  throw error;
448
457
  }
449
458
 
@@ -89,6 +89,7 @@ import LLMService, {
89
89
  } from "../Utils/LLM/LLMService";
90
90
  import LlmProviderService from "./LlmProviderService";
91
91
  import LlmProvider from "../../Models/DatabaseModels/LlmProvider";
92
+ import SentinelIncidentInvestigationRunner from "../Utils/AI/Sentinel/IncidentInvestigationRunner";
92
93
  import IncidentAIContextBuilder, {
93
94
  AIGenerationContext,
94
95
  IncidentContextData,
@@ -1241,6 +1242,30 @@ export class Service extends DatabaseService<Model> {
1241
1242
  );
1242
1243
  }
1243
1244
  })
1245
+ .then(async () => {
1246
+ /*
1247
+ * Sentinel (AI SRE): automatically investigate the new incident and post
1248
+ * a cited root cause analysis to the incident timeline + Slack/Teams.
1249
+ * Runs last so the workspace channels already exist, and is gated per
1250
+ * project (opt-in) + requires a configured LLM provider. Read-only.
1251
+ */
1252
+ try {
1253
+ if (createdItem.projectId && createdItem.id) {
1254
+ await SentinelIncidentInvestigationRunner.investigateNewIncident({
1255
+ incidentId: createdItem.id,
1256
+ projectId: createdItem.projectId,
1257
+ });
1258
+ }
1259
+ } catch (error) {
1260
+ logger.error(
1261
+ `Sentinel incident investigation failed in IncidentService.onCreateSuccess: ${error}`,
1262
+ {
1263
+ projectId: createdItem.projectId?.toString(),
1264
+ incidentId: createdItem.id?.toString(),
1265
+ } as LogAttributes,
1266
+ );
1267
+ }
1268
+ })
1244
1269
  .catch((error: Error) => {
1245
1270
  logger.error(
1246
1271
  `Critical error in IncidentService sequential operations: ${error}`,
@@ -3479,7 +3504,7 @@ ${incidentSeverity.name}
3479
3504
  const response: LLMCompletionResponse = await LLMService.getCompletion({
3480
3505
  llmProviderConfig: llmConfig,
3481
3506
  messages: aiContext.messages,
3482
- temperature: 0.7,
3507
+ temperature: 0.2,
3483
3508
  });
3484
3509
 
3485
3510
  return response.content;
@@ -27,6 +27,7 @@ import IncidentRole from "../../Models/DatabaseModels/IncidentRole";
27
27
  import { IsBillingEnabled } from "../EnvironmentConfig";
28
28
  import logger, { LogAttributes } from "../Utils/Logger";
29
29
  import IncidentFeedService from "./IncidentFeedService";
30
+ import SentinelIncidentPostmortemRunner from "../Utils/AI/Sentinel/IncidentPostmortemRunner";
30
31
  import { IncidentFeedEventType } from "../../Models/DatabaseModels/IncidentFeed";
31
32
  import CaptureSpan from "../Utils/Telemetry/CaptureSpan";
32
33
  import { LIMIT_PER_PROJECT } from "../../Types/Database/LimitMax";
@@ -555,6 +556,24 @@ ${createdItem.rootCause}`,
555
556
  createdItem.startsAt || undefined,
556
557
  );
557
558
  }
559
+
560
+ /*
561
+ * Sentinel: auto-draft a postmortem now that the incident is resolved
562
+ * (gated per project; never overwrites an existing postmortem).
563
+ */
564
+ SentinelIncidentPostmortemRunner.draftPostmortemOnResolve({
565
+ incidentId: createdItem.incidentId!,
566
+ projectId: createdItem.projectId!,
567
+ }).catch((error: Error) => {
568
+ logger.error(`Sentinel auto-postmortem failed on resolve:`, {
569
+ projectId: createdItem.projectId?.toString(),
570
+ incidentId: createdItem.incidentId?.toString(),
571
+ } as LogAttributes);
572
+ logger.error(error, {
573
+ projectId: createdItem.projectId?.toString(),
574
+ incidentId: createdItem.incidentId?.toString(),
575
+ } as LogAttributes);
576
+ });
558
577
  }
559
578
 
560
579
  if (onCreate.carryForward.publicNote) {