@oneuptime/common 12.0.23 → 12.0.25

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 (323) hide show
  1. package/Models/AnalyticsModels/Span.ts +101 -0
  2. package/Models/DatabaseModels/DetectionRule.ts +55 -0
  3. package/Models/DatabaseModels/NetworkDeviceAutoImportRule.ts +27 -7
  4. package/Models/DatabaseModels/NetworkDeviceDiscoveryScan.ts +67 -0
  5. package/Models/DatabaseModels/Project.ts +68 -0
  6. package/Models/DatabaseModels/User.ts +68 -0
  7. package/Server/API/BaseAPI.ts +0 -24
  8. package/Server/API/SlackAPI.ts +0 -2
  9. package/Server/API/TelemetryAPI.ts +29 -0
  10. package/Server/Infrastructure/Postgres/SchemaMigrations/1789400000000-AddNameToNetworkDeviceDiscoveryScan.ts +28 -0
  11. package/Server/Infrastructure/Postgres/SchemaMigrations/1789500000000-AddCampaignUtmFields.ts +49 -0
  12. package/Server/Infrastructure/Postgres/SchemaMigrations/1789512000000-AddDetectionRuleDistinctCountColumns.ts +33 -0
  13. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
  14. package/Server/Middleware/GzipRequestBody.ts +311 -0
  15. package/Server/Middleware/MultipartFormData.ts +87 -3
  16. package/Server/Middleware/SlackAuthorization.ts +96 -18
  17. package/Server/Services/DetectionRuleService.ts +73 -6
  18. package/Server/Services/Index.ts +205 -0
  19. package/Server/Services/NetworkDeviceDiscoveryScanService.ts +59 -0
  20. package/Server/Services/NetworkDeviceService.ts +148 -0
  21. package/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.ts +65 -0
  22. package/Server/Services/OnCallDutyPolicyFeedService.ts +1 -1
  23. package/Server/Services/ProjectService.ts +29 -19
  24. package/Server/Services/SecurityEventService.ts +90 -13
  25. package/Server/Services/StatusPageResourceService.ts +223 -0
  26. package/Server/Services/TelemetryAttributeService.ts +17 -0
  27. package/Server/Services/UserService.ts +4 -6
  28. package/Server/Types/Markdown.ts +161 -67
  29. package/Server/Utils/AI/Toolbox/OnCallTools.ts +12 -4
  30. package/Server/Utils/AnalyticsDatabase/Statement.ts +13 -1
  31. package/Server/Utils/AnalyticsDatabase/StatementGenerator.ts +297 -6
  32. package/Server/Utils/Attribution.ts +4 -0
  33. package/Server/Utils/Marketing/MarketingEventUtil.ts +45 -7
  34. package/Server/Utils/SecurityEvent/DetectionRuleEvaluator.ts +55 -3
  35. package/Server/Utils/SecurityEvent/Sigma/SigmaClickhouseCompiler.ts +21 -0
  36. package/Server/Utils/StartServer.ts +12 -32
  37. package/Server/Utils/Telemetry/LlmCostBudgetEvaluator.ts +101 -4
  38. package/Server/Utils/Telemetry/LlmMetricSpend.ts +181 -0
  39. package/Server/Utils/Telemetry/LlmSpan.ts +46 -0
  40. package/Server/Utils/Workspace/Slack/Actions/Auth.ts +0 -12
  41. package/Server/Views/Partials/AnalyticsConsent.ejs +159 -102
  42. package/Server/Views/Partials/Head.ejs +2 -1
  43. package/Tests/App/Dashboard/AdminUserNotificationMethodsPage.test.tsx +776 -38
  44. package/Tests/App/Dashboard/CorrelateFilterBuilder.test.tsx +359 -0
  45. package/Tests/App/Dashboard/CorrelateGraph.test.tsx +865 -0
  46. package/Tests/App/Dashboard/CorrelationGraph.test.ts +346 -0
  47. package/Tests/App/Dashboard/CriteriaFilterConditionDropdown.test.tsx +256 -0
  48. package/Tests/App/Dashboard/CriteriaFilterDefaults.test.ts +738 -0
  49. package/Tests/App/Dashboard/CriteriaFilterMonitorTypeChange.test.ts +1122 -0
  50. package/Tests/App/Dashboard/DiscoveryScanWizardValidation.test.tsx +283 -0
  51. package/Tests/App/Dashboard/ExternalStatusPageCriteriaFilter.test.ts +407 -0
  52. package/Tests/App/Dashboard/LlmCallsTableIdentity.test.tsx +322 -0
  53. package/Tests/App/Dashboard/LlmOverview.test.tsx +335 -0
  54. package/Tests/App/Dashboard/LlmSpanDisplay.test.ts +391 -0
  55. package/Tests/App/Dashboard/LlmUsageBreakdown.test.tsx +1007 -0
  56. package/Tests/App/Dashboard/MetricSeriesInvestigateMenu.test.tsx +5 -14
  57. package/Tests/App/Dashboard/MonitorCriteriaActionToggles.test.tsx +426 -0
  58. package/Tests/App/Dashboard/MonitorStepsCriteriaAlignmentWiring.test.tsx +352 -0
  59. package/Tests/App/Dashboard/OnCallLayerCardOverrides.test.tsx +278 -0
  60. package/Tests/App/Dashboard/OnCallLayerShiftPreviewOverrides.test.ts +237 -0
  61. package/Tests/App/Dashboard/OnCallReadinessSurfaces.test.tsx +2 -2
  62. package/Tests/App/Dashboard/OnCallSchedulePreviewOverrides.test.tsx +460 -0
  63. package/Tests/App/Dashboard/SecurityEventAttributeUtil.test.ts +171 -0
  64. package/Tests/App/Dashboard/SecurityEventCorrelation.test.ts +857 -0
  65. package/Tests/App/Dashboard/SecurityEventDetailObservables.test.tsx +194 -0
  66. package/Tests/App/Dashboard/SecurityEventsDetectionRulesPage.test.tsx +124 -0
  67. package/Tests/App/Dashboard/SecurityEventsMonitorStepForm.test.tsx +79 -19
  68. package/Tests/App/Dashboard/SecurityEventsTableColumns.test.tsx +382 -0
  69. package/Tests/App/StatusPage/BulkAddStatusPageMonitors.test.ts +216 -0
  70. package/Tests/App/StatusPage/BulkAddStatusPageMonitorsModal.test.tsx +590 -11
  71. package/Tests/App/StatusPage/StatusPageResourceExplorer.test.tsx +757 -0
  72. package/Tests/Models/DiscoveryScanNameColumn.test.ts +293 -0
  73. package/Tests/Server/API/BaseAPI.test.ts +41 -0
  74. package/Tests/Server/API/BaseAPIUpdatePayloadValidation.test.ts +9 -16
  75. package/Tests/Server/API/SecurityEventAttributesAPI.test.ts +564 -0
  76. package/Tests/Server/Infrastructure/Postgres/SchemaMigrationsOrdering.test.ts +120 -4
  77. package/Tests/Server/Middleware/GzipRequestBody.test.ts +725 -0
  78. package/Tests/Server/Middleware/MultipartFormData.test.ts +298 -0
  79. package/Tests/Server/Middleware/SlackAuthorization.test.ts +262 -5
  80. package/Tests/Server/Services/AddDetectionRuleDistinctCountColumnsMigration.test.ts +311 -0
  81. package/Tests/Server/Services/DetectionRuleService.test.ts +134 -2
  82. package/Tests/Server/Services/DiscoveryScanClaimHookFreeSafety.test.ts +7 -1
  83. package/Tests/Server/Services/FeedRetentionConsistency.test.ts +131 -0
  84. package/Tests/Server/Services/NetworkDeviceDiscoveryScanService.test.ts +194 -0
  85. package/Tests/Server/Services/NetworkDeviceMonitorStatusStamp.test.ts +800 -0
  86. package/Tests/Server/Services/OnCallScheduleAttachRosterRefresh.test.ts +244 -0
  87. package/Tests/Server/Services/SecurityEventService.test.ts +376 -0
  88. package/Tests/Server/Services/StatusPageResourceDuplicates.test.ts +703 -0
  89. package/Tests/Server/Services/TelemetryAttributeServiceSecurityEvent.test.ts +256 -0
  90. package/Tests/Server/Types/Workflow/Components/ComponentRegistryParity.test.ts +417 -0
  91. package/Tests/Server/Utils/AnalyticsDatabase/StatementGeneratorWhereOperators.test.ts +677 -0
  92. package/Tests/Server/Utils/Marketing/MarketingEventUtil.test.ts +43 -0
  93. package/Tests/Server/Utils/Monitor/Criteria/ProfileMonitorCriteria.test.ts +15 -11
  94. package/Tests/Server/Utils/SecurityEvent/DetectionRuleEvaluator.test.ts +369 -8
  95. package/Tests/Server/Utils/SecurityEvent/SigmaClickhouseCompiler.test.ts +35 -0
  96. package/Tests/Server/Utils/Telemetry/LlmCostBudgetEvaluator.test.ts +387 -4
  97. package/Tests/Server/Utils/Telemetry/LlmMetricSpend.test.ts +386 -0
  98. package/Tests/Server/Utils/Telemetry/LlmSpan.test.ts +804 -0
  99. package/Tests/Server/Views/AnalyticsConsentPartial.test.ts +48 -5
  100. package/Tests/Types/Code/YamlSyntax.test.ts +396 -0
  101. package/Tests/Types/Monitor/MetricAndProfileDefaultCriteria.test.ts +957 -0
  102. package/Tests/Types/Monitor/MonitorCriteriaActionValidation.test.ts +598 -0
  103. package/Tests/Types/Monitor/MonitorCriteriaInstance.test.ts +49 -0
  104. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +6 -6
  105. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.test.ts +4 -4
  106. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationUtil.test.ts +4 -3
  107. package/Tests/Types/Telemetry/LlmMetricConventions.test.ts +584 -0
  108. package/Tests/UI/Components/AiInvestigationSettingsCard.test.tsx +0 -12
  109. package/Tests/UI/Components/CardModelDetailEdit.test.tsx +1 -17
  110. package/Tests/UI/Components/CodeEditor.test.tsx +474 -10
  111. package/Tests/UI/Components/Detail/YamlField.test.tsx +105 -0
  112. package/Tests/UI/Components/EntityDropdownLabelsBulkAdd.test.tsx +319 -0
  113. package/Tests/UI/Components/Forms/FormFieldYaml.test.tsx +231 -0
  114. package/Tests/UI/Components/Forms/Utils/FormFieldSchemaTypeUtil.test.ts +1 -0
  115. package/Tests/UI/Components/Forms/ValidationYAML.test.ts +234 -0
  116. package/Tests/UI/Components/ModelTable/AttributeColumns.test.tsx +573 -0
  117. package/Tests/UI/Components/ModelTable/BaseModelTableAttributeColumns.test.tsx +824 -0
  118. package/Tests/UI/Components/ModelTable/ColumnCustomizationModalAddableColumns.test.tsx +707 -0
  119. package/Tests/UI/Components/SideOver.test.tsx +1 -1
  120. package/Tests/UI/Components/StatusPage/ResourceGridSelection.test.tsx +294 -0
  121. package/Tests/UI/Components/StatusPage/ResourceListSelection.test.tsx +436 -0
  122. package/Tests/UI/Components/TableBulkCsvExport.test.tsx +6 -2
  123. package/Tests/UI/Components/Toggle.test.tsx +25 -0
  124. package/Tests/UI/Components/YamlEditor.test.tsx +847 -0
  125. package/Tests/Utils/NetworkDevice/DeviceReachabilityUtil.test.ts +252 -0
  126. package/Tests/Utils/NetworkDiscovery/DiscoveredHostUtil.test.ts +221 -0
  127. package/Tests/Utils/NetworkDiscovery/ScanNameUtil.test.ts +312 -0
  128. package/Tests/Utils/StatusPage/ResourceExplorer.test.ts +468 -0
  129. package/Tests/Utils/Telemetry/LlmMetricQuery.test.ts +770 -0
  130. package/Types/Code/YamlSyntax.ts +396 -0
  131. package/Types/Exception/ExceptionCode.ts +1 -0
  132. package/Types/Exception/PayloadTooLargeException.ts +8 -0
  133. package/Types/Marketing/Attribution.ts +10 -0
  134. package/Types/Marketing/MarketingEvent.ts +4 -0
  135. package/Types/Monitor/MonitorCriteriaInstance.ts +116 -56
  136. package/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.ts +2 -1
  137. package/Types/SecurityEvent/DetectionFindingConstants.ts +11 -0
  138. package/Types/Telemetry/LlmConventions.ts +255 -0
  139. package/Types/Telemetry/LlmMetricConventions.ts +329 -0
  140. package/UI/Components/AutocompleteTextInput/AutocompleteTextInput.tsx +3 -0
  141. package/UI/Components/BulkUpdate/BulkUpdateForm.tsx +10 -1
  142. package/UI/Components/CodeEditor/CodeEditor.tsx +241 -79
  143. package/UI/Components/CodeEditor/YamlEditor.tsx +369 -0
  144. package/UI/Components/Detail/Detail.tsx +10 -0
  145. package/UI/Components/EntityDropdown/EntityDropdown.tsx +33 -0
  146. package/UI/Components/Forms/Fields/FormField.tsx +31 -0
  147. package/UI/Components/Forms/Types/Field.ts +8 -0
  148. package/UI/Components/Forms/Types/FormFieldSchemaType.ts +1 -0
  149. package/UI/Components/Forms/Utils/FormFieldSchemaTypeUtil.ts +2 -0
  150. package/UI/Components/Forms/Validation.ts +46 -0
  151. package/UI/Components/Input/Input.tsx +3 -0
  152. package/UI/Components/ModelTable/AttributeColumns.tsx +321 -0
  153. package/UI/Components/ModelTable/BaseModelTable.tsx +263 -14
  154. package/UI/Components/ModelTable/Column.ts +8 -0
  155. package/UI/Components/ModelTable/ColumnCustomizationModal.tsx +310 -0
  156. package/UI/Components/ModelTable/ColumnPreference.ts +13 -1
  157. package/UI/Components/MonitorTemplateVariables/TemplateVariablesModal.tsx +2 -2
  158. package/UI/Components/SideOver/SideOver.tsx +5 -5
  159. package/UI/Components/StatusPage/ResourceGrid.tsx +82 -2
  160. package/UI/Components/StatusPage/ResourceList.tsx +197 -38
  161. package/UI/Components/Toggle/Toggle.tsx +9 -1
  162. package/UI/Components/Types/FieldType.ts +1 -0
  163. package/Utils/NetworkDevice/DeviceReachabilityUtil.ts +73 -1
  164. package/Utils/NetworkDiscovery/ScanNameUtil.ts +181 -0
  165. package/Utils/StatusPage/ResourceExplorer.ts +258 -0
  166. package/Utils/Telemetry/LlmMetricQuery.ts +287 -0
  167. package/build/dist/Models/AnalyticsModels/Span.js +89 -0
  168. package/build/dist/Models/AnalyticsModels/Span.js.map +1 -1
  169. package/build/dist/Models/DatabaseModels/DetectionRule.js +57 -0
  170. package/build/dist/Models/DatabaseModels/DetectionRule.js.map +1 -1
  171. package/build/dist/Models/DatabaseModels/NetworkDeviceAutoImportRule.js +27 -7
  172. package/build/dist/Models/DatabaseModels/NetworkDeviceAutoImportRule.js.map +1 -1
  173. package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js +69 -0
  174. package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js.map +1 -1
  175. package/build/dist/Models/DatabaseModels/Project.js +76 -0
  176. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  177. package/build/dist/Models/DatabaseModels/User.js +76 -0
  178. package/build/dist/Models/DatabaseModels/User.js.map +1 -1
  179. package/build/dist/Server/API/BaseAPI.js +3 -19
  180. package/build/dist/Server/API/BaseAPI.js.map +1 -1
  181. package/build/dist/Server/API/SlackAPI.js +0 -2
  182. package/build/dist/Server/API/SlackAPI.js.map +1 -1
  183. package/build/dist/Server/API/TelemetryAPI.js +17 -0
  184. package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
  185. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1789400000000-AddNameToNetworkDeviceDiscoveryScan.js +21 -0
  186. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1789400000000-AddNameToNetworkDeviceDiscoveryScan.js.map +1 -0
  187. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1789500000000-AddCampaignUtmFields.js +42 -0
  188. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1789500000000-AddCampaignUtmFields.js.map +1 -0
  189. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1789512000000-AddDetectionRuleDistinctCountColumns.js +22 -0
  190. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1789512000000-AddDetectionRuleDistinctCountColumns.js.map +1 -0
  191. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +6 -0
  192. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  193. package/build/dist/Server/Middleware/GzipRequestBody.js +224 -0
  194. package/build/dist/Server/Middleware/GzipRequestBody.js.map +1 -0
  195. package/build/dist/Server/Middleware/MultipartFormData.js +71 -2
  196. package/build/dist/Server/Middleware/MultipartFormData.js.map +1 -1
  197. package/build/dist/Server/Middleware/SlackAuthorization.js +58 -7
  198. package/build/dist/Server/Middleware/SlackAuthorization.js.map +1 -1
  199. package/build/dist/Server/Services/DetectionRuleService.js +49 -4
  200. package/build/dist/Server/Services/DetectionRuleService.js.map +1 -1
  201. package/build/dist/Server/Services/Index.js +204 -0
  202. package/build/dist/Server/Services/Index.js.map +1 -1
  203. package/build/dist/Server/Services/NetworkDeviceDiscoveryScanService.js +50 -0
  204. package/build/dist/Server/Services/NetworkDeviceDiscoveryScanService.js.map +1 -1
  205. package/build/dist/Server/Services/NetworkDeviceService.js +124 -0
  206. package/build/dist/Server/Services/NetworkDeviceService.js.map +1 -1
  207. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js +68 -13
  208. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js.map +1 -1
  209. package/build/dist/Server/Services/OnCallDutyPolicyFeedService.js +1 -1
  210. package/build/dist/Server/Services/OnCallDutyPolicyFeedService.js.map +1 -1
  211. package/build/dist/Server/Services/ProjectService.js +25 -45
  212. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  213. package/build/dist/Server/Services/SecurityEventService.js +57 -5
  214. package/build/dist/Server/Services/SecurityEventService.js.map +1 -1
  215. package/build/dist/Server/Services/StatusPageResourceService.js +140 -0
  216. package/build/dist/Server/Services/StatusPageResourceService.js.map +1 -1
  217. package/build/dist/Server/Services/TelemetryAttributeService.js +17 -0
  218. package/build/dist/Server/Services/TelemetryAttributeService.js.map +1 -1
  219. package/build/dist/Server/Services/UserService.js +2 -12
  220. package/build/dist/Server/Services/UserService.js.map +1 -1
  221. package/build/dist/Server/Types/Markdown.js +147 -61
  222. package/build/dist/Server/Types/Markdown.js.map +1 -1
  223. package/build/dist/Server/Utils/AI/Toolbox/OnCallTools.js +12 -4
  224. package/build/dist/Server/Utils/AI/Toolbox/OnCallTools.js.map +1 -1
  225. package/build/dist/Server/Utils/AnalyticsDatabase/Statement.js +12 -1
  226. package/build/dist/Server/Utils/AnalyticsDatabase/Statement.js.map +1 -1
  227. package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js +246 -9
  228. package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js.map +1 -1
  229. package/build/dist/Server/Utils/Attribution.js.map +1 -1
  230. package/build/dist/Server/Utils/Marketing/MarketingEventUtil.js +27 -7
  231. package/build/dist/Server/Utils/Marketing/MarketingEventUtil.js.map +1 -1
  232. package/build/dist/Server/Utils/SecurityEvent/DetectionRuleEvaluator.js +42 -7
  233. package/build/dist/Server/Utils/SecurityEvent/DetectionRuleEvaluator.js.map +1 -1
  234. package/build/dist/Server/Utils/SecurityEvent/Sigma/SigmaClickhouseCompiler.js +18 -0
  235. package/build/dist/Server/Utils/SecurityEvent/Sigma/SigmaClickhouseCompiler.js.map +1 -1
  236. package/build/dist/Server/Utils/StartServer.js +12 -21
  237. package/build/dist/Server/Utils/StartServer.js.map +1 -1
  238. package/build/dist/Server/Utils/Telemetry/LlmCostBudgetEvaluator.js +76 -5
  239. package/build/dist/Server/Utils/Telemetry/LlmCostBudgetEvaluator.js.map +1 -1
  240. package/build/dist/Server/Utils/Telemetry/LlmMetricSpend.js +151 -0
  241. package/build/dist/Server/Utils/Telemetry/LlmMetricSpend.js.map +1 -0
  242. package/build/dist/Server/Utils/Telemetry/LlmSpan.js +24 -1
  243. package/build/dist/Server/Utils/Telemetry/LlmSpan.js.map +1 -1
  244. package/build/dist/Server/Utils/Workspace/Slack/Actions/Auth.js +0 -10
  245. package/build/dist/Server/Utils/Workspace/Slack/Actions/Auth.js.map +1 -1
  246. package/build/dist/Types/Code/YamlSyntax.js +212 -0
  247. package/build/dist/Types/Code/YamlSyntax.js.map +1 -0
  248. package/build/dist/Types/Exception/ExceptionCode.js +1 -0
  249. package/build/dist/Types/Exception/ExceptionCode.js.map +1 -1
  250. package/build/dist/Types/Exception/PayloadTooLargeException.js +8 -0
  251. package/build/dist/Types/Exception/PayloadTooLargeException.js.map +1 -0
  252. package/build/dist/Types/Marketing/Attribution.js +10 -0
  253. package/build/dist/Types/Marketing/Attribution.js.map +1 -1
  254. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +112 -51
  255. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
  256. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.js +2 -1
  257. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.js.map +1 -1
  258. package/build/dist/Types/SecurityEvent/DetectionFindingConstants.js +9 -0
  259. package/build/dist/Types/SecurityEvent/DetectionFindingConstants.js.map +1 -1
  260. package/build/dist/Types/Telemetry/LlmConventions.js +236 -0
  261. package/build/dist/Types/Telemetry/LlmConventions.js.map +1 -1
  262. package/build/dist/Types/Telemetry/LlmMetricConventions.js +290 -0
  263. package/build/dist/Types/Telemetry/LlmMetricConventions.js.map +1 -0
  264. package/build/dist/UI/Components/AutocompleteTextInput/AutocompleteTextInput.js +1 -1
  265. package/build/dist/UI/Components/AutocompleteTextInput/AutocompleteTextInput.js.map +1 -1
  266. package/build/dist/UI/Components/BulkUpdate/BulkUpdateForm.js +5 -2
  267. package/build/dist/UI/Components/BulkUpdate/BulkUpdateForm.js.map +1 -1
  268. package/build/dist/UI/Components/CodeEditor/CodeEditor.js +206 -76
  269. package/build/dist/UI/Components/CodeEditor/CodeEditor.js.map +1 -1
  270. package/build/dist/UI/Components/CodeEditor/YamlEditor.js +201 -0
  271. package/build/dist/UI/Components/CodeEditor/YamlEditor.js.map +1 -0
  272. package/build/dist/UI/Components/Detail/Detail.js +9 -0
  273. package/build/dist/UI/Components/Detail/Detail.js.map +1 -1
  274. package/build/dist/UI/Components/EntityDropdown/EntityDropdown.js +16 -1
  275. package/build/dist/UI/Components/EntityDropdown/EntityDropdown.js.map +1 -1
  276. package/build/dist/UI/Components/Forms/Fields/FormField.js +14 -1
  277. package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
  278. package/build/dist/UI/Components/Forms/Types/Field.js.map +1 -1
  279. package/build/dist/UI/Components/Forms/Types/FormFieldSchemaType.js +1 -0
  280. package/build/dist/UI/Components/Forms/Types/FormFieldSchemaType.js.map +1 -1
  281. package/build/dist/UI/Components/Forms/Utils/FormFieldSchemaTypeUtil.js +2 -0
  282. package/build/dist/UI/Components/Forms/Utils/FormFieldSchemaTypeUtil.js.map +1 -1
  283. package/build/dist/UI/Components/Forms/Validation.js +27 -0
  284. package/build/dist/UI/Components/Forms/Validation.js.map +1 -1
  285. package/build/dist/UI/Components/Input/Input.js +1 -1
  286. package/build/dist/UI/Components/Input/Input.js.map +1 -1
  287. package/build/dist/UI/Components/ModelTable/AttributeColumns.js +159 -0
  288. package/build/dist/UI/Components/ModelTable/AttributeColumns.js.map +1 -0
  289. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +179 -17
  290. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  291. package/build/dist/UI/Components/ModelTable/ColumnCustomizationModal.js +133 -2
  292. package/build/dist/UI/Components/ModelTable/ColumnCustomizationModal.js.map +1 -1
  293. package/build/dist/UI/Components/ModelTable/ColumnPreference.js +7 -1
  294. package/build/dist/UI/Components/ModelTable/ColumnPreference.js.map +1 -1
  295. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesModal.js +2 -2
  296. package/build/dist/UI/Components/SideOver/SideOver.js +5 -5
  297. package/build/dist/UI/Components/StatusPage/ResourceGrid.js +28 -2
  298. package/build/dist/UI/Components/StatusPage/ResourceGrid.js.map +1 -1
  299. package/build/dist/UI/Components/StatusPage/ResourceList.js +87 -20
  300. package/build/dist/UI/Components/StatusPage/ResourceList.js.map +1 -1
  301. package/build/dist/UI/Components/Toggle/Toggle.js +9 -1
  302. package/build/dist/UI/Components/Toggle/Toggle.js.map +1 -1
  303. package/build/dist/UI/Components/Types/FieldType.js +1 -0
  304. package/build/dist/UI/Components/Types/FieldType.js.map +1 -1
  305. package/build/dist/Utils/NetworkDevice/DeviceReachabilityUtil.js +37 -1
  306. package/build/dist/Utils/NetworkDevice/DeviceReachabilityUtil.js.map +1 -1
  307. package/build/dist/Utils/NetworkDiscovery/ScanNameUtil.js +120 -0
  308. package/build/dist/Utils/NetworkDiscovery/ScanNameUtil.js.map +1 -0
  309. package/build/dist/Utils/StatusPage/ResourceExplorer.js +171 -0
  310. package/build/dist/Utils/StatusPage/ResourceExplorer.js.map +1 -1
  311. package/build/dist/Utils/Telemetry/LlmMetricQuery.js +175 -0
  312. package/build/dist/Utils/Telemetry/LlmMetricQuery.js.map +1 -0
  313. package/jest.config.json +2 -0
  314. package/package.json +1 -1
  315. package/tsconfig.json +2 -1
  316. package/Tests/UI/Components/Toast.test.tsx +0 -197
  317. package/Tests/UI/Components/ToastStacking.test.tsx +0 -198
  318. package/UI/Components/Toast/Toast.tsx +0 -189
  319. package/UI/Components/Toast/ToastInit.tsx +0 -110
  320. package/build/dist/UI/Components/Toast/Toast.js +0 -123
  321. package/build/dist/UI/Components/Toast/Toast.js.map +0 -1
  322. package/build/dist/UI/Components/Toast/ToastInit.js +0 -53
  323. package/build/dist/UI/Components/Toast/ToastInit.js.map +0 -1
