@oneuptime/common 11.4.0 → 11.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (473) hide show
  1. package/Models/DatabaseModels/AIRun.ts +50 -0
  2. package/Models/DatabaseModels/AlertSeverity.ts +6 -0
  3. package/Models/DatabaseModels/IncidentSeverity.ts +6 -0
  4. package/Models/DatabaseModels/Index.ts +16 -0
  5. package/Models/DatabaseModels/IoTDeviceCredential.ts +471 -0
  6. package/Models/DatabaseModels/LlmLog.ts +56 -0
  7. package/Models/DatabaseModels/LlmProvider.ts +33 -0
  8. package/Models/DatabaseModels/NetworkDevice.ts +1385 -0
  9. package/Models/DatabaseModels/NetworkDeviceDiscoveryScan.ts +717 -0
  10. package/Models/DatabaseModels/NetworkDeviceLabelRule.ts +514 -0
  11. package/Models/DatabaseModels/NetworkDeviceOwnerRule.ts +596 -0
  12. package/Models/DatabaseModels/NetworkDeviceOwnerTeam.ts +487 -0
  13. package/Models/DatabaseModels/NetworkDeviceOwnerUser.ts +486 -0
  14. package/Models/DatabaseModels/NetworkInterface.ts +563 -0
  15. package/Models/DatabaseModels/Project.ts +145 -0
  16. package/Models/DatabaseModels/TelemetryEntityRelationship.ts +54 -0
  17. package/Server/API/AIAgentTaskAPI.ts +10 -24
  18. package/Server/API/AIInvestigationAPI.ts +131 -63
  19. package/Server/API/AlertAPI.ts +5 -0
  20. package/Server/API/IncidentAPI.ts +10 -0
  21. package/Server/API/IncidentEpisodeAPI.ts +5 -0
  22. package/Server/API/LlmProviderAPI.ts +4 -0
  23. package/Server/API/ScheduledMaintenanceAPI.ts +5 -0
  24. package/Server/API/TelemetryAPI.ts +4 -3
  25. package/Server/Infrastructure/Postgres/SchemaMigrations/1783650000000-AddAdditionalParamsToLlmProvider.ts +19 -0
  26. package/Server/Infrastructure/Postgres/SchemaMigrations/1783695782697-AddCacheTokenColumnsToLlmLog.ts +25 -0
  27. package/Server/Infrastructure/Postgres/SchemaMigrations/1783701585317-AddAlertInvestigationGating.ts +31 -0
  28. package/Server/Infrastructure/Postgres/SchemaMigrations/1783702431535-AddAiDailyAutonomousTokenLimitToProject.ts +19 -0
  29. package/Server/Infrastructure/Postgres/SchemaMigrations/1783720000000-AddNetworkDeviceTables.ts +105 -0
  30. package/Server/Infrastructure/Postgres/SchemaMigrations/1783721121260-AddAttemptCountToAIRun.ts +15 -0
  31. package/Server/Infrastructure/Postgres/SchemaMigrations/1783730000000-AddNetworkDeviceOwnersAndRules.ts +192 -0
  32. package/Server/Infrastructure/Postgres/SchemaMigrations/1783740000000-AddNetworkDeviceDiscoveryScan.ts +37 -0
  33. package/Server/Infrastructure/Postgres/SchemaMigrations/1783750000000-AddLldpNeighborsToNetworkDevice.ts +19 -0
  34. package/Server/Infrastructure/Postgres/SchemaMigrations/1783760576655-AddInvestigationTuningToProject.ts +25 -0
  35. package/Server/Infrastructure/Postgres/SchemaMigrations/1783762505482-AddTelemetryEntityRelationshipMetrics.ts +31 -0
  36. package/Server/Infrastructure/Postgres/SchemaMigrations/1783780000000-AddIoTDeviceCredentialTable.ts +79 -0
  37. package/Server/Infrastructure/Postgres/SchemaMigrations/1783790000000-AddSnmpV3AuthColumnsToNetworkDevice.ts +49 -0
  38. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +24 -0
  39. package/Server/Services/AIAgentTaskService.ts +62 -0
  40. package/Server/Services/AIRunService.ts +58 -0
  41. package/Server/Services/AIService.ts +101 -0
  42. package/Server/Services/AnalyticsDatabaseService.ts +27 -0
  43. package/Server/Services/IncidentService.ts +14 -41
  44. package/Server/Services/Index.ts +14 -0
  45. package/Server/Services/IoTDeviceCredentialService.ts +351 -0
  46. package/Server/Services/IoTDeviceService.ts +64 -21
  47. package/Server/Services/LlmLogService.ts +26 -0
  48. package/Server/Services/LlmProviderService.ts +3 -0
  49. package/Server/Services/LogAggregationService.ts +29 -11
  50. package/Server/Services/MetricService.ts +603 -13
  51. package/Server/Services/MonitorService.ts +4 -1
  52. package/Server/Services/NetworkDeviceDiscoveryScanService.ts +10 -0
  53. package/Server/Services/NetworkDeviceLabelRuleEngineService.ts +204 -0
  54. package/Server/Services/NetworkDeviceLabelRuleService.ts +14 -0
  55. package/Server/Services/NetworkDeviceOwnerRuleEngineService.ts +222 -0
  56. package/Server/Services/NetworkDeviceOwnerRuleService.ts +14 -0
  57. package/Server/Services/NetworkDeviceOwnerTeamService.ts +10 -0
  58. package/Server/Services/NetworkDeviceOwnerUserService.ts +10 -0
  59. package/Server/Services/NetworkDeviceService.ts +50 -0
  60. package/Server/Services/NetworkInterfaceService.ts +10 -0
  61. package/Server/Services/TelemetryEntityRelationshipService.ts +23 -0
  62. package/Server/Services/TelemetryEntityService.ts +72 -2
  63. package/Server/Utils/AI/Sentinel/AlertInvestigationRunner.ts +244 -12
  64. package/Server/Utils/AI/Sentinel/IncidentInvestigationRunner.ts +92 -19
  65. package/Server/Utils/AI/Sentinel/InvestigationQueue.ts +493 -0
  66. package/Server/Utils/AI/Sentinel/README.md +10 -0
  67. package/Server/Utils/AI/Sentinel/SentinelInvestigationEngine.ts +88 -68
  68. package/Server/Utils/AI/Toolbox/Index.ts +2 -1
  69. package/Server/Utils/AI/Toolbox/MetricTools.ts +391 -0
  70. package/Server/Utils/LLM/LLMService.ts +21 -0
  71. package/Server/Utils/Monitor/Criteria/APIRequestCriteria.ts +44 -0
  72. package/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.ts +170 -2
  73. package/Server/Utils/Monitor/IoTDeviceAbsenceSeries.ts +101 -0
  74. package/Server/Utils/Monitor/MonitorAlert.ts +15 -3
  75. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +1 -1
  76. package/Server/Utils/Monitor/MonitorIncident.ts +19 -3
  77. package/Server/Utils/Monitor/MonitorMetricUtil.ts +195 -2
  78. package/Server/Utils/Monitor/MonitorResource.ts +77 -21
  79. package/Server/Utils/Monitor/MonitorTemplateUtil.ts +1 -1
  80. package/Server/Utils/Monitor/NetworkDeviceHydrationUtil.ts +201 -0
  81. package/Server/Utils/Monitor/NetworkInventoryUtil.ts +215 -0
  82. package/Server/Utils/Monitor/SnmpInterfaceRateUtil.ts +169 -0
  83. package/Tests/Server/Services/AIAgentTaskServiceClaim.test.ts +146 -0
  84. package/Tests/Server/Services/AIServiceDailyBudget.test.ts +173 -0
  85. package/Tests/Server/Services/IncidentInternalNoteAnnouncement.test.ts +97 -0
  86. package/Tests/Server/Services/IoTDeviceService.test.ts +54 -0
  87. package/Tests/Server/Services/LogAggregationService.test.ts +22 -0
  88. package/Tests/Server/Services/MetricServiceAggregate.test.ts +194 -0
  89. package/Tests/Server/Utils/AI/BaselineAnomalyTool.test.ts +253 -0
  90. package/Tests/Server/Utils/AI/LLMServiceToolCalling.test.ts +44 -0
  91. package/Tests/Server/Utils/AI/SentinelAlertGating.test.ts +360 -0
  92. package/Tests/Server/Utils/AI/SentinelInvestigationQueue.test.ts +295 -0
  93. package/Tests/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.test.ts +59 -0
  94. package/Tests/Server/Utils/Monitor/IoTDeviceAbsenceSeries.test.ts +113 -0
  95. package/Tests/Server/Utils/Monitor/PerSeriesRecoveryResolution.test.ts +198 -0
  96. package/Tests/Types/AI/AIAgentTaskStatus.test.ts +86 -0
  97. package/Tests/Types/BaseDatabase/AggregationIntervalUtil.test.ts +127 -0
  98. package/Tests/Types/BaseDatabase/DatabaseCommonInteractionPropsUtil.test.ts +152 -0
  99. package/Tests/Types/Monitor/MonitorType.test.ts +1 -1
  100. package/Tests/Types/Trace/TraceRecordingRuleDefinition.test.ts +308 -0
  101. package/Tests/UI/Components/Dropdown.test.tsx +17 -0
  102. package/Tests/UI/Components/EntityDropdown.test.tsx +130 -0
  103. package/Tests/UI/Components/Modal.test.tsx +144 -2
  104. package/Tests/UI/Components/TelemetrySearchBar.test.tsx +90 -0
  105. package/Tests/UI/Utils/Theme.test.ts +161 -0
  106. package/Tests/Utils/Monitor/LatencyMatrixUtil.test.ts +111 -0
  107. package/Types/AI/AIRunStatus.ts +9 -0
  108. package/Types/BaseDatabase/AggregateBy.ts +12 -0
  109. package/Types/Dashboard/DashboardComponentType.ts +1 -0
  110. package/Types/Dashboard/DashboardComponents/DashboardLogChartComponent.ts +24 -0
  111. package/Types/Dashboard/DashboardTemplates.ts +9 -1
  112. package/Types/LlmLogStatus.ts +1 -0
  113. package/Types/Monitor/CriteriaFilter.ts +9 -0
  114. package/Types/Monitor/HttpPhaseTimings.ts +16 -0
  115. package/Types/Monitor/IotAlertTemplates.ts +22 -3
  116. package/Types/Monitor/LatencyMatrix.ts +27 -0
  117. package/Types/Monitor/MonitorCriteriaInstance.ts +2 -2
  118. package/Types/Monitor/MonitorMetricType.ts +27 -0
  119. package/Types/Monitor/MonitorStep.ts +36 -11
  120. package/Types/Monitor/MonitorStepNetworkDeviceMonitor.ts +55 -0
  121. package/Types/Monitor/MonitorStepSnmpMonitor.ts +8 -0
  122. package/Types/Monitor/MonitorType.ts +14 -9
  123. package/Types/Monitor/PingMonitor/PingMonitorResponse.ts +20 -0
  124. package/Types/Monitor/SnmpMonitor/LldpNeighbor.ts +12 -0
  125. package/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.ts +116 -0
  126. package/Types/Monitor/SnmpMonitor/NetworkTopology.ts +29 -0
  127. package/Types/Monitor/SnmpMonitor/SnmpInterface.ts +31 -0
  128. package/Types/Monitor/SnmpMonitor/SnmpMonitorResponse.ts +24 -0
  129. package/Types/Monitor/SnmpMonitor/SnmpTrap.ts +20 -0
  130. package/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.ts +173 -0
  131. package/Types/Permission.ts +314 -0
  132. package/Types/Probe/ProbeMonitorResponse.ts +22 -0
  133. package/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.tsx +8 -5
  134. package/UI/Components/Charts/ChartLibrary/BarChart/BarChart.tsx +4 -1
  135. package/UI/Components/Charts/ChartLibrary/LineChart/LineChart.tsx +6 -3
  136. package/UI/Components/CodeBlock/CodeBlock.tsx +2 -1
  137. package/UI/Components/CodeEditor/CodeEditor.tsx +3 -0
  138. package/UI/Components/Divider/Divider.tsx +1 -1
  139. package/UI/Components/Dropdown/Dropdown.tsx +13 -4
  140. package/UI/Components/EntityDropdown/EntityDropdown.tsx +110 -2
  141. package/UI/Components/ErrorBoundary.tsx +2 -1
  142. package/UI/Components/EventItem/EventItem.tsx +2 -2
  143. package/UI/Components/GanttChart/Bar/Index.tsx +1 -1
  144. package/UI/Components/Graphs/UptimeBarTooltip.tsx +30 -23
  145. package/UI/Components/Header/Header.tsx +7 -0
  146. package/UI/Components/Header/HeaderIconDropdownButton.tsx +2 -0
  147. package/UI/Components/Icon/Icon.tsx +8 -6
  148. package/UI/Components/Label/Label.tsx +2 -2
  149. package/UI/Components/LogsViewer/components/LogsAnalyticsView.tsx +22 -10
  150. package/UI/Components/LogsViewer/components/LogsHistogram.tsx +9 -3
  151. package/UI/Components/Markdown.tsx/MarkdownEditor.tsx +8 -8
  152. package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +44 -20
  153. package/UI/Components/Modal/ConfirmModal.tsx +1 -1
  154. package/UI/Components/Modal/Modal.tsx +213 -121
  155. package/UI/Components/Modal/ModalFooter.tsx +33 -22
  156. package/UI/Components/ModelTable/TableView.tsx +1 -1
  157. package/UI/Components/MonitorGraphs/UptimeBarDayModal.tsx +20 -12
  158. package/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.ts +2 -2
  159. package/UI/Components/Pill/Pill.tsx +21 -13
  160. package/UI/Components/StatusBubble/StatusBubble.tsx +3 -3
  161. package/UI/Components/Tabs/Tabs.tsx +10 -1
  162. package/UI/Components/TelemetryViewer/TelemetryViewer.tsx +7 -1
  163. package/UI/Components/TelemetryViewer/components/TelemetryHistogram.tsx +9 -3
  164. package/UI/Components/TelemetryViewer/components/TelemetrySearchBar.tsx +62 -4
  165. package/UI/Components/Workflow/Component.tsx +53 -33
  166. package/UI/Components/Workflow/ComponentPortViewer.tsx +6 -6
  167. package/UI/Components/Workflow/ComponentReturnValueViewer.tsx +8 -8
  168. package/UI/Components/Workflow/ComponentsModal.tsx +16 -9
  169. package/UI/Components/Workflow/Workflow.tsx +13 -11
  170. package/UI/Utils/Navigation.ts +10 -1
  171. package/UI/Utils/Theme.ts +140 -0
  172. package/Utils/Dashboard/Components/DashboardLogChartComponent.ts +99 -0
  173. package/Utils/Dashboard/Components/Index.ts +7 -0
  174. package/Utils/Monitor/LatencyMatrixUtil.ts +162 -0
  175. package/Utils/Monitor/MonitorMetricType.ts +141 -3
  176. package/Utils/Monitor/NetworkTopologyUtil.ts +159 -0
  177. package/Utils/Telemetry/EntityRelationship.ts +11 -0
  178. package/build/dist/Models/DatabaseModels/AIRun.js +52 -0
  179. package/build/dist/Models/DatabaseModels/AIRun.js.map +1 -1
  180. package/build/dist/Models/DatabaseModels/AlertSeverity.js +6 -0
  181. package/build/dist/Models/DatabaseModels/AlertSeverity.js.map +1 -1
  182. package/build/dist/Models/DatabaseModels/IncidentSeverity.js +6 -0
  183. package/build/dist/Models/DatabaseModels/IncidentSeverity.js.map +1 -1
  184. package/build/dist/Models/DatabaseModels/Index.js +16 -0
  185. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  186. package/build/dist/Models/DatabaseModels/IoTDeviceCredential.js +493 -0
  187. package/build/dist/Models/DatabaseModels/IoTDeviceCredential.js.map +1 -0
  188. package/build/dist/Models/DatabaseModels/LlmLog.js +58 -0
  189. package/build/dist/Models/DatabaseModels/LlmLog.js.map +1 -1
  190. package/build/dist/Models/DatabaseModels/LlmProvider.js +33 -0
  191. package/build/dist/Models/DatabaseModels/LlmProvider.js.map +1 -1
  192. package/build/dist/Models/DatabaseModels/NetworkDevice.js +1426 -0
  193. package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -0
  194. package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js +738 -0
  195. package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js.map +1 -0
  196. package/build/dist/Models/DatabaseModels/NetworkDeviceLabelRule.js +522 -0
  197. package/build/dist/Models/DatabaseModels/NetworkDeviceLabelRule.js.map +1 -0
  198. package/build/dist/Models/DatabaseModels/NetworkDeviceOwnerRule.js +603 -0
  199. package/build/dist/Models/DatabaseModels/NetworkDeviceOwnerRule.js.map +1 -0
  200. package/build/dist/Models/DatabaseModels/NetworkDeviceOwnerTeam.js +503 -0
  201. package/build/dist/Models/DatabaseModels/NetworkDeviceOwnerTeam.js.map +1 -0
  202. package/build/dist/Models/DatabaseModels/NetworkDeviceOwnerUser.js +502 -0
  203. package/build/dist/Models/DatabaseModels/NetworkDeviceOwnerUser.js.map +1 -0
  204. package/build/dist/Models/DatabaseModels/NetworkInterface.js +589 -0
  205. package/build/dist/Models/DatabaseModels/NetworkInterface.js.map +1 -0
  206. package/build/dist/Models/DatabaseModels/Project.js +147 -0
  207. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  208. package/build/dist/Models/DatabaseModels/TelemetryEntityRelationship.js +57 -0
  209. package/build/dist/Models/DatabaseModels/TelemetryEntityRelationship.js.map +1 -1
  210. package/build/dist/Server/API/AIAgentTaskAPI.js +8 -23
  211. package/build/dist/Server/API/AIAgentTaskAPI.js.map +1 -1
  212. package/build/dist/Server/API/AIInvestigationAPI.js +95 -55
  213. package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
  214. package/build/dist/Server/API/AlertAPI.js +5 -0
  215. package/build/dist/Server/API/AlertAPI.js.map +1 -1
  216. package/build/dist/Server/API/IncidentAPI.js +10 -0
  217. package/build/dist/Server/API/IncidentAPI.js.map +1 -1
  218. package/build/dist/Server/API/IncidentEpisodeAPI.js +5 -0
  219. package/build/dist/Server/API/IncidentEpisodeAPI.js.map +1 -1
  220. package/build/dist/Server/API/LlmProviderAPI.js +5 -7
  221. package/build/dist/Server/API/LlmProviderAPI.js.map +1 -1
  222. package/build/dist/Server/API/ScheduledMaintenanceAPI.js +5 -0
  223. package/build/dist/Server/API/ScheduledMaintenanceAPI.js.map +1 -1
  224. package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
  225. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783650000000-AddAdditionalParamsToLlmProvider.js +12 -0
  226. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783650000000-AddAdditionalParamsToLlmProvider.js.map +1 -0
  227. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783695782697-AddCacheTokenColumnsToLlmLog.js +14 -0
  228. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783695782697-AddCacheTokenColumnsToLlmLog.js.map +1 -0
  229. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783701585317-AddAlertInvestigationGating.js +18 -0
  230. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783701585317-AddAlertInvestigationGating.js.map +1 -0
  231. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783702431535-AddAiDailyAutonomousTokenLimitToProject.js +12 -0
  232. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783702431535-AddAiDailyAutonomousTokenLimitToProject.js.map +1 -0
  233. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783720000000-AddNetworkDeviceTables.js +51 -0
  234. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783720000000-AddNetworkDeviceTables.js.map +1 -0
  235. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783721121260-AddAttemptCountToAIRun.js +12 -0
  236. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783721121260-AddAttemptCountToAIRun.js.map +1 -0
  237. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783730000000-AddNetworkDeviceOwnersAndRules.js +101 -0
  238. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783730000000-AddNetworkDeviceOwnersAndRules.js.map +1 -0
  239. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783740000000-AddNetworkDeviceDiscoveryScan.js +18 -0
  240. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783740000000-AddNetworkDeviceDiscoveryScan.js.map +1 -0
  241. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783750000000-AddLldpNeighborsToNetworkDevice.js +12 -0
  242. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783750000000-AddLldpNeighborsToNetworkDevice.js.map +1 -0
  243. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783760576655-AddInvestigationTuningToProject.js +14 -0
  244. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783760576655-AddInvestigationTuningToProject.js.map +1 -0
  245. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783762505482-AddTelemetryEntityRelationshipMetrics.js +16 -0
  246. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783762505482-AddTelemetryEntityRelationshipMetrics.js.map +1 -0
  247. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783780000000-AddIoTDeviceCredentialTable.js +38 -0
  248. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783780000000-AddIoTDeviceCredentialTable.js.map +1 -0
  249. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783790000000-AddSnmpV3AuthColumnsToNetworkDevice.js +22 -0
  250. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1783790000000-AddSnmpV3AuthColumnsToNetworkDevice.js.map +1 -0
  251. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +24 -0
  252. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  253. package/build/dist/Server/Services/AIAgentTaskService.js +59 -0
  254. package/build/dist/Server/Services/AIAgentTaskService.js.map +1 -1
  255. package/build/dist/Server/Services/AIRunService.js +33 -0
  256. package/build/dist/Server/Services/AIRunService.js.map +1 -1
  257. package/build/dist/Server/Services/AIService.js +82 -9
  258. package/build/dist/Server/Services/AIService.js.map +1 -1
  259. package/build/dist/Server/Services/AnalyticsDatabaseService.js +19 -0
  260. package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
  261. package/build/dist/Server/Services/IncidentService.js +14 -25
  262. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  263. package/build/dist/Server/Services/Index.js +14 -0
  264. package/build/dist/Server/Services/Index.js.map +1 -1
  265. package/build/dist/Server/Services/IoTDeviceCredentialService.js +321 -0
  266. package/build/dist/Server/Services/IoTDeviceCredentialService.js.map +1 -0
  267. package/build/dist/Server/Services/IoTDeviceService.js +49 -15
  268. package/build/dist/Server/Services/IoTDeviceService.js.map +1 -1
  269. package/build/dist/Server/Services/LlmLogService.js +29 -0
  270. package/build/dist/Server/Services/LlmLogService.js.map +1 -1
  271. package/build/dist/Server/Services/LlmProviderService.js +3 -0
  272. package/build/dist/Server/Services/LlmProviderService.js.map +1 -1
  273. package/build/dist/Server/Services/LogAggregationService.js +21 -7
  274. package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
  275. package/build/dist/Server/Services/MetricService.js +449 -7
  276. package/build/dist/Server/Services/MetricService.js.map +1 -1
  277. package/build/dist/Server/Services/MonitorService.js +2 -1
  278. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  279. package/build/dist/Server/Services/NetworkDeviceDiscoveryScanService.js +9 -0
  280. package/build/dist/Server/Services/NetworkDeviceDiscoveryScanService.js.map +1 -0
  281. package/build/dist/Server/Services/NetworkDeviceLabelRuleEngineService.js +166 -0
  282. package/build/dist/Server/Services/NetworkDeviceLabelRuleEngineService.js.map +1 -0
  283. package/build/dist/Server/Services/NetworkDeviceLabelRuleService.js +13 -0
  284. package/build/dist/Server/Services/NetworkDeviceLabelRuleService.js.map +1 -0
  285. package/build/dist/Server/Services/NetworkDeviceOwnerRuleEngineService.js +186 -0
  286. package/build/dist/Server/Services/NetworkDeviceOwnerRuleEngineService.js.map +1 -0
  287. package/build/dist/Server/Services/NetworkDeviceOwnerRuleService.js +13 -0
  288. package/build/dist/Server/Services/NetworkDeviceOwnerRuleService.js.map +1 -0
  289. package/build/dist/Server/Services/NetworkDeviceOwnerTeamService.js +9 -0
  290. package/build/dist/Server/Services/NetworkDeviceOwnerTeamService.js.map +1 -0
  291. package/build/dist/Server/Services/NetworkDeviceOwnerUserService.js +9 -0
  292. package/build/dist/Server/Services/NetworkDeviceOwnerUserService.js.map +1 -0
  293. package/build/dist/Server/Services/NetworkDeviceService.js +52 -0
  294. package/build/dist/Server/Services/NetworkDeviceService.js.map +1 -0
  295. package/build/dist/Server/Services/NetworkInterfaceService.js +9 -0
  296. package/build/dist/Server/Services/NetworkInterfaceService.js.map +1 -0
  297. package/build/dist/Server/Services/TelemetryEntityRelationshipService.js +22 -0
  298. package/build/dist/Server/Services/TelemetryEntityRelationshipService.js.map +1 -1
  299. package/build/dist/Server/Services/TelemetryEntityService.js +64 -2
  300. package/build/dist/Server/Services/TelemetryEntityService.js.map +1 -1
  301. package/build/dist/Server/Utils/AI/Sentinel/AlertInvestigationRunner.js +189 -9
  302. package/build/dist/Server/Utils/AI/Sentinel/AlertInvestigationRunner.js.map +1 -1
  303. package/build/dist/Server/Utils/AI/Sentinel/IncidentInvestigationRunner.js +84 -17
  304. package/build/dist/Server/Utils/AI/Sentinel/IncidentInvestigationRunner.js.map +1 -1
  305. package/build/dist/Server/Utils/AI/Sentinel/InvestigationQueue.js +428 -0
  306. package/build/dist/Server/Utils/AI/Sentinel/InvestigationQueue.js.map +1 -0
  307. package/build/dist/Server/Utils/AI/Sentinel/SentinelInvestigationEngine.js +63 -47
  308. package/build/dist/Server/Utils/AI/Sentinel/SentinelInvestigationEngine.js.map +1 -1
  309. package/build/dist/Server/Utils/AI/Toolbox/Index.js +2 -1
  310. package/build/dist/Server/Utils/AI/Toolbox/Index.js.map +1 -1
  311. package/build/dist/Server/Utils/AI/Toolbox/MetricTools.js +300 -0
  312. package/build/dist/Server/Utils/AI/Toolbox/MetricTools.js.map +1 -1
  313. package/build/dist/Server/Utils/LLM/LLMService.js +16 -0
  314. package/build/dist/Server/Utils/LLM/LLMService.js.map +1 -1
  315. package/build/dist/Server/Utils/Monitor/Criteria/APIRequestCriteria.js +29 -0
  316. package/build/dist/Server/Utils/Monitor/Criteria/APIRequestCriteria.js.map +1 -1
  317. package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js +130 -2
  318. package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js.map +1 -1
  319. package/build/dist/Server/Utils/Monitor/IoTDeviceAbsenceSeries.js +81 -0
  320. package/build/dist/Server/Utils/Monitor/IoTDeviceAbsenceSeries.js.map +1 -0
  321. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +18 -7
  322. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
  323. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +1 -1
  324. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  325. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +25 -10
  326. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
  327. package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js +155 -5
  328. package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js.map +1 -1
  329. package/build/dist/Server/Utils/Monitor/MonitorResource.js +76 -30
  330. package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
  331. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js +1 -1
  332. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js.map +1 -1
  333. package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js +147 -0
  334. package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js.map +1 -0
  335. package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js +167 -0
  336. package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js.map +1 -0
  337. package/build/dist/Server/Utils/Monitor/SnmpInterfaceRateUtil.js +93 -0
  338. package/build/dist/Server/Utils/Monitor/SnmpInterfaceRateUtil.js.map +1 -0
  339. package/build/dist/Types/AI/AIRunStatus.js +9 -0
  340. package/build/dist/Types/AI/AIRunStatus.js.map +1 -1
  341. package/build/dist/Types/Dashboard/DashboardComponentType.js +1 -0
  342. package/build/dist/Types/Dashboard/DashboardComponentType.js.map +1 -1
  343. package/build/dist/Types/Dashboard/DashboardComponents/DashboardLogChartComponent.js +2 -0
  344. package/build/dist/Types/Dashboard/DashboardComponents/DashboardLogChartComponent.js.map +1 -0
  345. package/build/dist/Types/Dashboard/DashboardTemplates.js +9 -1
  346. package/build/dist/Types/Dashboard/DashboardTemplates.js.map +1 -1
  347. package/build/dist/Types/LlmLogStatus.js +1 -0
  348. package/build/dist/Types/LlmLogStatus.js.map +1 -1
  349. package/build/dist/Types/Monitor/CriteriaFilter.js +9 -0
  350. package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
  351. package/build/dist/Types/Monitor/HttpPhaseTimings.js +2 -0
  352. package/build/dist/Types/Monitor/HttpPhaseTimings.js.map +1 -0
  353. package/build/dist/Types/Monitor/IotAlertTemplates.js +7 -7
  354. package/build/dist/Types/Monitor/IotAlertTemplates.js.map +1 -1
  355. package/build/dist/Types/Monitor/LatencyMatrix.js +2 -0
  356. package/build/dist/Types/Monitor/LatencyMatrix.js.map +1 -0
  357. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +2 -2
  358. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
  359. package/build/dist/Types/Monitor/MonitorMetricType.js +24 -0
  360. package/build/dist/Types/Monitor/MonitorMetricType.js.map +1 -1
  361. package/build/dist/Types/Monitor/MonitorStep.js +22 -9
  362. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  363. package/build/dist/Types/Monitor/MonitorStepNetworkDeviceMonitor.js +36 -0
  364. package/build/dist/Types/Monitor/MonitorStepNetworkDeviceMonitor.js.map +1 -0
  365. package/build/dist/Types/Monitor/MonitorStepSnmpMonitor.js +3 -0
  366. package/build/dist/Types/Monitor/MonitorStepSnmpMonitor.js.map +1 -1
  367. package/build/dist/Types/Monitor/MonitorType.js +14 -9
  368. package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
  369. package/build/dist/Types/Monitor/PingMonitor/PingMonitorResponse.js +2 -0
  370. package/build/dist/Types/Monitor/PingMonitor/PingMonitorResponse.js.map +1 -0
  371. package/build/dist/Types/Monitor/SnmpMonitor/LldpNeighbor.js +2 -0
  372. package/build/dist/Types/Monitor/SnmpMonitor/LldpNeighbor.js.map +1 -0
  373. package/build/dist/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.js +89 -0
  374. package/build/dist/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.js.map +1 -0
  375. package/build/dist/Types/Monitor/SnmpMonitor/NetworkTopology.js +2 -0
  376. package/build/dist/Types/Monitor/SnmpMonitor/NetworkTopology.js.map +1 -0
  377. package/build/dist/Types/Monitor/SnmpMonitor/SnmpInterface.js +2 -0
  378. package/build/dist/Types/Monitor/SnmpMonitor/SnmpInterface.js.map +1 -0
  379. package/build/dist/Types/Monitor/SnmpMonitor/SnmpTrap.js +2 -0
  380. package/build/dist/Types/Monitor/SnmpMonitor/SnmpTrap.js.map +1 -0
  381. package/build/dist/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.js +137 -0
  382. package/build/dist/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.js.map +1 -0
  383. package/build/dist/Types/Permission.js +280 -0
  384. package/build/dist/Types/Permission.js.map +1 -1
  385. package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js +7 -4
  386. package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js.map +1 -1
  387. package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js +4 -1
  388. package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js.map +1 -1
  389. package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js +6 -3
  390. package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js.map +1 -1
  391. package/build/dist/UI/Components/CodeBlock/CodeBlock.js +1 -1
  392. package/build/dist/UI/Components/CodeBlock/CodeBlock.js.map +1 -1
  393. package/build/dist/UI/Components/CodeEditor/CodeEditor.js +3 -1
  394. package/build/dist/UI/Components/CodeEditor/CodeEditor.js.map +1 -1
  395. package/build/dist/UI/Components/Divider/Divider.js +1 -1
  396. package/build/dist/UI/Components/Divider/Divider.js.map +1 -1
  397. package/build/dist/UI/Components/Dropdown/Dropdown.js +10 -4
  398. package/build/dist/UI/Components/Dropdown/Dropdown.js.map +1 -1
  399. package/build/dist/UI/Components/EntityDropdown/EntityDropdown.js +76 -3
  400. package/build/dist/UI/Components/EntityDropdown/EntityDropdown.js.map +1 -1
  401. package/build/dist/UI/Components/ErrorBoundary.js +2 -1
  402. package/build/dist/UI/Components/ErrorBoundary.js.map +1 -1
  403. package/build/dist/UI/Components/EventItem/EventItem.js +2 -2
  404. package/build/dist/UI/Components/EventItem/EventItem.js.map +1 -1
  405. package/build/dist/UI/Components/GanttChart/Bar/Index.js +1 -1
  406. package/build/dist/UI/Components/GanttChart/Bar/Index.js.map +1 -1
  407. package/build/dist/UI/Components/Graphs/UptimeBarTooltip.js +29 -23
  408. package/build/dist/UI/Components/Graphs/UptimeBarTooltip.js.map +1 -1
  409. package/build/dist/UI/Components/Header/Header.js +1 -0
  410. package/build/dist/UI/Components/Header/Header.js.map +1 -1
  411. package/build/dist/UI/Components/Header/HeaderIconDropdownButton.js +1 -1
  412. package/build/dist/UI/Components/Header/HeaderIconDropdownButton.js.map +1 -1
  413. package/build/dist/UI/Components/Icon/Icon.js +8 -6
  414. package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
  415. package/build/dist/UI/Components/Label/Label.js +2 -2
  416. package/build/dist/UI/Components/Label/Label.js.map +1 -1
  417. package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js +20 -8
  418. package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js.map +1 -1
  419. package/build/dist/UI/Components/LogsViewer/components/LogsHistogram.js +8 -2
  420. package/build/dist/UI/Components/LogsViewer/components/LogsHistogram.js.map +1 -1
  421. package/build/dist/UI/Components/Markdown.tsx/MarkdownEditor.js +8 -8
  422. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +40 -20
  423. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
  424. package/build/dist/UI/Components/Modal/ConfirmModal.js +1 -1
  425. package/build/dist/UI/Components/Modal/ConfirmModal.js.map +1 -1
  426. package/build/dist/UI/Components/Modal/Modal.js +109 -51
  427. package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
  428. package/build/dist/UI/Components/Modal/ModalFooter.js +13 -10
  429. package/build/dist/UI/Components/Modal/ModalFooter.js.map +1 -1
  430. package/build/dist/UI/Components/ModelTable/TableView.js +1 -1
  431. package/build/dist/UI/Components/ModelTable/TableView.js.map +1 -1
  432. package/build/dist/UI/Components/MonitorGraphs/UptimeBarDayModal.js +17 -12
  433. package/build/dist/UI/Components/MonitorGraphs/UptimeBarDayModal.js.map +1 -1
  434. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js +2 -2
  435. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js.map +1 -1
  436. package/build/dist/UI/Components/Pill/Pill.js +12 -13
  437. package/build/dist/UI/Components/Pill/Pill.js.map +1 -1
  438. package/build/dist/UI/Components/StatusBubble/StatusBubble.js +3 -3
  439. package/build/dist/UI/Components/StatusBubble/StatusBubble.js.map +1 -1
  440. package/build/dist/UI/Components/Tabs/Tabs.js +3 -1
  441. package/build/dist/UI/Components/Tabs/Tabs.js.map +1 -1
  442. package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js +1 -1
  443. package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js.map +1 -1
  444. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js +8 -2
  445. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js.map +1 -1
  446. package/build/dist/UI/Components/TelemetryViewer/components/TelemetrySearchBar.js +36 -6
  447. package/build/dist/UI/Components/TelemetryViewer/components/TelemetrySearchBar.js.map +1 -1
  448. package/build/dist/UI/Components/Workflow/Component.js +43 -33
  449. package/build/dist/UI/Components/Workflow/Component.js.map +1 -1
  450. package/build/dist/UI/Components/Workflow/ComponentPortViewer.js +6 -6
  451. package/build/dist/UI/Components/Workflow/ComponentPortViewer.js.map +1 -1
  452. package/build/dist/UI/Components/Workflow/ComponentReturnValueViewer.js +8 -8
  453. package/build/dist/UI/Components/Workflow/ComponentReturnValueViewer.js.map +1 -1
  454. package/build/dist/UI/Components/Workflow/ComponentsModal.js +15 -9
  455. package/build/dist/UI/Components/Workflow/ComponentsModal.js.map +1 -1
  456. package/build/dist/UI/Components/Workflow/Workflow.js +13 -11
  457. package/build/dist/UI/Components/Workflow/Workflow.js.map +1 -1
  458. package/build/dist/UI/Utils/Navigation.js +11 -1
  459. package/build/dist/UI/Utils/Navigation.js.map +1 -1
  460. package/build/dist/UI/Utils/Theme.js +106 -0
  461. package/build/dist/UI/Utils/Theme.js.map +1 -0
  462. package/build/dist/Utils/Dashboard/Components/DashboardLogChartComponent.js +89 -0
  463. package/build/dist/Utils/Dashboard/Components/DashboardLogChartComponent.js.map +1 -0
  464. package/build/dist/Utils/Dashboard/Components/Index.js +4 -0
  465. package/build/dist/Utils/Dashboard/Components/Index.js.map +1 -1
  466. package/build/dist/Utils/Monitor/LatencyMatrixUtil.js +89 -0
  467. package/build/dist/Utils/Monitor/LatencyMatrixUtil.js.map +1 -0
  468. package/build/dist/Utils/Monitor/MonitorMetricType.js +138 -4
  469. package/build/dist/Utils/Monitor/MonitorMetricType.js.map +1 -1
  470. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +112 -0
  471. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -0
  472. package/build/dist/Utils/Telemetry/EntityRelationship.js.map +1 -1
  473. package/package.json +1 -1
