@oneuptime/common 11.3.25 → 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 (397) hide show
  1. package/Models/DatabaseModels/AIConversation.ts +322 -0
  2. package/Models/DatabaseModels/AIConversationMessage.ts +495 -0
  3. package/Models/DatabaseModels/AIRun.ts +584 -0
  4. package/Models/DatabaseModels/AIRunEvent.ts +443 -0
  5. package/Models/DatabaseModels/IncidentEpisodeRoleMember.ts +1 -1
  6. package/Models/DatabaseModels/IncidentMember.ts +1 -1
  7. package/Models/DatabaseModels/IncomingCallPolicy.ts +13 -0
  8. package/Models/DatabaseModels/Index.ts +11 -0
  9. package/Models/DatabaseModels/LlmLog.ts +26 -0
  10. package/Models/DatabaseModels/LlmProvider.ts +2 -2
  11. package/Models/DatabaseModels/MigrationFailure.ts +170 -0
  12. package/Models/DatabaseModels/OnCallDutyPolicyExecutionLog.ts +51 -2
  13. package/Models/DatabaseModels/OnCallDutyPolicySchedule.ts +44 -0
  14. package/Models/DatabaseModels/OnCallDutyPolicyScheduleLayer.ts +6 -0
  15. package/Models/DatabaseModels/OnCallDutyPolicyScheduleLayerUser.ts +6 -0
  16. package/Models/DatabaseModels/OnCallDutyPolicyTimeLog.ts +1 -1
  17. package/Models/DatabaseModels/OnCallDutyPolicyUserOverride.ts +2 -2
  18. package/Server/API/AIChatAPI.ts +693 -0
  19. package/Server/API/AlertAPI.ts +1 -1
  20. package/Server/API/IncidentAPI.ts +2 -2
  21. package/Server/API/IncidentEpisodeAPI.ts +1 -1
  22. package/Server/API/LlmProviderAPI.ts +170 -0
  23. package/Server/API/MicrosoftTeamsAPI.ts +5 -0
  24. package/Server/API/ScheduledMaintenanceAPI.ts +1 -1
  25. package/Server/API/SlackAPI.ts +663 -0
  26. package/Server/Infrastructure/Postgres/SchemaMigrations/1783363279075-AddAIChatModels.ts +245 -0
  27. package/Server/Infrastructure/Postgres/SchemaMigrations/1783443471795-AddLlmProviderToAIConversation.ts +36 -0
  28. package/Server/Infrastructure/Postgres/SchemaMigrations/1783453297388-AddAIChatWriteActionsAndWidgets.ts +46 -0
  29. package/Server/Infrastructure/Postgres/SchemaMigrations/1783461767405-MigrationName.ts +119 -0
  30. package/Server/Infrastructure/Postgres/SchemaMigrations/1783470000000-AddIncomingCallPolicyRoutingPhoneNumberUnique.ts +25 -0
  31. package/Server/Infrastructure/Postgres/SchemaMigrations/1783510935686-FixNotNullForeignKeysOnDelete.ts +81 -0
  32. package/Server/Infrastructure/Postgres/SchemaMigrations/1783515836148-MigrationName.ts +25 -0
  33. package/Server/Infrastructure/Postgres/SchemaMigrations/1783523076215-AddMigrationFailureTable.ts +35 -0
  34. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +16 -0
  35. package/Server/Infrastructure/PostgresDatabase.ts +11 -0
  36. package/Server/Services/AIConversationMessageService.ts +39 -0
  37. package/Server/Services/AIConversationService.ts +63 -0
  38. package/Server/Services/AIRunEventService.ts +39 -0
  39. package/Server/Services/AIRunService.ts +39 -0
  40. package/Server/Services/AIService.ts +127 -33
  41. package/Server/Services/AnalyticsDatabaseService.ts +10 -1
  42. package/Server/Services/DatabaseService.ts +29 -1
  43. package/Server/Services/IncidentService.ts +1 -1
  44. package/Server/Services/IncomingCallPolicyEscalationRuleService.ts +75 -2
  45. package/Server/Services/IncomingCallPolicyService.ts +42 -1
  46. package/Server/Services/Index.ts +2 -0
  47. package/Server/Services/LlmProviderService.ts +110 -0
  48. package/Server/Services/MigrationFailureService.ts +9 -0
  49. package/Server/Services/MonitorProbeService.ts +33 -7
  50. package/Server/Services/MonitorService.ts +19 -7
  51. package/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.ts +65 -0
  52. package/Server/Services/OnCallDutyPolicyEscalationRuleService.ts +185 -41
  53. package/Server/Services/OnCallDutyPolicyEscalationRuleUserService.ts +23 -15
  54. package/Server/Services/OnCallDutyPolicyExecutionLogService.ts +39 -0
  55. package/Server/Services/OnCallDutyPolicyScheduleLayerService.ts +148 -0
  56. package/Server/Services/OnCallDutyPolicyScheduleLayerUserService.ts +11 -2
  57. package/Server/Services/OnCallDutyPolicyScheduleService.ts +502 -26
  58. package/Server/Services/OnCallDutyPolicyTimeLogService.ts +49 -7
  59. package/Server/Services/OnCallDutyPolicyUserOverrideService.ts +218 -4
  60. package/Server/Services/ProjectCallSMSConfigService.ts +82 -1
  61. package/Server/Services/ProjectService.ts +24 -0
  62. package/Server/Services/TeamMemberService.ts +6 -0
  63. package/Server/Services/UserNotificationRuleService.ts +13 -42
  64. package/Server/Services/UserOnCallLogService.ts +90 -0
  65. package/Server/Services/UserOnCallLogTimelineService.ts +43 -1
  66. package/Server/Types/AnalyticsDatabase/ModelPermission.ts +74 -9
  67. package/Server/Types/Database/QueryUtil.ts +57 -0
  68. package/Server/Utils/AI/AIChatPrivacyFilter.ts +28 -0
  69. package/Server/Utils/AI/AlertAIContextBuilder.ts +6 -1
  70. package/Server/Utils/AI/Chat/ChatAgentRunner.ts +1066 -0
  71. package/Server/Utils/AI/Chat/ObservabilityAssistant.ts +239 -0
  72. package/Server/Utils/AI/Chat/ObservabilityChatPrompt.ts +51 -0
  73. package/Server/Utils/AI/IncidentAIContextBuilder.ts +18 -3
  74. package/Server/Utils/AI/IncidentEpisodeAIContextBuilder.ts +6 -1
  75. package/Server/Utils/AI/ScheduledMaintenanceAIContextBuilder.ts +12 -2
  76. package/Server/Utils/AI/Toolbox/AlertTools.ts +201 -0
  77. package/Server/Utils/AI/Toolbox/AlertWriteTools.ts +174 -0
  78. package/Server/Utils/AI/Toolbox/ContextTools.ts +189 -0
  79. package/Server/Utils/AI/Toolbox/ExceptionTools.ts +149 -0
  80. package/Server/Utils/AI/Toolbox/IncidentTools.ts +386 -0
  81. package/Server/Utils/AI/Toolbox/IncidentWriteTools.ts +350 -0
  82. package/Server/Utils/AI/Toolbox/Index.ts +231 -0
  83. package/Server/Utils/AI/Toolbox/LogTools.ts +339 -0
  84. package/Server/Utils/AI/Toolbox/MetricTools.ts +179 -0
  85. package/Server/Utils/AI/Toolbox/MonitorTools.ts +193 -0
  86. package/Server/Utils/AI/Toolbox/RecentChangesTools.ts +208 -0
  87. package/Server/Utils/AI/Toolbox/Serializer.ts +299 -0
  88. package/Server/Utils/AI/Toolbox/ToolTypes.ts +249 -0
  89. package/Server/Utils/AI/Toolbox/TraceTools.ts +402 -0
  90. package/Server/Utils/AI/Toolbox/WidgetBuilder.ts +189 -0
  91. package/Server/Utils/Database/MigrationFailureLog.ts +240 -0
  92. package/Server/Utils/IncomingCallPhoneNumber.ts +41 -0
  93. package/Server/Utils/LLM/LLMService.ts +605 -96
  94. package/Server/Utils/Telemetry/IoTSnapshotScan.ts +12 -9
  95. package/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.ts +12 -9
  96. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +512 -19
  97. package/Server/Utils/Workspace/Slack/Slack.ts +80 -0
  98. package/Server/Utils/Workspace/Slack/app-manifest.json +16 -1
  99. package/Tests/Server/Services/AnalyticsDatabaseService.test.ts +0 -8
  100. package/Tests/Server/Services/OnCallDutyPolicyScheduleLayerUserReorder.test.ts +233 -0
  101. package/Tests/Server/Services/OnCallDutyPolicyTimeLogServiceScoping.test.ts +242 -0
  102. package/Tests/Server/Services/OnCallDutyPolicyUserOverrideEdit.test.ts +198 -0
  103. package/Tests/Server/Services/UserOnCallLogClaimNotificationRule.test.ts +495 -0
  104. package/Tests/Server/Types/Database/QueryUtil.test.ts +74 -0
  105. package/Tests/Server/Utils/AI/AIChatModelACL.test.ts +42 -0
  106. package/Tests/Server/Utils/AI/ChatAgentHelpers.test.ts +89 -0
  107. package/Tests/Server/Utils/AI/LLMServiceBaseUrl.test.ts +139 -0
  108. package/Tests/Server/Utils/AI/LLMServiceToolCalling.test.ts +386 -0
  109. package/Tests/Server/Utils/AI/ToolArgsGetTimeRange.test.ts +62 -0
  110. package/Tests/Server/Utils/AI/ToolArgsScopeServiceIds.test.ts +79 -0
  111. package/Tests/Server/Utils/AI/ToolResultSerializer.test.ts +223 -0
  112. package/Tests/Types/Billing/SubscriptionStatus.test.ts +127 -0
  113. package/Tests/Types/DateExhaustiveTimezone.test.ts +700 -0
  114. package/Tests/Types/DateTimezoneWallClock.test.ts +99 -0
  115. package/Tests/Types/Events/Recurring.test.ts +22 -9
  116. package/Tests/Types/Metrics/RecordingRuleDefinition.test.ts +213 -0
  117. package/Tests/Types/OnCallDutyPolicy/LayerUtilAuditFixes.test.ts +291 -0
  118. package/Tests/Types/OnCallDutyPolicy/LayerUtilAuditFixesRound2.test.ts +398 -0
  119. package/Tests/Types/OnCallDutyPolicy/LayerUtilDSTWeekendGap.test.ts +114 -0
  120. package/Tests/Types/OnCallDutyPolicy/LayerUtilDSTWeeklyDayShift.test.ts +76 -0
  121. package/Tests/Types/OnCallDutyPolicy/LayerUtilDailyMutation.test.ts +128 -0
  122. package/Tests/Types/OnCallDutyPolicy/LayerUtilDailyProbe.test.ts +203 -0
  123. package/Tests/Types/OnCallDutyPolicy/LayerUtilDiffFuzz.test.ts +322 -0
  124. package/Tests/Types/OnCallDutyPolicy/LayerUtilEdgeCases.test.ts +280 -0
  125. package/Tests/Types/OnCallDutyPolicy/LayerUtilExhaustiveCurrentUser.test.ts +863 -0
  126. package/Tests/Types/OnCallDutyPolicy/LayerUtilExhaustiveDaily.test.ts +900 -0
  127. package/Tests/Types/OnCallDutyPolicy/LayerUtilExhaustiveMultiLayer.test.ts +1104 -0
  128. package/Tests/Types/OnCallDutyPolicy/LayerUtilExhaustiveRotation.test.ts +957 -0
  129. package/Tests/Types/OnCallDutyPolicy/LayerUtilExhaustiveWeekly.test.ts +1095 -0
  130. package/Tests/Types/OnCallDutyPolicy/LayerUtilInvariants.test.ts +232 -0
  131. package/Tests/Types/OnCallDutyPolicy/LayerUtilMergeAudit.test.ts +227 -0
  132. package/Tests/Types/OnCallDutyPolicy/LayerUtilMonthYearAudit.test.ts +255 -0
  133. package/Tests/Types/OnCallDutyPolicy/LayerUtilMultiLayerAudit.test.ts +388 -0
  134. package/Tests/Types/OnCallDutyPolicy/LayerUtilMultiLayerEdge.test.ts +300 -0
  135. package/Tests/Types/OnCallDutyPolicy/LayerUtilOvernightDSTAudit.test.ts +158 -0
  136. package/Tests/Types/OnCallDutyPolicy/LayerUtilRestrictedGapFix.test.ts +253 -0
  137. package/Tests/Types/OnCallDutyPolicy/LayerUtilRestrictedGapRepro.test.ts +157 -0
  138. package/Tests/Types/OnCallDutyPolicy/LayerUtilRotationFixes.test.ts +414 -0
  139. package/Tests/Types/OnCallDutyPolicy/LayerUtilTimezone.test.ts +243 -0
  140. package/Tests/Types/OnCallDutyPolicy/LayerUtilWeekendGapRepro.test.ts +112 -0
  141. package/Tests/Types/OnCallDutyPolicy/OverrideLensAudit.test.ts +117 -0
  142. package/Tests/Types/OnCallDutyPolicy/RestrictionTimes.test.ts +8 -6
  143. package/Tests/Types/OnCallDutyPolicy/RestrictionTimesDefaultDayAudit.test.ts +112 -0
  144. package/Tests/Types/OnCallDutyPolicy/RestrictionTimesExhaustive.test.ts +821 -0
  145. package/Tests/Types/OnCallDutyPolicy/RestrictionTimesMutationInvariant.test.ts +886 -0
  146. package/Tests/Types/OnCallDutyPolicy/UserOverrideUtil.test.ts +255 -0
  147. package/Tests/Types/OnCallDutyPolicy/UserOverrideUtilExhaustive.test.ts +1126 -0
  148. package/Types/AI/AIChatMessageRole.ts +6 -0
  149. package/Types/AI/AIChatMessageStatus.ts +32 -0
  150. package/Types/AI/AIChatPermissionMode.ts +69 -0
  151. package/Types/AI/AIChatTypes.ts +231 -0
  152. package/Types/AI/AIRunEventType.ts +17 -0
  153. package/Types/AI/AIRunStatus.ts +28 -0
  154. package/Types/AI/AIRunType.ts +6 -0
  155. package/Types/Date.ts +200 -15
  156. package/Types/LLM/LlmType.ts +6 -0
  157. package/Types/OnCallDutyPolicy/Layer.ts +790 -260
  158. package/Types/OnCallDutyPolicy/RestrictionTimes.ts +39 -13
  159. package/Types/OnCallDutyPolicy/UserOverrideUtil.ts +21 -5
  160. package/UI/Components/Events/RecurringFieldElement.tsx +16 -0
  161. package/UI/Components/Header/HeaderIconDropdownButton.tsx +22 -12
  162. package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +35 -3
  163. package/UI/Components/ModelFormModal/ModelFormModal.tsx +8 -0
  164. package/UI/Components/Page/Page.tsx +14 -0
  165. package/UI/Components/RadioButtons/BasicRadioButtons.tsx +1 -1
  166. package/UI/Utils/LlmTypeDropdownOptions.ts +40 -0
  167. package/UI/Utils/TestLLMProvider.ts +59 -0
  168. package/build/dist/Models/DatabaseModels/AIConversation.js +345 -0
  169. package/build/dist/Models/DatabaseModels/AIConversation.js.map +1 -0
  170. package/build/dist/Models/DatabaseModels/AIConversationMessage.js +521 -0
  171. package/build/dist/Models/DatabaseModels/AIConversationMessage.js.map +1 -0
  172. package/build/dist/Models/DatabaseModels/AIRun.js +619 -0
  173. package/build/dist/Models/DatabaseModels/AIRun.js.map +1 -0
  174. package/build/dist/Models/DatabaseModels/AIRunEvent.js +469 -0
  175. package/build/dist/Models/DatabaseModels/AIRunEvent.js.map +1 -0
  176. package/build/dist/Models/DatabaseModels/IncidentEpisodeRoleMember.js +1 -1
  177. package/build/dist/Models/DatabaseModels/IncidentEpisodeRoleMember.js.map +1 -1
  178. package/build/dist/Models/DatabaseModels/IncidentMember.js +1 -1
  179. package/build/dist/Models/DatabaseModels/IncidentMember.js.map +1 -1
  180. package/build/dist/Models/DatabaseModels/IncomingCallPolicy.js +10 -0
  181. package/build/dist/Models/DatabaseModels/IncomingCallPolicy.js.map +1 -1
  182. package/build/dist/Models/DatabaseModels/Index.js +10 -0
  183. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  184. package/build/dist/Models/DatabaseModels/LlmLog.js +28 -0
  185. package/build/dist/Models/DatabaseModels/LlmLog.js.map +1 -1
  186. package/build/dist/Models/DatabaseModels/LlmProvider.js +2 -2
  187. package/build/dist/Models/DatabaseModels/LlmProvider.js.map +1 -1
  188. package/build/dist/Models/DatabaseModels/MigrationFailure.js +196 -0
  189. package/build/dist/Models/DatabaseModels/MigrationFailure.js.map +1 -0
  190. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyExecutionLog.js +52 -2
  191. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyExecutionLog.js.map +1 -1
  192. package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js +45 -0
  193. package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js.map +1 -1
  194. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleLayer.js +6 -0
  195. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleLayer.js.map +1 -1
  196. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleLayerUser.js +6 -0
  197. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyScheduleLayerUser.js.map +1 -1
  198. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyTimeLog.js +1 -1
  199. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyTimeLog.js.map +1 -1
  200. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyUserOverride.js +2 -2
  201. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyUserOverride.js.map +1 -1
  202. package/build/dist/Server/API/AIChatAPI.js +498 -0
  203. package/build/dist/Server/API/AIChatAPI.js.map +1 -0
  204. package/build/dist/Server/API/AlertAPI.js +1 -1
  205. package/build/dist/Server/API/IncidentAPI.js +2 -2
  206. package/build/dist/Server/API/IncidentEpisodeAPI.js +1 -1
  207. package/build/dist/Server/API/LlmProviderAPI.js +108 -1
  208. package/build/dist/Server/API/LlmProviderAPI.js.map +1 -1
  209. package/build/dist/Server/API/MicrosoftTeamsAPI.js +4 -0
  210. package/build/dist/Server/API/MicrosoftTeamsAPI.js.map +1 -1
  211. package/build/dist/Server/API/ScheduledMaintenanceAPI.js +1 -1
  212. package/build/dist/Server/API/SlackAPI.js +442 -0
  213. package/build/dist/Server/API/SlackAPI.js.map +1 -1
  214. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783363279075-AddAIChatModels.js +96 -0
  215. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783363279075-AddAIChatModels.js.map +1 -0
  216. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783443471795-AddLlmProviderToAIConversation.js +25 -0
  217. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783443471795-AddLlmProviderToAIConversation.js.map +1 -0
  218. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783453297388-AddAIChatWriteActionsAndWidgets.js +31 -0
  219. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783453297388-AddAIChatWriteActionsAndWidgets.js.map +1 -0
  220. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783461767405-MigrationName.js +46 -0
  221. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783461767405-MigrationName.js.map +1 -0
  222. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783470000000-AddIncomingCallPolicyRoutingPhoneNumberUnique.js +18 -0
  223. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783470000000-AddIncomingCallPolicyRoutingPhoneNumberUnique.js.map +1 -0
  224. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783510935686-FixNotNullForeignKeysOnDelete.js +38 -0
  225. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783510935686-FixNotNullForeignKeysOnDelete.js.map +1 -0
  226. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783515836148-MigrationName.js +16 -0
  227. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783515836148-MigrationName.js.map +1 -0
  228. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783523076215-AddMigrationFailureTable.js +18 -0
  229. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783523076215-AddMigrationFailureTable.js.map +1 -0
  230. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +16 -0
  231. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  232. package/build/dist/Server/Infrastructure/PostgresDatabase.js +9 -0
  233. package/build/dist/Server/Infrastructure/PostgresDatabase.js.map +1 -1
  234. package/build/dist/Server/Services/AIConversationMessageService.js +34 -0
  235. package/build/dist/Server/Services/AIConversationMessageService.js.map +1 -0
  236. package/build/dist/Server/Services/AIConversationService.js +42 -0
  237. package/build/dist/Server/Services/AIConversationService.js.map +1 -0
  238. package/build/dist/Server/Services/AIRunEventService.js +34 -0
  239. package/build/dist/Server/Services/AIRunEventService.js.map +1 -0
  240. package/build/dist/Server/Services/AIRunService.js +34 -0
  241. package/build/dist/Server/Services/AIRunService.js.map +1 -0
  242. package/build/dist/Server/Services/AIService.js +84 -25
  243. package/build/dist/Server/Services/AIService.js.map +1 -1
  244. package/build/dist/Server/Services/AnalyticsDatabaseService.js +10 -1
  245. package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
  246. package/build/dist/Server/Services/DatabaseService.js +20 -1
  247. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  248. package/build/dist/Server/Services/IncidentService.js +1 -1
  249. package/build/dist/Server/Services/IncomingCallPolicyEscalationRuleService.js +55 -2
  250. package/build/dist/Server/Services/IncomingCallPolicyEscalationRuleService.js.map +1 -1
  251. package/build/dist/Server/Services/IncomingCallPolicyService.js +40 -0
  252. package/build/dist/Server/Services/IncomingCallPolicyService.js.map +1 -1
  253. package/build/dist/Server/Services/Index.js +2 -0
  254. package/build/dist/Server/Services/Index.js.map +1 -1
  255. package/build/dist/Server/Services/LlmProviderService.js +108 -0
  256. package/build/dist/Server/Services/LlmProviderService.js.map +1 -1
  257. package/build/dist/Server/Services/MigrationFailureService.js +9 -0
  258. package/build/dist/Server/Services/MigrationFailureService.js.map +1 -0
  259. package/build/dist/Server/Services/MonitorProbeService.js +33 -7
  260. package/build/dist/Server/Services/MonitorProbeService.js.map +1 -1
  261. package/build/dist/Server/Services/MonitorService.js +12 -5
  262. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  263. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js +81 -22
  264. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js.map +1 -1
  265. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleService.js +134 -31
  266. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleService.js.map +1 -1
  267. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleUserService.js +21 -13
  268. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleUserService.js.map +1 -1
  269. package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogService.js +36 -0
  270. package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogService.js.map +1 -1
  271. package/build/dist/Server/Services/OnCallDutyPolicyScheduleLayerService.js +121 -0
  272. package/build/dist/Server/Services/OnCallDutyPolicyScheduleLayerService.js.map +1 -1
  273. package/build/dist/Server/Services/OnCallDutyPolicyScheduleLayerUserService.js +11 -2
  274. package/build/dist/Server/Services/OnCallDutyPolicyScheduleLayerUserService.js.map +1 -1
  275. package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js +409 -36
  276. package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js.map +1 -1
  277. package/build/dist/Server/Services/OnCallDutyPolicyTimeLogService.js +52 -8
  278. package/build/dist/Server/Services/OnCallDutyPolicyTimeLogService.js.map +1 -1
  279. package/build/dist/Server/Services/OnCallDutyPolicyUserOverrideService.js +170 -3
  280. package/build/dist/Server/Services/OnCallDutyPolicyUserOverrideService.js.map +1 -1
  281. package/build/dist/Server/Services/ProjectCallSMSConfigService.js +72 -0
  282. package/build/dist/Server/Services/ProjectCallSMSConfigService.js.map +1 -1
  283. package/build/dist/Server/Services/ProjectService.js +25 -0
  284. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  285. package/build/dist/Server/Services/TeamMemberService.js +6 -0
  286. package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
  287. package/build/dist/Server/Services/UserNotificationRuleService.js +12 -30
  288. package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
  289. package/build/dist/Server/Services/UserOnCallLogService.js +75 -0
  290. package/build/dist/Server/Services/UserOnCallLogService.js.map +1 -1
  291. package/build/dist/Server/Services/UserOnCallLogTimelineService.js +31 -1
  292. package/build/dist/Server/Services/UserOnCallLogTimelineService.js.map +1 -1
  293. package/build/dist/Server/Types/AnalyticsDatabase/ModelPermission.js +50 -7
  294. package/build/dist/Server/Types/AnalyticsDatabase/ModelPermission.js.map +1 -1
  295. package/build/dist/Server/Types/Database/QueryUtil.js +45 -0
  296. package/build/dist/Server/Types/Database/QueryUtil.js.map +1 -1
  297. package/build/dist/Server/Utils/AI/AIChatPrivacyFilter.js +18 -0
  298. package/build/dist/Server/Utils/AI/AIChatPrivacyFilter.js.map +1 -0
  299. package/build/dist/Server/Utils/AI/AlertAIContextBuilder.js +6 -1
  300. package/build/dist/Server/Utils/AI/AlertAIContextBuilder.js.map +1 -1
  301. package/build/dist/Server/Utils/AI/Chat/ChatAgentRunner.js +756 -0
  302. package/build/dist/Server/Utils/AI/Chat/ChatAgentRunner.js.map +1 -0
  303. package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js +165 -0
  304. package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js.map +1 -0
  305. package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js +44 -0
  306. package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js.map +1 -0
  307. package/build/dist/Server/Utils/AI/IncidentAIContextBuilder.js +18 -3
  308. package/build/dist/Server/Utils/AI/IncidentAIContextBuilder.js.map +1 -1
  309. package/build/dist/Server/Utils/AI/IncidentEpisodeAIContextBuilder.js +6 -1
  310. package/build/dist/Server/Utils/AI/IncidentEpisodeAIContextBuilder.js.map +1 -1
  311. package/build/dist/Server/Utils/AI/ScheduledMaintenanceAIContextBuilder.js +12 -2
  312. package/build/dist/Server/Utils/AI/ScheduledMaintenanceAIContextBuilder.js.map +1 -1
  313. package/build/dist/Server/Utils/AI/Toolbox/AlertTools.js +167 -0
  314. package/build/dist/Server/Utils/AI/Toolbox/AlertTools.js.map +1 -0
  315. package/build/dist/Server/Utils/AI/Toolbox/AlertWriteTools.js +136 -0
  316. package/build/dist/Server/Utils/AI/Toolbox/AlertWriteTools.js.map +1 -0
  317. package/build/dist/Server/Utils/AI/Toolbox/ContextTools.js +141 -0
  318. package/build/dist/Server/Utils/AI/Toolbox/ContextTools.js.map +1 -0
  319. package/build/dist/Server/Utils/AI/Toolbox/ExceptionTools.js +117 -0
  320. package/build/dist/Server/Utils/AI/Toolbox/ExceptionTools.js.map +1 -0
  321. package/build/dist/Server/Utils/AI/Toolbox/IncidentTools.js +318 -0
  322. package/build/dist/Server/Utils/AI/Toolbox/IncidentTools.js.map +1 -0
  323. package/build/dist/Server/Utils/AI/Toolbox/IncidentWriteTools.js +280 -0
  324. package/build/dist/Server/Utils/AI/Toolbox/IncidentWriteTools.js.map +1 -0
  325. package/build/dist/Server/Utils/AI/Toolbox/Index.js +153 -0
  326. package/build/dist/Server/Utils/AI/Toolbox/Index.js.map +1 -0
  327. package/build/dist/Server/Utils/AI/Toolbox/LogTools.js +246 -0
  328. package/build/dist/Server/Utils/AI/Toolbox/LogTools.js.map +1 -0
  329. package/build/dist/Server/Utils/AI/Toolbox/MetricTools.js +120 -0
  330. package/build/dist/Server/Utils/AI/Toolbox/MetricTools.js.map +1 -0
  331. package/build/dist/Server/Utils/AI/Toolbox/MonitorTools.js +158 -0
  332. package/build/dist/Server/Utils/AI/Toolbox/MonitorTools.js.map +1 -0
  333. package/build/dist/Server/Utils/AI/Toolbox/RecentChangesTools.js +165 -0
  334. package/build/dist/Server/Utils/AI/Toolbox/RecentChangesTools.js.map +1 -0
  335. package/build/dist/Server/Utils/AI/Toolbox/Serializer.js +228 -0
  336. package/build/dist/Server/Utils/AI/Toolbox/Serializer.js.map +1 -0
  337. package/build/dist/Server/Utils/AI/Toolbox/ToolTypes.js +142 -0
  338. package/build/dist/Server/Utils/AI/Toolbox/ToolTypes.js.map +1 -0
  339. package/build/dist/Server/Utils/AI/Toolbox/TraceTools.js +309 -0
  340. package/build/dist/Server/Utils/AI/Toolbox/TraceTools.js.map +1 -0
  341. package/build/dist/Server/Utils/AI/Toolbox/WidgetBuilder.js +120 -0
  342. package/build/dist/Server/Utils/AI/Toolbox/WidgetBuilder.js.map +1 -0
  343. package/build/dist/Server/Utils/Database/MigrationFailureLog.js +174 -0
  344. package/build/dist/Server/Utils/Database/MigrationFailureLog.js.map +1 -0
  345. package/build/dist/Server/Utils/IncomingCallPhoneNumber.js +30 -0
  346. package/build/dist/Server/Utils/IncomingCallPhoneNumber.js.map +1 -0
  347. package/build/dist/Server/Utils/LLM/LLMService.js +452 -92
  348. package/build/dist/Server/Utils/LLM/LLMService.js.map +1 -1
  349. package/build/dist/Server/Utils/Telemetry/IoTSnapshotScan.js +11 -8
  350. package/build/dist/Server/Utils/Telemetry/IoTSnapshotScan.js.map +1 -1
  351. package/build/dist/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.js +11 -8
  352. package/build/dist/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.js.map +1 -1
  353. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +378 -15
  354. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
  355. package/build/dist/Server/Utils/Workspace/Slack/Slack.js +59 -0
  356. package/build/dist/Server/Utils/Workspace/Slack/Slack.js.map +1 -1
  357. package/build/dist/Server/Utils/Workspace/Slack/app-manifest.json +16 -1
  358. package/build/dist/Types/AI/AIChatMessageRole.js +7 -0
  359. package/build/dist/Types/AI/AIChatMessageRole.js.map +1 -0
  360. package/build/dist/Types/AI/AIChatMessageStatus.js +27 -0
  361. package/build/dist/Types/AI/AIChatMessageStatus.js.map +1 -0
  362. package/build/dist/Types/AI/AIChatPermissionMode.js +53 -0
  363. package/build/dist/Types/AI/AIChatPermissionMode.js.map +1 -0
  364. package/build/dist/Types/AI/AIChatTypes.js +74 -0
  365. package/build/dist/Types/AI/AIChatTypes.js.map +1 -0
  366. package/build/dist/Types/AI/AIRunEventType.js +18 -0
  367. package/build/dist/Types/AI/AIRunEventType.js.map +1 -0
  368. package/build/dist/Types/AI/AIRunStatus.js +26 -0
  369. package/build/dist/Types/AI/AIRunStatus.js.map +1 -0
  370. package/build/dist/Types/AI/AIRunType.js +7 -0
  371. package/build/dist/Types/AI/AIRunType.js.map +1 -0
  372. package/build/dist/Types/Date.js +153 -15
  373. package/build/dist/Types/Date.js.map +1 -1
  374. package/build/dist/Types/LLM/LlmType.js +6 -0
  375. package/build/dist/Types/LLM/LlmType.js.map +1 -1
  376. package/build/dist/Types/OnCallDutyPolicy/Layer.js +602 -171
  377. package/build/dist/Types/OnCallDutyPolicy/Layer.js.map +1 -1
  378. package/build/dist/Types/OnCallDutyPolicy/RestrictionTimes.js +27 -13
  379. package/build/dist/Types/OnCallDutyPolicy/RestrictionTimes.js.map +1 -1
  380. package/build/dist/Types/OnCallDutyPolicy/UserOverrideUtil.js +20 -5
  381. package/build/dist/Types/OnCallDutyPolicy/UserOverrideUtil.js.map +1 -1
  382. package/build/dist/UI/Components/Events/RecurringFieldElement.js +13 -0
  383. package/build/dist/UI/Components/Events/RecurringFieldElement.js.map +1 -1
  384. package/build/dist/UI/Components/Header/HeaderIconDropdownButton.js +10 -5
  385. package/build/dist/UI/Components/Header/HeaderIconDropdownButton.js.map +1 -1
  386. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +18 -4
  387. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
  388. package/build/dist/UI/Components/ModelFormModal/ModelFormModal.js.map +1 -1
  389. package/build/dist/UI/Components/Page/Page.js +3 -1
  390. package/build/dist/UI/Components/Page/Page.js.map +1 -1
  391. package/build/dist/UI/Components/RadioButtons/BasicRadioButtons.js +1 -1
  392. package/build/dist/UI/Components/RadioButtons/BasicRadioButtons.js.map +1 -1
  393. package/build/dist/UI/Utils/LlmTypeDropdownOptions.js +38 -0
  394. package/build/dist/UI/Utils/LlmTypeDropdownOptions.js.map +1 -0
  395. package/build/dist/UI/Utils/TestLLMProvider.js +37 -0
  396. package/build/dist/UI/Utils/TestLLMProvider.js.map +1 -0
  397. package/package.json +1 -1
