@oneuptime/common 12.0.8 → 12.0.9

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 (769) hide show
  1. package/Models/AnalyticsModels/MetricItemAggMV1mByK8sCluster.ts +1 -1
  2. package/Models/AnalyticsModels/MetricItemAggMV1mByService.ts +1 -1
  3. package/Models/DatabaseModels/AIConversation.ts +32 -0
  4. package/Models/DatabaseModels/AIConversationMessage.ts +41 -0
  5. package/Models/DatabaseModels/AlertEpisodeMember.ts +27 -0
  6. package/Models/DatabaseModels/IncidentEpisodeMember.ts +28 -0
  7. package/Models/DatabaseModels/Index.ts +12 -4
  8. package/Models/DatabaseModels/{TelemetryEntity.ts → InventoryItem.ts} +139 -9
  9. package/Models/DatabaseModels/InventoryItemCustomField.ts +434 -0
  10. package/Models/DatabaseModels/{TelemetryEntityRelationship.ts → InventoryItemRelationship.ts} +8 -8
  11. package/Models/DatabaseModels/NetworkDevice.ts +141 -0
  12. package/Models/DatabaseModels/NetworkDeviceLink.ts +699 -0
  13. package/Models/DatabaseModels/NetworkDeviceLinkRule.ts +467 -0
  14. package/Models/DatabaseModels/NetworkTopologySuppression.ts +429 -0
  15. package/Models/DatabaseModels/OnCallDutyPolicyFeed.ts +9 -0
  16. package/Models/DatabaseModels/Project.ts +78 -0
  17. package/Models/DatabaseModels/UserCall.ts +42 -0
  18. package/Models/DatabaseModels/UserEmail.ts +44 -0
  19. package/Models/DatabaseModels/UserNotificationRule.ts +425 -55
  20. package/Models/DatabaseModels/UserOnCallLogTimeline.ts +24 -2
  21. package/Models/DatabaseModels/UserPush.ts +49 -0
  22. package/Models/DatabaseModels/UserSMS.ts +43 -0
  23. package/Models/DatabaseModels/UserTelegram.ts +59 -0
  24. package/Models/DatabaseModels/UserWebhook.ts +52 -0
  25. package/Models/DatabaseModels/UserWhatsApp.ts +41 -0
  26. package/Models/DatabaseModels/WorkflowVariable.ts +12 -0
  27. package/Server/API/AIChatAPI.ts +315 -1
  28. package/Server/API/DashboardAPI.ts +217 -1
  29. package/Server/API/OnCallReadinessAPI.ts +841 -0
  30. package/Server/API/TeamComplianceAPI.ts +69 -17
  31. package/Server/API/TelemetryAPI.ts +220 -12
  32. package/Server/EnvironmentConfig.ts +52 -0
  33. package/Server/Infrastructure/Postgres/DataSourceOptions.ts +22 -0
  34. package/Server/Infrastructure/Postgres/SchemaMigrations/1786100000000-RestoreServiceLowerNameIndex.ts +4 -4
  35. package/Server/Infrastructure/Postgres/SchemaMigrations/1786200000000-RestoreDroppedUniqueIndexes.ts +5 -5
  36. package/Server/Infrastructure/Postgres/SchemaMigrations/1786625176831-AddMonitoringMethodToNetworkDevice.ts +35 -0
  37. package/Server/Infrastructure/Postgres/SchemaMigrations/1786634985763-AddNetworkDeviceLink.ts +82 -0
  38. package/Server/Infrastructure/Postgres/SchemaMigrations/1786639512056-AddNetworkDeviceLinkRule.ts +91 -0
  39. package/Server/Infrastructure/Postgres/SchemaMigrations/1786639972982-AddNetworkTopologySuppression.ts +47 -0
  40. package/Server/Infrastructure/Postgres/SchemaMigrations/1786800000000-RenameTelemetryEntityToInventoryItem.ts +255 -0
  41. package/Server/Infrastructure/Postgres/SchemaMigrations/1786900000000-AddInventoryItemArchiveAndCustomFields.ts +107 -0
  42. package/Server/Infrastructure/Postgres/SchemaMigrations/1787000000000-AddOnCallNotificationFallbackColumns.ts +90 -0
  43. package/Server/Infrastructure/Postgres/SchemaMigrations/1787100000000-AddAIConversationPageContext.ts +39 -0
  44. package/Server/Infrastructure/Postgres/SchemaMigrations/1787200000000-AddAIChatMessageFeedback.ts +33 -0
  45. package/Server/Infrastructure/Postgres/SchemaMigrations/1787300000000-AddEpisodeMemberNotifyIndexes.ts +59 -0
  46. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +20 -0
  47. package/Server/Infrastructure/Queue.ts +78 -13
  48. package/Server/Middleware/PublicDashboardRateLimit.ts +593 -0
  49. package/Server/Services/AIService.ts +7 -0
  50. package/Server/Services/AlertEpisodeStateTimelineService.ts +29 -0
  51. package/Server/Services/AlertSeverityService.ts +63 -0
  52. package/Server/Services/DashboardService.ts +9 -10
  53. package/Server/Services/DatabaseService.ts +32 -2
  54. package/Server/Services/IncidentEpisodeStateTimelineService.ts +29 -0
  55. package/Server/Services/IncidentSeverityService.ts +76 -0
  56. package/Server/Services/Index.ts +12 -4
  57. package/Server/Services/InventoryItemCustomFieldService.ts +9 -0
  58. package/Server/Services/{TelemetryEntityRelationshipService.ts → InventoryItemRelationshipService.ts} +4 -4
  59. package/Server/Services/{TelemetryEntityService.ts → InventoryItemService.ts} +89 -20
  60. package/Server/Services/LogAggregationService.ts +45 -8
  61. package/Server/Services/MetricAggregationService.ts +121 -0
  62. package/Server/Services/MetricService.ts +7 -7
  63. package/Server/Services/NetworkDeviceLinkRuleService.ts +10 -0
  64. package/Server/Services/NetworkDeviceLinkService.ts +84 -0
  65. package/Server/Services/NetworkDeviceService.ts +140 -0
  66. package/Server/Services/NetworkSiteService.ts +77 -25
  67. package/Server/Services/NetworkTopologySuppressionService.ts +84 -0
  68. package/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.ts +41 -29
  69. package/Server/Services/OnCallDutyPolicyExecutionLogService.ts +8 -0
  70. package/Server/Services/OnCallDutyPolicyExecutionLogTimelineService.ts +62 -13
  71. package/Server/Services/OnCallDutyPolicyScheduleService.ts +61 -1
  72. package/Server/Services/OnCallNotificationAlertingService.ts +742 -0
  73. package/Server/Services/OnCallReadinessService.ts +2803 -0
  74. package/Server/Services/OnCallSetupReminderService.ts +955 -0
  75. package/Server/Services/ProfileAggregationService.ts +123 -0
  76. package/Server/Services/StatusPageService.ts +9 -10
  77. package/Server/Services/TeamComplianceService.ts +429 -252
  78. package/Server/Services/UserCallService.ts +26 -1
  79. package/Server/Services/UserEmailService.ts +26 -1
  80. package/Server/Services/UserNotificationRuleAdminService.ts +1183 -0
  81. package/Server/Services/UserNotificationRuleService.ts +3812 -333
  82. package/Server/Services/UserOnCallLogService.ts +561 -48
  83. package/Server/Services/UserPushService.ts +29 -0
  84. package/Server/Services/UserService.ts +11 -0
  85. package/Server/Services/UserSmsService.ts +26 -1
  86. package/Server/Services/UserTelegramService.ts +24 -1
  87. package/Server/Services/UserWebhookService.ts +28 -1
  88. package/Server/Services/UserWhatsAppService.ts +24 -1
  89. package/Server/Types/Database/Permissions/BasePermission.ts +19 -0
  90. package/Server/Types/Database/Permissions/CreatePermission.ts +164 -0
  91. package/Server/Types/Database/Permissions/OwnerOnlyColumnPermission.ts +340 -0
  92. package/Server/Types/Database/Permissions/QueryPermission.ts +48 -0
  93. package/Server/Types/Database/Permissions/TenantPermission.ts +8 -1
  94. package/Server/Types/Workflow/Components/API/Delete.ts +1 -1
  95. package/Server/Types/Workflow/Components/API/Get.ts +1 -1
  96. package/Server/Types/Workflow/Components/API/Patch.ts +1 -1
  97. package/Server/Types/Workflow/Components/API/Post.ts +1 -1
  98. package/Server/Types/Workflow/Components/API/Put.ts +1 -1
  99. package/Server/Types/Workflow/Components/BaseModel/CreateManyBaseModel.ts +29 -5
  100. package/Server/Types/Workflow/Components/BaseModel/CreateOneBaseModel.ts +18 -10
  101. package/Server/Types/Workflow/Components/BaseModel/ModelArguments.ts +55 -0
  102. package/Server/Types/Workflow/Components/Conditions/IfElse.ts +3 -17
  103. package/Server/Types/Workflow/Components/Email.ts +25 -7
  104. package/Server/Types/Workflow/Components/JavaScript.ts +10 -3
  105. package/Server/Types/Workflow/Components/MicrosoftTeams/SendMessageToChannel.ts +1 -1
  106. package/Server/Utils/AI/Chat/ChatAgentRunner.ts +643 -48
  107. package/Server/Utils/AI/Chat/ObservabilityAssistant.ts +32 -3
  108. package/Server/Utils/AI/Chat/ObservabilityChatPrompt.ts +20 -6
  109. package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +7 -0
  110. package/Server/Utils/AI/Toolbox/AIActionTools.ts +2 -2
  111. package/Server/Utils/AI/Toolbox/AIMetaTools.ts +863 -0
  112. package/Server/Utils/AI/Toolbox/AlertTools.ts +177 -15
  113. package/Server/Utils/AI/Toolbox/IncidentTools.ts +191 -10
  114. package/Server/Utils/AI/Toolbox/Index.ts +48 -0
  115. package/Server/Utils/AI/Toolbox/MonitorTools.ts +298 -11
  116. package/Server/Utils/AI/Toolbox/NoteWriteTools.ts +295 -0
  117. package/Server/Utils/AI/Toolbox/OnCallTools.ts +1246 -0
  118. package/Server/Utils/AI/Toolbox/RunbookTools.ts +424 -0
  119. package/Server/Utils/AI/Toolbox/SloTools.ts +456 -0
  120. package/Server/Utils/AI/Toolbox/StatusPageTools.ts +559 -0
  121. package/Server/Utils/AI/Toolbox/TeamTools.ts +327 -0
  122. package/Server/Utils/AI/Toolbox/TimelineTools.ts +615 -0
  123. package/Server/Utils/AI/Toolbox/WorkflowProbeTools.ts +664 -0
  124. package/Server/Utils/ClientIp.ts +221 -0
  125. package/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.ts +47 -0
  126. package/Server/Utils/Dashboard/PublicDashboardSloHistoryPolicy.ts +163 -0
  127. package/Server/Utils/Dashboard/PublicDashboardSloWidget.ts +147 -0
  128. package/Server/Utils/Express.ts +12 -17
  129. package/Server/Utils/LLM/LLMService.ts +85 -8
  130. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +204 -10
  131. package/Server/Utils/SSRFProtection.ts +98 -23
  132. package/Server/Utils/StartServer.ts +12 -3
  133. package/Server/Utils/Telemetry/EntityRegistry.ts +205 -18
  134. package/Server/Utils/Telemetry/InventoryEntityRegistry.ts +25 -25
  135. package/Server/Utils/Telemetry/TelemetryEntity.ts +160 -52
  136. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +7 -3
  137. package/Tests/App/Dashboard/AdminNotificationRulesPage.test.tsx +2146 -0
  138. package/Tests/App/Dashboard/CreateWorkflowModal.test.tsx +561 -0
  139. package/Tests/App/Dashboard/EscalationRuleReadiness.test.tsx +2470 -0
  140. package/Tests/App/Dashboard/OnCallPreventionGuards.test.tsx +1897 -0
  141. package/Tests/App/Dashboard/OnCallReadinessSurfaces.test.tsx +3606 -0
  142. package/Tests/App/Dashboard/OnCallRulesDeleteGuard.test.tsx +784 -0
  143. package/Tests/App/Dashboard/OnCallRulesTable.test.tsx +1119 -0
  144. package/Tests/App/Dashboard/SloWidgetFetching.test.tsx +531 -0
  145. package/Tests/App/Dashboard/UserSettingsSetupChecklistModel.test.ts +1312 -0
  146. package/Tests/App/Dashboard/UserSettingsSetupChecklistPage.test.tsx +1390 -0
  147. package/Tests/Models/InventoryItemModel.test.ts +174 -0
  148. package/Tests/Models/InventoryItemNaming.test.ts +302 -0
  149. package/Tests/Server/API/AIChatCancelAndFeedback.test.ts +437 -0
  150. package/Tests/Server/API/DashboardPublicRateLimit.test.ts +659 -0
  151. package/Tests/Server/API/DashboardPublicResourceListAPI.test.ts +18 -0
  152. package/Tests/Server/API/DashboardPublicSloAPI.test.ts +880 -0
  153. package/Tests/Server/API/Helpers.ts +24 -15
  154. package/Tests/Server/API/OnCallReadinessAPI.test.ts +2680 -0
  155. package/Tests/Server/API/OnCallSetupReminderAPI.test.ts +915 -0
  156. package/Tests/Server/Infrastructure/Postgres/EpisodeMemberNotifyIndexesMigration.test.ts +533 -0
  157. package/Tests/Server/Infrastructure/Postgres/InventoryItemArchiveMigration.test.ts +213 -0
  158. package/Tests/Server/Infrastructure/Postgres/RenameInventoryItemMigration.test.ts +432 -0
  159. package/Tests/Server/Infrastructure/Queue.test.ts +293 -0
  160. package/Tests/Server/Middleware/PublicDashboardRateLimit.test.ts +1645 -0
  161. package/Tests/Server/Services/AdminRuleEditGuards.test.ts +2848 -0
  162. package/Tests/Server/Services/DeliverNotificationForRuleExtraction.test.ts +1393 -0
  163. package/Tests/Server/Services/EpisodeRuleSeverityRepair.test.ts +1802 -0
  164. package/Tests/Server/Services/EpisodeStateTimelineNote.test.ts +304 -0
  165. package/Tests/Server/Services/InventoryItemDisplayName.test.ts +339 -0
  166. package/Tests/Server/Services/{TelemetryEntityManualCreate.test.ts → InventoryItemManualCreate.test.ts} +27 -27
  167. package/Tests/Server/Services/IpAllowlistSpoofing.test.ts +450 -0
  168. package/Tests/Server/Services/LogAggregationService.test.ts +235 -1
  169. package/Tests/Server/Services/MetricAggregationService.test.ts +231 -0
  170. package/Tests/Server/Services/MetricEntityMVKeyParity.test.ts +80 -29
  171. package/Tests/Server/Services/MetricServiceAggregate.test.ts +30 -30
  172. package/Tests/Server/Services/NetworkSiteService.test.ts +18 -3
  173. package/Tests/Server/Services/NotificationChannelEventCoverage.test.ts +1728 -0
  174. package/Tests/Server/Services/NotificationDeletionImpact.test.ts +2402 -0
  175. package/Tests/Server/Services/OnCallDutyPolicyExecutionLogTimelineGapFeed.test.ts +394 -0
  176. package/Tests/Server/Services/OnCallNotificationFallback.test.ts +1744 -0
  177. package/Tests/Server/Services/OnCallReadinessService.test.ts +4295 -0
  178. package/Tests/Server/Services/OnCallSetupReminder.test.ts +1272 -0
  179. package/Tests/Server/Services/OnCallWeeklyReadinessDigest.test.ts +1021 -0
  180. package/Tests/Server/Services/ProfileAggregationService.test.ts +296 -0
  181. package/Tests/Server/Services/SeverityCreationRuleBackfill.test.ts +1536 -0
  182. package/Tests/Server/Services/SeverityRuleBackfill.test.ts +1818 -0
  183. package/Tests/Server/Services/TeamComplianceServiceBehaviour.test.ts +1845 -0
  184. package/Tests/Server/Services/UserNotificationRuleAdminGuards.test.ts +1394 -0
  185. package/Tests/Server/Services/UserNotificationRuleDefaultCreation.test.ts +1166 -0
  186. package/Tests/Server/Services/UserNotificationRuleExecuteItem.test.ts +1468 -0
  187. package/Tests/Server/Services/UserOnCallLogNoNotificationRules.test.ts +1457 -0
  188. package/Tests/Server/Types/Database/Permissions/AdminNotificationRuleAccess.test.ts +1546 -0
  189. package/Tests/Server/Types/Database/Permissions/CreateOwnershipScoping.test.ts +529 -0
  190. package/Tests/Server/Types/Database/Permissions/OwnerOnlyColumns.test.ts +1219 -0
  191. package/Tests/Server/Types/Database/Permissions/UserNotificationRuleScoping.test.ts +1089 -0
  192. package/Tests/Server/Types/Workflow/Components/ApiComponentErrorPort.test.ts +2 -1
  193. package/Tests/Server/Types/Workflow/Components/BaseModelDatabaseComponents.test.ts +190 -0
  194. package/Tests/Server/Types/Workflow/Components/ChatWebhookComponents.test.ts +44 -14
  195. package/Tests/Server/Types/Workflow/Components/Email.test.ts +151 -0
  196. package/Tests/Server/Types/Workflow/Components/IfElse.test.ts +98 -0
  197. package/Tests/Server/Types/Workflow/Components/JavaScript.test.ts +51 -0
  198. package/Tests/Server/Utils/AI/AIMetaTools.test.ts +586 -0
  199. package/Tests/Server/Utils/AI/AlertMonitorFilters.test.ts +582 -0
  200. package/Tests/Server/Utils/AI/ChatAgentRunner.test.ts +726 -0
  201. package/Tests/Server/Utils/AI/IncidentToolsFilters.test.ts +315 -0
  202. package/Tests/Server/Utils/AI/LLMServiceStopReason.test.ts +314 -0
  203. package/Tests/Server/Utils/AI/LLMServiceToolCalling.test.ts +26 -3
  204. package/Tests/Server/Utils/AI/NoteWriteTools.test.ts +268 -0
  205. package/Tests/Server/Utils/AI/ObservabilityChatPrompt.test.ts +169 -0
  206. package/Tests/Server/Utils/AI/OnCallTools.test.ts +664 -0
  207. package/Tests/Server/Utils/AI/RunbookTools.test.ts +325 -0
  208. package/Tests/Server/Utils/AI/SloTools.test.ts +306 -0
  209. package/Tests/Server/Utils/AI/StatusPageTools.test.ts +391 -0
  210. package/Tests/Server/Utils/AI/TeamTools.test.ts +257 -0
  211. package/Tests/Server/Utils/AI/TimelineTools.test.ts +472 -0
  212. package/Tests/Server/Utils/AI/WorkflowProbeTools.test.ts +428 -0
  213. package/Tests/Server/Utils/ClientIp.test.ts +438 -0
  214. package/Tests/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.test.ts +171 -0
  215. package/Tests/Server/Utils/Dashboard/PublicDashboardSloHistoryPolicy.test.ts +383 -0
  216. package/Tests/Server/Utils/EntityRegistryRowFence.test.ts +23 -25
  217. package/Tests/Server/Utils/MicrosoftTeamsWebhookUrlValidation.test.ts +6 -0
  218. package/Tests/Server/Utils/Monitor/Criteria/DnssecMonitorCriteria.test.ts +307 -0
  219. package/Tests/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.test.ts +468 -0
  220. package/Tests/Server/Utils/Monitor/MonitorCriteriaEvaluatorTelemetryDeepLinks.test.ts +460 -0
  221. package/Tests/Server/Utils/ResponseRateLimitStatusCodes.test.ts +137 -0
  222. package/Tests/Server/Utils/SSRFProtectionBypasses.test.ts +40 -8
  223. package/Tests/Server/Utils/SSRFProtectionUserInfo.test.ts +351 -0
  224. package/Tests/Server/Utils/Telemetry/EntityRegistryRetirement.test.ts +531 -0
  225. package/Tests/Server/Utils/Telemetry/InventoryEntityRegistry.test.ts +15 -15
  226. package/Tests/Server/Utils/Telemetry/TelemetryEntity.test.ts +356 -39
  227. package/Tests/Types/IP/IP.test.ts +263 -0
  228. package/Tests/Types/IP/IPWhitelist.test.ts +197 -0
  229. package/Tests/Types/IP/IPv6.test.ts +12 -1
  230. package/Tests/Types/Monitor/SnmpOid.test.ts +64 -0
  231. package/Tests/Types/NetworkDevice/NetworkDeviceMonitoringMethod.test.ts +110 -0
  232. package/Tests/Types/OnCallDutyPolicy/LayerUtilMergeAudit.test.ts +106 -0
  233. package/Tests/Types/OnCallDutyPolicy/LayerUtilMergeDifferential.test.ts +511 -0
  234. package/Tests/Types/OnCallDutyPolicy/ScheduleCoverageEndToEnd.test.ts +489 -0
  235. package/Tests/Types/OnCallDutyPolicy/ScheduleCoverageGapTolerance.test.ts +479 -0
  236. package/Tests/Types/OnCallDutyPolicy/ScheduleCoverageState.test.ts +822 -0
  237. package/Tests/Types/Telemetry/EntityTypeGroups.test.ts +6 -6
  238. package/Tests/Types/Workflow/BaseModelComponents.test.ts +429 -0
  239. package/Tests/Types/Workflow/Components/BaseModel.test.ts +225 -0
  240. package/Tests/Types/Workflow/IntegrationCredentialMetadata.test.ts +100 -0
  241. package/Tests/Types/Workflow/TemplateSyntax.test.ts +112 -0
  242. package/Tests/Types/Workflow/Templates.test.ts +916 -101
  243. package/Tests/UI/Components/ActiveFilterChipsOpenRoute.test.tsx +82 -0
  244. package/Tests/UI/Components/ComponentsModal.test.tsx +564 -7
  245. package/Tests/UI/Components/KeyboardShortcut.test.tsx +95 -0
  246. package/Tests/UI/Components/LogDetailsPanelCrossSignal.test.tsx +448 -0
  247. package/Tests/UI/Components/LogsTableCrossLinks.test.tsx +263 -0
  248. package/Tests/UI/Components/PendingProjectInvitations.test.tsx +913 -0
  249. package/Tests/UI/Components/SimpleLogViewer.test.tsx +228 -0
  250. package/Tests/UI/Components/TableRowSelectability.test.tsx +312 -0
  251. package/Tests/UI/Components/Workflow/GraphLint.test.ts +72 -0
  252. package/Tests/UI/Components/Workflow/GraphLintSummary.test.ts +755 -0
  253. package/Tests/UI/Components/Workflow/ModelColumnEditor.test.ts +242 -7
  254. package/Tests/UI/Components/Workflow/ModelColumnEditorServerContract.test.ts +15 -7
  255. package/Tests/UI/Components/Workflow/ModelSchema.test.ts +242 -28
  256. package/Tests/UI/Components/Workflow/RunStatusWatcher.test.ts +59 -1
  257. package/Tests/UI/Components/Workflow/StepTraceViewer.test.tsx +256 -0
  258. package/Tests/UI/Components/Workflow/UseRunWatch.test.tsx +665 -0
  259. package/Tests/UI/Components/Workflow/WorkflowIssuesModal.test.tsx +485 -0
  260. package/Tests/UI/Components/Workflow/WorkflowLogModal.test.tsx +478 -0
  261. package/Tests/UI/Components/Workflow/WorkflowStatusBar.test.tsx +379 -0
  262. package/Tests/UI/EsbuildConfig.test.ts +607 -0
  263. package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +5 -0
  264. package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +11 -4
  265. package/Tests/UI/Utils/ModelAPICreateMiscData.test.ts +94 -0
  266. package/Tests/UI/Utils/Platform.test.ts +147 -0
  267. package/Tests/UI/Utils/ProjectInvitationDisplay.test.ts +357 -0
  268. package/Tests/Utils/Monitor/NetworkDeviceLinkRuleUtil.test.ts +198 -0
  269. package/Tests/Utils/Monitor/NetworkTopologyUtil.test.ts +487 -0
  270. package/Tests/Utils/Telemetry/CrossSignalScope.test.ts +698 -0
  271. package/Tests/__mocks__/bullmq.js +55 -0
  272. package/Types/AI/AIChatMessageStatus.ts +8 -1
  273. package/Types/AI/AIChatTypes.ts +12 -0
  274. package/Types/Database/AccessControl/OwnerOnlyColumn.ts +88 -0
  275. package/Types/Exception/ExceptionCode.ts +2 -0
  276. package/Types/Exception/ServiceUnavailableException.ts +8 -0
  277. package/Types/Exception/TooManyRequestsException.ts +8 -0
  278. package/Types/IP/IP.ts +93 -47
  279. package/Types/Monitor/SnmpMonitor/NetworkTopology.ts +49 -3
  280. package/Types/NetworkDevice/NetworkDeviceMonitoringMethod.ts +55 -0
  281. package/Types/OnCallDutyPolicy/Layer.ts +203 -149
  282. package/Types/OnCallDutyPolicy/OnCallDutyPolicyStatus.ts +13 -0
  283. package/Types/OnCallDutyPolicy/ScheduleShiftUtil.ts +155 -10
  284. package/Types/Permission.ts +193 -0
  285. package/Types/Telemetry/EntityRelationshipType.ts +1 -1
  286. package/Types/Telemetry/EntitySource.ts +1 -1
  287. package/Types/Telemetry/EntityType.ts +1 -1
  288. package/Types/Telemetry/EntityTypeGroups.ts +1 -1
  289. package/Types/Workflow/Components/BaseModel.ts +75 -29
  290. package/Types/Workflow/Components/Discord.ts +1 -0
  291. package/Types/Workflow/Components/Email.ts +12 -3
  292. package/Types/Workflow/Components/JavaScript.ts +7 -0
  293. package/Types/Workflow/Components/MicrosoftTeams.ts +3 -2
  294. package/Types/Workflow/Components/Slack.ts +1 -0
  295. package/Types/Workflow/Components/Telegram.ts +1 -0
  296. package/Types/Workflow/TemplateSyntax.ts +44 -0
  297. package/Types/Workflow/Templates.ts +2097 -45
  298. package/UI/Components/Calendar/Calendar.css +43 -0
  299. package/UI/Components/Calendar/Calendar.tsx +8 -0
  300. package/UI/Components/Card/Card.tsx +2 -2
  301. package/UI/Components/Checkbox/Checkbox.tsx +16 -0
  302. package/UI/Components/Dictionary/Dictionary.tsx +48 -9
  303. package/UI/Components/FormModal/BasicFormModal.tsx +2 -1
  304. package/UI/Components/Header/HeaderIconDropdownButton.tsx +53 -3
  305. package/UI/Components/Input/Input.tsx +1 -0
  306. package/UI/Components/KeyboardShortcut/KeyboardKey.ts +185 -0
  307. package/UI/Components/KeyboardShortcut/KeyboardShortcut.tsx +87 -0
  308. package/UI/Components/LogsViewer/LogsViewer.tsx +28 -0
  309. package/UI/Components/LogsViewer/components/ActiveFilterChips.tsx +31 -0
  310. package/UI/Components/LogsViewer/components/KeyboardShortcutsHelp.tsx +18 -18
  311. package/UI/Components/LogsViewer/components/LogDetailsPanel.tsx +363 -14
  312. package/UI/Components/LogsViewer/components/LogsAnalyticsView.tsx +11 -0
  313. package/UI/Components/LogsViewer/components/LogsTable.tsx +155 -12
  314. package/UI/Components/LogsViewer/components/LogsViewerToolbar.tsx +29 -0
  315. package/UI/Components/LogsViewer/types.ts +23 -0
  316. package/UI/Components/Markdown.tsx/MarkdownEditor.tsx +9 -2
  317. package/UI/Components/Navbar/NavBarMenuModal.tsx +15 -30
  318. package/UI/Components/ProjectInvitations/PendingProjectInvitations.tsx +442 -0
  319. package/UI/Components/SimpleLogViewer/SimpleLogViewer.tsx +23 -1
  320. package/UI/Components/Table/Table.tsx +49 -16
  321. package/UI/Components/Table/TableBody.tsx +53 -28
  322. package/UI/Components/Table/TableHeader.tsx +13 -0
  323. package/UI/Components/Table/TableRow.tsx +58 -26
  324. package/UI/Components/Workflow/ArgumentsForm.tsx +155 -9
  325. package/UI/Components/Workflow/ComponentReturnValueViewer.tsx +26 -0
  326. package/UI/Components/Workflow/ComponentSettingsModal.tsx +10 -1
  327. package/UI/Components/Workflow/ComponentValuePickerModal.tsx +135 -7
  328. package/UI/Components/Workflow/ComponentsModal.tsx +116 -22
  329. package/UI/Components/Workflow/DocumentationViewer.tsx +59 -9
  330. package/UI/Components/Workflow/GraphLint.ts +42 -5
  331. package/UI/Components/Workflow/GraphLintSummary.ts +390 -0
  332. package/UI/Components/Workflow/ModelColumnEditor.tsx +154 -22
  333. package/UI/Components/Workflow/ModelSchema.ts +115 -33
  334. package/UI/Components/Workflow/RunStatusWatcher.ts +1 -1
  335. package/UI/Components/Workflow/StepTraceViewer.tsx +1 -1
  336. package/UI/Components/Workflow/UseRunWatch.ts +212 -0
  337. package/UI/Components/Workflow/VariableModal.tsx +6 -2
  338. package/UI/Components/Workflow/Workflow.tsx +49 -3
  339. package/UI/Components/Workflow/WorkflowIssuesModal.tsx +255 -0
  340. package/UI/Components/Workflow/WorkflowLogModal.tsx +128 -0
  341. package/UI/Components/Workflow/WorkflowStatusBar.tsx +224 -0
  342. package/UI/Utils/AIChatExport/ConversationMarkdown.ts +10 -0
  343. package/UI/Utils/ModelAPI/ModelAPI.ts +7 -1
  344. package/UI/Utils/Platform.ts +149 -0
  345. package/UI/Utils/ProjectInvitationDisplay.ts +118 -0
  346. package/UI/esbuild-config.js +22 -1
  347. package/Utils/Monitor/NetworkDeviceLinkRuleUtil.ts +187 -0
  348. package/Utils/Monitor/NetworkTopologyUtil.ts +888 -164
  349. package/Utils/Telemetry/CrossSignalScope.ts +502 -0
  350. package/Utils/Telemetry/EntityKey.ts +5 -5
  351. package/Utils/Telemetry/EntityRelationship.ts +1 -1
  352. package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByK8sCluster.js +1 -1
  353. package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByService.js +1 -1
  354. package/build/dist/Models/DatabaseModels/AIConversation.js +32 -0
  355. package/build/dist/Models/DatabaseModels/AIConversation.js.map +1 -1
  356. package/build/dist/Models/DatabaseModels/AIConversationMessage.js +42 -0
  357. package/build/dist/Models/DatabaseModels/AIConversationMessage.js.map +1 -1
  358. package/build/dist/Models/DatabaseModels/AlertEpisodeMember.js +28 -0
  359. package/build/dist/Models/DatabaseModels/AlertEpisodeMember.js.map +1 -1
  360. package/build/dist/Models/DatabaseModels/IncidentEpisodeMember.js +29 -0
  361. package/build/dist/Models/DatabaseModels/IncidentEpisodeMember.js.map +1 -1
  362. package/build/dist/Models/DatabaseModels/Index.js +12 -4
  363. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  364. package/build/dist/Models/DatabaseModels/{TelemetryEntity.js → InventoryItem.js} +167 -31
  365. package/build/dist/Models/DatabaseModels/InventoryItem.js.map +1 -0
  366. package/build/dist/Models/DatabaseModels/InventoryItemCustomField.js +454 -0
  367. package/build/dist/Models/DatabaseModels/InventoryItemCustomField.js.map +1 -0
  368. package/build/dist/Models/DatabaseModels/{TelemetryEntityRelationship.js → InventoryItemRelationship.js} +27 -27
  369. package/build/dist/Models/DatabaseModels/InventoryItemRelationship.js.map +1 -0
  370. package/build/dist/Models/DatabaseModels/NetworkDevice.js +141 -0
  371. package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
  372. package/build/dist/Models/DatabaseModels/NetworkDeviceLink.js +719 -0
  373. package/build/dist/Models/DatabaseModels/NetworkDeviceLink.js.map +1 -0
  374. package/build/dist/Models/DatabaseModels/NetworkDeviceLinkRule.js +475 -0
  375. package/build/dist/Models/DatabaseModels/NetworkDeviceLinkRule.js.map +1 -0
  376. package/build/dist/Models/DatabaseModels/NetworkTopologySuppression.js +446 -0
  377. package/build/dist/Models/DatabaseModels/NetworkTopologySuppression.js.map +1 -0
  378. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyFeed.js +9 -0
  379. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyFeed.js.map +1 -1
  380. package/build/dist/Models/DatabaseModels/Project.js +80 -0
  381. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  382. package/build/dist/Models/DatabaseModels/UserCall.js +46 -2
  383. package/build/dist/Models/DatabaseModels/UserCall.js.map +1 -1
  384. package/build/dist/Models/DatabaseModels/UserEmail.js +48 -2
  385. package/build/dist/Models/DatabaseModels/UserEmail.js.map +1 -1
  386. package/build/dist/Models/DatabaseModels/UserNotificationRule.js +424 -55
  387. package/build/dist/Models/DatabaseModels/UserNotificationRule.js.map +1 -1
  388. package/build/dist/Models/DatabaseModels/UserOnCallLogTimeline.js +24 -2
  389. package/build/dist/Models/DatabaseModels/UserOnCallLogTimeline.js.map +1 -1
  390. package/build/dist/Models/DatabaseModels/UserPush.js +51 -1
  391. package/build/dist/Models/DatabaseModels/UserPush.js.map +1 -1
  392. package/build/dist/Models/DatabaseModels/UserSMS.js +47 -2
  393. package/build/dist/Models/DatabaseModels/UserSMS.js.map +1 -1
  394. package/build/dist/Models/DatabaseModels/UserTelegram.js +65 -3
  395. package/build/dist/Models/DatabaseModels/UserTelegram.js.map +1 -1
  396. package/build/dist/Models/DatabaseModels/UserWebhook.js +56 -2
  397. package/build/dist/Models/DatabaseModels/UserWebhook.js.map +1 -1
  398. package/build/dist/Models/DatabaseModels/UserWhatsApp.js +45 -2
  399. package/build/dist/Models/DatabaseModels/UserWhatsApp.js.map +1 -1
  400. package/build/dist/Models/DatabaseModels/WorkflowVariable.js +12 -0
  401. package/build/dist/Models/DatabaseModels/WorkflowVariable.js.map +1 -1
  402. package/build/dist/Server/API/AIChatAPI.js +237 -1
  403. package/build/dist/Server/API/AIChatAPI.js.map +1 -1
  404. package/build/dist/Server/API/DashboardAPI.js +165 -13
  405. package/build/dist/Server/API/DashboardAPI.js.map +1 -1
  406. package/build/dist/Server/API/OnCallReadinessAPI.js +599 -0
  407. package/build/dist/Server/API/OnCallReadinessAPI.js.map +1 -0
  408. package/build/dist/Server/API/TeamComplianceAPI.js +68 -9
  409. package/build/dist/Server/API/TeamComplianceAPI.js.map +1 -1
  410. package/build/dist/Server/API/TelemetryAPI.js +129 -18
  411. package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
  412. package/build/dist/Server/EnvironmentConfig.js +45 -0
  413. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  414. package/build/dist/Server/Infrastructure/Postgres/DataSourceOptions.js +22 -0
  415. package/build/dist/Server/Infrastructure/Postgres/DataSourceOptions.js.map +1 -1
  416. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786100000000-RestoreServiceLowerNameIndex.js +4 -4
  417. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786625176831-AddMonitoringMethodToNetworkDevice.js +18 -0
  418. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786625176831-AddMonitoringMethodToNetworkDevice.js.map +1 -0
  419. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786634985763-AddNetworkDeviceLink.js +39 -0
  420. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786634985763-AddNetworkDeviceLink.js.map +1 -0
  421. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786639512056-AddNetworkDeviceLinkRule.js +38 -0
  422. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786639512056-AddNetworkDeviceLinkRule.js.map +1 -0
  423. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786639972982-AddNetworkTopologySuppression.js +22 -0
  424. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786639972982-AddNetworkTopologySuppression.js.map +1 -0
  425. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786800000000-RenameTelemetryEntityToInventoryItem.js +150 -0
  426. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786800000000-RenameTelemetryEntityToInventoryItem.js.map +1 -0
  427. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786900000000-AddInventoryItemArchiveAndCustomFields.js +57 -0
  428. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786900000000-AddInventoryItemArchiveAndCustomFields.js.map +1 -0
  429. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787000000000-AddOnCallNotificationFallbackColumns.js +69 -0
  430. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787000000000-AddOnCallNotificationFallbackColumns.js.map +1 -0
  431. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787100000000-AddAIConversationPageContext.js +32 -0
  432. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787100000000-AddAIConversationPageContext.js.map +1 -0
  433. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787200000000-AddAIChatMessageFeedback.js +26 -0
  434. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787200000000-AddAIChatMessageFeedback.js.map +1 -0
  435. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787300000000-AddEpisodeMemberNotifyIndexes.js +48 -0
  436. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787300000000-AddEpisodeMemberNotifyIndexes.js.map +1 -0
  437. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +20 -0
  438. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  439. package/build/dist/Server/Infrastructure/Queue.js +72 -13
  440. package/build/dist/Server/Infrastructure/Queue.js.map +1 -1
  441. package/build/dist/Server/Middleware/PublicDashboardRateLimit.js +399 -0
  442. package/build/dist/Server/Middleware/PublicDashboardRateLimit.js.map +1 -0
  443. package/build/dist/Server/Services/AIService.js +1 -0
  444. package/build/dist/Server/Services/AIService.js.map +1 -1
  445. package/build/dist/Server/Services/AlertEpisodeStateTimelineService.js +24 -3
  446. package/build/dist/Server/Services/AlertEpisodeStateTimelineService.js.map +1 -1
  447. package/build/dist/Server/Services/AlertSeverityService.js +54 -0
  448. package/build/dist/Server/Services/AlertSeverityService.js.map +1 -1
  449. package/build/dist/Server/Services/DashboardService.js +10 -9
  450. package/build/dist/Server/Services/DashboardService.js.map +1 -1
  451. package/build/dist/Server/Services/DatabaseService.js +24 -2
  452. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  453. package/build/dist/Server/Services/IncidentEpisodeStateTimelineService.js +24 -3
  454. package/build/dist/Server/Services/IncidentEpisodeStateTimelineService.js.map +1 -1
  455. package/build/dist/Server/Services/IncidentSeverityService.js +67 -0
  456. package/build/dist/Server/Services/IncidentSeverityService.js.map +1 -1
  457. package/build/dist/Server/Services/Index.js +12 -4
  458. package/build/dist/Server/Services/Index.js.map +1 -1
  459. package/build/dist/Server/Services/InventoryItemCustomFieldService.js +9 -0
  460. package/build/dist/Server/Services/InventoryItemCustomFieldService.js.map +1 -0
  461. package/build/dist/Server/Services/{TelemetryEntityRelationshipService.js → InventoryItemRelationshipService.js} +6 -6
  462. package/build/dist/Server/Services/InventoryItemRelationshipService.js.map +1 -0
  463. package/build/dist/Server/Services/{TelemetryEntityService.js → InventoryItemService.js} +68 -23
  464. package/build/dist/Server/Services/InventoryItemService.js.map +1 -0
  465. package/build/dist/Server/Services/LogAggregationService.js +27 -8
  466. package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
  467. package/build/dist/Server/Services/MetricAggregationService.js +80 -0
  468. package/build/dist/Server/Services/MetricAggregationService.js.map +1 -1
  469. package/build/dist/Server/Services/MetricService.js +6 -6
  470. package/build/dist/Server/Services/MetricService.js.map +1 -1
  471. package/build/dist/Server/Services/NetworkDeviceLinkRuleService.js +9 -0
  472. package/build/dist/Server/Services/NetworkDeviceLinkRuleService.js.map +1 -0
  473. package/build/dist/Server/Services/NetworkDeviceLinkService.js +71 -0
  474. package/build/dist/Server/Services/NetworkDeviceLinkService.js.map +1 -0
  475. package/build/dist/Server/Services/NetworkDeviceService.js +113 -0
  476. package/build/dist/Server/Services/NetworkDeviceService.js.map +1 -1
  477. package/build/dist/Server/Services/NetworkSiteService.js +53 -13
  478. package/build/dist/Server/Services/NetworkSiteService.js.map +1 -1
  479. package/build/dist/Server/Services/NetworkTopologySuppressionService.js +85 -0
  480. package/build/dist/Server/Services/NetworkTopologySuppressionService.js.map +1 -0
  481. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js +48 -32
  482. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js.map +1 -1
  483. package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogService.js +8 -0
  484. package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogService.js.map +1 -1
  485. package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogTimelineService.js +51 -12
  486. package/build/dist/Server/Services/OnCallDutyPolicyExecutionLogTimelineService.js.map +1 -1
  487. package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js +57 -13
  488. package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js.map +1 -1
  489. package/build/dist/Server/Services/OnCallNotificationAlertingService.js +548 -0
  490. package/build/dist/Server/Services/OnCallNotificationAlertingService.js.map +1 -0
  491. package/build/dist/Server/Services/OnCallReadinessService.js +1961 -0
  492. package/build/dist/Server/Services/OnCallReadinessService.js.map +1 -0
  493. package/build/dist/Server/Services/OnCallSetupReminderService.js +738 -0
  494. package/build/dist/Server/Services/OnCallSetupReminderService.js.map +1 -0
  495. package/build/dist/Server/Services/ProfileAggregationService.js +68 -4
  496. package/build/dist/Server/Services/ProfileAggregationService.js.map +1 -1
  497. package/build/dist/Server/Services/StatusPageService.js +11 -10
  498. package/build/dist/Server/Services/StatusPageService.js.map +1 -1
  499. package/build/dist/Server/Services/TeamComplianceService.js +312 -160
  500. package/build/dist/Server/Services/TeamComplianceService.js.map +1 -1
  501. package/build/dist/Server/Services/UserCallService.js +24 -1
  502. package/build/dist/Server/Services/UserCallService.js.map +1 -1
  503. package/build/dist/Server/Services/UserEmailService.js +24 -1
  504. package/build/dist/Server/Services/UserEmailService.js.map +1 -1
  505. package/build/dist/Server/Services/UserNotificationRuleAdminService.js +858 -0
  506. package/build/dist/Server/Services/UserNotificationRuleAdminService.js.map +1 -0
  507. package/build/dist/Server/Services/UserNotificationRuleService.js +2830 -175
  508. package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
  509. package/build/dist/Server/Services/UserOnCallLogService.js +488 -43
  510. package/build/dist/Server/Services/UserOnCallLogService.js.map +1 -1
  511. package/build/dist/Server/Services/UserPushService.js +26 -0
  512. package/build/dist/Server/Services/UserPushService.js.map +1 -1
  513. package/build/dist/Server/Services/UserService.js +10 -0
  514. package/build/dist/Server/Services/UserService.js.map +1 -1
  515. package/build/dist/Server/Services/UserSmsService.js +24 -1
  516. package/build/dist/Server/Services/UserSmsService.js.map +1 -1
  517. package/build/dist/Server/Services/UserTelegramService.js +22 -1
  518. package/build/dist/Server/Services/UserTelegramService.js.map +1 -1
  519. package/build/dist/Server/Services/UserWebhookService.js +25 -1
  520. package/build/dist/Server/Services/UserWebhookService.js.map +1 -1
  521. package/build/dist/Server/Services/UserWhatsAppService.js +22 -1
  522. package/build/dist/Server/Services/UserWhatsAppService.js.map +1 -1
  523. package/build/dist/Server/Types/Database/Permissions/BasePermission.js +12 -1
  524. package/build/dist/Server/Types/Database/Permissions/BasePermission.js.map +1 -1
  525. package/build/dist/Server/Types/Database/Permissions/CreatePermission.js +126 -0
  526. package/build/dist/Server/Types/Database/Permissions/CreatePermission.js.map +1 -1
  527. package/build/dist/Server/Types/Database/Permissions/OwnerOnlyColumnPermission.js +254 -0
  528. package/build/dist/Server/Types/Database/Permissions/OwnerOnlyColumnPermission.js.map +1 -0
  529. package/build/dist/Server/Types/Database/Permissions/QueryPermission.js +47 -2
  530. package/build/dist/Server/Types/Database/Permissions/QueryPermission.js.map +1 -1
  531. package/build/dist/Server/Types/Database/Permissions/TenantPermission.js +7 -0
  532. package/build/dist/Server/Types/Database/Permissions/TenantPermission.js.map +1 -1
  533. package/build/dist/Server/Types/Workflow/Components/API/Delete.js +1 -1
  534. package/build/dist/Server/Types/Workflow/Components/API/Delete.js.map +1 -1
  535. package/build/dist/Server/Types/Workflow/Components/API/Get.js +1 -1
  536. package/build/dist/Server/Types/Workflow/Components/API/Get.js.map +1 -1
  537. package/build/dist/Server/Types/Workflow/Components/API/Patch.js +1 -1
  538. package/build/dist/Server/Types/Workflow/Components/API/Patch.js.map +1 -1
  539. package/build/dist/Server/Types/Workflow/Components/API/Post.js +1 -1
  540. package/build/dist/Server/Types/Workflow/Components/API/Post.js.map +1 -1
  541. package/build/dist/Server/Types/Workflow/Components/API/Put.js +1 -1
  542. package/build/dist/Server/Types/Workflow/Components/API/Put.js.map +1 -1
  543. package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateManyBaseModel.js +21 -5
  544. package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateManyBaseModel.js.map +1 -1
  545. package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateOneBaseModel.js +14 -10
  546. package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateOneBaseModel.js.map +1 -1
  547. package/build/dist/Server/Types/Workflow/Components/BaseModel/ModelArguments.js +31 -0
  548. package/build/dist/Server/Types/Workflow/Components/BaseModel/ModelArguments.js.map +1 -1
  549. package/build/dist/Server/Types/Workflow/Components/Conditions/IfElse.js +3 -9
  550. package/build/dist/Server/Types/Workflow/Components/Conditions/IfElse.js.map +1 -1
  551. package/build/dist/Server/Types/Workflow/Components/Email.js +15 -4
  552. package/build/dist/Server/Types/Workflow/Components/Email.js.map +1 -1
  553. package/build/dist/Server/Types/Workflow/Components/JavaScript.js +7 -2
  554. package/build/dist/Server/Types/Workflow/Components/JavaScript.js.map +1 -1
  555. package/build/dist/Server/Types/Workflow/Components/MicrosoftTeams/SendMessageToChannel.js +1 -1
  556. package/build/dist/Server/Types/Workflow/Components/MicrosoftTeams/SendMessageToChannel.js.map +1 -1
  557. package/build/dist/Server/Utils/AI/Chat/ChatAgentRunner.js +514 -56
  558. package/build/dist/Server/Utils/AI/Chat/ChatAgentRunner.js.map +1 -1
  559. package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js +20 -3
  560. package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js.map +1 -1
  561. package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js +19 -6
  562. package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js.map +1 -1
  563. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +7 -0
  564. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
  565. package/build/dist/Server/Utils/AI/Toolbox/AIActionTools.js +2 -2
  566. package/build/dist/Server/Utils/AI/Toolbox/AIActionTools.js.map +1 -1
  567. package/build/dist/Server/Utils/AI/Toolbox/AIMetaTools.js +692 -0
  568. package/build/dist/Server/Utils/AI/Toolbox/AIMetaTools.js.map +1 -0
  569. package/build/dist/Server/Utils/AI/Toolbox/AlertTools.js +148 -12
  570. package/build/dist/Server/Utils/AI/Toolbox/AlertTools.js.map +1 -1
  571. package/build/dist/Server/Utils/AI/Toolbox/IncidentTools.js +157 -10
  572. package/build/dist/Server/Utils/AI/Toolbox/IncidentTools.js.map +1 -1
  573. package/build/dist/Server/Utils/AI/Toolbox/Index.js +37 -0
  574. package/build/dist/Server/Utils/AI/Toolbox/Index.js.map +1 -1
  575. package/build/dist/Server/Utils/AI/Toolbox/MonitorTools.js +259 -14
  576. package/build/dist/Server/Utils/AI/Toolbox/MonitorTools.js.map +1 -1
  577. package/build/dist/Server/Utils/AI/Toolbox/NoteWriteTools.js +235 -0
  578. package/build/dist/Server/Utils/AI/Toolbox/NoteWriteTools.js.map +1 -0
  579. package/build/dist/Server/Utils/AI/Toolbox/OnCallTools.js +1000 -0
  580. package/build/dist/Server/Utils/AI/Toolbox/OnCallTools.js.map +1 -0
  581. package/build/dist/Server/Utils/AI/Toolbox/RunbookTools.js +356 -0
  582. package/build/dist/Server/Utils/AI/Toolbox/RunbookTools.js.map +1 -0
  583. package/build/dist/Server/Utils/AI/Toolbox/SloTools.js +394 -0
  584. package/build/dist/Server/Utils/AI/Toolbox/SloTools.js.map +1 -0
  585. package/build/dist/Server/Utils/AI/Toolbox/StatusPageTools.js +465 -0
  586. package/build/dist/Server/Utils/AI/Toolbox/StatusPageTools.js.map +1 -0
  587. package/build/dist/Server/Utils/AI/Toolbox/TeamTools.js +280 -0
  588. package/build/dist/Server/Utils/AI/Toolbox/TeamTools.js.map +1 -0
  589. package/build/dist/Server/Utils/AI/Toolbox/TimelineTools.js +527 -0
  590. package/build/dist/Server/Utils/AI/Toolbox/TimelineTools.js.map +1 -0
  591. package/build/dist/Server/Utils/AI/Toolbox/WorkflowProbeTools.js +548 -0
  592. package/build/dist/Server/Utils/AI/Toolbox/WorkflowProbeTools.js.map +1 -0
  593. package/build/dist/Server/Utils/ClientIp.js +137 -0
  594. package/build/dist/Server/Utils/ClientIp.js.map +1 -0
  595. package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js +38 -0
  596. package/build/dist/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.js.map +1 -1
  597. package/build/dist/Server/Utils/Dashboard/PublicDashboardSloHistoryPolicy.js +89 -0
  598. package/build/dist/Server/Utils/Dashboard/PublicDashboardSloHistoryPolicy.js.map +1 -0
  599. package/build/dist/Server/Utils/Dashboard/PublicDashboardSloWidget.js +77 -0
  600. package/build/dist/Server/Utils/Dashboard/PublicDashboardSloWidget.js.map +1 -0
  601. package/build/dist/Server/Utils/Express.js +12 -12
  602. package/build/dist/Server/Utils/Express.js.map +1 -1
  603. package/build/dist/Server/Utils/LLM/LLMService.js +70 -7
  604. package/build/dist/Server/Utils/LLM/LLMService.js.map +1 -1
  605. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +121 -11
  606. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  607. package/build/dist/Server/Utils/SSRFProtection.js +82 -21
  608. package/build/dist/Server/Utils/SSRFProtection.js.map +1 -1
  609. package/build/dist/Server/Utils/StartServer.js +12 -4
  610. package/build/dist/Server/Utils/StartServer.js.map +1 -1
  611. package/build/dist/Server/Utils/Telemetry/EntityRegistry.js +165 -18
  612. package/build/dist/Server/Utils/Telemetry/EntityRegistry.js.map +1 -1
  613. package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js +11 -11
  614. package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js.map +1 -1
  615. package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js +122 -47
  616. package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js.map +1 -1
  617. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +7 -3
  618. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
  619. package/build/dist/Types/AI/AIChatMessageStatus.js +8 -1
  620. package/build/dist/Types/AI/AIChatMessageStatus.js.map +1 -1
  621. package/build/dist/Types/AI/AIChatTypes.js +12 -0
  622. package/build/dist/Types/AI/AIChatTypes.js.map +1 -1
  623. package/build/dist/Types/Database/AccessControl/OwnerOnlyColumn.js +60 -0
  624. package/build/dist/Types/Database/AccessControl/OwnerOnlyColumn.js.map +1 -0
  625. package/build/dist/Types/Exception/ExceptionCode.js +2 -0
  626. package/build/dist/Types/Exception/ExceptionCode.js.map +1 -1
  627. package/build/dist/Types/Exception/ServiceUnavailableException.js +8 -0
  628. package/build/dist/Types/Exception/ServiceUnavailableException.js.map +1 -0
  629. package/build/dist/Types/Exception/TooManyRequestsException.js +8 -0
  630. package/build/dist/Types/Exception/TooManyRequestsException.js.map +1 -0
  631. package/build/dist/Types/IP/IP.js +87 -43
  632. package/build/dist/Types/IP/IP.js.map +1 -1
  633. package/build/dist/Types/NetworkDevice/NetworkDeviceMonitoringMethod.js +50 -0
  634. package/build/dist/Types/NetworkDevice/NetworkDeviceMonitoringMethod.js.map +1 -0
  635. package/build/dist/Types/OnCallDutyPolicy/Layer.js +186 -123
  636. package/build/dist/Types/OnCallDutyPolicy/Layer.js.map +1 -1
  637. package/build/dist/Types/OnCallDutyPolicy/OnCallDutyPolicyStatus.js +13 -0
  638. package/build/dist/Types/OnCallDutyPolicy/OnCallDutyPolicyStatus.js.map +1 -1
  639. package/build/dist/Types/OnCallDutyPolicy/ScheduleShiftUtil.js +105 -11
  640. package/build/dist/Types/OnCallDutyPolicy/ScheduleShiftUtil.js.map +1 -1
  641. package/build/dist/Types/Permission.js +174 -0
  642. package/build/dist/Types/Permission.js.map +1 -1
  643. package/build/dist/Types/Telemetry/EntityRelationshipType.js +1 -1
  644. package/build/dist/Types/Telemetry/EntitySource.js +1 -1
  645. package/build/dist/Types/Telemetry/EntityType.js +1 -1
  646. package/build/dist/Types/Telemetry/EntityTypeGroups.js +1 -1
  647. package/build/dist/Types/Telemetry/EntityTypeGroups.js.map +1 -1
  648. package/build/dist/Types/Workflow/Components/BaseModel.js +66 -28
  649. package/build/dist/Types/Workflow/Components/BaseModel.js.map +1 -1
  650. package/build/dist/Types/Workflow/Components/Discord.js +1 -0
  651. package/build/dist/Types/Workflow/Components/Discord.js.map +1 -1
  652. package/build/dist/Types/Workflow/Components/Email.js +12 -3
  653. package/build/dist/Types/Workflow/Components/Email.js.map +1 -1
  654. package/build/dist/Types/Workflow/Components/JavaScript.js +7 -0
  655. package/build/dist/Types/Workflow/Components/JavaScript.js.map +1 -1
  656. package/build/dist/Types/Workflow/Components/MicrosoftTeams.js +3 -2
  657. package/build/dist/Types/Workflow/Components/MicrosoftTeams.js.map +1 -1
  658. package/build/dist/Types/Workflow/Components/Slack.js +1 -0
  659. package/build/dist/Types/Workflow/Components/Slack.js.map +1 -1
  660. package/build/dist/Types/Workflow/Components/Telegram.js +1 -0
  661. package/build/dist/Types/Workflow/Components/Telegram.js.map +1 -1
  662. package/build/dist/Types/Workflow/TemplateSyntax.js +12 -0
  663. package/build/dist/Types/Workflow/TemplateSyntax.js.map +1 -1
  664. package/build/dist/Types/Workflow/Templates.js +1931 -38
  665. package/build/dist/Types/Workflow/Templates.js.map +1 -1
  666. package/build/dist/UI/Components/Calendar/Calendar.js +1 -1
  667. package/build/dist/UI/Components/Calendar/Calendar.js.map +1 -1
  668. package/build/dist/UI/Components/Checkbox/Checkbox.js +1 -1
  669. package/build/dist/UI/Components/Checkbox/Checkbox.js.map +1 -1
  670. package/build/dist/UI/Components/Dictionary/Dictionary.js +25 -11
  671. package/build/dist/UI/Components/Dictionary/Dictionary.js.map +1 -1
  672. package/build/dist/UI/Components/FormModal/BasicFormModal.js.map +1 -1
  673. package/build/dist/UI/Components/Header/HeaderIconDropdownButton.js +27 -4
  674. package/build/dist/UI/Components/Header/HeaderIconDropdownButton.js.map +1 -1
  675. package/build/dist/UI/Components/Input/Input.js +1 -0
  676. package/build/dist/UI/Components/Input/Input.js.map +1 -1
  677. package/build/dist/UI/Components/KeyboardShortcut/KeyboardKey.js +163 -0
  678. package/build/dist/UI/Components/KeyboardShortcut/KeyboardKey.js.map +1 -0
  679. package/build/dist/UI/Components/KeyboardShortcut/KeyboardShortcut.js +47 -0
  680. package/build/dist/UI/Components/KeyboardShortcut/KeyboardShortcut.js.map +1 -0
  681. package/build/dist/UI/Components/LogsViewer/LogsViewer.js +4 -4
  682. package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
  683. package/build/dist/UI/Components/LogsViewer/components/ActiveFilterChips.js +11 -1
  684. package/build/dist/UI/Components/LogsViewer/components/ActiveFilterChips.js.map +1 -1
  685. package/build/dist/UI/Components/LogsViewer/components/KeyboardShortcutsHelp.js +10 -8
  686. package/build/dist/UI/Components/LogsViewer/components/KeyboardShortcutsHelp.js.map +1 -1
  687. package/build/dist/UI/Components/LogsViewer/components/LogDetailsPanel.js +227 -14
  688. package/build/dist/UI/Components/LogsViewer/components/LogDetailsPanel.js.map +1 -1
  689. package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js +5 -0
  690. package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js.map +1 -1
  691. package/build/dist/UI/Components/LogsViewer/components/LogsTable.js +69 -5
  692. package/build/dist/UI/Components/LogsViewer/components/LogsTable.js.map +1 -1
  693. package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js +8 -0
  694. package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js.map +1 -1
  695. package/build/dist/UI/Components/LogsViewer/types.js.map +1 -1
  696. package/build/dist/UI/Components/Markdown.tsx/MarkdownEditor.js +9 -2
  697. package/build/dist/UI/Components/Markdown.tsx/MarkdownEditor.js.map +1 -1
  698. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js +8 -21
  699. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js.map +1 -1
  700. package/build/dist/UI/Components/ProjectInvitations/PendingProjectInvitations.js +251 -0
  701. package/build/dist/UI/Components/ProjectInvitations/PendingProjectInvitations.js.map +1 -0
  702. package/build/dist/UI/Components/SimpleLogViewer/SimpleLogViewer.js +9 -2
  703. package/build/dist/UI/Components/SimpleLogViewer/SimpleLogViewer.js.map +1 -1
  704. package/build/dist/UI/Components/Table/Table.js +27 -15
  705. package/build/dist/UI/Components/Table/Table.js.map +1 -1
  706. package/build/dist/UI/Components/Table/TableBody.js +24 -18
  707. package/build/dist/UI/Components/Table/TableBody.js.map +1 -1
  708. package/build/dist/UI/Components/Table/TableHeader.js +9 -1
  709. package/build/dist/UI/Components/Table/TableHeader.js.map +1 -1
  710. package/build/dist/UI/Components/Table/TableRow.js +29 -21
  711. package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
  712. package/build/dist/UI/Components/Workflow/ArgumentsForm.js +130 -12
  713. package/build/dist/UI/Components/Workflow/ArgumentsForm.js.map +1 -1
  714. package/build/dist/UI/Components/Workflow/ComponentReturnValueViewer.js +10 -1
  715. package/build/dist/UI/Components/Workflow/ComponentReturnValueViewer.js.map +1 -1
  716. package/build/dist/UI/Components/Workflow/ComponentSettingsModal.js +4 -4
  717. package/build/dist/UI/Components/Workflow/ComponentSettingsModal.js.map +1 -1
  718. package/build/dist/UI/Components/Workflow/ComponentValuePickerModal.js +57 -7
  719. package/build/dist/UI/Components/Workflow/ComponentValuePickerModal.js.map +1 -1
  720. package/build/dist/UI/Components/Workflow/ComponentsModal.js +53 -18
  721. package/build/dist/UI/Components/Workflow/ComponentsModal.js.map +1 -1
  722. package/build/dist/UI/Components/Workflow/DocumentationViewer.js +19 -6
  723. package/build/dist/UI/Components/Workflow/DocumentationViewer.js.map +1 -1
  724. package/build/dist/UI/Components/Workflow/GraphLint.js +33 -4
  725. package/build/dist/UI/Components/Workflow/GraphLint.js.map +1 -1
  726. package/build/dist/UI/Components/Workflow/GraphLintSummary.js +231 -0
  727. package/build/dist/UI/Components/Workflow/GraphLintSummary.js.map +1 -0
  728. package/build/dist/UI/Components/Workflow/ModelColumnEditor.js +116 -21
  729. package/build/dist/UI/Components/Workflow/ModelColumnEditor.js.map +1 -1
  730. package/build/dist/UI/Components/Workflow/ModelSchema.js +72 -34
  731. package/build/dist/UI/Components/Workflow/ModelSchema.js.map +1 -1
  732. package/build/dist/UI/Components/Workflow/RunStatusWatcher.js +1 -1
  733. package/build/dist/UI/Components/Workflow/RunStatusWatcher.js.map +1 -1
  734. package/build/dist/UI/Components/Workflow/StepTraceViewer.js +1 -1
  735. package/build/dist/UI/Components/Workflow/StepTraceViewer.js.map +1 -1
  736. package/build/dist/UI/Components/Workflow/UseRunWatch.js +123 -0
  737. package/build/dist/UI/Components/Workflow/UseRunWatch.js.map +1 -0
  738. package/build/dist/UI/Components/Workflow/VariableModal.js +3 -2
  739. package/build/dist/UI/Components/Workflow/VariableModal.js.map +1 -1
  740. package/build/dist/UI/Components/Workflow/Workflow.js +41 -1
  741. package/build/dist/UI/Components/Workflow/Workflow.js.map +1 -1
  742. package/build/dist/UI/Components/Workflow/WorkflowIssuesModal.js +99 -0
  743. package/build/dist/UI/Components/Workflow/WorkflowIssuesModal.js.map +1 -0
  744. package/build/dist/UI/Components/Workflow/WorkflowLogModal.js +56 -0
  745. package/build/dist/UI/Components/Workflow/WorkflowLogModal.js.map +1 -0
  746. package/build/dist/UI/Components/Workflow/WorkflowStatusBar.js +92 -0
  747. package/build/dist/UI/Components/Workflow/WorkflowStatusBar.js.map +1 -0
  748. package/build/dist/UI/Utils/AIChatExport/ConversationMarkdown.js +9 -0
  749. package/build/dist/UI/Utils/AIChatExport/ConversationMarkdown.js.map +1 -1
  750. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js +1 -1
  751. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js.map +1 -1
  752. package/build/dist/UI/Utils/Platform.js +118 -0
  753. package/build/dist/UI/Utils/Platform.js.map +1 -0
  754. package/build/dist/UI/Utils/ProjectInvitationDisplay.js +106 -0
  755. package/build/dist/UI/Utils/ProjectInvitationDisplay.js.map +1 -0
  756. package/build/dist/Utils/Monitor/NetworkDeviceLinkRuleUtil.js +108 -0
  757. package/build/dist/Utils/Monitor/NetworkDeviceLinkRuleUtil.js.map +1 -0
  758. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +642 -136
  759. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
  760. package/build/dist/Utils/Telemetry/CrossSignalScope.js +328 -0
  761. package/build/dist/Utils/Telemetry/CrossSignalScope.js.map +1 -0
  762. package/build/dist/Utils/Telemetry/EntityKey.js +5 -5
  763. package/build/dist/Utils/Telemetry/EntityRelationship.js +1 -1
  764. package/jest.config.json +1 -0
  765. package/package.json +1 -1
  766. package/build/dist/Models/DatabaseModels/TelemetryEntity.js.map +0 -1
  767. package/build/dist/Models/DatabaseModels/TelemetryEntityRelationship.js.map +0 -1
  768. package/build/dist/Server/Services/TelemetryEntityRelationshipService.js.map +0 -1
  769. package/build/dist/Server/Services/TelemetryEntityService.js.map +0 -1
