@oneuptime/common 11.3.26 → 11.3.28

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 (241) hide show
  1. package/Models/DatabaseModels/IncidentEpisodeRoleMember.ts +1 -1
  2. package/Models/DatabaseModels/IncidentMember.ts +1 -1
  3. package/Models/DatabaseModels/IncomingCallPolicy.ts +13 -0
  4. package/Models/DatabaseModels/Index.ts +3 -0
  5. package/Models/DatabaseModels/MigrationFailure.ts +170 -0
  6. package/Models/DatabaseModels/OnCallDutyPolicyExecutionLog.ts +51 -2
  7. package/Models/DatabaseModels/OnCallDutyPolicySchedule.ts +44 -0
  8. package/Models/DatabaseModels/OnCallDutyPolicyScheduleLayer.ts +6 -0
  9. package/Models/DatabaseModels/OnCallDutyPolicyScheduleLayerUser.ts +6 -0
  10. package/Models/DatabaseModels/OnCallDutyPolicyTimeLog.ts +1 -1
  11. package/Models/DatabaseModels/OnCallDutyPolicyUserOverride.ts +2 -2
  12. package/Server/API/AlertAPI.ts +1 -1
  13. package/Server/API/IncidentAPI.ts +2 -2
  14. package/Server/API/IncidentEpisodeAPI.ts +1 -1
  15. package/Server/API/LlmProviderAPI.ts +1 -0
  16. package/Server/API/ScheduledMaintenanceAPI.ts +1 -1
  17. package/Server/Infrastructure/Postgres/SchemaMigrations/1783470000000-AddIncomingCallPolicyRoutingPhoneNumberUnique.ts +25 -0
  18. package/Server/Infrastructure/Postgres/SchemaMigrations/1783510935686-FixNotNullForeignKeysOnDelete.ts +81 -0
  19. package/Server/Infrastructure/Postgres/SchemaMigrations/1783515836148-MigrationName.ts +25 -0
  20. package/Server/Infrastructure/Postgres/SchemaMigrations/1783523076215-AddMigrationFailureTable.ts +35 -0
  21. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +8 -0
  22. package/Server/Infrastructure/PostgresDatabase.ts +11 -0
  23. package/Server/Services/AIService.ts +74 -2
  24. package/Server/Services/AnalyticsDatabaseService.ts +10 -1
  25. package/Server/Services/DatabaseService.ts +10 -1
  26. package/Server/Services/IncidentService.ts +1 -1
  27. package/Server/Services/IncomingCallPolicyEscalationRuleService.ts +75 -2
  28. package/Server/Services/IncomingCallPolicyService.ts +42 -1
  29. package/Server/Services/Index.ts +2 -0
  30. package/Server/Services/MigrationFailureService.ts +9 -0
  31. package/Server/Services/MonitorProbeService.ts +33 -7
  32. package/Server/Services/MonitorService.ts +19 -7
  33. package/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.ts +65 -0
  34. package/Server/Services/OnCallDutyPolicyEscalationRuleService.ts +185 -41
  35. package/Server/Services/OnCallDutyPolicyEscalationRuleUserService.ts +23 -15
  36. package/Server/Services/OnCallDutyPolicyExecutionLogService.ts +39 -0
  37. package/Server/Services/OnCallDutyPolicyScheduleLayerService.ts +148 -0
  38. package/Server/Services/OnCallDutyPolicyScheduleLayerUserService.ts +11 -2
  39. package/Server/Services/OnCallDutyPolicyScheduleService.ts +502 -26
  40. package/Server/Services/OnCallDutyPolicyTimeLogService.ts +49 -7
  41. package/Server/Services/OnCallDutyPolicyUserOverrideService.ts +218 -4
  42. package/Server/Services/ProjectCallSMSConfigService.ts +82 -1
  43. package/Server/Services/TeamMemberService.ts +6 -0
  44. package/Server/Services/UserNotificationRuleService.ts +13 -42
  45. package/Server/Services/UserOnCallLogService.ts +90 -0
  46. package/Server/Services/UserOnCallLogTimelineService.ts +43 -1
  47. package/Server/Types/Database/QueryUtil.ts +57 -0
  48. package/Server/Utils/AI/AlertAIContextBuilder.ts +6 -1
  49. package/Server/Utils/AI/Chat/ChatAgentRunner.ts +14 -2
  50. package/Server/Utils/AI/IncidentAIContextBuilder.ts +18 -3
  51. package/Server/Utils/AI/IncidentEpisodeAIContextBuilder.ts +6 -1
  52. package/Server/Utils/AI/ScheduledMaintenanceAIContextBuilder.ts +12 -2
  53. package/Server/Utils/AI/Toolbox/IncidentTools.ts +183 -1
  54. package/Server/Utils/AI/Toolbox/Index.ts +4 -1
  55. package/Server/Utils/AI/Toolbox/RecentChangesTools.ts +208 -0
  56. package/Server/Utils/AI/Toolbox/Serializer.ts +42 -0
  57. package/Server/Utils/Database/MigrationFailureLog.ts +240 -0
  58. package/Server/Utils/IncomingCallPhoneNumber.ts +41 -0
  59. package/Server/Utils/LLM/LLMService.ts +110 -11
  60. package/Server/Utils/Telemetry/IoTSnapshotScan.ts +12 -9
  61. package/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.ts +12 -9
  62. package/Tests/Server/Services/AnalyticsDatabaseService.test.ts +0 -8
  63. package/Tests/Server/Services/OnCallDutyPolicyScheduleLayerUserReorder.test.ts +233 -0
  64. package/Tests/Server/Services/OnCallDutyPolicyTimeLogServiceScoping.test.ts +242 -0
  65. package/Tests/Server/Services/OnCallDutyPolicyUserOverrideEdit.test.ts +198 -0
  66. package/Tests/Server/Services/UserOnCallLogClaimNotificationRule.test.ts +495 -0
  67. package/Tests/Server/Types/Database/QueryUtil.test.ts +74 -0
  68. package/Tests/Server/Utils/AI/LLMServiceToolCalling.test.ts +78 -0
  69. package/Tests/Server/Utils/AI/ToolResultSerializer.test.ts +68 -0
  70. package/Tests/Types/DateExhaustiveTimezone.test.ts +700 -0
  71. package/Tests/Types/DateTimezoneWallClock.test.ts +99 -0
  72. package/Tests/Types/Events/Recurring.test.ts +22 -9
  73. package/Tests/Types/OnCallDutyPolicy/LayerUtilAuditFixes.test.ts +291 -0
  74. package/Tests/Types/OnCallDutyPolicy/LayerUtilAuditFixesRound2.test.ts +398 -0
  75. package/Tests/Types/OnCallDutyPolicy/LayerUtilDSTWeekendGap.test.ts +114 -0
  76. package/Tests/Types/OnCallDutyPolicy/LayerUtilDSTWeeklyDayShift.test.ts +76 -0
  77. package/Tests/Types/OnCallDutyPolicy/LayerUtilDailyMutation.test.ts +128 -0
  78. package/Tests/Types/OnCallDutyPolicy/LayerUtilDailyProbe.test.ts +203 -0
  79. package/Tests/Types/OnCallDutyPolicy/LayerUtilDiffFuzz.test.ts +322 -0
  80. package/Tests/Types/OnCallDutyPolicy/LayerUtilEdgeCases.test.ts +280 -0
  81. package/Tests/Types/OnCallDutyPolicy/LayerUtilExhaustiveCurrentUser.test.ts +863 -0
  82. package/Tests/Types/OnCallDutyPolicy/LayerUtilExhaustiveDaily.test.ts +900 -0
  83. package/Tests/Types/OnCallDutyPolicy/LayerUtilExhaustiveMultiLayer.test.ts +1104 -0
  84. package/Tests/Types/OnCallDutyPolicy/LayerUtilExhaustiveRotation.test.ts +957 -0
  85. package/Tests/Types/OnCallDutyPolicy/LayerUtilExhaustiveWeekly.test.ts +1095 -0
  86. package/Tests/Types/OnCallDutyPolicy/LayerUtilInvariants.test.ts +232 -0
  87. package/Tests/Types/OnCallDutyPolicy/LayerUtilMergeAudit.test.ts +227 -0
  88. package/Tests/Types/OnCallDutyPolicy/LayerUtilMonthYearAudit.test.ts +255 -0
  89. package/Tests/Types/OnCallDutyPolicy/LayerUtilMultiLayerAudit.test.ts +388 -0
  90. package/Tests/Types/OnCallDutyPolicy/LayerUtilMultiLayerEdge.test.ts +300 -0
  91. package/Tests/Types/OnCallDutyPolicy/LayerUtilOvernightDSTAudit.test.ts +158 -0
  92. package/Tests/Types/OnCallDutyPolicy/LayerUtilRestrictedGapFix.test.ts +253 -0
  93. package/Tests/Types/OnCallDutyPolicy/LayerUtilRestrictedGapRepro.test.ts +157 -0
  94. package/Tests/Types/OnCallDutyPolicy/LayerUtilRotationFixes.test.ts +414 -0
  95. package/Tests/Types/OnCallDutyPolicy/LayerUtilTimezone.test.ts +243 -0
  96. package/Tests/Types/OnCallDutyPolicy/LayerUtilWeekendGapRepro.test.ts +112 -0
  97. package/Tests/Types/OnCallDutyPolicy/OverrideLensAudit.test.ts +117 -0
  98. package/Tests/Types/OnCallDutyPolicy/RestrictionTimes.test.ts +8 -6
  99. package/Tests/Types/OnCallDutyPolicy/RestrictionTimesDefaultDayAudit.test.ts +112 -0
  100. package/Tests/Types/OnCallDutyPolicy/RestrictionTimesExhaustive.test.ts +821 -0
  101. package/Tests/Types/OnCallDutyPolicy/RestrictionTimesMutationInvariant.test.ts +886 -0
  102. package/Tests/Types/OnCallDutyPolicy/UserOverrideUtil.test.ts +255 -0
  103. package/Tests/Types/OnCallDutyPolicy/UserOverrideUtilExhaustive.test.ts +1126 -0
  104. package/Types/Date.ts +200 -15
  105. package/Types/OnCallDutyPolicy/Layer.ts +790 -260
  106. package/Types/OnCallDutyPolicy/RestrictionTimes.ts +39 -13
  107. package/Types/OnCallDutyPolicy/UserOverrideUtil.ts +21 -5
  108. package/UI/Components/Events/RecurringFieldElement.tsx +16 -0
  109. package/UI/Components/ModelFormModal/ModelFormModal.tsx +8 -0
  110. package/UI/Components/RadioButtons/BasicRadioButtons.tsx +1 -1
  111. package/build/dist/Models/DatabaseModels/IncidentEpisodeRoleMember.js +1 -1
  112. package/build/dist/Models/DatabaseModels/IncidentEpisodeRoleMember.js.map +1 -1
  113. package/build/dist/Models/DatabaseModels/IncidentMember.js +1 -1
  114. package/build/dist/Models/DatabaseModels/IncidentMember.js.map +1 -1
  115. package/build/dist/Models/DatabaseModels/IncomingCallPolicy.js +10 -0
  116. package/build/dist/Models/DatabaseModels/IncomingCallPolicy.js.map +1 -1
  117. package/build/dist/Models/DatabaseModels/Index.js +2 -0
  118. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  119. package/build/dist/Models/DatabaseModels/MigrationFailure.js +196 -0
  120. package/build/dist/Models/DatabaseModels/MigrationFailure.js.map +1 -0
  121. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyExecutionLog.js +52 -2
  122. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyExecutionLog.js.map +1 -1
  123. package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js +45 -0
  124. package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js.map +1 -1
  125. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleLayer.js +6 -0
  126. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleLayer.js.map +1 -1
  127. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleLayerUser.js +6 -0
  128. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleLayerUser.js.map +1 -1
  129. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyTimeLog.js +1 -1
  130. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyTimeLog.js.map +1 -1
  131. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyUserOverride.js +2 -2
  132. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyUserOverride.js.map +1 -1
  133. package/build/dist/Server/API/AlertAPI.js +1 -1
  134. package/build/dist/Server/API/IncidentAPI.js +2 -2
  135. package/build/dist/Server/API/IncidentEpisodeAPI.js +1 -1
  136. package/build/dist/Server/API/LlmProviderAPI.js +1 -0
  137. package/build/dist/Server/API/LlmProviderAPI.js.map +1 -1
  138. package/build/dist/Server/API/ScheduledMaintenanceAPI.js +1 -1
  139. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783470000000-AddIncomingCallPolicyRoutingPhoneNumberUnique.js +18 -0
  140. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783470000000-AddIncomingCallPolicyRoutingPhoneNumberUnique.js.map +1 -0
  141. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783510935686-FixNotNullForeignKeysOnDelete.js +38 -0
  142. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783510935686-FixNotNullForeignKeysOnDelete.js.map +1 -0
  143. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783515836148-MigrationName.js +16 -0
  144. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783515836148-MigrationName.js.map +1 -0
  145. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783523076215-AddMigrationFailureTable.js +18 -0
  146. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783523076215-AddMigrationFailureTable.js.map +1 -0
  147. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +8 -0
  148. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  149. package/build/dist/Server/Infrastructure/PostgresDatabase.js +9 -0
  150. package/build/dist/Server/Infrastructure/PostgresDatabase.js.map +1 -1
  151. package/build/dist/Server/Services/AIService.js +53 -2
  152. package/build/dist/Server/Services/AIService.js.map +1 -1
  153. package/build/dist/Server/Services/AnalyticsDatabaseService.js +10 -1
  154. package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
  155. package/build/dist/Server/Services/DatabaseService.js +10 -1
  156. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  157. package/build/dist/Server/Services/IncidentService.js +1 -1
  158. package/build/dist/Server/Services/IncomingCallPolicyEscalationRuleService.js +55 -2
  159. package/build/dist/Server/Services/IncomingCallPolicyEscalationRuleService.js.map +1 -1
  160. package/build/dist/Server/Services/IncomingCallPolicyService.js +40 -0
  161. package/build/dist/Server/Services/IncomingCallPolicyService.js.map +1 -1
  162. package/build/dist/Server/Services/Index.js +2 -0
  163. package/build/dist/Server/Services/Index.js.map +1 -1
  164. package/build/dist/Server/Services/MigrationFailureService.js +9 -0
  165. package/build/dist/Server/Services/MigrationFailureService.js.map +1 -0
  166. package/build/dist/Server/Services/MonitorProbeService.js +33 -7
  167. package/build/dist/Server/Services/MonitorProbeService.js.map +1 -1
  168. package/build/dist/Server/Services/MonitorService.js +12 -5
  169. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  170. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js +81 -22
  171. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js.map +1 -1
  172. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleService.js +134 -31
  173. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleService.js.map +1 -1
  174. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleUserService.js +21 -13
  175. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleUserService.js.map +1 -1
  176. package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogService.js +36 -0
  177. package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogService.js.map +1 -1
  178. package/build/dist/Server/Services/OnCallDutyPolicyScheduleLayerService.js +121 -0
  179. package/build/dist/Server/Services/OnCallDutyPolicyScheduleLayerService.js.map +1 -1
  180. package/build/dist/Server/Services/OnCallDutyPolicyScheduleLayerUserService.js +11 -2
  181. package/build/dist/Server/Services/OnCallDutyPolicyScheduleLayerUserService.js.map +1 -1
  182. package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js +409 -36
  183. package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js.map +1 -1
  184. package/build/dist/Server/Services/OnCallDutyPolicyTimeLogService.js +52 -8
  185. package/build/dist/Server/Services/OnCallDutyPolicyTimeLogService.js.map +1 -1
  186. package/build/dist/Server/Services/OnCallDutyPolicyUserOverrideService.js +170 -3
  187. package/build/dist/Server/Services/OnCallDutyPolicyUserOverrideService.js.map +1 -1
  188. package/build/dist/Server/Services/ProjectCallSMSConfigService.js +72 -0
  189. package/build/dist/Server/Services/ProjectCallSMSConfigService.js.map +1 -1
  190. package/build/dist/Server/Services/TeamMemberService.js +6 -0
  191. package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
  192. package/build/dist/Server/Services/UserNotificationRuleService.js +12 -30
  193. package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
  194. package/build/dist/Server/Services/UserOnCallLogService.js +75 -0
  195. package/build/dist/Server/Services/UserOnCallLogService.js.map +1 -1
  196. package/build/dist/Server/Services/UserOnCallLogTimelineService.js +31 -1
  197. package/build/dist/Server/Services/UserOnCallLogTimelineService.js.map +1 -1
  198. package/build/dist/Server/Types/Database/QueryUtil.js +45 -0
  199. package/build/dist/Server/Types/Database/QueryUtil.js.map +1 -1
  200. package/build/dist/Server/Utils/AI/AlertAIContextBuilder.js +6 -1
  201. package/build/dist/Server/Utils/AI/AlertAIContextBuilder.js.map +1 -1
  202. package/build/dist/Server/Utils/AI/Chat/ChatAgentRunner.js +13 -2
  203. package/build/dist/Server/Utils/AI/Chat/ChatAgentRunner.js.map +1 -1
  204. package/build/dist/Server/Utils/AI/IncidentAIContextBuilder.js +18 -3
  205. package/build/dist/Server/Utils/AI/IncidentAIContextBuilder.js.map +1 -1
  206. package/build/dist/Server/Utils/AI/IncidentEpisodeAIContextBuilder.js +6 -1
  207. package/build/dist/Server/Utils/AI/IncidentEpisodeAIContextBuilder.js.map +1 -1
  208. package/build/dist/Server/Utils/AI/ScheduledMaintenanceAIContextBuilder.js +12 -2
  209. package/build/dist/Server/Utils/AI/ScheduledMaintenanceAIContextBuilder.js.map +1 -1
  210. package/build/dist/Server/Utils/AI/Toolbox/IncidentTools.js +152 -1
  211. package/build/dist/Server/Utils/AI/Toolbox/IncidentTools.js.map +1 -1
  212. package/build/dist/Server/Utils/AI/Toolbox/Index.js +4 -1
  213. package/build/dist/Server/Utils/AI/Toolbox/Index.js.map +1 -1
  214. package/build/dist/Server/Utils/AI/Toolbox/RecentChangesTools.js +165 -0
  215. package/build/dist/Server/Utils/AI/Toolbox/RecentChangesTools.js.map +1 -0
  216. package/build/dist/Server/Utils/AI/Toolbox/Serializer.js +40 -0
  217. package/build/dist/Server/Utils/AI/Toolbox/Serializer.js.map +1 -1
  218. package/build/dist/Server/Utils/Database/MigrationFailureLog.js +174 -0
  219. package/build/dist/Server/Utils/Database/MigrationFailureLog.js.map +1 -0
  220. package/build/dist/Server/Utils/IncomingCallPhoneNumber.js +30 -0
  221. package/build/dist/Server/Utils/IncomingCallPhoneNumber.js.map +1 -0
  222. package/build/dist/Server/Utils/LLM/LLMService.js +81 -5
  223. package/build/dist/Server/Utils/LLM/LLMService.js.map +1 -1
  224. package/build/dist/Server/Utils/Telemetry/IoTSnapshotScan.js +11 -8
  225. package/build/dist/Server/Utils/Telemetry/IoTSnapshotScan.js.map +1 -1
  226. package/build/dist/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.js +11 -8
  227. package/build/dist/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.js.map +1 -1
  228. package/build/dist/Types/Date.js +153 -15
  229. package/build/dist/Types/Date.js.map +1 -1
  230. package/build/dist/Types/OnCallDutyPolicy/Layer.js +602 -171
  231. package/build/dist/Types/OnCallDutyPolicy/Layer.js.map +1 -1
  232. package/build/dist/Types/OnCallDutyPolicy/RestrictionTimes.js +27 -13
  233. package/build/dist/Types/OnCallDutyPolicy/RestrictionTimes.js.map +1 -1
  234. package/build/dist/Types/OnCallDutyPolicy/UserOverrideUtil.js +20 -5
  235. package/build/dist/Types/OnCallDutyPolicy/UserOverrideUtil.js.map +1 -1
  236. package/build/dist/UI/Components/Events/RecurringFieldElement.js +13 -0
  237. package/build/dist/UI/Components/Events/RecurringFieldElement.js.map +1 -1
  238. package/build/dist/UI/Components/ModelFormModal/ModelFormModal.js.map +1 -1
  239. package/build/dist/UI/Components/RadioButtons/BasicRadioButtons.js +1 -1
  240. package/build/dist/UI/Components/RadioButtons/BasicRadioButtons.js.map +1 -1
  241. package/package.json +1 -1