@@ -0,0 +1,208 @@
1
+ import Monitor from "../../../../Models/DatabaseModels/Monitor";
2
+ import MonitorStatusTimeline from "../../../../Models/DatabaseModels/MonitorStatusTimeline";
3
+ import ScheduledMaintenance from "../../../../Models/DatabaseModels/ScheduledMaintenance";
4
+ import TelemetryException from "../../../../Models/DatabaseModels/TelemetryException";
5
+ import { JSONObject } from "../../../../Types/JSON";
6
+ import Permission from "../../../../Types/Permission";
7
+ import SortOrder from "../../../../Types/BaseDatabase/SortOrder";
8
+ import MonitorStatusTimelineService from "../../../Services/MonitorStatusTimelineService";
9
+ import ScheduledMaintenanceService from "../../../Services/ScheduledMaintenanceService";
10
+ import TelemetryExceptionService from "../../../Services/TelemetryExceptionService";
11
+ import QueryHelper from "../../../Types/Database/QueryHelper";
12
+ import logger from "../../Logger";
13
+ import ToolResultSerializer, { SerializedResult } from "./Serializer";
14
+ import {
15
+ ObservabilityTool,
16
+ ToolArgs,
17
+ ToolContext,
18
+ ToolExecutionResult,
19
+ TimeRangeSchemaProperties,
20
+ } from "./ToolTypes";
21
+
22
+ /*
23
+ * Gate on Monitor read permissions. This is defense-in-depth only: every
24
+ * source query below runs under the requesting user's props, so a user who
25
+ * cannot see monitors / exceptions / maintenance simply gets no rows from that
26
+ * source — never another user's data. Resolved lazily to avoid the
27
+ * import-time circular-dependency TypeError other tools document.
28
+ */
29
+ let cachedReadPermissions: Array<Permission> | null = null;
30
+ const resolveReadPermissions: () => Array<Permission> =
31
+ (): Array<Permission> => {
32
+ if (!cachedReadPermissions) {
33
+ cachedReadPermissions = new Monitor().getReadPermissions();
34
+ }
35
+ return cachedReadPermissions;
36
+ };
37
+
38
+ // One normalized entry in the merged "what changed" feed.
39
+ interface ChangeEvent {
40
+ at: Date;
41
+ change: string;
42
+ detail: string;
43
+ }
44
+
45
+ export const RecentChangesTool: ObservabilityTool = {
46
+ name: "recent_changes",
47
+ description:
48
+ "Get a single chronological feed of what changed in a time window: newly-seen exceptions, monitor status changes (up/down), and scheduled maintenance overlapping the window. This is the highest-yield way to answer 'what changed right before this started?' during root-cause analysis — call it with the window around when a problem began.",
49
+ inputSchema: {
50
+ type: "object",
51
+ properties: {
52
+ ...TimeRangeSchemaProperties,
53
+ limitPerSource: {
54
+ type: "number",
55
+ description:
56
+ "Maximum items to pull from each source (exceptions, monitor changes, maintenance) before merging. Default 15, max 30.",
57
+ },
58
+ },
59
+ },
60
+ get requiredPermissions(): Array<Permission> {
61
+ return resolveReadPermissions();
62
+ },
63
+ execute: async (
64
+ args: JSONObject,
65
+ ctx: ToolContext,
66
+ ): Promise<ToolExecutionResult> => {
67
+ const timeRange: { startTime: Date; endTime: Date } = ToolArgs.getTimeRange(
68
+ args,
69
+ { defaultHours: 24, maxDays: 30 },
70
+ );
71
+ const startTime: Date = timeRange.startTime;
72
+ const endTime: Date = timeRange.endTime;
73
+
74
+ const limitPerSource: number = ToolArgs.getNumber(args, "limitPerSource", {
75
+ defaultValue: 15,
76
+ min: 1,
77
+ max: 30,
78
+ });
79
+
80
+ const events: Array<ChangeEvent> = [];
81
+
82
+ // 1) Newly-seen exceptions — their first occurrence falls inside the window.
83
+ try {
84
+ const exceptions: Array<TelemetryException> =
85
+ await TelemetryExceptionService.findBy({
86
+ query: {
87
+ firstSeenAt: QueryHelper.inBetween(startTime, endTime),
88
+ } as never,
89
+ select: {
90
+ message: true,
91
+ exceptionType: true,
92
+ firstSeenAt: true,
93
+ occuranceCount: true,
94
+ },
95
+ sort: { firstSeenAt: SortOrder.Descending },
96
+ limit: limitPerSource,
97
+ skip: 0,
98
+ props: ctx.props,
99
+ });
100
+
101
+ for (const exception of exceptions) {
102
+ if (!exception.firstSeenAt) {
103
+ continue;
104
+ }
105
+ events.push({
106
+ at: exception.firstSeenAt,
107
+ change: "new_exception",
108
+ detail: `${exception.exceptionType || "Exception"}: ${exception.message || ""} (x${exception.occuranceCount ?? 0})`,
109
+ });
110
+ }
111
+ } catch (error) {
112
+ logger.debug(`recent_changes: exceptions source skipped: ${error}`);
113
+ }
114
+
115
+ // 2) Monitor status changes (up/down) inside the window.
116
+ try {
117
+ const statusChanges: Array<MonitorStatusTimeline> =
118
+ await MonitorStatusTimelineService.findBy({
119
+ query: {
120
+ createdAt: QueryHelper.inBetween(startTime, endTime),
121
+ },
122
+ select: {
123
+ createdAt: true,
124
+ monitor: { name: true },
125
+ monitorStatus: { name: true },
126
+ },
127
+ sort: { createdAt: SortOrder.Descending },
128
+ limit: limitPerSource,
129
+ skip: 0,
130
+ props: ctx.props,
131
+ });
132
+
133
+ for (const statusChange of statusChanges) {
134
+ if (!statusChange.createdAt) {
135
+ continue;
136
+ }
137
+ events.push({
138
+ at: statusChange.createdAt,
139
+ change: "monitor_status_change",
140
+ detail: `${statusChange.monitor?.name || "Monitor"} → ${statusChange.monitorStatus?.name || "unknown"}`,
141
+ });
142
+ }
143
+ } catch (error) {
144
+ logger.debug(`recent_changes: monitor source skipped: ${error}`);
145
+ }
146
+
147
+ /*
148
+ * 3) Scheduled maintenance overlapping the window (started before it ended,
149
+ * ends after it started).
150
+ */
151
+ try {
152
+ const maintenanceEvents: Array<ScheduledMaintenance> =
153
+ await ScheduledMaintenanceService.findBy({
154
+ query: {
155
+ startsAt: QueryHelper.lessThanEqualTo(endTime),
156
+ endsAt: QueryHelper.greaterThanEqualTo(startTime),
157
+ },
158
+ select: {
159
+ title: true,
160
+ startsAt: true,
161
+ endsAt: true,
162
+ currentScheduledMaintenanceState: { name: true },
163
+ },
164
+ sort: { startsAt: SortOrder.Descending },
165
+ limit: limitPerSource,
166
+ skip: 0,
167
+ props: ctx.props,
168
+ });
169
+
170
+ for (const maintenance of maintenanceEvents) {
171
+ if (!maintenance.startsAt) {
172
+ continue;
173
+ }
174
+ events.push({
175
+ at: maintenance.startsAt,
176
+ change: "scheduled_maintenance",
177
+ detail: `${maintenance.title || "Maintenance"} (${maintenance.currentScheduledMaintenanceState?.name || "scheduled"})`,
178
+ });
179
+ }
180
+ } catch (error) {
181
+ logger.debug(`recent_changes: maintenance source skipped: ${error}`);
182
+ }
183
+
184
+ // Merge into one chronological feed, most recent first.
185
+ events.sort((a: ChangeEvent, b: ChangeEvent) => {
186
+ return b.at.getTime() - a.at.getTime();
187
+ });
188
+
189
+ const rows: Array<JSONObject> = events.map((event: ChangeEvent) => {
190
+ return {
191
+ at: event.at,
192
+ change: event.change,
193
+ detail: event.detail,
194
+ };
195
+ });
196
+
197
+ const serialized: SerializedResult =
198
+ ToolResultSerializer.serializeRows(rows);
199
+
200
+ return {
201
+ dataForLlm: serialized.text,
202
+ rowCount: serialized.rowCount,
203
+ citationLabel: `Changes ${startTime.toISOString()} → ${endTime.toISOString()} (${serialized.rowCount} events)`,
204
+ redactionCount: serialized.redactionCount,
205
+ isTruncated: serialized.isTruncated,
206
+ };
207
+ },
208
+ };
@@ -0,0 +1,299 @@
1
+ import { JSONObject, JSONValue } from "../../../../Types/JSON";
2
+
3
+ /*
4
+ * Prepares tool results for the LLM prompt: redacts likely secrets/PII,
5
+ * truncates long fields, and caps total payload size. Everything that enters
6
+ * the prompt (and therefore leaves for the LLM provider, and is previewed in
7
+ * LlmLog.requestPrompt) passes through here first.
8
+ */
9
+
10
+ const MAX_ROWS: number = 50;
11
+ const MAX_FIELD_LENGTH: number = 500;
12
+ const MAX_PAYLOAD_BYTES: number = 16 * 1024;
13
+
14
+ interface RedactionRule {
15
+ name: string;
16
+ regex: RegExp;
17
+ replacement: string;
18
+ }
19
+
20
+ /*
21
+ * These are security redactions, not the fingerprint-normalization regexes
22
+ * (those normalize numbers/uuids for grouping and do not cover credentials).
23
+ */
24
+ const REDACTION_RULES: Array<RedactionRule> = [
25
+ {
26
+ name: "jwt",
27
+ regex: /eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{5,}/g,
28
+ replacement: "[redacted-jwt]",
29
+ },
30
+ {
31
+ name: "bearer",
32
+ regex: /Bearer\s+[A-Za-z0-9._~+/-]{16,}=*/gi,
33
+ replacement: "Bearer [redacted-token]",
34
+ },
35
+ {
36
+ /*
37
+ * PEM private key blocks (RSA/EC/OPENSSH/PGP…). Match the whole
38
+ * BEGIN…END block, including newlines, so no key material leaks.
39
+ */
40
+ name: "private-key",
41
+ regex:
42
+ /-----BEGIN (?:[A-Z0-9]+ )*PRIVATE KEY-----[\s\S]*?-----END (?:[A-Z0-9]+ )*PRIVATE KEY-----/g,
43
+ replacement: "[redacted-private-key]",
44
+ },
45
+ {
46
+ name: "aws-access-key-id",
47
+ regex: /\b(?:AKIA|ASIA|AGPA|AIDA|AROA|AIPA|ANPA|ANVA|ASCA)[0-9A-Z]{16}\b/g,
48
+ replacement: "[redacted-aws-key]",
49
+ },
50
+ {
51
+ name: "github-token",
52
+ regex:
53
+ /\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9]{36,}\b|\bgithub_pat_[A-Za-z0-9_]{22,}\b/g,
54
+ replacement: "[redacted-github-token]",
55
+ },
56
+ {
57
+ name: "slack-token",
58
+ regex: /\bxox[baprs]-[A-Za-z0-9-]{10,}\b/g,
59
+ replacement: "[redacted-slack-token]",
60
+ },
61
+ {
62
+ name: "google-api-key",
63
+ regex: /\bAIza[0-9A-Za-z_-]{35}\b/g,
64
+ replacement: "[redacted-google-api-key]",
65
+ },
66
+ {
67
+ name: "email",
68
+ regex: /[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}/g,
69
+ replacement: "[redacted-email]",
70
+ },
71
+ {
72
+ name: "ipv4",
73
+ regex: /\b(?:\d{1,3}\.){3}\d{1,3}\b/g,
74
+ replacement: "[redacted-ip]",
75
+ },
76
+ {
77
+ /*
78
+ * Payment card numbers in the classic space/dash-separated grouping
79
+ * (e.g. "4111 1111 1111 1111"). Deliberately NOT matching bare 16-digit
80
+ * runs: an all-numeric 16-char OTel span id would collide with those and
81
+ * break the search_logs → get_trace pivot.
82
+ */
83
+ name: "credit-card",
84
+ regex: /\b\d{4}[ -]\d{4}[ -]\d{4}[ -]\d{4}\b/g,
85
+ replacement: "[redacted-card]",
86
+ },
87
+ {
88
+ /*
89
+ * Long hex blobs are usually secrets (SHA-256 digests, 40+ char API
90
+ * keys). But W3C/OTel trace IDs are exactly 32 hex chars and span IDs
91
+ * exactly 16 — redacting those would break the documented
92
+ * search_logs → get_trace pivot, since the model would never see the ID
93
+ * it needs to pass back. So only redact runs of 33+ hex chars, which
94
+ * preserves both ID lengths while still catching typical hash-length
95
+ * secrets. Labeled secrets of any length are still caught by
96
+ * key-value-secret below.
97
+ */
98
+ name: "hex-secret",
99
+ regex: /\b[0-9a-fA-F]{33,}\b/g,
100
+ replacement: "[redacted-hex]",
101
+ },
102
+ {
103
+ name: "key-value-secret",
104
+ regex:
105
+ /\b(password|passwd|secret|api[_-]?key|access[_-]?token|authorization)\b(\s*[:=]\s*)("[^"]{4,}"|'[^']{4,}'|[^\s,;&]{4,})/gi,
106
+ replacement: "$1$2[redacted]",
107
+ },
108
+ ];
109
+
110
+ export interface SerializedResult {
111
+ text: string;
112
+ rowCount: number;
113
+ redactionCount: number;
114
+ isTruncated: boolean;
115
+ bytes: number;
116
+ }
117
+
118
+ export default class ToolResultSerializer {
119
+ // Single pass per rule: count and substitute ($1/$2 groups) together.
120
+ private static applyRedactionRule(
121
+ text: string,
122
+ rule: RedactionRule,
123
+ ): { text: string; count: number } {
124
+ let count: number = 0;
125
+
126
+ const result: string = text.replace(
127
+ rule.regex,
128
+ (...matchArgs: Array<unknown>): string => {
129
+ count++;
130
+ return rule.replacement.replace(
131
+ /\$(\d)/g,
132
+ (_full: string, groupIndex: string): string => {
133
+ return String(matchArgs[Number(groupIndex)] ?? "");
134
+ },
135
+ );
136
+ },
137
+ );
138
+
139
+ return { text: result, count };
140
+ }
141
+
142
+ public static redact(text: string): { text: string; count: number } {
143
+ let redacted: string = text;
144
+ let count: number = 0;
145
+
146
+ for (const rule of REDACTION_RULES) {
147
+ const applied: { text: string; count: number } = this.applyRedactionRule(
148
+ redacted,
149
+ rule,
150
+ );
151
+ redacted = applied.text;
152
+ count += applied.count;
153
+ }
154
+
155
+ return { text: redacted, count };
156
+ }
157
+
158
+ // Byte-accurate truncation (substring counts UTF-16 units, not bytes).
159
+ private static truncateToBytes(text: string, maxBytes: number): string {
160
+ if (Buffer.byteLength(text, "utf8") <= maxBytes) {
161
+ return text;
162
+ }
163
+ return Buffer.from(text, "utf8").subarray(0, maxBytes).toString("utf8");
164
+ }
165
+
166
+ private static truncateField(value: string): {
167
+ value: string;
168
+ truncated: boolean;
169
+ } {
170
+ if (value.length <= MAX_FIELD_LENGTH) {
171
+ return { value, truncated: false };
172
+ }
173
+ return {
174
+ value: `${value.substring(0, MAX_FIELD_LENGTH)}… [truncated]`,
175
+ truncated: true,
176
+ };
177
+ }
178
+
179
+ private static serializeValue(value: JSONValue): string {
180
+ if (value === null || value === undefined) {
181
+ return "";
182
+ }
183
+ if (value instanceof Date) {
184
+ return value.toISOString();
185
+ }
186
+ if (typeof value === "object") {
187
+ return JSON.stringify(value);
188
+ }
189
+ return String(value);
190
+ }
191
+
192
+ /*
193
+ * Serialize rows as a compact markdown-ish record list. Applies row cap,
194
+ * per-field truncation, redaction and total payload cap.
195
+ */
196
+ public static serializeRows(
197
+ rows: Array<JSONObject>,
198
+ totalRowCount?: number,
199
+ ): SerializedResult {
200
+ let isTruncated: boolean = false;
201
+ let redactionCount: number = 0;
202
+
203
+ let rowsToSerialize: Array<JSONObject> = rows;
204
+ if (rows.length > MAX_ROWS) {
205
+ rowsToSerialize = rows.slice(0, MAX_ROWS);
206
+ isTruncated = true;
207
+ }
208
+
209
+ const lines: Array<string> = [];
210
+
211
+ for (const row of rowsToSerialize) {
212
+ const parts: Array<string> = [];
213
+
214
+ for (const key of Object.keys(row)) {
215
+ const rawValue: string = this.serializeValue(row[key] as JSONValue);
216
+ if (!rawValue) {
217
+ continue;
218
+ }
219
+
220
+ const redacted: { text: string; count: number } = this.redact(rawValue);
221
+ redactionCount += redacted.count;
222
+
223
+ const truncated: { value: string; truncated: boolean } =
224
+ this.truncateField(redacted.text);
225
+ if (truncated.truncated) {
226
+ isTruncated = true;
227
+ }
228
+
229
+ parts.push(`${key}=${truncated.value}`);
230
+ }
231
+
232
+ lines.push(`- ${parts.join(" | ")}`);
233
+ }
234
+
235
+ let text: string = lines.join("\n");
236
+
237
+ if (Buffer.byteLength(text, "utf8") > MAX_PAYLOAD_BYTES) {
238
+ isTruncated = true;
239
+ while (
240
+ lines.length > 1 &&
241
+ Buffer.byteLength(lines.join("\n"), "utf8") > MAX_PAYLOAD_BYTES
242
+ ) {
243
+ lines.pop();
244
+ }
245
+ // A single oversized row can still exceed the cap — hard-slice it.
246
+ text = `${this.truncateToBytes(lines.join("\n"), MAX_PAYLOAD_BYTES)}\n… [payload truncated]`;
247
+ }
248
+
249
+ const rowCount: number = totalRowCount ?? rows.length;
250
+
251
+ if (rows.length === 0) {
252
+ text = "(no rows found)";
253
+ }
254
+
255
+ /*
256
+ * Tell the model when it is only seeing a slice. Without this marker a
257
+ * capped result looks complete, and the model reports partial data as if it
258
+ * were the whole picture.
259
+ */
260
+ if (rows.length > MAX_ROWS) {
261
+ text = `${text}\n… [showing the first ${MAX_ROWS} of ${rowCount} rows; narrow the query — a shorter time range or more filters — to see the rest]`;
262
+ }
263
+
264
+ return {
265
+ text,
266
+ rowCount,
267
+ redactionCount,
268
+ isTruncated,
269
+ bytes: Buffer.byteLength(text, "utf8"),
270
+ };
271
+ }
272
+
273
+ // Serialize free-form text (e.g. a rendered trace tree).
274
+ public static serializeText(
275
+ text: string,
276
+ rowCount: number,
277
+ ): SerializedResult {
278
+ const redacted: { text: string; count: number } = this.redact(text);
279
+ let output: string = redacted.text;
280
+ let isTruncated: boolean = false;
281
+
282
+ if (Buffer.byteLength(output, "utf8") > MAX_PAYLOAD_BYTES) {
283
+ output = `${this.truncateToBytes(output, MAX_PAYLOAD_BYTES)}… [payload truncated]`;
284
+ isTruncated = true;
285
+ }
286
+
287
+ if (!output) {
288
+ output = "(no data found)";
289
+ }
290
+
291
+ return {
292
+ text: output,
293
+ rowCount,
294
+ redactionCount: redacted.count,
295
+ isTruncated,
296
+ bytes: Buffer.byteLength(output, "utf8"),
297
+ };
298
+ }
299
+ }