@@ -19,6 +19,8 @@ import LlmCostBudgetService from "../../../../Server/Services/LlmCostBudgetServi
19
19
  import MetricService from "../../../../Server/Services/MetricService";
20
20
  import SpanService from "../../../../Server/Services/SpanService";
21
21
  import TelemetryUtil from "../../../../Server/Utils/Telemetry/Telemetry";
22
+ import { LlmMicroUsdCostMetricNames } from "../../../../Types/Telemetry/LlmMetricConventions";
23
+ import { LlmMetricScope } from "../../../../Utils/Telemetry/LlmMetricQuery";
22
24
  /*
23
25
  * `jest` deliberately comes from the global scope, not @jest/globals — the
24
26
  * imported value would shadow the global `jest` NAMESPACE and break the
@@ -41,6 +43,11 @@ jest.mock("../../../../Server/Services/MetricService", () => {
41
43
  __esModule: true,
42
44
  default: {
43
45
  insertJsonRows: jest.fn(),
46
+ /*
47
+ * aggregateBy backs the metric-sourced spend fallback that
48
+ * resolveSpend reaches for when the span stream is empty.
49
+ */
50
+ aggregateBy: jest.fn(),
44
51
  },
45
52
  };
46
53
  });
@@ -70,10 +77,41 @@ const mockedSpanService: { aggregateBy: MockedFn } = SpanService as unknown as {
70
77
  aggregateBy: MockedFn;
71
78
  };