@@ -15,6 +15,8 @@ import UserNotificationExecutionStatus from "../../Types/UserNotification/UserNo
15
15
  import User from "../../Models/DatabaseModels/User";
16
16
  import Model from "../../Models/DatabaseModels/UserOnCallLogTimeline";
17
17
  import AlertService from "./AlertService";
18
+ import AlertEpisodeService from "./AlertEpisodeService";
19
+ import IncidentEpisodeService from "./IncidentEpisodeService";
18
20
 
19
21
  export class Service extends DatabaseService<Model> {
20
22
  public constructor() {
@@ -40,6 +42,8 @@ export class Service extends DatabaseService<Model> {
40
42
  onCallDutyPolicyExecutionLogId: true,
41
43
  triggeredByIncidentId: true,
42
44
  triggeredByAlertId: true,
45
+ triggeredByAlertEpisodeId: true,
46
+ triggeredByIncidentEpisodeId: true,
43
47
  onCallDutyPolicyExecutionLogTimelineId: true,
44
48
  },
45
49
  skip: 0,
@@ -52,6 +56,19 @@ export class Service extends DatabaseService<Model> {
52
56
  for (const item of items) {
53
57
  const isIncident: boolean = Boolean(item.triggeredByIncidentId);
54
58
  const isAlert: boolean = Boolean(item.triggeredByAlertId);
59
+ /*
60
+ * Alert-episode and incident-episode pages were never handled here, so
61
+ * acknowledging one via call/SMS/email/push marked only this user's log
62
+ * done but never acknowledged the EPISODE. ExecutePendingExecutions gates
63
+ * every co-notified user's continuation solely on isEpisodeAcknowledged,
64
+ * so the other responders kept escalating and the episode stayed
65
+ * unacknowledged in its own state (audit F15). Handle both episode kinds
66
+ * the same way incident/alert are handled below.
67
+ */
68
+ const isAlertEpisode: boolean = Boolean(item.triggeredByAlertEpisodeId);
69
+ const isIncidentEpisode: boolean = Boolean(
70
+ item.triggeredByIncidentEpisodeId,
71
+ );
55
72
 
56
73
  // this incident is acknowledged.
57
74
 
@@ -73,7 +90,16 @@ export class Service extends DatabaseService<Model> {
73
90
  throw new BadDataException("User not found.");
74
91
  }
75
92
 
76
- const statusMessage: string = `${isIncident ? "Incident" : "Alert"} acknowledged by ${user.name} (${user.email})`;
93
+ const entityLabel: string =
94
+ isIncident || isIncidentEpisode
95
+ ? isIncidentEpisode
96
+ ? "Incident Episode"
97
+ : "Incident"
98
+ : isAlertEpisode
99
+ ? "Alert Episode"
100
+ : "Alert";
101
+
102
+ const statusMessage: string = `${entityLabel} acknowledged by ${user.name} (${user.email})`;
77
103
 
78
104
  await UserOnCallLogService.updateOneById({
79
105
  id: item.userNotificationLogId!,
@@ -133,6 +159,22 @@ export class Service extends DatabaseService<Model> {
133
159
  item.userId!,
134
160
  );
135
161
  }
162
+
163
+ if (isAlertEpisode) {
164
+ // alert episode — stops co-notified responders from escalating.
165
+ await AlertEpisodeService.acknowledgeEpisode(
166
+ item.triggeredByAlertEpisodeId!,
167
+ item.userId!,
168
+ );
169
+ }
170
+
171
+ if (isIncidentEpisode) {
172
+ // incident episode — stops co-notified responders from escalating.
173
+ await IncidentEpisodeService.acknowledgeEpisode(
174
+ item.triggeredByIncidentEpisodeId!,
175
+ item.userId!,
176
+ );
177
+ }
136
178
  }
137
179
  }
138
180
 
@@ -549,6 +549,63 @@ export default class QueryUtil {
549
549
  _id: QueryHelper.any(query[key] as Array<string>),
550
550
  };
551
551
  }
552
+
553
+ /*
554
+ * Text-search operator nested under a single-Entity relation, e.g.
555
+ * { user: { name: new Search("foo") } }. serializeQuery otherwise only
556
+ * visits top-level keys, so the nested operator reaches TypeORM as a raw
557
+ * class instance and silently degrades to an exact equality
558
+ * (`user.name = 'foo'` instead of `user.name ILIKE '%foo%'`) — which is
559
+ * why the Owner / user picker "search" appeared to do nothing once a
560
+ * project had more than a page of members.
561
+ *
562
+ * We deliberately touch ONLY the ILIKE-family leaf operators here and
563
+ * leave every other nested value (arrays, ids, plain equality, other
564
+ * operators) exactly as it was, so existing nested relation filters (the
565
+ * access-control label filters built by @CanAccessIfCanReadOn, etc.)
566
+ * serialize unchanged.
567
+ */
568
+ if (
569
+ tableColumnMetadata &&
570
+ tableColumnMetadata.modelType &&
571
+ tableColumnMetadata.type === TableColumnType.Entity &&
572
+ query[key] &&
573
+ typeof query[key] === Typeof.Object &&
574
+ !Array.isArray(query[key]) &&
575
+ (Object.getPrototypeOf(query[key]) === Object.prototype ||
576
+ Object.getPrototypeOf(query[key]) === null)
577
+ ) {
578
+ const relationModel: BaseModel = new tableColumnMetadata.modelType();
579
+ const relationQuery: Record<string, any> = query[key] as Record<
580
+ string,
581
+ any
582
+ >;
583
+ for (const relationKey in relationQuery) {
584
+ const relationColumnMetadata: TableColumnMetadata =
585
+ relationModel.getTableColumnMetadata(relationKey);
586
+ if (!relationColumnMetadata) {
587
+ continue;
588
+ }
589
+ const nestedValue: any = relationQuery[relationKey];
590
+ if (nestedValue instanceof Search) {
591
+ relationQuery[relationKey] = QueryHelper.search(
592
+ (nestedValue as Search<string>).toString(),
593
+ ) as any;
594
+ } else if (nestedValue instanceof StartsWith) {
595
+ relationQuery[relationKey] = QueryHelper.startsWith(
596
+ (nestedValue as StartsWith<string>).toString(),
597
+ ) as any;
598
+ } else if (nestedValue instanceof EndsWith) {
599
+ relationQuery[relationKey] = QueryHelper.endsWith(
600
+ (nestedValue as EndsWith<string>).toString(),
601
+ ) as any;
602
+ } else if (nestedValue instanceof NotContains) {
603
+ relationQuery[relationKey] = QueryHelper.notContains(
604
+ (nestedValue as NotContains<string>).toString(),
605
+ ) as any;
606
+ }
607
+ }
608
+ }
552
609
  }
553
610
 
554
611
  return query;
@@ -235,7 +235,12 @@ The note should:
235
235
  4. Be detailed enough to help team members understand the situation
236
236
  5. Use technical language appropriate for the engineering team
237
237
 
238
- Write in markdown format for better readability. Be thorough and technical.`;
238
+ Write in markdown format for better readability. Be thorough and technical.
239
+
240
+ Grounding rules (important):
241
+ - Use ONLY facts that appear in the provided alert data. Do NOT invent causes, metrics, impact, or actions the data does not support.
242
+ - If something a section needs is not in the data, write "Not available in the alert record" instead of guessing.
243
+ - Never fabricate numbers or state confidence levels.`;
239
244
  }