@@ -0,0 +1,169 @@
1
+ import { JSONObject } from "../../../Types/JSON";
2
+ import SnmpInterface from "../../../Types/Monitor/SnmpMonitor/SnmpInterface";
3
+ import ProbeMonitorResponse from "../../../Types/Probe/ProbeMonitorResponse";
4
+ import OneUptimeDate from "../../../Types/Date";
5
+ import logger from "../Logger";
6
+
7
+ /*
8
+ * Computes per-interface rates (bandwidth, utilization, errors) for SNMP
9
+ * monitors by comparing the cumulative IF-MIB counters of the current check
10
+ * against the previous check stored in MonitorProbe.lastMonitoringLog.
11
+ *
12
+ * Probes stay stateless — the delta is computed here, on ingest, before the
13
+ * response is persisted. Negative deltas (counter wrap or device reboot) are
14
+ * skipped for that interface; rates resume on the following check.
15
+ */
16
+ export default class SnmpInterfaceRateUtil {
17
+ public static attachInterfaceRates(data: {
18
+ probeMonitorResponse: ProbeMonitorResponse;
19
+ previousStepLog: JSONObject | undefined;
20
+ }): void {
21
+ const interfaces: Array<SnmpInterface> | undefined =
22
+ data.probeMonitorResponse.snmpResponse?.interfaces;
23
+
24
+ if (!interfaces || interfaces.length === 0) {
25
+ return;
26
+ }
27
+
28
+ if (!data.previousStepLog) {
29
+ return;
30
+ }
31
+
32
+ const previousSnmpResponse: JSONObject | undefined = data.previousStepLog[
33
+ "snmpResponse"
34
+ ] as JSONObject | undefined;
35
+
36
+ const previousInterfaces: Array<JSONObject> | undefined =
37
+ previousSnmpResponse?.["interfaces"] as Array<JSONObject> | undefined;
38
+
39
+ const previousMonitoredAtValue: unknown =
40
+ data.previousStepLog["monitoredAt"];
41
+
42
+ if (
43
+ !previousInterfaces ||
44
+ previousInterfaces.length === 0 ||
45
+ !previousMonitoredAtValue
46
+ ) {
47
+ return;
48
+ }
49
+
50
+ const previousMonitoredAt: Date = new Date(
51
+ previousMonitoredAtValue as string,
52
+ );
53
+
54
+ if (isNaN(previousMonitoredAt.getTime())) {
55
+ return;
56
+ }
57
+
58
+ /*
59
+ * lastMonitoringLog stores server receipt time as monitoredAt, so the
60
+ * current side of the delta uses server time too.
61
+ */
62
+ const elapsedSeconds: number =
63
+ (OneUptimeDate.getCurrentDate().getTime() -
64
+ previousMonitoredAt.getTime()) /
65
+ 1000;
66
+
67
+ if (elapsedSeconds <= 0) {
68
+ return;
69
+ }
70
+
71
+ const counterDelta: (
72
+ currentValue: number | undefined,
73
+ previousValue: unknown,
74
+ ) => number | undefined = (
75
+ currentValue: number | undefined,
76
+ previousValue: unknown,
77
+ ) => {
78
+ if (
79
+ currentValue === undefined ||
80
+ typeof previousValue !== "number" ||
81
+ !isFinite(previousValue)
82
+ ) {
83
+ return undefined;
84
+ }
85
+
86
+ const delta: number = currentValue - previousValue;
87
+
88
+ // Negative delta: counter wrapped or the device rebooted.
89
+ return delta >= 0 ? delta : undefined;
90
+ };
91
+
92
+ const round: (value: number) => number = (value: number) => {
93
+ return Math.round(value * 100) / 100;
94
+ };
95
+
96
+ const previousByIndex: Map<number, JSONObject> = new Map();
97
+ for (const previousInterface of previousInterfaces) {
98
+ const index: unknown = previousInterface["interfaceIndex"];
99
+ if (typeof index === "number") {
100
+ previousByIndex.set(index, previousInterface);
101
+ }
102
+ }
103
+
104
+ for (const currentInterface of interfaces) {
105
+ const previousInterface: JSONObject | undefined = previousByIndex.get(
106
+ currentInterface.interfaceIndex,
107
+ );
108
+
109
+ if (!previousInterface) {
110
+ continue;
111
+ }
112
+
113
+ const inOctetsDelta: number | undefined = counterDelta(
114
+ currentInterface.inOctets,
115
+ previousInterface["inOctets"],
116
+ );
117
+ const outOctetsDelta: number | undefined = counterDelta(
118
+ currentInterface.outOctets,
119
+ previousInterface["outOctets"],
120
+ );
121
+
122
+ if (inOctetsDelta !== undefined) {
123
+ currentInterface.inBitsPerSecond = round(
124
+ (inOctetsDelta * 8) / elapsedSeconds,
125
+ );
126
+ }
127
+
128
+ if (outOctetsDelta !== undefined) {
129
+ currentInterface.outBitsPerSecond = round(
130
+ (outOctetsDelta * 8) / elapsedSeconds,
131
+ );
132
+ }
133
+
134
+ if (
135
+ currentInterface.speedInBitsPerSecond &&
136
+ currentInterface.speedInBitsPerSecond > 0 &&
137
+ (currentInterface.inBitsPerSecond !== undefined ||
138
+ currentInterface.outBitsPerSecond !== undefined)
139
+ ) {
140
+ const busiestDirectionBps: number = Math.max(
141
+ currentInterface.inBitsPerSecond || 0,
142
+ currentInterface.outBitsPerSecond || 0,
143
+ );
144
+ currentInterface.utilizationPercent = round(
145
+ (busiestDirectionBps / currentInterface.speedInBitsPerSecond) * 100,
146
+ );
147
+ }
148
+
149
+ const inErrorsDelta: number | undefined = counterDelta(
150
+ currentInterface.inErrors,
151
+ previousInterface["inErrors"],
152
+ );
153
+ const outErrorsDelta: number | undefined = counterDelta(
154
+ currentInterface.outErrors,
155
+ previousInterface["outErrors"],
156
+ );
157
+
158
+ if (inErrorsDelta !== undefined || outErrorsDelta !== undefined) {
159
+ currentInterface.errorsPerSecond = round(
160
+ ((inErrorsDelta || 0) + (outErrorsDelta || 0)) / elapsedSeconds,
161
+ );
162
+ }
163
+ }
164
+
165
+ logger.debug(
166
+ `Attached SNMP interface rates for monitor ${data.probeMonitorResponse.monitorId.toString()} over ${round(elapsedSeconds)}s window`,
167
+ );
168
+ }
169
+ }
@@ -0,0 +1,146 @@
1
+ import AIAgentTaskService from "../../../Server/Services/AIAgentTaskService";
2
+ import Model from "../../../Models/DatabaseModels/AIAgentTask";
3
+ import AIAgentTaskStatus from "../../../Types/AI/AIAgentTaskStatus";
4
+ import ObjectID from "../../../Types/ObjectID";
5
+ import { describe, expect, test, afterEach } from "@jest/globals";
6
+
7
+ /*
8
+ * claimNextScheduledTask is the atomic-claim fix for the get-pending-task
9
+ * double-processing race: multiple KEDA-scaled AIAgent workers poll the same
10
+ * endpoint, and the old plain findOneBy returned the oldest Scheduled task
11
+ * without mutating it, so two workers could both receive — and both execute —
12
+ * the same task.
13
+ *
14
+ * The claim collapses the read-then-take into findOneBy + a status-guarded
15
+ * updateOneBy (Scheduled -> InProgress). updateOneBy returns the number of
16
+ * rows changed: 1 means this caller won the claim; 0 means another worker
17
+ * already took the task, and the loop retries with the next candidate.
18
+ *
19
+ * These tests mock the two inherited persistence helpers (no Postgres) to
20
+ * lock in:
21
+ * (a) a won claim returns the task, with the guard and the InProgress
22
+ * transition on the exact row that was read;
23
+ * (b) a lost claim (0 rows) is never returned — the loop moves to the
24
+ * next candidate;
25
+ * (c) no Scheduled tasks => null, with no write at all;
26
+ * (d) the retry loop is bounded, so a pathological all-losses storm
27
+ * terminates.
28
+ */
29
+
30
+ function fakeTask(id: ObjectID): Model {
31
+ return {
32
+ id,
33
+ _id: id.toString(),
34
+ projectId: ObjectID.generate(),
35
+ taskType: "FixException",
36
+ } as unknown as Model;
37
+ }
38
+
39
+ describe("AIAgentTaskService.claimNextScheduledTask", () => {
40
+ const aiAgentId: ObjectID = ObjectID.generate();
41
+
42
+ afterEach(() => {
43
+ jest.restoreAllMocks();
44
+ });
45
+
46
+ test("returns the task when the claim wins, guarding on Scheduled status", async () => {
47
+ const task: Model = fakeTask(ObjectID.generate());
48
+
49
+ const findOneBy: jest.SpyInstance = jest
50
+ .spyOn(AIAgentTaskService, "findOneBy")
51
+ .mockResolvedValue(task);
52
+ const updateOneBy: jest.SpyInstance = jest
53
+ .spyOn(AIAgentTaskService, "updateOneBy")
54
+ .mockResolvedValue(1);
55
+
56
+ const claimed: Model | null =
57
+ await AIAgentTaskService.claimNextScheduledTask({
58
+ aiAgentId: aiAgentId,
59
+ });
60
+
61
+ expect(claimed).toBe(task);
62
+ expect(findOneBy).toHaveBeenCalledTimes(1);
63
+ expect(findOneBy).toHaveBeenCalledWith(
64
+ expect.objectContaining({
65
+ query: { status: AIAgentTaskStatus.Scheduled },
66
+ }),
67
+ );
68
+ expect(updateOneBy).toHaveBeenCalledTimes(1);
69
+ expect(updateOneBy).toHaveBeenCalledWith(
70
+ expect.objectContaining({
71
+ query: {
72
+ _id: task.id!.toString(),
73
+ status: AIAgentTaskStatus.Scheduled,
74
+ },
75
+ data: expect.objectContaining({
76
+ status: AIAgentTaskStatus.InProgress,
77
+ aiAgentId: aiAgentId,
78
+ startedAt: expect.any(Date),
79
+ }),
80
+ }),
81
+ );
82
+ });
83
+
84
+ test("retries with the next candidate when another worker wins the race", async () => {
85
+ const lostTask: Model = fakeTask(ObjectID.generate());
86
+ const wonTask: Model = fakeTask(ObjectID.generate());
87
+
88
+ const findOneBy: jest.SpyInstance = jest
89
+ .spyOn(AIAgentTaskService, "findOneBy")
90
+ .mockResolvedValueOnce(lostTask)
91
+ .mockResolvedValueOnce(wonTask);
92
+ const updateOneBy: jest.SpyInstance = jest
93
+ .spyOn(AIAgentTaskService, "updateOneBy")
94
+ .mockResolvedValueOnce(0)
95
+ .mockResolvedValueOnce(1);
96
+
97
+ const claimed: Model | null =
98
+ await AIAgentTaskService.claimNextScheduledTask({
99
+ aiAgentId: aiAgentId,
100
+ });
101
+
102
+ expect(claimed).toBe(wonTask);
103
+ expect(findOneBy).toHaveBeenCalledTimes(2);
104
+ expect(updateOneBy).toHaveBeenCalledTimes(2);
105
+ expect(updateOneBy).toHaveBeenLastCalledWith(
106
+ expect.objectContaining({
107
+ query: {
108
+ _id: wonTask.id!.toString(),
109
+ status: AIAgentTaskStatus.Scheduled,
110
+ },
111
+ }),
112
+ );
113
+ });
114
+
115
+ test("returns null without writing when no Scheduled task exists", async () => {
116
+ jest.spyOn(AIAgentTaskService, "findOneBy").mockResolvedValue(null);
117
+ const updateOneBy: jest.SpyInstance = jest
118
+ .spyOn(AIAgentTaskService, "updateOneBy")
119
+ .mockResolvedValue(1);
120
+
121
+ const claimed: Model | null =
122
+ await AIAgentTaskService.claimNextScheduledTask({
123
+ aiAgentId: aiAgentId,
124
+ });
125
+
126
+ expect(claimed).toBeNull();
127
+ expect(updateOneBy).not.toHaveBeenCalled();
128
+ });
129
+
130
+ test("gives up after a bounded number of lost claims", async () => {
131
+ const findOneBy: jest.SpyInstance = jest
132
+ .spyOn(AIAgentTaskService, "findOneBy")
133
+ .mockImplementation(async () => {
134
+ return fakeTask(ObjectID.generate());
135
+ });
136
+ jest.spyOn(AIAgentTaskService, "updateOneBy").mockResolvedValue(0);
137
+
138
+ const claimed: Model | null =
139
+ await AIAgentTaskService.claimNextScheduledTask({
140
+ aiAgentId: aiAgentId,
141
+ });
142
+
143
+ expect(claimed).toBeNull();
144
+ expect(findOneBy).toHaveBeenCalledTimes(5);
145
+ });
146
+ });
@@ -0,0 +1,173 @@
1
+ import AIService, {
2
+ AUTONOMOUS_AI_FEATURES,
3
+ AutonomousBudgetStatus,
4
+ } from "../../../Server/Services/AIService";
5
+ import SentinelInvestigationQueue from "../../../Server/Utils/AI/Sentinel/InvestigationQueue";
6
+ import LlmLogService from "../../../Server/Services/LlmLogService";
7
+ import ProjectService from "../../../Server/Services/ProjectService";
8
+ import AIRunService from "../../../Server/Services/AIRunService";
9
+ import Project from "../../../Models/DatabaseModels/Project";
10
+ import ObjectID from "../../../Types/ObjectID";
11
+ import PositiveNumber from "../../../Types/PositiveNumber";
12
+ import { describe, expect, test, afterEach } from "@jest/globals";
13
+
14
+ /*
15
+ * G4 daily budget: Project.aiDailyAutonomousTokenLimit bounds the tokens the
16
+ * AUTONOMOUS_AI_FEATURES may consume per UTC day. The engine skips new
17
+ * investigations quietly when the budget is exhausted (no Error run created);
18
+ * AIService.executeWithLogging is the hard backstop mid-run. Interactive chat
19
+ * is never blocked — its features are not in AUTONOMOUS_AI_FEATURES.
20
+ *
21
+ * These tests mock the persistence layer and lock in:
22
+ * (a) no limit configured => never exhausted, and no usage query is run;
23
+ * (b) usage below the limit => not exhausted;
24
+ * (c) usage at/over the limit => exhausted, with the numbers reported;
25
+ * (d) the engine skips run creation when the budget is exhausted.
26
+ */
27
+
28
+ function fakeProject(limit: number | undefined): Project {
29
+ return {
30
+ id: ObjectID.generate(),
31
+ aiDailyAutonomousTokenLimit: limit,
32
+ } as unknown as Project;
33
+ }
34
+
35
+ describe("AIService.getAutonomousDailyBudgetStatus", () => {
36
+ const projectId: ObjectID = ObjectID.generate();
37
+
38
+ afterEach(() => {
39
+ jest.restoreAllMocks();
40
+ });
41
+
42
+ test("no configured limit means never exhausted and no usage query", async () => {
43
+ jest
44
+ .spyOn(ProjectService, "findOneById")
45
+ .mockResolvedValue(fakeProject(undefined));
46
+ const getTokens: jest.SpyInstance = jest.spyOn(
47
+ LlmLogService,
48
+ "getTotalTokensUsedSince",
49
+ );
50
+
51
+ const status: AutonomousBudgetStatus =
52
+ await AIService.getAutonomousDailyBudgetStatus(projectId);
53
+
54
+ expect(status.exhausted).toBe(false);
55
+ expect(status.limitInTokens).toBeNull();
56
+ expect(getTokens).not.toHaveBeenCalled();
57
+ });
58
+
59
+ test("a limit of 0 pauses autonomous runs without querying usage", async () => {
60
+ jest.spyOn(ProjectService, "findOneById").mockResolvedValue(fakeProject(0));
61
+ const getTokens: jest.SpyInstance = jest.spyOn(
62
+ LlmLogService,
63
+ "getTotalTokensUsedSince",
64
+ );
65
+
66
+ const status: AutonomousBudgetStatus =
67
+ await AIService.getAutonomousDailyBudgetStatus(projectId);
68
+
69
+ expect(status.exhausted).toBe(true);
70
+ expect(status.limitInTokens).toBe(0);
71
+ expect(getTokens).not.toHaveBeenCalled();
72
+ });
73
+
74
+ test("usage below the limit is not exhausted", async () => {
75
+ jest
76
+ .spyOn(ProjectService, "findOneById")
77
+ .mockResolvedValue(fakeProject(100_000));
78
+ jest
79
+ .spyOn(LlmLogService, "getTotalTokensUsedSince")
80
+ .mockResolvedValue(99_999);
81
+
82
+ const status: AutonomousBudgetStatus =
83
+ await AIService.getAutonomousDailyBudgetStatus(projectId);
84
+
85
+ expect(status.exhausted).toBe(false);
86
+ expect(status.limitInTokens).toBe(100_000);
87
+ expect(status.usedTokensToday).toBe(99_999);
88
+ });
89
+
90
+ test("usage at the limit is exhausted, scoped to autonomous features", async () => {
91
+ jest
92
+ .spyOn(ProjectService, "findOneById")
93
+ .mockResolvedValue(fakeProject(100_000));
94
+ const getTokens: jest.SpyInstance = jest
95
+ .spyOn(LlmLogService, "getTotalTokensUsedSince")
96
+ .mockResolvedValue(100_000);
97
+
98
+ const status: AutonomousBudgetStatus =
99
+ await AIService.getAutonomousDailyBudgetStatus(projectId);
100
+
101
+ expect(status.exhausted).toBe(true);
102
+ expect(getTokens).toHaveBeenCalledWith(
103
+ expect.objectContaining({
104
+ features: AUTONOMOUS_AI_FEATURES,
105
+ }),
106
+ );
107
+ });
108
+ });
109
+
110
+ describe("SentinelInvestigationQueue budget skip", () => {
111
+ afterEach(() => {
112
+ jest.restoreAllMocks();
113
+ });
114
+
115
+ test("does not enqueue when the daily budget is exhausted", async () => {
116
+ jest.spyOn(AIService, "getAutonomousDailyBudgetStatus").mockResolvedValue({
117
+ exhausted: true,
118
+ limitInTokens: 100_000,
119
+ usedTokensToday: 120_000,
120
+ });
121
+ const create: jest.SpyInstance = jest.spyOn(AIRunService, "create");
122
+
123
+ await SentinelInvestigationQueue.enqueue({
124
+ projectId: ObjectID.generate(),
125
+ subjectAlertId: ObjectID.generate(),
126
+ });
127
+
128
+ expect(create).not.toHaveBeenCalled();
129
+ });
130
+
131
+ test("does not enqueue when the budget check itself fails", async () => {
132
+ jest
133
+ .spyOn(AIService, "getAutonomousDailyBudgetStatus")
134
+ .mockRejectedValue(new Error("db down"));
135
+ const create: jest.SpyInstance = jest.spyOn(AIRunService, "create");
136
+
137
+ await SentinelInvestigationQueue.enqueue({
138
+ projectId: ObjectID.generate(),
139
+ subjectAlertId: ObjectID.generate(),
140
+ });
141
+
142
+ expect(create).not.toHaveBeenCalled();
143
+ });
144
+
145
+ test("leaves a queued run unclaimed when the budget is exhausted at claim time", async () => {
146
+ // No per-project cap override; concurrency cap passes…
147
+ jest
148
+ .spyOn(ProjectService, "findOneById")
149
+ .mockResolvedValue(fakeProject(undefined));
150
+ jest
151
+ .spyOn(AIRunService, "countBy")
152
+ .mockResolvedValue(new PositiveNumber(0));
153
+ // …but the budget is exhausted.
154
+ jest.spyOn(AIService, "getAutonomousDailyBudgetStatus").mockResolvedValue({
155
+ exhausted: true,
156
+ limitInTokens: 100_000,
157
+ usedTokensToday: 120_000,
158
+ });
159
+ const claim: jest.SpyInstance = jest.spyOn(
160
+ AIRunService,
161
+ "attemptStatusTransition",
162
+ );
163
+
164
+ await SentinelInvestigationQueue.processRun({
165
+ id: ObjectID.generate(),
166
+ projectId: ObjectID.generate(),
167
+ attemptCount: 0,
168
+ triggeredByAlertId: ObjectID.generate(),
169
+ });
170
+
171
+ expect(claim).not.toHaveBeenCalled();
172
+ });
173
+ });
@@ -0,0 +1,97 @@
1
+ import IncidentInternalNoteService from "../../../Server/Services/IncidentInternalNoteService";
2
+ import IncidentFeedService from "../../../Server/Services/IncidentFeedService";
3
+ import IncidentService from "../../../Server/Services/IncidentService";
4
+ import Model from "../../../Models/DatabaseModels/IncidentInternalNote";
5
+ import ObjectID from "../../../Types/ObjectID";
6
+ import URL from "../../../Types/API/URL";
7
+ import { describe, expect, test, afterEach } from "@jest/globals";
8
+
9
+ /*
10
+ * IncidentInternalNoteService.onCreateSuccess announces every new note with a
11
+ * "posted private note" feed item + workspace ping — INCLUDING user-less
12
+ * system notes: the SLA note-reminder job (SendNoteReminders.ts) creates notes
13
+ * with no createdByUserId and relies entirely on this hook for its feed entry
14
+ * and Slack/Teams ping (it sets isOwnerNotified itself, so the hook is its
15
+ * only push channel).
16
+ *
17
+ * Callers that must NOT announce (Sentinel's RCA note, which has its own
18
+ * quiet-mode-gated RootCause feed item) opt out explicitly with
19
+ * props.ignoreHooks — see IncidentInvestigationRunner. These tests lock in
20
+ * that the hook announces for both user-authored and user-less notes, so the
21
+ * SLA flow can't be silenced again by a "system notes are quiet" shortcut.
22
+ */
23
+
24
+ function fakeNote(userId?: ObjectID | undefined): Model {
25
+ return {
26
+ id: ObjectID.generate(),
27
+ incidentId: ObjectID.generate(),
28
+ projectId: ObjectID.generate(),
29
+ note: "test note",
30
+ createdByUserId: userId,
31
+ createdByUser: undefined,
32
+ } as unknown as Model;
33
+ }
34
+
35
+ describe("IncidentInternalNoteService.onCreateSuccess", () => {
36
+ afterEach(() => {
37
+ jest.restoreAllMocks();
38
+ });
39
+
40
+ function mockAnnouncementDeps(): jest.SpyInstance {
41
+ const createFeedItem: jest.SpyInstance = jest
42
+ .spyOn(IncidentFeedService, "createIncidentFeedItem")
43
+ .mockResolvedValue(undefined as never);
44
+ jest.spyOn(IncidentService, "getIncidentNumber").mockResolvedValue({
45
+ number: 42,
46
+ numberWithPrefix: "INC-42",
47
+ });
48
+ jest
49
+ .spyOn(IncidentService, "getIncidentLinkInDashboard")
50
+ .mockResolvedValue(URL.fromString("https://oneuptime.example/incident"));
51
+ // No attachments on these notes.
52
+ jest
53
+ .spyOn(IncidentInternalNoteService, "findOneById")
54
+ .mockResolvedValue(null);
55
+ return createFeedItem;
56
+ }
57
+
58
+ test("user-authored note announces with a feed item attributed to the user", async () => {
59
+ const createFeedItem: jest.SpyInstance = mockAnnouncementDeps();
60
+ const userId: ObjectID = ObjectID.generate();
61
+ const note: Model = fakeNote(userId);
62
+
63
+ await IncidentInternalNoteService.onCreateSuccess(
64
+ { createBy: { data: note, props: { isRoot: true } }, carryForward: null },
65
+ note,
66
+ );
67
+
68
+ expect(createFeedItem).toHaveBeenCalledTimes(1);
69
+ expect(createFeedItem).toHaveBeenCalledWith(
70
+ expect.objectContaining({
71
+ userId,
72
+ workspaceNotification: expect.objectContaining({
73
+ sendWorkspaceNotification: true,
74
+ }),
75
+ }),
76
+ );
77
+ });
78
+
79
+ test("user-less system note (e.g. SLA reminder) still announces", async () => {
80
+ const createFeedItem: jest.SpyInstance = mockAnnouncementDeps();
81
+ const note: Model = fakeNote(undefined);
82
+
83
+ await IncidentInternalNoteService.onCreateSuccess(
84
+ { createBy: { data: note, props: { isRoot: true } }, carryForward: null },
85
+ note,
86
+ );
87
+
88
+ expect(createFeedItem).toHaveBeenCalledTimes(1);
89
+ expect(createFeedItem).toHaveBeenCalledWith(
90
+ expect.objectContaining({
91
+ workspaceNotification: expect.objectContaining({
92
+ sendWorkspaceNotification: true,
93
+ }),
94
+ }),
95
+ );
96
+ });
97
+ });
@@ -278,3 +278,57 @@ describe("IoTDeviceService.bulkUpdateLatestMetrics — sanitation matches the up
278
278
  expect(params).not.toContain(10);
279
279
  });
