@oneuptime/common 12.0.22 → 12.0.24

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 (345) hide show
  1. package/Models/DatabaseModels/DetectionRule.ts +55 -0
  2. package/Models/DatabaseModels/Index.ts +2 -0
  3. package/Models/DatabaseModels/NetworkDevice.ts +44 -0
  4. package/Models/DatabaseModels/NetworkDeviceAutoImportRule.ts +584 -0
  5. package/Models/DatabaseModels/NetworkDeviceDiscoveryScan.ts +105 -0
  6. package/Models/DatabaseModels/Project.ts +68 -0
  7. package/Models/DatabaseModels/User.ts +68 -0
  8. package/Server/API/TelemetryAPI.ts +29 -0
  9. package/Server/Infrastructure/Postgres/SchemaMigrations/1789100000000-AddNetworkDeviceAutoImportRule.ts +60 -0
  10. package/Server/Infrastructure/Postgres/SchemaMigrations/1789200000000-AddSysObjectIdPatternToAutoImportRule.ts +26 -0
  11. package/Server/Infrastructure/Postgres/SchemaMigrations/1789300000000-AddAutoApplyVendorHealthTemplate.ts +26 -0
  12. package/Server/Infrastructure/Postgres/SchemaMigrations/1789400000000-AddNameToNetworkDeviceDiscoveryScan.ts +28 -0
  13. package/Server/Infrastructure/Postgres/SchemaMigrations/1789500000000-AddCampaignUtmFields.ts +49 -0
  14. package/Server/Infrastructure/Postgres/SchemaMigrations/1789512000000-AddDetectionRuleDistinctCountColumns.ts +33 -0
  15. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +12 -0
  16. package/Server/Middleware/GzipRequestBody.ts +311 -0
  17. package/Server/Middleware/MultipartFormData.ts +87 -3
  18. package/Server/Services/DetectionRuleService.ts +73 -6
  19. package/Server/Services/Index.ts +207 -0
  20. package/Server/Services/NetworkDeviceAutoImportRuleEngineService.ts +917 -0
  21. package/Server/Services/NetworkDeviceAutoImportRuleService.ts +181 -0
  22. package/Server/Services/NetworkDeviceDiscoveryScanService.ts +59 -0
  23. package/Server/Services/NetworkDeviceService.ts +148 -0
  24. package/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.ts +65 -0
  25. package/Server/Services/OnCallDutyPolicyFeedService.ts +1 -1
  26. package/Server/Services/ProjectService.ts +29 -19
  27. package/Server/Services/SecurityEventService.ts +90 -13
  28. package/Server/Services/StatusPageResourceService.ts +223 -0
  29. package/Server/Services/TelemetryAttributeService.ts +17 -0
  30. package/Server/Services/UserService.ts +4 -6
  31. package/Server/Types/Markdown.ts +161 -67
  32. package/Server/Utils/AI/Toolbox/OnCallTools.ts +12 -4
  33. package/Server/Utils/AnalyticsDatabase/Statement.ts +13 -1
  34. package/Server/Utils/AnalyticsDatabase/StatementGenerator.ts +297 -6
  35. package/Server/Utils/Attribution.ts +4 -0
  36. package/Server/Utils/Marketing/MarketingEventUtil.ts +45 -7
  37. package/Server/Utils/Monitor/NetworkInventoryUtil.ts +39 -1
  38. package/Server/Utils/SecurityEvent/DetectionRuleEvaluator.ts +55 -3
  39. package/Server/Utils/SecurityEvent/Sigma/SigmaClickhouseCompiler.ts +21 -0
  40. package/Server/Utils/StartServer.ts +12 -32
  41. package/Server/Utils/Telemetry/LlmCostBudgetEvaluator.ts +101 -4
  42. package/Server/Utils/Telemetry/LlmMetricSpend.ts +130 -0
  43. package/Server/Views/Partials/AnalyticsConsent.ejs +159 -102
  44. package/Server/Views/Partials/Head.ejs +2 -1
  45. package/Tests/App/Dashboard/AdminUserNotificationMethodsPage.test.tsx +776 -38
  46. package/Tests/App/Dashboard/CorrelateFilterBuilder.test.tsx +359 -0
  47. package/Tests/App/Dashboard/CorrelateGraph.test.tsx +865 -0
  48. package/Tests/App/Dashboard/CorrelationGraph.test.ts +346 -0
  49. package/Tests/App/Dashboard/CriteriaFilterConditionDropdown.test.tsx +256 -0
  50. package/Tests/App/Dashboard/CriteriaFilterDefaults.test.ts +738 -0
  51. package/Tests/App/Dashboard/CriteriaFilterMonitorTypeChange.test.ts +1122 -0
  52. package/Tests/App/Dashboard/DiscoveryScanWizardValidation.test.tsx +283 -0
  53. package/Tests/App/Dashboard/ExternalStatusPageCriteriaFilter.test.ts +407 -0
  54. package/Tests/App/Dashboard/MetricSeriesInvestigateMenu.test.tsx +5 -14
  55. package/Tests/App/Dashboard/MonitorCriteriaActionToggles.test.tsx +426 -0
  56. package/Tests/App/Dashboard/MonitorStepsCriteriaAlignmentWiring.test.tsx +352 -0
  57. package/Tests/App/Dashboard/OnCallLayerCardOverrides.test.tsx +278 -0
  58. package/Tests/App/Dashboard/OnCallLayerShiftPreviewOverrides.test.ts +237 -0
  59. package/Tests/App/Dashboard/OnCallReadinessSurfaces.test.tsx +2 -2
  60. package/Tests/App/Dashboard/OnCallSchedulePreviewOverrides.test.tsx +460 -0
  61. package/Tests/App/Dashboard/SecurityEventAttributeUtil.test.ts +171 -0
  62. package/Tests/App/Dashboard/SecurityEventCorrelation.test.ts +857 -0
  63. package/Tests/App/Dashboard/SecurityEventDetailObservables.test.tsx +194 -0
  64. package/Tests/App/Dashboard/SecurityEventsDetectionRulesPage.test.tsx +124 -0
  65. package/Tests/App/Dashboard/SecurityEventsMonitorStepForm.test.tsx +79 -19
  66. package/Tests/App/Dashboard/SecurityEventsTableColumns.test.tsx +382 -0
  67. package/Tests/App/StatusPage/BulkAddStatusPageMonitors.test.ts +216 -0
  68. package/Tests/App/StatusPage/BulkAddStatusPageMonitorsModal.test.tsx +590 -11
  69. package/Tests/App/StatusPage/StatusPageResourceExplorer.test.tsx +757 -0
  70. package/Tests/Models/DiscoveryScanNameColumn.test.ts +293 -0
  71. package/Tests/Server/API/SecurityEventAttributesAPI.test.ts +564 -0
  72. package/Tests/Server/Infrastructure/Postgres/SchemaMigrationsOrdering.test.ts +120 -4
  73. package/Tests/Server/Middleware/GzipRequestBody.test.ts +725 -0
  74. package/Tests/Server/Middleware/MultipartFormData.test.ts +298 -0
  75. package/Tests/Server/Services/AddDetectionRuleDistinctCountColumnsMigration.test.ts +311 -0
  76. package/Tests/Server/Services/AutoImportScanCredentialSelect.test.ts +205 -0
  77. package/Tests/Server/Services/DetectionRuleService.test.ts +134 -2
  78. package/Tests/Server/Services/DiscoveryScanClaimHookFreeSafety.test.ts +7 -1
  79. package/Tests/Server/Services/FeedRetentionConsistency.test.ts +131 -0
  80. package/Tests/Server/Services/NetworkDeviceAutoImportRuleEngineService.test.ts +933 -0
  81. package/Tests/Server/Services/NetworkDeviceDiscoveryScanService.test.ts +194 -0
  82. package/Tests/Server/Services/NetworkDeviceMonitorStatusStamp.test.ts +800 -0
  83. package/Tests/Server/Services/OnCallScheduleAttachRosterRefresh.test.ts +244 -0
  84. package/Tests/Server/Services/SecurityEventService.test.ts +376 -0
  85. package/Tests/Server/Services/StatusPageResourceDuplicates.test.ts +703 -0
  86. package/Tests/Server/Services/TelemetryAttributeServiceSecurityEvent.test.ts +256 -0
  87. package/Tests/Server/Types/Workflow/Components/ComponentRegistryParity.test.ts +417 -0
  88. package/Tests/Server/Utils/AnalyticsDatabase/StatementGeneratorWhereOperators.test.ts +677 -0
  89. package/Tests/Server/Utils/Marketing/MarketingEventUtil.test.ts +43 -0
  90. package/Tests/Server/Utils/Monitor/Criteria/ProfileMonitorCriteria.test.ts +15 -11
  91. package/Tests/Server/Utils/Monitor/NetworkInventoryUtil.test.ts +97 -1
  92. package/Tests/Server/Utils/SecurityEvent/DetectionRuleEvaluator.test.ts +369 -8
  93. package/Tests/Server/Utils/SecurityEvent/SigmaClickhouseCompiler.test.ts +35 -0
  94. package/Tests/Server/Utils/Telemetry/LlmCostBudgetEvaluator.test.ts +368 -4
  95. package/Tests/Server/Utils/Telemetry/LlmMetricSpend.test.ts +245 -0
  96. package/Tests/Server/Views/AnalyticsConsentPartial.test.ts +48 -5
  97. package/Tests/Types/Code/YamlSyntax.test.ts +396 -0
  98. package/Tests/Types/Monitor/MetricAndProfileDefaultCriteria.test.ts +957 -0
  99. package/Tests/Types/Monitor/MonitorCriteriaActionValidation.test.ts +598 -0
  100. package/Tests/Types/Monitor/MonitorCriteriaInstance.test.ts +49 -0
  101. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +6 -6
  102. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.test.ts +4 -4
  103. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationUtil.test.ts +4 -3
  104. package/Tests/Types/Telemetry/LlmMetricConventions.test.ts +193 -0
  105. package/Tests/UI/Components/AiInvestigationSettingsCard.test.tsx +0 -12
  106. package/Tests/UI/Components/CardModelDetailEdit.test.tsx +1 -17
  107. package/Tests/UI/Components/CodeEditor.test.tsx +474 -10
  108. package/Tests/UI/Components/Detail/YamlField.test.tsx +105 -0
  109. package/Tests/UI/Components/EntityDropdownLabelsBulkAdd.test.tsx +319 -0
  110. package/Tests/UI/Components/Forms/FormFieldYaml.test.tsx +231 -0
  111. package/Tests/UI/Components/Forms/Utils/FormFieldSchemaTypeUtil.test.ts +1 -0
  112. package/Tests/UI/Components/Forms/ValidationYAML.test.ts +234 -0
  113. package/Tests/UI/Components/ModelTable/AttributeColumns.test.tsx +573 -0
  114. package/Tests/UI/Components/ModelTable/BaseModelTableAttributeColumns.test.tsx +824 -0
  115. package/Tests/UI/Components/ModelTable/ColumnCustomizationModalAddableColumns.test.tsx +707 -0
  116. package/Tests/UI/Components/SideOver.test.tsx +1 -1
  117. package/Tests/UI/Components/StatusPage/ResourceGridSelection.test.tsx +294 -0
  118. package/Tests/UI/Components/StatusPage/ResourceListSelection.test.tsx +436 -0
  119. package/Tests/UI/Components/TableBulkCsvExport.test.tsx +6 -2
  120. package/Tests/UI/Components/Toggle.test.tsx +25 -0
  121. package/Tests/UI/Components/YamlEditor.test.tsx +847 -0
  122. package/Tests/Utils/NetworkDevice/DeviceReachabilityUtil.test.ts +252 -0
  123. package/Tests/Utils/NetworkDiscovery/AutoImportRuleMatcher.test.ts +516 -0
  124. package/Tests/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.test.ts +272 -0
  125. package/Tests/Utils/NetworkDiscovery/DiscoveredHostUtil.test.ts +221 -0
  126. package/Tests/Utils/NetworkDiscovery/ScanNameUtil.test.ts +312 -0
  127. package/Tests/Utils/NetworkDiscovery/ScanTargetUtil.test.ts +164 -0
  128. package/Tests/Utils/StatusPage/ResourceExplorer.test.ts +468 -0
  129. package/Tests/Utils/Telemetry/LlmMetricQuery.test.ts +472 -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/NetworkAutomation/RuleRunResult.ts +84 -0
  138. package/Types/Permission.ts +47 -0
  139. package/Types/SecurityEvent/DetectionFindingConstants.ts +11 -0
  140. package/Types/Telemetry/LlmMetricConventions.ts +124 -0
  141. package/UI/Components/AutocompleteTextInput/AutocompleteTextInput.tsx +3 -0
  142. package/UI/Components/BulkUpdate/BulkUpdateForm.tsx +10 -1
  143. package/UI/Components/CodeEditor/CodeEditor.tsx +241 -79
  144. package/UI/Components/CodeEditor/YamlEditor.tsx +369 -0
  145. package/UI/Components/Detail/Detail.tsx +10 -0
  146. package/UI/Components/EntityDropdown/EntityDropdown.tsx +33 -0
  147. package/UI/Components/Forms/Fields/FormField.tsx +31 -0
  148. package/UI/Components/Forms/Types/Field.ts +8 -0
  149. package/UI/Components/Forms/Types/FormFieldSchemaType.ts +1 -0
  150. package/UI/Components/Forms/Utils/FormFieldSchemaTypeUtil.ts +2 -0
  151. package/UI/Components/Forms/Validation.ts +46 -0
  152. package/UI/Components/Input/Input.tsx +3 -0
  153. package/UI/Components/ModelTable/AttributeColumns.tsx +321 -0
  154. package/UI/Components/ModelTable/BaseModelTable.tsx +263 -14
  155. package/UI/Components/ModelTable/Column.ts +8 -0
  156. package/UI/Components/ModelTable/ColumnCustomizationModal.tsx +310 -0
  157. package/UI/Components/ModelTable/ColumnPreference.ts +13 -1
  158. package/UI/Components/MonitorTemplateVariables/TemplateVariablesModal.tsx +2 -2
  159. package/UI/Components/SideOver/SideOver.tsx +5 -5
  160. package/UI/Components/StatusPage/ResourceGrid.tsx +82 -2
  161. package/UI/Components/StatusPage/ResourceList.tsx +197 -38
  162. package/UI/Components/Toggle/Toggle.tsx +9 -1
  163. package/UI/Components/Types/FieldType.ts +1 -0
  164. package/Utils/NetworkDevice/DeviceReachabilityUtil.ts +73 -1
  165. package/Utils/NetworkDiscovery/AutoImportRuleMatcher.ts +257 -0
  166. package/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.ts +183 -0
  167. package/Utils/NetworkDiscovery/DiscoveredHostUtil.ts +95 -0
  168. package/Utils/NetworkDiscovery/DiscoveryImportEligibility.ts +66 -0
  169. package/Utils/NetworkDiscovery/ScanNameUtil.ts +181 -0
  170. package/Utils/NetworkDiscovery/ScanTargetUtil.ts +82 -0
  171. package/Utils/StatusPage/ResourceExplorer.ts +258 -0
  172. package/Utils/Telemetry/LlmMetricQuery.ts +204 -0
  173. package/build/dist/Models/DatabaseModels/DetectionRule.js +57 -0
  174. package/build/dist/Models/DatabaseModels/DetectionRule.js.map +1 -1
  175. package/build/dist/Models/DatabaseModels/Index.js +2 -0
  176. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  177. package/build/dist/Models/DatabaseModels/NetworkDevice.js +45 -0
  178. package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
  179. package/build/dist/Models/DatabaseModels/NetworkDeviceAutoImportRule.js +609 -0
  180. package/build/dist/Models/DatabaseModels/NetworkDeviceAutoImportRule.js.map +1 -0
  181. package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js +97 -0
  182. package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js.map +1 -1
  183. package/build/dist/Models/DatabaseModels/Project.js +76 -0
  184. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  185. package/build/dist/Models/DatabaseModels/User.js +76 -0
  186. package/build/dist/Models/DatabaseModels/User.js.map +1 -1
  187. package/build/dist/Server/API/TelemetryAPI.js +17 -0
  188. package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
  189. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1789100000000-AddNetworkDeviceAutoImportRule.js +35 -0
  190. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1789100000000-AddNetworkDeviceAutoImportRule.js.map +1 -0
  191. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1789200000000-AddSysObjectIdPatternToAutoImportRule.js +19 -0
  192. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1789200000000-AddSysObjectIdPatternToAutoImportRule.js.map +1 -0
  193. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1789300000000-AddAutoApplyVendorHealthTemplate.js +19 -0
  194. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1789300000000-AddAutoApplyVendorHealthTemplate.js.map +1 -0
  195. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1789400000000-AddNameToNetworkDeviceDiscoveryScan.js +21 -0
  196. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1789400000000-AddNameToNetworkDeviceDiscoveryScan.js.map +1 -0
  197. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1789500000000-AddCampaignUtmFields.js +42 -0
  198. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1789500000000-AddCampaignUtmFields.js.map +1 -0
  199. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1789512000000-AddDetectionRuleDistinctCountColumns.js +22 -0
  200. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1789512000000-AddDetectionRuleDistinctCountColumns.js.map +1 -0
  201. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +12 -0
  202. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  203. package/build/dist/Server/Middleware/GzipRequestBody.js +224 -0
  204. package/build/dist/Server/Middleware/GzipRequestBody.js.map +1 -0
  205. package/build/dist/Server/Middleware/MultipartFormData.js +71 -2
  206. package/build/dist/Server/Middleware/MultipartFormData.js.map +1 -1
  207. package/build/dist/Server/Services/DetectionRuleService.js +49 -4
  208. package/build/dist/Server/Services/DetectionRuleService.js.map +1 -1
  209. package/build/dist/Server/Services/Index.js +206 -0
  210. package/build/dist/Server/Services/Index.js.map +1 -1
  211. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js +711 -0
  212. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleEngineService.js.map +1 -0
  213. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleService.js +155 -0
  214. package/build/dist/Server/Services/NetworkDeviceAutoImportRuleService.js.map +1 -0
  215. package/build/dist/Server/Services/NetworkDeviceDiscoveryScanService.js +50 -0
  216. package/build/dist/Server/Services/NetworkDeviceDiscoveryScanService.js.map +1 -1
  217. package/build/dist/Server/Services/NetworkDeviceService.js +124 -0
  218. package/build/dist/Server/Services/NetworkDeviceService.js.map +1 -1
  219. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js +68 -13
  220. package/build/dist/Server/Services/OnCallDutyPolicyEscalationRuleScheduleService.js.map +1 -1
  221. package/build/dist/Server/Services/OnCallDutyPolicyFeedService.js +1 -1
  222. package/build/dist/Server/Services/OnCallDutyPolicyFeedService.js.map +1 -1
  223. package/build/dist/Server/Services/ProjectService.js +25 -45
  224. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  225. package/build/dist/Server/Services/SecurityEventService.js +57 -5
  226. package/build/dist/Server/Services/SecurityEventService.js.map +1 -1
  227. package/build/dist/Server/Services/StatusPageResourceService.js +140 -0
  228. package/build/dist/Server/Services/StatusPageResourceService.js.map +1 -1
  229. package/build/dist/Server/Services/TelemetryAttributeService.js +17 -0
  230. package/build/dist/Server/Services/TelemetryAttributeService.js.map +1 -1
  231. package/build/dist/Server/Services/UserService.js +2 -12
  232. package/build/dist/Server/Services/UserService.js.map +1 -1
  233. package/build/dist/Server/Types/Markdown.js +147 -61
  234. package/build/dist/Server/Types/Markdown.js.map +1 -1
  235. package/build/dist/Server/Utils/AI/Toolbox/OnCallTools.js +12 -4
  236. package/build/dist/Server/Utils/AI/Toolbox/OnCallTools.js.map +1 -1
  237. package/build/dist/Server/Utils/AnalyticsDatabase/Statement.js +12 -1
  238. package/build/dist/Server/Utils/AnalyticsDatabase/Statement.js.map +1 -1
  239. package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js +246 -9
  240. package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js.map +1 -1
  241. package/build/dist/Server/Utils/Attribution.js.map +1 -1
  242. package/build/dist/Server/Utils/Marketing/MarketingEventUtil.js +27 -7
  243. package/build/dist/Server/Utils/Marketing/MarketingEventUtil.js.map +1 -1
  244. package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js +26 -0
  245. package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js.map +1 -1
  246. package/build/dist/Server/Utils/SecurityEvent/DetectionRuleEvaluator.js +42 -7
  247. package/build/dist/Server/Utils/SecurityEvent/DetectionRuleEvaluator.js.map +1 -1
  248. package/build/dist/Server/Utils/SecurityEvent/Sigma/SigmaClickhouseCompiler.js +18 -0
  249. package/build/dist/Server/Utils/SecurityEvent/Sigma/SigmaClickhouseCompiler.js.map +1 -1
  250. package/build/dist/Server/Utils/StartServer.js +12 -21
  251. package/build/dist/Server/Utils/StartServer.js.map +1 -1
  252. package/build/dist/Server/Utils/Telemetry/LlmCostBudgetEvaluator.js +76 -5
  253. package/build/dist/Server/Utils/Telemetry/LlmCostBudgetEvaluator.js.map +1 -1
  254. package/build/dist/Server/Utils/Telemetry/LlmMetricSpend.js +102 -0
  255. package/build/dist/Server/Utils/Telemetry/LlmMetricSpend.js.map +1 -0
  256. package/build/dist/Types/Code/YamlSyntax.js +212 -0
  257. package/build/dist/Types/Code/YamlSyntax.js.map +1 -0
  258. package/build/dist/Types/Exception/ExceptionCode.js +1 -0
  259. package/build/dist/Types/Exception/ExceptionCode.js.map +1 -1
  260. package/build/dist/Types/Exception/PayloadTooLargeException.js +8 -0
  261. package/build/dist/Types/Exception/PayloadTooLargeException.js.map +1 -0
  262. package/build/dist/Types/Marketing/Attribution.js +10 -0
  263. package/build/dist/Types/Marketing/Attribution.js.map +1 -1
  264. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +112 -51
  265. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
  266. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.js +2 -1
  267. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.js.map +1 -1
  268. package/build/dist/Types/NetworkAutomation/RuleRunResult.js +24 -0
  269. package/build/dist/Types/NetworkAutomation/RuleRunResult.js.map +1 -1
  270. package/build/dist/Types/Permission.js +41 -0
  271. package/build/dist/Types/Permission.js.map +1 -1
  272. package/build/dist/Types/SecurityEvent/DetectionFindingConstants.js +9 -0
  273. package/build/dist/Types/SecurityEvent/DetectionFindingConstants.js.map +1 -1
  274. package/build/dist/Types/Telemetry/LlmMetricConventions.js +98 -0
  275. package/build/dist/Types/Telemetry/LlmMetricConventions.js.map +1 -0
  276. package/build/dist/UI/Components/AutocompleteTextInput/AutocompleteTextInput.js +1 -1
  277. package/build/dist/UI/Components/AutocompleteTextInput/AutocompleteTextInput.js.map +1 -1
  278. package/build/dist/UI/Components/BulkUpdate/BulkUpdateForm.js +5 -2
  279. package/build/dist/UI/Components/BulkUpdate/BulkUpdateForm.js.map +1 -1
  280. package/build/dist/UI/Components/CodeEditor/CodeEditor.js +206 -76
  281. package/build/dist/UI/Components/CodeEditor/CodeEditor.js.map +1 -1
  282. package/build/dist/UI/Components/CodeEditor/YamlEditor.js +201 -0
  283. package/build/dist/UI/Components/CodeEditor/YamlEditor.js.map +1 -0
  284. package/build/dist/UI/Components/Detail/Detail.js +9 -0
  285. package/build/dist/UI/Components/Detail/Detail.js.map +1 -1
  286. package/build/dist/UI/Components/EntityDropdown/EntityDropdown.js +16 -1
  287. package/build/dist/UI/Components/EntityDropdown/EntityDropdown.js.map +1 -1
  288. package/build/dist/UI/Components/Forms/Fields/FormField.js +14 -1
  289. package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
  290. package/build/dist/UI/Components/Forms/Types/Field.js.map +1 -1
  291. package/build/dist/UI/Components/Forms/Types/FormFieldSchemaType.js +1 -0
  292. package/build/dist/UI/Components/Forms/Types/FormFieldSchemaType.js.map +1 -1
  293. package/build/dist/UI/Components/Forms/Utils/FormFieldSchemaTypeUtil.js +2 -0
  294. package/build/dist/UI/Components/Forms/Utils/FormFieldSchemaTypeUtil.js.map +1 -1
  295. package/build/dist/UI/Components/Forms/Validation.js +27 -0
  296. package/build/dist/UI/Components/Forms/Validation.js.map +1 -1
  297. package/build/dist/UI/Components/Input/Input.js +1 -1
  298. package/build/dist/UI/Components/Input/Input.js.map +1 -1
  299. package/build/dist/UI/Components/ModelTable/AttributeColumns.js +159 -0
  300. package/build/dist/UI/Components/ModelTable/AttributeColumns.js.map +1 -0
  301. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +179 -17
  302. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  303. package/build/dist/UI/Components/ModelTable/ColumnCustomizationModal.js +133 -2
  304. package/build/dist/UI/Components/ModelTable/ColumnCustomizationModal.js.map +1 -1
  305. package/build/dist/UI/Components/ModelTable/ColumnPreference.js +7 -1
  306. package/build/dist/UI/Components/ModelTable/ColumnPreference.js.map +1 -1
  307. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesModal.js +2 -2
  308. package/build/dist/UI/Components/SideOver/SideOver.js +5 -5
  309. package/build/dist/UI/Components/StatusPage/ResourceGrid.js +28 -2
  310. package/build/dist/UI/Components/StatusPage/ResourceGrid.js.map +1 -1
  311. package/build/dist/UI/Components/StatusPage/ResourceList.js +87 -20
  312. package/build/dist/UI/Components/StatusPage/ResourceList.js.map +1 -1
  313. package/build/dist/UI/Components/Toggle/Toggle.js +9 -1
  314. package/build/dist/UI/Components/Toggle/Toggle.js.map +1 -1
  315. package/build/dist/UI/Components/Types/FieldType.js +1 -0
  316. package/build/dist/UI/Components/Types/FieldType.js.map +1 -1
  317. package/build/dist/Utils/NetworkDevice/DeviceReachabilityUtil.js +37 -1
  318. package/build/dist/Utils/NetworkDevice/DeviceReachabilityUtil.js.map +1 -1
  319. package/build/dist/Utils/NetworkDiscovery/AutoImportRuleMatcher.js +149 -0
  320. package/build/dist/Utils/NetworkDiscovery/AutoImportRuleMatcher.js.map +1 -0
  321. package/build/dist/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.js +121 -0
  322. package/build/dist/Utils/NetworkDiscovery/DiscoveredDeviceBuilder.js.map +1 -0
  323. package/build/dist/Utils/NetworkDiscovery/DiscoveredHostUtil.js +75 -0
  324. package/build/dist/Utils/NetworkDiscovery/DiscoveredHostUtil.js.map +1 -0
  325. package/build/dist/Utils/NetworkDiscovery/DiscoveryImportEligibility.js +59 -0
  326. package/build/dist/Utils/NetworkDiscovery/DiscoveryImportEligibility.js.map +1 -0
  327. package/build/dist/Utils/NetworkDiscovery/ScanNameUtil.js +120 -0
  328. package/build/dist/Utils/NetworkDiscovery/ScanNameUtil.js.map +1 -0
  329. package/build/dist/Utils/NetworkDiscovery/ScanTargetUtil.js +60 -0
  330. package/build/dist/Utils/NetworkDiscovery/ScanTargetUtil.js.map +1 -1
  331. package/build/dist/Utils/StatusPage/ResourceExplorer.js +171 -0
  332. package/build/dist/Utils/StatusPage/ResourceExplorer.js.map +1 -1
  333. package/build/dist/Utils/Telemetry/LlmMetricQuery.js +119 -0
  334. package/build/dist/Utils/Telemetry/LlmMetricQuery.js.map +1 -0
  335. package/jest.config.json +2 -0
  336. package/package.json +1 -1
  337. package/tsconfig.json +2 -1
  338. package/Tests/UI/Components/Toast.test.tsx +0 -197
  339. package/Tests/UI/Components/ToastStacking.test.tsx +0 -198
  340. package/UI/Components/Toast/Toast.tsx +0 -189
  341. package/UI/Components/Toast/ToastInit.tsx +0 -110
  342. package/build/dist/UI/Components/Toast/Toast.js +0 -123
  343. package/build/dist/UI/Components/Toast/Toast.js.map +0 -1
  344. package/build/dist/UI/Components/Toast/ToastInit.js +0 -53
  345. package/build/dist/UI/Components/Toast/ToastInit.js.map +0 -1