240
245
 
241
246
  // Build user message
@@ -908,9 +908,21 @@ export default class ChatAgentRunner {
908
908
  continue;
909
909
  }
910
910
 
911
+ const isUserMessage: boolean = message.role === AIChatMessageRole.User;
912
+
911
913
  messages.push({
912
- role: message.role === AIChatMessageRole.User ? "user" : "assistant",
913
- content: message.contentInMarkdown,
914
+ role: isUserMessage ? "user" : "assistant",
915
+ /*
916
+ * A prior assistant answer carries [C#] citation markers that pointed
917
+ * at that turn's tool results — citations that no longer exist in this
918
+ * turn. Left in the replayed history the model echoes and renumbers
919
+ * them, and this turn's stripFabricatedCitationMarkers then deletes the
920
+ * unmatched ones, leaving claims that look uncited. Strip the markers
921
+ * from replayed answers so only freshly minted citations ever appear.
922
+ */
923
+ content: isUserMessage
924
+ ? message.contentInMarkdown
925
+ : message.contentInMarkdown.replace(/\s?\[C\d+\]/g, ""),
914
926
  });
915
927
  }
916
928
 
@@ -365,7 +365,12 @@ The postmortem should:
365
365
 
366
366
  Use a standard incident postmortem format with sections for: Executive Summary, Timeline, Root Cause Analysis, Impact, Action Items, and Lessons Learned.