@@ -1,6 +1,8 @@
1
+ import AIConversation from "../../../../Models/DatabaseModels/AIConversation";
1
2
  import AIConversationMessage from "../../../../Models/DatabaseModels/AIConversationMessage";
2
3
  import AIRun from "../../../../Models/DatabaseModels/AIRun";
3
4
  import DatabaseCommonInteractionProps from "../../../../Types/BaseDatabase/DatabaseCommonInteractionProps";
5
+ import PositiveNumber from "../../../../Types/PositiveNumber";
4
6
  import SortOrder from "../../../../Types/BaseDatabase/SortOrder";
5
7
  import OneUptimeDate from "../../../../Types/Date";
6
8
  import { JSONObject } from "../../../../Types/JSON";
@@ -47,8 +49,12 @@ export interface ChatTurnRequest {
47
49
  /*
48
50
  * What the user was looking at in the dashboard when they sent this message
49
51
  * (already sanitized by the API). Folded into the system prompt so "this
50
- * incident" resolves to the entity on screen. Per-turn: not persisted, and
51
- * not needed on resume (the paused state already contains the built prompt).
52
+ * incident" resolves to the entity on screen. The first turn that carries
53
+ * one persists it to AIConversation.pageContext as the conversation's
54
+ * subject; later turns that arrive without a page context (the user
55
+ * navigated away mid-conversation) fall back to that persisted subject so
56
+ * "this incident" keeps resolving. Not needed on resume (the paused state
57
+ * already contains the built prompt).
52
58
  */
53
59
  pageContext?: AIChatPageContext | undefined;
54
60
  // The requesting user's real permission props, captured at request time.
@@ -69,7 +75,27 @@ const MAX_HISTORY_MESSAGES: number = 20;
69
75
  const MAX_OUTPUT_TOKENS: number = 4096;
70
76
  const TEMPERATURE: number = 0.2;
71
77
 
78
+ /*
79
+ * Replayed history is bounded twice: by row count (MAX_HISTORY_MESSAGES,
80
+ * above) and by an approximate token budget so a few enormous answers cannot
81
+ * crowd the entire context window. chars/4 is the usual rough heuristic for
82
+ * English prose + JSON.
83
+ */
84
+ const MAX_HISTORY_TOKENS: number = 24000;
85
+ const APPROX_CHARS_PER_TOKEN: number = 4;
86
+
87
+ // Caps for the per-message evidence digest appended to replayed answers.
88
+ const MAX_EVIDENCE_DIGEST_CHARS: number = 1500;
89
+ const MAX_DIGEST_ARGUMENTS_CHARS: number = 200;
90
+ const MAX_SHOWN_SUMMARY_CHARS: number = 300;
91
+
92
+ // Conversation title generation (first exchange only).
93
+ const MAX_TITLE_CHARS: number = 90;
94
+ const MAX_TITLE_SOURCE_CHARS: number = 500;
95
+ const TITLE_MAX_OUTPUT_TOKENS: number = 100;
96
+
72
97
  export const OBSERVABILITY_CHAT_FEATURE: string = "Observability Chat";
98
+ export const CHAT_TITLE_FEATURE: string = "Chat Title";
73
99
 
74
100
  /*
75
101
  * Remove citation markers the model fabricated: only markers matching
@@ -101,6 +127,275 @@ export function escapeToolResultContent(text: string): string {
101
127
  return text.replace(/<\/(tool_result)/gi, "<\\/$1");
102
128
  }
103
129
 
130
+ /*
131
+ * A compact, replayable record of the evidence behind a prior assistant
132
+ * answer, e.g.:
133
+ *
134
+ * [Evidence from this turn: C1 query_incidents({"incidentId":"..."}) ->
135
+ * 5 rows (Incidents, last 168h); C2 ...]
136
+ *
137
+ * History replay strips the [C#] markers from prior prose (this turn's
138
+ * citations are different objects), which used to discard all prior evidence.
139
+ * The digest keeps that evidence referable — the model can see what was
140
+ * already queried, with which arguments, and what came back — without
141
+ * replaying the raw tool payloads.
142
+ */
143
+ export function buildEvidenceDigest(citations: Array<AIChatCitation>): string {
144
+ if (citations.length === 0) {
145
+ return "";
146
+ }
147
+
148
+ const prefix: string = "[Evidence from this turn: ";
149
+ const entries: Array<string> = [];
150
+ let usedChars: number = prefix.length + 1; // +1 for the closing bracket
151
+ let includedCount: number = 0;
152
+
153
+ for (const citation of citations) {
154
+ let queryArguments: string;
155
+ try {
156
+ queryArguments = JSON.stringify(citation.queryArguments || {});
157
+ } catch {
158
+ queryArguments = "{…}";
159
+ }
160
+
161
+ if (queryArguments.length > MAX_DIGEST_ARGUMENTS_CHARS) {
162
+ queryArguments = `${queryArguments.substring(
163
+ 0,
164
+ MAX_DIGEST_ARGUMENTS_CHARS,
165
+ )}…`;
166
+ }
167
+
168
+ const entry: string = `${citation.id} ${citation.toolName}(${queryArguments}) -> ${citation.rowCount} rows (${citation.label})`;
169
+ const separatorChars: number = entries.length > 0 ? 2 : 0; // "; "
170
+
171
+ if (
172
+ entries.length > 0 &&
173
+ usedChars + separatorChars + entry.length > MAX_EVIDENCE_DIGEST_CHARS
174
+ ) {
175
+ break;
176
+ }
177
+
178
+ entries.push(entry);
179
+ usedChars += separatorChars + entry.length;
180
+ includedCount++;
181
+ }
182
+
183
+ const omittedCount: number = citations.length - includedCount;
184
+
185
+ let digest: string = prefix + entries.join("; ");
186
+ if (omittedCount > 0) {
187
+ digest += `; ... and ${omittedCount} more ${
188
+ omittedCount === 1 ? "query" : "queries"
189
+ }`;
190
+ }
191
+
192
+ return `${digest}]`;
193
+ }
194
+
195
+ /*
196
+ * A one-line summary of the non-text content of a prior assistant message —
197
+ * widget titles first (the user actually saw those), tool-action titles as a
198
+ * fallback. Used so widget-only answers no longer vanish from replayed
199
+ * history. Returns "" when there is nothing to summarize.
200
+ */
201
+ export function summarizeShownContent(
202
+ widgets: Array<AIChatWidget>,
203
+ toolActions: Array<AIChatToolAction>,
204
+ ): string {
205
+ const widgetTitles: Array<string> = widgets
206
+ .map((widget: AIChatWidget) => {
207
+ return widget.title;
208
+ })
209
+ .filter((title: string) => {
210
+ return Boolean(title);
211
+ });
212
+
213
+ const actionTitles: Array<string> = toolActions
214
+ .map((action: AIChatToolAction) => {
215
+ return action.title;
216
+ })
217
+ .filter((title: string) => {
218
+ return Boolean(title);
219
+ });
220
+
221
+ const summary: string = (
222
+ widgetTitles.length > 0 ? widgetTitles : actionTitles
223
+ ).join(", ");
224
+
225
+ return summary.length > MAX_SHOWN_SUMMARY_CHARS
226
+ ? `${summary.substring(0, MAX_SHOWN_SUMMARY_CHARS)}…`
227
+ : summary;
228
+ }
229
+
230
+ // One prior conversation message, already rendered for replay to the LLM.
231
+ export interface ReplayedHistoryMessage {
232
+ role: "user" | "assistant";
233
+ content: string;
234
+ }
235
+
236
+ export interface HistoryBudgetResult {
237
+ kept: Array<ReplayedHistoryMessage>;
238
+ // How many of the oldest entries were dropped to fit the budget.
239
+ droppedCount: number;
240
+ }
241
+
242
+ /*
243
+ * Enforce an approximate token budget over replayed history, dropping oldest
244
+ * entries first. The newest entry (the user message that started this turn)
245
+ * is always kept, even if it alone exceeds the budget — the model needs
246
+ * something to answer.
247
+ */
248
+ export function applyHistoryTokenBudget(
249
+ entries: Array<ReplayedHistoryMessage>,
250
+ maxTokens: number,
251
+ ): HistoryBudgetResult {
252
+ const kept: Array<ReplayedHistoryMessage> = [];
253
+ let usedTokens: number = 0;
254
+
255
+ for (let i: number = entries.length - 1; i >= 0; i--) {
256
+ const entry: ReplayedHistoryMessage | undefined = entries[i];
257
+ if (!entry) {
258
+ continue;
259
+ }
260
+
261
+ const entryTokens: number = Math.ceil(
262
+ entry.content.length / APPROX_CHARS_PER_TOKEN,
263
+ );
264
+
265
+ if (kept.length > 0 && usedTokens + entryTokens > maxTokens) {
266
+ return { kept, droppedCount: i + 1 };
267
+ }
268
+
269
+ kept.unshift(entry);
270
+ usedTokens += entryTokens;
271
+ }
272
+
273
+ return { kept, droppedCount: 0 };
274
+ }
275
+
276
+ /*
277
+ * Render one persisted conversation message for history replay, or undefined
278
+ * when the row should be skipped (unfinished/errored assistant turns, empty
279
+ * rows). Assistant answers get their stale [C#] markers stripped and a
280
+ * compact evidence digest appended; widget-only answers are replayed as a
281
+ * "[Showed the user: …]" summary instead of vanishing.
282
+ */
283
+ export function buildReplayedHistoryMessage(
284
+ message: AIConversationMessage,
285
+ ): ReplayedHistoryMessage | undefined {
286
+ if (message.role === AIChatMessageRole.User) {
287
+ if (!message.contentInMarkdown) {
288
+ return undefined;
289
+ }
290
+ return { role: "user", content: message.contentInMarkdown };
291
+ }
292
+
293
+ /*
294
+ * Assistant rows: replay only terminal-with-output turns. Cancelled is
295
+ * terminal too — a cancelled turn's partial answer is part of what the
296
+ * user saw. In-flight and errored rows are skipped as before.
297
+ */
298
+ if (
299
+ message.status !== AIChatMessageStatus.Completed &&
300
+ message.status !== AIChatMessageStatus.Cancelled
301
+ ) {
302
+ return undefined;
303
+ }
304
+
305
+ const digest: string = buildEvidenceDigest(message.citations || []);
306
+
307
+ /*
308
+ * A cancelled turn's contentInMarkdown is the server's finalizer text
309
+ * ("Stopped by user."), not assistant prose — replaying it verbatim
310
+ * teaches the model to imitate or apologize for it. Replay a neutral
311
+ * marker instead, keeping the evidence digest so queries that DID run
312
+ * before the stop stay referable.
313
+ */
314
+ if (message.status === AIChatMessageStatus.Cancelled) {
315
+ const cancelledParts: Array<string> = [
316
+ "[The user stopped this answer before it finished.]",
317
+ ];
318
+ if (digest) {
319
+ cancelledParts.push(digest);
320
+ }
321
+ return { role: "assistant", content: cancelledParts.join("\n\n") };
322
+ }
323
+
324
+ /*
325
+ * A prior assistant answer carries [C#] citation markers that pointed at
326
+ * that turn's tool results — citations that no longer exist in this turn.
327
+ * Left in the replayed history the model echoes and renumbers them, and
328
+ * this turn's stripFabricatedCitationMarkers then deletes the unmatched
329
+ * ones, leaving claims that look uncited. Strip the markers from replayed
330
+ * answers so only freshly minted citations ever appear; the digest above
331
+ * keeps the underlying evidence referable.
332
+ */
333
+ const prose: string = (message.contentInMarkdown || "").replace(
334
+ /\s?\[C\d+\]/g,
335
+ "",
336
+ );
337
+
338
+ if (prose.trim()) {
339
+ return {
340
+ role: "assistant",
341
+ content: digest ? `${prose}\n\n${digest}` : prose,
342
+ };
343
+ }
344
+
345
+ const shown: string = summarizeShownContent(
346
+ message.widgets || [],
347
+ message.toolActions || [],
348
+ );
349
+
350
+ const parts: Array<string> = [];
351
+ if (shown) {
352
+ parts.push(`[Showed the user: ${shown}]`);
353
+ }
354
+ if (digest) {
355
+ parts.push(digest);
356
+ }
357
+
358
+ if (parts.length === 0) {
359
+ return undefined;
360
+ }
361
+
362
+ return { role: "assistant", content: parts.join("\n\n") };
363
+ }
364
+
365
+ /*
366
+ * Clean up an LLM-generated conversation title: first non-empty line only,
367
+ * wrapping quotes and markdown headings stripped, trailing punctuation
368
+ * removed, whitespace collapsed, clamped to MAX_TITLE_CHARS. Returns "" when
369
+ * nothing usable remains (callers keep the old title in that case).
370
+ */
371
+ export function sanitizeGeneratedTitle(raw: string): string {
372
+ const firstLine: string | undefined = raw
373
+ .split("\n")
374
+ .map((line: string) => {
375
+ return line.trim();
376
+ })
377
+ .find((line: string) => {
378
+ return line.length > 0;
379
+ });
380
+
381
+ let title: string = firstLine || "";
382
+
383
+ title = title
384
+ .replace(/^#+\s*/, "")
385
+ .replace(/^Title:\s*/i, "")
386
+ .replace(/^["'`“”‘’\s]+/, "")
387
+ .replace(/["'`“”‘’\s]+$/, "")
388
+ .replace(/[.,;:!?…\s]+$/, "")
389
+ .replace(/\s+/g, " ")
390
+ .trim();
391
+
392
+ if (title.length > MAX_TITLE_CHARS) {
393
+ title = title.substring(0, MAX_TITLE_CHARS).trim();
394
+ }
395
+
396
+ return title;
397
+ }
398
+
104
399
  interface TurnState {
105
400
  llmCallCount: number;
106
401
  toolCallCount: number;
@@ -139,8 +434,17 @@ export default class ChatAgentRunner {
139
434
  eventType: AIRunEventType.RunStarted,
140
435
  });
141
436
 
142
- const messages: Array<LLMMessage> =
143
- await this.buildInitialMessages(request);
437
+ /*
438
+ * The conversation's subject: a fresh page context is persisted on
439
+ * first use, and turns without one fall back to the persisted subject.
440
+ */
441
+ const pageContext: AIChatPageContext | undefined =
442
+ await this.resolvePageContext(request);
443
+
444
+ const messages: Array<LLMMessage> = await this.buildInitialMessages(
445
+ request,
446
+ pageContext,
447
+ );
144
448
 
145
449
  await this.runAgentLoop(request, state, messages, toolContext);
146
450
  } catch (error) {
@@ -284,6 +588,15 @@ export default class ChatAgentRunner {
284
588
 
285
589
  // Apply the decisions: run approved actions, refuse denied ones.
286
590
  for (const toolCall of pendingToolCalls) {
591
+ /*
592
+ * Cooperative cancellation: if POST /ai-chat/cancel-run took the run while
593
+ * this batch was executing, it already finalized the assistant message
594
+ * and the run. Abandon immediately — write nothing, emit nothing.
595
+ */
596
+ if (await this.isRunCancelled(request)) {
597
+ return;
598
+ }
599
+
287
600
  const decision: ResumeToolDecision | undefined = decisions.find(
288
601
  (item: ResumeToolDecision) => {
289
602
  return item.toolCallId === toolCall.id;
@@ -361,9 +674,19 @@ export default class ChatAgentRunner {
361
674
  toolContext: ToolContext,
362
675
  ): Promise<LoopOutcome> {
363
676
  let finalContent: string = "";
677
+ let finalStopReason: string | undefined = undefined;
364
678
  let manifest: AIRunEgressManifest | undefined = undefined;
365
679
 
366
680
  while (true) {
681
+ /*
682
+ * Cooperative cancellation: POST /ai-chat/cancel-run flips the run to
683
+ * Cancelled and finalizes the assistant message itself. Abandon
684
+ * immediately — overwrite nothing, emit nothing further.
685
+ */
686
+ if (await this.isRunCancelled(request)) {
687
+ return { paused: false };
688
+ }
689
+
367
690
  const budgetExhausted: boolean =
368
691
  state.llmCallCount >= MAX_LLM_CALLS - 1 ||
369
692
  state.toolCallCount >= MAX_TOOL_CALLS ||
@@ -425,7 +748,15 @@ export default class ChatAgentRunner {
425
748
  if (
426
749
  !budgetExhausted &&
427
750
  response.toolCalls &&
428
- response.toolCalls.length > 0
751
+ response.toolCalls.length > 0 &&
752
+ /*
753
+ * Never execute tool calls from a truncated response: when the
754
+ * output hit the token cap mid-generation, the parsed calls may have
755
+ * cut-off arguments — running one (especially a mutation) would act
756
+ * on mangled input. Fall through to the final-answer path, which
757
+ * appends the truncation notice instead.
758
+ */
759
+ response.stopReason !== "length"
429
760
  ) {
430
761
  messages.push({
431
762
  role: "assistant",
@@ -436,6 +767,11 @@ export default class ChatAgentRunner {
436
767
  const pendingApproval: Array<LLMToolCall> = [];
437
768
 
438
769
  for (const toolCall of response.toolCalls) {
770
+ // Re-check between tools: a batch can run long and cancel must cut in.
771
+ if (await this.isRunCancelled(request)) {
772
+ return { paused: false };
773
+ }
774
+
439
775
  /*
440
776
  * The batch size is model-controlled — budgets must hold inside
441
777
  * the batch too, not just between LLM rounds.
@@ -545,6 +881,8 @@ export default class ChatAgentRunner {
545
881
  }
546
882
 
547
883
  finalContent = response.content;
884
+ finalStopReason = response.stopReason;
885
+
548
886
  break;
549
887
  }
550
888
 
@@ -553,6 +891,11 @@ export default class ChatAgentRunner {
553
891
  state.citations,
554
892
  );
555
893
 
894
+ // Make output truncation visible instead of silently ending mid-sentence.
895
+ if (finalStopReason === "length") {
896
+ finalContent = `${finalContent}\n\n_[Answer truncated by the output token limit.]_`;
897
+ }
898
+
556
899
  if (manifest) {
557
900
  manifest.llmCallCount = state.llmCallCount;
558
901
  manifest.totalTokens = state.totalTokens;
@@ -561,7 +904,8 @@ export default class ChatAgentRunner {
561
904
 
562
905
  /*
563
906
  * Scope the finalizing writes by current status so a run the stale-run
564
- * sweeper already failed (or a crashed retry) is never flipped back to
907
+ * sweeper already failed, a crashed retry or a message the cancel
908
+ * endpoint already finalized as Cancelled — is never flipped back to
565
909
  * Completed underneath the user.
566
910
  */
567
911
  await AIConversationMessageService.updateOneBy({
@@ -579,7 +923,7 @@ export default class ChatAgentRunner {
579
923
  props: { isRoot: true },
580
924
  });
581
925
 
582
- await AIRunService.updateOneBy({
926
+ const finalizedRunCount: number = await AIRunService.updateOneBy({
583
927
  query: {
584
928
  _id: request.aiRunId.toString(),
585
929
  status: AIRunStatus.Running,
@@ -598,12 +942,31 @@ export default class ChatAgentRunner {
598
942
  props: { isRoot: true },
599
943
  });
600
944
 
945
+ /*
946
+ * Zero rows means the run is no longer ours — the cancel endpoint (or the
947
+ * stale-run sweeper) finalized it while the last LLM round was in flight.
948
+ * Its owner wrote the final state; emit nothing further.
949
+ */
950
+ if (finalizedRunCount === 0) {
951
+ return { paused: false };
952
+ }
953
+
601
954
  await this.emitEvent(request, state, {
602
955
  eventType: AIRunEventType.RunCompleted,
603
956
  });
604
957
 
605
958
  await this.updateConversationAfterTurn(request);
606
959
 
960
+ /*
961
+ * Naming the conversation is cosmetic: fire-and-forget, off the critical
962
+ * path, and a failure never affects the finished turn.
963
+ */
964
+ this.generateConversationTitleIfFirstExchange(request).catch(
965
+ (error: Error) => {
966
+ logger.error(`AI chat title generation failed: ${error.message}`);
967
+ },
968
+ );
969
+
607
970
  return { paused: false };
608
971
  }
609
972
 
@@ -663,16 +1026,30 @@ export default class ChatAgentRunner {
663
1026
  state: TurnState,
664
1027
  status: AIChatMessageStatus,
665
1028
  ): Promise<void> {
666
- await AIConversationMessageService.updateOneById({
667
- id: request.assistantMessageId,
668
- data: {
669
- citations: state.citations,
670
- widgets: state.widgets,
671
- toolActions: state.toolActions,
672
- status: status,
673
- } as never,
674
- props: { isRoot: true },
675
- });
1029
+ /*
1030
+ * Scope progress writes to rows still in flight so they can never
1031
+ * resurrect a message another path already finalized — completed,
1032
+ * errored, or cancelled by POST /ai-chat/cancel-run while a tool batch was
1033
+ * running. Same protection the finalizing writes use.
1034
+ */
1035
+ for (const inFlightStatus of [
1036
+ AIChatMessageStatus.InProgress,
1037
+ AIChatMessageStatus.WaitingForApproval,
1038
+ ]) {
1039
+ await AIConversationMessageService.updateOneBy({
1040
+ query: {
1041
+ _id: request.assistantMessageId.toString(),
1042
+ status: inFlightStatus,
1043
+ },
1044
+ data: {
1045
+ citations: state.citations,
1046
+ widgets: state.widgets,
1047
+ toolActions: state.toolActions,
1048
+ status: status,
1049
+ } as never,
1050
+ props: { isRoot: true },
1051
+ });
1052
+ }
676
1053
  }
677
1054
 
678
1055
  // Upsert a tool action (mutation) into state, keyed by the tool call id.
@@ -870,13 +1247,18 @@ export default class ChatAgentRunner {
870
1247
 
871
1248
  private static async buildInitialMessages(
872
1249
  request: ChatTurnRequest,
1250
+ pageContext: AIChatPageContext | undefined,
873
1251
  ): Promise<Array<LLMMessage>> {
874
1252
  /*
875
1253
  * History is read with the requesting user's props: the privacy pin
876
- * guarantees these are the user's own messages.
1254
+ * guarantees these are the user's own messages. The count (pinned the
1255
+ * same way) tells us how many earlier messages the row cap left behind.
877
1256
  */
878
- const history: Array<AIConversationMessage> =
879
- await AIConversationMessageService.findBy({
1257
+ const [history, totalMessageCount]: [
1258
+ Array<AIConversationMessage>,
1259
+ PositiveNumber,
1260
+ ] = await Promise.all([
1261
+ AIConversationMessageService.findBy({
880
1262
  query: {
881
1263
  conversationId: request.conversationId,
882
1264
  },
@@ -884,6 +1266,9 @@ export default class ChatAgentRunner {
884
1266
  role: true,
885
1267
  contentInMarkdown: true,
886
1268
  status: true,
1269
+ citations: true,
1270
+ widgets: true,
1271
+ toolActions: true,
887
1272
  },
888
1273
  sort: {
889
1274
  createdAt: SortOrder.Descending,
@@ -891,7 +1276,40 @@ export default class ChatAgentRunner {
891
1276
  limit: MAX_HISTORY_MESSAGES,
892
1277
  skip: 0,
893
1278
  props: request.props,
894
- });
1279
+ }),
1280
+ AIConversationMessageService.countBy({
1281
+ query: {
1282
+ conversationId: request.conversationId,
1283
+ },
1284
+ props: request.props,
1285
+ }),
1286
+ ]);
1287
+
1288
+ const fetchedCount: number = history.length;
1289
+
1290
+ // Oldest first, skipping unfinished/errored assistant rows.
1291
+ const replayable: Array<ReplayedHistoryMessage> = [];
1292
+ for (const message of history.reverse()) {
1293
+ const replayed: ReplayedHistoryMessage | undefined =
1294
+ buildReplayedHistoryMessage(message);
1295
+ if (replayed) {
1296
+ replayable.push(replayed);
1297
+ }
1298
+ }
1299
+
1300
+ const budgeted: HistoryBudgetResult = applyHistoryTokenBudget(
1301
+ replayable,
1302
+ MAX_HISTORY_TOKENS,
1303
+ );
1304
+
1305
+ /*
1306
+ * Everything the model will not see: rows beyond the fetch cap plus rows
1307
+ * the token budget dropped. Skipped in-flight/errored rows are not
1308
+ * counted — they were never replayable in the first place.
1309
+ */
1310
+ const droppedCount: number =
1311
+ Math.max(0, totalMessageCount.toNumber() - fetchedCount) +
1312
+ budgeted.droppedCount;
895
1313
 
896
1314
  const messages: Array<LLMMessage> = [
897
1315
  {
@@ -899,43 +1317,204 @@ export default class ChatAgentRunner {
899
1317
  content: buildObservabilityChatSystemPrompt({
900
1318
  currentTime: OneUptimeDate.getCurrentDate(),
901
1319
  permissionMode: request.permissionMode,
902
- pageContext: request.pageContext,
1320
+ pageContext: pageContext,
903
1321
  }),
904
1322
  },
905
1323
  ];
906
1324
 
907
- // Oldest first, skipping unfinished/errored assistant rows.
908
- for (const message of history.reverse()) {
909
- if (!message.contentInMarkdown) {
910
- continue;
1325
+ if (droppedCount > 0) {
1326
+ // Tell the model history is partial so it never asserts "you never said X".
1327
+ messages.push({
1328
+ role: "user",
1329
+ content: `[Note: ${droppedCount} earlier messages in this conversation were omitted for length.]`,
1330
+ });
1331
+ }
1332
+
1333
+ for (const entry of budgeted.kept) {
1334
+ messages.push({
1335
+ role: entry.role,
1336
+ content: entry.content,
1337
+ });
1338
+ }
1339
+
1340
+ return messages;
1341
+ }
1342
+
1343
+ /*
1344
+ * Cheap cooperative-cancellation probe: a status-only read of the run.
1345
+ * Checked at the top of every agent-loop iteration and before every tool
1346
+ * execution. A probe failure never kills the turn — cancellation is
1347
+ * best-effort, and the status-scoped finalizing writes are the backstop.
1348
+ */
1349
+ private static async isRunCancelled(
1350
+ request: ChatTurnRequest,
1351
+ ): Promise<boolean> {
1352
+ try {
1353
+ const run: AIRun | null = await AIRunService.findOneById({
1354
+ id: request.aiRunId,
1355
+ select: {
1356
+ status: true,
1357
+ },
1358
+ props: { isRoot: true },
1359
+ });
1360
+
1361
+ return run?.status === AIRunStatus.Cancelled;
1362
+ } catch {
1363
+ return false;
1364
+ }
1365
+ }
1366
+
1367
+ /*
1368
+ * Resolve the page context for this turn and keep the conversation's
1369
+ * subject persistent: the first turn that carries a page context pins it to
1370
+ * AIConversation.pageContext (root props — same as the runner's other
1371
+ * conversation updates), and later turns without one fall back to the
1372
+ * pinned subject so "this incident" keeps resolving. Page context is a
1373
+ * hint, so a failure here degrades to whatever the request carried rather
1374
+ * than failing the turn.
1375
+ */
1376
+ private static async resolvePageContext(
1377
+ request: ChatTurnRequest,
1378
+ ): Promise<AIChatPageContext | undefined> {
1379
+ try {
1380
+ const conversation: AIConversation | null =
1381
+ await AIConversationService.findOneById({
1382
+ id: request.conversationId,
1383
+ select: {
1384
+ pageContext: true,
1385
+ },
1386
+ props: { isRoot: true },
1387
+ });
1388
+
1389
+ const persisted: AIChatPageContext | undefined =
1390
+ conversation?.pageContext || undefined;
1391
+
1392
+ if (!request.pageContext) {
1393
+ return persisted;
911
1394
  }
912
1395
 
913
- if (
914
- message.role === AIChatMessageRole.Assistant &&
915
- message.status !== AIChatMessageStatus.Completed
916
- ) {
917
- continue;
1396
+ /*
1397
+ * Persist the LATEST explicit context, not just the first: when the
1398
+ * user carries a conversation from incident A to incident B, "this
1399
+ * incident" on later contextless turns must mean B — replaying a
1400
+ * stale first subject would silently flip the conversation back.
1401
+ */
1402
+ const persistedSignature: string = persisted
1403
+ ? `${persisted.type}:${persisted.entityId || ""}`
1404
+ : "";
1405
+ const incomingSignature: string = `${request.pageContext.type}:${
1406
+ request.pageContext.entityId || ""
1407
+ }`;
1408
+
1409
+ if (persistedSignature !== incomingSignature) {
1410
+ await AIConversationService.updateOneById({
1411
+ id: request.conversationId,
1412
+ data: {
1413
+ pageContext: request.pageContext,
1414
+ } as never,
1415
+ props: { isRoot: true },
1416
+ });
918
1417
  }
919
1418
 
920
- const isUserMessage: boolean = message.role === AIChatMessageRole.User;
1419
+ return request.pageContext;
1420
+ } catch (error) {
1421
+ logger.error(
1422
+ `Failed to resolve AI chat page context: ${
1423
+ error instanceof Error ? error.message : String(error)
1424
+ }`,
1425
+ );
1426
+ return request.pageContext;
1427
+ }
1428
+ }
921
1429
 
922
- messages.push({
923
- role: isUserMessage ? "user" : "assistant",
924
- /*
925
- * A prior assistant answer carries [C#] citation markers that pointed
926
- * at that turn's tool results — citations that no longer exist in this
927
- * turn. Left in the replayed history the model echoes and renumbers
928
- * them, and this turn's stripFabricatedCitationMarkers then deletes the
929
- * unmatched ones, leaving claims that look uncited. Strip the markers
930
- * from replayed answers so only freshly minted citations ever appear.
931
- */
932
- content: isUserMessage
933
- ? message.contentInMarkdown
934
- : message.contentInMarkdown.replace(/\s?\[C\d+\]/g, ""),
1430
+ /*
1431
+ * After the first successful exchange, name the conversation with a small
1432
+ * LLM call. Callers invoke this fire-and-forget: it runs off the turn's
1433
+ * critical path and any failure is logged, never surfaced.
1434
+ */
1435
+ private static async generateConversationTitleIfFirstExchange(
1436
+ request: ChatTurnRequest,
1437
+ ): Promise<void> {
1438
+ const messageCount: PositiveNumber =
1439
+ await AIConversationMessageService.countBy({
1440
+ query: {
1441
+ conversationId: request.conversationId,
1442
+ /*
1443
+ * Count only completed rows: a first turn that errored or was
1444
+ * stopped still leaves rows behind, and counting those would
1445
+ * permanently skip titling once the first SUCCESSFUL exchange
1446
+ * finally lands.
1447
+ */
1448
+ status: AIChatMessageStatus.Completed,
1449
+ },
1450
+ props: { isRoot: true },
935
1451
  });
1452
+
1453
+ // Only the first user/assistant exchange earns a generated title.
1454
+ if (messageCount.toNumber() > 2) {
1455
+ return;
936
1456
  }
937
1457
 
938
- return messages;
1458
+ const firstUserMessage: AIConversationMessage | null =
1459
+ await AIConversationMessageService.findOneBy({
1460
+ query: {
1461
+ conversationId: request.conversationId,
1462
+ role: AIChatMessageRole.User,
1463
+ },
1464
+ select: {
1465
+ contentInMarkdown: true,
1466
+ },
1467
+ sort: {
1468
+ createdAt: SortOrder.Ascending,
1469
+ },
1470
+ props: { isRoot: true },
1471
+ });
1472
+
1473
+ const firstMessageText: string = (firstUserMessage?.contentInMarkdown || "")
1474
+ .substring(0, MAX_TITLE_SOURCE_CHARS)
1475
+ .trim();
1476
+
1477
+ if (!firstMessageText) {
1478
+ return;
1479
+ }
1480
+
1481
+ const response: AILogResponse = await AIService.executeWithLogging({
1482
+ projectId: request.projectId,
1483
+ userId: request.userId,
1484
+ aiRunId: request.aiRunId,
1485
+ llmProviderId: request.llmProviderId,
1486
+ feature: CHAT_TITLE_FEATURE,
1487
+ messages: [
1488
+ {
1489
+ role: "system",
1490
+ content:
1491
+ "You title conversations. Reply with ONLY a concise 3-8 word title for the conversation — no quotes, no trailing punctuation, no explanation.",
1492
+ },
1493
+ {
1494
+ role: "user",
1495
+ content: `Title a conversation that starts with this user message:\n\n${firstMessageText}`,
1496
+ },
1497
+ ],
1498
+ maxTokens: TITLE_MAX_OUTPUT_TOKENS,
1499
+ temperature: TEMPERATURE,
1500
+ // Same privacy rule as the chat itself: LlmLog is project-readable.
1501
+ storeContentPreviews: false,
1502
+ });
1503
+
1504
+ const title: string = sanitizeGeneratedTitle(response.content);
1505
+
1506
+ // An unusable title keeps whatever the conversation already had.
1507
+ if (!title) {
1508
+ return;
1509
+ }
1510
+
1511
+ await AIConversationService.updateOneById({
1512
+ id: request.conversationId,
1513
+ data: {
1514
+ title: title,
1515
+ } as never,
1516
+ props: { isRoot: true },
1517
+ });
939
1518
  }
940
1519
 
941
1520
  private static async heartbeat(
@@ -1022,7 +1601,9 @@ export default class ChatAgentRunner {
1022
1601
  * finalization (e.g. a transient error updating the conversation) must
1023
1602
  * not flip an already-Completed answer to Error. Both non-terminal
1024
1603
  * statuses are covered — InProgress (a live turn) and WaitingForApproval
1025
- * (a turn that errored while resuming).
1604
+ * (a turn that errored while resuming). Terminal statuses (Completed,
1605
+ * Error, Cancelled) are deliberately excluded: a message the cancel
1606
+ * endpoint finalized is never flipped to Error underneath the user.
1026
1607
  */
1027
1608
  for (const inFlightStatus of [
1028
1609
  AIChatMessageStatus.InProgress,
@@ -1043,11 +1624,13 @@ export default class ChatAgentRunner {
1043
1624
  });
1044
1625
  }
1045
1626
 
1627
+ let failedRunCount: number = 0;
1628
+
1046
1629
  for (const inFlightStatus of [
1047
1630
  AIRunStatus.Running,
1048
1631
  AIRunStatus.WaitingForApproval,
1049
1632
  ]) {
1050
- await AIRunService.updateOneBy({
1633
+ failedRunCount += await AIRunService.updateOneBy({
1051
1634
  query: {
1052
1635
  _id: request.aiRunId.toString(),
1053
1636
  status: inFlightStatus,
@@ -1061,9 +1644,21 @@ export default class ChatAgentRunner {
1061
1644
  props: { isRoot: true },
1062
1645
  }).catch(() => {
1063
1646
  // best-effort
1647
+ return 0;
1064
1648
  });
1065
1649
  }
1066
1650
 
1651
+ /*
1652
+ * Emit the terminal event only when this call actually flipped the run.
1653
+ * Zero rows means another writer already finalized it — most commonly
1654
+ * the cancel endpoint, which emitted its own terminal event at the same
1655
+ * sequence; emitting a second one here would make a deliberately stopped
1656
+ * turn render as a provider failure.
1657
+ */
1658
+ if (failedRunCount === 0) {
1659
+ return;
1660
+ }
1661
+
1067
1662
  const state: TurnState = this.freshState();
1068
1663
  state.eventSequence = 100000; // error events sort after progress events
1069
1664