72
79
 
73
- const mockedMetricService: { insertJsonRows: MockedFn } =
74
- MetricService as unknown as {
75
- insertJsonRows: MockedFn;
76
- };
80
+ const mockedMetricService: {
81
+ insertJsonRows: MockedFn;
82
+ aggregateBy: MockedFn;
83
+ } = MetricService as unknown as {
84
+ insertJsonRows: MockedFn;
85
+ aggregateBy: MockedFn;
86
+ };
87
+
88
+ /*
89
+ * Metric-sourced cost is TWO aggregates, not one: the USD-denominated metric
90
+ * names and the micro-USD ones (the Codex CLI reports millionths of a dollar)
91
+ * are queried separately and scaled before being added, because a single Sum
92
+ * over both units cannot be un-mixed afterwards. A plain mockResolvedValue
93
+ * answers BOTH queries with the same payload, which would feed the same
94
+ * figure in twice — once at 1e-6 — and quietly skew every expectation here.
95
+ *
96
+ * So the mock dispatches on the metric names the query actually selects: the
97
+ * rows are the project's USD spend, and the micro-USD query correctly finds
98
+ * nothing.
99
+ */
100
+ function mockUsdMetricRows(rows: Array<JSONObject>): void {
101
+ mockedMetricService.aggregateBy.mockImplementation(
102
+ (aggregate: { query: Record<string, unknown> }): Promise<JSONObject> => {
103
+ const names: Array<string> = ((
104
+ aggregate?.query?.["name"] as { values?: Array<string> } | undefined
105
+ )?.values || []) as Array<string>;
106
+
107
+ const isMicroUsd: boolean = names.some((name: string) => {
108
+ return LlmMicroUsdCostMetricNames.includes(name);
109
+ });
110
+
111
+ return Promise.resolve({ data: isMicroUsd ? [] : rows });
112
+ },
113
+ );
114
+ }
77
115
 