367
367
 
368
- Write in a professional, clear, and concise manner. Use markdown formatting for better readability.`;
368
+ Write in a professional, clear, and concise manner. Use markdown formatting for better readability.
369
+
370
+ Grounding rules (important):
371
+ - Use ONLY facts that appear in the provided incident data. Do NOT invent root causes, timelines, metrics, customer impact, or actions the data does not support.
372
+ - If a section needs information the data does not contain, write "Not available in the incident record" instead of guessing.
373
+ - Never fabricate numbers or state confidence levels.`;
369
374
  }
370
375
 
371
376
  // Build user message based on whether template is provided
@@ -549,7 +554,12 @@ DO NOT include:
549
554
  - Confidential information
550
555
  - Excessive jargon
551
556
 
552
- Write in markdown format for better readability.`;
557
+ Write in markdown format for better readability.
558
+
559
+ Grounding rules (important):
560
+ - Use ONLY facts that appear in the provided incident data; never invent impact, causes, timing, or status.
561
+ - If something is not known from the data, say it is still being investigated rather than guessing.
562
+ - Never fabricate numbers or specific timings the data does not support.`;
553
563
  }
554
564
  } else if (template) {
555
565
  // Internal note with template
@@ -577,7 +587,12 @@ The note should:
577
587
  4. Be detailed enough to help team members understand the situation
578
588
  5. Use technical language appropriate for the engineering team
579
589
 
580
- Write in markdown format for better readability. Be thorough and technical.`;
590
+ Write in markdown format for better readability. Be thorough and technical.
591
+
592
+ Grounding rules (important):
593
+ - Use ONLY facts that appear in the provided incident data. Do NOT invent root causes, metrics, impact, or actions the data does not support.
594
+ - If something a section needs is not in the data, write "Not available in the incident record" instead of guessing.
595
+ - Never fabricate numbers or state confidence levels.`;
581
596
  }