@@ -242,6 +242,27 @@ export function buildSigmaFieldExpression(field: string): Statement {
242
242
  return new Statement([resolved.column], []);
243
243
  }
244
244
 
245
+ /*
246
+ * buildSigmaFieldExpression with the column's "unset" sentinel normalized
247
+ * away, for distinct counting. Text and attribute lookups yield '' when
248
+ * absent, which the caller's nullIf(expr, '') already excludes — but the
249
+ * number columns are non-Nullable with 0 as their documented
250
+ * not-applicable value, and toString(0) is '0', not ''. Mapping 0 to NULL
251
+ * here, where the column type is known, keeps a portless event from
252
+ * counting as distinct port "0" in a port-scan rule. severityId 0 (OCSF
253
+ * Unknown) is deliberately treated as missing too, consistent with the
254
+ * empty-string rule for text.
255
+ */
256
+ export function buildSigmaDistinctCountExpression(field: string): Statement {
257
+ const resolved: ResolvedField = resolveSigmaField(field);
258
+
259
+ if (resolved.kind === "numberColumn") {
260
+ return new Statement([`toString(nullIf(${resolved.column}, 0))`], []);
261
+ }
262
+
263
+ return buildSigmaFieldExpression(field);
264
+ }
265
+
245
266
  export default class SigmaClickhouseCompiler {
246
267
  /*
247
268
  * Compile a rule (or raw YAML) into a boolean SQL expression. The
@@ -9,6 +9,7 @@ import {
9
9
  } from "../EnvironmentConfig";
10
10
  import LocalCache from "../Infrastructure/LocalCache";
11
11
  import HttpMetricsMiddleware from "../Middleware/HttpMetricsMiddleware";
12
+ import GzipRequestBodyMiddleware from "../Middleware/GzipRequestBody";
12
13
  import CorsOptions, {
13
14
  CORS_EXPOSED_HEADERS,
14
15
  CORS_PREFLIGHT_MAX_AGE_SECONDS,
@@ -41,7 +42,6 @@ import StatusCode from "../../Types/API/StatusCode";
41
42
  import HTTPErrorResponse from "../../Types/API/HTTPErrorResponse";
42
43
  import Exception from "../../Types/Exception/Exception";
43
44
  import NotFoundException from "../../Types/Exception/NotFoundException";
44
- import ServerException from "../../Types/Exception/ServerException";
45
45
  import { PromiseVoidFunction } from "../../Types/FunctionTypes";
46
46
  import { JSONObject } from "../../Types/JSON";
47
47
  import JSONFunctions from "../../Types/JSONFunctions";
@@ -49,7 +49,6 @@ import Port from "../../Types/Port";
49
49
  import Typeof from "../../Types/Typeof";
50
50
  import CookieParser from "cookie-parser";
51
51
  import cors from "cors";
52
- import zlib from "zlib";
53
52
  import crypto from "crypto";
54
53
  import path from "path";
55
54
  import "ejs";
@@ -206,10 +205,11 @@ app.use((req: OneUptimeRequest, res: ExpressResponse, next: NextFunction) => {
206
205
  * several prefixes, so /telemetry/otlp/v1/... and
207
206
  * /telemetry/session-replay/v1/... are equally live. A prefix-anchored
208
207
  * test would let the prefixed path fall into the gzip fast-path below,
209
- * which has NO size limit and no content-length pre-check (a zip-bomb
210
- * vector on a public browser endpoint) and which sets req.body to the
211
- * DECOMPRESSED buffer that in turn trips the ingest middleware's
212
- * "already parsed" early-out, so its byte cap would never run at all.
208
+ * which sets req.body to the DECOMPRESSED buffer that in turn trips
209
+ * the ingest middleware's "already parsed" early-out, so its own,
210
+ * tighter, byte cap would never run at all. (The fast path has its own
211
+ * limits since GHSA-cp58-wc9q-qv53, but they are the generic 50 MiB
212
+ * body-parser numbers, not the 4 MiB these routes are sized for.)
213
213
  */
214
214
  if (
215
215
  req.path.includes("/otlp/v1/") ||
@@ -226,32 +226,12 @@ app.use((req: OneUptimeRequest, res: ExpressResponse, next: NextFunction) => {
226
226
  );
227
227
 
228
228
  if (contentEncoding?.includes("gzip")) {
229
- const buffers: any = [];
230
-
231
- req.on("data", (chunk: any) => {
232
- buffers.push(chunk);
233
- });
234
-
235
- req.on("end", () => {
236
- const buffer: Buffer = Buffer.concat(buffers);
237
- zlib.gunzip(buffer as Uint8Array, (err: unknown, decoded: Buffer) => {
238
- if (err) {
239
- logger.error(
240
- err,
241
- getLogAttributesFromRequest(req as OneUptimeRequest),
242
- );
243
- return Response.sendErrorResponse(
244
- req,
245
- res,
246
- new ServerException("Error decompressing data"),
247
- );
248
- }
249
-
250
- req.body = decoded;
251
-
252
- next();
253
- });
254
- });
229
+ /*
230
+ * Bounded on both sides - see GzipRequestBody. This used to buffer the
231
+ * whole compressed body and hand it to an unbounded zlib.gunzip, which
232
+ * turned 130 KB of anonymous request into 128 MiB of resident Buffer.
233
+ */
234
+ GzipRequestBodyMiddleware.parseBody(req, res, next);
255
235
  } else if (
256
236
  contentType &&
257
237
  (contentType.includes("application/x-protobuf") ||
@@ -19,14 +19,22 @@ import MetricService from "../../Services/MetricService";
19
19
  import SpanService from "../../Services/SpanService";
20
20
  import logger, { LogAttributes } from "../Logger";
21
21
  import CaptureSpan from "../Telemetry/CaptureSpan";
22
+ import LlmMetricSpend, { LlmMetricScope } from "./LlmMetricSpend";
22
23
  import TelemetryUtil from "./Telemetry";
23
24
 
24
25
  /*
25
- * Evaluates LLM cost budgets against the day's LLM span spend.
26
+ * Evaluates LLM cost budgets against the day's LLM spend.
27
+ *
28
+ * Spend is sourced from GenAI trace spans first and, when a scope produced no
29
+ * span spend at all, from the GenAI metric stream instead (see resolveSpend
30
+ * and Common/Server/Utils/Telemetry/LlmMetricSpend.ts). That second source is
31
+ * what lets a metrics-only emitter — an SDK exporting metrics without traces,
32
+ * or a gateway that publishes spend counters and no spans — hold a budget at
33
+ * all. The two are never summed; see resolveSpend for why.
26
34
  *
27
35
  * The worker job (App/FeatureSet/Workers/Jobs/Llm/EvaluateLlmCostBudgets.ts)
28
36
  * calls evaluateAllBudgets() on a 15-minute tick. For each enabled budget it
29
- * sums the UTC day's llmCost from ClickHouse (scoped by the budget's optional
37
+ * sums the UTC day's spend from ClickHouse (scoped by the budget's optional
30
38
  * service / provider / model filters), stamps the spend back onto the budget
31
39
  * row for the dashboard, and publishes two gauge metrics:
32
40
  *
@@ -65,6 +73,17 @@ export const LLM_BUDGET_SERVICE_ID_ATTRIBUTE: string =
65
73
  */
66
74
  const BUDGET_METRIC_RETENTION_IN_DAYS: number = 15;
67
75
 
76
+ /*
77
+ * Which telemetry signal a budget's spend figure came from. "none" means both
78
+ * sources were empty — a genuinely idle scope, not a failure.
79
+ */
80
+ export type LlmSpendSource = "spans" | "metrics" | "none";
81
+
82
+ export interface LlmResolvedSpend {
83
+ spendInUSD: number;
84
+ source: LlmSpendSource;
85
+ }
86
+
68
87
  export default class LlmCostBudgetEvaluator {
69
88
  /**
70
89
  * Percent of the daily budget consumed. 0 when the budget is missing or
@@ -262,12 +281,18 @@ export default class LlmCostBudgetEvaluator {
262
281
 
263
282
  const dayStart: Date = this.getUtcDayStart(data.now);
264
283
 
265
- const spendInUSD: number = await this.getSpendInUSD({
284
+ const resolved: LlmResolvedSpend = await this.resolveSpend({
266
285
  budget: budget,
267
286
  dayStart: dayStart,
268
287
  now: data.now,
269
288
  });
270
289
 
290
+ const spendInUSD: number = resolved.spendInUSD;
291
+
292
+ logger.debug(
293
+ `LLM cost budget ${budget.id.toString()}: spend ${spendInUSD} USD sourced from ${resolved.source}`,
294
+ );
295
+
271
296
  const percentUsed: number = this.computePercentUsed({
272
297
  spendInUSD: spendInUSD,
273
298
  dailyBudgetInUSD: budget.dailyBudgetInUSD,
@@ -293,11 +318,83 @@ export default class LlmCostBudgetEvaluator {
293
318
  });
294
319
  }
295
320
 
321
+ /**
322
+ * Translate a budget's scope into the equivalent metric-stream scope, so
323
+ * the span query and the metric query narrow to the same slice of traffic.
324
+ *
325
+ * Service scoping is exact — Span.primaryEntityId and Metric.primaryEntityId
326
+ * are the same telemetry-service id. Provider/model scoping matches the
327
+ * primary semantic-convention attribute keys only; see the caveat on
328
+ * LlmMetricSpend.
329
+ */
330
+ public static buildMetricScope(data: {
331
+ budget: LlmCostBudget;
332
+ dayStart: Date;
333
+ now: Date;
334
+ }): LlmMetricScope {
335
+ return {
336
+ projectId: data.budget.projectId!,
337
+ startTime: data.dayStart,
338
+ endTime: data.now,
339
+ serviceId: data.budget.serviceId,
340
+ llmSystem: data.budget.llmSystem,
341
+ llmModel: data.budget.llmModel,
342
+ };
343
+ }
344
+
345
+ /**
346
+ * The day's spend for a budget, and which telemetry signal it came from.
347
+ *
348
+ * Spans are authoritative: a GenAI span carries model, tokens and cost on
349
+ * one row, and it is the only source that can also back the per-call views.
350
+ * Metrics are consulted ONLY when the span-sourced total is zero.
351
+ *
352
+ * That ordering is a deliberate fallback rather than a sum. Instrumentations
353
+ * that emit both signals (OpenLLMetry is the common case) would otherwise be
354
+ * counted twice, and for a budget that gates alerting an inflated figure is
355
+ * worse than a missing one — it fires on spend that never happened. The
356
+ * fallback turns on exactly for the emitters that need it: those publishing
357
+ * GenAI metrics and no GenAI spans, whose span total is structurally zero.
358
+ *
359
+ * Known limit, documented rather than papered over: a scope where SOME
360
+ * services emit spans and others emit only metrics resolves to "spans" and
361
+ * under-counts the metrics-only services. Splitting a budget per service is
362
+ * the workaround; scoping each to its own service gives each the source it
363
+ * actually has.
364
+ *
365
+ * A metric-query failure is allowed to propagate for the same reason the
366
+ * span aggregate passes timeoutOverflowMode 'throw': returning 0 on error
367
+ * would silently suppress a real breach. evaluateAllBudgets isolates the
368
+ * failure to the one budget.
369
+ */
370
+ @CaptureSpan()
371
+ public static async resolveSpend(data: {
372
+ budget: LlmCostBudget;
373
+ dayStart: Date;
374
+ now: Date;
375
+ }): Promise<LlmResolvedSpend> {
376
+ const spanSpend: number = await this.getSpanSpendInUSD(data);
377
+
378
+ if (spanSpend > 0) {
379
+ return { spendInUSD: spanSpend, source: "spans" };
380
+ }
381
+
382
+ const metricSpend: number = await LlmMetricSpend.getCostInUSD(
383
+ this.buildMetricScope(data),
384
+ );
385
+
386
+ if (metricSpend > 0) {
387
+ return { spendInUSD: metricSpend, source: "metrics" };
388
+ }
389
+
390
+ return { spendInUSD: 0, source: "none" };
391
+ }
392
+
296
393
  /**
297
394
  * Sum the day's llmCost for the budget's scope from ClickHouse.
298
395
  */
299
396
  @CaptureSpan()
300
- private static async getSpendInUSD(data: {
397
+ private static async getSpanSpendInUSD(data: {
301
398
  budget: LlmCostBudget;
302
399
  dayStart: Date;
303
400
  now: Date;
@@ -0,0 +1,130 @@
1
+ import Metric from "../../../Models/AnalyticsModels/Metric";
2
+ import AggregatedResult from "../../../Types/BaseDatabase/AggregatedResult";
3
+ import AggregationInterval from "../../../Types/BaseDatabase/AggregationInterval";
4
+ import AggregationType from "../../../Types/BaseDatabase/AggregationType";
5
+ import { LIMIT_PER_PROJECT } from "../../../Types/Database/LimitMax";
6
+ import { LlmTokenTypeAttributeKeys } from "../../../Types/Telemetry/LlmMetricConventions";
7
+ import LlmMetricQuery, {
8
+ LlmMetricScope,
9
+ LlmMetricTokenTotals,
10
+ } from "../../../Utils/Telemetry/LlmMetricQuery";
11
+ import AggregateBy from "../../Types/AnalyticsDatabase/AggregateBy";
12
+ import MetricService from "../../Services/MetricService";
13
+ import CaptureSpan from "./CaptureSpan";
14
+
15
+ /*
16
+ * Metric-sourced LLM token and cost totals.
17
+ *
18
+ * The LLM feature reads spans first — a GenAI span carries model, tokens and
19
+ * cost on one row, which is the richest source and the only one that can back
20
+ * the per-call views. This module is the SECOND source, for the emitters that
21
+ * publish GenAI metrics but no GenAI spans:
22
+ *
23
+ * - An OpenTelemetry SDK wired for metrics without tracing.
24
+ * - AI gateways and vendor exporters that publish spend/usage counters and
25
+ * never export traces.
26
+ *
27
+ * Callers must not add these totals to the span-sourced ones. Instrumentations
28
+ * that emit both (OpenLLMetry is the common case) would then be counted twice,
29
+ * and for a cost budget that gates alerting a doubled figure is worse than a
30
+ * missing one. LlmCostBudgetEvaluator therefore treats this as a FALLBACK: it
31
+ * is consulted only when the span-sourced total for the same scope is zero.
32
+ *
33
+ * Query construction and result folding live in the isomorphic
34
+ * Common/Utils/Telemetry/LlmMetricQuery, so the dashboard's AI / LLM overview
35
+ * asks the same questions of the same data. This module only adds the
36
+ * AggregateBy envelope and executes them with root props.
37
+ */
38
+
39
+ export { LlmMetricScope, LlmMetricTokenTotals };
40
+
41
+ export default class LlmMetricSpend {
42
+ /**
43
+ * Aggregate descriptor for the cost sum: one total over the whole window.
44
+ *
45
+ * `value` is the right column for every point type here — for a histogram
46
+ * ClickHouse stores the bucket sum in it, and MetricService resolves the
47
+ * point type before building the statement so distribution metrics skip the
48
+ * materialized views. Cost metrics are counters (delta or cumulative spend),
49
+ * so summing them across the window is the intended reduction.
50
+ */
51
+ public static buildCostAggregateBy(
52
+ scope: LlmMetricScope,
53
+ ): AggregateBy<Metric> {
54
+ return {
55
+ query: LlmMetricQuery.buildCostQuery(scope),
56
+ aggregationType: AggregationType.Sum,
57
+ aggregateColumnName: "value",
58
+ aggregationTimestampColumnName: "time",
59
+ startTimestamp: scope.startTime,
60
+ endTimestamp: scope.endTime,
61
+ // One total over the whole window — no time bucketing.
62
+ aggregationInterval: AggregationInterval.Total,
63
+ /*
64
+ * Same reasoning as the span path: this figure feeds budget monitors, so
65
+ * a query timeout must fail loudly rather than return a
66
+ * silently-partial sum that would understate spend and suppress a real
67
+ * breach.
68
+ */
69
+ timeoutOverflowMode: "throw",
70
+ limit: LIMIT_PER_PROJECT,
71
+ skip: 0,
72
+ props: {
73
+ isRoot: true,
74
+ },
75
+ } as AggregateBy<Metric>;
76
+ }
77
+
78
+ /**
79
+ * Aggregate descriptor for the token sum.
80
+ *
81
+ * Grouping by every candidate token-type attribute key in ONE query —
82
+ * rather than issuing a query per key and per direction — is what keeps this
83
+ * both complete and free of double counting: each returned group carries the
84
+ * attribute values that produced it, so LlmMetricQuery.reduceTokenRows
85
+ * classifies them against the full set of recognized spellings instead of
86
+ * the query having to pick one.
87
+ */
88
+ public static buildTokenAggregateBy(
89
+ scope: LlmMetricScope,
90
+ ): AggregateBy<Metric> {
91
+ return {
92
+ query: LlmMetricQuery.buildTokenQuery(scope),
93
+ aggregationType: AggregationType.Sum,
94
+ aggregateColumnName: "value",
95
+ aggregationTimestampColumnName: "time",
96
+ startTimestamp: scope.startTime,
97
+ endTimestamp: scope.endTime,
98
+ aggregationInterval: AggregationInterval.Total,
99
+ groupByAttributeKeys: [...LlmTokenTypeAttributeKeys],
100
+ timeoutOverflowMode: "throw",
101
+ limit: LIMIT_PER_PROJECT,
102
+ skip: 0,
103
+ props: {
104
+ isRoot: true,
105
+ },
106
+ } as AggregateBy<Metric>;
107
+ }
108
+
109
+ /** Metric-sourced spend in USD for the scope, or 0 when nothing matched. */
110
+ @CaptureSpan()
111
+ public static async getCostInUSD(scope: LlmMetricScope): Promise<number> {
112
+ const result: AggregatedResult = await MetricService.aggregateBy(
113
+ this.buildCostAggregateBy(scope),
114
+ );
115
+
116
+ return LlmMetricQuery.sumAggregatedRows(result?.data);
117
+ }
118
+
119
+ /** Metric-sourced input/output token totals for the scope. */
120
+ @CaptureSpan()
121
+ public static async getTokenTotals(
122
+ scope: LlmMetricScope,
123
+ ): Promise<LlmMetricTokenTotals> {
124
+ const result: AggregatedResult = await MetricService.aggregateBy(
125
+ this.buildTokenAggregateBy(scope),
126
+ );
127
+
128
+ return LlmMetricQuery.reduceTokenRows(result?.data);
129
+ }
130
+ }