78
116
  const mockedBudgetService: {
79
117
  findBy: MockedFn;
@@ -328,6 +366,7 @@ describe("LlmCostBudgetEvaluator.evaluateBudget — orchestration", () => {
328
366
  beforeEach(() => {
329
367
  jest.clearAllMocks();
330
368
  mockedSpanService.aggregateBy.mockResolvedValue({ data: [] } as never);
369
+ mockedMetricService.aggregateBy.mockResolvedValue({ data: [] } as never);
331
370
  mockedMetricService.insertJsonRows.mockResolvedValue(undefined as never);
332
371
  mockedBudgetService.updateOneById.mockResolvedValue(undefined as never);
333
372
  mockedTelemetryUtil.indexMetricNameServiceNameMap.mockResolvedValue(
@@ -447,6 +486,7 @@ describe("LlmCostBudgetEvaluator.evaluateBudget — orchestration", () => {
447
486
  describe("LlmCostBudgetEvaluator.evaluateAllBudgets — sweep resilience", () => {
448
487
  beforeEach(() => {
449
488
  jest.clearAllMocks();
489
+ mockedMetricService.aggregateBy.mockResolvedValue({ data: [] } as never);
450
490
  mockedMetricService.insertJsonRows.mockResolvedValue(undefined as never);
451
491
  mockedBudgetService.updateOneById.mockResolvedValue(undefined as never);
452
492
  mockedTelemetryUtil.indexMetricNameServiceNameMap.mockResolvedValue(
@@ -481,6 +521,7 @@ describe("LlmCostBudgetEvaluator.evaluateAllBudgets — sweep resilience", () =>
481
521
  await LlmCostBudgetEvaluator.evaluateAllBudgets();
482
522
 
483
523
  expect(mockedSpanService.aggregateBy).not.toHaveBeenCalled();
524
+ expect(mockedMetricService.aggregateBy).not.toHaveBeenCalled();
484
525
  });
485
526
 
486
527
  test("only enabled budgets are loaded", async () => {
@@ -495,3 +536,345 @@ describe("LlmCostBudgetEvaluator.evaluateAllBudgets — sweep resilience", () =>
495
536
  expect(findArg.query["isEnabled"]).toBe(true);
496
537
  });
497
538
  });
539
+
540
+ describe("LlmCostBudgetEvaluator.buildMetricScope", () => {
541
+ const DAY_START: Date = new Date(Date.UTC(2026, 7, 22, 0, 0, 0));
542
+
543
+ test("carries the project and the day-so-far window", () => {
544
+ const budget: LlmCostBudget = makeBudget();
545
+
546
+ const scope: LlmMetricScope = LlmCostBudgetEvaluator.buildMetricScope({
547
+ budget,
548
+ dayStart: DAY_START,
549
+ now: NOW,
550
+ });
551
+
552
+ expect(scope.projectId).toBe(budget.projectId);
553
+ expect(scope.startTime).toBe(DAY_START);
554
+ expect(scope.endTime).toBe(NOW);
555
+ });
556
+
557
+ test("leaves an unscoped budget unscoped — it must see every datapoint", () => {
558
+ const scope: LlmMetricScope = LlmCostBudgetEvaluator.buildMetricScope({
559
+ budget: makeBudget(),
560
+ dayStart: DAY_START,
561
+ now: NOW,
562
+ });
563
+
564
+ expect(scope.serviceId).toBeUndefined();
565
+ expect(scope.llmSystem).toBeUndefined();
566
+ expect(scope.llmModel).toBeUndefined();
567
+ });
568
+
569
+ test("mirrors the budget's service / provider / model scoping", () => {
570
+ const serviceId: ObjectID = ObjectID.generate();
571
+
572
+ const scope: LlmMetricScope = LlmCostBudgetEvaluator.buildMetricScope({
573
+ budget: makeBudget({
574
+ serviceId: serviceId,
575
+ llmSystem: "anthropic",
576
+ llmModel: "claude-sonnet-4",
577
+ }),
578
+ dayStart: DAY_START,
579
+ now: NOW,
580
+ });
581
+
582
+ expect(scope.serviceId).toBe(serviceId);
583
+ expect(scope.llmSystem).toBe("anthropic");
584
+ expect(scope.llmModel).toBe("claude-sonnet-4");
585
+ });
586
+
587
+ /*
588
+ * The span query and the metric query must narrow to the same slice of
589
+ * traffic, or the fallback would silently measure something else.
590
+ */
591
+ test("agrees with buildSpanQuery on the service scope", () => {
592
+ const serviceId: ObjectID = ObjectID.generate();
593
+ const budget: LlmCostBudget = makeBudget({ serviceId: serviceId });
594
+
595
+ const spanQuery: Record<string, unknown> =
596
+ LlmCostBudgetEvaluator.buildSpanQuery({
597
+ budget,
598
+ dayStart: DAY_START,
599
+ now: NOW,
600
+ }) as unknown as Record<string, unknown>;
601
+
602
+ const scope: LlmMetricScope = LlmCostBudgetEvaluator.buildMetricScope({
603
+ budget,
604
+ dayStart: DAY_START,
605
+ now: NOW,
606
+ });
607
+
608
+ expect(spanQuery["primaryEntityId"]).toBe(scope.serviceId);
609
+ });
610
+ });
611
+
612
+ describe("LlmCostBudgetEvaluator.resolveSpend — source selection", () => {
613
+ const DAY_START: Date = new Date(Date.UTC(2026, 7, 22, 0, 0, 0));
614
+
615
+ beforeEach(() => {
616
+ jest.clearAllMocks();
617
+ mockedSpanService.aggregateBy.mockResolvedValue({ data: [] } as never);
618
+ mockedMetricService.aggregateBy.mockResolvedValue({ data: [] } as never);
619
+ });
620
+
621
+ function mockSpanSpend(value: number): void {
622
+ mockedSpanService.aggregateBy.mockResolvedValue({
623
+ data: [{ timestamp: NOW, value: value }],
624
+ } as never);
625
+ }
626
+
627
+ function mockMetricSpend(value: number): void {
628
+ mockUsdMetricRows([{ timestamp: NOW, value: value }]);
629
+ }
630
+
631
+ test("uses spans when the span stream reported spend", async () => {
632
+ mockSpanSpend(42);
633
+ mockMetricSpend(999);
634
+
635
+ await expect(
636
+ LlmCostBudgetEvaluator.resolveSpend({
637
+ budget: makeBudget(),
638
+ dayStart: DAY_START,
639
+ now: NOW,
640
+ }),
641
+ ).resolves.toEqual({ spendInUSD: 42, source: "spans" });
642
+ });
643
+
644
+ /*
645
+ * The double-counting guard, and the reason this is a fallback rather than a
646
+ * sum: an SDK emitting both signals would otherwise report 1041 here, and a
647
+ * budget that fires on spend that never happened is worse than one that
648
+ * misses.
649
+ */
650
+ test("never adds metric spend on top of span spend", async () => {
651
+ mockSpanSpend(42);
652
+ mockMetricSpend(999);
653
+
654
+ const resolved: { spendInUSD: number } =
655
+ await LlmCostBudgetEvaluator.resolveSpend({
656
+ budget: makeBudget(),
657
+ dayStart: DAY_START,
658
+ now: NOW,
659
+ });
660
+
661
+ expect(resolved.spendInUSD).toBe(42);
662
+ expect(resolved.spendInUSD).not.toBe(1041);
663
+ });
664
+
665
+ test("does not query metrics at all when spans answered", async () => {
666
+ mockSpanSpend(42);
667
+
668
+ await LlmCostBudgetEvaluator.resolveSpend({
669
+ budget: makeBudget(),
670
+ dayStart: DAY_START,
671
+ now: NOW,
672
+ });
673
+
674
+ expect(mockedMetricService.aggregateBy).not.toHaveBeenCalled();
675
+ });
676
+
677
+ test("falls back to metrics when the span stream is empty", async () => {
678
+ mockMetricSpend(17.5);
679
+
680
+ await expect(
681
+ LlmCostBudgetEvaluator.resolveSpend({
682
+ budget: makeBudget(),
683
+ dayStart: DAY_START,
684
+ now: NOW,
685
+ }),
686
+ ).resolves.toEqual({ spendInUSD: 17.5, source: "metrics" });
687
+ });
688
+
689
+ test("reports source 'none' when both streams are empty", async () => {
690
+ await expect(
691
+ LlmCostBudgetEvaluator.resolveSpend({
692
+ budget: makeBudget(),
693
+ dayStart: DAY_START,
694
+ now: NOW,
695
+ }),
696
+ ).resolves.toEqual({ spendInUSD: 0, source: "none" });
697
+ });
698
+
699
+ test("treats a zero-valued span bucket as no span spend", async () => {
700
+ mockSpanSpend(0);
701
+ mockMetricSpend(8);
702
+
703
+ await expect(
704
+ LlmCostBudgetEvaluator.resolveSpend({
705
+ budget: makeBudget(),
706
+ dayStart: DAY_START,
707
+ now: NOW,
708
+ }),
709
+ ).resolves.toEqual({ spendInUSD: 8, source: "metrics" });
710
+ });
711
+
712
+ test("a zero metric total still resolves to 'none', not 'metrics'", async () => {
713
+ mockMetricSpend(0);
714
+
715
+ await expect(
716
+ LlmCostBudgetEvaluator.resolveSpend({
717
+ budget: makeBudget(),
718
+ dayStart: DAY_START,
719
+ now: NOW,
720
+ }),
721
+ ).resolves.toEqual({ spendInUSD: 0, source: "none" });
722
+ });
723
+
724
+ /*
725
+ * Returning 0 on a failed metric query would silently suppress a real
726
+ * breach — the same reasoning behind the span aggregate's
727
+ * timeoutOverflowMode: 'throw'. evaluateAllBudgets isolates the failure.
728
+ */
729
+ test("propagates a metric-query failure rather than reporting zero spend", async () => {
730
+ mockedMetricService.aggregateBy.mockRejectedValue(
731
+ new Error("clickhouse timeout") as never,
732
+ );
733
+
734
+ await expect(
735
+ LlmCostBudgetEvaluator.resolveSpend({
736
+ budget: makeBudget(),
737
+ dayStart: DAY_START,
738
+ now: NOW,
739
+ }),
740
+ ).rejects.toThrow("clickhouse timeout");
741
+ });
742
+
743
+ test("propagates a span-query failure without reaching the fallback", async () => {
744
+ mockedSpanService.aggregateBy.mockRejectedValue(
745
+ new Error("span boom") as never,
746
+ );
747
+
748
+ await expect(
749
+ LlmCostBudgetEvaluator.resolveSpend({
750
+ budget: makeBudget(),
751
+ dayStart: DAY_START,
752
+ now: NOW,
753
+ }),
754
+ ).rejects.toThrow("span boom");
755
+
756
+ expect(mockedMetricService.aggregateBy).not.toHaveBeenCalled();
757
+ });
758
+
759
+ test("sums multiple metric buckets", async () => {
760
+ mockUsdMetricRows([
761
+ { timestamp: NOW, value: 1.5 },
762
+ { timestamp: NOW, value: 2.5 },
763
+ ]);
764
+
765
+ await expect(
766
+ LlmCostBudgetEvaluator.resolveSpend({
767
+ budget: makeBudget(),
768
+ dayStart: DAY_START,
769
+ now: NOW,
770
+ }),
771
+ ).resolves.toEqual({ spendInUSD: 4, source: "metrics" });
772
+ });
773
+
774
+ test("passes the budget's scope through to the metric query", async () => {
775
+ const serviceId: ObjectID = ObjectID.generate();
776
+ mockMetricSpend(3);
777
+
778
+ await LlmCostBudgetEvaluator.resolveSpend({
779
+ budget: makeBudget({ serviceId: serviceId, llmSystem: "openai" }),
780
+ dayStart: DAY_START,
781
+ now: NOW,
782
+ });
783
+
784
+ const aggregateArg: { query: Record<string, unknown> } = mockedMetricService
785
+ .aggregateBy.mock.calls[0]![0] as {
786
+ query: Record<string, unknown>;
787
+ };
788
+
789
+ expect(aggregateArg.query["primaryEntityId"]).toBe(serviceId);
790
+ expect(aggregateArg.query["attributes"]).toEqual({
791
+ "gen_ai.system": "openai",
792
+ });
793
+ });
794
+ });
795
+
796
+ describe("LlmCostBudgetEvaluator.evaluateBudget — metric-sourced spend", () => {
797
+ beforeEach(() => {
798
+ jest.clearAllMocks();
799
+ mockedSpanService.aggregateBy.mockResolvedValue({ data: [] } as never);
800
+ mockedMetricService.aggregateBy.mockResolvedValue({ data: [] } as never);
801
+ mockedMetricService.insertJsonRows.mockResolvedValue(undefined as never);
802
+ mockedBudgetService.updateOneById.mockResolvedValue(undefined as never);
803
+ mockedTelemetryUtil.indexMetricNameServiceNameMap.mockResolvedValue(
804
+ undefined as never,
805
+ );
806
+ });
807
+
808
+ test("a metrics-only project gets its spend stamped on the budget row", async () => {
809
+ mockUsdMetricRows([{ timestamp: NOW, value: 60 }]);
810
+
811
+ const budget: LlmCostBudget = makeBudget({ dailyBudgetInUSD: 100 });
812
+
813
+ await LlmCostBudgetEvaluator.evaluateBudget({ budget, now: NOW });
814
+
815
+ const updateArg: { data: Record<string, unknown> } = mockedBudgetService
816
+ .updateOneById.mock.calls[0]![0] as {
817
+ data: Record<string, unknown>;
818
+ };
819
+
820
+ expect(updateArg.data["currentDaySpendInUSD"]).toBe(60);
821
+ });
822
+
823
+ test("a metrics-only project publishes the same budget series as a span-backed one", async () => {
824
+ mockUsdMetricRows([{ timestamp: NOW, value: 80 }]);
825
+
826
+ await LlmCostBudgetEvaluator.evaluateBudget({
827
+ budget: makeBudget({ dailyBudgetInUSD: 100 }),
828
+ now: NOW,
829
+ });
830
+
831
+ const rows: Array<Record<string, unknown>> = mockedMetricService
832
+ .insertJsonRows.mock.calls[0]![0] as Array<Record<string, unknown>>;
833
+
834
+ expect(rows).toHaveLength(2);
835
+ expect(rows[0]!["name"]).toBe(LLM_BUDGET_SPEND_METRIC_NAME);
836
+ expect(rows[0]!["value"]).toBe(80);
837
+ expect(rows[1]!["name"]).toBe(LLM_BUDGET_PERCENT_METRIC_NAME);
838
+ expect(rows[1]!["value"]).toBe(80);
839
+ });
840
+
841
+ /*
842
+ * The published series must stay byte-identical to what a span-backed budget
843
+ * emits — existing monitors filter on oneuptime.llm.budget.id and must not
844
+ * have to learn about the source.
845
+ */
846
+ test("the published series carries no source-specific attribute", async () => {
847
+ mockUsdMetricRows([{ timestamp: NOW, value: 5 }]);
848
+
849
+ const budget: LlmCostBudget = makeBudget();
850
+
851
+ await LlmCostBudgetEvaluator.evaluateBudget({ budget, now: NOW });
852
+
853
+ const rows: Array<Record<string, unknown>> = mockedMetricService
854
+ .insertJsonRows.mock.calls[0]![0] as Array<Record<string, unknown>>;
855
+
856
+ const attributes: Record<string, string> = rows[0]!["attributes"] as Record<
857
+ string,
858
+ string
859
+ >;
860
+
861
+ expect(Object.keys(attributes).sort()).toEqual(
862
+ [LLM_BUDGET_ID_ATTRIBUTE, LLM_BUDGET_NAME_ATTRIBUTE].sort(),
863
+ );
864
+ });
865
+
866
+ test("an idle project still stamps zero and publishes its series", async () => {
867
+ await LlmCostBudgetEvaluator.evaluateBudget({
868
+ budget: makeBudget(),
869
+ now: NOW,
870
+ });
871
+
872
+ const updateArg: { data: Record<string, unknown> } = mockedBudgetService
873
+ .updateOneById.mock.calls[0]![0] as {
874
+ data: Record<string, unknown>;
875
+ };
876
+
877
+ expect(updateArg.data["currentDaySpendInUSD"]).toBe(0);
878
+ expect(mockedMetricService.insertJsonRows).toHaveBeenCalledTimes(1);
879
+ });
880
+ });