582
597
 
583
598
  // Build user message
@@ -389,7 +389,12 @@ The postmortem should:
389
389
 
390
390
  Use a standard incident postmortem format with sections for: Executive Summary, Timeline, Root Cause Analysis, Impact, Action Items, and Lessons Learned.
391
391
 
392
- Write in a professional, clear, and concise manner. Use markdown formatting for better readability.`;
392
+ Write in a professional, clear, and concise manner. Use markdown formatting for better readability.
393
+
394
+ Grounding rules (important):
395
+ - Use ONLY facts that appear in the provided episode data. Do NOT invent root causes, timelines, metrics, impact, or actions the data does not support.
396
+ - If a section needs information the data does not contain, write "Not available in the incident record" instead of guessing.
397
+ - Never fabricate numbers or state confidence levels.`;
393
398
  }
394
399
 
395
400
  // Build user message based on whether template is provided
@@ -288,7 +288,12 @@ DO NOT include:
288
288
  - Confidential information
289
289
  - Excessive jargon
290
290
 
291
- Write in markdown format for better readability.`;
291
+ Write in markdown format for better readability.
292
+
293
+ Grounding rules (important):
294
+ - Use ONLY facts that appear in the provided maintenance data; never invent scope, impact, timing, or status.
295
+ - If something is not known from the data, say it will be confirmed rather than guessing.
296
+ - Never fabricate numbers or specific timings the data does not support.`;
292
297
  }