280
280
  });
281
+
282
+ describe("IoTDeviceService.deleteStaleForFleet — registered devices survive", () => {
283
+ const CUTOFF: Date = new Date("2026-06-13T00:00:00.000Z");
284
+
285
+ test("marks registered devices offline and deletes only unregistered ones", async () => {
286
+ const query: jest.Mock = mockQueryRunner();
287
+ query
288
+ .mockResolvedValueOnce([[], 2]) // UPDATE (registered -> isUp=false)
289
+ .mockResolvedValueOnce([[], 5]); // DELETE (unregistered)
290
+
291
+ const result: { deleted: number; markedOffline: number } =
292
+ await IoTDeviceService.deleteStaleForFleet({
293
+ iotFleetId: FLEET_ID,
294
+ olderThan: CUTOFF,
295
+ });
296
+
297
+ expect(query).toHaveBeenCalledTimes(2);
298
+
299
+ const [updateSql, updateParams] = query.mock.calls[0] as QueryCall;
300
+ expect(updateSql).toContain('UPDATE "IoTDevice" SET "isUp" = false');
301
+ // Registered = credential on the same project + fleet + externalId.
302
+ expect(updateSql).toContain('EXISTS (SELECT 1 FROM "IoTDeviceCredential"');
303
+ expect(updateSql).toContain('c."externalId" = "IoTDevice"."externalId"');
304
+ expect(updateSql).toContain('c."projectId" = "IoTDevice"."projectId"');
305
+ // The credential correlation itself is kind-agnostic.
306
+ expect(updateSql).not.toContain('c."kind"');
307
+ // Reconnect recovery depends on lastSeenAt staying untouched.
308
+ expect(updateSql).not.toContain('"lastSeenAt" =');
309
+ // Idempotent across cron ticks: already-down rows are not rewritten.
310
+ expect(updateSql).toContain('"isUp" IS DISTINCT FROM false');
311
+ // Stale duplicate-kind rows self-heal instead of being pinned offline.
312
+ expect(updateSql).toContain("NOT EXISTS");
313
+ expect(updateParams).toEqual([FLEET_ID.toString(), CUTOFF]);
314
+
315
+ const [deleteSql, deleteParams] = query.mock.calls[1] as QueryCall;
316
+ expect(deleteSql).toContain('DELETE FROM "IoTDevice"');
317
+ expect(deleteSql).toContain("NOT EXISTS");
318
+ expect(deleteParams).toEqual([FLEET_ID.toString(), CUTOFF]);
319
+
320
+ expect(result).toEqual({ deleted: 5, markedOffline: 2 });
321
+ });
322
+
323
+ test("normalizes a driver result without an affected count to zero", async () => {
324
+ mockQueryRunner([]);
325
+
326
+ const result: { deleted: number; markedOffline: number } =
327
+ await IoTDeviceService.deleteStaleForFleet({
328
+ iotFleetId: FLEET_ID,
329
+ olderThan: CUTOFF,
330
+ });
331
+
332
+ expect(result).toEqual({ deleted: 0, markedOffline: 0 });
333
+ });
334
+ });
@@ -98,6 +98,7 @@ describe("LogAggregationService", () => {
98
98
  ).buildHistogramStatement({
99
99
  ...defaultRequest,
100
100
  facetKey: undefined,
101
+ bucketSizeInMinutes: 60,
101
102
  attributes: { requestid: "uuid-123" },
102
103
  });
103
104
 
@@ -110,4 +111,25 @@ describe("LogAggregationService", () => {
110
111
  expect(Object.values(statement.query_params)).toContain("requestid");
111
112
  expect(Object.values(statement.query_params)).toContain("uuid-123");
112
113
  });
114
+
115
+ test("histogram supports multi-value dashboard attribute filters", () => {
116
+ const statement: Statement = (
117
+ LogAggregationService as any
118
+ ).buildHistogramStatement({
119
+ ...defaultRequest,
120
+ facetKey: undefined,
121
+ bucketSizeInMinutes: 60,
122
+ attributes: { region: ["eu-west-1", "us-east-1"] },
123
+ });
124
+
125
+ expect(statement.query).toContain(
126
+ "arrayExists((k, v) -> lowerUTF8(k) = lowerUTF8(",
127
+ );
128
+ expect(statement.query).toContain("AND v IN (");
129
+ expect(Object.values(statement.query_params)).toContain("region");
130
+ expect(Object.values(statement.query_params)).toContainEqual([
131
+ "eu-west-1",
132
+ "us-east-1",
133
+ ]);
134
+ });
113
135
  });