293
298
  } else if (template) {
294
299
  // Internal note with template
@@ -316,7 +321,12 @@ The note should:
316
321
  4. Be detailed enough to help team members understand the current status
317
322
  5. Use technical language appropriate for the engineering team
318
323
 
319
- Write in markdown format for better readability. Be thorough and technical.`;
324
+ Write in markdown format for better readability. Be thorough and technical.
325
+
326
+ Grounding rules (important):
327
+ - Use ONLY facts that appear in the provided maintenance data. Do NOT invent scope, metrics, impact, or actions the data does not support.
328
+ - If something a section needs is not in the data, write "Not available in the maintenance record" instead of guessing.
329
+ - Never fabricate numbers or state confidence levels.`;
320
330
  }
321
331
 
322
332
  // Build user message
@@ -35,7 +35,7 @@ const resolveReadPermissions: () => Array<Permission> =
35
35
  export const QueryIncidentsTool: ObservabilityTool = {
36
36
  name: "query_incidents",
37
37
  description:
38
- "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.",
38
+ "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.",
39
39
  inputSchema: {
40
40
  type: "object",
41
41
  properties: {
@@ -81,10 +81,44 @@ export const QueryIncidentsTool: ObservabilityTool = {
81
81
  incidentSeverity: {
82
82
  name: true,
83
83
  },
84
+ monitors: {
85
+ _id: true,
86
+ name: true,
87
+ },
88
+ labels: {
89
+ name: true,
90
+ },
91
+ rootCause: true,
92
+ remediationNotes: true,
93
+ postmortemNote: true,
84
94
  },
85
95
  props: ctx.props,
86
96
  });
87
97
 
98
+ /*
99
+ * Surface the incident's blast radius (affected monitors + labels) and
100
+ * its own window so the model can pivot from an incident into the
101
+ * logs/traces/metrics of the affected services over the right time
102
+ * range, instead of guessing which service or hour to look at.
103
+ */
104
+ const affectedMonitors: string = (incident?.monitors || [])
105
+ .map((monitor: { name?: string }) => {
106
+ return monitor.name || "";
107
+ })
108
+ .filter((value: string) => {
109
+ return value.length > 0;
110
+ })
111
+ .join(", ");
112
+
113
+ const incidentLabels: string = (incident?.labels || [])
114
+ .map((label: { name?: string }) => {
115
+ return label.name || "";
116
+ })
117
+ .filter((value: string) => {
118
+ return value.length > 0;
119
+ })
120
+ .join(", ");
121
+
88
122
  const rows: Array<JSONObject> = incident
89
123
  ? [
90
124
  {
@@ -95,6 +129,12 @@ export const QueryIncidentsTool: ObservabilityTool = {
95
129
  state: incident.currentIncidentState?.name,
96
130
  severity: incident.incidentSeverity?.name,
97
131
  createdAt: incident.createdAt,
132
+ affectedMonitors: affectedMonitors || undefined,
133
+ labels: incidentLabels || undefined,
134
+ rootCause: incident.rootCause,
135
+ remediationNotes: incident.remediationNotes,
136
+ postmortemNote: incident.postmortemNote,
137
+ telemetryWindowStart: incident.createdAt,
98
138
  },
99
139
  ]
100
140
  : [];
@@ -202,3 +242,145 @@ export const QueryIncidentsTool: ObservabilityTool = {
202
242
  };
203
243
  },
204
244
  };
245
+
246
+ export const SearchIncidentsTool: ObservabilityTool = {
247
+ name: "search_incidents",
248
+ description:
249
+ "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.",
250
+ inputSchema: {
251
+ type: "object",
252
+ properties: {
253
+ searchText: {
254
+ type: "string",
255
+ description:
256
+ "Text to match (case-insensitive substring) across incident title, description, root cause, remediation notes and postmortem.",
257
+ },
258
+ createdWithinHours: {
259
+ type: "number",
260
+ description:
261
+ "Only incidents created within this many hours (default 2160 = 90 days, max 8760 = 1 year).",
262
+ },
263
+ limit: {
264
+ type: "number",
265
+ description: "Maximum incidents to return (default 5, max 15).",
266
+ },
267
+ },
268
+ required: ["searchText"],
269
+ },
270
+ get requiredPermissions(): Array<Permission> {
271
+ return resolveReadPermissions();
272
+ },
273
+ execute: async (
274
+ args: JSONObject,
275
+ ctx: ToolContext,
276
+ ): Promise<ToolExecutionResult> => {
277
+ const searchText: string | undefined = ToolArgs.getString(
278
+ args,
279
+ "searchText",
280
+ );
281
+
282
+ if (!searchText) {
283
+ return {
284
+ dataForLlm:
285
+ "Error: searchText is required. Provide the text to search past incidents for.",
286
+ rowCount: 0,
287
+ citationLabel: "Incident search (no query)",
288
+ redactionCount: 0,
289
+ isTruncated: false,
290
+ };
291
+ }
292
+
293
+ const createdWithinHours: number = ToolArgs.getNumber(
294
+ args,
295
+ "createdWithinHours",
296
+ { defaultValue: 2160, min: 1, max: 8760 },
297
+ );
298
+ const limit: number = ToolArgs.getNumber(args, "limit", {
299
+ defaultValue: 5,
300
+ min: 1,
301
+ max: 15,
302
+ });
303
+
304
+ const endTime: Date = OneUptimeDate.getCurrentDate();
305
+ const startTime: Date = OneUptimeDate.addRemoveHours(
306
+ endTime,
307
+ -1 * createdWithinHours,
308
+ );
309
+
310
+ const incidents: Array<Incident> = await IncidentService.findBy({
311
+ query: {
312
+ createdAt: QueryHelper.inBetween(startTime, endTime),
313
+ /*
314
+ * The OR-joined ILIKE Raw references the listed columns, not the
315
+ * attached property — this is the established multiSearch attachment
316
+ * pattern (see QueryUtil).
317
+ */
318
+ title: QueryHelper.multiSearch(
319
+ [
320
+ "title",
321
+ "description",
322
+ "rootCause",
323
+ "remediationNotes",
324
+ "postmortemNote",
325
+ ],
326
+ searchText,
327
+ ),
328
+ },
329
+ select: {
330
+ _id: true,
331
+ title: true,
332
+ incidentNumber: true,
333
+ createdAt: true,
334
+ currentIncidentState: {
335
+ name: true,
336
+ },
337
+ incidentSeverity: {
338
+ name: true,
339
+ },
340
+ rootCause: true,
341
+ postmortemNote: true,
342
+ },
343
+ sort: {
344
+ createdAt: SortOrder.Descending,
345
+ },
346
+ limit: limit,
347
+ skip: 0,
348
+ props: ctx.props,
349
+ });
350
+
351
+ const rows: Array<JSONObject> = incidents.map((incident: Incident) => {
352
+ return {
353
+ id: incident.id?.toString(),
354
+ incidentNumber: incident.incidentNumber,
355
+ title: incident.title,
356
+ state: incident.currentIncidentState?.name,
357
+ severity: incident.incidentSeverity?.name,
358
+ createdAt: incident.createdAt,
359
+ rootCause: incident.rootCause,
360
+ postmortemNote: incident.postmortemNote,
361
+ };
362
+ });
363
+
364
+ const serialized: SerializedResult =
365
+ ToolResultSerializer.serializeRows(rows);
366
+
367
+ return {
368
+ dataForLlm: serialized.text,
369
+ rowCount: serialized.rowCount,
370
+ citationLabel: `Incident search "${searchText}" (${serialized.rowCount} found)`,
371
+ citationTarget: {
372
+ type: AIChatCitationTargetType.Incidents,
373
+ },
374
+ redactionCount: serialized.redactionCount,
375
+ isTruncated: serialized.isTruncated,
376
+ widget:
377
+ rows.length > 0
378
+ ? WidgetBuilder.incidentList({
379
+ title: `Incidents matching "${searchText}" (${rows.length})`,
380
+ items: rows,
381
+ link: { type: AIChatCitationTargetType.Incidents },
382
+ })
383
+ : undefined,
384
+ };
385
+ },
386
+ };
@@ -13,11 +13,12 @@ import {
13
13
  ToolContext,
14
14
  ToolExecutionResult,
15
15
  } from "./ToolTypes";
16
- import { QueryIncidentsTool } from "./IncidentTools";
16
+ import { QueryIncidentsTool, SearchIncidentsTool } from "./IncidentTools";
17
17
  import { QueryAlertsTool } from "./AlertTools";
18
18
  import { QueryMonitorsTool } from "./MonitorTools";
19
19
  import { TopExceptionsTool } from "./ExceptionTools";
20
20
  import { LogHistogramTool, SearchLogsTool } from "./LogTools";
21
+ import { RecentChangesTool } from "./RecentChangesTools";
21
22
  import { QueryMetricsTool } from "./MetricTools";
22
23
  import { GetTraceTool, QueryTracesTool } from "./TraceTools";
23
24
  import { LookupContextTool } from "./ContextTools";
@@ -53,6 +54,7 @@ export default class AIToolbox {
53
54
  private static readonly tools: Array<ObservabilityTool> = [
54
55
  LookupContextTool,
55
56
  QueryIncidentsTool,
57
+ SearchIncidentsTool,
56
58
  QueryAlertsTool,
57
59
  QueryMonitorsTool,
58
60
  TopExceptionsTool,
@@ -61,6 +63,7 @@ export default class AIToolbox {
61
63
  QueryMetricsTool,
62
64
  QueryTracesTool,
63
65
  GetTraceTool,
66
+ RecentChangesTool,
64
67
  // Write tools (mutations). Gated by conversation permission mode.
65
68
  CreateIncidentTool,
66
69
  AcknowledgeIncidentTool,